From a94a9396266461adcce2e424a1e2d3939dc59472 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Thu, 4 Jun 2026 10:58:50 -0400 Subject: [PATCH] docs: document cli command runtimes --- src/cli/hooks-cli.ts | 2 ++ src/cli/json-output-mode.ts | 1 + src/cli/log-level-option.ts | 1 + src/cli/logs-cli.runtime.ts | 2 ++ src/cli/logs-cli.ts | 2 ++ src/cli/mcp-cli.ts | 2 ++ src/cli/models-cli.runtime.ts | 2 ++ src/cli/models-cli.ts | 2 ++ src/cli/node-cli/daemon.ts | 2 ++ src/cli/node-cli/register.ts | 2 ++ 10 files changed, 18 insertions(+) diff --git a/src/cli/hooks-cli.ts b/src/cli/hooks-cli.ts index a34cf3fe3979..f251f682ccc5 100644 --- a/src/cli/hooks-cli.ts +++ b/src/cli/hooks-cli.ts @@ -1,3 +1,4 @@ +// Hooks CLI for listing, checking, toggling, installing, and updating hook integrations. import type { Command } from "commander"; import { decorativeEmoji, @@ -50,6 +51,7 @@ function mergeHookEntries(pluginEntries: HookEntry[], workspaceEntries: HookEntr } function buildHooksReport(config: OpenClawConfig): HookStatusReport { + // Plugin-managed and workspace hooks share one resolved policy view for status/actions. const workspaceDir = resolveAgentWorkspaceDir(config, resolveDefaultAgentId(config)); const workspaceEntries = loadWorkspaceHookEntries(workspaceDir, { config }); const pluginReport = buildPluginDiagnosticsReport({ config, workspaceDir }); diff --git a/src/cli/json-output-mode.ts b/src/cli/json-output-mode.ts index 9a4c5920265b..bebbeaeff8e8 100644 --- a/src/cli/json-output-mode.ts +++ b/src/cli/json-output-mode.ts @@ -1,3 +1,4 @@ +// Early JSON-output detection and console-log routing for parseable CLI stdout. import { loggingState } from "../logging/state.js"; /** Detects CLI JSON mode before Commander parses options, stopping at the argv sentinel. */ diff --git a/src/cli/log-level-option.ts b/src/cli/log-level-option.ts index 407957e9b1ad..b95244e30552 100644 --- a/src/cli/log-level-option.ts +++ b/src/cli/log-level-option.ts @@ -1,3 +1,4 @@ +// Commander parser for the shared CLI --log-level option. import { InvalidArgumentError } from "commander"; import { ALLOWED_LOG_LEVELS, type LogLevel, tryParseLogLevel } from "../logging/levels.js"; diff --git a/src/cli/logs-cli.runtime.ts b/src/cli/logs-cli.runtime.ts index aa71c0fa87fe..6832c910cfc9 100644 --- a/src/cli/logs-cli.runtime.ts +++ b/src/cli/logs-cli.runtime.ts @@ -1,3 +1,4 @@ +// Runtime helpers for bounded subprocess log tails and service runtime lookups. import { spawn } from "node:child_process"; export { buildGatewayConnectionDetails } from "../gateway/call.js"; @@ -11,6 +12,7 @@ export async function execFileUtf8Tail( args: string[], options: { env?: NodeJS.ProcessEnv; maxBytes: number }, ): Promise { + // Keep only the newest stdout bytes; log commands should not buffer unbounded output. return await new Promise((resolve) => { const child = spawn(command, args, { env: options.env, diff --git a/src/cli/logs-cli.ts b/src/cli/logs-cli.ts index aefcc444d621..b27f3bb711fd 100644 --- a/src/cli/logs-cli.ts +++ b/src/cli/logs-cli.ts @@ -1,3 +1,4 @@ +// Gateway logs CLI with RPC tailing, local file fallback, and systemd journal fallback. import { setTimeout as delay } from "node:timers/promises"; import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import type { Command } from "commander"; @@ -159,6 +160,7 @@ function normalizeErrorMessage(error: unknown): string { } function shouldUseLocalLogsFallback(opts: LogsCliOptions, error: unknown): boolean { + // Fallback reads local files only for implicit loopback Gateway RPC failures. if (!isLocalGatewayRpcUnavailableError(error)) { return false; } diff --git a/src/cli/mcp-cli.ts b/src/cli/mcp-cli.ts index a20564eeca98..741399553f5a 100644 --- a/src/cli/mcp-cli.ts +++ b/src/cli/mcp-cli.ts @@ -1,3 +1,4 @@ +// MCP CLI for configured servers, OAuth auth, diagnostics, and channel MCP serving. import { constants as fsConstants } from "node:fs"; import fs from "node:fs/promises"; import path from "node:path"; @@ -127,6 +128,7 @@ async function clearStaleMcpOAuthCredentialsForReplacement(params: { previous: unknown; next: unknown; }): Promise { + // Replacing an OAuth HTTP server should not leave credentials bound to the old URL. if (!hasOAuthAuth(params.previous)) { return; } diff --git a/src/cli/models-cli.runtime.ts b/src/cli/models-cli.runtime.ts index f3f245066a68..87c6880def78 100644 --- a/src/cli/models-cli.runtime.ts +++ b/src/cli/models-cli.runtime.ts @@ -1,3 +1,4 @@ +// Runtime helpers for model CLI commands and shared agent option handling. import type { Command } from "commander"; import { defaultRuntime } from "../runtime.js"; import { resolveOptionFromCommand, runCommandWithRuntime } from "./cli-utils.js"; @@ -23,6 +24,7 @@ export function rejectAgentScopedModelWrite( command: Command, commandName: "set" | "set-image", ): void { + // Write commands update global defaults; accepting --agent here would imply per-agent mutation. const agent = resolveOptionFromCommand(command, "agent"); if (!agent) { return; diff --git a/src/cli/models-cli.ts b/src/cli/models-cli.ts index 613236427ce5..0fb8d3e7867d 100644 --- a/src/cli/models-cli.ts +++ b/src/cli/models-cli.ts @@ -1,3 +1,4 @@ +// Commander registration for model catalog, status, auth, alias, and fallback commands. import type { Command } from "commander"; import { formatDocsLink } from "../../packages/terminal-core/src/links.js"; import { theme } from "../../packages/terminal-core/src/theme.js"; @@ -5,6 +6,7 @@ import { theme } from "../../packages/terminal-core/src/theme.js"; type ModelsCliRuntime = typeof import("./models-cli.runtime.js"); function createModuleLoader(load: () => Promise): () => Promise { + // Model subcommands are heavy; load each implementation once on first use. let promise: Promise | undefined; return () => (promise ??= load()); } diff --git a/src/cli/node-cli/daemon.ts b/src/cli/node-cli/daemon.ts index 5b52bc225d22..1fe4fe0dba17 100644 --- a/src/cli/node-cli/daemon.ts +++ b/src/cli/node-cli/daemon.ts @@ -1,3 +1,4 @@ +// Node-host daemon lifecycle commands for install, status, start, stop, and restart. import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { colorize } from "../../../packages/terminal-core/src/theme.js"; import { buildNodeInstallPlan } from "../../commands/node-daemon-install-helpers.js"; @@ -78,6 +79,7 @@ function resolveNodeDefaults( opts: NodeDaemonInstallOptions, config: Awaited>, ) { + // CLI flags override node-host config; missing values fall back to loopback Gateway defaults. const host = normalizeOptionalString(opts.host) || config?.gateway?.host || "127.0.0.1"; const portOverride = parsePort(opts.port); if (opts.port !== undefined && portOverride === null) { diff --git a/src/cli/node-cli/register.ts b/src/cli/node-cli/register.ts index b024402c155b..8056496c5574 100644 --- a/src/cli/node-cli/register.ts +++ b/src/cli/node-cli/register.ts @@ -1,3 +1,4 @@ +// Commander registration for foreground node host and node service lifecycle commands. import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import type { Command } from "commander"; import { formatDocsLink } from "../../../packages/terminal-core/src/links.js"; @@ -18,6 +19,7 @@ import { } from "./daemon.js"; function parsePortOption(value: unknown, fallback: number): number | null { + // Undefined keeps config/default port; invalid explicit input returns null for CLI errors. if (value === undefined) { return fallback; }