@bike4mind/cli 0.2.1-feat-cli-file-reference.17023 → 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 +1179 -1096
- 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,71 +202,23 @@ function searchCommands(query) {
|
|
|
404
202
|
}
|
|
405
203
|
|
|
406
204
|
// src/components/InputPrompt.tsx
|
|
407
|
-
function shouldShowFileAutocomplete(_query) {
|
|
408
|
-
return true;
|
|
409
|
-
}
|
|
410
|
-
function findAtTrigger(value) {
|
|
411
|
-
for (let i = value.length - 1; i >= 0; i--) {
|
|
412
|
-
if (value[i] === "@") {
|
|
413
|
-
const isValid = i === 0 || value[i - 1] === " ";
|
|
414
|
-
if (isValid) {
|
|
415
|
-
const query = value.slice(i + 1);
|
|
416
|
-
if (query.includes(" ")) {
|
|
417
|
-
return null;
|
|
418
|
-
}
|
|
419
|
-
if (!shouldShowFileAutocomplete(query)) {
|
|
420
|
-
return null;
|
|
421
|
-
}
|
|
422
|
-
return { startIndex: i, query };
|
|
423
|
-
}
|
|
424
|
-
}
|
|
425
|
-
}
|
|
426
|
-
return null;
|
|
427
|
-
}
|
|
428
205
|
function InputPrompt({ onSubmit, disabled = false, history = [] }) {
|
|
429
206
|
const [value, setValue] = useState("");
|
|
430
207
|
const [selectedIndex, setSelectedIndex] = useState(0);
|
|
431
208
|
const [historyIndex, setHistoryIndex] = useState(-1);
|
|
432
209
|
const [tempInput, setTempInput] = useState("");
|
|
433
210
|
const [inputKey, setInputKey] = useState(0);
|
|
434
|
-
const
|
|
435
|
-
const
|
|
436
|
-
const shouldShowCommandAutocomplete = value.startsWith("/") && !disabled && !fileAutocomplete?.active;
|
|
437
|
-
const commandQuery = shouldShowCommandAutocomplete ? value.slice(1) : "";
|
|
211
|
+
const shouldShowAutocomplete = value.startsWith("/") && !disabled;
|
|
212
|
+
const query = shouldShowAutocomplete ? value.slice(1) : "";
|
|
438
213
|
const filteredCommands = useMemo(() => {
|
|
439
|
-
if (!
|
|
440
|
-
return searchCommands(
|
|
441
|
-
}, [
|
|
442
|
-
const filteredFiles = useMemo(() => {
|
|
443
|
-
if (!fileAutocomplete?.active) return [];
|
|
444
|
-
return searchFiles(fileAutocomplete.query);
|
|
445
|
-
}, [fileAutocomplete?.active, fileAutocomplete?.query]);
|
|
214
|
+
if (!shouldShowAutocomplete) return [];
|
|
215
|
+
return searchCommands(query);
|
|
216
|
+
}, [shouldShowAutocomplete, query]);
|
|
446
217
|
useEffect(() => {
|
|
447
218
|
setSelectedIndex(0);
|
|
448
219
|
}, [filteredCommands]);
|
|
449
|
-
useEffect(() => {
|
|
450
|
-
setFileSelectedIndex(0);
|
|
451
|
-
}, [filteredFiles]);
|
|
452
220
|
useInput((input, key) => {
|
|
453
|
-
if (
|
|
454
|
-
if (key.upArrow) {
|
|
455
|
-
setFileSelectedIndex((prev) => prev > 0 ? prev - 1 : filteredFiles.length - 1);
|
|
456
|
-
return;
|
|
457
|
-
} else if (key.downArrow) {
|
|
458
|
-
setFileSelectedIndex((prev) => prev < filteredFiles.length - 1 ? prev + 1 : 0);
|
|
459
|
-
return;
|
|
460
|
-
} else if (key.tab) {
|
|
461
|
-
const selectedFile = filteredFiles[fileSelectedIndex];
|
|
462
|
-
if (selectedFile) {
|
|
463
|
-
insertSelectedFile(selectedFile);
|
|
464
|
-
}
|
|
465
|
-
return;
|
|
466
|
-
} else if (key.escape) {
|
|
467
|
-
setFileAutocomplete(null);
|
|
468
|
-
return;
|
|
469
|
-
}
|
|
470
|
-
}
|
|
471
|
-
if (shouldShowCommandAutocomplete && filteredCommands.length > 0) {
|
|
221
|
+
if (shouldShowAutocomplete && filteredCommands.length > 0) {
|
|
472
222
|
if (key.upArrow) {
|
|
473
223
|
setSelectedIndex((prev) => prev > 0 ? prev - 1 : filteredCommands.length - 1);
|
|
474
224
|
} else if (key.downArrow) {
|
|
@@ -476,7 +226,7 @@ function InputPrompt({ onSubmit, disabled = false, history = [] }) {
|
|
|
476
226
|
}
|
|
477
227
|
return;
|
|
478
228
|
}
|
|
479
|
-
if (!
|
|
229
|
+
if (!shouldShowAutocomplete && history.length > 0) {
|
|
480
230
|
if (key.upArrow) {
|
|
481
231
|
if (historyIndex === -1) {
|
|
482
232
|
setTempInput(value);
|
|
@@ -499,35 +249,9 @@ function InputPrompt({ onSubmit, disabled = false, history = [] }) {
|
|
|
499
249
|
}
|
|
500
250
|
}
|
|
501
251
|
});
|
|
502
|
-
const insertSelectedFile = (file) => {
|
|
503
|
-
if (!fileAutocomplete) return;
|
|
504
|
-
const beforeAt = value.slice(0, fileAutocomplete.startIndex);
|
|
505
|
-
const afterQuery = value.slice(fileAutocomplete.startIndex + 1 + fileAutocomplete.query.length);
|
|
506
|
-
const pathToInsert = file.isDirectory ? `@${file.path}/` : `@${file.path}`;
|
|
507
|
-
const newValue = beforeAt + pathToInsert + afterQuery;
|
|
508
|
-
setValue(newValue);
|
|
509
|
-
setInputKey((prev) => prev + 1);
|
|
510
|
-
if (file.isDirectory) {
|
|
511
|
-
setFileAutocomplete({
|
|
512
|
-
active: true,
|
|
513
|
-
startIndex: fileAutocomplete.startIndex,
|
|
514
|
-
query: file.path + "/"
|
|
515
|
-
});
|
|
516
|
-
setFileSelectedIndex(0);
|
|
517
|
-
} else {
|
|
518
|
-
setFileAutocomplete(null);
|
|
519
|
-
}
|
|
520
|
-
};
|
|
521
252
|
const handleSubmit = (input) => {
|
|
522
253
|
if (disabled || !input.trim()) return;
|
|
523
|
-
if (
|
|
524
|
-
const selectedFile = filteredFiles[fileSelectedIndex];
|
|
525
|
-
if (selectedFile) {
|
|
526
|
-
insertSelectedFile(selectedFile);
|
|
527
|
-
}
|
|
528
|
-
return;
|
|
529
|
-
}
|
|
530
|
-
if (shouldShowCommandAutocomplete && filteredCommands.length > 0) {
|
|
254
|
+
if (shouldShowAutocomplete && filteredCommands.length > 0) {
|
|
531
255
|
const selectedCommand = filteredCommands[selectedIndex];
|
|
532
256
|
const commandText = `/${selectedCommand.name}`;
|
|
533
257
|
if (selectedCommand.args) {
|
|
@@ -544,7 +268,6 @@ function InputPrompt({ onSubmit, disabled = false, history = [] }) {
|
|
|
544
268
|
onSubmit(input);
|
|
545
269
|
setValue("");
|
|
546
270
|
setHistoryIndex(-1);
|
|
547
|
-
setFileAutocomplete(null);
|
|
548
271
|
};
|
|
549
272
|
const handleChange = (newValue) => {
|
|
550
273
|
setValue(newValue);
|
|
@@ -552,40 +275,30 @@ function InputPrompt({ onSubmit, disabled = false, history = [] }) {
|
|
|
552
275
|
setHistoryIndex(-1);
|
|
553
276
|
setTempInput("");
|
|
554
277
|
}
|
|
555
|
-
const atTrigger = findAtTrigger(newValue);
|
|
556
|
-
if (atTrigger) {
|
|
557
|
-
setFileAutocomplete({
|
|
558
|
-
active: true,
|
|
559
|
-
startIndex: atTrigger.startIndex,
|
|
560
|
-
query: atTrigger.query
|
|
561
|
-
});
|
|
562
|
-
} else {
|
|
563
|
-
setFileAutocomplete(null);
|
|
564
|
-
}
|
|
565
278
|
};
|
|
566
|
-
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(
|
|
567
280
|
TextInput,
|
|
568
281
|
{
|
|
569
282
|
key: inputKey,
|
|
570
283
|
value,
|
|
571
284
|
onChange: handleChange,
|
|
572
285
|
onSubmit: handleSubmit,
|
|
573
|
-
placeholder: disabled ? "Thinking..." : "Type your message
|
|
286
|
+
placeholder: disabled ? "Thinking..." : "Type your message or /help for commands",
|
|
574
287
|
showCursor: !disabled
|
|
575
288
|
}
|
|
576
|
-
)),
|
|
289
|
+
)), shouldShowAutocomplete && /* @__PURE__ */ React3.createElement(CommandAutocomplete, { commands: filteredCommands, selectedIndex }));
|
|
577
290
|
}
|
|
578
291
|
|
|
579
292
|
// src/components/AgentThinking.tsx
|
|
580
|
-
import
|
|
581
|
-
import { Box as
|
|
293
|
+
import React5 from "react";
|
|
294
|
+
import { Box as Box5 } from "ink";
|
|
582
295
|
|
|
583
296
|
// src/components/ThoughtStream.tsx
|
|
584
|
-
import
|
|
585
|
-
import { Box as
|
|
297
|
+
import React4 from "react";
|
|
298
|
+
import { Box as Box4, Text as Text4 } from "ink";
|
|
586
299
|
import Spinner from "ink-spinner";
|
|
587
|
-
var ThoughtStream =
|
|
588
|
-
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...")));
|
|
589
302
|
});
|
|
590
303
|
|
|
591
304
|
// src/store/index.ts
|
|
@@ -611,32 +324,32 @@ var useCliStore = create((set) => ({
|
|
|
611
324
|
}));
|
|
612
325
|
|
|
613
326
|
// src/components/AgentThinking.tsx
|
|
614
|
-
var AgentThinking =
|
|
327
|
+
var AgentThinking = React5.memo(function AgentThinking2() {
|
|
615
328
|
const isThinking = useCliStore((state) => state.isThinking);
|
|
616
329
|
const agentSteps = useCliStore((state) => state.agentSteps);
|
|
617
330
|
if (!isThinking) {
|
|
618
331
|
return null;
|
|
619
332
|
}
|
|
620
|
-
return /* @__PURE__ */
|
|
333
|
+
return /* @__PURE__ */ React5.createElement(Box5, { borderStyle: "single", borderColor: "yellow", paddingX: 1, marginY: 1 }, /* @__PURE__ */ React5.createElement(ThoughtStream, { steps: agentSteps }));
|
|
621
334
|
});
|
|
622
335
|
|
|
623
336
|
// src/components/PermissionPrompt.tsx
|
|
624
|
-
import
|
|
625
|
-
import { Box as
|
|
337
|
+
import React6 from "react";
|
|
338
|
+
import { Box as Box6, Text as Text5 } from "ink";
|
|
626
339
|
import SelectInput from "ink-select-input";
|
|
627
340
|
function renderDiffPreview(preview) {
|
|
628
341
|
const lines = preview.split("\n");
|
|
629
342
|
return lines.map((line, index) => {
|
|
630
343
|
if (line.startsWith("+")) {
|
|
631
|
-
return /* @__PURE__ */
|
|
344
|
+
return /* @__PURE__ */ React6.createElement(Text5, { key: index, color: "green" }, line);
|
|
632
345
|
}
|
|
633
346
|
if (line.startsWith("-")) {
|
|
634
|
-
return /* @__PURE__ */
|
|
347
|
+
return /* @__PURE__ */ React6.createElement(Text5, { key: index, color: "red" }, line);
|
|
635
348
|
}
|
|
636
349
|
if (line.startsWith("@@")) {
|
|
637
|
-
return /* @__PURE__ */
|
|
350
|
+
return /* @__PURE__ */ React6.createElement(Text5, { key: index, color: "cyan" }, line);
|
|
638
351
|
}
|
|
639
|
-
return /* @__PURE__ */
|
|
352
|
+
return /* @__PURE__ */ React6.createElement(Text5, { key: index, dimColor: true }, line);
|
|
640
353
|
});
|
|
641
354
|
}
|
|
642
355
|
function PermissionPrompt({
|
|
@@ -656,121 +369,7 @@ function PermissionPrompt({
|
|
|
656
369
|
{ label: "\u2717 Deny", value: "deny" }
|
|
657
370
|
];
|
|
658
371
|
const argsString = typeof args === "string" ? args : JSON.stringify(args, null, 2);
|
|
659
|
-
return /* @__PURE__ */
|
|
660
|
-
}
|
|
661
|
-
|
|
662
|
-
// src/utils/processFileReferences.ts
|
|
663
|
-
import * as fs2 from "fs";
|
|
664
|
-
import * as path2 from "path";
|
|
665
|
-
|
|
666
|
-
// src/utils/constants.ts
|
|
667
|
-
var NAME_SUFFIXES = ["jr", "sr", "ii", "iii", "iv", "v", "phd", "md", "esq"];
|
|
668
|
-
function isNameSuffix(value) {
|
|
669
|
-
return NAME_SUFFIXES.includes(value);
|
|
670
|
-
}
|
|
671
|
-
|
|
672
|
-
// src/utils/processFileReferences.ts
|
|
673
|
-
var FILE_REFERENCE_REGEX = /(?:^|\s)@([^\s@]+)/g;
|
|
674
|
-
function looksLikeFilePath(ref) {
|
|
675
|
-
if (ref.includes("/") || ref.includes(path2.sep)) {
|
|
676
|
-
return true;
|
|
677
|
-
}
|
|
678
|
-
const extensionMatch = /\.(\w+)$/.exec(ref);
|
|
679
|
-
if (extensionMatch) {
|
|
680
|
-
const ext = extensionMatch[1].toLowerCase();
|
|
681
|
-
if (isNameSuffix(ext)) {
|
|
682
|
-
return false;
|
|
683
|
-
}
|
|
684
|
-
if (ext.length > 10) {
|
|
685
|
-
return false;
|
|
686
|
-
}
|
|
687
|
-
return true;
|
|
688
|
-
}
|
|
689
|
-
return false;
|
|
690
|
-
}
|
|
691
|
-
function extractFileReferences(message) {
|
|
692
|
-
const references = [];
|
|
693
|
-
const regex = /(?:^|\s)@([^\s@]+)/g;
|
|
694
|
-
let match;
|
|
695
|
-
while ((match = regex.exec(message)) !== null) {
|
|
696
|
-
const ref = match[1];
|
|
697
|
-
if (looksLikeFilePath(ref)) {
|
|
698
|
-
references.push(ref);
|
|
699
|
-
}
|
|
700
|
-
}
|
|
701
|
-
return references;
|
|
702
|
-
}
|
|
703
|
-
function readFileContents(filePath) {
|
|
704
|
-
const cwd = process.cwd();
|
|
705
|
-
const absolutePath = path2.resolve(cwd, filePath);
|
|
706
|
-
if (!isPathWithinCwd(filePath)) {
|
|
707
|
-
return { error: `Security: Path "${filePath}" is outside the current working directory` };
|
|
708
|
-
}
|
|
709
|
-
if (!fs2.existsSync(absolutePath)) {
|
|
710
|
-
return { error: `File not found: "${filePath}"` };
|
|
711
|
-
}
|
|
712
|
-
const stats = fs2.statSync(absolutePath);
|
|
713
|
-
if (stats.isDirectory()) {
|
|
714
|
-
try {
|
|
715
|
-
const entries = fs2.readdirSync(absolutePath);
|
|
716
|
-
const fileCount = entries.length;
|
|
717
|
-
return {
|
|
718
|
-
content: `(Directory with ${fileCount} items. Use file tools to explore if needed.)`,
|
|
719
|
-
size: 0
|
|
720
|
-
};
|
|
721
|
-
} catch (err) {
|
|
722
|
-
return { error: `Cannot read directory "${filePath}": ${err instanceof Error ? err.message : "Unknown error"}` };
|
|
723
|
-
}
|
|
724
|
-
}
|
|
725
|
-
if (stats.size > MAX_FILE_SIZE) {
|
|
726
|
-
return {
|
|
727
|
-
error: `File too large: "${filePath}" is ${formatFileSize(stats.size)} (max ${formatFileSize(MAX_FILE_SIZE)})`
|
|
728
|
-
};
|
|
729
|
-
}
|
|
730
|
-
if (isBinaryFile(filePath)) {
|
|
731
|
-
return { error: `Binary file: "${filePath}" cannot be included as text content` };
|
|
732
|
-
}
|
|
733
|
-
try {
|
|
734
|
-
const content = fs2.readFileSync(absolutePath, "utf-8");
|
|
735
|
-
return { content, size: stats.size };
|
|
736
|
-
} catch (err) {
|
|
737
|
-
return { error: `Cannot read file "${filePath}": ${err instanceof Error ? err.message : "Unknown error"}` };
|
|
738
|
-
}
|
|
739
|
-
}
|
|
740
|
-
function formatFileBlock(filePath, content, size, isDirectory) {
|
|
741
|
-
if (isDirectory) {
|
|
742
|
-
return `
|
|
743
|
-
--- Directory Reference: ${filePath} ---
|
|
744
|
-
${content}
|
|
745
|
-
--- End of ${filePath} ---`;
|
|
746
|
-
}
|
|
747
|
-
return `
|
|
748
|
-
--- Referenced File: ${filePath} (${formatFileSize(size)}) ---
|
|
749
|
-
${content}
|
|
750
|
-
--- End of ${filePath} ---`;
|
|
751
|
-
}
|
|
752
|
-
async function processFileReferences(message) {
|
|
753
|
-
const references = extractFileReferences(message);
|
|
754
|
-
const errors = [];
|
|
755
|
-
const fileBlocks = [];
|
|
756
|
-
for (const ref of references) {
|
|
757
|
-
const result = readFileContents(ref);
|
|
758
|
-
if ("error" in result) {
|
|
759
|
-
errors.push(result.error);
|
|
760
|
-
continue;
|
|
761
|
-
}
|
|
762
|
-
const isDirectory = result.size === 0 && result.content.startsWith("(Directory");
|
|
763
|
-
fileBlocks.push(formatFileBlock(ref, result.content, result.size, isDirectory));
|
|
764
|
-
}
|
|
765
|
-
if (fileBlocks.length === 0) {
|
|
766
|
-
return { content: message, errors };
|
|
767
|
-
}
|
|
768
|
-
const processedContent = message + "\n" + fileBlocks.join("\n");
|
|
769
|
-
return { content: processedContent, errors };
|
|
770
|
-
}
|
|
771
|
-
function hasFileReferences(message) {
|
|
772
|
-
FILE_REFERENCE_REGEX.lastIndex = 0;
|
|
773
|
-
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) })));
|
|
774
373
|
}
|
|
775
374
|
|
|
776
375
|
// src/components/App.tsx
|
|
@@ -783,7 +382,7 @@ function App({ onMessage, onCommand, onPermissionResponse, commandHistory = [] }
|
|
|
783
382
|
const permissionPrompt = useCliStore((state) => state.permissionPrompt);
|
|
784
383
|
const exitRequested = useCliStore((state) => state.exitRequested);
|
|
785
384
|
const setIsThinking = useCliStore((state) => state.setIsThinking);
|
|
786
|
-
const handleSubmit =
|
|
385
|
+
const handleSubmit = React7.useCallback(
|
|
787
386
|
async (input) => {
|
|
788
387
|
const trimmed = input.trim();
|
|
789
388
|
if (!trimmed) return;
|
|
@@ -794,25 +393,14 @@ function App({ onMessage, onCommand, onPermissionResponse, commandHistory = [] }
|
|
|
794
393
|
}
|
|
795
394
|
setIsThinking(true);
|
|
796
395
|
try {
|
|
797
|
-
|
|
798
|
-
if (hasFileReferences(trimmed)) {
|
|
799
|
-
const processed = await processFileReferences(trimmed);
|
|
800
|
-
messageToSend = processed.content;
|
|
801
|
-
if (processed.errors.length > 0) {
|
|
802
|
-
const errorBlock = processed.errors.map((e) => `[Warning: ${e}]`).join("\n");
|
|
803
|
-
messageToSend = `${messageToSend}
|
|
804
|
-
|
|
805
|
-
${errorBlock}`;
|
|
806
|
-
}
|
|
807
|
-
}
|
|
808
|
-
await onMessage(messageToSend);
|
|
396
|
+
await onMessage(trimmed);
|
|
809
397
|
} finally {
|
|
810
398
|
setIsThinking(false);
|
|
811
399
|
}
|
|
812
400
|
},
|
|
813
401
|
[onMessage, onCommand, setIsThinking]
|
|
814
402
|
);
|
|
815
|
-
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(
|
|
816
404
|
PermissionPrompt,
|
|
817
405
|
{
|
|
818
406
|
toolName: permissionPrompt.toolName,
|
|
@@ -821,39 +409,39 @@ ${errorBlock}`;
|
|
|
821
409
|
canBeTrusted: permissionPrompt.canBeTrusted,
|
|
822
410
|
onResponse: onPermissionResponse
|
|
823
411
|
}
|
|
824
|
-
)) : /* @__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 }))));
|
|
825
413
|
}
|
|
826
414
|
function MessageItem({ message }) {
|
|
827
|
-
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) => {
|
|
828
416
|
if (step.type === "thought") {
|
|
829
|
-
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 ? "..." : ""}`));
|
|
830
418
|
}
|
|
831
419
|
if (step.type === "action") {
|
|
832
420
|
const toolName = step.metadata?.toolName || "unknown";
|
|
833
421
|
const toolInput = step.metadata?.toolInput;
|
|
834
422
|
const observationStep = message.metadata.steps[idx + 1];
|
|
835
423
|
const result = observationStep?.type === "observation" ? observationStep.content : null;
|
|
836
|
-
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 ? "..." : ""}`));
|
|
837
425
|
}
|
|
838
426
|
return null;
|
|
839
|
-
}).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`)));
|
|
840
428
|
}
|
|
841
429
|
|
|
842
430
|
// src/components/MessageList.tsx
|
|
843
|
-
import
|
|
844
|
-
import { Box as
|
|
431
|
+
import React8 from "react";
|
|
432
|
+
import { Box as Box8, Text as Text7 } from "ink";
|
|
845
433
|
function stripThinkingTags(content) {
|
|
846
434
|
return content.replace(/<think>[\s\S]*?<\/think>/g, "").trim();
|
|
847
435
|
}
|
|
848
|
-
var MessageList =
|
|
436
|
+
var MessageList = React8.memo(
|
|
849
437
|
function MessageList2({ messages }) {
|
|
850
438
|
if (messages.length === 0) {
|
|
851
|
-
return /* @__PURE__ */
|
|
439
|
+
return /* @__PURE__ */ React8.createElement(Box8, { paddingY: 1 }, /* @__PURE__ */ React8.createElement(Text7, { dimColor: true }, "No messages yet. Type a message to start!"));
|
|
852
440
|
}
|
|
853
|
-
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) => {
|
|
854
442
|
if (step.type === "thought") {
|
|
855
|
-
return /* @__PURE__ */
|
|
856
|
-
|
|
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,
|
|
857
445
|
{
|
|
858
446
|
dimColor: true
|
|
859
447
|
},
|
|
@@ -865,10 +453,10 @@ var MessageList = React9.memo(
|
|
|
865
453
|
const toolInput = step.metadata?.toolInput;
|
|
866
454
|
const observationStep = message.metadata.steps[idx + 1];
|
|
867
455
|
const result = observationStep?.type === "observation" ? observationStep.content : null;
|
|
868
|
-
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 ? "..." : ""}`));
|
|
869
457
|
}
|
|
870
458
|
return null;
|
|
871
|
-
}).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`)))));
|
|
872
460
|
},
|
|
873
461
|
(prevProps, nextProps) => {
|
|
874
462
|
if (prevProps.messages.length !== nextProps.messages.length) {
|
|
@@ -878,6 +466,39 @@ var MessageList = React9.memo(
|
|
|
878
466
|
}
|
|
879
467
|
);
|
|
880
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
|
+
|
|
881
502
|
// src/components/LoginFlow.tsx
|
|
882
503
|
import React10, { useState as useState2, useEffect as useEffect2 } from "react";
|
|
883
504
|
import { Box as Box10, Text as Text9 } from "ink";
|
|
@@ -990,7 +611,7 @@ var OAuthClient = class {
|
|
|
990
611
|
* Sleep for specified milliseconds
|
|
991
612
|
*/
|
|
992
613
|
sleep(ms) {
|
|
993
|
-
return new Promise((
|
|
614
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
994
615
|
}
|
|
995
616
|
};
|
|
996
617
|
|
|
@@ -1055,19 +676,19 @@ function LoginFlow({ apiUrl = "http://localhost:3000", configStore, onSuccess, o
|
|
|
1055
676
|
}
|
|
1056
677
|
|
|
1057
678
|
// src/storage/SessionStore.ts
|
|
1058
|
-
import { promises as
|
|
1059
|
-
import
|
|
679
|
+
import { promises as fs } from "fs";
|
|
680
|
+
import path from "path";
|
|
1060
681
|
import { homedir } from "os";
|
|
1061
682
|
var SessionStore = class {
|
|
1062
683
|
constructor(basePath) {
|
|
1063
|
-
this.basePath = basePath ||
|
|
684
|
+
this.basePath = basePath || path.join(homedir(), ".bike4mind", "sessions");
|
|
1064
685
|
}
|
|
1065
686
|
/**
|
|
1066
687
|
* Initialize storage directory
|
|
1067
688
|
*/
|
|
1068
689
|
async init() {
|
|
1069
690
|
try {
|
|
1070
|
-
await
|
|
691
|
+
await fs.mkdir(this.basePath, { recursive: true });
|
|
1071
692
|
} catch (error) {
|
|
1072
693
|
console.error("Failed to initialize session storage:", error);
|
|
1073
694
|
throw error;
|
|
@@ -1078,9 +699,9 @@ var SessionStore = class {
|
|
|
1078
699
|
*/
|
|
1079
700
|
async save(session) {
|
|
1080
701
|
await this.init();
|
|
1081
|
-
const filePath =
|
|
702
|
+
const filePath = path.join(this.basePath, `${session.id}.json`);
|
|
1082
703
|
try {
|
|
1083
|
-
await
|
|
704
|
+
await fs.writeFile(filePath, JSON.stringify(session, null, 2), "utf-8");
|
|
1084
705
|
} catch (error) {
|
|
1085
706
|
console.error("Failed to save session:", error);
|
|
1086
707
|
throw error;
|
|
@@ -1090,9 +711,9 @@ var SessionStore = class {
|
|
|
1090
711
|
* Load a session from disk by ID
|
|
1091
712
|
*/
|
|
1092
713
|
async load(id) {
|
|
1093
|
-
const filePath =
|
|
714
|
+
const filePath = path.join(this.basePath, `${id}.json`);
|
|
1094
715
|
try {
|
|
1095
|
-
const data = await
|
|
716
|
+
const data = await fs.readFile(filePath, "utf-8");
|
|
1096
717
|
return JSON.parse(data);
|
|
1097
718
|
} catch (error) {
|
|
1098
719
|
if (error.code === "ENOENT") {
|
|
@@ -1116,12 +737,12 @@ var SessionStore = class {
|
|
|
1116
737
|
async list() {
|
|
1117
738
|
await this.init();
|
|
1118
739
|
try {
|
|
1119
|
-
const files = await
|
|
740
|
+
const files = await fs.readdir(this.basePath);
|
|
1120
741
|
const jsonFiles = files.filter((f) => f.endsWith(".json"));
|
|
1121
742
|
const sessions = await Promise.all(
|
|
1122
743
|
jsonFiles.map(async (file) => {
|
|
1123
|
-
const filePath =
|
|
1124
|
-
const data = await
|
|
744
|
+
const filePath = path.join(this.basePath, file);
|
|
745
|
+
const data = await fs.readFile(filePath, "utf-8");
|
|
1125
746
|
return JSON.parse(data);
|
|
1126
747
|
})
|
|
1127
748
|
);
|
|
@@ -1135,9 +756,9 @@ var SessionStore = class {
|
|
|
1135
756
|
* Delete a session
|
|
1136
757
|
*/
|
|
1137
758
|
async delete(id) {
|
|
1138
|
-
const filePath =
|
|
759
|
+
const filePath = path.join(this.basePath, `${id}.json`);
|
|
1139
760
|
try {
|
|
1140
|
-
await
|
|
761
|
+
await fs.unlink(filePath);
|
|
1141
762
|
return true;
|
|
1142
763
|
} catch (error) {
|
|
1143
764
|
if (error.code === "ENOENT") {
|
|
@@ -1173,8 +794,8 @@ var SessionStore = class {
|
|
|
1173
794
|
};
|
|
1174
795
|
|
|
1175
796
|
// src/storage/ConfigStore.ts
|
|
1176
|
-
import { promises as
|
|
1177
|
-
import
|
|
797
|
+
import { promises as fs2, existsSync } from "fs";
|
|
798
|
+
import path2 from "path";
|
|
1178
799
|
import { homedir as homedir2 } from "os";
|
|
1179
800
|
import { v4 as uuidv4 } from "uuid";
|
|
1180
801
|
import { z } from "zod";
|
|
@@ -1220,6 +841,53 @@ var CliConfigSchema = z.object({
|
|
|
1220
841
|
}),
|
|
1221
842
|
trustedTools: z.array(z.string()).optional().default([])
|
|
1222
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
|
+
});
|
|
1223
891
|
var DEFAULT_CONFIG = {
|
|
1224
892
|
version: "0.1.0",
|
|
1225
893
|
userId: uuidv4(),
|
|
@@ -1245,18 +913,132 @@ var DEFAULT_CONFIG = {
|
|
|
1245
913
|
trustedTools: []
|
|
1246
914
|
// No tools trusted by default
|
|
1247
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
|
+
}
|
|
1248
1029
|
var ConfigStore = class {
|
|
1249
1030
|
constructor(configPath) {
|
|
1250
1031
|
this.config = null;
|
|
1251
|
-
this.
|
|
1032
|
+
this.projectConfigDir = null;
|
|
1033
|
+
this.configPath = configPath || path2.join(homedir2(), ".bike4mind", "config.json");
|
|
1252
1034
|
}
|
|
1253
1035
|
/**
|
|
1254
1036
|
* Initialize config directory
|
|
1255
1037
|
*/
|
|
1256
1038
|
async init() {
|
|
1257
|
-
const dir =
|
|
1039
|
+
const dir = path2.dirname(this.configPath);
|
|
1258
1040
|
try {
|
|
1259
|
-
await
|
|
1041
|
+
await fs2.mkdir(dir, { recursive: true });
|
|
1260
1042
|
} catch (error) {
|
|
1261
1043
|
console.error("Failed to initialize config directory:", error);
|
|
1262
1044
|
throw error;
|
|
@@ -1264,51 +1046,76 @@ var ConfigStore = class {
|
|
|
1264
1046
|
}
|
|
1265
1047
|
/**
|
|
1266
1048
|
* Load configuration from disk with Zod validation
|
|
1049
|
+
* Merges global → project → local configs
|
|
1267
1050
|
*/
|
|
1268
1051
|
async load() {
|
|
1269
1052
|
if (this.config) {
|
|
1270
1053
|
return this.config;
|
|
1271
1054
|
}
|
|
1272
1055
|
try {
|
|
1056
|
+
let globalConfig;
|
|
1273
1057
|
try {
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
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
|
+
}
|
|
1279
1076
|
}
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
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 };
|
|
1288
1104
|
} else {
|
|
1289
|
-
|
|
1105
|
+
throw error;
|
|
1290
1106
|
}
|
|
1291
1107
|
}
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
...DEFAULT_CONFIG.tools,
|
|
1304
|
-
...validated.tools
|
|
1305
|
-
},
|
|
1306
|
-
toolApiKeys: {
|
|
1307
|
-
...DEFAULT_CONFIG.toolApiKeys,
|
|
1308
|
-
...validated.toolApiKeys || {}
|
|
1309
|
-
},
|
|
1310
|
-
trustedTools: validated.trustedTools || []
|
|
1311
|
-
};
|
|
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);
|
|
1312
1119
|
return this.config;
|
|
1313
1120
|
} catch (error) {
|
|
1314
1121
|
if (error.code === "ENOENT") {
|
|
@@ -1352,8 +1159,8 @@ var ConfigStore = class {
|
|
|
1352
1159
|
throw new Error("No configuration to save");
|
|
1353
1160
|
}
|
|
1354
1161
|
try {
|
|
1355
|
-
await
|
|
1356
|
-
await
|
|
1162
|
+
await fs2.writeFile(this.configPath, JSON.stringify(this.config, null, 2), "utf-8");
|
|
1163
|
+
await fs2.chmod(this.configPath, 384);
|
|
1357
1164
|
} catch (error) {
|
|
1358
1165
|
console.error("Failed to save config:", error);
|
|
1359
1166
|
throw error;
|
|
@@ -1495,27 +1302,126 @@ var ConfigStore = class {
|
|
|
1495
1302
|
} else {
|
|
1496
1303
|
config.apiConfig = { customUrl: url };
|
|
1497
1304
|
}
|
|
1498
|
-
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);
|
|
1499
1405
|
}
|
|
1500
1406
|
};
|
|
1501
1407
|
|
|
1502
1408
|
// src/storage/CommandHistoryStore.ts
|
|
1503
|
-
import { promises as
|
|
1504
|
-
import
|
|
1409
|
+
import { promises as fs3 } from "fs";
|
|
1410
|
+
import path3 from "path";
|
|
1505
1411
|
import { homedir as homedir3 } from "os";
|
|
1506
1412
|
var MAX_HISTORY_ENTRIES = 1e3;
|
|
1507
1413
|
var CommandHistoryStore = class {
|
|
1508
1414
|
constructor(historyPath) {
|
|
1509
1415
|
this.history = null;
|
|
1510
|
-
this.historyPath = historyPath ||
|
|
1416
|
+
this.historyPath = historyPath || path3.join(homedir3(), ".bike4mind", "history.jsonl");
|
|
1511
1417
|
}
|
|
1512
1418
|
/**
|
|
1513
1419
|
* Initialize history directory
|
|
1514
1420
|
*/
|
|
1515
1421
|
async init() {
|
|
1516
|
-
const dir =
|
|
1422
|
+
const dir = path3.dirname(this.historyPath);
|
|
1517
1423
|
try {
|
|
1518
|
-
await
|
|
1424
|
+
await fs3.mkdir(dir, { recursive: true });
|
|
1519
1425
|
} catch (error) {
|
|
1520
1426
|
console.error("Failed to initialize history directory:", error);
|
|
1521
1427
|
throw error;
|
|
@@ -1530,7 +1436,7 @@ var CommandHistoryStore = class {
|
|
|
1530
1436
|
return this.history;
|
|
1531
1437
|
}
|
|
1532
1438
|
try {
|
|
1533
|
-
const data = await
|
|
1439
|
+
const data = await fs3.readFile(this.historyPath, "utf-8");
|
|
1534
1440
|
const lines = data.trim().split("\n").filter((line) => line.length > 0);
|
|
1535
1441
|
const entries = lines.map((line) => {
|
|
1536
1442
|
try {
|
|
@@ -1567,7 +1473,7 @@ var CommandHistoryStore = class {
|
|
|
1567
1473
|
};
|
|
1568
1474
|
await this.init();
|
|
1569
1475
|
const line = JSON.stringify(entry) + "\n";
|
|
1570
|
-
await
|
|
1476
|
+
await fs3.appendFile(this.historyPath, line, "utf-8");
|
|
1571
1477
|
this.history = [command, ...this.history || []];
|
|
1572
1478
|
if (this.history.length > MAX_HISTORY_ENTRIES) {
|
|
1573
1479
|
await this.trim();
|
|
@@ -1590,7 +1496,7 @@ var CommandHistoryStore = class {
|
|
|
1590
1496
|
};
|
|
1591
1497
|
return JSON.stringify(entry);
|
|
1592
1498
|
}).join("\n");
|
|
1593
|
-
await
|
|
1499
|
+
await fs3.writeFile(this.historyPath, lines + "\n", "utf-8");
|
|
1594
1500
|
this.history = trimmedCommands;
|
|
1595
1501
|
}
|
|
1596
1502
|
/**
|
|
@@ -1598,7 +1504,7 @@ var CommandHistoryStore = class {
|
|
|
1598
1504
|
*/
|
|
1599
1505
|
async clear() {
|
|
1600
1506
|
try {
|
|
1601
|
-
await
|
|
1507
|
+
await fs3.unlink(this.historyPath);
|
|
1602
1508
|
} catch (error) {
|
|
1603
1509
|
if (error.code !== "ENOENT") {
|
|
1604
1510
|
throw error;
|
|
@@ -2372,7 +2278,7 @@ import { GoogleGenerativeAI } from "@google/generative-ai";
|
|
|
2372
2278
|
import OpenAI2 from "openai";
|
|
2373
2279
|
|
|
2374
2280
|
// ../../b4m-core/packages/services/dist/src/importHistoryService/index.js
|
|
2375
|
-
import
|
|
2281
|
+
import fs4, { unlinkSync } from "fs";
|
|
2376
2282
|
import yauzl from "yauzl";
|
|
2377
2283
|
import axios3 from "axios";
|
|
2378
2284
|
|
|
@@ -2979,196 +2885,190 @@ var listFabFilesBySessionSchema = z90.object({
|
|
|
2979
2885
|
sessionId: z90.string()
|
|
2980
2886
|
});
|
|
2981
2887
|
|
|
2982
|
-
// ../../b4m-core/packages/services/dist/src/fabFileService/listByQuest.js
|
|
2983
|
-
import { z as z91 } from "zod";
|
|
2984
|
-
var listFabFilesByQuestSchema = z91.object({
|
|
2985
|
-
questId: z91.string()
|
|
2986
|
-
});
|
|
2987
|
-
|
|
2988
2888
|
// ../../b4m-core/packages/services/dist/src/fabFileService/createByUrl.js
|
|
2989
|
-
import { z as
|
|
2990
|
-
var createFabFileByUrlSchema =
|
|
2991
|
-
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,})).+/)
|
|
2992
2892
|
});
|
|
2993
2893
|
|
|
2994
2894
|
// ../../b4m-core/packages/services/dist/src/fabFileService/search.js
|
|
2995
|
-
import { z as
|
|
2996
|
-
var searchFabFilesSchema =
|
|
2997
|
-
search:
|
|
2998
|
-
filters:
|
|
2999
|
-
tags:
|
|
3000
|
-
type:
|
|
3001
|
-
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(),
|
|
3002
2902
|
// Indicates if the user is searching for shared files
|
|
3003
|
-
curated:
|
|
2903
|
+
curated: z92.coerce.boolean().optional(),
|
|
3004
2904
|
// Indicates if the user is searching for curated notebook files
|
|
3005
|
-
projectId:
|
|
3006
|
-
ids:
|
|
2905
|
+
projectId: z92.string().optional(),
|
|
2906
|
+
ids: z92.array(z92.string()).optional()
|
|
3007
2907
|
// Add support for filtering by IDs
|
|
3008
2908
|
}).optional(),
|
|
3009
|
-
pagination:
|
|
3010
|
-
page:
|
|
3011
|
-
limit:
|
|
2909
|
+
pagination: z92.object({
|
|
2910
|
+
page: z92.coerce.number(),
|
|
2911
|
+
limit: z92.coerce.number()
|
|
3012
2912
|
}).optional(),
|
|
3013
|
-
order:
|
|
3014
|
-
by:
|
|
3015
|
-
direction:
|
|
2913
|
+
order: z92.object({
|
|
2914
|
+
by: z92.enum(["createdAt", "fileName", "fileSize"]),
|
|
2915
|
+
direction: z92.enum(["asc", "desc"])
|
|
3016
2916
|
}).optional(),
|
|
3017
|
-
options:
|
|
3018
|
-
includeShared:
|
|
2917
|
+
options: z92.object({
|
|
2918
|
+
includeShared: z92.coerce.boolean().optional()
|
|
3019
2919
|
}).optional()
|
|
3020
2920
|
});
|
|
3021
2921
|
|
|
3022
2922
|
// ../../b4m-core/packages/services/dist/src/fabFileService/addFavorite.js
|
|
3023
|
-
import { z as
|
|
3024
|
-
var addFavoriteParametersSchema3 =
|
|
3025
|
-
fileId:
|
|
2923
|
+
import { z as z93 } from "zod";
|
|
2924
|
+
var addFavoriteParametersSchema3 = z93.object({
|
|
2925
|
+
fileId: z93.string()
|
|
3026
2926
|
});
|
|
3027
2927
|
|
|
3028
2928
|
// ../../b4m-core/packages/services/dist/src/fabFileService/deleteFavorite.js
|
|
3029
|
-
import { z as
|
|
3030
|
-
var deleteFavoriteParametersSchema4 =
|
|
3031
|
-
fileId:
|
|
2929
|
+
import { z as z94 } from "zod";
|
|
2930
|
+
var deleteFavoriteParametersSchema4 = z94.object({
|
|
2931
|
+
fileId: z94.string()
|
|
3032
2932
|
});
|
|
3033
2933
|
|
|
3034
2934
|
// ../../b4m-core/packages/services/dist/src/fabFileService/toggleTags.js
|
|
3035
|
-
import { z as
|
|
3036
|
-
var fabFileToggleTagsSchema =
|
|
3037
|
-
ids:
|
|
3038
|
-
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())
|
|
3039
2939
|
});
|
|
3040
2940
|
|
|
3041
2941
|
// ../../b4m-core/packages/services/dist/src/fabFileService/edit.js
|
|
3042
|
-
import { z as
|
|
2942
|
+
import { z as z96 } from "zod";
|
|
3043
2943
|
import { diffLines } from "diff";
|
|
3044
|
-
var editFabFileSchema =
|
|
3045
|
-
id:
|
|
3046
|
-
instruction:
|
|
3047
|
-
selection:
|
|
3048
|
-
start:
|
|
3049
|
-
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()
|
|
3050
2950
|
}).optional(),
|
|
3051
|
-
preserveFormatting:
|
|
3052
|
-
applyImmediately:
|
|
2951
|
+
preserveFormatting: z96.boolean().optional().default(true),
|
|
2952
|
+
applyImmediately: z96.boolean().optional().default(false)
|
|
3053
2953
|
});
|
|
3054
2954
|
|
|
3055
2955
|
// ../../b4m-core/packages/services/dist/src/fabFileService/applyEdit.js
|
|
3056
2956
|
import mime2 from "mime-types";
|
|
3057
2957
|
import { v4 as uuidv43 } from "uuid";
|
|
3058
|
-
import { z as
|
|
3059
|
-
var applyEditSchema =
|
|
3060
|
-
id:
|
|
3061
|
-
modifiedContent:
|
|
3062
|
-
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)
|
|
3063
2963
|
});
|
|
3064
2964
|
|
|
3065
2965
|
// ../../b4m-core/packages/services/dist/src/friendshipService/respondToFriendRequest.js
|
|
3066
|
-
import { z as
|
|
3067
|
-
var respondToFriendRequestSchema =
|
|
3068
|
-
id:
|
|
2966
|
+
import { z as z98 } from "zod";
|
|
2967
|
+
var respondToFriendRequestSchema = z98.object({
|
|
2968
|
+
id: z98.string(),
|
|
3069
2969
|
/** The user ID of the recipient of the friend request */
|
|
3070
|
-
userId:
|
|
3071
|
-
accept:
|
|
2970
|
+
userId: z98.string(),
|
|
2971
|
+
accept: z98.boolean()
|
|
3072
2972
|
});
|
|
3073
2973
|
|
|
3074
2974
|
// ../../b4m-core/packages/services/dist/src/friendshipService/unfriend.js
|
|
3075
|
-
import { z as
|
|
3076
|
-
var unfriendSchema =
|
|
3077
|
-
friendshipId:
|
|
2975
|
+
import { z as z99 } from "zod";
|
|
2976
|
+
var unfriendSchema = z99.object({
|
|
2977
|
+
friendshipId: z99.string(),
|
|
3078
2978
|
/** The user ID of the user who wants to unfriend the other user */
|
|
3079
|
-
userId:
|
|
2979
|
+
userId: z99.string()
|
|
3080
2980
|
});
|
|
3081
2981
|
|
|
3082
2982
|
// ../../b4m-core/packages/services/dist/src/friendshipService/list.js
|
|
3083
|
-
import { z as
|
|
3084
|
-
var listFriendsSchema =
|
|
3085
|
-
userId:
|
|
2983
|
+
import { z as z100 } from "zod";
|
|
2984
|
+
var listFriendsSchema = z100.object({
|
|
2985
|
+
userId: z100.string()
|
|
3086
2986
|
});
|
|
3087
|
-
var listPendingFriendRequestsSchema =
|
|
3088
|
-
userId:
|
|
2987
|
+
var listPendingFriendRequestsSchema = z100.object({
|
|
2988
|
+
userId: z100.string()
|
|
3089
2989
|
});
|
|
3090
2990
|
|
|
3091
2991
|
// ../../b4m-core/packages/services/dist/src/adminService/loginAs.js
|
|
3092
|
-
import { z as
|
|
3093
|
-
var loginAsSchema =
|
|
3094
|
-
targetUserId:
|
|
2992
|
+
import { z as z101 } from "zod";
|
|
2993
|
+
var loginAsSchema = z101.object({
|
|
2994
|
+
targetUserId: z101.string()
|
|
3095
2995
|
});
|
|
3096
2996
|
|
|
3097
2997
|
// ../../b4m-core/packages/services/dist/src/cacheService/get.js
|
|
3098
|
-
import { z as
|
|
3099
|
-
var getParamsSchema =
|
|
3100
|
-
key:
|
|
2998
|
+
import { z as z102 } from "zod";
|
|
2999
|
+
var getParamsSchema = z102.object({
|
|
3000
|
+
key: z102.string()
|
|
3101
3001
|
});
|
|
3102
3002
|
|
|
3103
3003
|
// ../../b4m-core/packages/services/dist/src/cacheService/set.js
|
|
3104
|
-
import { z as
|
|
3105
|
-
var setParamsSchema =
|
|
3106
|
-
key:
|
|
3107
|
-
value:
|
|
3004
|
+
import { z as z103 } from "zod";
|
|
3005
|
+
var setParamsSchema = z103.object({
|
|
3006
|
+
key: z103.string(),
|
|
3007
|
+
value: z103.any(),
|
|
3108
3008
|
/**
|
|
3109
3009
|
* Time to live in milliseconds
|
|
3110
3010
|
*/
|
|
3111
|
-
ttl:
|
|
3112
|
-
recache:
|
|
3011
|
+
ttl: z103.number(),
|
|
3012
|
+
recache: z103.boolean().optional()
|
|
3113
3013
|
});
|
|
3114
3014
|
|
|
3115
3015
|
// ../../b4m-core/packages/services/dist/src/cacheService/ttl.js
|
|
3116
|
-
import { z as
|
|
3117
|
-
var ttlParamsSchema =
|
|
3118
|
-
key:
|
|
3016
|
+
import { z as z104 } from "zod";
|
|
3017
|
+
var ttlParamsSchema = z104.object({
|
|
3018
|
+
key: z104.string()
|
|
3119
3019
|
});
|
|
3120
3020
|
|
|
3121
3021
|
// ../../b4m-core/packages/services/dist/src/cacheService/weeklyReports.js
|
|
3122
|
-
import { z as
|
|
3022
|
+
import { z as z105 } from "zod";
|
|
3123
3023
|
import dayjs3 from "dayjs";
|
|
3124
|
-
var weeklyReportSchema =
|
|
3125
|
-
startDate:
|
|
3126
|
-
endDate:
|
|
3127
|
-
report:
|
|
3128
|
-
aiInsights:
|
|
3024
|
+
var weeklyReportSchema = z105.object({
|
|
3025
|
+
startDate: z105.string(),
|
|
3026
|
+
endDate: z105.string(),
|
|
3027
|
+
report: z105.string(),
|
|
3028
|
+
aiInsights: z105.string().nullable()
|
|
3129
3029
|
});
|
|
3130
3030
|
|
|
3131
3031
|
// ../../b4m-core/packages/services/dist/src/embeddingCacheService/generateCacheKey.js
|
|
3132
3032
|
import crypto2 from "crypto";
|
|
3133
3033
|
|
|
3134
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
|
|
3135
3042
|
import { z as z107 } from "zod";
|
|
3136
|
-
var
|
|
3043
|
+
var researchAgentUpdateSchema = z107.object({
|
|
3044
|
+
id: z107.string(),
|
|
3137
3045
|
name: z107.string().min(1),
|
|
3138
3046
|
description: z107.string().min(1)
|
|
3139
3047
|
});
|
|
3140
3048
|
|
|
3141
|
-
// ../../b4m-core/packages/services/dist/src/researchAgentService/
|
|
3049
|
+
// ../../b4m-core/packages/services/dist/src/researchAgentService/remove.js
|
|
3142
3050
|
import { z as z108 } from "zod";
|
|
3143
|
-
var
|
|
3144
|
-
id: z108.string()
|
|
3145
|
-
name: z108.string().min(1),
|
|
3146
|
-
description: z108.string().min(1)
|
|
3051
|
+
var researchAgentRemoveSchema = z108.object({
|
|
3052
|
+
id: z108.string()
|
|
3147
3053
|
});
|
|
3148
3054
|
|
|
3149
|
-
// ../../b4m-core/packages/services/dist/src/researchAgentService/
|
|
3055
|
+
// ../../b4m-core/packages/services/dist/src/researchAgentService/get.js
|
|
3150
3056
|
import { z as z109 } from "zod";
|
|
3151
|
-
var
|
|
3057
|
+
var researchAgentGetSchema = z109.object({
|
|
3152
3058
|
id: z109.string()
|
|
3153
3059
|
});
|
|
3154
3060
|
|
|
3155
|
-
// ../../b4m-core/packages/services/dist/src/researchAgentService/get.js
|
|
3156
|
-
import { z as z110 } from "zod";
|
|
3157
|
-
var researchAgentGetSchema = z110.object({
|
|
3158
|
-
id: z110.string()
|
|
3159
|
-
});
|
|
3160
|
-
|
|
3161
3061
|
// ../../b4m-core/packages/services/dist/src/researchAgentService/listFiles.js
|
|
3162
|
-
import { z as
|
|
3163
|
-
var researchAgentListFilesSchema =
|
|
3062
|
+
import { z as z110 } from "zod";
|
|
3063
|
+
var researchAgentListFilesSchema = z110.object({
|
|
3164
3064
|
/**
|
|
3165
3065
|
* The ID of the research agent
|
|
3166
3066
|
*/
|
|
3167
|
-
id:
|
|
3067
|
+
id: z110.string()
|
|
3168
3068
|
});
|
|
3169
3069
|
|
|
3170
3070
|
// ../../b4m-core/packages/services/dist/src/researchTaskService/process.js
|
|
3171
|
-
import { z as
|
|
3071
|
+
import { z as z111 } from "zod";
|
|
3172
3072
|
|
|
3173
3073
|
// ../../b4m-core/packages/services/dist/src/lib/turndown.js
|
|
3174
3074
|
import turndown from "turndown";
|
|
@@ -3559,316 +3459,316 @@ var deepResearchTool = {
|
|
|
3559
3459
|
};
|
|
3560
3460
|
|
|
3561
3461
|
// ../../b4m-core/packages/services/dist/src/researchTaskService/process.js
|
|
3562
|
-
var ResearchTaskProcessSchema =
|
|
3563
|
-
id:
|
|
3462
|
+
var ResearchTaskProcessSchema = z111.object({
|
|
3463
|
+
id: z111.string()
|
|
3564
3464
|
});
|
|
3565
3465
|
|
|
3566
3466
|
// ../../b4m-core/packages/services/dist/src/researchTaskService/create.js
|
|
3567
|
-
import { z as
|
|
3568
|
-
var researchTaskCreateSchema =
|
|
3569
|
-
researchAgentId:
|
|
3570
|
-
title:
|
|
3571
|
-
description:
|
|
3572
|
-
prompt:
|
|
3573
|
-
type:
|
|
3574
|
-
executionType:
|
|
3575
|
-
fileTagId:
|
|
3576
|
-
autoGeneratedTag:
|
|
3577
|
-
name:
|
|
3578
|
-
icon:
|
|
3579
|
-
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()
|
|
3580
3480
|
}).optional()
|
|
3581
3481
|
});
|
|
3582
3482
|
var researchTaskScrapeCreateSchema = researchTaskCreateSchema.extend({
|
|
3583
|
-
urls:
|
|
3584
|
-
canDiscoverLinks:
|
|
3483
|
+
urls: z112.array(z112.string().url()).min(1),
|
|
3484
|
+
canDiscoverLinks: z112.boolean()
|
|
3585
3485
|
});
|
|
3586
3486
|
var researchTaskPeriodicCreateSchema = researchTaskCreateSchema.extend({
|
|
3587
|
-
executionPeriodicStartAt:
|
|
3588
|
-
executionPeriodicEndAt:
|
|
3589
|
-
executionPeriodicFrequency:
|
|
3487
|
+
executionPeriodicStartAt: z112.coerce.date(),
|
|
3488
|
+
executionPeriodicEndAt: z112.coerce.date(),
|
|
3489
|
+
executionPeriodicFrequency: z112.nativeEnum(ResearchTaskPeriodicFrequencyType)
|
|
3590
3490
|
});
|
|
3591
3491
|
var researchTaskScheduledCreateSchema = researchTaskCreateSchema.extend({
|
|
3592
|
-
executionScheduledAt:
|
|
3492
|
+
executionScheduledAt: z112.coerce.date()
|
|
3593
3493
|
});
|
|
3594
3494
|
var researchTaskDeepResearchCreateSchema = researchTaskCreateSchema.extend({
|
|
3595
|
-
maxDepth:
|
|
3495
|
+
maxDepth: z112.number().min(1).max(10).optional()
|
|
3596
3496
|
});
|
|
3597
3497
|
|
|
3598
3498
|
// ../../b4m-core/packages/services/dist/src/researchTaskService/search.js
|
|
3599
|
-
import { z as
|
|
3600
|
-
var searchResearchTasksSchema =
|
|
3601
|
-
search:
|
|
3499
|
+
import { z as z113 } from "zod";
|
|
3500
|
+
var searchResearchTasksSchema = z113.object({
|
|
3501
|
+
search: z113.string().optional(),
|
|
3602
3502
|
// ADD FILTERS SCHEMA HERE
|
|
3603
3503
|
// filters: z
|
|
3604
3504
|
// .object({
|
|
3605
3505
|
// userId: z.string().optional(),
|
|
3606
3506
|
// })
|
|
3607
3507
|
// .optional(),
|
|
3608
|
-
pagination:
|
|
3609
|
-
page:
|
|
3610
|
-
limit:
|
|
3508
|
+
pagination: z113.object({
|
|
3509
|
+
page: z113.coerce.number().optional(),
|
|
3510
|
+
limit: z113.coerce.number().optional()
|
|
3611
3511
|
}).optional(),
|
|
3612
|
-
orderBy:
|
|
3613
|
-
by:
|
|
3614
|
-
direction:
|
|
3512
|
+
orderBy: z113.object({
|
|
3513
|
+
by: z113.enum(["createdAt", "updatedAt"]).optional(),
|
|
3514
|
+
direction: z113.enum(["asc", "desc"]).optional()
|
|
3615
3515
|
}).optional()
|
|
3616
3516
|
});
|
|
3617
3517
|
|
|
3618
3518
|
// ../../b4m-core/packages/services/dist/src/researchTaskService/get.js
|
|
3619
|
-
import { z as
|
|
3620
|
-
var getResearchTaskSchema =
|
|
3621
|
-
id:
|
|
3519
|
+
import { z as z114 } from "zod";
|
|
3520
|
+
var getResearchTaskSchema = z114.object({
|
|
3521
|
+
id: z114.string().min(1)
|
|
3622
3522
|
});
|
|
3623
3523
|
|
|
3624
3524
|
// ../../b4m-core/packages/services/dist/src/researchTaskService/update.js
|
|
3625
|
-
import { z as
|
|
3626
|
-
var updateResearchTaskSchema =
|
|
3627
|
-
id:
|
|
3628
|
-
title:
|
|
3629
|
-
description:
|
|
3630
|
-
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)
|
|
3631
3531
|
});
|
|
3632
3532
|
var researchTaskScrapeUpdateSchema = updateResearchTaskSchema.extend({
|
|
3633
|
-
urls:
|
|
3634
|
-
canDiscoverLinks:
|
|
3533
|
+
urls: z115.array(z115.string().url()).min(1),
|
|
3534
|
+
canDiscoverLinks: z115.boolean()
|
|
3635
3535
|
});
|
|
3636
3536
|
|
|
3637
3537
|
// ../../b4m-core/packages/services/dist/src/researchTaskService/listByAgentId.js
|
|
3638
|
-
import { z as
|
|
3639
|
-
var listByAgentIdSchema =
|
|
3640
|
-
researchAgentId:
|
|
3538
|
+
import { z as z116 } from "zod";
|
|
3539
|
+
var listByAgentIdSchema = z116.object({
|
|
3540
|
+
researchAgentId: z116.string()
|
|
3641
3541
|
});
|
|
3642
3542
|
|
|
3643
3543
|
// ../../b4m-core/packages/services/dist/src/researchTaskService/remove.js
|
|
3644
|
-
import { z as
|
|
3645
|
-
var researchTaskRemoveSchema =
|
|
3646
|
-
id:
|
|
3544
|
+
import { z as z117 } from "zod";
|
|
3545
|
+
var researchTaskRemoveSchema = z117.object({
|
|
3546
|
+
id: z117.string().min(1)
|
|
3647
3547
|
});
|
|
3648
3548
|
|
|
3649
3549
|
// ../../b4m-core/packages/services/dist/src/researchTaskService/retry.js
|
|
3650
|
-
import { z as
|
|
3651
|
-
var researchTaskRetrySchema =
|
|
3652
|
-
id:
|
|
3653
|
-
userId:
|
|
3550
|
+
import { z as z118 } from "zod";
|
|
3551
|
+
var researchTaskRetrySchema = z118.object({
|
|
3552
|
+
id: z118.string(),
|
|
3553
|
+
userId: z118.string()
|
|
3654
3554
|
});
|
|
3655
3555
|
|
|
3656
3556
|
// ../../b4m-core/packages/services/dist/src/researchTaskService/processDiscoveredLinks.js
|
|
3657
3557
|
import axios4 from "axios";
|
|
3658
|
-
import { z as
|
|
3558
|
+
import { z as z119 } from "zod";
|
|
3659
3559
|
import plimit from "p-limit";
|
|
3660
3560
|
import pLimit2 from "p-limit";
|
|
3661
|
-
var researchTaskProcessDiscoveredLinksSchema =
|
|
3662
|
-
id:
|
|
3561
|
+
var researchTaskProcessDiscoveredLinksSchema = z119.object({
|
|
3562
|
+
id: z119.string()
|
|
3663
3563
|
});
|
|
3664
3564
|
|
|
3665
3565
|
// ../../b4m-core/packages/services/dist/src/researchTaskService/downloadRelevantLinks.js
|
|
3666
|
-
import { z as
|
|
3566
|
+
import { z as z120 } from "zod";
|
|
3667
3567
|
import plimit2 from "p-limit";
|
|
3668
3568
|
import axios5 from "axios";
|
|
3669
3569
|
import { fileTypeFromBuffer } from "file-type";
|
|
3670
|
-
var researchTaskDownloadRelevantLinksSchema =
|
|
3671
|
-
id:
|
|
3570
|
+
var researchTaskDownloadRelevantLinksSchema = z120.object({
|
|
3571
|
+
id: z120.string()
|
|
3672
3572
|
});
|
|
3673
3573
|
|
|
3674
3574
|
// ../../b4m-core/packages/services/dist/src/researchData/remove.js
|
|
3675
|
-
import { z as
|
|
3676
|
-
var researchDataRemoveSchema =
|
|
3677
|
-
id:
|
|
3678
|
-
researchAgentId:
|
|
3575
|
+
import { z as z121 } from "zod";
|
|
3576
|
+
var researchDataRemoveSchema = z121.object({
|
|
3577
|
+
id: z121.string(),
|
|
3578
|
+
researchAgentId: z121.string()
|
|
3679
3579
|
});
|
|
3680
3580
|
|
|
3681
3581
|
// ../../b4m-core/packages/services/dist/src/taskSchedulerService/create.js
|
|
3682
|
-
import { z as
|
|
3683
|
-
var researchTaskPayload =
|
|
3684
|
-
id:
|
|
3685
|
-
userId:
|
|
3582
|
+
import { z as z122 } from "zod";
|
|
3583
|
+
var researchTaskPayload = z122.object({
|
|
3584
|
+
id: z122.string(),
|
|
3585
|
+
userId: z122.string()
|
|
3686
3586
|
});
|
|
3687
|
-
var customTaskPayload =
|
|
3688
|
-
test:
|
|
3587
|
+
var customTaskPayload = z122.object({
|
|
3588
|
+
test: z122.string()
|
|
3689
3589
|
});
|
|
3690
|
-
var taskSchedulerCreate =
|
|
3691
|
-
|
|
3692
|
-
handler:
|
|
3590
|
+
var taskSchedulerCreate = z122.discriminatedUnion("handler", [
|
|
3591
|
+
z122.object({
|
|
3592
|
+
handler: z122.literal(TaskScheduleHandler.RESEARCH_TASK_PROCESS),
|
|
3693
3593
|
payload: researchTaskPayload,
|
|
3694
|
-
processDate:
|
|
3594
|
+
processDate: z122.date()
|
|
3695
3595
|
}),
|
|
3696
|
-
|
|
3697
|
-
handler:
|
|
3596
|
+
z122.object({
|
|
3597
|
+
handler: z122.literal(TaskScheduleHandler.CUSTOM_TASK_PROCESS),
|
|
3698
3598
|
payload: customTaskPayload,
|
|
3699
|
-
processDate:
|
|
3599
|
+
processDate: z122.date()
|
|
3700
3600
|
})
|
|
3701
3601
|
]);
|
|
3702
3602
|
|
|
3703
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
|
|
3704
3613
|
import { z as z124 } from "zod";
|
|
3705
|
-
var
|
|
3614
|
+
var tagCreateSchema = z124.object({
|
|
3706
3615
|
name: z124.string(),
|
|
3707
3616
|
icon: z124.string().optional(),
|
|
3617
|
+
description: z124.string().optional(),
|
|
3708
3618
|
color: z124.string().optional(),
|
|
3709
|
-
|
|
3619
|
+
type: z124.nativeEnum(TagType)
|
|
3710
3620
|
});
|
|
3711
3621
|
|
|
3712
|
-
// ../../b4m-core/packages/services/dist/src/tagService/
|
|
3622
|
+
// ../../b4m-core/packages/services/dist/src/tagService/update.js
|
|
3713
3623
|
import { z as z125 } from "zod";
|
|
3714
|
-
var
|
|
3715
|
-
|
|
3624
|
+
var tagUpdateSchema = z125.object({
|
|
3625
|
+
id: z125.string(),
|
|
3626
|
+
name: z125.string().optional(),
|
|
3716
3627
|
icon: z125.string().optional(),
|
|
3717
3628
|
description: z125.string().optional(),
|
|
3718
|
-
color: z125.string().optional()
|
|
3719
|
-
type: z125.nativeEnum(TagType)
|
|
3720
|
-
});
|
|
3721
|
-
|
|
3722
|
-
// ../../b4m-core/packages/services/dist/src/tagService/update.js
|
|
3723
|
-
import { z as z126 } from "zod";
|
|
3724
|
-
var tagUpdateSchema = z126.object({
|
|
3725
|
-
id: z126.string(),
|
|
3726
|
-
name: z126.string().optional(),
|
|
3727
|
-
icon: z126.string().optional(),
|
|
3728
|
-
description: z126.string().optional(),
|
|
3729
|
-
color: z126.string().optional()
|
|
3629
|
+
color: z125.string().optional()
|
|
3730
3630
|
});
|
|
3731
3631
|
|
|
3732
3632
|
// ../../b4m-core/packages/services/dist/src/tagService/remove.js
|
|
3733
|
-
import { z as
|
|
3734
|
-
var tagRemoveSchema =
|
|
3735
|
-
id:
|
|
3633
|
+
import { z as z126 } from "zod";
|
|
3634
|
+
var tagRemoveSchema = z126.object({
|
|
3635
|
+
id: z126.string()
|
|
3736
3636
|
});
|
|
3737
3637
|
|
|
3738
3638
|
// ../../b4m-core/packages/services/dist/src/artifactService/create.js
|
|
3739
|
-
import { z as
|
|
3740
|
-
var createArtifactSchema =
|
|
3741
|
-
id:
|
|
3639
|
+
import { z as z127 } from "zod";
|
|
3640
|
+
var createArtifactSchema = z127.object({
|
|
3641
|
+
id: z127.string().optional(),
|
|
3742
3642
|
// Allow custom ID for AI-generated artifacts
|
|
3743
|
-
type:
|
|
3744
|
-
title:
|
|
3745
|
-
description:
|
|
3746
|
-
content:
|
|
3747
|
-
projectId:
|
|
3748
|
-
organizationId:
|
|
3749
|
-
visibility:
|
|
3750
|
-
tags:
|
|
3751
|
-
versionTag:
|
|
3752
|
-
sourceQuestId:
|
|
3753
|
-
sessionId:
|
|
3754
|
-
parentArtifactId:
|
|
3755
|
-
permissions:
|
|
3756
|
-
canRead:
|
|
3757
|
-
canWrite:
|
|
3758
|
-
canDelete:
|
|
3759
|
-
isPublic:
|
|
3760
|
-
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)
|
|
3761
3661
|
}).optional(),
|
|
3762
|
-
metadata:
|
|
3662
|
+
metadata: z127.record(z127.unknown()).default({})
|
|
3763
3663
|
});
|
|
3764
3664
|
|
|
3765
3665
|
// ../../b4m-core/packages/services/dist/src/artifactService/get.js
|
|
3766
|
-
import { z as
|
|
3767
|
-
var getArtifactSchema =
|
|
3768
|
-
id:
|
|
3769
|
-
includeContent:
|
|
3770
|
-
includeVersions:
|
|
3771
|
-
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()
|
|
3772
3672
|
});
|
|
3773
3673
|
|
|
3774
3674
|
// ../../b4m-core/packages/services/dist/src/artifactService/list.js
|
|
3775
|
-
import { z as
|
|
3776
|
-
var listArtifactsSchema =
|
|
3777
|
-
type:
|
|
3778
|
-
status:
|
|
3779
|
-
visibility:
|
|
3780
|
-
projectId:
|
|
3781
|
-
sessionId:
|
|
3782
|
-
tags:
|
|
3783
|
-
search:
|
|
3784
|
-
limit:
|
|
3785
|
-
offset:
|
|
3786
|
-
sortBy:
|
|
3787
|
-
sortOrder:
|
|
3788
|
-
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)
|
|
3789
3689
|
});
|
|
3790
3690
|
|
|
3791
3691
|
// ../../b4m-core/packages/services/dist/src/artifactService/update.js
|
|
3792
|
-
import { z as
|
|
3793
|
-
var updateArtifactSchema =
|
|
3794
|
-
id:
|
|
3795
|
-
title:
|
|
3796
|
-
description:
|
|
3797
|
-
content:
|
|
3798
|
-
visibility:
|
|
3799
|
-
status:
|
|
3800
|
-
tags:
|
|
3801
|
-
versionTag:
|
|
3802
|
-
permissions:
|
|
3803
|
-
canRead:
|
|
3804
|
-
canWrite:
|
|
3805
|
-
canDelete:
|
|
3806
|
-
isPublic:
|
|
3807
|
-
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()
|
|
3808
3708
|
}).optional(),
|
|
3809
|
-
metadata:
|
|
3810
|
-
changes:
|
|
3811
|
-
changeDescription:
|
|
3812
|
-
createNewVersion:
|
|
3813
|
-
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()
|
|
3814
3714
|
});
|
|
3815
3715
|
|
|
3816
3716
|
// ../../b4m-core/packages/services/dist/src/artifactService/delete.js
|
|
3817
|
-
import { z as
|
|
3818
|
-
var deleteArtifactSchema =
|
|
3819
|
-
id:
|
|
3820
|
-
hardDelete:
|
|
3717
|
+
import { z as z131 } from "zod";
|
|
3718
|
+
var deleteArtifactSchema = z131.object({
|
|
3719
|
+
id: z131.string(),
|
|
3720
|
+
hardDelete: z131.boolean().default(false)
|
|
3821
3721
|
// For future implementation
|
|
3822
3722
|
});
|
|
3823
3723
|
|
|
3824
3724
|
// ../../b4m-core/packages/services/dist/src/questMasterService/create.js
|
|
3825
|
-
import { z as
|
|
3826
|
-
var questSchema =
|
|
3827
|
-
id:
|
|
3828
|
-
title:
|
|
3829
|
-
description:
|
|
3830
|
-
status:
|
|
3831
|
-
order:
|
|
3832
|
-
dependencies:
|
|
3833
|
-
estimatedTime:
|
|
3834
|
-
});
|
|
3835
|
-
var questResourceSchema =
|
|
3836
|
-
title:
|
|
3837
|
-
url:
|
|
3838
|
-
type:
|
|
3839
|
-
});
|
|
3840
|
-
var createQuestMasterSchema =
|
|
3841
|
-
title:
|
|
3842
|
-
description:
|
|
3843
|
-
goal:
|
|
3844
|
-
complexity:
|
|
3845
|
-
estimatedTotalTime:
|
|
3846
|
-
prerequisites:
|
|
3847
|
-
quests:
|
|
3848
|
-
resources:
|
|
3849
|
-
projectId:
|
|
3850
|
-
organizationId:
|
|
3851
|
-
visibility:
|
|
3852
|
-
tags:
|
|
3853
|
-
permissions:
|
|
3854
|
-
canRead:
|
|
3855
|
-
canWrite:
|
|
3856
|
-
canDelete:
|
|
3857
|
-
isPublic:
|
|
3858
|
-
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)
|
|
3859
3759
|
}).optional(),
|
|
3860
|
-
sourceQuestId:
|
|
3861
|
-
sessionId:
|
|
3862
|
-
metadata:
|
|
3760
|
+
sourceQuestId: z132.string().optional(),
|
|
3761
|
+
sessionId: z132.string().optional(),
|
|
3762
|
+
metadata: z132.record(z132.unknown()).default({})
|
|
3863
3763
|
});
|
|
3864
3764
|
|
|
3865
3765
|
// ../../b4m-core/packages/services/dist/src/questMasterService/updateQuestStatus.js
|
|
3866
|
-
import { z as
|
|
3867
|
-
var updateQuestStatusSchema =
|
|
3868
|
-
artifactId:
|
|
3869
|
-
questId:
|
|
3870
|
-
status:
|
|
3871
|
-
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()
|
|
3872
3772
|
});
|
|
3873
3773
|
|
|
3874
3774
|
// ../../b4m-core/packages/services/dist/src/dataLakeService/opensearchClient.js
|
|
@@ -3888,63 +3788,63 @@ import { v4 as uuidv44 } from "uuid";
|
|
|
3888
3788
|
import { randomUUID as randomUUID5 } from "crypto";
|
|
3889
3789
|
|
|
3890
3790
|
// ../../b4m-core/packages/services/dist/src/emailIngestionService/types.js
|
|
3891
|
-
import { z as
|
|
3892
|
-
var processIngestedEmailOptionsSchema =
|
|
3893
|
-
platformDomain:
|
|
3894
|
-
isNewsletter:
|
|
3791
|
+
import { z as z134 } from "zod";
|
|
3792
|
+
var processIngestedEmailOptionsSchema = z134.object({
|
|
3793
|
+
platformDomain: z134.string().optional(),
|
|
3794
|
+
isNewsletter: z134.boolean().optional()
|
|
3895
3795
|
}).optional();
|
|
3896
|
-
var emailAttachmentSchema =
|
|
3897
|
-
filename:
|
|
3898
|
-
contentType:
|
|
3899
|
-
contentDisposition:
|
|
3900
|
-
size:
|
|
3901
|
-
content:
|
|
3902
|
-
related:
|
|
3903
|
-
});
|
|
3904
|
-
var parsedEmailObjectSchema =
|
|
3905
|
-
messageId:
|
|
3906
|
-
inReplyTo:
|
|
3907
|
-
references:
|
|
3908
|
-
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(),
|
|
3909
3809
|
// Complex email address object
|
|
3910
|
-
to:
|
|
3911
|
-
cc:
|
|
3912
|
-
bcc:
|
|
3913
|
-
subject:
|
|
3914
|
-
date:
|
|
3915
|
-
text:
|
|
3916
|
-
html:
|
|
3917
|
-
attachments:
|
|
3918
|
-
});
|
|
3919
|
-
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({
|
|
3920
3820
|
parsedEmail: parsedEmailObjectSchema,
|
|
3921
|
-
rawEmailS3Key:
|
|
3821
|
+
rawEmailS3Key: z134.string().min(1, "rawEmailS3Key cannot be empty"),
|
|
3922
3822
|
options: processIngestedEmailOptionsSchema
|
|
3923
3823
|
});
|
|
3924
3824
|
|
|
3925
3825
|
// ../../b4m-core/packages/services/dist/src/emailAnalysisService/types.js
|
|
3926
|
-
import { z as
|
|
3927
|
-
var llmAnalysisResponseSchema =
|
|
3928
|
-
summary:
|
|
3929
|
-
entities:
|
|
3930
|
-
companies:
|
|
3931
|
-
people:
|
|
3932
|
-
products:
|
|
3933
|
-
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([])
|
|
3934
3834
|
}),
|
|
3935
|
-
sentiment:
|
|
3936
|
-
actionItems:
|
|
3937
|
-
description:
|
|
3938
|
-
deadline:
|
|
3835
|
+
sentiment: z135.enum(["positive", "neutral", "negative", "urgent"]),
|
|
3836
|
+
actionItems: z135.array(z135.object({
|
|
3837
|
+
description: z135.string(),
|
|
3838
|
+
deadline: z135.string().optional()
|
|
3939
3839
|
// ISO date string from LLM
|
|
3940
3840
|
})).default([]),
|
|
3941
|
-
privacyRecommendation:
|
|
3942
|
-
embargoDetected:
|
|
3943
|
-
suggestedTags:
|
|
3841
|
+
privacyRecommendation: z135.enum(["public", "team", "private"]),
|
|
3842
|
+
embargoDetected: z135.boolean().default(false),
|
|
3843
|
+
suggestedTags: z135.array(z135.string()).default([])
|
|
3944
3844
|
});
|
|
3945
3845
|
|
|
3946
3846
|
// ../../b4m-core/packages/services/dist/src/llm/ChatCompletion.js
|
|
3947
|
-
import { z as
|
|
3847
|
+
import { z as z137 } from "zod";
|
|
3948
3848
|
|
|
3949
3849
|
// ../../b4m-core/packages/services/dist/src/llm/ChatCompletionInvoke.js
|
|
3950
3850
|
import { fromZodError } from "zod-validation-error";
|
|
@@ -4058,8 +3958,8 @@ async function processAndStoreImages(images, context) {
|
|
|
4058
3958
|
const buffer = await downloadImage(image);
|
|
4059
3959
|
const fileType = await fileTypeFromBuffer2(buffer);
|
|
4060
3960
|
const filename = `${uuidv45()}.${fileType?.ext}`;
|
|
4061
|
-
const
|
|
4062
|
-
return
|
|
3961
|
+
const path11 = await context.imageGenerateStorage.upload(buffer, filename, {});
|
|
3962
|
+
return path11;
|
|
4063
3963
|
}));
|
|
4064
3964
|
}
|
|
4065
3965
|
async function updateQuestAndReturnMarkdown(storedImageUrls, context) {
|
|
@@ -5004,17 +4904,17 @@ var rechartsTool = {
|
|
|
5004
4904
|
};
|
|
5005
4905
|
|
|
5006
4906
|
// ../../b4m-core/packages/services/dist/src/llm/tools/implementation/editFile/index.js
|
|
5007
|
-
import { z as
|
|
4907
|
+
import { z as z136 } from "zod";
|
|
5008
4908
|
import { diffLines as diffLines2 } from "diff";
|
|
5009
|
-
var editFileSchema =
|
|
5010
|
-
fileId:
|
|
5011
|
-
instruction:
|
|
5012
|
-
selection:
|
|
5013
|
-
start:
|
|
5014
|
-
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")
|
|
5015
4915
|
}).optional().describe("Optional selection range to edit within the file"),
|
|
5016
|
-
preserveFormatting:
|
|
5017
|
-
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")
|
|
5018
4918
|
});
|
|
5019
4919
|
function generateSimpleDiff(original, modified) {
|
|
5020
4920
|
const differences = diffLines2(original, modified);
|
|
@@ -5243,8 +5143,8 @@ async function processAndStoreImage(imageUrl, context) {
|
|
|
5243
5143
|
const buffer = await downloadImage2(imageUrl);
|
|
5244
5144
|
const fileType = await fileTypeFromBuffer3(buffer);
|
|
5245
5145
|
const filename = `${uuidv46()}.${fileType?.ext}`;
|
|
5246
|
-
const
|
|
5247
|
-
return
|
|
5146
|
+
const path11 = await context.imageGenerateStorage.upload(buffer, filename, {});
|
|
5147
|
+
return path11;
|
|
5248
5148
|
}
|
|
5249
5149
|
async function updateQuestAndReturnMarkdown2(storedImagePath, context) {
|
|
5250
5150
|
await context.onFinish?.("edit_image", storedImagePath);
|
|
@@ -6773,8 +6673,8 @@ var getHeliocentricCoords = (planet, T) => {
|
|
|
6773
6673
|
const sinNode = Math.sin(longNode);
|
|
6774
6674
|
const x = r * (cosNode * cosOmega - sinNode * sinOmega * cosI);
|
|
6775
6675
|
const y = r * (sinNode * cosOmega + cosNode * sinOmega * cosI);
|
|
6776
|
-
const
|
|
6777
|
-
return { x, y, z:
|
|
6676
|
+
const z143 = r * sinOmega * sinI;
|
|
6677
|
+
return { x, y, z: z143, r };
|
|
6778
6678
|
};
|
|
6779
6679
|
var getGeocentricEcliptic = (planet, earth) => {
|
|
6780
6680
|
const dx = planet.x - earth.x;
|
|
@@ -7081,33 +6981,33 @@ var planetVisibilityTool = {
|
|
|
7081
6981
|
};
|
|
7082
6982
|
|
|
7083
6983
|
// ../../b4m-core/packages/services/dist/src/llm/tools/implementation/fileRead/index.js
|
|
7084
|
-
import { promises as
|
|
7085
|
-
import { existsSync as existsSync2, statSync
|
|
7086
|
-
import
|
|
7087
|
-
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;
|
|
7088
6988
|
async function readFileContent(params) {
|
|
7089
6989
|
const { path: filePath, encoding = "utf-8", maxLines } = params;
|
|
7090
|
-
const normalizedPath =
|
|
7091
|
-
const resolvedPath =
|
|
7092
|
-
const cwd =
|
|
6990
|
+
const normalizedPath = path4.normalize(filePath);
|
|
6991
|
+
const resolvedPath = path4.resolve(process.cwd(), normalizedPath);
|
|
6992
|
+
const cwd = path4.resolve(process.cwd());
|
|
7093
6993
|
if (!resolvedPath.startsWith(cwd)) {
|
|
7094
6994
|
throw new Error(`Access denied: Cannot read files outside of current working directory`);
|
|
7095
6995
|
}
|
|
7096
6996
|
if (!existsSync2(resolvedPath)) {
|
|
7097
6997
|
throw new Error(`File not found: ${filePath}`);
|
|
7098
6998
|
}
|
|
7099
|
-
const stats =
|
|
6999
|
+
const stats = statSync(resolvedPath);
|
|
7100
7000
|
if (stats.isDirectory()) {
|
|
7101
7001
|
throw new Error(`Path is a directory, not a file: ${filePath}`);
|
|
7102
7002
|
}
|
|
7103
|
-
if (stats.size >
|
|
7104
|
-
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)`);
|
|
7105
7005
|
}
|
|
7106
7006
|
const isBinary = await checkIfBinary(resolvedPath);
|
|
7107
7007
|
if (isBinary && encoding === "utf-8") {
|
|
7108
7008
|
throw new Error(`File appears to be binary. Use encoding 'base64' to read binary files, or specify a different encoding.`);
|
|
7109
7009
|
}
|
|
7110
|
-
const content = await
|
|
7010
|
+
const content = await fs5.readFile(resolvedPath, encoding);
|
|
7111
7011
|
if (maxLines && typeof content === "string") {
|
|
7112
7012
|
const lines = content.split("\n");
|
|
7113
7013
|
if (lines.length > maxLines) {
|
|
@@ -7122,7 +7022,7 @@ ${content}`;
|
|
|
7122
7022
|
}
|
|
7123
7023
|
async function checkIfBinary(filePath) {
|
|
7124
7024
|
const buffer = Buffer.alloc(8192);
|
|
7125
|
-
const fd = await
|
|
7025
|
+
const fd = await fs5.open(filePath, "r");
|
|
7126
7026
|
try {
|
|
7127
7027
|
const { bytesRead } = await fd.read(buffer, 0, 8192, 0);
|
|
7128
7028
|
const chunk = buffer.slice(0, bytesRead);
|
|
@@ -7139,7 +7039,7 @@ var fileReadTool = {
|
|
|
7139
7039
|
context.logger.info("\u{1F4C4} FileRead: Reading file", { path: params.path });
|
|
7140
7040
|
try {
|
|
7141
7041
|
const content = await readFileContent(params);
|
|
7142
|
-
const stats =
|
|
7042
|
+
const stats = statSync(path4.resolve(process.cwd(), path4.normalize(params.path)));
|
|
7143
7043
|
context.logger.info("\u2705 FileRead: Success", {
|
|
7144
7044
|
path: params.path,
|
|
7145
7045
|
size: stats.size,
|
|
@@ -7178,25 +7078,25 @@ var fileReadTool = {
|
|
|
7178
7078
|
};
|
|
7179
7079
|
|
|
7180
7080
|
// ../../b4m-core/packages/services/dist/src/llm/tools/implementation/createFile/index.js
|
|
7181
|
-
import { promises as
|
|
7081
|
+
import { promises as fs6 } from "fs";
|
|
7182
7082
|
import { existsSync as existsSync3 } from "fs";
|
|
7183
|
-
import
|
|
7083
|
+
import path5 from "path";
|
|
7184
7084
|
async function createFile(params) {
|
|
7185
7085
|
const { path: filePath, content, createDirectories = true } = params;
|
|
7186
|
-
const normalizedPath =
|
|
7187
|
-
const resolvedPath =
|
|
7188
|
-
const cwd =
|
|
7086
|
+
const normalizedPath = path5.normalize(filePath);
|
|
7087
|
+
const resolvedPath = path5.resolve(process.cwd(), normalizedPath);
|
|
7088
|
+
const cwd = path5.resolve(process.cwd());
|
|
7189
7089
|
if (!resolvedPath.startsWith(cwd)) {
|
|
7190
7090
|
throw new Error(`Access denied: Cannot create files outside of current working directory`);
|
|
7191
7091
|
}
|
|
7192
7092
|
const fileExists = existsSync3(resolvedPath);
|
|
7193
7093
|
const action = fileExists ? "overwritten" : "created";
|
|
7194
7094
|
if (createDirectories) {
|
|
7195
|
-
const dir =
|
|
7196
|
-
await
|
|
7095
|
+
const dir = path5.dirname(resolvedPath);
|
|
7096
|
+
await fs6.mkdir(dir, { recursive: true });
|
|
7197
7097
|
}
|
|
7198
|
-
await
|
|
7199
|
-
const stats = await
|
|
7098
|
+
await fs6.writeFile(resolvedPath, content, "utf-8");
|
|
7099
|
+
const stats = await fs6.stat(resolvedPath);
|
|
7200
7100
|
const lines = content.split("\n").length;
|
|
7201
7101
|
return `File ${action} successfully: ${filePath}
|
|
7202
7102
|
Size: ${stats.size} bytes
|
|
@@ -7207,7 +7107,7 @@ var createFileTool = {
|
|
|
7207
7107
|
implementation: (context) => ({
|
|
7208
7108
|
toolFn: async (value) => {
|
|
7209
7109
|
const params = value;
|
|
7210
|
-
const fileExists = existsSync3(
|
|
7110
|
+
const fileExists = existsSync3(path5.resolve(process.cwd(), path5.normalize(params.path)));
|
|
7211
7111
|
context.logger.info(`\u{1F4DD} CreateFile: ${fileExists ? "Overwriting" : "Creating"} file`, {
|
|
7212
7112
|
path: params.path,
|
|
7213
7113
|
size: params.content.length
|
|
@@ -7248,8 +7148,8 @@ var createFileTool = {
|
|
|
7248
7148
|
|
|
7249
7149
|
// ../../b4m-core/packages/services/dist/src/llm/tools/implementation/globFiles/index.js
|
|
7250
7150
|
import { readdir } from "fs/promises";
|
|
7251
|
-
import { statSync as
|
|
7252
|
-
import
|
|
7151
|
+
import { statSync as statSync2 } from "fs";
|
|
7152
|
+
import path6 from "path";
|
|
7253
7153
|
function matchGlob(filePath, pattern) {
|
|
7254
7154
|
let regexPattern = pattern.replace(/\./g, "\\.").replace(/\*\*/g, "{{GLOBSTAR}}").replace(/\*/g, "[^/]*").replace(/\?/g, ".").replace(/\{([^}]+)\}/g, (_, options) => `(${options.split(",").join("|")})`).replace(/\[([^\]]+)\]/g, "[$1]");
|
|
7255
7155
|
regexPattern = regexPattern.replace(/\{\{GLOBSTAR\}\}\//g, "(.*/)?").replace(/\/\{\{GLOBSTAR\}\}/g, "(/.*)?").replace(/\{\{GLOBSTAR\}\}/g, ".*");
|
|
@@ -7267,8 +7167,8 @@ async function walkDir(dir, pattern, includeHidden, maxResults, basePath = "") {
|
|
|
7267
7167
|
if (!includeHidden && entry.name.startsWith(".")) {
|
|
7268
7168
|
continue;
|
|
7269
7169
|
}
|
|
7270
|
-
const relativePath = basePath ?
|
|
7271
|
-
const fullPath =
|
|
7170
|
+
const relativePath = basePath ? path6.join(basePath, entry.name) : entry.name;
|
|
7171
|
+
const fullPath = path6.join(dir, entry.name);
|
|
7272
7172
|
if (matchGlob(relativePath, pattern)) {
|
|
7273
7173
|
matches.push(relativePath);
|
|
7274
7174
|
}
|
|
@@ -7284,7 +7184,7 @@ async function walkDir(dir, pattern, includeHidden, maxResults, basePath = "") {
|
|
|
7284
7184
|
async function listFiles(params) {
|
|
7285
7185
|
const { pattern, cwd: relativeCwd, includeHidden = false, maxResults = 1e3 } = params;
|
|
7286
7186
|
const baseCwd = process.cwd();
|
|
7287
|
-
const targetCwd = relativeCwd ?
|
|
7187
|
+
const targetCwd = relativeCwd ? path6.resolve(baseCwd, path6.normalize(relativeCwd)) : baseCwd;
|
|
7288
7188
|
if (!targetCwd.startsWith(baseCwd)) {
|
|
7289
7189
|
throw new Error(`Access denied: Cannot list files outside of current working directory`);
|
|
7290
7190
|
}
|
|
@@ -7295,8 +7195,8 @@ async function listFiles(params) {
|
|
|
7295
7195
|
const filesInfo = [];
|
|
7296
7196
|
for (const match of matches) {
|
|
7297
7197
|
try {
|
|
7298
|
-
const fullPath =
|
|
7299
|
-
const stats =
|
|
7198
|
+
const fullPath = path6.join(targetCwd, match);
|
|
7199
|
+
const stats = statSync2(fullPath);
|
|
7300
7200
|
filesInfo.push({
|
|
7301
7201
|
path: match,
|
|
7302
7202
|
size: stats.size,
|
|
@@ -7377,9 +7277,9 @@ var globFilesTool = {
|
|
|
7377
7277
|
|
|
7378
7278
|
// ../../b4m-core/packages/services/dist/src/llm/tools/implementation/grepSearch/index.js
|
|
7379
7279
|
import { readdir as readdir2 } from "fs/promises";
|
|
7380
|
-
import { readFileSync
|
|
7381
|
-
import
|
|
7382
|
-
var
|
|
7280
|
+
import { readFileSync, statSync as statSync3 } from "fs";
|
|
7281
|
+
import path7 from "path";
|
|
7282
|
+
var MAX_FILE_SIZE2 = 10 * 1024 * 1024;
|
|
7383
7283
|
function matchGlob2(filePath, pattern) {
|
|
7384
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]");
|
|
7385
7285
|
const regex = new RegExp(`^${regexPattern}$`);
|
|
@@ -7396,8 +7296,8 @@ async function walkDir2(dir, pattern, maxResults, basePath = "") {
|
|
|
7396
7296
|
if (entry.name.startsWith(".")) {
|
|
7397
7297
|
continue;
|
|
7398
7298
|
}
|
|
7399
|
-
const relativePath = basePath ?
|
|
7400
|
-
const fullPath =
|
|
7299
|
+
const relativePath = basePath ? path7.join(basePath, entry.name) : entry.name;
|
|
7300
|
+
const fullPath = path7.join(dir, entry.name);
|
|
7401
7301
|
if (matchGlob2(relativePath, pattern)) {
|
|
7402
7302
|
matches.push(relativePath);
|
|
7403
7303
|
}
|
|
@@ -7410,10 +7310,10 @@ async function walkDir2(dir, pattern, maxResults, basePath = "") {
|
|
|
7410
7310
|
}
|
|
7411
7311
|
return matches;
|
|
7412
7312
|
}
|
|
7413
|
-
async function
|
|
7313
|
+
async function searchFiles(params) {
|
|
7414
7314
|
const { pattern, filePattern = "**/*", cwd: relativeCwd, caseSensitive = false, maxResults = 100, contextLines = 0 } = params;
|
|
7415
7315
|
const baseCwd = process.cwd();
|
|
7416
|
-
const targetCwd = relativeCwd ?
|
|
7316
|
+
const targetCwd = relativeCwd ? path7.resolve(baseCwd, path7.normalize(relativeCwd)) : baseCwd;
|
|
7417
7317
|
if (!targetCwd.startsWith(baseCwd)) {
|
|
7418
7318
|
throw new Error(`Access denied: Cannot search files outside of current working directory`);
|
|
7419
7319
|
}
|
|
@@ -7427,13 +7327,13 @@ async function searchFiles2(params) {
|
|
|
7427
7327
|
const filesToSearch = await walkDir2(targetCwd, filePattern, 1e4);
|
|
7428
7328
|
const filteredFiles = [];
|
|
7429
7329
|
for (const match of filesToSearch) {
|
|
7430
|
-
const fullPath =
|
|
7330
|
+
const fullPath = path7.join(targetCwd, match);
|
|
7431
7331
|
try {
|
|
7432
|
-
const stats =
|
|
7433
|
-
if (stats.isDirectory() || stats.size >
|
|
7332
|
+
const stats = statSync3(fullPath);
|
|
7333
|
+
if (stats.isDirectory() || stats.size > MAX_FILE_SIZE2) {
|
|
7434
7334
|
continue;
|
|
7435
7335
|
}
|
|
7436
|
-
if (
|
|
7336
|
+
if (isBinaryFile(fullPath)) {
|
|
7437
7337
|
continue;
|
|
7438
7338
|
}
|
|
7439
7339
|
filteredFiles.push(match);
|
|
@@ -7451,9 +7351,9 @@ async function searchFiles2(params) {
|
|
|
7451
7351
|
break;
|
|
7452
7352
|
}
|
|
7453
7353
|
filesSearched++;
|
|
7454
|
-
const fullPath =
|
|
7354
|
+
const fullPath = path7.join(targetCwd, file);
|
|
7455
7355
|
try {
|
|
7456
|
-
const content =
|
|
7356
|
+
const content = readFileSync(fullPath, "utf-8");
|
|
7457
7357
|
const lines = content.split("\n");
|
|
7458
7358
|
for (let i = 0; i < lines.length; i++) {
|
|
7459
7359
|
if (matches.length >= maxResults) {
|
|
@@ -7517,7 +7417,7 @@ ${match.context.after.map((l) => ` ${l}`).join("\n")}`;
|
|
|
7517
7417
|
}).join("\n");
|
|
7518
7418
|
return `${summary}${patternInfo}${cwdInfo}${matchesList}`;
|
|
7519
7419
|
}
|
|
7520
|
-
function
|
|
7420
|
+
function isBinaryFile(filePath) {
|
|
7521
7421
|
try {
|
|
7522
7422
|
const buffer = Buffer.alloc(8192);
|
|
7523
7423
|
const fd = __require("fs").openSync(filePath, "r");
|
|
@@ -7540,7 +7440,7 @@ var grepSearchTool = {
|
|
|
7540
7440
|
cwd: params.cwd || "."
|
|
7541
7441
|
});
|
|
7542
7442
|
try {
|
|
7543
|
-
const result = await
|
|
7443
|
+
const result = await searchFiles(params);
|
|
7544
7444
|
context.logger.info("\u2705 GrepSearch: Success");
|
|
7545
7445
|
return result;
|
|
7546
7446
|
} catch (error) {
|
|
@@ -7586,31 +7486,31 @@ var grepSearchTool = {
|
|
|
7586
7486
|
};
|
|
7587
7487
|
|
|
7588
7488
|
// ../../b4m-core/packages/services/dist/src/llm/tools/implementation/deleteFile/index.js
|
|
7589
|
-
import { promises as
|
|
7590
|
-
import { existsSync as existsSync4, statSync as
|
|
7591
|
-
import
|
|
7489
|
+
import { promises as fs7 } from "fs";
|
|
7490
|
+
import { existsSync as existsSync4, statSync as statSync4 } from "fs";
|
|
7491
|
+
import path8 from "path";
|
|
7592
7492
|
async function deleteFile(params) {
|
|
7593
7493
|
const { path: filePath, recursive = false } = params;
|
|
7594
|
-
const normalizedPath =
|
|
7595
|
-
const resolvedPath =
|
|
7596
|
-
const cwd =
|
|
7494
|
+
const normalizedPath = path8.normalize(filePath);
|
|
7495
|
+
const resolvedPath = path8.resolve(process.cwd(), normalizedPath);
|
|
7496
|
+
const cwd = path8.resolve(process.cwd());
|
|
7597
7497
|
if (!resolvedPath.startsWith(cwd)) {
|
|
7598
7498
|
throw new Error(`Access denied: Cannot delete files outside of current working directory`);
|
|
7599
7499
|
}
|
|
7600
7500
|
if (!existsSync4(resolvedPath)) {
|
|
7601
7501
|
throw new Error(`File or directory not found: ${filePath}`);
|
|
7602
7502
|
}
|
|
7603
|
-
const stats =
|
|
7503
|
+
const stats = statSync4(resolvedPath);
|
|
7604
7504
|
const isDirectory = stats.isDirectory();
|
|
7605
7505
|
const size = stats.size;
|
|
7606
7506
|
if (isDirectory && !recursive) {
|
|
7607
7507
|
throw new Error(`Path is a directory: ${filePath}. Use recursive=true to delete directories and their contents.`);
|
|
7608
7508
|
}
|
|
7609
7509
|
if (isDirectory) {
|
|
7610
|
-
await
|
|
7510
|
+
await fs7.rm(resolvedPath, { recursive: true, force: true });
|
|
7611
7511
|
return `Directory deleted successfully: ${filePath}`;
|
|
7612
7512
|
} else {
|
|
7613
|
-
await
|
|
7513
|
+
await fs7.unlink(resolvedPath);
|
|
7614
7514
|
return `File deleted successfully: ${filePath}
|
|
7615
7515
|
Size: ${size} bytes`;
|
|
7616
7516
|
}
|
|
@@ -7620,8 +7520,8 @@ var deleteFileTool = {
|
|
|
7620
7520
|
implementation: (context) => ({
|
|
7621
7521
|
toolFn: async (value) => {
|
|
7622
7522
|
const params = value;
|
|
7623
|
-
const resolvedPath =
|
|
7624
|
-
const isDirectory = existsSync4(resolvedPath) &&
|
|
7523
|
+
const resolvedPath = path8.resolve(process.cwd(), path8.normalize(params.path));
|
|
7524
|
+
const isDirectory = existsSync4(resolvedPath) && statSync4(resolvedPath).isDirectory();
|
|
7625
7525
|
context.logger.info(`\u{1F5D1}\uFE0F DeleteFile: Deleting ${isDirectory ? "directory" : "file"}`, {
|
|
7626
7526
|
path: params.path,
|
|
7627
7527
|
recursive: params.recursive
|
|
@@ -7799,42 +7699,42 @@ var DISABLE_SERVER_THROTTLING = process.env.DISABLE_SERVER_THROTTLING === "true"
|
|
|
7799
7699
|
var questSaveMutex = new Mutex();
|
|
7800
7700
|
|
|
7801
7701
|
// ../../b4m-core/packages/services/dist/src/llm/ChatCompletion.js
|
|
7802
|
-
var QuestStartBodySchema =
|
|
7803
|
-
userId:
|
|
7804
|
-
sessionId:
|
|
7805
|
-
questId:
|
|
7806
|
-
message:
|
|
7807
|
-
messageFileIds:
|
|
7808
|
-
historyCount:
|
|
7809
|
-
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()),
|
|
7810
7710
|
params: ChatCompletionCreateInputSchema,
|
|
7811
7711
|
dashboardParams: DashboardParamsSchema.optional(),
|
|
7812
|
-
enableQuestMaster:
|
|
7813
|
-
enableMementos:
|
|
7814
|
-
enableArtifacts:
|
|
7815
|
-
enableAgents:
|
|
7712
|
+
enableQuestMaster: z137.boolean().optional(),
|
|
7713
|
+
enableMementos: z137.boolean().optional(),
|
|
7714
|
+
enableArtifacts: z137.boolean().optional(),
|
|
7715
|
+
enableAgents: z137.boolean().optional(),
|
|
7816
7716
|
promptMeta: PromptMetaZodSchema,
|
|
7817
|
-
tools:
|
|
7818
|
-
mcpServers:
|
|
7819
|
-
projectId:
|
|
7820
|
-
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(),
|
|
7821
7721
|
questMaster: QuestMasterParamsSchema.optional(),
|
|
7822
|
-
toolPromptId:
|
|
7722
|
+
toolPromptId: z137.string().optional(),
|
|
7823
7723
|
researchMode: ResearchModeParamsSchema.optional(),
|
|
7824
|
-
fallbackModel:
|
|
7825
|
-
embeddingModel:
|
|
7826
|
-
queryComplexity:
|
|
7724
|
+
fallbackModel: z137.string().optional(),
|
|
7725
|
+
embeddingModel: z137.string().optional(),
|
|
7726
|
+
queryComplexity: z137.string(),
|
|
7827
7727
|
imageConfig: GenerateImageToolCallSchema.optional(),
|
|
7828
|
-
deepResearchConfig:
|
|
7829
|
-
maxDepth:
|
|
7830
|
-
duration:
|
|
7728
|
+
deepResearchConfig: z137.object({
|
|
7729
|
+
maxDepth: z137.number().optional(),
|
|
7730
|
+
duration: z137.number().optional(),
|
|
7831
7731
|
// Note: searchers are passed via ToolContext and not through this API schema
|
|
7832
|
-
searchers:
|
|
7732
|
+
searchers: z137.array(z137.any()).optional()
|
|
7833
7733
|
}).optional(),
|
|
7834
|
-
extraContextMessages:
|
|
7835
|
-
role:
|
|
7836
|
-
content:
|
|
7837
|
-
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()
|
|
7838
7738
|
})).optional()
|
|
7839
7739
|
});
|
|
7840
7740
|
|
|
@@ -7842,9 +7742,30 @@ var QuestStartBodySchema = z138.object({
|
|
|
7842
7742
|
import axios8 from "axios";
|
|
7843
7743
|
import { fileTypeFromBuffer as fileTypeFromBuffer4 } from "file-type";
|
|
7844
7744
|
import { v4 as uuidv47 } from "uuid";
|
|
7845
|
-
import { z as
|
|
7745
|
+
import { z as z138 } from "zod";
|
|
7846
7746
|
import { fromZodError as fromZodError2 } from "zod-validation-error";
|
|
7847
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({
|
|
7848
7769
|
sessionId: z139.string(),
|
|
7849
7770
|
questId: z139.string(),
|
|
7850
7771
|
userId: z139.string(),
|
|
@@ -7852,56 +7773,35 @@ var ImageGenerationBodySchema = OpenAIImageGenerationInput.extend({
|
|
|
7852
7773
|
safety_tolerance: z139.number().min(BFL_SAFETY_TOLERANCE.MIN).max(BFL_SAFETY_TOLERANCE.MAX).optional().default(BFL_SAFETY_TOLERANCE.DEFAULT),
|
|
7853
7774
|
prompt_upsampling: z139.boolean().optional().default(false),
|
|
7854
7775
|
seed: z139.number().nullable().optional(),
|
|
7855
|
-
output_format: z139.enum(["jpeg", "png"]).
|
|
7776
|
+
output_format: z139.enum(["jpeg", "png"]).optional().default("png"),
|
|
7856
7777
|
width: z139.number().optional(),
|
|
7857
7778
|
height: z139.number().optional(),
|
|
7858
7779
|
aspect_ratio: z139.string().optional(),
|
|
7859
|
-
|
|
7860
|
-
|
|
7861
|
-
|
|
7862
|
-
// ../../b4m-core/packages/services/dist/src/llm/ImageEdit.js
|
|
7863
|
-
import axios9 from "axios";
|
|
7864
|
-
import { fileTypeFromBuffer as fileTypeFromBuffer5 } from "file-type";
|
|
7865
|
-
import { v4 as uuidv48 } from "uuid";
|
|
7866
|
-
import { z as z140 } from "zod";
|
|
7867
|
-
import { fromZodError as fromZodError3 } from "zod-validation-error";
|
|
7868
|
-
var ImageEditBodySchema = OpenAIImageGenerationInput.extend({
|
|
7869
|
-
sessionId: z140.string(),
|
|
7870
|
-
questId: z140.string(),
|
|
7871
|
-
userId: z140.string(),
|
|
7872
|
-
prompt: z140.string(),
|
|
7873
|
-
safety_tolerance: z140.number().min(BFL_SAFETY_TOLERANCE.MIN).max(BFL_SAFETY_TOLERANCE.MAX).optional().default(BFL_SAFETY_TOLERANCE.DEFAULT),
|
|
7874
|
-
prompt_upsampling: z140.boolean().optional().default(false),
|
|
7875
|
-
seed: z140.number().nullable().optional(),
|
|
7876
|
-
output_format: z140.enum(["jpeg", "png"]).optional().default("png"),
|
|
7877
|
-
width: z140.number().optional(),
|
|
7878
|
-
height: z140.number().optional(),
|
|
7879
|
-
aspect_ratio: z140.string().optional(),
|
|
7880
|
-
size: z140.string().optional(),
|
|
7881
|
-
fabFileIds: z140.array(z140.string()).optional(),
|
|
7882
|
-
image: z140.string()
|
|
7780
|
+
size: z139.string().optional(),
|
|
7781
|
+
fabFileIds: z139.array(z139.string()).optional(),
|
|
7782
|
+
image: z139.string()
|
|
7883
7783
|
});
|
|
7884
7784
|
|
|
7885
7785
|
// ../../b4m-core/packages/services/dist/src/llm/refineText.js
|
|
7886
|
-
import { z as
|
|
7887
|
-
var refineTextLLMSchema =
|
|
7888
|
-
text:
|
|
7889
|
-
context:
|
|
7786
|
+
import { z as z140 } from "zod";
|
|
7787
|
+
var refineTextLLMSchema = z140.object({
|
|
7788
|
+
text: z140.string(),
|
|
7789
|
+
context: z140.string().optional()
|
|
7890
7790
|
// tone: z.enum(['formal', 'informal', 'neutral']).optional(),
|
|
7891
7791
|
// style: z.enum(['technical', 'creative', 'academic', 'business', 'narrative']).optional(),
|
|
7892
7792
|
});
|
|
7893
7793
|
|
|
7894
7794
|
// ../../b4m-core/packages/services/dist/src/llm/MementoEvaluationService.js
|
|
7895
|
-
import { z as
|
|
7896
|
-
var SingleMementoEvalSchema =
|
|
7897
|
-
importance:
|
|
7795
|
+
import { z as z141 } from "zod";
|
|
7796
|
+
var SingleMementoEvalSchema = z141.object({
|
|
7797
|
+
importance: z141.number().min(1).max(10),
|
|
7898
7798
|
// 1-10 scale for personal info importance
|
|
7899
|
-
summary:
|
|
7900
|
-
tags:
|
|
7799
|
+
summary: z141.string(),
|
|
7800
|
+
tags: z141.array(z141.string()).optional()
|
|
7901
7801
|
});
|
|
7902
|
-
var MementoEvalResponseSchema =
|
|
7903
|
-
isPersonal:
|
|
7904
|
-
mementos:
|
|
7802
|
+
var MementoEvalResponseSchema = z141.object({
|
|
7803
|
+
isPersonal: z141.boolean(),
|
|
7804
|
+
mementos: z141.array(SingleMementoEvalSchema).optional()
|
|
7905
7805
|
// Array of distinct personal information
|
|
7906
7806
|
});
|
|
7907
7807
|
|
|
@@ -7947,7 +7847,7 @@ async function generateFileDeletePreview(args) {
|
|
|
7947
7847
|
if (!existsSync5(args.path)) {
|
|
7948
7848
|
return `[File does not exist: ${args.path}]`;
|
|
7949
7849
|
}
|
|
7950
|
-
const stats = await import("fs/promises").then((
|
|
7850
|
+
const stats = await import("fs/promises").then((fs9) => fs9.stat(args.path));
|
|
7951
7851
|
return `[File will be deleted]
|
|
7952
7852
|
|
|
7953
7853
|
Path: ${args.path}
|
|
@@ -7963,21 +7863,21 @@ var NoOpStorage = class extends BaseStorage {
|
|
|
7963
7863
|
async upload(input, destination, options) {
|
|
7964
7864
|
return `/tmp/${destination}`;
|
|
7965
7865
|
}
|
|
7966
|
-
async download(
|
|
7866
|
+
async download(path11) {
|
|
7967
7867
|
throw new Error("Download not supported in CLI");
|
|
7968
7868
|
}
|
|
7969
|
-
async delete(
|
|
7869
|
+
async delete(path11) {
|
|
7970
7870
|
}
|
|
7971
|
-
async getSignedUrl(
|
|
7972
|
-
return `/tmp/${
|
|
7871
|
+
async getSignedUrl(path11) {
|
|
7872
|
+
return `/tmp/${path11}`;
|
|
7973
7873
|
}
|
|
7974
|
-
getPublicUrl(
|
|
7975
|
-
return `/tmp/${
|
|
7874
|
+
getPublicUrl(path11) {
|
|
7875
|
+
return `/tmp/${path11}`;
|
|
7976
7876
|
}
|
|
7977
|
-
async getPreview(
|
|
7978
|
-
return `/tmp/${
|
|
7877
|
+
async getPreview(path11) {
|
|
7878
|
+
return `/tmp/${path11}`;
|
|
7979
7879
|
}
|
|
7980
|
-
async getMetadata(
|
|
7880
|
+
async getMetadata(path11) {
|
|
7981
7881
|
return { size: 0, contentType: "application/octet-stream" };
|
|
7982
7882
|
}
|
|
7983
7883
|
};
|
|
@@ -7997,7 +7897,7 @@ var CliLogger = class extends Logger {
|
|
|
7997
7897
|
log(...args) {
|
|
7998
7898
|
}
|
|
7999
7899
|
};
|
|
8000
|
-
function wrapToolWithPermission(tool, permissionManager, showPermissionPrompt, agentContext) {
|
|
7900
|
+
function wrapToolWithPermission(tool, permissionManager, showPermissionPrompt, agentContext, configStore) {
|
|
8001
7901
|
const originalFn = tool.toolFn;
|
|
8002
7902
|
const toolName = tool.toolSchema.name;
|
|
8003
7903
|
return {
|
|
@@ -8041,7 +7941,25 @@ function wrapToolWithPermission(tool, permissionManager, showPermissionPrompt, a
|
|
|
8041
7941
|
throw new PermissionDeniedError(toolName, args);
|
|
8042
7942
|
}
|
|
8043
7943
|
if (response.action === "allow-always") {
|
|
8044
|
-
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
|
+
}
|
|
8045
7963
|
}
|
|
8046
7964
|
const result = await originalFn(args);
|
|
8047
7965
|
agentContext.observationQueue.push({ toolName, result });
|
|
@@ -8049,7 +7967,7 @@ function wrapToolWithPermission(tool, permissionManager, showPermissionPrompt, a
|
|
|
8049
7967
|
}
|
|
8050
7968
|
};
|
|
8051
7969
|
}
|
|
8052
|
-
function generateCliTools(userId, llm, model, permissionManager, showPermissionPrompt, agentContext, toolApiKeys) {
|
|
7970
|
+
function generateCliTools(userId, llm, model, permissionManager, showPermissionPrompt, agentContext, configStore, toolApiKeys) {
|
|
8053
7971
|
const logger2 = new CliLogger();
|
|
8054
7972
|
const storage = new NoOpStorage();
|
|
8055
7973
|
const user = {
|
|
@@ -8133,13 +8051,15 @@ function generateCliTools(userId, llm, model, permissionManager, showPermissionP
|
|
|
8133
8051
|
toolConfig,
|
|
8134
8052
|
model
|
|
8135
8053
|
);
|
|
8136
|
-
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
|
+
);
|
|
8137
8057
|
return { tools: tools2, agentContext };
|
|
8138
8058
|
}
|
|
8139
8059
|
|
|
8140
8060
|
// src/config/toolSafety.ts
|
|
8141
|
-
import { z as
|
|
8142
|
-
var ToolCategorySchema =
|
|
8061
|
+
import { z as z142 } from "zod";
|
|
8062
|
+
var ToolCategorySchema = z142.enum([
|
|
8143
8063
|
"auto_approve",
|
|
8144
8064
|
// Safe tools that run automatically without permission
|
|
8145
8065
|
"prompt_always",
|
|
@@ -8147,9 +8067,9 @@ var ToolCategorySchema = z143.enum([
|
|
|
8147
8067
|
"prompt_default"
|
|
8148
8068
|
// Tools that prompt by default but can be trusted
|
|
8149
8069
|
]);
|
|
8150
|
-
var ToolSafetyConfigSchema =
|
|
8151
|
-
categories:
|
|
8152
|
-
trustedTools:
|
|
8070
|
+
var ToolSafetyConfigSchema = z142.object({
|
|
8071
|
+
categories: z142.record(z142.string(), ToolCategorySchema),
|
|
8072
|
+
trustedTools: z142.array(z142.string())
|
|
8153
8073
|
});
|
|
8154
8074
|
var DEFAULT_TOOL_CATEGORIES = {
|
|
8155
8075
|
// ===== AUTO APPROVE (Safe tools) =====
|
|
@@ -8198,23 +8118,30 @@ function canTrustTool(toolName, customCategories) {
|
|
|
8198
8118
|
|
|
8199
8119
|
// src/utils/PermissionManager.ts
|
|
8200
8120
|
var PermissionManager = class {
|
|
8201
|
-
constructor(trustedTools = [], customCategories) {
|
|
8121
|
+
constructor(trustedTools = [], customCategories, deniedTools) {
|
|
8202
8122
|
this.trustedTools = /* @__PURE__ */ new Set();
|
|
8123
|
+
this.deniedTools = /* @__PURE__ */ new Set();
|
|
8203
8124
|
this.trustedTools = new Set(trustedTools);
|
|
8204
8125
|
this.customCategories = new Map(Object.entries(customCategories || {}));
|
|
8126
|
+
this.deniedTools = new Set(deniedTools || []);
|
|
8205
8127
|
}
|
|
8206
8128
|
/**
|
|
8207
8129
|
* Check if a tool needs permission before execution
|
|
8208
8130
|
*
|
|
8209
8131
|
* A tool needs permission if:
|
|
8210
|
-
* 1. It's
|
|
8211
|
-
* 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
|
|
8212
8135
|
*
|
|
8213
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)
|
|
8214
8138
|
*/
|
|
8215
8139
|
needsPermission(toolName) {
|
|
8216
8140
|
const categoryMap = Object.fromEntries(this.customCategories);
|
|
8217
8141
|
const category = getToolCategory(toolName, categoryMap);
|
|
8142
|
+
if (this.deniedTools.has(toolName)) {
|
|
8143
|
+
return true;
|
|
8144
|
+
}
|
|
8218
8145
|
if (category === "auto_approve") {
|
|
8219
8146
|
return false;
|
|
8220
8147
|
}
|
|
@@ -8225,10 +8152,13 @@ var PermissionManager = class {
|
|
|
8225
8152
|
}
|
|
8226
8153
|
/**
|
|
8227
8154
|
* Add a tool to the trusted list
|
|
8228
|
-
* 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)
|
|
8229
8156
|
*/
|
|
8230
8157
|
trustTool(toolName) {
|
|
8231
8158
|
const categoryMap = Object.fromEntries(this.customCategories);
|
|
8159
|
+
if (this.deniedTools.has(toolName)) {
|
|
8160
|
+
return false;
|
|
8161
|
+
}
|
|
8232
8162
|
if (!canTrustTool(toolName, categoryMap)) {
|
|
8233
8163
|
return false;
|
|
8234
8164
|
}
|
|
@@ -8261,12 +8191,27 @@ var PermissionManager = class {
|
|
|
8261
8191
|
return getToolCategory(toolName, categoryMap);
|
|
8262
8192
|
}
|
|
8263
8193
|
/**
|
|
8264
|
-
* 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)
|
|
8265
8195
|
*/
|
|
8266
8196
|
canBeTrusted(toolName) {
|
|
8267
8197
|
const categoryMap = Object.fromEntries(this.customCategories);
|
|
8198
|
+
if (this.deniedTools.has(toolName)) {
|
|
8199
|
+
return false;
|
|
8200
|
+
}
|
|
8268
8201
|
return canTrustTool(toolName, categoryMap);
|
|
8269
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
|
+
}
|
|
8270
8215
|
/**
|
|
8271
8216
|
* Clear all trusted tools
|
|
8272
8217
|
*/
|
|
@@ -8303,8 +8248,8 @@ function getEnvironmentName(configApiConfig) {
|
|
|
8303
8248
|
}
|
|
8304
8249
|
|
|
8305
8250
|
// src/utils/Logger.ts
|
|
8306
|
-
import
|
|
8307
|
-
import
|
|
8251
|
+
import fs8 from "fs/promises";
|
|
8252
|
+
import path9 from "path";
|
|
8308
8253
|
import os from "os";
|
|
8309
8254
|
var Logger2 = class _Logger {
|
|
8310
8255
|
constructor() {
|
|
@@ -8327,9 +8272,9 @@ var Logger2 = class _Logger {
|
|
|
8327
8272
|
*/
|
|
8328
8273
|
async initialize(sessionId) {
|
|
8329
8274
|
this.sessionId = sessionId;
|
|
8330
|
-
const debugDir =
|
|
8331
|
-
await
|
|
8332
|
-
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`);
|
|
8333
8278
|
await this.writeToFile("INFO", "=== CLI SESSION START ===");
|
|
8334
8279
|
}
|
|
8335
8280
|
/**
|
|
@@ -8393,7 +8338,7 @@ var Logger2 = class _Logger {
|
|
|
8393
8338
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").substring(0, 19);
|
|
8394
8339
|
const logEntry = `[${timestamp}] [${level}] ${message}
|
|
8395
8340
|
`;
|
|
8396
|
-
await
|
|
8341
|
+
await fs8.appendFile(this.logFilePath, logEntry, "utf-8");
|
|
8397
8342
|
} catch (error) {
|
|
8398
8343
|
console.error("File logging failed:", error);
|
|
8399
8344
|
}
|
|
@@ -8539,15 +8484,15 @@ var Logger2 = class _Logger {
|
|
|
8539
8484
|
async cleanupOldLogs() {
|
|
8540
8485
|
if (!this.fileLoggingEnabled) return;
|
|
8541
8486
|
try {
|
|
8542
|
-
const debugDir =
|
|
8543
|
-
const files = await
|
|
8487
|
+
const debugDir = path9.join(os.homedir(), ".bike4mind", "debug");
|
|
8488
|
+
const files = await fs8.readdir(debugDir);
|
|
8544
8489
|
const now = Date.now();
|
|
8545
8490
|
const thirtyDaysAgo = now - 30 * 24 * 60 * 60 * 1e3;
|
|
8546
8491
|
for (const file of files) {
|
|
8547
|
-
const filePath =
|
|
8548
|
-
const stats = await
|
|
8492
|
+
const filePath = path9.join(debugDir, file);
|
|
8493
|
+
const stats = await fs8.stat(filePath);
|
|
8549
8494
|
if (stats.mtime.getTime() < thirtyDaysAgo) {
|
|
8550
|
-
await
|
|
8495
|
+
await fs8.unlink(filePath);
|
|
8551
8496
|
}
|
|
8552
8497
|
}
|
|
8553
8498
|
} catch (error) {
|
|
@@ -8560,8 +8505,8 @@ var logger = Logger2.getInstance();
|
|
|
8560
8505
|
// ../../b4m-core/packages/mcp/dist/src/client.js
|
|
8561
8506
|
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
|
|
8562
8507
|
import { Client as Client2 } from "@modelcontextprotocol/sdk/client/index.js";
|
|
8563
|
-
import
|
|
8564
|
-
import { existsSync as existsSync6, readdirSync
|
|
8508
|
+
import path10 from "path";
|
|
8509
|
+
import { existsSync as existsSync6, readdirSync } from "fs";
|
|
8565
8510
|
var MCPClient = class {
|
|
8566
8511
|
// Note: This class handles MCP server communication with repository filtering
|
|
8567
8512
|
mcp;
|
|
@@ -8586,20 +8531,20 @@ var MCPClient = class {
|
|
|
8586
8531
|
const root = process.env.INIT_CWD || process.cwd();
|
|
8587
8532
|
const candidatePaths = [
|
|
8588
8533
|
// When running from SST Lambda with node_modules structure (copyFiles)
|
|
8589
|
-
|
|
8534
|
+
path10.join(root, `node_modules/@bike4mind/mcp/dist/src/${this.serverName}/index.js`),
|
|
8590
8535
|
// When running from SST Lambda deployed environment (/var/task)
|
|
8591
|
-
|
|
8536
|
+
path10.join(root, `b4m-core/packages/mcp/dist/src/${this.serverName}/index.js`),
|
|
8592
8537
|
// When running from SST Lambda (.sst/artifacts/mcpHandler-dev), navigate to monorepo root (3 levels up)
|
|
8593
|
-
|
|
8538
|
+
path10.join(root, `../../../b4m-core/packages/mcp/dist/src/${this.serverName}/index.js`),
|
|
8594
8539
|
// When running from packages/client (Next.js app), navigate to monorepo root (2 levels up)
|
|
8595
|
-
|
|
8540
|
+
path10.join(root, `../../b4m-core/packages/mcp/dist/src/${this.serverName}/index.js`),
|
|
8596
8541
|
// Original paths (backward compatibility)
|
|
8597
|
-
|
|
8598
|
-
|
|
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")
|
|
8599
8544
|
];
|
|
8600
8545
|
const serverScriptPath = candidatePaths.find((p) => existsSync6(p));
|
|
8601
8546
|
if (!serverScriptPath) {
|
|
8602
|
-
const getDirectories = (source) =>
|
|
8547
|
+
const getDirectories = (source) => readdirSync(source, { withFileTypes: true }).filter((dirent) => dirent.isDirectory()).map((dirent) => dirent.name);
|
|
8603
8548
|
console.error(`[MCP] Server script not found. Tried paths:`, candidatePaths);
|
|
8604
8549
|
console.error(`[MCP] Available directories in ${root}:`, getDirectories(root));
|
|
8605
8550
|
throw new Error(`MCP Server script path not found for ${this.serverName}. Root: ${root}, Available dirs: ${getDirectories(root).join(", ")}`);
|
|
@@ -8628,7 +8573,7 @@ var MCPClient = class {
|
|
|
8628
8573
|
}
|
|
8629
8574
|
};
|
|
8630
8575
|
await this.mcp.connect(this.transport);
|
|
8631
|
-
await new Promise((
|
|
8576
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
8632
8577
|
const toolsResult = await this.mcp.listTools();
|
|
8633
8578
|
this.tools = toolsResult.tools.map((tool) => {
|
|
8634
8579
|
return {
|
|
@@ -8811,7 +8756,7 @@ var ServerLlmBackend = class {
|
|
|
8811
8756
|
*/
|
|
8812
8757
|
async complete(model, messages, options, callback) {
|
|
8813
8758
|
logger.debug(`[ServerLlmBackend] Starting complete() with model: ${model}`);
|
|
8814
|
-
return new Promise(async (
|
|
8759
|
+
return new Promise(async (resolve, reject) => {
|
|
8815
8760
|
try {
|
|
8816
8761
|
logger.debug("[ServerLlmBackend] Making streaming request...");
|
|
8817
8762
|
const response = await this.makeStreamingRequest(model, messages, options);
|
|
@@ -8841,15 +8786,15 @@ var ServerLlmBackend = class {
|
|
|
8841
8786
|
reject(err);
|
|
8842
8787
|
}).then(() => {
|
|
8843
8788
|
logger.debug("[ServerLlmBackend] Callback completed, resolving");
|
|
8844
|
-
|
|
8789
|
+
resolve();
|
|
8845
8790
|
});
|
|
8846
8791
|
} else if (cleanedText) {
|
|
8847
8792
|
callback([cleanedText], lastUsageInfo).catch((err) => {
|
|
8848
8793
|
logger.error("[ServerLlmBackend] Callback error:", err);
|
|
8849
8794
|
reject(err);
|
|
8850
|
-
}).then(() =>
|
|
8795
|
+
}).then(() => resolve());
|
|
8851
8796
|
} else {
|
|
8852
|
-
|
|
8797
|
+
resolve();
|
|
8853
8798
|
}
|
|
8854
8799
|
return;
|
|
8855
8800
|
}
|
|
@@ -8909,7 +8854,7 @@ var ServerLlmBackend = class {
|
|
|
8909
8854
|
response.data.on("end", () => {
|
|
8910
8855
|
if (!receivedDone) {
|
|
8911
8856
|
logger.debug("[ServerLlmBackend] Stream ended without [DONE], resolving anyway");
|
|
8912
|
-
|
|
8857
|
+
resolve();
|
|
8913
8858
|
} else {
|
|
8914
8859
|
logger.debug("[ServerLlmBackend] Stream ended, [DONE] handler will resolve");
|
|
8915
8860
|
}
|
|
@@ -9176,7 +9121,7 @@ var ApiClient = class {
|
|
|
9176
9121
|
// package.json
|
|
9177
9122
|
var package_default = {
|
|
9178
9123
|
name: "@bike4mind/cli",
|
|
9179
|
-
version: "0.2.1-feat-cli-
|
|
9124
|
+
version: "0.2.1-feat-cli-project-scoped-config.16996+16c515189",
|
|
9180
9125
|
type: "module",
|
|
9181
9126
|
description: "Interactive CLI tool for Bike4Mind with ReAct agents",
|
|
9182
9127
|
license: "UNLICENSED",
|
|
@@ -9187,9 +9132,6 @@ var package_default = {
|
|
|
9187
9132
|
},
|
|
9188
9133
|
homepage: "https://github.com/bike4mind/lumina5#readme",
|
|
9189
9134
|
bugs: "https://github.com/bike4mind/lumina5/issues",
|
|
9190
|
-
publishConfig: {
|
|
9191
|
-
access: "public"
|
|
9192
|
-
},
|
|
9193
9135
|
keywords: [
|
|
9194
9136
|
"cli",
|
|
9195
9137
|
"ai",
|
|
@@ -9210,8 +9152,6 @@ var package_default = {
|
|
|
9210
9152
|
dev: "tsx src/index.tsx",
|
|
9211
9153
|
build: "tsup",
|
|
9212
9154
|
typecheck: "tsc --noEmit",
|
|
9213
|
-
test: "vitest run",
|
|
9214
|
-
"test:watch": "vitest",
|
|
9215
9155
|
start: "node dist/index.js",
|
|
9216
9156
|
prepublishOnly: "pnpm build"
|
|
9217
9157
|
},
|
|
@@ -9278,10 +9218,10 @@ var package_default = {
|
|
|
9278
9218
|
},
|
|
9279
9219
|
devDependencies: {
|
|
9280
9220
|
"@bike4mind/agents": "0.1.0",
|
|
9281
|
-
"@bike4mind/common": "2.36.1-feat-cli-
|
|
9282
|
-
"@bike4mind/mcp": "1.19.4-feat-cli-
|
|
9283
|
-
"@bike4mind/services": "2.29.1-feat-cli-
|
|
9284
|
-
"@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",
|
|
9285
9225
|
"@types/diff": "^5.0.9",
|
|
9286
9226
|
"@types/jsonwebtoken": "^9.0.4",
|
|
9287
9227
|
"@types/node": "^22.9.0",
|
|
@@ -9290,10 +9230,9 @@ var package_default = {
|
|
|
9290
9230
|
"@types/yargs": "^17.0.32",
|
|
9291
9231
|
tsup: "^8.5.1",
|
|
9292
9232
|
tsx: "^4.21.0",
|
|
9293
|
-
typescript: "^5.9.3"
|
|
9294
|
-
vitest: "^3.2.4"
|
|
9233
|
+
typescript: "^5.9.3"
|
|
9295
9234
|
},
|
|
9296
|
-
gitHead: "
|
|
9235
|
+
gitHead: "16c515189f0b9a7e3ccea2c9874866dd2e8fe084"
|
|
9297
9236
|
};
|
|
9298
9237
|
|
|
9299
9238
|
// src/index.tsx
|
|
@@ -9316,7 +9255,8 @@ function CliApp() {
|
|
|
9316
9255
|
agent: null,
|
|
9317
9256
|
mcpManager: null,
|
|
9318
9257
|
permissionManager: null,
|
|
9319
|
-
permissionPrompt: null
|
|
9258
|
+
permissionPrompt: null,
|
|
9259
|
+
trustLocationSelector: null
|
|
9320
9260
|
});
|
|
9321
9261
|
const [isInitialized, setIsInitialized] = useState3(false);
|
|
9322
9262
|
const [initError, setInitError] = useState3(null);
|
|
@@ -9345,7 +9285,7 @@ function CliApp() {
|
|
|
9345
9285
|
}
|
|
9346
9286
|
await Promise.race([
|
|
9347
9287
|
Promise.all(cleanupTasks),
|
|
9348
|
-
new Promise((
|
|
9288
|
+
new Promise((resolve) => setTimeout(resolve, 500))
|
|
9349
9289
|
// 500ms timeout
|
|
9350
9290
|
]);
|
|
9351
9291
|
setTimeout(() => {
|
|
@@ -9477,11 +9417,17 @@ function CliApp() {
|
|
|
9477
9417
|
debug: () => {
|
|
9478
9418
|
}
|
|
9479
9419
|
};
|
|
9480
|
-
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
|
+
);
|
|
9481
9427
|
const promptFn = (toolName, args, preview) => {
|
|
9482
|
-
return new Promise((
|
|
9428
|
+
return new Promise((resolve) => {
|
|
9483
9429
|
const canBeTrusted = permissionManager.canBeTrusted(toolName);
|
|
9484
|
-
const prompt = { toolName, args, preview, canBeTrusted, resolve
|
|
9430
|
+
const prompt = { toolName, args, preview, canBeTrusted, resolve };
|
|
9485
9431
|
setState((prev) => ({
|
|
9486
9432
|
...prev,
|
|
9487
9433
|
permissionManager,
|
|
@@ -9505,6 +9451,7 @@ function CliApp() {
|
|
|
9505
9451
|
permissionManager,
|
|
9506
9452
|
promptFn,
|
|
9507
9453
|
agentContext,
|
|
9454
|
+
state.configStore,
|
|
9508
9455
|
config.toolApiKeys
|
|
9509
9456
|
);
|
|
9510
9457
|
console.log(`\u{1F6E0}\uFE0F Loaded ${b4mTools.length} B4M tool(s)`);
|
|
@@ -9683,6 +9630,9 @@ Tool Permissions:
|
|
|
9683
9630
|
/trust <tool-name> - Trust a tool (won't ask permission again)
|
|
9684
9631
|
/untrust <tool-name> - Remove tool from trusted list
|
|
9685
9632
|
/trusted - List all trusted tools
|
|
9633
|
+
|
|
9634
|
+
Project Configuration:
|
|
9635
|
+
/project-config - Show merged project configuration
|
|
9686
9636
|
`);
|
|
9687
9637
|
break;
|
|
9688
9638
|
case "exit":
|
|
@@ -9774,7 +9724,7 @@ Tool Permissions:
|
|
|
9774
9724
|
console.log("");
|
|
9775
9725
|
break;
|
|
9776
9726
|
}
|
|
9777
|
-
case "trust":
|
|
9727
|
+
case "trust": {
|
|
9778
9728
|
if (!state.permissionManager) {
|
|
9779
9729
|
console.log("Permission manager not initialized");
|
|
9780
9730
|
return;
|
|
@@ -9782,16 +9732,85 @@ Tool Permissions:
|
|
|
9782
9732
|
const toolToTrust = args[0];
|
|
9783
9733
|
if (!toolToTrust) {
|
|
9784
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("");
|
|
9785
9739
|
return;
|
|
9786
9740
|
}
|
|
9787
|
-
const
|
|
9788
|
-
if (
|
|
9789
|
-
|
|
9790
|
-
|
|
9791
|
-
|
|
9792
|
-
|
|
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;
|
|
9793
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
|
+
}));
|
|
9794
9812
|
break;
|
|
9813
|
+
}
|
|
9795
9814
|
case "untrust":
|
|
9796
9815
|
if (!state.permissionManager) {
|
|
9797
9816
|
console.log("Permission manager not initialized");
|
|
@@ -9840,6 +9859,50 @@ Tool Permissions:
|
|
|
9840
9859
|
console.log(`Expires: ${new Date(authTokens.expiresAt).toLocaleString()}`);
|
|
9841
9860
|
console.log("");
|
|
9842
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
|
+
}
|
|
9843
9906
|
default:
|
|
9844
9907
|
console.log(`Unknown command: /${command}`);
|
|
9845
9908
|
console.log("Type /help for available commands");
|
|
@@ -9848,6 +9911,26 @@ Tool Permissions:
|
|
|
9848
9911
|
if (initError) {
|
|
9849
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"));
|
|
9850
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
|
+
}
|
|
9851
9934
|
if (state.showLoginFlow) {
|
|
9852
9935
|
const loginApiUrl = getApiUrl(state.config?.apiConfig);
|
|
9853
9936
|
return /* @__PURE__ */ React11.createElement(
|