@nomad-e/bluma-cli 0.0.11 → 0.0.13
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/config/bluma-mcp.json +0 -13
- package/dist/main.js +374 -61
- package/package.json +1 -1
|
@@ -10,19 +10,6 @@
|
|
|
10
10
|
"@sousaalex1605/bluma-nootebook"
|
|
11
11
|
]
|
|
12
12
|
},
|
|
13
|
-
"githubApi": {
|
|
14
|
-
"type": "stdio",
|
|
15
|
-
"command": "cmd",
|
|
16
|
-
"args": [
|
|
17
|
-
"/c",
|
|
18
|
-
"npx",
|
|
19
|
-
"-y",
|
|
20
|
-
"@modelcontextprotocol/server-github"
|
|
21
|
-
],
|
|
22
|
-
"env": {
|
|
23
|
-
"GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_PERSONAL_ACCESS_TOKEN}"
|
|
24
|
-
}
|
|
25
|
-
},
|
|
26
13
|
"notionApi": {
|
|
27
14
|
"type": "stdio",
|
|
28
15
|
"command": "cmd",
|
package/dist/main.js
CHANGED
|
@@ -7,8 +7,7 @@ import { v4 as uuidv42 } from "uuid";
|
|
|
7
7
|
|
|
8
8
|
// src/app/ui/App.tsx
|
|
9
9
|
import { useState as useState4, useEffect as useEffect3, useRef, useCallback, memo as memo4 } from "react";
|
|
10
|
-
import { Box as
|
|
11
|
-
import Spinner from "ink-spinner";
|
|
10
|
+
import { Box as Box13, Text as Text12, Static } from "ink";
|
|
12
11
|
|
|
13
12
|
// src/app/ui/layout.tsx
|
|
14
13
|
import { Box, Text } from "ink";
|
|
@@ -21,14 +20,34 @@ var BRAND_COLORS = {
|
|
|
21
20
|
greydark: "#444"
|
|
22
21
|
};
|
|
23
22
|
var Header = () => {
|
|
24
|
-
return /* @__PURE__ */
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
23
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
24
|
+
/* @__PURE__ */ jsx(
|
|
25
|
+
Box,
|
|
26
|
+
{
|
|
27
|
+
flexDirection: "column",
|
|
28
|
+
height: 8,
|
|
29
|
+
marginBottom: 1,
|
|
30
|
+
children: /* @__PURE__ */ jsx(
|
|
31
|
+
BigText,
|
|
32
|
+
{
|
|
33
|
+
text: "BluMa CLI",
|
|
34
|
+
font: "block",
|
|
35
|
+
colors: [BRAND_COLORS.main, BRAND_COLORS.accent, BRAND_COLORS.shadow]
|
|
36
|
+
}
|
|
37
|
+
)
|
|
38
|
+
}
|
|
39
|
+
),
|
|
40
|
+
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", paddingX: 1, children: [
|
|
41
|
+
/* @__PURE__ */ jsx(Text, { children: "How to get started with BluMa:" }),
|
|
42
|
+
/* @__PURE__ */ jsx(Text, { children: "1. You can ask questions, modify files, or execute commands directly." }),
|
|
43
|
+
/* @__PURE__ */ jsx(Text, { children: "2. Be as clear and specific as possible to get accurate responses." }),
|
|
44
|
+
/* @__PURE__ */ jsxs(Text, { children: [
|
|
45
|
+
"3. Type ",
|
|
46
|
+
/* @__PURE__ */ jsx(Text, { color: "cyan", children: "/help" }),
|
|
47
|
+
" to explore available commands and features."
|
|
48
|
+
] })
|
|
49
|
+
] })
|
|
50
|
+
] });
|
|
32
51
|
};
|
|
33
52
|
var SessionInfo = ({
|
|
34
53
|
sessionId: sessionId2,
|
|
@@ -44,7 +63,6 @@ var SessionInfo = ({
|
|
|
44
63
|
{
|
|
45
64
|
borderStyle: "round",
|
|
46
65
|
borderColor: "gray",
|
|
47
|
-
paddingX: 1,
|
|
48
66
|
flexDirection: "column",
|
|
49
67
|
marginBottom: 1,
|
|
50
68
|
children: [
|
|
@@ -64,26 +82,18 @@ var SessionInfo = ({
|
|
|
64
82
|
] }),
|
|
65
83
|
/* @__PURE__ */ jsxs(Text, { children: [
|
|
66
84
|
/* @__PURE__ */ jsx(Text, { color: "magenta", children: "\u21B3" }),
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
/* @__PURE__ */ jsxs(Text, { children: [
|
|
70
|
-
/* @__PURE__ */ jsx(Text, { color: "magenta", children: "\u21B3" }),
|
|
71
|
-
/* @__PURE__ */ jsx(Text, { color: "gray", children: "MCP: " }),
|
|
85
|
+
" ",
|
|
86
|
+
/* @__PURE__ */ jsx(Text, { color: "gray", children: "mcp: " }),
|
|
72
87
|
/* @__PURE__ */ jsx(Text, { color: mcpStatus === "connected" ? "green" : "yellow", children: mcpStatus })
|
|
73
|
-
] }),
|
|
74
|
-
/* @__PURE__ */ jsxs(Text, { children: [
|
|
75
|
-
/* @__PURE__ */ jsx(Text, { color: "magenta", children: "\u21B3" }),
|
|
76
|
-
/* @__PURE__ */ jsx(Text, { color: "gray", children: "Tools: " }),
|
|
77
|
-
/* @__PURE__ */ jsx(Text, { color: "cyan", children: toolsCount !== null ? toolsCount : "loading..." })
|
|
78
88
|
] })
|
|
79
89
|
]
|
|
80
90
|
}
|
|
81
91
|
);
|
|
82
92
|
|
|
83
|
-
// src/app/ui/
|
|
84
|
-
import { Box as Box2, Text as Text2, useStdout } from "ink";
|
|
93
|
+
// src/app/ui/components/InputPrompt.tsx
|
|
94
|
+
import { Box as Box2, Text as Text2, useStdout, useInput as useInput2 } from "ink";
|
|
85
95
|
|
|
86
|
-
// src/app/ui/
|
|
96
|
+
// src/app/ui/utils/useSimpleInputBuffer.ts
|
|
87
97
|
import { useReducer } from "react";
|
|
88
98
|
import { useInput } from "ink";
|
|
89
99
|
function inputReducer(state, action, viewWidth) {
|
|
@@ -175,9 +185,24 @@ var useCustomInput = ({ onSubmit, viewWidth, isReadOnly, onInterrupt }) => {
|
|
|
175
185
|
};
|
|
176
186
|
};
|
|
177
187
|
|
|
178
|
-
// src/app/ui/
|
|
179
|
-
import { useEffect, useState } from "react";
|
|
188
|
+
// src/app/ui/components/InputPrompt.tsx
|
|
189
|
+
import { useEffect, useMemo, useState } from "react";
|
|
180
190
|
import { EventEmitter } from "events";
|
|
191
|
+
|
|
192
|
+
// src/app/ui/utils/slashRegistry.ts
|
|
193
|
+
var getSlashCommands = () => [
|
|
194
|
+
{ name: "/help", description: "list commands" },
|
|
195
|
+
{ name: "/mcp", description: "list tools connected via MCP" },
|
|
196
|
+
{ name: "/tools", description: "list native tools" },
|
|
197
|
+
{ name: "/clear", description: "clear history" }
|
|
198
|
+
];
|
|
199
|
+
var filterSlashCommands = (query) => {
|
|
200
|
+
const list = getSlashCommands();
|
|
201
|
+
const q = query.toLowerCase();
|
|
202
|
+
return list.filter((c) => c.name.toLowerCase().startsWith(q));
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
// src/app/ui/components/InputPrompt.tsx
|
|
181
206
|
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
182
207
|
var uiEventBus = global.__bluma_ui_eventbus__ || new EventEmitter();
|
|
183
208
|
global.__bluma_ui_eventbus__ = uiEventBus;
|
|
@@ -209,6 +234,8 @@ var InputPrompt = ({ onSubmit, isReadOnly, onInterrupt }) => {
|
|
|
209
234
|
isReadOnly,
|
|
210
235
|
onInterrupt
|
|
211
236
|
});
|
|
237
|
+
const [slashOpen, setSlashOpen] = useState(false);
|
|
238
|
+
const [slashIndex, setSlashIndex] = useState(0);
|
|
212
239
|
const visibleText = text.slice(viewStart, viewStart + viewWidth);
|
|
213
240
|
const visibleCursorPosition = cursorPosition - viewStart;
|
|
214
241
|
const textBeforeCursor = visibleText.slice(0, visibleCursorPosition);
|
|
@@ -221,8 +248,42 @@ var InputPrompt = ({ onSubmit, isReadOnly, onInterrupt }) => {
|
|
|
221
248
|
const borderColor = isReadOnly ? "gray" : "gray";
|
|
222
249
|
const placeholder = isReadOnly ? " press esc to cancel | type a message while agent processes" : "";
|
|
223
250
|
const showPlaceholder = text.length === 0 && isReadOnly;
|
|
251
|
+
const slashQuery = useMemo(() => text.startsWith("/") ? text : "", [text]);
|
|
252
|
+
const slashSuggestions = useMemo(() => {
|
|
253
|
+
if (!slashQuery) return [];
|
|
254
|
+
return filterSlashCommands(slashQuery);
|
|
255
|
+
}, [slashQuery]);
|
|
256
|
+
useEffect(() => {
|
|
257
|
+
if (isReadOnly) {
|
|
258
|
+
setSlashOpen(false);
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
if (text.startsWith("/")) {
|
|
262
|
+
setSlashOpen(true);
|
|
263
|
+
setSlashIndex(0);
|
|
264
|
+
} else {
|
|
265
|
+
setSlashOpen(false);
|
|
266
|
+
}
|
|
267
|
+
}, [text, isReadOnly]);
|
|
268
|
+
useInput2((input, key) => {
|
|
269
|
+
if (!slashOpen) return;
|
|
270
|
+
if (key.downArrow) {
|
|
271
|
+
setSlashIndex((i) => Math.min(i + 1, Math.max(0, slashSuggestions.length - 1)));
|
|
272
|
+
} else if (key.upArrow) {
|
|
273
|
+
setSlashIndex((i) => Math.max(i - 1, 0));
|
|
274
|
+
} else if (key.return) {
|
|
275
|
+
const choice = slashSuggestions[slashIndex];
|
|
276
|
+
if (choice) {
|
|
277
|
+
const cmd = choice.name;
|
|
278
|
+
setSlashOpen(false);
|
|
279
|
+
permissiveOnSubmit(cmd);
|
|
280
|
+
}
|
|
281
|
+
} else if (key.escape) {
|
|
282
|
+
setSlashOpen(false);
|
|
283
|
+
}
|
|
284
|
+
}, { isActive: slashOpen });
|
|
224
285
|
return /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", children: [
|
|
225
|
-
/* @__PURE__ */ jsx2(Box2, { borderStyle: "
|
|
286
|
+
/* @__PURE__ */ jsx2(Box2, { borderStyle: "round", borderColor, borderDimColor: !isReadOnly, width: viewWidth - 7, paddingY: 0, children: /* @__PURE__ */ jsxs2(Box2, { flexDirection: "row", paddingX: 1, flexWrap: "nowrap", children: [
|
|
226
287
|
/* @__PURE__ */ jsxs2(Text2, { color: "white", dimColor: true, children: [
|
|
227
288
|
">",
|
|
228
289
|
" "
|
|
@@ -231,8 +292,22 @@ var InputPrompt = ({ onSubmit, isReadOnly, onInterrupt }) => {
|
|
|
231
292
|
/* @__PURE__ */ jsx2(Text2, { inverse: true, children: cursorGlyph }),
|
|
232
293
|
showPlaceholder ? /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: placeholder }) : /* @__PURE__ */ jsx2(Text2, { children: textAfterCursor })
|
|
233
294
|
] }) }),
|
|
295
|
+
slashOpen && slashSuggestions.length > 0 && /* @__PURE__ */ jsx2(Box2, { flexDirection: "column", marginTop: 1, children: slashSuggestions.map((s, idx) => {
|
|
296
|
+
const isSelected = idx === slashIndex;
|
|
297
|
+
return /* @__PURE__ */ jsxs2(Box2, { paddingLeft: 1, paddingY: 0, children: [
|
|
298
|
+
/* @__PURE__ */ jsx2(Text2, { color: isSelected ? "blue" : "gray", children: isSelected ? "\u276F " : " " }),
|
|
299
|
+
/* @__PURE__ */ jsxs2(Text2, { color: isSelected ? "blue" : "white", bold: isSelected, dimColor: !isSelected, children: [
|
|
300
|
+
s.name,
|
|
301
|
+
" ",
|
|
302
|
+
/* @__PURE__ */ jsxs2(Text2, { color: "gray", children: [
|
|
303
|
+
"- ",
|
|
304
|
+
s.description
|
|
305
|
+
] })
|
|
306
|
+
] })
|
|
307
|
+
] }, s.name);
|
|
308
|
+
}) }),
|
|
234
309
|
/* @__PURE__ */ jsx2(Box2, { paddingX: 1, justifyContent: "center", children: /* @__PURE__ */ jsxs2(Text2, { color: "gray", dimColor: true, children: [
|
|
235
|
-
"ctrl+c to exit | esc to interrupt | ",
|
|
310
|
+
"ctrl+c to exit | /help to explore commands | esc to interrupt | ",
|
|
236
311
|
isReadOnly ? "Read-only mode (message passthrough)" : "Editable mode"
|
|
237
312
|
] }) })
|
|
238
313
|
] });
|
|
@@ -243,7 +318,7 @@ import { Box as Box6, Text as Text6 } from "ink";
|
|
|
243
318
|
|
|
244
319
|
// src/app/ui/InteractiveMenu.tsx
|
|
245
320
|
import { useState as useState2, memo } from "react";
|
|
246
|
-
import { Box as Box3, Text as Text3, useInput as
|
|
321
|
+
import { Box as Box3, Text as Text3, useInput as useInput3 } from "ink";
|
|
247
322
|
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
248
323
|
var InteractiveMenuComponent = ({ onDecision }) => {
|
|
249
324
|
const options = [
|
|
@@ -252,7 +327,7 @@ var InteractiveMenuComponent = ({ onDecision }) => {
|
|
|
252
327
|
{ label: "3. Always allow this type of command", value: "accept_always" }
|
|
253
328
|
];
|
|
254
329
|
const [selectedOption, setSelectedOption] = useState2(0);
|
|
255
|
-
|
|
330
|
+
useInput3((input, key) => {
|
|
256
331
|
if (key.upArrow) {
|
|
257
332
|
setSelectedOption((prev) => prev > 0 ? prev - 1 : options.length - 1);
|
|
258
333
|
}
|
|
@@ -1581,7 +1656,7 @@ var MCPClient = class {
|
|
|
1581
1656
|
try {
|
|
1582
1657
|
this.eventBus.emit("backend_message", {
|
|
1583
1658
|
type: "connection_status",
|
|
1584
|
-
message:
|
|
1659
|
+
message: `${serverName} server is being connected...`
|
|
1585
1660
|
});
|
|
1586
1661
|
if (serverConf.type === "stdio") {
|
|
1587
1662
|
await this.connectToStdioServer(serverName, serverConf);
|
|
@@ -1673,6 +1748,19 @@ var MCPClient = class {
|
|
|
1673
1748
|
getAvailableTools() {
|
|
1674
1749
|
return this.globalToolsForLlm;
|
|
1675
1750
|
}
|
|
1751
|
+
// New: detailed list for UI with origin metadata
|
|
1752
|
+
getAvailableToolsDetailed() {
|
|
1753
|
+
const detailed = [];
|
|
1754
|
+
for (const tool of this.globalToolsForLlm) {
|
|
1755
|
+
const name = tool.function?.name;
|
|
1756
|
+
if (!name) continue;
|
|
1757
|
+
const route = this.toolToServerMap.get(name);
|
|
1758
|
+
if (!route) continue;
|
|
1759
|
+
const source = route.server === "native" ? "native" : "mcp";
|
|
1760
|
+
detailed.push({ ...tool, source, server: route.server, originalName: route.originalName });
|
|
1761
|
+
}
|
|
1762
|
+
return detailed;
|
|
1763
|
+
}
|
|
1676
1764
|
async close() {
|
|
1677
1765
|
for (const [name, session] of this.sessions.entries()) {
|
|
1678
1766
|
try {
|
|
@@ -1891,6 +1979,10 @@ var Agent = class {
|
|
|
1891
1979
|
getAvailableTools() {
|
|
1892
1980
|
return this.mcpClient.getAvailableTools();
|
|
1893
1981
|
}
|
|
1982
|
+
// UI helper: detailed tools with origin metadata
|
|
1983
|
+
getUiToolsDetailed() {
|
|
1984
|
+
return this.mcpClient.getAvailableToolsDetailed();
|
|
1985
|
+
}
|
|
1894
1986
|
async processTurn(userInput) {
|
|
1895
1987
|
this.isInterrupted = false;
|
|
1896
1988
|
this.history.push({ role: "user", content: userInput.content });
|
|
@@ -2077,7 +2169,7 @@ var WorkingTimer = () => {
|
|
|
2077
2169
|
return () => clearInterval(dotsTimer);
|
|
2078
2170
|
}, []);
|
|
2079
2171
|
const dots = ".".repeat(dotIndex).padEnd(3, " ");
|
|
2080
|
-
return /* @__PURE__ */ jsx7(Box7, { marginBottom:
|
|
2172
|
+
return /* @__PURE__ */ jsx7(Box7, { marginBottom: 0.5, paddingX: 1, children: /* @__PURE__ */ jsxs7(Text7, { color: "magenta", children: [
|
|
2081
2173
|
`working${dots}`,
|
|
2082
2174
|
` ${seconds}s`
|
|
2083
2175
|
] }) });
|
|
@@ -2306,8 +2398,191 @@ var ToolResultDisplayComponent = ({ toolName, result }) => {
|
|
|
2306
2398
|
};
|
|
2307
2399
|
var ToolResultDisplay = memo3(ToolResultDisplayComponent);
|
|
2308
2400
|
|
|
2309
|
-
// src/app/ui/
|
|
2401
|
+
// src/app/ui/SessionInfoConnectingMCP.tsx
|
|
2402
|
+
import { Box as Box11, Text as Text10 } from "ink";
|
|
2403
|
+
import Spinner from "ink-spinner";
|
|
2310
2404
|
import { jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
2405
|
+
var SessionInfoConnectingMCP = ({ sessionId: sessionId2, workdir, statusMessage }) => {
|
|
2406
|
+
return /* @__PURE__ */ jsxs9(
|
|
2407
|
+
Box11,
|
|
2408
|
+
{
|
|
2409
|
+
borderStyle: "round",
|
|
2410
|
+
borderColor: "gray",
|
|
2411
|
+
flexDirection: "column",
|
|
2412
|
+
marginBottom: 1,
|
|
2413
|
+
children: [
|
|
2414
|
+
/* @__PURE__ */ jsxs9(Text10, { children: [
|
|
2415
|
+
/* @__PURE__ */ jsx11(Text10, { bold: true, color: "white", children: "localhost" }),
|
|
2416
|
+
" ",
|
|
2417
|
+
/* @__PURE__ */ jsx11(Text10, { color: "gray", children: " session:" }),
|
|
2418
|
+
" ",
|
|
2419
|
+
/* @__PURE__ */ jsx11(Text10, { color: "magenta", children: sessionId2 })
|
|
2420
|
+
] }),
|
|
2421
|
+
/* @__PURE__ */ jsxs9(Text10, { children: [
|
|
2422
|
+
/* @__PURE__ */ jsx11(Text10, { color: "magenta", children: "\u21B3" }),
|
|
2423
|
+
" ",
|
|
2424
|
+
/* @__PURE__ */ jsxs9(Text10, { color: "gray", children: [
|
|
2425
|
+
"workdir: ",
|
|
2426
|
+
workdir
|
|
2427
|
+
] })
|
|
2428
|
+
] }),
|
|
2429
|
+
/* @__PURE__ */ jsxs9(Text10, { children: [
|
|
2430
|
+
/* @__PURE__ */ jsx11(Text10, { color: "magenta", children: "\u21B3" }),
|
|
2431
|
+
" ",
|
|
2432
|
+
/* @__PURE__ */ jsx11(Text10, { color: "gray", children: "MCP: " }),
|
|
2433
|
+
/* @__PURE__ */ jsxs9(Text10, { color: "yellow", children: [
|
|
2434
|
+
/* @__PURE__ */ jsx11(Spinner, { type: "dots" }),
|
|
2435
|
+
" connecting"
|
|
2436
|
+
] })
|
|
2437
|
+
] }),
|
|
2438
|
+
/* @__PURE__ */ jsxs9(Text10, { children: [
|
|
2439
|
+
/* @__PURE__ */ jsx11(Text10, { color: "magenta", children: "\u21B3" }),
|
|
2440
|
+
" ",
|
|
2441
|
+
/* @__PURE__ */ jsx11(Text10, { color: "gray", children: "status: " }),
|
|
2442
|
+
/* @__PURE__ */ jsx11(Text10, { color: "white", children: statusMessage || "Please wait while we establish connections." })
|
|
2443
|
+
] })
|
|
2444
|
+
]
|
|
2445
|
+
}
|
|
2446
|
+
);
|
|
2447
|
+
};
|
|
2448
|
+
var SessionInfoConnectingMCP_default = SessionInfoConnectingMCP;
|
|
2449
|
+
|
|
2450
|
+
// src/app/ui/components/SlashCommands.tsx
|
|
2451
|
+
import { Box as Box12, Text as Text11 } from "ink";
|
|
2452
|
+
import { Fragment, jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
2453
|
+
var SlashCommands = ({ input, setHistory, agentRef }) => {
|
|
2454
|
+
const [cmd, ...args] = input.slice(1).trim().split(/\s+/);
|
|
2455
|
+
const outBox = (children) => /* @__PURE__ */ jsx12(Box12, { borderStyle: "round", borderColor: "gray", paddingX: 1, marginBottom: 1, flexDirection: "column", children });
|
|
2456
|
+
const render2 = () => {
|
|
2457
|
+
if (!cmd) {
|
|
2458
|
+
return null;
|
|
2459
|
+
}
|
|
2460
|
+
if (cmd === "help") {
|
|
2461
|
+
const cmds = getSlashCommands();
|
|
2462
|
+
return outBox(
|
|
2463
|
+
/* @__PURE__ */ jsxs10(Fragment, { children: [
|
|
2464
|
+
/* @__PURE__ */ jsx12(Text11, { color: "cyan", bold: true, children: "Available commands" }),
|
|
2465
|
+
cmds.map((c, i) => /* @__PURE__ */ jsxs10(Text11, { color: "gray", children: [
|
|
2466
|
+
c.name,
|
|
2467
|
+
" - ",
|
|
2468
|
+
c.description
|
|
2469
|
+
] }, i))
|
|
2470
|
+
] })
|
|
2471
|
+
);
|
|
2472
|
+
}
|
|
2473
|
+
if (cmd === "clear") {
|
|
2474
|
+
setHistory((prev) => prev.filter((item) => item.id === 0 || item.id === 1));
|
|
2475
|
+
return outBox(/* @__PURE__ */ jsx12(Text11, { color: "green", children: "History cleared." }));
|
|
2476
|
+
}
|
|
2477
|
+
if (cmd === "mcp") {
|
|
2478
|
+
const all = agentRef.current?.getUiToolsDetailed?.() || agentRef.current?.getAvailableTools?.() || [];
|
|
2479
|
+
const isMcp = (t) => t.source?.toLowerCase?.() === "mcp" || !!t.server && t.server !== "native";
|
|
2480
|
+
const tools = all.filter(isMcp);
|
|
2481
|
+
const term = (args?.[0] || "").toLowerCase();
|
|
2482
|
+
const filtered = term ? tools.filter((t) => (t.function?.name || t.name || "tool").toLowerCase().includes(term)) : tools;
|
|
2483
|
+
const pad = (s, n) => s.length >= n ? s.slice(0, n - 1) + "\u2026" : s.padEnd(n, " ");
|
|
2484
|
+
const colName = 34;
|
|
2485
|
+
const colType = 10;
|
|
2486
|
+
const colSource = 18;
|
|
2487
|
+
return outBox(
|
|
2488
|
+
/* @__PURE__ */ jsxs10(Fragment, { children: [
|
|
2489
|
+
/* @__PURE__ */ jsx12(Text11, { color: "cyan", bold: true, children: "MCP Tools" }),
|
|
2490
|
+
/* @__PURE__ */ jsxs10(Text11, { color: "gray", children: [
|
|
2491
|
+
"Total MCP: ",
|
|
2492
|
+
tools.length,
|
|
2493
|
+
term ? ` | Filter: "${term}" | Showing: ${filtered.length}` : ""
|
|
2494
|
+
] }),
|
|
2495
|
+
filtered.length === 0 ? /* @__PURE__ */ jsx12(Text11, { color: "yellow", children: "No MCP tools to display." }) : /* @__PURE__ */ jsxs10(Box12, { flexDirection: "column", children: [
|
|
2496
|
+
/* @__PURE__ */ jsxs10(Text11, { color: "gray", children: [
|
|
2497
|
+
pad("Name", colName),
|
|
2498
|
+
" | ",
|
|
2499
|
+
pad("Type", colType),
|
|
2500
|
+
" | ",
|
|
2501
|
+
pad("Source", colSource)
|
|
2502
|
+
] }),
|
|
2503
|
+
/* @__PURE__ */ jsxs10(Text11, { color: "gray", children: [
|
|
2504
|
+
"".padEnd(colName, "-"),
|
|
2505
|
+
"---",
|
|
2506
|
+
"".padEnd(colType, "-"),
|
|
2507
|
+
"---",
|
|
2508
|
+
"".padEnd(colSource, "-")
|
|
2509
|
+
] }),
|
|
2510
|
+
filtered.map((t, i) => {
|
|
2511
|
+
const name = t.function?.name || t.name || "tool";
|
|
2512
|
+
const type = t.function?.name ? "fn" : t.type || "tool";
|
|
2513
|
+
const source = t.source || t.provider || "mcp";
|
|
2514
|
+
return /* @__PURE__ */ jsxs10(Text11, { color: "white", children: [
|
|
2515
|
+
pad(name, colName),
|
|
2516
|
+
" | ",
|
|
2517
|
+
pad(String(type), colType),
|
|
2518
|
+
" | ",
|
|
2519
|
+
pad(String(source), colSource)
|
|
2520
|
+
] }, i);
|
|
2521
|
+
})
|
|
2522
|
+
] })
|
|
2523
|
+
] })
|
|
2524
|
+
);
|
|
2525
|
+
}
|
|
2526
|
+
if (cmd === "tools") {
|
|
2527
|
+
const all = agentRef.current?.getUiToolsDetailed?.() || agentRef.current?.getAvailableTools?.() || [];
|
|
2528
|
+
const isMcp = (t) => t.source?.toLowerCase?.() === "mcp" || !!t.server && t.server !== "native";
|
|
2529
|
+
const tools = all.filter((t) => !isMcp(t));
|
|
2530
|
+
const term = (args?.[0] || "").toLowerCase();
|
|
2531
|
+
const filtered = term ? tools.filter((t) => (t.function?.name || t.name || "tool").toLowerCase().includes(term)) : tools;
|
|
2532
|
+
const pad = (s, n) => s.length >= n ? s.slice(0, n - 1) + "\u2026" : s.padEnd(n, " ");
|
|
2533
|
+
const colName = 34;
|
|
2534
|
+
const colType = 10;
|
|
2535
|
+
const colSource = 18;
|
|
2536
|
+
return outBox(
|
|
2537
|
+
/* @__PURE__ */ jsxs10(Fragment, { children: [
|
|
2538
|
+
/* @__PURE__ */ jsx12(Text11, { color: "cyan", bold: true, children: "Native Tools" }),
|
|
2539
|
+
/* @__PURE__ */ jsxs10(Text11, { color: "gray", children: [
|
|
2540
|
+
"Total Native: ",
|
|
2541
|
+
tools.length,
|
|
2542
|
+
term ? ` | Filter: "${term}" | Showing: ${filtered.length}` : ""
|
|
2543
|
+
] }),
|
|
2544
|
+
filtered.length === 0 ? /* @__PURE__ */ jsx12(Text11, { color: "yellow", children: "No native tools to display." }) : /* @__PURE__ */ jsxs10(Box12, { flexDirection: "column", children: [
|
|
2545
|
+
/* @__PURE__ */ jsxs10(Text11, { color: "gray", children: [
|
|
2546
|
+
pad("Name", colName),
|
|
2547
|
+
" | ",
|
|
2548
|
+
pad("Type", colType),
|
|
2549
|
+
" | ",
|
|
2550
|
+
pad("Source", colSource)
|
|
2551
|
+
] }),
|
|
2552
|
+
/* @__PURE__ */ jsxs10(Text11, { color: "gray", children: [
|
|
2553
|
+
"".padEnd(colName, "-"),
|
|
2554
|
+
"---",
|
|
2555
|
+
"".padEnd(colType, "-"),
|
|
2556
|
+
"---",
|
|
2557
|
+
"".padEnd(colSource, "-")
|
|
2558
|
+
] }),
|
|
2559
|
+
filtered.map((t, i) => {
|
|
2560
|
+
const name = t.function?.name || t.name || "tool";
|
|
2561
|
+
const type = t.function?.name ? "fn" : t.type || "tool";
|
|
2562
|
+
const source = t.source || "native";
|
|
2563
|
+
return /* @__PURE__ */ jsxs10(Text11, { color: "white", children: [
|
|
2564
|
+
pad(name, colName),
|
|
2565
|
+
" | ",
|
|
2566
|
+
pad(String(type), colType),
|
|
2567
|
+
" | ",
|
|
2568
|
+
pad(String(source), colSource)
|
|
2569
|
+
] }, i);
|
|
2570
|
+
})
|
|
2571
|
+
] })
|
|
2572
|
+
] })
|
|
2573
|
+
);
|
|
2574
|
+
}
|
|
2575
|
+
return outBox(/* @__PURE__ */ jsxs10(Text11, { color: "red", children: [
|
|
2576
|
+
"Command not recognized: /",
|
|
2577
|
+
cmd
|
|
2578
|
+
] }));
|
|
2579
|
+
};
|
|
2580
|
+
return /* @__PURE__ */ jsx12(Fragment, { children: render2() });
|
|
2581
|
+
};
|
|
2582
|
+
var SlashCommands_default = SlashCommands;
|
|
2583
|
+
|
|
2584
|
+
// src/app/ui/App.tsx
|
|
2585
|
+
import { jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
2311
2586
|
var AppComponent = ({ eventBus: eventBus2, sessionId: sessionId2 }) => {
|
|
2312
2587
|
const agentInstance = useRef(null);
|
|
2313
2588
|
const [history, setHistory] = useState4([]);
|
|
@@ -2322,7 +2597,9 @@ var AppComponent = ({ eventBus: eventBus2, sessionId: sessionId2 }) => {
|
|
|
2322
2597
|
const [pendingConfirmation, setPendingConfirmation] = useState4(
|
|
2323
2598
|
null
|
|
2324
2599
|
);
|
|
2325
|
-
const [confirmationPreview, setConfirmationPreview] = useState4(
|
|
2600
|
+
const [confirmationPreview, setConfirmationPreview] = useState4(
|
|
2601
|
+
null
|
|
2602
|
+
);
|
|
2326
2603
|
const alwaysAcceptList = useRef([]);
|
|
2327
2604
|
const workdir = process.cwd();
|
|
2328
2605
|
const handleInterrupt = useCallback(() => {
|
|
@@ -2333,13 +2610,33 @@ var AppComponent = ({ eventBus: eventBus2, sessionId: sessionId2 }) => {
|
|
|
2333
2610
|
...prev,
|
|
2334
2611
|
{
|
|
2335
2612
|
id: prev.length,
|
|
2336
|
-
component: /* @__PURE__ */
|
|
2613
|
+
component: /* @__PURE__ */ jsx13(Text12, { color: "yellow", children: "-- Task cancelled by dev. --" })
|
|
2337
2614
|
}
|
|
2338
2615
|
]);
|
|
2339
2616
|
}, [isProcessing, eventBus2]);
|
|
2340
2617
|
const handleSubmit = useCallback(
|
|
2341
2618
|
(text) => {
|
|
2342
2619
|
if (!text || isProcessing || !agentInstance.current) return;
|
|
2620
|
+
if (text.startsWith("/")) {
|
|
2621
|
+
const [cmd] = text.slice(1).trim().split(/\s+/);
|
|
2622
|
+
if (!cmd) {
|
|
2623
|
+
setIsProcessing(false);
|
|
2624
|
+
return;
|
|
2625
|
+
}
|
|
2626
|
+
setHistory((prev) => [
|
|
2627
|
+
...prev,
|
|
2628
|
+
{
|
|
2629
|
+
id: prev.length,
|
|
2630
|
+
component: /* @__PURE__ */ jsx13(Box13, { marginBottom: 1, children: /* @__PURE__ */ jsx13(Text12, { color: "white", dimColor: true, children: text }) })
|
|
2631
|
+
},
|
|
2632
|
+
{
|
|
2633
|
+
id: prev.length + 1,
|
|
2634
|
+
component: /* @__PURE__ */ jsx13(SlashCommands_default, { input: text, setHistory, agentRef: agentInstance })
|
|
2635
|
+
}
|
|
2636
|
+
]);
|
|
2637
|
+
setIsProcessing(false);
|
|
2638
|
+
return;
|
|
2639
|
+
}
|
|
2343
2640
|
setIsProcessing(true);
|
|
2344
2641
|
const displayText = text.length > 1e4 ? text.substring(0, 1e4) + "..." : text;
|
|
2345
2642
|
setHistory((prev) => [
|
|
@@ -2348,8 +2645,8 @@ var AppComponent = ({ eventBus: eventBus2, sessionId: sessionId2 }) => {
|
|
|
2348
2645
|
id: prev.length,
|
|
2349
2646
|
component: (
|
|
2350
2647
|
// Uma única Box para o espaçamento
|
|
2351
|
-
/* @__PURE__ */
|
|
2352
|
-
/* @__PURE__ */
|
|
2648
|
+
/* @__PURE__ */ jsx13(Box13, { marginBottom: 1, children: /* @__PURE__ */ jsxs11(Text12, { color: "white", dimColor: true, children: [
|
|
2649
|
+
/* @__PURE__ */ jsxs11(Text12, { color: "white", children: [
|
|
2353
2650
|
">",
|
|
2354
2651
|
" "
|
|
2355
2652
|
] }),
|
|
@@ -2384,7 +2681,7 @@ var AppComponent = ({ eventBus: eventBus2, sessionId: sessionId2 }) => {
|
|
|
2384
2681
|
[]
|
|
2385
2682
|
);
|
|
2386
2683
|
useEffect3(() => {
|
|
2387
|
-
setHistory([{ id: 0, component: /* @__PURE__ */
|
|
2684
|
+
setHistory([{ id: 0, component: /* @__PURE__ */ jsx13(Header, {}) }]);
|
|
2388
2685
|
const initializeAgent = async () => {
|
|
2389
2686
|
try {
|
|
2390
2687
|
agentInstance.current = new Agent(sessionId2, eventBus2);
|
|
@@ -2436,7 +2733,7 @@ var AppComponent = ({ eventBus: eventBus2, sessionId: sessionId2 }) => {
|
|
|
2436
2733
|
if (prev.length < 2) {
|
|
2437
2734
|
newHistory.push({
|
|
2438
2735
|
id: 1,
|
|
2439
|
-
component: /* @__PURE__ */
|
|
2736
|
+
component: /* @__PURE__ */ jsx13(
|
|
2440
2737
|
SessionInfo,
|
|
2441
2738
|
{
|
|
2442
2739
|
sessionId: sessionId2,
|
|
@@ -2457,10 +2754,10 @@ var AppComponent = ({ eventBus: eventBus2, sessionId: sessionId2 }) => {
|
|
|
2457
2754
|
}
|
|
2458
2755
|
let newComponent = null;
|
|
2459
2756
|
if (parsed.type === "debug") {
|
|
2460
|
-
newComponent = /* @__PURE__ */
|
|
2757
|
+
newComponent = /* @__PURE__ */ jsx13(Text12, { color: "gray", children: parsed.message });
|
|
2461
2758
|
} else if (parsed.type === "protocol_violation") {
|
|
2462
|
-
newComponent = /* @__PURE__ */
|
|
2463
|
-
|
|
2759
|
+
newComponent = /* @__PURE__ */ jsxs11(
|
|
2760
|
+
Box13,
|
|
2464
2761
|
{
|
|
2465
2762
|
borderStyle: "round",
|
|
2466
2763
|
borderColor: "yellow",
|
|
@@ -2468,19 +2765,19 @@ var AppComponent = ({ eventBus: eventBus2, sessionId: sessionId2 }) => {
|
|
|
2468
2765
|
marginBottom: 1,
|
|
2469
2766
|
paddingX: 1,
|
|
2470
2767
|
children: [
|
|
2471
|
-
/* @__PURE__ */
|
|
2472
|
-
/* @__PURE__ */
|
|
2473
|
-
/* @__PURE__ */
|
|
2768
|
+
/* @__PURE__ */ jsx13(Text12, { color: "yellow", bold: true, children: "Protocol Violation" }),
|
|
2769
|
+
/* @__PURE__ */ jsx13(Text12, { color: "gray", children: parsed.content }),
|
|
2770
|
+
/* @__PURE__ */ jsx13(Text12, { color: "yellow", children: parsed.message })
|
|
2474
2771
|
]
|
|
2475
2772
|
}
|
|
2476
2773
|
);
|
|
2477
2774
|
} else if (parsed.type === "error") {
|
|
2478
|
-
newComponent = /* @__PURE__ */
|
|
2775
|
+
newComponent = /* @__PURE__ */ jsxs11(Text12, { color: "red", children: [
|
|
2479
2776
|
"\u274C ",
|
|
2480
2777
|
parsed.message
|
|
2481
2778
|
] });
|
|
2482
2779
|
} else if (parsed.type === "tool_call") {
|
|
2483
|
-
newComponent = /* @__PURE__ */
|
|
2780
|
+
newComponent = /* @__PURE__ */ jsx13(
|
|
2484
2781
|
ToolCallDisplay,
|
|
2485
2782
|
{
|
|
2486
2783
|
toolName: parsed.tool_name,
|
|
@@ -2489,7 +2786,7 @@ var AppComponent = ({ eventBus: eventBus2, sessionId: sessionId2 }) => {
|
|
|
2489
2786
|
}
|
|
2490
2787
|
);
|
|
2491
2788
|
} else if (parsed.type === "tool_result") {
|
|
2492
|
-
newComponent = /* @__PURE__ */
|
|
2789
|
+
newComponent = /* @__PURE__ */ jsx13(
|
|
2493
2790
|
ToolResultDisplay,
|
|
2494
2791
|
{
|
|
2495
2792
|
toolName: parsed.tool_name,
|
|
@@ -2497,9 +2794,15 @@ var AppComponent = ({ eventBus: eventBus2, sessionId: sessionId2 }) => {
|
|
|
2497
2794
|
}
|
|
2498
2795
|
);
|
|
2499
2796
|
} else if (parsed.type === "dev_overlay") {
|
|
2500
|
-
newComponent = /* @__PURE__ */
|
|
2797
|
+
newComponent = /* @__PURE__ */ jsx13(Box13, { marginBottom: 1, children: /* @__PURE__ */ jsxs11(Text12, { color: "gray", children: [
|
|
2798
|
+
/* @__PURE__ */ jsxs11(Text12, { color: "blue", children: [
|
|
2799
|
+
">",
|
|
2800
|
+
" "
|
|
2801
|
+
] }),
|
|
2802
|
+
parsed.payload
|
|
2803
|
+
] }) });
|
|
2501
2804
|
} else if (parsed.type === "log") {
|
|
2502
|
-
newComponent = /* @__PURE__ */
|
|
2805
|
+
newComponent = /* @__PURE__ */ jsxs11(Text12, { color: "gray", children: [
|
|
2503
2806
|
"\u2139\uFE0F ",
|
|
2504
2807
|
parsed.message,
|
|
2505
2808
|
parsed.payload ? `: ${parsed.payload}` : ""
|
|
@@ -2529,14 +2832,24 @@ var AppComponent = ({ eventBus: eventBus2, sessionId: sessionId2 }) => {
|
|
|
2529
2832
|
}, [eventBus2, sessionId2, handleConfirmation]);
|
|
2530
2833
|
const renderInteractiveComponent = () => {
|
|
2531
2834
|
if (mcpStatus !== "connected") {
|
|
2532
|
-
return /* @__PURE__ */
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
|
|
2835
|
+
return /* @__PURE__ */ jsx13(
|
|
2836
|
+
Box13,
|
|
2837
|
+
{
|
|
2838
|
+
borderStyle: "round",
|
|
2839
|
+
borderColor: "black",
|
|
2840
|
+
children: /* @__PURE__ */ jsx13(
|
|
2841
|
+
SessionInfoConnectingMCP_default,
|
|
2842
|
+
{
|
|
2843
|
+
sessionId: sessionId2,
|
|
2844
|
+
workdir,
|
|
2845
|
+
statusMessage
|
|
2846
|
+
}
|
|
2847
|
+
)
|
|
2848
|
+
}
|
|
2849
|
+
);
|
|
2537
2850
|
}
|
|
2538
2851
|
if (pendingConfirmation) {
|
|
2539
|
-
return /* @__PURE__ */
|
|
2852
|
+
return /* @__PURE__ */ jsx13(
|
|
2540
2853
|
ConfirmationPrompt,
|
|
2541
2854
|
{
|
|
2542
2855
|
toolCalls: pendingConfirmation,
|
|
@@ -2548,9 +2861,9 @@ var AppComponent = ({ eventBus: eventBus2, sessionId: sessionId2 }) => {
|
|
|
2548
2861
|
}
|
|
2549
2862
|
);
|
|
2550
2863
|
}
|
|
2551
|
-
return /* @__PURE__ */
|
|
2552
|
-
isProcessing && !pendingConfirmation && /* @__PURE__ */
|
|
2553
|
-
/* @__PURE__ */
|
|
2864
|
+
return /* @__PURE__ */ jsxs11(Box13, { flexDirection: "column", children: [
|
|
2865
|
+
isProcessing && !pendingConfirmation && /* @__PURE__ */ jsx13(WorkingTimer, {}),
|
|
2866
|
+
/* @__PURE__ */ jsx13(
|
|
2554
2867
|
InputPrompt,
|
|
2555
2868
|
{
|
|
2556
2869
|
onSubmit: handleSubmit,
|
|
@@ -2560,8 +2873,8 @@ var AppComponent = ({ eventBus: eventBus2, sessionId: sessionId2 }) => {
|
|
|
2560
2873
|
)
|
|
2561
2874
|
] });
|
|
2562
2875
|
};
|
|
2563
|
-
return /* @__PURE__ */
|
|
2564
|
-
/* @__PURE__ */
|
|
2876
|
+
return /* @__PURE__ */ jsxs11(Box13, { flexDirection: "column", children: [
|
|
2877
|
+
/* @__PURE__ */ jsx13(Static, { items: history, children: (item) => /* @__PURE__ */ jsx13(Box13, { children: item.component }, item.id) }),
|
|
2565
2878
|
renderInteractiveComponent()
|
|
2566
2879
|
] });
|
|
2567
2880
|
};
|