Files
pikasTech-unidesk/scripts/code-queue-cli-submit-prompt-contract-test.ts
T
2026-06-11 00:41:20 +00:00

167 lines
9.2 KiB
TypeScript

import { spawnSync } from "node:child_process";
import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
import { join } from "node:path";
import { tmpdir } from "node:os";
import { compactSubmitSuccessResponseForTest } from "./src/code-queue";
type JsonRecord = Record<string, unknown>;
function assertCondition(condition: unknown, message: string, detail: unknown = {}): void {
if (!condition) throw new Error(`${message}: ${JSON.stringify(detail)}`);
}
function runCli(args: string[], stdin?: string): { status: number | null; stdout: string; stderr: string; json: JsonRecord | null } {
const result = spawnSync("bun", ["scripts/cli.ts", ...args], {
cwd: process.cwd(),
input: stdin,
encoding: "utf8",
});
const stdout = String(result.stdout || "");
let json: JsonRecord | null = null;
try {
json = JSON.parse(stdout) as JsonRecord;
} catch {
json = null;
}
return {
status: result.status,
stdout,
stderr: String(result.stderr || ""),
json,
};
}
function nestedRecord(value: unknown, path: string[]): JsonRecord {
let current: unknown = value;
for (const key of path) {
assertCondition(current !== null && typeof current === "object" && !Array.isArray(current), "expected object while traversing JSON", { path, key, current });
current = (current as JsonRecord)[key];
}
assertCondition(current !== null && typeof current === "object" && !Array.isArray(current), "expected nested object", { path, current });
return current as JsonRecord;
}
function stringArray(value: unknown): string[] {
return Array.isArray(value) ? value.map((item) => String(item)) : [];
}
function assertLegacyFrozenWrite(result: { status: number | null; stdout: string; stderr: string; json: JsonRecord | null }, command: string): void {
assertCondition(result.status !== 0 && result.json?.ok === false, `${command} should be frozen`, result.json ?? { stdout: result.stdout, stderr: result.stderr });
const data = nestedRecord(result.json?.data, []);
assertCondition(data.ok === false, `${command} frozen payload should be ok=false`, data);
assertCondition(data.frozen === true, `${command} frozen payload should expose frozen=true`, data);
assertCondition(data.mutation === false, `${command} frozen payload should be non-mutating`, data);
assertCondition(data.degradedReason === "legacy-code-queue-frozen", `${command} should use the legacy frozen reason`, data);
assertCondition(data.command === command, `${command} frozen payload should identify the command`, data);
const replacement = nestedRecord(data, ["replacement"]);
assertCondition(String(replacement.queueSubmit || "").includes("agentrun queue submit"), `${command} should point to AgentRun queue submit`, replacement);
assertCondition(String(replacement.sessionsSteer || "").includes("agentrun sessions steer"), `${command} should point to AgentRun sessions steer`, replacement);
const legacy = nestedRecord(data, ["legacy"]);
assertCondition(legacy.noDoubleWrite === true, `${command} should document no double-write`, legacy);
}
function assertDryRunPrompt(response: JsonRecord, expectedText: string): void {
assertCondition(response.ok === true, "submit dry-run should succeed", response);
const data = nestedRecord(response.data, []);
assertCondition(data.dryRun === true, "submit dry-run should expose dryRun=true", data);
const request = nestedRecord(response.data, ["request"]);
const prompt = nestedRecord(request, ["prompt"]);
assertCondition(prompt.text === expectedText, "submit dry-run prompt text mismatch", prompt);
assertCondition(prompt.chars === expectedText.length, "submit dry-run prompt char count mismatch", prompt);
assertCondition(prompt.truncated === false, "submit dry-run prompt must expose the full prompt", prompt);
}
export function runCodeQueueCliSubmitPromptContract(): JsonRecord {
const multilinePrompt = [
"Goal: verify stdin prompt path",
"JSON: {\"quote\":\"'single' and \\\"double\\\"\"}",
"Markdown: `code` | table | value",
"Backslash: C:\\tmp\\prompt",
"",
].join("\n");
const stdin = runCli(["codex", "submit", "--prompt-stdin", "--queue", "prompt-contract", "--dry-run"], multilinePrompt);
assertLegacyFrozenWrite(stdin, "codex submit");
assertCondition(!stdin.stdout.includes(multilinePrompt), "frozen submit must not echo stdin prompt", { stdout: stdin.stdout });
const tmp = mkdtempSync(join(tmpdir(), "unidesk-code-queue-submit-"));
const promptFile = join(tmp, "prompt.md");
const filePrompt = `${multilinePrompt}file prompt tail\n`;
writeFileSync(promptFile, filePrompt, "utf8");
try {
const fromFile = runCli(["codex", "submit", "--prompt-file", promptFile, "--queue", "prompt-contract", "--dry-run"]);
assertLegacyFrozenWrite(fromFile, "codex submit");
assertCondition(!fromFile.stdout.includes("file prompt tail"), "frozen submit must not echo file prompt text", { stdout: fromFile.stdout });
} finally {
rmSync(tmp, { recursive: true, force: true });
}
const positional = runCli(["codex", "submit", "short smoke prompt", "--dry-run"]);
assertLegacyFrozenWrite(positional, "codex submit");
assertCondition(String(positional.json?.command || "").includes("<prompt:redacted>"), "outer command should redact positional submit prompt", positional.json ?? {});
assertCondition(!String(positional.json?.command || "").includes("short smoke prompt"), "outer command must not echo positional submit prompt", positional.json ?? {});
const duplicateSource = runCli(["codex", "submit", "positional", "--prompt-stdin", "--dry-run"], "stdin\n");
assertLegacyFrozenWrite(duplicateSource, "codex submit");
const longSubmittedPrompt = `${multilinePrompt}${"submitted prompt body must not be echoed\n".repeat(80)}`;
const submitSuccess = compactSubmitSuccessResponseForTest({
tasks: [{
id: "codex_submit_success_contract",
queueId: "prompt-contract",
status: "queued",
providerId: "D601",
model: "gpt-5.5",
cwd: "/workspace",
prompt: longSubmittedPrompt,
maxAttempts: 99,
createdAt: "2026-05-22T00:00:00.000Z",
updatedAt: "2026-05-22T00:00:00.000Z",
}],
queue: {
total: 1,
queueCount: 1,
counts: { queued: 1 },
queuedTaskIds: ["codex_submit_success_contract"],
},
}, { ok: true, status: 200 }, { mode: "local-atomic-directory-submit-serialization", acquiredAfterMs: 1, heldMs: 2, throttleMs: 2000 });
const submitSuccessJson = JSON.stringify(submitSuccess);
const submitted = nestedRecord(submitSuccess, ["submitted"]);
assertCondition(submitted.accepted === true, "submit success should confirm accepted write", submitSuccess);
assertCondition((submitted.taskIds as unknown[]).includes("codex_submit_success_contract"), "submit success should expose task id", submitSuccess);
assertCondition(submitSuccessJson.includes("promptOmitted"), "submit success should explicitly mark prompt omitted", submitSuccess);
assertCondition(!submitSuccessJson.includes("submitted prompt body must not be echoed"), "submit success must not echo prompt text", submitSuccess);
assertCondition(!submitSuccessJson.includes("promptPreview"), "submit success must not include promptPreview", submitSuccess);
const help = runCli(["codex", "submit", "--help"]);
assertCondition(help.status === 0 && help.json?.ok === true, "codex submit help should succeed", help.json ?? { stdout: help.stdout });
const data = nestedRecord(help.json?.data, []);
const usage = stringArray(data.usage);
const promptInput = nestedRecord(data, ["promptInput"]);
const recommended = stringArray(promptInput.recommended);
const examples = nestedRecord(data, ["examples"]);
const submitSummary = nestedRecord(data, ["submitSummary"]);
assertCondition(usage.some((line) => line.includes("codex submit # frozen legacy write entry")), "help usage should document frozen legacy submit", { usage });
assertCondition(recommended.includes("--prompt-stdin") && recommended.includes("--prompt-file"), "help should recommend stdin and file prompt sources", promptInput);
assertCondition(String(promptInput.sourceRule || "").includes("Exactly one prompt source"), "help should document exact prompt source rule", promptInput);
assertCondition(String(submitSummary.default || "").includes("legacy-code-queue-frozen"), "help submit summary should document frozen reason", submitSummary);
assertCondition(String(submitSummary.replacement || "").includes("agentrun queue submit"), "help should point new submissions at AgentRun", submitSummary);
assertCondition(String(examples.agentRunSubmit || "").includes("agentrun queue submit"), "help examples should include AgentRun submit", examples);
return {
ok: true,
checks: [
"legacy submit --prompt-stdin is frozen and does not echo prompt text",
"legacy submit --prompt-file is frozen and does not echo prompt text",
"submit positional prompt is redacted from the outer command envelope",
"legacy submit duplicate prompt sources still fail at the frozen boundary",
"submit success confirms write without echoing prompt",
"codex submit help documents frozen legacy submit and AgentRun replacement",
],
};
}
if (import.meta.main) {
process.stdout.write(`${JSON.stringify(runCodeQueueCliSubmitPromptContract(), null, 2)}\n`);
}