diff --git a/deploy/rsync-pi-agent.sh b/deploy/rsync-pi-agent.sh index 3d2904c..ee19da6 100755 --- a/deploy/rsync-pi-agent.sh +++ b/deploy/rsync-pi-agent.sh @@ -59,7 +59,8 @@ for pkg in settings.get("packages") or []: subprocess.run(["git", "clone", "--quiet", url, str(target)], check=True) if ref: subprocess.run(["git", "checkout", "--quiet", ref], cwd=target, check=True) - shutil.rmtree(target / ".git", ignore_errors=True) + # keep .git: pi's package manager runs `git fetch` + `rev-parse` on + # existing installs; a stripped dir would fail resolution. if (target / "package.json").exists(): npm = "/usr/bin/npm" if Path("/usr/bin/npm").exists() else "npm" subprocess.run( diff --git a/docker/control.Dockerfile b/docker/control.Dockerfile index 7e0bb49..9de8676 100644 --- a/docker/control.Dockerfile +++ b/docker/control.Dockerfile @@ -13,9 +13,9 @@ RUN apt-get update \ RUN npm install -g --ignore-scripts @earendil-works/pi-coding-agent # Same npm shim as the worker image (see worker.Dockerfile). -RUN mv /usr/local/bin/npm /usr/local/bin/npm-real +COPY docker/npm-real /usr/local/bin/npm-real COPY docker/npm-shim /usr/local/bin/npm -RUN chmod +x /usr/local/bin/npm +RUN chmod +x /usr/local/bin/npm-real /usr/local/bin/npm # Same pi config as workers (dotfiles, filtered; git: packages stripped). COPY docker/pi-agent/ /root/.pi/agent/ diff --git a/docker/npm-real b/docker/npm-real new file mode 100644 index 0000000..e039f3f --- /dev/null +++ b/docker/npm-real @@ -0,0 +1,3 @@ +#!/bin/sh +# Thin launcher for the real npm CLI (npm ships as JS, not a binary). +exec node /usr/local/lib/node_modules/npm/bin/npm-cli.js "$@" diff --git a/docker/npm-shim b/docker/npm-shim index 5ecc0ed..c6f6da0 100644 --- a/docker/npm-shim +++ b/docker/npm-shim @@ -1,16 +1,15 @@ #!/bin/sh # npm shim for headless pi containers: skip lifecycle scripts during package -# installs. pi installs git: packages by running `npm install --omit=dev` in -# each clone; some upstream packages (e.g. husky in rpiv-mono) have -# postinstall scripts that assume a dev machine and fail/crash headless -# installs. --ignore-scripts makes installs safe; runtime code (pure TS/JS -# extensions) does not need lifecycle scripts. Everything else passes through -# to the real npm transparently. +# installs. pi installs git: packages by running `npm install` in each clone; +# some upstream packages (e.g. husky in rpiv-mono) have postinstall scripts +# that assume a dev machine and fail headless installs. --ignore-scripts +# makes installs safe; runtime code (pure TS/JS extensions) does not need +# installs. Everything else passes through to the real npm (docker/npm-real). case "$1" in install|i) - exec /usr/bin/npm-real "$@" --ignore-scripts + exec /usr/local/bin/npm-real "$@" --ignore-scripts ;; *) - exec /usr/bin/npm-real "$@" + exec /usr/local/bin/npm-real "$@" ;; esac diff --git a/docker/worker.Dockerfile b/docker/worker.Dockerfile index d8811e2..4a20583 100644 --- a/docker/worker.Dockerfile +++ b/docker/worker.Dockerfile @@ -17,9 +17,9 @@ RUN npm install -g --ignore-scripts @earendil-works/pi-coding-agent # scripts (husky etc.) crash headless installs. Route installs through # --ignore-scripts so ALL dotfiles packages (pi-subagents, todo tooling, # async agents, every extension) survive the bake. -RUN mv /usr/local/bin/npm /usr/local/bin/npm-real +COPY docker/npm-real /usr/local/bin/npm-real COPY docker/npm-shim /usr/local/bin/npm -RUN chmod +x /usr/local/bin/npm +RUN chmod +x /usr/local/bin/npm-real /usr/local/bin/npm # User's pi config from dotfiles (settings, skills, agents, extensions, # APPEND_SYSTEM.md) — synced by deploy.sh from ~/.dotfiles/pi/agent (filtered: