Phase 21: container terminal (web exec), local + agent (0.27.0)

Interactive shell into a compose-managed container over WebSocket + xterm.js,
opened from the container card on the stack Overview tab. Admin-only (non-admin
handshake rejected with 4403); only containers with the compose project label
are reachable.

- backend services/exec_service.py: create/start/resize exec + a shared
  bidirectional pump_exec (recv/sendall on sock._sock, executor thread,
  resize control frames, exit-code frame).
- routers/ws.py: _authorize_admin + /ws/exec/{container_id} and the
  /ws/agent-exec/{agent_id}/{container_id} proxy (forwards BOTH directions).
- agent_app.py: /agent/ws/exec/{container_id}.
- frontend: @xterm/xterm + @xterm/addon-fit; ContainerTerminal modal (shell
  picker, fit/resize, exit/error handling) + a Terminal button on ContainerCard.

Live-verified (TestClient): local happy/exit/guard/4403/4401, agent happy/4401,
proxy bidirectional round-trip.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
menzelj
2026-06-09 12:53:21 +00:00
co-authored by Claude Opus 4.8
parent b44a5b9f86
commit be3568274f
10 changed files with 3014 additions and 6 deletions
+1 -1
View File
@@ -56,7 +56,7 @@ async def lifespan(app: FastAPI):
schedule_task.cancel()
app = FastAPI(title="StackPilot", version="0.26.0", lifespan=lifespan)
app = FastAPI(title="StackPilot", version="0.27.0", lifespan=lifespan)
app.add_middleware(
CORSMiddleware,