# SPDX-FileCopyrightText: 2026 James Harton # # SPDX-License-Identifier: Apache-2.0 defmodule BB.MCP.Resources.RobotCommands do @moduledoc """ Declared commands on a robot, with typed argument schemas. Read via `bb://robots/{robot}/commands`. The same data is available via the `list_commands` tool — this resource exists so agents can load the command catalogue as context before invoking anything. """ use Anubis.Server.Component, type: :resource, uri_template: "bb://robots/{robot}/commands", name: "robot_commands" alias Anubis.Server.Response alias BB.Dsl.Info alias BB.MCP.JsonSchema alias BB.MCP.Resources @impl true def description, do: "Commands declared in the robot's Spark DSL" @impl true def mime_type, do: "application/json" @impl true def read(params, frame) do case Resources.fetch_robot(params) do {:ok, module} -> commands = module |> Info.commands() |> Enum.map(fn cmd -> %{ "name" => Atom.to_string(cmd.name), "category" => to_string(cmd.category || ""), "allowed_states" => Enum.map(cmd.allowed_states, &Atom.to_string/1), "timeout" => format_timeout(cmd.timeout), "arguments" => JsonSchema.for_command(cmd) } end) {:reply, Response.json(Response.resource(), %{"commands" => commands}), frame} {:error, error} -> {:error, error, frame} end end defp format_timeout(:infinity), do: "infinity" defp format_timeout(timeout) when is_integer(timeout), do: timeout end