@rahularya01/pi-cursor 1.3.3 → 1.4.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 +22 -0
- package/README.md +18 -1
- package/dist/index.js +17 -17
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.4.0] - 2026-07-29
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- **Extension initialization took 10–15 seconds.** Activation now completes in **3–12ms** (measured; previously ~6.8s of blocking work before pi could continue). Three independent causes, all on the critical path:
|
|
8
|
+
- **A doomed token refresh on every launch (~2.6s).** The credential cascade tried the macOS Keychain first and, finding the Cursor CLI's access token expired, POSTed a refresh that could never succeed — the CLI writes the _same expired token_ into `cursor-refresh-token`, so `exchange_user_api_key` answers `Invalid User API Key` — before falling through to the Cursor IDE database, which resolved in 2ms. Both system sources are now read concurrently and every locally stored token is checked before any network exchange, so a valid token is never two milliseconds away behind a failing one. Resolution: **2762ms → 214ms**.
|
|
9
|
+
- **Blocking model discovery (~4s).** `await discoverStartupModels()` ran two unary RPCs before the provider was registered at all. Discovery moved to pi's `refreshModels(context)` hook, which pi calls in the background and again whenever `/model` is opened; `allowNetwork:false` and aborted signals return the current rows without touching the network.
|
|
10
|
+
- **Nothing survived the process.** The model cache was in-memory with a 5-minute TTL, so every new pi process re-paid full discovery. The catalog is now persisted to disk and read synchronously at startup.
|
|
11
|
+
- v1.3.4 added the startup `await` specifically so the full live catalog (Grok, Luna, Kimi) was registered upfront. That still holds — the persisted catalog means launches register the real discovered list (147 models here), not the bundled fallback — but it no longer costs a blocking round-trip.
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- **Persistent model catalog cache** (`src/stream/model-cache.ts`) at `$XDG_CACHE_HOME/pi-cursor` (override with `PI_CURSOR_CACHE_DIR`). Stores the raw Cursor model shapes rather than pi `ModelConfig` rows, because the effort/max-mode routing `streamSimple` depends on does not survive that conversion. Version-stamped, 30-day max age, and tolerant of a corrupt or unwritable cache.
|
|
16
|
+
- **Refresh back-off** (`src/auth/refresh-guard.ts`). A refresh token that fails is remembered for 10 minutes and not retried, so a permanently-stale Cursor CLI keychain entry costs nothing on subsequent launches. The back-off is disk-backed and survives restarts; only a SHA-256 prefix is stored, never the token.
|
|
17
|
+
- **In-process HTTP/2 for unary RPCs** (`src/client/h2-unary.ts`). Model discovery no longer spawns a child process per call, saving ~1.5s of local overhead across the two RPCs. The h2-bridge subprocess still carries the bidirectional chat stream, where Bun's `node:http2` is unusable, and remains the automatic fallback if the in-process client fails. Force the old path with `PI_CURSOR_UNARY_BRIDGE=1`.
|
|
18
|
+
- `/cursor.doctor` reports `catalogCache`, `catalogCacheDir`, and `unaryTransport`.
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
|
|
22
|
+
- `PI_OFFLINE` now skips live model discovery entirely rather than only skipping it at startup.
|
|
23
|
+
- `tokenSource` starts as `none` and fills in on the first stream or background refresh, since activation no longer resolves a credential. A `/cursor.doctor` run in the first second of a session may show `tokenSource=none`.
|
|
24
|
+
|
|
3
25
|
## [1.3.2] - 2026-07-26
|
|
4
26
|
|
|
5
27
|
### Fixed
|
package/README.md
CHANGED
|
@@ -150,7 +150,9 @@ Pi Coding Agent → streamSimple (cursor-native)
|
|
|
150
150
|
| `PI_CURSOR_PROVIDER_DEBUG` | Enable verbose JSONL debug logging. |
|
|
151
151
|
| `PI_CURSOR_LIFECYCLE_LOG` | Always-on compact lifecycle log path (default: `$TMPDIR/pi-cursor-lifecycle.jsonl`). |
|
|
152
152
|
| `CURSOR_USAGE_SESSION_TOKEN` | Optional `WorkosCursorSessionToken` fallback cookie for `/cursor.usage`. |
|
|
153
|
-
| `PI_OFFLINE` | Skip live model discovery
|
|
153
|
+
| `PI_OFFLINE` | Skip live model discovery entirely; always use the bundled fallback catalog. |
|
|
154
|
+
| `PI_CURSOR_CACHE_DIR` | Where the model catalog and refresh back-off are cached (default: `$XDG_CACHE_HOME/pi-cursor` or `~/.cache/pi-cursor`). Delete it to force a full rediscovery. |
|
|
155
|
+
| `PI_CURSOR_UNARY_BRIDGE` | `1` forces unary RPCs (model discovery) through the h2-bridge subprocess instead of the in-process HTTP/2 client. Diagnostic escape hatch. |
|
|
154
156
|
| `PI_CURSOR_STREAM_IDLE_TIMEOUT_MS` | Silence safety net: ms with **no upstream progress of any kind** before recover/retry/error. **Default `120000` (2 min)**; `0` disables (turns run unbounded). Any server signal resets it and it is paused during tool execution, so long reasoning/tools are unaffected — it only fires on a genuine park. |
|
|
155
157
|
| `PI_CURSOR_RESUME_IDLE_TIMEOUT_MS` | Same silence safety net after tool-result resume. **Default `120000` (2 min)**; `0` disables. |
|
|
156
158
|
| `PI_CURSOR_STREAM_IDLE_MAX_RETRIES` | Auto-recovery attempts after a silence timeout before erroring (skipped once any text/thinking was streamed, to avoid duplicate output). **Default `2`**; `0` disables. |
|
|
@@ -172,6 +174,7 @@ Stream modules are split under `src/stream/`:
|
|
|
172
174
|
| `images.ts` | Image decode + Cursor CLI format and size validation |
|
|
173
175
|
| `model-routing.ts` | Effort suffix / requested model resolution |
|
|
174
176
|
| `model-discovery.ts` | `GetUsableModels` unary RPCs + per-token model cache |
|
|
177
|
+
| `model-cache.ts` | Cross-process catalog cache read synchronously at startup |
|
|
175
178
|
| `context-normalize.ts` | Context-mode side-channel folding |
|
|
176
179
|
| `message-parsing.ts` | Pi/OpenAI message list → Cursor turn structures |
|
|
177
180
|
| `pi-adapter.ts` | Pi context/model types ↔ OpenAI-shaped request, usage accounting |
|
|
@@ -188,6 +191,18 @@ Stream modules are split under `src/stream/`:
|
|
|
188
191
|
Native `streamSimple` is the only chat path. The OpenAI-compatible local proxy that
|
|
189
192
|
used to sit alongside it was removed in favour of a single code path.
|
|
190
193
|
|
|
194
|
+
### Startup
|
|
195
|
+
|
|
196
|
+
Extension activation does no network and no credential lookup. Models are registered
|
|
197
|
+
synchronously from the persisted catalog (`PI_CURSOR_CACHE_DIR`), falling back to the
|
|
198
|
+
catalog bundled in `src/models/catalog.json` on a first-ever launch. Live discovery runs
|
|
199
|
+
through pi's `refreshModels` hook — off the critical path, in the background, and again
|
|
200
|
+
whenever `/model` is opened — then persists its result for the next launch.
|
|
201
|
+
|
|
202
|
+
Unary RPCs (both discovery calls) use an in-process `node:http2` client. The h2-bridge
|
|
203
|
+
subprocess is still used for the bidirectional chat stream, where Bun's `node:http2` is
|
|
204
|
+
unusable, and remains the automatic fallback if the in-process client fails.
|
|
205
|
+
|
|
191
206
|
`src/proto/agent_pb.ts` is a large generated Connect/protobuf surface used by the wire
|
|
192
207
|
layer. Never hand-edit it — regenerate with `npm run proto:gen` (see
|
|
193
208
|
[`proto/README.md`](proto/README.md)) when Cursor changes the agent schema.
|
|
@@ -201,6 +216,8 @@ layer. Never hand-edit it — regenerate with `npm run proto:gen` (see
|
|
|
201
216
|
- **Stuck / dies after a few minutes of work:** v1.2.2 answers all Cursor `InteractionQuery` permission prompts (web search / ask-question / etc.) that previously parked the stream. Inspect `$TMPDIR/pi-cursor-lifecycle.jsonl` for `interaction_query` / `bridge_close` events, and `/cursor.doctor` for `lastStreamEvent`. Full debug: `PI_CURSOR_PROVIDER_DEBUG=1`.
|
|
202
217
|
- **Tool continuation lost:** The provider now prefers full-history rebuild when checkpoints are stale/mismatched. If recovery still skips, `/cursor.doctor` shows `lastRecoverySkipReason`. Retry the turn or start a new chat.
|
|
203
218
|
- **WSL credential detection:** Ensure your Windows user profile folder exists under `/mnt/c/Users/` and is readable from WSL. Disable with `PI_CURSOR_SYSTEM_CREDENTIALS=0` if undesired.
|
|
219
|
+
- **Slow startup:** Activation should be a few milliseconds. `/cursor.doctor` reports `catalogCache` (`none(using bundled fallback)` means every launch is starting cold — check that `catalogCacheDir` is writable) and `unaryTransport`. A stale Cursor CLI keychain entry no longer blocks startup: a refresh token that fails is remembered for 10 minutes so it is not retried on the next launch, and any valid locally stored token is always preferred over a network exchange.
|
|
220
|
+
- **Model list looks stale:** It is the last successfully discovered catalog. Open `/model` to trigger a background refresh, or delete `PI_CURSOR_CACHE_DIR` to force full rediscovery.
|
|
204
221
|
|
|
205
222
|
## Development
|
|
206
223
|
|