Pi coding agent: how to install (npm) extensions?

Hi all! I’ve installed the pi-coding-agent package from unstable. It works fine, but installing extensions (e.g. pi-mcp-adapter) does not work, because it calls npm install under the hood (I assume) and thus results in:

Installing npm:pi-mcp-adapter...
npm error code ENOENT
npm error syscall mkdir
npm error path /nix/store/4pl6afcwfmv0xn65r7mqjy3avpb785j9-nodejs-slim-24.14.0/lib
npm error errno -2
npm error enoent ENOENT: no such file or directory, mkdir '/nix/store/4pl6afcwfmv0xn65r7mqjy3avpb785j9-nodejs-slim-24.14.0/lib'
npm error enoent This is related to npm not being able to find a file.
npm error enoent

It’s pretty clear why it fails. My question is: what’s the best / recommended way to install these (npm based) plugins? I’ve never configured npm/node.js on NixOS (or any other distro, tbh).

2 Likes

OK, so I came up with this solution (home-manager module):

{ pkgs, config, ... }:

{
  home.packages = [    
    (pkgs.symlinkJoin {
      name = "pi-coding-agent";
      buildInputs = [ pkgs.makeWrapper ];
      paths = [ pkgs.pi-coding-agent ];
      postBuild = ''
        wrapProgram $out/bin/pi \
          --set NPM_CONFIG_PREFIX ${config.home.homeDirectory}/.pi/npm/ \
          --prefix PATH : ${
            pkgs.lib.makeBinPath [
              pkgs.nodejs_latest
            ]
          }
      '';
    })
  ];
}

I’m redirecting NPM packages to ~/.pi/npm/ only for Pi, because I didn’t want to change the NPM global prefix via ~/.npmrc for all packages. By doing this, I have all Pi related NPM packages in one place. I’ve also tried to set PI_PACKAGE_DIR but that didn’t work (I guess that would have to be done during build time, but I’m not sure).

Also, note that I’ve added nodejs_latest to the runtime dependencies. Without Node.js, the plugins don’t work. Imo, this should be a dependency of the original nixpkgs derivation (because Pi is barely usable without extensions), but for some reason it’s not.

Of course, this is not an ideal solution (i.e. not fully declarative and reproducible). But as long as the nixpkgs package doesn’t support extension management, this works for me.

3 Likes