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>
4.8 KiB
4.8 KiB
1. Runtime package and web-resource setup
- 1.1 Add direct
jinja2>=3.1andpython-multipartRuntime dependencies, configure setuptools package-data for Runtime console templates/CSS/JavaScript, regenerateuv.lock, and verifyuv lock --check. - 1.2 Create the Runtime-owned template and static-asset layout under
api/for the/ui/console, with names suitable for wheel packaging and standard static-file serving. - 1.3 Add a package-resource smoke test that builds and installs
device-agent-runtimeoutside the source checkout and confirms/ui/can find its templates and assets.
2. Shared API-layer console operations
- 2.1 Refactor
api/console.pyto expose an API-local typed console service for device, task, timeline, and runtime-config reads and mutations, preserving current validation and error semantics. - 2.2 Rewire
create_console_router()to use the shared service and retain every existing/console/*method, JSON response shape, status code, filtering rule, and persistence behavior. - 2.3 Update
api/rest.pyto construct one shared service from its existing injected Runtime state and pass it to both JSON and HTML console routers without changing lower-layer dependencies.
3. Jinja2 Runtime console routes and pages
- 3.1 Implement
api/console_web.pywith one module-level Jinja2Environment,FileSystemLoader,select_autoescape(["html", "xml"]), and a smallHTMLResponserender helper. - 3.2 Mount same-origin
/ui/page routes and/ui/assetsstatic resources; makeGET /redirect to/ui/unconditionally. - 3.3 Implement the shared base layout, dashboard, and Jinja-rendered live-status fragment, including the small polling enhancement that replaces only the live region.
- 3.4 Implement server-rendered task list/filter and task-detail/timeline pages, including ordered records, safe structured tool/result output, and available screenshot data URIs.
- 3.5 Implement the configuration page and POST/Redirect/GET device registration/removal and
max_stepsupdate handlers, with readable400HTML validation errors that retain submitted safe values and perform no partial mutation. - 3.6 Port the existing console visual layout to package-owned CSS and the narrow polling script without adding a JavaScript framework or a frontend build step.
4. Retire SPA deployment wiring and update documentation
- 4.1 Remove
RUNTIME_CONSOLE_STATIC_DIR,SpaStaticFiles, the SPA fallback, and the wildcard CORS middleware used only for Vite development fromapi/rest.py. - 4.2 Delete the top-level
console/Vue/Vite project and remove its obsolete environment, npm, and ignore-file references while leavingcloud-console/untouched. - 4.3 Update
README.md,docs/CONSTITUTION.md, anddocs/MACOS_IPHONE_SETUP.mdto document normal Runtime startup followed by/ui/, the breaking removal of the npm/static-directory workflow, and the trusted-network-only security boundary. - 4.4 Remove stale Docker ignore/configuration entries that only described the deleted Runtime SPA, without changing Cloud Console build or deployment behavior.
5. Automated verification
- 5.1 Keep and extend console JSON API tests to prove
/console/*compatibility before and after page-route mutations. - 5.2 Add template tests covering every Runtime console template, module-level autoescape configuration, XSS probes in device/task/timeline/configuration values, safe structured JSON output, and absence of unintended
|safebypasses. - 5.3 Add FastAPI
TestClientcoverage for root redirect, page navigation, empty/populated dashboard state, task filters/detail/timeline, dashboard fragment refresh, static assets, form PRG success paths, and invalid-form no-mutation paths. - 5.4 Add regression coverage that same-origin
/ui/works withoutRUNTIME_CONSOLE_STATIC_DIRand does not depend on the removed wildcard CORS middleware.
6. Validation and migration handoff
- 6.1 Run targeted formatting, lint, compile, and Runtime console tests, then run the repository non-integration test suite; record any pre-existing failures separately from this change.
- 6.2 Build the Runtime wheel and run the isolated package-resource smoke test after the final dependency lock update.
- 6.3 Run
openspec validate runtime-console-jinja2-templates --strictand resolve all validation failures. - 6.4 Perform a browser walkthrough of dashboard live refresh, task filtering/timeline replay, valid and invalid device configuration, device removal, and
max_stepsupdate using a real Runtime process. - 6.5 After human browser verification, reconcile the remaining manual verification and superseded SPA decision in the pending
web-consolechange before any archive decision; do not mark it complete from automated evidence alone.