@probelabs/visor 0.1.182-ee → 0.1.183-ee

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 (205) hide show
  1. package/defaults/assistant.yaml +2 -1
  2. package/defaults/code-talk.yaml +6 -0
  3. package/defaults/skills/task-progress.yaml +39 -0
  4. package/dist/agent-protocol/task-evaluator.d.ts +2 -1
  5. package/dist/agent-protocol/task-evaluator.d.ts.map +1 -1
  6. package/dist/agent-protocol/task-progress-tool.d.ts +29 -0
  7. package/dist/agent-protocol/task-progress-tool.d.ts.map +1 -0
  8. package/dist/agent-protocol/task-store.d.ts +8 -0
  9. package/dist/agent-protocol/task-store.d.ts.map +1 -1
  10. package/dist/agent-protocol/tasks-cli-handler.d.ts.map +1 -1
  11. package/dist/agent-protocol/trace-serializer.d.ts +5 -2
  12. package/dist/agent-protocol/trace-serializer.d.ts.map +1 -1
  13. package/dist/agent-protocol/track-execution.d.ts +1 -1
  14. package/dist/agent-protocol/track-execution.d.ts.map +1 -1
  15. package/dist/ai-review-service.d.ts.map +1 -1
  16. package/dist/cli-main.d.ts.map +1 -1
  17. package/dist/debug-visualizer/trace-reader.d.ts.map +1 -1
  18. package/dist/defaults/assistant.yaml +2 -1
  19. package/dist/defaults/code-talk.yaml +6 -0
  20. package/dist/defaults/skills/task-progress.yaml +39 -0
  21. package/dist/docs/telemetry-live-spans-plan.md +510 -0
  22. package/dist/generated/config-schema.json +43 -6
  23. package/dist/index.js +3545 -701
  24. package/dist/providers/ai-check-provider.d.ts.map +1 -1
  25. package/dist/providers/git-checkout-provider.d.ts.map +1 -1
  26. package/dist/providers/mcp-custom-sse-server.d.ts.map +1 -1
  27. package/dist/reviewer.d.ts +2 -0
  28. package/dist/reviewer.d.ts.map +1 -1
  29. package/dist/runners/process-cli-handler.d.ts +2 -0
  30. package/dist/runners/process-cli-handler.d.ts.map +1 -0
  31. package/dist/runners/process-discovery.d.ts +29 -0
  32. package/dist/runners/process-discovery.d.ts.map +1 -0
  33. package/dist/sandbox/check-runner.d.ts.map +1 -1
  34. package/dist/sandbox/sandbox-telemetry.d.ts +7 -0
  35. package/dist/sandbox/sandbox-telemetry.d.ts.map +1 -1
  36. package/dist/sandbox/trace-ingester.d.ts +28 -15
  37. package/dist/sandbox/trace-ingester.d.ts.map +1 -1
  38. package/dist/scheduler/schedule-tool.d.ts +5 -0
  39. package/dist/scheduler/schedule-tool.d.ts.map +1 -1
  40. package/dist/sdk/{a2a-frontend-MU5EO2HZ.mjs → a2a-frontend-5YDHFQXD.mjs} +47 -8
  41. package/dist/sdk/{a2a-frontend-MU5EO2HZ.mjs.map → a2a-frontend-5YDHFQXD.mjs.map} +1 -1
  42. package/dist/sdk/{a2a-frontend-4LP3MLTS.mjs → a2a-frontend-6LWBIPMS.mjs} +19 -3
  43. package/dist/sdk/a2a-frontend-6LWBIPMS.mjs.map +1 -0
  44. package/dist/sdk/check-provider-registry-WSEVHJEV.mjs +31 -0
  45. package/dist/sdk/{check-provider-registry-I4BCWKRU.mjs → check-provider-registry-YRADEEQY.mjs} +6 -6
  46. package/dist/sdk/chunk-4BN2XI4X.mjs +459 -0
  47. package/dist/sdk/chunk-4BN2XI4X.mjs.map +1 -0
  48. package/dist/sdk/chunk-54KOAC4W.mjs +665 -0
  49. package/dist/sdk/chunk-54KOAC4W.mjs.map +1 -0
  50. package/dist/sdk/chunk-6C3R6E42.mjs +1700 -0
  51. package/dist/sdk/chunk-6C3R6E42.mjs.map +1 -0
  52. package/dist/sdk/{chunk-4I3TJ7UJ.mjs → chunk-7W5QCO4Y.mjs} +47 -10
  53. package/dist/sdk/chunk-7W5QCO4Y.mjs.map +1 -0
  54. package/dist/sdk/chunk-B2OUZAWY.mjs +237 -0
  55. package/dist/sdk/chunk-B2OUZAWY.mjs.map +1 -0
  56. package/dist/sdk/chunk-FWWLD555.mjs +244 -0
  57. package/dist/sdk/chunk-FWWLD555.mjs.map +1 -0
  58. package/dist/sdk/{chunk-QXT47ZHR.mjs → chunk-G7GSN3SK.mjs} +2 -2
  59. package/dist/sdk/{chunk-QXT47ZHR.mjs.map → chunk-G7GSN3SK.mjs.map} +1 -1
  60. package/dist/sdk/{chunk-DHETLQIX.mjs → chunk-GA2TYKSR.mjs} +5 -5
  61. package/dist/sdk/{chunk-6DPPP7LD.mjs → chunk-IDL3AA3G.mjs} +203 -42
  62. package/dist/sdk/chunk-IDL3AA3G.mjs.map +1 -0
  63. package/dist/sdk/chunk-MEB2TTIE.mjs +157 -0
  64. package/dist/sdk/chunk-MEB2TTIE.mjs.map +1 -0
  65. package/dist/sdk/{chunk-3JFK6KCD.mjs → chunk-MFXPJUUE.mjs} +150 -280
  66. package/dist/sdk/chunk-MFXPJUUE.mjs.map +1 -0
  67. package/dist/sdk/{chunk-KBGQJKIZ.mjs → chunk-NPSLGKXB.mjs} +3 -3
  68. package/dist/sdk/chunk-P2K4VOMU.mjs +825 -0
  69. package/dist/sdk/chunk-P2K4VOMU.mjs.map +1 -0
  70. package/dist/sdk/chunk-RI4ONH5X.mjs +482 -0
  71. package/dist/sdk/chunk-RI4ONH5X.mjs.map +1 -0
  72. package/dist/sdk/chunk-S5FSRHMY.mjs +139 -0
  73. package/dist/sdk/chunk-S5FSRHMY.mjs.map +1 -0
  74. package/dist/sdk/{chunk-7ERVRLDV.mjs → chunk-TFUQ2D5L.mjs} +13 -2
  75. package/dist/sdk/chunk-TFUQ2D5L.mjs.map +1 -0
  76. package/dist/sdk/{chunk-TQQNSHQV.mjs → chunk-UXB4XWEE.mjs} +1044 -179
  77. package/dist/sdk/chunk-UXB4XWEE.mjs.map +1 -0
  78. package/dist/sdk/{chunk-U6K5SK7X.mjs → chunk-V45TITKX.mjs} +2 -2
  79. package/dist/sdk/{chunk-ANUT54HW.mjs → chunk-WKLJ57WF.mjs} +6 -6
  80. package/dist/sdk/chunk-XOAEKFKB.mjs +1150 -0
  81. package/dist/sdk/chunk-XOAEKFKB.mjs.map +1 -0
  82. package/dist/sdk/chunk-ZPYODGYA.mjs +251 -0
  83. package/dist/sdk/chunk-ZPYODGYA.mjs.map +1 -0
  84. package/dist/sdk/command-executor-YNJOS77A.mjs +14 -0
  85. package/dist/sdk/{config-2STD74CJ.mjs → config-PCP6O6Y6.mjs} +4 -4
  86. package/dist/sdk/{failure-condition-evaluator-FFWJRAEQ.mjs → failure-condition-evaluator-H3PBFBYT.mjs} +4 -4
  87. package/dist/sdk/failure-condition-evaluator-IRFKTYZD.mjs +18 -0
  88. package/dist/sdk/github-auth-BJQBLK2V.mjs +196 -0
  89. package/dist/sdk/github-auth-BJQBLK2V.mjs.map +1 -0
  90. package/dist/sdk/{github-frontend-L3F5JXPJ.mjs → github-frontend-DECYOBRN.mjs} +8 -8
  91. package/dist/sdk/{github-frontend-KGV2R5Z6.mjs → github-frontend-TZRBOQCN.mjs} +4 -4
  92. package/dist/sdk/{host-QBJ7TOWG.mjs → host-CFM2ASDI.mjs} +4 -4
  93. package/dist/sdk/{host-X5ZZCEWN.mjs → host-T4LNVU2H.mjs} +3 -3
  94. package/dist/sdk/{knex-store-QCEW4I4R.mjs → knex-store-OEWSZEBY.mjs} +3 -3
  95. package/dist/sdk/lazy-otel-5RDTVS5L.mjs +24 -0
  96. package/dist/sdk/liquid-extensions-E3AKRX7P.mjs +25 -0
  97. package/dist/sdk/{loader-ZNKKJEZ3.mjs → loader-WRGI244P.mjs} +5 -5
  98. package/dist/sdk/memory-store-OHUIXCWJ.mjs +12 -0
  99. package/dist/sdk/metrics-MYUPQBBV.mjs +41 -0
  100. package/dist/sdk/{opa-policy-engine-QCSSIMUF.mjs → opa-policy-engine-IVMCGVNA.mjs} +3 -3
  101. package/dist/sdk/prompt-state-LN57DQF3.mjs +16 -0
  102. package/dist/sdk/renderer-schema-BT2IXMLW.mjs +51 -0
  103. package/dist/sdk/renderer-schema-BT2IXMLW.mjs.map +1 -0
  104. package/dist/sdk/routing-H2PQ57OA.mjs +26 -0
  105. package/dist/sdk/{routing-CVQT4KHX.mjs → routing-JMZ7HDCC.mjs} +5 -5
  106. package/dist/sdk/schedule-tool-2DPNSU63.mjs +37 -0
  107. package/dist/sdk/{schedule-tool-AECLFHSY.mjs → schedule-tool-4M45RK3E.mjs} +6 -6
  108. package/dist/sdk/{schedule-tool-handler-6QLZRTQA.mjs → schedule-tool-handler-KLHE2SOW.mjs} +6 -6
  109. package/dist/sdk/schedule-tool-handler-KLHE2SOW.mjs.map +1 -0
  110. package/dist/sdk/{schedule-tool-handler-J4NUETJ6.mjs → schedule-tool-handler-NBEO46RV.mjs} +16 -16
  111. package/dist/sdk/schedule-tool-handler-NBEO46RV.mjs.map +1 -0
  112. package/dist/sdk/sdk.d.mts +2 -0
  113. package/dist/sdk/sdk.d.ts +2 -0
  114. package/dist/sdk/sdk.js +3125 -666
  115. package/dist/sdk/sdk.js.map +1 -1
  116. package/dist/sdk/sdk.mjs +15 -15
  117. package/dist/sdk/slack-frontend-DF5VL4OF.mjs +929 -0
  118. package/dist/sdk/slack-frontend-DF5VL4OF.mjs.map +1 -0
  119. package/dist/sdk/{task-evaluator-HLNXKKVV.mjs → task-evaluator-GQYDOSGT.mjs} +138 -24
  120. package/dist/sdk/task-evaluator-GQYDOSGT.mjs.map +1 -0
  121. package/dist/sdk/task-evaluator-OVMG7S56.mjs +263 -0
  122. package/dist/sdk/task-evaluator-OVMG7S56.mjs.map +1 -0
  123. package/dist/sdk/{trace-helpers-WJXYVV4S.mjs → trace-helpers-26ZCAE2V.mjs} +7 -5
  124. package/dist/sdk/trace-helpers-26ZCAE2V.mjs.map +1 -0
  125. package/dist/sdk/{trace-helpers-3FFAI7X3.mjs → trace-helpers-XV5GAX5L.mjs} +3 -3
  126. package/dist/sdk/trace-helpers-XV5GAX5L.mjs.map +1 -0
  127. package/dist/sdk/{trace-reader-ZY77OFNM.mjs → trace-reader-OVE4DL2D.mjs} +6 -2
  128. package/dist/sdk/trace-reader-OVE4DL2D.mjs.map +1 -0
  129. package/dist/sdk/trace-serializer-KKBJHM7J.mjs +24 -0
  130. package/dist/sdk/trace-serializer-KKBJHM7J.mjs.map +1 -0
  131. package/dist/sdk/{track-execution-AMQQNXKE.mjs → track-execution-3EC24C2X.mjs} +68 -7
  132. package/dist/sdk/track-execution-3EC24C2X.mjs.map +1 -0
  133. package/dist/sdk/{track-execution-MKIQXP2C.mjs → track-execution-66RLL6QT.mjs} +10 -3
  134. package/dist/sdk/track-execution-66RLL6QT.mjs.map +1 -0
  135. package/dist/sdk/utcp-check-provider-WI3QZ3W6.mjs +16 -0
  136. package/dist/sdk/utcp-check-provider-WI3QZ3W6.mjs.map +1 -0
  137. package/dist/sdk/workflow-check-provider-X2UREEH7.mjs +31 -0
  138. package/dist/sdk/workflow-check-provider-X2UREEH7.mjs.map +1 -0
  139. package/dist/sdk/{workflow-check-provider-EXMC6JIS.mjs → workflow-check-provider-YXALZNAQ.mjs} +6 -6
  140. package/dist/sdk/workflow-check-provider-YXALZNAQ.mjs.map +1 -0
  141. package/dist/sdk/workflow-registry-YCZ3FCJC.mjs +12 -0
  142. package/dist/sdk/workflow-registry-YCZ3FCJC.mjs.map +1 -0
  143. package/dist/slack/socket-runner.d.ts.map +1 -1
  144. package/dist/state-machine/dispatch/sandbox-routing.d.ts.map +1 -1
  145. package/dist/state-machine/states/level-dispatch.d.ts.map +1 -1
  146. package/dist/telemetry/fallback-ndjson.d.ts +21 -0
  147. package/dist/telemetry/fallback-ndjson.d.ts.map +1 -1
  148. package/dist/telemetry/lazy-otel.d.ts +2 -0
  149. package/dist/telemetry/lazy-otel.d.ts.map +1 -1
  150. package/dist/telemetry/opentelemetry.d.ts +5 -0
  151. package/dist/telemetry/opentelemetry.d.ts.map +1 -1
  152. package/dist/telemetry/trace-helpers.d.ts +10 -0
  153. package/dist/telemetry/trace-helpers.d.ts.map +1 -1
  154. package/dist/test-runner/conversation-sugar.d.ts +7 -0
  155. package/dist/test-runner/conversation-sugar.d.ts.map +1 -1
  156. package/dist/test-runner/core/flow-stage.d.ts.map +1 -1
  157. package/dist/test-runner/index.d.ts.map +1 -1
  158. package/dist/test-runner/validator.d.ts.map +1 -1
  159. package/dist/types/git-checkout.d.ts +2 -0
  160. package/dist/types/git-checkout.d.ts.map +1 -1
  161. package/dist/utils/script-tool-environment.d.ts.map +1 -1
  162. package/package.json +2 -2
  163. package/dist/sdk/a2a-frontend-4LP3MLTS.mjs.map +0 -1
  164. package/dist/sdk/check-provider-registry-RRWCXSTG.mjs +0 -31
  165. package/dist/sdk/chunk-3JFK6KCD.mjs.map +0 -1
  166. package/dist/sdk/chunk-4I3TJ7UJ.mjs.map +0 -1
  167. package/dist/sdk/chunk-6DPPP7LD.mjs.map +0 -1
  168. package/dist/sdk/chunk-6VVXKXTI.mjs +0 -164
  169. package/dist/sdk/chunk-6VVXKXTI.mjs.map +0 -1
  170. package/dist/sdk/chunk-7ERVRLDV.mjs.map +0 -1
  171. package/dist/sdk/chunk-TQQNSHQV.mjs.map +0 -1
  172. package/dist/sdk/failure-condition-evaluator-5DZYMCGW.mjs +0 -18
  173. package/dist/sdk/routing-XALEDC2G.mjs +0 -26
  174. package/dist/sdk/schedule-tool-Z6QYL2B3.mjs +0 -37
  175. package/dist/sdk/task-evaluator-HLNXKKVV.mjs.map +0 -1
  176. package/dist/sdk/trace-reader-ZY77OFNM.mjs.map +0 -1
  177. package/dist/sdk/track-execution-AMQQNXKE.mjs.map +0 -1
  178. package/dist/sdk/track-execution-MKIQXP2C.mjs.map +0 -1
  179. package/dist/sdk/workflow-check-provider-VKYGI5GK.mjs +0 -31
  180. /package/dist/sdk/{check-provider-registry-I4BCWKRU.mjs.map → check-provider-registry-WSEVHJEV.mjs.map} +0 -0
  181. /package/dist/sdk/{check-provider-registry-RRWCXSTG.mjs.map → check-provider-registry-YRADEEQY.mjs.map} +0 -0
  182. /package/dist/sdk/{chunk-DHETLQIX.mjs.map → chunk-GA2TYKSR.mjs.map} +0 -0
  183. /package/dist/sdk/{chunk-ANUT54HW.mjs.map → chunk-NPSLGKXB.mjs.map} +0 -0
  184. /package/dist/sdk/{chunk-U6K5SK7X.mjs.map → chunk-V45TITKX.mjs.map} +0 -0
  185. /package/dist/sdk/{chunk-KBGQJKIZ.mjs.map → chunk-WKLJ57WF.mjs.map} +0 -0
  186. /package/dist/sdk/{config-2STD74CJ.mjs.map → command-executor-YNJOS77A.mjs.map} +0 -0
  187. /package/dist/sdk/{failure-condition-evaluator-5DZYMCGW.mjs.map → config-PCP6O6Y6.mjs.map} +0 -0
  188. /package/dist/sdk/{failure-condition-evaluator-FFWJRAEQ.mjs.map → failure-condition-evaluator-H3PBFBYT.mjs.map} +0 -0
  189. /package/dist/sdk/{routing-CVQT4KHX.mjs.map → failure-condition-evaluator-IRFKTYZD.mjs.map} +0 -0
  190. /package/dist/sdk/{github-frontend-KGV2R5Z6.mjs.map → github-frontend-DECYOBRN.mjs.map} +0 -0
  191. /package/dist/sdk/{github-frontend-L3F5JXPJ.mjs.map → github-frontend-TZRBOQCN.mjs.map} +0 -0
  192. /package/dist/sdk/{host-QBJ7TOWG.mjs.map → host-CFM2ASDI.mjs.map} +0 -0
  193. /package/dist/sdk/{host-X5ZZCEWN.mjs.map → host-T4LNVU2H.mjs.map} +0 -0
  194. /package/dist/sdk/{knex-store-QCEW4I4R.mjs.map → knex-store-OEWSZEBY.mjs.map} +0 -0
  195. /package/dist/sdk/{routing-XALEDC2G.mjs.map → lazy-otel-5RDTVS5L.mjs.map} +0 -0
  196. /package/dist/sdk/{schedule-tool-AECLFHSY.mjs.map → liquid-extensions-E3AKRX7P.mjs.map} +0 -0
  197. /package/dist/sdk/{loader-ZNKKJEZ3.mjs.map → loader-WRGI244P.mjs.map} +0 -0
  198. /package/dist/sdk/{schedule-tool-Z6QYL2B3.mjs.map → memory-store-OHUIXCWJ.mjs.map} +0 -0
  199. /package/dist/sdk/{schedule-tool-handler-6QLZRTQA.mjs.map → metrics-MYUPQBBV.mjs.map} +0 -0
  200. /package/dist/sdk/{opa-policy-engine-QCSSIMUF.mjs.map → opa-policy-engine-IVMCGVNA.mjs.map} +0 -0
  201. /package/dist/sdk/{schedule-tool-handler-J4NUETJ6.mjs.map → prompt-state-LN57DQF3.mjs.map} +0 -0
  202. /package/dist/sdk/{trace-helpers-3FFAI7X3.mjs.map → routing-H2PQ57OA.mjs.map} +0 -0
  203. /package/dist/sdk/{trace-helpers-WJXYVV4S.mjs.map → routing-JMZ7HDCC.mjs.map} +0 -0
  204. /package/dist/sdk/{workflow-check-provider-EXMC6JIS.mjs.map → schedule-tool-2DPNSU63.mjs.map} +0 -0
  205. /package/dist/sdk/{workflow-check-provider-VKYGI5GK.mjs.map → schedule-tool-4M45RK3E.mjs.map} +0 -0
@@ -31,11 +31,11 @@ import {
31
31
  init_utcp_check_provider,
32
32
  normalizeIssue,
33
33
  normalizeIssueArray
34
- } from "./chunk-7XRSCOKE.mjs";
34
+ } from "./chunk-P2K4VOMU.mjs";
35
35
  import {
36
36
  getPromptStateManager,
37
37
  init_prompt_state
38
- } from "./chunk-7VTZDC2X.mjs";
38
+ } from "./chunk-MEB2TTIE.mjs";
39
39
  import {
40
40
  init_tracer_init,
41
41
  initializeTracer
@@ -48,17 +48,17 @@ import {
48
48
  import {
49
49
  commandExecutor,
50
50
  init_command_executor
51
- } from "./chunk-RHKPFJLG.mjs";
51
+ } from "./chunk-S5FSRHMY.mjs";
52
52
  import {
53
53
  DependencyResolver,
54
54
  WorkflowRegistry,
55
55
  init_dependency_resolver,
56
56
  init_workflow_registry
57
- } from "./chunk-J27D43HS.mjs";
57
+ } from "./chunk-54KOAC4W.mjs";
58
58
  import {
59
59
  config_exports,
60
60
  init_config
61
- } from "./chunk-ZOF5QT6U.mjs";
61
+ } from "./chunk-7W5QCO4Y.mjs";
62
62
  import {
63
63
  ExecutionJournal,
64
64
  checkLoopBudget,
@@ -67,14 +67,16 @@ import {
67
67
  init_routing,
68
68
  init_snapshot_store,
69
69
  snapshot_store_exports
70
- } from "./chunk-ANUT54HW.mjs";
70
+ } from "./chunk-WKLJ57WF.mjs";
71
71
  import {
72
72
  FailureConditionEvaluator,
73
73
  init_failure_condition_evaluator
74
- } from "./chunk-DHETLQIX.mjs";
74
+ } from "./chunk-GA2TYKSR.mjs";
75
75
  import {
76
76
  addEvent,
77
+ emitImmediateSpan,
77
78
  emitNdjsonFallback,
79
+ emitNdjsonFullSpan,
78
80
  emitNdjsonSpanWithEvents,
79
81
  fallback_ndjson_exports,
80
82
  init_fallback_ndjson,
@@ -82,20 +84,20 @@ import {
82
84
  setSpanAttributes,
83
85
  trace_helpers_exports,
84
86
  withActiveSpan
85
- } from "./chunk-7ERVRLDV.mjs";
87
+ } from "./chunk-XOAEKFKB.mjs";
86
88
  import {
87
89
  generateHumanId,
88
90
  init_human_id
89
- } from "./chunk-QXT47ZHR.mjs";
91
+ } from "./chunk-G7GSN3SK.mjs";
90
92
  import {
91
93
  addDiagramBlock,
92
94
  init_metrics,
93
95
  metrics_exports
94
- } from "./chunk-34QX63WK.mjs";
96
+ } from "./chunk-FWWLD555.mjs";
95
97
  import {
96
98
  createExtendedLiquid,
97
99
  init_liquid_extensions
98
- } from "./chunk-PQWZ6NFL.mjs";
100
+ } from "./chunk-4BN2XI4X.mjs";
99
101
  import {
100
102
  createPermissionHelpers,
101
103
  detectLocalMode,
@@ -112,18 +114,18 @@ import {
112
114
  MemoryStore,
113
115
  init_memory_store,
114
116
  memory_store_exports
115
- } from "./chunk-UFHOIB3R.mjs";
117
+ } from "./chunk-RI4ONH5X.mjs";
116
118
  import {
117
119
  init_logger,
118
120
  logger,
119
121
  logger_exports
120
- } from "./chunk-FT3I25QV.mjs";
122
+ } from "./chunk-ZPYODGYA.mjs";
121
123
  import {
122
124
  context,
123
125
  init_lazy_otel,
124
126
  lazy_otel_exports,
125
127
  trace
126
- } from "./chunk-UCMJJ3IM.mjs";
128
+ } from "./chunk-B2OUZAWY.mjs";
127
129
  import {
128
130
  __commonJS,
129
131
  __esm,
@@ -238,6 +240,11 @@ function getCurrentDateXml() {
238
240
  }
239
241
  function createProbeTracerAdapter(fallbackTracer) {
240
242
  const fallback = fallbackTracer && typeof fallbackTracer === "object" ? fallbackTracer : null;
243
+ const LIVE_LIFECYCLE_SPANS = /* @__PURE__ */ new Set(["visor.ai_check", "ai.request", "search.delegate"]);
244
+ const PROBE_LIFECYCLE_ALIASES = {
245
+ "ai.request": "probe.ai_request",
246
+ "search.delegate": "probe.search_delegate"
247
+ };
241
248
  const flattenAttrs = (attrs) => {
242
249
  if (!attrs) return attrs;
243
250
  const out = {};
@@ -265,8 +272,13 @@ function createProbeTracerAdapter(fallbackTracer) {
265
272
  "delegation.start",
266
273
  "delegation.complete",
267
274
  "graceful_stop.invoked",
275
+ "graceful_stop.initiated",
268
276
  "probe.timeout_configured",
269
- "negotiated_timeout.observer"
277
+ "negotiated_timeout.observer",
278
+ "negotiated_timeout.observer_extended",
279
+ "negotiated_timeout.observer_declined",
280
+ "negotiated_timeout.observer_exhausted",
281
+ "negotiated_timeout.abort_summary"
270
282
  ]);
271
283
  const emitEvent = (name, attrs) => {
272
284
  try {
@@ -288,13 +300,94 @@ function createProbeTracerAdapter(fallbackTracer) {
288
300
  } catch {
289
301
  }
290
302
  };
303
+ const emitLifecycle = (name, phase, attrs) => {
304
+ emitImmediateSpan(`${name}.${phase}`, {
305
+ "probe.lifecycle.target": name,
306
+ ...flattenAttrs(attrs)
307
+ });
308
+ const alias = PROBE_LIFECYCLE_ALIASES[name];
309
+ if (alias) {
310
+ emitImmediateSpan(`${alias}.${phase}`, {
311
+ "probe.lifecycle.target": name,
312
+ ...flattenAttrs(attrs)
313
+ });
314
+ }
315
+ };
291
316
  return {
292
- withSpan: async (name, fn, attrs) => withActiveSpan(name, attrs, async (span) => {
293
- if (fallback && typeof fallback.withSpan === "function") {
294
- return await fallback.withSpan(name, async () => fn(span), attrs);
317
+ withSpan: async (name, fn, attrs, onResult) => {
318
+ const startHr = process.hrtime();
319
+ if (LIVE_LIFECYCLE_SPANS.has(name)) {
320
+ emitLifecycle(name, "started", attrs);
321
+ }
322
+ try {
323
+ const result = await withActiveSpan(name, attrs, async (span) => {
324
+ let innerResult;
325
+ if (fallback && typeof fallback.withSpan === "function") {
326
+ innerResult = await fallback.withSpan(name, async () => fn(span), attrs);
327
+ } else {
328
+ innerResult = await fn(span);
329
+ }
330
+ const extraAttrs = {};
331
+ if (onResult) {
332
+ try {
333
+ const capturingSpan = {
334
+ setAttributes: (a) => {
335
+ Object.assign(extraAttrs, a);
336
+ try {
337
+ span.setAttributes(a);
338
+ } catch {
339
+ }
340
+ },
341
+ setAttribute: (k, v) => {
342
+ extraAttrs[k] = v;
343
+ try {
344
+ span.setAttribute(k, v);
345
+ } catch {
346
+ }
347
+ },
348
+ addEvent: (...args) => {
349
+ try {
350
+ span.addEvent(...args);
351
+ } catch {
352
+ }
353
+ }
354
+ };
355
+ onResult(capturingSpan, innerResult);
356
+ } catch {
357
+ }
358
+ }
359
+ try {
360
+ const endHr = process.hrtime();
361
+ const ctx = span.spanContext?.() || {};
362
+ const parentCtx = span.parentSpanContext || span._parentSpanContext;
363
+ emitNdjsonFullSpan({
364
+ name,
365
+ traceId: ctx.traceId,
366
+ spanId: ctx.spanId,
367
+ parentSpanId: parentCtx?.spanId,
368
+ startTime: [startHr[0], startHr[1]],
369
+ endTime: [endHr[0], endHr[1]],
370
+ attributes: { ...flattenAttrs(attrs), ...flattenAttrs(extraAttrs) },
371
+ events: [],
372
+ status: { code: 1 }
373
+ });
374
+ } catch {
375
+ }
376
+ return innerResult;
377
+ });
378
+ if (LIVE_LIFECYCLE_SPANS.has(name)) {
379
+ emitLifecycle(name, "completed");
380
+ }
381
+ return result;
382
+ } catch (error) {
383
+ if (LIVE_LIFECYCLE_SPANS.has(name)) {
384
+ emitLifecycle(name, "failed", {
385
+ error: error instanceof Error ? error.message : String(error)
386
+ });
387
+ }
388
+ throw error;
295
389
  }
296
- return await fn(span);
297
- }),
390
+ },
298
391
  recordEvent: (name, attrs) => {
299
392
  emitEvent(name, attrs);
300
393
  if (fallback && typeof fallback.recordEvent === "function") {
@@ -328,6 +421,11 @@ function createProbeTracerAdapter(fallbackTracer) {
328
421
  "tool.success": success,
329
422
  ...metadata || {}
330
423
  });
424
+ emitImmediateSpan(success ? "probe.tool.completed" : "probe.tool.failed", {
425
+ "tool.name": toolName,
426
+ "tool.duration_ms": durationMs,
427
+ "tool.success": success
428
+ });
331
429
  if (fallback && typeof fallback.recordToolResult === "function") {
332
430
  try {
333
431
  fallback.recordToolResult(toolName, result, success, durationMs, metadata);
@@ -337,6 +435,11 @@ function createProbeTracerAdapter(fallbackTracer) {
337
435
  },
338
436
  recordToolDecision: (toolName, params, metadata) => {
339
437
  const paramsStr = typeof params === "string" ? params : JSON.stringify(params || {});
438
+ emitImmediateSpan("probe.tool.started", {
439
+ "tool.name": toolName,
440
+ "tool.params.length": paramsStr.length,
441
+ ...flattenAttrs(metadata)
442
+ });
340
443
  emitEvent("tool.decision", {
341
444
  "tool.name": toolName,
342
445
  "tool.params": paramsStr.substring(0, 5e3),
@@ -377,6 +480,76 @@ function createProbeTracerAdapter(fallbackTracer) {
377
480
  }
378
481
  }
379
482
  },
483
+ createToolSpan: (toolName, attrs) => {
484
+ let fallbackSpan = null;
485
+ if (fallback && typeof fallback.createToolSpan === "function") {
486
+ try {
487
+ fallbackSpan = fallback.createToolSpan(toolName, attrs);
488
+ } catch {
489
+ }
490
+ }
491
+ emitImmediateSpan("probe.tool.started", {
492
+ "tool.name": toolName,
493
+ ...flattenAttrs(attrs)
494
+ });
495
+ const tracer = trace.getTracer("visor");
496
+ const span = tracer.startSpan(`probe.tool.${toolName}`, {
497
+ attributes: {
498
+ "tool.name": toolName,
499
+ ...flattenAttrs(attrs)
500
+ }
501
+ });
502
+ return {
503
+ setAttributes: (spanAttrs) => {
504
+ try {
505
+ if (spanAttrs) span.setAttributes(spanAttrs);
506
+ } catch {
507
+ }
508
+ if (fallbackSpan?.setAttributes) {
509
+ try {
510
+ fallbackSpan.setAttributes(spanAttrs);
511
+ } catch {
512
+ }
513
+ }
514
+ },
515
+ setStatus: (status) => {
516
+ try {
517
+ span.setStatus(status);
518
+ } catch {
519
+ }
520
+ if (fallbackSpan?.setStatus) {
521
+ try {
522
+ fallbackSpan.setStatus(status);
523
+ } catch {
524
+ }
525
+ }
526
+ },
527
+ addEvent: (eventName, eventAttrs) => {
528
+ try {
529
+ span.addEvent(eventName, flattenAttrs(eventAttrs) || {});
530
+ } catch {
531
+ }
532
+ if (fallbackSpan?.addEvent) {
533
+ try {
534
+ fallbackSpan.addEvent(eventName, eventAttrs);
535
+ } catch {
536
+ }
537
+ }
538
+ },
539
+ end: () => {
540
+ try {
541
+ span.end();
542
+ } catch {
543
+ }
544
+ if (fallbackSpan?.end) {
545
+ try {
546
+ fallbackSpan.end();
547
+ } catch {
548
+ }
549
+ }
550
+ }
551
+ };
552
+ },
380
553
  createDelegationSpan: (sessionId, task) => {
381
554
  let fallbackSpan = null;
382
555
  if (fallback && typeof fallback.createDelegationSpan === "function") {
@@ -398,10 +571,19 @@ function createProbeTracerAdapter(fallbackTracer) {
398
571
  }
399
572
  if (!span && fallbackSpan) return fallbackSpan;
400
573
  if (!span) return null;
574
+ const accumulated = {
575
+ "delegation.session_id": sessionId,
576
+ "delegation.task": task
577
+ };
578
+ const delegStartHr = process.hrtime();
579
+ let delegStatus = 1;
401
580
  return {
402
581
  setAttributes: (attrs) => {
403
582
  try {
404
- if (attrs) span.setAttributes(attrs);
583
+ if (attrs) {
584
+ Object.assign(accumulated, attrs);
585
+ span.setAttributes(attrs);
586
+ }
405
587
  } catch {
406
588
  }
407
589
  if (fallbackSpan && typeof fallbackSpan.setAttributes === "function") {
@@ -413,6 +595,8 @@ function createProbeTracerAdapter(fallbackTracer) {
413
595
  },
414
596
  setStatus: (status) => {
415
597
  try {
598
+ const code = status?.code;
599
+ if (code === 2) delegStatus = 2;
416
600
  span.setStatus(status);
417
601
  } catch {
418
602
  }
@@ -434,6 +618,23 @@ function createProbeTracerAdapter(fallbackTracer) {
434
618
  } catch {
435
619
  }
436
620
  }
621
+ try {
622
+ const delegEndHr = process.hrtime();
623
+ const ctx = span.spanContext?.() || {};
624
+ emitNdjsonFullSpan({
625
+ name: "probe.delegation",
626
+ traceId: ctx.traceId,
627
+ spanId: ctx.spanId,
628
+ parentSpanId: void 0,
629
+ // delegation spans are roots within probe
630
+ startTime: [delegStartHr[0], delegStartHr[1]],
631
+ endTime: [delegEndHr[0], delegEndHr[1]],
632
+ attributes: flattenAttrs(accumulated) || {},
633
+ events: [],
634
+ status: { code: delegStatus }
635
+ });
636
+ } catch {
637
+ }
437
638
  }
438
639
  };
439
640
  },
@@ -481,6 +682,7 @@ var init_ai_review_service = __esm({
481
682
  init_logger();
482
683
  init_lazy_otel();
483
684
  init_trace_helpers();
685
+ init_fallback_ndjson();
484
686
  init_tracer_init();
485
687
  init_diff_processor();
486
688
  init_comment_metadata();
@@ -1295,7 +1497,24 @@ ${this.escapeXml(processedFallbackDiff)}
1295
1497
  <text>${this.escapeXml(String(current.text || ""))}</text>
1296
1498
  <timestamp>${this.escapeXml(String(current.timestamp || ""))}</timestamp>
1297
1499
  <origin>${this.escapeXml(String(current.origin || ""))}</origin>${this.formatFilesXml(current.files)}
1298
- </current>
1500
+ </current>`;
1501
+ const activeTasks = prInfo?.activeTasks;
1502
+ if (Array.isArray(activeTasks) && activeTasks.length > 0) {
1503
+ xml += `
1504
+ <active_tasks hint="These tasks are already in progress in this thread. If the current message is asking about the same thing as an active task, inform the user that you are already working on it. If it is a different question or a follow-up, proceed normally.">`;
1505
+ for (const t of activeTasks) {
1506
+ xml += `
1507
+ <task>
1508
+ <id>${this.escapeXml(String(t.id || ""))}</id>
1509
+ <state>${this.escapeXml(String(t.state || ""))}</state>
1510
+ <started>${this.escapeXml(String(t.created_at || ""))}</started>
1511
+ <trigger_message>${this.escapeXml(String(t.trigger_message || ""))}</trigger_message>
1512
+ </task>`;
1513
+ }
1514
+ xml += `
1515
+ </active_tasks>`;
1516
+ }
1517
+ xml += `
1299
1518
  </slack_context>`;
1300
1519
  return xml;
1301
1520
  } catch {
@@ -1817,6 +2036,15 @@ ${"=".repeat(60)}
1817
2036
  if (!systemPrompt && schema !== "code-review" && !this.config.promptType) {
1818
2037
  systemPrompt = "You are general assistant, follow user instructions.";
1819
2038
  }
2039
+ if (systemPrompt && (this.config.aiTimeout || this.config.timeoutBehavior)) {
2040
+ systemPrompt += `
2041
+
2042
+ IMPORTANT \u2014 Time-limit behavior:
2043
+ If you receive a message that the time limit has been reached or your operation is being interrupted, this means YOUR ALLOCATED TIME BUDGET for this task has been exhausted. The system is NOT shutting down or going offline.
2044
+ - Frame it as: "I ran out of the allocated time for this task."
2045
+ - NEVER say "the system is shutting down", "try again when the system is back online", or similar misleading language.
2046
+ - Summarize what you accomplished, what you didn't finish, and any actionable recommendations the user can follow up on.`;
2047
+ }
1820
2048
  log(
1821
2049
  `\u{1F527} AIReviewService config: allowEdit=${this.config.allowEdit}, allowBash=${this.config.allowBash}, promptType=${this.config.promptType}`
1822
2050
  );
@@ -2383,12 +2611,21 @@ ${"=".repeat(60)}
2383
2611
  );
2384
2612
  }
2385
2613
  }
2614
+ const buildPlainTextOutput = (text, rawOutput) => {
2615
+ const trimmed = typeof text === "string" ? text.trim() : "";
2616
+ const out = {};
2617
+ if (trimmed) {
2618
+ out.text = trimmed;
2619
+ out.content = trimmed;
2620
+ }
2621
+ if (rawOutput) out._rawOutput = rawOutput;
2622
+ return out;
2623
+ };
2386
2624
  if (_schema === "plain" || !_schema) {
2387
2625
  log(
2388
2626
  `\u{1F4CB} ${_schema === "plain" ? "Plain" : "No"} schema detected - treating raw response as text output`
2389
2627
  );
2390
- const trimmed = typeof response === "string" ? response.trim() : "";
2391
- const out = trimmed ? { text: trimmed } : {};
2628
+ const out = buildPlainTextOutput(response);
2392
2629
  return {
2393
2630
  issues: [],
2394
2631
  // Expose assistant-style content via output.text so downstream formatters
@@ -2427,9 +2664,10 @@ ${"=".repeat(60)}
2427
2664
  if (!recovered) {
2428
2665
  if (response.toLowerCase().includes("i cannot") || response.toLowerCase().includes("unable to")) {
2429
2666
  console.error("\u{1F6AB} AI refused to analyze - returning refusal as output");
2430
- const trimmed2 = responseForParsing.trim();
2431
- const out = trimmed2 ? { text: trimmed2 } : {};
2432
- if (rawOutputBlocks.length > 0) out._rawOutput = rawOutputBlocks.join("\n\n");
2667
+ const out = buildPlainTextOutput(
2668
+ responseForParsing,
2669
+ rawOutputBlocks.length > 0 ? rawOutputBlocks.join("\n\n") : void 0
2670
+ );
2433
2671
  return {
2434
2672
  issues: [],
2435
2673
  output: out,
@@ -2437,9 +2675,10 @@ ${"=".repeat(60)}
2437
2675
  };
2438
2676
  }
2439
2677
  log("\u{1F527} Treating response as plain text (no JSON extraction)");
2440
- const trimmed = responseForParsing.trim();
2441
- const fallbackOut = { text: trimmed };
2442
- if (rawOutputBlocks.length > 0) fallbackOut._rawOutput = rawOutputBlocks.join("\n\n");
2678
+ const fallbackOut = buildPlainTextOutput(
2679
+ responseForParsing,
2680
+ rawOutputBlocks.length > 0 ? rawOutputBlocks.join("\n\n") : void 0
2681
+ );
2443
2682
  return {
2444
2683
  issues: [],
2445
2684
  output: fallbackOut,
@@ -4295,7 +4534,7 @@ async function executeWorkflowAsTool(workflowId, args, context2, argsOverrides)
4295
4534
  ...args,
4296
4535
  ...argsOverrides
4297
4536
  };
4298
- const { WorkflowCheckProvider: WorkflowCheckProvider2 } = await import("./workflow-check-provider-EXMC6JIS.mjs");
4537
+ const { WorkflowCheckProvider: WorkflowCheckProvider2 } = await import("./workflow-check-provider-X2UREEH7.mjs");
4299
4538
  const provider = new WorkflowCheckProvider2();
4300
4539
  const checkConfig = {
4301
4540
  type: "workflow",
@@ -6289,6 +6528,12 @@ function addEvent2(name, attrs) {
6289
6528
  helpers.addEvent(name, attrs);
6290
6529
  }
6291
6530
  }
6531
+ function emitImmediateSpan2(name, attrs, options) {
6532
+ const helpers = getTraceHelpers();
6533
+ if (helpers) {
6534
+ helpers.emitImmediateSpan(name, attrs, options);
6535
+ }
6536
+ }
6292
6537
  function setSpanError(err) {
6293
6538
  const helpers = getTraceHelpers();
6294
6539
  if (helpers) {
@@ -7503,7 +7748,7 @@ var init_env_filter = __esm({
7503
7748
  });
7504
7749
 
7505
7750
  // src/sandbox/trace-ingester.ts
7506
- import { readFileSync as readFileSync3 } from "fs";
7751
+ import { existsSync as existsSync6, readFileSync as readFileSync3 } from "fs";
7507
7752
  function getTracer() {
7508
7753
  try {
7509
7754
  const helpers = (init_trace_helpers(), __toCommonJS(trace_helpers_exports));
@@ -7519,16 +7764,27 @@ function getOtelContext() {
7519
7764
  return null;
7520
7765
  }
7521
7766
  }
7522
- function ingestChildTrace(filePath) {
7523
- let content;
7524
- try {
7525
- content = readFileSync3(filePath, "utf8");
7526
- } catch {
7527
- return;
7528
- }
7529
- const lines = content.split("\n");
7767
+ function buildFallbackSpanContext(child) {
7768
+ if (!child.traceId || !child.spanId) return null;
7769
+ return {
7770
+ traceId: child.traceId,
7771
+ spanId: child.spanId,
7772
+ traceFlags: 1,
7773
+ isRemote: true
7774
+ };
7775
+ }
7776
+ function computeSpanKey(child) {
7777
+ if (child.traceId && child.spanId) return `${child.traceId}:${child.spanId}`;
7778
+ const timing = JSON.stringify({
7779
+ name: child.name,
7780
+ startTime: child.startTime,
7781
+ endTime: child.endTime
7782
+ });
7783
+ return `fallback:${timing}`;
7784
+ }
7785
+ function parseLines(text) {
7530
7786
  const spans = [];
7531
- for (const line of lines) {
7787
+ for (const line of text.split("\n")) {
7532
7788
  const trimmed = line.trim();
7533
7789
  if (!trimmed) continue;
7534
7790
  try {
@@ -7536,61 +7792,186 @@ function ingestChildTrace(filePath) {
7536
7792
  } catch {
7537
7793
  }
7538
7794
  }
7539
- if (spans.length === 0) return;
7795
+ return spans;
7796
+ }
7797
+ function emitChildSpan(tracer, otel, parentContext, child) {
7798
+ if (!child.name) return;
7799
+ if (child.name === "visor.run" || child.name === "visor.event") return;
7800
+ if (!child.traceId && !child.startTime) return;
7801
+ try {
7802
+ const spanOptions = {
7803
+ attributes: {
7804
+ "visor.sandbox.child_span": true,
7805
+ "visor.sandbox.original_trace_id": child.traceId || "",
7806
+ "visor.sandbox.original_span_id": child.spanId || "",
7807
+ "visor.sandbox.original_parent_span_id": child.parentSpanId || "",
7808
+ ...child.attributes || {}
7809
+ }
7810
+ };
7811
+ if (child.startTime) {
7812
+ spanOptions.startTime = child.startTime;
7813
+ }
7814
+ const span = tracer.startSpan(child.name, spanOptions, parentContext);
7815
+ if (Array.isArray(child.events)) {
7816
+ for (const evt of child.events) {
7817
+ const evtAttrs = evt.attributes || evt.attrs || {};
7818
+ if (evt.time) span.addEvent(evt.name, evtAttrs, evt.time);
7819
+ else span.addEvent(evt.name, evtAttrs);
7820
+ }
7821
+ }
7822
+ if (child.status?.code === 2) {
7823
+ try {
7824
+ span.setStatus({
7825
+ code: otel?.SpanStatusCode?.ERROR || 2,
7826
+ message: child.status.message
7827
+ });
7828
+ } catch {
7829
+ }
7830
+ }
7831
+ if (child.endTime) span.end(child.endTime);
7832
+ else span.end();
7833
+ if (otel?.trace?.setSpan) {
7834
+ return otel.trace.setSpan(parentContext, span);
7835
+ }
7836
+ const fallbackSpanContext = buildFallbackSpanContext(child);
7837
+ if (fallbackSpanContext && otel?.trace?.setSpanContext) {
7838
+ return otel.trace.setSpanContext(parentContext, fallbackSpanContext);
7839
+ }
7840
+ return parentContext;
7841
+ } catch {
7842
+ const fallbackSpanContext = buildFallbackSpanContext(child);
7843
+ if (fallbackSpanContext && otel?.trace?.setSpanContext) {
7844
+ try {
7845
+ return otel.trace.setSpanContext(parentContext, fallbackSpanContext);
7846
+ } catch {
7847
+ }
7848
+ }
7849
+ return parentContext;
7850
+ }
7851
+ }
7852
+ function ingestRecords(records, seenKeys, parentContext, replayContexts) {
7853
+ if (records.length === 0) return 0;
7540
7854
  const tracer = getTracer();
7541
7855
  if (!tracer) {
7542
- logger.info(`[trace-ingester] ${spans.length} child spans (OTel unavailable)`);
7543
- return;
7856
+ logger.info(`[trace-ingester] ${records.length} child spans (OTel unavailable)`);
7857
+ return 0;
7544
7858
  }
7545
7859
  const otel = getOtelContext();
7546
- for (const child of spans) {
7547
- if (!child.name) continue;
7548
- if (child.name === "visor.run" || child.name === "visor.event") continue;
7549
- if (!child.traceId && !child.startTime) continue;
7550
- try {
7551
- const spanOptions = {
7552
- attributes: {
7553
- "visor.sandbox.child_span": true,
7554
- ...child.attributes || {}
7555
- }
7556
- };
7557
- if (child.startTime) {
7558
- spanOptions.startTime = child.startTime;
7559
- }
7560
- const span = tracer.startSpan(`child: ${child.name}`, spanOptions);
7561
- if (Array.isArray(child.events)) {
7562
- for (const evt of child.events) {
7563
- const evtAttrs = evt.attributes || evt.attrs || {};
7564
- if (evt.time) {
7565
- span.addEvent(evt.name, evtAttrs, evt.time);
7566
- } else {
7567
- span.addEvent(evt.name, evtAttrs);
7568
- }
7569
- }
7860
+ const effectiveParentContext = parentContext || otel?.context?.active?.();
7861
+ const replayParentContexts = replayContexts ?? /* @__PURE__ */ new Map();
7862
+ let ingested = 0;
7863
+ const pending = records.filter((child) => {
7864
+ const key = computeSpanKey(child);
7865
+ if (seenKeys.has(key)) return false;
7866
+ seenKeys.add(key);
7867
+ return true;
7868
+ });
7869
+ while (pending.length > 0) {
7870
+ let emittedInPass = 0;
7871
+ for (let i = 0; i < pending.length; ) {
7872
+ const child = pending[i];
7873
+ const hasKnownParent = !child.parentSpanId || replayParentContexts.has(child.parentSpanId);
7874
+ const parentCtx = child.parentSpanId ? replayParentContexts.get(child.parentSpanId) || effectiveParentContext : effectiveParentContext;
7875
+ if (!hasKnownParent && pending.some((candidate) => candidate.spanId === child.parentSpanId)) {
7876
+ i += 1;
7877
+ continue;
7570
7878
  }
7571
- if (child.status && child.status.code === 2) {
7572
- try {
7573
- const { SpanStatusCode } = otel || {};
7574
- span.setStatus({
7575
- code: SpanStatusCode?.ERROR || 2,
7576
- message: child.status.message
7577
- });
7578
- } catch {
7579
- }
7879
+ const replayContext = emitChildSpan(tracer, otel, parentCtx, child);
7880
+ if (child.spanId && replayContext) {
7881
+ replayParentContexts.set(child.spanId, replayContext);
7580
7882
  }
7581
- if (child.endTime) {
7582
- span.end(child.endTime);
7583
- } else {
7584
- span.end();
7883
+ pending.splice(i, 1);
7884
+ ingested += 1;
7885
+ emittedInPass += 1;
7886
+ }
7887
+ if (emittedInPass === 0) {
7888
+ for (const child of pending.splice(0)) {
7889
+ const replayContext = emitChildSpan(tracer, otel, effectiveParentContext, child);
7890
+ if (child.spanId && replayContext) {
7891
+ replayParentContexts.set(child.spanId, replayContext);
7892
+ }
7893
+ ingested += 1;
7585
7894
  }
7586
- } catch {
7895
+ break;
7587
7896
  }
7588
7897
  }
7898
+ return ingested;
7589
7899
  }
7900
+ var ChildTraceTailer;
7590
7901
  var init_trace_ingester = __esm({
7591
7902
  "src/sandbox/trace-ingester.ts"() {
7592
7903
  "use strict";
7593
7904
  init_logger();
7905
+ ChildTraceTailer = class {
7906
+ filePath;
7907
+ pollIntervalMs;
7908
+ seenKeys;
7909
+ parentContext;
7910
+ replayContexts;
7911
+ offset = 0;
7912
+ partialLine = "";
7913
+ timer = null;
7914
+ activePoll = null;
7915
+ constructor(filePath, options) {
7916
+ this.filePath = filePath;
7917
+ this.pollIntervalMs = options?.pollIntervalMs ?? 500;
7918
+ this.seenKeys = options?.seenKeys ?? /* @__PURE__ */ new Set();
7919
+ this.parentContext = options?.parentContext;
7920
+ this.replayContexts = /* @__PURE__ */ new Map();
7921
+ }
7922
+ start() {
7923
+ if (this.timer) return;
7924
+ this.timer = setInterval(() => {
7925
+ if (!this.activePoll) {
7926
+ this.activePoll = this.pollOnce().finally(() => {
7927
+ this.activePoll = null;
7928
+ });
7929
+ }
7930
+ }, this.pollIntervalMs);
7931
+ this.timer.unref?.();
7932
+ }
7933
+ async stop() {
7934
+ if (this.timer) {
7935
+ clearInterval(this.timer);
7936
+ this.timer = null;
7937
+ }
7938
+ if (this.activePoll) {
7939
+ await this.activePoll;
7940
+ }
7941
+ await this.pollOnce(true);
7942
+ }
7943
+ async pollOnce(finalSweep = false) {
7944
+ if (!existsSync6(this.filePath)) return;
7945
+ let buf;
7946
+ try {
7947
+ buf = readFileSync3(this.filePath);
7948
+ } catch {
7949
+ return;
7950
+ }
7951
+ if (buf.length < this.offset) {
7952
+ this.offset = 0;
7953
+ this.partialLine = "";
7954
+ }
7955
+ if (buf.length === this.offset && !finalSweep) {
7956
+ return;
7957
+ }
7958
+ const chunk = buf.subarray(this.offset).toString("utf8");
7959
+ this.offset = buf.length;
7960
+ if (!chunk && !finalSweep) return;
7961
+ const combined = this.partialLine + chunk;
7962
+ const endsWithNewline = combined.endsWith("\n");
7963
+ const lines = combined.split("\n");
7964
+ this.partialLine = endsWithNewline ? "" : lines.pop() || "";
7965
+ const completedText = lines.join("\n");
7966
+ const records = parseLines(completedText);
7967
+ ingestRecords(records, this.seenKeys, this.parentContext, this.replayContexts);
7968
+ if (finalSweep && this.partialLine.trim()) {
7969
+ const trailing = parseLines(this.partialLine);
7970
+ this.partialLine = "";
7971
+ ingestRecords(trailing, this.seenKeys, this.parentContext, this.replayContexts);
7972
+ }
7973
+ }
7974
+ };
7594
7975
  }
7595
7976
  });
7596
7977
 
@@ -7599,7 +7980,7 @@ var check_runner_exports = {};
7599
7980
  __export(check_runner_exports, {
7600
7981
  CheckRunner: () => CheckRunner
7601
7982
  });
7602
- import { writeFileSync as writeFileSync4, existsSync as existsSync6, unlinkSync as unlinkSync3 } from "fs";
7983
+ import { writeFileSync as writeFileSync4, existsSync as existsSync7, unlinkSync as unlinkSync3 } from "fs";
7603
7984
  import { join as join7 } from "path";
7604
7985
  import { randomUUID as randomUUID3 } from "crypto";
7605
7986
  function serializePRInfo(prInfo) {
@@ -7647,11 +8028,13 @@ var init_check_runner = __esm({
7647
8028
  * 5. Return as ReviewSummary
7648
8029
  */
7649
8030
  static async runCheck(sandboxManager, sandboxName, sandboxConfig, checkConfig, prInfo, dependencyResults, timeoutMs, workspaceDefaults, serviceEnvVars) {
8031
+ const checkName = checkConfig.name || "unknown";
8032
+ const engineerCheck = checkName === "engineer-task";
7650
8033
  return withActiveSpan2(
7651
8034
  "visor.sandbox.runCheck",
7652
8035
  {
7653
8036
  "visor.sandbox.name": sandboxName,
7654
- "visor.check.name": checkConfig.name || "unknown"
8037
+ "visor.check.name": checkName
7655
8038
  },
7656
8039
  async () => {
7657
8040
  const dependencyOutputs = {};
@@ -7676,6 +8059,7 @@ var init_check_runner = __esm({
7676
8059
  }
7677
8060
  const workdir = sandboxConfig.workdir === "host" ? sandboxManager.getRepoPath() : sandboxConfig.workdir || "/workspace";
7678
8061
  let hostTracePath;
8062
+ let traceTailer;
7679
8063
  if (!sandboxConfig.read_only) {
7680
8064
  const traceFileName = `.visor-trace-${randomUUID3().slice(0, 8)}.ndjson`;
7681
8065
  hostTracePath = join7(sandboxManager.getRepoPath(), traceFileName);
@@ -7705,21 +8089,68 @@ var init_check_runner = __esm({
7705
8089
  }
7706
8090
  const command = `echo ${b64Payload} | base64 -d | node ${visorPath}/index.js --run-check -`;
7707
8091
  logger.info(`Executing check in sandbox '${sandboxName}'`);
7708
- const result = await sandboxManager.exec(sandboxName, {
7709
- command,
7710
- env,
7711
- timeoutMs: timeoutMs || 6e5,
7712
- maxBuffer: 50 * 1024 * 1024
8092
+ emitImmediateSpan2("visor.sandbox.child.started", {
8093
+ "visor.sandbox.name": sandboxName,
8094
+ "visor.check.name": checkName,
8095
+ "visor.trace.relay": hostTracePath ? "file-tail" : "disabled"
7713
8096
  });
8097
+ if (engineerCheck) {
8098
+ emitImmediateSpan2("visor.engineer.child_spawned", {
8099
+ "visor.sandbox.name": sandboxName,
8100
+ "visor.check.name": checkName,
8101
+ "visor.trace.relay": hostTracePath ? "file-tail" : "disabled"
8102
+ });
8103
+ }
7714
8104
  if (hostTracePath) {
7715
8105
  try {
7716
- if (existsSync6(hostTracePath)) {
7717
- ingestChildTrace(hostTracePath);
7718
- unlinkSync3(hostTracePath);
7719
- }
8106
+ const { context: otContext } = (init_lazy_otel(), __toCommonJS(lazy_otel_exports));
8107
+ traceTailer = new ChildTraceTailer(hostTracePath, {
8108
+ parentContext: otContext?.active?.()
8109
+ });
7720
8110
  } catch {
8111
+ traceTailer = new ChildTraceTailer(hostTracePath);
8112
+ }
8113
+ traceTailer.start();
8114
+ }
8115
+ emitImmediateSpan2("visor.sandbox.child.waiting", {
8116
+ "visor.sandbox.name": sandboxName,
8117
+ "visor.check.name": checkName
8118
+ });
8119
+ if (engineerCheck) {
8120
+ emitImmediateSpan2("visor.engineer.waiting_on_child", {
8121
+ "visor.sandbox.name": sandboxName,
8122
+ "visor.check.name": checkName
8123
+ });
8124
+ }
8125
+ let result;
8126
+ try {
8127
+ result = await sandboxManager.exec(sandboxName, {
8128
+ command,
8129
+ env,
8130
+ timeoutMs: timeoutMs || 6e5,
8131
+ maxBuffer: 50 * 1024 * 1024
8132
+ });
8133
+ emitImmediateSpan2("visor.sandbox.child.completed", {
8134
+ "visor.sandbox.name": sandboxName,
8135
+ "visor.check.name": checkName
8136
+ });
8137
+ } catch (error) {
8138
+ emitImmediateSpan2("visor.sandbox.child.failed", {
8139
+ "visor.sandbox.name": sandboxName,
8140
+ "visor.check.name": checkName,
8141
+ error: error instanceof Error ? error.message : String(error)
8142
+ });
8143
+ throw error;
8144
+ } finally {
8145
+ if (traceTailer) {
7721
8146
  try {
7722
- if (existsSync6(hostTracePath)) unlinkSync3(hostTracePath);
8147
+ await traceTailer.stop();
8148
+ } catch {
8149
+ }
8150
+ }
8151
+ if (hostTracePath) {
8152
+ try {
8153
+ if (existsSync7(hostTracePath)) unlinkSync3(hostTracePath);
7723
8154
  } catch {
7724
8155
  }
7725
8156
  }
@@ -7826,6 +8257,7 @@ function extractProjectMeta(dependencyResults) {
7826
8257
  }
7827
8258
  async function executeWithSandboxRouting(checkId, checkConfig, context2, prInfo, dependencyResults, timeout, hostExecute, projectMeta) {
7828
8259
  const sandboxManager = context2.sandboxManager;
8260
+ const engineerCheck = checkId === "engineer-task";
7829
8261
  if (!sandboxManager) {
7830
8262
  return hostExecute();
7831
8263
  }
@@ -7834,8 +8266,30 @@ async function executeWithSandboxRouting(checkId, checkConfig, context2, prInfo,
7834
8266
  context2.config.sandbox
7835
8267
  );
7836
8268
  if (!sandboxName) {
8269
+ emitImmediateSpan("visor.sandbox.routing.host", {
8270
+ "visor.check.id": checkId,
8271
+ "visor.sandbox.selected": ""
8272
+ });
8273
+ if (engineerCheck) {
8274
+ emitImmediateSpan("visor.engineer.sandbox_resolved", {
8275
+ "visor.check.id": checkId,
8276
+ "visor.sandbox.selected": "",
8277
+ "visor.sandbox.mode": "host"
8278
+ });
8279
+ }
7837
8280
  return hostExecute();
7838
8281
  }
8282
+ emitImmediateSpan("visor.sandbox.routing.selected", {
8283
+ "visor.check.id": checkId,
8284
+ "visor.sandbox.selected": sandboxName
8285
+ });
8286
+ if (engineerCheck) {
8287
+ emitImmediateSpan("visor.engineer.sandbox_resolved", {
8288
+ "visor.check.id": checkId,
8289
+ "visor.sandbox.selected": sandboxName,
8290
+ "visor.sandbox.mode": "sandbox"
8291
+ });
8292
+ }
7839
8293
  const sandboxConfig = context2.config.sandboxes?.[sandboxName];
7840
8294
  if (!sandboxConfig) {
7841
8295
  throw new Error(`Sandbox '${sandboxName}' not found in sandboxes configuration`);
@@ -7888,6 +8342,7 @@ var init_sandbox_routing = __esm({
7888
8342
  "src/state-machine/dispatch/sandbox-routing.ts"() {
7889
8343
  "use strict";
7890
8344
  init_logger();
8345
+ init_trace_helpers();
7891
8346
  }
7892
8347
  });
7893
8348
 
@@ -8097,7 +8552,7 @@ var init_dependency_gating = __esm({
8097
8552
  // src/state-machine/dispatch/template-renderer.ts
8098
8553
  async function renderTemplateContent(checkId, checkConfig, reviewSummary) {
8099
8554
  try {
8100
- const { createExtendedLiquid: createExtendedLiquid2 } = await import("./liquid-extensions-P6KDYILF.mjs");
8555
+ const { createExtendedLiquid: createExtendedLiquid2 } = await import("./liquid-extensions-E3AKRX7P.mjs");
8101
8556
  const fs13 = await import("fs/promises");
8102
8557
  const path15 = await import("path");
8103
8558
  const schemaRaw = checkConfig.schema || "plain";
@@ -9777,6 +10232,33 @@ var init_execution_invoker = __esm({
9777
10232
  });
9778
10233
 
9779
10234
  // src/state-machine/states/level-dispatch.ts
10235
+ function isEngineerCheck(checkId) {
10236
+ return checkId === "engineer-task";
10237
+ }
10238
+ function startCheckProgressTelemetry(checkId, providerType, attrs) {
10239
+ const intervalMs = Math.max(
10240
+ 5e3,
10241
+ parseInt(process.env.VISOR_CHECK_PROGRESS_INTERVAL_MS || "30000", 10) || 3e4
10242
+ );
10243
+ const startedAt = Date.now();
10244
+ const timer = setInterval(() => {
10245
+ const progressAttrs = {
10246
+ "visor.check.id": checkId,
10247
+ "visor.check.type": providerType,
10248
+ "visor.check.elapsed_ms": Date.now() - startedAt,
10249
+ ...attrs
10250
+ };
10251
+ emitImmediateSpan(`visor.check.${checkId}.progress`, progressAttrs);
10252
+ if (isEngineerCheck(checkId)) {
10253
+ emitImmediateSpan("visor.engineer.progress", progressAttrs);
10254
+ }
10255
+ }, intervalMs);
10256
+ if (typeof timer.unref === "function") timer.unref();
10257
+ return timer;
10258
+ }
10259
+ function stopCheckProgressTelemetry(timer) {
10260
+ if (timer) clearInterval(timer);
10261
+ }
9780
10262
  async function renderTemplateArgs(args, dependencyResults, context2) {
9781
10263
  if (!args || Object.keys(args).length === 0) {
9782
10264
  return args;
@@ -10486,32 +10968,84 @@ async function executeCheckWithForEachItems2(checkId, forEachParent, forEachItem
10486
10968
  });
10487
10969
  } catch {
10488
10970
  }
10489
- const itemResult = await withActiveSpan(
10490
- `visor.check.${checkId}`,
10491
- {
10971
+ emitImmediateSpan(`visor.check.${checkId}.started`, {
10972
+ "visor.check.id": checkId,
10973
+ "visor.check.type": providerType,
10974
+ "visor.foreach.index": itemIndex,
10975
+ session_id: context2.sessionId,
10976
+ wave: state.wave
10977
+ });
10978
+ if (isEngineerCheck(checkId)) {
10979
+ emitImmediateSpan("visor.engineer.started", {
10492
10980
  "visor.check.id": checkId,
10493
10981
  "visor.check.type": providerType,
10494
- "visor.foreach.index": itemIndex,
10495
- session_id: context2.sessionId,
10496
- wave: state.wave
10497
- },
10498
- async (span) => {
10499
- const res = await executeWithSandboxRouting(
10500
- checkId,
10501
- checkConfig,
10502
- context2,
10503
- prInfo,
10504
- dependencyResults,
10505
- checkConfig.timeout || checkConfig.ai?.timeout || 18e5,
10506
- () => provider.execute(prInfo, providerConfig, dependencyResults, executionContext)
10507
- );
10508
- try {
10509
- captureCheckOutput(span, res.output);
10510
- } catch {
10982
+ "visor.foreach.index": itemIndex
10983
+ });
10984
+ }
10985
+ const progressTimer = startCheckProgressTelemetry(checkId, providerType, {
10986
+ "visor.foreach.index": itemIndex,
10987
+ session_id: context2.sessionId,
10988
+ wave: state.wave
10989
+ });
10990
+ let itemResult;
10991
+ try {
10992
+ itemResult = await withActiveSpan(
10993
+ `visor.check.${checkId}`,
10994
+ {
10995
+ "visor.check.id": checkId,
10996
+ "visor.check.type": providerType,
10997
+ "visor.foreach.index": itemIndex,
10998
+ session_id: context2.sessionId,
10999
+ wave: state.wave
11000
+ },
11001
+ async (span) => {
11002
+ const res = await executeWithSandboxRouting(
11003
+ checkId,
11004
+ checkConfig,
11005
+ context2,
11006
+ prInfo,
11007
+ dependencyResults,
11008
+ checkConfig.timeout || checkConfig.ai?.timeout || 18e5,
11009
+ () => provider.execute(prInfo, providerConfig, dependencyResults, executionContext)
11010
+ );
11011
+ try {
11012
+ captureCheckOutput(span, res.output);
11013
+ } catch {
11014
+ }
11015
+ return res;
10511
11016
  }
10512
- return res;
11017
+ );
11018
+ emitImmediateSpan(`visor.check.${checkId}.completed`, {
11019
+ "visor.check.id": checkId,
11020
+ "visor.check.type": providerType,
11021
+ "visor.foreach.index": itemIndex
11022
+ });
11023
+ if (isEngineerCheck(checkId)) {
11024
+ emitImmediateSpan("visor.engineer.completed", {
11025
+ "visor.check.id": checkId,
11026
+ "visor.check.type": providerType,
11027
+ "visor.foreach.index": itemIndex
11028
+ });
10513
11029
  }
10514
- );
11030
+ } catch (error) {
11031
+ emitImmediateSpan(`visor.check.${checkId}.failed`, {
11032
+ "visor.check.id": checkId,
11033
+ "visor.check.type": providerType,
11034
+ "visor.foreach.index": itemIndex,
11035
+ error: error instanceof Error ? error.message : String(error)
11036
+ });
11037
+ if (isEngineerCheck(checkId)) {
11038
+ emitImmediateSpan("visor.engineer.failed", {
11039
+ "visor.check.id": checkId,
11040
+ "visor.check.type": providerType,
11041
+ "visor.foreach.index": itemIndex,
11042
+ error: error instanceof Error ? error.message : String(error)
11043
+ });
11044
+ }
11045
+ throw error;
11046
+ } finally {
11047
+ stopCheckProgressTelemetry(progressTimer);
11048
+ }
10515
11049
  const enrichedIssues = (itemResult.issues || []).map((issue) => ({
10516
11050
  ...issue,
10517
11051
  checkName: checkId,
@@ -10552,7 +11086,7 @@ async function executeCheckWithForEachItems2(checkId, forEachParent, forEachItem
10552
11086
  let schemaObj = (typeof checkConfig.schema === "object" ? checkConfig.schema : void 0) || checkConfig.output_schema;
10553
11087
  if (!schemaObj && typeof checkConfig.schema === "string") {
10554
11088
  try {
10555
- const { loadRendererSchema } = await import("./renderer-schema-KOIH75RZ.mjs");
11089
+ const { loadRendererSchema } = await import("./renderer-schema-BT2IXMLW.mjs");
10556
11090
  schemaObj = await loadRendererSchema(checkConfig.schema);
10557
11091
  } catch {
10558
11092
  }
@@ -10890,7 +11424,7 @@ async function executeCheckWithForEachItems2(checkId, forEachParent, forEachItem
10890
11424
  }
10891
11425
  }
10892
11426
  try {
10893
- const { evaluateTransitions } = await import("./routing-CVQT4KHX.mjs");
11427
+ const { evaluateTransitions } = await import("./routing-H2PQ57OA.mjs");
10894
11428
  const transTarget = await evaluateTransitions(
10895
11429
  onFinish.transitions,
10896
11430
  forEachParent,
@@ -10950,7 +11484,7 @@ async function executeCheckWithForEachItems2(checkId, forEachParent, forEachItem
10950
11484
  `[LevelDispatch] Error evaluating on_finish transitions for ${forEachParent}: ${e instanceof Error ? e.message : String(e)}`
10951
11485
  );
10952
11486
  }
10953
- const { evaluateGoto: evaluateGoto2 } = await import("./routing-CVQT4KHX.mjs");
11487
+ const { evaluateGoto: evaluateGoto2 } = await import("./routing-H2PQ57OA.mjs");
10954
11488
  if (context2.debug) {
10955
11489
  logger.info(
10956
11490
  `[LevelDispatch] Evaluating on_finish.goto_js for forEach parent: ${forEachParent}`
@@ -11589,31 +12123,76 @@ async function executeSingleCheck2(checkId, context2, state, emitEvent, transiti
11589
12123
  });
11590
12124
  } catch {
11591
12125
  }
11592
- const result = await withActiveSpan(
11593
- `visor.check.${checkId}`,
11594
- {
12126
+ emitImmediateSpan(`visor.check.${checkId}.started`, {
12127
+ "visor.check.id": checkId,
12128
+ "visor.check.type": providerType,
12129
+ session_id: context2.sessionId,
12130
+ wave: state.wave
12131
+ });
12132
+ if (isEngineerCheck(checkId)) {
12133
+ emitImmediateSpan("visor.engineer.started", {
11595
12134
  "visor.check.id": checkId,
11596
- "visor.check.type": providerType,
11597
- session_id: context2.sessionId,
11598
- wave: state.wave
11599
- },
11600
- async (span) => {
11601
- const res = await executeWithSandboxRouting(
11602
- checkId,
11603
- checkConfig2,
11604
- context2,
11605
- prInfo,
11606
- dependencyResults,
11607
- checkConfig2.timeout || checkConfig2.ai?.timeout || 18e5,
11608
- () => provider.execute(prInfo, providerConfig, dependencyResults, executionContext)
11609
- );
11610
- try {
11611
- captureCheckOutput(span, res.output);
11612
- } catch {
12135
+ "visor.check.type": providerType
12136
+ });
12137
+ }
12138
+ const progressTimer = startCheckProgressTelemetry(checkId, providerType, {
12139
+ session_id: context2.sessionId,
12140
+ wave: state.wave
12141
+ });
12142
+ let result;
12143
+ try {
12144
+ result = await withActiveSpan(
12145
+ `visor.check.${checkId}`,
12146
+ {
12147
+ "visor.check.id": checkId,
12148
+ "visor.check.type": providerType,
12149
+ session_id: context2.sessionId,
12150
+ wave: state.wave
12151
+ },
12152
+ async (span) => {
12153
+ const res = await executeWithSandboxRouting(
12154
+ checkId,
12155
+ checkConfig2,
12156
+ context2,
12157
+ prInfo,
12158
+ dependencyResults,
12159
+ checkConfig2.timeout || checkConfig2.ai?.timeout || 18e5,
12160
+ () => provider.execute(prInfo, providerConfig, dependencyResults, executionContext)
12161
+ );
12162
+ try {
12163
+ captureCheckOutput(span, res.output);
12164
+ } catch {
12165
+ }
12166
+ return res;
11613
12167
  }
11614
- return res;
12168
+ );
12169
+ emitImmediateSpan(`visor.check.${checkId}.completed`, {
12170
+ "visor.check.id": checkId,
12171
+ "visor.check.type": providerType
12172
+ });
12173
+ if (isEngineerCheck(checkId)) {
12174
+ emitImmediateSpan("visor.engineer.completed", {
12175
+ "visor.check.id": checkId,
12176
+ "visor.check.type": providerType
12177
+ });
11615
12178
  }
11616
- );
12179
+ } catch (error) {
12180
+ emitImmediateSpan(`visor.check.${checkId}.failed`, {
12181
+ "visor.check.id": checkId,
12182
+ "visor.check.type": providerType,
12183
+ error: error instanceof Error ? error.message : String(error)
12184
+ });
12185
+ if (isEngineerCheck(checkId)) {
12186
+ emitImmediateSpan("visor.engineer.failed", {
12187
+ "visor.check.id": checkId,
12188
+ "visor.check.type": providerType,
12189
+ error: error instanceof Error ? error.message : String(error)
12190
+ });
12191
+ }
12192
+ throw error;
12193
+ } finally {
12194
+ stopCheckProgressTelemetry(progressTimer);
12195
+ }
11617
12196
  try {
11618
12197
  const awaitingHumanInput = result?.awaitingHumanInput === true || result?.output && result.output.awaitingHumanInput === true;
11619
12198
  if (awaitingHumanInput) {
@@ -11643,7 +12222,7 @@ async function executeSingleCheck2(checkId, context2, state, emitEvent, transiti
11643
12222
  let schemaObj = (typeof checkConfig2.schema === "object" ? checkConfig2.schema : void 0) || checkConfig2.output_schema;
11644
12223
  if (!schemaObj && typeof checkConfig2.schema === "string") {
11645
12224
  try {
11646
- const { loadRendererSchema } = await import("./renderer-schema-KOIH75RZ.mjs");
12225
+ const { loadRendererSchema } = await import("./renderer-schema-BT2IXMLW.mjs");
11647
12226
  schemaObj = await loadRendererSchema(checkConfig2.schema);
11648
12227
  } catch {
11649
12228
  }
@@ -12209,7 +12788,7 @@ function updateStats2(results, state, isForEachIteration = false) {
12209
12788
  }
12210
12789
  async function renderTemplateContent2(checkId, checkConfig, reviewSummary) {
12211
12790
  try {
12212
- const { createExtendedLiquid: createExtendedLiquid2 } = await import("./liquid-extensions-P6KDYILF.mjs");
12791
+ const { createExtendedLiquid: createExtendedLiquid2 } = await import("./liquid-extensions-E3AKRX7P.mjs");
12213
12792
  const fs13 = await import("fs/promises");
12214
12793
  const path15 = await import("path");
12215
12794
  const schemaRaw = checkConfig.schema || "plain";
@@ -13998,7 +14577,7 @@ var init_state_machine_execution_engine = __esm({
13998
14577
  }
13999
14578
  try {
14000
14579
  if (options.config?.memory) {
14001
- const { MemoryStore: MemoryStore2 } = await import("./memory-store-K5N7MC7U.mjs");
14580
+ const { MemoryStore: MemoryStore2 } = await import("./memory-store-OHUIXCWJ.mjs");
14002
14581
  const memoryStore = MemoryStore2.getInstance(options.config.memory);
14003
14582
  await memoryStore.initialize();
14004
14583
  logger.debug("Memory store initialized");
@@ -14041,7 +14620,7 @@ var init_state_machine_execution_engine = __esm({
14041
14620
  try {
14042
14621
  const map = options?.webhookContext?.webhookData;
14043
14622
  if (map) {
14044
- const { CheckProviderRegistry: CheckProviderRegistry2 } = await import("./check-provider-registry-I4BCWKRU.mjs");
14623
+ const { CheckProviderRegistry: CheckProviderRegistry2 } = await import("./check-provider-registry-WSEVHJEV.mjs");
14045
14624
  const reg = CheckProviderRegistry2.getInstance();
14046
14625
  const p = reg.getProvider("http_input");
14047
14626
  if (p && typeof p.setWebhookContext === "function") p.setWebhookContext(map);
@@ -14154,7 +14733,7 @@ var init_state_machine_execution_engine = __esm({
14154
14733
  logger.info("[StateMachine] Using state machine engine");
14155
14734
  }
14156
14735
  if (!config) {
14157
- const { ConfigManager } = await import("./config-JE4HKTWW.mjs");
14736
+ const { ConfigManager } = await import("./config-PCP6O6Y6.mjs");
14158
14737
  const configManager = new ConfigManager();
14159
14738
  config = await configManager.getDefaultConfig();
14160
14739
  logger.debug("[StateMachine] Using default configuration (no config provided)");
@@ -14164,7 +14743,7 @@ var init_state_machine_execution_engine = __esm({
14164
14743
  tag_filter: tagFilter
14165
14744
  } : config;
14166
14745
  try {
14167
- const { CheckProviderRegistry: CheckProviderRegistry2 } = await import("./check-provider-registry-I4BCWKRU.mjs");
14746
+ const { CheckProviderRegistry: CheckProviderRegistry2 } = await import("./check-provider-registry-WSEVHJEV.mjs");
14168
14747
  const registry = CheckProviderRegistry2.getInstance();
14169
14748
  registry.setCustomTools(configWithTagFilter.tools || {});
14170
14749
  } catch (error) {
@@ -14205,7 +14784,7 @@ var init_state_machine_execution_engine = __esm({
14205
14784
  logger.debug(
14206
14785
  `[PolicyEngine] Loading enterprise policy engine (engine=${configWithTagFilter.policy.engine})`
14207
14786
  );
14208
- const { loadEnterprisePolicyEngine } = await import("./loader-ZNKKJEZ3.mjs");
14787
+ const { loadEnterprisePolicyEngine } = await import("./loader-WRGI244P.mjs");
14209
14788
  context2.policyEngine = await loadEnterprisePolicyEngine(configWithTagFilter.policy);
14210
14789
  logger.debug(
14211
14790
  `[PolicyEngine] Initialized: ${context2.policyEngine?.constructor?.name || "unknown"}`
@@ -14228,7 +14807,7 @@ var init_state_machine_execution_engine = __esm({
14228
14807
  try {
14229
14808
  const webhookData = this.executionContext?.webhookContext?.webhookData;
14230
14809
  if (webhookData instanceof Map) {
14231
- const { extractSlackContext: extractSlackContext2 } = await import("./schedule-tool-handler-6QLZRTQA.mjs");
14810
+ const { extractSlackContext: extractSlackContext2 } = await import("./schedule-tool-handler-NBEO46RV.mjs");
14232
14811
  const slackCtx = extractSlackContext2(webhookData);
14233
14812
  if (slackCtx) {
14234
14813
  const payload = Array.from(webhookData.values())[0];
@@ -14257,7 +14836,7 @@ var init_state_machine_execution_engine = __esm({
14257
14836
  if (Array.isArray(configWithTagFilter.frontends) && configWithTagFilter.frontends.length > 0) {
14258
14837
  try {
14259
14838
  const { EventBus } = await import("./event-bus-5K3Y2FCS.mjs");
14260
- const { FrontendsHost } = await import("./host-QBJ7TOWG.mjs");
14839
+ const { FrontendsHost } = await import("./host-CFM2ASDI.mjs");
14261
14840
  const bus = new EventBus();
14262
14841
  context2.eventBus = bus;
14263
14842
  frontendsHost = new FrontendsHost(bus, logger);
@@ -14309,7 +14888,7 @@ var init_state_machine_execution_engine = __esm({
14309
14888
  }
14310
14889
  let runTraceId;
14311
14890
  try {
14312
- const { trace: lazyTrace, context: lazyCtx } = await import("./lazy-otel-5NH4ZJJM.mjs");
14891
+ const { trace: lazyTrace, context: lazyCtx } = await import("./lazy-otel-5RDTVS5L.mjs");
14313
14892
  const activeSpan = lazyTrace.getSpan(lazyCtx.active());
14314
14893
  runTraceId = activeSpan?.spanContext()?.traceId;
14315
14894
  } catch {
@@ -14609,10 +15188,10 @@ var init_state_machine_execution_engine = __esm({
14609
15188
  * @returns Array of failure condition evaluation results
14610
15189
  */
14611
15190
  async evaluateFailureConditions(checkName, reviewSummary, config, previousOutputs, authorAssociation) {
14612
- const { FailureConditionEvaluator: FailureConditionEvaluator2 } = await import("./failure-condition-evaluator-5DZYMCGW.mjs");
15191
+ const { FailureConditionEvaluator: FailureConditionEvaluator2 } = await import("./failure-condition-evaluator-IRFKTYZD.mjs");
14613
15192
  const evaluator = new FailureConditionEvaluator2();
14614
- const { addEvent: addEvent3 } = await import("./trace-helpers-WJXYVV4S.mjs");
14615
- const { addFailIfTriggered } = await import("./metrics-JTOG2HNO.mjs");
15193
+ const { addEvent: addEvent3 } = await import("./trace-helpers-26ZCAE2V.mjs");
15194
+ const { addFailIfTriggered } = await import("./metrics-MYUPQBBV.mjs");
14616
15195
  const checkConfig = config.checks?.[checkName];
14617
15196
  if (!checkConfig) {
14618
15197
  return [];
@@ -15432,7 +16011,7 @@ var init_scheduler = __esm({
15432
16011
  const endpoint = "/scheduler/trigger";
15433
16012
  webhookData.set(endpoint, syntheticPayload);
15434
16013
  try {
15435
- const { refreshGitHubCredentials } = await import("./github-auth-27SZGPEC.mjs");
16014
+ const { refreshGitHubCredentials } = await import("./github-auth-BJQBLK2V.mjs");
15436
16015
  await refreshGitHubCredentials();
15437
16016
  } catch {
15438
16017
  }
@@ -15447,7 +16026,7 @@ var init_scheduler = __esm({
15447
16026
  inputs: schedule.workflowInputs
15448
16027
  });
15449
16028
  if (this.taskStore) {
15450
- const { trackExecution } = await import("./track-execution-MKIQXP2C.mjs");
16029
+ const { trackExecution } = await import("./track-execution-3EC24C2X.mjs");
15451
16030
  await trackExecution(
15452
16031
  {
15453
16032
  taskStore: this.taskStore,
@@ -15557,7 +16136,7 @@ Please provide an updated response based on the reminder above. You may referenc
15557
16136
  }
15558
16137
  }
15559
16138
  try {
15560
- const { refreshGitHubCredentials } = await import("./github-auth-27SZGPEC.mjs");
16139
+ const { refreshGitHubCredentials } = await import("./github-auth-BJQBLK2V.mjs");
15561
16140
  await refreshGitHubCredentials();
15562
16141
  } catch {
15563
16142
  }
@@ -15576,7 +16155,7 @@ Please provide an updated response based on the reminder above. You may referenc
15576
16155
  debug: process.env.VISOR_DEBUG === "true"
15577
16156
  });
15578
16157
  if (this.taskStore) {
15579
- const { trackExecution } = await import("./track-execution-MKIQXP2C.mjs");
16158
+ const { trackExecution } = await import("./track-execution-3EC24C2X.mjs");
15580
16159
  await trackExecution(
15581
16160
  {
15582
16161
  taskStore: this.taskStore,
@@ -15846,6 +16425,13 @@ async function handleScheduleAction(args, context2) {
15846
16425
  }
15847
16426
  }
15848
16427
  async function handleCreate(args, context2, store) {
16428
+ if (context2.executionSource === "scheduler") {
16429
+ return {
16430
+ success: false,
16431
+ message: "Scheduled runs cannot create new schedules",
16432
+ error: "Creating schedules from a scheduler-triggered execution is not allowed to prevent recursive scheduling."
16433
+ };
16434
+ }
15849
16435
  if (!args.reminder_text && !args.workflow) {
15850
16436
  return {
15851
16437
  success: false,
@@ -16095,6 +16681,13 @@ function formatTrigger(trigger) {
16095
16681
  return `\`${trigger.id.substring(0, 8)}\` - channels: ${channels} \u2192 workflow: "${trigger.workflow}"${filterStr}${status}`;
16096
16682
  }
16097
16683
  async function handleCreateTrigger(args, context2, store) {
16684
+ if (context2.executionSource === "scheduler") {
16685
+ return {
16686
+ success: false,
16687
+ message: "Scheduled runs cannot create new triggers",
16688
+ error: "Creating message triggers from a scheduler-triggered execution is not allowed to prevent recursive scheduling."
16689
+ };
16690
+ }
16098
16691
  const workflow = args.workflow || "default";
16099
16692
  if (context2.availableWorkflows && !context2.availableWorkflows.includes(workflow)) {
16100
16693
  return {
@@ -16532,6 +17125,7 @@ function slackChannelTypeToScheduleType(channelType) {
16532
17125
  }
16533
17126
  }
16534
17127
  function buildScheduleToolContext(sources, availableWorkflows, permissions, outputInfo) {
17128
+ const executionSource = sources.schedulerContext ? "scheduler" : "user";
16535
17129
  if (sources.slackContext) {
16536
17130
  const contextType = `slack:${sources.slackContext.userId}`;
16537
17131
  const scheduleType = determineScheduleType(
@@ -16555,7 +17149,8 @@ function buildScheduleToolContext(sources, availableWorkflows, permissions, outp
16555
17149
  availableWorkflows,
16556
17150
  scheduleType: finalScheduleType,
16557
17151
  permissions,
16558
- allowedScheduleType
17152
+ allowedScheduleType,
17153
+ executionSource
16559
17154
  };
16560
17155
  }
16561
17156
  if (sources.githubContext) {
@@ -16567,8 +17162,9 @@ function buildScheduleToolContext(sources, availableWorkflows, permissions, outp
16567
17162
  availableWorkflows,
16568
17163
  scheduleType: "personal",
16569
17164
  permissions,
16570
- allowedScheduleType: "personal"
17165
+ allowedScheduleType: "personal",
16571
17166
  // GitHub context only allows personal schedules
17167
+ executionSource
16572
17168
  };
16573
17169
  }
16574
17170
  return {
@@ -16578,8 +17174,9 @@ function buildScheduleToolContext(sources, availableWorkflows, permissions, outp
16578
17174
  availableWorkflows,
16579
17175
  scheduleType: "personal",
16580
17176
  permissions,
16581
- allowedScheduleType: "personal"
17177
+ allowedScheduleType: "personal",
16582
17178
  // CLI context only allows personal schedules
17179
+ executionSource
16583
17180
  };
16584
17181
  }
16585
17182
  var init_schedule_tool = __esm({
@@ -16591,6 +17188,170 @@ var init_schedule_tool = __esm({
16591
17188
  }
16592
17189
  });
16593
17190
 
17191
+ // src/agent-protocol/task-progress-tool.ts
17192
+ function getTaskProgressToolDefinition() {
17193
+ return {
17194
+ name: "task_progress",
17195
+ description: `Inspect the progress of tasks you are currently working on or have recently completed.
17196
+
17197
+ Use this tool when:
17198
+ - A user asks about progress, status, or what you've been doing
17199
+ - You need to check if a similar task is already running
17200
+ - You want to see the execution trace (steps taken, tools called, AI decisions) of a task
17201
+
17202
+ ACTIONS:
17203
+ - list: Show active and recent tasks in the current context (thread/channel)
17204
+ - trace: Get the detailed execution trace of a specific task \u2014 shows every step, tool call, and AI decision made so far
17205
+
17206
+ The trace output is a structured tree showing the full execution flow including:
17207
+ - Workflow steps and their durations
17208
+ - AI model calls with token counts
17209
+ - Tool invocations with inputs and results
17210
+ - Search queries and their results
17211
+ - Errors and retries`,
17212
+ inputSchema: {
17213
+ type: "object",
17214
+ properties: {
17215
+ action: {
17216
+ type: "string",
17217
+ enum: ["list", "trace"],
17218
+ description: 'Action to perform: "list" to see tasks, "trace" to see execution details of a specific task'
17219
+ },
17220
+ task_id: {
17221
+ type: "string",
17222
+ description: 'Task ID to inspect (required for "trace" action). Use "list" first to find task IDs.'
17223
+ }
17224
+ },
17225
+ required: ["action"]
17226
+ }
17227
+ };
17228
+ }
17229
+ function isTaskProgressTool(toolName) {
17230
+ return toolName === "task_progress";
17231
+ }
17232
+ async function handleTaskProgressAction(args, context2, taskStore) {
17233
+ try {
17234
+ switch (args.action) {
17235
+ case "list":
17236
+ return await handleList2(context2, taskStore);
17237
+ case "trace":
17238
+ if (!args.task_id) {
17239
+ return { success: false, error: 'task_id is required for the "trace" action' };
17240
+ }
17241
+ return await handleTrace(args.task_id, taskStore);
17242
+ default:
17243
+ return { success: false, error: `Unknown action: ${args.action}` };
17244
+ }
17245
+ } catch (err) {
17246
+ const msg = err instanceof Error ? err.message : String(err);
17247
+ logger.error(`[TaskProgressTool] Error: ${msg}`);
17248
+ return { success: false, error: msg };
17249
+ }
17250
+ }
17251
+ async function handleList2(context2, taskStore) {
17252
+ const metadata = {};
17253
+ if (context2.channelId) metadata.slack_channel = context2.channelId;
17254
+ if (context2.threadTs) metadata.slack_thread_ts = context2.threadTs;
17255
+ const activeResult = taskStore.listTasksRaw?.({
17256
+ state: ["submitted", "working"],
17257
+ metadata: Object.keys(metadata).length > 0 ? metadata : void 0,
17258
+ limit: 20
17259
+ }) || { rows: [] };
17260
+ const recentResult = taskStore.listTasksRaw?.({
17261
+ state: ["completed", "failed"],
17262
+ metadata: Object.keys(metadata).length > 0 ? metadata : void 0,
17263
+ limit: 10
17264
+ }) || { rows: [] };
17265
+ const lines = [];
17266
+ if (activeResult.rows?.length > 0) {
17267
+ lines.push("## Active Tasks");
17268
+ for (const row of activeResult.rows) {
17269
+ const trigger = row.metadata?.slack_trigger_text || (row.request_message || "").slice(0, 200);
17270
+ const elapsed = timeSince(row.created_at);
17271
+ lines.push(`- **${row.id}** [${row.state}] (${elapsed} ago)`);
17272
+ lines.push(` Workflow: ${row.workflow_id || "unknown"}`);
17273
+ lines.push(` Trigger: ${trigger}`);
17274
+ }
17275
+ } else {
17276
+ lines.push("No active tasks in this context.");
17277
+ }
17278
+ if (recentResult.rows?.length > 0) {
17279
+ lines.push("");
17280
+ lines.push("## Recent Completed Tasks");
17281
+ for (const row of recentResult.rows) {
17282
+ const trigger = row.metadata?.slack_trigger_text || (row.request_message || "").slice(0, 200);
17283
+ const elapsed = timeSince(row.created_at);
17284
+ lines.push(`- **${row.id}** [${row.state}] (${elapsed} ago)`);
17285
+ lines.push(` Workflow: ${row.workflow_id || "unknown"}`);
17286
+ lines.push(` Trigger: ${trigger}`);
17287
+ }
17288
+ }
17289
+ return { success: true, message: lines.join("\n") };
17290
+ }
17291
+ async function handleTrace(taskId, taskStore) {
17292
+ const task = taskStore.getTask?.(taskId);
17293
+ if (!task) {
17294
+ return { success: false, error: `Task not found: ${taskId}` };
17295
+ }
17296
+ const traceId = task.metadata?.trace_id;
17297
+ const traceFile = task.metadata?.trace_file;
17298
+ if (!traceId && !traceFile) {
17299
+ const trigger2 = task.metadata?.slack_trigger_text || "";
17300
+ return {
17301
+ success: true,
17302
+ message: [
17303
+ `## Task ${taskId}`,
17304
+ `State: ${task.state}`,
17305
+ `Created: ${task.created_at}`,
17306
+ `Workflow: ${task.workflow_id || "unknown"}`,
17307
+ trigger2 ? `Trigger: ${trigger2}` : "",
17308
+ "",
17309
+ "(No execution trace available for this task)"
17310
+ ].filter(Boolean).join("\n")
17311
+ };
17312
+ }
17313
+ const { serializeTraceForPrompt, readTraceIdFromFile } = await import("./trace-serializer-KKBJHM7J.mjs");
17314
+ let resolvedTraceId = traceId;
17315
+ if (!resolvedTraceId && traceFile) {
17316
+ resolvedTraceId = await readTraceIdFromFile(traceFile);
17317
+ }
17318
+ const taskResponse = task.status?.message?.parts?.[0]?.text;
17319
+ const traceTree = await serializeTraceForPrompt(
17320
+ traceFile || resolvedTraceId || "",
17321
+ 8e3,
17322
+ // generous limit so AI gets good context
17323
+ void 0,
17324
+ taskResponse,
17325
+ resolvedTraceId || void 0
17326
+ );
17327
+ const trigger = task.metadata?.slack_trigger_text || "";
17328
+ const elapsed = timeSince(task.created_at);
17329
+ const lines = [
17330
+ `## Task ${taskId}`,
17331
+ `State: ${task.state}`,
17332
+ `Started: ${elapsed} ago`,
17333
+ `Workflow: ${task.workflow_id || "unknown"}`,
17334
+ trigger ? `Trigger: ${trigger}` : "",
17335
+ "",
17336
+ "## Execution Trace",
17337
+ traceTree
17338
+ ];
17339
+ return { success: true, message: lines.filter(Boolean).join("\n") };
17340
+ }
17341
+ function timeSince(isoDate) {
17342
+ const ms = Date.now() - new Date(isoDate).getTime();
17343
+ if (ms < 6e4) return `${Math.round(ms / 1e3)}s`;
17344
+ if (ms < 36e5) return `${Math.round(ms / 6e4)}m`;
17345
+ if (ms < 864e5) return `${Math.round(ms / 36e5)}h`;
17346
+ return `${Math.round(ms / 864e5)}d`;
17347
+ }
17348
+ var init_task_progress_tool = __esm({
17349
+ "src/agent-protocol/task-progress-tool.ts"() {
17350
+ "use strict";
17351
+ init_logger();
17352
+ }
17353
+ });
17354
+
16594
17355
  // src/scheduler/cli-handler.ts
16595
17356
  var init_cli_handler = __esm({
16596
17357
  "src/scheduler/cli-handler.ts"() {
@@ -16779,9 +17540,11 @@ var init_mcp_custom_sse_server = __esm({
16779
17540
  init_custom_tool_executor();
16780
17541
  init_workflow_registry();
16781
17542
  init_schedule_tool();
17543
+ init_task_progress_tool();
16782
17544
  init_schedule_tool_handler();
16783
17545
  init_env_resolver();
16784
17546
  init_rate_limiter();
17547
+ init_sandbox();
16785
17548
  CustomToolsSSEServer = class _CustomToolsSSEServer {
16786
17549
  server = null;
16787
17550
  port = 0;
@@ -17481,6 +18244,7 @@ var init_mcp_custom_sse_server = __esm({
17481
18244
  try {
17482
18245
  if (isScheduleTool(toolName)) {
17483
18246
  const webhookData = this.workflowContext?.executionContext?.webhookContext?.webhookData;
18247
+ const webhookEventType = this.workflowContext?.executionContext?.webhookContext?.eventType;
17484
18248
  const slackContext = webhookData ? extractSlackContext(webhookData) : null;
17485
18249
  const visorCfg = this.workflowContext?.visorConfig;
17486
18250
  const availableWorkflows = visorCfg?.checks ? Object.keys(visorCfg.checks) : void 0;
@@ -17499,6 +18263,9 @@ var init_mcp_custom_sse_server = __esm({
17499
18263
  userName: slackContext.userName,
17500
18264
  timezone: slackContext.timezone,
17501
18265
  channelType: slackContext.channelType
18266
+ } : void 0,
18267
+ schedulerContext: webhookEventType === "schedule" ? {
18268
+ scheduleId: this.workflowContext?.executionContext?.inputs?.schedule?.id
17502
18269
  } : void 0
17503
18270
  },
17504
18271
  availableWorkflows,
@@ -17544,6 +18311,28 @@ var init_mcp_custom_sse_server = __esm({
17544
18311
  result = scheduleResult.success ? scheduleResult.message : `Error: ${scheduleResult.error}`;
17545
18312
  break;
17546
18313
  }
18314
+ if (isTaskProgressTool(toolName)) {
18315
+ const webhookData = this.workflowContext?.executionContext?.webhookContext?.webhookData;
18316
+ const slackCtx = webhookData ? extractSlackContext(webhookData) : null;
18317
+ const taskStore = this.workflowContext?.taskStore || this.workflowContext?.executionContext?.taskStore || this.workflowContext?.executionContext?._parentContext?.taskStore || webhookData?.get?.("__taskStore");
18318
+ if (!taskStore) {
18319
+ result = "Error: Task store not available in this context";
18320
+ break;
18321
+ }
18322
+ const progressResult = await handleTaskProgressAction(
18323
+ {
18324
+ action: args.action || "list",
18325
+ task_id: args.task_id
18326
+ },
18327
+ {
18328
+ channelId: slackCtx?.channel || void 0,
18329
+ threadTs: slackCtx?.threadTs || void 0
18330
+ },
18331
+ taskStore
18332
+ );
18333
+ result = progressResult.success ? progressResult.message : `Error: ${progressResult.error}`;
18334
+ break;
18335
+ }
17547
18336
  const tool = this.tools.get(toolName);
17548
18337
  if (tool && isWorkflowTool(tool)) {
17549
18338
  if (this.gracefulStopRequested) {
@@ -17736,18 +18525,49 @@ var init_mcp_custom_sse_server = __esm({
17736
18525
  );
17737
18526
  }
17738
18527
  const contentType = response.headers.get("content-type");
18528
+ let data;
17739
18529
  if (contentType && contentType.includes("application/json")) {
17740
- return await response.json();
18530
+ data = await response.json();
18531
+ } else {
18532
+ const text = await response.text();
18533
+ if (text.trim().startsWith("{") || text.trim().startsWith("[")) {
18534
+ try {
18535
+ data = JSON.parse(text);
18536
+ } catch {
18537
+ data = text;
18538
+ }
18539
+ } else {
18540
+ data = text;
18541
+ }
17741
18542
  }
17742
- const text = await response.text();
17743
- if (text.trim().startsWith("{") || text.trim().startsWith("[")) {
18543
+ const transformJs = tool.transform_js;
18544
+ if (transformJs && data !== void 0) {
17744
18545
  try {
17745
- return JSON.parse(text);
17746
- } catch {
17747
- return text;
18546
+ const sandbox = createSecureSandbox();
18547
+ const jsScope = {
18548
+ output: data,
18549
+ path: apiPath,
18550
+ method,
18551
+ query: queryParams,
18552
+ args
18553
+ };
18554
+ data = compileAndRun(sandbox, transformJs, jsScope, {
18555
+ injectLog: true,
18556
+ logPrefix: `\u{1F50D} [${tool.type}:transform_js]`,
18557
+ wrapFunction: true
18558
+ });
18559
+ if (this.debug) {
18560
+ logger.debug(
18561
+ `[CustomToolsSSEServer:${this.sessionId}] Applied transform_js for http_client tool`
18562
+ );
18563
+ }
18564
+ } catch (error) {
18565
+ logger.error(
18566
+ `[CustomToolsSSEServer:${this.sessionId}] transform_js failed: ${error instanceof Error ? error.message : "Unknown error"}`
18567
+ );
17748
18568
  }
17749
18569
  }
17750
- return text;
18570
+ return data;
17751
18571
  } catch (error) {
17752
18572
  clearTimeout(timeoutId);
17753
18573
  if (error instanceof Error && error.name === "AbortError") {
@@ -17770,7 +18590,7 @@ var init_mcp_custom_sse_server = __esm({
17770
18590
  `[CustomToolsSSEServer:${this.sessionId}] Executing UTCP tool '${utcpToolName}' with args: ${JSON.stringify(args)}`
17771
18591
  );
17772
18592
  }
17773
- const { UtcpCheckProvider: UtcpCheckProvider2 } = await import("./utcp-check-provider-JLIYF5HH.mjs");
18593
+ const { UtcpCheckProvider: UtcpCheckProvider2 } = await import("./utcp-check-provider-WI3QZ3W6.mjs");
17774
18594
  return UtcpCheckProvider2.callTool(manual, utcpToolName, args, {
17775
18595
  variables: tool.__utcpVariables || {},
17776
18596
  plugins: tool.__utcpPlugins || ["http"],
@@ -17950,6 +18770,7 @@ var init_ai_check_provider = __esm({
17950
18770
  init_tool_resolver();
17951
18771
  init_sandbox();
17952
18772
  init_schedule_tool();
18773
+ init_task_progress_tool();
17953
18774
  init_schedule_tool_handler();
17954
18775
  AICheckProvider = class _AICheckProvider extends CheckProvider {
17955
18776
  aiReviewService;
@@ -17996,6 +18817,12 @@ var init_ai_check_provider = __esm({
17996
18817
  } catch {
17997
18818
  }
17998
18819
  }
18820
+ if (first.active_tasks && prInfo) {
18821
+ try {
18822
+ prInfo.activeTasks = first.active_tasks;
18823
+ } catch {
18824
+ }
18825
+ }
17999
18826
  const transportCtx = slackConv ? { slack: { event: ev, conversation: slackConv } } : { telegram: { event: ev, conversation: telegramConv } };
18000
18827
  return { ...transportCtx, conversation: conv };
18001
18828
  } catch {
@@ -18977,8 +19804,20 @@ ${preview}`);
18977
19804
  const contextInfo = slackContext ? `user=${slackContext.userId}, channelType=${slackContext.channelType}` : "cli";
18978
19805
  logger.debug(`[AICheckProvider] Schedule tool requested (${contextInfo})`);
18979
19806
  }
19807
+ const taskProgressToolRequested = !config.ai?.disableTools && customToolsToLoad.some(
19808
+ (tool) => tool === "task_progress" || typeof tool === "object" && tool.tool === "task_progress"
19809
+ );
19810
+ if (taskProgressToolRequested) {
19811
+ customToolsToLoad = customToolsToLoad.filter(
19812
+ (tool) => tool !== "task_progress" && !(typeof tool === "object" && tool.tool === "task_progress")
19813
+ );
19814
+ if (!customToolsServerName) {
19815
+ customToolsServerName = "__tools__";
19816
+ }
19817
+ logger.debug(`[AICheckProvider] Task progress tool requested`);
19818
+ }
18980
19819
  const scheduleToolEnabled = scheduleToolRequested || config.ai?.enable_scheduler === true && !config.ai?.disableTools;
18981
- if ((customToolsToLoad.length > 0 || scheduleToolEnabled || httpClientEntriesFromMcp.length > 0) && (customToolsServerName || scheduleToolEnabled || httpClientEntriesFromMcp.length > 0) && !config.ai?.disableTools) {
19820
+ if ((customToolsToLoad.length > 0 || scheduleToolEnabled || taskProgressToolRequested || httpClientEntriesFromMcp.length > 0) && (customToolsServerName || scheduleToolEnabled || taskProgressToolRequested || httpClientEntriesFromMcp.length > 0) && !config.ai?.disableTools) {
18982
19821
  if (!customToolsServerName) {
18983
19822
  customToolsServerName = "__tools__";
18984
19823
  }
@@ -19010,6 +19849,11 @@ ${preview}`);
19010
19849
  customTools.set(scheduleTool.name, scheduleTool);
19011
19850
  logger.debug(`[AICheckProvider] Added built-in schedule tool`);
19012
19851
  }
19852
+ if (taskProgressToolRequested) {
19853
+ const taskProgressTool = getTaskProgressToolDefinition();
19854
+ customTools.set(taskProgressTool.name, taskProgressTool);
19855
+ logger.debug(`[AICheckProvider] Added built-in task_progress tool`);
19856
+ }
19013
19857
  for (const entry of httpClientEntriesFromMcp) {
19014
19858
  const httpTool = {
19015
19859
  name: entry.name,
@@ -19055,7 +19899,7 @@ ${preview}`);
19055
19899
  if (utcpEntriesFromMcp.length > 0) {
19056
19900
  for (const entry of utcpEntriesFromMcp) {
19057
19901
  try {
19058
- const { UtcpCheckProvider: UtcpCheckProvider2 } = await import("./utcp-check-provider-JLIYF5HH.mjs");
19902
+ const { UtcpCheckProvider: UtcpCheckProvider2 } = await import("./utcp-check-provider-WI3QZ3W6.mjs");
19059
19903
  const manual = entry.config.manual;
19060
19904
  const variables = entry.config.variables;
19061
19905
  const plugins = entry.config.plugins || ["http"];
@@ -19147,6 +19991,12 @@ ${preview}`);
19147
19991
  executionContext: sessionInfo,
19148
19992
  workspace: parentCtxForTools?.workspace
19149
19993
  };
19994
+ if (taskProgressToolRequested) {
19995
+ const taskStoreRef = parentCtxForTools?.taskStore || sessionInfo?.taskStore;
19996
+ if (taskStoreRef) {
19997
+ workflowContext.taskStore = taskStoreRef;
19998
+ }
19999
+ }
19150
20000
  customToolsServer = new CustomToolsSSEServer(
19151
20001
  customTools,
19152
20002
  sessionId,
@@ -42466,10 +43316,11 @@ function buildBuiltinGlobals(opts) {
42466
43316
  const asyncFunctionNames = /* @__PURE__ */ new Set();
42467
43317
  const scheduleFn = async (args = {}) => {
42468
43318
  try {
42469
- const { handleScheduleAction: handleScheduleAction2, buildScheduleToolContext: buildScheduleToolContext2 } = await import("./schedule-tool-AECLFHSY.mjs");
42470
- const { extractSlackContext: extractSlackContext2 } = await import("./schedule-tool-handler-6QLZRTQA.mjs");
43319
+ const { handleScheduleAction: handleScheduleAction2, buildScheduleToolContext: buildScheduleToolContext2 } = await import("./schedule-tool-2DPNSU63.mjs");
43320
+ const { extractSlackContext: extractSlackContext2 } = await import("./schedule-tool-handler-NBEO46RV.mjs");
42471
43321
  const parentCtx = opts.sessionInfo?._parentContext;
42472
43322
  const webhookData = parentCtx?.prInfo?.eventContext?.webhookData;
43323
+ const webhookEventType = parentCtx?.webhookContext?.eventType || parentCtx?.prInfo?.eventContext?.eventType;
42473
43324
  const visorCfg = parentCtx?.config;
42474
43325
  const slackContext = webhookData ? extractSlackContext2(webhookData) : null;
42475
43326
  const availableWorkflows = visorCfg?.checks ? Object.keys(visorCfg.checks) : void 0;
@@ -42477,7 +43328,8 @@ function buildBuiltinGlobals(opts) {
42477
43328
  const context2 = buildScheduleToolContext2(
42478
43329
  {
42479
43330
  slackContext: slackContext || void 0,
42480
- cliContext: slackContext ? void 0 : { userId: "script" }
43331
+ cliContext: slackContext ? void 0 : { userId: "script" },
43332
+ schedulerContext: webhookEventType === "schedule" ? { scheduleId: parentCtx?.inputs?.schedule?.id } : void 0
42481
43333
  },
42482
43334
  availableWorkflows,
42483
43335
  permissions
@@ -42596,7 +43448,7 @@ function buildBuiltinGlobals(opts) {
42596
43448
  if (opts.config.enable_bash === true) {
42597
43449
  const bashFn = async (args = {}) => {
42598
43450
  try {
42599
- const { CommandExecutor } = await import("./command-executor-3AHGIYQG.mjs");
43451
+ const { CommandExecutor } = await import("./command-executor-YNJOS77A.mjs");
42600
43452
  const executor = CommandExecutor.getInstance();
42601
43453
  const command = String(args.command || "");
42602
43454
  if (!command) return "ERROR: command is required";
@@ -44051,7 +44903,20 @@ var init_git_checkout_provider = __esm({
44051
44903
  if (!resolvedRef || resolvedRef.trim().length === 0) {
44052
44904
  resolvedRef = "HEAD";
44053
44905
  }
44054
- const resolvedRepository = checkoutConfig.repository ? await this.liquid.parseAndRender(checkoutConfig.repository, templateContext) : process.env.GITHUB_REPOSITORY || "unknown/unknown";
44906
+ let resolvedRepository = checkoutConfig.repository ? await this.liquid.parseAndRender(checkoutConfig.repository, templateContext) : process.env.GITHUB_REPOSITORY || "";
44907
+ resolvedRepository = resolvedRepository.trim();
44908
+ if (!resolvedRepository || resolvedRepository === "unknown/unknown") {
44909
+ logger.warn(
44910
+ `[GitCheckout] Skipping checkout: repository resolved to empty (template: "${checkoutConfig.repository}")`
44911
+ );
44912
+ const output2 = {
44913
+ success: false,
44914
+ skipped: true,
44915
+ reason: "repository not configured",
44916
+ error: "repository not configured"
44917
+ };
44918
+ return { issues: [], output: output2 };
44919
+ }
44055
44920
  const resolvedToken = checkoutConfig.token ? await this.liquid.parseAndRender(checkoutConfig.token, templateContext) : void 0;
44056
44921
  const resolvedWorkingDirectory = checkoutConfig.working_directory ? await this.liquid.parseAndRender(checkoutConfig.working_directory, templateContext) : void 0;
44057
44922
  logger.info(`Checking out repository: ${resolvedRepository}@${resolvedRef}`);
@@ -44195,7 +45060,7 @@ var init_git_checkout_provider = __esm({
44195
45060
  }
44196
45061
  async isAvailable() {
44197
45062
  try {
44198
- const { commandExecutor: commandExecutor2 } = await import("./command-executor-3AHGIYQG.mjs");
45063
+ const { commandExecutor: commandExecutor2 } = await import("./command-executor-YNJOS77A.mjs");
44199
45064
  const result = await commandExecutor2.execute("git --version", { timeout: 5e3 });
44200
45065
  return result.exitCode === 0;
44201
45066
  } catch (_error) {
@@ -46191,4 +47056,4 @@ undici/lib/fetch/body.js:
46191
47056
  undici/lib/websocket/frame.js:
46192
47057
  (*! ws. MIT License. Einar Otto Stangvik <einaros@gmail.com> *)
46193
47058
  */
46194
- //# sourceMappingURL=chunk-TQQNSHQV.mjs.map
47059
+ //# sourceMappingURL=chunk-UXB4XWEE.mjs.map