feat(ui): Stage 1 demo mode — UI runs with no backend#220
Merged
Conversation
MSW v2 intercepts /api/* fetch + SSE so the UI bootstraps cleanly with no
Alice/UTA running. Auto-authed, PTY terminal stub'd, minimum-viable fixtures
for the 5 non-trivial domains (auth, trading, workspaces, events SSE, chat
SSE); the long tail of ~130 endpoints falls through a catchAll handler that
returns 200 {} and console.warns the unmocked path so Stage 2 can walk the
log and flesh out per-endpoint handlers.
Colocated under ui/src/demo/ behind import.meta.env.VITE_DEMO_MODE — Rollup
tree-shakes the entire subtree (and the Terminal.tsx stub branch) out of
production bundles. Verified: prod bundle grep for msw/VITE_DEMO_MODE/
DemoTerminalStub returns zero matches.
Files of note:
- ui/src/demo/handlers/catchAll.ts uses a RegExp literal (not '/api/*'
glob) to dodge a path-to-regexp v8 incompatibility inside MSW v2's
string-pattern matcher
- Root pnpm.overrides adds scoped 'msw>path-to-regexp@^6.3.0' so MSW gets
the v6-syntax-compatible (and CVE-patched) version, while everyone else
stays on the security-pinned v8 override
- ui/src/components/workspace/Terminal.tsx gets a one-line early-return
guard that renders DemoTerminalStub when demo mode is on — verified
zero WebSocket attempts to /api/workspaces/pty when a session pane opens
Verified end-to-end in browser (Playwright):
- npx tsc -b in ui/ clean
- pnpm -F open-alice-ui dev:demo + navigate to /inbox, /portfolio, /news,
/workspaces/demo-ws, /workspaces/demo-ws/s/demo-session, /settings: 0
console errors throughout, demo terminal stub renders correctly
- 2 catchAll warns surfaced (PUT /api/config/snapshot, PUT
/api/config/compaction) — Stage 2 backlog
- pnpm -F open-alice-ui build (no demo flag): 2.8MB main chunk, zero msw
references, zero VITE_DEMO_MODE references, zero DemoTerminalStub
Out of scope (Stage 2): rich fixtures, scripted SSE timelines, PTY replay,
in-memory mutation persistence, demo-mode banner.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
OpenAlice's web UI now runs with no backend when launched in demo mode. MSW v2 intercepts
/api/*fetch + SSE so the UI bootstraps cleanly without Alice / UTA running. Auto-authed, PTY terminal stub'd, minimum-viable fixtures for the 5 non-trivial domains (auth / trading / workspaces / events SSE / chat SSE); the long tail of ~130 endpoints falls through acatchAllhandler that returns200 {}andconsole.warns the unmocked path so Stage 2 can walk the log and flesh out handlers as they actually break.Continues the cost-curve-inversion line from #216 (Electron split, ~1G saved). Next axis: a cloud Claude Code session can now iterate on UI without standing up Alice + UTA. Also the structural prereq for the future marketing demo site (Stage 2, deferred).
Plan:
/Users/ame/.claude/plans/merry-cooking-origami.mdWhat changed
ui/src/demo/DemoTerminalStub.tsx+ README. Dynamic-imported inmain.tsxonly whenimport.meta.env.VITE_DEMO_MODEis truthy → Rollup tree-shakes the whole subtree in prod builds.ui/public/mockServiceWorker.jspnpm -F open-alice-ui msw:init. Committed (deterministic, version-pinned).ui/.env.demoVITE_DEMO_MODE=true..gitignoreexception added since.env*is broadly gitignored.ui/src/vite-env.d.tsimport.meta.envtypes — referencingvite/clientand declaringVITE_DEMO_MODE.ui/src/main.tsxawait import('./demo')beforecreateRoot.ui/src/components/workspace/Terminal.tsxDemoTerminalStuband early-return when env flag is on. Both the guard and the import are dead-code-eliminated in production.ui/package.jsonmsw@^2.14.6), +3 scripts (dev:demo,build:demo,msw:init).package.jsonmsw>path-to-regexp: ^6.3.0. MSW v2 expects v6 path-syntax; root's security-pinned v8 override broke MSW's matcher. v6.3.0 is also patched for CVE-2024-45296.Verification — end-to-end in browser
Ran
pnpm -F open-alice-ui dev:demowith no backend running. Navigated via Playwright through:/inbox(initial) — auto-authed, no login screen/portfolio— demo UTA $10k equity, empty positions/news— empty list/workspaces/demo-ws— demo workspace + git/files panels render/workspaces/demo-ws/s/demo-session—Demo mode — terminal disabledstub renders, zero WebSocket attempts to/api/workspaces/pty(the key safety check)/settings— settings page loadsResult: 0 console errors across the entire walk. 2 catchAll warns surfaced (
PUT /api/config/snapshot,PUT /api/config/compaction) — these are the Stage 2 backlog signals working as designed.Production bundle accounting
pnpm -F open-alice-ui build(no demo flag) →ui/dist/assets/index-*.js:Main chunk 2.84MB / 845KB gzip — identical magnitude vs master (the chunk-size warning is pre-existing).
Install size delta
pnpm install --filter='!@traderalice/desktop'(cloud sessions).pnpm)The "UI-only install" sub-target hit a pnpm limitation: with
--frozen-lockfile, pnpm populates.pnpm/from the full lockfile regardless of--filter. Getting below 750M would require lockfile sharding — deferred.Test plan
pnpm -F open-alice-ui tsc -bcleanpnpm -F open-alice-ui dev:demo+ Playwright walkthrough (0 errors)pnpm -F open-alice-ui build— no msw / VITE_DEMO_MODE / DemoTerminalStub refs in prod bundleptyWebSocket attemptsconsole.warn(= Stage 2 backlog)pnpm dev(full stack) to confirm production path still works unchanged — deferred to reviewer (this is the non-demo path, untouched by this PR)Out of scope (Stage 2)
Rich scenario fixtures, scripted SSE timelines, WebSocket PTY replay (waits for MSW v2 WS GA), in-memory mutation persistence, persistent "Demo Mode" UI banner, marketing-quality copy. The current PR lays the structural foundation; Stage 2 walks the
[demo] unmocked …console.warn log to fill in coverage.Boundary touch
None — no trading / auth / broker / migrations code modified.
🤖 Generated with Claude Code