From da3f2b4898b11e69c04464d6121b095d5175bcae Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sat, 24 Jan 2026 00:11:01 +0000 Subject: [PATCH] fix: table auth probe output --- CHANGELOG.md | 1 + src/commands/models/list.status-command.ts | 55 ++++++++++++---------- 2 files changed, 31 insertions(+), 25 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fc09c651a..17f0da5ec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ Docs: https://docs.clawd.bot - CLI: skip usage lines in `clawdbot models status` when provider usage is unavailable. - CLI: suppress diagnostic session/run noise during auth probes. - CLI: hide auth probe timeout warnings from embedded runs. +- CLI: render auth probe results as a table in `clawdbot models status`. - Linux: include env-configured user bin roots in systemd PATH and align PATH audits. (#1512) Thanks @robbyczgw-cla. - TUI: render Gateway slash-command replies as system output (for example, `/context`). - Media: preserve PNG alpha when possible; fall back to JPEG when still over size cap. (#1491) Thanks @robbyczgw-cla. diff --git a/src/commands/models/list.status-command.ts b/src/commands/models/list.status-command.ts index 41c126460..6b8c8c36d 100644 --- a/src/commands/models/list.status-command.ts +++ b/src/commands/models/list.status-command.ts @@ -28,6 +28,7 @@ import { } from "../../infra/provider-usage.js"; import type { RuntimeEnv } from "../../runtime.js"; import { colorize, theme } from "../../terminal/theme.js"; +import { renderTable } from "../../terminal/table.js"; import { formatCliCommand } from "../../cli/command-format.js"; import { shortenHomePath } from "../../utils.js"; import { resolveProviderAuthOverview } from "./list.auth-overview.js"; @@ -35,7 +36,6 @@ import { isRich } from "./list.format.js"; import { describeProbeSummary, formatProbeLatency, - groupProbeResults, runAuthProbes, sortProbeResults, type AuthProbeSummary, @@ -571,7 +571,8 @@ export async function modelsStatusCommand( if (probeSummary.results.length === 0) { runtime.log(colorize(rich, theme.muted, "- none")); } else { - const grouped = groupProbeResults(sortProbeResults(probeSummary.results)); + const tableWidth = Math.max(60, (process.stdout.columns ?? 120) - 1); + const sorted = sortProbeResults(probeSummary.results); const statusColor = (status: string) => { if (status === "ok") return theme.success; if (status === "rate_limit") return theme.warn; @@ -580,29 +581,33 @@ export async function modelsStatusCommand( if (status === "no_model") return theme.muted; return theme.muted; }; - for (const [provider, results] of grouped) { - const modelLabel = results.find((r) => r.model)?.model ?? "-"; - runtime.log( - `- ${theme.heading(provider)}${colorize( - rich, - theme.muted, - modelLabel ? ` (model: ${modelLabel})` : "", - )}`, - ); - for (const result of results) { - const status = colorize(rich, statusColor(result.status), result.status); - const latency = formatProbeLatency(result.latencyMs); - const mode = result.mode ? ` (${result.mode})` : ""; - const detail = result.error ? colorize(rich, theme.muted, ` - ${result.error}`) : ""; - runtime.log( - ` - ${colorize(rich, theme.accent, result.label)}${mode} ${status} ${colorize( - rich, - theme.muted, - latency, - )}${detail}`, - ); - } - } + const rows = sorted.map((result) => { + const status = colorize(rich, statusColor(result.status), result.status); + const latency = formatProbeLatency(result.latencyMs); + const detail = result.error ? colorize(rich, theme.muted, result.error) : ""; + const modelLabel = result.model ?? `${result.provider}/-`; + const modeLabel = result.mode ? ` ${colorize(rich, theme.muted, `(${result.mode})`)}` : ""; + const profile = `${colorize(rich, theme.accent, result.label)}${modeLabel}`; + const statusLabel = `${status}${colorize(rich, theme.muted, ` ยท ${latency}`)}`; + return { + Model: colorize(rich, theme.heading, modelLabel), + Profile: profile, + Status: statusLabel, + Detail: detail, + }; + }); + runtime.log( + renderTable({ + width: tableWidth, + columns: [ + { key: "Model", header: "Model", minWidth: 18 }, + { key: "Profile", header: "Profile", minWidth: 24 }, + { key: "Status", header: "Status", minWidth: 12 }, + { key: "Detail", header: "Detail", minWidth: 16, flex: true }, + ], + rows, + }).trimEnd(), + ); runtime.log(colorize(rich, theme.muted, describeProbeSummary(probeSummary))); } }