@chances-ai/tui 13.0.0 → 14.0.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/api-key-prompt.d.ts.map +1 -1
- package/dist/api-key-prompt.js +3 -1
- package/dist/api-key-prompt.js.map +1 -1
- package/dist/app.d.ts +13 -16
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +82 -75
- package/dist/app.js.map +1 -1
- package/dist/code-view.d.ts +9 -0
- package/dist/code-view.d.ts.map +1 -0
- package/dist/code-view.js +28 -0
- package/dist/code-view.js.map +1 -0
- package/dist/diff-model.d.ts +64 -0
- package/dist/diff-model.d.ts.map +1 -0
- package/dist/diff-model.js +156 -0
- package/dist/diff-model.js.map +1 -0
- package/dist/diff-view.d.ts +13 -0
- package/dist/diff-view.d.ts.map +1 -0
- package/dist/diff-view.js +60 -0
- package/dist/diff-view.js.map +1 -0
- package/dist/highlight-to-segments.d.ts +18 -0
- package/dist/highlight-to-segments.d.ts.map +1 -0
- package/dist/highlight-to-segments.js +224 -0
- package/dist/highlight-to-segments.js.map +1 -0
- package/dist/index.d.ts +13 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -2
- package/dist/index.js.map +1 -1
- package/dist/markdown.d.ts +5 -0
- package/dist/markdown.d.ts.map +1 -0
- package/dist/markdown.js +117 -0
- package/dist/markdown.js.map +1 -0
- package/dist/model-picker.d.ts.map +1 -1
- package/dist/model-picker.js +4 -2
- package/dist/model-picker.js.map +1 -1
- package/dist/progress.d.ts +41 -0
- package/dist/progress.d.ts.map +1 -0
- package/dist/progress.js +122 -0
- package/dist/progress.js.map +1 -0
- package/dist/session-picker.d.ts.map +1 -1
- package/dist/session-picker.js +4 -2
- package/dist/session-picker.js.map +1 -1
- package/dist/theme-context.d.ts +25 -0
- package/dist/theme-context.d.ts.map +1 -0
- package/dist/theme-context.js +24 -0
- package/dist/theme-context.js.map +1 -0
- package/dist/theme.d.ts +106 -0
- package/dist/theme.d.ts.map +1 -0
- package/dist/theme.js +116 -0
- package/dist/theme.js.map +1 -0
- package/dist/tool-line.d.ts +33 -0
- package/dist/tool-line.d.ts.map +1 -0
- package/dist/tool-line.js +168 -0
- package/dist/tool-line.js.map +1 -0
- package/dist/tool-message.d.ts +18 -0
- package/dist/tool-message.d.ts.map +1 -0
- package/dist/tool-message.js +37 -0
- package/dist/tool-message.js.map +1 -0
- package/dist/view-model.d.ts +46 -1
- package/dist/view-model.d.ts.map +1 -1
- package/dist/view-model.js +109 -16
- package/dist/view-model.js.map +1 -1
- package/package.json +8 -4
package/dist/markdown.js
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* (5.9 / v14) Render committed assistant text as terminal Markdown via marked's
|
|
4
|
+
* lexer → Ink nodes. NEVER throws: a bad lex falls back to the raw text, and
|
|
5
|
+
* each block is rendered under its own guard so one malformed token can't take
|
|
6
|
+
* down the turn.
|
|
7
|
+
*
|
|
8
|
+
* Streaming contract: this renders only on COMMITTED lines. The live (still
|
|
9
|
+
* streaming) assistant line is rendered as plain text by `app.tsx`, so
|
|
10
|
+
* half-finished Markdown never flickers (5.9 §4, builds on v13's committed/live
|
|
11
|
+
* split).
|
|
12
|
+
*/
|
|
13
|
+
import { Box, Text } from "ink";
|
|
14
|
+
import { lexer } from "marked";
|
|
15
|
+
import { CodeView } from "./code-view.js";
|
|
16
|
+
import {} from "./theme.js";
|
|
17
|
+
import { useTheme } from "./theme-context.js";
|
|
18
|
+
const HR_WIDTH = 40;
|
|
19
|
+
export function Markdown({ text }) {
|
|
20
|
+
const { theme, glyphs } = useTheme();
|
|
21
|
+
let tokens;
|
|
22
|
+
try {
|
|
23
|
+
tokens = lexer(text);
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
return _jsx(Text, { children: text });
|
|
27
|
+
}
|
|
28
|
+
return (_jsx(Box, { flexDirection: "column", children: tokens.map((t, i) => (_jsx(Block, { token: t, theme: theme, glyphs: glyphs }, i))) }));
|
|
29
|
+
}
|
|
30
|
+
function Block({ token, theme, glyphs }) {
|
|
31
|
+
try {
|
|
32
|
+
return renderBlock(token, theme, glyphs);
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return _jsx(Text, { children: "raw" in token ? token.raw : "" });
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function renderBlock(token, theme, glyphs) {
|
|
39
|
+
switch (token.type) {
|
|
40
|
+
case "space":
|
|
41
|
+
return _jsx(Text, { children: " " });
|
|
42
|
+
case "heading": {
|
|
43
|
+
const h = token;
|
|
44
|
+
return (_jsx(Text, { bold: true, color: h.depth === 1 ? theme.accent : undefined, children: renderInline(h.tokens, theme) }));
|
|
45
|
+
}
|
|
46
|
+
case "paragraph": {
|
|
47
|
+
const p = token;
|
|
48
|
+
return _jsx(Text, { children: renderInline(p.tokens, theme) });
|
|
49
|
+
}
|
|
50
|
+
case "text": {
|
|
51
|
+
const t = token;
|
|
52
|
+
return _jsx(Text, { children: t.tokens ? renderInline(t.tokens, theme) : t.text });
|
|
53
|
+
}
|
|
54
|
+
case "code": {
|
|
55
|
+
const c = token;
|
|
56
|
+
return _jsx(CodeView, { code: c.text, lang: c.lang });
|
|
57
|
+
}
|
|
58
|
+
case "blockquote": {
|
|
59
|
+
const bq = token;
|
|
60
|
+
const lines = bq.text.split("\n");
|
|
61
|
+
return (_jsx(Box, { flexDirection: "column", children: lines.map((line, i) => (_jsxs(Text, { dimColor: true, children: [glyphs.blockquote, " ", line] }, i))) }));
|
|
62
|
+
}
|
|
63
|
+
case "list": {
|
|
64
|
+
const list = token;
|
|
65
|
+
return (_jsx(Box, { flexDirection: "column", children: list.items.map((item, i) => {
|
|
66
|
+
const marker = list.ordered ? `${(Number(list.start) || 1) + i}.` : glyphs.bullet;
|
|
67
|
+
return (_jsxs(Text, { children: [marker, " ", renderInline(item.tokens, theme)] }, i));
|
|
68
|
+
}) }));
|
|
69
|
+
}
|
|
70
|
+
case "hr":
|
|
71
|
+
return _jsx(Text, { dimColor: true, children: glyphs.hr.repeat(HR_WIDTH) });
|
|
72
|
+
case "table": {
|
|
73
|
+
const table = token;
|
|
74
|
+
const header = table.header.map((c) => c.text).join(" ");
|
|
75
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, children: header }), table.rows.map((row, i) => (_jsx(Text, { children: row.map((c) => c.text).join(" ") }, i)))] }));
|
|
76
|
+
}
|
|
77
|
+
default: {
|
|
78
|
+
const raw = "raw" in token ? token.raw : "text" in token ? token.text : "";
|
|
79
|
+
return raw ? _jsx(Text, { children: raw }) : null;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/** Render inline tokens (within a paragraph/heading/list item) into Ink Text
|
|
84
|
+
* runs. Unknown inline types fall back to their raw text. */
|
|
85
|
+
function renderInline(tokens, theme) {
|
|
86
|
+
if (!tokens)
|
|
87
|
+
return [];
|
|
88
|
+
return tokens.map((t, i) => {
|
|
89
|
+
switch (t.type) {
|
|
90
|
+
case "text": {
|
|
91
|
+
const tt = t;
|
|
92
|
+
return tt.tokens ? _jsx(Text, { children: renderInline(tt.tokens, theme) }, i) : tt.text;
|
|
93
|
+
}
|
|
94
|
+
case "strong":
|
|
95
|
+
return (_jsx(Text, { bold: true, children: renderInline(t.tokens, theme) }, i));
|
|
96
|
+
case "em":
|
|
97
|
+
return (_jsx(Text, { italic: true, children: renderInline(t.tokens, theme) }, i));
|
|
98
|
+
case "del":
|
|
99
|
+
return (_jsx(Text, { strikethrough: true, children: renderInline(t.tokens, theme) }, i));
|
|
100
|
+
case "codespan":
|
|
101
|
+
return (_jsx(Text, { color: theme.synString, children: t.text }, i));
|
|
102
|
+
case "link": {
|
|
103
|
+
const link = t;
|
|
104
|
+
const label = renderInline(link.tokens, theme);
|
|
105
|
+
const showUrl = link.href && link.href !== link.text;
|
|
106
|
+
return (_jsxs(Text, { children: [_jsx(Text, { color: theme.accent, children: label }), showUrl ? _jsxs(Text, { dimColor: true, children: [" (", link.href, ")"] }) : null] }, i));
|
|
107
|
+
}
|
|
108
|
+
case "br":
|
|
109
|
+
return "\n";
|
|
110
|
+
case "escape":
|
|
111
|
+
return t.text;
|
|
112
|
+
default:
|
|
113
|
+
return "raw" in t ? t.raw : "text" in t ? t.text : "";
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=markdown.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown.js","sourceRoot":"","sources":["../src/markdown.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-picker.d.ts","sourceRoot":"","sources":["../src/model-picker.tsx"],"names":[],"mappings":"AACA,OAAO,EAAY,KAAK,GAAG,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"model-picker.d.ts","sourceRoot":"","sources":["../src/model-picker.tsx"],"names":[],"mappings":"AACA,OAAO,EAAY,KAAK,GAAG,EAAE,MAAM,OAAO,CAAC;AAG3C,MAAM,WAAW,aAAa;IAC5B,0CAA0C;IAC1C,EAAE,EAAE,MAAM,CAAC;IACX,4DAA4D;IAC5D,QAAQ,EAAE,MAAM,CAAC;IACjB,mEAAmE;IACnE,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;uCAEuC;AACvC,MAAM,WAAW,SAAS;IACxB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED;iDACiD;AACjD,wBAAgB,YAAY,CAAC,MAAM,EAAE,aAAa,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,aAAa,EAAE,CAIrF;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,gBAAgB,EACvB,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,SAAS,EACd,MAAM,EAAE,aAAa,EAAE,GACtB;IAAE,KAAK,EAAE,gBAAgB,CAAC;IAAC,QAAQ,CAAC,EAAE,aAAa,GAAG,IAAI,CAAA;CAAE,CAsB9D;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,EAC1B,MAAM,EACN,QAAQ,GACT,EAAE;IACD,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,QAAQ,EAAE,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI,KAAK,IAAI,CAAC;CACjD,GAAG,GAAG,CAAC,OAAO,CA6Cd"}
|
package/dist/model-picker.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Box, Text, useInput } from "ink";
|
|
3
3
|
import { useState } from "react";
|
|
4
|
+
import { useTheme } from "./theme-context.js";
|
|
4
5
|
/** Subset of the active match list the reducer needs — kept as a generic
|
|
5
6
|
* function over PickableModel for ergonomics. */
|
|
6
7
|
export function filterModels(models, filter) {
|
|
@@ -49,6 +50,7 @@ export function reduceModelPicker(state, char, key, models) {
|
|
|
49
50
|
* pure function — this component is just glue to Ink's useInput.
|
|
50
51
|
*/
|
|
51
52
|
export function ModelPicker({ models, onChoose, }) {
|
|
53
|
+
const { theme } = useTheme();
|
|
52
54
|
const [state, setState] = useState({ filter: "", cursor: 0 });
|
|
53
55
|
useInput((char, key) => {
|
|
54
56
|
const { state: next, resolved } = reduceModelPicker(state, char, key, models);
|
|
@@ -61,10 +63,10 @@ export function ModelPicker({ models, onChoose, }) {
|
|
|
61
63
|
});
|
|
62
64
|
const matches = filterModels(models, state.filter);
|
|
63
65
|
const safeCursor = Math.min(state.cursor, Math.max(0, matches.length - 1));
|
|
64
|
-
return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor:
|
|
66
|
+
return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: theme.permission, paddingX: 1, children: [_jsx(Text, { color: theme.permission, children: "Pick a model \u00B7 type to filter \u00B7 \u2191\u2193 \u00B7 Enter \u00B7 Esc" }), _jsxs(Box, { marginTop: 1, children: [_jsx(Text, { children: "filter: " }), _jsx(Text, { color: theme.warning, children: state.filter || "(any)" })] }), _jsxs(Box, { flexDirection: "column", marginTop: 1, children: [matches.length === 0 ? (_jsx(Text, { dimColor: true, children: "no models match" })) : (matches.slice(0, 10).map((m, i) => {
|
|
65
67
|
const selected = i === safeCursor;
|
|
66
68
|
const marker = m.current ? "●" : " ";
|
|
67
|
-
return (_jsxs(Text, { color: selected ?
|
|
69
|
+
return (_jsxs(Text, { color: selected ? theme.permission : undefined, children: [selected ? "▸ " : " ", marker, " ", _jsxs(Text, { dimColor: true, children: [m.provider, "/"] }), m.id] }, `${m.provider}/${m.id}`));
|
|
68
70
|
})), matches.length > 10 ? (_jsxs(Text, { dimColor: true, children: ["\u2026 ", matches.length - 10, " more (type to narrow)"] })) : null] })] }));
|
|
69
71
|
}
|
|
70
72
|
//# sourceMappingURL=model-picker.js.map
|
package/dist/model-picker.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-picker.js","sourceRoot":"","sources":["../src/model-picker.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAY,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"model-picker.js","sourceRoot":"","sources":["../src/model-picker.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { type JSX } from "react";
|
|
2
|
+
/** Our own small set of lively progress verbs (user decision D3 — not
|
|
3
|
+
* claude-code's whimsical brand list, not a bare static "Thinking…"). */
|
|
4
|
+
export declare const DEFAULT_VERBS: readonly ["Thinking", "Working", "Crunching", "Wrangling", "Plotting", "Cooking", "Pondering", "Tinkering", "Computing", "Noodling"];
|
|
5
|
+
/** Pick a verb by index (deterministic; callers vary the index per turn). */
|
|
6
|
+
export declare function pickVerb(index: number): string;
|
|
7
|
+
/** Human token count: `1234 → "1.2k"`, `980 → "980"`. */
|
|
8
|
+
export declare function formatTokenCount(n: number): string;
|
|
9
|
+
/** Human elapsed: `<60s → "8s"`, else `"2m 5s"`. */
|
|
10
|
+
export declare function formatElapsed(ms: number): string;
|
|
11
|
+
export interface ProgressInfo {
|
|
12
|
+
verb: string;
|
|
13
|
+
elapsedMs: number;
|
|
14
|
+
tokens: number;
|
|
15
|
+
/** Width budget for the text (excluding the leading glyph + space). */
|
|
16
|
+
width: number;
|
|
17
|
+
arrowDown: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Build the progress text after the glyph. Segments are appended in display
|
|
21
|
+
* order `esc · elapsed · tokens` but dropped from the TAIL (tokens, then
|
|
22
|
+
* elapsed, then esc) so the most useful hint — how to interrupt — survives
|
|
23
|
+
* longest. The `verb…` head is always kept (it's never dropped).
|
|
24
|
+
*/
|
|
25
|
+
export declare function formatProgress({ verb, elapsedMs, tokens, width, arrowDown }: ProgressInfo): string;
|
|
26
|
+
export interface ProgressProps {
|
|
27
|
+
active: boolean;
|
|
28
|
+
/** Verb to display. Omitted ⇒ a lively verb is picked once on mount (varies
|
|
29
|
+
* per turn because the component is mounted only while busy). */
|
|
30
|
+
verb?: string;
|
|
31
|
+
/** Estimated tokens streamed this turn (≈ chars / 4). */
|
|
32
|
+
tokens: number;
|
|
33
|
+
reducedMotion?: boolean;
|
|
34
|
+
width?: number;
|
|
35
|
+
/** Test seam: fixed elapsed ms (skips the wall clock). */
|
|
36
|
+
elapsedMsOverride?: number;
|
|
37
|
+
/** Test seam: fixed frame index (skips the interval). */
|
|
38
|
+
frameOverride?: number;
|
|
39
|
+
}
|
|
40
|
+
export declare function Progress({ active, verb, tokens, reducedMotion, width, elapsedMsOverride, frameOverride, }: ProgressProps): JSX.Element | null;
|
|
41
|
+
//# sourceMappingURL=progress.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"progress.d.ts","sourceRoot":"","sources":["../src/progress.tsx"],"names":[],"mappings":"AAcA,OAAO,EAAE,KAAK,GAAG,EAA+B,MAAM,OAAO,CAAC;AAQ9D;0EAC0E;AAC1E,eAAO,MAAM,aAAa,sIAWhB,CAAC;AAEX,6EAA6E;AAC7E,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE9C;AAED,yDAAyD;AACzD,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAGlD;AAED,oDAAoD;AACpD,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAMhD;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,uEAAuE;IACvE,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,YAAY,GAAG,MAAM,CAYlG;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,OAAO,CAAC;IAChB;sEACkE;IAClE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,yDAAyD;IACzD,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0DAA0D;IAC1D,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,yDAAyD;IACzD,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAOD,wBAAgB,QAAQ,CAAC,EACvB,MAAM,EACN,IAAI,EACJ,MAAM,EACN,aAAqB,EACrB,KAAK,EACL,iBAAiB,EACjB,aAAa,GACd,EAAE,aAAa,GAAG,GAAG,CAAC,OAAO,GAAG,IAAI,CAoDpC"}
|
package/dist/progress.js
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* (5.9 / v14) The progress / "thinking" line shown above the input while a turn
|
|
4
|
+
* streams: `✻ Crunching… (esc to interrupt · 8s · ↓ 1.2k tokens)`.
|
|
5
|
+
*
|
|
6
|
+
* - `formatProgress` is a pure, width-aware formatter (segments drop as the
|
|
7
|
+
* terminal narrows, keeping `esc to interrupt` longest). Tested without a clock.
|
|
8
|
+
* - The component owns a single `setInterval` for the 12-step pulse glyph,
|
|
9
|
+
* created in a `useEffect` keyed on `active` and cleared on unmount / when the
|
|
10
|
+
* turn ends (codex R1 SHOULD-2). It holds ONLY local frame state — it never
|
|
11
|
+
* touches the view-model, so it can't race the v13 FrameScheduler.
|
|
12
|
+
* - Glyph color is the accent, shifting to `stall` red after ~3s with no new
|
|
13
|
+
* tokens. Reduced-motion / NO_COLOR → a static dot.
|
|
14
|
+
*/
|
|
15
|
+
import { Box, Text } from "ink";
|
|
16
|
+
import { useEffect, useRef, useState } from "react";
|
|
17
|
+
import stringWidth from "string-width";
|
|
18
|
+
import { SPINNER_FRAMES, SPINNER_STATIC } from "./theme.js";
|
|
19
|
+
import { useTheme } from "./theme-context.js";
|
|
20
|
+
const TICK_MS = 120;
|
|
21
|
+
const STALL_MS = 3000;
|
|
22
|
+
/** Our own small set of lively progress verbs (user decision D3 — not
|
|
23
|
+
* claude-code's whimsical brand list, not a bare static "Thinking…"). */
|
|
24
|
+
export const DEFAULT_VERBS = [
|
|
25
|
+
"Thinking",
|
|
26
|
+
"Working",
|
|
27
|
+
"Crunching",
|
|
28
|
+
"Wrangling",
|
|
29
|
+
"Plotting",
|
|
30
|
+
"Cooking",
|
|
31
|
+
"Pondering",
|
|
32
|
+
"Tinkering",
|
|
33
|
+
"Computing",
|
|
34
|
+
"Noodling",
|
|
35
|
+
];
|
|
36
|
+
/** Pick a verb by index (deterministic; callers vary the index per turn). */
|
|
37
|
+
export function pickVerb(index) {
|
|
38
|
+
return DEFAULT_VERBS[Math.abs(index) % DEFAULT_VERBS.length];
|
|
39
|
+
}
|
|
40
|
+
/** Human token count: `1234 → "1.2k"`, `980 → "980"`. */
|
|
41
|
+
export function formatTokenCount(n) {
|
|
42
|
+
if (n >= 1000)
|
|
43
|
+
return `${(n / 1000).toFixed(1)}k`;
|
|
44
|
+
return String(Math.max(0, Math.round(n)));
|
|
45
|
+
}
|
|
46
|
+
/** Human elapsed: `<60s → "8s"`, else `"2m 5s"`. */
|
|
47
|
+
export function formatElapsed(ms) {
|
|
48
|
+
const s = Math.floor(ms / 1000);
|
|
49
|
+
if (s < 60)
|
|
50
|
+
return `${s}s`;
|
|
51
|
+
const m = Math.floor(s / 60);
|
|
52
|
+
const rem = s % 60;
|
|
53
|
+
return rem === 0 ? `${m}m` : `${m}m ${rem}s`;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Build the progress text after the glyph. Segments are appended in display
|
|
57
|
+
* order `esc · elapsed · tokens` but dropped from the TAIL (tokens, then
|
|
58
|
+
* elapsed, then esc) so the most useful hint — how to interrupt — survives
|
|
59
|
+
* longest. The `verb…` head is always kept (it's never dropped).
|
|
60
|
+
*/
|
|
61
|
+
export function formatProgress({ verb, elapsedMs, tokens, width, arrowDown }) {
|
|
62
|
+
const head = `${verb}…`;
|
|
63
|
+
const segs = ["esc to interrupt", formatElapsed(elapsedMs)];
|
|
64
|
+
if (tokens > 0)
|
|
65
|
+
segs.push(`${arrowDown} ${formatTokenCount(tokens)} tokens`);
|
|
66
|
+
// Drop from the tail until the whole line fits the width budget.
|
|
67
|
+
for (let keep = segs.length; keep >= 0; keep--) {
|
|
68
|
+
const kept = segs.slice(0, keep);
|
|
69
|
+
const text = kept.length > 0 ? `${head} (${kept.join(" · ")})` : head;
|
|
70
|
+
if (stringWidth(text) <= width || keep === 0)
|
|
71
|
+
return text;
|
|
72
|
+
}
|
|
73
|
+
return head;
|
|
74
|
+
}
|
|
75
|
+
function termWidth() {
|
|
76
|
+
const cols = process.stdout?.columns;
|
|
77
|
+
return typeof cols === "number" && cols > 0 ? cols : 80;
|
|
78
|
+
}
|
|
79
|
+
export function Progress({ active, verb, tokens, reducedMotion = false, width, elapsedMsOverride, frameOverride, }) {
|
|
80
|
+
const { theme, glyphs } = useTheme();
|
|
81
|
+
const [frame, setFrame] = useState(0);
|
|
82
|
+
const [autoVerb] = useState(() => pickVerb(Math.floor(Math.random() * DEFAULT_VERBS.length)));
|
|
83
|
+
const shownVerb = verb ?? autoVerb;
|
|
84
|
+
const startRef = useRef(Date.now());
|
|
85
|
+
const lastTokenRef = useRef({ tokens, at: Date.now() });
|
|
86
|
+
// Reset the turn clock on each activation. `tokens` is intentionally NOT a
|
|
87
|
+
// dependency — we seed it once when the turn begins; live movement is read
|
|
88
|
+
// through `lastTokenRef` below.
|
|
89
|
+
useEffect(() => {
|
|
90
|
+
if (active) {
|
|
91
|
+
startRef.current = Date.now();
|
|
92
|
+
lastTokenRef.current = { tokens, at: Date.now() };
|
|
93
|
+
}
|
|
94
|
+
}, [active]);
|
|
95
|
+
// Single pulse interval, cleared on unmount / when inactive (R1 SHOULD-2).
|
|
96
|
+
useEffect(() => {
|
|
97
|
+
if (!active || reducedMotion || frameOverride !== undefined)
|
|
98
|
+
return;
|
|
99
|
+
const id = setInterval(() => setFrame((f) => (f + 1) % SPINNER_FRAMES.length), TICK_MS);
|
|
100
|
+
return () => clearInterval(id);
|
|
101
|
+
}, [active, reducedMotion, frameOverride]);
|
|
102
|
+
// Track token movement for stall detection.
|
|
103
|
+
if (tokens !== lastTokenRef.current.tokens) {
|
|
104
|
+
lastTokenRef.current = { tokens, at: Date.now() };
|
|
105
|
+
}
|
|
106
|
+
if (!active)
|
|
107
|
+
return null;
|
|
108
|
+
const elapsedMs = elapsedMsOverride ?? Date.now() - startRef.current;
|
|
109
|
+
const stalled = Date.now() - lastTokenRef.current.at > STALL_MS;
|
|
110
|
+
const glyphIndex = frameOverride ?? frame;
|
|
111
|
+
const glyph = reducedMotion ? SPINNER_STATIC : (SPINNER_FRAMES[glyphIndex % SPINNER_FRAMES.length] ?? glyphs.thinking);
|
|
112
|
+
const glyphColor = stalled ? theme.stall : theme.accent;
|
|
113
|
+
const text = formatProgress({
|
|
114
|
+
verb: shownVerb,
|
|
115
|
+
elapsedMs,
|
|
116
|
+
tokens,
|
|
117
|
+
width: Math.max(8, (width ?? termWidth()) - 2),
|
|
118
|
+
arrowDown: glyphs.arrowDown,
|
|
119
|
+
});
|
|
120
|
+
return (_jsxs(Box, { marginTop: 1, children: [_jsx(Text, { color: glyphColor, children: glyph }), _jsxs(Text, { dimColor: true, children: [" ", text] })] }));
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=progress.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"progress.js","sourceRoot":"","sources":["../src/progress.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-picker.d.ts","sourceRoot":"","sources":["../src/session-picker.tsx"],"names":[],"mappings":"AACA,OAAO,EAAY,KAAK,GAAG,EAAE,MAAM,OAAO,CAAC;AAC3C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"session-picker.d.ts","sourceRoot":"","sources":["../src/session-picker.tsx"],"names":[],"mappings":"AACA,OAAO,EAAY,KAAK,GAAG,EAAE,MAAM,OAAO,CAAC;AAC3C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAGnD,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,kEAAkE;IAClE,SAAS,EAAE,MAAM,CAAC;IAClB;qEACiE;IACjE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,SAAS,EACd,QAAQ,EAAE,eAAe,EAAE,GAC1B;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,eAAe,GAAG,IAAI,CAAA;CAAE,CAOvD;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,EAC5B,QAAQ,EACR,QAAQ,GACT,EAAE;IACD,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,QAAQ,EAAE,CAAC,OAAO,EAAE,eAAe,GAAG,IAAI,KAAK,IAAI,CAAC;CACrD,GAAG,GAAG,CAAC,OAAO,CAwCd"}
|
package/dist/session-picker.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Box, Text, useInput } from "ink";
|
|
3
3
|
import { useState } from "react";
|
|
4
|
+
import { useTheme } from "./theme-context.js";
|
|
4
5
|
/**
|
|
5
6
|
* Pure reducer for the SessionPicker. Same convention as the model picker —
|
|
6
7
|
* returns `resolved: PickableSession | null` when the user picked or
|
|
@@ -25,6 +26,7 @@ export function reduceSessionPicker(cursor, key, sessions) {
|
|
|
25
26
|
* logic in {@link reduceSessionPicker} for testability.
|
|
26
27
|
*/
|
|
27
28
|
export function SessionPicker({ sessions, onChoose, }) {
|
|
29
|
+
const { theme } = useTheme();
|
|
28
30
|
const [cursor, setCursor] = useState(0);
|
|
29
31
|
const safeCursor = Math.min(cursor, Math.max(0, sessions.length - 1));
|
|
30
32
|
useInput((_char, key) => {
|
|
@@ -36,10 +38,10 @@ export function SessionPicker({ sessions, onChoose, }) {
|
|
|
36
38
|
if (next !== cursor)
|
|
37
39
|
setCursor(next);
|
|
38
40
|
});
|
|
39
|
-
return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor:
|
|
41
|
+
return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: theme.permission, paddingX: 1, children: [_jsx(Text, { color: theme.permission, children: "Resume a session \u00B7 \u2191\u2193 \u00B7 Enter \u00B7 Esc" }), _jsx(Box, { flexDirection: "column", marginTop: 1, children: sessions.length === 0 ? (_jsx(Text, { dimColor: true, children: "no saved sessions in this workspace" })) : (sessions.slice(0, 10).map((s, i) => {
|
|
40
42
|
const selected = i === safeCursor;
|
|
41
43
|
const date = s.updatedAt.slice(0, 10);
|
|
42
|
-
return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { color: selected ?
|
|
44
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { color: selected ? theme.permission : undefined, children: [selected ? "▸ " : " ", _jsx(Text, { dimColor: true, children: date }), " ", s.title] }), s.preview ? (_jsxs(Text, { dimColor: true, children: [" ", s.preview.slice(0, 60)] })) : null] }, s.id));
|
|
43
45
|
})) })] }));
|
|
44
46
|
}
|
|
45
47
|
//# sourceMappingURL=session-picker.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-picker.js","sourceRoot":"","sources":["../src/session-picker.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAY,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"session-picker.js","sourceRoot":"","sources":["../src/session-picker.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* (5.9 / v14) Minimal React seam over the pure `theme.ts` literals. Components
|
|
3
|
+
* read the resolved palette + glyphs via `useTheme()`; the host wraps the tree
|
|
4
|
+
* once in `<ThemeProvider>`. Defaults to the dark palette + platform glyphs so
|
|
5
|
+
* components rendered without a provider (e.g. focused component tests) still
|
|
6
|
+
* work unchanged.
|
|
7
|
+
*/
|
|
8
|
+
import { type JSX, type ReactNode } from "react";
|
|
9
|
+
import { type Glyphs, type Theme, type ThemeSetting } from "./theme.js";
|
|
10
|
+
export interface ThemeContextValue {
|
|
11
|
+
theme: Theme;
|
|
12
|
+
glyphs: Glyphs;
|
|
13
|
+
/** Whether code blocks + diff context get syntax colors (`config.tui.
|
|
14
|
+
* syntaxHighlight`). Under `NO_COLOR` the syntax theme roles are already
|
|
15
|
+
* undefined, so plain output falls out regardless. */
|
|
16
|
+
syntaxHighlight: boolean;
|
|
17
|
+
}
|
|
18
|
+
export declare function ThemeProvider({ setting, glyphs, syntaxHighlight, children, }: {
|
|
19
|
+
setting?: ThemeSetting;
|
|
20
|
+
glyphs?: Glyphs;
|
|
21
|
+
syntaxHighlight?: boolean;
|
|
22
|
+
children: ReactNode;
|
|
23
|
+
}): JSX.Element;
|
|
24
|
+
export declare function useTheme(): ThemeContextValue;
|
|
25
|
+
//# sourceMappingURL=theme-context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme-context.d.ts","sourceRoot":"","sources":["../src/theme-context.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAA6B,KAAK,GAAG,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAC5E,OAAO,EAAU,KAAK,MAAM,EAAgB,KAAK,KAAK,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAE9F,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,KAAK,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf;;2DAEuD;IACvD,eAAe,EAAE,OAAO,CAAC;CAC1B;AAUD,wBAAgB,aAAa,CAAC,EAC5B,OAAO,EACP,MAAe,EACf,eAAsB,EACtB,QAAQ,GACT,EAAE;IACD,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,QAAQ,EAAE,SAAS,CAAC;CACrB,GAAG,GAAG,CAAC,OAAO,CAGd;AAED,wBAAgB,QAAQ,IAAI,iBAAiB,CAE5C"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* (5.9 / v14) Minimal React seam over the pure `theme.ts` literals. Components
|
|
4
|
+
* read the resolved palette + glyphs via `useTheme()`; the host wraps the tree
|
|
5
|
+
* once in `<ThemeProvider>`. Defaults to the dark palette + platform glyphs so
|
|
6
|
+
* components rendered without a provider (e.g. focused component tests) still
|
|
7
|
+
* work unchanged.
|
|
8
|
+
*/
|
|
9
|
+
import { createContext, useContext } from "react";
|
|
10
|
+
import { GLYPHS, resolveTheme } from "./theme.js";
|
|
11
|
+
const defaultValue = {
|
|
12
|
+
theme: resolveTheme("dark"),
|
|
13
|
+
glyphs: GLYPHS,
|
|
14
|
+
syntaxHighlight: true,
|
|
15
|
+
};
|
|
16
|
+
const ThemeContext = createContext(defaultValue);
|
|
17
|
+
export function ThemeProvider({ setting, glyphs = GLYPHS, syntaxHighlight = true, children, }) {
|
|
18
|
+
const value = { theme: resolveTheme(setting), glyphs, syntaxHighlight };
|
|
19
|
+
return _jsx(ThemeContext.Provider, { value: value, children: children });
|
|
20
|
+
}
|
|
21
|
+
export function useTheme() {
|
|
22
|
+
return useContext(ThemeContext);
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=theme-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme-context.js","sourceRoot":"","sources":["../src/theme-context.tsx"],"names":[],"mappings":";AAAA;;;;;;GAMG;AACH,OAAO,EAAE,aAAa,EAAE,UAAU,EAA4B,MAAM,OAAO,CAAC;AAC5E,OAAO,EAAE,MAAM,EAAe,YAAY,EAAiC,MAAM,YAAY,CAAC;AAW9F,MAAM,YAAY,GAAsB;IACtC,KAAK,EAAE,YAAY,CAAC,MAAM,CAAC;IAC3B,MAAM,EAAE,MAAM;IACd,eAAe,EAAE,IAAI;CACtB,CAAC;AAEF,MAAM,YAAY,GAAG,aAAa,CAAoB,YAAY,CAAC,CAAC;AAEpE,MAAM,UAAU,aAAa,CAAC,EAC5B,OAAO,EACP,MAAM,GAAG,MAAM,EACf,eAAe,GAAG,IAAI,EACtB,QAAQ,GAMT;IACC,MAAM,KAAK,GAAsB,EAAE,KAAK,EAAE,YAAY,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC;IAC3F,OAAO,KAAC,YAAY,CAAC,QAAQ,IAAC,KAAK,EAAE,KAAK,YAAG,QAAQ,GAAyB,CAAC;AACjF,CAAC;AAED,MAAM,UAAU,QAAQ;IACtB,OAAO,UAAU,CAAC,YAAY,CAAC,CAAC;AAClC,CAAC"}
|
package/dist/theme.d.ts
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* (5.9 / v14) The single home for the TUI's visual-language literals: glyphs +
|
|
3
|
+
* color palettes. Pure module — NO React, NO Ink — so every consumer (the
|
|
4
|
+
* pure diff/highlight/markdown cores AND the components) reads one source and
|
|
5
|
+
* the constants are unit-testable in isolation. The React seam lives in
|
|
6
|
+
* `theme-context.tsx`.
|
|
7
|
+
*
|
|
8
|
+
* Colors are emitted as Ink-compatible `rgb(r,g,b)` strings; Ink renders them
|
|
9
|
+
* through chalk, which downsamples truecolor → 256/16 by the terminal's
|
|
10
|
+
* detected level. We therefore keep ONE truecolor palette per mode and let
|
|
11
|
+
* chalk degrade — there is no hand-rolled 16-ANSI fallback table (5.9 §0).
|
|
12
|
+
*
|
|
13
|
+
* `NO_COLOR` (https://no-color.org) is honored explicitly here because chalk
|
|
14
|
+
* 5 / Ink 7 only read the `--no-color` *flag*, not the env var (codex R1
|
|
15
|
+
* MUST-2): when set, `resolveTheme` returns a palette whose every color is
|
|
16
|
+
* `undefined`, so components emit no `color`/`backgroundColor` and meaning is
|
|
17
|
+
* carried by glyphs + sigils alone (the diff `+`/`-`, the `⏺`/`⎿` shapes).
|
|
18
|
+
*
|
|
19
|
+
* Dark RGB values are the facts of claude-code's `darkTheme` visual language
|
|
20
|
+
* (verified `~/Projects/github/claude-code/src/utils/theme.ts`); light values
|
|
21
|
+
* track its `lightTheme`. Syntax colors are an OneDark-ish set legible on the
|
|
22
|
+
* respective background.
|
|
23
|
+
*/
|
|
24
|
+
/** A resolved palette. Every field optional: `undefined` ⇒ emit no color for
|
|
25
|
+
* that role (terminal default fg / no bg). The NO_COLOR palette is all-undefined. */
|
|
26
|
+
export interface Theme {
|
|
27
|
+
/** Claude accent (orange). Running tool dot, top-level headings, links, spinner glyph. */
|
|
28
|
+
accent?: string;
|
|
29
|
+
/** Successful tool / ok states. */
|
|
30
|
+
success?: string;
|
|
31
|
+
/** Errors (dot, message body). */
|
|
32
|
+
error?: string;
|
|
33
|
+
/** Amber warnings. */
|
|
34
|
+
warning?: string;
|
|
35
|
+
/** Permission dialog rule + title. */
|
|
36
|
+
permission?: string;
|
|
37
|
+
/** Plan-mode badge. */
|
|
38
|
+
planMode?: string;
|
|
39
|
+
/** auto-edit / yolo badge (violet). */
|
|
40
|
+
autoAccept?: string;
|
|
41
|
+
/** Bash tool accent (pink). */
|
|
42
|
+
bashPink?: string;
|
|
43
|
+
/** Full-line diff backgrounds. */
|
|
44
|
+
diffAddedBg?: string;
|
|
45
|
+
diffRemovedBg?: string;
|
|
46
|
+
/** Word-level (intra-line) diff backgrounds — brighter than the line bg. */
|
|
47
|
+
diffAddedWordBg?: string;
|
|
48
|
+
diffRemovedWordBg?: string;
|
|
49
|
+
/** User-message bubble background. */
|
|
50
|
+
userMessageBg?: string;
|
|
51
|
+
/** Stalled-spinner red (interpolation target when no token for ~3s). */
|
|
52
|
+
stall?: string;
|
|
53
|
+
synKeyword?: string;
|
|
54
|
+
synString?: string;
|
|
55
|
+
synComment?: string;
|
|
56
|
+
synNumber?: string;
|
|
57
|
+
synFunction?: string;
|
|
58
|
+
synType?: string;
|
|
59
|
+
synLiteral?: string;
|
|
60
|
+
synTitle?: string;
|
|
61
|
+
synAttr?: string;
|
|
62
|
+
}
|
|
63
|
+
/** Theme selection as it arrives from config. `'auto'` resolves to `'dark'` in
|
|
64
|
+
* v14 (terminal-background detection is a later lever). */
|
|
65
|
+
export type ThemeSetting = "dark" | "light" | "auto";
|
|
66
|
+
/** `NO_COLOR` (https://no-color.org): present and NON-EMPTY ⇒ disable color,
|
|
67
|
+
* regardless of value. An empty string does NOT disable (per the spec). */
|
|
68
|
+
export declare function isNoColor(env?: NodeJS.ProcessEnv): boolean;
|
|
69
|
+
/**
|
|
70
|
+
* Resolve a palette. `NO_COLOR` wins over any setting; otherwise `'light'` →
|
|
71
|
+
* the light palette and `'dark'`/`'auto'`/undefined → dark.
|
|
72
|
+
*/
|
|
73
|
+
export declare function resolveTheme(setting: ThemeSetting | undefined, env?: NodeJS.ProcessEnv): Theme;
|
|
74
|
+
export interface Glyphs {
|
|
75
|
+
/** Tool/turn status dot. `⏺` aligns well only on macOS terminals; `●`
|
|
76
|
+
* elsewhere (matches claude-code `figures.ts` BLACK_CIRCLE). */
|
|
77
|
+
dot: string;
|
|
78
|
+
/** Result continuation L-branch. */
|
|
79
|
+
branch: string;
|
|
80
|
+
/** Input + selection prompt caret. */
|
|
81
|
+
prompt: string;
|
|
82
|
+
/** Blockquote bar. */
|
|
83
|
+
blockquote: string;
|
|
84
|
+
/** Plan-mode badge symbol. */
|
|
85
|
+
plan: string;
|
|
86
|
+
/** Accept-edits / auto badge symbol. */
|
|
87
|
+
accept: string;
|
|
88
|
+
/** Success tick. */
|
|
89
|
+
tick: string;
|
|
90
|
+
/** Horizontal rule fill. */
|
|
91
|
+
hr: string;
|
|
92
|
+
/** Unordered-list bullet. */
|
|
93
|
+
bullet: string;
|
|
94
|
+
/** Progress "thinking" glyph (also the brightest spinner frame). */
|
|
95
|
+
thinking: string;
|
|
96
|
+
arrowDown: string;
|
|
97
|
+
arrowUp: string;
|
|
98
|
+
}
|
|
99
|
+
/** Build the glyph set for a platform. Exported as a function so tests can pin
|
|
100
|
+
* both the darwin (`⏺`) and non-darwin (`●`) dot without monkey-patching. */
|
|
101
|
+
export declare function makeGlyphs(platform?: NodeJS.Platform): Glyphs;
|
|
102
|
+
export declare const GLYPHS: Glyphs;
|
|
103
|
+
export declare const SPINNER_FRAMES: readonly string[];
|
|
104
|
+
/** Static glyph shown instead of the animation under reduced-motion / NO_COLOR. */
|
|
105
|
+
export declare const SPINNER_STATIC = "\u25CF";
|
|
106
|
+
//# sourceMappingURL=theme.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../src/theme.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH;sFACsF;AACtF,MAAM,WAAW,KAAK;IACpB,0FAA0F;IAC1F,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mCAAmC;IACnC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kCAAkC;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sBAAsB;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,sCAAsC;IACtC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uBAAuB;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,uCAAuC;IACvC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,+BAA+B;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kCAAkC;IAClC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,4EAA4E;IAC5E,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,sCAAsC;IACtC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,wEAAwE;IACxE,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;4DAC4D;AAC5D,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;AAyDrD;4EAC4E;AAC5E,wBAAgB,SAAS,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,OAAO,CAGvE;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,YAAY,GAAG,SAAS,EACjC,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,KAAK,CAGP;AAED,MAAM,WAAW,MAAM;IACrB;qEACiE;IACjE,GAAG,EAAE,MAAM,CAAC;IACZ,oCAAoC;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,sCAAsC;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,sBAAsB;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,8BAA8B;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,wCAAwC;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,oBAAoB;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,4BAA4B;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,6BAA6B;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,oEAAoE;IACpE,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;8EAC8E;AAC9E,wBAAgB,UAAU,CAAC,QAAQ,GAAE,MAAM,CAAC,QAA2B,GAAG,MAAM,CAe/E;AAED,eAAO,MAAM,MAAM,EAAE,MAAqB,CAAC;AAK3C,eAAO,MAAM,cAAc,EAAE,SAAS,MAAM,EAAsD,CAAC;AAEnG,mFAAmF;AACnF,eAAO,MAAM,cAAc,WAAM,CAAC"}
|