@vincemakes/kiso-tui-cells 0.24.4 → 0.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -376,22 +376,6 @@ export declare const CAP_PREVIEW = 5;
376
376
  /** The rows a card costs besides its window: two pads, the head, two
377
377
  * blanks and the status row. Below this there is no card (DC-43). */
378
378
  export declare const CARD_CHROME = 6;
379
- /**
380
- * 0.24.2 ③ — the appended expansion, as a CARD.
381
- *
382
- * `ctrl+o` used to append bare ground under a `✦` — the turn recap's own
383
- * mark, one symbol for two meanings (§4.1) — in a page where every other
384
- * piece of machine work is a card. And it lands after the recap, so the
385
- * only tie to the call it came from was that mark's sentence.
386
- *
387
- * The card's head row names the call, which is the tie, so the mark is
388
- * not needed for it. The body is the WHOLE result: an expansion that
389
- * capped would be no expansion.
390
- *
391
- * Expanding IN PLACE is a different problem — committed rows are final
392
- * (§7.1) — and it waits for route B (DC-50).
393
- */
394
- export declare function expandedCard(verb: string, target: string, meta: string, sections: readonly string[], outcome: string, W: number): string[];
395
379
  /** 0.24.2 ② — the live region's `thinking…` placeholder: dim italic at
396
380
  * column 2, no glyph, the SAME shape a thinking paragraph takes so that
397
381
  * whatever arrives replaces it in place. Never committed — see the
@@ -771,15 +771,6 @@ class ToolExecution {
771
771
  // a pipe with the colour stripped. A failure keeps its colour
772
772
  // AND its words — see settledMeta.
773
773
  const body = toolBlockParts(c, W, ctx).rows;
774
- if (body.length > 0 && c.expanded) {
775
- // An EXPANDED block is already showing everything, and its own
776
- // footer ("ctrl+o collapses") is what closes it. Giving it an
777
- // outcome row as well would put two closing rows on one block
778
- // and move the metadata off a head row every width gate pins.
779
- // It takes the SURFACE and nothing else.
780
- const head = c.isError ? ` ${p.red}${text}${p.reset}` : ` ${text}`;
781
- return slabBlock(appendSuffix(head, expandSuffix(hidden, W - visibleWidth(head))), body, null, W);
782
- }
783
774
  if (body.length > 0) {
784
775
  // R13 — THE CARD, when there is something to preview: the head
785
776
  // row names the call, the preview sits inside, and the outcome
@@ -804,8 +795,34 @@ class ToolExecution {
804
795
  // what happened and how long it took — is never cut open.
805
796
  const join = (...xs) => xs.filter((x) => x !== "").join(" · ");
806
797
  const attr = approvedBy.replace(/^ · /, "");
807
- const words = pickTier([join(meta, counted, `${elapsed}s`, attr), join(meta, counted, `${elapsed}s`), join(meta, `${elapsed}s`), meta], W - visibleWidth(noteIndent()));
808
- const outcome = c.isError ? `${p.red}${words}${p.reset}` : words;
798
+ // DC-50 / R14: the key is RESERVED (§7.5), so its width comes
799
+ // out of the budget BEFORE the tiers are picked — not
800
+ // appended after, which is what the first build did and
801
+ // which let a narrow row cut the affordance off entirely.
802
+ // The tier ladder is what gives way; the key never is.
803
+ const keySuffix = c.expanded ? ` · ${COLLAPSE_ROW}` : "";
804
+ const words = pickTier([join(meta, counted, `${elapsed}s`, attr), join(meta, counted, `${elapsed}s`), join(meta, `${elapsed}s`), meta], W - visibleWidth(noteIndent()) - keySuffix.length);
805
+ // DC-50 / R14 — ONE CARD, ONE SKELETON, expanded or not.
806
+ //
807
+ // The expanded card used to take a DIFFERENT shape: its head
808
+ // row carried the outcome inline (`shell npm test · exit 0 ·
809
+ // 40 lines · 0.1s`), it had no outcome row at all, and the
810
+ // `ctrl+o collapses` affordance was a row of its own at the
811
+ // end of the body. That was defensible while an expanded card
812
+ // was rare — reachable only for a live or approval-parked
813
+ // cell — and it stopped being defensible the moment ctrl+o
814
+ // became a switch that expands EVERY settled card at once: a
815
+ // page where the same call has two skeletons depending on a
816
+ // global toggle is the instability this round is named for.
817
+ //
818
+ // So both states are pad · head · blank · body · blank ·
819
+ // outcome · pad. The head row says WHAT was run and nothing
820
+ // else; the outcome row says what happened, how much, how
821
+ // long — and carries the affordance, because the affordance
822
+ // is a fact about this card's state and the outcome row is
823
+ // where this card's facts live.
824
+ const withKey = `${words}${keySuffix}`;
825
+ const outcome = c.isError ? `${p.red}${withKey}${p.reset}` : withKey;
809
826
  return slabBlock(head, body, outcome, W);
810
827
  }
811
828
  // R13 — nothing to preview: the SAME card, three rows, with the
@@ -1570,30 +1587,20 @@ function slabBlock(head, body, outcome, W) {
1570
1587
  return [...top, slabRow("", W)];
1571
1588
  return [...top, slabRow("", W), ...noteRow(outcome, W, "body").map((r) => slabRow(r, W)), slabRow("", W)];
1572
1589
  }
1573
- /**
1574
- * 0.24.2 the appended expansion, as a CARD.
1590
+ /*
1591
+ * RETIRED (DC-50 / R14, 2026-09-05) `expandedCard`.
1575
1592
  *
1576
- * `ctrl+o` used to append bare ground under a `✦` the turn recap's own
1577
- * mark, one symbol for two meanings (§4.1) in a page where every other
1578
- * piece of machine work is a card. And it lands after the recap, so the
1579
- * only tie to the call it came from was that mark's sentence.
1593
+ * It drew the APPENDED block the old ctrl+o produced: a card printed far
1594
+ * below the call it belonged to, which is why its head row had to carry
1595
+ * `expanded · N turns back` and why its body carried section headers
1596
+ * around the raw input and output. All of that was addressing a way
1597
+ * for a copy to say which original it was a copy of.
1580
1598
  *
1581
- * The card's head row names the call, which is the tie, so the mark is
1582
- * not needed for it. The body is the WHOLE result: an expansion that
1583
- * capped would be no expansion.
1584
- *
1585
- * Expanding IN PLACE is a different problem — committed rows are final
1586
- * (§7.1) — and it waits for route B (DC-50).
1599
+ * DC-50 removes the copy. An expanded card is the ordinary `toolCard`
1600
+ * with `expanded` set, rendered where the call stands, so nothing needs
1601
+ * to say where it came from. Its shape is gated in
1602
+ * `r13-rhythm-surface.test.ts`.
1587
1603
  */
1588
- export function expandedCard(verb, target, meta, sections, outcome, W) {
1589
- const p = palette();
1590
- const head = cutLine(` ${verb} ${p.bold}${escapeTerminal(target)}${p.reset}${slabPaints() ? p.washDim : p.dim} · ${escapeTerminal(meta)}${slabPaints() ? p.washDimEnd : p.reset}`, W);
1591
- const body = [];
1592
- for (const raw of sections)
1593
- for (const row of blockRows(raw, W, slabPaints() ? "body" : "dim"))
1594
- body.push(row);
1595
- return slabBlock(head, body, outcome, W);
1596
- }
1597
1604
  /** 0.24.2 ② — the live region's `thinking…` placeholder: dim italic at
1598
1605
  * column 2, no glyph, the SAME shape a thinking paragraph takes so that
1599
1606
  * whatever arrives replaces it in place. Never committed — see the
@@ -1687,7 +1694,13 @@ function toolBlockParts(c, W, ctx) {
1687
1694
  // rides a block that HAS rows — an expanded delegate whose summary
1688
1695
  // marker is missing renders nothing, and a lone footer under a head
1689
1696
  // row would be an affordance for an empty block.
1690
- if (c.expanded && rows.length > 0)
1697
+ //
1698
+ // DC-50 / R14: a SETTLED card carries the affordance on its OUTCOME
1699
+ // row instead, so that both states have one skeleton. This footer is
1700
+ // for the states that have no outcome row to carry it — a card parked
1701
+ // for approval, or one still running that was expanded before it
1702
+ // settled.
1703
+ if (c.expanded && rows.length > 0 && c.state !== "done")
1691
1704
  rows.push(...foldLine(`${p.dim}${noteIndent()}${COLLAPSE_ROW}${p.reset}`, W));
1692
1705
  // R9 P2: `└` opens a block that has no surface. Inside a slab the
1693
1706
  // surface IS the container, and a corner in it is §1.3's empty mark
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vincemakes/kiso-tui-cells",
3
- "version": "0.24.4",
3
+ "version": "0.25.0",
4
4
  "description": "kiso tui-cells — the components cell renderer (components, diff, width, the render slice). Zero runtime dependencies: input is data, output is bytes.",
5
5
  "type": "module",
6
6
  "license": "MIT",