@probelabs/visor 0.1.131 → 0.1.132

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 (116) hide show
  1. package/README.md +460 -596
  2. package/action.yml +2 -2
  3. package/dist/ai-review-service.d.ts +3 -0
  4. package/dist/ai-review-service.d.ts.map +1 -1
  5. package/dist/cli-main.d.ts.map +1 -1
  6. package/dist/config/config-watcher.d.ts +15 -1
  7. package/dist/config/config-watcher.d.ts.map +1 -1
  8. package/dist/enterprise/policy/policy-input-builder.d.ts +2 -0
  9. package/dist/enterprise/policy/policy-input-builder.d.ts.map +1 -1
  10. package/dist/frontends/slack-frontend.d.ts.map +1 -1
  11. package/dist/generated/config-schema.d.ts +404 -96
  12. package/dist/generated/config-schema.d.ts.map +1 -1
  13. package/dist/generated/config-schema.json +2875 -0
  14. package/dist/index.js +23064 -8507
  15. package/dist/{traces/run-2026-02-15T19-14-20-379Z.ndjson → output/traces/run-2026-02-18T11-06-48-673Z.ndjson} +84 -84
  16. package/dist/{traces/run-2026-02-15T19-15-09-410Z.ndjson → output/traces/run-2026-02-18T11-07-37-310Z.ndjson} +1017 -1017
  17. package/dist/providers/ai-check-provider.d.ts +12 -0
  18. package/dist/providers/ai-check-provider.d.ts.map +1 -1
  19. package/dist/providers/workflow-check-provider.d.ts.map +1 -1
  20. package/dist/providers/workflow-tool-executor.d.ts +5 -1
  21. package/dist/providers/workflow-tool-executor.d.ts.map +1 -1
  22. package/dist/sdk/{check-provider-registry-S7BMQ2FC.mjs → check-provider-registry-4WLTLPMU.mjs} +6 -6
  23. package/dist/sdk/{check-provider-registry-ZOLEYDKM.mjs → check-provider-registry-7TCA3NSG.mjs} +6 -6
  24. package/dist/sdk/{check-provider-registry-AAPPJ4CP.mjs → check-provider-registry-RRUZHGJI.mjs} +6 -6
  25. package/dist/sdk/{chunk-OMFPM576.mjs → chunk-27RV5RR2.mjs} +2 -2
  26. package/dist/sdk/{chunk-6ZZ4DPAA.mjs → chunk-5VY5QJTY.mjs} +231 -42
  27. package/dist/sdk/chunk-5VY5QJTY.mjs.map +1 -0
  28. package/dist/sdk/{chunk-2GCSK3PD.mjs → chunk-BGBXLPLL.mjs} +3 -3
  29. package/dist/sdk/{chunk-LDFUW34H.mjs → chunk-BOGVSF57.mjs} +231 -42
  30. package/dist/sdk/chunk-BOGVSF57.mjs.map +1 -0
  31. package/dist/sdk/{chunk-EBTD2D4L.mjs → chunk-FAKITJ3J.mjs} +2 -2
  32. package/dist/sdk/{chunk-RI77TA6V.mjs → chunk-LMJNI6RM.mjs} +4 -4
  33. package/dist/sdk/chunk-LMJNI6RM.mjs.map +1 -0
  34. package/dist/sdk/{chunk-LQ5B4T6L.mjs → chunk-U3BLLEW3.mjs} +431 -82
  35. package/dist/sdk/chunk-U3BLLEW3.mjs.map +1 -0
  36. package/dist/sdk/{chunk-VO4N6TEL.mjs → chunk-UBDHAGYY.mjs} +3 -3
  37. package/dist/sdk/{chunk-N4I6ZDCJ.mjs → chunk-VG7FWDC2.mjs} +3 -3
  38. package/dist/sdk/{chunk-RI77TA6V.mjs.map → chunk-VG7FWDC2.mjs.map} +1 -1
  39. package/dist/sdk/{chunk-MQ57AB4U.mjs → chunk-XGI47XIH.mjs} +260 -55
  40. package/dist/sdk/chunk-XGI47XIH.mjs.map +1 -0
  41. package/dist/sdk/{config-4EG7IQIU.mjs → config-FMIIATKX.mjs} +2 -2
  42. package/dist/sdk/{failure-condition-evaluator-GLHZZF47.mjs → failure-condition-evaluator-MUUAK7MN.mjs} +3 -3
  43. package/dist/sdk/{failure-condition-evaluator-KN55WXRO.mjs → failure-condition-evaluator-PNONVBXD.mjs} +3 -3
  44. package/dist/sdk/{github-frontend-F4TE2JY7.mjs → github-frontend-DWF6BLZH.mjs} +3 -3
  45. package/dist/sdk/{github-frontend-HCOKL53D.mjs → github-frontend-WR4S3NG5.mjs} +3 -3
  46. package/dist/sdk/{host-SAT6RHDX.mjs → host-S3LSWESP.mjs} +3 -3
  47. package/dist/sdk/{host-VA3ET7N6.mjs → host-U7V54J2H.mjs} +3 -3
  48. package/dist/sdk/{routing-KFYQGOYU.mjs → routing-F4FOWVKF.mjs} +4 -4
  49. package/dist/sdk/{routing-OXQKETSA.mjs → routing-MVDVJDYJ.mjs} +4 -4
  50. package/dist/sdk/{schedule-tool-handler-OQF57URO.mjs → schedule-tool-handler-7DNEGDZC.mjs} +6 -6
  51. package/dist/sdk/{schedule-tool-handler-PJVKWSYX.mjs → schedule-tool-handler-FRN3KKRM.mjs} +6 -6
  52. package/dist/sdk/{schedule-tool-handler-G353DHS6.mjs → schedule-tool-handler-VFES42DD.mjs} +6 -6
  53. package/dist/sdk/sdk.d.mts +56 -38
  54. package/dist/sdk/sdk.d.ts +56 -38
  55. package/dist/sdk/sdk.js +744 -115
  56. package/dist/sdk/sdk.js.map +1 -1
  57. package/dist/sdk/sdk.mjs +5 -5
  58. package/dist/sdk/{slack-frontend-LAY45IBR.mjs → slack-frontend-JS2VAZWB.mjs} +95 -4
  59. package/dist/sdk/slack-frontend-JS2VAZWB.mjs.map +1 -0
  60. package/dist/sdk/{trace-helpers-R2ETIEC2.mjs → trace-helpers-KSPGA24B.mjs} +2 -2
  61. package/dist/sdk/{trace-helpers-LOPBHYYX.mjs → trace-helpers-RDPXIN4S.mjs} +2 -2
  62. package/dist/sdk/{workflow-check-provider-LRWD52WN.mjs → workflow-check-provider-4NFWH6YO.mjs} +6 -6
  63. package/dist/sdk/{workflow-check-provider-N2DRFQDB.mjs → workflow-check-provider-BMVJ6X7N.mjs} +6 -6
  64. package/dist/sdk/{workflow-check-provider-57KAR4Y4.mjs → workflow-check-provider-CPGIRZMH.mjs} +6 -6
  65. package/dist/slack/adapter.d.ts +2 -0
  66. package/dist/slack/adapter.d.ts.map +1 -1
  67. package/dist/slack/client.d.ts +3 -0
  68. package/dist/slack/client.d.ts.map +1 -1
  69. package/dist/slack/markdown.d.ts +29 -0
  70. package/dist/slack/markdown.d.ts.map +1 -1
  71. package/dist/slack/socket-runner.d.ts +2 -0
  72. package/dist/slack/socket-runner.d.ts.map +1 -1
  73. package/dist/{output/traces/run-2026-02-15T19-14-20-379Z.ndjson → traces/run-2026-02-18T11-06-48-673Z.ndjson} +84 -84
  74. package/dist/{output/traces/run-2026-02-15T19-15-09-410Z.ndjson → traces/run-2026-02-18T11-07-37-310Z.ndjson} +1017 -1017
  75. package/dist/tui/chat-tui.d.ts +7 -0
  76. package/dist/tui/chat-tui.d.ts.map +1 -1
  77. package/dist/tui/components/input-bar.d.ts +11 -0
  78. package/dist/tui/components/input-bar.d.ts.map +1 -1
  79. package/dist/tui/components/trace-viewer.d.ts +25 -1
  80. package/dist/tui/components/trace-viewer.d.ts.map +1 -1
  81. package/dist/types/bot.d.ts +12 -0
  82. package/dist/types/bot.d.ts.map +1 -1
  83. package/dist/types/config.d.ts +4 -1
  84. package/dist/types/config.d.ts.map +1 -1
  85. package/package.json +3 -3
  86. package/dist/defaults/.visor.yaml +0 -420
  87. package/dist/sdk/chunk-6ZZ4DPAA.mjs.map +0 -1
  88. package/dist/sdk/chunk-LDFUW34H.mjs.map +0 -1
  89. package/dist/sdk/chunk-LQ5B4T6L.mjs.map +0 -1
  90. package/dist/sdk/chunk-MQ57AB4U.mjs.map +0 -1
  91. package/dist/sdk/chunk-N4I6ZDCJ.mjs.map +0 -1
  92. package/dist/sdk/slack-frontend-LAY45IBR.mjs.map +0 -1
  93. /package/dist/sdk/{check-provider-registry-AAPPJ4CP.mjs.map → check-provider-registry-4WLTLPMU.mjs.map} +0 -0
  94. /package/dist/sdk/{check-provider-registry-S7BMQ2FC.mjs.map → check-provider-registry-7TCA3NSG.mjs.map} +0 -0
  95. /package/dist/sdk/{check-provider-registry-ZOLEYDKM.mjs.map → check-provider-registry-RRUZHGJI.mjs.map} +0 -0
  96. /package/dist/sdk/{chunk-EBTD2D4L.mjs.map → chunk-27RV5RR2.mjs.map} +0 -0
  97. /package/dist/sdk/{chunk-2GCSK3PD.mjs.map → chunk-BGBXLPLL.mjs.map} +0 -0
  98. /package/dist/sdk/{chunk-OMFPM576.mjs.map → chunk-FAKITJ3J.mjs.map} +0 -0
  99. /package/dist/sdk/{chunk-VO4N6TEL.mjs.map → chunk-UBDHAGYY.mjs.map} +0 -0
  100. /package/dist/sdk/{config-4EG7IQIU.mjs.map → config-FMIIATKX.mjs.map} +0 -0
  101. /package/dist/sdk/{failure-condition-evaluator-GLHZZF47.mjs.map → failure-condition-evaluator-MUUAK7MN.mjs.map} +0 -0
  102. /package/dist/sdk/{failure-condition-evaluator-KN55WXRO.mjs.map → failure-condition-evaluator-PNONVBXD.mjs.map} +0 -0
  103. /package/dist/sdk/{github-frontend-F4TE2JY7.mjs.map → github-frontend-DWF6BLZH.mjs.map} +0 -0
  104. /package/dist/sdk/{github-frontend-HCOKL53D.mjs.map → github-frontend-WR4S3NG5.mjs.map} +0 -0
  105. /package/dist/sdk/{host-SAT6RHDX.mjs.map → host-S3LSWESP.mjs.map} +0 -0
  106. /package/dist/sdk/{host-VA3ET7N6.mjs.map → host-U7V54J2H.mjs.map} +0 -0
  107. /package/dist/sdk/{routing-KFYQGOYU.mjs.map → routing-F4FOWVKF.mjs.map} +0 -0
  108. /package/dist/sdk/{routing-OXQKETSA.mjs.map → routing-MVDVJDYJ.mjs.map} +0 -0
  109. /package/dist/sdk/{schedule-tool-handler-G353DHS6.mjs.map → schedule-tool-handler-7DNEGDZC.mjs.map} +0 -0
  110. /package/dist/sdk/{schedule-tool-handler-OQF57URO.mjs.map → schedule-tool-handler-FRN3KKRM.mjs.map} +0 -0
  111. /package/dist/sdk/{schedule-tool-handler-PJVKWSYX.mjs.map → schedule-tool-handler-VFES42DD.mjs.map} +0 -0
  112. /package/dist/sdk/{trace-helpers-LOPBHYYX.mjs.map → trace-helpers-KSPGA24B.mjs.map} +0 -0
  113. /package/dist/sdk/{trace-helpers-R2ETIEC2.mjs.map → trace-helpers-RDPXIN4S.mjs.map} +0 -0
  114. /package/dist/sdk/{workflow-check-provider-57KAR4Y4.mjs.map → workflow-check-provider-4NFWH6YO.mjs.map} +0 -0
  115. /package/dist/sdk/{workflow-check-provider-LRWD52WN.mjs.map → workflow-check-provider-BMVJ6X7N.mjs.map} +0 -0
  116. /package/dist/sdk/{workflow-check-provider-N2DRFQDB.mjs.map → workflow-check-provider-CPGIRZMH.mjs.map} +0 -0
@@ -28,7 +28,7 @@ import {
28
28
  import {
29
29
  config_exports,
30
30
  init_config
31
- } from "./chunk-LQ5B4T6L.mjs";
31
+ } from "./chunk-U3BLLEW3.mjs";
32
32
  import {
33
33
  ExecutionJournal,
34
34
  checkLoopBudget,
@@ -37,11 +37,11 @@ import {
37
37
  init_routing,
38
38
  init_snapshot_store,
39
39
  snapshot_store_exports
40
- } from "./chunk-2GCSK3PD.mjs";
40
+ } from "./chunk-BGBXLPLL.mjs";
41
41
  import {
42
42
  FailureConditionEvaluator,
43
43
  init_failure_condition_evaluator
44
- } from "./chunk-EBTD2D4L.mjs";
44
+ } from "./chunk-27RV5RR2.mjs";
45
45
  import {
46
46
  addEvent,
47
47
  emitNdjsonFallback,
@@ -52,7 +52,7 @@ import {
52
52
  setSpanAttributes,
53
53
  trace_helpers_exports,
54
54
  withActiveSpan
55
- } from "./chunk-N4I6ZDCJ.mjs";
55
+ } from "./chunk-VG7FWDC2.mjs";
56
56
  import {
57
57
  addDiagramBlock,
58
58
  init_metrics
@@ -1049,7 +1049,7 @@ ${this.escapeXml(processedFallbackDiff)}
1049
1049
  <user>${this.escapeXml(String(m.user || ""))}</user>
1050
1050
  <text>${this.escapeXml(String(m.text || ""))}</text>
1051
1051
  <timestamp>${this.escapeXml(String(m.timestamp || ""))}</timestamp>
1052
- <origin>${this.escapeXml(String(m.origin || ""))}</origin>
1052
+ <origin>${this.escapeXml(String(m.origin || ""))}</origin>${this.formatFilesXml(m.files)}
1053
1053
  </message>`;
1054
1054
  }
1055
1055
  xml += `
@@ -1061,7 +1061,7 @@ ${this.escapeXml(processedFallbackDiff)}
1061
1061
  <user>${this.escapeXml(String(current.user || ""))}</user>
1062
1062
  <text>${this.escapeXml(String(current.text || ""))}</text>
1063
1063
  <timestamp>${this.escapeXml(String(current.timestamp || ""))}</timestamp>
1064
- <origin>${this.escapeXml(String(current.origin || ""))}</origin>
1064
+ <origin>${this.escapeXml(String(current.origin || ""))}</origin>${this.formatFilesXml(current.files)}
1065
1065
  </current>
1066
1066
  </slack_context>`;
1067
1067
  return xml;
@@ -1069,6 +1069,25 @@ ${this.escapeXml(processedFallbackDiff)}
1069
1069
  return "";
1070
1070
  }
1071
1071
  }
1072
+ /** Render file attachment metadata as XML fragment for a message. */
1073
+ formatFilesXml(files) {
1074
+ if (!Array.isArray(files) || files.length === 0) return "";
1075
+ let xml = `
1076
+ <files>`;
1077
+ for (const f of files) {
1078
+ xml += `
1079
+ <file>
1080
+ <name>${this.escapeXml(String(f.name || ""))}</name>
1081
+ <mimetype>${this.escapeXml(String(f.mimetype || ""))}</mimetype>
1082
+ <filetype>${this.escapeXml(String(f.filetype || ""))}</filetype>
1083
+ <url>${this.escapeXml(String(f.url_private || f.permalink || ""))}</url>
1084
+ <size>${f.size || 0}</size>
1085
+ </file>`;
1086
+ }
1087
+ xml += `
1088
+ </files>`;
1089
+ return xml;
1090
+ }
1072
1091
  /**
1073
1092
  * Build a normalized ConversationContext for GitHub (PR/issue + comments)
1074
1093
  * using the same contract as Slack's ConversationContext. This is exposed
@@ -1574,6 +1593,9 @@ ${"=".repeat(60)}
1574
1593
  if (this.config.enableTasks !== void 0) {
1575
1594
  options.enableTasks = this.config.enableTasks;
1576
1595
  }
1596
+ if (this.config.enableExecutePlan !== void 0) {
1597
+ options.enableExecutePlan = this.config.enableExecutePlan;
1598
+ }
1577
1599
  if (this.config.retry) {
1578
1600
  options.retry = this.config.retry;
1579
1601
  }
@@ -1600,6 +1622,9 @@ ${"=".repeat(60)}
1600
1622
  if (this.config.completionPrompt !== void 0) {
1601
1623
  options.completionPrompt = this.config.completionPrompt;
1602
1624
  }
1625
+ if (this.config.concurrencyLimiter) {
1626
+ options.concurrencyLimiter = this.config.concurrencyLimiter;
1627
+ }
1603
1628
  try {
1604
1629
  const cfgAny = this.config;
1605
1630
  const allowedFolders = cfgAny.allowedFolders;
@@ -2018,7 +2043,22 @@ ${"=".repeat(60)}
2018
2043
  log("\u{1F4CB} Full response preview:", response);
2019
2044
  }
2020
2045
  try {
2021
- let reviewData;
2046
+ let reviewData = void 0;
2047
+ const RAW_OUTPUT_RE = /\n<<<RAW_OUTPUT>>>\n([\s\S]*?)\n<<<END_RAW_OUTPUT>>>/g;
2048
+ const rawOutputBlocks = [];
2049
+ let responseForParsing = response;
2050
+ {
2051
+ let rawMatch;
2052
+ while ((rawMatch = RAW_OUTPUT_RE.exec(response)) !== null) {
2053
+ rawOutputBlocks.push(rawMatch[1]);
2054
+ }
2055
+ if (rawOutputBlocks.length > 0) {
2056
+ responseForParsing = response.replace(RAW_OUTPUT_RE, "");
2057
+ log(
2058
+ `\u{1F4E6} Extracted ${rawOutputBlocks.length} RAW_OUTPUT blocks (${rawOutputBlocks.reduce((s, b) => s + b.length, 0)} chars) from response`
2059
+ );
2060
+ }
2061
+ }
2022
2062
  if (_schema === "plain" || !_schema) {
2023
2063
  log(
2024
2064
  `\u{1F4CB} ${_schema === "plain" ? "Plain" : "No"} schema detected - treating raw response as text output`
@@ -2035,7 +2075,7 @@ ${"=".repeat(60)}
2035
2075
  }
2036
2076
  {
2037
2077
  log("\u{1F50D} Extracting JSON from AI response...");
2038
- const sanitizedResponse = response.replace(/^\uFEFF/, "").replace(/[\u200B-\u200D\uFEFF\u00A0]/g, "").replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g, "").trim();
2078
+ const sanitizedResponse = responseForParsing.replace(/^\uFEFF/, "").replace(/[\u200B-\u200D\uFEFF\u00A0]/g, "").replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g, "").trim();
2039
2079
  try {
2040
2080
  reviewData = JSON.parse(sanitizedResponse);
2041
2081
  log("\u2705 Successfully parsed direct JSON response");
@@ -2043,22 +2083,48 @@ ${"=".repeat(60)}
2043
2083
  } catch (parseErr) {
2044
2084
  const errMsg = parseErr instanceof Error ? parseErr.message : String(parseErr);
2045
2085
  log(`\u{1F50D} Direct JSON parsing failed: ${errMsg}`);
2046
- if (response.toLowerCase().includes("i cannot") || response.toLowerCase().includes("unable to")) {
2047
- console.error("\u{1F6AB} AI refused to analyze - returning refusal as output");
2048
- const trimmed2 = response.trim();
2086
+ let recovered = false;
2087
+ const trailingMatch = errMsg.match(/after JSON at position (\d+)/);
2088
+ if (trailingMatch) {
2089
+ const pos = parseInt(trailingMatch[1], 10);
2090
+ try {
2091
+ reviewData = JSON.parse(sanitizedResponse.substring(0, pos));
2092
+ const trailing = sanitizedResponse.substring(pos).trim();
2093
+ if (trailing && reviewData && typeof reviewData === "object" && typeof reviewData.text === "string") {
2094
+ reviewData.text = reviewData.text + "\n\n" + trailing;
2095
+ log(
2096
+ `\u2705 Recovered JSON and appended ${trailing.length} chars of trailing content to text field`
2097
+ );
2098
+ } else {
2099
+ log(`\u2705 Recovered JSON by trimming trailing content at position ${pos}`);
2100
+ }
2101
+ if (debugInfo) debugInfo.jsonParseSuccess = true;
2102
+ recovered = true;
2103
+ } catch {
2104
+ }
2105
+ }
2106
+ if (!recovered) {
2107
+ if (response.toLowerCase().includes("i cannot") || response.toLowerCase().includes("unable to")) {
2108
+ console.error("\u{1F6AB} AI refused to analyze - returning refusal as output");
2109
+ const trimmed2 = responseForParsing.trim();
2110
+ const out = trimmed2 ? { text: trimmed2 } : {};
2111
+ if (rawOutputBlocks.length > 0) out._rawOutput = rawOutputBlocks.join("\n\n");
2112
+ return {
2113
+ issues: [],
2114
+ output: out,
2115
+ debug: debugInfo
2116
+ };
2117
+ }
2118
+ log("\u{1F527} Treating response as plain text (no JSON extraction)");
2119
+ const trimmed = responseForParsing.trim();
2120
+ const fallbackOut = { text: trimmed };
2121
+ if (rawOutputBlocks.length > 0) fallbackOut._rawOutput = rawOutputBlocks.join("\n\n");
2049
2122
  return {
2050
2123
  issues: [],
2051
- output: trimmed2 ? { text: trimmed2 } : {},
2124
+ output: fallbackOut,
2052
2125
  debug: debugInfo
2053
2126
  };
2054
2127
  }
2055
- log("\u{1F527} Treating response as plain text (no JSON extraction)");
2056
- const trimmed = response.trim();
2057
- return {
2058
- issues: [],
2059
- output: { text: trimmed },
2060
- debug: debugInfo
2061
- };
2062
2128
  }
2063
2129
  }
2064
2130
  const looksLikeTextOutput = reviewData && typeof reviewData === "object" && typeof reviewData.text === "string" && String(reviewData.text).trim().length > 0;
@@ -2106,6 +2172,9 @@ ${"=".repeat(60)}
2106
2172
  out.text = fallbackText;
2107
2173
  }
2108
2174
  }
2175
+ if (rawOutputBlocks.length > 0) {
2176
+ out._rawOutput = rawOutputBlocks.join("\n\n");
2177
+ }
2109
2178
  const result2 = {
2110
2179
  // Keep issues empty for custom-schema rendering; consumers read from output.*
2111
2180
  issues: [],
@@ -2953,7 +3022,7 @@ function workflowInputsToJsonSchema(inputs) {
2953
3022
  required: required.length > 0 ? required : void 0
2954
3023
  };
2955
3024
  }
2956
- function createWorkflowToolDefinition(workflow, argsOverrides) {
3025
+ function createWorkflowToolDefinition(workflow, argsOverrides, nameOverride) {
2957
3026
  const baseSchema = workflowInputsToJsonSchema(workflow.inputs);
2958
3027
  let inputSchema = baseSchema;
2959
3028
  if (argsOverrides && baseSchema && typeof baseSchema === "object") {
@@ -2971,7 +3040,7 @@ function createWorkflowToolDefinition(workflow, argsOverrides) {
2971
3040
  };
2972
3041
  }
2973
3042
  return {
2974
- name: workflow.id,
3043
+ name: nameOverride || workflow.id,
2975
3044
  description: workflow.description || `Execute the ${workflow.name} workflow`,
2976
3045
  inputSchema,
2977
3046
  // Workflow tools don't have an exec command - they're executed specially
@@ -2999,7 +3068,7 @@ async function executeWorkflowAsTool(workflowId, args, context2, argsOverrides)
2999
3068
  ...args,
3000
3069
  ...argsOverrides
3001
3070
  };
3002
- const { WorkflowCheckProvider: WorkflowCheckProvider2 } = await import("./workflow-check-provider-57KAR4Y4.mjs");
3071
+ const { WorkflowCheckProvider: WorkflowCheckProvider2 } = await import("./workflow-check-provider-4NFWH6YO.mjs");
3003
3072
  const provider = new WorkflowCheckProvider2();
3004
3073
  const checkConfig = {
3005
3074
  type: "workflow",
@@ -3021,6 +3090,16 @@ async function executeWorkflowAsTool(workflowId, args, context2, argsOverrides)
3021
3090
  );
3022
3091
  logger.debug(`[WorkflowToolExecutor] Workflow '${workflowId}' output preview: ${outputPreview}`);
3023
3092
  if (output !== void 0) {
3093
+ if (output && typeof output === "object" && typeof output._rawOutput === "string") {
3094
+ const rawOutput = output._rawOutput;
3095
+ const cleanOutput = { ...output };
3096
+ delete cleanOutput._rawOutput;
3097
+ const jsonStr = JSON.stringify(cleanOutput, null, 2);
3098
+ logger.debug(
3099
+ `[WorkflowToolExecutor] Wrapping _rawOutput (${rawOutput.length} chars) in RAW_OUTPUT delimiters for '${workflowId}'`
3100
+ );
3101
+ return jsonStr + "\n<<<RAW_OUTPUT>>>\n" + rawOutput + "\n<<<END_RAW_OUTPUT>>>";
3102
+ }
3024
3103
  return output;
3025
3104
  }
3026
3105
  if (result.content) {
@@ -3045,7 +3124,7 @@ function resolveWorkflowToolFromItem(item) {
3045
3124
  logger.warn(`[WorkflowToolExecutor] Workflow '${item.workflow}' not found in registry`);
3046
3125
  return void 0;
3047
3126
  }
3048
- return createWorkflowToolDefinition(workflow, item.args);
3127
+ return createWorkflowToolDefinition(workflow, item.args, item.name);
3049
3128
  }
3050
3129
  return void 0;
3051
3130
  }
@@ -8711,7 +8790,7 @@ async function executeCheckWithForEachItems2(checkId, forEachParent, forEachItem
8711
8790
  }
8712
8791
  }
8713
8792
  try {
8714
- const { evaluateTransitions } = await import("./routing-OXQKETSA.mjs");
8793
+ const { evaluateTransitions } = await import("./routing-F4FOWVKF.mjs");
8715
8794
  const transTarget = await evaluateTransitions(
8716
8795
  onFinish.transitions,
8717
8796
  forEachParent,
@@ -8771,7 +8850,7 @@ async function executeCheckWithForEachItems2(checkId, forEachParent, forEachItem
8771
8850
  `[LevelDispatch] Error evaluating on_finish transitions for ${forEachParent}: ${e instanceof Error ? e.message : String(e)}`
8772
8851
  );
8773
8852
  }
8774
- const { evaluateGoto: evaluateGoto2 } = await import("./routing-OXQKETSA.mjs");
8853
+ const { evaluateGoto: evaluateGoto2 } = await import("./routing-F4FOWVKF.mjs");
8775
8854
  if (context2.debug) {
8776
8855
  logger.info(
8777
8856
  `[LevelDispatch] Evaluating on_finish.goto_js for forEach parent: ${forEachParent}`
@@ -10027,7 +10106,7 @@ async function renderTemplateContent2(checkId, checkConfig, reviewSummary) {
10027
10106
  const fs11 = await import("fs/promises");
10028
10107
  const path14 = await import("path");
10029
10108
  const schemaRaw = checkConfig.schema || "plain";
10030
- const schema = typeof schemaRaw === "string" ? schemaRaw : "code-review";
10109
+ const schema = typeof schemaRaw === "string" && !schemaRaw.includes("{{") && !schemaRaw.includes("{%") ? schemaRaw : typeof schemaRaw === "object" ? "code-review" : "plain";
10031
10110
  let templateContent;
10032
10111
  if (checkConfig.template && checkConfig.template.content) {
10033
10112
  templateContent = String(checkConfig.template.content);
@@ -11714,6 +11793,17 @@ function buildEngineContextForRun(workingDirectory, config, prInfo, debug, maxPa
11714
11793
  }
11715
11794
  const journal = new ExecutionJournal();
11716
11795
  const memory = MemoryStore.getInstance(clonedConfig.memory);
11796
+ let sharedConcurrencyLimiter = void 0;
11797
+ if (clonedConfig.max_ai_concurrency && _DelegationManager) {
11798
+ sharedConcurrencyLimiter = new _DelegationManager({
11799
+ maxConcurrent: clonedConfig.max_ai_concurrency,
11800
+ maxPerSession: 999
11801
+ // No per-session limit needed for global AI gating
11802
+ });
11803
+ logger.debug(
11804
+ `[EngineContext] Created shared AI concurrency limiter (max: ${clonedConfig.max_ai_concurrency})`
11805
+ );
11806
+ }
11717
11807
  return {
11718
11808
  mode: "state-machine",
11719
11809
  config: clonedConfig,
@@ -11726,6 +11816,7 @@ function buildEngineContextForRun(workingDirectory, config, prInfo, debug, maxPa
11726
11816
  event: prInfo.eventType,
11727
11817
  debug,
11728
11818
  maxParallelism,
11819
+ sharedConcurrencyLimiter,
11729
11820
  failFast,
11730
11821
  requestedChecks: requestedChecks && requestedChecks.length > 0 ? requestedChecks : void 0,
11731
11822
  // Store prInfo for later access (e.g., in getOutputHistorySnapshot)
@@ -11772,6 +11863,7 @@ async function initializeWorkspace(context2) {
11772
11863
  return context2;
11773
11864
  }
11774
11865
  }
11866
+ var _DelegationManager;
11775
11867
  var init_build_engine_context = __esm({
11776
11868
  "src/state-machine/context/build-engine-context.ts"() {
11777
11869
  "use strict";
@@ -11780,6 +11872,14 @@ var init_build_engine_context = __esm({
11780
11872
  init_human_id();
11781
11873
  init_logger();
11782
11874
  init_workspace_manager();
11875
+ _DelegationManager = null;
11876
+ try {
11877
+ const probe = __require("@probelabs/probe");
11878
+ if (probe && typeof probe.DelegationManager === "function") {
11879
+ _DelegationManager = probe.DelegationManager;
11880
+ }
11881
+ } catch {
11882
+ }
11783
11883
  }
11784
11884
  });
11785
11885
 
@@ -11923,7 +12023,7 @@ var init_state_machine_execution_engine = __esm({
11923
12023
  try {
11924
12024
  const map = options?.webhookContext?.webhookData;
11925
12025
  if (map) {
11926
- const { CheckProviderRegistry: CheckProviderRegistry2 } = await import("./check-provider-registry-ZOLEYDKM.mjs");
12026
+ const { CheckProviderRegistry: CheckProviderRegistry2 } = await import("./check-provider-registry-7TCA3NSG.mjs");
11927
12027
  const reg = CheckProviderRegistry2.getInstance();
11928
12028
  const p = reg.getProvider("http_input");
11929
12029
  if (p && typeof p.setWebhookContext === "function") p.setWebhookContext(map);
@@ -12036,7 +12136,7 @@ var init_state_machine_execution_engine = __esm({
12036
12136
  logger.info("[StateMachine] Using state machine engine");
12037
12137
  }
12038
12138
  if (!config) {
12039
- const { ConfigManager } = await import("./config-4EG7IQIU.mjs");
12139
+ const { ConfigManager } = await import("./config-FMIIATKX.mjs");
12040
12140
  const configManager = new ConfigManager();
12041
12141
  config = await configManager.getDefaultConfig();
12042
12142
  logger.debug("[StateMachine] Using default configuration (no config provided)");
@@ -12101,7 +12201,7 @@ var init_state_machine_execution_engine = __esm({
12101
12201
  try {
12102
12202
  const webhookData = this.executionContext?.webhookContext?.webhookData;
12103
12203
  if (webhookData instanceof Map) {
12104
- const { extractSlackContext: extractSlackContext2 } = await import("./schedule-tool-handler-PJVKWSYX.mjs");
12204
+ const { extractSlackContext: extractSlackContext2 } = await import("./schedule-tool-handler-VFES42DD.mjs");
12105
12205
  const slackCtx = extractSlackContext2(webhookData);
12106
12206
  if (slackCtx) {
12107
12207
  const payload = Array.from(webhookData.values())[0];
@@ -12130,7 +12230,7 @@ var init_state_machine_execution_engine = __esm({
12130
12230
  if (Array.isArray(configWithTagFilter.frontends) && configWithTagFilter.frontends.length > 0) {
12131
12231
  try {
12132
12232
  const { EventBus } = await import("./event-bus-5K3Y2FCS.mjs");
12133
- const { FrontendsHost } = await import("./host-VA3ET7N6.mjs");
12233
+ const { FrontendsHost } = await import("./host-U7V54J2H.mjs");
12134
12234
  const bus = new EventBus();
12135
12235
  context2.eventBus = bus;
12136
12236
  frontendsHost = new FrontendsHost(bus, logger);
@@ -12480,9 +12580,9 @@ var init_state_machine_execution_engine = __esm({
12480
12580
  * @returns Array of failure condition evaluation results
12481
12581
  */
12482
12582
  async evaluateFailureConditions(checkName, reviewSummary, config, previousOutputs, authorAssociation) {
12483
- const { FailureConditionEvaluator: FailureConditionEvaluator2 } = await import("./failure-condition-evaluator-GLHZZF47.mjs");
12583
+ const { FailureConditionEvaluator: FailureConditionEvaluator2 } = await import("./failure-condition-evaluator-PNONVBXD.mjs");
12484
12584
  const evaluator = new FailureConditionEvaluator2();
12485
- const { addEvent: addEvent3 } = await import("./trace-helpers-R2ETIEC2.mjs");
12585
+ const { addEvent: addEvent3 } = await import("./trace-helpers-RDPXIN4S.mjs");
12486
12586
  const { addFailIfTriggered } = await import("./metrics-I6A7IHG4.mjs");
12487
12587
  const checkConfig = config.checks?.[checkName];
12488
12588
  if (!checkConfig) {
@@ -13593,7 +13693,7 @@ var init_ai_check_provider = __esm({
13593
13693
  init_sandbox();
13594
13694
  init_schedule_tool();
13595
13695
  init_schedule_tool_handler();
13596
- AICheckProvider = class extends CheckProvider {
13696
+ AICheckProvider = class _AICheckProvider extends CheckProvider {
13597
13697
  aiReviewService;
13598
13698
  liquidEngine;
13599
13699
  sandbox = null;
@@ -14175,6 +14275,9 @@ ${preview}`);
14175
14275
  if (aiAny2.enableTasks !== void 0) {
14176
14276
  aiConfig.enableTasks = aiAny2.enableTasks;
14177
14277
  }
14278
+ if (aiAny2.enableExecutePlan !== void 0) {
14279
+ aiConfig.enableExecutePlan = aiAny2.enableExecutePlan;
14280
+ }
14178
14281
  if (aiAny2.allowEdit !== void 0) {
14179
14282
  aiConfig.allowEdit = aiAny2.allowEdit;
14180
14283
  }
@@ -14303,6 +14406,10 @@ ${preview}`);
14303
14406
  if (config.ai_max_iterations !== void 0 && aiConfig.maxIterations === void 0) {
14304
14407
  aiConfig.maxIterations = config.ai_max_iterations;
14305
14408
  }
14409
+ const sharedLimiter = sessionInfo?._parentContext?.sharedConcurrencyLimiter;
14410
+ if (sharedLimiter) {
14411
+ aiConfig.concurrencyLimiter = sharedLimiter;
14412
+ }
14306
14413
  const policyEngine = sessionInfo?._parentContext?.policyEngine;
14307
14414
  if (policyEngine) {
14308
14415
  try {
@@ -14316,13 +14423,10 @@ ${preview}`);
14316
14423
  if (decision.capabilities.allowEdit === false) aiConfig.allowEdit = false;
14317
14424
  if (decision.capabilities.allowBash === false) aiConfig.allowBash = false;
14318
14425
  if (decision.capabilities.allowedTools) {
14319
- if (aiConfig.allowedTools) {
14320
- aiConfig.allowedTools = aiConfig.allowedTools.filter(
14321
- (t) => decision.capabilities.allowedTools.includes(t)
14322
- );
14323
- } else {
14324
- aiConfig.allowedTools = decision.capabilities.allowedTools;
14325
- }
14426
+ aiConfig.allowedTools = _AICheckProvider.intersectAllowedTools(
14427
+ aiConfig.allowedTools,
14428
+ decision.capabilities.allowedTools
14429
+ );
14326
14430
  }
14327
14431
  }
14328
14432
  } catch (err) {
@@ -14443,7 +14547,8 @@ ${preview}`);
14443
14547
  if (cfg.workflow && typeof cfg.workflow === "string") {
14444
14548
  workflowEntriesFromMcp.push({
14445
14549
  workflow: cfg.workflow,
14446
- args: cfg.inputs
14550
+ args: cfg.inputs,
14551
+ name: serverName
14447
14552
  });
14448
14553
  mcpEntriesToRemove.push(serverName);
14449
14554
  logger.debug(
@@ -14584,6 +14689,27 @@ ${preview}`);
14584
14689
  );
14585
14690
  }
14586
14691
  }
14692
+ const allowedToolsJsExpr = config.ai_allowed_tools_js;
14693
+ if (allowedToolsJsExpr && _dependencyResults) {
14694
+ try {
14695
+ const dynamicAllowedTools = this.evaluateAllowedToolsJs(
14696
+ allowedToolsJsExpr,
14697
+ prInfo,
14698
+ _dependencyResults,
14699
+ config
14700
+ );
14701
+ if (dynamicAllowedTools !== null) {
14702
+ aiConfig.allowedTools = dynamicAllowedTools;
14703
+ this.logDebug(
14704
+ `[AI Provider] ai_allowed_tools_js evaluated to: ${JSON.stringify(dynamicAllowedTools)}`
14705
+ );
14706
+ }
14707
+ } catch (error) {
14708
+ logger.error(
14709
+ `[AICheckProvider] Failed to evaluate ai_allowed_tools_js: ${error instanceof Error ? error.message : "Unknown error"}`
14710
+ );
14711
+ }
14712
+ }
14587
14713
  const templateContext = {
14588
14714
  pr: {
14589
14715
  number: prInfo.number,
@@ -15087,6 +15213,65 @@ ${processedPrompt}` : processedPrompt;
15087
15213
  return {};
15088
15214
  }
15089
15215
  }
15216
+ /**
15217
+ * Evaluate ai_allowed_tools_js expression to dynamically compute allowed tools list.
15218
+ * Returns a string array of tool names, or null if the expression returns a non-array.
15219
+ */
15220
+ evaluateAllowedToolsJs(expression, prInfo, dependencyResults, config) {
15221
+ if (!this.sandbox) {
15222
+ this.sandbox = createSecureSandbox();
15223
+ }
15224
+ const outputs = {};
15225
+ for (const [checkId, result] of dependencyResults.entries()) {
15226
+ const summary = result;
15227
+ outputs[checkId] = summary.output !== void 0 ? summary.output : summary;
15228
+ }
15229
+ const jsContext = {
15230
+ outputs,
15231
+ inputs: config.inputs || {},
15232
+ pr: {
15233
+ number: prInfo.number,
15234
+ title: prInfo.title,
15235
+ description: prInfo.body,
15236
+ author: prInfo.author,
15237
+ branch: prInfo.head,
15238
+ base: prInfo.base,
15239
+ authorAssociation: prInfo.authorAssociation
15240
+ },
15241
+ files: prInfo.files?.map((f) => ({
15242
+ filename: f.filename,
15243
+ status: f.status,
15244
+ additions: f.additions,
15245
+ deletions: f.deletions,
15246
+ changes: f.changes
15247
+ })) || [],
15248
+ env: this.buildSafeEnv(),
15249
+ memory: config.__memoryAccessor || {}
15250
+ };
15251
+ try {
15252
+ const result = compileAndRun(this.sandbox, expression, jsContext, {
15253
+ injectLog: true,
15254
+ wrapFunction: true,
15255
+ logPrefix: "[ai_allowed_tools_js]"
15256
+ });
15257
+ if (!Array.isArray(result)) {
15258
+ logger.warn(
15259
+ `[AICheckProvider] ai_allowed_tools_js must return an array, got ${typeof result}`
15260
+ );
15261
+ return null;
15262
+ }
15263
+ const tools = result.filter((item) => typeof item === "string");
15264
+ logger.debug(
15265
+ `[AICheckProvider] ai_allowed_tools_js evaluated to ${tools.length} tools: ${tools.join(", ")}`
15266
+ );
15267
+ return tools;
15268
+ } catch (error) {
15269
+ logger.error(
15270
+ `[AICheckProvider] Failed to evaluate ai_allowed_tools_js: ${error instanceof Error ? error.message : "Unknown error"}`
15271
+ );
15272
+ return null;
15273
+ }
15274
+ }
15090
15275
  /**
15091
15276
  * Build a safe subset of environment variables for sandbox access.
15092
15277
  * Excludes sensitive keys like API keys, secrets, tokens.
@@ -15148,6 +15333,22 @@ ${processedPrompt}` : processedPrompt;
15148
15333
  }
15149
15334
  return tools;
15150
15335
  }
15336
+ /**
15337
+ * Intersect config-level allowedTools with policy-level allowedTools.
15338
+ * When the config list contains glob patterns ("*", "!" exclusions),
15339
+ * it is passed through unchanged — ProbeAgent resolves those patterns.
15340
+ * Literal tool name lists are intersected normally.
15341
+ */
15342
+ static intersectAllowedTools(configTools, policyTools) {
15343
+ if (!configTools) {
15344
+ return policyTools;
15345
+ }
15346
+ const hasGlobs = configTools.some((t) => t === "*" || t.startsWith("!"));
15347
+ if (hasGlobs) {
15348
+ return configTools;
15349
+ }
15350
+ return configTools.filter((t) => policyTools.includes(t));
15351
+ }
15151
15352
  getSupportedConfigKeys() {
15152
15353
  return [
15153
15354
  "type",
@@ -15163,6 +15364,7 @@ ${processedPrompt}` : processedPrompt;
15163
15364
  "ai.mcpServers",
15164
15365
  "ai.enableDelegate",
15165
15366
  "ai.enableTasks",
15367
+ "ai.enableExecutePlan",
15166
15368
  // legacy persona/prompt keys supported in config
15167
15369
  "ai_persona",
15168
15370
  "ai_prompt_type",
@@ -15184,6 +15386,7 @@ ${processedPrompt}` : processedPrompt;
15184
15386
  "ai_custom_tools",
15185
15387
  "ai_custom_tools_js",
15186
15388
  "ai_bash_config_js",
15389
+ "ai_allowed_tools_js",
15187
15390
  "env"
15188
15391
  ];
15189
15392
  }
@@ -17531,19 +17734,7 @@ var init_command_check_provider = __esm({
17531
17734
  }
17532
17735
  }
17533
17736
  const timeoutMs = config.timeout || 6e4;
17534
- const normalizeNodeEval = (cmd) => {
17535
- const re = /^(?<prefix>\s*(?:\/usr\/bin\/env\s+)?node(?:\.exe)?\s+(?:-e|--eval)\s+)(['"])([\s\S]*?)\2(?<suffix>\s|$)/;
17536
- const m = cmd.match(re);
17537
- if (!m || !m.groups) return cmd;
17538
- const prefix = m.groups.prefix;
17539
- const quote = m[2];
17540
- const code = m[3];
17541
- const suffix = m.groups.suffix || "";
17542
- if (!code.includes("\n")) return cmd;
17543
- const escaped = code.replace(/\n/g, "\\n");
17544
- return cmd.replace(re, `${prefix}${quote}${escaped}${quote}${suffix}`);
17545
- };
17546
- const safeCommand = normalizeNodeEval(renderedCommand);
17737
+ const safeCommand = renderedCommand;
17547
17738
  const parentContext = context2?._parentContext;
17548
17739
  const workingDirectory = parentContext?.workingDirectory;
17549
17740
  const workspaceEnabled = parentContext?.workspace?.isEnabled?.();
@@ -39747,6 +39938,20 @@ var init_workflow_check_provider = __esm({
39747
39938
  `[WorkflowProvider] Workflow '${workflow.id}' has null/undefined outputs: [${nullOutputs.join(", ")}]. This may indicate value_js expressions are not finding expected data.`
39748
39939
  );
39749
39940
  }
39941
+ if (!outputs._rawOutput) {
39942
+ const rawParts = [];
39943
+ for (const stepOutput of Object.values(outputsMap)) {
39944
+ if (stepOutput && typeof stepOutput === "object" && typeof stepOutput._rawOutput === "string") {
39945
+ rawParts.push(stepOutput._rawOutput);
39946
+ }
39947
+ }
39948
+ if (rawParts.length > 0) {
39949
+ outputs._rawOutput = rawParts.join("\n\n");
39950
+ logger.debug(
39951
+ `[WorkflowProvider] Propagated _rawOutput from steps (${rawParts.length} blocks, ${outputs._rawOutput.length} chars)`
39952
+ );
39953
+ }
39954
+ }
39750
39955
  return outputs;
39751
39956
  }
39752
39957
  /**
@@ -39893,4 +40098,4 @@ undici/lib/fetch/body.js:
39893
40098
  undici/lib/websocket/frame.js:
39894
40099
  (*! ws. MIT License. Einar Otto Stangvik <einaros@gmail.com> *)
39895
40100
  */
39896
- //# sourceMappingURL=chunk-MQ57AB4U.mjs.map
40101
+ //# sourceMappingURL=chunk-XGI47XIH.mjs.map