facett-claude — the direct-Claude conversation pane
Class:
design· What it IS: the reusable facett-Elm component for a "chat with Claude" pane, extracted from nornir's weldedClaudeTabso every app (nornir · dwarves · holger) mounts ONE pane — no duplication (Law #1). Sibling how-to lives with the host; this file states only what the crate is.
Function axis
- f0 — the pane: an
Elm(ClaudeModel/ClaudeMsg/update/view) bridged toFacet/Panelviaimpl_facet_via_elm!, so it is headless-drivable (update_json/state_json) and paints in egui. - f1 — the model: user/assistant
turns, thepromptinput, the selectedmodel(defaultclaude-opus-4-8), thesendingflag, anerrorslot. - f2 — the transport seam: a
ClaudeTransporttrait (aliasedClaudeBackend) the host wires. The pane does NO HTTP — onSendit emitsClaudeEffect::Send{model, messages}(data); the host runs its transport (ClaudePane::deliver) and posts backReceivedOk/ReceivedErr. Ships a built-inEchoBackendmock/echo default so the crate builds + every test drives with no network and no secrets. The transport seam's shape is byte-identical to the sharednornir-claudeleaf'ssend_wire, so theEddaBackend<T>adapter mounts ANY leaf transport (OfflineTransport, the liveHttpTransport) with zero mapping — see f4. - f3 — coverage: robot JSON-drive test + testmatrix cell + kittest render proof.
- f4 — consumes the shared edda leaf
nornir-claude(L5, DRY).WireMsg,DEFAULT_MODEL,MODELS, credential resolution (resolve_credential/Credential), the error type (ClaudeError) and the offline stub (OfflineTransport) are NOT twinned here — they are re-exported fromnornir-claude(the whole leaf is re-exported asfacett_claude::nornir_claude).EchoBackendnow delegates toOfflineTransport::echoing()(no local echo logic); theEddaBackend<T>newtype bridges a leafnornir_claude::ClaudeTransportinto the pane seam by forwarding tosend_wire. The pane stays the ONLY egui-facing piece (L5a); all transport/credential logic lives in the network-free leaf. The liveHttpTransportis pulled by the HOST (leafhttpfeature), so this crate keeps no reqwest edge.
Why no nornir / reqwest edge
Apps depend on this crate, so it must not depend on nornir (cycle) and stays a pure leaf — the Anthropic HTTP client (viz::claude::HttpTransport, reqwest, claude-opus-4-8, $ANTHROPIC_API_KEY) is injected by the host. Mirrors the facett-brokkrview/facett-korp shape. A fake transport drives the tests offline — no network, no AI in the loop.
Remote-control (the north-star)
The whole conversation is drivable IN CODE over the update_json/state_json seam (prompt_changed → send → the host posts received_ok → assert last_assistant), so the robot harness + test-matrix cover it with no human and no AI at runtime.
Data / control flow
See assets/claude-pane.svg.
Sibling docs
guide.md(classguide) — how a host mounts the pane + wires a backend.reasoning.md(classreasoning) — the why (idiot-guide): why no HTTP in the pane, why the seam + echo default, why everything routes throughupdate_json.
Hosts (to wire)
- dwarves — the 🤖 Claude tab (the third pane: Pipeline · Funnel · Claude).
- nornir — de-weld
src/viz/claude_tab.rsto mount this crate (follow-up).