@rahularya01/pi-cursor 1.2.2 → 1.3.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 +28 -0
- package/README.md +54 -31
- package/dist/index.js +16 -16
- package/package.json +8 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,33 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.3.0] - 2026-07-24
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- **Wire-drift detection.** Unrecognized `agent.v1` server messages and unknown protobuf fields are no longer skipped silently. They are counted, written to the lifecycle log as `wire_drift`, appended to the failing turn's error message, and listed by `/cursor.doctor` (`lastDriftSignal`, `wireDrift`, `wireDriftStranding` plus a detail block). `wireDriftStranding=yes` distinguishes an unanswered message that could have parked the turn from a merely out-of-date schema — previously both surfaced as a bare idle timeout.
|
|
8
|
+
- **Reproducible protobuf codegen.** `proto/agent.proto` is now vendored as the source of truth for `src/proto/agent_pb.ts`, with `npm run proto:gen` (regenerate), `npm run proto:sync` (recover the `.proto` from an updated generated file — protoc-gen-es embeds the full descriptor), and `npm run proto:check` (fails the build when the two drift apart, and is part of `npm run check`). Uses `buf` + `protoc-gen-es` from devDependencies, so no system `protoc` is required. See [`proto/README.md`](proto/README.md).
|
|
9
|
+
- `npm run smoke:wire` performs the real Connect/HTTP2 handshake against the configured endpoint and reports schema drift without starting a chat turn.
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
|
|
13
|
+
- **`src/stream/native-core.ts` split into focused modules** (5,696 → ~1,650 lines): `types`, `tuning`, `debug-log`, `images`, `model-discovery`, `message-parsing`, `pi-adapter`, `request-build`, `bridge-session`, `session-state`, `server-messages`, `thinking-filter`, and `drift`. The public surface of `src/stream/index.ts` is unchanged.
|
|
14
|
+
- `native-core.ts` is now covered by ESLint and Prettier (it was previously exempted for being too large), which removed a large amount of dead code and unused imports.
|
|
15
|
+
- Shared structural types are declared once in `src/stream/types.ts`; `recovery.ts` and `native-core.ts` previously carried duplicate copies of `ParsedTurn`, `StoredConversation`, and friends.
|
|
16
|
+
|
|
17
|
+
### Removed
|
|
18
|
+
|
|
19
|
+
- **The quarantined OpenAI-compatible local proxy.** `startProxy`/`stopProxy` and the entire parallel request path (`handleChatCompletion`, `writeSSEStream`, `handleToolResultResume`, `handleNonStreamingResponse`, and helpers) are gone — roughly 1,250 lines that were unreachable from the provider. Native `streamSimple` was already the only chat path; `/cursor.doctor` now reports `proxyPath=removed`.
|
|
20
|
+
|
|
21
|
+
## [1.2.3] - 2026-07-24
|
|
22
|
+
|
|
23
|
+
### Fixed
|
|
24
|
+
|
|
25
|
+
- **Permanent hang guard.** A stream that receives no upstream progress of any kind now recovers/retries or ends the turn with a clear error instead of parking forever. Since 1.2.1 disabled the idle watchdog by default, any un-answered exec or silent/dropped upstream left the run "stuck on working" indefinitely (observed: a turn parked ~26 min until manually aborted). The watchdog is re-enabled by default as a **silence** guard: `PI_CURSOR_STREAM_IDLE_TIMEOUT_MS` / `PI_CURSOR_RESUME_IDLE_TIMEOUT_MS` default to `120000` (2 min) and `PI_CURSOR_STREAM_IDLE_MAX_RETRIES` to `2`. Every server signal (text/thinking/token deltas, tool-call events, thinkingCompleted, heartbeat, summary, answered interaction/exec) counts as progress and resets it, and it is paused during tool execution — so long reasoning turns and slow tools are unaffected; it only fires on a genuine park. Set the env vars to `0` to restore the previous unbounded behavior.
|
|
26
|
+
|
|
27
|
+
### Added
|
|
28
|
+
|
|
29
|
+
- `execServerMessage` handling is now recorded in the lifecycle log (`exec_server {execCase, handled}` for non-tool execs) and an unanswered exec sets `lastStreamEvent=exec_unanswered:<case>`. Previously exec messages were invisible in the lifecycle log — the blind spot behind unexplained mid-run stalls.
|
|
30
|
+
|
|
3
31
|
## [1.2.2] - 2026-07-23
|
|
4
32
|
|
|
5
33
|
### Fixed
|
package/README.md
CHANGED
|
@@ -140,46 +140,63 @@ Pi Coding Agent → streamSimple (cursor-native)
|
|
|
140
140
|
|
|
141
141
|
## Configuration
|
|
142
142
|
|
|
143
|
-
| Variable | Purpose
|
|
144
|
-
| ------------------------------------------ |
|
|
145
|
-
| `PI_CURSOR_AGENT_URL` / `CURSOR_AGENT_URL` | Override agent base URL (default: `https://agentn.us.api5.cursor.sh`).
|
|
146
|
-
| `CURSOR_ACCESS_TOKEN` | Static access token override.
|
|
147
|
-
| `PI_CURSOR_CLIENT_VERSION` | Pin `x-cursor-client-version` header sent by the HTTP/2 bridge.
|
|
148
|
-
| `PI_CURSOR_SYSTEM_CREDENTIALS` | `0`/`false` to disable Keychain/IDE credential reuse (default: allow).
|
|
149
|
-
| `PI_CURSOR_RAW_MODELS` | Disable effort-suffix model collapse.
|
|
150
|
-
| `PI_CURSOR_PROVIDER_DEBUG` | Enable verbose JSONL debug logging.
|
|
151
|
-
| `PI_CURSOR_LIFECYCLE_LOG` | Always-on compact lifecycle log path (default: `$TMPDIR/pi-cursor-lifecycle.jsonl`).
|
|
152
|
-
| `CURSOR_USAGE_SESSION_TOKEN` | Optional `WorkosCursorSessionToken` fallback cookie for `/cursor.usage`.
|
|
153
|
-
| `PI_OFFLINE` | Skip live model discovery on startup.
|
|
154
|
-
| `PI_CURSOR_STREAM_IDLE_TIMEOUT_MS` |
|
|
155
|
-
| `PI_CURSOR_RESUME_IDLE_TIMEOUT_MS` |
|
|
156
|
-
| `PI_CURSOR_STREAM_IDLE_MAX_RETRIES` |
|
|
157
|
-
| `PI_CURSOR_ACTIVE_BRIDGE_TTL_MS` | How long a mid-tool bridge stays parked waiting for tool results (default: 1 hour).
|
|
158
|
-
| `PI_CURSOR_H2_CONNECT_TIMEOUT_MS` | h2-bridge initial connect kill (default: `30000`; `0` disables).
|
|
159
|
-
| `PI_CURSOR_H2_IDLE_TIMEOUT_MS` | h2-bridge activity idle kill. **Default `0` (disabled)**. Parent heartbeats reset it when enabled.
|
|
160
|
-
| `PI_CURSOR_MIDPAUSE_REBUILD_MAX_AGE_MS` | Max age of mid-pause metadata used for full-history rebuild (default: 15 min).
|
|
143
|
+
| Variable | Purpose |
|
|
144
|
+
| ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
145
|
+
| `PI_CURSOR_AGENT_URL` / `CURSOR_AGENT_URL` | Override agent base URL (default: `https://agentn.us.api5.cursor.sh`). |
|
|
146
|
+
| `CURSOR_ACCESS_TOKEN` | Static access token override. |
|
|
147
|
+
| `PI_CURSOR_CLIENT_VERSION` | Pin `x-cursor-client-version` header sent by the HTTP/2 bridge. |
|
|
148
|
+
| `PI_CURSOR_SYSTEM_CREDENTIALS` | `0`/`false` to disable Keychain/IDE credential reuse (default: allow). |
|
|
149
|
+
| `PI_CURSOR_RAW_MODELS` | Disable effort-suffix model collapse. |
|
|
150
|
+
| `PI_CURSOR_PROVIDER_DEBUG` | Enable verbose JSONL debug logging. |
|
|
151
|
+
| `PI_CURSOR_LIFECYCLE_LOG` | Always-on compact lifecycle log path (default: `$TMPDIR/pi-cursor-lifecycle.jsonl`). |
|
|
152
|
+
| `CURSOR_USAGE_SESSION_TOKEN` | Optional `WorkosCursorSessionToken` fallback cookie for `/cursor.usage`. |
|
|
153
|
+
| `PI_OFFLINE` | Skip live model discovery on startup. |
|
|
154
|
+
| `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
|
+
| `PI_CURSOR_RESUME_IDLE_TIMEOUT_MS` | Same silence safety net after tool-result resume. **Default `120000` (2 min)**; `0` disables. |
|
|
156
|
+
| `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. |
|
|
157
|
+
| `PI_CURSOR_ACTIVE_BRIDGE_TTL_MS` | How long a mid-tool bridge stays parked waiting for tool results (default: 1 hour). |
|
|
158
|
+
| `PI_CURSOR_H2_CONNECT_TIMEOUT_MS` | h2-bridge initial connect kill (default: `30000`; `0` disables). |
|
|
159
|
+
| `PI_CURSOR_H2_IDLE_TIMEOUT_MS` | h2-bridge activity idle kill. **Default `0` (disabled)**. Parent heartbeats reset it when enabled. |
|
|
160
|
+
| `PI_CURSOR_MIDPAUSE_REBUILD_MAX_AGE_MS` | Max age of mid-pause metadata used for full-history rebuild (default: 15 min). |
|
|
161
161
|
|
|
162
162
|
## Architecture notes
|
|
163
163
|
|
|
164
164
|
Stream modules are split under `src/stream/`:
|
|
165
165
|
|
|
166
|
-
| Module | Responsibility
|
|
167
|
-
| ---------------------- |
|
|
168
|
-
| `
|
|
169
|
-
| `
|
|
170
|
-
| `
|
|
171
|
-
| `
|
|
172
|
-
| `
|
|
173
|
-
| `
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
`
|
|
166
|
+
| Module | Responsibility |
|
|
167
|
+
| ---------------------- | --------------------------------------------------------------------- |
|
|
168
|
+
| `types.ts` | Shared structural types (no runtime code — safe for anyone to import) |
|
|
169
|
+
| `config.ts` | Agent URL + client version resolution |
|
|
170
|
+
| `tuning.ts` | Timeouts, retry budgets, and the stream idle watchdog |
|
|
171
|
+
| `debug-log.ts` | Debug / lifecycle / metric sinks with secret redaction |
|
|
172
|
+
| `images.ts` | Image decode + Cursor CLI format and size validation |
|
|
173
|
+
| `model-routing.ts` | Effort suffix / requested model resolution |
|
|
174
|
+
| `model-discovery.ts` | `GetUsableModels` unary RPCs + per-token model cache |
|
|
175
|
+
| `context-normalize.ts` | Context-mode side-channel folding |
|
|
176
|
+
| `message-parsing.ts` | Pi/OpenAI message list → Cursor turn structures |
|
|
177
|
+
| `pi-adapter.ts` | Pi context/model types ↔ OpenAI-shaped request, usage accounting |
|
|
178
|
+
| `request-build.ts` | `AgentRunRequest` protobuf construction + blob store |
|
|
179
|
+
| `bridge-session.ts` | Active-bridge registry + h2-bridge lifecycle |
|
|
180
|
+
| `session-state.ts` | Conversation store, checkpoints, key derivation, session locks |
|
|
181
|
+
| `server-messages.ts` | Inbound KV / exec / interaction dispatch |
|
|
182
|
+
| `thinking-filter.ts` | Strips inline `<think>`-style tags from the text channel |
|
|
183
|
+
| `recovery.ts` | Tool-continuation recovery planner |
|
|
184
|
+
| `protocol.ts` | Auth/protocol error enhancement |
|
|
185
|
+
| `drift.ts` | Wire-drift detection (unknown message cases and protobuf fields) |
|
|
186
|
+
| `native-core.ts` | Native streamSimple runtime that drives all of the above |
|
|
187
|
+
|
|
188
|
+
Native `streamSimple` is the only chat path. The OpenAI-compatible local proxy that
|
|
189
|
+
used to sit alongside it was removed in favour of a single code path.
|
|
190
|
+
|
|
191
|
+
`src/proto/agent_pb.ts` is a large generated Connect/protobuf surface used by the wire
|
|
192
|
+
layer. Never hand-edit it — regenerate with `npm run proto:gen` (see
|
|
193
|
+
[`proto/README.md`](proto/README.md)) when Cursor changes the agent schema.
|
|
178
194
|
|
|
179
195
|
## Troubleshooting
|
|
180
196
|
|
|
181
197
|
- **Not logged in / 401:** Ensure Cursor CLI or app is logged in, or run `/login cursor` again. Check `/cursor.doctor` to verify your `tokenSource`. Tokens from CLI/IDE are re-resolved when near expiry; idle stream retries also force-refresh credentials.
|
|
182
198
|
- **Empty / hung stream:** Cursor may have updated wire headers; verify network connectivity or bump `PI_CURSOR_CLIENT_VERSION`. `/cursor.doctor` prints the active `clientVersion`.
|
|
199
|
+
- **Wire-protocol drift:** Cursor can change `agent.v1` at any time. Unrecognized server messages and unknown protobuf fields are no longer skipped silently — they are counted, written to the lifecycle log as `wire_drift`, appended to the failing turn's error message, and listed by `/cursor.doctor` under `wireDrift`. `wireDriftStranding=yes` means an unanswered message could have parked the turn, which is the difference between "our schema is a bit behind" and "this is why it hung". Run `CURSOR_ACCESS_TOKEN=... npm run smoke:wire` to check the handshake and schema against the live endpoint without starting a chat turn, then see [`proto/README.md`](proto/README.md) to resync the schema.
|
|
183
200
|
- **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`.
|
|
184
201
|
- **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.
|
|
185
202
|
- **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.
|
|
@@ -191,7 +208,13 @@ npm install
|
|
|
191
208
|
npm run check
|
|
192
209
|
```
|
|
193
210
|
|
|
194
|
-
`npm run check` runs TypeScript typechecking, ESLint, Prettier format verification, security checks, and unit tests.
|
|
211
|
+
`npm run check` runs TypeScript typechecking, ESLint, Prettier format verification, security checks, the protobuf staleness check, and unit tests.
|
|
212
|
+
|
|
213
|
+
| Script | Purpose |
|
|
214
|
+
| --------------------- | --------------------------------------------------------------------------------- |
|
|
215
|
+
| `npm run proto:gen` | Regenerate `src/proto/agent_pb.ts` from `proto/agent.proto`. |
|
|
216
|
+
| `npm run proto:sync` | Rebuild `proto/agent.proto` from an updated generated file obtained upstream. |
|
|
217
|
+
| `npm run proto:check` | Fail if the generated protobuf is stale or hand-edited (part of `npm run check`). |
|
|
195
218
|
|
|
196
219
|
## Attributions
|
|
197
220
|
|