feat(frontend): client web read-only pairing + snapshot état (#13)

Lot F2 du chantier server/client mode : client web read-only complétant le
premier incrément livrable — pairing, liste des projets, ouverture et
snapshot de l'état, sans PTY.

- frontend/src/adapters/http/webSession.ts : session web (pairing/cookie).
- frontend/src/features/web : PairingScreen, WebWorkspace, WebApp, index.
- Câblage main.tsx et adaptations httpInvoker.ts / index.ts (cas 401).
- Tests : webSession.test.ts, WebApp.test.tsx, cas 401 dans
  httpInvoker.test.ts.

Validé : frontend 736 tests verts, build vert, garde no-direct-invoke
verte, contrat B4↔F2 aligné, desktop non régressé.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-15 13:21:35 +02:00
parent fa353f6c0b
commit e500e31663
11 changed files with 768 additions and 3 deletions

View File

@ -18,6 +18,7 @@ import type { Gateways } from "@/ports";
import { LocalStorageUiPreferencesGateway } from "../uiPreferences";
import { HttpInvoker } from "./httpInvoker";
import { WsLiveClient } from "./wsLiveClient";
import { getWebSession } from "./webSession";
import {
HttpConversationGateway,
HttpEmbedderGateway,
@ -77,7 +78,13 @@ function resolveEndpoints(config: HttpWsGatewaysConfig): {
*/
export function createHttpWsGateways(config: HttpWsGatewaysConfig = {}): Gateways {
const { baseUrl, wsUrl } = resolveEndpoints(config);
const http = new HttpInvoker({ baseUrl, token: config.token });
// Route 401s back to the pairing screen via the shared web session (F2).
const session = getWebSession();
const http = new HttpInvoker({
baseUrl,
token: config.token,
onUnauthorized: () => session.notifyUnauthorized(),
});
const ws = new WsLiveClient({ wsUrl, token: config.token });
return {
@ -108,3 +115,4 @@ export function createHttpWsGateways(config: HttpWsGatewaysConfig = {}): Gateway
export { HttpInvoker } from "./httpInvoker";
export { WsLiveClient } from "./wsLiveClient";
export { WebSession, getWebSession, setWebSessionForTests } from "./webSession";