@vincemakes/kiso-tui 0.16.2 → 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.
- package/dist/compositor.d.ts +18 -2
- package/dist/compositor.js +24 -3
- package/dist/editor.d.ts +9 -0
- package/dist/editor.js +45 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/package.json +3 -3
package/dist/compositor.d.ts
CHANGED
|
@@ -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. */
|
package/dist/compositor.js
CHANGED
|
@@ -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";
|
|
@@ -293,7 +298,9 @@ export class Editor {
|
|
|
293
298
|
#queueState = () => [];
|
|
294
299
|
#queuePop = null;
|
|
295
300
|
#queuePopMode = false;
|
|
296
|
-
#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;
|
|
297
304
|
#decoder = new TextDecoder();
|
|
298
305
|
#entered = false;
|
|
299
306
|
#onData;
|
|
@@ -306,6 +313,17 @@ export class Editor {
|
|
|
306
313
|
this.#closedResolve = resolve;
|
|
307
314
|
});
|
|
308
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
|
+
}
|
|
309
327
|
onLine(cb) {
|
|
310
328
|
this.#lineCb = cb;
|
|
311
329
|
// Flush submits that arrived before the handler was wired (typed
|
|
@@ -1101,6 +1119,32 @@ export class Editor {
|
|
|
1101
1119
|
this.#csi(m[1], m[2]);
|
|
1102
1120
|
i += m[0].length + 1;
|
|
1103
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
|
+
}
|
|
1104
1148
|
else if (rest.startsWith("O")) {
|
|
1105
1149
|
i += 3; // SS3 (function keys) — ignored
|
|
1106
1150
|
}
|
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.
|
|
4
|
-
"description": "kiso tui
|
|
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.
|
|
38
|
+
"@vincemakes/kiso-tui-cells": "0.16.3"
|
|
39
39
|
}
|
|
40
40
|
}
|