@vincemakes/kiso-tui-cells 0.24.5 → 0.26.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 +27 -204
- package/dist/components.js +161 -582
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/render.d.ts +13 -17
- package/dist/render.js +54 -19
- package/dist/strings.js +32 -34
- package/dist/width.d.ts +8 -0
- package/dist/width.js +20 -0
- package/package.json +1 -1
package/dist/components.d.ts
CHANGED
|
@@ -40,18 +40,6 @@ export interface FrameCtx {
|
|
|
40
40
|
* the tier table reads H, so a resize RE-TIERS instead of
|
|
41
41
|
* re-folding frozen rows). */
|
|
42
42
|
readonly height: number;
|
|
43
|
-
/** R7a — this cell is drawn UNDER an activity header that carries the
|
|
44
|
-
* breathing mark, so its own head row wears a plain gutter.
|
|
45
|
-
*
|
|
46
|
-
* The mark belongs to the ACTIVITY, not to each call in it. A
|
|
47
|
-
* four-file burst drew four breathing marks, which is four marks
|
|
48
|
-
* distinguishing nothing (law 1.3, the same ground R2 retired the
|
|
49
|
-
* tick and cross on) — and worse, on a read that finishes in
|
|
50
|
-
* 200ms the mark is gone before the eye lands, so per-row it is
|
|
51
|
-
* motion that never resolves into meaning. On the header it is lit
|
|
52
|
-
* for the whole stretch, which is the fact it is there to carry:
|
|
53
|
-
* work is in flight. Owner-ruled 2026-08-31. */
|
|
54
|
-
readonly grouped?: boolean;
|
|
55
43
|
/** R13 E2 / DC-43 — how many PREVIEW rows a running card may take this
|
|
56
44
|
* frame. Undefined is the full window (`CAP_PREVIEW`); the compositor
|
|
57
45
|
* lowers it when the live region is tight, and 0 degrades the card to
|
|
@@ -77,7 +65,8 @@ export declare function foldLine(line: string, W: number): string[];
|
|
|
77
65
|
* renderer can measure without importing this module back — the
|
|
78
66
|
* re-export is verbatim, so every existing importer and the barrel see
|
|
79
67
|
* exactly what they saw. */
|
|
80
|
-
export { visibleWidth } from "./width.js";
|
|
68
|
+
export { visibleWidth, widthCut } from "./width.js";
|
|
69
|
+
export { cutLine } from "./render.js";
|
|
81
70
|
/** A component: render the display lines for one piece of state. */
|
|
82
71
|
export interface Component {
|
|
83
72
|
render(width: number, ctx: FrameCtx): string[];
|
|
@@ -90,7 +79,7 @@ export interface Component {
|
|
|
90
79
|
* `prev` is the previous sibling's OWN rows (raw — a cell's own blank
|
|
91
80
|
* must never count toward its height). The blank is a JOIN artifact:
|
|
92
81
|
* the cell's own render stays blank-free, so per-cell accounting
|
|
93
|
-
* (heights, the
|
|
82
|
+
* (heights, the line cache) never sees a fake row. */
|
|
94
83
|
export declare function bodySpacing(prev: readonly string[] | null, rows: readonly string[]): string[];
|
|
95
84
|
/** The container — vertical concatenation with the W11 formula. No
|
|
96
85
|
* component decides its own spacing: every blank in the body is the
|
|
@@ -133,9 +122,9 @@ export type BodyCell = {
|
|
|
133
122
|
* rows and redraws them); a committed cell can never toggle
|
|
134
123
|
* (history is never rewritten — ADR-0046). */
|
|
135
124
|
expanded: boolean;
|
|
136
|
-
/** W14: the
|
|
137
|
-
*
|
|
138
|
-
*
|
|
125
|
+
/** W14: the index of the turn record that created this cell
|
|
126
|
+
* (−1 before the first turn). The checklist reads it: a task
|
|
127
|
+
* list belongs to its turn. */
|
|
139
128
|
turn: number;
|
|
140
129
|
/** W19: a DENIED call's reason (the CLI extracted it from the
|
|
141
130
|
* result's "[Permission denied] " prefix, keyed on the "denied"
|
|
@@ -229,6 +218,24 @@ export declare function cellComponent(cell: BodyCell): Component;
|
|
|
229
218
|
* (the gutter's 2 cells), so a long line hard-folds INSIDE the chip
|
|
230
219
|
* and invariant ① holds on the band. */
|
|
231
220
|
export declare function pendingQueueRows(lines: readonly string[], W: number): string[];
|
|
221
|
+
/**
|
|
222
|
+
* TUI2-R1.5 ⑨ (VD-10) — the WORD-aware fold, for text a human reads.
|
|
223
|
+
*
|
|
224
|
+
* foldLine is a hard character fold at the width. That is exactly right
|
|
225
|
+
* for verbatim tool output, where a byte is a byte and a break is a
|
|
226
|
+
* display artefact the reader knows to ignore; it is exactly wrong for
|
|
227
|
+
* prose, where the reader's eye has to reassemble "ex" + "pected" into a
|
|
228
|
+
* word it already knew. The walkthrough read three of those off one
|
|
229
|
+
* screen.
|
|
230
|
+
*
|
|
231
|
+
* The implementation is a wrapper, not a second engine: the text is cut
|
|
232
|
+
* at the last space that fits and each resulting segment is handed to
|
|
233
|
+
* foldLine, which keeps the SGR close/reopen discipline, the display-
|
|
234
|
+
* width arithmetic and the newline handling in ONE place. A word longer
|
|
235
|
+
* than the width falls through to foldLine's hard break — an
|
|
236
|
+
* overflowing row would violate invariant ①, and a word that cannot fit
|
|
237
|
+
* has to be broken somewhere.
|
|
238
|
+
*/
|
|
232
239
|
export declare function foldWords(line: string, W: number): string[];
|
|
233
240
|
export declare function gutterFold(gutter: string, line: string, W: number): string[];
|
|
234
241
|
/** A6: the tool-header variant — ONE cut row, never a fold. A wide
|
|
@@ -239,81 +246,7 @@ export declare function gutterFold(gutter: string, line: string, W: number): str
|
|
|
239
246
|
* full content. The budget: the gutter's own visible width + the
|
|
240
247
|
* ellipsis ride the row (the invariant ① cap holds). */
|
|
241
248
|
export declare function gutterCut(gutter: string, line: string, W: number): string[];
|
|
242
|
-
export declare function expandSuffix(lines: number | null, room: number): string;
|
|
243
|
-
/**
|
|
244
|
-
* TUI2-R2 ⑤ (D, candidate 1) — the FOCUS tint.
|
|
245
|
-
*
|
|
246
|
-
* The cell the next ctrl+o will act on brightens its own `ctrl+o` token
|
|
247
|
-
* to the code tint; the rest of the suffix — the separator, the count —
|
|
248
|
-
* stays dim, because what is being marked is the KEY's target, not the
|
|
249
|
-
* row. Zero new rows, zero new columns: the affordance the cell already
|
|
250
|
-
* prints is the marker.
|
|
251
|
-
*
|
|
252
|
-
* Applied to a row rather than composed into it on purpose. The token is
|
|
253
|
-
* emitted from several places (the settled suffix, the renderer's own
|
|
254
|
-
* `└ +N … · ctrl+o` cut rows) and threading a flag through all of them
|
|
255
|
-
* would put the invariant "exactly one bright token" in as many hands as
|
|
256
|
-
* there are emitters. Here it has exactly one.
|
|
257
|
-
*
|
|
258
|
-
* NO_COLOR: p.dim is empty, so the row's bytes are untouched.
|
|
259
|
-
*/
|
|
260
|
-
export declare function focusToken(row: string, W: number): string;
|
|
261
|
-
/** W13 — the rollup opt-in table: which tools collapse, and the count
|
|
262
|
-
* NOUN (read_file calls → "5 files", list_dir → "5 dirs", search_text
|
|
263
|
-
* → "5 matches"). Only these tools opt in — a shell burst is never
|
|
264
|
-
* rolled up (its rows carry meaning). The folded-turn line (W14) reuses
|
|
265
|
-
* the plurals for its other-tool terms ("2 dirs", "1 match"). */
|
|
266
|
-
export declare const ROLLUP_NOUN: Readonly<Record<string, string>>;
|
|
267
|
-
/** TUI2-R1 (B) — the verb column of the expanded list names the ACT.
|
|
268
|
-
* TUI2-R2pre ④: this used to be a private three-tool table saying the
|
|
269
|
-
* same thing as the card head's `_file` strip, in a different way and
|
|
270
|
-
* for a different set of tools. Both are `displayVerb` now — the whole
|
|
271
|
-
* point of the ruling is that there is ONE answer to "what does the
|
|
272
|
-
* screen call this". The cut note, which used to be the deliberate
|
|
273
|
-
* exception here, moved with it (see toolCutNote). */
|
|
274
|
-
/** Whether a tool joins an exploration run. Exactly the read-only set —
|
|
275
|
-
* writes, edits, shells and extension tools never group (a burst of
|
|
276
|
-
* side effects is a list of things that HAPPENED, and every row of it
|
|
277
|
-
* carries meaning). */
|
|
278
|
-
export declare function isExploreTool(name: string): boolean;
|
|
279
|
-
/** Does this tool's fold term count distinct targets rather than calls? */
|
|
280
|
-
export declare function foldCountsObjects(name: string): boolean;
|
|
281
249
|
export declare function foldTerms(reads: number, edits: number, others: readonly [string, number][]): string[];
|
|
282
|
-
/**
|
|
283
|
-
* R3i — THE STRETCH LINE: the turn's one working row, in three phases.
|
|
284
|
-
*
|
|
285
|
-
* A STRETCH is the run of thinking and tool calls between two blocks of
|
|
286
|
-
* the model's prose. While it runs it is this line plus a bounded act
|
|
287
|
-
* window; when it closes it commits as this same line, frozen, with its
|
|
288
|
-
* key. The contract in one sentence: **the line you watch is the line
|
|
289
|
-
* you keep** — the settle changes the mark, the tense and the key, and
|
|
290
|
-
* nothing else.
|
|
291
|
-
*
|
|
292
|
-
* thinking ✧ thinking 4s
|
|
293
|
-
* acting ✶ reading 6 files · running 4 shell commands
|
|
294
|
-
* settled ✦ thought 9s · read 6 files · ran 4 shell commands · ctrl+o
|
|
295
|
-
*
|
|
296
|
-
* THE GIVE-WAY LADDER, in order, because at some width everything
|
|
297
|
-
* cannot fit:
|
|
298
|
-
*
|
|
299
|
-
* 1. the human's WORDS (the A9 chip on a quiet turn) — they are on
|
|
300
|
-
* screen above, in the chip band;
|
|
301
|
-
* 2. the NOUNS compact, cheapest word first, and stop as soon as the
|
|
302
|
-
* row fits — buying one cell must not spend every substitution;
|
|
303
|
-
* 3. the COUNTS cut, with the honest "…";
|
|
304
|
-
* 4. the TROUBLE CLAUSE cuts. The design first said it never gives
|
|
305
|
-
* way, and that was unimplementable: a long clause overflows after
|
|
306
|
-
* the counts have already cut to a bare "…", and invariant ①
|
|
307
|
-
* throws on that row;
|
|
308
|
-
* 5. the KEY gives way NEVER. A fold with no key is the turn's work
|
|
309
|
-
* behind a line with no way back to it, which is the one thing
|
|
310
|
-
* this row must not be.
|
|
311
|
-
*
|
|
312
|
-
* `…` in this file means CUT HERE and nothing else — which is why the
|
|
313
|
-
* live phases carry no trailing ellipsis for in-flight, though the
|
|
314
|
-
* reference implementation uses one. The moving mark and the present
|
|
315
|
-
* tense already say it twice.
|
|
316
|
-
*/
|
|
317
250
|
/**
|
|
318
251
|
* R3i phase 5 — THE ANSWERED QUESTION'S BLOCK.
|
|
319
252
|
*
|
|
@@ -331,7 +264,7 @@ export declare function foldTerms(reads: number, edits: number, others: readonly
|
|
|
331
264
|
* is emphasis, never information). A typed answer says `(typed)`,
|
|
332
265
|
* because where an answer came from is a fact about it.
|
|
333
266
|
*
|
|
334
|
-
* It is WORDS, not work (law 1.7):
|
|
267
|
+
* It is WORDS, not work (law 1.7): no summary ever stands for it,
|
|
335
268
|
* because the one thing a summary must not do is speak for the human.
|
|
336
269
|
*
|
|
337
270
|
* A result that is not the ask's own JSON yields NOTHING. This renderer
|
|
@@ -339,113 +272,16 @@ export declare function foldTerms(reads: number, edits: number, others: readonly
|
|
|
339
272
|
* would be a row the product cannot stand behind.
|
|
340
273
|
*/
|
|
341
274
|
export declare function askedBlock(resultText: string, seconds: number, W: number): string[];
|
|
342
|
-
export interface StretchTerms {
|
|
343
|
-
/** the segment's OWN measured thinking seconds; 0 drops the term */
|
|
344
|
-
readonly thoughtSeconds: number;
|
|
345
|
-
/** the segment's calls as [tool name, count], in first-call order.
|
|
346
|
-
* Object-counting tools are deduped by target upstream (R3h). */
|
|
347
|
-
readonly calls: readonly (readonly [string, number])[];
|
|
348
|
-
/** the targets acted on — read only when the stretch made exactly
|
|
349
|
-
* ONE call, where naming the target says everything the two rows it
|
|
350
|
-
* replaces said (see the one-call rule below). */
|
|
351
|
-
readonly targets: readonly string[];
|
|
352
|
-
/** the trouble the stretch met: [kind, count, what it was]. */
|
|
353
|
-
readonly trouble: readonly (readonly ["failed" | "denied" | "interrupted", number, string])[];
|
|
354
|
-
/** R4 — the tool names that still have a call IN FLIGHT. The tense is
|
|
355
|
-
* PER TERM, not per line: a stretch whose shell has finished while a
|
|
356
|
-
* read runs says `ran 1 shell command · reading 1 file`. The whole
|
|
357
|
-
* line used to go progressive, which the standing act slot made a
|
|
358
|
-
* visible contradiction — the gap frame put `running npm run check`
|
|
359
|
-
* directly above a row reading `(exit 0, 12.4s)`. Absent ⇒ every
|
|
360
|
-
* term takes the line's own tense, which is what the settled line
|
|
361
|
-
* wants. */
|
|
362
|
-
readonly liveNames?: readonly string[];
|
|
363
|
-
/** A9 — the human's words, on a QUIET turn's fold only. */
|
|
364
|
-
readonly words?: string;
|
|
365
|
-
/** the live mark; the caller passes the spinner's current frame. */
|
|
366
|
-
readonly mark?: string;
|
|
367
|
-
}
|
|
368
275
|
/** The caps — screen rows counted AFTER the fold, at the current width
|
|
369
276
|
* (the W7 table). The renderer-cut row is inside the cap. */
|
|
370
277
|
/** R13 — ONE preview cap, every tool. It was the shell's alone while
|
|
371
278
|
* the shell was the only settled call with rows on screen. */
|
|
372
279
|
export declare const CAP_PREVIEW = 5;
|
|
373
|
-
/** DC-46 — the running window's ceiling is the SETTLED preview's, and a
|
|
374
|
-
* running card reaches it by growing rather than by being handed it.
|
|
375
|
-
* `LIVE_WINDOW` (CAP_PREVIEW + 1) retires with the allocation it sized. */
|
|
376
|
-
/** The rows a card costs besides its window: two pads, the head, two
|
|
377
|
-
* blanks and the status row. Below this there is no card (DC-43). */
|
|
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
280
|
/** 0.24.2 ② — the live region's `thinking…` placeholder: dim italic at
|
|
396
281
|
* column 2, no glyph, the SAME shape a thinking paragraph takes so that
|
|
397
282
|
* whatever arrives replaces it in place. Never committed — see the
|
|
398
283
|
* compositor's #project for why that is what makes it allowed. */
|
|
399
284
|
export declare function thinkingRow(): string;
|
|
400
|
-
/**
|
|
401
|
-
* R4 — the standing act slot.
|
|
402
|
-
*
|
|
403
|
-
* The stretch's ONE line sits above it; this is the region under it,
|
|
404
|
-
* and it STANDS: allocated when the stretch opens, released at the
|
|
405
|
-
* fold.
|
|
406
|
-
*
|
|
407
|
-
* R3i built the same window INTERMITTENTLY — a running call got its
|
|
408
|
-
* fixed 1+3 block (W8), a finished one got nothing — so the live
|
|
409
|
-
* region's height was a function of how many calls happened to be in
|
|
410
|
-
* flight this frame. Over one real stretch that is 2 rows, then 7,
|
|
411
|
-
* then 2, then 17 for a three-call batch, then 2 again, and every
|
|
412
|
-
* transition scrolls everything above it. The owner's report was that
|
|
413
|
-
* the screen "keeps jumping", and it was an accurate description of
|
|
414
|
-
* the design, not a defect in its execution.
|
|
415
|
-
*
|
|
416
|
-
* The cure is not a smaller window, it is a STANDING one: between two
|
|
417
|
-
* calls the slot keeps the call that just finished rather than
|
|
418
|
-
* collapsing, and before any call it keeps the thinking that is
|
|
419
|
-
* producing them — which is R3i ruling 5 ("thinking belongs on the
|
|
420
|
-
* stretch line, IN THE ACT WINDOW, and in full in expansions") finally
|
|
421
|
-
* wired, since R3i stated it while building no window for the thinking
|
|
422
|
-
* phase to live in.
|
|
423
|
-
*
|
|
424
|
-
* Four rows, deliberately the same 1+3 shape W8 gave a running call, so
|
|
425
|
-
* the commonest frame — exactly one call in flight — renders byte-for-
|
|
426
|
-
* byte what 0.17.0 shipped.
|
|
427
|
-
*/
|
|
428
|
-
export declare const ACT_SLOT_ROWS = 4;
|
|
429
|
-
/**
|
|
430
|
-
* R4 — the slot's body rows: the tail of `text`, newest at the BOTTOM,
|
|
431
|
-
* bottom-padded to exactly `rows`.
|
|
432
|
-
*
|
|
433
|
-
* The same dim │ gutter a running call's window uses (W2's table), and
|
|
434
|
-
* the same two VD-4 rules: leading blank gutters are skipped, and the
|
|
435
|
-
* short-output pad goes at the BOTTOM so output starts under its own
|
|
436
|
-
* header and grows downward. The slot's CONTENTS change; its shape
|
|
437
|
-
* does not.
|
|
438
|
-
*/
|
|
439
|
-
export declare function slotTail(text: string, W: number, rows: number): string[];
|
|
440
|
-
/** R4 — clamp or pad assembled slot rows to EXACTLY `rows`. The padding
|
|
441
|
-
* is what makes the slot stand; the clamp is what keeps the slot from
|
|
442
|
-
* ever being the thing that trips the force-commit cap (a slot that
|
|
443
|
-
* could overflow would commit real cells to relieve blank rows). */
|
|
444
|
-
export declare function slotPad(content: readonly string[], rows: number): string[];
|
|
445
|
-
/** R4 — the slot's overflow row: the calls in flight beyond the head
|
|
446
|
-
* budget. It lives INSIDE the slot (it is one of the four rows), which
|
|
447
|
-
* is what keeps a parallel burst from growing the region. */
|
|
448
|
-
export declare function moreRunningRow(n: number, W: number): string;
|
|
449
285
|
/** The approval mini-diff (W7): capped at 12 folded rows — the head +
|
|
450
286
|
* the named middle (the renderer cut — what was cut, how to expand) +
|
|
451
287
|
* the tail. The rows are folded at the current width BEFORE the cap —
|
|
@@ -467,16 +303,6 @@ export declare function diffBody(diff: import("./diff.js").DiffLine[] | null, W:
|
|
|
467
303
|
* done-collapse. Every live row CUTS at W (never folds) — the block's
|
|
468
304
|
* height is its row count. */
|
|
469
305
|
export declare const CAP_TASK_LIVE = 6;
|
|
470
|
-
/** W20 — the live block's fixed-window row cut: an SGR-aware ONE-ROW
|
|
471
|
-
* truncation (foldLine wraps; a wrapped row would break the height
|
|
472
|
-
* cap — every live row is exactly one screen row at every width).
|
|
473
|
-
* A line that fits (≤ W) passes through whole; an overflow cuts the
|
|
474
|
-
* content at W−1 — the ellipsis's slot — and the ellipsis rides AFTER
|
|
475
|
-
* the reset (post-reset — the PTY needles' convention). The cut row
|
|
476
|
-
* never exceeds W (invariant ①). W21: exported for the approval
|
|
477
|
-
* panel's single-row lines (the rule line, the title, the divider,
|
|
478
|
-
* the options/affordance rows). */
|
|
479
|
-
export declare function cutLine(line: string, W: number): string;
|
|
480
306
|
/** W20 — the settled block's duration, the `2h 14m` form (the task
|
|
481
307
|
* narrative's long-horizon idiom): minutes+seconds under an hour,
|
|
482
308
|
* hours+minutes past it. */
|
|
@@ -503,11 +329,8 @@ export declare function formatDuration(totalSeconds: number): string;
|
|
|
503
329
|
* survives longest because it is the door to everything; `ctrl+r`
|
|
504
330
|
* outranks `↑ history` because pressing up is how a person finds the
|
|
505
331
|
* history by accident, and nothing finds ctrl+r by accident. */
|
|
506
|
-
export declare function idleHint(room: number): string;
|
|
507
|
-
export declare function statusLine(status: string, tail: string, W: number, hint?: string): string;
|
|
508
|
-
/** The display-width prefix of a plain (SGR-free) text. W21: exported
|
|
509
|
-
* for the approval panel's option-2 rule-name cut. */
|
|
510
|
-
export declare function widthCut(text: string, max: number): string;
|
|
332
|
+
export declare function idleHint(room: number, expand?: "expand all" | "collapse all" | null): string;
|
|
333
|
+
export declare function statusLine(status: string, tail: string, W: number, hint?: string, expand?: "expand all" | "collapse all" | null): string;
|
|
511
334
|
/**
|
|
512
335
|
* TUI2-R3v2 ① — THE selection bar. One engine, every selection surface.
|
|
513
336
|
*
|