pi-cursor-sdk 0.1.62 → 0.3.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +85 -0
- package/README.md +57 -53
- package/dist/bundled-context-windows.js +39 -0
- package/dist/context-window-cache.js +92 -0
- package/dist/context.js +338 -0
- package/dist/cursor-active-tools.js +3 -0
- package/dist/cursor-agent-message-web-tools.js +165 -0
- package/dist/cursor-agents-context-registration.js +17 -0
- package/dist/cursor-agents-context.js +113 -0
- package/dist/cursor-api-key.js +34 -0
- package/dist/cursor-bridge-contract.js +27 -0
- package/dist/cursor-cloud-lifecycle.js +650 -0
- package/dist/cursor-cloud-local-state.js +460 -0
- package/dist/cursor-cloud-options.js +145 -0
- package/dist/cursor-cloud-reporting.js +222 -0
- package/dist/cursor-compact-tool-summary.js +75 -0
- package/dist/cursor-config.js +613 -0
- package/dist/cursor-context-tools.js +4 -0
- package/dist/cursor-display-only-trace.js +11 -0
- package/dist/cursor-display-text.js +18 -0
- package/dist/cursor-durable-fs.js +53 -0
- package/dist/cursor-edit-diff.js +13 -0
- package/dist/cursor-env-boolean.js +19 -0
- package/dist/cursor-fallback-models.generated.js +7760 -0
- package/dist/cursor-fallback-warning.js +15 -0
- package/dist/cursor-http1.js +45 -0
- package/dist/cursor-incomplete-tool-visibility.js +83 -0
- package/dist/cursor-live-run-accounting.js +55 -0
- package/dist/cursor-live-run-coordinator.js +406 -0
- package/dist/cursor-mcp-timeout-override.js +116 -0
- package/dist/cursor-model-lifecycle.js +32 -0
- package/dist/cursor-model.js +5 -0
- package/dist/cursor-native-replay-routing.js +35 -0
- package/dist/cursor-native-replay-trace.js +28 -0
- package/dist/cursor-native-tool-display-registration.js +102 -0
- package/dist/cursor-native-tool-display-replay.js +428 -0
- package/dist/cursor-native-tool-display-state.js +70 -0
- package/dist/cursor-native-tool-display-tools.js +123 -0
- package/dist/cursor-native-tool-names.js +11 -0
- package/dist/cursor-partial-content-emitter.js +118 -0
- package/dist/cursor-pi-tool-bridge-abort.js +114 -0
- package/dist/cursor-pi-tool-bridge-constants.js +6 -0
- package/dist/cursor-pi-tool-bridge-diagnostics.js +125 -0
- package/dist/cursor-pi-tool-bridge-env.js +18 -0
- package/dist/cursor-pi-tool-bridge-mcp.js +100 -0
- package/dist/cursor-pi-tool-bridge-run.js +355 -0
- package/dist/cursor-pi-tool-bridge-server.js +163 -0
- package/dist/cursor-pi-tool-bridge-snapshot.js +63 -0
- package/dist/cursor-pi-tool-bridge-types.js +1 -0
- package/dist/cursor-pi-tool-bridge.js +123 -0
- package/dist/cursor-provider-errors.js +311 -0
- package/dist/cursor-provider-lazy.js +39 -0
- package/dist/cursor-provider-live-run-drain.js +412 -0
- package/dist/cursor-provider-overflow.js +90 -0
- package/dist/cursor-provider-run-finalizer.js +176 -0
- package/dist/cursor-provider-run-outcome.js +76 -0
- package/dist/cursor-provider-turn-coordinator.js +275 -0
- package/dist/cursor-provider-turn-display-router.js +158 -0
- package/dist/cursor-provider-turn-emit.js +35 -0
- package/dist/cursor-provider-turn-finalize.js +154 -0
- package/dist/cursor-provider-turn-lifecycle-emitter.js +126 -0
- package/dist/cursor-provider-turn-prepare.js +374 -0
- package/dist/cursor-provider-turn-runner.js +146 -0
- package/dist/cursor-provider-turn-sdk-normalizer.js +74 -0
- package/dist/cursor-provider-turn-send.js +138 -0
- package/dist/cursor-provider-turn-shell-output.js +117 -0
- package/dist/cursor-provider-turn-tool-ledger.js +99 -0
- package/dist/cursor-provider-turn-types.js +1 -0
- package/dist/cursor-provider.js +72 -0
- package/dist/cursor-question-tool.js +194 -0
- package/dist/cursor-record-utils.js +61 -0
- package/dist/cursor-replay-activity-builders.js +114 -0
- package/dist/cursor-replay-source-names.js +27 -0
- package/dist/cursor-replay-summary-args.js +105 -0
- package/dist/cursor-replay-tool-details.js +167 -0
- package/dist/cursor-ripgrep-path.js +27 -0
- package/dist/cursor-run-final-text.js +63 -0
- package/dist/cursor-runtime-state.js +380 -0
- package/dist/cursor-sdk-billed-usage.js +86 -0
- package/dist/cursor-sdk-event-debug-constants.js +33 -0
- package/dist/cursor-sdk-event-debug-session.js +107 -0
- package/dist/cursor-sdk-event-debug.js +461 -0
- package/dist/cursor-sdk-output-filter.js +1 -0
- package/dist/cursor-sdk-process-error-guard.js +221 -0
- package/dist/cursor-sdk-runtime.js +3 -0
- package/dist/cursor-sensitive-text.js +23 -0
- package/dist/cursor-session-agent-cleanup.js +311 -0
- package/dist/cursor-session-agent-lifecycle.js +32 -0
- package/dist/cursor-session-agent-lineage.js +103 -0
- package/dist/cursor-session-agent-resume.js +417 -0
- package/dist/cursor-session-agent.js +507 -0
- package/dist/cursor-session-compaction-prep.js +21 -0
- package/dist/cursor-session-scope.js +113 -0
- package/dist/cursor-session-send-policy.js +18 -0
- package/dist/cursor-session-store.js +105 -0
- package/dist/cursor-session-turn-queue.js +50 -0
- package/dist/cursor-setting-sources.js +15 -0
- package/dist/cursor-skill-tool.js +230 -0
- package/dist/cursor-state.js +519 -0
- package/dist/cursor-task-presentation.js +59 -0
- package/dist/cursor-tool-lifecycle.js +94 -0
- package/dist/cursor-tool-manifest.js +34 -0
- package/dist/cursor-tool-presentation-registry.js +305 -0
- package/dist/cursor-tool-result-display-readers.js +158 -0
- package/dist/cursor-tool-transcript.js +32 -0
- package/dist/cursor-tool-visibility.js +28 -0
- package/dist/cursor-transcript-tool-formatters.js +618 -0
- package/dist/cursor-transcript-tool-specs.js +284 -0
- package/dist/cursor-transcript-utils.js +170 -0
- package/dist/cursor-usage-accounting.js +166 -0
- package/dist/cursor-web-tool-activity.js +23 -0
- package/dist/cursor-web-tool-args.js +12 -0
- package/dist/index.js +82 -0
- package/dist/model-discovery.js +305 -0
- package/dist/model-list-cache.js +156 -0
- package/docs/cursor-dogfood-checklist.md +2 -1
- package/docs/cursor-live-smoke-checklist.md +15 -14
- package/docs/cursor-model-ux-spec.md +29 -8
- package/docs/cursor-native-tool-replay.md +13 -13
- package/docs/cursor-native-tool-visual-audit.md +6 -3
- package/docs/cursor-testing-lessons.md +7 -7
- package/docs/cursor-tool-surfaces.md +5 -5
- package/docs/platform-smoke.md +6 -6
- package/node_modules/fast-uri/index.js +37 -1
- package/node_modules/fast-uri/package.json +1 -1
- package/node_modules/fast-uri/test/security.test.js +136 -0
- package/node_modules/hono/dist/cjs/context.js +28 -13
- package/node_modules/hono/dist/cjs/helper/proxy/index.js +4 -0
- package/node_modules/hono/dist/cjs/helper/streaming/sse.js +1 -1
- package/node_modules/hono/dist/cjs/hono-base.js +3 -2
- package/node_modules/hono/dist/cjs/jsx/base.js +27 -23
- package/node_modules/hono/dist/cjs/jsx/hooks/index.js +16 -13
- package/node_modules/hono/dist/cjs/middleware/cache/index.js +103 -8
- package/node_modules/hono/dist/cjs/middleware/compress/index.js +5 -0
- package/node_modules/hono/dist/cjs/middleware/cors/index.js +2 -2
- package/node_modules/hono/dist/cjs/middleware/etag/index.js +1 -1
- package/node_modules/hono/dist/cjs/middleware/jwk/jwk.js +9 -4
- package/node_modules/hono/dist/cjs/middleware/jwt/jwt.js +9 -4
- package/node_modules/hono/dist/cjs/middleware/language/language.js +10 -6
- package/node_modules/hono/dist/cjs/middleware/method-not-allowed/index.js +90 -0
- package/node_modules/hono/dist/cjs/middleware/secure-headers/secure-headers.js +10 -4
- package/node_modules/hono/dist/cjs/request.js +7 -9
- package/node_modules/hono/dist/cjs/router/reg-exp-router/node.js +55 -56
- package/node_modules/hono/dist/cjs/router/reg-exp-router/router.js +64 -85
- package/node_modules/hono/dist/cjs/router/reg-exp-router/trie.js +13 -5
- package/node_modules/hono/dist/cjs/router.js +1 -1
- package/node_modules/hono/dist/cjs/utils/accept.js +1 -1
- package/node_modules/hono/dist/cjs/utils/cookie.js +3 -2
- package/node_modules/hono/dist/cjs/utils/url.js +8 -8
- package/node_modules/hono/dist/context.js +28 -13
- package/node_modules/hono/dist/helper/proxy/index.js +4 -0
- package/node_modules/hono/dist/helper/streaming/sse.js +1 -1
- package/node_modules/hono/dist/hono-base.js +3 -2
- package/node_modules/hono/dist/jsx/base.js +27 -23
- package/node_modules/hono/dist/jsx/hooks/index.js +16 -13
- package/node_modules/hono/dist/middleware/cache/index.js +103 -8
- package/node_modules/hono/dist/middleware/compress/index.js +5 -0
- package/node_modules/hono/dist/middleware/cors/index.js +2 -2
- package/node_modules/hono/dist/middleware/etag/index.js +1 -1
- package/node_modules/hono/dist/middleware/jwk/jwk.js +9 -4
- package/node_modules/hono/dist/middleware/jwt/jwt.js +9 -4
- package/node_modules/hono/dist/middleware/language/language.js +10 -6
- package/node_modules/hono/dist/middleware/method-not-allowed/index.js +68 -0
- package/node_modules/hono/dist/middleware/secure-headers/secure-headers.js +10 -4
- package/node_modules/hono/dist/request.js +8 -10
- package/node_modules/hono/dist/router/reg-exp-router/node.js +55 -56
- package/node_modules/hono/dist/router/reg-exp-router/router.js +64 -85
- package/node_modules/hono/dist/router/reg-exp-router/trie.js +13 -5
- package/node_modules/hono/dist/router.js +1 -1
- package/node_modules/hono/dist/types/adapter/aws-lambda/types.d.ts +9 -0
- package/node_modules/hono/dist/types/client/types.d.ts +1 -1
- package/node_modules/hono/dist/types/hono-base.d.ts +4 -3
- package/node_modules/hono/dist/types/jsx/base.d.ts +4 -2
- package/node_modules/hono/dist/types/jsx/dom/index.d.ts +5 -5
- package/node_modules/hono/dist/types/jsx/dom/intrinsic-element/components.d.ts +2 -2
- package/node_modules/hono/dist/types/jsx/dom/server.d.ts +5 -5
- package/node_modules/hono/dist/types/jsx/hooks/index.d.ts +8 -6
- package/node_modules/hono/dist/types/jsx/index.d.ts +5 -5
- package/node_modules/hono/dist/types/middleware/cache/index.d.ts +6 -4
- package/node_modules/hono/dist/types/middleware/cors/index.d.ts +1 -1
- package/node_modules/hono/dist/types/middleware/jsx-renderer/index.d.ts +2 -2
- package/node_modules/hono/dist/types/middleware/jwk/jwk.d.ts +2 -0
- package/node_modules/hono/dist/types/middleware/jwt/jwt.d.ts +2 -0
- package/node_modules/hono/dist/types/middleware/method-not-allowed/index.d.ts +49 -0
- package/node_modules/hono/dist/types/router/reg-exp-router/node.d.ts +1 -1
- package/node_modules/hono/dist/types/router/reg-exp-router/trie.d.ts +2 -1
- package/node_modules/hono/dist/types/router.d.ts +1 -1
- package/node_modules/hono/dist/types/utils/headers.d.ts +2 -2
- package/node_modules/hono/dist/types/utils/url.d.ts +1 -0
- package/node_modules/hono/dist/utils/accept.js +1 -1
- package/node_modules/hono/dist/utils/cookie.js +4 -3
- package/node_modules/hono/dist/utils/url.js +6 -7
- package/node_modules/hono/package.json +10 -3
- package/node_modules/ip-address/README.md +146 -126
- package/node_modules/ip-address/dist/common.d.ts +29 -0
- package/node_modules/ip-address/dist/common.js +44 -5
- package/node_modules/ip-address/dist/common.js.map +1 -1
- package/node_modules/ip-address/dist/ipv4.d.ts +8 -1
- package/node_modules/ip-address/dist/ipv4.js +24 -20
- package/node_modules/ip-address/dist/ipv4.js.map +1 -1
- package/node_modules/ip-address/dist/ipv6.d.ts +68 -3
- package/node_modules/ip-address/dist/ipv6.js +180 -53
- package/node_modules/ip-address/dist/ipv6.js.map +1 -1
- package/node_modules/ip-address/dist/v4/constants.js +5 -1
- package/node_modules/ip-address/dist/v4/constants.js.map +1 -1
- package/node_modules/ip-address/dist/v6/constants.js +3 -2
- package/node_modules/ip-address/dist/v6/constants.js.map +1 -1
- package/node_modules/ip-address/package.json +6 -4
- package/package.json +23 -11
- package/platform-smoke.config.mjs +1 -1
- package/scripts/build.mjs +126 -0
- package/scripts/cloud-runtime-smoke.mjs +3 -1
- package/scripts/debug-provider-events.mjs +3 -1
- package/scripts/debug-sdk-events.mjs +1 -1
- package/scripts/isolated-cursor-smoke.sh +5 -4
- package/scripts/lib/cloud-smoke-cleanup-evidence.mjs +1 -1
- package/scripts/lib/cursor-visual-render.mjs +1 -1
- package/scripts/lib/ensure-built.mjs +16 -0
- package/scripts/lib/local-resume-smoke-harness.mjs +1 -1
- package/scripts/local-resume-smoke.mjs +3 -1
- package/scripts/platform-smoke/card-detect.mjs +1 -1
- package/scripts/platform-smoke/live-suite-runner.mjs +16 -40
- package/scripts/platform-smoke/platform-build-windows.ps1 +1 -1
- package/scripts/platform-smoke/render-ansi.mjs +1 -1
- package/scripts/platform-smoke/scenarios.mjs +1 -1
- package/scripts/platform-smoke/targets.mjs +2 -2
- package/scripts/platform-smoke.mjs +5 -5
- package/scripts/prepare.mjs +102 -0
- package/scripts/refresh-cursor-model-snapshots.mjs +16 -7
- package/scripts/steering-rpc-smoke.mjs +4 -2
- package/scripts/tmux-live-smoke.sh +11 -11
- package/scripts/visual-tui-smoke-self-test.mjs +4 -1
- package/scripts/visual-tui-smoke.mjs +51 -7
- package/shared/cursor-model-selection-identities.d.mts +21 -0
- package/shared/cursor-model-selection-identities.mjs +95 -0
- package/src/bundled-context-windows.ts +21 -12
- package/src/context.ts +1 -1
- package/src/cursor-agents-context-registration.ts +2 -2
- package/src/cursor-agents-context.ts +0 -2
- package/src/cursor-api-key.ts +5 -4
- package/src/cursor-cloud-reporting.ts +23 -2
- package/src/cursor-context-tools.ts +1 -1
- package/src/cursor-display-only-trace.ts +1 -1
- package/src/cursor-fallback-models.generated.ts +1726 -824
- package/src/cursor-live-run-accounting.ts +1 -1
- package/src/cursor-live-run-coordinator.ts +2 -1
- package/src/cursor-native-replay-routing.ts +1 -1
- package/src/cursor-native-tool-display-registration.ts +10 -11
- package/src/cursor-partial-content-emitter.ts +1 -1
- package/src/cursor-pi-tool-bridge-mcp.ts +1 -1
- package/src/cursor-pi-tool-bridge-run.ts +1 -1
- package/src/cursor-pi-tool-bridge-types.ts +1 -1
- package/src/cursor-provider-errors.ts +1 -1
- package/src/cursor-provider-lazy.ts +6 -5
- package/src/cursor-provider-live-run-drain.ts +2 -1
- package/src/cursor-provider-overflow.ts +1 -1
- package/src/cursor-provider-run-finalizer.ts +2 -1
- package/src/cursor-provider-turn-coordinator.ts +1 -1
- package/src/cursor-provider-turn-finalize.ts +12 -0
- package/src/cursor-provider-turn-lifecycle-emitter.ts +1 -1
- package/src/cursor-provider-turn-prepare.ts +1 -1
- package/src/cursor-provider-turn-types.ts +3 -1
- package/src/cursor-provider.ts +1 -1
- package/src/cursor-run-final-text.ts +1 -1
- package/src/cursor-sdk-billed-usage.ts +107 -0
- package/src/cursor-sdk-event-debug.ts +1 -1
- package/src/cursor-sdk-process-error-guard.ts +6 -4
- package/src/cursor-session-agent-lifecycle.ts +8 -9
- package/src/cursor-session-agent-resume.ts +23 -0
- package/src/cursor-session-agent.ts +1 -1
- package/src/cursor-session-compaction-prep.ts +4 -0
- package/src/cursor-session-send-policy.ts +1 -1
- package/src/cursor-tool-manifest.ts +1 -1
- package/src/cursor-usage-accounting.ts +71 -10
- package/src/index.ts +1 -1
- package/src/model-discovery.ts +32 -89
- package/tsconfig.build.json +8 -0
- package/tsconfig.json +16 -0
- package/node_modules/cross-spawn/node_modules/which/CHANGELOG.md +0 -166
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,90 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.3.6 - 2026-08-18
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- Isolate `smoke:visual` captures from the host: pi runs with `PI_CODING_AGENT_DIR=<out-dir>/pi-agent` (seeded `auth.json`, `quietStartup`, telemetry off), `PI_OFFLINE=1`, and `PI_SKIP_VERSION_CHECK=1`, so host extensions, skills, MCP config, update banners, and package-update notices no longer pollute visual evidence.
|
|
8
|
+
- Start the visual-smoke tmux session in `--cwd` with a non-login shell, eliminating `shell-init: getcwd` noise from a stale tmux-server working directory.
|
|
9
|
+
- Forward `--session-id` to pi only when explicitly provided, so fresh captures no longer show the new-session warning line; the HTML render labels pi-assigned sessions instead of failing.
|
|
10
|
+
|
|
11
|
+
## 0.3.5 - 2026-08-18
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
|
|
15
|
+
- Keep billed `getUsage()` rows as spend only. Occupancy `totalTokens` uses local turn-ended usage only when it is below the latest compaction `tokensBefore`, so a stale or cumulative Cursor total cannot restick the footer or retrigger auto-compact (#204).
|
|
16
|
+
- Leave local-resume persist suppressed across any `turn_end` that fires during compaction summarization; only `session_compact` clears the guard (#223).
|
|
17
|
+
|
|
18
|
+
## 0.3.4 - 2026-08-18
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
|
|
22
|
+
- Pin the runtime to exact `@cursor/sdk@1.0.27` and recapture installed-package ripgrep, stalled-connection, HTTP/1.1, PR-control, closed-writable, and `getUsage` contracts against that pin.
|
|
23
|
+
- Refresh the 37-model Cursor fallback catalog and checkpoint-derived context-window snapshot from the live `@cursor/sdk@1.0.27` runtime, including Grok 4.6.
|
|
24
|
+
- Make `cursor/grok-4.6` the recommended local/smoke default (`:slow` for live evidence). Composer 2.5 remains in the catalog.
|
|
25
|
+
|
|
26
|
+
### Added
|
|
27
|
+
|
|
28
|
+
- Apply billed `Agent.getUsage()` spend to pi assistant usage for local and cloud turns. Local billed rows are selected by unseen usage UUIDs (never by a client-minted `run-*` id). Cloud reports prefer mapped `AgentUsage` and keep the REST `/v1/agents/:id/usage` fallback.
|
|
29
|
+
|
|
30
|
+
### Fixed
|
|
31
|
+
|
|
32
|
+
- Keep billed token spend when cumulative `inputTokens + outputTokens` exceeds the model context window, while occupancy `totalTokens` still uses in-window turn-ended occupancy or the post-compaction estimate floor.
|
|
33
|
+
- Ignore assistant occupancy at or before the latest `compactionSummary`, and ignore measurements at or above that summary's `tokensBefore`, so split-turn keep cannot restick the footer at the pre-compaction watermark.
|
|
34
|
+
- Drop compaction-summarizer local-resume handles: `session_before_compact` suppresses persist, and `session_compact` clears any pending handle so the first later `turn_end` cannot flush the one-message summarizer lineage (#223).
|
|
35
|
+
- Write smoke self-test fake `pi` helpers as ESM so Node 24 shebang execution can dump env without `require`.
|
|
36
|
+
|
|
37
|
+
## 0.3.3 - 2026-08-14
|
|
38
|
+
|
|
39
|
+
### Changed
|
|
40
|
+
|
|
41
|
+
- Hardened the precompiled import guard for legacy and future Pi package aliases plus `createRequire()` / `require.resolve()` escape hatches, while preserving the intentional Cursor SDK ripgrep resolution path.
|
|
42
|
+
|
|
43
|
+
## 0.3.2 - 2026-08-14
|
|
44
|
+
|
|
45
|
+
### Fixed
|
|
46
|
+
|
|
47
|
+
- Keep every Cursor runtime subtree that imports Pi host peers in Pi's static extension graph, preventing precompiled native `import()` from bypassing Pi's peer resolver after install-time dev-dependency pruning. This restores Cursor startup, native tool registration, provider turns, session-agent lifecycle, compaction, AGENTS.md deduplication, and stored Pi credential lookup from a pruned install.
|
|
48
|
+
- Retain safe lazy boundaries for the installed Cursor SDK, SQLite store, MCP bridge implementation, and generated fallback catalog, with an import-graph regression test that rejects future native dynamic imports reaching Pi host peers.
|
|
49
|
+
|
|
50
|
+
## 0.3.1 - 2026-08-14
|
|
51
|
+
|
|
52
|
+
### Changed
|
|
53
|
+
|
|
54
|
+
- `scripts/build.mjs` now reaps `dist.staging.<pid>` directories stranded by dead builds (SIGKILL or crash mid-emit) at the start of every build. Only pids already gone at the signal-0 probe are eligible; pid reuse in the tiny probe-to-remove window remains an inherent limitation. Reaping is best-effort: an unreapable strand warns instead of failing the build.
|
|
55
|
+
- `dist/` is now published by retrying this build's own `rename` instead of waiting on another build. A rename failure yields only when `dist/` exists and is non-empty (an existence check, not an errno check, so platforms that report a different code for rename-onto-existing-directory still behave correctly); otherwise the staging tree is retained and the rename retried, so this build can publish its own output rather than wait on a concurrent winner's scheduling. This closes the review-identified windows where a losing build could exit 1 while a concurrent winner was mid-swap or descheduled.
|
|
56
|
+
- `scripts/prepare.mjs` forwards build output on success too, so install-time diagnostics such as the concurrent-swap race-loss warning are no longer swallowed. If both the build and the final dev-dependency prune fail, the prune warning no longer masks the original build error (and may leave the dev toolchain for manual cleanup).
|
|
57
|
+
- New automated coverage for the staging swap: failed TypeScript emits preserve the previous `dist/`; successful builds purge stale files; dead-pid staging dirs are reaped while live ones survive; the real-process smoke narrows from three twelve-wide rounds to one four-way round; empty directories are not accepted as winners; slow winners cannot time out another build; and publish failures exhaust a bounded retry, fail loudly, and may leave `dist/` absent after removing the old output.
|
|
58
|
+
|
|
59
|
+
## 0.3.0 - 2026-08-13
|
|
60
|
+
|
|
61
|
+
### Changed
|
|
62
|
+
|
|
63
|
+
- The Pi extension manifest now loads precompiled `dist/index.js` instead of transpiling `src/index.ts` through jiti. This reduces load cost on cold starts and after cache invalidation (fresh installs, `pi update`, cache eviction); warm starts with a hot jiti cache were already near parity. A `prepare` lifecycle script builds `dist/` on install and update (including Pi's `npm install --omit=dev` flow) and prunes the dev toolchain back out afterwards.
|
|
64
|
+
|
|
65
|
+
## 0.2.0 - 2026-08-06
|
|
66
|
+
|
|
67
|
+
### Added
|
|
68
|
+
|
|
69
|
+
- Add a dated, hash-verified evidence bundle for Cursor's persisted system messages and reconstructed tool guidance for Grok 4.5, Claude Opus/Fable 5, and GPT-5.6 Sol/Terra/Luna.
|
|
70
|
+
|
|
71
|
+
### Changed
|
|
72
|
+
|
|
73
|
+
- Require Pi 0.84.0 or later, pin the local Pi validation packages to exact 0.84.0 with TypeBox 1.3.7, move pi-ai imports from the temporary compatibility entrypoint to the supported root API, and update test harness contexts for Pi's scoped-model and native-provider registration types.
|
|
74
|
+
- Bound Vitest concurrency to four workers so process and filesystem contract tests remain reliable on high-core platform-smoke hosts.
|
|
75
|
+
- Refresh the 34-model Cursor fallback catalog and checkpoint-derived context-window snapshot from the live `@cursor/sdk` 1.0.23 runtime.
|
|
76
|
+
|
|
77
|
+
### Security
|
|
78
|
+
|
|
79
|
+
- Refresh vulnerable transitive releases within their existing ranges: bundled Hono, fast-uri, and ip-address plus development-only PostCSS and protobufjs. The remaining production audit findings are confined to the pinned Cursor SDK → ConnectRPC → undici chain, which has no compatible fix.
|
|
80
|
+
|
|
81
|
+
### Fixed
|
|
82
|
+
|
|
83
|
+
- Normalize checkpoint context-window keys to current selectable model identities, collapse redundant default `:fast`/`:slow` aliases, reject conflicting equivalent selections, remove stale or ambiguous aliases, and reuse base-model context evidence for unobserved equivalent aliases.
|
|
84
|
+
- Give Windows platform-build checks the same 15-second Vitest scheduling headroom as the full Windows test run, while preserving normal local test timeouts.
|
|
85
|
+
- Pass live PTY smoke prompts as direct Node argv through Pi's interactive initial-message contract, isolate unrelated startup probes with `PI_OFFLINE=1`, and keep final markers out of prompt echoes.
|
|
86
|
+
- Run required platform targets sequentially so concurrent VM/container load and Cursor API calls cannot starve otherwise healthy smoke lanes.
|
|
87
|
+
|
|
3
88
|
## 0.1.62 - 2026-07-29
|
|
4
89
|
|
|
5
90
|
### Added
|
package/README.md
CHANGED
|
@@ -41,7 +41,7 @@ pi install https://github.com/fitchmultz/pi-cursor-sdk
|
|
|
41
41
|
2. Start pi with a Cursor model:
|
|
42
42
|
|
|
43
43
|
```bash
|
|
44
|
-
pi --model cursor/
|
|
44
|
+
pi --model cursor/grok-4.6
|
|
45
45
|
```
|
|
46
46
|
|
|
47
47
|
3. In pi, run `/login`, choose `Use an API key`, choose `Cursor`, and paste your Cursor SDK API key.
|
|
@@ -51,10 +51,10 @@ If pi started without a key, run `/cursor-refresh-models` after `/login` to refr
|
|
|
51
51
|
## Requirements
|
|
52
52
|
|
|
53
53
|
- Node.js 22.19+
|
|
54
|
-
-
|
|
54
|
+
- Pi 0.84.0 or later; pi core peer metadata remains optional and uses `"*"` ranges per Pi package guidance
|
|
55
55
|
- a Cursor SDK API key saved through `/login`, available as `CURSOR_API_KEY`, or passed with pi's `--api-key`
|
|
56
56
|
|
|
57
|
-
No global `@cursor/sdk` install is required. This package depends on exact `@cursor/sdk@1.0.
|
|
57
|
+
No global `@cursor/sdk` install is required. This package depends on exact `@cursor/sdk@1.0.27`, so normal package installation brings in the SDK version this extension was built and tested against. Cursor SDK 1.0.27 declares its Node ConnectRPC transport dependency directly, so npm installs place `@connectrpc/connect-node` where the SDK can resolve it. The extension intentionally does not bundle `@cursor/sdk` or its platform packages, because packing from one maintainer OS can otherwise ship the wrong optional SDK binary for another OS. Cursor SDK 1.0.27 keeps the older `sqlite3 -> node-gyp@8` dependency chain out of the runtime tree, so deprecated install warnings for `inflight`, `rimraf`, `glob@7`, `npmlog`, `gauge`, `are-we-there-yet`, and `tar@6` from that chain are not expected. Older Pi and Cursor SDK compatibility paths are not maintained.
|
|
58
58
|
|
|
59
59
|
## Install
|
|
60
60
|
|
|
@@ -78,10 +78,10 @@ Use `-l` if you want the package recorded in the current project's `.pi/settings
|
|
|
78
78
|
pi install -l npm:pi-cursor-sdk
|
|
79
79
|
```
|
|
80
80
|
|
|
81
|
-
Pi 0.
|
|
81
|
+
Pi 0.84.0 loads project-local extensions only after project trust is resolved, so this extension cannot observe that trust event. When a project-local install needs to read or write `.pi/cursor-sdk.json`, start every such run with explicit approval:
|
|
82
82
|
|
|
83
83
|
```bash
|
|
84
|
-
pi --approve --model cursor/
|
|
84
|
+
pi --approve --model cursor/grok-4.6
|
|
85
85
|
```
|
|
86
86
|
|
|
87
87
|
Without `--approve`, the project-local extension still runs after Pi trusts the project, but it ignores `.pi/cursor-sdk.json` and rejects `--save-project`; user config remains available.
|
|
@@ -91,10 +91,12 @@ Without `--approve`, the project-local extension still runs after Pi trusts the
|
|
|
91
91
|
For development from this repository:
|
|
92
92
|
|
|
93
93
|
```bash
|
|
94
|
-
npm install
|
|
95
|
-
pi --approve -e . --model cursor/
|
|
94
|
+
npm install # runs prepare, which compiles src/ into dist/ (the manifest entry pi loads)
|
|
95
|
+
pi --approve -e . --model cursor/grok-4.6
|
|
96
96
|
```
|
|
97
97
|
|
|
98
|
+
After editing `src/`, run `npm run build` before the next `pi -e .` run, or pi loads the previous build.
|
|
99
|
+
|
|
98
100
|
## Configure your Cursor SDK API key
|
|
99
101
|
|
|
100
102
|
`pi-cursor-sdk` passes an explicit API key to the Cursor SDK. It does **not** reuse Cursor Agent CLI login, Cursor Desktop login, or Cursor subscription/OAuth state shown by `agent status`.
|
|
@@ -104,7 +106,7 @@ Use either a user API key from Cursor Dashboard → API Keys or a service accoun
|
|
|
104
106
|
Preferred setup:
|
|
105
107
|
|
|
106
108
|
```bash
|
|
107
|
-
pi --model cursor/
|
|
109
|
+
pi --model cursor/grok-4.6
|
|
108
110
|
```
|
|
109
111
|
|
|
110
112
|
Then, inside pi:
|
|
@@ -123,13 +125,13 @@ Environment setup:
|
|
|
123
125
|
|
|
124
126
|
```bash
|
|
125
127
|
export CURSOR_API_KEY="your-key"
|
|
126
|
-
pi --model cursor/
|
|
128
|
+
pi --model cursor/grok-4.6
|
|
127
129
|
```
|
|
128
130
|
|
|
129
131
|
One-shot setup:
|
|
130
132
|
|
|
131
133
|
```bash
|
|
132
|
-
pi --api-key "your-key" --model cursor/
|
|
134
|
+
pi --api-key "your-key" --model cursor/grok-4.6 --cursor-no-fast -p "Say ok only."
|
|
133
135
|
```
|
|
134
136
|
|
|
135
137
|
Startup discovery intentionally does not parse Pi CLI arguments. It uses the stored `cursor` key in `~/.pi/agent/auth.json`, then `CURSOR_API_KEY`; without either, the bundled fallback catalog registers. Provider turns still receive Pi's resolved `--api-key`. `/cursor-refresh-models` and `/cursor-cloud` mutations ask Pi's ModelRegistry for provider `cursor`, so command-time auth follows Pi's provider-scoped resolution and is normalized through `CURSOR_API_KEY` placeholders before reaching the Cursor SDK.
|
|
@@ -140,10 +142,10 @@ To avoid a live `Cursor.models.list` network round-trip on every pi startup, the
|
|
|
140
142
|
|
|
141
143
|
```bash
|
|
142
144
|
# Cache lifetime in milliseconds (default 86400000 = 24h).
|
|
143
|
-
PI_CURSOR_SDK_MODEL_CACHE_TTL_MS=3600000 pi --model cursor/
|
|
145
|
+
PI_CURSOR_SDK_MODEL_CACHE_TTL_MS=3600000 pi --model cursor/grok-4.6
|
|
144
146
|
|
|
145
147
|
# Disable the cache and always discover live.
|
|
146
|
-
PI_CURSOR_SDK_DISABLE_MODEL_CACHE=1 pi --model cursor/
|
|
148
|
+
PI_CURSOR_SDK_DISABLE_MODEL_CACHE=1 pi --model cursor/grok-4.6
|
|
147
149
|
```
|
|
148
150
|
|
|
149
151
|
Do not store the API key in `~/.pi/agent/cursor-sdk.json`. That file is only for non-secret extension state such as Cursor fast defaults. `PATH` is only for executable lookup and should not contain the API key.
|
|
@@ -165,7 +167,7 @@ Expected behavior:
|
|
|
165
167
|
Smoke test:
|
|
166
168
|
|
|
167
169
|
```bash
|
|
168
|
-
pi --model cursor/
|
|
170
|
+
pi --model cursor/grok-4.6 --cursor-no-fast --no-session --mode json \
|
|
169
171
|
-p "Reply exactly PI_CURSOR_MODEL_OK and nothing else."
|
|
170
172
|
```
|
|
171
173
|
|
|
@@ -176,7 +178,7 @@ Expected: the final assistant text is `PI_CURSOR_MODEL_OK`. If auth is missing o
|
|
|
176
178
|
Choose Cursor models interactively with `/model`, or pass a model on the command line:
|
|
177
179
|
|
|
178
180
|
```bash
|
|
179
|
-
pi --model cursor/
|
|
181
|
+
pi --model cursor/grok-4.6
|
|
180
182
|
pi --model cursor/gpt-5.5@1m
|
|
181
183
|
pi --model cursor/gpt-5.5@272k
|
|
182
184
|
pi --model cursor/claude-opus-4-8@300k
|
|
@@ -198,7 +200,7 @@ pi --model cursor/claude-opus-4-7@1m:max
|
|
|
198
200
|
pi --model cursor/gpt-5.5@1m --thinking medium
|
|
199
201
|
```
|
|
200
202
|
|
|
201
|
-
Cursor `context` becomes a pi-visible model variant because it changes pi's native `contextWindow`. For models that expose Cursor's boolean `fast` parameter, the extension also registers virtual `:fast` and `:slow` model aliases such as `cursor/
|
|
203
|
+
Cursor `context` becomes a pi-visible model variant because it changes pi's native `contextWindow`. For models that expose Cursor's boolean `fast` parameter, the extension also registers virtual `:fast` and `:slow` model aliases such as `cursor/grok-4.6:slow` and `cursor/gpt-5.5@1m:fast`. Those aliases are selection-only controls for subagents and workflow-spawned agents: they send the same Cursor SDK model ID plus an explicit `fast=true` or `fast=false` param, and they take precedence over saved `/cursor-fast` session/global defaults. Cursor SDK conversation mode remains extension state, not model identity. Alias model IDs use their selected SDK ID for Cursor-only state such as fast defaults, with read fallback for older defaults keyed by the underlying Cursor base model.
|
|
202
204
|
|
|
203
205
|
## Thinking support
|
|
204
206
|
|
|
@@ -233,13 +235,13 @@ For one run, force fast on or off without changing saved defaults:
|
|
|
233
235
|
|
|
234
236
|
```bash
|
|
235
237
|
pi --model cursor/gpt-5.5@1m --cursor-fast -p "Say ok only"
|
|
236
|
-
pi --model cursor/
|
|
238
|
+
pi --model cursor/grok-4.6 --cursor-no-fast -p "Say ok only"
|
|
237
239
|
```
|
|
238
240
|
|
|
239
241
|
For per-agent control, select the virtual model alias instead of mutating the shared saved default:
|
|
240
242
|
|
|
241
243
|
```bash
|
|
242
|
-
pi --model cursor/
|
|
244
|
+
pi --model cursor/grok-4.6:slow -p "Say ok only"
|
|
243
245
|
pi --model cursor/gpt-5.5@1m:fast -p "Say ok only"
|
|
244
246
|
```
|
|
245
247
|
|
|
@@ -269,8 +271,8 @@ Cursor SDK conversation mode is Cursor-only extension state. It is not a pi mode
|
|
|
269
271
|
Default mode is `agent`. Start a one-shot run in a specific mode:
|
|
270
272
|
|
|
271
273
|
```bash
|
|
272
|
-
pi --model cursor/
|
|
273
|
-
pi --model cursor/
|
|
274
|
+
pi --model cursor/grok-4.6 --cursor-mode agent
|
|
275
|
+
pi --model cursor/grok-4.6 --cursor-mode plan
|
|
274
276
|
```
|
|
275
277
|
|
|
276
278
|
Change the session mode interactively:
|
|
@@ -296,15 +298,15 @@ Cursor SDK `plan` mode can produce plan-oriented output and Cursor todo/plan act
|
|
|
296
298
|
Cursor SDK local safety controls stay off by default. Enable them explicitly for one run:
|
|
297
299
|
|
|
298
300
|
```bash
|
|
299
|
-
PI_CURSOR_AUTO_REVIEW=1 PI_CURSOR_SANDBOX=1 pi --model cursor/
|
|
300
|
-
pi --model cursor/
|
|
301
|
+
PI_CURSOR_AUTO_REVIEW=1 PI_CURSOR_SANDBOX=1 pi --model cursor/grok-4.6
|
|
302
|
+
pi --model cursor/grok-4.6 --cursor-auto-review --cursor-sandbox
|
|
301
303
|
```
|
|
302
304
|
|
|
303
305
|
For manual stuck-run recovery only, explicitly force-expire the active persisted local SDK run before sending:
|
|
304
306
|
|
|
305
307
|
```bash
|
|
306
|
-
PI_CURSOR_LOCAL_FORCE=1 pi --model cursor/
|
|
307
|
-
pi --model cursor/
|
|
308
|
+
PI_CURSOR_LOCAL_FORCE=1 pi --model cursor/grok-4.6
|
|
309
|
+
pi --model cursor/grok-4.6 --cursor-local-force
|
|
308
310
|
```
|
|
309
311
|
|
|
310
312
|
This maps to the next actual `agent.send(..., { local: { force: true } })` only. SDK load, agent acquire, prompt preparation, or a pre-send abort does not consume it. A consumed CLI flag is not rearmed by session reload/tree lifecycle events; the environment override remains once per process. It is not a retry loop and does not cancel another live process's existing run handle; use it only when you know the persisted local run is wedged.
|
|
@@ -312,13 +314,13 @@ This maps to the next actual `agent.send(..., { local: { force: true } })` only.
|
|
|
312
314
|
Branch-scoped local resume reattaches to recorded local SDK agents after a pi restart. It is on by default for local runtime and records agent IDs plus their SDK store identity only in pi session custom entries, never user/project config. Independently of resume, each local agent whose send is initiated is also recorded once per native pi session as a best-effort non-resumable `cursor-sdk-agent-lineage` custom entry at the `Agent.send()` boundary for forensic lineage; cloned/forked sessions record their own lineage under their new pi session ID. Disable resume per run with CLI/env, or persist an opt-out in config:
|
|
313
315
|
|
|
314
316
|
```bash
|
|
315
|
-
pi --model cursor/
|
|
316
|
-
PI_CURSOR_LOCAL_RESUME=0 pi --model cursor/
|
|
317
|
+
pi --model cursor/grok-4.6 --cursor-no-local-resume
|
|
318
|
+
PI_CURSOR_LOCAL_RESUME=0 pi --model cursor/grok-4.6
|
|
317
319
|
```
|
|
318
320
|
|
|
319
321
|
Resume is strict: the current pi session file/id, branch path prefix, cwd/repo root, model/API/tool-surface pool key, SDK store identity, and compaction generation must match. Each persisted pi session gets a SQLite store under `<getDefaultSdkStateRoot(cwd)>/pi-sessions/<session-hash>/`, and that same store is used for create/resume, transcript reads, checkpoint lookup, and exact-ID cleanup so parallel pi sessions do not contend on one workspace `index.db`. Fileless sessions use a unique OS-temporary store per acquisition, remove it on graceful disposal, and start a fresh agent after invalidation instead of reopening a disposed temporary store. Legacy resume entries still try the SDK's default workspace store; if that resume fails or the agent is later replaced, the new agent moves to the per-session store. A trailing user message already present at process startup is crash-ambiguous and invalidates the old handle; only a user message appended in the current process may span a recorded handle, preventing restart from resending an already-submitted prompt. A successful process reattachment bootstraps the current pi transcript once while retaining the resumed Cursor agent's native state; later in-process turns remain incremental. If `Agent.resume()` fails, pi bootstraps a new local Cursor agent from the current transcript and streams one display-only continuity note. Superseded local agents can be cleaned up explicitly with `/cursor-local-resume-cleanup --dry-run` and `/cursor-local-resume-cleanup --yes`; cleanup only deletes exact recorded `agent-*` IDs from their recorded store. Cloud resume remains disabled; `/cursor-cloud list|archive|delete` only manages recorded cloud agents.
|
|
320
322
|
|
|
321
|
-
Config can also set non-secret defaults in `~/.pi/agent/cursor-sdk.json` or trusted `.pi/cursor-sdk.json`. Project config activates only when Pi's project-trust flow reached this extension and approved the project, or the run started with explicit `--approve`; Pi's implicit trust for a project with no recognized resources is not enough. Because Pi 0.
|
|
323
|
+
Config can also set non-secret defaults in `~/.pi/agent/cursor-sdk.json` or trusted `.pi/cursor-sdk.json`. Project config activates only when Pi's project-trust flow reached this extension and approved the project, or the run started with explicit `--approve`; Pi's implicit trust for a project with no recognized resources is not enough. Because Pi 0.84.0 loads project-local package extensions after the trust event, `pi install -l` users must pass `--approve` on every run that reads or writes `.pi/cursor-sdk.json`. A trust resource added after trust resolution requires restarting pi. `/cursor-runtime ... --save-project` requires the same trust provenance and does not create Pi trust resources automatically. Explicit runtime, fast-default, and HTTP transport saves preserve unrecognized fields, reject malformed or non-object JSON without rewriting it, and serialize concurrent writers. A completed global preference write is retained if Pi's subsequent session-journal append fails, because Pi may already have mutated the in-memory branch; the command reports that partial journal failure and ignores the uncertain session entry until a later successful save or session restart. If a process is force-killed during the tiny update window, the next save reports the `.lock` path; remove it only after confirming no pi process is writing that config.
|
|
322
324
|
|
|
323
325
|
```json
|
|
324
326
|
{
|
|
@@ -348,7 +350,7 @@ Project config may save a cloud runtime default but not first-use acknowledgemen
|
|
|
348
350
|
Cursor Cloud pull-request controls are strictly opt-in. Omit them to preserve the Cursor SDK's default behavior; when omitted, the extension sends neither SDK field.
|
|
349
351
|
|
|
350
352
|
```bash
|
|
351
|
-
pi --model cursor/
|
|
353
|
+
pi --model cursor/grok-4.6 --cursor-runtime cloud --cursor-cloud-ack \
|
|
352
354
|
--cursor-cloud-repo https://github.com/your-org/your-repo \
|
|
353
355
|
--cursor-cloud-branch main \
|
|
354
356
|
--cursor-cloud-auto-create-pr --cursor-cloud-skip-reviewer-request
|
|
@@ -358,7 +360,7 @@ PI_CURSOR_CLOUD_REPO=https://github.com/your-org/your-repo \
|
|
|
358
360
|
PI_CURSOR_CLOUD_BRANCH=main \
|
|
359
361
|
PI_CURSOR_CLOUD_AUTO_CREATE_PR=1 \
|
|
360
362
|
PI_CURSOR_CLOUD_SKIP_REVIEWER_REQUEST=1 \
|
|
361
|
-
pi --model cursor/
|
|
363
|
+
pi --model cursor/grok-4.6 --cursor-runtime cloud
|
|
362
364
|
```
|
|
363
365
|
|
|
364
366
|
User config uses `cloud.autoCreatePR` and `cloud.skipReviewerRequest`:
|
|
@@ -462,35 +464,35 @@ Bridge controls:
|
|
|
462
464
|
|
|
463
465
|
```bash
|
|
464
466
|
# Keep the pi bridge but disable Cursor's interactive question tool.
|
|
465
|
-
PI_CURSOR_ASK_QUESTION=0 pi --model cursor/
|
|
467
|
+
PI_CURSOR_ASK_QUESTION=0 pi --model cursor/grok-4.6
|
|
466
468
|
|
|
467
469
|
# Roll back to Cursor SDK tools/settings/MCP only; do not expose active pi tools through the bridge.
|
|
468
|
-
PI_CURSOR_PI_TOOL_BRIDGE=0 pi --model cursor/
|
|
470
|
+
PI_CURSOR_PI_TOOL_BRIDGE=0 pi --model cursor/grok-4.6
|
|
469
471
|
|
|
470
472
|
# Opt in to also expose overlapping pi tool names through the bridge.
|
|
471
|
-
PI_CURSOR_EXPOSE_BUILTIN_TOOLS=1 pi --model cursor/
|
|
473
|
+
PI_CURSOR_EXPOSE_BUILTIN_TOOLS=1 pi --model cursor/grok-4.6
|
|
472
474
|
|
|
473
475
|
# Override Cursor SDK MCP tool-call timeout, including bridged pi tools and configured Cursor MCP servers.
|
|
474
|
-
PI_CURSOR_MCP_TOOL_TIMEOUT_SECONDS=7200 pi --model cursor/
|
|
475
|
-
PI_CURSOR_MCP_TOOL_TIMEOUT_MS=7200000 pi --model cursor/
|
|
476
|
+
PI_CURSOR_MCP_TOOL_TIMEOUT_SECONDS=7200 pi --model cursor/grok-4.6
|
|
477
|
+
PI_CURSOR_MCP_TOOL_TIMEOUT_MS=7200000 pi --model cursor/grok-4.6
|
|
476
478
|
|
|
477
479
|
# Fail a stranded pi bridge CallTool sooner than the effective MCP tool timeout.
|
|
478
|
-
PI_CURSOR_PI_BRIDGE_CALL_TIMEOUT_MS=120000 pi --model cursor/
|
|
480
|
+
PI_CURSOR_PI_BRIDGE_CALL_TIMEOUT_MS=120000 pi --model cursor/grok-4.6
|
|
479
481
|
|
|
480
482
|
# Override known MCP initialize/listTools timeouts on first send (default 10s).
|
|
481
|
-
PI_CURSOR_MCP_CONNECT_TIMEOUT_SECONDS=5 pi --model cursor/
|
|
482
|
-
PI_CURSOR_MCP_CONNECT_TIMEOUT_MS=5000 pi --model cursor/
|
|
483
|
+
PI_CURSOR_MCP_CONNECT_TIMEOUT_SECONDS=5 pi --model cursor/grok-4.6
|
|
484
|
+
PI_CURSOR_MCP_CONNECT_TIMEOUT_MS=5000 pi --model cursor/grok-4.6
|
|
483
485
|
|
|
484
486
|
# Force Cursor SDK local-agent backend streams to HTTP/1.1/SSE instead of HTTP/2.
|
|
485
|
-
env 'PI_CURSOR_HTTP_1_1=true' pi --model cursor/
|
|
487
|
+
env 'PI_CURSOR_HTTP_1_1=true' pi --model cursor/grok-4.6
|
|
486
488
|
# Or toggle it inside an interactive Cursor session.
|
|
487
489
|
/cursor-http on
|
|
488
490
|
|
|
489
491
|
# Disable bootstrap callable-surface manifest (on by default).
|
|
490
|
-
PI_CURSOR_TOOL_MANIFEST=0 pi --model cursor/
|
|
492
|
+
PI_CURSOR_TOOL_MANIFEST=0 pi --model cursor/grok-4.6
|
|
491
493
|
|
|
492
494
|
# Emit scrubbed bridge diagnostics as JSONL to stderr with prefix [pi-cursor-sdk:bridge].
|
|
493
|
-
PI_CURSOR_PI_TOOL_BRIDGE_DEBUG=1 pi --model cursor/
|
|
495
|
+
PI_CURSOR_PI_TOOL_BRIDGE_DEBUG=1 pi --model cursor/grok-4.6
|
|
494
496
|
```
|
|
495
497
|
|
|
496
498
|
On bootstrap sends, a compact **callable tool surfaces** block is injected into the Cursor prompt by default. It reminds the model that Cursor host/configured MCP tools are controlled by Cursor, while pi tool toggles only affect pi tools/bridge exposure; when bridge tools are exposed, it lists the current `pi__*` names. Disable with `PI_CURSOR_TOOL_MANIFEST=0`.
|
|
@@ -505,7 +507,7 @@ On bootstrap sends, a compact **callable tool surfaces** block is injected into
|
|
|
505
507
|
|
|
506
508
|
For Cursor provider/runtime changes, the canonical local release and pre-commit gate is the local platform smoke gate in [Platform smoke](docs/platform-smoke.md): run `npm run smoke:platform:all`, which runs doctor before the target matrix. Cloud-runtime changes must also run `npm run smoke:cloud`. The platform gate validates macOS, Ubuntu, and Windows native through Crabbox using packed installs, a required HTTP/1.1/SSE provider-turn lane, PTY/ConPTY ANSI capture, host-rendered xterm/PNG evidence, JSONL assertions, bridge diagnostics, usage/cache checks, abort cleanup, artifact manifests, and redaction scans. After each platform run, `.artifacts/platform-smoke/latest.json` points to the latest useful evidence paths. Do not mark a release ready with optional, deferred, mostly-passing, or unobserved platform smoke checks outstanding.
|
|
507
509
|
|
|
508
|
-
The older live smoke helpers remain useful for inner-loop debugging and focused visual audits, not as the release gate. Use [Cursor live smoke checklist](docs/cursor-live-smoke-checklist.md), `npm run smoke:visual`, `npm run smoke:live`, or direct `pi --approve -e . --cursor-no-fast --model cursor/
|
|
510
|
+
The older live smoke helpers remain useful for inner-loop debugging and focused visual audits, not as the release gate. Use [Cursor live smoke checklist](docs/cursor-live-smoke-checklist.md), `npm run smoke:visual`, `npm run smoke:live`, or direct `pi --approve -e . --cursor-no-fast --model cursor/grok-4.6` runs when iterating on a specific TUI/card/runtime issue before the full platform gate. `npm run smoke:visual` captures an offscreen PTY rendered through browser/xterm and saved as PNG screenshots with Playwright, or with `agent_browser` from the generated HTML when available. Its default matrix is native replay only: native replay registration is forced on, Cursor setting sources are disabled, the pi bridge is off, overlapping built-in pi tools are not exposed, and inherited Cursor SDK event-debug artifact env is cleared; `--event-debug` writes to a deterministic debug directory under the visual output directory. The visible TUI/output, rendered screenshots, scrubbed diagnostics, and persisted JSONL must agree. See [Cursor testing lessons](docs/cursor-testing-lessons.md) for auth.json seeding, isolated `/tmp` harness layout, JSONL replay-error scans, and other regression traps.
|
|
509
511
|
|
|
510
512
|
### Maintainer Cursor SDK event capture
|
|
511
513
|
|
|
@@ -519,7 +521,7 @@ See [Cursor testing lessons](docs/cursor-testing-lessons.md#cursor-sdk-event-cap
|
|
|
519
521
|
|
|
520
522
|
If startup has no stored `/login` key or `CURSOR_API_KEY`, model discovery fails, or discovery returns no models, the extension registers a bundled fallback snapshot of the latest reviewed Cursor SDK model catalog and notifies interactive users when possible. Pi CLI `--api-key` remains available to provider turns but is not parsed independently during startup discovery.
|
|
521
523
|
|
|
522
|
-
The fallback snapshot includes Composer 2.5 (`composer-2.5` and `composer-2-5`), Composer 2, Cursor's GPT-5.6 Luna/Sol/Terra models, Claude, Gemini, Grok, Kimi, and other model IDs exposed by the reviewed `Cursor.models.list()` output. Pi's separate `openai-codex` catalog is owned by Pi itself; Pi 0.
|
|
524
|
+
The fallback snapshot includes Grok 4.6, Composer 2.5 (`composer-2.5` and `composer-2-5`), Composer 2, Cursor's GPT-5.6 Luna/Sol/Terra models, Claude, Gemini, Grok 4.5, Kimi, and other model IDs exposed by the reviewed `Cursor.models.list()` output. Recommended local/smoke runs use `cursor/grok-4.6`. Pi's separate `openai-codex` catalog is owned by Pi itself; Pi 0.84.0 includes native `gpt-5.6-luna`, `gpt-5.6-sol`, and `gpt-5.6-terra` support. The exact checked-in Cursor snapshot lives in `src/cursor-fallback-models.generated.ts`. A dated maintainer capture documents the assistant-visible [Cursor system prompts and tool guidance](https://github.com/fitchmultz/pi-cursor-sdk/blob/main/docs/evidence/cursor-system-prompts-2026-08-02/README.md) for Grok 4.5, Opus 5, Fable 5, and the GPT-5.6 Sol/Terra/Luna family.
|
|
523
525
|
|
|
524
526
|
Actual Cursor runs still need a key from `/login`, `CURSOR_API_KEY`, or `--api-key`. If you add auth after startup, run `/cursor-refresh-models` to refresh the full live Cursor model catalog without restarting pi.
|
|
525
527
|
|
|
@@ -546,19 +548,19 @@ When a Cursor run fails after auth is configured, pi now surfaces scrubbed provi
|
|
|
546
548
|
|
|
547
549
|
Aborted runs now include a likely cause when determinable, for example `Cancelled: prompt interrupted.` for user cancel or `Cancelled: Cursor SDK run was cancelled.` for SDK-side cancellation.
|
|
548
550
|
|
|
549
|
-
Network failures from the Cursor SDK connect layer (for example `ConnectError: read ETIMEDOUT` or `ConnectError: [aborted] read ECONNRESET`) surface as scrubbed `Network error` messages instead of crashing pi, matching pi's native auto-retry classifier. The exact Cursor SDK 1.0.23-provenance `WriteIterableClosedError: WritableIterable is closed` race is contained for the Pi session lifecycle because controlled-exec can reject after the originating provider turn; Connect/network suppression remains active-turn scoped; raw Cursor SDK `AbortError` DOMExceptions are suppressed while any provider turn or session process-error guard is active (stall/inter-turn timers). Unrelated failures remain fatal. The observed raw `write EPIPE` uncaught exception (SDK 1.0.23 local shell executor writes child stdin without a stream error listener
|
|
551
|
+
Network failures from the Cursor SDK connect layer (for example `ConnectError: read ETIMEDOUT` or `ConnectError: [aborted] read ECONNRESET`) surface as scrubbed `Network error` messages instead of crashing pi, matching pi's native auto-retry classifier. The exact Cursor SDK 1.0.23-provenance `WriteIterableClosedError: WritableIterable is closed` race is contained for the Pi session lifecycle because controlled-exec can reject after the originating provider turn; Connect/network suppression remains active-turn scoped; raw Cursor SDK `AbortError` DOMExceptions are suppressed while any provider turn or session process-error guard is active (stall/inter-turn timers). Unrelated failures remain fatal. The observed raw `write EPIPE` uncaught exception (SDK 1.0.23 local shell executor writes child stdin without a stream error listener; 1.0.27 attaches a no-op listener before that write) is still contained only for that exact one-frame shape and only while a local Cursor provider turn is active; a contained closed pipe marks that turn's pooled/resumable agent transport dead so the next turn recreates it. EPIPE outside an active local turn, and the multi-frame synchronous write-path EPIPE from pi's own piped stdout or a dead terminal, stay fatal. The affected run may still report its underlying transport or tool failure normally. Persistent failures may indicate a transient Cursor service or network issue.
|
|
550
552
|
|
|
551
553
|
You can also restart pi with a key in the same shell or launcher that starts pi:
|
|
552
554
|
|
|
553
555
|
```bash
|
|
554
556
|
export CURSOR_API_KEY="your-key"
|
|
555
|
-
pi --model cursor/
|
|
557
|
+
pi --model cursor/grok-4.6
|
|
556
558
|
```
|
|
557
559
|
|
|
558
560
|
Or run a one-shot command:
|
|
559
561
|
|
|
560
562
|
```bash
|
|
561
|
-
pi --api-key "your-key" --model cursor/
|
|
563
|
+
pi --api-key "your-key" --model cursor/grok-4.6 -p "Say ok only"
|
|
562
564
|
```
|
|
563
565
|
|
|
564
566
|
### `pi --list-models cursor` shows no Cursor models
|
|
@@ -612,13 +614,13 @@ pi extension toggles and pi's MCP catalog do not control Cursor ambient MCP. Loc
|
|
|
612
614
|
The local pi bridge only exposes tools that are active in the current pi session and present in pi's tool registry at Cursor run start. By default, it does not expose overlapping pi tool names that Cursor already has native equivalents for (`read`, `bash`, `write`, `edit`, `grep`, `find`, and `ls`). Opt in if you intentionally want Cursor to see both the Cursor-native tool and an overlapping built-in pi tool:
|
|
613
615
|
|
|
614
616
|
```bash
|
|
615
|
-
PI_CURSOR_EXPOSE_BUILTIN_TOOLS=1 pi --model cursor/
|
|
617
|
+
PI_CURSOR_EXPOSE_BUILTIN_TOOLS=1 pi --model cursor/grok-4.6
|
|
616
618
|
```
|
|
617
619
|
|
|
618
620
|
To disable the bridge for rollback or isolation, start pi with:
|
|
619
621
|
|
|
620
622
|
```bash
|
|
621
|
-
PI_CURSOR_PI_TOOL_BRIDGE=0 pi --model cursor/
|
|
623
|
+
PI_CURSOR_PI_TOOL_BRIDGE=0 pi --model cursor/grok-4.6
|
|
622
624
|
```
|
|
623
625
|
|
|
624
626
|
### First Cursor message is slow (10+ seconds)
|
|
@@ -626,14 +628,14 @@ PI_CURSOR_PI_TOOL_BRIDGE=0 pi --model cursor/composer-2-5
|
|
|
626
628
|
The extension loads Cursor setting sources with `PI_CURSOR_SETTING_SOURCES=all` by default, which includes user MCP servers from `~/.cursor/mcp.json`. On the first send of a session, the Cursor SDK connects to each configured MCP server before streaming a reply. pi-cursor-sdk shortens the known MCP initialize/listTools timeout path to **10 seconds by default** (the raw Cursor SDK default is 60 seconds), so a dead server should fail fast instead of blocking for a full minute. Unknown MCP protocol timeout stacks keep the SDK default instead of being shortened. A slow or unavailable server can still add roughly that connect timeout before the first reply. Tighten further with:
|
|
627
629
|
|
|
628
630
|
```bash
|
|
629
|
-
PI_CURSOR_MCP_CONNECT_TIMEOUT_SECONDS=5 pi --model cursor/
|
|
630
|
-
PI_CURSOR_MCP_CONNECT_TIMEOUT_MS=5000 pi --model cursor/
|
|
631
|
+
PI_CURSOR_MCP_CONNECT_TIMEOUT_SECONDS=5 pi --model cursor/grok-4.6
|
|
632
|
+
PI_CURSOR_MCP_CONNECT_TIMEOUT_MS=5000 pi --model cursor/grok-4.6
|
|
631
633
|
```
|
|
632
634
|
|
|
633
635
|
Workarounds if you do not need user-level MCP in pi:
|
|
634
636
|
|
|
635
637
|
```bash
|
|
636
|
-
PI_CURSOR_SETTING_SOURCES=project,plugins,team pi --model cursor/
|
|
638
|
+
PI_CURSOR_SETTING_SOURCES=project,plugins,team pi --model cursor/grok-4.6
|
|
637
639
|
```
|
|
638
640
|
|
|
639
641
|
Or fix/disable the slow MCP server in Cursor settings. Maintainer timing probe: `npm run debug:mcp-coldstart`.
|
|
@@ -643,14 +645,14 @@ Or fix/disable the slow MCP server in Cursor settings. Maintainer timing probe:
|
|
|
643
645
|
The extension raises Cursor SDK's MCP tool-call timeout from 60 seconds to 3600 seconds by default for Cursor SDK MCP `callTool` requests, including the local pi bridge and configured Cursor MCP servers. For longer local MCP tools, set one override:
|
|
644
646
|
|
|
645
647
|
```bash
|
|
646
|
-
PI_CURSOR_MCP_TOOL_TIMEOUT_SECONDS=7200 pi --model cursor/
|
|
647
|
-
PI_CURSOR_MCP_TOOL_TIMEOUT_MS=7200000 pi --model cursor/
|
|
648
|
+
PI_CURSOR_MCP_TOOL_TIMEOUT_SECONDS=7200 pi --model cursor/grok-4.6
|
|
649
|
+
PI_CURSOR_MCP_TOOL_TIMEOUT_MS=7200000 pi --model cursor/grok-4.6
|
|
648
650
|
```
|
|
649
651
|
|
|
650
652
|
A bridged pi call additionally uses a local deadline capped by that effective MCP timeout. To fail a stranded bridge call sooner without shortening other MCP servers:
|
|
651
653
|
|
|
652
654
|
```bash
|
|
653
|
-
PI_CURSOR_PI_BRIDGE_CALL_TIMEOUT_MS=120000 pi --model cursor/
|
|
655
|
+
PI_CURSOR_PI_BRIDGE_CALL_TIMEOUT_MS=120000 pi --model cursor/grok-4.6
|
|
654
656
|
```
|
|
655
657
|
|
|
656
658
|
### Tool calls appear as a plain text list instead of pi tool cards
|
|
@@ -703,9 +705,11 @@ Local development run:
|
|
|
703
705
|
|
|
704
706
|
```bash
|
|
705
707
|
npm install
|
|
706
|
-
CURSOR_API_KEY="your-key" pi --approve -e . --model cursor/
|
|
708
|
+
CURSOR_API_KEY="your-key" pi --approve -e . --model cursor/grok-4.6
|
|
707
709
|
```
|
|
708
710
|
|
|
711
|
+
After editing `src/`, run `npm run build` before the next `pi -e .` run, or pi loads the previous build.
|
|
712
|
+
|
|
709
713
|
Maintainer design notes live in [`docs/cursor-model-ux-spec.md`](docs/cursor-model-ux-spec.md).
|
|
710
714
|
|
|
711
715
|
## License
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// Generated from Cursor SDK checkpoint tokenDetails.maxTokens on 2026-08-18.
|
|
2
|
+
// Refresh with: npm run refresh:cursor-snapshots -- --write --context-windows ~/.pi/agent/cursor-sdk-context-windows.json
|
|
3
|
+
// Keys are current selectable model IDs. Equivalent default :fast/:slow selections
|
|
4
|
+
// collapse to one key; stale and ambiguous aliases are omitted. Values are observed
|
|
5
|
+
// or conservative default/non-Max-mode limits and may override a catalog context
|
|
6
|
+
// label when the completed SDK checkpoint reports a different effective limit.
|
|
7
|
+
export const BUNDLED_CONTEXT_WINDOWS = {
|
|
8
|
+
"default": 200000,
|
|
9
|
+
"auto-smart": 200000,
|
|
10
|
+
"claude-fable-5@300k": 300000,
|
|
11
|
+
"claude-haiku-4-5": 200000,
|
|
12
|
+
"claude-opus-4-5": 200000,
|
|
13
|
+
"claude-opus-4-8@1m": 300000,
|
|
14
|
+
"composer-2": 200000,
|
|
15
|
+
"composer-2.5": 200000,
|
|
16
|
+
"gemini-2.5-flash": 200000,
|
|
17
|
+
"gemini-3-flash": 200000,
|
|
18
|
+
"gemini-3.1-pro": 200000,
|
|
19
|
+
"gemini-3.5-flash": 200000,
|
|
20
|
+
"gemini-3.6-flash": 200000,
|
|
21
|
+
"gemini-3.7-flash": 200000,
|
|
22
|
+
"glm-5.2": 200000,
|
|
23
|
+
"gpt-5-5@272k": 272000,
|
|
24
|
+
"gpt-5-mini": 272000,
|
|
25
|
+
"gpt-5.1": 272000,
|
|
26
|
+
"gpt-5.2": 272000,
|
|
27
|
+
"gpt-5.3-codex": 272000,
|
|
28
|
+
"gpt-5.4-mini": 272000,
|
|
29
|
+
"gpt-5.4-nano": 272000,
|
|
30
|
+
"gpt-5.5@272k": 272000,
|
|
31
|
+
"gpt-5.6@1m": 272000,
|
|
32
|
+
"grok-4.5": 256000,
|
|
33
|
+
"grok-4.5:slow": 256000,
|
|
34
|
+
"grok-4.6": 256000,
|
|
35
|
+
"kimi-k2.7-code": 200000,
|
|
36
|
+
"kimi-k3": 200000,
|
|
37
|
+
"opus-4.8@1m": 300000,
|
|
38
|
+
"opus-4.8@300k": 300000,
|
|
39
|
+
};
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import { getAgentDir } from "@earendil-works/pi-coding-agent";
|
|
4
|
+
import { BUNDLED_CONTEXT_WINDOWS } from "./bundled-context-windows.js";
|
|
5
|
+
import { asRecord } from "./cursor-record-utils.js";
|
|
6
|
+
const CONTEXT_WINDOW_CACHE_FILE = "cursor-sdk-context-windows.json";
|
|
7
|
+
let userContextWindowOverrideLoadCount = 0;
|
|
8
|
+
function getCachePath() {
|
|
9
|
+
return join(getAgentDir(), CONTEXT_WINDOW_CACHE_FILE);
|
|
10
|
+
}
|
|
11
|
+
function isPositiveInteger(value) {
|
|
12
|
+
return typeof value === "number" && Number.isInteger(value) && value > 0;
|
|
13
|
+
}
|
|
14
|
+
function parseContextWindowCacheFile(value) {
|
|
15
|
+
const record = asRecord(value);
|
|
16
|
+
if (!record)
|
|
17
|
+
return undefined;
|
|
18
|
+
const { contextWindows } = record;
|
|
19
|
+
if (contextWindows === undefined)
|
|
20
|
+
return {};
|
|
21
|
+
const contextWindowRecord = asRecord(contextWindows);
|
|
22
|
+
if (!contextWindowRecord)
|
|
23
|
+
return undefined;
|
|
24
|
+
return {
|
|
25
|
+
contextWindows: Object.fromEntries(Object.entries(contextWindowRecord).filter((entry) => isPositiveInteger(entry[1]))),
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
function loadUserContextWindowOverrides() {
|
|
29
|
+
userContextWindowOverrideLoadCount += 1;
|
|
30
|
+
const path = getCachePath();
|
|
31
|
+
const overrides = new Map();
|
|
32
|
+
if (!existsSync(path))
|
|
33
|
+
return overrides;
|
|
34
|
+
try {
|
|
35
|
+
const parsed = parseContextWindowCacheFile(JSON.parse(readFileSync(path, "utf-8")));
|
|
36
|
+
for (const [modelId, contextWindow] of Object.entries(parsed?.contextWindows ?? {})) {
|
|
37
|
+
overrides.set(modelId, contextWindow);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
return overrides;
|
|
42
|
+
}
|
|
43
|
+
return overrides;
|
|
44
|
+
}
|
|
45
|
+
export function loadContextWindowCache() {
|
|
46
|
+
const cache = new Map(Object.entries(BUNDLED_CONTEXT_WINDOWS));
|
|
47
|
+
for (const [modelId, contextWindow] of loadUserContextWindowOverrides()) {
|
|
48
|
+
cache.set(modelId, contextWindow);
|
|
49
|
+
}
|
|
50
|
+
return cache;
|
|
51
|
+
}
|
|
52
|
+
export function getCachedContextWindowExact(modelId) {
|
|
53
|
+
return loadContextWindowCache().get(modelId);
|
|
54
|
+
}
|
|
55
|
+
export function getCachedContextWindow(modelId) {
|
|
56
|
+
const cache = loadContextWindowCache();
|
|
57
|
+
return cache.get(modelId) ?? cache.get("default");
|
|
58
|
+
}
|
|
59
|
+
export function getCheckpointContextWindow(checkpoint) {
|
|
60
|
+
const tokenDetails = asRecord(checkpoint)?.tokenDetails;
|
|
61
|
+
const maxTokens = asRecord(tokenDetails)?.maxTokens;
|
|
62
|
+
return isPositiveInteger(maxTokens) ? maxTokens : undefined;
|
|
63
|
+
}
|
|
64
|
+
export function saveCachedContextWindow(modelId, contextWindow) {
|
|
65
|
+
if (!isPositiveInteger(contextWindow))
|
|
66
|
+
return;
|
|
67
|
+
const overrides = loadUserContextWindowOverrides();
|
|
68
|
+
const bundledContextWindow = BUNDLED_CONTEXT_WINDOWS[modelId] ?? BUNDLED_CONTEXT_WINDOWS.default;
|
|
69
|
+
if (bundledContextWindow === contextWindow) {
|
|
70
|
+
if (!overrides.has(modelId))
|
|
71
|
+
return;
|
|
72
|
+
overrides.delete(modelId);
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
if (overrides.get(modelId) === contextWindow)
|
|
76
|
+
return;
|
|
77
|
+
overrides.set(modelId, contextWindow);
|
|
78
|
+
}
|
|
79
|
+
const path = getCachePath();
|
|
80
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
81
|
+
const data = {
|
|
82
|
+
contextWindows: Object.fromEntries([...overrides.entries()].sort(([a], [b]) => a.localeCompare(b))),
|
|
83
|
+
};
|
|
84
|
+
writeFileSync(path, `${JSON.stringify(data, null, 2)}\n`, { mode: 0o600 });
|
|
85
|
+
}
|
|
86
|
+
export const __testUtils = {
|
|
87
|
+
getCachePath,
|
|
88
|
+
getUserContextWindowOverrideLoadCount: () => userContextWindowOverrideLoadCount,
|
|
89
|
+
resetUserContextWindowOverrideLoadCount: () => {
|
|
90
|
+
userContextWindowOverrideLoadCount = 0;
|
|
91
|
+
},
|
|
92
|
+
};
|