fix(server): Cursor sandboxed threads find their helper when running from source - #13571
Conversation
…from source @cursor/sdk locates its platform package (cursorsandbox, rg, tree-sitter natives) by walking up from the entry script looking for node_modules/@cursor/sdk-<platform>-<arch>. pnpm's isolated layout keeps that optional dependency inside the virtual store next to the SDK, so the walk from apps/server never reaches it and restricted-mode threads fail with "sandboxing is not supported in this environment". Publicly hoisting @cursor/sdk-* links the installed platform package into the root node_modules, which the walk reaches. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
ApprovabilityVerdict: Approved at Macroscope's review found this PR approvable — This small workspace configuration fix makes the already-supported Cursor sandbox helpers discoverable during source-based server runs. Its effect is localized to dependency layout and existing Cursor execution, with staged desktop and CLI packaging paths remaining separately configured. You can add or adjust custom eligibility rules. Learn more. |
Thread transfer impact✅ Thread transfer remains within every enforced ceiling.
Baseline: unavailable · PR result: Scenario and decoded snapshot size10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.
Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed. |
e24ad9a
into
t3code/codex-turn-mapping
…from source (#13571) Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Restricted-mode (sandboxed) Cursor threads fail when T3 runs from source (
vp run dev,node apps/server/dist/bin.mjs) with "Local SDK sandboxing was requested, but sandboxing is not supported in this environment."Cause
@cursor/sdk1.0.31 finds its platform package throughplatform-package-locator: starting atdirname(process.argv[1])and thendirname(process.execPath), it walks up parent directories looking for<dir>/node_modules/@cursor/sdk-<platform>-<arch>/<file>(or@cursor/february-*). pnpm's isolated layout installs that optional dependency only as a sibling inside the virtual store (node_modules/.pnpm/@cursor+sdk@1.0.31/node_modules/@cursor/sdk-linux-x64).apps/server/node_modules/@cursor/contains onlysdk, so the walk fromapps/server/srcnever finds the package. Withoutcursorsandbox,isSandboxSupportedreturns false and the SDK refuses sandboxed runs.Two other lookups use the same locator and were silently degraded too:
rgfell back to whatever ripgrep is on PATH, or none.vendornatives were missing, which disables shell command analysis.Fix
Add
publicHoistPattern: ["@cursor/sdk-*"]topnpm-workspace.yaml. pnpm then links the installed platform package into the rootnode_modules/@cursor/, which the upward walk fromapps/server/...reaches.supportedArchitecturesstill filters optionals, so only the matching platform package is linked. On this Linux box that issdk-linux-x64.@cursor/sdk, unlike declaring the five platform packages as server optionalDependencies.Effect on packaged builds
build-desktop-artifact.tsruns its own stagedvp install --prodwith a generatedpnpm-workspace.yamlthat does not carrypublicHoistPattern.stageCursorSdkPlatformPackagesstill copiessdk-*from beside the real SDK directory intoresources/node_modules/@cursor. The root-level link is a symlink to the same store directory, and the asar globs already exclude**/node_modules/@cursor/sdk-*.npx t3: unaffected.build-cli-archive.tsinstalls runtime externals withnodeLinker: hoistedinto a separate stage dir, from its own generated workspace config.Verification
platform-package-locatormodule, sliced out ofdist/esm/index.js, withargv[1]set to each server entry:apps/server/src/bin.ts,apps/server/dist/bin.mjs, andapps/server/scripts/record-cursor-agent-sdk-replay-fixture.ts.cursorsandbox: null,rg: null,vendor: nullfor all three.cursorsandbox,rgandvendorall resolve under<repo>/node_modules/@cursor/sdk-linux-x64/…for all three.Agent.create({ model: { id: "composer-2.5" }, local: { cwd, autoReview: false, sandboxOptions: { enabled: true } } })withargv[1]atapps/server/src/bin.ts, prompt "Runcat hello.txt".Local SDK sandboxing was requested, but sandboxing is not supported in this environment.status: finished, outputsandbox-ok.vp i: lockfile up to date. The only new entry in the rootnode_modulesis the@cursor/sdk-linux-x64symlink.cd apps/server && vp test run src/orchestration-v2/testkit/OrchestratorReplayFixtures.integration.test.ts -t cursor: 10 passed.vp test run scripts/build-desktop-artifact.test.ts scripts/lib/cursor-sdk-packaging.test.ts: 67 passed, 6 failed. The same 6 fail on the base branch without this change, after a reinstall to the base layout. The causes are environmental on this box:cursor-sdk-packaging.test.tsasserts there is nonode_modulesabove TMPDIR, and/tmp/node_modulesexists.cd apps/server && vp exec tsc --noEmit -p .: noerror TSorwarning TS.vp run knip:check: one unused export,THREAD_DETAILS_PANEL_SPLIT_BUTTON_SURFACE_CLASSinapps/web. It comes from the base branch's head commit and is unrelated to this change.Model: Claude Opus 5.5 (Claude Code)
🤖 Generated with Claude Code