@nomad-e/bluma-cli 0.0.95 → 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.
Files changed (2) hide show
  1. package/dist/main.js +697 -588
  2. 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 useEffect4, useRef as useRef2, useCallback, memo as memo4 } from "react";
10
- import { Box as Box16, Text as Text15, Static } from "ink";
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 BigText from "ink-big-text";
15
- import { jsx, jsxs } from "react/jsx-runtime";
16
- var BRAND_COLORS = {
17
- main: "magenta",
18
- accent: "blue",
19
- shadow: "magenta",
20
- greydark: "#444"
21
- };
22
- var Header = () => {
23
- return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
24
- /* @__PURE__ */ jsx(Box, { flexDirection: "column", height: 8, marginBottom: 1, children: /* @__PURE__ */ jsx(
25
- BigText,
26
- {
27
- text: "BluMa CLI",
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(Text, { children: [
45
- "4. Type ",
46
- /* @__PURE__ */ jsx(Text, { color: "magenta", children: "/help" }),
47
- " to explore available commands and features."
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(/(||)/gm, "");
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) newCursorPosition--;
127
- if (action.direction === "right" && state.cursorPosition < state.text.length) newCursorPosition++;
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(/(||)/gm, "");
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.backspace || key.delete) return dispatch({ type: "BACKSPACE" });
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
- return dispatch({ type: "INPUT", payload: input });
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 || key.delete) return dispatch({ type: "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
- dispatch({ type: "INPUT", payload: input });
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) => dispatch({ type: "SET_CURSOR", payload: 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 useEffect2, useMemo, useState as useState2 } from "react";
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 = useRef("");
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
- useEffect(() => {
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 InputPrompt = ({ onSubmit, isReadOnly, onInterrupt, disableWhileProcessing = false }) => {
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, setViewWidth] = useState2(() => stdout.columns - 6);
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
- const payload = trimmed;
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, viewStart, setText } = useCustomInput({
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 visibleText = text.slice(viewStart, viewStart + viewWidth);
466
- const visibleCursorPosition = cursorPosition - viewStart;
467
- const textBeforeCursor = visibleText.slice(0, visibleCursorPosition);
468
- const charAtCursor = visibleText.slice(visibleCursorPosition, visibleCursorPosition + 1);
469
- const textAfterCursor = visibleText.slice(visibleCursorPosition + 1);
470
- const cursorGlyph = charAtCursor && charAtCursor.length > 0 ? charAtCursor : " ";
471
- const borderColor = isReadOnly ? "gray" : "gray";
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
- useEffect2(() => {
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(`${cmd} `);
707
+ setText(`${choice.name} `);
504
708
  } catch (e) {
505
- permissiveOnSubmit(`${cmd} `);
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
- useEffect2(() => {
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
- // Modo bloqueado visualmente, mantendo hooks estáveis
557
- /* @__PURE__ */ jsx2(Fragment, { children: /* @__PURE__ */ jsx2(Box2, { borderStyle: "round", borderColor: "gray", borderDimColor: true, children: /* @__PURE__ */ jsxs2(Box2, { flexDirection: "row", paddingX: 1, flexWrap: "nowrap", children: [
558
- /* @__PURE__ */ jsxs2(Text2, { color: "white", children: [
559
- ">",
560
- " "
561
- ] }),
562
- /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "ctrl+c to exit" })
563
- ] }) }) })
564
- ) : /* @__PURE__ */ jsxs2(Fragment, { children: [
565
- /* @__PURE__ */ jsx2(Box2, { borderStyle: "round", borderColor, borderDimColor: !isReadOnly, children: /* @__PURE__ */ jsxs2(Box2, { flexDirection: "row", paddingX: 1, flexWrap: "nowrap", children: [
566
- /* @__PURE__ */ jsxs2(Text2, { color: "white", children: [
567
- ">",
568
- " "
569
- ] }),
570
- /* @__PURE__ */ jsx2(Text2, { children: textBeforeCursor }),
571
- /* @__PURE__ */ jsx2(Text2, { inverse: true, children: cursorGlyph }),
572
- showPlaceholder ? /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: placeholder }) : /* @__PURE__ */ jsx2(Text2, { children: textAfterCursor })
573
- ] }) }),
574
- pathAutocomplete.open && pathAutocomplete.suggestions.length > 0 && (() => {
575
- const VISIBLE = 7;
576
- const total = pathAutocomplete.suggestions.length;
577
- const sel = Math.max(0, Math.min(pathAutocomplete.selected, total - 1));
578
- let start = Math.max(0, sel - Math.floor(VISIBLE / 2));
579
- if (start + VISIBLE > total) start = Math.max(0, total - VISIBLE);
580
- const windowItems = pathAutocomplete.suggestions.slice(start, start + VISIBLE);
581
- return /* @__PURE__ */ jsx2(Box2, { flexDirection: "column", marginTop: 1, height: Math.min(VISIBLE, total), children: windowItems.map((s, idx) => {
582
- const realIdx = start + idx;
583
- const isSelected = realIdx === pathAutocomplete.selected;
584
- return /* @__PURE__ */ jsxs2(Box2, { paddingLeft: 1, paddingY: 0, children: [
585
- /* @__PURE__ */ jsx2(Text2, { color: isSelected ? "magenta" : "gray", children: isSelected ? "\u276F " : " " }),
586
- /* @__PURE__ */ jsx2(Text2, { color: isSelected ? "magenta" : "white", bold: isSelected, dimColor: !isSelected, children: s.label })
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(Box2, { paddingX: 1, justifyContent: "center", children: /* @__PURE__ */ jsxs2(Text2, { color: "gray", dimColor: true, children: [
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
- { label: "1. Yes, allow this command to run once", value: "accept" },
622
- { label: "2. No, cancel this command", value: "decline" },
623
- { label: "3. Always allow this type of command", value: "accept_always" }
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: "Do you want to authorize the proposed command?" }) }),
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
- // Adicionando um pequeno espaçamento vertical entre cada opção também
646
- /* @__PURE__ */ jsxs3(Box3, { paddingLeft: 1, paddingY: 0, children: [
647
- /* @__PURE__ */ jsx3(Text3, { color: isSelected ? "magenta" : "gray", children: isSelected ? "\u276F " : " " }),
648
- /* @__PURE__ */ jsx3(
649
- Text3,
650
- {
651
- color: isSelected ? "magenta" : "white",
652
- bold: isSelected,
653
- dimColor: !isSelected,
654
- children: option.label
655
- }
656
- )
657
- ] }, option.value)
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 = memo(InteractiveMenuComponent);
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, { marginLeft: 2, children: /* @__PURE__ */ jsxs4(Text4, { dimColor: true, children: [
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 = "magenta";
894
+ color = "cyan";
895
+ prefix = "";
896
+ } else {
897
+ color = "gray";
898
+ prefix = " ";
696
899
  }
697
- return /* @__PURE__ */ jsx4(Text4, { color, children: line === "" ? " " : line }, index);
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 arguments";
919
+ command = "Error parsing command";
716
920
  }
717
- return /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", marginBottom: 1, children: [
718
- /* @__PURE__ */ jsx5(Box5, { children: /* @__PURE__ */ jsx5(Text5, { bold: true, children: "Shell Command" }) }),
719
- /* @__PURE__ */ jsx5(Box5, { paddingX: 2, children: /* @__PURE__ */ jsx5(Text5, { children: /* @__PURE__ */ jsx5(Text5, { color: "magenta", children: command }) }) })
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
- const finalDirectoryName = directoryPath;
731
- return /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", marginBottom: 1, children: [
732
- /* @__PURE__ */ jsx5(Box5, { children: /* @__PURE__ */ jsx5(Text5, { bold: true, children: "ls" }) }),
733
- /* @__PURE__ */ jsx5(Box5, { flexDirection: "column", children: /* @__PURE__ */ jsx5(Box5, { paddingX: 2, children: /* @__PURE__ */ jsx5(Text5, { children: /* @__PURE__ */ jsx5(Text5, { color: "magenta", dimColor: true, children: finalDirectoryName }) }) }) })
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 directoryPath = "[path not specified]";
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
- directoryPath = args.filepath || "[path not specified]";
949
+ filepath = args.filepath || "[path not specified]";
741
950
  } catch (e) {
742
- directoryPath = "Error parsing arguments";
951
+ filepath = "Error parsing arguments";
743
952
  }
744
- const finalDirectoryName = directoryPath;
745
- return /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", marginBottom: 1, children: [
746
- /* @__PURE__ */ jsx5(Box5, { children: /* @__PURE__ */ jsx5(Text5, { bold: true, children: "Count File Lines" }) }),
747
- /* @__PURE__ */ jsx5(Box5, { flexDirection: "column", children: /* @__PURE__ */ jsx5(Box5, { paddingX: 2, children: /* @__PURE__ */ jsxs5(Text5, { children: [
748
- /* @__PURE__ */ jsx5(Text5, { color: "gray", children: "\u21B3 " }),
749
- /* @__PURE__ */ jsx5(Text5, { color: "magenta", dimColor: true, children: finalDirectoryName })
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
- const finalFileName = filepath;
766
- return /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", marginBottom: 1, children: [
767
- /* @__PURE__ */ jsx5(Box5, { children: /* @__PURE__ */ jsx5(Text5, { bold: true, children: "Read File" }) }),
768
- /* @__PURE__ */ jsxs5(Box5, { paddingX: 2, flexDirection: "column", children: [
769
- /* @__PURE__ */ jsx5(Box5, { children: /* @__PURE__ */ jsx5(Text5, { children: /* @__PURE__ */ jsx5(Text5, { color: "magenta", children: finalFileName }) }) }),
770
- /* @__PURE__ */ jsx5(Box5, { paddingX: 3, children: /* @__PURE__ */ jsxs5(Text5, { children: [
771
- /* @__PURE__ */ jsx5(Text5, { color: "gray", children: "\u21B3 " }),
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__ */ jsx5(Box5, { children: /* @__PURE__ */ jsxs5(Text5, { bold: true, children: [
792
- "Edit ",
793
- /* @__PURE__ */ jsx5(Text5, { color: "magenta", children: finalFileName })
794
- ] }) }),
795
- preview ? (
796
- // Não precisamos da borda externa, o SimpleDiff é claro o suficiente.
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__ */ jsx5(Box5, { children: /* @__PURE__ */ jsx5(Text5, { bold: true, children: toolName }) }),
824
- formattedArgsString && /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", marginTop: 1, children: [
825
- /* @__PURE__ */ jsx5(Text5, { dimColor: true, children: "Arguments:" }),
826
- /* @__PURE__ */ jsx5(Box5, { marginLeft: 2, flexDirection: "column", children: visibleLines.map((line, idx) => /* @__PURE__ */ jsx5(Text5, { color: "gray", children: line }, idx)) }),
827
- isTruncated && /* @__PURE__ */ jsx5(Box5, { marginLeft: 2, children: /* @__PURE__ */ jsxs5(Text5, { dimColor: true, children: [
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 hidden)"
831
- ] }) })
1042
+ " more lines"
1043
+ ] })
832
1044
  ] })
833
1045
  ] });
834
1046
  };
@@ -2084,7 +2296,7 @@ var BluMaAgent = class {
2084
2296
  eventBus;
2085
2297
  mcpClient;
2086
2298
  feedbackSystem;
2087
- maxContextTurns = 30;
2299
+ maxContextTurns = 10;
2088
2300
  // Limite de turns no contexto da API
2089
2301
  todoListState = [];
2090
2302
  isInterrupted = false;
@@ -2219,9 +2431,7 @@ ${editData.error.display}`;
2219
2431
  temperature: 0,
2220
2432
  tools: this.mcpClient.getAvailableTools(),
2221
2433
  tool_choice: "required",
2222
- // reasoning: { effort: "high" },
2223
2434
  parallel_tool_calls: false
2224
- // max_tokens: 512, // Limite de tokens para evitar respostas muito longas
2225
2435
  });
2226
2436
  if (this.isInterrupted) {
2227
2437
  this.eventBus.emit("backend_message", { type: "info", message: "Agent task cancelled by user." });
@@ -2848,33 +3058,39 @@ var Agent = class {
2848
3058
  };
2849
3059
 
2850
3060
  // src/app/ui/WorkingTimer.tsx
2851
- import { useState as useState4, useEffect as useEffect3 } from "react";
3061
+ import { useState as useState4, useEffect as useEffect4 } from "react";
2852
3062
  import { Box as Box7, Text as Text7 } from "ink";
2853
3063
  import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
2854
3064
  var WorkingTimer = () => {
2855
3065
  const [seconds, setSeconds] = useState4(0);
2856
- const [dotIndex, setDotIndex] = useState4(1);
2857
- useEffect3(() => {
2858
- const secondsTimer = setInterval(() => {
3066
+ const [frame, setFrame] = useState4(0);
3067
+ useEffect4(() => {
3068
+ const timer = setInterval(() => {
2859
3069
  setSeconds((prev) => prev + 1);
2860
3070
  }, 1e3);
2861
- return () => clearInterval(secondsTimer);
3071
+ return () => clearInterval(timer);
2862
3072
  }, []);
2863
- useEffect3(() => {
2864
- const dotsTimer = setInterval(() => {
2865
- setDotIndex((prev) => prev % 3 + 1);
2866
- }, 100);
2867
- return () => clearInterval(dotsTimer);
3073
+ useEffect4(() => {
3074
+ const animator = setInterval(() => {
3075
+ setFrame((prev) => (prev + 1) % 10);
3076
+ }, 80);
3077
+ return () => clearInterval(animator);
2868
3078
  }, []);
2869
- const dots = ".".repeat(dotIndex).padEnd(3, " ");
2870
- return /* @__PURE__ */ jsx7(Box7, { marginBottom: 0.5, paddingX: 1, children: /* @__PURE__ */ jsxs7(Text7, { color: "magenta", children: [
2871
- `working${dots}`,
2872
- ` ${seconds}s`
2873
- ] }) });
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
+ ] });
2874
3090
  };
2875
3091
 
2876
3092
  // src/app/ui/components/ToolCallDisplay.tsx
2877
- import { memo as memo2 } from "react";
3093
+ import { memo as memo3 } from "react";
2878
3094
  import { Box as Box9 } from "ink";
2879
3095
 
2880
3096
  // src/app/ui/components/toolCallRenderers.tsx
@@ -2890,19 +3106,14 @@ var formatArgumentsForDisplay = (args) => {
2890
3106
  }
2891
3107
  return JSON.stringify(args, null, 2);
2892
3108
  };
2893
- var renderShellCommand2 = ({
2894
- args
2895
- }) => {
3109
+ var renderShellCommand2 = ({ args }) => {
2896
3110
  const command = args.command || "[command not found]";
2897
- return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
2898
- /* @__PURE__ */ jsx8(Box8, { children: /* @__PURE__ */ jsxs8(Text8, { bold: true, children: [
2899
- /* @__PURE__ */ jsx8(Text8, { color: "green", children: "\u25CF " }),
2900
- "Shell Command"
2901
- ] }) }),
2902
- /* @__PURE__ */ jsx8(Box8, { marginLeft: 2, paddingX: 1, children: /* @__PURE__ */ jsxs8(Text8, { children: [
2903
- /* @__PURE__ */ jsx8(Text8, { color: "gray", children: "\u21B3 " }),
2904
- /* @__PURE__ */ jsx8(Text8, { color: "magenta", children: command })
2905
- ] }) })
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 }) })
2906
3117
  ] });
2907
3118
  };
2908
3119
  var renderLsTool2 = ({ args }) => {
@@ -2913,43 +3124,31 @@ var renderLsTool2 = ({ args }) => {
2913
3124
  } catch (e) {
2914
3125
  directoryPath = "Error parsing arguments";
2915
3126
  }
2916
- const finalDirectoryName = directoryPath;
2917
- return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
2918
- /* @__PURE__ */ jsx8(Box8, { children: /* @__PURE__ */ jsxs8(Text8, { bold: true, children: [
2919
- /* @__PURE__ */ jsx8(Text8, { color: "green", children: "\u25CF " }),
2920
- "ls"
2921
- ] }) }),
2922
- /* @__PURE__ */ jsx8(Box8, { marginLeft: 2, paddingX: 1, children: /* @__PURE__ */ jsxs8(Text8, { children: [
2923
- /* @__PURE__ */ jsx8(Text8, { color: "gray", children: "\u21B3 " }),
2924
- /* @__PURE__ */ jsx8(Text8, { color: "magenta", children: finalDirectoryName })
2925
- ] }) })
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 }) })
2926
3133
  ] });
2927
3134
  };
2928
- var renderCountFilesLines = ({
2929
- args
2930
- }) => {
2931
- let directoryPath = "[path not found]";
3135
+ var renderCountFilesLines = ({ args }) => {
3136
+ let filepath = "[path not found]";
2932
3137
  try {
2933
3138
  const parsedArgs = typeof args === "string" ? JSON.parse(args) : args;
2934
- directoryPath = parsedArgs.filepath || "[path not specified]";
3139
+ filepath = parsedArgs.filepath || "[path not specified]";
2935
3140
  } catch (e) {
2936
- directoryPath = "Error parsing arguments";
3141
+ filepath = "Error parsing arguments";
2937
3142
  }
2938
- const finalDirectoryName = directoryPath;
2939
- return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
2940
- /* @__PURE__ */ jsx8(Box8, { children: /* @__PURE__ */ jsxs8(Text8, { bold: true, children: [
2941
- /* @__PURE__ */ jsx8(Text8, { color: "green", children: "\u25CF " }),
2942
- "Count File Lines"
2943
- ] }) }),
2944
- /* @__PURE__ */ jsx8(Box8, { marginLeft: 2, paddingX: 1, children: /* @__PURE__ */ jsxs8(Text8, { children: [
2945
- /* @__PURE__ */ jsx8(Text8, { color: "gray", children: "\u21B3 " }),
2946
- /* @__PURE__ */ jsx8(Text8, { color: "magenta", children: finalDirectoryName })
2947
- ] }) })
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 }) })
2948
3149
  ] });
2949
3150
  };
2950
- var renderReadFileLines2 = ({
2951
- args
2952
- }) => {
3151
+ var renderReadFileLines2 = ({ args }) => {
2953
3152
  let filepath = "[path not found]";
2954
3153
  let startLine = 0;
2955
3154
  let endLine = 0;
@@ -2961,33 +3160,23 @@ var renderReadFileLines2 = ({
2961
3160
  } catch (e) {
2962
3161
  filepath = "Error parsing arguments";
2963
3162
  }
2964
- const finalFileName = filepath;
2965
- return (
2966
- // A caixa externa com a borda, seguindo o template
2967
- /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
2968
- /* @__PURE__ */ jsx8(Box8, { children: /* @__PURE__ */ jsxs8(Text8, { bold: true, children: [
2969
- /* @__PURE__ */ jsx8(Text8, { color: "green", children: "\u25CF " }),
2970
- "Read File"
2971
- ] }) }),
2972
- /* @__PURE__ */ jsxs8(Box8, { marginLeft: 2, flexDirection: "column", children: [
2973
- /* @__PURE__ */ jsx8(Box8, { marginLeft: 2, paddingX: 1, children: /* @__PURE__ */ jsxs8(Text8, { children: [
2974
- /* @__PURE__ */ jsx8(Text8, { color: "gray", children: "\u21B3 " }),
2975
- /* @__PURE__ */ jsx8(Text8, { color: "magenta", children: finalFileName })
2976
- ] }) }),
2977
- /* @__PURE__ */ jsx8(Box8, { marginLeft: 2, paddingX: 4, children: /* @__PURE__ */ jsxs8(Text8, { children: [
2978
- /* @__PURE__ */ jsx8(Text8, { color: "gray", children: "\u21B3 " }),
2979
- /* @__PURE__ */ jsx8(Text8, { dimColor: true, children: "lines " }),
2980
- /* @__PURE__ */ jsx8(Text8, { color: "magenta", children: startLine }),
2981
- /* @__PURE__ */ jsx8(Text8, { dimColor: true, children: " to " }),
2982
- /* @__PURE__ */ jsx8(Text8, { color: "magenta", children: endLine })
2983
- ] }) })
2984
- ] })
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
+ ] }) })
2985
3176
  ] })
2986
- );
3177
+ ] });
2987
3178
  };
2988
- var renderBlumaNotebook = ({
2989
- args
2990
- }) => {
3179
+ var renderBlumaNotebook = ({ args }) => {
2991
3180
  try {
2992
3181
  let dataToParse = args;
2993
3182
  if (args && typeof args === "object") {
@@ -2996,33 +3185,17 @@ var renderBlumaNotebook = ({
2996
3185
  }
2997
3186
  const thinkingData = typeof dataToParse === "string" ? JSON.parse(dataToParse) : dataToParse;
2998
3187
  if (!thinkingData || typeof thinkingData.thought !== "string") {
2999
- throw new Error("Invalid or missing 'thought' property.");
3188
+ throw new Error("Invalid thought data");
3000
3189
  }
3001
- return (
3002
- // Usamos a mesma estrutura de caixa com borda
3003
- /* @__PURE__ */ jsx8(
3004
- Box8,
3005
- {
3006
- flexDirection: "column",
3007
- paddingX: 1,
3008
- children: /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
3009
- /* @__PURE__ */ jsx8(Text8, { color: "white", bold: true, children: "Reasoning:" }),
3010
- /* @__PURE__ */ jsx8(Box8, { marginLeft: 2, children: /* @__PURE__ */ jsx8(Text8, { color: "gray", children: thinkingData.thought }) })
3011
- ] })
3012
- }
3013
- )
3014
- );
3015
- } catch (e) {
3016
- return /* @__PURE__ */ jsxs8(Box8, { borderStyle: "round", borderColor: "magenta", paddingX: 1, children: [
3017
- /* @__PURE__ */ jsx8(Text8, { color: "magenta", bold: true, children: "Thinking (Error)" }),
3018
- /* @__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 }) })
3019
3193
  ] });
3194
+ } catch (e) {
3195
+ return /* @__PURE__ */ jsx8(Box8, { paddingX: 1, children: /* @__PURE__ */ jsx8(Text8, { color: "red", children: "Error parsing reasoning" }) });
3020
3196
  }
3021
3197
  };
3022
- var renderEditToolCall = ({
3023
- args,
3024
- preview
3025
- }) => {
3198
+ var renderEditToolCall = ({ args, preview }) => {
3026
3199
  let filepath = "[path not specified]";
3027
3200
  try {
3028
3201
  const parsedArgs = typeof args === "string" ? JSON.parse(args) : args;
@@ -3030,16 +3203,12 @@ var renderEditToolCall = ({
3030
3203
  } catch (e) {
3031
3204
  filepath = "Error parsing arguments";
3032
3205
  }
3033
- const finalFileName = filepath;
3034
3206
  return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", paddingX: 1, children: [
3035
- /* @__PURE__ */ jsx8(Box8, { children: /* @__PURE__ */ jsxs8(Text8, { bold: true, children: [
3036
- /* @__PURE__ */ jsx8(Text8, { color: "green", children: "\u25CF " }),
3037
- "Edit File"
3038
- ] }) }),
3039
- /* @__PURE__ */ jsx8(Box8, { marginLeft: 2, paddingX: 1, children: /* @__PURE__ */ jsxs8(Text8, { children: [
3040
- /* @__PURE__ */ jsx8(Text8, { color: "gray", children: "\u21B3 " }),
3041
- /* @__PURE__ */ jsx8(Text8, { color: "magenta", children: finalFileName })
3042
- ] }) }),
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
+ ] }),
3043
3212
  preview && /* @__PURE__ */ jsx8(Box8, { marginTop: 1, children: /* @__PURE__ */ jsx8(SimpleDiff, { text: preview, maxHeight: Infinity }) })
3044
3213
  ] });
3045
3214
  };
@@ -3051,54 +3220,44 @@ var renderTodoTool = ({ args }) => {
3051
3220
  switch (action) {
3052
3221
  case "add":
3053
3222
  const items = parsedArgs.items_to_add || [];
3054
- const itemCount = items.length;
3055
- detailText = `Adding ${itemCount} item${itemCount !== 1 ? "s" : ""}`;
3223
+ detailText = `Added ${items.length} task${items.length !== 1 ? "s" : ""}`;
3056
3224
  break;
3057
3225
  case "complete":
3058
- detailText = `Completing item #${parsedArgs.index}`;
3226
+ detailText = `Completed task #${parsedArgs.index}`;
3059
3227
  break;
3060
3228
  case "remove":
3061
- detailText = `Removing item #${parsedArgs.index}`;
3229
+ detailText = `Removed task #${parsedArgs.index}`;
3062
3230
  break;
3063
3231
  case "list":
3064
- detailText = `Listing all tasks...`;
3232
+ detailText = `Listed all tasks`;
3065
3233
  break;
3066
3234
  default:
3067
- detailText = `Executing action: ${action}`;
3235
+ detailText = `Action: ${action}`;
3068
3236
  break;
3069
3237
  }
3070
- return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
3071
- /* @__PURE__ */ jsx8(Box8, { children: /* @__PURE__ */ jsxs8(Text8, { bold: true, children: [
3072
- /* @__PURE__ */ jsx8(Text8, { color: "green", children: "\u25CF " }),
3073
- "To Do"
3074
- ] }) }),
3075
- /* @__PURE__ */ jsx8(Box8, { marginLeft: 2, paddingX: 1, children: /* @__PURE__ */ jsxs8(Text8, { children: [
3076
- /* @__PURE__ */ jsx8(Text8, { color: "gray", children: "\u21B3 " }),
3077
- /* @__PURE__ */ jsx8(Text8, { color: "magenta", children: detailText })
3078
- ] }) })
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 }) })
3079
3244
  ] });
3080
3245
  } catch (error) {
3081
- return /* @__PURE__ */ jsx8(Box8, { borderStyle: "round", borderColor: "red", paddingX: 1, children: /* @__PURE__ */ jsx8(Text8, { color: "red", children: "Error parsing To-Do arguments" }) });
3246
+ return /* @__PURE__ */ jsx8(Box8, { paddingX: 1, children: /* @__PURE__ */ jsx8(Text8, { color: "red", children: "Error parsing todo" }) });
3082
3247
  }
3083
3248
  };
3084
- var renderGenericToolCall = ({
3085
- toolName,
3086
- args
3087
- }) => {
3249
+ var renderGenericToolCall = ({ toolName, args }) => {
3088
3250
  const formattedArgs = formatArgumentsForDisplay(args);
3089
- return (
3090
- // A "moldura" padrão de sucesso com a borda cinza
3091
- /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
3092
- /* @__PURE__ */ jsx8(Box8, { children: /* @__PURE__ */ jsxs8(Text8, { bold: true, children: [
3093
- /* @__PURE__ */ jsx8(Text8, { color: "green", children: "\u25CF " }),
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
+ " ",
3094
3256
  toolName
3095
- ] }) }),
3096
- formattedArgs && formattedArgs !== "{}" && /* @__PURE__ */ jsxs8(Box8, { paddingX: 3, children: [
3097
- /* @__PURE__ */ jsx8(Text8, { color: "gray", children: "\u21B3 " }),
3098
- /* @__PURE__ */ jsx8(Box8, { flexDirection: "column", children: formattedArgs.split("\n").map((line, index) => /* @__PURE__ */ jsx8(Text8, { color: "gray", children: line }, index)) })
3099
3257
  ] })
3100
- ] })
3101
- );
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
+ ] });
3102
3261
  };
3103
3262
  var ToolRenderDisplay = {
3104
3263
  shell_command: renderShellCommand2,
@@ -3119,10 +3278,10 @@ var ToolCallDisplayComponent = ({ toolName, args, preview }) => {
3119
3278
  const Renderer = ToolRenderDisplay[toolName] || renderGenericToolCall;
3120
3279
  return /* @__PURE__ */ jsx9(Box9, { marginBottom: 1, children: /* @__PURE__ */ jsx9(Renderer, { toolName, args, preview }) });
3121
3280
  };
3122
- var ToolCallDisplay = memo2(ToolCallDisplayComponent);
3281
+ var ToolCallDisplay = memo3(ToolCallDisplayComponent);
3123
3282
 
3124
3283
  // src/app/ui/components/ToolResultDisplay.tsx
3125
- import { memo as memo3 } from "react";
3284
+ import { memo as memo4 } from "react";
3126
3285
  import { Box as Box11 } from "ink";
3127
3286
 
3128
3287
  // src/app/ui/components/MarkdownRenderer.tsx
@@ -3299,68 +3458,25 @@ var ToolResultDisplayComponent = ({ toolName, result }) => {
3299
3458
  }
3300
3459
  return null;
3301
3460
  };
3302
- var ToolResultDisplay = memo3(ToolResultDisplayComponent);
3461
+ var ToolResultDisplay = memo4(ToolResultDisplayComponent);
3303
3462
 
3304
- // src/app/ui/SessionInfoConnectingMCP.tsx
3463
+ // src/app/ui/components/SlashCommands.tsx
3305
3464
  import { Box as Box12, Text as Text11 } from "ink";
3306
- import Spinner from "ink-spinner";
3307
- import { jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
3308
- var SessionInfoConnectingMCP = ({
3309
- sessionId: sessionId2,
3310
- workdir,
3311
- statusMessage
3312
- }) => {
3313
- 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(
3314
3469
  Box12,
3315
3470
  {
3316
- borderStyle: "round",
3471
+ borderStyle: "single",
3317
3472
  borderColor: "gray",
3473
+ paddingX: 2,
3474
+ paddingY: 0,
3318
3475
  marginBottom: 1,
3319
- children: /* @__PURE__ */ jsxs10(
3320
- Box12,
3321
- {
3322
- marginLeft: 1,
3323
- flexDirection: "column",
3324
- children: [
3325
- /* @__PURE__ */ jsxs10(Text11, { children: [
3326
- /* @__PURE__ */ jsx12(Text11, { bold: true, color: "white", children: "localhost" }),
3327
- " ",
3328
- /* @__PURE__ */ jsx12(Text11, { color: "gray", children: " session:" }),
3329
- " ",
3330
- /* @__PURE__ */ jsx12(Text11, { color: "magenta", children: sessionId2 })
3331
- ] }),
3332
- /* @__PURE__ */ jsxs10(Text11, { children: [
3333
- /* @__PURE__ */ jsx12(Text11, { color: "magenta", children: "\u21B3" }),
3334
- " ",
3335
- /* @__PURE__ */ jsxs10(Text11, { color: "gray", children: [
3336
- "workdir: ",
3337
- workdir
3338
- ] })
3339
- ] }),
3340
- /* @__PURE__ */ jsxs10(Text11, { children: [
3341
- /* @__PURE__ */ jsx12(Text11, { color: "magenta", children: "\u21B3" }),
3342
- " ",
3343
- /* @__PURE__ */ jsx12(Text11, { color: "gray", children: "mcp: " }),
3344
- /* @__PURE__ */ jsxs10(Text11, { color: "yellow", children: [
3345
- /* @__PURE__ */ jsx12(Spinner, { type: "dots" }),
3346
- " "
3347
- ] }),
3348
- /* @__PURE__ */ jsx12(Text11, { color: "white", children: statusMessage || "Please wait while we establish connections." })
3349
- ] })
3350
- ]
3351
- }
3352
- )
3476
+ flexDirection: "column",
3477
+ children
3353
3478
  }
3354
3479
  );
3355
- };
3356
- var SessionInfoConnectingMCP_default = SessionInfoConnectingMCP;
3357
-
3358
- // src/app/ui/components/SlashCommands.tsx
3359
- import { Box as Box13, Text as Text12 } from "ink";
3360
- import { Fragment as Fragment2, jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
3361
- var SlashCommands = ({ input, setHistory, agentRef }) => {
3362
- const [cmd, ...args] = input.slice(1).trim().split(/\s+/);
3363
- const outBox = (children) => /* @__PURE__ */ jsx13(Box13, { borderStyle: "round", borderColor: "gray", paddingX: 1, marginBottom: 1, flexDirection: "column", children });
3364
3480
  const render2 = () => {
3365
3481
  if (!cmd) {
3366
3482
  return null;
@@ -3368,19 +3484,23 @@ var SlashCommands = ({ input, setHistory, agentRef }) => {
3368
3484
  if (cmd === "help") {
3369
3485
  const cmds = getSlashCommands();
3370
3486
  return outBox(
3371
- /* @__PURE__ */ jsxs11(Fragment2, { children: [
3372
- /* @__PURE__ */ jsx13(Text12, { color: "magenta", bold: true, children: "Available commands" }),
3373
- cmds.map((c, i) => /* @__PURE__ */ jsxs11(Text12, { color: "gray", children: [
3374
- c.name,
3375
- " - ",
3376
- c.description
3377
- ] }, 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)) })
3378
3493
  ] })
3379
3494
  );
3380
3495
  }
3381
3496
  if (cmd === "clear") {
3382
3497
  setHistory((prev) => prev.filter((item) => item.id === 0 || item.id === 1));
3383
- return outBox(/* @__PURE__ */ jsx13(Text12, { color: "green", children: "History cleared." }));
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
+ );
3384
3504
  }
3385
3505
  if (cmd === "init") {
3386
3506
  (async () => {
@@ -3389,10 +3509,12 @@ var SlashCommands = ({ input, setHistory, agentRef }) => {
3389
3509
  } catch (e) {
3390
3510
  setHistory((prev) => prev.concat({
3391
3511
  id: Date.now(),
3392
- component: outBox(/* @__PURE__ */ jsxs11(Text12, { color: "red", children: [
3393
- "Failed to execute /init: ",
3394
- e?.message || String(e)
3395
- ] }))
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
+ )
3396
3518
  }));
3397
3519
  }
3398
3520
  })();
@@ -3409,37 +3531,45 @@ var SlashCommands = ({ input, setHistory, agentRef }) => {
3409
3531
  const colType = 10;
3410
3532
  const colSource = 18;
3411
3533
  return outBox(
3412
- /* @__PURE__ */ jsxs11(Fragment2, { children: [
3413
- /* @__PURE__ */ jsx13(Text12, { color: "magenta", bold: true, children: "MCP Tools" }),
3414
- /* @__PURE__ */ jsxs11(Text12, { color: "gray", children: [
3415
- "Total MCP: ",
3416
- tools.length,
3417
- term ? ` | Filter: "${term}" | Showing: ${filtered.length}` : ""
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
+ ] })
3418
3554
  ] }),
3419
- filtered.length === 0 ? /* @__PURE__ */ jsx13(Text12, { color: "yellow", children: "No MCP tools to display." }) : /* @__PURE__ */ jsxs11(Box13, { flexDirection: "column", children: [
3420
- /* @__PURE__ */ jsxs11(Text12, { color: "gray", children: [
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: [
3421
3557
  pad("Name", colName),
3422
- " | ",
3558
+ " \u2502 ",
3423
3559
  pad("Type", colType),
3424
- " | ",
3560
+ " \u2502 ",
3425
3561
  pad("Source", colSource)
3426
- ] }),
3427
- /* @__PURE__ */ jsxs11(Text12, { color: "gray", children: [
3428
- "".padEnd(colName, "-"),
3429
- "---",
3430
- "".padEnd(colType, "-"),
3431
- "---",
3432
- "".padEnd(colSource, "-")
3433
- ] }),
3562
+ ] }) }),
3563
+ /* @__PURE__ */ jsx12(Text11, { color: "gray", children: "\u2500".repeat(colName + colType + colSource + 6) }),
3434
3564
  filtered.map((t, i) => {
3435
3565
  const name = t.function?.name || t.name || "tool";
3436
3566
  const type = t.function?.name ? "fn" : t.type || "tool";
3437
3567
  const source = t.source || t.provider || "mcp";
3438
- return /* @__PURE__ */ jsxs11(Text12, { color: "white", children: [
3568
+ return /* @__PURE__ */ jsxs10(Text11, { color: "white", children: [
3439
3569
  pad(name, colName),
3440
- " | ",
3570
+ " \u2502 ",
3441
3571
  pad(String(type), colType),
3442
- " | ",
3572
+ " \u2502 ",
3443
3573
  pad(String(source), colSource)
3444
3574
  ] }, i);
3445
3575
  })
@@ -3458,22 +3588,22 @@ var SlashCommands = ({ input, setHistory, agentRef }) => {
3458
3588
  const colType = 10;
3459
3589
  const colSource = 18;
3460
3590
  return outBox(
3461
- /* @__PURE__ */ jsxs11(Fragment2, { children: [
3462
- /* @__PURE__ */ jsx13(Text12, { color: "magenta", bold: true, children: "Native Tools" }),
3463
- /* @__PURE__ */ jsxs11(Text12, { color: "gray", children: [
3591
+ /* @__PURE__ */ jsxs10(Fragment3, { children: [
3592
+ /* @__PURE__ */ jsx12(Text11, { color: "magenta", bold: true, children: "Native Tools" }),
3593
+ /* @__PURE__ */ jsxs10(Text11, { color: "gray", children: [
3464
3594
  "Total Native: ",
3465
3595
  tools.length,
3466
3596
  term ? ` | Filter: "${term}" | Showing: ${filtered.length}` : ""
3467
3597
  ] }),
3468
- filtered.length === 0 ? /* @__PURE__ */ jsx13(Text12, { color: "yellow", children: "No native tools to display." }) : /* @__PURE__ */ jsxs11(Box13, { flexDirection: "column", children: [
3469
- /* @__PURE__ */ jsxs11(Text12, { color: "gray", children: [
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: [
3470
3600
  pad("Name", colName),
3471
3601
  " | ",
3472
3602
  pad("Type", colType),
3473
3603
  " | ",
3474
3604
  pad("Source", colSource)
3475
3605
  ] }),
3476
- /* @__PURE__ */ jsxs11(Text12, { color: "gray", children: [
3606
+ /* @__PURE__ */ jsxs10(Text11, { color: "gray", children: [
3477
3607
  "".padEnd(colName, "-"),
3478
3608
  "---",
3479
3609
  "".padEnd(colType, "-"),
@@ -3484,7 +3614,7 @@ var SlashCommands = ({ input, setHistory, agentRef }) => {
3484
3614
  const name = t.function?.name || t.name || "tool";
3485
3615
  const type = t.function?.name ? "fn" : t.type || "tool";
3486
3616
  const source = t.source || "native";
3487
- return /* @__PURE__ */ jsxs11(Text12, { color: "white", children: [
3617
+ return /* @__PURE__ */ jsxs10(Text11, { color: "white", children: [
3488
3618
  pad(name, colName),
3489
3619
  " | ",
3490
3620
  pad(String(type), colType),
@@ -3496,12 +3626,12 @@ var SlashCommands = ({ input, setHistory, agentRef }) => {
3496
3626
  ] })
3497
3627
  );
3498
3628
  }
3499
- return outBox(/* @__PURE__ */ jsxs11(Text12, { color: "red", children: [
3629
+ return outBox(/* @__PURE__ */ jsxs10(Text11, { color: "red", children: [
3500
3630
  "Command not recognized: /",
3501
3631
  cmd
3502
3632
  ] }));
3503
3633
  };
3504
- return /* @__PURE__ */ jsx13(Fragment2, { children: render2() });
3634
+ return /* @__PURE__ */ jsx12(Fragment3, { children: render2() });
3505
3635
  };
3506
3636
  var SlashCommands_default = SlashCommands;
3507
3637
 
@@ -3572,8 +3702,8 @@ async function checkForUpdates() {
3572
3702
  }
3573
3703
 
3574
3704
  // src/app/ui/components/UpdateNotice.tsx
3575
- import { Box as Box14, Text as Text13 } from "ink";
3576
- import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
3705
+ import { Box as Box13, Text as Text12 } from "ink";
3706
+ import { jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
3577
3707
  function parseUpdateMessage(msg) {
3578
3708
  const lines = msg.split(/\r?\n/).map((l) => l.trim());
3579
3709
  const first = lines[0] || "";
@@ -3592,20 +3722,20 @@ function parseUpdateMessage(msg) {
3592
3722
  }
3593
3723
  var UpdateNotice = ({ message }) => {
3594
3724
  const { name, current, latest, hint } = parseUpdateMessage(message);
3595
- return /* @__PURE__ */ jsxs12(Box14, { flexDirection: "column", marginBottom: 1, children: [
3596
- /* @__PURE__ */ jsx14(Text13, { color: "yellow", bold: true, children: "Update Available" }),
3597
- name && current && latest ? /* @__PURE__ */ jsx14(Text13, { color: "gray", children: `${name}: ${current} \u2192 ${latest}` }) : /* @__PURE__ */ jsx14(Text13, { color: "gray", children: message }),
3598
- hint ? /* @__PURE__ */ jsx14(Text13, { color: "gray", children: hint }) : null
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
3599
3729
  ] });
3600
3730
  };
3601
3731
  var UpdateNotice_default = UpdateNotice;
3602
3732
 
3603
3733
  // src/app/ui/components/ErrorMessage.tsx
3604
- import { Box as Box15, Text as Text14 } from "ink";
3605
- import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
3734
+ import { Box as Box14, Text as Text13 } from "ink";
3735
+ import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
3606
3736
  var ErrorMessage = ({ message, details, hint }) => {
3607
- return /* @__PURE__ */ jsxs13(
3608
- Box15,
3737
+ return /* @__PURE__ */ jsxs12(
3738
+ Box14,
3609
3739
  {
3610
3740
  borderStyle: "round",
3611
3741
  borderColor: "red",
@@ -3614,10 +3744,10 @@ var ErrorMessage = ({ message, details, hint }) => {
3614
3744
  flexDirection: "column",
3615
3745
  marginBottom: 1,
3616
3746
  children: [
3617
- /* @__PURE__ */ jsx15(Text14, { color: "red", bold: true, children: "Error" }),
3618
- /* @__PURE__ */ jsx15(Text14, { color: "red", children: message }),
3619
- details ? /* @__PURE__ */ jsx15(Text14, { color: "red", dimColor: true, children: details }) : null,
3620
- hint ? /* @__PURE__ */ jsxs13(Text14, { color: "gray", children: [
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: [
3621
3751
  "Hint: ",
3622
3752
  hint
3623
3753
  ] }) : null
@@ -3628,9 +3758,9 @@ var ErrorMessage = ({ message, details, hint }) => {
3628
3758
  var ErrorMessage_default = ErrorMessage;
3629
3759
 
3630
3760
  // src/app/ui/App.tsx
3631
- import { jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
3761
+ import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
3632
3762
  var AppComponent = ({ eventBus: eventBus2, sessionId: sessionId2 }) => {
3633
- const agentInstance = useRef2(null);
3763
+ const agentInstance = useRef4(null);
3634
3764
  const [history, setHistory] = useState5([]);
3635
3765
  const [statusMessage, setStatusMessage] = useState5(
3636
3766
  "Initializing agent..."
@@ -3647,10 +3777,10 @@ var AppComponent = ({ eventBus: eventBus2, sessionId: sessionId2 }) => {
3647
3777
  null
3648
3778
  );
3649
3779
  const [isInitAgentActive, setIsInitAgentActive] = useState5(false);
3650
- const alwaysAcceptList = useRef2([]);
3780
+ const alwaysAcceptList = useRef4([]);
3651
3781
  const workdir = process.cwd();
3652
- const updateCheckRan = useRef2(false);
3653
- const handleInterrupt = useCallback(() => {
3782
+ const updateCheckRan = useRef4(false);
3783
+ const handleInterrupt = useCallback2(() => {
3654
3784
  if (!isProcessing) return;
3655
3785
  eventBus2.emit("user_interrupt");
3656
3786
  setIsProcessing(false);
@@ -3658,11 +3788,11 @@ var AppComponent = ({ eventBus: eventBus2, sessionId: sessionId2 }) => {
3658
3788
  ...prev,
3659
3789
  {
3660
3790
  id: prev.length,
3661
- component: /* @__PURE__ */ jsx16(Text15, { color: "yellow", children: "-- Task cancelled by dev. --" })
3791
+ component: /* @__PURE__ */ jsx15(Text14, { color: "yellow", children: "-- Task cancelled by dev. --" })
3662
3792
  }
3663
3793
  ]);
3664
3794
  }, [isProcessing, eventBus2]);
3665
- const handleSubmit = useCallback(
3795
+ const handleSubmit = useCallback2(
3666
3796
  (text) => {
3667
3797
  if (!text || isProcessing || !agentInstance.current) return;
3668
3798
  if (text.startsWith("/")) {
@@ -3682,11 +3812,11 @@ var AppComponent = ({ eventBus: eventBus2, sessionId: sessionId2 }) => {
3682
3812
  ...prev,
3683
3813
  {
3684
3814
  id: prev.length,
3685
- component: /* @__PURE__ */ jsx16(Box16, { marginBottom: 1, children: /* @__PURE__ */ jsx16(Text15, { color: "white", dimColor: true, children: text }) })
3815
+ component: /* @__PURE__ */ jsx15(Box15, { marginBottom: 1, children: /* @__PURE__ */ jsx15(Text14, { color: "white", dimColor: true, children: text }) })
3686
3816
  },
3687
3817
  {
3688
3818
  id: prev.length + 1,
3689
- component: /* @__PURE__ */ jsx16(
3819
+ component: /* @__PURE__ */ jsx15(
3690
3820
  SlashCommands_default,
3691
3821
  {
3692
3822
  input: text,
@@ -3706,8 +3836,8 @@ var AppComponent = ({ eventBus: eventBus2, sessionId: sessionId2 }) => {
3706
3836
  id: prev.length,
3707
3837
  component: (
3708
3838
  // Uma única Box para o espaçamento
3709
- /* @__PURE__ */ jsx16(Box16, { marginBottom: 1, children: /* @__PURE__ */ jsxs14(Text15, { color: "white", dimColor: true, children: [
3710
- /* @__PURE__ */ jsxs14(Text15, { color: "white", children: [
3839
+ /* @__PURE__ */ jsx15(Box15, { marginBottom: 1, children: /* @__PURE__ */ jsxs13(Text14, { color: "white", dimColor: true, children: [
3840
+ /* @__PURE__ */ jsxs13(Text14, { color: "white", children: [
3711
3841
  ">",
3712
3842
  " "
3713
3843
  ] }),
@@ -3720,7 +3850,7 @@ var AppComponent = ({ eventBus: eventBus2, sessionId: sessionId2 }) => {
3720
3850
  },
3721
3851
  [isProcessing]
3722
3852
  );
3723
- const handleConfirmation = useCallback(
3853
+ const handleConfirmation = useCallback2(
3724
3854
  (decision, toolCalls) => {
3725
3855
  if (!agentInstance.current) return;
3726
3856
  setPendingConfirmation(null);
@@ -3741,8 +3871,8 @@ var AppComponent = ({ eventBus: eventBus2, sessionId: sessionId2 }) => {
3741
3871
  },
3742
3872
  []
3743
3873
  );
3744
- useEffect4(() => {
3745
- setHistory([{ id: 0, component: /* @__PURE__ */ jsx16(Header, {}) }]);
3874
+ useEffect5(() => {
3875
+ setHistory([{ id: 0, component: /* @__PURE__ */ jsx15(Header, { sessionId: sessionId2, workdir }) }]);
3746
3876
  const initializeAgent = async () => {
3747
3877
  try {
3748
3878
  agentInstance.current = new Agent(sessionId2, eventBus2);
@@ -3794,20 +3924,6 @@ var AppComponent = ({ eventBus: eventBus2, sessionId: sessionId2 }) => {
3794
3924
  setIsProcessing(false);
3795
3925
  setHistory((prev) => {
3796
3926
  const newHistory = [...prev];
3797
- if (prev.length < 2) {
3798
- newHistory.push({
3799
- id: 1,
3800
- component: /* @__PURE__ */ jsx16(
3801
- SessionInfo,
3802
- {
3803
- sessionId: sessionId2,
3804
- toolsCount: parsed.tools,
3805
- mcpStatus: "connected",
3806
- workdir
3807
- }
3808
- )
3809
- });
3810
- }
3811
3927
  return newHistory;
3812
3928
  });
3813
3929
  if (!updateCheckRan.current) {
@@ -3818,7 +3934,7 @@ var AppComponent = ({ eventBus: eventBus2, sessionId: sessionId2 }) => {
3818
3934
  ...prev,
3819
3935
  {
3820
3936
  id: prev.length,
3821
- component: /* @__PURE__ */ jsx16(UpdateNotice_default, { message: msg })
3937
+ component: /* @__PURE__ */ jsx15(UpdateNotice_default, { message: msg })
3822
3938
  }
3823
3939
  ]);
3824
3940
  }
@@ -3832,10 +3948,10 @@ var AppComponent = ({ eventBus: eventBus2, sessionId: sessionId2 }) => {
3832
3948
  }
3833
3949
  let newComponent = null;
3834
3950
  if (parsed.type === "debug") {
3835
- newComponent = /* @__PURE__ */ jsx16(Text15, { color: "gray", children: parsed.message });
3951
+ newComponent = /* @__PURE__ */ jsx15(Text14, { color: "gray", children: parsed.message });
3836
3952
  } else if (parsed.type === "protocol_violation") {
3837
- newComponent = /* @__PURE__ */ jsxs14(
3838
- Box16,
3953
+ newComponent = /* @__PURE__ */ jsxs13(
3954
+ Box15,
3839
3955
  {
3840
3956
  borderStyle: "round",
3841
3957
  borderColor: "yellow",
@@ -3843,14 +3959,14 @@ var AppComponent = ({ eventBus: eventBus2, sessionId: sessionId2 }) => {
3843
3959
  marginBottom: 1,
3844
3960
  paddingX: 1,
3845
3961
  children: [
3846
- /* @__PURE__ */ jsx16(Text15, { color: "yellow", bold: true, children: "Protocol Violation" }),
3847
- /* @__PURE__ */ jsx16(Text15, { color: "gray", children: parsed.content }),
3848
- /* @__PURE__ */ jsx16(Text15, { color: "yellow", children: parsed.message })
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 })
3849
3965
  ]
3850
3966
  }
3851
3967
  );
3852
3968
  } else if (parsed.type === "error") {
3853
- newComponent = /* @__PURE__ */ jsx16(
3969
+ newComponent = /* @__PURE__ */ jsx15(
3854
3970
  ErrorMessage_default,
3855
3971
  {
3856
3972
  message: parsed.message,
@@ -3860,7 +3976,7 @@ var AppComponent = ({ eventBus: eventBus2, sessionId: sessionId2 }) => {
3860
3976
  );
3861
3977
  } else if (parsed.type === "tool_call") {
3862
3978
  const nextId = history.length;
3863
- newComponent = /* @__PURE__ */ jsx16(
3979
+ newComponent = /* @__PURE__ */ jsx15(
3864
3980
  ToolCallDisplay,
3865
3981
  {
3866
3982
  toolName: parsed.tool_name,
@@ -3869,7 +3985,7 @@ var AppComponent = ({ eventBus: eventBus2, sessionId: sessionId2 }) => {
3869
3985
  }
3870
3986
  );
3871
3987
  } else if (parsed.type === "tool_result") {
3872
- newComponent = /* @__PURE__ */ jsx16(
3988
+ newComponent = /* @__PURE__ */ jsx15(
3873
3989
  ToolResultDisplay,
3874
3990
  {
3875
3991
  toolName: parsed.tool_name,
@@ -3877,15 +3993,15 @@ var AppComponent = ({ eventBus: eventBus2, sessionId: sessionId2 }) => {
3877
3993
  }
3878
3994
  );
3879
3995
  } else if (parsed.type === "user_overlay") {
3880
- newComponent = /* @__PURE__ */ jsx16(Box16, { marginBottom: 1, children: /* @__PURE__ */ jsxs14(Text15, { color: "gray", children: [
3881
- /* @__PURE__ */ jsxs14(Text15, { color: "magenta", children: [
3996
+ newComponent = /* @__PURE__ */ jsx15(Box15, { marginBottom: 1, children: /* @__PURE__ */ jsxs13(Text14, { color: "gray", children: [
3997
+ /* @__PURE__ */ jsxs13(Text14, { color: "magenta", children: [
3882
3998
  ">",
3883
3999
  " "
3884
4000
  ] }),
3885
4001
  parsed.payload
3886
4002
  ] }) });
3887
4003
  } else if (parsed.type === "log") {
3888
- newComponent = /* @__PURE__ */ jsxs14(Text15, { color: "gray", children: [
4004
+ newComponent = /* @__PURE__ */ jsxs13(Text14, { color: "gray", children: [
3889
4005
  "\u2139\uFE0F ",
3890
4006
  parsed.message,
3891
4007
  parsed.payload ? `: ${parsed.payload}` : ""
@@ -3915,17 +4031,10 @@ var AppComponent = ({ eventBus: eventBus2, sessionId: sessionId2 }) => {
3915
4031
  }, [eventBus2, sessionId2, handleConfirmation]);
3916
4032
  const renderInteractiveComponent = () => {
3917
4033
  if (mcpStatus !== "connected") {
3918
- return /* @__PURE__ */ jsx16(Box16, { borderStyle: "round", borderColor: "black", children: /* @__PURE__ */ jsx16(
3919
- SessionInfoConnectingMCP_default,
3920
- {
3921
- sessionId: sessionId2,
3922
- workdir,
3923
- statusMessage
3924
- }
3925
- ) });
4034
+ return;
3926
4035
  }
3927
4036
  if (pendingConfirmation) {
3928
- return /* @__PURE__ */ jsx16(
4037
+ return /* @__PURE__ */ jsx15(
3929
4038
  ConfirmationPrompt,
3930
4039
  {
3931
4040
  toolCalls: pendingConfirmation,
@@ -3937,9 +4046,9 @@ var AppComponent = ({ eventBus: eventBus2, sessionId: sessionId2 }) => {
3937
4046
  }
3938
4047
  );
3939
4048
  }
3940
- return /* @__PURE__ */ jsxs14(Box16, { flexDirection: "column", children: [
3941
- isProcessing && !pendingConfirmation && /* @__PURE__ */ jsx16(WorkingTimer, {}),
3942
- /* @__PURE__ */ jsx16(
4049
+ return /* @__PURE__ */ jsxs13(Box15, { flexDirection: "column", children: [
4050
+ isProcessing && !pendingConfirmation && /* @__PURE__ */ jsx15(WorkingTimer, {}),
4051
+ /* @__PURE__ */ jsx15(
3943
4052
  InputPrompt,
3944
4053
  {
3945
4054
  onSubmit: handleSubmit,
@@ -3950,12 +4059,12 @@ var AppComponent = ({ eventBus: eventBus2, sessionId: sessionId2 }) => {
3950
4059
  )
3951
4060
  ] });
3952
4061
  };
3953
- return /* @__PURE__ */ jsxs14(Box16, { flexDirection: "column", children: [
3954
- /* @__PURE__ */ jsx16(Static, { items: history, children: (item) => /* @__PURE__ */ jsx16(Box16, { children: item.component }, item.id) }),
4062
+ return /* @__PURE__ */ jsxs13(Box15, { flexDirection: "column", children: [
4063
+ /* @__PURE__ */ jsx15(Static, { items: history, children: (item) => /* @__PURE__ */ jsx15(Box15, { children: item.component }, item.id) }),
3955
4064
  renderInteractiveComponent()
3956
4065
  ] });
3957
4066
  };
3958
- var App = memo4(AppComponent);
4067
+ var App = memo5(AppComponent);
3959
4068
  var App_default = App;
3960
4069
 
3961
4070
  // src/app/ui/utils/terminalTitle.ts