diff --git a/packages/coding-agent/package.json b/packages/coding-agent/package.json index 85f81bcd3..9cfc6c40b 100644 --- a/packages/coding-agent/package.json +++ b/packages/coding-agent/package.json @@ -13,6 +13,7 @@ "oclif": { "bin": "omp", "commands": "./src/commands", + "helpClass": "./src/cli/oclif-help.ts", "plugins": [ "@oclif/plugin-autocomplete" ] diff --git a/packages/coding-agent/src/cli.ts b/packages/coding-agent/src/cli.ts index d631dbd14..8cb618949 100755 --- a/packages/coding-agent/src/cli.ts +++ b/packages/coding-agent/src/cli.ts @@ -12,7 +12,7 @@ process.title = APP_NAME; const argv = process.argv.slice(2); const runArgv = argv.length === 0 ? ["index"] : argv; run(runArgv, import.meta.url).catch((error: unknown) => { - const message = error instanceof Error ? error.stack ?? error.message : String(error); + const message = error instanceof Error ? (error.stack ?? error.message) : String(error); process.stderr.write(`${message}\n`); process.exit(1); }); diff --git a/packages/coding-agent/src/cli/args.ts b/packages/coding-agent/src/cli/args.ts index 58e201027..7ec4fa50c 100644 --- a/packages/coding-agent/src/cli/args.ts +++ b/packages/coding-agent/src/cli/args.ts @@ -180,100 +180,8 @@ export function parseArgs(args: string[], extensionFlags?: Map Model to use (fuzzy match: "opus", "gpt-5.2", or "p-openai/gpt-5.2") - --smol Smol/fast model for lightweight tasks (or PI_SMOL_MODEL env) - --slow Slow/reasoning model for thorough analysis (or PI_SLOW_MODEL env) - --plan Plan model for architectural planning (or PI_PLAN_MODEL env) - --api-key API key (defaults to env vars) - --system-prompt System prompt (default: coding assistant prompt) - --append-system-prompt Append text or file contents to the system prompt - --allow-home Allow starting in ~ without auto-switching to a temp dir - --mode Output mode: text (default), json, or rpc - --print, -p Non-interactive mode: process prompt and exit - --continue, -c Continue previous session - --resume, -r Select a session to resume - --session Use specific session file - --session-dir Directory for session storage and lookup - --no-session Don't save session (ephemeral) - --models Comma-separated model patterns for Ctrl+P cycling - Supports globs (anthropic/*, *sonnet*) and fuzzy matching - --no-tools Disable all built-in tools - --no-lsp Disable LSP tools, formatting, and diagnostics - --tools Comma-separated list of tools to enable (default: all) - Available: read, bash, edit, write, grep, find, lsp, - python, notebook, task, fetch, web_search, browser, ask - --thinking Set thinking level: off, minimal, low, medium, high, xhigh - --hook Load a hook/extension file (can be used multiple times) - --extension, -e Load an extension file (can be used multiple times) - --no-extensions Disable extension discovery (explicit -e paths still work) - --no-skills Disable skills discovery and loading - --skills Comma-separated glob patterns to filter skills (e.g., git-*,docker) - --export Export session file to HTML and exit - --list-models [search] List available models (with optional fuzzy search) - --help, -h Show this help - --version, -v Show version number - -${chalk.bold("Examples:")} - # Interactive mode - ${APP_NAME} - - # Interactive mode with initial prompt - ${APP_NAME} "List all .ts files in src/" - - # Include files in initial message - ${APP_NAME} @prompt.md @image.png "What color is the sky?" - - # Non-interactive mode (process and exit) - ${APP_NAME} -p "List all .ts files in src/" - - # Multiple messages (interactive) - ${APP_NAME} "Read package.json" "What dependencies do we have?" - - # Continue previous session - ${APP_NAME} --continue "What did we discuss?" - - # Use different model (fuzzy matching) - ${APP_NAME} --model opus "Help me refactor this code" - - # Limit model cycling to specific models - ${APP_NAME} --models claude-sonnet,claude-haiku,gpt-4o - - # Limit to a specific provider with glob pattern - ${APP_NAME} --models "github-copilot/*" - - # Cycle models with fixed thinking levels - ${APP_NAME} --models sonnet:high,haiku:low - - # Start with a specific thinking level - ${APP_NAME} --thinking high "Solve this complex problem" - - # Read-only mode (no file modifications possible) - ${APP_NAME} --tools read,grep,find -p "Review the code in src/" - - # Export a session file to HTML - ${APP_NAME} --export ~/${CONFIG_DIR_NAME}/agent/sessions/--path--/session.jsonl - ${APP_NAME} --export session.jsonl output.html - -${chalk.bold("Environment Variables:")} +export function getExtraHelpText(): string { + return `${chalk.bold("Environment Variables:")} ${chalk.dim("# Core Providers")} ANTHROPIC_API_KEY - Anthropic Claude models ANTHROPIC_OAUTH_TOKEN - Anthropic OAuth (takes precedence over API key) @@ -328,5 +236,13 @@ ${chalk.bold("Available Tools (all enabled by default):")} fetch - Fetch and process URLs web_search - Search the web ask - Ask user questions (interactive mode only) -`); +`; +} + +export function printHelp(): void { + process.stdout.write( + `${chalk.bold(APP_NAME)} - AI coding assistant\n\n` + + `Run ${APP_NAME} --help for full command and option details.\n\n` + + `${getExtraHelpText()}\n`, + ); } diff --git a/packages/coding-agent/src/cli/oclif-help.ts b/packages/coding-agent/src/cli/oclif-help.ts new file mode 100644 index 000000000..da7487dfa --- /dev/null +++ b/packages/coding-agent/src/cli/oclif-help.ts @@ -0,0 +1,26 @@ +/** + * Custom help renderer for the coding agent CLI. + */ +import { CommandHelp, Help } from "@oclif/core"; +import { getExtraHelpText } from "./args"; + +export default class OclifHelp extends Help { + protected async showRootHelp(): Promise { + await super.showRootHelp(); + const rootCommand = this.config.findCommand("index"); + if (rootCommand) { + const rootHelp = new CommandHelp(rootCommand, this.config, { + ...this.opts, + sections: ["arguments", "flags", "examples"], + }); + const output = rootHelp.generate(); + if (output.trim().length > 0) { + process.stdout.write(`\n${output}\n`); + } + } + const extra = getExtraHelpText(); + if (extra.trim().length > 0) { + process.stdout.write(`\n${extra}\n`); + } + } +}