@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 +18 -0
- package/README.md +74 -14
- package/dist/h2-bridge.mjs +17 -6
- package/dist/index.js +25 -25
- package/package.json +5 -1
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
|
[](https://www.npmjs.com/package/@rahularya01/pi-cursor)
|
|
4
4
|
[](LICENSE)
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
[](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
|
-
|
|
13
|
-
|
|
14
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
35
|
-
2.
|
|
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
|
|
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)
|
package/dist/h2-bridge.mjs
CHANGED
|
@@ -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
|
|
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
|
-
|
|
58
|
-
|
|
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 (
|
|
92
|
+
while (stdinLength < n) {
|
|
86
93
|
if (stdinEnded) return null;
|
|
87
94
|
await waitForData();
|
|
88
95
|
}
|
|
89
|
-
|
|
90
|
-
|
|
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
|
|