fix(cli): clarify remaining required options · openclaw/openclaw@e45b9d7
vincentkoc
·
2026-05-09
·
via Recent Commits to openclaw:main
| Original file line number | Diff line number | Diff line change |
|---|
@@ -2,6 +2,7 @@ import type { Command } from "commander";
|
2 | 2 | import { runAcpClientInteractive } from "../acp/client.js"; |
3 | 3 | import { serveAcpGateway } from "../acp/server.js"; |
4 | 4 | import { normalizeAcpProvenanceMode } from "../acp/types.js"; |
| 5 | +import { formatErrorMessage } from "../infra/errors.js"; |
5 | 6 | import { defaultRuntime } from "../runtime.js"; |
6 | 7 | import { formatDocsLink } from "../terminal/links.js"; |
7 | 8 | import { theme } from "../terminal/theme.js"; |
@@ -33,7 +34,7 @@ export function registerAcpCli(program: Command) {
|
33 | 34 | const { gatewayToken, gatewayPassword } = resolveGatewayAuthOptions(opts); |
34 | 35 | const provenanceMode = normalizeAcpProvenanceMode(opts.provenance as string | undefined); |
35 | 36 | if (opts.provenance && !provenanceMode) { |
36 | | -throw new Error("Invalid --provenance value. Use off, meta, or meta+receipt."); |
| 37 | +throw new Error('Invalid --provenance. Use "off", "meta", or "meta+receipt".'); |
37 | 38 | } |
38 | 39 | await serveAcpGateway({ |
39 | 40 | gatewayUrl: opts.url as string | undefined, |
@@ -48,7 +49,7 @@ export function registerAcpCli(program: Command) {
|
48 | 49 | verbose: Boolean(opts.verbose), |
49 | 50 | }); |
50 | 51 | } catch (err) { |
51 | | -defaultRuntime.error(String(err)); |
| 52 | +defaultRuntime.error(`ACP bridge failed: ${formatErrorMessage(err)}`); |
52 | 53 | defaultRuntime.exit(1); |
53 | 54 | } |
54 | 55 | }); |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -232,7 +232,7 @@ export function registerCronAddCommand(cron: Command) {
|
232 | 232 | |
233 | 233 | const name = normalizeOptionalString(opts.name) ?? ""; |
234 | 234 | if (!name) { |
235 | | -throw new Error("--name is required"); |
| 235 | +throw new Error("Cron job name is required. Pass --name <name>."); |
236 | 236 | } |
237 | 237 | |
238 | 238 | const description = normalizeOptionalString(opts.description); |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -104,14 +104,14 @@ function resolveDirectSchedule(options: NormalizedScheduleOptions): CronSchedule
|
104 | 104 | if (options.at) { |
105 | 105 | const atIso = parseAt(options.at, options.tz); |
106 | 106 | if (!atIso) { |
107 | | -throw new Error("Invalid --at; use ISO time or duration like 20m"); |
| 107 | +throw new Error("Invalid --at. Use an ISO timestamp or a duration like 20m."); |
108 | 108 | } |
109 | 109 | return { kind: "at", at: atIso }; |
110 | 110 | } |
111 | 111 | if (options.every) { |
112 | 112 | const everyMs = parseDurationMs(options.every); |
113 | 113 | if (!everyMs) { |
114 | | -throw new Error("Invalid --every; use e.g. 10m, 1h, 1d"); |
| 114 | +throw new Error("Invalid --every. Use a duration like 10m, 1h, or 1d."); |
115 | 115 | } |
116 | 116 | return { kind: "every", everyMs }; |
117 | 117 | } |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -7,7 +7,9 @@ import type { DaemonStatusOptions } from "./types.js";
|
7 | 7 | export async function runDaemonStatus(opts: DaemonStatusOptions) { |
8 | 8 | try { |
9 | 9 | if (opts.requireRpc && !opts.probe) { |
10 | | -defaultRuntime.error("Gateway status failed: --require-rpc cannot be used with --no-probe."); |
| 10 | +defaultRuntime.error( |
| 11 | +"Gateway status failed: --require-rpc needs probing enabled. Remove --no-probe or drop --require-rpc.", |
| 12 | +); |
11 | 13 | defaultRuntime.exit(1); |
12 | 14 | return; |
13 | 15 | } |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -30,6 +30,7 @@ import {
|
30 | 30 | import { sanitizeForLog } from "../terminal/ansi.js"; |
31 | 31 | import { getTerminalTableWidth, renderTable } from "../terminal/table.js"; |
32 | 32 | import { theme } from "../terminal/theme.js"; |
| 33 | +import { formatCliCommand } from "./command-format.js"; |
33 | 34 | import { applyParentDefaultHelpAction } from "./program/parent-default-help.js"; |
34 | 35 | import { withProgress } from "./progress.js"; |
35 | 36 | |
@@ -509,7 +510,9 @@ function resolveRequiredDeviceRole(
|
509 | 510 | if (deviceId && role) { |
510 | 511 | return { deviceId, role }; |
511 | 512 | } |
512 | | -defaultRuntime.error("--device and --role required"); |
| 513 | +defaultRuntime.error( |
| 514 | +`--device and --role are required. Run ${formatCliCommand("openclaw devices list")} to choose a paired device.`, |
| 515 | +); |
513 | 516 | defaultRuntime.exit(1); |
514 | 517 | return null; |
515 | 518 | } |
@@ -608,7 +611,9 @@ export function registerDevicesCli(program: Command) {
|
608 | 611 | .action(async (deviceId: string, opts: DevicesRpcOpts) => { |
609 | 612 | const trimmed = deviceId.trim(); |
610 | 613 | if (!trimmed) { |
611 | | -defaultRuntime.error("deviceId is required"); |
| 614 | +defaultRuntime.error( |
| 615 | +`deviceId is required. Run ${formatCliCommand("openclaw devices list")} to choose a paired device.`, |
| 616 | +); |
612 | 617 | defaultRuntime.exit(1); |
613 | 618 | return; |
614 | 619 | } |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -2,6 +2,7 @@ import type { Command } from "commander";
|
2 | 2 | import { defaultRuntime } from "../../runtime.js"; |
3 | 3 | import { normalizeOptionalString } from "../../shared/string-coerce.js"; |
4 | 4 | import { getTerminalTableWidth } from "../../terminal/table.js"; |
| 5 | +import { formatCliCommand } from "../command-format.js"; |
5 | 6 | import { getNodesTheme, runNodesCommand } from "./cli-utils.js"; |
6 | 7 | import { parsePairingList } from "./format.js"; |
7 | 8 | import { renderPendingPairingRequestsTable } from "./pairing-render.js"; |
@@ -80,7 +81,9 @@ export function registerNodesPairingCommands(nodes: Command) {
|
80 | 81 | await runNodesCommand("remove", async () => { |
81 | 82 | const nodeId = await resolveNodeId(opts, normalizeOptionalString(opts.node) ?? ""); |
82 | 83 | if (!nodeId) { |
83 | | -defaultRuntime.error("--node required"); |
| 84 | +defaultRuntime.error( |
| 85 | +`--node is required. Run ${formatCliCommand("openclaw nodes pairing pending")} to choose a node request.`, |
| 86 | +); |
84 | 87 | defaultRuntime.exit(1); |
85 | 88 | return; |
86 | 89 | } |
@@ -106,7 +109,9 @@ export function registerNodesPairingCommands(nodes: Command) {
|
106 | 109 | const nodeId = await resolveNodeId(opts, normalizeOptionalString(opts.node) ?? ""); |
107 | 110 | const name = normalizeOptionalString(opts.name) ?? ""; |
108 | 111 | if (!nodeId || !name) { |
109 | | -defaultRuntime.error("--node and --name required"); |
| 112 | +defaultRuntime.error( |
| 113 | +`--node and --name are required. Run ${formatCliCommand("openclaw nodes pairing pending")} to choose a node, then rerun with --name <displayName>.`, |
| 114 | +); |
110 | 115 | defaultRuntime.exit(1); |
111 | 116 | return; |
112 | 117 | } |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -4,6 +4,7 @@ import { defaultRuntime } from "../runtime.js";
|
4 | 4 | import { normalizeOptionalString } from "../shared/string-coerce.js"; |
5 | 5 | import { formatDocsLink } from "../terminal/links.js"; |
6 | 6 | import { theme } from "../terminal/theme.js"; |
| 7 | +import { formatCliCommand } from "./command-format.js"; |
7 | 8 | import type { GatewayRpcOpts } from "./gateway-rpc.js"; |
8 | 9 | import { addGatewayClientOptions, callGatewayFromCli } from "./gateway-rpc.js"; |
9 | 10 | |
@@ -62,7 +63,9 @@ export function registerSystemCli(program: Command) {
|
62 | 63 | async () => { |
63 | 64 | const text = normalizeOptionalString(opts.text) ?? ""; |
64 | 65 | if (!text) { |
65 | | -throw new Error("--text is required"); |
| 66 | +throw new Error( |
| 67 | +`--text is required. Example: ${formatCliCommand('openclaw system event --text "deploy finished"')}.`, |
| 68 | +); |
66 | 69 | } |
67 | 70 | const mode = normalizeWakeMode(opts.mode); |
68 | 71 | return await callGatewayFromCli("wake", opts, { mode, text }, { expectFinal: false }); |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -20,6 +20,7 @@ import { defaultRuntime } from "../runtime.js";
|
20 | 20 | import { normalizeOptionalString } from "../shared/string-coerce.js"; |
21 | 21 | import { formatDocsLink } from "../terminal/links.js"; |
22 | 22 | import { theme } from "../terminal/theme.js"; |
| 23 | +import { formatCliCommand } from "./command-format.js"; |
23 | 24 | |
24 | 25 | export function registerWebhooksCli(program: Command) { |
25 | 26 | const webhooks = program |
@@ -109,7 +110,9 @@ function parseGmailSetupOptions(raw: Record<string, unknown>): GmailSetupOptions
|
109 | 110 | const accountRaw = raw.account; |
110 | 111 | const account = normalizeOptionalString(accountRaw) ?? ""; |
111 | 112 | if (!account) { |
112 | | -throw new Error("--account is required"); |
| 113 | +throw new Error( |
| 114 | +`--account is required. Example: ${formatCliCommand("openclaw webhooks gmail setup --account default")}.`, |
| 115 | +); |
113 | 116 | } |
114 | 117 | const common = parseGmailCommonOptions(raw); |
115 | 118 | return { |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -413,7 +413,9 @@ export async function modelsAuthPasteTokenCommand(
|
413 | 413 | const agentDir = await resolveModelsAuthAgentDir(opts.agent); |
414 | 414 | const rawProvider = normalizeOptionalString(opts.provider); |
415 | 415 | if (!rawProvider) { |
416 | | -throw new Error("Missing --provider."); |
| 416 | +throw new Error( |
| 417 | +`Missing --provider. Run ${formatCliCommand("openclaw models status")} or ${formatCliCommand("openclaw plugins list")} to choose a provider.`, |
| 418 | +); |
417 | 419 | } |
418 | 420 | const provider = normalizeProviderId(rawProvider); |
419 | 421 | const profileId = |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -146,7 +146,9 @@ export function applyNonInteractiveGatewayConfig(params: {
|
146 | 146 | if (authMode === "password") { |
147 | 147 | const password = opts.gatewayPassword?.trim(); |
148 | 148 | if (!password) { |
149 | | -runtime.error("Missing --gateway-password for password auth."); |
| 149 | +runtime.error( |
| 150 | +"Missing --gateway-password for password auth. Pass --gateway-password or use --gateway-auth token.", |
| 151 | +); |
150 | 152 | runtime.exit(1); |
151 | 153 | return null; |
152 | 154 | } |
|
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。