@probelabs/probe 0.6.0-rc207 → 0.6.0-rc209

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 (33) hide show
  1. package/bin/binaries/probe-v0.6.0-rc209-aarch64-apple-darwin.tar.gz +0 -0
  2. package/bin/binaries/probe-v0.6.0-rc209-aarch64-unknown-linux-musl.tar.gz +0 -0
  3. package/bin/binaries/probe-v0.6.0-rc209-x86_64-apple-darwin.tar.gz +0 -0
  4. package/bin/binaries/probe-v0.6.0-rc209-x86_64-pc-windows-msvc.zip +0 -0
  5. package/bin/binaries/probe-v0.6.0-rc209-x86_64-unknown-linux-musl.tar.gz +0 -0
  6. package/build/agent/ProbeAgent.d.ts +4 -2
  7. package/build/agent/ProbeAgent.js +2 -1
  8. package/build/agent/bashPermissions.js +88 -7
  9. package/build/agent/index.js +342 -24
  10. package/build/agent/mcp/client.js +236 -5
  11. package/build/agent/mcp/config.js +87 -0
  12. package/build/agent/mcp/xmlBridge.js +15 -5
  13. package/build/agent/simpleTelemetry.js +26 -0
  14. package/build/tools/bash.js +5 -3
  15. package/cjs/agent/ProbeAgent.cjs +314 -18
  16. package/cjs/agent/simpleTelemetry.cjs +22 -0
  17. package/cjs/index.cjs +336 -18
  18. package/index.d.ts +4 -2
  19. package/package.json +1 -1
  20. package/src/agent/ProbeAgent.d.ts +4 -2
  21. package/src/agent/ProbeAgent.js +2 -1
  22. package/src/agent/bashPermissions.js +88 -7
  23. package/src/agent/index.js +5 -5
  24. package/src/agent/mcp/client.js +236 -5
  25. package/src/agent/mcp/config.js +87 -0
  26. package/src/agent/mcp/xmlBridge.js +15 -5
  27. package/src/agent/simpleTelemetry.js +26 -0
  28. package/src/tools/bash.js +5 -3
  29. package/bin/binaries/probe-v0.6.0-rc207-aarch64-apple-darwin.tar.gz +0 -0
  30. package/bin/binaries/probe-v0.6.0-rc207-aarch64-unknown-linux-musl.tar.gz +0 -0
  31. package/bin/binaries/probe-v0.6.0-rc207-x86_64-apple-darwin.tar.gz +0 -0
  32. package/bin/binaries/probe-v0.6.0-rc207-x86_64-pc-windows-msvc.zip +0 -0
  33. package/bin/binaries/probe-v0.6.0-rc207-x86_64-unknown-linux-musl.tar.gz +0 -0
package/cjs/index.cjs CHANGED
@@ -82300,6 +82300,47 @@ function validateTimeout(value) {
82300
82300
  if (!Number.isFinite(num) || num < 0) return void 0;
82301
82301
  return Math.min(num, MAX_TIMEOUT);
82302
82302
  }
82303
+ function validateMethodFilter(serverConfig, serverName = "unknown") {
82304
+ const result = { allowedMethods: null, blockedMethods: null };
82305
+ const debug = process.env.DEBUG === "1" || process.env.DEBUG_MCP === "1";
82306
+ if (serverConfig.allowedMethods && serverConfig.blockedMethods) {
82307
+ console.error(`[MCP WARN] Server '${serverName}' has both allowedMethods and blockedMethods - using allowedMethods only`);
82308
+ }
82309
+ if (serverConfig.allowedMethods) {
82310
+ if (!Array.isArray(serverConfig.allowedMethods)) {
82311
+ console.error(`[MCP WARN] Server '${serverName}' allowedMethods must be an array, ignoring`);
82312
+ } else {
82313
+ const validMethods = serverConfig.allowedMethods.filter((m4) => typeof m4 === "string" && m4.length > 0);
82314
+ if (validMethods.length !== serverConfig.allowedMethods.length) {
82315
+ console.error(`[MCP WARN] Server '${serverName}' allowedMethods contains non-string values, skipping those`);
82316
+ }
82317
+ if (validMethods.length > 0) {
82318
+ result.allowedMethods = validMethods;
82319
+ if (debug) {
82320
+ console.error(`[MCP DEBUG] Server '${serverName}' allowedMethods: ${validMethods.join(", ")}`);
82321
+ }
82322
+ }
82323
+ }
82324
+ return result;
82325
+ }
82326
+ if (serverConfig.blockedMethods) {
82327
+ if (!Array.isArray(serverConfig.blockedMethods)) {
82328
+ console.error(`[MCP WARN] Server '${serverName}' blockedMethods must be an array, ignoring`);
82329
+ } else {
82330
+ const validMethods = serverConfig.blockedMethods.filter((m4) => typeof m4 === "string" && m4.length > 0);
82331
+ if (validMethods.length !== serverConfig.blockedMethods.length) {
82332
+ console.error(`[MCP WARN] Server '${serverName}' blockedMethods contains non-string values, skipping those`);
82333
+ }
82334
+ if (validMethods.length > 0) {
82335
+ result.blockedMethods = validMethods;
82336
+ if (debug) {
82337
+ console.error(`[MCP DEBUG] Server '${serverName}' blockedMethods: ${validMethods.join(", ")}`);
82338
+ }
82339
+ }
82340
+ }
82341
+ }
82342
+ return result;
82343
+ }
82303
82344
  function loadMCPConfigurationFromPath(configPath) {
82304
82345
  if (!configPath) {
82305
82346
  throw new Error("Config path is required");
@@ -82393,6 +82434,12 @@ function mergeWithEnvironment(config) {
82393
82434
  console.error(`[MCP WARN] Invalid timeout value for ${normalizedName}: ${value}`);
82394
82435
  }
82395
82436
  break;
82437
+ case "ALLOWLIST":
82438
+ config.mcpServers[normalizedName].allowedMethods = value.split(",").map((m4) => m4.trim()).filter(Boolean);
82439
+ break;
82440
+ case "BLOCKLIST":
82441
+ config.mcpServers[normalizedName].blockedMethods = value.split(",").map((m4) => m4.trim()).filter(Boolean);
82442
+ break;
82396
82443
  }
82397
82444
  }
82398
82445
  }
@@ -82443,6 +82490,9 @@ function parseEnabledServers(config) {
82443
82490
  }
82444
82491
  server.timeout = validatedTimeout;
82445
82492
  }
82493
+ const methodFilter = validateMethodFilter(serverConfig, name14);
82494
+ server.allowedMethods = methodFilter.allowedMethods;
82495
+ server.blockedMethods = methodFilter.blockedMethods;
82446
82496
  servers.push(server);
82447
82497
  }
82448
82498
  return servers;
@@ -82480,6 +82530,22 @@ var init_config = __esm({
82480
82530
  });
82481
82531
 
82482
82532
  // src/agent/mcp/client.js
82533
+ function isMethodAllowed(methodName, allowedMethods, blockedMethods) {
82534
+ const matchesPattern2 = (name14, pattern) => {
82535
+ if (!pattern.includes("*")) {
82536
+ return name14 === pattern;
82537
+ }
82538
+ const regexPattern = pattern.replace(/[.+?^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*");
82539
+ return new RegExp(`^${regexPattern}$`).test(name14);
82540
+ };
82541
+ if (allowedMethods && allowedMethods.length > 0) {
82542
+ return allowedMethods.some((pattern) => matchesPattern2(methodName, pattern));
82543
+ }
82544
+ if (blockedMethods && blockedMethods.length > 0) {
82545
+ return !blockedMethods.some((pattern) => matchesPattern2(methodName, pattern));
82546
+ }
82547
+ return true;
82548
+ }
82483
82549
  function createTransport(serverConfig) {
82484
82550
  const { transport, command, args, url, env } = serverConfig;
82485
82551
  switch (transport) {
@@ -82564,6 +82630,17 @@ var init_client2 = __esm({
82564
82630
  this.tools = /* @__PURE__ */ new Map();
82565
82631
  this.debug = options.debug || process.env.DEBUG_MCP === "1";
82566
82632
  this.config = null;
82633
+ this.tracer = options.tracer || null;
82634
+ }
82635
+ /**
82636
+ * Record an MCP telemetry event if tracer is available
82637
+ * @param {string} eventType - Event type (e.g., 'server.connect', 'tool.discovered')
82638
+ * @param {Object} data - Event data
82639
+ */
82640
+ recordMcpEvent(eventType, data2 = {}) {
82641
+ if (this.tracer && typeof this.tracer.recordMcpEvent === "function") {
82642
+ this.tracer.recordMcpEvent(eventType, data2);
82643
+ }
82567
82644
  }
82568
82645
  /**
82569
82646
  * Initialize MCP clients from configuration
@@ -82572,10 +82649,20 @@ var init_client2 = __esm({
82572
82649
  async initialize(config = null) {
82573
82650
  this.config = config || loadMCPConfiguration();
82574
82651
  const servers = parseEnabledServers(this.config);
82652
+ this.recordMcpEvent("initialization.started", {
82653
+ serverCount: servers.length,
82654
+ serverNames: servers.map((s4) => s4.name)
82655
+ });
82575
82656
  console.error(`[MCP INFO] Found ${servers.length} enabled MCP server${servers.length !== 1 ? "s" : ""}`);
82576
82657
  if (servers.length === 0) {
82577
82658
  console.error("[MCP INFO] No MCP servers configured or enabled");
82578
82659
  console.error("[MCP INFO] 0 MCP tools available");
82660
+ this.recordMcpEvent("initialization.completed", {
82661
+ connected: 0,
82662
+ total: 0,
82663
+ toolCount: 0,
82664
+ tools: []
82665
+ });
82579
82666
  return {
82580
82667
  connected: 0,
82581
82668
  total: 0,
@@ -82612,10 +82699,17 @@ var init_client2 = __esm({
82612
82699
  console.error(`[MCP DEBUG] - ${toolName}`);
82613
82700
  });
82614
82701
  }
82702
+ const toolNames = Array.from(this.tools.keys());
82703
+ this.recordMcpEvent("initialization.completed", {
82704
+ connected: connectedCount,
82705
+ total: servers.length,
82706
+ toolCount: this.tools.size,
82707
+ tools: toolNames
82708
+ });
82615
82709
  return {
82616
82710
  connected: connectedCount,
82617
82711
  total: servers.length,
82618
- tools: Array.from(this.tools.keys())
82712
+ tools: toolNames
82619
82713
  };
82620
82714
  }
82621
82715
  /**
@@ -82624,6 +82718,12 @@ var init_client2 = __esm({
82624
82718
  */
82625
82719
  async connectToServer(serverConfig) {
82626
82720
  const { name: name14 } = serverConfig;
82721
+ this.recordMcpEvent("server.connecting", {
82722
+ serverName: name14,
82723
+ transport: serverConfig.transport,
82724
+ hasAllowedMethods: !!(serverConfig.allowedMethods && serverConfig.allowedMethods.length > 0),
82725
+ hasBlockedMethods: !!(serverConfig.blockedMethods && serverConfig.blockedMethods.length > 0)
82726
+ });
82627
82727
  try {
82628
82728
  if (this.debug) {
82629
82729
  console.error(`[MCP DEBUG] Connecting to ${name14} via ${serverConfig.transport}...`);
@@ -82645,27 +82745,92 @@ var init_client2 = __esm({
82645
82745
  config: serverConfig
82646
82746
  });
82647
82747
  const toolsResponse = await client.listTools();
82648
- const toolCount = toolsResponse?.tools?.length || 0;
82748
+ const totalToolCount = toolsResponse?.tools?.length || 0;
82749
+ let registeredCount = 0;
82750
+ let filteredCount = 0;
82751
+ const registeredTools = [];
82752
+ const filteredTools = [];
82649
82753
  if (toolsResponse && toolsResponse.tools) {
82754
+ const { allowedMethods, blockedMethods } = serverConfig;
82755
+ const allToolNames = toolsResponse.tools.map((t4) => t4.name);
82756
+ this.recordMcpEvent("tools.discovered", {
82757
+ serverName: name14,
82758
+ toolCount: totalToolCount,
82759
+ tools: allToolNames
82760
+ });
82650
82761
  for (const tool4 of toolsResponse.tools) {
82762
+ if (!isMethodAllowed(tool4.name, allowedMethods, blockedMethods)) {
82763
+ filteredCount++;
82764
+ filteredTools.push(tool4.name);
82765
+ if (this.debug) {
82766
+ console.error(`[MCP DEBUG] Filtered out tool: ${tool4.name} (not allowed by method filter)`);
82767
+ }
82768
+ continue;
82769
+ }
82651
82770
  const qualifiedName = `${name14}_${tool4.name}`;
82652
82771
  this.tools.set(qualifiedName, {
82653
82772
  ...tool4,
82654
82773
  serverName: name14,
82655
82774
  originalName: tool4.name
82656
82775
  });
82776
+ registeredCount++;
82777
+ registeredTools.push(qualifiedName);
82657
82778
  if (this.debug) {
82658
82779
  console.error(`[MCP DEBUG] Registered tool: ${qualifiedName}`);
82659
82780
  }
82660
82781
  }
82782
+ if (filteredCount > 0) {
82783
+ this.recordMcpEvent("tools.filtered", {
82784
+ serverName: name14,
82785
+ filteredCount,
82786
+ filteredTools,
82787
+ allowedMethods: allowedMethods || [],
82788
+ blockedMethods: blockedMethods || []
82789
+ });
82790
+ }
82791
+ if (allowedMethods && allowedMethods.length > 0) {
82792
+ const unmatchedPatterns = allowedMethods.filter((pattern) => {
82793
+ return !allToolNames.some((toolName) => isMethodAllowed(toolName, [pattern], null));
82794
+ });
82795
+ if (unmatchedPatterns.length > 0) {
82796
+ console.error(`[MCP WARN] Server '${name14}': The following allowedMethods patterns did not match any tools: ${unmatchedPatterns.join(", ")}`);
82797
+ console.error(`[MCP WARN] Available methods from '${name14}': ${allToolNames.join(", ")}`);
82798
+ }
82799
+ }
82800
+ if (blockedMethods && blockedMethods.length > 0) {
82801
+ const unmatchedPatterns = blockedMethods.filter((pattern) => {
82802
+ return !allToolNames.some((toolName) => !isMethodAllowed(toolName, null, [pattern]));
82803
+ });
82804
+ if (unmatchedPatterns.length > 0) {
82805
+ console.error(`[MCP WARN] Server '${name14}': The following blockedMethods patterns did not match any tools: ${unmatchedPatterns.join(", ")}`);
82806
+ console.error(`[MCP WARN] Available methods from '${name14}': ${allToolNames.join(", ")}`);
82807
+ }
82808
+ }
82661
82809
  }
82662
- console.error(`[MCP INFO] Connected to ${name14}: ${toolCount} tool${toolCount !== 1 ? "s" : ""} loaded`);
82810
+ if (filteredCount > 0) {
82811
+ console.error(`[MCP INFO] Connected to ${name14}: ${registeredCount} tool${registeredCount !== 1 ? "s" : ""} loaded (${filteredCount} filtered out)`);
82812
+ } else {
82813
+ console.error(`[MCP INFO] Connected to ${name14}: ${registeredCount} tool${registeredCount !== 1 ? "s" : ""} loaded`);
82814
+ }
82815
+ this.recordMcpEvent("server.connected", {
82816
+ serverName: name14,
82817
+ transport: serverConfig.transport,
82818
+ totalToolCount,
82819
+ registeredCount,
82820
+ filteredCount,
82821
+ registeredTools
82822
+ });
82663
82823
  return true;
82664
82824
  } catch (error2) {
82665
82825
  console.error(`[MCP ERROR] Error connecting to ${name14}:`, error2.message);
82666
82826
  if (this.debug) {
82667
82827
  console.error(`[MCP DEBUG] Full error details:`, error2);
82668
82828
  }
82829
+ this.recordMcpEvent("server.connection_failed", {
82830
+ serverName: name14,
82831
+ transport: serverConfig.transport,
82832
+ error: error2.message
82833
+ });
82669
82834
  return false;
82670
82835
  }
82671
82836
  }
@@ -82677,12 +82842,27 @@ var init_client2 = __esm({
82677
82842
  async callTool(toolName, args) {
82678
82843
  const tool4 = this.tools.get(toolName);
82679
82844
  if (!tool4) {
82845
+ this.recordMcpEvent("tool.call_failed", {
82846
+ toolName,
82847
+ error: "Unknown tool"
82848
+ });
82680
82849
  throw new Error(`Unknown tool: ${toolName}`);
82681
82850
  }
82682
82851
  const clientInfo = this.clients.get(tool4.serverName);
82683
82852
  if (!clientInfo) {
82853
+ this.recordMcpEvent("tool.call_failed", {
82854
+ toolName,
82855
+ serverName: tool4.serverName,
82856
+ error: "Server not connected"
82857
+ });
82684
82858
  throw new Error(`Server ${tool4.serverName} not connected`);
82685
82859
  }
82860
+ const startTime = Date.now();
82861
+ this.recordMcpEvent("tool.call_started", {
82862
+ toolName,
82863
+ serverName: tool4.serverName,
82864
+ originalToolName: tool4.originalName
82865
+ });
82686
82866
  try {
82687
82867
  if (this.debug) {
82688
82868
  console.error(`[MCP DEBUG] Calling ${toolName} with args:`, JSON.stringify(args, null, 2));
@@ -82699,18 +82879,34 @@ var init_client2 = __esm({
82699
82879
  clientInfo.client.callTool({
82700
82880
  name: tool4.originalName,
82701
82881
  arguments: args
82702
- }),
82882
+ }, void 0, { timeout }),
82703
82883
  timeoutPromise
82704
82884
  ]);
82885
+ const durationMs = Date.now() - startTime;
82705
82886
  if (this.debug) {
82706
82887
  console.error(`[MCP DEBUG] Tool ${toolName} executed successfully`);
82707
82888
  }
82889
+ this.recordMcpEvent("tool.call_completed", {
82890
+ toolName,
82891
+ serverName: tool4.serverName,
82892
+ originalToolName: tool4.originalName,
82893
+ durationMs
82894
+ });
82708
82895
  return result;
82709
82896
  } catch (error2) {
82897
+ const durationMs = Date.now() - startTime;
82710
82898
  console.error(`[MCP ERROR] Error calling tool ${toolName}:`, error2.message);
82711
82899
  if (this.debug) {
82712
82900
  console.error(`[MCP DEBUG] Full error details:`, error2);
82713
82901
  }
82902
+ this.recordMcpEvent("tool.call_failed", {
82903
+ toolName,
82904
+ serverName: tool4.serverName,
82905
+ originalToolName: tool4.originalName,
82906
+ error: error2.message,
82907
+ durationMs,
82908
+ isTimeout: error2.message.includes("timeout")
82909
+ });
82714
82910
  throw error2;
82715
82911
  }
82716
82912
  }
@@ -82755,12 +82951,17 @@ var init_client2 = __esm({
82755
82951
  */
82756
82952
  async disconnect() {
82757
82953
  const disconnectPromises = [];
82954
+ const serverNames = Array.from(this.clients.keys());
82758
82955
  if (this.clients.size === 0) {
82759
82956
  if (this.debug) {
82760
82957
  console.error("[MCP DEBUG] No MCP clients to disconnect");
82761
82958
  }
82762
82959
  return;
82763
82960
  }
82961
+ this.recordMcpEvent("disconnection.started", {
82962
+ serverCount: this.clients.size,
82963
+ serverNames
82964
+ });
82764
82965
  if (this.debug) {
82765
82966
  console.error(`[MCP DEBUG] Disconnecting from ${this.clients.size} MCP server${this.clients.size !== 1 ? "s" : ""}...`);
82766
82967
  }
@@ -82770,14 +82971,25 @@ var init_client2 = __esm({
82770
82971
  if (this.debug) {
82771
82972
  console.error(`[MCP DEBUG] Disconnected from ${name14}`);
82772
82973
  }
82974
+ this.recordMcpEvent("server.disconnected", {
82975
+ serverName: name14
82976
+ });
82773
82977
  }).catch((error2) => {
82774
82978
  console.error(`[MCP ERROR] Error disconnecting from ${name14}:`, error2.message);
82979
+ this.recordMcpEvent("server.disconnect_failed", {
82980
+ serverName: name14,
82981
+ error: error2.message
82982
+ });
82775
82983
  })
82776
82984
  );
82777
82985
  }
82778
82986
  await Promise.all(disconnectPromises);
82779
82987
  this.clients.clear();
82780
82988
  this.tools.clear();
82989
+ this.recordMcpEvent("disconnection.completed", {
82990
+ serverCount: serverNames.length,
82991
+ serverNames
82992
+ });
82781
82993
  if (this.debug) {
82782
82994
  console.error("[MCP DEBUG] All MCP connections closed");
82783
82995
  }
@@ -82921,6 +83133,7 @@ var init_xmlBridge = __esm({
82921
83133
  MCPXmlBridge = class {
82922
83134
  constructor(options = {}) {
82923
83135
  this.debug = options.debug || false;
83136
+ this.tracer = options.tracer || null;
82924
83137
  this.mcpTools = {};
82925
83138
  this.mcpManager = null;
82926
83139
  this.xmlDefinitions = {};
@@ -82963,7 +83176,7 @@ var init_xmlBridge = __esm({
82963
83176
  if (this.debug) {
82964
83177
  console.error("[MCP DEBUG] Initializing MCP client manager...");
82965
83178
  }
82966
- this.mcpManager = new MCPClientManager({ debug: this.debug });
83179
+ this.mcpManager = new MCPClientManager({ debug: this.debug, tracer: this.tracer });
82967
83180
  const result = await this.mcpManager.initialize(mcpConfigs);
82968
83181
  const vercelTools = this.mcpManager.getVercelTools();
82969
83182
  this.mcpTools = vercelTools;
@@ -82987,11 +83200,15 @@ var init_xmlBridge = __esm({
82987
83200
  }
82988
83201
  }
82989
83202
  /**
82990
- * Get all XML tool definitions for inclusion in system prompt
83203
+ * Get XML tool definitions for inclusion in system prompt
83204
+ * @param {Array<string>|null} filterToolNames - Optional list of tool names to include (if null, include all)
82991
83205
  * @returns {string} Combined XML tool definitions
82992
83206
  */
82993
- getXmlToolDefinitions() {
82994
- return Object.values(this.xmlDefinitions).join("\n\n");
83207
+ getXmlToolDefinitions(filterToolNames = null) {
83208
+ if (filterToolNames === null) {
83209
+ return Object.values(this.xmlDefinitions).join("\n\n");
83210
+ }
83211
+ return Object.entries(this.xmlDefinitions).filter(([name14]) => filterToolNames.includes(name14)).map(([, def]) => def).join("\n\n");
82995
83212
  }
82996
83213
  /**
82997
83214
  * Get list of MCP tool names
@@ -93216,7 +93433,7 @@ var init_ProbeAgent = __esm({
93216
93433
  this.maxIterations = options.maxIterations || null;
93217
93434
  this.disableMermaidValidation = !!options.disableMermaidValidation;
93218
93435
  this.disableJsonValidation = !!options.disableJsonValidation;
93219
- this.enableSkills = options.disableSkills ? false : options.enableSkills !== void 0 ? !!options.enableSkills : true;
93436
+ this.enableSkills = options.disableSkills ? false : !!(options.allowSkills || options.enableSkills);
93220
93437
  if (Array.isArray(options.skillDirs)) {
93221
93438
  this.skillDirs = options.skillDirs;
93222
93439
  } else if (typeof options.skillDirs === "string") {
@@ -97864,9 +98081,11 @@ var init_bashPermissions = __esm({
97864
98081
  * @param {boolean} [config.disableDefaultAllow] - Disable default allow list
97865
98082
  * @param {boolean} [config.disableDefaultDeny] - Disable default deny list
97866
98083
  * @param {boolean} [config.debug] - Enable debug logging
98084
+ * @param {Object} [config.tracer] - Optional tracer for telemetry
97867
98085
  */
97868
98086
  constructor(config = {}) {
97869
98087
  this.debug = config.debug || false;
98088
+ this.tracer = config.tracer || null;
97870
98089
  this.allowPatterns = [];
97871
98090
  if (!config.disableDefaultAllow) {
97872
98091
  this.allowPatterns.push(...DEFAULT_ALLOW_PATTERNS);
@@ -97896,6 +98115,24 @@ var init_bashPermissions = __esm({
97896
98115
  if (this.debug) {
97897
98116
  console.log(`[BashPermissions] Total patterns - Allow: ${this.allowPatterns.length}, Deny: ${this.denyPatterns.length}`);
97898
98117
  }
98118
+ this.recordBashEvent("permissions.initialized", {
98119
+ allowPatternCount: this.allowPatterns.length,
98120
+ denyPatternCount: this.denyPatterns.length,
98121
+ hasCustomAllowPatterns: !!(config.allow && config.allow.length > 0),
98122
+ hasCustomDenyPatterns: !!(config.deny && config.deny.length > 0),
98123
+ disableDefaultAllow: !!config.disableDefaultAllow,
98124
+ disableDefaultDeny: !!config.disableDefaultDeny
98125
+ });
98126
+ }
98127
+ /**
98128
+ * Record a bash telemetry event if tracer is available
98129
+ * @param {string} eventType - Event type (e.g., 'permission.checked', 'permission.denied')
98130
+ * @param {Object} data - Event data
98131
+ */
98132
+ recordBashEvent(eventType, data2 = {}) {
98133
+ if (this.tracer && typeof this.tracer.recordBashEvent === "function") {
98134
+ this.tracer.recordBashEvent(eventType, data2);
98135
+ }
97899
98136
  }
97900
98137
  /**
97901
98138
  * Check if a simple command is allowed (complex commands allowed if they match patterns)
@@ -97904,11 +98141,17 @@ var init_bashPermissions = __esm({
97904
98141
  */
97905
98142
  check(command) {
97906
98143
  if (!command || typeof command !== "string") {
97907
- return {
98144
+ const result2 = {
97908
98145
  allowed: false,
97909
98146
  reason: "Invalid or empty command",
97910
98147
  command
97911
98148
  };
98149
+ this.recordBashEvent("permission.denied", {
98150
+ command: String(command),
98151
+ reason: result2.reason,
98152
+ isComplex: false
98153
+ });
98154
+ return result2;
97912
98155
  }
97913
98156
  const commandIsComplex = isComplexCommand(command);
97914
98157
  if (commandIsComplex) {
@@ -97916,18 +98159,31 @@ var init_bashPermissions = __esm({
97916
98159
  }
97917
98160
  const parsed = parseCommand(command);
97918
98161
  if (parsed.error) {
97919
- return {
98162
+ const result2 = {
97920
98163
  allowed: false,
97921
98164
  reason: parsed.error,
97922
98165
  command
97923
98166
  };
98167
+ this.recordBashEvent("permission.denied", {
98168
+ command,
98169
+ reason: result2.reason,
98170
+ isComplex: false,
98171
+ parseError: true
98172
+ });
98173
+ return result2;
97924
98174
  }
97925
98175
  if (!parsed.command) {
97926
- return {
98176
+ const result2 = {
97927
98177
  allowed: false,
97928
98178
  reason: "No valid command found",
97929
98179
  command
97930
98180
  };
98181
+ this.recordBashEvent("permission.denied", {
98182
+ command,
98183
+ reason: result2.reason,
98184
+ isComplex: false
98185
+ });
98186
+ return result2;
97931
98187
  }
97932
98188
  if (this.debug) {
97933
98189
  console.log(`[BashPermissions] Checking simple command: "${command}"`);
@@ -97935,22 +98191,37 @@ var init_bashPermissions = __esm({
97935
98191
  }
97936
98192
  if (matchesAnyPattern(parsed, this.denyPatterns)) {
97937
98193
  const matchedPatterns = this.denyPatterns.filter((pattern) => matchesPattern(parsed, pattern));
97938
- return {
98194
+ const result2 = {
97939
98195
  allowed: false,
97940
98196
  reason: `Command matches deny pattern: ${matchedPatterns[0]}`,
97941
98197
  command,
97942
98198
  parsed,
97943
98199
  matchedPatterns
97944
98200
  };
98201
+ this.recordBashEvent("permission.denied", {
98202
+ command,
98203
+ parsedCommand: parsed.command,
98204
+ reason: "matches_deny_pattern",
98205
+ matchedPattern: matchedPatterns[0],
98206
+ isComplex: false
98207
+ });
98208
+ return result2;
97945
98209
  }
97946
98210
  if (this.allowPatterns.length > 0) {
97947
98211
  if (!matchesAnyPattern(parsed, this.allowPatterns)) {
97948
- return {
98212
+ const result2 = {
97949
98213
  allowed: false,
97950
98214
  reason: "Command not in allow list",
97951
98215
  command,
97952
98216
  parsed
97953
98217
  };
98218
+ this.recordBashEvent("permission.denied", {
98219
+ command,
98220
+ parsedCommand: parsed.command,
98221
+ reason: "not_in_allow_list",
98222
+ isComplex: false
98223
+ });
98224
+ return result2;
97954
98225
  }
97955
98226
  }
97956
98227
  const result = {
@@ -97962,6 +98233,11 @@ var init_bashPermissions = __esm({
97962
98233
  if (this.debug) {
97963
98234
  console.log(`[BashPermissions] ALLOWED - command passed all checks`);
97964
98235
  }
98236
+ this.recordBashEvent("permission.allowed", {
98237
+ command,
98238
+ parsedCommand: parsed.command,
98239
+ isComplex: false
98240
+ });
97965
98241
  return result;
97966
98242
  }
97967
98243
  /**
@@ -97985,13 +98261,20 @@ var init_bashPermissions = __esm({
97985
98261
  if (this.debug) {
97986
98262
  console.log(`[BashPermissions] DENIED - matches complex deny pattern: ${pattern}`);
97987
98263
  }
97988
- return {
98264
+ const result = {
97989
98265
  allowed: false,
97990
98266
  reason: `Command matches deny pattern: ${pattern}`,
97991
98267
  command,
97992
98268
  isComplex: true,
97993
98269
  matchedPatterns: [pattern]
97994
98270
  };
98271
+ this.recordBashEvent("permission.denied", {
98272
+ command,
98273
+ reason: "matches_deny_pattern",
98274
+ matchedPattern: pattern,
98275
+ isComplex: true
98276
+ });
98277
+ return result;
97995
98278
  }
97996
98279
  }
97997
98280
  for (const pattern of complexAllowPatterns) {
@@ -97999,17 +98282,28 @@ var init_bashPermissions = __esm({
97999
98282
  if (this.debug) {
98000
98283
  console.log(`[BashPermissions] ALLOWED - matches complex allow pattern: ${pattern}`);
98001
98284
  }
98002
- return {
98285
+ const result = {
98003
98286
  allowed: true,
98004
98287
  command,
98005
98288
  isComplex: true,
98006
98289
  matchedPattern: pattern
98007
98290
  };
98291
+ this.recordBashEvent("permission.allowed", {
98292
+ command,
98293
+ matchedPattern: pattern,
98294
+ isComplex: true
98295
+ });
98296
+ return result;
98008
98297
  }
98009
98298
  }
98010
98299
  if (this.debug) {
98011
98300
  console.log(`[BashPermissions] DENIED - no matching complex pattern found`);
98012
98301
  }
98302
+ this.recordBashEvent("permission.denied", {
98303
+ command,
98304
+ reason: "no_matching_complex_pattern",
98305
+ isComplex: true
98306
+ });
98013
98307
  return {
98014
98308
  allowed: false,
98015
98309
  reason: 'Complex shell commands require explicit allow patterns (e.g., "cd * && git *")',
@@ -98308,14 +98602,16 @@ var init_bash = __esm({
98308
98602
  bashConfig = {},
98309
98603
  debug = false,
98310
98604
  cwd,
98311
- allowedFolders = []
98605
+ allowedFolders = [],
98606
+ tracer = null
98312
98607
  } = options;
98313
98608
  const permissionChecker = new BashPermissionChecker({
98314
98609
  allow: bashConfig.allow,
98315
98610
  deny: bashConfig.deny,
98316
98611
  disableDefaultAllow: bashConfig.disableDefaultAllow,
98317
98612
  disableDefaultDeny: bashConfig.disableDefaultDeny,
98318
- debug
98613
+ debug,
98614
+ tracer
98319
98615
  });
98320
98616
  const getDefaultWorkingDirectory = () => {
98321
98617
  if (bashConfig.workingDirectory) {
@@ -99059,6 +99355,28 @@ var init_simpleTelemetry = __esm({
99059
99355
  ...data2
99060
99356
  });
99061
99357
  }
99358
+ /**
99359
+ * Record MCP (Model Context Protocol) events
99360
+ * Tracks server connections, tool discovery, method filtering, and tool execution
99361
+ */
99362
+ recordMcpEvent(eventType, data2 = {}) {
99363
+ if (!this.isEnabled()) return;
99364
+ this.addEvent(`mcp.${eventType}`, {
99365
+ "session.id": this.sessionId,
99366
+ ...data2
99367
+ });
99368
+ }
99369
+ /**
99370
+ * Record bash tool events
99371
+ * Tracks command permission checks, allowed/denied commands, and execution
99372
+ */
99373
+ recordBashEvent(eventType, data2 = {}) {
99374
+ if (!this.isEnabled()) return;
99375
+ this.addEvent(`bash.${eventType}`, {
99376
+ "session.id": this.sessionId,
99377
+ ...data2
99378
+ });
99379
+ }
99062
99380
  setAttributes(attributes) {
99063
99381
  if (this.telemetry && this.telemetry.enableConsole) {
99064
99382
  console.log("[Attributes]", attributes);
package/index.d.ts CHANGED
@@ -49,9 +49,11 @@ export interface ProbeAgentOptions {
49
49
  disableMermaidValidation?: boolean;
50
50
  /** Disable automatic JSON validation and fixing (prevents infinite recursion in JsonFixingAgent) */
51
51
  disableJsonValidation?: boolean;
52
- /** Enable agent skills discovery and activation */
52
+ /** Enable agent skills discovery and activation (disabled by default) */
53
+ allowSkills?: boolean;
54
+ /** @deprecated Use allowSkills instead. Enable agent skills discovery and activation (disabled by default) */
53
55
  enableSkills?: boolean;
54
- /** Disable agent skills (overrides enableSkills) */
56
+ /** Disable agent skills (overrides allowSkills/enableSkills) */
55
57
  disableSkills?: boolean;
56
58
  /** Skill directories to scan relative to repo root */
57
59
  skillDirs?: string[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@probelabs/probe",
3
- "version": "0.6.0-rc207",
3
+ "version": "0.6.0-rc209",
4
4
  "description": "Node.js wrapper for the probe code search tool",
5
5
  "main": "src/index.js",
6
6
  "module": "src/index.js",
@@ -68,9 +68,11 @@ export interface ProbeAgentOptions {
68
68
  disableMermaidValidation?: boolean;
69
69
  /** Disable automatic JSON validation and fixing (prevents infinite recursion in JsonFixingAgent) */
70
70
  disableJsonValidation?: boolean;
71
- /** Enable agent skills discovery and activation */
71
+ /** Enable agent skills discovery and activation (disabled by default) */
72
+ allowSkills?: boolean;
73
+ /** @deprecated Use allowSkills instead. Enable agent skills discovery and activation (disabled by default) */
72
74
  enableSkills?: boolean;
73
- /** Disable agent skills (overrides enableSkills) */
75
+ /** Disable agent skills (overrides allowSkills/enableSkills) */
74
76
  disableSkills?: boolean;
75
77
  /** Skill directories to scan relative to repo root */
76
78
  skillDirs?: string[];