@vincemakes/kiso-tui-cells 0.43.0 → 0.44.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.
@@ -493,8 +493,8 @@ export function panelLeadWidth(view, phase, cursor) {
493
493
  * the CLI's painting status (the compositor derives it from the panel
494
494
  * state; the "❯ run paused" etc. ride the options phase). */
495
495
  // R2 (design §4, the ❯ ruling): a panel that is WAITING ON A HUMAN says
496
- // so with the one mark that means it. `▸` is the checklist's "the
497
- // current one" — a mark meaning two things is worse than two marks
496
+ // so with the one mark that means it. `▸` already means "the current
497
+ // one" — a mark meaning two things is worse than two marks
498
498
  // (law 4.2), and the thing this row has to convey is not "here" but
499
499
  // "nothing moves until you answer".
500
500
  export function panelStatus(view, phase, cursor) {
@@ -124,8 +124,7 @@ export type BodyCell = {
124
124
  * (history is never rewritten — ADR-0046). */
125
125
  expanded: boolean;
126
126
  /** W14: the index of the turn record that created this cell
127
- * (−1 before the first turn). The checklist reads it: a task
128
- * list belongs to its turn. */
127
+ * (−1 before the first turn). */
129
128
  turn: number;
130
129
  /** W19: a DENIED call's reason (the CLI extracted it from the
131
130
  * result's "[Permission denied] " prefix, keyed on the "denied"
@@ -192,32 +191,6 @@ export type BodyCell = {
192
191
  label: string;
193
192
  line: string;
194
193
  done: true;
195
- } | {
196
- kind: "checklist";
197
- /** the model-authored header tail (parseChecklist's count line —
198
- * chat.ts). The compositor's fixed "task" prefix rides BEFORE it
199
- * (W20 naming ruling: never model-controlled). */
200
- header: string;
201
- items: {
202
- text: string;
203
- status: "pending" | "active" | "done";
204
- }[];
205
- /** W20: false while LIVE — the current turn's ONE in-place block
206
- * (the commit loop only takes done cells, so it stays in the
207
- * live region); true once SETTLED — endTurn committed it as the
208
- * turn's one recap block. */
209
- done: boolean;
210
- /** W20: the LIVE block's ctrl+o toggle (W15) — the capped form
211
- * flips to the full list in place. The settled render ignores
212
- * it (already full). */
213
- expanded: boolean;
214
- /** W20: the wall clock of the block's FIRST call — the settled
215
- * header's duration is clocked from here, compositor-side (the
216
- * CLI stays unchanged). */
217
- startedAt: number;
218
- /** W20: the run's duration at the settle — the `2h 14m` form. */
219
- durationSeconds: number;
220
- turn: number;
221
194
  };
222
195
  declare const TOOL_SUMMARY_MAX = 60;
223
196
  /** The component for one cell — the mapping table lives here so the
@@ -313,16 +286,6 @@ export declare function thinkingRow(): string;
313
286
  * W21: exported for the approval panel — the expanded path renders
314
287
  * the approval's ALWAYS-verbose args (never the capped copy). */
315
288
  export declare function diffBody(diff: import("./diff.js").DiffLine[] | null, W: number, expanded?: boolean): string[];
316
- /** W20 — the task block's fixed-window height: the whole live block
317
- * (header + rows) in POST-FOLD screen rows at EVERY width: the header,
318
- * the active row, up to 2 pending, the overflow-pending fold, the
319
- * done-collapse. Every live row CUTS at W (never folds) — the block's
320
- * height is its row count. */
321
- export declare const CAP_TASK_LIVE = 6;
322
- /** W20 — the settled block's duration, the `2h 14m` form (the task
323
- * narrative's long-horizon idiom): minutes+seconds under an hour,
324
- * hours+minutes past it. Unchanged. */
325
- export declare function formatDuration(totalSeconds: number): string;
326
289
  /** The LIVE elapsed label — every place a duration is shown while it is
327
290
  * still running, and on the card that settles from it, so a card and the
328
291
  * status row can never disagree.
@@ -331,7 +294,9 @@ export declare function formatDuration(totalSeconds: number): string;
331
294
  * row came to read "working 637s": ten minutes as a four-figure number,
332
295
  * with no branch anywhere that said otherwise. Past an hour it keeps
333
296
  * seconds, because a clock the user is watching tick should not stop
334
- * ticking. */
297
+ * ticking.
298
+ *
299
+ * Negative is clamped: a clock skew is not a negative duration. */
335
300
  export declare function elapsedLabel(totalSeconds: number): string;
336
301
  /** The SETTLED call's duration — R13's grammar (`exit 0 · 90 lines ·
337
302
  * 0.4s`). A finished call knows its length to a tenth, which is
@@ -187,8 +187,6 @@ export function cellComponent(cell) {
187
187
  return new RawBlock(cell);
188
188
  case "terminal":
189
189
  return new TerminalBlock(cell);
190
- case "checklist":
191
- return new Checklist(cell);
192
190
  }
193
191
  }
194
192
  /**
@@ -1800,22 +1798,18 @@ class Banner {
1800
1798
  return bannerLines(W, ctx.height, this.cell.version, this.cell.extensionsText, this.cell.resume, ctx.now, this.cell.meta);
1801
1799
  }
1802
1800
  }
1803
- /** W20 — the task block's fixed-window height: the whole live block
1804
- * (header + rows) in POST-FOLD screen rows at EVERY width: the header,
1805
- * the active row, up to 2 pending, the overflow-pending fold, the
1806
- * done-collapse. Every live row CUTS at W (never folds) — the block's
1807
- * height is its row count. */
1808
- export const CAP_TASK_LIVE = 6;
1809
- /** The two duration idioms, from ONE implementation.
1801
+ /** The LIVE elapsed label — every place a duration is shown while it is
1802
+ * still running, and on the card that settles from it, so a card and the
1803
+ * status row can never disagree.
1810
1804
  *
1811
- * They agree in every branch but the hour: W20's settled task block says
1812
- * `2h 14m` (a long-horizon narrative does not care about seconds), and a
1813
- * LIVE elapsed label says `1h 2m 3s` (a running clock does). A near-copy
1814
- * differing in one branch is the drift that a shared helper exists to
1815
- * prevent, so the branch is a parameter.
1805
+ * It replaced the hand-written second counts, which is how the status
1806
+ * row came to read "working 637s": ten minutes as a four-figure number,
1807
+ * with no branch anywhere that said otherwise. Past an hour it keeps
1808
+ * seconds, because a clock the user is watching tick should not stop
1809
+ * ticking.
1816
1810
  *
1817
1811
  * Negative is clamped: a clock skew is not a negative duration. */
1818
- function duration(totalSeconds, hoursKeepSeconds) {
1812
+ export function elapsedLabel(totalSeconds) {
1819
1813
  const s = Math.max(0, Math.round(totalSeconds));
1820
1814
  if (s < 60)
1821
1815
  return `${s}s`;
@@ -1823,25 +1817,7 @@ function duration(totalSeconds, hoursKeepSeconds) {
1823
1817
  if (m < 60)
1824
1818
  return `${m}m ${s % 60}s`;
1825
1819
  const h = Math.floor(m / 60);
1826
- return hoursKeepSeconds ? `${h}h ${m % 60}m ${s % 60}s` : `${h}h ${m % 60}m`;
1827
- }
1828
- /** W20 — the settled block's duration, the `2h 14m` form (the task
1829
- * narrative's long-horizon idiom): minutes+seconds under an hour,
1830
- * hours+minutes past it. Unchanged. */
1831
- export function formatDuration(totalSeconds) {
1832
- return duration(totalSeconds, false);
1833
- }
1834
- /** The LIVE elapsed label — every place a duration is shown while it is
1835
- * still running, and on the card that settles from it, so a card and the
1836
- * status row can never disagree.
1837
- *
1838
- * It replaced the hand-written second counts, which is how the status
1839
- * row came to read "working 637s": ten minutes as a four-figure number,
1840
- * with no branch anywhere that said otherwise. Past an hour it keeps
1841
- * seconds, because a clock the user is watching tick should not stop
1842
- * ticking. */
1843
- export function elapsedLabel(totalSeconds) {
1844
- return duration(totalSeconds, true);
1820
+ return `${h}h ${m % 60}m ${s % 60}s`;
1845
1821
  }
1846
1822
  /** The SETTLED call's duration — R13's grammar (`exit 0 · 90 lines ·
1847
1823
  * 0.4s`). A finished call knows its length to a tenth, which is
@@ -1858,70 +1834,6 @@ export function settledLabel(totalSeconds) {
1858
1834
  const tenths = Math.max(0, Math.round(totalSeconds * 10) / 10);
1859
1835
  return tenths < 60 ? `${tenths.toFixed(1)}s` : elapsedLabel(tenths);
1860
1836
  }
1861
- /**
1862
- * W20 — the task checklist as STATE: ONE live block that redraws in
1863
- * place (the current turn's in-place updates), settling at the turn's
1864
- * end as ONE recap block. LIVE (done:false): the fixed "task" prefix +
1865
- * the compositor-derived counts (the model tail rides AFTER — never
1866
- * model-controlled), the active item first with ▸ (the menu's "the
1867
- * current one"), pending next (≤2), the done items COLLAPSED behind the
1868
- * W10 cut family `└ +N done · ctrl+o`, overflow pending behind
1869
- * `└ +N more · ctrl+o` — every row cut at W so the cap holds at every
1870
- * width. ctrl+o (W15) toggles the full list in place (expanded). SETTLED
1871
- * (done:true): the recap idiom `task done · N items · <duration>` + the
1872
- * FULL final item list in the checklist's existing shape (▖/□/▣ —
1873
- * indented two, the glyph leads, no │ gutter).
1874
- */
1875
- class Checklist {
1876
- cell;
1877
- constructor(cell) {
1878
- this.cell = cell;
1879
- }
1880
- render(W, _ctx) {
1881
- const p = palette();
1882
- const { items, done, expanded, durationSeconds } = this.cell;
1883
- const active = items.filter((i) => i.status === "active");
1884
- const pending = items.filter((i) => i.status === "pending");
1885
- const doneCount = items.length - active.length - pending.length;
1886
- const plural = (n, word) => `${n} ${word}${n === 1 ? "" : "s"}`;
1887
- const tail = this.cell.header === "" ? "" : ` · ${this.cell.header}`;
1888
- const fixed = done
1889
- ? `task done · ${plural(items.length, "item")} · ${formatDuration(durationSeconds)}`
1890
- : `task · ${plural(items.length, "item")} · ${active.length} active · ${doneCount} done`;
1891
- const header = `${p.bold}✦${p.reset} ${escapeTerminal(fixed + tail)}`;
1892
- // the FULL-list forms: SETTLED — the durable record (the fold is
1893
- // fine — committed content wraps naturally) — and the LIVE ctrl+o
1894
- // toggle (the header CUTS — the block stays one window high; the
1895
- // expanded rows show the ▣ the collapse hid). The live flag picks
1896
- // the glyphs: the settled list keeps the durable ▖, the expanded
1897
- // live list the ▸.
1898
- const glyph = (status, live) => {
1899
- const g = status === "pending" ? "□" : status === "active" ? (live ? "▸" : "▖") : "▣";
1900
- return g === "▸" ? `${p.bold}▸${p.reset}` : g;
1901
- };
1902
- if (done || expanded) {
1903
- const rows = done ? foldLine(header, W) : [cutLine(header, W)];
1904
- for (const item of items)
1905
- rows.push(...foldLine(` ${glyph(item.status, !done)} ${escapeTerminal(item.text)}`, W));
1906
- return rows;
1907
- }
1908
- // LIVE — the fixed window: the header + the item rows CUT at W
1909
- // (one screen row each — the block's height is its row count,
1910
- // CAP_TASK_LIVE, at every width). The cut is the momentary view;
1911
- // the settle (and the ctrl+o toggle) show everything.
1912
- const itemRows = [];
1913
- if (active.length > 0)
1914
- itemRows.push(` ${p.bold}▸${p.reset} ${escapeTerminal(active[0].text)}`);
1915
- for (const item of pending.slice(0, 2))
1916
- itemRows.push(` □ ${escapeTerminal(item.text)}`);
1917
- const more = pending.length - 2;
1918
- if (more > 0)
1919
- itemRows.push(` ${p.dim}└ +${more} more · ctrl+o${p.reset}`);
1920
- if (doneCount > 0)
1921
- itemRows.push(` ${p.dim}└ +${doneCount} done · ctrl+o${p.reset}`);
1922
- return [cutLine(header, W), ...itemRows.map((r) => cutLine(r, W))];
1923
- }
1924
- }
1925
1837
  // ---- the chrome components (the status container, the footer) ----
1926
1838
  /** The status container's row: the status text (+ the tail) with the
1927
1839
  * right-aligned "/ commands · ↑ history" hint in the idle state —
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, settledLabel, 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, elapsedLabel, settledLabel, 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, settledLabel, formatDuration, statusLine, boxTop, boxBottom, terminalPipe, } from "./components.js";
9
+ export { SPINNER, foldLine, foldWords, visibleWidth, bodySpacing, Container, cellComponent, foldTerms, elapsedLabel, settledLabel, 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
@@ -72,14 +72,6 @@ export declare function projectUntrustedNote(count: number, root: string): strin
72
72
  * applied"); what follows it is the action the answer performs. The
73
73
  * invariant a test now holds for every simple view: the dock-less
74
74
  * question names `simpleOptions[0]`, the action `y` performs. */
75
- /**
76
- * TV-1B — the verification offer (the thin task driver's one question):
77
- * shown at a NORMAL settle when every item is claimed done and no
78
- * passing check is fresh. The panel's simple flavor; bare-Enter
79
- * approves, Esc dismisses. The fallback question serves a dock-less
80
- * TTY; non-interactive paths never reach askPanel at all.
81
- */
82
- export declare function verifyOfferView(): PanelView;
83
75
  export declare function uncertainView(name: string, executionId: string): PanelView;
84
76
  /**
85
77
  * KC3.5 — the SAME uncertainty gate, said honestly for an ask_user call.
package/dist/strings.js CHANGED
@@ -83,26 +83,6 @@ export function projectUntrustedNote(count, root) {
83
83
  * applied"); what follows it is the action the answer performs. The
84
84
  * invariant a test now holds for every simple view: the dock-less
85
85
  * question names `simpleOptions[0]`, the action `y` performs. */
86
- /**
87
- * TV-1B — the verification offer (the thin task driver's one question):
88
- * shown at a NORMAL settle when every item is claimed done and no
89
- * passing check is fresh. The panel's simple flavor; bare-Enter
90
- * approves, Esc dismisses. The fallback question serves a dock-less
91
- * TTY; non-interactive paths never reach askPanel at all.
92
- */
93
- export function verifyOfferView() {
94
- return {
95
- flavor: "simple",
96
- name: "verification",
97
- title: "finish the checklist?",
98
- speaker: "kiso",
99
- statusText: "\u23f8 run paused",
100
- args: { kind: "text", lines: [] },
101
- ruleOverride: "every item is marked done \u2014 run a check?",
102
- simpleOptions: ["run a verification pass", "not now"],
103
- fallbackQuestion: "run a verification pass? (y/n) ",
104
- };
105
- }
106
86
  export function uncertainView(name, executionId) {
107
87
  return {
108
88
  flavor: "simple",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vincemakes/kiso-tui-cells",
3
- "version": "0.43.0",
3
+ "version": "0.44.0",
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",