Files
pikasTech-unidesk/scripts/agentrun-cli-contract-test.ts
T

109 lines
5.3 KiB
TypeScript

import { readFileSync } from "node:fs";
import { agentRunHelp } from "./src/agentrun";
import { rootHelp } from "./src/help";
function assertCondition(condition: unknown, message: string, detail: unknown = {}): void {
if (!condition) throw new Error(`${message}: ${JSON.stringify(detail)}`);
}
const agentRunUsage = Array.isArray((agentRunHelp() as { usage?: unknown }).usage)
? ((agentRunHelp() as { usage: unknown[] }).usage).map(String)
: [];
assertCondition(
agentRunUsage.some((line) => line.includes("control-plane cleanup-runs --min-age-minutes 30 --limit 200 --dry-run"))
&& agentRunUsage.some((line) => line.includes("control-plane cleanup-runs --min-age-minutes 30 --limit 200 --confirm"))
&& agentRunUsage.some((line) => line.includes("control-plane cleanup-released-pvs --limit 200 --dry-run"))
&& agentRunUsage.some((line) => line.includes("control-plane cleanup-released-pvs --limit 200 --confirm")),
"AgentRun help must expose controlled CI workspace retention commands",
agentRunUsage,
);
assertCondition(
agentRunUsage.some((line) => line.includes("control-plane status --pipeline-run agentrun-v01-ci-<short-sha>"))
&& agentRunUsage.some((line) => line.includes("control-plane status --source-commit <full-sha>")),
"AgentRun help must expose targeted control-plane status drill-down options",
agentRunUsage,
);
assertCondition(
agentRunUsage.some((line) => line.includes("agentrun get tasks --queue commander --limit 20"))
&& agentRunUsage.some((line) => line.includes("agentrun describe task/<taskId>"))
&& agentRunUsage.some((line) => line.includes("agentrun events run/<runId> --after-seq 0 --limit 100"))
&& agentRunUsage.some((line) => line.includes("agentrun logs session/<sessionId> --tail 100")),
"AgentRun help must expose Kubernetes-style resource observation primitives",
agentRunUsage,
);
assertCondition(
!agentRunUsage.some((line) => line.includes("agentrun v01")),
"AgentRun help must hide the v01 lane from user-facing CLI entrypoints",
agentRunUsage,
);
assertCondition(
agentRunUsage.some((line) => line.includes("agentrun result run/<runId> --command <commandId>"))
&& agentRunUsage.some((line) => line.includes("agentrun ack task/<taskId> --reader-id cli"))
&& agentRunUsage.some((line) => line.includes("agentrun cancel task/<taskId> --reason <text> --dry-run"))
&& agentRunUsage.some((line) => line.includes("agentrun create task --aipod Artificer --prompt-stdin"))
&& agentRunUsage.some((line) => line.includes("agentrun apply -f - --dry-run"))
&& agentRunUsage.some((line) => line.includes("agentrun steer session/<sessionId> --prompt-stdin"))
&& agentRunUsage.some((line) => line.includes("agentrun send session/<sessionId> --aipod Artificer --prompt-stdin")),
"AgentRun help must expose resource lifecycle control primitives",
agentRunUsage,
);
assertCondition(
(agentRunHelp() as { output?: unknown }).output === "human by default; use -o json|yaml or --raw for machine/debug output",
"AgentRun help must declare human output as the default and machine output as opt-in",
agentRunHelp(),
);
const globalHelp = JSON.stringify(rootHelp());
assertCondition(
globalHelp.includes("agentrun get|describe|events|logs|result|ack|cancel|create|apply|steer|send"),
"global help must index AgentRun v0.1 entrypoints",
rootHelp(),
);
const agentRunSource = readFileSync("scripts/src/agentrun.ts", "utf8");
const runtimeJsonFallback = "\"node <<'NODE' || printf '{}\\\\n'\"";
assertCondition(
agentRunSource.includes(runtimeJsonFallback)
&& agentRunSource.includes("const sourceCommit = params.find((entry) => entry?.name === 'revision')?.value || null;"),
"AgentRun control-plane status must degrade empty runtime JSON snippets instead of failing the whole status probe",
);
assertCondition(
agentRunSource.includes('type AgentRunBridgeCaptureBackend = "local-backend-core-broker" | "remote-frontend-websocket"')
&& agentRunSource.includes('reason: "runner-environment"')
&& agentRunSource.includes('degradedReason: "capture-backend-unavailable"')
&& agentRunSource.includes('"agentrun-cli-returned-failure"')
&& agentRunSource.includes('failureKind: "bridge-execution-environment"')
&& agentRunSource.includes('key === "nextActions"'),
"AgentRun CLI bridge must use the remote frontend backend in runner/no-Docker environments and classify bridge failures separately",
);
assertCondition(
!agentRunSource.includes('degradedReason: "agentrun-cli-bridge-failed"'),
"AgentRun CLI bridge must not collapse official AgentRun failures into bridge failures",
);
console.log(JSON.stringify({
ok: true,
checks: [
"AgentRun command help exposes cleanup-runs and cleanup-released-pvs",
"AgentRun command help exposes targeted control-plane status drill-down options",
"AgentRun command help exposes resource observation primitives",
"AgentRun command help hides the v01 lane from user-facing CLI entrypoints",
"AgentRun command help exposes resource lifecycle control primitives",
"AgentRun command help declares human output by default",
"global help indexes AgentRun v0.1 entrypoints",
"AgentRun control-plane status degrades empty runtime JSON snippets",
"AgentRun CLI bridge selects remote frontend backend in runner/no-Docker environments",
"AgentRun CLI bridge keeps AgentRun failures distinct from bridge failures",
],
}));