--- parent: "[[002-pi-subagents-map]]" tags: - ticket/research --- # Herdr Pi integration Nix-pure deployment research ## Question Can the Herdr Pi integration be installed declaratively through Nix/Home Manager without vendoring the generated Pi extension file by hand? ## Findings Herdr exposes first-party integration management through the `herdr integration` command group. `herdr --help` lists `herdr integration ` as the built-in interface for managing agent integrations, and `herdr integration install --help` says the install command takes a single target argument whose possible values include `pi`. On this host, `herdr --version` reports `herdr 0.7.5`. The Pi integration installs a Pi-side extension file, not a Herdr config file. `herdr integration status` reported `pi: not installed (/home/alexion/.pi/agent/extensions/herdr-agent-state.ts)` before installation, and `herdr integration install pi` reported `installed pi integration to /home/alexion/.pi/agent/extensions/herdr-agent-state.ts`. After installation, `herdr integration status` reported `pi: current (v6) (/home/alexion/.pi/agent/extensions/herdr-agent-state.ts)`. The generated file begins with Herdr-owned metadata: `HERDR_INTEGRATION_ID=pi` and `HERDR_INTEGRATION_VERSION=6`. The installer does not create the Pi extension directory. With a temporary `HOME` and no `~/.pi/agent/extensions`, `herdr integration install pi` failed with `pi extension directory not found at .../.pi/agent/extensions. install pi first`. After creating that directory in the temporary home, the same command succeeded and wrote `herdr-agent-state.ts`. This matters for Nix because the derivation or activation code must provide a fake Pi home layout before invoking the installer. The installer can run in a Nix build derivation on this machine. A test derivation using `pkgs.stdenvNoCC.mkDerivation`, `nativeBuildInputs = [ pkgs.herdr ]`, a fake `$TMPDIR/home/.pi/agent/extensions`, and `HOME=$TMPDIR/home herdr integration install pi` built successfully and copied the generated file to `$out/herdr-agent-state.ts`. The generated store file was root-owned and read-only, as expected for a Nix build output. Its SHA-256 matched the file produced by the imperative install in the real home: `12efd27592fbf185343f035ee4fd2b1999e9356e323e4b01225f7d6bc89b16de` for both files. Therefore a Nix-pure deployment is feasible in this repository without manually vendoring the generated file. The dotfiles module can create a small derivation that runs Herdr's own installer into a fake home and then expose the generated `herdr-agent-state.ts` as a Home Manager-managed Pi extension. This keeps the generated adapter tied to the pinned `pkgs.herdr` package and avoids a stale checked-in copy. ## Recommended declarative shape Keep the extension deployment in the Pi module because the runtime artifact is a Pi extension file: ```nix let herdrPiIntegration = pkgs.stdenvNoCC.mkDerivation { name = "herdr-pi-integration"; nativeBuildInputs = [ pkgs.herdr ]; phases = [ "installPhase" ]; installPhase = '' mkdir -p $TMPDIR/home/.pi/agent/extensions HOME=$TMPDIR/home herdr integration install pi mkdir -p $out cp $TMPDIR/home/.pi/agent/extensions/herdr-agent-state.ts $out/herdr-agent-state.ts ''; }; in { home-manager.users.${user}.home.file."${piDir}/extensions/herdr-agent-state.ts".source = "${herdrPiIntegration}/herdr-agent-state.ts"; } ``` This uses Herdr as the source of truth for its adapter while leaving Pi to load the resulting file through its normal extension directory. It should not require `herdr integration install pi` during activation. It also avoids installing into `~/.pi/agent/extensions` imperatively, which is important because this repo already manages Pi extension deployment declaratively. A slightly more structured version could package the generated file as `pkgs.herdr-pi-integration` in an overlay or local package helper if more modules need it. For a single file used only by `modules/agents/pi/pi.nix`, an inline derivation is enough. ## Caveats The build-time test establishes that Herdr 0.7.5's Pi installer can run in a Nix derivation on this host. It does not prove future Herdr versions will remain build-sandbox friendly. If a future installer starts requiring network access, a running Herdr server, or writable global config, the derivation will fail and reveal that at build time. The generated file says it is "managed by herdr" and can be overwritten by reinstalling or updating the integration. When Nix generates the file, the practical manager is the Nix derivation, but the content still belongs to Herdr. Do not edit the generated TypeScript by hand. The current direct install under `~/.pi/agent/extensions/herdr-agent-state.ts` is not the final declarative state. A later implementation should either remove that unmanaged file or let Home Manager replace it with the generated store-backed file. ## Citations - `herdr --help` on this host lists `herdr integration ` as the interface for managing built-in agent integrations and reports config/log paths. - `herdr integration install --help` on this host defines `install ` and lists `pi` among supported targets. - `herdr integration status` on this host reported the Pi integration path and current installed state before and after installation. - `herdr integration install pi` on this host wrote `/home/alexion/.pi/agent/extensions/herdr-agent-state.ts` and reported success. - Temporary-home installer test: `HOME=$(mktemp -d)` without `.pi/agent/extensions` failed with the missing-directory diagnostic, and the same command succeeded after creating `.pi/agent/extensions`. - Nix derivation test at `/tmp/herdr-pi-integration-test.nix` built successfully with `nix build --impure --no-link --print-out-paths --file /tmp/herdr-pi-integration-test.nix` and generated `/nix/store/9qnkkqkv8f3smm09n4rzshwh961fbj9h-herdr-pi-integration-test/herdr-agent-state.ts`.