@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.
- package/defaults/assistant.yaml +31 -0
- package/defaults/code-talk.yaml +32 -0
- package/defaults/skills/code-explorer.yaml +6 -0
- package/dist/action-cli-bridge.d.ts.map +1 -1
- package/dist/agent-protocol/a2a-frontend.d.ts.map +1 -1
- package/dist/agent-protocol/index.d.ts.map +1 -1
- package/dist/agent-protocol/push-notification-manager.d.ts.map +1 -1
- package/dist/agent-protocol/state-transitions.d.ts.map +1 -1
- package/dist/agent-protocol/task-evaluator.d.ts.map +1 -1
- package/dist/agent-protocol/task-live-update-slack.d.ts +10 -0
- package/dist/agent-protocol/task-live-update-slack.d.ts.map +1 -1
- package/dist/agent-protocol/task-live-update-teams.d.ts.map +1 -1
- package/dist/agent-protocol/task-live-update-telegram.d.ts.map +1 -1
- package/dist/agent-protocol/task-live-updates.d.ts +10 -0
- package/dist/agent-protocol/task-live-updates.d.ts.map +1 -1
- package/dist/agent-protocol/task-progress-tool.d.ts.map +1 -1
- package/dist/agent-protocol/task-queue.d.ts.map +1 -1
- package/dist/agent-protocol/task-store.d.ts.map +1 -1
- package/dist/agent-protocol/task-stream-manager.d.ts.map +1 -1
- package/dist/agent-protocol/task-trace-resolution.d.ts.map +1 -1
- package/dist/agent-protocol/tasks-cli-handler.d.ts.map +1 -1
- package/dist/agent-protocol/tasks-tui.d.ts.map +1 -1
- package/dist/agent-protocol/trace-serializer.d.ts +43 -1
- package/dist/agent-protocol/trace-serializer.d.ts.map +1 -1
- package/dist/agent-protocol/track-execution.d.ts.map +1 -1
- package/dist/agent-protocol/types.d.ts.map +1 -1
- package/dist/ai-review-service.d.ts +22 -1
- package/dist/ai-review-service.d.ts.map +1 -1
- package/dist/check-execution-engine.d.ts.map +1 -1
- package/dist/cli-main.d.ts +1 -0
- package/dist/cli-main.d.ts.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/commands.d.ts.map +1 -1
- package/dist/config/cli-handler.d.ts.map +1 -1
- package/dist/config/config-reloader.d.ts.map +1 -1
- package/dist/config/config-snapshot-store.d.ts.map +1 -1
- package/dist/config/config-watcher.d.ts.map +1 -1
- package/dist/config/types.d.ts.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/cron-scheduler.d.ts.map +1 -1
- package/dist/debug-visualizer/debug-span-exporter.d.ts.map +1 -1
- package/dist/debug-visualizer/trace-reader.d.ts.map +1 -1
- package/dist/debug-visualizer/ws-server.d.ts.map +1 -1
- package/dist/defaults/assistant.yaml +31 -0
- package/dist/defaults/code-talk.yaml +32 -0
- package/dist/defaults/skills/code-explorer.yaml +6 -0
- package/dist/dependency-resolver.d.ts.map +1 -1
- package/dist/docs/telemetry-setup.md +18 -2
- package/dist/email/adapter.d.ts.map +1 -1
- package/dist/email/client.d.ts.map +1 -1
- package/dist/email/markdown.d.ts.map +1 -1
- package/dist/email/polling-runner.d.ts +1 -0
- package/dist/email/polling-runner.d.ts.map +1 -1
- package/dist/engine/on-finish/orchestrator.d.ts.map +1 -1
- package/dist/engine/on-finish/utils.d.ts.map +1 -1
- package/dist/event-bus/event-bus.d.ts.map +1 -1
- package/dist/event-bus/types.d.ts.map +1 -1
- package/dist/event-mapper.d.ts.map +1 -1
- package/dist/failure-condition-evaluator.d.ts.map +1 -1
- package/dist/footer.d.ts.map +1 -1
- package/dist/frontends/email-frontend.d.ts.map +1 -1
- package/dist/frontends/github-frontend.d.ts.map +1 -1
- package/dist/frontends/host.d.ts.map +1 -1
- package/dist/frontends/ndjson-sink.d.ts.map +1 -1
- package/dist/frontends/slack-frontend.d.ts.map +1 -1
- package/dist/frontends/teams-frontend.d.ts.map +1 -1
- package/dist/frontends/telegram-frontend.d.ts.map +1 -1
- package/dist/frontends/whatsapp-frontend.d.ts.map +1 -1
- package/dist/generated/config-schema.d.ts +16 -8
- package/dist/generated/config-schema.d.ts.map +1 -1
- package/dist/git-repository-analyzer.d.ts.map +1 -1
- package/dist/github-auth.d.ts.map +1 -1
- package/dist/github-check-service.d.ts.map +1 -1
- package/dist/github-comments.d.ts.map +1 -1
- package/dist/github-reactions.d.ts.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7656 -1458
- package/dist/issue-filter.d.ts.map +1 -1
- package/dist/liquid-extensions.d.ts.map +1 -1
- package/dist/logger.d.ts.map +1 -1
- package/dist/mcp-job-manager.d.ts.map +1 -1
- package/dist/mcp-server.d.ts.map +1 -1
- package/dist/memory-store.d.ts.map +1 -1
- package/dist/output/traces/{run-2026-05-05T12-31-47-571Z.ndjson → run-2026-08-20T13-50-06-218Z.ndjson} +2699 -2699
- package/dist/output-formatters.d.ts.map +1 -1
- package/dist/policy/default-engine.d.ts.map +1 -1
- package/dist/policy/index.d.ts.map +1 -1
- package/dist/policy/policy-check-command.d.ts.map +1 -1
- package/dist/policy/types.d.ts.map +1 -1
- package/dist/pr-analyzer.d.ts.map +1 -1
- package/dist/pr-detector.d.ts.map +1 -1
- package/dist/providers/a2a-check-provider.d.ts.map +1 -1
- package/dist/providers/ai-check-provider.d.ts.map +1 -1
- package/dist/providers/api-tool-executor.d.ts.map +1 -1
- package/dist/providers/check-provider-registry.d.ts.map +1 -1
- package/dist/providers/check-provider.interface.d.ts.map +1 -1
- package/dist/providers/claude-code-check-provider.d.ts.map +1 -1
- package/dist/providers/claude-code-types.d.ts.map +1 -1
- package/dist/providers/command-check-provider.d.ts.map +1 -1
- package/dist/providers/custom-tool-executor.d.ts.map +1 -1
- package/dist/providers/git-checkout-provider.d.ts.map +1 -1
- package/dist/providers/github-ops-provider.d.ts.map +1 -1
- package/dist/providers/http-check-provider.d.ts.map +1 -1
- package/dist/providers/http-client-provider.d.ts.map +1 -1
- package/dist/providers/http-input-provider.d.ts.map +1 -1
- package/dist/providers/human-input-check-provider.d.ts.map +1 -1
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/log-check-provider.d.ts.map +1 -1
- package/dist/providers/mcp-check-provider.d.ts.map +1 -1
- package/dist/providers/mcp-custom-sse-server.d.ts.map +1 -1
- package/dist/providers/mcp-tools.d.ts.map +1 -1
- package/dist/providers/memory-check-provider.d.ts.map +1 -1
- package/dist/providers/noop-check-provider.d.ts.map +1 -1
- package/dist/providers/script-check-provider.d.ts.map +1 -1
- package/dist/providers/utcp-check-provider.d.ts.map +1 -1
- package/dist/providers/workflow-check-provider.d.ts.map +1 -1
- package/dist/providers/workflow-tool-executor.d.ts.map +1 -1
- package/dist/reviewer.d.ts.map +1 -1
- package/dist/runners/config-reload-runtime.d.ts.map +1 -1
- package/dist/runners/graceful-restart.d.ts.map +1 -1
- package/dist/runners/mcp-server-runner.d.ts.map +1 -1
- package/dist/runners/process-cli-handler.d.ts.map +1 -1
- package/dist/runners/process-discovery.d.ts.map +1 -1
- package/dist/runners/runner-factory.d.ts.map +1 -1
- package/dist/runners/runner-host.d.ts.map +1 -1
- package/dist/runners/runner.d.ts.map +1 -1
- package/dist/runners/telemetry-init.d.ts.map +1 -1
- package/dist/sandbox/bubblewrap-sandbox.d.ts.map +1 -1
- package/dist/sandbox/cache-volume-manager.d.ts.map +1 -1
- package/dist/sandbox/check-runner.d.ts.map +1 -1
- package/dist/sandbox/compose-generator.d.ts.map +1 -1
- package/dist/sandbox/docker-compose-sandbox.d.ts.map +1 -1
- package/dist/sandbox/docker-image-sandbox.d.ts.map +1 -1
- package/dist/sandbox/env-filter.d.ts.map +1 -1
- package/dist/sandbox/index.d.ts.map +1 -1
- package/dist/sandbox/sandbox-manager.d.ts.map +1 -1
- package/dist/sandbox/sandbox-telemetry.d.ts.map +1 -1
- package/dist/sandbox/seatbelt-sandbox.d.ts.map +1 -1
- package/dist/sandbox/trace-ingester.d.ts.map +1 -1
- package/dist/sandbox/types.d.ts.map +1 -1
- package/dist/scheduler/cli-handler.d.ts.map +1 -1
- package/dist/scheduler/index.d.ts.map +1 -1
- package/dist/scheduler/message-trigger.d.ts.map +1 -1
- package/dist/scheduler/schedule-parser.d.ts.map +1 -1
- package/dist/scheduler/schedule-store.d.ts.map +1 -1
- package/dist/scheduler/schedule-tool.d.ts.map +1 -1
- package/dist/scheduler/scheduler.d.ts.map +1 -1
- package/dist/scheduler/store/index.d.ts.map +1 -1
- package/dist/scheduler/store/json-migrator.d.ts.map +1 -1
- package/dist/scheduler/store/sqlite-store.d.ts.map +1 -1
- package/dist/scheduler/store/types.d.ts.map +1 -1
- package/dist/sdk/{a2a-frontend-L3TQ7QQ6.mjs → a2a-frontend-XCQ4CQUF.mjs} +3 -3
- package/dist/sdk/{check-provider-registry-RQYIEQLJ.mjs → check-provider-registry-2D3MCWP3.mjs} +14 -11
- package/dist/sdk/{chunk-WZQMTD7W.mjs → chunk-2LLKENYD.mjs} +3 -3
- package/dist/sdk/{chunk-WZQMTD7W.mjs.map → chunk-2LLKENYD.mjs.map} +1 -1
- package/dist/sdk/{chunk-XXAEN5KU.mjs → chunk-77AKSSW2.mjs} +43 -65
- package/dist/sdk/chunk-77AKSSW2.mjs.map +1 -0
- package/dist/sdk/chunk-7QI6F66G.mjs +145 -0
- package/dist/sdk/chunk-7QI6F66G.mjs.map +1 -0
- package/dist/sdk/{chunk-NEZY2MXM.mjs → chunk-B2LQT6QU.mjs} +4 -4
- package/dist/sdk/{chunk-NEZY2MXM.mjs.map → chunk-B2LQT6QU.mjs.map} +1 -1
- package/dist/sdk/{chunk-IY5PQ5EN.mjs → chunk-BVEATT5V.mjs} +822 -51
- package/dist/sdk/chunk-BVEATT5V.mjs.map +1 -0
- package/dist/sdk/{chunk-TSX3YS3F.mjs → chunk-HW4MPCOW.mjs} +5 -139
- package/dist/sdk/chunk-HW4MPCOW.mjs.map +1 -0
- package/dist/sdk/chunk-PGBV3VZB.mjs +122 -0
- package/dist/sdk/chunk-PGBV3VZB.mjs.map +1 -0
- package/dist/sdk/{chunk-PDQTEBOJ.mjs → chunk-QT766ZLD.mjs} +5 -1
- package/dist/sdk/chunk-QT766ZLD.mjs.map +1 -0
- package/dist/sdk/{chunk-5TXIAPRA.mjs → chunk-S3GSZRYC.mjs} +2 -2
- package/dist/sdk/{chunk-NPOVLLKH.mjs → chunk-TGQBEM3Y.mjs} +570 -259
- package/dist/sdk/chunk-TGQBEM3Y.mjs.map +1 -0
- package/dist/sdk/chunk-TL3ZTYFY.mjs +141 -0
- package/dist/sdk/chunk-TL3ZTYFY.mjs.map +1 -0
- package/dist/sdk/{chunk-4UMDSYC7.mjs → chunk-VS3JE2DL.mjs} +3 -3
- package/dist/sdk/{chunk-A4WHMRK2.mjs → chunk-YETG675X.mjs} +2 -2
- package/dist/sdk/{chunk-XX6WT332.mjs → chunk-YTG5DN72.mjs} +17 -9
- package/dist/sdk/chunk-YTG5DN72.mjs.map +1 -0
- package/dist/sdk/{chunk-SRU5TFNY.mjs → chunk-YU3VR5SZ.mjs} +145 -16
- package/dist/sdk/chunk-YU3VR5SZ.mjs.map +1 -0
- package/dist/sdk/{config-BCYAVJ5S.mjs → config-H5IOLBFA.mjs} +2 -2
- package/dist/sdk/{email-frontend-P7QE4UUJ.mjs → email-frontend-AE5TYWNC.mjs} +18 -3
- package/dist/sdk/{email-frontend-P7QE4UUJ.mjs.map → email-frontend-AE5TYWNC.mjs.map} +1 -1
- package/dist/sdk/{failure-condition-evaluator-ZBOSD574.mjs → failure-condition-evaluator-66PWLV3D.mjs} +4 -4
- package/dist/sdk/{github-frontend-4WHT5JEU.mjs → github-frontend-BBFKCY4M.mjs} +4 -4
- package/dist/sdk/{host-FKR7H26C.mjs → host-UQRZDLT7.mjs} +8 -8
- package/dist/sdk/oauth2-token-cache-OS7WHLDI.mjs +13 -0
- package/dist/sdk/{routing-IB2PXYFC.mjs → routing-Q647KUMO.mjs} +5 -5
- package/dist/sdk/{schedule-tool-LB33KL2W.mjs → schedule-tool-WMGSM6IT.mjs} +14 -11
- package/dist/sdk/{schedule-tool-handler-KYWZHKSS.mjs → schedule-tool-handler-JMDHCGZ2.mjs} +14 -11
- package/dist/sdk/sdk.d.mts +14 -2
- package/dist/sdk/sdk.d.ts +14 -2
- package/dist/sdk/sdk.js +1927 -643
- package/dist/sdk/sdk.js.map +1 -1
- package/dist/sdk/sdk.mjs +13 -10
- package/dist/sdk/sdk.mjs.map +1 -1
- package/dist/sdk/session-registry-CENXWIFR.mjs +12 -0
- package/dist/sdk/{slack-frontend-K3TPGERM.mjs → slack-frontend-JMX5MUVZ.mjs} +42 -12
- package/dist/sdk/slack-frontend-JMX5MUVZ.mjs.map +1 -0
- package/dist/sdk/{task-evaluator-H3BXC7SE.mjs → task-evaluator-4QG4CYQA.mjs} +7 -6
- package/dist/sdk/task-evaluator-4QG4CYQA.mjs.map +1 -0
- package/dist/sdk/{teams-frontend-6RRW533K.mjs → teams-frontend-6MDAN7OR.mjs} +17 -4
- package/dist/sdk/teams-frontend-6MDAN7OR.mjs.map +1 -0
- package/dist/sdk/{telegram-frontend-5UA77YAT.mjs → telegram-frontend-NLX2ZHS4.mjs} +17 -4
- package/dist/sdk/telegram-frontend-NLX2ZHS4.mjs.map +1 -0
- package/dist/sdk/{trace-helpers-AMZ2524G.mjs → trace-helpers-AIUGQLK5.mjs} +3 -3
- package/dist/sdk/{trace-serializer-EBHTHZYT.mjs → trace-serializer-4TOIAVQL.mjs} +10 -2
- package/dist/sdk/{track-execution-VW6P3OYO.mjs → track-execution-CFRZXMEC.mjs} +91 -20
- package/dist/sdk/track-execution-CFRZXMEC.mjs.map +1 -0
- package/dist/sdk/{utcp-check-provider-Q4PD5EP2.mjs → utcp-check-provider-WDTSQ7DZ.mjs} +3 -2
- package/dist/sdk/{whatsapp-frontend-72XEIUIR.mjs → whatsapp-frontend-3EMMNC7R.mjs} +15 -2
- package/dist/sdk/whatsapp-frontend-3EMMNC7R.mjs.map +1 -0
- package/dist/sdk/{workflow-check-provider-N6KSDPWU.mjs → workflow-check-provider-G7A67EPP.mjs} +14 -11
- package/dist/sdk/workflow-check-provider-G7A67EPP.mjs.map +1 -0
- package/dist/sdk.d.ts.map +1 -1
- package/dist/session-registry.d.ts +2 -7
- package/dist/session-registry.d.ts.map +1 -1
- package/dist/slack/adapter.d.ts.map +1 -1
- package/dist/slack/cache-prewarmer.d.ts.map +1 -1
- package/dist/slack/client.d.ts +8 -0
- package/dist/slack/client.d.ts.map +1 -1
- package/dist/slack/markdown.d.ts.map +1 -1
- package/dist/slack/prompt-state.d.ts.map +1 -1
- package/dist/slack/rate-limiter.d.ts.map +1 -1
- package/dist/slack/schedule-tool-handler.d.ts.map +1 -1
- package/dist/slack/signature.d.ts.map +1 -1
- package/dist/slack/slack-output-adapter.d.ts.map +1 -1
- package/dist/slack/socket-runner.d.ts +1 -0
- package/dist/slack/socket-runner.d.ts.map +1 -1
- package/dist/slack/thread-cache.d.ts.map +1 -1
- package/dist/snapshot-store.d.ts.map +1 -1
- package/dist/state-machine/context/build-engine-context.d.ts.map +1 -1
- package/dist/state-machine/context/workflow-inputs.d.ts.map +1 -1
- package/dist/state-machine/dispatch/debounce-manager.d.ts +44 -0
- package/dist/state-machine/dispatch/debounce-manager.d.ts.map +1 -0
- package/dist/state-machine/dispatch/dependency-gating.d.ts.map +1 -1
- package/dist/state-machine/dispatch/execution-invoker.d.ts.map +1 -1
- package/dist/state-machine/dispatch/foreach-processor.d.ts.map +1 -1
- package/dist/state-machine/dispatch/history-snapshot.d.ts.map +1 -1
- package/dist/state-machine/dispatch/on-init-handlers.d.ts.map +1 -1
- package/dist/state-machine/dispatch/policy-gate.d.ts.map +1 -1
- package/dist/state-machine/dispatch/renderer-schema.d.ts.map +1 -1
- package/dist/state-machine/dispatch/sandbox-routing.d.ts.map +1 -1
- package/dist/state-machine/dispatch/stats-manager.d.ts.map +1 -1
- package/dist/state-machine/dispatch/template-renderer.d.ts.map +1 -1
- package/dist/state-machine/execution/summary.d.ts.map +1 -1
- package/dist/state-machine/runner.d.ts.map +1 -1
- package/dist/state-machine/states/check-running.d.ts.map +1 -1
- package/dist/state-machine/states/completed.d.ts.map +1 -1
- package/dist/state-machine/states/error.d.ts.map +1 -1
- package/dist/state-machine/states/init.d.ts.map +1 -1
- package/dist/state-machine/states/level-dispatch.d.ts.map +1 -1
- package/dist/state-machine/states/plan-ready.d.ts.map +1 -1
- package/dist/state-machine/states/routing.d.ts.map +1 -1
- package/dist/state-machine/states/wave-planning.d.ts.map +1 -1
- package/dist/state-machine/workflow-projection.d.ts.map +1 -1
- package/dist/state-machine-execution-engine.d.ts +1 -0
- package/dist/state-machine-execution-engine.d.ts.map +1 -1
- package/dist/teams/adapter.d.ts.map +1 -1
- package/dist/teams/client.d.ts.map +1 -1
- package/dist/teams/markdown.d.ts.map +1 -1
- package/dist/teams/webhook-runner.d.ts +1 -0
- package/dist/teams/webhook-runner.d.ts.map +1 -1
- package/dist/telegram/adapter.d.ts.map +1 -1
- package/dist/telegram/client.d.ts.map +1 -1
- package/dist/telegram/markdown.d.ts.map +1 -1
- package/dist/telegram/polling-runner.d.ts +1 -0
- package/dist/telegram/polling-runner.d.ts.map +1 -1
- package/dist/telemetry/fallback-ndjson.d.ts.map +1 -1
- package/dist/telemetry/file-span-exporter.d.ts.map +1 -1
- package/dist/telemetry/lazy-otel.d.ts.map +1 -1
- package/dist/telemetry/metrics.d.ts.map +1 -1
- package/dist/telemetry/opentelemetry.d.ts.map +1 -1
- package/dist/telemetry/state-capture.d.ts.map +1 -1
- package/dist/telemetry/trace-helpers.d.ts.map +1 -1
- package/dist/telemetry/trace-report-exporter.d.ts.map +1 -1
- package/dist/test-runner/assertions.d.ts.map +1 -1
- package/dist/test-runner/conversation-sugar.d.ts.map +1 -1
- package/dist/test-runner/core/environment.d.ts.map +1 -1
- package/dist/test-runner/core/fixture.d.ts.map +1 -1
- package/dist/test-runner/core/flow-stage.d.ts.map +1 -1
- package/dist/test-runner/core/mocks.d.ts.map +1 -1
- package/dist/test-runner/core/test-execution-wrapper.d.ts.map +1 -1
- package/dist/test-runner/evaluators.d.ts.map +1 -1
- package/dist/test-runner/fixture-loader.d.ts.map +1 -1
- package/dist/test-runner/index.d.ts.map +1 -1
- package/dist/test-runner/llm-judge.d.ts.map +1 -1
- package/dist/test-runner/recorders/github-recorder.d.ts.map +1 -1
- package/dist/test-runner/recorders/global-recorder.d.ts.map +1 -1
- package/dist/test-runner/recorders/slack-recorder.d.ts.map +1 -1
- package/dist/test-runner/utils/selectors.d.ts.map +1 -1
- package/dist/test-runner/validator.d.ts.map +1 -1
- package/dist/traces/{run-2026-05-05T12-31-47-571Z.ndjson → run-2026-08-20T13-50-06-218Z.ndjson} +2699 -2699
- package/dist/tui/chat-runner.d.ts.map +1 -1
- package/dist/tui/chat-state.d.ts.map +1 -1
- package/dist/tui/chat-tui.d.ts.map +1 -1
- package/dist/tui/components/chat-box.d.ts.map +1 -1
- package/dist/tui/components/input-bar.d.ts.map +1 -1
- package/dist/tui/components/status-bar.d.ts.map +1 -1
- package/dist/tui/components/trace-viewer.d.ts.map +1 -1
- package/dist/tui/index.d.ts.map +1 -1
- package/dist/tui/tui-frontend.d.ts.map +1 -1
- package/dist/types/bot.d.ts.map +1 -1
- package/dist/types/cli.d.ts.map +1 -1
- package/dist/types/config.d.ts +14 -2
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/engine.d.ts.map +1 -1
- package/dist/types/execution.d.ts.map +1 -1
- package/dist/types/git-checkout.d.ts.map +1 -1
- package/dist/types/github.d.ts.map +1 -1
- package/dist/types/workflow.d.ts.map +1 -1
- package/dist/utils/author-permissions.d.ts.map +1 -1
- package/dist/utils/child-process-error-handler.d.ts +19 -0
- package/dist/utils/child-process-error-handler.d.ts.map +1 -0
- package/dist/utils/command-executor.d.ts.map +1 -1
- package/dist/utils/comment-metadata.d.ts.map +1 -1
- package/dist/utils/config-loader.d.ts.map +1 -1
- package/dist/utils/config-merger.d.ts.map +1 -1
- package/dist/utils/diff-processor.d.ts.map +1 -1
- package/dist/utils/env-exposure.d.ts.map +1 -1
- package/dist/utils/env-resolver.d.ts.map +1 -1
- package/dist/utils/fair-concurrency-limiter.d.ts.map +1 -1
- package/dist/utils/file-exclusion.d.ts.map +1 -1
- package/dist/utils/head-sha.d.ts.map +1 -1
- package/dist/utils/human-id.d.ts.map +1 -1
- package/dist/utils/instance-id.d.ts.map +1 -1
- package/dist/utils/interactive-prompt.d.ts.map +1 -1
- package/dist/utils/issue-normalizer.d.ts.map +1 -1
- package/dist/utils/json-text-extractor.d.ts.map +1 -1
- package/dist/utils/mermaid-telemetry.d.ts.map +1 -1
- package/dist/utils/oauth2-token-cache.d.ts.map +1 -1
- package/dist/utils/rate-limiter.d.ts.map +1 -1
- package/dist/utils/sandbox.d.ts.map +1 -1
- package/dist/utils/script-memory-ops.d.ts.map +1 -1
- package/dist/utils/script-tool-environment.d.ts.map +1 -1
- package/dist/utils/stdin-reader.d.ts.map +1 -1
- package/dist/utils/template-context.d.ts.map +1 -1
- package/dist/utils/tool-resolver.d.ts.map +1 -1
- package/dist/utils/toolkit-expander.d.ts.map +1 -1
- package/dist/utils/tracer-init.d.ts.map +1 -1
- package/dist/utils/ui-helpers.d.ts.map +1 -1
- package/dist/utils/user-facing-error.d.ts +4 -0
- package/dist/utils/user-facing-error.d.ts.map +1 -0
- package/dist/utils/workspace-manager.d.ts +5 -0
- package/dist/utils/workspace-manager.d.ts.map +1 -1
- package/dist/utils/worktree-cleanup.d.ts +28 -0
- package/dist/utils/worktree-cleanup.d.ts.map +1 -1
- package/dist/utils/worktree-manager.d.ts +6 -0
- package/dist/utils/worktree-manager.d.ts.map +1 -1
- package/dist/webhook-server.d.ts.map +1 -1
- package/dist/whatsapp/adapter.d.ts.map +1 -1
- package/dist/whatsapp/client.d.ts.map +1 -1
- package/dist/whatsapp/markdown.d.ts.map +1 -1
- package/dist/whatsapp/webhook-runner.d.ts +1 -0
- package/dist/whatsapp/webhook-runner.d.ts.map +1 -1
- package/dist/workflow-executor.d.ts +7 -0
- package/dist/workflow-executor.d.ts.map +1 -1
- package/dist/workflow-registry.d.ts.map +1 -1
- package/package.json +3 -3
- package/dist/output/traces/run-2026-05-05T12-31-09-587Z.ndjson +0 -252
- package/dist/sdk/chunk-IY5PQ5EN.mjs.map +0 -1
- package/dist/sdk/chunk-NPOVLLKH.mjs.map +0 -1
- package/dist/sdk/chunk-PDQTEBOJ.mjs.map +0 -1
- package/dist/sdk/chunk-SRU5TFNY.mjs.map +0 -1
- package/dist/sdk/chunk-TSX3YS3F.mjs.map +0 -1
- package/dist/sdk/chunk-XX6WT332.mjs.map +0 -1
- package/dist/sdk/chunk-XXAEN5KU.mjs.map +0 -1
- package/dist/sdk/session-registry-6PV6SGEJ.mjs +0 -10
- package/dist/sdk/slack-frontend-K3TPGERM.mjs.map +0 -1
- package/dist/sdk/task-evaluator-H3BXC7SE.mjs.map +0 -1
- package/dist/sdk/teams-frontend-6RRW533K.mjs.map +0 -1
- package/dist/sdk/telegram-frontend-5UA77YAT.mjs.map +0 -1
- package/dist/sdk/trace-reader-OVE4DL2D.mjs +0 -270
- package/dist/sdk/trace-reader-OVE4DL2D.mjs.map +0 -1
- package/dist/sdk/track-execution-VW6P3OYO.mjs.map +0 -1
- package/dist/sdk/whatsapp-frontend-72XEIUIR.mjs.map +0 -1
- package/dist/traces/run-2026-05-05T12-31-09-587Z.ndjson +0 -252
- /package/dist/sdk/{a2a-frontend-L3TQ7QQ6.mjs.map → a2a-frontend-XCQ4CQUF.mjs.map} +0 -0
- /package/dist/sdk/{check-provider-registry-RQYIEQLJ.mjs.map → check-provider-registry-2D3MCWP3.mjs.map} +0 -0
- /package/dist/sdk/{chunk-5TXIAPRA.mjs.map → chunk-S3GSZRYC.mjs.map} +0 -0
- /package/dist/sdk/{chunk-4UMDSYC7.mjs.map → chunk-VS3JE2DL.mjs.map} +0 -0
- /package/dist/sdk/{chunk-A4WHMRK2.mjs.map → chunk-YETG675X.mjs.map} +0 -0
- /package/dist/sdk/{config-BCYAVJ5S.mjs.map → config-H5IOLBFA.mjs.map} +0 -0
- /package/dist/sdk/{failure-condition-evaluator-ZBOSD574.mjs.map → failure-condition-evaluator-66PWLV3D.mjs.map} +0 -0
- /package/dist/sdk/{github-frontend-4WHT5JEU.mjs.map → github-frontend-BBFKCY4M.mjs.map} +0 -0
- /package/dist/sdk/{host-FKR7H26C.mjs.map → host-UQRZDLT7.mjs.map} +0 -0
- /package/dist/sdk/{routing-IB2PXYFC.mjs.map → oauth2-token-cache-OS7WHLDI.mjs.map} +0 -0
- /package/dist/sdk/{schedule-tool-LB33KL2W.mjs.map → routing-Q647KUMO.mjs.map} +0 -0
- /package/dist/sdk/{schedule-tool-handler-KYWZHKSS.mjs.map → schedule-tool-WMGSM6IT.mjs.map} +0 -0
- /package/dist/sdk/{session-registry-6PV6SGEJ.mjs.map → schedule-tool-handler-JMDHCGZ2.mjs.map} +0 -0
- /package/dist/sdk/{trace-helpers-AMZ2524G.mjs.map → session-registry-CENXWIFR.mjs.map} +0 -0
- /package/dist/sdk/{trace-serializer-EBHTHZYT.mjs.map → trace-helpers-AIUGQLK5.mjs.map} +0 -0
- /package/dist/sdk/{utcp-check-provider-Q4PD5EP2.mjs.map → trace-serializer-4TOIAVQL.mjs.map} +0 -0
- /package/dist/sdk/{workflow-check-provider-N6KSDPWU.mjs.map → utcp-check-provider-WDTSQ7DZ.mjs.map} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/slack/markdown.ts"],"sourcesContent":["// Lightweight Markdown → Slack mrkdwn formatter.\n// The goal is to make common Markdown output from AI steps look natural in Slack\n// without pulling in a full Markdown parser.\n//\n// Supported conversions:\n// - # Header / ## Header → *Header* (bold with visual separation)\n// - **bold** / __bold__ → *bold*\n// - [label](url) → <url|label>\n// -  → <url|alt>\n// - *italic* (inline) → _italic_\n// - ```mermaid blocks → rendered to PNG and uploaded to Slack\n//\n// Everything else is passed through unchanged; Slack will still render many\n// Markdown-like constructs (lists, code fences, etc.) natively.\n\nimport { spawn } from 'child_process';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as os from 'os';\n\n/**\n * Represents an extracted mermaid diagram\n */\nexport interface MermaidDiagram {\n /** The full match including ```mermaid and ``` */\n fullMatch: string;\n /** The mermaid code content */\n code: string;\n /** Start index in the original text */\n startIndex: number;\n /** End index in the original text */\n endIndex: number;\n}\n\n/**\n * Extract all mermaid code blocks from text\n */\nexport function extractMermaidDiagrams(text: string): MermaidDiagram[] {\n const diagrams: MermaidDiagram[] = [];\n // Match ```mermaid followed by newline, content, and closing ```\n const regex = /```mermaid\\s*\\n([\\s\\S]*?)```/g;\n let match;\n while ((match = regex.exec(text)) !== null) {\n diagrams.push({\n fullMatch: match[0],\n code: match[1].trim(),\n startIndex: match.index,\n endIndex: match.index + match[0].length,\n });\n }\n return diagrams;\n}\n\n/**\n * Render a mermaid diagram to PNG using mmdc CLI (@mermaid-js/mermaid-cli).\n *\n * Requirements:\n * - Node.js and npx must be available in PATH\n * - Network access on first run (npx downloads the package)\n * - Puppeteer/Chromium dependencies (mermaid-cli uses headless browser)\n *\n * On Linux, you may need to install chromium dependencies:\n * apt-get install -y chromium-browser libatk-bridge2.0-0 libgtk-3-0\n *\n * On Docker/CI, consider using a base image with puppeteer support or\n * pre-installing @mermaid-js/mermaid-cli globally.\n *\n * @param mermaidCode The mermaid diagram code\n * @returns Buffer containing PNG data, or null if rendering failed\n */\nexport async function renderMermaidToPng(mermaidCode: string): Promise<Buffer | null> {\n // Create temp files for input and output\n const tmpDir = os.tmpdir();\n const inputFile = path.join(\n tmpDir,\n `mermaid-${Date.now()}-${Math.random().toString(36).slice(2)}.mmd`\n );\n const outputFile = path.join(\n tmpDir,\n `mermaid-${Date.now()}-${Math.random().toString(36).slice(2)}.png`\n );\n\n try {\n // Write mermaid code to temp file\n fs.writeFileSync(inputFile, mermaidCode, 'utf-8');\n\n // Detect system chromium for puppeteer (mermaid-cli dependency)\n // Without this, puppeteer may hang trying to download its own chromium\n const chromiumPaths = [\n '/usr/bin/chromium',\n '/usr/bin/chromium-browser',\n '/usr/bin/google-chrome',\n '/usr/bin/chrome',\n ];\n let chromiumPath: string | undefined;\n for (const p of chromiumPaths) {\n if (fs.existsSync(p)) {\n chromiumPath = p;\n break;\n }\n }\n\n // Build environment with chromium path if found\n const env = { ...process.env };\n if (chromiumPath) {\n env.PUPPETEER_EXECUTABLE_PATH = chromiumPath;\n }\n\n // Run mmdc to render PNG\n const result = await new Promise<{ success: boolean; error?: string }>(resolve => {\n const proc = spawn(\n 'npx',\n [\n '--yes',\n '@mermaid-js/mermaid-cli',\n '-i',\n inputFile,\n '-o',\n outputFile,\n '-e',\n 'png',\n '-b',\n 'white',\n '-w',\n '1200',\n ],\n {\n timeout: 60000, // 60 second timeout (first run may download packages)\n stdio: ['pipe', 'pipe', 'pipe'],\n env,\n }\n );\n\n let stderr = '';\n proc.stderr?.on('data', data => {\n stderr += data.toString();\n });\n\n proc.on('close', code => {\n if (code === 0) {\n resolve({ success: true });\n } else {\n resolve({ success: false, error: stderr || `Exit code ${code}` });\n }\n });\n\n proc.on('error', err => {\n resolve({ success: false, error: err.message });\n });\n });\n\n if (!result.success) {\n console.warn(`Mermaid rendering failed: ${result.error}`);\n return null;\n }\n\n // Read the output PNG\n if (!fs.existsSync(outputFile)) {\n console.warn('Mermaid output file not created');\n return null;\n }\n\n const pngBuffer = fs.readFileSync(outputFile);\n return pngBuffer;\n } catch (e) {\n console.warn(`Mermaid rendering error: ${e instanceof Error ? e.message : String(e)}`);\n return null;\n } finally {\n // Cleanup temp files\n try {\n if (fs.existsSync(inputFile)) fs.unlinkSync(inputFile);\n if (fs.existsSync(outputFile)) fs.unlinkSync(outputFile);\n } catch {\n // Ignore cleanup errors\n }\n }\n}\n\n/**\n * Replace mermaid blocks in text with a placeholder message\n * @param text Original text\n * @param diagrams Extracted diagrams\n * @param replacement Text to replace each diagram with (or a function that returns replacement for each index)\n */\nexport function replaceMermaidBlocks(\n text: string,\n diagrams: MermaidDiagram[],\n replacement: string | ((index: number) => string) = '_(See diagram above)_'\n): string {\n if (diagrams.length === 0) return text;\n\n // Sort by start index descending to replace from end to start (preserves indices)\n const sorted = [...diagrams].sort((a, b) => b.startIndex - a.startIndex);\n\n let result = text;\n sorted.forEach((diagram, sortedIndex) => {\n // Calculate original index (since we sorted in reverse)\n const originalIndex = diagrams.length - 1 - sortedIndex;\n const rep = typeof replacement === 'function' ? replacement(originalIndex) : replacement;\n result = result.slice(0, diagram.startIndex) + rep + result.slice(diagram.endIndex);\n });\n\n return result;\n}\n\nexport function markdownToSlack(text: string): string {\n if (!text || typeof text !== 'string') return '';\n\n // Process line-by-line so ALL transformations respect code blocks.\n const lines = text.split(/\\r?\\n/);\n let inCodeBlock = false;\n for (let i = 0; i < lines.length; i++) {\n const trimmed = lines[i].trimStart();\n\n // Track fenced code blocks — skip all transformations inside them\n if (/^```/.test(trimmed)) {\n inCodeBlock = !inCodeBlock;\n continue;\n }\n if (inCodeBlock) continue;\n\n let line = lines[i];\n\n // Images:  → <url|alt>\n line = line.replace(\n /!\\[([^\\]]*)\\]\\(([^)\\s]+)(?:\\s+\"[^\"]*\")?\\)/g,\n (_m, alt: string, url: string) => `<${url}|${alt || 'image'}>`\n );\n\n // Links: [label](url) → <url|label>\n line = line.replace(\n /\\[([^\\]]+)\\]\\(([^)\\s]+)(?:\\s+\"[^\"]*\")?\\)/g,\n (_m, label: string, url: string) => `<${url}|${label}>`\n );\n\n // Bold: **text** or __text__ → *text*\n line = line.replace(/\\*\\*([^*]+)\\*\\*/g, (_m, inner: string) => `*${inner}*`);\n line = line.replace(/__([^_]+)__/g, (_m, inner: string) => `*${inner}*`);\n\n // Headers: # Header → *Header* (Slack doesn't have native headers)\n const headerMatch = /^(#{1,6})\\s+(.+)$/.exec(line.trimStart());\n if (headerMatch) {\n const [, hashes, headerText] = headerMatch;\n // For h1/h2, add extra emphasis with newline before (if not first line\n // and previous line is not empty/header/code-fence)\n const prevLine = i > 0 ? lines[i - 1].trim() : '';\n const prevIsHeaderOrFence =\n /^#{1,6}\\s+/.test(prevLine) || /^\\*[^*]+\\*$/.test(prevLine) || /^```/.test(prevLine);\n if (hashes.length <= 2 && i > 0 && prevLine !== '' && !prevIsHeaderOrFence) {\n lines[i] = `\\n*${headerText.trim()}*`;\n } else {\n lines[i] = `*${headerText.trim()}*`;\n }\n continue;\n }\n\n // Bullet lists: \"- item\" or \"* item\" → \"• item\" (preserve indentation)\n const bulletMatch = /^(\\s*)([-*])\\s+(.+)$/.exec(line);\n if (bulletMatch) {\n const [, indent, , rest] = bulletMatch;\n lines[i] = `${indent}• ${rest}`;\n continue;\n }\n\n lines[i] = line;\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Represents an extracted file section delimited by --- filename.ext ---\n */\nexport interface FileSection {\n /** Full match including delimiter(s) and content */\n fullMatch: string;\n /** Extracted filename (e.g., \"report.csv\") */\n filename: string;\n /** Content after the opening delimiter (trimmed) */\n content: string;\n /** Start index in the original text */\n startIndex: number;\n /** End index in the original text */\n endIndex: number;\n}\n\n/**\n * Extract all file sections delimited by --- filename.ext --- from text.\n *\n * A section starts at a `--- filename.ext ---` line. It ends at:\n * 1. A closing delimiter with the same filename (optional, backward-compatible)\n * 2. The next `--- other.ext ---` delimiter (starts a new section)\n * 3. End of text\n */\nexport function extractFileSections(text: string): FileSection[] {\n const sections: FileSection[] = [];\n\n // Find all --- filename.ext --- delimiter lines\n const delimRegex = /^--- ([\\w][\\w.\\-]*\\.\\w+) ---$/gm;\n const delimiters: { filename: string; start: number; end: number }[] = [];\n let m;\n while ((m = delimRegex.exec(text)) !== null) {\n delimiters.push({\n filename: m[1],\n start: m.index,\n end: m.index + m[0].length,\n });\n }\n\n if (delimiters.length === 0) return sections;\n\n for (let i = 0; i < delimiters.length; i++) {\n const open = delimiters[i];\n\n // Content starts after the newline following the opening delimiter\n const contentStart =\n open.end < text.length && text[open.end] === '\\n' ? open.end + 1 : open.end;\n\n // Section extends to the next delimiter or end of text\n const sectionEnd = i + 1 < delimiters.length ? delimiters[i + 1].start : text.length;\n const content = text.substring(contentStart, sectionEnd).trim();\n if (content.length > 0) {\n sections.push({\n fullMatch: text.substring(open.start, sectionEnd),\n filename: open.filename,\n content,\n startIndex: open.start,\n endIndex: sectionEnd,\n });\n }\n }\n\n return sections;\n}\n\n/**\n * Replace file sections in text with placeholder messages.\n * Uses back-to-front replacement to preserve indices (same as replaceMermaidBlocks).\n */\nexport function replaceFileSections(\n text: string,\n sections: FileSection[],\n replacement: string | ((index: number) => string) = idx =>\n `_(See file: ${sections[idx].filename} above)_`\n): string {\n if (sections.length === 0) return text;\n\n const sorted = [...sections].sort((a, b) => b.startIndex - a.startIndex);\n\n let result = text;\n sorted.forEach((section, sortedIndex) => {\n const originalIndex = sections.length - 1 - sortedIndex;\n const rep = typeof replacement === 'function' ? replacement(originalIndex) : replacement;\n result = result.slice(0, section.startIndex) + rep + result.slice(section.endIndex);\n });\n\n return result;\n}\n\nexport function formatSlackText(text: string): string {\n return markdownToSlack(text);\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/agent-protocol/task-live-updates.ts"],"sourcesContent":["import crypto from 'crypto';\nimport { logger } from '../logger';\nimport type { TaskLiveUpdatesConfig } from '../types/config';\nimport { fetchTraceSpans, serializeTraceForPrompt } from './trace-serializer';\n\nexport const DEFAULT_TASK_LIVE_UPDATE_INTERVAL_SECONDS = 10;\nexport const DEFAULT_TASK_LIVE_UPDATE_MAX_TRACE_CHARS = 12_000;\nexport const DEFAULT_TASK_LIVE_UPDATE_FIRST_UPDATE_DELAY_SECONDS = 10;\nexport const DEFAULT_TASK_LIVE_UPDATE_METADATA_REFRESH_SECONDS = 5;\nexport const DEFAULT_TASK_LIVE_UPDATE_STALL_FALLBACK_SECONDS = 60;\nexport const DEFAULT_TASK_LIVE_UPDATE_MODEL = 'gemini-3.1-flash-lite-preview';\nconst DEFAULT_TASK_LIVE_UPDATE_STALL_NOTICE =\n '_No new meaningful progress is visible yet. Some steps can stay quiet for up to 5 minutes before there is new news._';\n\nexport const DEFAULT_TASK_LIVE_UPDATE_PROMPT = `You are generating a short live progress update for a user while an AI task is still running.\n\nThis is NOT the final answer.\nDo NOT answer the user's original request.\nDo NOT write the final solution.\nDo NOT explain the topic in full.\nDo NOT provide a root cause, recommendation, summary of findings, or conclusion.\nEven if you think you already know the answer, do NOT give it here.\n\nYou will receive:\n- the user's original request\n- the previous progress update, if any\n- timing metadata for this run\n- the latest execution trace snapshot\n\nYour job is to produce a concise status update that tells the user only:\n- the overall progress so far\n- the last meaningful action that finished\n- what the agent is doing right now\n- what it is likely waiting on, if anything\n\nRules:\n- This is a STATUS UPDATE, not the final answer\n- Never answer the user's request directly\n- Never switch into explanation mode\n- Never write a complete answer, even partially\n- Keep it short: exactly 4 short bullet points\n- Use the exact bullet labels below\n- Do NOT generate timing metadata lines\n- Do NOT generate task_id lines\n- Timing metadata is provided only so you understand task pace and recency\n- The system will append timing and task metadata separately\n- Prefer concrete progress over generic wording\n- Mention the most recent completed action before the current action\n- Do not claim completion unless the task is actually done\n- Do not mention internal implementation details unless they help explain the current work\n- Avoid repeating the previous update verbatim\n- Do not use code fences\n- Plain markdown text only\n\nRequired output format:\n- Progress: <very short overall progress statement, not a final answer>\n- Last done: <most recent completed action>\n- Now: <current action in progress>\n- Waiting on: <tool, search, model, user input, or \"nothing blocking right now\">\n\nTrace interpretation rules:\n- Translate internal trace phases into user-meaningful progress, do not just repeat raw span names\n- If the trace shows routing or classify work, describe that as understanding the request and choosing the right path\n- If the trace shows setup-projects, build-config, or loading context, describe that as preparing the workspace or gathering context\n- If the trace shows search, extract, code-explorer, or file inspection, describe that as investigating the codebase\n- If the trace shows engineer work, edits, tests, PR creation, or command execution, describe that as implementing or verifying changes\n- If the trace shows completion prompts, final answer generation, summarization, final validation, or output rendering, describe that as validating findings and preparing the final response\n- If the trace shows waiting on a long AI request, delegate, tool call, or sandboxed child task, describe that as waiting for analysis or validation to finish\n\nIf you are tempted to answer the user's question, stop and convert that into:\n- what was learned so far\n- what was just completed\n- what is still being checked\n\nBad update example:\n- \"API rate limiting works by...\"\n\nGood update example:\n- \"Progress: identified the gateway components involved in rate limiting\"\n- \"Last done: found the middleware files and session manager entry points\"\n- \"Now: tracing the enforcement path through the gateway\"\n- \"Waiting on: search results for the limiter implementation details\"`;\n\nexport interface TaskLiveUpdateSink {\n readonly kind: string;\n start(): Promise<{ ref?: Record<string, unknown> } | null>;\n update(text: string): Promise<{ ref?: Record<string, unknown> } | null>;\n complete(text: string): Promise<{ ref?: Record<string, unknown> } | null>;\n fail(text: string): Promise<{ ref?: Record<string, unknown> } | null>;\n}\n\nexport interface TaskLiveUpdateDeps {\n summarizeProgress?: (input: TaskProgressSummaryInput) => Promise<string | null>;\n serializeTrace?: (\n traceRef: string,\n maxChars: number,\n traceId?: string\n ) => Promise<string | undefined>;\n extractSkillMetadata?: (\n traceRef: string,\n traceId?: string\n ) => Promise<TaskLiveUpdateSkillMetadata | undefined>;\n}\n\nexport interface TaskProgressSummaryInput {\n requestText: string;\n previousUpdate?: string;\n traceSnapshot: string;\n config: RequiredTaskLiveUpdatesConfig;\n startedAt: Date;\n now: Date;\n elapsedSeconds: number;\n previousUpdateAt?: Date;\n secondsSincePreviousUpdate?: number;\n}\n\ninterface ProgressTimingMetadata {\n elapsedSeconds: number;\n previousUpdateAt?: Date;\n secondsSincePreviousUpdate?: number;\n activatedSkills?: string[];\n}\n\ninterface TaskLiveUpdateSkillMetadata {\n activatedSkills?: string[];\n}\n\nexport interface TaskLiveUpdateContext {\n taskId: string;\n requestText: string;\n traceRef?: string;\n traceId?: string;\n includeTraceId?: boolean;\n resolveTraceState?: () => { traceRef?: string; traceId?: string };\n sink: TaskLiveUpdateSink;\n config: RequiredTaskLiveUpdatesConfig;\n onPostedRef?: (ref: Record<string, unknown>) => void;\n appendHistory?: (text: string, stage: 'started' | 'progress' | 'completed' | 'failed') => void;\n}\n\nexport interface RequiredTaskLiveUpdatesConfig {\n enabled: boolean;\n intervalSeconds: number;\n model: string;\n provider?: string;\n prompt: string;\n initialMessage: string;\n maxTraceChars: number;\n}\n\nexport function resolveTaskLiveUpdatesConfig(\n config?: boolean | TaskLiveUpdatesConfig | null\n): RequiredTaskLiveUpdatesConfig | null {\n if (!config) return null;\n if (config === true) {\n return {\n enabled: true,\n intervalSeconds: DEFAULT_TASK_LIVE_UPDATE_INTERVAL_SECONDS,\n model: DEFAULT_TASK_LIVE_UPDATE_MODEL,\n prompt: DEFAULT_TASK_LIVE_UPDATE_PROMPT,\n initialMessage: '',\n maxTraceChars: DEFAULT_TASK_LIVE_UPDATE_MAX_TRACE_CHARS,\n };\n }\n\n if (config.enabled === false) return null;\n\n return {\n enabled: true,\n intervalSeconds: Math.max(\n 1,\n Math.floor(config.interval_seconds || DEFAULT_TASK_LIVE_UPDATE_INTERVAL_SECONDS)\n ),\n model: config.model || DEFAULT_TASK_LIVE_UPDATE_MODEL,\n provider: config.provider,\n prompt: config.prompt || DEFAULT_TASK_LIVE_UPDATE_PROMPT,\n initialMessage: config.initial_message || '',\n maxTraceChars: Math.max(\n 1000,\n Math.floor(config.max_trace_chars || DEFAULT_TASK_LIVE_UPDATE_MAX_TRACE_CHARS)\n ),\n };\n}\n\nexport function isFrontendLiveUpdatesEnabled(\n config: boolean | TaskLiveUpdatesConfig | null | undefined,\n frontend: 'slack' | 'telegram' | 'teams' | 'whatsapp'\n): boolean {\n if (!config) return false;\n if (config === true) return true;\n if (config.enabled === false) return false;\n const frontendCfg = config.frontends?.[frontend];\n if (frontendCfg?.enabled === false) return false;\n return true;\n}\n\nexport class TaskLiveUpdateManager {\n private readonly deps: Required<TaskLiveUpdateDeps>;\n private timer?: ReturnType<typeof setInterval>;\n private firstTickTimer?: ReturnType<typeof setTimeout>;\n private metadataRefreshTimer?: ReturnType<typeof setInterval>;\n private running = false;\n private started = false;\n private completed = false;\n private readonly startedAt = new Date();\n private lastUpdateText?: string;\n private lastUpdateAt?: Date;\n private lastTraceSnapshot?: string;\n private lastPostedMessage?: string;\n private lastStallFallbackAt?: Date;\n private lastUpdateKind: 'semantic' | 'stall' = 'semantic';\n private lastSkillMetadata?: TaskLiveUpdateSkillMetadata;\n\n constructor(\n private readonly ctx: TaskLiveUpdateContext,\n deps?: TaskLiveUpdateDeps\n ) {\n this.deps = {\n summarizeProgress: deps?.summarizeProgress || summarizeTaskProgress,\n serializeTrace: deps?.serializeTrace || defaultSerializeTrace,\n extractSkillMetadata: deps?.extractSkillMetadata || extractTraceSkillMetadata,\n };\n }\n\n async start(): Promise<void> {\n if (this.started) return;\n this.started = true;\n try {\n const started = await this.ctx.sink.start();\n this.recordSinkRef(started);\n logger.info(\n `[TaskLiveUpdates] Started for task ${this.ctx.taskId}; first update in ${DEFAULT_TASK_LIVE_UPDATE_FIRST_UPDATE_DELAY_SECONDS}s, interval=${this.ctx.config.intervalSeconds}s, provider=${this.ctx.config.provider || 'default'}, model=${this.ctx.config.model}`\n );\n } catch (err) {\n logger.warn(\n `[TaskLiveUpdates] Failed to initialize live updates for task ${this.ctx.taskId}: ${\n err instanceof Error ? err.message : String(err)\n }`\n );\n }\n\n this.firstTickTimer = setTimeout(() => {\n void this.runFirstTick();\n }, DEFAULT_TASK_LIVE_UPDATE_FIRST_UPDATE_DELAY_SECONDS * 1000);\n if (typeof (this.firstTickTimer as any)?.unref === 'function') {\n (this.firstTickTimer as any).unref();\n }\n }\n\n async complete(finalText: string): Promise<void> {\n if (this.completed) return;\n this.completed = true;\n this.stop();\n try {\n logger.info(`[TaskLiveUpdates] Publishing final success update for task ${this.ctx.taskId}`);\n const result = await this.ctx.sink.complete(this.decorateText(finalText));\n this.recordSinkRef(result);\n this.ctx.appendHistory?.(finalText, 'completed');\n } catch (err) {\n logger.warn(\n `[TaskLiveUpdates] Failed to publish final update for task ${this.ctx.taskId}: ${\n err instanceof Error ? err.message : String(err)\n }`\n );\n }\n }\n\n async fail(finalText: string): Promise<void> {\n if (this.completed) return;\n this.completed = true;\n this.stop();\n try {\n logger.info(`[TaskLiveUpdates] Publishing final failure update for task ${this.ctx.taskId}`);\n const result = await this.ctx.sink.fail(this.decorateText(finalText));\n this.recordSinkRef(result);\n this.ctx.appendHistory?.(finalText, 'failed');\n } catch (err) {\n logger.warn(\n `[TaskLiveUpdates] Failed to publish failure update for task ${this.ctx.taskId}: ${\n err instanceof Error ? err.message : String(err)\n }`\n );\n }\n }\n\n stop(): void {\n if (this.firstTickTimer) {\n clearTimeout(this.firstTickTimer);\n this.firstTickTimer = undefined;\n }\n if (this.timer) {\n clearInterval(this.timer);\n this.timer = undefined;\n }\n if (this.metadataRefreshTimer) {\n clearInterval(this.metadataRefreshTimer);\n this.metadataRefreshTimer = undefined;\n }\n }\n\n async tick(): Promise<void> {\n if (this.completed || this.running) return;\n const traceState = this.getTraceState();\n if (!traceState.traceRef && !traceState.traceId) {\n logger.debug(\n `[TaskLiveUpdates] Skipping tick for task ${this.ctx.taskId}: no trace reference available yet`\n );\n return;\n }\n this.running = true;\n try {\n const traceRef = traceState.traceRef || traceState.traceId!;\n const traceSnapshot = await this.deps.serializeTrace(\n traceRef,\n this.ctx.config.maxTraceChars,\n traceState.traceId\n );\n if (this.completed) {\n logger.debug(\n `[TaskLiveUpdates] Aborting in-flight tick for task ${this.ctx.taskId}: task already completed`\n );\n return;\n }\n if (!traceSnapshot || traceSnapshot === '(no trace data available)') {\n logger.debug(\n `[TaskLiveUpdates] Skipping tick for task ${this.ctx.taskId}: no trace data available yet (traceRef=${traceRef})`\n );\n return;\n }\n if (traceSnapshot === this.lastTraceSnapshot) {\n await this.maybePublishStallFallback(traceSnapshot, traceState.traceId);\n logger.debug(\n `[TaskLiveUpdates] Skipping tick for task ${this.ctx.taskId}: trace snapshot unchanged`\n );\n return;\n }\n\n const summary = await this.deps.summarizeProgress({\n requestText: this.ctx.requestText,\n previousUpdate: this.lastUpdateText,\n traceSnapshot,\n config: this.ctx.config,\n startedAt: this.startedAt,\n now: new Date(),\n elapsedSeconds: Math.max(0, Math.floor((Date.now() - this.startedAt.getTime()) / 1000)),\n previousUpdateAt: this.lastUpdateAt,\n secondsSincePreviousUpdate: this.lastUpdateAt\n ? Math.max(0, Math.floor((Date.now() - this.lastUpdateAt.getTime()) / 1000))\n : undefined,\n });\n if (this.completed) {\n logger.debug(\n `[TaskLiveUpdates] Aborting in-flight tick for task ${this.ctx.taskId}: task already completed after summarization`\n );\n return;\n }\n const cleaned = summary?.trim();\n if (!cleaned || cleaned === this.lastUpdateText) {\n await this.maybePublishStallFallback(traceSnapshot, traceState.traceId);\n logger.debug(\n `[TaskLiveUpdates] Skipping tick for task ${this.ctx.taskId}: summary empty or unchanged`\n );\n this.lastTraceSnapshot = traceSnapshot;\n return;\n }\n\n logger.info(\n `[TaskLiveUpdates] Publishing progress update for task ${this.ctx.taskId}: ${cleaned.slice(0, 160)}`\n );\n this.lastSkillMetadata = await this.deps.extractSkillMetadata(traceRef, traceState.traceId);\n this.lastUpdateKind = 'semantic';\n const message = this.decorateProgressText(\n cleaned,\n {\n elapsedSeconds: Math.max(0, Math.floor((Date.now() - this.startedAt.getTime()) / 1000)),\n previousUpdateAt: this.lastUpdateAt,\n secondsSincePreviousUpdate: this.lastUpdateAt\n ? Math.max(0, Math.floor((Date.now() - this.lastUpdateAt.getTime()) / 1000))\n : undefined,\n activatedSkills: this.lastSkillMetadata?.activatedSkills,\n },\n traceState.traceId\n );\n const result = await this.ctx.sink.update(message);\n this.recordSinkRef(result);\n this.ctx.appendHistory?.(cleaned, 'progress');\n this.lastUpdateText = cleaned;\n this.lastUpdateAt = new Date();\n this.lastTraceSnapshot = traceSnapshot;\n this.lastPostedMessage = message;\n this.lastStallFallbackAt = undefined;\n } catch (err) {\n logger.warn(\n `[TaskLiveUpdates] Progress update failed for task ${this.ctx.taskId}: ${\n err instanceof Error ? err.message : String(err)\n }`\n );\n } finally {\n this.running = false;\n }\n }\n\n private async runFirstTick(): Promise<void> {\n if (this.completed) return;\n logger.debug(`[TaskLiveUpdates] Running first scheduled tick for task ${this.ctx.taskId}`);\n await this.tick();\n if (this.completed) return;\n this.timer = setInterval(() => {\n void this.tick();\n }, this.ctx.config.intervalSeconds * 1000);\n if (typeof (this.timer as any)?.unref === 'function') {\n (this.timer as any).unref();\n }\n this.metadataRefreshTimer = setInterval(() => {\n void this.refreshProgressMetadata();\n }, DEFAULT_TASK_LIVE_UPDATE_METADATA_REFRESH_SECONDS * 1000);\n if (typeof (this.metadataRefreshTimer as any)?.unref === 'function') {\n (this.metadataRefreshTimer as any).unref();\n }\n }\n\n private recordSinkRef(result: { ref?: Record<string, unknown> } | null | undefined): void {\n if (result?.ref) this.ctx.onPostedRef?.(result.ref);\n }\n\n private getTraceState(): { traceRef?: string; traceId?: string } {\n const resolved = this.ctx.resolveTraceState?.();\n return {\n traceRef: resolved?.traceRef || this.ctx.traceRef,\n traceId: resolved?.traceId || this.ctx.traceId,\n };\n }\n\n private decorateText(text: string, _traceId?: string): string {\n if (!this.ctx.includeTraceId) return text;\n if (text.includes(`task_id: ${this.ctx.taskId}`)) return text;\n return `${text}\\n\\n\\`task_id: ${this.ctx.taskId}\\``;\n }\n\n private decorateProgressText(\n text: string,\n timing: ProgressTimingMetadata,\n traceId?: string\n ): string {\n const normalized = normalizeProgressSummary(text);\n const blocks = [\n '*Live Update*',\n '_Current task is still running. This message updates in place until the final answer is ready._',\n this.lastUpdateKind === 'stall' ? DEFAULT_TASK_LIVE_UPDATE_STALL_NOTICE : '',\n normalized,\n formatProgressMetadata(timing),\n ].filter(Boolean);\n return this.decorateText(blocks.join('\\n\\n'), traceId);\n }\n\n private async refreshProgressMetadata(): Promise<void> {\n if (this.completed || this.running || !this.lastUpdateText) return;\n const traceState = this.getTraceState();\n const message = this.decorateProgressText(\n this.lastUpdateText,\n {\n elapsedSeconds: Math.max(0, Math.floor((Date.now() - this.startedAt.getTime()) / 1000)),\n previousUpdateAt: this.lastUpdateAt,\n secondsSincePreviousUpdate: this.lastUpdateAt\n ? Math.max(0, Math.floor((Date.now() - this.lastUpdateAt.getTime()) / 1000))\n : undefined,\n activatedSkills: this.lastSkillMetadata?.activatedSkills,\n },\n traceState.traceId\n );\n if (!message || message === this.lastPostedMessage) return;\n if (this.completed) return;\n try {\n logger.debug(\n `[TaskLiveUpdates] Refreshing metadata-only live update for task ${this.ctx.taskId}`\n );\n const result = await this.ctx.sink.update(message);\n this.recordSinkRef(result);\n this.lastPostedMessage = message;\n } catch (err) {\n logger.warn(\n `[TaskLiveUpdates] Metadata refresh failed for task ${this.ctx.taskId}: ${\n err instanceof Error ? err.message : String(err)\n }`\n );\n }\n }\n\n private async maybePublishStallFallback(traceSnapshot: string, traceId?: string): Promise<void> {\n if (this.completed) return;\n const now = new Date();\n if (\n this.lastStallFallbackAt &&\n now.getTime() - this.lastStallFallbackAt.getTime() <\n DEFAULT_TASK_LIVE_UPDATE_STALL_FALLBACK_SECONDS * 1000\n ) {\n return;\n }\n if (\n this.lastUpdateAt &&\n now.getTime() - this.lastUpdateAt.getTime() <\n DEFAULT_TASK_LIVE_UPDATE_STALL_FALLBACK_SECONDS * 1000\n ) {\n return;\n }\n this.lastSkillMetadata = await this.deps.extractSkillMetadata(\n this.getTraceState().traceRef || traceId || '',\n traceId\n );\n\n const fallback = buildStallFallbackSummary(traceSnapshot, this.lastUpdateText);\n const baseText = this.lastUpdateText || fallback;\n if (!baseText) return;\n\n logger.info(\n `[TaskLiveUpdates] Publishing stall notice for task ${this.ctx.taskId}: ${baseText.slice(0, 160)}`\n );\n this.lastUpdateKind = 'stall';\n if (this.completed) return;\n const message = this.decorateProgressText(\n baseText,\n {\n elapsedSeconds: Math.max(0, Math.floor((Date.now() - this.startedAt.getTime()) / 1000)),\n previousUpdateAt: this.lastUpdateAt,\n secondsSincePreviousUpdate: this.lastUpdateAt\n ? Math.max(0, Math.floor((Date.now() - this.lastUpdateAt.getTime()) / 1000))\n : undefined,\n activatedSkills: this.lastSkillMetadata?.activatedSkills,\n },\n traceId\n );\n if (message === this.lastPostedMessage) {\n this.lastStallFallbackAt = now;\n return;\n }\n const result = await this.ctx.sink.update(message);\n this.recordSinkRef(result);\n if (!this.lastUpdateText) {\n this.ctx.appendHistory?.(baseText, 'progress');\n this.lastUpdateText = baseText;\n this.lastUpdateAt = now;\n }\n this.lastPostedMessage = message;\n this.lastStallFallbackAt = now;\n }\n}\n\nasync function defaultSerializeTrace(\n traceRef: string,\n maxChars: number,\n traceId?: string\n): Promise<string | undefined> {\n logger.debug(\n `[TaskLiveUpdates] Serializing trace for progress update (traceRef=${traceRef}, traceId=${traceId || '-'}, sink=${process.env.VISOR_TELEMETRY_SINK || 'auto'})`\n );\n return serializeTraceForPrompt(traceRef, maxChars, undefined, undefined, traceId);\n}\n\nexport async function summarizeTaskProgress(\n input: TaskProgressSummaryInput\n): Promise<string | null> {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const { ProbeAgent } = require('@probelabs/probe');\n\n const agentOptions: Record<string, unknown> = {\n sessionId: `visor-task-progress-${Date.now()}-${crypto.randomUUID().slice(0, 8)}`,\n systemPrompt: input.config.prompt,\n maxIterations: 1,\n disableTools: true,\n };\n if (input.config.model) agentOptions.model = input.config.model;\n if (input.config.provider) agentOptions.provider = input.config.provider;\n\n const agent = new ProbeAgent(agentOptions);\n if (typeof agent.initialize === 'function') {\n await agent.initialize();\n }\n\n const userPrompt = [\n `<user_request>\\n${input.requestText}\\n</user_request>`,\n input.previousUpdate\n ? `<previous_update>\\n${input.previousUpdate}\\n</previous_update>`\n : '<previous_update>(none)</previous_update>',\n `<timing>\\nstarted_at: ${input.startedAt.toISOString()}\\nnow: ${input.now.toISOString()}\\nelapsed: ${formatDuration(input.elapsedSeconds)}\\nlast_update_at: ${input.previousUpdateAt ? input.previousUpdateAt.toISOString() : '(none)'}\\ntime_since_last_update: ${\n input.previousUpdateAt ? formatDuration(input.secondsSincePreviousUpdate || 0) : '(none)'\n }\\n</timing>`,\n `<execution_trace>\\n${input.traceSnapshot}\\n</execution_trace>`,\n ].join('\\n\\n');\n\n const response = await agent.answer(userPrompt);\n const cleaned = response\n .replace(/^```(?:markdown|md|text)?\\s*\\n?/i, '')\n .replace(/\\n?```\\s*$/m, '')\n .trim();\n return cleaned || null;\n}\n\nfunction formatDuration(totalSeconds: number): string {\n const seconds = Math.max(0, Math.floor(totalSeconds));\n const hours = Math.floor(seconds / 3600);\n const minutes = Math.floor((seconds % 3600) / 60);\n const remainingSeconds = seconds % 60;\n const parts: string[] = [];\n if (hours > 0) parts.push(`${hours}h`);\n if (minutes > 0) parts.push(`${minutes}m`);\n if (remainingSeconds > 0 || parts.length === 0) parts.push(`${remainingSeconds}s`);\n return parts.join(' ');\n}\n\nfunction normalizeProgressSummary(text: string): string {\n const wantedLabels = ['Progress', 'Last done', 'Now', 'Waiting on'];\n const lines = text\n .split(/\\r?\\n/)\n .map(line => line.trim())\n .filter(Boolean);\n\n const matched = new Map<string, string>();\n for (const line of lines) {\n const match = line.match(/^-?\\s*(Progress|Last done|Now|Waiting on|Timing)\\s*:\\s*(.+)$/i);\n if (!match) continue;\n const label = match[1].toLowerCase();\n if (label === 'timing') continue;\n const canonical = wantedLabels.find(item => item.toLowerCase() === label);\n if (canonical && !matched.has(canonical)) {\n matched.set(canonical, match[2].trim());\n }\n }\n\n if (matched.size === wantedLabels.length) {\n return wantedLabels.map(label => `- ${label}: ${matched.get(label)}`).join('\\n');\n }\n\n const withoutTiming = lines.filter(line => !/^-?\\s*(Timing|Metadata|Trace)\\s*:/i.test(line));\n return withoutTiming.join('\\n');\n}\n\nfunction formatProgressMetadata(timing: ProgressTimingMetadata): string {\n const parts = [`elapsed ${formatDuration(timing.elapsedSeconds)}`];\n if (timing.previousUpdateAt) {\n parts.push(`previous update ${formatDuration(timing.secondsSincePreviousUpdate || 0)} ago`);\n parts.push(`at ${timing.previousUpdateAt.toISOString()}`);\n } else {\n parts.push('first live update');\n }\n if (timing.activatedSkills && timing.activatedSkills.length > 0) {\n parts.push(`activated skills ${formatSkillList(timing.activatedSkills)}`);\n }\n return `_Metadata: ${parts.join(' | ')}_`;\n}\n\nfunction formatSkillList(skills: string[]): string {\n const normalized = dedupeStrings(skills);\n if (normalized.length <= 4) return normalized.join(', ');\n return `${normalized.slice(0, 4).join(', ')} +${normalized.length - 4} more`;\n}\n\nfunction dedupeStrings(values: string[] | undefined): string[] {\n if (!Array.isArray(values)) return [];\n return [...new Set(values.map(value => String(value || '').trim()).filter(Boolean))];\n}\n\nasync function extractTraceSkillMetadata(\n traceRef: string,\n traceId?: string\n): Promise<TaskLiveUpdateSkillMetadata | undefined> {\n if (!traceRef && !traceId) return undefined;\n try {\n const spans = await fetchTraceSpans(traceId || traceRef);\n if (!spans.length) return undefined;\n\n const routeIntentSpan = spans.find(\n span => span.attributes['visor.check.id'] === 'route-intent'\n );\n const buildConfigSpan = spans.find(\n span => span.attributes['visor.check.id'] === 'build-config'\n );\n const classifySpan = spans.find(span => span.attributes['visor.check.id'] === 'classify');\n\n const routeIntentOutput = parseJsonAttribute(routeIntentSpan?.attributes['visor.check.output']);\n const classifyOutput = parseJsonAttribute(classifySpan?.attributes['visor.check.output']);\n const buildConfigOutput = parseJsonAttribute(buildConfigSpan?.attributes['visor.check.output']);\n\n const activatedSkills = dedupeStrings(\n Array.isArray(buildConfigOutput?.activated_skills)\n ? buildConfigOutput.activated_skills\n : undefined\n );\n\n const fallbackActivatedSkills = dedupeStrings(\n (Array.isArray(routeIntentOutput?.skills) ? routeIntentOutput.skills : undefined) ||\n (Array.isArray(classifyOutput?.skills) ? classifyOutput.skills : undefined)\n );\n\n const finalActivatedSkills =\n activatedSkills.length > 0 ? activatedSkills : fallbackActivatedSkills;\n if (!finalActivatedSkills.length) return undefined;\n return { activatedSkills: finalActivatedSkills };\n } catch (err) {\n logger.debug(\n `[TaskLiveUpdates] Failed to extract skill metadata from trace: ${\n err instanceof Error ? err.message : String(err)\n }`\n );\n return undefined;\n }\n}\n\nfunction parseJsonAttribute(value: unknown): Record<string, any> | undefined {\n if (typeof value !== 'string' || !value.trim()) return undefined;\n try {\n const parsed = JSON.parse(value);\n return parsed && typeof parsed === 'object' ? parsed : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction buildStallFallbackSummary(traceSnapshot: string, previousUpdate?: string): string {\n const lastDone =\n extractProgressField(previousUpdate, 'Last done') ||\n 'continuing from the last completed analysis step';\n\n const lower = traceSnapshot.toLowerCase();\n let now = 'waiting for the current analysis step to finish';\n let waitingOn = 'the current analysis step to complete';\n\n if (\n lower.includes('search.delegate') ||\n lower.includes('tool: search') ||\n lower.includes('search(')\n ) {\n now = 'running or waiting on the current code search step';\n waitingOn = 'search results and downstream analysis to finish';\n } else if (lower.includes('extract(') || lower.includes('tool: extract')) {\n now = 'extracting the relevant code or documentation context';\n waitingOn = 'the extract step to finish and be interpreted';\n } else if (lower.includes('engineer-task') || lower.includes('engineer')) {\n now = 'waiting on the current implementation or validation step';\n waitingOn = 'the engineer workflow to finish the current step';\n } else if (\n lower.includes('ai.request') ||\n lower.includes('gemini') ||\n lower.includes('claude') ||\n lower.includes('openai')\n ) {\n now = 'waiting on the current model analysis step';\n waitingOn = 'the active model response to finish';\n } else if (lower.includes('bash(') || lower.includes('go test') || lower.includes('npm test')) {\n now = 'running or waiting on command-based validation';\n waitingOn = 'the current command or test run to finish';\n } else if (lower.includes('setup-projects') || lower.includes('build-config')) {\n now = 'preparing the workspace and loading the required context';\n waitingOn = 'workspace setup and context loading to finish';\n }\n\n return [\n '- Progress: still working through the same step; no new completed action yet',\n `- Last done: ${lastDone}`,\n `- Now: ${now}`,\n `- Waiting on: ${waitingOn}`,\n ].join('\\n');\n}\n\nfunction extractProgressField(text: string | undefined, label: string): string | undefined {\n if (!text) return undefined;\n const match = text.match(new RegExp(`(?:^|\\\\n)-?\\\\s*${escapeRegExp(label)}\\\\s*:\\\\s*(.+)$`, 'im'));\n return match?.[1]?.trim() || undefined;\n}\n\nfunction escapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/providers/check-provider.interface.ts","../../src/utils/env-resolver.ts","../../src/utils/issue-normalizer.ts","../../src/utils/env-exposure.ts","../../src/providers/utcp-check-provider.ts"],"sourcesContent":["import { PRInfo } from '../pr-analyzer';\nimport { ReviewSummary } from '../reviewer';\nimport { EnvConfig, HumanInputRequest } from '../types/config';\n\n/**\n * Configuration for a check provider\n */\nexport interface CheckProviderConfig {\n type: string;\n prompt?: string;\n eventContext?: Record<string, unknown>;\n focus?: string;\n command?: string; // For PR comment triggers\n exec?: string; // For command execution (supports Liquid templates)\n stdin?: string; // Optional stdin input (supports Liquid templates)\n args?: string[] | Record<string, unknown>; // string[] deprecated for command args; Record for workflow inputs\n command_args?: string[]; // MCP stdio command arguments\n interpreter?: string;\n url?: string;\n method?: string;\n headers?: Record<string, string>;\n timeout?: number;\n metadata?: Record<string, unknown>;\n workingDirectory?: string;\n env?: EnvConfig;\n ai?: import('../types/config').AIProviderConfig;\n /** AI model to use for this check - overrides global setting */\n ai_model?: string;\n /** AI provider to use for this check - overrides global setting */\n ai_provider?: 'google' | 'anthropic' | 'openai' | string;\n /** Check name for sessionID and logging purposes */\n checkName?: string;\n /** Session ID for AI session management */\n sessionId?: string;\n /** Script content for 'script' provider */\n content?: string;\n [key: string]: unknown;\n}\n\n/**\n * Execution context passed to check providers\n */\nexport interface ExecutionContext {\n /** Session information for AI session reuse */\n parentSessionId?: string;\n reuseSession?: boolean;\n /** CLI message value (from --message argument) */\n cliMessage?: string;\n /** Conversation context - unified access to user message across transports (CLI, Slack, etc.) */\n conversation?: import('../types/bot').ConversationContext;\n /**\n * Stage-local baseline of output history lengths per check name.\n * When present, providers should expose an `outputs_history_stage` object in\n * Liquid/JS contexts that slices the global history from this baseline.\n * This enables stage-scoped assertions in the YAML test runner without\n * relying on global execution history.\n */\n stageHistoryBase?: Record<string, number>;\n /** Workflow inputs - available when executing within a workflow */\n workflowInputs?: Record<string, unknown>;\n /** Custom arguments passed from on_init 'with' directive */\n args?: Record<string, unknown>;\n /** SDK hooks for human input and check completion */\n hooks?: {\n onHumanInput?: (request: HumanInputRequest) => Promise<string>;\n onPromptCaptured?: (info: { step: string; provider: string; prompt: string }) => void;\n mockForStep?: (step: string) => unknown | undefined;\n /** Returns true if the mock for a step has been consumed (for loop termination) */\n isMockExhausted?: (step: string) => boolean;\n /** Called when a check completes - useful for streaming TUI updates */\n onCheckComplete?: (info: {\n checkId: string;\n result: { output?: unknown; content?: string };\n checkConfig?: { type?: string; group?: string; criticality?: string; schema?: unknown };\n }) => void;\n };\n /**\n * Optional execution mode hints. The core engine does not read environment\n * variables directly; callers (CLI, test runner) can set these flags to\n * request certain behaviors without polluting core logic with test-specific\n * branches.\n */\n mode?: {\n /** true when running under the YAML test runner */\n test?: boolean;\n /** post review comments from grouped execution paths (used by tests) */\n postGroupedComments?: boolean;\n /** reset per-run guard state before grouped execution */\n resetPerRunState?: boolean;\n };\n /**\n * Absolute timestamp (ms since epoch) by which this execution must complete.\n * Set by the engine from `Date.now() + timeout` and inherited by sub-workflows\n * so nested steps know how much time the parent has left.\n */\n deadline?: number;\n /** Optional event bus for emitting integration events (e.g., HumanInputRequested) */\n eventBus?: import('../event-bus/event-bus').EventBus;\n /** Optional webhook context (e.g., Slack Events API payload) */\n webhookContext?: { webhookData?: Map<string, unknown>; eventType?: string };\n /**\n * Callback for capturing AI responses - used by scheduler to store previousResponse\n * for recurring reminders. The text passed is the AI response before mrkdwn formatting.\n */\n responseCapture?: (text: string) => void;\n}\n\n/**\n * Abstract base class for all check providers\n * Implementing classes provide specific check functionality (AI, tool, script, etc.)\n */\nexport abstract class CheckProvider {\n /**\n * Get the unique name/type of this provider\n */\n abstract getName(): string;\n\n /**\n * Get a human-readable description of this provider\n */\n abstract getDescription(): string;\n\n /**\n * Validate provider-specific configuration\n * @param config The configuration to validate\n * @returns true if configuration is valid, false otherwise\n */\n abstract validateConfig(config: unknown): Promise<boolean>;\n\n /**\n * Execute the check on the given PR information\n * @param prInfo Information about the pull request\n * @param config Provider-specific configuration\n * @param dependencyResults Optional results from dependency checks that this check depends on\n * @param context Optional execution context with session info, hooks, and CLI state\n * @returns Review summary with scores, issues, and comments\n */\n abstract execute(\n prInfo: PRInfo,\n config: CheckProviderConfig,\n dependencyResults?: Map<string, ReviewSummary>,\n context?: ExecutionContext\n ): Promise<ReviewSummary>;\n\n /**\n * Get the list of configuration keys this provider supports\n * Used for documentation and validation\n */\n abstract getSupportedConfigKeys(): string[];\n\n /**\n * Check if this provider is available (e.g., has required API keys)\n * @returns true if provider can be used, false otherwise\n */\n abstract isAvailable(): Promise<boolean>;\n\n /**\n * Get provider requirements (e.g., environment variables needed)\n */\n abstract getRequirements(): string[];\n\n /**\n * Set webhook context for providers that need access to webhook data\n * This is optional and only used by http_input providers\n * @param webhookContext Map of endpoint paths to webhook data\n */\n setWebhookContext?(webhookContext: Map<string, unknown>): void;\n}\n","/**\n * Environment variable resolution utilities\n * Supports GitHub Actions-like syntax for referencing environment variables\n */\n\nimport { EnvConfig } from '../types/config';\n\n/**\n * Resolves environment variables in configuration values\n * Supports the following syntaxes:\n * - ${{ env.VARIABLE_NAME }} (GitHub Actions style)\n * - ${VARIABLE_NAME} (shell style)\n * - $VARIABLE_NAME (simple shell style)\n * - Direct environment variable names\n */\nexport class EnvironmentResolver {\n /**\n * Resolves a single configuration value that may contain environment variable references\n */\n static resolveValue(value: string | number | boolean): string | number | boolean {\n if (typeof value !== 'string') {\n return value;\n }\n\n // GitHub Actions style: ${{ env.VARIABLE_NAME }}\n let resolved = value.replace(/\\$\\{\\{\\s*env\\.([A-Z_][A-Z0-9_]*)\\s*\\}\\}/g, (match, envVar) => {\n return process.env[envVar] || match;\n });\n\n // Shell style: ${VARIABLE_NAME}\n resolved = resolved.replace(/\\$\\{([A-Z_][A-Z0-9_]*)\\}/g, (match, envVar) => {\n return process.env[envVar] || match;\n });\n\n // Simple shell style: $VARIABLE_NAME\n resolved = resolved.replace(/\\$([A-Z_][A-Z0-9_]*)/g, (match, envVar) => {\n return process.env[envVar] || match;\n });\n\n return resolved;\n }\n\n /**\n * Resolves all environment variables in an EnvConfig object\n */\n static resolveEnvConfig(envConfig: EnvConfig): EnvConfig {\n const resolved: EnvConfig = {};\n\n for (const [key, value] of Object.entries(envConfig)) {\n resolved[key] = this.resolveValue(value);\n }\n\n return resolved;\n }\n\n /**\n * Applies environment configuration to the process environment\n * This allows checks to access their specific environment variables\n */\n static applyEnvConfig(envConfig: EnvConfig): void {\n const resolved = this.resolveEnvConfig(envConfig);\n\n for (const [key, value] of Object.entries(resolved)) {\n if (value !== undefined) {\n process.env[key] = String(value);\n }\n }\n }\n\n /**\n * Creates a temporary environment for a specific check execution\n * Returns a cleanup function to restore the original environment\n */\n static withTemporaryEnv<T>(envConfig: EnvConfig, callback: () => T | Promise<T>): T | Promise<T> {\n const resolved = this.resolveEnvConfig(envConfig);\n const originalValues: Record<string, string | undefined> = {};\n\n // Store original values and apply new ones\n for (const [key, value] of Object.entries(resolved)) {\n originalValues[key] = process.env[key];\n if (value !== undefined) {\n process.env[key] = String(value);\n }\n }\n\n try {\n const result = callback();\n\n // If callback returns a promise, handle cleanup after it resolves\n if (result instanceof Promise) {\n return result.finally(() => {\n // Restore original values\n for (const [key, originalValue] of Object.entries(originalValues)) {\n if (originalValue === undefined) {\n delete process.env[key];\n } else {\n process.env[key] = originalValue;\n }\n }\n });\n }\n\n // Restore original values immediately for sync callbacks\n for (const [key, originalValue] of Object.entries(originalValues)) {\n if (originalValue === undefined) {\n delete process.env[key];\n } else {\n process.env[key] = originalValue;\n }\n }\n\n return result;\n } catch (error) {\n // Restore original values on error\n for (const [key, originalValue] of Object.entries(originalValues)) {\n if (originalValue === undefined) {\n delete process.env[key];\n } else {\n process.env[key] = originalValue;\n }\n }\n throw error;\n }\n }\n\n /**\n * Validates that all required environment variables are available\n */\n static validateRequiredEnvVars(envConfig: EnvConfig, requiredVars: string[]): string[] {\n const resolved = this.resolveEnvConfig(envConfig);\n const missing: string[] = [];\n\n for (const varName of requiredVars) {\n const value = resolved[varName] || process.env[varName];\n if (!value) {\n missing.push(varName);\n }\n }\n\n return missing;\n }\n\n /**\n * Resolves environment variables in HTTP headers\n * Each header value is processed through resolveValue to replace env var references\n */\n static resolveHeaders(headers: Record<string, string>): Record<string, string> {\n const resolved: Record<string, string> = {};\n for (const [key, value] of Object.entries(headers)) {\n resolved[key] = String(this.resolveValue(value));\n }\n return resolved;\n }\n\n /**\n * Sanitizes headers for logging/telemetry by redacting sensitive values\n * Headers like Authorization, API keys, and cookies are replaced with [REDACTED]\n */\n static sanitizeHeaders(headers: Record<string, string>): Record<string, string> {\n const sensitiveHeaders = ['authorization', 'x-api-key', 'cookie', 'set-cookie'];\n const sanitized: Record<string, string> = {};\n\n for (const [key, value] of Object.entries(headers)) {\n if (sensitiveHeaders.includes(key.toLowerCase())) {\n sanitized[key] = '[REDACTED]';\n } else {\n sanitized[key] = value;\n }\n }\n\n return sanitized;\n }\n}\n","/**\n * Shared issue normalization utilities.\n *\n * Used by MCP, UTCP, and command providers to extract and normalize\n * ReviewIssue objects from tool/command output.\n */\nimport { ReviewIssue } from '../reviewer';\n\n/**\n * Extract issues from tool output.\n * Handles: JSON strings, arrays of issues, objects with `issues` property, single issue objects.\n */\nexport function extractIssuesFromOutput(\n output: unknown,\n defaultRuleId?: string\n): { issues: ReviewIssue[]; remainingOutput: unknown } | null {\n if (output === null || output === undefined) {\n return null;\n }\n\n // If output is a string, try to parse as JSON\n if (typeof output === 'string') {\n try {\n const parsed = JSON.parse(output);\n return extractIssuesFromOutput(parsed, defaultRuleId);\n } catch {\n return null;\n }\n }\n\n // If output is an array of issues\n if (Array.isArray(output)) {\n const issues = normalizeIssueArray(output, defaultRuleId);\n if (issues) {\n return { issues, remainingOutput: undefined };\n }\n return null;\n }\n\n // If output is an object with issues property\n if (typeof output === 'object') {\n const record = output as Record<string, unknown>;\n\n if (Array.isArray(record.issues)) {\n const issues = normalizeIssueArray(record.issues, defaultRuleId);\n if (!issues) {\n return null;\n }\n\n const remaining = { ...record };\n delete (remaining as { issues?: unknown }).issues;\n\n return {\n issues,\n remainingOutput: Object.keys(remaining).length > 0 ? remaining : undefined,\n };\n }\n\n // Check if output itself is a single issue\n const singleIssue = normalizeIssue(record, defaultRuleId);\n if (singleIssue) {\n return { issues: [singleIssue], remainingOutput: undefined };\n }\n }\n\n return null;\n}\n\n/**\n * Normalize an array of issues. Returns null if any element cannot be normalized.\n */\nexport function normalizeIssueArray(\n values: unknown[],\n defaultRuleId?: string\n): ReviewIssue[] | null {\n const normalized: ReviewIssue[] = [];\n for (const value of values) {\n const issue = normalizeIssue(value, defaultRuleId);\n if (!issue) {\n return null;\n }\n normalized.push(issue);\n }\n return normalized;\n}\n\n/**\n * Normalize a single issue from raw data.\n * Accepts various field aliases (message/text/description, severity/level/priority, etc.)\n */\nexport function normalizeIssue(raw: unknown, defaultRuleId = 'tool'): ReviewIssue | null {\n if (!raw || typeof raw !== 'object') {\n return null;\n }\n\n const data = raw as Record<string, unknown>;\n\n // Only accept string values for issue message fields.\n // Non-string values (e.g. Slack's `message: {text: \"...\", ...}` object)\n // must not be coerced — they are API payloads, not issue descriptions.\n const rawMessage = data.message || data.text || data.description || data.summary;\n if (typeof rawMessage !== 'string') {\n return null;\n }\n const message = rawMessage.trim();\n if (!message) {\n return null;\n }\n\n const allowedSeverities = new Set(['info', 'warning', 'error', 'critical']);\n const severityRaw = toTrimmedString(data.severity || data.level || data.priority);\n let severity: ReviewIssue['severity'] = 'warning';\n if (severityRaw) {\n const lower = severityRaw.toLowerCase();\n if (allowedSeverities.has(lower)) {\n severity = lower as ReviewIssue['severity'];\n }\n }\n\n const allowedCategories = new Set(['security', 'performance', 'style', 'logic', 'documentation']);\n const categoryRaw = toTrimmedString(data.category || data.type || data.group);\n let category: ReviewIssue['category'] = 'logic';\n if (categoryRaw && allowedCategories.has(categoryRaw.toLowerCase())) {\n category = categoryRaw.toLowerCase() as ReviewIssue['category'];\n }\n\n const file = toTrimmedString(data.file || data.path || data.filename) || 'system';\n const line = toNumber(data.line || data.startLine || data.lineNumber) ?? 0;\n const endLine = toNumber(data.endLine || data.end_line || data.stopLine);\n const suggestion = toTrimmedString(data.suggestion);\n const replacement = toTrimmedString(data.replacement);\n const ruleId =\n toTrimmedString(data.ruleId || data.rule || data.id || data.check) || defaultRuleId;\n\n return {\n file,\n line,\n endLine: endLine ?? undefined,\n ruleId,\n message,\n severity,\n category,\n suggestion: suggestion || undefined,\n replacement: replacement || undefined,\n };\n}\n\nexport function toTrimmedString(value: unknown): string | null {\n if (typeof value === 'string') {\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : null;\n }\n if (value !== null && value !== undefined && typeof value.toString === 'function') {\n const converted = String(value).trim();\n return converted.length > 0 ? converted : null;\n }\n return null;\n}\n\nexport function toNumber(value: unknown): number | null {\n if (value === null || value === undefined) {\n return null;\n }\n const num = Number(value);\n if (Number.isFinite(num)) {\n return Math.trunc(num);\n }\n return null;\n}\n","export type EnvMap = Record<string, string>;\n\n// Default: expose all env vars except a conservative denylist.\n// If VISOR_ALLOW_ENV is set and not '*', restrict to that allowlist.\n// VISOR_DENY_ENV can further mask exact keys or prefix* patterns.\nexport function buildSandboxEnv(input: NodeJS.ProcessEnv): EnvMap {\n const denyDefaults = [\n 'GITHUB_TOKEN',\n 'INPUT_GITHUB-TOKEN',\n 'ACTIONS_RUNTIME_TOKEN',\n 'ACTIONS_ID_TOKEN_REQUEST_TOKEN',\n 'AWS_ACCESS_KEY_ID',\n 'AWS_SECRET_ACCESS_KEY',\n 'AWS_SESSION_TOKEN',\n 'AZURE_CLIENT_SECRET',\n 'GOOGLE_APPLICATION_CREDENTIALS',\n 'OPENAI_API_KEY',\n 'ANTHROPIC_API_KEY',\n 'HUGGINGFACE_API_KEY',\n 'CLAUDE_CODE_API_KEY',\n 'PROBE_API_KEY',\n ];\n\n const denyExtra = (input.VISOR_DENY_ENV || '')\n .split(',')\n .map(s => s.trim())\n .filter(Boolean);\n const deny = Array.from(new Set([...denyDefaults, ...denyExtra]));\n const allowSpec = (input.VISOR_ALLOW_ENV || '*').trim();\n\n const denyMatch = (key: string): boolean => {\n for (const pat of deny) {\n if (!pat) continue;\n if (pat.endsWith('*')) {\n const prefix = pat.slice(0, -1);\n if (key.startsWith(prefix)) return true;\n } else if (key === pat) {\n return true;\n }\n }\n if (/(_TOKEN|_SECRET|_PASSWORD|_PRIVATE_KEY)$/i.test(key)) return true;\n return false;\n };\n\n const out: EnvMap = {};\n if (allowSpec !== '*') {\n const allow = allowSpec\n .split(',')\n .map(s => s.trim())\n .filter(Boolean);\n for (const key of allow) {\n const val = input[key];\n if (key && val !== undefined && !denyMatch(key)) out[key] = String(val);\n }\n return out;\n }\n\n for (const [k, v] of Object.entries(input)) {\n if (v === undefined || v === null) continue;\n if (denyMatch(k)) continue;\n out[k] = String(v);\n }\n return out;\n}\n","import { CheckProvider, CheckProviderConfig } from './check-provider.interface';\nimport { PRInfo } from '../pr-analyzer';\nimport { ReviewSummary, ReviewIssue } from '../reviewer';\nimport { logger } from '../logger';\nimport { Liquid } from 'liquidjs';\nimport { createExtendedLiquid } from '../liquid-extensions';\nimport Sandbox from '@nyariv/sandboxjs';\nimport { createSecureSandbox, compileAndRun } from '../utils/sandbox';\nimport { EnvironmentResolver } from '../utils/env-resolver';\nimport { extractIssuesFromOutput } from '../utils/issue-normalizer';\nimport * as fs from 'fs';\nimport * as path from 'path';\n\n/**\n * UTCP Check Provider Configuration\n */\nexport interface UtcpCheckConfig extends CheckProviderConfig {\n /** UTCP manual source: URL string, file path string, or inline call template object */\n manual: string | Record<string, unknown>;\n /** Tool method name to call (format: manual_name.tool_name or just tool_name) */\n method: string;\n /** Arguments to pass to the UTCP tool (supports Liquid templates) */\n methodArgs?: Record<string, unknown>;\n /** Transform template for method arguments (Liquid) - overrides methodArgs */\n argsTransform?: string;\n /** UTCP variables for manual authentication/configuration */\n variables?: Record<string, string>;\n /** UTCP plugins to load (default: ['http']) */\n plugins?: string[];\n /** Transform template for output (Liquid) */\n transform?: string;\n /** Transform using JavaScript expressions */\n transform_js?: string;\n /** Timeout in seconds (default: 60) */\n timeout?: number;\n}\n\n/**\n * Check provider that calls UTCP (Universal Tool Calling Protocol) tools directly.\n * UTCP is a client-side protocol where tools publish JSON \"manuals\" describing\n * how to call them via their native protocols (HTTP, CLI, SSE, etc.).\n *\n * Supports manual discovery from:\n * - HTTP/HTTPS URLs (GET endpoint returning UTCP manual)\n * - Local JSON files\n * - Inline call template objects\n */\nexport class UtcpCheckProvider extends CheckProvider {\n private liquid: Liquid;\n private sandbox?: Sandbox;\n private sdkAvailable: boolean | null = null;\n\n constructor() {\n super();\n this.liquid = createExtendedLiquid({\n cache: false,\n strictFilters: false,\n strictVariables: false,\n });\n }\n\n getName(): string {\n return 'utcp';\n }\n\n getDescription(): string {\n return 'Call UTCP tools directly using their native protocols (HTTP, CLI, SSE)';\n }\n\n async validateConfig(config: unknown): Promise<boolean> {\n if (!config || typeof config !== 'object') {\n return false;\n }\n\n const cfg = config as UtcpCheckConfig;\n\n // Type must be utcp\n if (cfg.type !== 'utcp') {\n return false;\n }\n\n // Manual is required\n if (!cfg.manual) {\n logger.error('UTCP check requires a manual (URL, file path, or inline call template)');\n return false;\n }\n\n // Method is required\n if (!cfg.method || typeof cfg.method !== 'string') {\n logger.error('UTCP check requires a method name');\n return false;\n }\n\n // Validate manual format\n if (typeof cfg.manual === 'string') {\n // URL validation\n if (cfg.manual.startsWith('http://') || cfg.manual.startsWith('https://')) {\n try {\n const parsedUrl = new URL(cfg.manual);\n if (parsedUrl.protocol !== 'http:' && parsedUrl.protocol !== 'https:') {\n logger.error(`Invalid URL protocol for UTCP manual: ${parsedUrl.protocol}`);\n return false;\n }\n } catch {\n logger.error(`Invalid URL format for UTCP manual: ${cfg.manual}`);\n return false;\n }\n }\n // File paths are validated at execution time\n } else if (typeof cfg.manual === 'object') {\n // Inline call template must have call_template_type\n if (!cfg.manual.call_template_type) {\n logger.error('Inline UTCP manual must have call_template_type');\n return false;\n }\n } else {\n logger.error('UTCP manual must be a URL string, file path, or inline call template object');\n return false;\n }\n\n return true;\n }\n\n async execute(\n prInfo: PRInfo,\n config: CheckProviderConfig,\n dependencyResults?: Map<string, ReviewSummary>,\n sessionInfo?: any\n ): Promise<ReviewSummary> {\n const cfg = config as UtcpCheckConfig;\n\n // Test hook: mock output for this step\n try {\n const stepName = (config as any).checkName || 'unknown';\n const mock = sessionInfo?.hooks?.mockForStep?.(String(stepName));\n if (mock !== undefined) {\n const ms = mock as any;\n const issuesArr = Array.isArray(ms?.issues) ? (ms.issues as any[]) : [];\n const out = ms && typeof ms === 'object' && 'output' in ms ? ms.output : ms;\n return {\n issues: issuesArr,\n ...(out !== undefined ? { output: out } : {}),\n } as ReviewSummary;\n }\n } catch {}\n\n try {\n // Build template context\n const templateContext = {\n pr: {\n number: prInfo.number,\n title: prInfo.title,\n author: prInfo.author,\n branch: prInfo.head,\n base: prInfo.base,\n },\n files: prInfo.files,\n fileCount: prInfo.files.length,\n outputs: this.buildOutputContext(dependencyResults),\n args: sessionInfo?.args || {},\n env: this.getSafeEnvironmentVariables(),\n inputs: (config as any).workflowInputs || sessionInfo?.workflowInputs || {},\n };\n\n // Render method arguments\n let methodArgs = cfg.methodArgs || {};\n if (cfg.argsTransform) {\n const rendered = await this.liquid.parseAndRender(cfg.argsTransform, templateContext);\n try {\n methodArgs = JSON.parse(rendered);\n } catch (error) {\n logger.error(`Failed to parse argsTransform as JSON: ${error}`);\n return {\n issues: [\n {\n file: 'utcp',\n line: 0,\n ruleId: 'utcp/args_transform_error',\n message: `Failed to parse argsTransform: ${error instanceof Error ? error.message : 'Unknown error'}`,\n severity: 'error',\n category: 'logic',\n },\n ],\n };\n }\n } else if (methodArgs && typeof methodArgs === 'object') {\n // Recursively render Liquid templates in methodArgs\n const renderValue = async (val: unknown): Promise<unknown> => {\n if (typeof val === 'string' && (val.includes('{{') || val.includes('{%'))) {\n return await this.liquid.parseAndRender(val, templateContext);\n } else if (val && typeof val === 'object' && !Array.isArray(val)) {\n const rendered: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(val)) {\n rendered[k] = await renderValue(v);\n }\n return rendered;\n } else if (Array.isArray(val)) {\n return Promise.all(val.map(item => renderValue(item)));\n }\n return val;\n };\n methodArgs = (await renderValue(methodArgs)) as Record<string, unknown>;\n }\n\n // Resolve variables through environment resolver\n const resolvedVariables: Record<string, string> = {};\n if (cfg.variables) {\n for (const [key, value] of Object.entries(cfg.variables)) {\n resolvedVariables[key] = String(EnvironmentResolver.resolveValue(value));\n }\n }\n\n // Call tool via shared static method (handles SDK import, client lifecycle, timeout)\n const result = await UtcpCheckProvider.callTool(cfg.manual, cfg.method, methodArgs, {\n variables: resolvedVariables,\n plugins: cfg.plugins || ['http'],\n timeoutMs: (cfg.timeout || 60) * 1000,\n });\n\n {\n // Apply transforms\n let finalOutput = result;\n\n // Apply Liquid transform\n if (cfg.transform) {\n try {\n const transformContext = {\n ...templateContext,\n output: result,\n };\n const rendered = await this.liquid.parseAndRender(cfg.transform, transformContext);\n try {\n finalOutput = JSON.parse(rendered.trim());\n } catch {\n finalOutput = rendered.trim();\n }\n } catch (error) {\n logger.error(`Failed to apply Liquid transform: ${error}`);\n // Throw to let the outer finally close the client before returning\n throw new Error(\n `Failed to apply transform: ${error instanceof Error ? error.message : 'Unknown error'}`\n );\n }\n }\n\n // Apply JavaScript transform\n if (cfg.transform_js) {\n try {\n this.sandbox = createSecureSandbox();\n const scope = {\n output: finalOutput,\n pr: templateContext.pr,\n files: templateContext.files,\n outputs: templateContext.outputs,\n env: templateContext.env,\n };\n finalOutput = compileAndRun<unknown>(\n this.sandbox,\n `return (${cfg.transform_js});`,\n scope,\n { injectLog: true, wrapFunction: false, logPrefix: '[utcp:transform_js]' }\n );\n } catch (error) {\n logger.error(`Failed to apply JavaScript transform: ${error}`);\n // Throw to let the outer finally close the client before returning\n throw new Error(\n `Failed to apply JavaScript transform: ${error instanceof Error ? error.message : 'Unknown error'}`\n );\n }\n }\n\n // Extract issues from output\n const extracted = extractIssuesFromOutput(finalOutput, 'utcp');\n if (extracted) {\n return {\n issues: extracted.issues,\n ...(extracted.remainingOutput ? { output: extracted.remainingOutput } : {}),\n } as ReviewSummary;\n }\n\n // Return output directly\n return {\n issues: [],\n ...(finalOutput ? { output: finalOutput } : {}),\n } as ReviewSummary;\n }\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\n const isTimeout = this.isTimeoutError(error);\n const severity: ReviewIssue['severity'] = isTimeout ? 'warning' : 'error';\n const ruleId = isTimeout ? 'utcp/timeout' : 'utcp/execution_error';\n\n if (isTimeout) {\n logger.warn(`UTCP check timed out: ${errorMessage}`);\n } else {\n logger.error(`UTCP check failed: ${errorMessage}`);\n }\n\n return {\n issues: [\n {\n file: 'utcp',\n line: 0,\n ruleId,\n message: isTimeout\n ? `UTCP check timed out: ${errorMessage}`\n : `UTCP check failed: ${errorMessage}`,\n severity,\n category: 'logic',\n },\n ],\n };\n }\n }\n\n /**\n * Resolve manual config to a UTCP call template object.\n * Shared utility used by both the standalone UTCP provider and the AI check provider's UTCP-to-MCP bridge.\n */\n static async resolveManualCallTemplate(\n manual: string | Record<string, unknown>\n ): Promise<Record<string, unknown>> {\n if (typeof manual === 'object') {\n if (!manual.call_template_type) {\n throw new Error('Inline manual must have call_template_type');\n }\n // Ensure it has a name\n if (!manual.name) {\n manual.name = 'inline';\n }\n return manual;\n }\n\n // URL-based discovery\n if (manual.startsWith('http://') || manual.startsWith('https://')) {\n return {\n name: UtcpCheckProvider.deriveManualName(manual),\n call_template_type: 'http',\n url: manual,\n http_method: 'GET',\n };\n }\n\n // File-based discovery\n\n // Security: reject null bytes that could bypass path validation\n if (manual.includes('\\0')) {\n throw new Error('Invalid UTCP manual path: null bytes are not allowed');\n }\n\n const resolvedPath = path.resolve(manual);\n\n // Security: ensure resolved path stays within cwd (prevent path traversal)\n const cwd = path.resolve(process.cwd());\n const normalizedResolved = path.normalize(resolvedPath);\n const cwdPrefix = cwd.endsWith(path.sep) ? cwd : cwd + path.sep;\n if (normalizedResolved !== cwd && !normalizedResolved.startsWith(cwdPrefix)) {\n throw new Error(\n `Path traversal detected: \"${manual}\" resolves outside the project directory. ` +\n `UTCP manual paths must be within the project directory.`\n );\n }\n\n // Security: resolve symlinks and re-validate to prevent symlink attacks\n if (fs.existsSync(resolvedPath)) {\n const realPath = fs.realpathSync(resolvedPath);\n if (realPath !== cwd && !realPath.startsWith(cwdPrefix)) {\n throw new Error(\n `Symlink traversal detected: \"${manual}\" points outside the project directory via symlink.`\n );\n }\n }\n\n // Validate file exists and is readable\n if (!fs.existsSync(resolvedPath)) {\n throw new Error(`UTCP manual file not found: ${resolvedPath}`);\n }\n\n // Read and parse the file\n let content: string;\n try {\n content = fs.readFileSync(resolvedPath, 'utf-8');\n } catch (err) {\n throw new Error(\n `Failed to read UTCP manual file: ${resolvedPath}: ${err instanceof Error ? err.message : 'Unknown error'}`\n );\n }\n\n let parsed: Record<string, unknown>;\n try {\n parsed = JSON.parse(content);\n } catch (err) {\n throw new Error(\n `Failed to parse UTCP manual file as JSON: ${resolvedPath}: ${err instanceof Error ? err.message : 'Unknown error'}`\n );\n }\n\n if (parsed.call_template_type) {\n // File contains a call template directly - use as-is\n if (!parsed.name) {\n parsed.name = path.basename(resolvedPath, path.extname(resolvedPath));\n }\n return parsed;\n }\n\n // File contains a UTCP manual - use file call template to let SDK handle it\n // Load the file plugin for file-based manuals\n try {\n await import('@utcp/file');\n } catch {\n logger.debug('UTCP @utcp/file plugin not available, attempting direct parse');\n }\n\n return {\n name: parsed.name || path.basename(resolvedPath, path.extname(resolvedPath)),\n call_template_type: 'file',\n file_path: resolvedPath,\n allowed_communication_protocols: ['file', 'http', 'https'],\n };\n }\n\n /**\n * Derive a manual name from a URL.\n * Shared utility for UTCP manual name derivation.\n */\n static deriveManualName(url: string): string {\n try {\n const parsed = new URL(url);\n // Use hostname with dots replaced by underscores\n return parsed.hostname.replace(/\\./g, '_').replace(/-/g, '_');\n } catch {\n return 'utcp_manual';\n }\n }\n\n /**\n * Call a UTCP tool directly. Shared by both the standalone provider and the MCP-bridge SSE server.\n * Handles SDK import, plugin loading, client creation, tool calling, and cleanup.\n */\n static async callTool(\n manual: string | Record<string, unknown>,\n toolName: string,\n args: Record<string, unknown>,\n options?: {\n variables?: Record<string, string>;\n plugins?: string[];\n timeoutMs?: number;\n }\n ): Promise<unknown> {\n const variables = options?.variables || {};\n const plugins = options?.plugins || ['http'];\n const timeoutMs = options?.timeoutMs || 60000;\n\n // Dynamic import UTCP SDK and plugins\n const { UtcpClient } = await import('@utcp/sdk');\n for (const plugin of plugins) {\n try {\n await import(`@utcp/${plugin}`);\n } catch {\n logger.debug(`UTCP plugin @utcp/${plugin} not available`);\n }\n }\n\n // Resolve manual to call template\n const callTemplate = await UtcpCheckProvider.resolveManualCallTemplate(manual);\n\n // Create client\n const client = await UtcpClient.create(process.cwd(), {\n manual_call_templates: [callTemplate],\n variables,\n } as any);\n\n try {\n // Resolve tool name - try exact match first, then suffix match\n let resolvedToolName = toolName;\n try {\n const tools = await client.getTools();\n const toolNames = tools.map((t: any) => t.name as string);\n logger.debug(`UTCP tools available: ${JSON.stringify(toolNames)}`);\n\n if (!toolNames.includes(resolvedToolName)) {\n const suffixMatch = toolNames.find((name: string) =>\n name.endsWith(`.${resolvedToolName}`)\n );\n if (suffixMatch) {\n logger.debug(\n `UTCP method '${resolvedToolName}' resolved to '${suffixMatch}' via suffix match`\n );\n resolvedToolName = suffixMatch;\n }\n }\n } catch (err) {\n logger.debug(`Failed to list UTCP tools for name resolution: ${err}`);\n }\n\n // Call tool with timeout (clear timer on success to avoid resource leak)\n let timer: ReturnType<typeof setTimeout> | undefined;\n const result = await Promise.race([\n client.callTool(resolvedToolName, args as Record<string, any>),\n new Promise<never>((_, reject) => {\n timer = setTimeout(\n () => reject(new Error(`UTCP tool '${toolName}' timed out after ${timeoutMs}ms`)),\n timeoutMs\n );\n }),\n ]).finally(() => clearTimeout(timer));\n\n return result;\n } finally {\n try {\n if (typeof (client as any).close === 'function') {\n await (client as any).close();\n }\n } catch {}\n }\n }\n\n /**\n * Check if an error is a timeout error\n */\n private isTimeoutError(error: unknown): boolean {\n const err = error as { message?: unknown; code?: unknown; cause?: unknown };\n const message = typeof err?.message === 'string' ? err.message.toLowerCase() : '';\n const code = typeof err?.code === 'string' ? err.code.toLowerCase() : '';\n return message.includes('timeout') || message.includes('timed out') || code.includes('timeout');\n }\n\n /**\n * Build output context from dependency results\n */\n private buildOutputContext(\n dependencyResults?: Map<string, ReviewSummary>\n ): Record<string, unknown> {\n if (!dependencyResults) {\n return {};\n }\n const outputs: Record<string, unknown> = {};\n for (const [checkName, result] of dependencyResults) {\n const summary = result as ReviewSummary & { output?: unknown };\n outputs[checkName] = summary.output !== undefined ? summary.output : summary;\n }\n return outputs;\n }\n\n /**\n * Get safe environment variables\n */\n private getSafeEnvironmentVariables(): Record<string, string> {\n const safeVars: Record<string, string> = {};\n const { buildSandboxEnv } = require('../utils/env-exposure');\n const merged = buildSandboxEnv(process.env);\n for (const [key, value] of Object.entries(merged)) {\n safeVars[key] = String(value);\n }\n safeVars['PWD'] = process.cwd();\n return safeVars;\n }\n\n getSupportedConfigKeys(): string[] {\n return [\n 'type',\n 'manual',\n 'method',\n 'methodArgs',\n 'argsTransform',\n 'variables',\n 'plugins',\n 'transform',\n 'transform_js',\n 'timeout',\n 'depends_on',\n 'on',\n 'if',\n 'group',\n ];\n }\n\n async isAvailable(): Promise<boolean> {\n if (this.sdkAvailable !== null) {\n return this.sdkAvailable;\n }\n try {\n await import('@utcp/sdk');\n this.sdkAvailable = true;\n } catch {\n this.sdkAvailable = false;\n }\n return this.sdkAvailable;\n }\n\n getRequirements(): string[] {\n return [\n '@utcp/sdk package installed',\n 'UTCP manual source (URL, file path, or inline)',\n 'Tool method name',\n ];\n }\n}\n"],"mappings":"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","names":["buildSandboxEnv"]}
|