@nomad-e/bluma-cli 0.1.4 → 0.1.6

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 +50 -50
  2. package/package.json +1 -1
package/dist/main.js CHANGED
@@ -335,7 +335,7 @@ import { v4 as uuidv43 } from "uuid";
335
335
 
336
336
  // src/app/ui/App.tsx
337
337
  import { useState as useState7, useEffect as useEffect6, useRef as useRef5, useCallback as useCallback2, memo as memo11 } from "react";
338
- import { Box as Box17, Text as Text16, Static as Static2 } from "ink";
338
+ import { Box as Box17, Text as Text16, Static } from "ink";
339
339
 
340
340
  // src/app/ui/layout.tsx
341
341
  import { Box, Text } from "ink";
@@ -5894,7 +5894,7 @@ var Agent = class {
5894
5894
  };
5895
5895
 
5896
5896
  // src/app/ui/WorkingTimer.tsx
5897
- import React4, { useState as useState4, useEffect as useEffect4, memo as memo5 } from "react";
5897
+ import { useState as useState4, useEffect as useEffect4, memo as memo5 } from "react";
5898
5898
  import { Box as Box7, Text as Text7 } from "ink";
5899
5899
  import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
5900
5900
  var WorkingTimerComponent = ({ eventBus: eventBus2, taskName, taskStatus }) => {
@@ -5916,7 +5916,7 @@ var WorkingTimerComponent = ({ eventBus: eventBus2, taskName, taskStatus }) => {
5916
5916
  useEffect4(() => {
5917
5917
  const shineTimer = setInterval(() => {
5918
5918
  setShinePosition((prev) => (prev + 1) % 30);
5919
- }, 150);
5919
+ }, 120);
5920
5920
  return () => clearInterval(shineTimer);
5921
5921
  }, []);
5922
5922
  useEffect4(() => {
@@ -5926,9 +5926,9 @@ var WorkingTimerComponent = ({ eventBus: eventBus2, taskName, taskStatus }) => {
5926
5926
  return () => clearInterval(dotsTimer);
5927
5927
  }, []);
5928
5928
  const displayAction = taskStatus || currentAction;
5929
- const shineText = React4.useMemo(() => {
5930
- const chars = displayAction.split("");
5931
- const textLen = displayAction.length;
5929
+ const renderShineText = (text) => {
5930
+ const chars = text.split("");
5931
+ const textLen = text.length;
5932
5932
  const shineIdx = shinePosition % (textLen + 6);
5933
5933
  return chars.map((char, i) => {
5934
5934
  const distance = Math.abs(i - shineIdx);
@@ -5938,9 +5938,9 @@ var WorkingTimerComponent = ({ eventBus: eventBus2, taskName, taskStatus }) => {
5938
5938
  return /* @__PURE__ */ jsx7(Text7, { color: "gray", dimColor: true, children: char }, i);
5939
5939
  }
5940
5940
  });
5941
- }, [displayAction, shinePosition]);
5941
+ };
5942
5942
  return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", paddingX: 1, children: [
5943
- /* @__PURE__ */ jsx7(Box7, { children: shineText }),
5943
+ /* @__PURE__ */ jsx7(Box7, { children: renderShineText(displayAction) }),
5944
5944
  taskName && /* @__PURE__ */ jsx7(Box7, { paddingLeft: 2, children: /* @__PURE__ */ jsxs7(Text7, { dimColor: true, children: [
5945
5945
  "\u203A ",
5946
5946
  taskName
@@ -6480,9 +6480,11 @@ var ToolResultDisplayComponent = ({ toolName, result }) => {
6480
6480
  }
6481
6481
  if (!output && !stderr) return null;
6482
6482
  const { lines, truncated } = truncateLines(output || stderr, MAX_LINES);
6483
- const isError = exitCode !== 0 || stderr;
6483
+ const isError = exitCode !== 0;
6484
+ const isSuccess = exitCode === 0 && status !== "running";
6485
+ const textColor = isError ? "red" : isSuccess ? "green" : "gray";
6484
6486
  return /* @__PURE__ */ jsxs10(Box11, { flexDirection: "column", paddingLeft: 3, children: [
6485
- lines.map((line, i) => /* @__PURE__ */ jsx11(Text10, { dimColor: true, color: isError ? "red" : "gray", children: line.slice(0, 80) }, i)),
6487
+ lines.map((line, i) => /* @__PURE__ */ jsx11(Text10, { dimColor: true, color: textColor, children: line.slice(0, 80) }, i)),
6486
6488
  truncated > 0 && /* @__PURE__ */ jsxs10(Text10, { dimColor: true, children: [
6487
6489
  "... +",
6488
6490
  truncated,
@@ -6883,49 +6885,49 @@ var ReasoningDisplay = memo9(ReasoningDisplayComponent);
6883
6885
 
6884
6886
  // src/app/ui/components/StreamingText.tsx
6885
6887
  import { useState as useState6, useEffect as useEffect5, useRef as useRef4, memo as memo10 } from "react";
6886
- import { Box as Box16, Text as Text15, Static } from "ink";
6887
- import { jsx as jsx16, jsxs as jsxs15 } from "react/jsx-runtime";
6888
+ import { Box as Box16, Text as Text15 } from "ink";
6889
+ import { jsx as jsx16 } from "react/jsx-runtime";
6888
6890
  var StreamingTextComponent = ({ eventBus: eventBus2, onReasoningComplete }) => {
6889
- const [completedLines, setCompletedLines] = useState6([]);
6890
- const [currentLine, setCurrentLine] = useState6("");
6891
+ const [reasoning, setReasoning] = useState6("");
6891
6892
  const [isStreaming, setIsStreaming] = useState6(false);
6892
6893
  const reasoningRef = useRef4("");
6893
- const lastProcessedLength = useRef4(0);
6894
+ const lastUpdateRef = useRef4(0);
6895
+ const pendingUpdateRef = useRef4(null);
6894
6896
  useEffect5(() => {
6895
6897
  const handleStart = () => {
6896
- setCompletedLines([]);
6897
- setCurrentLine("");
6898
+ setReasoning("");
6898
6899
  reasoningRef.current = "";
6899
- lastProcessedLength.current = 0;
6900
+ lastUpdateRef.current = 0;
6900
6901
  setIsStreaming(true);
6901
6902
  };
6902
6903
  const handleReasoningChunk = (data) => {
6903
6904
  if (data.delta) {
6904
6905
  reasoningRef.current += data.delta;
6905
- const fullText = reasoningRef.current;
6906
- const lastNewlineIndex = fullText.lastIndexOf("\n");
6907
- if (lastNewlineIndex > lastProcessedLength.current) {
6908
- const newCompleteText = fullText.substring(0, lastNewlineIndex);
6909
- const lines = newCompleteText.split("\n");
6910
- setCompletedLines(lines.map((line, i) => ({ id: i, content: line })));
6911
- setCurrentLine(fullText.substring(lastNewlineIndex + 1));
6912
- lastProcessedLength.current = lastNewlineIndex + 1;
6913
- } else {
6914
- const startIdx = lastProcessedLength.current > 0 ? lastProcessedLength.current : fullText.lastIndexOf("\n") + 1;
6915
- setCurrentLine(fullText.substring(startIdx));
6906
+ const now = Date.now();
6907
+ if (now - lastUpdateRef.current >= 50) {
6908
+ lastUpdateRef.current = now;
6909
+ setReasoning(reasoningRef.current);
6910
+ } else if (!pendingUpdateRef.current) {
6911
+ pendingUpdateRef.current = setTimeout(() => {
6912
+ lastUpdateRef.current = Date.now();
6913
+ setReasoning(reasoningRef.current);
6914
+ pendingUpdateRef.current = null;
6915
+ }, 50 - (now - lastUpdateRef.current));
6916
6916
  }
6917
6917
  }
6918
6918
  };
6919
6919
  const handleEnd = () => {
6920
6920
  setIsStreaming(false);
6921
+ if (pendingUpdateRef.current) {
6922
+ clearTimeout(pendingUpdateRef.current);
6923
+ pendingUpdateRef.current = null;
6924
+ }
6921
6925
  const finalReasoning = reasoningRef.current;
6922
6926
  if (finalReasoning && onReasoningComplete) {
6923
6927
  onReasoningComplete(finalReasoning);
6924
6928
  }
6925
- setCompletedLines([]);
6926
- setCurrentLine("");
6929
+ setReasoning("");
6927
6930
  reasoningRef.current = "";
6928
- lastProcessedLength.current = 0;
6929
6931
  };
6930
6932
  eventBus2.on("stream_start", handleStart);
6931
6933
  eventBus2.on("stream_reasoning_chunk", handleReasoningChunk);
@@ -6936,18 +6938,16 @@ var StreamingTextComponent = ({ eventBus: eventBus2, onReasoningComplete }) => {
6936
6938
  eventBus2.off("stream_end", handleEnd);
6937
6939
  };
6938
6940
  }, [eventBus2, onReasoningComplete]);
6939
- if (!isStreaming || completedLines.length === 0 && !currentLine) {
6941
+ if (!isStreaming || !reasoning) {
6940
6942
  return null;
6941
6943
  }
6942
- return /* @__PURE__ */ jsx16(Box16, { flexDirection: "column", paddingX: 1, marginBottom: 1, marginTop: 1, children: /* @__PURE__ */ jsxs15(Box16, { paddingLeft: 2, flexDirection: "column", children: [
6943
- /* @__PURE__ */ jsx16(Static, { items: completedLines, children: (item) => /* @__PURE__ */ jsx16(Text15, { color: "gray", dimColor: true, children: item.content }, item.id) }),
6944
- currentLine && /* @__PURE__ */ jsx16(Text15, { color: "gray", dimColor: true, children: currentLine })
6945
- ] }) });
6944
+ const lines = reasoning.split("\n");
6945
+ return /* @__PURE__ */ jsx16(Box16, { flexDirection: "column", paddingX: 1, marginBottom: 1, marginTop: 1, children: /* @__PURE__ */ jsx16(Box16, { paddingLeft: 2, flexDirection: "column", children: lines.map((line, i) => /* @__PURE__ */ jsx16(Text15, { color: "gray", dimColor: true, children: line }, i)) }) });
6946
6946
  };
6947
6947
  var StreamingText = memo10(StreamingTextComponent);
6948
6948
 
6949
6949
  // src/app/ui/App.tsx
6950
- import { jsx as jsx17, jsxs as jsxs16 } from "react/jsx-runtime";
6950
+ import { jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
6951
6951
  var SAFE_AUTO_APPROVE_TOOLS = [
6952
6952
  // Comunicação/UI
6953
6953
  "message",
@@ -7045,7 +7045,7 @@ var AppComponent = ({ eventBus: eventBus2, sessionId: sessionId2 }) => {
7045
7045
  ...prev,
7046
7046
  {
7047
7047
  id: prev.length,
7048
- component: /* @__PURE__ */ jsxs16(Box17, { marginBottom: 1, children: [
7048
+ component: /* @__PURE__ */ jsxs15(Box17, { marginBottom: 1, children: [
7049
7049
  /* @__PURE__ */ jsx17(Text16, { color: "white", bold: true, children: "$ " }),
7050
7050
  /* @__PURE__ */ jsx17(Text16, { color: "white", children: command })
7051
7051
  ] })
@@ -7066,7 +7066,7 @@ Please use command_status to check the result and report back to the user.`;
7066
7066
  ...prev,
7067
7067
  {
7068
7068
  id: prev.length,
7069
- component: /* @__PURE__ */ jsxs16(Text16, { color: "red", children: [
7069
+ component: /* @__PURE__ */ jsxs15(Text16, { color: "red", children: [
7070
7070
  "Failed to execute: ",
7071
7071
  result.error || result.message
7072
7072
  ] })
@@ -7079,7 +7079,7 @@ Please use command_status to check the result and report back to the user.`;
7079
7079
  ...prev,
7080
7080
  {
7081
7081
  id: prev.length,
7082
- component: /* @__PURE__ */ jsxs16(Text16, { color: "red", children: [
7082
+ component: /* @__PURE__ */ jsxs15(Text16, { color: "red", children: [
7083
7083
  "Error: ",
7084
7084
  err.message
7085
7085
  ] })
@@ -7098,8 +7098,8 @@ Please use command_status to check the result and report back to the user.`;
7098
7098
  id: prev.length,
7099
7099
  component: (
7100
7100
  // Uma única Box para o espaçamento
7101
- /* @__PURE__ */ jsx17(Box17, { marginBottom: 1, children: /* @__PURE__ */ jsxs16(Text16, { color: "white", dimColor: true, children: [
7102
- /* @__PURE__ */ jsxs16(Text16, { color: "white", children: [
7101
+ /* @__PURE__ */ jsx17(Box17, { marginBottom: 1, children: /* @__PURE__ */ jsxs15(Text16, { color: "white", dimColor: true, children: [
7102
+ /* @__PURE__ */ jsxs15(Text16, { color: "white", children: [
7103
7103
  ">",
7104
7104
  " "
7105
7105
  ] }),
@@ -7216,7 +7216,7 @@ Please use command_status to check the result and report back to the user.`;
7216
7216
  if (parsed.type === "debug") {
7217
7217
  newComponent = /* @__PURE__ */ jsx17(Text16, { color: "gray", children: parsed.message });
7218
7218
  } else if (parsed.type === "protocol_violation") {
7219
- newComponent = /* @__PURE__ */ jsxs16(
7219
+ newComponent = /* @__PURE__ */ jsxs15(
7220
7220
  Box17,
7221
7221
  {
7222
7222
  borderStyle: "round",
@@ -7259,8 +7259,8 @@ Please use command_status to check the result and report back to the user.`;
7259
7259
  }
7260
7260
  );
7261
7261
  } else if (parsed.type === "user_overlay") {
7262
- newComponent = /* @__PURE__ */ jsx17(Box17, { marginBottom: 1, children: /* @__PURE__ */ jsxs16(Text16, { color: "gray", children: [
7263
- /* @__PURE__ */ jsxs16(Text16, { color: "magenta", children: [
7262
+ newComponent = /* @__PURE__ */ jsx17(Box17, { marginBottom: 1, children: /* @__PURE__ */ jsxs15(Text16, { color: "gray", children: [
7263
+ /* @__PURE__ */ jsxs15(Text16, { color: "magenta", children: [
7264
7264
  ">",
7265
7265
  " "
7266
7266
  ] }),
@@ -7269,7 +7269,7 @@ Please use command_status to check the result and report back to the user.`;
7269
7269
  } else if (parsed.type === "reasoning") {
7270
7270
  newComponent = /* @__PURE__ */ jsx17(ReasoningDisplay, { reasoning: parsed.content });
7271
7271
  } else if (parsed.type === "log") {
7272
- newComponent = /* @__PURE__ */ jsxs16(Text16, { color: "gray", children: [
7272
+ newComponent = /* @__PURE__ */ jsxs15(Text16, { color: "gray", children: [
7273
7273
  "\u2139\uFE0F ",
7274
7274
  parsed.message,
7275
7275
  parsed.payload ? `: ${parsed.payload}` : ""
@@ -7314,7 +7314,7 @@ Please use command_status to check the result and report back to the user.`;
7314
7314
  }
7315
7315
  );
7316
7316
  }
7317
- return /* @__PURE__ */ jsxs16(Box17, { flexDirection: "column", children: [
7317
+ return /* @__PURE__ */ jsxs15(Box17, { flexDirection: "column", children: [
7318
7318
  isProcessing && !pendingConfirmation && /* @__PURE__ */ jsx17(WorkingTimer, { eventBus: eventBus2 }),
7319
7319
  /* @__PURE__ */ jsx17(
7320
7320
  InputPrompt,
@@ -7327,8 +7327,8 @@ Please use command_status to check the result and report back to the user.`;
7327
7327
  )
7328
7328
  ] });
7329
7329
  };
7330
- return /* @__PURE__ */ jsxs16(Box17, { flexDirection: "column", children: [
7331
- /* @__PURE__ */ jsx17(Static2, { items: history, children: (item) => /* @__PURE__ */ jsx17(Box17, { children: item.component }, item.id) }),
7330
+ return /* @__PURE__ */ jsxs15(Box17, { flexDirection: "column", children: [
7331
+ /* @__PURE__ */ jsx17(Static, { items: history, children: (item) => /* @__PURE__ */ jsx17(Box17, { children: item.component }, item.id) }),
7332
7332
  /* @__PURE__ */ jsx17(
7333
7333
  StreamingText,
7334
7334
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nomad-e/bluma-cli",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "description": "BluMa independent agent for automation and advanced software engineering.",
5
5
  "author": "Alex Fonseca",
6
6
  "license": "Apache-2.0",