@bike4mind/cli 0.2.7-feat-cli-tool-lambda-v2.17131 → 0.2.7-feat-organization-overview-enhancements.17130

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 +295 -366
  2. package/package.json +7 -7
package/dist/index.js CHANGED
@@ -8713,17 +8713,6 @@ var MementoEvalResponseSchema = z142.object({
8713
8713
  // ../../b4m-core/packages/services/dist/src/auth/AccessTokenGeneratorService.js
8714
8714
  import jwt2 from "jsonwebtoken";
8715
8715
 
8716
- // ../../b4m-core/packages/services/dist/src/cliTools/types.js
8717
- var ToolErrorType;
8718
- (function(ToolErrorType2) {
8719
- ToolErrorType2["INVALID_INPUT"] = "INVALID_INPUT";
8720
- ToolErrorType2["API_KEY_MISSING"] = "API_KEY_MISSING";
8721
- ToolErrorType2["EXTERNAL_API_ERROR"] = "EXTERNAL_API_ERROR";
8722
- ToolErrorType2["RATE_LIMIT"] = "RATE_LIMIT";
8723
- ToolErrorType2["NETWORK_ERROR"] = "NETWORK_ERROR";
8724
- ToolErrorType2["UNKNOWN"] = "UNKNOWN";
8725
- })(ToolErrorType || (ToolErrorType = {}));
8726
-
8727
8716
  // src/utils/diffPreview.ts
8728
8717
  import * as Diff from "diff";
8729
8718
  import { readFile } from "fs/promises";
@@ -8774,338 +8763,6 @@ Last modified: ${stats.mtime.toLocaleString()}`;
8774
8763
  }
8775
8764
  }
8776
8765
 
8777
- // src/utils/Logger.ts
8778
- import fs10 from "fs/promises";
8779
- import path11 from "path";
8780
- import os from "os";
8781
- var Logger2 = class _Logger {
8782
- constructor() {
8783
- this.logFilePath = null;
8784
- this.sessionId = null;
8785
- this.fileLoggingEnabled = true;
8786
- this.consoleVerbose = false;
8787
- }
8788
- static {
8789
- this.instance = null;
8790
- }
8791
- static getInstance() {
8792
- if (!_Logger.instance) {
8793
- _Logger.instance = new _Logger();
8794
- }
8795
- return _Logger.instance;
8796
- }
8797
- /**
8798
- * Initialize the logger with a session ID
8799
- */
8800
- async initialize(sessionId) {
8801
- this.sessionId = sessionId;
8802
- const debugDir = path11.join(os.homedir(), ".bike4mind", "debug");
8803
- await fs10.mkdir(debugDir, { recursive: true });
8804
- this.logFilePath = path11.join(debugDir, `${sessionId}.txt`);
8805
- await this.writeToFile("INFO", "=== CLI SESSION START ===");
8806
- }
8807
- /**
8808
- * Set whether verbose console logging is enabled
8809
- */
8810
- setVerbose(enabled) {
8811
- this.consoleVerbose = enabled;
8812
- }
8813
- /**
8814
- * Set whether file logging is enabled
8815
- */
8816
- setFileLoggingEnabled(enabled) {
8817
- this.fileLoggingEnabled = enabled;
8818
- }
8819
- /**
8820
- * DEBUG level - verbose-only console, always file
8821
- */
8822
- debug(message) {
8823
- this.writeToFile("DEBUG", message).catch(() => {
8824
- });
8825
- if (this.consoleVerbose) {
8826
- console.log(message);
8827
- }
8828
- }
8829
- /**
8830
- * INFO level - always shown to user
8831
- */
8832
- info(message) {
8833
- this.writeToFile("INFO", message).catch(() => {
8834
- });
8835
- console.log(message);
8836
- }
8837
- /**
8838
- * WARN level - always shown to user
8839
- */
8840
- warn(message) {
8841
- this.writeToFile("WARN", message).catch(() => {
8842
- });
8843
- console.warn(message);
8844
- }
8845
- /**
8846
- * ERROR level - always shown to user
8847
- */
8848
- error(message, err) {
8849
- this.writeToFile("ERROR", message).catch(() => {
8850
- });
8851
- if (err) {
8852
- this.logErrorDetailsToFile(err).catch(() => {
8853
- });
8854
- }
8855
- console.error(message);
8856
- }
8857
- /**
8858
- * Write log entry to file
8859
- */
8860
- async writeToFile(level, message) {
8861
- if (!this.fileLoggingEnabled || !this.logFilePath) {
8862
- return;
8863
- }
8864
- try {
8865
- const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").substring(0, 19);
8866
- const logEntry = `[${timestamp}] [${level}] ${message}
8867
- `;
8868
- await fs10.appendFile(this.logFilePath, logEntry, "utf-8");
8869
- } catch (error) {
8870
- console.error("File logging failed:", error);
8871
- }
8872
- }
8873
- /**
8874
- * Log error details to file
8875
- */
8876
- async logErrorDetailsToFile(err) {
8877
- if (!this.fileLoggingEnabled || !this.logFilePath) {
8878
- return;
8879
- }
8880
- try {
8881
- if (err && typeof err === "object" && "response" in err && err.response) {
8882
- const response = err.response;
8883
- const config = err && typeof err === "object" && "config" in err ? err.config : void 0;
8884
- await this.writeToFile("ERROR", ` Status: ${response.status} ${response.statusText || ""}`);
8885
- await this.writeToFile("ERROR", ` URL: ${config?.url || "unknown"}`);
8886
- await this.writeToFile("ERROR", ` Headers: ${this.safeStringify(response.headers)}`);
8887
- if (response.data) {
8888
- const errorText = this.extractErrorMessage(response.data);
8889
- if (errorText.trim().startsWith("<!DOCTYPE") || errorText.trim().startsWith("<html")) {
8890
- await this.writeToFile("ERROR", ` Response Type: HTML Error Page`);
8891
- const parsedError = this.parseHtmlError(errorText);
8892
- if (parsedError) {
8893
- await this.writeToFile("ERROR", ` Error Message: ${parsedError}`);
8894
- }
8895
- await this.writeToFile("ERROR", ` Raw HTML: ${this.truncate(errorText, 1e3)}`);
8896
- } else {
8897
- const preview = this.truncate(errorText, 500);
8898
- await this.writeToFile("ERROR", ` Response: ${preview}`);
8899
- }
8900
- } else {
8901
- await this.writeToFile("ERROR", ` Response: (no data)`);
8902
- }
8903
- }
8904
- if (err && typeof err === "object" && "stack" in err && typeof err.stack === "string") {
8905
- const stackLines = err.stack.split("\n").slice(0, 5).join("\n ");
8906
- await this.writeToFile("ERROR", ` Stack: ${stackLines}`);
8907
- } else if (err && typeof err === "object" && "message" in err && typeof err.message === "string") {
8908
- await this.writeToFile("ERROR", ` Message: ${err.message}`);
8909
- }
8910
- } catch (error) {
8911
- }
8912
- }
8913
- /**
8914
- * Safely stringify object, handling circular references
8915
- */
8916
- safeStringify(obj) {
8917
- try {
8918
- return JSON.stringify(obj);
8919
- } catch (error) {
8920
- if (error instanceof Error && error.message.includes("circular")) {
8921
- try {
8922
- const seen = /* @__PURE__ */ new WeakSet();
8923
- return JSON.stringify(obj, (key, value) => {
8924
- if (typeof value === "object" && value !== null) {
8925
- if (seen.has(value)) {
8926
- return "[Circular]";
8927
- }
8928
- seen.add(value);
8929
- }
8930
- return value;
8931
- });
8932
- } catch {
8933
- return "[Unable to stringify]";
8934
- }
8935
- }
8936
- return "[Stringify error]";
8937
- }
8938
- }
8939
- /**
8940
- * Extract readable text from error response data
8941
- */
8942
- extractErrorMessage(data) {
8943
- if (Buffer.isBuffer(data)) {
8944
- return data.toString("utf-8");
8945
- }
8946
- if (typeof data === "string") {
8947
- return data;
8948
- }
8949
- 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) {
8950
- const chunks = [];
8951
- for (const chunk of data._readableState.buffer) {
8952
- if (chunk && typeof chunk === "object" && "type" in chunk && chunk.type === "Buffer" && "data" in chunk && Array.isArray(chunk.data)) {
8953
- chunks.push(Buffer.from(chunk.data));
8954
- } else if (Buffer.isBuffer(chunk)) {
8955
- chunks.push(chunk);
8956
- } else if (chunk && typeof chunk === "object" && "data" in chunk) {
8957
- if (Buffer.isBuffer(chunk.data)) {
8958
- chunks.push(chunk.data);
8959
- } else if (Array.isArray(chunk.data)) {
8960
- chunks.push(Buffer.from(chunk.data));
8961
- }
8962
- }
8963
- }
8964
- if (chunks.length > 0) {
8965
- return Buffer.concat(chunks).toString("utf-8");
8966
- }
8967
- }
8968
- return this.safeStringify(data);
8969
- }
8970
- /**
8971
- * Parse HTML error page to extract error message
8972
- */
8973
- parseHtmlError(html) {
8974
- const titleMatch = html.match(/<title>(.*?)<\/title>/i);
8975
- const h1Match = html.match(/<h1>(.*?)<\/h1>/i);
8976
- const bodyMatch = html.match(/<body[^>]*>(.*?)<\/body>/is);
8977
- if (titleMatch && titleMatch[1] !== "Error") {
8978
- return titleMatch[1].trim();
8979
- }
8980
- if (h1Match) {
8981
- return h1Match[1].trim();
8982
- }
8983
- if (bodyMatch) {
8984
- const text = bodyMatch[1].replace(/<[^>]+>/g, " ").replace(/\s+/g, " ").trim();
8985
- return text.substring(0, 200);
8986
- }
8987
- return null;
8988
- }
8989
- /**
8990
- * Truncate string to max length with ellipsis
8991
- */
8992
- truncate(str, maxLength) {
8993
- if (str.length <= maxLength) {
8994
- return str;
8995
- }
8996
- return str.substring(0, maxLength) + "... [truncated]";
8997
- }
8998
- /**
8999
- * Format bytes to human-readable size
9000
- */
9001
- formatBytes(bytes) {
9002
- if (bytes === 0) return "0 B";
9003
- const k = 1024;
9004
- const sizes = ["B", "KB", "MB", "GB"];
9005
- const i = Math.floor(Math.log(bytes) / Math.log(k));
9006
- return Math.round(bytes / Math.pow(k, i) * 100) / 100 + " " + sizes[i];
9007
- }
9008
- /**
9009
- * Clean up old debug logs (older than 30 days)
9010
- */
9011
- async cleanupOldLogs() {
9012
- if (!this.fileLoggingEnabled) return;
9013
- try {
9014
- const debugDir = path11.join(os.homedir(), ".bike4mind", "debug");
9015
- const files = await fs10.readdir(debugDir);
9016
- const now = Date.now();
9017
- const thirtyDaysAgo = now - 30 * 24 * 60 * 60 * 1e3;
9018
- for (const file of files) {
9019
- const filePath = path11.join(debugDir, file);
9020
- const stats = await fs10.stat(filePath);
9021
- if (stats.mtime.getTime() < thirtyDaysAgo) {
9022
- await fs10.unlink(filePath);
9023
- }
9024
- }
9025
- } catch (error) {
9026
- console.error("Failed to cleanup old logs:", error);
9027
- }
9028
- }
9029
- };
9030
- var logger = Logger2.getInstance();
9031
-
9032
- // src/llm/ServerToolExecutor.ts
9033
- var ServerToolExecutor = class {
9034
- constructor(apiClient) {
9035
- this.toolsEndpoint = "/api/ai/v1/tools";
9036
- this.apiClient = apiClient;
9037
- }
9038
- /**
9039
- * Execute a tool server-side
9040
- *
9041
- * @param toolName - Name of the tool to execute (e.g., 'weather_info', 'web_search')
9042
- * @param input - Tool input parameters
9043
- * @returns Tool execution result (content or error)
9044
- */
9045
- async executeTool(toolName, input) {
9046
- logger.debug(`[ServerToolExecutor] Executing tool: ${toolName}`);
9047
- logger.debug(`[ServerToolExecutor] Endpoint: ${this.toolsEndpoint}`);
9048
- logger.debug(`[ServerToolExecutor] Input: ${JSON.stringify(input)}`);
9049
- try {
9050
- const result = await this.apiClient.post(this.toolsEndpoint, {
9051
- toolName,
9052
- input
9053
- });
9054
- logger.debug(`[ServerToolExecutor] Response: ${JSON.stringify(result)}`);
9055
- if (!result.success) {
9056
- const errorMessage = result.error || "Tool execution failed";
9057
- logger.error(`[ServerToolExecutor] Tool ${toolName} failed: ${errorMessage}`);
9058
- return `Error executing ${toolName}: ${errorMessage}`;
9059
- }
9060
- logger.debug(`[ServerToolExecutor] Tool ${toolName} succeeded in ${result.executionTimeMs}ms`);
9061
- return result.content || "";
9062
- } catch (error) {
9063
- const err = error;
9064
- const errorMessage = err?.response?.data?.error || err?.message || "Unknown error";
9065
- const status = err?.response?.status || "unknown";
9066
- logger.error(`[ServerToolExecutor] Request failed for ${toolName}: ${errorMessage} (status: ${status})`);
9067
- logger.error(`[ServerToolExecutor] Full error: ${JSON.stringify(err, null, 2)}`);
9068
- return `Error executing ${toolName}: ${errorMessage}`;
9069
- }
9070
- }
9071
- };
9072
-
9073
- // src/llm/ToolRouter.ts
9074
- var SERVER_TOOLS = ["weather_info", "web_search"];
9075
- var LOCAL_TOOLS = [
9076
- "file_read",
9077
- "create_file",
9078
- "glob_files",
9079
- "grep_search",
9080
- "delete_file",
9081
- "edit_file",
9082
- "dice_roll",
9083
- "math_evaluate",
9084
- "current_datetime"
9085
- ];
9086
- function isServerTool(toolName) {
9087
- return SERVER_TOOLS.includes(toolName);
9088
- }
9089
- function isLocalTool(toolName) {
9090
- return LOCAL_TOOLS.includes(toolName);
9091
- }
9092
- async function executeTool(toolName, input, apiClient, localToolFn) {
9093
- if (isServerTool(toolName)) {
9094
- logger.debug(`[ToolRouter] Routing ${toolName} to server`);
9095
- const executor = new ServerToolExecutor(apiClient);
9096
- return await executor.executeTool(toolName, input);
9097
- } else if (isLocalTool(toolName)) {
9098
- logger.debug(`[ToolRouter] Executing ${toolName} locally`);
9099
- if (!localToolFn) {
9100
- throw new Error(`Local tool ${toolName} has no implementation`);
9101
- }
9102
- const result = await localToolFn(input);
9103
- return typeof result === "string" ? result : JSON.stringify(result);
9104
- } else {
9105
- throw new Error(`Unknown tool: ${toolName}`);
9106
- }
9107
- }
9108
-
9109
8766
  // src/utils/toolsAdapter.ts
9110
8767
  var NoOpStorage = class extends BaseStorage {
9111
8768
  async upload(input, destination, options) {
@@ -9145,14 +8802,14 @@ var CliLogger = class extends Logger {
9145
8802
  log(...args) {
9146
8803
  }
9147
8804
  };
9148
- function wrapToolWithPermission(tool, permissionManager, showPermissionPrompt, agentContext, configStore, apiClient) {
8805
+ function wrapToolWithPermission(tool, permissionManager, showPermissionPrompt, agentContext, configStore) {
9149
8806
  const originalFn = tool.toolFn;
9150
8807
  const toolName = tool.toolSchema.name;
9151
8808
  return {
9152
8809
  ...tool,
9153
8810
  toolFn: async (args) => {
9154
8811
  if (!permissionManager.needsPermission(toolName)) {
9155
- const result2 = await executeTool(toolName, args, apiClient, originalFn);
8812
+ const result2 = await originalFn(args);
9156
8813
  agentContext.observationQueue.push({ toolName, result: result2 });
9157
8814
  return result2;
9158
8815
  }
@@ -9209,13 +8866,13 @@ function wrapToolWithPermission(tool, permissionManager, showPermissionPrompt, a
9209
8866
  }
9210
8867
  }
9211
8868
  }
9212
- const result = await executeTool(toolName, args, apiClient, originalFn);
8869
+ const result = await originalFn(args);
9213
8870
  agentContext.observationQueue.push({ toolName, result });
9214
8871
  return result;
9215
8872
  }
9216
8873
  };
9217
8874
  }
9218
- function generateCliTools(userId, llm, model, permissionManager, showPermissionPrompt, agentContext, configStore, apiClient) {
8875
+ function generateCliTools(userId, llm, model, permissionManager, showPermissionPrompt, agentContext, configStore, toolApiKeys) {
9219
8876
  const logger2 = new CliLogger();
9220
8877
  const storage = new NoOpStorage();
9221
8878
  const user = {
@@ -9232,6 +8889,18 @@ function generateCliTools(userId, llm, model, permissionManager, showPermissionP
9232
8889
  };
9233
8890
  const mockAdminSettings = {
9234
8891
  findBySettingName: async (settingName) => {
8892
+ if (settingName === "OpenWeatherKey") {
8893
+ const key = toolApiKeys?.openweather || process.env.OPENWEATHER_API_KEY;
8894
+ if (key) {
8895
+ return { settingValue: key };
8896
+ }
8897
+ }
8898
+ if (settingName === "SerperKey") {
8899
+ const key = toolApiKeys?.serper || process.env.SERPER_API_KEY;
8900
+ if (key) {
8901
+ return { settingValue: key };
8902
+ }
8903
+ }
9235
8904
  return null;
9236
8905
  }
9237
8906
  };
@@ -9241,22 +8910,27 @@ function generateCliTools(userId, llm, model, permissionManager, showPermissionP
9241
8910
  adminSettings: mockAdminSettings
9242
8911
  }
9243
8912
  };
8913
+ const hasSerperKey = !!(toolApiKeys?.serper || process.env.SERPER_API_KEY);
8914
+ const hasOpenWeatherKey = !!(toolApiKeys?.openweather || process.env.OPENWEATHER_API_KEY);
9244
8915
  const toolConfig = {
9245
- // Local-only tools (no external API keys needed)
8916
+ // Enable these tools for CLI (no external API keys needed)
9246
8917
  dice_roll: {},
9247
8918
  math_evaluate: {},
9248
8919
  current_datetime: {},
9249
8920
  prompt_enhancement: {},
9250
- // File operation tools (CLI-specific, local execution)
8921
+ // File operation tools (CLI-specific)
9251
8922
  file_read: {},
9252
8923
  create_file: {},
9253
8924
  glob_files: {},
9254
8925
  grep_search: {},
9255
8926
  delete_file: {},
9256
- // Server-side tools (executed via /api/ai/v1/tools Lambda)
9257
- // Routed by ToolRouter to use B4M company API keys
9258
- weather_info: {},
9259
- web_search: {}
8927
+ // Tools requiring API keys (only include if API key is available)
8928
+ ...hasSerperKey && { web_search: {} },
8929
+ // Requires SERPER_API_KEY
8930
+ ...hasOpenWeatherKey && { weather_info: {} },
8931
+ // Requires OPENWEATHER_API_KEY
8932
+ ...hasSerperKey && { deep_research: {} }
8933
+ // Requires SERPER_API_KEY
9260
8934
  // Disable web-only tools
9261
8935
  // blog_publish: undefined,
9262
8936
  // blog_edit: undefined,
@@ -9266,7 +8940,6 @@ function generateCliTools(userId, llm, model, permissionManager, showPermissionP
9266
8940
  // mermaid_chart: undefined,
9267
8941
  // recharts: undefined,
9268
8942
  // edit_file: undefined,
9269
- // deep_research: undefined,
9270
8943
  };
9271
8944
  const toolsMap = generateTools(
9272
8945
  userId,
@@ -9284,7 +8957,7 @@ function generateCliTools(userId, llm, model, permissionManager, showPermissionP
9284
8957
  model
9285
8958
  );
9286
8959
  const tools2 = Object.entries(toolsMap).filter(([key]) => toolConfig[key] !== void 0).map(
9287
- ([_, tool]) => wrapToolWithPermission(tool, permissionManager, showPermissionPrompt, agentContext, configStore, apiClient)
8960
+ ([_, tool]) => wrapToolWithPermission(tool, permissionManager, showPermissionPrompt, agentContext, configStore)
9288
8961
  );
9289
8962
  return { tools: tools2, agentContext };
9290
8963
  }
@@ -9479,6 +9152,261 @@ function getEnvironmentName(configApiConfig) {
9479
9152
  return "Bike4Mind";
9480
9153
  }
9481
9154
 
9155
+ // src/utils/Logger.ts
9156
+ import fs10 from "fs/promises";
9157
+ import path11 from "path";
9158
+ import os from "os";
9159
+ var Logger2 = class _Logger {
9160
+ constructor() {
9161
+ this.logFilePath = null;
9162
+ this.sessionId = null;
9163
+ this.fileLoggingEnabled = true;
9164
+ this.consoleVerbose = false;
9165
+ }
9166
+ static {
9167
+ this.instance = null;
9168
+ }
9169
+ static getInstance() {
9170
+ if (!_Logger.instance) {
9171
+ _Logger.instance = new _Logger();
9172
+ }
9173
+ return _Logger.instance;
9174
+ }
9175
+ /**
9176
+ * Initialize the logger with a session ID
9177
+ */
9178
+ async initialize(sessionId) {
9179
+ this.sessionId = sessionId;
9180
+ const debugDir = path11.join(os.homedir(), ".bike4mind", "debug");
9181
+ await fs10.mkdir(debugDir, { recursive: true });
9182
+ this.logFilePath = path11.join(debugDir, `${sessionId}.txt`);
9183
+ await this.writeToFile("INFO", "=== CLI SESSION START ===");
9184
+ }
9185
+ /**
9186
+ * Set whether verbose console logging is enabled
9187
+ */
9188
+ setVerbose(enabled) {
9189
+ this.consoleVerbose = enabled;
9190
+ }
9191
+ /**
9192
+ * Set whether file logging is enabled
9193
+ */
9194
+ setFileLoggingEnabled(enabled) {
9195
+ this.fileLoggingEnabled = enabled;
9196
+ }
9197
+ /**
9198
+ * DEBUG level - verbose-only console, always file
9199
+ */
9200
+ debug(message) {
9201
+ this.writeToFile("DEBUG", message).catch(() => {
9202
+ });
9203
+ if (this.consoleVerbose) {
9204
+ console.log(message);
9205
+ }
9206
+ }
9207
+ /**
9208
+ * INFO level - always shown to user
9209
+ */
9210
+ info(message) {
9211
+ this.writeToFile("INFO", message).catch(() => {
9212
+ });
9213
+ console.log(message);
9214
+ }
9215
+ /**
9216
+ * WARN level - always shown to user
9217
+ */
9218
+ warn(message) {
9219
+ this.writeToFile("WARN", message).catch(() => {
9220
+ });
9221
+ console.warn(message);
9222
+ }
9223
+ /**
9224
+ * ERROR level - always shown to user
9225
+ */
9226
+ error(message, err) {
9227
+ this.writeToFile("ERROR", message).catch(() => {
9228
+ });
9229
+ if (err) {
9230
+ this.logErrorDetailsToFile(err).catch(() => {
9231
+ });
9232
+ }
9233
+ console.error(message);
9234
+ }
9235
+ /**
9236
+ * Write log entry to file
9237
+ */
9238
+ async writeToFile(level, message) {
9239
+ if (!this.fileLoggingEnabled || !this.logFilePath) {
9240
+ return;
9241
+ }
9242
+ try {
9243
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").substring(0, 19);
9244
+ const logEntry = `[${timestamp}] [${level}] ${message}
9245
+ `;
9246
+ await fs10.appendFile(this.logFilePath, logEntry, "utf-8");
9247
+ } catch (error) {
9248
+ console.error("File logging failed:", error);
9249
+ }
9250
+ }
9251
+ /**
9252
+ * Log error details to file
9253
+ */
9254
+ async logErrorDetailsToFile(err) {
9255
+ if (!this.fileLoggingEnabled || !this.logFilePath) {
9256
+ return;
9257
+ }
9258
+ try {
9259
+ if (err && typeof err === "object" && "response" in err && err.response) {
9260
+ const response = err.response;
9261
+ const config = err && typeof err === "object" && "config" in err ? err.config : void 0;
9262
+ await this.writeToFile("ERROR", ` Status: ${response.status} ${response.statusText || ""}`);
9263
+ await this.writeToFile("ERROR", ` URL: ${config?.url || "unknown"}`);
9264
+ await this.writeToFile("ERROR", ` Headers: ${this.safeStringify(response.headers)}`);
9265
+ if (response.data) {
9266
+ const errorText = this.extractErrorMessage(response.data);
9267
+ if (errorText.trim().startsWith("<!DOCTYPE") || errorText.trim().startsWith("<html")) {
9268
+ await this.writeToFile("ERROR", ` Response Type: HTML Error Page`);
9269
+ const parsedError = this.parseHtmlError(errorText);
9270
+ if (parsedError) {
9271
+ await this.writeToFile("ERROR", ` Error Message: ${parsedError}`);
9272
+ }
9273
+ await this.writeToFile("ERROR", ` Raw HTML: ${this.truncate(errorText, 1e3)}`);
9274
+ } else {
9275
+ const preview = this.truncate(errorText, 500);
9276
+ await this.writeToFile("ERROR", ` Response: ${preview}`);
9277
+ }
9278
+ } else {
9279
+ await this.writeToFile("ERROR", ` Response: (no data)`);
9280
+ }
9281
+ }
9282
+ if (err && typeof err === "object" && "stack" in err && typeof err.stack === "string") {
9283
+ const stackLines = err.stack.split("\n").slice(0, 5).join("\n ");
9284
+ await this.writeToFile("ERROR", ` Stack: ${stackLines}`);
9285
+ } else if (err && typeof err === "object" && "message" in err && typeof err.message === "string") {
9286
+ await this.writeToFile("ERROR", ` Message: ${err.message}`);
9287
+ }
9288
+ } catch (error) {
9289
+ }
9290
+ }
9291
+ /**
9292
+ * Safely stringify object, handling circular references
9293
+ */
9294
+ safeStringify(obj) {
9295
+ try {
9296
+ return JSON.stringify(obj);
9297
+ } catch (error) {
9298
+ if (error instanceof Error && error.message.includes("circular")) {
9299
+ try {
9300
+ const seen = /* @__PURE__ */ new WeakSet();
9301
+ return JSON.stringify(obj, (key, value) => {
9302
+ if (typeof value === "object" && value !== null) {
9303
+ if (seen.has(value)) {
9304
+ return "[Circular]";
9305
+ }
9306
+ seen.add(value);
9307
+ }
9308
+ return value;
9309
+ });
9310
+ } catch {
9311
+ return "[Unable to stringify]";
9312
+ }
9313
+ }
9314
+ return "[Stringify error]";
9315
+ }
9316
+ }
9317
+ /**
9318
+ * Extract readable text from error response data
9319
+ */
9320
+ extractErrorMessage(data) {
9321
+ if (Buffer.isBuffer(data)) {
9322
+ return data.toString("utf-8");
9323
+ }
9324
+ if (typeof data === "string") {
9325
+ return data;
9326
+ }
9327
+ 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) {
9328
+ const chunks = [];
9329
+ for (const chunk of data._readableState.buffer) {
9330
+ if (chunk && typeof chunk === "object" && "type" in chunk && chunk.type === "Buffer" && "data" in chunk && Array.isArray(chunk.data)) {
9331
+ chunks.push(Buffer.from(chunk.data));
9332
+ } else if (Buffer.isBuffer(chunk)) {
9333
+ chunks.push(chunk);
9334
+ } else if (chunk && typeof chunk === "object" && "data" in chunk) {
9335
+ if (Buffer.isBuffer(chunk.data)) {
9336
+ chunks.push(chunk.data);
9337
+ } else if (Array.isArray(chunk.data)) {
9338
+ chunks.push(Buffer.from(chunk.data));
9339
+ }
9340
+ }
9341
+ }
9342
+ if (chunks.length > 0) {
9343
+ return Buffer.concat(chunks).toString("utf-8");
9344
+ }
9345
+ }
9346
+ return this.safeStringify(data);
9347
+ }
9348
+ /**
9349
+ * Parse HTML error page to extract error message
9350
+ */
9351
+ parseHtmlError(html) {
9352
+ const titleMatch = html.match(/<title>(.*?)<\/title>/i);
9353
+ const h1Match = html.match(/<h1>(.*?)<\/h1>/i);
9354
+ const bodyMatch = html.match(/<body[^>]*>(.*?)<\/body>/is);
9355
+ if (titleMatch && titleMatch[1] !== "Error") {
9356
+ return titleMatch[1].trim();
9357
+ }
9358
+ if (h1Match) {
9359
+ return h1Match[1].trim();
9360
+ }
9361
+ if (bodyMatch) {
9362
+ const text = bodyMatch[1].replace(/<[^>]+>/g, " ").replace(/\s+/g, " ").trim();
9363
+ return text.substring(0, 200);
9364
+ }
9365
+ return null;
9366
+ }
9367
+ /**
9368
+ * Truncate string to max length with ellipsis
9369
+ */
9370
+ truncate(str, maxLength) {
9371
+ if (str.length <= maxLength) {
9372
+ return str;
9373
+ }
9374
+ return str.substring(0, maxLength) + "... [truncated]";
9375
+ }
9376
+ /**
9377
+ * Format bytes to human-readable size
9378
+ */
9379
+ formatBytes(bytes) {
9380
+ if (bytes === 0) return "0 B";
9381
+ const k = 1024;
9382
+ const sizes = ["B", "KB", "MB", "GB"];
9383
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
9384
+ return Math.round(bytes / Math.pow(k, i) * 100) / 100 + " " + sizes[i];
9385
+ }
9386
+ /**
9387
+ * Clean up old debug logs (older than 30 days)
9388
+ */
9389
+ async cleanupOldLogs() {
9390
+ if (!this.fileLoggingEnabled) return;
9391
+ try {
9392
+ const debugDir = path11.join(os.homedir(), ".bike4mind", "debug");
9393
+ const files = await fs10.readdir(debugDir);
9394
+ const now = Date.now();
9395
+ const thirtyDaysAgo = now - 30 * 24 * 60 * 60 * 1e3;
9396
+ for (const file of files) {
9397
+ const filePath = path11.join(debugDir, file);
9398
+ const stats = await fs10.stat(filePath);
9399
+ if (stats.mtime.getTime() < thirtyDaysAgo) {
9400
+ await fs10.unlink(filePath);
9401
+ }
9402
+ }
9403
+ } catch (error) {
9404
+ console.error("Failed to cleanup old logs:", error);
9405
+ }
9406
+ }
9407
+ };
9408
+ var logger = Logger2.getInstance();
9409
+
9482
9410
  // ../../b4m-core/packages/mcp/dist/src/client.js
9483
9411
  import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
9484
9412
  import { Client as Client2 } from "@modelcontextprotocol/sdk/client/index.js";
@@ -10282,10 +10210,7 @@ var ApiClient = class {
10282
10210
  * Make a POST request
10283
10211
  */
10284
10212
  async post(url, data, config) {
10285
- logger.debug(`[ApiClient] POST ${this.client.defaults.baseURL}${url}`);
10286
- logger.debug(`[ApiClient] Request body: ${JSON.stringify(data)}`);
10287
10213
  const response = await this.client.post(url, data, config);
10288
- logger.debug(`[ApiClient] Response status: ${response.status}`);
10289
10214
  return response.data;
10290
10215
  }
10291
10216
  /**
@@ -10336,7 +10261,7 @@ import { isAxiosError as isAxiosError2 } from "axios";
10336
10261
  // package.json
10337
10262
  var package_default = {
10338
10263
  name: "@bike4mind/cli",
10339
- version: "0.2.7-feat-cli-tool-lambda-v2.17131+a38465a4f",
10264
+ version: "0.2.7-feat-organization-overview-enhancements.17130+2e676f9be",
10340
10265
  type: "module",
10341
10266
  description: "Interactive CLI tool for Bike4Mind with ReAct agents",
10342
10267
  license: "UNLICENSED",
@@ -10439,11 +10364,11 @@ var package_default = {
10439
10364
  },
10440
10365
  devDependencies: {
10441
10366
  "@bike4mind/agents": "0.1.0",
10442
- "@bike4mind/common": "2.38.1-feat-cli-tool-lambda-v2.17131+a38465a4f",
10443
- "@bike4mind/mcp": "1.20.1-feat-cli-tool-lambda-v2.17131+a38465a4f",
10444
- "@bike4mind/services": "2.33.1-feat-cli-tool-lambda-v2.17131+a38465a4f",
10445
- "@bike4mind/utils": "2.1.2-feat-cli-tool-lambda-v2.17131+a38465a4f",
10446
- "@types/better-sqlite3": "^7.6.12",
10367
+ "@bike4mind/common": "2.38.1-feat-organization-overview-enhancements.17130+2e676f9be",
10368
+ "@bike4mind/mcp": "1.20.1-feat-organization-overview-enhancements.17130+2e676f9be",
10369
+ "@bike4mind/services": "2.33.1-feat-organization-overview-enhancements.17130+2e676f9be",
10370
+ "@bike4mind/utils": "2.1.2-feat-organization-overview-enhancements.17130+2e676f9be",
10371
+ "@types/better-sqlite3": "^7.6.13",
10447
10372
  "@types/diff": "^5.0.9",
10448
10373
  "@types/jsonwebtoken": "^9.0.4",
10449
10374
  "@types/node": "^22.9.0",
@@ -10455,7 +10380,7 @@ var package_default = {
10455
10380
  typescript: "^5.9.3",
10456
10381
  vitest: "^3.2.4"
10457
10382
  },
10458
- gitHead: "a38465a4f20beebef3d8bab525586f0826eaa06b"
10383
+ gitHead: "2e676f9bedcd3876486314a5bcade6acc1491e3f"
10459
10384
  };
10460
10385
 
10461
10386
  // src/config/constants.ts
@@ -10679,6 +10604,10 @@ function CliApp() {
10679
10604
  setPermissionPrompt(prompt);
10680
10605
  });
10681
10606
  };
10607
+ console.log("\u{1F511} Tool API Keys:", {
10608
+ openweather: config.toolApiKeys?.openweather ? "\u2713 configured" : "\u2717 missing",
10609
+ serper: config.toolApiKeys?.serper ? "\u2713 configured" : "\u2717 missing"
10610
+ });
10682
10611
  const agentContext = {
10683
10612
  currentAgent: null,
10684
10613
  observationQueue: []
@@ -10691,7 +10620,7 @@ function CliApp() {
10691
10620
  promptFn,
10692
10621
  agentContext,
10693
10622
  state.configStore,
10694
- apiClient
10623
+ config.toolApiKeys
10695
10624
  );
10696
10625
  console.log(`\u{1F6E0}\uFE0F Loaded ${b4mTools.length} B4M tool(s)`);
10697
10626
  const mcpManager = new McpManager(config);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bike4mind/cli",
3
- "version": "0.2.7-feat-cli-tool-lambda-v2.17131+a38465a4f",
3
+ "version": "0.2.7-feat-organization-overview-enhancements.17130+2e676f9be",
4
4
  "type": "module",
5
5
  "description": "Interactive CLI tool for Bike4Mind with ReAct agents",
6
6
  "license": "UNLICENSED",
@@ -103,11 +103,11 @@
103
103
  },
104
104
  "devDependencies": {
105
105
  "@bike4mind/agents": "0.1.0",
106
- "@bike4mind/common": "2.38.1-feat-cli-tool-lambda-v2.17131+a38465a4f",
107
- "@bike4mind/mcp": "1.20.1-feat-cli-tool-lambda-v2.17131+a38465a4f",
108
- "@bike4mind/services": "2.33.1-feat-cli-tool-lambda-v2.17131+a38465a4f",
109
- "@bike4mind/utils": "2.1.2-feat-cli-tool-lambda-v2.17131+a38465a4f",
110
- "@types/better-sqlite3": "^7.6.12",
106
+ "@bike4mind/common": "2.38.1-feat-organization-overview-enhancements.17130+2e676f9be",
107
+ "@bike4mind/mcp": "1.20.1-feat-organization-overview-enhancements.17130+2e676f9be",
108
+ "@bike4mind/services": "2.33.1-feat-organization-overview-enhancements.17130+2e676f9be",
109
+ "@bike4mind/utils": "2.1.2-feat-organization-overview-enhancements.17130+2e676f9be",
110
+ "@types/better-sqlite3": "^7.6.13",
111
111
  "@types/diff": "^5.0.9",
112
112
  "@types/jsonwebtoken": "^9.0.4",
113
113
  "@types/node": "^22.9.0",
@@ -119,5 +119,5 @@
119
119
  "typescript": "^5.9.3",
120
120
  "vitest": "^3.2.4"
121
121
  },
122
- "gitHead": "a38465a4f20beebef3d8bab525586f0826eaa06b"
122
+ "gitHead": "2e676f9bedcd3876486314a5bcade6acc1491e3f"
123
123
  }