From 36d2d6073c1a19b13b79a3c879c7c8786f088ee0 Mon Sep 17 00:00:00 2001 From: payneio Date: Mon, 27 Apr 2026 20:58:51 -0700 Subject: [PATCH] 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'. --- castle-api/src/castle_api/main.py | 3 ++- castle-api/src/castle_api/tools.py | 18 ++++++++++++------ 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/castle-api/src/castle_api/main.py b/castle-api/src/castle_api/main.py index 69a6c22..7521d1d 100644 --- a/castle-api/src/castle_api/main.py +++ b/castle-api/src/castle_api/main.py @@ -25,7 +25,7 @@ from castle_api.stream import ( unsubscribe, ) 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__) @@ -121,6 +121,7 @@ app.include_router(nodes_router) app.include_router(secrets_router) app.include_router(services_router) app.include_router(tools_router) +app.include_router(programs_router) @app.get("/health") diff --git a/castle-api/src/castle_api/tools.py b/castle-api/src/castle_api/tools.py index 68f720e..37dfc0f 100644 --- a/castle-api/src/castle_api/tools.py +++ b/castle-api/src/castle_api/tools.py @@ -14,6 +14,7 @@ from castle_api.config import get_config from castle_api.models import ToolDetail, ToolSummary router = APIRouter(tags=["tools"]) +programs_router = APIRouter(tags=["programs"]) 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)} 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, ) @@ -89,10 +87,18 @@ def get_tool(name: str) -> ToolDetail: # 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: """Run a lifecycle action on a program via its stack handler.""" if action not in _VALID_ACTIONS: