pi-cursor-sdk 0.1.56 → 0.1.57
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 +45 -1
- package/README.md +100 -28
- package/docs/cursor-live-smoke-checklist.md +7 -7
- package/docs/cursor-model-ux-spec.md +45 -38
- package/docs/cursor-native-tool-replay.md +2 -2
- package/docs/cursor-native-tool-visual-audit.md +1 -1
- package/docs/cursor-testing-lessons.md +20 -7
- package/docs/cursor-tool-surfaces.md +13 -2
- package/docs/platform-smoke-implementation.md +220 -0
- package/docs/platform-smoke.md +183 -247
- package/package.json +38 -6
- package/platform-smoke.config.mjs +5 -1
- package/scripts/cloud-runtime-smoke.d.mts +3 -0
- package/scripts/cloud-runtime-smoke.mjs +502 -0
- package/scripts/debug-provider-events.mjs +7 -2
- package/scripts/isolated-cursor-smoke.sh +4 -6
- package/scripts/lib/cursor-child-process.d.mts +1 -0
- package/scripts/lib/cursor-child-process.mjs +137 -7
- package/scripts/lib/local-resume-smoke-harness.mjs +543 -0
- package/scripts/local-resume-cleanup-smoke.mjs +108 -0
- package/scripts/local-resume-smoke.d.mts +1 -0
- package/scripts/local-resume-smoke.mjs +642 -0
- package/scripts/platform-smoke/artifact-anchored-extract.d.mts +10 -0
- package/scripts/platform-smoke/artifact-anchored-extract.mjs +111 -0
- package/scripts/platform-smoke/artifact-bundle-chunk.mjs +57 -0
- package/scripts/platform-smoke/artifact-bundle-contract.mjs +34 -0
- package/scripts/platform-smoke/artifact-fs-safety.mjs +311 -0
- package/scripts/platform-smoke/artifact-openat-extract.c +335 -0
- package/scripts/platform-smoke/artifact-secrets.mjs +155 -0
- package/scripts/platform-smoke/artifacts.mjs +293 -65
- package/scripts/platform-smoke/card-detect.mjs +16 -4
- package/scripts/platform-smoke/crabbox-runner.mjs +45 -3
- package/scripts/platform-smoke/doctor.mjs +20 -10
- package/scripts/platform-smoke/live-suite-runner.mjs +18 -57
- package/scripts/platform-smoke/local-resume-runner.mjs +252 -0
- package/scripts/platform-smoke/local-resume-suites.d.mts +15 -0
- package/scripts/platform-smoke/local-resume-suites.mjs +104 -0
- package/scripts/platform-smoke/scenarios.mjs +16 -2
- package/scripts/platform-smoke/target-runtime.mjs +206 -0
- package/scripts/platform-smoke/targets.mjs +33 -141
- package/scripts/platform-smoke/visual-evidence.mjs +6 -7
- package/scripts/platform-smoke/wrapped-line-match.mjs +9 -0
- package/scripts/platform-smoke.mjs +40 -27
- package/scripts/refresh-cursor-model-snapshots.mjs +18 -6
- package/scripts/steering-rpc-smoke.mjs +12 -2
- package/scripts/tmux-live-smoke.sh +3 -5
- package/shared/cursor-cloud-lifecycle-constants.d.mts +3 -0
- package/shared/cursor-cloud-lifecycle-constants.mjs +7 -0
- package/shared/cursor-sensitive-text.mjs +7 -1
- package/src/context.ts +5 -2
- package/src/cursor-agents-context-registration.ts +7 -0
- package/src/cursor-agents-context.ts +3 -1
- package/src/cursor-api-key.ts +15 -1
- package/src/cursor-bridge-contract.ts +3 -0
- package/src/cursor-cloud-lifecycle.ts +733 -0
- package/src/cursor-cloud-options.ts +206 -0
- package/src/cursor-cloud-reporting.ts +246 -0
- package/src/cursor-config.ts +659 -0
- package/src/cursor-display-only-trace.ts +14 -0
- package/src/cursor-display-text.ts +8 -2
- package/src/cursor-durable-fs.ts +49 -0
- package/src/cursor-fallback-models.generated.ts +2045 -485
- package/src/cursor-live-run-accounting.ts +7 -1
- package/src/cursor-live-run-coordinator.ts +1 -0
- package/src/cursor-pi-tool-bridge-run.ts +14 -4
- package/src/cursor-provider-live-run-drain.ts +5 -0
- package/src/cursor-provider-run-finalizer.ts +36 -28
- package/src/cursor-provider-turn-finalize.ts +72 -6
- package/src/cursor-provider-turn-prepare.ts +228 -12
- package/src/cursor-provider-turn-runner.ts +41 -13
- package/src/cursor-provider-turn-send.ts +59 -16
- package/src/cursor-provider-turn-types.ts +44 -10
- package/src/cursor-runtime-state.ts +478 -0
- package/src/cursor-sdk-event-debug.ts +46 -6
- package/src/cursor-sdk-process-error-guard.ts +101 -30
- package/src/cursor-session-agent-cleanup.ts +328 -0
- package/src/cursor-session-agent-resume.ts +439 -0
- package/src/cursor-session-agent.ts +109 -13
- package/src/cursor-session-scope.ts +35 -2
- package/src/cursor-session-send-policy.ts +1 -1
- package/src/cursor-skill-tool.ts +30 -11
- package/src/cursor-state.ts +112 -69
- package/src/cursor-usage-accounting.ts +14 -4
- package/src/index.ts +11 -2
- package/src/model-discovery.ts +10 -56
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,49 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.1.57 - 2026-07-10
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
|
|
7
|
+
- Prefer exposed `pi__mcp` and `pi__subagent` bridge tools for MCP work and delegation, with Cursor-configured MCP and Cursor-native subagents as fallbacks when the matching pi tool is not exposed or is unavailable.
|
|
8
|
+
- Update the Pi development and platform-smoke baseline to 0.80.5, including native `openai-codex/gpt-5.6-luna`, `gpt-5.6-sol`, and `gpt-5.6-terra` metadata.
|
|
9
|
+
- Enable guarded branch-scoped local Cursor SDK resume by default for local runtime; users can opt out with `--cursor-no-local-resume`, `PI_CURSOR_LOCAL_RESUME=0`, or `local.resume: false`.
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- Refresh the reviewed Cursor fallback catalog with Cursor's GPT-5.6 Luna/Sol/Terra models and Claude Sonnet 5, including the SDK-advertised aliases, context variants, reasoning/effort levels, and fast selections.
|
|
14
|
+
- Add `/cursor-refresh-config` to call the current pooled Cursor SDK agent's `agent.reload()` for filesystem Cursor config refreshes without recreating the agent.
|
|
15
|
+
- Add explicit local Cursor safety controls: `--cursor-auto-review` / `PI_CURSOR_AUTO_REVIEW` and `--cursor-sandbox` / `PI_CURSOR_SANDBOX`, plus `local.autoReview` and `local.sandboxOptions.enabled` config. Defaults stay off.
|
|
16
|
+
- Add one-shot manual local stuck-run recovery with `--cursor-local-force` / `PI_CURSOR_LOCAL_FORCE`, consumed only at the next actual `Agent.send(..., { local: { force: true } })` so pre-send failures/aborts preserve it and session reload cannot rearm a consumed CLI flag; no persistent config default, retry loop, or automatic force recovery is added.
|
|
17
|
+
- Add minimal explicit Cursor cloud runtime execution after first-use acknowledgement and safety preflight. Defaults stay local + loopback MCP; cloud runs use fresh context by default, skip the pi bridge/local MCP/env forwarding, leave cloud agents alive for Cursor-managed cleanup, and keep project config limited to the runtime default for the initial cloud slice.
|
|
18
|
+
- Show Cursor runtime directly in the interactive status footer (`cursor:local · fast:on|off|n/a`, `cursor:cloud · fast:n/a`) so cloud opt-in is visible.
|
|
19
|
+
- Name explicit Cursor cloud agents from the current pi session title when available so Cursor Cloud agent lists are easier to match back to pi sessions.
|
|
20
|
+
- Add explicit Cursor-managed cloud environment selection with `--cursor-cloud-env-type`, `--cursor-cloud-env-name`, `PI_CURSOR_CLOUD_ENV_TYPE`, `PI_CURSOR_CLOUD_ENV_NAME`, and `cloud.environment.type/name` user config. This selects Cursor Cloud `cloud` / `pool` / `machine` environments without forwarding local env values.
|
|
21
|
+
- Stream bounded display-only Cursor Cloud completion telemetry when available: agent/run IDs, pushed branch, repository and PR URL, passive artifact paths, and raw cloud usage without persisting it into transcript content or feeding that usage into pi accounting.
|
|
22
|
+
- Add `/cursor-cloud list`, `/cursor-cloud archive <bc-agentId>`, and `/cursor-cloud delete <bc-agentId> --yes` for session-branch recorded cloud agents; archive/delete reject empty, non-`bc-`, wildcard, unrecorded, bulk, and unconfirmed delete requests before SDK calls.
|
|
23
|
+
- Add guarded branch-scoped local Cursor SDK resume; it stores SDK agent IDs only in pi session custom entries, re-supplies the current model and loopback MCP bridge, bootstraps the current pi transcript once after process reattachment, and falls back to create+bootstrap with a display-only continuity note when resume is unavailable.
|
|
24
|
+
|
|
25
|
+
### Fixed
|
|
26
|
+
|
|
27
|
+
- Prevent Bun from terminating pi when `@cursor/sdk` 1.0.23's controlled-exec error path writes to an already closed internal iterable during a long bridged tool call. Suppression is limited to the exact `WriteIterableClosedError` name/message with Cursor SDK stack provenance for the Pi session lifecycle because controlled-exec can reject after the originating provider turn; Connect/network/abort suppression remains active-turn scoped, and unrelated failures remain fatal.
|
|
28
|
+
- Stop applying Cursor SDK `RunResult.usage` to pi assistant messages when no per-turn `turn-ended` usage is available; long local sessions can report full-agent-context usage there, which can poison compaction/session token totals. Pi now falls back to bounded local estimates unless real per-turn SDK usage is present and fits the selected model window.
|
|
29
|
+
- Pass the current Cursor model selection on every SDK `agent.send()` so resumed and pooled agents keep pi's active model as the source of truth.
|
|
30
|
+
- Fail closed on invalid explicit Cursor runtime or cloud-context CLI/environment values, and report the effective runtime source or safety cap from `/cursor-runtime` instead of claiming a shadowed session value took effect.
|
|
31
|
+
- Apply `local.resume` enable/disable changes to the next pooled-agent turn without recreating the agent.
|
|
32
|
+
- Force-create the replacement local SDK agent after incremental-threshold or context-divergence rebootstrap while keeping resume persistence enabled for the replacement, instead of resuming the agent the reset just disposed.
|
|
33
|
+
- Stop parsing process-wide `--api-key` values during startup discovery; provider turns keep Pi's scoped `options.apiKey`, while model refresh and Cloud lifecycle commands ask Pi's `ModelRegistry` for provider `cursor`, preventing another provider's key from reaching Cursor SDK calls while preserving stored and environment Cursor auth fallback.
|
|
34
|
+
- Terminate full smoke-runner process trees on timeout/cleanup, give bounded Windows CIM orphan discovery enough time under VM contention, reject unknown or conflicting paid smoke lane arguments before starting a live run, and prepare a root-started wrapper around the unprivileged Ubuntu Node image so Crabbox can install its SSH bootstrap dependencies.
|
|
35
|
+
- Persist Cursor Cloud agent intent immediately after `Agent.create()` and before debug/abort handling to a branch-bound, fsynced, newline-framed sidecar keyed by stable pi session ID, opened through regular-file descriptor identity checks without following symlinks (POSIX mode `0600`, Windows user-directory ACL), and persist returned run IDs before abort/wait handling so rejected, cancelled, or first-turn-crashed sends remain cleanup-eligible; individually truncated records no longer hide later valid IDs, successive run/report records merge without losing metadata, anchored journals fsync Pi session JSONL first, archive/delete require auth before durable intent/result records, tolerate optional Pi-mirror failure after a durable result, and leave durable intent pending when the sidecar result fails, Cloud requires a persisted pi session, lifecycle persistence failures fail closed with bounded cancellation and dashboard guidance, and optional debug-write failures cannot orphan returned or live runs.
|
|
36
|
+
- Verify and fsync exact local-agent cleanup intent in the Pi session JSONL before SDK deletion, fsync the result afterward, use Windows-compatible read-write flush descriptors, and keep both durable intent and current-process state blocking retry when result durability fails.
|
|
37
|
+
- Make Cloud smoke cleanup harvest exact agent IDs from canonical session/lifecycle artifacts as well as optional debug metadata, archive the union, and retain artifacts on run or cleanup failure.
|
|
38
|
+
- Keep canonical platform artifact transport below Crabbox's 64 KiB ceiling with gzip JSON/base64 inline bundles or checksum-verified 32 KiB no-sync chunk retrieval before lease release; large bundles now use only the exact CWD-relative `.platform-artifact-bundle.gz` final component, created and written exclusively through a no-follow identity-checked descriptor, and chunk/marker validation rejects every parent-bearing path. Bounded scans accept caller roots only when their real path matches the same relative path beneath the canonical real CWD or temp base (preserving expected macOS `/var` → `/private/var` aliasing while rejecting user-created intermediate links), then hold each traversed directory and recheck its identity plus immutable ctime/mtime/size/link/mode snapshot around traversal and file reads, so nested rename/symlink ABA cannot expose outside bytes. Scans still cover every regular artifact before transport exclusions, reject non-regular entries, prune `node_modules`/`.git`, fail closed on oversized or unscannable files, and any traversal failure emits only bounded failure evidence rather than findings or previously observed bytes; bundles cap compressed/inflated/per-file/file-count/aggregate extraction before host writes, reject duplicate/file-prefix bundle paths and symlinked or pre-existing host destinations, and extract only through exclusive identity-checked descriptors after securing destination directories. Compact output still uses `--capture-stdout` and preserves real scenario exit codes. Windows controllers reject nonempty extraction before mutation because Node has no handle-relative Windows creation API; Windows remains a supported matrix target from the POSIX controller, with target-side scan/spill identity guards kept free of POSIX-only flags.
|
|
39
|
+
- Reject local resume handles that cross user messages already persisted at process startup, preventing a hard-crash restart from resending a prompt that the prior Cursor agent may already have accepted.
|
|
40
|
+
- Reject non-HTTPS and credential/query/fragment-bearing Cursor Cloud repository URLs before `Agent.create()`, and redact URL/SCP-style userinfo from provider and maintainer output.
|
|
41
|
+
|
|
42
|
+
### Validation
|
|
43
|
+
|
|
44
|
+
- Current offline evidence is limited to the checked-in focused tests, full unit suite, platform-smoke syntax/tooling checks, and TypeScript checks; final command results belong in the release artifacts/status.
|
|
45
|
+
- Required and pending release gates are `npm publish --dry-run`, `npm run smoke:platform:all`, `npm run smoke:cloud`, and the applicable live release smokes. Their final results belong in the release artifacts/status, not this changelog.
|
|
46
|
+
|
|
3
47
|
## 0.1.56 - 2026-07-04
|
|
4
48
|
|
|
5
49
|
### Changed
|
|
@@ -44,7 +88,7 @@
|
|
|
44
88
|
|
|
45
89
|
### Changed
|
|
46
90
|
|
|
47
|
-
- Use real per-turn Cursor SDK usage when available, including cache read/write fields, while keeping local prompt/output estimates as the no-SDK-usage fallback. SDK-attributed context occupancy
|
|
91
|
+
- Use real per-turn Cursor SDK usage when available, including cache read/write fields, while keeping local prompt/output estimates as the no-SDK-usage fallback. SDK-attributed context occupancy includes the latest turn's input, output, cache-read, and cache-write counters per the SDK and pi compaction contracts; fallback context occupancy uses the replayable context estimate so split tool turns do not show a tiny footer percentage next to large input counts.
|
|
48
92
|
- Shorten Cursor bootstrap and incremental prompt boundary text while preserving host-tool, configured MCP, pi bridge, exact-output, shell cwd, plan-mode, and latest-image guidance. The callable-surface manifest remains enabled by default but uses compact wording for Cursor host/configured MCP tools and pi tools/bridge exposure.
|
|
49
93
|
|
|
50
94
|
### Fixed
|
package/README.md
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
# pi-cursor-sdk
|
|
2
2
|
|
|
3
|
-
A pi provider extension that lets pi use Cursor models through the local `@cursor/sdk` agent runtime.
|
|
3
|
+
A pi provider extension that lets pi use Cursor models through the local-by-default `@cursor/sdk` agent runtime, with explicit minimal Cursor Cloud opt-in.
|
|
4
4
|
|
|
5
|
-
Use this extension if you primarily use Cursor models inside pi and want Cursor's
|
|
5
|
+
Use this extension if you primarily use Cursor models inside pi and want Cursor's SDK agent loop preserved while pi adds native model selection, auth, thinking/context controls, session behavior, replay UI, optional local pi tool bridging, and explicit cloud runs when requested.
|
|
6
6
|
|
|
7
7
|
## Why use this instead of an OpenAI-compatible Cursor endpoint?
|
|
8
8
|
|
|
9
9
|
Use `pi-cursor-sdk` when you primarily want to use Cursor models **inside pi**.
|
|
10
10
|
|
|
11
|
-
This extension runs Cursor models through
|
|
11
|
+
This extension runs Cursor models through `@cursor/sdk` and keeps Cursor's agent loop intact. Local remains the default; explicit cloud runtime starts Cursor Cloud after acknowledgement and preflight. pi integrates around that loop: model discovery, model selection, context-window variants, thinking controls where Cursor exposes them, fast/slow aliases, Cursor mode, session handling, native replay cards, and the optional local pi tool bridge.
|
|
12
12
|
|
|
13
13
|
OpenAI-compatible Cursor proxies are useful when you want a generic `/v1/chat/completions` or `/v1/responses` endpoint for many clients such as curl, the OpenAI SDK, OpenCode, or other tools. That compatibility comes from translating Cursor behavior into OpenAI-shaped requests, responses, and tool calls.
|
|
14
14
|
|
|
@@ -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
|
-
- pi 0.80.
|
|
54
|
+
- pi 0.80.5 or newer recommended; pi core peer metadata is intentionally unpinned so newer pi releases are not blocked
|
|
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.23`, so normal package installation brings in the SDK version this extension was built and tested against. Cursor SDK 1.0.23 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.23 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. This package follows pi package guidance by declaring pi core package peers with `"*"` ranges, so users who update pi before this extension is republished are not blocked by peer metadata. The current recommended and validated pi baseline is 0.80.
|
|
57
|
+
No global `@cursor/sdk` install is required. This package depends on exact `@cursor/sdk@1.0.23`, so normal package installation brings in the SDK version this extension was built and tested against. Cursor SDK 1.0.23 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.23 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. This package follows pi package guidance by declaring pi core package peers with `"*"` ranges, so users who update pi before this extension is republished are not blocked by peer metadata. The current recommended and validated pi baseline is 0.80.5 plus Cursor SDK 1.0.23; older pi compatibility paths are best-effort and older Cursor SDK compatibility paths are not maintained.
|
|
58
58
|
|
|
59
59
|
## Install
|
|
60
60
|
|
|
@@ -124,7 +124,7 @@ One-shot setup:
|
|
|
124
124
|
pi --api-key "your-key" --model cursor/composer-2-5 --cursor-no-fast -p "Say ok only."
|
|
125
125
|
```
|
|
126
126
|
|
|
127
|
-
|
|
127
|
+
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.
|
|
128
128
|
|
|
129
129
|
### Model catalog cache
|
|
130
130
|
|
|
@@ -239,15 +239,16 @@ Composer 2 and Composer 2.5 can default to fast. Use `--cursor-no-fast` or a `:s
|
|
|
239
239
|
In interactive mode, the footer shows Cursor status only while a Cursor model is active. Fast-capable models show fast state explicitly, and fast and plan mode share one Cursor status value so they do not overwrite each other:
|
|
240
240
|
|
|
241
241
|
```text
|
|
242
|
-
cursor
|
|
243
|
-
cursor
|
|
244
|
-
cursor
|
|
245
|
-
cursor
|
|
246
|
-
cursor
|
|
247
|
-
cursor
|
|
242
|
+
cursor:local · fast:n/a
|
|
243
|
+
cursor:local · fast:n/a · plan
|
|
244
|
+
cursor:local · fast:off
|
|
245
|
+
cursor:local · fast:on
|
|
246
|
+
cursor:local · fast:off · plan
|
|
247
|
+
cursor:local · fast:on · plan
|
|
248
|
+
cursor:cloud · fast:n/a
|
|
248
249
|
```
|
|
249
250
|
|
|
250
|
-
`cursor
|
|
251
|
+
`cursor:local` / `cursor:cloud` shows the selected Cursor runtime. `fast:off` means fast mode is off. `fast:n/a` means the active runtime/model does not expose a local fast toggle. If you do not see `plan`, Cursor SDK mode is the default `agent` mode.
|
|
251
252
|
|
|
252
253
|
## Cursor SDK mode
|
|
253
254
|
|
|
@@ -276,6 +277,71 @@ When a new local Cursor SDK agent is created, the extension seeds the mode throu
|
|
|
276
277
|
|
|
277
278
|
Cursor SDK `plan` mode can produce plan-oriented output and Cursor todo/plan activity, but those replay cards remain display-only. They do not drive pi's plan-mode extension, pi todos, or active tool state.
|
|
278
279
|
|
|
280
|
+
## Cursor local agent config and safety controls
|
|
281
|
+
|
|
282
|
+
`/cursor-refresh-config` calls the current pooled SDK agent's `agent.reload()` so Cursor reloads filesystem config such as local hooks, project MCP, and subagents without restarting pi. If no Cursor agent exists yet, the next Cursor run loads config normally.
|
|
283
|
+
|
|
284
|
+
Cursor SDK local safety controls stay off by default. Enable them explicitly for one run:
|
|
285
|
+
|
|
286
|
+
```bash
|
|
287
|
+
PI_CURSOR_AUTO_REVIEW=1 PI_CURSOR_SANDBOX=1 pi --model cursor/composer-2-5
|
|
288
|
+
pi --model cursor/composer-2-5 --cursor-auto-review --cursor-sandbox
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
For manual stuck-run recovery only, explicitly force-expire the active persisted local SDK run before sending:
|
|
292
|
+
|
|
293
|
+
```bash
|
|
294
|
+
PI_CURSOR_LOCAL_FORCE=1 pi --model cursor/composer-2-5
|
|
295
|
+
pi --model cursor/composer-2-5 --cursor-local-force
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
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.
|
|
299
|
+
|
|
300
|
+
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 only in pi session custom entries, never user/project config. Disable it per run with CLI/env, or persist an opt-out in config:
|
|
301
|
+
|
|
302
|
+
```bash
|
|
303
|
+
pi --model cursor/composer-2-5 --cursor-no-local-resume
|
|
304
|
+
PI_CURSOR_LOCAL_RESUME=0 pi --model cursor/composer-2-5
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
Resume is strict: the current pi session file/id, branch path prefix, cwd/repo root, model/API/tool-surface pool key, and compaction generation must match. 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. Cloud resume remains disabled; `/cursor-cloud list|archive|delete` only manages recorded cloud agents.
|
|
308
|
+
|
|
309
|
+
Config can also set non-secret defaults in `~/.pi/agent/cursor-sdk.json` or trusted `.pi/cursor-sdk.json`:
|
|
310
|
+
|
|
311
|
+
```json
|
|
312
|
+
{
|
|
313
|
+
"runtime": "local",
|
|
314
|
+
"local": {
|
|
315
|
+
"autoReview": true,
|
|
316
|
+
"sandboxOptions": { "enabled": true },
|
|
317
|
+
"resume": true
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
Cloud/runtime keys are minimal and explicit. Defaults stay local runtime with the loopback MCP bridge as the sole Pi-tool transport, no inline cloud MCP, and no local-state/env-file forwarding. SDK `customTools` remains deferred pending SDK cancellation/deadline support. Invalid non-empty `--cursor-runtime`, `--cursor-cloud-context`, `PI_CURSOR_RUNTIME`, or `PI_CURSOR_CLOUD_CONTEXT` values fail closed instead of falling through to lower-precedence config. If `runtime` is explicitly set to `cloud` with `--cursor-runtime cloud`, `PI_CURSOR_RUNTIME=cloud`, `/cursor-runtime cloud`, or config, the provider starts a Cursor cloud agent after preflight instead of silently running local. On first interactive use, `/cursor-runtime cloud` shows one confirmation covering remote execution, fresh context by default (explicit bootstrap opt-in), unavailable Pi-local tools/bridge and Pi env forwarding, Cursor's ability to branch/commit/push/open PRs, retained cloud agents, and Max Mode billing at Cursor API pricing (including possible spend-limit setup). Cancelling that first-use confirmation writes no session or config state. Use `/cursor-runtime cloud --save-user` for a persistent personal acknowledgement or `--cursor-cloud-ack` / `PI_CURSOR_CLOUD_ACK=1` for non-interactive runs; acknowledged CLI, environment, session, or user state is not prompted again. Project config may save a cloud runtime default but not first-use acknowledgement or repo/branch/env/context/direct-push/local-state preferences. An explicit `--cursor-cloud-branch` / `PI_CURSOR_CLOUD_BRANCH` requires an explicit `--cursor-cloud-repo` / `PI_CURSOR_CLOUD_REPO` because the SDK exposes `startingRef` only on `cloud.repos` entries. Repository values must be HTTPS repository URLs without userinfo, query parameters, or fragments; invalid values fail before `Agent.create()`, and error scrubbing removes URL/SCP-style userinfo. Cloud runs use fresh context by default; pass `--cursor-cloud-context=bootstrap` / `PI_CURSOR_CLOUD_CONTEXT=bootstrap` to include prior pi context. Pass `--cursor-cloud-env-type=cloud|pool|machine` plus optional `--cursor-cloud-env-name=<name>` (or `PI_CURSOR_CLOUD_ENV_TYPE` / `PI_CURSOR_CLOUD_ENV_NAME`) to select a Cursor-managed cloud environment without forwarding local env values. Named `cloud` environments fail closed when combined with `--cursor-cloud-repo`; omit the repo or use a pool/machine environment. When a pi session has a title, cloud agents are created with that title for easier dashboard/list matching. At cloud run completion, pi streams display-only cloud telemetry when Cursor reports it: agent/run IDs, pushed branch, repository and PR URL, passive artifact paths, and raw cloud usage. Cloud runtime requires a persisted pi session and rejects `--no-session` before `Agent.send()`. Immediately after `Agent.create()` returns—and before debug work or abort checks—Pi appends a branch-local lifecycle entry, fsyncs the existing Pi session JSONL anchor through a read-write descriptor, and then fsyncs a newline-framed sidecar keyed by the stable pi session ID (POSIX mode `0600`; Windows inherits the user session directory ACL) in the session directory. Existing session files use the exact lifecycle entry ID as the branch anchor; a fileless first turn uses an orphan marker so a restart with the same session ID can claim the record onto exactly one matching or replacement branch after its new timestamped JSONL is created. That durable claim then restores normal sibling-branch isolation. It adds the returned run ID before post-send abort handling or waiting and enriches successful runs with branch/PR metadata. Readers skip individually truncated records so one interrupted append cannot hide later valid cleanup IDs. If the agent intent cannot be persisted, pi does not send; if the returned run cannot be persisted, pi requests bounded cancellation. Both paths fail closed and direct you to the Cursor Cloud dashboard for manual cleanup. `/cursor-cloud list`, `/cursor-cloud archive <bc-agentId>`, and `/cursor-cloud delete <bc-agentId> --yes` only accept exact recorded `bc-` cloud IDs. Archive/delete require resolved Cursor auth, fsync a durable intent before the SDK mutation, and fsync a durable success result afterward; an unresolved intent blocks retries and directs manual dashboard inspection instead of guessing whether an irreversible request completed. Raw cloud usage is not copied into pi message usage, context occupancy, compaction, or cost totals. The pi bridge is local-only, and pi env forwarding is not implemented yet, so `--cursor-cloud-env` forwarding-name config fails closed with Cursor-native environment setup guidance.
|
|
323
|
+
|
|
324
|
+
Cloud lifecycle commands are explicit and session-branch scoped:
|
|
325
|
+
|
|
326
|
+
```bash
|
|
327
|
+
/cursor-cloud list
|
|
328
|
+
/cursor-cloud archive <bc-agentId>
|
|
329
|
+
/cursor-cloud delete <bc-agentId> --yes
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
They only accept cloud agent IDs recorded in the current session branch or its branch-bound durable sidecar; agent intents are fsynced before send and returned run IDs are recorded before abort handling or waiting so rejected, failed, cancelled, or first-turn-crashed sends remain cleanup-eligible. Persistence failures fail closed with Cursor Cloud dashboard cleanup guidance.
|
|
333
|
+
|
|
334
|
+
Local resume cleanup is explicit and session-ledger scoped:
|
|
335
|
+
|
|
336
|
+
```bash
|
|
337
|
+
/cursor-local-resume-cleanup --dry-run
|
|
338
|
+
/cursor-local-resume-cleanup --yes
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
It only deletes superseded local `agent-*` IDs that this extension recorded as cleanup candidates, one exact ID at a time through the Cursor SDK, and protects agents still resumable from any session-tree branch. Before SDK deletion it verifies and fsyncs an exact intent in the Pi session JSONL, then verifies and fsyncs the result; a missing or non-durable intent prevents deletion, while a missing or non-durable result leaves the durable intent—and a conservative current-process marker—blocking automatic retry. It does not sweep the SDK store or call lower-level empty delete filters.
|
|
342
|
+
|
|
343
|
+
Only enabled local safety values are passed to `Agent.create({ local })`; false/default values are omitted to preserve the current local-agent behavior. Local force is one-shot/manual-only through CLI/env and is passed only to the next `Agent.send({ local: { force: true } })`. Local resume is enabled by default for local runtime; opt out with `local.resume: false`, `--cursor-no-local-resume`, or `PI_CURSOR_LOCAL_RESUME=0`. Changes take effect on the next turn without recreating a healthy pooled agent.
|
|
344
|
+
|
|
279
345
|
## Images
|
|
280
346
|
|
|
281
347
|
Images from the latest user message are forwarded to Cursor. Historical images are kept out of the transcript and appear only as `[image omitted from transcript]` placeholders, so follow-up questions about an earlier image should reattach the image or include a textual description. The extension advertises `text` and `image` input for Cursor models because Cursor's SDK accepts image messages and Cursor models are expected to support them.
|
|
@@ -285,14 +351,14 @@ Images from the latest user message are forwarded to Cursor. Historical images a
|
|
|
285
351
|
|
|
286
352
|
See [Cursor tool surfaces in pi](docs/cursor-tool-surfaces.md) for a concise guide to callable vs display-only tools, MCP catalog limits, JSONL ID patterns, and how pi toggles differ from Cursor ambient MCP.
|
|
287
353
|
|
|
288
|
-
Cursor runs use
|
|
354
|
+
Local Cursor runs use two separate tool surfaces:
|
|
289
355
|
|
|
290
356
|
- **Cursor-native surface:** Cursor local-agent tools, Cursor settings, plugins, and configured Cursor MCP servers. These remain owned by the Cursor SDK local agent path. Pi CLI tool toggles such as `--no-tools`, `--tools`, and `--exclude-tools` do not disable this Cursor-native surface.
|
|
291
357
|
- **pi bridge surface:** pi-cursor-sdk exposes bridgeable active pi tools through a per-run local loopback MCP bridge when the bridge is enabled and the current pi tool registry has exposed tools. Pi CLI tool toggles affect this bridge surface because they change pi's active tool registry.
|
|
292
358
|
|
|
293
|
-
Bridge capabilities are snapshotted from `pi.getActiveTools()` and `pi.getAllTools()` for each Cursor run, including per-tool prompt guidelines when pi exposes them. Cursor sees active bridgeable pi tools as collision-safe MCP names such as `pi__sem_reindex` only when they are exposed in that current run. Pi session output, tool cards, confirmations, hooks, renderers, history, and abort behavior use the real pi tool name, such as `sem_reindex`. The bridge queues Cursor's MCP call, emits a normal pi `toolCall`, waits for the matching pi `toolResult`, and resolves that result back into the same live Cursor SDK run without creating a new `Agent`, unless the run was disposed, aborted, or cancelled. The bridge does not call pi tool `execute()` handlers directly.
|
|
359
|
+
Bridge capabilities are snapshotted from `pi.getActiveTools()` and `pi.getAllTools()` for each Cursor run, including per-tool prompt guidelines when pi exposes them. Cursor sees active bridgeable pi tools as collision-safe MCP names such as `pi__sem_reindex` only when they are exposed in that current run. When exposed, Cursor is instructed to prefer `pi__mcp` for MCP work and `pi__subagent` for delegation; Cursor-configured MCP and Cursor-native subagents are fallbacks when the matching pi tool is not exposed or is unavailable. Pi session output, tool cards, confirmations, hooks, renderers, history, and abort behavior use the real pi tool name, such as `sem_reindex`. The bridge queues Cursor's MCP call, emits a normal pi `toolCall`, waits for the matching pi `toolResult`, and resolves that result back into the same live Cursor SDK run without creating a new `Agent`, unless the run was disposed, aborted, or cancelled. The bridge does not call pi tool `execute()` handlers directly.
|
|
294
360
|
|
|
295
|
-
Overlapping built-in pi tools (`read`, `bash`, `write`, `edit`, `grep`, `find`, `ls`) are hidden by default because Cursor local agents already have native equivalents. Extension/custom tools and non-overlapping active tools present in pi's active tool registry normally remain exposed. The bridge also exposes `cursor_ask_question` as `pi__cursor_ask_question` when enabled, allowing Cursor to ask the user through pi UI instead of silently choosing a default.
|
|
361
|
+
Overlapping built-in pi tools (`read`, `bash`, `write`, `edit`, `grep`, `find`, `ls`) are hidden by default because Cursor local agents already have native equivalents. Extension/custom tools and non-overlapping active tools present in pi's active tool registry normally remain exposed. The bridge also exposes `cursor_ask_question` as `pi__cursor_ask_question` when enabled, allowing Cursor to ask the user through pi UI instead of silently choosing a default. For local runtime, when pi has visible Agent Skills loaded, the extension rewrites pi's skill catalog for Cursor and exposes `cursor_activate_skill` as `pi__cursor_activate_skill`; Cursor should call that bridge tool with a listed skill name to load the full `SKILL.md` and bundled resource list before applying the skill. If the local bridge is disabled, the catalog remains available and instructs Cursor to fall back to reading the listed `SKILL.md` path directly. Cloud runtime preserves Pi project instructions but omits Pi's local skill catalog and keeps `cursor_activate_skill` inactive because the bridge and local absolute skill paths are unavailable there.
|
|
296
362
|
|
|
297
363
|
Cursor-native tool replay is separate from the bridge. Replay cards are display-only recorded Cursor SDK activity. They never re-run Cursor-side commands, reapply Cursor edits, call MCP servers, or mutate pi state. See [Cursor native tool replay](docs/cursor-native-tool-replay.md).
|
|
298
364
|
|
|
@@ -326,7 +392,7 @@ On bootstrap sends, a compact **callable tool surfaces** block is injected into
|
|
|
326
392
|
|
|
327
393
|
### Maintainer platform smoke release gate
|
|
328
394
|
|
|
329
|
-
For Cursor provider/runtime changes, the canonical 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. The gate validates macOS, Ubuntu, and Windows native through Crabbox using packed installs, 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.
|
|
395
|
+
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, 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.
|
|
330
396
|
|
|
331
397
|
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/composer-2-5` 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.
|
|
332
398
|
|
|
@@ -334,21 +400,21 @@ The older live smoke helpers remain useful for inner-loop debugging and focused
|
|
|
334
400
|
|
|
335
401
|
Use `npm run debug:sdk-events` to capture timestamped `run.stream()`, `onDelta`, and `onStep` timelines for one direct `@cursor/sdk` run.
|
|
336
402
|
|
|
337
|
-
Use `npm run debug:provider-events` to capture the same `onDelta`/`onStep` payloads **through pi's Cursor provider** (session agent reuse, bridge, native replay, send planning). Artifacts default under gitignored `.debug/cursor-sdk-events/`. Interactive multi-turn pi sessions group turns under `.debug/cursor-sdk-events/sessions/<session-slug>/turn-NNN-.../` with a `session.json` index. You can also opt in during any pi run with `PI_CURSOR_SDK_EVENT_DEBUG=1`; capture is file-only by default so the pi TUI stays normal.
|
|
403
|
+
Use `npm run debug:provider-events` to capture the same `onDelta`/`onStep` payloads **through pi's Cursor provider** (session agent reuse, bridge, native replay, send planning). Artifacts default under gitignored `.debug/cursor-sdk-events/`. Interactive multi-turn pi sessions group turns under `.debug/cursor-sdk-events/sessions/<session-slug>/turn-NNN-.../` with a `session.json` index. You can also opt in during any pi run with `PI_CURSOR_SDK_EVENT_DEBUG=1`; capture is file-only by default so the pi TUI stays normal. Each cumulative JSONL artifact is capped at 2 MiB, ends with an `artifact_truncated` record when capped, and is listed in `summary.json` under `truncatedJsonlFiles`.
|
|
338
404
|
|
|
339
405
|
See [Cursor testing lessons](docs/cursor-testing-lessons.md#cursor-sdk-event-capture-probe) for usage, artifact layout, and safety notes.
|
|
340
406
|
|
|
341
407
|
## Fallback models
|
|
342
408
|
|
|
343
|
-
If
|
|
409
|
+
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.
|
|
344
410
|
|
|
345
|
-
The fallback snapshot includes Composer 2.5 (`composer-2.5` and `composer-2-5`), Composer 2, GPT, Claude, Gemini, Grok, Kimi, and other model IDs exposed by the reviewed `Cursor.models.list()` output. The exact checked-in snapshot lives in `src/cursor-fallback-models.generated.ts`.
|
|
411
|
+
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.80.5 adds 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`.
|
|
346
412
|
|
|
347
413
|
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.
|
|
348
414
|
|
|
349
415
|
## Limits
|
|
350
416
|
|
|
351
|
-
- **Local Cursor
|
|
417
|
+
- **Cloud runtime is explicit and minimal.** Local remains the default. Cloud runs create Cursor cloud agents only after first-use acknowledgement and safety preflight, use fresh context by default, do not expose the pi bridge or local MCP, do not forward pi env vars, support explicit Cursor-managed environment selection, name agents from the pi session title when available, stream display-only agent/run/branch/PR/artifact/raw-usage telemetry when available, and record only explicit session-branch lifecycle commands for cleanup (`/cursor-cloud list|archive|delete`).
|
|
352
418
|
- **The pi tool bridge is local and MCP-backed.** Bridgeable active pi tools are exposed to local Cursor agents through a tokenized `127.0.0.1` MCP endpoint; internal Cursor replay activity names are excluded, and overlapping built-in pi tools are hidden by default. Set `PI_CURSOR_PI_TOOL_BRIDGE=0` to disable it or `PI_CURSOR_EXPOSE_BUILTIN_TOOLS=1` to expose overlapping built-ins too.
|
|
353
419
|
- **Cursor native tool replay is display-only.** Replay renders recorded Cursor SDK activity and never re-runs Cursor-side commands, reapplies Cursor edits, calls MCP servers, or mutates pi state. Workflow tools such as Cursor mode/task/todo/plan activity are not pi workflow controls. See [Cursor native tool replay](docs/cursor-native-tool-replay.md) for supported replay cards, ordering, conflict handling, and opt-out flags.
|
|
354
420
|
- **Cursor run state can span tool-use turns.** Within a pi session, the extension reuses one Cursor SDK agent across compatible follow-up turns and sends incremental prompts when context still matches. It recreates the agent when context diverges, after compaction or `/tree` navigation, on API key changes, after send errors, or on session shutdown. For bridged pi tools, the matching pi `toolResult` resolves into the same live Cursor SDK run without creating a new `Agent`, unless the run was disposed, aborted, or cancelled. Replay can also split one live Cursor SDK run across pi `toolUse` turns for display.
|
|
@@ -357,7 +423,7 @@ Actual Cursor runs still need a key from `/login`, `CURSOR_API_KEY`, or `--api-k
|
|
|
357
423
|
- **AGENTS.md / CLAUDE.md are not duplicated on Cursor models when Cursor loads the same rules.** Pi discovers global and project context files (`AGENTS.md`, `CLAUDE.md`, and case variants) unless you start with `-nc`. On `cursor/*` models the extension removes only `<project_instructions>` blocks that overlap Cursor `settingSources` via the `before_agent_start` hook: `user` for `~/.pi/agent/AGENTS.md`, `project` for repo/parent `AGENTS.md` and `CLAUDE.md` (verified Cursor behavior: local agents load project `AGENTS.md` and `CLAUDE.md` alongside Cursor rules). `~/.pi/agent/CLAUDE.md` is not stripped (Cursor user rules use `~/.claude/CLAUDE.md`, not pi's agent dir). With `PI_CURSOR_SETTING_SOURCES=none` or `plugins`-only, pi context is left intact. Set `PI_CURSOR_PRESERVE_PI_AGENTS_MD=1` to keep duplicate injection.
|
|
358
424
|
- **Max Mode is not a manual pi variant.** Cursor's SDK may enable Max Mode automatically for models that require it. This extension only advertises exact context-window variants that the SDK catalog exposes and otherwise uses conservative SDK-derived default/non-Max context windows.
|
|
359
425
|
- **Output token limits are conservative.** Cursor SDK model metadata does not currently expose output token limits directly.
|
|
360
|
-
- **Token usage uses Cursor SDK data when safely attributable.** For turns with in-time SDK usage, pi records the latest per-turn `inputTokens`, `outputTokens`, `cacheReadTokens`, and `cacheWriteTokens`; SDK-backed `totalTokens`
|
|
426
|
+
- **Token usage uses Cursor SDK data when safely attributable.** For turns with in-time SDK usage, pi records the latest per-turn `inputTokens`, `outputTokens`, `cacheReadTokens`, and `cacheWriteTokens`; SDK-backed `totalTokens` follows the SDK and pi compaction contracts: `inputTokens + outputTokens + cacheReadTokens + cacheWriteTokens`. If the SDK reports no usage in time, the extension falls back to local `input/output` activity estimates while setting `totalTokens` to the current replayable context estimate so the footer/compaction percentage does not collapse after split tool turns. Later usage for that live run is ignored rather than risk applying stale usage to the wrong pi turn. Cursor SDK cost is not exposed, so pi cost remains zero/absent.
|
|
361
427
|
|
|
362
428
|
## Troubleshooting
|
|
363
429
|
|
|
@@ -369,7 +435,7 @@ When a Cursor run fails after auth is configured, pi now surfaces scrubbed provi
|
|
|
369
435
|
|
|
370
436
|
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.
|
|
371
437
|
|
|
372
|
-
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. Persistent failures may indicate a transient Cursor service or network issue.
|
|
438
|
+
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/abort suppression remains active-turn scoped, and unrelated failures remain 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.
|
|
373
439
|
|
|
374
440
|
You can also restart pi with a key in the same shell or launcher that starts pi:
|
|
375
441
|
|
|
@@ -402,9 +468,9 @@ pi install npm:pi-cursor-sdk
|
|
|
402
468
|
|
|
403
469
|
That does not mean the model cannot think. It means the Cursor SDK does not expose a pi-controllable thinking parameter for that model. The model may still think internally and may still emit thinking deltas that pi renders natively.
|
|
404
470
|
|
|
405
|
-
### I do not see `cursor
|
|
471
|
+
### I do not see `cursor:local` / `cursor:cloud` or `plan` in the footer
|
|
406
472
|
|
|
407
|
-
The Cursor footer appears only while a Cursor model is active. Fast-capable models show `cursor
|
|
473
|
+
The Cursor footer appears only while a Cursor model is active. Fast-capable local models show `cursor:local · fast:on` or `cursor:local · fast:off`; Cursor models without a fast parameter show `cursor:local · fast:n/a`. Cloud runtime shows `cursor:cloud · fast:n/a`. Cursor SDK mode is the default `agent` mode when `plan` is absent. When both are active, pi shows one combined Cursor status such as `cursor:local · fast:on · plan` or `cursor:cloud · fast:n/a · plan`.
|
|
408
474
|
|
|
409
475
|
### My Cursor app settings or rules do not seem to apply
|
|
410
476
|
|
|
@@ -478,7 +544,7 @@ This usually needs session JSONL to classify. Common cases:
|
|
|
478
544
|
- **Stale replay routing / plan-strip:** Error `toolResult` or error assistant messages contain `Tool grep/cursor/find/ls not found`, or provider debug shows `inactive_trace` after plan-mode execute stripped active tools — tracked in **#52** (distinct from model text echo and #55).
|
|
479
545
|
- **Replay vs execution:** `cursor-replay-*` IDs and neutral **Cursor MCP** activity cards are display-only recorded Cursor results; they do not re-run browser/MCP work. See [Cursor native tool replay](docs/cursor-native-tool-replay.md).
|
|
480
546
|
- **Run failure / discarded tools:** A red toast with scrubbed detail may indicate an SDK failure (#55). Started-but-never-completed Cursor tools surface neutral **Cursor … did not complete** activity cards with a bounded reason when the run failed/aborted, produced no assistant text, or involved external/side-effectful tools. Incomplete fast local discovery starts (`read`, `grep`, `glob`, `ls`) are debug-only after a successful text-producing run so stale SDK start events do not create red post-answer cards; maintainer debug for the same gap remains in **#52** (`PI_CURSOR_SDK_EVENT_DEBUG=1`).
|
|
481
|
-
- **Hard
|
|
547
|
+
- **Hard SDK crash:** pi exited with an uncaught Cursor SDK `ConnectError` or `WriteIterableClosedError` instead of showing a normal run error — capture the stack/session tail as a process-guard regression, not #40 text echo.
|
|
482
548
|
|
|
483
549
|
Capture `pi --version`, extension version, model, flags, the exact prompt, and a redacted session dir before filing bugs.
|
|
484
550
|
|
|
@@ -495,7 +561,13 @@ npm test
|
|
|
495
561
|
npm run typecheck
|
|
496
562
|
```
|
|
497
563
|
|
|
498
|
-
|
|
564
|
+
Check the reviewable Cursor fallback catalog against the authenticated live catalog before releases:
|
|
565
|
+
|
|
566
|
+
```bash
|
|
567
|
+
CURSOR_API_KEY="your-key" npm run check:cursor-snapshots
|
|
568
|
+
```
|
|
569
|
+
|
|
570
|
+
Refresh it after Cursor model changes:
|
|
499
571
|
|
|
500
572
|
```bash
|
|
501
573
|
CURSOR_API_KEY="your-key" npm run refresh:cursor-snapshots -- --write
|
|
@@ -508,7 +580,7 @@ CURSOR_API_KEY="your-key" npm run refresh:cursor-snapshots -- --write \
|
|
|
508
580
|
--context-windows ~/.pi/agent/cursor-sdk-context-windows.json
|
|
509
581
|
```
|
|
510
582
|
|
|
511
|
-
The refresh
|
|
583
|
+
The check and refresh modes fetch and sort the same sanitized live catalog. Check mode byte-compares the generated fallback without writing; generated provenance records the installed `@cursor/sdk` version and model count. Both modes print public model metadata only and scrub known auth material from SDK errors. Do not run them with shell tracing that would echo API keys.
|
|
512
584
|
|
|
513
585
|
Local development run:
|
|
514
586
|
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# Cursor Live Smoke Checklist
|
|
2
2
|
|
|
3
|
-
> **Platform Smoke
|
|
3
|
+
> **Platform Smoke:** The required local cross-platform release gate is `npm run smoke:platform:all`; it runs doctor first. Cloud-runtime changes also require `npm run smoke:cloud`. See [docs/platform-smoke.md](./platform-smoke.md) for the full contract. The manual checks below remain useful inner-loop/debug tools but are not the required release gate.
|
|
4
4
|
|
|
5
5
|
## Purpose
|
|
6
6
|
|
|
7
|
-
Use this manual checklist during development and debugging of Cursor provider/runtime changes. Unit tests and mocks are necessary, but they are not enough for this extension. See [Cursor testing lessons](./cursor-testing-lessons.md) for auth/isolated-harness pitfalls and the plan-mode replay regression that motivated recent hardening.
|
|
7
|
+
Use this manual checklist during development and debugging of Cursor provider/runtime changes. Unit tests and mocks are necessary, but they are not enough for this extension. See [Cursor testing lessons](./cursor-testing-lessons.md) for auth/isolated-harness pitfalls and the plan-mode replay regression that motivated recent hardening. For release readiness, run the local platform gate in [docs/platform-smoke.md](./platform-smoke.md), plus `npm run smoke:cloud` for cloud-runtime changes; this checklist is inner-loop evidence only.
|
|
8
8
|
|
|
9
9
|
## Inner-loop rule
|
|
10
10
|
|
|
@@ -67,8 +67,8 @@ The replay scan flags only error `toolResult` / error assistant messages with `T
|
|
|
67
67
|
|
|
68
68
|
Pass criteria:
|
|
69
69
|
|
|
70
|
-
- `pi --version` reports pi 0.80.
|
|
71
|
-
- `npm ls` shows `@cursor/sdk@1.0.23` and local `@earendil-works/*@0.80.
|
|
70
|
+
- `pi --version` reports pi 0.80.5 for this cutover baseline.
|
|
71
|
+
- `npm ls` shows `@cursor/sdk@1.0.23` and local `@earendil-works/*@0.80.5` packages.
|
|
72
72
|
- `cursor/composer-2-5` appears in the model list.
|
|
73
73
|
- No Cursor key or auth token is printed.
|
|
74
74
|
- If neither `~/.pi/agent/auth.json` cursor auth nor `CURSOR_API_KEY` is available, stop and report the live smoke as blocked.
|
|
@@ -124,8 +124,8 @@ Observe with `tmux capture-pane -pt "$SESSION"` or attach manually.
|
|
|
124
124
|
|
|
125
125
|
Pass criteria:
|
|
126
126
|
|
|
127
|
-
- Footer shows `(cursor) composer-2-5`. With `--cursor-no-fast`, Cursor fast mode is off and the Cursor extension status should show `cursor
|
|
128
|
-
- The run uses pi 0.80.
|
|
127
|
+
- Footer shows `(cursor) composer-2-5`. With `--cursor-no-fast`, Cursor fast mode is off and the Cursor extension status should show `cursor:local · fast:off`; ignore unrelated status text from other extensions.
|
|
128
|
+
- The run uses pi 0.80.5 `--session-id` successfully.
|
|
129
129
|
- Assistant answer appears correctly.
|
|
130
130
|
- `/session` shows one user and one assistant message for the simple run.
|
|
131
131
|
- Persisted JSONL has one assistant message. If the screen appears duplicated, inspect JSONL before deciding whether it is a rendering bug.
|
|
@@ -133,7 +133,7 @@ Pass criteria:
|
|
|
133
133
|
|
|
134
134
|
## 4. Focused visual card/color rendering check
|
|
135
135
|
|
|
136
|
-
This is the canonical inner-loop visual debug path for Cursor provider/runtime changes. It requires offscreen TUI visual inspection, not only JSONL or code review. Use pi 0.80.
|
|
136
|
+
This is the canonical inner-loop visual debug path for Cursor provider/runtime changes. It requires offscreen TUI visual inspection, not only JSONL or code review. Use pi 0.80.5, `@cursor/sdk@1.0.23`, a fresh temporary session dir, Cursor SDK `plan` mode, native replay enabled, and the checked-in visual runner. The runner resolves `pi` by directly walking the parent `PATH`, uses `process.execPath` for Node, and prepends that Node directory for both prereq checks and tmux launches so `#!/usr/bin/env node` shims use the validated Node. The default matrix is native replay only: native replay registration is forced on, settings sources are `none`, the pi bridge is off, overlapping built-in pi tools are not exposed, and inherited Cursor SDK event-debug artifact env is cleared. With `--event-debug`, debug capture writes to a deterministic directory under `VISUAL_DIR`.
|
|
137
137
|
|
|
138
138
|
```bash
|
|
139
139
|
VISUAL_DIR="$(mktemp -d /tmp/pi-cursor-sdk-1016-visual.XXXXXX)"
|