fix: compact noisy cli health outputs

This commit is contained in:
Codex
2026-05-22 23:00:38 +00:00
parent 79fb17b546
commit 65ac76c235
10 changed files with 454 additions and 45 deletions
+134 -2
View File
@@ -87,6 +87,14 @@ function bool(value: unknown): boolean {
return value === true;
}
function hasFlag(args: string[], name: string): boolean {
return args.includes(name);
}
function shellQuote(value: string): string {
return `'${value.replace(/'/g, `'\\''`)}'`;
}
function lower(value: unknown): string {
return String(value ?? "").toLowerCase();
}
@@ -292,6 +300,127 @@ function observedErrorSignal(message: string, scope: ProviderSignalScope): Provi
return signal("observed-error", scope, "failed", message, { message, runnerErrorClassification: classifyRunnerError(message) }, scope !== "runner-local");
}
function compactStringList(value: unknown, limit = 6): Record<string, unknown> {
const all = Array.from(new Set(asArray(value).map((item) => String(item ?? "")).filter(Boolean)));
return {
items: all.slice(0, limit),
count: all.length,
truncated: all.length > limit,
omitted: Math.max(0, all.length - limit),
};
}
function compactEvidence(value: unknown): unknown {
const record = asRecord(value);
if (record === null) return value;
const body = bodyOf(value);
const devReady = asRecord(record.devReady) ?? asRecord(body?.devReady);
const diagnostics = asRecord(record.executionDiagnostics) ?? asRecord(body?.executionDiagnostics) ?? asRecord(asRecord(value)?.diagnostics);
return {
upstream: record.upstream ?? (body === null ? null : { ok: asRecord(value)?.ok ?? null, status: asRecord(value)?.status ?? null }),
status: record.status ?? body?.status ?? null,
ok: record.ok ?? body?.ok ?? null,
serviceId: record.serviceId ?? body?.serviceId ?? null,
providerGatewayVersion: record.providerGatewayVersion ?? null,
hostSshConfigured: record.hostSshConfigured ?? null,
taskId: record.taskId ?? null,
taskStatus: record.taskStatus ?? null,
exitCode: record.exitCode ?? null,
devReady: devReady === null ? null : {
ok: devReady.ok ?? null,
missingTools: compactStringList(devReady.missingTools),
},
executionDiagnostics: diagnostics === null ? null : {
state: diagnostics.state ?? null,
effectiveLiveness: diagnostics.effectiveLiveness ?? null,
recommendedAction: diagnostics.recommendedAction ?? null,
splitBrainLive: diagnostics.splitBrainLive ?? null,
heartbeatFreshTaskIds: compactStringList(diagnostics.heartbeatFreshTaskIds),
heartbeatRiskTaskIds: compactStringList(diagnostics.heartbeatRiskTaskIds),
},
fallback: record.fallback === undefined ? null : record.fallback,
error: record.error ?? null,
};
}
function providerTriageCommand(providerId: string, args: string[], mode: "--full" | "--raw"): string {
const kept: string[] = [];
const valueOptions = new Set(["--observed-error", "--observed-scope", "--microservice", "--service", "--microservices"]);
for (let index = 0; index < args.length; index += 1) {
const arg = args[index] ?? "";
if (arg === "--full" || arg === "--raw") continue;
if (valueOptions.has(arg)) {
const value = args[index + 1];
if (value !== undefined) {
kept.push(arg, shellQuote(value));
index += 1;
}
continue;
}
kept.push(arg);
}
return [`${commandPrefix} provider triage ${providerId}`, ...kept, mode].filter(Boolean).join(" ");
}
export function compactProviderTriageResult(result: ProviderTriageResult, args: string[] = []): Record<string, unknown> {
const issueSignals = result.signals
.filter((item) => item.status === "failed" || item.status === "degraded" || item.status === "unknown")
.sort((left, right) => {
const rank: Record<ProviderSignalStatus, number> = { failed: 0, degraded: 1, unknown: 2, ok: 3 };
return rank[left.status] - rank[right.status];
});
const sourceSignals = issueSignals.length > 0 ? issueSignals : [];
const signalLimit = issueSignals.length > 0 ? 8 : 0;
const visibleSignals = sourceSignals.slice(0, signalLimit);
const okSignalCount = result.signals.filter((item) => item.status === "ok").length;
const issueSignalCount = issueSignals.length;
return {
ok: result.ok,
providerId: result.providerId,
decision: result.decision,
scope: result.scope,
retryable: result.retryable,
blockingDisposition: result.blockingDisposition,
observedAt: result.observedAt,
failedScopes: result.failedScopes,
degradedScopes: result.degradedScopes,
healthyScopes: result.healthyScopes,
failedIndependentScopes: result.failedIndependentScopes,
healthyIndependentScopes: result.healthyIndependentScopes,
rationale: result.rationale,
signalCounts: {
total: result.signals.length,
returned: visibleSignals.length,
limit: signalLimit,
ok: okSignalCount,
degraded: result.signals.filter((item) => item.status === "degraded").length,
failed: result.signals.filter((item) => item.status === "failed").length,
unknown: result.signals.filter((item) => item.status === "unknown").length,
omittedOkSignals: Math.max(0, result.signals.filter((item) => item.status === "ok").length - visibleSignals.filter((item) => item.status === "ok").length),
omittedIssueSignals: Math.max(0, issueSignalCount - visibleSignals.filter((item) => item.status === "failed" || item.status === "degraded" || item.status === "unknown").length),
omittedSignals: Math.max(0, sourceSignals.length - visibleSignals.length),
},
signals: visibleSignals.map((item) => ({
id: item.id,
scope: item.scope,
status: item.status,
independentPath: item.independentPath,
observedAt: item.observedAt,
summary: item.summary,
evidenceSummary: compactEvidence(item.evidence),
})),
recommendedCrossChecks: result.recommendedCrossChecks.slice(0, 8),
outputPolicy: {
default: "compact-triage-summary",
signalLimit,
full: providerTriageCommand(result.providerId, args, "--full"),
raw: providerTriageCommand(result.providerId, args, "--raw"),
note: "Default output returns prioritized failed/degraded/unknown signals plus bounded evidence. Use --full or --raw only when complete evidence is required.",
},
contract: result.contract,
};
}
export function providerTriageRecommendedCrossChecks(providerId: string): string[] {
return [
`${commandPrefix} provider triage ${providerId}`,
@@ -429,10 +558,12 @@ function optionValue(args: string[], name: string): string | undefined {
}
function assertKnownOptions(args: string[]): void {
const flags = new Set(["--full", "--raw"]);
const valueOptions = new Set(["--observed-error", "--observed-scope", "--microservice", "--service", "--microservices"]);
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)) throw new Error(`unsupported provider triage option: ${arg}`);
const value = args[index + 1];
if (value === undefined || value.startsWith("--")) throw new Error(`${arg} requires a value`);
@@ -440,7 +571,7 @@ function assertKnownOptions(args: string[]): void {
}
}
export async function runProviderTriage(config: UniDeskConfig, providerId: string, args: string[] = []): Promise<ProviderTriageResult> {
export async function runProviderTriage(config: UniDeskConfig, providerId: string, args: string[] = []): Promise<unknown> {
if (!/^[A-Za-z0-9_.-]{1,64}$/u.test(providerId)) throw new Error("provider triage requires a safe provider id such as D601");
assertKnownOptions(args);
const observedAt = isoNow();
@@ -497,5 +628,6 @@ export async function runProviderTriage(config: UniDeskConfig, providerId: strin
}
}
return buildProviderTriageResult(providerId, signals, observedAt);
const result = buildProviderTriageResult(providerId, signals, observedAt);
return hasFlag(args, "--full") || hasFlag(args, "--raw") ? result : compactProviderTriageResult(result, args);
}