pi-cursor-sdk 0.1.39 → 0.1.41
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 +25 -0
- package/README.md +13 -12
- package/docs/cursor-dogfood-checklist.md +7 -1
- package/docs/cursor-live-smoke-checklist.md +13 -13
- package/docs/cursor-model-ux-spec.md +8 -8
- package/docs/cursor-native-tool-replay.md +4 -4
- package/docs/cursor-native-tool-visual-audit.md +5 -5
- package/docs/cursor-testing-lessons.md +5 -5
- package/docs/cursor-tool-surfaces.md +4 -0
- package/docs/platform-smoke.md +22 -7
- package/package.json +8 -5
- package/platform-smoke.config.mjs +5 -0
- package/scripts/debug-provider-events.mjs +1 -0
- package/scripts/isolated-cursor-smoke.sh +7 -7
- package/scripts/lib/cursor-visual-manifest.d.mts +3 -0
- package/scripts/lib/cursor-visual-manifest.mjs +82 -0
- package/scripts/platform-smoke/artifacts.mjs +225 -2
- package/scripts/platform-smoke/card-detect.mjs +1 -1
- package/scripts/platform-smoke/doctor.mjs +53 -8
- package/scripts/platform-smoke/live-suite-runner.mjs +7 -6
- package/scripts/platform-smoke/platform-build-windows.ps1 +2 -2
- package/scripts/platform-smoke/scenarios.mjs +1 -1
- package/scripts/platform-smoke/targets.mjs +2 -2
- package/scripts/platform-smoke.mjs +75 -6
- package/scripts/steering-rpc-smoke.mjs +1 -1
- package/scripts/tmux-live-smoke.sh +1 -1
- package/scripts/visual-tui-smoke-self-test.mjs +229 -0
- package/scripts/visual-tui-smoke.mjs +46 -179
- package/shared/cursor-setting-sources.d.mts +1 -0
- package/shared/cursor-setting-sources.mjs +2 -1
- package/src/context.ts +25 -10
- package/src/cursor-active-tools.ts +7 -0
- package/src/cursor-native-tool-display-registration.ts +31 -21
- package/src/cursor-native-tool-display-state.ts +13 -4
- package/src/cursor-pi-tool-bridge-run.ts +6 -3
- package/src/cursor-pi-tool-bridge-types.ts +2 -2
- package/src/cursor-provider-errors.ts +2 -1
- package/src/cursor-provider-live-run-drain.ts +1 -1
- package/src/cursor-provider-turn-prepare.ts +1 -1
- package/src/cursor-provider-turn-send.ts +2 -0
- package/src/cursor-question-tool.ts +2 -1
- package/src/cursor-sdk-event-debug.ts +3 -1
- package/src/cursor-setting-sources.ts +2 -0
- package/src/cursor-skill-tool.ts +2 -1
- package/src/cursor-state.ts +2 -1
- package/src/cursor-tool-manifest.ts +2 -1
- package/src/cursor-usage-accounting.ts +5 -4
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,31 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 0.1.41 - 2026-06-09
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
- Upgrade the pinned Cursor SDK runtime dependency to `@cursor/sdk@1.0.18` after auditing the 1.0.17 → 1.0.18 SDK type/docs delta; preserve existing local-agent defaults while carrying the SDK `requestId` correlation field through debug metadata and generic run failure diagnostics.
|
|
10
|
+
- Update the local pi validation baseline to `@earendil-works/pi-ai`, `@earendil-works/pi-coding-agent`, and `@earendil-works/pi-tui` `0.79.1`, including platform-smoke artifact retention and visual smoke manifest evidence for Pi 0.79.1 release checks.
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- Keep plan-mode Cursor tool guidance canonical so bootstrap prompts do not duplicate the same instructions while incremental prompts still carry the plan-mode reminder.
|
|
15
|
+
- Preserve turn-local Cursor usage estimates for incremental/live sends instead of replacing them with replayable-context totals.
|
|
16
|
+
- Honor pi's disabled tool registry state when syncing Cursor bridge/question/skill/replay tools so `--no-tools` removes pi bridge exposure while leaving Cursor SDK host tools under Cursor's own control.
|
|
17
|
+
- Keep bridge MCP result flushing behind the bridge run abstraction rather than leaking protocol scheduling into provider pre-send drain.
|
|
18
|
+
|
|
19
|
+
## 0.1.40 - 2026-06-08
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
|
|
23
|
+
- Update the local pi validation baseline to `@earendil-works/pi-ai`, `@earendil-works/pi-coding-agent`, and `@earendil-works/pi-tui` `0.79.0` after reviewing current Pi extension, package, SDK/RPC, model/provider, and project-trust docs. Runtime Cursor setting-source defaults remain risk-on and unchanged: unset `PI_CURSOR_SETTING_SOURCES` still loads `all` Cursor setting sources.
|
|
24
|
+
- Make maintainer smoke/debug scripts pass Pi 0.79 `--approve` explicitly when they must load project-local package settings, extensions, or instructions in noninteractive release automation.
|
|
25
|
+
|
|
26
|
+
### Fixed
|
|
27
|
+
|
|
28
|
+
- Prune old local platform-smoke artifact run directories before new matrix runs so `.artifacts/platform-smoke` does not grow without bound while preserving recent and manual evidence directories.
|
|
29
|
+
|
|
5
30
|
## 0.1.39 - 2026-06-08
|
|
6
31
|
|
|
7
32
|
### Fixed
|
package/README.md
CHANGED
|
@@ -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.
|
|
54
|
+
- pi 0.79.1 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.
|
|
57
|
+
No global `@cursor/sdk` install is required. This package depends on exact `@cursor/sdk@1.0.18`, so normal package installation brings in the SDK version this extension was built and tested against. The Cursor SDK currently depends on `sqlite3@^5.1.7`, whose install path can print deprecated transitive `node-gyp@8` dependency warnings such as `inflight`, `rimraf`, `glob`, `npmlog`, `gauge`, `are-we-there-yet`, and `tar@6`. Those warnings are non-fatal and come from the closed-source Cursor SDK dependency boundary; this package cannot force npm overrides into consumer projects. If you install from a root `package.json` you control, you may choose a root-level override such as `"overrides": { "sqlite3": "6.0.1" }`; pi package installs will still follow npm's normal transitive dependency rules. 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.79.1 plus Cursor SDK 1.0.18; older pi compatibility paths are best-effort and older Cursor SDK compatibility paths are not maintained.
|
|
58
58
|
|
|
59
59
|
## Install
|
|
60
60
|
|
|
@@ -84,7 +84,7 @@ For development from this repository:
|
|
|
84
84
|
|
|
85
85
|
```bash
|
|
86
86
|
npm install
|
|
87
|
-
pi -e . --model cursor/composer-2-5
|
|
87
|
+
pi --approve -e . --model cursor/composer-2-5
|
|
88
88
|
```
|
|
89
89
|
|
|
90
90
|
## Configure your Cursor SDK API key
|
|
@@ -151,6 +151,7 @@ pi --list-models cursor
|
|
|
151
151
|
Expected behavior:
|
|
152
152
|
|
|
153
153
|
- with a valid key, Cursor models appear under the `cursor` provider
|
|
154
|
+
- on pi 0.79.x, the model table may be written to stderr in automation; treat exit 0 plus a table on either stdout or stderr as success
|
|
154
155
|
- if discovery cannot authenticate or reach Cursor, pi may still show fallback Cursor models; after adding auth with `/login`, fallback model runs can use the saved key, and `/cursor-refresh-models` refreshes the live catalog
|
|
155
156
|
|
|
156
157
|
Smoke test:
|
|
@@ -283,8 +284,8 @@ See [Cursor tool surfaces in pi](docs/cursor-tool-surfaces.md) for a concise gui
|
|
|
283
284
|
|
|
284
285
|
Cursor runs use local Cursor SDK agents with two separate tool surfaces:
|
|
285
286
|
|
|
286
|
-
- **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.
|
|
287
|
-
- **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.
|
|
287
|
+
- **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.
|
|
288
|
+
- **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.
|
|
288
289
|
|
|
289
290
|
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.
|
|
290
291
|
|
|
@@ -316,15 +317,15 @@ PI_CURSOR_TOOL_MANIFEST=0 pi --model cursor/composer-2-5
|
|
|
316
317
|
PI_CURSOR_PI_TOOL_BRIDGE_DEBUG=1 pi --model cursor/composer-2-5
|
|
317
318
|
```
|
|
318
319
|
|
|
319
|
-
On bootstrap sends, a compact **callable tool surfaces** block is injected into the Cursor prompt by default so models see host-tool categories, exposed `pi__*` bridge names for the current run, and a reminder that configured Cursor MCP servers are discovered at runtime (not via pi's tool catalog). Disable with `PI_CURSOR_TOOL_MANIFEST=0`.
|
|
320
|
+
On bootstrap sends, a compact **callable tool surfaces** block is injected into the Cursor prompt by default so models see host-tool categories, exposed `pi__*` bridge names for the current run, and a reminder that configured Cursor MCP servers are discovered at runtime (not via pi's tool catalog). It also states that pi's `--no-tools` disables pi tools/bridge exposure only; Cursor SDK host tools and configured Cursor MCP remain controlled by Cursor. Disable with `PI_CURSOR_TOOL_MANIFEST=0`.
|
|
320
321
|
|
|
321
322
|
`PI_CURSOR_PI_TOOL_BRIDGE=0` is the supported rollback flag and disables the bridge entirely. The bridge also treats `false`, `off`, `none`, `no`, and `disabled` as off; `1`, `true`, `on`, `yes`, and `enabled` as on. `PI_CURSOR_EXPOSE_BUILTIN_TOOLS=1` opts in to exposing overlapping pi tool names that Cursor already has native equivalents for. The installed Cursor SDK uses a 60-second MCP protocol default with no public per-server timeout option. pi-cursor-sdk overrides that seam in two directions by default: MCP `callTool` requests are extended to 3600 seconds for long-running local MCP tools (including the pi bridge and configured Cursor MCP servers), and known MCP initialize/listTools requests on first send are shortened to 10 seconds so unavailable configured MCP servers fail fast instead of blocking for a full minute. Unknown Cursor SDK MCP protocol timeout stacks keep the SDK default instead of being shortened. Override tool-call timeouts with `PI_CURSOR_MCP_TOOL_TIMEOUT_MS` or `PI_CURSOR_MCP_TOOL_TIMEOUT_SECONDS`, and first-send initialize/listTools timeouts with `PI_CURSOR_MCP_CONNECT_TIMEOUT_MS` or `PI_CURSOR_MCP_CONNECT_TIMEOUT_SECONDS`. `PI_CURSOR_PI_TOOL_BRIDGE_DEBUG=1` is off by default and emits typed, allowlisted, scrubbed single-line JSONL records to `process.stderr`. These records are operational diagnostics, not anonymous telemetry: they intentionally include tool names, safe correlation IDs, bridge run state, exposed pi↔MCP name pairs, queued requests, result resolution, rejection, cancellation, and pending counts. They must not include endpoint URLs, endpoint path components, endpoint tokens, raw args/results, stdout/stderr payloads, file contents, Cursor settings output, API keys, bearer tokens, cookies, session credentials, or secrets. Do not enable or share bridge debug logs where tool names themselves are sensitive.
|
|
322
323
|
|
|
323
324
|
### Maintainer platform smoke release gate
|
|
324
325
|
|
|
325
|
-
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. Do not mark a release ready with optional, deferred, mostly-passing, or unobserved platform smoke checks outstanding.
|
|
326
|
+
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.
|
|
326
327
|
|
|
327
|
-
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 -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.
|
|
328
|
+
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.
|
|
328
329
|
|
|
329
330
|
### Maintainer Cursor SDK event capture
|
|
330
331
|
|
|
@@ -348,12 +349,12 @@ Actual Cursor runs still need a key from `/login`, `CURSOR_API_KEY`, or `--api-k
|
|
|
348
349
|
- **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.
|
|
349
350
|
- **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.
|
|
350
351
|
- **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.
|
|
351
|
-
- **Final assistant text is the last non-empty text part.** Composer responses can produce one assistant message with early progress `text`, thinking/tool metadata, and a later final `text` report. Consumers that need a final answer should scan assistant message content from the end and use the last non-empty `text` part, not the first.
|
|
352
|
+
- **Final assistant text is the last non-empty text part.** Composer responses can produce one assistant message with early progress `text`, thinking/tool metadata, and a later final `text` report. Consumers that need a final answer should scan assistant message content from the end and use the last non-empty `text` part, not the first. Cursor `thinking` deltas are shown as thinking traces when the SDK emits them; those traces can include draft answers or copied exact-output targets and are intentionally not collapsed by this extension.
|
|
352
353
|
- **Cursor setting sources default to all.** The extension passes `local.settingSources: ["all"]` by default so configured Cursor MCP servers, plugin tools, project/user settings, and related Cursor-native capabilities are available like they are in Cursor. To narrow loading, set a comma-separated list such as `PI_CURSOR_SETTING_SOURCES=project,user,plugins`. To disable ambient setting sources, set `PI_CURSOR_SETTING_SOURCES=none`. Direct Cursor SDK bootstrap logs (settings, skills, hook-load compatibility warnings, and similar) are suppressed so they do not pollute the TUI.
|
|
353
354
|
- **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.
|
|
354
355
|
- **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.
|
|
355
356
|
- **Output token limits are conservative.** Cursor SDK model metadata does not currently expose output token limits directly.
|
|
356
|
-
- **Token usage is approximate in pi.** Cursor SDK usage events include cumulative internal agent/tool/cache work, so raw Cursor SDK counters are not copied into pi usage. The extension reports
|
|
357
|
+
- **Token usage is approximate in pi.** Cursor SDK usage events include cumulative internal agent/tool/cache work, so raw Cursor SDK counters are not copied into pi usage. The extension reports an additive replayable-context estimate instead: `output` estimates visible assistant output, `input` estimates the replayable Cursor context before that output, cache fields are zero, and `totalTokens = input + output + cacheRead + cacheWrite`. This keeps pi context display and compaction sizing consistent while avoiding Cursor's cumulative internal counters.
|
|
357
358
|
|
|
358
359
|
## Troubleshooting
|
|
359
360
|
|
|
@@ -478,7 +479,7 @@ Capture `pi --version`, extension version, model, flags, the exact prompt, and a
|
|
|
478
479
|
|
|
479
480
|
### Cursor native tool cards conflict with another extension
|
|
480
481
|
|
|
481
|
-
Cursor native replay is a
|
|
482
|
+
Cursor native replay is a display enhancement for TUI sessions and structured JSON/RPC consumers. It replays recorded Cursor SDK activity without re-running tools, and print mode remains text-first. See [Cursor native tool replay](docs/cursor-native-tool-replay.md) for conflict behavior and opt-out flags.
|
|
482
483
|
|
|
483
484
|
## Development
|
|
484
485
|
|
|
@@ -508,7 +509,7 @@ Local development run:
|
|
|
508
509
|
|
|
509
510
|
```bash
|
|
510
511
|
npm install
|
|
511
|
-
CURSOR_API_KEY="your-key" pi -e . --model cursor/composer-2-5
|
|
512
|
+
CURSOR_API_KEY="your-key" pi --approve -e . --model cursor/composer-2-5
|
|
512
513
|
```
|
|
513
514
|
|
|
514
515
|
Maintainer design notes live in [`docs/cursor-model-ux-spec.md`](docs/cursor-model-ux-spec.md).
|
|
@@ -4,7 +4,7 @@ Short maintainer checklist for **minimal-surface** validation after prompt, brid
|
|
|
4
4
|
|
|
5
5
|
## Minimal environment
|
|
6
6
|
|
|
7
|
-
- Extension only: `pi -e . --cursor-no-fast --model cursor/composer-2-5`
|
|
7
|
+
- Extension only: `pi --approve -e . --cursor-no-fast --model cursor/composer-2-5`
|
|
8
8
|
- Fresh session dir: `--session-dir /tmp/pi-cursor-dogfood-<id>`
|
|
9
9
|
- Baseline surface (no ambient Cursor MCP/rules):
|
|
10
10
|
- `PI_CURSOR_SETTING_SOURCES=none`, **or**
|
|
@@ -17,8 +17,14 @@ Short maintainer checklist for **minimal-surface** validation after prompt, brid
|
|
|
17
17
|
2. **Pi bridge** (if enabled) — one bridged call via exposed `pi__*` MCP name, e.g. `pi__cursor_ask_question` when active.
|
|
18
18
|
3. **Configured MCP** (optional) — only when you intentionally load Cursor MCP via settings; skip for minimal baseline.
|
|
19
19
|
|
|
20
|
+
`pi --no-tools` is a pi-registry toggle, not a Cursor SDK host-tool kill switch. In dogfood, expect it to remove pi bridge exposure while Cursor host tools can still run.
|
|
21
|
+
|
|
20
22
|
In-session debug: `/cursor-tools` prints bridge enablement, bootstrap manifest enablement, effective `PI_CURSOR_SETTING_SOURCES`, and the callable-surface manifest snapshot for the current session.
|
|
21
23
|
|
|
24
|
+
## CLI spot-check
|
|
25
|
+
|
|
26
|
+
`pi --approve -e . --list-models cursor` should exit 0 and show a Cursor model table. On pi 0.79.x that table can land on stderr in automation, so capture both streams or redirect `2>&1` before treating empty stdout as a discovery failure.
|
|
27
|
+
|
|
22
28
|
## JSONL spot-check
|
|
23
29
|
|
|
24
30
|
Inspect the session JSONL under the temp `--session-dir`:
|
|
@@ -9,7 +9,7 @@ Use this manual checklist during development and debugging of Cursor provider/ru
|
|
|
9
9
|
## Inner-loop rule
|
|
10
10
|
|
|
11
11
|
- Run from a clean working tree except for the intended branch diff.
|
|
12
|
-
- Use the local extension under test: `pi -e . --cursor-no-fast --model cursor/composer-2-5`.
|
|
12
|
+
- Use the local extension under test: `pi --approve -e . --cursor-no-fast --model cursor/composer-2-5`.
|
|
13
13
|
- Use a temporary `--session-dir` for every run.
|
|
14
14
|
- Do not paste or commit Cursor API keys, raw session contents with secrets, endpoint URLs, or local private paths.
|
|
15
15
|
- If an inner-loop check fails, stop and fix or use [docs/platform-smoke.md](./platform-smoke.md) as the release-blocking source of truth. Do not treat this checklist as a narrower replacement for the platform gate.
|
|
@@ -23,7 +23,7 @@ export SMOKE_DIR="/tmp/pi-cursor-sdk-live-smoke-$(date +%Y%m%dT%H%M%S)"
|
|
|
23
23
|
mkdir -p "$SMOKE_DIR"
|
|
24
24
|
pi --version
|
|
25
25
|
npm ls @cursor/sdk @earendil-works/pi-coding-agent @earendil-works/pi-ai @earendil-works/pi-tui
|
|
26
|
-
pi -e . --list-models cursor
|
|
26
|
+
pi --approve -e . --list-models cursor
|
|
27
27
|
```
|
|
28
28
|
|
|
29
29
|
Live pi runs resolve provider auth from **`~/.pi/agent/auth.json`**, not only shell env. Isolated smoke copies that file into a clean temporary `HOME`. Ensure `auth.json` includes a `cursor` provider entry, or export `CURSOR_API_KEY` as a fallback.
|
|
@@ -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.
|
|
71
|
-
- `npm ls` shows `@cursor/sdk@1.0.
|
|
70
|
+
- `pi --version` reports pi 0.79.1 for this cutover baseline.
|
|
71
|
+
- `npm ls` shows `@cursor/sdk@1.0.18` and local `@earendil-works/*@0.79.1` 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.
|
|
@@ -77,7 +77,7 @@ Pass criteria:
|
|
|
77
77
|
|
|
78
78
|
```bash
|
|
79
79
|
PI_CURSOR_SETTING_SOURCES=none \
|
|
80
|
-
pi -e . --cursor-no-fast --model cursor/composer-2-5 \
|
|
80
|
+
pi --approve -e . --cursor-no-fast --model cursor/composer-2-5 \
|
|
81
81
|
--session-dir "$SMOKE_DIR/basic" \
|
|
82
82
|
--no-tools \
|
|
83
83
|
-p 'Live smoke. Reply exactly: PI_CURSOR_SMOKE_OK' \
|
|
@@ -95,7 +95,7 @@ Pass criteria:
|
|
|
95
95
|
## 2. Default setting-source startup noise check
|
|
96
96
|
|
|
97
97
|
```bash
|
|
98
|
-
pi -e . --cursor-no-fast --model cursor/composer-2-5 \
|
|
98
|
+
pi --approve -e . --cursor-no-fast --model cursor/composer-2-5 \
|
|
99
99
|
--session-dir "$SMOKE_DIR/default-settings" \
|
|
100
100
|
--no-tools \
|
|
101
101
|
-p 'Default settings smoke. Include PRODUCT=42 in the final answer.' \
|
|
@@ -117,7 +117,7 @@ Run a real interactive session under tmux:
|
|
|
117
117
|
```bash
|
|
118
118
|
SESSION="pi-cursor-sdk-smoke-$(date +%s)"
|
|
119
119
|
tmux new-session -d -s "$SESSION" -x 120 -y 40 -- zsh -lc \
|
|
120
|
-
"cd '$PWD' && PI_CURSOR_SETTING_SOURCES=none pi -e . --cursor-no-fast --model cursor/composer-2-5 --session-dir '$SMOKE_DIR/tui' --session-id cursor-sdk-1016-tui --no-tools 'TUI smoke. Compute 19 + 23. Reply only with SUM=<number>.'"
|
|
120
|
+
"cd '$PWD' && PI_CURSOR_SETTING_SOURCES=none pi --approve -e . --cursor-no-fast --model cursor/composer-2-5 --session-dir '$SMOKE_DIR/tui' --session-id cursor-sdk-1016-tui --no-tools 'TUI smoke. Compute 19 + 23. Reply only with SUM=<number>.'"
|
|
121
121
|
```
|
|
122
122
|
|
|
123
123
|
Observe with `tmux capture-pane -pt "$SESSION"` or attach manually.
|
|
@@ -125,7 +125,7 @@ Observe with `tmux capture-pane -pt "$SESSION"` or attach manually.
|
|
|
125
125
|
Pass criteria:
|
|
126
126
|
|
|
127
127
|
- Footer shows `(cursor) composer-2-5`. With `--cursor-no-fast`, Cursor fast mode is off and the Cursor extension status should not show `cursor fast`; ignore unrelated status text from other extensions.
|
|
128
|
-
- The run uses pi 0.
|
|
128
|
+
- The run uses pi 0.79.1 `--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.
|
|
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.79.1, `@cursor/sdk@1.0.18`, 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)"
|
|
@@ -204,7 +204,7 @@ Pass criteria:
|
|
|
204
204
|
|
|
205
205
|
```bash
|
|
206
206
|
PI_CURSOR_SETTING_SOURCES=none \
|
|
207
|
-
pi -e . --cursor-no-fast --cursor-mode plan --model cursor/composer-2-5 \
|
|
207
|
+
pi --approve -e . --cursor-no-fast --cursor-mode plan --model cursor/composer-2-5 \
|
|
208
208
|
--session-dir "$SMOKE_DIR/cursor-mode-plan" \
|
|
209
209
|
--session-id cursor-sdk-1016-plan \
|
|
210
210
|
--no-tools \
|
|
@@ -226,7 +226,7 @@ Pass criteria:
|
|
|
226
226
|
PI_CURSOR_SETTING_SOURCES=none \
|
|
227
227
|
PI_CURSOR_EXPOSE_BUILTIN_TOOLS=1 \
|
|
228
228
|
PI_CURSOR_PI_TOOL_BRIDGE_DEBUG=1 \
|
|
229
|
-
pi -e . --cursor-no-fast --model cursor/composer-2-5 \
|
|
229
|
+
pi --approve -e . --cursor-no-fast --model cursor/composer-2-5 \
|
|
230
230
|
--session-dir "$SMOKE_DIR/bridge" \
|
|
231
231
|
-p 'Bridge smoke. Do exactly two tool calls before answering: first call pi__read on ./package.json; second call pi__read on ./definitely-missing-pi-cursor-sdk-smoke-file.txt. Then answer: OK_NAME=<package name>; MISSING_RESULT=<error or success>. Do not use shell.' \
|
|
232
232
|
> "$SMOKE_DIR/bridge.stdout.txt" \
|
|
@@ -247,7 +247,7 @@ Pass criteria:
|
|
|
247
247
|
PI_CURSOR_SETTING_SOURCES=none \
|
|
248
248
|
PI_CURSOR_PI_TOOL_BRIDGE=0 \
|
|
249
249
|
PI_CURSOR_NATIVE_TOOL_DISPLAY=1 \
|
|
250
|
-
pi -e . --cursor-no-fast --model cursor/composer-2-5 \
|
|
250
|
+
pi --approve -e . --cursor-no-fast --model cursor/composer-2-5 \
|
|
251
251
|
--session-dir "$SMOKE_DIR/native-replay" \
|
|
252
252
|
-p 'Native replay smoke. Use your Cursor file-reading capability to read ./README.md, then answer README_SEEN=yes if it contains pi-cursor-sdk.' \
|
|
253
253
|
> "$SMOKE_DIR/native-replay.stdout.txt" \
|
|
@@ -321,7 +321,7 @@ Use a harmless long-running command and interrupt it after the bridge request is
|
|
|
321
321
|
PI_CURSOR_SETTING_SOURCES=none \
|
|
322
322
|
PI_CURSOR_EXPOSE_BUILTIN_TOOLS=1 \
|
|
323
323
|
PI_CURSOR_PI_TOOL_BRIDGE_DEBUG=1 \
|
|
324
|
-
pi -e . --cursor-no-fast --model cursor/composer-2-5 \
|
|
324
|
+
pi --approve -e . --cursor-no-fast --model cursor/composer-2-5 \
|
|
325
325
|
--session-dir "$SMOKE_DIR/abort" \
|
|
326
326
|
-p 'Abort smoke. Call pi__bash with command: sleep 30 && echo SHOULD_NOT_PRINT. Do not answer until the tool completes.'
|
|
327
327
|
```
|
|
@@ -15,7 +15,7 @@ Current implementation notes:
|
|
|
15
15
|
- Cursor status uses one coordinated `ctx.ui.setStatus("cursor", ...)` value for fast and non-default plan mode; the default pi footer remains intact.
|
|
16
16
|
- Installed `@cursor/sdk` user messages accept images, and Cursor models are treated as image-capable; registered input metadata is `text` plus `image`.
|
|
17
17
|
- Image payload forwarding sends images only from the latest user message. If the latest user turn is plain text after an earlier image turn, the transcript keeps an `[image omitted from transcript]` placeholder but no image bytes are sent to Cursor. The prompt explicitly tells Cursor that prior image bytes are unavailable and to ask the user to reattach or describe a prior image when needed. Carrying images forward across turns remains a future product decision because it affects token cost, privacy, stale visual context, and expected multimodal follow-up behavior.
|
|
18
|
-
- Exact `@cursor/sdk@1.0.
|
|
18
|
+
- Exact `@cursor/sdk@1.0.18` is a package dependency of this extension; users should not need a global SDK install. pi 0.79.1 is the current recommended validation baseline, while published pi core peer dependencies use `"*"` ranges per current pi package guidance. Newer pi versions are allowed to attempt loading this extension before a matching extension release exists; compatibility is best-effort until validated.
|
|
19
19
|
- Cursor auth uses pi-native API-key resolution for provider `cursor`: CLI `--api-key`, stored `~/.pi/agent/auth.json` API key from `/login`, then `CURSOR_API_KEY`. The extension config file stores only non-secret Cursor-only state such as fast defaults.
|
|
20
20
|
- Local agents pass `settingSources: ["all"]` by default so Cursor MCP servers, plugin tools, project/user settings, and related Cursor-native capabilities are available. Users can narrow loading with a comma-separated list such as `PI_CURSOR_SETTING_SOURCES=project,user,plugins`, or disable ambient setting sources with `PI_CURSOR_SETTING_SOURCES=none`. The provider suppresses direct Cursor SDK bootstrap stdout/stderr/console noise (including late first-send workspace loading such as hook compatibility warnings) so it does not pollute pi's TUI.
|
|
21
21
|
- On `cursor/*` models, pi-cursor-sdk removes only pi-generated `<project_instructions>` blocks that overlap the effective Cursor `settingSources`: `user` for `~/.pi/agent/AGENTS.md`; `project` for discovered repo/parent `AGENTS.md` and `CLAUDE.md` (verified Cursor behavior: local agents load project `AGENTS.md` and `CLAUDE.md`). `~/.pi/agent/CLAUDE.md` is not removed (Cursor user layer uses `~/.claude/CLAUDE.md`). Blocks are removed by exact pi serialization match from structured `contextFiles` via the `before_agent_start` hook, not in `buildCursorPrompt` sanitization. Suppression is skipped with `-nc`, `PI_CURSOR_SETTING_SOURCES=none`, narrowed sources such as `plugins` that omit the matching layer, or `PI_CURSOR_PRESERVE_PI_AGENTS_MD=1`. Switching away from a Cursor model restores pi's full context block on the next user message.
|
|
@@ -26,17 +26,17 @@ Current implementation notes:
|
|
|
26
26
|
- Prompt text is the primary provider/bridge contract. Bootstrap prompts carry a short boundary block plus the callable-surface manifest by default (`PI_CURSOR_TOOL_MANIFEST=1`). MCP `listTools` descriptions use a one-line pointer to the bootstrap prompt instead of repeating the full contract (`buildCursorPiBridgeMcpToolDescription()`). Cursor must call the exposed `pi__*` MCP name, not the real pi tool name shown in pi history or transcripts. Pi emits and executes the real pi tool name. Maintainer debug: `/cursor-tools` prints bridge/manifest enablement, effective `PI_CURSOR_SETTING_SOURCES`, and the current callable-surface snapshot.
|
|
27
27
|
- The provider also registers `cursor_ask_question` for Cursor models when the bridge is enabled. Cursor sees it as `pi__cursor_ask_question`, and pi executes it through the normal tool path so interactive users can choose options from pi UI. In non-UI modes it reports that UI is unavailable so Cursor can state a default assumption instead. When pi has visible Agent Skills loaded, the provider rewrites the skill catalog for Cursor and registers `cursor_activate_skill` as `pi__cursor_activate_skill`; pi executes it through the normal tool path so Cursor can load the full `SKILL.md` and skill resource list for the current pi-loaded skill source of truth. `PI_CURSOR_PI_TOOL_BRIDGE=0` disables the local bridge, including question and skill activation bridging. Cloud Cursor agents remain out of scope for the bridge.
|
|
28
28
|
- The bridge queues MCP calls, emits provider `toolcall_*` events, waits for matching pi `toolResult` messages by `toolCallId`, resolves the result back into the same live Cursor SDK run without creating a new `Agent`, and never calls tool `execute()` handlers directly. The same-run resume invariant holds unless the run was disposed, aborted, or cancelled.
|
|
29
|
-
- Cursor SDK MCP tool calls use a guarded timeout override because installed `@cursor/sdk` 1.0.
|
|
29
|
+
- Cursor SDK MCP tool calls use a guarded timeout override because installed `@cursor/sdk` 1.0.18 has a 60-second MCP request default with no public per-server timeout option. The extension extends the verified Cursor SDK MCP `callTool` timeout path to 3600 seconds by default and shortens the verified first-send MCP initialize/listTools timeout paths to 10 seconds by default so unavailable configured MCP servers do not block the first reply for a full minute; unknown MCP protocol timeout stacks keep the SDK default. Users can override tool-call timeouts with `PI_CURSOR_MCP_TOOL_TIMEOUT_MS` or `PI_CURSOR_MCP_TOOL_TIMEOUT_SECONDS`, and initialize/listTools timeouts with `PI_CURSOR_MCP_CONNECT_TIMEOUT_MS` or `PI_CURSOR_MCP_CONNECT_TIMEOUT_SECONDS`.
|
|
30
30
|
- Bridge diagnostics are opt-in only: `PI_CURSOR_PI_TOOL_BRIDGE_DEBUG=1` writes typed, allowlisted, scrubbed single-line JSONL records to `process.stderr` with prefix `[pi-cursor-sdk:bridge]`. Diagnostics are scrubbed operational logs, not anonymous telemetry. They intentionally include tool names, safe correlation IDs, run lifecycle, exposed pi↔MCP name pairs, queued requests, result resolution, rejection, cancellation, and pending counts. Correlation IDs are generated independently from the tokenized endpoint path, and Cursor MCP call IDs are hashed before serialization. Diagnostics must not include endpoint paths/URLs/path components/tokens, API keys, bearer tokens, cookies, session credentials, raw args/results, stdout/stderr payloads, file contents, Cursor settings output, or local private session paths in tracked docs, and they must not call pi UI status, notification, or footer APIs. If tool names themselves are unacceptable for a release target, bridge debug diagnostics are not safe for shared logs under the current contract.
|
|
31
31
|
- This repo does not provide a generic desktop-automation, browser-driver, or CDP recipe. Provider docs should describe pi-cursor-sdk's Cursor provider/bridge contract only.
|
|
32
|
-
- Cursor internal tool activity is recorded from SDK events and scrubbed. Maintainer reference for all 16 `@cursor/sdk@1.0.
|
|
32
|
+
- Cursor internal tool activity is recorded from SDK events and scrubbed. Maintainer reference for all 16 `@cursor/sdk@1.0.18` `ToolType` values, runtime alias normalization, and intentional mapping/fallback rules: [Cursor native tool replay — SDK ToolType replay matrix](./cursor-native-tool-replay.md#sdk-tooltype-replay-matrix) (official SDK docs: https://cursor.com/docs/sdk/typescript). In TUI sessions and structured JSON/RPC modes, supported completed `read`, `bash`, `grep`, `find`, `ls`, `edit`, `write`, diagnostics, delete, todo/plan, task, image generation, MCP, semantic search, and screen recording activity is replayed through pi's native tool-call rendering path with recorded Cursor results, so users and JSON/RPC consumers can see native-looking cards/events without rerunning Cursor's reads/shell commands/file edits. Cursor `glob` activity is replayed through native `find` cards. Cursor write activity is replayed through native-looking `write` cards, and Cursor StrReplace/edit activity uses native-looking `edit` only when recorded arguments truthfully satisfy pi's `edit` schema; path-only Cursor edit and notebook edit replay falls back to neutral Cursor activity before pi validation. Diagnostics, delete, todos/plans, task, image, and MCP activity use neutral Cursor activity cards with pi's default success/error shell. Neutral Cursor activity calls include `activityTitle` and, when available, `activitySummary` so partial/collapsed cards preserve identity such as `Cursor plan`, `Cursor todos`, `Cursor MCP`, or `Cursor edit`. For long-running or externally meaningful Cursor tools (`task`, `shell`, `mcp`, `generateImage`, `recordScreen`, `semSearch`, web search/fetch, plan/todo), the provider may surface one low-noise deferred in-progress thinking line such as `Cursor MCP: external_search` from bounded, scrubbed SDK args; fast local tools (`read`, `grep`, `glob`, and similar) skip lifecycle lines when completion follows immediately, and pi bridge MCP calls are excluded because pi already shows real pi tool execution ([lifecycle visibility](./cursor-native-tool-replay.md#low-noise-tool-lifecycle-visibility)). Replay-only tools display recorded Cursor results, normalize workspace-local paths/diff headers for display, use pi diff colors for edit previews and path-inferred syntax highlighting for write previews, and fail closed if called without a recorded result. Native replay wrappers are registered only for tool names not already owned by another extension; conflicting tools use the bounded scrubbed transcript fallback. Cursor workflow tools such as mode/task/todo/plan activity are not pi workflow controls; reported todo/plan events are displayed as Cursor activity only. Plan/todo replay cards can be followed by Cursor's final plan text, selected from `run.wait().result` when Cursor provides one and trimmed against already-emitted text. Started Cursor SDK tool calls that never receive a completion event are surfaced with bounded user-visible labels/traces (neutral activity cards when native replay routing allows, otherwise the same inactive or transcript trace fallbacks used for completed replay) instead of being silently discarded when the run failed/aborted, produced no assistant text, or involved external/side-effectful tools; incomplete fast local discovery starts (`read`, `grep`, `glob`, `ls`) remain maintainer-debug-only after successful text-producing runs so stale SDK start events do not create red post-answer cards. Explicit failures remain visible when Cursor reports them through completed tool calls or step results. Pi bridge MCP starts remain excluded from duplicate incomplete Cursor cards because pi already shows real pi tool execution. `PI_CURSOR_NATIVE_TOOL_DISPLAY=0` disables native replay, and `PI_CURSOR_REGISTER_NATIVE_TOOLS=0` is a registration-only opt-out that keeps the transcript fallback without shadowing pi tool names. When bridge or native replay cards are emitted, the provider mirrors Codex's turn shape as Cursor SDK activity arrives: assistant `toolUse`, pi `toolResult`s, live post-tool Cursor thinking/text, any later tool batches as further `toolUse` turns, then Cursor's final assistant answer. For shell replay, completed `stdout` / `stderr` are primary; unambiguous `shell-output-delta` data is also shown as bounded live progress while one shell call is active and used as display-only fallback for empty successful shell completions, while overlapping shell calls drop ambiguous deltas instead of guessing. Print mode keeps bounded scrubbed transcript output instead, preserving `pi -p` assistant text output. Cursor text deltas stream live when no live-run turn split is active.
|
|
33
33
|
- Cursor native replay uses one neutral replay tool name, `cursor`, plus native-compatible card names when renderer-compatible (`read`, `bash`, `grep`, `find`, `ls`, `edit`, `write`). Neutral replay identity lives in `activityTitle`, `activitySummary`, and typed replay details, not in extra registered tool names. Bridge MCP names such as `pi__sem_reindex` are MCP-only; pi session output uses real pi tool names.
|
|
34
|
-
- Cursor SDK usage events report cumulative internal agent/tool/cache work, not the replayable pi prompt context. The extension does not copy raw Cursor SDK usage into pi usage or compaction. For Cursor assistant messages, `usage.
|
|
34
|
+
- Cursor SDK usage events report cumulative internal agent/tool/cache work, not the replayable pi prompt context. The extension does not copy raw Cursor SDK usage into pi usage or compaction. For Cursor assistant messages, `usage.output` estimates visible assistant output, `usage.input` estimates the replayable Cursor context before that output, cache fields are zero, and `usage.totalTokens = input + output + cacheRead + cacheWrite`. The input/total estimate is derived from the same `buildCursorPrompt()` path used for `Agent.send` so context display and compaction keep using replayable Cursor context sizing while pi session summaries remain additive. `src/cursor-usage-accounting.ts` owns this usage policy.
|
|
35
35
|
- Audit observation, 2026-05-19, superseded by the 2026-05-21 replay pass and #68 incomplete visibility, then narrowed by the 2026-05-26 fast-local suppression: a missing-file read with Composer 2.5 emitted `tool-call-started` for Cursor `read`, then streamed final text `Error: File not found`, but did not emit `tool-call-completed` or an `onStep` `toolCall` error result. Leftover external/side-effectful started calls are surfaced at run completion through the same native replay routing as completed tools (activity cards when allowed, otherwise inactive/transcript traces), while fast local discovery starts are debug-only after a successful text-producing run. Cursor-reported completed/step errors remain visible.
|
|
36
36
|
- Maintainer visual verification for replay-card changes should follow [Cursor Native Tool Visual Audit Workflow](./cursor-native-tool-visual-audit.md): offscreen PTY-driven pi run, xterm.js/Playwright screenshot rendering, and JSONL inspection before accepting commits or PRs.
|
|
37
|
-
- Cursor provider/runtime releases must pass the [Platform Smoke Gate](./platform-smoke.md): `npm run smoke:platform:doctor && npm run smoke:platform:all`. Use [Cursor Live Smoke Checklist](./cursor-live-smoke-checklist.md) only for focused inner-loop/debug runs with real `pi -e . --cursor-no-fast --model cursor/composer-2-5` invocations, manual observation, temporary session dirs, diagnostics scans, and persisted JSONL inspection. See [Cursor testing lessons](./cursor-testing-lessons.md) for auth.json seeding, isolated smoke harnesses, and replay JSONL scans. Assume every runtime surface is in scope.
|
|
37
|
+
- Cursor provider/runtime releases must pass the [Platform Smoke Gate](./platform-smoke.md): `npm run smoke:platform:doctor && npm run smoke:platform:all`. Use [Cursor Live Smoke Checklist](./cursor-live-smoke-checklist.md) only for focused inner-loop/debug runs with real `pi --approve -e . --cursor-no-fast --model cursor/composer-2-5` invocations, manual observation, temporary session dirs, diagnostics scans, and persisted JSONL inspection. See [Cursor testing lessons](./cursor-testing-lessons.md) for auth.json seeding, isolated smoke harnesses, and replay JSONL scans. Assume every runtime surface is in scope.
|
|
38
38
|
- For models without a catalog `context` parameter, context windows are not hardcoded. The extension ships a bundled SDK-derived default/non-Max cache generated from `createAgentPlatform().checkpointStore.loadLatest(agentId).tokenDetails.maxTokens`. Successful runs can update a local override cache, but model discovery does not probe models at startup.
|
|
39
|
-
- Max Mode context windows are distinct from default/non-Max context windows. `@cursor/sdk` 1.0.
|
|
39
|
+
- Max Mode context windows are distinct from default/non-Max context windows. `@cursor/sdk` 1.0.18 documentation says the SDK may enable Max Mode automatically when a selected model requires it, but the public local-agent `ModelSelection` path still does not expose a manual Max Mode selector. Do not advertise Max Mode context windows unless the SDK catalog exposes an exact parameter/variant or the SDK public API adds a Max Mode selector that the extension actually sends.
|
|
40
40
|
- The installed `@cursor/sdk` exposes latest-style `ModelListItem.aliases`. The extension registers only unambiguous aliases as pi model IDs (with the same context suffixes when applicable) and sends the alias back in `ModelSelection.id`. Cursor-only fast preferences are keyed by the selected SDK model ID/alias, with read fallback for older preferences keyed by the underlying catalog `id`. Aliases shared by multiple base models, such as generic family aliases, are skipped because the pi row metadata would otherwise imply one base model while Cursor may resolve the alias to another.
|
|
41
41
|
- Session-scoped Cursor SDK agent pooling reuses one live `@cursor/sdk` agent across compatible follow-up turns within the same pi session scope. `planCursorSessionSend()` in `src/cursor-session-send-policy.ts` decides whether the next turn sends a full bootstrap prompt or an incremental follow-up, whether the SDK agent must be recreated, and why. `computeCursorContextFingerprint()` and `shouldBootstrapCursorContext()` remain the context-only bootstrap signal. The pool recreates the agent when context diverges, when branch or compaction summaries appear after `/tree` navigation or compaction, after 20 completed incremental sends, when the API key identity changes, after send errors, on `session_shutdown`, and when `session_before_tree` / `session_tree` invalidate the active branch. Incremental sends omit the full Cursor SDK tool boundary block because the session agent retains prior bootstrap context, but every send ends with a short tool tail guard placed after the latest user request (including an explicit shell `cd` hint).
|
|
42
42
|
- Pi steering/follow-up delivery can arrive while a split live Cursor SDK run is still active. The provider resolves pending live runs by scanning trailing `toolResult` messages while skipping trailing `user` messages, tracks the active live run per session scope, and resumes the in-flight run instead of calling `Agent.send()` again. When the context ends with steering user text after tool results, the provider releases the prior live run and chains an incremental `Agent.send()` for the latest user message in the same provider turn; if the prior run emits more text or tool requests after steering arrives, that stale activity is cancelled instead of surfacing another old-run tool turn and losing the new user input. A pre-send guard waits for or resumes any still-active scoped live run before starting a fresh send so `@cursor/sdk` `AgentBusyError` (`already has active run`) does not surface to pi users. Pooled session agents mark busy as soon as live/direct `run.wait()` tracking starts (`trackRunCompletion` on the session lease), and `acquireSessionCursorAgent()` awaits that busy state before returning a lease so send planning, transcript offsets, and later `Agent.send()` do not race the prior turn's SDK run completion (for example pi auto-compaction summarization). `session_before_compact` calls `prepareCursorSessionForCompaction()` to release scoped live-run drain state and reset the pooled agent before summarization streams. Tracked completions and send commits are scoped to the pooled agent `instanceId` so disposal/replacement drops stale tracking and ignores late commits from disposed agents.
|
|
@@ -386,7 +386,7 @@ cursor fast
|
|
|
386
386
|
|
|
387
387
|
## Cursor SDK Mode Behavior
|
|
388
388
|
|
|
389
|
-
Cursor SDK 1.0.
|
|
389
|
+
Cursor SDK 1.0.18 exposes SDK-native conversation mode:
|
|
390
390
|
|
|
391
391
|
```ts
|
|
392
392
|
type AgentModeOption = "agent" | "plan";
|
|
@@ -544,7 +544,7 @@ pi --model cursor/gpt-5.5@1m --cursor-fast -p "Say ok only"
|
|
|
544
544
|
|
|
545
545
|
## Discovered Model Capability Examples
|
|
546
546
|
|
|
547
|
-
These examples document the capability shapes the extension handles, not an exhaustive live catalog. The exact Cursor catalog changes over time; use `pi -e . --list-models cursor` or `Cursor.models.list()` for the current model surface. When the SDK reports aliases, only unambiguous aliases are registered; shared generic aliases are skipped.
|
|
547
|
+
These examples document the capability shapes the extension handles, not an exhaustive live catalog. The exact Cursor catalog changes over time; use `pi --approve -e . --list-models cursor` or `Cursor.models.list()` for the current model surface. When the SDK reports aliases, only unambiguous aliases are registered; shared generic aliases are skipped.
|
|
548
548
|
|
|
549
549
|
| Example model shape | Cursor controls | Pi representation |
|
|
550
550
|
|---|---|---|
|
|
@@ -62,13 +62,13 @@ When Cursor reports completed tool activity, the extension can display recorded
|
|
|
62
62
|
|
|
63
63
|
Cursor `glob` activity is displayed through native `find` cards.
|
|
64
64
|
|
|
65
|
-
For the full `@cursor/sdk@1.0.
|
|
65
|
+
For the full `@cursor/sdk@1.0.18` `ToolType` set, disposition matrix, and runtime alias normalization, see [SDK ToolType replay matrix](#sdk-tooltype-replay-matrix) below. Official SDK reference: https://cursor.com/docs/sdk/typescript
|
|
66
66
|
|
|
67
67
|
Edit and write activity replays through pi-facing `edit` and `write` cards only when replay arguments truthfully satisfy the matching pi schema, but still uses recorded Cursor results only. The adapter passes through truthful Cursor paths, content when Cursor reported it, and recorded diff/details; it does not pretend Cursor's editing schema is pi's schema and it fails closed if a recorded replay result is missing. Cursor `StrReplace` with recorded replacement text displays as native-looking `edit`; path-only Cursor `edit` and notebook edit activity fall back to neutral Cursor activity so pi does not reject the replay before recorded-result handling. Cursor `write` displays as native-looking `write`. Diagnostics, delete, todos/plans, task, image, MCP, semantic search, screen recording, and web search/fetch activity use neutral Cursor activity cards with pi's default success/error tool shell. MCP completions whose `toolName` is `WebSearch` / `web_search` / `WebFetch` / similar are labeled **Cursor web search** or **Cursor web fetch** instead of generic **Cursor MCP**. Neutral Cursor activity cards carry display metadata such as `activityTitle` and `activitySummary`, so partial/collapsed cards can say `Cursor plan`, `Cursor todos`, `Cursor MCP`, `Cursor semantic search`, `Cursor screen recording`, `Cursor web search`, `Cursor web fetch`, or `Cursor edit` instead of only `Cursor activity`. These replay tools only display recorded Cursor results; they never mutate files or execute tool work directly. Replay paths are normalized to workspace-relative paths when possible. Most collapsed replay cards include bounded previews for diffs and text details so small edits, todos, task output, and MCP results are visible without expanding; web search/fetch activity stays summary-only while collapsed because those cards often arrive after final text and can otherwise bury the answer. Ctrl+O expansion shows the recorded details. Edit previews omit raw unified diff headers and show compact numbered changed/context lines using pi's native diff added/removed/context colors, and write previews use syntax highlighting when pi can infer a language from the path. Image generation replay cards show the saved image path in the collapsed summary and render the image inline when pi terminal image display is enabled and the generated file is still readable.
|
|
68
68
|
|
|
69
69
|
## SDK ToolType replay matrix
|
|
70
70
|
|
|
71
|
-
Source of truth for SDK tool names: `@cursor/sdk@1.0.
|
|
71
|
+
Source of truth for SDK tool names: `@cursor/sdk@1.0.18` conversation `ToolType` values and https://cursor.com/docs/sdk/typescript
|
|
72
72
|
|
|
73
73
|
Implementation owners: `src/cursor-tool-presentation-registry.ts` (canonical names, labels, visibility, replay policy, bridge exclusions for internal replay wrappers, alias normalization, and display-spec key completeness), `src/cursor-transcript-tool-specs.ts` (registry-keyed display implementations for transcript formatting and pi display builders), `src/cursor-native-tool-display-replay.ts` (replay card rendering derived from registry replay metadata), and `src/cursor-web-tool-activity.ts` (MCP/web alias remapping before display lookup).
|
|
74
74
|
|
|
@@ -178,11 +178,11 @@ Lifecycle rules:
|
|
|
178
178
|
|
|
179
179
|
As Cursor SDK tool completions arrive, the extension mirrors native Codex ordering by ending a tool-use turn, letting pi render the recorded tool results, then continuing with live post-tool Cursor thinking/text, later Cursor tool batches, or Cursor's final answer as the next assistant turn. For plan-mode runs, neutral Cursor plan/todo cards can therefore appear before the final Cursor plan text.
|
|
180
180
|
|
|
181
|
-
Bridged pi tool calls follow the same visible pi `toolUse` turn shape, but they are real pi tool executions rather than replayed Cursor results.
|
|
181
|
+
Bridged pi tool calls follow the same visible pi `toolUse` turn shape, but they are real pi tool executions rather than replayed Cursor results. Usage accounting keeps Cursor SDK internal counters out of pi usage and reports an additive replayable-context estimate: `output` estimates visible assistant activity, `input` estimates the replayable Cursor context before that output, cache fields are zero, and `usage.totalTokens = input + output + cacheRead + cacheWrite`.
|
|
182
182
|
|
|
183
183
|
For shell replay, completed `stdout` / `stderr` remain the primary source. While exactly one shell call is active, the provider also emits a bounded scrubbed preview of the first few `shell-output-delta` stdout/stderr chunks so long-running commands show visible progress before completion. If a successful completed shell result is empty, the replay card uses unambiguous buffered delta data as display-only fallback data. Overlapping shell calls make delta attribution ambiguous, so those fallback/progress deltas are dropped rather than guessed. `(no output)` is kept only when no completed output or safe delta fallback is available.
|
|
184
184
|
|
|
185
|
-
|
|
185
|
+
JSON and RPC consumers receive structured replay for completed Cursor host tools when replay wrappers are active: host activity is emitted as pi `toolcall_*` / `tool_execution_*` events backed by recorded Cursor results, not by re-running the host tool. Print mode stays text-first so `pi -p` keeps printing normal assistant text. When replay wrappers are inactive, such as with `--no-tools`, non-interactive consumers fall back to bounded scrubbed transcript data in thinking blocks.
|
|
186
186
|
|
|
187
187
|
## Replay-name policy
|
|
188
188
|
|
|
@@ -6,16 +6,16 @@ This workflow is the canonical repo path for verifying Cursor SDK tool replay th
|
|
|
6
6
|
|
|
7
7
|
Use it before accepting replay-card commits or PRs, and for every Cursor provider/runtime release where TUI card/color behavior could regress. Text logs and JSONL are necessary, but they are not enough when the claim is visual parity: always keep PNGs for the exact prompt, and keep before/after PNGs when reviewing a rendering change.
|
|
8
8
|
|
|
9
|
-
Current validation baseline: pi 0.
|
|
9
|
+
Current validation baseline: pi 0.79.1, exact `@cursor/sdk@1.0.18`, local validation packages `@earendil-works/pi-ai`, `@earendil-works/pi-coding-agent`, and `@earendil-works/pi-tui` at 0.79.1. Published pi core peer dependencies use `"*"` ranges per current pi package guidance, so newer pi installs can try the extension before a matching validation release exists.
|
|
10
10
|
|
|
11
|
-
## Cursor SDK 1.0.17 / pi 0.
|
|
11
|
+
## Cursor SDK 1.0.17 / pi 0.79.0 cutover visual record
|
|
12
12
|
|
|
13
13
|
Record the required cutover validation here or in the final release handoff. The default matrix is native replay only: the runner forces native replay registration on, forces Cursor setting sources off, disables the pi bridge, disables overlapping built-in pi tool exposure, and clears inherited Cursor SDK event-debug artifact env. With `--event-debug`, debug capture writes to a deterministic directory under the visual output directory. Do not commit raw ANSI logs, screenshots, terminal recordings, debug artifacts, or `.debug/visual-smoke` scratch files.
|
|
14
14
|
|
|
15
15
|
| Field | Required value / evidence |
|
|
16
16
|
| --- | --- |
|
|
17
17
|
| Command/session used | `npm run smoke:visual -- --ext "$PWD" --cwd "$PWD" --mode plan --out-dir <fresh /tmp dir> --label <matrix label> --prompt <matrix prompt>` with default native-replay isolation |
|
|
18
|
-
| Baseline versions | `pi --version` = 0.
|
|
18
|
+
| Baseline versions | `pi --version` = 0.79.0; `npm ls` = `@cursor/sdk@1.0.17` and local `@earendil-works/*@0.79.0` |
|
|
19
19
|
| Card categories checked | Claim only categories proven by both PNG and JSONL. Required cutover categories are read, grep/search, find/glob, shell success, write, edit/diff, and true read failure. Direct `ls`/list is tracked as excluded from the current one-prompt platform matrix because composer-2-5 does not route it through native `ls` reliably; source-enumeration coverage is gated through find/glob. Neutral Cursor plan/todo/task/mode activity is optional/opportunistic and only counts when JSONL contains a completed Cursor workflow event. |
|
|
20
20
|
| Observed status/card colors | Confirm native-looking cards use native pi styling; neutral Cursor activity is not red; true errors are distinct; diff previews show red/green; plan status is readable |
|
|
21
21
|
| Screenshot/ANSI evidence location | External path only, for example `/tmp/pi-cursor-sdk-1016-visual.*/read-package.{ansi,txt,html,png,jsonl.path}` |
|
|
@@ -82,7 +82,7 @@ npx playwright install chromium
|
|
|
82
82
|
|
|
83
83
|
`scripts/visual-tui-smoke.mjs` is the durable source of truth for this workflow. It must keep supporting:
|
|
84
84
|
|
|
85
|
-
- fixed-size tmux PTY execution of the parent-resolved `pi -e <extension-dir> --model cursor/composer-2-5`
|
|
85
|
+
- fixed-size tmux PTY execution of the parent-resolved `pi --approve -e <extension-dir> --model cursor/composer-2-5`
|
|
86
86
|
- parent-resolved `pi` and `tmux` command paths reused in tmux-launched runs, with `process.execPath`'s directory prepended for prereq checks and tmux launches so Node shims use the validated Node
|
|
87
87
|
- `PI_CURSOR_NATIVE_TOOL_DISPLAY=1`
|
|
88
88
|
- `PI_CURSOR_REGISTER_NATIVE_TOOLS=1` by default
|
|
@@ -95,7 +95,7 @@ npx playwright install chromium
|
|
|
95
95
|
- prompt paste plus carriage return into the interactive TUI
|
|
96
96
|
- bounded post-prompt wait via `--wait-ms`
|
|
97
97
|
- artifacts outside the repo by default
|
|
98
|
-
- `<label>.ansi`, `<label>.txt`, `<label>.html`, `<label>.png`, and `<label>.
|
|
98
|
+
- `<label>.ansi`, `<label>.txt`, `<label>.html`, `<label>.png`, `<label>.jsonl.path`, and `<label>.manifest.json`
|
|
99
99
|
- `--label`, `--ext`, `--cwd`, `--prompt`, `--prompt-file`, `--wait-ms`, and `--out-dir`
|
|
100
100
|
- `--setting-sources` and `--bridge` opt-ins for non-default visual audits; `--expose-builtin-tools` is accepted only with `--bridge`
|
|
101
101
|
- repeatable `--leftover-pattern` checks for prompts that can background work
|
|
@@ -82,7 +82,7 @@ Never commit, log, or paste `auth.json` contents, API keys, or session JSONL wit
|
|
|
82
82
|
|
|
83
83
|
Use isolated `/tmp` trees when validating:
|
|
84
84
|
|
|
85
|
-
- packed tarball install (`npm pack` → extract → `pi install -l`)
|
|
85
|
+
- packed tarball install (`npm pack` → extract → `pi install --approve -l`)
|
|
86
86
|
- clean `HOME` with no inherited shell profile state
|
|
87
87
|
- plan-mode-style tool stripping via a shim extension
|
|
88
88
|
- JSONL replay-error scans independent of stdout
|
|
@@ -178,7 +178,7 @@ Simulate plan-mode execute stripping with the repo fixture:
|
|
|
178
178
|
It sets active tools to `read`, `bash`, `edit`, `write` on each `turn_start`. Run pi with:
|
|
179
179
|
|
|
180
180
|
```bash
|
|
181
|
-
pi -e scripts/fixtures/plan-strip-shim --cursor-no-fast --model cursor/composer-2-5 \
|
|
181
|
+
pi --approve -e scripts/fixtures/plan-strip-shim --cursor-no-fast --model cursor/composer-2-5 \
|
|
182
182
|
--session-dir "$SMOKE_DIR/plan-strip" \
|
|
183
183
|
-p 'After reset, read README.md and answer PLAN_STRIP_OK=yes.'
|
|
184
184
|
```
|
|
@@ -243,7 +243,7 @@ The script writes timestamped artifacts under `--out` (default `/tmp/pi-cursor-s
|
|
|
243
243
|
|
|
244
244
|
Stdout prints artifact paths and summary counts only. Raw payloads stay on disk and may contain local paths, project text, tool args/results, or secrets — do not commit or share them.
|
|
245
245
|
|
|
246
|
-
Hard repo rule: Cursor SDK behavior claims must come from the installed `@cursor/sdk` package and/or https://cursor.com/docs/sdk/typescript, not from memory or ad-hoc probes alone. Current cutover validation targets exact `@cursor/sdk@1.0.
|
|
246
|
+
Hard repo rule: Cursor SDK behavior claims must come from the installed `@cursor/sdk` package and/or https://cursor.com/docs/sdk/typescript, not from memory or ad-hoc probes alone. Current cutover validation targets exact `@cursor/sdk@1.0.18` and pi 0.79.1 local packages.
|
|
247
247
|
|
|
248
248
|
## Pi provider SDK event capture
|
|
249
249
|
|
|
@@ -294,7 +294,7 @@ Artifacts under `--out` (default `.debug/cursor-sdk-events/<timestamp>/` under `
|
|
|
294
294
|
During any normal pi session you can also opt in with:
|
|
295
295
|
|
|
296
296
|
```bash
|
|
297
|
-
PI_CURSOR_SDK_EVENT_DEBUG=1 pi -e . --model cursor/composer-2-5
|
|
297
|
+
PI_CURSOR_SDK_EVENT_DEBUG=1 pi --approve -e . --model cursor/composer-2-5
|
|
298
298
|
```
|
|
299
299
|
|
|
300
300
|
Multi-turn sessions group automatically by pi session file:
|
|
@@ -366,7 +366,7 @@ chmod 600 "$SMOKE_DIR/home/.pi/agent/auth.json"
|
|
|
366
366
|
env -i HOME="$SMOKE_DIR/home" PATH="/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin" \
|
|
367
367
|
MISE_DISABLE=1 \
|
|
368
368
|
PI_CURSOR_PI_TOOL_BRIDGE_DEBUG=1 \
|
|
369
|
-
pi -e . --cursor-no-fast --model cursor/composer-2-5 \
|
|
369
|
+
pi --approve -e . --cursor-no-fast --model cursor/composer-2-5 \
|
|
370
370
|
--session-dir "$SMOKE_DIR/session" \
|
|
371
371
|
-p '<exact reporter prompt>'
|
|
372
372
|
```
|
|
@@ -10,6 +10,8 @@ pi-cursor-sdk runs Cursor models through the local `@cursor/sdk` agent runtime.
|
|
|
10
10
|
| **Configured Cursor MCP** | Cursor settings / `~/.cursor/mcp.json` | Yes (when loaded) | Neutral **Cursor MCP** activity cards on replay |
|
|
11
11
|
| **Pi bridge (`pi__*`)** | pi-cursor-sdk loopback MCP | Yes, when exposed | Real pi tool names (`cursor_ask_question`, `cursor_activate_skill`, extension tools, …) |
|
|
12
12
|
|
|
13
|
+
Pi CLI tool toggles apply at the pi tool-registry boundary. `--no-tools`, `--tools`, and `--exclude-tools` can remove pi bridge exposure, but they do **not** disable Cursor SDK host tools or configured Cursor MCP servers.
|
|
14
|
+
|
|
13
15
|
**Not callable:** `cursor-replay-*` IDs in JSONL, pi history tool names used only for display, and transcript labels. Cursor must call exposed `pi__*` MCP names for bridged pi tools, not the pi card name.
|
|
14
16
|
|
|
15
17
|
## Discoverability
|
|
@@ -46,6 +48,8 @@ Disabling or removing an MCP server **only in pi** does not remove Cursor ambien
|
|
|
46
48
|
|
|
47
49
|
| Control | Effect |
|
|
48
50
|
| --- | --- |
|
|
51
|
+
| `pi --no-tools` | Disables pi built-in/extension/custom tools and therefore removes pi bridge exposure; Cursor SDK host tools still remain callable. |
|
|
52
|
+
| `pi --tools ...` / `pi --exclude-tools ...` | Narrows pi's active tool registry and therefore the pi bridge snapshot; Cursor SDK host tools and configured Cursor MCP are unchanged. |
|
|
49
53
|
| `PI_CURSOR_SETTING_SOURCES=all` (default) | Loads user/project Cursor MCP, plugins, rules (`~/.cursor/mcp.json`, etc.) |
|
|
50
54
|
| `PI_CURSOR_SETTING_SOURCES=none` | Disables ambient Cursor setting sources for local agents |
|
|
51
55
|
| `PI_CURSOR_SETTING_SOURCES=project,plugins` | Narrows which layers load |
|