@bike4mind/cli 0.2.1-feat-cli-file-reference.17024 → 0.2.1-feat-cli-project-scoped-config.16996
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/{chunk-5N4PG5EH.js → chunk-F3ETXO5N.js} +1 -1
- package/dist/{chunk-CJRAEEKV.js → chunk-LZMRYJ3B.js} +1 -1
- package/dist/{chunk-GZTILMGE.js → chunk-QXGU6KYI.js} +1 -1
- package/dist/{chunk-NZADYDFG.js → chunk-U3GPYBTD.js} +7 -12
- package/dist/{create-ZTK4723N.js → create-YUYXTEIS.js} +2 -2
- package/dist/index.js +1180 -1091
- package/dist/{mementoService-5XQYECNM.js → mementoService-2BDIT6PH.js} +2 -2
- package/dist/{src-DOO3QAO2.js → src-VLP2EHKE.js} +1 -1
- package/dist/{subtractCredits-Q2PDJLQH.js → subtractCredits-NNYIS5XZ.js} +2 -2
- package/package.json +7 -13
package/dist/index.js
CHANGED
|
@@ -4,9 +4,9 @@ import {
|
|
|
4
4
|
getEffectiveApiKey,
|
|
5
5
|
getOpenWeatherKey,
|
|
6
6
|
getSerperKey
|
|
7
|
-
} from "./chunk-
|
|
8
|
-
import "./chunk-
|
|
9
|
-
import "./chunk-
|
|
7
|
+
} from "./chunk-QXGU6KYI.js";
|
|
8
|
+
import "./chunk-LZMRYJ3B.js";
|
|
9
|
+
import "./chunk-F3ETXO5N.js";
|
|
10
10
|
import {
|
|
11
11
|
BFLImageService,
|
|
12
12
|
BaseStorage,
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
OpenAIBackend,
|
|
16
16
|
OpenAIImageService,
|
|
17
17
|
XAIImageService
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-U3GPYBTD.js";
|
|
19
19
|
import {
|
|
20
20
|
Logger
|
|
21
21
|
} from "./chunk-AMDXHL6S.js";
|
|
@@ -83,8 +83,8 @@ import { render, Box as Box11, Text as Text10, useApp, useInput as useInput2 } f
|
|
|
83
83
|
import { v4 as uuidv49 } from "uuid";
|
|
84
84
|
|
|
85
85
|
// src/components/App.tsx
|
|
86
|
-
import
|
|
87
|
-
import { Box as
|
|
86
|
+
import React7 from "react";
|
|
87
|
+
import { Box as Box7, Text as Text6, Static } from "ink";
|
|
88
88
|
|
|
89
89
|
// src/components/StatusBar.tsx
|
|
90
90
|
import React from "react";
|
|
@@ -94,8 +94,8 @@ var StatusBar = React.memo(function StatusBar2({ sessionName, model, tokenUsage
|
|
|
94
94
|
});
|
|
95
95
|
|
|
96
96
|
// src/components/InputPrompt.tsx
|
|
97
|
-
import
|
|
98
|
-
import { Box as
|
|
97
|
+
import React3, { useState, useMemo, useEffect } from "react";
|
|
98
|
+
import { Box as Box3, Text as Text3, useInput } from "ink";
|
|
99
99
|
import TextInput from "ink-text-input";
|
|
100
100
|
|
|
101
101
|
// src/components/CommandAutocomplete.tsx
|
|
@@ -112,210 +112,8 @@ function CommandAutocomplete({ commands, selectedIndex }) {
|
|
|
112
112
|
}));
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
-
// src/components/FileAutocomplete.tsx
|
|
116
|
-
import React3 from "react";
|
|
117
|
-
import { Box as Box3, Text as Text3 } from "ink";
|
|
118
|
-
|
|
119
|
-
// src/utils/fileSearch.ts
|
|
120
|
-
import * as fs from "fs";
|
|
121
|
-
import * as path from "path";
|
|
122
|
-
import Fuse from "fuse.js";
|
|
123
|
-
var DEFAULT_IGNORE_PATTERNS = [
|
|
124
|
-
"node_modules",
|
|
125
|
-
".git",
|
|
126
|
-
".next",
|
|
127
|
-
".turbo",
|
|
128
|
-
"dist",
|
|
129
|
-
"build",
|
|
130
|
-
".cache",
|
|
131
|
-
"coverage",
|
|
132
|
-
".DS_Store",
|
|
133
|
-
".env",
|
|
134
|
-
".env.local",
|
|
135
|
-
".env.secrets"
|
|
136
|
-
];
|
|
137
|
-
function walkDirectory(basePath = process.cwd(), maxDepth = 5, ignorePatterns = DEFAULT_IGNORE_PATTERNS) {
|
|
138
|
-
const results = [];
|
|
139
|
-
const normalizedBase = path.resolve(basePath);
|
|
140
|
-
function walk(currentPath, depth) {
|
|
141
|
-
if (depth > maxDepth) return;
|
|
142
|
-
try {
|
|
143
|
-
const entries = fs.readdirSync(currentPath, { withFileTypes: true });
|
|
144
|
-
for (const entry of entries) {
|
|
145
|
-
if (ignorePatterns.some((pattern) => entry.name === pattern || entry.name.startsWith(pattern))) {
|
|
146
|
-
continue;
|
|
147
|
-
}
|
|
148
|
-
const fullPath = path.join(currentPath, entry.name);
|
|
149
|
-
const relativePath = path.relative(normalizedBase, fullPath);
|
|
150
|
-
if (entry.isDirectory()) {
|
|
151
|
-
results.push({
|
|
152
|
-
path: relativePath,
|
|
153
|
-
isDirectory: true
|
|
154
|
-
});
|
|
155
|
-
walk(fullPath, depth + 1);
|
|
156
|
-
} else if (entry.isFile()) {
|
|
157
|
-
try {
|
|
158
|
-
const stats = fs.statSync(fullPath);
|
|
159
|
-
results.push({
|
|
160
|
-
path: relativePath,
|
|
161
|
-
isDirectory: false,
|
|
162
|
-
size: stats.size
|
|
163
|
-
});
|
|
164
|
-
} catch {
|
|
165
|
-
results.push({
|
|
166
|
-
path: relativePath,
|
|
167
|
-
isDirectory: false
|
|
168
|
-
});
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
} catch {
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
walk(normalizedBase, 0);
|
|
176
|
-
return results;
|
|
177
|
-
}
|
|
178
|
-
function formatFileSize(bytes) {
|
|
179
|
-
if (bytes < 1024) return `${bytes} B`;
|
|
180
|
-
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
|
181
|
-
if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
182
|
-
return `${(bytes / (1024 * 1024 * 1024)).toFixed(1)} GB`;
|
|
183
|
-
}
|
|
184
|
-
var cachedFiles = null;
|
|
185
|
-
var cacheTimestamp = 0;
|
|
186
|
-
var CACHE_TTL_MS = 3e4;
|
|
187
|
-
function getCachedFiles() {
|
|
188
|
-
const now = Date.now();
|
|
189
|
-
if (!cachedFiles || now - cacheTimestamp > CACHE_TTL_MS) {
|
|
190
|
-
cachedFiles = walkDirectory();
|
|
191
|
-
cacheTimestamp = now;
|
|
192
|
-
}
|
|
193
|
-
return cachedFiles;
|
|
194
|
-
}
|
|
195
|
-
function searchFiles(query) {
|
|
196
|
-
const files = getCachedFiles();
|
|
197
|
-
if (!query || query.trim() === "") {
|
|
198
|
-
return files.filter((f) => !f.path.includes(path.sep)).slice(0, 20);
|
|
199
|
-
}
|
|
200
|
-
const queryDir = path.dirname(query);
|
|
201
|
-
let searchPool = files;
|
|
202
|
-
if (queryDir && queryDir !== ".") {
|
|
203
|
-
const normalizedDir = queryDir.replace(/\\/g, "/");
|
|
204
|
-
searchPool = files.filter((f) => {
|
|
205
|
-
const normalizedPath = f.path.replace(/\\/g, "/");
|
|
206
|
-
return normalizedPath.startsWith(normalizedDir + "/") || normalizedPath === normalizedDir;
|
|
207
|
-
});
|
|
208
|
-
if (searchPool.length === 0) {
|
|
209
|
-
searchPool = files;
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
const fuse2 = new Fuse(searchPool, {
|
|
213
|
-
keys: [{ name: "path", weight: 1 }],
|
|
214
|
-
threshold: 0.4,
|
|
215
|
-
// Allow some fuzzy matching
|
|
216
|
-
includeScore: true,
|
|
217
|
-
minMatchCharLength: 1,
|
|
218
|
-
// Use extended search for better path matching
|
|
219
|
-
useExtendedSearch: false
|
|
220
|
-
});
|
|
221
|
-
const results = fuse2.search(query);
|
|
222
|
-
return results.slice(0, 20).map((result) => result.item);
|
|
223
|
-
}
|
|
224
|
-
function isPathWithinCwd(filePath) {
|
|
225
|
-
const cwd = path.resolve(process.cwd());
|
|
226
|
-
const absolutePath = path.resolve(cwd, filePath);
|
|
227
|
-
let resolvedCwd = cwd;
|
|
228
|
-
let resolvedPath = absolutePath;
|
|
229
|
-
try {
|
|
230
|
-
const realCwd = fs.realpathSync.native(cwd);
|
|
231
|
-
if (realCwd) {
|
|
232
|
-
resolvedCwd = realCwd;
|
|
233
|
-
}
|
|
234
|
-
} catch {
|
|
235
|
-
}
|
|
236
|
-
try {
|
|
237
|
-
const realPath = fs.realpathSync.native(absolutePath);
|
|
238
|
-
if (realPath) {
|
|
239
|
-
resolvedPath = realPath;
|
|
240
|
-
}
|
|
241
|
-
} catch {
|
|
242
|
-
const relativePath2 = path.relative(cwd, absolutePath);
|
|
243
|
-
resolvedPath = path.resolve(resolvedCwd, relativePath2);
|
|
244
|
-
}
|
|
245
|
-
const normalizedCwd = resolvedCwd.toLowerCase();
|
|
246
|
-
const normalizedPath = resolvedPath.toLowerCase();
|
|
247
|
-
const isWithin = normalizedPath === normalizedCwd || normalizedPath.startsWith(normalizedCwd + path.sep);
|
|
248
|
-
if (!isWithin) {
|
|
249
|
-
return false;
|
|
250
|
-
}
|
|
251
|
-
const relativePath = path.relative(resolvedCwd, resolvedPath);
|
|
252
|
-
return !relativePath.startsWith("..") && !path.isAbsolute(relativePath);
|
|
253
|
-
}
|
|
254
|
-
function isBinaryFile(filePath) {
|
|
255
|
-
const binaryExtensions = [
|
|
256
|
-
".png",
|
|
257
|
-
".jpg",
|
|
258
|
-
".jpeg",
|
|
259
|
-
".gif",
|
|
260
|
-
".bmp",
|
|
261
|
-
".ico",
|
|
262
|
-
".webp",
|
|
263
|
-
// Note: .svg is NOT included because SVG is XML text format that can be safely read
|
|
264
|
-
".pdf",
|
|
265
|
-
".doc",
|
|
266
|
-
".docx",
|
|
267
|
-
".xls",
|
|
268
|
-
".xlsx",
|
|
269
|
-
".ppt",
|
|
270
|
-
".pptx",
|
|
271
|
-
".zip",
|
|
272
|
-
".tar",
|
|
273
|
-
".gz",
|
|
274
|
-
".rar",
|
|
275
|
-
".7z",
|
|
276
|
-
".exe",
|
|
277
|
-
".dll",
|
|
278
|
-
".so",
|
|
279
|
-
".dylib",
|
|
280
|
-
".bin",
|
|
281
|
-
".dat",
|
|
282
|
-
".mp3",
|
|
283
|
-
".mp4",
|
|
284
|
-
".wav",
|
|
285
|
-
".avi",
|
|
286
|
-
".mov",
|
|
287
|
-
".mkv",
|
|
288
|
-
".ttf",
|
|
289
|
-
".otf",
|
|
290
|
-
".woff",
|
|
291
|
-
".woff2",
|
|
292
|
-
".eot",
|
|
293
|
-
".class",
|
|
294
|
-
".pyc",
|
|
295
|
-
".o",
|
|
296
|
-
".obj"
|
|
297
|
-
];
|
|
298
|
-
const ext = path.extname(filePath).toLowerCase();
|
|
299
|
-
return binaryExtensions.includes(ext);
|
|
300
|
-
}
|
|
301
|
-
var MAX_FILE_SIZE = 10 * 1024 * 1024;
|
|
302
|
-
|
|
303
|
-
// src/components/FileAutocomplete.tsx
|
|
304
|
-
function FileAutocomplete({ files, selectedIndex, query }) {
|
|
305
|
-
if (files.length === 0) {
|
|
306
|
-
return /* @__PURE__ */ React3.createElement(Box3, { marginLeft: 2, marginTop: 1 }, /* @__PURE__ */ React3.createElement(Text3, { dimColor: true }, "No matching files", query ? ` for "${query}"` : ""));
|
|
307
|
-
}
|
|
308
|
-
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) => {
|
|
309
|
-
const isSelected = index === selectedIndex;
|
|
310
|
-
const icon = file.isDirectory ? "[folder]" : "[file] ";
|
|
311
|
-
const sizeDisplay = file.isDirectory ? "" : file.size !== void 0 ? ` (${formatFileSize(file.size)})` : "";
|
|
312
|
-
const pathDisplay = file.isDirectory ? `${file.path}/` : file.path;
|
|
313
|
-
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));
|
|
314
|
-
}));
|
|
315
|
-
}
|
|
316
|
-
|
|
317
115
|
// src/utils/fuzzySearch.ts
|
|
318
|
-
import
|
|
116
|
+
import Fuse from "fuse.js";
|
|
319
117
|
|
|
320
118
|
// src/config/commands.ts
|
|
321
119
|
var COMMANDS = [
|
|
@@ -383,7 +181,7 @@ var COMMANDS = [
|
|
|
383
181
|
];
|
|
384
182
|
|
|
385
183
|
// src/utils/fuzzySearch.ts
|
|
386
|
-
var fuse = new
|
|
184
|
+
var fuse = new Fuse(COMMANDS, {
|
|
387
185
|
keys: [
|
|
388
186
|
{ name: "name", weight: 0.7 },
|
|
389
187
|
// Prioritize command name
|
|
@@ -404,65 +202,23 @@ function searchCommands(query) {
|
|
|
404
202
|
}
|
|
405
203
|
|
|
406
204
|
// src/components/InputPrompt.tsx
|
|
407
|
-
function findAtTrigger(value) {
|
|
408
|
-
for (let i = value.length - 1; i >= 0; i--) {
|
|
409
|
-
if (value[i] === "@") {
|
|
410
|
-
const isValid = i === 0 || value[i - 1] === " ";
|
|
411
|
-
if (isValid) {
|
|
412
|
-
const query = value.slice(i + 1);
|
|
413
|
-
if (query.includes(" ")) {
|
|
414
|
-
return null;
|
|
415
|
-
}
|
|
416
|
-
return { startIndex: i, query };
|
|
417
|
-
}
|
|
418
|
-
}
|
|
419
|
-
}
|
|
420
|
-
return null;
|
|
421
|
-
}
|
|
422
205
|
function InputPrompt({ onSubmit, disabled = false, history = [] }) {
|
|
423
206
|
const [value, setValue] = useState("");
|
|
424
207
|
const [selectedIndex, setSelectedIndex] = useState(0);
|
|
425
208
|
const [historyIndex, setHistoryIndex] = useState(-1);
|
|
426
209
|
const [tempInput, setTempInput] = useState("");
|
|
427
210
|
const [inputKey, setInputKey] = useState(0);
|
|
428
|
-
const
|
|
429
|
-
const
|
|
430
|
-
const shouldShowCommandAutocomplete = value.startsWith("/") && !disabled && !fileAutocomplete?.active;
|
|
431
|
-
const commandQuery = shouldShowCommandAutocomplete ? value.slice(1) : "";
|
|
211
|
+
const shouldShowAutocomplete = value.startsWith("/") && !disabled;
|
|
212
|
+
const query = shouldShowAutocomplete ? value.slice(1) : "";
|
|
432
213
|
const filteredCommands = useMemo(() => {
|
|
433
|
-
if (!
|
|
434
|
-
return searchCommands(
|
|
435
|
-
}, [
|
|
436
|
-
const filteredFiles = useMemo(() => {
|
|
437
|
-
if (!fileAutocomplete?.active) return [];
|
|
438
|
-
return searchFiles(fileAutocomplete.query);
|
|
439
|
-
}, [fileAutocomplete?.active, fileAutocomplete?.query]);
|
|
214
|
+
if (!shouldShowAutocomplete) return [];
|
|
215
|
+
return searchCommands(query);
|
|
216
|
+
}, [shouldShowAutocomplete, query]);
|
|
440
217
|
useEffect(() => {
|
|
441
218
|
setSelectedIndex(0);
|
|
442
219
|
}, [filteredCommands]);
|
|
443
|
-
useEffect(() => {
|
|
444
|
-
setFileSelectedIndex(0);
|
|
445
|
-
}, [filteredFiles]);
|
|
446
220
|
useInput((input, key) => {
|
|
447
|
-
if (
|
|
448
|
-
if (key.upArrow) {
|
|
449
|
-
setFileSelectedIndex((prev) => prev > 0 ? prev - 1 : filteredFiles.length - 1);
|
|
450
|
-
return;
|
|
451
|
-
} else if (key.downArrow) {
|
|
452
|
-
setFileSelectedIndex((prev) => prev < filteredFiles.length - 1 ? prev + 1 : 0);
|
|
453
|
-
return;
|
|
454
|
-
} else if (key.tab) {
|
|
455
|
-
const selectedFile = filteredFiles[fileSelectedIndex];
|
|
456
|
-
if (selectedFile) {
|
|
457
|
-
insertSelectedFile(selectedFile);
|
|
458
|
-
}
|
|
459
|
-
return;
|
|
460
|
-
} else if (key.escape) {
|
|
461
|
-
setFileAutocomplete(null);
|
|
462
|
-
return;
|
|
463
|
-
}
|
|
464
|
-
}
|
|
465
|
-
if (shouldShowCommandAutocomplete && filteredCommands.length > 0) {
|
|
221
|
+
if (shouldShowAutocomplete && filteredCommands.length > 0) {
|
|
466
222
|
if (key.upArrow) {
|
|
467
223
|
setSelectedIndex((prev) => prev > 0 ? prev - 1 : filteredCommands.length - 1);
|
|
468
224
|
} else if (key.downArrow) {
|
|
@@ -470,7 +226,7 @@ function InputPrompt({ onSubmit, disabled = false, history = [] }) {
|
|
|
470
226
|
}
|
|
471
227
|
return;
|
|
472
228
|
}
|
|
473
|
-
if (!
|
|
229
|
+
if (!shouldShowAutocomplete && history.length > 0) {
|
|
474
230
|
if (key.upArrow) {
|
|
475
231
|
if (historyIndex === -1) {
|
|
476
232
|
setTempInput(value);
|
|
@@ -493,35 +249,9 @@ function InputPrompt({ onSubmit, disabled = false, history = [] }) {
|
|
|
493
249
|
}
|
|
494
250
|
}
|
|
495
251
|
});
|
|
496
|
-
const insertSelectedFile = (file) => {
|
|
497
|
-
if (!fileAutocomplete) return;
|
|
498
|
-
const beforeAt = value.slice(0, fileAutocomplete.startIndex);
|
|
499
|
-
const afterQuery = value.slice(fileAutocomplete.startIndex + 1 + fileAutocomplete.query.length);
|
|
500
|
-
const pathToInsert = file.isDirectory ? `@${file.path}/` : `@${file.path}`;
|
|
501
|
-
const newValue = beforeAt + pathToInsert + afterQuery;
|
|
502
|
-
setValue(newValue);
|
|
503
|
-
setInputKey((prev) => prev + 1);
|
|
504
|
-
if (file.isDirectory) {
|
|
505
|
-
setFileAutocomplete({
|
|
506
|
-
active: true,
|
|
507
|
-
startIndex: fileAutocomplete.startIndex,
|
|
508
|
-
query: file.path + "/"
|
|
509
|
-
});
|
|
510
|
-
setFileSelectedIndex(0);
|
|
511
|
-
} else {
|
|
512
|
-
setFileAutocomplete(null);
|
|
513
|
-
}
|
|
514
|
-
};
|
|
515
252
|
const handleSubmit = (input) => {
|
|
516
253
|
if (disabled || !input.trim()) return;
|
|
517
|
-
if (
|
|
518
|
-
const selectedFile = filteredFiles[fileSelectedIndex];
|
|
519
|
-
if (selectedFile) {
|
|
520
|
-
insertSelectedFile(selectedFile);
|
|
521
|
-
}
|
|
522
|
-
return;
|
|
523
|
-
}
|
|
524
|
-
if (shouldShowCommandAutocomplete && filteredCommands.length > 0) {
|
|
254
|
+
if (shouldShowAutocomplete && filteredCommands.length > 0) {
|
|
525
255
|
const selectedCommand = filteredCommands[selectedIndex];
|
|
526
256
|
const commandText = `/${selectedCommand.name}`;
|
|
527
257
|
if (selectedCommand.args) {
|
|
@@ -538,7 +268,6 @@ function InputPrompt({ onSubmit, disabled = false, history = [] }) {
|
|
|
538
268
|
onSubmit(input);
|
|
539
269
|
setValue("");
|
|
540
270
|
setHistoryIndex(-1);
|
|
541
|
-
setFileAutocomplete(null);
|
|
542
271
|
};
|
|
543
272
|
const handleChange = (newValue) => {
|
|
544
273
|
setValue(newValue);
|
|
@@ -546,40 +275,30 @@ function InputPrompt({ onSubmit, disabled = false, history = [] }) {
|
|
|
546
275
|
setHistoryIndex(-1);
|
|
547
276
|
setTempInput("");
|
|
548
277
|
}
|
|
549
|
-
const atTrigger = findAtTrigger(newValue);
|
|
550
|
-
if (atTrigger) {
|
|
551
|
-
setFileAutocomplete({
|
|
552
|
-
active: true,
|
|
553
|
-
startIndex: atTrigger.startIndex,
|
|
554
|
-
query: atTrigger.query
|
|
555
|
-
});
|
|
556
|
-
} else {
|
|
557
|
-
setFileAutocomplete(null);
|
|
558
|
-
}
|
|
559
278
|
};
|
|
560
|
-
return /* @__PURE__ */
|
|
279
|
+
return /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column" }, /* @__PURE__ */ React3.createElement(Box3, null, /* @__PURE__ */ React3.createElement(Text3, { bold: true, color: "cyan" }, "> "), /* @__PURE__ */ React3.createElement(
|
|
561
280
|
TextInput,
|
|
562
281
|
{
|
|
563
282
|
key: inputKey,
|
|
564
283
|
value,
|
|
565
284
|
onChange: handleChange,
|
|
566
285
|
onSubmit: handleSubmit,
|
|
567
|
-
placeholder: disabled ? "Thinking..." : "Type your message
|
|
286
|
+
placeholder: disabled ? "Thinking..." : "Type your message or /help for commands",
|
|
568
287
|
showCursor: !disabled
|
|
569
288
|
}
|
|
570
|
-
)),
|
|
289
|
+
)), shouldShowAutocomplete && /* @__PURE__ */ React3.createElement(CommandAutocomplete, { commands: filteredCommands, selectedIndex }));
|
|
571
290
|
}
|
|
572
291
|
|
|
573
292
|
// src/components/AgentThinking.tsx
|
|
574
|
-
import
|
|
575
|
-
import { Box as
|
|
293
|
+
import React5 from "react";
|
|
294
|
+
import { Box as Box5 } from "ink";
|
|
576
295
|
|
|
577
296
|
// src/components/ThoughtStream.tsx
|
|
578
|
-
import
|
|
579
|
-
import { Box as
|
|
297
|
+
import React4 from "react";
|
|
298
|
+
import { Box as Box4, Text as Text4 } from "ink";
|
|
580
299
|
import Spinner from "ink-spinner";
|
|
581
|
-
var ThoughtStream =
|
|
582
|
-
return /* @__PURE__ */
|
|
300
|
+
var ThoughtStream = React4.memo(function ThoughtStream2({ steps }) {
|
|
301
|
+
return /* @__PURE__ */ React4.createElement(Box4, { flexDirection: "column", gap: 1 }, steps.map((step, index) => /* @__PURE__ */ React4.createElement(Box4, { key: index, flexDirection: "column" }, step.type === "thought" && /* @__PURE__ */ React4.createElement(Box4, null, /* @__PURE__ */ React4.createElement(Text4, { color: "magenta" }, "\u{1F914} Thought: "), /* @__PURE__ */ React4.createElement(Text4, null, step.content)), step.type === "action" && /* @__PURE__ */ React4.createElement(Box4, { flexDirection: "column" }, /* @__PURE__ */ React4.createElement(Box4, null, /* @__PURE__ */ React4.createElement(Text4, { color: "yellow" }, "\u26A1 Action: "), /* @__PURE__ */ React4.createElement(Text4, { bold: true }, step.metadata?.toolName || "unknown")), step.metadata?.toolInput && /* @__PURE__ */ React4.createElement(Box4, { paddingLeft: 2 }, /* @__PURE__ */ React4.createElement(Text4, { dimColor: true }, JSON.stringify(step.metadata.toolInput, null, 2)))), step.type === "observation" && /* @__PURE__ */ React4.createElement(Box4, { flexDirection: "column" }, /* @__PURE__ */ React4.createElement(Box4, null, /* @__PURE__ */ React4.createElement(Text4, { color: "blue" }, "\u{1F4CA} Observation: ")), /* @__PURE__ */ React4.createElement(Box4, { paddingLeft: 2 }, /* @__PURE__ */ React4.createElement(Text4, null, step.content))), step.type === "final_answer" && /* @__PURE__ */ React4.createElement(Box4, { flexDirection: "column" }, /* @__PURE__ */ React4.createElement(Box4, null, /* @__PURE__ */ React4.createElement(Text4, { color: "green", bold: true }, "\u2705 Final Answer:", " ")), /* @__PURE__ */ React4.createElement(Box4, { paddingLeft: 2 }, /* @__PURE__ */ React4.createElement(Text4, null, step.content)), step.metadata?.tokenUsage && /* @__PURE__ */ React4.createElement(Box4, { paddingLeft: 2 }, /* @__PURE__ */ React4.createElement(Text4, { dimColor: true }, "(", step.metadata.tokenUsage.total, " tokens)"))))), !steps.some((s) => s.type === "final_answer") && /* @__PURE__ */ React4.createElement(Box4, null, /* @__PURE__ */ React4.createElement(Text4, { color: "yellow" }, /* @__PURE__ */ React4.createElement(Spinner, { type: "dots" })), /* @__PURE__ */ React4.createElement(Text4, null, " ", steps.length === 0 ? "Thinking..." : "Processing...")));
|
|
583
302
|
});
|
|
584
303
|
|
|
585
304
|
// src/store/index.ts
|
|
@@ -605,32 +324,32 @@ var useCliStore = create((set) => ({
|
|
|
605
324
|
}));
|
|
606
325
|
|
|
607
326
|
// src/components/AgentThinking.tsx
|
|
608
|
-
var AgentThinking =
|
|
327
|
+
var AgentThinking = React5.memo(function AgentThinking2() {
|
|
609
328
|
const isThinking = useCliStore((state) => state.isThinking);
|
|
610
329
|
const agentSteps = useCliStore((state) => state.agentSteps);
|
|
611
330
|
if (!isThinking) {
|
|
612
331
|
return null;
|
|
613
332
|
}
|
|
614
|
-
return /* @__PURE__ */
|
|
333
|
+
return /* @__PURE__ */ React5.createElement(Box5, { borderStyle: "single", borderColor: "yellow", paddingX: 1, marginY: 1 }, /* @__PURE__ */ React5.createElement(ThoughtStream, { steps: agentSteps }));
|
|
615
334
|
});
|
|
616
335
|
|
|
617
336
|
// src/components/PermissionPrompt.tsx
|
|
618
|
-
import
|
|
619
|
-
import { Box as
|
|
337
|
+
import React6 from "react";
|
|
338
|
+
import { Box as Box6, Text as Text5 } from "ink";
|
|
620
339
|
import SelectInput from "ink-select-input";
|
|
621
340
|
function renderDiffPreview(preview) {
|
|
622
341
|
const lines = preview.split("\n");
|
|
623
342
|
return lines.map((line, index) => {
|
|
624
343
|
if (line.startsWith("+")) {
|
|
625
|
-
return /* @__PURE__ */
|
|
344
|
+
return /* @__PURE__ */ React6.createElement(Text5, { key: index, color: "green" }, line);
|
|
626
345
|
}
|
|
627
346
|
if (line.startsWith("-")) {
|
|
628
|
-
return /* @__PURE__ */
|
|
347
|
+
return /* @__PURE__ */ React6.createElement(Text5, { key: index, color: "red" }, line);
|
|
629
348
|
}
|
|
630
349
|
if (line.startsWith("@@")) {
|
|
631
|
-
return /* @__PURE__ */
|
|
350
|
+
return /* @__PURE__ */ React6.createElement(Text5, { key: index, color: "cyan" }, line);
|
|
632
351
|
}
|
|
633
|
-
return /* @__PURE__ */
|
|
352
|
+
return /* @__PURE__ */ React6.createElement(Text5, { key: index, dimColor: true }, line);
|
|
634
353
|
});
|
|
635
354
|
}
|
|
636
355
|
function PermissionPrompt({
|
|
@@ -650,121 +369,7 @@ function PermissionPrompt({
|
|
|
650
369
|
{ label: "\u2717 Deny", value: "deny" }
|
|
651
370
|
];
|
|
652
371
|
const argsString = typeof args === "string" ? args : JSON.stringify(args, null, 2);
|
|
653
|
-
return /* @__PURE__ */
|
|
654
|
-
}
|
|
655
|
-
|
|
656
|
-
// src/utils/processFileReferences.ts
|
|
657
|
-
import * as fs2 from "fs";
|
|
658
|
-
import * as path2 from "path";
|
|
659
|
-
|
|
660
|
-
// src/utils/constants.ts
|
|
661
|
-
var NAME_SUFFIXES = ["jr", "sr", "ii", "iii", "iv", "v", "phd", "md", "esq"];
|
|
662
|
-
function isNameSuffix(value) {
|
|
663
|
-
return NAME_SUFFIXES.includes(value);
|
|
664
|
-
}
|
|
665
|
-
|
|
666
|
-
// src/utils/processFileReferences.ts
|
|
667
|
-
var FILE_REFERENCE_REGEX = /(?:^|\s)@([^\s@]+)/g;
|
|
668
|
-
function looksLikeFilePath(ref) {
|
|
669
|
-
if (ref.includes("/") || ref.includes(path2.sep)) {
|
|
670
|
-
return true;
|
|
671
|
-
}
|
|
672
|
-
const extensionMatch = /\.(\w+)$/.exec(ref);
|
|
673
|
-
if (extensionMatch) {
|
|
674
|
-
const ext = extensionMatch[1].toLowerCase();
|
|
675
|
-
if (isNameSuffix(ext)) {
|
|
676
|
-
return false;
|
|
677
|
-
}
|
|
678
|
-
if (ext.length > 10) {
|
|
679
|
-
return false;
|
|
680
|
-
}
|
|
681
|
-
return true;
|
|
682
|
-
}
|
|
683
|
-
return false;
|
|
684
|
-
}
|
|
685
|
-
function extractFileReferences(message) {
|
|
686
|
-
const references = [];
|
|
687
|
-
const regex = /(?:^|\s)@([^\s@]+)/g;
|
|
688
|
-
let match;
|
|
689
|
-
while ((match = regex.exec(message)) !== null) {
|
|
690
|
-
const ref = match[1];
|
|
691
|
-
if (looksLikeFilePath(ref)) {
|
|
692
|
-
references.push(ref);
|
|
693
|
-
}
|
|
694
|
-
}
|
|
695
|
-
return references;
|
|
696
|
-
}
|
|
697
|
-
function readFileContents(filePath) {
|
|
698
|
-
const cwd = process.cwd();
|
|
699
|
-
const absolutePath = path2.resolve(cwd, filePath);
|
|
700
|
-
if (!isPathWithinCwd(filePath)) {
|
|
701
|
-
return { error: `Security: Path "${filePath}" is outside the current working directory` };
|
|
702
|
-
}
|
|
703
|
-
if (!fs2.existsSync(absolutePath)) {
|
|
704
|
-
return { error: `File not found: "${filePath}"` };
|
|
705
|
-
}
|
|
706
|
-
const stats = fs2.statSync(absolutePath);
|
|
707
|
-
if (stats.isDirectory()) {
|
|
708
|
-
try {
|
|
709
|
-
const entries = fs2.readdirSync(absolutePath);
|
|
710
|
-
const fileCount = entries.length;
|
|
711
|
-
return {
|
|
712
|
-
content: `(Directory with ${fileCount} items. Use file tools to explore if needed.)`,
|
|
713
|
-
size: 0
|
|
714
|
-
};
|
|
715
|
-
} catch (err) {
|
|
716
|
-
return { error: `Cannot read directory "${filePath}": ${err instanceof Error ? err.message : "Unknown error"}` };
|
|
717
|
-
}
|
|
718
|
-
}
|
|
719
|
-
if (stats.size > MAX_FILE_SIZE) {
|
|
720
|
-
return {
|
|
721
|
-
error: `File too large: "${filePath}" is ${formatFileSize(stats.size)} (max ${formatFileSize(MAX_FILE_SIZE)})`
|
|
722
|
-
};
|
|
723
|
-
}
|
|
724
|
-
if (isBinaryFile(filePath)) {
|
|
725
|
-
return { error: `Binary file: "${filePath}" cannot be included as text content` };
|
|
726
|
-
}
|
|
727
|
-
try {
|
|
728
|
-
const content = fs2.readFileSync(absolutePath, "utf-8");
|
|
729
|
-
return { content, size: stats.size };
|
|
730
|
-
} catch (err) {
|
|
731
|
-
return { error: `Cannot read file "${filePath}": ${err instanceof Error ? err.message : "Unknown error"}` };
|
|
732
|
-
}
|
|
733
|
-
}
|
|
734
|
-
function formatFileBlock(filePath, content, size, isDirectory) {
|
|
735
|
-
if (isDirectory) {
|
|
736
|
-
return `
|
|
737
|
-
--- Directory Reference: ${filePath} ---
|
|
738
|
-
${content}
|
|
739
|
-
--- End of ${filePath} ---`;
|
|
740
|
-
}
|
|
741
|
-
return `
|
|
742
|
-
--- Referenced File: ${filePath} (${formatFileSize(size)}) ---
|
|
743
|
-
${content}
|
|
744
|
-
--- End of ${filePath} ---`;
|
|
745
|
-
}
|
|
746
|
-
async function processFileReferences(message) {
|
|
747
|
-
const references = extractFileReferences(message);
|
|
748
|
-
const errors = [];
|
|
749
|
-
const fileBlocks = [];
|
|
750
|
-
for (const ref of references) {
|
|
751
|
-
const result = readFileContents(ref);
|
|
752
|
-
if ("error" in result) {
|
|
753
|
-
errors.push(result.error);
|
|
754
|
-
continue;
|
|
755
|
-
}
|
|
756
|
-
const isDirectory = result.size === 0 && result.content.startsWith("(Directory");
|
|
757
|
-
fileBlocks.push(formatFileBlock(ref, result.content, result.size, isDirectory));
|
|
758
|
-
}
|
|
759
|
-
if (fileBlocks.length === 0) {
|
|
760
|
-
return { content: message, errors };
|
|
761
|
-
}
|
|
762
|
-
const processedContent = message + "\n" + fileBlocks.join("\n");
|
|
763
|
-
return { content: processedContent, errors };
|
|
764
|
-
}
|
|
765
|
-
function hasFileReferences(message) {
|
|
766
|
-
FILE_REFERENCE_REGEX.lastIndex = 0;
|
|
767
|
-
return FILE_REFERENCE_REGEX.test(message);
|
|
372
|
+
return /* @__PURE__ */ React6.createElement(Box6, { flexDirection: "column", borderStyle: "bold", borderColor: "yellow", padding: 1, marginY: 1 }, /* @__PURE__ */ React6.createElement(Box6, null, /* @__PURE__ */ React6.createElement(Text5, { bold: true, color: "yellow" }, "\u26A0\uFE0F Permission Required")), /* @__PURE__ */ React6.createElement(Box6, { marginTop: 1 }, /* @__PURE__ */ React6.createElement(Text5, { dimColor: true }, "Tool: "), /* @__PURE__ */ React6.createElement(Text5, { bold: true, color: "cyan" }, toolName)), toolDescription && /* @__PURE__ */ React6.createElement(Box6, null, /* @__PURE__ */ React6.createElement(Text5, { dimColor: true }, "Action: "), /* @__PURE__ */ React6.createElement(Text5, null, toolDescription)), /* @__PURE__ */ React6.createElement(Box6, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React6.createElement(Text5, { bold: true }, "Arguments:"), /* @__PURE__ */ React6.createElement(Box6, { paddingLeft: 2, flexDirection: "column" }, /* @__PURE__ */ React6.createElement(Text5, { dimColor: true }, argsString))), preview && /* @__PURE__ */ React6.createElement(Box6, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React6.createElement(Text5, { bold: true }, "Preview:"), /* @__PURE__ */ React6.createElement(Box6, { borderStyle: "single", borderColor: "gray", paddingX: 1, flexDirection: "column" }, renderDiffPreview(preview))), !canBeTrusted && /* @__PURE__ */ React6.createElement(Box6, { marginTop: 1 }, /* @__PURE__ */ React6.createElement(Text5, { color: "red", dimColor: true }, "Note: This tool cannot be trusted due to its dangerous nature.")), /* @__PURE__ */ React6.createElement(Box6, { marginTop: 1 }, /* @__PURE__ */ React6.createElement(SelectInput, { items, onSelect: (item) => onResponse(item.value) })));
|
|
768
373
|
}
|
|
769
374
|
|
|
770
375
|
// src/components/App.tsx
|
|
@@ -777,7 +382,7 @@ function App({ onMessage, onCommand, onPermissionResponse, commandHistory = [] }
|
|
|
777
382
|
const permissionPrompt = useCliStore((state) => state.permissionPrompt);
|
|
778
383
|
const exitRequested = useCliStore((state) => state.exitRequested);
|
|
779
384
|
const setIsThinking = useCliStore((state) => state.setIsThinking);
|
|
780
|
-
const handleSubmit =
|
|
385
|
+
const handleSubmit = React7.useCallback(
|
|
781
386
|
async (input) => {
|
|
782
387
|
const trimmed = input.trim();
|
|
783
388
|
if (!trimmed) return;
|
|
@@ -788,25 +393,14 @@ function App({ onMessage, onCommand, onPermissionResponse, commandHistory = [] }
|
|
|
788
393
|
}
|
|
789
394
|
setIsThinking(true);
|
|
790
395
|
try {
|
|
791
|
-
|
|
792
|
-
if (hasFileReferences(trimmed)) {
|
|
793
|
-
const processed = await processFileReferences(trimmed);
|
|
794
|
-
messageToSend = processed.content;
|
|
795
|
-
if (processed.errors.length > 0) {
|
|
796
|
-
const errorBlock = processed.errors.map((e) => `[Warning: ${e}]`).join("\n");
|
|
797
|
-
messageToSend = `${messageToSend}
|
|
798
|
-
|
|
799
|
-
${errorBlock}`;
|
|
800
|
-
}
|
|
801
|
-
}
|
|
802
|
-
await onMessage(messageToSend);
|
|
396
|
+
await onMessage(trimmed);
|
|
803
397
|
} finally {
|
|
804
398
|
setIsThinking(false);
|
|
805
399
|
}
|
|
806
400
|
},
|
|
807
401
|
[onMessage, onCommand, setIsThinking]
|
|
808
402
|
);
|
|
809
|
-
return /* @__PURE__ */
|
|
403
|
+
return /* @__PURE__ */ React7.createElement(Box7, { flexDirection: "column" }, /* @__PURE__ */ React7.createElement(StatusBar, { sessionName, model: currentModel, tokenUsage: totalTokens }), permissionPrompt ? /* @__PURE__ */ React7.createElement(Box7, { flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React7.createElement(
|
|
810
404
|
PermissionPrompt,
|
|
811
405
|
{
|
|
812
406
|
toolName: permissionPrompt.toolName,
|
|
@@ -815,39 +409,39 @@ ${errorBlock}`;
|
|
|
815
409
|
canBeTrusted: permissionPrompt.canBeTrusted,
|
|
816
410
|
onResponse: onPermissionResponse
|
|
817
411
|
}
|
|
818
|
-
)) : /* @__PURE__ */
|
|
412
|
+
)) : /* @__PURE__ */ React7.createElement(React7.Fragment, null, /* @__PURE__ */ React7.createElement(Static, { items: messages }, (message, index) => /* @__PURE__ */ React7.createElement(Box7, { key: index, flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React7.createElement(MessageItem, { message }))), /* @__PURE__ */ React7.createElement(AgentThinking, null), exitRequested && /* @__PURE__ */ React7.createElement(Box7, { paddingX: 1, marginBottom: 1 }, /* @__PURE__ */ React7.createElement(Text6, { color: "yellow", bold: true }, "\u26A0\uFE0F Press Ctrl+C again to exit")), /* @__PURE__ */ React7.createElement(Box7, { borderStyle: "single", borderColor: "cyan", paddingX: 1 }, /* @__PURE__ */ React7.createElement(InputPrompt, { onSubmit: handleSubmit, disabled: isThinking, history: commandHistory }))));
|
|
819
413
|
}
|
|
820
414
|
function MessageItem({ message }) {
|
|
821
|
-
return /* @__PURE__ */
|
|
415
|
+
return /* @__PURE__ */ React7.createElement(Box7, { flexDirection: "column", marginBottom: 1 }, /* @__PURE__ */ React7.createElement(Box7, null, /* @__PURE__ */ React7.createElement(Text6, { bold: true, color: message.role === "user" ? "cyan" : "green" }, message.role === "user" ? "\u{1F464} You" : "\u{1F916} Assistant"), /* @__PURE__ */ React7.createElement(Text6, { dimColor: true }, " \u2022 ", new Date(message.timestamp).toLocaleTimeString())), /* @__PURE__ */ React7.createElement(Box7, { paddingLeft: 2 }, message.metadata?.permissionDenied ? /* @__PURE__ */ React7.createElement(Text6, { color: "yellow" }, "\u26A0\uFE0F ", message.content) : /* @__PURE__ */ React7.createElement(Text6, null, message.content)), message.metadata?.steps && message.metadata.steps.length > 0 && /* @__PURE__ */ React7.createElement(Box7, { paddingLeft: 2, marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React7.createElement(Text6, { 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__ */ React7.createElement(Text6, { dimColor: true }, "Step types: ", message.metadata.steps.map((s) => s.type).join(", ")), message.metadata.steps.map((step, idx) => {
|
|
822
416
|
if (step.type === "thought") {
|
|
823
|
-
return /* @__PURE__ */
|
|
417
|
+
return /* @__PURE__ */ React7.createElement(Box7, { key: idx, paddingLeft: 2, marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React7.createElement(Text6, { color: "blue" }, "\u{1F4AD} Thought:"), /* @__PURE__ */ React7.createElement(Text6, { dimColor: true }, ` ${step.content.slice(0, 200)}${step.content.length > 200 ? "..." : ""}`));
|
|
824
418
|
}
|
|
825
419
|
if (step.type === "action") {
|
|
826
420
|
const toolName = step.metadata?.toolName || "unknown";
|
|
827
421
|
const toolInput = step.metadata?.toolInput;
|
|
828
422
|
const observationStep = message.metadata.steps[idx + 1];
|
|
829
423
|
const result = observationStep?.type === "observation" ? observationStep.content : null;
|
|
830
|
-
return /* @__PURE__ */
|
|
424
|
+
return /* @__PURE__ */ React7.createElement(Box7, { key: idx, paddingLeft: 2, marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React7.createElement(Text6, { color: "yellow" }, "\u{1F527} Action: ", toolName), toolInput && /* @__PURE__ */ React7.createElement(Text6, { dimColor: true }, ` Input: ${typeof toolInput === "string" ? toolInput : JSON.stringify(toolInput).slice(0, 100)}`), result && /* @__PURE__ */ React7.createElement(Text6, { 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 ? "..." : ""}`));
|
|
831
425
|
}
|
|
832
426
|
return null;
|
|
833
|
-
}).filter(Boolean)), message.metadata?.tokenUsage && (!message.metadata.steps || message.metadata.steps.length === 0) && /* @__PURE__ */
|
|
427
|
+
}).filter(Boolean)), message.metadata?.tokenUsage && (!message.metadata.steps || message.metadata.steps.length === 0) && /* @__PURE__ */ React7.createElement(Box7, { paddingLeft: 2 }, /* @__PURE__ */ React7.createElement(Text6, { dimColor: true }, `${message.metadata.tokenUsage.total} tokens`)));
|
|
834
428
|
}
|
|
835
429
|
|
|
836
430
|
// src/components/MessageList.tsx
|
|
837
|
-
import
|
|
838
|
-
import { Box as
|
|
431
|
+
import React8 from "react";
|
|
432
|
+
import { Box as Box8, Text as Text7 } from "ink";
|
|
839
433
|
function stripThinkingTags(content) {
|
|
840
434
|
return content.replace(/<think>[\s\S]*?<\/think>/g, "").trim();
|
|
841
435
|
}
|
|
842
|
-
var MessageList =
|
|
436
|
+
var MessageList = React8.memo(
|
|
843
437
|
function MessageList2({ messages }) {
|
|
844
438
|
if (messages.length === 0) {
|
|
845
|
-
return /* @__PURE__ */
|
|
439
|
+
return /* @__PURE__ */ React8.createElement(Box8, { paddingY: 1 }, /* @__PURE__ */ React8.createElement(Text7, { dimColor: true }, "No messages yet. Type a message to start!"));
|
|
846
440
|
}
|
|
847
|
-
return /* @__PURE__ */
|
|
441
|
+
return /* @__PURE__ */ React8.createElement(Box8, { flexDirection: "column", gap: 1, paddingY: 1 }, messages.map((message, index) => /* @__PURE__ */ React8.createElement(Box8, { key: index, flexDirection: "column", marginBottom: 1 }, /* @__PURE__ */ React8.createElement(Box8, null, /* @__PURE__ */ React8.createElement(Text7, { bold: true, color: message.role === "user" ? "cyan" : "green" }, message.role === "user" ? "\u{1F464} You" : "\u{1F916} Assistant"), /* @__PURE__ */ React8.createElement(Text7, { dimColor: true }, " \u2022 ", new Date(message.timestamp).toLocaleTimeString())), /* @__PURE__ */ React8.createElement(Box8, { paddingLeft: 2 }, message.metadata?.permissionDenied ? /* @__PURE__ */ React8.createElement(Text7, { color: "yellow" }, "\u26A0\uFE0F ", stripThinkingTags(message.content)) : /* @__PURE__ */ React8.createElement(Text7, null, stripThinkingTags(message.content))), message.metadata?.steps && message.metadata.steps.length > 0 && /* @__PURE__ */ React8.createElement(Box8, { paddingLeft: 2, marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React8.createElement(Text7, { 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__ */ React8.createElement(Text7, { dimColor: true }, "Step types: ", message.metadata.steps.map((s) => s.type).join(", ")), message.metadata.steps.map((step, idx) => {
|
|
848
442
|
if (step.type === "thought") {
|
|
849
|
-
return /* @__PURE__ */
|
|
850
|
-
|
|
443
|
+
return /* @__PURE__ */ React8.createElement(Box8, { key: idx, paddingLeft: 2, marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React8.createElement(Text7, { color: "blue" }, "\u{1F4AD} Thought:"), /* @__PURE__ */ React8.createElement(
|
|
444
|
+
Text7,
|
|
851
445
|
{
|
|
852
446
|
dimColor: true
|
|
853
447
|
},
|
|
@@ -859,10 +453,10 @@ var MessageList = React9.memo(
|
|
|
859
453
|
const toolInput = step.metadata?.toolInput;
|
|
860
454
|
const observationStep = message.metadata.steps[idx + 1];
|
|
861
455
|
const result = observationStep?.type === "observation" ? observationStep.content : null;
|
|
862
|
-
return /* @__PURE__ */
|
|
456
|
+
return /* @__PURE__ */ React8.createElement(Box8, { key: idx, paddingLeft: 2, marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React8.createElement(Text7, { color: "yellow" }, "\u{1F527} Action: ", toolName), toolInput && /* @__PURE__ */ React8.createElement(Text7, { dimColor: true }, ` Input: ${typeof toolInput === "string" ? toolInput : JSON.stringify(toolInput).slice(0, 100)}`), result && /* @__PURE__ */ React8.createElement(Text7, { 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 ? "..." : ""}`));
|
|
863
457
|
}
|
|
864
458
|
return null;
|
|
865
|
-
}).filter(Boolean)), message.metadata?.tokenUsage && (!message.metadata.steps || message.metadata.steps.length === 0) && /* @__PURE__ */
|
|
459
|
+
}).filter(Boolean)), message.metadata?.tokenUsage && (!message.metadata.steps || message.metadata.steps.length === 0) && /* @__PURE__ */ React8.createElement(Box8, { paddingLeft: 2 }, /* @__PURE__ */ React8.createElement(Text7, { dimColor: true }, `${message.metadata.tokenUsage.total} tokens`)))));
|
|
866
460
|
},
|
|
867
461
|
(prevProps, nextProps) => {
|
|
868
462
|
if (prevProps.messages.length !== nextProps.messages.length) {
|
|
@@ -872,6 +466,39 @@ var MessageList = React9.memo(
|
|
|
872
466
|
}
|
|
873
467
|
);
|
|
874
468
|
|
|
469
|
+
// src/components/TrustLocationSelector.tsx
|
|
470
|
+
import React9 from "react";
|
|
471
|
+
import { Box as Box9, Text as Text8 } from "ink";
|
|
472
|
+
import SelectInput2 from "ink-select-input";
|
|
473
|
+
function TrustLocationSelector({ inProject, onSelect, onCancel }) {
|
|
474
|
+
const items = [];
|
|
475
|
+
if (inProject) {
|
|
476
|
+
items.push({
|
|
477
|
+
label: "Project settings (local) - Saved in .bike4mind/local.json (not committed)",
|
|
478
|
+
value: "local"
|
|
479
|
+
});
|
|
480
|
+
items.push({
|
|
481
|
+
label: "Project settings (team-wide) - Checked in at .bike4mind/config.json",
|
|
482
|
+
value: "project"
|
|
483
|
+
});
|
|
484
|
+
}
|
|
485
|
+
items.push({
|
|
486
|
+
label: "User settings - Saved at ~/.bike4mind/config.json",
|
|
487
|
+
value: "global"
|
|
488
|
+
});
|
|
489
|
+
const handleSelect = (item) => {
|
|
490
|
+
onSelect(item.value);
|
|
491
|
+
};
|
|
492
|
+
return /* @__PURE__ */ React9.createElement(Box9, { flexDirection: "column", marginY: 1 }, /* @__PURE__ */ React9.createElement(Box9, { marginBottom: 1 }, /* @__PURE__ */ React9.createElement(Text8, { bold: true }, "Where should this rule be saved?")), /* @__PURE__ */ React9.createElement(
|
|
493
|
+
SelectInput2,
|
|
494
|
+
{
|
|
495
|
+
items,
|
|
496
|
+
onSelect: handleSelect,
|
|
497
|
+
itemComponent: ({ isSelected, label }) => /* @__PURE__ */ React9.createElement(Box9, null, /* @__PURE__ */ React9.createElement(Text8, { color: isSelected ? "cyan" : void 0 }, isSelected ? "\u276F " : " ", label))
|
|
498
|
+
}
|
|
499
|
+
), /* @__PURE__ */ React9.createElement(Box9, { marginTop: 1 }, /* @__PURE__ */ React9.createElement(Text8, { dimColor: true }, "Use \u2191\u2193 arrows to navigate, Enter to select, Ctrl+C to cancel")));
|
|
500
|
+
}
|
|
501
|
+
|
|
875
502
|
// src/components/LoginFlow.tsx
|
|
876
503
|
import React10, { useState as useState2, useEffect as useEffect2 } from "react";
|
|
877
504
|
import { Box as Box10, Text as Text9 } from "ink";
|
|
@@ -984,7 +611,7 @@ var OAuthClient = class {
|
|
|
984
611
|
* Sleep for specified milliseconds
|
|
985
612
|
*/
|
|
986
613
|
sleep(ms) {
|
|
987
|
-
return new Promise((
|
|
614
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
988
615
|
}
|
|
989
616
|
};
|
|
990
617
|
|
|
@@ -1049,19 +676,19 @@ function LoginFlow({ apiUrl = "http://localhost:3000", configStore, onSuccess, o
|
|
|
1049
676
|
}
|
|
1050
677
|
|
|
1051
678
|
// src/storage/SessionStore.ts
|
|
1052
|
-
import { promises as
|
|
1053
|
-
import
|
|
679
|
+
import { promises as fs } from "fs";
|
|
680
|
+
import path from "path";
|
|
1054
681
|
import { homedir } from "os";
|
|
1055
682
|
var SessionStore = class {
|
|
1056
683
|
constructor(basePath) {
|
|
1057
|
-
this.basePath = basePath ||
|
|
684
|
+
this.basePath = basePath || path.join(homedir(), ".bike4mind", "sessions");
|
|
1058
685
|
}
|
|
1059
686
|
/**
|
|
1060
687
|
* Initialize storage directory
|
|
1061
688
|
*/
|
|
1062
689
|
async init() {
|
|
1063
690
|
try {
|
|
1064
|
-
await
|
|
691
|
+
await fs.mkdir(this.basePath, { recursive: true });
|
|
1065
692
|
} catch (error) {
|
|
1066
693
|
console.error("Failed to initialize session storage:", error);
|
|
1067
694
|
throw error;
|
|
@@ -1072,9 +699,9 @@ var SessionStore = class {
|
|
|
1072
699
|
*/
|
|
1073
700
|
async save(session) {
|
|
1074
701
|
await this.init();
|
|
1075
|
-
const filePath =
|
|
702
|
+
const filePath = path.join(this.basePath, `${session.id}.json`);
|
|
1076
703
|
try {
|
|
1077
|
-
await
|
|
704
|
+
await fs.writeFile(filePath, JSON.stringify(session, null, 2), "utf-8");
|
|
1078
705
|
} catch (error) {
|
|
1079
706
|
console.error("Failed to save session:", error);
|
|
1080
707
|
throw error;
|
|
@@ -1084,9 +711,9 @@ var SessionStore = class {
|
|
|
1084
711
|
* Load a session from disk by ID
|
|
1085
712
|
*/
|
|
1086
713
|
async load(id) {
|
|
1087
|
-
const filePath =
|
|
714
|
+
const filePath = path.join(this.basePath, `${id}.json`);
|
|
1088
715
|
try {
|
|
1089
|
-
const data = await
|
|
716
|
+
const data = await fs.readFile(filePath, "utf-8");
|
|
1090
717
|
return JSON.parse(data);
|
|
1091
718
|
} catch (error) {
|
|
1092
719
|
if (error.code === "ENOENT") {
|
|
@@ -1110,12 +737,12 @@ var SessionStore = class {
|
|
|
1110
737
|
async list() {
|
|
1111
738
|
await this.init();
|
|
1112
739
|
try {
|
|
1113
|
-
const files = await
|
|
740
|
+
const files = await fs.readdir(this.basePath);
|
|
1114
741
|
const jsonFiles = files.filter((f) => f.endsWith(".json"));
|
|
1115
742
|
const sessions = await Promise.all(
|
|
1116
743
|
jsonFiles.map(async (file) => {
|
|
1117
|
-
const filePath =
|
|
1118
|
-
const data = await
|
|
744
|
+
const filePath = path.join(this.basePath, file);
|
|
745
|
+
const data = await fs.readFile(filePath, "utf-8");
|
|
1119
746
|
return JSON.parse(data);
|
|
1120
747
|
})
|
|
1121
748
|
);
|
|
@@ -1129,9 +756,9 @@ var SessionStore = class {
|
|
|
1129
756
|
* Delete a session
|
|
1130
757
|
*/
|
|
1131
758
|
async delete(id) {
|
|
1132
|
-
const filePath =
|
|
759
|
+
const filePath = path.join(this.basePath, `${id}.json`);
|
|
1133
760
|
try {
|
|
1134
|
-
await
|
|
761
|
+
await fs.unlink(filePath);
|
|
1135
762
|
return true;
|
|
1136
763
|
} catch (error) {
|
|
1137
764
|
if (error.code === "ENOENT") {
|
|
@@ -1167,8 +794,8 @@ var SessionStore = class {
|
|
|
1167
794
|
};
|
|
1168
795
|
|
|
1169
796
|
// src/storage/ConfigStore.ts
|
|
1170
|
-
import { promises as
|
|
1171
|
-
import
|
|
797
|
+
import { promises as fs2, existsSync } from "fs";
|
|
798
|
+
import path2 from "path";
|
|
1172
799
|
import { homedir as homedir2 } from "os";
|
|
1173
800
|
import { v4 as uuidv4 } from "uuid";
|
|
1174
801
|
import { z } from "zod";
|
|
@@ -1214,6 +841,53 @@ var CliConfigSchema = z.object({
|
|
|
1214
841
|
}),
|
|
1215
842
|
trustedTools: z.array(z.string()).optional().default([])
|
|
1216
843
|
});
|
|
844
|
+
var ProjectConfigSchema = z.object({
|
|
845
|
+
tools: z.object({
|
|
846
|
+
enabled: z.array(z.string()).optional(),
|
|
847
|
+
denied: z.array(z.string()).optional(),
|
|
848
|
+
config: z.record(z.any()).optional()
|
|
849
|
+
}).optional(),
|
|
850
|
+
defaultModel: z.string().optional(),
|
|
851
|
+
mcpServers: z.array(
|
|
852
|
+
z.object({
|
|
853
|
+
name: z.string(),
|
|
854
|
+
command: z.string(),
|
|
855
|
+
args: z.array(z.string()),
|
|
856
|
+
env: z.record(z.string()),
|
|
857
|
+
enabled: z.boolean()
|
|
858
|
+
})
|
|
859
|
+
).optional(),
|
|
860
|
+
preferences: z.object({
|
|
861
|
+
maxTokens: z.number().optional(),
|
|
862
|
+
temperature: z.number().optional(),
|
|
863
|
+
autoSave: z.boolean().optional(),
|
|
864
|
+
theme: z.enum(["light", "dark"]).optional(),
|
|
865
|
+
exportFormat: z.enum(["markdown", "json"]).optional()
|
|
866
|
+
}).optional()
|
|
867
|
+
});
|
|
868
|
+
var ProjectLocalConfigSchema = z.object({
|
|
869
|
+
trustedTools: z.array(z.string()).optional(),
|
|
870
|
+
toolApiKeys: z.object({
|
|
871
|
+
openweather: z.string().optional(),
|
|
872
|
+
serper: z.string().optional()
|
|
873
|
+
}).optional(),
|
|
874
|
+
preferences: z.object({
|
|
875
|
+
maxTokens: z.number().optional(),
|
|
876
|
+
temperature: z.number().optional(),
|
|
877
|
+
autoSave: z.boolean().optional(),
|
|
878
|
+
theme: z.enum(["light", "dark"]).optional(),
|
|
879
|
+
exportFormat: z.enum(["markdown", "json"]).optional()
|
|
880
|
+
}).optional(),
|
|
881
|
+
mcpServers: z.array(
|
|
882
|
+
z.object({
|
|
883
|
+
name: z.string(),
|
|
884
|
+
command: z.string(),
|
|
885
|
+
args: z.array(z.string()),
|
|
886
|
+
env: z.record(z.string()),
|
|
887
|
+
enabled: z.boolean()
|
|
888
|
+
})
|
|
889
|
+
).optional()
|
|
890
|
+
});
|
|
1217
891
|
var DEFAULT_CONFIG = {
|
|
1218
892
|
version: "0.1.0",
|
|
1219
893
|
userId: uuidv4(),
|
|
@@ -1239,18 +913,132 @@ var DEFAULT_CONFIG = {
|
|
|
1239
913
|
trustedTools: []
|
|
1240
914
|
// No tools trusted by default
|
|
1241
915
|
};
|
|
916
|
+
function findProjectConfigDir(startDir = process.cwd()) {
|
|
917
|
+
let currentDir = startDir;
|
|
918
|
+
const { root } = path2.parse(currentDir);
|
|
919
|
+
while (currentDir !== root) {
|
|
920
|
+
const projectConfigPath = path2.join(currentDir, ".bike4mind", "config.json");
|
|
921
|
+
try {
|
|
922
|
+
if (existsSync(projectConfigPath)) {
|
|
923
|
+
return currentDir;
|
|
924
|
+
}
|
|
925
|
+
} catch {
|
|
926
|
+
}
|
|
927
|
+
currentDir = path2.dirname(currentDir);
|
|
928
|
+
}
|
|
929
|
+
return null;
|
|
930
|
+
}
|
|
931
|
+
async function loadProjectConfig(projectDir) {
|
|
932
|
+
const configPath = path2.join(projectDir, ".bike4mind", "config.json");
|
|
933
|
+
try {
|
|
934
|
+
const data = await fs2.readFile(configPath, "utf-8");
|
|
935
|
+
const rawConfig = JSON.parse(data);
|
|
936
|
+
const validated = ProjectConfigSchema.parse(rawConfig);
|
|
937
|
+
return validated;
|
|
938
|
+
} catch (error) {
|
|
939
|
+
if (error.code === "ENOENT") {
|
|
940
|
+
return null;
|
|
941
|
+
}
|
|
942
|
+
if (error instanceof z.ZodError) {
|
|
943
|
+
console.error("Project config validation error:", error.errors);
|
|
944
|
+
return null;
|
|
945
|
+
}
|
|
946
|
+
console.error("Failed to load project config:", error);
|
|
947
|
+
return null;
|
|
948
|
+
}
|
|
949
|
+
}
|
|
950
|
+
async function loadProjectLocalConfig(projectDir) {
|
|
951
|
+
const configPath = path2.join(projectDir, ".bike4mind", "local.json");
|
|
952
|
+
try {
|
|
953
|
+
const data = await fs2.readFile(configPath, "utf-8");
|
|
954
|
+
const rawConfig = JSON.parse(data);
|
|
955
|
+
const validated = ProjectLocalConfigSchema.parse(rawConfig);
|
|
956
|
+
return validated;
|
|
957
|
+
} catch (error) {
|
|
958
|
+
if (error.code === "ENOENT") {
|
|
959
|
+
return null;
|
|
960
|
+
}
|
|
961
|
+
if (error instanceof z.ZodError) {
|
|
962
|
+
console.error("Project local config validation error:", error.errors);
|
|
963
|
+
return null;
|
|
964
|
+
}
|
|
965
|
+
console.error("Failed to load project local config:", error);
|
|
966
|
+
return null;
|
|
967
|
+
}
|
|
968
|
+
}
|
|
969
|
+
function mergeMcpServers(...serverArrays) {
|
|
970
|
+
const serverMap = /* @__PURE__ */ new Map();
|
|
971
|
+
for (const servers of serverArrays) {
|
|
972
|
+
if (servers) {
|
|
973
|
+
for (const server of servers) {
|
|
974
|
+
serverMap.set(server.name, server);
|
|
975
|
+
}
|
|
976
|
+
}
|
|
977
|
+
}
|
|
978
|
+
return Array.from(serverMap.values());
|
|
979
|
+
}
|
|
980
|
+
function mergeConfigs(global, project, local) {
|
|
981
|
+
const merged = { ...global };
|
|
982
|
+
if (project) {
|
|
983
|
+
if (project.defaultModel) {
|
|
984
|
+
merged.defaultModel = project.defaultModel;
|
|
985
|
+
}
|
|
986
|
+
if (project.preferences) {
|
|
987
|
+
merged.preferences = {
|
|
988
|
+
...merged.preferences,
|
|
989
|
+
...project.preferences
|
|
990
|
+
};
|
|
991
|
+
}
|
|
992
|
+
if (project.tools) {
|
|
993
|
+
merged.tools = {
|
|
994
|
+
...merged.tools,
|
|
995
|
+
enabled: project.tools.enabled || merged.tools.enabled,
|
|
996
|
+
disabled: [...merged.tools.disabled, ...project.tools.denied || []],
|
|
997
|
+
config: {
|
|
998
|
+
...merged.tools.config,
|
|
999
|
+
...project.tools.config
|
|
1000
|
+
}
|
|
1001
|
+
};
|
|
1002
|
+
}
|
|
1003
|
+
if (project.mcpServers) {
|
|
1004
|
+
merged.mcpServers = mergeMcpServers(merged.mcpServers, project.mcpServers);
|
|
1005
|
+
}
|
|
1006
|
+
}
|
|
1007
|
+
if (local) {
|
|
1008
|
+
if (local.trustedTools) {
|
|
1009
|
+
merged.trustedTools = [...merged.trustedTools || [], ...local.trustedTools];
|
|
1010
|
+
}
|
|
1011
|
+
if (local.toolApiKeys) {
|
|
1012
|
+
merged.toolApiKeys = {
|
|
1013
|
+
...merged.toolApiKeys,
|
|
1014
|
+
...local.toolApiKeys
|
|
1015
|
+
};
|
|
1016
|
+
}
|
|
1017
|
+
if (local.preferences) {
|
|
1018
|
+
merged.preferences = {
|
|
1019
|
+
...merged.preferences,
|
|
1020
|
+
...local.preferences
|
|
1021
|
+
};
|
|
1022
|
+
}
|
|
1023
|
+
if (local.mcpServers) {
|
|
1024
|
+
merged.mcpServers = mergeMcpServers(merged.mcpServers, local.mcpServers);
|
|
1025
|
+
}
|
|
1026
|
+
}
|
|
1027
|
+
return merged;
|
|
1028
|
+
}
|
|
1242
1029
|
var ConfigStore = class {
|
|
1243
1030
|
constructor(configPath) {
|
|
1244
1031
|
this.config = null;
|
|
1245
|
-
this.
|
|
1032
|
+
this.projectConfigDir = null;
|
|
1033
|
+
this.configPath = configPath || path2.join(homedir2(), ".bike4mind", "config.json");
|
|
1246
1034
|
}
|
|
1247
1035
|
/**
|
|
1248
1036
|
* Initialize config directory
|
|
1249
1037
|
*/
|
|
1250
1038
|
async init() {
|
|
1251
|
-
const dir =
|
|
1039
|
+
const dir = path2.dirname(this.configPath);
|
|
1252
1040
|
try {
|
|
1253
|
-
await
|
|
1041
|
+
await fs2.mkdir(dir, { recursive: true });
|
|
1254
1042
|
} catch (error) {
|
|
1255
1043
|
console.error("Failed to initialize config directory:", error);
|
|
1256
1044
|
throw error;
|
|
@@ -1258,51 +1046,76 @@ var ConfigStore = class {
|
|
|
1258
1046
|
}
|
|
1259
1047
|
/**
|
|
1260
1048
|
* Load configuration from disk with Zod validation
|
|
1049
|
+
* Merges global → project → local configs
|
|
1261
1050
|
*/
|
|
1262
1051
|
async load() {
|
|
1263
1052
|
if (this.config) {
|
|
1264
1053
|
return this.config;
|
|
1265
1054
|
}
|
|
1266
1055
|
try {
|
|
1056
|
+
let globalConfig;
|
|
1267
1057
|
try {
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1058
|
+
try {
|
|
1059
|
+
const stats = await fs2.stat(this.configPath);
|
|
1060
|
+
const mode = stats.mode & 511;
|
|
1061
|
+
if (mode !== 384) {
|
|
1062
|
+
console.warn(`\u26A0\uFE0F Config file has insecure permissions (${mode.toString(8)}). Setting to 0600...`);
|
|
1063
|
+
await fs2.chmod(this.configPath, 384);
|
|
1064
|
+
}
|
|
1065
|
+
} catch (statError) {
|
|
1066
|
+
}
|
|
1067
|
+
const data = await fs2.readFile(this.configPath, "utf-8");
|
|
1068
|
+
const rawConfig = JSON.parse(data);
|
|
1069
|
+
if (rawConfig.apiConfig && "environment" in rawConfig.apiConfig) {
|
|
1070
|
+
const oldApiConfig = rawConfig.apiConfig;
|
|
1071
|
+
if (oldApiConfig.environment === "custom" && oldApiConfig.customUrl) {
|
|
1072
|
+
rawConfig.apiConfig = { customUrl: oldApiConfig.customUrl };
|
|
1073
|
+
} else {
|
|
1074
|
+
rawConfig.apiConfig = {};
|
|
1075
|
+
}
|
|
1273
1076
|
}
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1077
|
+
const validated = CliConfigSchema.parse(rawConfig);
|
|
1078
|
+
globalConfig = {
|
|
1079
|
+
...DEFAULT_CONFIG,
|
|
1080
|
+
...validated,
|
|
1081
|
+
auth: validated.auth,
|
|
1082
|
+
// Explicitly preserve auth field
|
|
1083
|
+
preferences: {
|
|
1084
|
+
...DEFAULT_CONFIG.preferences,
|
|
1085
|
+
...validated.preferences
|
|
1086
|
+
},
|
|
1087
|
+
tools: {
|
|
1088
|
+
...DEFAULT_CONFIG.tools,
|
|
1089
|
+
...validated.tools
|
|
1090
|
+
},
|
|
1091
|
+
toolApiKeys: {
|
|
1092
|
+
...DEFAULT_CONFIG.toolApiKeys,
|
|
1093
|
+
...validated.toolApiKeys || {}
|
|
1094
|
+
},
|
|
1095
|
+
trustedTools: validated.trustedTools || []
|
|
1096
|
+
};
|
|
1097
|
+
} catch (error) {
|
|
1098
|
+
if (error.code === "ENOENT") {
|
|
1099
|
+
globalConfig = { ...DEFAULT_CONFIG };
|
|
1100
|
+
} else if (error instanceof z.ZodError) {
|
|
1101
|
+
console.error("Global config validation error:", error.errors);
|
|
1102
|
+
console.error("Using default configuration");
|
|
1103
|
+
globalConfig = { ...DEFAULT_CONFIG };
|
|
1282
1104
|
} else {
|
|
1283
|
-
|
|
1105
|
+
throw error;
|
|
1284
1106
|
}
|
|
1285
1107
|
}
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
...DEFAULT_CONFIG.tools,
|
|
1298
|
-
...validated.tools
|
|
1299
|
-
},
|
|
1300
|
-
toolApiKeys: {
|
|
1301
|
-
...DEFAULT_CONFIG.toolApiKeys,
|
|
1302
|
-
...validated.toolApiKeys || {}
|
|
1303
|
-
},
|
|
1304
|
-
trustedTools: validated.trustedTools || []
|
|
1305
|
-
};
|
|
1108
|
+
this.projectConfigDir = findProjectConfigDir();
|
|
1109
|
+
let projectConfig = null;
|
|
1110
|
+
let projectLocalConfig = null;
|
|
1111
|
+
if (this.projectConfigDir) {
|
|
1112
|
+
projectConfig = await loadProjectConfig(this.projectConfigDir);
|
|
1113
|
+
projectLocalConfig = await loadProjectLocalConfig(this.projectConfigDir);
|
|
1114
|
+
if (projectConfig) {
|
|
1115
|
+
console.log(`\u{1F4C1} Project config loaded from: ${this.projectConfigDir}/.bike4mind/`);
|
|
1116
|
+
}
|
|
1117
|
+
}
|
|
1118
|
+
this.config = mergeConfigs(globalConfig, projectConfig, projectLocalConfig);
|
|
1306
1119
|
return this.config;
|
|
1307
1120
|
} catch (error) {
|
|
1308
1121
|
if (error.code === "ENOENT") {
|
|
@@ -1346,8 +1159,8 @@ var ConfigStore = class {
|
|
|
1346
1159
|
throw new Error("No configuration to save");
|
|
1347
1160
|
}
|
|
1348
1161
|
try {
|
|
1349
|
-
await
|
|
1350
|
-
await
|
|
1162
|
+
await fs2.writeFile(this.configPath, JSON.stringify(this.config, null, 2), "utf-8");
|
|
1163
|
+
await fs2.chmod(this.configPath, 384);
|
|
1351
1164
|
} catch (error) {
|
|
1352
1165
|
console.error("Failed to save config:", error);
|
|
1353
1166
|
throw error;
|
|
@@ -1489,27 +1302,126 @@ var ConfigStore = class {
|
|
|
1489
1302
|
} else {
|
|
1490
1303
|
config.apiConfig = { customUrl: url };
|
|
1491
1304
|
}
|
|
1492
|
-
await this.save(config);
|
|
1305
|
+
await this.save(config);
|
|
1306
|
+
}
|
|
1307
|
+
/**
|
|
1308
|
+
* Get project config directory (if any)
|
|
1309
|
+
*/
|
|
1310
|
+
getProjectConfigDir() {
|
|
1311
|
+
return this.projectConfigDir;
|
|
1312
|
+
}
|
|
1313
|
+
/**
|
|
1314
|
+
* Initialize project config in current directory
|
|
1315
|
+
* Creates .bike4mind/config.json with default project config
|
|
1316
|
+
* Also ensures .bike4mind/local.json is in .gitignore
|
|
1317
|
+
*/
|
|
1318
|
+
async initProjectConfig(projectDir = process.cwd()) {
|
|
1319
|
+
const configDir = path2.join(projectDir, ".bike4mind");
|
|
1320
|
+
const configPath = path2.join(configDir, "config.json");
|
|
1321
|
+
await fs2.mkdir(configDir, { recursive: true });
|
|
1322
|
+
try {
|
|
1323
|
+
await fs2.access(configPath);
|
|
1324
|
+
console.log(`Project config already exists at: ${configPath}`);
|
|
1325
|
+
} catch {
|
|
1326
|
+
const defaultProjectConfig = {
|
|
1327
|
+
tools: {
|
|
1328
|
+
enabled: [],
|
|
1329
|
+
denied: [],
|
|
1330
|
+
config: {}
|
|
1331
|
+
},
|
|
1332
|
+
mcpServers: [],
|
|
1333
|
+
preferences: {}
|
|
1334
|
+
};
|
|
1335
|
+
await fs2.writeFile(configPath, JSON.stringify(defaultProjectConfig, null, 2), "utf-8");
|
|
1336
|
+
console.log(`\u2705 Created project config at: ${configPath}`);
|
|
1337
|
+
}
|
|
1338
|
+
await this.ensureGitignore(projectDir);
|
|
1339
|
+
}
|
|
1340
|
+
/**
|
|
1341
|
+
* Ensure .gitignore includes .bike4mind/local.json
|
|
1342
|
+
*/
|
|
1343
|
+
async ensureGitignore(projectDir) {
|
|
1344
|
+
const gitignorePath = path2.join(projectDir, ".gitignore");
|
|
1345
|
+
const entryToAdd = ".bike4mind/local.json";
|
|
1346
|
+
try {
|
|
1347
|
+
let gitignoreContent = "";
|
|
1348
|
+
try {
|
|
1349
|
+
gitignoreContent = await fs2.readFile(gitignorePath, "utf-8");
|
|
1350
|
+
} catch {
|
|
1351
|
+
}
|
|
1352
|
+
if (gitignoreContent.includes(entryToAdd)) {
|
|
1353
|
+
return;
|
|
1354
|
+
}
|
|
1355
|
+
const newContent = gitignoreContent.trim() + (gitignoreContent ? "\n" : "") + `
|
|
1356
|
+
# Bike4Mind local config (developer-specific)
|
|
1357
|
+
${entryToAdd}
|
|
1358
|
+
`;
|
|
1359
|
+
await fs2.writeFile(gitignorePath, newContent, "utf-8");
|
|
1360
|
+
console.log(`\u2705 Added ${entryToAdd} to .gitignore`);
|
|
1361
|
+
} catch (error) {
|
|
1362
|
+
console.warn(`\u26A0\uFE0F Failed to update .gitignore:`, error);
|
|
1363
|
+
}
|
|
1364
|
+
}
|
|
1365
|
+
/**
|
|
1366
|
+
* Save project config to .bike4mind/config.json
|
|
1367
|
+
*/
|
|
1368
|
+
async saveProjectConfig(config, projectDir) {
|
|
1369
|
+
const targetDir = projectDir || this.projectConfigDir || process.cwd();
|
|
1370
|
+
const configPath = path2.join(targetDir, ".bike4mind", "config.json");
|
|
1371
|
+
await fs2.mkdir(path2.dirname(configPath), { recursive: true });
|
|
1372
|
+
const validated = ProjectConfigSchema.parse(config);
|
|
1373
|
+
await fs2.writeFile(configPath, JSON.stringify(validated, null, 2), "utf-8");
|
|
1374
|
+
console.log(`\u2705 Saved project config to: ${configPath}`);
|
|
1375
|
+
}
|
|
1376
|
+
/**
|
|
1377
|
+
* Save project-local config to .bike4mind/local.json
|
|
1378
|
+
*/
|
|
1379
|
+
async saveProjectLocalConfig(config, projectDir) {
|
|
1380
|
+
const targetDir = projectDir || this.projectConfigDir || process.cwd();
|
|
1381
|
+
const configPath = path2.join(targetDir, ".bike4mind", "local.json");
|
|
1382
|
+
await fs2.mkdir(path2.dirname(configPath), { recursive: true });
|
|
1383
|
+
const validated = ProjectLocalConfigSchema.parse(config);
|
|
1384
|
+
await fs2.writeFile(configPath, JSON.stringify(validated, null, 2), "utf-8");
|
|
1385
|
+
await fs2.chmod(configPath, 384);
|
|
1386
|
+
console.log(`\u2705 Saved project-local config to: ${configPath}`);
|
|
1387
|
+
}
|
|
1388
|
+
/**
|
|
1389
|
+
* Load raw project config (without merging)
|
|
1390
|
+
*/
|
|
1391
|
+
async loadRawProjectConfig() {
|
|
1392
|
+
if (!this.projectConfigDir) {
|
|
1393
|
+
return null;
|
|
1394
|
+
}
|
|
1395
|
+
return loadProjectConfig(this.projectConfigDir);
|
|
1396
|
+
}
|
|
1397
|
+
/**
|
|
1398
|
+
* Load raw project-local config (without merging)
|
|
1399
|
+
*/
|
|
1400
|
+
async loadRawProjectLocalConfig() {
|
|
1401
|
+
if (!this.projectConfigDir) {
|
|
1402
|
+
return null;
|
|
1403
|
+
}
|
|
1404
|
+
return loadProjectLocalConfig(this.projectConfigDir);
|
|
1493
1405
|
}
|
|
1494
1406
|
};
|
|
1495
1407
|
|
|
1496
1408
|
// src/storage/CommandHistoryStore.ts
|
|
1497
|
-
import { promises as
|
|
1498
|
-
import
|
|
1409
|
+
import { promises as fs3 } from "fs";
|
|
1410
|
+
import path3 from "path";
|
|
1499
1411
|
import { homedir as homedir3 } from "os";
|
|
1500
1412
|
var MAX_HISTORY_ENTRIES = 1e3;
|
|
1501
1413
|
var CommandHistoryStore = class {
|
|
1502
1414
|
constructor(historyPath) {
|
|
1503
1415
|
this.history = null;
|
|
1504
|
-
this.historyPath = historyPath ||
|
|
1416
|
+
this.historyPath = historyPath || path3.join(homedir3(), ".bike4mind", "history.jsonl");
|
|
1505
1417
|
}
|
|
1506
1418
|
/**
|
|
1507
1419
|
* Initialize history directory
|
|
1508
1420
|
*/
|
|
1509
1421
|
async init() {
|
|
1510
|
-
const dir =
|
|
1422
|
+
const dir = path3.dirname(this.historyPath);
|
|
1511
1423
|
try {
|
|
1512
|
-
await
|
|
1424
|
+
await fs3.mkdir(dir, { recursive: true });
|
|
1513
1425
|
} catch (error) {
|
|
1514
1426
|
console.error("Failed to initialize history directory:", error);
|
|
1515
1427
|
throw error;
|
|
@@ -1524,7 +1436,7 @@ var CommandHistoryStore = class {
|
|
|
1524
1436
|
return this.history;
|
|
1525
1437
|
}
|
|
1526
1438
|
try {
|
|
1527
|
-
const data = await
|
|
1439
|
+
const data = await fs3.readFile(this.historyPath, "utf-8");
|
|
1528
1440
|
const lines = data.trim().split("\n").filter((line) => line.length > 0);
|
|
1529
1441
|
const entries = lines.map((line) => {
|
|
1530
1442
|
try {
|
|
@@ -1561,7 +1473,7 @@ var CommandHistoryStore = class {
|
|
|
1561
1473
|
};
|
|
1562
1474
|
await this.init();
|
|
1563
1475
|
const line = JSON.stringify(entry) + "\n";
|
|
1564
|
-
await
|
|
1476
|
+
await fs3.appendFile(this.historyPath, line, "utf-8");
|
|
1565
1477
|
this.history = [command, ...this.history || []];
|
|
1566
1478
|
if (this.history.length > MAX_HISTORY_ENTRIES) {
|
|
1567
1479
|
await this.trim();
|
|
@@ -1584,7 +1496,7 @@ var CommandHistoryStore = class {
|
|
|
1584
1496
|
};
|
|
1585
1497
|
return JSON.stringify(entry);
|
|
1586
1498
|
}).join("\n");
|
|
1587
|
-
await
|
|
1499
|
+
await fs3.writeFile(this.historyPath, lines + "\n", "utf-8");
|
|
1588
1500
|
this.history = trimmedCommands;
|
|
1589
1501
|
}
|
|
1590
1502
|
/**
|
|
@@ -1592,7 +1504,7 @@ var CommandHistoryStore = class {
|
|
|
1592
1504
|
*/
|
|
1593
1505
|
async clear() {
|
|
1594
1506
|
try {
|
|
1595
|
-
await
|
|
1507
|
+
await fs3.unlink(this.historyPath);
|
|
1596
1508
|
} catch (error) {
|
|
1597
1509
|
if (error.code !== "ENOENT") {
|
|
1598
1510
|
throw error;
|
|
@@ -2366,7 +2278,7 @@ import { GoogleGenerativeAI } from "@google/generative-ai";
|
|
|
2366
2278
|
import OpenAI2 from "openai";
|
|
2367
2279
|
|
|
2368
2280
|
// ../../b4m-core/packages/services/dist/src/importHistoryService/index.js
|
|
2369
|
-
import
|
|
2281
|
+
import fs4, { unlinkSync } from "fs";
|
|
2370
2282
|
import yauzl from "yauzl";
|
|
2371
2283
|
import axios3 from "axios";
|
|
2372
2284
|
|
|
@@ -2973,196 +2885,190 @@ var listFabFilesBySessionSchema = z90.object({
|
|
|
2973
2885
|
sessionId: z90.string()
|
|
2974
2886
|
});
|
|
2975
2887
|
|
|
2976
|
-
// ../../b4m-core/packages/services/dist/src/fabFileService/listByQuest.js
|
|
2977
|
-
import { z as z91 } from "zod";
|
|
2978
|
-
var listFabFilesByQuestSchema = z91.object({
|
|
2979
|
-
questId: z91.string()
|
|
2980
|
-
});
|
|
2981
|
-
|
|
2982
2888
|
// ../../b4m-core/packages/services/dist/src/fabFileService/createByUrl.js
|
|
2983
|
-
import { z as
|
|
2984
|
-
var createFabFileByUrlSchema =
|
|
2985
|
-
url:
|
|
2889
|
+
import { z as z91 } from "zod";
|
|
2890
|
+
var createFabFileByUrlSchema = z91.object({
|
|
2891
|
+
url: z91.string().regex(/^(?!https?:\/\/(drive|docs)\.google\.com\/(?:file\/d\/|open\?id=|uc\?id=|document\/d\/|spreadsheets\/d\/|presentation\/d\/|forms\/d\/|drive\/folders\/)([a-zA-Z0-9_-]{10,})).+/)
|
|
2986
2892
|
});
|
|
2987
2893
|
|
|
2988
2894
|
// ../../b4m-core/packages/services/dist/src/fabFileService/search.js
|
|
2989
|
-
import { z as
|
|
2990
|
-
var searchFabFilesSchema =
|
|
2991
|
-
search:
|
|
2992
|
-
filters:
|
|
2993
|
-
tags:
|
|
2994
|
-
type:
|
|
2995
|
-
shared:
|
|
2895
|
+
import { z as z92 } from "zod";
|
|
2896
|
+
var searchFabFilesSchema = z92.object({
|
|
2897
|
+
search: z92.string().optional(),
|
|
2898
|
+
filters: z92.object({
|
|
2899
|
+
tags: z92.array(z92.string()).optional(),
|
|
2900
|
+
type: z92.enum(["text", "pdf", "url", "image", "excel", "word", "json", "csv", "markdown", "code"]).optional(),
|
|
2901
|
+
shared: z92.coerce.boolean().optional(),
|
|
2996
2902
|
// Indicates if the user is searching for shared files
|
|
2997
|
-
curated:
|
|
2903
|
+
curated: z92.coerce.boolean().optional(),
|
|
2998
2904
|
// Indicates if the user is searching for curated notebook files
|
|
2999
|
-
projectId:
|
|
3000
|
-
ids:
|
|
2905
|
+
projectId: z92.string().optional(),
|
|
2906
|
+
ids: z92.array(z92.string()).optional()
|
|
3001
2907
|
// Add support for filtering by IDs
|
|
3002
2908
|
}).optional(),
|
|
3003
|
-
pagination:
|
|
3004
|
-
page:
|
|
3005
|
-
limit:
|
|
2909
|
+
pagination: z92.object({
|
|
2910
|
+
page: z92.coerce.number(),
|
|
2911
|
+
limit: z92.coerce.number()
|
|
3006
2912
|
}).optional(),
|
|
3007
|
-
order:
|
|
3008
|
-
by:
|
|
3009
|
-
direction:
|
|
2913
|
+
order: z92.object({
|
|
2914
|
+
by: z92.enum(["createdAt", "fileName", "fileSize"]),
|
|
2915
|
+
direction: z92.enum(["asc", "desc"])
|
|
3010
2916
|
}).optional(),
|
|
3011
|
-
options:
|
|
3012
|
-
includeShared:
|
|
2917
|
+
options: z92.object({
|
|
2918
|
+
includeShared: z92.coerce.boolean().optional()
|
|
3013
2919
|
}).optional()
|
|
3014
2920
|
});
|
|
3015
2921
|
|
|
3016
2922
|
// ../../b4m-core/packages/services/dist/src/fabFileService/addFavorite.js
|
|
3017
|
-
import { z as
|
|
3018
|
-
var addFavoriteParametersSchema3 =
|
|
3019
|
-
fileId:
|
|
2923
|
+
import { z as z93 } from "zod";
|
|
2924
|
+
var addFavoriteParametersSchema3 = z93.object({
|
|
2925
|
+
fileId: z93.string()
|
|
3020
2926
|
});
|
|
3021
2927
|
|
|
3022
2928
|
// ../../b4m-core/packages/services/dist/src/fabFileService/deleteFavorite.js
|
|
3023
|
-
import { z as
|
|
3024
|
-
var deleteFavoriteParametersSchema4 =
|
|
3025
|
-
fileId:
|
|
2929
|
+
import { z as z94 } from "zod";
|
|
2930
|
+
var deleteFavoriteParametersSchema4 = z94.object({
|
|
2931
|
+
fileId: z94.string()
|
|
3026
2932
|
});
|
|
3027
2933
|
|
|
3028
2934
|
// ../../b4m-core/packages/services/dist/src/fabFileService/toggleTags.js
|
|
3029
|
-
import { z as
|
|
3030
|
-
var fabFileToggleTagsSchema =
|
|
3031
|
-
ids:
|
|
3032
|
-
tags:
|
|
2935
|
+
import { z as z95 } from "zod";
|
|
2936
|
+
var fabFileToggleTagsSchema = z95.object({
|
|
2937
|
+
ids: z95.array(z95.string()),
|
|
2938
|
+
tags: z95.array(z95.string())
|
|
3033
2939
|
});
|
|
3034
2940
|
|
|
3035
2941
|
// ../../b4m-core/packages/services/dist/src/fabFileService/edit.js
|
|
3036
|
-
import { z as
|
|
2942
|
+
import { z as z96 } from "zod";
|
|
3037
2943
|
import { diffLines } from "diff";
|
|
3038
|
-
var editFabFileSchema =
|
|
3039
|
-
id:
|
|
3040
|
-
instruction:
|
|
3041
|
-
selection:
|
|
3042
|
-
start:
|
|
3043
|
-
end:
|
|
2944
|
+
var editFabFileSchema = z96.object({
|
|
2945
|
+
id: z96.string(),
|
|
2946
|
+
instruction: z96.string(),
|
|
2947
|
+
selection: z96.object({
|
|
2948
|
+
start: z96.number(),
|
|
2949
|
+
end: z96.number()
|
|
3044
2950
|
}).optional(),
|
|
3045
|
-
preserveFormatting:
|
|
3046
|
-
applyImmediately:
|
|
2951
|
+
preserveFormatting: z96.boolean().optional().default(true),
|
|
2952
|
+
applyImmediately: z96.boolean().optional().default(false)
|
|
3047
2953
|
});
|
|
3048
2954
|
|
|
3049
2955
|
// ../../b4m-core/packages/services/dist/src/fabFileService/applyEdit.js
|
|
3050
2956
|
import mime2 from "mime-types";
|
|
3051
2957
|
import { v4 as uuidv43 } from "uuid";
|
|
3052
|
-
import { z as
|
|
3053
|
-
var applyEditSchema =
|
|
3054
|
-
id:
|
|
3055
|
-
modifiedContent:
|
|
3056
|
-
createBackup:
|
|
2958
|
+
import { z as z97 } from "zod";
|
|
2959
|
+
var applyEditSchema = z97.object({
|
|
2960
|
+
id: z97.string(),
|
|
2961
|
+
modifiedContent: z97.string(),
|
|
2962
|
+
createBackup: z97.boolean().optional().default(true)
|
|
3057
2963
|
});
|
|
3058
2964
|
|
|
3059
2965
|
// ../../b4m-core/packages/services/dist/src/friendshipService/respondToFriendRequest.js
|
|
3060
|
-
import { z as
|
|
3061
|
-
var respondToFriendRequestSchema =
|
|
3062
|
-
id:
|
|
2966
|
+
import { z as z98 } from "zod";
|
|
2967
|
+
var respondToFriendRequestSchema = z98.object({
|
|
2968
|
+
id: z98.string(),
|
|
3063
2969
|
/** The user ID of the recipient of the friend request */
|
|
3064
|
-
userId:
|
|
3065
|
-
accept:
|
|
2970
|
+
userId: z98.string(),
|
|
2971
|
+
accept: z98.boolean()
|
|
3066
2972
|
});
|
|
3067
2973
|
|
|
3068
2974
|
// ../../b4m-core/packages/services/dist/src/friendshipService/unfriend.js
|
|
3069
|
-
import { z as
|
|
3070
|
-
var unfriendSchema =
|
|
3071
|
-
friendshipId:
|
|
2975
|
+
import { z as z99 } from "zod";
|
|
2976
|
+
var unfriendSchema = z99.object({
|
|
2977
|
+
friendshipId: z99.string(),
|
|
3072
2978
|
/** The user ID of the user who wants to unfriend the other user */
|
|
3073
|
-
userId:
|
|
2979
|
+
userId: z99.string()
|
|
3074
2980
|
});
|
|
3075
2981
|
|
|
3076
2982
|
// ../../b4m-core/packages/services/dist/src/friendshipService/list.js
|
|
3077
|
-
import { z as
|
|
3078
|
-
var listFriendsSchema =
|
|
3079
|
-
userId:
|
|
2983
|
+
import { z as z100 } from "zod";
|
|
2984
|
+
var listFriendsSchema = z100.object({
|
|
2985
|
+
userId: z100.string()
|
|
3080
2986
|
});
|
|
3081
|
-
var listPendingFriendRequestsSchema =
|
|
3082
|
-
userId:
|
|
2987
|
+
var listPendingFriendRequestsSchema = z100.object({
|
|
2988
|
+
userId: z100.string()
|
|
3083
2989
|
});
|
|
3084
2990
|
|
|
3085
2991
|
// ../../b4m-core/packages/services/dist/src/adminService/loginAs.js
|
|
3086
|
-
import { z as
|
|
3087
|
-
var loginAsSchema =
|
|
3088
|
-
targetUserId:
|
|
2992
|
+
import { z as z101 } from "zod";
|
|
2993
|
+
var loginAsSchema = z101.object({
|
|
2994
|
+
targetUserId: z101.string()
|
|
3089
2995
|
});
|
|
3090
2996
|
|
|
3091
2997
|
// ../../b4m-core/packages/services/dist/src/cacheService/get.js
|
|
3092
|
-
import { z as
|
|
3093
|
-
var getParamsSchema =
|
|
3094
|
-
key:
|
|
2998
|
+
import { z as z102 } from "zod";
|
|
2999
|
+
var getParamsSchema = z102.object({
|
|
3000
|
+
key: z102.string()
|
|
3095
3001
|
});
|
|
3096
3002
|
|
|
3097
3003
|
// ../../b4m-core/packages/services/dist/src/cacheService/set.js
|
|
3098
|
-
import { z as
|
|
3099
|
-
var setParamsSchema =
|
|
3100
|
-
key:
|
|
3101
|
-
value:
|
|
3004
|
+
import { z as z103 } from "zod";
|
|
3005
|
+
var setParamsSchema = z103.object({
|
|
3006
|
+
key: z103.string(),
|
|
3007
|
+
value: z103.any(),
|
|
3102
3008
|
/**
|
|
3103
3009
|
* Time to live in milliseconds
|
|
3104
3010
|
*/
|
|
3105
|
-
ttl:
|
|
3106
|
-
recache:
|
|
3011
|
+
ttl: z103.number(),
|
|
3012
|
+
recache: z103.boolean().optional()
|
|
3107
3013
|
});
|
|
3108
3014
|
|
|
3109
3015
|
// ../../b4m-core/packages/services/dist/src/cacheService/ttl.js
|
|
3110
|
-
import { z as
|
|
3111
|
-
var ttlParamsSchema =
|
|
3112
|
-
key:
|
|
3016
|
+
import { z as z104 } from "zod";
|
|
3017
|
+
var ttlParamsSchema = z104.object({
|
|
3018
|
+
key: z104.string()
|
|
3113
3019
|
});
|
|
3114
3020
|
|
|
3115
3021
|
// ../../b4m-core/packages/services/dist/src/cacheService/weeklyReports.js
|
|
3116
|
-
import { z as
|
|
3022
|
+
import { z as z105 } from "zod";
|
|
3117
3023
|
import dayjs3 from "dayjs";
|
|
3118
|
-
var weeklyReportSchema =
|
|
3119
|
-
startDate:
|
|
3120
|
-
endDate:
|
|
3121
|
-
report:
|
|
3122
|
-
aiInsights:
|
|
3024
|
+
var weeklyReportSchema = z105.object({
|
|
3025
|
+
startDate: z105.string(),
|
|
3026
|
+
endDate: z105.string(),
|
|
3027
|
+
report: z105.string(),
|
|
3028
|
+
aiInsights: z105.string().nullable()
|
|
3123
3029
|
});
|
|
3124
3030
|
|
|
3125
3031
|
// ../../b4m-core/packages/services/dist/src/embeddingCacheService/generateCacheKey.js
|
|
3126
3032
|
import crypto2 from "crypto";
|
|
3127
3033
|
|
|
3128
3034
|
// ../../b4m-core/packages/services/dist/src/researchAgentService/create.js
|
|
3035
|
+
import { z as z106 } from "zod";
|
|
3036
|
+
var researchAgentCreateSchema = z106.object({
|
|
3037
|
+
name: z106.string().min(1),
|
|
3038
|
+
description: z106.string().min(1)
|
|
3039
|
+
});
|
|
3040
|
+
|
|
3041
|
+
// ../../b4m-core/packages/services/dist/src/researchAgentService/update.js
|
|
3129
3042
|
import { z as z107 } from "zod";
|
|
3130
|
-
var
|
|
3043
|
+
var researchAgentUpdateSchema = z107.object({
|
|
3044
|
+
id: z107.string(),
|
|
3131
3045
|
name: z107.string().min(1),
|
|
3132
3046
|
description: z107.string().min(1)
|
|
3133
3047
|
});
|
|
3134
3048
|
|
|
3135
|
-
// ../../b4m-core/packages/services/dist/src/researchAgentService/
|
|
3049
|
+
// ../../b4m-core/packages/services/dist/src/researchAgentService/remove.js
|
|
3136
3050
|
import { z as z108 } from "zod";
|
|
3137
|
-
var
|
|
3138
|
-
id: z108.string()
|
|
3139
|
-
name: z108.string().min(1),
|
|
3140
|
-
description: z108.string().min(1)
|
|
3051
|
+
var researchAgentRemoveSchema = z108.object({
|
|
3052
|
+
id: z108.string()
|
|
3141
3053
|
});
|
|
3142
3054
|
|
|
3143
|
-
// ../../b4m-core/packages/services/dist/src/researchAgentService/
|
|
3055
|
+
// ../../b4m-core/packages/services/dist/src/researchAgentService/get.js
|
|
3144
3056
|
import { z as z109 } from "zod";
|
|
3145
|
-
var
|
|
3057
|
+
var researchAgentGetSchema = z109.object({
|
|
3146
3058
|
id: z109.string()
|
|
3147
3059
|
});
|
|
3148
3060
|
|
|
3149
|
-
// ../../b4m-core/packages/services/dist/src/researchAgentService/get.js
|
|
3150
|
-
import { z as z110 } from "zod";
|
|
3151
|
-
var researchAgentGetSchema = z110.object({
|
|
3152
|
-
id: z110.string()
|
|
3153
|
-
});
|
|
3154
|
-
|
|
3155
3061
|
// ../../b4m-core/packages/services/dist/src/researchAgentService/listFiles.js
|
|
3156
|
-
import { z as
|
|
3157
|
-
var researchAgentListFilesSchema =
|
|
3062
|
+
import { z as z110 } from "zod";
|
|
3063
|
+
var researchAgentListFilesSchema = z110.object({
|
|
3158
3064
|
/**
|
|
3159
3065
|
* The ID of the research agent
|
|
3160
3066
|
*/
|
|
3161
|
-
id:
|
|
3067
|
+
id: z110.string()
|
|
3162
3068
|
});
|
|
3163
3069
|
|
|
3164
3070
|
// ../../b4m-core/packages/services/dist/src/researchTaskService/process.js
|
|
3165
|
-
import { z as
|
|
3071
|
+
import { z as z111 } from "zod";
|
|
3166
3072
|
|
|
3167
3073
|
// ../../b4m-core/packages/services/dist/src/lib/turndown.js
|
|
3168
3074
|
import turndown from "turndown";
|
|
@@ -3553,316 +3459,316 @@ var deepResearchTool = {
|
|
|
3553
3459
|
};
|
|
3554
3460
|
|
|
3555
3461
|
// ../../b4m-core/packages/services/dist/src/researchTaskService/process.js
|
|
3556
|
-
var ResearchTaskProcessSchema =
|
|
3557
|
-
id:
|
|
3462
|
+
var ResearchTaskProcessSchema = z111.object({
|
|
3463
|
+
id: z111.string()
|
|
3558
3464
|
});
|
|
3559
3465
|
|
|
3560
3466
|
// ../../b4m-core/packages/services/dist/src/researchTaskService/create.js
|
|
3561
|
-
import { z as
|
|
3562
|
-
var researchTaskCreateSchema =
|
|
3563
|
-
researchAgentId:
|
|
3564
|
-
title:
|
|
3565
|
-
description:
|
|
3566
|
-
prompt:
|
|
3567
|
-
type:
|
|
3568
|
-
executionType:
|
|
3569
|
-
fileTagId:
|
|
3570
|
-
autoGeneratedTag:
|
|
3571
|
-
name:
|
|
3572
|
-
icon:
|
|
3573
|
-
color:
|
|
3467
|
+
import { z as z112 } from "zod";
|
|
3468
|
+
var researchTaskCreateSchema = z112.object({
|
|
3469
|
+
researchAgentId: z112.string(),
|
|
3470
|
+
title: z112.string().max(100),
|
|
3471
|
+
description: z112.string().max(500),
|
|
3472
|
+
prompt: z112.string().max(500).optional(),
|
|
3473
|
+
type: z112.nativeEnum(ResearchTaskType),
|
|
3474
|
+
executionType: z112.nativeEnum(ResearchTaskExecutionType).default(ResearchTaskExecutionType.ON_DEMAND),
|
|
3475
|
+
fileTagId: z112.string().optional(),
|
|
3476
|
+
autoGeneratedTag: z112.object({
|
|
3477
|
+
name: z112.string(),
|
|
3478
|
+
icon: z112.string(),
|
|
3479
|
+
color: z112.string()
|
|
3574
3480
|
}).optional()
|
|
3575
3481
|
});
|
|
3576
3482
|
var researchTaskScrapeCreateSchema = researchTaskCreateSchema.extend({
|
|
3577
|
-
urls:
|
|
3578
|
-
canDiscoverLinks:
|
|
3483
|
+
urls: z112.array(z112.string().url()).min(1),
|
|
3484
|
+
canDiscoverLinks: z112.boolean()
|
|
3579
3485
|
});
|
|
3580
3486
|
var researchTaskPeriodicCreateSchema = researchTaskCreateSchema.extend({
|
|
3581
|
-
executionPeriodicStartAt:
|
|
3582
|
-
executionPeriodicEndAt:
|
|
3583
|
-
executionPeriodicFrequency:
|
|
3487
|
+
executionPeriodicStartAt: z112.coerce.date(),
|
|
3488
|
+
executionPeriodicEndAt: z112.coerce.date(),
|
|
3489
|
+
executionPeriodicFrequency: z112.nativeEnum(ResearchTaskPeriodicFrequencyType)
|
|
3584
3490
|
});
|
|
3585
3491
|
var researchTaskScheduledCreateSchema = researchTaskCreateSchema.extend({
|
|
3586
|
-
executionScheduledAt:
|
|
3492
|
+
executionScheduledAt: z112.coerce.date()
|
|
3587
3493
|
});
|
|
3588
3494
|
var researchTaskDeepResearchCreateSchema = researchTaskCreateSchema.extend({
|
|
3589
|
-
maxDepth:
|
|
3495
|
+
maxDepth: z112.number().min(1).max(10).optional()
|
|
3590
3496
|
});
|
|
3591
3497
|
|
|
3592
3498
|
// ../../b4m-core/packages/services/dist/src/researchTaskService/search.js
|
|
3593
|
-
import { z as
|
|
3594
|
-
var searchResearchTasksSchema =
|
|
3595
|
-
search:
|
|
3499
|
+
import { z as z113 } from "zod";
|
|
3500
|
+
var searchResearchTasksSchema = z113.object({
|
|
3501
|
+
search: z113.string().optional(),
|
|
3596
3502
|
// ADD FILTERS SCHEMA HERE
|
|
3597
3503
|
// filters: z
|
|
3598
3504
|
// .object({
|
|
3599
3505
|
// userId: z.string().optional(),
|
|
3600
3506
|
// })
|
|
3601
3507
|
// .optional(),
|
|
3602
|
-
pagination:
|
|
3603
|
-
page:
|
|
3604
|
-
limit:
|
|
3508
|
+
pagination: z113.object({
|
|
3509
|
+
page: z113.coerce.number().optional(),
|
|
3510
|
+
limit: z113.coerce.number().optional()
|
|
3605
3511
|
}).optional(),
|
|
3606
|
-
orderBy:
|
|
3607
|
-
by:
|
|
3608
|
-
direction:
|
|
3512
|
+
orderBy: z113.object({
|
|
3513
|
+
by: z113.enum(["createdAt", "updatedAt"]).optional(),
|
|
3514
|
+
direction: z113.enum(["asc", "desc"]).optional()
|
|
3609
3515
|
}).optional()
|
|
3610
3516
|
});
|
|
3611
3517
|
|
|
3612
3518
|
// ../../b4m-core/packages/services/dist/src/researchTaskService/get.js
|
|
3613
|
-
import { z as
|
|
3614
|
-
var getResearchTaskSchema =
|
|
3615
|
-
id:
|
|
3519
|
+
import { z as z114 } from "zod";
|
|
3520
|
+
var getResearchTaskSchema = z114.object({
|
|
3521
|
+
id: z114.string().min(1)
|
|
3616
3522
|
});
|
|
3617
3523
|
|
|
3618
3524
|
// ../../b4m-core/packages/services/dist/src/researchTaskService/update.js
|
|
3619
|
-
import { z as
|
|
3620
|
-
var updateResearchTaskSchema =
|
|
3621
|
-
id:
|
|
3622
|
-
title:
|
|
3623
|
-
description:
|
|
3624
|
-
type:
|
|
3525
|
+
import { z as z115 } from "zod";
|
|
3526
|
+
var updateResearchTaskSchema = z115.object({
|
|
3527
|
+
id: z115.string(),
|
|
3528
|
+
title: z115.string(),
|
|
3529
|
+
description: z115.string(),
|
|
3530
|
+
type: z115.nativeEnum(ResearchTaskType)
|
|
3625
3531
|
});
|
|
3626
3532
|
var researchTaskScrapeUpdateSchema = updateResearchTaskSchema.extend({
|
|
3627
|
-
urls:
|
|
3628
|
-
canDiscoverLinks:
|
|
3533
|
+
urls: z115.array(z115.string().url()).min(1),
|
|
3534
|
+
canDiscoverLinks: z115.boolean()
|
|
3629
3535
|
});
|
|
3630
3536
|
|
|
3631
3537
|
// ../../b4m-core/packages/services/dist/src/researchTaskService/listByAgentId.js
|
|
3632
|
-
import { z as
|
|
3633
|
-
var listByAgentIdSchema =
|
|
3634
|
-
researchAgentId:
|
|
3538
|
+
import { z as z116 } from "zod";
|
|
3539
|
+
var listByAgentIdSchema = z116.object({
|
|
3540
|
+
researchAgentId: z116.string()
|
|
3635
3541
|
});
|
|
3636
3542
|
|
|
3637
3543
|
// ../../b4m-core/packages/services/dist/src/researchTaskService/remove.js
|
|
3638
|
-
import { z as
|
|
3639
|
-
var researchTaskRemoveSchema =
|
|
3640
|
-
id:
|
|
3544
|
+
import { z as z117 } from "zod";
|
|
3545
|
+
var researchTaskRemoveSchema = z117.object({
|
|
3546
|
+
id: z117.string().min(1)
|
|
3641
3547
|
});
|
|
3642
3548
|
|
|
3643
3549
|
// ../../b4m-core/packages/services/dist/src/researchTaskService/retry.js
|
|
3644
|
-
import { z as
|
|
3645
|
-
var researchTaskRetrySchema =
|
|
3646
|
-
id:
|
|
3647
|
-
userId:
|
|
3550
|
+
import { z as z118 } from "zod";
|
|
3551
|
+
var researchTaskRetrySchema = z118.object({
|
|
3552
|
+
id: z118.string(),
|
|
3553
|
+
userId: z118.string()
|
|
3648
3554
|
});
|
|
3649
3555
|
|
|
3650
3556
|
// ../../b4m-core/packages/services/dist/src/researchTaskService/processDiscoveredLinks.js
|
|
3651
3557
|
import axios4 from "axios";
|
|
3652
|
-
import { z as
|
|
3558
|
+
import { z as z119 } from "zod";
|
|
3653
3559
|
import plimit from "p-limit";
|
|
3654
3560
|
import pLimit2 from "p-limit";
|
|
3655
|
-
var researchTaskProcessDiscoveredLinksSchema =
|
|
3656
|
-
id:
|
|
3561
|
+
var researchTaskProcessDiscoveredLinksSchema = z119.object({
|
|
3562
|
+
id: z119.string()
|
|
3657
3563
|
});
|
|
3658
3564
|
|
|
3659
3565
|
// ../../b4m-core/packages/services/dist/src/researchTaskService/downloadRelevantLinks.js
|
|
3660
|
-
import { z as
|
|
3566
|
+
import { z as z120 } from "zod";
|
|
3661
3567
|
import plimit2 from "p-limit";
|
|
3662
3568
|
import axios5 from "axios";
|
|
3663
3569
|
import { fileTypeFromBuffer } from "file-type";
|
|
3664
|
-
var researchTaskDownloadRelevantLinksSchema =
|
|
3665
|
-
id:
|
|
3570
|
+
var researchTaskDownloadRelevantLinksSchema = z120.object({
|
|
3571
|
+
id: z120.string()
|
|
3666
3572
|
});
|
|
3667
3573
|
|
|
3668
3574
|
// ../../b4m-core/packages/services/dist/src/researchData/remove.js
|
|
3669
|
-
import { z as
|
|
3670
|
-
var researchDataRemoveSchema =
|
|
3671
|
-
id:
|
|
3672
|
-
researchAgentId:
|
|
3575
|
+
import { z as z121 } from "zod";
|
|
3576
|
+
var researchDataRemoveSchema = z121.object({
|
|
3577
|
+
id: z121.string(),
|
|
3578
|
+
researchAgentId: z121.string()
|
|
3673
3579
|
});
|
|
3674
3580
|
|
|
3675
3581
|
// ../../b4m-core/packages/services/dist/src/taskSchedulerService/create.js
|
|
3676
|
-
import { z as
|
|
3677
|
-
var researchTaskPayload =
|
|
3678
|
-
id:
|
|
3679
|
-
userId:
|
|
3582
|
+
import { z as z122 } from "zod";
|
|
3583
|
+
var researchTaskPayload = z122.object({
|
|
3584
|
+
id: z122.string(),
|
|
3585
|
+
userId: z122.string()
|
|
3680
3586
|
});
|
|
3681
|
-
var customTaskPayload =
|
|
3682
|
-
test:
|
|
3587
|
+
var customTaskPayload = z122.object({
|
|
3588
|
+
test: z122.string()
|
|
3683
3589
|
});
|
|
3684
|
-
var taskSchedulerCreate =
|
|
3685
|
-
|
|
3686
|
-
handler:
|
|
3590
|
+
var taskSchedulerCreate = z122.discriminatedUnion("handler", [
|
|
3591
|
+
z122.object({
|
|
3592
|
+
handler: z122.literal(TaskScheduleHandler.RESEARCH_TASK_PROCESS),
|
|
3687
3593
|
payload: researchTaskPayload,
|
|
3688
|
-
processDate:
|
|
3594
|
+
processDate: z122.date()
|
|
3689
3595
|
}),
|
|
3690
|
-
|
|
3691
|
-
handler:
|
|
3596
|
+
z122.object({
|
|
3597
|
+
handler: z122.literal(TaskScheduleHandler.CUSTOM_TASK_PROCESS),
|
|
3692
3598
|
payload: customTaskPayload,
|
|
3693
|
-
processDate:
|
|
3599
|
+
processDate: z122.date()
|
|
3694
3600
|
})
|
|
3695
3601
|
]);
|
|
3696
3602
|
|
|
3697
3603
|
// ../../b4m-core/packages/services/dist/src/tagService/createFileTag.js
|
|
3604
|
+
import { z as z123 } from "zod";
|
|
3605
|
+
var tagCreateFileTagSchema = z123.object({
|
|
3606
|
+
name: z123.string(),
|
|
3607
|
+
icon: z123.string().optional(),
|
|
3608
|
+
color: z123.string().optional(),
|
|
3609
|
+
description: z123.string().optional()
|
|
3610
|
+
});
|
|
3611
|
+
|
|
3612
|
+
// ../../b4m-core/packages/services/dist/src/tagService/create.js
|
|
3698
3613
|
import { z as z124 } from "zod";
|
|
3699
|
-
var
|
|
3614
|
+
var tagCreateSchema = z124.object({
|
|
3700
3615
|
name: z124.string(),
|
|
3701
3616
|
icon: z124.string().optional(),
|
|
3617
|
+
description: z124.string().optional(),
|
|
3702
3618
|
color: z124.string().optional(),
|
|
3703
|
-
|
|
3619
|
+
type: z124.nativeEnum(TagType)
|
|
3704
3620
|
});
|
|
3705
3621
|
|
|
3706
|
-
// ../../b4m-core/packages/services/dist/src/tagService/
|
|
3622
|
+
// ../../b4m-core/packages/services/dist/src/tagService/update.js
|
|
3707
3623
|
import { z as z125 } from "zod";
|
|
3708
|
-
var
|
|
3709
|
-
|
|
3624
|
+
var tagUpdateSchema = z125.object({
|
|
3625
|
+
id: z125.string(),
|
|
3626
|
+
name: z125.string().optional(),
|
|
3710
3627
|
icon: z125.string().optional(),
|
|
3711
3628
|
description: z125.string().optional(),
|
|
3712
|
-
color: z125.string().optional()
|
|
3713
|
-
type: z125.nativeEnum(TagType)
|
|
3714
|
-
});
|
|
3715
|
-
|
|
3716
|
-
// ../../b4m-core/packages/services/dist/src/tagService/update.js
|
|
3717
|
-
import { z as z126 } from "zod";
|
|
3718
|
-
var tagUpdateSchema = z126.object({
|
|
3719
|
-
id: z126.string(),
|
|
3720
|
-
name: z126.string().optional(),
|
|
3721
|
-
icon: z126.string().optional(),
|
|
3722
|
-
description: z126.string().optional(),
|
|
3723
|
-
color: z126.string().optional()
|
|
3629
|
+
color: z125.string().optional()
|
|
3724
3630
|
});
|
|
3725
3631
|
|
|
3726
3632
|
// ../../b4m-core/packages/services/dist/src/tagService/remove.js
|
|
3727
|
-
import { z as
|
|
3728
|
-
var tagRemoveSchema =
|
|
3729
|
-
id:
|
|
3633
|
+
import { z as z126 } from "zod";
|
|
3634
|
+
var tagRemoveSchema = z126.object({
|
|
3635
|
+
id: z126.string()
|
|
3730
3636
|
});
|
|
3731
3637
|
|
|
3732
3638
|
// ../../b4m-core/packages/services/dist/src/artifactService/create.js
|
|
3733
|
-
import { z as
|
|
3734
|
-
var createArtifactSchema =
|
|
3735
|
-
id:
|
|
3639
|
+
import { z as z127 } from "zod";
|
|
3640
|
+
var createArtifactSchema = z127.object({
|
|
3641
|
+
id: z127.string().optional(),
|
|
3736
3642
|
// Allow custom ID for AI-generated artifacts
|
|
3737
|
-
type:
|
|
3738
|
-
title:
|
|
3739
|
-
description:
|
|
3740
|
-
content:
|
|
3741
|
-
projectId:
|
|
3742
|
-
organizationId:
|
|
3743
|
-
visibility:
|
|
3744
|
-
tags:
|
|
3745
|
-
versionTag:
|
|
3746
|
-
sourceQuestId:
|
|
3747
|
-
sessionId:
|
|
3748
|
-
parentArtifactId:
|
|
3749
|
-
permissions:
|
|
3750
|
-
canRead:
|
|
3751
|
-
canWrite:
|
|
3752
|
-
canDelete:
|
|
3753
|
-
isPublic:
|
|
3754
|
-
inheritFromProject:
|
|
3643
|
+
type: z127.enum(["mermaid", "recharts", "python", "react", "html", "svg", "code", "quest", "file", "questmaster"]),
|
|
3644
|
+
title: z127.string().min(1).max(255),
|
|
3645
|
+
description: z127.string().max(1e3).optional(),
|
|
3646
|
+
content: z127.string().min(1),
|
|
3647
|
+
projectId: z127.string().optional(),
|
|
3648
|
+
organizationId: z127.string().optional(),
|
|
3649
|
+
visibility: z127.enum(["private", "project", "organization", "public"]).default("private"),
|
|
3650
|
+
tags: z127.array(z127.string().max(50)).max(20).default([]),
|
|
3651
|
+
versionTag: z127.string().max(100).optional(),
|
|
3652
|
+
sourceQuestId: z127.string().optional(),
|
|
3653
|
+
sessionId: z127.string().optional(),
|
|
3654
|
+
parentArtifactId: z127.string().optional(),
|
|
3655
|
+
permissions: z127.object({
|
|
3656
|
+
canRead: z127.array(z127.string()).default([]),
|
|
3657
|
+
canWrite: z127.array(z127.string()).default([]),
|
|
3658
|
+
canDelete: z127.array(z127.string()).default([]),
|
|
3659
|
+
isPublic: z127.boolean().default(false),
|
|
3660
|
+
inheritFromProject: z127.boolean().default(true)
|
|
3755
3661
|
}).optional(),
|
|
3756
|
-
metadata:
|
|
3662
|
+
metadata: z127.record(z127.unknown()).default({})
|
|
3757
3663
|
});
|
|
3758
3664
|
|
|
3759
3665
|
// ../../b4m-core/packages/services/dist/src/artifactService/get.js
|
|
3760
|
-
import { z as
|
|
3761
|
-
var getArtifactSchema =
|
|
3762
|
-
id:
|
|
3763
|
-
includeContent:
|
|
3764
|
-
includeVersions:
|
|
3765
|
-
version:
|
|
3666
|
+
import { z as z128 } from "zod";
|
|
3667
|
+
var getArtifactSchema = z128.object({
|
|
3668
|
+
id: z128.string(),
|
|
3669
|
+
includeContent: z128.boolean().default(false),
|
|
3670
|
+
includeVersions: z128.boolean().default(false),
|
|
3671
|
+
version: z128.number().optional()
|
|
3766
3672
|
});
|
|
3767
3673
|
|
|
3768
3674
|
// ../../b4m-core/packages/services/dist/src/artifactService/list.js
|
|
3769
|
-
import { z as
|
|
3770
|
-
var listArtifactsSchema =
|
|
3771
|
-
type:
|
|
3772
|
-
status:
|
|
3773
|
-
visibility:
|
|
3774
|
-
projectId:
|
|
3775
|
-
sessionId:
|
|
3776
|
-
tags:
|
|
3777
|
-
search:
|
|
3778
|
-
limit:
|
|
3779
|
-
offset:
|
|
3780
|
-
sortBy:
|
|
3781
|
-
sortOrder:
|
|
3782
|
-
includeDeleted:
|
|
3675
|
+
import { z as z129 } from "zod";
|
|
3676
|
+
var listArtifactsSchema = z129.object({
|
|
3677
|
+
type: z129.string().optional(),
|
|
3678
|
+
status: z129.enum(["draft", "review", "published", "archived"]).optional(),
|
|
3679
|
+
visibility: z129.enum(["private", "project", "organization", "public"]).optional(),
|
|
3680
|
+
projectId: z129.string().optional(),
|
|
3681
|
+
sessionId: z129.string().optional(),
|
|
3682
|
+
tags: z129.array(z129.string()).optional(),
|
|
3683
|
+
search: z129.string().optional(),
|
|
3684
|
+
limit: z129.number().min(1).max(100).default(20),
|
|
3685
|
+
offset: z129.number().min(0).default(0),
|
|
3686
|
+
sortBy: z129.enum(["createdAt", "updatedAt", "title", "type"]).default("updatedAt"),
|
|
3687
|
+
sortOrder: z129.enum(["asc", "desc"]).default("desc"),
|
|
3688
|
+
includeDeleted: z129.boolean().default(false)
|
|
3783
3689
|
});
|
|
3784
3690
|
|
|
3785
3691
|
// ../../b4m-core/packages/services/dist/src/artifactService/update.js
|
|
3786
|
-
import { z as
|
|
3787
|
-
var updateArtifactSchema =
|
|
3788
|
-
id:
|
|
3789
|
-
title:
|
|
3790
|
-
description:
|
|
3791
|
-
content:
|
|
3792
|
-
visibility:
|
|
3793
|
-
status:
|
|
3794
|
-
tags:
|
|
3795
|
-
versionTag:
|
|
3796
|
-
permissions:
|
|
3797
|
-
canRead:
|
|
3798
|
-
canWrite:
|
|
3799
|
-
canDelete:
|
|
3800
|
-
isPublic:
|
|
3801
|
-
inheritFromProject:
|
|
3692
|
+
import { z as z130 } from "zod";
|
|
3693
|
+
var updateArtifactSchema = z130.object({
|
|
3694
|
+
id: z130.string(),
|
|
3695
|
+
title: z130.string().min(1).max(255).optional(),
|
|
3696
|
+
description: z130.string().max(1e3).optional(),
|
|
3697
|
+
content: z130.string().optional(),
|
|
3698
|
+
visibility: z130.enum(["private", "project", "organization", "public"]).optional(),
|
|
3699
|
+
status: z130.enum(["draft", "review", "published", "archived"]).optional(),
|
|
3700
|
+
tags: z130.array(z130.string().max(50)).max(20).optional(),
|
|
3701
|
+
versionTag: z130.string().max(100).optional(),
|
|
3702
|
+
permissions: z130.object({
|
|
3703
|
+
canRead: z130.array(z130.string()).optional(),
|
|
3704
|
+
canWrite: z130.array(z130.string()).optional(),
|
|
3705
|
+
canDelete: z130.array(z130.string()).optional(),
|
|
3706
|
+
isPublic: z130.boolean().optional(),
|
|
3707
|
+
inheritFromProject: z130.boolean().optional()
|
|
3802
3708
|
}).optional(),
|
|
3803
|
-
metadata:
|
|
3804
|
-
changes:
|
|
3805
|
-
changeDescription:
|
|
3806
|
-
createNewVersion:
|
|
3807
|
-
versionMessage:
|
|
3709
|
+
metadata: z130.record(z130.unknown()).optional(),
|
|
3710
|
+
changes: z130.array(z130.string()).optional(),
|
|
3711
|
+
changeDescription: z130.string().max(1e3).optional(),
|
|
3712
|
+
createNewVersion: z130.boolean().optional(),
|
|
3713
|
+
versionMessage: z130.string().max(500).optional()
|
|
3808
3714
|
});
|
|
3809
3715
|
|
|
3810
3716
|
// ../../b4m-core/packages/services/dist/src/artifactService/delete.js
|
|
3811
|
-
import { z as
|
|
3812
|
-
var deleteArtifactSchema =
|
|
3813
|
-
id:
|
|
3814
|
-
hardDelete:
|
|
3717
|
+
import { z as z131 } from "zod";
|
|
3718
|
+
var deleteArtifactSchema = z131.object({
|
|
3719
|
+
id: z131.string(),
|
|
3720
|
+
hardDelete: z131.boolean().default(false)
|
|
3815
3721
|
// For future implementation
|
|
3816
3722
|
});
|
|
3817
3723
|
|
|
3818
3724
|
// ../../b4m-core/packages/services/dist/src/questMasterService/create.js
|
|
3819
|
-
import { z as
|
|
3820
|
-
var questSchema =
|
|
3821
|
-
id:
|
|
3822
|
-
title:
|
|
3823
|
-
description:
|
|
3824
|
-
status:
|
|
3825
|
-
order:
|
|
3826
|
-
dependencies:
|
|
3827
|
-
estimatedTime:
|
|
3828
|
-
});
|
|
3829
|
-
var questResourceSchema =
|
|
3830
|
-
title:
|
|
3831
|
-
url:
|
|
3832
|
-
type:
|
|
3833
|
-
});
|
|
3834
|
-
var createQuestMasterSchema =
|
|
3835
|
-
title:
|
|
3836
|
-
description:
|
|
3837
|
-
goal:
|
|
3838
|
-
complexity:
|
|
3839
|
-
estimatedTotalTime:
|
|
3840
|
-
prerequisites:
|
|
3841
|
-
quests:
|
|
3842
|
-
resources:
|
|
3843
|
-
projectId:
|
|
3844
|
-
organizationId:
|
|
3845
|
-
visibility:
|
|
3846
|
-
tags:
|
|
3847
|
-
permissions:
|
|
3848
|
-
canRead:
|
|
3849
|
-
canWrite:
|
|
3850
|
-
canDelete:
|
|
3851
|
-
isPublic:
|
|
3852
|
-
inheritFromProject:
|
|
3725
|
+
import { z as z132 } from "zod";
|
|
3726
|
+
var questSchema = z132.object({
|
|
3727
|
+
id: z132.string(),
|
|
3728
|
+
title: z132.string().min(1).max(255),
|
|
3729
|
+
description: z132.string().max(1e3),
|
|
3730
|
+
status: z132.enum(["not_started", "in_progress", "completed", "blocked"]).default("not_started"),
|
|
3731
|
+
order: z132.number().min(0),
|
|
3732
|
+
dependencies: z132.array(z132.string()).default([]),
|
|
3733
|
+
estimatedTime: z132.string().optional()
|
|
3734
|
+
});
|
|
3735
|
+
var questResourceSchema = z132.object({
|
|
3736
|
+
title: z132.string().min(1).max(255),
|
|
3737
|
+
url: z132.string().url(),
|
|
3738
|
+
type: z132.enum(["documentation", "tutorial", "reference", "example"])
|
|
3739
|
+
});
|
|
3740
|
+
var createQuestMasterSchema = z132.object({
|
|
3741
|
+
title: z132.string().min(1).max(255),
|
|
3742
|
+
description: z132.string().max(1e3).optional(),
|
|
3743
|
+
goal: z132.string().min(1).max(1e3),
|
|
3744
|
+
complexity: z132.enum(["beginner", "intermediate", "advanced", "expert"]),
|
|
3745
|
+
estimatedTotalTime: z132.string().optional(),
|
|
3746
|
+
prerequisites: z132.array(z132.string().max(200)).default([]),
|
|
3747
|
+
quests: z132.array(questSchema).min(1),
|
|
3748
|
+
resources: z132.array(questResourceSchema).default([]),
|
|
3749
|
+
projectId: z132.string().optional(),
|
|
3750
|
+
organizationId: z132.string().optional(),
|
|
3751
|
+
visibility: z132.enum(["private", "project", "organization", "public"]).default("private"),
|
|
3752
|
+
tags: z132.array(z132.string().max(50)).max(20).default([]),
|
|
3753
|
+
permissions: z132.object({
|
|
3754
|
+
canRead: z132.array(z132.string()).default([]),
|
|
3755
|
+
canWrite: z132.array(z132.string()).default([]),
|
|
3756
|
+
canDelete: z132.array(z132.string()).default([]),
|
|
3757
|
+
isPublic: z132.boolean().default(false),
|
|
3758
|
+
inheritFromProject: z132.boolean().default(true)
|
|
3853
3759
|
}).optional(),
|
|
3854
|
-
sourceQuestId:
|
|
3855
|
-
sessionId:
|
|
3856
|
-
metadata:
|
|
3760
|
+
sourceQuestId: z132.string().optional(),
|
|
3761
|
+
sessionId: z132.string().optional(),
|
|
3762
|
+
metadata: z132.record(z132.unknown()).default({})
|
|
3857
3763
|
});
|
|
3858
3764
|
|
|
3859
3765
|
// ../../b4m-core/packages/services/dist/src/questMasterService/updateQuestStatus.js
|
|
3860
|
-
import { z as
|
|
3861
|
-
var updateQuestStatusSchema =
|
|
3862
|
-
artifactId:
|
|
3863
|
-
questId:
|
|
3864
|
-
status:
|
|
3865
|
-
completionNote:
|
|
3766
|
+
import { z as z133 } from "zod";
|
|
3767
|
+
var updateQuestStatusSchema = z133.object({
|
|
3768
|
+
artifactId: z133.string(),
|
|
3769
|
+
questId: z133.string(),
|
|
3770
|
+
status: z133.enum(["not_started", "in_progress", "completed", "blocked"]),
|
|
3771
|
+
completionNote: z133.string().max(500).optional()
|
|
3866
3772
|
});
|
|
3867
3773
|
|
|
3868
3774
|
// ../../b4m-core/packages/services/dist/src/dataLakeService/opensearchClient.js
|
|
@@ -3882,63 +3788,63 @@ import { v4 as uuidv44 } from "uuid";
|
|
|
3882
3788
|
import { randomUUID as randomUUID5 } from "crypto";
|
|
3883
3789
|
|
|
3884
3790
|
// ../../b4m-core/packages/services/dist/src/emailIngestionService/types.js
|
|
3885
|
-
import { z as
|
|
3886
|
-
var processIngestedEmailOptionsSchema =
|
|
3887
|
-
platformDomain:
|
|
3888
|
-
isNewsletter:
|
|
3791
|
+
import { z as z134 } from "zod";
|
|
3792
|
+
var processIngestedEmailOptionsSchema = z134.object({
|
|
3793
|
+
platformDomain: z134.string().optional(),
|
|
3794
|
+
isNewsletter: z134.boolean().optional()
|
|
3889
3795
|
}).optional();
|
|
3890
|
-
var emailAttachmentSchema =
|
|
3891
|
-
filename:
|
|
3892
|
-
contentType:
|
|
3893
|
-
contentDisposition:
|
|
3894
|
-
size:
|
|
3895
|
-
content:
|
|
3896
|
-
related:
|
|
3897
|
-
});
|
|
3898
|
-
var parsedEmailObjectSchema =
|
|
3899
|
-
messageId:
|
|
3900
|
-
inReplyTo:
|
|
3901
|
-
references:
|
|
3902
|
-
from:
|
|
3796
|
+
var emailAttachmentSchema = z134.object({
|
|
3797
|
+
filename: z134.string().optional(),
|
|
3798
|
+
contentType: z134.string().optional(),
|
|
3799
|
+
contentDisposition: z134.string().optional(),
|
|
3800
|
+
size: z134.number().min(0),
|
|
3801
|
+
content: z134.instanceof(Buffer),
|
|
3802
|
+
related: z134.boolean().optional()
|
|
3803
|
+
});
|
|
3804
|
+
var parsedEmailObjectSchema = z134.object({
|
|
3805
|
+
messageId: z134.string().optional(),
|
|
3806
|
+
inReplyTo: z134.string().optional(),
|
|
3807
|
+
references: z134.union([z134.string(), z134.array(z134.string())]).optional(),
|
|
3808
|
+
from: z134.any().optional(),
|
|
3903
3809
|
// Complex email address object
|
|
3904
|
-
to:
|
|
3905
|
-
cc:
|
|
3906
|
-
bcc:
|
|
3907
|
-
subject:
|
|
3908
|
-
date:
|
|
3909
|
-
text:
|
|
3910
|
-
html:
|
|
3911
|
-
attachments:
|
|
3912
|
-
});
|
|
3913
|
-
var processIngestedEmailSchema =
|
|
3810
|
+
to: z134.any().optional(),
|
|
3811
|
+
cc: z134.any().optional(),
|
|
3812
|
+
bcc: z134.any().optional(),
|
|
3813
|
+
subject: z134.string().optional(),
|
|
3814
|
+
date: z134.date().optional(),
|
|
3815
|
+
text: z134.string().optional(),
|
|
3816
|
+
html: z134.string().optional(),
|
|
3817
|
+
attachments: z134.array(emailAttachmentSchema).optional()
|
|
3818
|
+
});
|
|
3819
|
+
var processIngestedEmailSchema = z134.object({
|
|
3914
3820
|
parsedEmail: parsedEmailObjectSchema,
|
|
3915
|
-
rawEmailS3Key:
|
|
3821
|
+
rawEmailS3Key: z134.string().min(1, "rawEmailS3Key cannot be empty"),
|
|
3916
3822
|
options: processIngestedEmailOptionsSchema
|
|
3917
3823
|
});
|
|
3918
3824
|
|
|
3919
3825
|
// ../../b4m-core/packages/services/dist/src/emailAnalysisService/types.js
|
|
3920
|
-
import { z as
|
|
3921
|
-
var llmAnalysisResponseSchema =
|
|
3922
|
-
summary:
|
|
3923
|
-
entities:
|
|
3924
|
-
companies:
|
|
3925
|
-
people:
|
|
3926
|
-
products:
|
|
3927
|
-
technologies:
|
|
3826
|
+
import { z as z135 } from "zod";
|
|
3827
|
+
var llmAnalysisResponseSchema = z135.object({
|
|
3828
|
+
summary: z135.string().min(1, "Summary cannot be empty"),
|
|
3829
|
+
entities: z135.object({
|
|
3830
|
+
companies: z135.array(z135.string()).default([]),
|
|
3831
|
+
people: z135.array(z135.string()).default([]),
|
|
3832
|
+
products: z135.array(z135.string()).default([]),
|
|
3833
|
+
technologies: z135.array(z135.string()).default([])
|
|
3928
3834
|
}),
|
|
3929
|
-
sentiment:
|
|
3930
|
-
actionItems:
|
|
3931
|
-
description:
|
|
3932
|
-
deadline:
|
|
3835
|
+
sentiment: z135.enum(["positive", "neutral", "negative", "urgent"]),
|
|
3836
|
+
actionItems: z135.array(z135.object({
|
|
3837
|
+
description: z135.string(),
|
|
3838
|
+
deadline: z135.string().optional()
|
|
3933
3839
|
// ISO date string from LLM
|
|
3934
3840
|
})).default([]),
|
|
3935
|
-
privacyRecommendation:
|
|
3936
|
-
embargoDetected:
|
|
3937
|
-
suggestedTags:
|
|
3841
|
+
privacyRecommendation: z135.enum(["public", "team", "private"]),
|
|
3842
|
+
embargoDetected: z135.boolean().default(false),
|
|
3843
|
+
suggestedTags: z135.array(z135.string()).default([])
|
|
3938
3844
|
});
|
|
3939
3845
|
|
|
3940
3846
|
// ../../b4m-core/packages/services/dist/src/llm/ChatCompletion.js
|
|
3941
|
-
import { z as
|
|
3847
|
+
import { z as z137 } from "zod";
|
|
3942
3848
|
|
|
3943
3849
|
// ../../b4m-core/packages/services/dist/src/llm/ChatCompletionInvoke.js
|
|
3944
3850
|
import { fromZodError } from "zod-validation-error";
|
|
@@ -4052,8 +3958,8 @@ async function processAndStoreImages(images, context) {
|
|
|
4052
3958
|
const buffer = await downloadImage(image);
|
|
4053
3959
|
const fileType = await fileTypeFromBuffer2(buffer);
|
|
4054
3960
|
const filename = `${uuidv45()}.${fileType?.ext}`;
|
|
4055
|
-
const
|
|
4056
|
-
return
|
|
3961
|
+
const path11 = await context.imageGenerateStorage.upload(buffer, filename, {});
|
|
3962
|
+
return path11;
|
|
4057
3963
|
}));
|
|
4058
3964
|
}
|
|
4059
3965
|
async function updateQuestAndReturnMarkdown(storedImageUrls, context) {
|
|
@@ -4998,17 +4904,17 @@ var rechartsTool = {
|
|
|
4998
4904
|
};
|
|
4999
4905
|
|
|
5000
4906
|
// ../../b4m-core/packages/services/dist/src/llm/tools/implementation/editFile/index.js
|
|
5001
|
-
import { z as
|
|
4907
|
+
import { z as z136 } from "zod";
|
|
5002
4908
|
import { diffLines as diffLines2 } from "diff";
|
|
5003
|
-
var editFileSchema =
|
|
5004
|
-
fileId:
|
|
5005
|
-
instruction:
|
|
5006
|
-
selection:
|
|
5007
|
-
start:
|
|
5008
|
-
end:
|
|
4909
|
+
var editFileSchema = z136.object({
|
|
4910
|
+
fileId: z136.string().describe("The ID of the file to edit"),
|
|
4911
|
+
instruction: z136.string().describe("Natural language instruction describing the changes to make"),
|
|
4912
|
+
selection: z136.object({
|
|
4913
|
+
start: z136.number().describe("Starting character position of the selection"),
|
|
4914
|
+
end: z136.number().describe("Ending character position of the selection")
|
|
5009
4915
|
}).optional().describe("Optional selection range to edit within the file"),
|
|
5010
|
-
preserveFormatting:
|
|
5011
|
-
returnDiff:
|
|
4916
|
+
preserveFormatting: z136.boolean().optional().default(true).describe("Whether to preserve the original formatting style"),
|
|
4917
|
+
returnDiff: z136.boolean().optional().default(true).describe("Whether to return a diff of the changes")
|
|
5012
4918
|
});
|
|
5013
4919
|
function generateSimpleDiff(original, modified) {
|
|
5014
4920
|
const differences = diffLines2(original, modified);
|
|
@@ -5237,8 +5143,8 @@ async function processAndStoreImage(imageUrl, context) {
|
|
|
5237
5143
|
const buffer = await downloadImage2(imageUrl);
|
|
5238
5144
|
const fileType = await fileTypeFromBuffer3(buffer);
|
|
5239
5145
|
const filename = `${uuidv46()}.${fileType?.ext}`;
|
|
5240
|
-
const
|
|
5241
|
-
return
|
|
5146
|
+
const path11 = await context.imageGenerateStorage.upload(buffer, filename, {});
|
|
5147
|
+
return path11;
|
|
5242
5148
|
}
|
|
5243
5149
|
async function updateQuestAndReturnMarkdown2(storedImagePath, context) {
|
|
5244
5150
|
await context.onFinish?.("edit_image", storedImagePath);
|
|
@@ -6767,8 +6673,8 @@ var getHeliocentricCoords = (planet, T) => {
|
|
|
6767
6673
|
const sinNode = Math.sin(longNode);
|
|
6768
6674
|
const x = r * (cosNode * cosOmega - sinNode * sinOmega * cosI);
|
|
6769
6675
|
const y = r * (sinNode * cosOmega + cosNode * sinOmega * cosI);
|
|
6770
|
-
const
|
|
6771
|
-
return { x, y, z:
|
|
6676
|
+
const z143 = r * sinOmega * sinI;
|
|
6677
|
+
return { x, y, z: z143, r };
|
|
6772
6678
|
};
|
|
6773
6679
|
var getGeocentricEcliptic = (planet, earth) => {
|
|
6774
6680
|
const dx = planet.x - earth.x;
|
|
@@ -7075,33 +6981,33 @@ var planetVisibilityTool = {
|
|
|
7075
6981
|
};
|
|
7076
6982
|
|
|
7077
6983
|
// ../../b4m-core/packages/services/dist/src/llm/tools/implementation/fileRead/index.js
|
|
7078
|
-
import { promises as
|
|
7079
|
-
import { existsSync as existsSync2, statSync
|
|
7080
|
-
import
|
|
7081
|
-
var
|
|
6984
|
+
import { promises as fs5 } from "fs";
|
|
6985
|
+
import { existsSync as existsSync2, statSync } from "fs";
|
|
6986
|
+
import path4 from "path";
|
|
6987
|
+
var MAX_FILE_SIZE = 10 * 1024 * 1024;
|
|
7082
6988
|
async function readFileContent(params) {
|
|
7083
6989
|
const { path: filePath, encoding = "utf-8", maxLines } = params;
|
|
7084
|
-
const normalizedPath =
|
|
7085
|
-
const resolvedPath =
|
|
7086
|
-
const cwd =
|
|
6990
|
+
const normalizedPath = path4.normalize(filePath);
|
|
6991
|
+
const resolvedPath = path4.resolve(process.cwd(), normalizedPath);
|
|
6992
|
+
const cwd = path4.resolve(process.cwd());
|
|
7087
6993
|
if (!resolvedPath.startsWith(cwd)) {
|
|
7088
6994
|
throw new Error(`Access denied: Cannot read files outside of current working directory`);
|
|
7089
6995
|
}
|
|
7090
6996
|
if (!existsSync2(resolvedPath)) {
|
|
7091
6997
|
throw new Error(`File not found: ${filePath}`);
|
|
7092
6998
|
}
|
|
7093
|
-
const stats =
|
|
6999
|
+
const stats = statSync(resolvedPath);
|
|
7094
7000
|
if (stats.isDirectory()) {
|
|
7095
7001
|
throw new Error(`Path is a directory, not a file: ${filePath}`);
|
|
7096
7002
|
}
|
|
7097
|
-
if (stats.size >
|
|
7098
|
-
throw new Error(`File too large: ${(stats.size / 1024 / 1024).toFixed(2)}MB (max ${
|
|
7003
|
+
if (stats.size > MAX_FILE_SIZE) {
|
|
7004
|
+
throw new Error(`File too large: ${(stats.size / 1024 / 1024).toFixed(2)}MB (max ${MAX_FILE_SIZE / 1024 / 1024}MB)`);
|
|
7099
7005
|
}
|
|
7100
7006
|
const isBinary = await checkIfBinary(resolvedPath);
|
|
7101
7007
|
if (isBinary && encoding === "utf-8") {
|
|
7102
7008
|
throw new Error(`File appears to be binary. Use encoding 'base64' to read binary files, or specify a different encoding.`);
|
|
7103
7009
|
}
|
|
7104
|
-
const content = await
|
|
7010
|
+
const content = await fs5.readFile(resolvedPath, encoding);
|
|
7105
7011
|
if (maxLines && typeof content === "string") {
|
|
7106
7012
|
const lines = content.split("\n");
|
|
7107
7013
|
if (lines.length > maxLines) {
|
|
@@ -7116,7 +7022,7 @@ ${content}`;
|
|
|
7116
7022
|
}
|
|
7117
7023
|
async function checkIfBinary(filePath) {
|
|
7118
7024
|
const buffer = Buffer.alloc(8192);
|
|
7119
|
-
const fd = await
|
|
7025
|
+
const fd = await fs5.open(filePath, "r");
|
|
7120
7026
|
try {
|
|
7121
7027
|
const { bytesRead } = await fd.read(buffer, 0, 8192, 0);
|
|
7122
7028
|
const chunk = buffer.slice(0, bytesRead);
|
|
@@ -7133,7 +7039,7 @@ var fileReadTool = {
|
|
|
7133
7039
|
context.logger.info("\u{1F4C4} FileRead: Reading file", { path: params.path });
|
|
7134
7040
|
try {
|
|
7135
7041
|
const content = await readFileContent(params);
|
|
7136
|
-
const stats =
|
|
7042
|
+
const stats = statSync(path4.resolve(process.cwd(), path4.normalize(params.path)));
|
|
7137
7043
|
context.logger.info("\u2705 FileRead: Success", {
|
|
7138
7044
|
path: params.path,
|
|
7139
7045
|
size: stats.size,
|
|
@@ -7172,25 +7078,25 @@ var fileReadTool = {
|
|
|
7172
7078
|
};
|
|
7173
7079
|
|
|
7174
7080
|
// ../../b4m-core/packages/services/dist/src/llm/tools/implementation/createFile/index.js
|
|
7175
|
-
import { promises as
|
|
7081
|
+
import { promises as fs6 } from "fs";
|
|
7176
7082
|
import { existsSync as existsSync3 } from "fs";
|
|
7177
|
-
import
|
|
7083
|
+
import path5 from "path";
|
|
7178
7084
|
async function createFile(params) {
|
|
7179
7085
|
const { path: filePath, content, createDirectories = true } = params;
|
|
7180
|
-
const normalizedPath =
|
|
7181
|
-
const resolvedPath =
|
|
7182
|
-
const cwd =
|
|
7086
|
+
const normalizedPath = path5.normalize(filePath);
|
|
7087
|
+
const resolvedPath = path5.resolve(process.cwd(), normalizedPath);
|
|
7088
|
+
const cwd = path5.resolve(process.cwd());
|
|
7183
7089
|
if (!resolvedPath.startsWith(cwd)) {
|
|
7184
7090
|
throw new Error(`Access denied: Cannot create files outside of current working directory`);
|
|
7185
7091
|
}
|
|
7186
7092
|
const fileExists = existsSync3(resolvedPath);
|
|
7187
7093
|
const action = fileExists ? "overwritten" : "created";
|
|
7188
7094
|
if (createDirectories) {
|
|
7189
|
-
const dir =
|
|
7190
|
-
await
|
|
7095
|
+
const dir = path5.dirname(resolvedPath);
|
|
7096
|
+
await fs6.mkdir(dir, { recursive: true });
|
|
7191
7097
|
}
|
|
7192
|
-
await
|
|
7193
|
-
const stats = await
|
|
7098
|
+
await fs6.writeFile(resolvedPath, content, "utf-8");
|
|
7099
|
+
const stats = await fs6.stat(resolvedPath);
|
|
7194
7100
|
const lines = content.split("\n").length;
|
|
7195
7101
|
return `File ${action} successfully: ${filePath}
|
|
7196
7102
|
Size: ${stats.size} bytes
|
|
@@ -7201,7 +7107,7 @@ var createFileTool = {
|
|
|
7201
7107
|
implementation: (context) => ({
|
|
7202
7108
|
toolFn: async (value) => {
|
|
7203
7109
|
const params = value;
|
|
7204
|
-
const fileExists = existsSync3(
|
|
7110
|
+
const fileExists = existsSync3(path5.resolve(process.cwd(), path5.normalize(params.path)));
|
|
7205
7111
|
context.logger.info(`\u{1F4DD} CreateFile: ${fileExists ? "Overwriting" : "Creating"} file`, {
|
|
7206
7112
|
path: params.path,
|
|
7207
7113
|
size: params.content.length
|
|
@@ -7242,8 +7148,8 @@ var createFileTool = {
|
|
|
7242
7148
|
|
|
7243
7149
|
// ../../b4m-core/packages/services/dist/src/llm/tools/implementation/globFiles/index.js
|
|
7244
7150
|
import { readdir } from "fs/promises";
|
|
7245
|
-
import { statSync as
|
|
7246
|
-
import
|
|
7151
|
+
import { statSync as statSync2 } from "fs";
|
|
7152
|
+
import path6 from "path";
|
|
7247
7153
|
function matchGlob(filePath, pattern) {
|
|
7248
7154
|
let regexPattern = pattern.replace(/\./g, "\\.").replace(/\*\*/g, "{{GLOBSTAR}}").replace(/\*/g, "[^/]*").replace(/\?/g, ".").replace(/\{([^}]+)\}/g, (_, options) => `(${options.split(",").join("|")})`).replace(/\[([^\]]+)\]/g, "[$1]");
|
|
7249
7155
|
regexPattern = regexPattern.replace(/\{\{GLOBSTAR\}\}\//g, "(.*/)?").replace(/\/\{\{GLOBSTAR\}\}/g, "(/.*)?").replace(/\{\{GLOBSTAR\}\}/g, ".*");
|
|
@@ -7261,8 +7167,8 @@ async function walkDir(dir, pattern, includeHidden, maxResults, basePath = "") {
|
|
|
7261
7167
|
if (!includeHidden && entry.name.startsWith(".")) {
|
|
7262
7168
|
continue;
|
|
7263
7169
|
}
|
|
7264
|
-
const relativePath = basePath ?
|
|
7265
|
-
const fullPath =
|
|
7170
|
+
const relativePath = basePath ? path6.join(basePath, entry.name) : entry.name;
|
|
7171
|
+
const fullPath = path6.join(dir, entry.name);
|
|
7266
7172
|
if (matchGlob(relativePath, pattern)) {
|
|
7267
7173
|
matches.push(relativePath);
|
|
7268
7174
|
}
|
|
@@ -7278,7 +7184,7 @@ async function walkDir(dir, pattern, includeHidden, maxResults, basePath = "") {
|
|
|
7278
7184
|
async function listFiles(params) {
|
|
7279
7185
|
const { pattern, cwd: relativeCwd, includeHidden = false, maxResults = 1e3 } = params;
|
|
7280
7186
|
const baseCwd = process.cwd();
|
|
7281
|
-
const targetCwd = relativeCwd ?
|
|
7187
|
+
const targetCwd = relativeCwd ? path6.resolve(baseCwd, path6.normalize(relativeCwd)) : baseCwd;
|
|
7282
7188
|
if (!targetCwd.startsWith(baseCwd)) {
|
|
7283
7189
|
throw new Error(`Access denied: Cannot list files outside of current working directory`);
|
|
7284
7190
|
}
|
|
@@ -7289,8 +7195,8 @@ async function listFiles(params) {
|
|
|
7289
7195
|
const filesInfo = [];
|
|
7290
7196
|
for (const match of matches) {
|
|
7291
7197
|
try {
|
|
7292
|
-
const fullPath =
|
|
7293
|
-
const stats =
|
|
7198
|
+
const fullPath = path6.join(targetCwd, match);
|
|
7199
|
+
const stats = statSync2(fullPath);
|
|
7294
7200
|
filesInfo.push({
|
|
7295
7201
|
path: match,
|
|
7296
7202
|
size: stats.size,
|
|
@@ -7371,9 +7277,9 @@ var globFilesTool = {
|
|
|
7371
7277
|
|
|
7372
7278
|
// ../../b4m-core/packages/services/dist/src/llm/tools/implementation/grepSearch/index.js
|
|
7373
7279
|
import { readdir as readdir2 } from "fs/promises";
|
|
7374
|
-
import { readFileSync
|
|
7375
|
-
import
|
|
7376
|
-
var
|
|
7280
|
+
import { readFileSync, statSync as statSync3 } from "fs";
|
|
7281
|
+
import path7 from "path";
|
|
7282
|
+
var MAX_FILE_SIZE2 = 10 * 1024 * 1024;
|
|
7377
7283
|
function matchGlob2(filePath, pattern) {
|
|
7378
7284
|
const regexPattern = pattern.replace(/\./g, "\\.").replace(/\*\*/g, "{{GLOBSTAR}}").replace(/\*/g, "[^/]*").replace(/\{\{GLOBSTAR\}\}/g, ".*").replace(/\?/g, ".").replace(/\{([^}]+)\}/g, (_, options) => `(${options.split(",").join("|")})`).replace(/\[([^\]]+)\]/g, "[$1]");
|
|
7379
7285
|
const regex = new RegExp(`^${regexPattern}$`);
|
|
@@ -7390,8 +7296,8 @@ async function walkDir2(dir, pattern, maxResults, basePath = "") {
|
|
|
7390
7296
|
if (entry.name.startsWith(".")) {
|
|
7391
7297
|
continue;
|
|
7392
7298
|
}
|
|
7393
|
-
const relativePath = basePath ?
|
|
7394
|
-
const fullPath =
|
|
7299
|
+
const relativePath = basePath ? path7.join(basePath, entry.name) : entry.name;
|
|
7300
|
+
const fullPath = path7.join(dir, entry.name);
|
|
7395
7301
|
if (matchGlob2(relativePath, pattern)) {
|
|
7396
7302
|
matches.push(relativePath);
|
|
7397
7303
|
}
|
|
@@ -7404,10 +7310,10 @@ async function walkDir2(dir, pattern, maxResults, basePath = "") {
|
|
|
7404
7310
|
}
|
|
7405
7311
|
return matches;
|
|
7406
7312
|
}
|
|
7407
|
-
async function
|
|
7313
|
+
async function searchFiles(params) {
|
|
7408
7314
|
const { pattern, filePattern = "**/*", cwd: relativeCwd, caseSensitive = false, maxResults = 100, contextLines = 0 } = params;
|
|
7409
7315
|
const baseCwd = process.cwd();
|
|
7410
|
-
const targetCwd = relativeCwd ?
|
|
7316
|
+
const targetCwd = relativeCwd ? path7.resolve(baseCwd, path7.normalize(relativeCwd)) : baseCwd;
|
|
7411
7317
|
if (!targetCwd.startsWith(baseCwd)) {
|
|
7412
7318
|
throw new Error(`Access denied: Cannot search files outside of current working directory`);
|
|
7413
7319
|
}
|
|
@@ -7421,13 +7327,13 @@ async function searchFiles2(params) {
|
|
|
7421
7327
|
const filesToSearch = await walkDir2(targetCwd, filePattern, 1e4);
|
|
7422
7328
|
const filteredFiles = [];
|
|
7423
7329
|
for (const match of filesToSearch) {
|
|
7424
|
-
const fullPath =
|
|
7330
|
+
const fullPath = path7.join(targetCwd, match);
|
|
7425
7331
|
try {
|
|
7426
|
-
const stats =
|
|
7427
|
-
if (stats.isDirectory() || stats.size >
|
|
7332
|
+
const stats = statSync3(fullPath);
|
|
7333
|
+
if (stats.isDirectory() || stats.size > MAX_FILE_SIZE2) {
|
|
7428
7334
|
continue;
|
|
7429
7335
|
}
|
|
7430
|
-
if (
|
|
7336
|
+
if (isBinaryFile(fullPath)) {
|
|
7431
7337
|
continue;
|
|
7432
7338
|
}
|
|
7433
7339
|
filteredFiles.push(match);
|
|
@@ -7445,9 +7351,9 @@ async function searchFiles2(params) {
|
|
|
7445
7351
|
break;
|
|
7446
7352
|
}
|
|
7447
7353
|
filesSearched++;
|
|
7448
|
-
const fullPath =
|
|
7354
|
+
const fullPath = path7.join(targetCwd, file);
|
|
7449
7355
|
try {
|
|
7450
|
-
const content =
|
|
7356
|
+
const content = readFileSync(fullPath, "utf-8");
|
|
7451
7357
|
const lines = content.split("\n");
|
|
7452
7358
|
for (let i = 0; i < lines.length; i++) {
|
|
7453
7359
|
if (matches.length >= maxResults) {
|
|
@@ -7511,7 +7417,7 @@ ${match.context.after.map((l) => ` ${l}`).join("\n")}`;
|
|
|
7511
7417
|
}).join("\n");
|
|
7512
7418
|
return `${summary}${patternInfo}${cwdInfo}${matchesList}`;
|
|
7513
7419
|
}
|
|
7514
|
-
function
|
|
7420
|
+
function isBinaryFile(filePath) {
|
|
7515
7421
|
try {
|
|
7516
7422
|
const buffer = Buffer.alloc(8192);
|
|
7517
7423
|
const fd = __require("fs").openSync(filePath, "r");
|
|
@@ -7534,7 +7440,7 @@ var grepSearchTool = {
|
|
|
7534
7440
|
cwd: params.cwd || "."
|
|
7535
7441
|
});
|
|
7536
7442
|
try {
|
|
7537
|
-
const result = await
|
|
7443
|
+
const result = await searchFiles(params);
|
|
7538
7444
|
context.logger.info("\u2705 GrepSearch: Success");
|
|
7539
7445
|
return result;
|
|
7540
7446
|
} catch (error) {
|
|
@@ -7580,31 +7486,31 @@ var grepSearchTool = {
|
|
|
7580
7486
|
};
|
|
7581
7487
|
|
|
7582
7488
|
// ../../b4m-core/packages/services/dist/src/llm/tools/implementation/deleteFile/index.js
|
|
7583
|
-
import { promises as
|
|
7584
|
-
import { existsSync as existsSync4, statSync as
|
|
7585
|
-
import
|
|
7489
|
+
import { promises as fs7 } from "fs";
|
|
7490
|
+
import { existsSync as existsSync4, statSync as statSync4 } from "fs";
|
|
7491
|
+
import path8 from "path";
|
|
7586
7492
|
async function deleteFile(params) {
|
|
7587
7493
|
const { path: filePath, recursive = false } = params;
|
|
7588
|
-
const normalizedPath =
|
|
7589
|
-
const resolvedPath =
|
|
7590
|
-
const cwd =
|
|
7494
|
+
const normalizedPath = path8.normalize(filePath);
|
|
7495
|
+
const resolvedPath = path8.resolve(process.cwd(), normalizedPath);
|
|
7496
|
+
const cwd = path8.resolve(process.cwd());
|
|
7591
7497
|
if (!resolvedPath.startsWith(cwd)) {
|
|
7592
7498
|
throw new Error(`Access denied: Cannot delete files outside of current working directory`);
|
|
7593
7499
|
}
|
|
7594
7500
|
if (!existsSync4(resolvedPath)) {
|
|
7595
7501
|
throw new Error(`File or directory not found: ${filePath}`);
|
|
7596
7502
|
}
|
|
7597
|
-
const stats =
|
|
7503
|
+
const stats = statSync4(resolvedPath);
|
|
7598
7504
|
const isDirectory = stats.isDirectory();
|
|
7599
7505
|
const size = stats.size;
|
|
7600
7506
|
if (isDirectory && !recursive) {
|
|
7601
7507
|
throw new Error(`Path is a directory: ${filePath}. Use recursive=true to delete directories and their contents.`);
|
|
7602
7508
|
}
|
|
7603
7509
|
if (isDirectory) {
|
|
7604
|
-
await
|
|
7510
|
+
await fs7.rm(resolvedPath, { recursive: true, force: true });
|
|
7605
7511
|
return `Directory deleted successfully: ${filePath}`;
|
|
7606
7512
|
} else {
|
|
7607
|
-
await
|
|
7513
|
+
await fs7.unlink(resolvedPath);
|
|
7608
7514
|
return `File deleted successfully: ${filePath}
|
|
7609
7515
|
Size: ${size} bytes`;
|
|
7610
7516
|
}
|
|
@@ -7614,8 +7520,8 @@ var deleteFileTool = {
|
|
|
7614
7520
|
implementation: (context) => ({
|
|
7615
7521
|
toolFn: async (value) => {
|
|
7616
7522
|
const params = value;
|
|
7617
|
-
const resolvedPath =
|
|
7618
|
-
const isDirectory = existsSync4(resolvedPath) &&
|
|
7523
|
+
const resolvedPath = path8.resolve(process.cwd(), path8.normalize(params.path));
|
|
7524
|
+
const isDirectory = existsSync4(resolvedPath) && statSync4(resolvedPath).isDirectory();
|
|
7619
7525
|
context.logger.info(`\u{1F5D1}\uFE0F DeleteFile: Deleting ${isDirectory ? "directory" : "file"}`, {
|
|
7620
7526
|
path: params.path,
|
|
7621
7527
|
recursive: params.recursive
|
|
@@ -7793,42 +7699,42 @@ var DISABLE_SERVER_THROTTLING = process.env.DISABLE_SERVER_THROTTLING === "true"
|
|
|
7793
7699
|
var questSaveMutex = new Mutex();
|
|
7794
7700
|
|
|
7795
7701
|
// ../../b4m-core/packages/services/dist/src/llm/ChatCompletion.js
|
|
7796
|
-
var QuestStartBodySchema =
|
|
7797
|
-
userId:
|
|
7798
|
-
sessionId:
|
|
7799
|
-
questId:
|
|
7800
|
-
message:
|
|
7801
|
-
messageFileIds:
|
|
7802
|
-
historyCount:
|
|
7803
|
-
fabFileIds:
|
|
7702
|
+
var QuestStartBodySchema = z137.object({
|
|
7703
|
+
userId: z137.string(),
|
|
7704
|
+
sessionId: z137.string(),
|
|
7705
|
+
questId: z137.string(),
|
|
7706
|
+
message: z137.string(),
|
|
7707
|
+
messageFileIds: z137.array(z137.string()),
|
|
7708
|
+
historyCount: z137.number(),
|
|
7709
|
+
fabFileIds: z137.array(z137.string()),
|
|
7804
7710
|
params: ChatCompletionCreateInputSchema,
|
|
7805
7711
|
dashboardParams: DashboardParamsSchema.optional(),
|
|
7806
|
-
enableQuestMaster:
|
|
7807
|
-
enableMementos:
|
|
7808
|
-
enableArtifacts:
|
|
7809
|
-
enableAgents:
|
|
7712
|
+
enableQuestMaster: z137.boolean().optional(),
|
|
7713
|
+
enableMementos: z137.boolean().optional(),
|
|
7714
|
+
enableArtifacts: z137.boolean().optional(),
|
|
7715
|
+
enableAgents: z137.boolean().optional(),
|
|
7810
7716
|
promptMeta: PromptMetaZodSchema,
|
|
7811
|
-
tools:
|
|
7812
|
-
mcpServers:
|
|
7813
|
-
projectId:
|
|
7814
|
-
organizationId:
|
|
7717
|
+
tools: z137.array(z137.union([b4mLLMTools, z137.string()])).optional(),
|
|
7718
|
+
mcpServers: z137.array(z137.string()).optional(),
|
|
7719
|
+
projectId: z137.string().optional(),
|
|
7720
|
+
organizationId: z137.string().nullable().optional(),
|
|
7815
7721
|
questMaster: QuestMasterParamsSchema.optional(),
|
|
7816
|
-
toolPromptId:
|
|
7722
|
+
toolPromptId: z137.string().optional(),
|
|
7817
7723
|
researchMode: ResearchModeParamsSchema.optional(),
|
|
7818
|
-
fallbackModel:
|
|
7819
|
-
embeddingModel:
|
|
7820
|
-
queryComplexity:
|
|
7724
|
+
fallbackModel: z137.string().optional(),
|
|
7725
|
+
embeddingModel: z137.string().optional(),
|
|
7726
|
+
queryComplexity: z137.string(),
|
|
7821
7727
|
imageConfig: GenerateImageToolCallSchema.optional(),
|
|
7822
|
-
deepResearchConfig:
|
|
7823
|
-
maxDepth:
|
|
7824
|
-
duration:
|
|
7728
|
+
deepResearchConfig: z137.object({
|
|
7729
|
+
maxDepth: z137.number().optional(),
|
|
7730
|
+
duration: z137.number().optional(),
|
|
7825
7731
|
// Note: searchers are passed via ToolContext and not through this API schema
|
|
7826
|
-
searchers:
|
|
7732
|
+
searchers: z137.array(z137.any()).optional()
|
|
7827
7733
|
}).optional(),
|
|
7828
|
-
extraContextMessages:
|
|
7829
|
-
role:
|
|
7830
|
-
content:
|
|
7831
|
-
fabFileIds:
|
|
7734
|
+
extraContextMessages: z137.array(z137.object({
|
|
7735
|
+
role: z137.enum(["user", "assistant", "system", "function", "tool"]),
|
|
7736
|
+
content: z137.union([z137.string(), z137.array(z137.any())]),
|
|
7737
|
+
fabFileIds: z137.array(z137.string()).optional()
|
|
7832
7738
|
})).optional()
|
|
7833
7739
|
});
|
|
7834
7740
|
|
|
@@ -7836,9 +7742,30 @@ var QuestStartBodySchema = z138.object({
|
|
|
7836
7742
|
import axios8 from "axios";
|
|
7837
7743
|
import { fileTypeFromBuffer as fileTypeFromBuffer4 } from "file-type";
|
|
7838
7744
|
import { v4 as uuidv47 } from "uuid";
|
|
7839
|
-
import { z as
|
|
7745
|
+
import { z as z138 } from "zod";
|
|
7840
7746
|
import { fromZodError as fromZodError2 } from "zod-validation-error";
|
|
7841
7747
|
var ImageGenerationBodySchema = OpenAIImageGenerationInput.extend({
|
|
7748
|
+
sessionId: z138.string(),
|
|
7749
|
+
questId: z138.string(),
|
|
7750
|
+
userId: z138.string(),
|
|
7751
|
+
prompt: z138.string(),
|
|
7752
|
+
safety_tolerance: z138.number().min(BFL_SAFETY_TOLERANCE.MIN).max(BFL_SAFETY_TOLERANCE.MAX).optional().default(BFL_SAFETY_TOLERANCE.DEFAULT),
|
|
7753
|
+
prompt_upsampling: z138.boolean().optional().default(false),
|
|
7754
|
+
seed: z138.number().nullable().optional(),
|
|
7755
|
+
output_format: z138.enum(["jpeg", "png"]).nullable().optional().default("png"),
|
|
7756
|
+
width: z138.number().optional(),
|
|
7757
|
+
height: z138.number().optional(),
|
|
7758
|
+
aspect_ratio: z138.string().optional(),
|
|
7759
|
+
fabFileIds: z138.array(z138.string()).optional()
|
|
7760
|
+
});
|
|
7761
|
+
|
|
7762
|
+
// ../../b4m-core/packages/services/dist/src/llm/ImageEdit.js
|
|
7763
|
+
import axios9 from "axios";
|
|
7764
|
+
import { fileTypeFromBuffer as fileTypeFromBuffer5 } from "file-type";
|
|
7765
|
+
import { v4 as uuidv48 } from "uuid";
|
|
7766
|
+
import { z as z139 } from "zod";
|
|
7767
|
+
import { fromZodError as fromZodError3 } from "zod-validation-error";
|
|
7768
|
+
var ImageEditBodySchema = OpenAIImageGenerationInput.extend({
|
|
7842
7769
|
sessionId: z139.string(),
|
|
7843
7770
|
questId: z139.string(),
|
|
7844
7771
|
userId: z139.string(),
|
|
@@ -7846,56 +7773,35 @@ var ImageGenerationBodySchema = OpenAIImageGenerationInput.extend({
|
|
|
7846
7773
|
safety_tolerance: z139.number().min(BFL_SAFETY_TOLERANCE.MIN).max(BFL_SAFETY_TOLERANCE.MAX).optional().default(BFL_SAFETY_TOLERANCE.DEFAULT),
|
|
7847
7774
|
prompt_upsampling: z139.boolean().optional().default(false),
|
|
7848
7775
|
seed: z139.number().nullable().optional(),
|
|
7849
|
-
output_format: z139.enum(["jpeg", "png"]).
|
|
7776
|
+
output_format: z139.enum(["jpeg", "png"]).optional().default("png"),
|
|
7850
7777
|
width: z139.number().optional(),
|
|
7851
7778
|
height: z139.number().optional(),
|
|
7852
7779
|
aspect_ratio: z139.string().optional(),
|
|
7853
|
-
|
|
7854
|
-
|
|
7855
|
-
|
|
7856
|
-
// ../../b4m-core/packages/services/dist/src/llm/ImageEdit.js
|
|
7857
|
-
import axios9 from "axios";
|
|
7858
|
-
import { fileTypeFromBuffer as fileTypeFromBuffer5 } from "file-type";
|
|
7859
|
-
import { v4 as uuidv48 } from "uuid";
|
|
7860
|
-
import { z as z140 } from "zod";
|
|
7861
|
-
import { fromZodError as fromZodError3 } from "zod-validation-error";
|
|
7862
|
-
var ImageEditBodySchema = OpenAIImageGenerationInput.extend({
|
|
7863
|
-
sessionId: z140.string(),
|
|
7864
|
-
questId: z140.string(),
|
|
7865
|
-
userId: z140.string(),
|
|
7866
|
-
prompt: z140.string(),
|
|
7867
|
-
safety_tolerance: z140.number().min(BFL_SAFETY_TOLERANCE.MIN).max(BFL_SAFETY_TOLERANCE.MAX).optional().default(BFL_SAFETY_TOLERANCE.DEFAULT),
|
|
7868
|
-
prompt_upsampling: z140.boolean().optional().default(false),
|
|
7869
|
-
seed: z140.number().nullable().optional(),
|
|
7870
|
-
output_format: z140.enum(["jpeg", "png"]).optional().default("png"),
|
|
7871
|
-
width: z140.number().optional(),
|
|
7872
|
-
height: z140.number().optional(),
|
|
7873
|
-
aspect_ratio: z140.string().optional(),
|
|
7874
|
-
size: z140.string().optional(),
|
|
7875
|
-
fabFileIds: z140.array(z140.string()).optional(),
|
|
7876
|
-
image: z140.string()
|
|
7780
|
+
size: z139.string().optional(),
|
|
7781
|
+
fabFileIds: z139.array(z139.string()).optional(),
|
|
7782
|
+
image: z139.string()
|
|
7877
7783
|
});
|
|
7878
7784
|
|
|
7879
7785
|
// ../../b4m-core/packages/services/dist/src/llm/refineText.js
|
|
7880
|
-
import { z as
|
|
7881
|
-
var refineTextLLMSchema =
|
|
7882
|
-
text:
|
|
7883
|
-
context:
|
|
7786
|
+
import { z as z140 } from "zod";
|
|
7787
|
+
var refineTextLLMSchema = z140.object({
|
|
7788
|
+
text: z140.string(),
|
|
7789
|
+
context: z140.string().optional()
|
|
7884
7790
|
// tone: z.enum(['formal', 'informal', 'neutral']).optional(),
|
|
7885
7791
|
// style: z.enum(['technical', 'creative', 'academic', 'business', 'narrative']).optional(),
|
|
7886
7792
|
});
|
|
7887
7793
|
|
|
7888
7794
|
// ../../b4m-core/packages/services/dist/src/llm/MementoEvaluationService.js
|
|
7889
|
-
import { z as
|
|
7890
|
-
var SingleMementoEvalSchema =
|
|
7891
|
-
importance:
|
|
7795
|
+
import { z as z141 } from "zod";
|
|
7796
|
+
var SingleMementoEvalSchema = z141.object({
|
|
7797
|
+
importance: z141.number().min(1).max(10),
|
|
7892
7798
|
// 1-10 scale for personal info importance
|
|
7893
|
-
summary:
|
|
7894
|
-
tags:
|
|
7799
|
+
summary: z141.string(),
|
|
7800
|
+
tags: z141.array(z141.string()).optional()
|
|
7895
7801
|
});
|
|
7896
|
-
var MementoEvalResponseSchema =
|
|
7897
|
-
isPersonal:
|
|
7898
|
-
mementos:
|
|
7802
|
+
var MementoEvalResponseSchema = z141.object({
|
|
7803
|
+
isPersonal: z141.boolean(),
|
|
7804
|
+
mementos: z141.array(SingleMementoEvalSchema).optional()
|
|
7899
7805
|
// Array of distinct personal information
|
|
7900
7806
|
});
|
|
7901
7807
|
|
|
@@ -7941,7 +7847,7 @@ async function generateFileDeletePreview(args) {
|
|
|
7941
7847
|
if (!existsSync5(args.path)) {
|
|
7942
7848
|
return `[File does not exist: ${args.path}]`;
|
|
7943
7849
|
}
|
|
7944
|
-
const stats = await import("fs/promises").then((
|
|
7850
|
+
const stats = await import("fs/promises").then((fs9) => fs9.stat(args.path));
|
|
7945
7851
|
return `[File will be deleted]
|
|
7946
7852
|
|
|
7947
7853
|
Path: ${args.path}
|
|
@@ -7957,21 +7863,21 @@ var NoOpStorage = class extends BaseStorage {
|
|
|
7957
7863
|
async upload(input, destination, options) {
|
|
7958
7864
|
return `/tmp/${destination}`;
|
|
7959
7865
|
}
|
|
7960
|
-
async download(
|
|
7866
|
+
async download(path11) {
|
|
7961
7867
|
throw new Error("Download not supported in CLI");
|
|
7962
7868
|
}
|
|
7963
|
-
async delete(
|
|
7869
|
+
async delete(path11) {
|
|
7964
7870
|
}
|
|
7965
|
-
async getSignedUrl(
|
|
7966
|
-
return `/tmp/${
|
|
7871
|
+
async getSignedUrl(path11) {
|
|
7872
|
+
return `/tmp/${path11}`;
|
|
7967
7873
|
}
|
|
7968
|
-
getPublicUrl(
|
|
7969
|
-
return `/tmp/${
|
|
7874
|
+
getPublicUrl(path11) {
|
|
7875
|
+
return `/tmp/${path11}`;
|
|
7970
7876
|
}
|
|
7971
|
-
async getPreview(
|
|
7972
|
-
return `/tmp/${
|
|
7877
|
+
async getPreview(path11) {
|
|
7878
|
+
return `/tmp/${path11}`;
|
|
7973
7879
|
}
|
|
7974
|
-
async getMetadata(
|
|
7880
|
+
async getMetadata(path11) {
|
|
7975
7881
|
return { size: 0, contentType: "application/octet-stream" };
|
|
7976
7882
|
}
|
|
7977
7883
|
};
|
|
@@ -7991,7 +7897,7 @@ var CliLogger = class extends Logger {
|
|
|
7991
7897
|
log(...args) {
|
|
7992
7898
|
}
|
|
7993
7899
|
};
|
|
7994
|
-
function wrapToolWithPermission(tool, permissionManager, showPermissionPrompt, agentContext) {
|
|
7900
|
+
function wrapToolWithPermission(tool, permissionManager, showPermissionPrompt, agentContext, configStore) {
|
|
7995
7901
|
const originalFn = tool.toolFn;
|
|
7996
7902
|
const toolName = tool.toolSchema.name;
|
|
7997
7903
|
return {
|
|
@@ -8035,7 +7941,25 @@ function wrapToolWithPermission(tool, permissionManager, showPermissionPrompt, a
|
|
|
8035
7941
|
throw new PermissionDeniedError(toolName, args);
|
|
8036
7942
|
}
|
|
8037
7943
|
if (response.action === "allow-always") {
|
|
8038
|
-
permissionManager.trustTool(toolName);
|
|
7944
|
+
const canTrust = permissionManager.trustTool(toolName);
|
|
7945
|
+
if (canTrust) {
|
|
7946
|
+
const projectDir = configStore.getProjectConfigDir();
|
|
7947
|
+
if (projectDir) {
|
|
7948
|
+
try {
|
|
7949
|
+
await configStore.initProjectConfig();
|
|
7950
|
+
const existingLocal = await configStore.loadRawProjectLocalConfig() || {};
|
|
7951
|
+
const updatedLocal = {
|
|
7952
|
+
...existingLocal,
|
|
7953
|
+
trustedTools: [...existingLocal.trustedTools || [], toolName]
|
|
7954
|
+
};
|
|
7955
|
+
await configStore.saveProjectLocalConfig(updatedLocal);
|
|
7956
|
+
} catch (error) {
|
|
7957
|
+
await configStore.trustTool(toolName);
|
|
7958
|
+
}
|
|
7959
|
+
} else {
|
|
7960
|
+
await configStore.trustTool(toolName);
|
|
7961
|
+
}
|
|
7962
|
+
}
|
|
8039
7963
|
}
|
|
8040
7964
|
const result = await originalFn(args);
|
|
8041
7965
|
agentContext.observationQueue.push({ toolName, result });
|
|
@@ -8043,7 +7967,7 @@ function wrapToolWithPermission(tool, permissionManager, showPermissionPrompt, a
|
|
|
8043
7967
|
}
|
|
8044
7968
|
};
|
|
8045
7969
|
}
|
|
8046
|
-
function generateCliTools(userId, llm, model, permissionManager, showPermissionPrompt, agentContext, toolApiKeys) {
|
|
7970
|
+
function generateCliTools(userId, llm, model, permissionManager, showPermissionPrompt, agentContext, configStore, toolApiKeys) {
|
|
8047
7971
|
const logger2 = new CliLogger();
|
|
8048
7972
|
const storage = new NoOpStorage();
|
|
8049
7973
|
const user = {
|
|
@@ -8127,13 +8051,15 @@ function generateCliTools(userId, llm, model, permissionManager, showPermissionP
|
|
|
8127
8051
|
toolConfig,
|
|
8128
8052
|
model
|
|
8129
8053
|
);
|
|
8130
|
-
const tools2 = Object.entries(toolsMap).filter(([key]) => toolConfig[key] !== void 0).map(
|
|
8054
|
+
const tools2 = Object.entries(toolsMap).filter(([key]) => toolConfig[key] !== void 0).map(
|
|
8055
|
+
([_, tool]) => wrapToolWithPermission(tool, permissionManager, showPermissionPrompt, agentContext, configStore)
|
|
8056
|
+
);
|
|
8131
8057
|
return { tools: tools2, agentContext };
|
|
8132
8058
|
}
|
|
8133
8059
|
|
|
8134
8060
|
// src/config/toolSafety.ts
|
|
8135
|
-
import { z as
|
|
8136
|
-
var ToolCategorySchema =
|
|
8061
|
+
import { z as z142 } from "zod";
|
|
8062
|
+
var ToolCategorySchema = z142.enum([
|
|
8137
8063
|
"auto_approve",
|
|
8138
8064
|
// Safe tools that run automatically without permission
|
|
8139
8065
|
"prompt_always",
|
|
@@ -8141,9 +8067,9 @@ var ToolCategorySchema = z143.enum([
|
|
|
8141
8067
|
"prompt_default"
|
|
8142
8068
|
// Tools that prompt by default but can be trusted
|
|
8143
8069
|
]);
|
|
8144
|
-
var ToolSafetyConfigSchema =
|
|
8145
|
-
categories:
|
|
8146
|
-
trustedTools:
|
|
8070
|
+
var ToolSafetyConfigSchema = z142.object({
|
|
8071
|
+
categories: z142.record(z142.string(), ToolCategorySchema),
|
|
8072
|
+
trustedTools: z142.array(z142.string())
|
|
8147
8073
|
});
|
|
8148
8074
|
var DEFAULT_TOOL_CATEGORIES = {
|
|
8149
8075
|
// ===== AUTO APPROVE (Safe tools) =====
|
|
@@ -8192,23 +8118,30 @@ function canTrustTool(toolName, customCategories) {
|
|
|
8192
8118
|
|
|
8193
8119
|
// src/utils/PermissionManager.ts
|
|
8194
8120
|
var PermissionManager = class {
|
|
8195
|
-
constructor(trustedTools = [], customCategories) {
|
|
8121
|
+
constructor(trustedTools = [], customCategories, deniedTools) {
|
|
8196
8122
|
this.trustedTools = /* @__PURE__ */ new Set();
|
|
8123
|
+
this.deniedTools = /* @__PURE__ */ new Set();
|
|
8197
8124
|
this.trustedTools = new Set(trustedTools);
|
|
8198
8125
|
this.customCategories = new Map(Object.entries(customCategories || {}));
|
|
8126
|
+
this.deniedTools = new Set(deniedTools || []);
|
|
8199
8127
|
}
|
|
8200
8128
|
/**
|
|
8201
8129
|
* Check if a tool needs permission before execution
|
|
8202
8130
|
*
|
|
8203
8131
|
* A tool needs permission if:
|
|
8204
|
-
* 1. It's
|
|
8205
|
-
* 2. It's not in the
|
|
8132
|
+
* 1. It's in the denied tools list (from project config), OR
|
|
8133
|
+
* 2. It's not in the auto_approve category, AND
|
|
8134
|
+
* 3. It's not in the trusted tools set
|
|
8206
8135
|
*
|
|
8207
8136
|
* Note: prompt_always tools CANNOT be trusted, so they always need permission
|
|
8137
|
+
* Note: denied tools from project config ALWAYS need permission (cannot be overridden locally)
|
|
8208
8138
|
*/
|
|
8209
8139
|
needsPermission(toolName) {
|
|
8210
8140
|
const categoryMap = Object.fromEntries(this.customCategories);
|
|
8211
8141
|
const category = getToolCategory(toolName, categoryMap);
|
|
8142
|
+
if (this.deniedTools.has(toolName)) {
|
|
8143
|
+
return true;
|
|
8144
|
+
}
|
|
8212
8145
|
if (category === "auto_approve") {
|
|
8213
8146
|
return false;
|
|
8214
8147
|
}
|
|
@@ -8219,10 +8152,13 @@ var PermissionManager = class {
|
|
|
8219
8152
|
}
|
|
8220
8153
|
/**
|
|
8221
8154
|
* Add a tool to the trusted list
|
|
8222
|
-
* Returns false if the tool cannot be trusted (prompt_always category)
|
|
8155
|
+
* Returns false if the tool cannot be trusted (prompt_always category or denied by project)
|
|
8223
8156
|
*/
|
|
8224
8157
|
trustTool(toolName) {
|
|
8225
8158
|
const categoryMap = Object.fromEntries(this.customCategories);
|
|
8159
|
+
if (this.deniedTools.has(toolName)) {
|
|
8160
|
+
return false;
|
|
8161
|
+
}
|
|
8226
8162
|
if (!canTrustTool(toolName, categoryMap)) {
|
|
8227
8163
|
return false;
|
|
8228
8164
|
}
|
|
@@ -8255,12 +8191,27 @@ var PermissionManager = class {
|
|
|
8255
8191
|
return getToolCategory(toolName, categoryMap);
|
|
8256
8192
|
}
|
|
8257
8193
|
/**
|
|
8258
|
-
* Check if a tool can be trusted (not in prompt_always category)
|
|
8194
|
+
* Check if a tool can be trusted (not in prompt_always category or denied by project)
|
|
8259
8195
|
*/
|
|
8260
8196
|
canBeTrusted(toolName) {
|
|
8261
8197
|
const categoryMap = Object.fromEntries(this.customCategories);
|
|
8198
|
+
if (this.deniedTools.has(toolName)) {
|
|
8199
|
+
return false;
|
|
8200
|
+
}
|
|
8262
8201
|
return canTrustTool(toolName, categoryMap);
|
|
8263
8202
|
}
|
|
8203
|
+
/**
|
|
8204
|
+
* Check if a tool is denied by project config
|
|
8205
|
+
*/
|
|
8206
|
+
isDenied(toolName) {
|
|
8207
|
+
return this.deniedTools.has(toolName);
|
|
8208
|
+
}
|
|
8209
|
+
/**
|
|
8210
|
+
* Get list of denied tools
|
|
8211
|
+
*/
|
|
8212
|
+
getDeniedTools() {
|
|
8213
|
+
return Array.from(this.deniedTools).sort();
|
|
8214
|
+
}
|
|
8264
8215
|
/**
|
|
8265
8216
|
* Clear all trusted tools
|
|
8266
8217
|
*/
|
|
@@ -8297,8 +8248,8 @@ function getEnvironmentName(configApiConfig) {
|
|
|
8297
8248
|
}
|
|
8298
8249
|
|
|
8299
8250
|
// src/utils/Logger.ts
|
|
8300
|
-
import
|
|
8301
|
-
import
|
|
8251
|
+
import fs8 from "fs/promises";
|
|
8252
|
+
import path9 from "path";
|
|
8302
8253
|
import os from "os";
|
|
8303
8254
|
var Logger2 = class _Logger {
|
|
8304
8255
|
constructor() {
|
|
@@ -8321,9 +8272,9 @@ var Logger2 = class _Logger {
|
|
|
8321
8272
|
*/
|
|
8322
8273
|
async initialize(sessionId) {
|
|
8323
8274
|
this.sessionId = sessionId;
|
|
8324
|
-
const debugDir =
|
|
8325
|
-
await
|
|
8326
|
-
this.logFilePath =
|
|
8275
|
+
const debugDir = path9.join(os.homedir(), ".bike4mind", "debug");
|
|
8276
|
+
await fs8.mkdir(debugDir, { recursive: true });
|
|
8277
|
+
this.logFilePath = path9.join(debugDir, `${sessionId}.txt`);
|
|
8327
8278
|
await this.writeToFile("INFO", "=== CLI SESSION START ===");
|
|
8328
8279
|
}
|
|
8329
8280
|
/**
|
|
@@ -8387,7 +8338,7 @@ var Logger2 = class _Logger {
|
|
|
8387
8338
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").substring(0, 19);
|
|
8388
8339
|
const logEntry = `[${timestamp}] [${level}] ${message}
|
|
8389
8340
|
`;
|
|
8390
|
-
await
|
|
8341
|
+
await fs8.appendFile(this.logFilePath, logEntry, "utf-8");
|
|
8391
8342
|
} catch (error) {
|
|
8392
8343
|
console.error("File logging failed:", error);
|
|
8393
8344
|
}
|
|
@@ -8533,15 +8484,15 @@ var Logger2 = class _Logger {
|
|
|
8533
8484
|
async cleanupOldLogs() {
|
|
8534
8485
|
if (!this.fileLoggingEnabled) return;
|
|
8535
8486
|
try {
|
|
8536
|
-
const debugDir =
|
|
8537
|
-
const files = await
|
|
8487
|
+
const debugDir = path9.join(os.homedir(), ".bike4mind", "debug");
|
|
8488
|
+
const files = await fs8.readdir(debugDir);
|
|
8538
8489
|
const now = Date.now();
|
|
8539
8490
|
const thirtyDaysAgo = now - 30 * 24 * 60 * 60 * 1e3;
|
|
8540
8491
|
for (const file of files) {
|
|
8541
|
-
const filePath =
|
|
8542
|
-
const stats = await
|
|
8492
|
+
const filePath = path9.join(debugDir, file);
|
|
8493
|
+
const stats = await fs8.stat(filePath);
|
|
8543
8494
|
if (stats.mtime.getTime() < thirtyDaysAgo) {
|
|
8544
|
-
await
|
|
8495
|
+
await fs8.unlink(filePath);
|
|
8545
8496
|
}
|
|
8546
8497
|
}
|
|
8547
8498
|
} catch (error) {
|
|
@@ -8554,8 +8505,8 @@ var logger = Logger2.getInstance();
|
|
|
8554
8505
|
// ../../b4m-core/packages/mcp/dist/src/client.js
|
|
8555
8506
|
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
|
|
8556
8507
|
import { Client as Client2 } from "@modelcontextprotocol/sdk/client/index.js";
|
|
8557
|
-
import
|
|
8558
|
-
import { existsSync as existsSync6, readdirSync
|
|
8508
|
+
import path10 from "path";
|
|
8509
|
+
import { existsSync as existsSync6, readdirSync } from "fs";
|
|
8559
8510
|
var MCPClient = class {
|
|
8560
8511
|
// Note: This class handles MCP server communication with repository filtering
|
|
8561
8512
|
mcp;
|
|
@@ -8580,20 +8531,20 @@ var MCPClient = class {
|
|
|
8580
8531
|
const root = process.env.INIT_CWD || process.cwd();
|
|
8581
8532
|
const candidatePaths = [
|
|
8582
8533
|
// When running from SST Lambda with node_modules structure (copyFiles)
|
|
8583
|
-
|
|
8534
|
+
path10.join(root, `node_modules/@bike4mind/mcp/dist/src/${this.serverName}/index.js`),
|
|
8584
8535
|
// When running from SST Lambda deployed environment (/var/task)
|
|
8585
|
-
|
|
8536
|
+
path10.join(root, `b4m-core/packages/mcp/dist/src/${this.serverName}/index.js`),
|
|
8586
8537
|
// When running from SST Lambda (.sst/artifacts/mcpHandler-dev), navigate to monorepo root (3 levels up)
|
|
8587
|
-
|
|
8538
|
+
path10.join(root, `../../../b4m-core/packages/mcp/dist/src/${this.serverName}/index.js`),
|
|
8588
8539
|
// When running from packages/client (Next.js app), navigate to monorepo root (2 levels up)
|
|
8589
|
-
|
|
8540
|
+
path10.join(root, `../../b4m-core/packages/mcp/dist/src/${this.serverName}/index.js`),
|
|
8590
8541
|
// Original paths (backward compatibility)
|
|
8591
|
-
|
|
8592
|
-
|
|
8542
|
+
path10.join(root, `/b4m-core/packages/mcp/dist/src/${this.serverName}/index.js`),
|
|
8543
|
+
path10.join(root, "core", "mcp", "servers", this.serverName, "dist", "index.js")
|
|
8593
8544
|
];
|
|
8594
8545
|
const serverScriptPath = candidatePaths.find((p) => existsSync6(p));
|
|
8595
8546
|
if (!serverScriptPath) {
|
|
8596
|
-
const getDirectories = (source) =>
|
|
8547
|
+
const getDirectories = (source) => readdirSync(source, { withFileTypes: true }).filter((dirent) => dirent.isDirectory()).map((dirent) => dirent.name);
|
|
8597
8548
|
console.error(`[MCP] Server script not found. Tried paths:`, candidatePaths);
|
|
8598
8549
|
console.error(`[MCP] Available directories in ${root}:`, getDirectories(root));
|
|
8599
8550
|
throw new Error(`MCP Server script path not found for ${this.serverName}. Root: ${root}, Available dirs: ${getDirectories(root).join(", ")}`);
|
|
@@ -8622,7 +8573,7 @@ var MCPClient = class {
|
|
|
8622
8573
|
}
|
|
8623
8574
|
};
|
|
8624
8575
|
await this.mcp.connect(this.transport);
|
|
8625
|
-
await new Promise((
|
|
8576
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
8626
8577
|
const toolsResult = await this.mcp.listTools();
|
|
8627
8578
|
this.tools = toolsResult.tools.map((tool) => {
|
|
8628
8579
|
return {
|
|
@@ -8805,7 +8756,7 @@ var ServerLlmBackend = class {
|
|
|
8805
8756
|
*/
|
|
8806
8757
|
async complete(model, messages, options, callback) {
|
|
8807
8758
|
logger.debug(`[ServerLlmBackend] Starting complete() with model: ${model}`);
|
|
8808
|
-
return new Promise(async (
|
|
8759
|
+
return new Promise(async (resolve, reject) => {
|
|
8809
8760
|
try {
|
|
8810
8761
|
logger.debug("[ServerLlmBackend] Making streaming request...");
|
|
8811
8762
|
const response = await this.makeStreamingRequest(model, messages, options);
|
|
@@ -8835,15 +8786,15 @@ var ServerLlmBackend = class {
|
|
|
8835
8786
|
reject(err);
|
|
8836
8787
|
}).then(() => {
|
|
8837
8788
|
logger.debug("[ServerLlmBackend] Callback completed, resolving");
|
|
8838
|
-
|
|
8789
|
+
resolve();
|
|
8839
8790
|
});
|
|
8840
8791
|
} else if (cleanedText) {
|
|
8841
8792
|
callback([cleanedText], lastUsageInfo).catch((err) => {
|
|
8842
8793
|
logger.error("[ServerLlmBackend] Callback error:", err);
|
|
8843
8794
|
reject(err);
|
|
8844
|
-
}).then(() =>
|
|
8795
|
+
}).then(() => resolve());
|
|
8845
8796
|
} else {
|
|
8846
|
-
|
|
8797
|
+
resolve();
|
|
8847
8798
|
}
|
|
8848
8799
|
return;
|
|
8849
8800
|
}
|
|
@@ -8903,7 +8854,7 @@ var ServerLlmBackend = class {
|
|
|
8903
8854
|
response.data.on("end", () => {
|
|
8904
8855
|
if (!receivedDone) {
|
|
8905
8856
|
logger.debug("[ServerLlmBackend] Stream ended without [DONE], resolving anyway");
|
|
8906
|
-
|
|
8857
|
+
resolve();
|
|
8907
8858
|
} else {
|
|
8908
8859
|
logger.debug("[ServerLlmBackend] Stream ended, [DONE] handler will resolve");
|
|
8909
8860
|
}
|
|
@@ -9170,7 +9121,7 @@ var ApiClient = class {
|
|
|
9170
9121
|
// package.json
|
|
9171
9122
|
var package_default = {
|
|
9172
9123
|
name: "@bike4mind/cli",
|
|
9173
|
-
version: "0.2.1-feat-cli-
|
|
9124
|
+
version: "0.2.1-feat-cli-project-scoped-config.16996+16c515189",
|
|
9174
9125
|
type: "module",
|
|
9175
9126
|
description: "Interactive CLI tool for Bike4Mind with ReAct agents",
|
|
9176
9127
|
license: "UNLICENSED",
|
|
@@ -9181,9 +9132,6 @@ var package_default = {
|
|
|
9181
9132
|
},
|
|
9182
9133
|
homepage: "https://github.com/bike4mind/lumina5#readme",
|
|
9183
9134
|
bugs: "https://github.com/bike4mind/lumina5/issues",
|
|
9184
|
-
publishConfig: {
|
|
9185
|
-
access: "public"
|
|
9186
|
-
},
|
|
9187
9135
|
keywords: [
|
|
9188
9136
|
"cli",
|
|
9189
9137
|
"ai",
|
|
@@ -9204,8 +9152,6 @@ var package_default = {
|
|
|
9204
9152
|
dev: "tsx src/index.tsx",
|
|
9205
9153
|
build: "tsup",
|
|
9206
9154
|
typecheck: "tsc --noEmit",
|
|
9207
|
-
test: "vitest run",
|
|
9208
|
-
"test:watch": "vitest",
|
|
9209
9155
|
start: "node dist/index.js",
|
|
9210
9156
|
prepublishOnly: "pnpm build"
|
|
9211
9157
|
},
|
|
@@ -9272,10 +9218,10 @@ var package_default = {
|
|
|
9272
9218
|
},
|
|
9273
9219
|
devDependencies: {
|
|
9274
9220
|
"@bike4mind/agents": "0.1.0",
|
|
9275
|
-
"@bike4mind/common": "2.36.1-feat-cli-
|
|
9276
|
-
"@bike4mind/mcp": "1.19.4-feat-cli-
|
|
9277
|
-
"@bike4mind/services": "2.29.1-feat-cli-
|
|
9278
|
-
"@bike4mind/utils": "2.0.3-feat-cli-
|
|
9221
|
+
"@bike4mind/common": "2.36.1-feat-cli-project-scoped-config.16996+16c515189",
|
|
9222
|
+
"@bike4mind/mcp": "1.19.4-feat-cli-project-scoped-config.16996+16c515189",
|
|
9223
|
+
"@bike4mind/services": "2.29.1-feat-cli-project-scoped-config.16996+16c515189",
|
|
9224
|
+
"@bike4mind/utils": "2.0.3-feat-cli-project-scoped-config.16996+16c515189",
|
|
9279
9225
|
"@types/diff": "^5.0.9",
|
|
9280
9226
|
"@types/jsonwebtoken": "^9.0.4",
|
|
9281
9227
|
"@types/node": "^22.9.0",
|
|
@@ -9284,10 +9230,9 @@ var package_default = {
|
|
|
9284
9230
|
"@types/yargs": "^17.0.32",
|
|
9285
9231
|
tsup: "^8.5.1",
|
|
9286
9232
|
tsx: "^4.21.0",
|
|
9287
|
-
typescript: "^5.9.3"
|
|
9288
|
-
vitest: "^3.2.4"
|
|
9233
|
+
typescript: "^5.9.3"
|
|
9289
9234
|
},
|
|
9290
|
-
gitHead: "
|
|
9235
|
+
gitHead: "16c515189f0b9a7e3ccea2c9874866dd2e8fe084"
|
|
9291
9236
|
};
|
|
9292
9237
|
|
|
9293
9238
|
// src/index.tsx
|
|
@@ -9310,7 +9255,8 @@ function CliApp() {
|
|
|
9310
9255
|
agent: null,
|
|
9311
9256
|
mcpManager: null,
|
|
9312
9257
|
permissionManager: null,
|
|
9313
|
-
permissionPrompt: null
|
|
9258
|
+
permissionPrompt: null,
|
|
9259
|
+
trustLocationSelector: null
|
|
9314
9260
|
});
|
|
9315
9261
|
const [isInitialized, setIsInitialized] = useState3(false);
|
|
9316
9262
|
const [initError, setInitError] = useState3(null);
|
|
@@ -9339,7 +9285,7 @@ function CliApp() {
|
|
|
9339
9285
|
}
|
|
9340
9286
|
await Promise.race([
|
|
9341
9287
|
Promise.all(cleanupTasks),
|
|
9342
|
-
new Promise((
|
|
9288
|
+
new Promise((resolve) => setTimeout(resolve, 500))
|
|
9343
9289
|
// 500ms timeout
|
|
9344
9290
|
]);
|
|
9345
9291
|
setTimeout(() => {
|
|
@@ -9471,11 +9417,17 @@ function CliApp() {
|
|
|
9471
9417
|
debug: () => {
|
|
9472
9418
|
}
|
|
9473
9419
|
};
|
|
9474
|
-
const permissionManager = new PermissionManager(
|
|
9420
|
+
const permissionManager = new PermissionManager(
|
|
9421
|
+
config.trustedTools || [],
|
|
9422
|
+
void 0,
|
|
9423
|
+
// customCategories (not used yet)
|
|
9424
|
+
config.tools.disabled || []
|
|
9425
|
+
// denied tools from project config
|
|
9426
|
+
);
|
|
9475
9427
|
const promptFn = (toolName, args, preview) => {
|
|
9476
|
-
return new Promise((
|
|
9428
|
+
return new Promise((resolve) => {
|
|
9477
9429
|
const canBeTrusted = permissionManager.canBeTrusted(toolName);
|
|
9478
|
-
const prompt = { toolName, args, preview, canBeTrusted, resolve
|
|
9430
|
+
const prompt = { toolName, args, preview, canBeTrusted, resolve };
|
|
9479
9431
|
setState((prev) => ({
|
|
9480
9432
|
...prev,
|
|
9481
9433
|
permissionManager,
|
|
@@ -9499,6 +9451,7 @@ function CliApp() {
|
|
|
9499
9451
|
permissionManager,
|
|
9500
9452
|
promptFn,
|
|
9501
9453
|
agentContext,
|
|
9454
|
+
state.configStore,
|
|
9502
9455
|
config.toolApiKeys
|
|
9503
9456
|
);
|
|
9504
9457
|
console.log(`\u{1F6E0}\uFE0F Loaded ${b4mTools.length} B4M tool(s)`);
|
|
@@ -9549,7 +9502,7 @@ Remember: Use context from previous messages to understand follow-up questions.`
|
|
|
9549
9502
|
llm,
|
|
9550
9503
|
model: modelInfo.id,
|
|
9551
9504
|
tools: allTools,
|
|
9552
|
-
maxIterations:
|
|
9505
|
+
maxIterations: 3,
|
|
9553
9506
|
maxTokens: config.preferences.maxTokens,
|
|
9554
9507
|
temperature: config.preferences.temperature,
|
|
9555
9508
|
systemPrompt: cliSystemPrompt
|
|
@@ -9677,6 +9630,9 @@ Tool Permissions:
|
|
|
9677
9630
|
/trust <tool-name> - Trust a tool (won't ask permission again)
|
|
9678
9631
|
/untrust <tool-name> - Remove tool from trusted list
|
|
9679
9632
|
/trusted - List all trusted tools
|
|
9633
|
+
|
|
9634
|
+
Project Configuration:
|
|
9635
|
+
/project-config - Show merged project configuration
|
|
9680
9636
|
`);
|
|
9681
9637
|
break;
|
|
9682
9638
|
case "exit":
|
|
@@ -9768,7 +9724,7 @@ Tool Permissions:
|
|
|
9768
9724
|
console.log("");
|
|
9769
9725
|
break;
|
|
9770
9726
|
}
|
|
9771
|
-
case "trust":
|
|
9727
|
+
case "trust": {
|
|
9772
9728
|
if (!state.permissionManager) {
|
|
9773
9729
|
console.log("Permission manager not initialized");
|
|
9774
9730
|
return;
|
|
@@ -9776,16 +9732,85 @@ Tool Permissions:
|
|
|
9776
9732
|
const toolToTrust = args[0];
|
|
9777
9733
|
if (!toolToTrust) {
|
|
9778
9734
|
console.log("Usage: /trust <tool-name>");
|
|
9735
|
+
console.log("");
|
|
9736
|
+
console.log("Example:");
|
|
9737
|
+
console.log(" /trust file_read - Opens interactive location selector");
|
|
9738
|
+
console.log("");
|
|
9779
9739
|
return;
|
|
9780
9740
|
}
|
|
9781
|
-
const
|
|
9782
|
-
if (
|
|
9783
|
-
|
|
9784
|
-
|
|
9785
|
-
|
|
9786
|
-
|
|
9741
|
+
const canTrust = state.permissionManager.trustTool(toolToTrust);
|
|
9742
|
+
if (!canTrust) {
|
|
9743
|
+
if (state.permissionManager.isDenied(toolToTrust)) {
|
|
9744
|
+
console.log(`\u274C Tool '${toolToTrust}' is denied by project configuration and cannot be trusted`);
|
|
9745
|
+
} else {
|
|
9746
|
+
console.log(`\u274C Tool '${toolToTrust}' cannot be trusted (it's in the 'prompt_always' category)`);
|
|
9747
|
+
}
|
|
9748
|
+
return;
|
|
9787
9749
|
}
|
|
9750
|
+
state.permissionManager.untrustTool(toolToTrust);
|
|
9751
|
+
const handleLocationSelect = async (location) => {
|
|
9752
|
+
setState((prev) => ({ ...prev, trustLocationSelector: null }));
|
|
9753
|
+
if (!location) {
|
|
9754
|
+
console.log("\u274C Trust operation cancelled");
|
|
9755
|
+
return;
|
|
9756
|
+
}
|
|
9757
|
+
const projectDir = state.configStore.getProjectConfigDir();
|
|
9758
|
+
switch (location) {
|
|
9759
|
+
case "local": {
|
|
9760
|
+
if (!projectDir) {
|
|
9761
|
+
console.log('\u274C No project found. Use "global" to save to ~/.bike4mind/config.json');
|
|
9762
|
+
return;
|
|
9763
|
+
}
|
|
9764
|
+
await state.configStore.initProjectConfig();
|
|
9765
|
+
const existingLocal = await state.configStore.loadRawProjectLocalConfig() || {};
|
|
9766
|
+
const updatedLocal = {
|
|
9767
|
+
...existingLocal,
|
|
9768
|
+
trustedTools: [...existingLocal.trustedTools || [], toolToTrust]
|
|
9769
|
+
};
|
|
9770
|
+
await state.configStore.saveProjectLocalConfig(updatedLocal);
|
|
9771
|
+
state.permissionManager?.trustTool(toolToTrust);
|
|
9772
|
+
console.log(`\u2705 Tool '${toolToTrust}' trusted for this project only`);
|
|
9773
|
+
console.log(` Saved in: ${projectDir}/.bike4mind/local.json`);
|
|
9774
|
+
break;
|
|
9775
|
+
}
|
|
9776
|
+
case "project": {
|
|
9777
|
+
if (!projectDir) {
|
|
9778
|
+
console.log('\u274C No project found. Use "global" to save to ~/.bike4mind/config.json');
|
|
9779
|
+
return;
|
|
9780
|
+
}
|
|
9781
|
+
const existingProject = await state.configStore.loadRawProjectConfig() || {};
|
|
9782
|
+
const updatedProject = {
|
|
9783
|
+
...existingProject,
|
|
9784
|
+
tools: {
|
|
9785
|
+
...existingProject.tools,
|
|
9786
|
+
enabled: [...existingProject.tools?.enabled || [], toolToTrust]
|
|
9787
|
+
}
|
|
9788
|
+
};
|
|
9789
|
+
await state.configStore.saveProjectConfig(updatedProject);
|
|
9790
|
+
state.permissionManager?.trustTool(toolToTrust);
|
|
9791
|
+
console.log(`\u2705 Tool '${toolToTrust}' trusted for entire team`);
|
|
9792
|
+
console.log(` Saved in: ${projectDir}/.bike4mind/config.json`);
|
|
9793
|
+
console.log(" \u26A0\uFE0F Remember to commit this file to share with your team!");
|
|
9794
|
+
break;
|
|
9795
|
+
}
|
|
9796
|
+
case "global": {
|
|
9797
|
+
await state.configStore.trustTool(toolToTrust);
|
|
9798
|
+
state.permissionManager?.trustTool(toolToTrust);
|
|
9799
|
+
console.log(`\u2705 Tool '${toolToTrust}' trusted globally (all projects)`);
|
|
9800
|
+
console.log(" Saved in: ~/.bike4mind/config.json");
|
|
9801
|
+
break;
|
|
9802
|
+
}
|
|
9803
|
+
}
|
|
9804
|
+
};
|
|
9805
|
+
setState((prev) => ({
|
|
9806
|
+
...prev,
|
|
9807
|
+
trustLocationSelector: {
|
|
9808
|
+
toolName: toolToTrust,
|
|
9809
|
+
resolve: handleLocationSelect
|
|
9810
|
+
}
|
|
9811
|
+
}));
|
|
9788
9812
|
break;
|
|
9813
|
+
}
|
|
9789
9814
|
case "untrust":
|
|
9790
9815
|
if (!state.permissionManager) {
|
|
9791
9816
|
console.log("Permission manager not initialized");
|
|
@@ -9834,6 +9859,50 @@ Tool Permissions:
|
|
|
9834
9859
|
console.log(`Expires: ${new Date(authTokens.expiresAt).toLocaleString()}`);
|
|
9835
9860
|
console.log("");
|
|
9836
9861
|
break;
|
|
9862
|
+
case "project-config": {
|
|
9863
|
+
const projectDir = state.configStore.getProjectConfigDir();
|
|
9864
|
+
const config = await state.configStore.get();
|
|
9865
|
+
console.log("\n\u{1F4C1} Project Configuration:\n");
|
|
9866
|
+
if (projectDir) {
|
|
9867
|
+
console.log(`Project Directory: ${projectDir}/.bike4mind/`);
|
|
9868
|
+
console.log("");
|
|
9869
|
+
const projectConfig = await state.configStore.loadRawProjectConfig();
|
|
9870
|
+
const localConfig = await state.configStore.loadRawProjectLocalConfig();
|
|
9871
|
+
if (projectConfig) {
|
|
9872
|
+
console.log("Team Config (.bike4mind/config.json):");
|
|
9873
|
+
if (projectConfig.defaultModel) {
|
|
9874
|
+
console.log(` Default Model: ${projectConfig.defaultModel}`);
|
|
9875
|
+
}
|
|
9876
|
+
if (projectConfig.tools?.denied && projectConfig.tools.denied.length > 0) {
|
|
9877
|
+
console.log(` Denied Tools: ${projectConfig.tools.denied.join(", ")}`);
|
|
9878
|
+
}
|
|
9879
|
+
if (projectConfig.mcpServers && projectConfig.mcpServers.length > 0) {
|
|
9880
|
+
console.log(` MCP Servers: ${projectConfig.mcpServers.map((s) => s.name).join(", ")}`);
|
|
9881
|
+
}
|
|
9882
|
+
console.log("");
|
|
9883
|
+
}
|
|
9884
|
+
if (localConfig) {
|
|
9885
|
+
console.log("Local Config (.bike4mind/local.json):");
|
|
9886
|
+
if (localConfig.trustedTools && localConfig.trustedTools.length > 0) {
|
|
9887
|
+
console.log(` Trusted Tools: ${localConfig.trustedTools.join(", ")}`);
|
|
9888
|
+
}
|
|
9889
|
+
if (localConfig.mcpServers && localConfig.mcpServers.length > 0) {
|
|
9890
|
+
console.log(` MCP Servers: ${localConfig.mcpServers.map((s) => s.name).join(", ")}`);
|
|
9891
|
+
}
|
|
9892
|
+
console.log("");
|
|
9893
|
+
}
|
|
9894
|
+
console.log("Merged Configuration (what you're using):");
|
|
9895
|
+
console.log(` Default Model: ${config.defaultModel}`);
|
|
9896
|
+
console.log(` Trusted Tools: ${config.trustedTools?.length || 0} tools`);
|
|
9897
|
+
console.log(` Denied Tools: ${config.tools.disabled.length} tools`);
|
|
9898
|
+
console.log(` MCP Servers: ${config.mcpServers.length} servers`);
|
|
9899
|
+
} else {
|
|
9900
|
+
console.log("No project configuration found.");
|
|
9901
|
+
console.log("Tip: Create .bike4mind/config.json in your project root for team-wide settings.");
|
|
9902
|
+
}
|
|
9903
|
+
console.log("");
|
|
9904
|
+
break;
|
|
9905
|
+
}
|
|
9837
9906
|
default:
|
|
9838
9907
|
console.log(`Unknown command: /${command}`);
|
|
9839
9908
|
console.log("Type /help for available commands");
|
|
@@ -9842,6 +9911,26 @@ Tool Permissions:
|
|
|
9842
9911
|
if (initError) {
|
|
9843
9912
|
return /* @__PURE__ */ React11.createElement(Box11, { flexDirection: "column", padding: 1 }, /* @__PURE__ */ React11.createElement(Text10, { color: "red", bold: true }, "\u274C Initialization Error"), /* @__PURE__ */ React11.createElement(Text10, null, initError), /* @__PURE__ */ React11.createElement(Text10, { dimColor: true }, "\n", "Tip: Run /config to set up your API keys"));
|
|
9844
9913
|
}
|
|
9914
|
+
if (state.trustLocationSelector) {
|
|
9915
|
+
const projectDir = state.configStore.getProjectConfigDir();
|
|
9916
|
+
const inProject = projectDir !== null;
|
|
9917
|
+
return /* @__PURE__ */ React11.createElement(
|
|
9918
|
+
TrustLocationSelector,
|
|
9919
|
+
{
|
|
9920
|
+
inProject,
|
|
9921
|
+
onSelect: (location) => {
|
|
9922
|
+
if (state.trustLocationSelector) {
|
|
9923
|
+
state.trustLocationSelector.resolve(location);
|
|
9924
|
+
}
|
|
9925
|
+
},
|
|
9926
|
+
onCancel: () => {
|
|
9927
|
+
if (state.trustLocationSelector) {
|
|
9928
|
+
state.trustLocationSelector.resolve(null);
|
|
9929
|
+
}
|
|
9930
|
+
}
|
|
9931
|
+
}
|
|
9932
|
+
);
|
|
9933
|
+
}
|
|
9845
9934
|
if (state.showLoginFlow) {
|
|
9846
9935
|
const loginApiUrl = getApiUrl(state.config?.apiConfig);
|
|
9847
9936
|
return /* @__PURE__ */ React11.createElement(
|