@claude-code-kit/ui 0.1.0 → 0.1.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/LICENSE +21 -0
- package/README.md +43 -0
- package/dist/index.d.mts +409 -21
- package/dist/index.d.ts +409 -21
- package/dist/index.js +1608 -115
- package/dist/index.mjs +1564 -85
- package/package.json +8 -5
package/dist/index.js
CHANGED
|
@@ -31,30 +31,55 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
31
31
|
// src/index.ts
|
|
32
32
|
var index_exports = {};
|
|
33
33
|
__export(index_exports, {
|
|
34
|
+
Byline: () => Byline,
|
|
34
35
|
CommandRegistry: () => CommandRegistry,
|
|
35
36
|
DEFAULT_BINDINGS: () => DEFAULT_BINDINGS,
|
|
37
|
+
Dialog: () => Dialog,
|
|
36
38
|
Divider: () => Divider,
|
|
39
|
+
FuzzyPicker: () => FuzzyPicker,
|
|
37
40
|
KeybindingSetup: () => KeybindingSetup,
|
|
41
|
+
KeyboardShortcutHint: () => KeyboardShortcutHint,
|
|
42
|
+
ListItem: () => ListItem,
|
|
43
|
+
LoadingState: () => LoadingState,
|
|
44
|
+
Markdown: () => Markdown,
|
|
45
|
+
MarkdownTable: () => MarkdownTable,
|
|
38
46
|
MessageList: () => MessageList,
|
|
39
47
|
MultiSelect: () => MultiSelect,
|
|
48
|
+
Pane: () => Pane,
|
|
40
49
|
ProgressBar: () => ProgressBar,
|
|
41
50
|
PromptInput: () => PromptInput,
|
|
42
51
|
REPL: () => REPL,
|
|
52
|
+
Ratchet: () => Ratchet,
|
|
43
53
|
Select: () => Select,
|
|
44
54
|
Spinner: () => Spinner,
|
|
45
55
|
StatusIcon: () => StatusIcon,
|
|
46
56
|
StatusLine: () => StatusLine,
|
|
57
|
+
StreamingMarkdown: () => StreamingMarkdown,
|
|
47
58
|
StreamingText: () => StreamingText,
|
|
59
|
+
Tab: () => Tab,
|
|
60
|
+
Tabs: () => Tabs,
|
|
61
|
+
TextHoverColorContext: () => TextHoverColorContext,
|
|
62
|
+
ThemeProvider: () => ThemeProvider,
|
|
63
|
+
ThemedBox: () => ThemedBox_default,
|
|
64
|
+
ThemedText: () => ThemedText,
|
|
48
65
|
clearCommand: () => clearCommand,
|
|
66
|
+
color: () => color,
|
|
49
67
|
createCommandRegistry: () => createCommandRegistry,
|
|
50
68
|
defineCommand: () => defineCommand,
|
|
51
69
|
defineJSXCommand: () => defineJSXCommand,
|
|
52
70
|
defineLocalCommand: () => defineLocalCommand,
|
|
53
71
|
exitCommand: () => exitCommand,
|
|
72
|
+
getTheme: () => getTheme,
|
|
54
73
|
helpCommand: () => helpCommand,
|
|
74
|
+
useDoublePress: () => useDoublePress,
|
|
55
75
|
useKeybinding: () => useKeybinding,
|
|
56
76
|
useKeybindings: () => useKeybindings,
|
|
57
|
-
|
|
77
|
+
usePreviewTheme: () => usePreviewTheme,
|
|
78
|
+
useStatusLine: () => useStatusLine,
|
|
79
|
+
useTabsWidth: () => useTabsWidth,
|
|
80
|
+
useTerminalSize: () => useTerminalSize,
|
|
81
|
+
useTheme: () => useTheme,
|
|
82
|
+
useThemeSetting: () => useThemeSetting
|
|
58
83
|
});
|
|
59
84
|
module.exports = __toCommonJS(index_exports);
|
|
60
85
|
__reExport(index_exports, require("@claude-code-kit/ink-renderer"), module.exports);
|
|
@@ -63,7 +88,7 @@ __reExport(index_exports, require("@claude-code-kit/ink-renderer"), module.expor
|
|
|
63
88
|
var import_react = require("react");
|
|
64
89
|
var import_ink_renderer = require("@claude-code-kit/ink-renderer");
|
|
65
90
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
66
|
-
function Divider({ width, color, char = "\u2500", padding = 0, title }) {
|
|
91
|
+
function Divider({ width, color: color2, char = "\u2500", padding = 0, title }) {
|
|
67
92
|
const terminalSize = (0, import_react.useContext)(import_ink_renderer.TerminalSizeContext);
|
|
68
93
|
const terminalWidth = terminalSize?.columns ?? 80;
|
|
69
94
|
const effectiveWidth = Math.max(0, (width ?? terminalWidth - 2) - padding);
|
|
@@ -72,7 +97,7 @@ function Divider({ width, color, char = "\u2500", padding = 0, title }) {
|
|
|
72
97
|
const sideWidth = Math.max(0, effectiveWidth - titleWidth);
|
|
73
98
|
const leftWidth = Math.floor(sideWidth / 2);
|
|
74
99
|
const rightWidth = sideWidth - leftWidth;
|
|
75
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_ink_renderer.Text, { color, dimColor: !
|
|
100
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_ink_renderer.Text, { color: color2, dimColor: !color2, children: [
|
|
76
101
|
char.repeat(leftWidth),
|
|
77
102
|
" ",
|
|
78
103
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ink_renderer.Text, { dimColor: true, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ink_renderer.Ansi, { children: title }) }),
|
|
@@ -80,7 +105,7 @@ function Divider({ width, color, char = "\u2500", padding = 0, title }) {
|
|
|
80
105
|
char.repeat(rightWidth)
|
|
81
106
|
] });
|
|
82
107
|
}
|
|
83
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ink_renderer.Text, { color, dimColor: !
|
|
108
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ink_renderer.Text, { color: color2, dimColor: !color2, children: char.repeat(effectiveWidth) });
|
|
84
109
|
}
|
|
85
110
|
|
|
86
111
|
// src/ProgressBar.tsx
|
|
@@ -418,10 +443,13 @@ function parseBindings(blocks) {
|
|
|
418
443
|
|
|
419
444
|
// src/keybindings/resolver.ts
|
|
420
445
|
function getBindingDisplayText(action, context, bindings) {
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
446
|
+
for (let i = bindings.length - 1; i >= 0; i--) {
|
|
447
|
+
const binding = bindings[i];
|
|
448
|
+
if (binding && binding.action === action && binding.context === context) {
|
|
449
|
+
return chordToString(binding.chord);
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
return void 0;
|
|
425
453
|
}
|
|
426
454
|
function buildKeystroke(input, key) {
|
|
427
455
|
const keyName = getKeyName(input, key);
|
|
@@ -1759,9 +1787,63 @@ function ChordInterceptor({
|
|
|
1759
1787
|
return null;
|
|
1760
1788
|
}
|
|
1761
1789
|
|
|
1762
|
-
// src/
|
|
1790
|
+
// src/hooks/useDoublePress.ts
|
|
1763
1791
|
var import_react6 = require("react");
|
|
1792
|
+
var DOUBLE_PRESS_TIMEOUT_MS = 800;
|
|
1793
|
+
function useDoublePress(setPending, onDoublePress, onFirstPress) {
|
|
1794
|
+
const lastPressRef = (0, import_react6.useRef)(0);
|
|
1795
|
+
const timeoutRef = (0, import_react6.useRef)(void 0);
|
|
1796
|
+
const clearTimeoutSafe = (0, import_react6.useCallback)(() => {
|
|
1797
|
+
if (timeoutRef.current) {
|
|
1798
|
+
clearTimeout(timeoutRef.current);
|
|
1799
|
+
timeoutRef.current = void 0;
|
|
1800
|
+
}
|
|
1801
|
+
}, []);
|
|
1802
|
+
(0, import_react6.useEffect)(() => {
|
|
1803
|
+
return () => {
|
|
1804
|
+
clearTimeoutSafe();
|
|
1805
|
+
};
|
|
1806
|
+
}, [clearTimeoutSafe]);
|
|
1807
|
+
return (0, import_react6.useCallback)(() => {
|
|
1808
|
+
const now = Date.now();
|
|
1809
|
+
const timeSinceLastPress = now - lastPressRef.current;
|
|
1810
|
+
const isDoublePress = timeSinceLastPress <= DOUBLE_PRESS_TIMEOUT_MS && timeoutRef.current !== void 0;
|
|
1811
|
+
if (isDoublePress) {
|
|
1812
|
+
clearTimeoutSafe();
|
|
1813
|
+
setPending(false);
|
|
1814
|
+
onDoublePress();
|
|
1815
|
+
} else {
|
|
1816
|
+
onFirstPress?.();
|
|
1817
|
+
setPending(true);
|
|
1818
|
+
clearTimeoutSafe();
|
|
1819
|
+
timeoutRef.current = setTimeout(
|
|
1820
|
+
(setPending2, timeoutRef2) => {
|
|
1821
|
+
setPending2(false);
|
|
1822
|
+
timeoutRef2.current = void 0;
|
|
1823
|
+
},
|
|
1824
|
+
DOUBLE_PRESS_TIMEOUT_MS,
|
|
1825
|
+
setPending,
|
|
1826
|
+
timeoutRef
|
|
1827
|
+
);
|
|
1828
|
+
}
|
|
1829
|
+
lastPressRef.current = now;
|
|
1830
|
+
}, [setPending, onDoublePress, onFirstPress, clearTimeoutSafe]);
|
|
1831
|
+
}
|
|
1832
|
+
|
|
1833
|
+
// src/hooks/useTerminalSize.ts
|
|
1834
|
+
var import_react7 = require("react");
|
|
1764
1835
|
var import_ink_renderer7 = require("@claude-code-kit/ink-renderer");
|
|
1836
|
+
function useTerminalSize() {
|
|
1837
|
+
const size = (0, import_react7.useContext)(import_ink_renderer7.TerminalSizeContext);
|
|
1838
|
+
if (!size) {
|
|
1839
|
+
throw new Error("useTerminalSize must be used within an Ink App component");
|
|
1840
|
+
}
|
|
1841
|
+
return size;
|
|
1842
|
+
}
|
|
1843
|
+
|
|
1844
|
+
// src/PromptInput.tsx
|
|
1845
|
+
var import_react8 = require("react");
|
|
1846
|
+
var import_ink_renderer8 = require("@claude-code-kit/ink-renderer");
|
|
1765
1847
|
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
1766
1848
|
function PromptInput({
|
|
1767
1849
|
value,
|
|
@@ -1775,13 +1857,13 @@ function PromptInput({
|
|
|
1775
1857
|
onCommandSelect,
|
|
1776
1858
|
history = []
|
|
1777
1859
|
}) {
|
|
1778
|
-
const [cursor, setCursor] = (0,
|
|
1779
|
-
const [historyIndex, setHistoryIndex] = (0,
|
|
1780
|
-
const [suggestionIndex, setSuggestionIndex] = (0,
|
|
1781
|
-
const [showSuggestions, setShowSuggestions] = (0,
|
|
1860
|
+
const [cursor, setCursor] = (0, import_react8.useState)(0);
|
|
1861
|
+
const [historyIndex, setHistoryIndex] = (0, import_react8.useState)(-1);
|
|
1862
|
+
const [suggestionIndex, setSuggestionIndex] = (0, import_react8.useState)(0);
|
|
1863
|
+
const [showSuggestions, setShowSuggestions] = (0, import_react8.useState)(false);
|
|
1782
1864
|
const suggestions = value.startsWith("/") && commands.length > 0 ? commands.filter((cmd) => `/${cmd.name}`.startsWith(value)) : [];
|
|
1783
1865
|
const hasSuggestions = showSuggestions && suggestions.length > 0;
|
|
1784
|
-
const updateValue = (0,
|
|
1866
|
+
const updateValue = (0, import_react8.useCallback)(
|
|
1785
1867
|
(newValue, newCursor) => {
|
|
1786
1868
|
onChange(newValue);
|
|
1787
1869
|
setCursor(newCursor ?? newValue.length);
|
|
@@ -1791,7 +1873,7 @@ function PromptInput({
|
|
|
1791
1873
|
},
|
|
1792
1874
|
[onChange]
|
|
1793
1875
|
);
|
|
1794
|
-
(0,
|
|
1876
|
+
(0, import_ink_renderer8.useInput)(
|
|
1795
1877
|
(input, key) => {
|
|
1796
1878
|
if (disabled) return;
|
|
1797
1879
|
if (key.return) {
|
|
@@ -1912,45 +1994,45 @@ function PromptInput({
|
|
|
1912
1994
|
);
|
|
1913
1995
|
const renderTextWithCursor = () => {
|
|
1914
1996
|
if (value.length === 0 && placeholder) {
|
|
1915
|
-
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
1916
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1917
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1997
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_ink_renderer8.Text, { children: [
|
|
1998
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_ink_renderer8.Text, { inverse: true, children: " " }),
|
|
1999
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_ink_renderer8.Text, { dimColor: true, children: placeholder })
|
|
1918
2000
|
] });
|
|
1919
2001
|
}
|
|
1920
2002
|
const before = value.slice(0, cursor);
|
|
1921
2003
|
const atCursor = cursor < value.length ? value[cursor] : " ";
|
|
1922
2004
|
const after = cursor < value.length ? value.slice(cursor + 1) : "";
|
|
1923
|
-
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
2005
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_ink_renderer8.Text, { children: [
|
|
1924
2006
|
before,
|
|
1925
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2007
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_ink_renderer8.Text, { inverse: true, children: atCursor }),
|
|
1926
2008
|
after
|
|
1927
2009
|
] });
|
|
1928
2010
|
};
|
|
1929
|
-
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
1930
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
1931
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
2011
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_ink_renderer8.Box, { flexDirection: "column", children: [
|
|
2012
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_ink_renderer8.Box, { children: [
|
|
2013
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_ink_renderer8.Text, { color: prefixColor, children: [
|
|
1932
2014
|
prefix,
|
|
1933
2015
|
" "
|
|
1934
2016
|
] }),
|
|
1935
2017
|
renderTextWithCursor()
|
|
1936
2018
|
] }),
|
|
1937
|
-
hasSuggestions && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2019
|
+
hasSuggestions && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_ink_renderer8.Box, { flexDirection: "column", marginLeft: 2, children: suggestions.map((cmd, i) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_ink_renderer8.Box, { children: [
|
|
1938
2020
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1939
|
-
|
|
2021
|
+
import_ink_renderer8.Text,
|
|
1940
2022
|
{
|
|
1941
2023
|
inverse: i === suggestionIndex,
|
|
1942
2024
|
color: i === suggestionIndex ? "cyan" : void 0,
|
|
1943
2025
|
children: ` /${cmd.name}`
|
|
1944
2026
|
}
|
|
1945
2027
|
),
|
|
1946
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2028
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_ink_renderer8.Text, { dimColor: true, children: ` ${cmd.description}` })
|
|
1947
2029
|
] }, cmd.name)) })
|
|
1948
2030
|
] });
|
|
1949
2031
|
}
|
|
1950
2032
|
|
|
1951
2033
|
// src/Spinner.tsx
|
|
1952
|
-
var
|
|
1953
|
-
var
|
|
2034
|
+
var import_react9 = require("react");
|
|
2035
|
+
var import_ink_renderer9 = require("@claude-code-kit/ink-renderer");
|
|
1954
2036
|
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
1955
2037
|
var FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
1956
2038
|
var SPINNER_INTERVAL = 80;
|
|
@@ -1961,22 +2043,22 @@ function Spinner({
|
|
|
1961
2043
|
label,
|
|
1962
2044
|
verb,
|
|
1963
2045
|
verbs,
|
|
1964
|
-
color = DEFAULT_COLOR,
|
|
2046
|
+
color: color2 = DEFAULT_COLOR,
|
|
1965
2047
|
showElapsed = true
|
|
1966
2048
|
}) {
|
|
1967
|
-
const [frameIndex, setFrameIndex] = (0,
|
|
1968
|
-
const [verbIndex, setVerbIndex] = (0,
|
|
1969
|
-
const [elapsed, setElapsed] = (0,
|
|
1970
|
-
const startRef = (0,
|
|
2049
|
+
const [frameIndex, setFrameIndex] = (0, import_react9.useState)(0);
|
|
2050
|
+
const [verbIndex, setVerbIndex] = (0, import_react9.useState)(0);
|
|
2051
|
+
const [elapsed, setElapsed] = (0, import_react9.useState)(0);
|
|
2052
|
+
const startRef = (0, import_react9.useRef)(Date.now());
|
|
1971
2053
|
const allVerbs = verbs ?? (verb ? [verb] : ["Thinking"]);
|
|
1972
|
-
(0,
|
|
2054
|
+
(0, import_react9.useEffect)(() => {
|
|
1973
2055
|
const id = setInterval(() => {
|
|
1974
2056
|
setFrameIndex((i) => (i + 1) % FRAMES.length);
|
|
1975
2057
|
setElapsed(Date.now() - startRef.current);
|
|
1976
2058
|
}, SPINNER_INTERVAL);
|
|
1977
2059
|
return () => clearInterval(id);
|
|
1978
2060
|
}, []);
|
|
1979
|
-
(0,
|
|
2061
|
+
(0, import_react9.useEffect)(() => {
|
|
1980
2062
|
if (allVerbs.length <= 1) return;
|
|
1981
2063
|
const id = setInterval(() => {
|
|
1982
2064
|
setVerbIndex((i) => (i + 1) % allVerbs.length);
|
|
@@ -1987,18 +2069,18 @@ function Spinner({
|
|
|
1987
2069
|
const currentVerb = allVerbs[verbIndex % allVerbs.length];
|
|
1988
2070
|
const elapsedSec = Math.floor(elapsed / 1e3);
|
|
1989
2071
|
const showTime = showElapsed && elapsed >= ELAPSED_SHOW_AFTER;
|
|
1990
|
-
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
1991
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1992
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
2072
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_ink_renderer9.Box, { children: [
|
|
2073
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_ink_renderer9.Text, { color: color2, children: frame }),
|
|
2074
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_ink_renderer9.Text, { children: [
|
|
1993
2075
|
" ",
|
|
1994
2076
|
currentVerb,
|
|
1995
2077
|
"..."
|
|
1996
2078
|
] }),
|
|
1997
|
-
label && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
2079
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_ink_renderer9.Text, { children: [
|
|
1998
2080
|
" ",
|
|
1999
2081
|
label
|
|
2000
2082
|
] }),
|
|
2001
|
-
showTime && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
2083
|
+
showTime && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_ink_renderer9.Text, { dimColor: true, children: [
|
|
2002
2084
|
" (",
|
|
2003
2085
|
elapsedSec,
|
|
2004
2086
|
"s)"
|
|
@@ -2006,29 +2088,766 @@ function Spinner({
|
|
|
2006
2088
|
] });
|
|
2007
2089
|
}
|
|
2008
2090
|
|
|
2009
|
-
// src/
|
|
2010
|
-
var
|
|
2011
|
-
var
|
|
2091
|
+
// src/Markdown.tsx
|
|
2092
|
+
var import_marked2 = require("marked");
|
|
2093
|
+
var import_react12 = require("react");
|
|
2094
|
+
var import_ink_renderer16 = require("@claude-code-kit/ink-renderer");
|
|
2095
|
+
|
|
2096
|
+
// src/design-system/ThemeProvider.tsx
|
|
2097
|
+
var import_react10 = require("react");
|
|
2012
2098
|
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
2099
|
+
var themes = {
|
|
2100
|
+
dark: {
|
|
2101
|
+
text: "#E0E0E0",
|
|
2102
|
+
dimText: "#666666",
|
|
2103
|
+
border: "#444444",
|
|
2104
|
+
accent: "#5B9BD5",
|
|
2105
|
+
success: "#6BC76B",
|
|
2106
|
+
warning: "#E5C07B",
|
|
2107
|
+
error: "#E06C75",
|
|
2108
|
+
assistant: "#DA7756",
|
|
2109
|
+
inactive: "#666666",
|
|
2110
|
+
inverseText: "#1E1E1E",
|
|
2111
|
+
permission: "#5B9BD5"
|
|
2112
|
+
},
|
|
2113
|
+
light: {
|
|
2114
|
+
text: "#1E1E1E",
|
|
2115
|
+
dimText: "#999999",
|
|
2116
|
+
border: "#CCCCCC",
|
|
2117
|
+
accent: "#0066CC",
|
|
2118
|
+
success: "#2E7D32",
|
|
2119
|
+
warning: "#F57C00",
|
|
2120
|
+
error: "#C62828",
|
|
2121
|
+
assistant: "#DA7756",
|
|
2122
|
+
inactive: "#999999",
|
|
2123
|
+
inverseText: "#FFFFFF",
|
|
2124
|
+
permission: "#0066CC"
|
|
2125
|
+
}
|
|
2126
|
+
};
|
|
2127
|
+
function getTheme(name) {
|
|
2128
|
+
return themes[name] ?? themes.dark;
|
|
2129
|
+
}
|
|
2130
|
+
var DEFAULT_THEME = "dark";
|
|
2131
|
+
var ThemeContext = (0, import_react10.createContext)({
|
|
2132
|
+
themeSetting: DEFAULT_THEME,
|
|
2133
|
+
setThemeSetting: () => {
|
|
2134
|
+
},
|
|
2135
|
+
setPreviewTheme: () => {
|
|
2136
|
+
},
|
|
2137
|
+
savePreview: () => {
|
|
2138
|
+
},
|
|
2139
|
+
cancelPreview: () => {
|
|
2140
|
+
},
|
|
2141
|
+
currentTheme: DEFAULT_THEME
|
|
2142
|
+
});
|
|
2143
|
+
function ThemeProvider({
|
|
2144
|
+
children,
|
|
2145
|
+
initialState = "dark",
|
|
2146
|
+
onThemeSave
|
|
2147
|
+
}) {
|
|
2148
|
+
const [themeSetting, setThemeSetting] = (0, import_react10.useState)(initialState);
|
|
2149
|
+
const [previewTheme, setPreviewTheme] = (0, import_react10.useState)(null);
|
|
2150
|
+
const activeSetting = previewTheme ?? themeSetting;
|
|
2151
|
+
const currentTheme = activeSetting === "auto" ? "dark" : activeSetting;
|
|
2152
|
+
const value = (0, import_react10.useMemo)(
|
|
2153
|
+
() => ({
|
|
2154
|
+
themeSetting,
|
|
2155
|
+
setThemeSetting: (newSetting) => {
|
|
2156
|
+
setThemeSetting(newSetting);
|
|
2157
|
+
setPreviewTheme(null);
|
|
2158
|
+
onThemeSave?.(newSetting);
|
|
2159
|
+
},
|
|
2160
|
+
setPreviewTheme: (newSetting) => {
|
|
2161
|
+
setPreviewTheme(newSetting);
|
|
2162
|
+
},
|
|
2163
|
+
savePreview: () => {
|
|
2164
|
+
if (previewTheme !== null) {
|
|
2165
|
+
setThemeSetting(previewTheme);
|
|
2166
|
+
setPreviewTheme(null);
|
|
2167
|
+
onThemeSave?.(previewTheme);
|
|
2168
|
+
}
|
|
2169
|
+
},
|
|
2170
|
+
cancelPreview: () => {
|
|
2171
|
+
if (previewTheme !== null) {
|
|
2172
|
+
setPreviewTheme(null);
|
|
2173
|
+
}
|
|
2174
|
+
},
|
|
2175
|
+
currentTheme
|
|
2176
|
+
}),
|
|
2177
|
+
[themeSetting, previewTheme, currentTheme, onThemeSave]
|
|
2178
|
+
);
|
|
2179
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ThemeContext.Provider, { value, children });
|
|
2180
|
+
}
|
|
2181
|
+
function useTheme() {
|
|
2182
|
+
const { currentTheme, setThemeSetting } = (0, import_react10.useContext)(ThemeContext);
|
|
2183
|
+
return [currentTheme, setThemeSetting];
|
|
2184
|
+
}
|
|
2185
|
+
function useThemeSetting() {
|
|
2186
|
+
return (0, import_react10.useContext)(ThemeContext).themeSetting;
|
|
2187
|
+
}
|
|
2188
|
+
function usePreviewTheme() {
|
|
2189
|
+
const { setPreviewTheme, savePreview, cancelPreview } = (0, import_react10.useContext)(ThemeContext);
|
|
2190
|
+
return { setPreviewTheme, savePreview, cancelPreview };
|
|
2191
|
+
}
|
|
2192
|
+
|
|
2193
|
+
// src/utils/optional/cliHighlight.ts
|
|
2194
|
+
var cliHighlightPromise;
|
|
2195
|
+
async function loadCliHighlight() {
|
|
2196
|
+
try {
|
|
2197
|
+
const cliHighlight = await import("cli-highlight");
|
|
2198
|
+
return {
|
|
2199
|
+
highlight: cliHighlight.highlight,
|
|
2200
|
+
supportsLanguage: cliHighlight.supportsLanguage
|
|
2201
|
+
};
|
|
2202
|
+
} catch {
|
|
2203
|
+
return null;
|
|
2204
|
+
}
|
|
2205
|
+
}
|
|
2206
|
+
function getCliHighlightPromise() {
|
|
2207
|
+
cliHighlightPromise ?? (cliHighlightPromise = loadCliHighlight());
|
|
2208
|
+
return cliHighlightPromise;
|
|
2209
|
+
}
|
|
2210
|
+
|
|
2211
|
+
// src/utils/hash.ts
|
|
2212
|
+
function hashContent(content) {
|
|
2213
|
+
let h = 2166136261 | 0;
|
|
2214
|
+
for (let i = 0; i < content.length; i++) {
|
|
2215
|
+
h ^= content.charCodeAt(i);
|
|
2216
|
+
h = Math.imul(h, 16777619);
|
|
2217
|
+
}
|
|
2218
|
+
let h2 = 26499749718 | 0;
|
|
2219
|
+
for (let i = 0; i < content.length; i++) {
|
|
2220
|
+
h2 ^= content.charCodeAt(i);
|
|
2221
|
+
h2 = Math.imul(h2, 16777619);
|
|
2222
|
+
}
|
|
2223
|
+
return ((h >>> 0) * 1048576 + (h2 >>> 0)).toString(36) + content.length.toString(36);
|
|
2224
|
+
}
|
|
2225
|
+
|
|
2226
|
+
// src/utils/markdown.ts
|
|
2227
|
+
var import_chalk = __toESM(require("chalk"));
|
|
2228
|
+
var import_marked = require("marked");
|
|
2229
|
+
var import_strip_ansi = __toESM(require("strip-ansi"));
|
|
2230
|
+
var import_ink_renderer11 = require("@claude-code-kit/ink-renderer");
|
|
2231
|
+
|
|
2232
|
+
// src/design-system/color.ts
|
|
2233
|
+
var import_ink_renderer10 = require("@claude-code-kit/ink-renderer");
|
|
2234
|
+
function color(c, theme, type = "foreground") {
|
|
2235
|
+
return (text) => {
|
|
2236
|
+
if (!c) {
|
|
2237
|
+
return text;
|
|
2238
|
+
}
|
|
2239
|
+
if (c.startsWith("rgb(") || c.startsWith("#") || c.startsWith("ansi256(") || c.startsWith("ansi:")) {
|
|
2240
|
+
return (0, import_ink_renderer10.colorize)(text, c, type);
|
|
2241
|
+
}
|
|
2242
|
+
return (0, import_ink_renderer10.colorize)(text, getTheme(theme)[c], type);
|
|
2243
|
+
};
|
|
2244
|
+
}
|
|
2245
|
+
|
|
2246
|
+
// src/utils/markdown.ts
|
|
2247
|
+
function logForDebugging3(...args) {
|
|
2248
|
+
if (process.env["DEBUG"]) {
|
|
2249
|
+
console.debug(...args);
|
|
2250
|
+
}
|
|
2251
|
+
}
|
|
2252
|
+
var EOL = "\n";
|
|
2253
|
+
var BLOCKQUOTE_BAR = "\u258E";
|
|
2254
|
+
var OSC8_START = "\x1B]8;;";
|
|
2255
|
+
var OSC8_END = "\x07";
|
|
2256
|
+
function supportsHyperlinks() {
|
|
2257
|
+
const termProgram = process.env["TERM_PROGRAM"];
|
|
2258
|
+
const lcTerminal = process.env["LC_TERMINAL"];
|
|
2259
|
+
const term = process.env["TERM"];
|
|
2260
|
+
const supported = ["ghostty", "Hyper", "kitty", "alacritty", "iTerm.app", "iTerm2"];
|
|
2261
|
+
return !!(termProgram && supported.includes(termProgram)) || !!(lcTerminal && supported.includes(lcTerminal)) || !!term?.includes("kitty");
|
|
2262
|
+
}
|
|
2263
|
+
function createHyperlink(url, content) {
|
|
2264
|
+
if (!supportsHyperlinks()) {
|
|
2265
|
+
return url;
|
|
2266
|
+
}
|
|
2267
|
+
const displayText = content ?? url;
|
|
2268
|
+
const coloredText = import_chalk.default.blue(displayText);
|
|
2269
|
+
return `${OSC8_START}${url}${OSC8_END}${coloredText}${OSC8_START}${OSC8_END}`;
|
|
2270
|
+
}
|
|
2271
|
+
var markedConfigured = false;
|
|
2272
|
+
function configureMarked() {
|
|
2273
|
+
if (markedConfigured) return;
|
|
2274
|
+
markedConfigured = true;
|
|
2275
|
+
import_marked.marked.use({
|
|
2276
|
+
tokenizer: {
|
|
2277
|
+
del() {
|
|
2278
|
+
return void 0;
|
|
2279
|
+
}
|
|
2280
|
+
}
|
|
2281
|
+
});
|
|
2282
|
+
}
|
|
2283
|
+
function formatToken(token, theme, listDepth = 0, orderedListNumber = null, parent = null, highlight = null) {
|
|
2284
|
+
switch (token.type) {
|
|
2285
|
+
case "blockquote": {
|
|
2286
|
+
const inner = (token.tokens ?? []).map((_) => formatToken(_, theme, 0, null, null, highlight)).join("");
|
|
2287
|
+
const bar = import_chalk.default.dim(BLOCKQUOTE_BAR);
|
|
2288
|
+
return inner.split(EOL).map(
|
|
2289
|
+
(line) => (0, import_strip_ansi.default)(line).trim() ? `${bar} ${import_chalk.default.italic(line)}` : line
|
|
2290
|
+
).join(EOL);
|
|
2291
|
+
}
|
|
2292
|
+
case "code": {
|
|
2293
|
+
if (!highlight) {
|
|
2294
|
+
return token.text + EOL;
|
|
2295
|
+
}
|
|
2296
|
+
let language = "plaintext";
|
|
2297
|
+
if (token.lang) {
|
|
2298
|
+
if (highlight.supportsLanguage(token.lang)) {
|
|
2299
|
+
language = token.lang;
|
|
2300
|
+
} else {
|
|
2301
|
+
logForDebugging3(
|
|
2302
|
+
`Language not supported while highlighting code, falling back to plaintext: ${token.lang}`
|
|
2303
|
+
);
|
|
2304
|
+
}
|
|
2305
|
+
}
|
|
2306
|
+
return highlight.highlight(token.text, { language }) + EOL;
|
|
2307
|
+
}
|
|
2308
|
+
case "codespan": {
|
|
2309
|
+
return color("permission", theme)(token.text);
|
|
2310
|
+
}
|
|
2311
|
+
case "em":
|
|
2312
|
+
return import_chalk.default.italic(
|
|
2313
|
+
(token.tokens ?? []).map((_) => formatToken(_, theme, 0, null, parent, highlight)).join("")
|
|
2314
|
+
);
|
|
2315
|
+
case "strong":
|
|
2316
|
+
return import_chalk.default.bold(
|
|
2317
|
+
(token.tokens ?? []).map((_) => formatToken(_, theme, 0, null, parent, highlight)).join("")
|
|
2318
|
+
);
|
|
2319
|
+
case "heading":
|
|
2320
|
+
switch (token.depth) {
|
|
2321
|
+
case 1:
|
|
2322
|
+
return import_chalk.default.bold.italic.underline(
|
|
2323
|
+
(token.tokens ?? []).map((_) => formatToken(_, theme, 0, null, null, highlight)).join("")
|
|
2324
|
+
) + EOL + EOL;
|
|
2325
|
+
case 2:
|
|
2326
|
+
return import_chalk.default.bold(
|
|
2327
|
+
(token.tokens ?? []).map((_) => formatToken(_, theme, 0, null, null, highlight)).join("")
|
|
2328
|
+
) + EOL + EOL;
|
|
2329
|
+
default:
|
|
2330
|
+
return import_chalk.default.bold(
|
|
2331
|
+
(token.tokens ?? []).map((_) => formatToken(_, theme, 0, null, null, highlight)).join("")
|
|
2332
|
+
) + EOL + EOL;
|
|
2333
|
+
}
|
|
2334
|
+
case "hr":
|
|
2335
|
+
return "---";
|
|
2336
|
+
case "image":
|
|
2337
|
+
return token.href;
|
|
2338
|
+
case "link": {
|
|
2339
|
+
if (token.href.startsWith("mailto:")) {
|
|
2340
|
+
const email = token.href.replace(/^mailto:/, "");
|
|
2341
|
+
return email;
|
|
2342
|
+
}
|
|
2343
|
+
const linkText = (token.tokens ?? []).map((_) => formatToken(_, theme, 0, null, token, highlight)).join("");
|
|
2344
|
+
const plainLinkText = (0, import_strip_ansi.default)(linkText);
|
|
2345
|
+
if (plainLinkText && plainLinkText !== token.href) {
|
|
2346
|
+
return createHyperlink(token.href, linkText);
|
|
2347
|
+
}
|
|
2348
|
+
return createHyperlink(token.href);
|
|
2349
|
+
}
|
|
2350
|
+
case "list": {
|
|
2351
|
+
return token.items.map(
|
|
2352
|
+
(_, index) => formatToken(
|
|
2353
|
+
_,
|
|
2354
|
+
theme,
|
|
2355
|
+
listDepth,
|
|
2356
|
+
token.ordered ? token.start + index : null,
|
|
2357
|
+
token,
|
|
2358
|
+
highlight
|
|
2359
|
+
)
|
|
2360
|
+
).join("");
|
|
2361
|
+
}
|
|
2362
|
+
case "list_item":
|
|
2363
|
+
return (token.tokens ?? []).map(
|
|
2364
|
+
(_) => `${" ".repeat(listDepth)}${formatToken(_, theme, listDepth + 1, orderedListNumber, token, highlight)}`
|
|
2365
|
+
).join("");
|
|
2366
|
+
case "paragraph":
|
|
2367
|
+
return (token.tokens ?? []).map((_) => formatToken(_, theme, 0, null, null, highlight)).join("") + EOL;
|
|
2368
|
+
case "space":
|
|
2369
|
+
return EOL;
|
|
2370
|
+
case "br":
|
|
2371
|
+
return EOL;
|
|
2372
|
+
case "text":
|
|
2373
|
+
if (parent?.type === "link") {
|
|
2374
|
+
return token.text;
|
|
2375
|
+
}
|
|
2376
|
+
if (parent?.type === "list_item") {
|
|
2377
|
+
return `${orderedListNumber === null ? "-" : getListNumber(listDepth, orderedListNumber) + "."} ${token.tokens ? token.tokens.map((_) => formatToken(_, theme, listDepth, orderedListNumber, token, highlight)).join("") : linkifyIssueReferences(token.text)}${EOL}`;
|
|
2378
|
+
}
|
|
2379
|
+
return linkifyIssueReferences(token.text);
|
|
2380
|
+
case "table": {
|
|
2381
|
+
let getDisplayText2 = function(tokens) {
|
|
2382
|
+
return (0, import_strip_ansi.default)(
|
|
2383
|
+
tokens?.map((_) => formatToken(_, theme, 0, null, null, highlight)).join("") ?? ""
|
|
2384
|
+
);
|
|
2385
|
+
};
|
|
2386
|
+
var getDisplayText = getDisplayText2;
|
|
2387
|
+
const tableToken = token;
|
|
2388
|
+
const columnWidths = tableToken.header.map((header, index) => {
|
|
2389
|
+
let maxWidth = (0, import_ink_renderer11.stringWidth)(getDisplayText2(header.tokens));
|
|
2390
|
+
for (const row of tableToken.rows) {
|
|
2391
|
+
const cellLength = (0, import_ink_renderer11.stringWidth)(getDisplayText2(row[index]?.tokens));
|
|
2392
|
+
maxWidth = Math.max(maxWidth, cellLength);
|
|
2393
|
+
}
|
|
2394
|
+
return Math.max(maxWidth, 3);
|
|
2395
|
+
});
|
|
2396
|
+
let tableOutput = "| ";
|
|
2397
|
+
tableToken.header.forEach((header, index) => {
|
|
2398
|
+
const content = header.tokens?.map((_) => formatToken(_, theme, 0, null, null, highlight)).join("") ?? "";
|
|
2399
|
+
const displayText = getDisplayText2(header.tokens);
|
|
2400
|
+
const width = columnWidths[index];
|
|
2401
|
+
const align = tableToken.align?.[index];
|
|
2402
|
+
tableOutput += padAligned(content, (0, import_ink_renderer11.stringWidth)(displayText), width, align) + " | ";
|
|
2403
|
+
});
|
|
2404
|
+
tableOutput = tableOutput.trimEnd() + EOL;
|
|
2405
|
+
tableOutput += "|";
|
|
2406
|
+
columnWidths.forEach((width) => {
|
|
2407
|
+
const separator = "-".repeat(width + 2);
|
|
2408
|
+
tableOutput += separator + "|";
|
|
2409
|
+
});
|
|
2410
|
+
tableOutput += EOL;
|
|
2411
|
+
tableToken.rows.forEach((row) => {
|
|
2412
|
+
tableOutput += "| ";
|
|
2413
|
+
row.forEach((cell, index) => {
|
|
2414
|
+
const content = cell.tokens?.map((_) => formatToken(_, theme, 0, null, null, highlight)).join("") ?? "";
|
|
2415
|
+
const displayText = getDisplayText2(cell.tokens);
|
|
2416
|
+
const width = columnWidths[index];
|
|
2417
|
+
const align = tableToken.align?.[index];
|
|
2418
|
+
tableOutput += padAligned(content, (0, import_ink_renderer11.stringWidth)(displayText), width, align) + " | ";
|
|
2419
|
+
});
|
|
2420
|
+
tableOutput = tableOutput.trimEnd() + EOL;
|
|
2421
|
+
});
|
|
2422
|
+
return tableOutput + EOL;
|
|
2423
|
+
}
|
|
2424
|
+
case "escape":
|
|
2425
|
+
return token.text;
|
|
2426
|
+
case "def":
|
|
2427
|
+
case "del":
|
|
2428
|
+
case "html":
|
|
2429
|
+
return "";
|
|
2430
|
+
}
|
|
2431
|
+
return "";
|
|
2432
|
+
}
|
|
2433
|
+
var ISSUE_REF_PATTERN = /(^|[^\w./-])([A-Za-z0-9][\w-]*\/[A-Za-z0-9][\w.-]*)#(\d+)\b/g;
|
|
2434
|
+
function linkifyIssueReferences(text) {
|
|
2435
|
+
if (!supportsHyperlinks()) {
|
|
2436
|
+
return text;
|
|
2437
|
+
}
|
|
2438
|
+
return text.replace(
|
|
2439
|
+
ISSUE_REF_PATTERN,
|
|
2440
|
+
(_match, prefix, repo, num) => prefix + createHyperlink(
|
|
2441
|
+
`https://github.com/${repo}/issues/${num}`,
|
|
2442
|
+
`${repo}#${num}`
|
|
2443
|
+
)
|
|
2444
|
+
);
|
|
2445
|
+
}
|
|
2446
|
+
function numberToLetter(n) {
|
|
2447
|
+
let result = "";
|
|
2448
|
+
while (n > 0) {
|
|
2449
|
+
n--;
|
|
2450
|
+
result = String.fromCharCode(97 + n % 26) + result;
|
|
2451
|
+
n = Math.floor(n / 26);
|
|
2452
|
+
}
|
|
2453
|
+
return result;
|
|
2454
|
+
}
|
|
2455
|
+
var ROMAN_VALUES = [
|
|
2456
|
+
[1e3, "m"],
|
|
2457
|
+
[900, "cm"],
|
|
2458
|
+
[500, "d"],
|
|
2459
|
+
[400, "cd"],
|
|
2460
|
+
[100, "c"],
|
|
2461
|
+
[90, "xc"],
|
|
2462
|
+
[50, "l"],
|
|
2463
|
+
[40, "xl"],
|
|
2464
|
+
[10, "x"],
|
|
2465
|
+
[9, "ix"],
|
|
2466
|
+
[5, "v"],
|
|
2467
|
+
[4, "iv"],
|
|
2468
|
+
[1, "i"]
|
|
2469
|
+
];
|
|
2470
|
+
function numberToRoman(n) {
|
|
2471
|
+
let result = "";
|
|
2472
|
+
for (const [value, numeral] of ROMAN_VALUES) {
|
|
2473
|
+
while (n >= value) {
|
|
2474
|
+
result += numeral;
|
|
2475
|
+
n -= value;
|
|
2476
|
+
}
|
|
2477
|
+
}
|
|
2478
|
+
return result;
|
|
2479
|
+
}
|
|
2480
|
+
function getListNumber(listDepth, orderedListNumber) {
|
|
2481
|
+
switch (listDepth) {
|
|
2482
|
+
case 0:
|
|
2483
|
+
case 1:
|
|
2484
|
+
return orderedListNumber.toString();
|
|
2485
|
+
case 2:
|
|
2486
|
+
return numberToLetter(orderedListNumber);
|
|
2487
|
+
case 3:
|
|
2488
|
+
return numberToRoman(orderedListNumber);
|
|
2489
|
+
default:
|
|
2490
|
+
return orderedListNumber.toString();
|
|
2491
|
+
}
|
|
2492
|
+
}
|
|
2493
|
+
function padAligned(content, displayWidth, targetWidth, align) {
|
|
2494
|
+
const padding = Math.max(0, targetWidth - displayWidth);
|
|
2495
|
+
if (align === "center") {
|
|
2496
|
+
const leftPad = Math.floor(padding / 2);
|
|
2497
|
+
return " ".repeat(leftPad) + content + " ".repeat(padding - leftPad);
|
|
2498
|
+
}
|
|
2499
|
+
if (align === "right") {
|
|
2500
|
+
return " ".repeat(padding) + content;
|
|
2501
|
+
}
|
|
2502
|
+
return content + " ".repeat(padding);
|
|
2503
|
+
}
|
|
2504
|
+
|
|
2505
|
+
// src/MarkdownTable.tsx
|
|
2506
|
+
var import_react11 = require("react");
|
|
2507
|
+
var import_strip_ansi2 = __toESM(require("strip-ansi"));
|
|
2508
|
+
var import_ink_renderer12 = require("@claude-code-kit/ink-renderer");
|
|
2509
|
+
var import_ink_renderer13 = require("@claude-code-kit/ink-renderer");
|
|
2510
|
+
var import_ink_renderer14 = require("@claude-code-kit/ink-renderer");
|
|
2511
|
+
var import_ink_renderer15 = require("@claude-code-kit/ink-renderer");
|
|
2512
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
2513
|
+
var SAFETY_MARGIN = 4;
|
|
2514
|
+
var MIN_COLUMN_WIDTH = 3;
|
|
2515
|
+
var MAX_ROW_LINES = 4;
|
|
2516
|
+
var ANSI_BOLD_START = "\x1B[1m";
|
|
2517
|
+
var ANSI_BOLD_END = "\x1B[22m";
|
|
2518
|
+
function wrapText(text, width, options) {
|
|
2519
|
+
if (width <= 0) return [text];
|
|
2520
|
+
const trimmedText = text.trimEnd();
|
|
2521
|
+
const wrapped = (0, import_ink_renderer14.wrapAnsi)(trimmedText, width, {
|
|
2522
|
+
hard: options?.hard ?? false,
|
|
2523
|
+
trim: false,
|
|
2524
|
+
wordWrap: true
|
|
2525
|
+
});
|
|
2526
|
+
const lines = wrapped.split("\n").filter((line) => line.length > 0);
|
|
2527
|
+
return lines.length > 0 ? lines : [""];
|
|
2528
|
+
}
|
|
2529
|
+
function MarkdownTable({
|
|
2530
|
+
token,
|
|
2531
|
+
highlight,
|
|
2532
|
+
forceWidth
|
|
2533
|
+
}) {
|
|
2534
|
+
const [theme] = useTheme();
|
|
2535
|
+
const terminalSize = (0, import_react11.useContext)(import_ink_renderer12.TerminalSizeContext);
|
|
2536
|
+
const actualTerminalWidth = terminalSize?.columns ?? 80;
|
|
2537
|
+
const terminalWidth = forceWidth ?? actualTerminalWidth;
|
|
2538
|
+
function formatCell(tokens) {
|
|
2539
|
+
return tokens?.map((_) => formatToken(_, theme, 0, null, null, highlight)).join("") ?? "";
|
|
2540
|
+
}
|
|
2541
|
+
function getPlainText(tokens_0) {
|
|
2542
|
+
return (0, import_strip_ansi2.default)(formatCell(tokens_0));
|
|
2543
|
+
}
|
|
2544
|
+
function getMinWidth(tokens_1) {
|
|
2545
|
+
const text = getPlainText(tokens_1);
|
|
2546
|
+
const words = text.split(/\s+/).filter((w) => w.length > 0);
|
|
2547
|
+
if (words.length === 0) return MIN_COLUMN_WIDTH;
|
|
2548
|
+
return Math.max(...words.map((w_0) => (0, import_ink_renderer13.stringWidth)(w_0)), MIN_COLUMN_WIDTH);
|
|
2549
|
+
}
|
|
2550
|
+
function getIdealWidth(tokens_2) {
|
|
2551
|
+
return Math.max((0, import_ink_renderer13.stringWidth)(getPlainText(tokens_2)), MIN_COLUMN_WIDTH);
|
|
2552
|
+
}
|
|
2553
|
+
const minWidths = token.header.map((header, colIndex) => {
|
|
2554
|
+
let maxMinWidth = getMinWidth(header.tokens);
|
|
2555
|
+
for (const row of token.rows) {
|
|
2556
|
+
maxMinWidth = Math.max(maxMinWidth, getMinWidth(row[colIndex]?.tokens));
|
|
2557
|
+
}
|
|
2558
|
+
return maxMinWidth;
|
|
2559
|
+
});
|
|
2560
|
+
const idealWidths = token.header.map((header_0, colIndex_0) => {
|
|
2561
|
+
let maxIdeal = getIdealWidth(header_0.tokens);
|
|
2562
|
+
for (const row_0 of token.rows) {
|
|
2563
|
+
maxIdeal = Math.max(maxIdeal, getIdealWidth(row_0[colIndex_0]?.tokens));
|
|
2564
|
+
}
|
|
2565
|
+
return maxIdeal;
|
|
2566
|
+
});
|
|
2567
|
+
const numCols = token.header.length;
|
|
2568
|
+
const borderOverhead = 1 + numCols * 3;
|
|
2569
|
+
const availableWidth = Math.max(terminalWidth - borderOverhead - SAFETY_MARGIN, numCols * MIN_COLUMN_WIDTH);
|
|
2570
|
+
const totalMin = minWidths.reduce((sum, w_1) => sum + w_1, 0);
|
|
2571
|
+
const totalIdeal = idealWidths.reduce((sum_0, w_2) => sum_0 + w_2, 0);
|
|
2572
|
+
let needsHardWrap = false;
|
|
2573
|
+
let columnWidths;
|
|
2574
|
+
if (totalIdeal <= availableWidth) {
|
|
2575
|
+
columnWidths = idealWidths;
|
|
2576
|
+
} else if (totalMin <= availableWidth) {
|
|
2577
|
+
const extraSpace = availableWidth - totalMin;
|
|
2578
|
+
const overflows = idealWidths.map((ideal, i) => ideal - minWidths[i]);
|
|
2579
|
+
const totalOverflow = overflows.reduce((sum_1, o) => sum_1 + o, 0);
|
|
2580
|
+
columnWidths = minWidths.map((min, i_0) => {
|
|
2581
|
+
if (totalOverflow === 0) return min;
|
|
2582
|
+
const extra = Math.floor(overflows[i_0] / totalOverflow * extraSpace);
|
|
2583
|
+
return min + extra;
|
|
2584
|
+
});
|
|
2585
|
+
} else {
|
|
2586
|
+
needsHardWrap = true;
|
|
2587
|
+
const scaleFactor = availableWidth / totalMin;
|
|
2588
|
+
columnWidths = minWidths.map((w_3) => Math.max(Math.floor(w_3 * scaleFactor), MIN_COLUMN_WIDTH));
|
|
2589
|
+
}
|
|
2590
|
+
function calculateMaxRowLines() {
|
|
2591
|
+
let maxLines = 1;
|
|
2592
|
+
for (let i_1 = 0; i_1 < token.header.length; i_1++) {
|
|
2593
|
+
const content = formatCell(token.header[i_1].tokens);
|
|
2594
|
+
const wrapped = wrapText(content, columnWidths[i_1], {
|
|
2595
|
+
hard: needsHardWrap
|
|
2596
|
+
});
|
|
2597
|
+
maxLines = Math.max(maxLines, wrapped.length);
|
|
2598
|
+
}
|
|
2599
|
+
for (const row_1 of token.rows) {
|
|
2600
|
+
for (let i_2 = 0; i_2 < row_1.length; i_2++) {
|
|
2601
|
+
const content_0 = formatCell(row_1[i_2]?.tokens);
|
|
2602
|
+
const wrapped_0 = wrapText(content_0, columnWidths[i_2], {
|
|
2603
|
+
hard: needsHardWrap
|
|
2604
|
+
});
|
|
2605
|
+
maxLines = Math.max(maxLines, wrapped_0.length);
|
|
2606
|
+
}
|
|
2607
|
+
}
|
|
2608
|
+
return maxLines;
|
|
2609
|
+
}
|
|
2610
|
+
const maxRowLines = calculateMaxRowLines();
|
|
2611
|
+
const useVerticalFormat = maxRowLines > MAX_ROW_LINES;
|
|
2612
|
+
function renderRowLines(cells, isHeader) {
|
|
2613
|
+
const cellLines = cells.map((cell, colIndex_1) => {
|
|
2614
|
+
const formattedText = formatCell(cell.tokens);
|
|
2615
|
+
const width = columnWidths[colIndex_1];
|
|
2616
|
+
return wrapText(formattedText, width, {
|
|
2617
|
+
hard: needsHardWrap
|
|
2618
|
+
});
|
|
2619
|
+
});
|
|
2620
|
+
const maxLines_0 = Math.max(...cellLines.map((lines) => lines.length), 1);
|
|
2621
|
+
const verticalOffsets = cellLines.map((lines_0) => Math.floor((maxLines_0 - lines_0.length) / 2));
|
|
2622
|
+
const result = [];
|
|
2623
|
+
for (let lineIdx = 0; lineIdx < maxLines_0; lineIdx++) {
|
|
2624
|
+
let line = "\u2502";
|
|
2625
|
+
for (let colIndex_2 = 0; colIndex_2 < cells.length; colIndex_2++) {
|
|
2626
|
+
const lines_1 = cellLines[colIndex_2];
|
|
2627
|
+
const offset = verticalOffsets[colIndex_2];
|
|
2628
|
+
const contentLineIdx = lineIdx - offset;
|
|
2629
|
+
const lineText = contentLineIdx >= 0 && contentLineIdx < lines_1.length ? lines_1[contentLineIdx] : "";
|
|
2630
|
+
const width_0 = columnWidths[colIndex_2];
|
|
2631
|
+
const align = isHeader ? "center" : token.align?.[colIndex_2] ?? "left";
|
|
2632
|
+
line += " " + padAligned(lineText, (0, import_ink_renderer13.stringWidth)(lineText), width_0, align) + " \u2502";
|
|
2633
|
+
}
|
|
2634
|
+
result.push(line);
|
|
2635
|
+
}
|
|
2636
|
+
return result;
|
|
2637
|
+
}
|
|
2638
|
+
function renderBorderLine(type) {
|
|
2639
|
+
const [left, mid, cross, right] = {
|
|
2640
|
+
top: ["\u250C", "\u2500", "\u252C", "\u2510"],
|
|
2641
|
+
middle: ["\u251C", "\u2500", "\u253C", "\u2524"],
|
|
2642
|
+
bottom: ["\u2514", "\u2500", "\u2534", "\u2518"]
|
|
2643
|
+
}[type];
|
|
2644
|
+
let line_0 = left;
|
|
2645
|
+
columnWidths.forEach((width_1, colIndex_3) => {
|
|
2646
|
+
line_0 += mid.repeat(width_1 + 2);
|
|
2647
|
+
line_0 += colIndex_3 < columnWidths.length - 1 ? cross : right;
|
|
2648
|
+
});
|
|
2649
|
+
return line_0;
|
|
2650
|
+
}
|
|
2651
|
+
function renderVerticalFormat() {
|
|
2652
|
+
const lines_2 = [];
|
|
2653
|
+
const headers = token.header.map((h) => getPlainText(h.tokens));
|
|
2654
|
+
const separatorWidth = Math.min(terminalWidth - 1, 40);
|
|
2655
|
+
const separator = "\u2500".repeat(separatorWidth);
|
|
2656
|
+
const wrapIndent = " ";
|
|
2657
|
+
token.rows.forEach((row_2, rowIndex) => {
|
|
2658
|
+
if (rowIndex > 0) {
|
|
2659
|
+
lines_2.push(separator);
|
|
2660
|
+
}
|
|
2661
|
+
row_2.forEach((cell_0, colIndex_4) => {
|
|
2662
|
+
const label = headers[colIndex_4] || `Column ${colIndex_4 + 1}`;
|
|
2663
|
+
const rawValue = formatCell(cell_0.tokens).trimEnd();
|
|
2664
|
+
const value = rawValue.replace(/\n+/g, " ").replace(/\s+/g, " ").trim();
|
|
2665
|
+
const firstLineWidth = terminalWidth - (0, import_ink_renderer13.stringWidth)(label) - 3;
|
|
2666
|
+
const subsequentLineWidth = terminalWidth - wrapIndent.length - 1;
|
|
2667
|
+
const firstPassLines = wrapText(value, Math.max(firstLineWidth, 10));
|
|
2668
|
+
const firstLine = firstPassLines[0] || "";
|
|
2669
|
+
let wrappedValue;
|
|
2670
|
+
if (firstPassLines.length <= 1 || subsequentLineWidth <= firstLineWidth) {
|
|
2671
|
+
wrappedValue = firstPassLines;
|
|
2672
|
+
} else {
|
|
2673
|
+
const remainingText = firstPassLines.slice(1).map((l) => l.trim()).join(" ");
|
|
2674
|
+
const rewrapped = wrapText(remainingText, subsequentLineWidth);
|
|
2675
|
+
wrappedValue = [firstLine, ...rewrapped];
|
|
2676
|
+
}
|
|
2677
|
+
lines_2.push(`${ANSI_BOLD_START}${label}:${ANSI_BOLD_END} ${wrappedValue[0] || ""}`);
|
|
2678
|
+
for (let i_3 = 1; i_3 < wrappedValue.length; i_3++) {
|
|
2679
|
+
const line_1 = wrappedValue[i_3];
|
|
2680
|
+
if (!line_1.trim()) continue;
|
|
2681
|
+
lines_2.push(`${wrapIndent}${line_1}`);
|
|
2682
|
+
}
|
|
2683
|
+
});
|
|
2684
|
+
});
|
|
2685
|
+
return lines_2.join("\n");
|
|
2686
|
+
}
|
|
2687
|
+
if (useVerticalFormat) {
|
|
2688
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_ink_renderer15.Ansi, { children: renderVerticalFormat() });
|
|
2689
|
+
}
|
|
2690
|
+
const tableLines = [];
|
|
2691
|
+
tableLines.push(renderBorderLine("top"));
|
|
2692
|
+
tableLines.push(...renderRowLines(token.header, true));
|
|
2693
|
+
tableLines.push(renderBorderLine("middle"));
|
|
2694
|
+
token.rows.forEach((row_3, rowIndex_0) => {
|
|
2695
|
+
tableLines.push(...renderRowLines(row_3, false));
|
|
2696
|
+
if (rowIndex_0 < token.rows.length - 1) {
|
|
2697
|
+
tableLines.push(renderBorderLine("middle"));
|
|
2698
|
+
}
|
|
2699
|
+
});
|
|
2700
|
+
tableLines.push(renderBorderLine("bottom"));
|
|
2701
|
+
const maxLineWidth = Math.max(...tableLines.map((line_2) => (0, import_ink_renderer13.stringWidth)((0, import_strip_ansi2.default)(line_2))));
|
|
2702
|
+
if (maxLineWidth > terminalWidth - SAFETY_MARGIN) {
|
|
2703
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_ink_renderer15.Ansi, { children: renderVerticalFormat() });
|
|
2704
|
+
}
|
|
2705
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_ink_renderer15.Ansi, { children: tableLines.join("\n") });
|
|
2706
|
+
}
|
|
2707
|
+
|
|
2708
|
+
// src/Markdown.tsx
|
|
2709
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
2710
|
+
var TOKEN_CACHE_MAX = 500;
|
|
2711
|
+
var tokenCache = /* @__PURE__ */ new Map();
|
|
2712
|
+
var MD_SYNTAX_RE = /[#*`|[>\-_~]|\n\n|^\d+\. |\n\d+\. /;
|
|
2713
|
+
function hasMarkdownSyntax(s) {
|
|
2714
|
+
return MD_SYNTAX_RE.test(s.length > 500 ? s.slice(0, 500) : s);
|
|
2715
|
+
}
|
|
2716
|
+
function stripPromptXMLTags(content) {
|
|
2717
|
+
return content.replace(/<(commit_analysis|context|function_analysis|pr_analysis)>.*?<\/\1>\n?/gs, "").trim();
|
|
2718
|
+
}
|
|
2719
|
+
function cachedLexer(content) {
|
|
2720
|
+
if (!hasMarkdownSyntax(content)) {
|
|
2721
|
+
return [
|
|
2722
|
+
{
|
|
2723
|
+
type: "paragraph",
|
|
2724
|
+
raw: content,
|
|
2725
|
+
text: content,
|
|
2726
|
+
tokens: [{ type: "text", raw: content, text: content }]
|
|
2727
|
+
}
|
|
2728
|
+
];
|
|
2729
|
+
}
|
|
2730
|
+
const key = hashContent(content);
|
|
2731
|
+
const hit = tokenCache.get(key);
|
|
2732
|
+
if (hit) {
|
|
2733
|
+
tokenCache.delete(key);
|
|
2734
|
+
tokenCache.set(key, hit);
|
|
2735
|
+
return hit;
|
|
2736
|
+
}
|
|
2737
|
+
const tokens = import_marked2.marked.lexer(content);
|
|
2738
|
+
if (tokenCache.size >= TOKEN_CACHE_MAX) {
|
|
2739
|
+
const first = tokenCache.keys().next().value;
|
|
2740
|
+
if (first !== void 0) tokenCache.delete(first);
|
|
2741
|
+
}
|
|
2742
|
+
tokenCache.set(key, tokens);
|
|
2743
|
+
return tokens;
|
|
2744
|
+
}
|
|
2745
|
+
function Markdown(props) {
|
|
2746
|
+
const settings = {};
|
|
2747
|
+
if (settings.syntaxHighlightingDisabled) {
|
|
2748
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(MarkdownBody, { ...props, highlight: null });
|
|
2749
|
+
}
|
|
2750
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react12.Suspense, { fallback: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(MarkdownBody, { ...props, highlight: null }), children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(MarkdownWithHighlight, { ...props }) });
|
|
2751
|
+
}
|
|
2752
|
+
function MarkdownWithHighlight(props) {
|
|
2753
|
+
const highlight = (0, import_react12.use)(getCliHighlightPromise());
|
|
2754
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(MarkdownBody, { ...props, highlight });
|
|
2755
|
+
}
|
|
2756
|
+
function MarkdownBody({
|
|
2757
|
+
children,
|
|
2758
|
+
dimColor,
|
|
2759
|
+
highlight
|
|
2760
|
+
}) {
|
|
2761
|
+
const [theme] = useTheme();
|
|
2762
|
+
configureMarked();
|
|
2763
|
+
const elements = (0, import_react12.useMemo)(() => {
|
|
2764
|
+
const tokens = cachedLexer(stripPromptXMLTags(children));
|
|
2765
|
+
const elements2 = [];
|
|
2766
|
+
let nonTableContent = "";
|
|
2767
|
+
function flushNonTableContent() {
|
|
2768
|
+
if (nonTableContent) {
|
|
2769
|
+
elements2.push(
|
|
2770
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_ink_renderer16.Ansi, { dimColor, children: nonTableContent.trim() }, elements2.length)
|
|
2771
|
+
);
|
|
2772
|
+
nonTableContent = "";
|
|
2773
|
+
}
|
|
2774
|
+
}
|
|
2775
|
+
for (const token of tokens) {
|
|
2776
|
+
if (token.type === "table") {
|
|
2777
|
+
flushNonTableContent();
|
|
2778
|
+
elements2.push(
|
|
2779
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2780
|
+
MarkdownTable,
|
|
2781
|
+
{
|
|
2782
|
+
token,
|
|
2783
|
+
highlight
|
|
2784
|
+
},
|
|
2785
|
+
elements2.length
|
|
2786
|
+
)
|
|
2787
|
+
);
|
|
2788
|
+
} else {
|
|
2789
|
+
nonTableContent += formatToken(token, theme, 0, null, null, highlight);
|
|
2790
|
+
}
|
|
2791
|
+
}
|
|
2792
|
+
flushNonTableContent();
|
|
2793
|
+
return elements2;
|
|
2794
|
+
}, [children, dimColor, highlight, theme]);
|
|
2795
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_ink_renderer16.Box, { flexDirection: "column", gap: 1, children: elements });
|
|
2796
|
+
}
|
|
2797
|
+
function StreamingMarkdown({
|
|
2798
|
+
children
|
|
2799
|
+
}) {
|
|
2800
|
+
"use no memo";
|
|
2801
|
+
configureMarked();
|
|
2802
|
+
const stripped = stripPromptXMLTags(children);
|
|
2803
|
+
const stablePrefixRef = (0, import_react12.useRef)("");
|
|
2804
|
+
if (!stripped.startsWith(stablePrefixRef.current)) {
|
|
2805
|
+
stablePrefixRef.current = "";
|
|
2806
|
+
}
|
|
2807
|
+
const boundary = stablePrefixRef.current.length;
|
|
2808
|
+
const tokens = import_marked2.marked.lexer(stripped.substring(boundary));
|
|
2809
|
+
let lastContentIdx = tokens.length - 1;
|
|
2810
|
+
while (lastContentIdx >= 0 && tokens[lastContentIdx].type === "space") {
|
|
2811
|
+
lastContentIdx--;
|
|
2812
|
+
}
|
|
2813
|
+
let advance = 0;
|
|
2814
|
+
for (let i = 0; i < lastContentIdx; i++) {
|
|
2815
|
+
advance += tokens[i].raw.length;
|
|
2816
|
+
}
|
|
2817
|
+
if (advance > 0) {
|
|
2818
|
+
stablePrefixRef.current = stripped.substring(0, boundary + advance);
|
|
2819
|
+
}
|
|
2820
|
+
const stablePrefix = stablePrefixRef.current;
|
|
2821
|
+
const unstableSuffix = stripped.substring(stablePrefix.length);
|
|
2822
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_ink_renderer16.Box, { flexDirection: "column", gap: 1, children: [
|
|
2823
|
+
stablePrefix && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Markdown, { children: stablePrefix }),
|
|
2824
|
+
unstableSuffix && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Markdown, { children: unstableSuffix })
|
|
2825
|
+
] });
|
|
2826
|
+
}
|
|
2827
|
+
|
|
2828
|
+
// src/Select.tsx
|
|
2829
|
+
var import_react13 = require("react");
|
|
2830
|
+
var import_ink_renderer17 = require("@claude-code-kit/ink-renderer");
|
|
2831
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
2013
2832
|
function useListNavigation(opts) {
|
|
2014
2833
|
const { options, maxVisible, onCancel, onSelect, extraHandler } = opts;
|
|
2015
|
-
const [focusIndex, setFocusIndex] = (0,
|
|
2016
|
-
const focusRef = (0,
|
|
2834
|
+
const [focusIndex, setFocusIndex] = (0, import_react13.useState)(0);
|
|
2835
|
+
const focusRef = (0, import_react13.useRef)(focusIndex);
|
|
2017
2836
|
focusRef.current = focusIndex;
|
|
2018
2837
|
const total = options.length;
|
|
2019
2838
|
const max = maxVisible ?? total;
|
|
2020
|
-
const scrollOffset = (0,
|
|
2839
|
+
const scrollOffset = (0, import_react13.useMemo)(() => {
|
|
2021
2840
|
if (total <= max) return 0;
|
|
2022
2841
|
const half = Math.floor(max / 2);
|
|
2023
2842
|
if (focusIndex <= half) return 0;
|
|
2024
2843
|
if (focusIndex >= total - max + half) return total - max;
|
|
2025
2844
|
return focusIndex - half;
|
|
2026
2845
|
}, [focusIndex, total, max]);
|
|
2027
|
-
const visibleOptions = (0,
|
|
2846
|
+
const visibleOptions = (0, import_react13.useMemo)(
|
|
2028
2847
|
() => options.slice(scrollOffset, scrollOffset + max),
|
|
2029
2848
|
[options, scrollOffset, max]
|
|
2030
2849
|
);
|
|
2031
|
-
const moveFocus = (0,
|
|
2850
|
+
const moveFocus = (0, import_react13.useCallback)(
|
|
2032
2851
|
(dir) => {
|
|
2033
2852
|
setFocusIndex((prev) => {
|
|
2034
2853
|
let next = prev;
|
|
@@ -2041,7 +2860,7 @@ function useListNavigation(opts) {
|
|
|
2041
2860
|
},
|
|
2042
2861
|
[options, total]
|
|
2043
2862
|
);
|
|
2044
|
-
(0,
|
|
2863
|
+
(0, import_ink_renderer17.useInput)((input, key) => {
|
|
2045
2864
|
if (extraHandler?.(input, key, focusRef.current)) return;
|
|
2046
2865
|
if (key.upArrow || input === "k") {
|
|
2047
2866
|
moveFocus(-1);
|
|
@@ -2064,7 +2883,7 @@ function useListNavigation(opts) {
|
|
|
2064
2883
|
return { focusIndex, scrollOffset, visibleOptions, max, total };
|
|
2065
2884
|
}
|
|
2066
2885
|
function ScrollHint({ count, direction }) {
|
|
2067
|
-
return /* @__PURE__ */ (0,
|
|
2886
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_ink_renderer17.Text, { dimColor: true, children: [
|
|
2068
2887
|
" ",
|
|
2069
2888
|
direction === "up" ? "\u2191" : "\u2193",
|
|
2070
2889
|
" ",
|
|
@@ -2080,26 +2899,26 @@ function Select({
|
|
|
2080
2899
|
title,
|
|
2081
2900
|
maxVisible
|
|
2082
2901
|
}) {
|
|
2083
|
-
const handleSelect = (0,
|
|
2902
|
+
const handleSelect = (0, import_react13.useCallback)(
|
|
2084
2903
|
(index) => onChange(options[index].value),
|
|
2085
2904
|
[onChange, options]
|
|
2086
2905
|
);
|
|
2087
2906
|
const { focusIndex, scrollOffset, visibleOptions, max, total } = useListNavigation({ options, maxVisible, onCancel, onSelect: handleSelect });
|
|
2088
|
-
return /* @__PURE__ */ (0,
|
|
2089
|
-
title && /* @__PURE__ */ (0,
|
|
2090
|
-
scrollOffset > 0 && /* @__PURE__ */ (0,
|
|
2907
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_ink_renderer17.Box, { flexDirection: "column", children: [
|
|
2908
|
+
title && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_ink_renderer17.Box, { marginBottom: 1, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_ink_renderer17.Text, { bold: true, children: title }) }),
|
|
2909
|
+
scrollOffset > 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ScrollHint, { count: scrollOffset, direction: "up" }),
|
|
2091
2910
|
visibleOptions.map((opt, i) => {
|
|
2092
2911
|
const realIndex = scrollOffset + i;
|
|
2093
2912
|
const isFocused = realIndex === focusIndex;
|
|
2094
2913
|
const isSelected = opt.value === defaultValue;
|
|
2095
2914
|
const isDisabled = opt.disabled === true;
|
|
2096
|
-
return /* @__PURE__ */ (0,
|
|
2097
|
-
/* @__PURE__ */ (0,
|
|
2915
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_ink_renderer17.Box, { children: [
|
|
2916
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_ink_renderer17.Text, { color: isFocused ? "cyan" : void 0, children: [
|
|
2098
2917
|
isFocused ? "\u276F" : " ",
|
|
2099
2918
|
" "
|
|
2100
2919
|
] }),
|
|
2101
|
-
/* @__PURE__ */ (0,
|
|
2102
|
-
|
|
2920
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
2921
|
+
import_ink_renderer17.Text,
|
|
2103
2922
|
{
|
|
2104
2923
|
color: isDisabled ? "gray" : isFocused ? "cyan" : void 0,
|
|
2105
2924
|
bold: isFocused,
|
|
@@ -2111,15 +2930,15 @@ function Select({
|
|
|
2111
2930
|
]
|
|
2112
2931
|
}
|
|
2113
2932
|
),
|
|
2114
|
-
isSelected && /* @__PURE__ */ (0,
|
|
2115
|
-
opt.description && /* @__PURE__ */ (0,
|
|
2933
|
+
isSelected && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_ink_renderer17.Text, { color: "green", children: " \u2713" }),
|
|
2934
|
+
opt.description && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_ink_renderer17.Text, { dimColor: true, children: [
|
|
2116
2935
|
" ",
|
|
2117
2936
|
opt.description
|
|
2118
2937
|
] })
|
|
2119
2938
|
] }, realIndex);
|
|
2120
2939
|
}),
|
|
2121
|
-
scrollOffset + max < total && /* @__PURE__ */ (0,
|
|
2122
|
-
/* @__PURE__ */ (0,
|
|
2940
|
+
scrollOffset + max < total && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ScrollHint, { count: total - scrollOffset - max, direction: "down" }),
|
|
2941
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_ink_renderer17.Box, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_ink_renderer17.Text, { dimColor: true, children: "Enter to confirm \xB7 Esc to exit" }) })
|
|
2123
2942
|
] });
|
|
2124
2943
|
}
|
|
2125
2944
|
function MultiSelect({
|
|
@@ -2131,12 +2950,12 @@ function MultiSelect({
|
|
|
2131
2950
|
title,
|
|
2132
2951
|
maxVisible
|
|
2133
2952
|
}) {
|
|
2134
|
-
const [selected, setSelected] = (0,
|
|
2135
|
-
const handleConfirm = (0,
|
|
2953
|
+
const [selected, setSelected] = (0, import_react13.useState)(() => new Set(selectedValues));
|
|
2954
|
+
const handleConfirm = (0, import_react13.useCallback)(
|
|
2136
2955
|
() => onConfirm(Array.from(selected)),
|
|
2137
2956
|
[onConfirm, selected]
|
|
2138
2957
|
);
|
|
2139
|
-
const handleSpace = (0,
|
|
2958
|
+
const handleSpace = (0, import_react13.useCallback)(
|
|
2140
2959
|
(input, _key, focusIndex2) => {
|
|
2141
2960
|
if (input !== " ") return false;
|
|
2142
2961
|
const opt = options[focusIndex2];
|
|
@@ -2159,21 +2978,21 @@ function MultiSelect({
|
|
|
2159
2978
|
onSelect: handleConfirm,
|
|
2160
2979
|
extraHandler: handleSpace
|
|
2161
2980
|
});
|
|
2162
|
-
return /* @__PURE__ */ (0,
|
|
2163
|
-
title && /* @__PURE__ */ (0,
|
|
2164
|
-
scrollOffset > 0 && /* @__PURE__ */ (0,
|
|
2981
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_ink_renderer17.Box, { flexDirection: "column", children: [
|
|
2982
|
+
title && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_ink_renderer17.Box, { marginBottom: 1, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_ink_renderer17.Text, { bold: true, children: title }) }),
|
|
2983
|
+
scrollOffset > 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ScrollHint, { count: scrollOffset, direction: "up" }),
|
|
2165
2984
|
visibleOptions.map((opt, i) => {
|
|
2166
2985
|
const realIndex = scrollOffset + i;
|
|
2167
2986
|
const isFocused = realIndex === focusIndex;
|
|
2168
2987
|
const isChecked = selected.has(opt.value);
|
|
2169
2988
|
const isDisabled = opt.disabled === true;
|
|
2170
|
-
return /* @__PURE__ */ (0,
|
|
2171
|
-
/* @__PURE__ */ (0,
|
|
2989
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_ink_renderer17.Box, { children: [
|
|
2990
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_ink_renderer17.Text, { color: isFocused ? "cyan" : void 0, children: [
|
|
2172
2991
|
isFocused ? "\u276F" : " ",
|
|
2173
2992
|
" "
|
|
2174
2993
|
] }),
|
|
2175
|
-
/* @__PURE__ */ (0,
|
|
2176
|
-
|
|
2994
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
2995
|
+
import_ink_renderer17.Text,
|
|
2177
2996
|
{
|
|
2178
2997
|
color: isDisabled ? "gray" : isFocused ? "cyan" : void 0,
|
|
2179
2998
|
bold: isFocused,
|
|
@@ -2187,20 +3006,20 @@ function MultiSelect({
|
|
|
2187
3006
|
]
|
|
2188
3007
|
}
|
|
2189
3008
|
),
|
|
2190
|
-
opt.description && /* @__PURE__ */ (0,
|
|
3009
|
+
opt.description && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_ink_renderer17.Text, { dimColor: true, children: [
|
|
2191
3010
|
" ",
|
|
2192
3011
|
opt.description
|
|
2193
3012
|
] })
|
|
2194
3013
|
] }, realIndex);
|
|
2195
3014
|
}),
|
|
2196
|
-
scrollOffset + max < total && /* @__PURE__ */ (0,
|
|
2197
|
-
/* @__PURE__ */ (0,
|
|
3015
|
+
scrollOffset + max < total && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ScrollHint, { count: total - scrollOffset - max, direction: "down" }),
|
|
3016
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_ink_renderer17.Box, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_ink_renderer17.Text, { dimColor: true, children: "Space to toggle \xB7 Enter to confirm \xB7 Esc to exit" }) })
|
|
2198
3017
|
] });
|
|
2199
3018
|
}
|
|
2200
3019
|
|
|
2201
3020
|
// src/MessageList.tsx
|
|
2202
|
-
var
|
|
2203
|
-
var
|
|
3021
|
+
var import_ink_renderer18 = require("@claude-code-kit/ink-renderer");
|
|
3022
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
2204
3023
|
var ROLE_CONFIG = {
|
|
2205
3024
|
user: { icon: "\u276F", label: "You", color: "cyan" },
|
|
2206
3025
|
assistant: { icon: "\u25CF", label: "Claude", color: "#DA7756" },
|
|
@@ -2215,15 +3034,15 @@ function MessageItem({
|
|
|
2215
3034
|
}
|
|
2216
3035
|
const config = ROLE_CONFIG[message.role];
|
|
2217
3036
|
const isSystem = message.role === "system";
|
|
2218
|
-
return /* @__PURE__ */ (0,
|
|
2219
|
-
/* @__PURE__ */ (0,
|
|
2220
|
-
/* @__PURE__ */ (0,
|
|
2221
|
-
/* @__PURE__ */ (0,
|
|
3037
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_ink_renderer18.Box, { flexDirection: "column", children: [
|
|
3038
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_ink_renderer18.Box, { children: [
|
|
3039
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_ink_renderer18.Text, { color: config.color, dimColor: isSystem, children: config.icon }),
|
|
3040
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_ink_renderer18.Text, { color: config.color, dimColor: isSystem, bold: !isSystem, children: [
|
|
2222
3041
|
" ",
|
|
2223
3042
|
config.label
|
|
2224
3043
|
] })
|
|
2225
3044
|
] }),
|
|
2226
|
-
message.content.split("\n").map((line, i) => /* @__PURE__ */ (0,
|
|
3045
|
+
message.content.split("\n").map((line, i) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_ink_renderer18.Box, { marginLeft: 2, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_ink_renderer18.Text, { dimColor: isSystem, children: line }) }, i))
|
|
2227
3046
|
] });
|
|
2228
3047
|
}
|
|
2229
3048
|
function MessageList({
|
|
@@ -2231,39 +3050,39 @@ function MessageList({
|
|
|
2231
3050
|
streamingContent,
|
|
2232
3051
|
renderMessage
|
|
2233
3052
|
}) {
|
|
2234
|
-
return /* @__PURE__ */ (0,
|
|
2235
|
-
messages.map((message, i) => /* @__PURE__ */ (0,
|
|
2236
|
-
streamingContent != null && streamingContent.length > 0 && /* @__PURE__ */ (0,
|
|
2237
|
-
/* @__PURE__ */ (0,
|
|
2238
|
-
/* @__PURE__ */ (0,
|
|
2239
|
-
/* @__PURE__ */ (0,
|
|
3053
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_ink_renderer18.Box, { flexDirection: "column", children: [
|
|
3054
|
+
messages.map((message, i) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_ink_renderer18.Box, { flexDirection: "column", marginTop: i > 0 ? 1 : 0, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(MessageItem, { message, renderMessage }) }, message.id)),
|
|
3055
|
+
streamingContent != null && streamingContent.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_ink_renderer18.Box, { flexDirection: "column", marginTop: messages.length > 0 ? 1 : 0, children: [
|
|
3056
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_ink_renderer18.Box, { children: [
|
|
3057
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_ink_renderer18.Text, { color: "#DA7756", children: "\u25CF" }),
|
|
3058
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_ink_renderer18.Text, { color: "#DA7756", bold: true, children: [
|
|
2240
3059
|
" ",
|
|
2241
3060
|
"Claude"
|
|
2242
3061
|
] })
|
|
2243
3062
|
] }),
|
|
2244
|
-
streamingContent.split("\n").map((line, i) => /* @__PURE__ */ (0,
|
|
3063
|
+
streamingContent.split("\n").map((line, i) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_ink_renderer18.Box, { marginLeft: 2, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_ink_renderer18.Text, { children: [
|
|
2245
3064
|
line,
|
|
2246
|
-
i === streamingContent.split("\n").length - 1 && /* @__PURE__ */ (0,
|
|
3065
|
+
i === streamingContent.split("\n").length - 1 && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_ink_renderer18.Text, { color: "#DA7756", children: "\u2588" })
|
|
2247
3066
|
] }) }, i))
|
|
2248
3067
|
] })
|
|
2249
3068
|
] });
|
|
2250
3069
|
}
|
|
2251
3070
|
|
|
2252
3071
|
// src/StreamingText.tsx
|
|
2253
|
-
var
|
|
2254
|
-
var
|
|
2255
|
-
var
|
|
3072
|
+
var import_react14 = require("react");
|
|
3073
|
+
var import_ink_renderer19 = require("@claude-code-kit/ink-renderer");
|
|
3074
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
2256
3075
|
function StreamingText({
|
|
2257
3076
|
text,
|
|
2258
3077
|
speed = 3,
|
|
2259
3078
|
interval = 20,
|
|
2260
3079
|
onComplete,
|
|
2261
|
-
color
|
|
3080
|
+
color: color2
|
|
2262
3081
|
}) {
|
|
2263
|
-
const [revealed, setRevealed] = (0,
|
|
2264
|
-
const onCompleteRef = (0,
|
|
3082
|
+
const [revealed, setRevealed] = (0, import_react14.useState)(0);
|
|
3083
|
+
const onCompleteRef = (0, import_react14.useRef)(onComplete);
|
|
2265
3084
|
onCompleteRef.current = onComplete;
|
|
2266
|
-
(0,
|
|
3085
|
+
(0, import_react14.useEffect)(() => {
|
|
2267
3086
|
if (revealed >= text.length) return;
|
|
2268
3087
|
const id = setInterval(() => {
|
|
2269
3088
|
setRevealed((prev) => {
|
|
@@ -2276,13 +3095,13 @@ function StreamingText({
|
|
|
2276
3095
|
}, interval);
|
|
2277
3096
|
return () => clearInterval(id);
|
|
2278
3097
|
}, [text.length, speed, interval, revealed >= text.length]);
|
|
2279
|
-
return /* @__PURE__ */ (0,
|
|
3098
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_ink_renderer19.Text, { color: color2, children: text.slice(0, revealed) });
|
|
2280
3099
|
}
|
|
2281
3100
|
|
|
2282
3101
|
// src/REPL.tsx
|
|
2283
|
-
var
|
|
2284
|
-
var
|
|
2285
|
-
var
|
|
3102
|
+
var import_react15 = require("react");
|
|
3103
|
+
var import_ink_renderer20 = require("@claude-code-kit/ink-renderer");
|
|
3104
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
2286
3105
|
function REPL({
|
|
2287
3106
|
onSubmit,
|
|
2288
3107
|
onExit,
|
|
@@ -2298,16 +3117,16 @@ function REPL({
|
|
|
2298
3117
|
renderMessage,
|
|
2299
3118
|
spinner
|
|
2300
3119
|
}) {
|
|
2301
|
-
const { exit } = (0,
|
|
2302
|
-
const [inputValue, setInputValue] = (0,
|
|
2303
|
-
const [internalHistory, setInternalHistory] = (0,
|
|
2304
|
-
const submittingRef = (0,
|
|
3120
|
+
const { exit } = (0, import_ink_renderer20.useApp)();
|
|
3121
|
+
const [inputValue, setInputValue] = (0, import_react15.useState)("");
|
|
3122
|
+
const [internalHistory, setInternalHistory] = (0, import_react15.useState)([]);
|
|
3123
|
+
const submittingRef = (0, import_react15.useRef)(false);
|
|
2305
3124
|
const history = externalHistory ?? internalHistory;
|
|
2306
3125
|
const promptCommands = commands.map((c) => ({
|
|
2307
3126
|
name: c.name,
|
|
2308
3127
|
description: c.description
|
|
2309
3128
|
}));
|
|
2310
|
-
const handleSubmit = (0,
|
|
3129
|
+
const handleSubmit = (0, import_react15.useCallback)(
|
|
2311
3130
|
(value) => {
|
|
2312
3131
|
if (submittingRef.current) return;
|
|
2313
3132
|
const trimmed = value.trim();
|
|
@@ -2339,7 +3158,7 @@ function REPL({
|
|
|
2339
3158
|
},
|
|
2340
3159
|
[commands, onSubmit, externalHistory]
|
|
2341
3160
|
);
|
|
2342
|
-
(0,
|
|
3161
|
+
(0, import_ink_renderer20.useInput)(
|
|
2343
3162
|
(_input, key) => {
|
|
2344
3163
|
if (key.ctrl && _input === "c" && isLoading) {
|
|
2345
3164
|
return;
|
|
@@ -2355,9 +3174,9 @@ function REPL({
|
|
|
2355
3174
|
{ isActive: true }
|
|
2356
3175
|
);
|
|
2357
3176
|
const resolvedSegments = statusSegments ?? buildDefaultSegments(model);
|
|
2358
|
-
return /* @__PURE__ */ (0,
|
|
2359
|
-
/* @__PURE__ */ (0,
|
|
2360
|
-
/* @__PURE__ */ (0,
|
|
3177
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_ink_renderer20.Box, { flexDirection: "column", flexGrow: 1, children: [
|
|
3178
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_ink_renderer20.Box, { flexDirection: "column", flexGrow: 1, children: [
|
|
3179
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2361
3180
|
MessageList,
|
|
2362
3181
|
{
|
|
2363
3182
|
messages,
|
|
@@ -2365,10 +3184,10 @@ function REPL({
|
|
|
2365
3184
|
renderMessage
|
|
2366
3185
|
}
|
|
2367
3186
|
),
|
|
2368
|
-
isLoading && !streamingContent && /* @__PURE__ */ (0,
|
|
3187
|
+
isLoading && !streamingContent && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_ink_renderer20.Box, { marginTop: messages.length > 0 ? 1 : 0, children: spinner ?? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Spinner, {}) })
|
|
2369
3188
|
] }),
|
|
2370
|
-
/* @__PURE__ */ (0,
|
|
2371
|
-
/* @__PURE__ */ (0,
|
|
3189
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Divider, {}),
|
|
3190
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2372
3191
|
PromptInput,
|
|
2373
3192
|
{
|
|
2374
3193
|
value: inputValue,
|
|
@@ -2381,39 +3200,713 @@ function REPL({
|
|
|
2381
3200
|
history
|
|
2382
3201
|
}
|
|
2383
3202
|
),
|
|
2384
|
-
/* @__PURE__ */ (0,
|
|
2385
|
-
resolvedSegments.length > 0 && /* @__PURE__ */ (0,
|
|
3203
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Divider, {}),
|
|
3204
|
+
resolvedSegments.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(StatusLine, { segments: resolvedSegments })
|
|
2386
3205
|
] });
|
|
2387
3206
|
}
|
|
2388
3207
|
function buildDefaultSegments(model) {
|
|
2389
3208
|
if (!model) return [];
|
|
2390
3209
|
return [{ content: model, color: "green" }];
|
|
2391
3210
|
}
|
|
3211
|
+
|
|
3212
|
+
// src/design-system/ThemedBox.tsx
|
|
3213
|
+
var import_ink_renderer21 = require("@claude-code-kit/ink-renderer");
|
|
3214
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
3215
|
+
function resolveColor(color2, theme) {
|
|
3216
|
+
if (!color2) return void 0;
|
|
3217
|
+
if (color2.startsWith("rgb(") || color2.startsWith("#") || color2.startsWith("ansi256(") || color2.startsWith("ansi:")) {
|
|
3218
|
+
return color2;
|
|
3219
|
+
}
|
|
3220
|
+
return theme[color2];
|
|
3221
|
+
}
|
|
3222
|
+
function ThemedBox({
|
|
3223
|
+
borderColor,
|
|
3224
|
+
borderTopColor,
|
|
3225
|
+
borderBottomColor,
|
|
3226
|
+
borderLeftColor,
|
|
3227
|
+
borderRightColor,
|
|
3228
|
+
backgroundColor,
|
|
3229
|
+
children,
|
|
3230
|
+
ref,
|
|
3231
|
+
...rest
|
|
3232
|
+
}) {
|
|
3233
|
+
const [themeName] = useTheme();
|
|
3234
|
+
const theme = getTheme(themeName);
|
|
3235
|
+
const resolvedBorderColor = resolveColor(borderColor, theme);
|
|
3236
|
+
const resolvedBorderTopColor = resolveColor(borderTopColor, theme);
|
|
3237
|
+
const resolvedBorderBottomColor = resolveColor(borderBottomColor, theme);
|
|
3238
|
+
const resolvedBorderLeftColor = resolveColor(borderLeftColor, theme);
|
|
3239
|
+
const resolvedBorderRightColor = resolveColor(borderRightColor, theme);
|
|
3240
|
+
const resolvedBackgroundColor = resolveColor(backgroundColor, theme);
|
|
3241
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3242
|
+
import_ink_renderer21.Box,
|
|
3243
|
+
{
|
|
3244
|
+
ref,
|
|
3245
|
+
borderColor: resolvedBorderColor,
|
|
3246
|
+
borderTopColor: resolvedBorderTopColor,
|
|
3247
|
+
borderBottomColor: resolvedBorderBottomColor,
|
|
3248
|
+
borderLeftColor: resolvedBorderLeftColor,
|
|
3249
|
+
borderRightColor: resolvedBorderRightColor,
|
|
3250
|
+
backgroundColor: resolvedBackgroundColor,
|
|
3251
|
+
...rest,
|
|
3252
|
+
children
|
|
3253
|
+
}
|
|
3254
|
+
);
|
|
3255
|
+
}
|
|
3256
|
+
var ThemedBox_default = ThemedBox;
|
|
3257
|
+
|
|
3258
|
+
// src/design-system/ThemedText.tsx
|
|
3259
|
+
var import_react16 = __toESM(require("react"));
|
|
3260
|
+
var import_ink_renderer22 = require("@claude-code-kit/ink-renderer");
|
|
3261
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
3262
|
+
var TextHoverColorContext = import_react16.default.createContext(void 0);
|
|
3263
|
+
function resolveColor2(color2, theme) {
|
|
3264
|
+
if (!color2) return void 0;
|
|
3265
|
+
if (color2.startsWith("rgb(") || color2.startsWith("#") || color2.startsWith("ansi256(") || color2.startsWith("ansi:")) {
|
|
3266
|
+
return color2;
|
|
3267
|
+
}
|
|
3268
|
+
return theme[color2];
|
|
3269
|
+
}
|
|
3270
|
+
function ThemedText({
|
|
3271
|
+
color: color2,
|
|
3272
|
+
backgroundColor,
|
|
3273
|
+
dimColor = false,
|
|
3274
|
+
bold = false,
|
|
3275
|
+
italic = false,
|
|
3276
|
+
underline = false,
|
|
3277
|
+
strikethrough = false,
|
|
3278
|
+
inverse = false,
|
|
3279
|
+
wrap = "wrap",
|
|
3280
|
+
children
|
|
3281
|
+
}) {
|
|
3282
|
+
const [themeName] = useTheme();
|
|
3283
|
+
const theme = getTheme(themeName);
|
|
3284
|
+
const hoverColor = (0, import_react16.useContext)(TextHoverColorContext);
|
|
3285
|
+
const resolvedColor = !color2 && hoverColor ? resolveColor2(hoverColor, theme) : dimColor ? theme.inactive : resolveColor2(color2, theme);
|
|
3286
|
+
const resolvedBackgroundColor = backgroundColor ? theme[backgroundColor] : void 0;
|
|
3287
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3288
|
+
import_ink_renderer22.Text,
|
|
3289
|
+
{
|
|
3290
|
+
color: resolvedColor,
|
|
3291
|
+
backgroundColor: resolvedBackgroundColor,
|
|
3292
|
+
bold,
|
|
3293
|
+
italic,
|
|
3294
|
+
underline,
|
|
3295
|
+
strikethrough,
|
|
3296
|
+
inverse,
|
|
3297
|
+
wrap,
|
|
3298
|
+
children
|
|
3299
|
+
}
|
|
3300
|
+
);
|
|
3301
|
+
}
|
|
3302
|
+
|
|
3303
|
+
// src/design-system/Dialog.tsx
|
|
3304
|
+
var import_react18 = require("react");
|
|
3305
|
+
var import_ink_renderer26 = require("@claude-code-kit/ink-renderer");
|
|
3306
|
+
|
|
3307
|
+
// src/design-system/Byline.tsx
|
|
3308
|
+
var import_react17 = __toESM(require("react"));
|
|
3309
|
+
var import_ink_renderer23 = require("@claude-code-kit/ink-renderer");
|
|
3310
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
3311
|
+
function Byline({ children }) {
|
|
3312
|
+
const validChildren = import_react17.Children.toArray(children);
|
|
3313
|
+
if (validChildren.length === 0) {
|
|
3314
|
+
return null;
|
|
3315
|
+
}
|
|
3316
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_jsx_runtime18.Fragment, { children: validChildren.map((child, index) => /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
3317
|
+
import_react17.default.Fragment,
|
|
3318
|
+
{
|
|
3319
|
+
children: [
|
|
3320
|
+
index > 0 && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_ink_renderer23.Text, { dimColor: true, children: " \xB7 " }),
|
|
3321
|
+
child
|
|
3322
|
+
]
|
|
3323
|
+
},
|
|
3324
|
+
(0, import_react17.isValidElement)(child) ? child.key ?? index : index
|
|
3325
|
+
)) });
|
|
3326
|
+
}
|
|
3327
|
+
|
|
3328
|
+
// src/design-system/KeyboardShortcutHint.tsx
|
|
3329
|
+
var import_ink_renderer24 = require("@claude-code-kit/ink-renderer");
|
|
3330
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
3331
|
+
function KeyboardShortcutHint({
|
|
3332
|
+
shortcut,
|
|
3333
|
+
action,
|
|
3334
|
+
parens = false,
|
|
3335
|
+
bold = false
|
|
3336
|
+
}) {
|
|
3337
|
+
const shortcutText = bold ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_ink_renderer24.Text, { bold: true, children: shortcut }) : shortcut;
|
|
3338
|
+
if (parens) {
|
|
3339
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_ink_renderer24.Text, { children: [
|
|
3340
|
+
"(",
|
|
3341
|
+
shortcutText,
|
|
3342
|
+
" to ",
|
|
3343
|
+
action,
|
|
3344
|
+
")"
|
|
3345
|
+
] });
|
|
3346
|
+
}
|
|
3347
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_ink_renderer24.Text, { children: [
|
|
3348
|
+
shortcutText,
|
|
3349
|
+
" to ",
|
|
3350
|
+
action
|
|
3351
|
+
] });
|
|
3352
|
+
}
|
|
3353
|
+
|
|
3354
|
+
// src/design-system/Pane.tsx
|
|
3355
|
+
var import_ink_renderer25 = require("@claude-code-kit/ink-renderer");
|
|
3356
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
3357
|
+
function Pane({ children, color: color2 }) {
|
|
3358
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_ink_renderer25.Box, { flexDirection: "column", paddingTop: 1, children: [
|
|
3359
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Divider, { color: color2 }),
|
|
3360
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_ink_renderer25.Box, { flexDirection: "column", paddingX: 2, children })
|
|
3361
|
+
] });
|
|
3362
|
+
}
|
|
3363
|
+
|
|
3364
|
+
// src/design-system/Dialog.tsx
|
|
3365
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
3366
|
+
function Dialog({
|
|
3367
|
+
title,
|
|
3368
|
+
subtitle,
|
|
3369
|
+
children,
|
|
3370
|
+
onCancel,
|
|
3371
|
+
color: color2 = "permission",
|
|
3372
|
+
hideInputGuide,
|
|
3373
|
+
hideBorder
|
|
3374
|
+
}) {
|
|
3375
|
+
(0, import_ink_renderer26.useInput)(
|
|
3376
|
+
(0, import_react18.useCallback)(
|
|
3377
|
+
(_input, key) => {
|
|
3378
|
+
if (key.escape) {
|
|
3379
|
+
onCancel();
|
|
3380
|
+
}
|
|
3381
|
+
},
|
|
3382
|
+
[onCancel]
|
|
3383
|
+
)
|
|
3384
|
+
);
|
|
3385
|
+
const defaultInputGuide = /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(Byline, { children: [
|
|
3386
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(KeyboardShortcutHint, { shortcut: "Enter", action: "confirm" }),
|
|
3387
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(KeyboardShortcutHint, { shortcut: "Esc", action: "cancel" })
|
|
3388
|
+
] });
|
|
3389
|
+
const content = /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
|
|
3390
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_ink_renderer26.Box, { flexDirection: "column", gap: 1, children: [
|
|
3391
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_ink_renderer26.Box, { flexDirection: "column", children: [
|
|
3392
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_ink_renderer26.Text, { bold: true, color: color2, children: title }),
|
|
3393
|
+
subtitle && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_ink_renderer26.Text, { dimColor: true, children: subtitle })
|
|
3394
|
+
] }),
|
|
3395
|
+
children
|
|
3396
|
+
] }),
|
|
3397
|
+
!hideInputGuide && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_ink_renderer26.Box, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_ink_renderer26.Text, { dimColor: true, italic: true, children: defaultInputGuide }) })
|
|
3398
|
+
] });
|
|
3399
|
+
if (hideBorder) {
|
|
3400
|
+
return content;
|
|
3401
|
+
}
|
|
3402
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Pane, { color: color2, children: content });
|
|
3403
|
+
}
|
|
3404
|
+
|
|
3405
|
+
// src/design-system/FuzzyPicker.tsx
|
|
3406
|
+
var import_react19 = require("react");
|
|
3407
|
+
var import_ink_renderer29 = require("@claude-code-kit/ink-renderer");
|
|
3408
|
+
|
|
3409
|
+
// src/design-system/ListItem.tsx
|
|
3410
|
+
var import_figures2 = __toESM(require("figures"));
|
|
3411
|
+
var import_ink_renderer27 = require("@claude-code-kit/ink-renderer");
|
|
3412
|
+
var import_ink_renderer28 = require("@claude-code-kit/ink-renderer");
|
|
3413
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
3414
|
+
function ListItem({
|
|
3415
|
+
isFocused,
|
|
3416
|
+
isSelected = false,
|
|
3417
|
+
children,
|
|
3418
|
+
description,
|
|
3419
|
+
showScrollDown,
|
|
3420
|
+
showScrollUp,
|
|
3421
|
+
styled = true,
|
|
3422
|
+
disabled = false,
|
|
3423
|
+
declareCursor
|
|
3424
|
+
}) {
|
|
3425
|
+
function renderIndicator() {
|
|
3426
|
+
if (disabled) {
|
|
3427
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_ink_renderer28.Text, { children: " " });
|
|
3428
|
+
}
|
|
3429
|
+
if (isFocused) {
|
|
3430
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_ink_renderer28.Text, { color: "suggestion", children: import_figures2.default.pointer });
|
|
3431
|
+
}
|
|
3432
|
+
if (showScrollDown) {
|
|
3433
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_ink_renderer28.Text, { dimColor: true, children: import_figures2.default.arrowDown });
|
|
3434
|
+
}
|
|
3435
|
+
if (showScrollUp) {
|
|
3436
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_ink_renderer28.Text, { dimColor: true, children: import_figures2.default.arrowUp });
|
|
3437
|
+
}
|
|
3438
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_ink_renderer28.Text, { children: " " });
|
|
3439
|
+
}
|
|
3440
|
+
function getTextColor() {
|
|
3441
|
+
if (disabled) {
|
|
3442
|
+
return "inactive";
|
|
3443
|
+
}
|
|
3444
|
+
if (!styled) {
|
|
3445
|
+
return void 0;
|
|
3446
|
+
}
|
|
3447
|
+
if (isSelected) {
|
|
3448
|
+
return "success";
|
|
3449
|
+
}
|
|
3450
|
+
if (isFocused) {
|
|
3451
|
+
return "suggestion";
|
|
3452
|
+
}
|
|
3453
|
+
return void 0;
|
|
3454
|
+
}
|
|
3455
|
+
const textColor = getTextColor();
|
|
3456
|
+
const cursorRef = (0, import_ink_renderer27.useDeclaredCursor)({
|
|
3457
|
+
line: 0,
|
|
3458
|
+
column: 0,
|
|
3459
|
+
active: isFocused && !disabled && declareCursor !== false
|
|
3460
|
+
});
|
|
3461
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_ink_renderer28.Box, { ref: cursorRef, flexDirection: "column", children: [
|
|
3462
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_ink_renderer28.Box, { flexDirection: "row", gap: 1, children: [
|
|
3463
|
+
renderIndicator(),
|
|
3464
|
+
styled ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_ink_renderer28.Text, { color: textColor, dimColor: disabled, children }) : children,
|
|
3465
|
+
isSelected && !disabled && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_ink_renderer28.Text, { color: "success", children: import_figures2.default.tick })
|
|
3466
|
+
] }),
|
|
3467
|
+
description && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_ink_renderer28.Box, { paddingLeft: 2, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_ink_renderer28.Text, { color: "inactive", children: description }) })
|
|
3468
|
+
] });
|
|
3469
|
+
}
|
|
3470
|
+
|
|
3471
|
+
// src/design-system/FuzzyPicker.tsx
|
|
3472
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
3473
|
+
var DEFAULT_VISIBLE = 8;
|
|
3474
|
+
var CHROME_ROWS = 10;
|
|
3475
|
+
var MIN_VISIBLE = 2;
|
|
3476
|
+
function FuzzyPicker({
|
|
3477
|
+
title,
|
|
3478
|
+
placeholder = "Type to search...",
|
|
3479
|
+
initialQuery,
|
|
3480
|
+
items,
|
|
3481
|
+
getKey,
|
|
3482
|
+
renderItem,
|
|
3483
|
+
renderPreview,
|
|
3484
|
+
previewPosition = "bottom",
|
|
3485
|
+
visibleCount: requestedVisible = DEFAULT_VISIBLE,
|
|
3486
|
+
direction = "down",
|
|
3487
|
+
onQueryChange,
|
|
3488
|
+
onSelect,
|
|
3489
|
+
onTab,
|
|
3490
|
+
onShiftTab,
|
|
3491
|
+
onFocus,
|
|
3492
|
+
onCancel,
|
|
3493
|
+
emptyMessage = "No results",
|
|
3494
|
+
matchLabel,
|
|
3495
|
+
selectAction = "select",
|
|
3496
|
+
extraHints
|
|
3497
|
+
}) {
|
|
3498
|
+
const terminalSize = (0, import_react19.useContext)(import_ink_renderer29.TerminalSizeContext);
|
|
3499
|
+
const rows = terminalSize?.rows ?? 24;
|
|
3500
|
+
const columns = terminalSize?.columns ?? 80;
|
|
3501
|
+
const [focusedIndex, setFocusedIndex] = (0, import_react19.useState)(0);
|
|
3502
|
+
const [query, setQuery] = (0, import_react19.useState)(initialQuery ?? "");
|
|
3503
|
+
const visibleCount = Math.max(
|
|
3504
|
+
MIN_VISIBLE,
|
|
3505
|
+
Math.min(requestedVisible, rows - CHROME_ROWS - (matchLabel ? 1 : 0))
|
|
3506
|
+
);
|
|
3507
|
+
const compact = columns < 120;
|
|
3508
|
+
const step = (0, import_react19.useCallback)(
|
|
3509
|
+
(delta) => {
|
|
3510
|
+
setFocusedIndex((i) => (0, import_ink_renderer29.clamp)(i + delta, 0, items.length - 1));
|
|
3511
|
+
},
|
|
3512
|
+
[items.length]
|
|
3513
|
+
);
|
|
3514
|
+
(0, import_ink_renderer29.useInput)(
|
|
3515
|
+
(0, import_react19.useCallback)(
|
|
3516
|
+
(input, key) => {
|
|
3517
|
+
if (key.escape) {
|
|
3518
|
+
onCancel();
|
|
3519
|
+
return;
|
|
3520
|
+
}
|
|
3521
|
+
if (key.upArrow || key.ctrl && input === "p") {
|
|
3522
|
+
step(direction === "up" ? 1 : -1);
|
|
3523
|
+
return;
|
|
3524
|
+
}
|
|
3525
|
+
if (key.downArrow || key.ctrl && input === "n") {
|
|
3526
|
+
step(direction === "up" ? -1 : 1);
|
|
3527
|
+
return;
|
|
3528
|
+
}
|
|
3529
|
+
if (key.return) {
|
|
3530
|
+
const selected = items[focusedIndex];
|
|
3531
|
+
if (selected) onSelect(selected);
|
|
3532
|
+
return;
|
|
3533
|
+
}
|
|
3534
|
+
if (key.tab) {
|
|
3535
|
+
const selected = items[focusedIndex];
|
|
3536
|
+
if (!selected) return;
|
|
3537
|
+
const tabAction = key.shift ? onShiftTab ?? onTab : onTab;
|
|
3538
|
+
if (tabAction) {
|
|
3539
|
+
tabAction.handler(selected);
|
|
3540
|
+
} else {
|
|
3541
|
+
onSelect(selected);
|
|
3542
|
+
}
|
|
3543
|
+
return;
|
|
3544
|
+
}
|
|
3545
|
+
if (key.backspace) {
|
|
3546
|
+
setQuery((q) => q.slice(0, -1));
|
|
3547
|
+
return;
|
|
3548
|
+
}
|
|
3549
|
+
if (input && !key.ctrl) {
|
|
3550
|
+
setQuery((q) => q + input);
|
|
3551
|
+
}
|
|
3552
|
+
},
|
|
3553
|
+
[onCancel, step, direction, items, focusedIndex, onSelect, onShiftTab, onTab]
|
|
3554
|
+
)
|
|
3555
|
+
);
|
|
3556
|
+
(0, import_react19.useEffect)(() => {
|
|
3557
|
+
onQueryChange(query);
|
|
3558
|
+
setFocusedIndex(0);
|
|
3559
|
+
}, [query]);
|
|
3560
|
+
(0, import_react19.useEffect)(() => {
|
|
3561
|
+
setFocusedIndex((i) => (0, import_ink_renderer29.clamp)(i, 0, items.length - 1));
|
|
3562
|
+
}, [items.length]);
|
|
3563
|
+
const focused = items[focusedIndex];
|
|
3564
|
+
(0, import_react19.useEffect)(() => {
|
|
3565
|
+
onFocus?.(focused);
|
|
3566
|
+
}, [focused]);
|
|
3567
|
+
const windowStart = (0, import_ink_renderer29.clamp)(
|
|
3568
|
+
focusedIndex - visibleCount + 1,
|
|
3569
|
+
0,
|
|
3570
|
+
items.length - visibleCount
|
|
3571
|
+
);
|
|
3572
|
+
const visible = items.slice(windowStart, windowStart + visibleCount);
|
|
3573
|
+
const emptyText = typeof emptyMessage === "function" ? emptyMessage(query) : emptyMessage;
|
|
3574
|
+
const searchInput = /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_ink_renderer29.Box, { borderStyle: "round", paddingX: 1, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_ink_renderer29.Text, { dimColor: !query, children: query || placeholder }) });
|
|
3575
|
+
const listBlock = /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
3576
|
+
List,
|
|
3577
|
+
{
|
|
3578
|
+
visible,
|
|
3579
|
+
windowStart,
|
|
3580
|
+
visibleCount,
|
|
3581
|
+
total: items.length,
|
|
3582
|
+
focusedIndex,
|
|
3583
|
+
direction,
|
|
3584
|
+
getKey,
|
|
3585
|
+
renderItem,
|
|
3586
|
+
emptyText
|
|
3587
|
+
}
|
|
3588
|
+
);
|
|
3589
|
+
const preview = renderPreview && focused ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_ink_renderer29.Box, { flexDirection: "column", flexGrow: 1, children: renderPreview(focused) }) : null;
|
|
3590
|
+
const listGroup = renderPreview && previewPosition === "right" ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
3591
|
+
import_ink_renderer29.Box,
|
|
3592
|
+
{
|
|
3593
|
+
flexDirection: "row",
|
|
3594
|
+
gap: 2,
|
|
3595
|
+
height: visibleCount + (matchLabel ? 1 : 0),
|
|
3596
|
+
children: [
|
|
3597
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_ink_renderer29.Box, { flexDirection: "column", flexShrink: 0, children: [
|
|
3598
|
+
listBlock,
|
|
3599
|
+
matchLabel && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_ink_renderer29.Text, { dimColor: true, children: matchLabel })
|
|
3600
|
+
] }),
|
|
3601
|
+
preview ?? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_ink_renderer29.Box, { flexGrow: 1 })
|
|
3602
|
+
]
|
|
3603
|
+
}
|
|
3604
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_ink_renderer29.Box, { flexDirection: "column", children: [
|
|
3605
|
+
listBlock,
|
|
3606
|
+
matchLabel && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_ink_renderer29.Text, { dimColor: true, children: matchLabel }),
|
|
3607
|
+
preview
|
|
3608
|
+
] });
|
|
3609
|
+
const inputAbove = direction !== "up";
|
|
3610
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Pane, { color: "permission", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_ink_renderer29.Box, { flexDirection: "column", gap: 1, children: [
|
|
3611
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_ink_renderer29.Text, { bold: true, color: "permission", children: title }),
|
|
3612
|
+
inputAbove && searchInput,
|
|
3613
|
+
listGroup,
|
|
3614
|
+
!inputAbove && searchInput,
|
|
3615
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_ink_renderer29.Text, { dimColor: true, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(Byline, { children: [
|
|
3616
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
3617
|
+
KeyboardShortcutHint,
|
|
3618
|
+
{
|
|
3619
|
+
shortcut: "up/dn",
|
|
3620
|
+
action: compact ? "nav" : "navigate"
|
|
3621
|
+
}
|
|
3622
|
+
),
|
|
3623
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(KeyboardShortcutHint, { shortcut: "Enter", action: selectAction }),
|
|
3624
|
+
onTab && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(KeyboardShortcutHint, { shortcut: "Tab", action: onTab.action }),
|
|
3625
|
+
onShiftTab && !compact && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
3626
|
+
KeyboardShortcutHint,
|
|
3627
|
+
{
|
|
3628
|
+
shortcut: "shift+tab",
|
|
3629
|
+
action: onShiftTab.action
|
|
3630
|
+
}
|
|
3631
|
+
),
|
|
3632
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(KeyboardShortcutHint, { shortcut: "Esc", action: "cancel" }),
|
|
3633
|
+
extraHints
|
|
3634
|
+
] }) })
|
|
3635
|
+
] }) });
|
|
3636
|
+
}
|
|
3637
|
+
function List({
|
|
3638
|
+
visible,
|
|
3639
|
+
windowStart,
|
|
3640
|
+
visibleCount,
|
|
3641
|
+
total,
|
|
3642
|
+
focusedIndex,
|
|
3643
|
+
direction,
|
|
3644
|
+
getKey,
|
|
3645
|
+
renderItem,
|
|
3646
|
+
emptyText
|
|
3647
|
+
}) {
|
|
3648
|
+
if (visible.length === 0) {
|
|
3649
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_ink_renderer29.Box, { height: visibleCount, flexShrink: 0, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_ink_renderer29.Text, { dimColor: true, children: emptyText }) });
|
|
3650
|
+
}
|
|
3651
|
+
const rows = visible.map((item, i) => {
|
|
3652
|
+
const actualIndex = windowStart + i;
|
|
3653
|
+
const isFocused = actualIndex === focusedIndex;
|
|
3654
|
+
const atLowEdge = i === 0 && windowStart > 0;
|
|
3655
|
+
const atHighEdge = i === visible.length - 1 && windowStart + visibleCount < total;
|
|
3656
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
3657
|
+
ListItem,
|
|
3658
|
+
{
|
|
3659
|
+
isFocused,
|
|
3660
|
+
showScrollUp: direction === "up" ? atHighEdge : atLowEdge,
|
|
3661
|
+
showScrollDown: direction === "up" ? atLowEdge : atHighEdge,
|
|
3662
|
+
styled: false,
|
|
3663
|
+
children: renderItem(item, isFocused)
|
|
3664
|
+
},
|
|
3665
|
+
getKey(item)
|
|
3666
|
+
);
|
|
3667
|
+
});
|
|
3668
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
3669
|
+
import_ink_renderer29.Box,
|
|
3670
|
+
{
|
|
3671
|
+
height: visibleCount,
|
|
3672
|
+
flexShrink: 0,
|
|
3673
|
+
flexDirection: direction === "up" ? "column-reverse" : "column",
|
|
3674
|
+
children: rows
|
|
3675
|
+
}
|
|
3676
|
+
);
|
|
3677
|
+
}
|
|
3678
|
+
|
|
3679
|
+
// src/design-system/LoadingState.tsx
|
|
3680
|
+
var import_ink_renderer30 = require("@claude-code-kit/ink-renderer");
|
|
3681
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
3682
|
+
function LoadingState({
|
|
3683
|
+
message,
|
|
3684
|
+
bold = false,
|
|
3685
|
+
dimColor = false,
|
|
3686
|
+
subtitle
|
|
3687
|
+
}) {
|
|
3688
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_ink_renderer30.Box, { flexDirection: "column", children: [
|
|
3689
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_ink_renderer30.Box, { flexDirection: "row", children: [
|
|
3690
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Spinner, {}),
|
|
3691
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_ink_renderer30.Text, { bold, dimColor, children: [
|
|
3692
|
+
" ",
|
|
3693
|
+
message
|
|
3694
|
+
] })
|
|
3695
|
+
] }),
|
|
3696
|
+
subtitle && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_ink_renderer30.Text, { dimColor: true, children: subtitle })
|
|
3697
|
+
] });
|
|
3698
|
+
}
|
|
3699
|
+
|
|
3700
|
+
// src/design-system/Ratchet.tsx
|
|
3701
|
+
var import_react20 = require("react");
|
|
3702
|
+
var import_ink_renderer31 = require("@claude-code-kit/ink-renderer");
|
|
3703
|
+
var import_ink_renderer32 = require("@claude-code-kit/ink-renderer");
|
|
3704
|
+
var import_ink_renderer33 = require("@claude-code-kit/ink-renderer");
|
|
3705
|
+
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
3706
|
+
function Ratchet({
|
|
3707
|
+
children,
|
|
3708
|
+
lock = "always"
|
|
3709
|
+
}) {
|
|
3710
|
+
const [viewportRef, { isVisible }] = (0, import_ink_renderer32.useTerminalViewport)();
|
|
3711
|
+
const terminalSize = (0, import_react20.useContext)(import_ink_renderer31.TerminalSizeContext);
|
|
3712
|
+
const rows = terminalSize?.rows ?? 24;
|
|
3713
|
+
const innerRef = (0, import_react20.useRef)(null);
|
|
3714
|
+
const maxHeight = (0, import_react20.useRef)(0);
|
|
3715
|
+
const [minHeight, setMinHeight] = (0, import_react20.useState)(0);
|
|
3716
|
+
const outerRef = (0, import_react20.useCallback)(
|
|
3717
|
+
(el) => {
|
|
3718
|
+
viewportRef(el);
|
|
3719
|
+
},
|
|
3720
|
+
[viewportRef]
|
|
3721
|
+
);
|
|
3722
|
+
const engaged = lock === "always" || !isVisible;
|
|
3723
|
+
(0, import_react20.useLayoutEffect)(() => {
|
|
3724
|
+
if (!innerRef.current) {
|
|
3725
|
+
return;
|
|
3726
|
+
}
|
|
3727
|
+
const { height } = (0, import_ink_renderer33.measureElement)(innerRef.current);
|
|
3728
|
+
if (height > maxHeight.current) {
|
|
3729
|
+
maxHeight.current = Math.min(height, rows);
|
|
3730
|
+
setMinHeight(maxHeight.current);
|
|
3731
|
+
}
|
|
3732
|
+
});
|
|
3733
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_ink_renderer33.Box, { minHeight: engaged ? minHeight : void 0, ref: outerRef, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_ink_renderer33.Box, { ref: innerRef, flexDirection: "column", children }) });
|
|
3734
|
+
}
|
|
3735
|
+
|
|
3736
|
+
// src/design-system/Tabs.tsx
|
|
3737
|
+
var import_react21 = require("react");
|
|
3738
|
+
var import_ink_renderer34 = require("@claude-code-kit/ink-renderer");
|
|
3739
|
+
var import_ink_renderer35 = require("@claude-code-kit/ink-renderer");
|
|
3740
|
+
var import_ink_renderer36 = require("@claude-code-kit/ink-renderer");
|
|
3741
|
+
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
3742
|
+
var TabsContext = (0, import_react21.createContext)({
|
|
3743
|
+
selectedTab: void 0,
|
|
3744
|
+
width: void 0
|
|
3745
|
+
});
|
|
3746
|
+
function Tabs({
|
|
3747
|
+
title,
|
|
3748
|
+
color: color2,
|
|
3749
|
+
defaultTab,
|
|
3750
|
+
children,
|
|
3751
|
+
hidden,
|
|
3752
|
+
useFullWidth,
|
|
3753
|
+
selectedTab: controlledSelectedTab,
|
|
3754
|
+
onTabChange,
|
|
3755
|
+
banner,
|
|
3756
|
+
disableNavigation
|
|
3757
|
+
}) {
|
|
3758
|
+
const terminalSize = (0, import_react21.useContext)(import_ink_renderer34.TerminalSizeContext);
|
|
3759
|
+
const terminalWidth = terminalSize?.columns ?? 80;
|
|
3760
|
+
const tabs = children.map((child) => [
|
|
3761
|
+
child.props.id ?? child.props.title,
|
|
3762
|
+
child.props.title
|
|
3763
|
+
]);
|
|
3764
|
+
const defaultTabIndex = defaultTab ? tabs.findIndex((tab) => defaultTab === tab[0]) : 0;
|
|
3765
|
+
const isControlled = controlledSelectedTab !== void 0;
|
|
3766
|
+
const [internalSelectedTab, setInternalSelectedTab] = (0, import_react21.useState)(
|
|
3767
|
+
defaultTabIndex !== -1 ? defaultTabIndex : 0
|
|
3768
|
+
);
|
|
3769
|
+
const controlledTabIndex = isControlled ? tabs.findIndex((tab) => tab[0] === controlledSelectedTab) : -1;
|
|
3770
|
+
const selectedTabIndex = isControlled ? controlledTabIndex !== -1 ? controlledTabIndex : 0 : internalSelectedTab;
|
|
3771
|
+
const handleTabChange = (0, import_react21.useCallback)(
|
|
3772
|
+
(offset) => {
|
|
3773
|
+
const newIndex = (selectedTabIndex + tabs.length + offset) % tabs.length;
|
|
3774
|
+
const newTabId = tabs[newIndex]?.[0];
|
|
3775
|
+
if (isControlled && onTabChange && newTabId) {
|
|
3776
|
+
onTabChange(newTabId);
|
|
3777
|
+
} else {
|
|
3778
|
+
setInternalSelectedTab(newIndex);
|
|
3779
|
+
}
|
|
3780
|
+
},
|
|
3781
|
+
[selectedTabIndex, tabs, isControlled, onTabChange]
|
|
3782
|
+
);
|
|
3783
|
+
(0, import_ink_renderer36.useInput)(
|
|
3784
|
+
(0, import_react21.useCallback)(
|
|
3785
|
+
(_input, key) => {
|
|
3786
|
+
if (hidden || disableNavigation) return;
|
|
3787
|
+
if (key.tab && !key.shift) {
|
|
3788
|
+
handleTabChange(1);
|
|
3789
|
+
} else if (key.tab && key.shift) {
|
|
3790
|
+
handleTabChange(-1);
|
|
3791
|
+
} else if (key.leftArrow) {
|
|
3792
|
+
handleTabChange(-1);
|
|
3793
|
+
} else if (key.rightArrow) {
|
|
3794
|
+
handleTabChange(1);
|
|
3795
|
+
}
|
|
3796
|
+
},
|
|
3797
|
+
[hidden, disableNavigation, handleTabChange]
|
|
3798
|
+
)
|
|
3799
|
+
);
|
|
3800
|
+
const titleWidth = title ? (0, import_ink_renderer35.stringWidth)(title) + 1 : 0;
|
|
3801
|
+
const tabsWidth = tabs.reduce(
|
|
3802
|
+
(sum, [, tabTitle]) => sum + (tabTitle ? (0, import_ink_renderer35.stringWidth)(tabTitle) : 0) + 3,
|
|
3803
|
+
0
|
|
3804
|
+
);
|
|
3805
|
+
const usedWidth = titleWidth + tabsWidth;
|
|
3806
|
+
const spacerWidth = useFullWidth ? Math.max(0, terminalWidth - usedWidth) : 0;
|
|
3807
|
+
const contentWidth = useFullWidth ? terminalWidth : void 0;
|
|
3808
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
3809
|
+
TabsContext.Provider,
|
|
3810
|
+
{
|
|
3811
|
+
value: {
|
|
3812
|
+
selectedTab: tabs[selectedTabIndex]?.[0],
|
|
3813
|
+
width: contentWidth
|
|
3814
|
+
},
|
|
3815
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_ink_renderer36.Box, { flexDirection: "column", children: [
|
|
3816
|
+
!hidden && /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_ink_renderer36.Box, { flexDirection: "row", gap: 1, children: [
|
|
3817
|
+
title !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_ink_renderer36.Text, { bold: true, color: color2, children: title }),
|
|
3818
|
+
tabs.map(([id, tabTitle], i) => {
|
|
3819
|
+
const isCurrent = selectedTabIndex === i;
|
|
3820
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
|
|
3821
|
+
import_ink_renderer36.Text,
|
|
3822
|
+
{
|
|
3823
|
+
inverse: isCurrent,
|
|
3824
|
+
bold: isCurrent,
|
|
3825
|
+
children: [
|
|
3826
|
+
" ",
|
|
3827
|
+
tabTitle,
|
|
3828
|
+
" "
|
|
3829
|
+
]
|
|
3830
|
+
},
|
|
3831
|
+
id
|
|
3832
|
+
);
|
|
3833
|
+
}),
|
|
3834
|
+
spacerWidth > 0 && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_ink_renderer36.Text, { children: " ".repeat(spacerWidth) })
|
|
3835
|
+
] }),
|
|
3836
|
+
banner,
|
|
3837
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
3838
|
+
import_ink_renderer36.Box,
|
|
3839
|
+
{
|
|
3840
|
+
width: contentWidth,
|
|
3841
|
+
marginTop: hidden ? 0 : 1,
|
|
3842
|
+
children
|
|
3843
|
+
}
|
|
3844
|
+
)
|
|
3845
|
+
] })
|
|
3846
|
+
}
|
|
3847
|
+
);
|
|
3848
|
+
}
|
|
3849
|
+
function Tab({ title, id, children }) {
|
|
3850
|
+
const { selectedTab, width } = (0, import_react21.useContext)(TabsContext);
|
|
3851
|
+
if (selectedTab !== (id ?? title)) {
|
|
3852
|
+
return null;
|
|
3853
|
+
}
|
|
3854
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_ink_renderer36.Box, { width, children });
|
|
3855
|
+
}
|
|
3856
|
+
function useTabsWidth() {
|
|
3857
|
+
const { width } = (0, import_react21.useContext)(TabsContext);
|
|
3858
|
+
return width;
|
|
3859
|
+
}
|
|
2392
3860
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2393
3861
|
0 && (module.exports = {
|
|
3862
|
+
Byline,
|
|
2394
3863
|
CommandRegistry,
|
|
2395
3864
|
DEFAULT_BINDINGS,
|
|
3865
|
+
Dialog,
|
|
2396
3866
|
Divider,
|
|
3867
|
+
FuzzyPicker,
|
|
2397
3868
|
KeybindingSetup,
|
|
3869
|
+
KeyboardShortcutHint,
|
|
3870
|
+
ListItem,
|
|
3871
|
+
LoadingState,
|
|
3872
|
+
Markdown,
|
|
3873
|
+
MarkdownTable,
|
|
2398
3874
|
MessageList,
|
|
2399
3875
|
MultiSelect,
|
|
3876
|
+
Pane,
|
|
2400
3877
|
ProgressBar,
|
|
2401
3878
|
PromptInput,
|
|
2402
3879
|
REPL,
|
|
3880
|
+
Ratchet,
|
|
2403
3881
|
Select,
|
|
2404
3882
|
Spinner,
|
|
2405
3883
|
StatusIcon,
|
|
2406
3884
|
StatusLine,
|
|
3885
|
+
StreamingMarkdown,
|
|
2407
3886
|
StreamingText,
|
|
3887
|
+
Tab,
|
|
3888
|
+
Tabs,
|
|
3889
|
+
TextHoverColorContext,
|
|
3890
|
+
ThemeProvider,
|
|
3891
|
+
ThemedBox,
|
|
3892
|
+
ThemedText,
|
|
2408
3893
|
clearCommand,
|
|
3894
|
+
color,
|
|
2409
3895
|
createCommandRegistry,
|
|
2410
3896
|
defineCommand,
|
|
2411
3897
|
defineJSXCommand,
|
|
2412
3898
|
defineLocalCommand,
|
|
2413
3899
|
exitCommand,
|
|
3900
|
+
getTheme,
|
|
2414
3901
|
helpCommand,
|
|
3902
|
+
useDoublePress,
|
|
2415
3903
|
useKeybinding,
|
|
2416
3904
|
useKeybindings,
|
|
3905
|
+
usePreviewTheme,
|
|
2417
3906
|
useStatusLine,
|
|
3907
|
+
useTabsWidth,
|
|
3908
|
+
useTerminalSize,
|
|
3909
|
+
useTheme,
|
|
3910
|
+
useThemeSetting,
|
|
2418
3911
|
...require("@claude-code-kit/ink-renderer")
|
|
2419
3912
|
});
|