diff --git a/src/cli/gateway-cli/register.ts b/src/cli/gateway-cli/register.ts index 3ec90bb526..ea5ac46845 100644 --- a/src/cli/gateway-cli/register.ts +++ b/src/cli/gateway-cli/register.ts @@ -7,6 +7,7 @@ import { loadConfig } from "../../config/config.js"; import { discoverGatewayBeacons } from "../../infra/bonjour-discovery.js"; import { resolveWideAreaDiscoveryDomain } from "../../infra/widearea-dns.js"; import { defaultRuntime } from "../../runtime.js"; +import { styleHealthChannelLine } from "../../terminal/health-style.js"; import { formatDocsLink } from "../../terminal/links.js"; import { colorize, isRich, theme } from "../../terminal/theme.js"; import { formatTokenCount, formatUsd } from "../../utils/usage-format.js"; @@ -30,47 +31,6 @@ import { } from "./discover.js"; import { addGatewayRunCommand } from "./run.js"; -function styleHealthChannelLine(line: string, rich: boolean): string { - if (!rich) { - return line; - } - const colon = line.indexOf(":"); - if (colon === -1) { - return line; - } - - const label = line.slice(0, colon + 1); - const detail = line.slice(colon + 1).trimStart(); - const normalized = detail.toLowerCase(); - - const applyPrefix = (prefix: string, color: (value: string) => string) => - `${label} ${color(detail.slice(0, prefix.length))}${detail.slice(prefix.length)}`; - - if (normalized.startsWith("failed")) { - return applyPrefix("failed", theme.error); - } - if (normalized.startsWith("ok")) { - return applyPrefix("ok", theme.success); - } - if (normalized.startsWith("linked")) { - return applyPrefix("linked", theme.success); - } - if (normalized.startsWith("configured")) { - return applyPrefix("configured", theme.success); - } - if (normalized.startsWith("not linked")) { - return applyPrefix("not linked", theme.warn); - } - if (normalized.startsWith("not configured")) { - return applyPrefix("not configured", theme.muted); - } - if (normalized.startsWith("unknown")) { - return applyPrefix("unknown", theme.warn); - } - - return line; -} - function runGatewayCommand(action: () => Promise, label?: string) { return runCommandWithRuntime(defaultRuntime, action, (err) => { const message = String(err); diff --git a/src/commands/health.ts b/src/commands/health.ts index 88b65948ed..f615a8ede0 100644 --- a/src/commands/health.ts +++ b/src/commands/health.ts @@ -17,7 +17,8 @@ import { } from "../infra/heartbeat-runner.js"; import { buildChannelAccountBindings, resolvePreferredAccountId } from "../routing/bindings.js"; import { normalizeAgentId } from "../routing/session-key.js"; -import { theme } from "../terminal/theme.js"; +import { styleHealthChannelLine } from "../terminal/health-style.js"; +import { isRich } from "../terminal/theme.js"; export type ChannelAccountHealthSummary = { accountId: string; @@ -248,44 +249,6 @@ const isProbeFailure = (summary: ChannelAccountHealthSummary): boolean => { return ok === false; }; -function styleHealthChannelLine(line: string): string { - const colon = line.indexOf(":"); - if (colon === -1) { - return line; - } - - const label = line.slice(0, colon + 1); - const detail = line.slice(colon + 1).trimStart(); - const normalized = detail.toLowerCase(); - - const applyPrefix = (prefix: string, color: (value: string) => string) => - `${label} ${color(detail.slice(0, prefix.length))}${detail.slice(prefix.length)}`; - - if (normalized.startsWith("failed")) { - return applyPrefix("failed", theme.error); - } - if (normalized.startsWith("ok")) { - return applyPrefix("ok", theme.success); - } - if (normalized.startsWith("linked")) { - return applyPrefix("linked", theme.success); - } - if (normalized.startsWith("configured")) { - return applyPrefix("configured", theme.success); - } - if (normalized.startsWith("not linked")) { - return applyPrefix("not linked", theme.warn); - } - if (normalized.startsWith("not configured")) { - return applyPrefix("not configured", theme.muted); - } - if (normalized.startsWith("unknown")) { - return applyPrefix("unknown", theme.warn); - } - - return line; -} - export const formatHealthChannelLines = ( summary: HealthSummary, opts: { @@ -586,6 +549,7 @@ export async function healthCommand( runtime.log(JSON.stringify(summary, null, 2)); } else { const debugEnabled = isTruthyEnvValue(process.env.OPENCLAW_DEBUG_HEALTH); + const rich = isRich(); if (opts.verbose) { const details = buildGatewayConnectionDetails({ config: cfg }); runtime.log(info("Gateway connection:")); @@ -705,7 +669,7 @@ export async function healthCommand( accountMode: opts.verbose ? "all" : "default", }); for (const line of channelLines) { - runtime.log(styleHealthChannelLine(line)); + runtime.log(styleHealthChannelLine(line, rich)); } for (const plugin of listChannelPlugins()) { const channelSummary = summary.channels?.[plugin.id]; diff --git a/src/terminal/health-style.ts b/src/terminal/health-style.ts new file mode 100644 index 0000000000..67bcfa62cc --- /dev/null +++ b/src/terminal/health-style.ts @@ -0,0 +1,43 @@ +import { theme } from "./theme.js"; + +export function styleHealthChannelLine(line: string, rich: boolean): string { + if (!rich) { + return line; + } + + const colon = line.indexOf(":"); + if (colon === -1) { + return line; + } + + const label = line.slice(0, colon + 1); + const detail = line.slice(colon + 1).trimStart(); + const normalized = detail.toLowerCase(); + + const applyPrefix = (prefix: string, color: (value: string) => string) => + `${label} ${color(detail.slice(0, prefix.length))}${detail.slice(prefix.length)}`; + + if (normalized.startsWith("failed")) { + return applyPrefix("failed", theme.error); + } + if (normalized.startsWith("ok")) { + return applyPrefix("ok", theme.success); + } + if (normalized.startsWith("linked")) { + return applyPrefix("linked", theme.success); + } + if (normalized.startsWith("configured")) { + return applyPrefix("configured", theme.success); + } + if (normalized.startsWith("not linked")) { + return applyPrefix("not linked", theme.warn); + } + if (normalized.startsWith("not configured")) { + return applyPrefix("not configured", theme.muted); + } + if (normalized.startsWith("unknown")) { + return applyPrefix("unknown", theme.warn); + } + + return line; +}