@bike4mind/cli 0.2.1-optimize-mcp-server-call.17006 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -4,9 +4,9 @@ import {
4
4
  getEffectiveApiKey,
5
5
  getOpenWeatherKey,
6
6
  getSerperKey
7
- } from "./chunk-QXGU6KYI.js";
8
- import "./chunk-LZMRYJ3B.js";
9
- import "./chunk-F3ETXO5N.js";
7
+ } from "./chunk-GZTILMGE.js";
8
+ import "./chunk-Y4HMTEDH.js";
9
+ import "./chunk-5N4PG5EH.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-U3GPYBTD.js";
18
+ } from "./chunk-NZADYDFG.js";
19
19
  import {
20
20
  Logger
21
21
  } from "./chunk-AMDXHL6S.js";
@@ -29,6 +29,7 @@ import {
29
29
  AuthEvents,
30
30
  BFL_IMAGE_MODELS,
31
31
  BFL_SAFETY_TOLERANCE,
32
+ CREDIT_DEDUCT_TRANSACTION_TYPES,
32
33
  ChatCompletionCreateInputSchema,
33
34
  ChatModels,
34
35
  CollectionType,
@@ -78,13 +79,13 @@ import {
78
79
  } from "./chunk-PDX44BCA.js";
79
80
 
80
81
  // src/index.tsx
81
- import React10, { useState as useState3, useEffect as useEffect3, useCallback } from "react";
82
- import { render, Box as Box10, Text as Text9, useApp, useInput as useInput2 } from "ink";
82
+ import React11, { useState as useState3, useEffect as useEffect3, useCallback } from "react";
83
+ import { render, Box as Box11, Text as Text10, useApp, useInput as useInput2 } from "ink";
83
84
  import { v4 as uuidv49 } from "uuid";
84
85
 
85
86
  // src/components/App.tsx
86
- import React7 from "react";
87
- import { Box as Box7, Text as Text6, Static } from "ink";
87
+ import React8 from "react";
88
+ import { Box as Box8, Text as Text7, Static } from "ink";
88
89
 
89
90
  // src/components/StatusBar.tsx
90
91
  import React from "react";
@@ -94,8 +95,8 @@ var StatusBar = React.memo(function StatusBar2({ sessionName, model, tokenUsage
94
95
  });
95
96
 
96
97
  // src/components/InputPrompt.tsx
97
- import React3, { useState, useMemo, useEffect } from "react";
98
- import { Box as Box3, Text as Text3, useInput } from "ink";
98
+ import React4, { useState, useMemo, useEffect } from "react";
99
+ import { Box as Box4, Text as Text4, useInput } from "ink";
99
100
  import TextInput from "ink-text-input";
100
101
 
101
102
  // src/components/CommandAutocomplete.tsx
@@ -112,8 +113,210 @@ function CommandAutocomplete({ commands, selectedIndex }) {
112
113
  }));
113
114
  }
114
115
 
115
- // src/utils/fuzzySearch.ts
116
+ // src/components/FileAutocomplete.tsx
117
+ import React3 from "react";
118
+ import { Box as Box3, Text as Text3 } from "ink";
119
+
120
+ // src/utils/fileSearch.ts
121
+ import * as fs from "fs";
122
+ import * as path from "path";
116
123
  import Fuse from "fuse.js";
124
+ var DEFAULT_IGNORE_PATTERNS = [
125
+ "node_modules",
126
+ ".git",
127
+ ".next",
128
+ ".turbo",
129
+ "dist",
130
+ "build",
131
+ ".cache",
132
+ "coverage",
133
+ ".DS_Store",
134
+ ".env",
135
+ ".env.local",
136
+ ".env.secrets"
137
+ ];
138
+ function walkDirectory(basePath = process.cwd(), maxDepth = 5, ignorePatterns = DEFAULT_IGNORE_PATTERNS) {
139
+ const results = [];
140
+ const normalizedBase = path.resolve(basePath);
141
+ function walk(currentPath, depth) {
142
+ if (depth > maxDepth) return;
143
+ try {
144
+ const entries = fs.readdirSync(currentPath, { withFileTypes: true });
145
+ for (const entry of entries) {
146
+ if (ignorePatterns.some((pattern) => entry.name === pattern || entry.name.startsWith(pattern))) {
147
+ continue;
148
+ }
149
+ const fullPath = path.join(currentPath, entry.name);
150
+ const relativePath = path.relative(normalizedBase, fullPath);
151
+ if (entry.isDirectory()) {
152
+ results.push({
153
+ path: relativePath,
154
+ isDirectory: true
155
+ });
156
+ walk(fullPath, depth + 1);
157
+ } else if (entry.isFile()) {
158
+ try {
159
+ const stats = fs.statSync(fullPath);
160
+ results.push({
161
+ path: relativePath,
162
+ isDirectory: false,
163
+ size: stats.size
164
+ });
165
+ } catch {
166
+ results.push({
167
+ path: relativePath,
168
+ isDirectory: false
169
+ });
170
+ }
171
+ }
172
+ }
173
+ } catch {
174
+ }
175
+ }
176
+ walk(normalizedBase, 0);
177
+ return results;
178
+ }
179
+ function formatFileSize(bytes) {
180
+ if (bytes < 1024) return `${bytes} B`;
181
+ if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
182
+ if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
183
+ return `${(bytes / (1024 * 1024 * 1024)).toFixed(1)} GB`;
184
+ }
185
+ var cachedFiles = null;
186
+ var cacheTimestamp = 0;
187
+ var CACHE_TTL_MS = 3e4;
188
+ function getCachedFiles() {
189
+ const now = Date.now();
190
+ if (!cachedFiles || now - cacheTimestamp > CACHE_TTL_MS) {
191
+ cachedFiles = walkDirectory();
192
+ cacheTimestamp = now;
193
+ }
194
+ return cachedFiles;
195
+ }
196
+ function searchFiles(query) {
197
+ const files = getCachedFiles();
198
+ if (!query || query.trim() === "") {
199
+ return files.filter((f) => !f.path.includes(path.sep)).slice(0, 20);
200
+ }
201
+ const queryDir = path.dirname(query);
202
+ let searchPool = files;
203
+ if (queryDir && queryDir !== ".") {
204
+ const normalizedDir = queryDir.replace(/\\/g, "/");
205
+ searchPool = files.filter((f) => {
206
+ const normalizedPath = f.path.replace(/\\/g, "/");
207
+ return normalizedPath.startsWith(normalizedDir + "/") || normalizedPath === normalizedDir;
208
+ });
209
+ if (searchPool.length === 0) {
210
+ searchPool = files;
211
+ }
212
+ }
213
+ const fuse2 = new Fuse(searchPool, {
214
+ keys: [{ name: "path", weight: 1 }],
215
+ threshold: 0.4,
216
+ // Allow some fuzzy matching
217
+ includeScore: true,
218
+ minMatchCharLength: 1,
219
+ // Use extended search for better path matching
220
+ useExtendedSearch: false
221
+ });
222
+ const results = fuse2.search(query);
223
+ return results.slice(0, 20).map((result) => result.item);
224
+ }
225
+ function isPathWithinCwd(filePath) {
226
+ const cwd = path.resolve(process.cwd());
227
+ const absolutePath = path.resolve(cwd, filePath);
228
+ let resolvedCwd = cwd;
229
+ let resolvedPath = absolutePath;
230
+ try {
231
+ const realCwd = fs.realpathSync.native(cwd);
232
+ if (realCwd) {
233
+ resolvedCwd = realCwd;
234
+ }
235
+ } catch {
236
+ }
237
+ try {
238
+ const realPath = fs.realpathSync.native(absolutePath);
239
+ if (realPath) {
240
+ resolvedPath = realPath;
241
+ }
242
+ } catch {
243
+ const relativePath2 = path.relative(cwd, absolutePath);
244
+ resolvedPath = path.resolve(resolvedCwd, relativePath2);
245
+ }
246
+ const normalizedCwd = resolvedCwd.toLowerCase();
247
+ const normalizedPath = resolvedPath.toLowerCase();
248
+ const isWithin = normalizedPath === normalizedCwd || normalizedPath.startsWith(normalizedCwd + path.sep);
249
+ if (!isWithin) {
250
+ return false;
251
+ }
252
+ const relativePath = path.relative(resolvedCwd, resolvedPath);
253
+ return !relativePath.startsWith("..") && !path.isAbsolute(relativePath);
254
+ }
255
+ function isBinaryFile(filePath) {
256
+ const binaryExtensions = [
257
+ ".png",
258
+ ".jpg",
259
+ ".jpeg",
260
+ ".gif",
261
+ ".bmp",
262
+ ".ico",
263
+ ".webp",
264
+ // Note: .svg is NOT included because SVG is XML text format that can be safely read
265
+ ".pdf",
266
+ ".doc",
267
+ ".docx",
268
+ ".xls",
269
+ ".xlsx",
270
+ ".ppt",
271
+ ".pptx",
272
+ ".zip",
273
+ ".tar",
274
+ ".gz",
275
+ ".rar",
276
+ ".7z",
277
+ ".exe",
278
+ ".dll",
279
+ ".so",
280
+ ".dylib",
281
+ ".bin",
282
+ ".dat",
283
+ ".mp3",
284
+ ".mp4",
285
+ ".wav",
286
+ ".avi",
287
+ ".mov",
288
+ ".mkv",
289
+ ".ttf",
290
+ ".otf",
291
+ ".woff",
292
+ ".woff2",
293
+ ".eot",
294
+ ".class",
295
+ ".pyc",
296
+ ".o",
297
+ ".obj"
298
+ ];
299
+ const ext = path.extname(filePath).toLowerCase();
300
+ return binaryExtensions.includes(ext);
301
+ }
302
+ var MAX_FILE_SIZE = 10 * 1024 * 1024;
303
+
304
+ // src/components/FileAutocomplete.tsx
305
+ function FileAutocomplete({ files, selectedIndex, query }) {
306
+ if (files.length === 0) {
307
+ return /* @__PURE__ */ React3.createElement(Box3, { marginLeft: 2, marginTop: 1 }, /* @__PURE__ */ React3.createElement(Text3, { dimColor: true }, "No matching files", query ? ` for "${query}"` : ""));
308
+ }
309
+ return /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column", marginLeft: 2, marginTop: 1 }, /* @__PURE__ */ React3.createElement(Box3, { marginBottom: 1 }, /* @__PURE__ */ React3.createElement(Text3, { dimColor: true }, files.length === 1 ? "1 match" : `${files.length} matches`, " - Use up/down to navigate, Tab to select")), files.map((file, index) => {
310
+ const isSelected = index === selectedIndex;
311
+ const icon = file.isDirectory ? "[folder]" : "[file] ";
312
+ const sizeDisplay = file.isDirectory ? "" : file.size !== void 0 ? ` (${formatFileSize(file.size)})` : "";
313
+ const pathDisplay = file.isDirectory ? `${file.path}/` : file.path;
314
+ return /* @__PURE__ */ React3.createElement(Box3, { key: file.path, marginLeft: 1 }, /* @__PURE__ */ React3.createElement(Text3, { color: isSelected ? "cyan" : void 0, bold: isSelected }, isSelected ? "> " : " "), /* @__PURE__ */ React3.createElement(Text3, { color: file.isDirectory ? "yellow" : isSelected ? "cyan" : void 0, bold: isSelected }, icon), /* @__PURE__ */ React3.createElement(Text3, { color: isSelected ? "cyan" : void 0, bold: isSelected }, " ", pathDisplay), /* @__PURE__ */ React3.createElement(Text3, { dimColor: true }, sizeDisplay));
315
+ }));
316
+ }
317
+
318
+ // src/utils/fuzzySearch.ts
319
+ import Fuse2 from "fuse.js";
117
320
 
118
321
  // src/config/commands.ts
119
322
  var COMMANDS = [
@@ -177,11 +380,15 @@ var COMMANDS = [
177
380
  {
178
381
  name: "trusted",
179
382
  description: "List all trusted tools"
383
+ },
384
+ {
385
+ name: "usage",
386
+ description: "Show credit usage and balance"
180
387
  }
181
388
  ];
182
389
 
183
390
  // src/utils/fuzzySearch.ts
184
- var fuse = new Fuse(COMMANDS, {
391
+ var fuse = new Fuse2(COMMANDS, {
185
392
  keys: [
186
393
  { name: "name", weight: 0.7 },
187
394
  // Prioritize command name
@@ -202,23 +409,65 @@ function searchCommands(query) {
202
409
  }
203
410
 
204
411
  // src/components/InputPrompt.tsx
412
+ function findAtTrigger(value) {
413
+ for (let i = value.length - 1; i >= 0; i--) {
414
+ if (value[i] === "@") {
415
+ const isValid = i === 0 || value[i - 1] === " ";
416
+ if (isValid) {
417
+ const query = value.slice(i + 1);
418
+ if (query.includes(" ")) {
419
+ return null;
420
+ }
421
+ return { startIndex: i, query };
422
+ }
423
+ }
424
+ }
425
+ return null;
426
+ }
205
427
  function InputPrompt({ onSubmit, disabled = false, history = [] }) {
206
428
  const [value, setValue] = useState("");
207
429
  const [selectedIndex, setSelectedIndex] = useState(0);
208
430
  const [historyIndex, setHistoryIndex] = useState(-1);
209
431
  const [tempInput, setTempInput] = useState("");
210
432
  const [inputKey, setInputKey] = useState(0);
211
- const shouldShowAutocomplete = value.startsWith("/") && !disabled;
212
- const query = shouldShowAutocomplete ? value.slice(1) : "";
433
+ const [fileAutocomplete, setFileAutocomplete] = useState(null);
434
+ const [fileSelectedIndex, setFileSelectedIndex] = useState(0);
435
+ const shouldShowCommandAutocomplete = value.startsWith("/") && !disabled && !fileAutocomplete?.active;
436
+ const commandQuery = shouldShowCommandAutocomplete ? value.slice(1) : "";
213
437
  const filteredCommands = useMemo(() => {
214
- if (!shouldShowAutocomplete) return [];
215
- return searchCommands(query);
216
- }, [shouldShowAutocomplete, query]);
438
+ if (!shouldShowCommandAutocomplete) return [];
439
+ return searchCommands(commandQuery);
440
+ }, [shouldShowCommandAutocomplete, commandQuery]);
441
+ const filteredFiles = useMemo(() => {
442
+ if (!fileAutocomplete?.active) return [];
443
+ return searchFiles(fileAutocomplete.query);
444
+ }, [fileAutocomplete?.active, fileAutocomplete?.query]);
217
445
  useEffect(() => {
218
446
  setSelectedIndex(0);
219
447
  }, [filteredCommands]);
448
+ useEffect(() => {
449
+ setFileSelectedIndex(0);
450
+ }, [filteredFiles]);
220
451
  useInput((input, key) => {
221
- if (shouldShowAutocomplete && filteredCommands.length > 0) {
452
+ if (fileAutocomplete?.active && filteredFiles.length > 0) {
453
+ if (key.upArrow) {
454
+ setFileSelectedIndex((prev) => prev > 0 ? prev - 1 : filteredFiles.length - 1);
455
+ return;
456
+ } else if (key.downArrow) {
457
+ setFileSelectedIndex((prev) => prev < filteredFiles.length - 1 ? prev + 1 : 0);
458
+ return;
459
+ } else if (key.tab) {
460
+ const selectedFile = filteredFiles[fileSelectedIndex];
461
+ if (selectedFile) {
462
+ insertSelectedFile(selectedFile);
463
+ }
464
+ return;
465
+ } else if (key.escape) {
466
+ setFileAutocomplete(null);
467
+ return;
468
+ }
469
+ }
470
+ if (shouldShowCommandAutocomplete && filteredCommands.length > 0) {
222
471
  if (key.upArrow) {
223
472
  setSelectedIndex((prev) => prev > 0 ? prev - 1 : filteredCommands.length - 1);
224
473
  } else if (key.downArrow) {
@@ -226,7 +475,7 @@ function InputPrompt({ onSubmit, disabled = false, history = [] }) {
226
475
  }
227
476
  return;
228
477
  }
229
- if (!shouldShowAutocomplete && history.length > 0) {
478
+ if (!shouldShowCommandAutocomplete && !fileAutocomplete?.active && history.length > 0) {
230
479
  if (key.upArrow) {
231
480
  if (historyIndex === -1) {
232
481
  setTempInput(value);
@@ -249,9 +498,35 @@ function InputPrompt({ onSubmit, disabled = false, history = [] }) {
249
498
  }
250
499
  }
251
500
  });
501
+ const insertSelectedFile = (file) => {
502
+ if (!fileAutocomplete) return;
503
+ const beforeAt = value.slice(0, fileAutocomplete.startIndex);
504
+ const afterQuery = value.slice(fileAutocomplete.startIndex + 1 + fileAutocomplete.query.length);
505
+ const pathToInsert = file.isDirectory ? `@${file.path}/` : `@${file.path}`;
506
+ const newValue = beforeAt + pathToInsert + afterQuery;
507
+ setValue(newValue);
508
+ setInputKey((prev) => prev + 1);
509
+ if (file.isDirectory) {
510
+ setFileAutocomplete({
511
+ active: true,
512
+ startIndex: fileAutocomplete.startIndex,
513
+ query: file.path + "/"
514
+ });
515
+ setFileSelectedIndex(0);
516
+ } else {
517
+ setFileAutocomplete(null);
518
+ }
519
+ };
252
520
  const handleSubmit = (input) => {
253
521
  if (disabled || !input.trim()) return;
254
- if (shouldShowAutocomplete && filteredCommands.length > 0) {
522
+ if (fileAutocomplete?.active && filteredFiles.length > 0) {
523
+ const selectedFile = filteredFiles[fileSelectedIndex];
524
+ if (selectedFile) {
525
+ insertSelectedFile(selectedFile);
526
+ }
527
+ return;
528
+ }
529
+ if (shouldShowCommandAutocomplete && filteredCommands.length > 0) {
255
530
  const selectedCommand = filteredCommands[selectedIndex];
256
531
  const commandText = `/${selectedCommand.name}`;
257
532
  if (selectedCommand.args) {
@@ -268,6 +543,7 @@ function InputPrompt({ onSubmit, disabled = false, history = [] }) {
268
543
  onSubmit(input);
269
544
  setValue("");
270
545
  setHistoryIndex(-1);
546
+ setFileAutocomplete(null);
271
547
  };
272
548
  const handleChange = (newValue) => {
273
549
  setValue(newValue);
@@ -275,30 +551,40 @@ function InputPrompt({ onSubmit, disabled = false, history = [] }) {
275
551
  setHistoryIndex(-1);
276
552
  setTempInput("");
277
553
  }
554
+ const atTrigger = findAtTrigger(newValue);
555
+ if (atTrigger) {
556
+ setFileAutocomplete({
557
+ active: true,
558
+ startIndex: atTrigger.startIndex,
559
+ query: atTrigger.query
560
+ });
561
+ } else {
562
+ setFileAutocomplete(null);
563
+ }
278
564
  };
279
- return /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column" }, /* @__PURE__ */ React3.createElement(Box3, null, /* @__PURE__ */ React3.createElement(Text3, { bold: true, color: "cyan" }, "> "), /* @__PURE__ */ React3.createElement(
565
+ return /* @__PURE__ */ React4.createElement(Box4, { flexDirection: "column" }, /* @__PURE__ */ React4.createElement(Box4, null, /* @__PURE__ */ React4.createElement(Text4, { bold: true, color: "cyan" }, "> "), /* @__PURE__ */ React4.createElement(
280
566
  TextInput,
281
567
  {
282
568
  key: inputKey,
283
569
  value,
284
570
  onChange: handleChange,
285
571
  onSubmit: handleSubmit,
286
- placeholder: disabled ? "Thinking..." : "Type your message or /help for commands",
572
+ placeholder: disabled ? "Thinking..." : "Type your message, /help for commands, or @file to reference",
287
573
  showCursor: !disabled
288
574
  }
289
- )), shouldShowAutocomplete && /* @__PURE__ */ React3.createElement(CommandAutocomplete, { commands: filteredCommands, selectedIndex }));
575
+ )), shouldShowCommandAutocomplete && /* @__PURE__ */ React4.createElement(CommandAutocomplete, { commands: filteredCommands, selectedIndex }), fileAutocomplete?.active && /* @__PURE__ */ React4.createElement(FileAutocomplete, { files: filteredFiles, selectedIndex: fileSelectedIndex, query: fileAutocomplete.query }));
290
576
  }
291
577
 
292
578
  // src/components/AgentThinking.tsx
293
- import React5 from "react";
294
- import { Box as Box5 } from "ink";
579
+ import React6 from "react";
580
+ import { Box as Box6 } from "ink";
295
581
 
296
582
  // src/components/ThoughtStream.tsx
297
- import React4 from "react";
298
- import { Box as Box4, Text as Text4 } from "ink";
583
+ import React5 from "react";
584
+ import { Box as Box5, Text as Text5 } from "ink";
299
585
  import Spinner from "ink-spinner";
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...")));
586
+ var ThoughtStream = React5.memo(function ThoughtStream2({ steps }) {
587
+ return /* @__PURE__ */ React5.createElement(Box5, { flexDirection: "column", gap: 1 }, steps.map((step, index) => /* @__PURE__ */ React5.createElement(Box5, { key: index, flexDirection: "column" }, step.type === "thought" && /* @__PURE__ */ React5.createElement(Box5, null, /* @__PURE__ */ React5.createElement(Text5, { color: "magenta" }, "\u{1F914} Thought: "), /* @__PURE__ */ React5.createElement(Text5, null, step.content)), step.type === "action" && /* @__PURE__ */ React5.createElement(Box5, { flexDirection: "column" }, /* @__PURE__ */ React5.createElement(Box5, null, /* @__PURE__ */ React5.createElement(Text5, { color: "yellow" }, "\u26A1 Action: "), /* @__PURE__ */ React5.createElement(Text5, { bold: true }, step.metadata?.toolName || "unknown")), step.metadata?.toolInput && /* @__PURE__ */ React5.createElement(Box5, { paddingLeft: 2 }, /* @__PURE__ */ React5.createElement(Text5, { dimColor: true }, JSON.stringify(step.metadata.toolInput, null, 2)))), step.type === "observation" && /* @__PURE__ */ React5.createElement(Box5, { flexDirection: "column" }, /* @__PURE__ */ React5.createElement(Box5, null, /* @__PURE__ */ React5.createElement(Text5, { color: "blue" }, "\u{1F4CA} Observation: ")), /* @__PURE__ */ React5.createElement(Box5, { paddingLeft: 2 }, /* @__PURE__ */ React5.createElement(Text5, null, step.content))), step.type === "final_answer" && /* @__PURE__ */ React5.createElement(Box5, { flexDirection: "column" }, /* @__PURE__ */ React5.createElement(Box5, null, /* @__PURE__ */ React5.createElement(Text5, { color: "green", bold: true }, "\u2705 Final Answer:", " ")), /* @__PURE__ */ React5.createElement(Box5, { paddingLeft: 2 }, /* @__PURE__ */ React5.createElement(Text5, null, step.content)), step.metadata?.tokenUsage && /* @__PURE__ */ React5.createElement(Box5, { paddingLeft: 2 }, /* @__PURE__ */ React5.createElement(Text5, { dimColor: true }, "(", step.metadata.tokenUsage.total, " tokens)"))))), !steps.some((s) => s.type === "final_answer") && /* @__PURE__ */ React5.createElement(Box5, null, /* @__PURE__ */ React5.createElement(Text5, { color: "yellow" }, /* @__PURE__ */ React5.createElement(Spinner, { type: "dots" })), /* @__PURE__ */ React5.createElement(Text5, null, " ", steps.length === 0 ? "Thinking..." : "Processing...")));
302
588
  });
303
589
 
304
590
  // src/store/index.ts
@@ -324,32 +610,32 @@ var useCliStore = create((set) => ({
324
610
  }));
325
611
 
326
612
  // src/components/AgentThinking.tsx
327
- var AgentThinking = React5.memo(function AgentThinking2() {
613
+ var AgentThinking = React6.memo(function AgentThinking2() {
328
614
  const isThinking = useCliStore((state) => state.isThinking);
329
615
  const agentSteps = useCliStore((state) => state.agentSteps);
330
616
  if (!isThinking) {
331
617
  return null;
332
618
  }
333
- return /* @__PURE__ */ React5.createElement(Box5, { borderStyle: "single", borderColor: "yellow", paddingX: 1, marginY: 1 }, /* @__PURE__ */ React5.createElement(ThoughtStream, { steps: agentSteps }));
619
+ return /* @__PURE__ */ React6.createElement(Box6, { borderStyle: "single", borderColor: "yellow", paddingX: 1, marginY: 1 }, /* @__PURE__ */ React6.createElement(ThoughtStream, { steps: agentSteps }));
334
620
  });
335
621
 
336
622
  // src/components/PermissionPrompt.tsx
337
- import React6 from "react";
338
- import { Box as Box6, Text as Text5 } from "ink";
623
+ import React7 from "react";
624
+ import { Box as Box7, Text as Text6 } from "ink";
339
625
  import SelectInput from "ink-select-input";
340
626
  function renderDiffPreview(preview) {
341
627
  const lines = preview.split("\n");
342
628
  return lines.map((line, index) => {
343
629
  if (line.startsWith("+")) {
344
- return /* @__PURE__ */ React6.createElement(Text5, { key: index, color: "green" }, line);
630
+ return /* @__PURE__ */ React7.createElement(Text6, { key: index, color: "green" }, line);
345
631
  }
346
632
  if (line.startsWith("-")) {
347
- return /* @__PURE__ */ React6.createElement(Text5, { key: index, color: "red" }, line);
633
+ return /* @__PURE__ */ React7.createElement(Text6, { key: index, color: "red" }, line);
348
634
  }
349
635
  if (line.startsWith("@@")) {
350
- return /* @__PURE__ */ React6.createElement(Text5, { key: index, color: "cyan" }, line);
636
+ return /* @__PURE__ */ React7.createElement(Text6, { key: index, color: "cyan" }, line);
351
637
  }
352
- return /* @__PURE__ */ React6.createElement(Text5, { key: index, dimColor: true }, line);
638
+ return /* @__PURE__ */ React7.createElement(Text6, { key: index, dimColor: true }, line);
353
639
  });
354
640
  }
355
641
  function PermissionPrompt({
@@ -369,7 +655,121 @@ function PermissionPrompt({
369
655
  { label: "\u2717 Deny", value: "deny" }
370
656
  ];
371
657
  const argsString = typeof args === "string" ? args : JSON.stringify(args, null, 2);
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) })));
658
+ return /* @__PURE__ */ React7.createElement(Box7, { flexDirection: "column", borderStyle: "bold", borderColor: "yellow", padding: 1, marginY: 1 }, /* @__PURE__ */ React7.createElement(Box7, null, /* @__PURE__ */ React7.createElement(Text6, { bold: true, color: "yellow" }, "\u26A0\uFE0F Permission Required")), /* @__PURE__ */ React7.createElement(Box7, { marginTop: 1 }, /* @__PURE__ */ React7.createElement(Text6, { dimColor: true }, "Tool: "), /* @__PURE__ */ React7.createElement(Text6, { bold: true, color: "cyan" }, toolName)), toolDescription && /* @__PURE__ */ React7.createElement(Box7, null, /* @__PURE__ */ React7.createElement(Text6, { dimColor: true }, "Action: "), /* @__PURE__ */ React7.createElement(Text6, null, toolDescription)), /* @__PURE__ */ React7.createElement(Box7, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React7.createElement(Text6, { bold: true }, "Arguments:"), /* @__PURE__ */ React7.createElement(Box7, { paddingLeft: 2, flexDirection: "column" }, /* @__PURE__ */ React7.createElement(Text6, { dimColor: true }, argsString))), preview && /* @__PURE__ */ React7.createElement(Box7, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React7.createElement(Text6, { bold: true }, "Preview:"), /* @__PURE__ */ React7.createElement(Box7, { borderStyle: "single", borderColor: "gray", paddingX: 1, flexDirection: "column" }, renderDiffPreview(preview))), !canBeTrusted && /* @__PURE__ */ React7.createElement(Box7, { marginTop: 1 }, /* @__PURE__ */ React7.createElement(Text6, { color: "red", dimColor: true }, "Note: This tool cannot be trusted due to its dangerous nature.")), /* @__PURE__ */ React7.createElement(Box7, { marginTop: 1 }, /* @__PURE__ */ React7.createElement(SelectInput, { items, onSelect: (item) => onResponse(item.value) })));
659
+ }
660
+
661
+ // src/utils/processFileReferences.ts
662
+ import * as fs2 from "fs";
663
+ import * as path2 from "path";
664
+
665
+ // src/utils/constants.ts
666
+ var NAME_SUFFIXES = ["jr", "sr", "ii", "iii", "iv", "v", "phd", "md", "esq"];
667
+ function isNameSuffix(value) {
668
+ return NAME_SUFFIXES.includes(value);
669
+ }
670
+
671
+ // src/utils/processFileReferences.ts
672
+ var FILE_REFERENCE_REGEX = /(?:^|\s)@([^\s@]+)/g;
673
+ function looksLikeFilePath(ref) {
674
+ if (ref.includes("/") || ref.includes(path2.sep)) {
675
+ return true;
676
+ }
677
+ const extensionMatch = /\.(\w+)$/.exec(ref);
678
+ if (extensionMatch) {
679
+ const ext = extensionMatch[1].toLowerCase();
680
+ if (isNameSuffix(ext)) {
681
+ return false;
682
+ }
683
+ if (ext.length > 10) {
684
+ return false;
685
+ }
686
+ return true;
687
+ }
688
+ return false;
689
+ }
690
+ function extractFileReferences(message) {
691
+ const references = [];
692
+ const regex = /(?:^|\s)@([^\s@]+)/g;
693
+ let match;
694
+ while ((match = regex.exec(message)) !== null) {
695
+ const ref = match[1];
696
+ if (looksLikeFilePath(ref)) {
697
+ references.push(ref);
698
+ }
699
+ }
700
+ return references;
701
+ }
702
+ function readFileContents(filePath) {
703
+ const cwd = process.cwd();
704
+ const absolutePath = path2.resolve(cwd, filePath);
705
+ if (!isPathWithinCwd(filePath)) {
706
+ return { error: `Security: Path "${filePath}" is outside the current working directory` };
707
+ }
708
+ if (!fs2.existsSync(absolutePath)) {
709
+ return { error: `File not found: "${filePath}"` };
710
+ }
711
+ const stats = fs2.statSync(absolutePath);
712
+ if (stats.isDirectory()) {
713
+ try {
714
+ const entries = fs2.readdirSync(absolutePath);
715
+ const fileCount = entries.length;
716
+ return {
717
+ content: `(Directory with ${fileCount} items. Use file tools to explore if needed.)`,
718
+ size: 0
719
+ };
720
+ } catch (err) {
721
+ return { error: `Cannot read directory "${filePath}": ${err instanceof Error ? err.message : "Unknown error"}` };
722
+ }
723
+ }
724
+ if (stats.size > MAX_FILE_SIZE) {
725
+ return {
726
+ error: `File too large: "${filePath}" is ${formatFileSize(stats.size)} (max ${formatFileSize(MAX_FILE_SIZE)})`
727
+ };
728
+ }
729
+ if (isBinaryFile(filePath)) {
730
+ return { error: `Binary file: "${filePath}" cannot be included as text content` };
731
+ }
732
+ try {
733
+ const content = fs2.readFileSync(absolutePath, "utf-8");
734
+ return { content, size: stats.size };
735
+ } catch (err) {
736
+ return { error: `Cannot read file "${filePath}": ${err instanceof Error ? err.message : "Unknown error"}` };
737
+ }
738
+ }
739
+ function formatFileBlock(filePath, content, size, isDirectory) {
740
+ if (isDirectory) {
741
+ return `
742
+ --- Directory Reference: ${filePath} ---
743
+ ${content}
744
+ --- End of ${filePath} ---`;
745
+ }
746
+ return `
747
+ --- Referenced File: ${filePath} (${formatFileSize(size)}) ---
748
+ ${content}
749
+ --- End of ${filePath} ---`;
750
+ }
751
+ async function processFileReferences(message) {
752
+ const references = extractFileReferences(message);
753
+ const errors = [];
754
+ const fileBlocks = [];
755
+ for (const ref of references) {
756
+ const result = readFileContents(ref);
757
+ if ("error" in result) {
758
+ errors.push(result.error);
759
+ continue;
760
+ }
761
+ const isDirectory = result.size === 0 && result.content.startsWith("(Directory");
762
+ fileBlocks.push(formatFileBlock(ref, result.content, result.size, isDirectory));
763
+ }
764
+ if (fileBlocks.length === 0) {
765
+ return { content: message, errors };
766
+ }
767
+ const processedContent = message + "\n" + fileBlocks.join("\n");
768
+ return { content: processedContent, errors };
769
+ }
770
+ function hasFileReferences(message) {
771
+ FILE_REFERENCE_REGEX.lastIndex = 0;
772
+ return FILE_REFERENCE_REGEX.test(message);
373
773
  }
374
774
 
375
775
  // src/components/App.tsx
@@ -382,7 +782,7 @@ function App({ onMessage, onCommand, onPermissionResponse, commandHistory = [] }
382
782
  const permissionPrompt = useCliStore((state) => state.permissionPrompt);
383
783
  const exitRequested = useCliStore((state) => state.exitRequested);
384
784
  const setIsThinking = useCliStore((state) => state.setIsThinking);
385
- const handleSubmit = React7.useCallback(
785
+ const handleSubmit = React8.useCallback(
386
786
  async (input) => {
387
787
  const trimmed = input.trim();
388
788
  if (!trimmed) return;
@@ -393,14 +793,25 @@ function App({ onMessage, onCommand, onPermissionResponse, commandHistory = [] }
393
793
  }
394
794
  setIsThinking(true);
395
795
  try {
396
- await onMessage(trimmed);
796
+ let messageToSend = trimmed;
797
+ if (hasFileReferences(trimmed)) {
798
+ const processed = await processFileReferences(trimmed);
799
+ messageToSend = processed.content;
800
+ if (processed.errors.length > 0) {
801
+ const errorBlock = processed.errors.map((e) => `[Warning: ${e}]`).join("\n");
802
+ messageToSend = `${messageToSend}
803
+
804
+ ${errorBlock}`;
805
+ }
806
+ }
807
+ await onMessage(messageToSend);
397
808
  } finally {
398
809
  setIsThinking(false);
399
810
  }
400
811
  },
401
812
  [onMessage, onCommand, setIsThinking]
402
813
  );
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(
814
+ return /* @__PURE__ */ React8.createElement(Box8, { flexDirection: "column" }, /* @__PURE__ */ React8.createElement(StatusBar, { sessionName, model: currentModel, tokenUsage: totalTokens }), permissionPrompt ? /* @__PURE__ */ React8.createElement(Box8, { flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React8.createElement(
404
815
  PermissionPrompt,
405
816
  {
406
817
  toolName: permissionPrompt.toolName,
@@ -409,39 +820,39 @@ function App({ onMessage, onCommand, onPermissionResponse, commandHistory = [] }
409
820
  canBeTrusted: permissionPrompt.canBeTrusted,
410
821
  onResponse: onPermissionResponse
411
822
  }
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 }))));
823
+ )) : /* @__PURE__ */ React8.createElement(React8.Fragment, null, /* @__PURE__ */ React8.createElement(Static, { items: messages }, (message, index) => /* @__PURE__ */ React8.createElement(Box8, { key: index, flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React8.createElement(MessageItem, { message }))), /* @__PURE__ */ React8.createElement(AgentThinking, null), exitRequested && /* @__PURE__ */ React8.createElement(Box8, { paddingX: 1, marginBottom: 1 }, /* @__PURE__ */ React8.createElement(Text7, { color: "yellow", bold: true }, "\u26A0\uFE0F Press Ctrl+C again to exit")), /* @__PURE__ */ React8.createElement(Box8, { borderStyle: "single", borderColor: "cyan", paddingX: 1 }, /* @__PURE__ */ React8.createElement(InputPrompt, { onSubmit: handleSubmit, disabled: isThinking, history: commandHistory }))));
413
824
  }
414
825
  function MessageItem({ message }) {
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) => {
826
+ return /* @__PURE__ */ React8.createElement(Box8, { 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 ", message.content) : /* @__PURE__ */ React8.createElement(Text7, null, 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) => {
416
827
  if (step.type === "thought") {
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 ? "..." : ""}`));
828
+ 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(Text7, { dimColor: true }, ` ${step.content.slice(0, 200)}${step.content.length > 200 ? "..." : ""}`));
418
829
  }
419
830
  if (step.type === "action") {
420
831
  const toolName = step.metadata?.toolName || "unknown";
421
832
  const toolInput = step.metadata?.toolInput;
422
833
  const observationStep = message.metadata.steps[idx + 1];
423
834
  const result = observationStep?.type === "observation" ? observationStep.content : null;
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 ? "..." : ""}`));
835
+ 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 ? "..." : ""}`));
425
836
  }
426
837
  return null;
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`)));
838
+ }).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`)));
428
839
  }
429
840
 
430
841
  // src/components/MessageList.tsx
431
- import React8 from "react";
432
- import { Box as Box8, Text as Text7 } from "ink";
842
+ import React9 from "react";
843
+ import { Box as Box9, Text as Text8 } from "ink";
433
844
  function stripThinkingTags(content) {
434
845
  return content.replace(/<think>[\s\S]*?<\/think>/g, "").trim();
435
846
  }
436
- var MessageList = React8.memo(
847
+ var MessageList = React9.memo(
437
848
  function MessageList2({ messages }) {
438
849
  if (messages.length === 0) {
439
- return /* @__PURE__ */ React8.createElement(Box8, { paddingY: 1 }, /* @__PURE__ */ React8.createElement(Text7, { dimColor: true }, "No messages yet. Type a message to start!"));
850
+ return /* @__PURE__ */ React9.createElement(Box9, { paddingY: 1 }, /* @__PURE__ */ React9.createElement(Text8, { dimColor: true }, "No messages yet. Type a message to start!"));
440
851
  }
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) => {
852
+ return /* @__PURE__ */ React9.createElement(Box9, { flexDirection: "column", gap: 1, paddingY: 1 }, messages.map((message, index) => /* @__PURE__ */ React9.createElement(Box9, { key: index, flexDirection: "column", marginBottom: 1 }, /* @__PURE__ */ React9.createElement(Box9, null, /* @__PURE__ */ React9.createElement(Text8, { bold: true, color: message.role === "user" ? "cyan" : "green" }, message.role === "user" ? "\u{1F464} You" : "\u{1F916} Assistant"), /* @__PURE__ */ React9.createElement(Text8, { dimColor: true }, " \u2022 ", new Date(message.timestamp).toLocaleTimeString())), /* @__PURE__ */ React9.createElement(Box9, { paddingLeft: 2 }, message.metadata?.permissionDenied ? /* @__PURE__ */ React9.createElement(Text8, { color: "yellow" }, "\u26A0\uFE0F ", stripThinkingTags(message.content)) : /* @__PURE__ */ React9.createElement(Text8, null, stripThinkingTags(message.content))), message.metadata?.steps && message.metadata.steps.length > 0 && /* @__PURE__ */ React9.createElement(Box9, { paddingLeft: 2, marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React9.createElement(Text8, { dimColor: true, bold: true }, "\u{1F527} Agent Reasoning Trace (", message.metadata.steps.filter((s) => s.type === "action").length, " tools used,", " ", message.metadata.steps.length, " total steps)", message.metadata.tokenUsage && ` \u2022 ${message.metadata.tokenUsage.total} tokens`), /* @__PURE__ */ React9.createElement(Text8, { dimColor: true }, "Step types: ", message.metadata.steps.map((s) => s.type).join(", ")), message.metadata.steps.map((step, idx) => {
442
853
  if (step.type === "thought") {
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,
854
+ return /* @__PURE__ */ React9.createElement(Box9, { key: idx, paddingLeft: 2, marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React9.createElement(Text8, { color: "blue" }, "\u{1F4AD} Thought:"), /* @__PURE__ */ React9.createElement(
855
+ Text8,
445
856
  {
446
857
  dimColor: true
447
858
  },
@@ -453,10 +864,10 @@ var MessageList = React8.memo(
453
864
  const toolInput = step.metadata?.toolInput;
454
865
  const observationStep = message.metadata.steps[idx + 1];
455
866
  const result = observationStep?.type === "observation" ? observationStep.content : null;
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 ? "..." : ""}`));
867
+ return /* @__PURE__ */ React9.createElement(Box9, { key: idx, paddingLeft: 2, marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React9.createElement(Text8, { color: "yellow" }, "\u{1F527} Action: ", toolName), toolInput && /* @__PURE__ */ React9.createElement(Text8, { dimColor: true }, ` Input: ${typeof toolInput === "string" ? toolInput : JSON.stringify(toolInput).slice(0, 100)}`), result && /* @__PURE__ */ React9.createElement(Text8, { dimColor: true }, ` Result: ${typeof result === "string" ? result.slice(0, 200) : JSON.stringify(result).slice(0, 200)}${(typeof result === "string" ? result.length : JSON.stringify(result).length) > 200 ? "..." : ""}`));
457
868
  }
458
869
  return null;
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`)))));
870
+ }).filter(Boolean)), message.metadata?.tokenUsage && (!message.metadata.steps || message.metadata.steps.length === 0) && /* @__PURE__ */ React9.createElement(Box9, { paddingLeft: 2 }, /* @__PURE__ */ React9.createElement(Text8, { dimColor: true }, `${message.metadata.tokenUsage.total} tokens`)))));
460
871
  },
461
872
  (prevProps, nextProps) => {
462
873
  if (prevProps.messages.length !== nextProps.messages.length) {
@@ -467,8 +878,8 @@ var MessageList = React8.memo(
467
878
  );
468
879
 
469
880
  // src/components/LoginFlow.tsx
470
- import React9, { useState as useState2, useEffect as useEffect2 } from "react";
471
- import { Box as Box9, Text as Text8 } from "ink";
881
+ import React10, { useState as useState2, useEffect as useEffect2 } from "react";
882
+ import { Box as Box10, Text as Text9 } from "ink";
472
883
  import Spinner2 from "ink-spinner";
473
884
  import jwt from "jsonwebtoken";
474
885
  import open from "open";
@@ -578,7 +989,7 @@ var OAuthClient = class {
578
989
  * Sleep for specified milliseconds
579
990
  */
580
991
  sleep(ms) {
581
- return new Promise((resolve) => setTimeout(resolve, ms));
992
+ return new Promise((resolve3) => setTimeout(resolve3, ms));
582
993
  }
583
994
  };
584
995
 
@@ -631,31 +1042,31 @@ function LoginFlow({ apiUrl = "http://localhost:3000", configStore, onSuccess, o
631
1042
  }
632
1043
  }, [deviceFlow, status]);
633
1044
  if (status === "initiating") {
634
- return /* @__PURE__ */ React9.createElement(Box9, { flexDirection: "column", padding: 1 }, /* @__PURE__ */ React9.createElement(Box9, null, /* @__PURE__ */ React9.createElement(Text8, { color: "cyan" }, /* @__PURE__ */ React9.createElement(Spinner2, { type: "dots" }), " Initiating device authorization...")));
1045
+ return /* @__PURE__ */ React10.createElement(Box10, { flexDirection: "column", padding: 1 }, /* @__PURE__ */ React10.createElement(Box10, null, /* @__PURE__ */ React10.createElement(Text9, { color: "cyan" }, /* @__PURE__ */ React10.createElement(Spinner2, { type: "dots" }), " Initiating device authorization...")));
635
1046
  }
636
1047
  if (status === "error") {
637
- return /* @__PURE__ */ React9.createElement(Box9, { flexDirection: "column", padding: 1 }, /* @__PURE__ */ React9.createElement(Box9, { marginBottom: 1 }, /* @__PURE__ */ React9.createElement(Text8, { color: "red", bold: true }, "\u2716 Authentication Failed")), /* @__PURE__ */ React9.createElement(Box9, null, /* @__PURE__ */ React9.createElement(Text8, { color: "red" }, error)));
1048
+ return /* @__PURE__ */ React10.createElement(Box10, { flexDirection: "column", padding: 1 }, /* @__PURE__ */ React10.createElement(Box10, { marginBottom: 1 }, /* @__PURE__ */ React10.createElement(Text9, { color: "red", bold: true }, "\u2716 Authentication Failed")), /* @__PURE__ */ React10.createElement(Box10, null, /* @__PURE__ */ React10.createElement(Text9, { color: "red" }, error)));
638
1049
  }
639
1050
  if (status === "success") {
640
- return /* @__PURE__ */ React9.createElement(Box9, { flexDirection: "column", padding: 1 }, /* @__PURE__ */ React9.createElement(Box9, { marginBottom: 1 }, /* @__PURE__ */ React9.createElement(Text8, { color: "green", bold: true }, "\u2714 Successfully authenticated!")), /* @__PURE__ */ React9.createElement(Box9, null, /* @__PURE__ */ React9.createElement(Text8, { dimColor: true }, "You can now use B4M CLI with your account.")));
1051
+ return /* @__PURE__ */ React10.createElement(Box10, { flexDirection: "column", padding: 1 }, /* @__PURE__ */ React10.createElement(Box10, { marginBottom: 1 }, /* @__PURE__ */ React10.createElement(Text9, { color: "green", bold: true }, "\u2714 Successfully authenticated!")), /* @__PURE__ */ React10.createElement(Box10, null, /* @__PURE__ */ React10.createElement(Text9, { dimColor: true }, "You can now use B4M CLI with your account.")));
641
1052
  }
642
- return /* @__PURE__ */ React9.createElement(Box9, { flexDirection: "column", padding: 1, borderStyle: "round", borderColor: "cyan" }, /* @__PURE__ */ React9.createElement(Box9, { marginBottom: 1 }, /* @__PURE__ */ React9.createElement(Text8, { color: "cyan", bold: true }, "\u{1F510} Device Authorization")), /* @__PURE__ */ React9.createElement(Box9, { marginBottom: 1 }, /* @__PURE__ */ React9.createElement(Text8, null, "Opening browser automatically... If it doesn't open, please visit:")), /* @__PURE__ */ React9.createElement(Box9, { marginBottom: 1, paddingLeft: 2 }, /* @__PURE__ */ React9.createElement(Text8, { color: "blue", bold: true }, deviceFlow?.verification_uri)), /* @__PURE__ */ React9.createElement(Box9, { marginBottom: 1 }, /* @__PURE__ */ React9.createElement(Text8, null, "And enter this code when prompted:")), /* @__PURE__ */ React9.createElement(Box9, { marginBottom: 1, paddingLeft: 2 }, /* @__PURE__ */ React9.createElement(Text8, { color: "yellow", bold: true }, deviceFlow?.user_code)), /* @__PURE__ */ React9.createElement(Box9, { marginTop: 1 }, /* @__PURE__ */ React9.createElement(Text8, { color: "cyan" }, /* @__PURE__ */ React9.createElement(Spinner2, { type: "dots" }), " ", statusMessage)), /* @__PURE__ */ React9.createElement(Box9, { marginTop: 1 }, /* @__PURE__ */ React9.createElement(Text8, { dimColor: true }, "Expires in ", deviceFlow ? Math.floor(deviceFlow.expires_in / 60) : 0, " minutes")));
1053
+ return /* @__PURE__ */ React10.createElement(Box10, { flexDirection: "column", padding: 1, borderStyle: "round", borderColor: "cyan" }, /* @__PURE__ */ React10.createElement(Box10, { marginBottom: 1 }, /* @__PURE__ */ React10.createElement(Text9, { color: "cyan", bold: true }, "\u{1F510} Device Authorization")), /* @__PURE__ */ React10.createElement(Box10, { marginBottom: 1 }, /* @__PURE__ */ React10.createElement(Text9, null, "Opening browser automatically... If it doesn't open, please visit:")), /* @__PURE__ */ React10.createElement(Box10, { marginBottom: 1, paddingLeft: 2 }, /* @__PURE__ */ React10.createElement(Text9, { color: "blue", bold: true }, deviceFlow?.verification_uri)), /* @__PURE__ */ React10.createElement(Box10, { marginBottom: 1 }, /* @__PURE__ */ React10.createElement(Text9, null, "And enter this code when prompted:")), /* @__PURE__ */ React10.createElement(Box10, { marginBottom: 1, paddingLeft: 2 }, /* @__PURE__ */ React10.createElement(Text9, { color: "yellow", bold: true }, deviceFlow?.user_code)), /* @__PURE__ */ React10.createElement(Box10, { marginTop: 1 }, /* @__PURE__ */ React10.createElement(Text9, { color: "cyan" }, /* @__PURE__ */ React10.createElement(Spinner2, { type: "dots" }), " ", statusMessage)), /* @__PURE__ */ React10.createElement(Box10, { marginTop: 1 }, /* @__PURE__ */ React10.createElement(Text9, { dimColor: true }, "Expires in ", deviceFlow ? Math.floor(deviceFlow.expires_in / 60) : 0, " minutes")));
643
1054
  }
644
1055
 
645
1056
  // src/storage/SessionStore.ts
646
- import { promises as fs } from "fs";
647
- import path from "path";
1057
+ import { promises as fs3 } from "fs";
1058
+ import path3 from "path";
648
1059
  import { homedir } from "os";
649
1060
  var SessionStore = class {
650
1061
  constructor(basePath) {
651
- this.basePath = basePath || path.join(homedir(), ".bike4mind", "sessions");
1062
+ this.basePath = basePath || path3.join(homedir(), ".bike4mind", "sessions");
652
1063
  }
653
1064
  /**
654
1065
  * Initialize storage directory
655
1066
  */
656
1067
  async init() {
657
1068
  try {
658
- await fs.mkdir(this.basePath, { recursive: true });
1069
+ await fs3.mkdir(this.basePath, { recursive: true });
659
1070
  } catch (error) {
660
1071
  console.error("Failed to initialize session storage:", error);
661
1072
  throw error;
@@ -666,9 +1077,9 @@ var SessionStore = class {
666
1077
  */
667
1078
  async save(session) {
668
1079
  await this.init();
669
- const filePath = path.join(this.basePath, `${session.id}.json`);
1080
+ const filePath = path3.join(this.basePath, `${session.id}.json`);
670
1081
  try {
671
- await fs.writeFile(filePath, JSON.stringify(session, null, 2), "utf-8");
1082
+ await fs3.writeFile(filePath, JSON.stringify(session, null, 2), "utf-8");
672
1083
  } catch (error) {
673
1084
  console.error("Failed to save session:", error);
674
1085
  throw error;
@@ -678,9 +1089,9 @@ var SessionStore = class {
678
1089
  * Load a session from disk by ID
679
1090
  */
680
1091
  async load(id) {
681
- const filePath = path.join(this.basePath, `${id}.json`);
1092
+ const filePath = path3.join(this.basePath, `${id}.json`);
682
1093
  try {
683
- const data = await fs.readFile(filePath, "utf-8");
1094
+ const data = await fs3.readFile(filePath, "utf-8");
684
1095
  return JSON.parse(data);
685
1096
  } catch (error) {
686
1097
  if (error.code === "ENOENT") {
@@ -704,12 +1115,12 @@ var SessionStore = class {
704
1115
  async list() {
705
1116
  await this.init();
706
1117
  try {
707
- const files = await fs.readdir(this.basePath);
1118
+ const files = await fs3.readdir(this.basePath);
708
1119
  const jsonFiles = files.filter((f) => f.endsWith(".json"));
709
1120
  const sessions = await Promise.all(
710
1121
  jsonFiles.map(async (file) => {
711
- const filePath = path.join(this.basePath, file);
712
- const data = await fs.readFile(filePath, "utf-8");
1122
+ const filePath = path3.join(this.basePath, file);
1123
+ const data = await fs3.readFile(filePath, "utf-8");
713
1124
  return JSON.parse(data);
714
1125
  })
715
1126
  );
@@ -723,9 +1134,9 @@ var SessionStore = class {
723
1134
  * Delete a session
724
1135
  */
725
1136
  async delete(id) {
726
- const filePath = path.join(this.basePath, `${id}.json`);
1137
+ const filePath = path3.join(this.basePath, `${id}.json`);
727
1138
  try {
728
- await fs.unlink(filePath);
1139
+ await fs3.unlink(filePath);
729
1140
  return true;
730
1141
  } catch (error) {
731
1142
  if (error.code === "ENOENT") {
@@ -761,8 +1172,8 @@ var SessionStore = class {
761
1172
  };
762
1173
 
763
1174
  // src/storage/ConfigStore.ts
764
- import { promises as fs2 } from "fs";
765
- import path2 from "path";
1175
+ import { promises as fs4 } from "fs";
1176
+ import path4 from "path";
766
1177
  import { homedir as homedir2 } from "os";
767
1178
  import { v4 as uuidv4 } from "uuid";
768
1179
  import { z } from "zod";
@@ -836,15 +1247,15 @@ var DEFAULT_CONFIG = {
836
1247
  var ConfigStore = class {
837
1248
  constructor(configPath) {
838
1249
  this.config = null;
839
- this.configPath = configPath || path2.join(homedir2(), ".bike4mind", "config.json");
1250
+ this.configPath = configPath || path4.join(homedir2(), ".bike4mind", "config.json");
840
1251
  }
841
1252
  /**
842
1253
  * Initialize config directory
843
1254
  */
844
1255
  async init() {
845
- const dir = path2.dirname(this.configPath);
1256
+ const dir = path4.dirname(this.configPath);
846
1257
  try {
847
- await fs2.mkdir(dir, { recursive: true });
1258
+ await fs4.mkdir(dir, { recursive: true });
848
1259
  } catch (error) {
849
1260
  console.error("Failed to initialize config directory:", error);
850
1261
  throw error;
@@ -859,15 +1270,15 @@ var ConfigStore = class {
859
1270
  }
860
1271
  try {
861
1272
  try {
862
- const stats = await fs2.stat(this.configPath);
1273
+ const stats = await fs4.stat(this.configPath);
863
1274
  const mode = stats.mode & 511;
864
1275
  if (mode !== 384) {
865
1276
  console.warn(`\u26A0\uFE0F Config file has insecure permissions (${mode.toString(8)}). Setting to 0600...`);
866
- await fs2.chmod(this.configPath, 384);
1277
+ await fs4.chmod(this.configPath, 384);
867
1278
  }
868
1279
  } catch (statError) {
869
1280
  }
870
- const data = await fs2.readFile(this.configPath, "utf-8");
1281
+ const data = await fs4.readFile(this.configPath, "utf-8");
871
1282
  const rawConfig = JSON.parse(data);
872
1283
  if (rawConfig.apiConfig && "environment" in rawConfig.apiConfig) {
873
1284
  const oldApiConfig = rawConfig.apiConfig;
@@ -940,8 +1351,8 @@ var ConfigStore = class {
940
1351
  throw new Error("No configuration to save");
941
1352
  }
942
1353
  try {
943
- await fs2.writeFile(this.configPath, JSON.stringify(this.config, null, 2), "utf-8");
944
- await fs2.chmod(this.configPath, 384);
1354
+ await fs4.writeFile(this.configPath, JSON.stringify(this.config, null, 2), "utf-8");
1355
+ await fs4.chmod(this.configPath, 384);
945
1356
  } catch (error) {
946
1357
  console.error("Failed to save config:", error);
947
1358
  throw error;
@@ -1088,22 +1499,22 @@ var ConfigStore = class {
1088
1499
  };
1089
1500
 
1090
1501
  // src/storage/CommandHistoryStore.ts
1091
- import { promises as fs3 } from "fs";
1092
- import path3 from "path";
1502
+ import { promises as fs5 } from "fs";
1503
+ import path5 from "path";
1093
1504
  import { homedir as homedir3 } from "os";
1094
1505
  var MAX_HISTORY_ENTRIES = 1e3;
1095
1506
  var CommandHistoryStore = class {
1096
1507
  constructor(historyPath) {
1097
1508
  this.history = null;
1098
- this.historyPath = historyPath || path3.join(homedir3(), ".bike4mind", "history.jsonl");
1509
+ this.historyPath = historyPath || path5.join(homedir3(), ".bike4mind", "history.jsonl");
1099
1510
  }
1100
1511
  /**
1101
1512
  * Initialize history directory
1102
1513
  */
1103
1514
  async init() {
1104
- const dir = path3.dirname(this.historyPath);
1515
+ const dir = path5.dirname(this.historyPath);
1105
1516
  try {
1106
- await fs3.mkdir(dir, { recursive: true });
1517
+ await fs5.mkdir(dir, { recursive: true });
1107
1518
  } catch (error) {
1108
1519
  console.error("Failed to initialize history directory:", error);
1109
1520
  throw error;
@@ -1118,7 +1529,7 @@ var CommandHistoryStore = class {
1118
1529
  return this.history;
1119
1530
  }
1120
1531
  try {
1121
- const data = await fs3.readFile(this.historyPath, "utf-8");
1532
+ const data = await fs5.readFile(this.historyPath, "utf-8");
1122
1533
  const lines = data.trim().split("\n").filter((line) => line.length > 0);
1123
1534
  const entries = lines.map((line) => {
1124
1535
  try {
@@ -1155,7 +1566,7 @@ var CommandHistoryStore = class {
1155
1566
  };
1156
1567
  await this.init();
1157
1568
  const line = JSON.stringify(entry) + "\n";
1158
- await fs3.appendFile(this.historyPath, line, "utf-8");
1569
+ await fs5.appendFile(this.historyPath, line, "utf-8");
1159
1570
  this.history = [command, ...this.history || []];
1160
1571
  if (this.history.length > MAX_HISTORY_ENTRIES) {
1161
1572
  await this.trim();
@@ -1178,7 +1589,7 @@ var CommandHistoryStore = class {
1178
1589
  };
1179
1590
  return JSON.stringify(entry);
1180
1591
  }).join("\n");
1181
- await fs3.writeFile(this.historyPath, lines + "\n", "utf-8");
1592
+ await fs5.writeFile(this.historyPath, lines + "\n", "utf-8");
1182
1593
  this.history = trimmedCommands;
1183
1594
  }
1184
1595
  /**
@@ -1186,7 +1597,7 @@ var CommandHistoryStore = class {
1186
1597
  */
1187
1598
  async clear() {
1188
1599
  try {
1189
- await fs3.unlink(this.historyPath);
1600
+ await fs5.unlink(this.historyPath);
1190
1601
  } catch (error) {
1191
1602
  if (error.code !== "ENOENT") {
1192
1603
  throw error;
@@ -1960,7 +2371,7 @@ import { GoogleGenerativeAI } from "@google/generative-ai";
1960
2371
  import OpenAI2 from "openai";
1961
2372
 
1962
2373
  // ../../b4m-core/packages/services/dist/src/importHistoryService/index.js
1963
- import fs4, { unlinkSync } from "fs";
2374
+ import fs6, { unlinkSync } from "fs";
1964
2375
  import yauzl from "yauzl";
1965
2376
  import axios3 from "axios";
1966
2377
 
@@ -2567,190 +2978,196 @@ var listFabFilesBySessionSchema = z90.object({
2567
2978
  sessionId: z90.string()
2568
2979
  });
2569
2980
 
2570
- // ../../b4m-core/packages/services/dist/src/fabFileService/createByUrl.js
2981
+ // ../../b4m-core/packages/services/dist/src/fabFileService/listByQuest.js
2571
2982
  import { z as z91 } from "zod";
2572
- var createFabFileByUrlSchema = z91.object({
2573
- 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,})).+/)
2983
+ var listFabFilesByQuestSchema = z91.object({
2984
+ questId: z91.string()
2574
2985
  });
2575
2986
 
2576
- // ../../b4m-core/packages/services/dist/src/fabFileService/search.js
2987
+ // ../../b4m-core/packages/services/dist/src/fabFileService/createByUrl.js
2577
2988
  import { z as z92 } from "zod";
2578
- var searchFabFilesSchema = z92.object({
2579
- search: z92.string().optional(),
2580
- filters: z92.object({
2581
- tags: z92.array(z92.string()).optional(),
2582
- type: z92.enum(["text", "pdf", "url", "image", "excel", "word", "json", "csv", "markdown", "code"]).optional(),
2583
- shared: z92.coerce.boolean().optional(),
2989
+ var createFabFileByUrlSchema = z92.object({
2990
+ url: z92.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,})).+/)
2991
+ });
2992
+
2993
+ // ../../b4m-core/packages/services/dist/src/fabFileService/search.js
2994
+ import { z as z93 } from "zod";
2995
+ var searchFabFilesSchema = z93.object({
2996
+ search: z93.string().optional(),
2997
+ filters: z93.object({
2998
+ tags: z93.array(z93.string()).optional(),
2999
+ type: z93.enum(["text", "pdf", "url", "image", "excel", "word", "json", "csv", "markdown", "code"]).optional(),
3000
+ shared: z93.coerce.boolean().optional(),
2584
3001
  // Indicates if the user is searching for shared files
2585
- curated: z92.coerce.boolean().optional(),
3002
+ curated: z93.coerce.boolean().optional(),
2586
3003
  // Indicates if the user is searching for curated notebook files
2587
- projectId: z92.string().optional(),
2588
- ids: z92.array(z92.string()).optional()
3004
+ projectId: z93.string().optional(),
3005
+ ids: z93.array(z93.string()).optional()
2589
3006
  // Add support for filtering by IDs
2590
3007
  }).optional(),
2591
- pagination: z92.object({
2592
- page: z92.coerce.number(),
2593
- limit: z92.coerce.number()
3008
+ pagination: z93.object({
3009
+ page: z93.coerce.number(),
3010
+ limit: z93.coerce.number()
2594
3011
  }).optional(),
2595
- order: z92.object({
2596
- by: z92.enum(["createdAt", "fileName", "fileSize"]),
2597
- direction: z92.enum(["asc", "desc"])
3012
+ order: z93.object({
3013
+ by: z93.enum(["createdAt", "fileName", "fileSize"]),
3014
+ direction: z93.enum(["asc", "desc"])
2598
3015
  }).optional(),
2599
- options: z92.object({
2600
- includeShared: z92.coerce.boolean().optional()
3016
+ options: z93.object({
3017
+ includeShared: z93.coerce.boolean().optional()
2601
3018
  }).optional()
2602
3019
  });
2603
3020
 
2604
3021
  // ../../b4m-core/packages/services/dist/src/fabFileService/addFavorite.js
2605
- import { z as z93 } from "zod";
2606
- var addFavoriteParametersSchema3 = z93.object({
2607
- fileId: z93.string()
3022
+ import { z as z94 } from "zod";
3023
+ var addFavoriteParametersSchema3 = z94.object({
3024
+ fileId: z94.string()
2608
3025
  });
2609
3026
 
2610
3027
  // ../../b4m-core/packages/services/dist/src/fabFileService/deleteFavorite.js
2611
- import { z as z94 } from "zod";
2612
- var deleteFavoriteParametersSchema4 = z94.object({
2613
- fileId: z94.string()
3028
+ import { z as z95 } from "zod";
3029
+ var deleteFavoriteParametersSchema4 = z95.object({
3030
+ fileId: z95.string()
2614
3031
  });
2615
3032
 
2616
3033
  // ../../b4m-core/packages/services/dist/src/fabFileService/toggleTags.js
2617
- import { z as z95 } from "zod";
2618
- var fabFileToggleTagsSchema = z95.object({
2619
- ids: z95.array(z95.string()),
2620
- tags: z95.array(z95.string())
3034
+ import { z as z96 } from "zod";
3035
+ var fabFileToggleTagsSchema = z96.object({
3036
+ ids: z96.array(z96.string()),
3037
+ tags: z96.array(z96.string())
2621
3038
  });
2622
3039
 
2623
3040
  // ../../b4m-core/packages/services/dist/src/fabFileService/edit.js
2624
- import { z as z96 } from "zod";
3041
+ import { z as z97 } from "zod";
2625
3042
  import { diffLines } from "diff";
2626
- var editFabFileSchema = z96.object({
2627
- id: z96.string(),
2628
- instruction: z96.string(),
2629
- selection: z96.object({
2630
- start: z96.number(),
2631
- end: z96.number()
3043
+ var editFabFileSchema = z97.object({
3044
+ id: z97.string(),
3045
+ instruction: z97.string(),
3046
+ selection: z97.object({
3047
+ start: z97.number(),
3048
+ end: z97.number()
2632
3049
  }).optional(),
2633
- preserveFormatting: z96.boolean().optional().default(true),
2634
- applyImmediately: z96.boolean().optional().default(false)
3050
+ preserveFormatting: z97.boolean().optional().default(true),
3051
+ applyImmediately: z97.boolean().optional().default(false)
2635
3052
  });
2636
3053
 
2637
3054
  // ../../b4m-core/packages/services/dist/src/fabFileService/applyEdit.js
2638
3055
  import mime2 from "mime-types";
2639
3056
  import { v4 as uuidv43 } from "uuid";
2640
- import { z as z97 } from "zod";
2641
- var applyEditSchema = z97.object({
2642
- id: z97.string(),
2643
- modifiedContent: z97.string(),
2644
- createBackup: z97.boolean().optional().default(true)
3057
+ import { z as z98 } from "zod";
3058
+ var applyEditSchema = z98.object({
3059
+ id: z98.string(),
3060
+ modifiedContent: z98.string(),
3061
+ createBackup: z98.boolean().optional().default(true)
2645
3062
  });
2646
3063
 
2647
3064
  // ../../b4m-core/packages/services/dist/src/friendshipService/respondToFriendRequest.js
2648
- import { z as z98 } from "zod";
2649
- var respondToFriendRequestSchema = z98.object({
2650
- id: z98.string(),
3065
+ import { z as z99 } from "zod";
3066
+ var respondToFriendRequestSchema = z99.object({
3067
+ id: z99.string(),
2651
3068
  /** The user ID of the recipient of the friend request */
2652
- userId: z98.string(),
2653
- accept: z98.boolean()
3069
+ userId: z99.string(),
3070
+ accept: z99.boolean()
2654
3071
  });
2655
3072
 
2656
3073
  // ../../b4m-core/packages/services/dist/src/friendshipService/unfriend.js
2657
- import { z as z99 } from "zod";
2658
- var unfriendSchema = z99.object({
2659
- friendshipId: z99.string(),
3074
+ import { z as z100 } from "zod";
3075
+ var unfriendSchema = z100.object({
3076
+ friendshipId: z100.string(),
2660
3077
  /** The user ID of the user who wants to unfriend the other user */
2661
- userId: z99.string()
3078
+ userId: z100.string()
2662
3079
  });
2663
3080
 
2664
3081
  // ../../b4m-core/packages/services/dist/src/friendshipService/list.js
2665
- import { z as z100 } from "zod";
2666
- var listFriendsSchema = z100.object({
2667
- userId: z100.string()
3082
+ import { z as z101 } from "zod";
3083
+ var listFriendsSchema = z101.object({
3084
+ userId: z101.string()
2668
3085
  });
2669
- var listPendingFriendRequestsSchema = z100.object({
2670
- userId: z100.string()
3086
+ var listPendingFriendRequestsSchema = z101.object({
3087
+ userId: z101.string()
2671
3088
  });
2672
3089
 
2673
3090
  // ../../b4m-core/packages/services/dist/src/adminService/loginAs.js
2674
- import { z as z101 } from "zod";
2675
- var loginAsSchema = z101.object({
2676
- targetUserId: z101.string()
3091
+ import { z as z102 } from "zod";
3092
+ var loginAsSchema = z102.object({
3093
+ targetUserId: z102.string()
2677
3094
  });
2678
3095
 
2679
3096
  // ../../b4m-core/packages/services/dist/src/cacheService/get.js
2680
- import { z as z102 } from "zod";
2681
- var getParamsSchema = z102.object({
2682
- key: z102.string()
3097
+ import { z as z103 } from "zod";
3098
+ var getParamsSchema = z103.object({
3099
+ key: z103.string()
2683
3100
  });
2684
3101
 
2685
3102
  // ../../b4m-core/packages/services/dist/src/cacheService/set.js
2686
- import { z as z103 } from "zod";
2687
- var setParamsSchema = z103.object({
2688
- key: z103.string(),
2689
- value: z103.any(),
3103
+ import { z as z104 } from "zod";
3104
+ var setParamsSchema = z104.object({
3105
+ key: z104.string(),
3106
+ value: z104.any(),
2690
3107
  /**
2691
3108
  * Time to live in milliseconds
2692
3109
  */
2693
- ttl: z103.number(),
2694
- recache: z103.boolean().optional()
3110
+ ttl: z104.number(),
3111
+ recache: z104.boolean().optional()
2695
3112
  });
2696
3113
 
2697
3114
  // ../../b4m-core/packages/services/dist/src/cacheService/ttl.js
2698
- import { z as z104 } from "zod";
2699
- var ttlParamsSchema = z104.object({
2700
- key: z104.string()
3115
+ import { z as z105 } from "zod";
3116
+ var ttlParamsSchema = z105.object({
3117
+ key: z105.string()
2701
3118
  });
2702
3119
 
2703
3120
  // ../../b4m-core/packages/services/dist/src/cacheService/weeklyReports.js
2704
- import { z as z105 } from "zod";
3121
+ import { z as z106 } from "zod";
2705
3122
  import dayjs3 from "dayjs";
2706
- var weeklyReportSchema = z105.object({
2707
- startDate: z105.string(),
2708
- endDate: z105.string(),
2709
- report: z105.string(),
2710
- aiInsights: z105.string().nullable()
3123
+ var weeklyReportSchema = z106.object({
3124
+ startDate: z106.string(),
3125
+ endDate: z106.string(),
3126
+ report: z106.string(),
3127
+ aiInsights: z106.string().nullable()
2711
3128
  });
2712
3129
 
2713
3130
  // ../../b4m-core/packages/services/dist/src/embeddingCacheService/generateCacheKey.js
2714
3131
  import crypto2 from "crypto";
2715
3132
 
2716
3133
  // ../../b4m-core/packages/services/dist/src/researchAgentService/create.js
2717
- import { z as z106 } from "zod";
2718
- var researchAgentCreateSchema = z106.object({
2719
- name: z106.string().min(1),
2720
- description: z106.string().min(1)
2721
- });
2722
-
2723
- // ../../b4m-core/packages/services/dist/src/researchAgentService/update.js
2724
3134
  import { z as z107 } from "zod";
2725
- var researchAgentUpdateSchema = z107.object({
2726
- id: z107.string(),
3135
+ var researchAgentCreateSchema = z107.object({
2727
3136
  name: z107.string().min(1),
2728
3137
  description: z107.string().min(1)
2729
3138
  });
2730
3139
 
2731
- // ../../b4m-core/packages/services/dist/src/researchAgentService/remove.js
3140
+ // ../../b4m-core/packages/services/dist/src/researchAgentService/update.js
2732
3141
  import { z as z108 } from "zod";
2733
- var researchAgentRemoveSchema = z108.object({
2734
- id: z108.string()
3142
+ var researchAgentUpdateSchema = z108.object({
3143
+ id: z108.string(),
3144
+ name: z108.string().min(1),
3145
+ description: z108.string().min(1)
2735
3146
  });
2736
3147
 
2737
- // ../../b4m-core/packages/services/dist/src/researchAgentService/get.js
3148
+ // ../../b4m-core/packages/services/dist/src/researchAgentService/remove.js
2738
3149
  import { z as z109 } from "zod";
2739
- var researchAgentGetSchema = z109.object({
3150
+ var researchAgentRemoveSchema = z109.object({
2740
3151
  id: z109.string()
2741
3152
  });
2742
3153
 
2743
- // ../../b4m-core/packages/services/dist/src/researchAgentService/listFiles.js
3154
+ // ../../b4m-core/packages/services/dist/src/researchAgentService/get.js
2744
3155
  import { z as z110 } from "zod";
2745
- var researchAgentListFilesSchema = z110.object({
3156
+ var researchAgentGetSchema = z110.object({
3157
+ id: z110.string()
3158
+ });
3159
+
3160
+ // ../../b4m-core/packages/services/dist/src/researchAgentService/listFiles.js
3161
+ import { z as z111 } from "zod";
3162
+ var researchAgentListFilesSchema = z111.object({
2746
3163
  /**
2747
3164
  * The ID of the research agent
2748
3165
  */
2749
- id: z110.string()
3166
+ id: z111.string()
2750
3167
  });
2751
3168
 
2752
3169
  // ../../b4m-core/packages/services/dist/src/researchTaskService/process.js
2753
- import { z as z111 } from "zod";
3170
+ import { z as z112 } from "zod";
2754
3171
 
2755
3172
  // ../../b4m-core/packages/services/dist/src/lib/turndown.js
2756
3173
  import turndown from "turndown";
@@ -3141,316 +3558,316 @@ var deepResearchTool = {
3141
3558
  };
3142
3559
 
3143
3560
  // ../../b4m-core/packages/services/dist/src/researchTaskService/process.js
3144
- var ResearchTaskProcessSchema = z111.object({
3145
- id: z111.string()
3561
+ var ResearchTaskProcessSchema = z112.object({
3562
+ id: z112.string()
3146
3563
  });
3147
3564
 
3148
3565
  // ../../b4m-core/packages/services/dist/src/researchTaskService/create.js
3149
- import { z as z112 } from "zod";
3150
- var researchTaskCreateSchema = z112.object({
3151
- researchAgentId: z112.string(),
3152
- title: z112.string().max(100),
3153
- description: z112.string().max(500),
3154
- prompt: z112.string().max(500).optional(),
3155
- type: z112.nativeEnum(ResearchTaskType),
3156
- executionType: z112.nativeEnum(ResearchTaskExecutionType).default(ResearchTaskExecutionType.ON_DEMAND),
3157
- fileTagId: z112.string().optional(),
3158
- autoGeneratedTag: z112.object({
3159
- name: z112.string(),
3160
- icon: z112.string(),
3161
- color: z112.string()
3566
+ import { z as z113 } from "zod";
3567
+ var researchTaskCreateSchema = z113.object({
3568
+ researchAgentId: z113.string(),
3569
+ title: z113.string().max(100),
3570
+ description: z113.string().max(500),
3571
+ prompt: z113.string().max(500).optional(),
3572
+ type: z113.nativeEnum(ResearchTaskType),
3573
+ executionType: z113.nativeEnum(ResearchTaskExecutionType).default(ResearchTaskExecutionType.ON_DEMAND),
3574
+ fileTagId: z113.string().optional(),
3575
+ autoGeneratedTag: z113.object({
3576
+ name: z113.string(),
3577
+ icon: z113.string(),
3578
+ color: z113.string()
3162
3579
  }).optional()
3163
3580
  });
3164
3581
  var researchTaskScrapeCreateSchema = researchTaskCreateSchema.extend({
3165
- urls: z112.array(z112.string().url()).min(1),
3166
- canDiscoverLinks: z112.boolean()
3582
+ urls: z113.array(z113.string().url()).min(1),
3583
+ canDiscoverLinks: z113.boolean()
3167
3584
  });
3168
3585
  var researchTaskPeriodicCreateSchema = researchTaskCreateSchema.extend({
3169
- executionPeriodicStartAt: z112.coerce.date(),
3170
- executionPeriodicEndAt: z112.coerce.date(),
3171
- executionPeriodicFrequency: z112.nativeEnum(ResearchTaskPeriodicFrequencyType)
3586
+ executionPeriodicStartAt: z113.coerce.date(),
3587
+ executionPeriodicEndAt: z113.coerce.date(),
3588
+ executionPeriodicFrequency: z113.nativeEnum(ResearchTaskPeriodicFrequencyType)
3172
3589
  });
3173
3590
  var researchTaskScheduledCreateSchema = researchTaskCreateSchema.extend({
3174
- executionScheduledAt: z112.coerce.date()
3591
+ executionScheduledAt: z113.coerce.date()
3175
3592
  });
3176
3593
  var researchTaskDeepResearchCreateSchema = researchTaskCreateSchema.extend({
3177
- maxDepth: z112.number().min(1).max(10).optional()
3594
+ maxDepth: z113.number().min(1).max(10).optional()
3178
3595
  });
3179
3596
 
3180
3597
  // ../../b4m-core/packages/services/dist/src/researchTaskService/search.js
3181
- import { z as z113 } from "zod";
3182
- var searchResearchTasksSchema = z113.object({
3183
- search: z113.string().optional(),
3598
+ import { z as z114 } from "zod";
3599
+ var searchResearchTasksSchema = z114.object({
3600
+ search: z114.string().optional(),
3184
3601
  // ADD FILTERS SCHEMA HERE
3185
3602
  // filters: z
3186
3603
  // .object({
3187
3604
  // userId: z.string().optional(),
3188
3605
  // })
3189
3606
  // .optional(),
3190
- pagination: z113.object({
3191
- page: z113.coerce.number().optional(),
3192
- limit: z113.coerce.number().optional()
3607
+ pagination: z114.object({
3608
+ page: z114.coerce.number().optional(),
3609
+ limit: z114.coerce.number().optional()
3193
3610
  }).optional(),
3194
- orderBy: z113.object({
3195
- by: z113.enum(["createdAt", "updatedAt"]).optional(),
3196
- direction: z113.enum(["asc", "desc"]).optional()
3611
+ orderBy: z114.object({
3612
+ by: z114.enum(["createdAt", "updatedAt"]).optional(),
3613
+ direction: z114.enum(["asc", "desc"]).optional()
3197
3614
  }).optional()
3198
3615
  });
3199
3616
 
3200
3617
  // ../../b4m-core/packages/services/dist/src/researchTaskService/get.js
3201
- import { z as z114 } from "zod";
3202
- var getResearchTaskSchema = z114.object({
3203
- id: z114.string().min(1)
3618
+ import { z as z115 } from "zod";
3619
+ var getResearchTaskSchema = z115.object({
3620
+ id: z115.string().min(1)
3204
3621
  });
3205
3622
 
3206
3623
  // ../../b4m-core/packages/services/dist/src/researchTaskService/update.js
3207
- import { z as z115 } from "zod";
3208
- var updateResearchTaskSchema = z115.object({
3209
- id: z115.string(),
3210
- title: z115.string(),
3211
- description: z115.string(),
3212
- type: z115.nativeEnum(ResearchTaskType)
3624
+ import { z as z116 } from "zod";
3625
+ var updateResearchTaskSchema = z116.object({
3626
+ id: z116.string(),
3627
+ title: z116.string(),
3628
+ description: z116.string(),
3629
+ type: z116.nativeEnum(ResearchTaskType)
3213
3630
  });
3214
3631
  var researchTaskScrapeUpdateSchema = updateResearchTaskSchema.extend({
3215
- urls: z115.array(z115.string().url()).min(1),
3216
- canDiscoverLinks: z115.boolean()
3632
+ urls: z116.array(z116.string().url()).min(1),
3633
+ canDiscoverLinks: z116.boolean()
3217
3634
  });
3218
3635
 
3219
3636
  // ../../b4m-core/packages/services/dist/src/researchTaskService/listByAgentId.js
3220
- import { z as z116 } from "zod";
3221
- var listByAgentIdSchema = z116.object({
3222
- researchAgentId: z116.string()
3637
+ import { z as z117 } from "zod";
3638
+ var listByAgentIdSchema = z117.object({
3639
+ researchAgentId: z117.string()
3223
3640
  });
3224
3641
 
3225
3642
  // ../../b4m-core/packages/services/dist/src/researchTaskService/remove.js
3226
- import { z as z117 } from "zod";
3227
- var researchTaskRemoveSchema = z117.object({
3228
- id: z117.string().min(1)
3643
+ import { z as z118 } from "zod";
3644
+ var researchTaskRemoveSchema = z118.object({
3645
+ id: z118.string().min(1)
3229
3646
  });
3230
3647
 
3231
3648
  // ../../b4m-core/packages/services/dist/src/researchTaskService/retry.js
3232
- import { z as z118 } from "zod";
3233
- var researchTaskRetrySchema = z118.object({
3234
- id: z118.string(),
3235
- userId: z118.string()
3649
+ import { z as z119 } from "zod";
3650
+ var researchTaskRetrySchema = z119.object({
3651
+ id: z119.string(),
3652
+ userId: z119.string()
3236
3653
  });
3237
3654
 
3238
3655
  // ../../b4m-core/packages/services/dist/src/researchTaskService/processDiscoveredLinks.js
3239
3656
  import axios4 from "axios";
3240
- import { z as z119 } from "zod";
3657
+ import { z as z120 } from "zod";
3241
3658
  import plimit from "p-limit";
3242
3659
  import pLimit2 from "p-limit";
3243
- var researchTaskProcessDiscoveredLinksSchema = z119.object({
3244
- id: z119.string()
3660
+ var researchTaskProcessDiscoveredLinksSchema = z120.object({
3661
+ id: z120.string()
3245
3662
  });
3246
3663
 
3247
3664
  // ../../b4m-core/packages/services/dist/src/researchTaskService/downloadRelevantLinks.js
3248
- import { z as z120 } from "zod";
3665
+ import { z as z121 } from "zod";
3249
3666
  import plimit2 from "p-limit";
3250
3667
  import axios5 from "axios";
3251
3668
  import { fileTypeFromBuffer } from "file-type";
3252
- var researchTaskDownloadRelevantLinksSchema = z120.object({
3253
- id: z120.string()
3669
+ var researchTaskDownloadRelevantLinksSchema = z121.object({
3670
+ id: z121.string()
3254
3671
  });
3255
3672
 
3256
3673
  // ../../b4m-core/packages/services/dist/src/researchData/remove.js
3257
- import { z as z121 } from "zod";
3258
- var researchDataRemoveSchema = z121.object({
3259
- id: z121.string(),
3260
- researchAgentId: z121.string()
3674
+ import { z as z122 } from "zod";
3675
+ var researchDataRemoveSchema = z122.object({
3676
+ id: z122.string(),
3677
+ researchAgentId: z122.string()
3261
3678
  });
3262
3679
 
3263
3680
  // ../../b4m-core/packages/services/dist/src/taskSchedulerService/create.js
3264
- import { z as z122 } from "zod";
3265
- var researchTaskPayload = z122.object({
3266
- id: z122.string(),
3267
- userId: z122.string()
3681
+ import { z as z123 } from "zod";
3682
+ var researchTaskPayload = z123.object({
3683
+ id: z123.string(),
3684
+ userId: z123.string()
3268
3685
  });
3269
- var customTaskPayload = z122.object({
3270
- test: z122.string()
3686
+ var customTaskPayload = z123.object({
3687
+ test: z123.string()
3271
3688
  });
3272
- var taskSchedulerCreate = z122.discriminatedUnion("handler", [
3273
- z122.object({
3274
- handler: z122.literal(TaskScheduleHandler.RESEARCH_TASK_PROCESS),
3689
+ var taskSchedulerCreate = z123.discriminatedUnion("handler", [
3690
+ z123.object({
3691
+ handler: z123.literal(TaskScheduleHandler.RESEARCH_TASK_PROCESS),
3275
3692
  payload: researchTaskPayload,
3276
- processDate: z122.date()
3693
+ processDate: z123.date()
3277
3694
  }),
3278
- z122.object({
3279
- handler: z122.literal(TaskScheduleHandler.CUSTOM_TASK_PROCESS),
3695
+ z123.object({
3696
+ handler: z123.literal(TaskScheduleHandler.CUSTOM_TASK_PROCESS),
3280
3697
  payload: customTaskPayload,
3281
- processDate: z122.date()
3698
+ processDate: z123.date()
3282
3699
  })
3283
3700
  ]);
3284
3701
 
3285
3702
  // ../../b4m-core/packages/services/dist/src/tagService/createFileTag.js
3286
- import { z as z123 } from "zod";
3287
- var tagCreateFileTagSchema = z123.object({
3288
- name: z123.string(),
3289
- icon: z123.string().optional(),
3290
- color: z123.string().optional(),
3291
- description: z123.string().optional()
3292
- });
3293
-
3294
- // ../../b4m-core/packages/services/dist/src/tagService/create.js
3295
3703
  import { z as z124 } from "zod";
3296
- var tagCreateSchema = z124.object({
3704
+ var tagCreateFileTagSchema = z124.object({
3297
3705
  name: z124.string(),
3298
3706
  icon: z124.string().optional(),
3299
- description: z124.string().optional(),
3300
3707
  color: z124.string().optional(),
3301
- type: z124.nativeEnum(TagType)
3708
+ description: z124.string().optional()
3302
3709
  });
3303
3710
 
3304
- // ../../b4m-core/packages/services/dist/src/tagService/update.js
3711
+ // ../../b4m-core/packages/services/dist/src/tagService/create.js
3305
3712
  import { z as z125 } from "zod";
3306
- var tagUpdateSchema = z125.object({
3307
- id: z125.string(),
3308
- name: z125.string().optional(),
3713
+ var tagCreateSchema = z125.object({
3714
+ name: z125.string(),
3309
3715
  icon: z125.string().optional(),
3310
3716
  description: z125.string().optional(),
3311
- color: z125.string().optional()
3717
+ color: z125.string().optional(),
3718
+ type: z125.nativeEnum(TagType)
3312
3719
  });
3313
3720
 
3314
- // ../../b4m-core/packages/services/dist/src/tagService/remove.js
3721
+ // ../../b4m-core/packages/services/dist/src/tagService/update.js
3315
3722
  import { z as z126 } from "zod";
3316
- var tagRemoveSchema = z126.object({
3317
- id: z126.string()
3723
+ var tagUpdateSchema = z126.object({
3724
+ id: z126.string(),
3725
+ name: z126.string().optional(),
3726
+ icon: z126.string().optional(),
3727
+ description: z126.string().optional(),
3728
+ color: z126.string().optional()
3318
3729
  });
3319
3730
 
3320
- // ../../b4m-core/packages/services/dist/src/artifactService/create.js
3731
+ // ../../b4m-core/packages/services/dist/src/tagService/remove.js
3321
3732
  import { z as z127 } from "zod";
3322
- var createArtifactSchema = z127.object({
3323
- id: z127.string().optional(),
3733
+ var tagRemoveSchema = z127.object({
3734
+ id: z127.string()
3735
+ });
3736
+
3737
+ // ../../b4m-core/packages/services/dist/src/artifactService/create.js
3738
+ import { z as z128 } from "zod";
3739
+ var createArtifactSchema = z128.object({
3740
+ id: z128.string().optional(),
3324
3741
  // Allow custom ID for AI-generated artifacts
3325
- type: z127.enum(["mermaid", "recharts", "python", "react", "html", "svg", "code", "quest", "file", "questmaster"]),
3326
- title: z127.string().min(1).max(255),
3327
- description: z127.string().max(1e3).optional(),
3328
- content: z127.string().min(1),
3329
- projectId: z127.string().optional(),
3330
- organizationId: z127.string().optional(),
3331
- visibility: z127.enum(["private", "project", "organization", "public"]).default("private"),
3332
- tags: z127.array(z127.string().max(50)).max(20).default([]),
3333
- versionTag: z127.string().max(100).optional(),
3334
- sourceQuestId: z127.string().optional(),
3335
- sessionId: z127.string().optional(),
3336
- parentArtifactId: z127.string().optional(),
3337
- permissions: z127.object({
3338
- canRead: z127.array(z127.string()).default([]),
3339
- canWrite: z127.array(z127.string()).default([]),
3340
- canDelete: z127.array(z127.string()).default([]),
3341
- isPublic: z127.boolean().default(false),
3342
- inheritFromProject: z127.boolean().default(true)
3742
+ type: z128.enum(["mermaid", "recharts", "python", "react", "html", "svg", "code", "quest", "file", "questmaster"]),
3743
+ title: z128.string().min(1).max(255),
3744
+ description: z128.string().max(1e3).optional(),
3745
+ content: z128.string().min(1),
3746
+ projectId: z128.string().optional(),
3747
+ organizationId: z128.string().optional(),
3748
+ visibility: z128.enum(["private", "project", "organization", "public"]).default("private"),
3749
+ tags: z128.array(z128.string().max(50)).max(20).default([]),
3750
+ versionTag: z128.string().max(100).optional(),
3751
+ sourceQuestId: z128.string().optional(),
3752
+ sessionId: z128.string().optional(),
3753
+ parentArtifactId: z128.string().optional(),
3754
+ permissions: z128.object({
3755
+ canRead: z128.array(z128.string()).default([]),
3756
+ canWrite: z128.array(z128.string()).default([]),
3757
+ canDelete: z128.array(z128.string()).default([]),
3758
+ isPublic: z128.boolean().default(false),
3759
+ inheritFromProject: z128.boolean().default(true)
3343
3760
  }).optional(),
3344
- metadata: z127.record(z127.unknown()).default({})
3761
+ metadata: z128.record(z128.unknown()).default({})
3345
3762
  });
3346
3763
 
3347
3764
  // ../../b4m-core/packages/services/dist/src/artifactService/get.js
3348
- import { z as z128 } from "zod";
3349
- var getArtifactSchema = z128.object({
3350
- id: z128.string(),
3351
- includeContent: z128.boolean().default(false),
3352
- includeVersions: z128.boolean().default(false),
3353
- version: z128.number().optional()
3765
+ import { z as z129 } from "zod";
3766
+ var getArtifactSchema = z129.object({
3767
+ id: z129.string(),
3768
+ includeContent: z129.boolean().default(false),
3769
+ includeVersions: z129.boolean().default(false),
3770
+ version: z129.number().optional()
3354
3771
  });
3355
3772
 
3356
3773
  // ../../b4m-core/packages/services/dist/src/artifactService/list.js
3357
- import { z as z129 } from "zod";
3358
- var listArtifactsSchema = z129.object({
3359
- type: z129.string().optional(),
3360
- status: z129.enum(["draft", "review", "published", "archived"]).optional(),
3361
- visibility: z129.enum(["private", "project", "organization", "public"]).optional(),
3362
- projectId: z129.string().optional(),
3363
- sessionId: z129.string().optional(),
3364
- tags: z129.array(z129.string()).optional(),
3365
- search: z129.string().optional(),
3366
- limit: z129.number().min(1).max(100).default(20),
3367
- offset: z129.number().min(0).default(0),
3368
- sortBy: z129.enum(["createdAt", "updatedAt", "title", "type"]).default("updatedAt"),
3369
- sortOrder: z129.enum(["asc", "desc"]).default("desc"),
3370
- includeDeleted: z129.boolean().default(false)
3774
+ import { z as z130 } from "zod";
3775
+ var listArtifactsSchema = z130.object({
3776
+ type: z130.string().optional(),
3777
+ status: z130.enum(["draft", "review", "published", "archived"]).optional(),
3778
+ visibility: z130.enum(["private", "project", "organization", "public"]).optional(),
3779
+ projectId: z130.string().optional(),
3780
+ sessionId: z130.string().optional(),
3781
+ tags: z130.array(z130.string()).optional(),
3782
+ search: z130.string().optional(),
3783
+ limit: z130.number().min(1).max(100).default(20),
3784
+ offset: z130.number().min(0).default(0),
3785
+ sortBy: z130.enum(["createdAt", "updatedAt", "title", "type"]).default("updatedAt"),
3786
+ sortOrder: z130.enum(["asc", "desc"]).default("desc"),
3787
+ includeDeleted: z130.boolean().default(false)
3371
3788
  });
3372
3789
 
3373
3790
  // ../../b4m-core/packages/services/dist/src/artifactService/update.js
3374
- import { z as z130 } from "zod";
3375
- var updateArtifactSchema = z130.object({
3376
- id: z130.string(),
3377
- title: z130.string().min(1).max(255).optional(),
3378
- description: z130.string().max(1e3).optional(),
3379
- content: z130.string().optional(),
3380
- visibility: z130.enum(["private", "project", "organization", "public"]).optional(),
3381
- status: z130.enum(["draft", "review", "published", "archived"]).optional(),
3382
- tags: z130.array(z130.string().max(50)).max(20).optional(),
3383
- versionTag: z130.string().max(100).optional(),
3384
- permissions: z130.object({
3385
- canRead: z130.array(z130.string()).optional(),
3386
- canWrite: z130.array(z130.string()).optional(),
3387
- canDelete: z130.array(z130.string()).optional(),
3388
- isPublic: z130.boolean().optional(),
3389
- inheritFromProject: z130.boolean().optional()
3791
+ import { z as z131 } from "zod";
3792
+ var updateArtifactSchema = z131.object({
3793
+ id: z131.string(),
3794
+ title: z131.string().min(1).max(255).optional(),
3795
+ description: z131.string().max(1e3).optional(),
3796
+ content: z131.string().optional(),
3797
+ visibility: z131.enum(["private", "project", "organization", "public"]).optional(),
3798
+ status: z131.enum(["draft", "review", "published", "archived"]).optional(),
3799
+ tags: z131.array(z131.string().max(50)).max(20).optional(),
3800
+ versionTag: z131.string().max(100).optional(),
3801
+ permissions: z131.object({
3802
+ canRead: z131.array(z131.string()).optional(),
3803
+ canWrite: z131.array(z131.string()).optional(),
3804
+ canDelete: z131.array(z131.string()).optional(),
3805
+ isPublic: z131.boolean().optional(),
3806
+ inheritFromProject: z131.boolean().optional()
3390
3807
  }).optional(),
3391
- metadata: z130.record(z130.unknown()).optional(),
3392
- changes: z130.array(z130.string()).optional(),
3393
- changeDescription: z130.string().max(1e3).optional(),
3394
- createNewVersion: z130.boolean().optional(),
3395
- versionMessage: z130.string().max(500).optional()
3808
+ metadata: z131.record(z131.unknown()).optional(),
3809
+ changes: z131.array(z131.string()).optional(),
3810
+ changeDescription: z131.string().max(1e3).optional(),
3811
+ createNewVersion: z131.boolean().optional(),
3812
+ versionMessage: z131.string().max(500).optional()
3396
3813
  });
3397
3814
 
3398
3815
  // ../../b4m-core/packages/services/dist/src/artifactService/delete.js
3399
- import { z as z131 } from "zod";
3400
- var deleteArtifactSchema = z131.object({
3401
- id: z131.string(),
3402
- hardDelete: z131.boolean().default(false)
3816
+ import { z as z132 } from "zod";
3817
+ var deleteArtifactSchema = z132.object({
3818
+ id: z132.string(),
3819
+ hardDelete: z132.boolean().default(false)
3403
3820
  // For future implementation
3404
3821
  });
3405
3822
 
3406
3823
  // ../../b4m-core/packages/services/dist/src/questMasterService/create.js
3407
- import { z as z132 } from "zod";
3408
- var questSchema = z132.object({
3409
- id: z132.string(),
3410
- title: z132.string().min(1).max(255),
3411
- description: z132.string().max(1e3),
3412
- status: z132.enum(["not_started", "in_progress", "completed", "blocked"]).default("not_started"),
3413
- order: z132.number().min(0),
3414
- dependencies: z132.array(z132.string()).default([]),
3415
- estimatedTime: z132.string().optional()
3416
- });
3417
- var questResourceSchema = z132.object({
3418
- title: z132.string().min(1).max(255),
3419
- url: z132.string().url(),
3420
- type: z132.enum(["documentation", "tutorial", "reference", "example"])
3421
- });
3422
- var createQuestMasterSchema = z132.object({
3423
- title: z132.string().min(1).max(255),
3424
- description: z132.string().max(1e3).optional(),
3425
- goal: z132.string().min(1).max(1e3),
3426
- complexity: z132.enum(["beginner", "intermediate", "advanced", "expert"]),
3427
- estimatedTotalTime: z132.string().optional(),
3428
- prerequisites: z132.array(z132.string().max(200)).default([]),
3429
- quests: z132.array(questSchema).min(1),
3430
- resources: z132.array(questResourceSchema).default([]),
3431
- projectId: z132.string().optional(),
3432
- organizationId: z132.string().optional(),
3433
- visibility: z132.enum(["private", "project", "organization", "public"]).default("private"),
3434
- tags: z132.array(z132.string().max(50)).max(20).default([]),
3435
- permissions: z132.object({
3436
- canRead: z132.array(z132.string()).default([]),
3437
- canWrite: z132.array(z132.string()).default([]),
3438
- canDelete: z132.array(z132.string()).default([]),
3439
- isPublic: z132.boolean().default(false),
3440
- inheritFromProject: z132.boolean().default(true)
3824
+ import { z as z133 } from "zod";
3825
+ var questSchema = z133.object({
3826
+ id: z133.string(),
3827
+ title: z133.string().min(1).max(255),
3828
+ description: z133.string().max(1e3),
3829
+ status: z133.enum(["not_started", "in_progress", "completed", "blocked"]).default("not_started"),
3830
+ order: z133.number().min(0),
3831
+ dependencies: z133.array(z133.string()).default([]),
3832
+ estimatedTime: z133.string().optional()
3833
+ });
3834
+ var questResourceSchema = z133.object({
3835
+ title: z133.string().min(1).max(255),
3836
+ url: z133.string().url(),
3837
+ type: z133.enum(["documentation", "tutorial", "reference", "example"])
3838
+ });
3839
+ var createQuestMasterSchema = z133.object({
3840
+ title: z133.string().min(1).max(255),
3841
+ description: z133.string().max(1e3).optional(),
3842
+ goal: z133.string().min(1).max(1e3),
3843
+ complexity: z133.enum(["beginner", "intermediate", "advanced", "expert"]),
3844
+ estimatedTotalTime: z133.string().optional(),
3845
+ prerequisites: z133.array(z133.string().max(200)).default([]),
3846
+ quests: z133.array(questSchema).min(1),
3847
+ resources: z133.array(questResourceSchema).default([]),
3848
+ projectId: z133.string().optional(),
3849
+ organizationId: z133.string().optional(),
3850
+ visibility: z133.enum(["private", "project", "organization", "public"]).default("private"),
3851
+ tags: z133.array(z133.string().max(50)).max(20).default([]),
3852
+ permissions: z133.object({
3853
+ canRead: z133.array(z133.string()).default([]),
3854
+ canWrite: z133.array(z133.string()).default([]),
3855
+ canDelete: z133.array(z133.string()).default([]),
3856
+ isPublic: z133.boolean().default(false),
3857
+ inheritFromProject: z133.boolean().default(true)
3441
3858
  }).optional(),
3442
- sourceQuestId: z132.string().optional(),
3443
- sessionId: z132.string().optional(),
3444
- metadata: z132.record(z132.unknown()).default({})
3859
+ sourceQuestId: z133.string().optional(),
3860
+ sessionId: z133.string().optional(),
3861
+ metadata: z133.record(z133.unknown()).default({})
3445
3862
  });
3446
3863
 
3447
3864
  // ../../b4m-core/packages/services/dist/src/questMasterService/updateQuestStatus.js
3448
- import { z as z133 } from "zod";
3449
- var updateQuestStatusSchema = z133.object({
3450
- artifactId: z133.string(),
3451
- questId: z133.string(),
3452
- status: z133.enum(["not_started", "in_progress", "completed", "blocked"]),
3453
- completionNote: z133.string().max(500).optional()
3865
+ import { z as z134 } from "zod";
3866
+ var updateQuestStatusSchema = z134.object({
3867
+ artifactId: z134.string(),
3868
+ questId: z134.string(),
3869
+ status: z134.enum(["not_started", "in_progress", "completed", "blocked"]),
3870
+ completionNote: z134.string().max(500).optional()
3454
3871
  });
3455
3872
 
3456
3873
  // ../../b4m-core/packages/services/dist/src/dataLakeService/opensearchClient.js
@@ -3470,63 +3887,63 @@ import { v4 as uuidv44 } from "uuid";
3470
3887
  import { randomUUID as randomUUID5 } from "crypto";
3471
3888
 
3472
3889
  // ../../b4m-core/packages/services/dist/src/emailIngestionService/types.js
3473
- import { z as z134 } from "zod";
3474
- var processIngestedEmailOptionsSchema = z134.object({
3475
- platformDomain: z134.string().optional(),
3476
- isNewsletter: z134.boolean().optional()
3890
+ import { z as z135 } from "zod";
3891
+ var processIngestedEmailOptionsSchema = z135.object({
3892
+ platformDomain: z135.string().optional(),
3893
+ isNewsletter: z135.boolean().optional()
3477
3894
  }).optional();
3478
- var emailAttachmentSchema = z134.object({
3479
- filename: z134.string().optional(),
3480
- contentType: z134.string().optional(),
3481
- contentDisposition: z134.string().optional(),
3482
- size: z134.number().min(0),
3483
- content: z134.instanceof(Buffer),
3484
- related: z134.boolean().optional()
3485
- });
3486
- var parsedEmailObjectSchema = z134.object({
3487
- messageId: z134.string().optional(),
3488
- inReplyTo: z134.string().optional(),
3489
- references: z134.union([z134.string(), z134.array(z134.string())]).optional(),
3490
- from: z134.any().optional(),
3895
+ var emailAttachmentSchema = z135.object({
3896
+ filename: z135.string().optional(),
3897
+ contentType: z135.string().optional(),
3898
+ contentDisposition: z135.string().optional(),
3899
+ size: z135.number().min(0),
3900
+ content: z135.instanceof(Buffer),
3901
+ related: z135.boolean().optional()
3902
+ });
3903
+ var parsedEmailObjectSchema = z135.object({
3904
+ messageId: z135.string().optional(),
3905
+ inReplyTo: z135.string().optional(),
3906
+ references: z135.union([z135.string(), z135.array(z135.string())]).optional(),
3907
+ from: z135.any().optional(),
3491
3908
  // Complex email address object
3492
- to: z134.any().optional(),
3493
- cc: z134.any().optional(),
3494
- bcc: z134.any().optional(),
3495
- subject: z134.string().optional(),
3496
- date: z134.date().optional(),
3497
- text: z134.string().optional(),
3498
- html: z134.string().optional(),
3499
- attachments: z134.array(emailAttachmentSchema).optional()
3500
- });
3501
- var processIngestedEmailSchema = z134.object({
3909
+ to: z135.any().optional(),
3910
+ cc: z135.any().optional(),
3911
+ bcc: z135.any().optional(),
3912
+ subject: z135.string().optional(),
3913
+ date: z135.date().optional(),
3914
+ text: z135.string().optional(),
3915
+ html: z135.string().optional(),
3916
+ attachments: z135.array(emailAttachmentSchema).optional()
3917
+ });
3918
+ var processIngestedEmailSchema = z135.object({
3502
3919
  parsedEmail: parsedEmailObjectSchema,
3503
- rawEmailS3Key: z134.string().min(1, "rawEmailS3Key cannot be empty"),
3920
+ rawEmailS3Key: z135.string().min(1, "rawEmailS3Key cannot be empty"),
3504
3921
  options: processIngestedEmailOptionsSchema
3505
3922
  });
3506
3923
 
3507
3924
  // ../../b4m-core/packages/services/dist/src/emailAnalysisService/types.js
3508
- import { z as z135 } from "zod";
3509
- var llmAnalysisResponseSchema = z135.object({
3510
- summary: z135.string().min(1, "Summary cannot be empty"),
3511
- entities: z135.object({
3512
- companies: z135.array(z135.string()).default([]),
3513
- people: z135.array(z135.string()).default([]),
3514
- products: z135.array(z135.string()).default([]),
3515
- technologies: z135.array(z135.string()).default([])
3925
+ import { z as z136 } from "zod";
3926
+ var llmAnalysisResponseSchema = z136.object({
3927
+ summary: z136.string().min(1, "Summary cannot be empty"),
3928
+ entities: z136.object({
3929
+ companies: z136.array(z136.string()).default([]),
3930
+ people: z136.array(z136.string()).default([]),
3931
+ products: z136.array(z136.string()).default([]),
3932
+ technologies: z136.array(z136.string()).default([])
3516
3933
  }),
3517
- sentiment: z135.enum(["positive", "neutral", "negative", "urgent"]),
3518
- actionItems: z135.array(z135.object({
3519
- description: z135.string(),
3520
- deadline: z135.string().optional()
3934
+ sentiment: z136.enum(["positive", "neutral", "negative", "urgent"]),
3935
+ actionItems: z136.array(z136.object({
3936
+ description: z136.string(),
3937
+ deadline: z136.string().optional()
3521
3938
  // ISO date string from LLM
3522
3939
  })).default([]),
3523
- privacyRecommendation: z135.enum(["public", "team", "private"]),
3524
- embargoDetected: z135.boolean().default(false),
3525
- suggestedTags: z135.array(z135.string()).default([])
3940
+ privacyRecommendation: z136.enum(["public", "team", "private"]),
3941
+ embargoDetected: z136.boolean().default(false),
3942
+ suggestedTags: z136.array(z136.string()).default([])
3526
3943
  });
3527
3944
 
3528
3945
  // ../../b4m-core/packages/services/dist/src/llm/ChatCompletion.js
3529
- import { z as z137 } from "zod";
3946
+ import { z as z138 } from "zod";
3530
3947
 
3531
3948
  // ../../b4m-core/packages/services/dist/src/llm/ChatCompletionInvoke.js
3532
3949
  import { fromZodError } from "zod-validation-error";
@@ -3640,8 +4057,8 @@ async function processAndStoreImages(images, context) {
3640
4057
  const buffer = await downloadImage(image);
3641
4058
  const fileType = await fileTypeFromBuffer2(buffer);
3642
4059
  const filename = `${uuidv45()}.${fileType?.ext}`;
3643
- const path11 = await context.imageGenerateStorage.upload(buffer, filename, {});
3644
- return path11;
4060
+ const path13 = await context.imageGenerateStorage.upload(buffer, filename, {});
4061
+ return path13;
3645
4062
  }));
3646
4063
  }
3647
4064
  async function updateQuestAndReturnMarkdown(storedImageUrls, context) {
@@ -4586,17 +5003,17 @@ var rechartsTool = {
4586
5003
  };
4587
5004
 
4588
5005
  // ../../b4m-core/packages/services/dist/src/llm/tools/implementation/editFile/index.js
4589
- import { z as z136 } from "zod";
5006
+ import { z as z137 } from "zod";
4590
5007
  import { diffLines as diffLines2 } from "diff";
4591
- var editFileSchema = z136.object({
4592
- fileId: z136.string().describe("The ID of the file to edit"),
4593
- instruction: z136.string().describe("Natural language instruction describing the changes to make"),
4594
- selection: z136.object({
4595
- start: z136.number().describe("Starting character position of the selection"),
4596
- end: z136.number().describe("Ending character position of the selection")
5008
+ var editFileSchema = z137.object({
5009
+ fileId: z137.string().describe("The ID of the file to edit"),
5010
+ instruction: z137.string().describe("Natural language instruction describing the changes to make"),
5011
+ selection: z137.object({
5012
+ start: z137.number().describe("Starting character position of the selection"),
5013
+ end: z137.number().describe("Ending character position of the selection")
4597
5014
  }).optional().describe("Optional selection range to edit within the file"),
4598
- preserveFormatting: z136.boolean().optional().default(true).describe("Whether to preserve the original formatting style"),
4599
- returnDiff: z136.boolean().optional().default(true).describe("Whether to return a diff of the changes")
5015
+ preserveFormatting: z137.boolean().optional().default(true).describe("Whether to preserve the original formatting style"),
5016
+ returnDiff: z137.boolean().optional().default(true).describe("Whether to return a diff of the changes")
4600
5017
  });
4601
5018
  function generateSimpleDiff(original, modified) {
4602
5019
  const differences = diffLines2(original, modified);
@@ -4825,8 +5242,8 @@ async function processAndStoreImage(imageUrl, context) {
4825
5242
  const buffer = await downloadImage2(imageUrl);
4826
5243
  const fileType = await fileTypeFromBuffer3(buffer);
4827
5244
  const filename = `${uuidv46()}.${fileType?.ext}`;
4828
- const path11 = await context.imageGenerateStorage.upload(buffer, filename, {});
4829
- return path11;
5245
+ const path13 = await context.imageGenerateStorage.upload(buffer, filename, {});
5246
+ return path13;
4830
5247
  }
4831
5248
  async function updateQuestAndReturnMarkdown2(storedImagePath, context) {
4832
5249
  await context.onFinish?.("edit_image", storedImagePath);
@@ -6355,8 +6772,8 @@ var getHeliocentricCoords = (planet, T) => {
6355
6772
  const sinNode = Math.sin(longNode);
6356
6773
  const x = r * (cosNode * cosOmega - sinNode * sinOmega * cosI);
6357
6774
  const y = r * (sinNode * cosOmega + cosNode * sinOmega * cosI);
6358
- const z143 = r * sinOmega * sinI;
6359
- return { x, y, z: z143, r };
6775
+ const z144 = r * sinOmega * sinI;
6776
+ return { x, y, z: z144, r };
6360
6777
  };
6361
6778
  var getGeocentricEcliptic = (planet, earth) => {
6362
6779
  const dx = planet.x - earth.x;
@@ -6663,33 +7080,33 @@ var planetVisibilityTool = {
6663
7080
  };
6664
7081
 
6665
7082
  // ../../b4m-core/packages/services/dist/src/llm/tools/implementation/fileRead/index.js
6666
- import { promises as fs5 } from "fs";
6667
- import { existsSync, statSync } from "fs";
6668
- import path4 from "path";
6669
- var MAX_FILE_SIZE = 10 * 1024 * 1024;
7083
+ import { promises as fs7 } from "fs";
7084
+ import { existsSync as existsSync2, statSync as statSync3 } from "fs";
7085
+ import path6 from "path";
7086
+ var MAX_FILE_SIZE2 = 10 * 1024 * 1024;
6670
7087
  async function readFileContent(params) {
6671
7088
  const { path: filePath, encoding = "utf-8", maxLines } = params;
6672
- const normalizedPath = path4.normalize(filePath);
6673
- const resolvedPath = path4.resolve(process.cwd(), normalizedPath);
6674
- const cwd = path4.resolve(process.cwd());
7089
+ const normalizedPath = path6.normalize(filePath);
7090
+ const resolvedPath = path6.resolve(process.cwd(), normalizedPath);
7091
+ const cwd = path6.resolve(process.cwd());
6675
7092
  if (!resolvedPath.startsWith(cwd)) {
6676
7093
  throw new Error(`Access denied: Cannot read files outside of current working directory`);
6677
7094
  }
6678
- if (!existsSync(resolvedPath)) {
7095
+ if (!existsSync2(resolvedPath)) {
6679
7096
  throw new Error(`File not found: ${filePath}`);
6680
7097
  }
6681
- const stats = statSync(resolvedPath);
7098
+ const stats = statSync3(resolvedPath);
6682
7099
  if (stats.isDirectory()) {
6683
7100
  throw new Error(`Path is a directory, not a file: ${filePath}`);
6684
7101
  }
6685
- if (stats.size > MAX_FILE_SIZE) {
6686
- throw new Error(`File too large: ${(stats.size / 1024 / 1024).toFixed(2)}MB (max ${MAX_FILE_SIZE / 1024 / 1024}MB)`);
7102
+ if (stats.size > MAX_FILE_SIZE2) {
7103
+ throw new Error(`File too large: ${(stats.size / 1024 / 1024).toFixed(2)}MB (max ${MAX_FILE_SIZE2 / 1024 / 1024}MB)`);
6687
7104
  }
6688
7105
  const isBinary = await checkIfBinary(resolvedPath);
6689
7106
  if (isBinary && encoding === "utf-8") {
6690
7107
  throw new Error(`File appears to be binary. Use encoding 'base64' to read binary files, or specify a different encoding.`);
6691
7108
  }
6692
- const content = await fs5.readFile(resolvedPath, encoding);
7109
+ const content = await fs7.readFile(resolvedPath, encoding);
6693
7110
  if (maxLines && typeof content === "string") {
6694
7111
  const lines = content.split("\n");
6695
7112
  if (lines.length > maxLines) {
@@ -6704,7 +7121,7 @@ ${content}`;
6704
7121
  }
6705
7122
  async function checkIfBinary(filePath) {
6706
7123
  const buffer = Buffer.alloc(8192);
6707
- const fd = await fs5.open(filePath, "r");
7124
+ const fd = await fs7.open(filePath, "r");
6708
7125
  try {
6709
7126
  const { bytesRead } = await fd.read(buffer, 0, 8192, 0);
6710
7127
  const chunk = buffer.slice(0, bytesRead);
@@ -6721,7 +7138,7 @@ var fileReadTool = {
6721
7138
  context.logger.info("\u{1F4C4} FileRead: Reading file", { path: params.path });
6722
7139
  try {
6723
7140
  const content = await readFileContent(params);
6724
- const stats = statSync(path4.resolve(process.cwd(), path4.normalize(params.path)));
7141
+ const stats = statSync3(path6.resolve(process.cwd(), path6.normalize(params.path)));
6725
7142
  context.logger.info("\u2705 FileRead: Success", {
6726
7143
  path: params.path,
6727
7144
  size: stats.size,
@@ -6760,25 +7177,25 @@ var fileReadTool = {
6760
7177
  };
6761
7178
 
6762
7179
  // ../../b4m-core/packages/services/dist/src/llm/tools/implementation/createFile/index.js
6763
- import { promises as fs6 } from "fs";
6764
- import { existsSync as existsSync2 } from "fs";
6765
- import path5 from "path";
7180
+ import { promises as fs8 } from "fs";
7181
+ import { existsSync as existsSync3 } from "fs";
7182
+ import path7 from "path";
6766
7183
  async function createFile(params) {
6767
7184
  const { path: filePath, content, createDirectories = true } = params;
6768
- const normalizedPath = path5.normalize(filePath);
6769
- const resolvedPath = path5.resolve(process.cwd(), normalizedPath);
6770
- const cwd = path5.resolve(process.cwd());
7185
+ const normalizedPath = path7.normalize(filePath);
7186
+ const resolvedPath = path7.resolve(process.cwd(), normalizedPath);
7187
+ const cwd = path7.resolve(process.cwd());
6771
7188
  if (!resolvedPath.startsWith(cwd)) {
6772
7189
  throw new Error(`Access denied: Cannot create files outside of current working directory`);
6773
7190
  }
6774
- const fileExists = existsSync2(resolvedPath);
7191
+ const fileExists = existsSync3(resolvedPath);
6775
7192
  const action = fileExists ? "overwritten" : "created";
6776
7193
  if (createDirectories) {
6777
- const dir = path5.dirname(resolvedPath);
6778
- await fs6.mkdir(dir, { recursive: true });
7194
+ const dir = path7.dirname(resolvedPath);
7195
+ await fs8.mkdir(dir, { recursive: true });
6779
7196
  }
6780
- await fs6.writeFile(resolvedPath, content, "utf-8");
6781
- const stats = await fs6.stat(resolvedPath);
7197
+ await fs8.writeFile(resolvedPath, content, "utf-8");
7198
+ const stats = await fs8.stat(resolvedPath);
6782
7199
  const lines = content.split("\n").length;
6783
7200
  return `File ${action} successfully: ${filePath}
6784
7201
  Size: ${stats.size} bytes
@@ -6789,7 +7206,7 @@ var createFileTool = {
6789
7206
  implementation: (context) => ({
6790
7207
  toolFn: async (value) => {
6791
7208
  const params = value;
6792
- const fileExists = existsSync2(path5.resolve(process.cwd(), path5.normalize(params.path)));
7209
+ const fileExists = existsSync3(path7.resolve(process.cwd(), path7.normalize(params.path)));
6793
7210
  context.logger.info(`\u{1F4DD} CreateFile: ${fileExists ? "Overwriting" : "Creating"} file`, {
6794
7211
  path: params.path,
6795
7212
  size: params.content.length
@@ -6830,8 +7247,8 @@ var createFileTool = {
6830
7247
 
6831
7248
  // ../../b4m-core/packages/services/dist/src/llm/tools/implementation/globFiles/index.js
6832
7249
  import { readdir } from "fs/promises";
6833
- import { statSync as statSync2 } from "fs";
6834
- import path6 from "path";
7250
+ import { statSync as statSync4 } from "fs";
7251
+ import path8 from "path";
6835
7252
  function matchGlob(filePath, pattern) {
6836
7253
  let regexPattern = pattern.replace(/\./g, "\\.").replace(/\*\*/g, "{{GLOBSTAR}}").replace(/\*/g, "[^/]*").replace(/\?/g, ".").replace(/\{([^}]+)\}/g, (_, options) => `(${options.split(",").join("|")})`).replace(/\[([^\]]+)\]/g, "[$1]");
6837
7254
  regexPattern = regexPattern.replace(/\{\{GLOBSTAR\}\}\//g, "(.*/)?").replace(/\/\{\{GLOBSTAR\}\}/g, "(/.*)?").replace(/\{\{GLOBSTAR\}\}/g, ".*");
@@ -6849,8 +7266,8 @@ async function walkDir(dir, pattern, includeHidden, maxResults, basePath = "") {
6849
7266
  if (!includeHidden && entry.name.startsWith(".")) {
6850
7267
  continue;
6851
7268
  }
6852
- const relativePath = basePath ? path6.join(basePath, entry.name) : entry.name;
6853
- const fullPath = path6.join(dir, entry.name);
7269
+ const relativePath = basePath ? path8.join(basePath, entry.name) : entry.name;
7270
+ const fullPath = path8.join(dir, entry.name);
6854
7271
  if (matchGlob(relativePath, pattern)) {
6855
7272
  matches.push(relativePath);
6856
7273
  }
@@ -6866,7 +7283,7 @@ async function walkDir(dir, pattern, includeHidden, maxResults, basePath = "") {
6866
7283
  async function listFiles(params) {
6867
7284
  const { pattern, cwd: relativeCwd, includeHidden = false, maxResults = 1e3 } = params;
6868
7285
  const baseCwd = process.cwd();
6869
- const targetCwd = relativeCwd ? path6.resolve(baseCwd, path6.normalize(relativeCwd)) : baseCwd;
7286
+ const targetCwd = relativeCwd ? path8.resolve(baseCwd, path8.normalize(relativeCwd)) : baseCwd;
6870
7287
  if (!targetCwd.startsWith(baseCwd)) {
6871
7288
  throw new Error(`Access denied: Cannot list files outside of current working directory`);
6872
7289
  }
@@ -6877,8 +7294,8 @@ async function listFiles(params) {
6877
7294
  const filesInfo = [];
6878
7295
  for (const match of matches) {
6879
7296
  try {
6880
- const fullPath = path6.join(targetCwd, match);
6881
- const stats = statSync2(fullPath);
7297
+ const fullPath = path8.join(targetCwd, match);
7298
+ const stats = statSync4(fullPath);
6882
7299
  filesInfo.push({
6883
7300
  path: match,
6884
7301
  size: stats.size,
@@ -6959,9 +7376,9 @@ var globFilesTool = {
6959
7376
 
6960
7377
  // ../../b4m-core/packages/services/dist/src/llm/tools/implementation/grepSearch/index.js
6961
7378
  import { readdir as readdir2 } from "fs/promises";
6962
- import { readFileSync, statSync as statSync3 } from "fs";
6963
- import path7 from "path";
6964
- var MAX_FILE_SIZE2 = 10 * 1024 * 1024;
7379
+ import { readFileSync as readFileSync2, statSync as statSync5 } from "fs";
7380
+ import path9 from "path";
7381
+ var MAX_FILE_SIZE3 = 10 * 1024 * 1024;
6965
7382
  function matchGlob2(filePath, pattern) {
6966
7383
  const regexPattern = pattern.replace(/\./g, "\\.").replace(/\*\*/g, "{{GLOBSTAR}}").replace(/\*/g, "[^/]*").replace(/\{\{GLOBSTAR\}\}/g, ".*").replace(/\?/g, ".").replace(/\{([^}]+)\}/g, (_, options) => `(${options.split(",").join("|")})`).replace(/\[([^\]]+)\]/g, "[$1]");
6967
7384
  const regex = new RegExp(`^${regexPattern}$`);
@@ -6978,8 +7395,8 @@ async function walkDir2(dir, pattern, maxResults, basePath = "") {
6978
7395
  if (entry.name.startsWith(".")) {
6979
7396
  continue;
6980
7397
  }
6981
- const relativePath = basePath ? path7.join(basePath, entry.name) : entry.name;
6982
- const fullPath = path7.join(dir, entry.name);
7398
+ const relativePath = basePath ? path9.join(basePath, entry.name) : entry.name;
7399
+ const fullPath = path9.join(dir, entry.name);
6983
7400
  if (matchGlob2(relativePath, pattern)) {
6984
7401
  matches.push(relativePath);
6985
7402
  }
@@ -6992,10 +7409,10 @@ async function walkDir2(dir, pattern, maxResults, basePath = "") {
6992
7409
  }
6993
7410
  return matches;
6994
7411
  }
6995
- async function searchFiles(params) {
7412
+ async function searchFiles2(params) {
6996
7413
  const { pattern, filePattern = "**/*", cwd: relativeCwd, caseSensitive = false, maxResults = 100, contextLines = 0 } = params;
6997
7414
  const baseCwd = process.cwd();
6998
- const targetCwd = relativeCwd ? path7.resolve(baseCwd, path7.normalize(relativeCwd)) : baseCwd;
7415
+ const targetCwd = relativeCwd ? path9.resolve(baseCwd, path9.normalize(relativeCwd)) : baseCwd;
6999
7416
  if (!targetCwd.startsWith(baseCwd)) {
7000
7417
  throw new Error(`Access denied: Cannot search files outside of current working directory`);
7001
7418
  }
@@ -7009,13 +7426,13 @@ async function searchFiles(params) {
7009
7426
  const filesToSearch = await walkDir2(targetCwd, filePattern, 1e4);
7010
7427
  const filteredFiles = [];
7011
7428
  for (const match of filesToSearch) {
7012
- const fullPath = path7.join(targetCwd, match);
7429
+ const fullPath = path9.join(targetCwd, match);
7013
7430
  try {
7014
- const stats = statSync3(fullPath);
7015
- if (stats.isDirectory() || stats.size > MAX_FILE_SIZE2) {
7431
+ const stats = statSync5(fullPath);
7432
+ if (stats.isDirectory() || stats.size > MAX_FILE_SIZE3) {
7016
7433
  continue;
7017
7434
  }
7018
- if (isBinaryFile(fullPath)) {
7435
+ if (isBinaryFile2(fullPath)) {
7019
7436
  continue;
7020
7437
  }
7021
7438
  filteredFiles.push(match);
@@ -7033,9 +7450,9 @@ async function searchFiles(params) {
7033
7450
  break;
7034
7451
  }
7035
7452
  filesSearched++;
7036
- const fullPath = path7.join(targetCwd, file);
7453
+ const fullPath = path9.join(targetCwd, file);
7037
7454
  try {
7038
- const content = readFileSync(fullPath, "utf-8");
7455
+ const content = readFileSync2(fullPath, "utf-8");
7039
7456
  const lines = content.split("\n");
7040
7457
  for (let i = 0; i < lines.length; i++) {
7041
7458
  if (matches.length >= maxResults) {
@@ -7099,7 +7516,7 @@ ${match.context.after.map((l) => ` ${l}`).join("\n")}`;
7099
7516
  }).join("\n");
7100
7517
  return `${summary}${patternInfo}${cwdInfo}${matchesList}`;
7101
7518
  }
7102
- function isBinaryFile(filePath) {
7519
+ function isBinaryFile2(filePath) {
7103
7520
  try {
7104
7521
  const buffer = Buffer.alloc(8192);
7105
7522
  const fd = __require("fs").openSync(filePath, "r");
@@ -7122,7 +7539,7 @@ var grepSearchTool = {
7122
7539
  cwd: params.cwd || "."
7123
7540
  });
7124
7541
  try {
7125
- const result = await searchFiles(params);
7542
+ const result = await searchFiles2(params);
7126
7543
  context.logger.info("\u2705 GrepSearch: Success");
7127
7544
  return result;
7128
7545
  } catch (error) {
@@ -7168,31 +7585,31 @@ var grepSearchTool = {
7168
7585
  };
7169
7586
 
7170
7587
  // ../../b4m-core/packages/services/dist/src/llm/tools/implementation/deleteFile/index.js
7171
- import { promises as fs7 } from "fs";
7172
- import { existsSync as existsSync3, statSync as statSync4 } from "fs";
7173
- import path8 from "path";
7588
+ import { promises as fs9 } from "fs";
7589
+ import { existsSync as existsSync4, statSync as statSync6 } from "fs";
7590
+ import path10 from "path";
7174
7591
  async function deleteFile(params) {
7175
7592
  const { path: filePath, recursive = false } = params;
7176
- const normalizedPath = path8.normalize(filePath);
7177
- const resolvedPath = path8.resolve(process.cwd(), normalizedPath);
7178
- const cwd = path8.resolve(process.cwd());
7593
+ const normalizedPath = path10.normalize(filePath);
7594
+ const resolvedPath = path10.resolve(process.cwd(), normalizedPath);
7595
+ const cwd = path10.resolve(process.cwd());
7179
7596
  if (!resolvedPath.startsWith(cwd)) {
7180
7597
  throw new Error(`Access denied: Cannot delete files outside of current working directory`);
7181
7598
  }
7182
- if (!existsSync3(resolvedPath)) {
7599
+ if (!existsSync4(resolvedPath)) {
7183
7600
  throw new Error(`File or directory not found: ${filePath}`);
7184
7601
  }
7185
- const stats = statSync4(resolvedPath);
7602
+ const stats = statSync6(resolvedPath);
7186
7603
  const isDirectory = stats.isDirectory();
7187
7604
  const size = stats.size;
7188
7605
  if (isDirectory && !recursive) {
7189
7606
  throw new Error(`Path is a directory: ${filePath}. Use recursive=true to delete directories and their contents.`);
7190
7607
  }
7191
7608
  if (isDirectory) {
7192
- await fs7.rm(resolvedPath, { recursive: true, force: true });
7609
+ await fs9.rm(resolvedPath, { recursive: true, force: true });
7193
7610
  return `Directory deleted successfully: ${filePath}`;
7194
7611
  } else {
7195
- await fs7.unlink(resolvedPath);
7612
+ await fs9.unlink(resolvedPath);
7196
7613
  return `File deleted successfully: ${filePath}
7197
7614
  Size: ${size} bytes`;
7198
7615
  }
@@ -7202,8 +7619,8 @@ var deleteFileTool = {
7202
7619
  implementation: (context) => ({
7203
7620
  toolFn: async (value) => {
7204
7621
  const params = value;
7205
- const resolvedPath = path8.resolve(process.cwd(), path8.normalize(params.path));
7206
- const isDirectory = existsSync3(resolvedPath) && statSync4(resolvedPath).isDirectory();
7622
+ const resolvedPath = path10.resolve(process.cwd(), path10.normalize(params.path));
7623
+ const isDirectory = existsSync4(resolvedPath) && statSync6(resolvedPath).isDirectory();
7207
7624
  context.logger.info(`\u{1F5D1}\uFE0F DeleteFile: Deleting ${isDirectory ? "directory" : "file"}`, {
7208
7625
  path: params.path,
7209
7626
  recursive: params.recursive
@@ -7381,42 +7798,42 @@ var DISABLE_SERVER_THROTTLING = process.env.DISABLE_SERVER_THROTTLING === "true"
7381
7798
  var questSaveMutex = new Mutex();
7382
7799
 
7383
7800
  // ../../b4m-core/packages/services/dist/src/llm/ChatCompletion.js
7384
- var QuestStartBodySchema = z137.object({
7385
- userId: z137.string(),
7386
- sessionId: z137.string(),
7387
- questId: z137.string(),
7388
- message: z137.string(),
7389
- messageFileIds: z137.array(z137.string()),
7390
- historyCount: z137.number(),
7391
- fabFileIds: z137.array(z137.string()),
7801
+ var QuestStartBodySchema = z138.object({
7802
+ userId: z138.string(),
7803
+ sessionId: z138.string(),
7804
+ questId: z138.string(),
7805
+ message: z138.string(),
7806
+ messageFileIds: z138.array(z138.string()),
7807
+ historyCount: z138.number(),
7808
+ fabFileIds: z138.array(z138.string()),
7392
7809
  params: ChatCompletionCreateInputSchema,
7393
7810
  dashboardParams: DashboardParamsSchema.optional(),
7394
- enableQuestMaster: z137.boolean().optional(),
7395
- enableMementos: z137.boolean().optional(),
7396
- enableArtifacts: z137.boolean().optional(),
7397
- enableAgents: z137.boolean().optional(),
7811
+ enableQuestMaster: z138.boolean().optional(),
7812
+ enableMementos: z138.boolean().optional(),
7813
+ enableArtifacts: z138.boolean().optional(),
7814
+ enableAgents: z138.boolean().optional(),
7398
7815
  promptMeta: PromptMetaZodSchema,
7399
- tools: z137.array(z137.union([b4mLLMTools, z137.string()])).optional(),
7400
- mcpServers: z137.array(z137.string()).optional(),
7401
- projectId: z137.string().optional(),
7402
- organizationId: z137.string().nullable().optional(),
7816
+ tools: z138.array(z138.union([b4mLLMTools, z138.string()])).optional(),
7817
+ mcpServers: z138.array(z138.string()).optional(),
7818
+ projectId: z138.string().optional(),
7819
+ organizationId: z138.string().nullable().optional(),
7403
7820
  questMaster: QuestMasterParamsSchema.optional(),
7404
- toolPromptId: z137.string().optional(),
7821
+ toolPromptId: z138.string().optional(),
7405
7822
  researchMode: ResearchModeParamsSchema.optional(),
7406
- fallbackModel: z137.string().optional(),
7407
- embeddingModel: z137.string().optional(),
7408
- queryComplexity: z137.string(),
7823
+ fallbackModel: z138.string().optional(),
7824
+ embeddingModel: z138.string().optional(),
7825
+ queryComplexity: z138.string(),
7409
7826
  imageConfig: GenerateImageToolCallSchema.optional(),
7410
- deepResearchConfig: z137.object({
7411
- maxDepth: z137.number().optional(),
7412
- duration: z137.number().optional(),
7827
+ deepResearchConfig: z138.object({
7828
+ maxDepth: z138.number().optional(),
7829
+ duration: z138.number().optional(),
7413
7830
  // Note: searchers are passed via ToolContext and not through this API schema
7414
- searchers: z137.array(z137.any()).optional()
7831
+ searchers: z138.array(z138.any()).optional()
7415
7832
  }).optional(),
7416
- extraContextMessages: z137.array(z137.object({
7417
- role: z137.enum(["user", "assistant", "system", "function", "tool"]),
7418
- content: z137.union([z137.string(), z137.array(z137.any())]),
7419
- fabFileIds: z137.array(z137.string()).optional()
7833
+ extraContextMessages: z138.array(z138.object({
7834
+ role: z138.enum(["user", "assistant", "system", "function", "tool"]),
7835
+ content: z138.union([z138.string(), z138.array(z138.any())]),
7836
+ fabFileIds: z138.array(z138.string()).optional()
7420
7837
  })).optional()
7421
7838
  });
7422
7839
 
@@ -7424,30 +7841,9 @@ var QuestStartBodySchema = z137.object({
7424
7841
  import axios8 from "axios";
7425
7842
  import { fileTypeFromBuffer as fileTypeFromBuffer4 } from "file-type";
7426
7843
  import { v4 as uuidv47 } from "uuid";
7427
- import { z as z138 } from "zod";
7844
+ import { z as z139 } from "zod";
7428
7845
  import { fromZodError as fromZodError2 } from "zod-validation-error";
7429
7846
  var ImageGenerationBodySchema = OpenAIImageGenerationInput.extend({
7430
- sessionId: z138.string(),
7431
- questId: z138.string(),
7432
- userId: z138.string(),
7433
- prompt: z138.string(),
7434
- safety_tolerance: z138.number().min(BFL_SAFETY_TOLERANCE.MIN).max(BFL_SAFETY_TOLERANCE.MAX).optional().default(BFL_SAFETY_TOLERANCE.DEFAULT),
7435
- prompt_upsampling: z138.boolean().optional().default(false),
7436
- seed: z138.number().nullable().optional(),
7437
- output_format: z138.enum(["jpeg", "png"]).nullable().optional().default("png"),
7438
- width: z138.number().optional(),
7439
- height: z138.number().optional(),
7440
- aspect_ratio: z138.string().optional(),
7441
- fabFileIds: z138.array(z138.string()).optional()
7442
- });
7443
-
7444
- // ../../b4m-core/packages/services/dist/src/llm/ImageEdit.js
7445
- import axios9 from "axios";
7446
- import { fileTypeFromBuffer as fileTypeFromBuffer5 } from "file-type";
7447
- import { v4 as uuidv48 } from "uuid";
7448
- import { z as z139 } from "zod";
7449
- import { fromZodError as fromZodError3 } from "zod-validation-error";
7450
- var ImageEditBodySchema = OpenAIImageGenerationInput.extend({
7451
7847
  sessionId: z139.string(),
7452
7848
  questId: z139.string(),
7453
7849
  userId: z139.string(),
@@ -7455,35 +7851,56 @@ var ImageEditBodySchema = OpenAIImageGenerationInput.extend({
7455
7851
  safety_tolerance: z139.number().min(BFL_SAFETY_TOLERANCE.MIN).max(BFL_SAFETY_TOLERANCE.MAX).optional().default(BFL_SAFETY_TOLERANCE.DEFAULT),
7456
7852
  prompt_upsampling: z139.boolean().optional().default(false),
7457
7853
  seed: z139.number().nullable().optional(),
7458
- output_format: z139.enum(["jpeg", "png"]).optional().default("png"),
7854
+ output_format: z139.enum(["jpeg", "png"]).nullable().optional().default("png"),
7459
7855
  width: z139.number().optional(),
7460
7856
  height: z139.number().optional(),
7461
7857
  aspect_ratio: z139.string().optional(),
7462
- size: z139.string().optional(),
7463
- fabFileIds: z139.array(z139.string()).optional(),
7464
- image: z139.string()
7858
+ fabFileIds: z139.array(z139.string()).optional()
7465
7859
  });
7466
7860
 
7467
- // ../../b4m-core/packages/services/dist/src/llm/refineText.js
7861
+ // ../../b4m-core/packages/services/dist/src/llm/ImageEdit.js
7862
+ import axios9 from "axios";
7863
+ import { fileTypeFromBuffer as fileTypeFromBuffer5 } from "file-type";
7864
+ import { v4 as uuidv48 } from "uuid";
7468
7865
  import { z as z140 } from "zod";
7469
- var refineTextLLMSchema = z140.object({
7470
- text: z140.string(),
7471
- context: z140.string().optional()
7866
+ import { fromZodError as fromZodError3 } from "zod-validation-error";
7867
+ var ImageEditBodySchema = OpenAIImageGenerationInput.extend({
7868
+ sessionId: z140.string(),
7869
+ questId: z140.string(),
7870
+ userId: z140.string(),
7871
+ prompt: z140.string(),
7872
+ safety_tolerance: z140.number().min(BFL_SAFETY_TOLERANCE.MIN).max(BFL_SAFETY_TOLERANCE.MAX).optional().default(BFL_SAFETY_TOLERANCE.DEFAULT),
7873
+ prompt_upsampling: z140.boolean().optional().default(false),
7874
+ seed: z140.number().nullable().optional(),
7875
+ output_format: z140.enum(["jpeg", "png"]).optional().default("png"),
7876
+ width: z140.number().optional(),
7877
+ height: z140.number().optional(),
7878
+ aspect_ratio: z140.string().optional(),
7879
+ size: z140.string().optional(),
7880
+ fabFileIds: z140.array(z140.string()).optional(),
7881
+ image: z140.string()
7882
+ });
7883
+
7884
+ // ../../b4m-core/packages/services/dist/src/llm/refineText.js
7885
+ import { z as z141 } from "zod";
7886
+ var refineTextLLMSchema = z141.object({
7887
+ text: z141.string(),
7888
+ context: z141.string().optional()
7472
7889
  // tone: z.enum(['formal', 'informal', 'neutral']).optional(),
7473
7890
  // style: z.enum(['technical', 'creative', 'academic', 'business', 'narrative']).optional(),
7474
7891
  });
7475
7892
 
7476
7893
  // ../../b4m-core/packages/services/dist/src/llm/MementoEvaluationService.js
7477
- import { z as z141 } from "zod";
7478
- var SingleMementoEvalSchema = z141.object({
7479
- importance: z141.number().min(1).max(10),
7894
+ import { z as z142 } from "zod";
7895
+ var SingleMementoEvalSchema = z142.object({
7896
+ importance: z142.number().min(1).max(10),
7480
7897
  // 1-10 scale for personal info importance
7481
- summary: z141.string(),
7482
- tags: z141.array(z141.string()).optional()
7898
+ summary: z142.string(),
7899
+ tags: z142.array(z142.string()).optional()
7483
7900
  });
7484
- var MementoEvalResponseSchema = z141.object({
7485
- isPersonal: z141.boolean(),
7486
- mementos: z141.array(SingleMementoEvalSchema).optional()
7901
+ var MementoEvalResponseSchema = z142.object({
7902
+ isPersonal: z142.boolean(),
7903
+ mementos: z142.array(SingleMementoEvalSchema).optional()
7487
7904
  // Array of distinct personal information
7488
7905
  });
7489
7906
 
@@ -7493,10 +7910,10 @@ import jwt2 from "jsonwebtoken";
7493
7910
  // src/utils/diffPreview.ts
7494
7911
  import * as Diff from "diff";
7495
7912
  import { readFile } from "fs/promises";
7496
- import { existsSync as existsSync4 } from "fs";
7913
+ import { existsSync as existsSync5 } from "fs";
7497
7914
  async function generateFileDiffPreview(args) {
7498
7915
  try {
7499
- if (!existsSync4(args.path)) {
7916
+ if (!existsSync5(args.path)) {
7500
7917
  const lines2 = args.content.split("\n");
7501
7918
  const preview = lines2.slice(0, 20).join("\n");
7502
7919
  const hasMore = lines2.length > 20;
@@ -7526,10 +7943,10 @@ ${preview}${hasMore ? `
7526
7943
  }
7527
7944
  async function generateFileDeletePreview(args) {
7528
7945
  try {
7529
- if (!existsSync4(args.path)) {
7946
+ if (!existsSync5(args.path)) {
7530
7947
  return `[File does not exist: ${args.path}]`;
7531
7948
  }
7532
- const stats = await import("fs/promises").then((fs9) => fs9.stat(args.path));
7949
+ const stats = await import("fs/promises").then((fs11) => fs11.stat(args.path));
7533
7950
  return `[File will be deleted]
7534
7951
 
7535
7952
  Path: ${args.path}
@@ -7545,21 +7962,21 @@ var NoOpStorage = class extends BaseStorage {
7545
7962
  async upload(input, destination, options) {
7546
7963
  return `/tmp/${destination}`;
7547
7964
  }
7548
- async download(path11) {
7965
+ async download(path13) {
7549
7966
  throw new Error("Download not supported in CLI");
7550
7967
  }
7551
- async delete(path11) {
7968
+ async delete(path13) {
7552
7969
  }
7553
- async getSignedUrl(path11) {
7554
- return `/tmp/${path11}`;
7970
+ async getSignedUrl(path13) {
7971
+ return `/tmp/${path13}`;
7555
7972
  }
7556
- getPublicUrl(path11) {
7557
- return `/tmp/${path11}`;
7973
+ getPublicUrl(path13) {
7974
+ return `/tmp/${path13}`;
7558
7975
  }
7559
- async getPreview(path11) {
7560
- return `/tmp/${path11}`;
7976
+ async getPreview(path13) {
7977
+ return `/tmp/${path13}`;
7561
7978
  }
7562
- async getMetadata(path11) {
7979
+ async getMetadata(path13) {
7563
7980
  return { size: 0, contentType: "application/octet-stream" };
7564
7981
  }
7565
7982
  };
@@ -7720,8 +8137,8 @@ function generateCliTools(userId, llm, model, permissionManager, showPermissionP
7720
8137
  }
7721
8138
 
7722
8139
  // src/config/toolSafety.ts
7723
- import { z as z142 } from "zod";
7724
- var ToolCategorySchema = z142.enum([
8140
+ import { z as z143 } from "zod";
8141
+ var ToolCategorySchema = z143.enum([
7725
8142
  "auto_approve",
7726
8143
  // Safe tools that run automatically without permission
7727
8144
  "prompt_always",
@@ -7729,9 +8146,9 @@ var ToolCategorySchema = z142.enum([
7729
8146
  "prompt_default"
7730
8147
  // Tools that prompt by default but can be trusted
7731
8148
  ]);
7732
- var ToolSafetyConfigSchema = z142.object({
7733
- categories: z142.record(z142.string(), ToolCategorySchema),
7734
- trustedTools: z142.array(z142.string())
8149
+ var ToolSafetyConfigSchema = z143.object({
8150
+ categories: z143.record(z143.string(), ToolCategorySchema),
8151
+ trustedTools: z143.array(z143.string())
7735
8152
  });
7736
8153
  var DEFAULT_TOOL_CATEGORIES = {
7737
8154
  // ===== AUTO APPROVE (Safe tools) =====
@@ -7885,8 +8302,8 @@ function getEnvironmentName(configApiConfig) {
7885
8302
  }
7886
8303
 
7887
8304
  // src/utils/Logger.ts
7888
- import fs8 from "fs/promises";
7889
- import path9 from "path";
8305
+ import fs10 from "fs/promises";
8306
+ import path11 from "path";
7890
8307
  import os from "os";
7891
8308
  var Logger2 = class _Logger {
7892
8309
  constructor() {
@@ -7909,9 +8326,9 @@ var Logger2 = class _Logger {
7909
8326
  */
7910
8327
  async initialize(sessionId) {
7911
8328
  this.sessionId = sessionId;
7912
- const debugDir = path9.join(os.homedir(), ".bike4mind", "debug");
7913
- await fs8.mkdir(debugDir, { recursive: true });
7914
- this.logFilePath = path9.join(debugDir, `${sessionId}.txt`);
8329
+ const debugDir = path11.join(os.homedir(), ".bike4mind", "debug");
8330
+ await fs10.mkdir(debugDir, { recursive: true });
8331
+ this.logFilePath = path11.join(debugDir, `${sessionId}.txt`);
7915
8332
  await this.writeToFile("INFO", "=== CLI SESSION START ===");
7916
8333
  }
7917
8334
  /**
@@ -7975,7 +8392,7 @@ var Logger2 = class _Logger {
7975
8392
  const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").substring(0, 19);
7976
8393
  const logEntry = `[${timestamp}] [${level}] ${message}
7977
8394
  `;
7978
- await fs8.appendFile(this.logFilePath, logEntry, "utf-8");
8395
+ await fs10.appendFile(this.logFilePath, logEntry, "utf-8");
7979
8396
  } catch (error) {
7980
8397
  console.error("File logging failed:", error);
7981
8398
  }
@@ -8121,15 +8538,15 @@ var Logger2 = class _Logger {
8121
8538
  async cleanupOldLogs() {
8122
8539
  if (!this.fileLoggingEnabled) return;
8123
8540
  try {
8124
- const debugDir = path9.join(os.homedir(), ".bike4mind", "debug");
8125
- const files = await fs8.readdir(debugDir);
8541
+ const debugDir = path11.join(os.homedir(), ".bike4mind", "debug");
8542
+ const files = await fs10.readdir(debugDir);
8126
8543
  const now = Date.now();
8127
8544
  const thirtyDaysAgo = now - 30 * 24 * 60 * 60 * 1e3;
8128
8545
  for (const file of files) {
8129
- const filePath = path9.join(debugDir, file);
8130
- const stats = await fs8.stat(filePath);
8546
+ const filePath = path11.join(debugDir, file);
8547
+ const stats = await fs10.stat(filePath);
8131
8548
  if (stats.mtime.getTime() < thirtyDaysAgo) {
8132
- await fs8.unlink(filePath);
8549
+ await fs10.unlink(filePath);
8133
8550
  }
8134
8551
  }
8135
8552
  } catch (error) {
@@ -8142,8 +8559,8 @@ var logger = Logger2.getInstance();
8142
8559
  // ../../b4m-core/packages/mcp/dist/src/client.js
8143
8560
  import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
8144
8561
  import { Client as Client2 } from "@modelcontextprotocol/sdk/client/index.js";
8145
- import path10 from "path";
8146
- import { existsSync as existsSync5, readdirSync } from "fs";
8562
+ import path12 from "path";
8563
+ import { existsSync as existsSync6, readdirSync as readdirSync3 } from "fs";
8147
8564
  var MCPClient = class {
8148
8565
  // Note: This class handles MCP server communication with repository filtering
8149
8566
  mcp;
@@ -8168,20 +8585,20 @@ var MCPClient = class {
8168
8585
  const root = process.env.INIT_CWD || process.cwd();
8169
8586
  const candidatePaths = [
8170
8587
  // When running from SST Lambda with node_modules structure (copyFiles)
8171
- path10.join(root, `node_modules/@bike4mind/mcp/dist/src/${this.serverName}/index.js`),
8588
+ path12.join(root, `node_modules/@bike4mind/mcp/dist/src/${this.serverName}/index.js`),
8172
8589
  // When running from SST Lambda deployed environment (/var/task)
8173
- path10.join(root, `b4m-core/packages/mcp/dist/src/${this.serverName}/index.js`),
8590
+ path12.join(root, `b4m-core/packages/mcp/dist/src/${this.serverName}/index.js`),
8174
8591
  // When running from SST Lambda (.sst/artifacts/mcpHandler-dev), navigate to monorepo root (3 levels up)
8175
- path10.join(root, `../../../b4m-core/packages/mcp/dist/src/${this.serverName}/index.js`),
8592
+ path12.join(root, `../../../b4m-core/packages/mcp/dist/src/${this.serverName}/index.js`),
8176
8593
  // When running from packages/client (Next.js app), navigate to monorepo root (2 levels up)
8177
- path10.join(root, `../../b4m-core/packages/mcp/dist/src/${this.serverName}/index.js`),
8594
+ path12.join(root, `../../b4m-core/packages/mcp/dist/src/${this.serverName}/index.js`),
8178
8595
  // Original paths (backward compatibility)
8179
- path10.join(root, `/b4m-core/packages/mcp/dist/src/${this.serverName}/index.js`),
8180
- path10.join(root, "core", "mcp", "servers", this.serverName, "dist", "index.js")
8596
+ path12.join(root, `/b4m-core/packages/mcp/dist/src/${this.serverName}/index.js`),
8597
+ path12.join(root, "core", "mcp", "servers", this.serverName, "dist", "index.js")
8181
8598
  ];
8182
- const serverScriptPath = candidatePaths.find((p) => existsSync5(p));
8599
+ const serverScriptPath = candidatePaths.find((p) => existsSync6(p));
8183
8600
  if (!serverScriptPath) {
8184
- const getDirectories = (source) => readdirSync(source, { withFileTypes: true }).filter((dirent) => dirent.isDirectory()).map((dirent) => dirent.name);
8601
+ const getDirectories = (source) => readdirSync3(source, { withFileTypes: true }).filter((dirent) => dirent.isDirectory()).map((dirent) => dirent.name);
8185
8602
  console.error(`[MCP] Server script not found. Tried paths:`, candidatePaths);
8186
8603
  console.error(`[MCP] Available directories in ${root}:`, getDirectories(root));
8187
8604
  throw new Error(`MCP Server script path not found for ${this.serverName}. Root: ${root}, Available dirs: ${getDirectories(root).join(", ")}`);
@@ -8210,7 +8627,7 @@ var MCPClient = class {
8210
8627
  }
8211
8628
  };
8212
8629
  await this.mcp.connect(this.transport);
8213
- await new Promise((resolve) => setTimeout(resolve, 100));
8630
+ await new Promise((resolve3) => setTimeout(resolve3, 100));
8214
8631
  const toolsResult = await this.mcp.listTools();
8215
8632
  this.tools = toolsResult.tools.map((tool) => {
8216
8633
  return {
@@ -8393,7 +8810,7 @@ var ServerLlmBackend = class {
8393
8810
  */
8394
8811
  async complete(model, messages, options, callback) {
8395
8812
  logger.debug(`[ServerLlmBackend] Starting complete() with model: ${model}`);
8396
- return new Promise(async (resolve, reject) => {
8813
+ return new Promise(async (resolve3, reject) => {
8397
8814
  try {
8398
8815
  logger.debug("[ServerLlmBackend] Making streaming request...");
8399
8816
  const response = await this.makeStreamingRequest(model, messages, options);
@@ -8423,15 +8840,15 @@ var ServerLlmBackend = class {
8423
8840
  reject(err);
8424
8841
  }).then(() => {
8425
8842
  logger.debug("[ServerLlmBackend] Callback completed, resolving");
8426
- resolve();
8843
+ resolve3();
8427
8844
  });
8428
8845
  } else if (cleanedText) {
8429
8846
  callback([cleanedText], lastUsageInfo).catch((err) => {
8430
8847
  logger.error("[ServerLlmBackend] Callback error:", err);
8431
8848
  reject(err);
8432
- }).then(() => resolve());
8849
+ }).then(() => resolve3());
8433
8850
  } else {
8434
- resolve();
8851
+ resolve3();
8435
8852
  }
8436
8853
  return;
8437
8854
  }
@@ -8491,7 +8908,7 @@ var ServerLlmBackend = class {
8491
8908
  response.data.on("end", () => {
8492
8909
  if (!receivedDone) {
8493
8910
  logger.debug("[ServerLlmBackend] Stream ended without [DONE], resolving anyway");
8494
- resolve();
8911
+ resolve3();
8495
8912
  } else {
8496
8913
  logger.debug("[ServerLlmBackend] Stream ended, [DONE] handler will resolve");
8497
8914
  }
@@ -8755,10 +9172,13 @@ var ApiClient = class {
8755
9172
  }
8756
9173
  };
8757
9174
 
9175
+ // src/index.tsx
9176
+ import { isAxiosError as isAxiosError2 } from "axios";
9177
+
8758
9178
  // package.json
8759
9179
  var package_default = {
8760
9180
  name: "@bike4mind/cli",
8761
- version: "0.2.1-optimize-mcp-server-call.17006+38f5cefe6",
9181
+ version: "0.2.2",
8762
9182
  type: "module",
8763
9183
  description: "Interactive CLI tool for Bike4Mind with ReAct agents",
8764
9184
  license: "UNLICENSED",
@@ -8769,6 +9189,9 @@ var package_default = {
8769
9189
  },
8770
9190
  homepage: "https://github.com/bike4mind/lumina5#readme",
8771
9191
  bugs: "https://github.com/bike4mind/lumina5/issues",
9192
+ publishConfig: {
9193
+ access: "public"
9194
+ },
8772
9195
  keywords: [
8773
9196
  "cli",
8774
9197
  "ai",
@@ -8789,6 +9212,8 @@ var package_default = {
8789
9212
  dev: "tsx src/index.tsx",
8790
9213
  build: "tsup",
8791
9214
  typecheck: "tsc --noEmit",
9215
+ test: "vitest run",
9216
+ "test:watch": "vitest",
8792
9217
  start: "node dist/index.js",
8793
9218
  prepublishOnly: "pnpm build"
8794
9219
  },
@@ -8854,11 +9279,11 @@ var package_default = {
8854
9279
  zustand: "^4.5.4"
8855
9280
  },
8856
9281
  devDependencies: {
8857
- "@bike4mind/agents": "0.1.0",
8858
- "@bike4mind/common": "2.36.1-optimize-mcp-server-call.17006+38f5cefe6",
8859
- "@bike4mind/mcp": "1.19.4-optimize-mcp-server-call.17006+38f5cefe6",
8860
- "@bike4mind/services": "2.29.1-optimize-mcp-server-call.17006+38f5cefe6",
8861
- "@bike4mind/utils": "2.0.3-optimize-mcp-server-call.17006+38f5cefe6",
9282
+ "@bike4mind/agents": "workspace:*",
9283
+ "@bike4mind/common": "workspace:*",
9284
+ "@bike4mind/mcp": "workspace:*",
9285
+ "@bike4mind/services": "workspace:*",
9286
+ "@bike4mind/utils": "workspace:*",
8862
9287
  "@types/diff": "^5.0.9",
8863
9288
  "@types/jsonwebtoken": "^9.0.4",
8864
9289
  "@types/node": "^22.9.0",
@@ -8867,11 +9292,16 @@ var package_default = {
8867
9292
  "@types/yargs": "^17.0.32",
8868
9293
  tsup: "^8.5.1",
8869
9294
  tsx: "^4.21.0",
8870
- typescript: "^5.9.3"
8871
- },
8872
- gitHead: "38f5cefe64c7b9aee37f9d7c1db5609ea0335957"
9295
+ typescript: "^5.9.3",
9296
+ vitest: "^3.2.4"
9297
+ }
8873
9298
  };
8874
9299
 
9300
+ // src/config/constants.ts
9301
+ var USAGE_DAYS = 30;
9302
+ var MODEL_NAME_COLUMN_WIDTH = 18;
9303
+ var USAGE_CACHE_TTL = 5 * 60 * 1e3;
9304
+
8875
9305
  // src/index.tsx
8876
9306
  process.removeAllListeners("warning");
8877
9307
  process.on("warning", (warning) => {
@@ -8882,6 +9312,7 @@ process.on("warning", (warning) => {
8882
9312
  });
8883
9313
  var exitTimestamp = null;
8884
9314
  var EXIT_TIMEOUT_MS = 2e3;
9315
+ var usageCache = null;
8885
9316
  function CliApp() {
8886
9317
  const { exit } = useApp();
8887
9318
  const [state, setState] = useState3({
@@ -8921,7 +9352,7 @@ function CliApp() {
8921
9352
  }
8922
9353
  await Promise.race([
8923
9354
  Promise.all(cleanupTasks),
8924
- new Promise((resolve) => setTimeout(resolve, 500))
9355
+ new Promise((resolve3) => setTimeout(resolve3, 500))
8925
9356
  // 500ms timeout
8926
9357
  ]);
8927
9358
  setTimeout(() => {
@@ -9055,9 +9486,9 @@ function CliApp() {
9055
9486
  };
9056
9487
  const permissionManager = new PermissionManager(config.trustedTools || []);
9057
9488
  const promptFn = (toolName, args, preview) => {
9058
- return new Promise((resolve) => {
9489
+ return new Promise((resolve3) => {
9059
9490
  const canBeTrusted = permissionManager.canBeTrusted(toolName);
9060
- const prompt = { toolName, args, preview, canBeTrusted, resolve };
9491
+ const prompt = { toolName, args, preview, canBeTrusted, resolve: resolve3 };
9061
9492
  setState((prev) => ({
9062
9493
  ...prev,
9063
9494
  permissionManager,
@@ -9131,7 +9562,7 @@ Remember: Use context from previous messages to understand follow-up questions.`
9131
9562
  llm,
9132
9563
  model: modelInfo.id,
9133
9564
  tools: allTools,
9134
- maxIterations: 3,
9565
+ maxIterations: 10,
9135
9566
  maxTokens: config.preferences.maxTokens,
9136
9567
  temperature: config.preferences.temperature,
9137
9568
  systemPrompt: cliSystemPrompt
@@ -9246,6 +9677,7 @@ Available commands:
9246
9677
  /login - Authenticate with your B4M account
9247
9678
  /logout - Clear authentication and sign out
9248
9679
  /whoami - Show current authenticated user
9680
+ /usage - Show credit usage and balance
9249
9681
  /save <name> - Save current session
9250
9682
  /sessions - List saved sessions
9251
9683
  /config - Show configuration
@@ -9416,17 +9848,114 @@ Tool Permissions:
9416
9848
  console.log(`Expires: ${new Date(authTokens.expiresAt).toLocaleString()}`);
9417
9849
  console.log("");
9418
9850
  break;
9851
+ case "usage": {
9852
+ const usageAuthTokens = await state.configStore.getAuthTokens();
9853
+ if (!usageAuthTokens || new Date(usageAuthTokens.expiresAt) <= /* @__PURE__ */ new Date()) {
9854
+ console.log("\nNot authenticated. Run /login to authenticate.\n");
9855
+ return;
9856
+ }
9857
+ console.log("\nFetching usage data...");
9858
+ const now = Date.now();
9859
+ let currentCredits;
9860
+ let transactions;
9861
+ if (usageCache && now - usageCache.timestamp < USAGE_CACHE_TTL) {
9862
+ currentCredits = usageCache.data.currentCredits;
9863
+ transactions = usageCache.data.transactions;
9864
+ console.log("(using cached data)\n");
9865
+ } else {
9866
+ try {
9867
+ const config = await state.configStore.get();
9868
+ const apiBaseURL = getApiUrl(config.apiConfig);
9869
+ const apiClient = new ApiClient(apiBaseURL, state.configStore);
9870
+ const [identifyResponse, transactionsResponse] = await Promise.all([
9871
+ apiClient.get("/api/identify"),
9872
+ apiClient.get(`/api/credits/transactions?days=${USAGE_DAYS}`)
9873
+ ]);
9874
+ currentCredits = identifyResponse.user.currentCredits;
9875
+ transactions = transactionsResponse || [];
9876
+ usageCache = {
9877
+ data: { currentCredits, transactions },
9878
+ timestamp: now
9879
+ };
9880
+ } catch (error) {
9881
+ if (isAxiosError2(error)) {
9882
+ if (error.response?.status === 401) {
9883
+ console.log("\n\u274C Authentication failed. Run /login to re-authenticate.\n");
9884
+ } else if (error.response?.status === 403) {
9885
+ console.log("\n\u274C Access denied. You may not have permission to view usage data.\n");
9886
+ } else if (error.response?.status === 404) {
9887
+ console.log("\n\u274C Usage endpoint not available on this server.\n");
9888
+ } else if (error.code === "ECONNREFUSED" || error.code === "ENOTFOUND") {
9889
+ console.log("\n\u274C Cannot connect to server. Check your API configuration with /api-info\n");
9890
+ } else {
9891
+ console.log(`
9892
+ \u274C Error fetching usage data: ${error.message}
9893
+ `);
9894
+ }
9895
+ } else if (error instanceof Error) {
9896
+ console.log(`
9897
+ \u274C Error: ${error.message}
9898
+ `);
9899
+ } else {
9900
+ console.log("\n\u274C Unexpected error fetching usage data. Please try again.\n");
9901
+ }
9902
+ break;
9903
+ }
9904
+ }
9905
+ const deductTransactions = transactions.filter(
9906
+ (t) => CREDIT_DEDUCT_TRANSACTION_TYPES.includes(t.type)
9907
+ );
9908
+ const totalCreditsUsed = deductTransactions.reduce((sum2, t) => sum2 + Math.abs(t.credits), 0);
9909
+ const dailyBurnRate = Math.round(totalCreditsUsed / USAGE_DAYS);
9910
+ let daysRemainingStr;
9911
+ if (dailyBurnRate === 0) {
9912
+ daysRemainingStr = "N/A (no usage)";
9913
+ } else {
9914
+ const daysRemaining = Math.floor(currentCredits / dailyBurnRate);
9915
+ daysRemainingStr = `~${daysRemaining.toLocaleString()} days`;
9916
+ }
9917
+ const usageByModel = {};
9918
+ for (const t of deductTransactions) {
9919
+ const modelName = t.metadata?.modelName || ("model" in t ? t.model : null) || "Unknown";
9920
+ usageByModel[modelName] = (usageByModel[modelName] || 0) + Math.abs(t.credits);
9921
+ }
9922
+ const sortedModels = Object.entries(usageByModel).sort((a, b) => b[1] - a[1]);
9923
+ console.log("\n Credit Usage Summary");
9924
+ console.log("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n");
9925
+ console.log(`Credits Balance: ${currentCredits.toLocaleString()}`);
9926
+ console.log(`Daily Burn Rate: ${dailyBurnRate.toLocaleString()} credits/day`);
9927
+ console.log(`Days Remaining: ${daysRemainingStr}`);
9928
+ if (currentCredits === 0) {
9929
+ console.log("\n\u26A0\uFE0F You have no credits remaining.");
9930
+ console.log("\u{1F4A1} Visit bike4mind.io to purchase more credits.\n");
9931
+ break;
9932
+ }
9933
+ if (sortedModels.length > 0) {
9934
+ console.log(`
9935
+ Usage by Model (Last ${USAGE_DAYS} days):`);
9936
+ for (const [model, credits] of sortedModels) {
9937
+ const percentage = totalCreditsUsed > 0 ? Math.round(credits / totalCreditsUsed * 100) : 0;
9938
+ const paddedModel = model.padEnd(MODEL_NAME_COLUMN_WIDTH);
9939
+ console.log(` ${paddedModel}${credits.toLocaleString()} credits (${percentage}%)`);
9940
+ }
9941
+ } else {
9942
+ console.log(`
9943
+ No usage data available for the last ${USAGE_DAYS} days.`);
9944
+ }
9945
+ console.log("");
9946
+ break;
9947
+ }
9419
9948
  default:
9420
9949
  console.log(`Unknown command: /${command}`);
9421
9950
  console.log("Type /help for available commands");
9422
9951
  }
9423
9952
  };
9424
9953
  if (initError) {
9425
- return /* @__PURE__ */ React10.createElement(Box10, { flexDirection: "column", padding: 1 }, /* @__PURE__ */ React10.createElement(Text9, { color: "red", bold: true }, "\u274C Initialization Error"), /* @__PURE__ */ React10.createElement(Text9, null, initError), /* @__PURE__ */ React10.createElement(Text9, { dimColor: true }, "\n", "Tip: Run /config to set up your API keys"));
9954
+ 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"));
9426
9955
  }
9427
9956
  if (state.showLoginFlow) {
9428
9957
  const loginApiUrl = getApiUrl(state.config?.apiConfig);
9429
- return /* @__PURE__ */ React10.createElement(
9958
+ return /* @__PURE__ */ React11.createElement(
9430
9959
  LoginFlow,
9431
9960
  {
9432
9961
  apiUrl: loginApiUrl,
@@ -9449,9 +9978,9 @@ Tool Permissions:
9449
9978
  );
9450
9979
  }
9451
9980
  if (!isInitialized) {
9452
- return /* @__PURE__ */ React10.createElement(Box10, { flexDirection: "column", padding: 1 }, /* @__PURE__ */ React10.createElement(Text9, null, "\u{1F680} Initializing..."));
9981
+ return /* @__PURE__ */ React11.createElement(Box11, { flexDirection: "column", padding: 1 }, /* @__PURE__ */ React11.createElement(Text10, null, "\u{1F680} Initializing..."));
9453
9982
  }
9454
- return /* @__PURE__ */ React10.createElement(
9983
+ return /* @__PURE__ */ React11.createElement(
9455
9984
  App,
9456
9985
  {
9457
9986
  onMessage: handleMessage,
@@ -9482,6 +10011,6 @@ var isDevMode = import.meta.url.includes("/src/") || process.env.NODE_ENV === "d
9482
10011
  if (isDevMode) {
9483
10012
  console.log("\u{1F527} Running in development mode (using TypeScript source)\n");
9484
10013
  }
9485
- render(/* @__PURE__ */ React10.createElement(CliApp, null), {
10014
+ render(/* @__PURE__ */ React11.createElement(CliApp, null), {
9486
10015
  exitOnCtrlC: false
9487
10016
  });