mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-10-16 20:02:20 +02:00
docs(specs): routine specifications update
This commit is contained in:
+38
-16
@@ -1,6 +1,6 @@
|
||||
# Frontend
|
||||
|
||||
Last updated: dev@e71f8ce | 2026-08-25
|
||||
Last updated: dev@c74f475 | 2026-10-15
|
||||
|
||||
## Scope
|
||||
|
||||
@@ -11,14 +11,14 @@ This spec covers the current browser app in:
|
||||
- `static/index.html`;
|
||||
- `static/login.html`;
|
||||
- `static/app.js`;
|
||||
- `static/style.css`;
|
||||
- ordered stylesheets under `static/css/`;
|
||||
- `static/js/*.js` and `static/js/*/*.js`;
|
||||
- vendor libraries under `static/lib/*`;
|
||||
- custom fonts and static assets under `static/fonts/*`;
|
||||
- `static/sw.js` and `static/manifest.json`;
|
||||
- frontend-oriented tests in `tests/*_js.py`, `tests/*.mjs`, `tests/bombadil-spec.ts`, static DOM/CSS/source-shape tests, and app/static tests such as `tests/test_app_static_mime.py`.
|
||||
|
||||
`/backgrounds` currently targets `static/backgrounds.html`; if that route remains, the file must exist or the route should be removed.
|
||||
`/backgrounds` remains registered in `app.py` but targets the absent `static/backgrounds.html`. Authentication middleware also gates it when auth is enabled, despite its handler docstring describing a public prototype page. This is a known route/static gap; the page is not a working frontend surface at the checked revision.
|
||||
|
||||
`static/manifest.json`, `static/index.html`, and `static/login.html` reference first-party PWA icon files under `static/icons/` (192px, 512px, and maskable). At runtime, route-specific manifests can also be generated as Blob URLs when supported, and per-route favicon links use generated inline SVG.
|
||||
|
||||
@@ -35,7 +35,7 @@ This spec covers the current browser app in:
|
||||
|
||||
## Runtime Shape
|
||||
|
||||
The frontend is a raw static SPA served by FastAPI. There is no Vite, React, TypeScript, bundler, or generated build output.
|
||||
The browser runtime is a static native-ES-module SPA served by FastAPI, without a runtime Node/build dependency. Incremental maintained sources now live under `frontend/src/`, with explicit source-to-deployment mappings in `frontend/modules.json`; the map publishes `shared/actionMenuOrder.js`, the Notes feature graph and shared confetti to committed `static/js/` outputs. `scripts/build_frontend.py` publishes/checks those bytes during development, never application startup. Legacy modules remain authored under `static/`; there is no Vite/React/TypeScript bundle.
|
||||
|
||||
`app.py` owns:
|
||||
|
||||
@@ -49,7 +49,11 @@ The frontend is a raw static SPA served by FastAPI. There is no Vite, React, Typ
|
||||
|
||||
The two first-paint Fira Code faces are preloaded so the shell does not wait for later CSS discovery. `static/js/startupShell.js` lets the visible shell initialize before session loading completes; session/transcript hydration is deferred and coordinated by `static/js/sessions.js` plus history/session routes rather than blocking first paint.
|
||||
|
||||
Exact script URL identity matters. Versioned script tags, unversioned imports, and service-worker precache entries must stay aligned. `static/sw.js` deliberately separates first-paint `PRECACHE` from lazy `PANEL_PRECACHE`; the latter currently contains the image-editor module graph so an editor never opened online can still open offline. KaTeX scripts/styles/fonts are also precached. Current service-worker coverage is not a generated full module-graph manifest, so changes still need direct verification.
|
||||
Exact script URL identity matters. Versioned script tags, unversioned imports, and service-worker precache entries must stay aligned. `static/sw.js` deliberately separates first-paint `PRECACHE` from lazy `PANEL_PRECACHE`; the latter contains the image-editor module graph so an editor never opened online can still open offline. The Notes feature graph and shared confetti are explicitly in `PRECACHE`, together with their exact legacy helper URLs. KaTeX scripts/styles/fonts are also precached. Current service-worker coverage is not a generated full module-graph manifest, so changes still need direct verification.
|
||||
|
||||
`static/style.css` has been removed. `static/index.html` loads numbered `static/css/00-tokens.css` through `17-research.css` in order, followed by the three domain panel stylesheets. `static/sw.js` precaches those exact versioned URLs; cascade order remains part of behavior.
|
||||
|
||||
New extracted owners include `static/js/turnRendering.js` for live/canonical turn DOM reconciliation, `backgroundToolJobs.js` for deduplicated background deliveries and research status cards, `emailReplyStream.js` for email reply streams, and `chatgptSubscriptionUsage.js` for account usage UI. Settings panel modules now also include `agent.js`, `api.js`, `imageModels.js`, `speech.js`, and `writingStyle.js`.
|
||||
|
||||
## Security Policy
|
||||
|
||||
@@ -76,7 +80,7 @@ Storage/secrets policy:
|
||||
`static/sw.js` owns PWA cache behavior:
|
||||
|
||||
- API and non-GET requests are bypassed;
|
||||
- root navigation uses stale-while-revalidate;
|
||||
- only `/` navigation uses network-first with cached-shell fallback; other navigation URLs are not replaced with the app shell;
|
||||
- JS/CSS use network-first behavior;
|
||||
- other static assets use cache-first with background refresh;
|
||||
- `CACHE_NAME` bumps and `PRECACHE` updates must accompany cache policy or shell asset changes.
|
||||
@@ -97,7 +101,7 @@ Current major frontend areas include:
|
||||
- image editor integration in `static/js/galleryEditor.js` plus leaves under `static/js/editor/`;
|
||||
- gallery, email inbox/library, calendar, research panel/jobs/synapse, notes/tasks, assistant, memory/skills, Cookbook/HW Fit, workspace picker, provider device flow, composer ArrowUp recall, theme, modal/window utilities, storage, and accessibility helpers.
|
||||
|
||||
`static/js/emailLibrary/` is the one JS package with module-graph coverage: `tests/test_email_library_module_graph_js.py` pins the wrapper's public surface against the entry module's exports, evaluates every module on its own in a browser so an import cycle cannot hide a temporal-dead-zone read, and requires each module to be in the `sw.js` precache. Assertions about its source go through `tests/helpers/js_modules.py`, which reads the whole package, for the same reason `tests/helpers/stylesheets.py` reads the whole cascade.
|
||||
`static/js/emailLibrary.js` is a compatibility wrapper over one unversioned package entry and explicit leaves for reader, menus, attachments, reply, settings and unsubscribe behavior; the final wrapper has ten named exports. `tests/test_email_library_module_graph_js.py` compares the unversioned public surface, imports immediate package modules in synthetic browser shells and checks quoted service-worker URLs. It does not prove every callback, nested module, load order or offline behavior. `tests/helpers/js_modules.py` uses immediate entry-first file enumeration and column-zero source extraction; its package-name binding regex is not lexical-scope analysis.
|
||||
|
||||
Coordinator ownership:
|
||||
|
||||
@@ -116,9 +120,15 @@ Recent browser behavior contracts include mobile chat Enter inserting newlines w
|
||||
|
||||
The Settings finder and navigation are registry-backed, hide admin-only destinations from non-admin users, lazy-load admin panels, and keep the registry synchronized with DOM panels. Email OAuth connect preserves SMTP security and reopens the settings surface; unread message opens use one authoritative backend read/mark-seen request with stale-response guards; email-library prewarm is idle-only, single-flight, bounded to the initial page, and cancelled around visible foreground work.
|
||||
|
||||
## Notes Feature Ownership
|
||||
|
||||
`frontend/src/features/notes/index.js` composes one canonical Notes instance from domain rules/recurrence, application operations/state, infrastructure ports and UI factories. `frontend/modules.json` publishes its source modules byte-for-byte under `static/js/features/notes/` and shared confetti under `static/js/shared/ui/`. `static/js/notes.js` is the compatibility facade: it reexports the canonical methods/default, assigns `window.notesModule` and starts idempotent background reminders. Versioned/unversioned facade imports converge on the unversioned canonical entry. `static/app.js` retains the versioned facade caller; Compare voting imports and reexports shared confetti rather than owning it.
|
||||
|
||||
State mutations belong to `application/state.js`; UI gets live read-only views, and operation writes unwrap nested views to keep stored note data cloneable. The composition injects HTTP, persistence, clock/scheduler, notification and shared platform callbacks. Panel disposal releases owned portals, document/window listeners, gesture state and masonry observers; detached/closed-panel checks prevent late completions from recreating observers. Tablet reorder rewiring replaces stale binding sentinels. Reminder scheduling is page-owned and survives close/minimize; custom reminder date initialization uses DOM value assignment rather than HTML interpolation. Domain-specific drafts/reminder/selection contracts and remaining races are in `calendar-tasks-notes.md`.
|
||||
|
||||
## UI Policy
|
||||
|
||||
- New code must run as browser ES modules without a build step.
|
||||
- New runtime code remains native browser ES modules; manifest-selected maintained sources use the development publication/check step without adding a startup build.
|
||||
- Reuse existing CSS variables, modal/window patterns, icon style, storage helpers, and route conventions.
|
||||
- Custom font handling includes bundled OpenDyslexic assets plus user-supplied fonts exposed through `/api/fonts/custom`; font and text-size settings must stay coordinated between settings UI, theme helpers, and CSS variables.
|
||||
- Avoid relying on stale module summaries.
|
||||
@@ -138,25 +148,37 @@ The Settings finder and navigation are registry-backed, hide admin-only destinat
|
||||
|
||||
Existing frontend coverage is a mix of Node-executed helper tests, `.mjs` tests, static DOM/CSS/source-shape tests, browser exploration specs, and app/static tests. Many tests are useful source-shape regressions but do not replace browser/module-graph execution.
|
||||
|
||||
`tests/test_css_computed_style_snapshot.py` pins `getComputedStyle` for a fixed element inventory across pages, viewports, themes and density modes, so a `static/style.css` restructuring that changes which declaration wins fails a test instead of shipping; see `tests/css_snapshot/README.md` for what it does and does not cover.
|
||||
`tests/test_css_computed_style_snapshot.py` pins `getComputedStyle` for a fixed element inventory across pages, viewports, themes and density modes, so a stylesheet cascade restructuring that changes which declaration wins fails a test instead of shipping; see `tests/css_snapshot/README.md` for what it does and does not cover.
|
||||
|
||||
Recent focused coverage includes model-key matching under Node, document-library counters, chat resend/delete/mobile Enter/ArrowUp, scoped approval continuation and compare routing, route provenance, live-thinking throttling, startup shell/history hydration, shared app-config caching/invalidation, settings registry/navigation/finder/lifecycle, lazy panel loading/offline editor precache, vendored lazy KaTeX/Mermaid rendering, email read dedup/prewarm, Markdown restoration, malformed keybinds, currency-safe inline math, notes/calendar/modal/manifest/admin-log behavior, Markdown XSS helpers, and CardDAV unchanged-password handling.
|
||||
|
||||
Missing coverage includes:
|
||||
Areas that still need explicit behavior verification include:
|
||||
|
||||
- SPA route/static auth and no-cache headers;
|
||||
- CSP header contents and nonce injection for `/` and `/login`;
|
||||
- service-worker API/non-GET bypass and cache strategy;
|
||||
- service-worker precache versus `index.html` script/module tags, including query strings (stylesheet links and their `?v=` strings are covered by `tests/test_static_stylesheet_manifest.py`; script and module tags are not);
|
||||
- ongoing manifest/icon reference drift;
|
||||
- module graph/load-order validation;
|
||||
- complete service-worker precache membership versus HTML scripts/modules: stylesheet parity is covered by `tests/test_static_stylesheet_manifest.py`, and `tests/test_frontend_module_version_parity.py` checks selected app/index/SW versions plus regex-discovered JS/index URL identities, but neither proves complete graph evaluation;
|
||||
- ongoing manifest/icon reference drift; `sw.js` now explicitly precaches the default manifest and three PWA icons;
|
||||
- complete legacy module graph/load-order behavior beyond maintained-source architecture gates and the email-library browser graph;
|
||||
- degraded vendor-library/browser API behavior, including Pyodide's remaining CDN path.
|
||||
|
||||
## Rendering, Provider UI And Static Checks
|
||||
|
||||
`turnRendering.js` reconciles canonical/live ownership with turn replacement metadata while keeping tool activity. Compact corrected/final events can replace earlier prose; the server completion gate can buffer answer deltas, so this is not a promise of immediate streaming. Ordinary ask-user choices have 1–3 keyboard shortcuts; tool approval cards are excluded. Active document state restores the exact chat-bound document; editor rich-only font controls and stats portal z-order are independent of chat tool authority. The research map SVG has an image role and accessible name, without proving complete accessibility.
|
||||
|
||||
Usage ledgers use nested Maps to preserve arbitrary legacy keys as data, while fresh writes require a nonempty session id and reject reserved session/run keys before accounting. JSON conversion preserves wire shape; metrics with a run id replace that run's previous value, while legacy writes without one add to aggregate totals and use per-object recorded/pending guards. Web Locks are used when available and bounded entries fold into totals, so evicted run replay is not forever deduplicated. Admin provider cards hide ChatGPT/recognized Featherless base URLs; optional fingerprints and displayed version/source commit are informational rather than byte attestation. Featherless catalog search is debounced/paginated with bounded results; optimistic pin/tool-mode PATCH saves and load-more handling do not guarantee acknowledged persistence or universal stale-response cancellation. Collapsed account usage cards retain loaded DOM, including errors, rather than proving fresh telemetry.
|
||||
|
||||
Markdown SVG uses an empty-sandbox, no-referrer iframe and restrictive CSP; title extraction is flat escaped text rather than parent-DOM parsing. Fenced and complete raw SVG are separate from generic HTML fences, with bounded aspect ratio. This does not confer the different permissions used by document print/run iframes. Remote mail rendering and image thumbnail assignment retain their own sanitizer/network boundaries.
|
||||
|
||||
Stylesheet helpers read the shell-ordered complete app cascade, exclude vendored libraries and share cache-token checks. Recursive lexical hygiene rejects deleted-monolith references with bounded exceptions; comment-stripped keyframe counting catches duplicate global names. Document-source helpers enumerate implementation files and scan braces lexically; quoted import/SW membership and minimum callable export tests are narrower than semantic module execution. The fixed computed-style snapshot covers 676 elements across its configured page/viewport/theme/density cases, freezes animation timing and checks a global rule-swap sensitivity count; it is not arbitrary browser/layout coverage. Manual benchmark HTML and historical screenshots are not newly reproduced acceptance.
|
||||
|
||||
The website has seven hover/focus/tap preview clips, ambient video, failure placeholders and thresholded swipe navigation. Reduced-motion CSS disables selected animation rather than guaranteeing all video stops. Restored branding/PWA assets do not prove license clearance or decoded-image review; the known `/backgrounds` absent-file/auth gap remains.
|
||||
|
||||
## Current Gaps
|
||||
|
||||
- `static/style.css` and large coordinators remain high-risk owners: `static/js/document.js`, `static/js/settings.js`, `static/js/chat.js`, and `static/app.js`.
|
||||
- There is no build-time type checking, module graph validation, or script-order validation. Service-worker precache validation exists for stylesheets, and for the `static/js/emailLibrary/` package only.
|
||||
- The ordered stylesheet cascade and large coordinators remain high-risk owners: `static/js/document.js`, `static/js/settings.js`, `static/js/chat.js`, and `static/app.js`.
|
||||
- There is no general build-time type checking or complete legacy script-order validation. `scripts/check_frontend.mjs` checks maintained-source imports, layer boundaries, explicit legacy exceptions, deployment URL/precache identity, and dependency cycles; its inventory mode reports legacy static imports/cycles. These gates cover the manifest-selected maintained graph, not every legacy module. Service-worker checks also cover stylesheet URLs and the email-library package.
|
||||
- Frontend state is mostly module/global/localStorage driven, so cross-session and cross-user behavior needs explicit care.
|
||||
- `window.*` compatibility bridges remain widespread.
|
||||
- PWA/static-serving behavior may deserve a separate spec if service worker, manifests, route-specific icons, and cache policy keep growing.
|
||||
- The static asset/route manifest regression covers stylesheets referenced by app-owned HTML and `sw.js`; scripts, modules and `manifest.json` icon references are still unverified.
|
||||
- Static regressions cover stylesheet references, selected script/module URL identities and maintained-output precache membership; complete legacy graph membership/evaluation and ongoing manifest icon drift still require checks.
|
||||
|
||||
Reference in New Issue
Block a user