@nomad-e/bluma-cli 0.0.96 → 0.0.97
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/main.js +696 -585
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -6,103 +6,76 @@ import { EventEmitter as EventEmitter2 } from "events";
|
|
|
6
6
|
import { v4 as uuidv42 } from "uuid";
|
|
7
7
|
|
|
8
8
|
// src/app/ui/App.tsx
|
|
9
|
-
import { useState as useState5, useEffect as
|
|
10
|
-
import { Box as
|
|
9
|
+
import { useState as useState5, useEffect as useEffect5, useRef as useRef4, useCallback as useCallback2, memo as memo5 } from "react";
|
|
10
|
+
import { Box as Box15, Text as Text14, Static } from "ink";
|
|
11
11
|
|
|
12
12
|
// src/app/ui/layout.tsx
|
|
13
13
|
import { Box, Text } from "ink";
|
|
14
|
-
import
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
/* @__PURE__ */
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
font: "block",
|
|
29
|
-
colors: [BRAND_COLORS.main, BRAND_COLORS.accent, BRAND_COLORS.shadow]
|
|
30
|
-
}
|
|
31
|
-
) }),
|
|
32
|
-
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", paddingX: 1, children: [
|
|
33
|
-
/* @__PURE__ */ jsx(Text, { children: "How to get started with BluMa:" }),
|
|
34
|
-
/* @__PURE__ */ jsx(Text, { children: "1. You can ask questions, modify files, or execute commands directly." }),
|
|
35
|
-
/* @__PURE__ */ jsx(Text, { children: "2. Be as clear and specific as possible to get accurate responses." }),
|
|
36
|
-
/* @__PURE__ */ jsxs(Text, { children: [
|
|
37
|
-
"3. Run ",
|
|
38
|
-
/* @__PURE__ */ jsx(Text, { color: "magenta", children: "/init" }),
|
|
39
|
-
" to create a",
|
|
40
|
-
" ",
|
|
41
|
-
/* @__PURE__ */ jsx(Text, { color: "magenta", children: "BluMa.md" }),
|
|
42
|
-
", file with instructions for BluMa."
|
|
14
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
15
|
+
var Header = ({
|
|
16
|
+
sessionId: sessionId2,
|
|
17
|
+
workdir
|
|
18
|
+
}) => {
|
|
19
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [
|
|
20
|
+
/* @__PURE__ */ jsxs(Box, { marginBottom: 1, children: [
|
|
21
|
+
/* @__PURE__ */ jsx(Text, { bold: true, color: "magenta", children: "BluMa" }),
|
|
22
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: " \u2022 AI Coding Assistant" })
|
|
23
|
+
] }),
|
|
24
|
+
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", paddingX: 1, marginBottom: 1, children: [
|
|
25
|
+
/* @__PURE__ */ jsxs(Box, { children: [
|
|
26
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "workspace " }),
|
|
27
|
+
/* @__PURE__ */ jsx(Text, { color: "cyan", children: workdir })
|
|
43
28
|
] }),
|
|
44
|
-
/* @__PURE__ */ jsxs(
|
|
45
|
-
"
|
|
46
|
-
/* @__PURE__ */
|
|
47
|
-
|
|
29
|
+
/* @__PURE__ */ jsxs(Box, { marginTop: 0, children: [
|
|
30
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "session " }),
|
|
31
|
+
/* @__PURE__ */ jsxs(Text, { color: "gray", children: [
|
|
32
|
+
sessionId2.slice(0, 8),
|
|
33
|
+
"..."
|
|
34
|
+
] })
|
|
48
35
|
] })
|
|
49
|
-
] })
|
|
36
|
+
] }),
|
|
37
|
+
/* @__PURE__ */ jsx(Box, { paddingX: 1, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: "/init /tools /mcp /clear /help" }) })
|
|
50
38
|
] });
|
|
51
39
|
};
|
|
52
|
-
var SessionInfo = ({
|
|
53
|
-
sessionId: sessionId2,
|
|
54
|
-
// ID único da sessão atual, para segregação ou rastreio
|
|
55
|
-
workdir,
|
|
56
|
-
// Diretório de trabalho atual do BluMa, útil para saber contexto da execução
|
|
57
|
-
toolsCount,
|
|
58
|
-
// Número de ferramentas ativas carregadas pelo MCP
|
|
59
|
-
mcpStatus
|
|
60
|
-
// Estado da conexão central MCP (connecting/connected)
|
|
61
|
-
}) => /* @__PURE__ */ jsx(
|
|
62
|
-
Box,
|
|
63
|
-
{
|
|
64
|
-
borderStyle: "round",
|
|
65
|
-
borderColor: "gray",
|
|
66
|
-
flexDirection: "column",
|
|
67
|
-
marginBottom: 1,
|
|
68
|
-
children: /* @__PURE__ */ jsxs(
|
|
69
|
-
Box,
|
|
70
|
-
{
|
|
71
|
-
marginLeft: 1,
|
|
72
|
-
flexDirection: "column",
|
|
73
|
-
children: [
|
|
74
|
-
/* @__PURE__ */ jsxs(Text, { children: [
|
|
75
|
-
/* @__PURE__ */ jsx(Text, { bold: true, color: "white", children: "localhost" }),
|
|
76
|
-
/* @__PURE__ */ jsx(Text, { color: "gray", children: " session:" }),
|
|
77
|
-
" ",
|
|
78
|
-
/* @__PURE__ */ jsx(Text, { color: "magenta", children: sessionId2 })
|
|
79
|
-
] }),
|
|
80
|
-
/* @__PURE__ */ jsxs(Text, { children: [
|
|
81
|
-
/* @__PURE__ */ jsx(Text, { color: "magenta", children: "\u21B3" }),
|
|
82
|
-
" ",
|
|
83
|
-
/* @__PURE__ */ jsxs(Text, { color: "gray", children: [
|
|
84
|
-
"workdir: ",
|
|
85
|
-
workdir
|
|
86
|
-
] })
|
|
87
|
-
] }),
|
|
88
|
-
/* @__PURE__ */ jsxs(Text, { children: [
|
|
89
|
-
/* @__PURE__ */ jsx(Text, { color: "magenta", children: "\u21B3" }),
|
|
90
|
-
" ",
|
|
91
|
-
/* @__PURE__ */ jsx(Text, { color: "gray", children: "mcp: " }),
|
|
92
|
-
/* @__PURE__ */ jsx(Text, { color: mcpStatus === "connected" ? "green" : "yellow", children: mcpStatus })
|
|
93
|
-
] })
|
|
94
|
-
]
|
|
95
|
-
}
|
|
96
|
-
)
|
|
97
|
-
}
|
|
98
|
-
);
|
|
99
40
|
|
|
100
41
|
// src/app/ui/components/InputPrompt.tsx
|
|
101
42
|
import { Box as Box2, Text as Text2, useStdout, useInput as useInput2 } from "ink";
|
|
102
43
|
|
|
103
44
|
// src/app/ui/utils/useSimpleInputBuffer.ts
|
|
104
|
-
import { useReducer } from "react";
|
|
45
|
+
import { useReducer, useRef, useCallback, useEffect } from "react";
|
|
105
46
|
import { useInput } from "ink";
|
|
47
|
+
function getLineStart(text, cursorPos) {
|
|
48
|
+
let pos = cursorPos - 1;
|
|
49
|
+
while (pos >= 0 && text[pos] !== "\n") {
|
|
50
|
+
pos--;
|
|
51
|
+
}
|
|
52
|
+
return pos + 1;
|
|
53
|
+
}
|
|
54
|
+
function getLineEnd(text, cursorPos) {
|
|
55
|
+
let pos = cursorPos;
|
|
56
|
+
while (pos < text.length && text[pos] !== "\n") {
|
|
57
|
+
pos++;
|
|
58
|
+
}
|
|
59
|
+
return pos;
|
|
60
|
+
}
|
|
61
|
+
function moveToAdjacentLine(text, cursorPos, direction) {
|
|
62
|
+
const currentLineStart = getLineStart(text, cursorPos);
|
|
63
|
+
const currentLineEnd = getLineEnd(text, cursorPos);
|
|
64
|
+
const column = cursorPos - currentLineStart;
|
|
65
|
+
if (direction === "up") {
|
|
66
|
+
if (currentLineStart === 0) return cursorPos;
|
|
67
|
+
const prevLineEnd = currentLineStart - 1;
|
|
68
|
+
const prevLineStart = getLineStart(text, prevLineEnd);
|
|
69
|
+
const prevLineLength = prevLineEnd - prevLineStart;
|
|
70
|
+
return prevLineStart + Math.min(column, prevLineLength);
|
|
71
|
+
} else {
|
|
72
|
+
if (currentLineEnd === text.length) return cursorPos;
|
|
73
|
+
const nextLineStart = currentLineEnd + 1;
|
|
74
|
+
const nextLineEnd = getLineEnd(text, nextLineStart);
|
|
75
|
+
const nextLineLength = nextLineEnd - nextLineStart;
|
|
76
|
+
return nextLineStart + Math.min(column, nextLineLength);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
106
79
|
function inputReducer(state, action, viewWidth) {
|
|
107
80
|
const adjustView = (newCursorPos, currentViewStart) => {
|
|
108
81
|
if (newCursorPos < currentViewStart) {
|
|
@@ -115,16 +88,51 @@ function inputReducer(state, action, viewWidth) {
|
|
|
115
88
|
};
|
|
116
89
|
switch (action.type) {
|
|
117
90
|
case "INPUT": {
|
|
118
|
-
const cleanInput = action.payload.replace(/(
|
|
91
|
+
const cleanInput = action.payload.replace(/(\r\n|\r)/gm, "\n");
|
|
119
92
|
const newText = state.text.slice(0, state.cursorPosition) + cleanInput + state.text.slice(state.cursorPosition);
|
|
120
93
|
const newCursorPosition = state.cursorPosition + cleanInput.length;
|
|
121
94
|
const newViewStart = adjustView(newCursorPosition, state.viewStart);
|
|
95
|
+
if (newText === state.text && newCursorPosition === state.cursorPosition) {
|
|
96
|
+
return state;
|
|
97
|
+
}
|
|
98
|
+
return { text: newText, cursorPosition: newCursorPosition, viewStart: newViewStart };
|
|
99
|
+
}
|
|
100
|
+
case "NEWLINE": {
|
|
101
|
+
const newText = state.text.slice(0, state.cursorPosition) + "\n" + state.text.slice(state.cursorPosition);
|
|
102
|
+
const newCursorPosition = state.cursorPosition + 1;
|
|
103
|
+
const newViewStart = adjustView(newCursorPosition, state.viewStart);
|
|
122
104
|
return { text: newText, cursorPosition: newCursorPosition, viewStart: newViewStart };
|
|
123
105
|
}
|
|
124
106
|
case "MOVE_CURSOR": {
|
|
125
107
|
let newCursorPosition = state.cursorPosition;
|
|
126
|
-
if (action.direction === "left" && state.cursorPosition > 0)
|
|
127
|
-
|
|
108
|
+
if (action.direction === "left" && state.cursorPosition > 0) {
|
|
109
|
+
newCursorPosition--;
|
|
110
|
+
} else if (action.direction === "right" && state.cursorPosition < state.text.length) {
|
|
111
|
+
newCursorPosition++;
|
|
112
|
+
} else if (action.direction === "up") {
|
|
113
|
+
newCursorPosition = moveToAdjacentLine(state.text, state.cursorPosition, "up");
|
|
114
|
+
} else if (action.direction === "down") {
|
|
115
|
+
newCursorPosition = moveToAdjacentLine(state.text, state.cursorPosition, "down");
|
|
116
|
+
}
|
|
117
|
+
if (newCursorPosition === state.cursorPosition) {
|
|
118
|
+
return state;
|
|
119
|
+
}
|
|
120
|
+
const newViewStart = adjustView(newCursorPosition, state.viewStart);
|
|
121
|
+
return { ...state, cursorPosition: newCursorPosition, viewStart: newViewStart };
|
|
122
|
+
}
|
|
123
|
+
case "MOVE_LINE_START": {
|
|
124
|
+
const newCursorPosition = getLineStart(state.text, state.cursorPosition);
|
|
125
|
+
if (newCursorPosition === state.cursorPosition) {
|
|
126
|
+
return state;
|
|
127
|
+
}
|
|
128
|
+
const newViewStart = adjustView(newCursorPosition, state.viewStart);
|
|
129
|
+
return { ...state, cursorPosition: newCursorPosition, viewStart: newViewStart };
|
|
130
|
+
}
|
|
131
|
+
case "MOVE_LINE_END": {
|
|
132
|
+
const newCursorPosition = getLineEnd(state.text, state.cursorPosition);
|
|
133
|
+
if (newCursorPosition === state.cursorPosition) {
|
|
134
|
+
return state;
|
|
135
|
+
}
|
|
128
136
|
const newViewStart = adjustView(newCursorPosition, state.viewStart);
|
|
129
137
|
return { ...state, cursorPosition: newCursorPosition, viewStart: newViewStart };
|
|
130
138
|
}
|
|
@@ -137,11 +145,18 @@ function inputReducer(state, action, viewWidth) {
|
|
|
137
145
|
}
|
|
138
146
|
return state;
|
|
139
147
|
}
|
|
148
|
+
case "DELETE": {
|
|
149
|
+
if (state.cursorPosition < state.text.length) {
|
|
150
|
+
const newText = state.text.slice(0, state.cursorPosition) + state.text.slice(state.cursorPosition + 1);
|
|
151
|
+
return { ...state, text: newText };
|
|
152
|
+
}
|
|
153
|
+
return state;
|
|
154
|
+
}
|
|
140
155
|
case "SUBMIT": {
|
|
141
156
|
return { text: "", cursorPosition: 0, viewStart: 0 };
|
|
142
157
|
}
|
|
143
158
|
case "SET": {
|
|
144
|
-
const t = action.payload.text.replace(/(
|
|
159
|
+
const t = action.payload.text.replace(/(\r\n|\r)/gm, "\n");
|
|
145
160
|
let newCursorPosition;
|
|
146
161
|
if (typeof action.payload.cursorPosition === "number") {
|
|
147
162
|
newCursorPosition = Math.min(action.payload.cursorPosition, t.length);
|
|
@@ -154,6 +169,14 @@ function inputReducer(state, action, viewWidth) {
|
|
|
154
169
|
const newViewStart = adjustView(newCursorPosition, 0);
|
|
155
170
|
return { text: newText, cursorPosition: newCursorPosition, viewStart: newViewStart };
|
|
156
171
|
}
|
|
172
|
+
case "SET_CURSOR": {
|
|
173
|
+
const newCursorPosition = Math.max(0, Math.min(action.payload, state.text.length));
|
|
174
|
+
if (newCursorPosition === state.cursorPosition) {
|
|
175
|
+
return state;
|
|
176
|
+
}
|
|
177
|
+
const newViewStart = adjustView(newCursorPosition, state.viewStart);
|
|
178
|
+
return { ...state, cursorPosition: newCursorPosition, viewStart: newViewStart };
|
|
179
|
+
}
|
|
157
180
|
default:
|
|
158
181
|
return state;
|
|
159
182
|
}
|
|
@@ -163,30 +186,76 @@ var useCustomInput = ({ onSubmit, viewWidth, isReadOnly, onInterrupt }) => {
|
|
|
163
186
|
(s, a) => inputReducer(s, a, viewWidth),
|
|
164
187
|
{ text: "", cursorPosition: 0, viewStart: 0 }
|
|
165
188
|
);
|
|
189
|
+
const inputBuffer = useRef("");
|
|
190
|
+
const flushScheduled = useRef(false);
|
|
191
|
+
const flushInputBuffer = useCallback(() => {
|
|
192
|
+
if (inputBuffer.current.length > 0) {
|
|
193
|
+
const buffered = inputBuffer.current;
|
|
194
|
+
inputBuffer.current = "";
|
|
195
|
+
dispatch({ type: "INPUT", payload: buffered });
|
|
196
|
+
}
|
|
197
|
+
flushScheduled.current = false;
|
|
198
|
+
}, []);
|
|
199
|
+
useEffect(() => {
|
|
200
|
+
return () => {
|
|
201
|
+
if (flushScheduled.current) {
|
|
202
|
+
flushInputBuffer();
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
}, [flushInputBuffer]);
|
|
166
206
|
useInput(
|
|
167
207
|
(input, key) => {
|
|
208
|
+
if (inputBuffer.current.length > 0 && (key.ctrl || key.meta || key.escape || key.return || key.backspace || key.delete || key.leftArrow || key.rightArrow || key.upArrow || key.downArrow || key.tab)) {
|
|
209
|
+
flushInputBuffer();
|
|
210
|
+
}
|
|
168
211
|
if (key.escape) {
|
|
169
212
|
onInterrupt();
|
|
170
213
|
return;
|
|
171
214
|
}
|
|
172
215
|
if (isReadOnly) {
|
|
173
|
-
if (key.return) {
|
|
216
|
+
if (key.ctrl && key.return) {
|
|
174
217
|
if (state.text.trim().length > 0) {
|
|
175
218
|
onSubmit(state.text);
|
|
176
219
|
dispatch({ type: "SUBMIT" });
|
|
177
220
|
}
|
|
178
221
|
return;
|
|
179
222
|
}
|
|
180
|
-
if (key.
|
|
223
|
+
if (key.return) {
|
|
224
|
+
dispatch({ type: "NEWLINE" });
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
if (key.backspace) return dispatch({ type: "BACKSPACE" });
|
|
228
|
+
if (key.delete) return dispatch({ type: "DELETE" });
|
|
181
229
|
if (key.leftArrow) return dispatch({ type: "MOVE_CURSOR", direction: "left" });
|
|
182
230
|
if (key.rightArrow) return dispatch({ type: "MOVE_CURSOR", direction: "right" });
|
|
231
|
+
if (key.upArrow) return dispatch({ type: "MOVE_CURSOR", direction: "up" });
|
|
232
|
+
if (key.downArrow) return dispatch({ type: "MOVE_CURSOR", direction: "down" });
|
|
183
233
|
if (key.ctrl || key.meta || key.tab) return;
|
|
184
|
-
|
|
234
|
+
inputBuffer.current += input;
|
|
235
|
+
if (!flushScheduled.current) {
|
|
236
|
+
flushScheduled.current = true;
|
|
237
|
+
queueMicrotask(flushInputBuffer);
|
|
238
|
+
}
|
|
239
|
+
return;
|
|
185
240
|
}
|
|
186
|
-
if (key.return) {
|
|
187
|
-
if (globalThis.__BLUMA_AT_OPEN__)
|
|
241
|
+
if (key.ctrl && key.return) {
|
|
242
|
+
if (globalThis.__BLUMA_AT_OPEN__) return;
|
|
243
|
+
if (globalThis.__BLUMA_SUPPRESS_SUBMIT__) {
|
|
244
|
+
globalThis.__BLUMA_SUPPRESS_SUBMIT__ = false;
|
|
188
245
|
return;
|
|
189
246
|
}
|
|
247
|
+
if (state.text.trim().length > 0) {
|
|
248
|
+
onSubmit(state.text);
|
|
249
|
+
dispatch({ type: "SUBMIT" });
|
|
250
|
+
}
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
if (key.shift && key.return) {
|
|
254
|
+
dispatch({ type: "NEWLINE" });
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
if (key.return) {
|
|
258
|
+
if (globalThis.__BLUMA_AT_OPEN__) return;
|
|
190
259
|
if (globalThis.__BLUMA_SUPPRESS_SUBMIT__) {
|
|
191
260
|
globalThis.__BLUMA_SUPPRESS_SUBMIT__ = false;
|
|
192
261
|
return;
|
|
@@ -197,32 +266,52 @@ var useCustomInput = ({ onSubmit, viewWidth, isReadOnly, onInterrupt }) => {
|
|
|
197
266
|
}
|
|
198
267
|
return;
|
|
199
268
|
}
|
|
200
|
-
if (key.backspace
|
|
269
|
+
if (key.backspace) return dispatch({ type: "BACKSPACE" });
|
|
270
|
+
if (key.delete) return dispatch({ type: "DELETE" });
|
|
201
271
|
if (key.leftArrow) return dispatch({ type: "MOVE_CURSOR", direction: "left" });
|
|
202
272
|
if (key.rightArrow) return dispatch({ type: "MOVE_CURSOR", direction: "right" });
|
|
273
|
+
if (key.upArrow) return dispatch({ type: "MOVE_CURSOR", direction: "up" });
|
|
274
|
+
if (key.downArrow) return dispatch({ type: "MOVE_CURSOR", direction: "down" });
|
|
275
|
+
if (key.ctrl && input === "a") {
|
|
276
|
+
return dispatch({ type: "MOVE_LINE_START" });
|
|
277
|
+
}
|
|
278
|
+
if (key.ctrl && input === "e") {
|
|
279
|
+
return dispatch({ type: "MOVE_LINE_END" });
|
|
280
|
+
}
|
|
203
281
|
if (key.ctrl || key.meta || key.tab) return;
|
|
204
|
-
|
|
282
|
+
inputBuffer.current += input;
|
|
283
|
+
if (!flushScheduled.current) {
|
|
284
|
+
flushScheduled.current = true;
|
|
285
|
+
queueMicrotask(flushInputBuffer);
|
|
286
|
+
}
|
|
205
287
|
},
|
|
206
|
-
// useInput está SEMPRE ativo para capturar todas as teclas
|
|
207
288
|
{ isActive: true }
|
|
208
289
|
);
|
|
209
290
|
return {
|
|
210
291
|
text: state.text,
|
|
211
292
|
cursorPosition: state.cursorPosition,
|
|
212
293
|
viewStart: state.viewStart,
|
|
213
|
-
setText: (t, pos) => {
|
|
294
|
+
setText: useCallback((t, pos) => {
|
|
295
|
+
if (inputBuffer.current.length > 0) {
|
|
296
|
+
flushInputBuffer();
|
|
297
|
+
}
|
|
214
298
|
if (typeof pos === "number") {
|
|
215
299
|
dispatch({ type: "SET", payload: { text: t, moveCursorToEnd: false, cursorPosition: pos } });
|
|
216
300
|
} else {
|
|
217
301
|
dispatch({ type: "SET", payload: { text: t, moveCursorToEnd: true } });
|
|
218
302
|
}
|
|
219
|
-
},
|
|
220
|
-
setCursor: (pos) =>
|
|
303
|
+
}, [flushInputBuffer]),
|
|
304
|
+
setCursor: useCallback((pos) => {
|
|
305
|
+
if (inputBuffer.current.length > 0) {
|
|
306
|
+
flushInputBuffer();
|
|
307
|
+
}
|
|
308
|
+
dispatch({ type: "SET_CURSOR", payload: pos });
|
|
309
|
+
}, [flushInputBuffer])
|
|
221
310
|
};
|
|
222
311
|
};
|
|
223
312
|
|
|
224
313
|
// src/app/ui/components/InputPrompt.tsx
|
|
225
|
-
import { useEffect as
|
|
314
|
+
import { useEffect as useEffect3, useMemo, useState as useState2, memo } from "react";
|
|
226
315
|
import { EventEmitter } from "events";
|
|
227
316
|
|
|
228
317
|
// src/app/ui/utils/slashRegistry.ts
|
|
@@ -272,7 +361,7 @@ var filterSlashCommands = (query) => {
|
|
|
272
361
|
};
|
|
273
362
|
|
|
274
363
|
// src/app/ui/hooks/useAtCompletion.ts
|
|
275
|
-
import { useEffect, useRef, useState } from "react";
|
|
364
|
+
import { useEffect as useEffect2, useRef as useRef2, useState } from "react";
|
|
276
365
|
import fs from "fs";
|
|
277
366
|
import path from "path";
|
|
278
367
|
var MAX_RESULTS = 50;
|
|
@@ -349,7 +438,7 @@ function useAtCompletion({
|
|
|
349
438
|
const [open, setOpen] = useState(false);
|
|
350
439
|
const [selected, setSelected] = useState(0);
|
|
351
440
|
const [suggestions, setSuggestions] = useState([]);
|
|
352
|
-
const lastQuery =
|
|
441
|
+
const lastQuery = useRef2("");
|
|
353
442
|
function scanForAt(text2, pos) {
|
|
354
443
|
const before = text2.slice(0, pos);
|
|
355
444
|
const m = before.match(/@([\w\/.\-_]*)$/);
|
|
@@ -371,7 +460,7 @@ function useAtCompletion({
|
|
|
371
460
|
setSuggestions([]);
|
|
372
461
|
}
|
|
373
462
|
}
|
|
374
|
-
|
|
463
|
+
useEffect2(() => {
|
|
375
464
|
update(text, cursorPosition);
|
|
376
465
|
}, [text, cursorPosition, cwd]);
|
|
377
466
|
function insertAtSelection() {
|
|
@@ -423,36 +512,133 @@ function useAtCompletion({
|
|
|
423
512
|
}
|
|
424
513
|
|
|
425
514
|
// src/app/ui/components/InputPrompt.tsx
|
|
426
|
-
import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
515
|
+
import { Fragment as Fragment2, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
427
516
|
var uiEventBus = global.__bluma_ui_eventbus__ || new EventEmitter();
|
|
428
517
|
global.__bluma_ui_eventbus__ = uiEventBus;
|
|
429
|
-
var
|
|
518
|
+
var TextLine = memo(({
|
|
519
|
+
line,
|
|
520
|
+
lineIndex,
|
|
521
|
+
cursorLine,
|
|
522
|
+
cursorCol,
|
|
523
|
+
showCursor
|
|
524
|
+
}) => {
|
|
525
|
+
const isCursorLine = lineIndex === cursorLine;
|
|
526
|
+
if (!isCursorLine || !showCursor) {
|
|
527
|
+
return /* @__PURE__ */ jsx2(Text2, { children: line });
|
|
528
|
+
}
|
|
529
|
+
const before = line.slice(0, cursorCol);
|
|
530
|
+
const char = line[cursorCol] || " ";
|
|
531
|
+
const after = line.slice(cursorCol + 1);
|
|
532
|
+
return /* @__PURE__ */ jsxs2(Text2, { children: [
|
|
533
|
+
before,
|
|
534
|
+
/* @__PURE__ */ jsx2(Text2, { inverse: true, color: "magenta", children: char }),
|
|
535
|
+
after
|
|
536
|
+
] });
|
|
537
|
+
}, (prev, next) => {
|
|
538
|
+
if (prev.line !== next.line) return false;
|
|
539
|
+
if (prev.showCursor !== next.showCursor) return false;
|
|
540
|
+
const prevIsCursorLine = prev.lineIndex === prev.cursorLine;
|
|
541
|
+
const nextIsCursorLine = next.lineIndex === next.cursorLine;
|
|
542
|
+
if (prevIsCursorLine !== nextIsCursorLine) return false;
|
|
543
|
+
if (nextIsCursorLine && prev.cursorCol !== next.cursorCol) return false;
|
|
544
|
+
return true;
|
|
545
|
+
});
|
|
546
|
+
TextLine.displayName = "TextLine";
|
|
547
|
+
var PathSuggestions = memo(({
|
|
548
|
+
suggestions,
|
|
549
|
+
selected
|
|
550
|
+
}) => {
|
|
551
|
+
const VISIBLE = 7;
|
|
552
|
+
const total = suggestions.length;
|
|
553
|
+
const sel = Math.max(0, Math.min(selected, total - 1));
|
|
554
|
+
let start = Math.max(0, sel - Math.floor(VISIBLE / 2));
|
|
555
|
+
if (start + VISIBLE > total) start = Math.max(0, total - VISIBLE);
|
|
556
|
+
const windowItems = suggestions.slice(start, start + VISIBLE);
|
|
557
|
+
return /* @__PURE__ */ jsx2(Box2, { flexDirection: "column", marginTop: 1, height: Math.min(VISIBLE, total), children: windowItems.map((s, idx) => {
|
|
558
|
+
const realIdx = start + idx;
|
|
559
|
+
const isSelected = realIdx === selected;
|
|
560
|
+
return /* @__PURE__ */ jsxs2(Box2, { paddingLeft: 1, paddingY: 0, children: [
|
|
561
|
+
/* @__PURE__ */ jsx2(Text2, { color: isSelected ? "magenta" : "gray", children: isSelected ? "\u276F " : " " }),
|
|
562
|
+
/* @__PURE__ */ jsx2(Text2, { color: isSelected ? "magenta" : "white", bold: isSelected, dimColor: !isSelected, children: s.label })
|
|
563
|
+
] }, s.fullPath);
|
|
564
|
+
}) });
|
|
565
|
+
});
|
|
566
|
+
PathSuggestions.displayName = "PathSuggestions";
|
|
567
|
+
var SlashSuggestions = memo(({
|
|
568
|
+
suggestions,
|
|
569
|
+
selectedIndex
|
|
570
|
+
}) => /* @__PURE__ */ jsx2(Box2, { flexDirection: "column", marginTop: 1, children: suggestions.map((s, idx) => {
|
|
571
|
+
const isSelected = idx === selectedIndex;
|
|
572
|
+
return /* @__PURE__ */ jsxs2(Box2, { paddingLeft: 1, paddingY: 0, children: [
|
|
573
|
+
/* @__PURE__ */ jsx2(Text2, { color: isSelected ? "magenta" : "gray", children: isSelected ? "\u276F " : " " }),
|
|
574
|
+
/* @__PURE__ */ jsxs2(Text2, { color: isSelected ? "magenta" : "white", bold: isSelected, dimColor: !isSelected, children: [
|
|
575
|
+
s.name,
|
|
576
|
+
" ",
|
|
577
|
+
/* @__PURE__ */ jsxs2(Text2, { color: "gray", children: [
|
|
578
|
+
"- ",
|
|
579
|
+
s.description
|
|
580
|
+
] })
|
|
581
|
+
] })
|
|
582
|
+
] }, s.name);
|
|
583
|
+
}) }));
|
|
584
|
+
SlashSuggestions.displayName = "SlashSuggestions";
|
|
585
|
+
var Footer = memo(({ isReadOnly }) => /* @__PURE__ */ jsx2(Box2, { paddingX: 1, justifyContent: "center", children: /* @__PURE__ */ jsx2(Text2, { color: "gray", dimColor: true, children: "ctrl+c to exit | Enter to submit | Shift+Enter for new line | /help commands | esc interrupt" }) }));
|
|
586
|
+
Footer.displayName = "Footer";
|
|
587
|
+
var TextLinesRenderer = memo(({
|
|
588
|
+
lines,
|
|
589
|
+
cursorLine,
|
|
590
|
+
cursorCol,
|
|
591
|
+
showCursor,
|
|
592
|
+
showPlaceholder,
|
|
593
|
+
placeholder
|
|
594
|
+
}) => {
|
|
595
|
+
return /* @__PURE__ */ jsx2(Fragment2, { children: lines.map((line, idx) => {
|
|
596
|
+
const isFirstLine = idx === 0;
|
|
597
|
+
return /* @__PURE__ */ jsxs2(Box2, { flexDirection: "row", paddingX: 1, children: [
|
|
598
|
+
isFirstLine && /* @__PURE__ */ jsxs2(Text2, { color: "white", children: [
|
|
599
|
+
">",
|
|
600
|
+
" "
|
|
601
|
+
] }),
|
|
602
|
+
!isFirstLine && /* @__PURE__ */ jsxs2(Text2, { color: "gray", children: [
|
|
603
|
+
"\u2502",
|
|
604
|
+
" "
|
|
605
|
+
] }),
|
|
606
|
+
showPlaceholder && isFirstLine && line.length === 0 ? /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: placeholder }) : /* @__PURE__ */ jsx2(
|
|
607
|
+
TextLine,
|
|
608
|
+
{
|
|
609
|
+
line,
|
|
610
|
+
lineIndex: idx,
|
|
611
|
+
cursorLine,
|
|
612
|
+
cursorCol,
|
|
613
|
+
showCursor
|
|
614
|
+
}
|
|
615
|
+
)
|
|
616
|
+
] }, idx);
|
|
617
|
+
}) });
|
|
618
|
+
});
|
|
619
|
+
TextLinesRenderer.displayName = "TextLinesRenderer";
|
|
620
|
+
var InputPrompt = memo(({
|
|
621
|
+
onSubmit,
|
|
622
|
+
isReadOnly,
|
|
623
|
+
onInterrupt,
|
|
624
|
+
disableWhileProcessing = false
|
|
625
|
+
}) => {
|
|
430
626
|
const { stdout } = useStdout();
|
|
431
|
-
const [viewWidth
|
|
627
|
+
const [viewWidth] = useState2(() => stdout.columns - 6);
|
|
432
628
|
const [slashOpen, setSlashOpen] = useState2(false);
|
|
433
629
|
const [slashIndex, setSlashIndex] = useState2(0);
|
|
434
|
-
useEffect2(() => {
|
|
435
|
-
const onResize = () => setViewWidth(stdout.columns - 6);
|
|
436
|
-
stdout.on("resize", onResize);
|
|
437
|
-
return () => {
|
|
438
|
-
stdout.off("resize", onResize);
|
|
439
|
-
};
|
|
440
|
-
}, [stdout]);
|
|
441
630
|
const permissiveOnSubmit = (value) => {
|
|
442
631
|
const trimmed = (value || "").trim();
|
|
443
632
|
if (isReadOnly) {
|
|
444
633
|
if (trimmed.length > 0) {
|
|
445
|
-
|
|
446
|
-
uiEventBus.emit("user_overlay", { kind: "message", payload, ts: Date.now() });
|
|
447
|
-
return;
|
|
634
|
+
uiEventBus.emit("user_overlay", { kind: "message", payload: trimmed, ts: Date.now() });
|
|
448
635
|
}
|
|
449
636
|
return;
|
|
450
637
|
}
|
|
451
638
|
onSubmit(value);
|
|
452
639
|
};
|
|
453
640
|
const effectiveReadOnly = isReadOnly;
|
|
454
|
-
const { text, cursorPosition,
|
|
455
|
-
// Sobrepõe a lógica padrão: nunca submete se autocomplete aberto
|
|
641
|
+
const { text, cursorPosition, setText } = useCustomInput({
|
|
456
642
|
onSubmit: (value) => {
|
|
457
643
|
if (disableWhileProcessing && isReadOnly) return;
|
|
458
644
|
if (pathAutocomplete.open) return;
|
|
@@ -462,13 +648,32 @@ var InputPrompt = ({ onSubmit, isReadOnly, onInterrupt, disableWhileProcessing =
|
|
|
462
648
|
isReadOnly: effectiveReadOnly,
|
|
463
649
|
onInterrupt
|
|
464
650
|
});
|
|
465
|
-
const
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
651
|
+
const linesData = useMemo(() => {
|
|
652
|
+
const lines = text.split("\n");
|
|
653
|
+
let remainingChars = cursorPosition;
|
|
654
|
+
let cursorLine = 0;
|
|
655
|
+
let cursorCol = 0;
|
|
656
|
+
for (let i = 0; i < lines.length; i++) {
|
|
657
|
+
const lineLength = lines[i].length;
|
|
658
|
+
if (remainingChars <= lineLength) {
|
|
659
|
+
cursorLine = i;
|
|
660
|
+
cursorCol = remainingChars;
|
|
661
|
+
break;
|
|
662
|
+
}
|
|
663
|
+
remainingChars -= lineLength + 1;
|
|
664
|
+
if (i === lines.length - 1) {
|
|
665
|
+
cursorLine = i;
|
|
666
|
+
cursorCol = lineLength;
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
return {
|
|
670
|
+
lines,
|
|
671
|
+
cursorLine,
|
|
672
|
+
cursorCol,
|
|
673
|
+
totalLines: lines.length
|
|
674
|
+
};
|
|
675
|
+
}, [text, cursorPosition]);
|
|
676
|
+
const displayData = linesData;
|
|
472
677
|
const placeholder = isReadOnly ? " Press Esc to cancel | Enter message while agent runs" : "";
|
|
473
678
|
const showPlaceholder = text.length === 0 && isReadOnly;
|
|
474
679
|
const slashQuery = useMemo(() => text.startsWith("/") ? text : "", [text]);
|
|
@@ -476,7 +681,7 @@ var InputPrompt = ({ onSubmit, isReadOnly, onInterrupt, disableWhileProcessing =
|
|
|
476
681
|
if (!slashQuery) return [];
|
|
477
682
|
return filterSlashCommands(slashQuery);
|
|
478
683
|
}, [slashQuery]);
|
|
479
|
-
|
|
684
|
+
useEffect3(() => {
|
|
480
685
|
if (isReadOnly) {
|
|
481
686
|
setSlashOpen(false);
|
|
482
687
|
return;
|
|
@@ -497,19 +702,18 @@ var InputPrompt = ({ onSubmit, isReadOnly, onInterrupt, disableWhileProcessing =
|
|
|
497
702
|
} else if (key.return) {
|
|
498
703
|
const choice = slashSuggestions[slashIndex];
|
|
499
704
|
if (choice) {
|
|
500
|
-
const cmd = choice.name;
|
|
501
705
|
setSlashOpen(false);
|
|
502
706
|
try {
|
|
503
|
-
setText(`${
|
|
707
|
+
setText(`${choice.name} `);
|
|
504
708
|
} catch (e) {
|
|
505
|
-
permissiveOnSubmit(`${
|
|
709
|
+
permissiveOnSubmit(`${choice.name} `);
|
|
506
710
|
}
|
|
507
711
|
}
|
|
508
712
|
} else if (key.escape) {
|
|
509
713
|
setSlashOpen(false);
|
|
510
714
|
}
|
|
511
715
|
}, { isActive: slashOpen });
|
|
512
|
-
|
|
716
|
+
useEffect3(() => {
|
|
513
717
|
if (globalThis.__BLUMA_FORCE_CURSOR_END__) {
|
|
514
718
|
setText(text, text.length);
|
|
515
719
|
delete globalThis.__BLUMA_FORCE_CURSOR_END__;
|
|
@@ -544,83 +748,72 @@ var InputPrompt = ({ onSubmit, isReadOnly, onInterrupt, disableWhileProcessing =
|
|
|
544
748
|
return;
|
|
545
749
|
}
|
|
546
750
|
}, { isActive: true });
|
|
547
|
-
function canSubmitGivenCursor() {
|
|
548
|
-
if (visibleCursorPosition < visibleText.length) {
|
|
549
|
-
return visibleText[visibleCursorPosition] === " ";
|
|
550
|
-
} else {
|
|
551
|
-
return false;
|
|
552
|
-
}
|
|
553
|
-
}
|
|
554
751
|
return /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", children: [
|
|
555
|
-
disableWhileProcessing ? (
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
] }, s.fullPath);
|
|
588
|
-
}) });
|
|
589
|
-
})(),
|
|
590
|
-
slashOpen && slashSuggestions.length > 0 && /* @__PURE__ */ jsx2(Box2, { flexDirection: "column", marginTop: 1, children: slashSuggestions.map((s, idx) => {
|
|
591
|
-
const isSelected = idx === slashIndex;
|
|
592
|
-
return /* @__PURE__ */ jsxs2(Box2, { paddingLeft: 1, paddingY: 0, children: [
|
|
593
|
-
/* @__PURE__ */ jsx2(Text2, { color: isSelected ? "magenta" : "gray", children: isSelected ? "\u276F " : " " }),
|
|
594
|
-
/* @__PURE__ */ jsxs2(Text2, { color: isSelected ? "magenta" : "white", bold: isSelected, dimColor: !isSelected, children: [
|
|
595
|
-
s.name,
|
|
596
|
-
" ",
|
|
597
|
-
/* @__PURE__ */ jsxs2(Text2, { color: "gray", children: [
|
|
598
|
-
"- ",
|
|
599
|
-
s.description
|
|
600
|
-
] })
|
|
601
|
-
] })
|
|
602
|
-
] }, s.name);
|
|
603
|
-
}) })
|
|
752
|
+
disableWhileProcessing ? /* @__PURE__ */ jsx2(Box2, { children: /* @__PURE__ */ jsxs2(Box2, { flexDirection: "row", paddingX: 1, flexWrap: "nowrap", children: [
|
|
753
|
+
/* @__PURE__ */ jsxs2(Text2, { color: "white", children: [
|
|
754
|
+
">",
|
|
755
|
+
" "
|
|
756
|
+
] }),
|
|
757
|
+
/* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "ctrl+c to exit" })
|
|
758
|
+
] }) }) : /* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
759
|
+
/* @__PURE__ */ jsx2(Box2, { flexDirection: "column", children: /* @__PURE__ */ jsx2(
|
|
760
|
+
TextLinesRenderer,
|
|
761
|
+
{
|
|
762
|
+
lines: displayData.lines,
|
|
763
|
+
cursorLine: displayData.cursorLine,
|
|
764
|
+
cursorCol: displayData.cursorCol,
|
|
765
|
+
showCursor: !isReadOnly,
|
|
766
|
+
showPlaceholder,
|
|
767
|
+
placeholder
|
|
768
|
+
}
|
|
769
|
+
) }),
|
|
770
|
+
pathAutocomplete.open && pathAutocomplete.suggestions.length > 0 && /* @__PURE__ */ jsx2(
|
|
771
|
+
PathSuggestions,
|
|
772
|
+
{
|
|
773
|
+
suggestions: pathAutocomplete.suggestions,
|
|
774
|
+
selected: pathAutocomplete.selected
|
|
775
|
+
}
|
|
776
|
+
),
|
|
777
|
+
slashOpen && slashSuggestions.length > 0 && /* @__PURE__ */ jsx2(
|
|
778
|
+
SlashSuggestions,
|
|
779
|
+
{
|
|
780
|
+
suggestions: slashSuggestions,
|
|
781
|
+
selectedIndex: slashIndex
|
|
782
|
+
}
|
|
783
|
+
)
|
|
604
784
|
] }),
|
|
605
|
-
/* @__PURE__ */ jsx2(
|
|
606
|
-
"ctrl+c to exit | /help to explore commands | esc to interrupt | ",
|
|
607
|
-
isReadOnly ? "Read-only mode (message passthrough)" : "Editable mode"
|
|
608
|
-
] }) })
|
|
785
|
+
/* @__PURE__ */ jsx2(Footer, { isReadOnly })
|
|
609
786
|
] });
|
|
610
|
-
};
|
|
787
|
+
});
|
|
788
|
+
InputPrompt.displayName = "InputPrompt";
|
|
611
789
|
|
|
612
790
|
// src/app/ui/ConfirmationPrompt.tsx
|
|
613
791
|
import { Box as Box6, Text as Text6 } from "ink";
|
|
614
792
|
|
|
615
793
|
// src/app/ui/InteractiveMenu.tsx
|
|
616
|
-
import { useState as useState3, memo } from "react";
|
|
794
|
+
import { useState as useState3, memo as memo2 } from "react";
|
|
617
795
|
import { Box as Box3, Text as Text3, useInput as useInput3 } from "ink";
|
|
618
796
|
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
619
797
|
var InteractiveMenuComponent = ({ onDecision }) => {
|
|
620
798
|
const options = [
|
|
621
|
-
{
|
|
622
|
-
|
|
623
|
-
|
|
799
|
+
{
|
|
800
|
+
key: "y",
|
|
801
|
+
label: "Accept",
|
|
802
|
+
value: "accept",
|
|
803
|
+
color: "green"
|
|
804
|
+
},
|
|
805
|
+
{
|
|
806
|
+
key: "n",
|
|
807
|
+
label: "Decline",
|
|
808
|
+
value: "decline",
|
|
809
|
+
color: "red"
|
|
810
|
+
},
|
|
811
|
+
{
|
|
812
|
+
key: "a",
|
|
813
|
+
label: "Always Accept",
|
|
814
|
+
value: "accept_always",
|
|
815
|
+
color: "yellow"
|
|
816
|
+
}
|
|
624
817
|
];
|
|
625
818
|
const [selectedOption, setSelectedOption] = useState3(0);
|
|
626
819
|
useInput3((input, key) => {
|
|
@@ -636,30 +829,36 @@ var InteractiveMenuComponent = ({ onDecision }) => {
|
|
|
636
829
|
if (key.return) {
|
|
637
830
|
onDecision(options[selectedOption].value);
|
|
638
831
|
}
|
|
832
|
+
const option = options.find((opt) => opt.key === input.toLowerCase());
|
|
833
|
+
if (option) {
|
|
834
|
+
onDecision(option.value);
|
|
835
|
+
}
|
|
639
836
|
});
|
|
640
|
-
return /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", children: [
|
|
641
|
-
/* @__PURE__ */ jsx3(Box3, { children: /* @__PURE__ */ jsx3(Text3, { bold: true, children: "
|
|
642
|
-
/* @__PURE__ */ jsx3(Box3, { flexDirection: "column", children: options.map((option, index) => {
|
|
837
|
+
return /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", paddingX: 1, children: [
|
|
838
|
+
/* @__PURE__ */ jsx3(Box3, { marginBottom: 1, children: /* @__PURE__ */ jsx3(Text3, { bold: true, children: "Authorize this action?" }) }),
|
|
839
|
+
/* @__PURE__ */ jsx3(Box3, { flexDirection: "column", paddingLeft: 1, children: options.map((option, index) => {
|
|
643
840
|
const isSelected = selectedOption === index;
|
|
644
|
-
return (
|
|
645
|
-
|
|
646
|
-
/* @__PURE__ */ jsxs3(
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
841
|
+
return /* @__PURE__ */ jsxs3(Box3, { marginBottom: 0, children: [
|
|
842
|
+
/* @__PURE__ */ jsx3(Text3, { color: isSelected ? "magenta" : "gray", children: isSelected ? "\u25B8 " : " " }),
|
|
843
|
+
/* @__PURE__ */ jsxs3(
|
|
844
|
+
Text3,
|
|
845
|
+
{
|
|
846
|
+
color: isSelected ? option.color : "gray",
|
|
847
|
+
bold: isSelected,
|
|
848
|
+
children: [
|
|
849
|
+
"[",
|
|
850
|
+
option.key,
|
|
851
|
+
"] ",
|
|
852
|
+
option.label
|
|
853
|
+
]
|
|
854
|
+
}
|
|
855
|
+
)
|
|
856
|
+
] }, option.value);
|
|
857
|
+
}) }),
|
|
858
|
+
/* @__PURE__ */ jsx3(Box3, { marginTop: 1, paddingLeft: 1, children: /* @__PURE__ */ jsx3(Text3, { dimColor: true, children: "\u2191\u2193 to select \u2022 Enter to confirm \u2022 Esc to cancel" }) })
|
|
660
859
|
] });
|
|
661
860
|
};
|
|
662
|
-
var InteractiveMenu =
|
|
861
|
+
var InteractiveMenu = memo2(InteractiveMenuComponent);
|
|
663
862
|
|
|
664
863
|
// src/app/ui/components/promptRenderers.tsx
|
|
665
864
|
import { Box as Box5, Text as Text5 } from "ink";
|
|
@@ -669,32 +868,39 @@ import path2 from "path";
|
|
|
669
868
|
import { Box as Box4, Text as Text4 } from "ink";
|
|
670
869
|
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
671
870
|
var SimpleDiff = ({ text, maxHeight }) => {
|
|
672
|
-
const allLines = (text || "").split("\n");
|
|
673
|
-
if (allLines.length > 0 && allLines[allLines.length - 1] === "") {
|
|
674
|
-
allLines.pop();
|
|
675
|
-
}
|
|
871
|
+
const allLines = (text || "").split("\n").filter((line) => line !== "");
|
|
676
872
|
const isTruncated = maxHeight > 0 && allLines.length > maxHeight;
|
|
677
873
|
const linesToRender = isTruncated ? allLines.slice(-maxHeight) : allLines;
|
|
678
874
|
const hiddenCount = allLines.length - linesToRender.length;
|
|
679
|
-
return /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", children: [
|
|
680
|
-
isTruncated && /* @__PURE__ */ jsx4(Box4, {
|
|
681
|
-
"
|
|
875
|
+
return /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", paddingX: 2, children: [
|
|
876
|
+
isTruncated && /* @__PURE__ */ jsx4(Box4, { marginBottom: 0, children: /* @__PURE__ */ jsxs4(Text4, { dimColor: true, children: [
|
|
877
|
+
"\u22EF ",
|
|
682
878
|
hiddenCount,
|
|
683
|
-
" lines hidden
|
|
879
|
+
" lines hidden"
|
|
684
880
|
] }) }),
|
|
685
881
|
linesToRender.map((line, index) => {
|
|
686
882
|
if (line.startsWith("---") || line.startsWith("+++")) {
|
|
687
883
|
return null;
|
|
688
884
|
}
|
|
689
885
|
let color = "white";
|
|
886
|
+
let prefix = "";
|
|
690
887
|
if (line.startsWith("+")) {
|
|
691
888
|
color = "green";
|
|
889
|
+
prefix = "+ ";
|
|
692
890
|
} else if (line.startsWith("-")) {
|
|
693
891
|
color = "red";
|
|
892
|
+
prefix = "- ";
|
|
694
893
|
} else if (line.startsWith("@@")) {
|
|
695
|
-
color = "
|
|
894
|
+
color = "cyan";
|
|
895
|
+
prefix = "";
|
|
896
|
+
} else {
|
|
897
|
+
color = "gray";
|
|
898
|
+
prefix = " ";
|
|
696
899
|
}
|
|
697
|
-
return /* @__PURE__ */ jsx4(
|
|
900
|
+
return /* @__PURE__ */ jsx4(Box4, { children: /* @__PURE__ */ jsxs4(Text4, { color, children: [
|
|
901
|
+
prefix,
|
|
902
|
+
line.replace(/^[+\-]/, "")
|
|
903
|
+
] }) }, index);
|
|
698
904
|
})
|
|
699
905
|
] });
|
|
700
906
|
};
|
|
@@ -704,19 +910,20 @@ import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
|
704
910
|
var getBasePath = (filePath) => {
|
|
705
911
|
return path2.basename(filePath);
|
|
706
912
|
};
|
|
707
|
-
var renderShellCommand = ({
|
|
708
|
-
toolCall
|
|
709
|
-
}) => {
|
|
913
|
+
var renderShellCommand = ({ toolCall }) => {
|
|
710
914
|
let command = "";
|
|
711
915
|
try {
|
|
712
916
|
const args = typeof toolCall.function.arguments === "string" ? JSON.parse(toolCall.function.arguments) : toolCall.function.arguments;
|
|
713
917
|
command = args.command || "[command not found]";
|
|
714
918
|
} catch (e) {
|
|
715
|
-
command = "Error parsing command
|
|
919
|
+
command = "Error parsing command";
|
|
716
920
|
}
|
|
717
|
-
return /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", marginBottom: 1, children: [
|
|
718
|
-
/* @__PURE__ */
|
|
719
|
-
|
|
921
|
+
return /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", paddingX: 1, marginBottom: 1, children: [
|
|
922
|
+
/* @__PURE__ */ jsxs5(Box5, { children: [
|
|
923
|
+
/* @__PURE__ */ jsx5(Text5, { color: "blue", children: "\u25B8" }),
|
|
924
|
+
/* @__PURE__ */ jsx5(Text5, { dimColor: true, children: " shell" })
|
|
925
|
+
] }),
|
|
926
|
+
/* @__PURE__ */ jsx5(Box5, { paddingLeft: 2, children: /* @__PURE__ */ jsx5(Text5, { color: "cyan", children: command }) })
|
|
720
927
|
] });
|
|
721
928
|
};
|
|
722
929
|
var renderLsTool = ({ toolCall }) => {
|
|
@@ -727,27 +934,28 @@ var renderLsTool = ({ toolCall }) => {
|
|
|
727
934
|
} catch (e) {
|
|
728
935
|
directoryPath = "Error parsing arguments";
|
|
729
936
|
}
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
937
|
+
return /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", paddingX: 1, marginBottom: 1, children: [
|
|
938
|
+
/* @__PURE__ */ jsxs5(Box5, { children: [
|
|
939
|
+
/* @__PURE__ */ jsx5(Text5, { color: "blue", children: "\u25B8" }),
|
|
940
|
+
/* @__PURE__ */ jsx5(Text5, { dimColor: true, children: " ls" })
|
|
941
|
+
] }),
|
|
942
|
+
/* @__PURE__ */ jsx5(Box5, { paddingLeft: 2, children: /* @__PURE__ */ jsx5(Text5, { color: "cyan", children: directoryPath }) })
|
|
734
943
|
] });
|
|
735
944
|
};
|
|
736
945
|
var renderCountFilesLinesTool = ({ toolCall }) => {
|
|
737
|
-
let
|
|
946
|
+
let filepath = "[path not specified]";
|
|
738
947
|
try {
|
|
739
948
|
const args = typeof toolCall.function.arguments === "string" ? JSON.parse(toolCall.function.arguments) : toolCall.function.arguments;
|
|
740
|
-
|
|
949
|
+
filepath = args.filepath || "[path not specified]";
|
|
741
950
|
} catch (e) {
|
|
742
|
-
|
|
951
|
+
filepath = "Error parsing arguments";
|
|
743
952
|
}
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
] }) }) })
|
|
953
|
+
return /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", paddingX: 1, marginBottom: 1, children: [
|
|
954
|
+
/* @__PURE__ */ jsxs5(Box5, { children: [
|
|
955
|
+
/* @__PURE__ */ jsx5(Text5, { color: "blue", children: "\u25B8" }),
|
|
956
|
+
/* @__PURE__ */ jsx5(Text5, { dimColor: true, children: " count lines" })
|
|
957
|
+
] }),
|
|
958
|
+
/* @__PURE__ */ jsx5(Box5, { paddingLeft: 2, children: /* @__PURE__ */ jsx5(Text5, { color: "cyan", children: filepath }) })
|
|
751
959
|
] });
|
|
752
960
|
};
|
|
753
961
|
var renderReadFileLines = ({ toolCall }) => {
|
|
@@ -762,18 +970,19 @@ var renderReadFileLines = ({ toolCall }) => {
|
|
|
762
970
|
} catch (e) {
|
|
763
971
|
filepath = "Error parsing arguments";
|
|
764
972
|
}
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
973
|
+
return /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", paddingX: 1, marginBottom: 1, children: [
|
|
974
|
+
/* @__PURE__ */ jsxs5(Box5, { children: [
|
|
975
|
+
/* @__PURE__ */ jsx5(Text5, { color: "blue", children: "\u25B8" }),
|
|
976
|
+
/* @__PURE__ */ jsx5(Text5, { dimColor: true, children: " read" })
|
|
977
|
+
] }),
|
|
978
|
+
/* @__PURE__ */ jsxs5(Box5, { paddingLeft: 2, flexDirection: "column", children: [
|
|
979
|
+
/* @__PURE__ */ jsx5(Text5, { color: "cyan", children: filepath }),
|
|
980
|
+
/* @__PURE__ */ jsxs5(Box5, { paddingLeft: 2, children: [
|
|
772
981
|
/* @__PURE__ */ jsx5(Text5, { dimColor: true, children: "lines " }),
|
|
773
982
|
/* @__PURE__ */ jsx5(Text5, { color: "magenta", children: startLine }),
|
|
774
983
|
/* @__PURE__ */ jsx5(Text5, { dimColor: true, children: " to " }),
|
|
775
984
|
/* @__PURE__ */ jsx5(Text5, { color: "magenta", children: endLine })
|
|
776
|
-
] })
|
|
985
|
+
] })
|
|
777
986
|
] })
|
|
778
987
|
] });
|
|
779
988
|
};
|
|
@@ -787,15 +996,13 @@ var renderEditTool = ({ toolCall, preview }) => {
|
|
|
787
996
|
filepath = "Error parsing arguments";
|
|
788
997
|
}
|
|
789
998
|
const finalFileName = getBasePath(filepath);
|
|
790
|
-
return /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", marginBottom: 1, children: [
|
|
791
|
-
/* @__PURE__ */
|
|
792
|
-
"
|
|
793
|
-
/* @__PURE__ */ jsx5(Text5, {
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
/* @__PURE__ */ jsx5(Box5, { marginTop: 1, children: /* @__PURE__ */ jsx5(SimpleDiff, { text: preview, maxHeight: diffMaxHeight }) })
|
|
798
|
-
) : /* @__PURE__ */ jsx5(Text5, { color: "yellow", children: "Generating preview..." })
|
|
999
|
+
return /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", paddingX: 1, marginBottom: 1, children: [
|
|
1000
|
+
/* @__PURE__ */ jsxs5(Box5, { children: [
|
|
1001
|
+
/* @__PURE__ */ jsx5(Text5, { color: "blue", children: "\u25B8" }),
|
|
1002
|
+
/* @__PURE__ */ jsx5(Text5, { dimColor: true, children: " edit " }),
|
|
1003
|
+
/* @__PURE__ */ jsx5(Text5, { color: "cyan", children: finalFileName })
|
|
1004
|
+
] }),
|
|
1005
|
+
preview ? /* @__PURE__ */ jsx5(Box5, { marginTop: 1, children: /* @__PURE__ */ jsx5(SimpleDiff, { text: preview, maxHeight: diffMaxHeight }) }) : /* @__PURE__ */ jsx5(Box5, { paddingLeft: 2, children: /* @__PURE__ */ jsx5(Text5, { color: "yellow", children: "Generating preview..." }) })
|
|
799
1006
|
] });
|
|
800
1007
|
};
|
|
801
1008
|
var renderGeneric = ({ toolCall }) => {
|
|
@@ -819,16 +1026,21 @@ var renderGeneric = ({ toolCall }) => {
|
|
|
819
1026
|
const isTruncated = lines.length > MAX_LINES;
|
|
820
1027
|
const visibleLines = isTruncated ? lines.slice(0, MAX_LINES) : lines;
|
|
821
1028
|
const remainingCount = lines.length - MAX_LINES;
|
|
822
|
-
return /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", marginBottom: 1, children: [
|
|
823
|
-
/* @__PURE__ */
|
|
824
|
-
|
|
825
|
-
/* @__PURE__ */
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
1029
|
+
return /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", paddingX: 1, marginBottom: 1, children: [
|
|
1030
|
+
/* @__PURE__ */ jsxs5(Box5, { children: [
|
|
1031
|
+
/* @__PURE__ */ jsx5(Text5, { color: "blue", children: "\u25B8" }),
|
|
1032
|
+
/* @__PURE__ */ jsxs5(Text5, { dimColor: true, children: [
|
|
1033
|
+
" ",
|
|
1034
|
+
toolName
|
|
1035
|
+
] })
|
|
1036
|
+
] }),
|
|
1037
|
+
formattedArgsString && /* @__PURE__ */ jsxs5(Box5, { paddingLeft: 2, flexDirection: "column", children: [
|
|
1038
|
+
visibleLines.map((line, idx) => /* @__PURE__ */ jsx5(Text5, { color: "gray", children: line }, idx)),
|
|
1039
|
+
isTruncated && /* @__PURE__ */ jsxs5(Text5, { dimColor: true, children: [
|
|
1040
|
+
"\u22EF ",
|
|
829
1041
|
remainingCount,
|
|
830
|
-
" more lines
|
|
831
|
-
] })
|
|
1042
|
+
" more lines"
|
|
1043
|
+
] })
|
|
832
1044
|
] })
|
|
833
1045
|
] });
|
|
834
1046
|
};
|
|
@@ -2846,33 +3058,39 @@ var Agent = class {
|
|
|
2846
3058
|
};
|
|
2847
3059
|
|
|
2848
3060
|
// src/app/ui/WorkingTimer.tsx
|
|
2849
|
-
import { useState as useState4, useEffect as
|
|
3061
|
+
import { useState as useState4, useEffect as useEffect4 } from "react";
|
|
2850
3062
|
import { Box as Box7, Text as Text7 } from "ink";
|
|
2851
3063
|
import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
2852
3064
|
var WorkingTimer = () => {
|
|
2853
3065
|
const [seconds, setSeconds] = useState4(0);
|
|
2854
|
-
const [
|
|
2855
|
-
|
|
2856
|
-
const
|
|
3066
|
+
const [frame, setFrame] = useState4(0);
|
|
3067
|
+
useEffect4(() => {
|
|
3068
|
+
const timer = setInterval(() => {
|
|
2857
3069
|
setSeconds((prev) => prev + 1);
|
|
2858
3070
|
}, 1e3);
|
|
2859
|
-
return () => clearInterval(
|
|
3071
|
+
return () => clearInterval(timer);
|
|
2860
3072
|
}, []);
|
|
2861
|
-
|
|
2862
|
-
const
|
|
2863
|
-
|
|
2864
|
-
},
|
|
2865
|
-
return () => clearInterval(
|
|
3073
|
+
useEffect4(() => {
|
|
3074
|
+
const animator = setInterval(() => {
|
|
3075
|
+
setFrame((prev) => (prev + 1) % 10);
|
|
3076
|
+
}, 80);
|
|
3077
|
+
return () => clearInterval(animator);
|
|
2866
3078
|
}, []);
|
|
2867
|
-
const
|
|
2868
|
-
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
|
|
3079
|
+
const spinners = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
3080
|
+
const spinner = spinners[frame];
|
|
3081
|
+
return /* @__PURE__ */ jsxs7(Box7, { paddingX: 1, marginBottom: 0, children: [
|
|
3082
|
+
/* @__PURE__ */ jsx7(Text7, { color: "magenta", children: spinner }),
|
|
3083
|
+
/* @__PURE__ */ jsx7(Text7, { dimColor: true, children: " thinking" }),
|
|
3084
|
+
/* @__PURE__ */ jsxs7(Text7, { color: "gray", children: [
|
|
3085
|
+
" ",
|
|
3086
|
+
seconds,
|
|
3087
|
+
"s"
|
|
3088
|
+
] })
|
|
3089
|
+
] });
|
|
2872
3090
|
};
|
|
2873
3091
|
|
|
2874
3092
|
// src/app/ui/components/ToolCallDisplay.tsx
|
|
2875
|
-
import { memo as
|
|
3093
|
+
import { memo as memo3 } from "react";
|
|
2876
3094
|
import { Box as Box9 } from "ink";
|
|
2877
3095
|
|
|
2878
3096
|
// src/app/ui/components/toolCallRenderers.tsx
|
|
@@ -2888,19 +3106,14 @@ var formatArgumentsForDisplay = (args) => {
|
|
|
2888
3106
|
}
|
|
2889
3107
|
return JSON.stringify(args, null, 2);
|
|
2890
3108
|
};
|
|
2891
|
-
var renderShellCommand2 = ({
|
|
2892
|
-
args
|
|
2893
|
-
}) => {
|
|
3109
|
+
var renderShellCommand2 = ({ args }) => {
|
|
2894
3110
|
const command = args.command || "[command not found]";
|
|
2895
|
-
return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
|
|
2896
|
-
/* @__PURE__ */
|
|
2897
|
-
/* @__PURE__ */ jsx8(Text8, { color: "green", children: "\
|
|
2898
|
-
"
|
|
2899
|
-
] })
|
|
2900
|
-
/* @__PURE__ */ jsx8(Box8, {
|
|
2901
|
-
/* @__PURE__ */ jsx8(Text8, { color: "gray", children: "\u21B3 " }),
|
|
2902
|
-
/* @__PURE__ */ jsx8(Text8, { color: "magenta", children: command })
|
|
2903
|
-
] }) })
|
|
3111
|
+
return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", paddingX: 1, children: [
|
|
3112
|
+
/* @__PURE__ */ jsxs8(Box8, { children: [
|
|
3113
|
+
/* @__PURE__ */ jsx8(Text8, { color: "green", children: "\u2713" }),
|
|
3114
|
+
/* @__PURE__ */ jsx8(Text8, { dimColor: true, children: " shell" })
|
|
3115
|
+
] }),
|
|
3116
|
+
/* @__PURE__ */ jsx8(Box8, { paddingLeft: 2, children: /* @__PURE__ */ jsx8(Text8, { color: "gray", children: command }) })
|
|
2904
3117
|
] });
|
|
2905
3118
|
};
|
|
2906
3119
|
var renderLsTool2 = ({ args }) => {
|
|
@@ -2911,43 +3124,31 @@ var renderLsTool2 = ({ args }) => {
|
|
|
2911
3124
|
} catch (e) {
|
|
2912
3125
|
directoryPath = "Error parsing arguments";
|
|
2913
3126
|
}
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
/* @__PURE__ */ jsx8(Text8, {
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
/* @__PURE__ */ jsx8(Box8, { marginLeft: 2, paddingX: 1, children: /* @__PURE__ */ jsxs8(Text8, { children: [
|
|
2921
|
-
/* @__PURE__ */ jsx8(Text8, { color: "gray", children: "\u21B3 " }),
|
|
2922
|
-
/* @__PURE__ */ jsx8(Text8, { color: "magenta", children: finalDirectoryName })
|
|
2923
|
-
] }) })
|
|
3127
|
+
return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", paddingX: 1, children: [
|
|
3128
|
+
/* @__PURE__ */ jsxs8(Box8, { children: [
|
|
3129
|
+
/* @__PURE__ */ jsx8(Text8, { color: "green", children: "\u2713" }),
|
|
3130
|
+
/* @__PURE__ */ jsx8(Text8, { dimColor: true, children: " ls" })
|
|
3131
|
+
] }),
|
|
3132
|
+
/* @__PURE__ */ jsx8(Box8, { paddingLeft: 2, children: /* @__PURE__ */ jsx8(Text8, { color: "gray", children: directoryPath }) })
|
|
2924
3133
|
] });
|
|
2925
3134
|
};
|
|
2926
|
-
var renderCountFilesLines = ({
|
|
2927
|
-
|
|
2928
|
-
}) => {
|
|
2929
|
-
let directoryPath = "[path not found]";
|
|
3135
|
+
var renderCountFilesLines = ({ args }) => {
|
|
3136
|
+
let filepath = "[path not found]";
|
|
2930
3137
|
try {
|
|
2931
3138
|
const parsedArgs = typeof args === "string" ? JSON.parse(args) : args;
|
|
2932
|
-
|
|
3139
|
+
filepath = parsedArgs.filepath || "[path not specified]";
|
|
2933
3140
|
} catch (e) {
|
|
2934
|
-
|
|
3141
|
+
filepath = "Error parsing arguments";
|
|
2935
3142
|
}
|
|
2936
|
-
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
/* @__PURE__ */ jsx8(Text8, {
|
|
2940
|
-
|
|
2941
|
-
|
|
2942
|
-
/* @__PURE__ */ jsx8(Box8, { marginLeft: 2, paddingX: 1, children: /* @__PURE__ */ jsxs8(Text8, { children: [
|
|
2943
|
-
/* @__PURE__ */ jsx8(Text8, { color: "gray", children: "\u21B3 " }),
|
|
2944
|
-
/* @__PURE__ */ jsx8(Text8, { color: "magenta", children: finalDirectoryName })
|
|
2945
|
-
] }) })
|
|
3143
|
+
return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", paddingX: 1, children: [
|
|
3144
|
+
/* @__PURE__ */ jsxs8(Box8, { children: [
|
|
3145
|
+
/* @__PURE__ */ jsx8(Text8, { color: "green", children: "\u2713" }),
|
|
3146
|
+
/* @__PURE__ */ jsx8(Text8, { dimColor: true, children: " count lines" })
|
|
3147
|
+
] }),
|
|
3148
|
+
/* @__PURE__ */ jsx8(Box8, { paddingLeft: 2, children: /* @__PURE__ */ jsx8(Text8, { color: "gray", children: filepath }) })
|
|
2946
3149
|
] });
|
|
2947
3150
|
};
|
|
2948
|
-
var renderReadFileLines2 = ({
|
|
2949
|
-
args
|
|
2950
|
-
}) => {
|
|
3151
|
+
var renderReadFileLines2 = ({ args }) => {
|
|
2951
3152
|
let filepath = "[path not found]";
|
|
2952
3153
|
let startLine = 0;
|
|
2953
3154
|
let endLine = 0;
|
|
@@ -2959,33 +3160,23 @@ var renderReadFileLines2 = ({
|
|
|
2959
3160
|
} catch (e) {
|
|
2960
3161
|
filepath = "Error parsing arguments";
|
|
2961
3162
|
}
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
|
|
2966
|
-
|
|
2967
|
-
|
|
2968
|
-
|
|
2969
|
-
|
|
2970
|
-
|
|
2971
|
-
|
|
2972
|
-
|
|
2973
|
-
|
|
2974
|
-
|
|
2975
|
-
/* @__PURE__ */ jsx8(Box8, { marginLeft: 2, paddingX: 4, children: /* @__PURE__ */ jsxs8(Text8, { children: [
|
|
2976
|
-
/* @__PURE__ */ jsx8(Text8, { color: "gray", children: "\u21B3 " }),
|
|
2977
|
-
/* @__PURE__ */ jsx8(Text8, { dimColor: true, children: "lines " }),
|
|
2978
|
-
/* @__PURE__ */ jsx8(Text8, { color: "magenta", children: startLine }),
|
|
2979
|
-
/* @__PURE__ */ jsx8(Text8, { dimColor: true, children: " to " }),
|
|
2980
|
-
/* @__PURE__ */ jsx8(Text8, { color: "magenta", children: endLine })
|
|
2981
|
-
] }) })
|
|
2982
|
-
] })
|
|
3163
|
+
return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", paddingX: 1, children: [
|
|
3164
|
+
/* @__PURE__ */ jsxs8(Box8, { children: [
|
|
3165
|
+
/* @__PURE__ */ jsx8(Text8, { color: "green", children: "\u2713" }),
|
|
3166
|
+
/* @__PURE__ */ jsx8(Text8, { dimColor: true, children: " read" })
|
|
3167
|
+
] }),
|
|
3168
|
+
/* @__PURE__ */ jsxs8(Box8, { paddingLeft: 2, flexDirection: "column", children: [
|
|
3169
|
+
/* @__PURE__ */ jsx8(Text8, { color: "gray", children: filepath }),
|
|
3170
|
+
/* @__PURE__ */ jsx8(Box8, { paddingLeft: 2, children: /* @__PURE__ */ jsxs8(Text8, { dimColor: true, children: [
|
|
3171
|
+
"lines ",
|
|
3172
|
+
startLine,
|
|
3173
|
+
" to ",
|
|
3174
|
+
endLine
|
|
3175
|
+
] }) })
|
|
2983
3176
|
] })
|
|
2984
|
-
);
|
|
3177
|
+
] });
|
|
2985
3178
|
};
|
|
2986
|
-
var renderBlumaNotebook = ({
|
|
2987
|
-
args
|
|
2988
|
-
}) => {
|
|
3179
|
+
var renderBlumaNotebook = ({ args }) => {
|
|
2989
3180
|
try {
|
|
2990
3181
|
let dataToParse = args;
|
|
2991
3182
|
if (args && typeof args === "object") {
|
|
@@ -2994,33 +3185,17 @@ var renderBlumaNotebook = ({
|
|
|
2994
3185
|
}
|
|
2995
3186
|
const thinkingData = typeof dataToParse === "string" ? JSON.parse(dataToParse) : dataToParse;
|
|
2996
3187
|
if (!thinkingData || typeof thinkingData.thought !== "string") {
|
|
2997
|
-
throw new Error("Invalid
|
|
3188
|
+
throw new Error("Invalid thought data");
|
|
2998
3189
|
}
|
|
2999
|
-
return (
|
|
3000
|
-
|
|
3001
|
-
/* @__PURE__ */ jsx8(
|
|
3002
|
-
Box8,
|
|
3003
|
-
{
|
|
3004
|
-
flexDirection: "column",
|
|
3005
|
-
paddingX: 1,
|
|
3006
|
-
children: /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
|
|
3007
|
-
/* @__PURE__ */ jsx8(Text8, { color: "white", bold: true, children: "Reasoning:" }),
|
|
3008
|
-
/* @__PURE__ */ jsx8(Box8, { marginLeft: 2, children: /* @__PURE__ */ jsx8(Text8, { color: "gray", children: thinkingData.thought }) })
|
|
3009
|
-
] })
|
|
3010
|
-
}
|
|
3011
|
-
)
|
|
3012
|
-
);
|
|
3013
|
-
} catch (e) {
|
|
3014
|
-
return /* @__PURE__ */ jsxs8(Box8, { borderStyle: "round", borderColor: "magenta", paddingX: 1, children: [
|
|
3015
|
-
/* @__PURE__ */ jsx8(Text8, { color: "magenta", bold: true, children: "Thinking (Error)" }),
|
|
3016
|
-
/* @__PURE__ */ jsx8(Text8, { color: "gray", children: JSON.stringify(args, null, 2) })
|
|
3190
|
+
return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", paddingX: 1, marginBottom: 1, children: [
|
|
3191
|
+
/* @__PURE__ */ jsx8(Box8, { children: /* @__PURE__ */ jsx8(Text8, { bold: true, color: "cyan", children: "\u{1F4AD} Reasoning" }) }),
|
|
3192
|
+
/* @__PURE__ */ jsx8(Box8, { paddingLeft: 2, children: /* @__PURE__ */ jsx8(Text8, { color: "gray", children: thinkingData.thought }) })
|
|
3017
3193
|
] });
|
|
3194
|
+
} catch (e) {
|
|
3195
|
+
return /* @__PURE__ */ jsx8(Box8, { paddingX: 1, children: /* @__PURE__ */ jsx8(Text8, { color: "red", children: "Error parsing reasoning" }) });
|
|
3018
3196
|
}
|
|
3019
3197
|
};
|
|
3020
|
-
var renderEditToolCall = ({
|
|
3021
|
-
args,
|
|
3022
|
-
preview
|
|
3023
|
-
}) => {
|
|
3198
|
+
var renderEditToolCall = ({ args, preview }) => {
|
|
3024
3199
|
let filepath = "[path not specified]";
|
|
3025
3200
|
try {
|
|
3026
3201
|
const parsedArgs = typeof args === "string" ? JSON.parse(args) : args;
|
|
@@ -3028,16 +3203,12 @@ var renderEditToolCall = ({
|
|
|
3028
3203
|
} catch (e) {
|
|
3029
3204
|
filepath = "Error parsing arguments";
|
|
3030
3205
|
}
|
|
3031
|
-
const finalFileName = filepath;
|
|
3032
3206
|
return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", paddingX: 1, children: [
|
|
3033
|
-
/* @__PURE__ */
|
|
3034
|
-
/* @__PURE__ */ jsx8(Text8, { color: "green", children: "\
|
|
3035
|
-
"
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
/* @__PURE__ */ jsx8(Text8, { color: "gray", children: "\u21B3 " }),
|
|
3039
|
-
/* @__PURE__ */ jsx8(Text8, { color: "magenta", children: finalFileName })
|
|
3040
|
-
] }) }),
|
|
3207
|
+
/* @__PURE__ */ jsxs8(Box8, { children: [
|
|
3208
|
+
/* @__PURE__ */ jsx8(Text8, { color: "green", children: "\u2713" }),
|
|
3209
|
+
/* @__PURE__ */ jsx8(Text8, { dimColor: true, children: " edit " }),
|
|
3210
|
+
/* @__PURE__ */ jsx8(Text8, { color: "cyan", children: filepath })
|
|
3211
|
+
] }),
|
|
3041
3212
|
preview && /* @__PURE__ */ jsx8(Box8, { marginTop: 1, children: /* @__PURE__ */ jsx8(SimpleDiff, { text: preview, maxHeight: Infinity }) })
|
|
3042
3213
|
] });
|
|
3043
3214
|
};
|
|
@@ -3049,54 +3220,44 @@ var renderTodoTool = ({ args }) => {
|
|
|
3049
3220
|
switch (action) {
|
|
3050
3221
|
case "add":
|
|
3051
3222
|
const items = parsedArgs.items_to_add || [];
|
|
3052
|
-
|
|
3053
|
-
detailText = `Adding ${itemCount} item${itemCount !== 1 ? "s" : ""}`;
|
|
3223
|
+
detailText = `Added ${items.length} task${items.length !== 1 ? "s" : ""}`;
|
|
3054
3224
|
break;
|
|
3055
3225
|
case "complete":
|
|
3056
|
-
detailText = `
|
|
3226
|
+
detailText = `Completed task #${parsedArgs.index}`;
|
|
3057
3227
|
break;
|
|
3058
3228
|
case "remove":
|
|
3059
|
-
detailText = `
|
|
3229
|
+
detailText = `Removed task #${parsedArgs.index}`;
|
|
3060
3230
|
break;
|
|
3061
3231
|
case "list":
|
|
3062
|
-
detailText = `
|
|
3232
|
+
detailText = `Listed all tasks`;
|
|
3063
3233
|
break;
|
|
3064
3234
|
default:
|
|
3065
|
-
detailText = `
|
|
3235
|
+
detailText = `Action: ${action}`;
|
|
3066
3236
|
break;
|
|
3067
3237
|
}
|
|
3068
|
-
return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
|
|
3069
|
-
/* @__PURE__ */
|
|
3070
|
-
/* @__PURE__ */ jsx8(Text8, { color: "green", children: "\
|
|
3071
|
-
"
|
|
3072
|
-
] })
|
|
3073
|
-
/* @__PURE__ */ jsx8(Box8, {
|
|
3074
|
-
/* @__PURE__ */ jsx8(Text8, { color: "gray", children: "\u21B3 " }),
|
|
3075
|
-
/* @__PURE__ */ jsx8(Text8, { color: "magenta", children: detailText })
|
|
3076
|
-
] }) })
|
|
3238
|
+
return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", paddingX: 1, children: [
|
|
3239
|
+
/* @__PURE__ */ jsxs8(Box8, { children: [
|
|
3240
|
+
/* @__PURE__ */ jsx8(Text8, { color: "green", children: "\u2713" }),
|
|
3241
|
+
/* @__PURE__ */ jsx8(Text8, { dimColor: true, children: " todo" })
|
|
3242
|
+
] }),
|
|
3243
|
+
/* @__PURE__ */ jsx8(Box8, { paddingLeft: 2, children: /* @__PURE__ */ jsx8(Text8, { color: "gray", children: detailText }) })
|
|
3077
3244
|
] });
|
|
3078
3245
|
} catch (error) {
|
|
3079
|
-
return /* @__PURE__ */ jsx8(Box8, {
|
|
3246
|
+
return /* @__PURE__ */ jsx8(Box8, { paddingX: 1, children: /* @__PURE__ */ jsx8(Text8, { color: "red", children: "Error parsing todo" }) });
|
|
3080
3247
|
}
|
|
3081
3248
|
};
|
|
3082
|
-
var renderGenericToolCall = ({
|
|
3083
|
-
toolName,
|
|
3084
|
-
args
|
|
3085
|
-
}) => {
|
|
3249
|
+
var renderGenericToolCall = ({ toolName, args }) => {
|
|
3086
3250
|
const formattedArgs = formatArgumentsForDisplay(args);
|
|
3087
|
-
return (
|
|
3088
|
-
|
|
3089
|
-
|
|
3090
|
-
/* @__PURE__ */
|
|
3091
|
-
|
|
3251
|
+
return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", paddingX: 1, children: [
|
|
3252
|
+
/* @__PURE__ */ jsxs8(Box8, { children: [
|
|
3253
|
+
/* @__PURE__ */ jsx8(Text8, { color: "green", children: "\u2713" }),
|
|
3254
|
+
/* @__PURE__ */ jsxs8(Text8, { dimColor: true, children: [
|
|
3255
|
+
" ",
|
|
3092
3256
|
toolName
|
|
3093
|
-
] }) }),
|
|
3094
|
-
formattedArgs && formattedArgs !== "{}" && /* @__PURE__ */ jsxs8(Box8, { paddingX: 3, children: [
|
|
3095
|
-
/* @__PURE__ */ jsx8(Text8, { color: "gray", children: "\u21B3 " }),
|
|
3096
|
-
/* @__PURE__ */ jsx8(Box8, { flexDirection: "column", children: formattedArgs.split("\n").map((line, index) => /* @__PURE__ */ jsx8(Text8, { color: "gray", children: line }, index)) })
|
|
3097
3257
|
] })
|
|
3098
|
-
] })
|
|
3099
|
-
|
|
3258
|
+
] }),
|
|
3259
|
+
formattedArgs && formattedArgs !== "{}" && /* @__PURE__ */ jsx8(Box8, { paddingLeft: 2, flexDirection: "column", children: formattedArgs.split("\n").slice(0, 3).map((line, index) => /* @__PURE__ */ jsx8(Text8, { color: "gray", children: line }, index)) })
|
|
3260
|
+
] });
|
|
3100
3261
|
};
|
|
3101
3262
|
var ToolRenderDisplay = {
|
|
3102
3263
|
shell_command: renderShellCommand2,
|
|
@@ -3117,10 +3278,10 @@ var ToolCallDisplayComponent = ({ toolName, args, preview }) => {
|
|
|
3117
3278
|
const Renderer = ToolRenderDisplay[toolName] || renderGenericToolCall;
|
|
3118
3279
|
return /* @__PURE__ */ jsx9(Box9, { marginBottom: 1, children: /* @__PURE__ */ jsx9(Renderer, { toolName, args, preview }) });
|
|
3119
3280
|
};
|
|
3120
|
-
var ToolCallDisplay =
|
|
3281
|
+
var ToolCallDisplay = memo3(ToolCallDisplayComponent);
|
|
3121
3282
|
|
|
3122
3283
|
// src/app/ui/components/ToolResultDisplay.tsx
|
|
3123
|
-
import { memo as
|
|
3284
|
+
import { memo as memo4 } from "react";
|
|
3124
3285
|
import { Box as Box11 } from "ink";
|
|
3125
3286
|
|
|
3126
3287
|
// src/app/ui/components/MarkdownRenderer.tsx
|
|
@@ -3297,68 +3458,25 @@ var ToolResultDisplayComponent = ({ toolName, result }) => {
|
|
|
3297
3458
|
}
|
|
3298
3459
|
return null;
|
|
3299
3460
|
};
|
|
3300
|
-
var ToolResultDisplay =
|
|
3461
|
+
var ToolResultDisplay = memo4(ToolResultDisplayComponent);
|
|
3301
3462
|
|
|
3302
|
-
// src/app/ui/
|
|
3463
|
+
// src/app/ui/components/SlashCommands.tsx
|
|
3303
3464
|
import { Box as Box12, Text as Text11 } from "ink";
|
|
3304
|
-
import
|
|
3305
|
-
|
|
3306
|
-
|
|
3307
|
-
|
|
3308
|
-
workdir,
|
|
3309
|
-
statusMessage
|
|
3310
|
-
}) => {
|
|
3311
|
-
return /* @__PURE__ */ jsx12(
|
|
3465
|
+
import { Fragment as Fragment3, jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
3466
|
+
var SlashCommands = ({ input, setHistory, agentRef }) => {
|
|
3467
|
+
const [cmd, ...args] = input.slice(1).trim().split(/\s+/);
|
|
3468
|
+
const outBox = (children) => /* @__PURE__ */ jsx12(
|
|
3312
3469
|
Box12,
|
|
3313
3470
|
{
|
|
3314
|
-
borderStyle: "
|
|
3471
|
+
borderStyle: "single",
|
|
3315
3472
|
borderColor: "gray",
|
|
3473
|
+
paddingX: 2,
|
|
3474
|
+
paddingY: 0,
|
|
3316
3475
|
marginBottom: 1,
|
|
3317
|
-
|
|
3318
|
-
|
|
3319
|
-
{
|
|
3320
|
-
marginLeft: 1,
|
|
3321
|
-
flexDirection: "column",
|
|
3322
|
-
children: [
|
|
3323
|
-
/* @__PURE__ */ jsxs10(Text11, { children: [
|
|
3324
|
-
/* @__PURE__ */ jsx12(Text11, { bold: true, color: "white", children: "localhost" }),
|
|
3325
|
-
" ",
|
|
3326
|
-
/* @__PURE__ */ jsx12(Text11, { color: "gray", children: " session:" }),
|
|
3327
|
-
" ",
|
|
3328
|
-
/* @__PURE__ */ jsx12(Text11, { color: "magenta", children: sessionId2 })
|
|
3329
|
-
] }),
|
|
3330
|
-
/* @__PURE__ */ jsxs10(Text11, { children: [
|
|
3331
|
-
/* @__PURE__ */ jsx12(Text11, { color: "magenta", children: "\u21B3" }),
|
|
3332
|
-
" ",
|
|
3333
|
-
/* @__PURE__ */ jsxs10(Text11, { color: "gray", children: [
|
|
3334
|
-
"workdir: ",
|
|
3335
|
-
workdir
|
|
3336
|
-
] })
|
|
3337
|
-
] }),
|
|
3338
|
-
/* @__PURE__ */ jsxs10(Text11, { children: [
|
|
3339
|
-
/* @__PURE__ */ jsx12(Text11, { color: "magenta", children: "\u21B3" }),
|
|
3340
|
-
" ",
|
|
3341
|
-
/* @__PURE__ */ jsx12(Text11, { color: "gray", children: "mcp: " }),
|
|
3342
|
-
/* @__PURE__ */ jsxs10(Text11, { color: "yellow", children: [
|
|
3343
|
-
/* @__PURE__ */ jsx12(Spinner, { type: "dots" }),
|
|
3344
|
-
" "
|
|
3345
|
-
] }),
|
|
3346
|
-
/* @__PURE__ */ jsx12(Text11, { color: "white", children: statusMessage || "Please wait while we establish connections." })
|
|
3347
|
-
] })
|
|
3348
|
-
]
|
|
3349
|
-
}
|
|
3350
|
-
)
|
|
3476
|
+
flexDirection: "column",
|
|
3477
|
+
children
|
|
3351
3478
|
}
|
|
3352
3479
|
);
|
|
3353
|
-
};
|
|
3354
|
-
var SessionInfoConnectingMCP_default = SessionInfoConnectingMCP;
|
|
3355
|
-
|
|
3356
|
-
// src/app/ui/components/SlashCommands.tsx
|
|
3357
|
-
import { Box as Box13, Text as Text12 } from "ink";
|
|
3358
|
-
import { Fragment as Fragment2, jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
3359
|
-
var SlashCommands = ({ input, setHistory, agentRef }) => {
|
|
3360
|
-
const [cmd, ...args] = input.slice(1).trim().split(/\s+/);
|
|
3361
|
-
const outBox = (children) => /* @__PURE__ */ jsx13(Box13, { borderStyle: "round", borderColor: "gray", paddingX: 1, marginBottom: 1, flexDirection: "column", children });
|
|
3362
3480
|
const render2 = () => {
|
|
3363
3481
|
if (!cmd) {
|
|
3364
3482
|
return null;
|
|
@@ -3366,19 +3484,23 @@ var SlashCommands = ({ input, setHistory, agentRef }) => {
|
|
|
3366
3484
|
if (cmd === "help") {
|
|
3367
3485
|
const cmds = getSlashCommands();
|
|
3368
3486
|
return outBox(
|
|
3369
|
-
/* @__PURE__ */
|
|
3370
|
-
/* @__PURE__ */
|
|
3371
|
-
cmds.map((c, i) => /* @__PURE__ */
|
|
3372
|
-
c.name,
|
|
3373
|
-
|
|
3374
|
-
|
|
3375
|
-
] }, i))
|
|
3487
|
+
/* @__PURE__ */ jsxs10(Fragment3, { children: [
|
|
3488
|
+
/* @__PURE__ */ jsx12(Box12, { marginBottom: 1, children: /* @__PURE__ */ jsx12(Text11, { bold: true, color: "magenta", children: "Available Commands" }) }),
|
|
3489
|
+
/* @__PURE__ */ jsx12(Box12, { flexDirection: "column", children: cmds.map((c, i) => /* @__PURE__ */ jsxs10(Box12, { children: [
|
|
3490
|
+
/* @__PURE__ */ jsx12(Text11, { color: "cyan", children: c.name.padEnd(12) }),
|
|
3491
|
+
/* @__PURE__ */ jsx12(Text11, { dimColor: true, children: c.description })
|
|
3492
|
+
] }, i)) })
|
|
3376
3493
|
] })
|
|
3377
3494
|
);
|
|
3378
3495
|
}
|
|
3379
3496
|
if (cmd === "clear") {
|
|
3380
3497
|
setHistory((prev) => prev.filter((item) => item.id === 0 || item.id === 1));
|
|
3381
|
-
return outBox(
|
|
3498
|
+
return outBox(
|
|
3499
|
+
/* @__PURE__ */ jsxs10(Box12, { children: [
|
|
3500
|
+
/* @__PURE__ */ jsx12(Text11, { color: "green", children: "\u2713" }),
|
|
3501
|
+
/* @__PURE__ */ jsx12(Text11, { dimColor: true, children: " History cleared" })
|
|
3502
|
+
] })
|
|
3503
|
+
);
|
|
3382
3504
|
}
|
|
3383
3505
|
if (cmd === "init") {
|
|
3384
3506
|
(async () => {
|
|
@@ -3387,10 +3509,12 @@ var SlashCommands = ({ input, setHistory, agentRef }) => {
|
|
|
3387
3509
|
} catch (e) {
|
|
3388
3510
|
setHistory((prev) => prev.concat({
|
|
3389
3511
|
id: Date.now(),
|
|
3390
|
-
component: outBox(
|
|
3391
|
-
|
|
3392
|
-
|
|
3393
|
-
|
|
3512
|
+
component: outBox(
|
|
3513
|
+
/* @__PURE__ */ jsx12(Box12, { children: /* @__PURE__ */ jsxs10(Text11, { color: "red", children: [
|
|
3514
|
+
"\u2716 Failed to execute /init: ",
|
|
3515
|
+
e?.message || String(e)
|
|
3516
|
+
] }) })
|
|
3517
|
+
)
|
|
3394
3518
|
}));
|
|
3395
3519
|
}
|
|
3396
3520
|
})();
|
|
@@ -3407,37 +3531,45 @@ var SlashCommands = ({ input, setHistory, agentRef }) => {
|
|
|
3407
3531
|
const colType = 10;
|
|
3408
3532
|
const colSource = 18;
|
|
3409
3533
|
return outBox(
|
|
3410
|
-
/* @__PURE__ */
|
|
3411
|
-
/* @__PURE__ */
|
|
3412
|
-
|
|
3413
|
-
|
|
3414
|
-
|
|
3415
|
-
|
|
3534
|
+
/* @__PURE__ */ jsxs10(Fragment3, { children: [
|
|
3535
|
+
/* @__PURE__ */ jsxs10(Box12, { marginBottom: 1, children: [
|
|
3536
|
+
/* @__PURE__ */ jsx12(Text11, { bold: true, color: "magenta", children: "MCP Tools" }),
|
|
3537
|
+
/* @__PURE__ */ jsx12(Text11, { dimColor: true, children: " \u2022 " }),
|
|
3538
|
+
/* @__PURE__ */ jsxs10(Text11, { dimColor: true, children: [
|
|
3539
|
+
tools.length,
|
|
3540
|
+
" total"
|
|
3541
|
+
] }),
|
|
3542
|
+
term && /* @__PURE__ */ jsxs10(Fragment3, { children: [
|
|
3543
|
+
/* @__PURE__ */ jsx12(Text11, { dimColor: true, children: " \u2022 filter: " }),
|
|
3544
|
+
/* @__PURE__ */ jsxs10(Text11, { color: "cyan", children: [
|
|
3545
|
+
'"',
|
|
3546
|
+
term,
|
|
3547
|
+
'"'
|
|
3548
|
+
] }),
|
|
3549
|
+
/* @__PURE__ */ jsxs10(Text11, { dimColor: true, children: [
|
|
3550
|
+
" \u2022 showing: ",
|
|
3551
|
+
filtered.length
|
|
3552
|
+
] })
|
|
3553
|
+
] })
|
|
3416
3554
|
] }),
|
|
3417
|
-
filtered.length === 0 ? /* @__PURE__ */
|
|
3418
|
-
/* @__PURE__ */
|
|
3555
|
+
filtered.length === 0 ? /* @__PURE__ */ jsx12(Text11, { color: "yellow", children: "No MCP tools found" }) : /* @__PURE__ */ jsxs10(Box12, { flexDirection: "column", children: [
|
|
3556
|
+
/* @__PURE__ */ jsx12(Box12, { children: /* @__PURE__ */ jsxs10(Text11, { color: "gray", children: [
|
|
3419
3557
|
pad("Name", colName),
|
|
3420
|
-
"
|
|
3558
|
+
" \u2502 ",
|
|
3421
3559
|
pad("Type", colType),
|
|
3422
|
-
"
|
|
3560
|
+
" \u2502 ",
|
|
3423
3561
|
pad("Source", colSource)
|
|
3424
|
-
] }),
|
|
3425
|
-
/* @__PURE__ */
|
|
3426
|
-
"".padEnd(colName, "-"),
|
|
3427
|
-
"---",
|
|
3428
|
-
"".padEnd(colType, "-"),
|
|
3429
|
-
"---",
|
|
3430
|
-
"".padEnd(colSource, "-")
|
|
3431
|
-
] }),
|
|
3562
|
+
] }) }),
|
|
3563
|
+
/* @__PURE__ */ jsx12(Text11, { color: "gray", children: "\u2500".repeat(colName + colType + colSource + 6) }),
|
|
3432
3564
|
filtered.map((t, i) => {
|
|
3433
3565
|
const name = t.function?.name || t.name || "tool";
|
|
3434
3566
|
const type = t.function?.name ? "fn" : t.type || "tool";
|
|
3435
3567
|
const source = t.source || t.provider || "mcp";
|
|
3436
|
-
return /* @__PURE__ */
|
|
3568
|
+
return /* @__PURE__ */ jsxs10(Text11, { color: "white", children: [
|
|
3437
3569
|
pad(name, colName),
|
|
3438
|
-
"
|
|
3570
|
+
" \u2502 ",
|
|
3439
3571
|
pad(String(type), colType),
|
|
3440
|
-
"
|
|
3572
|
+
" \u2502 ",
|
|
3441
3573
|
pad(String(source), colSource)
|
|
3442
3574
|
] }, i);
|
|
3443
3575
|
})
|
|
@@ -3456,22 +3588,22 @@ var SlashCommands = ({ input, setHistory, agentRef }) => {
|
|
|
3456
3588
|
const colType = 10;
|
|
3457
3589
|
const colSource = 18;
|
|
3458
3590
|
return outBox(
|
|
3459
|
-
/* @__PURE__ */
|
|
3460
|
-
/* @__PURE__ */
|
|
3461
|
-
/* @__PURE__ */
|
|
3591
|
+
/* @__PURE__ */ jsxs10(Fragment3, { children: [
|
|
3592
|
+
/* @__PURE__ */ jsx12(Text11, { color: "magenta", bold: true, children: "Native Tools" }),
|
|
3593
|
+
/* @__PURE__ */ jsxs10(Text11, { color: "gray", children: [
|
|
3462
3594
|
"Total Native: ",
|
|
3463
3595
|
tools.length,
|
|
3464
3596
|
term ? ` | Filter: "${term}" | Showing: ${filtered.length}` : ""
|
|
3465
3597
|
] }),
|
|
3466
|
-
filtered.length === 0 ? /* @__PURE__ */
|
|
3467
|
-
/* @__PURE__ */
|
|
3598
|
+
filtered.length === 0 ? /* @__PURE__ */ jsx12(Text11, { color: "yellow", children: "No native tools to display." }) : /* @__PURE__ */ jsxs10(Box12, { flexDirection: "column", children: [
|
|
3599
|
+
/* @__PURE__ */ jsxs10(Text11, { color: "gray", children: [
|
|
3468
3600
|
pad("Name", colName),
|
|
3469
3601
|
" | ",
|
|
3470
3602
|
pad("Type", colType),
|
|
3471
3603
|
" | ",
|
|
3472
3604
|
pad("Source", colSource)
|
|
3473
3605
|
] }),
|
|
3474
|
-
/* @__PURE__ */
|
|
3606
|
+
/* @__PURE__ */ jsxs10(Text11, { color: "gray", children: [
|
|
3475
3607
|
"".padEnd(colName, "-"),
|
|
3476
3608
|
"---",
|
|
3477
3609
|
"".padEnd(colType, "-"),
|
|
@@ -3482,7 +3614,7 @@ var SlashCommands = ({ input, setHistory, agentRef }) => {
|
|
|
3482
3614
|
const name = t.function?.name || t.name || "tool";
|
|
3483
3615
|
const type = t.function?.name ? "fn" : t.type || "tool";
|
|
3484
3616
|
const source = t.source || "native";
|
|
3485
|
-
return /* @__PURE__ */
|
|
3617
|
+
return /* @__PURE__ */ jsxs10(Text11, { color: "white", children: [
|
|
3486
3618
|
pad(name, colName),
|
|
3487
3619
|
" | ",
|
|
3488
3620
|
pad(String(type), colType),
|
|
@@ -3494,12 +3626,12 @@ var SlashCommands = ({ input, setHistory, agentRef }) => {
|
|
|
3494
3626
|
] })
|
|
3495
3627
|
);
|
|
3496
3628
|
}
|
|
3497
|
-
return outBox(/* @__PURE__ */
|
|
3629
|
+
return outBox(/* @__PURE__ */ jsxs10(Text11, { color: "red", children: [
|
|
3498
3630
|
"Command not recognized: /",
|
|
3499
3631
|
cmd
|
|
3500
3632
|
] }));
|
|
3501
3633
|
};
|
|
3502
|
-
return /* @__PURE__ */
|
|
3634
|
+
return /* @__PURE__ */ jsx12(Fragment3, { children: render2() });
|
|
3503
3635
|
};
|
|
3504
3636
|
var SlashCommands_default = SlashCommands;
|
|
3505
3637
|
|
|
@@ -3570,8 +3702,8 @@ async function checkForUpdates() {
|
|
|
3570
3702
|
}
|
|
3571
3703
|
|
|
3572
3704
|
// src/app/ui/components/UpdateNotice.tsx
|
|
3573
|
-
import { Box as
|
|
3574
|
-
import { jsx as
|
|
3705
|
+
import { Box as Box13, Text as Text12 } from "ink";
|
|
3706
|
+
import { jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
3575
3707
|
function parseUpdateMessage(msg) {
|
|
3576
3708
|
const lines = msg.split(/\r?\n/).map((l) => l.trim());
|
|
3577
3709
|
const first = lines[0] || "";
|
|
@@ -3590,20 +3722,20 @@ function parseUpdateMessage(msg) {
|
|
|
3590
3722
|
}
|
|
3591
3723
|
var UpdateNotice = ({ message }) => {
|
|
3592
3724
|
const { name, current, latest, hint } = parseUpdateMessage(message);
|
|
3593
|
-
return /* @__PURE__ */
|
|
3594
|
-
/* @__PURE__ */
|
|
3595
|
-
name && current && latest ? /* @__PURE__ */
|
|
3596
|
-
hint ? /* @__PURE__ */
|
|
3725
|
+
return /* @__PURE__ */ jsxs11(Box13, { flexDirection: "column", marginBottom: 1, children: [
|
|
3726
|
+
/* @__PURE__ */ jsx13(Text12, { color: "yellow", bold: true, children: "Update Available" }),
|
|
3727
|
+
name && current && latest ? /* @__PURE__ */ jsx13(Text12, { color: "gray", children: `${name}: ${current} \u2192 ${latest}` }) : /* @__PURE__ */ jsx13(Text12, { color: "gray", children: message }),
|
|
3728
|
+
hint ? /* @__PURE__ */ jsx13(Text12, { color: "gray", children: hint }) : null
|
|
3597
3729
|
] });
|
|
3598
3730
|
};
|
|
3599
3731
|
var UpdateNotice_default = UpdateNotice;
|
|
3600
3732
|
|
|
3601
3733
|
// src/app/ui/components/ErrorMessage.tsx
|
|
3602
|
-
import { Box as
|
|
3603
|
-
import { jsx as
|
|
3734
|
+
import { Box as Box14, Text as Text13 } from "ink";
|
|
3735
|
+
import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
3604
3736
|
var ErrorMessage = ({ message, details, hint }) => {
|
|
3605
|
-
return /* @__PURE__ */
|
|
3606
|
-
|
|
3737
|
+
return /* @__PURE__ */ jsxs12(
|
|
3738
|
+
Box14,
|
|
3607
3739
|
{
|
|
3608
3740
|
borderStyle: "round",
|
|
3609
3741
|
borderColor: "red",
|
|
@@ -3612,10 +3744,10 @@ var ErrorMessage = ({ message, details, hint }) => {
|
|
|
3612
3744
|
flexDirection: "column",
|
|
3613
3745
|
marginBottom: 1,
|
|
3614
3746
|
children: [
|
|
3615
|
-
/* @__PURE__ */
|
|
3616
|
-
/* @__PURE__ */
|
|
3617
|
-
details ? /* @__PURE__ */
|
|
3618
|
-
hint ? /* @__PURE__ */
|
|
3747
|
+
/* @__PURE__ */ jsx14(Text13, { color: "red", bold: true, children: "Error" }),
|
|
3748
|
+
/* @__PURE__ */ jsx14(Text13, { color: "red", children: message }),
|
|
3749
|
+
details ? /* @__PURE__ */ jsx14(Text13, { color: "red", dimColor: true, children: details }) : null,
|
|
3750
|
+
hint ? /* @__PURE__ */ jsxs12(Text13, { color: "gray", children: [
|
|
3619
3751
|
"Hint: ",
|
|
3620
3752
|
hint
|
|
3621
3753
|
] }) : null
|
|
@@ -3626,9 +3758,9 @@ var ErrorMessage = ({ message, details, hint }) => {
|
|
|
3626
3758
|
var ErrorMessage_default = ErrorMessage;
|
|
3627
3759
|
|
|
3628
3760
|
// src/app/ui/App.tsx
|
|
3629
|
-
import { jsx as
|
|
3761
|
+
import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
3630
3762
|
var AppComponent = ({ eventBus: eventBus2, sessionId: sessionId2 }) => {
|
|
3631
|
-
const agentInstance =
|
|
3763
|
+
const agentInstance = useRef4(null);
|
|
3632
3764
|
const [history, setHistory] = useState5([]);
|
|
3633
3765
|
const [statusMessage, setStatusMessage] = useState5(
|
|
3634
3766
|
"Initializing agent..."
|
|
@@ -3645,10 +3777,10 @@ var AppComponent = ({ eventBus: eventBus2, sessionId: sessionId2 }) => {
|
|
|
3645
3777
|
null
|
|
3646
3778
|
);
|
|
3647
3779
|
const [isInitAgentActive, setIsInitAgentActive] = useState5(false);
|
|
3648
|
-
const alwaysAcceptList =
|
|
3780
|
+
const alwaysAcceptList = useRef4([]);
|
|
3649
3781
|
const workdir = process.cwd();
|
|
3650
|
-
const updateCheckRan =
|
|
3651
|
-
const handleInterrupt =
|
|
3782
|
+
const updateCheckRan = useRef4(false);
|
|
3783
|
+
const handleInterrupt = useCallback2(() => {
|
|
3652
3784
|
if (!isProcessing) return;
|
|
3653
3785
|
eventBus2.emit("user_interrupt");
|
|
3654
3786
|
setIsProcessing(false);
|
|
@@ -3656,11 +3788,11 @@ var AppComponent = ({ eventBus: eventBus2, sessionId: sessionId2 }) => {
|
|
|
3656
3788
|
...prev,
|
|
3657
3789
|
{
|
|
3658
3790
|
id: prev.length,
|
|
3659
|
-
component: /* @__PURE__ */
|
|
3791
|
+
component: /* @__PURE__ */ jsx15(Text14, { color: "yellow", children: "-- Task cancelled by dev. --" })
|
|
3660
3792
|
}
|
|
3661
3793
|
]);
|
|
3662
3794
|
}, [isProcessing, eventBus2]);
|
|
3663
|
-
const handleSubmit =
|
|
3795
|
+
const handleSubmit = useCallback2(
|
|
3664
3796
|
(text) => {
|
|
3665
3797
|
if (!text || isProcessing || !agentInstance.current) return;
|
|
3666
3798
|
if (text.startsWith("/")) {
|
|
@@ -3680,11 +3812,11 @@ var AppComponent = ({ eventBus: eventBus2, sessionId: sessionId2 }) => {
|
|
|
3680
3812
|
...prev,
|
|
3681
3813
|
{
|
|
3682
3814
|
id: prev.length,
|
|
3683
|
-
component: /* @__PURE__ */
|
|
3815
|
+
component: /* @__PURE__ */ jsx15(Box15, { marginBottom: 1, children: /* @__PURE__ */ jsx15(Text14, { color: "white", dimColor: true, children: text }) })
|
|
3684
3816
|
},
|
|
3685
3817
|
{
|
|
3686
3818
|
id: prev.length + 1,
|
|
3687
|
-
component: /* @__PURE__ */
|
|
3819
|
+
component: /* @__PURE__ */ jsx15(
|
|
3688
3820
|
SlashCommands_default,
|
|
3689
3821
|
{
|
|
3690
3822
|
input: text,
|
|
@@ -3704,8 +3836,8 @@ var AppComponent = ({ eventBus: eventBus2, sessionId: sessionId2 }) => {
|
|
|
3704
3836
|
id: prev.length,
|
|
3705
3837
|
component: (
|
|
3706
3838
|
// Uma única Box para o espaçamento
|
|
3707
|
-
/* @__PURE__ */
|
|
3708
|
-
/* @__PURE__ */
|
|
3839
|
+
/* @__PURE__ */ jsx15(Box15, { marginBottom: 1, children: /* @__PURE__ */ jsxs13(Text14, { color: "white", dimColor: true, children: [
|
|
3840
|
+
/* @__PURE__ */ jsxs13(Text14, { color: "white", children: [
|
|
3709
3841
|
">",
|
|
3710
3842
|
" "
|
|
3711
3843
|
] }),
|
|
@@ -3718,7 +3850,7 @@ var AppComponent = ({ eventBus: eventBus2, sessionId: sessionId2 }) => {
|
|
|
3718
3850
|
},
|
|
3719
3851
|
[isProcessing]
|
|
3720
3852
|
);
|
|
3721
|
-
const handleConfirmation =
|
|
3853
|
+
const handleConfirmation = useCallback2(
|
|
3722
3854
|
(decision, toolCalls) => {
|
|
3723
3855
|
if (!agentInstance.current) return;
|
|
3724
3856
|
setPendingConfirmation(null);
|
|
@@ -3739,8 +3871,8 @@ var AppComponent = ({ eventBus: eventBus2, sessionId: sessionId2 }) => {
|
|
|
3739
3871
|
},
|
|
3740
3872
|
[]
|
|
3741
3873
|
);
|
|
3742
|
-
|
|
3743
|
-
setHistory([{ id: 0, component: /* @__PURE__ */
|
|
3874
|
+
useEffect5(() => {
|
|
3875
|
+
setHistory([{ id: 0, component: /* @__PURE__ */ jsx15(Header, { sessionId: sessionId2, workdir }) }]);
|
|
3744
3876
|
const initializeAgent = async () => {
|
|
3745
3877
|
try {
|
|
3746
3878
|
agentInstance.current = new Agent(sessionId2, eventBus2);
|
|
@@ -3792,20 +3924,6 @@ var AppComponent = ({ eventBus: eventBus2, sessionId: sessionId2 }) => {
|
|
|
3792
3924
|
setIsProcessing(false);
|
|
3793
3925
|
setHistory((prev) => {
|
|
3794
3926
|
const newHistory = [...prev];
|
|
3795
|
-
if (prev.length < 2) {
|
|
3796
|
-
newHistory.push({
|
|
3797
|
-
id: 1,
|
|
3798
|
-
component: /* @__PURE__ */ jsx16(
|
|
3799
|
-
SessionInfo,
|
|
3800
|
-
{
|
|
3801
|
-
sessionId: sessionId2,
|
|
3802
|
-
toolsCount: parsed.tools,
|
|
3803
|
-
mcpStatus: "connected",
|
|
3804
|
-
workdir
|
|
3805
|
-
}
|
|
3806
|
-
)
|
|
3807
|
-
});
|
|
3808
|
-
}
|
|
3809
3927
|
return newHistory;
|
|
3810
3928
|
});
|
|
3811
3929
|
if (!updateCheckRan.current) {
|
|
@@ -3816,7 +3934,7 @@ var AppComponent = ({ eventBus: eventBus2, sessionId: sessionId2 }) => {
|
|
|
3816
3934
|
...prev,
|
|
3817
3935
|
{
|
|
3818
3936
|
id: prev.length,
|
|
3819
|
-
component: /* @__PURE__ */
|
|
3937
|
+
component: /* @__PURE__ */ jsx15(UpdateNotice_default, { message: msg })
|
|
3820
3938
|
}
|
|
3821
3939
|
]);
|
|
3822
3940
|
}
|
|
@@ -3830,10 +3948,10 @@ var AppComponent = ({ eventBus: eventBus2, sessionId: sessionId2 }) => {
|
|
|
3830
3948
|
}
|
|
3831
3949
|
let newComponent = null;
|
|
3832
3950
|
if (parsed.type === "debug") {
|
|
3833
|
-
newComponent = /* @__PURE__ */
|
|
3951
|
+
newComponent = /* @__PURE__ */ jsx15(Text14, { color: "gray", children: parsed.message });
|
|
3834
3952
|
} else if (parsed.type === "protocol_violation") {
|
|
3835
|
-
newComponent = /* @__PURE__ */
|
|
3836
|
-
|
|
3953
|
+
newComponent = /* @__PURE__ */ jsxs13(
|
|
3954
|
+
Box15,
|
|
3837
3955
|
{
|
|
3838
3956
|
borderStyle: "round",
|
|
3839
3957
|
borderColor: "yellow",
|
|
@@ -3841,14 +3959,14 @@ var AppComponent = ({ eventBus: eventBus2, sessionId: sessionId2 }) => {
|
|
|
3841
3959
|
marginBottom: 1,
|
|
3842
3960
|
paddingX: 1,
|
|
3843
3961
|
children: [
|
|
3844
|
-
/* @__PURE__ */
|
|
3845
|
-
/* @__PURE__ */
|
|
3846
|
-
/* @__PURE__ */
|
|
3962
|
+
/* @__PURE__ */ jsx15(Text14, { color: "yellow", bold: true, children: "Protocol Violation" }),
|
|
3963
|
+
/* @__PURE__ */ jsx15(Text14, { color: "gray", children: parsed.content }),
|
|
3964
|
+
/* @__PURE__ */ jsx15(Text14, { color: "yellow", children: parsed.message })
|
|
3847
3965
|
]
|
|
3848
3966
|
}
|
|
3849
3967
|
);
|
|
3850
3968
|
} else if (parsed.type === "error") {
|
|
3851
|
-
newComponent = /* @__PURE__ */
|
|
3969
|
+
newComponent = /* @__PURE__ */ jsx15(
|
|
3852
3970
|
ErrorMessage_default,
|
|
3853
3971
|
{
|
|
3854
3972
|
message: parsed.message,
|
|
@@ -3858,7 +3976,7 @@ var AppComponent = ({ eventBus: eventBus2, sessionId: sessionId2 }) => {
|
|
|
3858
3976
|
);
|
|
3859
3977
|
} else if (parsed.type === "tool_call") {
|
|
3860
3978
|
const nextId = history.length;
|
|
3861
|
-
newComponent = /* @__PURE__ */
|
|
3979
|
+
newComponent = /* @__PURE__ */ jsx15(
|
|
3862
3980
|
ToolCallDisplay,
|
|
3863
3981
|
{
|
|
3864
3982
|
toolName: parsed.tool_name,
|
|
@@ -3867,7 +3985,7 @@ var AppComponent = ({ eventBus: eventBus2, sessionId: sessionId2 }) => {
|
|
|
3867
3985
|
}
|
|
3868
3986
|
);
|
|
3869
3987
|
} else if (parsed.type === "tool_result") {
|
|
3870
|
-
newComponent = /* @__PURE__ */
|
|
3988
|
+
newComponent = /* @__PURE__ */ jsx15(
|
|
3871
3989
|
ToolResultDisplay,
|
|
3872
3990
|
{
|
|
3873
3991
|
toolName: parsed.tool_name,
|
|
@@ -3875,15 +3993,15 @@ var AppComponent = ({ eventBus: eventBus2, sessionId: sessionId2 }) => {
|
|
|
3875
3993
|
}
|
|
3876
3994
|
);
|
|
3877
3995
|
} else if (parsed.type === "user_overlay") {
|
|
3878
|
-
newComponent = /* @__PURE__ */
|
|
3879
|
-
/* @__PURE__ */
|
|
3996
|
+
newComponent = /* @__PURE__ */ jsx15(Box15, { marginBottom: 1, children: /* @__PURE__ */ jsxs13(Text14, { color: "gray", children: [
|
|
3997
|
+
/* @__PURE__ */ jsxs13(Text14, { color: "magenta", children: [
|
|
3880
3998
|
">",
|
|
3881
3999
|
" "
|
|
3882
4000
|
] }),
|
|
3883
4001
|
parsed.payload
|
|
3884
4002
|
] }) });
|
|
3885
4003
|
} else if (parsed.type === "log") {
|
|
3886
|
-
newComponent = /* @__PURE__ */
|
|
4004
|
+
newComponent = /* @__PURE__ */ jsxs13(Text14, { color: "gray", children: [
|
|
3887
4005
|
"\u2139\uFE0F ",
|
|
3888
4006
|
parsed.message,
|
|
3889
4007
|
parsed.payload ? `: ${parsed.payload}` : ""
|
|
@@ -3913,17 +4031,10 @@ var AppComponent = ({ eventBus: eventBus2, sessionId: sessionId2 }) => {
|
|
|
3913
4031
|
}, [eventBus2, sessionId2, handleConfirmation]);
|
|
3914
4032
|
const renderInteractiveComponent = () => {
|
|
3915
4033
|
if (mcpStatus !== "connected") {
|
|
3916
|
-
return
|
|
3917
|
-
SessionInfoConnectingMCP_default,
|
|
3918
|
-
{
|
|
3919
|
-
sessionId: sessionId2,
|
|
3920
|
-
workdir,
|
|
3921
|
-
statusMessage
|
|
3922
|
-
}
|
|
3923
|
-
) });
|
|
4034
|
+
return;
|
|
3924
4035
|
}
|
|
3925
4036
|
if (pendingConfirmation) {
|
|
3926
|
-
return /* @__PURE__ */
|
|
4037
|
+
return /* @__PURE__ */ jsx15(
|
|
3927
4038
|
ConfirmationPrompt,
|
|
3928
4039
|
{
|
|
3929
4040
|
toolCalls: pendingConfirmation,
|
|
@@ -3935,9 +4046,9 @@ var AppComponent = ({ eventBus: eventBus2, sessionId: sessionId2 }) => {
|
|
|
3935
4046
|
}
|
|
3936
4047
|
);
|
|
3937
4048
|
}
|
|
3938
|
-
return /* @__PURE__ */
|
|
3939
|
-
isProcessing && !pendingConfirmation && /* @__PURE__ */
|
|
3940
|
-
/* @__PURE__ */
|
|
4049
|
+
return /* @__PURE__ */ jsxs13(Box15, { flexDirection: "column", children: [
|
|
4050
|
+
isProcessing && !pendingConfirmation && /* @__PURE__ */ jsx15(WorkingTimer, {}),
|
|
4051
|
+
/* @__PURE__ */ jsx15(
|
|
3941
4052
|
InputPrompt,
|
|
3942
4053
|
{
|
|
3943
4054
|
onSubmit: handleSubmit,
|
|
@@ -3948,12 +4059,12 @@ var AppComponent = ({ eventBus: eventBus2, sessionId: sessionId2 }) => {
|
|
|
3948
4059
|
)
|
|
3949
4060
|
] });
|
|
3950
4061
|
};
|
|
3951
|
-
return /* @__PURE__ */
|
|
3952
|
-
/* @__PURE__ */
|
|
4062
|
+
return /* @__PURE__ */ jsxs13(Box15, { flexDirection: "column", children: [
|
|
4063
|
+
/* @__PURE__ */ jsx15(Static, { items: history, children: (item) => /* @__PURE__ */ jsx15(Box15, { children: item.component }, item.id) }),
|
|
3953
4064
|
renderInteractiveComponent()
|
|
3954
4065
|
] });
|
|
3955
4066
|
};
|
|
3956
|
-
var App =
|
|
4067
|
+
var App = memo5(AppComponent);
|
|
3957
4068
|
var App_default = App;
|
|
3958
4069
|
|
|
3959
4070
|
// src/app/ui/utils/terminalTitle.ts
|