pi-cursor-sdk 0.5.2 → 0.5.3

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 (47) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/README.md +38 -17
  3. package/dist/context.js +2 -2
  4. package/dist/cursor-custom-subagent-definitions.js +1 -1
  5. package/dist/cursor-fallback-models.generated.js +402 -1
  6. package/dist/cursor-local-agent-ownership.js +17 -0
  7. package/dist/cursor-mcp-timeout-override.js +1 -1
  8. package/dist/cursor-pi-tool-bridge-diagnostics.js +4 -0
  9. package/dist/cursor-pi-tool-bridge-run.js +10 -3
  10. package/dist/cursor-provider-errors.js +2 -2
  11. package/dist/cursor-provider-turn-summary.js +1 -1
  12. package/dist/cursor-session-agent-cleanup.js +10 -1
  13. package/dist/cursor-session-agent-lifecycle.js +2 -2
  14. package/dist/cursor-session-agent-lineage.js +11 -7
  15. package/dist/cursor-session-agent-resume.js +15 -9
  16. package/dist/cursor-session-agent.js +22 -7
  17. package/dist/cursor-session-scope.js +27 -14
  18. package/dist/cursor-session-settings.js +3 -3
  19. package/dist/cursor-session-store.js +1 -1
  20. package/dist/cursor-state.js +17 -6
  21. package/dist/model-discovery.js +8 -9
  22. package/docs/cursor-live-smoke-checklist.md +2 -2
  23. package/docs/cursor-model-ux-spec.md +23 -14
  24. package/docs/cursor-native-tool-replay.md +6 -3
  25. package/docs/cursor-native-tool-visual-audit.md +1 -1
  26. package/docs/cursor-testing-lessons.md +24 -6
  27. package/docs/cursor-tool-surfaces.md +16 -1
  28. package/package.json +8 -8
  29. package/src/context.ts +2 -2
  30. package/src/cursor-custom-subagent-definitions.ts +1 -1
  31. package/src/cursor-fallback-models.generated.ts +402 -1
  32. package/src/cursor-local-agent-ownership.ts +18 -0
  33. package/src/cursor-mcp-timeout-override.ts +1 -1
  34. package/src/cursor-pi-tool-bridge-diagnostics.ts +17 -0
  35. package/src/cursor-pi-tool-bridge-run.ts +10 -3
  36. package/src/cursor-provider-errors.ts +2 -2
  37. package/src/cursor-provider-turn-summary.ts +1 -1
  38. package/src/cursor-session-agent-cleanup.ts +6 -1
  39. package/src/cursor-session-agent-lifecycle.ts +2 -2
  40. package/src/cursor-session-agent-lineage.ts +10 -5
  41. package/src/cursor-session-agent-resume.ts +14 -7
  42. package/src/cursor-session-agent.ts +23 -7
  43. package/src/cursor-session-scope.ts +33 -11
  44. package/src/cursor-session-settings.ts +3 -3
  45. package/src/cursor-session-store.ts +1 -1
  46. package/src/cursor-state.ts +25 -5
  47. package/src/model-discovery.ts +7 -8
package/CHANGELOG.md CHANGED
@@ -1,5 +1,31 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.5.3 - 2026-10-07
4
+
5
+ ### Changed
6
+
7
+ - Upgrade the exact unbundled Cursor SDK and five optional platform pins to 1.0.37. Keep the SDK 1.0.36 catalog capture from 2026-10-06 and private hook canary attributed to their historical version.
8
+ - Refresh the fallback catalog from the authenticated SDK 1.0.37 catalog-only observation on 2026-10-07: 46 models, adding Claude Haiku 5.5 (`claude-haiku-5-5`) with 20 thinking/context/effort variants while preserving all 45 prior model records. The 33 bundled checkpoint-derived entries remain unchanged; no Agent/model turn or Cloud run was performed.
9
+
10
+ ### Fixed
11
+
12
+ - Map boolean `thinking` combined with either `effort` or `reasoning_effort` through native thinking controls. Haiku 5.5 now exposes all five catalog-supported enabled effort levels at both `@300k` and `@1m`; `off` sends `thinking=false` without the effort parameter. Verified offline against the captured SDK 1.0.37 catalog; no Agent/model turn or Cloud run was performed.
13
+ - Select the declared TypeScript 7 entrypoint explicitly for all typechecks, matching the build and avoiding npm `tsc` shim collisions.
14
+ - Separate SessionManager-owned runtime scopes from unchanged durable identities. A same-file sibling's reload/tree/shutdown no longer closes another manager's pool or pending bridge run; process-local claims exclude live handles from resume and cleanup (#282 reproduced trigger, not the original reporter's full qualification).
15
+ - Label structured tool history as historical request/result/error without declaring unmatched requests completed. Preserve prose, IDs, arguments, errors and raw history; do not synthesize tool calls, strip narration or automatically resend effects (#257 mitigation).
16
+ - Make `/cursor-tools` report current-registry exposure eligibility, not live-run connectivity. Add opt-in validated initialization and catalog-handler output receipts with explicit client/model/health ceilings (#206 diagnostics, not Windows reporter qualification).
17
+
18
+ ### Security
19
+
20
+ - Update development-only transitive `source-map-js` to 1.2.2 for its event-loop denial-of-service fix.
21
+
22
+ ### Verification and limits
23
+
24
+ - Document SDK 1.0.37's new public `computerUse` output through the existing bounded generic Cursor activity/summary fallback, without dedicated action/screenshot presentation or a new public local execution option.
25
+ - Record SDK 1.0.37's vendored HTTP/2 ping/response-iteration and local retry-classification source changes. Public controls, bearer/lease/reload mechanisms, LOCAL ID/inherit-only custom agents and inspected storage layouts remain unchanged; internal definition-only MCP setters are not supported options. These source comparisons do not resolve the original #247 authentication cause, #339 signal sender, #173 rtk behavior, #233 Windows loader or #206 readiness reports.
26
+ - Exercise real public installed-SDK first-send linking through a blocked key-exchange boundary, with a request-time missing-module negative control. Native SDK-substituted session tests remain separate; neither proves authenticated inference or every embedded loader.
27
+ - Clarify inspected SDK hook/parser/authentication mechanisms and remaining reporter-only unknowns (#173, #339, #247, #233). Public commit/PR attribution controls remain absent (#302); no SDK-internal patch or paid test campaign is added.
28
+
3
29
  ## 0.5.2
4
30
 
5
31
  ### Fixed
package/README.md CHANGED
@@ -51,11 +51,11 @@ If pi started without a key, run `/cursor-refresh-models` after `/login` to refr
51
51
  ## Requirements
52
52
 
53
53
  - Node.js 24+
54
- - pi-cursor-sdk 0.5.2 requires official Pi 0.87.1 or later. The latest stable official Pi and current `fitchmultz/pi` main are required compatibility targets, resolved once per workflow run; locked development Pi packages are reproducible snapshots, not validation targets
54
+ - pi-cursor-sdk 0.5.3 requires official Pi 0.87.1 or later. The latest stable official Pi and current `fitchmultz/pi` main are required compatibility targets, resolved once per workflow run; locked development Pi packages are reproducible snapshots, not validation targets
55
55
  - optional Pi and TypeBox peer metadata uses `"*"` ranges per Pi package guidance
56
56
  - a Cursor SDK API key saved through `/login`, available as `CURSOR_API_KEY`, or passed with pi's `--api-key`
57
57
 
58
- No global `@cursor/sdk` install is required. This package depends on exact `@cursor/sdk@1.0.36`, so normal package installation brings in the tested SDK. The extension intentionally does not bundle `@cursor/sdk` or its platform packages, because packing from one maintainer OS can ship the wrong optional SDK binary for another OS. The SDK has used its current single-file/new-chunk package layout since 1.0.28. Pi hosts that pass transcript-only provider contexts are supported through Pi 0.87.1's required public replay helpers.
58
+ No global `@cursor/sdk` install is required. This package depends on exact `@cursor/sdk@1.0.37`, so normal package installation brings in that SDK. The extension intentionally does not bundle `@cursor/sdk` or its platform packages, because packing from one maintainer OS can ship the wrong optional SDK binary for another OS. The SDK has used its current single-file/new-chunk package layout since 1.0.28. Pi hosts that pass transcript-only provider contexts are supported through Pi 0.87.1's required public replay helpers.
59
59
 
60
60
  ## Install
61
61
 
@@ -149,7 +149,7 @@ Pi owns CLI parsing and credential storage. Cursor's public native API-key auth
149
149
 
150
150
  The discovered catalog is cached at `~/.pi/agent/cursor-sdk-model-list.json` (written `0600`, keyed by an API-key fingerprint — the key itself is never stored). Startup and native auth mutations are always cache-only: a matching cache, even if expired, or the bundled fallback supplies known models with zero catalog/network calls. The SDK remains in the static extension graph for compiled-Bun loading; cache-only does not mean zero SDK module evaluation. Pi may separately request a network-allowed refresh; fresh matching caches then skip the request. `/cursor-refresh-models` requests a forced native live refresh and reports cancellation or failure truthfully. Authenticated errors prefer the matching cached catalog over the generic fallback.
151
151
 
152
- Only an accepted native generation can update the catalog, selection metadata, cache, and fallback warning. An effective no-auth refresh removes only the extension's valid regular-file orphaned catalog. Cancelled, superseded, or shut-down refreshes cannot install late results. SDK 1.0.36 catalog requests have no public caller-abort option, so cancellation rejects their late publication rather than promising to stop the underlying request.
152
+ Only an accepted native generation can update the catalog, selection metadata, cache, and fallback warning. An effective no-auth refresh removes only the extension's valid regular-file orphaned catalog. Cancelled, superseded, or shut-down refreshes cannot install late results. SDK 1.0.37 catalog requests have no public caller-abort option, so cancellation rejects their late publication rather than promising to stop the underlying request.
153
153
 
154
154
  Known host limitation: official Pi 1.0.4 has a demonstrated startup refresh-admission race that can temporarily leave fallback models and an incorrect missing-key warning despite a matching authenticated cache. The shared-owner repair is merged in `fitchmultz/pi` via [#190](https://github.com/fitchmultz/pi/pull/190); this is not an official-host fix. See [#337](https://github.com/fitchmultz/pi-cursor-sdk/pull/337). It is separate from Cursor service authentication failures and the compiled-loader repair.
155
155
 
@@ -222,12 +222,12 @@ For models where Cursor exposes `reasoning`, `effort`, `reasoning_effort`, or bo
222
222
 
223
223
  - `reasoning=none|low|medium|high|extra-high`
224
224
  - `effort=low|medium|high|xhigh|max`
225
- - `reasoning_effort=low|medium|high`
225
+ - `reasoning_effort=low|medium|high|xhigh|max` where exposed by the catalog
226
226
  - `thinking=false|true` for boolean thinking models
227
227
 
228
228
  Pi `xhigh` maps to Cursor `xhigh` or `extra-high`; Pi `max` maps only to a distinct Cursor `max` value. Gemini 3.8 Flash exposes only `low`, `medium`, and `high` through `reasoning_effort`; its SDK default remains `high`.
229
229
 
230
- For Claude models with both `thinking` and `effort`, pi thinking `off` sends `thinking=false` and omits `effort`.
230
+ For Claude models with boolean `thinking` and either `effort` or `reasoning_effort`, enabled pi levels send `thinking=true` and the mapped effort value; `off` sends `thinking=false` and omits the effort parameter. Haiku 5.5 exposes all five enabled effort levels (`low`, `medium`, `high`, `xhigh`, `max`) at both `@300k` and `@1m`.
231
231
 
232
232
  ### Why some Cursor models show `thinking=no`
233
233
 
@@ -298,7 +298,7 @@ Change the session mode interactively:
298
298
 
299
299
  `/cursor-mode` with no argument reports the current mode and usage. The CLI flag does not persist to the session; slash-command changes are persisted with `pi.appendEntry()`.
300
300
 
301
- Maintainers can run `/cursor-tools` in a Cursor model session to print the current bridge enablement, bootstrap manifest enablement, effective `PI_CURSOR_SETTING_SOURCES`, and callable-surface snapshot (host tools summary plus current `pi__*` names). See [Cursor dogfood checklist](docs/cursor-dogfood-checklist.md).
301
+ Maintainers can run `/cursor-tools` in a Cursor model session to print bridge/manifest enablement, effective `PI_CURSOR_SETTING_SOURCES`, and the current registry's bridge exposure eligibility. This is not a live-run connection or invocation check; use the [bridge diagnostics](#cursor-provider-tool-contract) below for per-run observations. See [Cursor dogfood checklist](docs/cursor-dogfood-checklist.md).
302
302
 
303
303
  For conversation agents, the extension seeds the mode through `Agent.create({ mode })` and sends it on each `agent.send(..., { mode })` so `/cursor-mode` and `--cursor-mode` remain the source of truth when a pooled agent is reused. LOCAL compaction/tree summary agents always use text-only `agent` mode.
304
304
 
@@ -308,6 +308,8 @@ Cursor SDK `plan` mode can produce plan-oriented output and Cursor todo/plan act
308
308
 
309
309
  `/cursor-refresh-config` calls the current pooled SDK agent's `agent.reload()` so Cursor reloads its filesystem config such as local hooks, project MCP, and Cursor-managed subagents without restarting pi. Extension `cursor-sdk.json` definitions below are captured on the next ordinary turn; changed definitions recreate the pooled agent instead of relying on SDK reload.
310
310
 
311
+ **Hook enforcement is not qualified by settings loading or replay cards.** SDK 1.0.37 source retains Shell `preToolUse` command-rewrite plumbing. The retained SDK 1.0.36 offline probe executed a rewritten command using private lexical bindings and permissive approval; it is not an executed SDK 1.0.37 canary. That is not an end-to-end Pi/rtk or security-policy guarantee. Replay may show the original model arguments before the SDK applies a rewrite. Verify the hook decision and actual executed command together when relying on hooks; the reported native-Agent/Pi discrepancy remains open in [#173](https://github.com/fitchmultz/pi-cursor-sdk/issues/173).
312
+
311
313
  Cursor SDK local safety controls stay off by default. Enable them explicitly for one run:
312
314
 
313
315
  ```bash
@@ -391,9 +393,9 @@ Define named Cursor delegates in user `~/.pi/agent/cursor-sdk.json` or trusted p
391
393
 
392
394
  - Names follow this extension's policy: 1–64 characters, starting with an ASCII letter, then letters, digits, `.`, `_`, or `-`. Required `description` and `prompt` must be nonblank strings; text is trimmed. Invalid entries are skipped individually. Invalid optional `model`, `thinking`, or `fast` values are omitted; unsupported fields, including per-entry MCP, are not forwarded.
393
395
  - A trusted project with any valid definitions replaces the **whole** user set, not individual names. Empty/all-invalid project sets fall back to user definitions. No CLI, environment, or session override exists. Keep definitions non-secret.
394
- - `model` uses a registered Cursor model ID **without** the `cursor/` provider prefix; set thinking separately to `off`, `minimal`, `low`, `medium`, `high`, `xhigh`, or `max`. Omitted model and explicit `inherit` both inherit the parent model in SDK 1.0.36; `thinking`/`fast` do not override inherited models.
396
+ - `model` uses a registered Cursor model ID **without** the `cursor/` provider prefix; set thinking separately to `off`, `minimal`, `low`, `medium`, `high`, `xhigh`, or `max`. Omitted model and explicit `inherit` both inherit the parent model in SDK 1.0.37; `thinking`/`fast` do not override inherited models.
395
397
  - Explicit models use catalog metadata for aliases, context and thinking. `:fast`/`:slow` wins over the entry's `fast`; unsuffixed models use entry `fast`, otherwise the catalog default. Parent thinking, `/cursor-fast`, saved fast defaults and process fast flags do not affect the definition. Unknown IDs pass through unchanged without invented parameters or a catalog request.
396
- - **SDK 1.0.36 LOCAL ceiling:** its converter sends only the selected model ID or `inherit`, dropping all thinking/fast/context parameters. Thus `grok-4.6:slow` resolves to `grok-4.6`, but does not enforce child slow mode locally. Cloud conversion preserves the full selection; service acceptance/honoring of those parameters is not qualified here. Resource inheritance (`local.subagentInherit`) is not a model-parameter workaround.
398
+ - **SDK 1.0.37 LOCAL ceiling:** its converter sends only the selected model ID or `inherit`, dropping all thinking/fast/context parameters. Thus `grok-4.6:slow` resolves to `grok-4.6`, but does not enforce child slow mode locally. Cloud conversion preserves the full selection; service acceptance/honoring of those parameters is not qualified here. Resource inheritance (`local.subagentInherit`) is not a model-parameter workaround.
397
399
  - Definitions are passed through public SDK `agents` on ordinary create/resume and cloud creation. Changed resolved content replaces the local pooled agent on the next turn and rejects stale resume handles, bootstrapping from the Pi transcript; equivalent reordered content reuses it. Resume keys contain only a digest, not definition text. Removing all definitions restores the original no-feature key.
398
400
 
399
401
  This is Cursor SDK-native delegation by configured name, not a second Pi subagent implementation. When exposed, `pi__subagent` remains preferred. LOCAL compaction/tree summary agents receive no definitions, tools, settings or MCP; bug-report streams retain ordinary capabilities.
@@ -501,7 +503,7 @@ Local resume cleanup is explicit and session-ledger scoped:
501
503
  /cursor-local-resume-cleanup --yes
502
504
  ```
503
505
 
504
- With SDK-default storage selected, SDK 1.0.36 derives workspace roots with SHA256 instead of MD5 and may rename the entire old workspace root on first use. Pi admits only exact cwd/session-derived old or current identities. After a rename, it verifies the recorded agent and cwd in the derived destination before resuming or cleaning up. If both roots exist, recorded legacy identities stay with the legacy store; nothing is merged. Failed renames retain the old store. Same-cwd acquisitions share atomic in-flight root derivation and retain ownership through resume/cleanup admission and open-store disposal; only then may the SDK retry. User-managed links/junctions above the SDK-owned `sdk-agent-store` prefix (such as `~/.cursor` or `~/.cursor/projects`) remain supported. Owned prefix and old/current workspace components are checked before the SDK getter can migrate history; links/non-directories within the owned layout fail closed. Recorded identities must match exact derived roots before any path walk; malformed paths fall back on resume or are durably non-retryable for cleanup. Stop other processes using old SDK state before upgrading; this in-process ownership guard is not a cross-process migration lock.
506
+ With SDK-default storage selected, SDK 1.0.37 retains SDK 1.0.36's workspace-root derivation with SHA256 instead of MD5 and may rename the entire old workspace root on first use. Pi admits only exact cwd/session-derived old or current identities. After a rename, it verifies the recorded agent and cwd in the derived destination before resuming or cleaning up. If both roots exist, recorded legacy identities stay with the legacy store; nothing is merged. Failed renames retain the old store. Same-cwd acquisitions share atomic in-flight root derivation and retain ownership through resume/cleanup admission and open-store disposal; only then may the SDK retry. User-managed links/junctions above the SDK-owned `sdk-agent-store` prefix (such as `~/.cursor` or `~/.cursor/projects`) remain supported. Owned prefix and old/current workspace components are checked before the SDK getter can migrate history; links/non-directories within the owned layout fail closed. Recorded identities must match exact derived roots before any path walk; malformed paths fall back on resume or are durably non-retryable for cleanup. Stop other processes using old SDK state before upgrading; this in-process ownership guard is not a cross-process migration lock.
505
507
 
506
508
  It only deletes superseded local `agent-*` IDs that this extension recorded as cleanup candidates, one exact ID at a time through the Cursor SDK using the candidate's recorded store identity (or, only with default storage selected, the SDK default workspace store for legacy candidates without one), and protects agents still resumable from any session-tree branch. Before SDK deletion it verifies and fsyncs an exact intent in the Pi session JSONL, then verifies and fsyncs the result; a missing or non-durable intent prevents deletion, while a missing or non-durable result leaves the durable intent—and a conservative current-process marker—blocking automatic retry. A candidate with a recorded store identity that is invalid for the current session is durably marked non-retryable and excluded from later cleanup attempts. It does not sweep any SDK store or call lower-level empty delete filters. Removing a pi session file does not automatically remove its persisted store directory. After permanently retiring that session and confirming no pi process is using it, a recorded root may be removed manually only when it is the exact cwd/session-derived current or surviving legacy `pi-sessions/<session-hash>/` directory. Do not remove a stale recorded MD5 path after migration: resolve and verify the actual owning directory first. Never manually remove the SDK default workspace root, which legacy entries may record and other sessions may share.
507
509
 
@@ -516,7 +518,7 @@ For request-equivalent native session inputs, images from the latest pending nat
516
518
 
517
519
  Pi's default footer and `/stats` remain native. Assistant usage components are additive and describe the current context; cumulative Cursor billing never drives Pi's overflow or compaction checks. When fresh LOCAL SDK usage is unavailable, a historical occupancy floor is used only if the owning native projection matches the actual request and the same-model measurement follows the latest native compaction or context edit. Quoted summary text and wall-clock timestamps do not establish a boundary.
518
520
 
519
- LOCAL compaction and tree summaries use a fresh text-only SDK agent: `tools: []`, no ambient settings or MCP, no pi bridge, no tool manifest/replay, `agent` mode even when the conversation uses `plan`, and a temporary store removed on completion, cancellation, or failure. Ordinary turns retain their configured capabilities. Cloud does not support the same tool restriction; bug-report streams have no public purpose hook and retain ordinary capabilities rather than being guessed from their text. Direct and summary cancellation depends on SDK settlement; SDK 1.0.36 provides no completion deadline, so a controller that never settles can leave cancellation waiting.
521
+ LOCAL compaction and tree summaries use a fresh text-only SDK agent: `tools: []`, no ambient settings or MCP, no pi bridge, no tool manifest/replay, `agent` mode even when the conversation uses `plan`, and a temporary store removed on completion, cancellation, or failure. Ordinary turns retain their configured capabilities. Cloud does not support the same tool restriction; bug-report streams have no public purpose hook and retain ordinary capabilities rather than being guessed from their text. Direct and summary cancellation depends on SDK settlement; SDK 1.0.37 provides no public completion deadline, so a controller that never settles can leave cancellation waiting.
520
522
 
521
523
  Use the separate accounting view for recorded Cursor facts:
522
524
 
@@ -598,10 +600,19 @@ Pending pi bridge calls keep their owning local Cursor live run active, includin
598
600
 
599
601
  `PI_CURSOR_LIVE_RUN_IDLE_DISPOSE_MS` sets that window for eligible retained local replay runs. It defaults to `300000` (five minutes); only decimal digits representing an integer from `1` through `2147483647` are accepted. Unset, blank, malformed (including surrounding whitespace), and out-of-range values fall back to five minutes. For example, `PI_CURSOR_LIVE_RUN_IDLE_DISPOSE_MS=900000 pi --model cursor/grok-4.6` selects fifteen minutes. The full configured window restarts after the last owned pending call settles and the provider drain lease ends. This environment-only setting does not change bridge/MCP deadlines or explicit abort/shutdown cleanup, and is not a fix for backend authentication, transport, or lost-executor failures.
600
602
 
601
- `PI_CURSOR_HTTP_1_1=true` maps to the Cursor SDK `Cursor.configure({ local: { useHttp1ForAgent: true } })` compatibility mode for corporate VPN/proxy environments where HTTP/2 streams fail. In interactive sessions, `/cursor-http on`, `/cursor-http off`, and `/cursor-http toggle` set the branch-scoped session preference and save the user default as `local.useHttp1ForAgent` in `~/.pi/agent/cursor-sdk.json`; `/cursor-http` with no argument reports the effective state. Precedence is session command/history, explicit `PI_CURSOR_HTTP_1_1`, user config, then the built-in unset default; project config is ignored for this user-level compatibility choice. Unset performs no SDK configuration, preserving the existing default path. Session shutdown clears extension-owned SDK transport state before module reload. Changing the effective setting splits the local agent pool so an agent created under another transport is not reused. When enabled, the local Cursor footer shows `http1` (for example `cursor:local · fast:on · http1`); cloud status never does. This affects Cursor SDK local-agent backend streams only; it does not configure HTTP proxies, TLS certificates, or HTTP/3. SDK 1.0.36 vendors its patched Node ConnectRPC client; its HTTP/2 default ping interval is 59 seconds and idle connection timeout is 29 seconds. Those are connection settings, not a model-turn deadline or a promise of service recovery.
603
+ `PI_CURSOR_HTTP_1_1=true` maps to the Cursor SDK `Cursor.configure({ local: { useHttp1ForAgent: true } })` compatibility mode for corporate VPN/proxy environments where HTTP/2 streams fail. In interactive sessions, `/cursor-http on`, `/cursor-http off`, and `/cursor-http toggle` set the branch-scoped session preference and save the user default as `local.useHttp1ForAgent` in `~/.pi/agent/cursor-sdk.json`; `/cursor-http` with no argument reports the effective state. Precedence is session command/history, explicit `PI_CURSOR_HTTP_1_1`, user config, then the built-in unset default; project config is ignored for this user-level compatibility choice. Unset performs no SDK configuration, preserving the existing default path. Session shutdown clears extension-owned SDK transport state before module reload. Changing the effective setting splits the local agent pool so an agent created under another transport is not reused. When enabled, the local Cursor footer shows `http1` (for example `cursor:local · fast:on · http1`); cloud status never does. This affects Cursor SDK local-agent backend streams only; it does not configure HTTP proxies, TLS certificates, or HTTP/3. SDK 1.0.37 vendors its patched Node ConnectRPC client; its HTTP/2 default ping interval is 59 seconds and idle connection timeout is 29 seconds. Those are connection settings, not a model-turn deadline or a promise of service recovery.
602
604
 
603
605
  `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.
604
606
 
607
+ Interpret the bridge diagnostic records by their boundary:
608
+
609
+ - `run_created` / `tools_exposed`: bridge exposure, not a client connection.
610
+ - `mcp_initialized`: the server received a validated `notifications/initialized`.
611
+ - `mcp_tools_list`: the catalog handler produced `toolCount` tools after request validation, not proof the client received or model consumed them.
612
+ - `request_queued` / `request_resolved` / `request_rejected`: actual bridge call handling.
613
+
614
+ These server observations do not identify the client as Cursor or prove ongoing connection health. Missing receipts do not diagnose why a client/model made no request. `/cursor-tools` cannot inspect an already captured run's surface. See [Cursor tool surfaces](docs/cursor-tool-surfaces.md#diagnosing-advertised-but-unused-bridge-tools).
615
+
605
616
  ### Maintainer cost-conscious verification
606
617
 
607
618
  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.
@@ -624,12 +635,14 @@ See [Cursor testing lessons](docs/cursor-testing-lessons.md#cursor-sdk-event-cap
624
635
 
625
636
  If no matching cached catalog is available in a cache-only phase, auth is missing, or live discovery fails or returns no models, the extension retains known bundled fallback identities and notifies interactive users when possible. By default these models remain available without auth. With `PI_CURSOR_HIDE_MODELS_WHEN_LOGGED_OUT=1`, unauthenticated picker/list availability is empty, but known CLI selection and native login remain functional. Pi owns `--api-key` parsing.
626
637
 
627
- The fallback snapshot includes Grok 4.6, Composer 2.5 (`composer-2.5` and `composer-2-5`), Composer 2, Cursor's GPT-5.6 Luna/Sol/Terra models, Claude, Gemini, Grok 4.5, Kimi, and other model IDs exposed by the reviewed `Cursor.models.list()` output. Recommended local/smoke runs use `cursor/grok-4.6`. Pi's separate `openai-codex` catalog is owned by Pi itself and includes native `gpt-5.6-luna`, `gpt-5.6-sol`, and `gpt-5.6-terra` support. The exact checked-in Cursor snapshot lives in `src/cursor-fallback-models.generated.ts`; its generator provenance records the authenticated SDK 1.0.36 catalog refresh on 2026-10-06. All 45 model records matched the reviewed metadata; checkpoint limits were retained. A dated maintainer capture documents the assistant-visible [Cursor system prompts and tool guidance](https://github.com/fitchmultz/pi-cursor-sdk/blob/main/docs/evidence/cursor-system-prompts-2026-08-02/README.md) for Grok 4.5, Opus 5, Fable 5, and the GPT-5.6 Sol/Terra/Luna family.
638
+ The fallback snapshot includes Grok 4.6, Composer 2.5 (`composer-2.5` and `composer-2-5`), Composer 2, Cursor's GPT-5.6 Luna/Sol/Terra models, Claude, Gemini, Grok 4.5, Kimi, and other model IDs exposed by the reviewed `Cursor.models.list()` output. Recommended local/smoke runs use `cursor/grok-4.6`. Pi's separate `openai-codex` catalog is owned by Pi itself and includes native `gpt-5.6-luna`, `gpt-5.6-sol`, and `gpt-5.6-terra` support. The exact checked-in Cursor snapshot lives in `src/cursor-fallback-models.generated.ts`; its generator provenance records SDK 1.0.37 and 46 models from the authenticated catalog-only refresh on 2026-10-07. That refresh added Claude Haiku 5.5 (`claude-haiku-5-5`), preserving all 45 prior model records from the SDK 1.0.36 capture on 2026-10-06. The 33 bundled checkpoint-derived entries were unchanged; no Agent/model turn or Cloud run was performed. A dated maintainer capture documents the assistant-visible [Cursor system prompts and tool guidance](https://github.com/fitchmultz/pi-cursor-sdk/blob/main/docs/evidence/cursor-system-prompts-2026-08-02/README.md) for Grok 4.5, Opus 5, Fable 5, and the GPT-5.6 Sol/Terra/Luna family.
628
639
 
629
640
  Actual Cursor runs still need a key from `/login`, `CURSOR_API_KEY`, or `--api-key`. If you add auth after startup, run `/cursor-refresh-models` to refresh the full live Cursor model catalog without restarting pi.
630
641
 
631
642
  ## Limits
632
643
 
644
+ - **Commit/PR attribution has no supported opt-out.** SDK 1.0.37 exposes neither attribution control through public create/local/send/configure options. CLI-file edits and SDK-internal patches are not supported extension settings; [#302](https://github.com/fitchmultz/pi-cursor-sdk/issues/302) tracks both controls.
645
+
633
646
  - **Cloud runtime is explicit and minimal.** Local remains the default. Cloud runs create Cursor cloud agents only after first-use acknowledgement and safety preflight, use fresh context by default, do not expose the pi bridge or local MCP, do not forward pi env vars, support explicit Cursor-managed environment selection, name agents from the pi session title when available, stream display-only agent/run/branch/PR/artifact/raw-usage telemetry when available, and record only explicit session-branch lifecycle commands for cleanup (`/cursor-cloud list|archive|delete`).
634
647
  - **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.
635
648
  - **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.
@@ -652,6 +665,8 @@ When a Cursor run fails after auth is configured, pi surfaces scrubbed provider
652
665
 
653
666
  Aborted runs now include a likely cause when determinable, for example `Cancelled: prompt interrupted.` for user cancel or `Cancelled: Cursor SDK run was cancelled.` for SDK-side cancellation.
654
667
 
668
+ SDK 1.0.37 source preserves SDK 1.0.36's client bearer refresh and unauthenticated handling, but those mechanisms do not establish the cause of [#247](https://github.com/fitchmultz/pi-cursor-sdk/issues/247)'s historical idle failure. Reloading filesystem config is not a public auth-reset API. No guessed idle TTL or extension-level automatic resend is added: resending can duplicate executed tool effects.
669
+
655
670
  Network failures from the Cursor SDK connect layer (for example `ConnectError: read ETIMEDOUT` or `ConnectError: [aborted] read ECONNRESET`) surface as scrubbed `Network error` messages instead of crashing pi, matching pi's native auto-retry classifier. The SDK-provenance `WriteIterableClosedError: WritableIterable is closed` race remains guarded for the Pi session lifecycle; Connect/network suppression remains active-turn scoped; raw Cursor SDK `AbortError` DOMExceptions are suppressed while any provider turn or session process-error guard is active. Unrelated failures remain fatal. The old raw child-stdin EPIPE workaround was removed because Cursor SDK fixed that path by 1.0.27. Persistent failures may indicate a transient Cursor service or network issue.
656
671
 
657
672
  You can also restart pi with a key in the same shell or launcher that starts pi:
@@ -671,6 +686,8 @@ pi --api-key "your-key" --model cursor/grok-4.6 -p "Say ok only"
671
686
 
672
687
  In-process sessions using independent `ModelRuntime` instances (the SDK default on supported Pi hosts) support concurrent turns, children launched inside parent tools, and direct compaction/tree/bug-report summaries. Each provider registration captures its own session, bridge, storage, and debug scope. Fork-inherited tool-result IDs cannot drain a parent's live run; replay wrappers reject foreign-owner or wrong-tool results without consuming the original card or executing work. Native request-header receipts verify the calling session before SDK/storage work, including auxiliary streams. Explicitly sharing a `ModelRuntime` overwrites its Cursor registration: requests from another session fail closed rather than entering the sibling's scope. Use independent runtimes, or reload the intended session to restore its registration; catalog refresh does not replace a sibling's provider. A not-yet-bound or shut-down provider closure cannot send. **Migration from 0.4.0:** bare `ctx.modelRegistry.complete(...)` and `ctx.modelRegistry.streamSimple(...)` calls lack the native receipt and are unsupported for Cursor, including custom compaction integrations; bind/refresh/reload does not fix that path. Use the owning AgentSession's stream path or an independent child AgentSession. CLI flags and their one-shot local-force consumption remain owned by each embedded session runtime across reload. Cursor SDK HTTP/1.1 transport configuration and environment/user defaults remain process-global; branch preferences are session-scoped, not independent SDK transport configurations. See [multi-session embedding semantics](docs/cursor-model-ux-spec.md#multi-session-embedding).
673
688
 
689
+ Independent SessionManagers opening the same persisted file have separate transient Cursor pools, generations and live-run ownership. Reload/tree/shutdown of one manager does not invalidate the other's resources. Durable store/resume/lineage identities remain unchanged; an atomic process-local agent claim prevents a sibling from resuming or deleting a still-owned handle. Failed or timed-out SDK disposal retains that claim until successful disposal or process exit. This fixes a reproduced same-file `Cursor session agent scope is closed` trigger, not every cause reported in [#282](https://github.com/fitchmultz/pi-cursor-sdk/issues/282). It is not a cross-process lock or qualification of concurrent real SQLite/journal writes to one file; use native forks or separate files for independent conversations.
690
+
674
691
  ### Native shell parsing or module loading fails
675
692
 
676
693
  Before loading the SDK, the extension resolves the installed `@cursor/sdk-<platform>-<arch>` package relative to `@cursor/sdk` and supplies its `vendor` directory through the SDK's `CURSOR_TREE_SITTER_VENDOR_DIR`. This lets native Bash parsing work when Pi's launcher and extension live in separate installation trees. The platform package must be installed; the extension does not download or bundle replacement native binaries.
@@ -679,7 +696,9 @@ An explicitly set `CURSOR_TREE_SITTER_VENDOR_DIR` is left untouched. Use an abso
679
696
 
680
697
  The automatically selected path is process-wide and inherited by bash commands and child Pi processes. A child running another extension install or worktree treats that inherited value as an explicit override, even if the parent's install has moved or been deleted. To rediscover the child's own parser package, launch it with `env -u CURSOR_TREE_SITTER_VENDOR_DIR pi -e .` (or remove the variable from the child environment on Windows). Alternatively, set an absolute vendor path for the child's install. Inherited overrides are not validated or replaced automatically.
681
698
 
682
- A `ResolveMessage`, missing module, or missing `protoBase64` export is a loader problem, not evidence of a bad API key. The static SDK and bridge imports in 0.5.1 also repair the compiled-Bun extension graph. A packed installation reached expected invalid-key handling in official compiled Pi 1.0.3 on macOS arm64. The embedded Windows missing-export report remains unqualified; an npm-installed Node Pi remains its working control. Likewise, preserving the reported idle-session `Authentication error` does not establish why an hour-idle session fails or promise automatic recovery.
699
+ A `ResolveMessage`, missing module, or missing `protoBase64` export is a loader problem, not evidence of a bad API key. The static SDK and bridge imports in 0.5.1 also repair the compiled-Bun extension graph. A packed installation reached expected invalid-key handling in official compiled Pi 1.0.3 on macOS arm64. The retained SDK 1.0.36 installed-package probe showed its nested Connect 1.7.0 / Protobuf 1.10.0 graph linking normally; forcing its Protobuf import to the root 2.16.0 package reproduces the exact missing export. That does not establish the unnamed Windows hosts' resolution in [#233](https://github.com/fitchmultz/pi-cursor-sdk/issues/233); their importer-relative paths and bootstrap remain necessary. The credential-free real-SDK first-send test reaches a blocked key-exchange boundary, not authenticated inference or every embedded loader.
700
+
701
+ SDK 1.0.37 source retains the parser-unavailable branch returning `parsingFailed`; the retained SDK 1.0.36 private package probe still executed the command. It does not itself establish why Pi received SIGTERM in the non-Cursor/opencode report [#339](https://github.com/fitchmultz/pi-cursor-sdk/issues/339). Warning text alone cannot identify the emitting artifact or signal sender.
683
702
 
684
703
  ### `pi --list-models cursor` shows no Cursor models
685
704
 
@@ -779,13 +798,13 @@ PI_CURSOR_PI_BRIDGE_CALL_TIMEOUT_MS=120000 pi --model cursor/grok-4.6
779
798
 
780
799
  This usually needs session JSONL to classify. Common cases:
781
800
 
782
- - **Model text echo:** Assistant `text` blocks contain lines like `Tool call`, `Cursor activity`, or `call cursor-replay-…` without matching `toolCall` blocks — the Cursor model narrated pi prompt transcript format instead of invoking SDK tools. See [Tool calls listed as plain text (#40 triage)](docs/cursor-testing-lessons.md#tool-calls-listed-as-plain-text-40-triage).
801
+ - **Model text echo:** Assistant `text` blocks contain lines like `Tool call`, `Cursor activity`, or `call cursor-replay-…` without matching `toolCall` blocks — narration is not tool execution. Structured history now uses `Historical tool request/result/error` labels, retaining arguments, IDs and errors without implying an unmatched request completed. This reduces an imitable template; it does not prevent model narration or strip legitimate prose/code examples. Raw assistant history is preserved and prose is never converted into tool calls or automatically resent. See [Tool calls listed as plain text (#40 triage)](docs/cursor-testing-lessons.md#tool-calls-listed-as-plain-text-40-triage).
783
802
  - **Stale replay routing / plan-strip:** Error `toolResult` or error assistant messages contain `Tool grep/cursor/find/ls not found`, or provider debug shows `inactive_trace` after plan-mode execute stripped active tools — tracked in **#52** (distinct from model text echo and #55).
784
803
  - **Replay vs execution:** `cursor-replay-*` IDs and neutral **Cursor MCP** activity cards are display-only recorded Cursor results; they do not re-run browser/MCP work. See [Cursor native tool replay](docs/cursor-native-tool-replay.md).
785
804
  - **Run failure / discarded tools:** A red toast with scrubbed detail may indicate an SDK failure (#55). Started-but-never-completed Cursor tools surface neutral **Cursor … did not complete** activity cards with a bounded reason when the run failed/aborted, produced no assistant text, or involved external/side-effectful tools. Incomplete fast local discovery starts (`read`, `grep`, `glob`, `ls`) are debug-only after a successful text-producing run so stale SDK start events do not create red post-answer cards; maintainer debug for the same gap remains in **#52** (`PI_CURSOR_SDK_EVENT_DEBUG=1`).
786
805
  - **Hard SDK crash:** pi exited with an uncaught Cursor SDK `ConnectError` or `WriteIterableClosedError` instead of showing a normal run error — capture the stack/session tail as a process-guard regression, not #40 text echo.
787
806
 
788
- Shell correlation accepts legacy names (`shell`, `bash`, `run_terminal_cmd`) with different IDs only when exactly one pending shell has identical arguments; exact IDs take precedence. This is compatibility handling, not evidence that SDK 1.0.36 emits alias-changing callback pairs. Its public shell payload uses `type: "shell"`; the installed accumulator's `onStep` preserves that completed ToolCall without adding a step ID. Assistant text or stdout progress alone does not establish completion; unmatched shell starts still remain visible and debug capture is unchanged.
807
+ Shell correlation accepts legacy names (`shell`, `bash`, `run_terminal_cmd`) with different IDs only when exactly one pending shell has identical arguments; exact IDs take precedence. This is compatibility handling, not evidence that SDK 1.0.37 emits alias-changing callback pairs. Its public shell payload uses `type: "shell"`; retained SDK 1.0.36 installed-accumulator evidence shows `onStep` preserving that completed ToolCall without adding a step ID. Assistant text or stdout progress alone does not establish completion; unmatched shell starts still remain visible and debug capture is unchanged.
789
808
 
790
809
  Capture `pi --version`, extension version, model, flags, the exact prompt, and a redacted session dir before filing bugs.
791
810
 
@@ -801,11 +820,13 @@ Approve only after checking the exact source commit, version, downloaded candida
801
820
 
802
821
  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.
803
822
 
823
+ 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.
824
+
804
825
  ## Development
805
826
 
806
- 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.36**. 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.0.4** dependencies are reproducible snapshots, not qualification targets. 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.
827
+ 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.0.4** dependencies are reproducible snapshots, not qualification targets. 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.
807
828
 
808
- TypeScript 7 builds and checks package types. `@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.
829
+ 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.
809
830
 
810
831
  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.
811
832
 
package/dist/context.js CHANGED
@@ -90,7 +90,7 @@ function formatContentBlocks(content) {
90
90
  }
91
91
  function formatToolCall(toolCall) {
92
92
  const args = JSON.stringify(toolCall.arguments) ?? "";
93
- return `Tool call (${getCursorReplayPromptLabel(toolCall.name)}, call ${toolCall.id}): ${args}`;
93
+ return `Historical tool request (${getCursorReplayPromptLabel(toolCall.name)}, call ${toolCall.id}): ${args}`;
94
94
  }
95
95
  function sanitizeSystemPromptForCursor(systemPrompt) {
96
96
  let sanitized = systemPrompt;
@@ -126,7 +126,7 @@ function formatMessage(msg) {
126
126
  }
127
127
  case "toolResult": {
128
128
  const text = formatContentBlocks(msg.content);
129
- const label = msg.isError ? "Tool error" : "Tool result";
129
+ const label = msg.isError ? "Historical tool error" : "Historical tool result";
130
130
  return `${label} (${getCursorReplayPromptLabel(msg.toolName)}, call ${msg.toolCallId}): ${text}`;
131
131
  }
132
132
  }
@@ -10,5 +10,5 @@ export function buildCursorCustomSubagentDefinitions(config) {
10
10
  }),
11
11
  }]));
12
12
  }
13
- // ponytail: SDK 1.0.36 LOCAL conversion keeps only model ID/inherit; it drops params.
13
+ // ponytail: SDK 1.0.37 LOCAL conversion keeps only model ID/inherit; it drops params.
14
14
  // Upgrade this claim only after the installed public converter preserves them.