@rahularya01/pi-cursor 1.4.15 → 1.4.17
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 +15 -0
- package/dist/h2-bridge.mjs +17 -6
- package/dist/index.js +22 -22
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.4.17] - 2026-08-16
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- **A corrupted/misaligned incoming Connect frame (`Connect message exceeds 67108864 bytes`) no longer fails the turn outright.** This case bypassed the existing transport-loss retry machinery used for every other bridge failure (GOAWAY, connection reset, auth, ...). It's now treated the same way: the bridge is killed and, since the desync is local per-connection state rather than a permanent condition, the turn resumes over a fresh connection via checkpoint/history recovery when possible, falling back to the same error as before only when a retry isn't safe or attempts are exhausted.
|
|
8
|
+
- Added a randomized differential test for the Connect frame reassembly logic (chunk-boundary fragmentation, large frames split across many tiny reads), which also caught and fixed a correctness bug in the chunk accumulator introduced in 1.4.16 — verified byte-for-byte against a reference implementation across many trials.
|
|
9
|
+
|
|
10
|
+
## [1.4.16] - 2026-08-16
|
|
11
|
+
|
|
12
|
+
### Performance
|
|
13
|
+
|
|
14
|
+
- **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.
|
|
15
|
+
- **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.
|
|
16
|
+
- **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.
|
|
17
|
+
|
|
3
18
|
## [1.4.15] - 2026-08-15
|
|
4
19
|
|
|
5
20
|
### Documentation
|
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
|
|