@vincemakes/kiso-tui-cells 0.39.2 → 0.40.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.
- package/dist/components.d.ts +16 -1
- package/dist/components.js +32 -6
- package/dist/diff.d.ts +5 -2
- package/dist/diff.js +3 -3
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/render.d.ts +1 -6
- package/dist/render.js +19 -0
- package/dist/strings.d.ts +15 -2
- package/dist/strings.js +36 -5
- package/package.json +1 -1
package/dist/components.d.ts
CHANGED
|
@@ -162,6 +162,19 @@ export type BodyCell = {
|
|
|
162
162
|
kind: "notice";
|
|
163
163
|
text: string;
|
|
164
164
|
done: true;
|
|
165
|
+
}
|
|
166
|
+
/** 4c — the resumed session's earlier history, replayed into cells and
|
|
167
|
+
* FOLDED: the row is ONE line on screen and never expands there (a
|
|
168
|
+
* resize reprint of a six-thousand-event session redraws one row);
|
|
169
|
+
* the children are the replayed cells, read in the ctrl+r viewer.
|
|
170
|
+
* `summary` is a compaction checkpoint's text — what the model sees in
|
|
171
|
+
* place of the turns it covers — null for a plain fold. */
|
|
172
|
+
| {
|
|
173
|
+
kind: "fold";
|
|
174
|
+
label: string;
|
|
175
|
+
children: BodyCell[];
|
|
176
|
+
summary: string | null;
|
|
177
|
+
done: true;
|
|
165
178
|
} | {
|
|
166
179
|
kind: "banner";
|
|
167
180
|
version: string;
|
|
@@ -272,7 +285,9 @@ export declare function foldTerms(reads: number, edits: number, others: readonly
|
|
|
272
285
|
* reads a payload it did not write, and a guess about what it means
|
|
273
286
|
* would be a row the product cannot stand behind.
|
|
274
287
|
*/
|
|
275
|
-
|
|
288
|
+
/** `seconds` null: 4c's replayed card, settled from a log with no clock —
|
|
289
|
+
* the head names the outcome and says nothing about time. */
|
|
290
|
+
export declare function askedBlock(resultText: string, seconds: number | null, W: number): string[];
|
|
276
291
|
/** The caps — screen rows counted AFTER the fold, at the current width
|
|
277
292
|
* (the W7 table). The renderer-cut row is inside the cap. */
|
|
278
293
|
/** R13 — ONE preview cap, every tool. It was the shell's alone while
|
package/dist/components.js
CHANGED
|
@@ -30,7 +30,7 @@ import { displayWidth, visibleWidth, widthCut } from "./width.js";
|
|
|
30
30
|
// KEY_BINDINGS). strings.js imports only render/width here, so this edge
|
|
31
31
|
// adds no cycle.
|
|
32
32
|
import { displayVerb } from "./strings.js";
|
|
33
|
-
import { bannerLines, breathFrame, cutLine, escapeTerminal, foldThinking, foldThinkingRow, foldResult, renderTerminalGap, renderToolSummary, toolTarget, kUnit, palette, currentGround, } from "./render.js";
|
|
33
|
+
import { bannerLines, breathFrame, cutLine, escapeTerminal, stripAnsi, foldThinking, foldThinkingRow, foldResult, renderTerminalGap, renderToolSummary, toolTarget, kUnit, palette, currentGround, } from "./render.js";
|
|
34
34
|
// TUI2-MD: the markdown renderer's surface reaches the tui through this
|
|
35
35
|
// module (the tui's components shim re-exports it) — one import edge,
|
|
36
36
|
// and it points one way: md.ts measures with the width authority, never
|
|
@@ -179,6 +179,8 @@ export function cellComponent(cell) {
|
|
|
179
179
|
return new MarkdownBlock(cell);
|
|
180
180
|
case "notice":
|
|
181
181
|
return new ErrorLine(cell);
|
|
182
|
+
case "fold":
|
|
183
|
+
return new FoldRow(cell);
|
|
182
184
|
case "banner":
|
|
183
185
|
return new Banner(cell);
|
|
184
186
|
case "raw":
|
|
@@ -627,7 +629,7 @@ class ToolExecution {
|
|
|
627
629
|
// that is not the ask's own JSON, so a payload this renderer
|
|
628
630
|
// did not write can never be guessed at.
|
|
629
631
|
if (c.name === "ask_user" && c.reason === null && !c.isError) {
|
|
630
|
-
const asked = askedBlock(c.resultText, c.startedAt !== null && c.doneAt !== null ? (c.doneAt - c.startedAt) / 1000 : 0, W);
|
|
632
|
+
const asked = askedBlock(c.resultText, c.startedAt !== null && c.doneAt !== null ? (c.doneAt - c.startedAt) / 1000 : c.startedAt === null && c.doneAt === null ? null : 0, W);
|
|
631
633
|
if (asked.length > 0)
|
|
632
634
|
return asked;
|
|
633
635
|
}
|
|
@@ -644,7 +646,10 @@ class ToolExecution {
|
|
|
644
646
|
out.push(...toolBlockBody(c, W, ctx));
|
|
645
647
|
return out;
|
|
646
648
|
}
|
|
647
|
-
|
|
649
|
+
// 4c: a card settled from the durable log carries no clock at all
|
|
650
|
+
// (the log's events have no timestamps) — it says nothing about
|
|
651
|
+
// time rather than `?s`, which reads as a measurement that failed.
|
|
652
|
+
const elapsed = c.startedAt !== null && c.doneAt !== null ? settledLabel((c.doneAt - c.startedAt) / 1000) : c.startedAt === null && c.doneAt === null ? "" : "?s";
|
|
648
653
|
// TUI2-R1.5 ⑤ (VD-6): the line count is stated EXACTLY ONCE. Every
|
|
649
654
|
// read card carried it twice — `(2 lines, 0.0s) · 2 lines · ctrl+o
|
|
650
655
|
// expands` — because the parens and the suffix were written by
|
|
@@ -1099,6 +1104,8 @@ export function foldTerms(reads, edits, others) {
|
|
|
1099
1104
|
* reads a payload it did not write, and a guess about what it means
|
|
1100
1105
|
* would be a row the product cannot stand behind.
|
|
1101
1106
|
*/
|
|
1107
|
+
/** `seconds` null: 4c's replayed card, settled from a log with no clock —
|
|
1108
|
+
* the head names the outcome and says nothing about time. */
|
|
1102
1109
|
export function askedBlock(resultText, seconds, W) {
|
|
1103
1110
|
let parsed;
|
|
1104
1111
|
try {
|
|
@@ -1111,7 +1118,7 @@ export function askedBlock(resultText, seconds, W) {
|
|
|
1111
1118
|
return [];
|
|
1112
1119
|
const asked = parsed;
|
|
1113
1120
|
const p = palette();
|
|
1114
|
-
const head = (n, outcome) => cutLine(` ${p.bold}asked${p.reset} ${n} ${n === 1 ? "question" : "questions"} ${p.dim}(${outcome}, ${seconds.toFixed(1)}s)${p.reset}`, W);
|
|
1121
|
+
const head = (n, outcome) => cutLine(` ${p.bold}asked${p.reset} ${n} ${n === 1 ? "question" : "questions"} ${p.dim}(${seconds === null ? outcome : `${outcome}, ${seconds.toFixed(1)}s`})${p.reset}`, W);
|
|
1115
1122
|
const row = (body) => cutLine(` ${p.dim}│${p.reset} ${body}`, W);
|
|
1116
1123
|
if (Array.isArray(asked.declined) && asked.declined.length > 0) {
|
|
1117
1124
|
// the honest decline record: WHAT went unanswered, and what the
|
|
@@ -1439,7 +1446,8 @@ function blockRows(text, W, tone = "dim") {
|
|
|
1439
1446
|
// rows around them take `washDim`, which was chosen for that ground.
|
|
1440
1447
|
const open = tone === "dim" ? p.dim : "";
|
|
1441
1448
|
const close = tone === "dim" ? p.reset : "";
|
|
1442
|
-
|
|
1449
|
+
// 0.40.0: the output's own styling is dropped whole before the escape
|
|
1450
|
+
for (const raw of escapeTerminal(stripAnsi(text)).split("\n")) {
|
|
1443
1451
|
for (const row of foldLine(raw, textW))
|
|
1444
1452
|
rows.push(`${open}${bodyRow()}${row}${close}`);
|
|
1445
1453
|
}
|
|
@@ -1643,7 +1651,12 @@ export function diffBody(diff, W, expanded = false) {
|
|
|
1643
1651
|
? `${p.red}- ${escapeTerminal(d.text)}${p.reset}`
|
|
1644
1652
|
: d.kind === "+"
|
|
1645
1653
|
? `${p.green}+ ${escapeTerminal(d.text)}${p.reset}`
|
|
1646
|
-
:
|
|
1654
|
+
: d.kind === "note"
|
|
1655
|
+
? // 0.40.0: a note starts in the MARKER column, where no line
|
|
1656
|
+
// of the file ever does — it reads as kiso's sentence about
|
|
1657
|
+
// the diff, not as an unchanged line inside it
|
|
1658
|
+
`${p.dim}${escapeTerminal(d.text)}${p.reset}`
|
|
1659
|
+
: `${p.dim} ${escapeTerminal(d.text)}${p.reset}`;
|
|
1647
1660
|
// W2: the diff body is a bounded block's body — the │ gutter
|
|
1648
1661
|
// (dim), never the old bold ▎ rail (the table lists no ▎); the
|
|
1649
1662
|
// +/- marks and their colors ride the content
|
|
@@ -1728,6 +1741,19 @@ class ErrorLine {
|
|
|
1728
1741
|
return foldWords(escapeTerminal(this.cell.text), W);
|
|
1729
1742
|
}
|
|
1730
1743
|
}
|
|
1744
|
+
/** 4c — the folded history's ONE row. Dim, like every row that is about
|
|
1745
|
+
* the transcript rather than in it; cut, never wrapped, so it is one row
|
|
1746
|
+
* at every width. */
|
|
1747
|
+
class FoldRow {
|
|
1748
|
+
cell;
|
|
1749
|
+
constructor(cell) {
|
|
1750
|
+
this.cell = cell;
|
|
1751
|
+
}
|
|
1752
|
+
render(W, _ctx) {
|
|
1753
|
+
const p = palette();
|
|
1754
|
+
return [cutLine(` ${p.dim}${escapeTerminal(this.cell.label)}${p.reset}`, W)];
|
|
1755
|
+
}
|
|
1756
|
+
}
|
|
1731
1757
|
/** The CLI's pre-rendered blocks (the banner, the recap, slash-command
|
|
1732
1758
|
* output) — the SGR applied at composition (render.ts), folded here
|
|
1733
1759
|
* verbatim: the #16b contract (no re-escaping) holds, and the fold is
|
package/dist/diff.d.ts
CHANGED
|
@@ -10,9 +10,12 @@
|
|
|
10
10
|
* RENDERER truncates (18 head + 18 tail + "… N lines"); the stats come
|
|
11
11
|
* from the full diff.
|
|
12
12
|
*/
|
|
13
|
-
/** The diff block's per-row kind.
|
|
13
|
+
/** The diff block's per-row kind. `note` (0.40.0) is kiso's sentence
|
|
14
|
+
* ABOUT the diff — the renderer's cut, a search that is not there or is
|
|
15
|
+
* there more than once — never a line of the file, so never drawn where
|
|
16
|
+
* the file's lines are. */
|
|
14
17
|
export type DiffLine = {
|
|
15
|
-
kind: "-" | "+" | " ";
|
|
18
|
+
kind: "-" | "+" | " " | "note";
|
|
16
19
|
text: string;
|
|
17
20
|
};
|
|
18
21
|
export interface DiffResult {
|
package/dist/diff.js
CHANGED
|
@@ -76,7 +76,7 @@ export function truncateDiff(diff) {
|
|
|
76
76
|
const omitted = diff.length - 2 * TRUNCATE_KEEP;
|
|
77
77
|
return [
|
|
78
78
|
...diff.slice(0, TRUNCATE_KEEP),
|
|
79
|
-
{ kind: "
|
|
79
|
+
{ kind: "note", text: `… ${omitted} lines (/last for full)` },
|
|
80
80
|
...diff.slice(diff.length - TRUNCATE_KEEP),
|
|
81
81
|
];
|
|
82
82
|
}
|
|
@@ -117,7 +117,7 @@ export function editFileDiff(oldContent, search, replace, path) {
|
|
|
117
117
|
const at = oldContent.indexOf(search);
|
|
118
118
|
if (at < 0) {
|
|
119
119
|
return {
|
|
120
|
-
lines: [{ kind: "
|
|
120
|
+
lines: [{ kind: "note", text: `pattern not found in ${path ?? "the file"}` }],
|
|
121
121
|
added: 0,
|
|
122
122
|
removed: 0,
|
|
123
123
|
outcome: "not-found",
|
|
@@ -131,7 +131,7 @@ export function editFileDiff(oldContent, search, replace, path) {
|
|
|
131
131
|
// same rule as the miss above, for the same reason.
|
|
132
132
|
if (search.length > 0 && oldContent.indexOf(search, at + 1) > at) {
|
|
133
133
|
return {
|
|
134
|
-
lines: [{ kind: "
|
|
134
|
+
lines: [{ kind: "note", text: `pattern matches more than one place in ${path ?? "the file"}` }],
|
|
135
135
|
added: 0,
|
|
136
136
|
removed: 0,
|
|
137
137
|
outcome: "ambiguous",
|
package/dist/index.d.ts
CHANGED
|
@@ -12,7 +12,7 @@ export { pendingQueueRows } from "./components.js";
|
|
|
12
12
|
export { charWidth, displayWidth, leadWidth, widthOf } from "./width.js";
|
|
13
13
|
export { panelAffordance, panelBlockRows, panelLead, panelLeadPlain, panelLeadWidth, panelStatus, type PanelArgs, type PanelFlavor, type PanelPhase, deletionRiskHint, SAFER_BACK, SAFER_DEGRADED, type SaferOption, type SaferRuntime, panelOptions, type PanelOption, type PanelOptionKind, type PanelState, type PanelVerdict, type PanelView, type AskAnswer, type AskOption, type AskQuestion, type AskResult, type AskRuntime, type AskSpec, } from "./approval-panel.js";
|
|
14
14
|
export { interactivePrompt, projectTrustRows, projectTrustView, projectUntrustedNote, uncertainView, type TrustArtifact, } from "./strings.js";
|
|
15
|
-
export { extensionsBannerText, helpRows, unansweredAskView, type BannerExtension } from "./strings.js";
|
|
15
|
+
export { coldResumeLine, coldResumeView, extensionsBannerText, helpRows, unansweredAskView, type BannerExtension } from "./strings.js";
|
|
16
16
|
export { displayVerb } from "./strings.js";
|
|
17
17
|
export { bannerLines, COLOR_OFF, COLOR_DARK, COLOR_LIGHT, COLOR_NEUTRAL, COLOR_ON, currentGround, setGround, escapeTerminal, foldResult, foldThinking, kUnit, palette, relativeTime, renderResumeList, MOTION_FRAMES, TWINKLE, breathFrame, twinkleFrame, renderTerminalGap, renderToolSummary, TAGLINE, toolTarget, truncateRow, type Palette, type ResumeMeta, } from "./render.js";
|
|
18
18
|
/** DC-3 — the ground: is the terminal light or dark. Pure; see the
|
package/dist/index.js
CHANGED
|
@@ -24,7 +24,7 @@ export { panelAffordance, panelBlockRows, panelLead, panelLeadPlain, panelLeadWi
|
|
|
24
24
|
// the cli; what the human reads is presentation.
|
|
25
25
|
export { interactivePrompt, projectTrustRows, projectTrustView, projectUntrustedNote, uncertainView, } from "./strings.js";
|
|
26
26
|
// KC3.5: the interrupted-ask copy and the extracted /help table.
|
|
27
|
-
export { extensionsBannerText, helpRows, unansweredAskView } from "./strings.js";
|
|
27
|
+
export { coldResumeLine, coldResumeView, extensionsBannerText, helpRows, unansweredAskView } from "./strings.js";
|
|
28
28
|
// TUI2-R2pre ④: the ONE display-verb table — the screen names the act,
|
|
29
29
|
// the tool table names the call.
|
|
30
30
|
export { displayVerb } from "./strings.js";
|
package/dist/render.d.ts
CHANGED
|
@@ -146,12 +146,7 @@ export declare const COLOR_OFF: Palette;
|
|
|
146
146
|
export declare function setGround(g: Ground): void;
|
|
147
147
|
export declare function currentGround(): Ground;
|
|
148
148
|
export declare function palette(): Palette;
|
|
149
|
-
|
|
150
|
-
* E group/round 8: strip terminal-injection vectors from MODEL/TOOL text before it
|
|
151
|
-
* reaches the terminal — ESC, C0 (except \t \n), C1, CR, backspace, and
|
|
152
|
-
* bidi overrides. The kiso colors are applied by render, not by the data.
|
|
153
|
-
* EVERY externally-sourced string must pass through this before any output.
|
|
154
|
-
*/
|
|
149
|
+
export declare function stripAnsi(text: string): string;
|
|
155
150
|
export declare function escapeTerminal(text: string): string;
|
|
156
151
|
/**
|
|
157
152
|
* v2b — one thinking BLOCK folds to ONE dim line: the first 100 chars, a
|
package/dist/render.js
CHANGED
|
@@ -97,6 +97,25 @@ export function palette() {
|
|
|
97
97
|
* bidi overrides. The kiso colors are applied by render, not by the data.
|
|
98
98
|
* EVERY externally-sourced string must pass through this before any output.
|
|
99
99
|
*/
|
|
100
|
+
/**
|
|
101
|
+
* 0.40.0 (the owner's dogfood) — a tool's OUTPUT, shown without its
|
|
102
|
+
* terminal styling. escapeTerminal drops the ESC byte and nothing else, so
|
|
103
|
+
* a coloured test run reached the card as `[31m─── [1m[41m Failed Tests`.
|
|
104
|
+
* Here the whole sequence goes: CSI (colours, cursor moves), OSC (titles,
|
|
105
|
+
* links), DCS/SOS/PM/APC strings, charset selections, the two-byte escapes,
|
|
106
|
+
* and the 8-bit CSI. Every branch is linear: a string body stops at the
|
|
107
|
+
* first ESC (only its terminator may hold one), so hostile output — an
|
|
108
|
+
* unterminated `ESC P` repeated — never scans to the end of the text once
|
|
109
|
+
* per sequence (the lead's review: that was n²/2 on the render path).
|
|
110
|
+
* Only output bodies pass through here — in a NAME the
|
|
111
|
+
* `[31m` remnant is the visible sign of an injected sequence, and stripping
|
|
112
|
+
* it would let `sh<ESC>[31mell` read as `shell`.
|
|
113
|
+
*/
|
|
114
|
+
// eslint-disable-next-line no-control-regex
|
|
115
|
+
const ANSI_SEQUENCE = /\x1b\[[0-?]*[ -/]*[@-~]|\x1b\][^\x07\x1b]*(?:\x07|\x1b\\)|\x1b[PX^_][^\x1b]*\x1b\\|\x1b[ -/]+[0-~]|\x1b[@-Z\\-_]|\x9b[0-?]*[ -/]*[@-~]/g;
|
|
116
|
+
export function stripAnsi(text) {
|
|
117
|
+
return text.replace(ANSI_SEQUENCE, "");
|
|
118
|
+
}
|
|
100
119
|
export function escapeTerminal(text) {
|
|
101
120
|
// eslint-disable-next-line no-control-regex
|
|
102
121
|
return text
|
package/dist/strings.d.ts
CHANGED
|
@@ -96,6 +96,16 @@ export declare function uncertainView(name: string, executionId: string): PanelV
|
|
|
96
96
|
* back. Re-asking is safe — that is what the first option says out loud.)
|
|
97
97
|
*/
|
|
98
98
|
export declare function unansweredAskView(executionId: string): PanelView;
|
|
99
|
+
/**
|
|
100
|
+
* 0.40.0 (the owner's session) — the cold resume. A session resumed 27
|
|
101
|
+
* minutes after its last request re-sent a 727k prefix the provider had
|
|
102
|
+
* evicted. The first request after a long pause pays for the whole prefix
|
|
103
|
+
* either way; compacting first turns that one expensive request into a
|
|
104
|
+
* summary call, and every turn after it is small. The line names the size
|
|
105
|
+
* and the age, so the person can judge.
|
|
106
|
+
*/
|
|
107
|
+
export declare function coldResumeLine(tokens: number, minutesAgo: number): string;
|
|
108
|
+
export declare function coldResumeView(tokens: number, minutesAgo: number): PanelView;
|
|
99
109
|
/** An extension as the banner names it — the live `connecting` flag is
|
|
100
110
|
* the MCP bridge's in-flight state ("mcp (connecting…)"). Structural on
|
|
101
111
|
* purpose: the runtime's KisoExtension satisfies it without this
|
|
@@ -103,6 +113,9 @@ export declare function unansweredAskView(executionId: string): PanelView;
|
|
|
103
113
|
export interface BannerExtension {
|
|
104
114
|
readonly name: string;
|
|
105
115
|
readonly connecting?: boolean;
|
|
116
|
+
/** A fact about the extension in this session, printed in parentheses
|
|
117
|
+
* after its name — "ask (off in dontAsk)". `connecting` wins. */
|
|
118
|
+
readonly note?: string;
|
|
106
119
|
}
|
|
107
120
|
/**
|
|
108
121
|
* KC3.5 slice ⓪ (the extraction) — the `[N extensions: …]` banner text:
|
|
@@ -188,7 +201,7 @@ export declare function keysSheetRows(W: number): string[];
|
|
|
188
201
|
* sheet renders, joined — so the two can disagree only by deleting a
|
|
189
202
|
* test. The sheet is the readable form; this is the greppable one. */
|
|
190
203
|
export declare function keysHelpRow(): string;
|
|
191
|
-
/** The slash commands `/help` lists. The keys
|
|
192
|
-
* table are not commands and are not here. */
|
|
204
|
+
/** The slash commands `/help` lists. The keys, the `!` gestures and the
|
|
205
|
+
* `/<name>` skill rule in the table are not commands and are not here. */
|
|
193
206
|
export declare function slashCommandNames(): readonly string[];
|
|
194
207
|
export declare function helpRows(): string[];
|
package/dist/strings.js
CHANGED
|
@@ -143,6 +143,31 @@ export function unansweredAskView(executionId) {
|
|
|
143
143
|
fallbackQuestion: `an unanswered question was interrupted (${executionId}) — ask it again? (y)es / (n)o `,
|
|
144
144
|
};
|
|
145
145
|
}
|
|
146
|
+
/**
|
|
147
|
+
* 0.40.0 (the owner's session) — the cold resume. A session resumed 27
|
|
148
|
+
* minutes after its last request re-sent a 727k prefix the provider had
|
|
149
|
+
* evicted. The first request after a long pause pays for the whole prefix
|
|
150
|
+
* either way; compacting first turns that one expensive request into a
|
|
151
|
+
* summary call, and every turn after it is small. The line names the size
|
|
152
|
+
* and the age, so the person can judge.
|
|
153
|
+
*/
|
|
154
|
+
export function coldResumeLine(tokens, minutesAgo) {
|
|
155
|
+
return `this session is ${Math.round(tokens / 1000)}k tokens, last used ${minutesAgo} min ago, and its cache is cold`;
|
|
156
|
+
}
|
|
157
|
+
export function coldResumeView(tokens, minutesAgo) {
|
|
158
|
+
const line = coldResumeLine(tokens, minutesAgo);
|
|
159
|
+
return {
|
|
160
|
+
flavor: "simple",
|
|
161
|
+
name: "cold cache",
|
|
162
|
+
title: `compact first? (${Math.round(tokens / 1000)}k tokens, ${minutesAgo} min idle)`,
|
|
163
|
+
speaker: "kiso",
|
|
164
|
+
statusText: "❯ resumed session",
|
|
165
|
+
args: { kind: "text", lines: [line, "compacting first is one summary call, then every turn is cheap"] },
|
|
166
|
+
ruleOverride: `${line} — compact first? (one summary call, then every turn is cheap)`,
|
|
167
|
+
simpleOptions: ["compact first", "keep the full history"],
|
|
168
|
+
fallbackQuestion: `${line} — compact first? (y)es / (n)o `,
|
|
169
|
+
};
|
|
170
|
+
}
|
|
146
171
|
/**
|
|
147
172
|
* KC3.5 slice ⓪ (the extraction) — the `[N extensions: …]` banner text:
|
|
148
173
|
* the built-in column, then the user-level names, then the project-level
|
|
@@ -158,7 +183,7 @@ export function extensionsBannerText(builtIn, user, project) {
|
|
|
158
183
|
const total = builtIn.length + user.length + project.length;
|
|
159
184
|
if (total === 0)
|
|
160
185
|
return "";
|
|
161
|
-
const label = (e) =>
|
|
186
|
+
const label = (e) => e.connecting === true ? `${e.name} (connecting…)` : e.note !== undefined ? `${e.name} (${e.note})` : e.name;
|
|
162
187
|
const parts = [];
|
|
163
188
|
if (builtIn.length > 0)
|
|
164
189
|
parts.push(`built-in: ${builtIn.map(label).join(", ")}`);
|
|
@@ -447,7 +472,7 @@ const HELP_TABLE = [
|
|
|
447
472
|
// been dispatchable since TUI2-R1 slice 6 and was never listed here,
|
|
448
473
|
// so the only way to learn it existed was to read the source.
|
|
449
474
|
["/context", "show where the context went — the per-request rent ledger"],
|
|
450
|
-
["/mode", "show the approval tier; /mode <name> switches (
|
|
475
|
+
["/mode", "show the approval tier; /mode <name> switches (default/accept-edits/plan/dontAsk/bypass)"],
|
|
451
476
|
["/model", "list model profiles; /model <name|provider/model> switches"],
|
|
452
477
|
["/compact", "summarize the older conversation to free context"],
|
|
453
478
|
["/clear", "start a fresh conversation (the old session stays resumable)"],
|
|
@@ -455,6 +480,12 @@ const HELP_TABLE = [
|
|
|
455
480
|
// §2.5: the conversation is untouched — this rereads what kiso was
|
|
456
481
|
// built with, not what it has said.
|
|
457
482
|
["/reload", "reread extensions, skills and config into this session"],
|
|
483
|
+
// 0.40.0: a skill is a user turn — its SKILL.md, then your args. The
|
|
484
|
+
// `/<name>` row says the rule a person needs before they install a
|
|
485
|
+
// skill named like a command: the command wins.
|
|
486
|
+
["/skills", "list the installed skills, and any that cannot load"],
|
|
487
|
+
["/skill", "run a skill as your turn: /skill <name> [args]"],
|
|
488
|
+
["/<name>", "runs the skill <name> when no command above has that name"],
|
|
458
489
|
// §2.2: the two shell gestures and their one escape. They sit
|
|
459
490
|
// beside the slash commands because that is what a reader is
|
|
460
491
|
// looking for when they look here, even though `!` is not one.
|
|
@@ -477,10 +508,10 @@ const HELP_TABLE = [
|
|
|
477
508
|
// table is mentioned here. DC-1 changes the PADDING, not the words.
|
|
478
509
|
["keys", "enter sends \u00b7 ctrl+J newline (shift+enter where encoded) \u00b7 esc stops the run \u00b7 alt+\u23ce stops it and sends this instead \u00b7 @ files \u00b7 1-4 answers an ask"],
|
|
479
510
|
];
|
|
480
|
-
/** The slash commands `/help` lists. The keys
|
|
481
|
-
* table are not commands and are not here. */
|
|
511
|
+
/** The slash commands `/help` lists. The keys, the `!` gestures and the
|
|
512
|
+
* `/<name>` skill rule in the table are not commands and are not here. */
|
|
482
513
|
export function slashCommandNames() {
|
|
483
|
-
return HELP_TABLE.map(([name]) => name).filter((n) => n
|
|
514
|
+
return HELP_TABLE.map(([name]) => name).filter((n) => /^\/[a-z]+$/.test(n));
|
|
484
515
|
}
|
|
485
516
|
export function helpRows() {
|
|
486
517
|
const p = palette();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vincemakes/kiso-tui-cells",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.40.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",
|