Files
pikasTech-unidesk/scripts/src/code-queue.ts
T
2026-05-23 09:37:14 +00:00

6528 lines
291 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { mkdirSync, readFileSync, rmSync, statSync, writeFileSync } from "node:fs";
import { runCommand } from "./command";
import { type UniDeskConfig, repoRoot, rootPath } from "./config";
import { coreInternalFetch } from "./microservices";
import { previewJson } from "./preview";
import { createSteerId, type SteerDeliveryState } from "../../src/components/microservices/code-queue/src/steer-confirmation";
import {
codeAgentPortForModel,
codeExecutionModes,
codeModelPorts as sharedCodeModelPorts,
defaultCodeModels as sharedDefaultCodeModels,
normalizeCodeExecutionMode,
normalizeRequestedCodeExecutionMode,
opencodeModels as sharedOpencodeModels,
requestedCodeExecutionModeIsRecognized,
} from "../../src/components/microservices/code-queue/src/code-agent/common";
const defaultToolLimit = 3;
const defaultTraceLimit = 80;
const maxTraceLimit = 500;
const defaultOutputLimit = 20;
const defaultOutputPreviewChars = 500;
const maxOutputPreviewChars = 1200;
const defaultTasksLimit = 20;
const defaultQueuesLimit = 8;
const maxTasksLimit = 100;
const tasksOverviewSourceFetchLimit = 200;
const supervisorSectionReturnedLimit = 3;
const supervisorRecentCompletedLimit = 3;
const supervisorPromptPreviewChars = 70;
const supervisorBodyPreviewChars = 70;
const supervisorRecentBodyPreviewChars = 50;
const unreadTriageCountLimit = 12;
const diagnosticsIdPreviewLimit = 3;
const diagnosticsReasonPreviewLimit = 2;
const mutationQueueIdPreviewLimit = 15;
const steerPromptPreviewChars = 320;
const rawCodeQueueOverviewCommand = "bun scripts/cli.ts microservice proxy code-queue /api/tasks/overview?limit=30 --raw --full";
const sandboxLikeExecutionModes = new Set(["full-access", "danger-full-access", "workspace-write", "read-only"]);
const detailAttemptReturnedLimit = 3;
const detailInitialPromptPreviewChars = 1200;
const detailBasePromptPreviewChars = 800;
const detailLastAssistantPreviewChars = 1200;
const minimaxSubmitModel = "minimax-m2.7";
const deepseekSubmitModel = "deepseek-chat";
const gptSubmitModel = "gpt-5.5";
const submitLockWaitMs = 60_000;
const submitLockPollMs = 250;
const submitLockStaleMs = 120_000;
const submitThrottleMs = nonNegativeIntegerEnv("UNIDESK_CODEX_SUBMIT_THROTTLE_MS", 2000);
const defaultSteerRetryAttempts = 2;
const maxSteerRetryAttempts = 3;
const defaultSteerRetryDelayMs = 750;
const maxSteerRetryDelayMs = 5_000;
interface CodexTaskOptions {
detail: boolean;
trace: boolean;
traceLimit: number;
traceMode: "tail" | "after" | "before";
afterSeq: number;
beforeSeq: number | null;
toolLimit: number;
full: boolean;
rawSummary: boolean;
}
interface CodexOutputOptions {
requestedLimit: number;
limit: number;
mode: "tail" | "after" | "before";
afterSeq: number;
beforeSeq: number | null;
fullText: boolean;
maxTextChars: number;
}
interface CodexJudgeOptions {
attempt: number | null;
dryRun: boolean;
includePrompt: boolean;
}
type LiveTestAuthorizationClass = "read-only" | "live-read" | "live-mutating";
type PromptLintSeverity = "info" | "warning" | "block";
type PromptLintDisposition = "ready" | "review" | "needs-authorization";
interface CodexPromptLintOptions {
prompt: string;
}
interface PromptLintSignal {
id: string;
severity: PromptLintSeverity;
matched: boolean;
evidence: string[];
message: string;
}
interface PromptLiveAuthorizationLint {
ok: boolean;
dryRun: true;
mutation: false;
dispatchDisposition: PromptLintDisposition;
declaredClass: LiveTestAuthorizationClass | null;
effectiveClass: LiveTestAuthorizationClass;
requiredClass: LiveTestAuthorizationClass;
defaultedReadOnly: boolean;
liveMutationAuthorized: boolean;
promptShape: {
chars: number;
lines: number;
textEchoed: false;
};
requiredPromptFields: {
devTestClass: {
present: boolean;
value: LiveTestAuthorizationClass | null;
allowedValues: LiveTestAuthorizationClass[];
};
allowedLiveMutation: {
present: boolean;
nonNone: boolean;
requiredWhen: "live-mutating";
};
forbiddenActions: {
present: boolean;
};
closeoutFields: {
present: boolean;
};
};
signals: PromptLintSignal[];
missingOrContradictory: string[];
policy: {
defaultWhenUnclassified: "read-only";
promptLintOnly: true;
accessesLiveService: false;
printsPromptText: false;
reference: string;
};
commands: {
lintFile: string;
submitDryRun: string;
steerDryRun: string;
};
}
interface CodexSubmitOptions {
prompt: string;
queueId: string | undefined;
providerId: string | undefined;
cwd: string | undefined;
model: string | undefined;
reasoningEffort: string | undefined;
executionMode: string | undefined;
maxAttempts: number | undefined;
referenceTaskIds: string[];
dryRun: boolean;
}
type SubmitRoute = "minimax-opencode" | "deepseek-opencode" | "gpt-5.5-codex" | "commander-human-only";
type SubmitRouteSignalSeverity = "info" | "warning" | "block";
interface SubmitRouteSignal {
id: string;
severity: SubmitRouteSignalSeverity;
matched: boolean;
evidence: string[];
message: string;
}
interface SubmitRoutingRecommendation {
route: SubmitRoute;
recommendedRunner: "opencode" | "codex" | "commander";
recommendedModel: string | null;
confidence: "medium" | "high";
reason: string;
signals: SubmitRouteSignal[];
riskControls: {
promptSelfContained: boolean;
issueIsNotOnlySource: boolean;
noProdRestartSecretOrDbWrite: boolean;
noRuntimeCoreOrReleaseWork: boolean;
evidenceRequiredByPrompt: boolean;
mediumComplexityCandidate: boolean;
commanderMustReviewUnread: true;
};
explicitRequest: {
model: string | null;
runner: "opencode" | "codex" | null;
note: string | null;
};
routingPolicy: {
dryRunOnly: true;
doesNotChangeSubmittedPayload: true;
prodMiniMaxAssumedAvailable: false;
prodDeepSeekAssumedAvailable: false;
runtimeAdmissionUnchanged: true;
};
policyContract: {
selectionPrinciples: string[];
concurrency: {
gpt55Routine: number;
gpt55BurstMax: number;
minimaxSimpleMax: number;
deepseekMediumDefault: number;
};
modelTiers: Array<{
model: string;
runner: "opencode" | "codex";
taskRisk: string;
requiredGuards: string[];
}>;
externalProvider429: {
commanderAction: string;
interveneWhen: string[];
};
};
}
interface CodexSteerOptions {
prompt: string;
steerId: string | undefined;
dryRun: boolean;
retryAttempts: number;
retryDelayMs: number;
full: boolean;
raw: boolean;
}
interface CodexSteerConfirmOptions {
steerId: string;
raw: boolean;
}
type CodexSteerFailureReason =
| "backend-core-unreachable"
| "code-queue-microservice-unregistered"
| "proxy-unauthorized"
| "proxy-404"
| "steer-endpoint-404"
| "upstream-runtime-rejected"
| "stable-proxy-failed"
| "invalid-proxy-response";
type CodexSteerAcceptanceStatus = "accepted" | "not_accepted" | "accepted_response_timeout" | "unknown";
interface ClassifiedCodexSteerError {
reason: CodexSteerFailureReason;
scope: "backend-core" | "stable-proxy" | "code-queue-runtime" | "unknown";
status: number | null;
exitCode: number | null;
retryable: boolean;
message: string;
requestPath: string;
stableProxyPath: string;
upstreamBodyPreview: unknown;
rawProxyEquivalent: string;
recommendedCrossChecks: string[];
}
interface CodexSteerAttemptSummary {
attempt: number;
ok: boolean;
durationMs: number;
status: number | null;
exitCode: number | null;
reason: CodexSteerFailureReason | null;
scope: ClassifiedCodexSteerError["scope"] | null;
retryable: boolean;
message: string | null;
deliveryState?: CodexSteerDeliveryState | null;
steerId?: string | null;
}
type CodexSteerDeliveryState = SteerDeliveryState;
interface CompactTaskMutationResponseOptions {
fullPrompt?: boolean;
}
interface CompactSubmitQueueConfirmationOptions {
submittedTasks?: Record<string, unknown>[];
idPreviewLimit?: number;
}
interface CodexTasksOptions {
queueId: string | undefined;
requestedLimit: number;
limit: number;
beforeId: string | undefined;
unreadOnly: boolean;
statusFilter: string[] | null;
view: "supervisor" | "full";
}
type CodexUnreadAction = "summary" | "mark-read";
interface CodexUnreadOptions {
queueId: string | undefined;
requestedLimit: number;
limit: number;
beforeId: string | undefined;
statusFilter: string[] | null;
repoFilter: string | undefined;
issueFilter: string | undefined;
action: CodexUnreadAction;
confirm: boolean;
dryRun: boolean;
}
interface CodexTasksEntry {
taskId: string;
queueId: string | null;
status: string | null;
statusLabel: string | null;
awaitingTerminalJudge?: boolean;
closeoutState?: "awaiting-terminal-or-judge" | "awaiting-judge";
closeoutHint?: string;
finalResponseAt?: unknown;
currentAttempt: number | null;
updatedAt: string | null;
finishedAt: string | null;
readAt: string | null;
unread: boolean;
unreadTerminal: boolean;
promptPreview: Record<string, unknown>;
queuedReason: Record<string, unknown> | null;
lastAssistantMessage: Record<string, unknown> | null;
commands: {
show: string;
trace: string;
output: string;
steer: string;
read: string;
full: string;
detail: string;
};
}
interface SupervisorTextSummary {
text: string;
chars: number;
truncated: boolean;
}
interface SupervisorMessageSummary extends SupervisorTextSummary {
at: unknown;
source: unknown;
}
interface CodexTasksSupervisorEntry {
id: string;
queue: string | null;
status: string | null;
statusLabel?: string;
awaitingTerminalJudge?: boolean;
closeoutState?: "awaiting-terminal-or-judge" | "awaiting-judge";
closeoutHint?: string;
finalResponseAt?: unknown;
attempt: number | null;
updatedAt: string | null;
finishedAt?: string | null;
unreadTerminal?: boolean;
issues: string[];
kind: "direct-progress" | "deployment-fix" | "verification" | "management-noise" | "documentation" | "unknown";
noise?: boolean;
prompt: string;
promptChars: number;
promptTruncated?: boolean;
last?: string;
lastAt?: unknown;
lastChars?: number;
lastTruncated?: boolean;
queuedReason?: Record<string, unknown>;
read?: string;
}
interface CodexTasksSection<T = CodexTasksEntry> {
count: number;
returned: number;
truncated: boolean;
hasMore: boolean;
commands: {
next: string | null;
full: string;
showTemplate?: string;
detailTemplate?: string;
traceTemplate?: string;
outputTemplate?: string;
taskFullTemplate?: string;
readTemplate?: string;
};
items: T[];
}
interface CodexTasksDegraded {
summaryFetchFailedTaskIds: string[];
summaryFetchErrorCount: number;
summaryFetchOmittedTaskCount: number;
reason: string;
}
interface SupervisorStatusCounts {
counts: Record<string, number>;
exact: boolean;
source: "queue-summary-counts" | "overview-page-fallback";
scope: "all-queues" | "queue";
queueId: string | null;
}
interface CodexQueuesOptions {
full: boolean;
limit: number;
offset: number;
page: number;
}
interface CodexPrPreflightOptions {
remote: boolean;
pushDryRun: boolean;
pushDryRunRef: string | undefined;
prCreateDryRun: boolean;
prCreateDryRunHead: string | undefined;
issueNumber: number | null;
full: boolean;
}
interface CodexSkillsSyncOptions {
dryRun: boolean;
full: boolean;
}
type CodeQueuePrPreflightFailureKind = "auth-missing" | "runner-skills-blocker" | "github-transient" | "proxy-gap" | "git-remote-gap" | "control-plane-missing" | "target-stack-not-running";
type CodeQueueObservationGapKind = "runner-local-observation-gap" | "control-plane-observation-gap" | null;
interface CodeQueuePrPreflightTransport {
config?: UniDeskConfig | null;
coreFetch?: CodexResponseFetcher;
remoteMainServerPrPreflight?: (optionArgs: string[], config: UniDeskConfig | null) => unknown;
}
type CodexRequestInit = { method?: string; body?: unknown };
type CodexResponseFetcher = (path: string, init?: CodexRequestInit) => unknown;
type AsyncCodexResponseFetcher = (path: string, init?: CodexRequestInit) => Promise<unknown>;
const codeQueueProxyPrefix = "/api/microservices/code-queue/proxy";
function codeQueueProxyPath(path: string): string {
if (!path.startsWith("/")) throw new Error("Code Queue proxy path must start with /");
return `${codeQueueProxyPrefix}${path}`;
}
function codeQueueProxyEquivalentCommand(targetPath: string, bodyJson: string): string {
return `bun scripts/cli.ts microservice proxy code-queue ${targetPath} --method POST --body-json '${bodyJson}'`;
}
function steerConfirmationPath(taskId: string, steerId: string): string {
return `/api/tasks/${encodeURIComponent(taskId)}/steer-confirmation${queryString({ steerId })}`;
}
function steerConfirmationCommand(taskId: string, steerId: string): string {
return `bun scripts/cli.ts codex steer-confirm ${taskId} --steer-id ${steerId}`;
}
function rawSteerConfirmationCommand(taskId: string, steerId: string): string {
return `bun scripts/cli.ts microservice proxy code-queue ${steerConfirmationPath(taskId, steerId)} --raw`;
}
function nonNegativeIntegerEnv(name: string, fallback: number): number {
const raw = process.env[name];
if (raw === undefined || raw.trim().length === 0) return fallback;
const parsed = Number(raw);
if (!Number.isFinite(parsed) || parsed < 0) return fallback;
return Math.floor(parsed);
}
function sleepSync(ms: number): void {
if (ms <= 0) return;
const buffer = new SharedArrayBuffer(4);
Atomics.wait(new Int32Array(buffer), 0, 0, ms);
}
function acquireSubmitLock(): { lockPath: string; acquiredAfterMs: number; release: () => void } {
const lockRoot = rootPath(".state", "locks");
const lockPath = rootPath(".state", "locks", "codex-submit.lock.d");
mkdirSync(lockRoot, { recursive: true });
const startedAt = Date.now();
while (Date.now() - startedAt <= submitLockWaitMs) {
try {
mkdirSync(lockPath);
writeFileSync(rootPath(".state", "locks", "codex-submit.lock.d", "owner.json"), `${JSON.stringify({
pid: process.pid,
createdAt: new Date().toISOString(),
repoRoot,
}, null, 2)}\n`, "utf8");
let released = false;
return {
lockPath,
acquiredAfterMs: Date.now() - startedAt,
release: () => {
if (released) return;
released = true;
rmSync(lockPath, { recursive: true, force: true });
},
};
} catch (error) {
const code = (error as { code?: string }).code;
if (code !== "EEXIST") throw error;
let stale = false;
try {
stale = Date.now() - statSync(lockPath).mtimeMs > submitLockStaleMs;
} catch {
stale = true;
}
if (stale) {
rmSync(lockPath, { recursive: true, force: true });
continue;
}
sleepSync(submitLockPollMs);
}
}
throw new Error(`codex submit lock timed out after ${submitLockWaitMs}ms: ${lockPath}`);
}
function runWithSubmitLock<T>(operation: () => T): { result: T; lock: Record<string, unknown> } {
const lock = acquireSubmitLock();
const operationStartedAt = Date.now();
try {
sleepSync(submitThrottleMs);
const result = operation();
return {
result,
lock: {
path: lock.lockPath,
acquiredAfterMs: lock.acquiredAfterMs,
heldMs: Date.now() - operationStartedAt,
throttleMs: submitThrottleMs,
staleMs: submitLockStaleMs,
mode: "local-atomic-directory-submit-serialization",
},
};
} finally {
lock.release();
}
}
function requireTaskId(value: string | undefined, command: string): string {
if (value === undefined || value.trim().length === 0) throw new Error(`${command} requires task id`);
return value.trim();
}
function asRecord(value: unknown): Record<string, unknown> | null {
return typeof value === "object" && value !== null && !Array.isArray(value) ? value as Record<string, unknown> : null;
}
function compactObjectFields(record: Record<string, unknown> | null, keys: string[]): Record<string, unknown> | null {
if (record === null) return null;
const selected: Record<string, unknown> = {};
for (const key of keys) {
if (record[key] !== undefined) selected[key] = record[key];
}
return Object.keys(selected).length > 0 ? selected : null;
}
function asArray(value: unknown): unknown[] {
return Array.isArray(value) ? value : [];
}
function asString(value: unknown): string {
return typeof value === "string" ? value : "";
}
function asNumber(value: unknown, fallback = 0): number {
return typeof value === "number" && Number.isFinite(value) ? value : fallback;
}
function finiteNumber(value: unknown): number | null {
return typeof value === "number" && Number.isFinite(value) ? value : null;
}
function asBoolean(value: unknown): boolean {
return value === true || value === 1 || value === "1" || value === "true";
}
function stringList(value: unknown): string[] {
return asArray(value).map((item) => String(item ?? "")).filter((item) => item.length > 0);
}
function textPreview(value: string, maxChars: number): Record<string, unknown> {
const truncated = value.length > maxChars;
return {
text: truncated ? value.slice(0, maxChars) : value,
chars: value.length,
truncated,
omittedChars: truncated ? value.length - maxChars : 0,
};
}
function compactInlinePreview(value: string, maxChars: number): Record<string, unknown> {
return textPreview(value.replace(/\s+/gu, " ").trim(), maxChars);
}
function supervisorTextSummary(value: string, maxChars: number): SupervisorTextSummary {
const compact = value.replace(/\s+/gu, " ").trim();
const truncated = compact.length > maxChars;
return {
text: truncated ? compact.slice(0, maxChars) : compact,
chars: compact.length,
truncated,
};
}
function fmtDuration(ms: unknown): string {
const value = Number(ms);
if (!Number.isFinite(value) || value < 0) return "--";
const totalSeconds = Math.floor(value / 1000);
const minutes = Math.floor(totalSeconds / 60);
const seconds = totalSeconds % 60;
if (minutes > 0) return `${minutes}m ${String(seconds).padStart(2, "0")}s`;
return `${seconds}s`;
}
function upstreamError(response: unknown): string {
const record = asRecord(response);
if (record === null) return String(response);
const body = asRecord(record.body);
const bodyError = body?.error;
if (typeof bodyError === "string") {
const requestId = typeof body?.requestId === "string" ? ` requestId=${body.requestId}` : "";
const providerId = typeof body?.providerId === "string" ? ` providerId=${body.providerId}` : "";
const observationHint = /\b(microservice|proxy|provider|tunnel|k3sctl|adapter|backend-core|offline|unavailable|timed out|timeout)\b/iu.test(bodyError)
? " The stable code-queue proxy failure is observation-path evidence only; from the supervisor or main-server CLI environment, also check `bun scripts/cli.ts codex queues`, `codex tasks`, or `codex task <taskId>` before declaring the work unevaluable or stopped."
: "";
return `${bodyError}${providerId}${requestId}${observationHint}`;
}
if (typeof record.codeQueueObservationNote === "string") {
const commands = Array.isArray(record.recommendedCommands) ? ` recommendedCommands=${JSON.stringify(record.recommendedCommands)}` : "";
return `${record.codeQueueObservationNote}${commands}`;
}
const status = typeof record.status === "number" ? `HTTP ${record.status}` : "upstream request failed";
return `${status}: ${JSON.stringify(response).slice(0, 1200)}`;
}
function parseJsonRecord(text: string): Record<string, unknown> | null {
if (text.trim().length === 0) return null;
try {
const parsed = JSON.parse(text) as unknown;
return asRecord(parsed);
} catch {
return null;
}
}
function unwrapCodexResponse(response: unknown): { upstream: { ok: unknown; status: unknown }; body: Record<string, unknown> } {
const record = asRecord(response);
if (record?.ok !== true) throw new Error(upstreamError(response));
const body = asRecord(record.body);
if (body?.ok !== true) throw new Error(upstreamError(response));
return { upstream: { ok: record.ok, status: record.status }, body };
}
function responseStatus(response: Record<string, unknown> | null): number | null {
const value = response?.status;
return typeof value === "number" && Number.isFinite(value) ? value : null;
}
function responseExitCode(response: Record<string, unknown> | null): number | null {
const value = response?.exitCode ?? response?.commandExitCode;
return typeof value === "number" && Number.isFinite(value) ? value : null;
}
function responseBody(response: Record<string, unknown> | null): Record<string, unknown> | null {
return asRecord(response?.body);
}
function responseErrorMessage(response: Record<string, unknown> | null): string {
const body = responseBody(response);
const bodyError = body?.error;
const providerError = body?.providerError;
if (typeof bodyError === "string" && bodyError.length > 0) {
return typeof providerError === "string" && providerError.length > 0 ? `${bodyError}: ${providerError}` : bodyError;
}
if (typeof response?.codeQueueObservationNote === "string") return response.codeQueueObservationNote;
if (typeof response?.stderrTail === "string" && response.stderrTail.length > 0) return response.stderrTail;
if (typeof response?.commandStderrTail === "string" && response.commandStderrTail.length > 0) return response.commandStderrTail;
return "Code Queue steer request failed";
}
function classifySteerFailure(response: unknown, targetPath: string, stableProxyPath: string, rawProxyEquivalent: string): ClassifiedCodexSteerError {
const record = asRecord(response);
const status = responseStatus(record);
const exitCode = responseExitCode(record);
const body = responseBody(record);
const message = responseErrorMessage(record);
const lowerMessage = message.toLowerCase();
const bodyPath = typeof body?.path === "string" ? body.path : "";
const bodyStage = typeof body?.stage === "string" ? body.stage : "";
const bodyServiceId = typeof body?.serviceId === "string" ? body.serviceId : "";
let reason: CodexSteerFailureReason = "invalid-proxy-response";
let scope: ClassifiedCodexSteerError["scope"] = "unknown";
let retryable = false;
if (record === null || status === null && exitCode !== null) {
reason = "backend-core-unreachable";
scope = "backend-core";
retryable = true;
} else if (status === 401 || status === 403) {
reason = "proxy-unauthorized";
scope = "stable-proxy";
retryable = false;
} else if (status === 404 && /microservice not found: code-queue/u.test(lowerMessage)) {
reason = "code-queue-microservice-unregistered";
scope = "stable-proxy";
retryable = false;
} else if (status === 404 && (lowerMessage === "task not found" || lowerMessage === "not found" || bodyPath === targetPath || bodyServiceId === "code-queue")) {
reason = "steer-endpoint-404";
scope = "code-queue-runtime";
retryable = false;
} else if (status === 404) {
reason = "proxy-404";
scope = "stable-proxy";
retryable = false;
} else if (status === 400 || status === 405 || status === 409 || /active run|steerable|scheduler-only|read-only|prompt is required/u.test(lowerMessage)) {
reason = "upstream-runtime-rejected";
scope = "code-queue-runtime";
retryable = status === 409;
} else if (status === 502 || status === 503 || status === 504 || /proxy|tunnel|provider|k3sctl|adapter|timed out|timeout|unavailable|disconnected/u.test(lowerMessage) || bodyStage.length > 0) {
reason = "stable-proxy-failed";
scope = "stable-proxy";
retryable = true;
}
return {
reason,
scope,
status,
exitCode,
retryable,
message,
requestPath: targetPath,
stableProxyPath,
upstreamBodyPreview: previewJson(body ?? record, { maxDepth: 3, maxArrayItems: 3, maxObjectKeys: 16, maxStringLength: 320 }),
rawProxyEquivalent,
recommendedCrossChecks: [
"bun scripts/cli.ts codex queues",
"bun scripts/cli.ts codex tasks --view supervisor --limit 20",
"bun scripts/cli.ts codex task <taskId>",
"bun scripts/cli.ts microservice health code-queue",
"bun scripts/cli.ts microservice diagnostics code-queue",
],
};
}
function compactSteerFailureDiagnostics(diagnostics: ClassifiedCodexSteerError, includeDetails: boolean): Record<string, unknown> {
return {
reason: diagnostics.reason,
scope: diagnostics.scope,
status: diagnostics.status,
exitCode: diagnostics.exitCode,
retryable: diagnostics.retryable,
message: diagnostics.message,
recommendedCrossChecks: diagnostics.recommendedCrossChecks,
...(includeDetails ? {
upstreamBodyPreview: diagnostics.upstreamBodyPreview,
rawProxyEquivalent: diagnostics.rawProxyEquivalent,
} : {}),
};
}
function compactSteerTraceConfirmation(value: unknown, taskId: string, steerId: string): Record<string, unknown> {
const record = asRecord(value) ?? {};
const confirmation = asRecord(record.confirmation) ?? record;
const trace = asRecord(confirmation.trace);
return {
taskId: asString(confirmation.taskId) || taskId,
steerId: asString(confirmation.steerId) || steerId,
found: confirmation.found === true,
accepted: confirmation.accepted === true,
deliveryState: asString(confirmation.deliveryState) || (confirmation.found === true ? "accepted" : "unknown"),
matchCount: asNumber(confirmation.matchCount, 0),
trace: trace === null ? null : {
seq: trace.seq ?? null,
at: trace.at ?? null,
method: trace.method ?? null,
steerId: trace.steerId ?? steerId,
promptChars: trace.promptChars ?? null,
promptHash: trace.promptHash ?? null,
promptOmitted: true,
source: trace.source ?? null,
},
duplicateSuppressionKey: confirmation.duplicateSuppressionKey ?? steerId,
promptOmitted: true,
};
}
function fetchSteerTraceConfirmation(taskId: string, steerId: string, fetcher: CodexResponseFetcher): Record<string, unknown> {
const response = unwrapCodexResponse(fetcher(codeQueueProxyPath(steerConfirmationPath(taskId, steerId))));
return compactSteerTraceConfirmation(response.body, taskId, steerId);
}
function safeFetchSteerTraceConfirmation(taskId: string, steerId: string, fetcher: CodexResponseFetcher): Record<string, unknown> {
try {
return fetchSteerTraceConfirmation(taskId, steerId, fetcher);
} catch (error) {
return {
taskId,
steerId,
found: false,
accepted: false,
deliveryState: "unknown",
promptOmitted: true,
lookupError: error instanceof Error ? error.message : String(error),
commands: {
retryLookup: steerConfirmationCommand(taskId, steerId),
rawLookup: rawSteerConfirmationCommand(taskId, steerId),
},
};
}
}
function unwrapSteerResponse(response: unknown, targetPath: string, stableProxyPath: string, rawProxyEquivalent: string): { ok: true; upstream: { ok: unknown; status: unknown }; body: Record<string, unknown> } | { ok: false; diagnostics: ClassifiedCodexSteerError; rawResponse: unknown } {
const record = asRecord(response);
const body = responseBody(record);
if (record?.ok === true && body?.ok === true) return { ok: true, upstream: { ok: record.ok, status: record.status }, body };
return { ok: false, diagnostics: classifySteerFailure(response, targetPath, stableProxyPath, rawProxyEquivalent), rawResponse: response };
}
function terminalStatusFromTask(task: Record<string, unknown> | null): string {
const direct = asString(task?.terminalStatus);
if (direct.length > 0) return direct;
const attempts = asArray(task?.attempts).map((item) => asRecord(item)).filter((item): item is Record<string, unknown> => item !== null);
for (let index = attempts.length - 1; index >= 0; index -= 1) {
const status = asString(attempts[index]?.terminalStatus);
if (status.length > 0) return status;
}
return "";
}
function compactTerminalSteerRejection(taskId: string, steerId: string, response: unknown): Record<string, unknown> | null {
const record = asRecord(response);
const body = responseBody(record);
const task = asRecord(body?.task);
const status = asString(task?.status);
if (!isTerminalTaskStatus(status)) return null;
const terminalStatus = terminalStatusFromTask(task);
const lastUpdate = task?.updatedAt ?? task?.finishedAt ?? null;
return {
ok: false,
steer: {
accepted: false,
status: "not_accepted",
deliveryState: "not_accepted",
steerId,
reason: "task-already-terminal",
taskId,
taskStatus: status,
terminalStatus: terminalStatus || null,
lastUpdate,
updatedAt: task?.updatedAt ?? null,
finishedAt: task?.finishedAt ?? null,
retryable: false,
},
message: `task ${taskId} is already terminal (${status}); codex steer only applies to an active running turn`,
commands: {
show: `bun scripts/cli.ts codex task ${taskId}`,
read: `bun scripts/cli.ts codex read ${taskId}`,
followUpSubmit: `bun scripts/cli.ts codex submit --prompt-file <path> --reference-task-id ${taskId}`,
supervisor: `bun scripts/cli.ts codex tasks --view supervisor --limit ${defaultTasksLimit}`,
},
upstream: {
status: responseStatus(record),
error: asString(body?.error) || null,
},
};
}
function attachSteerDisclosure(
result: Record<string, unknown>,
disclosure: { full: boolean; raw: boolean },
response: unknown,
targetPath: string,
stableProxyPath: string,
rawProxyEquivalent: string,
): Record<string, unknown> {
if (!disclosure.full && !disclosure.raw) return result;
const record = asRecord(response);
const body = responseBody(record);
result.disclosure = {
defaultPolicy: "compact rejection; upstream body and raw response are only included with explicit --full or --raw",
full: disclosure.full,
raw: disclosure.raw,
defaultOmitted: ["request", "diagnostics.upstreamBodyPreview", "rawFailure"],
};
if (disclosure.full) {
result.request = {
path: targetPath,
stableProxyPath,
method: "POST",
bodySummary: {
promptOmitted: true,
},
};
result.diagnostics = {
upstreamBodyPreview: previewJson(body ?? record, { maxDepth: 4, maxArrayItems: 8, maxObjectKeys: 24, maxStringLength: 600 }),
rawProxyEquivalent,
};
}
if (disclosure.raw) result.rawFailure = response;
return result;
}
function steerSuccessAttempt(attempt: number, durationMs: number, upstream: { ok: unknown; status: unknown }, steerId?: string, deliveryState: CodexSteerDeliveryState = "accepted"): CodexSteerAttemptSummary {
const status = typeof upstream.status === "number" && Number.isFinite(upstream.status) ? upstream.status : null;
return {
attempt,
ok: true,
durationMs,
status,
exitCode: null,
reason: null,
scope: null,
retryable: false,
message: "steer accepted by Code Queue",
deliveryState,
steerId: steerId ?? null,
};
}
function steerFailureAttempt(attempt: number, durationMs: number, diagnostics: ClassifiedCodexSteerError): CodexSteerAttemptSummary {
return {
attempt,
ok: false,
durationMs,
status: diagnostics.status,
exitCode: diagnostics.exitCode,
reason: diagnostics.reason,
scope: diagnostics.scope,
retryable: diagnostics.retryable,
message: diagnostics.message,
deliveryState: null,
steerId: null,
};
}
function shouldRetrySteerFailure(diagnostics: ClassifiedCodexSteerError, attempt: number, maxAttempts: number): boolean {
if (attempt >= maxAttempts) return false;
return diagnostics.retryable === true && (diagnostics.reason === "stable-proxy-failed" || diagnostics.reason === "backend-core-unreachable");
}
function positiveIntegerOption(args: string[], names: string[], defaultValue: number, maxValue = Number.MAX_SAFE_INTEGER): number {
for (const name of names) {
const index = args.indexOf(name);
if (index === -1) continue;
const raw = args[index + 1];
const value = Number(raw);
if (!Number.isInteger(value) || value <= 0) throw new Error(`${name} must be a positive integer`);
return Math.min(value, maxValue);
}
return defaultValue;
}
function nonNegativeNumberOption(args: string[], names: string[], defaultValue: number): number {
for (const name of names) {
const index = args.indexOf(name);
if (index === -1) continue;
const raw = args[index + 1];
const value = Number(raw);
if (!Number.isFinite(value) || value < 0) throw new Error(`${name} must be a non-negative number`);
return value;
}
return defaultValue;
}
function nonNegativeIntegerOption(args: string[], names: string[], defaultValue: number, maxValue = Number.MAX_SAFE_INTEGER): number {
for (const name of names) {
const index = args.indexOf(name);
if (index === -1) continue;
const raw = args[index + 1];
const value = Number(raw);
if (!Number.isInteger(value) || value < 0) throw new Error(`${name} must be a non-negative integer`);
return Math.min(value, maxValue);
}
return defaultValue;
}
function nullablePositiveNumberOption(args: string[], names: string[]): number | null {
for (const name of names) {
const index = args.indexOf(name);
if (index === -1) continue;
const raw = args[index + 1];
const value = Number(raw);
if (!Number.isFinite(value) || value <= 0) throw new Error(`${name} must be a positive number`);
return value;
}
return null;
}
function hasFlag(args: string[], name: string): boolean {
return args.includes(name);
}
function assertKnownOptions(args: string[], spec: { flags?: string[]; valueOptions?: string[] }, command: string): void {
const flags = new Set(spec.flags ?? []);
const valueOptions = new Set(spec.valueOptions ?? []);
for (let index = 0; index < args.length; index += 1) {
const arg = args[index] ?? "";
if (!arg.startsWith("--")) continue;
if (flags.has(arg)) continue;
if (valueOptions.has(arg)) {
const value = args[index + 1];
if (value === undefined || value.startsWith("--")) throw new Error(`${arg} requires a value`);
index += 1;
continue;
}
throw new Error(`unsupported ${command} option: ${arg}`);
}
}
function textView(text: string, full: boolean, maxChars: number): Record<string, unknown> {
const truncated = !full && text.length > maxChars;
return {
text: truncated ? text.slice(0, maxChars) : text,
chars: text.length,
truncated,
omittedChars: truncated ? text.length - maxChars : 0,
};
}
function compactText(text: unknown, full: boolean, maxChars: number): Record<string, unknown> {
return textView(asString(text), full, maxChars);
}
function compactLastAssistant(value: unknown, full: boolean, maxChars = 4000): Record<string, unknown> {
const record = asRecord(value) ?? {};
return {
at: record.at ?? null,
seq: record.seq ?? null,
source: record.source ?? "none",
...textView(asString(record.text), full, maxChars),
};
}
function compactFinalResponse(value: unknown, full: boolean): Record<string, unknown> {
const record = compactLastAssistant(value, full);
return {
at: record.at,
seq: record.seq,
source: record.source,
text: record.text,
chars: record.chars,
truncated: record.truncated,
omittedChars: record.omittedChars,
};
}
function compactQueuedReason(value: unknown): Record<string, unknown> | null {
const record = asRecord(value);
if (record === null) return null;
return {
code: record.code ?? null,
label: record.label ?? null,
message: textPreview(asString(record.message), 280),
blockerTaskId: record.blockerTaskId ?? null,
blockerQueueId: record.blockerQueueId ?? null,
waitPosition: record.waitPosition ?? null,
activeRunSlotCount: record.activeRunSlotCount ?? null,
maxActiveQueues: record.maxActiveQueues ?? null,
};
}
function normalizeSubmitModel(value: string | null | undefined): string {
const raw = String(value ?? "").trim();
if (raw.length === 0) return raw;
const lower = raw.toLowerCase();
const leaf = lower.includes("/") ? lower.split("/").at(-1) ?? lower : lower;
if (leaf === minimaxSubmitModel || leaf === "m2.7") return minimaxSubmitModel;
if (leaf === deepseekSubmitModel || leaf === "deepseek") return deepseekSubmitModel;
return raw;
}
function submitModelRegistry(models: string[] = sharedDefaultCodeModels): {
codeModels: string[];
codexModels: string[];
opencodeModels: string[];
modelPorts: Record<string, "codex" | "opencode">;
} {
const codeModels = Array.from(new Set(models.map((model) => normalizeSubmitModel(model)).filter(Boolean)));
return {
codeModels,
codexModels: codeModels.filter((model) => codeAgentPortForModel(model) === "codex"),
opencodeModels: sharedOpencodeModels(codeModels),
modelPorts: sharedCodeModelPorts(codeModels),
};
}
function submitRunnerForModel(model: string | null | undefined): "opencode" | "codex" | null {
const normalized = normalizeSubmitModel(model);
if (normalized.length === 0) return null;
return normalized === minimaxSubmitModel || normalized === deepseekSubmitModel ? "opencode" : "codex";
}
function regexEvidence(text: string, patterns: RegExp[], limit = 6): string[] {
const evidence: string[] = [];
for (const pattern of patterns) {
for (const match of text.matchAll(pattern)) {
const value = String(match[0] ?? "").trim().replace(/\s+/gu, " ");
if (value.length > 0 && !evidence.includes(value)) evidence.push(value);
if (evidence.length >= limit) return evidence;
}
}
return evidence;
}
function regexEvidenceWithoutNegatedContext(text: string, patterns: RegExp[], limit = 6): string[] {
const evidence: string[] = [];
for (const pattern of patterns) {
for (const match of text.matchAll(pattern)) {
const index = match.index ?? 0;
const context = text.slice(Math.max(0, index - 36), Math.min(text.length, index + String(match[0] ?? "").length + 36));
if (/(?:禁止|不要|不得|不能|不应|不触碰|不修改|不涉及|不处理|不更改|请勿|严禁|avoid|forbid|forbidden|do not|don't|must not|no\s+)/iu.test(context)) continue;
const value = String(match[0] ?? "").trim().replace(/\s+/gu, " ");
if (value.length > 0 && !evidence.includes(value)) evidence.push(value);
if (evidence.length >= limit) return evidence;
}
}
return evidence;
}
function routeSignal(id: string, severity: SubmitRouteSignalSeverity, evidence: string[], message: string): SubmitRouteSignal {
return { id, severity, matched: evidence.length > 0, evidence, message };
}
function promptLintSignal(id: string, severity: PromptLintSeverity, evidence: string[], message: string): PromptLintSignal {
return { id, severity, matched: evidence.length > 0, evidence, message };
}
function declaredLiveTestClass(prompt: string): LiveTestAuthorizationClass | null {
const patterns: Array<[LiveTestAuthorizationClass, RegExp[]]> = [
["live-mutating", [
/\bDEV\s+test\s+class\s*[:]\s*`?live-mutating`?/iu,
/\blive\s+test\s+class\s*[:]\s*`?live-mutating`?/iu,
/\btest\s+class\s*[:]\s*`?live-mutating`?/iu,
/\bDEV\s+测试(?:授权)?分级\s*[:]\s*`?live-mutating`?/iu,
]],
["live-read", [
/\bDEV\s+test\s+class\s*[:]\s*`?live-read`?/iu,
/\blive\s+test\s+class\s*[:]\s*`?live-read`?/iu,
/\btest\s+class\s*[:]\s*`?live-read`?/iu,
/\bDEV\s+测试(?:授权)?分级\s*[:]\s*`?live-read`?/iu,
]],
["read-only", [
/\bDEV\s+test\s+class\s*[:]\s*`?read-only`?/iu,
/\blive\s+test\s+class\s*[:]\s*`?read-only`?/iu,
/\btest\s+class\s*[:]\s*`?read-only`?/iu,
/\bDEV\s+测试(?:授权)?分级\s*[:]\s*`?read-only`?/iu,
]],
];
for (const [value, valuePatterns] of patterns) {
if (valuePatterns.some((pattern) => pattern.test(prompt))) return value;
}
return null;
}
function liveClassRank(value: LiveTestAuthorizationClass): number {
if (value === "read-only") return 0;
if (value === "live-read") return 1;
return 2;
}
function hasPromptField(prompt: string, patterns: RegExp[]): boolean {
return patterns.some((pattern) => pattern.test(prompt));
}
function sanitizePromptLintEvidence(evidence: string[]): string[] {
return evidence.map((item) => item
.replace(/([?&](?:token|api[_-]?key|secret|password|credential)=)[^&\s]+/giu, "$1<redacted>")
.replace(/((?:token|api[_-]?key|secret|password|credential)\s*[:=]\s*)[^\s,;]+/giu, "$1<redacted>")
.replace(/(Bearer\s+)[A-Za-z0-9._~+/-]+=*/giu, "$1<redacted>")
.slice(0, 160));
}
function buildPromptLiveAuthorizationLint(prompt: string): PromptLiveAuthorizationLint {
const declaredClass = declaredLiveTestClass(prompt);
const effectiveClass = declaredClass ?? "read-only";
const allowedClasses: LiveTestAuthorizationClass[] = ["read-only", "live-read", "live-mutating"];
const liveReadEvidence = sanitizePromptLintEvidence(regexEvidenceWithoutNegatedContext(prompt, [
/\blive[- ]read\b/giu,
/\blive\s+(?:dev\s+)?(?:service|runtime|endpoint|health|status|logs?|metrics?)\b/giu,
/\bGET\s+\/(?:health|status|live|metrics|api\/diagnostics)\b/gu,
/\bkubectl\s+(?:get|describe|logs)\b/giu,
/\bmicroservice\s+(?:health|status|diagnostics)\b/giu,
/\bdiagnostics\b|\bstatus\b|\bmetrics\b|\blogs?\b/giu,
/只读(?:读取|观察|诊断|状态|日志)/gu,
/读取\s*(?:DEV|live|运行中|服务|日志|状态)/giu,
]));
const liveMutationEvidence = sanitizePromptLintEvidence(regexEvidenceWithoutNegatedContext(prompt, [
/\blive-mutating\b/giu,
/\bDEV\s+smoke\b|\blive\s+smoke\b|\bM3\s+smoke\b/giu,
/\bdeploy\s+apply\b|\brollout\s+restart\b|\bkubectl\s+(?:apply|delete|patch|rollout)\b/giu,
/\b(?:POST|PUT|PATCH|DELETE)\s+\/[A-Za-z0-9_./:-]*/gu,
/\bcodex\s+(?:submit|steer|interrupt|cancel)\b/giu,
/\btask\s+(?:submit|steer|retry|trigger)\b/giu,
/\btrigger\s+(?:schedule|job|task|operation|audit|evidence)\b/giu,
/\bschedule\s+(?:run|retry-run|delete)\b/giu,
/\b(?:create|write|post|put|patch)\b[^\n。]{0,40}\b(?:operation|audit|evidence)\b/giu,
/\b(?:operation|audit|evidence)\s+(?:id|record|write|create)\b/giu,
/\bDO\d+\b|\bDI\d+\b|\bres_boxsimu_\d+\b|\bhwlab-patch-panel\b/giu,
/触发|写入|部署|重启|重建|回滚|创建(?:任务|operation|audit|evidence)|硬件|虚拟硬件/gu,
]));
const prodMutationEvidence = sanitizePromptLintEvidence(regexEvidenceWithoutNegatedContext(prompt, [
/\bprod(?:uction)?\b[^\n。]*(?:deploy|restart|write|mutation|mutating|apply|rollout|delete|patch)\b/giu,
/\b(?:deploy|restart|write|mutation|mutating|apply|rollout|delete|patch)\b[^\n。]*\bprod(?:uction)?\b/giu,
/生产[^\n。]*(?:写入|部署|重启|变更|删除|回滚)/gu,
]));
const requiredClass = liveMutationEvidence.length > 0 || prodMutationEvidence.length > 0
? "live-mutating"
: liveReadEvidence.length > 0
? "live-read"
: "read-only";
const allowedLiveMutationPresent = hasPromptField(prompt, [
/\ballowed\s+live\s+mutation\s*[:]/iu,
/允许的\s*live\s*mutation\s*[:]/iu,
/允许的(?:现场|实时|运行态)?(?:写入|变更|mutation)\s*[:]/iu,
]);
const allowedLiveMutationNone = hasPromptField(prompt, [
/\ballowed\s+live\s+mutation\s*[:]\s*(?:`?none`?|无|なし)(?:\s|$|[。.;,])/iu,
/允许的\s*live\s*mutation\s*[:]\s*(?:`?none`?|无|なし)(?:\s|$|[。.;,])/iu,
/允许的(?:现场|实时|运行态)?(?:写入|变更|mutation)\s*[:]\s*(?:`?none`?|无|なし)(?:\s|$|[。.;,])/iu,
]);
const forbiddenActionsPresent = hasPromptField(prompt, [
/\bforbidden\s+actions?\s*[:]/iu,
/禁止动作\s*[:]/u,
/禁止\s*[:]/u,
]);
const closeoutFieldsPresent = hasPromptField(prompt, [
/\bcloseout\s+fields?\s*[:]/iu,
/\bfinal\s+response\b[^\n。]*(?:must|include|report)/iu,
/\b收口字段\s*[:]/u,
/\bfinal\s+response\b[^\n。]*报告/iu,
]);
const effectiveInsufficient = liveClassRank(effectiveClass) < liveClassRank(requiredClass);
const liveMutationAuthorized = effectiveClass === "live-mutating" && allowedLiveMutationPresent && !allowedLiveMutationNone;
const contradictionEvidence = [
...(effectiveClass === "read-only" && liveMutationEvidence.length > 0 ? ["declares/read-only but prompt contains live mutation signals"] : []),
...(effectiveClass === "live-read" && liveMutationEvidence.length > 0 ? ["declares/live-read but prompt contains live mutation signals"] : []),
...(effectiveClass === "live-mutating" && allowedLiveMutationNone ? ["declares/live-mutating but allowed live mutation is none"] : []),
...(prodMutationEvidence.length > 0 ? prodMutationEvidence.map((item) => `prod mutation signal: ${item}`) : []),
];
const missingOrContradictory = [
...(declaredClass === null ? ["missing DEV test class; defaulting to read-only"] : []),
...(effectiveInsufficient ? [`effective class ${effectiveClass} is below required ${requiredClass}`] : []),
...(requiredClass === "live-mutating" && !allowedLiveMutationPresent ? ["live-mutating prompt must include allowed live mutation"] : []),
...(requiredClass === "live-mutating" && allowedLiveMutationNone ? ["live-mutating prompt cannot set allowed live mutation to none"] : []),
...(!forbiddenActionsPresent ? ["missing forbidden actions"] : []),
...(!closeoutFieldsPresent ? ["missing closeout fields"] : []),
...contradictionEvidence,
];
const signals = [
promptLintSignal("declared-dev-test-class", "info", declaredClass === null ? [] : [declaredClass], "Prompt explicitly declares DEV test class."),
promptLintSignal("live-read-signal", "warning", liveReadEvidence, "Prompt appears to read live DEV service state, logs, health, status, metrics, or Kubernetes objects."),
promptLintSignal("live-mutation-signal", "block", liveMutationEvidence, "Prompt appears to trigger runtime writes, deployment, task control, operation/audit/evidence creation, or HWLAB DO/DI activity."),
promptLintSignal("prod-mutation-signal", "block", prodMutationEvidence, "Prompt appears to mention production mutation; Code Queue runner prompts must not implicitly authorize this."),
promptLintSignal("allowed-live-mutation-field", requiredClass === "live-mutating" ? "block" : "info", allowedLiveMutationPresent && !allowedLiveMutationNone ? ["present"] : [], "live-mutating prompts must enumerate allowed live mutation commands and target state changes."),
promptLintSignal("forbidden-actions-field", "warning", forbiddenActionsPresent ? ["present"] : [], "Prompt should list forbidden high-risk actions."),
promptLintSignal("closeout-fields-field", "warning", closeoutFieldsPresent ? ["present"] : [], "Prompt should require final closeout fields for class, mutation, commands, targets, evidence, and residual risk."),
];
const ok = missingOrContradictory.length === 0;
const dispatchDisposition: PromptLintDisposition = ok
? "ready"
: requiredClass === "live-mutating" || effectiveInsufficient || contradictionEvidence.length > 0
? "needs-authorization"
: "review";
return {
ok,
dryRun: true,
mutation: false,
dispatchDisposition,
declaredClass,
effectiveClass,
requiredClass,
defaultedReadOnly: declaredClass === null,
liveMutationAuthorized,
promptShape: {
chars: prompt.length,
lines: prompt.split(/\r\n|\r|\n/u).length,
textEchoed: false,
},
requiredPromptFields: {
devTestClass: {
present: declaredClass !== null,
value: declaredClass,
allowedValues: allowedClasses,
},
allowedLiveMutation: {
present: allowedLiveMutationPresent,
nonNone: allowedLiveMutationPresent && !allowedLiveMutationNone,
requiredWhen: "live-mutating",
},
forbiddenActions: {
present: forbiddenActionsPresent,
},
closeoutFields: {
present: closeoutFieldsPresent,
},
},
signals,
missingOrContradictory,
policy: {
defaultWhenUnclassified: "read-only",
promptLintOnly: true,
accessesLiveService: false,
printsPromptText: false,
reference: "docs/reference/code-queue-supervision.md#dev-测试授权分级",
},
commands: {
lintFile: "bun scripts/cli.ts codex prompt-lint --prompt-file <path>",
submitDryRun: "bun scripts/cli.ts codex submit --prompt-file <path> --dry-run",
steerDryRun: "bun scripts/cli.ts codex steer <taskId> --prompt-file <path> --dry-run",
},
};
}
function submitPolicyContract(): SubmitRoutingRecommendation["policyContract"] {
return {
selectionPrinciples: [
"Use GPT-5.5 for high-risk, runtime/core, security, CI/CD, deploy, release, and final quality calls.",
"Use DeepSeek/OpenCode for self-contained medium-complexity work with limited write scope and verifiable tests.",
"Use MiniMax only for simple, low-risk, self-contained work with external evidence and commander review.",
"Keep prod restart, secret access, DB writes, destructive Git, and running-task control with the commander or human.",
],
concurrency: {
gpt55Routine: 5,
gpt55BurstMax: 10,
minimaxSimpleMax: 10,
deepseekMediumDefault: 5,
},
modelTiers: [
{
model: gptSubmitModel,
runner: "codex",
taskRisk: "high-risk-or-complex",
requiredGuards: ["bounded ownership", "multi-signal verification", "no implicit prod rollout"],
},
{
model: deepseekSubmitModel,
runner: "opencode",
taskRisk: "medium-complexity",
requiredGuards: ["self-contained prompt", "limited write scope", "contract/unit verification", "commander review"],
},
{
model: minimaxSubmitModel,
runner: "opencode",
taskRisk: "simple-low-risk",
requiredGuards: ["issue is auxiliary only", "evidence required", "no prod/secrets/DB writes", "diff and test review"],
},
],
externalProvider429: {
commanderAction: "wait-while-exponential-backoff-is-healthy",
interveneWhen: ["heartbeat expired", "retry state machine stuck", "task lost", "retry attempts exhausted"],
},
};
}
function submitRoutingRecommendation(options: CodexSubmitOptions): SubmitRoutingRecommendation {
const prompt = options.prompt;
const lower = prompt.toLowerCase();
const prodOrStateMutation = regexEvidenceWithoutNegatedContext(lower, [
/\bprod(?:uction)?\b/gu,
/\brestart(?:ing|ed)?\b/gu,
/\brebuild(?:ing|ed)?\b/gu,
/\bdeploy(?:ment|ing|ed)?\b/gu,
/\bserver\s+rebuild\b/gu,
/\bdeploy\s+apply\b/gu,
/\binterrupt\b|\bcancel\b/gu,
/\bsecret\b|\btoken\b|\bapi[_-]?key\b|\bcredential\b/gu,
/\bpostgres(?:ql)?\b|\bpsql\b|\bdatabase\b|\bdb\b|\bsql\b|\bmigration\b/gu,
]);
const runtimeCore = regexEvidenceWithoutNegatedContext(lower, [
/\bcode[- ]queue\s+(?:runtime|scheduler|backend|execution|runner)\b/gu,
/\bbackend-core\b/gu,
/\bprovider-gateway\b/gu,
/\bk3sctl-adapter\b/gu,
/\bruntime-preflight\b/gu,
/\bactive\s+run\b/gu,
]);
const issueReference = regexEvidence(lower, [
/\bgithub\s+issue\b/gu,
/\bissue\s+#?\d+\b/gu,
/#\d+/gu,
/\bgh\s+issue\s+view\b/gu,
]);
const issueOnly = regexEvidence(lower, [
/\bread\s+(?:the\s+)?issue\b/gu,
/\bsee\s+(?:github\s+)?issue\b/gu,
/\bfrom\s+issue\s+#?\d+\b/gu,
/\bissue\s+(?:has|contains)\s+(?:the\s+)?(?:full|complete)\s+(?:context|requirements?)\b/gu,
/读取\s*(?:github\s*)?issue/gu,
/查看\s*(?:github\s*)?issue/gu,
]);
const issueAuxiliaryGuard = regexEvidence(prompt, [
/issue[^。\n]*辅助引用/giu,
/issue[^。\n]*不能作为唯一来源/giu,
/issue[^。\n]*not[^。\n]*only[^。\n]*source/giu,
/issue[^。\n]*auxiliary[^。\n]*reference/giu,
]);
const lowRiskEvidence = regexEvidence(lower, [
/\bdry-run\b/gu,
/\bpreflight\b/gu,
/\bcontract\s+test\b/gu,
/\btypecheck\b/gu,
/\bdocs?\b|\bdocumentation\b/gu,
/\bread[- ]?only\b/gu,
/只读/gu,
/文档/gu,
/轻量/gu,
]);
const mediumComplexityEvidence = regexEvidence(lower, [
/\bfront[- ]?end\b|\bfrontend\b|\breact\b|\btsx\b|\bcss\b|\bui\b|\bcomponent\b/gu,
/\buser[- ]service\b|\bservice\s+module\b/gu,
/\blocal\s+(?:module|helper|cli|tool)\b/gu,
/\bbounded\s+(?:bug\s*)?fix\b|\bsmall\s+(?:bug\s*)?fix\b/gu,
/\bunit\s+test\b|\bcontract\s+guard\b/gu,
/中等复杂|中等风险|前端|组件|样式|局部(?:模块|修复)|用户服务|契约守卫/gu,
]);
const evidenceRequest = regexEvidence(lower, [
/\bevidence\b/gu,
/\bverification\b|\bverified\b|\bvalidate\b|\bvalidation\b/gu,
/\btest(?:s|ed|ing)?\b/gu,
/\bdry-run\b/gu,
/\bcommit\b/gu,
/验证/gu,
/证据/gu,
/自测/gu,
]);
const selfContainedHints = regexEvidence(prompt, [
/目标[:]/gu,
/范围[:]/gu,
/禁止[:]/gu,
/验证[:]/gu,
/final response/giu,
/完整需求/gu,
/本 prompt/gu,
]);
const destructiveWords = regexEvidenceWithoutNegatedContext(lower, [
/\brm\s+-rf\b/gu,
/\bgit\s+reset\s+--hard\b/gu,
/\bgit\s+checkout\s+--\b/gu,
/\bdrop\s+table\b/gu,
/\btruncate\s+table\b/gu,
/\bdelete\s+from\b/gu,
]);
const crossModule = regexEvidenceWithoutNegatedContext(lower, [
/\bcross[- ]module\b/gu,
/\barchitecture\b|\barchitectural\b/gu,
/\brelease\/v1\b/gu,
/\bci\/cd\b/gu,
/\brollout\b|\brollback\b/gu,
/跨模块/gu,
/架构/gu,
/回滚方案|复杂回滚/gu,
]);
const model = normalizeSubmitModel(options.model);
const explicitRunner = submitRunnerForModel(model);
const promptSelfContained = prompt.length >= 700 || selfContainedHints.length >= 3;
const issueIsNotOnlySource = issueReference.length === 0 || issueAuxiliaryGuard.length > 0 || issueOnly.length === 0 && prompt.length >= 500;
const noProdRestartSecretOrDbWrite = prodOrStateMutation.length === 0 && destructiveWords.length === 0;
const noRuntimeCoreOrReleaseWork = runtimeCore.length === 0 && crossModule.length === 0;
const evidenceRequiredByPrompt = evidenceRequest.length > 0;
const mediumComplexityCandidate = promptSelfContained
&& issueIsNotOnlySource
&& noProdRestartSecretOrDbWrite
&& noRuntimeCoreOrReleaseWork
&& evidenceRequiredByPrompt
&& mediumComplexityEvidence.length > 0;
const signals = [
routeSignal("prod-state-secret-db-write", "block", [...prodOrStateMutation, ...destructiveWords], "Mentions production/state mutation, restart, secrets, DB writes, or destructive commands."),
routeSignal("runtime-core", "warning", runtimeCore, "Touches Code Queue runtime, backend-core, provider-gateway, k3s adapter, or active run behavior."),
routeSignal("issue-source-risk", "warning", issueOnly, "Prompt appears to rely on GitHub issue reading as task context."),
routeSignal("issue-auxiliary-source-guard", "info", issueAuxiliaryGuard, "Prompt explicitly says GitHub issue is auxiliary and not the only source."),
routeSignal("cross-module-release", "warning", crossModule, "Mentions cross-module architecture, CI/CD rollout, release line, or rollback work."),
routeSignal("medium-complexity-verifiable", "info", mediumComplexityEvidence, "Mentions bounded medium-complexity work such as frontend, local CLI/helper, user-service module, or contract guard changes."),
routeSignal("low-risk-verifiable", "info", lowRiskEvidence, "Mentions low-risk or verifiable work such as docs, read-only checks, dry-run, preflight, or contract tests."),
routeSignal("evidence-requested", "info", evidenceRequest, "Prompt asks for tests, validation, commit, or evidence."),
routeSignal("self-contained-hints", "info", selfContainedHints, "Prompt includes explicit task sections that make it easier to verify without reading an issue."),
];
let route: SubmitRoute = "gpt-5.5-codex";
let recommendedRunner: SubmitRoutingRecommendation["recommendedRunner"] = "codex";
let recommendedModel: string | null = gptSubmitModel;
let confidence: SubmitRoutingRecommendation["confidence"] = "medium";
let reason = "Default to GPT-5.5 when the prompt is not clearly low-risk and self-contained.";
if (prodOrStateMutation.length > 0 || destructiveWords.length > 0) {
route = "commander-human-only";
recommendedRunner = "commander";
recommendedModel = null;
confidence = "high";
reason = "This task mentions production/state mutation, restart, secrets, DB writes, or destructive operations; keep it with the commander or a human.";
} else if (runtimeCore.length > 0 || crossModule.length > 0) {
route = "gpt-5.5-codex";
confidence = "high";
reason = "This task touches runtime/core/cross-module or release-governance surfaces, so it should stay on GPT-5.5.";
} else if (mediumComplexityCandidate) {
route = "deepseek-opencode";
recommendedRunner = "opencode";
recommendedModel = deepseekSubmitModel;
confidence = "high";
reason = "The prompt looks self-contained, medium-complexity, and verifiable without production/state privileges; it is a DeepSeek/OpenCode candidate after commander review.";
} else if (mediumComplexityEvidence.length > 0 && issueIsNotOnlySource && noProdRestartSecretOrDbWrite && noRuntimeCoreOrReleaseWork) {
route = "deepseek-opencode";
recommendedRunner = "opencode";
recommendedModel = deepseekSubmitModel;
confidence = "medium";
reason = "The prompt has medium-complexity signals, but the commander should tighten self-contained context, write scope, and verification requirements before relying on DeepSeek/OpenCode.";
} else if (promptSelfContained && issueIsNotOnlySource && evidenceRequiredByPrompt && lowRiskEvidence.length > 0) {
route = "minimax-opencode";
recommendedRunner = "opencode";
recommendedModel = minimaxSubmitModel;
confidence = "high";
reason = "The prompt looks self-contained, low-risk, and asks for verifiable evidence; it is a MiniMax/OpenCode candidate if the runner smoke is currently green.";
} else if (lowRiskEvidence.length > 0 && issueIsNotOnlySource && noProdRestartSecretOrDbWrite) {
route = "minimax-opencode";
recommendedRunner = "opencode";
recommendedModel = minimaxSubmitModel;
confidence = "medium";
reason = "The prompt has low-risk signals, but the commander should tighten self-contained context and evidence requirements before relying on MiniMax.";
}
const explicitNote = model.length === 0
? null
: explicitRunner === recommendedRunner
? "Explicit --model matches the dry-run recommendation."
: "Explicit --model differs from the dry-run recommendation; this dry-run does not rewrite the payload.";
return {
route,
recommendedRunner,
recommendedModel,
confidence,
reason,
signals,
riskControls: {
promptSelfContained,
issueIsNotOnlySource,
noProdRestartSecretOrDbWrite,
noRuntimeCoreOrReleaseWork,
evidenceRequiredByPrompt,
mediumComplexityCandidate,
commanderMustReviewUnread: true,
},
explicitRequest: {
model: model.length === 0 ? null : model,
runner: explicitRunner,
note: explicitNote,
},
routingPolicy: {
dryRunOnly: true,
doesNotChangeSubmittedPayload: true,
prodMiniMaxAssumedAvailable: false,
prodDeepSeekAssumedAvailable: false,
runtimeAdmissionUnchanged: true,
},
policyContract: submitPolicyContract(),
};
}
function compactSchedulerHeartbeat(value: unknown): Record<string, unknown> | null {
const record = asRecord(value);
if (record === null) return null;
return {
taskId: record.taskId ?? null,
attempt: record.attempt ?? null,
owner: record.owner ?? null,
schedulerInstance: record.schedulerInstance ?? null,
agentPort: record.agentPort ?? null,
activeTurnId: record.activeTurnId ?? null,
codexThreadId: record.codexThreadId ?? null,
lastLocalHeartbeatAt: record.lastLocalHeartbeatAt ?? null,
lastObservedAgentEventAt: record.lastObservedAgentEventAt ?? null,
lastPersistedTraceAt: record.lastPersistedTraceAt ?? null,
outputMaxSeq: record.outputMaxSeq ?? null,
};
}
function splitBrainLiveFromDiagnostics(record: Record<string, unknown>): boolean {
if (typeof record.splitBrainLive === "boolean") return record.splitBrainLive;
const state = String(record.state ?? record.health ?? "").toLowerCase();
const riskTaskIds = Array.from(new Set([
...stringList(record.heartbeatRiskTaskIds),
...stringList(record.heartbeatExpiredTaskIds),
...stringList(record.heartbeatMissingTaskIds),
...stringList(record.staleRecoveryCandidateTaskIds),
]));
return state === "split-brain" && stringList(record.heartbeatFreshTaskIds).length > 0 && riskTaskIds.length === 0;
}
function effectiveLivenessFromDiagnostics(record: Record<string, unknown>): string {
if (typeof record.effectiveLiveness === "string" && record.effectiveLiveness.length > 0) return record.effectiveLiveness;
if (stringList(record.heartbeatRiskTaskIds).length > 0
|| stringList(record.heartbeatExpiredTaskIds).length > 0
|| stringList(record.heartbeatMissingTaskIds).length > 0
|| stringList(record.staleRecoveryCandidateTaskIds).length > 0) {
return "at-risk";
}
if (splitBrainLiveFromDiagnostics(record)) return "live";
return String(record.state ?? record.health ?? "unknown") === "healthy" ? "healthy" : "degraded";
}
function recommendedActionFromDiagnostics(record: Record<string, unknown>): string {
if (typeof record.recommendedAction === "string" && record.recommendedAction.length > 0) return record.recommendedAction;
const effectiveLiveness = effectiveLivenessFromDiagnostics(record);
if (effectiveLiveness === "at-risk") return "investigate-heartbeat-risk";
if (effectiveLiveness === "live") return "continue-supervision";
if (effectiveLiveness === "degraded") return "observe-degraded";
return "none";
}
function activeHeartbeatCountFromDiagnostics(record: Record<string, unknown>, activeHeartbeatTaskIds: { count: number }, heartbeatFreshTaskIds: { count: number }): number {
const explicit = asNumber(record.activeHeartbeatCount, Number.NaN);
return Number.isFinite(explicit) ? explicit : Math.max(activeHeartbeatTaskIds.count, heartbeatFreshTaskIds.count);
}
function compactLivenessDecision(record: Record<string, unknown>, lists: {
activeHeartbeatTaskIds: { items: string[]; count: number; truncated: boolean; omitted: number };
heartbeatFreshTaskIds: { items: string[]; count: number; truncated: boolean; omitted: number };
heartbeatRiskTaskIds: { items: string[]; count: number };
databaseActiveTaskIds: { count: number };
}): Record<string, unknown> {
const splitBrainLive = splitBrainLiveFromDiagnostics(record);
const effectiveLiveness = effectiveLivenessFromDiagnostics(record);
const recommendedAction = recommendedActionFromDiagnostics(record);
const activeHeartbeatCount = activeHeartbeatCountFromDiagnostics(record, lists.activeHeartbeatTaskIds, lists.heartbeatFreshTaskIds);
return {
effectiveLiveness,
recommendedAction,
splitBrainLive,
activeHeartbeatCount,
heartbeatFreshTaskCount: lists.heartbeatFreshTaskIds.count,
heartbeatFreshTaskIds: lists.heartbeatFreshTaskIds.items,
heartbeatFreshTaskIdsTruncated: lists.heartbeatFreshTaskIds.truncated,
databaseActiveTaskCount: asNumber(record.databaseActiveTaskCount, lists.databaseActiveTaskIds.count),
schedulerActiveRunSlotCount: record.schedulerActiveRunSlotCount ?? null,
heartbeatRiskTaskCount: lists.heartbeatRiskTaskIds.count,
interpretation: splitBrainLive
? "scheduler heartbeat is fresh; treat active task count from heartbeat as live and continue supervision"
: effectiveLiveness === "at-risk"
? "heartbeat risk is present; investigate heartbeat freshness before recovery"
: effectiveLiveness === "degraded"
? "diagnostics are degraded; cross-check heartbeat, trace and control-plane sources"
: "diagnostics indicate healthy liveness",
};
}
function boundedUniqueStringList(value: unknown, limit = diagnosticsIdPreviewLimit): { items: string[]; count: number; omitted: number; truncated: boolean } {
const all = Array.from(new Set(stringList(value))).sort();
const items = all.slice(0, limit);
return {
items,
count: all.length,
omitted: Math.max(0, all.length - items.length),
truncated: all.length > items.length,
};
}
function boundedInlineString(value: unknown, maxChars: number): { text: string | null; chars: number; truncated: boolean; omittedChars: number } {
const text = asString(value).replace(/\s+/gu, " ").trim();
const truncated = text.length > maxChars;
return {
text: text.length === 0 ? null : truncated ? text.slice(0, maxChars) : text,
chars: text.length,
truncated,
omittedChars: truncated ? text.length - maxChars : 0,
};
}
function compactExecutionDiagnostics(value: unknown): Record<string, unknown> | null {
const record = asRecord(value);
if (record === null) return null;
const fullHeartbeatRiskTaskIds = Array.from(new Set([
...stringList(record.heartbeatRiskTaskIds),
...stringList(record.heartbeatExpiredTaskIds),
...stringList(record.heartbeatMissingTaskIds),
...stringList(record.staleRecoveryCandidateTaskIds),
])).sort();
const databaseActiveTaskIds = boundedUniqueStringList(record.databaseActiveTaskIds);
const schedulerActiveTaskIds = boundedUniqueStringList(record.schedulerActiveTaskIds);
const activeHeartbeatTaskIds = boundedUniqueStringList(record.activeHeartbeatTaskIds);
const heartbeatFreshTaskIds = boundedUniqueStringList(record.heartbeatFreshTaskIds);
const heartbeatExpiredTaskIds = boundedUniqueStringList(record.heartbeatExpiredTaskIds);
const heartbeatMissingTaskIds = boundedUniqueStringList(record.heartbeatMissingTaskIds);
const staleRecoveryCandidateTaskIds = boundedUniqueStringList(record.staleRecoveryCandidateTaskIds);
const heartbeatRiskTaskIds = boundedUniqueStringList(fullHeartbeatRiskTaskIds);
const traceGapTaskIds = boundedUniqueStringList(record.traceGapTaskIds);
const traceGapNotStaleTaskIds = boundedUniqueStringList(record.traceGapNotStaleTaskIds);
const allReasons = stringList(record.reasons);
const reasons = allReasons.slice(0, diagnosticsReasonPreviewLimit).map((reason) => boundedInlineString(reason, 240).text).filter((reason): reason is string => reason !== null);
const livenessSummary = boundedInlineString(record.livenessSummary, 420);
const liveness = compactLivenessDecision(record, {
activeHeartbeatTaskIds,
heartbeatFreshTaskIds,
heartbeatRiskTaskIds,
databaseActiveTaskIds,
});
const omittedCounts = {
databaseActiveTaskIds: databaseActiveTaskIds.omitted,
schedulerActiveTaskIds: schedulerActiveTaskIds.omitted,
activeHeartbeatTaskIds: activeHeartbeatTaskIds.omitted,
heartbeatFreshTaskIds: heartbeatFreshTaskIds.omitted,
heartbeatExpiredTaskIds: heartbeatExpiredTaskIds.omitted,
heartbeatMissingTaskIds: heartbeatMissingTaskIds.omitted,
staleRecoveryCandidateTaskIds: staleRecoveryCandidateTaskIds.omitted,
heartbeatRiskTaskIds: heartbeatRiskTaskIds.omitted,
traceGapTaskIds: traceGapTaskIds.omitted,
traceGapNotStaleTaskIds: traceGapNotStaleTaskIds.omitted,
reasons: Math.max(0, allReasons.length - reasons.length),
livenessSummaryChars: livenessSummary.omittedChars,
};
return {
state: record.state ?? record.health ?? null,
degraded: record.degraded ?? null,
splitBrain: record.splitBrain ?? null,
splitBrainLive: splitBrainLiveFromDiagnostics(record),
effectiveLiveness: liveness.effectiveLiveness,
recommendedAction: liveness.recommendedAction,
liveness,
livenessSummary: livenessSummary.text,
livenessSummaryChars: livenessSummary.chars,
livenessSummaryTruncated: livenessSummary.truncated,
executionStateSource: record.executionStateSource ?? null,
controlPlane: boundedInlineString(record.controlPlane, 120).text,
databaseActiveTaskCount: record.databaseActiveTaskCount ?? databaseActiveTaskIds.count,
databaseActiveTaskIds: databaseActiveTaskIds.items,
schedulerActiveRunSlotCount: record.schedulerActiveRunSlotCount ?? null,
schedulerActiveTaskIds: schedulerActiveTaskIds.items,
activeHeartbeatCount: liveness.activeHeartbeatCount,
activeHeartbeatTaskIds: activeHeartbeatTaskIds.items,
heartbeatFreshTaskIds: heartbeatFreshTaskIds.items,
heartbeatExpiredTaskIds: heartbeatExpiredTaskIds.items,
heartbeatMissingTaskIds: heartbeatMissingTaskIds.items,
staleRecoveryCandidateTaskIds: staleRecoveryCandidateTaskIds.items,
heartbeatRiskTaskIds: heartbeatRiskTaskIds.items,
traceGapTaskIds: traceGapTaskIds.items,
traceGapNotStaleTaskIds: traceGapNotStaleTaskIds.items,
lastSchedulerHeartbeatAt: record.lastSchedulerHeartbeatAt ?? null,
lastObservedAgentEventAt: record.lastObservedAgentEventAt ?? null,
lastPersistedTraceAt: record.lastPersistedTraceAt ?? null,
oaPublisher: previewJson(record.oaPublisher ?? null, { maxDepth: 3, maxArrayItems: 4, maxObjectKeys: 12, maxStringLength: 240 }),
reasons,
listBudget: {
idPreviewLimit: diagnosticsIdPreviewLimit,
reasonPreviewLimit: diagnosticsReasonPreviewLimit,
truncated: Object.values(omittedCounts).some((count) => count > 0),
omittedCounts,
rawCommand: "bun scripts/cli.ts microservice proxy code-queue /api/tasks/overview?limit=30 --raw --full",
},
};
}
function compactQueueExecutionDiagnostics(value: unknown): Record<string, unknown> | null {
const diagnostics = compactExecutionDiagnostics(value);
if (diagnostics === null) return null;
const listBudget = asRecord(diagnostics.listBudget) ?? {};
const omittedCounts = asRecord(listBudget.omittedCounts) ?? {};
return {
state: diagnostics.state ?? null,
degraded: diagnostics.degraded ?? null,
splitBrain: diagnostics.splitBrain ?? null,
splitBrainLive: diagnostics.splitBrainLive ?? null,
effectiveLiveness: diagnostics.effectiveLiveness ?? null,
recommendedAction: diagnostics.recommendedAction ?? null,
liveness: diagnostics.liveness ?? null,
executionStateSource: diagnostics.executionStateSource ?? null,
controlPlane: diagnostics.controlPlane ?? null,
databaseActiveTaskCount: diagnostics.databaseActiveTaskCount ?? null,
schedulerActiveRunSlotCount: diagnostics.schedulerActiveRunSlotCount ?? null,
activeHeartbeatCount: diagnostics.activeHeartbeatCount ?? null,
lastSchedulerHeartbeatAt: diagnostics.lastSchedulerHeartbeatAt ?? null,
lastObservedAgentEventAt: diagnostics.lastObservedAgentEventAt ?? null,
lastPersistedTraceAt: diagnostics.lastPersistedTraceAt ?? null,
reasons: diagnostics.reasons ?? [],
listBudget: {
truncated: listBudget.truncated ?? false,
omittedCounts: {
databaseActiveTaskIds: omittedCounts.databaseActiveTaskIds ?? 0,
activeHeartbeatTaskIds: omittedCounts.activeHeartbeatTaskIds ?? 0,
heartbeatFreshTaskIds: omittedCounts.heartbeatFreshTaskIds ?? 0,
heartbeatRiskTaskIds: omittedCounts.heartbeatRiskTaskIds ?? 0,
reasons: omittedCounts.reasons ?? 0,
},
rawCommand: listBudget.rawCommand ?? "bun scripts/cli.ts microservice proxy code-queue /api/tasks/overview?limit=30 --raw --full",
},
};
}
function firstFiniteNumber(...values: unknown[]): number | null {
for (const value of values) {
const number = finiteNumber(value);
if (number !== null) return number;
}
return null;
}
function stringListCount(value: unknown): number | null {
return Array.isArray(value) ? stringList(value).length : null;
}
function compactCodeQueueActivity(
queue: Record<string, unknown>,
diagnostics: Record<string, unknown> | null,
options: { schedulerLocalActiveQueueIds?: string[]; runnableQueueCount?: number | null } = {},
): Record<string, unknown> {
const rawDiagnostics = asRecord(queue.executionDiagnostics) ?? {};
const compactDiagnostics = diagnostics ?? {};
const rawLiveness = asRecord(rawDiagnostics.liveness) ?? {};
const compactLiveness = asRecord(compactDiagnostics.liveness) ?? {};
const counts = asRecord(queue.counts) ?? {};
const schedulerLocalActiveQueueIds = options.schedulerLocalActiveQueueIds ?? stringList(queue.activeQueueIds);
const databaseRunningTaskCount = firstFiniteNumber(counts.running) ?? 0;
const databaseJudgingTaskCount = firstFiniteNumber(counts.judging) ?? 0;
const databaseActiveTaskCount = firstFiniteNumber(
rawDiagnostics.databaseActiveTaskCount,
queue.databaseActiveTaskCount,
compactDiagnostics.databaseActiveTaskCount,
stringListCount(rawDiagnostics.databaseActiveTaskIds),
stringListCount(queue.databaseActiveTaskIds),
databaseRunningTaskCount + databaseJudgingTaskCount,
) ?? 0;
const heartbeatFreshActiveTaskCount = firstFiniteNumber(
rawLiveness.heartbeatFreshTaskCount,
compactLiveness.heartbeatFreshTaskCount,
stringListCount(rawDiagnostics.heartbeatFreshTaskIds),
stringListCount(compactDiagnostics.heartbeatFreshTaskIds),
) ?? 0;
const activeHeartbeatTaskCount = firstFiniteNumber(
rawDiagnostics.activeHeartbeatCount,
compactDiagnostics.activeHeartbeatCount,
stringListCount(rawDiagnostics.activeHeartbeatTaskIds),
heartbeatFreshActiveTaskCount,
) ?? 0;
const heartbeatRiskTaskCount = firstFiniteNumber(
rawLiveness.heartbeatRiskTaskCount,
compactLiveness.heartbeatRiskTaskCount,
stringListCount(rawDiagnostics.heartbeatRiskTaskIds),
stringListCount(compactDiagnostics.heartbeatRiskTaskIds),
) ?? 0;
const staleRecoveryCandidateTaskCount = firstFiniteNumber(
rawLiveness.staleRecoveryCandidateTaskCount,
compactLiveness.staleRecoveryCandidateTaskCount,
stringListCount(rawDiagnostics.staleRecoveryCandidateTaskIds),
stringListCount(compactDiagnostics.staleRecoveryCandidateTaskIds),
) ?? 0;
const schedulerLocalActiveRunSlotCount = firstFiniteNumber(
rawDiagnostics.schedulerActiveRunSlotCount,
queue.schedulerActiveRunSlotCount,
queue.activeRunSlotCount,
compactDiagnostics.schedulerActiveRunSlotCount,
);
const runnableQueueCount = firstFiniteNumber(options.runnableQueueCount, queue.runnableQueueCount);
const effectiveActiveTaskCount = Math.max(databaseActiveTaskCount, databaseRunningTaskCount, heartbeatFreshActiveTaskCount);
const executionState = asString(rawDiagnostics.state ?? compactDiagnostics.state);
const effectiveLiveness = asString(rawDiagnostics.effectiveLiveness ?? compactDiagnostics.effectiveLiveness ?? rawLiveness.effectiveLiveness ?? compactLiveness.effectiveLiveness);
const recommendedAction = asString(rawDiagnostics.recommendedAction ?? compactDiagnostics.recommendedAction ?? rawLiveness.recommendedAction ?? compactLiveness.recommendedAction);
const splitBrain = asBoolean(rawDiagnostics.splitBrain) || asBoolean(compactDiagnostics.splitBrain) || executionState === "split-brain";
const splitBrainLive = splitBrainLiveFromDiagnostics(rawDiagnostics) || splitBrainLiveFromDiagnostics(compactDiagnostics);
const effectiveActiveSource = heartbeatFreshActiveTaskCount > 0 && heartbeatFreshActiveTaskCount >= databaseActiveTaskCount
? "heartbeat-fresh"
: databaseActiveTaskCount > 0
? "database-active"
: schedulerLocalActiveQueueIds.length > 0 || (schedulerLocalActiveRunSlotCount ?? 0) > 0
? "scheduler-local"
: "none";
const activeQueueIdsNote = schedulerLocalActiveQueueIds.length === 0 && effectiveActiveTaskCount > 0
? "activeQueueIds are scheduler-local only; zero local queue ids does not mean zero active runners when database or heartbeat counts are nonzero."
: "activeQueueIds are scheduler-local active-run slots; use effectiveActiveTaskCount for commander concurrency decisions.";
const recommendedActionIntervenes = recommendedAction.length > 0 && recommendedAction !== "continue-supervision";
const interventionRequired = heartbeatRiskTaskCount > 0 || staleRecoveryCandidateTaskCount > 0 || recommendedActionIntervenes || (splitBrain && !splitBrainLive);
const splitBrainDisposition = splitBrainLive
? "live-count-as-active"
: splitBrain
? "risk-investigate-before-new-work"
: "not-split-brain";
const splitBrainReason = splitBrainLive
? "database active/running tasks have fresh heartbeat evidence and no heartbeat-risk candidates in the compact summary."
: splitBrain
? "split-brain without fresh-heartbeat live evidence is risky; inspect heartbeat risk, stale recovery candidates, and raw diagnostics before changing capacity."
: "control-plane and execution-plane activity signals are not split-brain.";
const interventionReason = splitBrainLive
? "fresh heartbeat makes split-brain live; count these runners as active and continue supervision."
: heartbeatRiskTaskCount > 0
? "heartbeat risk is present; inspect before adding replacement work or recovering tasks."
: staleRecoveryCandidateTaskCount > 0
? "stale recovery candidates are present; follow the recovery runbook before changing concurrency."
: recommendedActionIntervenes
? `execution diagnostics recommend ${recommendedAction}; intervene before adding work.`
: splitBrain
? "split-brain is not proven live; inspect raw diagnostics before treating capacity as available."
: "no intervention signal in compact activity summary.";
const commanderConcurrency = {
activeRunnerCount: effectiveActiveTaskCount,
activeRunnerCountField: "activity.effectiveActiveTaskCount",
activeRunnerCountSource: effectiveActiveSource,
decisionRule: "subtract activeRunnerCount from the commander concurrency target; for a 15-runner policy, remaining slots = 15 - activeRunnerCount.",
splitBrainDisposition,
splitBrainReason,
interventionRequired,
interventionReason,
};
return {
effectiveActiveTaskCount,
effectiveActiveSource,
databaseRunningTaskCount,
databaseActiveTaskCount,
heartbeatFreshActiveTaskCount,
activeHeartbeatTaskCount,
heartbeatRiskTaskCount,
staleRecoveryCandidateTaskCount,
schedulerLocalActiveQueueCount: schedulerLocalActiveQueueIds.length,
schedulerLocalActiveRunSlotCount,
runnableQueueCount,
effectiveLiveness: effectiveLiveness || null,
recommendedAction: recommendedAction || null,
splitBrainLive,
splitBrainDisposition,
splitBrainReason,
commanderConcurrency,
activeQueueIdsScope: "scheduler-local-active-run-slots",
activeQueueIdsNote,
interpretation: splitBrainLive
? "split-brain live: database-active tasks have fresh scheduler heartbeat; continue supervision."
: heartbeatRiskTaskCount > 0
? "heartbeat risk is present; investigate before retry or recovery."
: effectiveActiveTaskCount > 0
? "active work is present; compare database, heartbeat, and scheduler-local counts before changing concurrency."
: "no active work observed by database, heartbeat, or scheduler-local signals.",
};
}
function supervisorExecutionDiagnostics(value: unknown): Record<string, unknown> | null {
const diagnostics = compactExecutionDiagnostics(value);
if (diagnostics === null) return null;
const liveness = asRecord(diagnostics.liveness) ?? {};
const listBudget = asRecord(diagnostics.listBudget) ?? {};
return {
state: diagnostics.state ?? null,
effectiveLiveness: diagnostics.effectiveLiveness ?? null,
recommendedAction: diagnostics.recommendedAction ?? null,
splitBrainLive: diagnostics.splitBrainLive ?? null,
activeHeartbeatCount: diagnostics.activeHeartbeatCount ?? null,
databaseActiveTaskCount: diagnostics.databaseActiveTaskCount ?? null,
schedulerActiveRunSlotCount: diagnostics.schedulerActiveRunSlotCount ?? null,
lastObservedAgentEventAt: diagnostics.lastObservedAgentEventAt ?? null,
heartbeatFreshTaskIds: diagnostics.heartbeatFreshTaskIds ?? [],
heartbeatRiskTaskIds: diagnostics.heartbeatRiskTaskIds ?? [],
traceGapTaskIds: diagnostics.traceGapTaskIds ?? [],
reasons: diagnostics.reasons ?? [],
interpretation: liveness.interpretation ?? null,
listBudget: {
idPreviewLimit: listBudget.idPreviewLimit ?? diagnosticsIdPreviewLimit,
reasonPreviewLimit: listBudget.reasonPreviewLimit ?? diagnosticsReasonPreviewLimit,
truncated: listBudget.truncated ?? false,
omittedCounts: listBudget.omittedCounts ?? {},
rawCommand: listBudget.rawCommand ?? "bun scripts/cli.ts microservice proxy code-queue /api/tasks/overview?limit=30 --raw --full",
},
};
}
function compactToolSummary(value: unknown, full: boolean, limit = defaultToolLimit): Record<string, unknown> {
const record = asRecord(value) ?? {};
const allItems = asArray(record.items);
const sourceItems = full ? allItems : allItems.slice(0, limit);
const items = sourceItems.map((item) => {
const line = asRecord(item) ?? {};
return {
seq: line.seq ?? null,
at: line.at ?? null,
kind: line.kind ?? null,
title: line.title ?? "",
status: line.status ?? null,
commandPreview: compactText(line.commandPreview, full, 360),
commandOmittedLines: line.commandOmittedLines ?? 0,
outputPreview: compactText(line.outputPreview, full, 360),
outputOmittedLines: line.outputOmittedLines ?? 0,
rawSeqs: line.rawSeqs ?? [],
};
});
return {
count: record.count ?? allItems.length,
returned: items.length,
limit,
truncated: record.truncated === true || (!full && allItems.length > items.length),
items,
};
}
function compactSummary(summary: unknown, options: CodexTaskOptions, taskId: string): Record<string, unknown> {
const record = asRecord(summary) ?? {};
const transcriptCount = asNumber(record.transcriptCount, 0);
const transcriptMaxSeq = transcriptCount > 0 ? record.transcriptMaxSeq ?? null : null;
const initialPrompt = asString(record.initialPrompt ?? record.prompt);
const initialPromptView = textView(initialPrompt, options.full, detailInitialPromptPreviewChars);
const basePromptView = textView(asString(record.basePrompt), options.full, detailBasePromptPreviewChars);
const attemptRecordsSource = asArray(record.attempts);
const attemptRecords = (options.full ? attemptRecordsSource : attemptRecordsSource.slice(0, detailAttemptReturnedLimit))
.map((attempt) => compactAttemptCycle(attempt, options.full));
return {
id: record.id ?? taskId,
queueId: record.queueId ?? null,
status: record.status ?? null,
providerId: record.providerId ?? null,
model: record.model ?? null,
agentPort: record.agentPort ?? null,
agentPortInfo: record.agentPortInfo ?? null,
reasoningEffort: record.reasoningEffort ?? null,
cwd: record.cwd ?? null,
attempts: {
currentAttempt: record.currentAttempt ?? null,
maxAttempts: record.maxAttempts ?? null,
currentMode: record.currentMode ?? null,
judgeFailCount: record.judgeFailCount ?? null,
judgeFailRetryLimit: record.judgeFailRetryLimit ?? null,
attemptRecordCount: attemptRecordsSource.length,
attemptRecordsReturned: attemptRecords.length,
attemptRecordsTruncated: !options.full && attemptRecordsSource.length > attemptRecords.length,
attemptRecords,
},
thread: {
codexThreadId: record.codexThreadId ?? null,
activeTurnId: record.activeTurnId ?? null,
cancelRequested: record.cancelRequested ?? null,
schedulerHeartbeat: compactSchedulerHeartbeat(record.schedulerHeartbeat),
},
timing: record.timing ?? null,
createdAt: record.createdAt ?? null,
startedAt: record.startedAt ?? null,
updatedAt: record.updatedAt ?? null,
finishedAt: record.finishedAt ?? null,
...(options.full
? { initialPrompt: initialPromptView, basePrompt: basePromptView }
: { initialPromptPreview: initialPromptView, basePromptPreview: basePromptView }),
referenceTaskIds: record.referenceTaskIds ?? [],
referenceInjection: record.referenceInjection ?? null,
lastAssistantMessage: compactLastAssistant(record.lastAssistantMessage, options.full, detailLastAssistantPreviewChars),
lastJudge: record.lastJudge ?? null,
lastError: record.lastError ?? null,
toolSummary: compactToolSummary(record.toolSummary, options.full, options.toolLimit),
counts: {
transcript: record.transcriptCount ?? null,
output: record.outputCount ?? null,
events: record.eventCount ?? null,
},
traceDisclosure: {
included: options.trace,
renderer: "shared trace-summary/trace-steps progressive abstraction; CLI and WebUI diverge only at final rendering",
total: record.transcriptCount ?? null,
maxSeq: transcriptMaxSeq,
detailOutputPolicy: "bounded detail by default; use --full, --trace, --tool-limit, or codex output for progressive disclosure",
defaultPage: `bun scripts/cli.ts codex task ${taskId} --trace --limit ${defaultTraceLimit}`,
firstPage: `bun scripts/cli.ts codex task ${taskId} --trace --from-start --limit ${defaultTraceLimit}`,
nextPageTemplate: `bun scripts/cli.ts codex task ${taskId} --trace --after-seq <nextAfterSeq> --limit ${defaultTraceLimit}`,
previousPageTemplate: `bun scripts/cli.ts codex task ${taskId} --trace --before-seq <previousBeforeSeq> --limit ${defaultTraceLimit}`,
rawOutputTemplate: `bun scripts/cli.ts codex output ${taskId} --after-seq <rawSeq> --limit ${defaultOutputLimit}`,
fullTextSummary: `bun scripts/cli.ts codex task ${taskId} --detail --full --tool-limit ${Math.max(options.toolLimit, defaultToolLimit)}`,
},
};
}
function compactReviewSummary(summary: unknown, options: CodexTaskOptions, taskId: string): Record<string, unknown> {
const record = asRecord(summary) ?? {};
const initialPrompt = asString(record.basePrompt || record.initialPrompt || record.prompt);
const transcriptCount = asNumber(record.transcriptCount, 0);
return {
id: record.id ?? taskId,
queueId: record.queueId ?? null,
status: record.status ?? null,
providerId: record.providerId ?? null,
model: record.model ?? null,
agentPort: record.agentPort ?? null,
agentPortInfo: record.agentPortInfo ?? null,
cwd: record.cwd ?? null,
attempts: {
currentAttempt: record.currentAttempt ?? null,
maxAttempts: record.maxAttempts ?? null,
currentMode: record.currentMode ?? null,
},
timing: record.timing ?? null,
createdAt: record.createdAt ?? null,
startedAt: record.startedAt ?? null,
updatedAt: record.updatedAt ?? null,
finishedAt: record.finishedAt ?? null,
originalPrompt: textView(initialPrompt, options.full, 3000),
finalResponse: compactFinalResponse(record.lastAssistantMessage, options.full),
lastError: record.lastError ?? null,
counts: {
transcript: record.transcriptCount ?? null,
output: record.outputCount ?? null,
events: record.eventCount ?? null,
},
disclosure: {
mode: "review",
defaultScope: "original prompt and final response only; use detail/trace/output commands for progressive disclosure",
fullPromptAndResponse: `bun scripts/cli.ts codex task ${taskId} --full`,
detail: `bun scripts/cli.ts codex task ${taskId} --detail`,
fullDetail: `bun scripts/cli.ts codex task ${taskId} --detail --full --tool-limit ${Math.max(options.toolLimit, defaultToolLimit)}`,
traceTail: `bun scripts/cli.ts codex task ${taskId} --trace --tail --limit ${defaultTraceLimit}`,
outputTail: `bun scripts/cli.ts codex output ${taskId} --tail --limit ${defaultOutputLimit}`,
rawOutputTemplate: `bun scripts/cli.ts codex output ${taskId} --after-seq <rawSeq> --limit ${defaultOutputLimit}`,
transcriptTotal: transcriptCount,
transcriptMaxSeq: transcriptCount > 0 ? record.transcriptMaxSeq ?? null : null,
},
};
}
function traceKindLabel(kind: unknown): string {
const value = String(kind || "");
if (value === "ran") return "Ran";
if (value === "explored") return "Explored";
if (value === "edited") return "Edited";
if (value === "error") return "Error";
if (value === "system") return "System";
return "Message";
}
function transcriptLineToStep(line: unknown): Record<string, unknown> {
const record = asRecord(line) ?? {};
const summaryLines = stringList(record.summaryLines);
const fallbackSummary = [record.commandPreview, record.bodyPreview, record.title].map((value) => asString(value).trim()).filter(Boolean);
return {
seq: record.seq ?? null,
at: record.at ?? null,
kind: record.kind ?? "message",
title: record.title ?? "",
status: record.status ?? null,
durationMs: record.durationMs ?? null,
rawSeqs: record.rawSeqs ?? [],
summaryLines: summaryLines.length > 0 ? summaryLines : fallbackSummary.slice(0, 4),
hasDetail: true,
};
}
function compactTraceStep(step: unknown, taskId: string): Record<string, unknown> {
const record = asRecord(step) ?? {};
const seq = record.seq ?? null;
return {
seq,
at: record.at ?? null,
kind: record.kind ?? "message",
label: traceKindLabel(record.kind),
title: record.title ?? "",
status: record.status ?? null,
durationMs: record.durationMs ?? null,
duration: fmtDuration(record.durationMs),
rawSeqs: record.rawSeqs ?? [],
summaryLines: stringList(record.summaryLines),
hasDetail: asBoolean(record.hasDetail),
detailCommand: seq === null ? null : `bun scripts/cli.ts microservice proxy code-queue /api/tasks/${encodeURIComponent(taskId)}/trace-step?seq=${encodeURIComponent(String(seq))} --raw`,
};
}
function compactAttemptCycle(value: unknown, full: boolean): Record<string, unknown> {
const record = asRecord(value) ?? {};
return {
index: record.index ?? null,
synthetic: record.synthetic ?? false,
label: record.label ?? null,
mode: record.mode ?? null,
terminalStatus: record.terminalStatus ?? null,
appServerExitCode: record.appServerExitCode ?? null,
appServerSignal: record.appServerSignal ?? null,
error: record.error ?? null,
stderrTail: textView(asString(record.stderrTail), full, 600),
startedAt: record.startedAt ?? null,
finishedAt: record.finishedAt ?? null,
startSeq: record.startSeq ?? null,
endSeq: record.endSeq ?? null,
execution: record.execution ?? null,
finalResponse: textView(asString(record.finalResponsePreview ?? record.finalResponse), full, 1200),
judge: record.judge ?? null,
runnerErrorClassification: record.runnerErrorClassification ?? null,
feedbackPrompt: textView(asString(record.feedbackPromptPreview), full, 800),
};
}
function renderTraceConsoleRows(summary: Record<string, unknown>, steps: Record<string, unknown>[]): string[] {
const rows: string[] = [];
const execution = asRecord(summary.execution) ?? {};
const stats = asRecord(execution.traceStats) ?? asRecord(summary.traceStats);
const statsSource = String(execution.statsSource || summary.statsSource || "");
const statsUsable = stats !== null && (statsSource === "oa-event-flow" || statsSource === "raw-trace-fallback" || stats.source === "oa-event-flow");
const stat = (key: string): string | number => {
if (!statsUsable) return "--";
const value = Number(stats[key]);
return Number.isFinite(value) && value >= 0 ? Math.floor(value) : "--";
};
rows.push([
`task=${summary.id ?? ""}`,
`status=${summary.status ?? ""}`,
`port=${summary.agentPort ?? "codex"}`,
`model=${summary.model ?? ""}`,
`updated=${summary.updatedAt ?? ""}`,
].filter((item) => !item.endsWith("=")).join(" "));
const read = stat("readCount");
const edit = stat("editCount");
const run = stat("runCount");
const toolCount = typeof read === "number" || typeof edit === "number" || typeof run === "number" ? Number(read === "--" ? 0 : read) + Number(edit === "--" ? 0 : edit) + Number(run === "--" ? 0 : run) : "--";
rows.push(`progressive steps=${steps.length} tools=${toolCount} read=${read} edit=${edit} run=${run} errors=${stat("errorCount")}`);
for (const step of steps) {
const head = [`#${step.seq ?? "?"}`, `[${step.label ?? traceKindLabel(step.kind)}]`, step.title ?? ""]
.filter((item) => String(item).length > 0)
.join(" ");
rows.push(`${head}${step.status ? ` (${step.status})` : ""}${step.duration && step.duration !== "--" ? ` ${step.duration}` : ""}`);
for (const line of stringList(step.summaryLines).slice(0, 4)) rows.push(` ${line}`);
}
return rows;
}
function compactProgressiveTrace(summaryBody: Record<string, unknown>, steps: Record<string, unknown>[], taskId: string, full: boolean): Record<string, unknown> {
const summary = asRecord(summaryBody.summary) ?? summaryBody;
return {
taskId: summary.id ?? taskId,
queueId: summary.queueId ?? null,
status: summary.status ?? null,
updatedAt: summary.updatedAt ?? null,
model: summary.model ?? null,
agentPort: summary.agentPort ?? null,
agentPortInfo: summary.agentPortInfo ?? null,
prompt: summary.prompt ?? null,
execution: summary.execution ?? null,
attempts: asArray(summary.attempts).map((attempt) => compactAttemptCycle(attempt, full)),
displayedStepSeqs: steps.map((step) => step.seq ?? null),
renderedRows: renderTraceConsoleRows(summary, steps),
};
}
function compactTracePage(body: Record<string, unknown>, taskId: string, limit: number, summaryBody: Record<string, unknown> | null, options: CodexTaskOptions): Record<string, unknown> {
const stepsSource = asArray(body.steps).length > 0 ? asArray(body.steps) : asArray(body.transcript).map(transcriptLineToStep);
const steps = stepsSource.map((step) => compactTraceStep(step, taskId));
const summary = summaryBody === null ? null : asRecord(summaryBody.summary) ?? summaryBody;
const nextAfterSeq = body.nextAfterSeq ?? null;
const previousBeforeSeq = body.previousBeforeSeq ?? null;
const omittedInPage = steps.some((item) => {
const line = asRecord(item) ?? {};
return asNumber(line.bodyOmittedLines, 0) > 0 || asNumber(line.commandOmittedLines, 0) > 0;
});
const hasRawSeqs = steps.some((item) => asArray(item.rawSeqs).length > 0);
return {
taskId: body.taskId ?? taskId,
queueId: body.queueId ?? null,
status: body.status ?? null,
updatedAt: body.updatedAt ?? null,
agentPort: body.agentPort ?? summary?.agentPort ?? null,
agentPortInfo: body.agentPortInfo ?? summary?.agentPortInfo ?? null,
mode: body.mode ?? null,
limit,
returned: steps.length,
total: body.total ?? null,
maxSeq: body.maxSeq ?? null,
afterSeq: body.afterSeq ?? null,
nextAfterSeq,
beforeSeq: body.beforeSeq ?? null,
previousBeforeSeq,
hasMore: body.hasMore ?? false,
hasBefore: body.hasBefore ?? false,
steps,
progressive: summaryBody === null ? null : compactProgressiveTrace(summaryBody, steps, taskId, options.full),
commands: {
next: body.hasMore === true && nextAfterSeq !== null ? `bun scripts/cli.ts codex task ${taskId} --trace --after-seq ${nextAfterSeq} --limit ${limit}` : null,
previous: body.hasBefore === true && previousBeforeSeq !== null ? `bun scripts/cli.ts codex task ${taskId} --trace --before-seq ${previousBeforeSeq} --limit ${limit}` : null,
tail: `bun scripts/cli.ts codex task ${taskId} --trace --tail --limit ${limit}`,
first: `bun scripts/cli.ts codex task ${taskId} --trace --from-start --limit ${limit}`,
stepDetailTemplate: `bun scripts/cli.ts microservice proxy code-queue /api/tasks/${taskId}/trace-step?seq=<seq> --raw`,
rawOutput: omittedInPage || hasRawSeqs ? `Use rawSeqs on each trace step, e.g. bun scripts/cli.ts codex output ${taskId} --after-seq <rawSeqBefore> --limit ${defaultOutputLimit}` : null,
},
};
}
function parseTaskOptions(args: string[]): CodexTaskOptions {
assertKnownOptions(args, {
flags: ["--detail", "--trace", "--tail", "--from-start", "--first", "--full", "--raw-summary"],
valueOptions: ["--before-seq", "--beforeSeq", "--after-seq", "--afterSeq", "--trace-limit", "--limit", "--tool-limit"],
}, "codex task");
const beforeSeq = nullablePositiveNumberOption(args, ["--before-seq", "--beforeSeq"]);
const afterSeq = nonNegativeNumberOption(args, ["--after-seq", "--afterSeq"], 0);
const fromStart = hasFlag(args, "--from-start") || hasFlag(args, "--first");
const trace = hasFlag(args, "--trace") || beforeSeq !== null || args.some((arg) => arg === "--after-seq" || arg === "--afterSeq") || fromStart || hasFlag(args, "--tail");
const traceMode = beforeSeq !== null ? "before" : fromStart || args.some((arg) => arg === "--after-seq" || arg === "--afterSeq") ? "after" : "tail";
const rawSummary = hasFlag(args, "--raw-summary");
return {
detail: hasFlag(args, "--detail") || rawSummary,
trace,
traceLimit: positiveIntegerOption(args, ["--trace-limit", "--limit"], defaultTraceLimit, maxTraceLimit),
traceMode,
afterSeq,
beforeSeq,
toolLimit: positiveIntegerOption(args, ["--tool-limit"], defaultToolLimit, 500),
full: hasFlag(args, "--full") || hasFlag(args, "--raw-summary"),
rawSummary,
};
}
function parseOutputOptions(args: string[]): CodexOutputOptions {
assertKnownOptions(args, {
flags: ["--tail", "--from-start", "--first", "--full-text", "--raw"],
valueOptions: ["--before-seq", "--beforeSeq", "--after-seq", "--afterSeq", "--limit", "--max-text-chars"],
}, "codex output");
const beforeSeq = nullablePositiveNumberOption(args, ["--before-seq", "--beforeSeq"]);
const afterSeq = nonNegativeNumberOption(args, ["--after-seq", "--afterSeq"], 0);
const fromStart = hasFlag(args, "--from-start") || hasFlag(args, "--first");
const mode = beforeSeq !== null ? "before" : fromStart || args.some((arg) => arg === "--after-seq" || arg === "--afterSeq") ? "after" : "tail";
const fullText = hasFlag(args, "--full-text") || hasFlag(args, "--raw");
const requestedLimit = positiveIntegerOption(args, ["--limit"], defaultOutputLimit, maxTraceLimit);
return {
requestedLimit,
limit: fullText ? requestedLimit : Math.min(requestedLimit, defaultOutputLimit),
mode,
afterSeq,
beforeSeq,
fullText,
maxTextChars: positiveIntegerOption(args, ["--max-text-chars"], defaultOutputPreviewChars, fullText ? 500_000 : maxOutputPreviewChars),
};
}
function parseTasksOptions(args: string[]): CodexTasksOptions {
assertKnownOptions(args, {
flags: ["--unread-only", "--unread", "--full", "--all"],
valueOptions: ["--queue", "--queue-id", "--limit", "--status", "--view", "--before-id", "--beforeId"],
}, "codex tasks");
const viewValue = optionValue(args, ["--view"]) ?? "supervisor";
if (viewValue !== "supervisor" && viewValue !== "full") throw new Error(`--view must be supervisor or full; got ${viewValue}`);
const statusRaw = optionValue(args, ["--status"]);
const statusFilter = statusRaw === undefined
? null
: statusRaw.split(/[,\s]+/u).map((item) => item.trim()).filter(Boolean);
if (statusFilter !== null) {
const supported = new Set(["queued", "running", "judging", "retry_wait", "succeeded", "failed", "canceled"]);
const unsupported = statusFilter.filter((status) => !supported.has(status));
if (unsupported.length > 0) throw new Error(`unsupported --status value: ${unsupported.join(", ")}; supported: ${Array.from(supported).join(", ")}`);
}
const requestedLimit = positiveIntegerOption(args, ["--limit"], defaultTasksLimit);
return {
queueId: optionValue(args, ["--queue", "--queue-id"]),
requestedLimit,
limit: Math.min(requestedLimit, maxTasksLimit),
beforeId: optionValue(args, ["--before-id", "--beforeId"]),
unreadOnly: hasFlag(args, "--unread-only") || hasFlag(args, "--unread"),
statusFilter,
view: hasFlag(args, "--full") || hasFlag(args, "--all") ? "full" : viewValue,
};
}
function normalizeRepoFilter(value: string | undefined): string | undefined {
if (value === undefined) return undefined;
const trimmed = value.trim()
.replace(/^https?:\/\/github\.com\//iu, "")
.replace(/\.git$/iu, "")
.replace(/^\/+|\/+$/gu, "");
if (!/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/u.test(trimmed)) {
throw new Error(`--repo must be owner/name; got ${value}`);
}
return trimmed;
}
function normalizeIssueFilter(value: string | undefined): string | undefined {
if (value === undefined) return undefined;
const trimmed = value.trim().replace(/^#/u, "");
const number = Number(trimmed);
if (!Number.isInteger(number) || number <= 0) throw new Error(`--issue must be a positive issue number; got ${value}`);
return `#${number}`;
}
function parseUnreadOptions(args: string[]): CodexUnreadOptions {
const first = args[0];
const hasSubcommand = first !== undefined && !first.startsWith("--");
const subcommand = hasSubcommand ? first : "summary";
if (subcommand !== "summary" && subcommand !== "list" && subcommand !== "mark-read") {
throw new Error(`codex unread subcommand must be summary, list, or mark-read; got ${subcommand}`);
}
const optionArgs = hasSubcommand ? args.slice(1) : args;
assertKnownOptions(optionArgs, {
flags: ["--mark-read", "--confirm", "--dry-run"],
valueOptions: ["--queue", "--queue-id", "--limit", "--status", "--repo", "--issue", "--before-id", "--beforeId"],
}, "codex unread");
const statusRaw = optionValue(optionArgs, ["--status"]);
const statusFilter = statusRaw === undefined
? null
: statusRaw.split(/[,\s]+/u).map((item) => item.trim()).filter(Boolean);
if (statusFilter !== null) {
const supported = new Set(["succeeded", "failed", "canceled"]);
const unsupported = statusFilter.filter((status) => !supported.has(status));
if (unsupported.length > 0) throw new Error(`unsupported --status value for codex unread: ${unsupported.join(", ")}; supported terminal statuses: ${Array.from(supported).join(", ")}`);
}
const requestedLimit = positiveIntegerOption(optionArgs, ["--limit"], defaultTasksLimit);
const action: CodexUnreadAction = subcommand === "mark-read" || hasFlag(optionArgs, "--mark-read") ? "mark-read" : "summary";
const explicitDryRun = hasFlag(optionArgs, "--dry-run");
return {
queueId: optionValue(optionArgs, ["--queue", "--queue-id"]),
requestedLimit,
limit: Math.min(requestedLimit, maxTasksLimit),
beforeId: optionValue(optionArgs, ["--before-id", "--beforeId"]),
statusFilter,
repoFilter: normalizeRepoFilter(optionValue(optionArgs, ["--repo"])),
issueFilter: normalizeIssueFilter(optionValue(optionArgs, ["--issue"])),
action,
confirm: hasFlag(optionArgs, "--confirm"),
dryRun: explicitDryRun || action === "summary",
};
}
function parseQueuesOptions(args: string[]): CodexQueuesOptions {
assertKnownOptions(args, {
flags: ["--full", "--all"],
valueOptions: ["--limit", "--offset", "--page"],
}, "codex queues");
const limit = positiveIntegerOption(args, ["--limit"], defaultQueuesLimit, maxTasksLimit);
const page = positiveIntegerOption(args, ["--page"], 1);
const offsetExplicit = args.includes("--offset");
const offset = offsetExplicit ? nonNegativeIntegerOption(args, ["--offset"], 0) : (page - 1) * limit;
return {
full: hasFlag(args, "--full") || hasFlag(args, "--all"),
limit,
offset,
page: Math.floor(offset / limit) + 1,
};
}
function parsePrPreflightOptions(args: string[]): CodexPrPreflightOptions {
assertKnownOptions(args, {
flags: ["--remote", "--push-dry-run", "--pushDryRun", "--pr-create-dry-run", "--prCreateDryRun", "--full", "--raw"],
valueOptions: ["--push-dry-run-ref", "--pushDryRunRef", "--pr-create-dry-run-head", "--prCreateDryRunHead", "--issue", "--issue-number", "--issueNumber"],
}, "codex pr-preflight");
return {
remote: hasFlag(args, "--remote"),
pushDryRun: hasFlag(args, "--push-dry-run") || hasFlag(args, "--pushDryRun"),
pushDryRunRef: optionValue(args, ["--push-dry-run-ref", "--pushDryRunRef"]),
prCreateDryRun: hasFlag(args, "--pr-create-dry-run") || hasFlag(args, "--prCreateDryRun"),
prCreateDryRunHead: optionValue(args, ["--pr-create-dry-run-head", "--prCreateDryRunHead"]),
issueNumber: nullablePositiveNumberOption(args, ["--issue", "--issue-number", "--issueNumber"]),
full: hasFlag(args, "--full") || hasFlag(args, "--raw"),
};
}
function parseSkillsSyncOptions(args: string[]): CodexSkillsSyncOptions {
assertKnownOptions(args, {
flags: ["--dry-run", "--dryRun", "--full", "--raw"],
}, "codex skills-sync");
const dryRun = hasFlag(args, "--dry-run") || hasFlag(args, "--dryRun");
return {
dryRun,
full: hasFlag(args, "--full") || hasFlag(args, "--raw"),
};
}
function parseJudgeOptions(args: string[]): CodexJudgeOptions {
assertKnownOptions(args, {
flags: ["--dry-run", "--no-call", "--include-prompt"],
valueOptions: ["--attempt", "--attempt-id", "--attemptIndex"],
}, "codex judge");
const rawAttempt = optionValue(args, ["--attempt", "--attempt-id", "--attemptIndex"]) ?? positionalArgs(args)[0];
let attempt: number | null = null;
if (rawAttempt !== undefined) {
const value = Number(rawAttempt);
if (!Number.isInteger(value) || value <= 0) throw new Error("--attempt must be a positive integer");
attempt = value;
}
return {
attempt,
dryRun: hasFlag(args, "--dry-run") || hasFlag(args, "--no-call"),
includePrompt: hasFlag(args, "--include-prompt"),
};
}
function queryString(params: Record<string, string | number | boolean | null | undefined>): string {
const search = new URLSearchParams();
for (const [key, value] of Object.entries(params)) {
if (value !== undefined && value !== null) search.set(key, String(value));
}
const text = search.toString();
return text.length > 0 ? `?${text}` : "";
}
function codexTaskSummary(taskId: string, options: CodexTaskOptions, fetcher: CodexResponseFetcher): unknown {
const summaryPath = codeQueueProxyPath(`/api/tasks/${encodeURIComponent(taskId)}/summary${queryString({ toolLimit: options.toolLimit })}`);
const summaryResponse = unwrapCodexResponse(fetcher(summaryPath));
const summary = summaryResponse.body.summary;
const result: Record<string, unknown> = {
upstream: summaryResponse.upstream,
summary: options.detail ? compactSummary(summary, options, taskId) : compactReviewSummary(summary, options, taskId),
};
if (options.rawSummary) result.rawSummary = summary;
if (options.trace) {
const traceParams: Record<string, string | number | boolean | null> = { limit: options.traceLimit };
if (options.traceMode === "tail") traceParams.tail = 1;
if (options.traceMode === "after") traceParams.afterSeq = options.afterSeq;
if (options.traceMode === "before") traceParams.beforeSeq = options.beforeSeq;
const traceSummaryResponse = unwrapCodexResponse(fetcher(codeQueueProxyPath(`/api/tasks/${encodeURIComponent(taskId)}/trace-summary`)));
const traceResponse = unwrapCodexResponse(fetcher(codeQueueProxyPath(`/api/tasks/${encodeURIComponent(taskId)}/trace-steps${queryString(traceParams)}`)));
result.trace = compactTracePage(traceResponse.body, taskId, options.traceLimit, traceSummaryResponse.body, options);
}
return result;
}
function compactOutputRecord(item: unknown, options: CodexOutputOptions): Record<string, unknown> {
const record = asRecord(item) ?? {};
const text = textView(asString(record.text), options.fullText, options.maxTextChars);
return {
seq: record.seq ?? null,
at: record.at ?? null,
channel: record.channel ?? null,
method: record.method ?? null,
itemId: record.itemId ?? null,
text: text.text,
textChars: text.chars,
...(text.truncated ? { textTruncated: true, textOmittedChars: text.omittedChars } : {}),
};
}
function compactOutputPage(body: Record<string, unknown>, taskId: string, options: CodexOutputOptions): Record<string, unknown> {
const output = asArray(body.output).map((item) => compactOutputRecord(item, options));
const nextAfterSeq = body.nextAfterSeq ?? null;
const previousBeforeSeq = body.previousBeforeSeq ?? null;
return {
taskId: body.taskId ?? taskId,
queueId: body.queueId ?? null,
status: body.status ?? null,
updatedAt: body.updatedAt ?? null,
mode: body.mode ?? null,
requestedLimit: options.requestedLimit,
limit: options.limit,
returned: output.length,
total: body.total ?? null,
maxSeq: body.maxSeq ?? null,
afterSeq: body.afterSeq ?? null,
nextAfterSeq,
beforeSeq: body.beforeSeq ?? null,
previousBeforeSeq,
hasMore: body.hasMore ?? false,
hasBefore: body.hasBefore ?? false,
disclosure: {
defaultPolicy: "bounded output rows and bounded text previews; use --full-text with an explicit seq window only when raw text is required",
limitCapped: !options.fullText && options.limit < options.requestedLimit,
fullText: options.fullText,
textPreviewChars: options.maxTextChars,
requestedLimit: options.requestedLimit,
effectiveLimit: options.limit,
},
output,
commands: {
next: body.hasMore === true && nextAfterSeq !== null ? `bun scripts/cli.ts codex output ${taskId} --after-seq ${nextAfterSeq} --limit ${options.limit}` : null,
previous: body.hasBefore === true && previousBeforeSeq !== null ? `bun scripts/cli.ts codex output ${taskId} --before-seq ${previousBeforeSeq} --limit ${options.limit}` : null,
tail: `bun scripts/cli.ts codex output ${taskId} --tail --limit ${options.limit}`,
first: `bun scripts/cli.ts codex output ${taskId} --from-start --limit ${options.limit}`,
fullText: `bun scripts/cli.ts codex output ${taskId} --after-seq <rawSeqBefore> --limit ${Math.min(options.requestedLimit, defaultOutputLimit)} --full-text`,
},
};
}
function codexTaskOutput(taskId: string, options: CodexOutputOptions, fetcher: CodexResponseFetcher): unknown {
const params: Record<string, string | number | boolean | null> = {
limit: options.limit,
fullText: options.fullText ? 1 : 0,
maxTextChars: options.maxTextChars,
};
if (options.mode === "tail") params.tail = 1;
if (options.mode === "after") params.afterSeq = options.afterSeq;
if (options.mode === "before") params.beforeSeq = options.beforeSeq;
const response = unwrapCodexResponse(fetcher(codeQueueProxyPath(`/api/tasks/${encodeURIComponent(taskId)}/output${queryString(params)}`)));
return { upstream: response.upstream, outputPage: compactOutputPage(response.body, taskId, options) };
}
function codexTaskJudge(taskId: string, options: CodexJudgeOptions, fetcher: CodexResponseFetcher): unknown {
const params = queryString({
attempt: options.attempt,
dryRun: options.dryRun ? 1 : undefined,
includePrompt: options.includePrompt ? 1 : undefined,
});
const response = unwrapCodexResponse(fetcher(codeQueueProxyPath(`/api/tasks/${encodeURIComponent(taskId)}/judge${params}`), { method: "POST" }));
return { upstream: response.upstream, judgeReplay: response.body };
}
export function codexTaskQuery(taskId: string, optionArgs: string[], fetcher: CodexResponseFetcher = coreInternalFetch): unknown {
return codexTaskSummary(taskId, parseTaskOptions(optionArgs), fetcher);
}
export function codexOutputQuery(taskId: string, optionArgs: string[], fetcher: CodexResponseFetcher = coreInternalFetch): unknown {
return codexTaskOutput(taskId, parseOutputOptions(optionArgs), fetcher);
}
export function codexJudgeQuery(taskId: string, optionArgs: string[], fetcher: CodexResponseFetcher = coreInternalFetch): unknown {
return codexTaskJudge(taskId, parseJudgeOptions(optionArgs), fetcher);
}
export function codexSteerTaskForTest(taskId: string, optionArgs: string[], fetcher: CodexResponseFetcher): unknown {
return codexSteerTask(taskId, optionArgs, fetcher);
}
export function codexSteerTraceConfirmForTest(taskId: string, optionArgs: string[], fetcher: CodexResponseFetcher): unknown {
return codexSteerTraceConfirm(taskId, optionArgs, fetcher);
}
function isTerminalTaskStatus(status: unknown): boolean {
return status === "succeeded" || status === "failed" || status === "canceled";
}
function isActiveTaskStatus(status: unknown): boolean {
return status === "running" || status === "judging";
}
function taskStatusRank(status: unknown): number {
if (status === "running") return 0;
if (status === "judging") return 1;
if (status === "retry_wait") return 2;
if (status === "queued") return 3;
if (status === "succeeded") return 9;
if (status === "failed") return 10;
if (status === "canceled") return 11;
return 99;
}
function taskTimelineMs(task: Record<string, unknown>): number {
const value = asString(task.finishedAt ?? task.updatedAt ?? task.createdAt);
const timestamp = Date.parse(value);
return Number.isFinite(timestamp) ? timestamp : 0;
}
function taskOverviewCandidateKey(task: Record<string, unknown>): string {
return asString(task.id);
}
function taskUnreadTerminal(task: Record<string, unknown>): boolean {
const directUnread = task.terminalUnread ?? task.unreadTerminal ?? task.unread;
if (typeof directUnread === "boolean") return directUnread;
const status = asString(task.status);
const readAt = task.readAt;
return isTerminalTaskStatus(status) && (readAt === null || readAt === undefined || readAt === "");
}
function taskQueuedRunnable(task: Record<string, unknown>): boolean {
const status = asString(task.status);
if (status === "queued" || status === "retry_wait") return true;
return asRecord(task.queuedReason)?.code === "ready";
}
function taskIssueRefs(task: Record<string, unknown>, summary: Record<string, unknown> | null): string[] {
const text = [
asString(task.displayPrompt),
asString(task.basePrompt),
asString(task.prompt),
asString(summary?.initialPrompt),
asString(summary?.basePrompt),
asString(summary?.prompt),
asString(summary?.lastError),
asString(task.lastError),
].join("\n");
return Array.from(new Set(Array.from(text.matchAll(/#(\d{1,6})\b/gu)).map((match) => `#${match[1]}`))).slice(0, 8);
}
function taskClassification(task: Record<string, unknown>, summary: Record<string, unknown> | null): {
kind: CodexTasksSupervisorEntry["kind"];
labels: string[];
managementNoise: boolean;
reason: string;
} {
const text = [
asString(task.displayPrompt),
asString(task.basePrompt),
asString(task.prompt),
asString(task.lastError),
asString(summary?.lastError),
asString(asRecord(summary?.lastAssistantMessage)?.text),
].join("\n").toLowerCase();
const matches = (pattern: RegExp): boolean => pattern.test(text);
const labels: string[] = [];
if (matches(/\b(?:gate|report|aggregator|runbook|contract|audit|review|brief|evidence|diagnostic|observability|visibility|preflight|smoke)\b|报告|审查|汇总|观测|诊断|预检|门禁/iu)) labels.push("management-or-verification");
if (matches(/\b(?:deploy|deployment|prod|dev|release|artifact|ci|cd)\b|部署|发布|上线/iu)) labels.push("deployment");
if (matches(/\b(?:fix|bug|repair|implement|feature|ui|frontend|backend|api|database|db|workbench|patch-panel|box-simu|gateway-simu)\b|修复|实现|用户|工作台|接线|仿真|数据库/iu)) labels.push("direct-work");
if (matches(/\b(?:doc|docs|reference|markdown)\b|文档|参考/iu)) labels.push("documentation");
if (labels.length === 0) labels.push("uncategorized");
if (labels.includes("management-or-verification") && !labels.includes("direct-work") && !labels.includes("deployment")) {
return { kind: "management-noise", labels, managementNoise: true, reason: "matched report/gate/review/diagnostic terms without direct implementation or deployment terms" };
}
if (labels.includes("deployment")) {
return { kind: "deployment-fix", labels, managementNoise: labels.includes("management-or-verification") && !labels.includes("direct-work"), reason: "matched deployment or artifact terms" };
}
if (labels.includes("direct-work")) {
return { kind: "direct-progress", labels, managementNoise: false, reason: "matched implementation, user-visible, runtime, or repair terms" };
}
if (labels.includes("management-or-verification")) {
return { kind: "verification", labels, managementNoise: true, reason: "matched verification/report terms; keep folded unless it blocks real work" };
}
if (labels.includes("documentation")) {
return { kind: "documentation", labels, managementNoise: false, reason: "matched documentation terms" };
}
return { kind: "unknown", labels, managementNoise: false, reason: "no strong classifier term matched" };
}
function supervisorLastMessage(summaryLastAssistant: unknown, maxChars: number): SupervisorMessageSummary | null {
if (summaryLastAssistant === undefined || summaryLastAssistant === null) return null;
const record = asRecord(summaryLastAssistant) ?? {};
const text = asString(record.text);
return {
at: record.at ?? null,
source: record.source ?? "none",
...supervisorTextSummary(text, maxChars),
};
}
const awaitingTerminalJudgeHint = "finalResponse is visible while task status is non-terminal; wait for terminal status and judge before closeout.";
function finalResponseAwaitingTerminalStatus(status: string | null, summaryLastAssistant: unknown): {
label: string;
state: "awaiting-terminal-or-judge" | "awaiting-judge";
finalResponseAt: unknown;
} | null {
if (status !== "running" && status !== "judging") return null;
const record = asRecord(summaryLastAssistant);
if (record === null) return null;
if (asString(record.source) !== "finalResponse") return null;
if (asString(record.text).trim().length === 0) return null;
return {
label: status === "judging" ? "judging (awaiting judge)" : "running (awaiting terminal/judge)",
state: status === "judging" ? "awaiting-judge" : "awaiting-terminal-or-judge",
finalResponseAt: record.at ?? null,
};
}
function taskWatchEntry(task: Record<string, unknown>, summary: Record<string, unknown> | null): CodexTasksEntry {
const taskId = asString(task.id);
const summaryCommands = summary === null ? null : asRecord(summary.commands);
const summaryLastAssistant = summary?.lastAssistantMessage ?? task.lastAssistantMessage;
const status = asString(task.status) || null;
const awaitingStatus = finalResponseAwaitingTerminalStatus(status, summaryLastAssistant);
const promptPreview = textPreview(asString(task.displayPrompt ?? task.basePrompt ?? task.prompt), 360);
const showCommand = typeof summary?.cliHint === "string" && summary.cliHint.length > 0
? summary.cliHint
: `bun scripts/cli.ts codex task ${taskId}`;
const traceCommand = typeof summary?.traceHint === "string" && summary.traceHint.length > 0
? summary.traceHint
: `bun scripts/cli.ts codex task ${taskId} --trace --tail --limit ${defaultTraceLimit}`;
const outputCommand = `bun scripts/cli.ts codex output ${taskId} --tail --limit ${defaultOutputLimit}`;
const steerCommand = `bun scripts/cli.ts codex steer ${taskId} --prompt-file <path>`;
return {
taskId,
queueId: asString(task.queueId) || null,
status,
statusLabel: awaitingStatus?.label ?? status,
...(awaitingStatus === null ? {} : {
awaitingTerminalJudge: true,
closeoutState: awaitingStatus.state,
closeoutHint: awaitingTerminalJudgeHint,
finalResponseAt: awaitingStatus.finalResponseAt,
}),
currentAttempt: typeof task.currentAttempt === "number" && Number.isFinite(task.currentAttempt) ? task.currentAttempt : null,
updatedAt: asString(task.updatedAt) || null,
finishedAt: asString(task.finishedAt) || null,
readAt: asString(task.readAt) || null,
unread: taskUnreadTerminal(task),
unreadTerminal: taskUnreadTerminal(task),
promptPreview,
queuedReason: compactQueuedReason(task.queuedReason),
lastAssistantMessage: summaryLastAssistant === undefined || summaryLastAssistant === null ? null : compactLastAssistant(summaryLastAssistant, false),
commands: {
show: typeof summaryCommands?.show === "string" && summaryCommands.show.length > 0 ? summaryCommands.show : showCommand,
trace: typeof summaryCommands?.trace === "string" && summaryCommands.trace.length > 0 ? summaryCommands.trace : traceCommand,
output: outputCommand,
steer: steerCommand,
read: `bun scripts/cli.ts codex read ${taskId}`,
full: `bun scripts/cli.ts codex task ${taskId} --full`,
detail: `bun scripts/cli.ts codex task ${taskId} --detail`,
},
};
}
function taskSupervisorEntry(task: Record<string, unknown>, summary: Record<string, unknown> | null, bodyPreviewChars = supervisorBodyPreviewChars): CodexTasksSupervisorEntry {
const taskId = asString(task.id);
const summaryLastAssistant = summary?.lastAssistantMessage ?? task.lastAssistantMessage;
const status = asString(task.status) || null;
const awaitingStatus = finalResponseAwaitingTerminalStatus(status, summaryLastAssistant);
const unreadTerminal = taskUnreadTerminal(task);
const classification = taskClassification(task, summary);
const queuedReason = compactQueuedReason(task.queuedReason);
const prompt = supervisorTextSummary(asString(task.displayPrompt ?? task.basePrompt ?? task.prompt), supervisorPromptPreviewChars);
const lastMessage = supervisorLastMessage(summaryLastAssistant, bodyPreviewChars);
return {
id: taskId,
queue: asString(task.queueId) || null,
status,
...(awaitingStatus === null ? {} : {
statusLabel: awaitingStatus.label,
awaitingTerminalJudge: true,
closeoutState: awaitingStatus.state,
closeoutHint: awaitingTerminalJudgeHint,
finalResponseAt: awaitingStatus.finalResponseAt,
}),
attempt: typeof task.currentAttempt === "number" && Number.isFinite(task.currentAttempt) ? task.currentAttempt : null,
updatedAt: asString(task.updatedAt) || null,
...(isTerminalTaskStatus(status) ? { finishedAt: asString(task.finishedAt) || null, unreadTerminal } : {}),
issues: taskIssueRefs(task, summary),
kind: classification.kind,
...(classification.managementNoise ? { noise: true } : {}),
prompt: prompt.text,
promptChars: prompt.chars,
...(prompt.truncated ? { promptTruncated: true } : {}),
...(lastMessage === null ? {} : {
last: lastMessage.text,
lastAt: lastMessage.at,
lastChars: lastMessage.chars,
...(lastMessage.truncated ? { lastTruncated: true } : {}),
}),
...(queuedReason === null ? {} : { queuedReason }),
...(unreadTerminal ? { read: `bun scripts/cli.ts codex read ${taskId}` } : {}),
};
}
function buildTaskWatchSection(
tasks: Record<string, unknown>[],
summaries: Map<string, Record<string, unknown>>,
limit: number,
nextCommand: string | null,
fullCommand: string,
): CodexTasksSection {
const visibleTasks = tasks.slice(0, limit);
const items = visibleTasks.map((task) => taskWatchEntry(task, summaries.get(taskOverviewCandidateKey(task)) ?? null));
const truncated = tasks.length > limit;
return {
count: tasks.length,
returned: items.length,
truncated,
hasMore: truncated,
commands: {
next: truncated ? nextCommand : null,
full: fullCommand,
},
items,
};
}
function buildSupervisorTaskSection(
tasks: Record<string, unknown>[],
summaries: Map<string, Record<string, unknown>>,
limit: number,
nextCommand: string | null,
fullCommand: string,
bodyPreviewChars = supervisorBodyPreviewChars,
): CodexTasksSection<CodexTasksSupervisorEntry> {
const visibleTasks = tasks.slice(0, limit);
const items = visibleTasks.map((task) => taskSupervisorEntry(task, summaries.get(taskOverviewCandidateKey(task)) ?? null, bodyPreviewChars));
const truncated = tasks.length > limit;
const commands = {
next: truncated || nextCommand !== null ? nextCommand : null,
full: fullCommand,
...(items.length === 0 ? {} : {
showTemplate: "bun scripts/cli.ts codex task <taskId>",
detailTemplate: "bun scripts/cli.ts codex task <taskId> --detail",
traceTemplate: `bun scripts/cli.ts codex task <taskId> --trace --tail --limit ${defaultTraceLimit}`,
outputTemplate: `bun scripts/cli.ts codex output <taskId> --tail --limit ${defaultOutputLimit}`,
taskFullTemplate: "bun scripts/cli.ts codex task <taskId> --full",
readTemplate: "bun scripts/cli.ts codex read <taskId>",
}),
};
return {
count: tasks.length,
returned: items.length,
truncated,
hasMore: truncated || nextCommand !== null,
commands,
items,
};
}
function collectTaskWatchDegraded(summaryErrors: Array<{ taskId: string; message: string }>, omittedTaskCount = 0): CodexTasksDegraded | null {
if (summaryErrors.length === 0 && omittedTaskCount === 0) return null;
return {
summaryFetchFailedTaskIds: summaryErrors.map((error) => error.taskId),
summaryFetchErrorCount: summaryErrors.length,
summaryFetchOmittedTaskCount: omittedTaskCount,
reason: summaryErrors.length > 0
? "task summary fetch failed for one or more entries; unread state still comes from task-level overview data"
: "task summary fetch was intentionally omitted for bounded full view; use commands.show for per-task detail",
};
}
function sortRunningWatchTasks(tasks: Record<string, unknown>[]): Record<string, unknown>[] {
return [...tasks]
.filter((task) => isActiveTaskStatus(asString(task.status)))
.sort((left, right) => {
const rankDelta = taskStatusRank(asString(left.status)) - taskStatusRank(asString(right.status));
if (rankDelta !== 0) return rankDelta;
const timeDelta = taskTimelineMs(right) - taskTimelineMs(left);
if (timeDelta !== 0) return timeDelta;
return asString(left.id).localeCompare(asString(right.id));
});
}
function sortCompletedWatchTasks(tasks: Record<string, unknown>[]): Record<string, unknown>[] {
return [...tasks]
.filter((task) => isTerminalTaskStatus(asString(task.status)))
.sort((left, right) => {
const timeDelta = taskTimelineMs(right) - taskTimelineMs(left);
if (timeDelta !== 0) return timeDelta;
return asString(left.id).localeCompare(asString(right.id));
});
}
function sortQueuedWatchTasks(tasks: Record<string, unknown>[]): Record<string, unknown>[] {
return [...tasks]
.filter((task) => taskQueuedRunnable(task))
.sort((left, right) => {
const rankDelta = taskStatusRank(asString(left.status)) - taskStatusRank(asString(right.status));
if (rankDelta !== 0) return rankDelta;
const timeDelta = taskTimelineMs(left) - taskTimelineMs(right);
if (timeDelta !== 0) return timeDelta;
return asString(left.id).localeCompare(asString(right.id));
});
}
function taskMatchesStatusFilter(task: Record<string, unknown>, statusFilter: string[] | null): boolean {
return statusFilter === null || statusFilter.includes(asString(task.status));
}
function filterTasksForOptions(tasks: Record<string, unknown>[], options: CodexTasksOptions): Record<string, unknown>[] {
return tasks
.filter((task) => options.queueId === undefined || asString(task.queueId) === options.queueId)
.filter((task) => taskMatchesStatusFilter(task, options.statusFilter))
.filter((task) => !options.unreadOnly || taskUnreadTerminal(task));
}
function baseTaskListOptions(options: CodexTasksOptions): CodexTasksOptions {
return {
queueId: options.queueId,
requestedLimit: options.requestedLimit,
limit: options.limit,
beforeId: options.beforeId,
unreadOnly: options.unreadOnly,
statusFilter: options.statusFilter,
view: options.view,
};
}
function taskListCommand(options: CodexTasksOptions, extra: string[] = []): string {
const args = ["codex", "tasks"];
if (options.view !== "supervisor") args.push("--view", options.view);
if (options.queueId !== undefined) args.push("--queue", options.queueId);
if (options.unreadOnly) args.push("--unread");
if (options.statusFilter !== null) args.push("--status", options.statusFilter.join(","));
if (options.requestedLimit !== defaultTasksLimit) args.push("--limit", String(options.requestedLimit));
if (options.beforeId !== undefined) args.push("--before-id", options.beforeId);
args.push(...extra);
return `bun scripts/cli.ts ${args.join(" ")}`;
}
function codexTasksLimitDisclosure(options: CodexTasksOptions): Record<string, unknown> {
return {
requestedLimit: options.requestedLimit,
effectiveLimit: options.limit,
maxLimit: maxTasksLimit,
limitCapped: options.requestedLimit > options.limit,
};
}
function codexTasksSourceDisclosure(pagination: Record<string, unknown>): Record<string, unknown> {
const effectiveLimit = asNumber(pagination.limit, 0) || null;
return {
endpoint: "/api/tasks/overview",
requestedLimit: tasksOverviewSourceFetchLimit,
fetchLimit: tasksOverviewSourceFetchLimit,
limit: effectiveLimit,
effectiveLimit,
limitCapped: effectiveLimit !== null && effectiveLimit < tasksOverviewSourceFetchLimit,
returned: asNumber(pagination.returned, 0) || null,
total: asNumber(pagination.total, 0) || null,
hasMore: asBoolean(pagination.hasMore),
nextBeforeId: asString(pagination.nextBeforeId) || null,
includeActive: asBoolean(pagination.includeActive),
};
}
function taskSectionLimit(options: CodexTasksOptions, maxReturned = supervisorSectionReturnedLimit): number {
return Math.min(options.limit, maxReturned);
}
function sectionNextCommand(
tasks: Record<string, unknown>[],
limit: number,
options: CodexTasksOptions,
sourceNextCommand: string | null,
): string | null {
if (tasks.length > limit) {
const lastVisibleTask = tasks[limit - 1];
const beforeId = lastVisibleTask === undefined ? "" : taskOverviewCandidateKey(lastVisibleTask);
if (beforeId.length > 0) return taskListCommand({ ...options, beforeId });
}
return sourceNextCommand;
}
function countRecordValues(value: unknown): Record<string, number> {
const record = asRecord(value);
const counts: Record<string, number> = {};
if (record === null) return counts;
for (const [status, rawCount] of Object.entries(record)) {
const count = typeof rawCount === "number" ? rawCount : typeof rawCount === "string" ? Number(rawCount) : Number.NaN;
if (Number.isFinite(count) && count >= 0) counts[status] = Math.floor(count);
}
return counts;
}
function queueSummaryCountsForOptions(taskPage: CodexTasksTaskPage, options: CodexTasksOptions): SupervisorStatusCounts | null {
const queue = taskPage.queue;
if (queue === null) return null;
if (options.queueId !== undefined) {
for (const row of asArray(queue.queues)) {
const record = asRecord(row);
if (record === null || asString(record.id) !== options.queueId) continue;
if (asRecord(record.counts) === null) return null;
return {
counts: countRecordValues(record.counts),
exact: true,
source: "queue-summary-counts",
scope: "queue",
queueId: options.queueId,
};
}
return null;
}
if (asRecord(queue.counts) === null) return null;
return {
counts: countRecordValues(queue.counts),
exact: true,
source: "queue-summary-counts",
scope: "all-queues",
queueId: null,
};
}
function fallbackStatusCountsForOptions(taskPage: CodexTasksTaskPage, options: CodexTasksOptions): SupervisorStatusCounts {
const counts: Record<string, number> = {};
for (const task of taskPage.tasks) {
if (options.queueId !== undefined && asString(task.queueId) !== options.queueId) continue;
const status = asString(task.status);
if (status.length === 0) continue;
counts[status] = (counts[status] ?? 0) + 1;
}
return {
counts,
exact: false,
source: "overview-page-fallback",
scope: options.queueId === undefined ? "all-queues" : "queue",
queueId: options.queueId ?? null,
};
}
function statusCountsForOptions(taskPage: CodexTasksTaskPage, options: CodexTasksOptions): SupervisorStatusCounts {
return queueSummaryCountsForOptions(taskPage, options) ?? fallbackStatusCountsForOptions(taskPage, options);
}
function positiveCount(value: unknown): number | null {
const count = asNumber(value, Number.NaN);
return Number.isFinite(count) && count >= 0 ? Math.floor(count) : null;
}
function runtimeMaxActiveQueues(taskPage: CodexTasksTaskPage): number | null {
const value = positiveCount(taskPage.queue?.maxActiveQueues);
return value !== null && value > 0 ? value : null;
}
function activeRunningRedlineState(activeCount: number, hardRedline: number, burstRedline: number, routineTarget: number): string {
if (activeCount >= hardRedline) return "at-or-over-hard-redline";
if (activeCount >= burstRedline) return "burst-redline";
if (activeCount >= routineTarget) return "above-routine-target";
return "below-routine-target";
}
function supervisorActiveRunningSummary(
taskPage: CodexTasksTaskPage,
options: CodexTasksOptions,
runningSection: CodexTasksSection<CodexTasksSupervisorEntry>,
diagnostics: Record<string, unknown> | null,
): Record<string, unknown> {
const statusCounts = statusCountsForOptions(taskPage, options);
const runningCount = statusCounts.counts.running ?? 0;
const judgingCount = statusCounts.counts.judging ?? 0;
const activeStatusCount = runningCount + judgingCount;
const heartbeatActiveCount = positiveCount(diagnostics?.activeHeartbeatCount);
const schedulerLocalActiveRunSlotCount = positiveCount(diagnostics?.schedulerActiveRunSlotCount);
const effectiveActiveRunnerCount = Math.max(activeStatusCount, heartbeatActiveCount ?? 0, schedulerLocalActiveRunSlotCount ?? 0);
const policy = submitPolicyContract().concurrency;
const routineTarget = policy.gpt55Routine;
const burstRedline = Math.max(policy.gpt55BurstMax, policy.minimaxSimpleMax);
const hardRedline = 15;
const runtimeLimit = runtimeMaxActiveQueues(taskPage);
const redlineState = activeRunningRedlineState(activeStatusCount, hardRedline, burstRedline, routineTarget);
const exactInterpretation = statusCounts.exact
? "activeRunning.count is exact from queue status counts; row pagination does not change this count"
: "activeRunning.count is page-scoped because queue status counts were absent; do not use it for commander redline decisions without a queue summary/raw cross-check";
const baseOptions = baseTaskListOptions({ ...options, beforeId: undefined, unreadOnly: false, statusFilter: null });
const runningOptions: CodexTasksOptions = { ...baseOptions, statusFilter: ["running", "judging"] };
const queuedOptions: CodexTasksOptions = { ...baseOptions, statusFilter: ["queued", "retry_wait"] };
return {
count: activeStatusCount,
exact: statusCounts.exact,
source: statusCounts.source,
scope: statusCounts.scope,
queueId: statusCounts.queueId,
statuses: {
running: runningCount,
judging: judgingCount,
},
effectiveActiveRunnerCount,
effectiveActiveRunnerCountSources: {
activeStatusCount,
heartbeatActiveCount,
schedulerLocalActiveRunSlotCount,
},
rowPage: {
returned: runningSection.returned,
availableInCurrentOverview: runningSection.count,
returnedLimit: taskSectionLimit(options),
truncated: runningSection.truncated,
hasMore: runningSection.hasMore,
distinction: "returned is the compact row page; count is the active running total used for supervision",
},
redline: {
countField: "supervisor.activeRunning.count",
routineTarget,
burstRedline,
hardRedline,
runtimeMaxActiveQueues: runtimeLimit,
state: redlineState,
remainingToRoutineTarget: Math.max(0, routineTarget - activeStatusCount),
remainingToBurstRedline: Math.max(0, burstRedline - activeStatusCount),
remainingToHardRedline: Math.max(0, hardRedline - activeStatusCount),
decisionReady: statusCounts.exact,
interpretation: exactInterpretation,
},
commands: {
running: taskListCommand(runningOptions),
runningFull: taskListCommand({ ...runningOptions, view: "full" }),
queued: taskListCommand(queuedOptions),
queues: "bun scripts/cli.ts codex queues",
nextRunningPage: runningSection.commands.next,
},
};
}
function fetchTaskSummaries(taskIds: string[], fetcher: CodexResponseFetcher): { summaries: Map<string, Record<string, unknown>>; degraded: CodexTasksDegraded | null } {
const boundedIds = taskIds.slice(0, maxTasksLimit);
const summaries = new Map<string, Record<string, unknown>>();
const errors: Array<{ taskId: string; message: string }> = [];
for (const taskId of boundedIds) {
try {
const response = unwrapCodexResponse(fetcher(codeQueueProxyPath(`/api/tasks/${encodeURIComponent(taskId)}/summary${queryString({ toolLimit: 1 })}`)));
const summary = asRecord(response.body.summary) ?? {};
summaries.set(taskId, summary);
} catch (error) {
errors.push({ taskId, message: error instanceof Error ? error.message : String(error) });
}
}
return { summaries, degraded: collectTaskWatchDegraded(errors, Math.max(0, taskIds.length - boundedIds.length)) };
}
async function fetchTaskSummariesAsync(taskIds: string[], fetcher: AsyncCodexResponseFetcher): Promise<{ summaries: Map<string, Record<string, unknown>>; degraded: CodexTasksDegraded | null }> {
const boundedIds = taskIds.slice(0, maxTasksLimit);
const summaries = new Map<string, Record<string, unknown>>();
const errors: Array<{ taskId: string; message: string }> = [];
await Promise.all(boundedIds.map(async (taskId) => {
try {
const response = unwrapCodexResponse(await fetcher(codeQueueProxyPath(`/api/tasks/${encodeURIComponent(taskId)}/summary${queryString({ toolLimit: 1 })}`)));
const summary = asRecord(response.body.summary) ?? {};
summaries.set(taskId, summary);
} catch (error) {
errors.push({ taskId, message: error instanceof Error ? error.message : String(error) });
}
}));
return { summaries, degraded: collectTaskWatchDegraded(errors, Math.max(0, taskIds.length - boundedIds.length)) };
}
type CodexTasksTaskPage = {
queue: Record<string, unknown> | null;
pagination: Record<string, unknown>;
tasks: Record<string, unknown>[];
};
function tasksListQueryString(options: CodexTasksOptions): string {
return queryString({
limit: tasksOverviewSourceFetchLimit,
priorityLimit: tasksOverviewSourceFetchLimit,
queueId: options.queueId,
beforeId: options.beforeId,
includeActive: 1,
selected: 0,
compact: 1,
stats: 0,
skipTrace: 1,
});
}
function loadCodexTasks(taskArgs: CodexTasksOptions, fetcher: CodexResponseFetcher): { upstream: { ok: unknown; status: unknown }; page: CodexTasksTaskPage } {
const byId = new Map<string, Record<string, unknown>>();
const response = unwrapCodexResponse(fetcher(codeQueueProxyPath(`/api/tasks/overview${tasksListQueryString(taskArgs)}`)));
const pageTasks = asArray(response.body.tasks).map((task) => asRecord(task)).filter((task): task is Record<string, unknown> => task !== null);
for (const task of pageTasks) {
const taskId = taskOverviewCandidateKey(task);
if (taskId.length === 0) continue;
const existing = byId.get(taskId);
if (existing === undefined || taskTimelineMs(task) >= taskTimelineMs(existing)) byId.set(taskId, task);
}
const tasks = Array.from(byId.values()).sort((left, right) => {
const leftTime = taskTimelineMs(left);
const rightTime = taskTimelineMs(right);
if (leftTime !== rightTime) return rightTime - leftTime;
return asString(left.id).localeCompare(asString(right.id));
});
return { upstream: response.upstream, page: { queue: asRecord(response.body.queue), pagination: asRecord(response.body.pagination) ?? {}, tasks } };
}
function unreadLoadOptions(options: CodexUnreadOptions): CodexTasksOptions {
return {
queueId: options.queueId,
requestedLimit: maxTasksLimit,
limit: maxTasksLimit,
beforeId: undefined,
unreadOnly: true,
statusFilter: null,
view: "full",
};
}
function unreadTriageCommand(options: CodexUnreadOptions, action: CodexUnreadAction = "summary", extra: string[] = []): string {
const args = ["codex", "unread"];
if (action === "mark-read") args.push("mark-read");
if (options.queueId !== undefined) args.push("--queue", options.queueId);
if (options.repoFilter !== undefined) args.push("--repo", options.repoFilter);
if (options.issueFilter !== undefined) args.push("--issue", options.issueFilter.replace(/^#/u, ""));
if (options.statusFilter !== null) args.push("--status", options.statusFilter.join(","));
if (options.requestedLimit !== defaultTasksLimit) args.push("--limit", String(options.requestedLimit));
if (options.beforeId !== undefined) args.push("--before-id", options.beforeId);
args.push(...extra);
return `bun scripts/cli.ts ${args.join(" ")}`;
}
function taskTriageSearchText(task: Record<string, unknown>): string {
return [
asString(task.displayPrompt),
asString(task.basePrompt),
asString(task.prompt),
asString(task.cwd),
asString(task.lastError),
...stringList(task.referenceTaskIds),
].join("\n");
}
function taskRepoRefs(task: Record<string, unknown>): string[] {
const text = taskTriageSearchText(task);
const repos = new Set<string>();
for (const match of text.matchAll(/\b([A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+)#\d{1,6}\b/gu)) {
const repo = match[1] ?? "";
if (repo.length > 0) repos.add(repo);
}
for (const match of text.matchAll(/\bgithub\.com[:/]([A-Za-z0-9_.-]+)\/([A-Za-z0-9_.-]+?)(?:\.git)?(?:[#/\s?]|$)/giu)) {
const owner = match[1] ?? "";
const name = (match[2] ?? "").replace(/\.git$/iu, "");
if (owner.length > 0 && name.length > 0) repos.add(`${owner}/${name}`);
}
return Array.from(repos).sort((left, right) => left.localeCompare(right));
}
function taskIssueRefsForTriage(task: Record<string, unknown>): string[] {
const text = taskTriageSearchText(task);
const issues = new Set<string>();
for (const match of text.matchAll(/#(\d{1,6})\b/gu)) issues.add(`#${match[1]}`);
for (const match of text.matchAll(/\/issues\/(\d{1,6})\b/gu)) issues.add(`#${match[1]}`);
return Array.from(issues)
.sort((left, right) => Number(left.slice(1)) - Number(right.slice(1)));
}
function lowerSet(values: string[]): Set<string> {
return new Set(values.map((value) => value.toLowerCase()));
}
function taskMatchesUnreadFilters(task: Record<string, unknown>, options: CodexUnreadOptions): boolean {
if (!taskUnreadTerminal(task)) return false;
if (!taskMatchesStatusFilter(task, options.statusFilter)) return false;
if (options.queueId !== undefined && asString(task.queueId) !== options.queueId) return false;
if (options.repoFilter !== undefined && !lowerSet(taskRepoRefs(task)).has(options.repoFilter.toLowerCase())) return false;
if (options.issueFilter !== undefined && !taskIssueRefsForTriage(task).includes(options.issueFilter)) return false;
return true;
}
function unreadSortedCandidates(tasks: Record<string, unknown>[], options: CodexUnreadOptions): Record<string, unknown>[] {
return sortCompletedWatchTasks(tasks.filter((task) => taskMatchesUnreadFilters(task, options)));
}
function unreadPageCandidates(candidates: Record<string, unknown>[], options: CodexUnreadOptions): Record<string, unknown>[] {
if (options.beforeId === undefined) return candidates;
const beforeIndex = candidates.findIndex((task) => taskOverviewCandidateKey(task) === options.beforeId);
return beforeIndex < 0 ? candidates : candidates.slice(beforeIndex + 1);
}
function incrementCount(map: Map<string, number>, key: string): void {
map.set(key, (map.get(key) ?? 0) + 1);
}
function countBucket(map: Map<string, number>, limit = unreadTriageCountLimit): Record<string, unknown> {
const rows = Array.from(map.entries())
.map(([key, count]) => ({ key, count }))
.sort((left, right) => right.count - left.count || left.key.localeCompare(right.key));
return {
totalDistinct: rows.length,
returned: Math.min(rows.length, limit),
truncated: rows.length > limit,
items: rows.slice(0, limit),
};
}
function unreadTriageCounts(candidates: Record<string, unknown>[]): Record<string, unknown> {
const byRepo = new Map<string, number>();
const byIssue = new Map<string, number>();
const byStatus = new Map<string, number>();
const byQueue = new Map<string, number>();
for (const task of candidates) {
incrementCount(byStatus, asString(task.status) || "unknown");
incrementCount(byQueue, asString(task.queueId) || "unknown");
const repos = taskRepoRefs(task);
const issues = taskIssueRefsForTriage(task);
if (repos.length === 0) incrementCount(byRepo, "unknown");
for (const repo of repos) incrementCount(byRepo, repo);
if (issues.length === 0) incrementCount(byIssue, "unknown");
for (const issue of issues) incrementCount(byIssue, issue);
}
return {
totalUnreadTerminal: candidates.length,
byRepo: countBucket(byRepo),
byIssue: countBucket(byIssue),
byStatus: countBucket(byStatus),
byQueue: countBucket(byQueue),
};
}
function unreadTriageItem(task: Record<string, unknown>): Record<string, unknown> {
const taskId = taskOverviewCandidateKey(task);
return {
id: taskId,
queue: asString(task.queueId) || null,
status: asString(task.status) || null,
repos: taskRepoRefs(task),
issues: taskIssueRefsForTriage(task),
updatedAt: asString(task.updatedAt) || null,
finishedAt: asString(task.finishedAt) || null,
commands: {
show: `bun scripts/cli.ts codex task ${taskId}`,
detail: `bun scripts/cli.ts codex task ${taskId} --detail`,
trace: `bun scripts/cli.ts codex task ${taskId} --trace --tail --limit ${defaultTraceLimit}`,
output: `bun scripts/cli.ts codex output ${taskId} --tail --limit ${defaultOutputLimit}`,
read: `bun scripts/cli.ts codex read ${taskId}`,
},
};
}
function unreadTriageSummary(upstream: { ok: unknown; status: unknown }, page: CodexTasksTaskPage, options: CodexUnreadOptions): {
result: Record<string, unknown>;
visibleCandidates: Record<string, unknown>[];
} {
const allCandidates = unreadSortedCandidates(page.tasks, options);
const pagedCandidates = unreadPageCandidates(allCandidates, options);
const visibleCandidates = pagedCandidates.slice(0, options.limit);
const hasMore = pagedCandidates.length > visibleCandidates.length;
const nextBeforeId = hasMore ? taskOverviewCandidateKey(visibleCandidates.at(-1) ?? {}) || null : null;
const nextCommand = nextBeforeId === null ? null : unreadTriageCommand({ ...options, beforeId: nextBeforeId });
const readCommand = unreadTriageCommand(options, "mark-read", ["--confirm"]);
return {
visibleCandidates,
result: {
ok: true,
upstream,
unreadTriage: {
filters: {
queueId: options.queueId ?? null,
repo: options.repoFilter ?? null,
issue: options.issueFilter ?? null,
status: options.statusFilter,
requestedLimit: options.requestedLimit,
limit: options.limit,
limitCapped: options.requestedLimit > options.limit,
beforeId: options.beforeId ?? null,
},
readOnly: options.action === "summary" || options.dryRun,
bounded: true,
disclosure: {
policy: "summary counts plus bounded task ids only; no raw prompt, final response, trace, or output is included by default",
countBucketLimit: unreadTriageCountLimit,
itemLimit: options.limit,
mutationPolicy: "batch mark-read requires codex unread mark-read --confirm; per-task read remains codex read <taskId>",
},
counts: unreadTriageCounts(allCandidates),
newest: {
count: allCandidates.length,
returned: visibleCandidates.length,
hasMore,
nextBeforeId,
commands: {
next: nextCommand,
showTemplate: "bun scripts/cli.ts codex task <taskId>",
detailTemplate: "bun scripts/cli.ts codex task <taskId> --detail",
traceTemplate: `bun scripts/cli.ts codex task <taskId> --trace --tail --limit ${defaultTraceLimit}`,
outputTemplate: `bun scripts/cli.ts codex output <taskId> --tail --limit ${defaultOutputLimit}`,
readTemplate: "bun scripts/cli.ts codex read <taskId>",
},
items: visibleCandidates.map(unreadTriageItem),
},
commands: {
refresh: unreadTriageCommand(options),
tasksUnread: taskListCommand({
queueId: options.queueId,
requestedLimit: Math.min(options.requestedLimit, defaultTasksLimit),
limit: Math.min(options.limit, defaultTasksLimit),
beforeId: undefined,
unreadOnly: true,
statusFilter: options.statusFilter,
view: "supervisor",
}),
byRepo: "bun scripts/cli.ts codex unread --repo owner/name",
byIssue: "bun scripts/cli.ts codex unread --issue <number>",
byStatus: "bun scripts/cli.ts codex unread --status succeeded|failed|canceled",
byQueue: "bun scripts/cli.ts codex unread --queue <queueId>",
perTaskRead: "bun scripts/cli.ts codex read <taskId>",
batchReadDryRun: unreadTriageCommand(options, "mark-read", ["--dry-run"]),
batchReadConfirm: readCommand,
},
},
},
};
}
function codexUnreadMutationGuard(result: Record<string, unknown>, visibleCandidates: Record<string, unknown>[], options: CodexUnreadOptions): Record<string, unknown> {
const triage = asRecord(result.unreadTriage) ?? {};
return {
...result,
ok: false,
unreadTriage: {
...triage,
readOnly: true,
mutation: {
requested: true,
confirmed: false,
blocked: true,
reason: "batch mark-read requires --confirm; default codex unread output is read-only",
candidateTaskIds: visibleCandidates.map(taskOverviewCandidateKey),
command: unreadTriageCommand(options, "mark-read", ["--confirm"]),
},
},
};
}
function codexUnreadMutationResult(result: Record<string, unknown>, options: CodexUnreadOptions, results: Record<string, unknown>[]): Record<string, unknown> {
const triage = asRecord(result.unreadTriage) ?? {};
const failed = results.filter((item) => item.ok === false);
return {
...result,
ok: failed.length === 0,
unreadTriage: {
...triage,
readOnly: false,
mutation: {
requested: true,
confirmed: true,
action: "mark-read",
limit: options.limit,
attempted: results.length,
succeeded: results.length - failed.length,
failed: failed.length,
results,
commands: {
refresh: unreadTriageCommand({ ...options, action: "summary", confirm: false, dryRun: true }),
tasksUnread: `bun scripts/cli.ts codex unread --limit ${defaultTasksLimit}`,
},
},
},
};
}
function codexUnreadTriage(taskArgs: string[], fetcher: CodexResponseFetcher = coreInternalFetch): unknown {
const options = parseUnreadOptions(taskArgs);
const { upstream, page } = loadCodexTasks(unreadLoadOptions(options), fetcher);
const { result, visibleCandidates } = unreadTriageSummary(upstream, page, options);
if (options.action !== "mark-read" || options.dryRun) return result;
if (!options.confirm) return codexUnreadMutationGuard(result, visibleCandidates, options);
const results: Record<string, unknown>[] = [];
for (const task of visibleCandidates) {
const taskId = taskOverviewCandidateKey(task);
try {
const response = unwrapCodexResponse(fetcher(codeQueueProxyPath(`/api/tasks/${encodeURIComponent(taskId)}/read`), { method: "POST", body: {} }));
results.push({ taskId, ok: true, upstream: response.upstream });
} catch (error) {
results.push({ taskId, ok: false, error: error instanceof Error ? error.message : String(error) });
}
}
return codexUnreadMutationResult(result, options, results);
}
function codexTasksOverviewResult(
taskPage: CodexTasksTaskPage,
upstream: { ok: unknown; status: unknown },
options: CodexTasksOptions,
summaries: Map<string, Record<string, unknown>>,
degraded: CodexTasksDegraded | null,
): Record<string, unknown> {
if (options.view === "full") return codexTasksFullResult(taskPage, upstream, options, summaries, degraded);
const allTasks = filterTasksForOptions(taskPage.tasks, options);
const runningTasks = sortRunningWatchTasks(allTasks);
const unreadCompletedTasks = sortCompletedWatchTasks(allTasks).filter((task) => taskUnreadTerminal(task));
const recentCompletedTasks = options.unreadOnly ? [] : sortCompletedWatchTasks(allTasks).filter((task) => !taskUnreadTerminal(task));
const queuedTasks = options.unreadOnly ? [] : sortQueuedWatchTasks(allTasks);
const nextBeforeId = asString(taskPage.pagination.nextBeforeId) || null;
const sourceHasMore = asBoolean(taskPage.pagination.hasMore);
const nextCommand = sourceHasMore && nextBeforeId !== null ? taskListCommand({ ...options, beforeId: nextBeforeId }) : null;
const fullCommand = taskListCommand({ ...options, view: "full" });
const sectionLimit = taskSectionLimit(options);
const recentLimit = Math.min(options.limit, supervisorRecentCompletedLimit);
const runningSection = buildSupervisorTaskSection(runningTasks, summaries, sectionLimit, sectionNextCommand(runningTasks, sectionLimit, options, nextCommand), fullCommand);
const unreadSection = buildSupervisorTaskSection(unreadCompletedTasks, summaries, sectionLimit, sectionNextCommand(unreadCompletedTasks, sectionLimit, options, nextCommand), fullCommand);
const recentSection = buildSupervisorTaskSection(recentCompletedTasks, summaries, recentLimit, sectionNextCommand(recentCompletedTasks, recentLimit, options, nextCommand), fullCommand, supervisorRecentBodyPreviewChars);
const queuedSection = buildSupervisorTaskSection(queuedTasks, summaries, sectionLimit, sectionNextCommand(queuedTasks, sectionLimit, options, nextCommand), fullCommand);
const pagination = taskPage.pagination;
const diagnostics = supervisorExecutionDiagnostics(asRecord(taskPage.queue)?.executionDiagnostics);
const activity = compactCodeQueueActivity(asRecord(taskPage.queue) ?? {}, diagnostics);
const commanderConcurrency = asRecord(activity.commanderConcurrency) ?? {};
const activeRunning = supervisorActiveRunningSummary(taskPage, options, runningSection, diagnostics);
const visibleSupervisorItems = [...runningSection.items, ...unreadSection.items, ...recentSection.items, ...queuedSection.items];
const classifierCounts = visibleSupervisorItems.reduce((counts, item) => {
const key = item.kind;
counts[key] = (counts[key] ?? 0) + 1;
if (item.noise) counts.managementNoise = (counts.managementNoise ?? 0) + 1;
return counts;
}, {} as Record<string, number>);
return {
upstream,
supervisor: {
filters: {
view: options.view,
queueId: options.queueId ?? null,
requestedLimit: options.requestedLimit,
limit: options.limit,
...codexTasksLimitDisclosure(options),
unreadOnly: options.unreadOnly,
status: options.statusFilter,
beforeId: options.beforeId ?? null,
},
source: { queueId: options.queueId ?? null, ...codexTasksSourceDisclosure(pagination) },
bounded: true,
disclosure: {
defaultView: "supervisor",
policy: "bounded summary rows only; prompt/body are short previews and raw detail requires explicit task/full/trace/output commands",
limitSemantics: "--limit is request/scanning/page budget; supervisor sections still return compact bounded row pages and expose counts separately",
limitPolicy: {
...codexTasksLimitDisclosure(options),
sourceFetchLimit: tasksOverviewSourceFetchLimit,
sourceEffectiveLimit: asNumber(pagination.limit, 0) || null,
sourceReturned: asNumber(pagination.returned, 0) || null,
note: "codex tasks --limit is capped for CLI output safety; supervisor sections also keep small row caps and expose commands.next for pagination",
},
outputBudget: {
promptPreviewChars: supervisorPromptPreviewChars,
bodyPreviewChars: supervisorBodyPreviewChars,
requestedLimit: options.requestedLimit,
effectiveLimit: options.limit,
limitCapped: options.limit < options.requestedLimit,
sectionReturnedLimit: sectionLimit,
recentCompletedReturnedLimit: recentLimit,
recentCompletedBodyPreviewChars: supervisorRecentBodyPreviewChars,
rowCommands: "task id is the row drill-down key; show/detail/trace/output/full/read are section templates to avoid repeated noise",
},
fullCommand,
next: nextCommand,
rawOverview: `bun scripts/cli.ts microservice proxy code-queue /api/tasks/overview${tasksListQueryString(options)} --raw`,
},
counts: {
scanned: allTasks.length,
running: runningSection.count,
activeRunningCount: activeRunning.count,
activeRunningExact: activeRunning.exact,
activeRunningRowsReturned: runningSection.returned,
completedUnread: unreadSection.count,
recentCompleted: recentSection.count,
queued: queuedSection.count,
commanderActiveRunnerCount: asNumber(commanderConcurrency.activeRunnerCount, 0),
effectiveActive: asNumber(activity.effectiveActiveTaskCount, 0),
databaseRunning: asNumber(activity.databaseRunningTaskCount, 0),
heartbeatFreshActive: asNumber(activity.heartbeatFreshActiveTaskCount, 0),
schedulerLocalActiveQueues: asNumber(activity.schedulerLocalActiveQueueCount, 0),
},
classifierCounts,
commanderConcurrency,
activity,
activeRunning,
executionDiagnostics: diagnostics,
degraded,
commands: {
refresh: taskListCommand(options),
unread: taskListCommand({ ...options, unreadOnly: true }),
byStatus: `bun scripts/cli.ts codex tasks --status <status>${options.queueId === undefined ? "" : ` --queue ${options.queueId}`}${options.requestedLimit === defaultTasksLimit ? "" : ` --limit ${options.requestedLimit}`}`,
full: fullCommand,
next: nextCommand,
},
running: runningSection,
completedUnread: unreadSection,
recentCompleted: recentSection,
queued: queuedSection,
},
};
}
function codexTasksFullResult(
taskPage: CodexTasksTaskPage,
upstream: { ok: unknown; status: unknown },
options: CodexTasksOptions,
summaries: Map<string, Record<string, unknown>>,
degraded: CodexTasksDegraded | null,
): Record<string, unknown> {
const filtered = filterTasksForOptions(taskPage.tasks, options);
const visible = filtered.slice(0, options.limit);
const pagination = taskPage.pagination;
const nextBeforeId = asString(pagination.nextBeforeId) || null;
const sourceHasMore = asBoolean(pagination.hasMore);
const nextCommand = sourceHasMore && nextBeforeId !== null ? taskListCommand({ ...options, beforeId: nextBeforeId }) : null;
return {
upstream,
tasks: {
filters: {
view: "full",
queueId: options.queueId ?? null,
requestedLimit: options.requestedLimit,
limit: options.limit,
...codexTasksLimitDisclosure(options),
unreadOnly: options.unreadOnly,
status: options.statusFilter,
beforeId: options.beforeId ?? null,
},
source: codexTasksSourceDisclosure(pagination),
count: filtered.length,
returned: visible.length,
hasMore: filtered.length > visible.length || sourceHasMore,
degraded,
commands: {
supervisor: taskListCommand({ ...options, view: "supervisor" }),
next: nextCommand,
rawOverview: `bun scripts/cli.ts microservice proxy code-queue /api/tasks/overview${tasksListQueryString(options)} --raw`,
},
items: visible.map((task) => taskWatchEntry(task, summaries.get(taskOverviewCandidateKey(task)) ?? null)),
},
};
}
function visibleTaskIdsForOverview(tasks: Record<string, unknown>[], options: CodexTasksOptions): string[] {
const filtered = filterTasksForOptions(tasks, options);
if (options.view === "full") {
return filtered.slice(0, options.limit).map((task) => taskOverviewCandidateKey(task)).filter((taskId) => taskId.length > 0);
}
const sectionLimit = taskSectionLimit(options);
return Array.from(new Set([
...sortRunningWatchTasks(filtered).slice(0, sectionLimit),
...sortCompletedWatchTasks(filtered).filter((task) => taskUnreadTerminal(task)).slice(0, sectionLimit),
...sortCompletedWatchTasks(filtered).filter((task) => !taskUnreadTerminal(task)).slice(0, Math.min(options.limit, supervisorRecentCompletedLimit)),
...sortQueuedWatchTasks(filtered).slice(0, sectionLimit),
].map((task) => taskOverviewCandidateKey(task))))
.filter((taskId) => taskId.length > 0);
}
function codexTasksQuery(taskArgs: string[], fetcher: CodexResponseFetcher = coreInternalFetch): unknown {
const options = parseTasksOptions(taskArgs);
const { upstream, page } = loadCodexTasks(options, fetcher);
const sectionTaskIds = visibleTaskIdsForOverview(page.tasks, options);
const { summaries, degraded } = fetchTaskSummaries(sectionTaskIds, fetcher);
return codexTasksOverviewResult(page, upstream, options, summaries, degraded);
}
export function codexTasksQueryForTest(taskArgs: string[], fetcher: CodexResponseFetcher): unknown {
return codexTasksQuery(taskArgs, fetcher);
}
export function codexUnreadTriageForTest(taskArgs: string[], fetcher: CodexResponseFetcher): unknown {
return codexUnreadTriage(taskArgs, fetcher);
}
async function codexTasksQueryAsync(taskArgs: string[], fetcher: AsyncCodexResponseFetcher): Promise<unknown> {
const options = parseTasksOptions(taskArgs);
const byId = new Map<string, Record<string, unknown>>();
const response = unwrapCodexResponse(await fetcher(codeQueueProxyPath(`/api/tasks/overview${tasksListQueryString(options)}`)));
const pageTasks = asArray(response.body.tasks).map((task) => asRecord(task)).filter((task): task is Record<string, unknown> => task !== null);
for (const task of pageTasks) {
const taskId = taskOverviewCandidateKey(task);
if (taskId.length === 0) continue;
const existing = byId.get(taskId);
if (existing === undefined || taskTimelineMs(task) >= taskTimelineMs(existing)) byId.set(taskId, task);
}
const tasks = Array.from(byId.values()).sort((left, right) => {
const leftTime = taskTimelineMs(left);
const rightTime = taskTimelineMs(right);
if (leftTime !== rightTime) return rightTime - leftTime;
return asString(left.id).localeCompare(asString(right.id));
});
const page: CodexTasksTaskPage = { queue: asRecord(response.body.queue), pagination: asRecord(response.body.pagination) ?? {}, tasks };
const visibleTaskIds = visibleTaskIdsForOverview(page.tasks, options);
const { summaries, degraded } = await fetchTaskSummariesAsync(visibleTaskIds, fetcher);
return codexTasksOverviewResult(page, response.upstream, options, summaries, degraded);
}
async function codexUnreadTriageAsync(taskArgs: string[], fetcher: AsyncCodexResponseFetcher): Promise<unknown> {
const options = parseUnreadOptions(taskArgs);
const loadOptions = unreadLoadOptions(options);
const byId = new Map<string, Record<string, unknown>>();
const response = unwrapCodexResponse(await fetcher(codeQueueProxyPath(`/api/tasks/overview${tasksListQueryString(loadOptions)}`)));
const pageTasks = asArray(response.body.tasks).map((task) => asRecord(task)).filter((task): task is Record<string, unknown> => task !== null);
for (const task of pageTasks) {
const taskId = taskOverviewCandidateKey(task);
if (taskId.length === 0) continue;
const existing = byId.get(taskId);
if (existing === undefined || taskTimelineMs(task) >= taskTimelineMs(existing)) byId.set(taskId, task);
}
const tasks = Array.from(byId.values()).sort((left, right) => {
const leftTime = taskTimelineMs(left);
const rightTime = taskTimelineMs(right);
if (leftTime !== rightTime) return rightTime - leftTime;
return asString(left.id).localeCompare(asString(right.id));
});
const page: CodexTasksTaskPage = { queue: asRecord(response.body.queue), pagination: asRecord(response.body.pagination) ?? {}, tasks };
const { result, visibleCandidates } = unreadTriageSummary(response.upstream, page, options);
if (options.action !== "mark-read" || options.dryRun) return result;
if (!options.confirm) return codexUnreadMutationGuard(result, visibleCandidates, options);
const results: Record<string, unknown>[] = [];
for (const task of visibleCandidates) {
const taskId = taskOverviewCandidateKey(task);
try {
const readResponse = unwrapCodexResponse(await fetcher(codeQueueProxyPath(`/api/tasks/${encodeURIComponent(taskId)}/read`), { method: "POST", body: {} }));
results.push({ taskId, ok: true, upstream: readResponse.upstream });
} catch (error) {
results.push({ taskId, ok: false, error: error instanceof Error ? error.message : String(error) });
}
}
return codexUnreadMutationResult(result, options, results);
}
async function codexTaskSummaryAsync(taskId: string, options: CodexTaskOptions, fetcher: AsyncCodexResponseFetcher): Promise<unknown> {
const summaryPath = codeQueueProxyPath(`/api/tasks/${encodeURIComponent(taskId)}/summary${queryString({ toolLimit: options.toolLimit })}`);
const summaryResponse = unwrapCodexResponse(await fetcher(summaryPath));
const summary = summaryResponse.body.summary;
const result: Record<string, unknown> = {
upstream: summaryResponse.upstream,
summary: options.detail ? compactSummary(summary, options, taskId) : compactReviewSummary(summary, options, taskId),
};
if (options.rawSummary) result.rawSummary = summary;
if (options.trace) {
const traceParams: Record<string, string | number | boolean | null> = { limit: options.traceLimit };
if (options.traceMode === "tail") traceParams.tail = 1;
if (options.traceMode === "after") traceParams.afterSeq = options.afterSeq;
if (options.traceMode === "before") traceParams.beforeSeq = options.beforeSeq;
const traceSummaryResponse = unwrapCodexResponse(await fetcher(codeQueueProxyPath(`/api/tasks/${encodeURIComponent(taskId)}/trace-summary`)));
const traceResponse = unwrapCodexResponse(await fetcher(codeQueueProxyPath(`/api/tasks/${encodeURIComponent(taskId)}/trace-steps${queryString(traceParams)}`)));
result.trace = compactTracePage(traceResponse.body, taskId, options.traceLimit, traceSummaryResponse.body, options);
}
return result;
}
async function codexTaskOutputAsync(taskId: string, options: CodexOutputOptions, fetcher: AsyncCodexResponseFetcher): Promise<unknown> {
const params: Record<string, string | number | boolean | null> = {
limit: options.limit,
fullText: options.fullText ? 1 : 0,
maxTextChars: options.maxTextChars,
};
if (options.mode === "tail") params.tail = 1;
if (options.mode === "after") params.afterSeq = options.afterSeq;
if (options.mode === "before") params.beforeSeq = options.beforeSeq;
const response = unwrapCodexResponse(await fetcher(codeQueueProxyPath(`/api/tasks/${encodeURIComponent(taskId)}/output${queryString(params)}`)));
return { upstream: response.upstream, outputPage: compactOutputPage(response.body, taskId, options) };
}
async function codexTaskJudgeAsync(taskId: string, options: CodexJudgeOptions, fetcher: AsyncCodexResponseFetcher): Promise<unknown> {
const params = queryString({
attempt: options.attempt,
dryRun: options.dryRun ? 1 : undefined,
includePrompt: options.includePrompt ? 1 : undefined,
});
const response = unwrapCodexResponse(await fetcher(codeQueueProxyPath(`/api/tasks/${encodeURIComponent(taskId)}/judge${params}`), { method: "POST" }));
return { upstream: response.upstream, judgeReplay: response.body };
}
export async function codexTaskQueryAsync(taskId: string, optionArgs: string[], fetcher: AsyncCodexResponseFetcher): Promise<unknown> {
return codexTaskSummaryAsync(taskId, parseTaskOptions(optionArgs), fetcher);
}
export async function codexOutputQueryAsync(taskId: string, optionArgs: string[], fetcher: AsyncCodexResponseFetcher): Promise<unknown> {
return codexTaskOutputAsync(taskId, parseOutputOptions(optionArgs), fetcher);
}
export async function codexJudgeQueryAsync(taskId: string, optionArgs: string[], fetcher: AsyncCodexResponseFetcher): Promise<unknown> {
return codexTaskJudgeAsync(taskId, parseJudgeOptions(optionArgs), fetcher);
}
export { codexQueuesQueryAsync, codexTasksQueryAsync, codexUnreadTriageAsync };
function requireQueueId(args: string[], command: string): string {
const index = args.indexOf("--queue");
const raw = index === -1 ? args[0] : args[index + 1];
if (raw === undefined || raw.trim().length === 0) throw new Error(`${command} requires queue id, for example --queue default`);
return raw.trim();
}
function optionValue(args: string[], names: string[]): string | undefined {
for (const name of names) {
const index = args.indexOf(name);
if (index === -1) continue;
const raw = args[index + 1];
if (raw === undefined || raw.trim().length === 0) throw new Error(`${name} requires a non-empty value`);
return raw.trim();
}
return undefined;
}
function optionValues(args: string[], names: string[]): string[] {
const values: string[] = [];
for (let index = 0; index < args.length; index += 1) {
const name = args[index] ?? "";
if (!names.includes(name)) continue;
const raw = args[index + 1];
if (raw === undefined || raw.trim().length === 0) throw new Error(`${name} requires a non-empty value`);
values.push(raw.trim());
index += 1;
}
return values;
}
function positionalArgs(args: string[]): string[] {
const positions: string[] = [];
for (let index = 0; index < args.length; index += 1) {
const value = args[index] ?? "";
if (value.startsWith("--")) {
index += 1;
continue;
}
positions.push(value);
}
return positions;
}
function positionalArgsWithValueOptions(args: string[], valueOptions: Set<string>): string[] {
const positions: string[] = [];
for (let index = 0; index < args.length; index += 1) {
const value = args[index] ?? "";
if (value.startsWith("--")) {
if (valueOptions.has(value)) index += 1;
continue;
}
positions.push(value);
}
return positions;
}
function requireMergeSourceQueueId(args: string[], command: string): string {
const raw = optionValue(args, ["--source", "--from", "--queue"]) ?? positionalArgs(args)[0];
if (raw === undefined || raw.trim().length === 0) throw new Error(`${command} requires source queue id, for example: codex queue merge old --into default`);
return raw.trim();
}
function requireMergeTargetQueueId(args: string[], command: string): string {
const raw = optionValue(args, ["--into", "--target", "--to"]) ?? positionalArgs(args)[1];
if (raw === undefined || raw.trim().length === 0) throw new Error(`${command} requires target queue id, for example: codex queue merge old --into default`);
return raw.trim();
}
function compactCounts(value: unknown): Record<string, unknown> {
const counts = asRecord(value) ?? {};
const compact: Record<string, unknown> = {};
for (const [key, count] of Object.entries(counts)) {
if (typeof count === "number" && count === 0) continue;
compact[key] = count;
}
return compact;
}
function compactQueueRow(value: unknown): Record<string, unknown> {
const record = asRecord(value) ?? {};
return {
id: record.id ?? null,
name: record.name ?? null,
total: record.total ?? null,
counts: compactCounts(record.counts),
unreadTerminal: record.unreadTerminal ?? 0,
activeTaskId: record.activeTaskId ?? null,
runnableTaskId: record.runnableTaskId ?? null,
processing: record.processing ?? null,
updatedAt: record.updatedAt ?? null,
commands: {
tasks: record.id === undefined || record.id === null ? null : `bun scripts/cli.ts codex tasks --queue ${String(record.id)} --limit ${defaultTasksLimit}`,
unread: record.id === undefined || record.id === null ? null : `bun scripts/cli.ts codex unread --queue ${String(record.id)} --limit ${defaultTasksLimit}`,
},
};
}
function queueListCommand(options: Partial<CodexQueuesOptions> = {}): string {
const full = options.full === true;
const limit = options.limit ?? defaultQueuesLimit;
const offset = options.offset ?? 0;
return [
"bun scripts/cli.ts codex queues",
full ? "--full" : "",
limit === defaultQueuesLimit ? "" : `--limit ${limit}`,
offset > 0 ? `--offset ${offset}` : "",
].filter(Boolean).join(" ");
}
function compactQueuesResponse(body: Record<string, unknown>, options: CodexQueuesOptions, upstream: { ok: unknown; status: unknown }): Record<string, unknown> {
const queue = asRecord(body.queue) ?? asRecord(body.summary) ?? {};
const queues = asArray(body.queues).map(compactQueueRow);
const activeIds = stringList(queue.activeQueueIds);
const nonemptyQueues = queues.filter((row) => asNumber(row.total, 0) > 0);
const unreadQueues = queues.filter((row) => asNumber(row.unreadTerminal, 0) > 0);
const runnableQueues = queues.filter((row) => row.runnableTaskId !== null && row.runnableTaskId !== undefined);
const activeQueues = queues.filter((row) => typeof row.id === "string" && activeIds.includes(row.id));
const selected = options.full ? queues : Array.from(new Map([...activeQueues, ...unreadQueues, ...runnableQueues, ...nonemptyQueues].map((row) => [String(row.id), row])).values());
const visible = selected.slice(options.offset, options.offset + options.limit);
const diagnostics = compactQueueExecutionDiagnostics(queue.executionDiagnostics);
const activity = compactCodeQueueActivity(queue, diagnostics, { schedulerLocalActiveQueueIds: activeIds, runnableQueueCount: runnableQueues.length });
const commanderConcurrency = asRecord(activity.commanderConcurrency) ?? {};
const activeTaskIds = boundedUniqueStringList(queue.activeTaskIds, Math.min(options.limit, maxTasksLimit));
const queuedTaskIds = boundedUniqueStringList(queue.queuedTaskIds, Math.min(options.limit, maxTasksLimit));
const nextOffset = options.offset + visible.length;
const previousOffset = Math.max(0, options.offset - options.limit);
const hasMore = nextOffset < selected.length;
const hasPrevious = options.offset > 0;
return {
upstream,
queues: {
view: options.full ? "full" : "summary",
bounded: true,
outputPolicy: {
default: "paged-low-noise",
stableItemsPath: "data.queues.items[]",
rawFullCommand: "bun scripts/cli.ts microservice proxy code-queue /api/queues --raw --full",
},
count: selected.length,
returned: visible.length,
limit: options.limit,
offset: options.offset,
page: options.page,
hasMore,
hasPrevious,
totals: {
totalTasks: queue.total ?? null,
queueCount: queue.queueCount ?? queues.length,
activeQueueCount: activeIds.length,
activeQueueCountScope: "scheduler-local-active-run-slots",
schedulerLocalActiveQueueCount: activeIds.length,
commanderActiveRunnerCount: commanderConcurrency.activeRunnerCount,
effectiveActiveTaskCount: activity.effectiveActiveTaskCount,
databaseRunningTaskCount: activity.databaseRunningTaskCount,
databaseActiveTaskCount: activity.databaseActiveTaskCount,
heartbeatFreshActiveTaskCount: activity.heartbeatFreshActiveTaskCount,
nonemptyQueueCount: nonemptyQueues.length,
unreadQueueCount: unreadQueues.length,
runnableQueueCount: runnableQueues.length,
},
commanderConcurrency,
activity,
activeQueueIds: queue.activeQueueIds ?? [],
activeQueueIdsScope: "scheduler-local-active-run-slots",
activeQueueIdsNote: activity.activeQueueIdsNote,
activeTaskIds: activeTaskIds.items,
activeTaskIdsCount: activeTaskIds.count,
activeTaskIdsTruncated: activeTaskIds.truncated,
queuedTaskIds: queuedTaskIds.items,
queuedTaskIdsCount: queuedTaskIds.count,
queuedTaskIdsTruncated: queuedTaskIds.truncated,
counts: queue.counts ?? {},
unreadTerminal: queue.unreadTerminal ?? 0,
executionDiagnostics: diagnostics,
items: visible,
...(options.full
? {
compatibility: {
deprecated: true,
deprecatedPath: "data.queues.deprecatedFullArray[]",
stablePath: "data.queues.items[]",
deprecatedFullArrayOmitted: true,
message: "Use data.queues.items[] for both codex queues and codex queues --full; raw full upstream is available only through the explicit raw command.",
},
}
: {}),
commands: {
refresh: queueListCommand({ full: options.full, limit: options.limit, offset: options.offset }),
next: hasMore ? queueListCommand({ full: options.full, limit: options.limit, offset: nextOffset }) : null,
previous: hasPrevious ? queueListCommand({ full: options.full, limit: options.limit, offset: previousOffset }) : null,
first: queueListCommand({ full: options.full, limit: options.limit, offset: 0 }),
full: queueListCommand({ full: true, limit: options.limit, offset: 0 }),
tasks: `bun scripts/cli.ts codex tasks --view supervisor --limit ${Math.min(options.limit, defaultTasksLimit)}`,
unread: `bun scripts/cli.ts codex unread --limit ${Math.min(options.limit, defaultTasksLimit)}`,
raw: "bun scripts/cli.ts microservice proxy code-queue /api/queues --raw --full",
},
},
};
}
export function codexQueuesQueryForTest(optionArgs: string[], fetcher: CodexResponseFetcher): unknown {
const options = parseQueuesOptions(optionArgs);
const response = unwrapCodexResponse(fetcher(codeQueueProxyPath("/api/queues")));
return compactQueuesResponse(response.body, options, response.upstream);
}
async function codexQueuesQueryAsync(optionArgs: string[], fetcher: AsyncCodexResponseFetcher): Promise<unknown> {
const options = parseQueuesOptions(optionArgs);
const response = unwrapCodexResponse(await fetcher(codeQueueProxyPath("/api/queues")));
return compactQueuesResponse(response.body, options, response.upstream);
}
function codeQueues(optionArgs: string[] = []): unknown {
return codexQueuesQueryForTest(optionArgs, coreInternalFetch);
}
function codexCreateQueue(queueId: string): unknown {
return unwrapCodexResponse(coreInternalFetch(codeQueueProxyPath("/api/queues"), { method: "POST", body: { queueId } }));
}
function codexMergeQueue(sourceQueueId: string, targetQueueId: string): unknown {
return unwrapCodexResponse(coreInternalFetch(codeQueueProxyPath(`/api/queues/${encodeURIComponent(targetQueueId)}/merge`), { method: "POST", body: { sourceQueueId } }));
}
function codexMoveTask(taskId: string, queueId: string): unknown {
return unwrapCodexResponse(coreInternalFetch(codeQueueProxyPath(`/api/tasks/${encodeURIComponent(taskId)}/move`), { method: "POST", body: { queueId } }));
}
function promptFromArgs(args: string[], command: string, valueOptions: Set<string>): string {
const promptFile = optionValue(args, ["--prompt-file", "--file"]);
const promptStdin = hasFlag(args, "--prompt-stdin") || hasFlag(args, "--stdin");
const promptArgs = positionalArgsWithValueOptions(args, valueOptions);
const sources = [promptFile !== undefined, promptStdin, promptArgs.length > 0].filter(Boolean).length;
if (sources !== 1) throw new Error(`${command} requires exactly one prompt source: positional prompt, --prompt-file, or --prompt-stdin`);
const text = promptFile !== undefined
? (promptFile === "-" ? readFileSync(0, "utf8") : readFileSync(promptFile, "utf8"))
: promptStdin
? readFileSync(0, "utf8")
: promptArgs.join(" ");
if (text.trim().length === 0) throw new Error(`${command} prompt must not be empty`);
return text;
}
const submitPromptValueOptions = new Set([
"--prompt-file",
"--file",
"--queue",
"--queue-id",
"--provider",
"--provider-id",
"--cwd",
"--workdir",
"--model",
"--reasoning-effort",
"--execution-mode",
"--mode",
"--max-attempts",
"--reference-task-id",
"--reference",
"--ref",
]);
const steerPromptValueOptions = new Set([
"--prompt-file",
"--file",
"--retry-attempts",
"--retry-delay-ms",
"--steer-id",
"--steerId",
]);
function referenceTaskIdsFromOptions(args: string[]): string[] {
const values = optionValues(args, ["--reference-task-id", "--reference", "--ref"]);
const ids: string[] = [];
for (const value of values.flatMap((item) => item.split(/[,\s]+/u))) {
const id = value.trim();
if (id.length > 0 && !ids.includes(id)) ids.push(id);
}
return ids;
}
function parseRequestedExecutionMode(value: string | undefined): string | undefined {
if (value === undefined) return undefined;
const requested = normalizeRequestedCodeExecutionMode(value);
if (requested === null) throw new Error("--execution-mode must be a short mode identifier");
return requested;
}
function executionModeSummary(requestedValue: string | null | undefined, effectiveValue?: unknown): Record<string, unknown> {
const requested = normalizeRequestedCodeExecutionMode(requestedValue);
const effective = typeof effectiveValue === "string" && effectiveValue.trim().length > 0
? normalizeCodeExecutionMode(effectiveValue)
: normalizeCodeExecutionMode(requested);
const requestedLooksLikeSandbox = requested !== null && sandboxLikeExecutionModes.has(requested);
const recognized = requestedCodeExecutionModeIsRecognized(requested);
return {
requested,
effective,
recognized,
normalized: requested !== null && requested !== effective,
availableModes: codeExecutionModes,
requestedLooksLikeSandbox,
permissionBoundary: "--execution-mode selects the Code Queue runtime mode; Codex sandbox permissions come from runnerPermissions.sandbox.",
...(requestedLooksLikeSandbox ? { warning: `${requested} is not a Code Queue execution mode and is not applied as a per-task sandbox override.` } : {}),
};
}
function dryRunRunnerPermissionsSummary(): Record<string, unknown> {
return {
observed: false,
scope: "code-queue-service-config",
sandbox: null,
approvalPolicy: null,
perTaskOverrideSupported: false,
note: "Dry-run does not contact Code Queue; real submit responses include observed runnerPermissions from the service.",
secretsPrinted: false,
};
}
function compactRunnerPermissions(value: unknown): Record<string, unknown> | null {
const record = asRecord(value);
if (record === null) return null;
return {
observed: record.observed ?? true,
scope: record.scope ?? "code-queue-service-config",
sandbox: record.sandbox ?? null,
approvalPolicy: record.approvalPolicy ?? null,
perTaskOverrideSupported: record.perTaskOverrideSupported ?? false,
secretsPrinted: false,
};
}
function compactTaskExecutionModeRequest(record: Record<string, unknown>): Record<string, unknown> {
return executionModeSummary(asString(record.requestedExecutionMode) || null, record.executionMode);
}
function parseSubmitOptions(args: string[]): CodexSubmitOptions {
assertKnownOptions(args, {
flags: ["--prompt-stdin", "--stdin", "--dry-run"],
valueOptions: [
"--prompt-file",
"--file",
"--queue",
"--queue-id",
"--provider-id",
"--provider",
"--cwd",
"--workdir",
"--model",
"--reasoning-effort",
"--execution-mode",
"--mode",
"--max-attempts",
"--reference-task-id",
"--reference",
"--ref",
],
}, "codex submit");
const maxAttempts = args.some((arg) => arg === "--max-attempts")
? positiveIntegerOption(args, ["--max-attempts"], 99, 99)
: undefined;
return {
prompt: promptFromArgs(args, "codex submit", submitPromptValueOptions),
queueId: optionValue(args, ["--queue", "--queue-id"]),
providerId: optionValue(args, ["--provider-id", "--provider"]),
cwd: optionValue(args, ["--cwd", "--workdir"]),
model: optionValue(args, ["--model"]),
reasoningEffort: optionValue(args, ["--reasoning-effort"]),
executionMode: parseRequestedExecutionMode(optionValue(args, ["--execution-mode", "--mode"])),
maxAttempts,
referenceTaskIds: referenceTaskIdsFromOptions(args),
dryRun: hasFlag(args, "--dry-run"),
};
}
function parseSteerOptions(args: string[]): CodexSteerOptions {
assertKnownOptions(args, {
flags: ["--prompt-stdin", "--stdin", "--dry-run", "--no-retry", "--full", "--raw"],
valueOptions: ["--prompt-file", "--file", "--retry-attempts", "--retry-delay-ms", "--steer-id", "--steerId"],
}, "codex steer");
const retryAttempts = hasFlag(args, "--no-retry")
? 1
: positiveIntegerOption(args, ["--retry-attempts"], defaultSteerRetryAttempts, maxSteerRetryAttempts);
const steerId = optionValue(args, ["--steer-id", "--steerId"]);
if (steerId !== undefined && !/^[A-Za-z0-9._:-]{8,128}$/u.test(steerId)) throw new Error("--steer-id must be 8-128 chars using letters, numbers, dot, underscore, colon, or dash");
return {
prompt: promptFromArgs(args, "codex steer", steerPromptValueOptions),
steerId,
dryRun: hasFlag(args, "--dry-run"),
retryAttempts,
retryDelayMs: nonNegativeIntegerOption(args, ["--retry-delay-ms"], defaultSteerRetryDelayMs, maxSteerRetryDelayMs),
full: hasFlag(args, "--full") || hasFlag(args, "--raw"),
raw: hasFlag(args, "--raw"),
};
}
function parseSteerConfirmOptions(args: string[]): CodexSteerConfirmOptions {
assertKnownOptions(args, {
flags: ["--raw"],
valueOptions: ["--steer-id", "--steerId"],
}, "codex steer-confirm");
const steerId = optionValue(args, ["--steer-id", "--steerId"]);
if (steerId === undefined) throw new Error("codex steer-confirm requires --steer-id <id>");
if (!/^[A-Za-z0-9._:-]{8,128}$/u.test(steerId)) throw new Error("--steer-id must be 8-128 chars using letters, numbers, dot, underscore, colon, or dash");
return { steerId, raw: hasFlag(args, "--raw") };
}
function parsePromptLintOptions(args: string[]): CodexPromptLintOptions {
assertKnownOptions(args, {
flags: ["--prompt-stdin", "--stdin"],
valueOptions: ["--prompt-file", "--file"],
}, "codex prompt-lint");
return {
prompt: promptFromArgs(args, "codex prompt-lint", steerPromptValueOptions),
};
}
function submitPayload(options: CodexSubmitOptions): Record<string, unknown> {
return {
prompt: options.prompt,
...(options.queueId === undefined ? {} : { queueId: options.queueId }),
...(options.providerId === undefined ? {} : { providerId: options.providerId }),
...(options.cwd === undefined ? {} : { cwd: options.cwd }),
...(options.model === undefined ? {} : { model: options.model }),
...(options.reasoningEffort === undefined ? {} : { reasoningEffort: options.reasoningEffort }),
...(options.executionMode === undefined ? {} : { executionMode: options.executionMode }),
...(options.maxAttempts === undefined ? {} : { maxAttempts: options.maxAttempts }),
...(options.referenceTaskIds.length === 0 ? {} : { referenceTaskIds: options.referenceTaskIds }),
};
}
function compactTaskMutationResponse(task: unknown, options: CompactTaskMutationResponseOptions = {}): Record<string, unknown> {
const record = asRecord(task) ?? {};
const taskId = asString(record.id);
const prompt = asString(record.displayPrompt ?? record.basePrompt ?? record.prompt);
return {
id: taskId || null,
queueId: record.queueId ?? null,
status: record.status ?? null,
queuedReason: record.queuedReason ?? null,
providerId: record.providerId ?? null,
model: record.model ?? null,
reasoningEffort: record.reasoningEffort ?? null,
cwd: record.cwd ?? null,
executionMode: record.executionMode ?? null,
requestedExecutionMode: record.requestedExecutionMode ?? null,
executionModeRequest: compactTaskExecutionModeRequest(record),
maxAttempts: record.maxAttempts ?? null,
currentAttempt: record.currentAttempt ?? null,
cancelRequested: record.cancelRequested ?? null,
schedulerHeartbeat: compactSchedulerHeartbeat(record.schedulerHeartbeat),
createdAt: record.createdAt ?? null,
startedAt: record.startedAt ?? null,
updatedAt: record.updatedAt ?? null,
finishedAt: record.finishedAt ?? null,
...(options.fullPrompt === true ? { prompt: textView(prompt, true, 1200) } : { promptPreview: textView(prompt, false, 1200) }),
commands: taskId.length === 0 ? null : {
show: `bun scripts/cli.ts codex task ${taskId}`,
trace: `bun scripts/cli.ts codex task ${taskId} --trace --tail --limit ${defaultTraceLimit}`,
output: `bun scripts/cli.ts codex output ${taskId} --tail --limit ${defaultOutputLimit}`,
steer: `bun scripts/cli.ts codex steer ${taskId} --prompt-file <path>`,
interrupt: `bun scripts/cli.ts codex interrupt ${taskId}`,
move: `bun scripts/cli.ts codex move ${taskId} --queue <queueId>`,
},
};
}
function compactSubmitTaskConfirmation(task: unknown): Record<string, unknown> {
const record = asRecord(task) ?? {};
const taskId = asString(record.id);
const prompt = asString(record.displayPrompt ?? record.basePrompt ?? record.prompt);
return {
id: taskId || null,
queueId: record.queueId ?? null,
status: record.status ?? null,
queuedReason: record.queuedReason ?? null,
providerId: record.providerId ?? null,
model: record.model ?? null,
reasoningEffort: record.reasoningEffort ?? null,
cwd: record.cwd ?? null,
executionMode: record.executionMode ?? null,
requestedExecutionMode: record.requestedExecutionMode ?? null,
executionModeRequest: compactTaskExecutionModeRequest(record),
maxAttempts: record.maxAttempts ?? null,
createdAt: record.createdAt ?? null,
updatedAt: record.updatedAt ?? null,
promptChars: prompt.length,
promptOmitted: true,
commands: taskId.length === 0 ? null : {
show: `bun scripts/cli.ts codex task ${taskId}`,
detail: `bun scripts/cli.ts codex task ${taskId} --detail`,
trace: `bun scripts/cli.ts codex task ${taskId} --trace --tail --limit ${defaultTraceLimit}`,
},
};
}
function compactSteerTaskConfirmation(task: unknown, steerId: string): Record<string, unknown> {
const compact = compactSubmitTaskConfirmation(task);
const commands = asRecord(compact.commands) ?? {};
return {
...compact,
commands: {
...commands,
traceConfirm: steerConfirmationCommand(asString(compact.id) || "<taskId>", steerId),
},
};
}
function orderedUniqueStringList(values: string[]): string[] {
const seen = new Set<string>();
const items: string[] = [];
for (const value of values) {
if (seen.has(value)) continue;
seen.add(value);
items.push(value);
}
return items;
}
function compactIdPreview(knownIds: string[], totalCount: number, limit: number, source: string, note: string | null = null): Record<string, unknown> {
const all = orderedUniqueStringList(knownIds);
const count = Math.max(0, totalCount, all.length);
const items = all.slice(0, limit);
const omitted = Math.max(0, count - items.length);
const idsUnavailable = count > 0 && items.length === 0;
const result: Record<string, unknown> = {
count,
returned: items.length,
omitted,
truncated: omitted > 0 || all.length > items.length,
source,
countsAreAuthoritative: true,
idsUnavailable,
itemsMeaning: idsUnavailable
? "not-enumerated-in-default-submit-output"
: count === 0
? "authoritative-empty"
: omitted > 0 || all.length > items.length
? "bounded-preview"
: "complete-known-list",
rawCommand: rawCodeQueueOverviewCommand,
...(note === null ? {} : { note }),
};
if (idsUnavailable) {
result.itemsOmitted = true;
result.note = note ?? "Count is nonzero, but the default submit response did not enumerate ids for this list; use rawCommand for drill-down.";
} else {
result.items = items;
}
return result;
}
function idPreviewInputItems(value: unknown): string[] {
const record = asRecord(value);
return stringList(record?.items ?? value);
}
function idPreviewInputCount(value: unknown): number {
const record = asRecord(value);
const explicit = asNumber(record?.count, Number.NaN);
if (Number.isFinite(explicit)) return explicit;
return idPreviewInputItems(value).length;
}
function countForStatus(counts: Record<string, unknown>, status: string): number {
return asNumber(counts[status], 0);
}
function maxFiniteNumber(values: number[]): number {
const finite = values.filter((value) => Number.isFinite(value));
return finite.length === 0 ? 0 : Math.max(...finite);
}
function taskIdsForStatuses(tasks: Record<string, unknown>[], statuses: Set<string> | null): string[] {
return tasks.flatMap((task) => {
const id = asString(task.id);
if (id.length === 0) return [];
if (statuses !== null && !statuses.has(asString(task.status))) return [];
return [id];
});
}
function submittedTaskState(task: Record<string, unknown>): Record<string, unknown> {
const id = asString(task.id);
const status = asString(task.status) || "unknown";
const queueId = asString(task.queueId) || null;
const state = status === "queued" || status === "retry_wait"
? "queued"
: status === "running" || status === "judging"
? "running"
: isTerminalTaskStatus(status)
? "terminal"
: "unknown";
return {
id: id || null,
queueId,
status,
state,
source: "response.tasks[].status",
};
}
function submittedTaskStatusCounts(tasks: Record<string, unknown>[]): Record<string, number> {
const counts: Record<string, number> = {};
for (const task of tasks) {
const status = asString(task.status) || "unknown";
counts[status] = (counts[status] ?? 0) + 1;
}
return counts;
}
function previewSource(parts: string[], fallback: string): string {
const unique = orderedUniqueStringList(parts.filter((part) => part.length > 0));
return unique.length > 0 ? unique.join("+") : fallback;
}
function compactSubmitQueueConfirmation(value: unknown, options: CompactSubmitQueueConfirmationOptions = {}): Record<string, unknown> | null {
const record = asRecord(value);
if (record === null) return null;
const counts = asRecord(record.counts) ?? {};
const diagnosticsRecord = asRecord(record.executionDiagnostics) ?? {};
const submittedTasks = options.submittedTasks ?? [];
const idPreviewLimit = Math.max(1, Math.min(options.idPreviewLimit ?? mutationQueueIdPreviewLimit, maxTasksLimit));
const submittedTaskIds = taskIdsForStatuses(submittedTasks, null);
const submittedQueuedTaskIds = taskIdsForStatuses(submittedTasks, new Set(["queued", "retry_wait"]));
const submittedActiveTaskIds = taskIdsForStatuses(submittedTasks, new Set(["running", "judging"]));
const upstreamQueuedTaskIds = idPreviewInputItems(record.queuedTaskIds);
const queuedKnownIds = orderedUniqueStringList([...submittedQueuedTaskIds, ...upstreamQueuedTaskIds]);
const queuedStatusCount = countForStatus(counts, "queued") + countForStatus(counts, "retry_wait");
const queuedCount = Math.max(queuedKnownIds.length, idPreviewInputCount(record.queuedTaskIds), queuedStatusCount);
const queuedPreview: Record<string, unknown> = {
...compactIdPreview(
queuedKnownIds,
queuedCount,
idPreviewLimit,
previewSource([
submittedQueuedTaskIds.length > 0 ? "submittedTaskIds" : "",
upstreamQueuedTaskIds.length > 0 ? "upstreamQueuedTaskIds" : "",
queuedKnownIds.length === 0 && queuedCount > 0 ? "aggregateCountsOnly" : "",
], "none"),
queuedCount > queuedKnownIds.length ? "Upstream did not enumerate every queued id in this low-noise mutation response; count remains authoritative." : null,
),
sourceCounts: {
queued: countForStatus(counts, "queued"),
retryWait: countForStatus(counts, "retry_wait"),
upstreamQueuedTaskIds: idPreviewInputCount(record.queuedTaskIds),
submittedQueuedTaskIds: submittedQueuedTaskIds.length,
},
};
const upstreamActiveTaskIds = idPreviewInputItems(record.activeTaskIds);
const databaseActiveTaskIds = idPreviewInputItems(record.databaseActiveTaskIds);
const diagnosticsDatabaseActiveTaskIds = idPreviewInputItems(diagnosticsRecord.databaseActiveTaskIds);
const diagnosticsHeartbeatTaskIds = idPreviewInputItems(diagnosticsRecord.heartbeatFreshTaskIds);
const activeKnownIds = orderedUniqueStringList([
...submittedActiveTaskIds,
...upstreamActiveTaskIds,
...databaseActiveTaskIds,
...diagnosticsDatabaseActiveTaskIds,
...diagnosticsHeartbeatTaskIds,
]);
const statusActiveCount = countForStatus(counts, "running") + countForStatus(counts, "judging");
const databaseActiveTaskCount = maxFiniteNumber([
databaseActiveTaskIds.length,
diagnosticsDatabaseActiveTaskIds.length,
asNumber(record.databaseActiveTaskCount, Number.NaN),
asNumber(diagnosticsRecord.databaseActiveTaskCount, Number.NaN),
]);
const activeCount = maxFiniteNumber([
activeKnownIds.length,
idPreviewInputCount(record.activeTaskIds),
databaseActiveTaskCount,
statusActiveCount,
]);
const activePreview: Record<string, unknown> = {
...compactIdPreview(
activeKnownIds,
activeCount,
idPreviewLimit,
previewSource([
submittedActiveTaskIds.length > 0 ? "submittedTaskIds" : "",
upstreamActiveTaskIds.length > 0 ? "upstreamActiveTaskIds" : "",
databaseActiveTaskIds.length > 0 ? "databaseActiveTaskIds" : "",
diagnosticsDatabaseActiveTaskIds.length > 0 ? "executionDiagnostics.databaseActiveTaskIds" : "",
diagnosticsHeartbeatTaskIds.length > 0 ? "executionDiagnostics.heartbeatFreshTaskIds" : "",
activeKnownIds.length === 0 && activeCount > 0 ? "aggregateCountsOnly" : "",
], "none"),
activeCount > activeKnownIds.length ? "Upstream only exposed aggregate active counts for part of the running set; count remains authoritative." : null,
),
sourceCounts: {
running: countForStatus(counts, "running"),
judging: countForStatus(counts, "judging"),
upstreamActiveTaskIds: idPreviewInputCount(record.activeTaskIds),
databaseActiveTaskCount,
diagnosticsDatabaseActiveTaskIds: idPreviewInputCount(diagnosticsRecord.databaseActiveTaskIds),
diagnosticsHeartbeatFreshTaskIds: idPreviewInputCount(diagnosticsRecord.heartbeatFreshTaskIds),
submittedActiveTaskIds: submittedActiveTaskIds.length,
},
};
const databaseActivePreview: Record<string, unknown> = {
...compactIdPreview(
orderedUniqueStringList([...databaseActiveTaskIds, ...diagnosticsDatabaseActiveTaskIds]),
maxFiniteNumber([databaseActiveTaskCount, idPreviewInputCount(record.databaseActiveTaskIds), idPreviewInputCount(diagnosticsRecord.databaseActiveTaskIds)]),
idPreviewLimit,
previewSource([
databaseActiveTaskIds.length > 0 ? "databaseActiveTaskIds" : "",
diagnosticsDatabaseActiveTaskIds.length > 0 ? "executionDiagnostics.databaseActiveTaskIds" : "",
databaseActiveTaskCount > 0 && databaseActiveTaskIds.length === 0 && diagnosticsDatabaseActiveTaskIds.length === 0 ? "aggregateCountsOnly" : "",
], "none"),
),
sourceCounts: {
queueDatabaseActiveTaskCount: asNumber(record.databaseActiveTaskCount, Number.NaN),
diagnosticsDatabaseActiveTaskCount: asNumber(diagnosticsRecord.databaseActiveTaskCount, Number.NaN),
queueDatabaseActiveTaskIds: idPreviewInputCount(record.databaseActiveTaskIds),
diagnosticsDatabaseActiveTaskIds: idPreviewInputCount(diagnosticsRecord.databaseActiveTaskIds),
},
};
const submittedPreview = compactIdPreview(submittedTaskIds, submittedTaskIds.length, idPreviewLimit, "response.tasks");
const omittedCounts = {
activeTaskIds: asNumber(activePreview.omitted, 0),
databaseActiveTaskIds: asNumber(databaseActivePreview.omitted, 0),
queuedTaskIds: asNumber(queuedPreview.omitted, 0),
submittedTaskIds: asNumber(submittedPreview.omitted, 0),
};
const listsTruncated = Object.values(omittedCounts).some((count) => count > 0)
|| activePreview.truncated === true
|| databaseActivePreview.truncated === true
|| queuedPreview.truncated === true
|| submittedPreview.truncated === true;
const diagnostics = compactQueueExecutionDiagnostics(record.executionDiagnostics);
const activity = compactCodeQueueActivity(record, diagnostics);
const commanderConcurrency = asRecord(activity.commanderConcurrency) ?? {};
const unavailableIdLists = {
activeTaskIds: activePreview.idsUnavailable === true,
databaseActiveTaskIds: databaseActivePreview.idsUnavailable === true,
queuedTaskIds: queuedPreview.idsUnavailable === true,
submittedTaskIds: submittedPreview.idsUnavailable === true,
};
return {
total: record.total ?? null,
queueCount: record.queueCount ?? null,
counts: record.counts ?? null,
activeQueueIds: boundedUniqueStringList(record.activeQueueIds, 8),
activeTaskIds: activePreview,
databaseActiveTaskCount,
databaseActiveTaskIds: databaseActivePreview,
queuedTaskIds: queuedPreview,
activity,
commanderConcurrency,
executionDiagnostics: diagnostics,
runnerPermissions: compactRunnerPermissions(record.runnerPermissions),
...(submittedTasks.length === 0 ? {} : { submittedTaskIds: submittedPreview }),
countContext: {
queued: countForStatus(counts, "queued"),
retryWait: countForStatus(counts, "retry_wait"),
running: countForStatus(counts, "running"),
judging: countForStatus(counts, "judging"),
active: statusActiveCount,
databaseActive: databaseActiveTaskCount,
submitted: submittedTaskIds.length,
},
listPreviewPolicy: {
bounded: true,
idPreviewLimit,
countsAreAuthoritative: true,
truncated: listsTruncated,
omittedCounts,
unavailableIdLists,
emptyItemsSemantics: "items=[] is only emitted for an authoritative empty list or a nonempty bounded preview result; if count is nonzero and ids were not enumerated, the preview omits items and sets idsUnavailable=true.",
note: listsTruncated
? "Low-noise mutation output omits additional task ids from one or more previews; use the raw command for full upstream queue detail."
: "Low-noise mutation output includes all known task ids returned for these previews.",
rawCommand: rawCodeQueueOverviewCommand,
},
stateDisclosure: {
submittedStatusSource: "response.tasks[].status",
queueCountsSource: "response.queue.counts",
activeCountField: "queue.countContext.active",
commanderActiveRunnerCountField: "queue.activity.effectiveActiveTaskCount",
splitBrainLive: diagnostics?.splitBrainLive ?? false,
splitBrainDisposition: diagnostics?.splitBrainLive === true ? "live-counts-remain-active; continue supervision unless commanderConcurrency.interventionRequired=true" : "not-split-brain-live",
idsUnavailableMeaning: "A nonzero count with idsUnavailable=true means ids were omitted or unavailable in the bounded submit summary, not that there are no tasks.",
rawCommand: rawCodeQueueOverviewCommand,
},
byQueue: Array.isArray(record.byQueue) ? record.byQueue : undefined,
};
}
function compactSubmitConcurrencyGuard(value: Record<string, unknown>): Record<string, unknown> {
return {
mode: value.mode ?? null,
acquiredAfterMs: value.acquiredAfterMs ?? null,
heldMs: value.heldMs ?? null,
throttleMs: value.throttleMs ?? null,
staleMs: value.staleMs ?? null,
};
}
function compactSubmitSuccessResponse(body: Record<string, unknown>, upstream: Record<string, unknown>, lock: Record<string, unknown>): Record<string, unknown> {
const rawTasks = asArray(body.tasks);
const submittedTasks = rawTasks.map((task) => asRecord(task)).filter((task): task is Record<string, unknown> => task !== null);
const allTasks = rawTasks.map(compactSubmitTaskConfirmation);
const tasks = allTasks.slice(0, defaultTasksLimit);
const allTaskStates = submittedTasks.map(submittedTaskState);
const taskStates = allTaskStates.slice(0, defaultTasksLimit);
const allTaskIds = allTasks.map((task) => asString(task.id)).filter(Boolean);
const taskIds = allTaskIds.slice(0, defaultTasksLimit);
const queueIds = Array.from(new Set(tasks.map((task) => asString(task.queueId)).filter(Boolean))).sort();
const firstTaskId = taskIds[0] ?? null;
const firstQueueId = queueIds[0] ?? null;
const firstSubmittedTask = submittedTasks[0] ?? {};
const queueRecord = asRecord(body.queue);
const runnerPermissions = compactRunnerPermissions(queueRecord?.runnerPermissions);
return {
ok: true,
upstream,
executionMode: executionModeSummary(asString(firstSubmittedTask.requestedExecutionMode) || null, firstSubmittedTask.executionMode),
runnerPermissions,
submitted: {
accepted: true,
taskCount: allTasks.length,
returnedTaskCount: tasks.length,
taskIds,
taskIdsCount: allTaskIds.length,
taskIdsTruncated: allTaskIds.length > taskIds.length,
queueIds,
statusCounts: submittedTaskStatusCounts(submittedTasks),
taskStates,
taskStatesTruncated: allTaskStates.length > taskStates.length,
stateSource: "response.tasks[].status is authoritative for the submitted task state at submit-confirmation time.",
tasks,
tasksTruncated: allTasks.length > tasks.length,
promptOmitted: true,
outputPolicy: {
default: "write-confirmation",
promptEchoed: false,
reason: "codex submit is a write operation; default output confirms persistence and provides drill-down commands without echoing prompt text.",
},
},
queue: compactSubmitQueueConfirmation(body.queue, { submittedTasks }),
submitConcurrencyGuard: compactSubmitConcurrencyGuard(lock),
commands: {
firstTask: firstTaskId === null ? null : `bun scripts/cli.ts codex task ${firstTaskId}`,
firstTaskDetail: firstTaskId === null ? null : `bun scripts/cli.ts codex task ${firstTaskId} --detail`,
queue: firstQueueId === null ? null : `bun scripts/cli.ts codex tasks --queue ${firstQueueId} --limit ${defaultTasksLimit}`,
supervisor: `bun scripts/cli.ts codex tasks --view supervisor --limit ${defaultTasksLimit}`,
queues: "bun scripts/cli.ts codex queues",
},
};
}
export function compactSubmitSuccessResponseForTest(body: Record<string, unknown>, upstream: Record<string, unknown> = { ok: true, status: 200 }, lock: Record<string, unknown> = {}): Record<string, unknown> {
return compactSubmitSuccessResponse(body, upstream, lock);
}
function compactTerminalReadAttempt(value: unknown): Record<string, unknown> | null {
const record = asRecord(value);
if (record === null) return null;
return {
index: record.index ?? null,
synthetic: record.synthetic ?? false,
label: record.label ?? null,
mode: record.mode ?? null,
terminalStatus: record.terminalStatus ?? null,
appServerExitCode: record.appServerExitCode ?? null,
appServerSignal: record.appServerSignal ?? null,
transportClosedBeforeTerminal: record.transportClosedBeforeTerminal ?? null,
error: record.error ?? null,
stderrTail: textView(asString(record.stderrTail), false, 1200),
startedAt: record.startedAt ?? null,
finishedAt: record.finishedAt ?? null,
startSeq: record.startSeq ?? record.outputStartSeq ?? null,
endSeq: record.endSeq ?? record.outputEndSeq ?? null,
execution: record.execution ?? null,
finalResponse: textView(asString(record.finalResponsePreview ?? record.finalResponse), false, 3000),
judge: record.judge ?? null,
runnerErrorClassification: record.runnerErrorClassification ?? null,
};
}
function compactTerminalReadFinalResponse(summary: Record<string, unknown>, readTask: Record<string, unknown>): Record<string, unknown> {
const lastAssistantMessage = asRecord(summary.lastAssistantMessage);
const text = asString(lastAssistantMessage?.text ?? summary.finalResponse ?? readTask.finalResponse);
return {
at: lastAssistantMessage?.at ?? summary.finishedAt ?? readTask.finishedAt ?? null,
seq: lastAssistantMessage?.seq ?? null,
source: lastAssistantMessage?.source ?? (text.trim().length > 0 ? "finalResponse" : "none"),
...textView(text, false, 6000),
};
}
function compactReadReferenceInjection(value: unknown): Record<string, unknown> | null {
const record = asRecord(value);
if (record === null) return null;
const items = asArray(record.items);
const returnedItems = items.slice(0, 12);
return {
version: record.version ?? null,
injectedAt: record.injectedAt ?? null,
itemCount: record.itemCount ?? null,
directReferenceTaskIds: record.directReferenceTaskIds ?? [],
maxRounds: record.maxRounds ?? null,
truncated: record.truncated ?? null,
itemsReturned: returnedItems.length,
itemsTruncated: items.length > returnedItems.length,
items: returnedItems.map((item) => {
const itemRecord = asRecord(item) ?? {};
return {
round: itemRecord.round ?? null,
roundIndex: itemRecord.roundIndex ?? null,
taskId: itemRecord.taskId ?? null,
viaTaskId: itemRecord.viaTaskId ?? null,
status: itemRecord.status ?? null,
providerId: itemRecord.providerId ?? null,
executionMode: itemRecord.executionMode ?? null,
model: itemRecord.model ?? null,
cwd: itemRecord.cwd ?? null,
createdAt: itemRecord.createdAt ?? null,
updatedAt: itemRecord.updatedAt ?? null,
promptChars: itemRecord.promptChars ?? null,
finalResponseChars: itemRecord.finalResponseChars ?? null,
finalResponseAt: itemRecord.finalResponseAt ?? null,
finalResponseSource: itemRecord.finalResponseSource ?? null,
referenceTaskIds: itemRecord.referenceTaskIds ?? [],
cliHint: itemRecord.cliHint ?? null,
};
}),
};
}
function compactTerminalReadTask(summary: unknown, readTask: unknown, taskId: string): Record<string, unknown> {
const summaryRecord = asRecord(summary) ?? {};
const readRecord = asRecord(readTask) ?? {};
const id = asString(summaryRecord.id ?? readRecord.id) || taskId;
const attempts = asArray(summaryRecord.attempts);
const lastAttempt = compactTerminalReadAttempt(attempts.at(-1));
const toolSummary = asRecord(summaryRecord.toolSummary) ?? {};
const readAt = readRecord.readAt ?? summaryRecord.readAt ?? null;
const referenceInjection = compactReadReferenceInjection(summaryRecord.referenceInjection ?? readRecord.referenceInjectionSummary);
return {
id,
queueId: summaryRecord.queueId ?? readRecord.queueId ?? null,
status: summaryRecord.status ?? readRecord.status ?? null,
terminalUnread: false,
readAt,
providerId: summaryRecord.providerId ?? readRecord.providerId ?? null,
executionMode: summaryRecord.executionMode ?? readRecord.executionMode ?? null,
requestedExecutionMode: summaryRecord.requestedExecutionMode ?? readRecord.requestedExecutionMode ?? null,
executionModeRequest: compactTaskExecutionModeRequest({
requestedExecutionMode: summaryRecord.requestedExecutionMode ?? readRecord.requestedExecutionMode ?? null,
executionMode: summaryRecord.executionMode ?? readRecord.executionMode ?? null,
}),
executionModeInfo: summaryRecord.executionModeInfo ?? readRecord.executionModeInfo ?? null,
model: summaryRecord.model ?? readRecord.model ?? null,
agentPort: summaryRecord.agentPort ?? readRecord.agentPort ?? null,
agentPortInfo: summaryRecord.agentPortInfo ?? readRecord.agentPortInfo ?? null,
cwd: summaryRecord.cwd ?? readRecord.cwd ?? null,
reasoningEffort: summaryRecord.reasoningEffort ?? readRecord.reasoningEffort ?? null,
maxAttempts: summaryRecord.maxAttempts ?? readRecord.maxAttempts ?? null,
attempts: {
currentAttempt: summaryRecord.currentAttempt ?? readRecord.currentAttempt ?? null,
maxAttempts: summaryRecord.maxAttempts ?? readRecord.maxAttempts ?? null,
currentMode: summaryRecord.currentMode ?? readRecord.currentMode ?? null,
judgeFailCount: summaryRecord.judgeFailCount ?? readRecord.judgeFailCount ?? null,
judgeFailRetryLimit: summaryRecord.judgeFailRetryLimit ?? readRecord.judgeFailRetryLimit ?? null,
count: attempts.length,
lastAttempt,
},
thread: {
codexThreadId: summaryRecord.codexThreadId ?? readRecord.codexThreadId ?? null,
activeTurnId: summaryRecord.activeTurnId ?? readRecord.activeTurnId ?? null,
cancelRequested: summaryRecord.cancelRequested ?? readRecord.cancelRequested ?? null,
},
timing: summaryRecord.timing ?? readRecord.timing ?? null,
createdAt: summaryRecord.createdAt ?? readRecord.createdAt ?? null,
startedAt: summaryRecord.startedAt ?? readRecord.startedAt ?? null,
updatedAt: summaryRecord.updatedAt ?? readRecord.updatedAt ?? null,
finishedAt: summaryRecord.finishedAt ?? readRecord.finishedAt ?? null,
referenceTaskIds: summaryRecord.referenceTaskIds ?? readRecord.referenceTaskIds ?? [],
referenceInjection,
finalResponse: compactTerminalReadFinalResponse(summaryRecord, readRecord),
lastError: summaryRecord.lastError ?? readRecord.lastError ?? lastAttempt?.error ?? null,
lastJudge: summaryRecord.lastJudge ?? readRecord.lastJudge ?? null,
counts: {
transcript: summaryRecord.transcriptCount ?? readRecord.transcriptCount ?? null,
transcriptMaxSeq: summaryRecord.transcriptMaxSeq ?? readRecord.transcriptMaxSeq ?? null,
output: summaryRecord.outputCount ?? readRecord.outputCount ?? null,
retainedOutput: summaryRecord.retainedOutputCount ?? readRecord.retainedOutputCount ?? null,
outputMaxSeq: summaryRecord.outputMaxSeq ?? readRecord.outputMaxSeq ?? null,
events: summaryRecord.eventCount ?? readRecord.eventCount ?? null,
tools: toolSummary.count ?? null,
},
disclosure: {
mode: "terminal-read",
promptIncluded: false,
toolLogsIncluded: false,
finalResponseIncluded: true,
promptChars: asString(summaryRecord.initialPrompt ?? summaryRecord.prompt).length || (summaryRecord.promptChars ?? null),
toolCount: toolSummary.count ?? null,
policy: "read returns terminal metadata and final response; prompt and tool logs remain behind explicit progressive drill-down commands",
},
commands: {
show: `bun scripts/cli.ts codex task ${id}`,
detail: `bun scripts/cli.ts codex task ${id} --detail`,
full: `bun scripts/cli.ts codex task ${id} --full`,
trace: `bun scripts/cli.ts codex task ${id} --trace --tail --limit ${defaultTraceLimit}`,
output: `bun scripts/cli.ts codex output ${id} --tail --limit ${defaultOutputLimit}`,
},
};
}
function codexReadTaskWithFetcher(taskId: string, fetcher: CodexResponseFetcher): unknown {
const summaryResponse = unwrapCodexResponse(fetcher(codeQueueProxyPath(`/api/tasks/${encodeURIComponent(taskId)}/summary${queryString({ toolLimit: defaultToolLimit })}`)));
const response = unwrapCodexResponse(fetcher(codeQueueProxyPath(`/api/tasks/${encodeURIComponent(taskId)}/read`), { method: "POST", body: {} }));
const readTask = asRecord(response.body.task) ?? {};
const terminalUnread = readTask.terminalUnread ?? readTask.unreadTerminal ?? false;
return {
upstream: {
summary: summaryResponse.upstream,
read: response.upstream,
},
read: {
marked: true,
readAt: readTask.readAt ?? null,
terminalUnread,
},
task: compactTerminalReadTask(summaryResponse.body.summary, response.body.task, taskId),
queue: compactQueueMutationSummary(response.body.queue),
commands: {
show: `bun scripts/cli.ts codex task ${taskId}`,
detail: `bun scripts/cli.ts codex task ${taskId} --detail`,
trace: `bun scripts/cli.ts codex task ${taskId} --trace --tail --limit ${defaultTraceLimit}`,
output: `bun scripts/cli.ts codex output ${taskId} --tail --limit ${defaultOutputLimit}`,
unread: `bun scripts/cli.ts codex unread --limit ${defaultTasksLimit}`,
},
};
}
function codexReadTask(taskId: string): unknown {
return codexReadTaskWithFetcher(taskId, coreInternalFetch);
}
export function codexReadTaskForTest(taskId: string, fetcher: CodexResponseFetcher): unknown {
return codexReadTaskWithFetcher(taskId, fetcher);
}
function compactQueueMutationSummary(value: unknown): Record<string, unknown> | null {
const record = asRecord(value);
if (record === null) return null;
return {
activeQueueIds: record.activeQueueIds ?? null,
activeTaskIds: record.activeTaskIds ?? null,
databaseActiveTaskCount: record.databaseActiveTaskCount ?? null,
databaseActiveTaskIds: record.databaseActiveTaskIds ?? null,
schedulerHeartbeatStaleMs: record.schedulerHeartbeatStaleMs ?? null,
executionDiagnostics: compactExecutionDiagnostics(record.executionDiagnostics),
queuedTaskIds: record.queuedTaskIds ?? null,
counts: record.counts ?? null,
byQueue: Array.isArray(record.byQueue) ? record.byQueue : undefined,
};
}
function compactSkillsStatus(value: unknown): Record<string, unknown> | null {
const record = asRecord(value);
if (record === null) return null;
return {
ok: record.ok ?? false,
path: record.path ?? null,
source: record.source ?? null,
target: record.target ?? null,
mountPoint: record.mountPoint ?? null,
exists: record.exists ?? false,
available: record.available ?? false,
degraded: record.degraded ?? true,
blocker: record.blocker ?? null,
readonly: record.readonly ?? false,
skillCount: record.skillCount ?? 0,
requiredSkills: Array.isArray(record.requiredSkills) ? record.requiredSkills : [],
missingSkills: Array.isArray(record.missingSkills) ? record.missingSkills : [],
valuesPrinted: record.valuesPrinted ?? false,
pathSpelling: compactObjectFields(asRecord(record.pathSpelling), [
"expectedTarget",
"forbiddenPathChecked",
"forbiddenPathExists",
"forbiddenPathConfigured",
"forbiddenPathRoles",
"forbiddenPathMustNotBeUsed",
]),
repairHint: record.repairHint ?? null,
};
}
function compactSkillPathReport(value: unknown): Record<string, unknown> | null {
const record = asRecord(value);
if (record === null) return null;
return {
path: record.path ?? null,
approved: record.approved ?? false,
exists: record.exists ?? false,
directory: record.directory ?? false,
readable: record.readable ?? false,
writable: record.writable ?? false,
readonly: record.readonly ?? false,
mountPoint: record.mountPoint ?? null,
skillCount: record.skillCount ?? 0,
requiredSkills: Array.isArray(record.requiredSkills) ? record.requiredSkills.map(String) : [],
missingSkills: Array.isArray(record.missingSkills) ? record.missingSkills.map(String) : [],
error: record.error ?? null,
};
}
function compactSkillsSyncStatus(value: unknown, full = false): Record<string, unknown> | null {
const record = asRecord(value);
if (record === null) return null;
const source = compactSkillPathReport(record.source);
const target = compactSkillPathReport(record.target);
const compact: Record<string, unknown> = {
ok: record.ok ?? false,
degraded: record.degraded ?? true,
blocker: record.blocker ?? null,
checkedAt: record.checkedAt ?? null,
mode: record.mode ?? "dry-run",
dryRun: record.dryRun ?? true,
mutation: record.mutation ?? false,
syncMode: record.syncMode ?? null,
source,
target,
expected: record.expected ?? null,
counts: record.counts ?? null,
missing: record.missing ?? null,
permissionFailures: Array.isArray(record.permissionFailures) ? record.permissionFailures.slice(0, full ? undefined : 4) : [],
permissionFailureCount: Array.isArray(record.permissionFailures) ? record.permissionFailures.length : 0,
pathSpelling: record.pathSpelling ?? null,
plannedActions: record.plannedActions ?? null,
instructions: Array.isArray(record.instructions) ? record.instructions.map(String).slice(0, full ? undefined : 4) : [],
commands: record.commands ?? null,
valuesPrinted: record.valuesPrinted ?? false,
};
if (full) compact.rawSkillsSync = record;
return compact;
}
function codeQueueDevReady(): unknown {
const response = unwrapCodexResponse(coreInternalFetch(codeQueueProxyPath("/api/dev-ready")));
const devReady = asRecord(response.body.devReady) ?? {};
return {
upstream: response.upstream,
devReady: {
ok: devReady.ok ?? false,
missingTools: devReady.missingTools ?? [],
workdir: devReady.workdir ?? null,
docker: devReady.docker ?? null,
codexConfig: devReady.codexConfig ?? null,
ssh: devReady.ssh ?? null,
skills: compactSkillsStatus(devReady.skills),
skillsSync: compactSkillsSyncStatus(devReady.skillsSync),
},
commands: {
health: "bun scripts/cli.ts codex dev-ready",
raw: "bun scripts/cli.ts microservice proxy code-queue /api/dev-ready --raw",
skillsSync: "bun scripts/cli.ts codex skills-sync --dry-run",
},
};
}
function codeQueueSkillsSync(args: string[]): unknown {
const options = parseSkillsSyncOptions(args);
if (!options.dryRun) {
return {
ok: false,
failureKind: "dry-run-required",
runnerDisposition: "business-failed",
message: "codex skills-sync is dry-run only; pass --dry-run",
mutation: false,
commands: {
dryRun: "bun scripts/cli.ts codex skills-sync --dry-run",
full: "bun scripts/cli.ts codex skills-sync --dry-run --full",
},
};
}
const rawResponse = coreInternalFetch(codeQueueProxyPath("/api/skills-sync?dryRun=1"));
const response = asRecord(rawResponse);
if (response?.ok !== true) {
const targetStack = asRecord(response?.targetStack);
const observed = asRecord(response?.observed);
const missingContainers = Array.isArray(targetStack?.missingContainers) ? targetStack.missingContainers.map(String) : [];
const relatedContainers = Array.isArray(targetStack?.relatedContainers) ? targetStack.relatedContainers : [];
return {
ok: false,
dryRun: true,
mutation: false,
runnerDisposition: response?.runnerDisposition ?? "infra-blocked",
failureKind: response?.failureKind ?? "control-plane-missing",
degradedReason: response?.degradedReason ?? "backend-core-proxy-unavailable",
message: response?.message ?? response?.stderrTail ?? response?.stdoutTail ?? "Code Queue skills sync dry-run could not reach the control plane",
controlPlane: {
mode: "local-backend-core",
localBackendCoreMissing: response?.failureKind === "target-stack-not-running",
schedulerStateChanged: false,
liveRunnerHostPathMutated: false,
},
targetStackSummary: targetStack === null ? null : {
missingContainers,
missingContainerCount: missingContainers.length,
relatedContainerCount: relatedContainers.length,
verifyOnlyObserved: targetStack.verifyOnlyObserved ?? false,
},
observed: observed === null ? null : {
commandExitCode: observed.commandExitCode ?? null,
stderrTail: typeof observed.stderrTail === "string" ? textView(observed.stderrTail, false, 600) : null,
},
outputPolicy: {
default: "compact-skills-sync-control-plane-failure",
unrelatedDiagnosticsOmitted: true,
full: "use microservice health/proxy commands only when control-plane diagnostics are needed",
},
commands: {
retry: "bun scripts/cli.ts codex skills-sync --dry-run",
full: "bun scripts/cli.ts codex skills-sync --dry-run --full",
health: "bun scripts/cli.ts microservice health code-queue",
rawProxy: "bun scripts/cli.ts microservice proxy code-queue /api/skills-sync?dryRun=1 --raw --full",
},
};
}
const body = asRecord(response.body);
if (body?.ok !== true) {
return {
ok: false,
dryRun: true,
mutation: false,
runnerDisposition: "infra-blocked",
failureKind: "runtime-skills-sync-missing",
degradedReason: "runtime-skills-sync-response-invalid",
message: "Code Queue skills sync dry-run response did not include a valid body",
upstream: { ok: response.ok, status: response.status ?? null },
bodyPreview: body,
commands: {
retry: "bun scripts/cli.ts codex skills-sync --dry-run",
rawProxy: "bun scripts/cli.ts microservice proxy code-queue /api/skills-sync?dryRun=1 --raw --full",
},
};
}
const skillsSync = asRecord(body.skillsSync);
return {
upstream: { ok: response.ok, status: response.status ?? null },
skillsSync: compactSkillsSyncStatus(skillsSync, options.full),
outputPolicy: {
default: "compact-skills-sync-dry-run",
full: "bun scripts/cli.ts codex skills-sync --dry-run --full",
mutation: false,
},
};
}
function compactCommandProbe(value: unknown): Record<string, unknown> | null {
const probe = asRecord(value);
if (probe === null) return null;
return {
command: probe.command ?? null,
args: Array.isArray(probe.args) ? probe.args : [],
ok: probe.ok ?? false,
exitCode: probe.exitCode ?? null,
signal: probe.signal ?? null,
error: probe.error ?? null,
stdout: typeof probe.stdout === "string" ? textView(probe.stdout, false, 1200) : null,
stderr: typeof probe.stderr === "string" ? textView(probe.stderr, false, 1200) : null,
};
}
function commandProbeFailureText(value: unknown): string {
const probe = asRecord(value);
if (probe === null || probe.ok === true) return "";
const args = Array.isArray(probe.args) ? probe.args.map(String).join(" ") : "";
return [
typeof probe.command === "string" ? probe.command : "",
args,
typeof probe.error === "string" ? probe.error : "",
typeof probe.stderr === "string" ? probe.stderr : "",
typeof probe.stdout === "string" ? probe.stdout : "",
].filter((item) => item.length > 0).join("\n");
}
function commandProbeLooksLikeGithubTransient(value: unknown): boolean {
const text = commandProbeFailureText(value);
if (text.length === 0) return false;
if (/\bproxy\b/iu.test(text) && /could not resolve|connect|tunnel|proxy/iu.test(text)) return false;
return /temporary failure in name resolution|error connecting to api\.github\.com|getaddrinfo|could not resolve host:? (github\.com|api\.github\.com)|name or service not known|eai_again|enotfound|etimedout|econnreset|ehostunreach|enetunreach|failed to connect to (github\.com|api\.github\.com)|network is unreachable/iu.test(text);
}
function githubTransientEvidence(pull: Record<string, unknown>): Record<string, unknown> | null {
const egress = asRecord(pull.egress) ?? {};
const remote = asRecord(pull.remote);
const probes: Array<[string, unknown]> = [
["egress.githubDefault", egress.githubDefault],
["egress.apiDefault", egress.apiDefault],
["egress.issueApi", egress.issueApi],
];
if (remote !== null) {
probes.push(
["remote.gitLsRemote", remote.gitLsRemote],
["remote.gitHttpsLsRemote", remote.gitHttpsLsRemote],
["remote.ghAuthStatus", remote.ghAuthStatus],
["remote.ghRepoView", remote.ghRepoView],
["remote.ghIssueView", remote.ghIssueView],
["remote.ghPrReadOnly", remote.ghPrReadOnly],
);
}
const failedProbes = probes
.map(([name, probe]) => ({ name, probe, text: commandProbeFailureText(probe) }))
.filter((item) => commandProbeLooksLikeGithubTransient(item.probe))
.slice(0, 4);
if (failedProbes.length === 0) return null;
return {
kind: "github-transient",
retryable: true,
scope: "github-dns-api",
failedProbes: failedProbes.map((item) => ({
name: item.name,
preview: compactInlinePreview(item.text, 240),
})),
commanderAction: "retry/backoff; if Code Queue heartbeat or trace is fresh, keep the task running and continue supervision",
notAuthMissing: true,
notPrSemanticFailure: true,
valuesPrinted: false,
};
}
function compactToolStatus(value: unknown): Record<string, unknown> {
const tool = asRecord(value) ?? {};
return {
ok: tool.ok ?? false,
path: tool.path ?? null,
version: tool.version ?? null,
};
}
function compactUniDeskGhCliStatus(value: unknown): Record<string, unknown> {
const cli = asRecord(value);
const observed = cli !== null;
const ok = observed ? cli.ok === true : null;
return {
ok,
observed,
path: observed ? cli.path ?? null : null,
present: observed ? cli.present ?? false : null,
role: "repo-native REST GitHub CLI used by bun scripts/cli.ts gh",
requiresSystemGhBinary: false,
unavailableReason: ok === true
? null
: observed
? "scripts-cli-missing"
: "runtime-preflight-did-not-report-unidesk-gh-cli",
};
}
function compactAuthBrokerRuntimeStatus(value: unknown): Record<string, unknown> {
const broker = asRecord(value);
const observed = broker !== null;
const capability = asRecord(broker?.capability);
const configured = broker?.configured === true || broker?.ok === true && broker?.source === "auth-broker";
const operations = Array.isArray(capability?.operations)
? capability.operations.map(String)
: ["github.auth.status", "github.issue.read", "github.pr.read", "github.pr.create"];
return {
ok: configured,
observed,
configured,
source: typeof broker?.source === "string" ? broker.source : configured ? "auth-broker" : "broker/auth-broker-needed",
endpointEnvKey: typeof broker?.endpointEnvKey === "string" ? broker.endpointEnvKey : null,
runnerEnvTokenRequired: broker?.runnerEnvTokenRequired === true,
credentialSource: typeof broker?.credentialSource === "string" ? broker.credentialSource : configured ? "broker-held-github-credential" : null,
failureKind: configured ? null : broker?.failureKind ?? "auth-missing",
degradedReason: configured ? null : broker?.degradedReason ?? "auth-broker-needed",
capability: {
source: typeof capability?.source === "string" ? capability.source : configured ? "broker-issued-token" : "missing-token",
githubRestAuth: capability?.githubRestAuth === true || configured,
operations,
systemGhBinaryRequiredForWrites: false,
preflightWritesRemote: false,
preflightCreatesPr: false,
preflightMergesPr: false,
realPrCreateRequiresCommanderAuthorization: true,
valuesPrinted: false,
},
nextAction: typeof broker?.nextAction === "string"
? broker.nextAction
: configured
? "use-auth-broker"
: "configure-auth-broker-or-env-token",
next: Array.isArray(broker?.next) ? broker.next.map(String) : configured
? ["keep PR preflight read-only; create a real PR only after commander authorization"]
: [
"configure UNIDESK_AUTH_BROKER_URL or AUTH_BROKER_URL for broker-backed runner auth",
"or inject GH_TOKEN/GITHUB_TOKEN into the Code Queue scheduler runtime secret until broker mode is live",
],
valuesRead: false,
valuesPrinted: false,
};
}
function compactAgentPortStatus(value: unknown): Record<string, unknown> {
const port = asRecord(value) ?? {};
return {
ok: port.ok ?? false,
commandPath: port.commandPath ?? null,
version: port.version ?? null,
errors: Array.isArray(port.errors) ? port.errors : [],
};
}
function tokenCoverageStatus(credentials: Record<string, unknown>, authBroker: Record<string, unknown>): Record<string, unknown> {
const ghTokenPresent = credentials.ghTokenPresent === true;
const githubTokenPresent = credentials.githubTokenPresent === true;
const anyEnvToken = ghTokenPresent || githubTokenPresent;
const anyGhCredentialStore = credentials.ghHostsConfigPresent === true || credentials.gitCredentialsPresent === true;
const authBrokerOk = authBroker.ok === true;
const effective = authBrokerOk || anyEnvToken;
const envSource = ghTokenPresent ? "GH_TOKEN" : githubTokenPresent ? "GITHUB_TOKEN" : null;
return {
ok: effective,
source: authBrokerOk ? "auth-broker" : envSource,
credentialSource: authBrokerOk ? "broker-issued-token" : anyEnvToken ? "env-token" : null,
ghTokenPresent,
githubTokenPresent,
ghCredentialStorePresent: anyGhCredentialStore,
authBrokerPresent: authBrokerOk,
authBrokerSource: authBroker.source ?? null,
runnerEnvTokenRequired: !authBrokerOk,
runnerDisposition: effective ? "ready" : "infra-blocked",
missing: effective ? [] : ["GH_TOKEN", "GITHUB_TOKEN"],
envMissing: anyEnvToken ? [] : ["GH_TOKEN", "GITHUB_TOKEN"],
scope: authBrokerOk ? "broker-held-github-credential" : "scheduler-runner-env",
note: authBrokerOk
? "scheduler can use auth-broker for GitHub REST PR preflight without exposing GH_TOKEN/GITHUB_TOKEN to runner env"
: anyEnvToken
? "scheduler has a GitHub env token that can be forwarded to provider dev containers through CODE_QUEUE_REMOTE_CODEX_ENV_KEYS"
: "scheduler is missing GH_TOKEN/GITHUB_TOKEN and auth-broker is not configured; provider dev containers cannot receive a GitHub token even though CODE_QUEUE_REMOTE_CODEX_ENV_KEYS includes those keys",
};
}
function authBrokerNeededStatus(tokenCoverage: Record<string, unknown>, runtimeAuthBroker: Record<string, unknown>, systemGhBinary: Record<string, unknown>, unideskGhCli: Record<string, unknown>): Record<string, unknown> {
const missing = Array.isArray(tokenCoverage.missing) ? tokenCoverage.missing.map(String) : [];
const ready = tokenCoverage.ok === true;
const authBrokerReady = tokenCoverage.source === "auth-broker";
const needed = !ready;
const capability = asRecord(runtimeAuthBroker.capability) ?? {};
const capabilitySource = tokenCoverage.credentialSource ?? "missing-token";
const nextAction = authBrokerReady
? "use-auth-broker"
: ready
? "use-env-token-until-auth-broker-live"
: "configure-auth-broker-or-env-token";
return {
ok: ready,
source: authBrokerReady ? "auth-broker" : needed ? "broker/auth-broker-needed" : tokenCoverage.source ?? "runner-env-token",
needed,
configured: runtimeAuthBroker.configured === true,
runnerDisposition: needed ? "infra-blocked" : "ready",
failureKind: needed ? "auth-missing" : null,
degradedReason: needed ? "auth-broker-needed" : null,
runnerEnvTokenRequiredWithoutBroker: !authBrokerReady,
brokerCredentialSource: authBrokerReady ? runtimeAuthBroker.credentialSource ?? "broker-held-github-credential" : null,
capability: {
source: capabilitySource,
githubRestAuth: ready,
operations: Array.isArray(capability.operations)
? capability.operations.map(String)
: ["github.auth.status", "github.issue.read", "github.pr.read", "github.pr.create"],
systemGhBinaryRequiredForWrites: false,
unideskGhCliRequired: true,
preflightWritesRemote: false,
preflightCreatesPr: false,
preflightMergesPr: false,
realPrCreateRequiresCommanderAuthorization: true,
valuesPrinted: false,
},
nextAction,
valuesPrinted: false,
evidence: {
envTokenMissing: needed,
missing,
authBrokerObserved: runtimeAuthBroker.observed ?? false,
authBrokerConfigured: runtimeAuthBroker.configured ?? false,
authBrokerSource: runtimeAuthBroker.source ?? null,
systemGhBinaryOk: systemGhBinary.ok === true,
systemGhBinaryRequiredForWrites: false,
unideskGhCliObserved: unideskGhCli.observed ?? false,
unideskGhCliOk: unideskGhCli.ok ?? null,
unideskGhCliRequiresSystemGhBinary: false,
systemGhMissingMisclassifiedAsUniDeskCliMissing: false,
},
next: needed
? [
"configure UNIDESK_AUTH_BROKER_URL or AUTH_BROKER_URL so PR preflight can use a broker-held GitHub credential without exposing runner env tokens",
"or inject GH_TOKEN/GITHUB_TOKEN into the Code Queue scheduler runtime secret until broker mode is live",
]
: authBrokerReady
? ["keep PR preflight read-only; create a real PR only after commander authorization"]
: ["env token path is ready; Auth Broker is still needed before removing runner env GitHub credentials"],
reference: "docs/reference/auth-broker.md#post-v1githubpr-preflight",
};
}
function activeRunnerDevContainerCapability(): Record<string, unknown> {
const ghTokenPresent = typeof process.env.GH_TOKEN === "string" && process.env.GH_TOKEN.length > 0;
const githubTokenPresent = typeof process.env.GITHUB_TOKEN === "string" && process.env.GITHUB_TOKEN.length > 0;
const anyToken = ghTokenPresent || githubTokenPresent;
return {
scope: "current-cli-process",
applicableWhen: "this command is running inside the active Code Queue runner/dev container",
observed: true,
ok: anyToken,
ghTokenPresent,
githubTokenPresent,
credentialSource: ghTokenPresent ? "GH_TOKEN" : githubTokenPresent ? "GITHUB_TOKEN" : null,
notEquivalentToSchedulerEnv: true,
relationToRemotePreflight: "independent-scope; scheduler-runner-env auth-missing does not prove the active runner/dev container lacks GitHub PR capability",
valuesPrinted: false,
commands: {
authStatus: "bun scripts/cli.ts gh auth status --repo pikasTech/unidesk",
prCreateDryRun: "bun scripts/cli.ts gh pr create --repo pikasTech/unidesk --title <title> --body-file <file> --base master --head <head> --dry-run",
prCommentDryRun: "bun scripts/cli.ts gh pr comment create <number> --repo pikasTech/unidesk --body-file <file> --dry-run",
},
interpretation: anyToken
? "current CLI process has a GitHub token candidate; validate with gh auth status and PR dry-run before declaring this runner unable to create/comment PRs"
: "current CLI process did not expose GH_TOKEN/GITHUB_TOKEN; this still does not prove another active runner/dev container lacks token coverage",
};
}
function prPreflightScopeBoundary(tokenCoverage: Record<string, unknown> | null): Record<string, unknown> {
const schedulerScope = typeof tokenCoverage?.scope === "string" ? tokenCoverage.scope : "scheduler-runner-env";
return {
headline: "scheduler-runner-env auth-missing is not active runner/dev container PR incapability",
schedulerPreflightScope: schedulerScope,
activeRunnerDevContainerScope: "current-cli-process",
scopesAreIndependent: true,
schedulerAuthMissingDoesNotMeanActiveRunnerCannotCreatePr: true,
authMissingInterpretation: "auth-missing from codex pr-preflight --remote is scoped to the scheduler/runtime preflight surface; do not simplify it to 'the active runner cannot create PRs'",
currentRunnerCheck: "use activeRunnerDevContainer plus bun scripts/cli.ts gh auth status --repo pikasTech/unidesk and gh pr create --dry-run for the current dev container",
valuesPrinted: false,
};
}
function prPreflightRecommendedActions(tokenCoverage: Record<string, unknown> | null): Record<string, unknown>[] {
const schedulerReady = tokenCoverage?.ok === true;
return [
{
scope: "active-runner-dev-container",
priority: "first",
action: "verify-current-runner-auth",
command: "bun scripts/cli.ts gh auth status --repo pikasTech/unidesk",
writesRemote: false,
},
{
scope: "active-runner-dev-container",
priority: "first",
action: "verify-current-runner-pr-create-plan",
command: "bun scripts/cli.ts gh pr create --repo pikasTech/unidesk --title <title> --body-file <file> --base master --head <head> --dry-run",
writesRemote: false,
},
{
scope: "scheduler-runtime",
priority: schedulerReady ? "long-term" : "required-for-scheduler-preflight",
action: "configure-scheduler-auth-source",
command: "configure auth-broker or inject GH_TOKEN/GITHUB_TOKEN via the scheduler runtime secret",
writesRemote: false,
},
];
}
function prPreflightAuthScopeSummary(tokenCoverage: Record<string, unknown> | null, activeRunnerDevContainer: Record<string, unknown>): Record<string, unknown> {
const schedulerReady = tokenCoverage?.ok === true;
return {
schedulerPreflightScope: typeof tokenCoverage?.scope === "string" ? tokenCoverage.scope : "scheduler-runner-env",
schedulerAuthReady: schedulerReady,
schedulerAuthSource: tokenCoverage?.source ?? null,
schedulerAuthMissingIsScoped: !schedulerReady,
activeRunnerDevContainerScope: activeRunnerDevContainer.scope ?? "current-cli-process",
activeRunnerTokenCandidatePresent: activeRunnerDevContainer.ok === true,
interpretation: schedulerReady
? "scheduler preflight has GitHub auth coverage; active runner PR creation still needs repo-native dry-run verification before real writes"
: "scheduler-runner-env auth-missing does not prove the active runner/dev container lacks PR create/comment capability",
valuesPrinted: false,
};
}
function prPreflightTokenCoverage(record: Record<string, unknown>): Record<string, unknown> | null {
const preflight = asRecord(record.preflight);
const schedulerPreflight = asRecord(record.schedulerPreflight);
const schedulerAuth = asRecord(schedulerPreflight?.auth);
const schedulerSummary = schedulerPreflight === null ? null : {
ok: schedulerPreflight.authReady ?? null,
source: schedulerPreflight.authSource ?? null,
credentialSource: schedulerPreflight.credentialSource ?? null,
scope: schedulerPreflight.scope ?? null,
missing: Array.isArray(schedulerPreflight.missing) && schedulerPreflight.missing.length > 0
? schedulerPreflight.missing.map(String)
: schedulerPreflight.authReady === false
? ["GH_TOKEN", "GITHUB_TOKEN"]
: [],
runnerDisposition: schedulerPreflight.authReady === true ? "ready" : "infra-blocked",
};
return asRecord(record.tokenCoverage)
?? asRecord(preflight?.tokenCoverage)
?? schedulerAuth
?? schedulerSummary
?? null;
}
function prPreflightAuthBroker(record: Record<string, unknown>): Record<string, unknown> | null {
const preflight = asRecord(record.preflight);
const schedulerPreflight = asRecord(record.schedulerPreflight);
return asRecord(record.authBroker)
?? asRecord(preflight?.authBroker)
?? asRecord(schedulerPreflight?.authBroker)
?? null;
}
function prPreflightCapabilityContract(record: Record<string, unknown>): Record<string, unknown> | null {
const preflight = asRecord(record.preflight);
const prCapability = asRecord(record.prCapability);
return asRecord(record.prCapabilityContract)
?? asRecord(preflight?.prCapabilityContract)
?? prCapability
?? null;
}
function prPreflightCommandSet(record: Record<string, unknown>, options: CodexPrPreflightOptions): Record<string, unknown> {
const preflight = asRecord(record.preflight);
const commands = asRecord(record.commands) ?? asRecord(preflight?.commands) ?? {};
const activeRunnerDevContainer = asRecord(record.activeRunnerDevContainer) ?? activeRunnerDevContainerCapability();
const activeCommands = asRecord(activeRunnerDevContainer.commands) ?? {};
const remoteFlag = options.remote ? " --remote" : "";
const fullDetail = `bun scripts/cli.ts codex pr-preflight${remoteFlag} --full`;
return {
verifyActiveRunnerAuth: activeCommands.authStatus ?? commands.local ?? "bun scripts/cli.ts gh auth status --repo pikasTech/unidesk",
verifyActiveRunnerPrCreateDryRun: activeCommands.prCreateDryRun ?? "bun scripts/cli.ts gh pr create --repo pikasTech/unidesk --title <title> --body-file <file> --base master --head <head> --dry-run",
rerunSchedulerPreflight: commands.runner ?? `bun scripts/cli.ts codex pr-preflight${remoteFlag}`,
fullDetail,
rawProxy: commands.rawProxy ?? "bun scripts/cli.ts microservice proxy code-queue /api/runtime-preflight?remote=1 --raw --full",
schedulerAuthSource: "configure auth-broker or inject GH_TOKEN/GITHUB_TOKEN into the scheduler runtime secret",
};
}
function compactRecommendedActions(record: Record<string, unknown>): Record<string, unknown>[] {
const actions = Array.isArray(record.recommendedActions) ? record.recommendedActions : [];
if (actions.length > 0) {
return actions.slice(0, 3).map((item) => {
const action = asRecord(item) ?? {};
return {
scope: action.scope ?? null,
priority: action.priority ?? null,
action: action.action ?? null,
command: action.command ?? null,
writesRemote: action.writesRemote ?? false,
};
});
}
const tokenCoverage = prPreflightTokenCoverage(record);
return prPreflightRecommendedActions(tokenCoverage);
}
function compactPrPreflightCommanderView(record: Record<string, unknown>, options: CodexPrPreflightOptions): Record<string, unknown> {
if (options.full) return record;
const tokenCoverage = prPreflightTokenCoverage(record);
const authBroker = prPreflightAuthBroker(record);
const capability = prPreflightCapabilityContract(record);
const activeRunnerDevContainer = asRecord(record.activeRunnerDevContainer) ?? activeRunnerDevContainerCapability();
const activeCommands = asRecord(activeRunnerDevContainer.commands) ?? {};
const authBrokerCapability = asRecord(authBroker?.capability);
const expectedPrHandoff = asRecord(capability?.expectedPrHandoff);
const unideskGhCli = asRecord(capability?.unideskGhCli);
const pushDryRun = asRecord(capability?.pushDryRun);
const prCreateDryRun = asRecord(capability?.prCreateDryRun);
const unsupportedMergeBoundary = asRecord(capability?.unsupportedMergeBoundary);
const commands = prPreflightCommandSet(record, options);
const schedulerAuthReady = tokenCoverage?.ok === true;
const activeRunnerTokenCandidatePresent = activeRunnerDevContainer.ok === true;
const failureKind = record.failureKind ?? (schedulerAuthReady ? null : "auth-missing");
const degradedReason = record.degradedReason ?? (schedulerAuthReady ? null : "auth-broker-needed");
const githubTransient = asRecord(record.githubTransient);
return {
ok: record.ok === true,
runnerDisposition: record.runnerDisposition ?? (record.ok === true ? "ready" : "infra-blocked"),
failureKind,
degradedReason,
...(record.retryable === true ? { retryable: true } : {}),
...(typeof record.commanderAction === "string" ? { commanderAction: record.commanderAction } : {}),
...(githubTransient === null ? {} : { githubTransient }),
summary: {
status: record.ok === true ? "ready" : "blocked",
schedulerPreflightAuthReady: schedulerAuthReady,
schedulerPreflightScope: tokenCoverage?.scope ?? "scheduler-runner-env",
activeRunnerTokenCandidatePresent,
activeRunnerScope: activeRunnerDevContainer.scope ?? "current-cli-process",
interpretation: schedulerAuthReady
? "scheduler preflight auth is ready; still use active-runner dry-runs before writes"
: "scheduler auth is missing for preflight admission only; this does not prove the active runner/dev container cannot create or comment PRs",
},
schedulerPreflight: {
scope: tokenCoverage?.scope ?? "scheduler-runner-env",
authReady: schedulerAuthReady,
authSource: tokenCoverage?.source ?? null,
credentialSource: tokenCoverage?.credentialSource ?? null,
missing: Array.isArray(tokenCoverage?.missing) ? tokenCoverage.missing.map(String) : [],
failureKind: schedulerAuthReady ? null : failureKind,
degradedReason: schedulerAuthReady ? null : degradedReason,
authBroker: authBroker === null ? null : {
ok: authBroker.ok ?? schedulerAuthReady,
source: authBroker.source ?? null,
configured: authBroker.configured ?? null,
needed: authBroker.needed ?? !schedulerAuthReady,
nextAction: authBroker.nextAction ?? null,
capabilitySource: authBrokerCapability?.source ?? tokenCoverage?.credentialSource ?? null,
},
},
activeRunnerPrCapability: {
scope: activeRunnerDevContainer.scope ?? "current-cli-process",
tokenCandidatePresent: activeRunnerTokenCandidatePresent,
credentialSource: activeRunnerDevContainer.credentialSource ?? null,
ghTokenPresent: activeRunnerDevContainer.ghTokenPresent ?? false,
githubTokenPresent: activeRunnerDevContainer.githubTokenPresent ?? false,
independentOfSchedulerPreflight: activeRunnerDevContainer.notEquivalentToSchedulerEnv ?? true,
verifyCommands: {
authStatus: activeCommands.authStatus ?? commands.verifyActiveRunnerAuth,
prCreateDryRun: activeCommands.prCreateDryRun ?? commands.verifyActiveRunnerPrCreateDryRun,
},
},
prCapability: capability === null ? null : {
targetBranch: capability.targetBranch ?? "master",
sourceBranch: expectedPrHandoff?.sourceBranch ?? prCreateDryRun?.headBranch ?? null,
unideskGhCliOk: unideskGhCli?.ok ?? null,
systemGhBinaryRequiredForWrites: capability.systemGhBinaryRequiredForWrites ?? false,
realPrCreateRequiresCommanderAuthorization: capability.realPrCreateRequiresCommanderAuthorization ?? true,
pushDryRun: pushDryRun === null ? null : {
requested: pushDryRun.requested ?? false,
writesRemote: pushDryRun.writesRemote ?? false,
commandShape: pushDryRun.commandShape ?? null,
},
prCreateDryRun: prCreateDryRun === null ? null : {
requested: prCreateDryRun.requested ?? false,
writesRemote: prCreateDryRun.writesRemote ?? false,
commandShape: prCreateDryRun.commandShape ?? null,
},
mergeSupported: unsupportedMergeBoundary?.supported ?? false,
mergeCommand: unsupportedMergeBoundary?.command ?? "bun scripts/cli.ts gh pr merge <number> --repo pikasTech/unidesk",
},
authScopeSummary: record.authScopeSummary ?? prPreflightAuthScopeSummary(tokenCoverage, activeRunnerDevContainer),
scopeBoundary: record.scopeBoundary ?? prPreflightScopeBoundary(tokenCoverage),
recommendedActions: compactRecommendedActions(record),
upstream: record.upstream ?? null,
controlPlane: record.controlPlane ?? null,
observationGap: record.observationGap ?? undefined,
localObservationGap: record.localObservationGap ?? undefined,
localObservationSummary: record.localObservationSummary ?? undefined,
remoteObservationSummary: record.remoteObservationSummary ?? undefined,
commands,
disclosure: {
defaultView: "commander-compact",
fullDetailOmitted: true,
fullObservationsOmitted: asRecord(record.disclosure)?.fullObservationsOmitted ?? true,
expandWith: commands.fullDetail,
rawProxy: commands.rawProxy,
detailFieldsOmitted: ["preflight", "tools", "agentPorts", "git", "egress", "remote", "limitations", "risks", "rawRuntimePreflight"],
},
};
}
function decoratePrPreflightScopeBoundary(record: Record<string, unknown>): Record<string, unknown> {
const preflight = asRecord(record.preflight);
const tokenCoverage = prPreflightTokenCoverage(record);
const scopeBoundary = prPreflightScopeBoundary(tokenCoverage);
const activeRunnerDevContainer = activeRunnerDevContainerCapability();
const authScopeSummary = prPreflightAuthScopeSummary(tokenCoverage, activeRunnerDevContainer);
const recommendedActions = prPreflightRecommendedActions(tokenCoverage);
return {
...record,
authScopeSummary,
scopeBoundary,
activeRunnerDevContainer,
recommendedActions,
...(preflight === null ? {} : { preflight: { ...preflight, authScopeSummary, scopeBoundary, recommendedActions } }),
};
}
function prPreflightObservationGap(kind: Exclude<CodeQueueObservationGapKind, null>, detail: {
reason: string;
localBackendCoreMissing?: boolean;
remoteFallbackUsed?: boolean;
remoteControlPlaneReachable?: boolean | null;
}): Record<string, unknown> {
const controlPlaneGap = kind === "control-plane-observation-gap";
return {
kind,
blockingDisposition: kind,
scope: controlPlaneGap ? "control-plane" : "runner-local",
reason: detail.reason,
localBackendCoreMissing: detail.localBackendCoreMissing === true,
remoteFallbackUsed: detail.remoteFallbackUsed === true,
remoteControlPlaneReachable: detail.remoteControlPlaneReachable ?? null,
schedulerStoppage: false,
schedulerStateMachineChanged: false,
recommendedAction: controlPlaneGap ? "cross-check-control-plane" : "retry-from-control-plane-or-remote-fallback",
note: controlPlaneGap
? "The control-plane observation path is unavailable; this is not evidence that the scheduler stopped executing active tasks."
: "The current runner/local backend-core observation path is unavailable; this is not evidence that active Code Queue execution stopped.",
};
}
function prPreflightObservationSummary(record: Record<string, unknown> | null): Record<string, unknown> | null {
if (record === null) return null;
const preflight = asRecord(record.preflight);
const schedulerPreflight = asRecord(record.schedulerPreflight);
const tokenCoverage = asRecord(record.tokenCoverage)
?? asRecord(preflight?.tokenCoverage)
?? (schedulerPreflight === null ? null : {
ok: schedulerPreflight.authReady ?? null,
source: schedulerPreflight.authSource ?? null,
credentialSource: schedulerPreflight.credentialSource ?? null,
scope: schedulerPreflight.scope ?? null,
missing: Array.isArray(schedulerPreflight.missing) && schedulerPreflight.missing.length > 0
? schedulerPreflight.missing.map(String)
: schedulerPreflight.authReady === false
? ["GH_TOKEN", "GITHUB_TOKEN"]
: [],
});
const controlPlane = asRecord(record.controlPlane);
const targetStack = asRecord(record.targetStack);
return {
ok: record.ok ?? null,
runnerDisposition: record.runnerDisposition ?? null,
failureKind: record.failureKind ?? null,
degradedReason: record.degradedReason ?? null,
controlPlane: controlPlane === null ? null : {
mode: controlPlane.mode ?? null,
localBackendCoreMissing: controlPlane.localBackendCoreMissing ?? null,
remoteFallbackUsed: controlPlane.remoteFallbackUsed ?? null,
},
targetStack: targetStack === null ? null : {
missingContainers: Array.isArray(targetStack.missingContainers) ? targetStack.missingContainers.map(String) : [],
verifyOnlyObserved: targetStack.verifyOnlyObserved ?? false,
},
tokenCoverage: tokenCoverage === null ? null : {
ok: tokenCoverage.ok ?? null,
source: tokenCoverage.source ?? null,
credentialSource: tokenCoverage.credentialSource ?? null,
scope: tokenCoverage.scope ?? null,
missing: Array.isArray(tokenCoverage.missing) ? tokenCoverage.missing.map(String) : [],
},
};
}
function maybeFullPrPreflightObservations(options: CodexPrPreflightOptions, localRecord: Record<string, unknown>, remoteRecord: Record<string, unknown>): Record<string, unknown> {
if (options.full) {
return {
localObservation: localRecord,
remoteObservation: remoteRecord,
};
}
return {
localObservationSummary: prPreflightObservationSummary(localRecord),
remoteObservationSummary: prPreflightObservationSummary(remoteRecord),
disclosure: {
fullObservationsOmitted: true,
expandWith: "bun scripts/cli.ts codex pr-preflight --remote --full",
},
};
}
function compactPrRuntimePreflight(preflight: Record<string, unknown>, options: CodexPrPreflightOptions): Record<string, unknown> {
const pull = asRecord(preflight.pullRequestDelivery) ?? {};
const skills = compactSkillsStatus(preflight.skills);
const skillsSync = compactSkillsSyncStatus(preflight.skillsSync, options.full);
const tools = asRecord(pull.tools) ?? {};
const unideskGhCli = compactUniDeskGhCliStatus(pull.unideskGhCli);
const authBrokerRuntime = compactAuthBrokerRuntimeStatus(pull.authBroker);
const systemGhBinary = compactToolStatus(tools.gh);
const credentials = asRecord(pull.credentials) ?? {};
const git = asRecord(pull.git) ?? {};
const githubContext = asRecord(pull.githubContext) ?? {};
const egress = asRecord(pull.egress) ?? {};
const proxy = asRecord(egress.proxy) ?? {};
const remote = asRecord(pull.remote);
const ports = asRecord(preflight.ports) ?? {};
const tokenCoverage = tokenCoverageStatus(credentials, authBrokerRuntime);
const limitations = Array.isArray(pull.limitations) ? pull.limitations.map(String) : [];
const risks = Array.isArray(pull.risks) ? pull.risks.map(String) : [];
const ok = preflight.ok === true && tokenCoverage.ok === true;
const githubTransient = githubTransientEvidence(pull);
const skillsBlocked = skills !== null && skills.ok !== true;
const skillsSyncBlocked = skillsSync !== null && skillsSync.ok !== true;
const failureKind = !tokenCoverage.ok
? "auth-missing"
: skillsBlocked || skillsSyncBlocked
? "runner-skills-blocker"
: githubTransient !== null
? "github-transient"
: limitations.some((item) => item.includes("git ls-remote") || item.includes("git push --dry-run failed"))
? "git-remote-gap"
: !preflight.ok
? "proxy-gap"
: null;
const degradedReason = failureKind === "auth-missing"
? "auth-broker-needed"
: failureKind === "runner-skills-blocker"
? typeof skillsSync?.blocker === "string" ? skillsSync.blocker : typeof skills?.blocker === "string" ? skills.blocker : "runner-skills-degraded"
: failureKind === "github-transient"
? "github-dns-api-transient"
: failureKind === "git-remote-gap"
? "git remote probe failed"
: failureKind === "proxy-gap"
? limitations.find((item) => item.includes("proxy") || item.includes("auth") || item.includes("egress") || item.includes("reachable")) ?? null
: null;
const defaultPushDryRunRef = "refs/heads/probe/code-queue-pr-capability-dryrun";
const pushDryRunRef = options.pushDryRunRef ?? defaultPushDryRunRef;
const targetBranch = "master";
const expectedHeadBranch = options.prCreateDryRunHead ?? (typeof git.branch === "string" && git.branch.length > 0 ? git.branch : "<head-branch>");
const scopeBoundary = prPreflightScopeBoundary(tokenCoverage);
const activeRunnerDevContainer = activeRunnerDevContainerCapability();
const authScopeSummary = prPreflightAuthScopeSummary(tokenCoverage, activeRunnerDevContainer);
const recommendedActions = prPreflightRecommendedActions(tokenCoverage);
const result: Record<string, unknown> = {
ok,
failureKind,
degradedReason,
checkedAt: preflight.checkedAt ?? pull.checkedAt ?? null,
runner: {
serviceId: "code-queue",
plane: "D601 k3s scheduler/runner",
queueScope: "all queues executed by the scheduler, including default",
cwd: preflight.cwd ?? null,
pid: preflight.pid ?? null,
},
skills,
skillsSync,
tokenCoverage,
authBroker: authBrokerNeededStatus(tokenCoverage, authBrokerRuntime, systemGhBinary, unideskGhCli),
authScopeSummary,
scopeBoundary,
recommendedActions,
prCapabilityContract: {
targetBranch,
tokenSource: tokenCoverage.source,
authSource: tokenCoverage.credentialSource,
realPrCreateRequiresCommanderAuthorization: true,
systemGhBinaryRequiredForWrites: false,
unideskGhCli,
authBroker: authBrokerRuntime,
pushDryRun: {
requested: options.pushDryRun,
ref: pushDryRunRef,
writesRemote: false,
commandShape: `git push --dry-run origin HEAD:${pushDryRunRef}`,
},
prCreateDryRun: {
requested: options.prCreateDryRun,
headBranch: expectedHeadBranch,
writesRemote: false,
commandShape: `bun scripts/cli.ts gh pr create --repo pikasTech/unidesk --base ${targetBranch} --head ${expectedHeadBranch} --dry-run`,
},
expectedPrHandoff: {
sourceBranch: expectedHeadBranch,
targetBranch,
runnerCreatesPrAfterAuthorization: true,
commanderReviewsAndMerges: true,
preflightCreatesPr: false,
preflightMergesPr: false,
},
unsupportedMergeBoundary: {
supported: false,
command: "bun scripts/cli.ts gh pr merge <number> --repo pikasTech/unidesk",
degradedReason: "unsupported-command",
runnerDisposition: "business-failed",
note: "UniDesk CLI intentionally does not merge PRs in this phase; runner handoff stops at PR creation and evidence.",
},
},
controlPlane: {
mode: "local-backend-core",
localBackendCoreMissing: false,
remoteFallbackUsed: false,
},
tools: {
git: compactToolStatus(tools.git),
gh: systemGhBinary,
systemGhBinary,
hub: compactToolStatus(tools.hub),
jq: compactToolStatus(tools.jq),
ssh: compactToolStatus(tools.ssh),
curl: compactToolStatus(tools.curl),
unideskGhCli,
},
agentPorts: {
codex: compactAgentPortStatus(ports.codex),
opencode: compactAgentPortStatus(ports.opencode),
},
git: {
insideWorktree: git.insideWorktree ?? false,
branch: git.branch ?? null,
head: git.head ?? null,
originMaster: git.originMaster ?? null,
remoteOrigin: git.remoteOrigin ?? null,
home: git.home ?? null,
homeWritable: git.homeWritable ?? false,
knownHostsPresent: git.knownHostsPresent ?? false,
privateKeyPresent: git.privateKeyPresent ?? false,
},
githubContext: {
host: githubContext.host ?? null,
apiBaseUrl: githubContext.apiBaseUrl ?? null,
repo: githubContext.repo ?? null,
issueProbeNumber: githubContext.issueProbeNumber ?? null,
},
egress: {
proxy: {
selectedProxyHost: proxy.selectedProxyHost ?? null,
selectedProxyPort: proxy.selectedProxyPort ?? null,
selectedProxyHostResolvable: proxy.selectedProxyHostResolvable ?? null,
},
githubDefault: compactCommandProbe(egress.githubDefault),
apiDefault: compactCommandProbe(egress.apiDefault),
issueApi: compactCommandProbe(egress.issueApi),
},
remote: remote === null ? null : {
gitLsRemote: compactCommandProbe(remote.gitLsRemote),
gitHttpsLsRemote: compactCommandProbe(remote.gitHttpsLsRemote),
githubSshAuthenticated: remote.githubSshAuthenticated ?? false,
ghAuthStatus: compactCommandProbe(remote.ghAuthStatus),
ghRepoView: compactCommandProbe(remote.ghRepoView),
ghIssueView: compactCommandProbe(remote.ghIssueView),
ghPrReadOnly: compactCommandProbe(remote.ghPrReadOnly),
},
pushDryRun: compactCommandProbe(pull.pushDryRun),
prCreateDryRun: compactCommandProbe(pull.prCreateDryRun),
limitations,
risks,
runnerDisposition: ok ? "ready" : "infra-blocked",
...(githubTransient === null ? {} : {
retryable: true,
commanderAction: "retry-backoff-or-keep-running-if-heartbeat-fresh",
githubTransient,
}),
activeRunnerDevContainer,
recoveryHint: ok
? tokenCoverage.source === "auth-broker"
? "Runner PR workflow has auth-broker coverage for GitHub REST preflight; real PR creation still requires commander authorization."
: "Runner PR workflow has env-token coverage for the scheduler."
: githubTransient !== null
? "GitHub DNS/API connectivity failed transiently. Retry with backoff; if the task heartbeat or trace is fresh, keep supervising the running task instead of closing or requeueing business work."
: "Scheduler preflight lacks GitHub auth coverage for scheduler-scoped admission only. First verify the active task with repo-native gh auth status and PR create dry-run; long-term configure auth-broker or inject GH_TOKEN/GITHUB_TOKEN into the scheduler runtime secret.",
commands: {
local: "bun scripts/cli.ts gh auth status --repo pikasTech/unidesk",
runner: "bun scripts/cli.ts codex pr-preflight --remote",
runnerPushDryRun: "bun scripts/cli.ts codex pr-preflight --remote --push-dry-run --push-dry-run-ref refs/heads/probe/code-queue-pr-capability",
runnerPrCreateDryRun: "bun scripts/cli.ts codex pr-preflight --remote --pr-create-dry-run --pr-create-dry-run-head <head-branch>",
rawProxy: "bun scripts/cli.ts microservice proxy code-queue /api/runtime-preflight?remote=1 --raw",
},
};
if (options.full) result.rawRuntimePreflight = preflight;
return result;
}
function queryRemoteMainServerPrPreflight(optionArgs: string[], config: UniDeskConfig): unknown {
const command = ["bun", "scripts/cli.ts", "--main-server-ip", config.network.publicHost, "codex", "pr-preflight", ...optionArgs];
const result = runCommand(command, repoRoot, { timeoutMs: 120_000 });
const parsed = parseJsonRecord(result.stdout);
if (parsed !== null) {
const data = asRecord(parsed.data);
const dataResult = asRecord(data?.result);
if (dataResult !== null) return dataResult;
if (data !== null) return data;
const error = asRecord(parsed.error);
if (error !== null) {
const message = typeof error.message === "string" && error.message.length > 0
? error.message
: result.stderr.trim() || result.stdout.trim() || "remote control plane unreachable";
return {
ok: false,
runnerDisposition: "infra-blocked",
blockingDisposition: "control-plane-observation-gap",
failureKind: "control-plane-missing",
degradedReason: "remote-control-plane-unreachable",
message,
observationGap: prPreflightObservationGap("control-plane-observation-gap", {
reason: "remote control plane CLI returned a structured error",
localBackendCoreMissing: false,
remoteFallbackUsed: true,
remoteControlPlaneReachable: false,
}),
controlPlane: {
mode: "remote-frontend",
host: config.network.publicHost,
frontendUrl: `http://${config.network.publicHost}:${config.network.frontend.port}`,
localBackendCoreMissing: false,
remoteFallbackUsed: true,
},
observed: {
exitCode: result.exitCode,
stdoutTail: result.stdout.slice(-2000),
stderrTail: result.stderr.slice(-2000),
},
commands: {
retry: `bun scripts/cli.ts --main-server-ip ${config.network.publicHost} codex pr-preflight --remote`,
},
};
}
}
const message = result.stderr.trim() || result.stdout.trim() || `remote control plane unreachable: exitCode=${result.exitCode ?? "null"}`;
return {
ok: false,
runnerDisposition: "infra-blocked",
blockingDisposition: "control-plane-observation-gap",
failureKind: "control-plane-missing",
degradedReason: "remote-control-plane-unreachable",
message,
observationGap: prPreflightObservationGap("control-plane-observation-gap", {
reason: "remote control plane CLI could not be reached or returned non-JSON output",
localBackendCoreMissing: false,
remoteFallbackUsed: true,
remoteControlPlaneReachable: false,
}),
controlPlane: {
mode: "remote-frontend",
host: config.network.publicHost,
frontendUrl: `http://${config.network.publicHost}:${config.network.frontend.port}`,
localBackendCoreMissing: false,
remoteFallbackUsed: true,
},
observed: {
exitCode: result.exitCode,
stdoutTail: result.stdout.slice(-2000),
stderrTail: result.stderr.slice(-2000),
},
commands: {
retry: `bun scripts/cli.ts --main-server-ip ${config.network.publicHost} codex pr-preflight --remote`,
},
};
}
function codeQueuePrPreflight(optionArgs: string[] = [], transport: CodeQueuePrPreflightTransport = {}): unknown {
const options = parsePrPreflightOptions(optionArgs);
const config = transport.config ?? null;
const fetcher = transport.coreFetch ?? coreInternalFetch;
const path = codeQueueProxyPath(`/api/runtime-preflight${queryString({
remote: options.remote ? 1 : undefined,
pushDryRun: options.pushDryRun ? 1 : undefined,
pushDryRunRef: options.pushDryRunRef,
prCreateDryRun: options.prCreateDryRun ? 1 : undefined,
prCreateDryRunHead: options.prCreateDryRunHead,
issue: options.issueNumber,
})}`);
const localResponse = fetcher(path);
const localRecord = asRecord(localResponse);
const localTargetStackMissing = localRecord?.ok === false
&& localRecord.failureKind === "target-stack-not-running"
&& localRecord.degradedReason === "backend-core-container-missing";
const remoteMainServerPrPreflight = transport.remoteMainServerPrPreflight
?? (config === null ? null : (args: string[], _config: UniDeskConfig | null) => queryRemoteMainServerPrPreflight(args, config));
if (options.remote && localTargetStackMissing && remoteMainServerPrPreflight !== null) {
const remoteResponse = remoteMainServerPrPreflight(optionArgs, config);
const remoteRecord = asRecord(remoteResponse);
if (remoteRecord !== null) {
if (remoteRecord.ok === false) {
return compactPrPreflightCommanderView(decoratePrPreflightScopeBoundary({
...remoteRecord,
observationGap: prPreflightObservationGap(
remoteRecord.failureKind === "control-plane-missing" ? "control-plane-observation-gap" : "runner-local-observation-gap",
{
reason: remoteRecord.failureKind === "control-plane-missing"
? "remote control plane could not be observed after local backend-core target-stack absence"
: "local backend-core target-stack absence was bypassed by remote fallback, but the remote result still failed",
localBackendCoreMissing: true,
remoteFallbackUsed: true,
remoteControlPlaneReachable: remoteRecord.failureKind === "control-plane-missing" ? false : true,
},
),
blockingDisposition: remoteRecord.failureKind === "control-plane-missing" ? "control-plane-observation-gap" : remoteRecord.blockingDisposition ?? remoteRecord.runnerDisposition ?? "infra-blocked",
controlPlane: {
...(asRecord(remoteRecord.controlPlane) ?? {}),
mode: "remote-frontend",
host: config?.network.publicHost ?? null,
frontendUrl: config === null ? null : `http://${config.network.publicHost}:${config.network.frontend.port}`,
localBackendCoreMissing: true,
remoteFallbackUsed: true,
},
...maybeFullPrPreflightObservations(options, localRecord, remoteRecord),
}), options);
}
return compactPrPreflightCommanderView(decoratePrPreflightScopeBoundary({
...remoteRecord,
localObservationGap: prPreflightObservationGap("runner-local-observation-gap", {
reason: "local backend-core target-stack absence was bypassed by healthy remote control-plane fallback",
localBackendCoreMissing: true,
remoteFallbackUsed: true,
remoteControlPlaneReachable: true,
}),
controlPlane: {
...(asRecord(remoteRecord.controlPlane) ?? {}),
mode: "remote-frontend",
host: config?.network.publicHost ?? null,
frontendUrl: config === null ? null : `http://${config.network.publicHost}:${config.network.frontend.port}`,
localBackendCoreMissing: true,
remoteFallbackUsed: true,
},
...maybeFullPrPreflightObservations(options, localRecord, remoteRecord),
}), options);
}
}
if (localRecord?.ok !== true) {
if (options.remote && localTargetStackMissing) {
const failureKind: CodeQueuePrPreflightFailureKind = "control-plane-missing";
const degradedReason = "remote-control-plane-unreachable";
return {
...(localRecord ?? {}),
ok: false,
runnerDisposition: "infra-blocked",
blockingDisposition: "control-plane-observation-gap",
failureKind,
degradedReason,
message: "remote control plane unreachable; local backend-core target-stack absence is observation-gap evidence only",
observationGap: prPreflightObservationGap("control-plane-observation-gap", {
reason: "local backend-core target stack is missing and no remote control plane could be observed",
localBackendCoreMissing: true,
remoteFallbackUsed: false,
remoteControlPlaneReachable: false,
}),
controlPlane: {
mode: "local-backend-core",
localBackendCoreMissing: true,
remoteFallbackUsed: false,
},
commands: {
retry: config !== null
? `bun scripts/cli.ts --main-server-ip ${config.network.publicHost} codex pr-preflight --remote`
: "bun scripts/cli.ts codex pr-preflight --remote",
local: "bun scripts/cli.ts microservice proxy code-queue /api/runtime-preflight --raw",
},
};
}
return {
...(localRecord ?? {}),
ok: false,
runnerDisposition: localRecord?.runnerDisposition ?? "infra-blocked",
blockingDisposition: localTargetStackMissing ? "runner-local-observation-gap" : localRecord?.blockingDisposition ?? localRecord?.runnerDisposition ?? "infra-blocked",
failureKind: (localRecord?.failureKind as CodeQueuePrPreflightFailureKind | undefined) ?? "proxy-gap",
degradedReason: localRecord?.degradedReason ?? "backend-core-proxy-unavailable",
message: localRecord?.message ?? localRecord?.stderrTail ?? localRecord?.stdoutTail ?? "Code Queue runtime preflight could not be observed",
...(localTargetStackMissing
? {
observationGap: prPreflightObservationGap("runner-local-observation-gap", {
reason: "local backend-core target stack is missing in this runner observation path",
localBackendCoreMissing: true,
remoteFallbackUsed: false,
remoteControlPlaneReachable: null,
}),
}
: {}),
controlPlane: {
mode: "local-backend-core",
localBackendCoreMissing: localTargetStackMissing,
remoteFallbackUsed: false,
},
commands: {
retry: config !== null
? `bun scripts/cli.ts --main-server-ip ${config.network.publicHost} codex pr-preflight --remote`
: "bun scripts/cli.ts codex pr-preflight --remote",
local: "bun scripts/cli.ts microservice proxy code-queue /api/runtime-preflight --raw",
},
};
}
const response = asRecord(localRecord);
if (response?.ok !== true) {
throw new Error(upstreamError(localRecord));
}
const body = asRecord(response.body);
const preflight = asRecord(body?.runtimePreflight);
if (preflight === null) {
return {
ok: false,
runnerDisposition: "infra-blocked",
failureKind: "proxy-gap",
degradedReason: "runtime-preflight-missing",
message: "Code Queue runtime-preflight response did not include runtimePreflight",
controlPlane: {
mode: "local-backend-core",
localBackendCoreMissing: false,
remoteFallbackUsed: false,
},
upstream: { ok: response.ok, status: response.status },
commands: {
retry: "bun scripts/cli.ts codex pr-preflight --remote",
},
};
}
const compact = compactPrRuntimePreflight(preflight, options);
return compactPrPreflightCommanderView({
ok: compact.ok,
runnerDisposition: compact.runnerDisposition,
failureKind: compact.failureKind ?? null,
degradedReason: compact.degradedReason ?? null,
...(compact.retryable === true ? { retryable: true } : {}),
...(typeof compact.commanderAction === "string" ? { commanderAction: compact.commanderAction } : {}),
...(asRecord(compact.githubTransient) === null ? {} : { githubTransient: compact.githubTransient }),
authScopeSummary: compact.authScopeSummary,
scopeBoundary: compact.scopeBoundary,
activeRunnerDevContainer: compact.activeRunnerDevContainer,
recommendedActions: compact.recommendedActions,
upstream: { ok: response.ok, status: response.status },
controlPlane: {
mode: "local-backend-core",
localBackendCoreMissing: false,
remoteFallbackUsed: false,
},
preflight: compact,
}, options);
}
export function codexPrPreflightQueryForTest(optionArgs: string[], transport: CodeQueuePrPreflightTransport = {}): unknown {
return codeQueuePrPreflight(optionArgs, transport);
}
export async function codexPrPreflightQueryAsync(optionArgs: string[], fetcher: AsyncCodexResponseFetcher): Promise<unknown> {
const options = parsePrPreflightOptions(optionArgs);
const path = codeQueueProxyPath(`/api/runtime-preflight${queryString({
remote: options.remote ? 1 : undefined,
pushDryRun: options.pushDryRun ? 1 : undefined,
pushDryRunRef: options.pushDryRunRef,
prCreateDryRun: options.prCreateDryRun ? 1 : undefined,
prCreateDryRunHead: options.prCreateDryRunHead,
issue: options.issueNumber,
})}`);
const response = asRecord(await fetcher(path));
if (response?.ok !== true) throw new Error(upstreamError(response));
const body = asRecord(response.body);
const preflight = asRecord(body?.runtimePreflight);
if (preflight === null) {
return {
ok: false,
runnerDisposition: "infra-blocked",
failureKind: "proxy-gap",
degradedReason: "runtime-preflight-missing",
message: "Code Queue runtime-preflight response did not include runtimePreflight",
controlPlane: {
mode: "remote-frontend",
localBackendCoreMissing: false,
remoteFallbackUsed: false,
},
upstream: { ok: response.ok, status: response.status },
commands: {
retry: "bun scripts/cli.ts codex pr-preflight --remote",
},
};
}
const compact = compactPrRuntimePreflight(preflight, options);
return compactPrPreflightCommanderView({
ok: compact.ok,
runnerDisposition: compact.runnerDisposition,
failureKind: compact.failureKind ?? null,
degradedReason: compact.degradedReason ?? null,
...(compact.retryable === true ? { retryable: true } : {}),
...(typeof compact.commanderAction === "string" ? { commanderAction: compact.commanderAction } : {}),
...(asRecord(compact.githubTransient) === null ? {} : { githubTransient: compact.githubTransient }),
authScopeSummary: compact.authScopeSummary,
scopeBoundary: compact.scopeBoundary,
activeRunnerDevContainer: compact.activeRunnerDevContainer,
recommendedActions: compact.recommendedActions,
upstream: { ok: response.ok, status: response.status },
controlPlane: {
mode: "remote-frontend",
localBackendCoreMissing: false,
remoteFallbackUsed: false,
},
preflight: compact,
}, options);
}
export function codexSubmitRoutingRecommendationForTest(prompt: string, model?: string): SubmitRoutingRecommendation {
return submitRoutingRecommendation({
prompt,
model,
queueId: undefined,
providerId: undefined,
cwd: undefined,
reasoningEffort: undefined,
executionMode: undefined,
maxAttempts: undefined,
referenceTaskIds: [],
dryRun: true,
});
}
export function codexPromptLiveAuthorizationLintForTest(prompt: string): PromptLiveAuthorizationLint {
return buildPromptLiveAuthorizationLint(prompt);
}
export function codexSubmitModelRegistryForTest(models: string[] = sharedDefaultCodeModels): ReturnType<typeof submitModelRegistry> {
return submitModelRegistry(models);
}
function codexPromptLintTask(args: string[]): unknown {
const options = parsePromptLintOptions(args);
return buildPromptLiveAuthorizationLint(options.prompt);
}
function codexSubmitTask(args: string[]): unknown {
const options = parseSubmitOptions(args);
const payload = submitPayload(options);
const promptLint = buildPromptLiveAuthorizationLint(options.prompt);
if (options.dryRun) {
return {
ok: true,
dryRun: true,
promptLint,
executionMode: executionModeSummary(options.executionMode),
runnerPermissions: dryRunRunnerPermissionsSummary(),
routingRecommendation: submitRoutingRecommendation(options),
modelRegistry: submitModelRegistry(),
request: {
...payload,
prompt: textView(options.prompt, true, 3000),
},
commands: {
submitAsRequested: "remove --dry-run to submit exactly this payload",
minimaxCandidate: `bun scripts/cli.ts codex submit --prompt-file <path> --model ${minimaxSubmitModel} --dry-run`,
deepseekCandidate: `bun scripts/cli.ts codex submit --prompt-file <path> --model ${deepseekSubmitModel} --dry-run`,
gptCandidate: `bun scripts/cli.ts codex submit --prompt-file <path> --model ${gptSubmitModel} --dry-run`,
},
};
}
const locked = runWithSubmitLock(() => unwrapCodexResponse(coreInternalFetch(codeQueueProxyPath("/api/tasks"), { method: "POST", body: payload })));
const response = locked.result;
return compactSubmitSuccessResponse(response.body, response.upstream, locked.lock);
}
function codexInterruptTask(taskId: string): unknown {
const response = unwrapCodexResponse(coreInternalFetch(codeQueueProxyPath(`/api/tasks/${encodeURIComponent(taskId)}/interrupt`), { method: "POST" }));
return {
upstream: response.upstream,
task: compactTaskMutationResponse(response.body.task),
queue: compactQueueMutationSummary(response.body.queue),
};
}
function codexSteerTask(taskId: string, args: string[], fetcher: CodexResponseFetcher = coreInternalFetch): unknown {
const options = parseSteerOptions(args);
const promptLint = buildPromptLiveAuthorizationLint(options.prompt);
const steerId = options.steerId ?? createSteerId(taskId, options.prompt);
const targetPath = `/api/tasks/${encodeURIComponent(taskId)}/steer`;
const stableProxyPath = codeQueueProxyPath(targetPath);
const rawProxyEquivalent = codeQueueProxyEquivalentCommand(targetPath, `{"prompt":"...","steerId":"${steerId}"}`);
const prompt = textView(options.prompt, false, steerPromptPreviewChars);
const request = {
path: targetPath,
stableProxyPath,
method: "POST",
steerId,
retryPolicy: {
defaultAttempts: defaultSteerRetryAttempts,
maxAttempts: options.retryAttempts,
delayMs: options.retryDelayMs,
retryableReasons: ["stable-proxy-failed", "backend-core-unreachable"],
deliveryConfirmation: "success confirms Code Queue accepted the steer request; timeout-like failures trigger a bounded trace confirmation lookup by steerId",
idempotency: "the same steerId is reused for every CLI retry and suppresses duplicate trace injection on a backend that supports the contract",
},
bodySummary: {
steerId,
promptChars: options.prompt.length,
promptPreviewChars: steerPromptPreviewChars,
promptTruncated: prompt.truncated,
},
body: { steerId, prompt },
};
if (options.dryRun) {
return {
ok: true,
dryRun: true,
promptLint,
request,
commands: {
run: `bun scripts/cli.ts codex steer ${taskId} --prompt-file <path> --steer-id ${steerId}`,
noRetry: `bun scripts/cli.ts codex steer ${taskId} --prompt-file <path> --steer-id ${steerId} --no-retry`,
traceConfirm: steerConfirmationCommand(taskId, steerId),
rawProxy: rawProxyEquivalent,
},
};
}
const attempts: CodexSteerAttemptSummary[] = [];
let failedResponse: { ok: false; diagnostics: ClassifiedCodexSteerError; rawResponse: unknown } | null = null;
let successfulResponse: { ok: true; upstream: { ok: unknown; status: unknown }; body: Record<string, unknown> } | null = null;
for (let attempt = 1; attempt <= options.retryAttempts; attempt += 1) {
const startedAt = Date.now();
const response = unwrapSteerResponse(fetcher(stableProxyPath, { method: "POST", body: { prompt: options.prompt, steerId } }), targetPath, stableProxyPath, rawProxyEquivalent);
const durationMs = Date.now() - startedAt;
if (response.ok) {
attempts.push(steerSuccessAttempt(attempt, durationMs, response.upstream, asString(response.body.steerId) || steerId, asString(response.body.deliveryState) as CodexSteerDeliveryState || "accepted"));
successfulResponse = response;
break;
}
attempts.push(steerFailureAttempt(attempt, durationMs, response.diagnostics));
failedResponse = response;
const terminalRejection = compactTerminalSteerRejection(taskId, steerId, response.rawResponse);
if (terminalRejection !== null) {
terminalRejection.commands = {
...(asRecord(terminalRejection.commands) ?? {}),
fullDetails: `bun scripts/cli.ts codex steer ${taskId} --prompt-file <path> --full`,
rawDetails: `bun scripts/cli.ts codex steer ${taskId} --prompt-file <path> --raw`,
};
return attachSteerDisclosure(terminalRejection, options, response.rawResponse, targetPath, stableProxyPath, rawProxyEquivalent);
}
if (!shouldRetrySteerFailure(response.diagnostics, attempt, options.retryAttempts)) break;
sleepSync(options.retryDelayMs);
}
if (successfulResponse === null) {
const diagnostics = failedResponse?.diagnostics ?? classifySteerFailure(null, targetPath, stableProxyPath, rawProxyEquivalent);
const transportDeliveryUnconfirmed = diagnostics.reason === "stable-proxy-failed" || diagnostics.reason === "backend-core-unreachable";
const traceConfirmation = transportDeliveryUnconfirmed ? safeFetchSteerTraceConfirmation(taskId, steerId, fetcher) : null;
const confirmedAccepted = asBoolean(traceConfirmation?.accepted);
const deliveryState = confirmedAccepted ? "accepted_response_timeout" : transportDeliveryUnconfirmed ? "unknown" : "not_accepted";
const acceptanceStatus: CodexSteerAcceptanceStatus = confirmedAccepted ? "accepted_response_timeout" : transportDeliveryUnconfirmed ? "unknown" : "not_accepted";
const compactDiagnostics = compactSteerFailureDiagnostics(diagnostics, options.full);
return {
ok: confirmedAccepted,
steer: {
accepted: confirmedAccepted,
status: acceptanceStatus,
deliveryState,
steerId,
promptChars: options.prompt.length,
promptOmitted: true,
attempts,
deliveryUnconfirmed: transportDeliveryUnconfirmed && !confirmedAccepted,
duplicateSuppressionKey: steerId,
retryPolicy: {
attempted: attempts.length,
maxAttempts: options.retryAttempts,
retryDelayMs: options.retryDelayMs,
retried: attempts.length > 1,
exhausted: transportDeliveryUnconfirmed && attempts.length >= options.retryAttempts,
note: "codex steer retried only retryable stable-proxy/backend-core failures; raw microservice proxy uses the same tunnel and is diagnostic, not a lower-noise fallback.",
},
},
...(options.full ? {
request: {
...request,
body: { prompt: { chars: options.prompt.length, textOmitted: true } },
},
} : {}),
diagnostics: {
...compactDiagnostics,
attempts,
retryPolicy: {
attempted: attempts.length,
maxAttempts: options.retryAttempts,
retryDelayMs: options.retryDelayMs,
retried: attempts.length > 1,
exhausted: transportDeliveryUnconfirmed && attempts.length >= options.retryAttempts,
},
operatorGuidance: {
rawProxyEquivalentIsFallback: false,
deliveryUnconfirmed: transportDeliveryUnconfirmed && !confirmedAccepted,
traceConfirmationChecked: traceConfirmation !== null,
nextStep: confirmedAccepted
? "The stable proxy response timed out, but trace confirmation found this steerId. Do not resend the same corrective prompt."
: transportDeliveryUnconfirmed
? "Run the bounded trace confirmation command before retrying. If it remains unknown, retry with the same steerId to avoid duplicate trace injection on an updated backend."
: "Inspect the non-retryable reason before resubmitting the correction.",
},
},
traceConfirmation,
commands: {
dryRun: `bun scripts/cli.ts codex steer ${taskId} --prompt-file <path> --steer-id ${steerId} --dry-run`,
retry: `bun scripts/cli.ts codex steer ${taskId} --prompt-file <path> --steer-id ${steerId}`,
noRetry: `bun scripts/cli.ts codex steer ${taskId} --prompt-file <path> --steer-id ${steerId} --no-retry`,
traceConfirm: steerConfirmationCommand(taskId, steerId),
fullDetails: `bun scripts/cli.ts codex steer ${taskId} --prompt-file <path> --steer-id ${steerId} --full`,
rawDetails: `bun scripts/cli.ts codex steer ${taskId} --prompt-file <path> --steer-id ${steerId} --raw`,
rawProxy: rawProxyEquivalent,
tasks: "bun scripts/cli.ts codex tasks --view supervisor --limit 20",
health: "bun scripts/cli.ts microservice health code-queue",
},
disclosure: {
defaultPolicy: "compact rejection; request prompt, upstream body preview, and raw response require explicit --full or --raw",
full: options.full,
raw: options.raw,
defaultOmitted: ["request.body.prompt.text", "diagnostics.upstreamBodyPreview", "rawFailure"],
},
...(options.raw ? { rawFailure: failedResponse?.rawResponse ?? null } : {}),
};
}
const responseSteerId = asString(successfulResponse.body.steerId) || steerId;
const traceConfirmation = compactSteerTraceConfirmation(successfulResponse.body.traceConfirmation, taskId, responseSteerId);
const deliveryState = asString(successfulResponse.body.deliveryState) || asString(traceConfirmation.deliveryState) || "accepted";
const duplicateSuppressed = successfulResponse.body.duplicateSuppressed === true;
return {
ok: true,
upstream: successfulResponse.upstream,
steer: {
accepted: true,
status: "accepted",
deliveryState,
steerId: responseSteerId,
taskId,
promptChars: options.prompt.length,
promptOmitted: true,
duplicateSuppressed,
duplicateSuppressionKey: responseSteerId,
attempts,
retryPolicy: {
attempted: attempts.length,
maxAttempts: options.retryAttempts,
retryDelayMs: options.retryDelayMs,
retried: attempts.length > 1,
},
outputPolicy: {
default: "write-confirmation",
promptEchoed: false,
taskDetailEchoed: false,
reason: "codex steer is a write operation; default output confirms delivery and provides drill-down commands without echoing prompt text or full task state.",
},
},
traceConfirmation,
task: compactSteerTaskConfirmation(successfulResponse.body.task, responseSteerId),
queue: compactSubmitQueueConfirmation(successfulResponse.body.queue),
commands: {
show: `bun scripts/cli.ts codex task ${taskId}`,
detail: `bun scripts/cli.ts codex task ${taskId} --detail`,
trace: `bun scripts/cli.ts codex task ${taskId} --trace --tail --limit ${defaultTraceLimit}`,
traceConfirm: steerConfirmationCommand(taskId, responseSteerId),
output: `bun scripts/cli.ts codex output ${taskId} --tail --limit ${defaultOutputLimit}`,
supervisor: `bun scripts/cli.ts codex tasks --view supervisor --limit ${defaultTasksLimit}`,
},
};
}
function codexSteerTraceConfirm(taskId: string, args: string[], fetcher: CodexResponseFetcher = coreInternalFetch): unknown {
const options = parseSteerConfirmOptions(args);
const path = steerConfirmationPath(taskId, options.steerId);
const response = unwrapCodexResponse(fetcher(codeQueueProxyPath(path)));
const confirmation = compactSteerTraceConfirmation(response.body, taskId, options.steerId);
return {
ok: asBoolean(confirmation.accepted),
upstream: response.upstream,
traceConfirmation: confirmation,
delivery: {
steerId: options.steerId,
status: asBoolean(confirmation.accepted) ? "accepted" : "unknown",
deliveryState: confirmation.deliveryState,
promptOmitted: true,
},
commands: {
task: `bun scripts/cli.ts codex task ${taskId}`,
trace: `bun scripts/cli.ts codex task ${taskId} --trace --tail --limit ${defaultTraceLimit}`,
retrySameSteerId: `bun scripts/cli.ts codex steer ${taskId} --prompt-file <path> --steer-id ${options.steerId}`,
rawLookup: rawSteerConfirmationCommand(taskId, options.steerId),
},
...(options.raw ? { raw: response.body } : {}),
};
}
export async function runCodeQueueCommand(config: UniDeskConfig, args: string[]): Promise<unknown> {
const [action = "task", taskIdArg] = args;
if (action === "prompt-lint" || action === "lint-prompt") {
return codexPromptLintTask(args.slice(1));
}
if (action === "submit" || action === "enqueue") {
return codexSubmitTask(args.slice(1));
}
if (action === "task" || action === "summary" || action === "show") {
const taskId = requireTaskId(taskIdArg, `codex ${action}`);
return codexTaskQuery(taskId, args.slice(2));
}
if (action === "tasks" || action === "overview") {
return codexTasksQuery(args.slice(1));
}
if (action === "unread" || action === "terminal-unread") {
return codexUnreadTriage(args.slice(1));
}
if (action === "dev-ready" || action === "health") {
assertKnownOptions(args.slice(1), {}, `codex ${action}`);
return codeQueueDevReady();
}
if (action === "skills-sync") return codeQueueSkillsSync(args.slice(1));
if (action === "pr-preflight" || action === "runtime-preflight") return codeQueuePrPreflight(args.slice(1), { config });
if (action === "output") {
const taskId = requireTaskId(taskIdArg, "codex output");
return codexOutputQuery(taskId, args.slice(2));
}
if (action === "judge") {
const taskId = requireTaskId(taskIdArg, "codex judge");
return codexJudgeQuery(taskId, args.slice(2));
}
if (action === "read" || action === "mark-read") {
const taskId = requireTaskId(taskIdArg, `codex ${action}`);
return codexReadTask(taskId);
}
if (action === "queues") return codeQueues(args.slice(1));
if (action === "queue") {
const sub = taskIdArg ?? "list";
if (sub === "list") return codeQueues(args.slice(2));
if (sub === "create") return codexCreateQueue(requireQueueId(args.slice(2), "queue create"));
if (sub === "merge") {
const mergeArgs = args.slice(2);
return codexMergeQueue(requireMergeSourceQueueId(mergeArgs, "queue merge"), requireMergeTargetQueueId(mergeArgs, "queue merge"));
}
}
if (action === "move") {
const taskId = requireTaskId(taskIdArg, "codex move");
return codexMoveTask(taskId, requireQueueId(args.slice(2), "codex move"));
}
if (action === "interrupt" || action === "cancel") {
const taskId = requireTaskId(taskIdArg, `codex ${action}`);
return codexInterruptTask(taskId);
}
if (action === "steer") {
const taskId = requireTaskId(taskIdArg, "codex steer");
return codexSteerTask(taskId, args.slice(2));
}
if (action === "steer-confirm" || action === "steer-confirmation") {
const taskId = requireTaskId(taskIdArg, `codex ${action}`);
return codexSteerTraceConfirm(taskId, args.slice(2));
}
throw new Error("codex command must be one of: prompt-lint, submit, enqueue, task, summary, show, tasks, overview, unread, terminal-unread, output, judge, read, mark-read, dev-ready, health, skills-sync, pr-preflight, runtime-preflight, queues, queue list, queue create, queue merge, move, steer, steer-confirm, interrupt, cancel");
}