mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-12 09:41:11 +00:00
CLI: improve command descriptions in help output (#18486)
* CLI: clarify config vs configure descriptions * CLI: improve top-level command descriptions * CLI: make direct command help more descriptive * CLI: add commands hint to root help * CLI: show root help hint in implicit help output * CLI: add help example for command-specific help * CLI: tweak root subcommand marker spacing * CLI: mark clawbot as subcommand root in help * CLI: derive subcommand markers from registry metadata * CLI: escape help regex CLI name
This commit is contained in:
committed by
GitHub
parent
05a83b9e97
commit
b25f334fa2
@@ -9,6 +9,7 @@ type SubCliRegistrar = (program: Command) => Promise<void> | void;
|
||||
type SubCliEntry = {
|
||||
name: string;
|
||||
description: string;
|
||||
hasSubcommands: boolean;
|
||||
register: SubCliRegistrar;
|
||||
};
|
||||
|
||||
@@ -31,10 +32,14 @@ const loadConfig = async (): Promise<OpenClawConfig> => {
|
||||
return mod.loadConfig();
|
||||
};
|
||||
|
||||
// Note for humans and agents:
|
||||
// If you update the list of commands, also check whether they have subcommands
|
||||
// and set the flag accordingly.
|
||||
const entries: SubCliEntry[] = [
|
||||
{
|
||||
name: "acp",
|
||||
description: "Agent Control Protocol tools",
|
||||
hasSubcommands: true,
|
||||
register: async (program) => {
|
||||
const mod = await import("../acp-cli.js");
|
||||
mod.registerAcpCli(program);
|
||||
@@ -42,7 +47,8 @@ const entries: SubCliEntry[] = [
|
||||
},
|
||||
{
|
||||
name: "gateway",
|
||||
description: "Gateway control",
|
||||
description: "Run, inspect, and query the WebSocket Gateway",
|
||||
hasSubcommands: true,
|
||||
register: async (program) => {
|
||||
const mod = await import("../gateway-cli.js");
|
||||
mod.registerGatewayCli(program);
|
||||
@@ -51,6 +57,7 @@ const entries: SubCliEntry[] = [
|
||||
{
|
||||
name: "daemon",
|
||||
description: "Gateway service (legacy alias)",
|
||||
hasSubcommands: true,
|
||||
register: async (program) => {
|
||||
const mod = await import("../daemon-cli.js");
|
||||
mod.registerDaemonCli(program);
|
||||
@@ -58,7 +65,8 @@ const entries: SubCliEntry[] = [
|
||||
},
|
||||
{
|
||||
name: "logs",
|
||||
description: "Gateway logs",
|
||||
description: "Tail gateway file logs via RPC",
|
||||
hasSubcommands: false,
|
||||
register: async (program) => {
|
||||
const mod = await import("../logs-cli.js");
|
||||
mod.registerLogsCli(program);
|
||||
@@ -67,6 +75,7 @@ const entries: SubCliEntry[] = [
|
||||
{
|
||||
name: "system",
|
||||
description: "System events, heartbeat, and presence",
|
||||
hasSubcommands: true,
|
||||
register: async (program) => {
|
||||
const mod = await import("../system-cli.js");
|
||||
mod.registerSystemCli(program);
|
||||
@@ -74,7 +83,8 @@ const entries: SubCliEntry[] = [
|
||||
},
|
||||
{
|
||||
name: "models",
|
||||
description: "Model configuration",
|
||||
description: "Discover, scan, and configure models",
|
||||
hasSubcommands: true,
|
||||
register: async (program) => {
|
||||
const mod = await import("../models-cli.js");
|
||||
mod.registerModelsCli(program);
|
||||
@@ -82,7 +92,8 @@ const entries: SubCliEntry[] = [
|
||||
},
|
||||
{
|
||||
name: "approvals",
|
||||
description: "Exec approvals",
|
||||
description: "Manage exec approvals (gateway or node host)",
|
||||
hasSubcommands: true,
|
||||
register: async (program) => {
|
||||
const mod = await import("../exec-approvals-cli.js");
|
||||
mod.registerExecApprovalsCli(program);
|
||||
@@ -90,7 +101,8 @@ const entries: SubCliEntry[] = [
|
||||
},
|
||||
{
|
||||
name: "nodes",
|
||||
description: "Node commands",
|
||||
description: "Manage gateway-owned node pairing and node commands",
|
||||
hasSubcommands: true,
|
||||
register: async (program) => {
|
||||
const mod = await import("../nodes-cli.js");
|
||||
mod.registerNodesCli(program);
|
||||
@@ -99,6 +111,7 @@ const entries: SubCliEntry[] = [
|
||||
{
|
||||
name: "devices",
|
||||
description: "Device pairing + token management",
|
||||
hasSubcommands: true,
|
||||
register: async (program) => {
|
||||
const mod = await import("../devices-cli.js");
|
||||
mod.registerDevicesCli(program);
|
||||
@@ -106,7 +119,8 @@ const entries: SubCliEntry[] = [
|
||||
},
|
||||
{
|
||||
name: "node",
|
||||
description: "Node control",
|
||||
description: "Run and manage the headless node host service",
|
||||
hasSubcommands: true,
|
||||
register: async (program) => {
|
||||
const mod = await import("../node-cli.js");
|
||||
mod.registerNodeCli(program);
|
||||
@@ -114,7 +128,8 @@ const entries: SubCliEntry[] = [
|
||||
},
|
||||
{
|
||||
name: "sandbox",
|
||||
description: "Sandbox tools",
|
||||
description: "Manage sandbox containers for agent isolation",
|
||||
hasSubcommands: true,
|
||||
register: async (program) => {
|
||||
const mod = await import("../sandbox-cli.js");
|
||||
mod.registerSandboxCli(program);
|
||||
@@ -122,7 +137,8 @@ const entries: SubCliEntry[] = [
|
||||
},
|
||||
{
|
||||
name: "tui",
|
||||
description: "Terminal UI",
|
||||
description: "Open a terminal UI connected to the Gateway",
|
||||
hasSubcommands: false,
|
||||
register: async (program) => {
|
||||
const mod = await import("../tui-cli.js");
|
||||
mod.registerTuiCli(program);
|
||||
@@ -130,7 +146,8 @@ const entries: SubCliEntry[] = [
|
||||
},
|
||||
{
|
||||
name: "cron",
|
||||
description: "Cron scheduler",
|
||||
description: "Manage cron jobs via the Gateway scheduler",
|
||||
hasSubcommands: true,
|
||||
register: async (program) => {
|
||||
const mod = await import("../cron-cli.js");
|
||||
mod.registerCronCli(program);
|
||||
@@ -138,7 +155,8 @@ const entries: SubCliEntry[] = [
|
||||
},
|
||||
{
|
||||
name: "dns",
|
||||
description: "DNS helpers",
|
||||
description: "DNS helpers for wide-area discovery (Tailscale + CoreDNS)",
|
||||
hasSubcommands: true,
|
||||
register: async (program) => {
|
||||
const mod = await import("../dns-cli.js");
|
||||
mod.registerDnsCli(program);
|
||||
@@ -146,7 +164,8 @@ const entries: SubCliEntry[] = [
|
||||
},
|
||||
{
|
||||
name: "docs",
|
||||
description: "Docs helpers",
|
||||
description: "Search the live OpenClaw docs",
|
||||
hasSubcommands: false,
|
||||
register: async (program) => {
|
||||
const mod = await import("../docs-cli.js");
|
||||
mod.registerDocsCli(program);
|
||||
@@ -154,7 +173,8 @@ const entries: SubCliEntry[] = [
|
||||
},
|
||||
{
|
||||
name: "hooks",
|
||||
description: "Hooks tooling",
|
||||
description: "Manage internal agent hooks",
|
||||
hasSubcommands: true,
|
||||
register: async (program) => {
|
||||
const mod = await import("../hooks-cli.js");
|
||||
mod.registerHooksCli(program);
|
||||
@@ -162,7 +182,8 @@ const entries: SubCliEntry[] = [
|
||||
},
|
||||
{
|
||||
name: "webhooks",
|
||||
description: "Webhook helpers",
|
||||
description: "Webhook helpers and integrations",
|
||||
hasSubcommands: true,
|
||||
register: async (program) => {
|
||||
const mod = await import("../webhooks-cli.js");
|
||||
mod.registerWebhooksCli(program);
|
||||
@@ -171,6 +192,7 @@ const entries: SubCliEntry[] = [
|
||||
{
|
||||
name: "qr",
|
||||
description: "Generate iOS pairing QR/setup code",
|
||||
hasSubcommands: false,
|
||||
register: async (program) => {
|
||||
const mod = await import("../qr-cli.js");
|
||||
mod.registerQrCli(program);
|
||||
@@ -179,6 +201,7 @@ const entries: SubCliEntry[] = [
|
||||
{
|
||||
name: "clawbot",
|
||||
description: "Legacy clawbot command aliases",
|
||||
hasSubcommands: true,
|
||||
register: async (program) => {
|
||||
const mod = await import("../clawbot-cli.js");
|
||||
mod.registerClawbotCli(program);
|
||||
@@ -186,7 +209,8 @@ const entries: SubCliEntry[] = [
|
||||
},
|
||||
{
|
||||
name: "pairing",
|
||||
description: "Pairing helpers",
|
||||
description: "Secure DM pairing (approve inbound requests)",
|
||||
hasSubcommands: true,
|
||||
register: async (program) => {
|
||||
// Initialize plugins before registering pairing CLI.
|
||||
// The pairing CLI calls listPairingChannels() at registration time,
|
||||
@@ -199,7 +223,8 @@ const entries: SubCliEntry[] = [
|
||||
},
|
||||
{
|
||||
name: "plugins",
|
||||
description: "Plugin management",
|
||||
description: "Manage OpenClaw plugins and extensions",
|
||||
hasSubcommands: true,
|
||||
register: async (program) => {
|
||||
const mod = await import("../plugins-cli.js");
|
||||
mod.registerPluginsCli(program);
|
||||
@@ -209,7 +234,8 @@ const entries: SubCliEntry[] = [
|
||||
},
|
||||
{
|
||||
name: "channels",
|
||||
description: "Channel management",
|
||||
description: "Manage connected chat channels (Telegram, Discord, etc.)",
|
||||
hasSubcommands: true,
|
||||
register: async (program) => {
|
||||
const mod = await import("../channels-cli.js");
|
||||
mod.registerChannelsCli(program);
|
||||
@@ -217,7 +243,8 @@ const entries: SubCliEntry[] = [
|
||||
},
|
||||
{
|
||||
name: "directory",
|
||||
description: "Directory commands",
|
||||
description: "Lookup contact and group IDs (self, peers, groups) for supported chat channels",
|
||||
hasSubcommands: true,
|
||||
register: async (program) => {
|
||||
const mod = await import("../directory-cli.js");
|
||||
mod.registerDirectoryCli(program);
|
||||
@@ -225,7 +252,8 @@ const entries: SubCliEntry[] = [
|
||||
},
|
||||
{
|
||||
name: "security",
|
||||
description: "Security helpers",
|
||||
description: "Security tools and local config audits",
|
||||
hasSubcommands: true,
|
||||
register: async (program) => {
|
||||
const mod = await import("../security-cli.js");
|
||||
mod.registerSecurityCli(program);
|
||||
@@ -233,7 +261,8 @@ const entries: SubCliEntry[] = [
|
||||
},
|
||||
{
|
||||
name: "skills",
|
||||
description: "Skills management",
|
||||
description: "List and inspect available skills",
|
||||
hasSubcommands: true,
|
||||
register: async (program) => {
|
||||
const mod = await import("../skills-cli.js");
|
||||
mod.registerSkillsCli(program);
|
||||
@@ -241,7 +270,8 @@ const entries: SubCliEntry[] = [
|
||||
},
|
||||
{
|
||||
name: "update",
|
||||
description: "CLI update helpers",
|
||||
description: "Update OpenClaw and inspect update channel status",
|
||||
hasSubcommands: true,
|
||||
register: async (program) => {
|
||||
const mod = await import("../update-cli.js");
|
||||
mod.registerUpdateCli(program);
|
||||
@@ -250,6 +280,7 @@ const entries: SubCliEntry[] = [
|
||||
{
|
||||
name: "completion",
|
||||
description: "Generate shell completion script",
|
||||
hasSubcommands: false,
|
||||
register: async (program) => {
|
||||
const mod = await import("../completion-cli.js");
|
||||
mod.registerCompletionCli(program);
|
||||
@@ -261,6 +292,10 @@ export function getSubCliEntries(): SubCliEntry[] {
|
||||
return entries;
|
||||
}
|
||||
|
||||
export function getSubCliCommandsWithSubcommands(): string[] {
|
||||
return entries.filter((entry) => entry.hasSubcommands).map((entry) => entry.name);
|
||||
}
|
||||
|
||||
function removeCommand(program: Command, command: Command) {
|
||||
const commands = program.commands as Command[];
|
||||
const index = commands.indexOf(command);
|
||||
|
||||
Reference in New Issue
Block a user