fix(cli): daemon output + health colors

This commit is contained in:
Peter Steinberger
2026-01-15 08:28:33 +00:00
parent 2bae4d2dba
commit f1ac18933c
6 changed files with 58 additions and 3 deletions

View File

@@ -2,6 +2,7 @@ import { beforeEach, describe, expect, it, vi } from "vitest";
import type { HealthSummary } from "./health.js";
import { healthCommand } from "./health.js";
import { stripAnsi } from "../terminal/ansi.js";
const callGatewayMock = vi.fn();
const logWebSelfIdMock = vi.fn();
@@ -70,7 +71,9 @@ describe("healthCommand (coverage)", () => {
await healthCommand({ json: false, timeoutMs: 1000 }, runtime as never);
expect(runtime.exit).not.toHaveBeenCalled();
expect(runtime.log.mock.calls.map((c) => String(c[0])).join("\n")).toMatch(/WhatsApp: linked/i);
expect(stripAnsi(runtime.log.mock.calls.map((c) => String(c[0])).join("\n"))).toMatch(
/WhatsApp: linked/i,
);
expect(logWebSelfIdMock).toHaveBeenCalled();
});
});

View File

@@ -8,6 +8,7 @@ import { buildGatewayConnectionDetails, callGateway } from "../gateway/call.js";
import { info } from "../globals.js";
import { formatErrorMessage } from "../infra/errors.js";
import type { RuntimeEnv } from "../runtime.js";
import { theme } from "../terminal/theme.js";
import { resolveHeartbeatSeconds } from "../web/reconnect.js";
export type ChannelHealthSummary = {
@@ -79,6 +80,28 @@ const formatProbeLine = (probe: unknown): string | null => {
return label;
};
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): string[] => {
const channels = summary.channels ?? {};
const channelOrder =
@@ -263,7 +286,7 @@ export async function healthCommand(
}
}
for (const line of formatHealthChannelLines(summary)) {
runtime.log(line);
runtime.log(styleHealthChannelLine(line));
}
const cfg = loadConfig();
for (const plugin of listChannelPlugins()) {