fix(npm): install to a user cache when the package is read-only; signal-safe first run

- When the package's bin/ is not writable (a root-owned `sudo npm i -g`
  whose postinstall npm 12 skipped), install the binary to a per-user
  cache ($XDG_CACHE_HOME, ~/.cache, ~/Library/Caches on macOS, under
  <package>/<version>/); the launcher looks in both. Previously the first
  run failed with EACCES and advice to rerun npm install.
- Run the first-run installer asynchronously with SIGTERM/SIGHUP
  forwarded, so a supervisor stopping the launcher stops the download;
  the installer removes its partial file and the launcher exits by the
  same signal.
- Verify an IDX_BINARY_URL local file's checksum on the copy, not the
  source, so the installed bytes are the checked ones.
- npm smoke covers the read-only fallback.

The last three come from a Codex review.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V3syn2fN2LNo5pvTSqc6eh
This commit is contained in:
hermes 2026-10-16 08:07:41 +00:00
commit 907223a838
4 changed files with 156 additions and 51 deletions

View file

@ -52,6 +52,13 @@ itself on first start, logging to stderr so the `idx-mcp` stdout channel stays
clean; it fails only when that download fails too. Hermes Agent runs `npx` with
its own npm 12, which is how 0.3.1 broke there (issue #41).
The binary goes in the package's `bin/`, or, when that is not writable (a
root-owned `sudo npm install -g` whose postinstall npm 12 skipped), in a
per-user cache: `$XDG_CACHE_HOME`, else `~/.cache` (`~/Library/Caches` on
macOS), under `<package>/<version>/`. The launcher looks in both. A
termination signal during that first-run download stops the installer too,
and it removes its partial file.
To install the binary up front instead, allow the script explicitly:
```bash
@ -70,7 +77,8 @@ npm install --global --allow-scripts=idx-cli idx-cli
The smoke script builds or reuses `target/release/idx`, packs the npm wrapper,
installs the tarball into a new temporary directory, and runs the installed
`idx` command, then installs `idx-mcp` again with `--ignore-scripts` to check
the launcher's first-run install. It uses `IDX_BINARY_URL` with a local `file:` URL, so the test
the launcher's first-run install, also with a read-only package directory
(the per-user cache fallback). It uses `IDX_BINARY_URL` with a local `file:` URL, so the test
does not need a registry publish or a network download.
```bash