@probelabs/visor 0.1.130 → 0.1.131

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 (134) hide show
  1. package/README.md +7 -0
  2. package/defaults/visor.yaml +5 -2
  3. package/dist/ai-review-service.d.ts +2 -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/cli.d.ts.map +1 -1
  7. package/dist/config/cli-handler.d.ts +5 -0
  8. package/dist/config/cli-handler.d.ts.map +1 -0
  9. package/dist/config/config-reloader.d.ts +24 -0
  10. package/dist/config/config-reloader.d.ts.map +1 -0
  11. package/dist/config/config-snapshot-store.d.ts +21 -0
  12. package/dist/config/config-snapshot-store.d.ts.map +1 -0
  13. package/dist/config/config-watcher.d.ts +19 -0
  14. package/dist/config/config-watcher.d.ts.map +1 -0
  15. package/dist/config/types.d.ts +16 -0
  16. package/dist/config/types.d.ts.map +1 -0
  17. package/dist/defaults/visor.yaml +5 -2
  18. package/dist/docs/ai-configuration.md +139 -0
  19. package/dist/docs/ai-custom-tools.md +30 -0
  20. package/dist/docs/capacity-planning.md +359 -0
  21. package/dist/docs/commands.md +35 -0
  22. package/dist/docs/database-operations.md +487 -0
  23. package/dist/docs/index.md +6 -1
  24. package/dist/docs/licensing.md +372 -0
  25. package/dist/docs/production-deployment.md +583 -0
  26. package/dist/examples/ai-with-bash.yaml +17 -0
  27. package/dist/generated/config-schema.d.ts +4 -0
  28. package/dist/generated/config-schema.d.ts.map +1 -1
  29. package/dist/index.js +9945 -10907
  30. package/dist/liquid-extensions.d.ts +7 -0
  31. package/dist/liquid-extensions.d.ts.map +1 -1
  32. package/dist/output/traces/{run-2026-02-11T16-20-59-999Z.ndjson → run-2026-02-15T19-14-20-379Z.ndjson} +84 -84
  33. package/dist/{traces/run-2026-02-11T16-21-47-711Z.ndjson → output/traces/run-2026-02-15T19-15-09-410Z.ndjson} +1019 -1019
  34. package/dist/providers/ai-check-provider.d.ts +5 -0
  35. package/dist/providers/ai-check-provider.d.ts.map +1 -1
  36. package/dist/providers/command-check-provider.d.ts.map +1 -1
  37. package/dist/providers/workflow-check-provider.d.ts.map +1 -1
  38. package/dist/scheduler/schedule-tool.d.ts.map +1 -1
  39. package/dist/sdk/{check-provider-registry-PANIXYRB.mjs → check-provider-registry-AAPPJ4CP.mjs} +7 -7
  40. package/dist/sdk/{check-provider-registry-M3Y6JMTW.mjs → check-provider-registry-S7BMQ2FC.mjs} +7 -7
  41. package/dist/sdk/check-provider-registry-ZOLEYDKM.mjs +28 -0
  42. package/dist/sdk/{chunk-VMLORODQ.mjs → chunk-2GCSK3PD.mjs} +4 -4
  43. package/dist/sdk/{chunk-EUUAQBTW.mjs → chunk-6ZZ4DPAA.mjs} +240 -48
  44. package/dist/sdk/chunk-6ZZ4DPAA.mjs.map +1 -0
  45. package/dist/sdk/{chunk-HOKQOO3G.mjs → chunk-EBTD2D4L.mjs} +2 -2
  46. package/dist/sdk/chunk-LDFUW34H.mjs +39912 -0
  47. package/dist/sdk/chunk-LDFUW34H.mjs.map +1 -0
  48. package/dist/sdk/{chunk-UCNT3PDT.mjs → chunk-LQ5B4T6L.mjs} +5 -1
  49. package/dist/sdk/chunk-LQ5B4T6L.mjs.map +1 -0
  50. package/dist/sdk/{chunk-S6CD7GFM.mjs → chunk-MQ57AB4U.mjs} +211 -35
  51. package/dist/sdk/chunk-MQ57AB4U.mjs.map +1 -0
  52. package/dist/sdk/chunk-N4I6ZDCJ.mjs +436 -0
  53. package/dist/sdk/chunk-N4I6ZDCJ.mjs.map +1 -0
  54. package/dist/sdk/chunk-OMFPM576.mjs +739 -0
  55. package/dist/sdk/chunk-OMFPM576.mjs.map +1 -0
  56. package/dist/sdk/chunk-RI77TA6V.mjs +436 -0
  57. package/dist/sdk/chunk-RI77TA6V.mjs.map +1 -0
  58. package/dist/sdk/chunk-VO4N6TEL.mjs +1502 -0
  59. package/dist/sdk/chunk-VO4N6TEL.mjs.map +1 -0
  60. package/dist/sdk/{chunk-V2IV3ILA.mjs → chunk-XJQKTK6V.mjs} +31 -5
  61. package/dist/sdk/chunk-XJQKTK6V.mjs.map +1 -0
  62. package/dist/sdk/{config-OGOS4ZU4.mjs → config-4EG7IQIU.mjs} +2 -2
  63. package/dist/sdk/{failure-condition-evaluator-HC3M5377.mjs → failure-condition-evaluator-GLHZZF47.mjs} +3 -3
  64. package/dist/sdk/failure-condition-evaluator-KN55WXRO.mjs +17 -0
  65. package/dist/sdk/{github-frontend-E2KJSC3Y.mjs → github-frontend-F4TE2JY7.mjs} +3 -3
  66. package/dist/sdk/github-frontend-HCOKL53D.mjs +1356 -0
  67. package/dist/sdk/github-frontend-HCOKL53D.mjs.map +1 -0
  68. package/dist/sdk/{host-EE6EJ2FM.mjs → host-SAT6RHDX.mjs} +2 -2
  69. package/dist/sdk/host-VA3ET7N6.mjs +63 -0
  70. package/dist/sdk/host-VA3ET7N6.mjs.map +1 -0
  71. package/dist/sdk/{liquid-extensions-E4EUOCES.mjs → liquid-extensions-YDIIH33Q.mjs} +2 -2
  72. package/dist/sdk/{routing-OZQWAGAI.mjs → routing-KFYQGOYU.mjs} +5 -5
  73. package/dist/sdk/routing-OXQKETSA.mjs +25 -0
  74. package/dist/sdk/{schedule-tool-handler-IEB2VS7O.mjs → schedule-tool-handler-G353DHS6.mjs} +7 -7
  75. package/dist/sdk/{schedule-tool-handler-B7TMSG6A.mjs → schedule-tool-handler-OQF57URO.mjs} +7 -7
  76. package/dist/sdk/schedule-tool-handler-PJVKWSYX.mjs +38 -0
  77. package/dist/sdk/schedule-tool-handler-PJVKWSYX.mjs.map +1 -0
  78. package/dist/sdk/sdk.d.mts +15 -0
  79. package/dist/sdk/sdk.d.ts +15 -0
  80. package/dist/sdk/sdk.js +621 -183
  81. package/dist/sdk/sdk.js.map +1 -1
  82. package/dist/sdk/sdk.mjs +6 -6
  83. package/dist/sdk/{trace-helpers-PP3YHTAM.mjs → trace-helpers-LOPBHYYX.mjs} +4 -2
  84. package/dist/sdk/trace-helpers-LOPBHYYX.mjs.map +1 -0
  85. package/dist/sdk/trace-helpers-R2ETIEC2.mjs +25 -0
  86. package/dist/sdk/trace-helpers-R2ETIEC2.mjs.map +1 -0
  87. package/dist/sdk/{workflow-check-provider-2ET3SFZH.mjs → workflow-check-provider-57KAR4Y4.mjs} +7 -7
  88. package/dist/sdk/workflow-check-provider-57KAR4Y4.mjs.map +1 -0
  89. package/dist/sdk/{workflow-check-provider-HB4XTD4Z.mjs → workflow-check-provider-LRWD52WN.mjs} +7 -7
  90. package/dist/sdk/workflow-check-provider-LRWD52WN.mjs.map +1 -0
  91. package/dist/sdk/workflow-check-provider-N2DRFQDB.mjs +28 -0
  92. package/dist/sdk/workflow-check-provider-N2DRFQDB.mjs.map +1 -0
  93. package/dist/slack/socket-runner.d.ts.map +1 -1
  94. package/dist/state-machine/context/build-engine-context.d.ts.map +1 -1
  95. package/dist/state-machine/runner.d.ts.map +1 -1
  96. package/dist/state-machine/states/completed.d.ts.map +1 -1
  97. package/dist/telemetry/trace-helpers.d.ts +5 -0
  98. package/dist/telemetry/trace-helpers.d.ts.map +1 -1
  99. package/dist/test-runner/evaluators.d.ts.map +1 -1
  100. package/dist/test-runner/index.d.ts +7 -0
  101. package/dist/test-runner/index.d.ts.map +1 -1
  102. package/dist/test-runner/validator.d.ts.map +1 -1
  103. package/dist/traces/{run-2026-02-11T16-20-59-999Z.ndjson → run-2026-02-15T19-14-20-379Z.ndjson} +84 -84
  104. package/dist/{output/traces/run-2026-02-11T16-21-47-711Z.ndjson → traces/run-2026-02-15T19-15-09-410Z.ndjson} +1019 -1019
  105. package/dist/tui/chat-runner.d.ts.map +1 -1
  106. package/dist/types/cli.d.ts +2 -0
  107. package/dist/types/cli.d.ts.map +1 -1
  108. package/dist/types/config.d.ts +15 -0
  109. package/dist/types/config.d.ts.map +1 -1
  110. package/dist/types/engine.d.ts +2 -0
  111. package/dist/types/engine.d.ts.map +1 -1
  112. package/package.json +3 -3
  113. package/defaults/.visor.yaml +0 -420
  114. package/dist/sdk/chunk-EUUAQBTW.mjs.map +0 -1
  115. package/dist/sdk/chunk-S6CD7GFM.mjs.map +0 -1
  116. package/dist/sdk/chunk-UCNT3PDT.mjs.map +0 -1
  117. package/dist/sdk/chunk-V2IV3ILA.mjs.map +0 -1
  118. package/dist/sdk/chunk-YJRBN3XS.mjs +0 -217
  119. package/dist/sdk/chunk-YJRBN3XS.mjs.map +0 -1
  120. /package/dist/sdk/{check-provider-registry-M3Y6JMTW.mjs.map → check-provider-registry-AAPPJ4CP.mjs.map} +0 -0
  121. /package/dist/sdk/{check-provider-registry-PANIXYRB.mjs.map → check-provider-registry-S7BMQ2FC.mjs.map} +0 -0
  122. /package/dist/sdk/{config-OGOS4ZU4.mjs.map → check-provider-registry-ZOLEYDKM.mjs.map} +0 -0
  123. /package/dist/sdk/{chunk-VMLORODQ.mjs.map → chunk-2GCSK3PD.mjs.map} +0 -0
  124. /package/dist/sdk/{chunk-HOKQOO3G.mjs.map → chunk-EBTD2D4L.mjs.map} +0 -0
  125. /package/dist/sdk/{failure-condition-evaluator-HC3M5377.mjs.map → config-4EG7IQIU.mjs.map} +0 -0
  126. /package/dist/sdk/{liquid-extensions-E4EUOCES.mjs.map → failure-condition-evaluator-GLHZZF47.mjs.map} +0 -0
  127. /package/dist/sdk/{routing-OZQWAGAI.mjs.map → failure-condition-evaluator-KN55WXRO.mjs.map} +0 -0
  128. /package/dist/sdk/{github-frontend-E2KJSC3Y.mjs.map → github-frontend-F4TE2JY7.mjs.map} +0 -0
  129. /package/dist/sdk/{host-EE6EJ2FM.mjs.map → host-SAT6RHDX.mjs.map} +0 -0
  130. /package/dist/sdk/{schedule-tool-handler-B7TMSG6A.mjs.map → liquid-extensions-YDIIH33Q.mjs.map} +0 -0
  131. /package/dist/sdk/{schedule-tool-handler-IEB2VS7O.mjs.map → routing-KFYQGOYU.mjs.map} +0 -0
  132. /package/dist/sdk/{trace-helpers-PP3YHTAM.mjs.map → routing-OXQKETSA.mjs.map} +0 -0
  133. /package/dist/sdk/{workflow-check-provider-2ET3SFZH.mjs.map → schedule-tool-handler-G353DHS6.mjs.map} +0 -0
  134. /package/dist/sdk/{workflow-check-provider-HB4XTD4Z.mjs.map → schedule-tool-handler-OQF57URO.mjs.map} +0 -0
@@ -28,7 +28,7 @@ import {
28
28
  import {
29
29
  config_exports,
30
30
  init_config
31
- } from "./chunk-UCNT3PDT.mjs";
31
+ } from "./chunk-LQ5B4T6L.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-VMLORODQ.mjs";
40
+ } from "./chunk-VO4N6TEL.mjs";
41
41
  import {
42
42
  FailureConditionEvaluator,
43
43
  init_failure_condition_evaluator
44
- } from "./chunk-HOKQOO3G.mjs";
44
+ } from "./chunk-OMFPM576.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-YJRBN3XS.mjs";
55
+ } from "./chunk-RI77TA6V.mjs";
56
56
  import {
57
57
  addDiagramBlock,
58
58
  init_metrics
@@ -60,7 +60,7 @@ import {
60
60
  import {
61
61
  createExtendedLiquid,
62
62
  init_liquid_extensions
63
- } from "./chunk-V2IV3ILA.mjs";
63
+ } from "./chunk-XJQKTK6V.mjs";
64
64
  import {
65
65
  createPermissionHelpers,
66
66
  detectLocalMode,
@@ -681,6 +681,8 @@ var init_ai_review_service = __esm({
681
681
  const isCodeReviewSchema = schema === "code-review";
682
682
  const prContext = skipPRContext ? "" : await this.formatPRContext(prInfo, isCodeReviewSchema);
683
683
  const slackContextXml = skipSlackContext === true ? "" : this.formatSlackContextFromPRInfo(prInfo);
684
+ const traceIdXml = prInfo.otelTraceId ? `
685
+ <trace_id>${this.escapeXml(String(prInfo.otelTraceId))}</trace_id>` : "";
684
686
  const isIssue = prInfo.isIssue === true;
685
687
  if (isIssue) {
686
688
  if (skipPRContext && !slackContextXml) {
@@ -694,7 +696,7 @@ ${customInstructions}
694
696
  </instructions>
695
697
 
696
698
  <context>
697
- ${getCurrentDateXml()}
699
+ ${getCurrentDateXml()}${traceIdXml}
698
700
  ${prContext}${slackContextXml}
699
701
  </context>
700
702
 
@@ -736,7 +738,7 @@ ${customInstructions}
736
738
  </instructions>
737
739
 
738
740
  <context>
739
- ${getCurrentDateXml()}
741
+ ${getCurrentDateXml()}${traceIdXml}
740
742
  ${prContext}${slackContextXml}
741
743
  </context>
742
744
 
@@ -764,7 +766,7 @@ ${customInstructions}
764
766
  </instructions>
765
767
 
766
768
  <context>
767
- ${getCurrentDateXml()}
769
+ ${getCurrentDateXml()}${traceIdXml}
768
770
  ${prContext}${slackContextXml}
769
771
  </context>`;
770
772
  }
@@ -1598,6 +1600,9 @@ ${"=".repeat(60)}
1598
1600
  if (this.config.completionPrompt !== void 0) {
1599
1601
  options.completionPrompt = this.config.completionPrompt;
1600
1602
  }
1603
+ if (this.config.concurrencyLimiter) {
1604
+ options.concurrencyLimiter = this.config.concurrencyLimiter;
1605
+ }
1601
1606
  try {
1602
1607
  const cfgAny = this.config;
1603
1608
  const allowedFolders = cfgAny.allowedFolders;
@@ -2997,7 +3002,7 @@ async function executeWorkflowAsTool(workflowId, args, context2, argsOverrides)
2997
3002
  ...args,
2998
3003
  ...argsOverrides
2999
3004
  };
3000
- const { WorkflowCheckProvider: WorkflowCheckProvider2 } = await import("./workflow-check-provider-2ET3SFZH.mjs");
3005
+ const { WorkflowCheckProvider: WorkflowCheckProvider2 } = await import("./workflow-check-provider-N2DRFQDB.mjs");
3001
3006
  const provider = new WorkflowCheckProvider2();
3002
3007
  const checkConfig = {
3003
3008
  type: "workflow",
@@ -3996,7 +4001,7 @@ function formatScheduleList(schedules) {
3996
4001
  if (schedules.length === 0) {
3997
4002
  return `You don't have any active schedules.
3998
4003
 
3999
- To create one: "schedule daily-report every Monday at 9am"`;
4004
+ To create one: "remind me every Monday at 9am to check PRs" or "schedule %daily-report every Monday at 9am"`;
4000
4005
  }
4001
4006
  const lines = schedules.map((s, i) => `${i + 1}. ${formatSchedule(s)}`);
4002
4007
  return `**Your active schedules:**
@@ -4272,6 +4277,12 @@ function getScheduleToolDefinition() {
4272
4277
 
4273
4278
  YOU (the AI) must extract and structure all scheduling parameters. Do NOT pass natural language time expressions - convert them to cron or ISO timestamps.
4274
4279
 
4280
+ CRITICAL WORKFLOW RULE:
4281
+ - To schedule a WORKFLOW, the user MUST use a '%' prefix (e.g., "schedule %my-workflow daily").
4282
+ - If the '%' prefix is present, extract the word following it as the 'workflow' parameter (without the '%').
4283
+ - If the '%' prefix is NOT present, the request is a simple text reminder. The ENTIRE user request (excluding the schedule expression) MUST be placed in the 'reminder_text' parameter.
4284
+ - DO NOT guess or infer a workflow name from a user's request without the '%' prefix.
4285
+
4275
4286
  ACTIONS:
4276
4287
  - create: Schedule a new reminder or workflow
4277
4288
  - list: Show user's active schedules
@@ -4279,7 +4290,9 @@ ACTIONS:
4279
4290
  - pause/resume: Temporarily disable/enable a schedule
4280
4291
 
4281
4292
  FOR CREATE ACTION - Extract these from user's request:
4282
- 1. WHAT: Either reminder_text (message to send) OR workflow (workflow ID to run)
4293
+ 1. WHAT:
4294
+ - If user says "schedule %some-workflow ...", populate 'workflow' with "some-workflow".
4295
+ - Otherwise, populate 'reminder_text' with the user's full request text.
4283
4296
  2. WHERE: Use the CURRENT channel from context
4284
4297
  - target_id: The channel ID from context (C... for channels, D... for DMs)
4285
4298
  - target_type: "channel" for public/private channels, "dm" for direct messages
@@ -4314,7 +4327,7 @@ User in DM: "remind me to check builds every day at 9am"
4314
4327
  "original_expression": "every day at 9am"
4315
4328
  }
4316
4329
 
4317
- User in #security channel: "run security-scan every Monday at 10am"
4330
+ User in #security channel: "schedule %security-scan every Monday at 10am"
4318
4331
  \u2192 {
4319
4332
  "action": "create",
4320
4333
  "workflow": "security-scan",
@@ -4325,6 +4338,17 @@ User in #security channel: "run security-scan every Monday at 10am"
4325
4338
  "original_expression": "every Monday at 10am"
4326
4339
  }
4327
4340
 
4341
+ User in #security channel: "run security-scan every Monday at 10am" (NO % prefix!)
4342
+ \u2192 {
4343
+ "action": "create",
4344
+ "reminder_text": "run security-scan every Monday at 10am",
4345
+ "is_recurring": true,
4346
+ "cron": "0 10 * * 1",
4347
+ "target_type": "channel",
4348
+ "target_id": "<channel ID from context, e.g., C05ABC123>",
4349
+ "original_expression": "every Monday at 10am"
4350
+ }
4351
+
4328
4352
  User in DM: "remind me in 2 hours to review the PR"
4329
4353
  \u2192 {
4330
4354
  "action": "create",
@@ -4368,7 +4392,7 @@ User: "cancel schedule abc123"
4368
4392
  },
4369
4393
  workflow: {
4370
4394
  type: "string",
4371
- description: "For create: workflow/check ID to run (use instead of reminder_text for workflow execution)"
4395
+ description: 'For create: workflow ID to run. ONLY populate this if the user used the % prefix (e.g., "%my-workflow"). Extract the name without the % symbol. If no % prefix, use reminder_text instead.'
4372
4396
  },
4373
4397
  workflow_inputs: {
4374
4398
  type: "object",
@@ -5978,7 +6002,7 @@ var init_dependency_gating = __esm({
5978
6002
  // src/state-machine/dispatch/template-renderer.ts
5979
6003
  async function renderTemplateContent(checkId, checkConfig, reviewSummary) {
5980
6004
  try {
5981
- const { createExtendedLiquid: createExtendedLiquid2 } = await import("./liquid-extensions-E4EUOCES.mjs");
6005
+ const { createExtendedLiquid: createExtendedLiquid2 } = await import("./liquid-extensions-YDIIH33Q.mjs");
5982
6006
  const fs11 = await import("fs/promises");
5983
6007
  const path14 = await import("path");
5984
6008
  const schemaRaw = checkConfig.schema || "plain";
@@ -8690,7 +8714,7 @@ async function executeCheckWithForEachItems2(checkId, forEachParent, forEachItem
8690
8714
  }
8691
8715
  }
8692
8716
  try {
8693
- const { evaluateTransitions } = await import("./routing-OZQWAGAI.mjs");
8717
+ const { evaluateTransitions } = await import("./routing-KFYQGOYU.mjs");
8694
8718
  const transTarget = await evaluateTransitions(
8695
8719
  onFinish.transitions,
8696
8720
  forEachParent,
@@ -8750,7 +8774,7 @@ async function executeCheckWithForEachItems2(checkId, forEachParent, forEachItem
8750
8774
  `[LevelDispatch] Error evaluating on_finish transitions for ${forEachParent}: ${e instanceof Error ? e.message : String(e)}`
8751
8775
  );
8752
8776
  }
8753
- const { evaluateGoto: evaluateGoto2 } = await import("./routing-OZQWAGAI.mjs");
8777
+ const { evaluateGoto: evaluateGoto2 } = await import("./routing-KFYQGOYU.mjs");
8754
8778
  if (context2.debug) {
8755
8779
  logger.info(
8756
8780
  `[LevelDispatch] Evaluating on_finish.goto_js for forEach parent: ${forEachParent}`
@@ -10002,7 +10026,7 @@ function updateStats2(results, state, isForEachIteration = false) {
10002
10026
  }
10003
10027
  async function renderTemplateContent2(checkId, checkConfig, reviewSummary) {
10004
10028
  try {
10005
- const { createExtendedLiquid: createExtendedLiquid2 } = await import("./liquid-extensions-E4EUOCES.mjs");
10029
+ const { createExtendedLiquid: createExtendedLiquid2 } = await import("./liquid-extensions-YDIIH33Q.mjs");
10006
10030
  const fs11 = await import("fs/promises");
10007
10031
  const path14 = await import("path");
10008
10032
  const schemaRaw = checkConfig.schema || "plain";
@@ -10233,6 +10257,9 @@ var init_runner = __esm({
10233
10257
  break;
10234
10258
  }
10235
10259
  }
10260
+ if (this.state.currentState === "Completed" && !this.context._parentContext && !process.env.VISOR_TEST_MODE) {
10261
+ logger.info("All workflows finished \u2014 waiting for events");
10262
+ }
10236
10263
  return this.buildExecutionResult();
10237
10264
  } catch (error) {
10238
10265
  const errorMsg = error instanceof Error ? error.message : String(error);
@@ -11690,6 +11717,17 @@ function buildEngineContextForRun(workingDirectory, config, prInfo, debug, maxPa
11690
11717
  }
11691
11718
  const journal = new ExecutionJournal();
11692
11719
  const memory = MemoryStore.getInstance(clonedConfig.memory);
11720
+ let sharedConcurrencyLimiter = void 0;
11721
+ if (clonedConfig.max_ai_concurrency && _DelegationManager) {
11722
+ sharedConcurrencyLimiter = new _DelegationManager({
11723
+ maxConcurrent: clonedConfig.max_ai_concurrency,
11724
+ maxPerSession: 999
11725
+ // No per-session limit needed for global AI gating
11726
+ });
11727
+ logger.debug(
11728
+ `[EngineContext] Created shared AI concurrency limiter (max: ${clonedConfig.max_ai_concurrency})`
11729
+ );
11730
+ }
11693
11731
  return {
11694
11732
  mode: "state-machine",
11695
11733
  config: clonedConfig,
@@ -11702,6 +11740,7 @@ function buildEngineContextForRun(workingDirectory, config, prInfo, debug, maxPa
11702
11740
  event: prInfo.eventType,
11703
11741
  debug,
11704
11742
  maxParallelism,
11743
+ sharedConcurrencyLimiter,
11705
11744
  failFast,
11706
11745
  requestedChecks: requestedChecks && requestedChecks.length > 0 ? requestedChecks : void 0,
11707
11746
  // Store prInfo for later access (e.g., in getOutputHistorySnapshot)
@@ -11748,6 +11787,7 @@ async function initializeWorkspace(context2) {
11748
11787
  return context2;
11749
11788
  }
11750
11789
  }
11790
+ var _DelegationManager;
11751
11791
  var init_build_engine_context = __esm({
11752
11792
  "src/state-machine/context/build-engine-context.ts"() {
11753
11793
  "use strict";
@@ -11756,6 +11796,14 @@ var init_build_engine_context = __esm({
11756
11796
  init_human_id();
11757
11797
  init_logger();
11758
11798
  init_workspace_manager();
11799
+ _DelegationManager = null;
11800
+ try {
11801
+ const probe = __require("@probelabs/probe");
11802
+ if (probe && typeof probe.DelegationManager === "function") {
11803
+ _DelegationManager = probe.DelegationManager;
11804
+ }
11805
+ } catch {
11806
+ }
11759
11807
  }
11760
11808
  });
11761
11809
 
@@ -11899,7 +11947,7 @@ var init_state_machine_execution_engine = __esm({
11899
11947
  try {
11900
11948
  const map = options?.webhookContext?.webhookData;
11901
11949
  if (map) {
11902
- const { CheckProviderRegistry: CheckProviderRegistry2 } = await import("./check-provider-registry-M3Y6JMTW.mjs");
11950
+ const { CheckProviderRegistry: CheckProviderRegistry2 } = await import("./check-provider-registry-S7BMQ2FC.mjs");
11903
11951
  const reg = CheckProviderRegistry2.getInstance();
11904
11952
  const p = reg.getProvider("http_input");
11905
11953
  if (p && typeof p.setWebhookContext === "function") p.setWebhookContext(map);
@@ -12012,7 +12060,7 @@ var init_state_machine_execution_engine = __esm({
12012
12060
  logger.info("[StateMachine] Using state machine engine");
12013
12061
  }
12014
12062
  if (!config) {
12015
- const { ConfigManager } = await import("./config-OGOS4ZU4.mjs");
12063
+ const { ConfigManager } = await import("./config-4EG7IQIU.mjs");
12016
12064
  const configManager = new ConfigManager();
12017
12065
  config = await configManager.getDefaultConfig();
12018
12066
  logger.debug("[StateMachine] Using default configuration (no config provided)");
@@ -12077,7 +12125,7 @@ var init_state_machine_execution_engine = __esm({
12077
12125
  try {
12078
12126
  const webhookData = this.executionContext?.webhookContext?.webhookData;
12079
12127
  if (webhookData instanceof Map) {
12080
- const { extractSlackContext: extractSlackContext2 } = await import("./schedule-tool-handler-IEB2VS7O.mjs");
12128
+ const { extractSlackContext: extractSlackContext2 } = await import("./schedule-tool-handler-G353DHS6.mjs");
12081
12129
  const slackCtx = extractSlackContext2(webhookData);
12082
12130
  if (slackCtx) {
12083
12131
  const payload = Array.from(webhookData.values())[0];
@@ -12106,7 +12154,7 @@ var init_state_machine_execution_engine = __esm({
12106
12154
  if (Array.isArray(configWithTagFilter.frontends) && configWithTagFilter.frontends.length > 0) {
12107
12155
  try {
12108
12156
  const { EventBus } = await import("./event-bus-5K3Y2FCS.mjs");
12109
- const { FrontendsHost } = await import("./host-EE6EJ2FM.mjs");
12157
+ const { FrontendsHost } = await import("./host-SAT6RHDX.mjs");
12110
12158
  const bus = new EventBus();
12111
12159
  context2.eventBus = bus;
12112
12160
  frontendsHost = new FrontendsHost(bus, logger);
@@ -12456,9 +12504,9 @@ var init_state_machine_execution_engine = __esm({
12456
12504
  * @returns Array of failure condition evaluation results
12457
12505
  */
12458
12506
  async evaluateFailureConditions(checkName, reviewSummary, config, previousOutputs, authorAssociation) {
12459
- const { FailureConditionEvaluator: FailureConditionEvaluator2 } = await import("./failure-condition-evaluator-HC3M5377.mjs");
12507
+ const { FailureConditionEvaluator: FailureConditionEvaluator2 } = await import("./failure-condition-evaluator-KN55WXRO.mjs");
12460
12508
  const evaluator = new FailureConditionEvaluator2();
12461
- const { addEvent: addEvent3 } = await import("./trace-helpers-PP3YHTAM.mjs");
12509
+ const { addEvent: addEvent3 } = await import("./trace-helpers-LOPBHYYX.mjs");
12462
12510
  const { addFailIfTriggered } = await import("./metrics-I6A7IHG4.mjs");
12463
12511
  const checkConfig = config.checks?.[checkName];
12464
12512
  if (!checkConfig) {
@@ -13507,16 +13555,13 @@ var init_mcp_custom_sse_server = __esm({
13507
13555
  logger.error(
13508
13556
  `[CustomToolsSSEServer:${this.sessionId}] Tool execution failed: ${toolName} - ${errorMsg}`
13509
13557
  );
13558
+ const isValidationError = errorMsg.startsWith("Invalid workflow inputs:");
13510
13559
  return {
13511
13560
  jsonrpc: "2.0",
13512
13561
  id,
13513
13562
  error: {
13514
- code: -32603,
13515
- message: "Internal error",
13516
- data: {
13517
- tool: toolName,
13518
- error: errorMsg
13519
- }
13563
+ code: isValidationError ? -32602 : -32603,
13564
+ message: isValidationError ? `Invalid tool parameters: ${errorMsg}` : `Internal error during tool execution: ${errorMsg}`
13520
13565
  }
13521
13566
  };
13522
13567
  } finally {
@@ -14282,6 +14327,10 @@ ${preview}`);
14282
14327
  if (config.ai_max_iterations !== void 0 && aiConfig.maxIterations === void 0) {
14283
14328
  aiConfig.maxIterations = config.ai_max_iterations;
14284
14329
  }
14330
+ const sharedLimiter = sessionInfo?._parentContext?.sharedConcurrencyLimiter;
14331
+ if (sharedLimiter) {
14332
+ aiConfig.concurrencyLimiter = sharedLimiter;
14333
+ }
14285
14334
  const policyEngine = sessionInfo?._parentContext?.policyEngine;
14286
14335
  if (policyEngine) {
14287
14336
  try {
@@ -14513,13 +14562,13 @@ ${preview}`);
14513
14562
  `[AICheckProvider] Started custom tools SSE server '${customToolsServerName}' on port ${port} for ${customTools.size} tools`
14514
14563
  );
14515
14564
  }
14565
+ const workflowToolTimeout = config.ai?.timeout || 18e5;
14516
14566
  mcpServers[customToolsServerName] = {
14517
14567
  command: "",
14518
14568
  args: [],
14519
14569
  url: `http://localhost:${port}/sse`,
14520
14570
  transport: "sse",
14521
- timeout: 6e5
14522
- // 10 minutes for workflow tools
14571
+ timeout: workflowToolTimeout
14523
14572
  };
14524
14573
  }
14525
14574
  } catch (error) {
@@ -14532,6 +14581,37 @@ ${preview}`);
14532
14581
  aiConfig.mcpServers = mcpServers;
14533
14582
  } else if (config.ai?.disableTools) {
14534
14583
  }
14584
+ const bashConfigJsExpr = config.ai_bash_config_js;
14585
+ if (bashConfigJsExpr && _dependencyResults) {
14586
+ try {
14587
+ const dynamicBashConfig = this.evaluateBashConfigJs(
14588
+ bashConfigJsExpr,
14589
+ prInfo,
14590
+ _dependencyResults,
14591
+ config
14592
+ );
14593
+ if (!aiConfig.bashConfig) aiConfig.bashConfig = {};
14594
+ if (dynamicBashConfig.allow?.length) {
14595
+ aiConfig.bashConfig.allow = [
14596
+ ...aiConfig.bashConfig.allow || [],
14597
+ ...dynamicBashConfig.allow
14598
+ ];
14599
+ }
14600
+ if (dynamicBashConfig.deny?.length) {
14601
+ aiConfig.bashConfig.deny = [
14602
+ ...aiConfig.bashConfig.deny || [],
14603
+ ...dynamicBashConfig.deny
14604
+ ];
14605
+ }
14606
+ if (dynamicBashConfig.allow?.length || dynamicBashConfig.deny?.length) {
14607
+ aiConfig.allowBash = true;
14608
+ }
14609
+ } catch (error) {
14610
+ logger.error(
14611
+ `[AICheckProvider] Failed to evaluate ai_bash_config_js: ${error instanceof Error ? error.message : "Unknown error"}`
14612
+ );
14613
+ }
14614
+ }
14535
14615
  const templateContext = {
14536
14616
  pr: {
14537
14617
  number: prInfo.number,
@@ -14553,6 +14633,10 @@ ${preview}`);
14553
14633
  const span = trace.getSpan(context.active());
14554
14634
  if (span) {
14555
14635
  captureCheckInputContext(span, templateContext);
14636
+ const spanTraceId = span.spanContext()?.traceId;
14637
+ if (spanTraceId) {
14638
+ prInfo.otelTraceId = spanTraceId;
14639
+ }
14556
14640
  }
14557
14641
  } catch {
14558
14642
  }
@@ -14957,6 +15041,80 @@ ${processedPrompt}` : processedPrompt;
14957
15041
  return {};
14958
15042
  }
14959
15043
  }
15044
+ /**
15045
+ * Evaluate ai_bash_config_js expression to dynamically compute bash configuration.
15046
+ * Returns a partial BashConfig object with optional allow/deny arrays.
15047
+ */
15048
+ evaluateBashConfigJs(expression, prInfo, dependencyResults, config) {
15049
+ if (!this.sandbox) {
15050
+ this.sandbox = createSecureSandbox();
15051
+ }
15052
+ const outputs = {};
15053
+ for (const [checkId, result] of dependencyResults.entries()) {
15054
+ const summary = result;
15055
+ outputs[checkId] = summary.output !== void 0 ? summary.output : summary;
15056
+ }
15057
+ const jsContext = {
15058
+ outputs,
15059
+ inputs: config.inputs || {},
15060
+ pr: {
15061
+ number: prInfo.number,
15062
+ title: prInfo.title,
15063
+ description: prInfo.body,
15064
+ author: prInfo.author,
15065
+ branch: prInfo.head,
15066
+ base: prInfo.base,
15067
+ authorAssociation: prInfo.authorAssociation
15068
+ },
15069
+ files: prInfo.files?.map((f) => ({
15070
+ filename: f.filename,
15071
+ status: f.status,
15072
+ additions: f.additions,
15073
+ deletions: f.deletions,
15074
+ changes: f.changes
15075
+ })) || [],
15076
+ env: this.buildSafeEnv(),
15077
+ memory: config.__memoryAccessor || {}
15078
+ };
15079
+ try {
15080
+ const result = compileAndRun(this.sandbox, expression, jsContext, {
15081
+ injectLog: true,
15082
+ wrapFunction: true,
15083
+ logPrefix: "[ai_bash_config_js]"
15084
+ });
15085
+ if (typeof result !== "object" || result === null || Array.isArray(result)) {
15086
+ logger.warn(
15087
+ `[AICheckProvider] ai_bash_config_js must return an object, got ${Array.isArray(result) ? "array" : typeof result}`
15088
+ );
15089
+ return {};
15090
+ }
15091
+ const cfg = result;
15092
+ const validConfig = {};
15093
+ if (cfg.allow !== void 0) {
15094
+ if (Array.isArray(cfg.allow) && cfg.allow.every((item) => typeof item === "string")) {
15095
+ validConfig.allow = cfg.allow;
15096
+ } else {
15097
+ logger.warn(`[AICheckProvider] ai_bash_config_js: 'allow' must be a string array`);
15098
+ }
15099
+ }
15100
+ if (cfg.deny !== void 0) {
15101
+ if (Array.isArray(cfg.deny) && cfg.deny.every((item) => typeof item === "string")) {
15102
+ validConfig.deny = cfg.deny;
15103
+ } else {
15104
+ logger.warn(`[AICheckProvider] ai_bash_config_js: 'deny' must be a string array`);
15105
+ }
15106
+ }
15107
+ logger.debug(
15108
+ `[AICheckProvider] ai_bash_config_js evaluated: allow=${validConfig.allow?.length ?? 0}, deny=${validConfig.deny?.length ?? 0}`
15109
+ );
15110
+ return validConfig;
15111
+ } catch (error) {
15112
+ logger.error(
15113
+ `[AICheckProvider] Failed to evaluate ai_bash_config_js: ${error instanceof Error ? error.message : "Unknown error"}`
15114
+ );
15115
+ return {};
15116
+ }
15117
+ }
14960
15118
  /**
14961
15119
  * Build a safe subset of environment variables for sandbox access.
14962
15120
  * Excludes sensitive keys like API keys, secrets, tokens.
@@ -15053,6 +15211,7 @@ ${processedPrompt}` : processedPrompt;
15053
15211
  "ai_mcp_servers_js",
15054
15212
  "ai_custom_tools",
15055
15213
  "ai_custom_tools_js",
15214
+ "ai_bash_config_js",
15056
15215
  "env"
15057
15216
  ];
15058
15217
  }
@@ -17400,19 +17559,7 @@ var init_command_check_provider = __esm({
17400
17559
  }
17401
17560
  }
17402
17561
  const timeoutMs = config.timeout || 6e4;
17403
- const normalizeNodeEval = (cmd) => {
17404
- const re = /^(?<prefix>\s*(?:\/usr\/bin\/env\s+)?node(?:\.exe)?\s+(?:-e|--eval)\s+)(['"])([\s\S]*?)\2(?<suffix>\s|$)/;
17405
- const m = cmd.match(re);
17406
- if (!m || !m.groups) return cmd;
17407
- const prefix = m.groups.prefix;
17408
- const quote = m[2];
17409
- const code = m[3];
17410
- const suffix = m.groups.suffix || "";
17411
- if (!code.includes("\n")) return cmd;
17412
- const escaped = code.replace(/\n/g, "\\n");
17413
- return cmd.replace(re, `${prefix}${quote}${escaped}${quote}${suffix}`);
17414
- };
17415
- const safeCommand = normalizeNodeEval(renderedCommand);
17562
+ const safeCommand = renderedCommand;
17416
17563
  const parentContext = context2?._parentContext;
17417
17564
  const workingDirectory = parentContext?.workingDirectory;
17418
17565
  const workspaceEnabled = parentContext?.workspace?.isEnabled?.();
@@ -39395,6 +39542,31 @@ var init_workflow_check_provider = __esm({
39395
39542
  `[WorkflowProvider] NO WORKSPACE from parent - nested checkouts won't be added to workspace!`
39396
39543
  );
39397
39544
  }
39545
+ const stepPrefix = config.checkName || workflow.id;
39546
+ const parentExecCtx = parentContext?.executionContext;
39547
+ let childExecCtx = parentExecCtx;
39548
+ if (parentExecCtx?.hooks) {
39549
+ const parentHooks = parentExecCtx.hooks;
39550
+ childExecCtx = {
39551
+ ...parentExecCtx,
39552
+ hooks: {
39553
+ ...parentHooks,
39554
+ // Wrap onPromptCaptured: emit with prefixed step name so parent sees "route-intent.classify"
39555
+ onPromptCaptured: parentHooks.onPromptCaptured ? (info) => {
39556
+ parentHooks.onPromptCaptured({
39557
+ ...info,
39558
+ step: `${stepPrefix}.${info.step}`
39559
+ });
39560
+ } : void 0,
39561
+ // Wrap mockForStep: try prefixed name first, fall back to unprefixed for backward compat
39562
+ mockForStep: parentHooks.mockForStep ? (step) => {
39563
+ const prefixed = parentHooks.mockForStep(`${stepPrefix}.${step}`);
39564
+ if (prefixed !== void 0) return prefixed;
39565
+ return parentHooks.mockForStep(step);
39566
+ } : void 0
39567
+ }
39568
+ };
39569
+ }
39398
39570
  const childContext = {
39399
39571
  mode: "state-machine",
39400
39572
  config: workflowConfig,
@@ -39416,9 +39588,9 @@ var init_workflow_check_provider = __esm({
39416
39588
  debug: parentContext?.debug || false,
39417
39589
  maxParallelism: parentContext?.maxParallelism,
39418
39590
  failFast: parentContext?.failFast,
39419
- // Propagate execution hooks (mocks, octokit, etc.) into the child so
39420
- // nested steps can be mocked/observed by the YAML test runner.
39421
- executionContext: parentContext?.executionContext,
39591
+ // Propagate wrapped execution hooks (mocks, octokit, etc.) into the child so
39592
+ // nested steps can be mocked/observed by the YAML test runner with dotted prefixes.
39593
+ executionContext: childExecCtx,
39422
39594
  // Ensure all workflow steps are considered requested to avoid tag/event filtering surprises
39423
39595
  requestedChecks: Object.keys(checksMetadata)
39424
39596
  };
@@ -39432,6 +39604,26 @@ var init_workflow_check_provider = __esm({
39432
39604
  `[WorkflowProvider] Executing nested workflow '${workflow.id}' at depth ${currentDepth + 1}`
39433
39605
  );
39434
39606
  const result = await runner.run();
39607
+ if (parentContext?.journal && parentContext?.sessionId) {
39608
+ const parentJournal = parentContext.journal;
39609
+ const childSnapshot = childJournal.beginSnapshot();
39610
+ const childSessionId = childContext.sessionId;
39611
+ const childEntries = childJournal.readVisible(childSessionId, childSnapshot, void 0);
39612
+ for (const entry of childEntries) {
39613
+ parentJournal.commitEntry({
39614
+ sessionId: parentContext.sessionId,
39615
+ scope: entry.scope,
39616
+ checkId: `${stepPrefix}.${entry.checkId}`,
39617
+ result: entry.result,
39618
+ event: entry.event
39619
+ });
39620
+ }
39621
+ if (childEntries.length > 0) {
39622
+ logger.debug(
39623
+ `[WorkflowProvider] Propagated ${childEntries.length} child journal entries to parent with prefix '${stepPrefix}.'`
39624
+ );
39625
+ }
39626
+ }
39435
39627
  const bubbledEvents = childContext._bubbledEvents || [];
39436
39628
  if (bubbledEvents.length > 0 && parentContext) {
39437
39629
  if (parentContext.debug) {
@@ -39717,4 +39909,4 @@ undici/lib/fetch/body.js:
39717
39909
  undici/lib/websocket/frame.js:
39718
39910
  (*! ws. MIT License. Einar Otto Stangvik <einaros@gmail.com> *)
39719
39911
  */
39720
- //# sourceMappingURL=chunk-EUUAQBTW.mjs.map
39912
+ //# sourceMappingURL=chunk-6ZZ4DPAA.mjs.map