mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-16 04:20:44 +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
@@ -15,8 +15,14 @@ export type CommandRegistration = {
|
||||
register: (params: CommandRegisterParams) => void;
|
||||
};
|
||||
|
||||
type CoreCliCommandDescriptor = {
|
||||
name: string;
|
||||
description: string;
|
||||
hasSubcommands: boolean;
|
||||
};
|
||||
|
||||
type CoreCliEntry = {
|
||||
commands: Array<{ name: string; description: string }>;
|
||||
commands: CoreCliCommandDescriptor[];
|
||||
register: (params: CommandRegisterParams) => Promise<void> | void;
|
||||
};
|
||||
|
||||
@@ -27,30 +33,59 @@ const shouldRegisterCorePrimaryOnly = (argv: string[]) => {
|
||||
return true;
|
||||
};
|
||||
|
||||
// Note for humans and agents:
|
||||
// If you update the list of commands, also check whether they have subcommands
|
||||
// and set the flag accordingly.
|
||||
const coreEntries: CoreCliEntry[] = [
|
||||
{
|
||||
commands: [{ name: "setup", description: "Setup helpers" }],
|
||||
commands: [
|
||||
{
|
||||
name: "setup",
|
||||
description: "Initialize local config and agent workspace",
|
||||
hasSubcommands: false,
|
||||
},
|
||||
],
|
||||
register: async ({ program }) => {
|
||||
const mod = await import("./register.setup.js");
|
||||
mod.registerSetupCommand(program);
|
||||
},
|
||||
},
|
||||
{
|
||||
commands: [{ name: "onboard", description: "Onboarding helpers" }],
|
||||
commands: [
|
||||
{
|
||||
name: "onboard",
|
||||
description: "Interactive onboarding wizard for gateway, workspace, and skills",
|
||||
hasSubcommands: false,
|
||||
},
|
||||
],
|
||||
register: async ({ program }) => {
|
||||
const mod = await import("./register.onboard.js");
|
||||
mod.registerOnboardCommand(program);
|
||||
},
|
||||
},
|
||||
{
|
||||
commands: [{ name: "configure", description: "Configure wizard" }],
|
||||
commands: [
|
||||
{
|
||||
name: "configure",
|
||||
description:
|
||||
"Interactive setup wizard for credentials, channels, gateway, and agent defaults",
|
||||
hasSubcommands: false,
|
||||
},
|
||||
],
|
||||
register: async ({ program }) => {
|
||||
const mod = await import("./register.configure.js");
|
||||
mod.registerConfigureCommand(program);
|
||||
},
|
||||
},
|
||||
{
|
||||
commands: [{ name: "config", description: "Config helpers" }],
|
||||
commands: [
|
||||
{
|
||||
name: "config",
|
||||
description:
|
||||
"Non-interactive config helpers (get/set/unset). Default: starts setup wizard.",
|
||||
hasSubcommands: true,
|
||||
},
|
||||
],
|
||||
register: async ({ program }) => {
|
||||
const mod = await import("../config-cli.js");
|
||||
mod.registerConfigCli(program);
|
||||
@@ -58,12 +93,25 @@ const coreEntries: CoreCliEntry[] = [
|
||||
},
|
||||
{
|
||||
commands: [
|
||||
{ name: "doctor", description: "Health checks + quick fixes for the gateway and channels" },
|
||||
{ name: "dashboard", description: "Open the Control UI with your current token" },
|
||||
{ name: "reset", description: "Reset local config/state (keeps the CLI installed)" },
|
||||
{
|
||||
name: "doctor",
|
||||
description: "Health checks + quick fixes for the gateway and channels",
|
||||
hasSubcommands: false,
|
||||
},
|
||||
{
|
||||
name: "dashboard",
|
||||
description: "Open the Control UI with your current token",
|
||||
hasSubcommands: false,
|
||||
},
|
||||
{
|
||||
name: "reset",
|
||||
description: "Reset local config/state (keeps the CLI installed)",
|
||||
hasSubcommands: false,
|
||||
},
|
||||
{
|
||||
name: "uninstall",
|
||||
description: "Uninstall the gateway service + local data (CLI remains)",
|
||||
hasSubcommands: false,
|
||||
},
|
||||
],
|
||||
register: async ({ program }) => {
|
||||
@@ -72,14 +120,26 @@ const coreEntries: CoreCliEntry[] = [
|
||||
},
|
||||
},
|
||||
{
|
||||
commands: [{ name: "message", description: "Send, read, and manage messages" }],
|
||||
commands: [
|
||||
{
|
||||
name: "message",
|
||||
description: "Send, read, and manage messages",
|
||||
hasSubcommands: true,
|
||||
},
|
||||
],
|
||||
register: async ({ program, ctx }) => {
|
||||
const mod = await import("./register.message.js");
|
||||
mod.registerMessageCommands(program, ctx);
|
||||
},
|
||||
},
|
||||
{
|
||||
commands: [{ name: "memory", description: "Memory commands" }],
|
||||
commands: [
|
||||
{
|
||||
name: "memory",
|
||||
description: "Search and reindex memory files",
|
||||
hasSubcommands: true,
|
||||
},
|
||||
],
|
||||
register: async ({ program }) => {
|
||||
const mod = await import("../memory-cli.js");
|
||||
mod.registerMemoryCli(program);
|
||||
@@ -87,19 +147,41 @@ const coreEntries: CoreCliEntry[] = [
|
||||
},
|
||||
{
|
||||
commands: [
|
||||
{ name: "agent", description: "Agent commands" },
|
||||
{ name: "agents", description: "Manage isolated agents" },
|
||||
{
|
||||
name: "agent",
|
||||
description: "Run one agent turn via the Gateway",
|
||||
hasSubcommands: false,
|
||||
},
|
||||
{
|
||||
name: "agents",
|
||||
description: "Manage isolated agents (workspaces, auth, routing)",
|
||||
hasSubcommands: true,
|
||||
},
|
||||
],
|
||||
register: async ({ program, ctx }) => {
|
||||
const mod = await import("./register.agent.js");
|
||||
mod.registerAgentCommands(program, { agentChannelOptions: ctx.agentChannelOptions });
|
||||
mod.registerAgentCommands(program, {
|
||||
agentChannelOptions: ctx.agentChannelOptions,
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
commands: [
|
||||
{ name: "status", description: "Gateway status" },
|
||||
{ name: "health", description: "Gateway health" },
|
||||
{ name: "sessions", description: "Session management" },
|
||||
{
|
||||
name: "status",
|
||||
description: "Show channel health and recent session recipients",
|
||||
hasSubcommands: false,
|
||||
},
|
||||
{
|
||||
name: "health",
|
||||
description: "Fetch health from the running gateway",
|
||||
hasSubcommands: false,
|
||||
},
|
||||
{
|
||||
name: "sessions",
|
||||
description: "List stored conversation sessions",
|
||||
hasSubcommands: false,
|
||||
},
|
||||
],
|
||||
register: async ({ program }) => {
|
||||
const mod = await import("./register.status-health-sessions.js");
|
||||
@@ -107,7 +189,13 @@ const coreEntries: CoreCliEntry[] = [
|
||||
},
|
||||
},
|
||||
{
|
||||
commands: [{ name: "browser", description: "Browser tools" }],
|
||||
commands: [
|
||||
{
|
||||
name: "browser",
|
||||
description: "Manage OpenClaw's dedicated browser (Chrome/Chromium)",
|
||||
hasSubcommands: true,
|
||||
},
|
||||
],
|
||||
register: async ({ program }) => {
|
||||
const mod = await import("../browser-cli.js");
|
||||
mod.registerBrowserCli(program);
|
||||
@@ -115,21 +203,32 @@ const coreEntries: CoreCliEntry[] = [
|
||||
},
|
||||
];
|
||||
|
||||
export function getCoreCliCommandNames(): string[] {
|
||||
function collectCoreCliCommandNames(predicate?: (command: CoreCliCommandDescriptor) => boolean) {
|
||||
const seen = new Set<string>();
|
||||
const names: string[] = [];
|
||||
for (const entry of coreEntries) {
|
||||
for (const cmd of entry.commands) {
|
||||
if (seen.has(cmd.name)) {
|
||||
for (const command of entry.commands) {
|
||||
if (predicate && !predicate(command)) {
|
||||
continue;
|
||||
}
|
||||
seen.add(cmd.name);
|
||||
names.push(cmd.name);
|
||||
if (seen.has(command.name)) {
|
||||
continue;
|
||||
}
|
||||
seen.add(command.name);
|
||||
names.push(command.name);
|
||||
}
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
export function getCoreCliCommandNames(): string[] {
|
||||
return collectCoreCliCommandNames();
|
||||
}
|
||||
|
||||
export function getCoreCliCommandsWithSubcommands(): string[] {
|
||||
return collectCoreCliCommandNames((command) => command.hasSubcommands);
|
||||
}
|
||||
|
||||
function removeCommand(program: Command, command: Command) {
|
||||
const commands = program.commands as Command[];
|
||||
const index = commands.indexOf(command);
|
||||
@@ -142,7 +241,7 @@ function registerLazyCoreCommand(
|
||||
program: Command,
|
||||
ctx: ProgramContext,
|
||||
entry: CoreCliEntry,
|
||||
command: { name: string; description: string },
|
||||
command: CoreCliCommandDescriptor,
|
||||
) {
|
||||
const placeholder = program.command(command.name).description(command.description);
|
||||
placeholder.allowUnknownOption(true);
|
||||
|
||||
Reference in New Issue
Block a user