@vincemakes/kiso-tui 0.16.1 → 0.16.3

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.
@@ -52,7 +52,7 @@ export interface AtPanelState {
52
52
  readonly selected: number;
53
53
  readonly capped: boolean;
54
54
  }
55
- import { type ResumeMeta } from "./render.js";
55
+ import { type BannerMeta, type ResumeMeta } from "./render.js";
56
56
  /** The cursor marker — an APC private sequence the focus component
57
57
  * embeds at the edit position; the compositor strips it and moves
58
58
  * relatively (it never reaches the terminal). */
@@ -171,7 +171,7 @@ export declare class Body {
171
171
  * list re-gates with the tier (BIG only) and re-times with the
172
172
  * frame. The inactive path keeps the historical bytes (no resume —
173
173
  * the pipe contract). */
174
- banner(version: string, extensionsText: string, resume?: ResumeMeta[]): void;
174
+ banner(version: string, extensionsText: string, resume?: ResumeMeta[], meta?: BannerMeta | undefined): void;
175
175
  raw(lines: string[], wrap?: "words"): void;
176
176
  /** The last COMPLETE thinking block, for /think. */
177
177
  lastThinking(): string | null;
@@ -239,6 +239,20 @@ export declare class Body {
239
239
  * that choice here, and has to pay carefully.
240
240
  */
241
241
  onResize(): void;
242
+ /**
243
+ * DC-3 — the ground arrived, so every colour on the held screen is
244
+ * stale.
245
+ *
246
+ * The terminal answers `OSC 11` a few milliseconds after startup, by
247
+ * which time the first frame is already painted with the no-ground
248
+ * palette. Rather than delay the opening to wait for an answer that
249
+ * may never come, the frame is painted at once and repainted when the
250
+ * answer lands. Invalidating the held screen is exactly what a resize
251
+ * does, for exactly the same reason — every row's bytes are wrong —
252
+ * so it rides the settle the resize already owns and costs one
253
+ * repaint, once per session.
254
+ */
255
+ onGroundChange(): void;
242
256
  /** W18: the status row's right-aligned hint is part of the status
243
257
  * state — the compacting row passes "esc to cancel" (the affordance
244
258
  * must survive repaints). */
@@ -295,6 +309,8 @@ export declare class Dock {
295
309
  enter(): void;
296
310
  exit(): void;
297
311
  onResize(): void;
312
+ /** DC-3 — the terminal answered what its background is; repaint. */
313
+ onGroundChange(): void;
298
314
  /** TUI2-R3v2 ②: where the last frame put the panel's clickable option
299
315
  * rows (absolute screen rows). The editor binds this and does no row
300
316
  * arithmetic of its own. */
@@ -706,21 +706,21 @@ export class Body {
706
706
  * list re-gates with the tier (BIG only) and re-times with the
707
707
  * frame. The inactive path keeps the historical bytes (no resume —
708
708
  * the pipe contract). */
709
- banner(version, extensionsText, resume = []) {
709
+ banner(version, extensionsText, resume = [], meta) {
710
710
  if (!this.#isActive()) {
711
711
  this.#closeOpenThinking();
712
712
  this.#closeOpenText();
713
713
  const W = this.#opts.width() || 80; // a 0-size pty falls back
714
714
  const H = this.#opts.height();
715
715
  const p = palette();
716
- for (const r of bannerLines(W, H, version, extensionsText))
716
+ for (const r of bannerLines(W, H, version, extensionsText, [], Date.now(), meta))
717
717
  this.#write(`${p.dim}${r}${p.reset}\n`);
718
718
  this.#write("\n");
719
719
  return;
720
720
  }
721
721
  this.#closeOpenThinking();
722
722
  this.#closeOpenText();
723
- this.#cells.push({ kind: "banner", version, extensionsText, resume, done: true });
723
+ this.#cells.push({ kind: "banner", version, extensionsText, resume, meta, done: true });
724
724
  this.#mark();
725
725
  }
726
726
  raw(lines, wrap) {
@@ -1092,6 +1092,23 @@ export class Body {
1092
1092
  if (this.#resizeTimer.unref !== undefined)
1093
1093
  this.#resizeTimer.unref();
1094
1094
  }
1095
+ /**
1096
+ * DC-3 — the ground arrived, so every colour on the held screen is
1097
+ * stale.
1098
+ *
1099
+ * The terminal answers `OSC 11` a few milliseconds after startup, by
1100
+ * which time the first frame is already painted with the no-ground
1101
+ * palette. Rather than delay the opening to wait for an answer that
1102
+ * may never come, the frame is painted at once and repainted when the
1103
+ * answer lands. Invalidating the held screen is exactly what a resize
1104
+ * does, for exactly the same reason — every row's bytes are wrong —
1105
+ * so it rides the settle the resize already owns and costs one
1106
+ * repaint, once per session.
1107
+ */
1108
+ onGroundChange() {
1109
+ this.#screen = [];
1110
+ this.onResize();
1111
+ }
1095
1112
  /** The one repaint a drag earns, once its signals have stopped. */
1096
1113
  #settleResize() {
1097
1114
  if (!this.#resizePending || !this.#isActive())
@@ -2323,6 +2340,10 @@ export class Dock {
2323
2340
  onResize() {
2324
2341
  compositorRef?.onResize();
2325
2342
  }
2343
+ /** DC-3 — the terminal answered what its background is; repaint. */
2344
+ onGroundChange() {
2345
+ compositorRef?.onGroundChange();
2346
+ }
2326
2347
  /** TUI2-R3v2 ②: where the last frame put the panel's clickable option
2327
2348
  * rows (absolute screen rows). The editor binds this and does no row
2328
2349
  * arithmetic of its own. */
package/dist/editor.d.ts CHANGED
@@ -56,6 +56,15 @@ export declare class Editor {
56
56
  #private;
57
57
  readonly closed: Promise<void>;
58
58
  constructor(onRender: () => void);
59
+ /**
60
+ * DC-7 — the terminal answering a question kiso asked it.
61
+ *
62
+ * The body is everything between `ESC ]` and the terminator, verbatim
63
+ * and unparsed (`11;rgb:ffff/ffff/ffff`). The editor's job ends at
64
+ * keeping it out of the draft; deciding what a report MEANS belongs to
65
+ * whoever asked the question.
66
+ */
67
+ onOsc(cb: (body: string) => void): void;
59
68
  onLine(cb: (line: string) => void): void;
60
69
  onSigint(cb: () => void): void;
61
70
  onEot(cb: () => void): void;
package/dist/editor.js CHANGED
@@ -81,6 +81,11 @@ const TAB = 0x09;
81
81
  * the geometry stays legal down to the compositor's enter gate (H = 4
82
82
  * ⇒ one row, exactly today's minimum). */
83
83
  const N_MAX = 6;
84
+ /** DC-7 — the longest OSC kiso will hold while waiting for a terminator.
85
+ * The reports it reads are tens of bytes; anything past this is a
86
+ * payload for someone else, and holding it is how the editor goes
87
+ * deaf. */
88
+ const OSC_MAX = 1024;
84
89
  /** The dim "…" — the ONE truncation mark: the horizontal scroll's
85
90
  * prefix (unchanged) and the viewport's hidden-rows markers. */
86
91
  const ELLIPSIS = "\x1b[2m…\x1b[0m";
@@ -270,6 +275,19 @@ export class Editor {
270
275
  #history = [];
271
276
  #historyIdx = null;
272
277
  #preBrowse = [];
278
+ // UD-1: minimal draft undo. Two stacks of FROZEN snapshots beside
279
+ // the one mutable buffer (the KC1 flat-buffer discipline holds —
280
+ // the stacks are history, never a second projection). A checkpoint
281
+ // is pushed only by a gesture about to discard ≥1 code point (the
282
+ // kills, the menu-esc clear, each queue-pop replacement, the
283
+ // @-apply splice); typing and single backspace push nothing — v1
284
+ // is loss-recovery, not char-granular edit history. ctrl+z
285
+ // restores text+cursor exactly; ctrl+y mirrors; undo never
286
+ // discards (what it replaces always lands on the redo stack).
287
+ // Both stacks clear on submit/clearLine — a sent turn is in the
288
+ // durable log and the ↑ history, not a loss.
289
+ #undoStack = [];
290
+ #redoStack = [];
273
291
  // W22: the pending-turn queue's bound state — the CLI's live slots
274
292
  // (chat.ts). ↑ pops the LAST queued message into the buffer and
275
293
  // enters the pop-mode (the walk: repeated ↑ pop older ones, each
@@ -280,7 +298,9 @@ export class Editor {
280
298
  #queueState = () => [];
281
299
  #queuePop = null;
282
300
  #queuePopMode = false;
283
- #pending = ""; // an incomplete ESC/CSI prefix across chunks
301
+ #pending = ""; // an incomplete ESC/CSI/OSC prefix across chunks
302
+ /** DC-7: the terminal's own reports (OSC). Never a keystroke. */
303
+ #oscCb = null;
284
304
  #decoder = new TextDecoder();
285
305
  #entered = false;
286
306
  #onData;
@@ -293,6 +313,17 @@ export class Editor {
293
313
  this.#closedResolve = resolve;
294
314
  });
295
315
  }
316
+ /**
317
+ * DC-7 — the terminal answering a question kiso asked it.
318
+ *
319
+ * The body is everything between `ESC ]` and the terminator, verbatim
320
+ * and unparsed (`11;rgb:ffff/ffff/ffff`). The editor's job ends at
321
+ * keeping it out of the draft; deciding what a report MEANS belongs to
322
+ * whoever asked the question.
323
+ */
324
+ onOsc(cb) {
325
+ this.#oscCb = cb;
326
+ }
296
327
  onLine(cb) {
297
328
  this.#lineCb = cb;
298
329
  // Flush submits that arrived before the handler was wired (typed
@@ -355,6 +386,8 @@ export class Editor {
355
386
  return this.#sheetOpen;
356
387
  }
357
388
  clearLine() {
389
+ this.#undoStack.length = 0; // UD-1
390
+ this.#redoStack.length = 0;
358
391
  this.#chars = [];
359
392
  this.#cursor = 0;
360
393
  this.#scroll = 0;
@@ -577,6 +610,8 @@ export class Editor {
577
610
  if (view === null)
578
611
  return;
579
612
  const insert = [...`@${view.matches[view.selected].path} `].map((ch) => ch.codePointAt(0));
613
+ if (this.#cursor - view.start >= 1)
614
+ this.#checkpoint(); // UD-1
580
615
  this.#chars.splice(view.start, this.#cursor - view.start, ...insert);
581
616
  this.#cursor = view.start + insert.length;
582
617
  this.#atClose();
@@ -1084,6 +1119,32 @@ export class Editor {
1084
1119
  this.#csi(m[1], m[2]);
1085
1120
  i += m[0].length + 1;
1086
1121
  }
1122
+ else if (rest.startsWith("]")) {
1123
+ // DC-7: an OSC is a message FROM the terminal — a background
1124
+ // colour answer, a theme-change notice, a clipboard report.
1125
+ // There was no branch for it, so the bytes fell through to
1126
+ // the literal-text path and the answer was typed into the
1127
+ // draft. The terminator is BEL **or** ST: Apple Terminal
1128
+ // answers `ESC ] 11 ; rgb:… BEL`, and ST is the standard.
1129
+ const end = /\x07|\x1b\\/.exec(rest);
1130
+ if (end === null) {
1131
+ const tail = text.slice(i);
1132
+ // The unterminated case is the SGR-1006 hazard by another
1133
+ // door: park it and a stream that never terminates grows
1134
+ // #pending forever until the editor goes deaf. A report
1135
+ // long enough to be a payload (OSC 52 carries a whole
1136
+ // clipboard) is not one we read, so past the cap it is
1137
+ // dropped rather than held.
1138
+ if (tail.length > OSC_MAX) {
1139
+ i = text.length;
1140
+ break;
1141
+ }
1142
+ this.#pending = tail; // incomplete OSC — wait for more
1143
+ break;
1144
+ }
1145
+ this.#oscCb?.(rest.slice(1, end.index));
1146
+ i += 1 + end.index + end[0].length;
1147
+ }
1087
1148
  else if (rest.startsWith("O")) {
1088
1149
  i += 3; // SS3 (function keys) — ignored
1089
1150
  }
@@ -1102,6 +1163,8 @@ export class Editor {
1102
1163
  // v3 §04: Esc closes the menu and clears the buffer.
1103
1164
  // CA-4: the closing esc consumes its burst (the `i += 1`
1104
1165
  // convention) — a double-esc can never abort the turn.
1166
+ if (this.#chars.length > 0)
1167
+ this.#checkpoint(); // UD-1
1105
1168
  this.#chars = [];
1106
1169
  this.#cursor = 0;
1107
1170
  this.#scroll = 0;
@@ -1201,6 +1264,14 @@ export class Editor {
1201
1264
  this.#killWord();
1202
1265
  i += 1;
1203
1266
  }
1267
+ else if (c === "\x1a" || c === "\x1f") {
1268
+ this.#undoOp(); // UD-1: ctrl+z (and the readline ctrl+_)
1269
+ i += 1;
1270
+ }
1271
+ else if (c === "\x19") {
1272
+ this.#redoOp(); // UD-1: ctrl+y
1273
+ i += 1;
1274
+ }
1204
1275
  else if (c === "\x01") {
1205
1276
  this.#cursor = this.#cursorBounds().start; // A3: line-local (a single line starts at 0 — unchanged)
1206
1277
  this.#reflow();
@@ -1891,8 +1962,66 @@ export class Editor {
1891
1962
  if (!this.#pasting)
1892
1963
  this.#onRender();
1893
1964
  }
1965
+ // ---- UD-1: the undo machinery ----
1966
+ /** The caps: entries and total code points (a D13-class 260KB paste
1967
+ * fits with room). Evict oldest; both stacks share the shape. */
1968
+ static #UNDO_CAP = 64;
1969
+ static #UNDO_CP_CAP = 2 * 1024 * 1024;
1970
+ #snap() {
1971
+ return { chars: [...this.#chars], cursor: this.#cursor };
1972
+ }
1973
+ #sameSnap(a, b) {
1974
+ return a.cursor === b.cursor && a.chars.length === b.chars.length && a.chars.every((c, i) => c === b.chars[i]);
1975
+ }
1976
+ #capStack(stack) {
1977
+ while (stack.length > _a.#UNDO_CAP)
1978
+ stack.shift();
1979
+ let total = stack.reduce((n, s) => n + s.chars.length, 0);
1980
+ while (stack.length > 1 && total > _a.#UNDO_CP_CAP)
1981
+ total -= stack.shift().chars.length;
1982
+ }
1983
+ /** Push the CURRENT state before a destructive gesture. Always
1984
+ * clears the redo stack (a new destruction forks history); the
1985
+ * push itself is deduped against the top. */
1986
+ #checkpoint() {
1987
+ this.#redoStack.length = 0;
1988
+ const cur = this.#snap();
1989
+ const top = this.#undoStack.at(-1);
1990
+ if (top !== undefined && this.#sameSnap(top, cur))
1991
+ return;
1992
+ this.#undoStack.push(cur);
1993
+ this.#capStack(this.#undoStack);
1994
+ }
1995
+ #restoreSnap(s) {
1996
+ this.#chars = [...s.chars];
1997
+ this.#cursor = s.cursor;
1998
+ this.#scroll = 0;
1999
+ this.#verticalGoalCol = null;
2000
+ this.#reflow();
2001
+ this.#refreshMenu();
2002
+ if (!this.#pasting)
2003
+ this.#onRender();
2004
+ }
2005
+ #undoOp() {
2006
+ const prev = this.#undoStack.pop();
2007
+ if (prev === undefined)
2008
+ return;
2009
+ this.#redoStack.push(this.#snap());
2010
+ this.#capStack(this.#redoStack);
2011
+ this.#restoreSnap(prev);
2012
+ }
2013
+ #redoOp() {
2014
+ const next = this.#redoStack.pop();
2015
+ if (next === undefined)
2016
+ return;
2017
+ this.#undoStack.push(this.#snap());
2018
+ this.#capStack(this.#undoStack);
2019
+ this.#restoreSnap(next);
2020
+ }
1894
2021
  #killToStart() {
1895
2022
  const { start } = this.#cursorBounds(); // A3: line-local (0 on a single line — unchanged)
2023
+ if (this.#cursor > start)
2024
+ this.#checkpoint(); // UD-1
1896
2025
  this.#chars.splice(start, this.#cursor - start);
1897
2026
  this.#cursor = start;
1898
2027
  this.#reflow();
@@ -1901,6 +2030,8 @@ export class Editor {
1901
2030
  }
1902
2031
  #killToEnd() {
1903
2032
  const { end } = this.#cursorBounds(); // A3: line-local (the buffer's end on a single line — unchanged)
2033
+ if (end > this.#cursor)
2034
+ this.#checkpoint(); // UD-1
1904
2035
  this.#chars.splice(this.#cursor, end - this.#cursor);
1905
2036
  this.#reflow();
1906
2037
  if (!this.#pasting)
@@ -1915,6 +2046,8 @@ export class Editor {
1915
2046
  i -= 1; // trailing spaces
1916
2047
  while (i > 0 && this.#chars[i - 1] !== 0x20)
1917
2048
  i -= 1; // the word
2049
+ if (i < this.#cursor)
2050
+ this.#checkpoint(); // UD-1
1918
2051
  this.#chars.splice(i, this.#cursor - i);
1919
2052
  this.#cursor = i;
1920
2053
  this.#reflow();
@@ -2029,6 +2162,8 @@ export class Editor {
2029
2162
  }
2030
2163
  #takeLine() {
2031
2164
  const line = String.fromCodePoint(...this.#chars);
2165
+ this.#undoStack.length = 0; // UD-1: a sent turn is not a loss
2166
+ this.#redoStack.length = 0;
2032
2167
  this.#chars = [];
2033
2168
  this.#cursor = 0;
2034
2169
  this.#scroll = 0;
@@ -2196,6 +2331,8 @@ export class Editor {
2196
2331
  const line = this.#queuePop();
2197
2332
  if (line === null)
2198
2333
  return;
2334
+ if (this.#chars.length > 0)
2335
+ this.#checkpoint(); // UD-1: a mid-walk edit is recoverable
2199
2336
  this.#chars = [...line].map((ch) => ch.codePointAt(0));
2200
2337
  this.#cursor = this.#chars.length;
2201
2338
  this.#scroll = 0;
package/dist/index.d.ts CHANGED
@@ -10,7 +10,7 @@ export { Body, Dock, CURSOR_MARKER, type BodyOptions } from "./compositor.js";
10
10
  export { panelAffordance, panelBlockRows, panelLead, panelLeadPlain, panelLeadWidth, panelStatus, PICK_MAX, modelPickView, pickAffordance, pickBlockRows, pickLeadPlain, type PickOption, type PickResult, type PickRuntime, type PickSpec, type PanelArgs, type PanelFlavor, type PanelPhase, deletionRiskHint, SAFER_BACK, SAFER_DEGRADED, SAFER_DEGRADED_TRUNCATED, saferDegradedNote, type SaferAnswer, type SaferFailure, type SaferOption, type SaferRuntime, panelOptions, type PanelOption, type PanelOptionKind, type PanelState, type PanelVerdict, type PanelView, } from "./approval-panel.js";
11
11
  export { Container, foldLine, foldWords, visibleWidth, SPINNER, type Component, type FrameCtx } from "./components.js";
12
12
  export { Editor, MENU_ITEMS, PROMPT, PROMPT_WIDTH, displayWidth, charWidth, widthOf, type MenuItem, } from "./editor.js";
13
- export { bannerLines, COLOR_OFF, COLOR_ON, escapeTerminal, foldResult, foldThinking, kUnit, palette, renderEvent, renderRecap, renderResumeList, renderSessionLine, renderStatusLine, relativeTime, renderTerminalGap, renderToolSummary, TAGLINE, toolTarget, truncateRow, type Palette, type PathResolver, type RecapStats, type ResumeMeta, type RenderInput, type RenderResult, type RunUsage, } from "./render.js";
13
+ export { bannerLines, COLOR_OFF, COLOR_ON, currentGround, setGround, escapeTerminal, foldResult, foldThinking, kUnit, palette, renderEvent, renderRecap, renderResumeList, renderSessionLine, renderStatusLine, relativeTime, renderTerminalGap, renderToolSummary, TAGLINE, toolTarget, truncateRow, type Palette, type PathResolver, type RecapStats, type ResumeMeta, type RenderInput, type RenderResult, type RunUsage, } from "./render.js";
14
14
  export { editFileDiff, truncateDiff, writeFileDiff, type DiffLine, type DiffResult } from "./diff.js";
15
15
  export { STATUS_GLYPHS, cacheHitPct, idleStatus, runningStatus, type StatusMeter } from "./status.js";
16
16
  export { contextRows, contextUnavailableRows, type ContextLedger } from "./context-ledger.js";
@@ -18,4 +18,5 @@ export { interactivePrompt, projectTrustRows, projectTrustView, projectUntrusted
18
18
  export { AT_CAP, AT_SKIP, AT_VISIBLE, atEmbed, atFilter, atPanelRows, atWindow, bandHeader, longestRun, type AtItem, type AtMatch } from "./at-picker.js";
19
19
  export { BADGE_GLYPH, idColumn, sessionAge, sessionBadge, sessionCounterRow, sessionFilter, sessionListFooter, sessionListRow, sessionNote, sessionPickerRows, sessionRow, type SessionCardView, type SessionPickState, } from "./session-picker.js";
20
20
  export { ASK_HEADER_CAP, ASK_MAX_OPTIONS, ASK_MAX_QUESTIONS, ASK_MIN_OPTIONS, askAffordance, askAnswers, askBlockRows, askCommitCustom, askDeclineAll, askDeclineList, askKey, askLeadPlain, askStart, askStatus, askView, type AskAnswer, type AskOption, type AskQuestion, type AskResult, type AskRuntime, type AskSpec, type AskStep, } from "./ask-panel.js";
21
+ export { resolveGround, type Ground } from "@vincemakes/kiso-tui-cells";
21
22
  export { KEY_BINDINGS, PANEL_KEYS_ROW, displayVerb, extensionsBannerText, helpRows, keysHelpRow, keysSheetRows, unansweredAskView, type BannerExtension, type KeyBinding } from "./strings.js";
package/dist/index.js CHANGED
@@ -15,7 +15,7 @@ export { panelAffordance, panelBlockRows, panelLead, panelLeadPlain, panelLeadWi
15
15
  PICK_MAX, modelPickView, pickAffordance, pickBlockRows, pickLeadPlain, deletionRiskHint, SAFER_BACK, SAFER_DEGRADED, SAFER_DEGRADED_TRUNCATED, saferDegradedNote, panelOptions, } from "./approval-panel.js";
16
16
  export { Container, foldLine, foldWords, visibleWidth, SPINNER } from "./components.js";
17
17
  export { Editor, MENU_ITEMS, PROMPT, PROMPT_WIDTH, displayWidth, charWidth, widthOf, } from "./editor.js";
18
- export { bannerLines, COLOR_OFF, COLOR_ON, escapeTerminal, foldResult, foldThinking, kUnit, palette, renderEvent, renderRecap, renderResumeList, renderSessionLine, renderStatusLine, relativeTime, renderTerminalGap, renderToolSummary, TAGLINE, toolTarget, truncateRow, } from "./render.js";
18
+ export { bannerLines, COLOR_OFF, COLOR_ON, currentGround, setGround, escapeTerminal, foldResult, foldThinking, kUnit, palette, renderEvent, renderRecap, renderResumeList, renderSessionLine, renderStatusLine, relativeTime, renderTerminalGap, renderToolSummary, TAGLINE, toolTarget, truncateRow, } from "./render.js";
19
19
  export { editFileDiff, truncateDiff, writeFileDiff } from "./diff.js";
20
20
  // KC2 §5: the status rows' formatters — the CLI keeps the state and the
21
21
  // repaint, the terminal layer owns what the row says.
@@ -42,4 +42,5 @@ export { ASK_HEADER_CAP, ASK_MAX_OPTIONS, ASK_MAX_QUESTIONS, ASK_MIN_OPTIONS, as
42
42
  // honestly for a question nobody answered (the ① probe's surface).
43
43
  // TUI2-R1 (D): the keys sheet + THE key table — one source for the ?
44
44
  // overlay and /help's keys row.
45
+ export { resolveGround } from "@vincemakes/kiso-tui-cells";
45
46
  export { KEY_BINDINGS, PANEL_KEYS_ROW, displayVerb, extensionsBannerText, helpRows, keysHelpRow, keysSheetRows, unansweredAskView } from "./strings.js";
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@vincemakes/kiso-tui",
3
- "version": "0.16.1",
4
- "description": "kiso tui \u2014 the pure terminal layer (cell renderer, dock, raw editor, diff, palette). Zero runtime dependencies: input is data, output is bytes.",
3
+ "version": "0.16.3",
4
+ "description": "kiso tui the pure terminal layer (cell renderer, dock, raw editor, diff, palette). Zero runtime dependencies: input is data, output is bytes.",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
7
  "exports": {
@@ -35,6 +35,6 @@
35
35
  },
36
36
  "homepage": "https://github.com/vincemakes/kiso/tree/main/packages/tui#readme",
37
37
  "dependencies": {
38
- "@vincemakes/kiso-tui-cells": "0.16.1"
38
+ "@vincemakes/kiso-tui-cells": "0.16.3"
39
39
  }
40
40
  }