CLI command implementation package extracted from __main__.py.
cli_commands/lifecycle.py:start_bot,stop_bot,cmd_restart,upgrade,uninstall,_re_exec_botcli_commands/status.py:print_status,print_usagecli_commands/service.py:ductor service ...cli_commands/docker.py:ductor docker ...cli_commands/api_cmd.py:ductor api ...cli_commands/agents.py:ductor agents ...cli_commands/install.py:ductor install <extra>
ductor_bot/__main__.py is now a thin entrypoint:
- argument parsing + command dispatch
- config helpers (
_is_configured,load_config,run_bot) - imports/re-exports command handlers from
cli_commands/*
This keeps lifecycle logic testable and prevents command monolith growth.
- lifecycle:
ductor,stop,restart,upgrade,uninstall, onboarding/reset flow - status/help:
ductor status,ductor help - service: install/status/start/stop/logs/uninstall wrapper for platform backends
- docker: enable/disable/rebuild/mount/unmount/mounts/extras/extras-add/extras-remove
- api: enable/disable direct WebSocket API block in config
- agents: list/add/remove sub-agent entries in
agents.json - install extras:
ductor install <extra>for optional Python extras (matrix,api)
stop_bot()stops service first, then PID instance, then remaining ductor processes, then Docker container (if enabled).start_bot()callsload_config()and startsAgentSupervisorviarun_bot().ductor agents add <name>is an interactive Telegram-focused scaffold; Matrix sub-agents are configured viaagents.jsonor the bundled agent tool scripts.ductor restartalways runsstop_bot()and then re-execs the current process.- exit code
42is the in-app runtime/supervisor restart signal (/restart, service-managed restarts), not the behavior of the CLIductor restartcommand. status.pycurrently counts errors from latestductor*.log; runtime primary log file is~/.ductor/logs/agent.log.
When documenting CLI behavior, reference cli_commands/* for command internals.
Use __main__.py as the dispatch map, not as the implementation source.