mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-04 22:32:12 +03:00
refactor(sse): extract cursor protobuf wire primitives into a leaf (#5794)
Split open-sse/utils/cursorAgentProtobuf.ts (1520 -> 1400 LOC) by moving the
low-level protobuf wire-format primitives — varint/tag/length-delimited encode+
decode + the generic field walker (encodeVarint, encodeTag, encodeBytes,
encodeString, encodeMessage, encode{UInt32,Bool,Double}Field, decodeVarint,
checkedLen, decodeFields, findField, decode{String,Varint}Field, the Field type
and the WT_VARINT/WT_LEN wire-type constants) — into cursorAgentProtobuf/wire.ts.
These primitives were module-private, so the host's public API is unchanged; the
host imports them back internally. Bodies are verbatim: the code-line multiset of
host + wire.ts equals the original. First layer of the codec decomposition — the
value/framing codec and the message encoders/decoders build on this and stay in
the host (they share host-retained helpers; splitting them is a separate step).
Adds tests/unit/cursor-protobuf-wire-split.test.ts pinning the leaf surface, the
encode/decode round-trip invariants, the buffer-overrun guard, and the host wiring.
This commit is contained in:
committed by
GitHub
parent
10f00ef274
commit
a00e0acbb7
@@ -18,6 +18,25 @@
|
||||
|
||||
import zlib from "node:zlib";
|
||||
import crypto from "node:crypto";
|
||||
import {
|
||||
WT_VARINT,
|
||||
WT_LEN,
|
||||
encodeVarint,
|
||||
encodeTag,
|
||||
encodeBytes,
|
||||
encodeString,
|
||||
encodeMessage,
|
||||
encodeUInt32Field,
|
||||
encodeBoolField,
|
||||
encodeDoubleField,
|
||||
decodeVarint,
|
||||
checkedLen,
|
||||
decodeFields,
|
||||
findField,
|
||||
decodeStringField,
|
||||
decodeVarintField,
|
||||
type Field,
|
||||
} from "./cursorAgentProtobuf/wire.ts";
|
||||
|
||||
// ─── Field numbers (from agent.proto descriptor) ───────────────────────────
|
||||
|
||||
@@ -225,125 +244,6 @@ const LIST_VALUES = 1; // ListValue.values = repeated Value
|
||||
const MAP_KEY = 1;
|
||||
const MAP_VALUE = 2;
|
||||
|
||||
// ─── Wire-type constants ───────────────────────────────────────────────────
|
||||
|
||||
const WT_VARINT = 0;
|
||||
const WT_LEN = 2;
|
||||
|
||||
// ─── Primitive encoders ────────────────────────────────────────────────────
|
||||
|
||||
function encodeVarint(value: number | bigint): Buffer {
|
||||
let v = typeof value === "bigint" ? value : BigInt(value);
|
||||
const bytes: number[] = [];
|
||||
while (v > 0x7fn) {
|
||||
bytes.push(Number(v & 0x7fn) | 0x80);
|
||||
v >>= 7n;
|
||||
}
|
||||
bytes.push(Number(v));
|
||||
return Buffer.from(bytes);
|
||||
}
|
||||
|
||||
function encodeTag(fieldNumber: number, wireType: number): Buffer {
|
||||
return encodeVarint((fieldNumber << 3) | wireType);
|
||||
}
|
||||
|
||||
function encodeBytes(fieldNumber: number, value: Buffer | Uint8Array): Buffer {
|
||||
const buf = Buffer.isBuffer(value) ? value : Buffer.from(value);
|
||||
return Buffer.concat([encodeTag(fieldNumber, WT_LEN), encodeVarint(buf.length), buf]);
|
||||
}
|
||||
|
||||
function encodeString(fieldNumber: number, value: string): Buffer {
|
||||
return encodeBytes(fieldNumber, Buffer.from(value, "utf8"));
|
||||
}
|
||||
|
||||
function encodeMessage(fieldNumber: number, parts: Buffer[]): Buffer {
|
||||
const inner = Buffer.concat(parts);
|
||||
return Buffer.concat([encodeTag(fieldNumber, WT_LEN), encodeVarint(inner.length), inner]);
|
||||
}
|
||||
|
||||
function encodeUInt32Field(fieldNumber: number, value: number): Buffer {
|
||||
return Buffer.concat([encodeTag(fieldNumber, WT_VARINT), encodeVarint(value)]);
|
||||
}
|
||||
|
||||
function encodeBoolField(fieldNumber: number, value: boolean): Buffer {
|
||||
return Buffer.concat([encodeTag(fieldNumber, WT_VARINT), encodeVarint(value ? 1 : 0)]);
|
||||
}
|
||||
|
||||
function encodeDoubleField(fieldNumber: number, value: number): Buffer {
|
||||
// wire type 1 = 64-bit fixed (double)
|
||||
const buf = Buffer.alloc(8);
|
||||
buf.writeDoubleLE(value, 0);
|
||||
return Buffer.concat([encodeTag(fieldNumber, 1), buf]);
|
||||
}
|
||||
|
||||
// ─── Primitive decoders ────────────────────────────────────────────────────
|
||||
|
||||
function decodeVarint(buf: Buffer, offset: number): [bigint, number] {
|
||||
let result = 0n;
|
||||
let shift = 0n;
|
||||
let pos = offset;
|
||||
while (pos < buf.length) {
|
||||
const byte = buf[pos++];
|
||||
result |= BigInt(byte & 0x7f) << shift;
|
||||
if ((byte & 0x80) === 0) return [result, pos];
|
||||
shift += 7n;
|
||||
}
|
||||
throw new Error("varint truncated");
|
||||
}
|
||||
|
||||
type Field =
|
||||
| { fieldNumber: number; wireType: 0; varint: bigint }
|
||||
| { fieldNumber: number; wireType: 2; bytes: Buffer };
|
||||
|
||||
/**
|
||||
* Validate a length-delimited field's declared length against the bytes that
|
||||
* actually remain in the buffer. Cursor's frames are well-formed, but a
|
||||
* corrupted or hostile upstream could declare a length that overruns the
|
||||
* buffer; without this guard `Buffer.subarray` silently clamps to EOF and a
|
||||
* truncated tool argument (or any nested message) is decoded as empty/partial
|
||||
* data instead of being recognized as malformed. Throwing lets the caller —
|
||||
* `processFrame`, wrapped in driveH2's per-frame try/catch — skip the bad
|
||||
* frame rather than act on corrupted fields. Also rejects absurd lengths that
|
||||
* would not fit a JS safe integer.
|
||||
*/
|
||||
function checkedLen(len: bigint, pos: number, buf: Buffer): number {
|
||||
if (len < 0n || len > BigInt(buf.length - pos)) {
|
||||
throw new Error(
|
||||
`length-delimited field overruns buffer (len=${len}, remaining=${buf.length - pos})`
|
||||
);
|
||||
}
|
||||
return Number(len);
|
||||
}
|
||||
|
||||
function decodeFields(buf: Buffer): Field[] {
|
||||
const fields: Field[] = [];
|
||||
let pos = 0;
|
||||
while (pos < buf.length) {
|
||||
const [tag, np] = decodeVarint(buf, pos);
|
||||
pos = np;
|
||||
const fieldNumber = Number(tag >> 3n);
|
||||
const wireType = Number(tag & 0x7n);
|
||||
if (wireType === WT_VARINT) {
|
||||
const [v, np2] = decodeVarint(buf, pos);
|
||||
pos = np2;
|
||||
fields.push({ fieldNumber, wireType: 0, varint: v });
|
||||
} else if (wireType === WT_LEN) {
|
||||
const [len, np2] = decodeVarint(buf, pos);
|
||||
pos = np2;
|
||||
const lenN = checkedLen(len, pos, buf);
|
||||
fields.push({ fieldNumber, wireType: 2, bytes: buf.subarray(pos, pos + lenN) });
|
||||
pos += lenN;
|
||||
} else if (wireType === 5) {
|
||||
pos += 4;
|
||||
} else if (wireType === 1) {
|
||||
pos += 8;
|
||||
} else {
|
||||
throw new Error(`unsupported wireType ${wireType}`);
|
||||
}
|
||||
}
|
||||
return fields;
|
||||
}
|
||||
|
||||
// ─── Connect-RPC framing ───────────────────────────────────────────────────
|
||||
|
||||
const FLAG_NONE = 0x00;
|
||||
@@ -547,9 +447,7 @@ export function encodeAgentRunRequest(input: AgentRunInput): Buffer {
|
||||
const selectedContextParts: Buffer[] = [];
|
||||
if (input.images && input.images.length > 0) {
|
||||
for (const img of input.images) {
|
||||
selectedContextParts.push(
|
||||
encodeMessage(SC_SELECTED_IMAGES, [encodeSelectedImageBody(img)])
|
||||
);
|
||||
selectedContextParts.push(encodeMessage(SC_SELECTED_IMAGES, [encodeSelectedImageBody(img)]));
|
||||
}
|
||||
}
|
||||
// The empty selected_context placeholder and mode=1 match cursor-agent's
|
||||
@@ -652,24 +550,6 @@ export type DecodedDelta =
|
||||
| { kind: "kv_server_message" }
|
||||
| { kind: "unknown"; field: number };
|
||||
|
||||
function findField(fields: Field[], fieldNumber: number): Field | undefined {
|
||||
return fields.find((f) => f.fieldNumber === fieldNumber);
|
||||
}
|
||||
|
||||
function decodeStringField(buf: Buffer, fieldNumber: number): string {
|
||||
const fields = decodeFields(buf);
|
||||
const f = findField(fields, fieldNumber);
|
||||
if (f && f.wireType === 2) return f.bytes.toString("utf8");
|
||||
return "";
|
||||
}
|
||||
|
||||
function decodeVarintField(buf: Buffer, fieldNumber: number): number {
|
||||
const fields = decodeFields(buf);
|
||||
const f = findField(fields, fieldNumber);
|
||||
if (f && f.wireType === 0) return Number(f.varint);
|
||||
return 0;
|
||||
}
|
||||
|
||||
export function decodeAgentServerMessage(payload: Buffer): DecodedDelta[] {
|
||||
const out: DecodedDelta[] = [];
|
||||
for (const top of decodeFields(payload)) {
|
||||
|
||||
143
open-sse/utils/cursorAgentProtobuf/wire.ts
Normal file
143
open-sse/utils/cursorAgentProtobuf/wire.ts
Normal file
@@ -0,0 +1,143 @@
|
||||
// Low-level protobuf wire-format primitives for the Cursor Agent codec, extracted
|
||||
// verbatim from ../cursorAgentProtobuf.ts (god-file decomposition). Pure and
|
||||
// dependency-free (Buffer only): varint/tag/length-delimited encode+decode and the
|
||||
// generic field walker. Framing, the value codec, and the message encoders/decoders
|
||||
// all build on this layer. Nothing here was part of the module's public API, so the
|
||||
// host imports these back internally (no re-export).
|
||||
|
||||
// ─── Wire-type constants ───────────────────────────────────────────────────
|
||||
|
||||
export const WT_VARINT = 0;
|
||||
export const WT_LEN = 2;
|
||||
|
||||
// ─── Primitive encoders ────────────────────────────────────────────────────
|
||||
|
||||
export function encodeVarint(value: number | bigint): Buffer {
|
||||
let v = typeof value === "bigint" ? value : BigInt(value);
|
||||
const bytes: number[] = [];
|
||||
while (v > 0x7fn) {
|
||||
bytes.push(Number(v & 0x7fn) | 0x80);
|
||||
v >>= 7n;
|
||||
}
|
||||
bytes.push(Number(v));
|
||||
return Buffer.from(bytes);
|
||||
}
|
||||
|
||||
export function encodeTag(fieldNumber: number, wireType: number): Buffer {
|
||||
return encodeVarint((fieldNumber << 3) | wireType);
|
||||
}
|
||||
|
||||
export function encodeBytes(fieldNumber: number, value: Buffer | Uint8Array): Buffer {
|
||||
const buf = Buffer.isBuffer(value) ? value : Buffer.from(value);
|
||||
return Buffer.concat([encodeTag(fieldNumber, WT_LEN), encodeVarint(buf.length), buf]);
|
||||
}
|
||||
|
||||
export function encodeString(fieldNumber: number, value: string): Buffer {
|
||||
return encodeBytes(fieldNumber, Buffer.from(value, "utf8"));
|
||||
}
|
||||
|
||||
export function encodeMessage(fieldNumber: number, parts: Buffer[]): Buffer {
|
||||
const inner = Buffer.concat(parts);
|
||||
return Buffer.concat([encodeTag(fieldNumber, WT_LEN), encodeVarint(inner.length), inner]);
|
||||
}
|
||||
|
||||
export function encodeUInt32Field(fieldNumber: number, value: number): Buffer {
|
||||
return Buffer.concat([encodeTag(fieldNumber, WT_VARINT), encodeVarint(value)]);
|
||||
}
|
||||
|
||||
export function encodeBoolField(fieldNumber: number, value: boolean): Buffer {
|
||||
return Buffer.concat([encodeTag(fieldNumber, WT_VARINT), encodeVarint(value ? 1 : 0)]);
|
||||
}
|
||||
|
||||
export function encodeDoubleField(fieldNumber: number, value: number): Buffer {
|
||||
// wire type 1 = 64-bit fixed (double)
|
||||
const buf = Buffer.alloc(8);
|
||||
buf.writeDoubleLE(value, 0);
|
||||
return Buffer.concat([encodeTag(fieldNumber, 1), buf]);
|
||||
}
|
||||
|
||||
// ─── Primitive decoders ────────────────────────────────────────────────────
|
||||
|
||||
export function decodeVarint(buf: Buffer, offset: number): [bigint, number] {
|
||||
let result = 0n;
|
||||
let shift = 0n;
|
||||
let pos = offset;
|
||||
while (pos < buf.length) {
|
||||
const byte = buf[pos++];
|
||||
result |= BigInt(byte & 0x7f) << shift;
|
||||
if ((byte & 0x80) === 0) return [result, pos];
|
||||
shift += 7n;
|
||||
}
|
||||
throw new Error("varint truncated");
|
||||
}
|
||||
|
||||
export type Field =
|
||||
| { fieldNumber: number; wireType: 0; varint: bigint }
|
||||
| { fieldNumber: number; wireType: 2; bytes: Buffer };
|
||||
|
||||
/**
|
||||
* Validate a length-delimited field's declared length against the bytes that
|
||||
* actually remain in the buffer. Cursor's frames are well-formed, but a
|
||||
* corrupted or hostile upstream could declare a length that overruns the
|
||||
* buffer; without this guard `Buffer.subarray` silently clamps to EOF and a
|
||||
* truncated tool argument (or any nested message) is decoded as empty/partial
|
||||
* data instead of being recognized as malformed. Throwing lets the caller —
|
||||
* `processFrame`, wrapped in driveH2's per-frame try/catch — skip the bad
|
||||
* frame rather than act on corrupted fields. Also rejects absurd lengths that
|
||||
* would not fit a JS safe integer.
|
||||
*/
|
||||
export function checkedLen(len: bigint, pos: number, buf: Buffer): number {
|
||||
if (len < 0n || len > BigInt(buf.length - pos)) {
|
||||
throw new Error(
|
||||
`length-delimited field overruns buffer (len=${len}, remaining=${buf.length - pos})`
|
||||
);
|
||||
}
|
||||
return Number(len);
|
||||
}
|
||||
|
||||
export function decodeFields(buf: Buffer): Field[] {
|
||||
const fields: Field[] = [];
|
||||
let pos = 0;
|
||||
while (pos < buf.length) {
|
||||
const [tag, np] = decodeVarint(buf, pos);
|
||||
pos = np;
|
||||
const fieldNumber = Number(tag >> 3n);
|
||||
const wireType = Number(tag & 0x7n);
|
||||
if (wireType === WT_VARINT) {
|
||||
const [v, np2] = decodeVarint(buf, pos);
|
||||
pos = np2;
|
||||
fields.push({ fieldNumber, wireType: 0, varint: v });
|
||||
} else if (wireType === WT_LEN) {
|
||||
const [len, np2] = decodeVarint(buf, pos);
|
||||
pos = np2;
|
||||
const lenN = checkedLen(len, pos, buf);
|
||||
fields.push({ fieldNumber, wireType: 2, bytes: buf.subarray(pos, pos + lenN) });
|
||||
pos += lenN;
|
||||
} else if (wireType === 5) {
|
||||
pos += 4;
|
||||
} else if (wireType === 1) {
|
||||
pos += 8;
|
||||
} else {
|
||||
throw new Error(`unsupported wireType ${wireType}`);
|
||||
}
|
||||
}
|
||||
return fields;
|
||||
}
|
||||
|
||||
export function findField(fields: Field[], fieldNumber: number): Field | undefined {
|
||||
return fields.find((f) => f.fieldNumber === fieldNumber);
|
||||
}
|
||||
|
||||
export function decodeStringField(buf: Buffer, fieldNumber: number): string {
|
||||
const fields = decodeFields(buf);
|
||||
const f = findField(fields, fieldNumber);
|
||||
if (f && f.wireType === 2) return f.bytes.toString("utf8");
|
||||
return "";
|
||||
}
|
||||
|
||||
export function decodeVarintField(buf: Buffer, fieldNumber: number): number {
|
||||
const fields = decodeFields(buf);
|
||||
const f = findField(fields, fieldNumber);
|
||||
if (f && f.wireType === 0) return Number(f.varint);
|
||||
return 0;
|
||||
}
|
||||
83
tests/unit/cursor-protobuf-wire-split.test.ts
Normal file
83
tests/unit/cursor-protobuf-wire-split.test.ts
Normal file
@@ -0,0 +1,83 @@
|
||||
// Split-guard for the cursorAgentProtobuf wire-primitive extraction (god-file
|
||||
// decomposition): the low-level protobuf wire codec (varint/tag/length-delimited
|
||||
// encode+decode + the generic field walker) moved verbatim from cursorAgentProtobuf.ts
|
||||
// into cursorAgentProtobuf/wire.ts. These primitives were module-private, so the host's
|
||||
// public API is unchanged; the host imports them back internally. The locks pin the
|
||||
// leaf's surface, the encode↔decode round-trip invariants, the overrun guard, and that
|
||||
// the host now imports the wire leaf instead of defining the primitives inline.
|
||||
import { test } from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
|
||||
import * as wire from "../../open-sse/utils/cursorAgentProtobuf/wire.ts";
|
||||
|
||||
test("wire leaf exposes the primitives and wire-type constants", () => {
|
||||
assert.equal(wire.WT_VARINT, 0);
|
||||
assert.equal(wire.WT_LEN, 2);
|
||||
for (const fn of [
|
||||
"encodeVarint",
|
||||
"encodeTag",
|
||||
"encodeBytes",
|
||||
"encodeString",
|
||||
"encodeMessage",
|
||||
"encodeUInt32Field",
|
||||
"encodeBoolField",
|
||||
"encodeDoubleField",
|
||||
"decodeVarint",
|
||||
"checkedLen",
|
||||
"decodeFields",
|
||||
"findField",
|
||||
"decodeStringField",
|
||||
"decodeVarintField",
|
||||
]) {
|
||||
assert.equal(
|
||||
typeof (wire as Record<string, unknown>)[fn],
|
||||
"function",
|
||||
`${fn} must be exported`
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
test("varint round-trips across byte-boundaries and bigints", () => {
|
||||
for (const n of [0, 1, 127, 128, 300, 16384, 2 ** 31]) {
|
||||
const [decoded, next] = wire.decodeVarint(wire.encodeVarint(n), 0);
|
||||
assert.equal(decoded, BigInt(n), `varint ${n}`);
|
||||
assert.equal(next, wire.encodeVarint(n).length);
|
||||
}
|
||||
const big = 9007199254740993n; // > Number.MAX_SAFE_INTEGER
|
||||
assert.equal(wire.decodeVarint(wire.encodeVarint(big), 0)[0], big);
|
||||
});
|
||||
|
||||
test("string / uint32 / bool fields round-trip through decodeFields", () => {
|
||||
assert.equal(wire.decodeStringField(wire.encodeString(1, "héllo"), 1), "héllo");
|
||||
assert.equal(wire.decodeStringField(wire.encodeString(3, ""), 3), "");
|
||||
assert.equal(wire.decodeVarintField(wire.encodeUInt32Field(2, 42), 2), 42);
|
||||
assert.equal(wire.decodeVarintField(wire.encodeBoolField(4, true), 4), 1);
|
||||
assert.equal(wire.decodeVarintField(wire.encodeBoolField(4, false), 4), 0);
|
||||
});
|
||||
|
||||
test("decodeFields tags length-delimited vs varint fields and encodeMessage nests", () => {
|
||||
const nested = wire.encodeMessage(5, [wire.encodeString(1, "x"), wire.encodeUInt32Field(2, 7)]);
|
||||
const [outer] = wire.decodeFields(nested);
|
||||
assert.equal(outer.fieldNumber, 5);
|
||||
assert.equal(outer.wireType, 2);
|
||||
if (outer.wireType === 2) {
|
||||
const inner = wire.decodeFields(outer.bytes);
|
||||
assert.equal(inner.length, 2);
|
||||
assert.equal(wire.decodeStringField(outer.bytes, 1), "x");
|
||||
assert.equal(wire.decodeVarintField(outer.bytes, 2), 7);
|
||||
}
|
||||
});
|
||||
|
||||
test("checkedLen rejects a length that overruns the buffer", () => {
|
||||
assert.throws(() => wire.checkedLen(5n, 0, Buffer.alloc(3)), /overruns buffer/);
|
||||
assert.equal(wire.checkedLen(3n, 0, Buffer.alloc(3)), 3);
|
||||
});
|
||||
|
||||
test("host imports the wire leaf and no longer defines the primitives inline", () => {
|
||||
const host = fs.readFileSync(path.join("open-sse", "utils", "cursorAgentProtobuf.ts"), "utf-8");
|
||||
assert.match(host, /from "\.\/cursorAgentProtobuf\/wire\.ts"/);
|
||||
assert.doesNotMatch(host, /^function encodeVarint\(/m, "encodeVarint must live in the wire leaf");
|
||||
assert.doesNotMatch(host, /^function decodeFields\(/m, "decodeFields must live in the wire leaf");
|
||||
});
|
||||
Reference in New Issue
Block a user