Commit Graph
13 Commits
Author SHA1 Message Date
marcopan 90684c3280 refactor: remove legacy workspace UI state 2026-08-10 22:56:00 +02:00
marcopan d77c08884b test: use canonical workspace API fixtures 2026-08-09 20:44:35 +02:00
marcopan 7df21b5f21 fix: harden Pi management readiness 2026-08-05 06:20:25 +02:00
marcopanandClaude Opus 4.6 3b52c8c08c feat: DWH connectivity probe at startup — modal alert within 5s if unreachable
Backend: GET /health/dwh (unauthenticated) calls tht db ping with a 5s
timeout. Frontend: checkDwhHealth() races a 5s timer against the fetch;
on failure a non-dismissable Dialog with Retry appears immediately.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-20 13:59:11 +02:00
marcopanandClaude Opus 4.8 f979ada5e7 feat(frontend): open a live session straight to its pending gate
Opening an in-progress session that has a live Pi runtime now reconnects to
its pending gate instead of the empty landing screen that read as "stopped".
Cold/completed sessions keep the read-only documents panel with its explicit
Resume, so a mere click never spawns a runtime. Backend GET /sessions now
reports a per-session `active` flag (live runtime bound) to drive this.

Also:
- "New session" now closes any open session detail panel (left box).
- The model-activity separator can be dragged to a full 50/50 split
  (was capped at 576px); central-min still guards narrow viewports.

Test fixes uncovered along the way:
- Node 25 ships an experimental global localStorage that shadows jsdom's and
  lacks clear(), failing every jsdom test at setup; install a spec-compliant
  in-memory Storage (feature-detected, inert on CI/LTS).
- Fix 4 pre-existing session-mgmt tests that used an ambiguous getByText for a
  session shown in both nav and header; target the nav item by test id.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 22:56:12 +02:00
User 08b1f4909e fix: make session resume atomic across restarts 2026-07-15 00:42:35 +02:00
User 2b4797f133 fix: harden resume and SSE replay 2026-07-15 00:06:00 +02:00
marcopanandClaude Opus 4.8 4e6d4a4cea feat(frontend): restyle ThothII to the Omics Portal (GSD) design system
Adopt the portal's design language so the app embeds seamlessly into its
header/sidebar chrome later:
- Token layer rewritten as raw OKLCH triplets (the previous oklch()-wrapped
  vars produced invalid colors; the UI was effectively unstyled). Values mirror
  GSD: Manrope + Fraunces fonts, #cb333b red brand, warm off-white surfaces,
  pill buttons, brand focus rings. Dark tokens follow .dark or the portal's
  [data-bs-theme=dark].
- Layout: no left sidebar, no header (the portal supplies them). Conversation
  column flush-left with a slim F1-F8 phase strip; session rail moved to the
  RIGHT, mirroring the portal's left sidebar (red section label, red-tint active
  item). Editorial empty state.
- Transcript component now actually renders the streamed assistant turns (the
  store accumulated them but nothing displayed them). Toaster mounted for errors
  (matchMedia polyfill added to the jsdom test setup).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28 18:05:23 +02:00
marcopanandClaude Opus 4.8 ddbbe4d1ac test(frontend): unit tests exercise named SSE events (fidelity) + cleanup
FakeEventSource.addEventListener was a no-op, so emit() only drove onmessage.
Production relies on addEventListener for the backend's NAMED events
(event: ui_request), so the unit tests could pass while prod silently broke.

- fakeEventSource: store named handlers in a Map<string,Set>; add emitNamed()
  that dispatches to them; keep emit() for the unnamed/default onmessage path
- useSessionStream.test: ui_request now driven via emitNamed (production path);
  add a separate test for the unnamed text_delta path via plain emit
- f1-loop.test: widget emission switched to emitNamed("ui_request", ...)
- verified: tests FAIL if addEventListener wiring is removed from
  useSessionStream (then restored)
- cleanup: fake-pi.mjs drops unused execFileSync import, uses static spawnSync

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28 13:33:50 +02:00
marcopanandClaude Sonnet 4.6 1171181f9a test(frontend): Playwright e2e F1 vs backend+fake-pi (hermetic)
Adds a real-browser Playwright e2e of the full F1 disambiguation loop,
driven against the real backend + fake binaries (no VPN, no real Pi, no Python).

- frontend/e2e/fixtures/fake-tht.mjs: stubs tht CLI (session new/list/show)
- frontend/e2e/fixtures/fake-pi.mjs: wraps harness fake-pi-rpc with f1_disambiguation.json
- frontend/playwright.config.ts: two webServer entries (backend:8799, frontend:5199)
- frontend/e2e/f1.spec.ts: open app → create session → wait for SelectWidget → respond

Bug fixes discovered during e2e:
- useSessionStream: add addEventListener for named SSE events (backend sends
  'event: ui_request' etc.; onmessage only fires for unnamed 'event: message')
- FakeEventSource: add no-op addEventListener/removeEventListener stubs
- backend SSE route: add CORS headers manually in writeHead() since
  reply.raw bypasses the @fastify/cors onSend hook
- backend: install and register @fastify/cors for all non-SSE routes

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-28 13:27:00 +02:00
marcopan d238ddd395 feat(frontend): useSessionStream (EventSource -> store) 2026-06-28 12:19:55 +02:00
marcopanandClaude Sonnet 4.6 913ac30137 feat(frontend): contract types + REST client (MSW-tested)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-28 12:13:50 +02:00
marcopanandClaude Sonnet 4.6 662d944267 feat(frontend): scaffold Vite+React+TS+Tailwind/ShadCn + Vitest
TDD: App-renders-ThothII test RED then GREEN. ShadCn v4 (base-nova style)
init + button/checkbox/radio-group/textarea/card/dialog/badge/sonner added.
tailwind.config.ts extended with oklch CSS-variable color mapping required
by ShadCn v4 @apply directives. npm test passes; npm run build clean.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-28 12:08:22 +02:00