refactor: Move program endpoints to separate programs router

Relocates the POST /programs/{name}/{action} endpoint from the tools
router to a new programs_router for better API documentation
organization. Program lifecycle actions (build, test, lint, etc.) now
appear under 'programs' in the API docs instead of 'tools'.
This commit is contained in:
2026-04-27 20:58:51 -07:00
parent 22122b86f4
commit 36d2d6073c
2 changed files with 14 additions and 7 deletions

View File

@@ -25,7 +25,7 @@ from castle_api.stream import (
unsubscribe, unsubscribe,
) )
from castle_api.nodes import router as nodes_router from castle_api.nodes import router as nodes_router
from castle_api.tools import router as tools_router from castle_api.tools import programs_router, router as tools_router
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -121,6 +121,7 @@ app.include_router(nodes_router)
app.include_router(secrets_router) app.include_router(secrets_router)
app.include_router(services_router) app.include_router(services_router)
app.include_router(tools_router) app.include_router(tools_router)
app.include_router(programs_router)
@app.get("/health") @app.get("/health")

View File

@@ -14,6 +14,7 @@ from castle_api.config import get_config
from castle_api.models import ToolDetail, ToolSummary from castle_api.models import ToolDetail, ToolSummary
router = APIRouter(tags=["tools"]) router = APIRouter(tags=["tools"])
programs_router = APIRouter(tags=["programs"])
def _is_tool(comp: ProgramSpec) -> bool: def _is_tool(comp: ProgramSpec) -> bool:
@@ -55,10 +56,7 @@ def list_tools() -> list[ToolSummary]:
tools = {k: v for k, v in config.programs.items() if _is_tool(v)} tools = {k: v for k, v in config.programs.items() if _is_tool(v)}
return sorted( return sorted(
[ [_tool_summary(name, comp, config.root) for name, comp in tools.items()],
_tool_summary(name, comp, config.root)
for name, comp in tools.items()
],
key=lambda t: t.id, key=lambda t: t.id,
) )
@@ -89,10 +87,18 @@ def get_tool(name: str) -> ToolDetail:
# Unified program action endpoint # Unified program action endpoint
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
_VALID_ACTIONS = {"build", "test", "lint", "type-check", "check", "install", "uninstall"} _VALID_ACTIONS = {
"build",
"test",
"lint",
"type-check",
"check",
"install",
"uninstall",
}
@router.post("/programs/{name}/{action}") @programs_router.post("/programs/{name}/{action}")
async def program_action(name: str, action: str) -> dict: async def program_action(name: str, action: str) -> dict:
"""Run a lifecycle action on a program via its stack handler.""" """Run a lifecycle action on a program via its stack handler."""
if action not in _VALID_ACTIONS: if action not in _VALID_ACTIONS: