feat(code-queue): add commander tasks view
This commit is contained in:
@@ -0,0 +1,219 @@
|
||||
import { codexTasksQueryForTest } from "./src/code-queue";
|
||||
|
||||
type JsonRecord = Record<string, unknown>;
|
||||
|
||||
function assertCondition(condition: unknown, message: string, detail: JsonRecord = {}): void {
|
||||
if (!condition) throw new Error(`${message}: ${JSON.stringify(detail)}`);
|
||||
}
|
||||
|
||||
function asRecord(value: unknown): JsonRecord {
|
||||
assertCondition(typeof value === "object" && value !== null && !Array.isArray(value), "expected JSON object", { value });
|
||||
return value as JsonRecord;
|
||||
}
|
||||
|
||||
function asArray(value: unknown): unknown[] {
|
||||
assertCondition(Array.isArray(value), "expected JSON array", { value });
|
||||
return value as unknown[];
|
||||
}
|
||||
|
||||
function longText(marker: string, repeat: number): string {
|
||||
return Array.from({ length: repeat }, (_, index) => `${marker}-${index} status evidence command output final response prompt body should stay capped`).join("\n");
|
||||
}
|
||||
|
||||
function task(id: string, status: string, updatedAt: string, prompt: string, readAt: string | null = null, finalText = ""): JsonRecord {
|
||||
return {
|
||||
id,
|
||||
queueId: "default",
|
||||
status,
|
||||
currentAttempt: status === "queued" || status === "retry_wait" ? 0 : 1,
|
||||
updatedAt,
|
||||
finishedAt: status === "succeeded" || status === "failed" || status === "canceled" ? updatedAt : null,
|
||||
readAt,
|
||||
prompt: `${prompt}\n${longText(`raw-prompt-${id}`, 80)}`,
|
||||
basePrompt: `${prompt}\n${longText(`base-prompt-${id}`, 60)}`,
|
||||
displayPrompt: `${prompt}\n${longText(`display-prompt-${id}`, 70)}`,
|
||||
lastAssistantMessage: finalText.length === 0 ? null : {
|
||||
at: updatedAt,
|
||||
seq: 42,
|
||||
source: "finalResponse",
|
||||
text: `${finalText}\n${longText(`assistant-${id}`, 100)}`,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function summaryForTask(taskId: string): JsonRecord {
|
||||
const finalText = taskId === "task-running-risk"
|
||||
? "Blocked by provider auth token timeout and cannot proceed without commander authorization."
|
||||
: taskId === "task-failed-unread"
|
||||
? "CI failed and final response reports missing e2e evidence."
|
||||
: taskId === "task-running-watch"
|
||||
? "Implementation finished but task is still awaiting judge."
|
||||
: "Completed with compact evidence.";
|
||||
return {
|
||||
ok: true,
|
||||
status: 200,
|
||||
body: {
|
||||
ok: true,
|
||||
summary: {
|
||||
id: taskId,
|
||||
queueId: "default",
|
||||
status: taskId.includes("running") ? "running" : taskId.includes("failed") ? "failed" : "succeeded",
|
||||
currentAttempt: 1,
|
||||
maxAttempts: 99,
|
||||
prompt: longText(`summary-prompt-${taskId}`, 90),
|
||||
basePrompt: longText(`summary-base-${taskId}`, 70),
|
||||
lastAssistantMessage: {
|
||||
at: "2026-05-22T00:59:00.000Z",
|
||||
seq: 120,
|
||||
source: "finalResponse",
|
||||
text: `${finalText}\n${longText(`summary-final-${taskId}`, 120)}`,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function noisyCommanderFixture(path: string): JsonRecord {
|
||||
if (path.includes("/summary")) {
|
||||
const taskId = decodeURIComponent(path.split("/api/tasks/")[1]?.split("/")[0] ?? "unknown");
|
||||
return summaryForTask(taskId);
|
||||
}
|
||||
assertCondition(path.startsWith("/api/microservices/code-queue/proxy/api/tasks/overview"), "unexpected path", { path });
|
||||
return {
|
||||
ok: true,
|
||||
status: 200,
|
||||
body: {
|
||||
ok: true,
|
||||
queue: {
|
||||
counts: {
|
||||
running: 12,
|
||||
judging: 2,
|
||||
queued: 18,
|
||||
retry_wait: 4,
|
||||
succeeded: 28,
|
||||
failed: 3,
|
||||
canceled: 1,
|
||||
},
|
||||
unreadTerminal: 8,
|
||||
maxActiveQueues: 15,
|
||||
executionDiagnostics: {
|
||||
now: "2026-05-22T01:00:00.000Z",
|
||||
state: "stale-active",
|
||||
effectiveLiveness: "at-risk",
|
||||
recommendedAction: "investigate-heartbeat-risk",
|
||||
databaseActiveTaskCount: 14,
|
||||
databaseActiveTaskIds: ["task-running-risk", "task-running-watch"],
|
||||
activeHeartbeatCount: 13,
|
||||
heartbeatFreshTaskIds: ["task-running-watch"],
|
||||
heartbeatRiskTaskIds: ["task-running-risk"],
|
||||
heartbeatExpiredTaskIds: ["task-running-risk"],
|
||||
heartbeatMissingTaskIds: [],
|
||||
staleRecoveryCandidateTaskIds: ["task-running-risk"],
|
||||
traceGapTaskIds: ["task-running-risk", "task-running-watch"],
|
||||
reasons: [longText("diagnostic-reason", 30), longText("diagnostic-reason-two", 30)],
|
||||
},
|
||||
},
|
||||
pagination: {
|
||||
limit: 200,
|
||||
returned: 12,
|
||||
total: 68,
|
||||
hasMore: true,
|
||||
nextBeforeId: "task-oldest-page",
|
||||
includeActive: true,
|
||||
},
|
||||
tasks: [
|
||||
task("task-running-risk", "running", "2026-05-22T00:00:00.000Z", "HWLAB#7 backend-core provider token blocker for M3 hardware workbench", null, "Blocked by provider auth token timeout."),
|
||||
task("task-running-watch", "judging", "2026-05-22T00:52:00.000Z", "pikasTech/HWLAB#164 user-facing patch-panel verification", null, "Final response ready while judge is pending."),
|
||||
task("task-failed-unread", "failed", "2026-05-22T00:50:00.000Z", "UniDesk#20 CI e2e evidence gate for commander view", null, "CI failed and needs read closeout."),
|
||||
task("task-succeeded-unread", "succeeded", "2026-05-22T00:49:00.000Z", "pikasTech/HWLAB#317 deployment artifact digest publish evidence", null, "Artifact published."),
|
||||
task("task-canceled-unread", "canceled", "2026-05-22T00:48:00.000Z", "UniDesk#118 diagnostics gate report stale commander loop", null, "Canceled after blocker."),
|
||||
task("task-queued-priority", "queued", "2026-05-22T00:47:00.000Z", "HWLAB#99 business user-facing dashboard fix waiting for runner"),
|
||||
task("task-retry-priority", "retry_wait", "2026-05-22T00:46:00.000Z", "HWLAB#116 infrastructure blocker retry_wait due to github transient"),
|
||||
task("task-recent-read-docs", "succeeded", "2026-05-22T00:45:00.000Z", "docs governance reference update", "2026-05-22T00:45:01.000Z"),
|
||||
task("task-recent-read-business", "succeeded", "2026-05-22T00:44:00.000Z", "business user-facing workbench UI fix", "2026-05-22T00:44:01.000Z"),
|
||||
task("task-recent-read-evidence", "succeeded", "2026-05-22T00:43:00.000Z", "ci e2e evidence smoke report", "2026-05-22T00:43:01.000Z"),
|
||||
task("task-recent-read-artifact", "succeeded", "2026-05-22T00:42:00.000Z", "deployment artifact registry digest", "2026-05-22T00:42:01.000Z"),
|
||||
task("task-recent-read-diagnostic", "succeeded", "2026-05-22T00:41:00.000Z", "diagnostics gate report", "2026-05-22T00:41:01.000Z"),
|
||||
],
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function runCodeQueueCommanderViewContract(): JsonRecord {
|
||||
const commander = codexTasksQueryForTest(["--view", "commander", "--limit", "260"], noisyCommanderFixture);
|
||||
const supervisor = codexTasksQueryForTest(["--view", "supervisor", "--limit", "260"], noisyCommanderFixture);
|
||||
const full = codexTasksQueryForTest(["--view", "full", "--limit", "260"], noisyCommanderFixture);
|
||||
const commanderBody = JSON.stringify(commander);
|
||||
const fullBody = JSON.stringify(full);
|
||||
const commanderView = asRecord(asRecord(commander).commander);
|
||||
const supervisorView = asRecord(asRecord(supervisor).supervisor);
|
||||
const filters = asRecord(commanderView.filters);
|
||||
const activeRunners = asRecord(commanderView.activeRunners);
|
||||
const backlog = asRecord(commanderView.queueBacklog);
|
||||
const terminalUnread = asRecord(commanderView.terminalUnread);
|
||||
const riskCounts = asRecord(commanderView.riskCounts);
|
||||
const attentionCounts = asRecord(riskCounts.attention);
|
||||
const highPriorityIssues = asRecord(commanderView.highPriorityIssues);
|
||||
const classification = asRecord(commanderView.classification);
|
||||
const byCategory = asRecord(classification.byCategory);
|
||||
const commands = asRecord(commanderView.commands);
|
||||
const attention = asRecord(commanderView.attention);
|
||||
const attentionItems = asArray(attention.items).map(asRecord);
|
||||
const sections = asRecord(commanderView.sections);
|
||||
const terminalUnreadSection = asRecord(sections.terminalUnread);
|
||||
const recentCompletedSection = asRecord(sections.recentCompleted);
|
||||
const recentIds = asArray(recentCompletedSection.items).map((item) => String(asRecord(item).id ?? ""));
|
||||
const terminalIds = asArray(terminalUnreadSection.items).map((item) => String(asRecord(item).id ?? ""));
|
||||
const runningRisk = attentionItems.find((item) => item.id === "task-running-risk") ?? {};
|
||||
const failedUnread = attentionItems.find((item) => item.id === "task-failed-unread") ?? {};
|
||||
|
||||
assertCondition(commanderBody.length < 30_000, "commander output should stay under the noisy fixture budget", { chars: commanderBody.length });
|
||||
assertCondition(commanderBody.length < fullBody.length * 0.65, "commander output should stay materially smaller than full output", { commanderChars: commanderBody.length, fullChars: fullBody.length });
|
||||
assertCondition(filters.requestedLimit === 260 && filters.effectiveLimit === 100 && filters.limitCapped === true, "commander view should disclose requested/effective limit cap", filters);
|
||||
assertCondition(activeRunners.count === 14 && activeRunners.exact === true && activeRunners.source === "database-active", "commander view should expose exact active runner count and source/disposition", activeRunners);
|
||||
assertCondition(backlog.queued === 18 && backlog.retryWait === 4 && backlog.total === 22 && backlog.exact === true, "commander view should expose queued/retry_wait exact counts", backlog);
|
||||
assertCondition(terminalUnread.total === 8 && terminalUnread.rowsReturned === 3 && terminalUnread.rowsOmitted === 5 && terminalUnread.exact === true, "commander view should expose terminal unread count plus omitted rows", terminalUnread);
|
||||
assertCondition(attentionCounts.total === 7 && attentionCounts.returned === 7 && attentionCounts.omitted === 0, "commander attention counts should preserve total/returned/omitted", attentionCounts);
|
||||
assertCondition(highPriorityIssues.present === true && highPriorityIssues.matchedCount === 7, "commander should surface tracked high-priority issues", highPriorityIssues);
|
||||
assertCondition(Number(byCategory["business-user-facing"] ?? 0) >= 1
|
||||
&& Number(byCategory["deployment-artifact"] ?? 0) >= 1
|
||||
&& Number(byCategory["ci-e2e-evidence"] ?? 0) >= 1
|
||||
&& Number(byCategory["diagnostics-gate-report"] ?? 0) >= 1
|
||||
&& Number(byCategory["docs-governance"] ?? 0) >= 1
|
||||
&& Number(byCategory["infrastructure-blocker"] ?? 0) >= 1, "deterministic classifier should cover requested categories", byCategory);
|
||||
assertCondition(classification.deterministic === true, "classification metadata should be deterministic", classification);
|
||||
assertCondition(String(commands.refresh ?? "").includes("--view commander"), "commander refresh command should preserve explicit commander view", commands);
|
||||
assertCondition(String(commands.supervisor ?? "").startsWith("bun scripts/cli.ts codex tasks") && !String(commands.supervisor ?? "").includes("--view commander"), "commander should keep supervisor drilldown command", commands);
|
||||
assertCondition(String(commands.full ?? "").includes("--view full"), "commander should keep full drilldown command", commands);
|
||||
assertCondition(String(commands.rawOverview ?? "").includes("microservice proxy code-queue") && String(commands.rawOverview ?? "").includes("--raw"), "commander should expose raw overview drilldown", commands);
|
||||
assertCondition(String(commands.traceTemplate ?? "").includes("codex task <taskId> --trace"), "commander should expose trace drilldown template", commands);
|
||||
assertCondition(String(commands.outputTemplate ?? "").includes("codex output <taskId>"), "commander should expose output drilldown template", commands);
|
||||
assertCondition(asRecord(runningRisk.commands).show === "bun scripts/cli.ts codex task task-running-risk", "attention row should include task drilldown command", runningRisk);
|
||||
assertCondition(asArray(runningRisk.riskSignals).includes("stale-recovery-candidate") && asArray(runningRisk.riskSignals).includes("blocked"), "active risk row should expose stale/blocker signals", runningRisk);
|
||||
assertCondition(asRecord(failedUnread.commands).read === "bun scripts/cli.ts codex read task-failed-unread", "failed unread row should include read command", failedUnread);
|
||||
assertCondition(!commanderBody.includes("raw-prompt-task-running-risk-20"), "commander output should not dump long raw prompt bodies", { chars: commanderBody.length });
|
||||
assertCondition(!commanderBody.includes("summary-final-task-running-risk-20"), "commander output should not dump long final response bodies", { chars: commanderBody.length });
|
||||
assertCondition(!recentIds.some((id) => terminalIds.includes(id)), "recentCompleted section must not duplicate terminalUnread rows", { recentIds, terminalIds });
|
||||
assertCondition(recentIds.length === 3, "recentCompleted commander section should be independently capped", { recentIds });
|
||||
assertCondition(asRecord(supervisorView.completedUnread).count === 3 && asRecord(supervisorView.recentCompleted).count === 5, "supervisor view should remain available and keep separate unread/recent sections", supervisorView);
|
||||
|
||||
return {
|
||||
ok: true,
|
||||
checks: [
|
||||
"commander view is explicit and bounded",
|
||||
"exact active/queued/retry_wait/terminal-unread counts are preserved",
|
||||
"attention rows expose stale, heartbeat, terminal-unread and blocker signals",
|
||||
"high-priority issue refs are surfaced",
|
||||
"deterministic classifier emits requested categories",
|
||||
"drilldown commands are present without prompt/final-response flood",
|
||||
"recent completed does not duplicate terminal unread",
|
||||
"supervisor/full views remain available",
|
||||
],
|
||||
commanderChars: commanderBody.length,
|
||||
fullChars: fullBody.length,
|
||||
};
|
||||
}
|
||||
|
||||
if (import.meta.main) {
|
||||
process.stdout.write(`${JSON.stringify(runCodeQueueCommanderViewContract(), null, 2)}\n`);
|
||||
}
|
||||
Reference in New Issue
Block a user