diff --git a/bot_bottle/cli/__init__.py b/bot_bottle/cli/__init__.py index b26642a..6a1ea3b 100644 --- a/bot_bottle/cli/__init__.py +++ b/bot_bottle/cli/__init__.py @@ -1,6 +1,7 @@ """Main CLI dispatcher. -Commands: backend, cleanup, commit, edit, info, init, list, resume, start, supervise +Commands: backend, cleanup, commit, edit, help, info, init, list, login, +resume, start, supervise """ from __future__ import annotations @@ -17,6 +18,7 @@ from .commands.backend import cmd_backend from .commands.cleanup import cmd_cleanup from .commands.commit import cmd_commit from .commands.edit import cmd_edit +from .commands.help import cmd_help from .commands.info import cmd_info from .commands.init import cmd_init from .commands.login import cmd_login @@ -31,6 +33,7 @@ COMMANDS = { "cleanup": cmd_cleanup, "commit": cmd_commit, "edit": cmd_edit, + "help": cmd_help, "info": cmd_info, "init": cmd_init, "list": cmd_list, @@ -45,49 +48,23 @@ COMMANDS = { # the host (TAP pool, /dev/kvm, firecracker) and never opens the store, so # gating it on the schema breaks preflight on a fresh CI runner where stdin # isn't a TTY and the migration prompt can't be answered. -NO_MIGRATION_COMMANDS = frozenset({"backend", "login"}) - - -def usage() -> None: - sys.stderr.write(f"usage: {PROG} [args...]\n\n") - sys.stderr.write("Commands:\n") - sys.stderr.write(" backend set up / check / undo a backend's host prerequisites (setup|status|teardown)\n") - sys.stderr.write(" cleanup stop and remove all active bot-bottle containers\n") - sys.stderr.write(" commit snapshot a running bottle's container state to a Docker image\n") - sys.stderr.write(" edit open an agent in vim for editing\n") - sys.stderr.write(" info print env, skills, and prompt details for a named agent\n") - sys.stderr.write(" init interactively create a new agent and add it to bot-bottle.json\n") - sys.stderr.write(" list list available agents or active containers\n") - sys.stderr.write(" login register this host with a bot-bottle console\n") - sys.stderr.write( - " resume re-launch a bottle by its identity " - "(continues state from PRD 0016)\n" - ) - sys.stderr.write( - " start boot a container for a named agent and " - "attach an interactive session\n" - ) - sys.stderr.write( - " supervise view + approve/modify/reject pending supervise " - "proposals (PRD 0013)\n\n" - ) - sys.stderr.write(f"Run '{PROG} --help' for command-specific usage.\n") +NO_MIGRATION_COMMANDS = frozenset({"backend", "help", "login"}) def main(argv: list[str] | None = None) -> int: if argv is None: argv = sys.argv[1:] if not argv: - usage() + cmd_help() return 2 command = argv[0] rest = argv[1:] if command in ("-h", "--help"): - usage() + cmd_help() return 0 handler = COMMANDS.get(command) if handler is None: - usage() + cmd_help() die(f"unknown command: {command}") mgr = StoreManager.instance() if command not in NO_MIGRATION_COMMANDS and not mgr.is_migrated(): diff --git a/bot_bottle/cli/commands/help.py b/bot_bottle/cli/commands/help.py new file mode 100644 index 0000000..d7ee633 --- /dev/null +++ b/bot_bottle/cli/commands/help.py @@ -0,0 +1,37 @@ +"""help: print the top-level command list and usage. + +Rendered by the dispatcher for the `help` command and for its +`-h`/`--help`, no-args, and unknown-command fallbacks. The per-command +summaries live here; keep them in sync with the COMMANDS table in +`bot_bottle.cli`. +""" + +from __future__ import annotations + +import sys + +from ..constants import PROG + + +def cmd_help(argv: list[str] | None = None) -> int: + """Write the top-level usage + command list to stderr. Returns 0; + the dispatcher chooses the process exit code per entry path (0 for an + explicit `help`/`-h`, 2 for the bare no-args usage error).""" + del argv # help takes no arguments + w = sys.stderr.write + w(f"usage: {PROG} [args...]\n\n") + w("Commands:\n") + w(" backend set up / check / undo a backend's host prerequisites (setup|status|teardown)\n") + w(" cleanup stop and remove all active bot-bottle containers\n") + w(" commit snapshot a running bottle's container state to a Docker image\n") + w(" edit open an agent in vim for editing\n") + w(" help show this command list\n") + w(" info print env, skills, and prompt details for a named agent\n") + w(" init interactively create a new agent and add it to bot-bottle.json\n") + w(" list list available agents or active containers\n") + w(" login register this host with a bot-bottle console\n") + w(" resume re-launch a bottle by its identity (continues state from PRD 0016)\n") + w(" start boot a container for a named agent and attach an interactive session\n") + w(" supervise view + approve/modify/reject pending supervise proposals (PRD 0013)\n\n") + w(f"Run '{PROG} --help' for command-specific usage.\n") + return 0