Files
pikasTech-unidesk/scripts/host-codex-commander-skeleton-contract-test.ts
T
2026-05-23 19:22:07 +08:00

149 lines
7.9 KiB
TypeScript

import { mkdtempSync, readFileSync, rmSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { commanderContract } from "../src/components/microservices/host-codex-commander/src/contract";
import { createCommanderRequestHandler, type RuntimeConfig } from "../src/components/microservices/host-codex-commander/src/index";
import {
buildCommanderApprovalDraft,
commanderApprovalPreview,
commanderHealth,
commanderSessionPreview,
commanderStatePaths,
listCommanderSessions,
readCommanderApproval,
readCommanderSession,
summarizeCommanderTrace,
writeCommanderApproval,
writeCommanderSession,
} from "../src/components/microservices/host-codex-commander/src/state";
type JsonRecord = Record<string, unknown>;
function assertCondition(condition: unknown, message: string, detail: unknown = {}): void {
if (!condition) throw new Error(`${message}: ${JSON.stringify(detail)}`);
}
function asRecord(value: unknown, label: string): JsonRecord {
assertCondition(typeof value === "object" && value !== null && !Array.isArray(value), `${label} must be an object`, value);
return value as JsonRecord;
}
function dataOf(response: JsonRecord): JsonRecord {
return asRecord(response.body, "body");
}
async function readJson(response: Response): Promise<JsonRecord> {
const body = await response.json();
return asRecord(body, "response body");
}
const tmp = mkdtempSync(join(tmpdir(), "host-codex-commander-"));
const runtime: RuntimeConfig = {
rootDir: tmp,
host: "127.0.0.1",
port: 4261,
logFile: join(tmp, "logs", "commander.jsonl"),
serviceId: "host-codex-commander",
stateRoot: tmp,
sessionId: "primary",
};
const handler = createCommanderRequestHandler(runtime);
try {
const contract = commanderContract();
assertCondition(contract.ok === true, "contract must be ok", contract);
assertCondition(contract.serviceId === "host-codex-commander", "contract must expose service id", contract);
assertCondition(contract.daemonImplemented === false, "contract must remain skeleton only", contract);
assertCondition(contract.currentImplementation === "host-codex-commander-skeleton", "contract must identify skeleton implementation", contract);
const session = writeCommanderSession(runtime, {
sessionId: "primary",
state: "running",
promptState: "planned",
approvalState: "draft",
pid: 321,
cwd: "/workspace/unidesk",
lastSeq: 7,
heartbeatAt: "2026-05-21T00:00:00.000Z",
updatedAt: "2026-05-21T00:00:00.000Z",
notes: ["token=ghp_abcdef1234567890", "trace-summary:running"],
});
assertCondition(session.notes[0] === "<redacted>", "session notes must be redacted", session);
assertCondition(readCommanderSession(runtime, "primary").state === "running", "session read must round-trip", readCommanderSession(runtime, "primary"));
assertCondition(listCommanderSessions(runtime).length >= 1, "session listing must include stored session", listCommanderSessions(runtime));
const sessionPreview = asRecord(commanderSessionPreview(session), "session preview");
const sessionPreviewNotes = Array.isArray(sessionPreview.notes) ? sessionPreview.notes.map((item) => String(item)) : [];
assertCondition(sessionPreviewNotes.includes("<redacted>"), "session preview must redact notes", sessionPreview);
const trace = summarizeCommanderTrace({
taskId: "task-123",
sessionId: "primary",
traceJsonl: [
JSON.stringify({ seq: 1, kind: "message", status: "running", summary: "prompt token=ghp_1234567890abcdef" }),
JSON.stringify({ seq: 4, kind: "command", status: "attention_required", command: "ask-for-approval", output: "reason=https://user:secret@example.com" }),
JSON.stringify({ seq: 8, kind: "event", status: "completed", text: "done" }),
].join("\n"),
taskSummary: "task summary token=ghp_aaaaaaaaaaaaaaaa",
});
assertCondition(trace.taskId === "task-123", "trace summary must preserve task id", trace);
assertCondition(trace.lastSeq === 8, "trace summary must preserve last seq", trace);
assertCondition(trace.status === "terminal", "trace summary should reach terminal status", trace);
assertCondition(trace.redactionsApplied >= 2, "trace summary must redact secrets", trace);
assertCondition(trace.taskSummaryPreview?.includes("<redacted>") === true, "task summary preview must redact", trace);
assertCondition(trace.keyEvents.length > 0, "trace summary must include key events", trace);
const approval = buildCommanderApprovalDraft({
approvalId: "draft-1",
action: "code-queue-task-interrupt",
taskId: "task-123",
reason: "token=ghp_1234567890abcdef https://user:secret@example.com",
sessionId: "primary",
});
assertCondition(approval.reason.includes("<redacted>"), "approval reason must redact", approval);
assertCondition(approval.previewMarkdown.includes("<redacted>"), "approval preview must redact", approval);
assertCondition(approval.previewJson["sendImplemented"] === false, "approval preview must not imply sending", approval.previewJson);
writeCommanderApproval(runtime, approval);
assertCondition(readCommanderApproval(runtime, "draft-1").reason.includes("<redacted>"), "approval round-trip must preserve redaction", readCommanderApproval(runtime, "draft-1"));
const health = commanderHealth(runtime, "2026-05-21T00:00:00.000Z");
assertCondition(health.ok === true && health.service === "host-codex-commander", "health must expose service metadata", health);
assertCondition(health.stateRoot === tmp, "health must point at temp state root", health);
const healthBody = await readJson(await handler(new Request("http://localhost/health")));
assertCondition(healthBody.ok === true, "health route must succeed", healthBody);
const contractBody = await readJson(await handler(new Request("http://localhost/api/commander/contract")));
assertCondition(contractBody.serviceId === "host-codex-commander", "HTTP contract route must expose service id", contractBody);
const sessionsBody = await readJson(await handler(new Request("http://localhost/api/commander/sessions")));
assertCondition(Array.isArray(sessionsBody.sessions) && sessionsBody.sessions.length >= 1, "sessions route must list sessions", sessionsBody);
const traceBody = await readJson(await handler(new Request(`http://localhost/api/commander/trace-summary?taskId=task-123&traceJsonl=${encodeURIComponent(JSON.stringify({ seq: 1, status: "running", summary: "hello token=ghp_1234567890abcdef" }))}`)));
assertCondition(traceBody.ok === true && Number(asRecord(traceBody.summary, "summary").redactionsApplied) >= 1, "trace route must redact and summarize", traceBody);
const approvalBody = await readJson(await handler(new Request("http://localhost/api/commander/approvals", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({ action: "code-queue-task-cancel", reason: "cookie=session=secret", taskId: "task-123" }),
})));
assertCondition(approvalBody.ok === true, "approval route must succeed", approvalBody);
assertCondition(String(JSON.stringify(approvalBody)).includes("<redacted>"), "approval route must redact sensitive text", approvalBody);
const statePath = commanderStatePaths(runtime);
assertCondition(readFileSync(statePath.stateFile, "utf8").length > 0, "state file must be written", statePath);
assertCondition(readFileSync(statePath.approvalFile, "utf8").length > 0, "approval file must be written", statePath);
process.stdout.write(`${JSON.stringify({
ok: true,
checks: [
"commander contract exposes skeleton contract boundaries",
"state files round-trip and redact secrets",
"trace summary aggregates mock jsonl input",
"approval draft preview stays preview-only and redacted",
"HTTP handler serves /health, /api/commander/contract, /api/commander/sessions, /api/commander/trace-summary, and /api/commander/approvals",
],
}, null, 2)}\n`);
} finally {
rmSync(tmp, { recursive: true, force: true });
}