@vincemakes/kiso-tui-cells 0.19.0 → 0.20.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.
- package/dist/components.d.ts +16 -0
- package/dist/components.js +140 -29
- package/dist/render.d.ts +17 -0
- package/dist/render.js +2 -2
- package/dist/strings.d.ts +13 -1
- package/dist/strings.js +13 -1
- package/package.json +1 -1
package/dist/components.d.ts
CHANGED
|
@@ -32,6 +32,18 @@ export interface FrameCtx {
|
|
|
32
32
|
* the tier table reads H, so a resize RE-TIERS instead of
|
|
33
33
|
* re-folding frozen rows). */
|
|
34
34
|
readonly height: number;
|
|
35
|
+
/** R7a — this cell is drawn UNDER an activity header that carries the
|
|
36
|
+
* breathing mark, so its own head row wears a plain gutter.
|
|
37
|
+
*
|
|
38
|
+
* The mark belongs to the ACTIVITY, not to each call in it. A
|
|
39
|
+
* four-file burst drew four breathing marks, which is four marks
|
|
40
|
+
* distinguishing nothing (law 1.3, the same ground R2 retired the
|
|
41
|
+
* tick and cross on) — and worse, on a read that finishes in
|
|
42
|
+
* 200ms the mark is gone before the eye lands, so per-row it is
|
|
43
|
+
* motion that never resolves into meaning. On the header it is lit
|
|
44
|
+
* for the whole stretch, which is the fact it is there to carry:
|
|
45
|
+
* work is in flight. Owner-ruled 2026-08-31. */
|
|
46
|
+
readonly grouped?: boolean;
|
|
35
47
|
}
|
|
36
48
|
/** ONE screen line a component emits (raw, SGR included). */
|
|
37
49
|
export type RenderLine = string;
|
|
@@ -392,7 +404,11 @@ export interface StretchTerms {
|
|
|
392
404
|
*/
|
|
393
405
|
export declare function stretchLine(t: StretchTerms & {
|
|
394
406
|
readonly phase: "thinking" | "acting" | "settled";
|
|
407
|
+
readonly mark?: string;
|
|
395
408
|
}, W: number): string[];
|
|
409
|
+
/** R6/D3: the quiet turn's fold wears no mark either — the SECOND
|
|
410
|
+
* emission site, and the one the D3 brief did not name. Same ruling,
|
|
411
|
+
* same two-space indent; see stretchLine above for the argument. */
|
|
396
412
|
export declare function turnFold(t: {
|
|
397
413
|
words: string;
|
|
398
414
|
thoughtSeconds: number;
|
package/dist/components.js
CHANGED
|
@@ -149,7 +149,10 @@ export function cellComponent(cell) {
|
|
|
149
149
|
case "user":
|
|
150
150
|
return new UserMessage(cell);
|
|
151
151
|
case "thinking":
|
|
152
|
-
|
|
152
|
+
// R7: the committed/live surface is the BLOCK. ThinkingFold
|
|
153
|
+
// survives for the pipe path (render.ts's foldThinking), whose
|
|
154
|
+
// bytes are asserted by the --plain identity gate.
|
|
155
|
+
return new ThinkingBlock(cell);
|
|
153
156
|
case "tool":
|
|
154
157
|
return new ToolExecution(cell);
|
|
155
158
|
case "md":
|
|
@@ -281,6 +284,57 @@ export function pendingQueueRows(lines, W) {
|
|
|
281
284
|
* CJK — 2 cells per char — and tripped invariant ① on a real
|
|
282
285
|
* Chinese session). W2: the leading ⋯ is the thinking gutter — the
|
|
283
286
|
* midline mark (the state), never the text ellipsis (the truncation). */
|
|
287
|
+
/**
|
|
288
|
+
* R7 — THINKING IS A BLOCK OF WORDS.
|
|
289
|
+
*
|
|
290
|
+
* The owner's ruling, arrived at from a side-by-side with pi's screen:
|
|
291
|
+
* the model's reasoning reads as its own paragraphs — italic, dim,
|
|
292
|
+
* indented two — and is never folded away. `ThinkingFold` (below, kept
|
|
293
|
+
* for the pipe path) summarised it to one row with a key; four rounds
|
|
294
|
+
* of machinery were then built to hand the rest back, and the owner's
|
|
295
|
+
* complaint through all of them was the same sentence: I cannot see
|
|
296
|
+
* what it was thinking.
|
|
297
|
+
*
|
|
298
|
+
* THE INDENT IS NOT DECORATION. Law 1.2 is SETTLED — "strip every
|
|
299
|
+
* escape sequence and no fact is lost" — and italic is SGR 3, which a
|
|
300
|
+
* pipe strips and `COLOR_OFF` empties outright. Stripped, an italic
|
|
301
|
+
* paragraph and the model's ANSWER are the same bytes, and the reader
|
|
302
|
+
* cannot tell the reasoning from the reply. The two-space indent is the
|
|
303
|
+
* byte that survives: reasoning sits in, the answer stands at the
|
|
304
|
+
* margin. The owner chose this over the un-indented form for exactly
|
|
305
|
+
* that reason, with the cost stated.
|
|
306
|
+
*
|
|
307
|
+
* Paragraphs are preserved (a blank line between them); the newlines
|
|
308
|
+
* INSIDE a paragraph collapse, because a hard-wrapped source line is
|
|
309
|
+
* the model's line width, not the reader's.
|
|
310
|
+
*/
|
|
311
|
+
class ThinkingBlock {
|
|
312
|
+
cell;
|
|
313
|
+
constructor(cell) {
|
|
314
|
+
this.cell = cell;
|
|
315
|
+
}
|
|
316
|
+
render(W, _ctx) {
|
|
317
|
+
const p = palette();
|
|
318
|
+
const text = escapeTerminal(this.cell.text).trim();
|
|
319
|
+
if (text === "")
|
|
320
|
+
return [];
|
|
321
|
+
const room = Math.max(1, W - 2);
|
|
322
|
+
const rows = [];
|
|
323
|
+
for (const para of text.split(/\n\s*\n/)) {
|
|
324
|
+
const flat = para.replace(/\s+/g, " ").trim();
|
|
325
|
+
if (flat === "")
|
|
326
|
+
continue;
|
|
327
|
+
if (rows.length > 0)
|
|
328
|
+
rows.push("");
|
|
329
|
+
// foldLine is the ONE width authority and returns real rows —
|
|
330
|
+
// invariant ①b (a row is one physical row) holds by
|
|
331
|
+
// construction rather than by remembering to split.
|
|
332
|
+
for (const line of foldLine(flat, room))
|
|
333
|
+
rows.push(` ${p.dim}${p.italic}${line}${p.italicEnd}${p.reset}`);
|
|
334
|
+
}
|
|
335
|
+
return rows;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
284
338
|
class ThinkingFold {
|
|
285
339
|
cell;
|
|
286
340
|
constructor(cell) {
|
|
@@ -687,7 +741,7 @@ class ToolExecution {
|
|
|
687
741
|
// cannot be predicted: a turning mark implies progress the
|
|
688
742
|
// product does not have. With no ground the breath freezes to a
|
|
689
743
|
// static `●` and says the same thing more quietly.
|
|
690
|
-
const out = gutterCut(`${breathFrame(ctx.spinnerI)} `, `${verbCol} ${liveTarget(c)}`, Math.max(4, W - dur.length));
|
|
744
|
+
const out = gutterCut(ctx.grouped === true ? " " : `${breathFrame(ctx.spinnerI)} `, `${verbCol} ${liveTarget(c)}`, Math.max(4, W - dur.length));
|
|
691
745
|
out[0] = `${out[0]}${p.dim}${dur}${p.reset}`;
|
|
692
746
|
out.push(...toolBlockBody(c, W));
|
|
693
747
|
return out;
|
|
@@ -873,7 +927,7 @@ export function focusToken(row, W) {
|
|
|
873
927
|
// attribute like bold is spent everywhere. It closes with washEnd
|
|
874
928
|
// rather than a reset, so the surrounding dim survives instead of
|
|
875
929
|
// having to be re-applied.
|
|
876
|
-
return `${row.slice(0, at)}${p.
|
|
930
|
+
return `${row.slice(0, at)}${p.lift}${CTRL_R}${p.dim}${row.slice(at + CTRL_R.length)}`;
|
|
877
931
|
}
|
|
878
932
|
// A LIVE row does not carry the affordance today, and the live cell is
|
|
879
933
|
// the one ctrl+r takes FIRST (expandNext scans the live tail before
|
|
@@ -885,7 +939,7 @@ export function focusToken(row, W) {
|
|
|
885
939
|
const room = W - visibleWidth(row);
|
|
886
940
|
if (room < SUFFIX_MIN)
|
|
887
941
|
return row; // never at the cost of invariant ①
|
|
888
|
-
return `${row}${p.dim} · ${p.
|
|
942
|
+
return `${row}${p.dim} · ${p.lift}${CTRL_R}${p.reset}`;
|
|
889
943
|
}
|
|
890
944
|
const CTRL_R = "ctrl+r";
|
|
891
945
|
/** TUI2-R1 (A) — the expanded block's last row: the way back. The
|
|
@@ -1248,7 +1302,40 @@ function troubleClause(t) {
|
|
|
1248
1302
|
export function stretchLine(t, W) {
|
|
1249
1303
|
const p = palette();
|
|
1250
1304
|
const live = t.phase !== "settled";
|
|
1251
|
-
|
|
1305
|
+
// DECLARED SUPERSESSION (R6/D3, owner-ruled) — THE STRETCH LINE WEARS
|
|
1306
|
+
// NO MARK, in any phase.
|
|
1307
|
+
//
|
|
1308
|
+
// Law 1.3: a symbol earns its cell by carrying a fact the words do
|
|
1309
|
+
// not. When every settled fold, the live line AND the status row all
|
|
1310
|
+
// wear a star, none of them distinguishes anything — it is the tick
|
|
1311
|
+
// and the cross again (R2 retired those on exactly this ground), at
|
|
1312
|
+
// the stretch scale. design.md §7.4 had already ruled the principle
|
|
1313
|
+
// one scale down: "only the call still running carries a mark,
|
|
1314
|
+
// because only it is moving", with a settled call's mark "(none) —
|
|
1315
|
+
// the outcome is in the words. SETTLED." A settled STRETCH wearing
|
|
1316
|
+
// one contradicted a precedent the file had already ratified.
|
|
1317
|
+
//
|
|
1318
|
+
// Nothing settled is being reversed: §4 lists this mark PROPOSED and
|
|
1319
|
+
// §8 lists it OPEN. This is that proposal's ruling arriving, as a
|
|
1320
|
+
// decline, on the owner's own dogfood.
|
|
1321
|
+
//
|
|
1322
|
+
// The replacement is a two-space INDENT, not a column shift: the row
|
|
1323
|
+
// joins the settled-call family's geometry, the indent survives a
|
|
1324
|
+
// pipe as bytes (prose never starts at column 3), and both forms are
|
|
1325
|
+
// 2 cells so the width ladder below does not reflow. The status row's
|
|
1326
|
+
// twinkle survives as the ONE moving mark; `✦ took` survives as the
|
|
1327
|
+
// turn's seal.
|
|
1328
|
+
//
|
|
1329
|
+
// R7a AMENDS this by ONE case: the live ACTING line takes the
|
|
1330
|
+
// breathing mark, passed in. D3 declined a mark on the SETTLED fold,
|
|
1331
|
+
// where the words already carry the outcome; a line that means "work
|
|
1332
|
+
// is in flight RIGHT NOW" carries a fact its words do not, which is
|
|
1333
|
+
// exactly the test law 1.3 sets. It is also where the mark was
|
|
1334
|
+
// migrating TO: §7.4's "only the call still running carries one" now
|
|
1335
|
+
// applies at the stretch scale, one mark for the activity instead of
|
|
1336
|
+
// one per call. Owner-ruled 2026-08-31, on the ground that a fast
|
|
1337
|
+
// call's per-row mark is gone before the eye lands.
|
|
1338
|
+
const mark = t.mark ?? " ";
|
|
1252
1339
|
// R4a (owner ruling, 2026-08-30) — the fold row prints NO key.
|
|
1253
1340
|
//
|
|
1254
1341
|
// R4 printed `· ctrl+r 3` so the row could name its own target. The
|
|
@@ -1290,6 +1377,9 @@ export function stretchLine(t, W) {
|
|
|
1290
1377
|
const row = `${mark}${words === "" ? "" : ` ${p.rv}${words}${p.rvEnd}${p.dim} ·${p.reset}`} ${meta}${clause === "" ? "" : `${p.red}${clause}${p.reset}`}${key === "" ? "" : `${p.dim}${key}${p.reset}`}`;
|
|
1291
1378
|
return [visibleWidth(row) <= W ? row : cutLine(row, W)];
|
|
1292
1379
|
}
|
|
1380
|
+
/** R6/D3: the quiet turn's fold wears no mark either — the SECOND
|
|
1381
|
+
* emission site, and the one the D3 brief did not name. Same ruling,
|
|
1382
|
+
* same two-space indent; see stretchLine above for the argument. */
|
|
1293
1383
|
export function turnFold(t, W) {
|
|
1294
1384
|
const p = palette();
|
|
1295
1385
|
// R3b (owner, 2026-08-27): ZERO TERMS ARE DROPPED. W14 always wrote
|
|
@@ -1353,13 +1443,13 @@ export function turnFold(t, W) {
|
|
|
1353
1443
|
const keyW = KEY.length;
|
|
1354
1444
|
const key = `${p.dim}${KEY}${p.reset}`;
|
|
1355
1445
|
if (words === "") {
|
|
1356
|
-
const keyed =
|
|
1446
|
+
const keyed = ` ${meta}${key}`;
|
|
1357
1447
|
if (visibleWidth(keyed) <= W)
|
|
1358
1448
|
return [keyed];
|
|
1359
1449
|
let tightMeta = meta;
|
|
1360
1450
|
for (const [long, short] of COMPACT) {
|
|
1361
1451
|
tightMeta = tightMeta.replaceAll(long, short);
|
|
1362
|
-
const tight =
|
|
1452
|
+
const tight = ` ${tightMeta}${key}`;
|
|
1363
1453
|
if (visibleWidth(tight) <= W)
|
|
1364
1454
|
return [tight];
|
|
1365
1455
|
}
|
|
@@ -1375,22 +1465,22 @@ export function turnFold(t, W) {
|
|
|
1375
1465
|
// closed in the thinking fold, still open here. A width with no
|
|
1376
1466
|
// room for the mark is a width with nothing to say: the row is
|
|
1377
1467
|
// a hard cut of what it would have said.
|
|
1378
|
-
const cut =
|
|
1379
|
-
return [visibleWidth(cut) <= W ? cut : cutLine(
|
|
1468
|
+
const cut = ` ${widthCut(tightMeta, Math.max(1, W - 3))}…`;
|
|
1469
|
+
return [visibleWidth(cut) <= W ? cut : cutLine(` ${tightMeta}`, W)];
|
|
1380
1470
|
}
|
|
1381
|
-
return [
|
|
1471
|
+
return [` ${widthCut(tightMeta, room)}…${key}`];
|
|
1382
1472
|
}
|
|
1383
1473
|
// A9 (ruling R2, mock A): the user chip rides the fold — the human's
|
|
1384
1474
|
// words LEAD the one line, the same SGR-7 bracket as the live user
|
|
1385
1475
|
// row (#16f, side pads included). The words take the fold's width
|
|
1386
|
-
// budget: W − the gutter (
|
|
1476
|
+
// budget: W − the gutter (two spaces = 2, R6/D3) − the join (3) − the
|
|
1387
1477
|
// chip's side pads (2) − the cut-tail reserve (1, the "…") − the
|
|
1388
1478
|
// metadata's own width — the metadata survives, the words width-cut
|
|
1389
1479
|
// at the end with the honest "…" (the "…" alone is the honest floor:
|
|
1390
1480
|
// the words were there, cut).
|
|
1391
|
-
const budget = Math.max(0, W - visibleWidth(
|
|
1481
|
+
const budget = Math.max(0, W - visibleWidth(` ${meta}`) - 6 - keyW);
|
|
1392
1482
|
const cut = visibleWidth(words) > budget ? `${widthCut(words, budget)}…` : words;
|
|
1393
|
-
const row =
|
|
1483
|
+
const row = ` ${p.rv} ${cut} ${p.rvEnd} · ${meta}${key}`;
|
|
1394
1484
|
if (visibleWidth(row) <= W)
|
|
1395
1485
|
return [row];
|
|
1396
1486
|
// R3h: the same COMPACT ladder the wordless branch walks — the nouns
|
|
@@ -1398,7 +1488,7 @@ export function turnFold(t, W) {
|
|
|
1398
1488
|
let chipMeta = meta;
|
|
1399
1489
|
for (const [long, short] of COMPACT) {
|
|
1400
1490
|
chipMeta = chipMeta.replaceAll(long, short);
|
|
1401
|
-
const tighter =
|
|
1491
|
+
const tighter = ` ${p.rv} ${cut} ${p.rvEnd} · ${chipMeta}${key}`;
|
|
1402
1492
|
if (visibleWidth(tighter) <= W)
|
|
1403
1493
|
return [tighter];
|
|
1404
1494
|
}
|
|
@@ -1412,10 +1502,10 @@ export function turnFold(t, W) {
|
|
|
1412
1502
|
// bracket's pads, the join and the "…" are ten cells before a
|
|
1413
1503
|
// single character of content, so every width below ten threw
|
|
1414
1504
|
// invariant ① — see the wordless branch above for the same class.
|
|
1415
|
-
const tail =
|
|
1416
|
-
return [visibleWidth(tail) <= W ? tail : cutLine(
|
|
1505
|
+
const tail = ` ${p.rv} ${cut} ${p.rvEnd} · ${widthCut(compactAll(meta), Math.max(1, W - 8 - visibleWidth(cut)))}…`;
|
|
1506
|
+
return [visibleWidth(tail) <= W ? tail : cutLine(` ${p.rv} ${cut} ${p.rvEnd}`, W)];
|
|
1417
1507
|
}
|
|
1418
|
-
return [
|
|
1508
|
+
return [` ${p.rv} ${cut} ${p.rvEnd} · ${widthCut(compactAll(meta), room)}…${key}`];
|
|
1419
1509
|
}
|
|
1420
1510
|
// ---- the bounded-block flow contract (W7, W8, W10) ----
|
|
1421
1511
|
/** The caps — screen rows counted AFTER the fold, at the current width
|
|
@@ -1542,12 +1632,20 @@ function errorBody(c, W) {
|
|
|
1542
1632
|
function liveWindow(text, W) {
|
|
1543
1633
|
const p = palette();
|
|
1544
1634
|
if (text === "") {
|
|
1545
|
-
|
|
1635
|
+
// R7a: blank, not two bare gutters. A `│` marks a row that HAS
|
|
1636
|
+
// content; two of them above "waiting for output" drew a tall
|
|
1637
|
+
// empty bar under every command that had not printed yet — which
|
|
1638
|
+
// is most of them, for their first second.
|
|
1639
|
+
// ...and the waiting row sits DIRECTLY under its header, with the
|
|
1640
|
+
// blanks below it — VD-4's own rule ("the output starts under its
|
|
1641
|
+
// own header and grows downward"), which the gutter rows used to
|
|
1642
|
+
// satisfy by accident and blanks made visible as a two-row gap.
|
|
1643
|
+
return [`${p.dim}${CUT_ROW}waiting for output${p.reset}`, "", ""];
|
|
1546
1644
|
}
|
|
1547
1645
|
const rows = blockRows(text, W);
|
|
1548
1646
|
if (rows.length <= CAP_LIVE_WINDOW) {
|
|
1549
1647
|
while (rows.length < CAP_LIVE_WINDOW)
|
|
1550
|
-
rows.push(
|
|
1648
|
+
rows.push(""); // R7a: blank, not a bar
|
|
1551
1649
|
return rows;
|
|
1552
1650
|
}
|
|
1553
1651
|
const cut = foldLine(`${p.dim}${CUT_ROW}+${rows.length - (CAP_LIVE_WINDOW - 1)} earlier rows · ctrl+r${p.reset}`, W);
|
|
@@ -1593,7 +1691,7 @@ function shellLiveTail(text, W) {
|
|
|
1593
1691
|
return liveWindow("", W);
|
|
1594
1692
|
const kept = rows.slice(Math.max(0, rows.length - (CAP_LIVE_WINDOW - 1)));
|
|
1595
1693
|
while (kept.length < CAP_LIVE_WINDOW - 1)
|
|
1596
|
-
kept.push(
|
|
1694
|
+
kept.push(""); // R7a: blank, not a bar
|
|
1597
1695
|
return [...kept, cutLine(`${p.dim}${CUT_ROW}live tail · esc stop · alt+⏎ redirect${p.reset}`, W)];
|
|
1598
1696
|
}
|
|
1599
1697
|
/**
|
|
@@ -1642,10 +1740,10 @@ export function slotTail(text, W, rows) {
|
|
|
1642
1740
|
const all = blockRows(text, W);
|
|
1643
1741
|
const from = all.findIndex((r) => visibleWidth(r) > visibleWidth(BODY_ROW));
|
|
1644
1742
|
const body = from < 0 ? [] : all.slice(from);
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
return
|
|
1743
|
+
// R7a: no pad. The slot stopped padding (see slotPad) and this was
|
|
1744
|
+
// the same pad by another route — three blank rows under a call with
|
|
1745
|
+
// nothing to say yet, which is the hole a7's blank-run guard prices.
|
|
1746
|
+
return body.slice(Math.max(0, body.length - rows));
|
|
1649
1747
|
}
|
|
1650
1748
|
/** R4 — clamp or pad assembled slot rows to EXACTLY `rows`. The padding
|
|
1651
1749
|
* is what makes the slot stand; the clamp is what keeps the slot from
|
|
@@ -1654,11 +1752,24 @@ export function slotTail(text, W, rows) {
|
|
|
1654
1752
|
export function slotPad(content, rows) {
|
|
1655
1753
|
if (rows <= 0)
|
|
1656
1754
|
return [];
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1755
|
+
// R7a — THE SLOT NO LONGER PADS. It caps, and that is all.
|
|
1756
|
+
//
|
|
1757
|
+
// R4 padded to a fixed height because the slot's content came and
|
|
1758
|
+
// went: a finished call left the block, the block shrank, and every
|
|
1759
|
+
// row above it moved. The pad bought stability with rows drawn as
|
|
1760
|
+
// `│`, which is why a tall empty gutter ran down the screen under
|
|
1761
|
+
// every short block — the owner's own screenshot, and law 1.3's
|
|
1762
|
+
// case: a mark on a row with nothing to mark.
|
|
1763
|
+
//
|
|
1764
|
+
// Blanking the gutter revealed the hole it had been covering, and
|
|
1765
|
+
// the a7 replay priced the hole: blank runs over 2 in 653 of 733
|
|
1766
|
+
// frames, the screen never durably filling. So the pad had to go —
|
|
1767
|
+
// and the height it was buying is now bought by the CONTENT, since
|
|
1768
|
+
// R7a keeps every call's row for the life of the stretch. A block
|
|
1769
|
+
// whose rows only accumulate cannot shrink, so there is nothing
|
|
1770
|
+
// left for a pad to hold up. Measured: 65 of 733 at 40x24, the
|
|
1771
|
+
// pre-R7a number exactly, with the motion gates still green.
|
|
1772
|
+
return content.slice(0, rows);
|
|
1662
1773
|
}
|
|
1663
1774
|
/** R4 — the slot's overflow row: the calls in flight beyond the head
|
|
1664
1775
|
* budget. It lives INSIDE the slot (it is one of the four rows), which
|
package/dist/render.d.ts
CHANGED
|
@@ -77,6 +77,23 @@ export interface Palette {
|
|
|
77
77
|
* spans and must end without stranding them. */
|
|
78
78
|
readonly wash: string;
|
|
79
79
|
readonly washEnd: string;
|
|
80
|
+
/** R7a — THE FOCUS MARKER'S EMPHASIS, and it is not a background.
|
|
81
|
+
*
|
|
82
|
+
* DC-3 gave the `ctrl+r` token the wash, which is a BACKGROUND once
|
|
83
|
+
* a ground is resolved: `48;5;236` on dark reads as a black block
|
|
84
|
+
* behind the key, on a row that is otherwise plain text. The owner
|
|
85
|
+
* asked for it gone. The invariant DC-3 was serving — exactly one
|
|
86
|
+
* bright token per frame, because the key has exactly one target —
|
|
87
|
+
* never required a background; it required CONTRAST against the dim
|
|
88
|
+
* siblings, and full-strength bold foreground is more of it than a
|
|
89
|
+
* wash was.
|
|
90
|
+
*
|
|
91
|
+
* Three escapes because "dim" has two forms here: SGR 2 in the
|
|
92
|
+
* neutral palette, a 256-colour foreground in the resolved ones.
|
|
93
|
+
* 22 cancels the attribute, 39 restores the default foreground, 1
|
|
94
|
+
* is the emphasis. It closes by re-opening the palette's own dim,
|
|
95
|
+
* like `washEnd`, so the surrounding span survives. */
|
|
96
|
+
readonly lift: string;
|
|
80
97
|
readonly reset: string;
|
|
81
98
|
}
|
|
82
99
|
/**
|
package/dist/render.js
CHANGED
|
@@ -28,7 +28,7 @@ const BASE = { bold: "\x1b[1m", dim: "\x1b[2m", red: "\x1b[31m", green: "\x1b[32
|
|
|
28
28
|
* 4's principle exactly: when the ground is unknown, use the thing that
|
|
29
29
|
* is correct on any ground rather than guessing one.
|
|
30
30
|
*/
|
|
31
|
-
const withWash = (wash, washEnd, red = BASE.red, dim = BASE.dim) => ({ ...BASE, red, dim, wash, washEnd, code: wash });
|
|
31
|
+
const withWash = (wash, washEnd, red = BASE.red, dim = BASE.dim) => ({ ...BASE, red, dim, wash, washEnd, code: wash, lift: "\x1b[22m\x1b[39m\x1b[1m" });
|
|
32
32
|
/**
|
|
33
33
|
* DC-3 — one table per ground.
|
|
34
34
|
*
|
|
@@ -56,7 +56,7 @@ export const COLOR_DARK = withWash("\x1b[48;5;236m", "\x1b[49m", "\x1b[38;5;173m
|
|
|
56
56
|
* not been established. Unchanged in every byte except `code`, which
|
|
57
57
|
* was the defect. */
|
|
58
58
|
export const COLOR_ON = COLOR_NEUTRAL;
|
|
59
|
-
export const COLOR_OFF = { bold: "", dim: "", red: "", green: "", warn: "", code: "", italic: "", italicEnd: "", underline: "", underlineEnd: "", rv: "", rvEnd: "", wash: "", washEnd: "", reset: "" };
|
|
59
|
+
export const COLOR_OFF = { bold: "", dim: "", red: "", green: "", warn: "", code: "", italic: "", italicEnd: "", underline: "", underlineEnd: "", rv: "", rvEnd: "", wash: "", washEnd: "", lift: "", reset: "" };
|
|
60
60
|
/** DC-3 — the resolved ground, set once at startup when the terminal
|
|
61
61
|
* answers (see `ground.ts`). It starts UNKNOWN and may stay that way
|
|
62
62
|
* forever; that is a supported state, not a failure. */
|
package/dist/strings.d.ts
CHANGED
|
@@ -155,7 +155,19 @@ export declare function displayVerb(name: string): string;
|
|
|
155
155
|
* The two ask-only gestures keep their clauses because the ask is the
|
|
156
156
|
* only flavor with a set to build and an answer to write.
|
|
157
157
|
*/
|
|
158
|
-
|
|
158
|
+
/**
|
|
159
|
+
* R6/D2 — the row claims only what is TRUE OF EVERY panel.
|
|
160
|
+
*
|
|
161
|
+
* Its old sentence ("⏎ or click confirms · 1-4 instant · space toggles")
|
|
162
|
+
* was documented as true of every flavor, and had silently stopped
|
|
163
|
+
* being: `1-4 instant` is false on the ask's multi-select and on the
|
|
164
|
+
* pick panel (where a digit only moves the cursor and never commits),
|
|
165
|
+
* `or click` is false on both (their frames deliberately report no
|
|
166
|
+
* clickable span), and "1-4" is wrong whenever a panel has a different
|
|
167
|
+
* option count. Layered honesty: this row states the invariant, and each
|
|
168
|
+
* panel's own affordance row states that panel's whole truth.
|
|
169
|
+
*/
|
|
170
|
+
export declare const PANEL_KEYS_ROW = "panels: \u2191\u2193 move \u00B7 \u23CE confirms \u00B7 digits act on their row \u00B7 t types";
|
|
159
171
|
/**
|
|
160
172
|
* TUI2-R1 (D) — the sheet, one screen, static.
|
|
161
173
|
*
|
package/dist/strings.js
CHANGED
|
@@ -249,7 +249,19 @@ export function displayVerb(name) {
|
|
|
249
249
|
* The two ask-only gestures keep their clauses because the ask is the
|
|
250
250
|
* only flavor with a set to build and an answer to write.
|
|
251
251
|
*/
|
|
252
|
-
|
|
252
|
+
/**
|
|
253
|
+
* R6/D2 — the row claims only what is TRUE OF EVERY panel.
|
|
254
|
+
*
|
|
255
|
+
* Its old sentence ("⏎ or click confirms · 1-4 instant · space toggles")
|
|
256
|
+
* was documented as true of every flavor, and had silently stopped
|
|
257
|
+
* being: `1-4 instant` is false on the ask's multi-select and on the
|
|
258
|
+
* pick panel (where a digit only moves the cursor and never commits),
|
|
259
|
+
* `or click` is false on both (their frames deliberately report no
|
|
260
|
+
* clickable span), and "1-4" is wrong whenever a panel has a different
|
|
261
|
+
* option count. Layered honesty: this row states the invariant, and each
|
|
262
|
+
* panel's own affordance row states that panel's whole truth.
|
|
263
|
+
*/
|
|
264
|
+
export const PANEL_KEYS_ROW = "panels: ↑↓ move \u00b7 ⏎ confirms \u00b7 digits act on their row \u00b7 t types";
|
|
253
265
|
/** The sheet's grid: the first six bindings in two 3-column rows, the
|
|
254
266
|
* last four in two 2-column rows (the wide entries get the room). The
|
|
255
267
|
* COLUMN STOPS are the prototype's absolute positions, floored by the
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vincemakes/kiso-tui-cells",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.20.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",
|