@vincemakes/kiso-tui 0.1.36 → 0.1.38
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 +113 -7
- package/dist/components.js +471 -66
- package/dist/compositor.d.ts +58 -5
- package/dist/compositor.js +475 -58
- package/dist/editor.d.ts +3 -6
- package/dist/editor.js +27 -54
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/render.d.ts +46 -5
- package/dist/render.js +150 -30
- package/dist/width.d.ts +15 -0
- package/dist/width.js +59 -0
- package/package.json +1 -1
package/dist/components.d.ts
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* (untouched); render.ts supplies the original text (palette, escape,
|
|
16
16
|
* tint, fold wording).
|
|
17
17
|
*/
|
|
18
|
-
import { foldThinking, foldResult, renderToolSummary } from "./render.js";
|
|
18
|
+
import { foldThinking, foldResult, renderToolSummary, type ResumeMeta } from "./render.js";
|
|
19
19
|
/** The spinner glyphs, cycled by the compositor's on-demand tick. */
|
|
20
20
|
export declare const SPINNER: string[];
|
|
21
21
|
/** The frame context the compositor passes down — the pieces of time
|
|
@@ -24,6 +24,10 @@ export declare const SPINNER: string[];
|
|
|
24
24
|
export interface FrameCtx {
|
|
25
25
|
readonly spinnerI: number;
|
|
26
26
|
readonly now: number;
|
|
27
|
+
/** The terminal height (rows) — the banner cell's tier input (W1:
|
|
28
|
+
* the tier table reads H, so a resize RE-TIERS instead of
|
|
29
|
+
* re-folding frozen rows). */
|
|
30
|
+
readonly height: number;
|
|
27
31
|
}
|
|
28
32
|
/** ONE screen line a component emits (raw, SGR included). */
|
|
29
33
|
export type RenderLine = string;
|
|
@@ -43,7 +47,19 @@ export declare function visibleWidth(line: string): number;
|
|
|
43
47
|
export interface Component {
|
|
44
48
|
render(width: number, ctx: FrameCtx): string[];
|
|
45
49
|
}
|
|
46
|
-
/** The
|
|
50
|
+
/** The W11 spacing formula — "a row gets one blank line above it when
|
|
51
|
+
* the row is itself a block, or when the previous sibling was taller
|
|
52
|
+
* than one row". One-row siblings pack tight; anything multi-row
|
|
53
|
+
* breathes on both sides. The FIRST cell never gets the blank (it sits
|
|
54
|
+
* at the body's top — the banner would otherwise start one row down).
|
|
55
|
+
* `prev` is the previous sibling's OWN rows (raw — a cell's own blank
|
|
56
|
+
* must never count toward its height). The blank is a JOIN artifact:
|
|
57
|
+
* the cell's own render stays blank-free, so per-cell accounting
|
|
58
|
+
* (heights, the fold cache) never sees a fake row. */
|
|
59
|
+
export declare function bodySpacing(prev: readonly string[] | null, rows: readonly string[]): string[];
|
|
60
|
+
/** The container — vertical concatenation with the W11 formula. No
|
|
61
|
+
* component decides its own spacing: every blank in the body is the
|
|
62
|
+
* container's. */
|
|
47
63
|
export declare class Container implements Component {
|
|
48
64
|
private readonly children;
|
|
49
65
|
constructor(children: Component[]);
|
|
@@ -53,14 +69,21 @@ export type BodyCell = {
|
|
|
53
69
|
kind: "user";
|
|
54
70
|
text: string;
|
|
55
71
|
done: true;
|
|
72
|
+
turn: number;
|
|
56
73
|
} | {
|
|
57
74
|
kind: "thinking";
|
|
58
75
|
text: string;
|
|
59
76
|
done: boolean;
|
|
77
|
+
turn: number;
|
|
60
78
|
} | {
|
|
61
79
|
kind: "tool";
|
|
62
80
|
name: string;
|
|
63
81
|
input: string;
|
|
82
|
+
/** W15: the FULL input JSON (pretty-printed) — the display
|
|
83
|
+
* summary above is sliced at 60 chars; the expanded block's
|
|
84
|
+
* "--- input ---" section mirrors /last and needs it all. */
|
|
85
|
+
inputFull: string;
|
|
86
|
+
childRoles: string[];
|
|
64
87
|
state: "pending" | "approval" | "running" | "done";
|
|
65
88
|
isError: boolean;
|
|
66
89
|
resultText: string;
|
|
@@ -70,6 +93,32 @@ export type BodyCell = {
|
|
|
70
93
|
startedAt: number | null;
|
|
71
94
|
doneAt: number | null;
|
|
72
95
|
done: boolean;
|
|
96
|
+
/** W15: the live-region expand toggle — while the cell is live
|
|
97
|
+
* the FULL body renders in place (the compositor owns those
|
|
98
|
+
* rows and redraws them); a committed cell can never toggle
|
|
99
|
+
* (history is never rewritten — ADR-0046). */
|
|
100
|
+
expanded: boolean;
|
|
101
|
+
/** W14: the turn boundary — the index of the turn record that
|
|
102
|
+
* created this cell (the fold-hold's owner; −1 when no turn
|
|
103
|
+
* exists yet — the pre-turn cells never hold). */
|
|
104
|
+
turn: number;
|
|
105
|
+
/** W13: the rolled-up group summary — set at COMMIT time when
|
|
106
|
+
* the head of an N > 2 same-tool run renders the group (the
|
|
107
|
+
* work order's claimed shape: "✓ read 5 files (2.4k lines,
|
|
108
|
+
* 1.1s)" + the target children). The members carry null — the
|
|
109
|
+
* compositor's rolled-heads bookkeeping renders them []. */
|
|
110
|
+
rolled: null | {
|
|
111
|
+
count: number;
|
|
112
|
+
lines: number;
|
|
113
|
+
elapsed: string;
|
|
114
|
+
targets: string[];
|
|
115
|
+
};
|
|
116
|
+
/** W19: a DENIED call's reason (the CLI extracted it from the
|
|
117
|
+
* result's "[Permission denied] " prefix, keyed on the "denied"
|
|
118
|
+
* tag). Non-null renders the pinned row — the full call name,
|
|
119
|
+
* the target, the reason in the W4 parentheses idiom, NO timing
|
|
120
|
+
* metadata (the call never ran). */
|
|
121
|
+
reason: string | null;
|
|
73
122
|
} | {
|
|
74
123
|
kind: "text";
|
|
75
124
|
text: string;
|
|
@@ -78,6 +127,12 @@ export type BodyCell = {
|
|
|
78
127
|
kind: "notice";
|
|
79
128
|
text: string;
|
|
80
129
|
done: true;
|
|
130
|
+
} | {
|
|
131
|
+
kind: "banner";
|
|
132
|
+
version: string;
|
|
133
|
+
extensionsText: string;
|
|
134
|
+
resume: ResumeMeta[];
|
|
135
|
+
done: true;
|
|
81
136
|
} | {
|
|
82
137
|
kind: "raw";
|
|
83
138
|
lines: string[];
|
|
@@ -89,26 +144,77 @@ export type BodyCell = {
|
|
|
89
144
|
done: true;
|
|
90
145
|
} | {
|
|
91
146
|
kind: "checklist";
|
|
147
|
+
/** the model-authored header tail (parseChecklist's count line —
|
|
148
|
+
* chat.ts). The compositor's fixed "todo" prefix rides BEFORE it
|
|
149
|
+
* (W20 naming ruling: never model-controlled). */
|
|
92
150
|
header: string;
|
|
93
151
|
items: {
|
|
94
152
|
text: string;
|
|
95
153
|
status: "pending" | "active" | "done";
|
|
96
154
|
}[];
|
|
97
|
-
|
|
155
|
+
/** W20: false while LIVE — the current turn's ONE in-place block
|
|
156
|
+
* (the commit loop only takes done cells, so it stays in the
|
|
157
|
+
* live region); true once SETTLED — endTurn committed it as the
|
|
158
|
+
* turn's one recap block. */
|
|
159
|
+
done: boolean;
|
|
160
|
+
/** W20: the LIVE block's ctrl+r toggle (W15) — the capped form
|
|
161
|
+
* flips to the full list in place. The settled render ignores
|
|
162
|
+
* it (already full). */
|
|
163
|
+
expanded: boolean;
|
|
164
|
+
/** W20: the wall clock of the block's FIRST call — the settled
|
|
165
|
+
* header's duration is clocked from here, compositor-side (the
|
|
166
|
+
* CLI stays unchanged). */
|
|
167
|
+
startedAt: number;
|
|
168
|
+
/** W20: the run's duration at the settle — the `2h 14m` form. */
|
|
169
|
+
durationSeconds: number;
|
|
170
|
+
turn: number;
|
|
98
171
|
};
|
|
99
172
|
declare const TOOL_SUMMARY_MAX = 60;
|
|
100
173
|
/** The component for one cell — the mapping table lives here so the
|
|
101
174
|
* compositor stays a pure writer. */
|
|
102
175
|
export declare function cellComponent(cell: BodyCell): Component;
|
|
176
|
+
/** W13 — the rollup opt-in table: which tools collapse, and the count
|
|
177
|
+
* NOUN (read_file calls → "5 files", list_dir → "5 dirs", search_text
|
|
178
|
+
* → "5 matches"). Only these tools opt in — a shell burst is never
|
|
179
|
+
* rolled up (its rows carry meaning). The folded-turn line (W14) reuses
|
|
180
|
+
* the plurals for its other-tool terms ("2 dirs", "1 match"). */
|
|
181
|
+
export declare const ROLLUP_NOUN: Readonly<Record<string, string>>;
|
|
182
|
+
/** W14 — the folded-turn line: a whole QUIET turn (no text), once it is
|
|
183
|
+
* scrollback, becomes ONE line — the work order's claimed shape
|
|
184
|
+
* (`▞ thought 19s · 5 reads · no edits`), the counts accumulated at
|
|
185
|
+
* toolStart: read_file → "reads", edit_file → "edits", the other tools
|
|
186
|
+
* as first-call-order terms (the ROLLUP_NOUN plurals when the tool opts
|
|
187
|
+
* in, the verb + "s" otherwise). */
|
|
188
|
+
export declare function turnFold(t: {
|
|
189
|
+
thoughtSeconds: number;
|
|
190
|
+
reads: number;
|
|
191
|
+
edits: number;
|
|
192
|
+
others: [string, number][];
|
|
193
|
+
}): string[];
|
|
194
|
+
/** W20 — the todo block's fixed-window height: the whole live block
|
|
195
|
+
* (header + rows) in POST-FOLD screen rows at EVERY width: the header,
|
|
196
|
+
* the active row, up to 2 pending, the overflow-pending fold, the
|
|
197
|
+
* done-collapse. Every live row CUTS at W (never folds) — the block's
|
|
198
|
+
* height is its row count. */
|
|
199
|
+
export declare const CAP_TODO_LIVE = 6;
|
|
200
|
+
/** W20 — the settled block's duration, the `2h 14m` form (the todo
|
|
201
|
+
* narrative's long-horizon idiom): minutes+seconds under an hour,
|
|
202
|
+
* hours+minutes past it. */
|
|
203
|
+
export declare function formatDuration(totalSeconds: number): string;
|
|
103
204
|
/** The status container's row: the status text (+ the tail) with the
|
|
104
205
|
* right-aligned "/ commands · ↑ history" hint in the idle state —
|
|
105
206
|
* the hint CUT FIRST when the width is short (the #16g rule); when
|
|
106
207
|
* the STATUS ITSELF cannot fit, it cuts with a "…" — the last resort,
|
|
107
208
|
* enforced by invariant ① (the old code let the status soft-wrap). */
|
|
108
|
-
export declare function statusLine(status: string, tail: string, question: boolean, W: number): string;
|
|
109
|
-
/**
|
|
110
|
-
* the
|
|
111
|
-
|
|
209
|
+
export declare function statusLine(status: string, tail: string, question: boolean, W: number, hint?: string): string;
|
|
210
|
+
/** W6 — the box: the chrome's top rail. The two ╌ dotted rows become
|
|
211
|
+
* a rounded box (the box already says "input lives here"); the rails
|
|
212
|
+
* stay dim, the width is still the full W (the box is a rail with
|
|
213
|
+
* corners — the menu/gap rows above and the status below are
|
|
214
|
+
* untouched). */
|
|
215
|
+
export declare function boxTop(W: number): string;
|
|
216
|
+
/** W6 — the box: the chrome's bottom rail. */
|
|
217
|
+
export declare function boxBottom(W: number): string;
|
|
112
218
|
/** The terminal label + rhythm gap (the pipe path's v2c bytes — the
|
|
113
219
|
* exact render the passthrough needs). */
|
|
114
220
|
export declare function terminalPipe(label: string, statusLineText: string): string;
|