mirror of
https://github.com/0xWheatyz/handler.git
synced 2026-08-30 05:16:25 +00:00
bbb01d0882
Add a no-build, same-origin web frontend so an operator can open a URL, see every agent's state, and answer a paused question with no terminal (Phase 3 DoD). The UI is a client of the existing API — no endpoint, schema, or auth change — so the 106 existing tests pass unchanged. - app.py serves the bundled UI from / and /static, gated on UI_ENABLED (default on); optional CORS_ORIGINS (default empty => no middleware) for hosting the UI on a separate origin. Dedicated /static prefix + explicit / route so API routes are never shadowed. Zero new runtime deps (StaticFiles/CORSMiddleware ship with Starlette). - static/: vanilla fetch + plain CSS + vendored alpine.min.js (v3.14.8, no CDN). Token captured once into localStorage; all API values render via x-text (never x-html) to block agent-authored markup injection. Project switcher, agent list, checkmark panel, paginated log, shared feed, and Answer / Answer & Resume. Polling scoped to the selected agent to avoid an N+1 over the fleet. - config.py: ui_enabled, cors_origins (+ cors_origin_list); documented in .env.example. - tests/test_api_ui.py: serving, unauthenticated shell, non-shadowing 401 regression, CORS toggle, UI_ENABLED=false. 114 tests, ruff clean. The static assets ship in the wheel by default (they live inside the packaged src/handler tree) — no force-include needed.