mirror of
https://github.com/0xWheatyz/handler.git
synced 2026-08-30 08:26: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.
50 lines
1.2 KiB
TOML
50 lines
1.2 KiB
TOML
[build-system]
|
|
requires = ["hatchling"]
|
|
build-backend = "hatchling.build"
|
|
|
|
[project]
|
|
name = "handler"
|
|
version = "0.1.0"
|
|
description = "Remote control wrapper for Claude Code agents across isolated projects"
|
|
readme = "README.md"
|
|
requires-python = ">=3.11"
|
|
license = { text = "MIT" }
|
|
dependencies = [
|
|
"fastapi>=0.115,<0.116",
|
|
"uvicorn[standard]>=0.34,<0.35",
|
|
"sqlalchemy>=2.0,<2.1",
|
|
"alembic>=1.14,<1.15",
|
|
"psycopg[binary]>=3.2,<3.3",
|
|
"pydantic>=2.10,<3.0",
|
|
"pydantic-settings>=2.7,<3.0",
|
|
"httpx>=0.28,<0.29",
|
|
]
|
|
|
|
[project.optional-dependencies]
|
|
dev = [
|
|
"pytest>=8.3,<9.0",
|
|
"respx>=0.22,<0.23",
|
|
"ruff>=0.9,<0.10",
|
|
]
|
|
|
|
[project.scripts]
|
|
handler = "handler.control.cli:main"
|
|
|
|
[tool.hatch.build.targets.wheel]
|
|
# The bundled web UI (src/handler/api/static/*) ships automatically: it lives inside the
|
|
# packaged `src/handler` tree, and hatchling includes non-.py files there by default.
|
|
packages = ["src/handler"]
|
|
|
|
[tool.pytest.ini_options]
|
|
testpaths = ["tests"]
|
|
pythonpath = ["src"]
|
|
|
|
[tool.ruff]
|
|
src = ["src", "tests"]
|
|
line-length = 100
|
|
|
|
[tool.ruff.lint]
|
|
select = ["E", "F", "I", "W", "UP", "B"]
|
|
# B008: FastAPI's Depends()/Query() in argument defaults is the framework's idiom.
|
|
ignore = ["B008"]
|