diff --git a/src/cli/models-cli.ts b/src/cli/models-cli.ts index fe0a94d562d..89601119b78 100644 --- a/src/cli/models-cli.ts +++ b/src/cli/models-cli.ts @@ -3,6 +3,7 @@ import { defaultRuntime } from "../runtime.js"; import { formatDocsLink } from "../terminal/links.js"; import { theme } from "../terminal/theme.js"; import { resolveOptionFromCommand, runCommandWithRuntime } from "./cli-utils.js"; +import { formatCliCommand } from "./command-format.js"; function runModelsCommand(action: () => Promise) { return runCommandWithRuntime(defaultRuntime, action); @@ -14,7 +15,7 @@ function rejectAgentScopedModelWrite(command: Command, commandName: "set" | "set return; } throw new Error( - `\`openclaw models ${commandName}\` does not support \`--agent\`; it only updates global model defaults. Remove \`--agent\` or use agent config to set a per-agent model override.`, + `openclaw models ${commandName} does not support --agent; it only updates global model defaults. Remove --agent, or run ${formatCliCommand("openclaw agents list")} and set the per-agent model in agent config.`, ); } diff --git a/src/cli/plugins-install-command.ts b/src/cli/plugins-install-command.ts index f589a45e091..faa4f6afd1e 100644 --- a/src/cli/plugins-install-command.ts +++ b/src/cli/plugins-install-command.ts @@ -33,6 +33,7 @@ import { validateJsonSchemaValue } from "../plugins/schema-validator.js"; import { defaultRuntime, type RuntimeEnv } from "../runtime.js"; import { theme } from "../terminal/theme.js"; import { shortenHomePath } from "../utils.js"; +import { formatCliCommand } from "./command-format.js"; import { looksLikeLocalInstallSpec } from "./install-spec.js"; import { resolvePinnedNpmInstallRecordForCli } from "./npm-resolution.js"; import { @@ -587,30 +588,42 @@ export async function runPluginInstallCommand(params: { }; if (opts.marketplace) { if (opts.link) { - runtime.error("`--link` is not supported with `--marketplace`."); + runtime.error( + `--link is not supported with --marketplace. Remove --link, or install a local path with ${formatCliCommand("openclaw plugins install --link ")}.`, + ); return runtime.exit(1); } if (opts.pin) { - runtime.error("`--pin` is not supported with `--marketplace`."); + runtime.error( + `--pin is not supported with --marketplace. Use ${formatCliCommand("openclaw plugins install --marketplace ")} without --pin.`, + ); return runtime.exit(1); } } const gitPrefix = raw.trim().toLowerCase().startsWith("git:"); const gitSpec = parseGitPluginSpec(raw); if (gitPrefix && !gitSpec) { - runtime.error(`unsupported git: plugin spec: ${raw}`); + runtime.error( + `Unsupported git plugin spec: ${raw}. Use ${formatCliCommand("openclaw plugins install git:@")}.`, + ); return runtime.exit(1); } if (gitSpec && opts.link) { - runtime.error("`--link` is not supported with `git:` installs."); + runtime.error( + `--link is not supported with git: installs. Use ${formatCliCommand("openclaw plugins install git:@")} for Git installs or ${formatCliCommand("openclaw plugins install --link ")} for local paths.`, + ); return runtime.exit(1); } if (gitSpec && opts.pin) { - runtime.error("`--pin` is not supported with `git:` installs; use `git:@`."); + runtime.error( + `--pin is not supported with git: installs. Pin the ref in the spec instead, for example ${formatCliCommand("openclaw plugins install git:@")}.`, + ); return runtime.exit(1); } if (opts.link && opts.force) { - runtime.error("`--force` is not supported with `--link`."); + runtime.error( + `--force is not supported with --link. Linked plugins point at the source path directly; remove --force and re-run ${formatCliCommand("openclaw plugins install --link ")}.`, + ); return runtime.exit(1); } const requestResolution = resolvePluginInstallRequestContext({ @@ -766,14 +779,18 @@ export async function runPluginInstallCommand(params: { } if (opts.link) { - runtime.error("`--link` requires a local path."); + runtime.error( + `--link requires a local path. Run ${formatCliCommand("openclaw plugins install --link ")}.`, + ); return runtime.exit(1); } const npmPrefixSpec = parseNpmPrefixSpec(raw); if (npmPrefixSpec !== null) { if (!npmPrefixSpec) { - runtime.error("unsupported npm: spec: missing package"); + runtime.error( + `Unsupported npm plugin spec: missing package. Use ${formatCliCommand("openclaw plugins install npm:")}.`, + ); return runtime.exit(1); } const officialNpmTrust = resolveOfficialExternalNpmPackageTrust({ @@ -808,7 +825,9 @@ export async function runPluginInstallCommand(params: { const npmPackPath = parseNpmPackPrefixPath(raw); if (npmPackPath !== null) { if (!npmPackPath) { - runtime.error("unsupported npm-pack: spec: missing pack archive path"); + runtime.error( + `Unsupported npm-pack plugin spec: missing archive path. Use ${formatCliCommand("openclaw plugins install npm-pack:")}.`, + ); return runtime.exit(1); } const npmPackResult = await tryInstallPluginFromNpmPackArchive({ @@ -852,7 +871,9 @@ export async function runPluginInstallCommand(params: { ".zip", ]) ) { - runtime.error(`Path not found: ${resolved}`); + runtime.error( + `Plugin path not found: ${resolved}. Check the path, or install from npm with ${formatCliCommand("openclaw plugins install npm:")}.`, + ); return runtime.exit(1); } diff --git a/src/cli/plugins-list-command.ts b/src/cli/plugins-list-command.ts index 778a4dce82d..7e7c51467e6 100644 --- a/src/cli/plugins-list-command.ts +++ b/src/cli/plugins-list-command.ts @@ -3,6 +3,7 @@ import { formatPluginSourceForTable, resolvePluginSourceRoots } from "../plugins import { defaultRuntime, writeRuntimeJson, type RuntimeEnv } from "../runtime.js"; import { getTerminalTableWidth, renderTable } from "../terminal/table.js"; import { theme } from "../terminal/theme.js"; +import { formatCliCommand } from "./command-format.js"; import { quietPluginJsonLogger } from "./plugins-command-helpers.js"; import { formatPluginLine } from "./plugins-list-format.js"; @@ -39,7 +40,11 @@ export async function runPluginsListCommand( } if (list.length === 0) { - runtime.log(theme.muted("No plugins found.")); + runtime.log( + theme.muted( + `No plugins found. Run ${formatCliCommand("openclaw plugins install ")} to add one, or ${formatCliCommand("openclaw plugins list --json")} to inspect raw discovery state.`, + ), + ); return; } diff --git a/src/cli/secrets-cli.ts b/src/cli/secrets-cli.ts index a6c1e0d4d45..7b6616aa2f1 100644 --- a/src/cli/secrets-cli.ts +++ b/src/cli/secrets-cli.ts @@ -2,6 +2,7 @@ import fs from "node:fs"; import { confirm } from "@clack/prompts"; import type { Command } from "commander"; import { danger } from "../globals.js"; +import { formatErrorMessage } from "../infra/errors.js"; import { defaultRuntime } from "../runtime.js"; import { runSecretsApply } from "../secrets/apply.js"; import { resolveSecretsAuditExitCode, runSecretsAudit } from "../secrets/audit.js"; @@ -9,6 +10,7 @@ import { runSecretsConfigureInteractive } from "../secrets/configure.js"; import { isSecretsApplyPlan, type SecretsApplyPlan } from "../secrets/plan.js"; import { formatDocsLink } from "../terminal/links.js"; import { theme } from "../terminal/theme.js"; +import { formatCliCommand } from "./command-format.js"; import { addGatewayClientOptions, callGatewayFromCli, type GatewayRpcOpts } from "./gateway-rpc.js"; type SecretsReloadOptions = GatewayRpcOpts & { json?: boolean }; @@ -38,7 +40,9 @@ function readPlanFile(pathname: string): SecretsApplyPlan { const raw = fs.readFileSync(pathname, "utf8"); const parsed = JSON.parse(raw) as unknown; if (!isSecretsApplyPlan(parsed)) { - throw new Error(`Invalid secrets plan file: ${pathname}`); + throw new Error( + `Invalid secrets plan file: ${pathname}. Generate a fresh plan with ${formatCliCommand("openclaw secrets configure --plan-out ")}.`, + ); } return parsed; } @@ -76,7 +80,11 @@ export function registerSecretsCli(program: Command) { } defaultRuntime.log("Secrets reloaded."); } catch (err) { - defaultRuntime.error(danger(String(err))); + defaultRuntime.error( + danger( + `Secrets reload failed: ${formatErrorMessage(err)}. Run ${formatCliCommand("openclaw gateway status --deep")} to inspect the active gateway.`, + ), + ); defaultRuntime.exit(1); } }); @@ -123,7 +131,11 @@ export function registerSecretsCli(program: Command) { defaultRuntime.exit(exitCode); } } catch (err) { - defaultRuntime.error(danger(String(err))); + defaultRuntime.error( + danger( + `Secrets audit failed: ${formatErrorMessage(err)}. Run ${formatCliCommand("openclaw doctor")} to inspect config and credential state.`, + ), + ); defaultRuntime.exit(2); } }); @@ -232,7 +244,11 @@ export function registerSecretsCli(program: Command) { ); } } catch (err) { - defaultRuntime.error(danger(String(err))); + defaultRuntime.error( + danger( + `Secrets configure failed: ${formatErrorMessage(err)}. Re-run ${formatCliCommand("openclaw secrets audit")} before applying changes.`, + ), + ); defaultRuntime.exit(1); } }); @@ -275,7 +291,11 @@ export function registerSecretsCli(program: Command) { : "Secrets apply: no changes.", ); } catch (err) { - defaultRuntime.error(danger(String(err))); + defaultRuntime.error( + danger( + `Secrets apply failed: ${formatErrorMessage(err)}. Re-run ${formatCliCommand("openclaw secrets apply --from --dry-run")} to inspect the plan without writing.`, + ), + ); defaultRuntime.exit(1); } });