practice: the chain table — every reasoning chain in one selectable overlay (owner-approved plan, 2026-09-29)
- core formatChainLine: names + arrow one-liner, singleton marker, pure
- graph-view Chains button (chrome row, empty-graph hidden) opens the
overlay: fuzzy search (names/aliases/statements), collapsible chain →
member → statement rows, birth-session + created columns, no
understanding-levels column
- pinned Selected section derives the agents' actual input live
(chainsForSelection over the selection; premise without its
conclusion shows as the singleton it becomes)
- Generate opens the creation dialog in CUSTOM mode: selection summary
+ dated default title, posts {nodeIds, params, note}; cluster mode
untouched on /practice
- live-verified on the owner's dev server: 219 chains, derived preview,
search-never-filters-Selected, dialog handoff (selection pass-through
bug caught + fixed en route), Esc/backdrop dismiss, zero writes
- practice UI files re-normalized to tabs (my earlier prettier runs had
drifted them to the 2-space default; whitespace-only)
17 render/unit pins added; gates: tsc 0, 1174/1174, lint 0, build 0
This commit is contained in:
@@ -189,6 +189,49 @@ describe("PracticeDialogBody — creation (cluster picker)", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("PracticeDialogBody — creation (CUSTOM mode, the chains overlay's handoff)", () => {
|
||||
const base = {
|
||||
params: { ...DEFAULT_PRACTICE_PARAMS },
|
||||
onParam: () => {},
|
||||
note: "",
|
||||
onNote: () => {},
|
||||
clusters: clusters(),
|
||||
selectedKey: null,
|
||||
onSelect: () => {},
|
||||
busy: false,
|
||||
failure: null as PracticeFailure | null,
|
||||
onOpenSettings: () => {},
|
||||
onClose: () => {},
|
||||
onRun: () => {},
|
||||
};
|
||||
|
||||
it("no cluster picker — the selection summary + dated default title instead", () => {
|
||||
const html = renderToStaticMarkup(
|
||||
<PracticeDialogBody
|
||||
{...base}
|
||||
mode="custom"
|
||||
selection={{ nodeIds: ["n1", "n2", "n3", "n4"], propositions: 4, chains: 2 }}
|
||||
/>,
|
||||
);
|
||||
assert.ok(!html.includes('data-testid="practice-dialog-clusters"'), "custom mode has no picker");
|
||||
assert.ok(html.includes('data-testid="practice-dialog-selection"'));
|
||||
assert.match(html, /Practice — (<!-- -->)?\d{4}-\d{2}-\d{2}/, "the dated default title (the pipeline's own stamp)");
|
||||
assert.ok(html.includes('data-testid="practice-dialog-selection-line"'));
|
||||
assert.ok(html.includes("4 propositions"));
|
||||
assert.ok(html.includes("2 chains"));
|
||||
assert.ok(!html.includes('disabled=""'), "a non-empty selection enables Create immediately");
|
||||
});
|
||||
|
||||
it("dials + note still ride along — the params/note laws are mode-independent", () => {
|
||||
const html = renderToStaticMarkup(
|
||||
<PracticeDialogBody {...base} mode="custom" selection={{ nodeIds: ["n1"], propositions: 1, chains: 1 }} />,
|
||||
);
|
||||
assert.ok(html.includes('data-testid="param-ladder"'));
|
||||
assert.ok(html.includes('data-testid="practice-note"'));
|
||||
assert.ok(html.includes("1 proposition →"));
|
||||
});
|
||||
});
|
||||
|
||||
// ─── the list page ───────────────────────────────────────────────────────────
|
||||
|
||||
describe("PracticeListBody — the set list", () => {
|
||||
|
||||
Reference in New Issue
Block a user