5.4 KiB
Native assistant integration (2.1 candidate)
Requires UI/UX UAT approval from the maintainer.
The dashboard Chat route loads the vendored AIUI Vue components directly. It
retains the dashboard's existing KeepAlive lifetime and consent dialogs. There
is no AIUI shell iframe, second createApp, second router, or second Pinia.
Vite deduplicates Vue, Pinia, router and DOMPurify; the assistant shell and its
styles load with the chat route. Large optional renderers retain their lazy
imports. AIUI's import alias and Pinia IDs are namespaced to avoid collisions.
This is a trust-model change: reviewed AIUI application code has the same DOM, origin and privileges as the rest of the dashboard. It cannot be described as an origin-isolated application. A script execution vulnerability in reviewed native UI code would compromise that shared boundary. The protection for untrusted model and document content is prevention of active rendering, plus sandboxing of content that intentionally executes code.
The native bridge is a typed in-process request/reply adapter. It exposes the existing small context/action/content/chat inventory, never an arbitrary RPC method. It installs no window-message listener. Generated code cannot acquire this adapter by posting messages. The legacy standalone/embed transport still checks both the configured origin and exact source window. Backend permissions, rate limits, tool confirmation and fresh authorization remain authoritative; AIUI neither receives node model keys nor creates fresh authorization grants.
All rich HTML renderers sanitize output, including after math/diagram rendering.
Article printing escapes its title. Generated code runs only after Run in an
opaque sandbox="allow-scripts" iframe, with a restrictive CSP denying network,
forms, external resources and base URLs. Console messages require that exact
iframe source and opaque origin and are bounded. Website/article previews use
opaque sandboxed frames; their links and frame URLs must be HTTP(S). These
renderer fixes also apply to the rebuilt standalone /aiui/ entry point.
Structured-card links also reject executable URL schemes. The YouTube SDK runs
inside a separate opaque media frame, with fixed play/pause/seek commands and
bounded state/time replies checked against that frame. It cannot execute in the
native dashboard document; real provider playback still requires manual UAT.
Native AIUI keeps the existing aiui-* localStorage keys and the
aiui-store, aiui-vault, aiui-favorites, and aiui-nostr-dms databases.
Same-origin production installs need no copy or rekey. Existing encrypted
records are authenticated before accepting an unlock; a wrong passphrase
leaves ciphertext intact. The conversation component waits for that unlock. Destroying the native shell
clears unlocked keys and cached decrypted chat state; tab deactivation retains
it. Teardown also clears decrypted wallet-connection state and rejects delayed
vault callbacks, while preserving the saved vault entry. Comparison responses
and active file previews are cleared; their pending requests and callbacks are
cancelled or ignored after teardown. Selected comparison models and durable
conversation/settings data are retained. Pending saves capture
their key before asynchronous work, and a locked
writer cannot overwrite an encrypted conversation with plaintext. Skipping an
unlock retains existing encrypted records and shows only available plaintext
chats. Native mode does not use the standalone development file mirror.
The explicit data wipe touches only AIUI data; keeping keys also keeps the
vault and crypto salt. Dashboard storage and service-worker caches are not
cleared. A separate development origin remains separate browser storage and
requires its existing export/import mechanism if its operator wants to move it.
The native entry does not import standalone main.ts, including its PWA/cache
bootstrap. Theme, settings and teleports are scoped to the native shell. The
native stylesheet uses CSS @scope; supported browser/Companion qualification
is part of manual UAT. The build installs the vendored workspace from its
committed pnpm lockfile before building the dashboard. AIUI retains its own full
strict typecheck, and the dashboard retains its stricter compiler policy through
a concrete no-props/no-emits component boundary and typed request/reply unions. The Docker build reuses
the AIUI builder's dependency tree. Existing /aiui/ static assets and content
API paths remain available; a candidate must rebuild both entry points.
Automated acceptance covers native mounting/KeepAlive/queued asks, refusal of forged messages, broker permissions/consent, an actual browser executing hostile sandbox code, renderer payload nonexecution, and wrong/correct unlock against existing encrypted conversation/vault fixtures. A real PDF.js 6 worker renders a synthetic PDF and extracts its text, and real KaTeX 0.18 renders sanitized MathML. The app unit suite passes all 408 tests across 18 files. Exact runs are recorded with the implementation handoff. Source/fixture success is not installed-node, physical-device, artifact, release, or manual UX acceptance.
Manual draft review must check desktop/mobile layout, theme isolation, tab switch latency, draft and conversation retention, settings/history, existing vault unlock, provider setup, tool consent and fresh authorization, content surfaces, math/diagrams, article/website previews, and player behavior. No production deployment or live credential migration is authorized by this patch.