@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/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
- useStatusLine: () => useStatusLine
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: !color, children: [
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: !color, children: char.repeat(effectiveWidth) });
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
- const binding = bindings.findLast(
422
- (b) => b.action === action && b.context === context
423
- );
424
- return binding ? chordToString(binding.chord) : void 0;
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/PromptInput.tsx
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, import_react6.useState)(0);
1779
- const [historyIndex, setHistoryIndex] = (0, import_react6.useState)(-1);
1780
- const [suggestionIndex, setSuggestionIndex] = (0, import_react6.useState)(0);
1781
- const [showSuggestions, setShowSuggestions] = (0, import_react6.useState)(false);
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, import_react6.useCallback)(
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, import_ink_renderer7.useInput)(
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)(import_ink_renderer7.Text, { children: [
1916
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_ink_renderer7.Text, { inverse: true, children: " " }),
1917
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_ink_renderer7.Text, { dimColor: true, children: placeholder })
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)(import_ink_renderer7.Text, { children: [
2005
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_ink_renderer8.Text, { children: [
1924
2006
  before,
1925
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_ink_renderer7.Text, { inverse: true, children: atCursor }),
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)(import_ink_renderer7.Box, { flexDirection: "column", children: [
1930
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_ink_renderer7.Box, { children: [
1931
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_ink_renderer7.Text, { color: prefixColor, children: [
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)(import_ink_renderer7.Box, { flexDirection: "column", marginLeft: 2, children: suggestions.map((cmd, i) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_ink_renderer7.Box, { children: [
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
- import_ink_renderer7.Text,
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)(import_ink_renderer7.Text, { dimColor: true, children: ` ${cmd.description}` })
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 import_react7 = require("react");
1953
- var import_ink_renderer8 = require("@claude-code-kit/ink-renderer");
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, import_react7.useState)(0);
1968
- const [verbIndex, setVerbIndex] = (0, import_react7.useState)(0);
1969
- const [elapsed, setElapsed] = (0, import_react7.useState)(0);
1970
- const startRef = (0, import_react7.useRef)(Date.now());
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, import_react7.useEffect)(() => {
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, import_react7.useEffect)(() => {
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)(import_ink_renderer8.Box, { children: [
1991
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_ink_renderer8.Text, { color, children: frame }),
1992
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_ink_renderer8.Text, { children: [
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)(import_ink_renderer8.Text, { children: [
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)(import_ink_renderer8.Text, { dimColor: true, children: [
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/Select.tsx
2010
- var import_react8 = require("react");
2011
- var import_ink_renderer9 = require("@claude-code-kit/ink-renderer");
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, import_react8.useState)(0);
2016
- const focusRef = (0, import_react8.useRef)(focusIndex);
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, import_react8.useMemo)(() => {
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, import_react8.useMemo)(
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, import_react8.useCallback)(
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, import_ink_renderer9.useInput)((input, key) => {
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, import_jsx_runtime9.jsxs)(import_ink_renderer9.Text, { dimColor: true, children: [
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, import_react8.useCallback)(
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, import_jsx_runtime9.jsxs)(import_ink_renderer9.Box, { flexDirection: "column", children: [
2089
- title && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_ink_renderer9.Box, { marginBottom: 1, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_ink_renderer9.Text, { bold: true, children: title }) }),
2090
- scrollOffset > 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ScrollHint, { count: scrollOffset, direction: "up" }),
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, import_jsx_runtime9.jsxs)(import_ink_renderer9.Box, { children: [
2097
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_ink_renderer9.Text, { color: isFocused ? "cyan" : void 0, children: [
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, import_jsx_runtime9.jsxs)(
2102
- import_ink_renderer9.Text,
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, import_jsx_runtime9.jsx)(import_ink_renderer9.Text, { color: "green", children: " \u2713" }),
2115
- opt.description && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_ink_renderer9.Text, { dimColor: true, children: [
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, import_jsx_runtime9.jsx)(ScrollHint, { count: total - scrollOffset - max, direction: "down" }),
2122
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_ink_renderer9.Box, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_ink_renderer9.Text, { dimColor: true, children: "Enter to confirm \xB7 Esc to exit" }) })
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, import_react8.useState)(() => new Set(selectedValues));
2135
- const handleConfirm = (0, import_react8.useCallback)(
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, import_react8.useCallback)(
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, import_jsx_runtime9.jsxs)(import_ink_renderer9.Box, { flexDirection: "column", children: [
2163
- title && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_ink_renderer9.Box, { marginBottom: 1, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_ink_renderer9.Text, { bold: true, children: title }) }),
2164
- scrollOffset > 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ScrollHint, { count: scrollOffset, direction: "up" }),
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, import_jsx_runtime9.jsxs)(import_ink_renderer9.Box, { children: [
2171
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_ink_renderer9.Text, { color: isFocused ? "cyan" : void 0, children: [
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, import_jsx_runtime9.jsxs)(
2176
- import_ink_renderer9.Text,
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, import_jsx_runtime9.jsxs)(import_ink_renderer9.Text, { dimColor: true, children: [
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, import_jsx_runtime9.jsx)(ScrollHint, { count: total - scrollOffset - max, direction: "down" }),
2197
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_ink_renderer9.Box, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_ink_renderer9.Text, { dimColor: true, children: "Space to toggle \xB7 Enter to confirm \xB7 Esc to exit" }) })
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 import_ink_renderer10 = require("@claude-code-kit/ink-renderer");
2203
- var import_jsx_runtime10 = require("react/jsx-runtime");
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, import_jsx_runtime10.jsxs)(import_ink_renderer10.Box, { flexDirection: "column", children: [
2219
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_ink_renderer10.Box, { children: [
2220
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_ink_renderer10.Text, { color: config.color, dimColor: isSystem, children: config.icon }),
2221
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_ink_renderer10.Text, { color: config.color, dimColor: isSystem, bold: !isSystem, children: [
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, import_jsx_runtime10.jsx)(import_ink_renderer10.Box, { marginLeft: 2, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_ink_renderer10.Text, { dimColor: isSystem, children: line }) }, i))
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, import_jsx_runtime10.jsxs)(import_ink_renderer10.Box, { flexDirection: "column", children: [
2235
- messages.map((message, i) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_ink_renderer10.Box, { flexDirection: "column", marginTop: i > 0 ? 1 : 0, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(MessageItem, { message, renderMessage }) }, message.id)),
2236
- streamingContent != null && streamingContent.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_ink_renderer10.Box, { flexDirection: "column", marginTop: messages.length > 0 ? 1 : 0, children: [
2237
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_ink_renderer10.Box, { children: [
2238
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_ink_renderer10.Text, { color: "#DA7756", children: "\u25CF" }),
2239
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_ink_renderer10.Text, { color: "#DA7756", bold: true, children: [
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, import_jsx_runtime10.jsx)(import_ink_renderer10.Box, { marginLeft: 2, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_ink_renderer10.Text, { children: [
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, import_jsx_runtime10.jsx)(import_ink_renderer10.Text, { color: "#DA7756", children: "\u2588" })
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 import_react9 = require("react");
2254
- var import_ink_renderer11 = require("@claude-code-kit/ink-renderer");
2255
- var import_jsx_runtime11 = require("react/jsx-runtime");
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, import_react9.useState)(0);
2264
- const onCompleteRef = (0, import_react9.useRef)(onComplete);
3082
+ const [revealed, setRevealed] = (0, import_react14.useState)(0);
3083
+ const onCompleteRef = (0, import_react14.useRef)(onComplete);
2265
3084
  onCompleteRef.current = onComplete;
2266
- (0, import_react9.useEffect)(() => {
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, import_jsx_runtime11.jsx)(import_ink_renderer11.Text, { color, children: text.slice(0, revealed) });
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 import_react10 = require("react");
2284
- var import_ink_renderer12 = require("@claude-code-kit/ink-renderer");
2285
- var import_jsx_runtime12 = require("react/jsx-runtime");
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, import_ink_renderer12.useApp)();
2302
- const [inputValue, setInputValue] = (0, import_react10.useState)("");
2303
- const [internalHistory, setInternalHistory] = (0, import_react10.useState)([]);
2304
- const submittingRef = (0, import_react10.useRef)(false);
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, import_react10.useCallback)(
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, import_ink_renderer12.useInput)(
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, import_jsx_runtime12.jsxs)(import_ink_renderer12.Box, { flexDirection: "column", flexGrow: 1, children: [
2359
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_ink_renderer12.Box, { flexDirection: "column", flexGrow: 1, children: [
2360
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
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, import_jsx_runtime12.jsx)(import_ink_renderer12.Box, { marginTop: messages.length > 0 ? 1 : 0, children: spinner ?? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Spinner, {}) })
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, import_jsx_runtime12.jsx)(Divider, {}),
2371
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
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, import_jsx_runtime12.jsx)(Divider, {}),
2385
- resolvedSegments.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(StatusLine, { segments: resolvedSegments })
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
  });