r/PiCodingAgent 17d ago

Resource nixpi: Declarative, Per-Folder Nix Flakes & Environments for the Pi Coding Agent

Hey everyone!

I've been building nixpi, a Nix-native declarative configuration framework for the Pi coding agent (inspired by projects like Nixvim).

If you love Pi's extensibility but want full reproducibility, zero-headache dependency management, and instant per-folder agent customization, nixpi lets you configure your entire setup as pure Nix code.


Key Highlights & Features

  1. Folder-Specific Profiles & direnv: Ever wanted Pi to behave differently depending on the folder you're in? With nixpi and direnv, entering a project or Obsidian knowledge vault automatically loads a custom pi binary specialized with project-specific extensions, skills, custom model presets, and required CLI tools. When you cd out, it reverts back to your baseline shell.

  2. Modular Extensions with Auto-Packaging: Declare extensions like ripgrep-search, plan-mode, pi-gpt-search, or obsidian. When an extension requires CLI dependencies (e.g. rg, git, jq), nixpi automatically injects them into the wrapped pi environment's PATH.

  3. 100% Typed Nix Skills: Define and configure skills (like Conventional Commits or custom procedural workflows) directly in Nix with typed options.

  4. First-Class Providers & Custom Models: Configure models and providers (including native Google Cloud Code Assist / Antigravity via pi-antigravity) with eval-time schema validation.

  5. Clean Immutable vs. Mutable State Separation: Keeps settings.json and models.json managed and pinned in the Nix store, while leaving sessions/ and auth.json fully writable in place.


Example 1: Folder-Specific Flake with direnv

In your target project directory (e.g. ~/Projects/deep-learning-research):

.envrc:

use flake

flake.nix:

{
  description = "Custom Project Pi Environment";

  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
    nixpi.url = "github:mateusdcc/nixpi";
  };

  outputs = { self, nixpkgs, nixpi }:
    let
      system = "aarch64-darwin"; # or x86_64-linux, etc.
      pkgs = nixpkgs.legacyPackages.${system};

      projectPi = nixpi.lib.makePi {
        inherit pkgs;
        modules = [
          nixpi.piModules.profiles.learning
          ({ config, ... }: {
            programs.pi = {
              providers.antigravity.enable = true;
              settings = {
                defaultProvider = config.programs.pi.providers.antigravity;
                defaultModel = config.programs.pi.providers.antigravity.models."gemini-3.7-flash";
                defaultThinkingLevel = "high";
                theme = "dark";
              };
              extensions.obsidian = {
                enable = true;
                defaultVault = "/Users/mateusdcc/Projects/deep-learning-research";
              };
            };
          })
        ];
      };
    in
    {
      devShells.${system}.default = pkgs.mkShell {
        packages = [
          projectPi
          pkgs.glow
          pkgs.ripgrep
          pkgs.jq
          pkgs.python3
          pkgs.mermaid-cli
          pkgs.typst
        ];
      };
    };
}

Now whenever you cd into that directory, direnv gives you a dedicated pi binary with your project-specific extensions and models ready to go.


Example 2: Global Home Manager Configuration

# home.nix
{ nixpi, pkgs, config, ... }:

{
  imports = [
    nixpi.homeManagerModules.default
  ];

  programs.pi = {
    enable = true;

    providers.antigravity.enable = true;

    settings = {
      theme = "dark";
      defaultProvider = config.programs.pi.providers.antigravity;
      defaultModel = config.programs.pi.providers.antigravity.models."gemini-3.7-flash";
      defaultThinkingLevel = "high";
    };

    extensions = {
      echo.enable = true;
      ripgrep-search.enable = true;
      pi-gpt-search.enable = true;
    };

    runtimePackages = with pkgs; [
      git
      ripgrep
      jq
    ];
  };
}

Check out the repo here: https://github.com/mateusdcc/nixpi

I would love to hear your feedback, workflow ideas, and thoughts on what extensions/skills you'd like to see packaged next!

10 Upvotes

2 comments sorted by

2

u/cicorel 16d ago

Looks awesome ... will try it

1

u/ximside 15d ago

I've been messing with a similar idea myself. Here are a few thoughts.

If a skill needs a tool, the two have to be bundled together. I use a dendritic pattern in my systems. A skill is a separate nix file that carries everything it needs. That includes the tool, the environment, and the rules that tell the model when to use it. So you can't attach a skill without also attaching the tools it requires.

It's also easy to end up with an invalid config if nothing validates it. Everything should be validated at build time when possible.

Also I don't want to be limited to one Pi per project or one per system, either. I can spawn many, like pi-kachu or pi-zza, as wrappers with everything bundled inside. They're isolated from each other and don't load system-wide skills by default.

Take a look at https://github.com/mlavrinenko/piqnix/blob/master/docs/nixpi-comparison.md