Skip to main content

boost/tools/
commands.rs

1//! `list-available-commands` — wraps `anvil --help`.
2
3use async_trait::async_trait;
4use serde_json::{json, Value};
5
6use crate::protocol::CallToolResult;
7use crate::tool::{Context, Tool};
8
9pub struct ListAvailableCommands;
10
11#[async_trait]
12impl Tool for ListAvailableCommands {
13    fn name(&self) -> &'static str {
14        "list-available-commands"
15    }
16    fn description(&self) -> &'static str {
17        "List every CLI subcommand exposed by `anvil` (the Anvilforge Artisan equivalent). Useful for agents that need to invoke `anvil <verb>` shell commands."
18    }
19
20    async fn call(&self, _ctx: &Context, _args: Value) -> CallToolResult {
21        // We embed a static list rather than shelling to `anvil --help` so the
22        // tool works even if the user is debugging the CLI itself.
23        let commands = [
24            ("new", "Scaffold a new Anvil project"),
25            ("serve", "Run the development server"),
26            (
27                "dev",
28                "`serve --watch` shorthand (auto-reload on file changes)",
29            ),
30            ("routes", "List every route registered by the app"),
31            ("migrate", "Run pending database migrations"),
32            ("migrate:rollback", "Roll back the last batch of migrations"),
33            (
34                "migrate:fresh",
35                "Drop the whole schema and re-run all migrations",
36            ),
37            ("migrate:status", "Show which migrations have been applied"),
38            ("db:seed", "Run database seeders"),
39            ("db:wipe", "Wipe all tables in the default database"),
40            ("queue:work", "Run the queue worker"),
41            ("schedule:run", "Run a single scheduler tick"),
42            ("test", "Run the test suite"),
43            ("repl", "Open a REPL with the app context loaded"),
44            ("make:model", "Generate a model + optional migration"),
45            ("make:migration", "Generate a migration"),
46            (
47                "make:controller",
48                "Generate a controller (optionally resource-style)",
49            ),
50            ("make:request", "Generate a form-request validator"),
51            ("make:job", "Generate a queued job"),
52            ("make:event", "Generate an event payload"),
53            ("make:listener", "Generate an event listener"),
54            ("make:test", "Generate an integration test skeleton"),
55            ("make:seeder", "Generate a database seeder"),
56            ("make:factory", "Generate a model factory"),
57            ("make:component", "Generate a Spark reactive component"),
58            ("make:auth", "Scaffold login/register/logout"),
59            ("fmt", "cargo fmt --all"),
60            ("lint", "cargo clippy --workspace --all-targets"),
61            ("install", "Install this CLI to ~/.cargo/bin/anvil"),
62            ("bench", "Run the HTTP load test"),
63            ("bench:micro", "Run criterion microbenchmarks"),
64            ("bench:full", "bench:micro then bench"),
65            ("mcp", "Start the Boost MCP server (this server)"),
66            ("boost:install", "Generate AGENTS.md + editor MCP config"),
67        ];
68        let mut out = Vec::with_capacity(commands.len());
69        for (name, desc) in commands {
70            out.push(json!({ "name": name, "description": desc }));
71        }
72        CallToolResult::json(&json!({
73            "count": out.len(),
74            "commands": out,
75        }))
76    }
77}