@vincemakes/kiso-tui-cells 0.24.0 → 0.24.2
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.
- package/dist/components.d.ts +30 -1
- package/dist/components.js +94 -9
- package/package.json +1 -1
package/dist/components.d.ts
CHANGED
|
@@ -8,7 +8,15 @@
|
|
|
8
8
|
* lives HERE: every line a component returns must fit the terminal
|
|
9
9
|
* width — the compositor's crash-on-violation invariant backs it up
|
|
10
10
|
* (a component that forgets to fold CRASHES with a diagnostic, never
|
|
11
|
-
* silently truncates — the crash is the contract
|
|
11
|
+
* silently truncates — the crash is the contract UNDER TEST; in the
|
|
12
|
+
* field the row is cut and the fact is said, once, through the notice
|
|
13
|
+
* channel. DECLARED REVERSAL of "the crash is the contract, not a
|
|
14
|
+
* symptom" (owner-lane, 2026-09-04): two instances of this class in two
|
|
15
|
+
* days, one caught by a gate (DC-45) and one by the owner on the first
|
|
16
|
+
* frame of an ordinary command (DC-48). In a gate the crash is right; in
|
|
17
|
+
* a human's hands it costs them the composer and the session to save
|
|
18
|
+
* them a row one column too wide. `KISO_INVARIANTS=throw` is what every
|
|
19
|
+
* suite here runs under).
|
|
12
20
|
*
|
|
13
21
|
* The fold is SGR-AWARE: a line whose bold/dim span would straddle a
|
|
14
22
|
* fold boundary closes the span at the break and reopens it on the
|
|
@@ -368,6 +376,27 @@ export declare const CAP_PREVIEW = 5;
|
|
|
368
376
|
/** The rows a card costs besides its window: two pads, the head, two
|
|
369
377
|
* blanks and the status row. Below this there is no card (DC-43). */
|
|
370
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
|
+
/** 0.24.2 ② — the live region's `thinking…` placeholder: dim italic at
|
|
396
|
+
* column 2, no glyph, the SAME shape a thinking paragraph takes so that
|
|
397
|
+
* whatever arrives replaces it in place. Never committed — see the
|
|
398
|
+
* compositor's #project for why that is what makes it allowed. */
|
|
399
|
+
export declare function thinkingRow(): string;
|
|
371
400
|
/**
|
|
372
401
|
* R4 — the standing act slot.
|
|
373
402
|
*
|
package/dist/components.js
CHANGED
|
@@ -8,7 +8,15 @@
|
|
|
8
8
|
* lives HERE: every line a component returns must fit the terminal
|
|
9
9
|
* width — the compositor's crash-on-violation invariant backs it up
|
|
10
10
|
* (a component that forgets to fold CRASHES with a diagnostic, never
|
|
11
|
-
* silently truncates — the crash is the contract
|
|
11
|
+
* silently truncates — the crash is the contract UNDER TEST; in the
|
|
12
|
+
* field the row is cut and the fact is said, once, through the notice
|
|
13
|
+
* channel. DECLARED REVERSAL of "the crash is the contract, not a
|
|
14
|
+
* symptom" (owner-lane, 2026-09-04): two instances of this class in two
|
|
15
|
+
* days, one caught by a gate (DC-45) and one by the owner on the first
|
|
16
|
+
* frame of an ordinary command (DC-48). In a gate the crash is right; in
|
|
17
|
+
* a human's hands it costs them the composer and the session to save
|
|
18
|
+
* them a row one column too wide. `KISO_INVARIANTS=throw` is what every
|
|
19
|
+
* suite here runs under).
|
|
12
20
|
*
|
|
13
21
|
* The fold is SGR-AWARE: a line whose bold/dim span would straddle a
|
|
14
22
|
* fold boundary closes the span at the break and reopens it on the
|
|
@@ -864,7 +872,6 @@ class ToolExecution {
|
|
|
864
872
|
const bare = gutterCut(gutter, `${verbCol} ${liveTarget(c)}`, Math.max(4, W - dur.length));
|
|
865
873
|
return [`${bare[0]}${p.dim}${dur}${p.reset}`];
|
|
866
874
|
}
|
|
867
|
-
const head = gutterCut(gutter, `${verbCol} ${liveTarget(c)}`, W)[0];
|
|
868
875
|
// DC-46 — the two GESTURES ride the status row, where they cost
|
|
869
876
|
// nothing. They were a footer INSIDE the window, spending one of
|
|
870
877
|
// its rows on a sentence that is not output; with the window
|
|
@@ -875,7 +882,32 @@ class ToolExecution {
|
|
|
875
882
|
// 3.2s`.
|
|
876
883
|
const gestures = c.name === "shell" ? " · esc stops · alt+⏎ redirects" : "";
|
|
877
884
|
const status = pickTier([`${elapsed}s${gestures}`, `${elapsed}s`], Math.max(1, W - visibleWidth(noteIndent())));
|
|
878
|
-
|
|
885
|
+
const live = toolBlockBody(c, W, ctx);
|
|
886
|
+
if (live.length > 0)
|
|
887
|
+
return slabBlock(gutterCut(gutter, `${verbCol} ${liveTarget(c)}`, W)[0], live, status, W);
|
|
888
|
+
// DC-48 — THE THREE-ROW CARD IS ONE ROW, so it is assembled here
|
|
889
|
+
// against the room it actually has.
|
|
890
|
+
//
|
|
891
|
+
// This branch used to cut the head to `W` and hand it to
|
|
892
|
+
// `slabBlock`, which joins head and outcome and cut nothing —
|
|
893
|
+
// so the row came out `W` wide PLUS the whole status, and the
|
|
894
|
+
// compositor did what it promises: it threw. On the owner's
|
|
895
|
+
// 80-column terminal a long `find` produced a 113-column row on
|
|
896
|
+
// its FIRST FRAME, which is the first second of every command.
|
|
897
|
+
//
|
|
898
|
+
// Pin 4's order: the command is the cuttable span and the
|
|
899
|
+
// elapsed is never cut open, so the command takes what the
|
|
900
|
+
// status leaves — the `· ` between them and the two-column
|
|
901
|
+
// gutter included.
|
|
902
|
+
// the status takes its own tier against the room the row has, not
|
|
903
|
+
// against a whole width: on a narrow terminal the gestures give
|
|
904
|
+
// way so the COMMAND keeps something to say, and the elapsed —
|
|
905
|
+
// pin 4's core — never does.
|
|
906
|
+
const MIN_TARGET = 10; // the gutter, the verb column, a character of command
|
|
907
|
+
const oneRow = pickTier([`${elapsed}s${gestures}`, `${elapsed}s`], Math.max(1, W - MIN_TARGET - 3));
|
|
908
|
+
const room = Math.max(4, W - visibleWidth(oneRow) - 3);
|
|
909
|
+
const only = gutterCut(gutter, `${verbCol} ${liveTarget(c)}`, room)[0];
|
|
910
|
+
return slabBlock(`${only}${p.dim} · ${oneRow}${p.reset}`, [], null, W);
|
|
879
911
|
}
|
|
880
912
|
// W2: ◦ replaces → for QUEUED — · is the separator inside every
|
|
881
913
|
// metadata group; a queued marker that is also the separator
|
|
@@ -1002,8 +1034,16 @@ function settledHeadText(verbCol, target, meta, attr, elapsed, room, counted = "
|
|
|
1002
1034
|
const budget = room - visibleWidth(lead) - visibleWidth(stem) - 4; // the ellipsis + " · "
|
|
1003
1035
|
if (budget >= 1)
|
|
1004
1036
|
return `${lead}${widthCut(target, budget)}… · ${stem}`;
|
|
1005
|
-
// 4.
|
|
1006
|
-
//
|
|
1037
|
+
// 4. DC-48 — the ELAPSED still rides, and the target takes what is
|
|
1038
|
+
// left. This used to return the target alone, on the argument that
|
|
1039
|
+
// a cut core would leave a half-open parenthesis; R13's chain has
|
|
1040
|
+
// no bracket to leave open, so the reason retired with the
|
|
1041
|
+
// parentheses and pin 4's own rule applies at every width: what
|
|
1042
|
+
// happened and how long it took is never cut away.
|
|
1043
|
+
const floor = `${elapsed}s`;
|
|
1044
|
+
const left = room - visibleWidth(lead) - visibleWidth(floor) - 4; // the ellipsis + " · "
|
|
1045
|
+
if (left >= 1)
|
|
1046
|
+
return `${lead}${widthCut(target, left)}… · ${floor}`;
|
|
1007
1047
|
return `${lead}${widthCut(target, Math.max(1, room - visibleWidth(lead)))}`;
|
|
1008
1048
|
}
|
|
1009
1049
|
/**
|
|
@@ -1418,9 +1458,17 @@ const CARD_ROW = " ";
|
|
|
1418
1458
|
/** R13 E3 — the column the model's words begin in, the same one the
|
|
1419
1459
|
* card's rows and the chip's text begin in. */
|
|
1420
1460
|
const PROSE_COL = " ";
|
|
1421
|
-
/** DC-47 — the model's THINKING
|
|
1422
|
-
*
|
|
1423
|
-
|
|
1461
|
+
/** DC-47, ADJUDICATED — the model's THINKING begins in the SAME column
|
|
1462
|
+
* as everything else: two.
|
|
1463
|
+
*
|
|
1464
|
+
* It went to four when E3 moved prose to two, so that stripping the
|
|
1465
|
+
* escapes would still tell them apart (§1.2). The owner looked at it
|
|
1466
|
+
* and ruled against it: "the thinking area is not indented by the same
|
|
1467
|
+
* two as the first line — it needs to keep the same first-line indent
|
|
1468
|
+
* as everything else" (2026-09-04). §1.8's one left edge outranks the
|
|
1469
|
+
* distinction, and §1.2 takes a DECLARED EXCEPTION for this one pair —
|
|
1470
|
+
* see design.md §1.2 and §7.2 for what is given up and what is not. */
|
|
1471
|
+
const THINK_COL = " ";
|
|
1424
1472
|
const bodyRow = () => (slabPaints() ? CARD_ROW : BODY_ROW_FLAT);
|
|
1425
1473
|
const noteIndent = () => (slabPaints() ? CARD_ROW : NOTE_ROW_FLAT);
|
|
1426
1474
|
const CUT_ROW = "└ ";
|
|
@@ -1506,7 +1554,12 @@ function slabBlock(head, body, outcome, W) {
|
|
|
1506
1554
|
// instead — off the surface R8a's indent is still the fact, which is
|
|
1507
1555
|
// why the degradation above keeps it.
|
|
1508
1556
|
if (body.length === 0) {
|
|
1509
|
-
|
|
1557
|
+
// DC-48: the join makes a ROW, so it is cut like every other row.
|
|
1558
|
+
// The callers above size their parts against the room they have;
|
|
1559
|
+
// this is the backstop that makes invariant ① hold whatever they
|
|
1560
|
+
// do, and it is what was missing when a running card's head was
|
|
1561
|
+
// cut to W and then had a whole status appended to it.
|
|
1562
|
+
const only = cutLine(outcome === null ? head : `${head} ${outcome}`, W);
|
|
1510
1563
|
return [slabRow("", W), slabRow(only, W), slabRow("", W)];
|
|
1511
1564
|
}
|
|
1512
1565
|
const top = [slabRow("", W), slabRow(head, W), slabRow("", W), ...body.map((r) => slabRow(r, W))];
|
|
@@ -1517,6 +1570,38 @@ function slabBlock(head, body, outcome, W) {
|
|
|
1517
1570
|
return [...top, slabRow("", W)];
|
|
1518
1571
|
return [...top, slabRow("", W), ...noteRow(outcome, W, "body").map((r) => slabRow(r, W)), slabRow("", W)];
|
|
1519
1572
|
}
|
|
1573
|
+
/**
|
|
1574
|
+
* 0.24.2 ③ — the appended expansion, as a CARD.
|
|
1575
|
+
*
|
|
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.
|
|
1580
|
+
*
|
|
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).
|
|
1587
|
+
*/
|
|
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
|
+
/** 0.24.2 ② — the live region's `thinking…` placeholder: dim italic at
|
|
1598
|
+
* column 2, no glyph, the SAME shape a thinking paragraph takes so that
|
|
1599
|
+
* whatever arrives replaces it in place. Never committed — see the
|
|
1600
|
+
* compositor's #project for why that is what makes it allowed. */
|
|
1601
|
+
export function thinkingRow() {
|
|
1602
|
+
const p = palette();
|
|
1603
|
+
return `${THINK_COL}${p.dim}${p.italic}thinking…${p.italicEnd}${p.reset}`;
|
|
1604
|
+
}
|
|
1520
1605
|
/** R8a — stamp `└` on a block's FIRST row, after every slice and note
|
|
1521
1606
|
* has been assembled, so the mark is always on the first row actually
|
|
1522
1607
|
* emitted rather than on one a cap may have dropped. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vincemakes/kiso-tui-cells",
|
|
3
|
-
"version": "0.24.
|
|
3
|
+
"version": "0.24.2",
|
|
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",
|