Summary: Marketplace install uses bare node, which breaks under nvm (GUI PATH / wrong Node version); add a version-manager-aware launcher.
Description
The recommended install path (Cursor Settings → Plugins → add https://github.com/langchain-ai/langsmith-cursor-plugins) ships a static hooks/hooks.json that runs:
On macOS, Cursor launched from the Dock/Finder often resolves a different node than the developer’s interactive shell (or an old nvm default). Hooks that only buffer events can still succeed, while stop.js crashes on import because it requires Node ≥ 22.13 (node:sqlite). Tracing then never reaches LangSmith, and ~/.cursor/langsmith-hook.log may never be created (crash before logger init).
The local installer (scripts/install.mjs) already documents this and pins process.execPath into ~/.cursor/hooks.json, but:
- Most users never run that installer (marketplace is the recommended path).
- Pinning
…/versions/node/vX.Y.Z/bin/node drifts on the next nvm install / nvm alias default.
Observed failure mode
Command: node ./bundle/stop.js (…) exit code: 1
Error [ERR_UNKNOWN_BUILTIN_MODULE]: No such built-in module: node:sqlite
- Earlier hooks (
beforeSubmitPrompt, postToolUse, …) may still write ~/.cursor/langsmith-state.json.
turn_count stays 0 (stop never finalizes).
- No useful lines in
~/.cursor/langsmith-hook.log because the process dies at module load.
Proposal
Add a relative, version-manager-aware launcher in the plugin repo and use it from marketplace hooks.json (Cursor already runs hooks with cwd = plugin root).
1. Add scripts/run-node.sh
Resolve Node in this order (example):
LANGSMITH_CURSOR_NODE / NODE_BINARY override
- nvm default (
$NVM_DIR/alias/default, follow aliases → $NVM_DIR/versions/node/v…/bin/node)
- Optional: fnm / asdf / volta
command -v node
- Assert usability, e.g.
node -e "require('node:sqlite')" (or version ≥ 22.13), with a clear stderr message if not
Then exec the resolved binary with the hook script args.
2. Update hooks/hooks.json (marketplace path)
Change each hook from:
{ "command": "node ./bundle/stop.js" }
to something like:
{ "command": "/bin/bash ./scripts/run-node.sh ./bundle/stop.js" }
3. Align scripts/install.mjs
Prefer emitting the same launcher (or installing a copy under ~/.cursor/bin/) instead of baking a versioned absolute process.execPath, so upgrades of nvm’s default don’t require re-running the installer.
4. Docs
- README: Node ≥ 22.13, nvm/GUI PATH caveat, how to set
LANGSMITH_CURSOR_NODE.
- Troubleshooting: if
stop exits 1 with node:sqlite, check which Node the launcher selected (log path + version on stderr when check fails).
Related context
scripts/install.mjs already states:
Cursor spawns hooks from a GUI context without your shell PATH / version manager, so the command must use an absolute node binary and absolute bundle paths.
Marketplace install currently ignores that for the node binary itself.
Summary: Marketplace install uses bare
node, which breaks under nvm (GUI PATH / wrong Node version); add a version-manager-aware launcher.Description
The recommended install path (Cursor Settings → Plugins → add
https://github.com/langchain-ai/langsmith-cursor-plugins) ships a statichooks/hooks.jsonthat runs:On macOS, Cursor launched from the Dock/Finder often resolves a different
nodethan the developer’s interactive shell (or an old nvm default). Hooks that only buffer events can still succeed, whilestop.jscrashes on import because it requires Node ≥ 22.13 (node:sqlite). Tracing then never reaches LangSmith, and~/.cursor/langsmith-hook.logmay never be created (crash before logger init).The local installer (
scripts/install.mjs) already documents this and pinsprocess.execPathinto~/.cursor/hooks.json, but:…/versions/node/vX.Y.Z/bin/nodedrifts on the nextnvm install/nvm alias default.Observed failure mode
beforeSubmitPrompt,postToolUse, …) may still write~/.cursor/langsmith-state.json.turn_countstays0(stop never finalizes).~/.cursor/langsmith-hook.logbecause the process dies at module load.Proposal
Add a relative, version-manager-aware launcher in the plugin repo and use it from marketplace
hooks.json(Cursor already runs hooks with cwd = plugin root).1. Add
scripts/run-node.shResolve Node in this order (example):
LANGSMITH_CURSOR_NODE/NODE_BINARYoverride$NVM_DIR/alias/default, follow aliases →$NVM_DIR/versions/node/v…/bin/node)command -v nodenode -e "require('node:sqlite')"(or version ≥ 22.13), with a clear stderr message if notThen
execthe resolved binary with the hook script args.2. Update
hooks/hooks.json(marketplace path)Change each hook from:
{ "command": "node ./bundle/stop.js" }to something like:
{ "command": "/bin/bash ./scripts/run-node.sh ./bundle/stop.js" }3. Align
scripts/install.mjsPrefer emitting the same launcher (or installing a copy under
~/.cursor/bin/) instead of baking a versioned absoluteprocess.execPath, so upgrades of nvm’s default don’t require re-running the installer.4. Docs
LANGSMITH_CURSOR_NODE.stopexits 1 withnode:sqlite, check which Node the launcher selected (log path + version on stderr when check fails).Related context
scripts/install.mjsalready states:Marketplace install currently ignores that for the
nodebinary itself.