pi-cursor-sdk 0.5.2 → 0.5.4

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.
Files changed (114) hide show
  1. package/CHANGELOG.md +66 -1
  2. package/README.md +62 -795
  3. package/dist/context.js +13 -7
  4. package/dist/cursor-agents-context.js +6 -6
  5. package/dist/cursor-api-key.js +1 -1
  6. package/dist/cursor-bridge-contract.js +1 -13
  7. package/dist/cursor-cloud-local-state.js +0 -1
  8. package/dist/cursor-config.js +1 -17
  9. package/dist/cursor-custom-subagent-definitions.js +1 -1
  10. package/dist/cursor-fallback-models.generated.js +665 -1
  11. package/dist/cursor-live-run-coordinator.js +1 -0
  12. package/dist/cursor-local-agent-ownership.js +17 -0
  13. package/dist/cursor-mcp-timeout-override.js +7 -18
  14. package/dist/cursor-native-tool-display-replay.js +5 -5
  15. package/dist/cursor-native-tools.js +11 -0
  16. package/dist/cursor-pi-tool-bridge-diagnostics.js +4 -0
  17. package/dist/cursor-pi-tool-bridge-env.js +25 -2
  18. package/dist/cursor-pi-tool-bridge-run.js +10 -3
  19. package/dist/cursor-pi-tool-bridge-server.js +98 -48
  20. package/dist/cursor-pi-tool-bridge-snapshot.js +1 -1
  21. package/dist/cursor-pi-tool-bridge.js +4 -12
  22. package/dist/cursor-provider-errors.js +2 -8
  23. package/dist/cursor-provider-live-run-drain.js +8 -3
  24. package/dist/cursor-provider-overflow.js +7 -21
  25. package/dist/cursor-provider-turn-prepare.js +8 -1
  26. package/dist/cursor-provider-turn-runner.js +17 -6
  27. package/dist/cursor-provider-turn-summary.js +1 -1
  28. package/dist/cursor-provider.js +1 -4
  29. package/dist/cursor-runtime-state.js +3 -3
  30. package/dist/cursor-sdk-event-debug.js +2 -2
  31. package/dist/cursor-sdk-output-filter.js +1 -1
  32. package/dist/cursor-sdk-process-error-guard.js +1 -2
  33. package/dist/cursor-session-agent-cleanup.js +10 -1
  34. package/dist/cursor-session-agent-lifecycle.js +2 -2
  35. package/dist/cursor-session-agent-lineage.js +11 -7
  36. package/dist/cursor-session-agent-resume.js +15 -9
  37. package/dist/cursor-session-agent.js +28 -15
  38. package/dist/cursor-session-scope.js +28 -21
  39. package/dist/cursor-session-settings.js +3 -3
  40. package/dist/cursor-session-store.js +2 -2
  41. package/dist/cursor-state.js +26 -29
  42. package/dist/cursor-tool-lifecycle.js +0 -3
  43. package/dist/cursor-tool-manifest.js +3 -1
  44. package/dist/cursor-tool-presentation-registry.js +2 -4
  45. package/dist/cursor-tool-visibility.js +0 -3
  46. package/dist/cursor-transcript-tool-specs.js +1 -2
  47. package/dist/index.js +21 -0
  48. package/dist/model-discovery.js +8 -10
  49. package/dist/model-list-cache.js +4 -9
  50. package/docs/cursor-live-smoke-checklist.md +4 -4
  51. package/docs/cursor-model-ux-spec.md +36 -19
  52. package/docs/cursor-native-tool-replay.md +8 -5
  53. package/docs/cursor-native-tool-visual-audit.md +1 -1
  54. package/docs/cursor-testing-lessons.md +39 -9
  55. package/docs/cursor-tool-surfaces.md +48 -4
  56. package/docs/development.md +93 -0
  57. package/docs/platform-smoke-implementation.md +3 -2
  58. package/docs/reference.md +806 -0
  59. package/package.json +13 -11
  60. package/scripts/platform-smoke/artifact-secrets.mjs +13 -4
  61. package/scripts/platform-smoke/local-resume-runner.mjs +0 -1
  62. package/scripts/platform-smoke/target-runtime.mjs +4 -2
  63. package/scripts/platform-smoke/targets.mjs +0 -1
  64. package/shared/cursor-sdk-output-filter.d.mts +2 -0
  65. package/shared/cursor-sdk-output-filter.mjs +92 -28
  66. package/shared/cursor-sensitive-text.d.mts +1 -0
  67. package/shared/cursor-sensitive-text.mjs +7 -0
  68. package/src/context.ts +18 -11
  69. package/src/cursor-agents-context.ts +6 -6
  70. package/src/cursor-api-key.ts +1 -1
  71. package/src/cursor-bridge-contract.ts +1 -15
  72. package/src/cursor-cloud-local-state.ts +0 -2
  73. package/src/cursor-config.ts +1 -24
  74. package/src/cursor-custom-subagent-definitions.ts +1 -1
  75. package/src/cursor-fallback-models.generated.ts +665 -1
  76. package/src/cursor-live-run-coordinator.ts +5 -0
  77. package/src/cursor-local-agent-ownership.ts +18 -0
  78. package/src/cursor-mcp-timeout-override.ts +7 -31
  79. package/src/cursor-native-tool-display-replay.ts +4 -6
  80. package/src/cursor-native-tools.ts +14 -0
  81. package/src/cursor-pi-tool-bridge-diagnostics.ts +17 -0
  82. package/src/cursor-pi-tool-bridge-env.ts +31 -2
  83. package/src/cursor-pi-tool-bridge-run.ts +10 -3
  84. package/src/cursor-pi-tool-bridge-server.ts +89 -45
  85. package/src/cursor-pi-tool-bridge-snapshot.ts +0 -1
  86. package/src/cursor-pi-tool-bridge.ts +2 -18
  87. package/src/cursor-provider-errors.ts +2 -10
  88. package/src/cursor-provider-live-run-drain.ts +8 -2
  89. package/src/cursor-provider-overflow.ts +6 -24
  90. package/src/cursor-provider-turn-prepare.ts +10 -1
  91. package/src/cursor-provider-turn-runner.ts +17 -6
  92. package/src/cursor-provider-turn-summary.ts +1 -1
  93. package/src/cursor-provider.ts +0 -5
  94. package/src/cursor-runtime-state.ts +3 -3
  95. package/src/cursor-sdk-event-debug.ts +2 -2
  96. package/src/cursor-sdk-output-filter.ts +2 -1
  97. package/src/cursor-sdk-process-error-guard.ts +1 -3
  98. package/src/cursor-session-agent-cleanup.ts +6 -1
  99. package/src/cursor-session-agent-lifecycle.ts +2 -2
  100. package/src/cursor-session-agent-lineage.ts +10 -5
  101. package/src/cursor-session-agent-resume.ts +14 -7
  102. package/src/cursor-session-agent.ts +31 -15
  103. package/src/cursor-session-scope.ts +34 -20
  104. package/src/cursor-session-settings.ts +3 -3
  105. package/src/cursor-session-store.ts +2 -2
  106. package/src/cursor-state.ts +34 -41
  107. package/src/cursor-tool-lifecycle.ts +0 -4
  108. package/src/cursor-tool-manifest.ts +4 -1
  109. package/src/cursor-tool-presentation-registry.ts +3 -5
  110. package/src/cursor-tool-visibility.ts +0 -4
  111. package/src/cursor-transcript-tool-specs.ts +0 -3
  112. package/src/index.ts +18 -0
  113. package/src/model-discovery.ts +7 -9
  114. package/src/model-list-cache.ts +4 -10
@@ -4,9 +4,11 @@ pi-cursor-sdk runs Cursor models through the local `@cursor/sdk` agent runtime b
4
4
 
5
5
  ## The three surfaces
6
6
 
7
+ **Version boundary:** the MCP-only opt-out (`PI_CURSOR_NATIVE_TOOLS`) and `/cursor-abort` require **0.5.4 or later**, including [#372](https://github.com/fitchmultz/pi-cursor-sdk/pull/372). Source checkouts preparing 0.5.4 remain candidates until exact npm/GitHub publication records exist; verify the installed artifact separately. Published **0.5.3 ignores the flag and has no such command**. Do not treat these examples as enforcement on an older installed package, or infer feature availability from a development version label alone.
8
+
7
9
  | Surface | Who owns it | Callable by Cursor? | What pi shows |
8
10
  | --- | --- | --- | --- |
9
- | **Cursor SDK host tools** | Cursor local agent | Yes | Native replay cards (`read`, `bash`, …) or neutral Cursor activity. Representative ToolType list: [SDK ToolType replay matrix](./cursor-native-tool-replay.md#sdk-tooltype-replay-matrix). |
11
+ | **Cursor SDK host tools** | Cursor local agent | Yes by default; disabled with `PI_CURSOR_NATIVE_TOOLS=0` | Native replay cards (`read`, `bash`, …) or neutral Cursor activity. Representative ToolType list: [SDK ToolType replay matrix](./cursor-native-tool-replay.md#sdk-tooltype-replay-matrix). |
10
12
  | **Configured Cursor MCP** | Cursor settings / `~/.cursor/mcp.json` | Yes (when loaded) | Neutral **Cursor MCP** activity cards on replay |
11
13
  | **Pi bridge (`pi__*`)** | pi-cursor-sdk loopback MCP | Yes, when exposed | Real pi tool names (`cursor_ask_question`, `cursor_activate_skill`, extension tools, …) |
12
14
 
@@ -14,19 +16,55 @@ Pi CLI tool toggles apply at the pi tool-registry boundary. `--no-tools`, `--too
14
16
 
15
17
  **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.
16
18
 
19
+ ## Opt-in MCP-only local turns
20
+
21
+ This section requires the 0.5.4+ implementation and publication/installation check described above; it is not available in published npm 0.5.3.
22
+
23
+ `PI_CURSOR_NATIVE_TOOLS=0` restricts **ordinary LOCAL** agents through the public SDK `AgentOptions.tools: ["mcp"]`. All other main-agent tools are omitted, including native `task`/subagents (whose own curated toolsets do not inherit a main-loop restriction). Unset, blank, unrecognized, or enabled values preserve the SDK's default toolset. The canonical boolean parser accepts `0`, `false`, `off`, `none`, `no`, and `disabled` as off, and `1`, `true`, `on`, `yes`, and `enabled` as on, case-insensitively with surrounding whitespace ignored.
24
+
25
+ To send file/shell work through Pi's normal execution and `tool_call` hook boundary instead of native Cursor tools:
26
+
27
+ ```bash
28
+ # Requires 0.5.4+ containing #372; verify publication/installation (0.5.3 ignores the flag).
29
+ PI_CURSOR_NATIVE_TOOLS=0 PI_CURSOR_EXPOSE_BUILTIN_TOOLS=1 PI_CURSOR_SETTING_SOURCES=none pi --model cursor/grok-4.6
30
+ ```
31
+
32
+ The builtin-exposure flag is still required; disabling native tools does **not** silently expose Pi builtins. Pi's active tool registry and hooks still decide which bridged tools are available or blocked. Disabling the bridge as well leaves no Pi tools callable, but does not by itself disable configured Cursor MCP.
33
+
34
+ **MCP-only is not Pi-only or a sandbox.** The SDK `mcp` capability group retains configured Cursor MCP and the Pi bridge. Ambient configured MCP remains unless setting sources are narrowed or disabled (`PI_CURSOR_SETTING_SOURCES=none`). Non-Pi MCP calls do not pass through Pi's `tool_call` hooks. A permitted Pi or MCP tool can itself run a shell, access files/network, or delegate arbitrary work; this is no OS/process security boundary.
35
+
36
+ **Native replay cannot enforce a pre-execution policy.** Native Cursor work runs before its recorded result is replayed into Pi. Pi `tool_call` hooks may block a bridged Pi call before its real `execute()`, but blocking or rewriting native replay cannot prevent or transform the original Cursor command. `PI_CURSOR_NATIVE_TOOL_DISPLAY=0`, `PI_CURSOR_REGISTER_NATIVE_TOOLS=0`, Pi tool toggles, and `PI_CURSOR_PI_TOOL_BRIDGE=0` are not native execution controls. Use the SDK tool-surface opt-out rather than fabricated pre-execution callbacks.
37
+
38
+ The policy is captured before drain/acquisition and forwarded identically to create and resume (SDK tool restrictions are not persisted by Cursor). Opt-out agents have a distinct pooled/durable compatibility identity; defaults retain historical identity bytes. Changing policy replaces the agent at acquisition instead of reusing/resuming one with the opposite policy. Before draining a pending run, the provider checks its captured policy under the drain lease and rejects an opposite-policy continuation without delivering Pi results back to that SDK run. Ordinary mismatch does not cancel the old run: restore the prior policy to finish it, or invoke `/cursor-abort` to release the exact pending local run owned by this session before retrying. This command sends no model turn. If its owned run has an active Cursor Pi turn, it also invokes that turn's public abort before release; it does not abort a non-Cursor Pi turn or release sibling sessions or Cloud agents. Pi's normal abort only signals an active Pi turn; once the mismatch error has fully settled, idle Pi abort cannot reach that older Cursor waiter. Explicit active provider abort still releases its exact scoped pending run even when the signal was aborted before preparation. No recovery path undoes already-executed work. Fresh text-only LOCAL compaction/tree summary agents continue using `tools: []`, independently of this flag. Cloud with explicit native tools disabled fails before SDK creation or lifecycle side effects rather than silently ignoring the control.
39
+
17
40
  ## Discoverability
18
41
 
19
42
  - **MCP `listTools`** (and pi's MCP catalog when present) lists **MCP servers only** — for example `pi_tools` with `pi__cursor_ask_question`. It does **not** enumerate Cursor SDK host tools such as `Read` or `Shell`.
20
43
  - **Bootstrap prompts** include a short **Cursor SDK tool boundary** block plus a compact **callable tool surfaces** manifest by default (disable manifest with `PI_CURSOR_TOOL_MANIFEST=0`). The manifest reminds the model that Cursor host/configured MCP tools are controlled by Cursor, while pi tool toggles only affect pi tools/bridge exposure; when bridge tools are exposed, it lists the current `pi__*` names. MCP `listTools` entries for bridged pi tools point back to the bootstrap prompt instead of repeating the full contract.
21
44
  - **Incremental prompts** omit the full boundary block but keep a short tail guard (including an explicit shell `cd` hint); the session agent retains prior bootstrap context. They also omit invariant Pi system instructions; a changed system prompt forces bootstrap with the new section.
22
- - **In-session debug:** `/cursor-tools` prints bridge enablement, manifest enablement, effective `PI_CURSOR_SETTING_SOURCES`, and the current callable-surface snapshot.
45
+ - **In-session debug:** `/cursor-tools` prints bridge/manifest enablement, effective `PI_CURSOR_SETTING_SOURCES`, and current-registry exposure eligibility, including the builtin-exposure setting. It is not a live-run catalog or health check.
46
+
47
+ ## Diagnosing advertised but unused bridge tools
48
+
49
+ Enable `PI_CURSOR_PI_TOOL_BRIDGE_DEBUG=1` before the turn. The existing scrubbed stderr records correlate observations by safe run ID:
50
+
51
+ | Record | What it establishes |
52
+ | --- | --- |
53
+ | `run_created` / `tools_exposed` | Run exposure and pi↔MCP name mapping, not connection |
54
+ | `mcp_initialized` | Server receipt of validated `notifications/initialized` |
55
+ | `mcp_tools_list` | Catalog-handler output after request validation, with `toolCount` |
56
+ | `request_queued` / `request_resolved` / `request_rejected` | Actual bridge call handling |
57
+
58
+ Initialization/catalog receipts are server observations, not Cursor-client identity, response delivery, model consumption or ongoing health. Absence does not explain why no request occurred. `/cursor-tools` reflects the registry now, not an earlier run's captured surface; exposure alone is not invocation proof. These diagnostics do not enumerate Cursor-configured MCP connections. Do not share logs where tool names are sensitive; endpoint credentials and raw args/results are excluded.
59
+
60
+ For an advertised-but-unused `pi__subagent`, first identify the active provider/version (especially with multiple Cursor providers installed), then compare the run's exposure, initialization/catalog and call records with persisted pi `toolCall`/`toolResult` rows. Bash-spawned Pi is not evidence of bridged `subagent` execution. The original Windows/two-provider report remains open in [#206](https://github.com/fitchmultz/pi-cursor-sdk/issues/206).
23
61
 
24
62
  ## Pi bridge vs Cursor native
25
63
 
26
64
  Default behavior:
27
65
 
28
66
  - Cursor host tools handle files, shell, grep, and edits.
29
- - When exposed, `pi__mcp` is preferred for MCP work and `pi__subagent` is preferred for delegation. Cursor-configured MCP and Cursor-native subagents are fallbacks when the matching pi tool is not exposed or is unavailable.
67
+ - Prefer exposed `pi__*` tools for the capabilities described by their current schemas and prompt guidelines, including delegation or MCP work. Use Cursor-configured MCP or Cursor-native subagents only when no matching exposed Pi tool is available; do not assume a particular delegation tool name is registered.
30
68
  - The pi bridge exposes **active pi tools** as `pi__*` MCP names when `PI_CURSOR_PI_TOOL_BRIDGE` is enabled (default on).
31
69
  - Overlapping pi builtins (`read`, `bash`, `write`, `edit`, `grep`, `find`, `ls`) are **hidden** from the bridge unless `PI_CURSOR_EXPOSE_BUILTIN_TOOLS=1`.
32
70
 
@@ -45,10 +83,15 @@ PI_CURSOR_EXPOSE_BUILTIN_TOOLS=1 pi --model cursor/grok-4.6
45
83
  # Fail a stranded bridge call sooner than the effective MCP tool timeout
46
84
  PI_CURSOR_PI_BRIDGE_CALL_TIMEOUT_MS=120000 pi --model cursor/grok-4.6
47
85
 
86
+ # Announce the bridge URL as localhost and listen on a port or range (for example for a Cursor team MCP allowlist such as http://localhost:800*/mcp).
87
+ PI_CURSOR_PI_TOOL_BRIDGE_HOST=localhost PI_CURSOR_PI_TOOL_BRIDGE_PORT=8000-8009 pi --model cursor/grok-4.6
88
+
48
89
  # Disable bootstrap tool manifest
49
90
  PI_CURSOR_TOOL_MANIFEST=0 pi --model cursor/grok-4.6
50
91
  ```
51
92
 
93
+ For `localhost`, the bridge owns both `127.0.0.1` and `::1` on the selected port before advertising its URL; a conflict on either family skips the port, and missing IPv6 fails closed. The default remains IPv4-only. Host/port settings are captured for the shared server lifetime, not changed under active runs; dispose all its runs before changing them.
94
+
52
95
  ## Runtime and transport policy
53
96
 
54
97
  Current defaults:
@@ -67,6 +110,7 @@ Disabling or removing an MCP server **only in pi** does not remove Cursor ambien
67
110
  | --- | --- |
68
111
  | `pi --no-tools` | Disables pi built-in/extension/custom tools and therefore removes pi bridge exposure; Cursor SDK host tools still remain callable. |
69
112
  | `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. |
113
+ | `PI_CURSOR_NATIVE_TOOLS=0` | Restricts ordinary LOCAL main-agent tools to MCP only, including disabling native task/subagents; Cloud fails closed. Default unchanged. |
70
114
  | `PI_CURSOR_SETTING_SOURCES=all` (default) | Loads user/project Cursor MCP, plugins, rules (`~/.cursor/mcp.json`, etc.) |
71
115
  | `PI_CURSOR_SETTING_SOURCES=none` | Disables ambient Cursor setting sources for local agents |
72
116
  | `PI_CURSOR_SETTING_SOURCES=project,plugins` | Narrows which layers load |
@@ -85,6 +129,6 @@ Example mistake: treating `cursor-replay-…` as a tool to invoke. Replay never
85
129
 
86
130
  ## Related docs
87
131
 
88
- - [README — Cursor provider tool contract](../README.md#cursor-provider-tool-contract)
132
+ - [Reference — Cursor provider tool contract](reference.md#cursor-provider-tool-contract)
89
133
  - [Cursor native tool replay](./cursor-native-tool-replay.md)
90
134
  - [Cursor model UX spec](./cursor-model-ux-spec.md)
@@ -0,0 +1,93 @@
1
+ # Development and releases
2
+
3
+ Start with the [README](../README.md) for installation and the [Cursor SDK reference](reference.md) for runtime configuration. This page collects maintainer verification, event capture, compatibility and release procedures.
4
+
5
+ ## Maintainer cost-conscious verification
6
+
7
+ Run offline/faux tests, native contracts, type checks, builds, and package checks first; preserve offline cross-platform CI. Reuse retained evidence for unchanged tested inputs. Real Cursor calls are only for the smallest meaningful changed-behavior check that needs real-service proof, on one representative environment. Docs/metadata-only changes need no paid testing. Do not replay full paid campaigns, run host matrices merely for matrix coverage, or automatically retry paid failures. Automated Cursor PR reviews continue unchanged.
8
+
9
+ No paid Cursor Cloud testing for generic PRs or releases. Only a PR or issue explicitly focused on Cursor Cloud may use a necessary focused Cloud check; incidental Cloud code changes do not qualify. Cloud product capabilities, offline contracts, and explicit smoke commands remain available. Even for Cloud-focused work, the multi-lane `npm run smoke:cloud` is optional, not an unconditional gate; selected checks retain run/evidence and agent/repository cleanup requirements.
10
+
11
+ [Platform smoke](./platform-smoke.md) documents existing single-suite/single-target commands and the optional comprehensive `npm run smoke:platform:all` matrix. The matrix uses 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. `.artifacts/platform-smoke/latest.json` points to each platform run's evidence. Report exactly the scope observed, not unrun matrix coverage.
12
+
13
+ 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](./cursor-live-smoke-checklist.md), `npm run smoke:visual`, `npm run smoke:live`, or direct `pi --approve -e . --cursor-no-fast --model cursor/grok-4.6` runs only when a changed TUI/card/runtime behavior needs new live evidence. Select one relevant check rather than executing every helper. `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](./cursor-testing-lessons.md) for auth.json seeding, isolated `/tmp` harness layout, JSONL replay-error scans, and other regression traps.
14
+
15
+ ## Maintainer Cursor SDK event capture
16
+
17
+ Use `npm run debug:sdk-events` to capture timestamped `run.stream()`, `onDelta`, and `onStep` timelines for one direct `@cursor/sdk` run.
18
+
19
+ 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`.
20
+
21
+ See [Cursor testing lessons](./cursor-testing-lessons.md#cursor-sdk-event-capture-probe) for usage, artifact layout, and safety notes.
22
+
23
+ ## Automatic npm releases (maintainers)
24
+
25
+ Follow the [shared release procedure](https://github.com/fitchmultz/.github#automatic-npm-releases): merge a reviewed PR into `main` with an intentional `package.json` version bump and a matching versioned `CHANGELOG.md` section. Automation never bumps versions, overwrites releases, or republishes an existing version. Once configured and enabled, it runs the existing offline compatibility and native macOS/Windows jobs, qualifies one candidate tarball, then publishes it without an approval step.
26
+
27
+ For the first release containing the native-tool opt-out and `/cursor-abort` from #372, update their availability notes in `README.md`, `docs/reference.md`, and `docs/cursor-tool-surfaces.md` to name the minimum supporting release version. Preserve the warning that published 0.5.3 lacks these controls, and do not call the candidate published until npm/GitHub publication records confirm it.
28
+
29
+ Merging publishes, so before merging check the final PR head (up to date with `main`) and version against the [release review gate](../AGENTS.md#release-review-gate-maintainer) and [cost-conscious verification policy](#maintainer-cost-conscious-verification). Complete the exact-release-diff deep review with zero findings, the documented pre-release catalog check, and any genuinely necessary changed-behavior proof. Merging attests genuine satisfaction of existing requirements; it does not create proof. Authenticated checks remain outside CI; automated Cursor PR reviews remain unchanged, and no routine paid Cloud campaigns or paid retries are added. Automated publication disables npm hooks to publish the checked bytes; existing manual publisher instructions remain valid.
30
+
31
+ Failed/unpublished candidates can retry daily at 12:17 UTC or via manual dispatch of `npm release` on `main` only while the current source still owns the same version, tag, draft, and candidate assets. Inspect their exact source/run identities first: an authentication repair alone does not authorize publishing an old candidate after `main` advances. When source advances beyond a reserved candidate, use the next unused stable version and fresh qualification; never move its tag, overwrite its draft/assets, or relabel old proof. The [0.5.1 changelog](../CHANGELOG.md#051-unpublished-source-history) is unpublished source history carried into 0.5.2, not a successful publication record. Set repository variable `NPM_RELEASE_ENABLED` to anything other than `true` to stop new release plans; cancel pending runs separately when needed. Workflow validation is not evidence of a completed real OIDC publication.
32
+
33
+ Publication records are independent: on 2026-10-07, npm listed 0.5.2 as published and `latest`, while GitHub's `v0.5.2` release remained a draft bound to source `9820ae7`. Preserve that tag, draft, and candidate assets unchanged. The 0.5.3 source uses a new version and candidate; its preparation is not proof of npm or GitHub publication.
34
+
35
+ ## Development
36
+
37
+ Required qualification targets are the latest stable official Pi and latest maintained `fitchmultz/pi` main, with optional wildcard Pi/TypeBox host peers and exact Cursor SDK **1.0.37**. CI resolves the official version/fork commit once and retains exact SDK/CLI provenance. Types, tests and package checks use each selected host's consistent dependency graph; the locked development Pi **1.1.0** dependencies are reproducible snapshots, not qualification targets. Updating these snapshots does not upgrade the user's Pi installation or change the official Pi 0.87.1 minimum. After `npm ci --ignore-scripts`, run `node scripts/ci-compatibility.mjs --automation /path/to/automation` in an empty HOME/agent profile for credential-free latest qualification. Native macOS/Windows checks select the same resolved latest official graph. This builds the manifest entry, runs existing type/unit/package checks, and tests the compiled provider's registration plus production prompt shaping against native Pi transcript/tool transitions. Replay arguments must match their JSON stream deltas. A second native contract runs the registered Cursor provider with only its external SDK transport/storage substituted: real loopback bridge execution, display-only replay, persisted usage, incremental sends, tree navigation, compaction, request-boundary steering, abort and reload/disposal. Tests use no live Cursor service.
38
+
39
+ TypeScript 7 builds and checks package types. Build and typecheck commands invoke `node_modules/typescript/bin/tsc` explicitly to avoid npm's shared `tsc` shim selecting a different compiler. `@typescript/typescript6` is dev-only for AST architecture and installed-SDK contract tests because TypeScript 7 does not expose a stable compiler API. Vitest 5 runs with `clearMocks: true` by default.
40
+
41
+ Pull-request CI runs that suite once per selected host: the latest stable official Pi and a source-built revision of the latest maintained fork `main`, each using its own consistent dependency graph and the version/commit resolved once for the run. It checks both npm and Git installations against both hosts without starting a Cursor model turn. The selected official version and fork commit are printed in the check log. Separate macOS and Windows jobs install with lifecycle scripts, load `node-pty`, and run the platform-build test, typecheck, and pack checks on Node 24.
42
+
43
+ For authorized uncommitted repairs, qualify an isolated immutable working-tree snapshot without committing:
44
+
45
+ ```bash
46
+ node scripts/ci-compatibility.mjs --working-tree --official-only --versions 0.87.1,0.99.1,1.0.3
47
+ ```
48
+
49
+ This builds and packs the snapshot, checks package loading, and exercises actual official native provider/session flows. The default invocation still requires a clean checkout and includes the maintained fork. `--help` documents selection and exit codes.
50
+
51
+ This manual snapshot mode retains explicit older-host qualification for the advertised floor; it is separate from CI's once-resolved latest-only targets. Do not combine manual selection flags with `--automation`.
52
+
53
+ This is offline compatibility proof, not Cursor authentication, desktop/cloud execution, visual, or all-platform live proof. Add only necessary changed-behavior live evidence under the [cost-conscious verification policy](#maintainer-cost-conscious-verification); the comprehensive paid matrix is optional, and paid Cloud testing is restricted to explicitly Cursor Cloud-focused PRs/issues. Older advertised Pi/Node floors require their own offline compatibility evidence.
54
+
55
+ Run checks:
56
+
57
+ ```bash
58
+ npm test
59
+ npm run typecheck
60
+ ```
61
+
62
+ Check the reviewable Cursor fallback catalog against the authenticated live catalog before releases:
63
+
64
+ ```bash
65
+ CURSOR_API_KEY="your-key" npm run check:cursor-snapshots
66
+ ```
67
+
68
+ Refresh it after Cursor model changes:
69
+
70
+ ```bash
71
+ CURSOR_API_KEY="your-key" npm run refresh:cursor-snapshots -- --write
72
+ ```
73
+
74
+ Refresh the bundled default/non-Max context-window snapshot only when checkpoint-derived context windows have been collected from live local runs:
75
+
76
+ ```bash
77
+ CURSOR_API_KEY="your-key" npm run refresh:cursor-snapshots -- --write \
78
+ --context-windows ~/.pi/agent/cursor-sdk-context-windows.json
79
+ ```
80
+
81
+ 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.
82
+
83
+ Local development run:
84
+
85
+ ```bash
86
+ npm install
87
+ CURSOR_API_KEY="your-key" pi --approve -e . --model cursor/grok-4.6
88
+ ```
89
+
90
+ After editing `src/`, run `npm run build` before the next `pi -e .` run, or pi loads the previous build.
91
+
92
+ Maintainer design notes live in [`docs/cursor-model-ux-spec.md`](./cursor-model-ux-spec.md).
93
+
@@ -26,7 +26,7 @@ Meaningful gap closed: earlier card assertions could pass when the prompt mentio
26
26
 
27
27
  ## Registry visual classification
28
28
 
29
- The implementation must classify every `CURSOR_TOOL_PRESENTATION_SPECS` entry from `src/cursor-tool-presentation-registry.ts` as required or excluded for the optional comprehensive visual matrix. A validation check fails when a registry entry lacks classification.
29
+ The implementation must classify every `CURSOR_TOOL_PRESENTATION_SPECS` entry from `src/cursor-tool-presentation-registry.ts` as required or excluded for the optional comprehensive visual matrix. `test/smoke-tooling.test.ts` fails when a registry tool name is missing from these lists or an excluded entry lacks a rationale.
30
30
 
31
31
  Required deterministic cards:
32
32
 
@@ -40,6 +40,7 @@ Required deterministic cards:
40
40
 
41
41
  Excluded from release visual matrix with required rationale:
42
42
 
43
+ - `ls`: composer-2-5 does not route the deterministic source-enumeration step through the native `ls` surface reliably; the suite instead gates that behavior through a successful native `find` result for `src/cursor-provider.ts`.
43
44
  - `delete`: destructive and redundant with file mutation card coverage.
44
45
  - `readLints`: dependent on target diagnostics state.
45
46
  - `updateTodos`: model workflow dependent.
@@ -52,7 +53,7 @@ Excluded from release visual matrix with required rationale:
52
53
  - `webSearch`: network/search dependent.
53
54
  - `webFetch`: network dependent.
54
55
 
55
- Adding a registry entry requires adding it to the required or excluded list with rationale. `ls` is currently excluded from the required one-prompt matrix because composer-2-5 does not route the deterministic source-enumeration step through the native `ls` surface reliably; the suite instead gates that behavior through a successful native `find` result for `src/cursor-provider.ts`.
56
+ Adding a registry entry requires adding it to the required or excluded list with rationale.
56
57
 
57
58
  ## Platform command rendering
58
59