- URL as source of truth: parseRoute/urlForPath/urlForView ported verbatim
(src/router.ts), single catch-all route so encoded slashes survive
- hub shell: project nav with color chips, org bar, admin bar with pending
count, sign-out per session flags; volume shell renders too
- empty-state onboarding (invite paste + create project), /join/<token>
invite accept that survives the login redirect
- toast + modal prompt/confirm primitives (imperative promise API over a
React host, matching the classic behavior)
- e2e: 7 new hub specs (11 total green); harness gains a no-org 'solo'
account to reach the empty state
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P5cxPQdSGJnjXCYY9GeWXt
- Vite+React+TypeScript workspace at internal/webapp/frontend; vite build
emits committed assets into internal/webapp/static (the go:embed target),
so plain 'go build' still needs no Node
- style.css and the SVG sprite ported verbatim; boot layer (api/config,
401->login redirect) ported so the auth flow works end to end
- frontend(): content-hashed assets/* now served immutable; index.html
stays no-cache (TestFrontendSPAFallback covers both)
- committed e2e harness (BDRIVE_E2E_SERVE=1, deterministic seeded hub on
:8993) wired as Playwright webServer; 4 shell specs green
- check-dist.sh guards against stale committed build output
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P5cxPQdSGJnjXCYY9GeWXt