fix(frontend,harness): phase-stepper wiring, central tail, activity-panel markdown

- WorkflowBar: center the phase pills (add justify-center).
- tht-gate.js: the gate was sending the descriptive phase name (e.g.
  "chiarimento") instead of the workflow.yaml id ("F1") in the widget's
  `phase` field, so the frontend's F1..F8 match never hit and pills never
  lit up. Rename phaseName -> phaseId, return p.id.
- CentralStatus: expand the live "working" tail from a single truncated
  line to up to 5 lines (line-clamp-5 safety net for unbroken paragraphs).
- ModelActivityPanel: render the streamed tail through react-markdown +
  remark-gfm instead of raw per-line <p> tags, so emphasis/headings render
  and blank-line paragraph breaks (previously stripped) are preserved;
  tail-cut now operates on paragraphs instead of physical lines.

Updated tests accordingly (WorkflowBar/CentralStatus/ModelActivityPanel/
AppShell.session-mgmt); full frontend suite (98/98) + harness gate node
tests (34/34) + tsc -b pass.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-02 15:53:31 +02:00
co-authored by Claude Sonnet 5
parent 7c417d4cf1
commit 023c69d752
6 changed files with 86 additions and 48 deletions
@@ -99,9 +99,10 @@ test("WIP icon toggles the Model activity panel and shows the streamed text", as
server.use(http.post("http://localhost:8787/sessions/:id/resume", () => new HttpResponse(null, { status: 204 })));
await userEvent.click(await screen.findByText("Attiva uno")); // opens docs panel
await userEvent.click(await screen.findByRole("button", { name: /resume/i })); // active session
act(() => { useSessionStore.getState().applyEvent({ type: "text_delta", text: "FIRSTLINE alpha bravo charlie delta echo foxtrot golf hotel india juliet kilo" }); });
const SIX_LINES = ["FIRSTLINE step one", "step two", "step three", "step four", "step five", "step six"].join("\n");
act(() => { useSessionStore.getState().applyEvent({ type: "text_delta", text: SIX_LINES }); });
// The verbose stream stays in the (closed) left panel: its START is not shown centrally
// (the central working indicator shows only a short tail of last words, by design).
// (the central working indicator shows only the last 5 lines of tail, by design).
expect(screen.queryByRole("heading", { name: /model activity/i })).not.toBeInTheDocument();
expect(screen.queryByText(/FIRSTLINE/)).not.toBeInTheDocument();
await userEvent.click(screen.getByRole("button", { name: /model activity/i }));