Gateway Module — `dashboard/`
1. Purpose
The dashboard/ directory is a frontend artefact, not a code module — a set of static, hand-authored HTML pages plus CSS, fonts, and agent avatars that render the LisaOS operator dashboard (cache, memory, agents, context, jobs, compute, armoury, vault, analytics tabs). It contains zero TypeScript. Its data comes entirely from the gateway REST surface — primarily dashboard-api/ (see [dashboard-api](/docs/gateway/modules/dashboard-api)) plus direct authenticated fetches to /api/*. Its serving and the AK-415 read-token auth-shim injection live in server/index.ts, not here.
2. File Inventory
| File | Lines | Responsibility |
|---|---|---|
index.html | 1134 | Landing / overview tab |
agents.html | 1631 | Agent roster + health cards |
armoury.html | 943 | Skills armoury |
context.html | 855 | Context-assembly analytics |
cache.html | 768 | Psychic cache browser |
analytics.html | 667 | FIP analytics views |
memory.html | 637 | Persistent memory browser |
compute.html | 475 | AK-434 per-dispatch + central compute cost |
jobs.html | 358 | Scheduled jobs |
vault.html | 388 | Vault index status |
dashboard.css | 584 | Shared styles |
fonts/ | — | Inter (Variable + Italic), Roboto Mono, fonts.css, SIL OFL licence |
avatars/ | — | 9 agent PNGs (cyrax, genji, gray-fox, lisa, raiden, sektor, smoke, yoshimitsu, zer0) |
logo.png | — | Brand mark |
| Total (HTML+CSS) | ~8440 | (static assets; no TS) |
3. Public API Surface
REST Endpoints
None owned by this directory — it is served, not routed. Its backend surface is documented in [dashboard-api](/docs/gateway/modules/dashboard-api) (/api/dashboard/*) and the general /api/* surface it fetches with the injected read-only token.
Serving (in server/index.ts): 12 explicit page routes (GET /dashboard, /dashboard/cache, /dashboard/memory, /dashboard/agents, /dashboard/context, /dashboard/jobs, /dashboard/compute, /dashboard/armoury, /dashboard/vault, /dashboard/analytics) call renderDashboardPage(file, res), which:
- Reads the on-disk HTML.
- Injects a
<meta name="dashboard-read-token" content="…">tag (HTML-attr-escaped) + theDASHBOARD_AUTH_SHIM<script>immediately after<head>. - Sends the token-injected HTML.
The shim wraps window.fetch (adds Authorization: Bearer <read-token> to same-origin /api/ requests unless already set) and EventSource (appends ?token= since EventSource can't set headers). A static fallback app.use('/dashboard', express.static(dashboardDir)) (index.ts line 917) serves CSS/fonts/logo/avatars with no token literal — the token is only ever templated into the authenticated render path, never written into a statically-served asset. A leaked read-only token is read-only and cannot mint writes.
Auth: one of a small set of health and dashboard-static endpoints exempt from Bearer auth — the page shell and static assets need no Bearer. The token the shim carries authorises the page's subsequent /api/* read traffic; write mutations from the dashboard still 401 (read-only token rejected at the Bearer gate).
MCP Tools
None.
4. Internal API
None (no exports — static assets). The serving/render/shim logic (renderDashboardPage, DASHBOARD_AUTH_SHIM, escapeHtmlAttr, DASHBOARD_PAGES) lives in server/index.ts.
5. Background Services
None. Client-side JS in the pages opens EventSource streams (via dashboard-api SSE proxy) for live timeline updates, but no server-side background service belongs to this directory.
6. Data Contracts
None (no inbound schemas). The pages consume the JSON response shapes defined by the modules they fetch (analytics, dashboard-api, psychic-cache, agent-memory, compute-metering, curator, etc.).
7. Dependencies
- Backend surface:
dashboard-api/(/api/dashboard/*), plus direct fetches to/api/analytics,/api/psychic-cache,/api/agent-memory,/api/curator,/api/compute-capture/cost/*,/api/sessions/events(SSE), etc. - External libraries: none bundled — self-contained HTML/CSS with local variable fonts (Inter, Roboto Mono). No build step; no npm dependency.
- Environment variables: none (the read token is injected server-side at render).
8. Test Coverage
No direct test suite (static assets). The serving path, token injection, and auth posture are covered indirectly by test/ak415-funnel-auth.test.ts (dashboard exemption + token render) and test/dashboard-proxy.test.ts (the /api/dashboard/* backend the pages consume).
9. Known Limitations
- Hand-authored HTML per tab (no shared component framework) — cross-tab consistency (nav, styling, token-shim assumptions) is maintained by convention, not tooling; drift risk grows with tab count.
- The auth shim assumes every page has a literal
<head>string for injection; a page authored without<head>falls back to prepending the injection (handled, but fragile). - Static-asset serving is dark to the token-injection path by design — any future page that needs the token MUST be added to
DASHBOARD_PAGES(explicit route), orexpress.staticwill serve it token-less and its/api/fetches will 401.
10. Change History
| Date | Dispatch | Summary |
|---|---|---|
| 2026-07-04 | 2297 | Initial module spec (smoke-clone-3, LisaOS audit campaign Phase 4) |
| — | 1689 (AK-415) | Server-side read-token <meta> + fetch/EventSource auth shim injection |
| — | 392 | Analytics tab added |
| — | (AK-434) | Compute cost tab added |