Skip to content

fix(cli): self-heal missing deps in the sync/dispatcher entry point - #171

Open
Taste4458 wants to merge 1 commit into
obra:mainfrom
Taste4458:fix/sessionstart-dep-check
Open

Taste4458 wants to merge 1 commit into
obra:mainfrom
Taste4458:fix/sessionstart-dep-check

Conversation

@Taste4458

Copy link
Copy Markdown

Problem

`mcp-server-wrapper.js` already probes for missing `node_modules` (deps
externalized from the esbuild bundle — `@anthropic-ai/claude-agent-sdk`,
`better-sqlite3`, etc.) and runs `npm install` before launching the MCP
server (see the `#95`/`#161` fixes already in this repo).

`cli/episodic-memory.js`, the dispatcher the SessionStart hook invokes
directly (`episodic-memory sync --background`), had no equivalent check.
On a fresh plugin install/update — before the MCP server has had a chance
to self-heal `node_modules` for the plugin root — the SessionStart hook
crashes:

```
node:internal/modules/package_json_reader:301
Error [ERR_MODULE_NOT_FOUND]: Cannot find package '@anthropic-ai/claude-agent-sdk'
imported from .../dist/summarizer.js
```

This surfaces to the user as a Claude Code "SessionStart:startup hook
error," and recurs on every fresh install/update until something happens
to populate `node_modules` in that specific version directory (a manual
`npm install`, or an MCP connection racing ahead of the sync hook).

Fix

Give the CLI dispatcher the same self-heal check the MCP wrapper already
has, reusing the existing `install-check.js`/`install-runner.js`
utilities (same missing-deps probe, same single-flight install lock) so
both entry points share one code path instead of diverging further.

Skipped for `--help`/`-h`/no-args, since showing help doesn't need the
runtime deps.

Testing

  • Added `test/cli-dispatcher-install-check.test.ts`, mirroring the
    existing `mcp-server-wrapper` integration test pattern in
    `test/mcp-install-runner.test.ts`: spawns the real dispatcher against an
    empty `CLAUDE_PLUGIN_ROOT` with a stub `npm` on `PATH`, and asserts the
    install path is (and isn't, for `--help`) taken.
  • Full suite: `npm test` — 64 files, 352 tests, all passing.

mcp-server-wrapper.js already probes for missing node_modules (deps
externalized from the esbuild bundle, e.g. @anthropic-ai/claude-agent-sdk)
and runs npm install before launching the server. cli/episodic-memory.js
had no equivalent check, so the SessionStart `sync` hook — invoked
directly, not through the wrapper — crashed with ERR_MODULE_NOT_FOUND on
a fresh install/update, before the MCP server had a chance to self-heal
node_modules for the plugin root.

Reuses the existing install-check.js/install-runner.js utilities so both
entry points share one self-heal path and one install lock.

Co-Authored-By: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant