@bike4mind/cli 0.2.32 → 0.2.33-chore-5822-replace-deprecated-node-http-handler.19843
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/{artifactExtractor-RYUIMC5D.js → artifactExtractor-RDISRG3L.js} +1 -1
- package/dist/{chunk-74UKS7VY.js → chunk-4CSNU5HR.js} +7 -7
- package/dist/{chunk-2EHXPCA7.js → chunk-CHZRJCRO.js} +2 -2
- package/dist/{chunk-BYXFQJYT.js → chunk-G2LYCVZJ.js} +16 -0
- package/dist/{chunk-QHCGCQ72.js → chunk-I5EHZ4OG.js} +24 -6
- package/dist/{chunk-RPIEKKLZ.js → chunk-PVTWVKQE.js} +2 -2
- package/dist/{chunk-ORRROOHQ.js → chunk-XH4U37SN.js} +2 -2
- package/dist/{chunk-32PKF3N7.js → chunk-YRTLWZV6.js} +4 -1
- package/dist/{chunk-ZOM2E3PC.js → chunk-ZH3AH7U2.js} +50 -143
- package/dist/commands/doctorCommand.js +1 -1
- package/dist/commands/mcpCommand.js +2 -1
- package/dist/commands/updateCommand.js +1 -1
- package/dist/{create-BT3CXRUU.js → create-KXXYF4E2.js} +3 -3
- package/dist/index.js +516 -216
- package/dist/{llmMarkdownGenerator-6OOBQEVD.js → llmMarkdownGenerator-5TXQGZ72.js} +1 -1
- package/dist/{markdownGenerator-GQVNEMMH.js → markdownGenerator-DMQU4VBM.js} +1 -1
- package/dist/{mementoService-WTBF5FL5.js → mementoService-MWF6F3YR.js} +3 -3
- package/dist/{src-4VYAJBH3.js → src-HLXF7YYW.js} +1 -1
- package/dist/{src-GIZDQW3O.js → src-VYBV5W37.js} +2 -2
- package/dist/{store-K5MB3SE7.js → store-X5LEOSGZ.js} +1 -1
- package/dist/{subtractCredits-4V4LSJD4.js → subtractCredits-EXDDX7JJ.js} +3 -3
- package/package.json +7 -7
package/dist/index.js
CHANGED
|
@@ -1,26 +1,26 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import "./chunk-GQGOWACU.js";
|
|
3
|
-
import "./chunk-
|
|
4
|
-
import "./chunk-
|
|
3
|
+
import "./chunk-PVTWVKQE.js";
|
|
4
|
+
import "./chunk-CHZRJCRO.js";
|
|
5
5
|
import "./chunk-BPFEGDC7.js";
|
|
6
6
|
import "./chunk-BDQBOLYG.js";
|
|
7
7
|
import {
|
|
8
8
|
getEffectiveApiKey,
|
|
9
9
|
getOpenWeatherKey,
|
|
10
10
|
getSerperKey
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-XH4U37SN.js";
|
|
12
12
|
import {
|
|
13
13
|
ConfigStore,
|
|
14
14
|
logger
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-YRTLWZV6.js";
|
|
16
16
|
import {
|
|
17
17
|
checkForUpdate,
|
|
18
18
|
package_default
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-4CSNU5HR.js";
|
|
20
20
|
import {
|
|
21
21
|
selectActiveBackgroundAgents,
|
|
22
22
|
useCliStore
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-G2LYCVZJ.js";
|
|
24
24
|
import {
|
|
25
25
|
BFLImageService,
|
|
26
26
|
BaseStorage,
|
|
@@ -32,7 +32,7 @@ import {
|
|
|
32
32
|
OpenAIBackend,
|
|
33
33
|
OpenAIImageService,
|
|
34
34
|
XAIImageService
|
|
35
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-ZH3AH7U2.js";
|
|
36
36
|
import {
|
|
37
37
|
AiEvents,
|
|
38
38
|
ApiKeyEvents,
|
|
@@ -90,21 +90,21 @@ import {
|
|
|
90
90
|
getMcpProviderMetadata,
|
|
91
91
|
getViewById,
|
|
92
92
|
resolveNavigationIntents
|
|
93
|
-
} from "./chunk-
|
|
93
|
+
} from "./chunk-I5EHZ4OG.js";
|
|
94
94
|
import {
|
|
95
95
|
Logger
|
|
96
96
|
} from "./chunk-PFBYGCOW.js";
|
|
97
97
|
|
|
98
98
|
// src/index.tsx
|
|
99
|
-
import
|
|
100
|
-
import { render, Box as
|
|
99
|
+
import React22, { useState as useState11, useEffect as useEffect7, useCallback as useCallback3, useRef as useRef3 } from "react";
|
|
100
|
+
import { render, Box as Box21, Text as Text21, useApp, useInput as useInput10 } from "ink";
|
|
101
101
|
import { execSync } from "child_process";
|
|
102
102
|
import { randomBytes as randomBytes5 } from "crypto";
|
|
103
103
|
import { v4 as uuidv413 } from "uuid";
|
|
104
104
|
|
|
105
105
|
// src/components/App.tsx
|
|
106
|
-
import
|
|
107
|
-
import { Box as
|
|
106
|
+
import React16, { useState as useState7, useEffect as useEffect5 } from "react";
|
|
107
|
+
import { Box as Box15, Text as Text15, Static, useInput as useInput7 } from "ink";
|
|
108
108
|
|
|
109
109
|
// src/components/StatusBar.tsx
|
|
110
110
|
import React from "react";
|
|
@@ -1523,9 +1523,152 @@ function PermissionPrompt({
|
|
|
1523
1523
|
return /* @__PURE__ */ React10.createElement(Box9, { flexDirection: "column", borderStyle: "bold", borderColor: "yellow", padding: 1, marginY: 1 }, /* @__PURE__ */ React10.createElement(Box9, null, /* @__PURE__ */ React10.createElement(Text9, { bold: true, color: "yellow" }, "\u26A0\uFE0F Permission Required")), /* @__PURE__ */ React10.createElement(Box9, { marginTop: 1 }, /* @__PURE__ */ React10.createElement(Text9, { dimColor: true }, "Tool: "), /* @__PURE__ */ React10.createElement(Text9, { bold: true, color: "cyan" }, toolName)), toolDescription && /* @__PURE__ */ React10.createElement(Box9, null, /* @__PURE__ */ React10.createElement(Text9, { dimColor: true }, "Action: "), /* @__PURE__ */ React10.createElement(Text9, null, toolDescription)), /* @__PURE__ */ React10.createElement(Box9, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React10.createElement(Text9, { bold: true }, "Arguments:"), /* @__PURE__ */ React10.createElement(Box9, { paddingLeft: 2, flexDirection: "column" }, /* @__PURE__ */ React10.createElement(Text9, { dimColor: true }, argsString))), preview && /* @__PURE__ */ React10.createElement(Box9, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React10.createElement(Text9, { bold: true }, "Preview:"), /* @__PURE__ */ React10.createElement(Box9, { borderStyle: "single", borderColor: "gray", paddingX: 1, flexDirection: "column" }, renderDiffPreview(preview))), !canBeTrusted && /* @__PURE__ */ React10.createElement(Box9, { marginTop: 1 }, /* @__PURE__ */ React10.createElement(Text9, { color: "red", dimColor: true }, "Note: This tool cannot be trusted due to its dangerous nature.")), /* @__PURE__ */ React10.createElement(Box9, { marginTop: 1, flexDirection: "column" }, items.map((item, index) => /* @__PURE__ */ React10.createElement(Box9, { key: item.value }, /* @__PURE__ */ React10.createElement(Text9, { color: "cyan" }, index + 1, "."), /* @__PURE__ */ React10.createElement(Text9, { color: index === selectedIndex ? "cyan" : void 0, bold: index === selectedIndex }, index === selectedIndex ? " \u276F " : " ", item.label)))), /* @__PURE__ */ React10.createElement(Box9, { marginTop: 1 }, /* @__PURE__ */ React10.createElement(Text9, { dimColor: true }, "Press 1-", items.length, ", y/n, or \u2191\u2193 + Enter")));
|
|
1524
1524
|
}
|
|
1525
1525
|
|
|
1526
|
-
// src/components/
|
|
1527
|
-
import React11, { useState as useState5,
|
|
1526
|
+
// src/components/UserQuestionPrompt.tsx
|
|
1527
|
+
import React11, { useState as useState5, useCallback as useCallback2 } from "react";
|
|
1528
1528
|
import { Box as Box10, Text as Text10, useInput as useInput4 } from "ink";
|
|
1529
|
+
import TextInput from "ink-text-input";
|
|
1530
|
+
function UserQuestionPrompt({ payload, onResponse }) {
|
|
1531
|
+
const [questionIndex, setQuestionIndex] = useState5(0);
|
|
1532
|
+
const [answers, setAnswers] = useState5([]);
|
|
1533
|
+
const [selectedIndex, setSelectedIndex] = useState5(0);
|
|
1534
|
+
const [multiSelected, setMultiSelected] = useState5(/* @__PURE__ */ new Set());
|
|
1535
|
+
const [otherText, setOtherText] = useState5("");
|
|
1536
|
+
const [done, setDone] = useState5(false);
|
|
1537
|
+
const currentQuestion = payload.questions[questionIndex];
|
|
1538
|
+
const options = [...currentQuestion.options, { label: "Other...", description: "Provide your own answer" }];
|
|
1539
|
+
const otherIndex = options.length - 1;
|
|
1540
|
+
const isMulti = currentQuestion.multiSelect;
|
|
1541
|
+
const isOnOther = selectedIndex === otherIndex;
|
|
1542
|
+
const advanceToNextQuestion = useCallback2(
|
|
1543
|
+
(answer) => {
|
|
1544
|
+
const updatedAnswers = [...answers, answer];
|
|
1545
|
+
if (questionIndex + 1 >= payload.questions.length) {
|
|
1546
|
+
setDone(true);
|
|
1547
|
+
onResponse({ answers: updatedAnswers });
|
|
1548
|
+
} else {
|
|
1549
|
+
setAnswers(updatedAnswers);
|
|
1550
|
+
setQuestionIndex(questionIndex + 1);
|
|
1551
|
+
setSelectedIndex(0);
|
|
1552
|
+
setMultiSelected(/* @__PURE__ */ new Set());
|
|
1553
|
+
setOtherText("");
|
|
1554
|
+
}
|
|
1555
|
+
},
|
|
1556
|
+
[answers, questionIndex, payload.questions.length, onResponse]
|
|
1557
|
+
);
|
|
1558
|
+
const submitOther = useCallback2(() => {
|
|
1559
|
+
if (done) return;
|
|
1560
|
+
const text = otherText.trim();
|
|
1561
|
+
if (!text) return;
|
|
1562
|
+
if (isMulti) {
|
|
1563
|
+
const selected = Array.from(multiSelected).filter((i) => i !== otherIndex).map((i) => options[i].label);
|
|
1564
|
+
selected.push(text);
|
|
1565
|
+
advanceToNextQuestion({ question: currentQuestion.question, selected });
|
|
1566
|
+
} else {
|
|
1567
|
+
advanceToNextQuestion({ question: currentQuestion.question, selected: [text] });
|
|
1568
|
+
}
|
|
1569
|
+
}, [done, otherText, isMulti, multiSelected, otherIndex, options, currentQuestion, advanceToNextQuestion]);
|
|
1570
|
+
const confirmSelection = useCallback2(() => {
|
|
1571
|
+
if (done) return;
|
|
1572
|
+
if (isMulti) {
|
|
1573
|
+
const selected = Array.from(multiSelected).filter((i) => i !== otherIndex).map((i) => options[i].label);
|
|
1574
|
+
if (multiSelected.has(otherIndex) && otherText.trim()) {
|
|
1575
|
+
selected.push(otherText.trim());
|
|
1576
|
+
}
|
|
1577
|
+
if (selected.length === 0) return;
|
|
1578
|
+
advanceToNextQuestion({ question: currentQuestion.question, selected });
|
|
1579
|
+
} else if (isOnOther) {
|
|
1580
|
+
submitOther();
|
|
1581
|
+
} else {
|
|
1582
|
+
advanceToNextQuestion({
|
|
1583
|
+
question: currentQuestion.question,
|
|
1584
|
+
selected: [options[selectedIndex].label]
|
|
1585
|
+
});
|
|
1586
|
+
}
|
|
1587
|
+
}, [
|
|
1588
|
+
done,
|
|
1589
|
+
isMulti,
|
|
1590
|
+
multiSelected,
|
|
1591
|
+
selectedIndex,
|
|
1592
|
+
otherIndex,
|
|
1593
|
+
isOnOther,
|
|
1594
|
+
options,
|
|
1595
|
+
otherText,
|
|
1596
|
+
currentQuestion,
|
|
1597
|
+
advanceToNextQuestion,
|
|
1598
|
+
submitOther
|
|
1599
|
+
]);
|
|
1600
|
+
useInput4(
|
|
1601
|
+
(input, key) => {
|
|
1602
|
+
if (done) return;
|
|
1603
|
+
if (key.upArrow) {
|
|
1604
|
+
setSelectedIndex((i) => i > 0 ? i - 1 : options.length - 1);
|
|
1605
|
+
return;
|
|
1606
|
+
}
|
|
1607
|
+
if (key.downArrow) {
|
|
1608
|
+
setSelectedIndex((i) => i < options.length - 1 ? i + 1 : 0);
|
|
1609
|
+
return;
|
|
1610
|
+
}
|
|
1611
|
+
if (isOnOther) {
|
|
1612
|
+
if (key.return) {
|
|
1613
|
+
confirmSelection();
|
|
1614
|
+
}
|
|
1615
|
+
return;
|
|
1616
|
+
}
|
|
1617
|
+
const num = parseInt(input, 10);
|
|
1618
|
+
if (num >= 1 && num <= options.length) {
|
|
1619
|
+
const idx = num - 1;
|
|
1620
|
+
if (isMulti) {
|
|
1621
|
+
setMultiSelected((prev) => {
|
|
1622
|
+
const next = new Set(prev);
|
|
1623
|
+
if (next.has(idx)) next.delete(idx);
|
|
1624
|
+
else next.add(idx);
|
|
1625
|
+
return next;
|
|
1626
|
+
});
|
|
1627
|
+
setSelectedIndex(idx);
|
|
1628
|
+
} else if (idx === otherIndex) {
|
|
1629
|
+
setSelectedIndex(idx);
|
|
1630
|
+
} else {
|
|
1631
|
+
advanceToNextQuestion({
|
|
1632
|
+
question: currentQuestion.question,
|
|
1633
|
+
selected: [options[idx].label]
|
|
1634
|
+
});
|
|
1635
|
+
}
|
|
1636
|
+
return;
|
|
1637
|
+
}
|
|
1638
|
+
if (input === " " && isMulti) {
|
|
1639
|
+
setMultiSelected((prev) => {
|
|
1640
|
+
const next = new Set(prev);
|
|
1641
|
+
if (next.has(selectedIndex)) next.delete(selectedIndex);
|
|
1642
|
+
else next.add(selectedIndex);
|
|
1643
|
+
return next;
|
|
1644
|
+
});
|
|
1645
|
+
} else if (key.return) {
|
|
1646
|
+
confirmSelection();
|
|
1647
|
+
}
|
|
1648
|
+
},
|
|
1649
|
+
{ isActive: !done }
|
|
1650
|
+
);
|
|
1651
|
+
if (done) return null;
|
|
1652
|
+
const totalQuestions = payload.questions.length;
|
|
1653
|
+
return /* @__PURE__ */ React11.createElement(Box10, { flexDirection: "column", borderStyle: "bold", borderColor: "cyan", padding: 1, marginY: 1 }, /* @__PURE__ */ React11.createElement(Box10, null, /* @__PURE__ */ React11.createElement(Text10, { bold: true, color: "cyan" }, "? Question", totalQuestions > 1 ? ` ${questionIndex + 1}/${totalQuestions}` : "")), /* @__PURE__ */ React11.createElement(Box10, { marginTop: 1 }, /* @__PURE__ */ React11.createElement(Text10, { bold: true }, currentQuestion.question)), /* @__PURE__ */ React11.createElement(Box10, { marginTop: 1, flexDirection: "column" }, options.map((opt, idx) => {
|
|
1654
|
+
const isHighlighted = idx === selectedIndex;
|
|
1655
|
+
const isToggled = isMulti && multiSelected.has(idx);
|
|
1656
|
+
const prefix = isMulti ? isToggled ? "[x]" : "[ ]" : isHighlighted ? " > " : " ";
|
|
1657
|
+
return /* @__PURE__ */ React11.createElement(Box10, { key: idx }, /* @__PURE__ */ React11.createElement(Text10, { color: "cyan" }, idx + 1, "."), /* @__PURE__ */ React11.createElement(Text10, { color: isHighlighted ? "cyan" : void 0, bold: isHighlighted }, " ", prefix, " ", opt.label), idx === otherIndex && isHighlighted ? /* @__PURE__ */ React11.createElement(Box10, { marginLeft: 1 }, /* @__PURE__ */ React11.createElement(
|
|
1658
|
+
TextInput,
|
|
1659
|
+
{
|
|
1660
|
+
value: otherText,
|
|
1661
|
+
onChange: setOtherText,
|
|
1662
|
+
onSubmit: submitOther,
|
|
1663
|
+
placeholder: "Type your answer..."
|
|
1664
|
+
}
|
|
1665
|
+
)) : opt.description && idx !== otherIndex && /* @__PURE__ */ React11.createElement(Text10, { dimColor: true }, " - ", opt.description));
|
|
1666
|
+
})), /* @__PURE__ */ React11.createElement(Box10, { marginTop: 1 }, /* @__PURE__ */ React11.createElement(Text10, { dimColor: true }, isOnOther ? "Type your answer, Enter to submit, or arrow keys to go back" : isMulti ? "Press 1-" + options.length + ", Space to toggle, Enter to confirm" : "Press 1-" + options.length + ", or arrow keys + Enter")));
|
|
1667
|
+
}
|
|
1668
|
+
|
|
1669
|
+
// src/components/ConfigEditor.tsx
|
|
1670
|
+
import React12, { useState as useState6, useMemo as useMemo3 } from "react";
|
|
1671
|
+
import { Box as Box11, Text as Text11, useInput as useInput5 } from "ink";
|
|
1529
1672
|
var MAX_ITERATIONS_OPTIONS = [
|
|
1530
1673
|
{ label: "10", value: 10 },
|
|
1531
1674
|
{ label: "20", value: 20 },
|
|
@@ -1669,10 +1812,10 @@ function buildConfigItems(availableModels) {
|
|
|
1669
1812
|
return items;
|
|
1670
1813
|
}
|
|
1671
1814
|
function ConfigEditor({ config, availableModels, onSave, onClose }) {
|
|
1672
|
-
const [selectedIndex, setSelectedIndex] =
|
|
1673
|
-
const [editedConfig, setEditedConfig] =
|
|
1674
|
-
const [saveError, setSaveError] =
|
|
1675
|
-
const [isSaving, setIsSaving] =
|
|
1815
|
+
const [selectedIndex, setSelectedIndex] = useState6(0);
|
|
1816
|
+
const [editedConfig, setEditedConfig] = useState6(config);
|
|
1817
|
+
const [saveError, setSaveError] = useState6(null);
|
|
1818
|
+
const [isSaving, setIsSaving] = useState6(false);
|
|
1676
1819
|
const configItems = useMemo3(() => buildConfigItems(availableModels), [availableModels]);
|
|
1677
1820
|
const hasChanges = useMemo3(() => {
|
|
1678
1821
|
return JSON.stringify(config.preferences) !== JSON.stringify(editedConfig.preferences) || config.defaultModel !== editedConfig.defaultModel;
|
|
@@ -1692,7 +1835,7 @@ function ConfigEditor({ config, availableModels, onSave, onClose }) {
|
|
|
1692
1835
|
}
|
|
1693
1836
|
onClose();
|
|
1694
1837
|
};
|
|
1695
|
-
|
|
1838
|
+
useInput5((input, key) => {
|
|
1696
1839
|
const currentItem = configItems[selectedIndex];
|
|
1697
1840
|
if (key.upArrow) {
|
|
1698
1841
|
setSelectedIndex((prev) => prev > 0 ? prev - 1 : configItems.length - 1);
|
|
@@ -1757,33 +1900,33 @@ function ConfigEditor({ config, availableModels, onSave, onClose }) {
|
|
|
1757
1900
|
}
|
|
1758
1901
|
return String(value);
|
|
1759
1902
|
};
|
|
1760
|
-
return /* @__PURE__ */
|
|
1903
|
+
return /* @__PURE__ */ React12.createElement(Box11, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 2, paddingY: 1, marginY: 1 }, /* @__PURE__ */ React12.createElement(Box11, { justifyContent: "space-between", marginBottom: 1 }, /* @__PURE__ */ React12.createElement(Text11, { bold: true, color: "cyan" }, "Settings"), isSaving ? /* @__PURE__ */ React12.createElement(Text11, { color: "yellow" }, "Saving...") : hasChanges ? /* @__PURE__ */ React12.createElement(Text11, { dimColor: true, color: "yellow" }, "(unsaved changes)") : null), saveError && /* @__PURE__ */ React12.createElement(Box11, { marginBottom: 1 }, /* @__PURE__ */ React12.createElement(Text11, { color: "red" }, "Error: ", saveError)), /* @__PURE__ */ React12.createElement(Box11, { flexDirection: "column", marginBottom: 1 }, configItems.map((item, index) => {
|
|
1761
1904
|
const isSelected = index === selectedIndex;
|
|
1762
1905
|
const value = item.getValue(editedConfig);
|
|
1763
1906
|
const displayValue = formatValue(item, value);
|
|
1764
1907
|
const hasOptions = item.type === "select" || item.type === "boolean" || item.type === "number";
|
|
1765
|
-
return /* @__PURE__ */
|
|
1766
|
-
})), /* @__PURE__ */
|
|
1908
|
+
return /* @__PURE__ */ React12.createElement(Box11, { key: item.key }, /* @__PURE__ */ React12.createElement(Text11, { color: isSelected ? "cyan" : void 0 }, isSelected ? "> " : " "), /* @__PURE__ */ React12.createElement(Box11, { width: 18 }, /* @__PURE__ */ React12.createElement(Text11, { bold: isSelected, color: isSelected ? "white" : "gray" }, item.label, ":")), /* @__PURE__ */ React12.createElement(Box11, null, hasOptions && isSelected && /* @__PURE__ */ React12.createElement(Text11, { dimColor: true }, "< "), /* @__PURE__ */ React12.createElement(Text11, { bold: isSelected, color: isSelected ? "green" : void 0 }, displayValue), hasOptions && isSelected && /* @__PURE__ */ React12.createElement(Text11, { dimColor: true }, " >")));
|
|
1909
|
+
})), /* @__PURE__ */ React12.createElement(Box11, { borderStyle: "single", borderColor: "gray", paddingX: 1 }, /* @__PURE__ */ React12.createElement(Text11, { dimColor: true }, "\u2191/\u2193: Navigate | Space/\u2190/\u2192: Change | q/Esc: Save & Exit")));
|
|
1767
1910
|
}
|
|
1768
1911
|
|
|
1769
1912
|
// src/components/McpViewer.tsx
|
|
1770
|
-
import
|
|
1771
|
-
import { Box as
|
|
1913
|
+
import React13 from "react";
|
|
1914
|
+
import { Box as Box12, Text as Text12, useInput as useInput6 } from "ink";
|
|
1772
1915
|
function McpViewer({ config, mcpManager, onClose }) {
|
|
1773
|
-
|
|
1916
|
+
useInput6((input, key) => {
|
|
1774
1917
|
if (key.escape || input === "q") {
|
|
1775
1918
|
onClose();
|
|
1776
1919
|
}
|
|
1777
1920
|
});
|
|
1778
1921
|
if (config.mcpServers.length === 0) {
|
|
1779
|
-
return /* @__PURE__ */
|
|
1922
|
+
return /* @__PURE__ */ React13.createElement(Box12, { flexDirection: "column", paddingX: 2, paddingY: 1 }, /* @__PURE__ */ React13.createElement(Box12, { marginBottom: 1 }, /* @__PURE__ */ React13.createElement(Text12, { bold: true, color: "cyan" }, "\u{1F4E1} MCP Server Status")), /* @__PURE__ */ React13.createElement(Text12, { dimColor: true }, "No MCP servers configured."), /* @__PURE__ */ React13.createElement(Box12, { marginTop: 1 }, /* @__PURE__ */ React13.createElement(Text12, { dimColor: true }, "To add MCP servers, edit your config file:")), /* @__PURE__ */ React13.createElement(Text12, { dimColor: true }, " Global: ~/.bike4mind/config.json"), /* @__PURE__ */ React13.createElement(Text12, { dimColor: true }, " Project: .bike4mind/config.json"), /* @__PURE__ */ React13.createElement(Box12, { marginTop: 2 }, /* @__PURE__ */ React13.createElement(Text12, { dimColor: true, italic: true }, "Press Esc or q to close")));
|
|
1780
1923
|
}
|
|
1781
1924
|
const enabledServers = config.mcpServers.filter((s) => s.enabled);
|
|
1782
|
-
return /* @__PURE__ */
|
|
1925
|
+
return /* @__PURE__ */ React13.createElement(Box12, { flexDirection: "column", paddingX: 2, paddingY: 1 }, /* @__PURE__ */ React13.createElement(Box12, { marginBottom: 1 }, /* @__PURE__ */ React13.createElement(Text12, { bold: true, color: "cyan" }, "\u{1F4E1} MCP Server Status")), /* @__PURE__ */ React13.createElement(Box12, { flexDirection: "column", marginBottom: 2 }, /* @__PURE__ */ React13.createElement(Text12, { bold: true, dimColor: true }, "Configured Servers:"), config.mcpServers.map((server) => {
|
|
1783
1926
|
const status = server.enabled ? "\u2705 Enabled" : "\u23F8\uFE0F Disabled";
|
|
1784
1927
|
const commandInfo = server.command ? `${server.command} ${(server.args || []).join(" ")}` : "(internal)";
|
|
1785
|
-
return /* @__PURE__ */
|
|
1786
|
-
})), enabledServers.length > 0 && mcpManager && /* @__PURE__ */
|
|
1928
|
+
return /* @__PURE__ */ React13.createElement(Box12, { key: server.name, flexDirection: "column", marginTop: 1, marginLeft: 2 }, /* @__PURE__ */ React13.createElement(Text12, null, "\u2022 ", /* @__PURE__ */ React13.createElement(Text12, { bold: true }, server.name), " - ", /* @__PURE__ */ React13.createElement(Text12, { dimColor: true }, status)), /* @__PURE__ */ React13.createElement(Text12, { dimColor: true }, " Command: ", commandInfo), Object.keys(server.env).length > 0 && /* @__PURE__ */ React13.createElement(Text12, { dimColor: true }, " Env vars: ", Object.keys(server.env).join(", ")));
|
|
1929
|
+
})), enabledServers.length > 0 && mcpManager && /* @__PURE__ */ React13.createElement(Box12, { flexDirection: "column", marginBottom: 2 }, /* @__PURE__ */ React13.createElement(Text12, { bold: true, dimColor: true }, "Connection Status:"), enabledServers.map((server) => {
|
|
1787
1930
|
const state = mcpManager.getConnectionState(server.name);
|
|
1788
1931
|
let icon;
|
|
1789
1932
|
let statusText;
|
|
@@ -1813,30 +1956,30 @@ function McpViewer({ config, mcpManager, onClose }) {
|
|
|
1813
1956
|
const serverTools = toolCounts.find((t) => t.serverName === server.name);
|
|
1814
1957
|
const toolCount = serverTools?.count || 0;
|
|
1815
1958
|
const toolInfo = state === "connected" && toolCount > 0 ? ` (${toolCount} tool${toolCount === 1 ? "" : "s"})` : "";
|
|
1816
|
-
return /* @__PURE__ */
|
|
1817
|
-
}), /* @__PURE__ */
|
|
1959
|
+
return /* @__PURE__ */ React13.createElement(Box12, { key: server.name, marginTop: 1, marginLeft: 2 }, /* @__PURE__ */ React13.createElement(Text12, null, "\u2022 ", /* @__PURE__ */ React13.createElement(Text12, { bold: true }, server.name), " \xB7 ", /* @__PURE__ */ React13.createElement(Text12, { color }, icon), " ", /* @__PURE__ */ React13.createElement(Text12, { color }, statusText), toolInfo && /* @__PURE__ */ React13.createElement(Text12, { dimColor: true }, toolInfo)));
|
|
1960
|
+
}), /* @__PURE__ */ React13.createElement(Box12, { marginTop: 1, marginLeft: 2 }, (() => {
|
|
1818
1961
|
const toolCounts = mcpManager.getToolCount();
|
|
1819
1962
|
const totalTools = toolCounts.reduce((sum2, s) => sum2 + s.count, 0);
|
|
1820
1963
|
if (totalTools > 0) {
|
|
1821
|
-
return /* @__PURE__ */
|
|
1964
|
+
return /* @__PURE__ */ React13.createElement(Text12, { bold: true, color: "green" }, "Total: ", totalTools, " MCP tool", totalTools === 1 ? "" : "s", " available");
|
|
1822
1965
|
} else {
|
|
1823
|
-
return /* @__PURE__ */
|
|
1966
|
+
return /* @__PURE__ */ React13.createElement(Text12, { dimColor: true }, "No MCP tools available yet (servers still connecting)");
|
|
1824
1967
|
}
|
|
1825
|
-
})())), enabledServers.length === 0 && /* @__PURE__ */
|
|
1968
|
+
})())), enabledServers.length === 0 && /* @__PURE__ */ React13.createElement(Box12, { marginBottom: 2 }, /* @__PURE__ */ React13.createElement(Text12, { color: "yellow" }, "\u26A0\uFE0F No MCP servers enabled"), /* @__PURE__ */ React13.createElement(Text12, { dimColor: true }, " Use `b4m mcp enable ", "<name>", "` to enable a server")), /* @__PURE__ */ React13.createElement(Box12, { marginTop: 1 }, /* @__PURE__ */ React13.createElement(Text12, { dimColor: true, italic: true }, "Press Esc or q to close")));
|
|
1826
1969
|
}
|
|
1827
1970
|
|
|
1828
1971
|
// src/components/MessageItem.tsx
|
|
1829
|
-
import
|
|
1830
|
-
import { Box as
|
|
1972
|
+
import React15 from "react";
|
|
1973
|
+
import { Box as Box14, Text as Text14 } from "ink";
|
|
1831
1974
|
|
|
1832
1975
|
// src/components/MarkdownRenderer.tsx
|
|
1833
|
-
import
|
|
1834
|
-
import { Box as
|
|
1976
|
+
import React14 from "react";
|
|
1977
|
+
import { Box as Box13, Text as Text13 } from "ink";
|
|
1835
1978
|
import { marked } from "marked";
|
|
1836
1979
|
import { highlight } from "cli-highlight";
|
|
1837
1980
|
function MarkdownRenderer({ content }) {
|
|
1838
1981
|
const tokens = marked.lexer(content);
|
|
1839
|
-
return /* @__PURE__ */
|
|
1982
|
+
return /* @__PURE__ */ React14.createElement(Box13, { flexDirection: "column" }, tokens.map((token, idx) => renderToken(token, idx)));
|
|
1840
1983
|
}
|
|
1841
1984
|
function renderToken(token, idx) {
|
|
1842
1985
|
switch (token.type) {
|
|
@@ -1851,12 +1994,12 @@ function renderToken(token, idx) {
|
|
|
1851
1994
|
case "blockquote":
|
|
1852
1995
|
return renderBlockquote(token, idx);
|
|
1853
1996
|
case "hr":
|
|
1854
|
-
return /* @__PURE__ */
|
|
1997
|
+
return /* @__PURE__ */ React14.createElement(Text13, { key: idx, dimColor: true }, "\u2500".repeat(50));
|
|
1855
1998
|
case "space":
|
|
1856
1999
|
return null;
|
|
1857
2000
|
default:
|
|
1858
2001
|
if ("text" in token) {
|
|
1859
|
-
return /* @__PURE__ */
|
|
2002
|
+
return /* @__PURE__ */ React14.createElement(Text13, { key: idx }, token.text);
|
|
1860
2003
|
}
|
|
1861
2004
|
return null;
|
|
1862
2005
|
}
|
|
@@ -1871,7 +2014,7 @@ function renderHeading(token, idx) {
|
|
|
1871
2014
|
6: "white"
|
|
1872
2015
|
};
|
|
1873
2016
|
const color = colors[token.depth] || "white";
|
|
1874
|
-
return /* @__PURE__ */
|
|
2017
|
+
return /* @__PURE__ */ React14.createElement(Box13, { key: idx, marginTop: idx > 0 ? 1 : 0 }, /* @__PURE__ */ React14.createElement(Text13, { bold: true, color }, parseInlineText(token.text)));
|
|
1875
2018
|
}
|
|
1876
2019
|
function renderCodeBlock(token, idx) {
|
|
1877
2020
|
let highlightedCode;
|
|
@@ -1883,20 +2026,20 @@ function renderCodeBlock(token, idx) {
|
|
|
1883
2026
|
} catch (error) {
|
|
1884
2027
|
highlightedCode = token.text;
|
|
1885
2028
|
}
|
|
1886
|
-
return /* @__PURE__ */
|
|
2029
|
+
return /* @__PURE__ */ React14.createElement(Box13, { key: idx, flexDirection: "column", paddingLeft: 2 }, token.lang && /* @__PURE__ */ React14.createElement(Text13, { dimColor: true, color: "gray" }, token.lang), /* @__PURE__ */ React14.createElement(Text13, null, highlightedCode));
|
|
1887
2030
|
}
|
|
1888
2031
|
function renderParagraph(token, idx) {
|
|
1889
|
-
return /* @__PURE__ */
|
|
2032
|
+
return /* @__PURE__ */ React14.createElement(Box13, { key: idx }, /* @__PURE__ */ React14.createElement(Text13, null, parseInlineText(token.text)));
|
|
1890
2033
|
}
|
|
1891
2034
|
function renderList(token, idx) {
|
|
1892
|
-
return /* @__PURE__ */
|
|
2035
|
+
return /* @__PURE__ */ React14.createElement(Box13, { key: idx, flexDirection: "column" }, token.items.map((item, itemIdx) => renderListItem(item, itemIdx, token.ordered, itemIdx + 1)));
|
|
1893
2036
|
}
|
|
1894
2037
|
function renderListItem(item, idx, ordered, number) {
|
|
1895
2038
|
const bullet = ordered ? `${number}.` : "\u2022";
|
|
1896
|
-
return /* @__PURE__ */
|
|
2039
|
+
return /* @__PURE__ */ React14.createElement(Box13, { key: idx, paddingLeft: 2 }, /* @__PURE__ */ React14.createElement(Text13, null, bullet, " ", parseInlineText(item.text)));
|
|
1897
2040
|
}
|
|
1898
2041
|
function renderBlockquote(token, idx) {
|
|
1899
|
-
return /* @__PURE__ */
|
|
2042
|
+
return /* @__PURE__ */ React14.createElement(Box13, { key: idx, paddingLeft: 2, borderStyle: "single", borderLeft: true, borderColor: "gray" }, token.tokens.map((t, i) => renderToken(t, i)));
|
|
1900
2043
|
}
|
|
1901
2044
|
function parseInlineText(text) {
|
|
1902
2045
|
const parts = [];
|
|
@@ -1909,15 +2052,15 @@ function parseInlineText(text) {
|
|
|
1909
2052
|
}
|
|
1910
2053
|
if (match[1]) {
|
|
1911
2054
|
parts.push(
|
|
1912
|
-
/* @__PURE__ */
|
|
2055
|
+
/* @__PURE__ */ React14.createElement(Text13, { key: match.index, bold: true }, match[2])
|
|
1913
2056
|
);
|
|
1914
2057
|
} else if (match[3]) {
|
|
1915
2058
|
parts.push(
|
|
1916
|
-
/* @__PURE__ */
|
|
2059
|
+
/* @__PURE__ */ React14.createElement(Text13, { key: match.index, italic: true }, match[4])
|
|
1917
2060
|
);
|
|
1918
2061
|
} else if (match[5]) {
|
|
1919
2062
|
parts.push(
|
|
1920
|
-
/* @__PURE__ */
|
|
2063
|
+
/* @__PURE__ */ React14.createElement(Text13, { key: match.index, color: "cyan" }, match[6])
|
|
1921
2064
|
);
|
|
1922
2065
|
}
|
|
1923
2066
|
lastIndex = regex.lastIndex;
|
|
@@ -1928,7 +2071,7 @@ function parseInlineText(text) {
|
|
|
1928
2071
|
if (parts.length === 0) {
|
|
1929
2072
|
return text;
|
|
1930
2073
|
}
|
|
1931
|
-
return /* @__PURE__ */
|
|
2074
|
+
return /* @__PURE__ */ React14.createElement(React14.Fragment, null, parts);
|
|
1932
2075
|
}
|
|
1933
2076
|
|
|
1934
2077
|
// src/components/MessageItem.tsx
|
|
@@ -1939,21 +2082,21 @@ function truncateValue(value, maxLength) {
|
|
|
1939
2082
|
}
|
|
1940
2083
|
return str.slice(0, maxLength) + "...";
|
|
1941
2084
|
}
|
|
1942
|
-
var MessageItem =
|
|
2085
|
+
var MessageItem = React15.memo(function MessageItem2({ message }) {
|
|
1943
2086
|
const isUser = message.role === "user";
|
|
1944
|
-
return /* @__PURE__ */
|
|
2087
|
+
return /* @__PURE__ */ React15.createElement(Box14, { flexDirection: "column" }, isUser && message.content && /* @__PURE__ */ React15.createElement(Box14, { marginBottom: 1 }, /* @__PURE__ */ React15.createElement(Text14, { backgroundColor: "whiteBright", color: "black" }, "\u276F ", message.content, " ")), !isUser && message.metadata?.steps && message.metadata.steps.filter((s) => ["thought", "action"].includes(s.type)).length > 0 && /* @__PURE__ */ React15.createElement(Box14, { paddingLeft: 2, flexDirection: "column", marginBottom: 1 }, message.metadata.steps.map((step, idx) => {
|
|
1945
2088
|
if (step.type === "thought") {
|
|
1946
|
-
return /* @__PURE__ */
|
|
2089
|
+
return /* @__PURE__ */ React15.createElement(Box14, { key: idx, flexDirection: "column" }, /* @__PURE__ */ React15.createElement(Text14, { color: "blue" }, "\u{1F4AD} Thought:"), /* @__PURE__ */ React15.createElement(Text14, { dimColor: true }, ` ${step.content}`));
|
|
1947
2090
|
}
|
|
1948
2091
|
if (step.type === "action") {
|
|
1949
2092
|
const toolName = step.metadata?.toolName || "unknown";
|
|
1950
2093
|
const toolInput = step.metadata?.toolInput;
|
|
1951
2094
|
const observationStep = message.metadata?.steps?.[idx + 1];
|
|
1952
2095
|
const result = observationStep?.type === "observation" ? observationStep.content : null;
|
|
1953
|
-
return /* @__PURE__ */
|
|
2096
|
+
return /* @__PURE__ */ React15.createElement(Box14, { key: idx, marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React15.createElement(Text14, { color: "yellow" }, "\u{1F527} ", toolName), toolInput && /* @__PURE__ */ React15.createElement(Text14, { dimColor: true }, ` Input: ${truncateValue(toolInput, 100)}`), result && /* @__PURE__ */ React15.createElement(Text14, { dimColor: true }, ` Result: ${truncateValue(result, 200)}`));
|
|
1954
2097
|
}
|
|
1955
2098
|
return null;
|
|
1956
|
-
}).filter(Boolean)), !isUser && message.content !== "..." && /* @__PURE__ */
|
|
2099
|
+
}).filter(Boolean)), !isUser && message.content !== "..." && /* @__PURE__ */ React15.createElement(Box14, { paddingLeft: 2, marginBottom: 1 }, message.metadata?.permissionDenied ? /* @__PURE__ */ React15.createElement(Text14, { color: "yellow" }, "\u26A0\uFE0F ", message.content) : /* @__PURE__ */ React15.createElement(MarkdownRenderer, { content: message.content })), !isUser && message.content !== "..." && message.metadata && /* @__PURE__ */ React15.createElement(Box14, { paddingLeft: 2, marginBottom: 1 }, (message.metadata.tokenUsage?.total || message.metadata.creditsUsed) && /* @__PURE__ */ React15.createElement(Text14, { dimColor: true }, "(", message.metadata.tokenUsage?.total ? `${message.metadata.tokenUsage.total.toLocaleString()} tokens` : "", message.metadata.creditsUsed && message.metadata.creditsUsed > 0 ? (message.metadata.tokenUsage?.total ? " \u2022 " : "") + `used ${message.metadata.creditsUsed.toLocaleString()} ${message.metadata.creditsUsed === 1 ? "credit" : "credits"}` : "", ")")));
|
|
1957
2100
|
});
|
|
1958
2101
|
|
|
1959
2102
|
// src/utils/processFileReferences.ts
|
|
@@ -2081,6 +2224,7 @@ function App({
|
|
|
2081
2224
|
onCommand,
|
|
2082
2225
|
onBashCommand,
|
|
2083
2226
|
onPermissionResponse,
|
|
2227
|
+
onUserQuestionResponse,
|
|
2084
2228
|
onImageDetected,
|
|
2085
2229
|
commandHistory = [],
|
|
2086
2230
|
commands = [],
|
|
@@ -2094,11 +2238,12 @@ function App({
|
|
|
2094
2238
|
const messages = useCliStore((state) => state.session?.messages || []);
|
|
2095
2239
|
const pendingMessages = useCliStore((state) => state.pendingMessages);
|
|
2096
2240
|
const sessionName = useCliStore((state) => state.session?.name || "New Session");
|
|
2097
|
-
const currentModel = useCliStore((state) => state.session?.model ||
|
|
2241
|
+
const currentModel = useCliStore((state) => state.session?.model || ChatModels.CLAUDE_4_5_SONNET);
|
|
2098
2242
|
const totalTokens = useCliStore((state) => state.session?.metadata.totalTokens || 0);
|
|
2099
2243
|
const totalCredits = useCliStore((state) => state.session?.metadata.totalCredits);
|
|
2100
2244
|
const isThinking = useCliStore((state) => state.isThinking);
|
|
2101
2245
|
const permissionPrompt = useCliStore((state) => state.permissionPrompt);
|
|
2246
|
+
const userQuestionPrompt = useCliStore((state) => state.userQuestionPrompt);
|
|
2102
2247
|
const showConfigEditor = useCliStore((state) => state.showConfigEditor);
|
|
2103
2248
|
const setShowConfigEditor = useCliStore((state) => state.setShowConfigEditor);
|
|
2104
2249
|
const showMcpViewer = useCliStore((state) => state.showMcpViewer);
|
|
@@ -2114,13 +2259,13 @@ function App({
|
|
|
2114
2259
|
}
|
|
2115
2260
|
}, [pendingBackgroundTrigger, isThinking, setPendingBackgroundTrigger, onBackgroundCompletion]);
|
|
2116
2261
|
const toggleAutoAcceptEdits = useCliStore((state) => state.toggleAutoAcceptEdits);
|
|
2117
|
-
|
|
2262
|
+
useInput7((_input, key) => {
|
|
2118
2263
|
if (key.tab && key.shift) {
|
|
2119
2264
|
toggleAutoAcceptEdits();
|
|
2120
2265
|
}
|
|
2121
2266
|
});
|
|
2122
|
-
const [isBashMode, setIsBashMode] =
|
|
2123
|
-
const handleSubmit =
|
|
2267
|
+
const [isBashMode, setIsBashMode] = useState7(false);
|
|
2268
|
+
const handleSubmit = React16.useCallback(
|
|
2124
2269
|
async (input) => {
|
|
2125
2270
|
const trimmed = input.trim();
|
|
2126
2271
|
if (!trimmed) return;
|
|
@@ -2149,7 +2294,7 @@ ${errorBlock}`;
|
|
|
2149
2294
|
},
|
|
2150
2295
|
[onMessage, onCommand, setIsThinking]
|
|
2151
2296
|
);
|
|
2152
|
-
return /* @__PURE__ */
|
|
2297
|
+
return /* @__PURE__ */ React16.createElement(Box15, { flexDirection: "column" }, showConfigEditor && config && onSaveConfig ? /* @__PURE__ */ React16.createElement(Box15, { flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React16.createElement(
|
|
2153
2298
|
ConfigEditor,
|
|
2154
2299
|
{
|
|
2155
2300
|
config,
|
|
@@ -2159,8 +2304,8 @@ ${errorBlock}`;
|
|
|
2159
2304
|
}
|
|
2160
2305
|
)) : showMcpViewer && config ? (
|
|
2161
2306
|
/* MCP Viewer - full screen takeover */
|
|
2162
|
-
/* @__PURE__ */
|
|
2163
|
-
) : /* @__PURE__ */
|
|
2307
|
+
/* @__PURE__ */ React16.createElement(Box15, { flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React16.createElement(McpViewer, { config, mcpManager, onClose: () => setShowMcpViewer(false) }))
|
|
2308
|
+
) : /* @__PURE__ */ React16.createElement(React16.Fragment, null, /* @__PURE__ */ React16.createElement(Static, { items: messages }, (message) => /* @__PURE__ */ React16.createElement(Box15, { key: message.id, flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React16.createElement(MessageItem, { message }))), /* @__PURE__ */ React16.createElement(Box15, { flexDirection: "column" }, pendingMessages.map((message) => /* @__PURE__ */ React16.createElement(Box15, { key: message.id, flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React16.createElement(MessageItem, { message })))), permissionPrompt && /* @__PURE__ */ React16.createElement(Box15, { key: permissionPrompt.id, flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React16.createElement(
|
|
2164
2309
|
PermissionPrompt,
|
|
2165
2310
|
{
|
|
2166
2311
|
toolName: permissionPrompt.toolName,
|
|
@@ -2169,20 +2314,20 @@ ${errorBlock}`;
|
|
|
2169
2314
|
canBeTrusted: permissionPrompt.canBeTrusted,
|
|
2170
2315
|
onResponse: onPermissionResponse
|
|
2171
2316
|
}
|
|
2172
|
-
)), !permissionPrompt && /* @__PURE__ */
|
|
2317
|
+
)), userQuestionPrompt && /* @__PURE__ */ React16.createElement(Box15, { key: userQuestionPrompt.id, flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React16.createElement(UserQuestionPrompt, { payload: userQuestionPrompt.payload, onResponse: onUserQuestionResponse })), !permissionPrompt && !userQuestionPrompt && /* @__PURE__ */ React16.createElement(AgentThinking, null), /* @__PURE__ */ React16.createElement(BackgroundAgentStatus, null), /* @__PURE__ */ React16.createElement(CompletedGroupNotification, null), exitRequested && /* @__PURE__ */ React16.createElement(Box15, { paddingX: 1, marginBottom: 1 }, /* @__PURE__ */ React16.createElement(Text15, { color: "yellow", bold: true }, "Press Ctrl+C again to exit")), /* @__PURE__ */ React16.createElement(Box15, { borderStyle: "single", borderColor: isBashMode ? "yellow" : "cyan", paddingX: 1 }, /* @__PURE__ */ React16.createElement(
|
|
2173
2318
|
InputPrompt,
|
|
2174
2319
|
{
|
|
2175
2320
|
onSubmit: handleSubmit,
|
|
2176
2321
|
onBashCommand,
|
|
2177
2322
|
onImageDetected,
|
|
2178
|
-
disabled: isThinking || !!permissionPrompt,
|
|
2323
|
+
disabled: isThinking || !!permissionPrompt || !!userQuestionPrompt,
|
|
2179
2324
|
history: commandHistory,
|
|
2180
2325
|
commands,
|
|
2181
2326
|
prefillInput,
|
|
2182
2327
|
onPrefillConsumed,
|
|
2183
2328
|
onBashModeChange: setIsBashMode
|
|
2184
2329
|
}
|
|
2185
|
-
)), /* @__PURE__ */
|
|
2330
|
+
)), /* @__PURE__ */ React16.createElement(
|
|
2186
2331
|
StatusBar,
|
|
2187
2332
|
{
|
|
2188
2333
|
sessionName,
|
|
@@ -2194,20 +2339,20 @@ ${errorBlock}`;
|
|
|
2194
2339
|
}
|
|
2195
2340
|
|
|
2196
2341
|
// src/components/MessageList.tsx
|
|
2197
|
-
import
|
|
2198
|
-
import { Box as
|
|
2342
|
+
import React17 from "react";
|
|
2343
|
+
import { Box as Box16, Text as Text16 } from "ink";
|
|
2199
2344
|
function stripThinkingTags(content) {
|
|
2200
2345
|
return content.replace(/<think>[\s\S]*?<\/think>/g, "").trim();
|
|
2201
2346
|
}
|
|
2202
|
-
var MessageList =
|
|
2347
|
+
var MessageList = React17.memo(
|
|
2203
2348
|
function MessageList2({ messages }) {
|
|
2204
2349
|
if (messages.length === 0) {
|
|
2205
|
-
return /* @__PURE__ */
|
|
2350
|
+
return /* @__PURE__ */ React17.createElement(Box16, { paddingY: 1 }, /* @__PURE__ */ React17.createElement(Text16, { dimColor: true }, "No messages yet. Type a message to start!"));
|
|
2206
2351
|
}
|
|
2207
|
-
return /* @__PURE__ */
|
|
2352
|
+
return /* @__PURE__ */ React17.createElement(Box16, { flexDirection: "column", gap: 1, paddingY: 1 }, messages.map((message, index) => /* @__PURE__ */ React17.createElement(Box16, { key: index, flexDirection: "column", marginBottom: 1 }, /* @__PURE__ */ React17.createElement(Box16, null, /* @__PURE__ */ React17.createElement(Text16, { bold: true, color: message.role === "user" ? "cyan" : "green" }, message.role === "user" ? "\u{1F464} You" : "\u{1F916} Assistant"), /* @__PURE__ */ React17.createElement(Text16, { dimColor: true }, " \u2022 ", new Date(message.timestamp).toLocaleTimeString())), /* @__PURE__ */ React17.createElement(Box16, { paddingLeft: 2 }, message.metadata?.permissionDenied ? /* @__PURE__ */ React17.createElement(Text16, { color: "yellow" }, "\u26A0\uFE0F ", stripThinkingTags(message.content)) : /* @__PURE__ */ React17.createElement(Text16, null, stripThinkingTags(message.content))), message.metadata?.steps && message.metadata.steps.length > 0 && /* @__PURE__ */ React17.createElement(Box16, { paddingLeft: 2, marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React17.createElement(Text16, { 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__ */ React17.createElement(Text16, { dimColor: true }, "Step types: ", message.metadata.steps.map((s) => s.type).join(", ")), message.metadata.steps.map((step, idx) => {
|
|
2208
2353
|
if (step.type === "thought") {
|
|
2209
|
-
return /* @__PURE__ */
|
|
2210
|
-
|
|
2354
|
+
return /* @__PURE__ */ React17.createElement(Box16, { key: idx, paddingLeft: 2, marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React17.createElement(Text16, { color: "blue" }, "\u{1F4AD} Thought:"), /* @__PURE__ */ React17.createElement(
|
|
2355
|
+
Text16,
|
|
2211
2356
|
{
|
|
2212
2357
|
dimColor: true
|
|
2213
2358
|
},
|
|
@@ -2219,10 +2364,10 @@ var MessageList = React16.memo(
|
|
|
2219
2364
|
const toolInput = step.metadata?.toolInput;
|
|
2220
2365
|
const observationStep = message.metadata.steps[idx + 1];
|
|
2221
2366
|
const result = observationStep?.type === "observation" ? observationStep.content : null;
|
|
2222
|
-
return /* @__PURE__ */
|
|
2367
|
+
return /* @__PURE__ */ React17.createElement(Box16, { key: idx, paddingLeft: 2, marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React17.createElement(Text16, { color: "yellow" }, "\u{1F527} Action: ", toolName), toolInput && /* @__PURE__ */ React17.createElement(Text16, { dimColor: true }, ` Input: ${typeof toolInput === "string" ? toolInput : JSON.stringify(toolInput).slice(0, 100)}`), result && /* @__PURE__ */ React17.createElement(Text16, { dimColor: true }, ` Result: ${typeof result === "string" ? result.slice(0, 200) : JSON.stringify(result).slice(0, 200)}${(typeof result === "string" ? result.length : JSON.stringify(result).length) > 200 ? "..." : ""}`));
|
|
2223
2368
|
}
|
|
2224
2369
|
return null;
|
|
2225
|
-
}).filter(Boolean)), message.metadata?.tokenUsage && (!message.metadata.steps || message.metadata.steps.length === 0) && /* @__PURE__ */
|
|
2370
|
+
}).filter(Boolean)), message.metadata?.tokenUsage && (!message.metadata.steps || message.metadata.steps.length === 0) && /* @__PURE__ */ React17.createElement(Box16, { paddingLeft: 2 }, /* @__PURE__ */ React17.createElement(Text16, { dimColor: true }, `${message.metadata.tokenUsage.total} tokens`)))));
|
|
2226
2371
|
},
|
|
2227
2372
|
(prevProps, nextProps) => {
|
|
2228
2373
|
if (prevProps.messages.length !== nextProps.messages.length) {
|
|
@@ -2233,8 +2378,8 @@ var MessageList = React16.memo(
|
|
|
2233
2378
|
);
|
|
2234
2379
|
|
|
2235
2380
|
// src/components/TrustLocationSelector.tsx
|
|
2236
|
-
import
|
|
2237
|
-
import { Box as
|
|
2381
|
+
import React18 from "react";
|
|
2382
|
+
import { Box as Box17, Text as Text17 } from "ink";
|
|
2238
2383
|
import SelectInput from "ink-select-input";
|
|
2239
2384
|
function TrustLocationSelector({ inProject, onSelect, onCancel }) {
|
|
2240
2385
|
const items = [];
|
|
@@ -2255,24 +2400,24 @@ function TrustLocationSelector({ inProject, onSelect, onCancel }) {
|
|
|
2255
2400
|
const handleSelect = (item) => {
|
|
2256
2401
|
onSelect(item.value);
|
|
2257
2402
|
};
|
|
2258
|
-
return /* @__PURE__ */
|
|
2403
|
+
return /* @__PURE__ */ React18.createElement(Box17, { flexDirection: "column", marginY: 1 }, /* @__PURE__ */ React18.createElement(Box17, { marginBottom: 1 }, /* @__PURE__ */ React18.createElement(Text17, { bold: true }, "Where should this rule be saved?")), /* @__PURE__ */ React18.createElement(
|
|
2259
2404
|
SelectInput,
|
|
2260
2405
|
{
|
|
2261
2406
|
items,
|
|
2262
2407
|
onSelect: handleSelect,
|
|
2263
|
-
itemComponent: ({ isSelected, label }) => /* @__PURE__ */
|
|
2408
|
+
itemComponent: ({ isSelected, label }) => /* @__PURE__ */ React18.createElement(Box17, null, /* @__PURE__ */ React18.createElement(Text17, { color: isSelected ? "cyan" : void 0 }, isSelected ? "\u276F " : " ", label))
|
|
2264
2409
|
}
|
|
2265
|
-
), /* @__PURE__ */
|
|
2410
|
+
), /* @__PURE__ */ React18.createElement(Box17, { marginTop: 1 }, /* @__PURE__ */ React18.createElement(Text17, { dimColor: true }, "Use \u2191\u2193 arrows to navigate, Enter to select, Ctrl+C to cancel")));
|
|
2266
2411
|
}
|
|
2267
2412
|
|
|
2268
2413
|
// src/components/RewindSelector.tsx
|
|
2269
|
-
import
|
|
2270
|
-
import { Box as
|
|
2414
|
+
import React19, { useState as useState8 } from "react";
|
|
2415
|
+
import { Box as Box18, Text as Text18, useInput as useInput8 } from "ink";
|
|
2271
2416
|
import SelectInput2 from "ink-select-input";
|
|
2272
2417
|
function RewindSelector({ messages, onSelect, onCancel }) {
|
|
2273
|
-
const [step, setStep] =
|
|
2274
|
-
const [selectedMessageIndex, setSelectedMessageIndex] =
|
|
2275
|
-
|
|
2418
|
+
const [step, setStep] = useState8("selection");
|
|
2419
|
+
const [selectedMessageIndex, setSelectedMessageIndex] = useState8(null);
|
|
2420
|
+
useInput8((input, key) => {
|
|
2276
2421
|
if (key.escape) {
|
|
2277
2422
|
if (step === "confirmation") {
|
|
2278
2423
|
setStep("selection");
|
|
@@ -2309,14 +2454,14 @@ function RewindSelector({ messages, onSelect, onCancel }) {
|
|
|
2309
2454
|
return sum2 + (msg.metadata?.tokenUsage?.total || 0);
|
|
2310
2455
|
}, 0);
|
|
2311
2456
|
if (step === "selection") {
|
|
2312
|
-
return /* @__PURE__ */
|
|
2457
|
+
return /* @__PURE__ */ React19.createElement(Box18, { flexDirection: "column", marginY: 1 }, /* @__PURE__ */ React19.createElement(Box18, { marginBottom: 1 }, /* @__PURE__ */ React19.createElement(Text18, { bold: true }, "Select a point to rewind to:")), /* @__PURE__ */ React19.createElement(
|
|
2313
2458
|
SelectInput2,
|
|
2314
2459
|
{
|
|
2315
2460
|
items,
|
|
2316
2461
|
onSelect: handleSelectionSelect,
|
|
2317
|
-
itemComponent: ({ isSelected, label }) => /* @__PURE__ */
|
|
2462
|
+
itemComponent: ({ isSelected, label }) => /* @__PURE__ */ React19.createElement(Box18, null, /* @__PURE__ */ React19.createElement(Text18, { color: isSelected ? "cyan" : void 0 }, isSelected ? "\u276F " : " ", label))
|
|
2318
2463
|
}
|
|
2319
|
-
), /* @__PURE__ */
|
|
2464
|
+
), /* @__PURE__ */ React19.createElement(Box18, { marginTop: 1 }, /* @__PURE__ */ React19.createElement(Text18, { dimColor: true }, "Use \u2191\u2193 arrows to navigate, Enter to select, Esc to cancel")));
|
|
2320
2465
|
}
|
|
2321
2466
|
const confirmationItems = [
|
|
2322
2467
|
{ label: "Yes, rewind to this point", value: "confirm" },
|
|
@@ -2324,24 +2469,24 @@ function RewindSelector({ messages, onSelect, onCancel }) {
|
|
|
2324
2469
|
];
|
|
2325
2470
|
const selectedMessage = selectedMessageIndex !== null && selectedMessageIndex >= 0 && selectedMessageIndex < messages.length ? messages[selectedMessageIndex] : null;
|
|
2326
2471
|
const selectedPreview = selectedMessage ? selectedMessage.content.length > 50 ? selectedMessage.content.substring(0, 50) + "..." : selectedMessage.content : "";
|
|
2327
|
-
return /* @__PURE__ */
|
|
2472
|
+
return /* @__PURE__ */ React19.createElement(Box18, { flexDirection: "column", marginY: 1 }, /* @__PURE__ */ React19.createElement(Box18, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React19.createElement(Text18, { bold: true }, "Confirm rewind operation:"), /* @__PURE__ */ React19.createElement(Text18, { dimColor: true }, "Message: ", selectedPreview), /* @__PURE__ */ React19.createElement(Text18, { color: "yellow" }, "This will remove ", messagesToRemove.length, " message(s) (", tokensToRemove.toLocaleString(), " tokens)"), /* @__PURE__ */ React19.createElement(Text18, { color: "cyan" }, "The selected message will be placed in your input for editing.")), /* @__PURE__ */ React19.createElement(
|
|
2328
2473
|
SelectInput2,
|
|
2329
2474
|
{
|
|
2330
2475
|
items: confirmationItems,
|
|
2331
2476
|
onSelect: handleConfirmationSelect,
|
|
2332
|
-
itemComponent: ({ isSelected, label }) => /* @__PURE__ */
|
|
2477
|
+
itemComponent: ({ isSelected, label }) => /* @__PURE__ */ React19.createElement(Box18, null, /* @__PURE__ */ React19.createElement(Text18, { color: isSelected ? "cyan" : void 0 }, isSelected ? "\u276F " : " ", label))
|
|
2333
2478
|
}
|
|
2334
|
-
), /* @__PURE__ */
|
|
2479
|
+
), /* @__PURE__ */ React19.createElement(Box18, { marginTop: 1 }, /* @__PURE__ */ React19.createElement(Text18, { dimColor: true }, "Use \u2191\u2193 arrows to navigate, Enter to select, Esc to go back")));
|
|
2335
2480
|
}
|
|
2336
2481
|
|
|
2337
2482
|
// src/components/SessionSelector.tsx
|
|
2338
|
-
import
|
|
2339
|
-
import { Box as
|
|
2483
|
+
import React20, { useState as useState9 } from "react";
|
|
2484
|
+
import { Box as Box19, Text as Text19, useInput as useInput9 } from "ink";
|
|
2340
2485
|
import SelectInput3 from "ink-select-input";
|
|
2341
2486
|
function SessionSelector({ sessions, currentSession, onSelect, onCancel }) {
|
|
2342
|
-
const [step, setStep] =
|
|
2343
|
-
const [selectedSession, setSelectedSession] =
|
|
2344
|
-
|
|
2487
|
+
const [step, setStep] = useState9("selection");
|
|
2488
|
+
const [selectedSession, setSelectedSession] = useState9(null);
|
|
2489
|
+
useInput9((_input, key) => {
|
|
2345
2490
|
if (key.escape) {
|
|
2346
2491
|
if (step === "confirmation") {
|
|
2347
2492
|
setStep("selection");
|
|
@@ -2391,32 +2536,32 @@ function SessionSelector({ sessions, currentSession, onSelect, onCancel }) {
|
|
|
2391
2536
|
}
|
|
2392
2537
|
};
|
|
2393
2538
|
if (step === "selection") {
|
|
2394
|
-
return /* @__PURE__ */
|
|
2539
|
+
return /* @__PURE__ */ React20.createElement(Box19, { flexDirection: "column", marginY: 1 }, /* @__PURE__ */ React20.createElement(Box19, { marginBottom: 1 }, /* @__PURE__ */ React20.createElement(Text19, { bold: true }, "Select a session to resume:")), /* @__PURE__ */ React20.createElement(
|
|
2395
2540
|
SelectInput3,
|
|
2396
2541
|
{
|
|
2397
2542
|
items,
|
|
2398
2543
|
onSelect: handleSelectionSelect,
|
|
2399
|
-
itemComponent: ({ isSelected, label }) => /* @__PURE__ */
|
|
2544
|
+
itemComponent: ({ isSelected, label }) => /* @__PURE__ */ React20.createElement(Box19, null, /* @__PURE__ */ React20.createElement(Text19, { color: isSelected ? "cyan" : void 0 }, label))
|
|
2400
2545
|
}
|
|
2401
|
-
), /* @__PURE__ */
|
|
2546
|
+
), /* @__PURE__ */ React20.createElement(Box19, { marginTop: 1 }, /* @__PURE__ */ React20.createElement(Text19, { dimColor: true }, "Use \u2191\u2193 arrows to navigate, Enter to select, Esc to cancel")));
|
|
2402
2547
|
}
|
|
2403
2548
|
const confirmationItems = [
|
|
2404
2549
|
{ label: "Yes, resume this session", value: "confirm" },
|
|
2405
2550
|
{ label: "No, go back to selection", value: "cancel" }
|
|
2406
2551
|
];
|
|
2407
|
-
return /* @__PURE__ */
|
|
2552
|
+
return /* @__PURE__ */ React20.createElement(Box19, { flexDirection: "column", marginY: 1 }, /* @__PURE__ */ React20.createElement(Box19, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React20.createElement(Text19, { bold: true }, 'Resume session: "', selectedSession?.name, '"'), /* @__PURE__ */ React20.createElement(Text19, { dimColor: true }, selectedSession?.messages.length, " messages | ", selectedSession?.model, " |", " ", selectedSession?.metadata?.totalTokens?.toLocaleString() ?? 0, " tokens"), hasUnsavedWork && /* @__PURE__ */ React20.createElement(Text19, { color: "yellow" }, "Warning: Your current session has unsaved messages. Use /save first if needed.")), /* @__PURE__ */ React20.createElement(
|
|
2408
2553
|
SelectInput3,
|
|
2409
2554
|
{
|
|
2410
2555
|
items: confirmationItems,
|
|
2411
2556
|
onSelect: handleConfirmationSelect,
|
|
2412
|
-
itemComponent: ({ isSelected, label }) => /* @__PURE__ */
|
|
2557
|
+
itemComponent: ({ isSelected, label }) => /* @__PURE__ */ React20.createElement(Box19, null, /* @__PURE__ */ React20.createElement(Text19, { color: isSelected ? "cyan" : void 0 }, label))
|
|
2413
2558
|
}
|
|
2414
|
-
), /* @__PURE__ */
|
|
2559
|
+
), /* @__PURE__ */ React20.createElement(Box19, { marginTop: 1 }, /* @__PURE__ */ React20.createElement(Text19, { dimColor: true }, "Use \u2191\u2193 arrows to navigate, Enter to select, Esc to go back")));
|
|
2415
2560
|
}
|
|
2416
2561
|
|
|
2417
2562
|
// src/components/LoginFlow.tsx
|
|
2418
|
-
import
|
|
2419
|
-
import { Box as
|
|
2563
|
+
import React21, { useState as useState10, useEffect as useEffect6 } from "react";
|
|
2564
|
+
import { Box as Box20, Text as Text20 } from "ink";
|
|
2420
2565
|
import Spinner3 from "ink-spinner";
|
|
2421
2566
|
import jwt from "jsonwebtoken";
|
|
2422
2567
|
import open from "open";
|
|
@@ -2532,10 +2677,10 @@ var OAuthClient = class {
|
|
|
2532
2677
|
|
|
2533
2678
|
// src/components/LoginFlow.tsx
|
|
2534
2679
|
function LoginFlow({ apiUrl = "http://localhost:3000", configStore, onSuccess, onError }) {
|
|
2535
|
-
const [status, setStatus] =
|
|
2536
|
-
const [deviceFlow, setDeviceFlow] =
|
|
2537
|
-
const [statusMessage, setStatusMessage] =
|
|
2538
|
-
const [error, setError] =
|
|
2680
|
+
const [status, setStatus] = useState10("initiating");
|
|
2681
|
+
const [deviceFlow, setDeviceFlow] = useState10(null);
|
|
2682
|
+
const [statusMessage, setStatusMessage] = useState10("Initiating device authorization...");
|
|
2683
|
+
const [error, setError] = useState10(null);
|
|
2539
2684
|
useEffect6(() => {
|
|
2540
2685
|
const runLoginFlow = async () => {
|
|
2541
2686
|
const oauth = new OAuthClient(apiUrl);
|
|
@@ -2579,15 +2724,15 @@ function LoginFlow({ apiUrl = "http://localhost:3000", configStore, onSuccess, o
|
|
|
2579
2724
|
}
|
|
2580
2725
|
}, [deviceFlow, status]);
|
|
2581
2726
|
if (status === "initiating") {
|
|
2582
|
-
return /* @__PURE__ */
|
|
2727
|
+
return /* @__PURE__ */ React21.createElement(Box20, { flexDirection: "column", padding: 1 }, /* @__PURE__ */ React21.createElement(Box20, null, /* @__PURE__ */ React21.createElement(Text20, { color: "cyan" }, /* @__PURE__ */ React21.createElement(Spinner3, { type: "dots" }), " Initiating device authorization...")));
|
|
2583
2728
|
}
|
|
2584
2729
|
if (status === "error") {
|
|
2585
|
-
return /* @__PURE__ */
|
|
2730
|
+
return /* @__PURE__ */ React21.createElement(Box20, { flexDirection: "column", padding: 1 }, /* @__PURE__ */ React21.createElement(Box20, { marginBottom: 1 }, /* @__PURE__ */ React21.createElement(Text20, { color: "red", bold: true }, "\u2716 Authentication Failed")), /* @__PURE__ */ React21.createElement(Box20, null, /* @__PURE__ */ React21.createElement(Text20, { color: "red" }, error)));
|
|
2586
2731
|
}
|
|
2587
2732
|
if (status === "success") {
|
|
2588
|
-
return /* @__PURE__ */
|
|
2733
|
+
return /* @__PURE__ */ React21.createElement(Box20, { flexDirection: "column", padding: 1 }, /* @__PURE__ */ React21.createElement(Box20, { marginBottom: 1 }, /* @__PURE__ */ React21.createElement(Text20, { color: "green", bold: true }, "\u2714 Successfully authenticated!")), /* @__PURE__ */ React21.createElement(Box20, null, /* @__PURE__ */ React21.createElement(Text20, { dimColor: true }, "You can now use B4M CLI with your account.")));
|
|
2589
2734
|
}
|
|
2590
|
-
return /* @__PURE__ */
|
|
2735
|
+
return /* @__PURE__ */ React21.createElement(Box20, { flexDirection: "column", padding: 1, borderStyle: "round", borderColor: "cyan" }, /* @__PURE__ */ React21.createElement(Box20, { marginBottom: 1 }, /* @__PURE__ */ React21.createElement(Text20, { color: "cyan", bold: true }, "\u{1F510} Device Authorization")), /* @__PURE__ */ React21.createElement(Box20, { marginBottom: 1 }, /* @__PURE__ */ React21.createElement(Text20, null, "Opening browser automatically... If it doesn't open, please visit:")), /* @__PURE__ */ React21.createElement(Box20, { marginBottom: 1, paddingLeft: 2 }, /* @__PURE__ */ React21.createElement(Text20, { color: "blue", bold: true }, deviceFlow?.verification_uri)), /* @__PURE__ */ React21.createElement(Box20, { marginBottom: 1 }, /* @__PURE__ */ React21.createElement(Text20, null, "And enter this code when prompted:")), /* @__PURE__ */ React21.createElement(Box20, { marginBottom: 1, paddingLeft: 2 }, /* @__PURE__ */ React21.createElement(Text20, { color: "yellow", bold: true }, deviceFlow?.user_code)), /* @__PURE__ */ React21.createElement(Box20, { marginTop: 1 }, /* @__PURE__ */ React21.createElement(Text20, { color: "cyan" }, /* @__PURE__ */ React21.createElement(Spinner3, { type: "dots" }), " ", statusMessage)), /* @__PURE__ */ React21.createElement(Box20, { marginTop: 1 }, /* @__PURE__ */ React21.createElement(Text20, { dimColor: true }, "Expires in ", deviceFlow ? Math.floor(deviceFlow.expires_in / 60) : 0, " minutes")));
|
|
2591
2736
|
}
|
|
2592
2737
|
|
|
2593
2738
|
// src/storage/SessionStore.ts
|
|
@@ -4111,6 +4256,7 @@ var DEFAULT_TOOL_CATEGORIES = {
|
|
|
4111
4256
|
dice_roll: "auto_approve",
|
|
4112
4257
|
prompt_enhancement: "auto_approve",
|
|
4113
4258
|
find_definition: "auto_approve",
|
|
4259
|
+
ask_user_question: "auto_approve",
|
|
4114
4260
|
weather_info: "prompt_default",
|
|
4115
4261
|
// ===== PROMPT ALWAYS (Dangerous tools) =====
|
|
4116
4262
|
// These tools can modify files, execute code, or have other dangerous side effects
|
|
@@ -14594,6 +14740,135 @@ The tool combines git status (working tree) with git log (commit history) to giv
|
|
|
14594
14740
|
})
|
|
14595
14741
|
};
|
|
14596
14742
|
|
|
14743
|
+
// ../../b4m-core/packages/services/dist/src/llm/tools/implementation/askUserQuestion/index.js
|
|
14744
|
+
var _showUserQuestion = null;
|
|
14745
|
+
function setShowUserQuestionFn(fn) {
|
|
14746
|
+
_showUserQuestion = fn;
|
|
14747
|
+
}
|
|
14748
|
+
var MAX_QUESTIONS = 4;
|
|
14749
|
+
var MAX_OPTIONS_PER_QUESTION = 4;
|
|
14750
|
+
var MIN_OPTIONS_PER_QUESTION = 2;
|
|
14751
|
+
function validateArgs(args) {
|
|
14752
|
+
if (args === null || typeof args !== "object") {
|
|
14753
|
+
return { error: "Invalid arguments: expected an object." };
|
|
14754
|
+
}
|
|
14755
|
+
const obj = args;
|
|
14756
|
+
if (!Array.isArray(obj.questions) || obj.questions.length === 0) {
|
|
14757
|
+
return { error: "At least one question is required." };
|
|
14758
|
+
}
|
|
14759
|
+
if (obj.questions.length > MAX_QUESTIONS) {
|
|
14760
|
+
return { error: `Maximum ${MAX_QUESTIONS} questions allowed.` };
|
|
14761
|
+
}
|
|
14762
|
+
const questions = [];
|
|
14763
|
+
for (const raw of obj.questions) {
|
|
14764
|
+
if (raw === null || typeof raw !== "object") {
|
|
14765
|
+
return { error: "Each question must be an object." };
|
|
14766
|
+
}
|
|
14767
|
+
const q = raw;
|
|
14768
|
+
if (typeof q.question !== "string" || q.question.trim() === "") {
|
|
14769
|
+
return { error: 'Each question must have a non-empty "question" string.' };
|
|
14770
|
+
}
|
|
14771
|
+
if (!Array.isArray(q.options)) {
|
|
14772
|
+
return { error: `Question "${q.question}" must have an "options" array.` };
|
|
14773
|
+
}
|
|
14774
|
+
const options = [];
|
|
14775
|
+
for (const rawOpt of q.options.slice(0, MAX_OPTIONS_PER_QUESTION)) {
|
|
14776
|
+
if (rawOpt === null || typeof rawOpt !== "object")
|
|
14777
|
+
continue;
|
|
14778
|
+
const opt = rawOpt;
|
|
14779
|
+
options.push({
|
|
14780
|
+
label: typeof opt.label === "string" ? opt.label : "(untitled)",
|
|
14781
|
+
description: typeof opt.description === "string" ? opt.description : ""
|
|
14782
|
+
});
|
|
14783
|
+
}
|
|
14784
|
+
if (options.length < MIN_OPTIONS_PER_QUESTION) {
|
|
14785
|
+
return { error: `Question "${q.question}" must have at least ${MIN_OPTIONS_PER_QUESTION} options.` };
|
|
14786
|
+
}
|
|
14787
|
+
questions.push({
|
|
14788
|
+
question: q.question,
|
|
14789
|
+
options,
|
|
14790
|
+
multiSelect: q.multiSelect === true ? true : void 0
|
|
14791
|
+
});
|
|
14792
|
+
}
|
|
14793
|
+
return { questions };
|
|
14794
|
+
}
|
|
14795
|
+
var askUserQuestionTool = {
|
|
14796
|
+
name: "ask_user_question",
|
|
14797
|
+
implementation: () => ({
|
|
14798
|
+
toolFn: async (args) => {
|
|
14799
|
+
if (!_showUserQuestion) {
|
|
14800
|
+
return JSON.stringify({
|
|
14801
|
+
error: "ask_user_question is only available in the CLI environment."
|
|
14802
|
+
});
|
|
14803
|
+
}
|
|
14804
|
+
const validated = validateArgs(args);
|
|
14805
|
+
if ("error" in validated) {
|
|
14806
|
+
return JSON.stringify({ error: validated.error });
|
|
14807
|
+
}
|
|
14808
|
+
const payload = {
|
|
14809
|
+
questions: validated.questions.map((q) => ({
|
|
14810
|
+
question: q.question,
|
|
14811
|
+
options: q.options,
|
|
14812
|
+
multiSelect: q.multiSelect === true
|
|
14813
|
+
}))
|
|
14814
|
+
};
|
|
14815
|
+
const response = await _showUserQuestion(payload);
|
|
14816
|
+
return JSON.stringify(response);
|
|
14817
|
+
},
|
|
14818
|
+
toolSchema: {
|
|
14819
|
+
name: "ask_user_question",
|
|
14820
|
+
description: `Ask the user one or more structured questions with selectable options. Use this when you need clarification, user preferences, or decisions. Each question has ${MIN_OPTIONS_PER_QUESTION}-${MAX_OPTIONS_PER_QUESTION} options. The user can also provide free-text via "Other". For multiSelect questions, the user can pick multiple options.`,
|
|
14821
|
+
parameters: {
|
|
14822
|
+
type: "object",
|
|
14823
|
+
properties: {
|
|
14824
|
+
questions: {
|
|
14825
|
+
type: "array",
|
|
14826
|
+
description: `Array of questions to ask (1-${MAX_QUESTIONS} questions)`,
|
|
14827
|
+
minItems: 1,
|
|
14828
|
+
maxItems: MAX_QUESTIONS,
|
|
14829
|
+
items: {
|
|
14830
|
+
type: "object",
|
|
14831
|
+
properties: {
|
|
14832
|
+
question: {
|
|
14833
|
+
type: "string",
|
|
14834
|
+
description: "The question to ask. Should be clear and end with a question mark."
|
|
14835
|
+
},
|
|
14836
|
+
options: {
|
|
14837
|
+
type: "array",
|
|
14838
|
+
description: `Available choices (${MIN_OPTIONS_PER_QUESTION}-${MAX_OPTIONS_PER_QUESTION} options). An "Other" free-text option is always appended automatically.`,
|
|
14839
|
+
minItems: MIN_OPTIONS_PER_QUESTION,
|
|
14840
|
+
maxItems: MAX_OPTIONS_PER_QUESTION,
|
|
14841
|
+
items: {
|
|
14842
|
+
type: "object",
|
|
14843
|
+
properties: {
|
|
14844
|
+
label: {
|
|
14845
|
+
type: "string",
|
|
14846
|
+
description: "Short display text for this option (1-5 words)"
|
|
14847
|
+
},
|
|
14848
|
+
description: {
|
|
14849
|
+
type: "string",
|
|
14850
|
+
description: "Explanation of what this option means"
|
|
14851
|
+
}
|
|
14852
|
+
},
|
|
14853
|
+
required: ["label", "description"]
|
|
14854
|
+
}
|
|
14855
|
+
},
|
|
14856
|
+
multiSelect: {
|
|
14857
|
+
type: "boolean",
|
|
14858
|
+
description: "If true, the user can select multiple options. Default: false.",
|
|
14859
|
+
default: false
|
|
14860
|
+
}
|
|
14861
|
+
},
|
|
14862
|
+
required: ["question", "options"]
|
|
14863
|
+
}
|
|
14864
|
+
}
|
|
14865
|
+
},
|
|
14866
|
+
required: ["questions"]
|
|
14867
|
+
}
|
|
14868
|
+
}
|
|
14869
|
+
})
|
|
14870
|
+
};
|
|
14871
|
+
|
|
14597
14872
|
// ../../b4m-core/packages/services/dist/src/llm/tools/index.js
|
|
14598
14873
|
var b4mTools = {
|
|
14599
14874
|
dice_roll: diceRollTool,
|
|
@@ -14645,7 +14920,9 @@ var cliOnlyTools = {
|
|
|
14645
14920
|
lattice_set_value: latticeSetValueTool,
|
|
14646
14921
|
lattice_create_rule: latticeCreateRuleTool,
|
|
14647
14922
|
lattice_query: latticeQueryTool,
|
|
14648
|
-
lattice_explain: latticeExplainTool
|
|
14923
|
+
lattice_explain: latticeExplainTool,
|
|
14924
|
+
// Interactive tools
|
|
14925
|
+
ask_user_question: askUserQuestionTool
|
|
14649
14926
|
};
|
|
14650
14927
|
var generateTools = (userId, user, logger2, { db }, storage, imageGenerateStorage, statusUpdate, onStart, onFinish, llm, config, model, imageProcessorLambdaName, tools = b4mTools) => {
|
|
14651
14928
|
const context = {
|
|
@@ -14767,7 +15044,7 @@ var SUBAGENT_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
|
14767
15044
|
var CodeReviewAgent = (config) => ({
|
|
14768
15045
|
name: "code_review",
|
|
14769
15046
|
description: "Code review specialist for analyzing code quality, bugs, and improvements",
|
|
14770
|
-
model: config?.model ?? ChatModels.
|
|
15047
|
+
model: config?.model ?? ChatModels.CLAUDE_4_6_SONNET_BEDROCK,
|
|
14771
15048
|
fallbackModels: [ChatModels.GPT4_1, ChatModels.GPT4_1_MINI],
|
|
14772
15049
|
defaultThoroughness: config?.defaultThoroughness ?? "medium",
|
|
14773
15050
|
maxIterations: { quick: 3, medium: 8, very_thorough: 15 },
|
|
@@ -14808,7 +15085,7 @@ Focus on actionable, specific feedback referencing exact code locations. Your re
|
|
|
14808
15085
|
var ProjectManagerAgent = (config) => ({
|
|
14809
15086
|
name: "project_manager",
|
|
14810
15087
|
description: "Project management via Jira and Confluence (create issues, search, update status, write docs). ALWAYS delegate Jira/Confluence requests to this agent \u2014 you do not have direct access to these tools",
|
|
14811
|
-
model: config?.model ?? ChatModels.
|
|
15088
|
+
model: config?.model ?? ChatModels.CLAUDE_4_6_SONNET_BEDROCK,
|
|
14812
15089
|
fallbackModels: [ChatModels.GPT4_1, ChatModels.GPT4_1_MINI],
|
|
14813
15090
|
defaultThoroughness: config?.defaultThoroughness ?? "medium",
|
|
14814
15091
|
maxIterations: { quick: 3, medium: 8, very_thorough: 15 },
|
|
@@ -14850,7 +15127,7 @@ Be precise with issue keys and project names. Your results will be used by the m
|
|
|
14850
15127
|
var GithubManagerAgent = (config) => ({
|
|
14851
15128
|
name: "github_manager",
|
|
14852
15129
|
description: "GitHub operations (issues, pull requests, code search, branches, workflows, reviews). ALWAYS delegate GitHub requests to this agent \u2014 you do not have direct access to these tools",
|
|
14853
|
-
model: config?.model ?? ChatModels.
|
|
15130
|
+
model: config?.model ?? ChatModels.CLAUDE_4_6_SONNET_BEDROCK,
|
|
14854
15131
|
fallbackModels: [ChatModels.GPT4_1, ChatModels.GPT4_1_MINI],
|
|
14855
15132
|
defaultThoroughness: config?.defaultThoroughness ?? "medium",
|
|
14856
15133
|
maxIterations: { quick: 3, medium: 8, very_thorough: 15 },
|
|
@@ -15728,7 +16005,8 @@ var LOCAL_TOOLS = [
|
|
|
15728
16005
|
"math_evaluate",
|
|
15729
16006
|
"current_datetime",
|
|
15730
16007
|
"bash_execute",
|
|
15731
|
-
"recent_changes"
|
|
16008
|
+
"recent_changes",
|
|
16009
|
+
"ask_user_question"
|
|
15732
16010
|
];
|
|
15733
16011
|
function isServerTool(toolName) {
|
|
15734
16012
|
return SERVER_TOOLS.includes(toolName);
|
|
@@ -15954,7 +16232,7 @@ var DEFAULT_MAX_ITERATIONS = {
|
|
|
15954
16232
|
medium: 10,
|
|
15955
16233
|
very_thorough: 20
|
|
15956
16234
|
};
|
|
15957
|
-
var DEFAULT_AGENT_MODEL =
|
|
16235
|
+
var DEFAULT_AGENT_MODEL = ChatModels.CLAUDE_4_5_HAIKU;
|
|
15958
16236
|
var DEFAULT_THOROUGHNESS = "medium";
|
|
15959
16237
|
|
|
15960
16238
|
// src/utils/toolsAdapter.ts
|
|
@@ -16008,7 +16286,7 @@ function wrapToolWithPermission(tool, permissionManager, showPermissionPrompt, a
|
|
|
16008
16286
|
agentContext.observationQueue.push({ toolName, result: result2 });
|
|
16009
16287
|
return result2;
|
|
16010
16288
|
}
|
|
16011
|
-
const { useCliStore: useCliStore2 } = await import("./store-
|
|
16289
|
+
const { useCliStore: useCliStore2 } = await import("./store-X5LEOSGZ.js");
|
|
16012
16290
|
if (useCliStore2.getState().autoAcceptEdits) {
|
|
16013
16291
|
const result2 = await executeTool(toolName, args, apiClient, originalFn);
|
|
16014
16292
|
agentContext.observationQueue.push({ toolName, result: result2 });
|
|
@@ -16195,7 +16473,10 @@ function normalizeToolName(toolName) {
|
|
|
16195
16473
|
}
|
|
16196
16474
|
return TOOL_NAME_MAPPING[toolName] || toolName;
|
|
16197
16475
|
}
|
|
16198
|
-
function generateCliTools(userId, llm, model, permissionManager, showPermissionPrompt, agentContext, configStore, apiClient, toolFilter, checkpointStore) {
|
|
16476
|
+
function generateCliTools(userId, llm, model, permissionManager, showPermissionPrompt, agentContext, configStore, apiClient, toolFilter, showUserQuestion, checkpointStore) {
|
|
16477
|
+
if (showUserQuestion) {
|
|
16478
|
+
setShowUserQuestionFn(showUserQuestion);
|
|
16479
|
+
}
|
|
16199
16480
|
const logger2 = new CliLogger();
|
|
16200
16481
|
const storage = new NoOpStorage();
|
|
16201
16482
|
const user = {
|
|
@@ -17688,23 +17969,23 @@ var ServerLlmBackend = class {
|
|
|
17688
17969
|
getFallbackModels() {
|
|
17689
17970
|
return [
|
|
17690
17971
|
{
|
|
17691
|
-
id:
|
|
17972
|
+
id: ChatModels.CLAUDE_4_6_SONNET,
|
|
17692
17973
|
name: "Claude 4.6 Sonnet"
|
|
17693
17974
|
},
|
|
17694
17975
|
{
|
|
17695
|
-
id:
|
|
17976
|
+
id: ChatModels.CLAUDE_4_5_SONNET,
|
|
17696
17977
|
name: "Claude 4.5 Sonnet"
|
|
17697
17978
|
},
|
|
17698
17979
|
{
|
|
17699
|
-
id:
|
|
17980
|
+
id: ChatModels.CLAUDE_3_5_HAIKU_ANTHROPIC,
|
|
17700
17981
|
name: "Claude 3.5 Haiku"
|
|
17701
17982
|
},
|
|
17702
17983
|
{
|
|
17703
|
-
id:
|
|
17984
|
+
id: ChatModels.GPT4o,
|
|
17704
17985
|
name: "GPT-4o"
|
|
17705
17986
|
},
|
|
17706
17987
|
{
|
|
17707
|
-
id:
|
|
17988
|
+
id: ChatModels.GPT4o_MINI,
|
|
17708
17989
|
name: "GPT-4o Mini"
|
|
17709
17990
|
}
|
|
17710
17991
|
];
|
|
@@ -17899,11 +18180,11 @@ var WebSocketLlmBackend = class {
|
|
|
17899
18180
|
}
|
|
17900
18181
|
getFallbackModels() {
|
|
17901
18182
|
return [
|
|
17902
|
-
{ id:
|
|
17903
|
-
{ id:
|
|
17904
|
-
{ id:
|
|
17905
|
-
{ id:
|
|
17906
|
-
{ id:
|
|
18183
|
+
{ id: ChatModels.CLAUDE_4_6_SONNET, name: "Claude 4.6 Sonnet" },
|
|
18184
|
+
{ id: ChatModels.CLAUDE_4_5_SONNET, name: "Claude 4.5 Sonnet" },
|
|
18185
|
+
{ id: ChatModels.CLAUDE_3_5_HAIKU_ANTHROPIC, name: "Claude 3.5 Haiku" },
|
|
18186
|
+
{ id: ChatModels.GPT4o, name: "GPT-4o" },
|
|
18187
|
+
{ id: ChatModels.GPT4o_MINI, name: "GPT-4o Mini" }
|
|
17907
18188
|
];
|
|
17908
18189
|
}
|
|
17909
18190
|
};
|
|
@@ -18633,7 +18914,8 @@ var SubagentOrchestrator = class {
|
|
|
18633
18914
|
this.deps.configStore,
|
|
18634
18915
|
this.deps.apiClient,
|
|
18635
18916
|
void 0,
|
|
18636
|
-
// toolFilter (applied
|
|
18917
|
+
// toolFilter (applied below via filterToolsByPatterns)
|
|
18918
|
+
this.deps.showUserQuestion,
|
|
18637
18919
|
this.deps.checkpointStore
|
|
18638
18920
|
);
|
|
18639
18921
|
const filteredTools = filterToolsByPatterns2(allTools, toolFilter.allowedTools, toolFilter.deniedTools);
|
|
@@ -18816,94 +19098,94 @@ var MODEL_ALIASES = {
|
|
|
18816
19098
|
// Anthropic/Claude Models
|
|
18817
19099
|
// ===================
|
|
18818
19100
|
// Short aliases (most common)
|
|
18819
|
-
opus:
|
|
18820
|
-
sonnet:
|
|
18821
|
-
haiku:
|
|
19101
|
+
opus: ChatModels.CLAUDE_4_6_OPUS,
|
|
19102
|
+
sonnet: ChatModels.CLAUDE_4_5_SONNET,
|
|
19103
|
+
haiku: ChatModels.CLAUDE_3_5_HAIKU_ANTHROPIC,
|
|
18822
19104
|
// Claude-prefixed aliases
|
|
18823
|
-
"claude-opus":
|
|
18824
|
-
"claude-sonnet":
|
|
18825
|
-
"claude-haiku":
|
|
19105
|
+
"claude-opus": ChatModels.CLAUDE_4_6_OPUS,
|
|
19106
|
+
"claude-sonnet": ChatModels.CLAUDE_4_5_SONNET,
|
|
19107
|
+
"claude-haiku": ChatModels.CLAUDE_3_5_HAIKU_ANTHROPIC,
|
|
18826
19108
|
// Version-specific Claude aliases
|
|
18827
|
-
"claude-4.6-opus":
|
|
18828
|
-
"claude-4.6-sonnet":
|
|
18829
|
-
"claude-4.5-opus":
|
|
18830
|
-
"claude-4.5-sonnet":
|
|
18831
|
-
"claude-4.5-haiku":
|
|
18832
|
-
"claude-4-opus":
|
|
18833
|
-
"claude-4-sonnet":
|
|
18834
|
-
"claude-4.1-opus":
|
|
18835
|
-
"claude-3.7-sonnet":
|
|
18836
|
-
"claude-3.5-sonnet":
|
|
18837
|
-
"claude-3.5-haiku":
|
|
18838
|
-
"claude-3-opus":
|
|
19109
|
+
"claude-4.6-opus": ChatModels.CLAUDE_4_6_OPUS,
|
|
19110
|
+
"claude-4.6-sonnet": ChatModels.CLAUDE_4_6_SONNET,
|
|
19111
|
+
"claude-4.5-opus": ChatModels.CLAUDE_4_5_OPUS,
|
|
19112
|
+
"claude-4.5-sonnet": ChatModels.CLAUDE_4_5_SONNET,
|
|
19113
|
+
"claude-4.5-haiku": ChatModels.CLAUDE_4_5_HAIKU,
|
|
19114
|
+
"claude-4-opus": ChatModels.CLAUDE_4_OPUS,
|
|
19115
|
+
"claude-4-sonnet": ChatModels.CLAUDE_4_SONNET,
|
|
19116
|
+
"claude-4.1-opus": ChatModels.CLAUDE_4_1_OPUS,
|
|
19117
|
+
"claude-3.7-sonnet": ChatModels.CLAUDE_3_7_SONNET_ANTHROPIC,
|
|
19118
|
+
"claude-3.5-sonnet": ChatModels.CLAUDE_3_5_SONNET_ANTHROPIC,
|
|
19119
|
+
"claude-3.5-haiku": ChatModels.CLAUDE_3_5_HAIKU_ANTHROPIC,
|
|
19120
|
+
"claude-3-opus": ChatModels.CLAUDE_3_OPUS,
|
|
18839
19121
|
// ===================
|
|
18840
19122
|
// OpenAI Models
|
|
18841
19123
|
// ===================
|
|
18842
19124
|
// GPT-4 family
|
|
18843
|
-
"gpt-4":
|
|
18844
|
-
"gpt-4o":
|
|
18845
|
-
"gpt-4o-mini":
|
|
18846
|
-
"gpt-4-turbo":
|
|
18847
|
-
"gpt-4.1":
|
|
18848
|
-
"gpt-4.1-mini":
|
|
18849
|
-
"gpt-4.1-nano":
|
|
18850
|
-
"gpt-4.5":
|
|
19125
|
+
"gpt-4": ChatModels.GPT4,
|
|
19126
|
+
"gpt-4o": ChatModels.GPT4o,
|
|
19127
|
+
"gpt-4o-mini": ChatModels.GPT4o_MINI,
|
|
19128
|
+
"gpt-4-turbo": ChatModels.GPT4_TURBO,
|
|
19129
|
+
"gpt-4.1": ChatModels.GPT4_1,
|
|
19130
|
+
"gpt-4.1-mini": ChatModels.GPT4_1_MINI,
|
|
19131
|
+
"gpt-4.1-nano": ChatModels.GPT4_1_NANO,
|
|
19132
|
+
"gpt-4.5": ChatModels.GPT4_5_PREVIEW,
|
|
18851
19133
|
// GPT-5 family
|
|
18852
|
-
"gpt-5":
|
|
18853
|
-
"gpt-5-mini":
|
|
18854
|
-
"gpt-5-nano":
|
|
18855
|
-
"gpt-5.1":
|
|
18856
|
-
"gpt-5.2":
|
|
19134
|
+
"gpt-5": ChatModels.GPT5,
|
|
19135
|
+
"gpt-5-mini": ChatModels.GPT5_MINI,
|
|
19136
|
+
"gpt-5-nano": ChatModels.GPT5_NANO,
|
|
19137
|
+
"gpt-5.1": ChatModels.GPT5_1,
|
|
19138
|
+
"gpt-5.2": ChatModels.GPT5_2,
|
|
18857
19139
|
// OpenAI reasoning models (o-series)
|
|
18858
|
-
o1:
|
|
18859
|
-
"o1-preview":
|
|
18860
|
-
"o1-mini":
|
|
18861
|
-
o3:
|
|
18862
|
-
"o3-mini":
|
|
18863
|
-
"o4-mini":
|
|
19140
|
+
o1: ChatModels.O1,
|
|
19141
|
+
"o1-preview": ChatModels.O1_PREVIEW,
|
|
19142
|
+
"o1-mini": ChatModels.O1_MINI,
|
|
19143
|
+
o3: ChatModels.O3,
|
|
19144
|
+
"o3-mini": ChatModels.O3_MINI,
|
|
19145
|
+
"o4-mini": ChatModels.O4_MINI,
|
|
18864
19146
|
// ===================
|
|
18865
19147
|
// Google Gemini Models
|
|
18866
19148
|
// ===================
|
|
18867
|
-
gemini:
|
|
18868
|
-
"gemini-pro":
|
|
18869
|
-
"gemini-flash":
|
|
18870
|
-
"gemini-flash-lite":
|
|
19149
|
+
gemini: ChatModels.GEMINI_2_5_PRO,
|
|
19150
|
+
"gemini-pro": ChatModels.GEMINI_2_5_PRO,
|
|
19151
|
+
"gemini-flash": ChatModels.GEMINI_2_5_FLASH,
|
|
19152
|
+
"gemini-flash-lite": ChatModels.GEMINI_2_5_FLASH_LITE,
|
|
18871
19153
|
// Gemini 3 (preview)
|
|
18872
|
-
"gemini-3":
|
|
18873
|
-
"gemini-3-pro":
|
|
18874
|
-
"gemini-3-flash":
|
|
19154
|
+
"gemini-3": ChatModels.GEMINI_3_PRO_PREVIEW,
|
|
19155
|
+
"gemini-3-pro": ChatModels.GEMINI_3_PRO_PREVIEW,
|
|
19156
|
+
"gemini-3-flash": ChatModels.GEMINI_3_FLASH_PREVIEW,
|
|
18875
19157
|
// Gemini 2.5
|
|
18876
|
-
"gemini-2.5":
|
|
18877
|
-
"gemini-2.5-pro":
|
|
18878
|
-
"gemini-2.5-flash":
|
|
19158
|
+
"gemini-2.5": ChatModels.GEMINI_2_5_PRO,
|
|
19159
|
+
"gemini-2.5-pro": ChatModels.GEMINI_2_5_PRO,
|
|
19160
|
+
"gemini-2.5-flash": ChatModels.GEMINI_2_5_FLASH,
|
|
18879
19161
|
// Gemini 2.0
|
|
18880
|
-
"gemini-2.0-flash":
|
|
19162
|
+
"gemini-2.0-flash": ChatModels.GEMINI_2_0_FLASH_EXP,
|
|
18881
19163
|
// Gemini 1.5 (legacy)
|
|
18882
|
-
"gemini-1.5-pro":
|
|
18883
|
-
"gemini-1.5-flash":
|
|
18884
|
-
"gemini-1.5-flash-8b":
|
|
19164
|
+
"gemini-1.5-pro": ChatModels.GEMINI_1_5_PRO,
|
|
19165
|
+
"gemini-1.5-flash": ChatModels.GEMINI_1_5_FLASH,
|
|
19166
|
+
"gemini-1.5-flash-8b": ChatModels.GEMINI_1_5_FLASH_8B,
|
|
18885
19167
|
// ===================
|
|
18886
19168
|
// xAI Grok Models
|
|
18887
19169
|
// ===================
|
|
18888
|
-
grok:
|
|
18889
|
-
"grok-3":
|
|
18890
|
-
"grok-3-fast":
|
|
18891
|
-
"grok-3-mini":
|
|
18892
|
-
"grok-3-mini-fast":
|
|
18893
|
-
"grok-2":
|
|
18894
|
-
"grok-2-vision":
|
|
19170
|
+
grok: ChatModels.GROK_3,
|
|
19171
|
+
"grok-3": ChatModels.GROK_3,
|
|
19172
|
+
"grok-3-fast": ChatModels.GROK_3_FAST,
|
|
19173
|
+
"grok-3-mini": ChatModels.GROK_3_MINI,
|
|
19174
|
+
"grok-3-mini-fast": ChatModels.GROK_3_MINI_FAST,
|
|
19175
|
+
"grok-2": ChatModels.GROK_2,
|
|
19176
|
+
"grok-2-vision": ChatModels.GROK_2_VISION,
|
|
18895
19177
|
// ===================
|
|
18896
19178
|
// DeepSeek Models
|
|
18897
19179
|
// ===================
|
|
18898
|
-
deepseek:
|
|
18899
|
-
"deepseek-r1":
|
|
19180
|
+
deepseek: ChatModels.DEEPSEEK_R1,
|
|
19181
|
+
"deepseek-r1": ChatModels.DEEPSEEK_R1,
|
|
18900
19182
|
// ===================
|
|
18901
19183
|
// Llama Models (Ollama local)
|
|
18902
19184
|
// ===================
|
|
18903
|
-
llama:
|
|
18904
|
-
llama3:
|
|
18905
|
-
"llama3.3":
|
|
18906
|
-
tinyllama:
|
|
19185
|
+
llama: ChatModels.LLAMA3_LOCAL,
|
|
19186
|
+
llama3: ChatModels.LLAMA3_LOCAL,
|
|
19187
|
+
"llama3.3": ChatModels.LLAMA3_LOCAL,
|
|
19188
|
+
tinyllama: ChatModels.TINYLLAMA
|
|
18907
19189
|
};
|
|
18908
19190
|
function getAvailableModelAliases() {
|
|
18909
19191
|
return Object.keys(MODEL_ALIASES).sort();
|
|
@@ -19112,7 +19394,7 @@ var AgentStore = class {
|
|
|
19112
19394
|
await fs13.mkdir(targetDir, { recursive: true });
|
|
19113
19395
|
const template = `---
|
|
19114
19396
|
description: ${name} agent description
|
|
19115
|
-
model:
|
|
19397
|
+
model: ${ChatModels.CLAUDE_3_5_HAIKU_ANTHROPIC}
|
|
19116
19398
|
allowed-tools:
|
|
19117
19399
|
- file_read
|
|
19118
19400
|
- grep_search
|
|
@@ -19253,9 +19535,9 @@ ${agentDescriptions}
|
|
|
19253
19535
|
type: "string",
|
|
19254
19536
|
enum: ["quick", "medium", "very_thorough"],
|
|
19255
19537
|
description: `How thoroughly to execute:
|
|
19256
|
-
- quick: Fast lookup,
|
|
19257
|
-
- medium: Balanced exploration
|
|
19258
|
-
- very_thorough: Comprehensive analysis,
|
|
19538
|
+
- quick: Fast lookup, fewest iterations
|
|
19539
|
+
- medium: Balanced exploration (default)
|
|
19540
|
+
- very_thorough: Comprehensive analysis, maximum iterations`
|
|
19259
19541
|
},
|
|
19260
19542
|
variables: {
|
|
19261
19543
|
type: "object",
|
|
@@ -20102,7 +20384,7 @@ var usageCache = null;
|
|
|
20102
20384
|
function CliApp() {
|
|
20103
20385
|
const { exit } = useApp();
|
|
20104
20386
|
const imageRenderer = new ImageRenderer();
|
|
20105
|
-
const [state, setState] =
|
|
20387
|
+
const [state, setState] = useState11({
|
|
20106
20388
|
session: null,
|
|
20107
20389
|
sessionStore: new SessionStore(),
|
|
20108
20390
|
configStore: new ConfigStore(),
|
|
@@ -20127,17 +20409,19 @@ function CliApp() {
|
|
|
20127
20409
|
wsManager: null,
|
|
20128
20410
|
checkpointStore: null
|
|
20129
20411
|
});
|
|
20130
|
-
const [isInitialized, setIsInitialized] =
|
|
20131
|
-
const [initError, setInitError] =
|
|
20132
|
-
const [commandHistory, setCommandHistory] =
|
|
20412
|
+
const [isInitialized, setIsInitialized] = useState11(false);
|
|
20413
|
+
const [initError, setInitError] = useState11(null);
|
|
20414
|
+
const [commandHistory, setCommandHistory] = useState11([]);
|
|
20133
20415
|
const imageStoreInitPromise = useRef3(null);
|
|
20134
20416
|
const setStoreSession = useCliStore((state2) => state2.setSession);
|
|
20135
20417
|
const enqueuePermissionPrompt = useCliStore((state2) => state2.enqueuePermissionPrompt);
|
|
20136
20418
|
const dequeuePermissionPrompt = useCliStore((state2) => state2.dequeuePermissionPrompt);
|
|
20419
|
+
const enqueueUserQuestionPrompt = useCliStore((state2) => state2.enqueueUserQuestionPrompt);
|
|
20420
|
+
const dequeueUserQuestionPrompt = useCliStore((state2) => state2.dequeueUserQuestionPrompt);
|
|
20137
20421
|
const setShowConfigEditor = useCliStore((state2) => state2.setShowConfigEditor);
|
|
20138
20422
|
const setShowMcpViewer = useCliStore((state2) => state2.setShowMcpViewer);
|
|
20139
20423
|
const setExitRequested = useCliStore((state2) => state2.setExitRequested);
|
|
20140
|
-
const performCleanup =
|
|
20424
|
+
const performCleanup = useCallback3(async () => {
|
|
20141
20425
|
const cleanupTasks = [];
|
|
20142
20426
|
if (state.session) {
|
|
20143
20427
|
cleanupTasks.push(
|
|
@@ -20176,7 +20460,7 @@ function CliApp() {
|
|
|
20176
20460
|
process.exit(0);
|
|
20177
20461
|
}, 100);
|
|
20178
20462
|
}, [state.session, state.sessionStore, state.mcpManager, state.agent, state.imageStore, state.wsManager]);
|
|
20179
|
-
|
|
20463
|
+
useInput10((input, key) => {
|
|
20180
20464
|
if (key.escape) {
|
|
20181
20465
|
const store = useCliStore.getState();
|
|
20182
20466
|
if (store.pastedContent) {
|
|
@@ -20213,7 +20497,7 @@ function CliApp() {
|
|
|
20213
20497
|
}
|
|
20214
20498
|
}
|
|
20215
20499
|
});
|
|
20216
|
-
const init =
|
|
20500
|
+
const init = useCallback3(async () => {
|
|
20217
20501
|
try {
|
|
20218
20502
|
const startupLog = [];
|
|
20219
20503
|
const config = await state.configStore.load();
|
|
@@ -20379,6 +20663,13 @@ function CliApp() {
|
|
|
20379
20663
|
enqueuePermissionPrompt(prompt);
|
|
20380
20664
|
});
|
|
20381
20665
|
};
|
|
20666
|
+
let userQuestionCounter = 0;
|
|
20667
|
+
const userQuestionFn = (payload) => {
|
|
20668
|
+
return new Promise((resolve3) => {
|
|
20669
|
+
const id = `uq-${++userQuestionCounter}`;
|
|
20670
|
+
enqueueUserQuestionPrompt({ id, payload, resolve: resolve3 });
|
|
20671
|
+
});
|
|
20672
|
+
};
|
|
20382
20673
|
const checkpointProjectDir = state.configStore.getProjectConfigDir() || process.cwd();
|
|
20383
20674
|
const checkpointStore = new CheckpointStore(checkpointProjectDir);
|
|
20384
20675
|
try {
|
|
@@ -20400,6 +20691,7 @@ function CliApp() {
|
|
|
20400
20691
|
apiClient,
|
|
20401
20692
|
void 0,
|
|
20402
20693
|
// toolFilter
|
|
20694
|
+
userQuestionFn,
|
|
20403
20695
|
checkpointStore
|
|
20404
20696
|
);
|
|
20405
20697
|
startupLog.push(`\u{1F6E0}\uFE0F Loaded ${b4mTools2.length} B4M tool(s)`);
|
|
@@ -20432,6 +20724,7 @@ function CliApp() {
|
|
|
20432
20724
|
agentStore,
|
|
20433
20725
|
customCommandStore: state.customCommandStore,
|
|
20434
20726
|
enableParallelToolExecution: config.preferences.enableParallelToolExecution === true,
|
|
20727
|
+
showUserQuestion: userQuestionFn,
|
|
20435
20728
|
checkpointStore
|
|
20436
20729
|
});
|
|
20437
20730
|
const backgroundManager = new BackgroundAgentManager(orchestrator);
|
|
@@ -21073,7 +21366,7 @@ function CliApp() {
|
|
|
21073
21366
|
useCliStore.getState().setIsThinking(false);
|
|
21074
21367
|
}
|
|
21075
21368
|
};
|
|
21076
|
-
const handleBashCommand =
|
|
21369
|
+
const handleBashCommand = useCallback3(
|
|
21077
21370
|
(command) => {
|
|
21078
21371
|
if (!state.session) return;
|
|
21079
21372
|
let output;
|
|
@@ -21572,7 +21865,7 @@ Keyboard Shortcuts:
|
|
|
21572
21865
|
case "clear":
|
|
21573
21866
|
case "new": {
|
|
21574
21867
|
console.clear();
|
|
21575
|
-
const model = state.session?.model || state.config?.defaultModel ||
|
|
21868
|
+
const model = state.session?.model || state.config?.defaultModel || ChatModels.CLAUDE_4_5_SONNET;
|
|
21576
21869
|
const newSession = {
|
|
21577
21870
|
id: uuidv413(),
|
|
21578
21871
|
name: `Session ${(/* @__PURE__ */ new Date()).toLocaleString()}`,
|
|
@@ -22185,12 +22478,12 @@ No usage data available for the last ${USAGE_DAYS} days.`);
|
|
|
22185
22478
|
}
|
|
22186
22479
|
};
|
|
22187
22480
|
if (initError) {
|
|
22188
|
-
return /* @__PURE__ */
|
|
22481
|
+
return /* @__PURE__ */ React22.createElement(Box21, { flexDirection: "column", padding: 1 }, /* @__PURE__ */ React22.createElement(Text21, { color: "red", bold: true }, "\u274C Initialization Error"), /* @__PURE__ */ React22.createElement(Text21, null, initError), /* @__PURE__ */ React22.createElement(Text21, { dimColor: true }, "\n", "Tip: Run /config to set up your API keys"));
|
|
22189
22482
|
}
|
|
22190
22483
|
if (state.trustLocationSelector) {
|
|
22191
22484
|
const projectDir = state.configStore.getProjectConfigDir();
|
|
22192
22485
|
const inProject = projectDir !== null;
|
|
22193
|
-
return /* @__PURE__ */
|
|
22486
|
+
return /* @__PURE__ */ React22.createElement(
|
|
22194
22487
|
TrustLocationSelector,
|
|
22195
22488
|
{
|
|
22196
22489
|
inProject,
|
|
@@ -22208,7 +22501,7 @@ No usage data available for the last ${USAGE_DAYS} days.`);
|
|
|
22208
22501
|
);
|
|
22209
22502
|
}
|
|
22210
22503
|
if (state.rewindSelector && state.session) {
|
|
22211
|
-
return /* @__PURE__ */
|
|
22504
|
+
return /* @__PURE__ */ React22.createElement(
|
|
22212
22505
|
RewindSelector,
|
|
22213
22506
|
{
|
|
22214
22507
|
messages: state.session.messages,
|
|
@@ -22226,7 +22519,7 @@ No usage data available for the last ${USAGE_DAYS} days.`);
|
|
|
22226
22519
|
);
|
|
22227
22520
|
}
|
|
22228
22521
|
if (state.sessionSelector) {
|
|
22229
|
-
return /* @__PURE__ */
|
|
22522
|
+
return /* @__PURE__ */ React22.createElement(
|
|
22230
22523
|
SessionSelector,
|
|
22231
22524
|
{
|
|
22232
22525
|
sessions: state.sessionSelector.sessions,
|
|
@@ -22246,7 +22539,7 @@ No usage data available for the last ${USAGE_DAYS} days.`);
|
|
|
22246
22539
|
}
|
|
22247
22540
|
if (state.showLoginFlow) {
|
|
22248
22541
|
const loginApiUrl = getApiUrl(state.config?.apiConfig);
|
|
22249
|
-
return /* @__PURE__ */
|
|
22542
|
+
return /* @__PURE__ */ React22.createElement(
|
|
22250
22543
|
LoginFlow,
|
|
22251
22544
|
{
|
|
22252
22545
|
apiUrl: loginApiUrl,
|
|
@@ -22269,10 +22562,10 @@ No usage data available for the last ${USAGE_DAYS} days.`);
|
|
|
22269
22562
|
);
|
|
22270
22563
|
}
|
|
22271
22564
|
if (!isInitialized) {
|
|
22272
|
-
return /* @__PURE__ */
|
|
22565
|
+
return /* @__PURE__ */ React22.createElement(Box21, { flexDirection: "column", padding: 1 }, /* @__PURE__ */ React22.createElement(Text21, null, "\u{1F680} Initializing..."));
|
|
22273
22566
|
}
|
|
22274
22567
|
const allCommands = mergeCommands(state.customCommandStore.getAllCommands());
|
|
22275
|
-
return /* @__PURE__ */
|
|
22568
|
+
return /* @__PURE__ */ React22.createElement(
|
|
22276
22569
|
App,
|
|
22277
22570
|
{
|
|
22278
22571
|
onMessage: handleMessage,
|
|
@@ -22296,6 +22589,13 @@ No usage data available for the last ${USAGE_DAYS} days.`);
|
|
|
22296
22589
|
currentPrompt.resolve({ action: response });
|
|
22297
22590
|
dequeuePermissionPrompt();
|
|
22298
22591
|
}
|
|
22592
|
+
},
|
|
22593
|
+
onUserQuestionResponse: (response) => {
|
|
22594
|
+
const currentPrompt = useCliStore.getState().userQuestionPrompt;
|
|
22595
|
+
if (currentPrompt) {
|
|
22596
|
+
currentPrompt.resolve(response);
|
|
22597
|
+
dequeueUserQuestionPrompt();
|
|
22598
|
+
}
|
|
22299
22599
|
}
|
|
22300
22600
|
}
|
|
22301
22601
|
);
|
|
@@ -22318,6 +22618,6 @@ if (isDevMode) {
|
|
|
22318
22618
|
logger.debug("\u{1F527} Running in development mode (using TypeScript source)\n");
|
|
22319
22619
|
}
|
|
22320
22620
|
warmFileCache();
|
|
22321
|
-
render(/* @__PURE__ */
|
|
22621
|
+
render(/* @__PURE__ */ React22.createElement(CliApp, null), {
|
|
22322
22622
|
exitOnCtrlC: false
|
|
22323
22623
|
});
|