@vincemakes/kiso-tui-cells 0.9.0 → 0.11.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/approval-panel.d.ts +75 -0
- package/dist/approval-panel.js +93 -1
- package/dist/components.d.ts +45 -2
- package/dist/components.js +94 -29
- package/dist/index.d.ts +2 -1
- package/dist/index.js +4 -1
- package/dist/md.d.ts +137 -0
- package/dist/md.js +720 -0
- package/dist/render.d.ts +18 -0
- package/dist/render.js +2 -2
- package/dist/strings.d.ts +4 -0
- package/dist/strings.js +34 -0
- package/dist/width.d.ts +30 -6
- package/dist/width.js +145 -26
- package/package.json +1 -1
package/dist/render.d.ts
CHANGED
|
@@ -34,7 +34,25 @@ export interface Palette {
|
|
|
34
34
|
readonly dim: string;
|
|
35
35
|
readonly red: string;
|
|
36
36
|
readonly green: string;
|
|
37
|
+
/** TUI2-R2 ①: the third functional exception, finally spelled. The
|
|
38
|
+
* mono-discipline ruling above names "green ✓, yellow warn and red
|
|
39
|
+
* error" as the ONLY functional colours; warn had no entry because
|
|
40
|
+
* nothing had needed it yet. The uncertain badge needs exactly it —
|
|
41
|
+
* a state that is neither success nor failure but a question
|
|
42
|
+
* addressed to the human. This is the ruling's own set gaining its
|
|
43
|
+
* missing member, not a fourth colour. */
|
|
44
|
+
readonly warn: string;
|
|
37
45
|
readonly code: string;
|
|
46
|
+
/** TUI2-MD (MD-1, the owner's circle) — the markdown round's ONE new
|
|
47
|
+
* member. `*italic*` needs a rendering, and under the mono discipline
|
|
48
|
+
* the answer cannot be a colour: SGR 3 is an ATTRIBUTE, it costs the
|
|
49
|
+
* alphabet nothing chromatic, and a terminal without italics simply
|
|
50
|
+
* draws the text — a harmless degradation rather than a lie.
|
|
51
|
+
* It ships with its own close (23) for the same reason `rv` does: an
|
|
52
|
+
* italic span inside a bold heading must be able to end WITHOUT the
|
|
53
|
+
* SGR-0 that would strand the heading's own style. */
|
|
54
|
+
readonly italic: string;
|
|
55
|
+
readonly italicEnd: string;
|
|
38
56
|
readonly rv: string;
|
|
39
57
|
readonly rvEnd: string;
|
|
40
58
|
readonly reset: string;
|
package/dist/render.js
CHANGED
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
* dependencies (the tui-cells package has none).
|
|
7
7
|
*/
|
|
8
8
|
import { charWidth, displayWidth } from "./width.js";
|
|
9
|
-
export const COLOR_ON = { bold: "\x1b[1m", dim: "\x1b[2m", red: "\x1b[31m", green: "\x1b[32m", code: "\x1b[38;5;252m", rv: "\x1b[7m", rvEnd: "\x1b[27m", reset: "\x1b[0m" };
|
|
10
|
-
export const COLOR_OFF = { bold: "", dim: "", red: "", green: "", code: "", rv: "", rvEnd: "", reset: "" };
|
|
9
|
+
export const COLOR_ON = { bold: "\x1b[1m", dim: "\x1b[2m", red: "\x1b[31m", green: "\x1b[32m", warn: "\x1b[33m", code: "\x1b[38;5;252m", italic: "\x1b[3m", italicEnd: "\x1b[23m", rv: "\x1b[7m", rvEnd: "\x1b[27m", reset: "\x1b[0m" };
|
|
10
|
+
export const COLOR_OFF = { bold: "", dim: "", red: "", green: "", warn: "", code: "", italic: "", italicEnd: "", rv: "", rvEnd: "", reset: "" };
|
|
11
11
|
export function palette() {
|
|
12
12
|
return process.env.NO_COLOR === undefined && process.stdout.isTTY ? COLOR_ON : COLOR_OFF;
|
|
13
13
|
}
|
package/dist/strings.d.ts
CHANGED
|
@@ -111,6 +111,10 @@ export interface KeyBinding {
|
|
|
111
111
|
* then the completions.
|
|
112
112
|
*/
|
|
113
113
|
export declare const KEY_BINDINGS: readonly KeyBinding[];
|
|
114
|
+
/** A tool's name as the SCREEN says it. Display-only: the raw name stays
|
|
115
|
+
* on the cell, and dispatch, the mode gate, the policy keys, the /last
|
|
116
|
+
* RAW block and every model-facing byte keep reading that. */
|
|
117
|
+
export declare function displayVerb(name: string): string;
|
|
114
118
|
/** The panel keys, which belong to a panel rather than the composer —
|
|
115
119
|
* one dim line rather than four table rows, because they apply only
|
|
116
120
|
* while a panel is up. */
|
package/dist/strings.js
CHANGED
|
@@ -155,6 +155,40 @@ export const KEY_BINDINGS = [
|
|
|
155
155
|
{ keys: "tab", what: "complete (menu / @)" },
|
|
156
156
|
{ keys: "?", what: "this sheet" },
|
|
157
157
|
];
|
|
158
|
+
/**
|
|
159
|
+
* TUI2-R2pre ④ — THE display-verb table (the integrator's ruling).
|
|
160
|
+
*
|
|
161
|
+
* The screen names the ACT; the tool table names the CALL. Two
|
|
162
|
+
* audiences, two vocabularies, and only the human's one lives here: the
|
|
163
|
+
* API names DO NOT change, because the model-request surface is frozen
|
|
164
|
+
* rent and every byte of it is paid for on every turn. The
|
|
165
|
+
* rename-the-tools path is REJECTED by ruling.
|
|
166
|
+
*
|
|
167
|
+
* One table, for the same reason KEY_BINDINGS above is one table. The
|
|
168
|
+
* mapping used to exist three and a half times — a `.replace("_file",
|
|
169
|
+
* "")` in components.ts, another in render.ts, two more in the
|
|
170
|
+
* compositor, and a private three-tool table for the rollup's expanded
|
|
171
|
+
* list — and the drift was visible on a single screen: a card head
|
|
172
|
+
* reading `read` directly above one reading `list_dir`.
|
|
173
|
+
*
|
|
174
|
+
* An unmapped tool (an extension's, an MCP server's) renders its own
|
|
175
|
+
* name. Inventing a verb for a tool this package has never heard of
|
|
176
|
+
* would be a worse lie than printing what the model actually calls.
|
|
177
|
+
*/
|
|
178
|
+
const DISPLAY_VERB = {
|
|
179
|
+
read_file: "read",
|
|
180
|
+
list_dir: "list",
|
|
181
|
+
search_text: "search",
|
|
182
|
+
write_file: "write",
|
|
183
|
+
edit_file: "edit",
|
|
184
|
+
shell: "shell",
|
|
185
|
+
};
|
|
186
|
+
/** A tool's name as the SCREEN says it. Display-only: the raw name stays
|
|
187
|
+
* on the cell, and dispatch, the mode gate, the policy keys, the /last
|
|
188
|
+
* RAW block and every model-facing byte keep reading that. */
|
|
189
|
+
export function displayVerb(name) {
|
|
190
|
+
return DISPLAY_VERB[name] ?? name;
|
|
191
|
+
}
|
|
158
192
|
/** The panel keys, which belong to a panel rather than the composer —
|
|
159
193
|
* one dim line rather than four table rows, because they apply only
|
|
160
194
|
* while a panel is up. */
|
package/dist/width.d.ts
CHANGED
|
@@ -1,18 +1,42 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The display-width primitives — the SINGLE width authority (TUI v5
|
|
3
|
-
* #16e: "charWidth is the width authority"). The
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
3
|
+
* #16e: "charWidth is the width authority"). The table covers the East
|
|
4
|
+
* Asian Wide/Fullwidth ranges and Emoji_Presentation=Yes; everything
|
|
5
|
+
* else is one column, the box-drawing/brick glyphs █▀▄▞▸ and the text-
|
|
6
|
+
* presentation marks ✓ ✗ ⚠ ⏸ included.
|
|
7
|
+
*
|
|
8
|
+
* This is the compositor's FLOOR, not a cosmetic detail: a glyph scored
|
|
9
|
+
* one column that a terminal draws in two makes a line whose measured
|
|
10
|
+
* width is <= W really need W+1, the terminal soft-wraps the tail onto
|
|
11
|
+
* the row below, and the live region silently eats a row it never
|
|
12
|
+
* budgeted (TUI2-R2pre ① — the composer clobber).
|
|
13
|
+
*
|
|
14
|
+
* Known limitation, documented in the README: emoji ZWJ clusters and
|
|
15
|
+
* variation-selector sequences are not guaranteed perfect — each code
|
|
16
|
+
* point counts as its own width (U+26A0 + FE0F sums to 2, which is what
|
|
17
|
+
* a terminal draws, but that is arithmetic luck, not a model).
|
|
18
|
+
* Zero dependencies (importable from any module).
|
|
9
19
|
*/
|
|
10
20
|
/** A code point's display width: 2 for the wide ranges, 1 otherwise. */
|
|
11
21
|
export declare function charWidth(cp: number): number;
|
|
22
|
+
/** TUI2-MD ③ — may a row break immediately before/after this code
|
|
23
|
+
* point? True for the CJK scripts (they break between any two
|
|
24
|
+
* characters), false for everything else INCLUDING the wide
|
|
25
|
+
* pictographs. The wrapper asks this; the width table answers it. */
|
|
26
|
+
export declare function breakable(cp: number): boolean;
|
|
12
27
|
/** Display width of a code-point array (cursor math, scrolling). */
|
|
13
28
|
export declare function widthOf(chars: readonly number[]): number;
|
|
14
29
|
/** Display width of a string. */
|
|
15
30
|
export declare function displayWidth(text: string): number;
|
|
31
|
+
/** The visible width of a RENDERED line — the same table, asked with
|
|
32
|
+
* the SGR/CSI sequences skipped. The compositor's invariant ① measures
|
|
33
|
+
* with this, so every producer of a screen row must measure with it
|
|
34
|
+
* too. TUI2-MD ⑤: moved here verbatim from components.ts, where it had
|
|
35
|
+
* lived since the extraction. The markdown renderer needs it and
|
|
36
|
+
* components.ts needs the markdown renderer — and a width question
|
|
37
|
+
* belongs to the width authority anyway. components.ts re-exports it,
|
|
38
|
+
* so every existing importer and the barrel are untouched. */
|
|
39
|
+
export declare function visibleWidth(line: string): number;
|
|
16
40
|
/** A LEAD's display width — the prompt / the panel's phase lead,
|
|
17
41
|
* ANSI-stripped. W23: the ONE width authority shared by the editor
|
|
18
42
|
* (selfRender, #reflow), the compositor's #inputRow, and editCol — a
|
package/dist/width.js
CHANGED
|
@@ -1,47 +1,141 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The display-width primitives — the SINGLE width authority (TUI v5
|
|
3
|
-
* #16e: "charWidth is the width authority"). The
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
3
|
+
* #16e: "charWidth is the width authority"). The table covers the East
|
|
4
|
+
* Asian Wide/Fullwidth ranges and Emoji_Presentation=Yes; everything
|
|
5
|
+
* else is one column, the box-drawing/brick glyphs █▀▄▞▸ and the text-
|
|
6
|
+
* presentation marks ✓ ✗ ⚠ ⏸ included.
|
|
7
|
+
*
|
|
8
|
+
* This is the compositor's FLOOR, not a cosmetic detail: a glyph scored
|
|
9
|
+
* one column that a terminal draws in two makes a line whose measured
|
|
10
|
+
* width is <= W really need W+1, the terminal soft-wraps the tail onto
|
|
11
|
+
* the row below, and the live region silently eats a row it never
|
|
12
|
+
* budgeted (TUI2-R2pre ① — the composer clobber).
|
|
13
|
+
*
|
|
14
|
+
* Known limitation, documented in the README: emoji ZWJ clusters and
|
|
15
|
+
* variation-selector sequences are not guaranteed perfect — each code
|
|
16
|
+
* point counts as its own width (U+26A0 + FE0F sums to 2, which is what
|
|
17
|
+
* a terminal draws, but that is arithmetic luck, not a model).
|
|
18
|
+
* Zero dependencies (importable from any module).
|
|
9
19
|
*/
|
|
10
|
-
/**
|
|
11
|
-
|
|
20
|
+
/** TUI2-R2pre ① — the Emoji_Presentation=Yes code points inside
|
|
21
|
+
* U+2000..U+2BFF. The rest of that span is TEXT presentation and stays
|
|
22
|
+
* one column: ✓ ✗ ⚠ ⏸ ▞ ▸ and the box-drawing rails are all narrow, and
|
|
23
|
+
* widening any of them would move every card head on the screen. Listed
|
|
24
|
+
* as ranges because that is what the property is — the singles are
|
|
25
|
+
* singles in Unicode too. */
|
|
26
|
+
const EMOJI_PRESENTATION = [
|
|
27
|
+
[0x231a, 0x231b],
|
|
28
|
+
[0x23e9, 0x23ec],
|
|
29
|
+
[0x23f0, 0x23f0],
|
|
30
|
+
[0x23f3, 0x23f3],
|
|
31
|
+
[0x25fd, 0x25fe],
|
|
32
|
+
[0x2614, 0x2615],
|
|
33
|
+
[0x2648, 0x2653],
|
|
34
|
+
[0x267f, 0x267f],
|
|
35
|
+
[0x2693, 0x2693],
|
|
36
|
+
[0x26a1, 0x26a1],
|
|
37
|
+
[0x26aa, 0x26ab],
|
|
38
|
+
[0x26bd, 0x26be],
|
|
39
|
+
[0x26c4, 0x26c5],
|
|
40
|
+
[0x26ce, 0x26ce],
|
|
41
|
+
[0x26d4, 0x26d4],
|
|
42
|
+
[0x26ea, 0x26ea],
|
|
43
|
+
[0x26f2, 0x26f3],
|
|
44
|
+
[0x26f5, 0x26f5],
|
|
45
|
+
[0x26fa, 0x26fa],
|
|
46
|
+
[0x26fd, 0x26fd],
|
|
47
|
+
[0x2705, 0x2705],
|
|
48
|
+
[0x270a, 0x270b],
|
|
49
|
+
[0x2728, 0x2728],
|
|
50
|
+
[0x274c, 0x274c],
|
|
51
|
+
[0x274e, 0x274e],
|
|
52
|
+
[0x2753, 0x2755],
|
|
53
|
+
[0x2757, 0x2757],
|
|
54
|
+
[0x2795, 0x2797],
|
|
55
|
+
[0x27b0, 0x27b0],
|
|
56
|
+
[0x27bf, 0x27bf],
|
|
57
|
+
[0x2b1b, 0x2b1c],
|
|
58
|
+
[0x2b50, 0x2b50],
|
|
59
|
+
[0x2b55, 0x2b55],
|
|
60
|
+
];
|
|
61
|
+
/** TUI2-MD ③ — the CJK half of the wide table, split out so the SAME
|
|
62
|
+
* ranges answer a SECOND question: may a line break here? The width
|
|
63
|
+
* authority stays one table; the break class is a view of it, never a
|
|
64
|
+
* fork (a second copy would drift, and a drifted width table is the
|
|
65
|
+
* composer clobber all over again).
|
|
66
|
+
*
|
|
67
|
+
* These scripts break between any two characters, which is why a
|
|
68
|
+
* space-free CJK run must not be treated as one unbreakable word: a
|
|
69
|
+
* whitespace-only wrapper cannot place it at all. */
|
|
70
|
+
function cjkWide(cp) {
|
|
12
71
|
if (cp >= 0x1100 && cp <= 0x115f)
|
|
13
|
-
return
|
|
72
|
+
return true; // hangul jamo
|
|
14
73
|
if (cp >= 0x2e80 && cp <= 0x303e)
|
|
15
|
-
return
|
|
74
|
+
return true; // radicals .. CJK punctuation
|
|
16
75
|
if (cp >= 0x3041 && cp <= 0x33ff)
|
|
17
|
-
return
|
|
76
|
+
return true; // kana, CJK compat
|
|
18
77
|
if (cp >= 0x3400 && cp <= 0x4dbf)
|
|
19
|
-
return
|
|
78
|
+
return true; // CJK ext A
|
|
20
79
|
if (cp >= 0x4e00 && cp <= 0x9fff)
|
|
21
|
-
return
|
|
80
|
+
return true; // CJK unified
|
|
22
81
|
if (cp >= 0xa000 && cp <= 0xa4cf)
|
|
23
|
-
return
|
|
82
|
+
return true; // yi
|
|
24
83
|
if (cp >= 0xa960 && cp <= 0xa97f)
|
|
25
|
-
return
|
|
84
|
+
return true; // hangul jamo ext
|
|
26
85
|
if (cp >= 0xac00 && cp <= 0xd7a3)
|
|
27
|
-
return
|
|
86
|
+
return true; // hangul syllables
|
|
28
87
|
if (cp >= 0xf900 && cp <= 0xfaff)
|
|
29
|
-
return
|
|
88
|
+
return true; // CJK compat ideographs
|
|
30
89
|
if (cp >= 0xfe10 && cp <= 0xfe19)
|
|
31
|
-
return
|
|
90
|
+
return true; // vertical forms
|
|
32
91
|
if (cp >= 0xfe30 && cp <= 0xfe6f)
|
|
33
|
-
return
|
|
92
|
+
return true; // CJK compat forms
|
|
34
93
|
if (cp >= 0xff00 && cp <= 0xff60)
|
|
35
|
-
return
|
|
94
|
+
return true; // fullwidth forms
|
|
36
95
|
if (cp >= 0xffe0 && cp <= 0xffe6)
|
|
37
|
-
return
|
|
96
|
+
return true; // fullwidth signs
|
|
97
|
+
return cp >= 0x20000 && cp <= 0x3fffd; // CJK ext B..G
|
|
98
|
+
}
|
|
99
|
+
/** The PICTOGRAPHIC half: wide, and deliberately NOT breakable — a
|
|
100
|
+
* ZWJ/variation sequence must survive a line break whole. */
|
|
101
|
+
function emojiWide(cp) {
|
|
102
|
+
// TUI2-R1.5 shipped only two of the pictographic ranges; the holes
|
|
103
|
+
// (transport, mahjong/cards, enclosed, colored shapes, the extended
|
|
104
|
+
// block) were scored ONE column while every terminal draws them in
|
|
105
|
+
// two — the composer clobber of the owner's field report (①).
|
|
106
|
+
if (cp === 0x1f004 || cp === 0x1f0cf)
|
|
107
|
+
return true; // mahjong red dragon, joker
|
|
108
|
+
if (cp >= 0x1f18e && cp <= 0x1f19a)
|
|
109
|
+
return true; // enclosed alphanumerics
|
|
110
|
+
if (cp >= 0x1f200 && cp <= 0x1f251)
|
|
111
|
+
return true; // enclosed ideographic
|
|
38
112
|
if (cp >= 0x1f300 && cp <= 0x1f64f)
|
|
39
|
-
return
|
|
113
|
+
return true; // emoji (misc + emoticons)
|
|
114
|
+
if (cp >= 0x1f680 && cp <= 0x1f6ff)
|
|
115
|
+
return true; // transport + map
|
|
116
|
+
if (cp >= 0x1f7e0 && cp <= 0x1f7eb)
|
|
117
|
+
return true; // colored circles + squares
|
|
40
118
|
if (cp >= 0x1f900 && cp <= 0x1f9ff)
|
|
41
|
-
return
|
|
42
|
-
if (cp >=
|
|
43
|
-
return
|
|
44
|
-
|
|
119
|
+
return true; // supplemental emoji
|
|
120
|
+
if (cp >= 0x1fa70 && cp <= 0x1faff)
|
|
121
|
+
return true; // symbols + pictographs ext-A
|
|
122
|
+
if (cp >= 0x231a && cp <= 0x2b55) {
|
|
123
|
+
for (const [lo, hi] of EMOJI_PRESENTATION)
|
|
124
|
+
if (cp >= lo && cp <= hi)
|
|
125
|
+
return true;
|
|
126
|
+
}
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
129
|
+
/** A code point's display width: 2 for the wide ranges, 1 otherwise. */
|
|
130
|
+
export function charWidth(cp) {
|
|
131
|
+
return cjkWide(cp) || emojiWide(cp) ? 2 : 1;
|
|
132
|
+
}
|
|
133
|
+
/** TUI2-MD ③ — may a row break immediately before/after this code
|
|
134
|
+
* point? True for the CJK scripts (they break between any two
|
|
135
|
+
* characters), false for everything else INCLUDING the wide
|
|
136
|
+
* pictographs. The wrapper asks this; the width table answers it. */
|
|
137
|
+
export function breakable(cp) {
|
|
138
|
+
return cjkWide(cp);
|
|
45
139
|
}
|
|
46
140
|
/** Display width of a code-point array (cursor math, scrolling). */
|
|
47
141
|
export function widthOf(chars) {
|
|
@@ -57,6 +151,31 @@ export function displayWidth(text) {
|
|
|
57
151
|
w += charWidth(ch.codePointAt(0));
|
|
58
152
|
return w;
|
|
59
153
|
}
|
|
154
|
+
/** The visible width of a RENDERED line — the same table, asked with
|
|
155
|
+
* the SGR/CSI sequences skipped. The compositor's invariant ① measures
|
|
156
|
+
* with this, so every producer of a screen row must measure with it
|
|
157
|
+
* too. TUI2-MD ⑤: moved here verbatim from components.ts, where it had
|
|
158
|
+
* lived since the extraction. The markdown renderer needs it and
|
|
159
|
+
* components.ts needs the markdown renderer — and a width question
|
|
160
|
+
* belongs to the width authority anyway. components.ts re-exports it,
|
|
161
|
+
* so every existing importer and the barrel are untouched. */
|
|
162
|
+
export function visibleWidth(line) {
|
|
163
|
+
let w = 0;
|
|
164
|
+
for (let i = 0; i < line.length;) {
|
|
165
|
+
if (line[i] === "\x1b") {
|
|
166
|
+
const m = /^\x1b\[[0-9;?]*[A-Za-z]/.exec(line.slice(i));
|
|
167
|
+
if (m !== null) {
|
|
168
|
+
i += m[0].length;
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
i += 1;
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
w += displayWidth(line[i]);
|
|
175
|
+
i += 1;
|
|
176
|
+
}
|
|
177
|
+
return w;
|
|
178
|
+
}
|
|
60
179
|
/** A LEAD's display width — the prompt / the panel's phase lead,
|
|
61
180
|
* ANSI-stripped. W23: the ONE width authority shared by the editor
|
|
62
181
|
* (selfRender, #reflow), the compositor's #inputRow, and editCol — a
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vincemakes/kiso-tui-cells",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"description": "kiso tui-cells — 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",
|