Spaces:
Running
Running
| import type { Command } from "commander"; | |
| import { healthCommand } from "../../commands/health.js"; | |
| import { sessionsCommand } from "../../commands/sessions.js"; | |
| import { statusCommand } from "../../commands/status.js"; | |
| import { setVerbose } from "../../globals.js"; | |
| import { defaultRuntime } from "../../runtime.js"; | |
| import { formatDocsLink } from "../../terminal/links.js"; | |
| import { theme } from "../../terminal/theme.js"; | |
| import { runCommandWithRuntime } from "../cli-utils.js"; | |
| import { formatHelpExamples } from "../help-format.js"; | |
| import { parsePositiveIntOrUndefined } from "./helpers.js"; | |
| function resolveVerbose(opts: { verbose?: boolean; debug?: boolean }): boolean { | |
| return Boolean(opts.verbose || opts.debug); | |
| } | |
| function parseTimeoutMs(timeout: unknown): number | null | undefined { | |
| const parsed = parsePositiveIntOrUndefined(timeout); | |
| if (timeout !== undefined && parsed === undefined) { | |
| defaultRuntime.error("--timeout must be a positive integer (milliseconds)"); | |
| defaultRuntime.exit(1); | |
| return null; | |
| } | |
| return parsed; | |
| } | |
| export function registerStatusHealthSessionsCommands(program: Command) { | |
| program | |
| .command("status") | |
| .description("Show channel health and recent session recipients") | |
| .option("--json", "Output JSON instead of text", false) | |
| .option("--all", "Full diagnosis (read-only, pasteable)", false) | |
| .option("--usage", "Show model provider usage/quota snapshots", false) | |
| .option("--deep", "Probe channels (WhatsApp Web + Telegram + Discord + Slack + Signal)", false) | |
| .option("--timeout <ms>", "Probe timeout in milliseconds", "10000") | |
| .option("--verbose", "Verbose logging", false) | |
| .option("--debug", "Alias for --verbose", false) | |
| .addHelpText( | |
| "after", | |
| () => | |
| `\n${theme.heading("Examples:")}\n${formatHelpExamples([ | |
| ["openclaw status", "Show channel health + session summary."], | |
| ["openclaw status --all", "Full diagnosis (read-only)."], | |
| ["openclaw status --json", "Machine-readable output."], | |
| ["openclaw status --usage", "Show model provider usage/quota snapshots."], | |
| [ | |
| "openclaw status --deep", | |
| "Run channel probes (WA + Telegram + Discord + Slack + Signal).", | |
| ], | |
| ["openclaw status --deep --timeout 5000", "Tighten probe timeout."], | |
| ])}`, | |
| ) | |
| .addHelpText( | |
| "after", | |
| () => | |
| `\n${theme.muted("Docs:")} ${formatDocsLink("/cli/status", "docs.openclaw.ai/cli/status")}\n`, | |
| ) | |
| .action(async (opts) => { | |
| const verbose = resolveVerbose(opts); | |
| setVerbose(verbose); | |
| const timeout = parseTimeoutMs(opts.timeout); | |
| if (timeout === null) { | |
| return; | |
| } | |
| await runCommandWithRuntime(defaultRuntime, async () => { | |
| await statusCommand( | |
| { | |
| json: Boolean(opts.json), | |
| all: Boolean(opts.all), | |
| deep: Boolean(opts.deep), | |
| usage: Boolean(opts.usage), | |
| timeoutMs: timeout, | |
| verbose, | |
| }, | |
| defaultRuntime, | |
| ); | |
| }); | |
| }); | |
| program | |
| .command("health") | |
| .description("Fetch health from the running gateway") | |
| .option("--json", "Output JSON instead of text", false) | |
| .option("--timeout <ms>", "Connection timeout in milliseconds", "10000") | |
| .option("--verbose", "Verbose logging", false) | |
| .option("--debug", "Alias for --verbose", false) | |
| .addHelpText( | |
| "after", | |
| () => | |
| `\n${theme.muted("Docs:")} ${formatDocsLink("/cli/health", "docs.openclaw.ai/cli/health")}\n`, | |
| ) | |
| .action(async (opts) => { | |
| const verbose = resolveVerbose(opts); | |
| setVerbose(verbose); | |
| const timeout = parseTimeoutMs(opts.timeout); | |
| if (timeout === null) { | |
| return; | |
| } | |
| await runCommandWithRuntime(defaultRuntime, async () => { | |
| await healthCommand( | |
| { | |
| json: Boolean(opts.json), | |
| timeoutMs: timeout, | |
| verbose, | |
| }, | |
| defaultRuntime, | |
| ); | |
| }); | |
| }); | |
| program | |
| .command("sessions") | |
| .description("List stored conversation sessions") | |
| .option("--json", "Output as JSON", false) | |
| .option("--verbose", "Verbose logging", false) | |
| .option("--store <path>", "Path to session store (default: resolved from config)") | |
| .option("--active <minutes>", "Only show sessions updated within the past N minutes") | |
| .addHelpText( | |
| "after", | |
| () => | |
| `\n${theme.heading("Examples:")}\n${formatHelpExamples([ | |
| ["openclaw sessions", "List all sessions."], | |
| ["openclaw sessions --active 120", "Only last 2 hours."], | |
| ["openclaw sessions --json", "Machine-readable output."], | |
| ["openclaw sessions --store ./tmp/sessions.json", "Use a specific session store."], | |
| ])}\n\n${theme.muted( | |
| "Shows token usage per session when the agent reports it; set agents.defaults.contextTokens to cap the window and show %.", | |
| )}`, | |
| ) | |
| .addHelpText( | |
| "after", | |
| () => | |
| `\n${theme.muted("Docs:")} ${formatDocsLink("/cli/sessions", "docs.openclaw.ai/cli/sessions")}\n`, | |
| ) | |
| .action(async (opts) => { | |
| setVerbose(Boolean(opts.verbose)); | |
| await sessionsCommand( | |
| { | |
| json: Boolean(opts.json), | |
| store: opts.store as string | undefined, | |
| active: opts.active as string | undefined, | |
| }, | |
| defaultRuntime, | |
| ); | |
| }); | |
| } | |