1use 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 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}