| 1 | # Commands Plugin DOX |
| 2 | |
| 3 | ## Purpose |
| 4 | |
| 5 | - Own the built-in slash command manager and chat composer slash/reference picker. |
| 6 | - Keep file-backed `/command` discovery consistent across project, global, and plugin-provided scopes. |
| 7 | |
| 8 | ## Ownership |
| 9 | |
| 10 | - `plugin.yaml` owns the built-in `_commands` plugin metadata. |
| 11 | - `helpers/commands.py` owns command name sanitization, argument parsing, scope resolution, file persistence, plugin command discovery, and command invocation resolution. |
| 12 | - `api/commands.py` owns the Commands API actions used by the WebUI. |
| 13 | - `webui/` owns the manager/editor modal stores, HTML surfaces, and thumbnail asset. |
| 14 | - `commands/` owns bundled read-only slash command definitions shipped by `_commands`, including `/stop` agent-run control. |
| 15 | - `extensions/` owns the chat composer slash and `@` reference picker plus incoming-message command resolution. |
| 16 | - `extensions/python/startup_migration/` owns one-time migration from the legacy community `commands` plugin namespace. |
| 17 | - `skills/commands-create-slash-command/` owns the agent-facing authoring workflow for reusable slash commands. |
| 18 | - `tests/` owns regression coverage for parsing, CRUD, scope precedence, plugin-distributed commands, legacy migration, and skill discovery. |
| 19 | |
| 20 | ## Local Contracts |
| 21 | |
| 22 | - The plugin identity is `_commands`; user-created command files live under `usr/plugins/_commands/commands/` or `usr/projects/<project>/.a0proj/plugins/_commands/commands/`. |
| 23 | - Each command is one `.command.yaml` config plus one same-directory `.txt` text template or `.py` script hook. |
| 24 | - Project commands override global commands, global commands override bundled `_commands/commands/` defaults, and bundled defaults override other plugin-distributed commands with the same name. |
| 25 | - Bundled `_commands/commands/` definitions and commands contributed by other plugins are read-only from this manager. |
| 26 | - The manager lists bundled commands separately; editing one copies it unchanged into the selected project or global scope under the same name, then edits that higher-precedence override. |
| 27 | - Bundled command files use canonical command names only; do not ship alias-only built-ins such as `/img` for `/attach`. |
| 28 | - Command configs may set `webui_hidden: true` to stay resolvable but be omitted from the chat composer picker. |
| 29 | - Commands contributed by enabled plugins live in their `commands/` directory and must not be rediscovered through the generic plugin-distributed path from `_commands` itself. |
| 30 | - On startup, `_commands` copies legacy `usr/plugins/commands` command and skill files into `usr/plugins/_commands` without overwriting existing files, copies scoped legacy command folders to `_commands`, and disables the legacy `commands` plugin roots to prevent duplicate WebUI popovers. |
| 31 | - Script commands must expose `run(payload)` and return a string or a dict with `text` and optional `effects`; `show_markdown` effects render as auto-dismissing toast notifications. |
| 32 | - Script commands may emit `send_message` with `text` to submit the rendered composer text immediately after command resolution. |
| 33 | - Commands accept prefix syntax (`/goal objective`) and exact postfix syntax (`objective /goal`); ordinary mid-sentence mentions are not invocations. The composer picker opens only for prefix syntax, while postfix commands resolve when sent. |
| 34 | - Composer `@` selections insert plain references only: `@[./path]`, `@[./folder/]`, `@[agent/profile]`, `@[skill/name]`, or `@[mcp/server]`. They never load content, activate skills, call MCP, or delegate by themselves. |
| 35 | - Selected reference icons may use the composer highlight color while their labels keep the normal text color; serialized prompt text remains unchanged. |
| 36 | - File and folder references stay inside the active chat workdir and list one directory at a time through the existing file-browser and chat-path APIs. Profile and effective MCP server references reuse their scoped catalogs; skill references use only entries visible in the active chat scope. |
| 37 | - WebUI sends resolve through the picker effect path, while backend-originated messages resolve before reaching the agent. |
| 38 | - `/stop` uses the same shared cancellation operation as the composer Stop button, including progress cleanup and terminal logging. |
| 39 | - `/profile` opens Manage agents without arguments, keeps existing profile |
| 40 | selection, and creates through Agent Editor when given a name and instructions. |
| 41 | - `/permissions` opens Edit agent for the current WebUI profile; the A0 Connector |
| 42 | owns its separate Textual permissions screen for the same command name. |
| 43 | - Built-in `/computer-use on|off` emits a bounded `computer_use` effect. WebUI |
| 44 | only directs the user to Host access in A0 Launcher or the same command in A0 |
| 45 | CLI; it never changes a Launcher gateway lease from Agent Zero page content. |
| 46 | |
| 47 | ## Work Guidance |
| 48 | |
| 49 | - Keep the command storage and route namespace aligned with `_commands`. |
| 50 | - Preserve unknown command config keys when editing commands. |
| 51 | - Keep built-in source files immutable; user edits must be same-name scope overrides. |
| 52 | - Keep WebUI paths pointed at `/plugins/_commands/...`. |
| 53 | |
| 54 | ## Verification |
| 55 | |
| 56 | - Run `conda run -n a0 pytest plugins/_commands/tests` after backend or command contract changes. |
| 57 | |
| 58 | ## Child DOX Index |
| 59 | |
| 60 | No child DOX files. |