@vincemakes/kiso-tui-cells 0.46.2 → 0.47.1
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 +149 -62
- package/dist/approval-panel.js +346 -227
- package/dist/components.d.ts +151 -21
- package/dist/components.js +1242 -825
- package/dist/diff.d.ts +40 -3
- package/dist/diff.js +142 -5
- package/dist/graphite.d.ts +143 -0
- package/dist/graphite.js +311 -0
- package/dist/index.d.ts +6 -3
- package/dist/index.js +6 -3
- package/dist/md.d.ts +18 -7
- package/dist/md.js +290 -37
- package/dist/render.d.ts +136 -27
- package/dist/render.js +381 -137
- package/dist/strings.d.ts +47 -46
- package/dist/strings.js +130 -171
- package/package.json +1 -1
package/dist/diff.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* v2e — the diff renderer: edit/write changes as inline ± lines, zero
|
|
3
|
-
* dependencies, no syntax highlighting (the spec's scope line).
|
|
4
|
-
* the approval moment
|
|
5
|
-
*
|
|
3
|
+
* dependencies, no syntax highlighting (the spec's scope line). v2e drew
|
|
4
|
+
* it at the approval moment only; Graphite §6 (R2a) draws it on every
|
|
5
|
+
* edit's card too, from the call's own hunks (`hunksDiff`) — DECLARED
|
|
6
|
+
* REVERSAL of "the frozen summary stays one line".
|
|
6
7
|
*
|
|
7
8
|
* edit_file diffs IN PLACE (the search→replace windows are known — no
|
|
8
9
|
* general engine needed); write_file does a row-level LCS over the old
|
|
@@ -17,7 +18,17 @@
|
|
|
17
18
|
export type DiffLine = {
|
|
18
19
|
kind: "-" | "+" | " " | "note";
|
|
19
20
|
text: string;
|
|
21
|
+
/** Graphite §6 (R2a): the changed WORDS of a line that replaced one
|
|
22
|
+
* other line — `[start, end)` offsets into `text`, sorted, disjoint.
|
|
23
|
+
* Absent everywhere else. */
|
|
24
|
+
marks?: readonly (readonly [number, number])[];
|
|
20
25
|
};
|
|
26
|
+
/** One change an edit_file call asks for: the text it looks for, and what
|
|
27
|
+
* replaces it. */
|
|
28
|
+
export interface Hunk {
|
|
29
|
+
readonly search: string;
|
|
30
|
+
readonly replace: string;
|
|
31
|
+
}
|
|
21
32
|
export interface DiffResult {
|
|
22
33
|
/** The FULL diff (with context, not truncated) — the display truncates. */
|
|
23
34
|
lines: DiffLine[];
|
|
@@ -44,6 +55,8 @@ export interface DiffResult {
|
|
|
44
55
|
* changes meaning. */
|
|
45
56
|
notFound?: true;
|
|
46
57
|
}
|
|
58
|
+
/** A line-level LCS diff — the classic two-row DP, ~small inputs. */
|
|
59
|
+
export declare function lcsDiff(oldLines: string[], newLines: string[]): DiffLine[];
|
|
47
60
|
/** The RENDERER's truncation: head + "… N lines (/last for full)" + tail. */
|
|
48
61
|
export declare function truncateDiff(diff: DiffLine[]): DiffLine[];
|
|
49
62
|
/** edit_file: the preview of a CHARACTER splice.
|
|
@@ -72,3 +85,27 @@ export declare function editFileDiff(oldContent: string, search: string, replace
|
|
|
72
85
|
/** write_file: a new file is all +; an existing file diffs row-level
|
|
73
86
|
* against its old content. */
|
|
74
87
|
export declare function writeFileDiff(oldContent: string | null, newContent: string): DiffResult;
|
|
88
|
+
/** The hunks an edit_file call carries: its `edits`, or its one
|
|
89
|
+
* `search`/`replace` pair. Null when the input has neither (the tool
|
|
90
|
+
* refuses such a call, so there is nothing to draw). */
|
|
91
|
+
export declare function hunksOf(input: Record<string, unknown>): Hunk[] | null;
|
|
92
|
+
/** Graphite §6 (R2a) — what an edit CHANGED, drawn from the call's own
|
|
93
|
+
* hunks: per hunk a line LCS of `search` against `replace`, the lines
|
|
94
|
+
* both keep as context (two around each change), a `···` note between
|
|
95
|
+
* hunks, and word marks where one line replaced one line. The file is
|
|
96
|
+
* never read, so the diff is a pure function of the durable log — the
|
|
97
|
+
* same live, after a reprint, after resume. */
|
|
98
|
+
export declare function hunksDiff(hunks: readonly Hunk[]): DiffResult;
|
|
99
|
+
/** The approval preview of a batch: the hunks applied IN ORDER, each to
|
|
100
|
+
* the text the ones before it left — the tool's own rule (ACI-3) — and
|
|
101
|
+
* the result diffed against the file. A hunk the tool would refuse (not
|
|
102
|
+
* there, or there more than once) is named, and nothing is drawn: the
|
|
103
|
+
* tool writes all of the batch or none of it. */
|
|
104
|
+
export declare function editFileHunksDiff(oldContent: string, hunks: readonly Hunk[], path?: string): DiffResult;
|
|
105
|
+
/** A line's tokens: runs of word characters, runs of spaces, and every
|
|
106
|
+
* other character on its own. Joined, they are the line. */
|
|
107
|
+
export declare function wordTokens(line: string): string[];
|
|
108
|
+
/** The token LCS of two lines: for each side, the `[start, end)` offsets
|
|
109
|
+
* of the tokens the other side does not keep, adjacent ones merged.
|
|
110
|
+
* Null when too little survives for marks to mean anything. */
|
|
111
|
+
export declare function tokenMarks(a: string, b: string): [Array<[number, number]> | null, Array<[number, number]> | null];
|
package/dist/diff.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* v2e — the diff renderer: edit/write changes as inline ± lines, zero
|
|
3
|
-
* dependencies, no syntax highlighting (the spec's scope line).
|
|
4
|
-
* the approval moment
|
|
5
|
-
*
|
|
3
|
+
* dependencies, no syntax highlighting (the spec's scope line). v2e drew
|
|
4
|
+
* it at the approval moment only; Graphite §6 (R2a) draws it on every
|
|
5
|
+
* edit's card too, from the call's own hunks (`hunksDiff`) — DECLARED
|
|
6
|
+
* REVERSAL of "the frozen summary stays one line".
|
|
6
7
|
*
|
|
7
8
|
* edit_file diffs IN PLACE (the search→replace windows are known — no
|
|
8
9
|
* general engine needed); write_file does a row-level LCS over the old
|
|
@@ -11,7 +12,7 @@
|
|
|
11
12
|
* from the full diff.
|
|
12
13
|
*/
|
|
13
14
|
/** A line-level LCS diff — the classic two-row DP, ~small inputs. */
|
|
14
|
-
function lcsDiff(oldLines, newLines) {
|
|
15
|
+
export function lcsDiff(oldLines, newLines) {
|
|
15
16
|
const n = oldLines.length;
|
|
16
17
|
const m = newLines.length;
|
|
17
18
|
const dp = Array.from({ length: n + 1 }, () => new Array(m + 1).fill(0));
|
|
@@ -138,7 +139,7 @@ export function editFileDiff(oldContent, search, replace, path) {
|
|
|
138
139
|
};
|
|
139
140
|
}
|
|
140
141
|
const result = oldContent.slice(0, at) + replace + oldContent.slice(at + search.length);
|
|
141
|
-
const lines = withContext(lcsDiff(oldContent.split("\n"), result.split("\n")));
|
|
142
|
+
const lines = withMarks(withContext(lcsDiff(oldContent.split("\n"), result.split("\n"))));
|
|
142
143
|
return { lines, ...stats(lines), outcome: "diff" };
|
|
143
144
|
}
|
|
144
145
|
/** write_file: a new file is all +; an existing file diffs row-level
|
|
@@ -151,3 +152,139 @@ export function writeFileDiff(oldContent, newContent) {
|
|
|
151
152
|
const lines = withContext(lcsDiff(oldContent.split("\n"), newContent.split("\n")));
|
|
152
153
|
return { lines, ...stats(lines), outcome: "diff" };
|
|
153
154
|
}
|
|
155
|
+
/** The hunks an edit_file call carries: its `edits`, or its one
|
|
156
|
+
* `search`/`replace` pair. Null when the input has neither (the tool
|
|
157
|
+
* refuses such a call, so there is nothing to draw). */
|
|
158
|
+
export function hunksOf(input) {
|
|
159
|
+
const pair = (x) => {
|
|
160
|
+
if (typeof x !== "object" || x === null)
|
|
161
|
+
return null;
|
|
162
|
+
const { search, replace } = x;
|
|
163
|
+
return typeof search === "string" && typeof replace === "string" ? { search, replace } : null;
|
|
164
|
+
};
|
|
165
|
+
if (Array.isArray(input.edits)) {
|
|
166
|
+
const hunks = input.edits.map(pair);
|
|
167
|
+
return hunks.length > 0 && hunks.every((h) => h !== null) ? hunks : null;
|
|
168
|
+
}
|
|
169
|
+
const one = pair(input);
|
|
170
|
+
return one === null ? null : [one];
|
|
171
|
+
}
|
|
172
|
+
/** Graphite §6 (R2a) — what an edit CHANGED, drawn from the call's own
|
|
173
|
+
* hunks: per hunk a line LCS of `search` against `replace`, the lines
|
|
174
|
+
* both keep as context (two around each change), a `···` note between
|
|
175
|
+
* hunks, and word marks where one line replaced one line. The file is
|
|
176
|
+
* never read, so the diff is a pure function of the durable log — the
|
|
177
|
+
* same live, after a reprint, after resume. */
|
|
178
|
+
export function hunksDiff(hunks) {
|
|
179
|
+
const lines = [];
|
|
180
|
+
for (const [i, h] of hunks.entries()) {
|
|
181
|
+
const one = withMarks(withContext(lcsDiff(h.search.split("\n"), h.replace.split("\n"))));
|
|
182
|
+
if (one.length === 0)
|
|
183
|
+
continue;
|
|
184
|
+
if (i > 0 && lines.length > 0)
|
|
185
|
+
lines.push({ kind: "note", text: "\u00b7\u00b7\u00b7" });
|
|
186
|
+
lines.push(...one);
|
|
187
|
+
}
|
|
188
|
+
return { lines, ...stats(lines), outcome: "diff" };
|
|
189
|
+
}
|
|
190
|
+
/** The approval preview of a batch: the hunks applied IN ORDER, each to
|
|
191
|
+
* the text the ones before it left — the tool's own rule (ACI-3) — and
|
|
192
|
+
* the result diffed against the file. A hunk the tool would refuse (not
|
|
193
|
+
* there, or there more than once) is named, and nothing is drawn: the
|
|
194
|
+
* tool writes all of the batch or none of it. */
|
|
195
|
+
export function editFileHunksDiff(oldContent, hunks, path) {
|
|
196
|
+
if (hunks.length === 1)
|
|
197
|
+
return editFileDiff(oldContent, hunks[0].search, hunks[0].replace, path);
|
|
198
|
+
const where = path ?? "the file";
|
|
199
|
+
let edited = oldContent;
|
|
200
|
+
for (const [i, h] of hunks.entries()) {
|
|
201
|
+
const at = edited.indexOf(h.search);
|
|
202
|
+
const which = i === 0 ? "hunk 1" : `hunk ${i + 1}, after ${i === 1 ? "hunk 1" : `hunks 1\u2013${i}`} applied`;
|
|
203
|
+
if (at < 0)
|
|
204
|
+
return { lines: [{ kind: "note", text: `pattern not found in ${where} (${which})` }], added: 0, removed: 0, outcome: "not-found", notFound: true };
|
|
205
|
+
if (h.search.length > 0 && edited.indexOf(h.search, at + 1) > at) {
|
|
206
|
+
return { lines: [{ kind: "note", text: `pattern matches more than one place in ${where} (${which})` }], added: 0, removed: 0, outcome: "ambiguous" };
|
|
207
|
+
}
|
|
208
|
+
edited = edited.slice(0, at) + h.replace + edited.slice(at + h.search.length);
|
|
209
|
+
}
|
|
210
|
+
const lines = withMarks(withContext(lcsDiff(oldContent.split("\n"), edited.split("\n"))));
|
|
211
|
+
return { lines, ...stats(lines), outcome: "diff" };
|
|
212
|
+
}
|
|
213
|
+
/** A line's tokens: runs of word characters, runs of spaces, and every
|
|
214
|
+
* other character on its own. Joined, they are the line. */
|
|
215
|
+
export function wordTokens(line) {
|
|
216
|
+
return line.match(/[\p{L}\p{N}_]+|\s+|[\s\S]/gu) ?? [];
|
|
217
|
+
}
|
|
218
|
+
/** The share of a replaced line's tokens (spaces aside) that must survive
|
|
219
|
+
* for word marks to help: below it the whole line changed, and marking
|
|
220
|
+
* nearly every word says less than the line's own colour does. */
|
|
221
|
+
const MARK_MIN_KEPT = 0.34;
|
|
222
|
+
/** Word marks on a diff: every `-` line directly followed by one `+` line,
|
|
223
|
+
* with no other change beside the pair, gets the offsets of the tokens
|
|
224
|
+
* the other side does not keep (a token LCS). */
|
|
225
|
+
function withMarks(diff) {
|
|
226
|
+
const changed = (k) => k >= 0 && k < diff.length && (diff[k].kind === "-" || diff[k].kind === "+");
|
|
227
|
+
return diff.map((d, k) => {
|
|
228
|
+
const pairAt = d.kind === "-" ? k : d.kind === "+" ? k - 1 : -1;
|
|
229
|
+
if (pairAt < 0 || diff[pairAt]?.kind !== "-" || diff[pairAt + 1]?.kind !== "+" || changed(pairAt - 1) || changed(pairAt + 2))
|
|
230
|
+
return d;
|
|
231
|
+
const [oldMarks, newMarks] = tokenMarks(diff[pairAt].text, diff[pairAt + 1].text);
|
|
232
|
+
if (oldMarks === null || newMarks === null)
|
|
233
|
+
return d;
|
|
234
|
+
const marks = d.kind === "-" ? oldMarks : newMarks;
|
|
235
|
+
return marks.length === 0 ? d : { ...d, marks };
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
/** The token LCS of two lines: for each side, the `[start, end)` offsets
|
|
239
|
+
* of the tokens the other side does not keep, adjacent ones merged.
|
|
240
|
+
* Null when too little survives for marks to mean anything. */
|
|
241
|
+
export function tokenMarks(a, b) {
|
|
242
|
+
const ta = wordTokens(a);
|
|
243
|
+
const tb = wordTokens(b);
|
|
244
|
+
const n = ta.length;
|
|
245
|
+
const m = tb.length;
|
|
246
|
+
const dp = Array.from({ length: n + 1 }, () => new Array(m + 1).fill(0));
|
|
247
|
+
for (let i = n - 1; i >= 0; i -= 1) {
|
|
248
|
+
for (let j = m - 1; j >= 0; j -= 1)
|
|
249
|
+
dp[i][j] = ta[i] === tb[j] ? dp[i + 1][j + 1] + 1 : Math.max(dp[i + 1][j], dp[i][j + 1]);
|
|
250
|
+
}
|
|
251
|
+
const keptA = new Array(n).fill(false);
|
|
252
|
+
const keptB = new Array(m).fill(false);
|
|
253
|
+
for (let i = 0, j = 0; i < n && j < m;) {
|
|
254
|
+
if (ta[i] === tb[j]) {
|
|
255
|
+
keptA[i] = true;
|
|
256
|
+
keptB[j] = true;
|
|
257
|
+
i += 1;
|
|
258
|
+
j += 1;
|
|
259
|
+
}
|
|
260
|
+
else if (dp[i + 1][j] >= dp[i][j + 1])
|
|
261
|
+
i += 1;
|
|
262
|
+
else
|
|
263
|
+
j += 1;
|
|
264
|
+
}
|
|
265
|
+
const solid = (t) => /\S/.test(t);
|
|
266
|
+
const words = ta.filter(solid).length + tb.filter(solid).length;
|
|
267
|
+
const kept = ta.filter((t, i) => keptA[i] && solid(t)).length + tb.filter((t, j) => keptB[j] && solid(t)).length;
|
|
268
|
+
if (words === 0 || kept / words < MARK_MIN_KEPT)
|
|
269
|
+
return [null, null];
|
|
270
|
+
return [spans(ta, keptA), spans(tb, keptB)];
|
|
271
|
+
}
|
|
272
|
+
/** The offsets of the tokens not kept, adjacent spans merged; a run of
|
|
273
|
+
* spaces between two changed tokens joins them. */
|
|
274
|
+
function spans(tokens, kept) {
|
|
275
|
+
const line = tokens.join("");
|
|
276
|
+
const out = [];
|
|
277
|
+
let at = 0;
|
|
278
|
+
for (const [i, t] of tokens.entries()) {
|
|
279
|
+
const end = at + t.length;
|
|
280
|
+
if (!kept[i] && /\S/.test(t)) {
|
|
281
|
+
const last = out[out.length - 1];
|
|
282
|
+
if (last !== undefined && /^\s*$/.test(line.slice(last[1], at)))
|
|
283
|
+
last[1] = end;
|
|
284
|
+
else
|
|
285
|
+
out.push([at, end]);
|
|
286
|
+
}
|
|
287
|
+
at = end;
|
|
288
|
+
}
|
|
289
|
+
return out;
|
|
290
|
+
}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Graphite (design.md §2, §3.4) — the colour tokens, the output tier, and
|
|
3
|
+
* the surfaces derived from the ground the terminal actually reported.
|
|
4
|
+
*
|
|
5
|
+
* PURE: no process state is read except where a caller passes it in, so
|
|
6
|
+
* every decision here is testable without a terminal. `render.ts` turns
|
|
7
|
+
* these colours into SGR bytes; this module only decides the colours.
|
|
8
|
+
*/
|
|
9
|
+
import { type Rgb } from "./ground.js";
|
|
10
|
+
export type Kind = "light" | "dark";
|
|
11
|
+
/** How colour reaches the terminal: 24-bit (`38;2;r;g;b`) where the
|
|
12
|
+
* terminal says it renders it, the nearest xterm-256 index otherwise. */
|
|
13
|
+
export type Tier = "24bit" | "256";
|
|
14
|
+
/** The Graphite table (design.md §2), on the two reference grounds. */
|
|
15
|
+
export declare const GRAPHITE: {
|
|
16
|
+
readonly light: {
|
|
17
|
+
readonly ground: "#ffffff";
|
|
18
|
+
readonly ink: "#111111";
|
|
19
|
+
readonly ink2: "#444444";
|
|
20
|
+
readonly dim: "#646464";
|
|
21
|
+
readonly rail: "#8c8c8c";
|
|
22
|
+
readonly line: "#e6e6e6";
|
|
23
|
+
readonly washRun: "#edf2fb";
|
|
24
|
+
readonly washDone: "#f1f1f1";
|
|
25
|
+
readonly washFail: "#fbecea";
|
|
26
|
+
readonly washAsk: "#f7f1e3";
|
|
27
|
+
readonly human: "#f7efdc";
|
|
28
|
+
readonly humanInk: "#171923";
|
|
29
|
+
readonly gold: "#8a5a00";
|
|
30
|
+
readonly goldMark: "#c9921f";
|
|
31
|
+
readonly blue: "#2456b5";
|
|
32
|
+
readonly code: "#e4ebf8";
|
|
33
|
+
readonly ok: "#2f7a3a";
|
|
34
|
+
readonly fail: "#b3261e";
|
|
35
|
+
readonly add: "#dff0e2";
|
|
36
|
+
readonly del: "#fadfdc";
|
|
37
|
+
readonly track: "#e2e2e2";
|
|
38
|
+
};
|
|
39
|
+
readonly dark: {
|
|
40
|
+
readonly ground: "#0b0b0b";
|
|
41
|
+
readonly ink: "#ededed";
|
|
42
|
+
readonly ink2: "#c2c2c2";
|
|
43
|
+
readonly dim: "#a4a4a4";
|
|
44
|
+
readonly rail: "#6b6b6b";
|
|
45
|
+
readonly line: "#656565";
|
|
46
|
+
readonly washRun: "#2b3854";
|
|
47
|
+
readonly washDone: "#333333";
|
|
48
|
+
readonly washFail: "#4d2b28";
|
|
49
|
+
readonly washAsk: "#483818";
|
|
50
|
+
readonly human: "#e8dfc6";
|
|
51
|
+
readonly humanInk: "#141620";
|
|
52
|
+
readonly gold: "#e3b04b";
|
|
53
|
+
readonly goldMark: "#e3b04b";
|
|
54
|
+
readonly blue: "#82a8f5";
|
|
55
|
+
readonly code: "#283658";
|
|
56
|
+
readonly ok: "#8fd19e";
|
|
57
|
+
readonly fail: "#f2877a";
|
|
58
|
+
readonly add: "#2a5034";
|
|
59
|
+
readonly del: "#5e302d";
|
|
60
|
+
readonly track: "#474747";
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
export type Token = Exclude<keyof (typeof GRAPHITE)["light"], "ground">;
|
|
64
|
+
export type Colours = {
|
|
65
|
+
readonly [K in Token | "ground"]: Rgb;
|
|
66
|
+
};
|
|
67
|
+
/** The tokens that are GROUNDS near the terminal's own (§3.4): each is
|
|
68
|
+
* derived from the reported ground. Every other token is fixed per kind. */
|
|
69
|
+
export declare const SURFACES: readonly ["line", "washRun", "washDone", "washFail", "washAsk", "human", "code", "add", "del", "track"];
|
|
70
|
+
/** The text tokens that read on the ground and on the card surfaces (§2.1). */
|
|
71
|
+
export declare const CARD_TEXT: readonly ["ink", "ink2", "dim", "gold", "blue", "ok", "fail"];
|
|
72
|
+
export declare const CARDS: readonly ["washRun", "washDone", "washFail", "washAsk"];
|
|
73
|
+
type Surface = Token | "ground";
|
|
74
|
+
/** Every text-on-surface pair a human reads (§2.1's floor applies to each). */
|
|
75
|
+
export declare const TEXT_PAIRS: readonly (readonly [Token, Surface])[];
|
|
76
|
+
export declare const FLOOR = 4.5;
|
|
77
|
+
/** The floor for a GRAPHIC — a mark, not text (WCAG 1.4.11). The breath
|
|
78
|
+
* never drops below it (§2.2). */
|
|
79
|
+
export declare const GRAPHIC_FLOOR = 3;
|
|
80
|
+
export declare function hexRgb(hex: string): Rgb;
|
|
81
|
+
export declare function rgbHex({ r, g, b }: Rgb): string;
|
|
82
|
+
/** The WCAG contrast ratio, the measure of §2's floor. */
|
|
83
|
+
export declare function contrast(a: Rgb, b: Rgb): number;
|
|
84
|
+
/** `t` of the way from `a` to `b`, per channel. */
|
|
85
|
+
export declare function mix(a: Rgb, b: Rgb, t: number): Rgb;
|
|
86
|
+
/**
|
|
87
|
+
* §3.4 — one surface for any ground. A DARK ground: per channel an affine
|
|
88
|
+
* map `s = a + k·g`, fitted so that the white reference ground gives the
|
|
89
|
+
* table's white value and the black one its black value — a terminal
|
|
90
|
+
* whose black is `#1e1e1e` gets a card that sits the same distance off
|
|
91
|
+
* ITS ground, and the distance narrows as a dark ground lightens, which
|
|
92
|
+
* keeps the text above the floor on the lighter dark themes. A LIGHT
|
|
93
|
+
* ground: the light table, moved by how far the ground sits from white.
|
|
94
|
+
* The two reference grounds reproduce the table exactly.
|
|
95
|
+
*
|
|
96
|
+
* 0.47.1 (the dark table's re-adaptation): DECLARED REVERSAL for the
|
|
97
|
+
* light grounds only. The one map through both tables tied them to the
|
|
98
|
+
* dark table — lifting the dark cards pulled a card on `#eeeeee` to within
|
|
99
|
+
* 1.09:1 of its ground. A light ground now answers to the light table
|
|
100
|
+
* alone; on the light grounds measured the cards move by a channel step
|
|
101
|
+
* or two at most.
|
|
102
|
+
*/
|
|
103
|
+
export declare function deriveSurface(token: Token, ground: Rgb): Rgb;
|
|
104
|
+
/** A colour as the terminal will show it: itself in the 24-bit tier, the
|
|
105
|
+
* nearest xterm-256 entry in the 256 tier. The floor is checked on what
|
|
106
|
+
* is SHOWN — rounding to the nearest index can cost a pair its contrast. */
|
|
107
|
+
export declare function shown(c: Rgb, tier: Tier): Rgb;
|
|
108
|
+
/** The weakest text-on-surface pair of a colour set, as shown in `tier`. */
|
|
109
|
+
export declare function weakestPair(c: Colours, tier?: Tier): {
|
|
110
|
+
pair: readonly [Token, Surface];
|
|
111
|
+
ratio: number;
|
|
112
|
+
};
|
|
113
|
+
export declare function graphiteColours(kind: Kind, ground: Rgb | null, tier?: Tier): Colours;
|
|
114
|
+
/**
|
|
115
|
+
* The command breath (§5.2): seven steps from `gold` toward the running
|
|
116
|
+
* card's ground, peak → floor → peak. The floor is the deepest step that
|
|
117
|
+
* still meets the graphic floor on that ground (§2.2): the mark dims and
|
|
118
|
+
* never disappears.
|
|
119
|
+
*/
|
|
120
|
+
export declare function breathRamp(c: Colours): readonly Rgb[];
|
|
121
|
+
/** The xterm-256 palette's colour for an index 16–255 (the cube and the
|
|
122
|
+
* grey ramp; the first sixteen are the terminal's own and never chosen). */
|
|
123
|
+
export declare function xterm256(index: number): Rgb;
|
|
124
|
+
/** The nearest xterm-256 index (16–255) to a colour, by squared distance
|
|
125
|
+
* in RGB — the 256 tier's whole translation. */
|
|
126
|
+
export declare function nearest256(c: Rgb): number;
|
|
127
|
+
/** §2 — 24-bit where the terminal says it renders it. `COLORTERM` is the
|
|
128
|
+
* standard statement; anything else gets the 256 tier, which every
|
|
129
|
+
* terminal kiso docks in renders. */
|
|
130
|
+
export declare function colourTier(colorterm: string | undefined): Tier;
|
|
131
|
+
/** 0.47.1 (owner, 2026-10-07) — 24-bit where the terminal is KNOWN to
|
|
132
|
+
* render it, though it does not say so in COLORTERM. Windows Terminal is
|
|
133
|
+
* the case that found it: drawn in the 256 tier, the person's cream block
|
|
134
|
+
* became pink (index 224) and its gold edge olive (186). Each terminal is
|
|
135
|
+
* recognised by what it sets; the list is the reference implementation's.
|
|
136
|
+
* Inside tmux or screen only COLORTERM counts — the outer terminal's
|
|
137
|
+
* variables are inherited, its rendering is not. Apple Terminal says it
|
|
138
|
+
* in COLORTERM where it renders 24-bit (§2), and keeps the 256 tier
|
|
139
|
+
* otherwise. PURE: the environment and the platform are passed in. */
|
|
140
|
+
export declare function terminalTier(env: Readonly<Record<string, string | undefined>>, platform: string): Tier;
|
|
141
|
+
export declare function fg(c: Rgb, tier: Tier): string;
|
|
142
|
+
export declare function bg(c: Rgb, tier: Tier): string;
|
|
143
|
+
export {};
|