@probelabs/visor 0.1.186 → 0.1.187

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 (395) hide show
  1. package/defaults/assistant.yaml +31 -0
  2. package/defaults/code-talk.yaml +32 -0
  3. package/defaults/skills/code-explorer.yaml +6 -0
  4. package/dist/action-cli-bridge.d.ts.map +1 -1
  5. package/dist/agent-protocol/a2a-frontend.d.ts.map +1 -1
  6. package/dist/agent-protocol/index.d.ts.map +1 -1
  7. package/dist/agent-protocol/push-notification-manager.d.ts.map +1 -1
  8. package/dist/agent-protocol/state-transitions.d.ts.map +1 -1
  9. package/dist/agent-protocol/task-evaluator.d.ts.map +1 -1
  10. package/dist/agent-protocol/task-live-update-slack.d.ts +10 -0
  11. package/dist/agent-protocol/task-live-update-slack.d.ts.map +1 -1
  12. package/dist/agent-protocol/task-live-update-teams.d.ts.map +1 -1
  13. package/dist/agent-protocol/task-live-update-telegram.d.ts.map +1 -1
  14. package/dist/agent-protocol/task-live-updates.d.ts +10 -0
  15. package/dist/agent-protocol/task-live-updates.d.ts.map +1 -1
  16. package/dist/agent-protocol/task-progress-tool.d.ts.map +1 -1
  17. package/dist/agent-protocol/task-queue.d.ts.map +1 -1
  18. package/dist/agent-protocol/task-store.d.ts.map +1 -1
  19. package/dist/agent-protocol/task-stream-manager.d.ts.map +1 -1
  20. package/dist/agent-protocol/task-trace-resolution.d.ts.map +1 -1
  21. package/dist/agent-protocol/tasks-cli-handler.d.ts.map +1 -1
  22. package/dist/agent-protocol/tasks-tui.d.ts.map +1 -1
  23. package/dist/agent-protocol/trace-serializer.d.ts +43 -1
  24. package/dist/agent-protocol/trace-serializer.d.ts.map +1 -1
  25. package/dist/agent-protocol/track-execution.d.ts.map +1 -1
  26. package/dist/agent-protocol/types.d.ts.map +1 -1
  27. package/dist/ai-review-service.d.ts +22 -1
  28. package/dist/ai-review-service.d.ts.map +1 -1
  29. package/dist/check-execution-engine.d.ts.map +1 -1
  30. package/dist/cli-main.d.ts +1 -0
  31. package/dist/cli-main.d.ts.map +1 -1
  32. package/dist/cli.d.ts.map +1 -1
  33. package/dist/commands.d.ts.map +1 -1
  34. package/dist/config/cli-handler.d.ts.map +1 -1
  35. package/dist/config/config-reloader.d.ts.map +1 -1
  36. package/dist/config/config-snapshot-store.d.ts.map +1 -1
  37. package/dist/config/config-watcher.d.ts.map +1 -1
  38. package/dist/config/types.d.ts.map +1 -1
  39. package/dist/config.d.ts.map +1 -1
  40. package/dist/cron-scheduler.d.ts.map +1 -1
  41. package/dist/debug-visualizer/debug-span-exporter.d.ts.map +1 -1
  42. package/dist/debug-visualizer/trace-reader.d.ts.map +1 -1
  43. package/dist/debug-visualizer/ws-server.d.ts.map +1 -1
  44. package/dist/defaults/assistant.yaml +31 -0
  45. package/dist/defaults/code-talk.yaml +32 -0
  46. package/dist/defaults/skills/code-explorer.yaml +6 -0
  47. package/dist/dependency-resolver.d.ts.map +1 -1
  48. package/dist/docs/telemetry-setup.md +18 -2
  49. package/dist/email/adapter.d.ts.map +1 -1
  50. package/dist/email/client.d.ts.map +1 -1
  51. package/dist/email/markdown.d.ts.map +1 -1
  52. package/dist/email/polling-runner.d.ts +1 -0
  53. package/dist/email/polling-runner.d.ts.map +1 -1
  54. package/dist/engine/on-finish/orchestrator.d.ts.map +1 -1
  55. package/dist/engine/on-finish/utils.d.ts.map +1 -1
  56. package/dist/event-bus/event-bus.d.ts.map +1 -1
  57. package/dist/event-bus/types.d.ts.map +1 -1
  58. package/dist/event-mapper.d.ts.map +1 -1
  59. package/dist/failure-condition-evaluator.d.ts.map +1 -1
  60. package/dist/footer.d.ts.map +1 -1
  61. package/dist/frontends/email-frontend.d.ts.map +1 -1
  62. package/dist/frontends/github-frontend.d.ts.map +1 -1
  63. package/dist/frontends/host.d.ts.map +1 -1
  64. package/dist/frontends/ndjson-sink.d.ts.map +1 -1
  65. package/dist/frontends/slack-frontend.d.ts.map +1 -1
  66. package/dist/frontends/teams-frontend.d.ts.map +1 -1
  67. package/dist/frontends/telegram-frontend.d.ts.map +1 -1
  68. package/dist/frontends/whatsapp-frontend.d.ts.map +1 -1
  69. package/dist/generated/config-schema.d.ts +16 -8
  70. package/dist/generated/config-schema.d.ts.map +1 -1
  71. package/dist/git-repository-analyzer.d.ts.map +1 -1
  72. package/dist/github-auth.d.ts.map +1 -1
  73. package/dist/github-check-service.d.ts.map +1 -1
  74. package/dist/github-comments.d.ts.map +1 -1
  75. package/dist/github-reactions.d.ts.map +1 -1
  76. package/dist/index.d.ts +1 -0
  77. package/dist/index.d.ts.map +1 -1
  78. package/dist/index.js +7656 -1458
  79. package/dist/issue-filter.d.ts.map +1 -1
  80. package/dist/liquid-extensions.d.ts.map +1 -1
  81. package/dist/logger.d.ts.map +1 -1
  82. package/dist/mcp-job-manager.d.ts.map +1 -1
  83. package/dist/mcp-server.d.ts.map +1 -1
  84. package/dist/memory-store.d.ts.map +1 -1
  85. package/dist/output/traces/{run-2026-05-05T12-31-47-571Z.ndjson → run-2026-08-20T13-50-06-218Z.ndjson} +2699 -2699
  86. package/dist/output-formatters.d.ts.map +1 -1
  87. package/dist/policy/default-engine.d.ts.map +1 -1
  88. package/dist/policy/index.d.ts.map +1 -1
  89. package/dist/policy/policy-check-command.d.ts.map +1 -1
  90. package/dist/policy/types.d.ts.map +1 -1
  91. package/dist/pr-analyzer.d.ts.map +1 -1
  92. package/dist/pr-detector.d.ts.map +1 -1
  93. package/dist/providers/a2a-check-provider.d.ts.map +1 -1
  94. package/dist/providers/ai-check-provider.d.ts.map +1 -1
  95. package/dist/providers/api-tool-executor.d.ts.map +1 -1
  96. package/dist/providers/check-provider-registry.d.ts.map +1 -1
  97. package/dist/providers/check-provider.interface.d.ts.map +1 -1
  98. package/dist/providers/claude-code-check-provider.d.ts.map +1 -1
  99. package/dist/providers/claude-code-types.d.ts.map +1 -1
  100. package/dist/providers/command-check-provider.d.ts.map +1 -1
  101. package/dist/providers/custom-tool-executor.d.ts.map +1 -1
  102. package/dist/providers/git-checkout-provider.d.ts.map +1 -1
  103. package/dist/providers/github-ops-provider.d.ts.map +1 -1
  104. package/dist/providers/http-check-provider.d.ts.map +1 -1
  105. package/dist/providers/http-client-provider.d.ts.map +1 -1
  106. package/dist/providers/http-input-provider.d.ts.map +1 -1
  107. package/dist/providers/human-input-check-provider.d.ts.map +1 -1
  108. package/dist/providers/index.d.ts.map +1 -1
  109. package/dist/providers/log-check-provider.d.ts.map +1 -1
  110. package/dist/providers/mcp-check-provider.d.ts.map +1 -1
  111. package/dist/providers/mcp-custom-sse-server.d.ts.map +1 -1
  112. package/dist/providers/mcp-tools.d.ts.map +1 -1
  113. package/dist/providers/memory-check-provider.d.ts.map +1 -1
  114. package/dist/providers/noop-check-provider.d.ts.map +1 -1
  115. package/dist/providers/script-check-provider.d.ts.map +1 -1
  116. package/dist/providers/utcp-check-provider.d.ts.map +1 -1
  117. package/dist/providers/workflow-check-provider.d.ts.map +1 -1
  118. package/dist/providers/workflow-tool-executor.d.ts.map +1 -1
  119. package/dist/reviewer.d.ts.map +1 -1
  120. package/dist/runners/config-reload-runtime.d.ts.map +1 -1
  121. package/dist/runners/graceful-restart.d.ts.map +1 -1
  122. package/dist/runners/mcp-server-runner.d.ts.map +1 -1
  123. package/dist/runners/process-cli-handler.d.ts.map +1 -1
  124. package/dist/runners/process-discovery.d.ts.map +1 -1
  125. package/dist/runners/runner-factory.d.ts.map +1 -1
  126. package/dist/runners/runner-host.d.ts.map +1 -1
  127. package/dist/runners/runner.d.ts.map +1 -1
  128. package/dist/runners/telemetry-init.d.ts.map +1 -1
  129. package/dist/sandbox/bubblewrap-sandbox.d.ts.map +1 -1
  130. package/dist/sandbox/cache-volume-manager.d.ts.map +1 -1
  131. package/dist/sandbox/check-runner.d.ts.map +1 -1
  132. package/dist/sandbox/compose-generator.d.ts.map +1 -1
  133. package/dist/sandbox/docker-compose-sandbox.d.ts.map +1 -1
  134. package/dist/sandbox/docker-image-sandbox.d.ts.map +1 -1
  135. package/dist/sandbox/env-filter.d.ts.map +1 -1
  136. package/dist/sandbox/index.d.ts.map +1 -1
  137. package/dist/sandbox/sandbox-manager.d.ts.map +1 -1
  138. package/dist/sandbox/sandbox-telemetry.d.ts.map +1 -1
  139. package/dist/sandbox/seatbelt-sandbox.d.ts.map +1 -1
  140. package/dist/sandbox/trace-ingester.d.ts.map +1 -1
  141. package/dist/sandbox/types.d.ts.map +1 -1
  142. package/dist/scheduler/cli-handler.d.ts.map +1 -1
  143. package/dist/scheduler/index.d.ts.map +1 -1
  144. package/dist/scheduler/message-trigger.d.ts.map +1 -1
  145. package/dist/scheduler/schedule-parser.d.ts.map +1 -1
  146. package/dist/scheduler/schedule-store.d.ts.map +1 -1
  147. package/dist/scheduler/schedule-tool.d.ts.map +1 -1
  148. package/dist/scheduler/scheduler.d.ts.map +1 -1
  149. package/dist/scheduler/store/index.d.ts.map +1 -1
  150. package/dist/scheduler/store/json-migrator.d.ts.map +1 -1
  151. package/dist/scheduler/store/sqlite-store.d.ts.map +1 -1
  152. package/dist/scheduler/store/types.d.ts.map +1 -1
  153. package/dist/sdk/{a2a-frontend-L3TQ7QQ6.mjs → a2a-frontend-XCQ4CQUF.mjs} +3 -3
  154. package/dist/sdk/{check-provider-registry-RQYIEQLJ.mjs → check-provider-registry-2D3MCWP3.mjs} +14 -11
  155. package/dist/sdk/{chunk-WZQMTD7W.mjs → chunk-2LLKENYD.mjs} +3 -3
  156. package/dist/sdk/{chunk-WZQMTD7W.mjs.map → chunk-2LLKENYD.mjs.map} +1 -1
  157. package/dist/sdk/{chunk-XXAEN5KU.mjs → chunk-77AKSSW2.mjs} +43 -65
  158. package/dist/sdk/chunk-77AKSSW2.mjs.map +1 -0
  159. package/dist/sdk/chunk-7QI6F66G.mjs +145 -0
  160. package/dist/sdk/chunk-7QI6F66G.mjs.map +1 -0
  161. package/dist/sdk/{chunk-NEZY2MXM.mjs → chunk-B2LQT6QU.mjs} +4 -4
  162. package/dist/sdk/{chunk-NEZY2MXM.mjs.map → chunk-B2LQT6QU.mjs.map} +1 -1
  163. package/dist/sdk/{chunk-IY5PQ5EN.mjs → chunk-BVEATT5V.mjs} +822 -51
  164. package/dist/sdk/chunk-BVEATT5V.mjs.map +1 -0
  165. package/dist/sdk/{chunk-TSX3YS3F.mjs → chunk-HW4MPCOW.mjs} +5 -139
  166. package/dist/sdk/chunk-HW4MPCOW.mjs.map +1 -0
  167. package/dist/sdk/chunk-PGBV3VZB.mjs +122 -0
  168. package/dist/sdk/chunk-PGBV3VZB.mjs.map +1 -0
  169. package/dist/sdk/{chunk-PDQTEBOJ.mjs → chunk-QT766ZLD.mjs} +5 -1
  170. package/dist/sdk/chunk-QT766ZLD.mjs.map +1 -0
  171. package/dist/sdk/{chunk-5TXIAPRA.mjs → chunk-S3GSZRYC.mjs} +2 -2
  172. package/dist/sdk/{chunk-NPOVLLKH.mjs → chunk-TGQBEM3Y.mjs} +570 -259
  173. package/dist/sdk/chunk-TGQBEM3Y.mjs.map +1 -0
  174. package/dist/sdk/chunk-TL3ZTYFY.mjs +141 -0
  175. package/dist/sdk/chunk-TL3ZTYFY.mjs.map +1 -0
  176. package/dist/sdk/{chunk-4UMDSYC7.mjs → chunk-VS3JE2DL.mjs} +3 -3
  177. package/dist/sdk/{chunk-A4WHMRK2.mjs → chunk-YETG675X.mjs} +2 -2
  178. package/dist/sdk/{chunk-XX6WT332.mjs → chunk-YTG5DN72.mjs} +17 -9
  179. package/dist/sdk/chunk-YTG5DN72.mjs.map +1 -0
  180. package/dist/sdk/{chunk-SRU5TFNY.mjs → chunk-YU3VR5SZ.mjs} +145 -16
  181. package/dist/sdk/chunk-YU3VR5SZ.mjs.map +1 -0
  182. package/dist/sdk/{config-BCYAVJ5S.mjs → config-H5IOLBFA.mjs} +2 -2
  183. package/dist/sdk/{email-frontend-P7QE4UUJ.mjs → email-frontend-AE5TYWNC.mjs} +18 -3
  184. package/dist/sdk/{email-frontend-P7QE4UUJ.mjs.map → email-frontend-AE5TYWNC.mjs.map} +1 -1
  185. package/dist/sdk/{failure-condition-evaluator-ZBOSD574.mjs → failure-condition-evaluator-66PWLV3D.mjs} +4 -4
  186. package/dist/sdk/{github-frontend-4WHT5JEU.mjs → github-frontend-BBFKCY4M.mjs} +4 -4
  187. package/dist/sdk/{host-FKR7H26C.mjs → host-UQRZDLT7.mjs} +8 -8
  188. package/dist/sdk/oauth2-token-cache-OS7WHLDI.mjs +13 -0
  189. package/dist/sdk/{routing-IB2PXYFC.mjs → routing-Q647KUMO.mjs} +5 -5
  190. package/dist/sdk/{schedule-tool-LB33KL2W.mjs → schedule-tool-WMGSM6IT.mjs} +14 -11
  191. package/dist/sdk/{schedule-tool-handler-KYWZHKSS.mjs → schedule-tool-handler-JMDHCGZ2.mjs} +14 -11
  192. package/dist/sdk/sdk.d.mts +14 -2
  193. package/dist/sdk/sdk.d.ts +14 -2
  194. package/dist/sdk/sdk.js +1927 -643
  195. package/dist/sdk/sdk.js.map +1 -1
  196. package/dist/sdk/sdk.mjs +13 -10
  197. package/dist/sdk/sdk.mjs.map +1 -1
  198. package/dist/sdk/session-registry-CENXWIFR.mjs +12 -0
  199. package/dist/sdk/{slack-frontend-K3TPGERM.mjs → slack-frontend-JMX5MUVZ.mjs} +42 -12
  200. package/dist/sdk/slack-frontend-JMX5MUVZ.mjs.map +1 -0
  201. package/dist/sdk/{task-evaluator-H3BXC7SE.mjs → task-evaluator-4QG4CYQA.mjs} +7 -6
  202. package/dist/sdk/task-evaluator-4QG4CYQA.mjs.map +1 -0
  203. package/dist/sdk/{teams-frontend-6RRW533K.mjs → teams-frontend-6MDAN7OR.mjs} +17 -4
  204. package/dist/sdk/teams-frontend-6MDAN7OR.mjs.map +1 -0
  205. package/dist/sdk/{telegram-frontend-5UA77YAT.mjs → telegram-frontend-NLX2ZHS4.mjs} +17 -4
  206. package/dist/sdk/telegram-frontend-NLX2ZHS4.mjs.map +1 -0
  207. package/dist/sdk/{trace-helpers-AMZ2524G.mjs → trace-helpers-AIUGQLK5.mjs} +3 -3
  208. package/dist/sdk/{trace-serializer-EBHTHZYT.mjs → trace-serializer-4TOIAVQL.mjs} +10 -2
  209. package/dist/sdk/{track-execution-VW6P3OYO.mjs → track-execution-CFRZXMEC.mjs} +91 -20
  210. package/dist/sdk/track-execution-CFRZXMEC.mjs.map +1 -0
  211. package/dist/sdk/{utcp-check-provider-Q4PD5EP2.mjs → utcp-check-provider-WDTSQ7DZ.mjs} +3 -2
  212. package/dist/sdk/{whatsapp-frontend-72XEIUIR.mjs → whatsapp-frontend-3EMMNC7R.mjs} +15 -2
  213. package/dist/sdk/whatsapp-frontend-3EMMNC7R.mjs.map +1 -0
  214. package/dist/sdk/{workflow-check-provider-N6KSDPWU.mjs → workflow-check-provider-G7A67EPP.mjs} +14 -11
  215. package/dist/sdk/workflow-check-provider-G7A67EPP.mjs.map +1 -0
  216. package/dist/sdk.d.ts.map +1 -1
  217. package/dist/session-registry.d.ts +2 -7
  218. package/dist/session-registry.d.ts.map +1 -1
  219. package/dist/slack/adapter.d.ts.map +1 -1
  220. package/dist/slack/cache-prewarmer.d.ts.map +1 -1
  221. package/dist/slack/client.d.ts +8 -0
  222. package/dist/slack/client.d.ts.map +1 -1
  223. package/dist/slack/markdown.d.ts.map +1 -1
  224. package/dist/slack/prompt-state.d.ts.map +1 -1
  225. package/dist/slack/rate-limiter.d.ts.map +1 -1
  226. package/dist/slack/schedule-tool-handler.d.ts.map +1 -1
  227. package/dist/slack/signature.d.ts.map +1 -1
  228. package/dist/slack/slack-output-adapter.d.ts.map +1 -1
  229. package/dist/slack/socket-runner.d.ts +1 -0
  230. package/dist/slack/socket-runner.d.ts.map +1 -1
  231. package/dist/slack/thread-cache.d.ts.map +1 -1
  232. package/dist/snapshot-store.d.ts.map +1 -1
  233. package/dist/state-machine/context/build-engine-context.d.ts.map +1 -1
  234. package/dist/state-machine/context/workflow-inputs.d.ts.map +1 -1
  235. package/dist/state-machine/dispatch/debounce-manager.d.ts +44 -0
  236. package/dist/state-machine/dispatch/debounce-manager.d.ts.map +1 -0
  237. package/dist/state-machine/dispatch/dependency-gating.d.ts.map +1 -1
  238. package/dist/state-machine/dispatch/execution-invoker.d.ts.map +1 -1
  239. package/dist/state-machine/dispatch/foreach-processor.d.ts.map +1 -1
  240. package/dist/state-machine/dispatch/history-snapshot.d.ts.map +1 -1
  241. package/dist/state-machine/dispatch/on-init-handlers.d.ts.map +1 -1
  242. package/dist/state-machine/dispatch/policy-gate.d.ts.map +1 -1
  243. package/dist/state-machine/dispatch/renderer-schema.d.ts.map +1 -1
  244. package/dist/state-machine/dispatch/sandbox-routing.d.ts.map +1 -1
  245. package/dist/state-machine/dispatch/stats-manager.d.ts.map +1 -1
  246. package/dist/state-machine/dispatch/template-renderer.d.ts.map +1 -1
  247. package/dist/state-machine/execution/summary.d.ts.map +1 -1
  248. package/dist/state-machine/runner.d.ts.map +1 -1
  249. package/dist/state-machine/states/check-running.d.ts.map +1 -1
  250. package/dist/state-machine/states/completed.d.ts.map +1 -1
  251. package/dist/state-machine/states/error.d.ts.map +1 -1
  252. package/dist/state-machine/states/init.d.ts.map +1 -1
  253. package/dist/state-machine/states/level-dispatch.d.ts.map +1 -1
  254. package/dist/state-machine/states/plan-ready.d.ts.map +1 -1
  255. package/dist/state-machine/states/routing.d.ts.map +1 -1
  256. package/dist/state-machine/states/wave-planning.d.ts.map +1 -1
  257. package/dist/state-machine/workflow-projection.d.ts.map +1 -1
  258. package/dist/state-machine-execution-engine.d.ts +1 -0
  259. package/dist/state-machine-execution-engine.d.ts.map +1 -1
  260. package/dist/teams/adapter.d.ts.map +1 -1
  261. package/dist/teams/client.d.ts.map +1 -1
  262. package/dist/teams/markdown.d.ts.map +1 -1
  263. package/dist/teams/webhook-runner.d.ts +1 -0
  264. package/dist/teams/webhook-runner.d.ts.map +1 -1
  265. package/dist/telegram/adapter.d.ts.map +1 -1
  266. package/dist/telegram/client.d.ts.map +1 -1
  267. package/dist/telegram/markdown.d.ts.map +1 -1
  268. package/dist/telegram/polling-runner.d.ts +1 -0
  269. package/dist/telegram/polling-runner.d.ts.map +1 -1
  270. package/dist/telemetry/fallback-ndjson.d.ts.map +1 -1
  271. package/dist/telemetry/file-span-exporter.d.ts.map +1 -1
  272. package/dist/telemetry/lazy-otel.d.ts.map +1 -1
  273. package/dist/telemetry/metrics.d.ts.map +1 -1
  274. package/dist/telemetry/opentelemetry.d.ts.map +1 -1
  275. package/dist/telemetry/state-capture.d.ts.map +1 -1
  276. package/dist/telemetry/trace-helpers.d.ts.map +1 -1
  277. package/dist/telemetry/trace-report-exporter.d.ts.map +1 -1
  278. package/dist/test-runner/assertions.d.ts.map +1 -1
  279. package/dist/test-runner/conversation-sugar.d.ts.map +1 -1
  280. package/dist/test-runner/core/environment.d.ts.map +1 -1
  281. package/dist/test-runner/core/fixture.d.ts.map +1 -1
  282. package/dist/test-runner/core/flow-stage.d.ts.map +1 -1
  283. package/dist/test-runner/core/mocks.d.ts.map +1 -1
  284. package/dist/test-runner/core/test-execution-wrapper.d.ts.map +1 -1
  285. package/dist/test-runner/evaluators.d.ts.map +1 -1
  286. package/dist/test-runner/fixture-loader.d.ts.map +1 -1
  287. package/dist/test-runner/index.d.ts.map +1 -1
  288. package/dist/test-runner/llm-judge.d.ts.map +1 -1
  289. package/dist/test-runner/recorders/github-recorder.d.ts.map +1 -1
  290. package/dist/test-runner/recorders/global-recorder.d.ts.map +1 -1
  291. package/dist/test-runner/recorders/slack-recorder.d.ts.map +1 -1
  292. package/dist/test-runner/utils/selectors.d.ts.map +1 -1
  293. package/dist/test-runner/validator.d.ts.map +1 -1
  294. package/dist/traces/{run-2026-05-05T12-31-47-571Z.ndjson → run-2026-08-20T13-50-06-218Z.ndjson} +2699 -2699
  295. package/dist/tui/chat-runner.d.ts.map +1 -1
  296. package/dist/tui/chat-state.d.ts.map +1 -1
  297. package/dist/tui/chat-tui.d.ts.map +1 -1
  298. package/dist/tui/components/chat-box.d.ts.map +1 -1
  299. package/dist/tui/components/input-bar.d.ts.map +1 -1
  300. package/dist/tui/components/status-bar.d.ts.map +1 -1
  301. package/dist/tui/components/trace-viewer.d.ts.map +1 -1
  302. package/dist/tui/index.d.ts.map +1 -1
  303. package/dist/tui/tui-frontend.d.ts.map +1 -1
  304. package/dist/types/bot.d.ts.map +1 -1
  305. package/dist/types/cli.d.ts.map +1 -1
  306. package/dist/types/config.d.ts +14 -2
  307. package/dist/types/config.d.ts.map +1 -1
  308. package/dist/types/engine.d.ts.map +1 -1
  309. package/dist/types/execution.d.ts.map +1 -1
  310. package/dist/types/git-checkout.d.ts.map +1 -1
  311. package/dist/types/github.d.ts.map +1 -1
  312. package/dist/types/workflow.d.ts.map +1 -1
  313. package/dist/utils/author-permissions.d.ts.map +1 -1
  314. package/dist/utils/child-process-error-handler.d.ts +19 -0
  315. package/dist/utils/child-process-error-handler.d.ts.map +1 -0
  316. package/dist/utils/command-executor.d.ts.map +1 -1
  317. package/dist/utils/comment-metadata.d.ts.map +1 -1
  318. package/dist/utils/config-loader.d.ts.map +1 -1
  319. package/dist/utils/config-merger.d.ts.map +1 -1
  320. package/dist/utils/diff-processor.d.ts.map +1 -1
  321. package/dist/utils/env-exposure.d.ts.map +1 -1
  322. package/dist/utils/env-resolver.d.ts.map +1 -1
  323. package/dist/utils/fair-concurrency-limiter.d.ts.map +1 -1
  324. package/dist/utils/file-exclusion.d.ts.map +1 -1
  325. package/dist/utils/head-sha.d.ts.map +1 -1
  326. package/dist/utils/human-id.d.ts.map +1 -1
  327. package/dist/utils/instance-id.d.ts.map +1 -1
  328. package/dist/utils/interactive-prompt.d.ts.map +1 -1
  329. package/dist/utils/issue-normalizer.d.ts.map +1 -1
  330. package/dist/utils/json-text-extractor.d.ts.map +1 -1
  331. package/dist/utils/mermaid-telemetry.d.ts.map +1 -1
  332. package/dist/utils/oauth2-token-cache.d.ts.map +1 -1
  333. package/dist/utils/rate-limiter.d.ts.map +1 -1
  334. package/dist/utils/sandbox.d.ts.map +1 -1
  335. package/dist/utils/script-memory-ops.d.ts.map +1 -1
  336. package/dist/utils/script-tool-environment.d.ts.map +1 -1
  337. package/dist/utils/stdin-reader.d.ts.map +1 -1
  338. package/dist/utils/template-context.d.ts.map +1 -1
  339. package/dist/utils/tool-resolver.d.ts.map +1 -1
  340. package/dist/utils/toolkit-expander.d.ts.map +1 -1
  341. package/dist/utils/tracer-init.d.ts.map +1 -1
  342. package/dist/utils/ui-helpers.d.ts.map +1 -1
  343. package/dist/utils/user-facing-error.d.ts +4 -0
  344. package/dist/utils/user-facing-error.d.ts.map +1 -0
  345. package/dist/utils/workspace-manager.d.ts +5 -0
  346. package/dist/utils/workspace-manager.d.ts.map +1 -1
  347. package/dist/utils/worktree-cleanup.d.ts +28 -0
  348. package/dist/utils/worktree-cleanup.d.ts.map +1 -1
  349. package/dist/utils/worktree-manager.d.ts +6 -0
  350. package/dist/utils/worktree-manager.d.ts.map +1 -1
  351. package/dist/webhook-server.d.ts.map +1 -1
  352. package/dist/whatsapp/adapter.d.ts.map +1 -1
  353. package/dist/whatsapp/client.d.ts.map +1 -1
  354. package/dist/whatsapp/markdown.d.ts.map +1 -1
  355. package/dist/whatsapp/webhook-runner.d.ts +1 -0
  356. package/dist/whatsapp/webhook-runner.d.ts.map +1 -1
  357. package/dist/workflow-executor.d.ts +7 -0
  358. package/dist/workflow-executor.d.ts.map +1 -1
  359. package/dist/workflow-registry.d.ts.map +1 -1
  360. package/package.json +3 -3
  361. package/dist/output/traces/run-2026-05-05T12-31-09-587Z.ndjson +0 -252
  362. package/dist/sdk/chunk-IY5PQ5EN.mjs.map +0 -1
  363. package/dist/sdk/chunk-NPOVLLKH.mjs.map +0 -1
  364. package/dist/sdk/chunk-PDQTEBOJ.mjs.map +0 -1
  365. package/dist/sdk/chunk-SRU5TFNY.mjs.map +0 -1
  366. package/dist/sdk/chunk-TSX3YS3F.mjs.map +0 -1
  367. package/dist/sdk/chunk-XX6WT332.mjs.map +0 -1
  368. package/dist/sdk/chunk-XXAEN5KU.mjs.map +0 -1
  369. package/dist/sdk/session-registry-6PV6SGEJ.mjs +0 -10
  370. package/dist/sdk/slack-frontend-K3TPGERM.mjs.map +0 -1
  371. package/dist/sdk/task-evaluator-H3BXC7SE.mjs.map +0 -1
  372. package/dist/sdk/teams-frontend-6RRW533K.mjs.map +0 -1
  373. package/dist/sdk/telegram-frontend-5UA77YAT.mjs.map +0 -1
  374. package/dist/sdk/trace-reader-OVE4DL2D.mjs +0 -270
  375. package/dist/sdk/trace-reader-OVE4DL2D.mjs.map +0 -1
  376. package/dist/sdk/track-execution-VW6P3OYO.mjs.map +0 -1
  377. package/dist/sdk/whatsapp-frontend-72XEIUIR.mjs.map +0 -1
  378. package/dist/traces/run-2026-05-05T12-31-09-587Z.ndjson +0 -252
  379. /package/dist/sdk/{a2a-frontend-L3TQ7QQ6.mjs.map → a2a-frontend-XCQ4CQUF.mjs.map} +0 -0
  380. /package/dist/sdk/{check-provider-registry-RQYIEQLJ.mjs.map → check-provider-registry-2D3MCWP3.mjs.map} +0 -0
  381. /package/dist/sdk/{chunk-5TXIAPRA.mjs.map → chunk-S3GSZRYC.mjs.map} +0 -0
  382. /package/dist/sdk/{chunk-4UMDSYC7.mjs.map → chunk-VS3JE2DL.mjs.map} +0 -0
  383. /package/dist/sdk/{chunk-A4WHMRK2.mjs.map → chunk-YETG675X.mjs.map} +0 -0
  384. /package/dist/sdk/{config-BCYAVJ5S.mjs.map → config-H5IOLBFA.mjs.map} +0 -0
  385. /package/dist/sdk/{failure-condition-evaluator-ZBOSD574.mjs.map → failure-condition-evaluator-66PWLV3D.mjs.map} +0 -0
  386. /package/dist/sdk/{github-frontend-4WHT5JEU.mjs.map → github-frontend-BBFKCY4M.mjs.map} +0 -0
  387. /package/dist/sdk/{host-FKR7H26C.mjs.map → host-UQRZDLT7.mjs.map} +0 -0
  388. /package/dist/sdk/{routing-IB2PXYFC.mjs.map → oauth2-token-cache-OS7WHLDI.mjs.map} +0 -0
  389. /package/dist/sdk/{schedule-tool-LB33KL2W.mjs.map → routing-Q647KUMO.mjs.map} +0 -0
  390. /package/dist/sdk/{schedule-tool-handler-KYWZHKSS.mjs.map → schedule-tool-WMGSM6IT.mjs.map} +0 -0
  391. /package/dist/sdk/{session-registry-6PV6SGEJ.mjs.map → schedule-tool-handler-JMDHCGZ2.mjs.map} +0 -0
  392. /package/dist/sdk/{trace-helpers-AMZ2524G.mjs.map → session-registry-CENXWIFR.mjs.map} +0 -0
  393. /package/dist/sdk/{trace-serializer-EBHTHZYT.mjs.map → trace-helpers-AIUGQLK5.mjs.map} +0 -0
  394. /package/dist/sdk/{utcp-check-provider-Q4PD5EP2.mjs.map → trace-serializer-4TOIAVQL.mjs.map} +0 -0
  395. /package/dist/sdk/{workflow-check-provider-N6KSDPWU.mjs.map → utcp-check-provider-WDTSQ7DZ.mjs.map} +0 -0
@@ -16,26 +16,37 @@ import {
16
16
  extractFileSections,
17
17
  init_markdown,
18
18
  replaceFileSections
19
- } from "./chunk-PDQTEBOJ.mjs";
19
+ } from "./chunk-QT766ZLD.mjs";
20
20
  import {
21
21
  init_task_trace_resolution,
22
22
  resolveTaskTraceReference
23
- } from "./chunk-WZQMTD7W.mjs";
23
+ } from "./chunk-2LLKENYD.mjs";
24
+ import {
25
+ formatUserFacingExecutionError,
26
+ formatUserFacingExecutionMessage,
27
+ init_user_facing_error
28
+ } from "./chunk-TL3ZTYFY.mjs";
29
+ import {
30
+ OAuth2TokenCache,
31
+ init_oauth2_token_cache
32
+ } from "./chunk-PGBV3VZB.mjs";
24
33
  import {
25
34
  CheckProvider,
26
- EnvironmentResolver,
27
35
  UtcpCheckProvider,
28
36
  buildSandboxEnv,
29
37
  env_exposure_exports,
30
38
  extractIssuesFromOutput,
31
39
  init_check_provider_interface,
32
40
  init_env_exposure,
33
- init_env_resolver,
34
41
  init_issue_normalizer,
35
42
  init_utcp_check_provider,
36
43
  normalizeIssue,
37
44
  normalizeIssueArray
38
- } from "./chunk-TSX3YS3F.mjs";
45
+ } from "./chunk-HW4MPCOW.mjs";
46
+ import {
47
+ EnvironmentResolver,
48
+ init_env_resolver
49
+ } from "./chunk-7QI6F66G.mjs";
39
50
  import {
40
51
  getPromptStateManager,
41
52
  init_prompt_state
@@ -48,7 +59,7 @@ import {
48
59
  SessionRegistry,
49
60
  init_session_registry,
50
61
  session_registry_exports
51
- } from "./chunk-XXAEN5KU.mjs";
62
+ } from "./chunk-77AKSSW2.mjs";
52
63
  import {
53
64
  commandExecutor,
54
65
  init_command_executor
@@ -62,7 +73,7 @@ import {
62
73
  import {
63
74
  config_exports,
64
75
  init_config
65
- } from "./chunk-XX6WT332.mjs";
76
+ } from "./chunk-YTG5DN72.mjs";
66
77
  import {
67
78
  ExecutionJournal,
68
79
  checkLoopBudget,
@@ -71,11 +82,11 @@ import {
71
82
  init_routing,
72
83
  init_snapshot_store,
73
84
  snapshot_store_exports
74
- } from "./chunk-4UMDSYC7.mjs";
85
+ } from "./chunk-VS3JE2DL.mjs";
75
86
  import {
76
87
  FailureConditionEvaluator,
77
88
  init_failure_condition_evaluator
78
- } from "./chunk-5TXIAPRA.mjs";
89
+ } from "./chunk-S3GSZRYC.mjs";
79
90
  import {
80
91
  addEvent,
81
92
  emitImmediateSpan,
@@ -88,11 +99,11 @@ import {
88
99
  setSpanAttributes,
89
100
  trace_helpers_exports,
90
101
  withActiveSpan
91
- } from "./chunk-A4WHMRK2.mjs";
102
+ } from "./chunk-YETG675X.mjs";
92
103
  import {
93
104
  generateHumanId,
94
105
  init_human_id
95
- } from "./chunk-NEZY2MXM.mjs";
106
+ } from "./chunk-B2LQT6QU.mjs";
96
107
  import {
97
108
  addDiagramBlock,
98
109
  init_metrics,
@@ -148,7 +159,7 @@ async function processDiffWithOutline(diffContent) {
148
159
  }
149
160
  try {
150
161
  const originalProbePath = process.env.PROBE_PATH;
151
- const fs13 = __require("fs");
162
+ const fs14 = __require("fs");
152
163
  const possiblePaths = [
153
164
  // Relative to current working directory (most common in production)
154
165
  path.join(process.cwd(), "node_modules/@probelabs/probe/bin/probe-binary"),
@@ -159,7 +170,7 @@ async function processDiffWithOutline(diffContent) {
159
170
  ];
160
171
  let probeBinaryPath;
161
172
  for (const candidatePath of possiblePaths) {
162
- if (fs13.existsSync(candidatePath)) {
173
+ if (fs14.existsSync(candidatePath)) {
163
174
  probeBinaryPath = candidatePath;
164
175
  break;
165
176
  }
@@ -284,16 +295,36 @@ function createProbeTracerAdapter(fallbackTracer) {
284
295
  "negotiated_timeout.observer_exhausted",
285
296
  "negotiated_timeout.abort_summary"
286
297
  ]);
298
+ const isSpanWorthyEvent = (name) => SPAN_WORTHY_EVENTS.has(name) || name.startsWith("task.");
287
299
  const emitEvent = (name, attrs) => {
288
300
  try {
289
301
  const flat = flattenAttrs(attrs);
290
- if (SPAN_WORTHY_EVENTS.has(name)) {
302
+ if (isSpanWorthyEvent(name)) {
291
303
  try {
304
+ const startHr = process.hrtime();
292
305
  const tracer = trace.getTracer("visor");
293
306
  const childSpan = tracer.startSpan(`probe.event.${name}`, {
294
307
  attributes: { "probe.event.name": name, ...flat }
295
308
  });
296
309
  childSpan.end();
310
+ try {
311
+ const activeParent = trace.getActiveSpan?.();
312
+ const parentCtx = activeParent?.spanContext?.();
313
+ const childCtx = childSpan.spanContext?.();
314
+ const endHr = process.hrtime();
315
+ emitNdjsonFullSpan({
316
+ name: `probe.event.${name}`,
317
+ traceId: childCtx?.traceId || parentCtx?.traceId,
318
+ spanId: childCtx?.spanId,
319
+ parentSpanId: parentCtx?.spanId,
320
+ startTime: [startHr[0], startHr[1]],
321
+ endTime: [endHr[0], endHr[1]],
322
+ attributes: { "probe.event.name": name, ...flat },
323
+ events: [],
324
+ status: { code: 1 }
325
+ });
326
+ } catch {
327
+ }
297
328
  } catch {
298
329
  }
299
330
  }
@@ -484,6 +515,15 @@ function createProbeTracerAdapter(fallbackTracer) {
484
515
  }
485
516
  }
486
517
  },
518
+ recordTaskEvent: (phase, attrs) => {
519
+ emitEvent(`task.${phase}`, attrs);
520
+ if (fallback && typeof fallback.recordTaskEvent === "function") {
521
+ try {
522
+ fallback.recordTaskEvent(phase, attrs);
523
+ } catch {
524
+ }
525
+ }
526
+ },
487
527
  createToolSpan: (toolName, attrs) => {
488
528
  let fallbackSpan = null;
489
529
  if (fallback && typeof fallback.createToolSpan === "function") {
@@ -690,6 +730,7 @@ var init_ai_review_service = __esm({
690
730
  init_tracer_init();
691
731
  init_diff_processor();
692
732
  init_comment_metadata();
733
+ init_user_facing_error();
693
734
  init_markdown();
694
735
  PROBE_GRACEFUL_MARGIN_MS = 9e4;
695
736
  MIN_TIMEOUT_FOR_MARGIN_MS = PROBE_GRACEFUL_MARGIN_MS + 3e4;
@@ -1108,8 +1149,8 @@ var init_ai_review_service = __esm({
1108
1149
  /**
1109
1150
  * Cleanup a session from the registry
1110
1151
  */
1111
- cleanupSession(sessionId) {
1112
- this.sessionRegistry.unregisterSession(sessionId);
1152
+ async cleanupSession(sessionId) {
1153
+ await this.sessionRegistry.unregisterSession(sessionId);
1113
1154
  }
1114
1155
  /**
1115
1156
  * Build a custom prompt for AI review with XML-formatted data
@@ -1687,7 +1728,7 @@ ${schemaString}`);
1687
1728
  }
1688
1729
  if (process.env.VISOR_DEBUG_AI_SESSIONS === "true") {
1689
1730
  try {
1690
- const fs13 = __require("fs");
1731
+ const fs14 = __require("fs");
1691
1732
  const path15 = __require("path");
1692
1733
  const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
1693
1734
  const provider = this.config.provider || "auto";
@@ -1803,19 +1844,19 @@ ${"=".repeat(60)}
1803
1844
  readableVersion += `${"=".repeat(60)}
1804
1845
  `;
1805
1846
  const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS || path15.join(process.cwd(), "debug-artifacts");
1806
- if (!fs13.existsSync(debugArtifactsDir)) {
1807
- fs13.mkdirSync(debugArtifactsDir, { recursive: true });
1847
+ if (!fs14.existsSync(debugArtifactsDir)) {
1848
+ fs14.mkdirSync(debugArtifactsDir, { recursive: true });
1808
1849
  }
1809
1850
  const debugFile = path15.join(
1810
1851
  debugArtifactsDir,
1811
1852
  `prompt-${_checkName || "unknown"}-${timestamp}.json`
1812
1853
  );
1813
- fs13.writeFileSync(debugFile, debugJson, "utf-8");
1854
+ fs14.writeFileSync(debugFile, debugJson, "utf-8");
1814
1855
  const readableFile = path15.join(
1815
1856
  debugArtifactsDir,
1816
1857
  `prompt-${_checkName || "unknown"}-${timestamp}.txt`
1817
1858
  );
1818
- fs13.writeFileSync(readableFile, readableVersion, "utf-8");
1859
+ fs14.writeFileSync(readableFile, readableVersion, "utf-8");
1819
1860
  log(`
1820
1861
  \u{1F4BE} Full debug info saved to:`);
1821
1862
  log(` JSON: ${debugFile}`);
@@ -1853,7 +1894,7 @@ ${"=".repeat(60)}
1853
1894
  log(`\u{1F4E4} Response length: ${response.length} characters`);
1854
1895
  if (process.env.VISOR_DEBUG_AI_SESSIONS === "true") {
1855
1896
  try {
1856
- const fs13 = __require("fs");
1897
+ const fs14 = __require("fs");
1857
1898
  const path15 = __require("path");
1858
1899
  const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
1859
1900
  const agentAny2 = agent;
@@ -1878,7 +1919,7 @@ ${"=".repeat(60)}
1878
1919
  schema: effectiveSchema,
1879
1920
  totalMessages: fullHistory.length
1880
1921
  };
1881
- fs13.writeFileSync(sessionBase + ".json", JSON.stringify(sessionData, null, 2), "utf-8");
1922
+ fs14.writeFileSync(sessionBase + ".json", JSON.stringify(sessionData, null, 2), "utf-8");
1882
1923
  let readable = `=============================================================
1883
1924
  `;
1884
1925
  readable += `COMPLETE AI SESSION HISTORY (AFTER RESPONSE)
@@ -1905,7 +1946,7 @@ ${"=".repeat(60)}
1905
1946
  `;
1906
1947
  readable += content + "\n";
1907
1948
  });
1908
- fs13.writeFileSync(sessionBase + ".summary.txt", readable, "utf-8");
1949
+ fs14.writeFileSync(sessionBase + ".summary.txt", readable, "utf-8");
1909
1950
  log(`\u{1F4BE} Complete session history saved:`);
1910
1951
  log(` - Contains ALL ${fullHistory.length} messages (prompts + responses)`);
1911
1952
  } catch (error) {
@@ -1914,7 +1955,7 @@ ${"=".repeat(60)}
1914
1955
  }
1915
1956
  if (process.env.VISOR_DEBUG_AI_SESSIONS === "true") {
1916
1957
  try {
1917
- const fs13 = __require("fs");
1958
+ const fs14 = __require("fs");
1918
1959
  const path15 = __require("path");
1919
1960
  const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
1920
1961
  const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS || path15.join(process.cwd(), "debug-artifacts");
@@ -1951,7 +1992,7 @@ ${"=".repeat(60)}
1951
1992
  `;
1952
1993
  responseContent += `${"=".repeat(60)}
1953
1994
  `;
1954
- fs13.writeFileSync(responseFile, responseContent, "utf-8");
1995
+ fs14.writeFileSync(responseFile, responseContent, "utf-8");
1955
1996
  log(`\u{1F4BE} Response saved to: ${responseFile}`);
1956
1997
  } catch (error) {
1957
1998
  log(`\u26A0\uFE0F Could not save response file: ${error}`);
@@ -1967,9 +2008,9 @@ ${"=".repeat(60)}
1967
2008
  await agentAny._telemetryConfig.shutdown();
1968
2009
  log(`\u{1F4CA} OpenTelemetry trace saved to: ${agentAny._traceFilePath}`);
1969
2010
  if (process.env.GITHUB_ACTIONS) {
1970
- const fs13 = __require("fs");
1971
- if (fs13.existsSync(agentAny._traceFilePath)) {
1972
- const stats = fs13.statSync(agentAny._traceFilePath);
2011
+ const fs14 = __require("fs");
2012
+ if (fs14.existsSync(agentAny._traceFilePath)) {
2013
+ const stats = fs14.statSync(agentAny._traceFilePath);
1973
2014
  console.log(
1974
2015
  `::notice title=AI Trace Saved::${agentAny._traceFilePath} (${stats.size} bytes)`
1975
2016
  );
@@ -2239,7 +2280,7 @@ ${schemaString}`);
2239
2280
  const model = this.config.model || "default";
2240
2281
  if (process.env.VISOR_DEBUG_AI_SESSIONS === "true") {
2241
2282
  try {
2242
- const fs13 = __require("fs");
2283
+ const fs14 = __require("fs");
2243
2284
  const path15 = __require("path");
2244
2285
  const os = __require("os");
2245
2286
  const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
@@ -2315,7 +2356,7 @@ ${"=".repeat(60)}
2315
2356
  `;
2316
2357
  const tempDir = os.tmpdir();
2317
2358
  const promptFile = path15.join(tempDir, `visor-prompt-${timestamp}.txt`);
2318
- fs13.writeFileSync(promptFile, prompt, "utf-8");
2359
+ fs14.writeFileSync(promptFile, prompt, "utf-8");
2319
2360
  log(`
2320
2361
  \u{1F4BE} Prompt saved to: ${promptFile}`);
2321
2362
  const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS || path15.join(process.cwd(), "debug-artifacts");
@@ -2324,8 +2365,8 @@ ${"=".repeat(60)}
2324
2365
  debugArtifactsDir,
2325
2366
  `prompt-${_checkName || "unknown"}-${timestamp}`
2326
2367
  );
2327
- fs13.writeFileSync(base + ".json", debugJson, "utf-8");
2328
- fs13.writeFileSync(base + ".summary.txt", readableVersion, "utf-8");
2368
+ fs14.writeFileSync(base + ".json", debugJson, "utf-8");
2369
+ fs14.writeFileSync(base + ".summary.txt", readableVersion, "utf-8");
2329
2370
  log(`
2330
2371
  \u{1F4BE} Full debug info saved to directory: ${debugArtifactsDir}`);
2331
2372
  } catch {
@@ -2375,7 +2416,7 @@ $ ${cliCommand}
2375
2416
  log(`\u{1F4E4} Response length: ${response.length} characters`);
2376
2417
  if (process.env.VISOR_DEBUG_AI_SESSIONS === "true") {
2377
2418
  try {
2378
- const fs13 = __require("fs");
2419
+ const fs14 = __require("fs");
2379
2420
  const path15 = __require("path");
2380
2421
  const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
2381
2422
  const agentAny = agent;
@@ -2400,7 +2441,7 @@ $ ${cliCommand}
2400
2441
  schema: effectiveSchema,
2401
2442
  totalMessages: fullHistory.length
2402
2443
  };
2403
- fs13.writeFileSync(sessionBase + ".json", JSON.stringify(sessionData, null, 2), "utf-8");
2444
+ fs14.writeFileSync(sessionBase + ".json", JSON.stringify(sessionData, null, 2), "utf-8");
2404
2445
  let readable = `=============================================================
2405
2446
  `;
2406
2447
  readable += `COMPLETE AI SESSION HISTORY (AFTER RESPONSE)
@@ -2427,7 +2468,7 @@ ${"=".repeat(60)}
2427
2468
  `;
2428
2469
  readable += content + "\n";
2429
2470
  });
2430
- fs13.writeFileSync(sessionBase + ".summary.txt", readable, "utf-8");
2471
+ fs14.writeFileSync(sessionBase + ".summary.txt", readable, "utf-8");
2431
2472
  log(`\u{1F4BE} Complete session history saved:`);
2432
2473
  log(` - Contains ALL ${fullHistory.length} messages (prompts + responses)`);
2433
2474
  } catch (error) {
@@ -2436,7 +2477,7 @@ ${"=".repeat(60)}
2436
2477
  }
2437
2478
  if (process.env.VISOR_DEBUG_AI_SESSIONS === "true") {
2438
2479
  try {
2439
- const fs13 = __require("fs");
2480
+ const fs14 = __require("fs");
2440
2481
  const path15 = __require("path");
2441
2482
  const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
2442
2483
  const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS || path15.join(process.cwd(), "debug-artifacts");
@@ -2473,7 +2514,7 @@ ${"=".repeat(60)}
2473
2514
  `;
2474
2515
  responseContent += `${"=".repeat(60)}
2475
2516
  `;
2476
- fs13.writeFileSync(responseFile, responseContent, "utf-8");
2517
+ fs14.writeFileSync(responseFile, responseContent, "utf-8");
2477
2518
  log(`\u{1F4BE} Response saved to: ${responseFile}`);
2478
2519
  } catch (error) {
2479
2520
  log(`\u26A0\uFE0F Could not save response file: ${error}`);
@@ -2491,9 +2532,9 @@ ${"=".repeat(60)}
2491
2532
  await telemetry.shutdown();
2492
2533
  log(`\u{1F4CA} OpenTelemetry trace saved to: ${traceFilePath}`);
2493
2534
  if (process.env.GITHUB_ACTIONS) {
2494
- const fs13 = __require("fs");
2495
- if (fs13.existsSync(traceFilePath)) {
2496
- const stats = fs13.statSync(traceFilePath);
2535
+ const fs14 = __require("fs");
2536
+ if (fs14.existsSync(traceFilePath)) {
2537
+ const stats = fs14.statSync(traceFilePath);
2497
2538
  console.log(
2498
2539
  `::notice title=AI Trace Saved::OpenTelemetry trace file size: ${stats.size} bytes`
2499
2540
  );
@@ -2514,9 +2555,7 @@ ${"=".repeat(60)}
2514
2555
  return { response, effectiveSchema, sessionId };
2515
2556
  } catch (error) {
2516
2557
  console.error("\u274C ProbeAgent failed:", error);
2517
- throw new Error(
2518
- `ProbeAgent execution failed: ${error instanceof Error ? error.message : "Unknown error"}`
2519
- );
2558
+ throw new Error(formatUserFacingExecutionError(error));
2520
2559
  } finally {
2521
2560
  Object.keys(originalEnv).forEach((key) => {
2522
2561
  if (originalEnv[key] === void 0) {
@@ -2531,7 +2570,7 @@ ${"=".repeat(60)}
2531
2570
  * Load schema content from schema files or inline definitions
2532
2571
  */
2533
2572
  async loadSchemaContent(schema) {
2534
- const fs13 = __require("fs").promises;
2573
+ const fs14 = __require("fs").promises;
2535
2574
  const path15 = __require("path");
2536
2575
  if (typeof schema === "object" && schema !== null) {
2537
2576
  log("\u{1F4CB} Using inline schema object from configuration");
@@ -2552,7 +2591,7 @@ ${"=".repeat(60)}
2552
2591
  try {
2553
2592
  const schemaPath = path15.resolve(process.cwd(), schema);
2554
2593
  log(`\u{1F4CB} Loading custom schema from file: ${schemaPath}`);
2555
- const schemaContent = await fs13.readFile(schemaPath, "utf-8");
2594
+ const schemaContent = await fs14.readFile(schemaPath, "utf-8");
2556
2595
  return schemaContent.trim();
2557
2596
  } catch (error) {
2558
2597
  throw new Error(
@@ -2574,7 +2613,7 @@ ${"=".repeat(60)}
2574
2613
  ];
2575
2614
  for (const schemaPath of candidatePaths) {
2576
2615
  try {
2577
- const schemaContent = await fs13.readFile(schemaPath, "utf-8");
2616
+ const schemaContent = await fs14.readFile(schemaPath, "utf-8");
2578
2617
  return schemaContent.trim();
2579
2618
  } catch {
2580
2619
  }
@@ -4502,7 +4541,7 @@ function createWorkflowToolDefinition(workflow, argsOverrides, nameOverride) {
4502
4541
  for (const key of Object.keys(argsOverrides)) {
4503
4542
  delete filteredProperties[key];
4504
4543
  }
4505
- const filteredRequired = baseRequired ? baseRequired.filter((r) => !argsOverrides[r]) : void 0;
4544
+ const filteredRequired = baseRequired ? baseRequired.filter((r) => !(r in argsOverrides)) : void 0;
4506
4545
  inputSchema = {
4507
4546
  ...baseSchema,
4508
4547
  properties: filteredProperties,
@@ -4538,7 +4577,7 @@ async function executeWorkflowAsTool(workflowId, args, context2, argsOverrides)
4538
4577
  ...args,
4539
4578
  ...argsOverrides
4540
4579
  };
4541
- const { WorkflowCheckProvider: WorkflowCheckProvider2 } = await import("./workflow-check-provider-N6KSDPWU.mjs");
4580
+ const { WorkflowCheckProvider: WorkflowCheckProvider2 } = await import("./workflow-check-provider-G7A67EPP.mjs");
4542
4581
  const provider = new WorkflowCheckProvider2();
4543
4582
  const checkConfig = {
4544
4583
  type: "workflow",
@@ -8386,6 +8425,126 @@ var init_policy_gate = __esm({
8386
8425
  }
8387
8426
  });
8388
8427
 
8428
+ // src/state-machine/dispatch/debounce-manager.ts
8429
+ function effectiveDebounceMs(requested) {
8430
+ const override = process.env.VISOR_DEBOUNCE_OVERRIDE;
8431
+ if (override !== void 0) {
8432
+ const ms = parseInt(override, 10);
8433
+ if (!isNaN(ms) && ms >= 0) return ms;
8434
+ }
8435
+ return requested;
8436
+ }
8437
+ function getDebounceManager() {
8438
+ if (!__instance) __instance = new DebounceManager();
8439
+ return __instance;
8440
+ }
8441
+ var DebounceManager, __instance;
8442
+ var init_debounce_manager = __esm({
8443
+ "src/state-machine/dispatch/debounce-manager.ts"() {
8444
+ "use strict";
8445
+ init_logger();
8446
+ DebounceManager = class {
8447
+ pending = /* @__PURE__ */ new Map();
8448
+ /** Waiters that were superseded and should resolve as 'debounced' */
8449
+ superseded = /* @__PURE__ */ new Map();
8450
+ /** Keys currently executing — prevents parallel runs */
8451
+ executing = /* @__PURE__ */ new Set();
8452
+ /**
8453
+ * Enqueue an execution. Returns 'executed' if this invocation won the
8454
+ * debounce race, or 'debounced' if it was superseded by a later one
8455
+ * or if the function is already executing for this key.
8456
+ */
8457
+ enqueue(key, debounceMs, fn) {
8458
+ if (this.executing.has(key)) {
8459
+ logger.info(`[DebounceManager] ${key}: already executing, skipping this invocation`);
8460
+ return Promise.resolve({ outcome: "debounced" });
8461
+ }
8462
+ const actualMs = effectiveDebounceMs(debounceMs);
8463
+ return new Promise(
8464
+ (resolve10, reject) => {
8465
+ const existing = this.pending.get(key);
8466
+ if (existing) {
8467
+ clearTimeout(existing.timer);
8468
+ if (!this.superseded.has(key)) {
8469
+ this.superseded.set(key, []);
8470
+ }
8471
+ this.superseded.get(key).push(existing.resolve);
8472
+ existing.invocations++;
8473
+ logger.info(
8474
+ `[DebounceManager] ${key}: invocation #${existing.invocations}, resetting ${actualMs}ms timer`
8475
+ );
8476
+ } else {
8477
+ logger.info(
8478
+ `[DebounceManager] ${key}: first invocation, starting ${actualMs}ms debounce`
8479
+ );
8480
+ }
8481
+ const invocations = existing ? existing.invocations : 1;
8482
+ const firstTime = existing ? existing.firstInvocationTime : Date.now();
8483
+ const timer = setTimeout(async () => {
8484
+ this.pending.delete(key);
8485
+ const waiters2 = this.superseded.get(key) || [];
8486
+ this.superseded.delete(key);
8487
+ for (const w of waiters2) {
8488
+ w({ outcome: "debounced" });
8489
+ }
8490
+ const elapsed = Date.now() - firstTime;
8491
+ logger.info(
8492
+ `[DebounceManager] ${key}: executing after ${invocations} invocation(s) over ${elapsed}ms`
8493
+ );
8494
+ this.executing.add(key);
8495
+ try {
8496
+ const result = await fn();
8497
+ resolve10({ outcome: "executed", result });
8498
+ } catch (err) {
8499
+ reject(err);
8500
+ } finally {
8501
+ this.executing.delete(key);
8502
+ logger.info(`[DebounceManager] ${key}: execution finished`);
8503
+ }
8504
+ }, actualMs);
8505
+ this.pending.set(key, {
8506
+ timer,
8507
+ invocations,
8508
+ firstInvocationTime: firstTime,
8509
+ resolve: resolve10,
8510
+ reject,
8511
+ fn
8512
+ });
8513
+ }
8514
+ );
8515
+ }
8516
+ /** Cancel a pending debounce. All waiters resolve as 'debounced'. */
8517
+ cancel(key) {
8518
+ const entry = this.pending.get(key);
8519
+ if (!entry) return false;
8520
+ clearTimeout(entry.timer);
8521
+ this.pending.delete(key);
8522
+ entry.resolve({ outcome: "debounced" });
8523
+ const waiters2 = this.superseded.get(key) || [];
8524
+ this.superseded.delete(key);
8525
+ for (const w of waiters2) {
8526
+ w({ outcome: "debounced" });
8527
+ }
8528
+ return true;
8529
+ }
8530
+ /** Cancel all pending debounces. */
8531
+ clear() {
8532
+ for (const [key] of this.pending) {
8533
+ this.cancel(key);
8534
+ }
8535
+ }
8536
+ /** Number of pending debounce keys. */
8537
+ get size() {
8538
+ return this.pending.size;
8539
+ }
8540
+ /** Check if a key is currently executing. */
8541
+ isExecuting(key) {
8542
+ return this.executing.has(key);
8543
+ }
8544
+ };
8545
+ }
8546
+ });
8547
+
8389
8548
  // src/state-machine/dispatch/history-snapshot.ts
8390
8549
  var history_snapshot_exports = {};
8391
8550
  __export(history_snapshot_exports, {
@@ -8557,7 +8716,7 @@ var init_dependency_gating = __esm({
8557
8716
  async function renderTemplateContent(checkId, checkConfig, reviewSummary) {
8558
8717
  try {
8559
8718
  const { createExtendedLiquid: createExtendedLiquid2 } = await import("./liquid-extensions-KZIRR4OY.mjs");
8560
- const fs13 = await import("fs/promises");
8719
+ const fs14 = await import("fs/promises");
8561
8720
  const path15 = await import("path");
8562
8721
  const schemaRaw = checkConfig.schema || "plain";
8563
8722
  const schema = typeof schemaRaw === "string" ? schemaRaw : "code-review";
@@ -8568,7 +8727,7 @@ async function renderTemplateContent(checkId, checkConfig, reviewSummary) {
8568
8727
  } else if (checkConfig.template && checkConfig.template.file) {
8569
8728
  const file = String(checkConfig.template.file);
8570
8729
  const resolved = path15.resolve(process.cwd(), file);
8571
- templateContent = await fs13.readFile(resolved, "utf-8");
8730
+ templateContent = await fs14.readFile(resolved, "utf-8");
8572
8731
  logger.debug(`[TemplateRenderer] Using template file for ${checkId}: ${resolved}`);
8573
8732
  } else if (schema && schema !== "plain") {
8574
8733
  const sanitized = String(schema).replace(/[^a-zA-Z0-9-]/g, "");
@@ -8585,7 +8744,7 @@ async function renderTemplateContent(checkId, checkConfig, reviewSummary) {
8585
8744
  ];
8586
8745
  for (const p of candidatePaths) {
8587
8746
  try {
8588
- templateContent = await fs13.readFile(p, "utf-8");
8747
+ templateContent = await fs14.readFile(p, "utf-8");
8589
8748
  if (templateContent) {
8590
8749
  logger.debug(`[TemplateRenderer] Using schema template for ${checkId}: ${p}`);
8591
8750
  break;
@@ -11003,6 +11162,36 @@ async function executeCheckWithForEachItems2(checkId, forEachParent, forEachItem
11003
11162
  wave: state.wave
11004
11163
  },
11005
11164
  async (span) => {
11165
+ if (checkConfig.debounce && checkConfig.debounce > 0) {
11166
+ const debounceKey = checkConfig.debounce_key || checkId;
11167
+ const debounceResult = await getDebounceManager().enqueue(
11168
+ debounceKey,
11169
+ checkConfig.debounce,
11170
+ async () => {
11171
+ const r = await executeWithSandboxRouting(
11172
+ checkId,
11173
+ checkConfig,
11174
+ context2,
11175
+ prInfo,
11176
+ dependencyResults,
11177
+ checkConfig.timeout || checkConfig.ai?.timeout || 18e5,
11178
+ () => provider.execute(prInfo, providerConfig, dependencyResults, executionContext)
11179
+ );
11180
+ try {
11181
+ captureCheckOutput(span, r.output);
11182
+ } catch {
11183
+ }
11184
+ return r;
11185
+ }
11186
+ );
11187
+ if (debounceResult.outcome === "debounced") {
11188
+ logger.info(
11189
+ `[LevelDispatch] ${checkId}: debounced (superseded by later invocation)`
11190
+ );
11191
+ return { issues: [], output: { debounced: true } };
11192
+ }
11193
+ return debounceResult.result;
11194
+ }
11006
11195
  const res = await executeWithSandboxRouting(
11007
11196
  checkId,
11008
11197
  checkConfig,
@@ -11428,7 +11617,7 @@ async function executeCheckWithForEachItems2(checkId, forEachParent, forEachItem
11428
11617
  }
11429
11618
  }
11430
11619
  try {
11431
- const { evaluateTransitions } = await import("./routing-IB2PXYFC.mjs");
11620
+ const { evaluateTransitions } = await import("./routing-Q647KUMO.mjs");
11432
11621
  const transTarget = await evaluateTransitions(
11433
11622
  onFinish.transitions,
11434
11623
  forEachParent,
@@ -11488,7 +11677,7 @@ async function executeCheckWithForEachItems2(checkId, forEachParent, forEachItem
11488
11677
  `[LevelDispatch] Error evaluating on_finish transitions for ${forEachParent}: ${e instanceof Error ? e.message : String(e)}`
11489
11678
  );
11490
11679
  }
11491
- const { evaluateGoto: evaluateGoto2 } = await import("./routing-IB2PXYFC.mjs");
11680
+ const { evaluateGoto: evaluateGoto2 } = await import("./routing-Q647KUMO.mjs");
11492
11681
  if (context2.debug) {
11493
11682
  logger.info(
11494
11683
  `[LevelDispatch] Evaluating on_finish.goto_js for forEach parent: ${forEachParent}`
@@ -12154,6 +12343,34 @@ async function executeSingleCheck2(checkId, context2, state, emitEvent, transiti
12154
12343
  wave: state.wave
12155
12344
  },
12156
12345
  async (span) => {
12346
+ if (checkConfig2.debounce && checkConfig2.debounce > 0) {
12347
+ const debounceKey = checkConfig2.debounce_key || checkId;
12348
+ const debounceResult = await getDebounceManager().enqueue(
12349
+ debounceKey,
12350
+ checkConfig2.debounce,
12351
+ async () => {
12352
+ const r = await executeWithSandboxRouting(
12353
+ checkId,
12354
+ checkConfig2,
12355
+ context2,
12356
+ prInfo,
12357
+ dependencyResults,
12358
+ checkConfig2.timeout || checkConfig2.ai?.timeout || 18e5,
12359
+ () => provider.execute(prInfo, providerConfig, dependencyResults, executionContext)
12360
+ );
12361
+ try {
12362
+ captureCheckOutput(span, r.output);
12363
+ } catch {
12364
+ }
12365
+ return r;
12366
+ }
12367
+ );
12368
+ if (debounceResult.outcome === "debounced") {
12369
+ logger.info(`[LevelDispatch] ${checkId}: debounced (superseded by later invocation)`);
12370
+ return { issues: [], output: { debounced: true } };
12371
+ }
12372
+ return debounceResult.result;
12373
+ }
12157
12374
  const res = await executeWithSandboxRouting(
12158
12375
  checkId,
12159
12376
  checkConfig2,
@@ -12287,13 +12504,10 @@ async function executeSingleCheck2(checkId, context2, state, emitEvent, transiti
12287
12504
  }
12288
12505
  let isForEach = result.isForEach;
12289
12506
  let forEachItems2 = result.forEachItems;
12290
- logger.info(
12291
- `[LevelDispatch][DEBUG] After execution ${checkId}: checkConfig.forEach=${checkConfig2.forEach}, output type=${typeof result.output}, isArray=${Array.isArray(result.output)}`
12292
- );
12293
12507
  if (checkConfig2.forEach === true) {
12294
12508
  const output = result.output;
12295
- logger.info(
12296
- `[LevelDispatch][DEBUG] Processing forEach=true for ${checkId}, output=${JSON.stringify(output)?.substring(0, 200)}`
12509
+ logger.debug(
12510
+ `[LevelDispatch] Processing forEach=true for ${checkId}, output=${JSON.stringify(output)?.substring(0, 200)}`
12297
12511
  );
12298
12512
  if (output === void 0) {
12299
12513
  logger.error(`[LevelDispatch] forEach check "${checkId}" produced undefined output`);
@@ -12793,7 +13007,7 @@ function updateStats2(results, state, isForEachIteration = false) {
12793
13007
  async function renderTemplateContent2(checkId, checkConfig, reviewSummary) {
12794
13008
  try {
12795
13009
  const { createExtendedLiquid: createExtendedLiquid2 } = await import("./liquid-extensions-KZIRR4OY.mjs");
12796
- const fs13 = await import("fs/promises");
13010
+ const fs14 = await import("fs/promises");
12797
13011
  const path15 = await import("path");
12798
13012
  const schemaRaw = checkConfig.schema || "plain";
12799
13013
  const schema = typeof schemaRaw === "string" && !schemaRaw.includes("{{") && !schemaRaw.includes("{%") ? schemaRaw : typeof schemaRaw === "object" ? "code-review" : "plain";
@@ -12804,7 +13018,7 @@ async function renderTemplateContent2(checkId, checkConfig, reviewSummary) {
12804
13018
  } else if (checkConfig.template && checkConfig.template.file) {
12805
13019
  const file = String(checkConfig.template.file);
12806
13020
  const resolved = path15.resolve(process.cwd(), file);
12807
- templateContent = await fs13.readFile(resolved, "utf-8");
13021
+ templateContent = await fs14.readFile(resolved, "utf-8");
12808
13022
  logger.debug(`[LevelDispatch] Using template file for ${checkId}: ${resolved}`);
12809
13023
  } else if (schema && schema !== "plain") {
12810
13024
  const sanitized = String(schema).replace(/[^a-zA-Z0-9-]/g, "");
@@ -12823,7 +13037,7 @@ async function renderTemplateContent2(checkId, checkConfig, reviewSummary) {
12823
13037
  ];
12824
13038
  for (const p of candidatePaths) {
12825
13039
  try {
12826
- templateContent = await fs13.readFile(p, "utf-8");
13040
+ templateContent = await fs14.readFile(p, "utf-8");
12827
13041
  if (templateContent) {
12828
13042
  logger.debug(`[LevelDispatch] Using schema template for ${checkId}: ${p}`);
12829
13043
  break;
@@ -12891,6 +13105,7 @@ var init_level_dispatch = __esm({
12891
13105
  init_workflow_inputs();
12892
13106
  init_sandbox_routing();
12893
13107
  init_policy_gate();
13108
+ init_debounce_manager();
12894
13109
  init_liquid_extensions();
12895
13110
  }
12896
13111
  });
@@ -13438,6 +13653,7 @@ var init_runner = __esm({
13438
13653
  });
13439
13654
 
13440
13655
  // src/utils/workspace-manager.ts
13656
+ import * as fs6 from "fs";
13441
13657
  import * as fsp from "fs/promises";
13442
13658
  import * as path7 from "path";
13443
13659
  function shellEscape(str) {
@@ -13650,12 +13866,7 @@ var init_workspace_manager = __esm({
13650
13866
  }
13651
13867
  }
13652
13868
  try {
13653
- const entries = await fsp.readdir(this.workspacePath, { withFileTypes: true });
13654
- for (const entry of entries) {
13655
- if (entry.name !== mainProjectName) {
13656
- this.usedNames.add(entry.name);
13657
- }
13658
- }
13869
+ await this.loadExistingProjects(mainProjectName);
13659
13870
  } catch {
13660
13871
  }
13661
13872
  this.registerCleanupHandlers();
@@ -13800,6 +14011,41 @@ var init_workspace_manager = __esm({
13800
14011
  return false;
13801
14012
  }
13802
14013
  }
14014
+ /**
14015
+ * Rehydrate existing symlinked projects in a persisted workspace so future
14016
+ * runs update them in place instead of allocating project-2, project-3, etc.
14017
+ */
14018
+ async loadExistingProjects(mainProjectName) {
14019
+ const entries = await fsp.readdir(this.workspacePath, { withFileTypes: true });
14020
+ for (const entry of entries) {
14021
+ if (entry.name === mainProjectName) {
14022
+ continue;
14023
+ }
14024
+ const entryPath = path7.join(this.workspacePath, entry.name);
14025
+ this.usedNames.add(entry.name);
14026
+ if (!entry.isSymbolicLink()) {
14027
+ continue;
14028
+ }
14029
+ try {
14030
+ const targetPath = await fsp.realpath(entryPath);
14031
+ const metadataPath = `${targetPath.replace(/\/?$/, "")}.metadata.json`;
14032
+ if (!fs6.existsSync(metadataPath)) {
14033
+ continue;
14034
+ }
14035
+ const metadata = JSON.parse(await fsp.readFile(metadataPath, "utf8"));
14036
+ if (!metadata.repository) {
14037
+ continue;
14038
+ }
14039
+ this.projects.set(entry.name, {
14040
+ name: entry.name,
14041
+ path: entryPath,
14042
+ worktreePath: metadata.worktree_path || targetPath,
14043
+ repository: metadata.repository
14044
+ });
14045
+ } catch {
14046
+ }
14047
+ }
14048
+ }
13803
14049
  /**
13804
14050
  * Clean up stale workspace directories older than maxAge.
13805
14051
  * Call periodically (e.g. at socket-runner startup) to prevent disk bloat.
@@ -13815,6 +14061,17 @@ var init_workspace_manager = __esm({
13815
14061
  try {
13816
14062
  const stat2 = await fsp.stat(dirPath);
13817
14063
  if (now - stat2.mtimeMs > maxAgeMs) {
14064
+ const topGitPath = path7.join(dirPath, ".git");
14065
+ try {
14066
+ const topGitStat = await fsp.stat(topGitPath);
14067
+ if (topGitStat.isDirectory()) {
14068
+ logger.warn(
14069
+ `[Workspace] Skipping ${dirPath} \u2014 it is a real git repository, not a visor workspace`
14070
+ );
14071
+ continue;
14072
+ }
14073
+ } catch {
14074
+ }
13818
14075
  try {
13819
14076
  const subdirs = await fsp.readdir(dirPath, { withFileTypes: true });
13820
14077
  for (const sub of subdirs) {
@@ -13826,7 +14083,19 @@ var init_workspace_manager = __esm({
13826
14083
  const match = gitContent.match(/gitdir:\s*(.+)/);
13827
14084
  if (match) {
13828
14085
  const worktreeGitDir = match[1].trim();
14086
+ if (!worktreeGitDir.includes("/.git/worktrees/")) {
14087
+ logger.warn(
14088
+ `[Workspace] Skipping worktree removal for ${subPath} \u2014 gitdir does not point to a worktree`
14089
+ );
14090
+ continue;
14091
+ }
13829
14092
  const repoGitDir = worktreeGitDir.replace(/\/\.git\/worktrees\/.*$/, "");
14093
+ if (!repoGitDir.startsWith(basePath)) {
14094
+ logger.warn(
14095
+ `[Workspace] Skipping worktree removal for ${subPath} \u2014 parent repo ${repoGitDir} is outside workspace`
14096
+ );
14097
+ continue;
14098
+ }
13830
14099
  await commandExecutor.execute(
13831
14100
  `git -C ${shellEscape(repoGitDir)} worktree remove ${shellEscape(subPath)} --force`,
13832
14101
  { timeout: 1e4 }
@@ -14526,7 +14795,7 @@ var init_summary = __esm({
14526
14795
 
14527
14796
  // src/state-machine-execution-engine.ts
14528
14797
  import * as path8 from "path";
14529
- import * as fs6 from "fs";
14798
+ import * as fs7 from "fs";
14530
14799
  function serializeRunState(state) {
14531
14800
  return {
14532
14801
  ...state,
@@ -14590,7 +14859,7 @@ var init_state_machine_execution_engine = __esm({
14590
14859
  const gitAnalyzer = new GitRepositoryAnalyzer(options.workingDirectory);
14591
14860
  logger.info("Analyzing local git repository...");
14592
14861
  const repositoryInfo = await gitAnalyzer.analyzeRepository();
14593
- const hasConversation = !!this.executionContext?.conversation;
14862
+ const hasConversation = !!this.executionContext?.conversation || this.webhookContextHasConversation(options?.webhookContext);
14594
14863
  if (!repositoryInfo.isGitRepository && !hasConversation) {
14595
14864
  return this.createErrorResult(
14596
14865
  repositoryInfo,
@@ -14624,7 +14893,7 @@ var init_state_machine_execution_engine = __esm({
14624
14893
  try {
14625
14894
  const map = options?.webhookContext?.webhookData;
14626
14895
  if (map) {
14627
- const { CheckProviderRegistry: CheckProviderRegistry2 } = await import("./check-provider-registry-RQYIEQLJ.mjs");
14896
+ const { CheckProviderRegistry: CheckProviderRegistry2 } = await import("./check-provider-registry-2D3MCWP3.mjs");
14628
14897
  const reg = CheckProviderRegistry2.getInstance();
14629
14898
  const p = reg.getProvider("http_input");
14630
14899
  if (p && typeof p.setWebhookContext === "function") p.setWebhookContext(map);
@@ -14737,7 +15006,7 @@ var init_state_machine_execution_engine = __esm({
14737
15006
  logger.info("[StateMachine] Using state machine engine");
14738
15007
  }
14739
15008
  if (!config) {
14740
- const { ConfigManager } = await import("./config-BCYAVJ5S.mjs");
15009
+ const { ConfigManager } = await import("./config-H5IOLBFA.mjs");
14741
15010
  const configManager = new ConfigManager();
14742
15011
  config = await configManager.getDefaultConfig();
14743
15012
  logger.debug("[StateMachine] Using default configuration (no config provided)");
@@ -14747,7 +15016,7 @@ var init_state_machine_execution_engine = __esm({
14747
15016
  tag_filter: tagFilter
14748
15017
  } : config;
14749
15018
  try {
14750
- const { CheckProviderRegistry: CheckProviderRegistry2 } = await import("./check-provider-registry-RQYIEQLJ.mjs");
15019
+ const { CheckProviderRegistry: CheckProviderRegistry2 } = await import("./check-provider-registry-2D3MCWP3.mjs");
14751
15020
  const registry = CheckProviderRegistry2.getInstance();
14752
15021
  registry.setCustomTools(configWithTagFilter.tools || {});
14753
15022
  } catch (error) {
@@ -14811,7 +15080,7 @@ var init_state_machine_execution_engine = __esm({
14811
15080
  try {
14812
15081
  const webhookData = this.executionContext?.webhookContext?.webhookData;
14813
15082
  if (webhookData instanceof Map) {
14814
- const { extractSlackContext: extractSlackContext2 } = await import("./schedule-tool-handler-KYWZHKSS.mjs");
15083
+ const { extractSlackContext: extractSlackContext2 } = await import("./schedule-tool-handler-JMDHCGZ2.mjs");
14815
15084
  const slackCtx = extractSlackContext2(webhookData);
14816
15085
  if (slackCtx) {
14817
15086
  const payload = Array.from(webhookData.values())[0];
@@ -14840,7 +15109,7 @@ var init_state_machine_execution_engine = __esm({
14840
15109
  if (Array.isArray(configWithTagFilter.frontends) && configWithTagFilter.frontends.length > 0) {
14841
15110
  try {
14842
15111
  const { EventBus } = await import("./event-bus-5K3Y2FCS.mjs");
14843
- const { FrontendsHost } = await import("./host-FKR7H26C.mjs");
15112
+ const { FrontendsHost } = await import("./host-UQRZDLT7.mjs");
14844
15113
  const bus = new EventBus();
14845
15114
  context2.eventBus = bus;
14846
15115
  frontendsHost = new FrontendsHost(bus, logger);
@@ -14944,7 +15213,7 @@ var init_state_machine_execution_engine = __esm({
14944
15213
  const checkId = String(ev?.checkId || "unknown");
14945
15214
  const threadKey = ev?.threadKey || (channel && threadTs ? `${channel}:${threadTs}` : "session");
14946
15215
  const baseDir = process.env.VISOR_SNAPSHOT_DIR || path8.resolve(process.cwd(), ".visor", "snapshots");
14947
- fs6.mkdirSync(baseDir, { recursive: true });
15216
+ fs7.mkdirSync(baseDir, { recursive: true });
14948
15217
  const filePath = path8.join(baseDir, `${threadKey}-${checkId}.json`);
14949
15218
  await this.saveSnapshotToFile(filePath);
14950
15219
  logger.info(`[Snapshot] Saved run snapshot: ${filePath}`);
@@ -14987,9 +15256,9 @@ var init_state_machine_execution_engine = __esm({
14987
15256
  logger.info("[StateMachine] Execution complete");
14988
15257
  }
14989
15258
  try {
14990
- const { SessionRegistry: SessionRegistry2 } = await import("./session-registry-6PV6SGEJ.mjs");
15259
+ const { SessionRegistry: SessionRegistry2 } = await import("./session-registry-CENXWIFR.mjs");
14991
15260
  const sessionRegistry = SessionRegistry2.getInstance();
14992
- sessionRegistry.clearAllSessions();
15261
+ await sessionRegistry.clearAllSessions();
14993
15262
  } catch (error) {
14994
15263
  logger.debug(`[StateMachine] Failed to cleanup sessions: ${error}`);
14995
15264
  }
@@ -15086,7 +15355,7 @@ var init_state_machine_execution_engine = __esm({
15086
15355
  * Does not include secrets. Intended for debugging and future resume support.
15087
15356
  */
15088
15357
  async saveSnapshotToFile(filePath) {
15089
- const fs13 = await import("fs/promises");
15358
+ const fs14 = await import("fs/promises");
15090
15359
  const ctx = this._lastContext;
15091
15360
  const runner = this._lastRunner;
15092
15361
  if (!ctx || !runner) {
@@ -15106,14 +15375,14 @@ var init_state_machine_execution_engine = __esm({
15106
15375
  journal: entries,
15107
15376
  requestedChecks: ctx.requestedChecks || []
15108
15377
  };
15109
- await fs13.writeFile(filePath, JSON.stringify(payload, null, 2), "utf8");
15378
+ await fs14.writeFile(filePath, JSON.stringify(payload, null, 2), "utf8");
15110
15379
  }
15111
15380
  /**
15112
15381
  * Load a snapshot JSON from file and return it. Resume support can build on this.
15113
15382
  */
15114
15383
  async loadSnapshotFromFile(filePath) {
15115
- const fs13 = await import("fs/promises");
15116
- const raw = await fs13.readFile(filePath, "utf8");
15384
+ const fs14 = await import("fs/promises");
15385
+ const raw = await fs14.readFile(filePath, "utf8");
15117
15386
  return JSON.parse(raw);
15118
15387
  }
15119
15388
  /**
@@ -15178,6 +15447,20 @@ var init_state_machine_execution_engine = __esm({
15178
15447
  const { convertToReviewSummary: convertToReviewSummary2 } = (init_summary(), __toCommonJS(summary_exports));
15179
15448
  return convertToReviewSummary2(groupedResults, statistics);
15180
15449
  }
15450
+ webhookContextHasConversation(webhookContext) {
15451
+ try {
15452
+ const webhookData = webhookContext?.webhookData;
15453
+ if (!(webhookData instanceof Map)) return false;
15454
+ for (const payload of webhookData.values()) {
15455
+ const value = payload;
15456
+ if (value?.conversation || value?.slack_conversation || value?.mcp_conversation || value?.telegram_conversation || value?.teams_conversation || value?.whatsapp_conversation || value?.email_conversation) {
15457
+ return true;
15458
+ }
15459
+ }
15460
+ } catch {
15461
+ }
15462
+ return false;
15463
+ }
15181
15464
  /**
15182
15465
  * Evaluate failure conditions for a check result
15183
15466
  *
@@ -15192,9 +15475,9 @@ var init_state_machine_execution_engine = __esm({
15192
15475
  * @returns Array of failure condition evaluation results
15193
15476
  */
15194
15477
  async evaluateFailureConditions(checkName, reviewSummary, config, previousOutputs, authorAssociation) {
15195
- const { FailureConditionEvaluator: FailureConditionEvaluator2 } = await import("./failure-condition-evaluator-ZBOSD574.mjs");
15478
+ const { FailureConditionEvaluator: FailureConditionEvaluator2 } = await import("./failure-condition-evaluator-66PWLV3D.mjs");
15196
15479
  const evaluator = new FailureConditionEvaluator2();
15197
- const { addEvent: addEvent3 } = await import("./trace-helpers-AMZ2524G.mjs");
15480
+ const { addEvent: addEvent3 } = await import("./trace-helpers-AIUGQLK5.mjs");
15198
15481
  const { addFailIfTriggered } = await import("./metrics-MYUPQBBV.mjs");
15199
15482
  const checkConfig = config.checks?.[checkName];
15200
15483
  if (!checkConfig) {
@@ -15597,7 +15880,11 @@ var init_scheduler = __esm({
15597
15880
  if (!cron.validate(job.schedule)) {
15598
15881
  throw new Error(`Invalid cron expression: ${job.schedule}`);
15599
15882
  }
15600
- if (job.workflow !== "default") {
15883
+ if (!job.workflow) {
15884
+ if (!job.inputs?.text) {
15885
+ throw new Error("Cron job without a workflow must have inputs.text set");
15886
+ }
15887
+ } else if (job.workflow !== "default") {
15601
15888
  const allChecks = Object.keys(this.visorConfig.checks || {});
15602
15889
  if (!allChecks.includes(job.workflow)) {
15603
15890
  throw new Error(`Workflow "${job.workflow}" not found in configuration`);
@@ -15620,7 +15907,7 @@ var init_scheduler = __esm({
15620
15907
  const nextRun = getNextRunTime(job.schedule, job.timezone || this.defaultTimezone);
15621
15908
  const description = job.description ? ` (${job.description})` : "";
15622
15909
  logger.debug(
15623
- `[Scheduler] Scheduled static cron job '${jobId}'${description}: ${job.schedule} \u2192 ${job.workflow}, next run: ${nextRun.toISOString()}`
15910
+ `[Scheduler] Scheduled static cron job '${jobId}'${description}: ${job.schedule} \u2192 ${job.workflow || "(reminder)"}, next run: ${nextRun.toISOString()}`
15624
15911
  );
15625
15912
  } catch {
15626
15913
  }
@@ -16030,7 +16317,7 @@ var init_scheduler = __esm({
16030
16317
  inputs: schedule.workflowInputs
16031
16318
  });
16032
16319
  if (this.taskStore) {
16033
- const { trackExecution } = await import("./track-execution-VW6P3OYO.mjs");
16320
+ const { trackExecution } = await import("./track-execution-CFRZXMEC.mjs");
16034
16321
  await trackExecution(
16035
16322
  {
16036
16323
  taskStore: this.taskStore,
@@ -16159,7 +16446,7 @@ Please provide an updated response based on the reminder above. You may referenc
16159
16446
  debug: process.env.VISOR_DEBUG === "true"
16160
16447
  });
16161
16448
  if (this.taskStore) {
16162
- const { trackExecution } = await import("./track-execution-VW6P3OYO.mjs");
16449
+ const { trackExecution } = await import("./track-execution-CFRZXMEC.mjs");
16163
16450
  await trackExecution(
16164
16451
  {
16165
16452
  taskStore: this.taskStore,
@@ -17315,7 +17602,7 @@ async function handleTrace(taskId, taskStore) {
17315
17602
  ].filter(Boolean).join("\n")
17316
17603
  };
17317
17604
  }
17318
- const { serializeTraceForPrompt } = await import("./trace-serializer-EBHTHZYT.mjs");
17605
+ const { serializeTraceForPrompt } = await import("./trace-serializer-4TOIAVQL.mjs");
17319
17606
  const taskResponse = task.status?.message?.parts?.[0]?.text;
17320
17607
  const traceTree = await serializeTraceForPrompt(
17321
17608
  resolvedTrace.primaryRef || "",
@@ -17523,7 +17810,7 @@ var init_schedule_tool_handler = __esm({
17523
17810
  });
17524
17811
 
17525
17812
  // src/providers/mcp-custom-sse-server.ts
17526
- import fs7 from "fs";
17813
+ import fs8 from "fs";
17527
17814
  import http from "http";
17528
17815
  import { EventEmitter } from "events";
17529
17816
  function isHttpClientTool(tool) {
@@ -18098,9 +18385,24 @@ var init_mcp_custom_sse_server = __esm({
18098
18385
  }
18099
18386
  return record;
18100
18387
  };
18388
+ const fixRequiredFields = (obj) => {
18389
+ if (!obj || typeof obj !== "object" || Array.isArray(obj)) return obj;
18390
+ const record = obj;
18391
+ if (Array.isArray(record.required) && record.properties && typeof record.properties === "object") {
18392
+ const validProps = Object.keys(record.properties);
18393
+ record.required = record.required.filter((r) => validProps.includes(r));
18394
+ }
18395
+ for (const key of Object.keys(record)) {
18396
+ if (typeof record[key] === "object" && record[key] !== null) {
18397
+ fixRequiredFields(record[key]);
18398
+ }
18399
+ }
18400
+ return record;
18401
+ };
18101
18402
  const normalizeInputSchema = (schema) => {
18102
18403
  if (schema && schema.type === "object") {
18103
18404
  fixArraySchemas(schema);
18405
+ fixRequiredFields(schema);
18104
18406
  return schema;
18105
18407
  }
18106
18408
  return {
@@ -18109,7 +18411,10 @@ var init_mcp_custom_sse_server = __esm({
18109
18411
  required: []
18110
18412
  };
18111
18413
  };
18112
- const regularTools = await this.toolExecutor.listMcpTools();
18414
+ const regularTools = (await this.toolExecutor.listMcpTools()).map((tool) => ({
18415
+ ...tool,
18416
+ inputSchema: normalizeInputSchema(tool.inputSchema)
18417
+ }));
18113
18418
  const workflowTools = Array.from(this.tools.values()).filter(isWorkflowTool).map((tool) => ({
18114
18419
  name: tool.name,
18115
18420
  description: tool.description || `Execute ${tool.name}`,
@@ -18424,7 +18729,7 @@ var init_mcp_custom_sse_server = __esm({
18424
18729
  const contentType = r.content_type || r.output?.content_type || r.result?.content_type || "";
18425
18730
  if (filePath && typeof filePath === "string" && contentType.startsWith("image/")) {
18426
18731
  try {
18427
- const imageBuffer = fs7.readFileSync(filePath);
18732
+ const imageBuffer = fs8.readFileSync(filePath);
18428
18733
  contentBlocks.push({
18429
18734
  type: "image",
18430
18735
  data: imageBuffer.toString("base64"),
@@ -18494,6 +18799,11 @@ var init_mcp_custom_sse_server = __esm({
18494
18799
  if (authType === "bearer" && tool.auth.token) {
18495
18800
  const token = String(EnvironmentResolver.resolveValue(tool.auth.token));
18496
18801
  resolvedHeaders["Authorization"] = `Bearer ${token}`;
18802
+ } else if (authType === "oauth2_client_credentials" && tool.auth.token_url) {
18803
+ const { OAuth2TokenCache: OAuth2TokenCache2 } = await import("./oauth2-token-cache-OS7WHLDI.mjs");
18804
+ const tokenCache = OAuth2TokenCache2.getInstance();
18805
+ const token = await tokenCache.getToken(tool.auth);
18806
+ resolvedHeaders["Authorization"] = `Bearer ${token}`;
18497
18807
  }
18498
18808
  }
18499
18809
  if (this.debug) {
@@ -18592,7 +18902,7 @@ var init_mcp_custom_sse_server = __esm({
18592
18902
  `[CustomToolsSSEServer:${this.sessionId}] Executing UTCP tool '${utcpToolName}' with args: ${JSON.stringify(args)}`
18593
18903
  );
18594
18904
  }
18595
- const { UtcpCheckProvider: UtcpCheckProvider2 } = await import("./utcp-check-provider-Q4PD5EP2.mjs");
18905
+ const { UtcpCheckProvider: UtcpCheckProvider2 } = await import("./utcp-check-provider-WDTSQ7DZ.mjs");
18596
18906
  return UtcpCheckProvider2.callTool(manual, utcpToolName, args, {
18597
18907
  variables: tool.__utcpVariables || {},
18598
18908
  plugins: tool.__utcpPlugins || ["http"],
@@ -18753,7 +19063,7 @@ var init_tool_resolver = __esm({
18753
19063
  });
18754
19064
 
18755
19065
  // src/providers/ai-check-provider.ts
18756
- import fs8 from "fs/promises";
19066
+ import fs9 from "fs/promises";
18757
19067
  import path9 from "path";
18758
19068
  var AICheckProvider;
18759
19069
  var init_ai_check_provider = __esm({
@@ -18774,6 +19084,7 @@ var init_ai_check_provider = __esm({
18774
19084
  init_schedule_tool();
18775
19085
  init_task_progress_tool();
18776
19086
  init_schedule_tool_handler();
19087
+ init_user_facing_error();
18777
19088
  AICheckProvider = class _AICheckProvider extends CheckProvider {
18778
19089
  aiReviewService;
18779
19090
  liquidEngine;
@@ -18953,9 +19264,9 @@ var init_ai_check_provider = __esm({
18953
19264
  } else {
18954
19265
  resolvedPath = path9.resolve(process.cwd(), str);
18955
19266
  }
18956
- const fs13 = __require("fs").promises;
19267
+ const fs14 = __require("fs").promises;
18957
19268
  try {
18958
- const stat2 = await fs13.stat(resolvedPath);
19269
+ const stat2 = await fs14.stat(resolvedPath);
18959
19270
  return stat2.isFile();
18960
19271
  } catch {
18961
19272
  return hasFileExtension && (isRelativePath || isAbsolutePath || hasPathSeparators);
@@ -18988,7 +19299,7 @@ var init_ai_check_provider = __esm({
18988
19299
  throw new Error("Invalid prompt file path: path traversal detected");
18989
19300
  }
18990
19301
  try {
18991
- const promptContent = await fs8.readFile(resolvedPath, "utf-8");
19302
+ const promptContent = await fs9.readFile(resolvedPath, "utf-8");
18992
19303
  return promptContent;
18993
19304
  } catch (error) {
18994
19305
  throw new Error(
@@ -19904,7 +20215,7 @@ ${preview}`);
19904
20215
  if (utcpEntriesFromMcp.length > 0) {
19905
20216
  for (const entry of utcpEntriesFromMcp) {
19906
20217
  try {
19907
- const { UtcpCheckProvider: UtcpCheckProvider2 } = await import("./utcp-check-provider-Q4PD5EP2.mjs");
20218
+ const { UtcpCheckProvider: UtcpCheckProvider2 } = await import("./utcp-check-provider-WDTSQ7DZ.mjs");
19908
20219
  const manual = entry.config.manual;
19909
20220
  const variables = entry.config.variables;
19910
20221
  const plugins = entry.config.plugins || ["http"];
@@ -20376,13 +20687,14 @@ ${processedPrompt}` : processedPrompt;
20376
20687
  }
20377
20688
  } catch (error) {
20378
20689
  const errorMessage = error instanceof Error ? error.message : String(error);
20690
+ const userFacingMessage = formatUserFacingExecutionError(error);
20379
20691
  console.error(`\u274C AI Check Provider Error for check: ${errorMessage}`);
20380
20692
  const isCriticalError = errorMessage.includes("API rate limit") || errorMessage.includes("403") || errorMessage.includes("401") || errorMessage.includes("authentication") || errorMessage.includes("API key");
20381
20693
  if (isCriticalError) {
20382
20694
  console.error(`\u{1F6A8} CRITICAL ERROR: AI provider authentication or rate limit issue detected`);
20383
20695
  console.error(`\u{1F6A8} This check cannot proceed without valid API credentials`);
20384
20696
  }
20385
- throw new Error(`AI analysis failed: ${errorMessage}`);
20697
+ throw new Error(userFacingMessage);
20386
20698
  } finally {
20387
20699
  if (customToolsServer) {
20388
20700
  try {
@@ -21277,114 +21589,8 @@ var init_template_context = __esm({
21277
21589
  }
21278
21590
  });
21279
21591
 
21280
- // src/utils/oauth2-token-cache.ts
21281
- var OAuth2TokenCache;
21282
- var init_oauth2_token_cache = __esm({
21283
- "src/utils/oauth2-token-cache.ts"() {
21284
- "use strict";
21285
- init_logger();
21286
- init_env_resolver();
21287
- OAuth2TokenCache = class _OAuth2TokenCache {
21288
- static instance;
21289
- cache = /* @__PURE__ */ new Map();
21290
- static getInstance() {
21291
- if (!_OAuth2TokenCache.instance) {
21292
- _OAuth2TokenCache.instance = new _OAuth2TokenCache();
21293
- }
21294
- return _OAuth2TokenCache.instance;
21295
- }
21296
- /** Visible for testing */
21297
- static resetInstance() {
21298
- _OAuth2TokenCache.instance = void 0;
21299
- }
21300
- /**
21301
- * Get a valid Bearer token for the given config.
21302
- * Returns a cached token if still valid, otherwise fetches a new one.
21303
- */
21304
- async getToken(config) {
21305
- const clientId = String(EnvironmentResolver.resolveValue(config.client_id));
21306
- const clientSecret = String(EnvironmentResolver.resolveValue(config.client_secret));
21307
- const tokenUrl = String(EnvironmentResolver.resolveValue(config.token_url));
21308
- const bufferMs = (config.token_ttl_buffer ?? 300) * 1e3;
21309
- const cacheKey = `${tokenUrl}|${clientId}`;
21310
- const cached = this.cache.get(cacheKey);
21311
- if (cached && cached.expires_at - bufferMs > Date.now()) {
21312
- logger.verbose("[oauth2] Using cached token");
21313
- return cached.access_token;
21314
- }
21315
- if (cached?.refreshPromise) {
21316
- logger.verbose("[oauth2] Awaiting in-flight token refresh");
21317
- return cached.refreshPromise;
21318
- }
21319
- const refreshPromise = this.fetchToken(tokenUrl, clientId, clientSecret, config.scopes);
21320
- if (cached) {
21321
- cached.refreshPromise = refreshPromise;
21322
- } else {
21323
- this.cache.set(cacheKey, {
21324
- access_token: "",
21325
- expires_at: 0,
21326
- refreshPromise
21327
- });
21328
- }
21329
- try {
21330
- const token = await refreshPromise;
21331
- return token;
21332
- } finally {
21333
- const entry = this.cache.get(cacheKey);
21334
- if (entry) {
21335
- entry.refreshPromise = void 0;
21336
- }
21337
- }
21338
- }
21339
- async fetchToken(tokenUrl, clientId, clientSecret, scopes) {
21340
- logger.verbose(`[oauth2] Fetching token from ${tokenUrl}`);
21341
- const credentials = Buffer.from(`${clientId}:${clientSecret}`).toString("base64");
21342
- const bodyParams = new URLSearchParams({ grant_type: "client_credentials" });
21343
- if (scopes?.length) {
21344
- bodyParams.set("scope", scopes.join(" "));
21345
- }
21346
- const response = await fetch(tokenUrl, {
21347
- method: "POST",
21348
- headers: {
21349
- "Content-Type": "application/x-www-form-urlencoded",
21350
- Authorization: `Basic ${credentials}`
21351
- },
21352
- body: bodyParams.toString()
21353
- });
21354
- if (!response.ok) {
21355
- let errorDetail = "";
21356
- try {
21357
- errorDetail = await response.text();
21358
- } catch {
21359
- }
21360
- throw new Error(
21361
- `OAuth2 token request failed: HTTP ${response.status} ${response.statusText}${errorDetail ? ` - ${errorDetail.substring(0, 200)}` : ""}`
21362
- );
21363
- }
21364
- const data = await response.json();
21365
- if (!data.access_token) {
21366
- throw new Error("OAuth2 token response missing access_token");
21367
- }
21368
- const expiresIn = data.expires_in ?? 3600;
21369
- const expiresAt = Date.now() + expiresIn * 1e3;
21370
- const cacheKey = `${tokenUrl}|${clientId}`;
21371
- this.cache.set(cacheKey, {
21372
- access_token: data.access_token,
21373
- expires_at: expiresAt
21374
- });
21375
- logger.verbose(`[oauth2] Token acquired, expires in ${expiresIn}s`);
21376
- return data.access_token;
21377
- }
21378
- /** Clear all cached tokens (for testing or credential rotation) */
21379
- clear() {
21380
- this.cache.clear();
21381
- }
21382
- };
21383
- }
21384
- });
21385
-
21386
21592
  // src/providers/http-client-provider.ts
21387
- import * as fs9 from "fs";
21593
+ import * as fs10 from "fs";
21388
21594
  import * as path10 from "path";
21389
21595
  var HttpClientProvider;
21390
21596
  var init_http_client_provider = __esm({
@@ -21530,8 +21736,8 @@ var init_http_client_provider = __esm({
21530
21736
  `[http_client] Resolved relative output_file to workspace: ${resolvedOutputFile}`
21531
21737
  );
21532
21738
  }
21533
- if (skipIfExists && fs9.existsSync(resolvedOutputFile)) {
21534
- const stats = fs9.statSync(resolvedOutputFile);
21739
+ if (skipIfExists && fs10.existsSync(resolvedOutputFile)) {
21740
+ const stats = fs10.statSync(resolvedOutputFile);
21535
21741
  logger.verbose(`[http_client] File cached: ${resolvedOutputFile} (${stats.size} bytes)`);
21536
21742
  return {
21537
21743
  issues: [],
@@ -21762,12 +21968,12 @@ var init_http_client_provider = __esm({
21762
21968
  };
21763
21969
  }
21764
21970
  const parentDir = path10.dirname(outputFile);
21765
- if (parentDir && !fs9.existsSync(parentDir)) {
21766
- fs9.mkdirSync(parentDir, { recursive: true });
21971
+ if (parentDir && !fs10.existsSync(parentDir)) {
21972
+ fs10.mkdirSync(parentDir, { recursive: true });
21767
21973
  }
21768
21974
  const arrayBuffer = await response.arrayBuffer();
21769
21975
  const buffer = Buffer.from(arrayBuffer);
21770
- fs9.writeFileSync(outputFile, buffer);
21976
+ fs10.writeFileSync(outputFile, buffer);
21771
21977
  const contentType = response.headers.get("content-type") || "application/octet-stream";
21772
21978
  logger.verbose(`[http_client] Downloaded: ${outputFile} (${buffer.length} bytes)`);
21773
21979
  return {
@@ -22534,7 +22740,7 @@ var init_claude_code_types = __esm({
22534
22740
  });
22535
22741
 
22536
22742
  // src/providers/claude-code-check-provider.ts
22537
- import fs10 from "fs/promises";
22743
+ import fs11 from "fs/promises";
22538
22744
  import path11 from "path";
22539
22745
  function isClaudeCodeConstructor(value) {
22540
22746
  return typeof value === "function";
@@ -22710,7 +22916,7 @@ var init_claude_code_check_provider = __esm({
22710
22916
  resolvedPath = path11.resolve(process.cwd(), str);
22711
22917
  }
22712
22918
  try {
22713
- const stat2 = await fs10.stat(resolvedPath);
22919
+ const stat2 = await fs11.stat(resolvedPath);
22714
22920
  return stat2.isFile();
22715
22921
  } catch {
22716
22922
  return hasFileExtension && (isRelativePath || isAbsolutePath || hasPathSeparators);
@@ -22743,7 +22949,7 @@ var init_claude_code_check_provider = __esm({
22743
22949
  throw new Error("Invalid prompt file path: path traversal detected");
22744
22950
  }
22745
22951
  try {
22746
- const promptContent = await fs10.readFile(resolvedPath, "utf-8");
22952
+ const promptContent = await fs11.readFile(resolvedPath, "utf-8");
22747
22953
  return promptContent;
22748
22954
  } catch (error) {
22749
22955
  throw new Error(
@@ -41997,6 +42203,14 @@ var init_mcp_check_provider = __esm({
41997
42203
  }
41998
42204
  );
41999
42205
  const transport = createTransport();
42206
+ if ("stderr" in transport && transport.stderr) {
42207
+ const stderrStream = transport.stderr;
42208
+ if (typeof stderrStream.on === "function") {
42209
+ stderrStream.on("error", (err) => {
42210
+ logger.debug(`MCP transport stderr error (${transportName}): ${err.message}`);
42211
+ });
42212
+ }
42213
+ }
42000
42214
  try {
42001
42215
  let timeoutId;
42002
42216
  try {
@@ -42557,7 +42771,7 @@ var init_stdin_reader = __esm({
42557
42771
  });
42558
42772
 
42559
42773
  // src/providers/human-input-check-provider.ts
42560
- import * as fs11 from "fs";
42774
+ import * as fs12 from "fs";
42561
42775
  import * as path12 from "path";
42562
42776
  var HumanInputCheckProvider;
42563
42777
  var init_human_input_check_provider = __esm({
@@ -42748,12 +42962,12 @@ var init_human_input_check_provider = __esm({
42748
42962
  return null;
42749
42963
  }
42750
42964
  try {
42751
- await fs11.promises.access(normalizedPath, fs11.constants.R_OK);
42752
- const stats = await fs11.promises.stat(normalizedPath);
42965
+ await fs12.promises.access(normalizedPath, fs12.constants.R_OK);
42966
+ const stats = await fs12.promises.stat(normalizedPath);
42753
42967
  if (!stats.isFile()) {
42754
42968
  return null;
42755
42969
  }
42756
- const content = await fs11.promises.readFile(normalizedPath, "utf-8");
42970
+ const content = await fs12.promises.readFile(normalizedPath, "utf-8");
42757
42971
  return content.trim();
42758
42972
  } catch {
42759
42973
  return null;
@@ -43321,8 +43535,8 @@ function buildBuiltinGlobals(opts) {
43321
43535
  const asyncFunctionNames = /* @__PURE__ */ new Set();
43322
43536
  const scheduleFn = async (args = {}) => {
43323
43537
  try {
43324
- const { handleScheduleAction: handleScheduleAction2, buildScheduleToolContext: buildScheduleToolContext2 } = await import("./schedule-tool-LB33KL2W.mjs");
43325
- const { extractSlackContext: extractSlackContext2 } = await import("./schedule-tool-handler-KYWZHKSS.mjs");
43538
+ const { handleScheduleAction: handleScheduleAction2, buildScheduleToolContext: buildScheduleToolContext2 } = await import("./schedule-tool-WMGSM6IT.mjs");
43539
+ const { extractSlackContext: extractSlackContext2 } = await import("./schedule-tool-handler-JMDHCGZ2.mjs");
43326
43540
  const parentCtx = opts.sessionInfo?._parentContext;
43327
43541
  const webhookData = parentCtx?.prInfo?.eventContext?.webhookData;
43328
43542
  const webhookEventType = parentCtx?.webhookContext?.eventType || parentCtx?.prInfo?.eventContext?.eventType;
@@ -43810,6 +44024,11 @@ var init_script_check_provider = __esm({
43810
44024
  env,
43811
44025
  stderr: "pipe"
43812
44026
  });
44027
+ if (transport.stderr) {
44028
+ transport.stderr.on("error", (err) => {
44029
+ logger.debug(`MCP transport stderr error: ${err.message}`);
44030
+ });
44031
+ }
43813
44032
  await Promise.race([
43814
44033
  client.connect(transport),
43815
44034
  new Promise(
@@ -43907,8 +44126,39 @@ var init_script_check_provider = __esm({
43907
44126
  }
43908
44127
  });
43909
44128
 
44129
+ // src/utils/child-process-error-handler.ts
44130
+ function isChildProcessIOError(error) {
44131
+ if (!(error instanceof Error)) return false;
44132
+ const errno = error.code;
44133
+ if (errno && TRANSIENT_IO_CODES.has(errno)) return true;
44134
+ const msg = error.message;
44135
+ if (msg.includes("read EIO") || msg.includes("write EPIPE")) return true;
44136
+ if (msg.includes("ERR_STREAM_DESTROYED")) return true;
44137
+ return false;
44138
+ }
44139
+ var TRANSIENT_IO_CODES, GUARD;
44140
+ var init_child_process_error_handler = __esm({
44141
+ "src/utils/child-process-error-handler.ts"() {
44142
+ "use strict";
44143
+ init_logger();
44144
+ TRANSIENT_IO_CODES = /* @__PURE__ */ new Set(["EIO", "EPIPE", "ECONNRESET"]);
44145
+ GUARD = Symbol.for("visor.childProcessErrorHandler");
44146
+ if (!globalThis[GUARD]) {
44147
+ globalThis[GUARD] = true;
44148
+ process.on("uncaughtException", (error, origin) => {
44149
+ if (isChildProcessIOError(error)) {
44150
+ logger.warn(
44151
+ `[child-process-error-handler] Suppressed transient I/O error (${origin}): ${error.message}`
44152
+ );
44153
+ return;
44154
+ }
44155
+ });
44156
+ }
44157
+ }
44158
+ });
44159
+
43910
44160
  // src/utils/worktree-manager.ts
43911
- import * as fs12 from "fs";
44161
+ import * as fs13 from "fs";
43912
44162
  import * as fsp2 from "fs/promises";
43913
44163
  import * as path13 from "path";
43914
44164
  import * as crypto from "crypto";
@@ -43917,6 +44167,7 @@ var init_worktree_manager = __esm({
43917
44167
  "src/utils/worktree-manager.ts"() {
43918
44168
  "use strict";
43919
44169
  init_command_executor();
44170
+ init_child_process_error_handler();
43920
44171
  init_logger();
43921
44172
  WorktreeManager = class _WorktreeManager {
43922
44173
  static instance;
@@ -43967,12 +44218,12 @@ var init_worktree_manager = __esm({
43967
44218
  }
43968
44219
  const reposDir = this.getReposDir();
43969
44220
  const worktreesDir = this.getWorktreesDir();
43970
- if (!fs12.existsSync(reposDir)) {
43971
- fs12.mkdirSync(reposDir, { recursive: true });
44221
+ if (!fs13.existsSync(reposDir)) {
44222
+ fs13.mkdirSync(reposDir, { recursive: true });
43972
44223
  logger.debug(`Created repos directory: ${reposDir}`);
43973
44224
  }
43974
- if (!fs12.existsSync(worktreesDir)) {
43975
- fs12.mkdirSync(worktreesDir, { recursive: true });
44225
+ if (!fs13.existsSync(worktreesDir)) {
44226
+ fs13.mkdirSync(worktreesDir, { recursive: true });
43976
44227
  logger.debug(`Created worktrees directory: ${worktreesDir}`);
43977
44228
  }
43978
44229
  }
@@ -44006,7 +44257,7 @@ var init_worktree_manager = __esm({
44006
44257
  const reposDir = this.getReposDir();
44007
44258
  const repoName = repository.replace(/\//g, "-");
44008
44259
  const bareRepoPath = path13.join(reposDir, `${repoName}.git`);
44009
- if (fs12.existsSync(bareRepoPath)) {
44260
+ if (fs13.existsSync(bareRepoPath)) {
44010
44261
  logger.debug(`Bare repository already exists: ${bareRepoPath}`);
44011
44262
  const verifyResult = await this.verifyBareRepoRemote(bareRepoPath, repoUrl);
44012
44263
  if (verifyResult === "timeout") {
@@ -44075,6 +44326,7 @@ var init_worktree_manager = __esm({
44075
44326
  const result = await this.executeGitCommand(updateCmd, { timeout: 9e4 });
44076
44327
  if (result.exitCode === 0) {
44077
44328
  logger.debug(`Successfully updated bare repository`);
44329
+ await this.gcBareRepo(bareRepoPath);
44078
44330
  return;
44079
44331
  }
44080
44332
  logger.warn(`Bare repo update attempt ${attempt}/2 failed: ${result.stderr}`);
@@ -44088,6 +44340,36 @@ var init_worktree_manager = __esm({
44088
44340
  }
44089
44341
  logger.warn(`Failed to update bare repository after 2 attempts (will rely on per-ref fetch)`);
44090
44342
  }
44343
+ /**
44344
+ * Consolidate pack files after fetch to prevent unbounded pack accumulation.
44345
+ * Each `git fetch` creates a new pack file; without periodic repacking these
44346
+ * pile up and waste disk (especially on COW filesystems like BTRFS).
44347
+ */
44348
+ async gcBareRepo(bareRepoPath) {
44349
+ try {
44350
+ const packDir = path13.join(bareRepoPath, "objects", "pack");
44351
+ if (!fs13.existsSync(packDir)) return;
44352
+ const packFiles = fs13.readdirSync(packDir).filter((f) => f.endsWith(".pack"));
44353
+ if (packFiles.length <= 3) return;
44354
+ if (packFiles.length > 10) {
44355
+ logger.info(`Repacking bare repo (${packFiles.length} packs): ${bareRepoPath}`);
44356
+ const repackCmd = `git -C ${this.escapeShellArg(bareRepoPath)} repack -a -d --unpack-unreachable=now`;
44357
+ const result = await this.executeGitCommand(repackCmd, { timeout: 3e5 });
44358
+ if (result.exitCode === 0) {
44359
+ logger.info(`Repack complete for ${bareRepoPath}`);
44360
+ const pruneCmd = `git -C ${this.escapeShellArg(bareRepoPath)} prune --expire=now`;
44361
+ await this.executeGitCommand(pruneCmd, { timeout: 6e4 });
44362
+ } else {
44363
+ logger.warn(`Repack failed: ${result.stderr}`);
44364
+ }
44365
+ } else {
44366
+ const gcCmd = `git -C ${this.escapeShellArg(bareRepoPath)} gc --auto`;
44367
+ await this.executeGitCommand(gcCmd, { timeout: 12e4 });
44368
+ }
44369
+ } catch (error) {
44370
+ logger.debug(`gc/repack non-fatal error: ${error}`);
44371
+ }
44372
+ }
44091
44373
  /**
44092
44374
  * Verify that a bare repository has the correct remote URL.
44093
44375
  * This prevents reusing corrupted repos that were cloned from a different repository.
@@ -44180,7 +44462,7 @@ var init_worktree_manager = __esm({
44180
44462
  worktreePath = this.validatePath(options.workingDirectory);
44181
44463
  }
44182
44464
  let refreshFailedNeedsRecreate = false;
44183
- if (fs12.existsSync(worktreePath)) {
44465
+ if (fs13.existsSync(worktreePath)) {
44184
44466
  logger.debug(`Worktree already exists: ${worktreePath}`);
44185
44467
  const metadata2 = await this.loadMetadata(worktreePath);
44186
44468
  if (metadata2) {
@@ -44509,9 +44791,13 @@ var init_worktree_manager = __esm({
44509
44791
  * Remove a worktree
44510
44792
  */
44511
44793
  async removeWorktree(worktreeId) {
44512
- const metadata = this.activeWorktrees.get(worktreeId);
44794
+ let metadata = this.activeWorktrees.get(worktreeId);
44513
44795
  if (!metadata) {
44514
- logger.warn(`Worktree not found in active list: ${worktreeId}`);
44796
+ const worktreePath = path13.join(this.getWorktreesDir(), worktreeId);
44797
+ metadata = await this.loadMetadata(worktreePath) || void 0;
44798
+ }
44799
+ if (!metadata) {
44800
+ logger.warn(`Worktree metadata not found: ${worktreeId}`);
44515
44801
  return;
44516
44802
  }
44517
44803
  const { bare_repo_path, worktree_path } = metadata;
@@ -44520,15 +44806,15 @@ var init_worktree_manager = __esm({
44520
44806
  const result = await this.executeGitCommand(removeCmd, { timeout: 3e4 });
44521
44807
  if (result.exitCode !== 0) {
44522
44808
  logger.warn(`Failed to remove worktree via git: ${result.stderr}`);
44523
- if (fs12.existsSync(worktree_path)) {
44809
+ if (fs13.existsSync(worktree_path)) {
44524
44810
  logger.debug(`Manually removing worktree directory`);
44525
- fs12.rmSync(worktree_path, { recursive: true, force: true });
44811
+ fs13.rmSync(worktree_path, { recursive: true, force: true });
44526
44812
  }
44527
44813
  }
44528
44814
  const metadataPath = this.getMetadataPath(worktree_path);
44529
44815
  try {
44530
- if (fs12.existsSync(metadataPath)) {
44531
- fs12.unlinkSync(metadataPath);
44816
+ if (fs13.existsSync(metadataPath)) {
44817
+ fs13.unlinkSync(metadataPath);
44532
44818
  }
44533
44819
  } catch {
44534
44820
  }
@@ -44548,7 +44834,7 @@ var init_worktree_manager = __esm({
44548
44834
  */
44549
44835
  async saveMetadata(worktreePath, metadata) {
44550
44836
  const metadataPath = this.getMetadataPath(worktreePath);
44551
- fs12.writeFileSync(metadataPath, JSON.stringify(metadata, null, 2), "utf8");
44837
+ fs13.writeFileSync(metadataPath, JSON.stringify(metadata, null, 2), "utf8");
44552
44838
  }
44553
44839
  /**
44554
44840
  * Load worktree metadata
@@ -44556,12 +44842,12 @@ var init_worktree_manager = __esm({
44556
44842
  async loadMetadata(worktreePath) {
44557
44843
  const metadataPath = this.getMetadataPath(worktreePath);
44558
44844
  const legacyPath = path13.join(worktreePath, ".visor-metadata.json");
44559
- const pathToRead = fs12.existsSync(metadataPath) ? metadataPath : fs12.existsSync(legacyPath) ? legacyPath : null;
44845
+ const pathToRead = fs13.existsSync(metadataPath) ? metadataPath : fs13.existsSync(legacyPath) ? legacyPath : null;
44560
44846
  if (!pathToRead) {
44561
44847
  return null;
44562
44848
  }
44563
44849
  try {
44564
- const content = fs12.readFileSync(pathToRead, "utf8");
44850
+ const content = fs13.readFileSync(pathToRead, "utf8");
44565
44851
  return JSON.parse(content);
44566
44852
  } catch (error) {
44567
44853
  logger.warn(`Failed to load metadata: ${error}`);
@@ -44573,10 +44859,10 @@ var init_worktree_manager = __esm({
44573
44859
  */
44574
44860
  async listWorktrees() {
44575
44861
  const worktreesDir = this.getWorktreesDir();
44576
- if (!fs12.existsSync(worktreesDir)) {
44862
+ if (!fs13.existsSync(worktreesDir)) {
44577
44863
  return [];
44578
44864
  }
44579
- const entries = fs12.readdirSync(worktreesDir, { withFileTypes: true });
44865
+ const entries = fs13.readdirSync(worktreesDir, { withFileTypes: true });
44580
44866
  const worktrees = [];
44581
44867
  for (const entry of entries) {
44582
44868
  if (!entry.isDirectory()) continue;
@@ -44664,6 +44950,10 @@ var init_worktree_manager = __esm({
44664
44950
  process.exit(143);
44665
44951
  });
44666
44952
  process.on("uncaughtException", async (error) => {
44953
+ if (isChildProcessIOError(error)) {
44954
+ logger.warn(`Ignoring transient child-process I/O error: ${error.message}`);
44955
+ return;
44956
+ }
44667
44957
  logger.error(`Uncaught exception, cleaning up worktrees: ${error}`);
44668
44958
  await this.cleanupProcessWorktrees();
44669
44959
  process.exit(1);
@@ -45731,7 +46021,7 @@ var init_workflow_executor = __esm({
45731
46021
  if (step.if) {
45732
46022
  const shouldRun = this.evaluateCondition(step.if, {
45733
46023
  inputs: executionContext.inputs,
45734
- outputs: Object.fromEntries(stepResults),
46024
+ outputs: this.unwrapOutputs(stepResults),
45735
46025
  pr: runOptions.prInfo
45736
46026
  });
45737
46027
  if (!shouldRun) {
@@ -45894,18 +46184,14 @@ var init_workflow_executor = __esm({
45894
46184
  throw new Error("Expression mapping requires expression field");
45895
46185
  }
45896
46186
  const sandbox = createSecureSandbox();
46187
+ const unwrappedExpr = this.unwrapOutputs(stepResults);
45897
46188
  return compileAndRun(
45898
46189
  sandbox,
45899
46190
  typedMapping.expression,
45900
46191
  {
45901
46192
  inputs: executionContext.inputs,
45902
- outputs: Object.fromEntries(stepResults),
45903
- steps: Object.fromEntries(
45904
- Array.from(stepResults.entries()).map(([id, result]) => [
45905
- id,
45906
- result.output
45907
- ])
45908
- )
46193
+ outputs: unwrappedExpr,
46194
+ steps: unwrappedExpr
45909
46195
  },
45910
46196
  { injectLog: true, logPrefix: "workflow.input.expression" }
45911
46197
  );
@@ -45918,7 +46204,7 @@ var init_workflow_executor = __esm({
45918
46204
  if (typedMapping.template) {
45919
46205
  return await this.liquid.parseAndRender(typedMapping.template, {
45920
46206
  inputs: executionContext.inputs,
45921
- outputs: Object.fromEntries(stepResults)
46207
+ outputs: this.unwrapOutputs(stepResults)
45922
46208
  });
45923
46209
  }
45924
46210
  }
@@ -45945,32 +46231,44 @@ var init_workflow_executor = __esm({
45945
46231
  for (const output of workflow.outputs) {
45946
46232
  if (output.value_js) {
45947
46233
  const sandbox = createSecureSandbox();
46234
+ const unwrapped = this.unwrapOutputs(stepResults);
45948
46235
  outputs[output.name] = compileAndRun(
45949
46236
  sandbox,
45950
46237
  output.value_js,
45951
46238
  {
45952
46239
  inputs: executionContext.inputs,
45953
- steps: Object.fromEntries(
45954
- Array.from(stepResults.entries()).map(([id, result]) => [id, result.output])
45955
- ),
45956
- outputs: Object.fromEntries(stepResults),
46240
+ steps: unwrapped,
46241
+ outputs: unwrapped,
45957
46242
  pr: prInfo
45958
46243
  },
45959
46244
  { injectLog: true, logPrefix: `workflow.output.${output.name}` }
45960
46245
  );
45961
46246
  } else if (output.value) {
46247
+ const unwrappedLiquid = this.unwrapOutputs(stepResults);
45962
46248
  outputs[output.name] = await this.liquid.parseAndRender(output.value, {
45963
46249
  inputs: executionContext.inputs,
45964
- steps: Object.fromEntries(
45965
- Array.from(stepResults.entries()).map(([id, result]) => [id, result.output])
45966
- ),
45967
- outputs: Object.fromEntries(stepResults),
46250
+ steps: unwrappedLiquid,
46251
+ outputs: unwrappedLiquid,
45968
46252
  pr: prInfo
45969
46253
  });
45970
46254
  }
45971
46255
  }
45972
46256
  return outputs;
45973
46257
  }
46258
+ /**
46259
+ * Unwrap step outputs from ReviewSummary wrappers.
46260
+ * Script steps and MCP steps store results as { issues: [], output: <actual> }.
46261
+ * Workflow value_js/if/Liquid should see the unwrapped output, consistent with
46262
+ * how script step contexts already unwrap via buildProviderTemplateContext.
46263
+ */
46264
+ unwrapOutputs(stepResults) {
46265
+ const unwrapped = {};
46266
+ for (const [id, result] of stepResults.entries()) {
46267
+ const summary = result;
46268
+ unwrapped[id] = summary.output !== void 0 ? summary.output : summary;
46269
+ }
46270
+ return unwrapped;
46271
+ }
45974
46272
  /**
45975
46273
  * Aggregate results from all steps
45976
46274
  */
@@ -46162,6 +46460,7 @@ var init_workflow_check_provider = __esm({
46162
46460
  init_toolkit_expander();
46163
46461
  init_human_id();
46164
46462
  init_liquid_extensions();
46463
+ init_user_facing_error();
46165
46464
  WorkflowCheckProvider = class extends CheckProvider {
46166
46465
  registry;
46167
46466
  executor;
@@ -46779,6 +47078,18 @@ var init_workflow_check_provider = __esm({
46779
47078
  scoreCount++;
46780
47079
  }
46781
47080
  }
47081
+ for (const checkStats of result.statistics?.checks || []) {
47082
+ if (checkStats.errorMessage) {
47083
+ allIssues.push({
47084
+ file: "system",
47085
+ line: 0,
47086
+ ruleId: "system/error",
47087
+ message: formatUserFacingExecutionMessage(checkStats.errorMessage),
47088
+ severity: "error",
47089
+ category: "logic"
47090
+ });
47091
+ }
47092
+ }
46782
47093
  const outputs = await this.computeWorkflowOutputsFromState(
46783
47094
  workflow,
46784
47095
  inputs,
@@ -46973,13 +47284,13 @@ var init_workflow_check_provider = __esm({
46973
47284
  */
46974
47285
  async loadWorkflowFromConfigPath(sourcePath, baseDir) {
46975
47286
  const path15 = __require("path");
46976
- const fs13 = __require("fs");
47287
+ const fs14 = __require("fs");
46977
47288
  const yaml3 = __require("js-yaml");
46978
47289
  const resolved = path15.isAbsolute(sourcePath) ? sourcePath : path15.resolve(baseDir, sourcePath);
46979
- if (!fs13.existsSync(resolved)) {
47290
+ if (!fs14.existsSync(resolved)) {
46980
47291
  throw new Error(`Workflow config not found at: ${resolved}`);
46981
47292
  }
46982
- const rawContent = fs13.readFileSync(resolved, "utf8");
47293
+ const rawContent = fs14.readFileSync(resolved, "utf8");
46983
47294
  const rawData = yaml3.load(rawContent);
46984
47295
  if (rawData.imports && Array.isArray(rawData.imports)) {
46985
47296
  const configDir = path15.dirname(resolved);
@@ -47061,4 +47372,4 @@ undici/lib/fetch/body.js:
47061
47372
  undici/lib/websocket/frame.js:
47062
47373
  (*! ws. MIT License. Einar Otto Stangvik <einaros@gmail.com> *)
47063
47374
  */
47064
- //# sourceMappingURL=chunk-NPOVLLKH.mjs.map
47375
+ //# sourceMappingURL=chunk-TGQBEM3Y.mjs.map