@claude-code-kit/ui 0.1.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +265 -8
- package/dist/index.d.ts +265 -8
- package/dist/index.js +2000 -510
- package/dist/index.mjs +1866 -393
- package/package.json +18 -12
- package/LICENSE +0 -21
package/dist/index.js
CHANGED
|
@@ -31,11 +31,19 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
31
31
|
// src/index.ts
|
|
32
32
|
var index_exports = {};
|
|
33
33
|
__export(index_exports, {
|
|
34
|
+
AgentContext: () => AgentContext,
|
|
35
|
+
AgentProvider: () => AgentProvider,
|
|
36
|
+
AgentREPL: () => AgentREPL,
|
|
37
|
+
AuthFlowUI: () => AuthFlowUI,
|
|
38
|
+
BashPermissionContent: () => BashPermissionContent,
|
|
34
39
|
Byline: () => Byline,
|
|
40
|
+
ClawdLogo: () => ClawdLogo,
|
|
35
41
|
CommandRegistry: () => CommandRegistry,
|
|
36
42
|
DEFAULT_BINDINGS: () => DEFAULT_BINDINGS,
|
|
37
43
|
Dialog: () => Dialog,
|
|
44
|
+
DiffView: () => DiffView,
|
|
38
45
|
Divider: () => Divider,
|
|
46
|
+
FileEditPermissionContent: () => FileEditPermissionContent,
|
|
39
47
|
FuzzyPicker: () => FuzzyPicker,
|
|
40
48
|
KeybindingSetup: () => KeybindingSetup,
|
|
41
49
|
KeyboardShortcutHint: () => KeyboardShortcutHint,
|
|
@@ -46,10 +54,12 @@ __export(index_exports, {
|
|
|
46
54
|
MessageList: () => MessageList,
|
|
47
55
|
MultiSelect: () => MultiSelect,
|
|
48
56
|
Pane: () => Pane,
|
|
57
|
+
PermissionRequest: () => PermissionRequest,
|
|
49
58
|
ProgressBar: () => ProgressBar,
|
|
50
59
|
PromptInput: () => PromptInput,
|
|
51
60
|
REPL: () => REPL,
|
|
52
61
|
Ratchet: () => Ratchet,
|
|
62
|
+
SearchOverlay: () => SearchOverlay,
|
|
53
63
|
Select: () => Select,
|
|
54
64
|
Spinner: () => Spinner,
|
|
55
65
|
StatusIcon: () => StatusIcon,
|
|
@@ -62,6 +72,8 @@ __export(index_exports, {
|
|
|
62
72
|
ThemeProvider: () => ThemeProvider,
|
|
63
73
|
ThemedBox: () => ThemedBox_default,
|
|
64
74
|
ThemedText: () => ThemedText,
|
|
75
|
+
VirtualList: () => VirtualList,
|
|
76
|
+
WelcomeScreen: () => WelcomeScreen,
|
|
65
77
|
clearCommand: () => clearCommand,
|
|
66
78
|
color: () => color,
|
|
67
79
|
createCommandRegistry: () => createCommandRegistry,
|
|
@@ -71,46 +83,178 @@ __export(index_exports, {
|
|
|
71
83
|
exitCommand: () => exitCommand,
|
|
72
84
|
getTheme: () => getTheme,
|
|
73
85
|
helpCommand: () => helpCommand,
|
|
86
|
+
parseUnifiedDiff: () => parseUnifiedDiff,
|
|
87
|
+
useAgent: () => useAgent,
|
|
88
|
+
useAgentContext: () => useAgentContext,
|
|
74
89
|
useDoublePress: () => useDoublePress,
|
|
75
90
|
useKeybinding: () => useKeybinding,
|
|
76
91
|
useKeybindings: () => useKeybindings,
|
|
77
92
|
usePreviewTheme: () => usePreviewTheme,
|
|
93
|
+
useSearch: () => useSearch,
|
|
78
94
|
useStatusLine: () => useStatusLine,
|
|
79
95
|
useTabsWidth: () => useTabsWidth,
|
|
80
96
|
useTerminalSize: () => useTerminalSize,
|
|
81
97
|
useTheme: () => useTheme,
|
|
82
|
-
useThemeSetting: () => useThemeSetting
|
|
98
|
+
useThemeSetting: () => useThemeSetting,
|
|
99
|
+
useVirtualScroll: () => useVirtualScroll
|
|
83
100
|
});
|
|
84
101
|
module.exports = __toCommonJS(index_exports);
|
|
85
102
|
__reExport(index_exports, require("@claude-code-kit/ink-renderer"), module.exports);
|
|
86
103
|
|
|
87
|
-
// src/
|
|
104
|
+
// src/DiffView.tsx
|
|
88
105
|
var import_react = require("react");
|
|
89
106
|
var import_ink_renderer = require("@claude-code-kit/ink-renderer");
|
|
90
107
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
108
|
+
function parseUnifiedDiff(diff) {
|
|
109
|
+
const rawLines = diff.split("\n");
|
|
110
|
+
let filename = "";
|
|
111
|
+
const lines = [];
|
|
112
|
+
let oldLine = 0;
|
|
113
|
+
let newLine = 0;
|
|
114
|
+
for (const line of rawLines) {
|
|
115
|
+
if (line.startsWith("+++ ")) {
|
|
116
|
+
const path = line.slice(4).trim();
|
|
117
|
+
filename = path.startsWith("b/") ? path.slice(2) : path;
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
if (line.startsWith("--- ")) continue;
|
|
121
|
+
const hunkMatch = line.match(/^@@ -(\d+)(?:,\d+)? \+(\d+)(?:,\d+)? @@/);
|
|
122
|
+
if (hunkMatch) {
|
|
123
|
+
oldLine = parseInt(hunkMatch[1], 10);
|
|
124
|
+
newLine = parseInt(hunkMatch[2], 10);
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
if (line.startsWith("diff ") || line.startsWith("index ") || line.startsWith("\\")) {
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
if (oldLine === 0 && newLine === 0) continue;
|
|
131
|
+
if (line.startsWith("+")) {
|
|
132
|
+
lines.push({
|
|
133
|
+
type: "added",
|
|
134
|
+
content: line.slice(1),
|
|
135
|
+
newLineNumber: newLine
|
|
136
|
+
});
|
|
137
|
+
newLine++;
|
|
138
|
+
} else if (line.startsWith("-")) {
|
|
139
|
+
lines.push({
|
|
140
|
+
type: "removed",
|
|
141
|
+
content: line.slice(1),
|
|
142
|
+
oldLineNumber: oldLine
|
|
143
|
+
});
|
|
144
|
+
oldLine++;
|
|
145
|
+
} else {
|
|
146
|
+
lines.push({
|
|
147
|
+
type: "context",
|
|
148
|
+
content: line.startsWith(" ") ? line.slice(1) : line,
|
|
149
|
+
oldLineNumber: oldLine,
|
|
150
|
+
newLineNumber: newLine
|
|
151
|
+
});
|
|
152
|
+
oldLine++;
|
|
153
|
+
newLine++;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
return { filename: filename || "unknown", lines };
|
|
157
|
+
}
|
|
158
|
+
function DiffView({
|
|
159
|
+
filename,
|
|
160
|
+
lines: propLines,
|
|
161
|
+
diff,
|
|
162
|
+
showLineNumbers = true,
|
|
163
|
+
maxHeight,
|
|
164
|
+
color: colorOverrides
|
|
165
|
+
}) {
|
|
166
|
+
const parsed = (0, import_react.useMemo)(() => {
|
|
167
|
+
if (diff) return parseUnifiedDiff(diff);
|
|
168
|
+
return null;
|
|
169
|
+
}, [diff]);
|
|
170
|
+
const resolvedFilename = parsed?.filename ?? filename;
|
|
171
|
+
const resolvedLines = parsed?.lines ?? propLines;
|
|
172
|
+
const addedColor = colorOverrides?.added ?? "green";
|
|
173
|
+
const removedColor = colorOverrides?.removed ?? "red";
|
|
174
|
+
const headerColor = colorOverrides?.header ?? "cyan";
|
|
175
|
+
const contextColor = colorOverrides?.context;
|
|
176
|
+
const maxLineNum = (0, import_react.useMemo)(() => {
|
|
177
|
+
let max = 0;
|
|
178
|
+
for (const line of resolvedLines) {
|
|
179
|
+
if (line.oldLineNumber !== void 0 && line.oldLineNumber > max) max = line.oldLineNumber;
|
|
180
|
+
if (line.newLineNumber !== void 0 && line.newLineNumber > max) max = line.newLineNumber;
|
|
181
|
+
}
|
|
182
|
+
return max;
|
|
183
|
+
}, [resolvedLines]);
|
|
184
|
+
const gutterWidth = Math.max(2, String(maxLineNum).length);
|
|
185
|
+
const visibleLines = maxHeight && resolvedLines.length > maxHeight ? resolvedLines.slice(0, maxHeight) : resolvedLines;
|
|
186
|
+
const truncated = maxHeight && resolvedLines.length > maxHeight ? resolvedLines.length - maxHeight : 0;
|
|
187
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_ink_renderer.Box, { flexDirection: "column", children: [
|
|
188
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_ink_renderer.Text, { bold: true, color: headerColor, children: [
|
|
189
|
+
" ",
|
|
190
|
+
resolvedFilename
|
|
191
|
+
] }),
|
|
192
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_ink_renderer.Text, { dimColor: true, children: [
|
|
193
|
+
" ",
|
|
194
|
+
"\u2500".repeat(30)
|
|
195
|
+
] }),
|
|
196
|
+
visibleLines.map((line, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
197
|
+
DiffLineRow,
|
|
198
|
+
{
|
|
199
|
+
line,
|
|
200
|
+
gutterWidth,
|
|
201
|
+
showLineNumbers,
|
|
202
|
+
addedColor,
|
|
203
|
+
removedColor,
|
|
204
|
+
contextColor
|
|
205
|
+
},
|
|
206
|
+
i
|
|
207
|
+
)),
|
|
208
|
+
truncated > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_ink_renderer.Text, { dimColor: true, children: [
|
|
209
|
+
" ... ",
|
|
210
|
+
truncated,
|
|
211
|
+
" more lines"
|
|
212
|
+
] })
|
|
213
|
+
] });
|
|
214
|
+
}
|
|
215
|
+
function DiffLineRow({ line, gutterWidth, showLineNumbers, addedColor, removedColor, contextColor }) {
|
|
216
|
+
const lineNum = line.type === "removed" ? line.oldLineNumber : line.newLineNumber ?? line.oldLineNumber;
|
|
217
|
+
const prefix = line.type === "added" ? "+ " : line.type === "removed" ? "- " : " ";
|
|
218
|
+
const gutterStr = showLineNumbers && lineNum !== void 0 ? String(lineNum).padStart(gutterWidth) : " ".repeat(gutterWidth);
|
|
219
|
+
const contentColor = line.type === "added" ? addedColor : line.type === "removed" ? removedColor : contextColor;
|
|
220
|
+
const dim = line.type === "context" && !contextColor;
|
|
221
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_ink_renderer.Text, { children: [
|
|
222
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ink_renderer.Text, { dimColor: true, children: gutterStr }),
|
|
223
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ink_renderer.Text, { dimColor: true, children: " \u2502 " }),
|
|
224
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_ink_renderer.Text, { dimColor: dim, color: contentColor, children: [
|
|
225
|
+
prefix,
|
|
226
|
+
line.content
|
|
227
|
+
] })
|
|
228
|
+
] });
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// src/Divider.tsx
|
|
232
|
+
var import_react2 = require("react");
|
|
233
|
+
var import_ink_renderer2 = require("@claude-code-kit/ink-renderer");
|
|
234
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
91
235
|
function Divider({ width, color: color2, char = "\u2500", padding = 0, title }) {
|
|
92
|
-
const terminalSize = (0,
|
|
236
|
+
const terminalSize = (0, import_react2.useContext)(import_ink_renderer2.TerminalSizeContext);
|
|
93
237
|
const terminalWidth = terminalSize?.columns ?? 80;
|
|
94
238
|
const effectiveWidth = Math.max(0, (width ?? terminalWidth - 2) - padding);
|
|
95
239
|
if (title) {
|
|
96
|
-
const titleWidth = (0,
|
|
240
|
+
const titleWidth = (0, import_ink_renderer2.stringWidth)(title) + 2;
|
|
97
241
|
const sideWidth = Math.max(0, effectiveWidth - titleWidth);
|
|
98
242
|
const leftWidth = Math.floor(sideWidth / 2);
|
|
99
243
|
const rightWidth = sideWidth - leftWidth;
|
|
100
|
-
return /* @__PURE__ */ (0,
|
|
244
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_ink_renderer2.Text, { color: color2, dimColor: !color2, children: [
|
|
101
245
|
char.repeat(leftWidth),
|
|
102
246
|
" ",
|
|
103
|
-
/* @__PURE__ */ (0,
|
|
247
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_ink_renderer2.Text, { dimColor: true, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_ink_renderer2.Ansi, { children: title }) }),
|
|
104
248
|
" ",
|
|
105
249
|
char.repeat(rightWidth)
|
|
106
250
|
] });
|
|
107
251
|
}
|
|
108
|
-
return /* @__PURE__ */ (0,
|
|
252
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_ink_renderer2.Text, { color: color2, dimColor: !color2, children: char.repeat(effectiveWidth) });
|
|
109
253
|
}
|
|
110
254
|
|
|
111
255
|
// src/ProgressBar.tsx
|
|
112
|
-
var
|
|
113
|
-
var
|
|
256
|
+
var import_ink_renderer3 = require("@claude-code-kit/ink-renderer");
|
|
257
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
114
258
|
var BLOCKS = [" ", "\u258F", "\u258E", "\u258D", "\u258C", "\u258B", "\u258A", "\u2589", "\u2588"];
|
|
115
259
|
function ProgressBar({ ratio: inputRatio, width, fillColor, emptyColor }) {
|
|
116
260
|
const ratio = Math.min(1, Math.max(0, inputRatio));
|
|
@@ -125,13 +269,13 @@ function ProgressBar({ ratio: inputRatio, width, fillColor, emptyColor }) {
|
|
|
125
269
|
segments.push(BLOCKS[0].repeat(empty));
|
|
126
270
|
}
|
|
127
271
|
}
|
|
128
|
-
return /* @__PURE__ */ (0,
|
|
272
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_ink_renderer3.Text, { color: fillColor, backgroundColor: emptyColor, children: segments.join("") });
|
|
129
273
|
}
|
|
130
274
|
|
|
131
275
|
// src/StatusIcon.tsx
|
|
132
276
|
var import_figures = __toESM(require("figures"));
|
|
133
|
-
var
|
|
134
|
-
var
|
|
277
|
+
var import_ink_renderer4 = require("@claude-code-kit/ink-renderer");
|
|
278
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
135
279
|
var STATUS_CONFIG = {
|
|
136
280
|
success: { icon: import_figures.default.tick, color: "green" },
|
|
137
281
|
error: { icon: import_figures.default.cross, color: "red" },
|
|
@@ -142,16 +286,16 @@ var STATUS_CONFIG = {
|
|
|
142
286
|
};
|
|
143
287
|
function StatusIcon({ status, withSpace = false }) {
|
|
144
288
|
const config = STATUS_CONFIG[status];
|
|
145
|
-
return /* @__PURE__ */ (0,
|
|
289
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_ink_renderer4.Text, { color: config.color, dimColor: !config.color, children: [
|
|
146
290
|
config.icon,
|
|
147
291
|
withSpace && " "
|
|
148
292
|
] });
|
|
149
293
|
}
|
|
150
294
|
|
|
151
295
|
// src/StatusLine.tsx
|
|
152
|
-
var
|
|
153
|
-
var
|
|
154
|
-
var
|
|
296
|
+
var import_react3 = __toESM(require("react"));
|
|
297
|
+
var import_ink_renderer5 = require("@claude-code-kit/ink-renderer");
|
|
298
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
155
299
|
function hasAnsi(s) {
|
|
156
300
|
return /\x1b\[/.test(s);
|
|
157
301
|
}
|
|
@@ -159,28 +303,31 @@ function StatusLine({
|
|
|
159
303
|
segments,
|
|
160
304
|
text,
|
|
161
305
|
paddingX = 1,
|
|
162
|
-
|
|
306
|
+
separator = " \xB7 ",
|
|
163
307
|
borderStyle = "none",
|
|
164
308
|
borderColor
|
|
165
309
|
}) {
|
|
166
310
|
const border = borderStyle === "none" ? void 0 : borderStyle;
|
|
167
|
-
return /* @__PURE__ */ (0,
|
|
168
|
-
|
|
311
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
312
|
+
import_ink_renderer5.Box,
|
|
169
313
|
{
|
|
170
314
|
flexDirection: "row",
|
|
171
315
|
paddingX,
|
|
172
316
|
borderStyle: border,
|
|
173
317
|
borderColor,
|
|
174
|
-
children: text !== void 0 ? hasAnsi(text) ? /* @__PURE__ */ (0,
|
|
318
|
+
children: text !== void 0 ? hasAnsi(text) ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_ink_renderer5.Ansi, { children: text }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_ink_renderer5.Text, { dimColor: true, children: text }) : segments?.map((seg, i) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react3.default.Fragment, { children: [
|
|
319
|
+
i > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_ink_renderer5.Text, { dimColor: true, children: separator }),
|
|
320
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_ink_renderer5.Box, { flexGrow: seg.flex ? 1 : 0, children: hasAnsi(seg.content) ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_ink_renderer5.Ansi, { children: seg.content }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_ink_renderer5.Text, { dimColor: true, color: seg.color, children: seg.content }) })
|
|
321
|
+
] }, i))
|
|
175
322
|
}
|
|
176
323
|
);
|
|
177
324
|
}
|
|
178
325
|
function useStatusLine(updater, deps, intervalMs) {
|
|
179
|
-
const [value, setValue] = (0,
|
|
180
|
-
(0,
|
|
326
|
+
const [value, setValue] = (0, import_react3.useState)(() => updater());
|
|
327
|
+
(0, import_react3.useEffect)(() => {
|
|
181
328
|
setValue(updater());
|
|
182
329
|
}, deps);
|
|
183
|
-
(0,
|
|
330
|
+
(0, import_react3.useEffect)(() => {
|
|
184
331
|
if (!intervalMs) return;
|
|
185
332
|
const id = setInterval(() => setValue(updater()), intervalMs);
|
|
186
333
|
return () => clearInterval(id);
|
|
@@ -285,11 +432,11 @@ var clearCommand = {
|
|
|
285
432
|
};
|
|
286
433
|
|
|
287
434
|
// src/keybindings/useKeybinding.ts
|
|
288
|
-
var
|
|
289
|
-
var
|
|
435
|
+
var import_react5 = require("react");
|
|
436
|
+
var import_ink_renderer6 = require("@claude-code-kit/ink-renderer");
|
|
290
437
|
|
|
291
438
|
// src/keybindings/KeybindingContext.tsx
|
|
292
|
-
var
|
|
439
|
+
var import_react4 = require("react");
|
|
293
440
|
|
|
294
441
|
// src/keybindings/match.ts
|
|
295
442
|
function getKeyName(input, key) {
|
|
@@ -536,8 +683,8 @@ function resolveKeyWithChordState(input, key, activeContexts, bindings, pending)
|
|
|
536
683
|
}
|
|
537
684
|
|
|
538
685
|
// src/keybindings/KeybindingContext.tsx
|
|
539
|
-
var
|
|
540
|
-
var KeybindingContext = (0,
|
|
686
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
687
|
+
var KeybindingContext = (0, import_react4.createContext)(null);
|
|
541
688
|
function KeybindingProvider({
|
|
542
689
|
bindings,
|
|
543
690
|
pendingChordRef,
|
|
@@ -549,11 +696,11 @@ function KeybindingProvider({
|
|
|
549
696
|
handlerRegistryRef,
|
|
550
697
|
children
|
|
551
698
|
}) {
|
|
552
|
-
const getDisplayText = (0,
|
|
699
|
+
const getDisplayText = (0, import_react4.useMemo)(
|
|
553
700
|
() => (action, context) => getBindingDisplayText(action, context, bindings),
|
|
554
701
|
[bindings]
|
|
555
702
|
);
|
|
556
|
-
const registerHandler = (0,
|
|
703
|
+
const registerHandler = (0, import_react4.useMemo)(
|
|
557
704
|
() => (registration) => {
|
|
558
705
|
const registry = handlerRegistryRef.current;
|
|
559
706
|
if (!registry) return () => {
|
|
@@ -574,7 +721,7 @@ function KeybindingProvider({
|
|
|
574
721
|
},
|
|
575
722
|
[handlerRegistryRef]
|
|
576
723
|
);
|
|
577
|
-
const invokeAction = (0,
|
|
724
|
+
const invokeAction = (0, import_react4.useMemo)(
|
|
578
725
|
() => (action) => {
|
|
579
726
|
const registry = handlerRegistryRef.current;
|
|
580
727
|
if (!registry) return false;
|
|
@@ -590,7 +737,7 @@ function KeybindingProvider({
|
|
|
590
737
|
},
|
|
591
738
|
[activeContexts, handlerRegistryRef]
|
|
592
739
|
);
|
|
593
|
-
const resolve = (0,
|
|
740
|
+
const resolve = (0, import_react4.useMemo)(
|
|
594
741
|
() => (input, key, contexts) => resolveKeyWithChordState(
|
|
595
742
|
input,
|
|
596
743
|
key,
|
|
@@ -600,7 +747,7 @@ function KeybindingProvider({
|
|
|
600
747
|
),
|
|
601
748
|
[bindings, pendingChordRef]
|
|
602
749
|
);
|
|
603
|
-
const value = (0,
|
|
750
|
+
const value = (0, import_react4.useMemo)(
|
|
604
751
|
() => ({
|
|
605
752
|
resolve,
|
|
606
753
|
setPendingChord,
|
|
@@ -626,21 +773,21 @@ function KeybindingProvider({
|
|
|
626
773
|
invokeAction
|
|
627
774
|
]
|
|
628
775
|
);
|
|
629
|
-
return /* @__PURE__ */ (0,
|
|
776
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(KeybindingContext.Provider, { value, children });
|
|
630
777
|
}
|
|
631
778
|
function useOptionalKeybindingContext() {
|
|
632
|
-
return (0,
|
|
779
|
+
return (0, import_react4.useContext)(KeybindingContext);
|
|
633
780
|
}
|
|
634
781
|
|
|
635
782
|
// src/keybindings/useKeybinding.ts
|
|
636
783
|
function useKeybinding(action, handler, options = {}) {
|
|
637
784
|
const { context = "Global", isActive = true } = options;
|
|
638
785
|
const keybindingContext = useOptionalKeybindingContext();
|
|
639
|
-
(0,
|
|
786
|
+
(0, import_react5.useEffect)(() => {
|
|
640
787
|
if (!keybindingContext || !isActive) return;
|
|
641
788
|
return keybindingContext.registerHandler({ action, context, handler });
|
|
642
789
|
}, [action, context, handler, keybindingContext, isActive]);
|
|
643
|
-
const handleInput = (0,
|
|
790
|
+
const handleInput = (0, import_react5.useCallback)(
|
|
644
791
|
(input, key, event) => {
|
|
645
792
|
if (!keybindingContext) return;
|
|
646
793
|
const contextsToCheck = [
|
|
@@ -676,12 +823,12 @@ function useKeybinding(action, handler, options = {}) {
|
|
|
676
823
|
},
|
|
677
824
|
[action, context, handler, keybindingContext]
|
|
678
825
|
);
|
|
679
|
-
(0,
|
|
826
|
+
(0, import_ink_renderer6.useInput)(handleInput, { isActive });
|
|
680
827
|
}
|
|
681
828
|
function useKeybindings(handlers, options = {}) {
|
|
682
829
|
const { context = "Global", isActive = true } = options;
|
|
683
830
|
const keybindingContext = useOptionalKeybindingContext();
|
|
684
|
-
(0,
|
|
831
|
+
(0, import_react5.useEffect)(() => {
|
|
685
832
|
if (!keybindingContext || !isActive) return;
|
|
686
833
|
const unregisterFns = [];
|
|
687
834
|
for (const [action, handler] of Object.entries(handlers)) {
|
|
@@ -695,7 +842,7 @@ function useKeybindings(handlers, options = {}) {
|
|
|
695
842
|
}
|
|
696
843
|
};
|
|
697
844
|
}, [context, handlers, keybindingContext, isActive]);
|
|
698
|
-
const handleInput = (0,
|
|
845
|
+
const handleInput = (0, import_react5.useCallback)(
|
|
699
846
|
(input, key, event) => {
|
|
700
847
|
if (!keybindingContext) return;
|
|
701
848
|
const contextsToCheck = [
|
|
@@ -732,12 +879,12 @@ function useKeybindings(handlers, options = {}) {
|
|
|
732
879
|
},
|
|
733
880
|
[context, handlers, keybindingContext]
|
|
734
881
|
);
|
|
735
|
-
(0,
|
|
882
|
+
(0, import_ink_renderer6.useInput)(handleInput, { isActive });
|
|
736
883
|
}
|
|
737
884
|
|
|
738
885
|
// src/keybindings/KeybindingProviderSetup.tsx
|
|
739
|
-
var
|
|
740
|
-
var
|
|
886
|
+
var import_react6 = require("react");
|
|
887
|
+
var import_ink_renderer7 = require("@claude-code-kit/ink-renderer");
|
|
741
888
|
|
|
742
889
|
// src/keybindings/loadUserBindings.ts
|
|
743
890
|
var import_chokidar = __toESM(require("chokidar"));
|
|
@@ -1605,22 +1752,22 @@ function handleDelete(path) {
|
|
|
1605
1752
|
}
|
|
1606
1753
|
|
|
1607
1754
|
// src/keybindings/KeybindingProviderSetup.tsx
|
|
1608
|
-
var
|
|
1755
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
1609
1756
|
var plural = (n, s) => n === 1 ? s : s + "s";
|
|
1610
1757
|
function logForDebugging2(msg) {
|
|
1611
1758
|
if (process.env.DEBUG_KEYBINDINGS) console.error(msg);
|
|
1612
1759
|
}
|
|
1613
1760
|
var CHORD_TIMEOUT_MS = 1e3;
|
|
1614
1761
|
function KeybindingSetup({ children, onWarnings }) {
|
|
1615
|
-
const [{ bindings, warnings }, setLoadResult] = (0,
|
|
1762
|
+
const [{ bindings, warnings }, setLoadResult] = (0, import_react6.useState)(() => {
|
|
1616
1763
|
const result = loadKeybindingsSyncWithWarnings();
|
|
1617
1764
|
logForDebugging2(
|
|
1618
1765
|
`[keybindings] KeybindingSetup initialized with ${result.bindings.length} bindings, ${result.warnings.length} warnings`
|
|
1619
1766
|
);
|
|
1620
1767
|
return result;
|
|
1621
1768
|
});
|
|
1622
|
-
const [isReload, setIsReload] = (0,
|
|
1623
|
-
(0,
|
|
1769
|
+
const [isReload, setIsReload] = (0, import_react6.useState)(false);
|
|
1770
|
+
(0, import_react6.useEffect)(() => {
|
|
1624
1771
|
if (!onWarnings || warnings.length === 0) return;
|
|
1625
1772
|
const errorCount = warnings.filter((w) => w.severity === "error").length;
|
|
1626
1773
|
const warnCount = warnings.filter((w) => w.severity === "warning").length;
|
|
@@ -1634,29 +1781,29 @@ function KeybindingSetup({ children, onWarnings }) {
|
|
|
1634
1781
|
}
|
|
1635
1782
|
onWarnings(message + " \xB7 /doctor for details", errorCount > 0);
|
|
1636
1783
|
}, [warnings, isReload, onWarnings]);
|
|
1637
|
-
const pendingChordRef = (0,
|
|
1638
|
-
const [pendingChord, setPendingChordState] = (0,
|
|
1639
|
-
const chordTimeoutRef = (0,
|
|
1640
|
-
const handlerRegistryRef = (0,
|
|
1784
|
+
const pendingChordRef = (0, import_react6.useRef)(null);
|
|
1785
|
+
const [pendingChord, setPendingChordState] = (0, import_react6.useState)(null);
|
|
1786
|
+
const chordTimeoutRef = (0, import_react6.useRef)(null);
|
|
1787
|
+
const handlerRegistryRef = (0, import_react6.useRef)(
|
|
1641
1788
|
/* @__PURE__ */ new Map()
|
|
1642
1789
|
);
|
|
1643
|
-
const activeContextsRef = (0,
|
|
1644
|
-
const registerActiveContext = (0,
|
|
1790
|
+
const activeContextsRef = (0, import_react6.useRef)(/* @__PURE__ */ new Set());
|
|
1791
|
+
const registerActiveContext = (0, import_react6.useCallback)((context) => {
|
|
1645
1792
|
activeContextsRef.current.add(context);
|
|
1646
1793
|
}, []);
|
|
1647
|
-
const unregisterActiveContext = (0,
|
|
1794
|
+
const unregisterActiveContext = (0, import_react6.useCallback)(
|
|
1648
1795
|
(context) => {
|
|
1649
1796
|
activeContextsRef.current.delete(context);
|
|
1650
1797
|
},
|
|
1651
1798
|
[]
|
|
1652
1799
|
);
|
|
1653
|
-
const clearChordTimeout = (0,
|
|
1800
|
+
const clearChordTimeout = (0, import_react6.useCallback)(() => {
|
|
1654
1801
|
if (chordTimeoutRef.current) {
|
|
1655
1802
|
clearTimeout(chordTimeoutRef.current);
|
|
1656
1803
|
chordTimeoutRef.current = null;
|
|
1657
1804
|
}
|
|
1658
1805
|
}, []);
|
|
1659
|
-
const setPendingChord = (0,
|
|
1806
|
+
const setPendingChord = (0, import_react6.useCallback)(
|
|
1660
1807
|
(pending) => {
|
|
1661
1808
|
clearChordTimeout();
|
|
1662
1809
|
if (pending !== null) {
|
|
@@ -1671,7 +1818,7 @@ function KeybindingSetup({ children, onWarnings }) {
|
|
|
1671
1818
|
},
|
|
1672
1819
|
[clearChordTimeout]
|
|
1673
1820
|
);
|
|
1674
|
-
(0,
|
|
1821
|
+
(0, import_react6.useEffect)(() => {
|
|
1675
1822
|
void initializeKeybindingWatcher();
|
|
1676
1823
|
const unsubscribe = subscribeToKeybindingChanges((result) => {
|
|
1677
1824
|
setIsReload(true);
|
|
@@ -1685,7 +1832,7 @@ function KeybindingSetup({ children, onWarnings }) {
|
|
|
1685
1832
|
clearChordTimeout();
|
|
1686
1833
|
};
|
|
1687
1834
|
}, [clearChordTimeout]);
|
|
1688
|
-
return /* @__PURE__ */ (0,
|
|
1835
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
1689
1836
|
KeybindingProvider,
|
|
1690
1837
|
{
|
|
1691
1838
|
bindings,
|
|
@@ -1697,7 +1844,7 @@ function KeybindingSetup({ children, onWarnings }) {
|
|
|
1697
1844
|
unregisterActiveContext,
|
|
1698
1845
|
handlerRegistryRef,
|
|
1699
1846
|
children: [
|
|
1700
|
-
/* @__PURE__ */ (0,
|
|
1847
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1701
1848
|
ChordInterceptor,
|
|
1702
1849
|
{
|
|
1703
1850
|
bindings,
|
|
@@ -1719,7 +1866,7 @@ function ChordInterceptor({
|
|
|
1719
1866
|
activeContexts,
|
|
1720
1867
|
handlerRegistryRef
|
|
1721
1868
|
}) {
|
|
1722
|
-
const handleInput = (0,
|
|
1869
|
+
const handleInput = (0, import_react6.useCallback)(
|
|
1723
1870
|
(input, key, event) => {
|
|
1724
1871
|
if ((key.wheelUp || key.wheelDown) && pendingChordRef.current === null) {
|
|
1725
1872
|
return;
|
|
@@ -1783,28 +1930,28 @@ function ChordInterceptor({
|
|
|
1783
1930
|
},
|
|
1784
1931
|
[bindings, pendingChordRef, setPendingChord, activeContexts, handlerRegistryRef]
|
|
1785
1932
|
);
|
|
1786
|
-
(0,
|
|
1933
|
+
(0, import_ink_renderer7.useInput)(handleInput);
|
|
1787
1934
|
return null;
|
|
1788
1935
|
}
|
|
1789
1936
|
|
|
1790
1937
|
// src/hooks/useDoublePress.ts
|
|
1791
|
-
var
|
|
1938
|
+
var import_react7 = require("react");
|
|
1792
1939
|
var DOUBLE_PRESS_TIMEOUT_MS = 800;
|
|
1793
1940
|
function useDoublePress(setPending, onDoublePress, onFirstPress) {
|
|
1794
|
-
const lastPressRef = (0,
|
|
1795
|
-
const timeoutRef = (0,
|
|
1796
|
-
const clearTimeoutSafe = (0,
|
|
1941
|
+
const lastPressRef = (0, import_react7.useRef)(0);
|
|
1942
|
+
const timeoutRef = (0, import_react7.useRef)(void 0);
|
|
1943
|
+
const clearTimeoutSafe = (0, import_react7.useCallback)(() => {
|
|
1797
1944
|
if (timeoutRef.current) {
|
|
1798
1945
|
clearTimeout(timeoutRef.current);
|
|
1799
1946
|
timeoutRef.current = void 0;
|
|
1800
1947
|
}
|
|
1801
1948
|
}, []);
|
|
1802
|
-
(0,
|
|
1949
|
+
(0, import_react7.useEffect)(() => {
|
|
1803
1950
|
return () => {
|
|
1804
1951
|
clearTimeoutSafe();
|
|
1805
1952
|
};
|
|
1806
1953
|
}, [clearTimeoutSafe]);
|
|
1807
|
-
return (0,
|
|
1954
|
+
return (0, import_react7.useCallback)(() => {
|
|
1808
1955
|
const now = Date.now();
|
|
1809
1956
|
const timeSinceLastPress = now - lastPressRef.current;
|
|
1810
1957
|
const isDoublePress = timeSinceLastPress <= DOUBLE_PRESS_TIMEOUT_MS && timeoutRef.current !== void 0;
|
|
@@ -1831,10 +1978,10 @@ function useDoublePress(setPending, onDoublePress, onFirstPress) {
|
|
|
1831
1978
|
}
|
|
1832
1979
|
|
|
1833
1980
|
// src/hooks/useTerminalSize.ts
|
|
1834
|
-
var
|
|
1835
|
-
var
|
|
1981
|
+
var import_react8 = require("react");
|
|
1982
|
+
var import_ink_renderer8 = require("@claude-code-kit/ink-renderer");
|
|
1836
1983
|
function useTerminalSize() {
|
|
1837
|
-
const size = (0,
|
|
1984
|
+
const size = (0, import_react8.useContext)(import_ink_renderer8.TerminalSizeContext);
|
|
1838
1985
|
if (!size) {
|
|
1839
1986
|
throw new Error("useTerminalSize must be used within an Ink App component");
|
|
1840
1987
|
}
|
|
@@ -1842,9 +1989,43 @@ function useTerminalSize() {
|
|
|
1842
1989
|
}
|
|
1843
1990
|
|
|
1844
1991
|
// src/PromptInput.tsx
|
|
1845
|
-
var
|
|
1846
|
-
var
|
|
1847
|
-
|
|
1992
|
+
var import_react9 = require("react");
|
|
1993
|
+
var import_ink_renderer9 = require("@claude-code-kit/ink-renderer");
|
|
1994
|
+
|
|
1995
|
+
// src/utils/promptInputLogic.ts
|
|
1996
|
+
function wordFwd(s, p) {
|
|
1997
|
+
let i = p;
|
|
1998
|
+
while (i < s.length && s[i] !== " ") i++;
|
|
1999
|
+
while (i < s.length && s[i] === " ") i++;
|
|
2000
|
+
return i;
|
|
2001
|
+
}
|
|
2002
|
+
function wordBwd(s, p) {
|
|
2003
|
+
let i = p;
|
|
2004
|
+
if (i > 0) i--;
|
|
2005
|
+
while (i > 0 && s[i] === " ") i--;
|
|
2006
|
+
while (i > 0 && s[i - 1] !== " ") i--;
|
|
2007
|
+
return i;
|
|
2008
|
+
}
|
|
2009
|
+
function lineOffset(lines, line) {
|
|
2010
|
+
let pos = 0;
|
|
2011
|
+
for (let i = 0; i < line; i++) pos += lines[i].length + 1;
|
|
2012
|
+
return pos;
|
|
2013
|
+
}
|
|
2014
|
+
function cursorLineIndex(lines, cursor) {
|
|
2015
|
+
let pos = 0;
|
|
2016
|
+
for (let i = 0; i < lines.length; i++) {
|
|
2017
|
+
if (cursor <= pos + lines[i].length) return i;
|
|
2018
|
+
pos += lines[i].length + 1;
|
|
2019
|
+
}
|
|
2020
|
+
return lines.length - 1;
|
|
2021
|
+
}
|
|
2022
|
+
function filterCommands(commands, value) {
|
|
2023
|
+
if (!value.startsWith("/")) return [];
|
|
2024
|
+
return commands.filter((cmd) => `/${cmd.name}`.startsWith(value));
|
|
2025
|
+
}
|
|
2026
|
+
|
|
2027
|
+
// src/PromptInput.tsx
|
|
2028
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
1848
2029
|
function PromptInput({
|
|
1849
2030
|
value,
|
|
1850
2031
|
onChange,
|
|
@@ -1855,186 +2036,302 @@ function PromptInput({
|
|
|
1855
2036
|
disabled = false,
|
|
1856
2037
|
commands = [],
|
|
1857
2038
|
onCommandSelect,
|
|
1858
|
-
history = []
|
|
2039
|
+
history = [],
|
|
2040
|
+
vimMode = false,
|
|
2041
|
+
multiline = false
|
|
1859
2042
|
}) {
|
|
1860
|
-
const [cursor, setCursor] = (0,
|
|
1861
|
-
const [historyIndex, setHistoryIndex] = (0,
|
|
1862
|
-
const [suggestionIndex, setSuggestionIndex] = (0,
|
|
1863
|
-
const [showSuggestions, setShowSuggestions] = (0,
|
|
1864
|
-
const
|
|
2043
|
+
const [cursor, setCursor] = (0, import_react9.useState)(0);
|
|
2044
|
+
const [historyIndex, setHistoryIndex] = (0, import_react9.useState)(-1);
|
|
2045
|
+
const [suggestionIndex, setSuggestionIndex] = (0, import_react9.useState)(0);
|
|
2046
|
+
const [showSuggestions, setShowSuggestions] = (0, import_react9.useState)(false);
|
|
2047
|
+
const [vim, setVim] = (0, import_react9.useState)("INSERT");
|
|
2048
|
+
const [pendingD, setPendingD] = (0, import_react9.useState)(false);
|
|
2049
|
+
const isVimNormal = vimMode && vim === "NORMAL";
|
|
2050
|
+
const suggestions = commands.length > 0 ? filterCommands(commands, value) : [];
|
|
1865
2051
|
const hasSuggestions = showSuggestions && suggestions.length > 0;
|
|
1866
|
-
const
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
2052
|
+
const lines = multiline ? value.split("\n") : [value];
|
|
2053
|
+
const cursorLine = multiline ? cursorLineIndex(lines, cursor) : 0;
|
|
2054
|
+
const lineOffset2 = (line) => lineOffset(lines, line);
|
|
2055
|
+
const updateValue = (0, import_react9.useCallback)((nv, nc) => {
|
|
2056
|
+
onChange(nv);
|
|
2057
|
+
setCursor(nc ?? nv.length);
|
|
2058
|
+
setHistoryIndex(-1);
|
|
2059
|
+
setShowSuggestions(nv.startsWith("/"));
|
|
2060
|
+
setSuggestionIndex(0);
|
|
2061
|
+
}, [onChange]);
|
|
2062
|
+
const insertNewline = () => {
|
|
2063
|
+
updateValue(value.slice(0, cursor) + "\n" + value.slice(cursor), cursor + 1);
|
|
2064
|
+
};
|
|
2065
|
+
const moveLine = (dir) => {
|
|
2066
|
+
const target = cursorLine + dir;
|
|
2067
|
+
if (multiline && target >= 0 && target < lines.length) {
|
|
2068
|
+
const col = cursor - lineOffset2(cursorLine);
|
|
2069
|
+
setCursor(lineOffset2(target) + Math.min(col, lines[target].length));
|
|
2070
|
+
return true;
|
|
2071
|
+
}
|
|
2072
|
+
return false;
|
|
2073
|
+
};
|
|
2074
|
+
const historyUp = () => {
|
|
2075
|
+
if (history.length > 0 && historyIndex + 1 < history.length) {
|
|
2076
|
+
const ni = historyIndex + 1;
|
|
2077
|
+
setHistoryIndex(ni);
|
|
2078
|
+
const hv = history[ni];
|
|
2079
|
+
onChange(hv);
|
|
2080
|
+
setCursor(hv.length);
|
|
2081
|
+
}
|
|
2082
|
+
};
|
|
2083
|
+
const historyDown = () => {
|
|
2084
|
+
if (historyIndex > 0) {
|
|
2085
|
+
const ni = historyIndex - 1;
|
|
2086
|
+
setHistoryIndex(ni);
|
|
2087
|
+
const hv = history[ni];
|
|
2088
|
+
onChange(hv);
|
|
2089
|
+
setCursor(hv.length);
|
|
2090
|
+
} else if (historyIndex === 0) {
|
|
1870
2091
|
setHistoryIndex(-1);
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
}
|
|
1874
|
-
|
|
1875
|
-
)
|
|
1876
|
-
|
|
1877
|
-
(
|
|
1878
|
-
if (
|
|
1879
|
-
if (
|
|
1880
|
-
|
|
1881
|
-
const cmd = suggestions[suggestionIndex];
|
|
1882
|
-
const cmdValue = `/${cmd.name}`;
|
|
1883
|
-
onCommandSelect?.(cmd.name);
|
|
1884
|
-
onChange(cmdValue);
|
|
1885
|
-
setCursor(cmdValue.length);
|
|
1886
|
-
setShowSuggestions(false);
|
|
1887
|
-
return;
|
|
1888
|
-
}
|
|
1889
|
-
if (value.length > 0) {
|
|
1890
|
-
onSubmit(value);
|
|
1891
|
-
}
|
|
2092
|
+
onChange("");
|
|
2093
|
+
setCursor(0);
|
|
2094
|
+
}
|
|
2095
|
+
};
|
|
2096
|
+
(0, import_ink_renderer9.useInput)((input, key) => {
|
|
2097
|
+
if (disabled) return;
|
|
2098
|
+
if (isVimNormal) {
|
|
2099
|
+
if (input !== "d") setPendingD(false);
|
|
2100
|
+
if (input === "i") {
|
|
2101
|
+
setVim("INSERT");
|
|
1892
2102
|
return;
|
|
1893
2103
|
}
|
|
1894
|
-
if (
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
}
|
|
2104
|
+
if (input === "a") {
|
|
2105
|
+
setVim("INSERT");
|
|
2106
|
+
setCursor((c) => Math.min(value.length, c + 1));
|
|
1898
2107
|
return;
|
|
1899
2108
|
}
|
|
1900
|
-
if (key.
|
|
1901
|
-
|
|
1902
|
-
const cmd = suggestions[suggestionIndex];
|
|
1903
|
-
const cmdValue = `/${cmd.name} `;
|
|
1904
|
-
updateValue(cmdValue);
|
|
1905
|
-
}
|
|
2109
|
+
if (input === "h" || key.leftArrow) {
|
|
2110
|
+
setCursor((c) => Math.max(0, c - 1));
|
|
1906
2111
|
return;
|
|
1907
2112
|
}
|
|
1908
|
-
if (key.
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
2113
|
+
if (input === "l" || key.rightArrow) {
|
|
2114
|
+
setCursor((c) => Math.min(Math.max(0, value.length - 1), c + 1));
|
|
2115
|
+
return;
|
|
2116
|
+
}
|
|
2117
|
+
if (input === "0" || key.home) {
|
|
2118
|
+
setCursor(multiline ? lineOffset2(cursorLine) : 0);
|
|
2119
|
+
return;
|
|
2120
|
+
}
|
|
2121
|
+
if (input === "$" || key.end) {
|
|
2122
|
+
if (multiline) {
|
|
2123
|
+
const endOfLine = lineOffset2(cursorLine) + lines[cursorLine].length;
|
|
2124
|
+
setCursor(Math.max(lineOffset2(cursorLine), endOfLine - 1));
|
|
2125
|
+
} else {
|
|
2126
|
+
setCursor(Math.max(0, value.length - 1));
|
|
1912
2127
|
}
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
2128
|
+
return;
|
|
2129
|
+
}
|
|
2130
|
+
if (input === "w") {
|
|
2131
|
+
setCursor(wordFwd(value, cursor));
|
|
2132
|
+
return;
|
|
2133
|
+
}
|
|
2134
|
+
if (input === "b") {
|
|
2135
|
+
setCursor(wordBwd(value, cursor));
|
|
2136
|
+
return;
|
|
2137
|
+
}
|
|
2138
|
+
if (input === "x") {
|
|
2139
|
+
if (cursor < value.length) {
|
|
2140
|
+
const nv = value.slice(0, cursor) + value.slice(cursor + 1);
|
|
2141
|
+
updateValue(nv, Math.min(cursor, Math.max(0, nv.length - 1)));
|
|
1921
2142
|
}
|
|
1922
2143
|
return;
|
|
1923
2144
|
}
|
|
1924
|
-
if (
|
|
1925
|
-
if (
|
|
1926
|
-
|
|
2145
|
+
if (input === "d") {
|
|
2146
|
+
if (!pendingD) {
|
|
2147
|
+
setPendingD(true);
|
|
1927
2148
|
return;
|
|
1928
2149
|
}
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
const
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
2150
|
+
setPendingD(false);
|
|
2151
|
+
if (multiline && lines.length > 1) {
|
|
2152
|
+
const pos = lineOffset2(cursorLine);
|
|
2153
|
+
const end = pos + lines[cursorLine].length;
|
|
2154
|
+
const from = cursorLine === 0 ? pos : pos - 1;
|
|
2155
|
+
const to = cursorLine === 0 ? Math.min(end + 1, value.length) : end;
|
|
2156
|
+
const nv = value.slice(0, from) + value.slice(to);
|
|
2157
|
+
updateValue(nv, Math.min(from, Math.max(0, nv.length - 1)));
|
|
2158
|
+
} else {
|
|
2159
|
+
updateValue("", 0);
|
|
1939
2160
|
}
|
|
1940
2161
|
return;
|
|
1941
2162
|
}
|
|
1942
|
-
if (key.
|
|
1943
|
-
|
|
2163
|
+
if (key.upArrow || input === "k" && !key.ctrl) {
|
|
2164
|
+
if (!moveLine(-1)) historyUp();
|
|
1944
2165
|
return;
|
|
1945
2166
|
}
|
|
1946
|
-
if (key.
|
|
1947
|
-
|
|
2167
|
+
if (key.downArrow || input === "j" && !key.ctrl) {
|
|
2168
|
+
if (!moveLine(1)) historyDown();
|
|
2169
|
+
return;
|
|
2170
|
+
}
|
|
2171
|
+
if (key.return && value.length > 0) {
|
|
2172
|
+
onSubmit(value);
|
|
1948
2173
|
return;
|
|
1949
2174
|
}
|
|
1950
|
-
|
|
1951
|
-
|
|
2175
|
+
return;
|
|
2176
|
+
}
|
|
2177
|
+
if (key.return) {
|
|
2178
|
+
if (hasSuggestions) {
|
|
2179
|
+
const cmd = suggestions[suggestionIndex];
|
|
2180
|
+
const cv = `/${cmd.name}`;
|
|
2181
|
+
onCommandSelect?.(cmd.name);
|
|
2182
|
+
onChange(cv);
|
|
2183
|
+
setCursor(cv.length);
|
|
2184
|
+
setShowSuggestions(false);
|
|
1952
2185
|
return;
|
|
1953
2186
|
}
|
|
1954
|
-
if (
|
|
1955
|
-
|
|
2187
|
+
if (multiline && key.shift) {
|
|
2188
|
+
insertNewline();
|
|
1956
2189
|
return;
|
|
1957
2190
|
}
|
|
1958
|
-
if (
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
updateValue(newValue, i);
|
|
1965
|
-
}
|
|
2191
|
+
if (value.length > 0) onSubmit(value);
|
|
2192
|
+
return;
|
|
2193
|
+
}
|
|
2194
|
+
if (key.escape) {
|
|
2195
|
+
if (hasSuggestions) {
|
|
2196
|
+
setShowSuggestions(false);
|
|
1966
2197
|
return;
|
|
1967
2198
|
}
|
|
1968
|
-
if (
|
|
1969
|
-
|
|
1970
|
-
updateValue(newValue, 0);
|
|
2199
|
+
if (vimMode) {
|
|
2200
|
+
setVim("NORMAL");
|
|
1971
2201
|
return;
|
|
1972
2202
|
}
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
2203
|
+
return;
|
|
2204
|
+
}
|
|
2205
|
+
if (multiline && key.ctrl && input === "j") {
|
|
2206
|
+
insertNewline();
|
|
2207
|
+
return;
|
|
2208
|
+
}
|
|
2209
|
+
if (key.tab) {
|
|
2210
|
+
if (hasSuggestions) {
|
|
2211
|
+
updateValue(`/${suggestions[suggestionIndex].name} `);
|
|
2212
|
+
}
|
|
2213
|
+
;
|
|
2214
|
+
return;
|
|
2215
|
+
}
|
|
2216
|
+
if (key.upArrow) {
|
|
2217
|
+
if (hasSuggestions) {
|
|
2218
|
+
setSuggestionIndex((i) => i > 0 ? i - 1 : suggestions.length - 1);
|
|
1978
2219
|
return;
|
|
1979
2220
|
}
|
|
1980
|
-
if (
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
2221
|
+
if (!moveLine(-1)) historyUp();
|
|
2222
|
+
return;
|
|
2223
|
+
}
|
|
2224
|
+
if (key.downArrow) {
|
|
2225
|
+
if (hasSuggestions) {
|
|
2226
|
+
setSuggestionIndex((i) => i < suggestions.length - 1 ? i + 1 : 0);
|
|
1985
2227
|
return;
|
|
1986
2228
|
}
|
|
1987
|
-
if (
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
2229
|
+
if (!moveLine(1)) historyDown();
|
|
2230
|
+
return;
|
|
2231
|
+
}
|
|
2232
|
+
if (key.leftArrow) {
|
|
2233
|
+
setCursor((c) => Math.max(0, c - 1));
|
|
2234
|
+
return;
|
|
2235
|
+
}
|
|
2236
|
+
if (key.rightArrow) {
|
|
2237
|
+
setCursor((c) => Math.min(value.length, c + 1));
|
|
2238
|
+
return;
|
|
2239
|
+
}
|
|
2240
|
+
if (key.home || key.ctrl && input === "a") {
|
|
2241
|
+
setCursor(0);
|
|
2242
|
+
return;
|
|
2243
|
+
}
|
|
2244
|
+
if (key.end || key.ctrl && input === "e") {
|
|
2245
|
+
setCursor(value.length);
|
|
2246
|
+
return;
|
|
2247
|
+
}
|
|
2248
|
+
if (key.ctrl && input === "w") {
|
|
2249
|
+
if (cursor > 0) {
|
|
2250
|
+
let i = cursor - 1;
|
|
2251
|
+
while (i > 0 && value[i - 1] === " ") i--;
|
|
2252
|
+
while (i > 0 && value[i - 1] !== " ") i--;
|
|
2253
|
+
updateValue(value.slice(0, i) + value.slice(cursor), i);
|
|
1991
2254
|
}
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
return
|
|
1998
|
-
|
|
1999
|
-
|
|
2255
|
+
;
|
|
2256
|
+
return;
|
|
2257
|
+
}
|
|
2258
|
+
if (key.ctrl && input === "u") {
|
|
2259
|
+
updateValue(value.slice(cursor), 0);
|
|
2260
|
+
return;
|
|
2261
|
+
}
|
|
2262
|
+
if (key.backspace) {
|
|
2263
|
+
if (cursor > 0) updateValue(value.slice(0, cursor - 1) + value.slice(cursor), cursor - 1);
|
|
2264
|
+
return;
|
|
2265
|
+
}
|
|
2266
|
+
if (key.delete) {
|
|
2267
|
+
if (cursor < value.length) updateValue(value.slice(0, cursor) + value.slice(cursor + 1), cursor);
|
|
2268
|
+
return;
|
|
2269
|
+
}
|
|
2270
|
+
if (key.ctrl || key.meta) return;
|
|
2271
|
+
if (input.length > 0) updateValue(value.slice(0, cursor) + input + value.slice(cursor), cursor + input.length);
|
|
2272
|
+
}, { isActive: !disabled });
|
|
2273
|
+
const renderCursor = (text, cur) => {
|
|
2274
|
+
if (text.length === 0 && placeholder && cursor === 0) {
|
|
2275
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_ink_renderer9.Text, { children: [
|
|
2276
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_ink_renderer9.Text, { inverse: true, children: " " }),
|
|
2277
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_ink_renderer9.Text, { dimColor: true, children: placeholder })
|
|
2000
2278
|
] });
|
|
2001
2279
|
}
|
|
2002
|
-
const before =
|
|
2003
|
-
const
|
|
2004
|
-
const after =
|
|
2005
|
-
return /* @__PURE__ */ (0,
|
|
2280
|
+
const before = text.slice(0, cur);
|
|
2281
|
+
const at = cur < text.length ? text[cur] : " ";
|
|
2282
|
+
const after = cur < text.length ? text.slice(cur + 1) : "";
|
|
2283
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_ink_renderer9.Text, { children: [
|
|
2006
2284
|
before,
|
|
2007
|
-
/* @__PURE__ */ (0,
|
|
2285
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_ink_renderer9.Text, { inverse: true, children: at }),
|
|
2008
2286
|
after
|
|
2009
2287
|
] });
|
|
2010
2288
|
};
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
/* @__PURE__ */ (0,
|
|
2029
|
-
|
|
2289
|
+
const vimTag = vimMode ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_ink_renderer9.Text, { dimColor: true, children: ` -- ${vim} --` }) : null;
|
|
2290
|
+
const renderContent = () => {
|
|
2291
|
+
if (!multiline || lines.length <= 1) {
|
|
2292
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_ink_renderer9.Box, { children: [
|
|
2293
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_ink_renderer9.Text, { color: prefixColor, children: [
|
|
2294
|
+
prefix,
|
|
2295
|
+
" "
|
|
2296
|
+
] }),
|
|
2297
|
+
renderCursor(value, cursor),
|
|
2298
|
+
vimTag
|
|
2299
|
+
] });
|
|
2300
|
+
}
|
|
2301
|
+
let off = 0;
|
|
2302
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_ink_renderer9.Box, { flexDirection: "column", children: lines.map((line, i) => {
|
|
2303
|
+
const ls = off;
|
|
2304
|
+
off += line.length + 1;
|
|
2305
|
+
const active = i === cursorLine;
|
|
2306
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_ink_renderer9.Box, { children: [
|
|
2307
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_ink_renderer9.Text, { color: prefixColor, children: i === 0 ? `${prefix} ` : "\u2219 " }),
|
|
2308
|
+
active ? renderCursor(line, cursor - ls) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_ink_renderer9.Text, { children: line }),
|
|
2309
|
+
i === lines.length - 1 && vimTag
|
|
2310
|
+
] }, i);
|
|
2311
|
+
}) });
|
|
2312
|
+
};
|
|
2313
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_ink_renderer9.Box, { flexDirection: "column", children: [
|
|
2314
|
+
renderContent(),
|
|
2315
|
+
hasSuggestions && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_ink_renderer9.Box, { flexDirection: "column", marginLeft: 2, children: suggestions.map((cmd, i) => {
|
|
2316
|
+
const isFocused = i === suggestionIndex;
|
|
2317
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_ink_renderer9.Box, { children: [
|
|
2318
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_ink_renderer9.Text, { color: isFocused ? "cyan" : void 0, children: [
|
|
2319
|
+
isFocused ? "\u276F" : " ",
|
|
2320
|
+
" "
|
|
2321
|
+
] }),
|
|
2322
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_ink_renderer9.Text, { color: isFocused ? "cyan" : void 0, bold: isFocused, children: `/${cmd.name}` }),
|
|
2323
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_ink_renderer9.Text, { dimColor: true, children: ` ${cmd.description}` })
|
|
2324
|
+
] }, cmd.name);
|
|
2325
|
+
}) })
|
|
2030
2326
|
] });
|
|
2031
2327
|
}
|
|
2032
2328
|
|
|
2033
2329
|
// src/Spinner.tsx
|
|
2034
|
-
var
|
|
2035
|
-
var
|
|
2036
|
-
var
|
|
2037
|
-
var
|
|
2330
|
+
var import_react10 = require("react");
|
|
2331
|
+
var import_ink_renderer10 = require("@claude-code-kit/ink-renderer");
|
|
2332
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
2333
|
+
var DEFAULT_CHARACTERS = process.platform === "darwin" ? ["\xB7", "\u2722", "\u2733", "\u2736", "\u273B", "\u273D"] : ["\xB7", "\u2722", "*", "\u2736", "\u273B", "\u273D"];
|
|
2334
|
+
var FRAMES = [...DEFAULT_CHARACTERS, ...[...DEFAULT_CHARACTERS].reverse()];
|
|
2038
2335
|
var SPINNER_INTERVAL = 80;
|
|
2039
2336
|
var VERB_ROTATE_INTERVAL = 4e3;
|
|
2040
2337
|
var ELAPSED_SHOW_AFTER = 1e3;
|
|
@@ -2046,19 +2343,19 @@ function Spinner({
|
|
|
2046
2343
|
color: color2 = DEFAULT_COLOR,
|
|
2047
2344
|
showElapsed = true
|
|
2048
2345
|
}) {
|
|
2049
|
-
const [frameIndex, setFrameIndex] = (0,
|
|
2050
|
-
const [verbIndex, setVerbIndex] = (0,
|
|
2051
|
-
const [elapsed, setElapsed] = (0,
|
|
2052
|
-
const startRef = (0,
|
|
2346
|
+
const [frameIndex, setFrameIndex] = (0, import_react10.useState)(0);
|
|
2347
|
+
const [verbIndex, setVerbIndex] = (0, import_react10.useState)(0);
|
|
2348
|
+
const [elapsed, setElapsed] = (0, import_react10.useState)(0);
|
|
2349
|
+
const startRef = (0, import_react10.useRef)(Date.now());
|
|
2053
2350
|
const allVerbs = verbs ?? (verb ? [verb] : ["Thinking"]);
|
|
2054
|
-
(0,
|
|
2351
|
+
(0, import_react10.useEffect)(() => {
|
|
2055
2352
|
const id = setInterval(() => {
|
|
2056
2353
|
setFrameIndex((i) => (i + 1) % FRAMES.length);
|
|
2057
2354
|
setElapsed(Date.now() - startRef.current);
|
|
2058
2355
|
}, SPINNER_INTERVAL);
|
|
2059
2356
|
return () => clearInterval(id);
|
|
2060
2357
|
}, []);
|
|
2061
|
-
(0,
|
|
2358
|
+
(0, import_react10.useEffect)(() => {
|
|
2062
2359
|
if (allVerbs.length <= 1) return;
|
|
2063
2360
|
const id = setInterval(() => {
|
|
2064
2361
|
setVerbIndex((i) => (i + 1) % allVerbs.length);
|
|
@@ -2069,18 +2366,18 @@ function Spinner({
|
|
|
2069
2366
|
const currentVerb = allVerbs[verbIndex % allVerbs.length];
|
|
2070
2367
|
const elapsedSec = Math.floor(elapsed / 1e3);
|
|
2071
2368
|
const showTime = showElapsed && elapsed >= ELAPSED_SHOW_AFTER;
|
|
2072
|
-
return /* @__PURE__ */ (0,
|
|
2073
|
-
/* @__PURE__ */ (0,
|
|
2074
|
-
/* @__PURE__ */ (0,
|
|
2369
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_ink_renderer10.Box, { children: [
|
|
2370
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_ink_renderer10.Text, { color: color2, children: frame }),
|
|
2371
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_ink_renderer10.Text, { children: [
|
|
2075
2372
|
" ",
|
|
2076
2373
|
currentVerb,
|
|
2077
2374
|
"..."
|
|
2078
2375
|
] }),
|
|
2079
|
-
label && /* @__PURE__ */ (0,
|
|
2376
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_ink_renderer10.Text, { children: [
|
|
2080
2377
|
" ",
|
|
2081
2378
|
label
|
|
2082
2379
|
] }),
|
|
2083
|
-
showTime && /* @__PURE__ */ (0,
|
|
2380
|
+
showTime && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_ink_renderer10.Text, { dimColor: true, children: [
|
|
2084
2381
|
" (",
|
|
2085
2382
|
elapsedSec,
|
|
2086
2383
|
"s)"
|
|
@@ -2090,12 +2387,12 @@ function Spinner({
|
|
|
2090
2387
|
|
|
2091
2388
|
// src/Markdown.tsx
|
|
2092
2389
|
var import_marked2 = require("marked");
|
|
2093
|
-
var
|
|
2094
|
-
var
|
|
2390
|
+
var import_react13 = require("react");
|
|
2391
|
+
var import_ink_renderer17 = require("@claude-code-kit/ink-renderer");
|
|
2095
2392
|
|
|
2096
2393
|
// src/design-system/ThemeProvider.tsx
|
|
2097
|
-
var
|
|
2098
|
-
var
|
|
2394
|
+
var import_react11 = require("react");
|
|
2395
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
2099
2396
|
var themes = {
|
|
2100
2397
|
dark: {
|
|
2101
2398
|
text: "#E0E0E0",
|
|
@@ -2108,7 +2405,29 @@ var themes = {
|
|
|
2108
2405
|
assistant: "#DA7756",
|
|
2109
2406
|
inactive: "#666666",
|
|
2110
2407
|
inverseText: "#1E1E1E",
|
|
2111
|
-
permission: "#5B9BD5"
|
|
2408
|
+
permission: "#5B9BD5",
|
|
2409
|
+
diffAdded: "#1a3a1a",
|
|
2410
|
+
diffRemoved: "#3a1a1a",
|
|
2411
|
+
diffAddedWord: "#2d5a2d",
|
|
2412
|
+
diffRemovedWord: "#5a2d2d",
|
|
2413
|
+
diffHeader: "#1e2d3d",
|
|
2414
|
+
userMessage: "#2B4A6F",
|
|
2415
|
+
assistantMessage: "#3D2614",
|
|
2416
|
+
systemMessage: "#2D2D2D",
|
|
2417
|
+
toolUseMessage: "#1E3A2D",
|
|
2418
|
+
permissionAllow: "#1B4332",
|
|
2419
|
+
permissionDeny: "#3B1014",
|
|
2420
|
+
permissionAlways: "#1B2F4D",
|
|
2421
|
+
focus: "#5B9BD5",
|
|
2422
|
+
selection: "#264F78",
|
|
2423
|
+
placeholder: "#555555",
|
|
2424
|
+
link: "#79B8FF",
|
|
2425
|
+
code: "#F8BFB0",
|
|
2426
|
+
codeBackground: "#2D2D2D",
|
|
2427
|
+
blockquote: "#444444",
|
|
2428
|
+
info: "#5B9BD5",
|
|
2429
|
+
spinnerColor: "#DA7756",
|
|
2430
|
+
shimmer: "#3A3A3A"
|
|
2112
2431
|
},
|
|
2113
2432
|
light: {
|
|
2114
2433
|
text: "#1E1E1E",
|
|
@@ -2121,14 +2440,106 @@ var themes = {
|
|
|
2121
2440
|
assistant: "#DA7756",
|
|
2122
2441
|
inactive: "#999999",
|
|
2123
2442
|
inverseText: "#FFFFFF",
|
|
2124
|
-
permission: "#0066CC"
|
|
2443
|
+
permission: "#0066CC",
|
|
2444
|
+
diffAdded: "#E6FFEC",
|
|
2445
|
+
diffRemoved: "#FFEBE9",
|
|
2446
|
+
diffAddedWord: "#CCFFD8",
|
|
2447
|
+
diffRemovedWord: "#FFD7D5",
|
|
2448
|
+
diffHeader: "#DDF4FF",
|
|
2449
|
+
userMessage: "#E8F0FE",
|
|
2450
|
+
assistantMessage: "#FDF2EE",
|
|
2451
|
+
systemMessage: "#F5F5F5",
|
|
2452
|
+
toolUseMessage: "#EAF5EE",
|
|
2453
|
+
permissionAllow: "#E6F4EA",
|
|
2454
|
+
permissionDeny: "#FCE8E6",
|
|
2455
|
+
permissionAlways: "#E8F0FE",
|
|
2456
|
+
focus: "#0066CC",
|
|
2457
|
+
selection: "#B3D4FF",
|
|
2458
|
+
placeholder: "#AAAAAA",
|
|
2459
|
+
link: "#0066CC",
|
|
2460
|
+
code: "#C7522A",
|
|
2461
|
+
codeBackground: "#F5F5F5",
|
|
2462
|
+
blockquote: "#EEEEEE",
|
|
2463
|
+
info: "#0066CC",
|
|
2464
|
+
spinnerColor: "#DA7756",
|
|
2465
|
+
shimmer: "#E8E8E8"
|
|
2466
|
+
},
|
|
2467
|
+
"light-high-contrast": {
|
|
2468
|
+
text: "#000000",
|
|
2469
|
+
dimText: "#595959",
|
|
2470
|
+
border: "#767676",
|
|
2471
|
+
accent: "#0000EE",
|
|
2472
|
+
success: "#006400",
|
|
2473
|
+
warning: "#7A4000",
|
|
2474
|
+
error: "#AE1818",
|
|
2475
|
+
assistant: "#B55530",
|
|
2476
|
+
inactive: "#767676",
|
|
2477
|
+
inverseText: "#FFFFFF",
|
|
2478
|
+
permission: "#0000EE",
|
|
2479
|
+
diffAdded: "#CCF0D0",
|
|
2480
|
+
diffRemoved: "#F5C6C6",
|
|
2481
|
+
diffAddedWord: "#99E0A0",
|
|
2482
|
+
diffRemovedWord: "#EBA0A0",
|
|
2483
|
+
diffHeader: "#B8DEFF",
|
|
2484
|
+
userMessage: "#C8DCFF",
|
|
2485
|
+
assistantMessage: "#FCDAC8",
|
|
2486
|
+
systemMessage: "#E0E0E0",
|
|
2487
|
+
toolUseMessage: "#C4EED0",
|
|
2488
|
+
permissionAllow: "#C4EED0",
|
|
2489
|
+
permissionDeny: "#F5C6C6",
|
|
2490
|
+
permissionAlways: "#C8DCFF",
|
|
2491
|
+
focus: "#0000EE",
|
|
2492
|
+
selection: "#80BFFF",
|
|
2493
|
+
placeholder: "#767676",
|
|
2494
|
+
link: "#0000EE",
|
|
2495
|
+
code: "#8B0000",
|
|
2496
|
+
codeBackground: "#E8E8E8",
|
|
2497
|
+
blockquote: "#D0D0D0",
|
|
2498
|
+
info: "#0000EE",
|
|
2499
|
+
spinnerColor: "#B55530",
|
|
2500
|
+
shimmer: "#D0D0D0"
|
|
2501
|
+
},
|
|
2502
|
+
"dark-dimmed": {
|
|
2503
|
+
text: "#ADBAC7",
|
|
2504
|
+
dimText: "#545D68",
|
|
2505
|
+
border: "#373E47",
|
|
2506
|
+
accent: "#539BF5",
|
|
2507
|
+
success: "#57AB5A",
|
|
2508
|
+
warning: "#C69026",
|
|
2509
|
+
error: "#E5534B",
|
|
2510
|
+
assistant: "#DA7756",
|
|
2511
|
+
inactive: "#545D68",
|
|
2512
|
+
inverseText: "#22272E",
|
|
2513
|
+
permission: "#539BF5",
|
|
2514
|
+
diffAdded: "#1B2F23",
|
|
2515
|
+
diffRemoved: "#2F1B1E",
|
|
2516
|
+
diffAddedWord: "#264D30",
|
|
2517
|
+
diffRemovedWord: "#4D2628",
|
|
2518
|
+
diffHeader: "#1C2B3A",
|
|
2519
|
+
userMessage: "#1C2B3A",
|
|
2520
|
+
assistantMessage: "#2F211A",
|
|
2521
|
+
systemMessage: "#2D333B",
|
|
2522
|
+
toolUseMessage: "#1B2B23",
|
|
2523
|
+
permissionAllow: "#1B2B23",
|
|
2524
|
+
permissionDeny: "#2F1B1E",
|
|
2525
|
+
permissionAlways: "#1C2B3A",
|
|
2526
|
+
focus: "#539BF5",
|
|
2527
|
+
selection: "#1C4066",
|
|
2528
|
+
placeholder: "#545D68",
|
|
2529
|
+
link: "#6CB6FF",
|
|
2530
|
+
code: "#F0A070",
|
|
2531
|
+
codeBackground: "#2D333B",
|
|
2532
|
+
blockquote: "#373E47",
|
|
2533
|
+
info: "#539BF5",
|
|
2534
|
+
spinnerColor: "#DA7756",
|
|
2535
|
+
shimmer: "#373E47"
|
|
2125
2536
|
}
|
|
2126
2537
|
};
|
|
2127
2538
|
function getTheme(name) {
|
|
2128
2539
|
return themes[name] ?? themes.dark;
|
|
2129
2540
|
}
|
|
2130
2541
|
var DEFAULT_THEME = "dark";
|
|
2131
|
-
var ThemeContext = (0,
|
|
2542
|
+
var ThemeContext = (0, import_react11.createContext)({
|
|
2132
2543
|
themeSetting: DEFAULT_THEME,
|
|
2133
2544
|
setThemeSetting: () => {
|
|
2134
2545
|
},
|
|
@@ -2145,11 +2556,11 @@ function ThemeProvider({
|
|
|
2145
2556
|
initialState = "dark",
|
|
2146
2557
|
onThemeSave
|
|
2147
2558
|
}) {
|
|
2148
|
-
const [themeSetting, setThemeSetting] = (0,
|
|
2149
|
-
const [previewTheme, setPreviewTheme] = (0,
|
|
2559
|
+
const [themeSetting, setThemeSetting] = (0, import_react11.useState)(initialState);
|
|
2560
|
+
const [previewTheme, setPreviewTheme] = (0, import_react11.useState)(null);
|
|
2150
2561
|
const activeSetting = previewTheme ?? themeSetting;
|
|
2151
2562
|
const currentTheme = activeSetting === "auto" ? "dark" : activeSetting;
|
|
2152
|
-
const value = (0,
|
|
2563
|
+
const value = (0, import_react11.useMemo)(
|
|
2153
2564
|
() => ({
|
|
2154
2565
|
themeSetting,
|
|
2155
2566
|
setThemeSetting: (newSetting) => {
|
|
@@ -2176,17 +2587,17 @@ function ThemeProvider({
|
|
|
2176
2587
|
}),
|
|
2177
2588
|
[themeSetting, previewTheme, currentTheme, onThemeSave]
|
|
2178
2589
|
);
|
|
2179
|
-
return /* @__PURE__ */ (0,
|
|
2590
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ThemeContext.Provider, { value, children });
|
|
2180
2591
|
}
|
|
2181
2592
|
function useTheme() {
|
|
2182
|
-
const { currentTheme, setThemeSetting } = (0,
|
|
2593
|
+
const { currentTheme, setThemeSetting } = (0, import_react11.useContext)(ThemeContext);
|
|
2183
2594
|
return [currentTheme, setThemeSetting];
|
|
2184
2595
|
}
|
|
2185
2596
|
function useThemeSetting() {
|
|
2186
|
-
return (0,
|
|
2597
|
+
return (0, import_react11.useContext)(ThemeContext).themeSetting;
|
|
2187
2598
|
}
|
|
2188
2599
|
function usePreviewTheme() {
|
|
2189
|
-
const { setPreviewTheme, savePreview, cancelPreview } = (0,
|
|
2600
|
+
const { setPreviewTheme, savePreview, cancelPreview } = (0, import_react11.useContext)(ThemeContext);
|
|
2190
2601
|
return { setPreviewTheme, savePreview, cancelPreview };
|
|
2191
2602
|
}
|
|
2192
2603
|
|
|
@@ -2194,7 +2605,8 @@ function usePreviewTheme() {
|
|
|
2194
2605
|
var cliHighlightPromise;
|
|
2195
2606
|
async function loadCliHighlight() {
|
|
2196
2607
|
try {
|
|
2197
|
-
const
|
|
2608
|
+
const mod = await import("cli-highlight");
|
|
2609
|
+
const cliHighlight = mod;
|
|
2198
2610
|
return {
|
|
2199
2611
|
highlight: cliHighlight.highlight,
|
|
2200
2612
|
supportsLanguage: cliHighlight.supportsLanguage
|
|
@@ -2227,19 +2639,19 @@ function hashContent(content) {
|
|
|
2227
2639
|
var import_chalk = __toESM(require("chalk"));
|
|
2228
2640
|
var import_marked = require("marked");
|
|
2229
2641
|
var import_strip_ansi = __toESM(require("strip-ansi"));
|
|
2230
|
-
var
|
|
2642
|
+
var import_ink_renderer12 = require("@claude-code-kit/ink-renderer");
|
|
2231
2643
|
|
|
2232
2644
|
// src/design-system/color.ts
|
|
2233
|
-
var
|
|
2645
|
+
var import_ink_renderer11 = require("@claude-code-kit/ink-renderer");
|
|
2234
2646
|
function color(c, theme, type = "foreground") {
|
|
2235
2647
|
return (text) => {
|
|
2236
2648
|
if (!c) {
|
|
2237
2649
|
return text;
|
|
2238
2650
|
}
|
|
2239
2651
|
if (c.startsWith("rgb(") || c.startsWith("#") || c.startsWith("ansi256(") || c.startsWith("ansi:")) {
|
|
2240
|
-
return (0,
|
|
2652
|
+
return (0, import_ink_renderer11.colorize)(text, c, type);
|
|
2241
2653
|
}
|
|
2242
|
-
return (0,
|
|
2654
|
+
return (0, import_ink_renderer11.colorize)(text, getTheme(theme)[c], type);
|
|
2243
2655
|
};
|
|
2244
2656
|
}
|
|
2245
2657
|
|
|
@@ -2386,9 +2798,9 @@ function formatToken(token, theme, listDepth = 0, orderedListNumber = null, pare
|
|
|
2386
2798
|
var getDisplayText = getDisplayText2;
|
|
2387
2799
|
const tableToken = token;
|
|
2388
2800
|
const columnWidths = tableToken.header.map((header, index) => {
|
|
2389
|
-
let maxWidth = (0,
|
|
2801
|
+
let maxWidth = (0, import_ink_renderer12.stringWidth)(getDisplayText2(header.tokens));
|
|
2390
2802
|
for (const row of tableToken.rows) {
|
|
2391
|
-
const cellLength = (0,
|
|
2803
|
+
const cellLength = (0, import_ink_renderer12.stringWidth)(getDisplayText2(row[index]?.tokens));
|
|
2392
2804
|
maxWidth = Math.max(maxWidth, cellLength);
|
|
2393
2805
|
}
|
|
2394
2806
|
return Math.max(maxWidth, 3);
|
|
@@ -2399,7 +2811,7 @@ function formatToken(token, theme, listDepth = 0, orderedListNumber = null, pare
|
|
|
2399
2811
|
const displayText = getDisplayText2(header.tokens);
|
|
2400
2812
|
const width = columnWidths[index];
|
|
2401
2813
|
const align = tableToken.align?.[index];
|
|
2402
|
-
tableOutput += padAligned(content, (0,
|
|
2814
|
+
tableOutput += padAligned(content, (0, import_ink_renderer12.stringWidth)(displayText), width, align) + " | ";
|
|
2403
2815
|
});
|
|
2404
2816
|
tableOutput = tableOutput.trimEnd() + EOL;
|
|
2405
2817
|
tableOutput += "|";
|
|
@@ -2415,7 +2827,7 @@ function formatToken(token, theme, listDepth = 0, orderedListNumber = null, pare
|
|
|
2415
2827
|
const displayText = getDisplayText2(cell.tokens);
|
|
2416
2828
|
const width = columnWidths[index];
|
|
2417
2829
|
const align = tableToken.align?.[index];
|
|
2418
|
-
tableOutput += padAligned(content, (0,
|
|
2830
|
+
tableOutput += padAligned(content, (0, import_ink_renderer12.stringWidth)(displayText), width, align) + " | ";
|
|
2419
2831
|
});
|
|
2420
2832
|
tableOutput = tableOutput.trimEnd() + EOL;
|
|
2421
2833
|
});
|
|
@@ -2503,13 +2915,13 @@ function padAligned(content, displayWidth, targetWidth, align) {
|
|
|
2503
2915
|
}
|
|
2504
2916
|
|
|
2505
2917
|
// src/MarkdownTable.tsx
|
|
2506
|
-
var
|
|
2918
|
+
var import_react12 = require("react");
|
|
2507
2919
|
var import_strip_ansi2 = __toESM(require("strip-ansi"));
|
|
2508
|
-
var import_ink_renderer12 = require("@claude-code-kit/ink-renderer");
|
|
2509
2920
|
var import_ink_renderer13 = require("@claude-code-kit/ink-renderer");
|
|
2510
2921
|
var import_ink_renderer14 = require("@claude-code-kit/ink-renderer");
|
|
2511
2922
|
var import_ink_renderer15 = require("@claude-code-kit/ink-renderer");
|
|
2512
|
-
var
|
|
2923
|
+
var import_ink_renderer16 = require("@claude-code-kit/ink-renderer");
|
|
2924
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
2513
2925
|
var SAFETY_MARGIN = 4;
|
|
2514
2926
|
var MIN_COLUMN_WIDTH = 3;
|
|
2515
2927
|
var MAX_ROW_LINES = 4;
|
|
@@ -2518,7 +2930,7 @@ var ANSI_BOLD_END = "\x1B[22m";
|
|
|
2518
2930
|
function wrapText(text, width, options) {
|
|
2519
2931
|
if (width <= 0) return [text];
|
|
2520
2932
|
const trimmedText = text.trimEnd();
|
|
2521
|
-
const wrapped = (0,
|
|
2933
|
+
const wrapped = (0, import_ink_renderer15.wrapAnsi)(trimmedText, width, {
|
|
2522
2934
|
hard: options?.hard ?? false,
|
|
2523
2935
|
trim: false,
|
|
2524
2936
|
wordWrap: true
|
|
@@ -2532,7 +2944,7 @@ function MarkdownTable({
|
|
|
2532
2944
|
forceWidth
|
|
2533
2945
|
}) {
|
|
2534
2946
|
const [theme] = useTheme();
|
|
2535
|
-
const terminalSize = (0,
|
|
2947
|
+
const terminalSize = (0, import_react12.useContext)(import_ink_renderer13.TerminalSizeContext);
|
|
2536
2948
|
const actualTerminalWidth = terminalSize?.columns ?? 80;
|
|
2537
2949
|
const terminalWidth = forceWidth ?? actualTerminalWidth;
|
|
2538
2950
|
function formatCell(tokens) {
|
|
@@ -2545,10 +2957,10 @@ function MarkdownTable({
|
|
|
2545
2957
|
const text = getPlainText(tokens_1);
|
|
2546
2958
|
const words = text.split(/\s+/).filter((w) => w.length > 0);
|
|
2547
2959
|
if (words.length === 0) return MIN_COLUMN_WIDTH;
|
|
2548
|
-
return Math.max(...words.map((w_0) => (0,
|
|
2960
|
+
return Math.max(...words.map((w_0) => (0, import_ink_renderer14.stringWidth)(w_0)), MIN_COLUMN_WIDTH);
|
|
2549
2961
|
}
|
|
2550
2962
|
function getIdealWidth(tokens_2) {
|
|
2551
|
-
return Math.max((0,
|
|
2963
|
+
return Math.max((0, import_ink_renderer14.stringWidth)(getPlainText(tokens_2)), MIN_COLUMN_WIDTH);
|
|
2552
2964
|
}
|
|
2553
2965
|
const minWidths = token.header.map((header, colIndex) => {
|
|
2554
2966
|
let maxMinWidth = getMinWidth(header.tokens);
|
|
@@ -2629,7 +3041,7 @@ function MarkdownTable({
|
|
|
2629
3041
|
const lineText = contentLineIdx >= 0 && contentLineIdx < lines_1.length ? lines_1[contentLineIdx] : "";
|
|
2630
3042
|
const width_0 = columnWidths[colIndex_2];
|
|
2631
3043
|
const align = isHeader ? "center" : token.align?.[colIndex_2] ?? "left";
|
|
2632
|
-
line += " " + padAligned(lineText, (0,
|
|
3044
|
+
line += " " + padAligned(lineText, (0, import_ink_renderer14.stringWidth)(lineText), width_0, align) + " \u2502";
|
|
2633
3045
|
}
|
|
2634
3046
|
result.push(line);
|
|
2635
3047
|
}
|
|
@@ -2662,7 +3074,7 @@ function MarkdownTable({
|
|
|
2662
3074
|
const label = headers[colIndex_4] || `Column ${colIndex_4 + 1}`;
|
|
2663
3075
|
const rawValue = formatCell(cell_0.tokens).trimEnd();
|
|
2664
3076
|
const value = rawValue.replace(/\n+/g, " ").replace(/\s+/g, " ").trim();
|
|
2665
|
-
const firstLineWidth = terminalWidth - (0,
|
|
3077
|
+
const firstLineWidth = terminalWidth - (0, import_ink_renderer14.stringWidth)(label) - 3;
|
|
2666
3078
|
const subsequentLineWidth = terminalWidth - wrapIndent.length - 1;
|
|
2667
3079
|
const firstPassLines = wrapText(value, Math.max(firstLineWidth, 10));
|
|
2668
3080
|
const firstLine = firstPassLines[0] || "";
|
|
@@ -2685,7 +3097,7 @@ function MarkdownTable({
|
|
|
2685
3097
|
return lines_2.join("\n");
|
|
2686
3098
|
}
|
|
2687
3099
|
if (useVerticalFormat) {
|
|
2688
|
-
return /* @__PURE__ */ (0,
|
|
3100
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_ink_renderer16.Ansi, { children: renderVerticalFormat() });
|
|
2689
3101
|
}
|
|
2690
3102
|
const tableLines = [];
|
|
2691
3103
|
tableLines.push(renderBorderLine("top"));
|
|
@@ -2698,15 +3110,15 @@ function MarkdownTable({
|
|
|
2698
3110
|
}
|
|
2699
3111
|
});
|
|
2700
3112
|
tableLines.push(renderBorderLine("bottom"));
|
|
2701
|
-
const maxLineWidth = Math.max(...tableLines.map((line_2) => (0,
|
|
3113
|
+
const maxLineWidth = Math.max(...tableLines.map((line_2) => (0, import_ink_renderer14.stringWidth)((0, import_strip_ansi2.default)(line_2))));
|
|
2702
3114
|
if (maxLineWidth > terminalWidth - SAFETY_MARGIN) {
|
|
2703
|
-
return /* @__PURE__ */ (0,
|
|
3115
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_ink_renderer16.Ansi, { children: renderVerticalFormat() });
|
|
2704
3116
|
}
|
|
2705
|
-
return /* @__PURE__ */ (0,
|
|
3117
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_ink_renderer16.Ansi, { children: tableLines.join("\n") });
|
|
2706
3118
|
}
|
|
2707
3119
|
|
|
2708
3120
|
// src/Markdown.tsx
|
|
2709
|
-
var
|
|
3121
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
2710
3122
|
var TOKEN_CACHE_MAX = 500;
|
|
2711
3123
|
var tokenCache = /* @__PURE__ */ new Map();
|
|
2712
3124
|
var MD_SYNTAX_RE = /[#*`|[>\-_~]|\n\n|^\d+\. |\n\d+\. /;
|
|
@@ -2745,13 +3157,13 @@ function cachedLexer(content) {
|
|
|
2745
3157
|
function Markdown(props) {
|
|
2746
3158
|
const settings = {};
|
|
2747
3159
|
if (settings.syntaxHighlightingDisabled) {
|
|
2748
|
-
return /* @__PURE__ */ (0,
|
|
3160
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(MarkdownBody, { ...props, highlight: null });
|
|
2749
3161
|
}
|
|
2750
|
-
return /* @__PURE__ */ (0,
|
|
3162
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react13.Suspense, { fallback: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(MarkdownBody, { ...props, highlight: null }), children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(MarkdownWithHighlight, { ...props }) });
|
|
2751
3163
|
}
|
|
2752
3164
|
function MarkdownWithHighlight(props) {
|
|
2753
|
-
const highlight = (0,
|
|
2754
|
-
return /* @__PURE__ */ (0,
|
|
3165
|
+
const highlight = (0, import_react13.use)(getCliHighlightPromise());
|
|
3166
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(MarkdownBody, { ...props, highlight });
|
|
2755
3167
|
}
|
|
2756
3168
|
function MarkdownBody({
|
|
2757
3169
|
children,
|
|
@@ -2760,14 +3172,14 @@ function MarkdownBody({
|
|
|
2760
3172
|
}) {
|
|
2761
3173
|
const [theme] = useTheme();
|
|
2762
3174
|
configureMarked();
|
|
2763
|
-
const elements = (0,
|
|
3175
|
+
const elements = (0, import_react13.useMemo)(() => {
|
|
2764
3176
|
const tokens = cachedLexer(stripPromptXMLTags(children));
|
|
2765
3177
|
const elements2 = [];
|
|
2766
3178
|
let nonTableContent = "";
|
|
2767
3179
|
function flushNonTableContent() {
|
|
2768
3180
|
if (nonTableContent) {
|
|
2769
3181
|
elements2.push(
|
|
2770
|
-
/* @__PURE__ */ (0,
|
|
3182
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_ink_renderer17.Ansi, { dimColor, children: nonTableContent.trim() }, elements2.length)
|
|
2771
3183
|
);
|
|
2772
3184
|
nonTableContent = "";
|
|
2773
3185
|
}
|
|
@@ -2776,7 +3188,7 @@ function MarkdownBody({
|
|
|
2776
3188
|
if (token.type === "table") {
|
|
2777
3189
|
flushNonTableContent();
|
|
2778
3190
|
elements2.push(
|
|
2779
|
-
/* @__PURE__ */ (0,
|
|
3191
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2780
3192
|
MarkdownTable,
|
|
2781
3193
|
{
|
|
2782
3194
|
token,
|
|
@@ -2792,7 +3204,7 @@ function MarkdownBody({
|
|
|
2792
3204
|
flushNonTableContent();
|
|
2793
3205
|
return elements2;
|
|
2794
3206
|
}, [children, dimColor, highlight, theme]);
|
|
2795
|
-
return /* @__PURE__ */ (0,
|
|
3207
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_ink_renderer17.Box, { flexDirection: "column", gap: 1, children: elements });
|
|
2796
3208
|
}
|
|
2797
3209
|
function StreamingMarkdown({
|
|
2798
3210
|
children
|
|
@@ -2800,7 +3212,7 @@ function StreamingMarkdown({
|
|
|
2800
3212
|
"use no memo";
|
|
2801
3213
|
configureMarked();
|
|
2802
3214
|
const stripped = stripPromptXMLTags(children);
|
|
2803
|
-
const stablePrefixRef = (0,
|
|
3215
|
+
const stablePrefixRef = (0, import_react13.useRef)("");
|
|
2804
3216
|
if (!stripped.startsWith(stablePrefixRef.current)) {
|
|
2805
3217
|
stablePrefixRef.current = "";
|
|
2806
3218
|
}
|
|
@@ -2819,35 +3231,35 @@ function StreamingMarkdown({
|
|
|
2819
3231
|
}
|
|
2820
3232
|
const stablePrefix = stablePrefixRef.current;
|
|
2821
3233
|
const unstableSuffix = stripped.substring(stablePrefix.length);
|
|
2822
|
-
return /* @__PURE__ */ (0,
|
|
2823
|
-
stablePrefix && /* @__PURE__ */ (0,
|
|
2824
|
-
unstableSuffix && /* @__PURE__ */ (0,
|
|
3234
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_ink_renderer17.Box, { flexDirection: "column", gap: 1, children: [
|
|
3235
|
+
stablePrefix && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Markdown, { children: stablePrefix }),
|
|
3236
|
+
unstableSuffix && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Markdown, { children: unstableSuffix })
|
|
2825
3237
|
] });
|
|
2826
3238
|
}
|
|
2827
3239
|
|
|
2828
3240
|
// src/Select.tsx
|
|
2829
|
-
var
|
|
2830
|
-
var
|
|
2831
|
-
var
|
|
3241
|
+
var import_react14 = require("react");
|
|
3242
|
+
var import_ink_renderer18 = require("@claude-code-kit/ink-renderer");
|
|
3243
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
2832
3244
|
function useListNavigation(opts) {
|
|
2833
3245
|
const { options, maxVisible, onCancel, onSelect, extraHandler } = opts;
|
|
2834
|
-
const [focusIndex, setFocusIndex] = (0,
|
|
2835
|
-
const focusRef = (0,
|
|
3246
|
+
const [focusIndex, setFocusIndex] = (0, import_react14.useState)(0);
|
|
3247
|
+
const focusRef = (0, import_react14.useRef)(focusIndex);
|
|
2836
3248
|
focusRef.current = focusIndex;
|
|
2837
3249
|
const total = options.length;
|
|
2838
3250
|
const max = maxVisible ?? total;
|
|
2839
|
-
const scrollOffset = (0,
|
|
3251
|
+
const scrollOffset = (0, import_react14.useMemo)(() => {
|
|
2840
3252
|
if (total <= max) return 0;
|
|
2841
3253
|
const half = Math.floor(max / 2);
|
|
2842
3254
|
if (focusIndex <= half) return 0;
|
|
2843
3255
|
if (focusIndex >= total - max + half) return total - max;
|
|
2844
3256
|
return focusIndex - half;
|
|
2845
3257
|
}, [focusIndex, total, max]);
|
|
2846
|
-
const visibleOptions = (0,
|
|
3258
|
+
const visibleOptions = (0, import_react14.useMemo)(
|
|
2847
3259
|
() => options.slice(scrollOffset, scrollOffset + max),
|
|
2848
3260
|
[options, scrollOffset, max]
|
|
2849
3261
|
);
|
|
2850
|
-
const moveFocus = (0,
|
|
3262
|
+
const moveFocus = (0, import_react14.useCallback)(
|
|
2851
3263
|
(dir) => {
|
|
2852
3264
|
setFocusIndex((prev) => {
|
|
2853
3265
|
let next = prev;
|
|
@@ -2860,7 +3272,7 @@ function useListNavigation(opts) {
|
|
|
2860
3272
|
},
|
|
2861
3273
|
[options, total]
|
|
2862
3274
|
);
|
|
2863
|
-
(0,
|
|
3275
|
+
(0, import_ink_renderer18.useInput)((input, key) => {
|
|
2864
3276
|
if (extraHandler?.(input, key, focusRef.current)) return;
|
|
2865
3277
|
if (key.upArrow || input === "k") {
|
|
2866
3278
|
moveFocus(-1);
|
|
@@ -2883,7 +3295,7 @@ function useListNavigation(opts) {
|
|
|
2883
3295
|
return { focusIndex, scrollOffset, visibleOptions, max, total };
|
|
2884
3296
|
}
|
|
2885
3297
|
function ScrollHint({ count, direction }) {
|
|
2886
|
-
return /* @__PURE__ */ (0,
|
|
3298
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_ink_renderer18.Text, { dimColor: true, children: [
|
|
2887
3299
|
" ",
|
|
2888
3300
|
direction === "up" ? "\u2191" : "\u2193",
|
|
2889
3301
|
" ",
|
|
@@ -2899,26 +3311,26 @@ function Select({
|
|
|
2899
3311
|
title,
|
|
2900
3312
|
maxVisible
|
|
2901
3313
|
}) {
|
|
2902
|
-
const handleSelect = (0,
|
|
3314
|
+
const handleSelect = (0, import_react14.useCallback)(
|
|
2903
3315
|
(index) => onChange(options[index].value),
|
|
2904
3316
|
[onChange, options]
|
|
2905
3317
|
);
|
|
2906
3318
|
const { focusIndex, scrollOffset, visibleOptions, max, total } = useListNavigation({ options, maxVisible, onCancel, onSelect: handleSelect });
|
|
2907
|
-
return /* @__PURE__ */ (0,
|
|
2908
|
-
title && /* @__PURE__ */ (0,
|
|
2909
|
-
scrollOffset > 0 && /* @__PURE__ */ (0,
|
|
3319
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_ink_renderer18.Box, { flexDirection: "column", children: [
|
|
3320
|
+
title && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_ink_renderer18.Box, { marginBottom: 1, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_ink_renderer18.Text, { bold: true, children: title }) }),
|
|
3321
|
+
scrollOffset > 0 && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ScrollHint, { count: scrollOffset, direction: "up" }),
|
|
2910
3322
|
visibleOptions.map((opt, i) => {
|
|
2911
3323
|
const realIndex = scrollOffset + i;
|
|
2912
3324
|
const isFocused = realIndex === focusIndex;
|
|
2913
3325
|
const isSelected = opt.value === defaultValue;
|
|
2914
3326
|
const isDisabled = opt.disabled === true;
|
|
2915
|
-
return /* @__PURE__ */ (0,
|
|
2916
|
-
/* @__PURE__ */ (0,
|
|
3327
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_ink_renderer18.Box, { children: [
|
|
3328
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_ink_renderer18.Text, { color: isFocused ? "cyan" : void 0, children: [
|
|
2917
3329
|
isFocused ? "\u276F" : " ",
|
|
2918
3330
|
" "
|
|
2919
3331
|
] }),
|
|
2920
|
-
/* @__PURE__ */ (0,
|
|
2921
|
-
|
|
3332
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
3333
|
+
import_ink_renderer18.Text,
|
|
2922
3334
|
{
|
|
2923
3335
|
color: isDisabled ? "gray" : isFocused ? "cyan" : void 0,
|
|
2924
3336
|
bold: isFocused,
|
|
@@ -2930,15 +3342,15 @@ function Select({
|
|
|
2930
3342
|
]
|
|
2931
3343
|
}
|
|
2932
3344
|
),
|
|
2933
|
-
isSelected && /* @__PURE__ */ (0,
|
|
2934
|
-
opt.description && /* @__PURE__ */ (0,
|
|
3345
|
+
isSelected && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_ink_renderer18.Text, { color: "green", children: " \u2713" }),
|
|
3346
|
+
opt.description && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_ink_renderer18.Text, { dimColor: true, children: [
|
|
2935
3347
|
" ",
|
|
2936
3348
|
opt.description
|
|
2937
3349
|
] })
|
|
2938
3350
|
] }, realIndex);
|
|
2939
3351
|
}),
|
|
2940
|
-
scrollOffset + max < total && /* @__PURE__ */ (0,
|
|
2941
|
-
/* @__PURE__ */ (0,
|
|
3352
|
+
scrollOffset + max < total && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ScrollHint, { count: total - scrollOffset - max, direction: "down" }),
|
|
3353
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_ink_renderer18.Box, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_ink_renderer18.Text, { dimColor: true, children: "Enter to confirm \xB7 Esc to exit" }) })
|
|
2942
3354
|
] });
|
|
2943
3355
|
}
|
|
2944
3356
|
function MultiSelect({
|
|
@@ -2950,12 +3362,12 @@ function MultiSelect({
|
|
|
2950
3362
|
title,
|
|
2951
3363
|
maxVisible
|
|
2952
3364
|
}) {
|
|
2953
|
-
const [selected, setSelected] = (0,
|
|
2954
|
-
const handleConfirm = (0,
|
|
3365
|
+
const [selected, setSelected] = (0, import_react14.useState)(() => new Set(selectedValues));
|
|
3366
|
+
const handleConfirm = (0, import_react14.useCallback)(
|
|
2955
3367
|
() => onConfirm(Array.from(selected)),
|
|
2956
3368
|
[onConfirm, selected]
|
|
2957
3369
|
);
|
|
2958
|
-
const handleSpace = (0,
|
|
3370
|
+
const handleSpace = (0, import_react14.useCallback)(
|
|
2959
3371
|
(input, _key, focusIndex2) => {
|
|
2960
3372
|
if (input !== " ") return false;
|
|
2961
3373
|
const opt = options[focusIndex2];
|
|
@@ -2978,21 +3390,21 @@ function MultiSelect({
|
|
|
2978
3390
|
onSelect: handleConfirm,
|
|
2979
3391
|
extraHandler: handleSpace
|
|
2980
3392
|
});
|
|
2981
|
-
return /* @__PURE__ */ (0,
|
|
2982
|
-
title && /* @__PURE__ */ (0,
|
|
2983
|
-
scrollOffset > 0 && /* @__PURE__ */ (0,
|
|
3393
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_ink_renderer18.Box, { flexDirection: "column", children: [
|
|
3394
|
+
title && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_ink_renderer18.Box, { marginBottom: 1, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_ink_renderer18.Text, { bold: true, children: title }) }),
|
|
3395
|
+
scrollOffset > 0 && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ScrollHint, { count: scrollOffset, direction: "up" }),
|
|
2984
3396
|
visibleOptions.map((opt, i) => {
|
|
2985
3397
|
const realIndex = scrollOffset + i;
|
|
2986
3398
|
const isFocused = realIndex === focusIndex;
|
|
2987
3399
|
const isChecked = selected.has(opt.value);
|
|
2988
3400
|
const isDisabled = opt.disabled === true;
|
|
2989
|
-
return /* @__PURE__ */ (0,
|
|
2990
|
-
/* @__PURE__ */ (0,
|
|
3401
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_ink_renderer18.Box, { children: [
|
|
3402
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_ink_renderer18.Text, { color: isFocused ? "cyan" : void 0, children: [
|
|
2991
3403
|
isFocused ? "\u276F" : " ",
|
|
2992
3404
|
" "
|
|
2993
3405
|
] }),
|
|
2994
|
-
/* @__PURE__ */ (0,
|
|
2995
|
-
|
|
3406
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
3407
|
+
import_ink_renderer18.Text,
|
|
2996
3408
|
{
|
|
2997
3409
|
color: isDisabled ? "gray" : isFocused ? "cyan" : void 0,
|
|
2998
3410
|
bold: isFocused,
|
|
@@ -3006,72 +3418,319 @@ function MultiSelect({
|
|
|
3006
3418
|
]
|
|
3007
3419
|
}
|
|
3008
3420
|
),
|
|
3009
|
-
opt.description && /* @__PURE__ */ (0,
|
|
3421
|
+
opt.description && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_ink_renderer18.Text, { dimColor: true, children: [
|
|
3010
3422
|
" ",
|
|
3011
3423
|
opt.description
|
|
3012
3424
|
] })
|
|
3013
3425
|
] }, realIndex);
|
|
3014
3426
|
}),
|
|
3015
|
-
scrollOffset + max < total && /* @__PURE__ */ (0,
|
|
3016
|
-
/* @__PURE__ */ (0,
|
|
3427
|
+
scrollOffset + max < total && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ScrollHint, { count: total - scrollOffset - max, direction: "down" }),
|
|
3428
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_ink_renderer18.Box, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_ink_renderer18.Text, { dimColor: true, children: "Space to toggle \xB7 Enter to confirm \xB7 Esc to exit" }) })
|
|
3017
3429
|
] });
|
|
3018
3430
|
}
|
|
3019
3431
|
|
|
3020
|
-
// src/
|
|
3021
|
-
var
|
|
3022
|
-
var
|
|
3023
|
-
var
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
|
|
3432
|
+
// src/PermissionRequest.tsx
|
|
3433
|
+
var import_react15 = __toESM(require("react"));
|
|
3434
|
+
var import_ink_renderer19 = require("@claude-code-kit/ink-renderer");
|
|
3435
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
3436
|
+
function PermissionHeader({ toolName, width }) {
|
|
3437
|
+
const label = ` ${toolName} `;
|
|
3438
|
+
const labelLen = toolName.length + 2;
|
|
3439
|
+
const leftLen = 3;
|
|
3440
|
+
const rightLen = Math.max(0, width - leftLen - labelLen);
|
|
3441
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_ink_renderer19.Text, { children: [
|
|
3442
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_ink_renderer19.Text, { dimColor: true, children: "\u2500".repeat(leftLen) }),
|
|
3443
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_ink_renderer19.Text, { bold: true, color: "cyan", children: label }),
|
|
3444
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_ink_renderer19.Text, { dimColor: true, children: "\u2500".repeat(rightLen) })
|
|
3445
|
+
] });
|
|
3446
|
+
}
|
|
3447
|
+
function HorizontalRule({ width }) {
|
|
3448
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_ink_renderer19.Text, { dimColor: true, children: "\u2500".repeat(width) });
|
|
3449
|
+
}
|
|
3450
|
+
function BashPermissionContent({ command }) {
|
|
3451
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_ink_renderer19.Box, { flexDirection: "column", children: [
|
|
3452
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_ink_renderer19.Text, { children: "Run command:" }),
|
|
3453
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_ink_renderer19.Box, { marginLeft: 2, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_ink_renderer19.Text, { color: "yellow", children: command }) })
|
|
3454
|
+
] });
|
|
3455
|
+
}
|
|
3456
|
+
function FileEditPermissionContent({
|
|
3457
|
+
filename,
|
|
3458
|
+
diff
|
|
3031
3459
|
}) {
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
const isSystem = message.role === "system";
|
|
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: [
|
|
3041
|
-
" ",
|
|
3042
|
-
config.label
|
|
3043
|
-
] })
|
|
3460
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_ink_renderer19.Box, { flexDirection: "column", children: [
|
|
3461
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_ink_renderer19.Text, { children: [
|
|
3462
|
+
"Edit file: ",
|
|
3463
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_ink_renderer19.Text, { color: "cyan", bold: true, children: filename })
|
|
3044
3464
|
] }),
|
|
3045
|
-
|
|
3465
|
+
diff && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_ink_renderer19.Box, { marginTop: 1, flexDirection: "column", children: diff.split("\n").map((line, i) => {
|
|
3466
|
+
let color2;
|
|
3467
|
+
if (line.startsWith("+")) color2 = "green";
|
|
3468
|
+
else if (line.startsWith("-")) color2 = "red";
|
|
3469
|
+
else if (line.startsWith("@")) color2 = "cyan";
|
|
3470
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_ink_renderer19.Text, { color: color2, dimColor: !color2 && !line.startsWith("+"), children: line }, i);
|
|
3471
|
+
}) })
|
|
3046
3472
|
] });
|
|
3047
3473
|
}
|
|
3048
|
-
function
|
|
3049
|
-
|
|
3050
|
-
|
|
3051
|
-
|
|
3474
|
+
function PermissionRequest({
|
|
3475
|
+
toolName,
|
|
3476
|
+
description,
|
|
3477
|
+
details,
|
|
3478
|
+
showAlwaysAllow = true,
|
|
3479
|
+
onDecision,
|
|
3480
|
+
children,
|
|
3481
|
+
preview
|
|
3052
3482
|
}) {
|
|
3053
|
-
|
|
3054
|
-
|
|
3055
|
-
|
|
3056
|
-
|
|
3057
|
-
|
|
3058
|
-
|
|
3483
|
+
const terminalSize = (0, import_react15.useContext)(import_ink_renderer19.TerminalSizeContext);
|
|
3484
|
+
const terminalWidth = Math.min((terminalSize?.columns ?? 80) - 2, 80);
|
|
3485
|
+
const options = (0, import_react15.useMemo)(() => {
|
|
3486
|
+
const opts = [
|
|
3487
|
+
{ value: "allow", label: "Yes, allow this action" }
|
|
3488
|
+
];
|
|
3489
|
+
if (showAlwaysAllow) {
|
|
3490
|
+
opts.push({ value: "always_allow", label: `Yes, and always allow ${toolName}` });
|
|
3491
|
+
}
|
|
3492
|
+
opts.push({ value: "deny", label: "No, deny" });
|
|
3493
|
+
return opts;
|
|
3494
|
+
}, [showAlwaysAllow, toolName]);
|
|
3495
|
+
const [focusIndex, setFocusIndex] = import_react15.default.useState(0);
|
|
3496
|
+
const focusRef = import_react15.default.useRef(focusIndex);
|
|
3497
|
+
focusRef.current = focusIndex;
|
|
3498
|
+
const decide = (0, import_react15.useCallback)(
|
|
3499
|
+
(action) => {
|
|
3500
|
+
onDecision(action);
|
|
3501
|
+
},
|
|
3502
|
+
[onDecision]
|
|
3503
|
+
);
|
|
3504
|
+
(0, import_ink_renderer19.useInput)((input, key) => {
|
|
3505
|
+
if (input === "y") {
|
|
3506
|
+
decide("allow");
|
|
3507
|
+
return;
|
|
3508
|
+
}
|
|
3509
|
+
if (input === "a" && showAlwaysAllow) {
|
|
3510
|
+
decide("always_allow");
|
|
3511
|
+
return;
|
|
3512
|
+
}
|
|
3513
|
+
if (input === "n" || key.escape) {
|
|
3514
|
+
decide("deny");
|
|
3515
|
+
return;
|
|
3516
|
+
}
|
|
3517
|
+
if (key.upArrow || input === "k") {
|
|
3518
|
+
setFocusIndex((prev) => (prev - 1 + options.length) % options.length);
|
|
3519
|
+
} else if (key.downArrow || input === "j") {
|
|
3520
|
+
setFocusIndex((prev) => (prev + 1) % options.length);
|
|
3521
|
+
} else if (key.return) {
|
|
3522
|
+
decide(options[focusRef.current].value);
|
|
3523
|
+
} else if (input >= "1" && input <= "9") {
|
|
3524
|
+
const idx = parseInt(input, 10) - 1;
|
|
3525
|
+
if (idx < options.length) {
|
|
3526
|
+
setFocusIndex(idx);
|
|
3527
|
+
decide(options[idx].value);
|
|
3528
|
+
}
|
|
3529
|
+
}
|
|
3530
|
+
});
|
|
3531
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_ink_renderer19.Box, { flexDirection: "column", children: [
|
|
3532
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(PermissionHeader, { toolName, width: terminalWidth }),
|
|
3533
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_ink_renderer19.Box, { marginTop: 1, marginLeft: 2, flexDirection: "column", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_ink_renderer19.Text, { children: description }) }),
|
|
3534
|
+
details && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_ink_renderer19.Box, { marginTop: 1, marginLeft: 4, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_ink_renderer19.Text, { color: "yellow", children: details }) }),
|
|
3535
|
+
children && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_ink_renderer19.Box, { marginTop: 1, marginLeft: 2, flexDirection: "column", children }),
|
|
3536
|
+
preview && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_ink_renderer19.Box, { marginTop: 1, marginLeft: 2, flexDirection: "column", children: preview }),
|
|
3537
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_ink_renderer19.Box, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(HorizontalRule, { width: terminalWidth }) }),
|
|
3538
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_ink_renderer19.Box, { marginTop: 1, flexDirection: "column", children: options.map((opt, i) => {
|
|
3539
|
+
const isFocused = i === focusIndex;
|
|
3540
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_ink_renderer19.Box, { children: [
|
|
3541
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_ink_renderer19.Text, { color: isFocused ? "cyan" : void 0, children: [
|
|
3542
|
+
isFocused ? "\u276F" : " ",
|
|
3543
|
+
" "
|
|
3544
|
+
] }),
|
|
3545
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
3546
|
+
import_ink_renderer19.Text,
|
|
3547
|
+
{
|
|
3548
|
+
color: isFocused ? "cyan" : void 0,
|
|
3549
|
+
bold: isFocused,
|
|
3550
|
+
children: [
|
|
3551
|
+
i + 1,
|
|
3552
|
+
". ",
|
|
3553
|
+
opt.label
|
|
3554
|
+
]
|
|
3555
|
+
}
|
|
3556
|
+
)
|
|
3557
|
+
] }, opt.value);
|
|
3558
|
+
}) }),
|
|
3559
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_ink_renderer19.Box, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_ink_renderer19.Text, { dimColor: true, children: "Enter to confirm \xB7 Esc to deny" }) })
|
|
3560
|
+
] });
|
|
3561
|
+
}
|
|
3562
|
+
|
|
3563
|
+
// src/MessageList.tsx
|
|
3564
|
+
var import_react16 = require("react");
|
|
3565
|
+
var import_ink_renderer20 = require("@claude-code-kit/ink-renderer");
|
|
3566
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
3567
|
+
var ROLE_CONFIG = {
|
|
3568
|
+
user: { icon: "\u276F", label: "You", color: "cyan" },
|
|
3569
|
+
assistant: { icon: "\u25CF", label: "Claude", color: "#DA7756" },
|
|
3570
|
+
system: { icon: "\u273B", label: "System", color: void 0 }
|
|
3571
|
+
};
|
|
3572
|
+
var GUTTER = "\u23BF";
|
|
3573
|
+
function TextBlock({ text, dim }) {
|
|
3574
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_jsx_runtime15.Fragment, { children: text.split("\n").map((line, i) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_ink_renderer20.Box, { marginLeft: 2, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_ink_renderer20.Text, { dimColor: dim, children: line }) }, i)) });
|
|
3575
|
+
}
|
|
3576
|
+
function ToolUseBlock({ content }) {
|
|
3577
|
+
const statusColor = content.status === "error" ? "red" : content.status === "success" ? "green" : void 0;
|
|
3578
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_ink_renderer20.Box, { flexDirection: "column", marginLeft: 2, children: [
|
|
3579
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_ink_renderer20.Box, { children: [
|
|
3580
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_ink_renderer20.Text, { dimColor: true, children: [
|
|
3581
|
+
GUTTER,
|
|
3582
|
+
" "
|
|
3583
|
+
] }),
|
|
3584
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_ink_renderer20.Text, { bold: true, children: content.toolName })
|
|
3585
|
+
] }),
|
|
3586
|
+
content.input.split("\n").map((line, i) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_ink_renderer20.Box, { marginLeft: 4, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_ink_renderer20.Text, { dimColor: true, children: line }) }, i)),
|
|
3587
|
+
content.status === "running" && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_ink_renderer20.Box, { marginLeft: 4, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Spinner, { label: content.toolName, showElapsed: true }) }),
|
|
3588
|
+
content.result != null && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_ink_renderer20.Box, { flexDirection: "column", marginLeft: 4, children: [
|
|
3589
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_ink_renderer20.Box, { children: [
|
|
3590
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_ink_renderer20.Text, { dimColor: true, children: [
|
|
3591
|
+
GUTTER,
|
|
3592
|
+
" "
|
|
3593
|
+
] }),
|
|
3594
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_ink_renderer20.Text, { color: statusColor, children: [
|
|
3595
|
+
"result (",
|
|
3596
|
+
content.status ?? "done",
|
|
3597
|
+
")"
|
|
3598
|
+
] })
|
|
3599
|
+
] }),
|
|
3600
|
+
content.result.split("\n").map((line, i) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_ink_renderer20.Box, { marginLeft: 6, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_ink_renderer20.Text, { color: statusColor, dimColor: !statusColor, children: line }) }, i))
|
|
3601
|
+
] })
|
|
3602
|
+
] });
|
|
3603
|
+
}
|
|
3604
|
+
function ThinkingBlock({ content }) {
|
|
3605
|
+
const [collapsed, setCollapsed] = (0, import_react16.useState)(content.collapsed ?? true);
|
|
3606
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_ink_renderer20.Box, { flexDirection: "column", marginLeft: 2, children: [
|
|
3607
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_ink_renderer20.Box, { onClick: () => setCollapsed((c) => !c), children: [
|
|
3608
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_ink_renderer20.Text, { color: "#DA7756", children: [
|
|
3609
|
+
"\u273B",
|
|
3610
|
+
" "
|
|
3611
|
+
] }),
|
|
3612
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_ink_renderer20.Text, { dimColor: true, children: [
|
|
3613
|
+
"Thinking...",
|
|
3614
|
+
collapsed ? " (click to expand)" : ""
|
|
3615
|
+
] })
|
|
3616
|
+
] }),
|
|
3617
|
+
!collapsed && content.text.split("\n").map((line, i) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_ink_renderer20.Box, { marginLeft: 4, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_ink_renderer20.Text, { dimColor: true, children: line }) }, i))
|
|
3618
|
+
] });
|
|
3619
|
+
}
|
|
3620
|
+
function DiffBlock({ content }) {
|
|
3621
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_ink_renderer20.Box, { flexDirection: "column", marginLeft: 2, children: [
|
|
3622
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_ink_renderer20.Box, { children: [
|
|
3623
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_ink_renderer20.Text, { dimColor: true, children: [
|
|
3624
|
+
GUTTER,
|
|
3625
|
+
" "
|
|
3626
|
+
] }),
|
|
3627
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_ink_renderer20.Text, { bold: true, children: content.filename })
|
|
3628
|
+
] }),
|
|
3629
|
+
content.diff.split("\n").map((line, i) => {
|
|
3630
|
+
let color2;
|
|
3631
|
+
if (line.startsWith("+")) color2 = "green";
|
|
3632
|
+
else if (line.startsWith("-")) color2 = "red";
|
|
3633
|
+
else if (line.startsWith("@")) color2 = "cyan";
|
|
3634
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_ink_renderer20.Box, { marginLeft: 4, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_ink_renderer20.Text, { color: color2, dimColor: !color2, children: line }) }, i);
|
|
3635
|
+
})
|
|
3636
|
+
] });
|
|
3637
|
+
}
|
|
3638
|
+
function CodeBlock({ content }) {
|
|
3639
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_ink_renderer20.Box, { flexDirection: "column", marginLeft: 2, children: [
|
|
3640
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_ink_renderer20.Text, { dimColor: true, children: [
|
|
3641
|
+
"```",
|
|
3642
|
+
content.language ?? ""
|
|
3643
|
+
] }),
|
|
3644
|
+
content.code.split("\n").map((line, i) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_ink_renderer20.Box, { marginLeft: 2, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_ink_renderer20.Text, { children: line }) }, i)),
|
|
3645
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_ink_renderer20.Text, { dimColor: true, children: "```" })
|
|
3646
|
+
] });
|
|
3647
|
+
}
|
|
3648
|
+
function ErrorBlock({ content }) {
|
|
3649
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_ink_renderer20.Box, { flexDirection: "column", marginLeft: 2, children: [
|
|
3650
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_ink_renderer20.Box, { children: [
|
|
3651
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_ink_renderer20.Text, { color: "red", children: [
|
|
3652
|
+
"\u2716",
|
|
3653
|
+
" Error: "
|
|
3654
|
+
] }),
|
|
3655
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_ink_renderer20.Text, { color: "red", children: content.message })
|
|
3656
|
+
] }),
|
|
3657
|
+
content.details?.split("\n").map((line, i) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_ink_renderer20.Box, { marginLeft: 4, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_ink_renderer20.Text, { color: "red", dimColor: true, children: line }) }, i))
|
|
3658
|
+
] });
|
|
3659
|
+
}
|
|
3660
|
+
function ContentBlock({ block }) {
|
|
3661
|
+
switch (block.type) {
|
|
3662
|
+
case "text":
|
|
3663
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(TextBlock, { text: block.text });
|
|
3664
|
+
case "tool_use":
|
|
3665
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ToolUseBlock, { content: block });
|
|
3666
|
+
case "thinking":
|
|
3667
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ThinkingBlock, { content: block });
|
|
3668
|
+
case "diff":
|
|
3669
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(DiffBlock, { content: block });
|
|
3670
|
+
case "code":
|
|
3671
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(CodeBlock, { content: block });
|
|
3672
|
+
case "error":
|
|
3673
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ErrorBlock, { content: block });
|
|
3674
|
+
default:
|
|
3675
|
+
return null;
|
|
3676
|
+
}
|
|
3677
|
+
}
|
|
3678
|
+
function MessageItem({
|
|
3679
|
+
message,
|
|
3680
|
+
renderMessage
|
|
3681
|
+
}) {
|
|
3682
|
+
if (renderMessage) {
|
|
3683
|
+
return renderMessage(message);
|
|
3684
|
+
}
|
|
3685
|
+
const config = ROLE_CONFIG[message.role];
|
|
3686
|
+
const isSystem = message.role === "system";
|
|
3687
|
+
if (typeof message.content === "string") {
|
|
3688
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_ink_renderer20.Box, { flexDirection: "column", children: [
|
|
3689
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_ink_renderer20.Box, { children: [
|
|
3690
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_ink_renderer20.Text, { color: config.color, dimColor: isSystem, children: config.icon }),
|
|
3691
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_ink_renderer20.Text, { color: config.color, dimColor: isSystem, bold: !isSystem, children: [
|
|
3059
3692
|
" ",
|
|
3060
|
-
|
|
3693
|
+
config.label
|
|
3061
3694
|
] })
|
|
3062
3695
|
] }),
|
|
3063
|
-
|
|
3696
|
+
message.content.split("\n").map((line, i) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_ink_renderer20.Box, { marginLeft: 2, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_ink_renderer20.Text, { dimColor: isSystem, children: line }) }, i))
|
|
3697
|
+
] });
|
|
3698
|
+
}
|
|
3699
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_ink_renderer20.Box, { flexDirection: "column", children: [
|
|
3700
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_ink_renderer20.Box, { children: [
|
|
3701
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_ink_renderer20.Text, { color: config.color, dimColor: isSystem, children: config.icon }),
|
|
3702
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_ink_renderer20.Text, { color: config.color, dimColor: isSystem, bold: !isSystem, children: [
|
|
3703
|
+
" ",
|
|
3704
|
+
config.label
|
|
3705
|
+
] })
|
|
3706
|
+
] }),
|
|
3707
|
+
message.content.map((block, i) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ContentBlock, { block }, i))
|
|
3708
|
+
] });
|
|
3709
|
+
}
|
|
3710
|
+
function MessageList({
|
|
3711
|
+
messages,
|
|
3712
|
+
streamingContent,
|
|
3713
|
+
renderMessage
|
|
3714
|
+
}) {
|
|
3715
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_ink_renderer20.Box, { flexDirection: "column", children: [
|
|
3716
|
+
messages.map((message, i) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_ink_renderer20.Box, { flexDirection: "column", marginTop: i > 0 ? 1 : 0, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(MessageItem, { message, renderMessage }) }, message.id)),
|
|
3717
|
+
streamingContent != null && streamingContent.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_ink_renderer20.Box, { flexDirection: "column", marginTop: messages.length > 0 ? 1 : 0, children: [
|
|
3718
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_ink_renderer20.Box, { children: [
|
|
3719
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_ink_renderer20.Text, { color: "#DA7756", children: "\u25CF" }),
|
|
3720
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_ink_renderer20.Text, { color: "#DA7756", bold: true, children: " Claude" })
|
|
3721
|
+
] }),
|
|
3722
|
+
streamingContent.split("\n").map((line, i) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_ink_renderer20.Box, { marginLeft: 2, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_ink_renderer20.Text, { children: [
|
|
3064
3723
|
line,
|
|
3065
|
-
i === streamingContent.split("\n").length - 1 && /* @__PURE__ */ (0,
|
|
3724
|
+
i === streamingContent.split("\n").length - 1 && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_ink_renderer20.Text, { color: "#DA7756", children: "\u2588" })
|
|
3066
3725
|
] }) }, i))
|
|
3067
3726
|
] })
|
|
3068
3727
|
] });
|
|
3069
3728
|
}
|
|
3070
3729
|
|
|
3071
3730
|
// src/StreamingText.tsx
|
|
3072
|
-
var
|
|
3073
|
-
var
|
|
3074
|
-
var
|
|
3731
|
+
var import_react17 = require("react");
|
|
3732
|
+
var import_ink_renderer21 = require("@claude-code-kit/ink-renderer");
|
|
3733
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
3075
3734
|
function StreamingText({
|
|
3076
3735
|
text,
|
|
3077
3736
|
speed = 3,
|
|
@@ -3079,10 +3738,10 @@ function StreamingText({
|
|
|
3079
3738
|
onComplete,
|
|
3080
3739
|
color: color2
|
|
3081
3740
|
}) {
|
|
3082
|
-
const [revealed, setRevealed] = (0,
|
|
3083
|
-
const onCompleteRef = (0,
|
|
3741
|
+
const [revealed, setRevealed] = (0, import_react17.useState)(0);
|
|
3742
|
+
const onCompleteRef = (0, import_react17.useRef)(onComplete);
|
|
3084
3743
|
onCompleteRef.current = onComplete;
|
|
3085
|
-
(0,
|
|
3744
|
+
(0, import_react17.useEffect)(() => {
|
|
3086
3745
|
if (revealed >= text.length) return;
|
|
3087
3746
|
const id = setInterval(() => {
|
|
3088
3747
|
setRevealed((prev) => {
|
|
@@ -3095,19 +3754,171 @@ function StreamingText({
|
|
|
3095
3754
|
}, interval);
|
|
3096
3755
|
return () => clearInterval(id);
|
|
3097
3756
|
}, [text.length, speed, interval, revealed >= text.length]);
|
|
3098
|
-
return /* @__PURE__ */ (0,
|
|
3757
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_ink_renderer21.Text, { color: color2, children: text.slice(0, revealed) });
|
|
3099
3758
|
}
|
|
3100
3759
|
|
|
3101
3760
|
// src/REPL.tsx
|
|
3102
|
-
var
|
|
3103
|
-
var
|
|
3104
|
-
|
|
3761
|
+
var import_react19 = require("react");
|
|
3762
|
+
var import_ink_renderer23 = require("@claude-code-kit/ink-renderer");
|
|
3763
|
+
|
|
3764
|
+
// src/SearchOverlay.tsx
|
|
3765
|
+
var import_react18 = require("react");
|
|
3766
|
+
var import_ink_renderer22 = require("@claude-code-kit/ink-renderer");
|
|
3767
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
3768
|
+
function computeMatches(content, query) {
|
|
3769
|
+
if (!query) return [];
|
|
3770
|
+
const lower = query.toLowerCase();
|
|
3771
|
+
const found = [];
|
|
3772
|
+
for (let i = 0; i < content.length; i++) {
|
|
3773
|
+
const text = content[i] ?? "";
|
|
3774
|
+
let offset = 0;
|
|
3775
|
+
let pos = text.toLowerCase().indexOf(lower, offset);
|
|
3776
|
+
while (pos !== -1) {
|
|
3777
|
+
found.push({ index: i, offset: pos, length: query.length });
|
|
3778
|
+
offset = pos + 1;
|
|
3779
|
+
pos = text.toLowerCase().indexOf(lower, offset);
|
|
3780
|
+
}
|
|
3781
|
+
}
|
|
3782
|
+
return found;
|
|
3783
|
+
}
|
|
3784
|
+
function useSearch({ content, isActive }) {
|
|
3785
|
+
const [query, setQueryState] = (0, import_react18.useState)("");
|
|
3786
|
+
const [matches, setMatches] = (0, import_react18.useState)([]);
|
|
3787
|
+
const [currentIndex, setCurrentIndex] = (0, import_react18.useState)(0);
|
|
3788
|
+
const setQuery = (0, import_react18.useCallback)((q) => {
|
|
3789
|
+
setQueryState(q);
|
|
3790
|
+
const found = computeMatches(content, q);
|
|
3791
|
+
setMatches(found);
|
|
3792
|
+
setCurrentIndex(found.length > 0 ? 0 : -1);
|
|
3793
|
+
}, [content]);
|
|
3794
|
+
const next = (0, import_react18.useCallback)(() => {
|
|
3795
|
+
if (matches.length === 0) return;
|
|
3796
|
+
setCurrentIndex((i) => (i + 1) % matches.length);
|
|
3797
|
+
}, [matches.length]);
|
|
3798
|
+
const previous = (0, import_react18.useCallback)(() => {
|
|
3799
|
+
if (matches.length === 0) return;
|
|
3800
|
+
setCurrentIndex((i) => (i - 1 + matches.length) % matches.length);
|
|
3801
|
+
}, [matches.length]);
|
|
3802
|
+
(0, import_react18.useEffect)(() => {
|
|
3803
|
+
if (!isActive) {
|
|
3804
|
+
setQueryState("");
|
|
3805
|
+
setMatches([]);
|
|
3806
|
+
setCurrentIndex(0);
|
|
3807
|
+
}
|
|
3808
|
+
}, [isActive]);
|
|
3809
|
+
return { query, matches, currentIndex, next, previous, setQuery };
|
|
3810
|
+
}
|
|
3811
|
+
function SearchOverlay({
|
|
3812
|
+
isOpen,
|
|
3813
|
+
onClose,
|
|
3814
|
+
onSearch,
|
|
3815
|
+
onNavigate
|
|
3816
|
+
}) {
|
|
3817
|
+
const [query, setQueryState] = (0, import_react18.useState)("");
|
|
3818
|
+
const [cursor, setCursor] = (0, import_react18.useState)(0);
|
|
3819
|
+
const [matches, setMatches] = (0, import_react18.useState)([]);
|
|
3820
|
+
const matchIndexRef = (0, import_react18.useRef)(0);
|
|
3821
|
+
const [matchIndex, setMatchIndexState] = (0, import_react18.useState)(0);
|
|
3822
|
+
const setMatchIndex = (0, import_react18.useCallback)((next) => {
|
|
3823
|
+
matchIndexRef.current = next;
|
|
3824
|
+
setMatchIndexState(next);
|
|
3825
|
+
}, []);
|
|
3826
|
+
(0, import_react18.useEffect)(() => {
|
|
3827
|
+
if (!isOpen) {
|
|
3828
|
+
setQueryState("");
|
|
3829
|
+
setCursor(0);
|
|
3830
|
+
setMatches([]);
|
|
3831
|
+
setMatchIndex(0);
|
|
3832
|
+
}
|
|
3833
|
+
}, [isOpen, setMatchIndex]);
|
|
3834
|
+
const runSearch = (0, import_react18.useCallback)((q) => {
|
|
3835
|
+
const found = onSearch(q);
|
|
3836
|
+
setMatches(found);
|
|
3837
|
+
setMatchIndex(0);
|
|
3838
|
+
if (found.length > 0) onNavigate(found[0]);
|
|
3839
|
+
}, [onSearch, onNavigate, setMatchIndex]);
|
|
3840
|
+
const navigate = (0, import_react18.useCallback)((delta) => {
|
|
3841
|
+
setMatches((currentMatches) => {
|
|
3842
|
+
if (currentMatches.length === 0) return currentMatches;
|
|
3843
|
+
const next = (matchIndexRef.current + delta + currentMatches.length) % currentMatches.length;
|
|
3844
|
+
setMatchIndex(next);
|
|
3845
|
+
onNavigate(currentMatches[next]);
|
|
3846
|
+
return currentMatches;
|
|
3847
|
+
});
|
|
3848
|
+
}, [onNavigate, setMatchIndex]);
|
|
3849
|
+
(0, import_ink_renderer22.useInput)(
|
|
3850
|
+
(input, key) => {
|
|
3851
|
+
if (key.escape) {
|
|
3852
|
+
onClose();
|
|
3853
|
+
return;
|
|
3854
|
+
}
|
|
3855
|
+
if (key.return) {
|
|
3856
|
+
navigate(1);
|
|
3857
|
+
return;
|
|
3858
|
+
}
|
|
3859
|
+
if (input === "n" && key.ctrl) {
|
|
3860
|
+
navigate(1);
|
|
3861
|
+
return;
|
|
3862
|
+
}
|
|
3863
|
+
if (input === "p" && key.ctrl) {
|
|
3864
|
+
navigate(-1);
|
|
3865
|
+
return;
|
|
3866
|
+
}
|
|
3867
|
+
if (key.backspace) {
|
|
3868
|
+
if (cursor > 0) {
|
|
3869
|
+
const next = query.slice(0, cursor - 1) + query.slice(cursor);
|
|
3870
|
+
setQueryState(next);
|
|
3871
|
+
setCursor(cursor - 1);
|
|
3872
|
+
runSearch(next);
|
|
3873
|
+
}
|
|
3874
|
+
return;
|
|
3875
|
+
}
|
|
3876
|
+
if (key.leftArrow) {
|
|
3877
|
+
setCursor((c) => Math.max(0, c - 1));
|
|
3878
|
+
return;
|
|
3879
|
+
}
|
|
3880
|
+
if (key.rightArrow) {
|
|
3881
|
+
setCursor((c) => Math.min(query.length, c + 1));
|
|
3882
|
+
return;
|
|
3883
|
+
}
|
|
3884
|
+
if (key.ctrl || key.meta) return;
|
|
3885
|
+
if (input.length > 0) {
|
|
3886
|
+
const next = query.slice(0, cursor) + input + query.slice(cursor);
|
|
3887
|
+
setQueryState(next);
|
|
3888
|
+
setCursor(cursor + input.length);
|
|
3889
|
+
runSearch(next);
|
|
3890
|
+
}
|
|
3891
|
+
},
|
|
3892
|
+
{ isActive: isOpen }
|
|
3893
|
+
);
|
|
3894
|
+
if (!isOpen) return null;
|
|
3895
|
+
const total = matches.length;
|
|
3896
|
+
const current = total > 0 ? matchIndex + 1 : 0;
|
|
3897
|
+
const countLabel = total > 0 ? `${current}/${total} matches` : "no matches";
|
|
3898
|
+
const before = query.slice(0, cursor);
|
|
3899
|
+
const atCursor = cursor < query.length ? query[cursor] : " ";
|
|
3900
|
+
const after = cursor < query.length ? query.slice(cursor + 1) : "";
|
|
3901
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_ink_renderer22.Box, { flexDirection: "row", paddingX: 1, children: [
|
|
3902
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_ink_renderer22.Text, { color: "cyan", children: "Search: " }),
|
|
3903
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_ink_renderer22.Box, { flexGrow: 1, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_ink_renderer22.Text, { children: [
|
|
3904
|
+
before,
|
|
3905
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_ink_renderer22.Text, { inverse: true, children: atCursor }),
|
|
3906
|
+
after
|
|
3907
|
+
] }) }),
|
|
3908
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_ink_renderer22.Text, { dimColor: true, children: countLabel })
|
|
3909
|
+
] });
|
|
3910
|
+
}
|
|
3911
|
+
|
|
3912
|
+
// src/REPL.tsx
|
|
3913
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
3105
3914
|
function REPL({
|
|
3106
3915
|
onSubmit,
|
|
3107
3916
|
onExit,
|
|
3108
3917
|
messages,
|
|
3109
3918
|
isLoading = false,
|
|
3110
3919
|
streamingContent,
|
|
3920
|
+
welcome,
|
|
3921
|
+
permissionRequest,
|
|
3111
3922
|
commands = [],
|
|
3112
3923
|
model,
|
|
3113
3924
|
statusSegments,
|
|
@@ -3117,16 +3928,20 @@ function REPL({
|
|
|
3117
3928
|
renderMessage,
|
|
3118
3929
|
spinner
|
|
3119
3930
|
}) {
|
|
3120
|
-
const { exit } = (0,
|
|
3121
|
-
const [inputValue, setInputValue] = (0,
|
|
3122
|
-
const [internalHistory, setInternalHistory] = (0,
|
|
3123
|
-
const
|
|
3931
|
+
const { exit } = (0, import_ink_renderer23.useApp)();
|
|
3932
|
+
const [inputValue, setInputValue] = (0, import_react19.useState)("");
|
|
3933
|
+
const [internalHistory, setInternalHistory] = (0, import_react19.useState)([]);
|
|
3934
|
+
const [searchOpen, setSearchOpen] = (0, import_react19.useState)(false);
|
|
3935
|
+
const submittingRef = (0, import_react19.useRef)(false);
|
|
3124
3936
|
const history = externalHistory ?? internalHistory;
|
|
3937
|
+
const messageContents = messages.map(
|
|
3938
|
+
(m) => typeof m.content === "string" ? m.content : m.content.map((b) => "text" in b ? b.text : "").join(" ")
|
|
3939
|
+
);
|
|
3125
3940
|
const promptCommands = commands.map((c) => ({
|
|
3126
3941
|
name: c.name,
|
|
3127
3942
|
description: c.description
|
|
3128
3943
|
}));
|
|
3129
|
-
const handleSubmit = (0,
|
|
3944
|
+
const handleSubmit = (0, import_react19.useCallback)(
|
|
3130
3945
|
(value) => {
|
|
3131
3946
|
if (submittingRef.current) return;
|
|
3132
3947
|
const trimmed = value.trim();
|
|
@@ -3158,7 +3973,7 @@ function REPL({
|
|
|
3158
3973
|
},
|
|
3159
3974
|
[commands, onSubmit, externalHistory]
|
|
3160
3975
|
);
|
|
3161
|
-
(0,
|
|
3976
|
+
(0, import_ink_renderer23.useInput)(
|
|
3162
3977
|
(_input, key) => {
|
|
3163
3978
|
if (key.ctrl && _input === "c" && isLoading) {
|
|
3164
3979
|
return;
|
|
@@ -3170,13 +3985,20 @@ function REPL({
|
|
|
3170
3985
|
exit();
|
|
3171
3986
|
}
|
|
3172
3987
|
}
|
|
3988
|
+
if (key.ctrl && _input === "f") {
|
|
3989
|
+
setSearchOpen(true);
|
|
3990
|
+
}
|
|
3173
3991
|
},
|
|
3174
|
-
|
|
3992
|
+
// Deactivate when search overlay is open so only SearchOverlay handles input.
|
|
3993
|
+
{ isActive: !searchOpen }
|
|
3175
3994
|
);
|
|
3176
3995
|
const resolvedSegments = statusSegments ?? buildDefaultSegments(model);
|
|
3177
|
-
|
|
3178
|
-
|
|
3179
|
-
|
|
3996
|
+
const showWelcome = welcome && messages.length === 0 && !isLoading;
|
|
3997
|
+
const showPermission = !!permissionRequest;
|
|
3998
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_ink_renderer23.Box, { flexDirection: "column", flexGrow: 1, children: [
|
|
3999
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_ink_renderer23.Box, { flexDirection: "column", flexGrow: 1, children: [
|
|
4000
|
+
showWelcome && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_ink_renderer23.Box, { marginBottom: 1, children: welcome }),
|
|
4001
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
3180
4002
|
MessageList,
|
|
3181
4003
|
{
|
|
3182
4004
|
messages,
|
|
@@ -3184,10 +4006,29 @@ function REPL({
|
|
|
3184
4006
|
renderMessage
|
|
3185
4007
|
}
|
|
3186
4008
|
),
|
|
3187
|
-
isLoading && !streamingContent && /* @__PURE__ */ (0,
|
|
4009
|
+
isLoading && !streamingContent && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_ink_renderer23.Box, { marginTop: messages.length > 0 ? 1 : 0, children: spinner ?? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Spinner, {}) })
|
|
3188
4010
|
] }),
|
|
3189
|
-
/* @__PURE__ */ (0,
|
|
3190
|
-
|
|
4011
|
+
searchOpen && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4012
|
+
SearchOverlay,
|
|
4013
|
+
{
|
|
4014
|
+
isOpen: searchOpen,
|
|
4015
|
+
onClose: () => setSearchOpen(false),
|
|
4016
|
+
onSearch: (q) => computeMatches(messageContents, q),
|
|
4017
|
+
onNavigate: () => {
|
|
4018
|
+
}
|
|
4019
|
+
}
|
|
4020
|
+
),
|
|
4021
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Divider, {}),
|
|
4022
|
+
showPermission ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4023
|
+
PermissionRequest,
|
|
4024
|
+
{
|
|
4025
|
+
toolName: permissionRequest.toolName,
|
|
4026
|
+
description: permissionRequest.description,
|
|
4027
|
+
details: permissionRequest.details,
|
|
4028
|
+
preview: permissionRequest.preview,
|
|
4029
|
+
onDecision: permissionRequest.onDecision
|
|
4030
|
+
}
|
|
4031
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
3191
4032
|
PromptInput,
|
|
3192
4033
|
{
|
|
3193
4034
|
value: inputValue,
|
|
@@ -3195,13 +4036,13 @@ function REPL({
|
|
|
3195
4036
|
onSubmit: handleSubmit,
|
|
3196
4037
|
prefix,
|
|
3197
4038
|
placeholder,
|
|
3198
|
-
disabled: isLoading,
|
|
4039
|
+
disabled: isLoading || searchOpen,
|
|
3199
4040
|
commands: promptCommands,
|
|
3200
4041
|
history
|
|
3201
4042
|
}
|
|
3202
4043
|
),
|
|
3203
|
-
/* @__PURE__ */ (0,
|
|
3204
|
-
resolvedSegments.length > 0 && /* @__PURE__ */ (0,
|
|
4044
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Divider, {}),
|
|
4045
|
+
resolvedSegments.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(StatusLine, { segments: resolvedSegments })
|
|
3205
4046
|
] });
|
|
3206
4047
|
}
|
|
3207
4048
|
function buildDefaultSegments(model) {
|
|
@@ -3210,8 +4051,8 @@ function buildDefaultSegments(model) {
|
|
|
3210
4051
|
}
|
|
3211
4052
|
|
|
3212
4053
|
// src/design-system/ThemedBox.tsx
|
|
3213
|
-
var
|
|
3214
|
-
var
|
|
4054
|
+
var import_ink_renderer24 = require("@claude-code-kit/ink-renderer");
|
|
4055
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
3215
4056
|
function resolveColor(color2, theme) {
|
|
3216
4057
|
if (!color2) return void 0;
|
|
3217
4058
|
if (color2.startsWith("rgb(") || color2.startsWith("#") || color2.startsWith("ansi256(") || color2.startsWith("ansi:")) {
|
|
@@ -3238,8 +4079,8 @@ function ThemedBox({
|
|
|
3238
4079
|
const resolvedBorderLeftColor = resolveColor(borderLeftColor, theme);
|
|
3239
4080
|
const resolvedBorderRightColor = resolveColor(borderRightColor, theme);
|
|
3240
4081
|
const resolvedBackgroundColor = resolveColor(backgroundColor, theme);
|
|
3241
|
-
return /* @__PURE__ */ (0,
|
|
3242
|
-
|
|
4082
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4083
|
+
import_ink_renderer24.Box,
|
|
3243
4084
|
{
|
|
3244
4085
|
ref,
|
|
3245
4086
|
borderColor: resolvedBorderColor,
|
|
@@ -3256,10 +4097,10 @@ function ThemedBox({
|
|
|
3256
4097
|
var ThemedBox_default = ThemedBox;
|
|
3257
4098
|
|
|
3258
4099
|
// src/design-system/ThemedText.tsx
|
|
3259
|
-
var
|
|
3260
|
-
var
|
|
3261
|
-
var
|
|
3262
|
-
var TextHoverColorContext =
|
|
4100
|
+
var import_react20 = __toESM(require("react"));
|
|
4101
|
+
var import_ink_renderer25 = require("@claude-code-kit/ink-renderer");
|
|
4102
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
4103
|
+
var TextHoverColorContext = import_react20.default.createContext(void 0);
|
|
3263
4104
|
function resolveColor2(color2, theme) {
|
|
3264
4105
|
if (!color2) return void 0;
|
|
3265
4106
|
if (color2.startsWith("rgb(") || color2.startsWith("#") || color2.startsWith("ansi256(") || color2.startsWith("ansi:")) {
|
|
@@ -3281,11 +4122,11 @@ function ThemedText({
|
|
|
3281
4122
|
}) {
|
|
3282
4123
|
const [themeName] = useTheme();
|
|
3283
4124
|
const theme = getTheme(themeName);
|
|
3284
|
-
const hoverColor = (0,
|
|
4125
|
+
const hoverColor = (0, import_react20.useContext)(TextHoverColorContext);
|
|
3285
4126
|
const resolvedColor = !color2 && hoverColor ? resolveColor2(hoverColor, theme) : dimColor ? theme.inactive : resolveColor2(color2, theme);
|
|
3286
4127
|
const resolvedBackgroundColor = backgroundColor ? theme[backgroundColor] : void 0;
|
|
3287
|
-
return /* @__PURE__ */ (0,
|
|
3288
|
-
|
|
4128
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
4129
|
+
import_ink_renderer25.Text,
|
|
3289
4130
|
{
|
|
3290
4131
|
color: resolvedColor,
|
|
3291
4132
|
backgroundColor: resolvedBackgroundColor,
|
|
@@ -3301,42 +4142,42 @@ function ThemedText({
|
|
|
3301
4142
|
}
|
|
3302
4143
|
|
|
3303
4144
|
// src/design-system/Dialog.tsx
|
|
3304
|
-
var
|
|
3305
|
-
var
|
|
4145
|
+
var import_react22 = require("react");
|
|
4146
|
+
var import_ink_renderer29 = require("@claude-code-kit/ink-renderer");
|
|
3306
4147
|
|
|
3307
4148
|
// src/design-system/Byline.tsx
|
|
3308
|
-
var
|
|
3309
|
-
var
|
|
3310
|
-
var
|
|
4149
|
+
var import_react21 = __toESM(require("react"));
|
|
4150
|
+
var import_ink_renderer26 = require("@claude-code-kit/ink-renderer");
|
|
4151
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
3311
4152
|
function Byline({ children }) {
|
|
3312
|
-
const validChildren =
|
|
4153
|
+
const validChildren = import_react21.Children.toArray(children);
|
|
3313
4154
|
if (validChildren.length === 0) {
|
|
3314
4155
|
return null;
|
|
3315
4156
|
}
|
|
3316
|
-
return /* @__PURE__ */ (0,
|
|
3317
|
-
|
|
4157
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_jsx_runtime21.Fragment, { children: validChildren.map((child, index) => /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
4158
|
+
import_react21.default.Fragment,
|
|
3318
4159
|
{
|
|
3319
4160
|
children: [
|
|
3320
|
-
index > 0 && /* @__PURE__ */ (0,
|
|
4161
|
+
index > 0 && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_ink_renderer26.Text, { dimColor: true, children: " \xB7 " }),
|
|
3321
4162
|
child
|
|
3322
4163
|
]
|
|
3323
4164
|
},
|
|
3324
|
-
(0,
|
|
4165
|
+
(0, import_react21.isValidElement)(child) ? child.key ?? index : index
|
|
3325
4166
|
)) });
|
|
3326
4167
|
}
|
|
3327
4168
|
|
|
3328
4169
|
// src/design-system/KeyboardShortcutHint.tsx
|
|
3329
|
-
var
|
|
3330
|
-
var
|
|
4170
|
+
var import_ink_renderer27 = require("@claude-code-kit/ink-renderer");
|
|
4171
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
3331
4172
|
function KeyboardShortcutHint({
|
|
3332
4173
|
shortcut,
|
|
3333
4174
|
action,
|
|
3334
4175
|
parens = false,
|
|
3335
4176
|
bold = false
|
|
3336
4177
|
}) {
|
|
3337
|
-
const shortcutText = bold ? /* @__PURE__ */ (0,
|
|
4178
|
+
const shortcutText = bold ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_ink_renderer27.Text, { bold: true, children: shortcut }) : shortcut;
|
|
3338
4179
|
if (parens) {
|
|
3339
|
-
return /* @__PURE__ */ (0,
|
|
4180
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_ink_renderer27.Text, { children: [
|
|
3340
4181
|
"(",
|
|
3341
4182
|
shortcutText,
|
|
3342
4183
|
" to ",
|
|
@@ -3344,7 +4185,7 @@ function KeyboardShortcutHint({
|
|
|
3344
4185
|
")"
|
|
3345
4186
|
] });
|
|
3346
4187
|
}
|
|
3347
|
-
return /* @__PURE__ */ (0,
|
|
4188
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_ink_renderer27.Text, { children: [
|
|
3348
4189
|
shortcutText,
|
|
3349
4190
|
" to ",
|
|
3350
4191
|
action
|
|
@@ -3352,17 +4193,17 @@ function KeyboardShortcutHint({
|
|
|
3352
4193
|
}
|
|
3353
4194
|
|
|
3354
4195
|
// src/design-system/Pane.tsx
|
|
3355
|
-
var
|
|
3356
|
-
var
|
|
4196
|
+
var import_ink_renderer28 = require("@claude-code-kit/ink-renderer");
|
|
4197
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
3357
4198
|
function Pane({ children, color: color2 }) {
|
|
3358
|
-
return /* @__PURE__ */ (0,
|
|
3359
|
-
/* @__PURE__ */ (0,
|
|
3360
|
-
/* @__PURE__ */ (0,
|
|
4199
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_ink_renderer28.Box, { flexDirection: "column", paddingTop: 1, children: [
|
|
4200
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Divider, { color: color2 }),
|
|
4201
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_ink_renderer28.Box, { flexDirection: "column", paddingX: 2, children })
|
|
3361
4202
|
] });
|
|
3362
4203
|
}
|
|
3363
4204
|
|
|
3364
4205
|
// src/design-system/Dialog.tsx
|
|
3365
|
-
var
|
|
4206
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
3366
4207
|
function Dialog({
|
|
3367
4208
|
title,
|
|
3368
4209
|
subtitle,
|
|
@@ -3372,8 +4213,8 @@ function Dialog({
|
|
|
3372
4213
|
hideInputGuide,
|
|
3373
4214
|
hideBorder
|
|
3374
4215
|
}) {
|
|
3375
|
-
(0,
|
|
3376
|
-
(0,
|
|
4216
|
+
(0, import_ink_renderer29.useInput)(
|
|
4217
|
+
(0, import_react22.useCallback)(
|
|
3377
4218
|
(_input, key) => {
|
|
3378
4219
|
if (key.escape) {
|
|
3379
4220
|
onCancel();
|
|
@@ -3382,35 +4223,35 @@ function Dialog({
|
|
|
3382
4223
|
[onCancel]
|
|
3383
4224
|
)
|
|
3384
4225
|
);
|
|
3385
|
-
const defaultInputGuide = /* @__PURE__ */ (0,
|
|
3386
|
-
/* @__PURE__ */ (0,
|
|
3387
|
-
/* @__PURE__ */ (0,
|
|
4226
|
+
const defaultInputGuide = /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(Byline, { children: [
|
|
4227
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(KeyboardShortcutHint, { shortcut: "Enter", action: "confirm" }),
|
|
4228
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(KeyboardShortcutHint, { shortcut: "Esc", action: "cancel" })
|
|
3388
4229
|
] });
|
|
3389
|
-
const content = /* @__PURE__ */ (0,
|
|
3390
|
-
/* @__PURE__ */ (0,
|
|
3391
|
-
/* @__PURE__ */ (0,
|
|
3392
|
-
/* @__PURE__ */ (0,
|
|
3393
|
-
subtitle && /* @__PURE__ */ (0,
|
|
4230
|
+
const content = /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_jsx_runtime24.Fragment, { children: [
|
|
4231
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_ink_renderer29.Box, { flexDirection: "column", gap: 1, children: [
|
|
4232
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_ink_renderer29.Box, { flexDirection: "column", children: [
|
|
4233
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_ink_renderer29.Text, { bold: true, color: color2, children: title }),
|
|
4234
|
+
subtitle && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_ink_renderer29.Text, { dimColor: true, children: subtitle })
|
|
3394
4235
|
] }),
|
|
3395
4236
|
children
|
|
3396
4237
|
] }),
|
|
3397
|
-
!hideInputGuide && /* @__PURE__ */ (0,
|
|
4238
|
+
!hideInputGuide && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_ink_renderer29.Box, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_ink_renderer29.Text, { dimColor: true, italic: true, children: defaultInputGuide }) })
|
|
3398
4239
|
] });
|
|
3399
4240
|
if (hideBorder) {
|
|
3400
4241
|
return content;
|
|
3401
4242
|
}
|
|
3402
|
-
return /* @__PURE__ */ (0,
|
|
4243
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Pane, { color: color2, children: content });
|
|
3403
4244
|
}
|
|
3404
4245
|
|
|
3405
4246
|
// src/design-system/FuzzyPicker.tsx
|
|
3406
|
-
var
|
|
3407
|
-
var
|
|
4247
|
+
var import_react23 = require("react");
|
|
4248
|
+
var import_ink_renderer32 = require("@claude-code-kit/ink-renderer");
|
|
3408
4249
|
|
|
3409
4250
|
// src/design-system/ListItem.tsx
|
|
3410
4251
|
var import_figures2 = __toESM(require("figures"));
|
|
3411
|
-
var
|
|
3412
|
-
var
|
|
3413
|
-
var
|
|
4252
|
+
var import_ink_renderer30 = require("@claude-code-kit/ink-renderer");
|
|
4253
|
+
var import_ink_renderer31 = require("@claude-code-kit/ink-renderer");
|
|
4254
|
+
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
3414
4255
|
function ListItem({
|
|
3415
4256
|
isFocused,
|
|
3416
4257
|
isSelected = false,
|
|
@@ -3424,52 +4265,52 @@ function ListItem({
|
|
|
3424
4265
|
}) {
|
|
3425
4266
|
function renderIndicator() {
|
|
3426
4267
|
if (disabled) {
|
|
3427
|
-
return /* @__PURE__ */ (0,
|
|
4268
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_ink_renderer31.Text, { children: " " });
|
|
3428
4269
|
}
|
|
3429
4270
|
if (isFocused) {
|
|
3430
|
-
return /* @__PURE__ */ (0,
|
|
4271
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_ink_renderer31.Text, { color: "cyan", children: import_figures2.default.pointer });
|
|
3431
4272
|
}
|
|
3432
4273
|
if (showScrollDown) {
|
|
3433
|
-
return /* @__PURE__ */ (0,
|
|
4274
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_ink_renderer31.Text, { dimColor: true, children: import_figures2.default.arrowDown });
|
|
3434
4275
|
}
|
|
3435
4276
|
if (showScrollUp) {
|
|
3436
|
-
return /* @__PURE__ */ (0,
|
|
4277
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_ink_renderer31.Text, { dimColor: true, children: import_figures2.default.arrowUp });
|
|
3437
4278
|
}
|
|
3438
|
-
return /* @__PURE__ */ (0,
|
|
4279
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_ink_renderer31.Text, { children: " " });
|
|
3439
4280
|
}
|
|
3440
4281
|
function getTextColor() {
|
|
3441
4282
|
if (disabled) {
|
|
3442
|
-
return
|
|
4283
|
+
return void 0;
|
|
3443
4284
|
}
|
|
3444
4285
|
if (!styled) {
|
|
3445
4286
|
return void 0;
|
|
3446
4287
|
}
|
|
3447
4288
|
if (isSelected) {
|
|
3448
|
-
return "
|
|
4289
|
+
return "green";
|
|
3449
4290
|
}
|
|
3450
4291
|
if (isFocused) {
|
|
3451
|
-
return "
|
|
4292
|
+
return "cyan";
|
|
3452
4293
|
}
|
|
3453
4294
|
return void 0;
|
|
3454
4295
|
}
|
|
3455
4296
|
const textColor = getTextColor();
|
|
3456
|
-
const cursorRef = (0,
|
|
4297
|
+
const cursorRef = (0, import_ink_renderer30.useDeclaredCursor)({
|
|
3457
4298
|
line: 0,
|
|
3458
4299
|
column: 0,
|
|
3459
4300
|
active: isFocused && !disabled && declareCursor !== false
|
|
3460
4301
|
});
|
|
3461
|
-
return /* @__PURE__ */ (0,
|
|
3462
|
-
/* @__PURE__ */ (0,
|
|
4302
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_ink_renderer31.Box, { ref: cursorRef, flexDirection: "column", children: [
|
|
4303
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_ink_renderer31.Box, { flexDirection: "row", gap: 1, children: [
|
|
3463
4304
|
renderIndicator(),
|
|
3464
|
-
styled ? /* @__PURE__ */ (0,
|
|
3465
|
-
isSelected && !disabled && /* @__PURE__ */ (0,
|
|
4305
|
+
styled ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_ink_renderer31.Text, { color: textColor, dimColor: disabled, children }) : children,
|
|
4306
|
+
isSelected && !disabled && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_ink_renderer31.Text, { color: "green", children: import_figures2.default.tick })
|
|
3466
4307
|
] }),
|
|
3467
|
-
description && /* @__PURE__ */ (0,
|
|
4308
|
+
description && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_ink_renderer31.Box, { paddingLeft: 2, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_ink_renderer31.Text, { dimColor: true, children: description }) })
|
|
3468
4309
|
] });
|
|
3469
4310
|
}
|
|
3470
4311
|
|
|
3471
4312
|
// src/design-system/FuzzyPicker.tsx
|
|
3472
|
-
var
|
|
4313
|
+
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
3473
4314
|
var DEFAULT_VISIBLE = 8;
|
|
3474
4315
|
var CHROME_ROWS = 10;
|
|
3475
4316
|
var MIN_VISIBLE = 2;
|
|
@@ -3495,24 +4336,24 @@ function FuzzyPicker({
|
|
|
3495
4336
|
selectAction = "select",
|
|
3496
4337
|
extraHints
|
|
3497
4338
|
}) {
|
|
3498
|
-
const terminalSize = (0,
|
|
4339
|
+
const terminalSize = (0, import_react23.useContext)(import_ink_renderer32.TerminalSizeContext);
|
|
3499
4340
|
const rows = terminalSize?.rows ?? 24;
|
|
3500
4341
|
const columns = terminalSize?.columns ?? 80;
|
|
3501
|
-
const [focusedIndex, setFocusedIndex] = (0,
|
|
3502
|
-
const [query, setQuery] = (0,
|
|
4342
|
+
const [focusedIndex, setFocusedIndex] = (0, import_react23.useState)(0);
|
|
4343
|
+
const [query, setQuery] = (0, import_react23.useState)(initialQuery ?? "");
|
|
3503
4344
|
const visibleCount = Math.max(
|
|
3504
4345
|
MIN_VISIBLE,
|
|
3505
4346
|
Math.min(requestedVisible, rows - CHROME_ROWS - (matchLabel ? 1 : 0))
|
|
3506
4347
|
);
|
|
3507
4348
|
const compact = columns < 120;
|
|
3508
|
-
const step = (0,
|
|
4349
|
+
const step = (0, import_react23.useCallback)(
|
|
3509
4350
|
(delta) => {
|
|
3510
|
-
setFocusedIndex((i) => (0,
|
|
4351
|
+
setFocusedIndex((i) => (0, import_ink_renderer32.clamp)(i + delta, 0, items.length - 1));
|
|
3511
4352
|
},
|
|
3512
4353
|
[items.length]
|
|
3513
4354
|
);
|
|
3514
|
-
(0,
|
|
3515
|
-
(0,
|
|
4355
|
+
(0, import_ink_renderer32.useInput)(
|
|
4356
|
+
(0, import_react23.useCallback)(
|
|
3516
4357
|
(input, key) => {
|
|
3517
4358
|
if (key.escape) {
|
|
3518
4359
|
onCancel();
|
|
@@ -3553,26 +4394,26 @@ function FuzzyPicker({
|
|
|
3553
4394
|
[onCancel, step, direction, items, focusedIndex, onSelect, onShiftTab, onTab]
|
|
3554
4395
|
)
|
|
3555
4396
|
);
|
|
3556
|
-
(0,
|
|
4397
|
+
(0, import_react23.useEffect)(() => {
|
|
3557
4398
|
onQueryChange(query);
|
|
3558
4399
|
setFocusedIndex(0);
|
|
3559
4400
|
}, [query]);
|
|
3560
|
-
(0,
|
|
3561
|
-
setFocusedIndex((i) => (0,
|
|
4401
|
+
(0, import_react23.useEffect)(() => {
|
|
4402
|
+
setFocusedIndex((i) => (0, import_ink_renderer32.clamp)(i, 0, items.length - 1));
|
|
3562
4403
|
}, [items.length]);
|
|
3563
4404
|
const focused = items[focusedIndex];
|
|
3564
|
-
(0,
|
|
4405
|
+
(0, import_react23.useEffect)(() => {
|
|
3565
4406
|
onFocus?.(focused);
|
|
3566
4407
|
}, [focused]);
|
|
3567
|
-
const windowStart = (0,
|
|
4408
|
+
const windowStart = (0, import_ink_renderer32.clamp)(
|
|
3568
4409
|
focusedIndex - visibleCount + 1,
|
|
3569
4410
|
0,
|
|
3570
4411
|
items.length - visibleCount
|
|
3571
4412
|
);
|
|
3572
4413
|
const visible = items.slice(windowStart, windowStart + visibleCount);
|
|
3573
4414
|
const emptyText = typeof emptyMessage === "function" ? emptyMessage(query) : emptyMessage;
|
|
3574
|
-
const searchInput = /* @__PURE__ */ (0,
|
|
3575
|
-
const listBlock = /* @__PURE__ */ (0,
|
|
4415
|
+
const searchInput = /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_ink_renderer32.Box, { borderStyle: "round", paddingX: 1, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_ink_renderer32.Text, { dimColor: !query, children: query || placeholder }) });
|
|
4416
|
+
const listBlock = /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
3576
4417
|
List,
|
|
3577
4418
|
{
|
|
3578
4419
|
visible,
|
|
@@ -3586,50 +4427,50 @@ function FuzzyPicker({
|
|
|
3586
4427
|
emptyText
|
|
3587
4428
|
}
|
|
3588
4429
|
);
|
|
3589
|
-
const preview = renderPreview && focused ? /* @__PURE__ */ (0,
|
|
3590
|
-
const listGroup = renderPreview && previewPosition === "right" ? /* @__PURE__ */ (0,
|
|
3591
|
-
|
|
4430
|
+
const preview = renderPreview && focused ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_ink_renderer32.Box, { flexDirection: "column", flexGrow: 1, children: renderPreview(focused) }) : null;
|
|
4431
|
+
const listGroup = renderPreview && previewPosition === "right" ? /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
|
|
4432
|
+
import_ink_renderer32.Box,
|
|
3592
4433
|
{
|
|
3593
4434
|
flexDirection: "row",
|
|
3594
4435
|
gap: 2,
|
|
3595
4436
|
height: visibleCount + (matchLabel ? 1 : 0),
|
|
3596
4437
|
children: [
|
|
3597
|
-
/* @__PURE__ */ (0,
|
|
4438
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_ink_renderer32.Box, { flexDirection: "column", flexShrink: 0, children: [
|
|
3598
4439
|
listBlock,
|
|
3599
|
-
matchLabel && /* @__PURE__ */ (0,
|
|
4440
|
+
matchLabel && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_ink_renderer32.Text, { dimColor: true, children: matchLabel })
|
|
3600
4441
|
] }),
|
|
3601
|
-
preview ?? /* @__PURE__ */ (0,
|
|
4442
|
+
preview ?? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_ink_renderer32.Box, { flexGrow: 1 })
|
|
3602
4443
|
]
|
|
3603
4444
|
}
|
|
3604
|
-
) : /* @__PURE__ */ (0,
|
|
4445
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_ink_renderer32.Box, { flexDirection: "column", children: [
|
|
3605
4446
|
listBlock,
|
|
3606
|
-
matchLabel && /* @__PURE__ */ (0,
|
|
4447
|
+
matchLabel && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_ink_renderer32.Text, { dimColor: true, children: matchLabel }),
|
|
3607
4448
|
preview
|
|
3608
4449
|
] });
|
|
3609
4450
|
const inputAbove = direction !== "up";
|
|
3610
|
-
return /* @__PURE__ */ (0,
|
|
3611
|
-
/* @__PURE__ */ (0,
|
|
4451
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Pane, { color: "permission", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_ink_renderer32.Box, { flexDirection: "column", gap: 1, children: [
|
|
4452
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_ink_renderer32.Text, { bold: true, color: "permission", children: title }),
|
|
3612
4453
|
inputAbove && searchInput,
|
|
3613
4454
|
listGroup,
|
|
3614
4455
|
!inputAbove && searchInput,
|
|
3615
|
-
/* @__PURE__ */ (0,
|
|
3616
|
-
/* @__PURE__ */ (0,
|
|
4456
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_ink_renderer32.Text, { dimColor: true, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(Byline, { children: [
|
|
4457
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
3617
4458
|
KeyboardShortcutHint,
|
|
3618
4459
|
{
|
|
3619
4460
|
shortcut: "up/dn",
|
|
3620
4461
|
action: compact ? "nav" : "navigate"
|
|
3621
4462
|
}
|
|
3622
4463
|
),
|
|
3623
|
-
/* @__PURE__ */ (0,
|
|
3624
|
-
onTab && /* @__PURE__ */ (0,
|
|
3625
|
-
onShiftTab && !compact && /* @__PURE__ */ (0,
|
|
4464
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(KeyboardShortcutHint, { shortcut: "Enter", action: selectAction }),
|
|
4465
|
+
onTab && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(KeyboardShortcutHint, { shortcut: "Tab", action: onTab.action }),
|
|
4466
|
+
onShiftTab && !compact && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
3626
4467
|
KeyboardShortcutHint,
|
|
3627
4468
|
{
|
|
3628
4469
|
shortcut: "shift+tab",
|
|
3629
4470
|
action: onShiftTab.action
|
|
3630
4471
|
}
|
|
3631
4472
|
),
|
|
3632
|
-
/* @__PURE__ */ (0,
|
|
4473
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(KeyboardShortcutHint, { shortcut: "Esc", action: "cancel" }),
|
|
3633
4474
|
extraHints
|
|
3634
4475
|
] }) })
|
|
3635
4476
|
] }) });
|
|
@@ -3646,14 +4487,14 @@ function List({
|
|
|
3646
4487
|
emptyText
|
|
3647
4488
|
}) {
|
|
3648
4489
|
if (visible.length === 0) {
|
|
3649
|
-
return /* @__PURE__ */ (0,
|
|
4490
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_ink_renderer32.Box, { height: visibleCount, flexShrink: 0, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_ink_renderer32.Text, { dimColor: true, children: emptyText }) });
|
|
3650
4491
|
}
|
|
3651
4492
|
const rows = visible.map((item, i) => {
|
|
3652
4493
|
const actualIndex = windowStart + i;
|
|
3653
4494
|
const isFocused = actualIndex === focusedIndex;
|
|
3654
4495
|
const atLowEdge = i === 0 && windowStart > 0;
|
|
3655
4496
|
const atHighEdge = i === visible.length - 1 && windowStart + visibleCount < total;
|
|
3656
|
-
return /* @__PURE__ */ (0,
|
|
4497
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
3657
4498
|
ListItem,
|
|
3658
4499
|
{
|
|
3659
4500
|
isFocused,
|
|
@@ -3665,8 +4506,8 @@ function List({
|
|
|
3665
4506
|
getKey(item)
|
|
3666
4507
|
);
|
|
3667
4508
|
});
|
|
3668
|
-
return /* @__PURE__ */ (0,
|
|
3669
|
-
|
|
4509
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
4510
|
+
import_ink_renderer32.Box,
|
|
3670
4511
|
{
|
|
3671
4512
|
height: visibleCount,
|
|
3672
4513
|
flexShrink: 0,
|
|
@@ -3677,69 +4518,69 @@ function List({
|
|
|
3677
4518
|
}
|
|
3678
4519
|
|
|
3679
4520
|
// src/design-system/LoadingState.tsx
|
|
3680
|
-
var
|
|
3681
|
-
var
|
|
4521
|
+
var import_ink_renderer33 = require("@claude-code-kit/ink-renderer");
|
|
4522
|
+
var import_jsx_runtime27 = require("react/jsx-runtime");
|
|
3682
4523
|
function LoadingState({
|
|
3683
4524
|
message,
|
|
3684
4525
|
bold = false,
|
|
3685
4526
|
dimColor = false,
|
|
3686
4527
|
subtitle
|
|
3687
4528
|
}) {
|
|
3688
|
-
return /* @__PURE__ */ (0,
|
|
3689
|
-
/* @__PURE__ */ (0,
|
|
3690
|
-
/* @__PURE__ */ (0,
|
|
3691
|
-
/* @__PURE__ */ (0,
|
|
4529
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_ink_renderer33.Box, { flexDirection: "column", children: [
|
|
4530
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_ink_renderer33.Box, { flexDirection: "row", children: [
|
|
4531
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(Spinner, {}),
|
|
4532
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_ink_renderer33.Text, { bold, dimColor, children: [
|
|
3692
4533
|
" ",
|
|
3693
4534
|
message
|
|
3694
4535
|
] })
|
|
3695
4536
|
] }),
|
|
3696
|
-
subtitle && /* @__PURE__ */ (0,
|
|
4537
|
+
subtitle && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_ink_renderer33.Text, { dimColor: true, children: subtitle })
|
|
3697
4538
|
] });
|
|
3698
4539
|
}
|
|
3699
4540
|
|
|
3700
4541
|
// src/design-system/Ratchet.tsx
|
|
3701
|
-
var
|
|
3702
|
-
var
|
|
3703
|
-
var
|
|
3704
|
-
var
|
|
3705
|
-
var
|
|
4542
|
+
var import_react24 = require("react");
|
|
4543
|
+
var import_ink_renderer34 = require("@claude-code-kit/ink-renderer");
|
|
4544
|
+
var import_ink_renderer35 = require("@claude-code-kit/ink-renderer");
|
|
4545
|
+
var import_ink_renderer36 = require("@claude-code-kit/ink-renderer");
|
|
4546
|
+
var import_jsx_runtime28 = require("react/jsx-runtime");
|
|
3706
4547
|
function Ratchet({
|
|
3707
4548
|
children,
|
|
3708
4549
|
lock = "always"
|
|
3709
4550
|
}) {
|
|
3710
|
-
const [viewportRef, { isVisible }] = (0,
|
|
3711
|
-
const terminalSize = (0,
|
|
4551
|
+
const [viewportRef, { isVisible }] = (0, import_ink_renderer35.useTerminalViewport)();
|
|
4552
|
+
const terminalSize = (0, import_react24.useContext)(import_ink_renderer34.TerminalSizeContext);
|
|
3712
4553
|
const rows = terminalSize?.rows ?? 24;
|
|
3713
|
-
const innerRef = (0,
|
|
3714
|
-
const maxHeight = (0,
|
|
3715
|
-
const [minHeight, setMinHeight] = (0,
|
|
3716
|
-
const outerRef = (0,
|
|
4554
|
+
const innerRef = (0, import_react24.useRef)(null);
|
|
4555
|
+
const maxHeight = (0, import_react24.useRef)(0);
|
|
4556
|
+
const [minHeight, setMinHeight] = (0, import_react24.useState)(0);
|
|
4557
|
+
const outerRef = (0, import_react24.useCallback)(
|
|
3717
4558
|
(el) => {
|
|
3718
4559
|
viewportRef(el);
|
|
3719
4560
|
},
|
|
3720
4561
|
[viewportRef]
|
|
3721
4562
|
);
|
|
3722
4563
|
const engaged = lock === "always" || !isVisible;
|
|
3723
|
-
(0,
|
|
4564
|
+
(0, import_react24.useLayoutEffect)(() => {
|
|
3724
4565
|
if (!innerRef.current) {
|
|
3725
4566
|
return;
|
|
3726
4567
|
}
|
|
3727
|
-
const { height } = (0,
|
|
4568
|
+
const { height } = (0, import_ink_renderer36.measureElement)(innerRef.current);
|
|
3728
4569
|
if (height > maxHeight.current) {
|
|
3729
4570
|
maxHeight.current = Math.min(height, rows);
|
|
3730
4571
|
setMinHeight(maxHeight.current);
|
|
3731
4572
|
}
|
|
3732
4573
|
});
|
|
3733
|
-
return /* @__PURE__ */ (0,
|
|
4574
|
+
return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_ink_renderer36.Box, { minHeight: engaged ? minHeight : void 0, ref: outerRef, children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_ink_renderer36.Box, { ref: innerRef, flexDirection: "column", children }) });
|
|
3734
4575
|
}
|
|
3735
4576
|
|
|
3736
4577
|
// src/design-system/Tabs.tsx
|
|
3737
|
-
var
|
|
3738
|
-
var
|
|
3739
|
-
var
|
|
3740
|
-
var
|
|
3741
|
-
var
|
|
3742
|
-
var TabsContext = (0,
|
|
4578
|
+
var import_react25 = require("react");
|
|
4579
|
+
var import_ink_renderer37 = require("@claude-code-kit/ink-renderer");
|
|
4580
|
+
var import_ink_renderer38 = require("@claude-code-kit/ink-renderer");
|
|
4581
|
+
var import_ink_renderer39 = require("@claude-code-kit/ink-renderer");
|
|
4582
|
+
var import_jsx_runtime29 = require("react/jsx-runtime");
|
|
4583
|
+
var TabsContext = (0, import_react25.createContext)({
|
|
3743
4584
|
selectedTab: void 0,
|
|
3744
4585
|
width: void 0
|
|
3745
4586
|
});
|
|
@@ -3755,7 +4596,7 @@ function Tabs({
|
|
|
3755
4596
|
banner,
|
|
3756
4597
|
disableNavigation
|
|
3757
4598
|
}) {
|
|
3758
|
-
const terminalSize = (0,
|
|
4599
|
+
const terminalSize = (0, import_react25.useContext)(import_ink_renderer37.TerminalSizeContext);
|
|
3759
4600
|
const terminalWidth = terminalSize?.columns ?? 80;
|
|
3760
4601
|
const tabs = children.map((child) => [
|
|
3761
4602
|
child.props.id ?? child.props.title,
|
|
@@ -3763,12 +4604,12 @@ function Tabs({
|
|
|
3763
4604
|
]);
|
|
3764
4605
|
const defaultTabIndex = defaultTab ? tabs.findIndex((tab) => defaultTab === tab[0]) : 0;
|
|
3765
4606
|
const isControlled = controlledSelectedTab !== void 0;
|
|
3766
|
-
const [internalSelectedTab, setInternalSelectedTab] = (0,
|
|
4607
|
+
const [internalSelectedTab, setInternalSelectedTab] = (0, import_react25.useState)(
|
|
3767
4608
|
defaultTabIndex !== -1 ? defaultTabIndex : 0
|
|
3768
4609
|
);
|
|
3769
4610
|
const controlledTabIndex = isControlled ? tabs.findIndex((tab) => tab[0] === controlledSelectedTab) : -1;
|
|
3770
4611
|
const selectedTabIndex = isControlled ? controlledTabIndex !== -1 ? controlledTabIndex : 0 : internalSelectedTab;
|
|
3771
|
-
const handleTabChange = (0,
|
|
4612
|
+
const handleTabChange = (0, import_react25.useCallback)(
|
|
3772
4613
|
(offset) => {
|
|
3773
4614
|
const newIndex = (selectedTabIndex + tabs.length + offset) % tabs.length;
|
|
3774
4615
|
const newTabId = tabs[newIndex]?.[0];
|
|
@@ -3780,8 +4621,8 @@ function Tabs({
|
|
|
3780
4621
|
},
|
|
3781
4622
|
[selectedTabIndex, tabs, isControlled, onTabChange]
|
|
3782
4623
|
);
|
|
3783
|
-
(0,
|
|
3784
|
-
(0,
|
|
4624
|
+
(0, import_ink_renderer39.useInput)(
|
|
4625
|
+
(0, import_react25.useCallback)(
|
|
3785
4626
|
(_input, key) => {
|
|
3786
4627
|
if (hidden || disableNavigation) return;
|
|
3787
4628
|
if (key.tab && !key.shift) {
|
|
@@ -3797,28 +4638,28 @@ function Tabs({
|
|
|
3797
4638
|
[hidden, disableNavigation, handleTabChange]
|
|
3798
4639
|
)
|
|
3799
4640
|
);
|
|
3800
|
-
const titleWidth = title ? (0,
|
|
4641
|
+
const titleWidth = title ? (0, import_ink_renderer38.stringWidth)(title) + 1 : 0;
|
|
3801
4642
|
const tabsWidth = tabs.reduce(
|
|
3802
|
-
(sum, [, tabTitle]) => sum + (tabTitle ? (0,
|
|
4643
|
+
(sum, [, tabTitle]) => sum + (tabTitle ? (0, import_ink_renderer38.stringWidth)(tabTitle) : 0) + 3,
|
|
3803
4644
|
0
|
|
3804
4645
|
);
|
|
3805
4646
|
const usedWidth = titleWidth + tabsWidth;
|
|
3806
4647
|
const spacerWidth = useFullWidth ? Math.max(0, terminalWidth - usedWidth) : 0;
|
|
3807
4648
|
const contentWidth = useFullWidth ? terminalWidth : void 0;
|
|
3808
|
-
return /* @__PURE__ */ (0,
|
|
4649
|
+
return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
3809
4650
|
TabsContext.Provider,
|
|
3810
4651
|
{
|
|
3811
4652
|
value: {
|
|
3812
4653
|
selectedTab: tabs[selectedTabIndex]?.[0],
|
|
3813
4654
|
width: contentWidth
|
|
3814
4655
|
},
|
|
3815
|
-
children: /* @__PURE__ */ (0,
|
|
3816
|
-
!hidden && /* @__PURE__ */ (0,
|
|
3817
|
-
title !== void 0 && /* @__PURE__ */ (0,
|
|
4656
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(import_ink_renderer39.Box, { flexDirection: "column", children: [
|
|
4657
|
+
!hidden && /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(import_ink_renderer39.Box, { flexDirection: "row", gap: 1, children: [
|
|
4658
|
+
title !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_ink_renderer39.Text, { bold: true, color: color2, children: title }),
|
|
3818
4659
|
tabs.map(([id, tabTitle], i) => {
|
|
3819
4660
|
const isCurrent = selectedTabIndex === i;
|
|
3820
|
-
return /* @__PURE__ */ (0,
|
|
3821
|
-
|
|
4661
|
+
return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
|
|
4662
|
+
import_ink_renderer39.Text,
|
|
3822
4663
|
{
|
|
3823
4664
|
inverse: isCurrent,
|
|
3824
4665
|
bold: isCurrent,
|
|
@@ -3831,11 +4672,11 @@ function Tabs({
|
|
|
3831
4672
|
id
|
|
3832
4673
|
);
|
|
3833
4674
|
}),
|
|
3834
|
-
spacerWidth > 0 && /* @__PURE__ */ (0,
|
|
4675
|
+
spacerWidth > 0 && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_ink_renderer39.Text, { children: " ".repeat(spacerWidth) })
|
|
3835
4676
|
] }),
|
|
3836
4677
|
banner,
|
|
3837
|
-
/* @__PURE__ */ (0,
|
|
3838
|
-
|
|
4678
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
4679
|
+
import_ink_renderer39.Box,
|
|
3839
4680
|
{
|
|
3840
4681
|
width: contentWidth,
|
|
3841
4682
|
marginTop: hidden ? 0 : 1,
|
|
@@ -3847,23 +4688,663 @@ function Tabs({
|
|
|
3847
4688
|
);
|
|
3848
4689
|
}
|
|
3849
4690
|
function Tab({ title, id, children }) {
|
|
3850
|
-
const { selectedTab, width } = (0,
|
|
4691
|
+
const { selectedTab, width } = (0, import_react25.useContext)(TabsContext);
|
|
3851
4692
|
if (selectedTab !== (id ?? title)) {
|
|
3852
4693
|
return null;
|
|
3853
4694
|
}
|
|
3854
|
-
return /* @__PURE__ */ (0,
|
|
4695
|
+
return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_ink_renderer39.Box, { width, children });
|
|
3855
4696
|
}
|
|
3856
4697
|
function useTabsWidth() {
|
|
3857
|
-
const { width } = (0,
|
|
4698
|
+
const { width } = (0, import_react25.useContext)(TabsContext);
|
|
3858
4699
|
return width;
|
|
3859
4700
|
}
|
|
4701
|
+
|
|
4702
|
+
// src/useVirtualScroll.ts
|
|
4703
|
+
var import_react26 = __toESM(require("react"));
|
|
4704
|
+
var import_ink_renderer40 = require("@claude-code-kit/ink-renderer");
|
|
4705
|
+
function clamp2(value, min, max) {
|
|
4706
|
+
return Math.max(min, Math.min(max, value));
|
|
4707
|
+
}
|
|
4708
|
+
function useVirtualScroll(options) {
|
|
4709
|
+
const {
|
|
4710
|
+
itemCount,
|
|
4711
|
+
estimatedItemHeight = 3,
|
|
4712
|
+
overscan = 20,
|
|
4713
|
+
viewportHeight
|
|
4714
|
+
} = options;
|
|
4715
|
+
const totalHeight = itemCount * estimatedItemHeight;
|
|
4716
|
+
const maxOffset = Math.max(0, totalHeight - viewportHeight);
|
|
4717
|
+
const [scrollOffset, setScrollOffset] = (0, import_react26.useState)(0);
|
|
4718
|
+
const clampedOffset = clamp2(scrollOffset, 0, maxOffset);
|
|
4719
|
+
const rawStart = Math.floor(clampedOffset / estimatedItemHeight);
|
|
4720
|
+
const rawEnd = Math.ceil((clampedOffset + viewportHeight) / estimatedItemHeight);
|
|
4721
|
+
const startIndex = clamp2(rawStart - overscan, 0, itemCount);
|
|
4722
|
+
const endIndex = clamp2(rawEnd + overscan, 0, itemCount);
|
|
4723
|
+
const visibleItems = endIndex - startIndex;
|
|
4724
|
+
const scrollTo = (0, import_react26.useCallback)(
|
|
4725
|
+
(index) => {
|
|
4726
|
+
const targetOffset = clamp2(index * estimatedItemHeight, 0, maxOffset);
|
|
4727
|
+
setScrollOffset(targetOffset);
|
|
4728
|
+
},
|
|
4729
|
+
[estimatedItemHeight, maxOffset]
|
|
4730
|
+
);
|
|
4731
|
+
const scrollToEnd = (0, import_react26.useCallback)(() => {
|
|
4732
|
+
setScrollOffset(maxOffset);
|
|
4733
|
+
}, [maxOffset]);
|
|
4734
|
+
const onScroll = (0, import_react26.useCallback)(
|
|
4735
|
+
(delta) => {
|
|
4736
|
+
setScrollOffset((prev) => clamp2(prev + delta * estimatedItemHeight, 0, maxOffset));
|
|
4737
|
+
},
|
|
4738
|
+
[estimatedItemHeight, maxOffset]
|
|
4739
|
+
);
|
|
4740
|
+
const isAtTop = clampedOffset <= 0;
|
|
4741
|
+
const isAtEnd = clampedOffset >= maxOffset;
|
|
4742
|
+
return (0, import_react26.useMemo)(
|
|
4743
|
+
() => ({
|
|
4744
|
+
startIndex,
|
|
4745
|
+
endIndex,
|
|
4746
|
+
visibleItems,
|
|
4747
|
+
totalHeight,
|
|
4748
|
+
scrollOffset: clampedOffset,
|
|
4749
|
+
scrollTo,
|
|
4750
|
+
scrollToEnd,
|
|
4751
|
+
onScroll,
|
|
4752
|
+
isAtTop,
|
|
4753
|
+
isAtEnd
|
|
4754
|
+
}),
|
|
4755
|
+
[
|
|
4756
|
+
startIndex,
|
|
4757
|
+
endIndex,
|
|
4758
|
+
visibleItems,
|
|
4759
|
+
totalHeight,
|
|
4760
|
+
clampedOffset,
|
|
4761
|
+
scrollTo,
|
|
4762
|
+
scrollToEnd,
|
|
4763
|
+
onScroll,
|
|
4764
|
+
isAtTop,
|
|
4765
|
+
isAtEnd
|
|
4766
|
+
]
|
|
4767
|
+
);
|
|
4768
|
+
}
|
|
4769
|
+
function VirtualList(props) {
|
|
4770
|
+
const { items, renderItem, viewportHeight, estimatedItemHeight = 3, overscan = 20 } = props;
|
|
4771
|
+
const { startIndex, endIndex, totalHeight } = useVirtualScroll({
|
|
4772
|
+
itemCount: items.length,
|
|
4773
|
+
estimatedItemHeight,
|
|
4774
|
+
overscan,
|
|
4775
|
+
viewportHeight
|
|
4776
|
+
});
|
|
4777
|
+
const topPad = startIndex * estimatedItemHeight;
|
|
4778
|
+
const renderedHeight = (endIndex - startIndex) * estimatedItemHeight;
|
|
4779
|
+
const bottomPad = Math.max(0, totalHeight - topPad - renderedHeight);
|
|
4780
|
+
const visibleSlice = [];
|
|
4781
|
+
for (let i = startIndex; i < endIndex && i < items.length; i++) {
|
|
4782
|
+
visibleSlice.push(renderItem(items[i], i));
|
|
4783
|
+
}
|
|
4784
|
+
return import_react26.default.createElement(
|
|
4785
|
+
import_ink_renderer40.Box,
|
|
4786
|
+
{
|
|
4787
|
+
flexDirection: "column",
|
|
4788
|
+
height: viewportHeight,
|
|
4789
|
+
overflow: "hidden"
|
|
4790
|
+
},
|
|
4791
|
+
topPad > 0 ? import_react26.default.createElement(import_ink_renderer40.Box, { height: topPad, key: "__virtual-top" }) : null,
|
|
4792
|
+
...visibleSlice,
|
|
4793
|
+
bottomPad > 0 ? import_react26.default.createElement(import_ink_renderer40.Box, { height: bottomPad, key: "__virtual-bottom" }) : null
|
|
4794
|
+
);
|
|
4795
|
+
}
|
|
4796
|
+
|
|
4797
|
+
// src/WelcomeScreen.tsx
|
|
4798
|
+
var import_ink_renderer41 = require("@claude-code-kit/ink-renderer");
|
|
4799
|
+
var import_jsx_runtime30 = require("react/jsx-runtime");
|
|
4800
|
+
var DEFAULT_COLOR2 = "#DA7756";
|
|
4801
|
+
function ClawdLogo({ color: color2 = DEFAULT_COLOR2 }) {
|
|
4802
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_ink_renderer41.Box, { flexDirection: "column", children: [
|
|
4803
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_ink_renderer41.Text, { color: color2, children: " \u2590\u259B\u2588\u2588\u2588\u259C\u258C" }),
|
|
4804
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_ink_renderer41.Text, { color: color2, children: "\u259D\u259C\u2588\u2588\u2588\u2588\u2588\u259B\u2598" }),
|
|
4805
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_ink_renderer41.Text, { color: color2, children: " \u2598\u2598 \u259D\u259D " })
|
|
4806
|
+
] });
|
|
4807
|
+
}
|
|
4808
|
+
function WelcomeScreen({
|
|
4809
|
+
appName,
|
|
4810
|
+
subtitle,
|
|
4811
|
+
version,
|
|
4812
|
+
tips,
|
|
4813
|
+
logo,
|
|
4814
|
+
model,
|
|
4815
|
+
color: color2 = DEFAULT_COLOR2
|
|
4816
|
+
}) {
|
|
4817
|
+
const logoNode = logo ?? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(ClawdLogo, { color: color2 });
|
|
4818
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_ink_renderer41.Box, { flexDirection: "column", gap: 1, marginTop: 1, marginLeft: 1, children: [
|
|
4819
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_ink_renderer41.Box, { flexDirection: "row", gap: 2, alignItems: "flex-start", children: [
|
|
4820
|
+
logoNode,
|
|
4821
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_ink_renderer41.Box, { flexDirection: "column", justifyContent: "center", children: [
|
|
4822
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_ink_renderer41.Box, { flexDirection: "row", gap: 1, children: [
|
|
4823
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_ink_renderer41.Text, { bold: true, color: color2, children: appName }),
|
|
4824
|
+
version && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_ink_renderer41.Text, { dimColor: true, children: `v${version}` })
|
|
4825
|
+
] }),
|
|
4826
|
+
subtitle && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_ink_renderer41.Text, { dimColor: true, children: subtitle }),
|
|
4827
|
+
model && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_ink_renderer41.Text, { dimColor: true, children: model })
|
|
4828
|
+
] })
|
|
4829
|
+
] }),
|
|
4830
|
+
tips && tips.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_ink_renderer41.Box, { flexDirection: "column", gap: 0, children: [
|
|
4831
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_ink_renderer41.Text, { dimColor: true, children: "Tips:" }),
|
|
4832
|
+
tips.map((tip, i) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_ink_renderer41.Text, { dimColor: true, children: ` - ${tip}` }, i))
|
|
4833
|
+
] })
|
|
4834
|
+
] });
|
|
4835
|
+
}
|
|
4836
|
+
|
|
4837
|
+
// src/agent/useAgent.ts
|
|
4838
|
+
var import_react27 = require("react");
|
|
4839
|
+
var _msgId = 0;
|
|
4840
|
+
function nextId() {
|
|
4841
|
+
return `msg-${++_msgId}-${Date.now()}`;
|
|
4842
|
+
}
|
|
4843
|
+
function toolCallToContent(tc) {
|
|
4844
|
+
return {
|
|
4845
|
+
type: "tool_use",
|
|
4846
|
+
toolName: tc.name,
|
|
4847
|
+
input: JSON.stringify(tc.input, null, 2),
|
|
4848
|
+
status: "running"
|
|
4849
|
+
};
|
|
4850
|
+
}
|
|
4851
|
+
function useAgent({ agent, onError }) {
|
|
4852
|
+
const [messages, setMessages] = (0, import_react27.useState)([]);
|
|
4853
|
+
const [isLoading, setIsLoading] = (0, import_react27.useState)(false);
|
|
4854
|
+
const [streamingContent, setStreamingContent] = (0, import_react27.useState)(null);
|
|
4855
|
+
const [permissionRequest, setPermissionRequest] = (0, import_react27.useState)(null);
|
|
4856
|
+
const isRunningRef = (0, import_react27.useRef)(false);
|
|
4857
|
+
const toolMsgMap = (0, import_react27.useRef)(/* @__PURE__ */ new Map());
|
|
4858
|
+
(0, import_react27.useEffect)(() => {
|
|
4859
|
+
agent.setPermissionHandler(async (request) => {
|
|
4860
|
+
return new Promise((resolve) => {
|
|
4861
|
+
setPermissionRequest({
|
|
4862
|
+
toolName: request.tool,
|
|
4863
|
+
description: `Tool "${request.tool}" wants to execute`,
|
|
4864
|
+
details: JSON.stringify(request.input, null, 2),
|
|
4865
|
+
resolve: (decision) => {
|
|
4866
|
+
setPermissionRequest(null);
|
|
4867
|
+
resolve({ decision });
|
|
4868
|
+
}
|
|
4869
|
+
});
|
|
4870
|
+
});
|
|
4871
|
+
});
|
|
4872
|
+
}, [agent]);
|
|
4873
|
+
const cancel = (0, import_react27.useCallback)(() => {
|
|
4874
|
+
agent.abort();
|
|
4875
|
+
isRunningRef.current = false;
|
|
4876
|
+
setIsLoading(false);
|
|
4877
|
+
setStreamingContent(null);
|
|
4878
|
+
setPermissionRequest(null);
|
|
4879
|
+
}, [agent]);
|
|
4880
|
+
const clearMessages = (0, import_react27.useCallback)(() => {
|
|
4881
|
+
agent.clearMessages();
|
|
4882
|
+
setMessages([]);
|
|
4883
|
+
setStreamingContent(null);
|
|
4884
|
+
setPermissionRequest(null);
|
|
4885
|
+
}, [agent]);
|
|
4886
|
+
const submit = (0, import_react27.useCallback)(
|
|
4887
|
+
(input) => {
|
|
4888
|
+
if (isRunningRef.current) return;
|
|
4889
|
+
const trimmed = input.trim();
|
|
4890
|
+
if (!trimmed) return;
|
|
4891
|
+
const userMsg = {
|
|
4892
|
+
id: nextId(),
|
|
4893
|
+
role: "user",
|
|
4894
|
+
content: trimmed,
|
|
4895
|
+
timestamp: Date.now()
|
|
4896
|
+
};
|
|
4897
|
+
setMessages((prev) => [...prev, userMsg]);
|
|
4898
|
+
isRunningRef.current = true;
|
|
4899
|
+
setIsLoading(true);
|
|
4900
|
+
setStreamingContent(null);
|
|
4901
|
+
(async () => {
|
|
4902
|
+
let accumulated = "";
|
|
4903
|
+
try {
|
|
4904
|
+
for await (const event of agent.run(trimmed)) {
|
|
4905
|
+
switch (event.type) {
|
|
4906
|
+
case "text": {
|
|
4907
|
+
accumulated += event.text;
|
|
4908
|
+
setStreamingContent(accumulated);
|
|
4909
|
+
break;
|
|
4910
|
+
}
|
|
4911
|
+
case "tool_call": {
|
|
4912
|
+
const msgId = nextId();
|
|
4913
|
+
toolMsgMap.current.set(event.toolCall.id, msgId);
|
|
4914
|
+
const toolMsg = {
|
|
4915
|
+
id: msgId,
|
|
4916
|
+
role: "assistant",
|
|
4917
|
+
content: [toolCallToContent(event.toolCall)],
|
|
4918
|
+
timestamp: Date.now()
|
|
4919
|
+
};
|
|
4920
|
+
setMessages((prev) => [...prev, toolMsg]);
|
|
4921
|
+
break;
|
|
4922
|
+
}
|
|
4923
|
+
case "tool_result": {
|
|
4924
|
+
const targetId = toolMsgMap.current.get(event.toolCallId);
|
|
4925
|
+
if (targetId) {
|
|
4926
|
+
setMessages(
|
|
4927
|
+
(prev) => prev.map((m) => {
|
|
4928
|
+
if (m.id !== targetId) return m;
|
|
4929
|
+
const contents = Array.isArray(m.content) ? m.content : [];
|
|
4930
|
+
return {
|
|
4931
|
+
...m,
|
|
4932
|
+
content: contents.map((c) => {
|
|
4933
|
+
if (c.type !== "tool_use") return c;
|
|
4934
|
+
return {
|
|
4935
|
+
...c,
|
|
4936
|
+
result: event.result.content,
|
|
4937
|
+
status: event.result.isError ? "error" : "success"
|
|
4938
|
+
};
|
|
4939
|
+
})
|
|
4940
|
+
};
|
|
4941
|
+
})
|
|
4942
|
+
);
|
|
4943
|
+
toolMsgMap.current.delete(event.toolCallId);
|
|
4944
|
+
}
|
|
4945
|
+
break;
|
|
4946
|
+
}
|
|
4947
|
+
case "error": {
|
|
4948
|
+
onError?.(event.error);
|
|
4949
|
+
break;
|
|
4950
|
+
}
|
|
4951
|
+
case "done": {
|
|
4952
|
+
if (accumulated.length > 0) {
|
|
4953
|
+
const assistantMsg = {
|
|
4954
|
+
id: nextId(),
|
|
4955
|
+
role: "assistant",
|
|
4956
|
+
content: accumulated,
|
|
4957
|
+
timestamp: Date.now()
|
|
4958
|
+
};
|
|
4959
|
+
setMessages((prev) => [...prev, assistantMsg]);
|
|
4960
|
+
}
|
|
4961
|
+
accumulated = "";
|
|
4962
|
+
setStreamingContent(null);
|
|
4963
|
+
break;
|
|
4964
|
+
}
|
|
4965
|
+
}
|
|
4966
|
+
}
|
|
4967
|
+
} catch (err) {
|
|
4968
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
4969
|
+
onError?.(error);
|
|
4970
|
+
} finally {
|
|
4971
|
+
isRunningRef.current = false;
|
|
4972
|
+
setIsLoading(false);
|
|
4973
|
+
setStreamingContent(null);
|
|
4974
|
+
}
|
|
4975
|
+
})();
|
|
4976
|
+
},
|
|
4977
|
+
[agent, onError]
|
|
4978
|
+
);
|
|
4979
|
+
return {
|
|
4980
|
+
messages,
|
|
4981
|
+
isLoading,
|
|
4982
|
+
streamingContent,
|
|
4983
|
+
permissionRequest,
|
|
4984
|
+
submit,
|
|
4985
|
+
cancel,
|
|
4986
|
+
clearMessages
|
|
4987
|
+
};
|
|
4988
|
+
}
|
|
4989
|
+
|
|
4990
|
+
// src/agent/AgentProvider.tsx
|
|
4991
|
+
var import_react28 = require("react");
|
|
4992
|
+
var import_jsx_runtime31 = require("react/jsx-runtime");
|
|
4993
|
+
var AgentContext = (0, import_react28.createContext)(null);
|
|
4994
|
+
function AgentProvider({
|
|
4995
|
+
agent,
|
|
4996
|
+
model = "unknown",
|
|
4997
|
+
onError,
|
|
4998
|
+
children
|
|
4999
|
+
}) {
|
|
5000
|
+
const agentState = useAgent({ agent, onError });
|
|
5001
|
+
const value = (0, import_react28.useMemo)(
|
|
5002
|
+
() => ({
|
|
5003
|
+
...agentState,
|
|
5004
|
+
agent,
|
|
5005
|
+
model
|
|
5006
|
+
}),
|
|
5007
|
+
[agentState, agent, model]
|
|
5008
|
+
);
|
|
5009
|
+
return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(AgentContext.Provider, { value, children });
|
|
5010
|
+
}
|
|
5011
|
+
function useAgentContext() {
|
|
5012
|
+
const ctx = (0, import_react28.useContext)(AgentContext);
|
|
5013
|
+
if (!ctx) {
|
|
5014
|
+
throw new Error(
|
|
5015
|
+
"useAgentContext must be used within an <AgentProvider>. Wrap your component tree with <AgentProvider agent={agent}>."
|
|
5016
|
+
);
|
|
5017
|
+
}
|
|
5018
|
+
return ctx;
|
|
5019
|
+
}
|
|
5020
|
+
|
|
5021
|
+
// src/agent/AgentREPL.tsx
|
|
5022
|
+
var import_react29 = require("react");
|
|
5023
|
+
var import_jsx_runtime32 = require("react/jsx-runtime");
|
|
5024
|
+
function AgentREPLInner({
|
|
5025
|
+
commands,
|
|
5026
|
+
welcome,
|
|
5027
|
+
placeholder,
|
|
5028
|
+
onExit
|
|
5029
|
+
}) {
|
|
5030
|
+
const {
|
|
5031
|
+
messages,
|
|
5032
|
+
isLoading,
|
|
5033
|
+
streamingContent,
|
|
5034
|
+
permissionRequest,
|
|
5035
|
+
submit,
|
|
5036
|
+
model,
|
|
5037
|
+
clearMessages
|
|
5038
|
+
} = useAgentContext();
|
|
5039
|
+
const permissionState = (0, import_react29.useMemo)(() => {
|
|
5040
|
+
if (!permissionRequest) return void 0;
|
|
5041
|
+
return {
|
|
5042
|
+
toolName: permissionRequest.toolName,
|
|
5043
|
+
description: permissionRequest.description,
|
|
5044
|
+
details: permissionRequest.details,
|
|
5045
|
+
onDecision: (action) => {
|
|
5046
|
+
permissionRequest.resolve(action === "deny" ? "deny" : "allow");
|
|
5047
|
+
}
|
|
5048
|
+
};
|
|
5049
|
+
}, [permissionRequest]);
|
|
5050
|
+
const allCommands = (0, import_react29.useMemo)(() => {
|
|
5051
|
+
const builtIn = [
|
|
5052
|
+
{
|
|
5053
|
+
name: "clear",
|
|
5054
|
+
description: "Clear conversation history",
|
|
5055
|
+
onExecute: () => clearMessages()
|
|
5056
|
+
}
|
|
5057
|
+
];
|
|
5058
|
+
return [...builtIn, ...commands ?? []];
|
|
5059
|
+
}, [commands, clearMessages]);
|
|
5060
|
+
const handleSubmit = (0, import_react29.useCallback)(
|
|
5061
|
+
async (input) => {
|
|
5062
|
+
submit(input);
|
|
5063
|
+
},
|
|
5064
|
+
[submit]
|
|
5065
|
+
);
|
|
5066
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
5067
|
+
REPL,
|
|
5068
|
+
{
|
|
5069
|
+
onSubmit: handleSubmit,
|
|
5070
|
+
onExit,
|
|
5071
|
+
messages,
|
|
5072
|
+
isLoading,
|
|
5073
|
+
streamingContent,
|
|
5074
|
+
permissionRequest: permissionState,
|
|
5075
|
+
commands: allCommands,
|
|
5076
|
+
model,
|
|
5077
|
+
welcome,
|
|
5078
|
+
placeholder
|
|
5079
|
+
}
|
|
5080
|
+
);
|
|
5081
|
+
}
|
|
5082
|
+
function AgentREPL({
|
|
5083
|
+
agent,
|
|
5084
|
+
model,
|
|
5085
|
+
commands,
|
|
5086
|
+
welcome,
|
|
5087
|
+
placeholder,
|
|
5088
|
+
onError,
|
|
5089
|
+
onExit
|
|
5090
|
+
}) {
|
|
5091
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(AgentProvider, { agent, model, onError, children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
5092
|
+
AgentREPLInner,
|
|
5093
|
+
{
|
|
5094
|
+
commands,
|
|
5095
|
+
welcome,
|
|
5096
|
+
placeholder,
|
|
5097
|
+
onExit
|
|
5098
|
+
}
|
|
5099
|
+
) });
|
|
5100
|
+
}
|
|
5101
|
+
|
|
5102
|
+
// src/AuthFlow.tsx
|
|
5103
|
+
var import_react30 = require("react");
|
|
5104
|
+
var import_ink_renderer42 = require("@claude-code-kit/ink-renderer");
|
|
5105
|
+
var import_jsx_runtime33 = require("react/jsx-runtime");
|
|
5106
|
+
function CredentialInput({
|
|
5107
|
+
label,
|
|
5108
|
+
masked,
|
|
5109
|
+
onSubmit,
|
|
5110
|
+
onCancel
|
|
5111
|
+
}) {
|
|
5112
|
+
const [value, setValue] = (0, import_react30.useState)("");
|
|
5113
|
+
const [cursor, setCursor] = (0, import_react30.useState)(0);
|
|
5114
|
+
(0, import_ink_renderer42.useInput)((input, key) => {
|
|
5115
|
+
if (key.escape) {
|
|
5116
|
+
onCancel?.();
|
|
5117
|
+
return;
|
|
5118
|
+
}
|
|
5119
|
+
if (key.return) {
|
|
5120
|
+
if (value.length > 0) onSubmit(value);
|
|
5121
|
+
return;
|
|
5122
|
+
}
|
|
5123
|
+
if (key.backspace) {
|
|
5124
|
+
if (cursor > 0) {
|
|
5125
|
+
setValue((v) => v.slice(0, cursor - 1) + v.slice(cursor));
|
|
5126
|
+
setCursor((c) => c - 1);
|
|
5127
|
+
}
|
|
5128
|
+
return;
|
|
5129
|
+
}
|
|
5130
|
+
if (key.leftArrow) {
|
|
5131
|
+
setCursor((c) => Math.max(0, c - 1));
|
|
5132
|
+
return;
|
|
5133
|
+
}
|
|
5134
|
+
if (key.rightArrow) {
|
|
5135
|
+
setCursor((c) => Math.min(value.length, c + 1));
|
|
5136
|
+
return;
|
|
5137
|
+
}
|
|
5138
|
+
if (key.ctrl || key.meta) return;
|
|
5139
|
+
if (input.length > 0) {
|
|
5140
|
+
setValue((v) => v.slice(0, cursor) + input + v.slice(cursor));
|
|
5141
|
+
setCursor((c) => c + input.length);
|
|
5142
|
+
}
|
|
5143
|
+
});
|
|
5144
|
+
const display = masked ? "*".repeat(value.length) : value;
|
|
5145
|
+
const before = display.slice(0, cursor);
|
|
5146
|
+
const at = cursor < display.length ? display[cursor] : " ";
|
|
5147
|
+
const after = cursor < display.length ? display.slice(cursor + 1) : "";
|
|
5148
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_ink_renderer42.Box, { flexDirection: "column", children: [
|
|
5149
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_ink_renderer42.Text, { bold: true, children: label }),
|
|
5150
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_ink_renderer42.Box, { children: [
|
|
5151
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_ink_renderer42.Text, { color: "cyan", children: "> " }),
|
|
5152
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_ink_renderer42.Text, { children: [
|
|
5153
|
+
before,
|
|
5154
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_ink_renderer42.Text, { inverse: true, children: at }),
|
|
5155
|
+
after
|
|
5156
|
+
] })
|
|
5157
|
+
] }),
|
|
5158
|
+
value.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_ink_renderer42.Text, { dimColor: true, children: " Type your credential and press Enter" })
|
|
5159
|
+
] });
|
|
5160
|
+
}
|
|
5161
|
+
function AuthFlowUI({
|
|
5162
|
+
auth,
|
|
5163
|
+
onComplete,
|
|
5164
|
+
onCancel,
|
|
5165
|
+
title = "Authentication"
|
|
5166
|
+
}) {
|
|
5167
|
+
const [phase, setPhase] = (0, import_react30.useState)({ type: "select-provider" });
|
|
5168
|
+
const [baseURL, setBaseURL] = (0, import_react30.useState)();
|
|
5169
|
+
const [error, setError] = (0, import_react30.useState)();
|
|
5170
|
+
const flowState = auth.interactive();
|
|
5171
|
+
const providerOptions = (flowState.providers ?? []).map((p) => ({
|
|
5172
|
+
value: p.name,
|
|
5173
|
+
label: `${p.displayName}`,
|
|
5174
|
+
description: p.description
|
|
5175
|
+
}));
|
|
5176
|
+
const handleProviderSelect = (0, import_react30.useCallback)((providerName) => {
|
|
5177
|
+
setError(void 0);
|
|
5178
|
+
try {
|
|
5179
|
+
const state = auth.selectProvider(providerName);
|
|
5180
|
+
if (state.step === "done" && state.result) {
|
|
5181
|
+
onComplete(state.result.provider, state.result.providerName, state.result.model);
|
|
5182
|
+
setPhase({ type: "done" });
|
|
5183
|
+
return;
|
|
5184
|
+
}
|
|
5185
|
+
if (state.step === "input-credentials" && state.currentAuthMethod) {
|
|
5186
|
+
const method = state.currentAuthMethod;
|
|
5187
|
+
const needsBaseURL = method.type === "base-url-key" && !method.defaultBaseURL;
|
|
5188
|
+
setPhase({
|
|
5189
|
+
type: "input-credentials",
|
|
5190
|
+
providerName,
|
|
5191
|
+
method,
|
|
5192
|
+
needsBaseURL
|
|
5193
|
+
});
|
|
5194
|
+
return;
|
|
5195
|
+
}
|
|
5196
|
+
if (state.step === "select-model" && state.models) {
|
|
5197
|
+
setPhase({
|
|
5198
|
+
type: "select-model",
|
|
5199
|
+
providerName,
|
|
5200
|
+
method: state.currentAuthMethod,
|
|
5201
|
+
models: state.models,
|
|
5202
|
+
defaultModel: state.currentModel
|
|
5203
|
+
});
|
|
5204
|
+
return;
|
|
5205
|
+
}
|
|
5206
|
+
if (state.step === "select-auth-method" && state.authMethods) {
|
|
5207
|
+
const method = state.authMethods[0];
|
|
5208
|
+
const needsBaseURL = method.type === "base-url-key" && !("defaultBaseURL" in method && method.defaultBaseURL);
|
|
5209
|
+
setPhase({
|
|
5210
|
+
type: "input-credentials",
|
|
5211
|
+
providerName,
|
|
5212
|
+
method,
|
|
5213
|
+
needsBaseURL: needsBaseURL && method.type === "base-url-key"
|
|
5214
|
+
});
|
|
5215
|
+
return;
|
|
5216
|
+
}
|
|
5217
|
+
} catch (err) {
|
|
5218
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
5219
|
+
}
|
|
5220
|
+
}, [auth, onComplete]);
|
|
5221
|
+
const handleBaseURLSubmit = (0, import_react30.useCallback)((url) => {
|
|
5222
|
+
setBaseURL(url);
|
|
5223
|
+
}, []);
|
|
5224
|
+
const handleCredentialSubmit = (0, import_react30.useCallback)(async (apiKey) => {
|
|
5225
|
+
if (phase.type !== "input-credentials") return;
|
|
5226
|
+
setError(void 0);
|
|
5227
|
+
try {
|
|
5228
|
+
const credentials = {
|
|
5229
|
+
apiKey,
|
|
5230
|
+
baseURL: baseURL || (phase.method.type === "base-url-key" ? phase.method.defaultBaseURL : void 0)
|
|
5231
|
+
};
|
|
5232
|
+
const state = await auth.inputCredentials(phase.providerName, phase.method, credentials);
|
|
5233
|
+
if (state.step === "done" && state.result) {
|
|
5234
|
+
onComplete(state.result.provider, state.result.providerName, state.result.model);
|
|
5235
|
+
setPhase({ type: "done" });
|
|
5236
|
+
return;
|
|
5237
|
+
}
|
|
5238
|
+
if (state.step === "select-model" && state.models) {
|
|
5239
|
+
setPhase({
|
|
5240
|
+
type: "select-model",
|
|
5241
|
+
providerName: phase.providerName,
|
|
5242
|
+
method: phase.method,
|
|
5243
|
+
models: state.models,
|
|
5244
|
+
defaultModel: state.currentModel
|
|
5245
|
+
});
|
|
5246
|
+
return;
|
|
5247
|
+
}
|
|
5248
|
+
} catch (err) {
|
|
5249
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
5250
|
+
}
|
|
5251
|
+
}, [auth, phase, baseURL, onComplete]);
|
|
5252
|
+
const handleModelSelect = (0, import_react30.useCallback)(async (model) => {
|
|
5253
|
+
if (phase.type !== "select-model") return;
|
|
5254
|
+
setError(void 0);
|
|
5255
|
+
try {
|
|
5256
|
+
const state = await auth.selectModel(phase.providerName, phase.method, model);
|
|
5257
|
+
if (state.step === "done" && state.result) {
|
|
5258
|
+
onComplete(state.result.provider, state.result.providerName, state.result.model);
|
|
5259
|
+
setPhase({ type: "done" });
|
|
5260
|
+
}
|
|
5261
|
+
} catch (err) {
|
|
5262
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
5263
|
+
}
|
|
5264
|
+
}, [auth, phase, onComplete]);
|
|
5265
|
+
const handleCancel = (0, import_react30.useCallback)(() => {
|
|
5266
|
+
if (phase.type === "select-provider") {
|
|
5267
|
+
onCancel?.();
|
|
5268
|
+
} else {
|
|
5269
|
+
setPhase({ type: "select-provider" });
|
|
5270
|
+
setBaseURL(void 0);
|
|
5271
|
+
setError(void 0);
|
|
5272
|
+
}
|
|
5273
|
+
}, [phase, onCancel]);
|
|
5274
|
+
if (phase.type === "done") {
|
|
5275
|
+
return null;
|
|
5276
|
+
}
|
|
5277
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_ink_renderer42.Box, { flexDirection: "column", marginTop: 1, marginLeft: 1, children: [
|
|
5278
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_ink_renderer42.Box, { marginBottom: 1, children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_ink_renderer42.Text, { bold: true, color: "#DA7756", children: title }) }),
|
|
5279
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Divider, {}),
|
|
5280
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_ink_renderer42.Box, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_ink_renderer42.Text, { color: "red", children: [
|
|
5281
|
+
"Error: ",
|
|
5282
|
+
error
|
|
5283
|
+
] }) }),
|
|
5284
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_ink_renderer42.Box, { marginTop: 1, children: [
|
|
5285
|
+
phase.type === "select-provider" && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
5286
|
+
Select,
|
|
5287
|
+
{
|
|
5288
|
+
title: "Select a provider:",
|
|
5289
|
+
options: providerOptions,
|
|
5290
|
+
onChange: handleProviderSelect,
|
|
5291
|
+
onCancel: handleCancel
|
|
5292
|
+
}
|
|
5293
|
+
),
|
|
5294
|
+
phase.type === "input-credentials" && phase.method.type === "base-url-key" && phase.needsBaseURL && !baseURL && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
5295
|
+
CredentialInput,
|
|
5296
|
+
{
|
|
5297
|
+
label: "Enter Base URL:",
|
|
5298
|
+
masked: false,
|
|
5299
|
+
onSubmit: handleBaseURLSubmit,
|
|
5300
|
+
onCancel: handleCancel
|
|
5301
|
+
}
|
|
5302
|
+
),
|
|
5303
|
+
phase.type === "input-credentials" && !(phase.method.type === "base-url-key" && phase.needsBaseURL && !baseURL) && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
5304
|
+
CredentialInput,
|
|
5305
|
+
{
|
|
5306
|
+
label: phase.method.type === "api-key" || phase.method.type === "base-url-key" ? phase.method.inputLabel ?? "Enter API Key:" : "Enter API Key:",
|
|
5307
|
+
masked: true,
|
|
5308
|
+
onSubmit: handleCredentialSubmit,
|
|
5309
|
+
onCancel: handleCancel
|
|
5310
|
+
}
|
|
5311
|
+
),
|
|
5312
|
+
phase.type === "select-model" && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
5313
|
+
Select,
|
|
5314
|
+
{
|
|
5315
|
+
title: "Select a model:",
|
|
5316
|
+
options: phase.models.map((m) => ({
|
|
5317
|
+
value: m,
|
|
5318
|
+
label: m,
|
|
5319
|
+
description: m === phase.defaultModel ? "(default)" : void 0
|
|
5320
|
+
})),
|
|
5321
|
+
defaultValue: phase.defaultModel,
|
|
5322
|
+
onChange: handleModelSelect,
|
|
5323
|
+
onCancel: handleCancel
|
|
5324
|
+
}
|
|
5325
|
+
)
|
|
5326
|
+
] }),
|
|
5327
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_ink_renderer42.Box, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_ink_renderer42.Text, { dimColor: true, children: [
|
|
5328
|
+
"Esc to ",
|
|
5329
|
+
phase.type === "select-provider" ? "cancel" : "go back"
|
|
5330
|
+
] }) })
|
|
5331
|
+
] });
|
|
5332
|
+
}
|
|
3860
5333
|
// Annotate the CommonJS export names for ESM import in node:
|
|
3861
5334
|
0 && (module.exports = {
|
|
5335
|
+
AgentContext,
|
|
5336
|
+
AgentProvider,
|
|
5337
|
+
AgentREPL,
|
|
5338
|
+
AuthFlowUI,
|
|
5339
|
+
BashPermissionContent,
|
|
3862
5340
|
Byline,
|
|
5341
|
+
ClawdLogo,
|
|
3863
5342
|
CommandRegistry,
|
|
3864
5343
|
DEFAULT_BINDINGS,
|
|
3865
5344
|
Dialog,
|
|
5345
|
+
DiffView,
|
|
3866
5346
|
Divider,
|
|
5347
|
+
FileEditPermissionContent,
|
|
3867
5348
|
FuzzyPicker,
|
|
3868
5349
|
KeybindingSetup,
|
|
3869
5350
|
KeyboardShortcutHint,
|
|
@@ -3874,10 +5355,12 @@ function useTabsWidth() {
|
|
|
3874
5355
|
MessageList,
|
|
3875
5356
|
MultiSelect,
|
|
3876
5357
|
Pane,
|
|
5358
|
+
PermissionRequest,
|
|
3877
5359
|
ProgressBar,
|
|
3878
5360
|
PromptInput,
|
|
3879
5361
|
REPL,
|
|
3880
5362
|
Ratchet,
|
|
5363
|
+
SearchOverlay,
|
|
3881
5364
|
Select,
|
|
3882
5365
|
Spinner,
|
|
3883
5366
|
StatusIcon,
|
|
@@ -3890,6 +5373,8 @@ function useTabsWidth() {
|
|
|
3890
5373
|
ThemeProvider,
|
|
3891
5374
|
ThemedBox,
|
|
3892
5375
|
ThemedText,
|
|
5376
|
+
VirtualList,
|
|
5377
|
+
WelcomeScreen,
|
|
3893
5378
|
clearCommand,
|
|
3894
5379
|
color,
|
|
3895
5380
|
createCommandRegistry,
|
|
@@ -3899,14 +5384,19 @@ function useTabsWidth() {
|
|
|
3899
5384
|
exitCommand,
|
|
3900
5385
|
getTheme,
|
|
3901
5386
|
helpCommand,
|
|
5387
|
+
parseUnifiedDiff,
|
|
5388
|
+
useAgent,
|
|
5389
|
+
useAgentContext,
|
|
3902
5390
|
useDoublePress,
|
|
3903
5391
|
useKeybinding,
|
|
3904
5392
|
useKeybindings,
|
|
3905
5393
|
usePreviewTheme,
|
|
5394
|
+
useSearch,
|
|
3906
5395
|
useStatusLine,
|
|
3907
5396
|
useTabsWidth,
|
|
3908
5397
|
useTerminalSize,
|
|
3909
5398
|
useTheme,
|
|
3910
5399
|
useThemeSetting,
|
|
5400
|
+
useVirtualScroll,
|
|
3911
5401
|
...require("@claude-code-kit/ink-renderer")
|
|
3912
5402
|
});
|