diff --git a/src/cli/nodes-cli/rpc.runtime.ts b/src/cli/nodes-cli/rpc.runtime.ts index 78639e45fd95..4ab56a82febf 100644 --- a/src/cli/nodes-cli/rpc.runtime.ts +++ b/src/cli/nodes-cli/rpc.runtime.ts @@ -1,3 +1,4 @@ +// Runtime gateway RPC helpers for node host and node pairing CLI commands. import { GATEWAY_CLIENT_MODES, GATEWAY_CLIENT_NAMES, @@ -21,6 +22,7 @@ export async function callGatewayCliRuntime( params?: unknown, callOpts?: { transportTimeoutMs?: number }, ) { + // Progress is suppressed for JSON callers so stdout remains structured. return await withProgress( { label: `Nodes ${method}`, diff --git a/src/cli/nodes-media-utils.ts b/src/cli/nodes-media-utils.ts index 5da6eac173c9..8452e98ad0b9 100644 --- a/src/cli/nodes-media-utils.ts +++ b/src/cli/nodes-media-utils.ts @@ -1,3 +1,4 @@ +// Media utility adapters for node CLI commands and temporary media outputs. import { randomUUID } from "node:crypto"; import fs from "node:fs"; import { resolvePreferredOpenClawTmpDir } from "../infra/tmp-openclaw-dir.js"; @@ -13,6 +14,7 @@ export function resolveTempPathParts(opts: { ext: string; tmpDir?: string; id?: tmpDir: string; id: string; } { + // Restrict extensions before writing temp media paths derived from CLI/user input. const tmpDir = opts.tmpDir ?? resolvePreferredOpenClawTmpDir(); const rawExt = opts.ext.startsWith(".") ? opts.ext : `.${opts.ext}`; if (!/^\.[A-Za-z0-9][A-Za-z0-9_-]{0,15}$/u.test(rawExt)) { diff --git a/src/cli/outbound-send-mapping.ts b/src/cli/outbound-send-mapping.ts index 4752bf8c5372..a0fb2c974899 100644 --- a/src/cli/outbound-send-mapping.ts +++ b/src/cli/outbound-send-mapping.ts @@ -1,3 +1,4 @@ +// Maps CLI send dependency sources into outbound send dependencies with legacy aliases. import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { normalizeChannelId } from "../channels/registry.js"; import { @@ -87,6 +88,7 @@ export function createOutboundSendDepsFromCliSource(deps: CliOutboundSendSource) } const resolveFactoryValue = (key: string): unknown => { + // Proxy reads can come from legacy sendX keys or canonical channel ids. const candidate = outbound[key] === undefined ? (resolveChannelIdFromLegacyOutboundKey(key) ?? key) : key; const channelId = resolveKnownChannelId(candidate); diff --git a/src/cli/pairing-cli.ts b/src/cli/pairing-cli.ts index b2c12ca65606..2ac6043af6d5 100644 --- a/src/cli/pairing-cli.ts +++ b/src/cli/pairing-cli.ts @@ -1,3 +1,4 @@ +// Pairing CLI for listing and approving channel DM pairing requests. import { normalizeLowercaseStringOrEmpty, normalizeStringifiedOptionalString, @@ -60,6 +61,7 @@ async function maybeBootstrapCommandOwnerFromPairing(params: { channel: PairingChannel; id: string; }): Promise<{ ownerEntry: string | null; bootstrapped: boolean }> { + // First approved pairing can seed ownerAllowFrom so command access is not left open-ended. const ownerEntry = formatCommandOwnerFromChannelSender(params); if (!ownerEntry) { return { ownerEntry: null, bootstrapped: false }; diff --git a/src/cli/plugin-install-plan.ts b/src/cli/plugin-install-plan.ts index 8e244f29bd18..d551b63f2f05 100644 --- a/src/cli/plugin-install-plan.ts +++ b/src/cli/plugin-install-plan.ts @@ -1,3 +1,4 @@ +// Plugin install planning helpers for bundled, official external, and npm fallback paths. import { parseRegistryNpmSpec } from "../infra/npm-registry-spec.js"; import type { BundledPluginSource } from "../plugins/bundled-sources.js"; import { PLUGIN_INSTALL_ERROR_CODE } from "../plugins/install.js"; @@ -66,6 +67,7 @@ export function resolveBundledInstallPlanBeforeNpm(params: { rawSpec: string; findBundledSource: BundledLookup; }): { bundledSource: BundledPluginSource; warning: string } | null { + // Bundled plugin ids win before npm lookup so local official plugins do not hit the registry. const rawSpec = params.rawSpec.trim(); if (!rawSpec) { return null; diff --git a/src/cli/plugin-registry.ts b/src/cli/plugin-registry.ts index f39a2da953c0..6593842e8df2 100644 --- a/src/cli/plugin-registry.ts +++ b/src/cli/plugin-registry.ts @@ -1,3 +1,4 @@ +// CLI-facing plugin registry loader re-export. export { testing, ensurePluginRegistryLoaded, diff --git a/src/cli/plugins-authoring-command.ts b/src/cli/plugins-authoring-command.ts index 01108625b1f6..83c8ae4a666e 100644 --- a/src/cli/plugins-authoring-command.ts +++ b/src/cli/plugins-authoring-command.ts @@ -1,3 +1,4 @@ +// Plugin authoring commands for init/build/validate manifest generation. import fs from "node:fs"; import path from "node:path"; import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; @@ -114,6 +115,7 @@ export async function loadToolPlugin(params: { rootDir: string; entryPath: string; }): Promise { + // Authoring validation imports the entry once and requires SDK metadata from defineToolPlugin. if (!fs.existsSync(params.entryPath)) { throw new Error( `plugin entry not found: ${normalizeRelativePath(params.rootDir, params.entryPath)}`, diff --git a/src/cli/plugins-cli-test-helpers.ts b/src/cli/plugins-cli-test-helpers.ts index 3ddf8f15666d..1034f3fe5a21 100644 --- a/src/cli/plugins-cli-test-helpers.ts +++ b/src/cli/plugins-cli-test-helpers.ts @@ -1,3 +1,4 @@ +// Shared Vitest mocks and runtime capture helpers for plugin CLI command tests. import { Command } from "commander"; import type { Mock } from "vitest"; import { vi } from "vitest"; @@ -25,6 +26,7 @@ type PluginInstallRecordMap = Record; let mockInstalledPluginIndexInstallRecords: PluginInstallRecordMap = {}; function clonePluginInstallRecords(records: PluginInstallRecordMap): PluginInstallRecordMap { + // Tests mutate records freely; clone to keep helper state from leaking across assertions. return structuredClone(records); } diff --git a/src/cli/plugins-cli.ts b/src/cli/plugins-cli.ts index 02db06eaaea5..f09cb0cd332e 100644 --- a/src/cli/plugins-cli.ts +++ b/src/cli/plugins-cli.ts @@ -1,3 +1,4 @@ +// Commander registration for plugin list/search/inspect/install/update/authoring commands. import type { Command } from "commander"; import { formatDocsLink } from "../../packages/terminal-core/src/links.js"; import { theme } from "../../packages/terminal-core/src/theme.js"; @@ -52,6 +53,7 @@ export type PluginAuthoringInitOptions = { }; function createModuleLoader(load: () => Promise): () => Promise { + // Plugin runtime modules are heavy; load each command surface once on first use. let promise: Promise | undefined; return () => (promise ??= load()); } diff --git a/src/cli/plugins-command-helpers.ts b/src/cli/plugins-command-helpers.ts index ea7fe8e56c35..b5fc31da81fe 100644 --- a/src/cli/plugins-command-helpers.ts +++ b/src/cli/plugins-command-helpers.ts @@ -1,3 +1,4 @@ +// Shared plugin CLI helpers for install logging, file specs, hooks, and slot selection. import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { theme } from "../../packages/terminal-core/src/theme.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; @@ -99,6 +100,7 @@ export function applySlotSelectionForPlugin( config: OpenClawConfig, pluginId: string, ): { config: OpenClawConfig; warnings: string[] } { + // Static metadata is preferred; runtime diagnostics fill in kind for older manifests. const report = buildSlotSelectionRegistry(config, pluginId); const plugin = report.plugins.find((entry) => entry.id === pluginId); if (!plugin) {