Improves how reviewer gates render their content, and adds two small
hooks that make the frontend cooperate with the standalone replay server
(also useful as generic primitives).
Gate body rendering:
- IntroBody: gate intros now render paragraphs plus real bullet lists
with a hanging indent and emphasised bullet lead term, filling the
card width (no narrow measure cap). Backed by introFormat (parser) +
IntroBody (renderer), with tests.
- GateArtifactBody: artifact-review gates whose artifact is a bare file
reference (e.g. {kind:"phase", data:{file:"question.md"}}) now fetch
the referenced session document and render its full content, instead
of showing the file reference as text. Falls back to ArtifactView for
inline-content artifacts and unmapped files. Backed by gateArtifact
(resolver) with tests. ArtifactGateWidget passes sessionId through.
- SelectWidget renders intros via IntroBody.
Replay-friendly session exit:
- AppShell: a system_event {event:"session_exit"} now triggers
stopSession(), returning to the landing view. Generic primitive (the
real backend can emit it too); used by the replay server's "Esci".
- SessionMenu: the ⋮ trigger is now always visible (was opacity-0 /
group-hover only), so Resume is reachable without hovering.
Verified offline against the replay server (no VPN needed); tsc clean.
24 lines
909 B
TypeScript
24 lines
909 B
TypeScript
import { resolveFileArtifact } from "./gateArtifact";
|
|
|
|
test("resolves a bare question.md file reference to its document key", () => {
|
|
expect(resolveFileArtifact({ kind: "phase", data: { file: "question.md" } })).toEqual({
|
|
filename: "question.md",
|
|
docKey: "revised_question",
|
|
});
|
|
});
|
|
|
|
test("resolves a path reference by its basename", () => {
|
|
expect(
|
|
resolveFileArtifact({ kind: "phase", data: { path: "sessions/abc/question.md" } })
|
|
).toEqual({ filename: "question.md", docKey: "revised_question" });
|
|
});
|
|
|
|
test("returns null for inline string content (nothing to resolve)", () => {
|
|
expect(resolveFileArtifact({ kind: "sql", data: "SELECT 42" })).toBeNull();
|
|
expect(resolveFileArtifact({ kind: "cte", content: "SELECT 1" })).toBeNull();
|
|
});
|
|
|
|
test("returns null for an unmapped file", () => {
|
|
expect(resolveFileArtifact({ kind: "phase", data: { file: "notes.txt" } })).toBeNull();
|
|
});
|