Built the second prototype from the LLM-interaction research phase: a self-contained branching-conversation tool at /tools/branching-chat.html, one HTML file with no build step and no dependencies. The conversation is modelled as a tree rather than a list — each message, from the visitor and from Claude, is a node linked to the one it followed. Sending from a node assembles the request context as the path from the root of the tree down to that node, so a reply only ever sees its own lineage. Branching off a message starts a new child thread that diverges at that point, leaving the original thread intact for side-by-side comparison. A toolbar toggle switches between the hand-rolled pan/zoom canvas (draggable nodes, SVG edges, active-path highlighting) and a linear view that renders the selected thread as an ordinary top-to-bottom chat with a per-fork sibling picker.
Reused the Generative UI Canvas security and BYO-key posture: Anthropic-only, a browser fetch to https://api.anthropic.com/v1/messages with stream: true SSE, x-api-key plus anthropic-dangerous-direct-browser-access: true, the key in localStorage and sent to no server of ours, default Claude Sonnet 5 with an Opus 4.8 / Haiku 4.5 picker, and prominent “your key stays in your browser” messaging with a get-a-key link and a clear-key button. Current model IDs and the browser-direct calling contract were confirmed via the claude-api skill rather than hardcoded from memory. https://api.anthropic.com was already present in the public/_headers CSP connect-src, so the policy was left unchanged. Added the tools collection entry and verified: npm run check (0 errors) and npm run build both green.