pi-cursor-sdk 0.4.0 → 0.5.0
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 +30 -0
- package/README.md +65 -13
- package/dist/context-window-cache.js +0 -6
- package/dist/context.js +8 -0
- package/dist/cursor-cloud-lifecycle.js +122 -98
- package/dist/cursor-durable-fs.js +97 -3
- package/dist/cursor-fallback-models.generated.js +288 -1
- package/dist/cursor-fallback-warning.js +2 -2
- package/dist/cursor-http1.js +8 -8
- package/dist/cursor-live-run-coordinator.js +9 -13
- package/dist/cursor-native-replay-routing.js +1 -1
- package/dist/cursor-native-tool-display-registration.js +46 -22
- package/dist/cursor-native-tool-display-state.js +57 -22
- package/dist/cursor-native-tool-display-tools.js +5 -6
- package/dist/cursor-pi-tool-bridge-constants.js +23 -2
- package/dist/cursor-pi-tool-bridge-run.js +7 -3
- package/dist/cursor-pi-tool-bridge-snapshot.js +1 -1
- package/dist/cursor-pi-tool-bridge.js +31 -9
- package/dist/cursor-provider-binding.js +58 -0
- package/dist/cursor-provider-errors.js +28 -7
- package/dist/cursor-provider-lazy.js +23 -11
- package/dist/cursor-provider-live-run-drain.js +15 -12
- package/dist/cursor-provider-run-finalizer.js +19 -8
- package/dist/cursor-provider-turn-coordinator.js +1 -0
- package/dist/cursor-provider-turn-display-router.js +4 -0
- package/dist/cursor-provider-turn-emit.js +1 -0
- package/dist/cursor-provider-turn-finalize.js +29 -20
- package/dist/cursor-provider-turn-prepare.js +24 -11
- package/dist/cursor-provider-turn-runner.js +37 -11
- package/dist/cursor-provider-turn-send.js +22 -9
- package/dist/cursor-provider-turn-summary.js +89 -0
- package/dist/cursor-provider.js +9 -3
- package/dist/cursor-request-provenance.js +42 -0
- package/dist/cursor-ripgrep-path.js +14 -3
- package/dist/cursor-runtime-state.js +50 -43
- package/dist/cursor-sdk-billed-usage.js +54 -75
- package/dist/cursor-sdk-event-debug-session.js +5 -6
- package/dist/cursor-sdk-event-debug.js +9 -6
- package/dist/cursor-sdk-process-error-guard.js +8 -7
- package/dist/cursor-sdk-runtime.js +13 -0
- package/dist/cursor-session-agent-cleanup.js +2 -2
- package/dist/cursor-session-agent-lifecycle.js +18 -9
- package/dist/cursor-session-agent-lineage.js +28 -12
- package/dist/cursor-session-agent-resume.js +51 -35
- package/dist/cursor-session-agent.js +9 -9
- package/dist/cursor-session-compaction-prep.js +2 -7
- package/dist/cursor-session-scope.js +71 -39
- package/dist/cursor-session-settings.js +61 -0
- package/dist/cursor-skill-tool.js +32 -49
- package/dist/cursor-state.js +72 -62
- package/dist/cursor-usage-accounting.js +13 -70
- package/dist/cursor-usage-command.js +89 -0
- package/dist/cursor-usage-ledger.js +512 -0
- package/dist/index.js +11 -19
- package/dist/model-discovery.js +11 -19
- package/docs/cursor-dogfood-checklist.md +3 -3
- package/docs/cursor-live-smoke-checklist.md +15 -15
- package/docs/cursor-model-ux-spec.md +59 -18
- package/docs/cursor-native-tool-replay.md +5 -3
- package/docs/cursor-native-tool-visual-audit.md +8 -8
- package/docs/cursor-testing-lessons.md +47 -23
- package/docs/cursor-tool-surfaces.md +1 -1
- package/docs/platform-smoke-implementation.md +10 -6
- package/docs/platform-smoke.md +35 -46
- package/package.json +6 -6
- package/scripts/cloud-runtime-smoke.mjs +4 -2
- package/scripts/local-resume-smoke.mjs +1 -1
- package/scripts/platform-smoke/card-detect.mjs +2 -8
- package/scripts/platform-smoke/targets.mjs +8 -15
- package/scripts/platform-smoke/visual-evidence.mjs +7 -2
- package/scripts/tmux-live-smoke.sh +57 -90
- package/src/context-window-cache.ts +0 -6
- package/src/context.ts +8 -0
- package/src/cursor-cloud-lifecycle.ts +124 -98
- package/src/cursor-durable-fs.ts +65 -3
- package/src/cursor-fallback-models.generated.ts +288 -1
- package/src/cursor-fallback-warning.ts +2 -2
- package/src/cursor-http1.ts +8 -8
- package/src/cursor-live-run-coordinator.ts +12 -13
- package/src/cursor-native-replay-routing.ts +2 -1
- package/src/cursor-native-tool-display-registration.ts +48 -24
- package/src/cursor-native-tool-display-state.ts +65 -21
- package/src/cursor-native-tool-display-tools.ts +7 -4
- package/src/cursor-pi-tool-bridge-constants.ts +27 -2
- package/src/cursor-pi-tool-bridge-run.ts +11 -3
- package/src/cursor-pi-tool-bridge-snapshot.ts +1 -1
- package/src/cursor-pi-tool-bridge.ts +26 -9
- package/src/cursor-provider-binding.ts +62 -0
- package/src/cursor-provider-errors.ts +27 -7
- package/src/cursor-provider-lazy.ts +21 -15
- package/src/cursor-provider-live-run-drain.ts +20 -13
- package/src/cursor-provider-run-finalizer.ts +24 -15
- package/src/cursor-provider-turn-coordinator.ts +2 -0
- package/src/cursor-provider-turn-display-router.ts +5 -0
- package/src/cursor-provider-turn-emit.ts +3 -1
- package/src/cursor-provider-turn-finalize.ts +38 -23
- package/src/cursor-provider-turn-prepare.ts +23 -14
- package/src/cursor-provider-turn-runner.ts +40 -13
- package/src/cursor-provider-turn-send.ts +23 -15
- package/src/cursor-provider-turn-summary.ts +94 -0
- package/src/cursor-provider-turn-types.ts +37 -4
- package/src/cursor-provider.ts +25 -3
- package/src/cursor-request-provenance.ts +64 -0
- package/src/cursor-ripgrep-path.ts +15 -5
- package/src/cursor-runtime-state.ts +53 -48
- package/src/cursor-sdk-billed-usage.ts +54 -102
- package/src/cursor-sdk-event-debug-session.ts +5 -5
- package/src/cursor-sdk-event-debug.ts +10 -6
- package/src/cursor-sdk-process-error-guard.ts +7 -7
- package/src/cursor-sdk-runtime.ts +14 -0
- package/src/cursor-session-agent-cleanup.ts +2 -2
- package/src/cursor-session-agent-lifecycle.ts +14 -9
- package/src/cursor-session-agent-lineage.ts +26 -12
- package/src/cursor-session-agent-resume.ts +49 -36
- package/src/cursor-session-agent.ts +13 -10
- package/src/cursor-session-compaction-prep.ts +2 -7
- package/src/cursor-session-scope.ts +87 -39
- package/src/cursor-session-settings.ts +72 -0
- package/src/cursor-skill-tool.ts +37 -61
- package/src/cursor-state.ts +74 -67
- package/src/cursor-usage-accounting.ts +17 -82
- package/src/cursor-usage-command.ts +76 -0
- package/src/cursor-usage-ledger.ts +500 -0
- package/src/index.ts +14 -23
- package/src/model-discovery.ts +14 -22
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,35 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.5.0 - 2026-10-04
|
|
4
|
+
|
|
5
|
+
### Breaking Changes
|
|
6
|
+
|
|
7
|
+
- Bare `ctx.modelRegistry.complete(...)` and `ctx.modelRegistry.streamSimple(...)` calls are unsupported for Cursor models because they lack native session ownership receipts. Custom compaction and other integrations must use the owning AgentSession's stream path or an independent child AgentSession; bind/refresh/reload does not migrate bare calls. See [embedding migration guidance](README.md#embedded-sessions-report-concurrent-cursor-turns).
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
|
|
11
|
+
- Refresh the SDK-derived fallback catalog to 45 models, including Claude Sonnet 5.5, GLM 5.3, and GLM 5.3 Flash. Preserve existing checkpoint-derived context windows.
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
|
|
15
|
+
- Isolate concurrent and nested in-process Cursor sessions, including direct compaction/tree/bug-report streams, bridge/replay state, pooled agents, storage, journals, and debug artifacts (#217, #234). Native request-header ownership receipts reject mismatched shared ModelRuntime calls with recovery guidance rather than choosing a sibling.
|
|
16
|
+
- Keep cloud archive/delete authority, intents, and results in the command's originating session branch across auth/SDK waits and owner reload/shutdown; unstarted child reload/shutdown no longer closes a parent's live pool.
|
|
17
|
+
- Restore native replay wrapper ownership after `/new`, `/resume`, reloads, and session switches without replacing third-party tools (#203).
|
|
18
|
+
- Apply configured `models.json` cost rates to mapped token usage with Pi's native pricing helper; default rates and Cursor billed amounts are unchanged (#230, #231; thanks @TianZuo555).
|
|
19
|
+
- Resolve the installed Cursor SDK native parser package before SDK initialization, preserving explicit `CURSOR_TREE_SITTER_VENDOR_DIR` overrides (#232).
|
|
20
|
+
- Improve diagnostics with bounded, scrubbed structured errors and causes without diagnosing loader or ambiguous session-authentication failures as invalid API keys. The underlying compiled/embedded-host and idle-session failures reported in #228, #233, and #247 remain open.
|
|
21
|
+
- Bound bridge tool-call IDs while preserving unique calls and matching results (#237; thanks @gwatkins-arista).
|
|
22
|
+
- Keep skill activation callable with its catalog/descriptions intact and a stable system prompt (#244). Each registered session owns its skill catalog, so a sibling's same-named skill or catalog reset cannot change activation.
|
|
23
|
+
- Map SDK `reasoning_effort` controls to Pi thinking without changing SDK defaults.
|
|
24
|
+
- Repair context floors using the owning native projection, actual request equivalence, model compatibility, and source order after compaction/context edits—not timestamps, summary-looking text, or `tokensBefore`. Keep fresh LOCAL SDK usage authoritative and native components coherent so cumulative bills cannot trigger repeated false compaction.
|
|
25
|
+
- Isolate LOCAL compaction/tree summaries in fresh text-only agents and temporary stores, without conversation tools/MCP/bridge/manifest/replay, plan mode, or resume lineage. Await cleanup before summary terminal emission; ordinary capabilities remain intact.
|
|
26
|
+
- Preserve every raw turn and original reported/terminal snapshot separately from disjoint public billed data in durable origin/branch journals. Remove process-only UUID watermarks; retain delayed/revised/aggregate-only/error/abort/reopen facts without inventing branch attribution.
|
|
27
|
+
|
|
28
|
+
### Added
|
|
29
|
+
|
|
30
|
+
- `/cursor-usage` view, bounded public billing refresh, exclusive private JSON export, and recovery help, leaving Pi's default footer and configured-price estimates intact. Reports unavailable/pending settlement, shared or unknown history, journal gaps, other-branch facts and unclaimed records honestly. No private billing fallback or native invoice-total claim.
|
|
31
|
+
- Offline working-tree qualification for exact official Pi releases without committing, including native compaction, summary cleanup and billing regressions.
|
|
32
|
+
|
|
3
33
|
## 0.4.0 - 2026-09-26
|
|
4
34
|
|
|
5
35
|
### Breaking Changes
|
package/README.md
CHANGED
|
@@ -51,7 +51,7 @@ 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.
|
|
54
|
+
- pi-cursor-sdk 0.5.0 requires official Pi 0.87.1 or later. Official Pi 0.87.1/latest and current `fitchmultz/pi` main are compatibility targets; the exact development `@earendil-works/pi-ai`, `@earendil-works/pi-coding-agent`, and `@earendil-works/pi-tui` packages are 0.99.1
|
|
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
|
|
|
@@ -212,13 +212,14 @@ Cursor `context` becomes a pi-visible model variant because it changes pi's nati
|
|
|
212
212
|
|
|
213
213
|
All Cursor SDK models should be treated as thinking-capable Cursor models. The `thinking` column in `pi --list-models` is narrower: it only means pi can control a Cursor SDK thinking parameter for that model.
|
|
214
214
|
|
|
215
|
-
For models where Cursor exposes `reasoning`, `effort`, or boolean `thinking` parameters, pi's native thinking controls map to Cursor SDK params:
|
|
215
|
+
For models where Cursor exposes `reasoning`, `effort`, `reasoning_effort`, or boolean `thinking` parameters, pi's native thinking controls map to Cursor SDK params:
|
|
216
216
|
|
|
217
217
|
- `reasoning=none|low|medium|high|extra-high`
|
|
218
218
|
- `effort=low|medium|high|xhigh|max`
|
|
219
|
+
- `reasoning_effort=low|medium|high`
|
|
219
220
|
- `thinking=false|true` for boolean thinking models
|
|
220
221
|
|
|
221
|
-
Pi `xhigh` maps to Cursor `xhigh` or `extra-high`; Pi `max` maps only to a distinct Cursor `max` value.
|
|
222
|
+
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`.
|
|
222
223
|
|
|
223
224
|
For Claude models with both `thinking` and `effort`, pi thinking `off` sends `thinking=false` and omits `effort`.
|
|
224
225
|
|
|
@@ -226,7 +227,7 @@ For Claude models with both `thinking` and `effort`, pi thinking `off` sends `th
|
|
|
226
227
|
|
|
227
228
|
In `pi --list-models`, `thinking=no` means pi cannot control the model's thinking level with `--thinking`, a final `:medium` model suffix, or shift+tab. It does not mean the Cursor model cannot think.
|
|
228
229
|
|
|
229
|
-
Some Cursor SDK models do not expose a `reasoning`, `effort`, or `thinking` parameter for the extension to set. Cursor thinking is still enabled/supported by the model, and Cursor may still emit thinking deltas. The extension surfaces those deltas through pi's native thinking rendering when the SDK emits them.
|
|
230
|
+
Some Cursor SDK models do not expose a `reasoning`, `effort`, `reasoning_effort`, or `thinking` parameter for the extension to set. Cursor thinking is still enabled/supported by the model, and Cursor may still emit thinking deltas. The extension surfaces those deltas through pi's native thinking rendering when the SDK emits them.
|
|
230
231
|
|
|
231
232
|
## Fast mode
|
|
232
233
|
|
|
@@ -293,7 +294,7 @@ Change the session mode interactively:
|
|
|
293
294
|
|
|
294
295
|
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).
|
|
295
296
|
|
|
296
|
-
|
|
297
|
+
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.
|
|
297
298
|
|
|
298
299
|
Cursor SDK `plan` mode can produce plan-oriented output and Cursor todo/plan activity, but those replay cards remain display-only. They do not drive pi's plan-mode extension, pi todos, or active tool state.
|
|
299
300
|
|
|
@@ -419,7 +420,7 @@ If the agent intent cannot be persisted, pi does not send; if the returned run c
|
|
|
419
420
|
|
|
420
421
|
`/cursor-cloud list`, `/cursor-cloud archive <bc-agentId>`, and `/cursor-cloud delete <bc-agentId> --yes` only accept exact recorded `bc-` cloud IDs.
|
|
421
422
|
|
|
422
|
-
Archive/delete require resolved Cursor auth, fsync a durable intent before the
|
|
423
|
+
Archive/delete require resolved Cursor auth and unchanged originating session/branch authority before SDK work, fsync a durable intent before the mutation, and fsync its actual success result afterward. Once started, the result stays in the original journal even if that owner changes branch, reloads, or shuts down; it is not mirrored into a replacement branch. An unresolved intent blocks retries and directs manual dashboard inspection instead of guessing whether an irreversible request completed.
|
|
423
424
|
|
|
424
425
|
### Cloud boundaries
|
|
425
426
|
|
|
@@ -451,6 +452,30 @@ Only enabled local safety values are passed to `Agent.create({ local })`; false/
|
|
|
451
452
|
Images from the latest user message are forwarded to Cursor. Historical images are kept out of the transcript and appear only as `[image omitted from transcript]` placeholders, so follow-up questions about an earlier image should reattach the image or include a textual description. The extension advertises `text` and `image` input for Cursor models because Cursor's SDK accepts image messages and Cursor models are expected to support them.
|
|
452
453
|
|
|
453
454
|
|
|
455
|
+
## Context, compaction, and Cursor usage
|
|
456
|
+
|
|
457
|
+
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.
|
|
458
|
+
|
|
459
|
+
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.32 provides no completion deadline, so a controller that never settles can leave cancellation waiting.
|
|
460
|
+
|
|
461
|
+
Use the separate accounting view for recorded Cursor facts:
|
|
462
|
+
|
|
463
|
+
```text
|
|
464
|
+
/cursor-usage
|
|
465
|
+
/cursor-usage refresh
|
|
466
|
+
/cursor-usage export cursor-usage.json
|
|
467
|
+
/cursor-usage help
|
|
468
|
+
```
|
|
469
|
+
|
|
470
|
+
- **View:** current-branch corrected LOCAL raw turns, original SDK telemetry, terminal status, and whole-agent public billing observations. Raw turns, wait/handle snapshots, and bills overlap; they are never added together. Cloud raw normalization remains unqualified.
|
|
471
|
+
- **Refresh:** public `Agent.getUsage()` only, up to 32 recorded agents with a five-second limit each; no model sends or automatic polling. An unavailable endpoint remains unavailable—there is no private dashboard fallback.
|
|
472
|
+
- **Export:** creates a new private JSON file without replacing existing files. It contains IDs, lineage, usage, configured pricing, and observation status, not prompts or tool content. Inspect local paths/identifiers before sharing.
|
|
473
|
+
- **Honest limits:** observations may lag or revise; they are not final invoices. Known aggregate usage/cost stays visible even when inherited run history is incomplete; full run snapshots and aggregate-only remainders are withheld rather than invented. Unavailable refreshes retain explicitly labeled latest-known observations. LOCAL client run IDs do not join billing UUIDs. Resumed history without a known creation record is marked unknown; shared-lineage and multiple-origin observations are not billed to the current branch. Current official Pi has no public extension API for complete native invoice totals.
|
|
474
|
+
|
|
475
|
+
Before a send, the extension records a unique public native branch claim and a validated, fsynced intent. Usage journals live beside the Pi session JSONL as `cursor-usage-<session-id-hash>.journal`; they retain late facts for the original owner without writing a switched session or sibling branch. Fileless sessions are explicitly ephemeral. Missing or torn inherited journals remain explicitly incomplete. Known claims outside the current branch are shown as other-branch facts; same-directory, same-ID recovery with a lost initial claim is shown as unclaimed history. Neither is newly recognized current-branch spend. If every origin reference is lost after moving directories, the extension cannot discover that history without unsafe scanning.
|
|
476
|
+
|
|
477
|
+
Each origin journal has a **16 MiB ceiling**. Persistence failure before a send prevents that send. Later failure may warn once while the original owner is current; `/cursor-usage` exposes incomplete accounting without changing the response's outcome. For a torn trailing frame, view/export preserves the validated prefix and reports the incomplete journal; further appends fail closed without changing its bytes. For ceiling or torn-tail recovery, export and retain the old session/journal, then fork the conversation into a new native session or start a new session. Do not delete or truncate the journal to continue an old agent lineage. `/cursor-usage help` also documents this recovery.
|
|
478
|
+
|
|
454
479
|
## Cursor provider tool contract
|
|
455
480
|
|
|
456
481
|
See [Cursor tool surfaces in pi](docs/cursor-tool-surfaces.md) for a concise guide to callable vs display-only tools, MCP catalog limits, JSONL ID patterns, and how pi toggles differ from Cursor ambient MCP.
|
|
@@ -511,11 +536,15 @@ On bootstrap sends, a compact **callable tool surfaces** block is injected into
|
|
|
511
536
|
|
|
512
537
|
`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.
|
|
513
538
|
|
|
514
|
-
### Maintainer
|
|
539
|
+
### Maintainer cost-conscious verification
|
|
540
|
+
|
|
541
|
+
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.
|
|
542
|
+
|
|
543
|
+
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.
|
|
515
544
|
|
|
516
|
-
|
|
545
|
+
[Platform smoke](docs/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.
|
|
517
546
|
|
|
518
|
-
The older live smoke helpers remain useful for inner-loop debugging and focused visual audits, not as the release gate. Use [Cursor live smoke checklist](docs/cursor-live-smoke-checklist.md), `npm run smoke:visual`, `npm run smoke:live`, or direct `pi --approve -e . --cursor-no-fast --model cursor/grok-4.6` runs when
|
|
547
|
+
The older live smoke helpers remain useful for inner-loop debugging and focused visual audits, not as the release gate. Use [Cursor live smoke checklist](docs/cursor-live-smoke-checklist.md), `npm run smoke:visual`, `npm run smoke:live`, or direct `pi --approve -e . --cursor-no-fast --model cursor/grok-4.6` runs 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](docs/cursor-testing-lessons.md) for auth.json seeding, isolated `/tmp` harness layout, JSONL replay-error scans, and other regression traps.
|
|
519
548
|
|
|
520
549
|
### Maintainer Cursor SDK event capture
|
|
521
550
|
|
|
@@ -544,7 +573,8 @@ Actual Cursor runs still need a key from `/login`, `CURSOR_API_KEY`, or `--api-k
|
|
|
544
573
|
- **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.
|
|
545
574
|
- **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.
|
|
546
575
|
- **Output token limits are conservative.** Cursor SDK model metadata does not currently expose output token limits directly.
|
|
547
|
-
- **Local token usage uses Cursor SDK data when safely attributable.**
|
|
576
|
+
- **Local token usage uses Cursor SDK data when safely attributable.** In-time LOCAL raw `turn-ended` usage keeps full-prompt input with cache as a partition: pi maps `input = inputTokens - cacheRead - cacheWrite`, retains the cache fields, and sets `totalTokens = inputTokens + outputTokens`. Fallback components and total describe the same estimated current context. Late SDK usage is not retroactively applied to an emitted pi message, but every raw turn remains separately recorded by the [Cursor usage ledger](#context-compaction-and-cursor-usage). Raw Cloud telemetry is retained without assuming LOCAL normalization.
|
|
577
|
+
- **Configured cost is separate from Cursor billing.** Discovered models register zero rates. `models.json` per-million `cost` overrides, including tiers, use pi's native pricing helper on each emitted message's coherent context components. Fallback has no inferred cache split; split-message estimates can differ from actual internal request pricing. Public `getUsage()` billed input/cache/output categories are already disjoint—cache is not subtracted again—and optional `cost.rawCostCents` / `cost.chargedCents` are retained separately in floating-point cents. Neither these revisable observations nor native configured estimates promise invoice reconciliation.
|
|
548
578
|
|
|
549
579
|
## Troubleshooting
|
|
550
580
|
|
|
@@ -552,7 +582,7 @@ Actual Cursor runs still need a key from `/login`, `CURSOR_API_KEY`, or `--api-k
|
|
|
552
582
|
|
|
553
583
|
You may be seeing fallback startup models or a missing/invalid Cursor SDK API key. Cursor Agent CLI/Desktop login is not reused by this extension. In interactive pi, run `/login`, choose `Use an API key`, choose `Cursor`, paste the key, then run `/cursor-refresh-models`.
|
|
554
584
|
|
|
555
|
-
When a Cursor run fails after auth is configured, pi
|
|
585
|
+
When a Cursor run fails after auth is configured, pi surfaces scrubbed provider detail instead of only `Cursor SDK run failed`. Structured errors retain bounded name, code, message, and up to two nested causes; headers and other object fields are not displayed. Generic completed-run failures include safe run metadata such as model id, a short run id prefix, and duration when available, and are phrased as pi retryable provider errors so automatic retry/backoff can recover transient SDK failures. Unknown startup failures, module-loading errors, and ambiguous session authentication errors are not diagnosed as invalid API keys. Explicit missing, invalid, or revoked API-key errors still show key setup guidance.
|
|
556
586
|
|
|
557
587
|
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.
|
|
558
588
|
|
|
@@ -571,6 +601,20 @@ Or run a one-shot command:
|
|
|
571
601
|
pi --api-key "your-key" --model cursor/grok-4.6 -p "Say ok only"
|
|
572
602
|
```
|
|
573
603
|
|
|
604
|
+
### Embedded sessions report concurrent Cursor turns
|
|
605
|
+
|
|
606
|
+
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 run `/cursor-refresh-models`/reload to restore the intended registration. 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).
|
|
607
|
+
|
|
608
|
+
### Native shell parsing or module loading fails
|
|
609
|
+
|
|
610
|
+
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.
|
|
611
|
+
|
|
612
|
+
An explicitly set `CURSOR_TREE_SITTER_VENDOR_DIR` is left untouched. Use an absolute path to a vendor directory containing both `tree-sitter` and `tree-sitter-bash`, or unset it to use package-relative discovery. Empty and relative overrides are also preserved; the SDK decides whether to use them or its own fallback lookup.
|
|
613
|
+
|
|
614
|
+
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.
|
|
615
|
+
|
|
616
|
+
A `ResolveMessage`, missing module, or missing `protoBase64` export is a loader problem, not evidence of a bad API key. Reports involving compiled Bun Pi and embedded hosts remain open; this native-path repair does not change their dependency loading graph. An npm-installed Node Pi is the known working control. Likewise, preserving the reported idle-session `Authentication error` does not establish why an hour-idle session fails or promise automatic recovery.
|
|
617
|
+
|
|
574
618
|
### `pi --list-models cursor` shows no Cursor models
|
|
575
619
|
|
|
576
620
|
Confirm the package is installed:
|
|
@@ -681,13 +725,21 @@ Cursor native replay is a display enhancement for TUI sessions and structured JS
|
|
|
681
725
|
|
|
682
726
|
## Development
|
|
683
727
|
|
|
684
|
-
The source qualification baseline is official Pi **0.
|
|
728
|
+
The source qualification baseline is official Pi **0.99.1**, with official Pi latest and current `fitchmultz/pi` main as compatibility targets, optional wildcard Pi/TypeBox host peers, and exact Cursor SDK **1.0.32**. The exact development Pi cohort is 0.99.1, with host TypeBox 1.3.27. Run `npm ci --ignore-scripts` then `npm run check:compat` in an empty HOME/agent profile for credential-free qualification. 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.
|
|
685
729
|
|
|
686
730
|
TypeScript 7 builds and checks package types. `@typescript/typescript6` is dev-only and used solely by the AST architecture test because TypeScript 7 does not expose a stable compiler API. Vitest 5 runs with `clearMocks: true` by default.
|
|
687
731
|
|
|
688
732
|
Pull-request CI runs that suite once, then checks the installed package offline with the oldest supported official Pi release, the current official release, and a source-built revision of the Pi fork. It checks both npm and Git installations 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.
|
|
689
733
|
|
|
690
|
-
|
|
734
|
+
For authorized uncommitted repairs, qualify an isolated immutable working-tree snapshot without committing:
|
|
735
|
+
|
|
736
|
+
```bash
|
|
737
|
+
node scripts/ci-compatibility.mjs --working-tree --official-only --versions 0.87.1,0.99.1,1.0.2
|
|
738
|
+
```
|
|
739
|
+
|
|
740
|
+
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.
|
|
741
|
+
|
|
742
|
+
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.
|
|
691
743
|
|
|
692
744
|
Run checks:
|
|
693
745
|
|
|
@@ -4,7 +4,6 @@ import { getAgentDir } from "@earendil-works/pi-coding-agent";
|
|
|
4
4
|
import { BUNDLED_CONTEXT_WINDOWS } from "./bundled-context-windows.js";
|
|
5
5
|
import { asRecord } from "./cursor-record-utils.js";
|
|
6
6
|
const CONTEXT_WINDOW_CACHE_FILE = "cursor-sdk-context-windows.json";
|
|
7
|
-
let userContextWindowOverrideLoadCount = 0;
|
|
8
7
|
function getCachePath() {
|
|
9
8
|
return join(getAgentDir(), CONTEXT_WINDOW_CACHE_FILE);
|
|
10
9
|
}
|
|
@@ -26,7 +25,6 @@ function parseContextWindowCacheFile(value) {
|
|
|
26
25
|
};
|
|
27
26
|
}
|
|
28
27
|
function loadUserContextWindowOverrides() {
|
|
29
|
-
userContextWindowOverrideLoadCount += 1;
|
|
30
28
|
const path = getCachePath();
|
|
31
29
|
const overrides = new Map();
|
|
32
30
|
if (!existsSync(path))
|
|
@@ -85,8 +83,4 @@ export function saveCachedContextWindow(modelId, contextWindow) {
|
|
|
85
83
|
}
|
|
86
84
|
export const __testUtils = {
|
|
87
85
|
getCachePath,
|
|
88
|
-
getUserContextWindowOverrideLoadCount: () => userContextWindowOverrideLoadCount,
|
|
89
|
-
resetUserContextWindowOverrideLoadCount: () => {
|
|
90
|
-
userContextWindowOverrideLoadCount = 0;
|
|
91
|
-
},
|
|
92
86
|
};
|
package/dist/context.js
CHANGED
|
@@ -324,6 +324,14 @@ export function buildCursorIncrementalPrompt(context, options = {}) {
|
|
|
324
324
|
const parts = applyPromptBudget(sectionsBeforeMessages, latestUserMessageSections, [getCursorToolTailGuardText(options)], latestUserMessageIndex, budgetOptions);
|
|
325
325
|
return { text: parts.join(SECTION_SEPARATOR), images };
|
|
326
326
|
}
|
|
327
|
+
/** Native compaction/tree instructions are already a complete summarization request. */
|
|
328
|
+
export function buildCursorSummaryPrompt(context) {
|
|
329
|
+
const { systemPrompt } = resolveCursorPiContext(context);
|
|
330
|
+
const sections = normalizePiContextMessages(context.messages).map(formatMessage).filter((text) => text !== undefined);
|
|
331
|
+
if (systemPrompt)
|
|
332
|
+
sections.unshift(`System instructions from pi:\n${systemPrompt}`);
|
|
333
|
+
return { text: sections.join(SECTION_SEPARATOR), images: [] };
|
|
334
|
+
}
|
|
327
335
|
export function buildCursorPrompt(context, options = {}) {
|
|
328
336
|
const sectionsBeforeMessages = [getCursorToolBoundaryText({
|
|
329
337
|
agentMode: options.agentMode,
|