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
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Platform Smoke Implementation Reference
|
|
2
2
|
|
|
3
|
-
Back to the canonical [Platform Smoke
|
|
3
|
+
Back to the canonical [Platform Smoke runbook](./platform-smoke.md) for cost-conscious verification, focused suite selection, optional comprehensive targets/suites, artifacts, assertions, security, and the release bar. Offline/faux checks and exact-input retained evidence come first; only necessary changed-behavior proof warrants the smallest live check on one representative environment. No paid Cloud testing for generic PRs/releases; only explicitly Cursor Cloud-focused PRs/issues may select a necessary focused Cloud check. Automated Cursor PR reviews continue unchanged.
|
|
4
4
|
|
|
5
5
|
This document records detailed detector, registry, command-rendering, implementation-history, replacement, and portability material. The phase plan is retained as implementation history, not as active release instructions.
|
|
6
6
|
|
|
@@ -18,13 +18,15 @@ Required behavior:
|
|
|
18
18
|
- fail when a card/evidence item has the wrong success/error state;
|
|
19
19
|
- fail when footer/status is missing or unreadable.
|
|
20
20
|
|
|
21
|
-
The
|
|
21
|
+
The legacy card inventory and required-card assertions use the same rendered xterm buffer lines already collected for visual evidence and screenshots. Raw ANSI stripping cannot reconstruct cursor movement, line erasure, or redraws; `terminal.txt` remains raw diagnostic text, not card evidence. Raw ANSI remains unchanged for xterm/PNG rendering and secret scanning; exact card patterns, wrapped-line matching, and JSONL success/error assertions still apply. `test/fixtures/platform-read-hyperlinks.json` retains minimal native/bridge OSC-8 headers from real captures with only the local hyperlink target anonymized.
|
|
22
|
+
|
|
23
|
+
Run the host renderer regression with `node --test test/platform-smoke-rendered-cards.test.mjs`. It requires the host Playwright Chromium checked by platform doctor and fails, rather than skips, if rendering is unavailable. Default `npm test` does not require a guest/CI browser install; the full platform gate still requires doctor and live rendered-card evidence.
|
|
22
24
|
|
|
23
25
|
Meaningful gap closed: earlier card assertions could pass when the prompt mentioned `pi__read` or a missing-file path even if the actual tool card/result never rendered. The gate now requires JSONL result evidence and per-evidence rendered screenshots for native read, native shell success/failure, native edit diffs, bridge read success/failure, and bridge shell success.
|
|
24
26
|
|
|
25
27
|
## Registry visual classification
|
|
26
28
|
|
|
27
|
-
The implementation must classify every `CURSOR_TOOL_PRESENTATION_SPECS` entry from `src/cursor-tool-presentation-registry.ts` as required or excluded for the
|
|
29
|
+
The implementation must classify every `CURSOR_TOOL_PRESENTATION_SPECS` entry from `src/cursor-tool-presentation-registry.ts` as required or excluded for the optional comprehensive visual matrix. A validation check fails when a registry entry lacks classification.
|
|
28
30
|
|
|
29
31
|
Required deterministic cards:
|
|
30
32
|
|
|
@@ -176,8 +178,10 @@ Update:
|
|
|
176
178
|
|
|
177
179
|
They must state:
|
|
178
180
|
|
|
179
|
-
-
|
|
180
|
-
-
|
|
181
|
+
- offline/faux checks and exact-input retained proof come first; new live proof is limited to the smallest meaningful changed-behavior check on one representative environment;
|
|
182
|
+
- `npm run smoke:platform:all` is an optional comprehensive matrix, not an unconditional commit/release gate;
|
|
183
|
+
- no paid Cloud testing for generic PRs/releases; only explicitly Cursor Cloud-focused PRs/issues may select necessary focused Cloud proof, with unchanged run/evidence and cleanup contracts;
|
|
184
|
+
- no full paid campaign replay, matrix-only host coverage, or automatic paid retries; automated Cursor PR reviews continue unchanged;
|
|
181
185
|
- legacy smoke scripts are inner-loop/debug helpers;
|
|
182
186
|
- `tmux` visual smoke is not the canonical cross-platform gate.
|
|
183
187
|
|
|
@@ -195,7 +199,7 @@ Replace or redesign this platform runner if any of these become true:
|
|
|
195
199
|
- The full gate exceeds the fixed Cursor invocation budget.
|
|
196
200
|
- Node 24 + `node-pty` cannot be made reliable on Windows native.
|
|
197
201
|
|
|
198
|
-
If the
|
|
202
|
+
If the runner is replaced, document the new verification process before removing it. Keep offline cross-platform contracts and selected-suite evidence fidelity; the comprehensive paid matrix is optional, not a default ship step.
|
|
199
203
|
|
|
200
204
|
## Portability to other pi extensions
|
|
201
205
|
|
package/docs/platform-smoke.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
# Platform Smoke
|
|
1
|
+
# Platform Smoke
|
|
2
2
|
|
|
3
|
-
Status:
|
|
3
|
+
Status: optional comprehensive local-runtime matrix plus focused changed-behavior checks. Offline/faux verification and exact-input retained-evidence reuse come first. Paid checks are only the smallest meaningful proof needed for changed behavior on one representative environment; docs/metadata-only changes need none. No full paid campaign replay, matrix-only host coverage, or automatic paid retries. No paid Cloud testing for generic PRs/releases; only PRs/issues explicitly focused on Cursor Cloud may select a necessary focused Cloud check. Automated Cursor PR reviews continue unchanged. The Crabbox runner, packed-install platform-build suite, and real live PTY/ConPTY suite runner are implemented for macOS, Ubuntu, and Windows native targets with one-lease-per-target orchestration.
|
|
4
4
|
|
|
5
5
|
Detailed detector, registry, command-rendering, implementation-history, replacement, and portability reference: [Platform Smoke Implementation Reference](./platform-smoke-implementation.md).
|
|
6
6
|
|
|
@@ -12,48 +12,47 @@ Crabbox best-practice baseline applied from `~/Projects/crabbox`: Crabbox owns l
|
|
|
12
12
|
|
|
13
13
|
## Decision
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
Keep offline cross-platform CI, build/type/package checks, and native/faux contracts. Reuse retained proof when its tested inputs are unchanged. If changed behavior needs new real-service proof, choose the smallest existing check and one representative environment. Source-file touch alone does not require a live run.
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
Offline checks:
|
|
18
18
|
|
|
19
19
|
```bash
|
|
20
20
|
npm run verify
|
|
21
21
|
npm pack --dry-run
|
|
22
22
|
```
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
Example focused live selection for changed restart behavior (choose the relevant suite/target, not this example by default):
|
|
25
25
|
|
|
26
26
|
```bash
|
|
27
|
-
|
|
27
|
+
node scripts/platform-smoke.mjs run --target macos --suite cursor-local-resume-restart
|
|
28
28
|
```
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
Optional comprehensive coverage, not an unconditional commit/release gate:
|
|
31
31
|
|
|
32
32
|
```bash
|
|
33
|
-
npm run smoke:
|
|
33
|
+
npm run smoke:platform:all
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
That command runs doctor first, then all configured targets/suites. The CLI can run one existing suite on one target without running the full matrix. Doctor itself makes no Cursor calls but checks the comprehensive setup; it is not proof of a provider turn. Per-target commands without `--suite` run every configured suite on that target, so prefer explicit suite selection.
|
|
38
37
|
|
|
39
|
-
|
|
38
|
+
Only a PR/issue explicitly focused on Cursor Cloud permits necessary paid Cloud testing; generic PRs/releases and incidental Cloud changes do not. Even for Cloud-focused work, `npm run smoke:cloud` is an optional multi-lane matrix, not mandatory. Select coverage only when its live proof is needed, retaining the selected check's full assertions and cleanup contract.
|
|
40
39
|
|
|
41
|
-
|
|
40
|
+
Do not repeat successful unchanged lanes or automatically retry paid failures. Preserve raw failed evidence, diagnose offline, and choose another call only when necessary. Report selected scope honestly; optional unrun hosts/lanes do not block landing, and focused evidence is not full-matrix proof.
|
|
42
41
|
|
|
43
42
|
## Non-negotiable constraints
|
|
44
43
|
|
|
45
44
|
- No GitHub Actions dependency.
|
|
46
|
-
- No
|
|
45
|
+
- No paid Cloud testing for generic PRs/releases. Explicitly Cursor Cloud-focused PRs/issues are the only testing exception; keep Cloud checks separate from local checks.
|
|
47
46
|
- No Crabbox broker/coordinator dependency.
|
|
48
|
-
-
|
|
49
|
-
-
|
|
50
|
-
-
|
|
51
|
-
-
|
|
47
|
+
- Keep offline cross-platform coverage; do not require a paid host matrix merely for matrix coverage.
|
|
48
|
+
- Visual claims require rendered evidence, not command success alone.
|
|
49
|
+
- Packed-install claims require packed-install evidence; direct `pi -e .` proof has a narrower scope.
|
|
50
|
+
- Missing setup fails a selected check; optional unselected targets are not failed release prerequisites.
|
|
52
51
|
- No one-prompt-per-card visual matrix.
|
|
53
52
|
- No `tmux` as the canonical visual test contract.
|
|
54
53
|
- No target passes from stdout alone when JSONL or visual proof is required.
|
|
55
54
|
- No target loses artifacts on failure.
|
|
56
|
-
-
|
|
55
|
+
- Every selected suite retains its required artifacts and assertions or fails. Do not weaken a check to reduce cost.
|
|
57
56
|
|
|
58
57
|
## Required Crabbox baseline
|
|
59
58
|
|
|
@@ -67,7 +66,7 @@ version: 0.26.0 or newer
|
|
|
67
66
|
binary: Homebrew `crabbox` on PATH (`/opt/homebrew/bin/crabbox` on Apple Silicon Homebrew installs)
|
|
68
67
|
```
|
|
69
68
|
|
|
70
|
-
Use the Homebrew Crabbox binary on PATH for
|
|
69
|
+
Use the Homebrew Crabbox binary on PATH for selected platform checks. `PLATFORM_SMOKE_CRABBOX=/path/to/crabbox` is only an explicit override for testing a non-default binary. `smoke:platform:doctor` verifies the configured binary and fails when it is older than the configured minimum version.
|
|
71
70
|
|
|
72
71
|
Required Crabbox providers:
|
|
73
72
|
|
|
@@ -106,7 +105,7 @@ Rendering is host-side. Targets capture the real ANSI stream; the macOS host ren
|
|
|
106
105
|
|
|
107
106
|
## Target session model
|
|
108
107
|
|
|
109
|
-
Each target opens one Crabbox
|
|
108
|
+
Each selected target opens one Crabbox session, syncs once, runs selected suites under one coherent run id, collects artifacts, and stops/releases the target. The comprehensive entrypoint runs configured targets sequentially to prevent shared host, VM/container, and Cursor API contention; each target runs its own suites in order and fails fast within that target. Platform smoke disables Crabbox git-seed sync (`CRABBOX_SYNC_GIT_SEED=false`) so every run tests the current local checkout and uncommitted smoke-runner changes rather than a remote Git seed.
|
|
110
109
|
|
|
111
110
|
```text
|
|
112
111
|
start target session
|
|
@@ -135,7 +134,7 @@ start target session
|
|
|
135
134
|
end target session
|
|
136
135
|
```
|
|
137
136
|
|
|
138
|
-
The target session fails fast. The
|
|
137
|
+
The target session fails fast. The comprehensive path handles one target at a time: it warms one lease, syncs once, runs suites in order, and stops the target after its first failure before starting the next. This avoids competing VM/container load and Cursor calls. Routine verification should instead select the smallest meaningful changed-behavior suite on one representative target; do not replay the full campaign or duplicate a focused run with the full matrix.
|
|
139
138
|
|
|
140
139
|
Runtime budget is part of the contract:
|
|
141
140
|
|
|
@@ -146,7 +145,7 @@ Runtime budget is part of the contract:
|
|
|
146
145
|
- Visual coverage is batched into one native prompt, one focused HTTP/1.1 transport prompt, one bridge prompt, and one abort/cleanup prompt per target. Do not split the card matrices into one prompt per card.
|
|
147
146
|
- The gate is fail-fast by target to avoid burning Cursor calls after a platform has already failed.
|
|
148
147
|
|
|
149
|
-
##
|
|
148
|
+
## Comprehensive matrix targets
|
|
150
149
|
|
|
151
150
|
| Target | Crabbox provider | Execution contract | TUI visual contract |
|
|
152
151
|
| --- | --- | --- | --- |
|
|
@@ -156,15 +155,15 @@ Runtime budget is part of the contract:
|
|
|
156
155
|
|
|
157
156
|
Ubuntu is covered as its own local-container target, and Windows native remains a full visual TUI target.
|
|
158
157
|
|
|
159
|
-
##
|
|
158
|
+
## Explicit Cursor Cloud-focused testing exception
|
|
160
159
|
|
|
161
|
-
Cloud
|
|
160
|
+
No paid Cloud testing for generic PRs or releases. Only a PR or issue explicitly focused on Cursor Cloud may select necessary paid Cloud proof, after offline/faux checks and retained-evidence reuse. Incidental Cloud code changes do not qualify. The no-flag multi-lane command remains callable but is not mandatory even for Cloud-focused work:
|
|
162
161
|
|
|
163
162
|
```bash
|
|
164
163
|
npm run smoke:cloud
|
|
165
164
|
```
|
|
166
165
|
|
|
167
|
-
|
|
166
|
+
This optional `cursor/grok-4.6` matrix retains its complete run/evidence and cleanup contract. It uses current `gh` CLI authentication to create one private throwaway GitHub repository, seeds clean `main`, `starting-ref`, and `direct-push` branches, and runs persisted-session named lanes for:
|
|
168
167
|
|
|
169
168
|
- cancellation, with exact agent/run IDs captured before abort, retained `runIdSource` (`metadata` or installed-SDK `Agent.listRuns()` recovery), and terminal `cancelled` independently read through the SDK;
|
|
170
169
|
- explicit HTTPS repository plus `startingRef`, requiring a distinct pushed cloud branch with remote-content and starting-ref-ancestry proof, recording whether the SDK returned branch metadata, and validating any returned PR URL through GitHub;
|
|
@@ -179,13 +178,13 @@ Every path harvests exact IDs from provider metadata and canonical lifecycle ses
|
|
|
179
178
|
|
|
180
179
|
Before removing successful raw artifacts, the gate atomically replaces `docs/evidence/cursor-cloud-smoke-matrix-latest.json` with a known-shape summary containing timestamp, model, lane observations, exact agent/run IDs, agent cleanup proof, repository cleanup proof, and retained evidence provenance. Provenance records the extension package version, installed `@cursor/sdk` version, git source revision, and a deterministic `packageSourceSha256` over the full published package surface from `package.json` `files` plus `package.json` itself (relative path + bytes; directories expanded; symlinks/non-regular paths rejected). Generated `docs/evidence/*` is outside that published surface and is not hashed. Because successful pre-commit checkouts may be uncommitted, the package-source hash is authoritative for code identity and the revision is baseline identity only. The summary is a runtime-validated known shape (explicit six-lane allowlist, complete lane-agent cleanup coverage, repository proof, provenance) that round-trips through the persisted-evidence validator with no prompts or raw output, and must pass canonical secret scrubbing plus forbidden-field scanning; a run or cleanup failure observed before the atomic rename commit point never overwrites the last successful summary. A signal first dispatched after that point can fail the process while retaining the newly committed completed-cleanup summary, as defined above. Offline release-gate resource coordination (run → harvest IDs → cleanup agents → cleanup repo → evidence only on complete success) lives in `coordinateCloudSmokeReleaseGate()` inside `scripts/lib/cloud-smoke-cleanup-evidence.mjs`. GitHub throwaway fixture ownership lives in `scripts/lib/cloud-smoke-github.mjs`, signal-safe child shutdown lives in `scripts/lib/cloud-smoke-shutdown.mjs`, and `scripts/cloud-runtime-smoke.mjs` keeps concrete lane logic.
|
|
181
180
|
|
|
182
|
-
`npm run smoke:cloud:context` (`--context-matrix`) remains optional, separate proof for fresh-versus-bootstrap context handoff. `fresh` must answer `NO_MARKER`; `bootstrap` must recall the marker. Its agents receive the same archive, delete, `Agent.get` not-found/404, and archived-inclusive list-exclusion verification, but it does not create a GitHub repository or replace the required-matrix evidence summary.
|
|
181
|
+
Only within the explicitly Cursor Cloud-focused exception, `npm run smoke:cloud:context` (`--context-matrix`) remains optional, separate proof for fresh-versus-bootstrap context handoff. `fresh` must answer `NO_MARKER`; `bootstrap` must recall the marker. Its agents receive the same archive, delete, `Agent.get` not-found/404, and archived-inclusive list-exclusion verification, but it does not create a GitHub repository or replace the required-matrix evidence summary.
|
|
183
182
|
|
|
184
|
-
|
|
183
|
+
Cloud product capabilities and offline contracts remain supported. Neither this Cloud matrix nor the comprehensive local matrix is an unconditional ship requirement.
|
|
185
184
|
|
|
186
185
|
## Focused local resume smoke
|
|
187
186
|
|
|
188
|
-
The platform matrix includes
|
|
187
|
+
The optional comprehensive platform matrix includes these local-resume lanes: restart, safety, tool-surface, abort, tree, copy/switch, fallback, compaction, default/opt-out proof, and recorded-ID-only cleanup. Platform lanes run those scripts against the target's shared packed package path, then copy each lane's session JSONL, Cursor SDK debug metadata, runtime-launch record, and other bounded smoke artifacts into its canonical platform suite directory. The same scripts still load the source checkout by default when run directly as focused host-local inner-loop checks. Windows uses the intentionally short target-side evidence component `lr` so the Cursor SDK's derived SQLite path remains below legacy `MAX_PATH`; every suite removes and verifies that directory before use, failing closed on stale or locked evidence.
|
|
189
188
|
|
|
190
189
|
The smoke starts one sessionful local Cursor run with local resume enabled by default, records the SDK agent id from provider debug metadata, restarts pi against the same session, asks for the remembered marker, and verifies:
|
|
191
190
|
|
|
@@ -319,7 +318,7 @@ export default {
|
|
|
319
318
|
};
|
|
320
319
|
```
|
|
321
320
|
|
|
322
|
-
`ubuntuContainerBaseImage` is `cimg/node:24.21`, the Ubuntu 24.04 Node 24 base with the current glibc baseline for native test dependencies. The runner builds the local `ubuntuContainerImage` wrapper with only `USER root` changed before warmup because Crabbox 0.36.0 must install SSH/Git/rsync/curl during bootstrap and `cimg/node` defaults to an unprivileged user. An explicit `PLATFORM_SMOKE_UBUNTU_IMAGE` bypasses that build and must already support Crabbox bootstrap.
|
|
321
|
+
`ubuntuContainerBaseImage` is `cimg/node:24.21`, the Ubuntu 24.04 Node 24 base with the current glibc baseline for native test dependencies. The runner builds the local `ubuntuContainerImage` wrapper with only `USER root` changed before warmup because Crabbox 0.36.0 must install SSH/Git/rsync/curl during bootstrap and `cimg/node` defaults to an unprivileged user. An explicit `PLATFORM_SMOKE_UBUNTU_IMAGE` bypasses that build and must already support Crabbox bootstrap. The package requires Node 24+, and this gate validates Node 24 on macOS, Ubuntu, and Windows.
|
|
323
322
|
|
|
324
323
|
`windowsParallels` records this repo's default shared Windows template contract. Environment overrides may point at a temporary candidate template during infrastructure work, but release runs should use the shared `pi-extension-windows-template` / `crabbox-ready` baseline unless this document is updated.
|
|
325
324
|
|
|
@@ -524,7 +523,7 @@ Cursor calls: `2`.
|
|
|
524
523
|
|
|
525
524
|
Purpose:
|
|
526
525
|
|
|
527
|
-
- prove guarded local resume default-on behavior across a pi process restart on each
|
|
526
|
+
- prove guarded local resume default-on behavior across a pi process restart on each selected OS;
|
|
528
527
|
- assert the first turn creates a local `agent-*` and the second turn resumes the same `agent-*`;
|
|
529
528
|
- force local runtime and clear cloud env knobs so ambient cloud settings cannot satisfy this suite.
|
|
530
529
|
|
|
@@ -637,9 +636,9 @@ PI_CURSOR_SDK_EVENT_DEBUG=1
|
|
|
637
636
|
|
|
638
637
|
Purpose:
|
|
639
638
|
|
|
640
|
-
- prove the packed extension completes a real local provider turn through the SDK's opt-in HTTP/1.1/SSE transport on
|
|
639
|
+
- prove the packed extension completes a real local provider turn through the SDK's opt-in HTTP/1.1/SSE transport on each selected OS;
|
|
641
640
|
- prove the final TUI status visibly includes `cursor:local ... http1`;
|
|
642
|
-
-
|
|
641
|
+
- use offline contracts or valid retained default-transport evidence rather than adding unrelated live runs.
|
|
643
642
|
|
|
644
643
|
Required final marker: `HTTP1_LIVE_OK`.
|
|
645
644
|
|
|
@@ -796,9 +795,9 @@ cursor-local-resume-cleanup: 4
|
|
|
796
795
|
|
|
797
796
|
Maximum per target: `37` Cursor invocations.
|
|
798
797
|
|
|
799
|
-
|
|
798
|
+
Declared maximum full matrix: `111` Cursor invocations (`37` per target across three targets). These are scenario budgets, not measured fixed billable model-call or SDK-step counts; actual service usage can differ.
|
|
800
799
|
|
|
801
|
-
|
|
800
|
+
`npm run smoke:platform:all` is optional comprehensive coverage; it runs doctor first and then the matrix within these declared budgets. Routine verification selects only necessary changed-behavior proof on one representative environment. No suite adds a new Cursor invocation without updating this plan and the scenario source of truth (`scripts/platform-smoke/scenarios.mjs`, plus `scripts/platform-smoke/local-resume-suites.mjs` for local-resume lanes).
|
|
802
801
|
|
|
803
802
|
## Artifact contract
|
|
804
803
|
|
|
@@ -982,16 +981,6 @@ Bridge diagnostics may include safe tool names and correlation IDs only.
|
|
|
982
981
|
|
|
983
982
|
## Release bar
|
|
984
983
|
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
```bash
|
|
988
|
-
npm run smoke:platform:all
|
|
989
|
-
```
|
|
990
|
-
|
|
991
|
-
Cloud-runtime releases additionally require:
|
|
992
|
-
|
|
993
|
-
```bash
|
|
994
|
-
npm run smoke:cloud
|
|
995
|
-
```
|
|
984
|
+
Complete offline/faux verification and reuse valid exact-input retained proof. If changed behavior still needs real-service evidence, run the smallest meaningful existing check on one representative environment. Keep its assertions, visual proof when relevant, persisted session/debug evidence, and cleanup intact. Docs/metadata-only changes need no paid calls; optional unrun matrix lanes do not block landing.
|
|
996
985
|
|
|
997
|
-
`smoke:platform:all`
|
|
986
|
+
No paid Cloud testing for generic PRs/releases; only explicitly Cursor Cloud-focused PRs/issues may select necessary focused Cloud proof. The multi-lane Cloud command and `smoke:platform:all` remain optional comprehensive tools, not unconditional gates. No full paid campaign replay, matrix-only host coverage, or automatic paid retries. Automated Cursor PR reviews continue unchanged. Record exactly what passed, what retained evidence was reused, and any specific necessary proof still missing.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-cursor-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "pi provider extension backed by @cursor/sdk local and cloud agents",
|
|
5
5
|
"author": "Mitch Fultz (https://github.com/fitchmultz)",
|
|
6
6
|
"license": "MIT",
|
|
@@ -120,7 +120,7 @@
|
|
|
120
120
|
"node": ">=24"
|
|
121
121
|
},
|
|
122
122
|
"scripts": {
|
|
123
|
-
"check:compat": "npm run build && npm run verify && node --test test/native-provider.test.mjs",
|
|
123
|
+
"check:compat": "npm run build && npm run verify && node --test test/ci-compatibility.test.mjs test/native-provider.test.mjs test/native-cursor-flow.test.mjs",
|
|
124
124
|
"build": "node ./scripts/build.mjs",
|
|
125
125
|
"prepare": "node ./scripts/prepare.mjs",
|
|
126
126
|
"typecheck": "npm run typecheck:src && npm run typecheck:tests && npm run typecheck:replay-compile",
|
|
@@ -180,16 +180,16 @@
|
|
|
180
180
|
"typebox": "*"
|
|
181
181
|
},
|
|
182
182
|
"devDependencies": {
|
|
183
|
-
"@earendil-works/pi-ai": "0.
|
|
184
|
-
"@earendil-works/pi-coding-agent": "0.
|
|
185
|
-
"@earendil-works/pi-tui": "0.
|
|
183
|
+
"@earendil-works/pi-ai": "0.99.1",
|
|
184
|
+
"@earendil-works/pi-coding-agent": "0.99.1",
|
|
185
|
+
"@earendil-works/pi-tui": "0.99.1",
|
|
186
186
|
"@modelcontextprotocol/client": "2.1.0",
|
|
187
187
|
"@types/node": "24.19.0",
|
|
188
188
|
"@typescript/typescript6": "6.0.2",
|
|
189
189
|
"@xterm/xterm": "6.0.0",
|
|
190
190
|
"node-pty": "1.1.0",
|
|
191
191
|
"playwright": "1.63.0",
|
|
192
|
-
"typebox": "1.3.
|
|
192
|
+
"typebox": "1.3.27",
|
|
193
193
|
"typescript": "7.0.2",
|
|
194
194
|
"vitest": "5.0.2"
|
|
195
195
|
},
|
|
@@ -84,14 +84,16 @@ class SmokeFailure extends Error {
|
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
function printHelp() {
|
|
87
|
-
console.log(`
|
|
87
|
+
console.log(`Explicit Cursor Cloud-focused live smoke for pi-cursor-sdk.
|
|
88
|
+
|
|
89
|
+
No paid Cloud testing for generic PRs/releases. Only PRs/issues explicitly focused on Cursor Cloud may select necessary focused Cloud proof after offline checks and retained-evidence reuse. Automated Cursor PR reviews continue unchanged. The multi-lane matrix is optional, not an unconditional ship gate; no automatic paid retries.
|
|
88
90
|
|
|
89
91
|
Usage:
|
|
90
92
|
npm run smoke:cloud
|
|
91
93
|
npm run smoke:cloud:context
|
|
92
94
|
node scripts/cloud-runtime-smoke.mjs [--context-matrix]
|
|
93
95
|
|
|
94
|
-
The no-flag
|
|
96
|
+
The optional no-flag matrix creates and deletes one private throwaway GitHub repository and runs named lanes for cancel, explicit repo/startingRef branch reporting, direct push, missing branch failure, lifecycle delete, and account-conditional artifacts/raw usage. It requires current gh auth with private-repo create/push/delete access and Cursor Cloud access to that repository.
|
|
95
97
|
|
|
96
98
|
Environment:
|
|
97
99
|
CURSOR_API_KEY Required for cloud runs and verified agent cleanup.
|
|
@@ -473,7 +473,7 @@ async function runFallbackSmoke() {
|
|
|
473
473
|
const fallback = await promptAndRead({
|
|
474
474
|
rpc,
|
|
475
475
|
artifactDir: artifactRoot,
|
|
476
|
-
message: "
|
|
476
|
+
message: "Repeat the exact LOCAL_FALLBACK marker from my immediately previous message in this conversation. Use only conversation history; do not use tools or inspect files. Reply exactly MARKER=<marker> if that prior message is present, otherwise NO_MARKER.",
|
|
477
477
|
timeoutMs,
|
|
478
478
|
seenMetadata,
|
|
479
479
|
});
|
|
@@ -8,7 +8,6 @@
|
|
|
8
8
|
|
|
9
9
|
import { writeFileSync, mkdirSync } from "node:fs";
|
|
10
10
|
import { resolve } from "node:path";
|
|
11
|
-
import { stripVTControlCharacters } from "node:util";
|
|
12
11
|
import { matchesWrappedLineAt } from "./wrapped-line-match.mjs";
|
|
13
12
|
|
|
14
13
|
const CARD_PATTERNS = [
|
|
@@ -35,21 +34,16 @@ const CARD_PATTERNS = [
|
|
|
35
34
|
{ id: "footer-status", pattern: /\bgrok-4\.6\b|\bcomposer-2-5\b|\bcomposer-2\.5\b/i },
|
|
36
35
|
];
|
|
37
36
|
|
|
38
|
-
function cleanLine(line) {
|
|
39
|
-
return stripVTControlCharacters(line).replace(/\r/g, "");
|
|
40
|
-
}
|
|
41
|
-
|
|
42
37
|
function matchesCardAt(lines, index, card) {
|
|
43
38
|
return matchesWrappedLineAt(lines, index, card.pattern, card.wrappedPattern);
|
|
44
39
|
}
|
|
45
40
|
|
|
46
41
|
/**
|
|
47
|
-
* Detect stable
|
|
42
|
+
* Detect stable evidence regions in canonical rendered xterm buffer lines.
|
|
48
43
|
*
|
|
49
44
|
* Returns an array of { id, label, startLine, endLine }.
|
|
50
45
|
*/
|
|
51
|
-
export function detectCards(
|
|
52
|
-
const lines = txtContent.split("\n").map(cleanLine);
|
|
46
|
+
export function detectCards(lines) {
|
|
53
47
|
const cards = [];
|
|
54
48
|
const seen = new Set();
|
|
55
49
|
|
|
@@ -23,7 +23,7 @@ export { isSafePlatformBundlePath as isSafeBundlePath } from "./artifacts.mjs";
|
|
|
23
23
|
import { getScenario } from "./scenarios.mjs";
|
|
24
24
|
import { warmupLease, runOnLease, stopLease } from "./crabbox-runner.mjs";
|
|
25
25
|
import { renderAll } from "./render-ansi.mjs";
|
|
26
|
-
import { assertRequiredCards
|
|
26
|
+
import { assertRequiredCards } from "./card-detect.mjs";
|
|
27
27
|
import { collectVisualEvidence } from "./visual-evidence.mjs";
|
|
28
28
|
import { extractContentText, extractFinalTextContent } from "./jsonl-text.mjs";
|
|
29
29
|
import { executeLocalResumeSuite } from "./local-resume-runner.mjs";
|
|
@@ -531,7 +531,6 @@ async function executeLiveSuite(config, targetName, suiteName, suiteDir, slug, l
|
|
|
531
531
|
const terminalAnsi = resolve(liveArtifactDir, "terminal.ansi");
|
|
532
532
|
const terminalTxt = resolve(liveArtifactDir, "terminal.txt");
|
|
533
533
|
let renderResult = { pngOk: false };
|
|
534
|
-
let cards = [];
|
|
535
534
|
if (existsSync(terminalAnsi)) {
|
|
536
535
|
renderResult = await renderAll(terminalAnsi, liveArtifactDir, {
|
|
537
536
|
label: `${targetName}-${suiteName}`,
|
|
@@ -540,17 +539,12 @@ async function executeLiveSuite(config, targetName, suiteName, suiteDir, slug, l
|
|
|
540
539
|
sessionId: `${targetName}-${suiteName}`,
|
|
541
540
|
});
|
|
542
541
|
}
|
|
543
|
-
if (existsSync(terminalTxt)) {
|
|
544
|
-
cards = detectCards(readFileSync(terminalTxt, "utf8"));
|
|
545
|
-
writeCardArtifacts(liveArtifactDir, cards);
|
|
546
|
-
}
|
|
547
542
|
|
|
548
543
|
const statusPath = resolve(liveArtifactDir, "live-status.json");
|
|
549
544
|
const status = readJson(statusPath);
|
|
550
545
|
const terminalText = existsSync(terminalTxt) ? readFileSync(terminalTxt, "utf8") : "";
|
|
551
546
|
const jsonlPath = resolve(liveArtifactDir, "session.jsonl");
|
|
552
547
|
const jsonlRaw = existsSync(jsonlPath) ? readFileSync(jsonlPath, "utf8") : "";
|
|
553
|
-
const cardChecks = assertRequiredCards(liveArtifactDir, cards, scenario?.requiredCards ?? []);
|
|
554
548
|
const jsonlToolNames = collectJsonlToolNames(jsonlRaw);
|
|
555
549
|
const jsonlResults = collectJsonlToolResults(jsonlRaw);
|
|
556
550
|
const usageChecks = collectUsageChecks(jsonlRaw);
|
|
@@ -586,14 +580,13 @@ async function executeLiveSuite(config, targetName, suiteName, suiteDir, slug, l
|
|
|
586
580
|
{ id: "bridge-diagnostic-request-resolved", fn: () => bridgeDiagnostics.some((event) => event.event === "request_resolved") },
|
|
587
581
|
] : [];
|
|
588
582
|
const visualEvidenceSpecs = scenario?.visualEvidence ?? [];
|
|
589
|
-
const visualEvidence =
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
: { ok: false, checks: [{ id: "visual-html-present", ok: false, error: "terminal.html missing" }] };
|
|
583
|
+
const visualEvidence = await collectVisualEvidence({
|
|
584
|
+
htmlPath: resolve(liveArtifactDir, "terminal.html"),
|
|
585
|
+
pngPath: resolve(liveArtifactDir, "terminal.full.png"),
|
|
586
|
+
outDir: liveArtifactDir,
|
|
587
|
+
specs: visualEvidenceSpecs,
|
|
588
|
+
});
|
|
589
|
+
const cardChecks = assertRequiredCards(liveArtifactDir, visualEvidence.cards, scenario?.requiredCards ?? []);
|
|
597
590
|
const visualEvidenceResultChecks = visualEvidenceSpecs
|
|
598
591
|
.filter((spec) => spec.jsonlResultId)
|
|
599
592
|
.map((spec) => ({
|
|
@@ -2,6 +2,7 @@ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
|
2
2
|
import { resolve } from "node:path";
|
|
3
3
|
import { pathToFileURL } from "node:url";
|
|
4
4
|
import { matchesWrappedLineAt } from "./wrapped-line-match.mjs";
|
|
5
|
+
import { detectCards, writeCardArtifacts } from "./card-detect.mjs";
|
|
5
6
|
|
|
6
7
|
function pngSize(path) {
|
|
7
8
|
try {
|
|
@@ -39,6 +40,7 @@ export function findVisualEvidenceItems(lines, specs = []) {
|
|
|
39
40
|
|
|
40
41
|
export async function collectVisualEvidence({ htmlPath, pngPath, outDir, specs = [] }) {
|
|
41
42
|
mkdirSync(outDir, { recursive: true });
|
|
43
|
+
let cards = [];
|
|
42
44
|
const evidence = {
|
|
43
45
|
ok: false,
|
|
44
46
|
htmlPath,
|
|
@@ -52,8 +54,9 @@ export async function collectVisualEvidence({ htmlPath, pngPath, outDir, specs =
|
|
|
52
54
|
|
|
53
55
|
if (!existsSync(htmlPath)) {
|
|
54
56
|
evidence.checks.push({ id: "visual-html-present", ok: false, error: "terminal.html missing" });
|
|
57
|
+
writeCardArtifacts(outDir, cards);
|
|
55
58
|
writeFileSync(resolve(outDir, "visual-evidence.json"), JSON.stringify(evidence, null, 2));
|
|
56
|
-
return evidence;
|
|
59
|
+
return { ...evidence, cards };
|
|
57
60
|
}
|
|
58
61
|
|
|
59
62
|
let browser;
|
|
@@ -99,6 +102,7 @@ export async function collectVisualEvidence({ htmlPath, pngPath, outDir, specs =
|
|
|
99
102
|
}
|
|
100
103
|
return out;
|
|
101
104
|
});
|
|
105
|
+
cards = detectCards(lines);
|
|
102
106
|
|
|
103
107
|
for (const item of findVisualEvidenceItems(lines, specs)) {
|
|
104
108
|
if (item.ok) {
|
|
@@ -133,6 +137,7 @@ export async function collectVisualEvidence({ htmlPath, pngPath, outDir, specs =
|
|
|
133
137
|
evidence.checks.push({ id: `visual-evidence-${item.id}`, ok: item.ok === true, line: item.line, screenshot: item.screenshot, pattern: item.pattern, error: item.error });
|
|
134
138
|
}
|
|
135
139
|
evidence.ok = evidence.checks.every((check) => check.ok);
|
|
140
|
+
writeCardArtifacts(outDir, cards);
|
|
136
141
|
writeFileSync(resolve(outDir, "visual-evidence.json"), JSON.stringify(evidence, null, 2));
|
|
137
|
-
return evidence;
|
|
142
|
+
return { ...evidence, cards };
|
|
138
143
|
}
|