@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
@@ -1,270 +0,0 @@
1
- import {
2
- __esm
3
- } from "./chunk-J7LXIPZS.mjs";
4
-
5
- // src/debug-visualizer/trace-reader.ts
6
- import * as fs from "fs";
7
- import * as readline from "readline";
8
- async function parseNDJSONTrace(filePath) {
9
- const spans = [];
10
- let lineNumber = 0;
11
- const fileStream = fs.createReadStream(filePath);
12
- const rl = readline.createInterface({
13
- input: fileStream,
14
- crlfDelay: Infinity
15
- });
16
- for await (const line of rl) {
17
- lineNumber++;
18
- if (!line.trim()) {
19
- continue;
20
- }
21
- try {
22
- const rawSpan = JSON.parse(line);
23
- const processedSpan = processRawSpan(rawSpan);
24
- spans.push(processedSpan);
25
- } catch (error) {
26
- console.warn(`[trace-reader] Malformed JSON at line ${lineNumber}: ${error}`);
27
- }
28
- }
29
- if (spans.length === 0) {
30
- throw new Error("No valid spans found in trace file");
31
- }
32
- const tree = buildExecutionTree(spans);
33
- const snapshots = extractStateSnapshots(spans);
34
- const timeline = computeTimeline(spans);
35
- const sortedSpans = [...spans].sort((a, b) => compareTimeValues(a.startTime, b.startTime));
36
- const firstSpan = sortedSpans[0];
37
- const lastSpan = sortedSpans[sortedSpans.length - 1];
38
- const startTimeMs = timeValueToMillis(firstSpan.startTime);
39
- const endTimeMs = timeValueToMillis(lastSpan.endTime);
40
- return {
41
- runId: tree.checkId,
42
- traceId: firstSpan.traceId,
43
- spans,
44
- tree,
45
- timeline,
46
- snapshots,
47
- metadata: {
48
- startTime: timeValueToISO(firstSpan.startTime),
49
- endTime: timeValueToISO(lastSpan.endTime),
50
- duration: endTimeMs - startTimeMs,
51
- totalSpans: spans.length,
52
- totalSnapshots: snapshots.length
53
- }
54
- };
55
- }
56
- function processRawSpan(rawSpan) {
57
- const traceId = rawSpan.traceId || "";
58
- const spanId = rawSpan.spanId || "";
59
- const parentSpanId = rawSpan.parentSpanId || void 0;
60
- const name = rawSpan.name || "unknown";
61
- const startTime = rawSpan.startTime || [0, 0];
62
- const endTime = rawSpan.endTime || rawSpan.startTime || [0, 0];
63
- const startMs = timeValueToMillis(startTime);
64
- const endMs = timeValueToMillis(endTime);
65
- const duration = endMs - startMs;
66
- const attributes = rawSpan.attributes || {};
67
- const events = (rawSpan.events || []).map((evt) => ({
68
- name: evt.name || "unknown",
69
- time: evt.time || [0, 0],
70
- timestamp: evt.timestamp || timeValueToISO(evt.time || [0, 0]),
71
- attributes: evt.attributes || {}
72
- }));
73
- const status = rawSpan.status?.code === 2 ? "error" : "ok";
74
- return {
75
- traceId,
76
- spanId,
77
- parentSpanId,
78
- name,
79
- startTime,
80
- endTime,
81
- duration,
82
- attributes,
83
- events,
84
- status
85
- };
86
- }
87
- function buildExecutionTree(spans) {
88
- const nodeMap = /* @__PURE__ */ new Map();
89
- for (const span of spans) {
90
- const node = createExecutionNode(span);
91
- nodeMap.set(span.spanId, node);
92
- }
93
- let rootNode;
94
- const orphans = [];
95
- for (const span of spans) {
96
- const node = nodeMap.get(span.spanId);
97
- if (!span.parentSpanId) {
98
- rootNode = node;
99
- } else {
100
- const parent = nodeMap.get(span.parentSpanId);
101
- if (parent) {
102
- parent.children.push(node);
103
- } else {
104
- orphans.push(node);
105
- }
106
- }
107
- }
108
- if (!rootNode) {
109
- console.warn("[trace-reader] No root span found, creating synthetic root");
110
- rootNode = {
111
- checkId: "synthetic-root",
112
- type: "run",
113
- status: "completed",
114
- children: Array.from(nodeMap.values()).filter((n) => !n.span.parentSpanId),
115
- span: spans[0],
116
- // Use first span as placeholder
117
- state: {}
118
- };
119
- }
120
- if (orphans.length > 0 && rootNode) {
121
- rootNode.children.push(...orphans);
122
- }
123
- return rootNode;
124
- }
125
- function createExecutionNode(span) {
126
- const attrs = span.attributes;
127
- const checkId = attrs["visor.check.id"] || attrs["visor.run.id"] || span.spanId;
128
- let type = "unknown";
129
- if (span.name === "visor.run") {
130
- type = "run";
131
- } else if (span.name === "visor.check") {
132
- type = "check";
133
- } else if (span.name.startsWith("visor.provider.")) {
134
- type = "provider";
135
- }
136
- let status = "completed";
137
- if (span.status === "error") {
138
- status = "error";
139
- } else if (attrs["visor.check.skipped"] === true) {
140
- status = "skipped";
141
- }
142
- const state = {};
143
- if (attrs["visor.check.input.context"]) {
144
- try {
145
- state.inputContext = JSON.parse(attrs["visor.check.input.context"]);
146
- } catch {
147
- state.inputContext = attrs["visor.check.input.context"];
148
- }
149
- }
150
- if (attrs["visor.check.output"]) {
151
- try {
152
- state.output = JSON.parse(attrs["visor.check.output"]);
153
- } catch {
154
- state.output = attrs["visor.check.output"];
155
- }
156
- }
157
- if (span.status === "error" || attrs["visor.check.error"]) {
158
- state.errors = [attrs["visor.check.error"] || "Unknown error"];
159
- }
160
- state.metadata = {
161
- type: attrs["visor.check.type"],
162
- duration: span.duration,
163
- provider: attrs["visor.provider.type"]
164
- };
165
- return {
166
- checkId,
167
- type,
168
- status,
169
- children: [],
170
- span,
171
- state
172
- };
173
- }
174
- function extractStateSnapshots(spans) {
175
- const snapshots = [];
176
- for (const span of spans) {
177
- for (const event of span.events) {
178
- if (event.name === "state.snapshot") {
179
- const attrs = event.attributes || {};
180
- const snapshot = {
181
- checkId: attrs["visor.snapshot.check_id"] || span.attributes["visor.check.id"] || "unknown",
182
- timestamp: attrs["visor.snapshot.timestamp"] || event.timestamp || timeValueToISO(event.time),
183
- timestampNanos: event.time,
184
- outputs: parseJSON(attrs["visor.snapshot.outputs"], {}),
185
- memory: parseJSON(attrs["visor.snapshot.memory"], {})
186
- };
187
- snapshots.push(snapshot);
188
- }
189
- }
190
- }
191
- snapshots.sort((a, b) => compareTimeValues(a.timestampNanos, b.timestampNanos));
192
- return snapshots;
193
- }
194
- function computeTimeline(spans) {
195
- const events = [];
196
- for (const span of spans) {
197
- const checkId = span.attributes["visor.check.id"] || span.spanId;
198
- events.push({
199
- type: "check.started",
200
- checkId,
201
- timestamp: timeValueToISO(span.startTime),
202
- timestampNanos: span.startTime,
203
- metadata: {
204
- name: span.name,
205
- type: span.attributes["visor.check.type"]
206
- }
207
- });
208
- events.push({
209
- type: span.status === "error" ? "check.failed" : "check.completed",
210
- checkId,
211
- timestamp: timeValueToISO(span.endTime),
212
- timestampNanos: span.endTime,
213
- duration: span.duration,
214
- status: span.status,
215
- metadata: {
216
- name: span.name
217
- }
218
- });
219
- for (const evt of span.events) {
220
- events.push({
221
- type: evt.name === "state.snapshot" ? "state.snapshot" : "event",
222
- checkId: evt.attributes?.["visor.snapshot.check_id"] || checkId,
223
- timestamp: evt.timestamp || timeValueToISO(evt.time),
224
- timestampNanos: evt.time,
225
- metadata: {
226
- eventName: evt.name,
227
- attributes: evt.attributes
228
- }
229
- });
230
- }
231
- }
232
- events.sort((a, b) => compareTimeValues(a.timestampNanos, b.timestampNanos));
233
- return events;
234
- }
235
- function timeValueToMillis(timeValue) {
236
- const [seconds, nanos] = timeValue;
237
- return seconds * 1e3 + nanos / 1e6;
238
- }
239
- function timeValueToISO(timeValue) {
240
- const millis = timeValueToMillis(timeValue);
241
- return new Date(millis).toISOString();
242
- }
243
- function compareTimeValues(a, b) {
244
- if (a[0] !== b[0]) {
245
- return a[0] - b[0];
246
- }
247
- return a[1] - b[1];
248
- }
249
- function parseJSON(value, defaultValue) {
250
- if (typeof value !== "string") {
251
- return defaultValue;
252
- }
253
- try {
254
- return JSON.parse(value);
255
- } catch {
256
- return defaultValue;
257
- }
258
- }
259
- var init_trace_reader = __esm({
260
- "src/debug-visualizer/trace-reader.ts"() {
261
- }
262
- });
263
- init_trace_reader();
264
- export {
265
- buildExecutionTree,
266
- computeTimeline,
267
- extractStateSnapshots,
268
- parseNDJSONTrace
269
- };
270
- //# sourceMappingURL=trace-reader-OVE4DL2D.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/debug-visualizer/trace-reader.ts"],"sourcesContent":["/**\n * Trace File Reader & Processor\n *\n * Reads OpenTelemetry NDJSON trace files and reconstructs execution tree structure\n * for the Debug Visualizer.\n *\n * Milestone 2: Trace File Reader\n */\n\nimport * as fs from 'fs';\nimport * as readline from 'readline';\n\n// ============================================================================\n// Core Data Structures\n// ============================================================================\n\n/**\n * OTEL span event with attributes\n */\nexport interface SpanEvent {\n name: string;\n time: [number, number]; // [seconds, nanoseconds]\n timestamp?: string; // ISO timestamp for convenience\n attributes?: Record<string, any>;\n}\n\n/**\n * Processed OTEL span with clean structure\n */\nexport interface ProcessedSpan {\n traceId: string;\n spanId: string;\n parentSpanId?: string;\n name: string;\n startTime: [number, number]; // [seconds, nanoseconds]\n endTime: [number, number]; // [seconds, nanoseconds]\n duration: number; // milliseconds\n attributes: Record<string, any>;\n events: SpanEvent[];\n status: 'ok' | 'error';\n}\n\n/**\n * Hierarchical execution tree node\n */\nexport interface ExecutionNode {\n checkId: string;\n type: string; // 'run', 'check', 'provider'\n status: 'pending' | 'running' | 'completed' | 'error' | 'skipped';\n children: ExecutionNode[];\n span: ProcessedSpan;\n state: {\n inputContext?: any;\n output?: any;\n errors?: string[];\n metadata?: Record<string, any>;\n };\n}\n\n/**\n * State snapshot for time-travel debugging\n */\nexport interface StateSnapshot {\n checkId: string;\n timestamp: string;\n timestampNanos: [number, number];\n outputs: Record<string, any>;\n memory: Record<string, any>;\n}\n\n/**\n * Timeline event for visualization\n */\nexport interface TimelineEvent {\n type: 'check.started' | 'check.completed' | 'check.failed' | 'state.snapshot' | 'event';\n checkId?: string;\n timestamp: string;\n timestampNanos: [number, number];\n duration?: number;\n status?: string;\n metadata?: Record<string, any>;\n}\n\n/**\n * Complete parsed execution trace\n */\nexport interface ExecutionTrace {\n runId: string;\n traceId: string;\n spans: ProcessedSpan[];\n tree: ExecutionNode;\n timeline: TimelineEvent[];\n snapshots: StateSnapshot[];\n metadata: {\n startTime: string;\n endTime: string;\n duration: number; // milliseconds\n totalSpans: number;\n totalSnapshots: number;\n };\n}\n\n// ============================================================================\n// NDJSON Parser\n// ============================================================================\n\n/**\n * Parse NDJSON trace file and return structured execution trace\n *\n * @param filePath - Path to NDJSON trace file\n * @returns Parsed execution trace with tree, timeline, and snapshots\n */\nexport async function parseNDJSONTrace(filePath: string): Promise<ExecutionTrace> {\n const spans: ProcessedSpan[] = [];\n let lineNumber = 0;\n\n // Read file line by line\n const fileStream = fs.createReadStream(filePath);\n const rl = readline.createInterface({\n input: fileStream,\n crlfDelay: Infinity,\n });\n\n for await (const line of rl) {\n lineNumber++;\n\n // Skip empty lines\n if (!line.trim()) {\n continue;\n }\n\n try {\n const rawSpan = JSON.parse(line);\n const processedSpan = processRawSpan(rawSpan);\n spans.push(processedSpan);\n } catch (error) {\n console.warn(`[trace-reader] Malformed JSON at line ${lineNumber}: ${error}`);\n // Continue parsing remaining lines\n }\n }\n\n if (spans.length === 0) {\n throw new Error('No valid spans found in trace file');\n }\n\n // Build execution tree\n const tree = buildExecutionTree(spans);\n\n // Extract state snapshots\n const snapshots = extractStateSnapshots(spans);\n\n // Compute timeline\n const timeline = computeTimeline(spans);\n\n // Calculate metadata\n const sortedSpans = [...spans].sort((a, b) => compareTimeValues(a.startTime, b.startTime));\n const firstSpan = sortedSpans[0];\n const lastSpan = sortedSpans[sortedSpans.length - 1];\n\n const startTimeMs = timeValueToMillis(firstSpan.startTime);\n const endTimeMs = timeValueToMillis(lastSpan.endTime);\n\n return {\n runId: tree.checkId,\n traceId: firstSpan.traceId,\n spans,\n tree,\n timeline,\n snapshots,\n metadata: {\n startTime: timeValueToISO(firstSpan.startTime),\n endTime: timeValueToISO(lastSpan.endTime),\n duration: endTimeMs - startTimeMs,\n totalSpans: spans.length,\n totalSnapshots: snapshots.length,\n },\n };\n}\n\n/**\n * Process raw OTEL span into clean structure\n */\nfunction processRawSpan(rawSpan: any): ProcessedSpan {\n // Extract span IDs\n const traceId = rawSpan.traceId || '';\n const spanId = rawSpan.spanId || '';\n const parentSpanId = rawSpan.parentSpanId || undefined;\n\n // Extract name\n const name = rawSpan.name || 'unknown';\n\n // Extract times\n const startTime = rawSpan.startTime || [0, 0];\n const endTime = rawSpan.endTime || rawSpan.startTime || [0, 0];\n\n // Calculate duration in milliseconds\n const startMs = timeValueToMillis(startTime);\n const endMs = timeValueToMillis(endTime);\n const duration = endMs - startMs;\n\n // Extract attributes\n const attributes = rawSpan.attributes || {};\n\n // Extract events\n const events: SpanEvent[] = (rawSpan.events || []).map((evt: any) => ({\n name: evt.name || 'unknown',\n time: evt.time || [0, 0],\n timestamp: evt.timestamp || timeValueToISO(evt.time || [0, 0]),\n attributes: evt.attributes || {},\n }));\n\n // Determine status\n const status = rawSpan.status?.code === 2 ? 'error' : 'ok';\n\n return {\n traceId,\n spanId,\n parentSpanId,\n name,\n startTime,\n endTime,\n duration,\n attributes,\n events,\n status,\n };\n}\n\n// ============================================================================\n// Execution Tree Builder\n// ============================================================================\n\n/**\n * Build hierarchical execution tree from flat list of spans\n *\n * @param spans - List of processed spans\n * @returns Root execution node with children\n */\nexport function buildExecutionTree(spans: ProcessedSpan[]): ExecutionNode {\n // Create map of spanId -> ExecutionNode\n const nodeMap = new Map<string, ExecutionNode>();\n\n // First pass: create all nodes\n for (const span of spans) {\n const node = createExecutionNode(span);\n nodeMap.set(span.spanId, node);\n }\n\n // Second pass: build parent-child relationships\n let rootNode: ExecutionNode | undefined;\n const orphans: ExecutionNode[] = [];\n\n for (const span of spans) {\n const node = nodeMap.get(span.spanId)!;\n\n if (!span.parentSpanId) {\n // This is the root node (visor.run)\n rootNode = node;\n } else {\n // Find parent and add as child\n const parent = nodeMap.get(span.parentSpanId);\n if (parent) {\n parent.children.push(node);\n } else {\n // Orphaned span — parent not in this trace; attach to root later\n orphans.push(node);\n }\n }\n }\n\n if (!rootNode) {\n // No root found, create synthetic root\n console.warn('[trace-reader] No root span found, creating synthetic root');\n rootNode = {\n checkId: 'synthetic-root',\n type: 'run',\n status: 'completed',\n children: Array.from(nodeMap.values()).filter(n => !n.span.parentSpanId),\n span: spans[0], // Use first span as placeholder\n state: {},\n };\n }\n\n // Attach orphaned spans (e.g. probe-internal spans whose parent is outside\n // this trace) to the root so they appear in the visualization.\n if (orphans.length > 0 && rootNode) {\n rootNode.children.push(...orphans);\n }\n\n return rootNode;\n}\n\n/**\n * Create execution node from span\n */\nfunction createExecutionNode(span: ProcessedSpan): ExecutionNode {\n const attrs = span.attributes;\n\n // Extract check ID\n const checkId = attrs['visor.check.id'] || attrs['visor.run.id'] || span.spanId;\n\n // Determine type\n let type = 'unknown';\n if (span.name === 'visor.run') {\n type = 'run';\n } else if (span.name === 'visor.check') {\n type = 'check';\n } else if (span.name.startsWith('visor.provider.')) {\n type = 'provider';\n }\n\n // Determine status\n let status: ExecutionNode['status'] = 'completed';\n if (span.status === 'error') {\n status = 'error';\n } else if (attrs['visor.check.skipped'] === true) {\n status = 'skipped';\n }\n\n // Extract state\n const state: ExecutionNode['state'] = {};\n\n // Input context\n if (attrs['visor.check.input.context']) {\n try {\n state.inputContext = JSON.parse(attrs['visor.check.input.context']);\n } catch {\n state.inputContext = attrs['visor.check.input.context'];\n }\n }\n\n // Output\n if (attrs['visor.check.output']) {\n try {\n state.output = JSON.parse(attrs['visor.check.output']);\n } catch {\n state.output = attrs['visor.check.output'];\n }\n }\n\n // Errors\n if (span.status === 'error' || attrs['visor.check.error']) {\n state.errors = [attrs['visor.check.error'] || 'Unknown error'];\n }\n\n // Additional metadata\n state.metadata = {\n type: attrs['visor.check.type'],\n duration: span.duration,\n provider: attrs['visor.provider.type'],\n };\n\n return {\n checkId,\n type,\n status,\n children: [],\n span,\n state,\n };\n}\n\n// ============================================================================\n// State Snapshot Extractor\n// ============================================================================\n\n/**\n * Extract state snapshots from spans for time-travel debugging\n *\n * @param spans - List of processed spans\n * @returns Array of state snapshots sorted by timestamp\n */\nexport function extractStateSnapshots(spans: ProcessedSpan[]): StateSnapshot[] {\n const snapshots: StateSnapshot[] = [];\n\n for (const span of spans) {\n // Find state.snapshot events\n for (const event of span.events) {\n if (event.name === 'state.snapshot') {\n const attrs = event.attributes || {};\n\n const snapshot: StateSnapshot = {\n checkId:\n attrs['visor.snapshot.check_id'] || span.attributes['visor.check.id'] || 'unknown',\n timestamp:\n attrs['visor.snapshot.timestamp'] || event.timestamp || timeValueToISO(event.time),\n timestampNanos: event.time,\n outputs: parseJSON(attrs['visor.snapshot.outputs'], {}),\n memory: parseJSON(attrs['visor.snapshot.memory'], {}),\n };\n\n snapshots.push(snapshot);\n }\n }\n }\n\n // Sort by timestamp\n snapshots.sort((a, b) => compareTimeValues(a.timestampNanos, b.timestampNanos));\n\n return snapshots;\n}\n\n// ============================================================================\n// Timeline Generator\n// ============================================================================\n\n/**\n * Compute chronological timeline of execution events\n *\n * @param spans - List of processed spans\n * @returns Array of timeline events sorted chronologically\n */\nexport function computeTimeline(spans: ProcessedSpan[]): TimelineEvent[] {\n const events: TimelineEvent[] = [];\n\n for (const span of spans) {\n const checkId = span.attributes['visor.check.id'] || span.spanId;\n\n // Check started event\n events.push({\n type: 'check.started',\n checkId,\n timestamp: timeValueToISO(span.startTime),\n timestampNanos: span.startTime,\n metadata: {\n name: span.name,\n type: span.attributes['visor.check.type'],\n },\n });\n\n // Check completed/failed event\n events.push({\n type: span.status === 'error' ? 'check.failed' : 'check.completed',\n checkId,\n timestamp: timeValueToISO(span.endTime),\n timestampNanos: span.endTime,\n duration: span.duration,\n status: span.status,\n metadata: {\n name: span.name,\n },\n });\n\n // Add span events (state.snapshot, etc.)\n for (const evt of span.events) {\n events.push({\n type: evt.name === 'state.snapshot' ? 'state.snapshot' : 'event',\n checkId: evt.attributes?.['visor.snapshot.check_id'] || checkId,\n timestamp: evt.timestamp || timeValueToISO(evt.time),\n timestampNanos: evt.time,\n metadata: {\n eventName: evt.name,\n attributes: evt.attributes,\n },\n });\n }\n }\n\n // Sort chronologically\n events.sort((a, b) => compareTimeValues(a.timestampNanos, b.timestampNanos));\n\n return events;\n}\n\n// ============================================================================\n// Utility Functions\n// ============================================================================\n\n/**\n * Convert OTEL time value [seconds, nanoseconds] to milliseconds\n */\nfunction timeValueToMillis(timeValue: [number, number]): number {\n const [seconds, nanos] = timeValue;\n return seconds * 1000 + nanos / 1_000_000;\n}\n\n/**\n * Convert OTEL time value to ISO timestamp string\n */\nfunction timeValueToISO(timeValue: [number, number]): string {\n const millis = timeValueToMillis(timeValue);\n return new Date(millis).toISOString();\n}\n\n/**\n * Compare two time values for sorting\n * Returns: -1 if a < b, 0 if a === b, 1 if a > b\n */\nfunction compareTimeValues(a: [number, number], b: [number, number]): number {\n if (a[0] !== b[0]) {\n return a[0] - b[0];\n }\n return a[1] - b[1];\n}\n\n/**\n * Safely parse JSON string, return default on error\n */\nfunction parseJSON<T>(value: any, defaultValue: T): T {\n if (typeof value !== 'string') {\n return defaultValue;\n }\n\n try {\n return JSON.parse(value);\n } catch {\n return defaultValue;\n }\n}\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/agent-protocol/track-execution.ts"],"sourcesContent":["/**\n * Shared execution tracking helper.\n *\n * Wraps any engine execution call with task lifecycle management:\n * creates a task in 'submitted' state, transitions to 'working',\n * runs the executor, then sets terminal state (completed/failed).\n *\n * Used by CLI, Slack, TUI, and Scheduler frontends when task_tracking is enabled.\n */\n\nimport crypto from 'crypto';\nimport fs from 'fs';\nimport path from 'path';\nimport { logger } from '../logger';\nimport { trace } from '../telemetry/lazy-otel';\nimport { getInstanceId } from '../utils/instance-id';\nimport type { TaskLiveUpdatesConfig } from '../types/config';\nimport type { TaskStore } from './task-store';\nimport type { AgentMessage, AgentTask } from './types';\nimport {\n resolveTaskLiveUpdatesConfig,\n TaskLiveUpdateManager,\n type TaskLiveUpdateSink,\n} from './task-live-updates';\nimport { resolveTaskTraceReference } from './task-trace-resolution';\n\nfunction getPackageVersion(): string {\n try {\n return require('../../package.json')?.version || 'dev';\n } catch {\n return 'dev';\n }\n}\n\nasync function readTraceIdFromFallbackFile(traceFile?: string): Promise<string | undefined> {\n if (!traceFile || !fs.existsSync(traceFile)) return undefined;\n\n try {\n const { readTraceIdFromFile } = await import('./trace-serializer');\n return (await readTraceIdFromFile(traceFile)) || undefined;\n } catch {\n return undefined;\n }\n}\n\nexport type TaskSource =\n | 'cli'\n | 'slack'\n | 'telegram'\n | 'email'\n | 'whatsapp'\n | 'teams'\n | 'a2a'\n | 'mcp'\n | 'tui'\n | 'scheduler'\n | 'webhook'\n | 'test';\n\nexport interface TrackExecutionOptions {\n taskStore: TaskStore;\n source: TaskSource;\n workflowId?: string;\n /** Config file path — used to prefix workflowId as \"config.yaml#workflow\" */\n configPath?: string;\n metadata?: Record<string, unknown>;\n /** Human-readable description of what's being executed */\n messageText: string;\n /** Run LLM evaluation after task completion (non-blocking). */\n autoEvaluate?: boolean;\n /** Optional live progress updates for supported interactive frontends. */\n liveUpdates?: {\n config?: boolean | TaskLiveUpdatesConfig;\n sink?: TaskLiveUpdateSink;\n includeTraceId?: boolean;\n };\n}\n\n/**\n * Wrap an engine execution call with task lifecycle tracking.\n *\n * Creates a task, transitions to 'working', runs the executor,\n * then sets terminal state. Returns both the task and the original result.\n * Re-throws any executor error after marking the task as failed.\n */\nexport async function trackExecution<T>(\n opts: TrackExecutionOptions,\n executor: () => Promise<T>\n): Promise<{ task: AgentTask; result: T }> {\n const { taskStore, source, configPath, metadata, messageText } = opts;\n const configName = configPath ? path.basename(configPath, path.extname(configPath)) : undefined;\n const workflowId =\n configName && opts.workflowId ? `${configName}#${opts.workflowId}` : opts.workflowId;\n\n const requestMessage: AgentMessage = {\n message_id: crypto.randomUUID(),\n role: 'user',\n parts: [{ text: messageText }],\n };\n\n // Capture trace file path if telemetry is writing to a file\n const traceFile = process.env.VISOR_FALLBACK_TRACE_FILE || undefined;\n\n const task = taskStore.createTask({\n contextId: crypto.randomUUID(),\n requestMessage,\n workflowId,\n requestMetadata: {\n source,\n instance_id: getInstanceId(),\n visor_version: process.env.VISOR_VERSION || getPackageVersion(),\n ...(process.env.VISOR_COMMIT_SHORT ? { visor_commit: process.env.VISOR_COMMIT_SHORT } : {}),\n trace_id: trace.getActiveSpan()?.spanContext().traceId || undefined,\n ...(traceFile ? { trace_file: traceFile } : {}),\n ...metadata,\n },\n });\n\n const instanceId = getInstanceId();\n return await logger.withTaskContext(task.id, async () => {\n taskStore.updateTaskState(task.id, 'working');\n taskStore.claimTask(task.id, instanceId);\n logger.info(\n `[TaskTracking] Task ${task.id} started (source=${source}, workflow=${workflowId || '-'}, instance=${instanceId})`\n );\n\n const liveUpdateConfig = resolveTaskLiveUpdatesConfig(opts.liveUpdates?.config);\n const initialTraceId =\n trace.getActiveSpan()?.spanContext().traceId ||\n (task.metadata?.trace_id as string | undefined);\n if (initialTraceId && !task.metadata?.trace_id) {\n try {\n taskStore.updateMetadata(task.id, { trace_id: initialTraceId });\n } catch {\n // best-effort only\n }\n }\n const initialResolvedTrace = await resolveTaskTraceReference({\n trace_id: initialTraceId || (task.metadata?.trace_id as string | undefined),\n trace_file: task.metadata?.trace_file as string | undefined,\n });\n const liveUpdateManager =\n liveUpdateConfig && opts.liveUpdates?.sink\n ? new TaskLiveUpdateManager({\n taskId: task.id,\n requestText: messageText,\n traceRef: initialResolvedTrace.primaryRef,\n traceId: initialResolvedTrace.traceId,\n includeTraceId: opts.liveUpdates?.includeTraceId === true,\n sink: opts.liveUpdates.sink,\n config: liveUpdateConfig,\n resolveTraceState: () => {\n let current;\n try {\n current = taskStore.getTask(task.id);\n } catch {\n return {\n traceRef: initialResolvedTrace.primaryRef,\n traceId: initialResolvedTrace.traceId,\n };\n }\n return {\n traceRef:\n (current?.metadata?.trace_id as string | undefined) ||\n (current?.metadata?.trace_file as string | undefined) ||\n initialResolvedTrace.primaryRef,\n traceId: current?.metadata?.trace_id as string | undefined,\n };\n },\n onPostedRef: ref => {\n try {\n taskStore.updateMetadata(task.id, ref);\n } catch {\n // best-effort only\n }\n },\n appendHistory: (text, stage) => {\n try {\n taskStore.appendHistory(task.id, {\n message_id: crypto.randomUUID(),\n role: 'agent',\n parts: [{ text }],\n metadata: { kind: 'task_live_update', stage, source },\n });\n } catch {\n // best-effort only\n }\n },\n })\n : null;\n if (liveUpdateConfig && !opts.liveUpdates?.sink) {\n logger.debug(\n `[TaskTracking] Live updates requested for task ${task.id} but no sink is available for source=${source}`\n );\n } else if (liveUpdateManager) {\n logger.info(`[TaskTracking] Live updates enabled for task ${task.id} (source=${source})`);\n }\n\n // Heartbeat: periodically touch updated_at so stale-task detection\n // can distinguish live tasks from orphans (works across nodes).\n const HEARTBEAT_INTERVAL = 60_000; // 1 minute\n const heartbeatTimer = setInterval(() => {\n try {\n taskStore.heartbeat(task.id);\n } catch {\n // best-effort — don't crash the task over a heartbeat failure\n }\n }, HEARTBEAT_INTERVAL);\n\n try {\n if (liveUpdateManager) {\n await liveUpdateManager.start();\n }\n const result = await executor();\n\n // Now that execution is done, capture the trace ID from the active span.\n // At task creation time the span may not have been active yet, so we\n // update metadata post-execution to ensure trace_id is stored.\n try {\n const activeTraceId = trace.getActiveSpan()?.spanContext().traceId;\n const persistedTraceId =\n (activeTraceId && activeTraceId !== '' ? activeTraceId : undefined) ||\n (await readTraceIdFromFallbackFile(traceFile));\n if (persistedTraceId && !task.metadata?.trace_id) {\n taskStore.updateMetadata(task.id, { trace_id: persistedTraceId });\n }\n } catch {\n // best-effort — don't fail the task over metadata\n }\n\n // Extract AI response text from the result.\n // result.reviewSummary.history is keyed by checkId with arrays of outputs.\n // We want the LAST check's text output (the final AI response), not the\n // first (which is typically the intent router).\n let responseText = 'Execution completed';\n try {\n const history = (result as any)?.reviewSummary?.history as\n | Record<string, unknown[]>\n | undefined;\n if (history) {\n const entries = Object.values(history);\n // Iterate in reverse — last check output is the final response\n for (let i = entries.length - 1; i >= 0; i--) {\n const outputs = entries[i];\n if (!Array.isArray(outputs)) continue;\n // Within a check, look at the last output first too\n for (let j = outputs.length - 1; j >= 0; j--) {\n const text = (outputs[j] as any)?.text;\n if (typeof text === 'string' && text.trim().length > 0) {\n responseText = text.trim();\n break;\n }\n }\n if (responseText !== 'Execution completed') break;\n }\n }\n } catch {\n // ignore extraction errors\n }\n\n const completedMsg: AgentMessage = {\n message_id: crypto.randomUUID(),\n role: 'agent',\n parts: [{ text: responseText }],\n };\n try {\n taskStore.updateTaskState(task.id, 'completed', completedMsg);\n logger.info(`[TaskTracking] Task ${task.id} completed`);\n } catch (stateErr) {\n // Another process (e.g. stale sweep) may have already marked this task as failed.\n // Log a warning but do NOT re-throw — the execution itself succeeded.\n logger.warn(\n `[TaskTracking] Task ${task.id} completed but state transition failed: ${stateErr instanceof Error ? stateErr.message : stateErr}`\n );\n }\n\n // Fire-and-forget LLM evaluation (non-blocking)\n // Enabled via opts.autoEvaluate (from config.task_evaluate) or VISOR_TASK_EVALUATE env var\n if (opts.autoEvaluate || process.env.VISOR_TASK_EVALUATE === 'true') {\n scheduleEvaluation(task.id, taskStore);\n }\n\n if (liveUpdateManager) {\n await liveUpdateManager.complete(responseText);\n }\n\n return { task, result };\n } catch (err) {\n const errorText = err instanceof Error ? err.message : String(err);\n const failMessage: AgentMessage = {\n message_id: crypto.randomUUID(),\n role: 'agent',\n parts: [{ text: errorText }],\n };\n try {\n taskStore.updateTaskState(task.id, 'failed', failMessage);\n logger.info(`[TaskTracking] Task ${task.id} failed: ${errorText}`);\n } catch {\n // ignore double-failure\n }\n if (liveUpdateManager) {\n await liveUpdateManager.fail(`:warning: ${errorText}`);\n }\n throw err; // re-throw to preserve original behavior\n } finally {\n clearInterval(heartbeatTimer);\n liveUpdateManager?.stop();\n }\n });\n}\n\n// ---------------------------------------------------------------------------\n// Non-blocking auto-evaluation\n// ---------------------------------------------------------------------------\n\nfunction scheduleEvaluation(taskId: string, taskStore: TaskStore): void {\n // Delay slightly to let OTEL spans flush before we try to read the trace\n setTimeout(async () => {\n await logger.withTaskContext(taskId, async () => {\n try {\n const { evaluateAndStore } = await import('./task-evaluator');\n await evaluateAndStore(taskId, taskStore as any);\n logger.info(`[TaskEvaluator] Auto-evaluation completed for task ${taskId}`);\n } catch (err) {\n logger.warn(\n `[TaskEvaluator] Auto-evaluation failed for task ${taskId}: ${err instanceof Error ? err.message : err}`\n );\n }\n });\n }, 5000);\n}\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/whatsapp/markdown.ts","../../src/whatsapp/client.ts","../../src/frontends/whatsapp-frontend.ts"],"sourcesContent":["// Lightweight Markdown → WhatsApp formatter.\n// Converts common Markdown output from AI steps to WhatsApp-compatible text.\n//\n// Supported conversions:\n// - # Header / ## Header → *Header* (bold, no header support)\n// - **bold** / __bold__ → *bold*\n// - *italic* → _italic_\n// - ~~strike~~ → ~strike~\n// - `code` → ```code```\n// - ```block``` → ```block``` (preserved)\n// - [label](url) → label (url)\n// - > blockquote → > blockquote (preserved, WhatsApp renders this)\n//\n// WhatsApp text messages have a 4096 character limit.\n\n/**\n * Convert Markdown text to WhatsApp-compatible format.\n * Processes line-by-line, respecting fenced code blocks.\n */\nexport function markdownToWhatsApp(text: string): string {\n if (!text || typeof text !== 'string') return '';\n\n const lines = text.split(/\\r?\\n/);\n const result: string[] = [];\n let inCodeBlock = false;\n let codeLines: string[] = [];\n\n for (let i = 0; i < lines.length; i++) {\n const trimmed = lines[i].trimStart();\n\n // Track fenced code blocks\n if (/^```/.test(trimmed)) {\n if (!inCodeBlock) {\n inCodeBlock = true;\n codeLines = [];\n } else {\n // Close code block\n result.push('```' + codeLines.join('\\n') + '```');\n inCodeBlock = false;\n codeLines = [];\n }\n continue;\n }\n if (inCodeBlock) {\n codeLines.push(lines[i]);\n continue;\n }\n\n const line = lines[i];\n\n // Headers: # Header → *Header* (bold)\n const headerMatch = /^(#{1,6})\\s+(.+)$/.exec(line.trimStart());\n if (headerMatch) {\n result.push(`*${convertInline(headerMatch[2].trim())}*`);\n continue;\n }\n\n // Horizontal rules\n if (/^[-*_]{3,}\\s*$/.test(trimmed)) {\n result.push('---');\n continue;\n }\n\n // Bullet lists: \"- item\" or \"* item\" preserved\n const bulletMatch = /^(\\s*)([-*])\\s+(.+)$/.exec(line);\n if (bulletMatch) {\n result.push(`${bulletMatch[1]}- ${convertInline(bulletMatch[3])}`);\n continue;\n }\n\n // Numbered lists: preserve as-is but convert inline\n const numMatch = /^(\\s*)(\\d+\\.)\\s+(.+)$/.exec(line);\n if (numMatch) {\n result.push(`${numMatch[1]}${numMatch[2]} ${convertInline(numMatch[3])}`);\n continue;\n }\n\n // Blockquotes: > text — preserved (WhatsApp renders these)\n const bqMatch = /^>\\s?(.*)$/.exec(trimmed);\n if (bqMatch) {\n result.push(`> ${convertInline(bqMatch[1])}`);\n continue;\n }\n\n // Regular line: apply inline conversions\n result.push(convertInline(line));\n }\n\n // Close any unclosed code block\n if (inCodeBlock && codeLines.length > 0) {\n result.push('```' + codeLines.join('\\n') + '```');\n }\n\n return result.join('\\n');\n}\n\n/**\n * Apply inline Markdown conversions to a single line.\n */\nfunction convertInline(line: string): string {\n // First, identify and protect inline code spans\n const codeSpans: string[] = [];\n let processed = line.replace(/`([^`]+)`/g, (_m, code: string) => {\n const idx = codeSpans.length;\n codeSpans.push('```' + code + '```');\n return `\\x00CODE${idx}\\x00`;\n });\n\n // Images: ![alt](url) → alt (url)\n processed = processed.replace(\n /!\\[([^\\]]*)\\]\\(([^)\\s]+)(?:\\s+\"[^\"]*\")?\\)/g,\n (_m, alt: string, url: string) => `${alt || 'image'} (${url})`\n );\n\n // Links: [label](url) → label (url)\n processed = processed.replace(\n /\\[([^\\]]+)\\]\\(([^)\\s]+)(?:\\s+\"[^\"]*\")?\\)/g,\n (_m, label: string, url: string) => `${label} (${url})`\n );\n\n // Bold: **text** or __text__ → *text* (protect with placeholders first)\n const boldSpans: string[] = [];\n processed = processed.replace(/\\*\\*([^*]+)\\*\\*/g, (_m, content: string) => {\n const idx = boldSpans.length;\n boldSpans.push(`*${content}*`);\n return `\\x00BOLD${idx}\\x00`;\n });\n processed = processed.replace(/__([^_]+)__/g, (_m, content: string) => {\n const idx = boldSpans.length;\n boldSpans.push(`*${content}*`);\n return `\\x00BOLD${idx}\\x00`;\n });\n\n // Italic: *text* → _text_ (bold already protected)\n processed = processed.replace(/(?<!\\*)\\*([^*]+)\\*(?!\\*)/g, '_$1_');\n\n // Strikethrough: ~~text~~ → ~text~\n processed = processed.replace(/~~([^~]+)~~/g, '~$1~');\n\n // Restore bold spans\n processed = processed.replace(\n /\\x00BOLD(\\d+)\\x00/g,\n (_m, idx: string) => boldSpans[parseInt(idx)]\n );\n\n // Restore code spans\n processed = processed.replace(\n /\\x00CODE(\\d+)\\x00/g,\n (_m, idx: string) => codeSpans[parseInt(idx)]\n );\n\n return processed;\n}\n\n/**\n * Chunk text into segments no larger than limit, splitting at newlines.\n */\nexport function chunkText(text: string, limit: number = 4096): string[] {\n if (text.length <= limit) return [text];\n\n const chunks: string[] = [];\n const lines = text.split('\\n');\n let current = '';\n\n for (const line of lines) {\n const candidate = current ? current + '\\n' + line : line;\n if (candidate.length > limit) {\n if (current) {\n chunks.push(current);\n current = line;\n } else {\n // Single line exceeds limit — force split\n let remaining = line;\n while (remaining.length > limit) {\n chunks.push(remaining.slice(0, limit));\n remaining = remaining.slice(limit);\n }\n current = remaining;\n }\n } else {\n current = candidate;\n }\n }\n if (current) chunks.push(current);\n\n return chunks;\n}\n\n/**\n * Main entry point: convert Markdown to WhatsApp format.\n */\nexport function formatWhatsAppText(text: string): string {\n return markdownToWhatsApp(text);\n}\n","// WhatsApp Cloud API client.\n// Wraps Graph API calls behind a clean interface.\n// Uses fetch directly (no npm dependency — Meta's official SDK is archived).\n\nimport { createHmac } from 'crypto';\nimport { chunkText } from './markdown';\n\nexport interface WhatsAppSendResult {\n ok: boolean;\n messageId?: string; // wamid.* format\n error?: string;\n}\n\nexport interface WhatsAppMessageStatus {\n ok: boolean;\n error?: string;\n}\n\nexport interface WhatsAppClientOptions {\n accessToken: string;\n phoneNumberId: string;\n appSecret?: string;\n verifyToken?: string;\n apiVersion?: string; // default 'v21.0'\n}\n\nexport class WhatsAppClient {\n private accessToken: string;\n private phoneNumberId: string;\n private appSecret?: string;\n private verifyToken?: string;\n private baseUrl: string;\n\n constructor(opts: WhatsAppClientOptions) {\n if (!opts.accessToken || typeof opts.accessToken !== 'string') {\n throw new Error('WhatsAppClient: accessToken is required');\n }\n if (!opts.phoneNumberId || typeof opts.phoneNumberId !== 'string') {\n throw new Error('WhatsAppClient: phoneNumberId is required');\n }\n this.accessToken = opts.accessToken;\n this.phoneNumberId = opts.phoneNumberId;\n this.appSecret = opts.appSecret;\n this.verifyToken = opts.verifyToken;\n const version = opts.apiVersion || 'v21.0';\n this.baseUrl = `https://graph.facebook.com/${version}/${this.phoneNumberId}`;\n }\n\n /** Get the Phone Number ID */\n getPhoneNumberId(): string {\n return this.phoneNumberId;\n }\n\n /**\n * Send a text message. Auto-chunks at 4096 characters.\n */\n async sendMessage(opts: {\n to: string;\n text: string;\n replyToMessageId?: string;\n }): Promise<WhatsAppSendResult> {\n const chunks = chunkText(opts.text, 4096);\n let lastResult: WhatsAppSendResult = { ok: false, error: 'No chunks to send' };\n\n for (const chunk of chunks) {\n const body: any = {\n messaging_product: 'whatsapp',\n to: opts.to,\n type: 'text',\n text: { body: chunk },\n };\n\n // Add quoted reply context\n if (opts.replyToMessageId) {\n body.context = { message_id: opts.replyToMessageId };\n }\n\n try {\n const resp = await fetch(`${this.baseUrl}/messages`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${this.accessToken}`,\n },\n body: JSON.stringify(body),\n });\n\n const data = await resp.json();\n\n if (!resp.ok) {\n const errMsg = (data as any)?.error?.message || `HTTP ${resp.status}`;\n return { ok: false, error: errMsg };\n }\n\n const msgId = (data as any)?.messages?.[0]?.id;\n lastResult = { ok: true, messageId: msgId };\n } catch (err) {\n return {\n ok: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n }\n\n return lastResult;\n }\n\n /**\n * Mark a message as read (send read receipt).\n */\n async markAsRead(messageId: string): Promise<WhatsAppMessageStatus> {\n try {\n const resp = await fetch(`${this.baseUrl}/messages`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${this.accessToken}`,\n },\n body: JSON.stringify({\n messaging_product: 'whatsapp',\n status: 'read',\n message_id: messageId,\n }),\n });\n\n if (!resp.ok) {\n const data = await resp.json();\n return {\n ok: false,\n error: (data as any)?.error?.message || `HTTP ${resp.status}`,\n };\n }\n\n return { ok: true };\n } catch (err) {\n return {\n ok: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n }\n\n /**\n * Verify webhook signature (HMAC-SHA256 with X-Hub-Signature-256).\n * Returns true if valid or if no appSecret is configured (skip verification).\n */\n verifyWebhookSignature(rawBody: string, signatureHeader: string): boolean {\n if (!this.appSecret) return true; // no secret = skip verification\n if (!signatureHeader) return false;\n\n const expected = 'sha256=' + createHmac('sha256', this.appSecret).update(rawBody).digest('hex');\n\n return signatureHeader === expected;\n }\n\n /**\n * Verify GET challenge-response for webhook subscription.\n */\n verifyChallenge(params: Record<string, string>): {\n ok: boolean;\n challenge?: string;\n } {\n const mode = params['hub.mode'];\n const token = params['hub.verify_token'];\n const challenge = params['hub.challenge'];\n\n if (mode === 'subscribe' && token === this.verifyToken) {\n return { ok: true, challenge };\n }\n\n return { ok: false };\n }\n}\n","/**\n * WhatsApp Frontend for Visor workflows.\n *\n * Mirrors the TelegramFrontend pattern:\n * - Sends AI replies as WhatsApp text messages\n * - Converts Markdown to WhatsApp format\n * - No reaction equivalent (CheckScheduled is a no-op)\n */\nimport type { Frontend, FrontendContext } from './host';\nimport { WhatsAppClient } from '../whatsapp/client';\nimport { formatWhatsAppText } from '../whatsapp/markdown';\n\ntype WhatsAppFrontendConfig = {\n accessToken?: string;\n phoneNumberId?: string;\n};\n\nexport class WhatsAppFrontend implements Frontend {\n public readonly name = 'whatsapp';\n private subs: Array<{ unsubscribe(): void }> = [];\n private cfg: WhatsAppFrontendConfig;\n private errorNotified: boolean = false;\n\n constructor(config?: WhatsAppFrontendConfig) {\n this.cfg = config || {};\n }\n\n start(ctx: FrontendContext): void {\n const bus = ctx.eventBus;\n\n try {\n ctx.logger.info(`[whatsapp-frontend] started`);\n } catch {}\n\n // CheckCompleted: post AI replies\n this.subs.push(\n bus.on('CheckCompleted', async (env: any) => {\n const ev = (env && env.payload) || env;\n await this.maybePostDirectReply(ctx, ev.checkId, ev.result).catch(() => {});\n })\n );\n\n // CheckErrored: post error notice\n this.subs.push(\n bus.on('CheckErrored', async (env: any) => {\n const ev = (env && env.payload) || env;\n const message = ev?.error?.message || 'Execution error';\n await this.maybePostError(ctx, 'Check failed', message, ev?.checkId).catch(() => {});\n })\n );\n\n // Shutdown: post error\n this.subs.push(\n bus.on('Shutdown', async (env: any) => {\n const ev = (env && env.payload) || env;\n const message = ev?.error?.message || 'Fatal error';\n await this.maybePostError(ctx, 'Run failed', message).catch(() => {});\n })\n );\n\n // CheckScheduled: no-op (WhatsApp has no reaction equivalent)\n // StateTransition: no-op\n }\n\n stop(): void {\n for (const s of this.subs) s.unsubscribe();\n this.subs = [];\n }\n\n private getWhatsApp(ctx: FrontendContext): WhatsAppClient | undefined {\n // Prefer injected client (for tests or shared runner context)\n const injected = (ctx as any).whatsapp || (ctx as any).whatsappClient;\n if (injected) return injected;\n // Lazy-create from env or frontend config\n try {\n const token = this.cfg.accessToken || process.env.WHATSAPP_ACCESS_TOKEN;\n const phoneId = this.cfg.phoneNumberId || process.env.WHATSAPP_PHONE_NUMBER_ID;\n if (\n typeof token === 'string' &&\n token.trim() &&\n typeof phoneId === 'string' &&\n phoneId.trim()\n ) {\n return new WhatsAppClient({\n accessToken: token.trim(),\n phoneNumberId: phoneId.trim(),\n });\n }\n } catch {}\n return undefined;\n }\n\n private getInboundWhatsAppPayload(ctx: FrontendContext): any | null {\n try {\n const endpoint = '/bots/whatsapp/message';\n return (ctx as any).webhookContext?.webhookData?.get(endpoint) || null;\n } catch {\n return null;\n }\n }\n\n private async maybePostError(\n ctx: FrontendContext,\n title: string,\n message: string,\n checkId?: string\n ): Promise<void> {\n if (this.errorNotified) return;\n const whatsapp = this.getWhatsApp(ctx);\n if (!whatsapp) return;\n const payload = this.getInboundWhatsAppPayload(ctx);\n const ev: any = payload?.event;\n const from = ev?.from;\n if (!from) return;\n\n let text = `${title}`;\n if (checkId) text += `\\nCheck: ${checkId}`;\n if (message) text += `\\n${message}`;\n\n await whatsapp.sendMessage({\n to: from,\n text,\n replyToMessageId: ev?.message_id,\n });\n this.errorNotified = true;\n }\n\n private async maybePostDirectReply(\n ctx: FrontendContext,\n checkId: string,\n result: { output?: any; content?: string }\n ): Promise<void> {\n try {\n const cfg: any = ctx.config || {};\n const checkCfg: any = cfg.checks?.[checkId];\n if (!checkCfg) return;\n\n const providerType = (checkCfg.type as string) || '';\n const isAi = providerType === 'ai';\n const isLogChat = providerType === 'log' && checkCfg.group === 'chat';\n const isWorkflow = providerType === 'workflow';\n if (!isAi && !isLogChat && !isWorkflow) return;\n if (checkCfg.criticality === 'internal') return;\n\n // For AI checks, only post simple schemas\n if (isAi) {\n const schema = checkCfg.schema;\n if (typeof schema === 'string') {\n const simpleSchemas = ['code-review', 'markdown', 'text', 'plain'];\n if (!simpleSchemas.includes(schema)) return;\n }\n }\n\n const whatsapp = this.getWhatsApp(ctx);\n if (!whatsapp) return;\n\n const payload = this.getInboundWhatsAppPayload(ctx);\n const ev: any = payload?.event;\n const from = ev?.from;\n if (!from) {\n ctx.logger.warn(\n `[whatsapp-frontend] skip posting reply for ${checkId}: missing from number`\n );\n return;\n }\n\n // Extract text (same logic as Telegram/Email/Slack frontends)\n const out: any = (result as any)?.output;\n let text: string | undefined;\n if (out && typeof out.text === 'string' && out.text.trim().length > 0) {\n text = out.text.trim();\n } else if (isAi && typeof checkCfg.schema === 'string') {\n if (\n typeof (result as any)?.content === 'string' &&\n (result as any).content.trim().length > 0\n ) {\n text = (result as any).content.trim();\n }\n } else if (isLogChat && typeof (result as any)?.logOutput === 'string') {\n const raw = (result as any).logOutput;\n if (raw.trim().length > 0) text = raw.trim();\n }\n\n // Append raw output\n if (out && typeof out._rawOutput === 'string' && out._rawOutput.trim().length > 0) {\n text = (text || '') + '\\n\\n' + out._rawOutput.trim();\n }\n\n if (!text) {\n ctx.logger.info(\n `[whatsapp-frontend] skip posting reply for ${checkId}: no renderable text`\n );\n return;\n }\n\n // Normalize literal \\n escape sequences\n text = text.replace(/\\\\n/g, '\\n');\n\n const formattedText = formatWhatsAppText(text);\n const postResult = await whatsapp.sendMessage({\n to: from,\n text: formattedText,\n replyToMessageId: ev?.message_id,\n });\n\n if (!postResult.ok) {\n ctx.logger.warn(\n `[whatsapp-frontend] failed to post reply for ${checkId}: ${postResult.error}`\n );\n return;\n }\n ctx.logger.info(\n `[whatsapp-frontend] posted reply for ${checkId} to ${from} (messageId=${postResult.messageId})`\n );\n } catch (err) {\n try {\n ctx.logger.warn(\n `[whatsapp-frontend] maybePostDirectReply failed for ${checkId}: ${\n err instanceof Error ? err.message : String(err)\n }`\n );\n } catch {}\n }\n }\n}\n"],"mappings":"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","names":[]}