Files
openclaw/src/cli/program/help.ts

99 lines
3.3 KiB
TypeScript
Raw Normal View History

2026-01-14 01:08:15 +00:00
import type { Command } from "commander";
import type { ProgramContext } from "./context.js";
2026-01-14 01:08:15 +00:00
import { formatDocsLink } from "../../terminal/links.js";
import { isRich, theme } from "../../terminal/theme.js";
import { formatCliBannerLine, hasEmittedCliBanner } from "../banner.js";
2026-01-27 11:27:41 +00:00
import { replaceCliName, resolveCliName } from "../cli-name.js";
2026-01-14 01:08:15 +00:00
2026-01-27 11:27:41 +00:00
const CLI_NAME = resolveCliName();
2026-01-14 01:08:15 +00:00
const EXAMPLES = [
[
2026-01-30 03:15:10 +01:00
"openclaw channels login --verbose",
"Link personal WhatsApp Web and show QR + connection logs.",
],
[
'openclaw message send --target +15555550123 --message "Hi" --json',
2026-01-14 01:08:15 +00:00
"Send via your web session and print JSON result.",
],
2026-01-30 03:15:10 +01:00
["openclaw gateway --port 18789", "Run the WebSocket Gateway locally."],
["openclaw --dev gateway", "Run a dev Gateway (isolated state/config) on ws://127.0.0.1:19001."],
["openclaw gateway --force", "Kill anything bound to the default gateway port, then start it."],
["openclaw gateway ...", "Gateway control via WebSocket."],
2026-01-14 01:08:15 +00:00
[
2026-01-30 03:15:10 +01:00
'openclaw agent --to +15555550123 --message "Run summary" --deliver',
2026-01-14 01:08:15 +00:00
"Talk directly to the agent using the Gateway; optionally send the WhatsApp reply.",
],
[
2026-01-30 03:15:10 +01:00
'openclaw message send --channel telegram --target @mychat --message "Hi"',
2026-01-14 01:08:15 +00:00
"Send via your Telegram bot.",
],
] as const;
export function configureProgramHelp(program: Command, ctx: ProgramContext) {
program
2026-01-27 11:27:41 +00:00
.name(CLI_NAME)
2026-01-14 01:08:15 +00:00
.description("")
.version(ctx.programVersion)
.option(
"--dev",
2026-01-30 03:15:10 +01:00
"Dev profile: isolate state under ~/.openclaw-dev, default gateway port 19001, and shift derived ports (browser/canvas)",
2026-01-14 01:08:15 +00:00
)
.option(
"--profile <name>",
2026-01-30 03:15:10 +01:00
"Use a named profile (isolates OPENCLAW_STATE_DIR/OPENCLAW_CONFIG_PATH under ~/.openclaw-<name>)",
2026-01-14 01:08:15 +00:00
);
program.option("--no-color", "Disable ANSI colors", false);
program.configureHelp({
// sort options and subcommands alphabetically
sortSubcommands: true,
sortOptions: true,
2026-01-14 01:08:15 +00:00
optionTerm: (option) => theme.option(option.flags),
subcommandTerm: (cmd) => theme.command(cmd.name()),
});
program.configureOutput({
writeOut: (str) => {
const colored = str
.replace(/^Usage:/gm, theme.heading("Usage:"))
.replace(/^Options:/gm, theme.heading("Options:"))
.replace(/^Commands:/gm, theme.heading("Commands:"));
process.stdout.write(colored);
},
writeErr: (str) => process.stderr.write(str),
outputError: (str, write) => write(theme.error(str)),
});
if (
process.argv.includes("-V") ||
process.argv.includes("--version") ||
process.argv.includes("-v")
) {
console.log(ctx.programVersion);
process.exit(0);
}
program.addHelpText("beforeAll", () => {
if (hasEmittedCliBanner()) {
return "";
}
2026-01-14 01:08:15 +00:00
const rich = isRich();
const line = formatCliBannerLine(ctx.programVersion, { richTty: rich });
return `\n${line}\n`;
});
const fmtExamples = EXAMPLES.map(
2026-01-27 11:27:41 +00:00
([cmd, desc]) => ` ${theme.command(replaceCliName(cmd, CLI_NAME))}\n ${theme.muted(desc)}`,
2026-01-14 01:08:15 +00:00
).join("\n");
program.addHelpText("afterAll", ({ command }) => {
if (command !== program) {
return "";
}
2026-01-30 03:15:10 +01:00
const docs = formatDocsLink("/cli", "docs.openclaw.ai/cli");
return `\n${theme.heading("Examples:")}\n${fmtExamples}\n\n${theme.muted("Docs:")} ${docs}\n`;
2026-01-14 01:08:15 +00:00
});
}