@vincemakes/kiso-tui-cells 0.39.0 → 0.39.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 +12 -0
- package/dist/components.js +23 -8
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/strings.d.ts +3 -11
- package/dist/strings.js +53 -39
- package/package.json +1 -1
package/dist/components.d.ts
CHANGED
|
@@ -318,6 +318,18 @@ export declare function formatDuration(totalSeconds: number): string;
|
|
|
318
318
|
* seconds, because a clock the user is watching tick should not stop
|
|
319
319
|
* ticking. */
|
|
320
320
|
export declare function elapsedLabel(totalSeconds: number): string;
|
|
321
|
+
/** The SETTLED call's duration — R13's grammar (`exit 0 · 90 lines ·
|
|
322
|
+
* 0.4s`). A finished call knows its length to a tenth, which is
|
|
323
|
+
* information a running clock cannot have and a finished one should not
|
|
324
|
+
* throw away: under a minute the tenth stays.
|
|
325
|
+
*
|
|
326
|
+
* Past a minute the tenth stops being the interesting digit and the
|
|
327
|
+
* live label takes over — a twelve-minute call settled as `734.2s`, the
|
|
328
|
+
* same unreadable four-figure count the status row had. NOTHING under a
|
|
329
|
+
* minute moves, which is every duration the suite pinned before this.
|
|
330
|
+
* The suffix is part of the label (the live form's already is), so no
|
|
331
|
+
* caller appends its own `s`. */
|
|
332
|
+
export declare function settledLabel(totalSeconds: number): string;
|
|
321
333
|
/** The status container's row: the status text (+ the tail) with the
|
|
322
334
|
* right-aligned "/ commands · ↑ history" hint in the idle state —
|
|
323
335
|
* the hint CUT FIRST when the width is short (the #16g rule); when
|
package/dist/components.js
CHANGED
|
@@ -644,7 +644,7 @@ class ToolExecution {
|
|
|
644
644
|
out.push(...toolBlockBody(c, W, ctx));
|
|
645
645
|
return out;
|
|
646
646
|
}
|
|
647
|
-
const elapsed = c.startedAt !== null && c.doneAt !== null ? ((c.doneAt - c.startedAt) / 1000)
|
|
647
|
+
const elapsed = c.startedAt !== null && c.doneAt !== null ? settledLabel((c.doneAt - c.startedAt) / 1000) : "?s";
|
|
648
648
|
// TUI2-R1.5 ⑤ (VD-6): the line count is stated EXACTLY ONCE. Every
|
|
649
649
|
// read card carried it twice — `(2 lines, 0.0s) · 2 lines · ctrl+o
|
|
650
650
|
// expands` — because the parens and the suffix were written by
|
|
@@ -726,7 +726,7 @@ class ToolExecution {
|
|
|
726
726
|
// which let a narrow row cut the affordance off entirely.
|
|
727
727
|
// The tier ladder is what gives way; the key never is.
|
|
728
728
|
const keySuffix = c.expanded ? ` · ${COLLAPSE_ROW}` : "";
|
|
729
|
-
const words = pickTier([join(meta, counted,
|
|
729
|
+
const words = pickTier([join(meta, counted, elapsed, attr), join(meta, counted, elapsed), join(meta, elapsed), meta], W - visibleWidth(noteIndent()) - keySuffix.length);
|
|
730
730
|
// DC-50 / R14 — ONE CARD, ONE SKELETON, expanded or not.
|
|
731
731
|
//
|
|
732
732
|
// The expanded card used to take a DIFFERENT shape: its head
|
|
@@ -780,7 +780,7 @@ class ToolExecution {
|
|
|
780
780
|
// ("compil 1s"). The head is cut against the room the duration
|
|
781
781
|
// leaves; the duration then rides the row, always legible.
|
|
782
782
|
const elapsed = c.startedAt !== null ? Math.max(1, Math.round((ctx.now - c.startedAt) / 1000)) : 1;
|
|
783
|
-
const dur = ` · ${elapsed}
|
|
783
|
+
const dur = ` · ${elapsedLabel(elapsed)}`;
|
|
784
784
|
// R3 (design §5.2): a running command BREATHES — one glyph, seven
|
|
785
785
|
// greys, bottoming out on the ground's dim token (§2.2 applies
|
|
786
786
|
// mid-animation, not just at rest). The quadrant spinner it
|
|
@@ -954,18 +954,18 @@ function settledHeadText(verbCol, target, meta, attr, elapsed, room, counted = "
|
|
|
954
954
|
// first, then the count, and the core — what happened and how long it
|
|
955
955
|
// took — is never cut open; below that the target itself truncates.
|
|
956
956
|
const join = (...xs) => xs.filter((x) => x !== "").join(" · ");
|
|
957
|
-
const core = join(meta, counted,
|
|
958
|
-
const withAttr = join(meta, counted,
|
|
957
|
+
const core = join(meta, counted, elapsed);
|
|
958
|
+
const withAttr = join(meta, counted, elapsed, attr.replace(" · ", ""));
|
|
959
959
|
const lead = `${verbCol} `;
|
|
960
960
|
const row = (tail) => `${lead}${target}${tail === "" ? "" : ` · ${tail}`}`;
|
|
961
961
|
// 1. everything; 2. the attribution gives way; 2b. the COUNT gives
|
|
962
962
|
// way next (pin 4), where the suffix is not already carrying it —
|
|
963
963
|
// the target whole through all three
|
|
964
|
-
const whole = firstFit([row(withAttr), row(core), row(join(meta,
|
|
964
|
+
const whole = firstFit([row(withAttr), row(core), row(join(meta, elapsed))], room);
|
|
965
965
|
if (whole !== null)
|
|
966
966
|
return whole;
|
|
967
967
|
// 3. the target truncates, the core stays whole
|
|
968
|
-
const stem = join(meta,
|
|
968
|
+
const stem = join(meta, elapsed);
|
|
969
969
|
const budget = room - visibleWidth(lead) - visibleWidth(stem) - 4; // the ellipsis + " · "
|
|
970
970
|
if (budget >= 1)
|
|
971
971
|
return `${lead}${widthCut(target, budget)}… · ${stem}`;
|
|
@@ -975,7 +975,7 @@ function settledHeadText(verbCol, target, meta, attr, elapsed, room, counted = "
|
|
|
975
975
|
// no bracket to leave open, so the reason retired with the
|
|
976
976
|
// parentheses and pin 4's own rule applies at every width: what
|
|
977
977
|
// happened and how long it took is never cut away.
|
|
978
|
-
const floor =
|
|
978
|
+
const floor = elapsed;
|
|
979
979
|
const left = room - visibleWidth(lead) - visibleWidth(floor) - 4; // the ellipsis + " · "
|
|
980
980
|
if (left >= 1)
|
|
981
981
|
return `${lead}${widthCut(target, left)}… · ${floor}`;
|
|
@@ -1820,6 +1820,21 @@ export function formatDuration(totalSeconds) {
|
|
|
1820
1820
|
export function elapsedLabel(totalSeconds) {
|
|
1821
1821
|
return duration(totalSeconds, true);
|
|
1822
1822
|
}
|
|
1823
|
+
/** The SETTLED call's duration — R13's grammar (`exit 0 · 90 lines ·
|
|
1824
|
+
* 0.4s`). A finished call knows its length to a tenth, which is
|
|
1825
|
+
* information a running clock cannot have and a finished one should not
|
|
1826
|
+
* throw away: under a minute the tenth stays.
|
|
1827
|
+
*
|
|
1828
|
+
* Past a minute the tenth stops being the interesting digit and the
|
|
1829
|
+
* live label takes over — a twelve-minute call settled as `734.2s`, the
|
|
1830
|
+
* same unreadable four-figure count the status row had. NOTHING under a
|
|
1831
|
+
* minute moves, which is every duration the suite pinned before this.
|
|
1832
|
+
* The suffix is part of the label (the live form's already is), so no
|
|
1833
|
+
* caller appends its own `s`. */
|
|
1834
|
+
export function settledLabel(totalSeconds) {
|
|
1835
|
+
const tenths = Math.max(0, Math.round(totalSeconds * 10) / 10);
|
|
1836
|
+
return tenths < 60 ? `${tenths.toFixed(1)}s` : elapsedLabel(tenths);
|
|
1837
|
+
}
|
|
1823
1838
|
/**
|
|
1824
1839
|
* W20 — the task checklist as STATE: ONE live block that redraws in
|
|
1825
1840
|
* place (the current turn's in-place updates), settling at the turn's
|
package/dist/index.d.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* package); the cli never imports it directly. Experimental — no
|
|
7
7
|
* API-stability promise yet.
|
|
8
8
|
*/
|
|
9
|
-
export { SPINNER, foldLine, foldWords, visibleWidth, bodySpacing, Container, cellComponent, foldTerms, CAP_TASK_LIVE, elapsedLabel, formatDuration, statusLine, boxTop, boxBottom, terminalPipe, type FrameCtx, type RenderLine, type Component, type BodyCell, } from "./components.js";
|
|
9
|
+
export { SPINNER, foldLine, foldWords, visibleWidth, bodySpacing, Container, cellComponent, foldTerms, CAP_TASK_LIVE, elapsedLabel, settledLabel, formatDuration, statusLine, boxTop, boxBottom, terminalPipe, type FrameCtx, type RenderLine, type Component, type BodyCell, } from "./components.js";
|
|
10
10
|
export { editFileDiff, truncateDiff, writeFileDiff, type DiffLine, type DiffResult } from "./diff.js";
|
|
11
11
|
export { pendingQueueRows } from "./components.js";
|
|
12
12
|
export { charWidth, displayWidth, leadWidth, widthOf } from "./width.js";
|
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* package); the cli never imports it directly. Experimental — no
|
|
7
7
|
* API-stability promise yet.
|
|
8
8
|
*/
|
|
9
|
-
export { SPINNER, foldLine, foldWords, visibleWidth, bodySpacing, Container, cellComponent, foldTerms, CAP_TASK_LIVE, elapsedLabel, formatDuration, statusLine, boxTop, boxBottom, terminalPipe, } from "./components.js";
|
|
9
|
+
export { SPINNER, foldLine, foldWords, visibleWidth, bodySpacing, Container, cellComponent, foldTerms, CAP_TASK_LIVE, elapsedLabel, settledLabel, formatDuration, statusLine, boxTop, boxBottom, terminalPipe, } from "./components.js";
|
|
10
10
|
export { editFileDiff, truncateDiff, writeFileDiff } from "./diff.js";
|
|
11
11
|
// W22 (the v8 input round): the pending-queue chips — the SAME
|
|
12
12
|
// UserMessage chip with the □ gutter, pre-rendered above the input
|
package/dist/strings.d.ts
CHANGED
|
@@ -188,15 +188,7 @@ export declare function keysSheetRows(W: number): string[];
|
|
|
188
188
|
* sheet renders, joined — so the two can disagree only by deleting a
|
|
189
189
|
* test. The sheet is the readable form; this is the greppable one. */
|
|
190
190
|
export declare function keysHelpRow(): string;
|
|
191
|
-
/**
|
|
192
|
-
*
|
|
193
|
-
|
|
194
|
-
* The rows were eight bodyLog calls in the CLI's dispatcher; they are
|
|
195
|
-
* presentation, and presentation belongs here (the KC3 §1 pattern —
|
|
196
|
-
* the FLOW, which is "print these on the chain, then re-prompt", stays
|
|
197
|
-
* in dispatch.ts). The last row carries its own newline exactly as it
|
|
198
|
-
* did inline: bodyLog splits on \n, so `exit` and `keys` land as two
|
|
199
|
-
* rows from one call — the shape the KC1/KC2/KC3 gestures were added
|
|
200
|
-
* to, unchanged.
|
|
201
|
-
*/
|
|
191
|
+
/** The slash commands `/help` lists. The keys and the `!` gestures in the
|
|
192
|
+
* table are not commands and are not here. */
|
|
193
|
+
export declare function slashCommandNames(): readonly string[];
|
|
202
194
|
export declare function helpRows(): string[];
|
package/dist/strings.js
CHANGED
|
@@ -430,51 +430,65 @@ export function keysHelpRow() {
|
|
|
430
430
|
* rows from one call — the shape the KC1/KC2/KC3 gestures were added
|
|
431
431
|
* to, unchanged.
|
|
432
432
|
*/
|
|
433
|
+
/** The rows `/help` prints, as DATA — the one place that says which
|
|
434
|
+
* commands exist. `helpRows` renders it; `slashCommandNames` asks it
|
|
435
|
+
* whether a word is a command at all, so the dispatcher's error line
|
|
436
|
+
* cannot drift from the list the same screen prints. */
|
|
437
|
+
const HELP_TABLE = [
|
|
438
|
+
["/help", "print this list of commands"],
|
|
439
|
+
["/think", "show the last full thinking block"],
|
|
440
|
+
["/last", "show the most recent tool call's input and output"],
|
|
441
|
+
// R4 (C4d): a committed row is the terminal's, and cannot be
|
|
442
|
+
// re-wrapped in place (ADR-0046) — this appends it re-folded.
|
|
443
|
+
["/rewrap", "re-print the recent prose at the current width"],
|
|
444
|
+
["/copy", "copy the last answer (raw markdown) — ctrl+x does the same"],
|
|
445
|
+
["/status", "show session id, event count, and context estimate"],
|
|
446
|
+
// A command with no row is a command nobody can find. `/context` has
|
|
447
|
+
// been dispatchable since TUI2-R1 slice 6 and was never listed here,
|
|
448
|
+
// so the only way to learn it existed was to read the source.
|
|
449
|
+
["/context", "show where the context went — the per-request rent ledger"],
|
|
450
|
+
["/mode", "show the approval tier; /mode <name> switches (manual/default/accept-edits/plan/bypass)"],
|
|
451
|
+
["/model", "list model profiles; /model <name|provider/model> switches"],
|
|
452
|
+
["/compact", "summarize the older conversation to free context"],
|
|
453
|
+
["/clear", "start a fresh conversation (the old session stays resumable)"],
|
|
454
|
+
["/resume", "switch to another session; /resume <id> goes directly"],
|
|
455
|
+
// §2.5: the conversation is untouched — this rereads what kiso was
|
|
456
|
+
// built with, not what it has said.
|
|
457
|
+
["/reload", "reread extensions, skills and config into this session"],
|
|
458
|
+
// §2.2: the two shell gestures and their one escape. They sit
|
|
459
|
+
// beside the slash commands because that is what a reader is
|
|
460
|
+
// looking for when they look here, even though `!` is not one.
|
|
461
|
+
// §2.3: the switch belongs beside ctrl+o's job, and a gesture the
|
|
462
|
+
// sheet does not name is a gesture nobody uses (DC-30, DC-36).
|
|
463
|
+
["ctrl+t", "fold the thinking blocks, and fold them back"],
|
|
464
|
+
// §2.4: the composer, in your own editor. It names the variables
|
|
465
|
+
// because that is what a reader has to set for it to work.
|
|
466
|
+
["ctrl+g", "edit the composer in $VISUAL or $EDITOR — the text comes back unsent"],
|
|
467
|
+
["!<cmd>", "run a shell command and send it with its output as your turn"],
|
|
468
|
+
["!!<cmd>", "run one and show it here only — the model never sees it"],
|
|
469
|
+
["\\!", "send a line that really starts with ! (the only escape)"],
|
|
470
|
+
["exit", "leave the session"],
|
|
471
|
+
// TUI2-R1 (D): the SENTENCE is deliberately unchanged. Deriving it
|
|
472
|
+
// from KEY_BINDINGS would be an improvement and it would also move
|
|
473
|
+
// an assertion outside the round's declared supersession classes,
|
|
474
|
+
// so the sheet stays the derived surface and this row keeps its
|
|
475
|
+
// words. `keysHelpRow()` exists for the round allowed to swap it;
|
|
476
|
+
// until then the drift guard is the test that every binding in the
|
|
477
|
+
// table is mentioned here. DC-1 changes the PADDING, not the words.
|
|
478
|
+
["keys", "enter sends \u00b7 ctrl+J newline (shift+enter where encoded) \u00b7 esc stops the run \u00b7 alt+\u23ce stops it and sends this instead \u00b7 @ files \u00b7 1-4 answers an ask"],
|
|
479
|
+
];
|
|
480
|
+
/** The slash commands `/help` lists. The keys and the `!` gestures in the
|
|
481
|
+
* table are not commands and are not here. */
|
|
482
|
+
export function slashCommandNames() {
|
|
483
|
+
return HELP_TABLE.map(([name]) => name).filter((n) => n.startsWith("/"));
|
|
484
|
+
}
|
|
433
485
|
export function helpRows() {
|
|
434
486
|
const p = palette();
|
|
435
487
|
// DC-1: ONE description column. The gap used to be four spaces after
|
|
436
488
|
// the name whatever the name's length, so `/help`'s description began
|
|
437
489
|
// three columns left of `/compact`'s and the second column wandered
|
|
438
490
|
// down the list. displayWidth is the authority, as everywhere else.
|
|
439
|
-
const table =
|
|
440
|
-
["/help", "print this list of commands"],
|
|
441
|
-
["/think", "show the last full thinking block"],
|
|
442
|
-
["/last", "show the most recent tool call's input and output"],
|
|
443
|
-
// R4 (C4d): a committed row is the terminal's, and cannot be
|
|
444
|
-
// re-wrapped in place (ADR-0046) — this appends it re-folded.
|
|
445
|
-
["/rewrap", "re-print the recent prose at the current width"],
|
|
446
|
-
["/copy", "copy the last answer (raw markdown) — ctrl+x does the same"],
|
|
447
|
-
["/status", "show session id, event count, and context estimate"],
|
|
448
|
-
["/mode", "show the approval tier; /mode <name> switches (manual/default/accept-edits/plan/bypass)"],
|
|
449
|
-
["/model", "list model profiles; /model <name|provider/model> switches"],
|
|
450
|
-
["/compact", "summarize the older conversation to free context"],
|
|
451
|
-
["/clear", "start a fresh conversation (the old session stays resumable)"],
|
|
452
|
-
["/resume", "switch to another session; /resume <id> goes directly"],
|
|
453
|
-
// §2.5: the conversation is untouched — this rereads what kiso was
|
|
454
|
-
// built with, not what it has said.
|
|
455
|
-
["/reload", "reread extensions, skills and config into this session"],
|
|
456
|
-
// §2.2: the two shell gestures and their one escape. They sit
|
|
457
|
-
// beside the slash commands because that is what a reader is
|
|
458
|
-
// looking for when they look here, even though `!` is not one.
|
|
459
|
-
// §2.3: the switch belongs beside ctrl+o's job, and a gesture the
|
|
460
|
-
// sheet does not name is a gesture nobody uses (DC-30, DC-36).
|
|
461
|
-
["ctrl+t", "fold the thinking blocks, and fold them back"],
|
|
462
|
-
// §2.4: the composer, in your own editor. It names the variables
|
|
463
|
-
// because that is what a reader has to set for it to work.
|
|
464
|
-
["ctrl+g", "edit the composer in $VISUAL or $EDITOR — the text comes back unsent"],
|
|
465
|
-
["!<cmd>", "run a shell command and send it with its output as your turn"],
|
|
466
|
-
["!!<cmd>", "run one and show it here only — the model never sees it"],
|
|
467
|
-
["\\!", "send a line that really starts with ! (the only escape)"],
|
|
468
|
-
["exit", "leave the session"],
|
|
469
|
-
// TUI2-R1 (D): the SENTENCE is deliberately unchanged. Deriving it
|
|
470
|
-
// from KEY_BINDINGS would be an improvement and it would also move
|
|
471
|
-
// an assertion outside the round's declared supersession classes,
|
|
472
|
-
// so the sheet stays the derived surface and this row keeps its
|
|
473
|
-
// words. `keysHelpRow()` exists for the round allowed to swap it;
|
|
474
|
-
// until then the drift guard is the test that every binding in the
|
|
475
|
-
// table is mentioned here. DC-1 changes the PADDING, not the words.
|
|
476
|
-
["keys", "enter sends \u00b7 ctrl+J newline (shift+enter where encoded) \u00b7 esc stops the run \u00b7 alt+\u23ce stops it and sends this instead \u00b7 @ files \u00b7 1-4 answers an ask"],
|
|
477
|
-
];
|
|
491
|
+
const table = HELP_TABLE;
|
|
478
492
|
const stop = Math.max(...table.map(([name]) => displayWidth(name))) + 4;
|
|
479
493
|
const cmd = (name, desc) => `${p.bold}${name}${p.reset}${" ".repeat(stop - displayWidth(name))}${desc}`;
|
|
480
494
|
const rows = table.slice(0, -2).map(([name, desc]) => cmd(name, desc));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vincemakes/kiso-tui-cells",
|
|
3
|
-
"version": "0.39.
|
|
3
|
+
"version": "0.39.2",
|
|
4
4
|
"description": "kiso tui-cells \u2014 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",
|