@vincemakes/kiso-tui 0.1.29 → 0.1.32
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/body.d.ts +11 -6
- package/dist/body.js +83 -47
- package/dist/components.d.ts +116 -0
- package/dist/components.js +333 -0
- package/dist/compositor.d.ts +165 -0
- package/dist/compositor.js +779 -0
- package/dist/dock.js +9 -3
- package/dist/editor.js +3 -3
- package/dist/index.d.ts +5 -4
- package/dist/index.js +5 -4
- package/dist/render.d.ts +9 -9
- package/dist/render.js +11 -11
- package/package.json +1 -1
package/dist/dock.js
CHANGED
|
@@ -141,14 +141,20 @@ export class Dock {
|
|
|
141
141
|
if (!this.#active)
|
|
142
142
|
return;
|
|
143
143
|
const p = palette();
|
|
144
|
-
|
|
145
|
-
|
|
144
|
+
// #17 (P1): read the LIVE size, not the cache — the body's resize
|
|
145
|
+
// render calls onDock (this redraw) BEFORE this dock's own resize
|
|
146
|
+
// handler runs, so the cached geometry would draw the chrome at
|
|
147
|
+
// stale rows (clamped into the body — the separator residue wall).
|
|
148
|
+
// The live read makes the handler order irrelevant; the cache keeps
|
|
149
|
+
// serving exit().
|
|
150
|
+
const H = process.stdout.rows ?? this.#height;
|
|
151
|
+
const W = process.stdout.columns ?? this.#width;
|
|
146
152
|
const sep = `${p.dim}${"╌".repeat(W)}${p.reset}`;
|
|
147
153
|
const status = `${this.#status}${this.#tail === "" ? "" : ` · ${this.#tail}`}`;
|
|
148
154
|
const statusLine = this.#question ?? this.#statusRow(status, p, W);
|
|
149
155
|
const inp = this.#inputState();
|
|
150
156
|
const out = [];
|
|
151
|
-
// P3 (
|
|
157
|
+
// P3 (review): the DEC private-mode SET/RESET needs the "?" prefix —
|
|
152
158
|
// \x1b[?2026h/l, the pi source's exact form. Without it terminals
|
|
153
159
|
// silently ignore the mode and the anti-flicker never engages.
|
|
154
160
|
out.push("\x1b[?2026h"); // synchronized output ON (DEC 2026)
|
package/dist/editor.js
CHANGED
|
@@ -102,7 +102,7 @@ export class Editor {
|
|
|
102
102
|
#onRender;
|
|
103
103
|
#menuOpen = false; // v3 §04: the slash-command menu
|
|
104
104
|
#menuSel = 0;
|
|
105
|
-
// A2 (
|
|
105
|
+
// A2 (the feel): the session-scoped input history — every submitted TURN
|
|
106
106
|
// line (never a question answer), capped at 100, never persisted. ↑↓
|
|
107
107
|
// navigate it ONLY from an empty input or while already browsing.
|
|
108
108
|
#history = [];
|
|
@@ -337,7 +337,7 @@ export class Editor {
|
|
|
337
337
|
}
|
|
338
338
|
else if (final === "A" || final === "B") {
|
|
339
339
|
// v3 §04: the menu owns ↑↓ while open (the selection, never the
|
|
340
|
-
// cursor). A2 (
|
|
340
|
+
// cursor). A2 (the feel): otherwise ↑↓ navigate the session history
|
|
341
341
|
// — ONLY from an empty input or while already browsing; mid-edit
|
|
342
342
|
// the cursor semantics are unchanged (↑↓ do nothing).
|
|
343
343
|
if (this.#menuOpen) {
|
|
@@ -427,7 +427,7 @@ export class Editor {
|
|
|
427
427
|
#submit() {
|
|
428
428
|
let line = String.fromCodePoint(...this.#chars);
|
|
429
429
|
if (this.#menuOpen) {
|
|
430
|
-
// A1 (
|
|
430
|
+
// A1 (the feel): Enter submits the EXACT selection directly; a
|
|
431
431
|
// PARTIAL selection COMPLETES the buffer (the Tab semantics)
|
|
432
432
|
// without submitting — the user reviews and presses Enter
|
|
433
433
|
// again. The old behavior executed the completed command on
|
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* kiso-tui — the PURE terminal layer, extracted from the CLI (the
|
|
3
3
|
* ADR-0041 escape hatch). Zero runtime dependencies: input is data,
|
|
4
|
-
* output is bytes.
|
|
5
|
-
*
|
|
4
|
+
* output is bytes. TUI v6 (ADR-0046): the ONE compositor (the single
|
|
5
|
+
* writer — body.ts + dock.ts retired), the component tree, the raw-mode
|
|
6
|
+
* editor, the diff renderer, and the palette.
|
|
6
7
|
*/
|
|
7
|
-
export { Body, type BodyOptions } from "./
|
|
8
|
-
export {
|
|
8
|
+
export { Body, Dock, CURSOR_MARKER, type BodyOptions } from "./compositor.js";
|
|
9
|
+
export { Container, foldLine, visibleWidth, SPINNER, type Component, type FrameCtx } from "./components.js";
|
|
9
10
|
export { Editor, MENU_ITEMS, PROMPT, PROMPT_WIDTH, displayWidth, charWidth, widthOf, type MenuItem, } from "./editor.js";
|
|
10
11
|
export { bannerLines, COLOR_OFF, COLOR_ON, escapeTerminal, foldResult, foldThinking, kUnit, palette, renderEvent, renderRecap, renderSessionLine, renderStatusLine, renderTerminalGap, renderToolSummary, TAGLINE, truncateRow, type Palette, type PathResolver, type RecapStats, type RenderInput, type RenderResult, type RunUsage, } from "./render.js";
|
|
11
12
|
export { editFileDiff, truncateDiff, writeFileDiff, type DiffLine, type DiffResult } from "./diff.js";
|
package/dist/index.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* kiso-tui — the PURE terminal layer, extracted from the CLI (the
|
|
3
3
|
* ADR-0041 escape hatch). Zero runtime dependencies: input is data,
|
|
4
|
-
* output is bytes.
|
|
5
|
-
*
|
|
4
|
+
* output is bytes. TUI v6 (ADR-0046): the ONE compositor (the single
|
|
5
|
+
* writer — body.ts + dock.ts retired), the component tree, the raw-mode
|
|
6
|
+
* editor, the diff renderer, and the palette.
|
|
6
7
|
*/
|
|
7
|
-
export { Body } from "./
|
|
8
|
-
export {
|
|
8
|
+
export { Body, Dock, CURSOR_MARKER } from "./compositor.js";
|
|
9
|
+
export { Container, foldLine, visibleWidth, SPINNER } from "./components.js";
|
|
9
10
|
export { Editor, MENU_ITEMS, PROMPT, PROMPT_WIDTH, displayWidth, charWidth, widthOf, } from "./editor.js";
|
|
10
11
|
export { bannerLines, COLOR_OFF, COLOR_ON, escapeTerminal, foldResult, foldThinking, kUnit, palette, renderEvent, renderRecap, renderSessionLine, renderStatusLine, renderTerminalGap, renderToolSummary, TAGLINE, truncateRow, } from "./render.js";
|
|
11
12
|
export { editFileDiff, truncateDiff, writeFileDiff } from "./diff.js";
|
package/dist/render.d.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* input, produce the lines a human sees. Colors are raw ANSI — no
|
|
4
4
|
* dependencies.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
6
|
+
* the ergonomics batch C5: the input is the tui's OWN data shape (RenderInput), never
|
|
7
7
|
* kiso-core's Event — the CLI translates Event → RenderInput. The tui
|
|
8
8
|
* package has ZERO kiso-core imports: input is data, output is bytes.
|
|
9
9
|
*/
|
|
@@ -31,7 +31,7 @@ export declare const COLOR_ON: Palette;
|
|
|
31
31
|
export declare const COLOR_OFF: Palette;
|
|
32
32
|
export declare function palette(): Palette;
|
|
33
33
|
/**
|
|
34
|
-
* E
|
|
34
|
+
* E group/round 8: strip terminal-injection vectors from MODEL/TOOL text before it
|
|
35
35
|
* reaches the terminal — ESC, C0 (except \t \n), C1, CR, backspace, and
|
|
36
36
|
* bidi overrides. The kiso colors are applied by render, not by the data.
|
|
37
37
|
* EVERY externally-sourced string must pass through this before any output.
|
|
@@ -56,7 +56,7 @@ export interface RenderResult {
|
|
|
56
56
|
readonly prompt: boolean;
|
|
57
57
|
}
|
|
58
58
|
/**
|
|
59
|
-
*
|
|
59
|
+
* the ergonomics batch C5 — the render input, the tui's OWN data shape: the subset of
|
|
60
60
|
* an event stream the renderer reads, keyed by type. The CLI translates
|
|
61
61
|
* its Event stream into this (Event → RenderInput) before rendering —
|
|
62
62
|
* the tui package never imports kiso-core. Field names mirror the
|
|
@@ -149,7 +149,7 @@ export type RenderInput = {
|
|
|
149
149
|
* Render one event. `text` may be a continuation (text_delta appends to the
|
|
150
150
|
* current line); `newline` says whether the line is complete.
|
|
151
151
|
*
|
|
152
|
-
*
|
|
152
|
+
* bootstrap P1: `prevThinking` marks a thinking delta that continues the SAME
|
|
153
153
|
* block — it renders appended to the segment, without the … prefix. The
|
|
154
154
|
* consumer closes the segment with a newline at the next non-thinking
|
|
155
155
|
* event.
|
|
@@ -166,7 +166,7 @@ export declare function foldThinking(block: string): string;
|
|
|
166
166
|
export declare function foldResult(content: string): string;
|
|
167
167
|
export declare function renderEvent(ev: RenderInput, prevThinking?: boolean, resolvePath?: PathResolver): RenderResult;
|
|
168
168
|
/**
|
|
169
|
-
* B
|
|
169
|
+
* B area: one-line summary of a completed tool call, e.g.
|
|
170
170
|
* ✓ edit src/foo.ts (+12 -3) ✓ read src/bar.ts (140 lines)
|
|
171
171
|
* ✗ shell npm test (exit 1)
|
|
172
172
|
* edit/write show +/- line counts, read shows lines, shell shows the exit
|
|
@@ -178,7 +178,7 @@ export declare function renderToolSummary(name: string, input: Record<string, un
|
|
|
178
178
|
}): string;
|
|
179
179
|
/** k-units for the status line: 12345 → 12.3k, 800 → 800, null → ?. */
|
|
180
180
|
export declare function kUnit(value: number | null): string;
|
|
181
|
-
/** B
|
|
181
|
+
/** B area: usage data gathered from the run's usage events. */
|
|
182
182
|
export interface RunUsage {
|
|
183
183
|
readonly in: number | null;
|
|
184
184
|
readonly out: number | null;
|
|
@@ -186,9 +186,9 @@ export interface RunUsage {
|
|
|
186
186
|
readonly known: boolean;
|
|
187
187
|
}
|
|
188
188
|
/**
|
|
189
|
-
* B
|
|
189
|
+
* B area/v2a: the one-line status bar after a terminal, e.g.
|
|
190
190
|
* [turn 3 · in 12.4k out 1.8k · cache 9.2k · ctx ~14%]
|
|
191
|
-
*
|
|
191
|
+
* Denoising: unknown fields are OMITTED ENTIRELY (show what there is); a fully unknown
|
|
192
192
|
* usage → null (the caller prints nothing); faux mode → [turn N · faux].
|
|
193
193
|
* All data comes from usage events; ctx is the approximate estimate
|
|
194
194
|
* passed in (chars/4 vs the window), marked with ~.
|
|
@@ -196,7 +196,7 @@ export interface RunUsage {
|
|
|
196
196
|
export declare function renderStatusLine(turn: number, usage: RunUsage, ctxRatio: number, faux?: boolean): string | null;
|
|
197
197
|
/**
|
|
198
198
|
* v2a rhythm — the exact bytes after a terminal event: the status line
|
|
199
|
-
* hugs the terminal (
|
|
199
|
+
* hugs the terminal (show what there is — omitted when there is nothing to show),
|
|
200
200
|
* then EXACTLY one blank line before the next prompt. The consumer prints
|
|
201
201
|
* this verbatim; the render tests pin the sequence.
|
|
202
202
|
*/
|
package/dist/render.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* input, produce the lines a human sees. Colors are raw ANSI — no
|
|
4
4
|
* dependencies.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
6
|
+
* the ergonomics batch C5: the input is the tui's OWN data shape (RenderInput), never
|
|
7
7
|
* kiso-core's Event — the CLI translates Event → RenderInput. The tui
|
|
8
8
|
* package has ZERO kiso-core imports: input is data, output is bytes.
|
|
9
9
|
*/
|
|
@@ -13,7 +13,7 @@ export function palette() {
|
|
|
13
13
|
return process.env.NO_COLOR === undefined && process.stdout.isTTY ? COLOR_ON : COLOR_OFF;
|
|
14
14
|
}
|
|
15
15
|
/**
|
|
16
|
-
* E
|
|
16
|
+
* E group/round 8: strip terminal-injection vectors from MODEL/TOOL text before it
|
|
17
17
|
* reaches the terminal — ESC, C0 (except \t \n), C1, CR, backspace, and
|
|
18
18
|
* bidi overrides. The kiso colors are applied by render, not by the data.
|
|
19
19
|
* EVERY externally-sourced string must pass through this before any output.
|
|
@@ -44,7 +44,7 @@ export function colorInlineCode(line) {
|
|
|
44
44
|
* Render one event. `text` may be a continuation (text_delta appends to the
|
|
45
45
|
* current line); `newline` says whether the line is complete.
|
|
46
46
|
*
|
|
47
|
-
*
|
|
47
|
+
* bootstrap P1: `prevThinking` marks a thinking delta that continues the SAME
|
|
48
48
|
* block — it renders appended to the segment, without the … prefix. The
|
|
49
49
|
* consumer closes the segment with a newline at the next non-thinking
|
|
50
50
|
* event.
|
|
@@ -80,7 +80,7 @@ export function renderEvent(ev, prevThinking = false, resolvePath = (p) => p) {
|
|
|
80
80
|
case "text_end":
|
|
81
81
|
return { text: "\n", newline: true, prompt: false };
|
|
82
82
|
case "thinking":
|
|
83
|
-
//
|
|
83
|
+
// bootstrap P1/v2b: the CONSUMER buffers each thinking block and folds
|
|
84
84
|
// it to ONE dim line (foldThinking); this render is the generic
|
|
85
85
|
// path for tests. The full block goes to /think.
|
|
86
86
|
return {
|
|
@@ -112,7 +112,7 @@ export function renderEvent(ev, prevThinking = false, resolvePath = (p) => p) {
|
|
|
112
112
|
};
|
|
113
113
|
}
|
|
114
114
|
case "permission_requested":
|
|
115
|
-
//
|
|
115
|
+
// round 8: the tool NAME is model text — escaped like everything else.
|
|
116
116
|
return {
|
|
117
117
|
text: `⏸ ${escapeTerminal(ev.name)} needs approval ${p.dim}${approvalDetail(ev.name, ev.input, resolvePath)}${p.reset} `,
|
|
118
118
|
newline: false,
|
|
@@ -162,7 +162,7 @@ export function renderEvent(ev, prevThinking = false, resolvePath = (p) => p) {
|
|
|
162
162
|
}
|
|
163
163
|
}
|
|
164
164
|
/**
|
|
165
|
-
* The approval prompt detail (Area 5
|
|
165
|
+
* The approval prompt detail (Area 5/round 8): the human must be able to see
|
|
166
166
|
* EVERYTHING they are approving. The shell command is shown in full; the
|
|
167
167
|
* path is the CANONICAL one the tool will touch; write/edit show the FULL
|
|
168
168
|
* content (never a truncated tail that hides a dangerous payload). The
|
|
@@ -182,7 +182,7 @@ function approvalDetail(name, input, resolvePath) {
|
|
|
182
182
|
return `\n ${escapeTerminal(JSON.stringify(input))}`;
|
|
183
183
|
}
|
|
184
184
|
/**
|
|
185
|
-
* B
|
|
185
|
+
* B area: one-line summary of a completed tool call, e.g.
|
|
186
186
|
* ✓ edit src/foo.ts (+12 -3) ✓ read src/bar.ts (140 lines)
|
|
187
187
|
* ✗ shell npm test (exit 1)
|
|
188
188
|
* edit/write show +/- line counts, read shows lines, shell shows the exit
|
|
@@ -248,9 +248,9 @@ export function kUnit(value) {
|
|
|
248
248
|
return String(value);
|
|
249
249
|
}
|
|
250
250
|
/**
|
|
251
|
-
* B
|
|
251
|
+
* B area/v2a: the one-line status bar after a terminal, e.g.
|
|
252
252
|
* [turn 3 · in 12.4k out 1.8k · cache 9.2k · ctx ~14%]
|
|
253
|
-
*
|
|
253
|
+
* Denoising: unknown fields are OMITTED ENTIRELY (show what there is); a fully unknown
|
|
254
254
|
* usage → null (the caller prints nothing); faux mode → [turn N · faux].
|
|
255
255
|
* All data comes from usage events; ctx is the approximate estimate
|
|
256
256
|
* passed in (chars/4 vs the window), marked with ~.
|
|
@@ -275,7 +275,7 @@ export function renderStatusLine(turn, usage, ctxRatio, faux = false) {
|
|
|
275
275
|
}
|
|
276
276
|
/**
|
|
277
277
|
* v2a rhythm — the exact bytes after a terminal event: the status line
|
|
278
|
-
* hugs the terminal (
|
|
278
|
+
* hugs the terminal (show what there is — omitted when there is nothing to show),
|
|
279
279
|
* then EXACTLY one blank line before the next prompt. The consumer prints
|
|
280
280
|
* this verbatim; the render tests pin the sequence.
|
|
281
281
|
*/
|
|
@@ -345,6 +345,6 @@ export function renderRecap(s) {
|
|
|
345
345
|
/** One-line summary of a session, for `kiso sessions`. */
|
|
346
346
|
export function renderSessionLine(meta) {
|
|
347
347
|
const when = meta.updatedAt ? new Date(meta.updatedAt).toISOString().slice(0, 16) : "—";
|
|
348
|
-
//
|
|
348
|
+
// round 8: the title is the user's first prompt — model/user text, escaped.
|
|
349
349
|
return `${meta.id.padEnd(24)} ${meta.runs} runs ${String(meta.events).padStart(5)} events ${when} ${escapeTerminal(meta.title)}`;
|
|
350
350
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vincemakes/kiso-tui",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.32",
|
|
4
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",
|