@bike4mind/cli 0.2.10-fix-b4m-cli-flicker.17230 → 0.2.10-fix-b4m-cli-flicker.17243
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +121 -48
- package/package.json +6 -6
package/dist/index.js
CHANGED
|
@@ -79,23 +79,24 @@ import {
|
|
|
79
79
|
} from "./chunk-PDX44BCA.js";
|
|
80
80
|
|
|
81
81
|
// src/index.tsx
|
|
82
|
-
import React17, { useState as
|
|
82
|
+
import React17, { useState as useState8, useEffect as useEffect3, useCallback, useRef as useRef2 } from "react";
|
|
83
83
|
import { render, Box as Box16, Text as Text16, useApp, useInput as useInput6 } from "ink";
|
|
84
|
+
import { execSync } from "child_process";
|
|
84
85
|
import { v4 as uuidv49 } from "uuid";
|
|
85
86
|
|
|
86
87
|
// src/components/App.tsx
|
|
87
|
-
import React11 from "react";
|
|
88
|
+
import React11, { useState as useState4 } from "react";
|
|
88
89
|
import { Box as Box10, Text as Text10, Static } from "ink";
|
|
89
90
|
|
|
90
91
|
// src/components/StatusBar.tsx
|
|
91
92
|
import React from "react";
|
|
92
93
|
import { Box, Text } from "ink";
|
|
93
94
|
var StatusBar = React.memo(function StatusBar2({ sessionName, model, tokenUsage }) {
|
|
94
|
-
return /* @__PURE__ */ React.createElement(Box, {
|
|
95
|
+
return /* @__PURE__ */ React.createElement(Box, { flexDirection: "row", justifyContent: "space-between", width: "100%", paddingX: 1 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, sessionName), /* @__PURE__ */ React.createElement(Box, { gap: 2 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, tokenUsage.toLocaleString(), " tokens"), /* @__PURE__ */ React.createElement(Text, { dimColor: true }, model)));
|
|
95
96
|
});
|
|
96
97
|
|
|
97
98
|
// src/components/InputPrompt.tsx
|
|
98
|
-
import React5, { useState as useState2, useMemo, useEffect } from "react";
|
|
99
|
+
import React5, { useState as useState2, useMemo, useEffect, useRef } from "react";
|
|
99
100
|
import { Box as Box4, Text as Text5, useInput as useInput2 } from "ink";
|
|
100
101
|
|
|
101
102
|
// src/components/CustomTextInput.tsx
|
|
@@ -732,17 +733,19 @@ function findAtTrigger(value) {
|
|
|
732
733
|
}
|
|
733
734
|
function InputPrompt({
|
|
734
735
|
onSubmit,
|
|
736
|
+
onBashCommand,
|
|
735
737
|
onImageDetected,
|
|
736
738
|
disabled = false,
|
|
737
739
|
history = [],
|
|
738
740
|
prefillInput,
|
|
739
|
-
onPrefillConsumed
|
|
741
|
+
onPrefillConsumed,
|
|
742
|
+
onBashModeChange
|
|
740
743
|
}) {
|
|
741
744
|
const [value, setValue] = useState2("");
|
|
742
745
|
const [selectedIndex, setSelectedIndex] = useState2(0);
|
|
743
746
|
const [historyIndex, setHistoryIndex] = useState2(-1);
|
|
744
747
|
const [tempInput, setTempInput] = useState2("");
|
|
745
|
-
const
|
|
748
|
+
const inputKey = useRef(0);
|
|
746
749
|
useEffect(() => {
|
|
747
750
|
if (prefillInput) {
|
|
748
751
|
setValue(prefillInput);
|
|
@@ -751,6 +754,10 @@ function InputPrompt({
|
|
|
751
754
|
}, [prefillInput, onPrefillConsumed]);
|
|
752
755
|
const [fileAutocomplete, setFileAutocomplete] = useState2(null);
|
|
753
756
|
const [fileSelectedIndex, setFileSelectedIndex] = useState2(0);
|
|
757
|
+
const isBashMode = value.startsWith("!");
|
|
758
|
+
useEffect(() => {
|
|
759
|
+
onBashModeChange?.(isBashMode);
|
|
760
|
+
}, [isBashMode, onBashModeChange]);
|
|
754
761
|
const shouldShowCommandAutocomplete = value.startsWith("/") && !disabled && !fileAutocomplete?.active;
|
|
755
762
|
const commandQuery = shouldShowCommandAutocomplete ? value.slice(1) : "";
|
|
756
763
|
const filteredCommands = useMemo(() => {
|
|
@@ -857,6 +864,16 @@ function InputPrompt({
|
|
|
857
864
|
onSubmit(commandText);
|
|
858
865
|
return;
|
|
859
866
|
}
|
|
867
|
+
if (isBashMode && onBashCommand) {
|
|
868
|
+
const command = input.slice(1).trim();
|
|
869
|
+
if (command) {
|
|
870
|
+
onBashCommand(command);
|
|
871
|
+
setValue("");
|
|
872
|
+
setHistoryIndex(-1);
|
|
873
|
+
setFileAutocomplete(null);
|
|
874
|
+
}
|
|
875
|
+
return;
|
|
876
|
+
}
|
|
860
877
|
onSubmit(input);
|
|
861
878
|
setValue("");
|
|
862
879
|
setHistoryIndex(-1);
|
|
@@ -887,14 +904,19 @@ function InputPrompt({
|
|
|
887
904
|
setFileAutocomplete(null);
|
|
888
905
|
}
|
|
889
906
|
};
|
|
890
|
-
|
|
907
|
+
const getPlaceholder = () => {
|
|
908
|
+
if (disabled) return "Thinking...";
|
|
909
|
+
if (isBashMode) return "Enter shell command to execute...";
|
|
910
|
+
return "Type your message, /help for commands, @file to reference, or ! for bash";
|
|
911
|
+
};
|
|
912
|
+
return /* @__PURE__ */ React5.createElement(Box4, { flexDirection: "column" }, /* @__PURE__ */ React5.createElement(Box4, null, /* @__PURE__ */ React5.createElement(Text5, { bold: true, color: isBashMode ? "yellow" : "cyan" }, isBashMode ? "$ " : "> "), /* @__PURE__ */ React5.createElement(
|
|
891
913
|
CustomTextInput,
|
|
892
914
|
{
|
|
893
|
-
key: inputKey,
|
|
915
|
+
key: inputKey.current,
|
|
894
916
|
value,
|
|
895
917
|
onChange: handleChange,
|
|
896
918
|
onSubmit: handleSubmit,
|
|
897
|
-
placeholder:
|
|
919
|
+
placeholder: getPlaceholder(),
|
|
898
920
|
showCursor: !disabled
|
|
899
921
|
}
|
|
900
922
|
)), shouldShowCommandAutocomplete && /* @__PURE__ */ React5.createElement(CommandAutocomplete, { commands: filteredCommands, selectedIndex }), fileAutocomplete?.active && /* @__PURE__ */ React5.createElement(FileAutocomplete, { files: filteredFiles, selectedIndex: fileSelectedIndex, query: fileAutocomplete.query }));
|
|
@@ -918,6 +940,16 @@ var useCliStore = create((set) => ({
|
|
|
918
940
|
// Session state
|
|
919
941
|
session: null,
|
|
920
942
|
setSession: (session) => set({ session }),
|
|
943
|
+
addMessage: (message) => set((state) => {
|
|
944
|
+
if (!state.session) return state;
|
|
945
|
+
return {
|
|
946
|
+
session: {
|
|
947
|
+
...state.session,
|
|
948
|
+
messages: [...state.session.messages, message],
|
|
949
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
950
|
+
}
|
|
951
|
+
};
|
|
952
|
+
}),
|
|
921
953
|
// Pending messages
|
|
922
954
|
pendingMessages: [],
|
|
923
955
|
addPendingMessage: (message) => set((state) => ({ pendingMessages: [...state.pendingMessages, message] })),
|
|
@@ -1245,7 +1277,7 @@ import React10 from "react";
|
|
|
1245
1277
|
import { Box as Box9, Text as Text9 } from "ink";
|
|
1246
1278
|
function MessageItem({ message }) {
|
|
1247
1279
|
const isUser = message.role === "user";
|
|
1248
|
-
return /* @__PURE__ */ React10.createElement(Box9, { flexDirection: "column", marginBottom: 1 }, /* @__PURE__ */ React10.createElement(Box9, null, /* @__PURE__ */ React10.createElement(Text9, { bold: true, color: isUser ? "cyan" : "green" }, isUser ? "\u{1F464} You" : "\u{1F916} Assistant"), /* @__PURE__ */ React10.createElement(Text9, { dimColor: true }, " \u2022 ", new Date(message.timestamp).toLocaleTimeString())), isUser && message.content && /* @__PURE__ */ React10.createElement(Box9, { paddingLeft: 2 }, /* @__PURE__ */ React10.createElement(Text9, { backgroundColor: "whiteBright", color: "black" }, " ", message.content, " ")), !isUser && message.metadata?.steps && message.metadata.steps.length > 0 && /* @__PURE__ */ React10.createElement(Box9, { paddingLeft: 2, marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React10.createElement(Text9, { dimColor: true, bold: true }, "\u{1F527} Agent Reasoning Trace (", message.metadata.steps.filter((s) => s.type === "action").length, " ", "tools used, ", message.metadata.steps.length, " total steps)", message.metadata.tokenUsage && ` \u2022 ${message.metadata.tokenUsage.total} tokens`), /* @__PURE__ */ React10.createElement(Text9, { dimColor: true }, "Step types: ", message.metadata.steps.map((s) => s.type).join(", ")), message.metadata.steps.map((step, idx) => {
|
|
1280
|
+
return /* @__PURE__ */ React10.createElement(Box9, { flexDirection: "column", marginBottom: 1 }, /* @__PURE__ */ React10.createElement(Box9, null, /* @__PURE__ */ React10.createElement(Text9, { bold: true, color: isUser ? "cyan" : "green" }, isUser ? "\u{1F464} You" : "\u{1F916} Assistant"), isUser && /* @__PURE__ */ React10.createElement(Text9, { dimColor: true }, " \u2022 ", new Date(message.timestamp).toLocaleTimeString())), isUser && message.content && /* @__PURE__ */ React10.createElement(Box9, { paddingLeft: 2 }, /* @__PURE__ */ React10.createElement(Text9, { backgroundColor: "whiteBright", color: "black" }, " ", message.content, " ")), !isUser && message.metadata?.steps && message.metadata.steps.length > 0 && /* @__PURE__ */ React10.createElement(Box9, { paddingLeft: 2, marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React10.createElement(Text9, { dimColor: true, bold: true }, "\u{1F527} Agent Reasoning Trace (", message.metadata.steps.filter((s) => s.type === "action").length, " ", "tools used, ", message.metadata.steps.length, " total steps)", message.metadata.tokenUsage && ` \u2022 ${message.metadata.tokenUsage.total} tokens`), /* @__PURE__ */ React10.createElement(Text9, { dimColor: true }, "Step types: ", message.metadata.steps.map((s) => s.type).join(", ")), message.metadata.steps.map((step, idx) => {
|
|
1249
1281
|
if (step.type === "thought") {
|
|
1250
1282
|
return /* @__PURE__ */ React10.createElement(Box9, { key: idx, paddingLeft: 2, marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React10.createElement(Text9, { color: "blue" }, "\u{1F4AD} Thought:"), /* @__PURE__ */ React10.createElement(Text9, { dimColor: true }, ` ${step.content.slice(0, 200)}${step.content.length > 200 ? "..." : ""}`));
|
|
1251
1283
|
}
|
|
@@ -1378,6 +1410,7 @@ function hasFileReferences(message) {
|
|
|
1378
1410
|
function App({
|
|
1379
1411
|
onMessage,
|
|
1380
1412
|
onCommand,
|
|
1413
|
+
onBashCommand,
|
|
1381
1414
|
onPermissionResponse,
|
|
1382
1415
|
onImageDetected,
|
|
1383
1416
|
commandHistory = [],
|
|
@@ -1398,6 +1431,7 @@ function App({
|
|
|
1398
1431
|
const setShowConfigEditor = useCliStore((state) => state.setShowConfigEditor);
|
|
1399
1432
|
const exitRequested = useCliStore((state) => state.exitRequested);
|
|
1400
1433
|
const setIsThinking = useCliStore((state) => state.setIsThinking);
|
|
1434
|
+
const [isBashMode, setIsBashMode] = useState4(false);
|
|
1401
1435
|
const handleSubmit = React11.useCallback(
|
|
1402
1436
|
async (input) => {
|
|
1403
1437
|
const trimmed = input.trim();
|
|
@@ -1444,17 +1478,19 @@ ${errorBlock}`;
|
|
|
1444
1478
|
canBeTrusted: permissionPrompt.canBeTrusted,
|
|
1445
1479
|
onResponse: onPermissionResponse
|
|
1446
1480
|
}
|
|
1447
|
-
)) : /* @__PURE__ */ React11.createElement(React11.Fragment, null, /* @__PURE__ */ React11.createElement(Static, { items: messages }, (message, index) => /* @__PURE__ */ React11.createElement(Box10, { key: `${message.timestamp}-${message.role}-${index}`, flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React11.createElement(MessageItem, { message }))), /* @__PURE__ */ React11.createElement(Box10, { flexDirection: "column" }, pendingMessages.map((message, index) => /* @__PURE__ */ React11.createElement(Box10, { key: `pending-${message.timestamp}-${index}`, flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React11.createElement(MessageItem, { message })))), /* @__PURE__ */ React11.createElement(AgentThinking, null), exitRequested && /* @__PURE__ */ React11.createElement(Box10, { paddingX: 1, marginBottom: 1 }, /* @__PURE__ */ React11.createElement(Text10, { color: "yellow", bold: true }, "Press Ctrl+C again to exit")), /* @__PURE__ */ React11.createElement(
|
|
1481
|
+
)) : /* @__PURE__ */ React11.createElement(React11.Fragment, null, /* @__PURE__ */ React11.createElement(Static, { items: messages }, (message, index) => /* @__PURE__ */ React11.createElement(Box10, { key: `${message.timestamp}-${message.role}-${index}`, flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React11.createElement(MessageItem, { message }))), /* @__PURE__ */ React11.createElement(Box10, { flexDirection: "column" }, pendingMessages.map((message, index) => /* @__PURE__ */ React11.createElement(Box10, { key: `pending-${message.timestamp}-${index}`, flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React11.createElement(MessageItem, { message })))), /* @__PURE__ */ React11.createElement(AgentThinking, null), exitRequested && /* @__PURE__ */ React11.createElement(Box10, { paddingX: 1, marginBottom: 1 }, /* @__PURE__ */ React11.createElement(Text10, { color: "yellow", bold: true }, "Press Ctrl+C again to exit")), /* @__PURE__ */ React11.createElement(Box10, { borderStyle: "single", borderColor: isBashMode ? "yellow" : "cyan", paddingX: 1 }, /* @__PURE__ */ React11.createElement(
|
|
1448
1482
|
InputPrompt,
|
|
1449
1483
|
{
|
|
1450
1484
|
onSubmit: handleSubmit,
|
|
1485
|
+
onBashCommand,
|
|
1451
1486
|
onImageDetected,
|
|
1452
1487
|
disabled: isThinking,
|
|
1453
1488
|
history: commandHistory,
|
|
1454
1489
|
prefillInput,
|
|
1455
|
-
onPrefillConsumed
|
|
1490
|
+
onPrefillConsumed,
|
|
1491
|
+
onBashModeChange: setIsBashMode
|
|
1456
1492
|
}
|
|
1457
|
-
))));
|
|
1493
|
+
)), /* @__PURE__ */ React11.createElement(StatusBar, { sessionName, model: currentModel, tokenUsage: totalTokens })));
|
|
1458
1494
|
}
|
|
1459
1495
|
|
|
1460
1496
|
// src/components/MessageList.tsx
|
|
@@ -1530,12 +1566,12 @@ function TrustLocationSelector({ inProject, onSelect, onCancel }) {
|
|
|
1530
1566
|
}
|
|
1531
1567
|
|
|
1532
1568
|
// src/components/RewindSelector.tsx
|
|
1533
|
-
import React14, { useState as
|
|
1569
|
+
import React14, { useState as useState5 } from "react";
|
|
1534
1570
|
import { Box as Box13, Text as Text13, useInput as useInput4 } from "ink";
|
|
1535
1571
|
import SelectInput3 from "ink-select-input";
|
|
1536
1572
|
function RewindSelector({ messages, onSelect, onCancel }) {
|
|
1537
|
-
const [step, setStep] =
|
|
1538
|
-
const [selectedMessageIndex, setSelectedMessageIndex] =
|
|
1573
|
+
const [step, setStep] = useState5("selection");
|
|
1574
|
+
const [selectedMessageIndex, setSelectedMessageIndex] = useState5(null);
|
|
1539
1575
|
useInput4((input, key) => {
|
|
1540
1576
|
if (key.escape) {
|
|
1541
1577
|
if (step === "confirmation") {
|
|
@@ -1599,12 +1635,12 @@ function RewindSelector({ messages, onSelect, onCancel }) {
|
|
|
1599
1635
|
}
|
|
1600
1636
|
|
|
1601
1637
|
// src/components/SessionSelector.tsx
|
|
1602
|
-
import React15, { useState as
|
|
1638
|
+
import React15, { useState as useState6 } from "react";
|
|
1603
1639
|
import { Box as Box14, Text as Text14, useInput as useInput5 } from "ink";
|
|
1604
1640
|
import SelectInput4 from "ink-select-input";
|
|
1605
1641
|
function SessionSelector({ sessions, currentSession, onSelect, onCancel }) {
|
|
1606
|
-
const [step, setStep] =
|
|
1607
|
-
const [selectedSession, setSelectedSession] =
|
|
1642
|
+
const [step, setStep] = useState6("selection");
|
|
1643
|
+
const [selectedSession, setSelectedSession] = useState6(null);
|
|
1608
1644
|
useInput5((input, key) => {
|
|
1609
1645
|
if (key.escape) {
|
|
1610
1646
|
if (step === "confirmation") {
|
|
@@ -1662,7 +1698,7 @@ function SessionSelector({ sessions, currentSession, onSelect, onCancel }) {
|
|
|
1662
1698
|
}
|
|
1663
1699
|
|
|
1664
1700
|
// src/components/LoginFlow.tsx
|
|
1665
|
-
import React16, { useState as
|
|
1701
|
+
import React16, { useState as useState7, useEffect as useEffect2 } from "react";
|
|
1666
1702
|
import { Box as Box15, Text as Text15 } from "ink";
|
|
1667
1703
|
import Spinner2 from "ink-spinner";
|
|
1668
1704
|
import jwt from "jsonwebtoken";
|
|
@@ -1779,10 +1815,10 @@ var OAuthClient = class {
|
|
|
1779
1815
|
|
|
1780
1816
|
// src/components/LoginFlow.tsx
|
|
1781
1817
|
function LoginFlow({ apiUrl = "http://localhost:3000", configStore, onSuccess, onError }) {
|
|
1782
|
-
const [status, setStatus] =
|
|
1783
|
-
const [deviceFlow, setDeviceFlow] =
|
|
1784
|
-
const [statusMessage, setStatusMessage] =
|
|
1785
|
-
const [error, setError] =
|
|
1818
|
+
const [status, setStatus] = useState7("initiating");
|
|
1819
|
+
const [deviceFlow, setDeviceFlow] = useState7(null);
|
|
1820
|
+
const [statusMessage, setStatusMessage] = useState7("Initiating device authorization...");
|
|
1821
|
+
const [error, setError] = useState7(null);
|
|
1786
1822
|
useEffect2(() => {
|
|
1787
1823
|
const runLoginFlow = async () => {
|
|
1788
1824
|
const oauth = new OAuthClient(apiUrl);
|
|
@@ -9685,6 +9721,7 @@ var Logger2 = class _Logger {
|
|
|
9685
9721
|
}
|
|
9686
9722
|
};
|
|
9687
9723
|
var logger = Logger2.getInstance();
|
|
9724
|
+
logger.setVerbose(process.env.B4M_VERBOSE === "1");
|
|
9688
9725
|
|
|
9689
9726
|
// src/llm/ServerToolExecutor.ts
|
|
9690
9727
|
var ServerToolExecutor = class {
|
|
@@ -11113,7 +11150,7 @@ import { isAxiosError as isAxiosError2 } from "axios";
|
|
|
11113
11150
|
// package.json
|
|
11114
11151
|
var package_default = {
|
|
11115
11152
|
name: "@bike4mind/cli",
|
|
11116
|
-
version: "0.2.10-fix-b4m-cli-flicker.
|
|
11153
|
+
version: "0.2.10-fix-b4m-cli-flicker.17243+cbbca593a",
|
|
11117
11154
|
type: "module",
|
|
11118
11155
|
description: "Interactive CLI tool for Bike4Mind with ReAct agents",
|
|
11119
11156
|
license: "UNLICENSED",
|
|
@@ -11216,10 +11253,10 @@ var package_default = {
|
|
|
11216
11253
|
},
|
|
11217
11254
|
devDependencies: {
|
|
11218
11255
|
"@bike4mind/agents": "0.1.0",
|
|
11219
|
-
"@bike4mind/common": "2.39.1-fix-b4m-cli-flicker.
|
|
11220
|
-
"@bike4mind/mcp": "1.20.4-fix-b4m-cli-flicker.
|
|
11221
|
-
"@bike4mind/services": "2.34.2-fix-b4m-cli-flicker.
|
|
11222
|
-
"@bike4mind/utils": "2.1.4-fix-b4m-cli-flicker.
|
|
11256
|
+
"@bike4mind/common": "2.39.1-fix-b4m-cli-flicker.17243+cbbca593a",
|
|
11257
|
+
"@bike4mind/mcp": "1.20.4-fix-b4m-cli-flicker.17243+cbbca593a",
|
|
11258
|
+
"@bike4mind/services": "2.34.2-fix-b4m-cli-flicker.17243+cbbca593a",
|
|
11259
|
+
"@bike4mind/utils": "2.1.4-fix-b4m-cli-flicker.17243+cbbca593a",
|
|
11223
11260
|
"@types/better-sqlite3": "^7.6.13",
|
|
11224
11261
|
"@types/diff": "^5.0.9",
|
|
11225
11262
|
"@types/jsonwebtoken": "^9.0.4",
|
|
@@ -11232,7 +11269,7 @@ var package_default = {
|
|
|
11232
11269
|
typescript: "^5.9.3",
|
|
11233
11270
|
vitest: "^3.2.4"
|
|
11234
11271
|
},
|
|
11235
|
-
gitHead: "
|
|
11272
|
+
gitHead: "cbbca593a8f5107d0ff9ca4a7911de7616a61a91"
|
|
11236
11273
|
};
|
|
11237
11274
|
|
|
11238
11275
|
// src/config/constants.ts
|
|
@@ -11254,7 +11291,7 @@ var usageCache = null;
|
|
|
11254
11291
|
function CliApp() {
|
|
11255
11292
|
const { exit } = useApp();
|
|
11256
11293
|
const imageRenderer = new ImageRenderer();
|
|
11257
|
-
const [state, setState] =
|
|
11294
|
+
const [state, setState] = useState8({
|
|
11258
11295
|
session: null,
|
|
11259
11296
|
sessionStore: new SessionStore(),
|
|
11260
11297
|
configStore: new ConfigStore(),
|
|
@@ -11271,10 +11308,10 @@ function CliApp() {
|
|
|
11271
11308
|
rewindSelector: null,
|
|
11272
11309
|
sessionSelector: null
|
|
11273
11310
|
});
|
|
11274
|
-
const [isInitialized, setIsInitialized] =
|
|
11275
|
-
const [initError, setInitError] =
|
|
11276
|
-
const [commandHistory, setCommandHistory] =
|
|
11277
|
-
const imageStoreInitPromise =
|
|
11311
|
+
const [isInitialized, setIsInitialized] = useState8(false);
|
|
11312
|
+
const [initError, setInitError] = useState8(null);
|
|
11313
|
+
const [commandHistory, setCommandHistory] = useState8([]);
|
|
11314
|
+
const imageStoreInitPromise = useRef2(null);
|
|
11278
11315
|
const setStoreSession = useCliStore((state2) => state2.setSession);
|
|
11279
11316
|
const setPermissionPrompt = useCliStore((state2) => state2.setPermissionPrompt);
|
|
11280
11317
|
const setShowConfigEditor = useCliStore((state2) => state2.setShowConfigEditor);
|
|
@@ -11396,13 +11433,11 @@ function CliApp() {
|
|
|
11396
11433
|
if (models.length === 0) {
|
|
11397
11434
|
throw new Error("No models available from server.");
|
|
11398
11435
|
}
|
|
11399
|
-
|
|
11436
|
+
logger.debug(`\u{1F4CB} Available models: ${models.map((m) => m.id).join(", ")}`);
|
|
11400
11437
|
const modelInfo = models.find((m) => m.id === config.defaultModel) || models[0];
|
|
11401
11438
|
if (modelInfo.id !== config.defaultModel) {
|
|
11402
|
-
|
|
11403
|
-
|
|
11404
|
-
} else {
|
|
11405
|
-
console.log(`\u{1F916} Using model: ${modelInfo.id}`);
|
|
11439
|
+
logger.warn(`\u26A0\uFE0F Requested model '${config.defaultModel}' not available`);
|
|
11440
|
+
logger.warn(`\u{1F916} Using fallback model: ${modelInfo.id}`);
|
|
11406
11441
|
}
|
|
11407
11442
|
llm.currentModel = modelInfo.id;
|
|
11408
11443
|
const newSession = {
|
|
@@ -11421,9 +11456,6 @@ function CliApp() {
|
|
|
11421
11456
|
};
|
|
11422
11457
|
await logger.initialize(newSession.id);
|
|
11423
11458
|
logger.setVerbose(process.env.B4M_VERBOSE === "1");
|
|
11424
|
-
logger.info(`API: ${apiBaseURL}`);
|
|
11425
|
-
logger.info(`Environment: ${envName}`);
|
|
11426
|
-
logger.info(`Model: ${modelInfo.id}`);
|
|
11427
11459
|
logger.debug("=== Session Configuration Complete ===");
|
|
11428
11460
|
logger.cleanupOldLogs().catch(() => {
|
|
11429
11461
|
});
|
|
@@ -11472,7 +11504,7 @@ function CliApp() {
|
|
|
11472
11504
|
state.configStore,
|
|
11473
11505
|
apiClient
|
|
11474
11506
|
);
|
|
11475
|
-
console.log(`\u{1F6E0}\uFE0F
|
|
11507
|
+
console.log(`\u{1F6E0}\uFE0F Loaded ${b4mTools.length} B4M tool(s)`);
|
|
11476
11508
|
const mcpManager = new McpManager(config);
|
|
11477
11509
|
await mcpManager.initialize();
|
|
11478
11510
|
const mcpTools = mcpManager.getTools();
|
|
@@ -11483,7 +11515,6 @@ function CliApp() {
|
|
|
11483
11515
|
});
|
|
11484
11516
|
}
|
|
11485
11517
|
const allTools = [...b4mTools, ...mcpTools];
|
|
11486
|
-
console.log(`\u2705 Total: ${allTools.length} tool(s) available`);
|
|
11487
11518
|
const projectDir = state.configStore.getProjectConfigDir();
|
|
11488
11519
|
const contextResult = await loadContextFiles(projectDir);
|
|
11489
11520
|
if (contextResult.globalContext) {
|
|
@@ -11559,6 +11590,7 @@ Remember: Use context from previous messages to understand follow-up questions.$
|
|
|
11559
11590
|
}));
|
|
11560
11591
|
setStoreSession(newSession);
|
|
11561
11592
|
setIsInitialized(true);
|
|
11593
|
+
console.log("\n");
|
|
11562
11594
|
} catch (error) {
|
|
11563
11595
|
console.error("Initialization error:", error);
|
|
11564
11596
|
setInitError(error instanceof Error ? error.message : "Unknown error");
|
|
@@ -11687,6 +11719,46 @@ Remember: Use context from previous messages to understand follow-up questions.$
|
|
|
11687
11719
|
state.agent.off("action", stepHandler);
|
|
11688
11720
|
}
|
|
11689
11721
|
};
|
|
11722
|
+
const handleBashCommand = useCallback(
|
|
11723
|
+
(command) => {
|
|
11724
|
+
if (!state.session) return;
|
|
11725
|
+
let output;
|
|
11726
|
+
let isError = false;
|
|
11727
|
+
try {
|
|
11728
|
+
output = execSync(command, {
|
|
11729
|
+
encoding: "utf-8",
|
|
11730
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
11731
|
+
cwd: process.cwd(),
|
|
11732
|
+
maxBuffer: 10 * 1024 * 1024
|
|
11733
|
+
// 10MB buffer
|
|
11734
|
+
});
|
|
11735
|
+
} catch (error) {
|
|
11736
|
+
const execError = error;
|
|
11737
|
+
output = execError.stderr || execError.message || "Command failed";
|
|
11738
|
+
isError = true;
|
|
11739
|
+
}
|
|
11740
|
+
const userMessage = {
|
|
11741
|
+
role: "user",
|
|
11742
|
+
content: `$ ${command}`,
|
|
11743
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
11744
|
+
};
|
|
11745
|
+
const assistantMessage = {
|
|
11746
|
+
role: "assistant",
|
|
11747
|
+
content: isError ? `\u274C Error:
|
|
11748
|
+
${output}` : output.trim() || "(no output)",
|
|
11749
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
11750
|
+
};
|
|
11751
|
+
const updatedSession = {
|
|
11752
|
+
...state.session,
|
|
11753
|
+
messages: [...state.session.messages, userMessage, assistantMessage],
|
|
11754
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
11755
|
+
};
|
|
11756
|
+
setState((prev) => ({ ...prev, session: updatedSession }));
|
|
11757
|
+
setStoreSession(updatedSession);
|
|
11758
|
+
state.sessionStore.save(updatedSession);
|
|
11759
|
+
},
|
|
11760
|
+
[state.session, state.sessionStore]
|
|
11761
|
+
);
|
|
11690
11762
|
const handleImageDetected = async (imageData) => {
|
|
11691
11763
|
try {
|
|
11692
11764
|
let imageStore = state.imageStore;
|
|
@@ -12359,6 +12431,7 @@ No usage data available for the last ${USAGE_DAYS} days.`);
|
|
|
12359
12431
|
{
|
|
12360
12432
|
onMessage: handleMessage,
|
|
12361
12433
|
onCommand: handleCommand,
|
|
12434
|
+
onBashCommand: handleBashCommand,
|
|
12362
12435
|
onImageDetected: handleImageDetected,
|
|
12363
12436
|
commandHistory,
|
|
12364
12437
|
config: state.config,
|
|
@@ -12387,11 +12460,11 @@ var BANNER = `
|
|
|
12387
12460
|
\u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D
|
|
12388
12461
|
`;
|
|
12389
12462
|
console.log("\x1B[36m\x1B[1m%s\x1B[0m", BANNER);
|
|
12390
|
-
console.log(`\x1B[2m v${package_default.version} - AI-Powered CLI\x1B[0m
|
|
12391
|
-
|
|
12463
|
+
console.log(`\x1B[2m v${package_default.version} - AI-Powered CLI\x1B[0m`);
|
|
12464
|
+
console.log(" /help for more information\n");
|
|
12392
12465
|
var isDevMode = import.meta.url.includes("/src/") || process.env.NODE_ENV === "development";
|
|
12393
12466
|
if (isDevMode) {
|
|
12394
|
-
|
|
12467
|
+
logger.debug("\u{1F527} Running in development mode (using TypeScript source)\n");
|
|
12395
12468
|
}
|
|
12396
12469
|
render(/* @__PURE__ */ React17.createElement(CliApp, null), {
|
|
12397
12470
|
exitOnCtrlC: false
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bike4mind/cli",
|
|
3
|
-
"version": "0.2.10-fix-b4m-cli-flicker.
|
|
3
|
+
"version": "0.2.10-fix-b4m-cli-flicker.17243+cbbca593a",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Interactive CLI tool for Bike4Mind with ReAct agents",
|
|
6
6
|
"license": "UNLICENSED",
|
|
@@ -103,10 +103,10 @@
|
|
|
103
103
|
},
|
|
104
104
|
"devDependencies": {
|
|
105
105
|
"@bike4mind/agents": "0.1.0",
|
|
106
|
-
"@bike4mind/common": "2.39.1-fix-b4m-cli-flicker.
|
|
107
|
-
"@bike4mind/mcp": "1.20.4-fix-b4m-cli-flicker.
|
|
108
|
-
"@bike4mind/services": "2.34.2-fix-b4m-cli-flicker.
|
|
109
|
-
"@bike4mind/utils": "2.1.4-fix-b4m-cli-flicker.
|
|
106
|
+
"@bike4mind/common": "2.39.1-fix-b4m-cli-flicker.17243+cbbca593a",
|
|
107
|
+
"@bike4mind/mcp": "1.20.4-fix-b4m-cli-flicker.17243+cbbca593a",
|
|
108
|
+
"@bike4mind/services": "2.34.2-fix-b4m-cli-flicker.17243+cbbca593a",
|
|
109
|
+
"@bike4mind/utils": "2.1.4-fix-b4m-cli-flicker.17243+cbbca593a",
|
|
110
110
|
"@types/better-sqlite3": "^7.6.13",
|
|
111
111
|
"@types/diff": "^5.0.9",
|
|
112
112
|
"@types/jsonwebtoken": "^9.0.4",
|
|
@@ -119,5 +119,5 @@
|
|
|
119
119
|
"typescript": "^5.9.3",
|
|
120
120
|
"vitest": "^3.2.4"
|
|
121
121
|
},
|
|
122
|
-
"gitHead": "
|
|
122
|
+
"gitHead": "cbbca593a8f5107d0ff9ca4a7911de7616a61a91"
|
|
123
123
|
}
|