@rahularya01/pi-cursor 1.4.14 → 1.4.16

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
@@ -1,5 +1,23 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.4.16] - 2026-08-16
4
+
5
+ ### Performance
6
+
7
+ - **Eliminated O(n²) frame reassembly on the streaming hot path.** The bridge's stdout reader, the Connect frame parser, and `h2-bridge.mjs`'s stdin reader all re-concatenated the entire buffered backlog on every incoming chunk, which is quadratic in a frame's total size once it arrives split across many small reads (large tool results, images, checkpoints). Replaced with a chunk-array accumulator that only merges what's needed to make progress — up to ~690x faster reassembling a large frame from small chunks in benchmarks.
8
+ - **Cached checkpoint history fingerprinting.** `fingerprintCompletedTurns()` re-serialized and hashed the full completed-turn history from scratch on every call, even though it runs multiple times per turn over overlapping turn arrays. Added a per-turn cache keyed by turn-object identity.
9
+ - **Memoized MCP tool schema slimming.** `buildMcpToolDefinitions()` and the derived MCP tool-name list re-slimmed and re-encoded every tool's schema on every call, even when the underlying tool set was unchanged from the previous turn. Both are now cached by array identity.
10
+
11
+ ## [1.4.15] - 2026-08-15
12
+
13
+ ### Documentation
14
+
15
+ - **README Onboarding & Scannability:** Restructured README to prioritize quick setup and clear usage steps, added a table of contents, and moved detailed environment variable and architectural reference material into collapsible `<details>` blocks.
16
+
17
+ ### Refactored
18
+
19
+ - **Credential Handling & Import Cleanup:** Consolidated credential source definitions into a dedicated `CredentialSource` enum for improved type safety and consistency across auth modules. Streamlined imports, refined system credential policy helpers, and removed unused legacy code.
20
+
3
21
  ## [1.4.14] - 2026-08-15
4
22
 
5
23
  ### Fixed
package/README.md CHANGED
@@ -2,43 +2,83 @@
2
2
 
3
3
  [![npm version](https://img.shields.io/npm/v/@rahularya01/pi-cursor?logo=npm)](https://www.npmjs.com/package/@rahularya01/pi-cursor)
4
4
  [![license](https://img.shields.io/npm/l/@rahularya01/pi-cursor)](LICENSE)
5
-
6
- A Pi Coding Agent provider for **Cursor** models. It adds provider `cursor`, multi-source authentication resolution (macOS Keychain, Cursor IDE, WSL host, environment variables, or PKCE browser OAuth), native Connect/protobuf streaming over HTTP/2, model discovery, thinking effort routing, and visual TUI usage diagnostics—without invoking the Cursor CLI for day-to-day chat.
7
-
8
- > **Unofficial integration.** This project is not affiliated with or endorsed by Cursor / Anysphere. It uses reverse-engineered Wire protocol details shared by community clients (see attributions). Use it only with an account you are authorized to access, and review its source before granting OAuth permissions. Cursor may change wire protocol endpoints or formats at any time.
5
+ [![Sponsor](https://img.shields.io/badge/Sponsor-GitHub-ea4aaa?logo=github)](https://github.com/sponsors/Rahularya01)
6
+
7
+ Use your **Cursor** subscription's models — Composer, Claude, GPT, Grok — inside the **Pi Coding Agent**.
8
+ `pi-cursor` plugs in a `cursor` model provider that talks to Cursor's own backend directly (native
9
+ Connect/protobuf streaming over HTTP/2), so there's no separate API key to buy and no Cursor CLI
10
+ process running in the background for every chat turn. If you're already logged into Cursor's app
11
+ or CLI, it just works — no setup beyond installing the package.
12
+
13
+ > **Unofficial integration.** This project is not affiliated with or endorsed by Cursor / Anysphere. It uses reverse-engineered wire protocol details shared by community clients (see [Attributions](#attributions)). Use it only with an account you are authorized to access, and review its source before granting OAuth permissions. Cursor may change wire protocol endpoints or formats at any time.
14
+
15
+ ## Contents
16
+
17
+ - [Requirements](#requirements)
18
+ - [Install](#install)
19
+ - [Quick start](#quick-start)
20
+ - [Authentication](#authentication-and-resolution-cascade)
21
+ - [Commands](#commands)
22
+ - [Models & reasoning effort](#models-and-reasoning-effort-routing)
23
+ - [Usage dashboard](#usage-quota-and-visual-tui-dashboard)
24
+ - [Troubleshooting](#troubleshooting)
25
+ - [Configuration (advanced)](#configuration)
26
+ - [Architecture (advanced)](#architecture--wire-protocol)
27
+ - [Development](#development)
9
28
 
10
29
  ## Requirements
11
30
 
12
- - Pi Coding Agent and Pi AI version **0.80.0 or later**
13
- - A Cursor account with model access (or Cursor CLI / Cursor IDE logged in on your machine)
14
- - Node.js version **22.0.0 or later** (for native HTTP/2 Connect streaming and SQLite credential resolution)
31
+ | | |
32
+ | --------------------------- | ------------------------------------------------------------------------------------ |
33
+ | **Pi Coding Agent / Pi AI** | version `0.80.0` or later |
34
+ | **Node.js** | version `22.0.0` or later (needed for native HTTP/2 streaming and credential lookup) |
35
+ | **A Cursor account** | with model access — signed in via the Cursor app, Cursor CLI, or browser login below |
15
36
 
16
37
  ## Install
17
38
 
18
- Install from npm:
19
-
20
39
  ```bash
21
40
  pi install npm:@rahularya01/pi-cursor
22
41
  ```
23
42
 
24
- Or install the latest repository version:
43
+ Then **restart Pi** (or run `/reload`) so the new provider is picked up.
44
+
45
+ <details>
46
+ <summary>Other install options</summary>
47
+
48
+ Install the latest code straight from GitHub instead of npm:
25
49
 
26
50
  ```bash
27
51
  pi install git:github.com/Rahularya01/pi-cursor
28
52
  ```
29
53
 
30
- Restart Pi (or run `/reload`) after installation. To update the package later, run `pi update npm:@rahularya01/pi-cursor`.
54
+ To update later:
55
+
56
+ ```bash
57
+ pi update npm:@rahularya01/pi-cursor
58
+ ```
59
+
60
+ </details>
31
61
 
32
62
  ## Quick start
33
63
 
34
- 1. If you are already logged in to Cursor CLI or the Cursor app on your machine, `pi-cursor` auto-detects your credentials. Otherwise, start Pi and run `/login cursor` to sign in via browser.
35
- 2. Select a model, for example:
64
+ 1. **Sign in.** If Cursor's desktop app or CLI (`cursor` / `agent`) is already logged in on this
65
+ machine, `pi-cursor` detects it automatically — skip to step 2. Otherwise, run:
66
+
67
+ ```text
68
+ /login cursor
69
+ ```
70
+
71
+ This opens a browser tab to sign in with your Cursor account.
72
+
73
+ 2. **Pick a model:**
36
74
 
37
75
  ```text
38
76
  /model cursor/composer-2
39
77
  ```
40
78
 
41
- 3. Start working. Use `/cursor.doctor` to verify diagnostics and active authentication source.
79
+ 3. **Start chatting.** If anything looks off, run `/cursor.doctor` it prints which credential
80
+ source is active, the current endpoint, and the last error, and is the first thing to check
81
+ before filing an issue.
42
82
 
43
83
  ## Authentication and resolution cascade
44
84
 
@@ -128,6 +168,9 @@ Usage statistics are fetched directly from Cursor's native Connect period usage
128
168
 
129
169
  ## Architecture & Wire Protocol
130
170
 
171
+ > The rest of this README is reference material for troubleshooting, tuning, and contributing —
172
+ > nothing here is required for day-to-day use.
173
+
131
174
  ```text
132
175
  Pi Coding Agent → streamSimple (cursor-native)
133
176
  → h2-bridge.mjs (Node.js HTTP/2 child process)
@@ -141,6 +184,12 @@ Pi Coding Agent → streamSimple (cursor-native)
141
184
 
142
185
  ## Configuration
143
186
 
187
+ Everything below is optional — `pi-cursor` works out of the box. These environment variables exist
188
+ for tuning timeouts, debugging, and edge-case overrides.
189
+
190
+ <details>
191
+ <summary><strong>Full environment variable reference</strong></summary>
192
+
144
193
  | Variable | Purpose |
145
194
  | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
146
195
  | `PI_CURSOR_AGENT_URL` / `CURSOR_AGENT_URL` | Override agent base URL (default: `https://agentn.us.api5.cursor.sh`). |
@@ -163,8 +212,13 @@ Pi Coding Agent → streamSimple (cursor-native)
163
212
  | `PI_CURSOR_SLIM_TOOLS` | Compact Cursor MCP tool definitions: concise function purpose, no annotation-only parameter prose, full callable schema constraints preserved. **Default on**; set `0`/`false` for verbatim schemas. |
164
213
  | `PI_CURSOR_MIDPAUSE_REBUILD_MAX_AGE_MS` | Max age of mid-pause metadata used for full-history rebuild (default: 15 min). |
165
214
 
215
+ </details>
216
+
166
217
  ## Architecture notes
167
218
 
219
+ <details>
220
+ <summary><strong>Module layout (<code>src/stream/</code>)</strong></summary>
221
+
168
222
  Stream modules are split under `src/stream/`:
169
223
 
170
224
  | Module | Responsibility |
@@ -209,6 +263,8 @@ unusable, and remains the automatic fallback if the in-process client fails.
209
263
  layer. Never hand-edit it — regenerate with `npm run proto:gen` (see
210
264
  [`proto/README.md`](proto/README.md)) when Cursor changes the agent schema.
211
265
 
266
+ </details>
267
+
212
268
  ## Troubleshooting
213
269
 
214
270
  - **`No API provider registered for api: cursor-native`:** Update to the latest `pi-cursor` (`pi update npm:@rahularya01/pi-cursor`) and restart Pi (or `/reload`). This means the Agent tried to stream via Pi's global `streamSimple` dispatcher before the Cursor transport was registered there. Current builds register `cursor-native` on that registry during extension load.
@@ -245,6 +301,10 @@ Wire protocol and authentication patterns adapted from MIT community client line
245
301
 
246
302
  Package structure mirrors [pi-antigravity](https://github.com/Rahularya01/pi-antigravity).
247
303
 
304
+ ## Support the project
305
+
306
+ If `pi-cursor` is useful to you, consider [sponsoring the project on GitHub](https://github.com/sponsors/Rahularya01).
307
+
248
308
  ## License
249
309
 
250
310
  [MIT](LICENSE)
@@ -48,14 +48,21 @@ function connectEndStreamError(code, message) {
48
48
  }
49
49
 
50
50
  // --- Buffered stdin reader ---
51
+ //
52
+ // Chunks are queued in an array and only concatenated once enough bytes have arrived to satisfy
53
+ // a `readExact` call. Concatenating on every `data` event instead (`stdinBuf = Buffer.concat([
54
+ // stdinBuf, chunk])`) is O(n^2) in the message size when a large message arrives split across
55
+ // many small pipe reads, since every partial chunk re-copies everything buffered so far.
51
56
 
52
- let stdinBuf = Buffer.alloc(0);
57
+ let stdinChunks = [];
58
+ let stdinLength = 0;
53
59
  let stdinResolve = null;
54
60
  let stdinEnded = false;
55
61
 
56
62
  process.stdin.on("data", (chunk) => {
57
- stdinBuf = Buffer.concat([stdinBuf, chunk]);
58
- if (stdinBuf.length > MAX_BRIDGE_MESSAGE_BYTES + 4) {
63
+ stdinChunks.push(chunk);
64
+ stdinLength += chunk.length;
65
+ if (stdinLength > MAX_BRIDGE_MESSAGE_BYTES + 4) {
59
66
  process.stderr.write("[h2-bridge] stdin buffer limit exceeded\n");
60
67
  process.exit(1);
61
68
  }
@@ -82,12 +89,16 @@ function waitForData() {
82
89
  }
83
90
 
84
91
  async function readExact(n) {
85
- while (stdinBuf.length < n) {
92
+ while (stdinLength < n) {
86
93
  if (stdinEnded) return null;
87
94
  await waitForData();
88
95
  }
89
- const result = stdinBuf.subarray(0, n);
90
- stdinBuf = stdinBuf.subarray(n);
96
+ if (stdinChunks.length > 1) stdinChunks = [Buffer.concat(stdinChunks, stdinLength)];
97
+ const buf = stdinChunks[0] ?? Buffer.alloc(0);
98
+ const result = buf.subarray(0, n);
99
+ const rest = buf.subarray(n);
100
+ stdinChunks = rest.length > 0 ? [rest] : [];
101
+ stdinLength = rest.length;
91
102
  return Buffer.from(result);
92
103
  }
93
104