Replaces the separate Vue/Vite `console/` SPA with a same-origin, server-rendered console built on a module-level Jinja2 Environment with select_autoescape(["html","xml"]). - Add api/console_web.py with /ui/ routes (dashboard, tasks, task detail/timeline, config) and a _status_fragment polled every 10s. - Refactor api/console.py into a typed ConsoleService shared by the JSON and HTML routers so validation/persistence cannot drift. - Remove RUNTIME_CONSOLE_STATIC_DIR, SpaStaticFiles, and the wildcard CORS middleware from api/rest.py; GET / now redirects to /ui/. - Delete the top-level console/ project; add jinja2 and python-multipart as direct dependencies and ship templates/CSS/JS via package-data. - Add 31 tests (XSS probes, PRG flows, fragment refresh, no-static-dir and no-CORS regressions, wheel-packaging smoke test). /console/* JSON endpoints remain unchanged. The console keeps the trusted-network-only boundary; auth/CSRF is intentionally deferred. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2.9 KiB
2.9 KiB
Why
The local Runtime console is currently a separately built Vue/Vite SPA. It requires a Node toolchain for development and an optional static-directory configuration for same-process serving, even though its data and mutations already live in the Runtime FastAPI process. Rendering the console with Jinja2 will make the operator surface deploy with the Runtime itself while preserving the existing REST contract for programmatic clients.
What Changes
- Add a same-origin, server-rendered Runtime console under
/ui/, with Jinja2 pages for device status, task browsing/detail/timeline replay, device registration/removal, and runtime configuration. - Keep the existing
/console/*JSON endpoints and make page handlers and JSON handlers share API-layer console operations so their observable registration, deletion, filtering, and configuration semantics cannot drift. - Package console templates and static assets with
device-agent-runtime, add direct Jinja2 and HTML form-parsing dependencies, and render every HTML page through one autoescaping template environment. - Replace the Vue/Vite
console/project,RUNTIME_CONSOLE_STATIC_DIR, and SPA fallback static mount with Runtime-owned templates and normal static assets. Remove the permissive CORS configuration that existed only for cross-origin Vite development. - BREAKING: the independent
console/npm workflow andRUNTIME_CONSOLE_STATIC_DIRdeployment mode are removed. Operators will start the Runtime API normally and open/ui/; JSON API paths remain unchanged.
Capabilities
New Capabilities
runtime-console-template-rendering: Same-origin Jinja2-rendered Runtime console pages, automatic HTML escaping, form-based mutations, and packaged Runtime-owned web assets.
Modified Capabilities
- None. The existing canonical specs do not define the pending
web-consoleSPA, and the/console/*JSON API contract remains unchanged.
Impact
- Affected code:
api/rest.py,api/console.py, a new API-layer page router, Runtime template/static asset directories, rootpyproject.toml, and console-focused tests. - Removed code/assets: top-level
console/Vue/Vite sources, Node lockfile, Vite environment configuration, and SPA deployment wiring. - Documentation: Runtime startup and console guidance in
README.md,docs/CONSTITUTION.md, anddocs/MACOS_IPHONE_SETUP.mdchange to describe the built-in/ui/console. - Security boundary: this change preserves the existing trusted-network, unauthenticated Runtime console assumption. It does not add authentication, authorization, or session/CSRF protection; non-trusted exposure needs a separate security change.
- Architecture: all new HTTP, HTML, and template concerns remain in the outer
apilayer. Nocore,driver,device,tools,perception, orruntimepackage gains web-framework dependencies.