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

@ -5,7 +5,8 @@ import ReactDOM from "react-dom/client";
import { App } from "./App";
import { ViewWindow, parseViewWindowParams } from "./ViewWindow";
import { DIProvider } from "./di";
import { WebApp } from "@/features/web";
import { DIProvider, resolveTransport } from "./di";
import "@/shared/styles/theme.css";
const root = document.getElementById("root");
@ -18,10 +19,17 @@ if (!root) {
// follows the main window's focused project; otherwise the full app.
const viewParams = parseViewWindowParams(window.location.search);
// Ticket #13, F2: in web (HTTP) transport mode the browser client renders the
// pairing-gated, read-only `WebApp`. Desktop (Tauri) is unchanged — it renders
// the full `App` (or a detached view window). Detached windows are desktop-only.
const isWeb = resolveTransport() === "http";
ReactDOM.createRoot(root).render(
<React.StrictMode>
<DIProvider>
{viewParams ? (
{isWeb ? (
<WebApp />
) : viewParams ? (
<ViewWindow panel={viewParams.panel} />
) : (
<App />