Files
diegosouzapw--omniroute/tests/unit/cursor-agent-exec-router.test.ts
2026-07-13 13:39:12 +08:00

220 lines
8.3 KiB
TypeScript

import test from "node:test";
import assert from "node:assert/strict";
import {
decodeExecServerEvent,
iterateConnectFrames,
wrapConnectFrame,
} from "../../open-sse/utils/cursorAgentProtobuf";
// ─── Wire-format helpers (match the encoder's primitives) ──────────────────
//
// We synthesize ExecServerMessage payloads for each variant and assert
// decodeExecServerEvent returns the right kind + extracted fields. This
// validates the decoder against the field-number contract independently of
// the encoder (which runs the same code path in different test files).
function v(n: number): Buffer {
const out: number[] = [];
while (n > 0x7f) {
out.push((n & 0x7f) | 0x80);
n >>>= 7;
}
out.push(n);
return Buffer.from(out);
}
function tag(field: number, wireType: number): Buffer {
return v((field << 3) | wireType);
}
function lenPrefixed(field: number, payload: Buffer): Buffer {
return Buffer.concat([tag(field, 2), v(payload.length), payload]);
}
function varintField(field: number, value: number): Buffer {
return Buffer.concat([tag(field, 0), v(value)]);
}
function stringField(field: number, value: string): Buffer {
return lenPrefixed(field, Buffer.from(value, "utf8"));
}
// AgentServerMessage { exec_server_message (2): ExecServerMessage }
function buildAgentServerMessage(esmInner: Buffer): Buffer {
return lenPrefixed(2, esmInner);
}
// ExecServerMessage { id (1): execMsgId, exec_id (15): execId, <variant>: bytes }
function buildExecServerMessage(
execMsgId: number,
execId: string,
variantField: number,
variantPayload: Buffer
): Buffer {
return Buffer.concat([
varintField(1, execMsgId),
stringField(15, execId),
lenPrefixed(variantField, variantPayload),
]);
}
test("decodeExecServerEvent returns null for unrelated AgentServerMessage", () => {
// text_delta InteractionUpdate, no exec_server_message
const interactionUpdate = lenPrefixed(1, lenPrefixed(1, Buffer.from("hi", "utf8")));
const asm = lenPrefixed(1, interactionUpdate);
assert.equal(decodeExecServerEvent(asm), null);
});
test("decodeExecServerEvent recognizes request_context (field 10)", () => {
const variant = Buffer.alloc(0); // RequestContextArgs has no fields we care about
const esm = buildExecServerMessage(1, "exec-rc", 10, variant);
const asm = buildAgentServerMessage(esm);
const event = decodeExecServerEvent(asm);
assert.deepEqual(event, { kind: "exec_request_context", execMsgId: 1, execId: "exec-rc" });
});
test("decodeExecServerEvent recognizes read_args (field 7) with path", () => {
const variant = stringField(1, "/etc/passwd");
const esm = buildExecServerMessage(2, "exec-r", 7, variant);
const event = decodeExecServerEvent(buildAgentServerMessage(esm));
assert.deepEqual(event, {
kind: "exec_read",
execMsgId: 2,
execId: "exec-r",
path: "/etc/passwd",
});
});
test("decodeExecServerEvent recognizes write_args (field 3)", () => {
const variant = stringField(1, "/tmp/x");
const esm = buildExecServerMessage(3, "exec-w", 3, variant);
const event = decodeExecServerEvent(buildAgentServerMessage(esm));
assert.deepEqual(event, { kind: "exec_write", execMsgId: 3, execId: "exec-w", path: "/tmp/x" });
});
test("decodeExecServerEvent recognizes delete_args (field 4)", () => {
const variant = stringField(1, "/tmp/y");
const esm = buildExecServerMessage(4, "exec-d", 4, variant);
const event = decodeExecServerEvent(buildAgentServerMessage(esm));
assert.deepEqual(event, { kind: "exec_delete", execMsgId: 4, execId: "exec-d", path: "/tmp/y" });
});
test("decodeExecServerEvent recognizes ls_args (field 8)", () => {
const variant = stringField(1, "/home");
const esm = buildExecServerMessage(5, "exec-l", 8, variant);
const event = decodeExecServerEvent(buildAgentServerMessage(esm));
assert.deepEqual(event, { kind: "exec_ls", execMsgId: 5, execId: "exec-l", path: "/home" });
});
test("decodeExecServerEvent recognizes grep_args (field 5)", () => {
const variant = stringField(1, "pattern");
const esm = buildExecServerMessage(6, "exec-g", 5, variant);
const event = decodeExecServerEvent(buildAgentServerMessage(esm));
assert.deepEqual(event, { kind: "exec_grep", execMsgId: 6, execId: "exec-g" });
});
test("decodeExecServerEvent recognizes diagnostics_args (field 9)", () => {
const esm = buildExecServerMessage(7, "exec-diag", 9, Buffer.alloc(0));
const event = decodeExecServerEvent(buildAgentServerMessage(esm));
assert.deepEqual(event, { kind: "exec_diagnostics", execMsgId: 7, execId: "exec-diag" });
});
test("decodeExecServerEvent recognizes shell_args (field 2) with command + working_dir", () => {
const variant = Buffer.concat([stringField(1, "ls -la"), stringField(2, "/tmp")]);
const esm = buildExecServerMessage(8, "exec-s", 2, variant);
const event = decodeExecServerEvent(buildAgentServerMessage(esm));
assert.deepEqual(event, {
kind: "exec_shell",
execMsgId: 8,
execId: "exec-s",
command: "ls -la",
workingDir: "/tmp",
});
});
test("decodeExecServerEvent recognizes shell_stream_args (field 14)", () => {
const variant = Buffer.concat([stringField(1, "tail -f x"), stringField(2, "/var/log")]);
const esm = buildExecServerMessage(9, "exec-ss", 14, variant);
const event = decodeExecServerEvent(buildAgentServerMessage(esm));
assert.deepEqual(event, {
kind: "exec_shell_stream",
execMsgId: 9,
execId: "exec-ss",
command: "tail -f x",
workingDir: "/var/log",
});
});
test("decodeExecServerEvent recognizes background_shell_spawn (field 16)", () => {
const variant = Buffer.concat([stringField(1, "node server"), stringField(2, "/app")]);
const esm = buildExecServerMessage(10, "exec-bg", 16, variant);
const event = decodeExecServerEvent(buildAgentServerMessage(esm));
assert.deepEqual(event, {
kind: "exec_bg_shell",
execMsgId: 10,
execId: "exec-bg",
command: "node server",
workingDir: "/app",
});
});
test("decodeExecServerEvent recognizes fetch_args (field 20) with url", () => {
const variant = stringField(1, "https://example.com/x");
const esm = buildExecServerMessage(11, "exec-f", 20, variant);
const event = decodeExecServerEvent(buildAgentServerMessage(esm));
assert.deepEqual(event, {
kind: "exec_fetch",
execMsgId: 11,
execId: "exec-f",
url: "https://example.com/x",
});
});
test("decodeExecServerEvent recognizes write_shell_stdin_args (field 23)", () => {
const esm = buildExecServerMessage(12, "exec-stdin", 23, Buffer.alloc(0));
const event = decodeExecServerEvent(buildAgentServerMessage(esm));
assert.deepEqual(event, { kind: "exec_write_shell_stdin", execMsgId: 12, execId: "exec-stdin" });
});
test("decodeExecServerEvent recognizes mcp_args (field 11) with name + tool_call_id", () => {
// McpArgs { name (1): "foo", tool_call_id (3): "call_x" }
const variant = Buffer.concat([stringField(1, "get_weather"), stringField(3, "call_abc123")]);
const esm = buildExecServerMessage(13, "exec-mcp", 11, variant);
const event = decodeExecServerEvent(buildAgentServerMessage(esm));
assert.deepEqual(event, {
kind: "exec_mcp",
execMsgId: 13,
execId: "exec-mcp",
toolName: "get_weather",
toolCallId: "call_abc123",
args: {},
});
});
test("decodeExecServerEvent prefers tool_name (field 5) over name (field 1)", () => {
// McpArgs { name: "old", tool_name: "new", tool_call_id: "x" }
const variant = Buffer.concat([
stringField(1, "old_alias"),
stringField(3, "call_y"),
stringField(5, "canonical_name"),
]);
const esm = buildExecServerMessage(14, "exec-mcp2", 11, variant);
const event = decodeExecServerEvent(buildAgentServerMessage(esm));
if (event?.kind !== "exec_mcp") throw new Error("expected exec_mcp");
assert.equal(event.toolName, "canonical_name");
});
// ─── Wire-tap regression: real Connect-RPC frame round-trips ───────────────
test("decodeExecServerEvent works through a Connect-RPC frame", () => {
const variant = stringField(1, "/etc/shadow");
const esm = buildExecServerMessage(99, "exec-real", 7, variant);
const asm = buildAgentServerMessage(esm);
const framed = wrapConnectFrame(asm);
const frames = [...iterateConnectFrames(framed)];
assert.equal(frames.length, 1);
const event = decodeExecServerEvent(frames[0].payload);
assert.deepEqual(event, {
kind: "exec_read",
execMsgId: 99,
execId: "exec-real",
path: "/etc/shadow",
});
});