workspace/provider/model/thinking now come from getSettings() injected into
sessionRoutes; the request body supplies only question+name. Also teaches
fake_pi_rpc to respond to set_model and set_thinking_level RPC commands so
tests that pass real model settings don't hang.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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>
- Add PiProcessManager.resume(sessionId, tht): reads provider/model/thinking
from tht.sessionShow() and calls spawnFor with those values
- Add POST /sessions/:id/resume route: calls mgr.resume then re-wires
bridge.onClientEvent → hub.publish
- Confirm venv PATH already present in real spawn (no change needed)
- Add e2e test: POST /sessions → SSE receives ui_request via pendingWidget
re-emit → POST /sessions/s1/response → 204 (all over real HTTP against
fake-pi-rpc)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
POST /sessions no longer silently drops `workspace`. ThtRunner.run/json
take an optional workspace; configArg() selects workspaces/<ws>.yaml when
it exists under harnessDir, else falls back to default configPath.
sessionNew threads workspace through. Route forwards b.workspace with an
MVP note (gate/Pi side still single-workspace via symlinked config/tht.yaml).
19/19 tests pass, tsc clean.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Make buildApp injectable (deps.thtRunner + deps.spawnFn); create
src/routes/sessions.ts with all 7 session routes under authPreHandler;
wire bridge.onClientEvent→hub.publish before returning {id} from POST
/sessions; SSE subscribes with pendingWidget safety net.
18/18 tests pass, tsc clean.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>