@bike4mind/cli 0.2.7-basic-cli-shortcuts.17131 → 0.2.7-feature-notebook-splash-redesign.17129
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 +106 -201
- package/package.json +7 -7
package/dist/index.js
CHANGED
|
@@ -79,13 +79,13 @@ import {
|
|
|
79
79
|
} from "./chunk-PDX44BCA.js";
|
|
80
80
|
|
|
81
81
|
// src/index.tsx
|
|
82
|
-
import
|
|
83
|
-
import { render, Box as Box13, Text as
|
|
82
|
+
import React13, { useState as useState4, useEffect as useEffect3, useCallback, useRef } from "react";
|
|
83
|
+
import { render, Box as Box13, Text as Text12, useApp, useInput as useInput3 } from "ink";
|
|
84
84
|
import { v4 as uuidv49 } from "uuid";
|
|
85
85
|
|
|
86
86
|
// src/components/App.tsx
|
|
87
|
-
import
|
|
88
|
-
import { Box as Box9, Text as
|
|
87
|
+
import React9 from "react";
|
|
88
|
+
import { Box as Box9, Text as Text8, Static } from "ink";
|
|
89
89
|
|
|
90
90
|
// src/components/StatusBar.tsx
|
|
91
91
|
import React from "react";
|
|
@@ -95,127 +95,27 @@ var StatusBar = React.memo(function StatusBar2({ sessionName, model, tokenUsage
|
|
|
95
95
|
});
|
|
96
96
|
|
|
97
97
|
// src/components/InputPrompt.tsx
|
|
98
|
-
import
|
|
99
|
-
import { Box as Box4, Text as
|
|
100
|
-
|
|
101
|
-
// src/components/CustomTextInput.tsx
|
|
102
|
-
import React2, { useState } from "react";
|
|
103
|
-
import { Text as Text2, useInput } from "ink";
|
|
104
|
-
function CustomTextInput({
|
|
105
|
-
value,
|
|
106
|
-
onChange,
|
|
107
|
-
onSubmit,
|
|
108
|
-
placeholder = "",
|
|
109
|
-
showCursor = true
|
|
110
|
-
}) {
|
|
111
|
-
const [cursorOffset, setCursorOffset] = useState(value.length);
|
|
112
|
-
useInput(
|
|
113
|
-
(input, key) => {
|
|
114
|
-
if (key.return && !key.meta && !key.shift) {
|
|
115
|
-
onSubmit(value);
|
|
116
|
-
return;
|
|
117
|
-
}
|
|
118
|
-
if (key.ctrl) {
|
|
119
|
-
switch (input) {
|
|
120
|
-
case "u":
|
|
121
|
-
{
|
|
122
|
-
const lines = value.split("\n");
|
|
123
|
-
let currentLineStart = 0;
|
|
124
|
-
let currentLineIndex = 0;
|
|
125
|
-
let charCount = 0;
|
|
126
|
-
for (let i = 0; i < lines.length; i++) {
|
|
127
|
-
const lineLength = lines[i].length;
|
|
128
|
-
if (charCount + lineLength >= cursorOffset) {
|
|
129
|
-
currentLineIndex = i;
|
|
130
|
-
currentLineStart = charCount;
|
|
131
|
-
break;
|
|
132
|
-
}
|
|
133
|
-
charCount += lineLength + 1;
|
|
134
|
-
}
|
|
135
|
-
lines.splice(currentLineIndex, 1);
|
|
136
|
-
const newValue = lines.join("\n");
|
|
137
|
-
onChange(newValue);
|
|
138
|
-
setCursorOffset(Math.min(currentLineStart, newValue.length));
|
|
139
|
-
}
|
|
140
|
-
return;
|
|
141
|
-
case "k":
|
|
142
|
-
onChange(value.slice(0, cursorOffset));
|
|
143
|
-
return;
|
|
144
|
-
case "w":
|
|
145
|
-
{
|
|
146
|
-
const beforeCursor2 = value.slice(0, cursorOffset);
|
|
147
|
-
const afterCursor2 = value.slice(cursorOffset);
|
|
148
|
-
const trimmed = beforeCursor2.trimEnd();
|
|
149
|
-
const lastSpace = trimmed.lastIndexOf(" ");
|
|
150
|
-
const newBefore = lastSpace === -1 ? "" : trimmed.slice(0, lastSpace + 1);
|
|
151
|
-
const newValue = newBefore + afterCursor2;
|
|
152
|
-
onChange(newValue);
|
|
153
|
-
setCursorOffset(newBefore.length);
|
|
154
|
-
}
|
|
155
|
-
return;
|
|
156
|
-
case "a":
|
|
157
|
-
setCursorOffset(0);
|
|
158
|
-
return;
|
|
159
|
-
case "e":
|
|
160
|
-
setCursorOffset(value.length);
|
|
161
|
-
return;
|
|
162
|
-
case "l":
|
|
163
|
-
onChange("");
|
|
164
|
-
return;
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
if (key.backspace || key.delete) {
|
|
168
|
-
if (cursorOffset > 0) {
|
|
169
|
-
const newValue = value.slice(0, cursorOffset - 1) + value.slice(cursorOffset);
|
|
170
|
-
onChange(newValue);
|
|
171
|
-
setCursorOffset(cursorOffset - 1);
|
|
172
|
-
}
|
|
173
|
-
return;
|
|
174
|
-
}
|
|
175
|
-
if (key.leftArrow) {
|
|
176
|
-
setCursorOffset(Math.max(0, cursorOffset - 1));
|
|
177
|
-
return;
|
|
178
|
-
}
|
|
179
|
-
if (key.rightArrow) {
|
|
180
|
-
setCursorOffset(Math.min(value.length, cursorOffset + 1));
|
|
181
|
-
return;
|
|
182
|
-
}
|
|
183
|
-
if (!key.ctrl && !key.meta && input.length === 1) {
|
|
184
|
-
const sanitizedInput = input === "\r" ? "\n" : input;
|
|
185
|
-
const newValue = value.slice(0, cursorOffset) + sanitizedInput + value.slice(cursorOffset);
|
|
186
|
-
onChange(newValue);
|
|
187
|
-
setCursorOffset(cursorOffset + 1);
|
|
188
|
-
}
|
|
189
|
-
},
|
|
190
|
-
{ isActive: true }
|
|
191
|
-
);
|
|
192
|
-
const hasValue = value.length > 0;
|
|
193
|
-
if (!hasValue) {
|
|
194
|
-
return /* @__PURE__ */ React2.createElement(Text2, null, showCursor ? /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(Text2, { inverse: true }, " "), /* @__PURE__ */ React2.createElement(Text2, { dimColor: true }, placeholder)) : /* @__PURE__ */ React2.createElement(Text2, { dimColor: true }, placeholder));
|
|
195
|
-
}
|
|
196
|
-
const beforeCursor = value.slice(0, cursorOffset);
|
|
197
|
-
const cursorChar = value[cursorOffset] || " ";
|
|
198
|
-
const afterCursor = value.slice(cursorOffset + 1);
|
|
199
|
-
return /* @__PURE__ */ React2.createElement(Text2, null, beforeCursor, showCursor && /* @__PURE__ */ React2.createElement(Text2, { inverse: true }, cursorChar), !showCursor && cursorChar, afterCursor);
|
|
200
|
-
}
|
|
98
|
+
import React4, { useState, useMemo, useEffect } from "react";
|
|
99
|
+
import { Box as Box4, Text as Text4, useInput } from "ink";
|
|
100
|
+
import TextInput from "ink-text-input";
|
|
201
101
|
|
|
202
102
|
// src/components/CommandAutocomplete.tsx
|
|
203
|
-
import
|
|
204
|
-
import { Box as Box2, Text as
|
|
103
|
+
import React2 from "react";
|
|
104
|
+
import { Box as Box2, Text as Text2 } from "ink";
|
|
205
105
|
function CommandAutocomplete({ commands, selectedIndex }) {
|
|
206
106
|
if (commands.length === 0) {
|
|
207
|
-
return /* @__PURE__ */
|
|
107
|
+
return /* @__PURE__ */ React2.createElement(Box2, { marginLeft: 2, marginTop: 1 }, /* @__PURE__ */ React2.createElement(Text2, { dimColor: true }, "No matching commands"));
|
|
208
108
|
}
|
|
209
|
-
return /* @__PURE__ */
|
|
109
|
+
return /* @__PURE__ */ React2.createElement(Box2, { flexDirection: "column", marginLeft: 2, marginTop: 1 }, /* @__PURE__ */ React2.createElement(Box2, { marginBottom: 1 }, /* @__PURE__ */ React2.createElement(Text2, { dimColor: true }, commands.length === 1 ? "1 command" : `${commands.length} commands`, " \u2022 Use \u2191\u2193 to navigate, Enter to select")), commands.map((cmd, index) => {
|
|
210
110
|
const args = cmd.args ? ` ${cmd.args}` : "";
|
|
211
111
|
const isSelected = index === selectedIndex;
|
|
212
|
-
return /* @__PURE__ */
|
|
112
|
+
return /* @__PURE__ */ React2.createElement(Box2, { key: cmd.name, marginLeft: 1 }, /* @__PURE__ */ React2.createElement(Text2, { color: isSelected ? "cyan" : void 0, bold: isSelected }, isSelected ? "\u25B8 " : " ", "/", cmd.name, args, " - ", cmd.description));
|
|
213
113
|
}));
|
|
214
114
|
}
|
|
215
115
|
|
|
216
116
|
// src/components/FileAutocomplete.tsx
|
|
217
|
-
import
|
|
218
|
-
import { Box as Box3, Text as
|
|
117
|
+
import React3 from "react";
|
|
118
|
+
import { Box as Box3, Text as Text3 } from "ink";
|
|
219
119
|
|
|
220
120
|
// src/utils/fileSearch.ts
|
|
221
121
|
import * as fs from "fs";
|
|
@@ -404,14 +304,14 @@ var MAX_FILE_SIZE = 10 * 1024 * 1024;
|
|
|
404
304
|
// src/components/FileAutocomplete.tsx
|
|
405
305
|
function FileAutocomplete({ files, selectedIndex, query }) {
|
|
406
306
|
if (files.length === 0) {
|
|
407
|
-
return /* @__PURE__ */
|
|
307
|
+
return /* @__PURE__ */ React3.createElement(Box3, { marginLeft: 2, marginTop: 1 }, /* @__PURE__ */ React3.createElement(Text3, { dimColor: true }, "No matching files", query ? ` for "${query}"` : ""));
|
|
408
308
|
}
|
|
409
|
-
return /* @__PURE__ */
|
|
309
|
+
return /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column", marginLeft: 2, marginTop: 1 }, /* @__PURE__ */ React3.createElement(Box3, { marginBottom: 1 }, /* @__PURE__ */ React3.createElement(Text3, { dimColor: true }, files.length === 1 ? "1 match" : `${files.length} matches`, " - Use up/down to navigate, Tab to select")), files.map((file, index) => {
|
|
410
310
|
const isSelected = index === selectedIndex;
|
|
411
311
|
const icon = file.isDirectory ? "[folder]" : "[file] ";
|
|
412
312
|
const sizeDisplay = file.isDirectory ? "" : file.size !== void 0 ? ` (${formatFileSize(file.size)})` : "";
|
|
413
313
|
const pathDisplay = file.isDirectory ? `${file.path}/` : file.path;
|
|
414
|
-
return /* @__PURE__ */
|
|
314
|
+
return /* @__PURE__ */ React3.createElement(Box3, { key: file.path, marginLeft: 1 }, /* @__PURE__ */ React3.createElement(Text3, { color: isSelected ? "cyan" : void 0, bold: isSelected }, isSelected ? "> " : " "), /* @__PURE__ */ React3.createElement(Text3, { color: file.isDirectory ? "yellow" : isSelected ? "cyan" : void 0, bold: isSelected }, icon), /* @__PURE__ */ React3.createElement(Text3, { color: isSelected ? "cyan" : void 0, bold: isSelected }, " ", pathDisplay), /* @__PURE__ */ React3.createElement(Text3, { dimColor: true }, sizeDisplay));
|
|
415
315
|
}));
|
|
416
316
|
}
|
|
417
317
|
|
|
@@ -726,12 +626,13 @@ function findAtTrigger(value) {
|
|
|
726
626
|
return null;
|
|
727
627
|
}
|
|
728
628
|
function InputPrompt({ onSubmit, onImageDetected, disabled = false, history = [] }) {
|
|
729
|
-
const [value, setValue] =
|
|
730
|
-
const [selectedIndex, setSelectedIndex] =
|
|
731
|
-
const [historyIndex, setHistoryIndex] =
|
|
732
|
-
const [tempInput, setTempInput] =
|
|
733
|
-
const [
|
|
734
|
-
const [
|
|
629
|
+
const [value, setValue] = useState("");
|
|
630
|
+
const [selectedIndex, setSelectedIndex] = useState(0);
|
|
631
|
+
const [historyIndex, setHistoryIndex] = useState(-1);
|
|
632
|
+
const [tempInput, setTempInput] = useState("");
|
|
633
|
+
const [inputKey, setInputKey] = useState(0);
|
|
634
|
+
const [fileAutocomplete, setFileAutocomplete] = useState(null);
|
|
635
|
+
const [fileSelectedIndex, setFileSelectedIndex] = useState(0);
|
|
735
636
|
const shouldShowCommandAutocomplete = value.startsWith("/") && !disabled && !fileAutocomplete?.active;
|
|
736
637
|
const commandQuery = shouldShowCommandAutocomplete ? value.slice(1) : "";
|
|
737
638
|
const filteredCommands = useMemo(() => {
|
|
@@ -748,7 +649,7 @@ function InputPrompt({ onSubmit, onImageDetected, disabled = false, history = []
|
|
|
748
649
|
useEffect(() => {
|
|
749
650
|
setFileSelectedIndex(0);
|
|
750
651
|
}, [filteredFiles]);
|
|
751
|
-
|
|
652
|
+
useInput((input, key) => {
|
|
752
653
|
if (fileAutocomplete?.active && filteredFiles.length > 0) {
|
|
753
654
|
if (key.upArrow) {
|
|
754
655
|
setFileSelectedIndex((prev) => prev > 0 ? prev - 1 : filteredFiles.length - 1);
|
|
@@ -805,6 +706,7 @@ function InputPrompt({ onSubmit, onImageDetected, disabled = false, history = []
|
|
|
805
706
|
const pathToInsert = file.isDirectory ? `@${file.path}/` : `@${file.path}`;
|
|
806
707
|
const newValue = beforeAt + pathToInsert + afterQuery;
|
|
807
708
|
setValue(newValue);
|
|
709
|
+
setInputKey((prev) => prev + 1);
|
|
808
710
|
if (file.isDirectory) {
|
|
809
711
|
setFileAutocomplete({
|
|
810
712
|
active: true,
|
|
@@ -831,6 +733,7 @@ function InputPrompt({ onSubmit, onImageDetected, disabled = false, history = []
|
|
|
831
733
|
if (selectedCommand.args) {
|
|
832
734
|
setValue(commandText + " ");
|
|
833
735
|
setHistoryIndex(-1);
|
|
736
|
+
setInputKey((prev) => prev + 1);
|
|
834
737
|
return;
|
|
835
738
|
}
|
|
836
739
|
setValue("");
|
|
@@ -849,6 +752,7 @@ function InputPrompt({ onSubmit, onImageDetected, disabled = false, history = []
|
|
|
849
752
|
if (imageEvent && onImageDetected) {
|
|
850
753
|
const placeholder = await onImageDetected(imageEvent.data);
|
|
851
754
|
setValue(`${placeholder} `);
|
|
755
|
+
setInputKey((prev) => prev + 1);
|
|
852
756
|
return;
|
|
853
757
|
}
|
|
854
758
|
}
|
|
@@ -868,28 +772,29 @@ function InputPrompt({ onSubmit, onImageDetected, disabled = false, history = []
|
|
|
868
772
|
setFileAutocomplete(null);
|
|
869
773
|
}
|
|
870
774
|
};
|
|
871
|
-
return /* @__PURE__ */
|
|
872
|
-
|
|
775
|
+
return /* @__PURE__ */ React4.createElement(Box4, { flexDirection: "column" }, /* @__PURE__ */ React4.createElement(Box4, null, /* @__PURE__ */ React4.createElement(Text4, { bold: true, color: "cyan" }, "> "), /* @__PURE__ */ React4.createElement(
|
|
776
|
+
TextInput,
|
|
873
777
|
{
|
|
778
|
+
key: inputKey,
|
|
874
779
|
value,
|
|
875
780
|
onChange: handleChange,
|
|
876
781
|
onSubmit: handleSubmit,
|
|
877
782
|
placeholder: disabled ? "Thinking..." : "Type your message, /help for commands, or @file to reference",
|
|
878
783
|
showCursor: !disabled
|
|
879
784
|
}
|
|
880
|
-
)), shouldShowCommandAutocomplete && /* @__PURE__ */
|
|
785
|
+
)), shouldShowCommandAutocomplete && /* @__PURE__ */ React4.createElement(CommandAutocomplete, { commands: filteredCommands, selectedIndex }), fileAutocomplete?.active && /* @__PURE__ */ React4.createElement(FileAutocomplete, { files: filteredFiles, selectedIndex: fileSelectedIndex, query: fileAutocomplete.query }));
|
|
881
786
|
}
|
|
882
787
|
|
|
883
788
|
// src/components/AgentThinking.tsx
|
|
884
|
-
import
|
|
789
|
+
import React6 from "react";
|
|
885
790
|
import { Box as Box6 } from "ink";
|
|
886
791
|
|
|
887
792
|
// src/components/ThoughtStream.tsx
|
|
888
|
-
import
|
|
889
|
-
import { Box as Box5, Text as
|
|
793
|
+
import React5 from "react";
|
|
794
|
+
import { Box as Box5, Text as Text5 } from "ink";
|
|
890
795
|
import Spinner from "ink-spinner";
|
|
891
|
-
var ThoughtStream =
|
|
892
|
-
return /* @__PURE__ */
|
|
796
|
+
var ThoughtStream = React5.memo(function ThoughtStream2({ steps }) {
|
|
797
|
+
return /* @__PURE__ */ React5.createElement(Box5, { flexDirection: "column", gap: 1 }, steps.map((step, index) => /* @__PURE__ */ React5.createElement(Box5, { key: index, flexDirection: "column" }, step.type === "thought" && /* @__PURE__ */ React5.createElement(Box5, null, /* @__PURE__ */ React5.createElement(Text5, { color: "magenta" }, "\u{1F914} Thought: "), /* @__PURE__ */ React5.createElement(Text5, null, step.content)), step.type === "action" && /* @__PURE__ */ React5.createElement(Box5, { flexDirection: "column" }, /* @__PURE__ */ React5.createElement(Box5, null, /* @__PURE__ */ React5.createElement(Text5, { color: "yellow" }, "\u26A1 Action: "), /* @__PURE__ */ React5.createElement(Text5, { bold: true }, step.metadata?.toolName || "unknown")), step.metadata?.toolInput && /* @__PURE__ */ React5.createElement(Box5, { paddingLeft: 2 }, /* @__PURE__ */ React5.createElement(Text5, { dimColor: true }, JSON.stringify(step.metadata.toolInput, null, 2)))), step.type === "observation" && /* @__PURE__ */ React5.createElement(Box5, { flexDirection: "column" }, /* @__PURE__ */ React5.createElement(Box5, null, /* @__PURE__ */ React5.createElement(Text5, { color: "blue" }, "\u{1F4CA} Observation: ")), /* @__PURE__ */ React5.createElement(Box5, { paddingLeft: 2 }, /* @__PURE__ */ React5.createElement(Text5, null, step.content))), step.type === "final_answer" && /* @__PURE__ */ React5.createElement(Box5, { flexDirection: "column" }, /* @__PURE__ */ React5.createElement(Box5, null, /* @__PURE__ */ React5.createElement(Text5, { color: "green", bold: true }, "\u2705 Final Answer:", " ")), /* @__PURE__ */ React5.createElement(Box5, { paddingLeft: 2 }, /* @__PURE__ */ React5.createElement(Text5, null, step.content)), step.metadata?.tokenUsage && /* @__PURE__ */ React5.createElement(Box5, { paddingLeft: 2 }, /* @__PURE__ */ React5.createElement(Text5, { dimColor: true }, "(", step.metadata.tokenUsage.total, " tokens)"))))), !steps.some((s) => s.type === "final_answer") && /* @__PURE__ */ React5.createElement(Box5, null, /* @__PURE__ */ React5.createElement(Text5, { color: "yellow" }, /* @__PURE__ */ React5.createElement(Spinner, { type: "dots" })), /* @__PURE__ */ React5.createElement(Text5, null, " ", steps.length === 0 ? "Thinking..." : "Processing...")));
|
|
893
798
|
});
|
|
894
799
|
|
|
895
800
|
// src/store/index.ts
|
|
@@ -918,32 +823,32 @@ var useCliStore = create((set) => ({
|
|
|
918
823
|
}));
|
|
919
824
|
|
|
920
825
|
// src/components/AgentThinking.tsx
|
|
921
|
-
var AgentThinking =
|
|
826
|
+
var AgentThinking = React6.memo(function AgentThinking2() {
|
|
922
827
|
const isThinking = useCliStore((state) => state.isThinking);
|
|
923
828
|
const agentSteps = useCliStore((state) => state.agentSteps);
|
|
924
829
|
if (!isThinking) {
|
|
925
830
|
return null;
|
|
926
831
|
}
|
|
927
|
-
return /* @__PURE__ */
|
|
832
|
+
return /* @__PURE__ */ React6.createElement(Box6, { borderStyle: "single", borderColor: "yellow", paddingX: 1, marginY: 1 }, /* @__PURE__ */ React6.createElement(ThoughtStream, { steps: agentSteps }));
|
|
928
833
|
});
|
|
929
834
|
|
|
930
835
|
// src/components/PermissionPrompt.tsx
|
|
931
|
-
import
|
|
932
|
-
import { Box as Box7, Text as
|
|
836
|
+
import React7 from "react";
|
|
837
|
+
import { Box as Box7, Text as Text6 } from "ink";
|
|
933
838
|
import SelectInput from "ink-select-input";
|
|
934
839
|
function renderDiffPreview(preview) {
|
|
935
840
|
const lines = preview.split("\n");
|
|
936
841
|
return lines.map((line, index) => {
|
|
937
842
|
if (line.startsWith("+")) {
|
|
938
|
-
return /* @__PURE__ */
|
|
843
|
+
return /* @__PURE__ */ React7.createElement(Text6, { key: index, color: "green" }, line);
|
|
939
844
|
}
|
|
940
845
|
if (line.startsWith("-")) {
|
|
941
|
-
return /* @__PURE__ */
|
|
846
|
+
return /* @__PURE__ */ React7.createElement(Text6, { key: index, color: "red" }, line);
|
|
942
847
|
}
|
|
943
848
|
if (line.startsWith("@@")) {
|
|
944
|
-
return /* @__PURE__ */
|
|
849
|
+
return /* @__PURE__ */ React7.createElement(Text6, { key: index, color: "cyan" }, line);
|
|
945
850
|
}
|
|
946
|
-
return /* @__PURE__ */
|
|
851
|
+
return /* @__PURE__ */ React7.createElement(Text6, { key: index, dimColor: true }, line);
|
|
947
852
|
});
|
|
948
853
|
}
|
|
949
854
|
function PermissionPrompt({
|
|
@@ -963,12 +868,12 @@ function PermissionPrompt({
|
|
|
963
868
|
{ label: "\u2717 Deny", value: "deny" }
|
|
964
869
|
];
|
|
965
870
|
const argsString = typeof args === "string" ? args : JSON.stringify(args, null, 2);
|
|
966
|
-
return /* @__PURE__ */
|
|
871
|
+
return /* @__PURE__ */ React7.createElement(Box7, { flexDirection: "column", borderStyle: "bold", borderColor: "yellow", padding: 1, marginY: 1 }, /* @__PURE__ */ React7.createElement(Box7, null, /* @__PURE__ */ React7.createElement(Text6, { bold: true, color: "yellow" }, "\u26A0\uFE0F Permission Required")), /* @__PURE__ */ React7.createElement(Box7, { marginTop: 1 }, /* @__PURE__ */ React7.createElement(Text6, { dimColor: true }, "Tool: "), /* @__PURE__ */ React7.createElement(Text6, { bold: true, color: "cyan" }, toolName)), toolDescription && /* @__PURE__ */ React7.createElement(Box7, null, /* @__PURE__ */ React7.createElement(Text6, { dimColor: true }, "Action: "), /* @__PURE__ */ React7.createElement(Text6, null, toolDescription)), /* @__PURE__ */ React7.createElement(Box7, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React7.createElement(Text6, { bold: true }, "Arguments:"), /* @__PURE__ */ React7.createElement(Box7, { paddingLeft: 2, flexDirection: "column" }, /* @__PURE__ */ React7.createElement(Text6, { dimColor: true }, argsString))), preview && /* @__PURE__ */ React7.createElement(Box7, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React7.createElement(Text6, { bold: true }, "Preview:"), /* @__PURE__ */ React7.createElement(Box7, { borderStyle: "single", borderColor: "gray", paddingX: 1, flexDirection: "column" }, renderDiffPreview(preview))), !canBeTrusted && /* @__PURE__ */ React7.createElement(Box7, { marginTop: 1 }, /* @__PURE__ */ React7.createElement(Text6, { color: "red", dimColor: true }, "Note: This tool cannot be trusted due to its dangerous nature.")), /* @__PURE__ */ React7.createElement(Box7, { marginTop: 1 }, /* @__PURE__ */ React7.createElement(SelectInput, { items, onSelect: (item) => onResponse(item.value) })));
|
|
967
872
|
}
|
|
968
873
|
|
|
969
874
|
// src/components/ConfigEditor.tsx
|
|
970
|
-
import
|
|
971
|
-
import { Box as Box8, Text as
|
|
875
|
+
import React8, { useState as useState2, useMemo as useMemo2 } from "react";
|
|
876
|
+
import { Box as Box8, Text as Text7, useInput as useInput2 } from "ink";
|
|
972
877
|
var MAX_ITERATIONS_OPTIONS = [
|
|
973
878
|
{ label: "10", value: 10 },
|
|
974
879
|
{ label: "20", value: 20 },
|
|
@@ -1099,10 +1004,10 @@ function buildConfigItems(availableModels) {
|
|
|
1099
1004
|
return items;
|
|
1100
1005
|
}
|
|
1101
1006
|
function ConfigEditor({ config, availableModels, onSave, onClose }) {
|
|
1102
|
-
const [selectedIndex, setSelectedIndex] =
|
|
1103
|
-
const [editedConfig, setEditedConfig] =
|
|
1104
|
-
const [saveError, setSaveError] =
|
|
1105
|
-
const [isSaving, setIsSaving] =
|
|
1007
|
+
const [selectedIndex, setSelectedIndex] = useState2(0);
|
|
1008
|
+
const [editedConfig, setEditedConfig] = useState2(config);
|
|
1009
|
+
const [saveError, setSaveError] = useState2(null);
|
|
1010
|
+
const [isSaving, setIsSaving] = useState2(false);
|
|
1106
1011
|
const configItems = useMemo2(() => buildConfigItems(availableModels), [availableModels]);
|
|
1107
1012
|
const hasChanges = useMemo2(() => {
|
|
1108
1013
|
return JSON.stringify(config.preferences) !== JSON.stringify(editedConfig.preferences) || config.defaultModel !== editedConfig.defaultModel;
|
|
@@ -1122,7 +1027,7 @@ function ConfigEditor({ config, availableModels, onSave, onClose }) {
|
|
|
1122
1027
|
}
|
|
1123
1028
|
onClose();
|
|
1124
1029
|
};
|
|
1125
|
-
|
|
1030
|
+
useInput2((input, key) => {
|
|
1126
1031
|
const currentItem = configItems[selectedIndex];
|
|
1127
1032
|
if (key.upArrow) {
|
|
1128
1033
|
setSelectedIndex((prev) => prev > 0 ? prev - 1 : configItems.length - 1);
|
|
@@ -1187,13 +1092,13 @@ function ConfigEditor({ config, availableModels, onSave, onClose }) {
|
|
|
1187
1092
|
}
|
|
1188
1093
|
return String(value);
|
|
1189
1094
|
};
|
|
1190
|
-
return /* @__PURE__ */
|
|
1095
|
+
return /* @__PURE__ */ React8.createElement(Box8, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 2, paddingY: 1, marginY: 1 }, /* @__PURE__ */ React8.createElement(Box8, { justifyContent: "space-between", marginBottom: 1 }, /* @__PURE__ */ React8.createElement(Text7, { bold: true, color: "cyan" }, "Settings"), isSaving ? /* @__PURE__ */ React8.createElement(Text7, { color: "yellow" }, "Saving...") : hasChanges ? /* @__PURE__ */ React8.createElement(Text7, { dimColor: true, color: "yellow" }, "(unsaved changes)") : null), saveError && /* @__PURE__ */ React8.createElement(Box8, { marginBottom: 1 }, /* @__PURE__ */ React8.createElement(Text7, { color: "red" }, "Error: ", saveError)), /* @__PURE__ */ React8.createElement(Box8, { flexDirection: "column", marginBottom: 1 }, configItems.map((item, index) => {
|
|
1191
1096
|
const isSelected = index === selectedIndex;
|
|
1192
1097
|
const value = item.getValue(editedConfig);
|
|
1193
1098
|
const displayValue = formatValue(item, value);
|
|
1194
1099
|
const hasOptions = item.type === "select" || item.type === "boolean" || item.type === "number";
|
|
1195
|
-
return /* @__PURE__ */
|
|
1196
|
-
})), /* @__PURE__ */
|
|
1100
|
+
return /* @__PURE__ */ React8.createElement(Box8, { key: item.key }, /* @__PURE__ */ React8.createElement(Text7, { color: isSelected ? "cyan" : void 0 }, isSelected ? "> " : " "), /* @__PURE__ */ React8.createElement(Box8, { width: 18 }, /* @__PURE__ */ React8.createElement(Text7, { bold: isSelected, color: isSelected ? "white" : "gray" }, item.label, ":")), /* @__PURE__ */ React8.createElement(Box8, null, hasOptions && isSelected && /* @__PURE__ */ React8.createElement(Text7, { dimColor: true }, "< "), /* @__PURE__ */ React8.createElement(Text7, { bold: isSelected, color: isSelected ? "green" : void 0 }, displayValue), hasOptions && isSelected && /* @__PURE__ */ React8.createElement(Text7, { dimColor: true }, " >")));
|
|
1101
|
+
})), /* @__PURE__ */ React8.createElement(Box8, { borderStyle: "single", borderColor: "gray", paddingX: 1 }, /* @__PURE__ */ React8.createElement(Text7, { dimColor: true }, "\u2191/\u2193: Navigate | Space/\u2190/\u2192: Change | q/Esc: Save & Exit")));
|
|
1197
1102
|
}
|
|
1198
1103
|
|
|
1199
1104
|
// src/utils/processFileReferences.ts
|
|
@@ -1331,7 +1236,7 @@ function App({
|
|
|
1331
1236
|
const setShowConfigEditor = useCliStore((state) => state.setShowConfigEditor);
|
|
1332
1237
|
const exitRequested = useCliStore((state) => state.exitRequested);
|
|
1333
1238
|
const setIsThinking = useCliStore((state) => state.setIsThinking);
|
|
1334
|
-
const handleSubmit =
|
|
1239
|
+
const handleSubmit = React9.useCallback(
|
|
1335
1240
|
async (input) => {
|
|
1336
1241
|
const trimmed = input.trim();
|
|
1337
1242
|
if (!trimmed) return;
|
|
@@ -1360,7 +1265,7 @@ ${errorBlock}`;
|
|
|
1360
1265
|
},
|
|
1361
1266
|
[onMessage, onCommand, setIsThinking]
|
|
1362
1267
|
);
|
|
1363
|
-
return /* @__PURE__ */
|
|
1268
|
+
return /* @__PURE__ */ React9.createElement(Box9, { flexDirection: "column" }, /* @__PURE__ */ React9.createElement(StatusBar, { sessionName, model: currentModel, tokenUsage: totalTokens }), showConfigEditor && config && onSaveConfig ? /* @__PURE__ */ React9.createElement(Box9, { flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React9.createElement(
|
|
1364
1269
|
ConfigEditor,
|
|
1365
1270
|
{
|
|
1366
1271
|
config,
|
|
@@ -1368,7 +1273,7 @@ ${errorBlock}`;
|
|
|
1368
1273
|
onSave: onSaveConfig,
|
|
1369
1274
|
onClose: () => setShowConfigEditor(false)
|
|
1370
1275
|
}
|
|
1371
|
-
)) : permissionPrompt ? /* @__PURE__ */
|
|
1276
|
+
)) : permissionPrompt ? /* @__PURE__ */ React9.createElement(Box9, { flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React9.createElement(
|
|
1372
1277
|
PermissionPrompt,
|
|
1373
1278
|
{
|
|
1374
1279
|
toolName: permissionPrompt.toolName,
|
|
@@ -1377,7 +1282,7 @@ ${errorBlock}`;
|
|
|
1377
1282
|
canBeTrusted: permissionPrompt.canBeTrusted,
|
|
1378
1283
|
onResponse: onPermissionResponse
|
|
1379
1284
|
}
|
|
1380
|
-
)) : /* @__PURE__ */
|
|
1285
|
+
)) : /* @__PURE__ */ React9.createElement(React9.Fragment, null, /* @__PURE__ */ React9.createElement(Static, { items: messages }, (message, index) => /* @__PURE__ */ React9.createElement(Box9, { key: index, flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React9.createElement(MessageItem, { message }))), /* @__PURE__ */ React9.createElement(AgentThinking, null), exitRequested && /* @__PURE__ */ React9.createElement(Box9, { paddingX: 1, marginBottom: 1 }, /* @__PURE__ */ React9.createElement(Text8, { color: "yellow", bold: true }, "Press Ctrl+C again to exit")), /* @__PURE__ */ React9.createElement(Box9, { borderStyle: "single", borderColor: "cyan", paddingX: 1 }, /* @__PURE__ */ React9.createElement(
|
|
1381
1286
|
InputPrompt,
|
|
1382
1287
|
{
|
|
1383
1288
|
onSubmit: handleSubmit,
|
|
@@ -1388,36 +1293,36 @@ ${errorBlock}`;
|
|
|
1388
1293
|
))));
|
|
1389
1294
|
}
|
|
1390
1295
|
function MessageItem({ message }) {
|
|
1391
|
-
return /* @__PURE__ */
|
|
1296
|
+
return /* @__PURE__ */ React9.createElement(Box9, { flexDirection: "column", marginBottom: 1 }, /* @__PURE__ */ React9.createElement(Box9, null, /* @__PURE__ */ React9.createElement(Text8, { bold: true, color: message.role === "user" ? "cyan" : "green" }, message.role === "user" ? "\u{1F464} You" : "\u{1F916} Assistant"), /* @__PURE__ */ React9.createElement(Text8, { dimColor: true }, " \u2022 ", new Date(message.timestamp).toLocaleTimeString())), /* @__PURE__ */ React9.createElement(Box9, { paddingLeft: 2 }, message.metadata?.permissionDenied ? /* @__PURE__ */ React9.createElement(Text8, { color: "yellow" }, "\u26A0\uFE0F ", message.content) : /* @__PURE__ */ React9.createElement(Text8, null, message.content)), message.metadata?.steps && message.metadata.steps.length > 0 && /* @__PURE__ */ React9.createElement(Box9, { paddingLeft: 2, marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React9.createElement(Text8, { 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__ */ React9.createElement(Text8, { dimColor: true }, "Step types: ", message.metadata.steps.map((s) => s.type).join(", ")), message.metadata.steps.map((step, idx) => {
|
|
1392
1297
|
if (step.type === "thought") {
|
|
1393
|
-
return /* @__PURE__ */
|
|
1298
|
+
return /* @__PURE__ */ React9.createElement(Box9, { key: idx, paddingLeft: 2, marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React9.createElement(Text8, { color: "blue" }, "\u{1F4AD} Thought:"), /* @__PURE__ */ React9.createElement(Text8, { dimColor: true }, ` ${step.content.slice(0, 200)}${step.content.length > 200 ? "..." : ""}`));
|
|
1394
1299
|
}
|
|
1395
1300
|
if (step.type === "action") {
|
|
1396
1301
|
const toolName = step.metadata?.toolName || "unknown";
|
|
1397
1302
|
const toolInput = step.metadata?.toolInput;
|
|
1398
1303
|
const observationStep = message.metadata.steps[idx + 1];
|
|
1399
1304
|
const result = observationStep?.type === "observation" ? observationStep.content : null;
|
|
1400
|
-
return /* @__PURE__ */
|
|
1305
|
+
return /* @__PURE__ */ React9.createElement(Box9, { key: idx, paddingLeft: 2, marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React9.createElement(Text8, { color: "yellow" }, "\u{1F527} Action: ", toolName), toolInput && /* @__PURE__ */ React9.createElement(Text8, { dimColor: true }, ` Input: ${typeof toolInput === "string" ? toolInput : JSON.stringify(toolInput).slice(0, 100)}`), result && /* @__PURE__ */ React9.createElement(Text8, { 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 ? "..." : ""}`));
|
|
1401
1306
|
}
|
|
1402
1307
|
return null;
|
|
1403
|
-
}).filter(Boolean)), message.metadata?.tokenUsage && (!message.metadata.steps || message.metadata.steps.length === 0) && /* @__PURE__ */
|
|
1308
|
+
}).filter(Boolean)), message.metadata?.tokenUsage && (!message.metadata.steps || message.metadata.steps.length === 0) && /* @__PURE__ */ React9.createElement(Box9, { paddingLeft: 2 }, /* @__PURE__ */ React9.createElement(Text8, { dimColor: true }, `${message.metadata.tokenUsage.total} tokens`)));
|
|
1404
1309
|
}
|
|
1405
1310
|
|
|
1406
1311
|
// src/components/MessageList.tsx
|
|
1407
|
-
import
|
|
1408
|
-
import { Box as Box10, Text as
|
|
1312
|
+
import React10 from "react";
|
|
1313
|
+
import { Box as Box10, Text as Text9 } from "ink";
|
|
1409
1314
|
function stripThinkingTags(content) {
|
|
1410
1315
|
return content.replace(/<think>[\s\S]*?<\/think>/g, "").trim();
|
|
1411
1316
|
}
|
|
1412
|
-
var MessageList =
|
|
1317
|
+
var MessageList = React10.memo(
|
|
1413
1318
|
function MessageList2({ messages }) {
|
|
1414
1319
|
if (messages.length === 0) {
|
|
1415
|
-
return /* @__PURE__ */
|
|
1320
|
+
return /* @__PURE__ */ React10.createElement(Box10, { paddingY: 1 }, /* @__PURE__ */ React10.createElement(Text9, { dimColor: true }, "No messages yet. Type a message to start!"));
|
|
1416
1321
|
}
|
|
1417
|
-
return /* @__PURE__ */
|
|
1322
|
+
return /* @__PURE__ */ React10.createElement(Box10, { flexDirection: "column", gap: 1, paddingY: 1 }, messages.map((message, index) => /* @__PURE__ */ React10.createElement(Box10, { key: index, flexDirection: "column", marginBottom: 1 }, /* @__PURE__ */ React10.createElement(Box10, null, /* @__PURE__ */ React10.createElement(Text9, { bold: true, color: message.role === "user" ? "cyan" : "green" }, message.role === "user" ? "\u{1F464} You" : "\u{1F916} Assistant"), /* @__PURE__ */ React10.createElement(Text9, { dimColor: true }, " \u2022 ", new Date(message.timestamp).toLocaleTimeString())), /* @__PURE__ */ React10.createElement(Box10, { paddingLeft: 2 }, message.metadata?.permissionDenied ? /* @__PURE__ */ React10.createElement(Text9, { color: "yellow" }, "\u26A0\uFE0F ", stripThinkingTags(message.content)) : /* @__PURE__ */ React10.createElement(Text9, null, stripThinkingTags(message.content))), message.metadata?.steps && message.metadata.steps.length > 0 && /* @__PURE__ */ React10.createElement(Box10, { 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) => {
|
|
1418
1323
|
if (step.type === "thought") {
|
|
1419
|
-
return /* @__PURE__ */
|
|
1420
|
-
|
|
1324
|
+
return /* @__PURE__ */ React10.createElement(Box10, { key: idx, paddingLeft: 2, marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React10.createElement(Text9, { color: "blue" }, "\u{1F4AD} Thought:"), /* @__PURE__ */ React10.createElement(
|
|
1325
|
+
Text9,
|
|
1421
1326
|
{
|
|
1422
1327
|
dimColor: true
|
|
1423
1328
|
},
|
|
@@ -1429,10 +1334,10 @@ var MessageList = React11.memo(
|
|
|
1429
1334
|
const toolInput = step.metadata?.toolInput;
|
|
1430
1335
|
const observationStep = message.metadata.steps[idx + 1];
|
|
1431
1336
|
const result = observationStep?.type === "observation" ? observationStep.content : null;
|
|
1432
|
-
return /* @__PURE__ */
|
|
1337
|
+
return /* @__PURE__ */ React10.createElement(Box10, { key: idx, paddingLeft: 2, marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React10.createElement(Text9, { color: "yellow" }, "\u{1F527} Action: ", toolName), toolInput && /* @__PURE__ */ React10.createElement(Text9, { dimColor: true }, ` Input: ${typeof toolInput === "string" ? toolInput : JSON.stringify(toolInput).slice(0, 100)}`), result && /* @__PURE__ */ React10.createElement(Text9, { 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 ? "..." : ""}`));
|
|
1433
1338
|
}
|
|
1434
1339
|
return null;
|
|
1435
|
-
}).filter(Boolean)), message.metadata?.tokenUsage && (!message.metadata.steps || message.metadata.steps.length === 0) && /* @__PURE__ */
|
|
1340
|
+
}).filter(Boolean)), message.metadata?.tokenUsage && (!message.metadata.steps || message.metadata.steps.length === 0) && /* @__PURE__ */ React10.createElement(Box10, { paddingLeft: 2 }, /* @__PURE__ */ React10.createElement(Text9, { dimColor: true }, `${message.metadata.tokenUsage.total} tokens`)))));
|
|
1436
1341
|
},
|
|
1437
1342
|
(prevProps, nextProps) => {
|
|
1438
1343
|
if (prevProps.messages.length !== nextProps.messages.length) {
|
|
@@ -1443,8 +1348,8 @@ var MessageList = React11.memo(
|
|
|
1443
1348
|
);
|
|
1444
1349
|
|
|
1445
1350
|
// src/components/TrustLocationSelector.tsx
|
|
1446
|
-
import
|
|
1447
|
-
import { Box as Box11, Text as
|
|
1351
|
+
import React11 from "react";
|
|
1352
|
+
import { Box as Box11, Text as Text10 } from "ink";
|
|
1448
1353
|
import SelectInput2 from "ink-select-input";
|
|
1449
1354
|
function TrustLocationSelector({ inProject, onSelect, onCancel }) {
|
|
1450
1355
|
const items = [];
|
|
@@ -1465,19 +1370,19 @@ function TrustLocationSelector({ inProject, onSelect, onCancel }) {
|
|
|
1465
1370
|
const handleSelect = (item) => {
|
|
1466
1371
|
onSelect(item.value);
|
|
1467
1372
|
};
|
|
1468
|
-
return /* @__PURE__ */
|
|
1373
|
+
return /* @__PURE__ */ React11.createElement(Box11, { flexDirection: "column", marginY: 1 }, /* @__PURE__ */ React11.createElement(Box11, { marginBottom: 1 }, /* @__PURE__ */ React11.createElement(Text10, { bold: true }, "Where should this rule be saved?")), /* @__PURE__ */ React11.createElement(
|
|
1469
1374
|
SelectInput2,
|
|
1470
1375
|
{
|
|
1471
1376
|
items,
|
|
1472
1377
|
onSelect: handleSelect,
|
|
1473
|
-
itemComponent: ({ isSelected, label }) => /* @__PURE__ */
|
|
1378
|
+
itemComponent: ({ isSelected, label }) => /* @__PURE__ */ React11.createElement(Box11, null, /* @__PURE__ */ React11.createElement(Text10, { color: isSelected ? "cyan" : void 0 }, isSelected ? "\u276F " : " ", label))
|
|
1474
1379
|
}
|
|
1475
|
-
), /* @__PURE__ */
|
|
1380
|
+
), /* @__PURE__ */ React11.createElement(Box11, { marginTop: 1 }, /* @__PURE__ */ React11.createElement(Text10, { dimColor: true }, "Use \u2191\u2193 arrows to navigate, Enter to select, Ctrl+C to cancel")));
|
|
1476
1381
|
}
|
|
1477
1382
|
|
|
1478
1383
|
// src/components/LoginFlow.tsx
|
|
1479
|
-
import
|
|
1480
|
-
import { Box as Box12, Text as
|
|
1384
|
+
import React12, { useState as useState3, useEffect as useEffect2 } from "react";
|
|
1385
|
+
import { Box as Box12, Text as Text11 } from "ink";
|
|
1481
1386
|
import Spinner2 from "ink-spinner";
|
|
1482
1387
|
import jwt from "jsonwebtoken";
|
|
1483
1388
|
import open from "open";
|
|
@@ -1593,10 +1498,10 @@ var OAuthClient = class {
|
|
|
1593
1498
|
|
|
1594
1499
|
// src/components/LoginFlow.tsx
|
|
1595
1500
|
function LoginFlow({ apiUrl = "http://localhost:3000", configStore, onSuccess, onError }) {
|
|
1596
|
-
const [status, setStatus] =
|
|
1597
|
-
const [deviceFlow, setDeviceFlow] =
|
|
1598
|
-
const [statusMessage, setStatusMessage] =
|
|
1599
|
-
const [error, setError] =
|
|
1501
|
+
const [status, setStatus] = useState3("initiating");
|
|
1502
|
+
const [deviceFlow, setDeviceFlow] = useState3(null);
|
|
1503
|
+
const [statusMessage, setStatusMessage] = useState3("Initiating device authorization...");
|
|
1504
|
+
const [error, setError] = useState3(null);
|
|
1600
1505
|
useEffect2(() => {
|
|
1601
1506
|
const runLoginFlow = async () => {
|
|
1602
1507
|
const oauth = new OAuthClient(apiUrl);
|
|
@@ -1640,15 +1545,15 @@ function LoginFlow({ apiUrl = "http://localhost:3000", configStore, onSuccess, o
|
|
|
1640
1545
|
}
|
|
1641
1546
|
}, [deviceFlow, status]);
|
|
1642
1547
|
if (status === "initiating") {
|
|
1643
|
-
return /* @__PURE__ */
|
|
1548
|
+
return /* @__PURE__ */ React12.createElement(Box12, { flexDirection: "column", padding: 1 }, /* @__PURE__ */ React12.createElement(Box12, null, /* @__PURE__ */ React12.createElement(Text11, { color: "cyan" }, /* @__PURE__ */ React12.createElement(Spinner2, { type: "dots" }), " Initiating device authorization...")));
|
|
1644
1549
|
}
|
|
1645
1550
|
if (status === "error") {
|
|
1646
|
-
return /* @__PURE__ */
|
|
1551
|
+
return /* @__PURE__ */ React12.createElement(Box12, { flexDirection: "column", padding: 1 }, /* @__PURE__ */ React12.createElement(Box12, { marginBottom: 1 }, /* @__PURE__ */ React12.createElement(Text11, { color: "red", bold: true }, "\u2716 Authentication Failed")), /* @__PURE__ */ React12.createElement(Box12, null, /* @__PURE__ */ React12.createElement(Text11, { color: "red" }, error)));
|
|
1647
1552
|
}
|
|
1648
1553
|
if (status === "success") {
|
|
1649
|
-
return /* @__PURE__ */
|
|
1554
|
+
return /* @__PURE__ */ React12.createElement(Box12, { flexDirection: "column", padding: 1 }, /* @__PURE__ */ React12.createElement(Box12, { marginBottom: 1 }, /* @__PURE__ */ React12.createElement(Text11, { color: "green", bold: true }, "\u2714 Successfully authenticated!")), /* @__PURE__ */ React12.createElement(Box12, null, /* @__PURE__ */ React12.createElement(Text11, { dimColor: true }, "You can now use B4M CLI with your account.")));
|
|
1650
1555
|
}
|
|
1651
|
-
return /* @__PURE__ */
|
|
1556
|
+
return /* @__PURE__ */ React12.createElement(Box12, { flexDirection: "column", padding: 1, borderStyle: "round", borderColor: "cyan" }, /* @__PURE__ */ React12.createElement(Box12, { marginBottom: 1 }, /* @__PURE__ */ React12.createElement(Text11, { color: "cyan", bold: true }, "\u{1F510} Device Authorization")), /* @__PURE__ */ React12.createElement(Box12, { marginBottom: 1 }, /* @__PURE__ */ React12.createElement(Text11, null, "Opening browser automatically... If it doesn't open, please visit:")), /* @__PURE__ */ React12.createElement(Box12, { marginBottom: 1, paddingLeft: 2 }, /* @__PURE__ */ React12.createElement(Text11, { color: "blue", bold: true }, deviceFlow?.verification_uri)), /* @__PURE__ */ React12.createElement(Box12, { marginBottom: 1 }, /* @__PURE__ */ React12.createElement(Text11, null, "And enter this code when prompted:")), /* @__PURE__ */ React12.createElement(Box12, { marginBottom: 1, paddingLeft: 2 }, /* @__PURE__ */ React12.createElement(Text11, { color: "yellow", bold: true }, deviceFlow?.user_code)), /* @__PURE__ */ React12.createElement(Box12, { marginTop: 1 }, /* @__PURE__ */ React12.createElement(Text11, { color: "cyan" }, /* @__PURE__ */ React12.createElement(Spinner2, { type: "dots" }), " ", statusMessage)), /* @__PURE__ */ React12.createElement(Box12, { marginTop: 1 }, /* @__PURE__ */ React12.createElement(Text11, { dimColor: true }, "Expires in ", deviceFlow ? Math.floor(deviceFlow.expires_in / 60) : 0, " minutes")));
|
|
1652
1557
|
}
|
|
1653
1558
|
|
|
1654
1559
|
// src/storage/SessionStore.ts
|
|
@@ -10356,7 +10261,7 @@ import { isAxiosError as isAxiosError2 } from "axios";
|
|
|
10356
10261
|
// package.json
|
|
10357
10262
|
var package_default = {
|
|
10358
10263
|
name: "@bike4mind/cli",
|
|
10359
|
-
version: "0.2.7-
|
|
10264
|
+
version: "0.2.7-feature-notebook-splash-redesign.17129+59a337a9d",
|
|
10360
10265
|
type: "module",
|
|
10361
10266
|
description: "Interactive CLI tool for Bike4Mind with ReAct agents",
|
|
10362
10267
|
license: "UNLICENSED",
|
|
@@ -10459,11 +10364,11 @@ var package_default = {
|
|
|
10459
10364
|
},
|
|
10460
10365
|
devDependencies: {
|
|
10461
10366
|
"@bike4mind/agents": "0.1.0",
|
|
10462
|
-
"@bike4mind/common": "2.38.1-
|
|
10463
|
-
"@bike4mind/mcp": "1.20.1-
|
|
10464
|
-
"@bike4mind/services": "2.33.1-
|
|
10465
|
-
"@bike4mind/utils": "2.1.2-
|
|
10466
|
-
"@types/better-sqlite3": "^7.6.
|
|
10367
|
+
"@bike4mind/common": "2.38.1-feature-notebook-splash-redesign.17129+59a337a9d",
|
|
10368
|
+
"@bike4mind/mcp": "1.20.1-feature-notebook-splash-redesign.17129+59a337a9d",
|
|
10369
|
+
"@bike4mind/services": "2.33.1-feature-notebook-splash-redesign.17129+59a337a9d",
|
|
10370
|
+
"@bike4mind/utils": "2.1.2-feature-notebook-splash-redesign.17129+59a337a9d",
|
|
10371
|
+
"@types/better-sqlite3": "^7.6.13",
|
|
10467
10372
|
"@types/diff": "^5.0.9",
|
|
10468
10373
|
"@types/jsonwebtoken": "^9.0.4",
|
|
10469
10374
|
"@types/node": "^22.9.0",
|
|
@@ -10475,7 +10380,7 @@ var package_default = {
|
|
|
10475
10380
|
typescript: "^5.9.3",
|
|
10476
10381
|
vitest: "^3.2.4"
|
|
10477
10382
|
},
|
|
10478
|
-
gitHead: "
|
|
10383
|
+
gitHead: "59a337a9d7a8fddb596b5903547f09463ae4a05e"
|
|
10479
10384
|
};
|
|
10480
10385
|
|
|
10481
10386
|
// src/config/constants.ts
|
|
@@ -10497,7 +10402,7 @@ var usageCache = null;
|
|
|
10497
10402
|
function CliApp() {
|
|
10498
10403
|
const { exit } = useApp();
|
|
10499
10404
|
const imageRenderer = new ImageRenderer();
|
|
10500
|
-
const [state, setState] =
|
|
10405
|
+
const [state, setState] = useState4({
|
|
10501
10406
|
session: null,
|
|
10502
10407
|
sessionStore: new SessionStore(),
|
|
10503
10408
|
configStore: new ConfigStore(),
|
|
@@ -10512,9 +10417,9 @@ function CliApp() {
|
|
|
10512
10417
|
permissionPrompt: null,
|
|
10513
10418
|
trustLocationSelector: null
|
|
10514
10419
|
});
|
|
10515
|
-
const [isInitialized, setIsInitialized] =
|
|
10516
|
-
const [initError, setInitError] =
|
|
10517
|
-
const [commandHistory, setCommandHistory] =
|
|
10420
|
+
const [isInitialized, setIsInitialized] = useState4(false);
|
|
10421
|
+
const [initError, setInitError] = useState4(null);
|
|
10422
|
+
const [commandHistory, setCommandHistory] = useState4([]);
|
|
10518
10423
|
const imageStoreInitPromise = useRef(null);
|
|
10519
10424
|
const setStoreSession = useCliStore((state2) => state2.setSession);
|
|
10520
10425
|
const setPermissionPrompt = useCliStore((state2) => state2.setPermissionPrompt);
|
|
@@ -10555,7 +10460,7 @@ function CliApp() {
|
|
|
10555
10460
|
process.exit(0);
|
|
10556
10461
|
}, 100);
|
|
10557
10462
|
}, [state.session, state.sessionStore, state.mcpManager, state.agent, state.imageStore]);
|
|
10558
|
-
|
|
10463
|
+
useInput3((input, key) => {
|
|
10559
10464
|
if (key.ctrl && input === "c") {
|
|
10560
10465
|
const now = Date.now();
|
|
10561
10466
|
if (exitTimestamp && now - exitTimestamp < EXIT_TIMEOUT_MS) {
|
|
@@ -11345,12 +11250,12 @@ No usage data available for the last ${USAGE_DAYS} days.`);
|
|
|
11345
11250
|
setState((prev) => ({ ...prev, config: updatedConfig }));
|
|
11346
11251
|
};
|
|
11347
11252
|
if (initError) {
|
|
11348
|
-
return /* @__PURE__ */
|
|
11253
|
+
return /* @__PURE__ */ React13.createElement(Box13, { flexDirection: "column", padding: 1 }, /* @__PURE__ */ React13.createElement(Text12, { color: "red", bold: true }, "\u274C Initialization Error"), /* @__PURE__ */ React13.createElement(Text12, null, initError), /* @__PURE__ */ React13.createElement(Text12, { dimColor: true }, "\n", "Tip: Run /config to set up your API keys"));
|
|
11349
11254
|
}
|
|
11350
11255
|
if (state.trustLocationSelector) {
|
|
11351
11256
|
const projectDir = state.configStore.getProjectConfigDir();
|
|
11352
11257
|
const inProject = projectDir !== null;
|
|
11353
|
-
return /* @__PURE__ */
|
|
11258
|
+
return /* @__PURE__ */ React13.createElement(
|
|
11354
11259
|
TrustLocationSelector,
|
|
11355
11260
|
{
|
|
11356
11261
|
inProject,
|
|
@@ -11369,7 +11274,7 @@ No usage data available for the last ${USAGE_DAYS} days.`);
|
|
|
11369
11274
|
}
|
|
11370
11275
|
if (state.showLoginFlow) {
|
|
11371
11276
|
const loginApiUrl = getApiUrl(state.config?.apiConfig);
|
|
11372
|
-
return /* @__PURE__ */
|
|
11277
|
+
return /* @__PURE__ */ React13.createElement(
|
|
11373
11278
|
LoginFlow,
|
|
11374
11279
|
{
|
|
11375
11280
|
apiUrl: loginApiUrl,
|
|
@@ -11392,9 +11297,9 @@ No usage data available for the last ${USAGE_DAYS} days.`);
|
|
|
11392
11297
|
);
|
|
11393
11298
|
}
|
|
11394
11299
|
if (!isInitialized) {
|
|
11395
|
-
return /* @__PURE__ */
|
|
11300
|
+
return /* @__PURE__ */ React13.createElement(Box13, { flexDirection: "column", padding: 1 }, /* @__PURE__ */ React13.createElement(Text12, null, "\u{1F680} Initializing..."));
|
|
11396
11301
|
}
|
|
11397
|
-
return /* @__PURE__ */
|
|
11302
|
+
return /* @__PURE__ */ React13.createElement(
|
|
11398
11303
|
App,
|
|
11399
11304
|
{
|
|
11400
11305
|
onMessage: handleMessage,
|
|
@@ -11429,6 +11334,6 @@ var isDevMode = import.meta.url.includes("/src/") || process.env.NODE_ENV === "d
|
|
|
11429
11334
|
if (isDevMode) {
|
|
11430
11335
|
console.log("\u{1F527} Running in development mode (using TypeScript source)\n");
|
|
11431
11336
|
}
|
|
11432
|
-
render(/* @__PURE__ */
|
|
11337
|
+
render(/* @__PURE__ */ React13.createElement(CliApp, null), {
|
|
11433
11338
|
exitOnCtrlC: false
|
|
11434
11339
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bike4mind/cli",
|
|
3
|
-
"version": "0.2.7-
|
|
3
|
+
"version": "0.2.7-feature-notebook-splash-redesign.17129+59a337a9d",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Interactive CLI tool for Bike4Mind with ReAct agents",
|
|
6
6
|
"license": "UNLICENSED",
|
|
@@ -103,11 +103,11 @@
|
|
|
103
103
|
},
|
|
104
104
|
"devDependencies": {
|
|
105
105
|
"@bike4mind/agents": "0.1.0",
|
|
106
|
-
"@bike4mind/common": "2.38.1-
|
|
107
|
-
"@bike4mind/mcp": "1.20.1-
|
|
108
|
-
"@bike4mind/services": "2.33.1-
|
|
109
|
-
"@bike4mind/utils": "2.1.2-
|
|
110
|
-
"@types/better-sqlite3": "^7.6.
|
|
106
|
+
"@bike4mind/common": "2.38.1-feature-notebook-splash-redesign.17129+59a337a9d",
|
|
107
|
+
"@bike4mind/mcp": "1.20.1-feature-notebook-splash-redesign.17129+59a337a9d",
|
|
108
|
+
"@bike4mind/services": "2.33.1-feature-notebook-splash-redesign.17129+59a337a9d",
|
|
109
|
+
"@bike4mind/utils": "2.1.2-feature-notebook-splash-redesign.17129+59a337a9d",
|
|
110
|
+
"@types/better-sqlite3": "^7.6.13",
|
|
111
111
|
"@types/diff": "^5.0.9",
|
|
112
112
|
"@types/jsonwebtoken": "^9.0.4",
|
|
113
113
|
"@types/node": "^22.9.0",
|
|
@@ -119,5 +119,5 @@
|
|
|
119
119
|
"typescript": "^5.9.3",
|
|
120
120
|
"vitest": "^3.2.4"
|
|
121
121
|
},
|
|
122
|
-
"gitHead": "
|
|
122
|
+
"gitHead": "59a337a9d7a8fddb596b5903547f09463ae4a05e"
|
|
123
123
|
}
|