@bike4mind/cli 0.2.8-cli-bash-tools.17140 → 0.2.8-cli-bash-tools.17146

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.
Files changed (2) hide show
  1. package/dist/index.js +365 -294
  2. package/package.json +6 -6
package/dist/index.js CHANGED
@@ -9183,6 +9183,17 @@ var MementoEvalResponseSchema = z142.object({
9183
9183
  // ../../b4m-core/packages/services/dist/src/auth/AccessTokenGeneratorService.js
9184
9184
  import jwt2 from "jsonwebtoken";
9185
9185
 
9186
+ // ../../b4m-core/packages/services/dist/src/cliTools/types.js
9187
+ var ToolErrorType;
9188
+ (function(ToolErrorType2) {
9189
+ ToolErrorType2["INVALID_INPUT"] = "INVALID_INPUT";
9190
+ ToolErrorType2["API_KEY_MISSING"] = "API_KEY_MISSING";
9191
+ ToolErrorType2["EXTERNAL_API_ERROR"] = "EXTERNAL_API_ERROR";
9192
+ ToolErrorType2["RATE_LIMIT"] = "RATE_LIMIT";
9193
+ ToolErrorType2["NETWORK_ERROR"] = "NETWORK_ERROR";
9194
+ ToolErrorType2["UNKNOWN"] = "UNKNOWN";
9195
+ })(ToolErrorType || (ToolErrorType = {}));
9196
+
9186
9197
  // src/utils/diffPreview.ts
9187
9198
  import * as Diff from "diff";
9188
9199
  import { readFile } from "fs/promises";
@@ -9233,6 +9244,338 @@ Last modified: ${stats.mtime.toLocaleString()}`;
9233
9244
  }
9234
9245
  }
9235
9246
 
9247
+ // src/utils/Logger.ts
9248
+ import fs10 from "fs/promises";
9249
+ import path12 from "path";
9250
+ import os from "os";
9251
+ var Logger2 = class _Logger {
9252
+ constructor() {
9253
+ this.logFilePath = null;
9254
+ this.sessionId = null;
9255
+ this.fileLoggingEnabled = true;
9256
+ this.consoleVerbose = false;
9257
+ }
9258
+ static {
9259
+ this.instance = null;
9260
+ }
9261
+ static getInstance() {
9262
+ if (!_Logger.instance) {
9263
+ _Logger.instance = new _Logger();
9264
+ }
9265
+ return _Logger.instance;
9266
+ }
9267
+ /**
9268
+ * Initialize the logger with a session ID
9269
+ */
9270
+ async initialize(sessionId) {
9271
+ this.sessionId = sessionId;
9272
+ const debugDir = path12.join(os.homedir(), ".bike4mind", "debug");
9273
+ await fs10.mkdir(debugDir, { recursive: true });
9274
+ this.logFilePath = path12.join(debugDir, `${sessionId}.txt`);
9275
+ await this.writeToFile("INFO", "=== CLI SESSION START ===");
9276
+ }
9277
+ /**
9278
+ * Set whether verbose console logging is enabled
9279
+ */
9280
+ setVerbose(enabled) {
9281
+ this.consoleVerbose = enabled;
9282
+ }
9283
+ /**
9284
+ * Set whether file logging is enabled
9285
+ */
9286
+ setFileLoggingEnabled(enabled) {
9287
+ this.fileLoggingEnabled = enabled;
9288
+ }
9289
+ /**
9290
+ * DEBUG level - verbose-only console, always file
9291
+ */
9292
+ debug(message) {
9293
+ this.writeToFile("DEBUG", message).catch(() => {
9294
+ });
9295
+ if (this.consoleVerbose) {
9296
+ console.log(message);
9297
+ }
9298
+ }
9299
+ /**
9300
+ * INFO level - always shown to user
9301
+ */
9302
+ info(message) {
9303
+ this.writeToFile("INFO", message).catch(() => {
9304
+ });
9305
+ console.log(message);
9306
+ }
9307
+ /**
9308
+ * WARN level - always shown to user
9309
+ */
9310
+ warn(message) {
9311
+ this.writeToFile("WARN", message).catch(() => {
9312
+ });
9313
+ console.warn(message);
9314
+ }
9315
+ /**
9316
+ * ERROR level - always shown to user
9317
+ */
9318
+ error(message, err) {
9319
+ this.writeToFile("ERROR", message).catch(() => {
9320
+ });
9321
+ if (err) {
9322
+ this.logErrorDetailsToFile(err).catch(() => {
9323
+ });
9324
+ }
9325
+ console.error(message);
9326
+ }
9327
+ /**
9328
+ * Write log entry to file
9329
+ */
9330
+ async writeToFile(level, message) {
9331
+ if (!this.fileLoggingEnabled || !this.logFilePath) {
9332
+ return;
9333
+ }
9334
+ try {
9335
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").substring(0, 19);
9336
+ const logEntry = `[${timestamp}] [${level}] ${message}
9337
+ `;
9338
+ await fs10.appendFile(this.logFilePath, logEntry, "utf-8");
9339
+ } catch (error) {
9340
+ console.error("File logging failed:", error);
9341
+ }
9342
+ }
9343
+ /**
9344
+ * Log error details to file
9345
+ */
9346
+ async logErrorDetailsToFile(err) {
9347
+ if (!this.fileLoggingEnabled || !this.logFilePath) {
9348
+ return;
9349
+ }
9350
+ try {
9351
+ if (err && typeof err === "object" && "response" in err && err.response) {
9352
+ const response = err.response;
9353
+ const config = err && typeof err === "object" && "config" in err ? err.config : void 0;
9354
+ await this.writeToFile("ERROR", ` Status: ${response.status} ${response.statusText || ""}`);
9355
+ await this.writeToFile("ERROR", ` URL: ${config?.url || "unknown"}`);
9356
+ await this.writeToFile("ERROR", ` Headers: ${this.safeStringify(response.headers)}`);
9357
+ if (response.data) {
9358
+ const errorText = this.extractErrorMessage(response.data);
9359
+ if (errorText.trim().startsWith("<!DOCTYPE") || errorText.trim().startsWith("<html")) {
9360
+ await this.writeToFile("ERROR", ` Response Type: HTML Error Page`);
9361
+ const parsedError = this.parseHtmlError(errorText);
9362
+ if (parsedError) {
9363
+ await this.writeToFile("ERROR", ` Error Message: ${parsedError}`);
9364
+ }
9365
+ await this.writeToFile("ERROR", ` Raw HTML: ${this.truncate(errorText, 1e3)}`);
9366
+ } else {
9367
+ const preview = this.truncate(errorText, 500);
9368
+ await this.writeToFile("ERROR", ` Response: ${preview}`);
9369
+ }
9370
+ } else {
9371
+ await this.writeToFile("ERROR", ` Response: (no data)`);
9372
+ }
9373
+ }
9374
+ if (err && typeof err === "object" && "stack" in err && typeof err.stack === "string") {
9375
+ const stackLines = err.stack.split("\n").slice(0, 5).join("\n ");
9376
+ await this.writeToFile("ERROR", ` Stack: ${stackLines}`);
9377
+ } else if (err && typeof err === "object" && "message" in err && typeof err.message === "string") {
9378
+ await this.writeToFile("ERROR", ` Message: ${err.message}`);
9379
+ }
9380
+ } catch (error) {
9381
+ }
9382
+ }
9383
+ /**
9384
+ * Safely stringify object, handling circular references
9385
+ */
9386
+ safeStringify(obj) {
9387
+ try {
9388
+ return JSON.stringify(obj);
9389
+ } catch (error) {
9390
+ if (error instanceof Error && error.message.includes("circular")) {
9391
+ try {
9392
+ const seen = /* @__PURE__ */ new WeakSet();
9393
+ return JSON.stringify(obj, (key, value) => {
9394
+ if (typeof value === "object" && value !== null) {
9395
+ if (seen.has(value)) {
9396
+ return "[Circular]";
9397
+ }
9398
+ seen.add(value);
9399
+ }
9400
+ return value;
9401
+ });
9402
+ } catch {
9403
+ return "[Unable to stringify]";
9404
+ }
9405
+ }
9406
+ return "[Stringify error]";
9407
+ }
9408
+ }
9409
+ /**
9410
+ * Extract readable text from error response data
9411
+ */
9412
+ extractErrorMessage(data) {
9413
+ if (Buffer.isBuffer(data)) {
9414
+ return data.toString("utf-8");
9415
+ }
9416
+ if (typeof data === "string") {
9417
+ return data;
9418
+ }
9419
+ if (data && typeof data === "object" && "_readableState" in data && data._readableState && typeof data._readableState === "object" && "buffer" in data._readableState && Array.isArray(data._readableState.buffer) && data._readableState.buffer.length > 0) {
9420
+ const chunks = [];
9421
+ for (const chunk of data._readableState.buffer) {
9422
+ if (chunk && typeof chunk === "object" && "type" in chunk && chunk.type === "Buffer" && "data" in chunk && Array.isArray(chunk.data)) {
9423
+ chunks.push(Buffer.from(chunk.data));
9424
+ } else if (Buffer.isBuffer(chunk)) {
9425
+ chunks.push(chunk);
9426
+ } else if (chunk && typeof chunk === "object" && "data" in chunk) {
9427
+ if (Buffer.isBuffer(chunk.data)) {
9428
+ chunks.push(chunk.data);
9429
+ } else if (Array.isArray(chunk.data)) {
9430
+ chunks.push(Buffer.from(chunk.data));
9431
+ }
9432
+ }
9433
+ }
9434
+ if (chunks.length > 0) {
9435
+ return Buffer.concat(chunks).toString("utf-8");
9436
+ }
9437
+ }
9438
+ return this.safeStringify(data);
9439
+ }
9440
+ /**
9441
+ * Parse HTML error page to extract error message
9442
+ */
9443
+ parseHtmlError(html) {
9444
+ const titleMatch = html.match(/<title>(.*?)<\/title>/i);
9445
+ const h1Match = html.match(/<h1>(.*?)<\/h1>/i);
9446
+ const bodyMatch = html.match(/<body[^>]*>(.*?)<\/body>/is);
9447
+ if (titleMatch && titleMatch[1] !== "Error") {
9448
+ return titleMatch[1].trim();
9449
+ }
9450
+ if (h1Match) {
9451
+ return h1Match[1].trim();
9452
+ }
9453
+ if (bodyMatch) {
9454
+ const text = bodyMatch[1].replace(/<[^>]+>/g, " ").replace(/\s+/g, " ").trim();
9455
+ return text.substring(0, 200);
9456
+ }
9457
+ return null;
9458
+ }
9459
+ /**
9460
+ * Truncate string to max length with ellipsis
9461
+ */
9462
+ truncate(str, maxLength) {
9463
+ if (str.length <= maxLength) {
9464
+ return str;
9465
+ }
9466
+ return str.substring(0, maxLength) + "... [truncated]";
9467
+ }
9468
+ /**
9469
+ * Format bytes to human-readable size
9470
+ */
9471
+ formatBytes(bytes) {
9472
+ if (bytes === 0) return "0 B";
9473
+ const k = 1024;
9474
+ const sizes = ["B", "KB", "MB", "GB"];
9475
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
9476
+ return Math.round(bytes / Math.pow(k, i) * 100) / 100 + " " + sizes[i];
9477
+ }
9478
+ /**
9479
+ * Clean up old debug logs (older than 30 days)
9480
+ */
9481
+ async cleanupOldLogs() {
9482
+ if (!this.fileLoggingEnabled) return;
9483
+ try {
9484
+ const debugDir = path12.join(os.homedir(), ".bike4mind", "debug");
9485
+ const files = await fs10.readdir(debugDir);
9486
+ const now = Date.now();
9487
+ const thirtyDaysAgo = now - 30 * 24 * 60 * 60 * 1e3;
9488
+ for (const file of files) {
9489
+ const filePath = path12.join(debugDir, file);
9490
+ const stats = await fs10.stat(filePath);
9491
+ if (stats.mtime.getTime() < thirtyDaysAgo) {
9492
+ await fs10.unlink(filePath);
9493
+ }
9494
+ }
9495
+ } catch (error) {
9496
+ console.error("Failed to cleanup old logs:", error);
9497
+ }
9498
+ }
9499
+ };
9500
+ var logger = Logger2.getInstance();
9501
+
9502
+ // src/llm/ServerToolExecutor.ts
9503
+ var ServerToolExecutor = class {
9504
+ constructor(apiClient) {
9505
+ this.toolsEndpoint = "/api/ai/v1/tools";
9506
+ this.apiClient = apiClient;
9507
+ }
9508
+ /**
9509
+ * Execute a tool server-side
9510
+ *
9511
+ * @param toolName - Name of the tool to execute (e.g., 'weather_info', 'web_search')
9512
+ * @param input - Tool input parameters
9513
+ * @returns Tool execution result (content or error)
9514
+ */
9515
+ async executeTool(toolName, input) {
9516
+ logger.debug(`[ServerToolExecutor] Executing tool: ${toolName}`);
9517
+ logger.debug(`[ServerToolExecutor] Endpoint: ${this.toolsEndpoint}`);
9518
+ logger.debug(`[ServerToolExecutor] Input: ${JSON.stringify(input)}`);
9519
+ try {
9520
+ const result = await this.apiClient.post(this.toolsEndpoint, {
9521
+ toolName,
9522
+ input
9523
+ });
9524
+ logger.debug(`[ServerToolExecutor] Response: ${JSON.stringify(result)}`);
9525
+ if (!result.success) {
9526
+ const errorMessage = result.error || "Tool execution failed";
9527
+ logger.error(`[ServerToolExecutor] Tool ${toolName} failed: ${errorMessage}`);
9528
+ return `Error executing ${toolName}: ${errorMessage}`;
9529
+ }
9530
+ logger.debug(`[ServerToolExecutor] Tool ${toolName} succeeded in ${result.executionTimeMs}ms`);
9531
+ return result.content || "";
9532
+ } catch (error) {
9533
+ const err = error;
9534
+ const errorMessage = err?.response?.data?.error || err?.message || "Unknown error";
9535
+ const status = err?.response?.status || "unknown";
9536
+ logger.error(`[ServerToolExecutor] Request failed for ${toolName}: ${errorMessage} (status: ${status})`);
9537
+ logger.error(`[ServerToolExecutor] Full error: ${JSON.stringify(err, null, 2)}`);
9538
+ return `Error executing ${toolName}: ${errorMessage}`;
9539
+ }
9540
+ }
9541
+ };
9542
+
9543
+ // src/llm/ToolRouter.ts
9544
+ var SERVER_TOOLS = ["weather_info", "web_search"];
9545
+ var LOCAL_TOOLS = [
9546
+ "file_read",
9547
+ "create_file",
9548
+ "glob_files",
9549
+ "grep_search",
9550
+ "delete_file",
9551
+ "edit_file",
9552
+ "dice_roll",
9553
+ "math_evaluate",
9554
+ "current_datetime"
9555
+ ];
9556
+ function isServerTool(toolName) {
9557
+ return SERVER_TOOLS.includes(toolName);
9558
+ }
9559
+ function isLocalTool(toolName) {
9560
+ return LOCAL_TOOLS.includes(toolName);
9561
+ }
9562
+ async function executeTool(toolName, input, apiClient, localToolFn) {
9563
+ if (isServerTool(toolName)) {
9564
+ logger.debug(`[ToolRouter] Routing ${toolName} to server`);
9565
+ const executor = new ServerToolExecutor(apiClient);
9566
+ return await executor.executeTool(toolName, input);
9567
+ } else if (isLocalTool(toolName)) {
9568
+ logger.debug(`[ToolRouter] Executing ${toolName} locally`);
9569
+ if (!localToolFn) {
9570
+ throw new Error(`Local tool ${toolName} has no implementation`);
9571
+ }
9572
+ const result = await localToolFn(input);
9573
+ return typeof result === "string" ? result : JSON.stringify(result);
9574
+ } else {
9575
+ throw new Error(`Unknown tool: ${toolName}`);
9576
+ }
9577
+ }
9578
+
9236
9579
  // src/utils/toolsAdapter.ts
9237
9580
  var NoOpStorage = class extends BaseStorage {
9238
9581
  async upload(input, destination, options) {
@@ -9272,14 +9615,14 @@ var CliLogger = class extends Logger {
9272
9615
  log(...args) {
9273
9616
  }
9274
9617
  };
9275
- function wrapToolWithPermission(tool, permissionManager, showPermissionPrompt, agentContext, configStore) {
9618
+ function wrapToolWithPermission(tool, permissionManager, showPermissionPrompt, agentContext, configStore, apiClient) {
9276
9619
  const originalFn = tool.toolFn;
9277
9620
  const toolName = tool.toolSchema.name;
9278
9621
  return {
9279
9622
  ...tool,
9280
9623
  toolFn: async (args) => {
9281
9624
  if (!permissionManager.needsPermission(toolName)) {
9282
- const result2 = await originalFn(args);
9625
+ const result2 = await executeTool(toolName, args, apiClient, originalFn);
9283
9626
  agentContext.observationQueue.push({ toolName, result: result2 });
9284
9627
  return result2;
9285
9628
  }
@@ -9340,13 +9683,13 @@ function wrapToolWithPermission(tool, permissionManager, showPermissionPrompt, a
9340
9683
  }
9341
9684
  }
9342
9685
  }
9343
- const result = await originalFn(args);
9686
+ const result = await executeTool(toolName, args, apiClient, originalFn);
9344
9687
  agentContext.observationQueue.push({ toolName, result });
9345
9688
  return result;
9346
9689
  }
9347
9690
  };
9348
9691
  }
9349
- function generateCliTools(userId, llm, model, permissionManager, showPermissionPrompt, agentContext, configStore, toolApiKeys) {
9692
+ function generateCliTools(userId, llm, model, permissionManager, showPermissionPrompt, agentContext, configStore, apiClient) {
9350
9693
  const logger2 = new CliLogger();
9351
9694
  const storage = new NoOpStorage();
9352
9695
  const user = {
@@ -9363,18 +9706,6 @@ function generateCliTools(userId, llm, model, permissionManager, showPermissionP
9363
9706
  };
9364
9707
  const mockAdminSettings = {
9365
9708
  findBySettingName: async (settingName) => {
9366
- if (settingName === "OpenWeatherKey") {
9367
- const key = toolApiKeys?.openweather || process.env.OPENWEATHER_API_KEY;
9368
- if (key) {
9369
- return { settingValue: key };
9370
- }
9371
- }
9372
- if (settingName === "SerperKey") {
9373
- const key = toolApiKeys?.serper || process.env.SERPER_API_KEY;
9374
- if (key) {
9375
- return { settingValue: key };
9376
- }
9377
- }
9378
9709
  return null;
9379
9710
  }
9380
9711
  };
@@ -9384,15 +9715,13 @@ function generateCliTools(userId, llm, model, permissionManager, showPermissionP
9384
9715
  adminSettings: mockAdminSettings
9385
9716
  }
9386
9717
  };
9387
- const hasSerperKey = !!(toolApiKeys?.serper || process.env.SERPER_API_KEY);
9388
- const hasOpenWeatherKey = !!(toolApiKeys?.openweather || process.env.OPENWEATHER_API_KEY);
9389
9718
  const toolConfig = {
9390
- // Enable these tools for CLI (no external API keys needed)
9719
+ // Local-only tools (no external API keys needed)
9391
9720
  dice_roll: {},
9392
9721
  math_evaluate: {},
9393
9722
  current_datetime: {},
9394
9723
  prompt_enhancement: {},
9395
- // File operation tools (CLI-specific)
9724
+ // File operation tools (CLI-specific, local execution)
9396
9725
  file_read: {},
9397
9726
  create_file: {},
9398
9727
  glob_files: {},
@@ -9400,13 +9729,10 @@ function generateCliTools(userId, llm, model, permissionManager, showPermissionP
9400
9729
  delete_file: {},
9401
9730
  // Shell execution (always requires permission)
9402
9731
  bash_execute: {},
9403
- // Tools requiring API keys (only include if API key is available)
9404
- ...hasSerperKey && { web_search: {} },
9405
- // Requires SERPER_API_KEY
9406
- ...hasOpenWeatherKey && { weather_info: {} },
9407
- // Requires OPENWEATHER_API_KEY
9408
- ...hasSerperKey && { deep_research: {} }
9409
- // Requires SERPER_API_KEY
9732
+ // Server-side tools (executed via /api/ai/v1/tools Lambda)
9733
+ // Routed by ToolRouter to use B4M company API keys
9734
+ weather_info: {},
9735
+ web_search: {}
9410
9736
  // Disable web-only tools
9411
9737
  // blog_publish: undefined,
9412
9738
  // blog_edit: undefined,
@@ -9416,6 +9742,7 @@ function generateCliTools(userId, llm, model, permissionManager, showPermissionP
9416
9742
  // mermaid_chart: undefined,
9417
9743
  // recharts: undefined,
9418
9744
  // edit_file: undefined,
9745
+ // deep_research: undefined,
9419
9746
  };
9420
9747
  const toolsMap = generateTools(
9421
9748
  userId,
@@ -9433,7 +9760,7 @@ function generateCliTools(userId, llm, model, permissionManager, showPermissionP
9433
9760
  model
9434
9761
  );
9435
9762
  const tools2 = Object.entries(toolsMap).filter(([key]) => toolConfig[key] !== void 0).map(
9436
- ([_, tool]) => wrapToolWithPermission(tool, permissionManager, showPermissionPrompt, agentContext, configStore)
9763
+ ([_, tool]) => wrapToolWithPermission(tool, permissionManager, showPermissionPrompt, agentContext, configStore, apiClient)
9437
9764
  );
9438
9765
  return { tools: tools2, agentContext };
9439
9766
  }
@@ -9629,261 +9956,6 @@ function getEnvironmentName(configApiConfig) {
9629
9956
  return "Bike4Mind";
9630
9957
  }
9631
9958
 
9632
- // src/utils/Logger.ts
9633
- import fs10 from "fs/promises";
9634
- import path12 from "path";
9635
- import os from "os";
9636
- var Logger2 = class _Logger {
9637
- constructor() {
9638
- this.logFilePath = null;
9639
- this.sessionId = null;
9640
- this.fileLoggingEnabled = true;
9641
- this.consoleVerbose = false;
9642
- }
9643
- static {
9644
- this.instance = null;
9645
- }
9646
- static getInstance() {
9647
- if (!_Logger.instance) {
9648
- _Logger.instance = new _Logger();
9649
- }
9650
- return _Logger.instance;
9651
- }
9652
- /**
9653
- * Initialize the logger with a session ID
9654
- */
9655
- async initialize(sessionId) {
9656
- this.sessionId = sessionId;
9657
- const debugDir = path12.join(os.homedir(), ".bike4mind", "debug");
9658
- await fs10.mkdir(debugDir, { recursive: true });
9659
- this.logFilePath = path12.join(debugDir, `${sessionId}.txt`);
9660
- await this.writeToFile("INFO", "=== CLI SESSION START ===");
9661
- }
9662
- /**
9663
- * Set whether verbose console logging is enabled
9664
- */
9665
- setVerbose(enabled) {
9666
- this.consoleVerbose = enabled;
9667
- }
9668
- /**
9669
- * Set whether file logging is enabled
9670
- */
9671
- setFileLoggingEnabled(enabled) {
9672
- this.fileLoggingEnabled = enabled;
9673
- }
9674
- /**
9675
- * DEBUG level - verbose-only console, always file
9676
- */
9677
- debug(message) {
9678
- this.writeToFile("DEBUG", message).catch(() => {
9679
- });
9680
- if (this.consoleVerbose) {
9681
- console.log(message);
9682
- }
9683
- }
9684
- /**
9685
- * INFO level - always shown to user
9686
- */
9687
- info(message) {
9688
- this.writeToFile("INFO", message).catch(() => {
9689
- });
9690
- console.log(message);
9691
- }
9692
- /**
9693
- * WARN level - always shown to user
9694
- */
9695
- warn(message) {
9696
- this.writeToFile("WARN", message).catch(() => {
9697
- });
9698
- console.warn(message);
9699
- }
9700
- /**
9701
- * ERROR level - always shown to user
9702
- */
9703
- error(message, err) {
9704
- this.writeToFile("ERROR", message).catch(() => {
9705
- });
9706
- if (err) {
9707
- this.logErrorDetailsToFile(err).catch(() => {
9708
- });
9709
- }
9710
- console.error(message);
9711
- }
9712
- /**
9713
- * Write log entry to file
9714
- */
9715
- async writeToFile(level, message) {
9716
- if (!this.fileLoggingEnabled || !this.logFilePath) {
9717
- return;
9718
- }
9719
- try {
9720
- const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").substring(0, 19);
9721
- const logEntry = `[${timestamp}] [${level}] ${message}
9722
- `;
9723
- await fs10.appendFile(this.logFilePath, logEntry, "utf-8");
9724
- } catch (error) {
9725
- console.error("File logging failed:", error);
9726
- }
9727
- }
9728
- /**
9729
- * Log error details to file
9730
- */
9731
- async logErrorDetailsToFile(err) {
9732
- if (!this.fileLoggingEnabled || !this.logFilePath) {
9733
- return;
9734
- }
9735
- try {
9736
- if (err && typeof err === "object" && "response" in err && err.response) {
9737
- const response = err.response;
9738
- const config = err && typeof err === "object" && "config" in err ? err.config : void 0;
9739
- await this.writeToFile("ERROR", ` Status: ${response.status} ${response.statusText || ""}`);
9740
- await this.writeToFile("ERROR", ` URL: ${config?.url || "unknown"}`);
9741
- await this.writeToFile("ERROR", ` Headers: ${this.safeStringify(response.headers)}`);
9742
- if (response.data) {
9743
- const errorText = this.extractErrorMessage(response.data);
9744
- if (errorText.trim().startsWith("<!DOCTYPE") || errorText.trim().startsWith("<html")) {
9745
- await this.writeToFile("ERROR", ` Response Type: HTML Error Page`);
9746
- const parsedError = this.parseHtmlError(errorText);
9747
- if (parsedError) {
9748
- await this.writeToFile("ERROR", ` Error Message: ${parsedError}`);
9749
- }
9750
- await this.writeToFile("ERROR", ` Raw HTML: ${this.truncate(errorText, 1e3)}`);
9751
- } else {
9752
- const preview = this.truncate(errorText, 500);
9753
- await this.writeToFile("ERROR", ` Response: ${preview}`);
9754
- }
9755
- } else {
9756
- await this.writeToFile("ERROR", ` Response: (no data)`);
9757
- }
9758
- }
9759
- if (err && typeof err === "object" && "stack" in err && typeof err.stack === "string") {
9760
- const stackLines = err.stack.split("\n").slice(0, 5).join("\n ");
9761
- await this.writeToFile("ERROR", ` Stack: ${stackLines}`);
9762
- } else if (err && typeof err === "object" && "message" in err && typeof err.message === "string") {
9763
- await this.writeToFile("ERROR", ` Message: ${err.message}`);
9764
- }
9765
- } catch (error) {
9766
- }
9767
- }
9768
- /**
9769
- * Safely stringify object, handling circular references
9770
- */
9771
- safeStringify(obj) {
9772
- try {
9773
- return JSON.stringify(obj);
9774
- } catch (error) {
9775
- if (error instanceof Error && error.message.includes("circular")) {
9776
- try {
9777
- const seen = /* @__PURE__ */ new WeakSet();
9778
- return JSON.stringify(obj, (key, value) => {
9779
- if (typeof value === "object" && value !== null) {
9780
- if (seen.has(value)) {
9781
- return "[Circular]";
9782
- }
9783
- seen.add(value);
9784
- }
9785
- return value;
9786
- });
9787
- } catch {
9788
- return "[Unable to stringify]";
9789
- }
9790
- }
9791
- return "[Stringify error]";
9792
- }
9793
- }
9794
- /**
9795
- * Extract readable text from error response data
9796
- */
9797
- extractErrorMessage(data) {
9798
- if (Buffer.isBuffer(data)) {
9799
- return data.toString("utf-8");
9800
- }
9801
- if (typeof data === "string") {
9802
- return data;
9803
- }
9804
- if (data && typeof data === "object" && "_readableState" in data && data._readableState && typeof data._readableState === "object" && "buffer" in data._readableState && Array.isArray(data._readableState.buffer) && data._readableState.buffer.length > 0) {
9805
- const chunks = [];
9806
- for (const chunk of data._readableState.buffer) {
9807
- if (chunk && typeof chunk === "object" && "type" in chunk && chunk.type === "Buffer" && "data" in chunk && Array.isArray(chunk.data)) {
9808
- chunks.push(Buffer.from(chunk.data));
9809
- } else if (Buffer.isBuffer(chunk)) {
9810
- chunks.push(chunk);
9811
- } else if (chunk && typeof chunk === "object" && "data" in chunk) {
9812
- if (Buffer.isBuffer(chunk.data)) {
9813
- chunks.push(chunk.data);
9814
- } else if (Array.isArray(chunk.data)) {
9815
- chunks.push(Buffer.from(chunk.data));
9816
- }
9817
- }
9818
- }
9819
- if (chunks.length > 0) {
9820
- return Buffer.concat(chunks).toString("utf-8");
9821
- }
9822
- }
9823
- return this.safeStringify(data);
9824
- }
9825
- /**
9826
- * Parse HTML error page to extract error message
9827
- */
9828
- parseHtmlError(html) {
9829
- const titleMatch = html.match(/<title>(.*?)<\/title>/i);
9830
- const h1Match = html.match(/<h1>(.*?)<\/h1>/i);
9831
- const bodyMatch = html.match(/<body[^>]*>(.*?)<\/body>/is);
9832
- if (titleMatch && titleMatch[1] !== "Error") {
9833
- return titleMatch[1].trim();
9834
- }
9835
- if (h1Match) {
9836
- return h1Match[1].trim();
9837
- }
9838
- if (bodyMatch) {
9839
- const text = bodyMatch[1].replace(/<[^>]+>/g, " ").replace(/\s+/g, " ").trim();
9840
- return text.substring(0, 200);
9841
- }
9842
- return null;
9843
- }
9844
- /**
9845
- * Truncate string to max length with ellipsis
9846
- */
9847
- truncate(str, maxLength) {
9848
- if (str.length <= maxLength) {
9849
- return str;
9850
- }
9851
- return str.substring(0, maxLength) + "... [truncated]";
9852
- }
9853
- /**
9854
- * Format bytes to human-readable size
9855
- */
9856
- formatBytes(bytes) {
9857
- if (bytes === 0) return "0 B";
9858
- const k = 1024;
9859
- const sizes = ["B", "KB", "MB", "GB"];
9860
- const i = Math.floor(Math.log(bytes) / Math.log(k));
9861
- return Math.round(bytes / Math.pow(k, i) * 100) / 100 + " " + sizes[i];
9862
- }
9863
- /**
9864
- * Clean up old debug logs (older than 30 days)
9865
- */
9866
- async cleanupOldLogs() {
9867
- if (!this.fileLoggingEnabled) return;
9868
- try {
9869
- const debugDir = path12.join(os.homedir(), ".bike4mind", "debug");
9870
- const files = await fs10.readdir(debugDir);
9871
- const now = Date.now();
9872
- const thirtyDaysAgo = now - 30 * 24 * 60 * 60 * 1e3;
9873
- for (const file of files) {
9874
- const filePath = path12.join(debugDir, file);
9875
- const stats = await fs10.stat(filePath);
9876
- if (stats.mtime.getTime() < thirtyDaysAgo) {
9877
- await fs10.unlink(filePath);
9878
- }
9879
- }
9880
- } catch (error) {
9881
- console.error("Failed to cleanup old logs:", error);
9882
- }
9883
- }
9884
- };
9885
- var logger = Logger2.getInstance();
9886
-
9887
9959
  // ../../b4m-core/packages/mcp/dist/src/client.js
9888
9960
  import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
9889
9961
  import { Client as Client2 } from "@modelcontextprotocol/sdk/client/index.js";
@@ -10687,7 +10759,10 @@ var ApiClient = class {
10687
10759
  * Make a POST request
10688
10760
  */
10689
10761
  async post(url, data, config) {
10762
+ logger.debug(`[ApiClient] POST ${this.client.defaults.baseURL}${url}`);
10763
+ logger.debug(`[ApiClient] Request body: ${JSON.stringify(data)}`);
10690
10764
  const response = await this.client.post(url, data, config);
10765
+ logger.debug(`[ApiClient] Response status: ${response.status}`);
10691
10766
  return response.data;
10692
10767
  }
10693
10768
  /**
@@ -10738,7 +10813,7 @@ import { isAxiosError as isAxiosError2 } from "axios";
10738
10813
  // package.json
10739
10814
  var package_default = {
10740
10815
  name: "@bike4mind/cli",
10741
- version: "0.2.8-cli-bash-tools.17140+f678d9888",
10816
+ version: "0.2.8-cli-bash-tools.17146+9129ce1ea",
10742
10817
  type: "module",
10743
10818
  description: "Interactive CLI tool for Bike4Mind with ReAct agents",
10744
10819
  license: "UNLICENSED",
@@ -10841,10 +10916,10 @@ var package_default = {
10841
10916
  },
10842
10917
  devDependencies: {
10843
10918
  "@bike4mind/agents": "0.1.0",
10844
- "@bike4mind/common": "2.38.2-cli-bash-tools.17140+f678d9888",
10845
- "@bike4mind/mcp": "1.20.2-cli-bash-tools.17140+f678d9888",
10846
- "@bike4mind/services": "2.33.2-cli-bash-tools.17140+f678d9888",
10847
- "@bike4mind/utils": "2.1.3-cli-bash-tools.17140+f678d9888",
10919
+ "@bike4mind/common": "2.38.2-cli-bash-tools.17146+9129ce1ea",
10920
+ "@bike4mind/mcp": "1.20.2-cli-bash-tools.17146+9129ce1ea",
10921
+ "@bike4mind/services": "2.33.2-cli-bash-tools.17146+9129ce1ea",
10922
+ "@bike4mind/utils": "2.1.3-cli-bash-tools.17146+9129ce1ea",
10848
10923
  "@types/better-sqlite3": "^7.6.12",
10849
10924
  "@types/diff": "^5.0.9",
10850
10925
  "@types/jsonwebtoken": "^9.0.4",
@@ -10857,7 +10932,7 @@ var package_default = {
10857
10932
  typescript: "^5.9.3",
10858
10933
  vitest: "^3.2.4"
10859
10934
  },
10860
- gitHead: "f678d98888d841ba0496d91a1225dd89edb21e35"
10935
+ gitHead: "9129ce1ea5d8589dec80ac92bf32ca954c6844fc"
10861
10936
  };
10862
10937
 
10863
10938
  // src/config/constants.ts
@@ -11082,10 +11157,6 @@ function CliApp() {
11082
11157
  setPermissionPrompt(prompt);
11083
11158
  });
11084
11159
  };
11085
- console.log("\u{1F511} Tool API Keys:", {
11086
- openweather: config.toolApiKeys?.openweather ? "\u2713 configured" : "\u2717 missing",
11087
- serper: config.toolApiKeys?.serper ? "\u2713 configured" : "\u2717 missing"
11088
- });
11089
11160
  const agentContext = {
11090
11161
  currentAgent: null,
11091
11162
  observationQueue: []
@@ -11098,7 +11169,7 @@ function CliApp() {
11098
11169
  promptFn,
11099
11170
  agentContext,
11100
11171
  state.configStore,
11101
- config.toolApiKeys
11172
+ apiClient
11102
11173
  );
11103
11174
  console.log(`\u{1F6E0}\uFE0F Loaded ${b4mTools.length} B4M tool(s)`);
11104
11175
  const mcpManager = new McpManager(config);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bike4mind/cli",
3
- "version": "0.2.8-cli-bash-tools.17140+f678d9888",
3
+ "version": "0.2.8-cli-bash-tools.17146+9129ce1ea",
4
4
  "type": "module",
5
5
  "description": "Interactive CLI tool for Bike4Mind with ReAct agents",
6
6
  "license": "UNLICENSED",
@@ -103,10 +103,10 @@
103
103
  },
104
104
  "devDependencies": {
105
105
  "@bike4mind/agents": "0.1.0",
106
- "@bike4mind/common": "2.38.2-cli-bash-tools.17140+f678d9888",
107
- "@bike4mind/mcp": "1.20.2-cli-bash-tools.17140+f678d9888",
108
- "@bike4mind/services": "2.33.2-cli-bash-tools.17140+f678d9888",
109
- "@bike4mind/utils": "2.1.3-cli-bash-tools.17140+f678d9888",
106
+ "@bike4mind/common": "2.38.2-cli-bash-tools.17146+9129ce1ea",
107
+ "@bike4mind/mcp": "1.20.2-cli-bash-tools.17146+9129ce1ea",
108
+ "@bike4mind/services": "2.33.2-cli-bash-tools.17146+9129ce1ea",
109
+ "@bike4mind/utils": "2.1.3-cli-bash-tools.17146+9129ce1ea",
110
110
  "@types/better-sqlite3": "^7.6.12",
111
111
  "@types/diff": "^5.0.9",
112
112
  "@types/jsonwebtoken": "^9.0.4",
@@ -119,5 +119,5 @@
119
119
  "typescript": "^5.9.3",
120
120
  "vitest": "^3.2.4"
121
121
  },
122
- "gitHead": "f678d98888d841ba0496d91a1225dd89edb21e35"
122
+ "gitHead": "9129ce1ea5d8589dec80ac92bf32ca954c6844fc"
123
123
  }