pi-cursor-sdk 0.1.53 → 0.1.55

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 CHANGED
@@ -2,6 +2,30 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.1.55 - 2026-07-02
6
+
7
+ ### Changed
8
+
9
+ - Show Cursor models that do not expose a Cursor `fast` parameter as `cursor-fast:n/a` in the interactive footer instead of plain `cursor`, including `cursor-fast:n/a · plan` when Cursor plan mode is active.
10
+
11
+ ### Validation
12
+
13
+ - `npm test`, `npm run typecheck`, `npm run typecheck:tests`, `npm pack --dry-run`, `npm run smoke:platform:all`, and release review pass locally.
14
+
15
+ ## 0.1.54 - 2026-07-02
16
+
17
+ ### Changed
18
+
19
+ - Show Cursor fast state explicitly in the interactive footer for fast-capable Cursor models as `cursor-fast:on` or `cursor-fast:off`, while preserving plain `cursor` status for Cursor models without fast support and clearing status for non-Cursor models.
20
+
21
+ ### Fixed
22
+
23
+ - Accept wrapped `package.json` read-card paths in platform-smoke visual assertions while keeping JSONL result checks as the source of truth for the actual bridge read target.
24
+
25
+ ### Validation
26
+
27
+ - `npm test`, `npm run typecheck`, `npm run typecheck:tests`, `npm pack --dry-run`, `npm run smoke:platform:all`, and subagent review loop pass locally.
28
+
5
29
  ## 0.1.53 - 2026-06-29
6
30
 
7
31
  ### Changed
package/README.md CHANGED
@@ -236,15 +236,18 @@ The `:fast` and `:slow` aliases are available only for Cursor models whose catal
236
236
 
237
237
  Composer 2 and Composer 2.5 can default to fast. Use `--cursor-no-fast` or a `:slow` virtual alias for a one-shot no-fast Composer run. In print mode (`-p`), `--cursor-no-fast` is silent and does not write `~/.pi/agent/cursor-sdk.json`.
238
238
 
239
- In interactive mode, the footer only shows fast mode when fast is enabled and Cursor mode when it is non-default. Fast and plan mode share one Cursor status value, so they do not overwrite each other:
239
+ In interactive mode, the footer shows Cursor status only while a Cursor model is active. Fast-capable models show fast state explicitly, and fast and plan mode share one Cursor status value so they do not overwrite each other:
240
240
 
241
241
  ```text
242
- cursor fast
243
- cursor plan
244
- cursor fast · plan
242
+ cursor-fast:n/a
243
+ cursor-fast:n/a · plan
244
+ cursor-fast:off
245
+ cursor-fast:on
246
+ cursor-fast:off · plan
247
+ cursor-fast:on · plan
245
248
  ```
246
249
 
247
- If you do not see `cursor fast`, fast mode is off. If you do not see `cursor plan`, Cursor SDK mode is the default `agent` mode.
250
+ `cursor-fast:off` means fast mode is off. `cursor-fast:n/a` means the active Cursor model does not expose a fast parameter. If you do not see `plan`, Cursor SDK mode is the default `agent` mode.
248
251
 
249
252
  ## Cursor SDK mode
250
253
 
@@ -399,9 +402,9 @@ pi install npm:pi-cursor-sdk
399
402
 
400
403
  That does not mean the model cannot think. It means the Cursor SDK does not expose a pi-controllable thinking parameter for that model. The model may still think internally and may still emit thinking deltas that pi renders natively.
401
404
 
402
- ### I do not see `cursor fast` or `cursor plan` in the footer
405
+ ### I do not see `cursor-fast:on` / `cursor-fast:off` or `plan` in the footer
403
406
 
404
- Fast mode is currently off when `cursor fast` is absent. Cursor SDK mode is the default `agent` mode when `cursor plan` is absent. When both are active, pi shows one combined Cursor status: `cursor fast · plan`.
407
+ The Cursor footer appears only while a Cursor model is active. Fast-capable models show `cursor-fast:on` or `cursor-fast:off`; Cursor models without a fast parameter show `cursor-fast:n/a`. Cursor SDK mode is the default `agent` mode when `plan` is absent. When both are active, pi shows one combined Cursor status such as `cursor-fast:on · plan` or `cursor-fast:n/a · plan`.
405
408
 
406
409
  ### My Cursor app settings or rules do not seem to apply
407
410
 
@@ -124,7 +124,7 @@ Observe with `tmux capture-pane -pt "$SESSION"` or attach manually.
124
124
 
125
125
  Pass criteria:
126
126
 
127
- - Footer shows `(cursor) composer-2-5`. With `--cursor-no-fast`, Cursor fast mode is off and the Cursor extension status should not show `cursor fast`; ignore unrelated status text from other extensions.
127
+ - Footer shows `(cursor) composer-2-5`. With `--cursor-no-fast`, Cursor fast mode is off and the Cursor extension status should show `cursor-fast:off`; ignore unrelated status text from other extensions.
128
128
  - The run uses pi 0.80.2 `--session-id` successfully.
129
129
  - Assistant answer appears correctly.
130
130
  - `/session` shows one user and one assistant message for the simple run.
@@ -370,7 +370,7 @@ Rules:
370
370
  - Toggle unsuffixed models with `/cursor-fast`; do not persist a new default while a virtual fast alias is selected.
371
371
  - Store per-session and global per-base-model preferences for unsuffixed models.
372
372
  - When calling `Agent.create()` or `agent.send()`, include the selected `fast` value in Cursor model params.
373
- - Show `fast` through `ctx.ui.setStatus()` when enabled.
373
+ - Show fast-capable models as `cursor-fast:on` or `cursor-fast:off` through `ctx.ui.setStatus()` while a Cursor model is active.
374
374
  - Keep `--cursor-fast` and `--cursor-no-fast` as explicit process-level force flags.
375
375
 
376
376
  Reason:
@@ -378,10 +378,11 @@ Reason:
378
378
  - `fast` does not affect pi `contextWindow`, thinking levels, or input support.
379
379
  - The virtual aliases trade small `--list-models` noise for per-agent selection that works with subagents and dynamic workflows, where mutating a shared global fast default is the wrong abstraction.
380
380
 
381
- Status example:
381
+ Status examples:
382
382
 
383
383
  ```text
384
- cursor fast
384
+ cursor-fast:off
385
+ cursor-fast:on
385
386
  ```
386
387
 
387
388
  ## Cursor SDK Mode Behavior
@@ -409,8 +410,9 @@ Rules:
409
410
  Status examples:
410
411
 
411
412
  ```text
412
- cursor plan
413
- cursor fast · plan
413
+ cursor-fast:n/a · plan
414
+ cursor-fast:off · plan
415
+ cursor-fast:on · plan
414
416
  ```
415
417
 
416
418
  ## Footer Behavior
@@ -419,7 +421,7 @@ Hard requirement:
419
421
 
420
422
  - Leave pi's default footer intact.
421
423
  - Do not use `ctx.ui.setFooter()` for the first pass.
422
- - Use `ctx.ui.setStatus()` only for Cursor-only state that pi cannot show natively, such as `fast` and non-default Cursor SDK `plan` mode.
424
+ - Use `ctx.ui.setStatus()` only while a Cursor model is active, showing Cursor-only state that pi cannot show natively, such as `cursor-fast:on`, `cursor-fast:off`, and non-default Cursor SDK `plan` mode.
423
425
  - Non-cursor models must have no Cursor status.
424
426
 
425
427
  Reason:
@@ -433,13 +435,13 @@ Expected native footer behavior:
433
435
  - provider/model is shown by pi from the selected `cursor` model,
434
436
  - thinking level is shown by pi when `reasoning` is true,
435
437
  - context usage is computed from `contextWindow`,
436
- - extension status adds only Cursor-only text such as `cursor fast`, `cursor plan`, or `cursor fast · plan`.
438
+ - extension status adds only Cursor-only text such as `cursor-fast:n/a`, `cursor-fast:n/a · plan`, `cursor-fast:off`, `cursor-fast:on`, or `cursor-fast:on · plan`.
437
439
 
438
440
  `ctx.ui.setStatus()` adds an extension status line in the default footer. It does not patch the built-in model segment. The native shape is closer to:
439
441
 
440
442
  ```text
441
443
  ... (cursor) gpt-5.5@1m • medium
442
- cursor fast · plan
444
+ cursor-fast:off · plan
443
445
  ```
444
446
 
445
447
  not:
@@ -569,14 +571,14 @@ Initial Cursor default for Composer 2.5:
569
571
  pi model: cursor/composer-2-5
570
572
  Cursor params: fast=true
571
573
  pi thinking: off
572
- Cursor status: cursor fast
574
+ Cursor status: cursor-fast:on
573
575
  ```
574
576
 
575
577
  Toggle fast:
576
578
 
577
579
  ```text
578
580
  Cursor params: fast=false
579
- Cursor status: cleared
581
+ Cursor status: cursor-fast:off
580
582
  ```
581
583
 
582
584
  `shift+tab`: no-op because the model is not reasoning-capable.
@@ -589,7 +591,7 @@ Initial Cursor default:
589
591
  pi model: cursor/gpt-5.5@1m
590
592
  Cursor params: context=1m; reasoning=medium; fast=false
591
593
  pi thinking: medium
592
- Cursor status: cleared
594
+ Cursor status: cursor-fast:off
593
595
  ```
594
596
 
595
597
  After selecting the 272k variant:
@@ -604,7 +606,7 @@ After fast toggle:
604
606
 
605
607
  ```text
606
608
  Cursor params: context=272k; reasoning=medium; fast=true
607
- Cursor status: cursor fast
609
+ Cursor status: cursor-fast:on
608
610
  ```
609
611
 
610
612
  After `shift+tab` to xhigh:
@@ -622,7 +624,7 @@ Initial Cursor default:
622
624
  pi model: cursor/gpt-5.3-codex
623
625
  Cursor params: reasoning=high; fast=true
624
626
  pi thinking: high
625
- Cursor status: cursor fast
627
+ Cursor status: cursor-fast:on
626
628
  ```
627
629
 
628
630
  After `shift+tab` to low:
@@ -702,8 +704,9 @@ Before calling done:
702
704
  - confirm context variants show expected `context` column
703
705
  - launch interactive with Cursor
704
706
  - verify default pi footer remains unchanged
705
- - verify Cursor `fast` status appears only when enabled
706
- - verify Cursor `plan` status appears only in non-default mode and combines with fast as `cursor fast · plan`
707
+ - verify Cursor status appears only for Cursor models
708
+ - verify Cursor fast-capable models show `cursor-fast:on` or `cursor-fast:off`
709
+ - verify Cursor `plan` status appears only in non-default mode and combines with status as `cursor-fast:n/a · plan`, `cursor-fast:on · plan`, or `cursor-fast:off · plan`
707
710
  - verify non-cursor footer/status unchanged
708
711
  - verify `shift+tab` uses pi native thinking
709
712
  - verify context changes through native model selection
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-cursor-sdk",
3
- "version": "0.1.53",
3
+ "version": "0.1.55",
4
4
  "description": "pi provider extension backed by @cursor/sdk local agents",
5
5
  "author": "Mitch Fultz (https://github.com/fitchmultz)",
6
6
  "license": "MIT",
@@ -18,7 +18,7 @@ const CARD_PATTERNS = [
18
18
  { id: "write", pattern: /^\s*\+.*beta\s*$/i },
19
19
  { id: "edit-diff", pattern: /^\s*\+.*gamma\s*$/i },
20
20
  { id: "shell-failure", pattern: /^\s*(?:native shell failure|Command exited with code 7)\s*$/i },
21
- { id: "bridge-read-success", pattern: /^\s*read (?:\.\/package\.json|.*[\\/]package\.json)\s*$/i },
21
+ { id: "bridge-read-success", pattern: /^\s*read (?:\.\/package\.json|.*[\\/]package\.j(?:son|s))\s*$/i },
22
22
  { id: "bridge-read-failure", pattern: /^\s*(?:read \.\/definitely-missing-platform-smoke-file\.txt|ENOENT: no such file)\s*/i },
23
23
  { id: "bridge-shell-success", pattern: /^\s*bridge visual smoke\s*$/i },
24
24
  { id: "footer-status", pattern: /\bcomposer-2-5\b|\bcomposer-2\.5\b/i },
@@ -133,7 +133,7 @@ BRIDGE_MATRIX_OK bash_ok=<yes/no> read_ok=<yes/no> read_missing_error=<yes/no>`,
133
133
  ],
134
134
  expectedJSONLResultToolOrder: ["bash", "read", "read"],
135
135
  visualEvidence: [
136
- { id: "bridge-read-success", pattern: "^\\s*read (?:\\./package\\.json|.*[\\\\/]package\\.json)", jsonlResultId: "bridge-read-success" },
136
+ { id: "bridge-read-success", pattern: "^\\s*read (?:\\./package\\.json|.*[\\\\/]package\\.j(?:son|s))", jsonlResultId: "bridge-read-success" },
137
137
  { id: "bridge-read-failure", pattern: "^\\s*read \\./definitely-missing-platform-smoke-file\\.txt|ENOENT: no such file", jsonlResultId: "bridge-read-failure" },
138
138
  { id: "bridge-shell-success", pattern: "^\\s*bridge visual smoke\\s*$", jsonlResultId: "bridge-shell-success" },
139
139
  ],
@@ -203,16 +203,15 @@ export function getCursorProviderAgentModeOrThrow(): AgentModeOption {
203
203
  return resolution.mode;
204
204
  }
205
205
 
206
- function formatCursorStatus(fast: boolean | undefined): string | undefined {
207
- const parts: string[] = [];
206
+ function formatCursorStatus(fast: boolean | undefined): string {
207
+ const parts = [fast === true ? "cursor-fast:on" : fast === false ? "cursor-fast:off" : "cursor-fast:n/a"];
208
208
  const modeResolution = resolveCursorAgentMode();
209
- if (fast === true) parts.push("fast");
210
209
  if (modeResolution.kind === "invalid") {
211
210
  parts.push("mode invalid");
212
211
  } else if (modeResolution.mode === "plan") {
213
212
  parts.push("plan");
214
213
  }
215
- return parts.length > 0 ? `cursor ${parts.join(" · ")}` : undefined;
214
+ return parts.join(" · ");
216
215
  }
217
216
 
218
217
  function updateCursorStatus(ctx: Pick<ExtensionContext, "model" | "ui">, model = ctx.model): void {