@probelabs/visor 0.1.130 → 0.1.131
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -0
- package/defaults/visor.yaml +5 -2
- package/dist/ai-review-service.d.ts +2 -0
- package/dist/ai-review-service.d.ts.map +1 -1
- package/dist/cli-main.d.ts.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/config/cli-handler.d.ts +5 -0
- package/dist/config/cli-handler.d.ts.map +1 -0
- package/dist/config/config-reloader.d.ts +24 -0
- package/dist/config/config-reloader.d.ts.map +1 -0
- package/dist/config/config-snapshot-store.d.ts +21 -0
- package/dist/config/config-snapshot-store.d.ts.map +1 -0
- package/dist/config/config-watcher.d.ts +19 -0
- package/dist/config/config-watcher.d.ts.map +1 -0
- package/dist/config/types.d.ts +16 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/defaults/visor.yaml +5 -2
- package/dist/docs/ai-configuration.md +139 -0
- package/dist/docs/ai-custom-tools.md +30 -0
- package/dist/docs/capacity-planning.md +359 -0
- package/dist/docs/commands.md +35 -0
- package/dist/docs/database-operations.md +487 -0
- package/dist/docs/index.md +6 -1
- package/dist/docs/licensing.md +372 -0
- package/dist/docs/production-deployment.md +583 -0
- package/dist/examples/ai-with-bash.yaml +17 -0
- package/dist/generated/config-schema.d.ts +4 -0
- package/dist/generated/config-schema.d.ts.map +1 -1
- package/dist/index.js +9945 -10907
- package/dist/liquid-extensions.d.ts +7 -0
- package/dist/liquid-extensions.d.ts.map +1 -1
- package/dist/output/traces/{run-2026-02-11T16-20-59-999Z.ndjson → run-2026-02-15T19-14-20-379Z.ndjson} +84 -84
- package/dist/{traces/run-2026-02-11T16-21-47-711Z.ndjson → output/traces/run-2026-02-15T19-15-09-410Z.ndjson} +1019 -1019
- package/dist/providers/ai-check-provider.d.ts +5 -0
- package/dist/providers/ai-check-provider.d.ts.map +1 -1
- package/dist/providers/command-check-provider.d.ts.map +1 -1
- package/dist/providers/workflow-check-provider.d.ts.map +1 -1
- package/dist/scheduler/schedule-tool.d.ts.map +1 -1
- package/dist/sdk/{check-provider-registry-PANIXYRB.mjs → check-provider-registry-AAPPJ4CP.mjs} +7 -7
- package/dist/sdk/{check-provider-registry-M3Y6JMTW.mjs → check-provider-registry-S7BMQ2FC.mjs} +7 -7
- package/dist/sdk/check-provider-registry-ZOLEYDKM.mjs +28 -0
- package/dist/sdk/{chunk-VMLORODQ.mjs → chunk-2GCSK3PD.mjs} +4 -4
- package/dist/sdk/{chunk-EUUAQBTW.mjs → chunk-6ZZ4DPAA.mjs} +240 -48
- package/dist/sdk/chunk-6ZZ4DPAA.mjs.map +1 -0
- package/dist/sdk/{chunk-HOKQOO3G.mjs → chunk-EBTD2D4L.mjs} +2 -2
- package/dist/sdk/chunk-LDFUW34H.mjs +39912 -0
- package/dist/sdk/chunk-LDFUW34H.mjs.map +1 -0
- package/dist/sdk/{chunk-UCNT3PDT.mjs → chunk-LQ5B4T6L.mjs} +5 -1
- package/dist/sdk/chunk-LQ5B4T6L.mjs.map +1 -0
- package/dist/sdk/{chunk-S6CD7GFM.mjs → chunk-MQ57AB4U.mjs} +211 -35
- package/dist/sdk/chunk-MQ57AB4U.mjs.map +1 -0
- package/dist/sdk/chunk-N4I6ZDCJ.mjs +436 -0
- package/dist/sdk/chunk-N4I6ZDCJ.mjs.map +1 -0
- package/dist/sdk/chunk-OMFPM576.mjs +739 -0
- package/dist/sdk/chunk-OMFPM576.mjs.map +1 -0
- package/dist/sdk/chunk-RI77TA6V.mjs +436 -0
- package/dist/sdk/chunk-RI77TA6V.mjs.map +1 -0
- package/dist/sdk/chunk-VO4N6TEL.mjs +1502 -0
- package/dist/sdk/chunk-VO4N6TEL.mjs.map +1 -0
- package/dist/sdk/{chunk-V2IV3ILA.mjs → chunk-XJQKTK6V.mjs} +31 -5
- package/dist/sdk/chunk-XJQKTK6V.mjs.map +1 -0
- package/dist/sdk/{config-OGOS4ZU4.mjs → config-4EG7IQIU.mjs} +2 -2
- package/dist/sdk/{failure-condition-evaluator-HC3M5377.mjs → failure-condition-evaluator-GLHZZF47.mjs} +3 -3
- package/dist/sdk/failure-condition-evaluator-KN55WXRO.mjs +17 -0
- package/dist/sdk/{github-frontend-E2KJSC3Y.mjs → github-frontend-F4TE2JY7.mjs} +3 -3
- package/dist/sdk/github-frontend-HCOKL53D.mjs +1356 -0
- package/dist/sdk/github-frontend-HCOKL53D.mjs.map +1 -0
- package/dist/sdk/{host-EE6EJ2FM.mjs → host-SAT6RHDX.mjs} +2 -2
- package/dist/sdk/host-VA3ET7N6.mjs +63 -0
- package/dist/sdk/host-VA3ET7N6.mjs.map +1 -0
- package/dist/sdk/{liquid-extensions-E4EUOCES.mjs → liquid-extensions-YDIIH33Q.mjs} +2 -2
- package/dist/sdk/{routing-OZQWAGAI.mjs → routing-KFYQGOYU.mjs} +5 -5
- package/dist/sdk/routing-OXQKETSA.mjs +25 -0
- package/dist/sdk/{schedule-tool-handler-IEB2VS7O.mjs → schedule-tool-handler-G353DHS6.mjs} +7 -7
- package/dist/sdk/{schedule-tool-handler-B7TMSG6A.mjs → schedule-tool-handler-OQF57URO.mjs} +7 -7
- package/dist/sdk/schedule-tool-handler-PJVKWSYX.mjs +38 -0
- package/dist/sdk/schedule-tool-handler-PJVKWSYX.mjs.map +1 -0
- package/dist/sdk/sdk.d.mts +15 -0
- package/dist/sdk/sdk.d.ts +15 -0
- package/dist/sdk/sdk.js +621 -183
- package/dist/sdk/sdk.js.map +1 -1
- package/dist/sdk/sdk.mjs +6 -6
- package/dist/sdk/{trace-helpers-PP3YHTAM.mjs → trace-helpers-LOPBHYYX.mjs} +4 -2
- package/dist/sdk/trace-helpers-LOPBHYYX.mjs.map +1 -0
- package/dist/sdk/trace-helpers-R2ETIEC2.mjs +25 -0
- package/dist/sdk/trace-helpers-R2ETIEC2.mjs.map +1 -0
- package/dist/sdk/{workflow-check-provider-2ET3SFZH.mjs → workflow-check-provider-57KAR4Y4.mjs} +7 -7
- package/dist/sdk/workflow-check-provider-57KAR4Y4.mjs.map +1 -0
- package/dist/sdk/{workflow-check-provider-HB4XTD4Z.mjs → workflow-check-provider-LRWD52WN.mjs} +7 -7
- package/dist/sdk/workflow-check-provider-LRWD52WN.mjs.map +1 -0
- package/dist/sdk/workflow-check-provider-N2DRFQDB.mjs +28 -0
- package/dist/sdk/workflow-check-provider-N2DRFQDB.mjs.map +1 -0
- package/dist/slack/socket-runner.d.ts.map +1 -1
- package/dist/state-machine/context/build-engine-context.d.ts.map +1 -1
- package/dist/state-machine/runner.d.ts.map +1 -1
- package/dist/state-machine/states/completed.d.ts.map +1 -1
- package/dist/telemetry/trace-helpers.d.ts +5 -0
- package/dist/telemetry/trace-helpers.d.ts.map +1 -1
- package/dist/test-runner/evaluators.d.ts.map +1 -1
- package/dist/test-runner/index.d.ts +7 -0
- package/dist/test-runner/index.d.ts.map +1 -1
- package/dist/test-runner/validator.d.ts.map +1 -1
- package/dist/traces/{run-2026-02-11T16-20-59-999Z.ndjson → run-2026-02-15T19-14-20-379Z.ndjson} +84 -84
- package/dist/{output/traces/run-2026-02-11T16-21-47-711Z.ndjson → traces/run-2026-02-15T19-15-09-410Z.ndjson} +1019 -1019
- package/dist/tui/chat-runner.d.ts.map +1 -1
- package/dist/types/cli.d.ts +2 -0
- package/dist/types/cli.d.ts.map +1 -1
- package/dist/types/config.d.ts +15 -0
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/engine.d.ts +2 -0
- package/dist/types/engine.d.ts.map +1 -1
- package/package.json +3 -3
- package/defaults/.visor.yaml +0 -420
- package/dist/sdk/chunk-EUUAQBTW.mjs.map +0 -1
- package/dist/sdk/chunk-S6CD7GFM.mjs.map +0 -1
- package/dist/sdk/chunk-UCNT3PDT.mjs.map +0 -1
- package/dist/sdk/chunk-V2IV3ILA.mjs.map +0 -1
- package/dist/sdk/chunk-YJRBN3XS.mjs +0 -217
- package/dist/sdk/chunk-YJRBN3XS.mjs.map +0 -1
- /package/dist/sdk/{check-provider-registry-M3Y6JMTW.mjs.map → check-provider-registry-AAPPJ4CP.mjs.map} +0 -0
- /package/dist/sdk/{check-provider-registry-PANIXYRB.mjs.map → check-provider-registry-S7BMQ2FC.mjs.map} +0 -0
- /package/dist/sdk/{config-OGOS4ZU4.mjs.map → check-provider-registry-ZOLEYDKM.mjs.map} +0 -0
- /package/dist/sdk/{chunk-VMLORODQ.mjs.map → chunk-2GCSK3PD.mjs.map} +0 -0
- /package/dist/sdk/{chunk-HOKQOO3G.mjs.map → chunk-EBTD2D4L.mjs.map} +0 -0
- /package/dist/sdk/{failure-condition-evaluator-HC3M5377.mjs.map → config-4EG7IQIU.mjs.map} +0 -0
- /package/dist/sdk/{liquid-extensions-E4EUOCES.mjs.map → failure-condition-evaluator-GLHZZF47.mjs.map} +0 -0
- /package/dist/sdk/{routing-OZQWAGAI.mjs.map → failure-condition-evaluator-KN55WXRO.mjs.map} +0 -0
- /package/dist/sdk/{github-frontend-E2KJSC3Y.mjs.map → github-frontend-F4TE2JY7.mjs.map} +0 -0
- /package/dist/sdk/{host-EE6EJ2FM.mjs.map → host-SAT6RHDX.mjs.map} +0 -0
- /package/dist/sdk/{schedule-tool-handler-B7TMSG6A.mjs.map → liquid-extensions-YDIIH33Q.mjs.map} +0 -0
- /package/dist/sdk/{schedule-tool-handler-IEB2VS7O.mjs.map → routing-KFYQGOYU.mjs.map} +0 -0
- /package/dist/sdk/{trace-helpers-PP3YHTAM.mjs.map → routing-OXQKETSA.mjs.map} +0 -0
- /package/dist/sdk/{workflow-check-provider-2ET3SFZH.mjs.map → schedule-tool-handler-G353DHS6.mjs.map} +0 -0
- /package/dist/sdk/{workflow-check-provider-HB4XTD4Z.mjs.map → schedule-tool-handler-OQF57URO.mjs.map} +0 -0
package/dist/sdk/sdk.js
CHANGED
|
@@ -641,6 +641,205 @@ var init_fallback_ndjson = __esm({
|
|
|
641
641
|
}
|
|
642
642
|
});
|
|
643
643
|
|
|
644
|
+
// package.json
|
|
645
|
+
var require_package = __commonJS({
|
|
646
|
+
"package.json"(exports2, module2) {
|
|
647
|
+
module2.exports = {
|
|
648
|
+
name: "@probelabs/visor",
|
|
649
|
+
version: "0.1.131",
|
|
650
|
+
main: "dist/index.js",
|
|
651
|
+
bin: {
|
|
652
|
+
visor: "./dist/index.js"
|
|
653
|
+
},
|
|
654
|
+
exports: {
|
|
655
|
+
".": {
|
|
656
|
+
require: "./dist/index.js",
|
|
657
|
+
import: "./dist/index.js"
|
|
658
|
+
},
|
|
659
|
+
"./sdk": {
|
|
660
|
+
types: "./dist/sdk/sdk.d.ts",
|
|
661
|
+
import: "./dist/sdk/sdk.mjs",
|
|
662
|
+
require: "./dist/sdk/sdk.js"
|
|
663
|
+
},
|
|
664
|
+
"./cli": {
|
|
665
|
+
require: "./dist/index.js"
|
|
666
|
+
}
|
|
667
|
+
},
|
|
668
|
+
files: [
|
|
669
|
+
"dist/",
|
|
670
|
+
"defaults/",
|
|
671
|
+
"action.yml",
|
|
672
|
+
"README.md",
|
|
673
|
+
"LICENSE"
|
|
674
|
+
],
|
|
675
|
+
publishConfig: {
|
|
676
|
+
access: "public",
|
|
677
|
+
registry: "https://registry.npmjs.org/"
|
|
678
|
+
},
|
|
679
|
+
scripts: {
|
|
680
|
+
"build:cli": "ncc build src/index.ts -o dist && cp -r defaults dist/ && cp -r output dist/ && cp -r docs dist/ && cp -r examples dist/ && cp -r src/debug-visualizer/ui dist/debug-visualizer/ && node scripts/inject-version.js && echo '#!/usr/bin/env node' | cat - dist/index.js > temp && mv temp dist/index.js && chmod +x dist/index.js",
|
|
681
|
+
"build:sdk": "tsup src/sdk.ts --dts --sourcemap --format esm,cjs --out-dir dist/sdk",
|
|
682
|
+
build: "./scripts/build-oss.sh",
|
|
683
|
+
"build:ee": "npm run build:cli && npm run build:sdk",
|
|
684
|
+
test: "jest && npm run test:yaml",
|
|
685
|
+
"test:unit": "jest",
|
|
686
|
+
prepublishOnly: "npm run build",
|
|
687
|
+
"test:watch": "jest --watch",
|
|
688
|
+
"test:coverage": "jest --coverage",
|
|
689
|
+
"test:ee": "jest --testPathPatterns='tests/ee' --testPathIgnorePatterns='/node_modules/' --no-coverage",
|
|
690
|
+
"test:manual:bash": "RUN_MANUAL_TESTS=true jest tests/manual/bash-config-manual.test.ts",
|
|
691
|
+
lint: "eslint src tests --ext .ts",
|
|
692
|
+
"lint:fix": "eslint src tests --ext .ts --fix",
|
|
693
|
+
format: "prettier --write src tests",
|
|
694
|
+
"format:check": "prettier --check src tests",
|
|
695
|
+
clean: "",
|
|
696
|
+
prebuild: "npm run clean && node scripts/generate-config-schema.js",
|
|
697
|
+
pretest: "node scripts/generate-config-schema.js && npm run build:cli",
|
|
698
|
+
"pretest:unit": "node scripts/generate-config-schema.js && npm run build:cli",
|
|
699
|
+
"test:with-build": "npm run build:cli && jest",
|
|
700
|
+
"test:yaml": "node dist/index.js test --progress compact",
|
|
701
|
+
"test:yaml:parallel": "node dist/index.js test --progress compact --max-parallel 4",
|
|
702
|
+
prepare: "husky",
|
|
703
|
+
"pre-commit": "lint-staged",
|
|
704
|
+
"deploy:site": "cd site && npx wrangler pages deploy . --project-name=visor-site --commit-dirty=true",
|
|
705
|
+
"deploy:worker": "npx wrangler deploy",
|
|
706
|
+
deploy: "npm run deploy:site && npm run deploy:worker",
|
|
707
|
+
"publish:ee": "./scripts/publish-ee.sh",
|
|
708
|
+
release: "./scripts/release.sh",
|
|
709
|
+
"release:patch": "./scripts/release.sh patch",
|
|
710
|
+
"release:minor": "./scripts/release.sh minor",
|
|
711
|
+
"release:major": "./scripts/release.sh major",
|
|
712
|
+
"release:prerelease": "./scripts/release.sh prerelease",
|
|
713
|
+
"docs:validate": "node scripts/validate-readme-links.js",
|
|
714
|
+
"workshop:setup": "npm install -D reveal-md@6.1.2",
|
|
715
|
+
"workshop:serve": "cd workshop && reveal-md slides.md -w",
|
|
716
|
+
"workshop:export": "reveal-md workshop/slides.md --static workshop/build",
|
|
717
|
+
"workshop:pdf": "reveal-md workshop/slides.md --print workshop/Visor-Workshop.pdf --print-size letter",
|
|
718
|
+
"workshop:pdf:ci": 'reveal-md workshop/slides.md --print workshop/Visor-Workshop.pdf --print-size letter --puppeteer-launch-args="--no-sandbox --disable-dev-shm-usage"',
|
|
719
|
+
"workshop:pdf:a4": "reveal-md workshop/slides.md --print workshop/Visor-Workshop-A4.pdf --print-size A4",
|
|
720
|
+
"workshop:build": "npm run workshop:export && npm run workshop:pdf",
|
|
721
|
+
"simulate:issue": "TS_NODE_TRANSPILE_ONLY=1 ts-node scripts/simulate-gh-run.ts --event issues --action opened --debug",
|
|
722
|
+
"simulate:comment": "TS_NODE_TRANSPILE_ONLY=1 ts-node scripts/simulate-gh-run.ts --event issue_comment --action created --debug"
|
|
723
|
+
},
|
|
724
|
+
keywords: [
|
|
725
|
+
"code-review",
|
|
726
|
+
"ai",
|
|
727
|
+
"github-action",
|
|
728
|
+
"cli",
|
|
729
|
+
"pr-review",
|
|
730
|
+
"visor"
|
|
731
|
+
],
|
|
732
|
+
author: "Probe Labs",
|
|
733
|
+
license: "MIT",
|
|
734
|
+
description: "AI-powered code review tool for GitHub Pull Requests - CLI and GitHub Action",
|
|
735
|
+
repository: {
|
|
736
|
+
type: "git",
|
|
737
|
+
url: "git+https://github.com/probelabs/visor.git"
|
|
738
|
+
},
|
|
739
|
+
bugs: {
|
|
740
|
+
url: "https://github.com/probelabs/visor/issues"
|
|
741
|
+
},
|
|
742
|
+
homepage: "https://github.com/probelabs/visor#readme",
|
|
743
|
+
dependencies: {
|
|
744
|
+
"@actions/core": "^1.11.1",
|
|
745
|
+
"@modelcontextprotocol/sdk": "^1.25.3",
|
|
746
|
+
"@nyariv/sandboxjs": "github:probelabs/SandboxJS#f1c13b8eee98734a8ea024061eada4aa9a9ff2e9",
|
|
747
|
+
"@octokit/action": "^8.0.2",
|
|
748
|
+
"@octokit/auth-app": "^8.1.0",
|
|
749
|
+
"@octokit/core": "^7.0.3",
|
|
750
|
+
"@octokit/rest": "^22.0.0",
|
|
751
|
+
"@probelabs/probe": "^0.6.0-rc232",
|
|
752
|
+
"@types/commander": "^2.12.0",
|
|
753
|
+
"@types/uuid": "^10.0.0",
|
|
754
|
+
ajv: "^8.17.1",
|
|
755
|
+
"ajv-formats": "^3.0.1",
|
|
756
|
+
"better-sqlite3": "^11.0.0",
|
|
757
|
+
blessed: "^0.1.81",
|
|
758
|
+
"cli-table3": "^0.6.5",
|
|
759
|
+
commander: "^14.0.0",
|
|
760
|
+
dotenv: "^17.2.3",
|
|
761
|
+
ignore: "^7.0.5",
|
|
762
|
+
"js-yaml": "^4.1.0",
|
|
763
|
+
liquidjs: "^10.21.1",
|
|
764
|
+
"node-cron": "^3.0.3",
|
|
765
|
+
open: "^9.1.0",
|
|
766
|
+
"simple-git": "^3.28.0",
|
|
767
|
+
uuid: "^11.1.0",
|
|
768
|
+
ws: "^8.18.3"
|
|
769
|
+
},
|
|
770
|
+
optionalDependencies: {
|
|
771
|
+
"@anthropic/claude-code-sdk": "npm:null@*",
|
|
772
|
+
"@open-policy-agent/opa-wasm": "^1.10.0",
|
|
773
|
+
"@opentelemetry/api": "^1.9.0",
|
|
774
|
+
"@opentelemetry/core": "^1.30.1",
|
|
775
|
+
"@opentelemetry/exporter-trace-otlp-grpc": "^0.203.0",
|
|
776
|
+
"@opentelemetry/exporter-trace-otlp-http": "^0.203.0",
|
|
777
|
+
"@opentelemetry/instrumentation": "^0.203.0",
|
|
778
|
+
"@opentelemetry/resources": "^1.30.1",
|
|
779
|
+
"@opentelemetry/sdk-metrics": "^1.30.1",
|
|
780
|
+
"@opentelemetry/sdk-node": "^0.203.0",
|
|
781
|
+
"@opentelemetry/sdk-trace-base": "^1.30.1",
|
|
782
|
+
"@opentelemetry/semantic-conventions": "^1.30.1",
|
|
783
|
+
knex: "^3.1.0",
|
|
784
|
+
mysql2: "^3.11.0",
|
|
785
|
+
pg: "^8.13.0",
|
|
786
|
+
tedious: "^19.0.0"
|
|
787
|
+
},
|
|
788
|
+
devDependencies: {
|
|
789
|
+
"@eslint/js": "^9.34.0",
|
|
790
|
+
"@kie/act-js": "^2.6.2",
|
|
791
|
+
"@kie/mock-github": "^2.0.1",
|
|
792
|
+
"@swc/core": "^1.13.2",
|
|
793
|
+
"@swc/jest": "^0.2.37",
|
|
794
|
+
"@types/better-sqlite3": "^7.6.0",
|
|
795
|
+
"@types/blessed": "^0.1.27",
|
|
796
|
+
"@types/jest": "^30.0.0",
|
|
797
|
+
"@types/js-yaml": "^4.0.9",
|
|
798
|
+
"@types/node": "^24.3.0",
|
|
799
|
+
"@types/node-cron": "^3.0.11",
|
|
800
|
+
"@types/ws": "^8.18.1",
|
|
801
|
+
"@typescript-eslint/eslint-plugin": "^8.42.0",
|
|
802
|
+
"@typescript-eslint/parser": "^8.42.0",
|
|
803
|
+
"@vercel/ncc": "^0.38.4",
|
|
804
|
+
eslint: "^9.34.0",
|
|
805
|
+
"eslint-config-prettier": "^10.1.8",
|
|
806
|
+
"eslint-plugin-prettier": "^5.5.4",
|
|
807
|
+
husky: "^9.1.7",
|
|
808
|
+
jest: "^30.1.3",
|
|
809
|
+
"lint-staged": "^16.1.6",
|
|
810
|
+
prettier: "^3.6.2",
|
|
811
|
+
"reveal-md": "^6.1.2",
|
|
812
|
+
"ts-json-schema-generator": "^1.5.1",
|
|
813
|
+
"ts-node": "^10.9.2",
|
|
814
|
+
tsup: "^8.5.0",
|
|
815
|
+
typescript: "^5.9.2",
|
|
816
|
+
wrangler: "^3.0.0"
|
|
817
|
+
},
|
|
818
|
+
peerDependenciesMeta: {
|
|
819
|
+
"@anthropic/claude-code-sdk": {
|
|
820
|
+
optional: true
|
|
821
|
+
}
|
|
822
|
+
},
|
|
823
|
+
directories: {
|
|
824
|
+
test: "tests"
|
|
825
|
+
},
|
|
826
|
+
"lint-staged": {
|
|
827
|
+
"src/**/*.{ts,js}": [
|
|
828
|
+
"eslint --fix",
|
|
829
|
+
"prettier --write"
|
|
830
|
+
],
|
|
831
|
+
"tests/**/*.{ts,js}": [
|
|
832
|
+
"eslint --fix",
|
|
833
|
+
"prettier --write"
|
|
834
|
+
],
|
|
835
|
+
"*.{json,md,yml,yaml}": [
|
|
836
|
+
"prettier --write"
|
|
837
|
+
]
|
|
838
|
+
}
|
|
839
|
+
};
|
|
840
|
+
}
|
|
841
|
+
});
|
|
842
|
+
|
|
644
843
|
// src/telemetry/trace-helpers.ts
|
|
645
844
|
var trace_helpers_exports = {};
|
|
646
845
|
__export(trace_helpers_exports, {
|
|
@@ -648,6 +847,7 @@ __export(trace_helpers_exports, {
|
|
|
648
847
|
_appendRunMarker: () => _appendRunMarker,
|
|
649
848
|
addEvent: () => addEvent,
|
|
650
849
|
getTracer: () => getTracer,
|
|
850
|
+
getVisorRunAttributes: () => getVisorRunAttributes,
|
|
651
851
|
setSpanAttributes: () => setSpanAttributes,
|
|
652
852
|
setSpanError: () => setSpanError,
|
|
653
853
|
withActiveSpan: () => withActiveSpan
|
|
@@ -717,20 +917,37 @@ function setSpanError(err) {
|
|
|
717
917
|
} catch {
|
|
718
918
|
}
|
|
719
919
|
}
|
|
920
|
+
function getVisorRunAttributes() {
|
|
921
|
+
const attrs = {};
|
|
922
|
+
try {
|
|
923
|
+
attrs["visor.version"] = process.env.VISOR_VERSION || (require_package()?.version ?? "dev");
|
|
924
|
+
} catch {
|
|
925
|
+
attrs["visor.version"] = "dev";
|
|
926
|
+
}
|
|
927
|
+
const commitShort = process.env.VISOR_COMMIT_SHORT || "";
|
|
928
|
+
const commitFull = process.env.VISOR_COMMIT_SHA || process.env.VISOR_COMMIT || "";
|
|
929
|
+
if (commitShort) {
|
|
930
|
+
attrs["visor.commit"] = commitShort;
|
|
931
|
+
}
|
|
932
|
+
if (commitFull) {
|
|
933
|
+
attrs["visor.commit.sha"] = commitFull;
|
|
934
|
+
}
|
|
935
|
+
return attrs;
|
|
936
|
+
}
|
|
720
937
|
function __getOrCreateNdjsonPath() {
|
|
721
938
|
try {
|
|
722
939
|
if (process.env.VISOR_TELEMETRY_SINK && process.env.VISOR_TELEMETRY_SINK !== "file")
|
|
723
940
|
return null;
|
|
724
941
|
const path25 = require("path");
|
|
725
|
-
const
|
|
942
|
+
const fs21 = require("fs");
|
|
726
943
|
if (process.env.VISOR_FALLBACK_TRACE_FILE) {
|
|
727
944
|
__ndjsonPath = process.env.VISOR_FALLBACK_TRACE_FILE;
|
|
728
945
|
const dir = path25.dirname(__ndjsonPath);
|
|
729
|
-
if (!
|
|
946
|
+
if (!fs21.existsSync(dir)) fs21.mkdirSync(dir, { recursive: true });
|
|
730
947
|
return __ndjsonPath;
|
|
731
948
|
}
|
|
732
949
|
const outDir = process.env.VISOR_TRACE_DIR || path25.join(process.cwd(), "output", "traces");
|
|
733
|
-
if (!
|
|
950
|
+
if (!fs21.existsSync(outDir)) fs21.mkdirSync(outDir, { recursive: true });
|
|
734
951
|
if (!__ndjsonPath) {
|
|
735
952
|
const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
736
953
|
__ndjsonPath = path25.join(outDir, `${ts}.ndjson`);
|
|
@@ -742,11 +959,11 @@ function __getOrCreateNdjsonPath() {
|
|
|
742
959
|
}
|
|
743
960
|
function _appendRunMarker() {
|
|
744
961
|
try {
|
|
745
|
-
const
|
|
962
|
+
const fs21 = require("fs");
|
|
746
963
|
const p = __getOrCreateNdjsonPath();
|
|
747
964
|
if (!p) return;
|
|
748
965
|
const line = { name: "visor.run", attributes: { started: true } };
|
|
749
|
-
|
|
966
|
+
fs21.appendFileSync(p, JSON.stringify(line) + "\n", "utf8");
|
|
750
967
|
} catch {
|
|
751
968
|
}
|
|
752
969
|
}
|
|
@@ -3709,25 +3926,45 @@ function createExtendedLiquid(options = {}) {
|
|
|
3709
3926
|
configureLiquidWithExtensions(liquid);
|
|
3710
3927
|
return liquid;
|
|
3711
3928
|
}
|
|
3712
|
-
var import_liquidjs, import_async_hooks,
|
|
3929
|
+
var import_liquidjs, import_async_hooks, import_path2, ReadFileTag, permissionsALS;
|
|
3713
3930
|
var init_liquid_extensions = __esm({
|
|
3714
3931
|
"src/liquid-extensions.ts"() {
|
|
3715
3932
|
"use strict";
|
|
3716
3933
|
import_liquidjs = require("liquidjs");
|
|
3717
3934
|
import_async_hooks = require("async_hooks");
|
|
3718
|
-
import_promises2 = __toESM(require("fs/promises"));
|
|
3719
3935
|
import_path2 = __toESM(require("path"));
|
|
3720
3936
|
init_author_permissions();
|
|
3721
3937
|
init_memory_store();
|
|
3722
3938
|
init_sandbox();
|
|
3723
3939
|
ReadFileTag = class extends import_liquidjs.Tag {
|
|
3724
3940
|
filepath;
|
|
3941
|
+
indentValue = null;
|
|
3725
3942
|
constructor(token, remainTokens, liquid) {
|
|
3726
3943
|
super(token, remainTokens, liquid);
|
|
3727
|
-
|
|
3944
|
+
const argsStr = token.args.trim();
|
|
3945
|
+
const indentMatch = argsStr.match(/^(.+?)\s+indent:\s*(\d+)\s*$/);
|
|
3946
|
+
if (indentMatch) {
|
|
3947
|
+
this.filepath = new import_liquidjs.Value(indentMatch[1].trim(), liquid);
|
|
3948
|
+
this.indentValue = new import_liquidjs.Value(indentMatch[2], liquid);
|
|
3949
|
+
} else {
|
|
3950
|
+
this.filepath = new import_liquidjs.Value(argsStr, liquid);
|
|
3951
|
+
}
|
|
3728
3952
|
}
|
|
3729
3953
|
*render(ctx, emitter) {
|
|
3730
3954
|
const filePath = yield this.filepath.value(ctx, false);
|
|
3955
|
+
let indent = 0;
|
|
3956
|
+
if (this.indentValue) {
|
|
3957
|
+
const indentAmount = yield this.indentValue.value(ctx, false);
|
|
3958
|
+
indent = typeof indentAmount === "number" ? indentAmount : parseInt(String(indentAmount), 10) || 0;
|
|
3959
|
+
} else {
|
|
3960
|
+
const output = emitter.buffer || "";
|
|
3961
|
+
const lastNewline = output.lastIndexOf("\n");
|
|
3962
|
+
if (lastNewline >= 0) {
|
|
3963
|
+
const lineStart = output.substring(lastNewline + 1);
|
|
3964
|
+
const match = lineStart.match(/^(\s*)/);
|
|
3965
|
+
indent = match ? match[1].length : 0;
|
|
3966
|
+
}
|
|
3967
|
+
}
|
|
3731
3968
|
if (!filePath || typeof filePath !== "string") {
|
|
3732
3969
|
emitter.write("[Error: Invalid file path]");
|
|
3733
3970
|
return;
|
|
@@ -3741,7 +3978,12 @@ var init_liquid_extensions = __esm({
|
|
|
3741
3978
|
return;
|
|
3742
3979
|
}
|
|
3743
3980
|
try {
|
|
3744
|
-
|
|
3981
|
+
let content = require("fs").readFileSync(resolvedPath, "utf-8");
|
|
3982
|
+
if (indent > 0) {
|
|
3983
|
+
const indentStr = " ".repeat(indent);
|
|
3984
|
+
const lines = content.split("\n");
|
|
3985
|
+
content = lines.map((line, i) => i === 0 ? line : indentStr + line).join("\n");
|
|
3986
|
+
}
|
|
3745
3987
|
emitter.write(content);
|
|
3746
3988
|
} catch (error) {
|
|
3747
3989
|
const errorMessage = error instanceof Error ? error.message : error?.code || "Unknown error";
|
|
@@ -5453,14 +5695,14 @@ function emitMermaidFromMarkdown(checkName, markdown, origin) {
|
|
|
5453
5695
|
if (process.env.VISOR_TRACE_REPORT === "true") {
|
|
5454
5696
|
const outDir = process.env.VISOR_TRACE_DIR || path4.join(process.cwd(), "output", "traces");
|
|
5455
5697
|
try {
|
|
5456
|
-
if (!
|
|
5698
|
+
if (!fs3.existsSync(outDir)) fs3.mkdirSync(outDir, { recursive: true });
|
|
5457
5699
|
const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
5458
5700
|
const jsonPath = path4.join(outDir, `${ts}.trace.json`);
|
|
5459
5701
|
const htmlPath = path4.join(outDir, `${ts}.report.html`);
|
|
5460
5702
|
let data = { spans: [] };
|
|
5461
|
-
if (
|
|
5703
|
+
if (fs3.existsSync(jsonPath)) {
|
|
5462
5704
|
try {
|
|
5463
|
-
data = JSON.parse(
|
|
5705
|
+
data = JSON.parse(fs3.readFileSync(jsonPath, "utf8"));
|
|
5464
5706
|
} catch {
|
|
5465
5707
|
data = { spans: [] };
|
|
5466
5708
|
}
|
|
@@ -5468,9 +5710,9 @@ function emitMermaidFromMarkdown(checkName, markdown, origin) {
|
|
|
5468
5710
|
data.spans.push({
|
|
5469
5711
|
events: [{ name: "diagram.block", attrs: { check: checkName, origin, code } }]
|
|
5470
5712
|
});
|
|
5471
|
-
|
|
5472
|
-
if (!
|
|
5473
|
-
|
|
5713
|
+
fs3.writeFileSync(jsonPath, JSON.stringify(data, null, 2), "utf8");
|
|
5714
|
+
if (!fs3.existsSync(htmlPath)) {
|
|
5715
|
+
fs3.writeFileSync(
|
|
5474
5716
|
htmlPath,
|
|
5475
5717
|
'<!doctype html><html><head><meta charset="utf-8"/><title>Visor Trace Report</title></head><body><h2>Visor Trace Report</h2></body></html>',
|
|
5476
5718
|
"utf8"
|
|
@@ -5486,13 +5728,13 @@ function emitMermaidFromMarkdown(checkName, markdown, origin) {
|
|
|
5486
5728
|
}
|
|
5487
5729
|
return count;
|
|
5488
5730
|
}
|
|
5489
|
-
var
|
|
5731
|
+
var fs3, path4, MERMAID_RE;
|
|
5490
5732
|
var init_mermaid_telemetry = __esm({
|
|
5491
5733
|
"src/utils/mermaid-telemetry.ts"() {
|
|
5492
5734
|
"use strict";
|
|
5493
5735
|
init_trace_helpers();
|
|
5494
5736
|
init_metrics();
|
|
5495
|
-
|
|
5737
|
+
fs3 = __toESM(require("fs"));
|
|
5496
5738
|
path4 = __toESM(require("path"));
|
|
5497
5739
|
MERMAID_RE = /```mermaid\s*\n([\s\S]*?)\n```/gi;
|
|
5498
5740
|
}
|
|
@@ -6130,7 +6372,7 @@ var init_dependency_gating = __esm({
|
|
|
6130
6372
|
async function renderTemplateContent(checkId, checkConfig, reviewSummary) {
|
|
6131
6373
|
try {
|
|
6132
6374
|
const { createExtendedLiquid: createExtendedLiquid2 } = await Promise.resolve().then(() => (init_liquid_extensions(), liquid_extensions_exports));
|
|
6133
|
-
const
|
|
6375
|
+
const fs21 = await import("fs/promises");
|
|
6134
6376
|
const path25 = await import("path");
|
|
6135
6377
|
const schemaRaw = checkConfig.schema || "plain";
|
|
6136
6378
|
const schema = typeof schemaRaw === "string" ? schemaRaw : "code-review";
|
|
@@ -6140,7 +6382,7 @@ async function renderTemplateContent(checkId, checkConfig, reviewSummary) {
|
|
|
6140
6382
|
} else if (checkConfig.template && checkConfig.template.file) {
|
|
6141
6383
|
const file = String(checkConfig.template.file);
|
|
6142
6384
|
const resolved = path25.resolve(process.cwd(), file);
|
|
6143
|
-
templateContent = await
|
|
6385
|
+
templateContent = await fs21.readFile(resolved, "utf-8");
|
|
6144
6386
|
} else if (schema && schema !== "plain") {
|
|
6145
6387
|
const sanitized = String(schema).replace(/[^a-zA-Z0-9-]/g, "");
|
|
6146
6388
|
if (sanitized) {
|
|
@@ -6156,7 +6398,7 @@ async function renderTemplateContent(checkId, checkConfig, reviewSummary) {
|
|
|
6156
6398
|
];
|
|
6157
6399
|
for (const p of candidatePaths) {
|
|
6158
6400
|
try {
|
|
6159
|
-
templateContent = await
|
|
6401
|
+
templateContent = await fs21.readFile(p, "utf-8");
|
|
6160
6402
|
if (templateContent) break;
|
|
6161
6403
|
} catch {
|
|
6162
6404
|
}
|
|
@@ -6312,8 +6554,8 @@ async function initializeTracer(sessionId, checkName) {
|
|
|
6312
6554
|
const sanitizedCheckName = checkName ? path5.basename(checkName) : "check";
|
|
6313
6555
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
6314
6556
|
const traceDir = process.env.GITHUB_WORKSPACE ? path5.join(process.env.GITHUB_WORKSPACE, "debug-artifacts") : path5.join(process.cwd(), "debug-artifacts");
|
|
6315
|
-
if (!
|
|
6316
|
-
|
|
6557
|
+
if (!fs4.existsSync(traceDir)) {
|
|
6558
|
+
fs4.mkdirSync(traceDir, { recursive: true });
|
|
6317
6559
|
}
|
|
6318
6560
|
const traceFilePath = path5.join(traceDir, `trace-${sanitizedCheckName}-${timestamp}.jsonl`);
|
|
6319
6561
|
const resolvedTracePath = path5.resolve(traceFilePath);
|
|
@@ -6358,12 +6600,12 @@ async function initializeTracer(sessionId, checkName) {
|
|
|
6358
6600
|
return null;
|
|
6359
6601
|
}
|
|
6360
6602
|
}
|
|
6361
|
-
var path5,
|
|
6603
|
+
var path5, fs4;
|
|
6362
6604
|
var init_tracer_init = __esm({
|
|
6363
6605
|
"src/utils/tracer-init.ts"() {
|
|
6364
6606
|
"use strict";
|
|
6365
6607
|
path5 = __toESM(require("path"));
|
|
6366
|
-
|
|
6608
|
+
fs4 = __toESM(require("fs"));
|
|
6367
6609
|
}
|
|
6368
6610
|
});
|
|
6369
6611
|
|
|
@@ -6561,7 +6803,7 @@ async function processDiffWithOutline(diffContent) {
|
|
|
6561
6803
|
}
|
|
6562
6804
|
try {
|
|
6563
6805
|
const originalProbePath = process.env.PROBE_PATH;
|
|
6564
|
-
const
|
|
6806
|
+
const fs21 = require("fs");
|
|
6565
6807
|
const possiblePaths = [
|
|
6566
6808
|
// Relative to current working directory (most common in production)
|
|
6567
6809
|
path6.join(process.cwd(), "node_modules/@probelabs/probe/bin/probe-binary"),
|
|
@@ -6572,7 +6814,7 @@ async function processDiffWithOutline(diffContent) {
|
|
|
6572
6814
|
];
|
|
6573
6815
|
let probeBinaryPath;
|
|
6574
6816
|
for (const candidatePath of possiblePaths) {
|
|
6575
|
-
if (
|
|
6817
|
+
if (fs21.existsSync(candidatePath)) {
|
|
6576
6818
|
probeBinaryPath = candidatePath;
|
|
6577
6819
|
break;
|
|
6578
6820
|
}
|
|
@@ -7129,6 +7371,8 @@ var init_ai_review_service = __esm({
|
|
|
7129
7371
|
const isCodeReviewSchema = schema === "code-review";
|
|
7130
7372
|
const prContext = skipPRContext ? "" : await this.formatPRContext(prInfo, isCodeReviewSchema);
|
|
7131
7373
|
const slackContextXml = skipSlackContext === true ? "" : this.formatSlackContextFromPRInfo(prInfo);
|
|
7374
|
+
const traceIdXml = prInfo.otelTraceId ? `
|
|
7375
|
+
<trace_id>${this.escapeXml(String(prInfo.otelTraceId))}</trace_id>` : "";
|
|
7132
7376
|
const isIssue = prInfo.isIssue === true;
|
|
7133
7377
|
if (isIssue) {
|
|
7134
7378
|
if (skipPRContext && !slackContextXml) {
|
|
@@ -7142,7 +7386,7 @@ ${customInstructions}
|
|
|
7142
7386
|
</instructions>
|
|
7143
7387
|
|
|
7144
7388
|
<context>
|
|
7145
|
-
${getCurrentDateXml()}
|
|
7389
|
+
${getCurrentDateXml()}${traceIdXml}
|
|
7146
7390
|
${prContext}${slackContextXml}
|
|
7147
7391
|
</context>
|
|
7148
7392
|
|
|
@@ -7184,7 +7428,7 @@ ${customInstructions}
|
|
|
7184
7428
|
</instructions>
|
|
7185
7429
|
|
|
7186
7430
|
<context>
|
|
7187
|
-
${getCurrentDateXml()}
|
|
7431
|
+
${getCurrentDateXml()}${traceIdXml}
|
|
7188
7432
|
${prContext}${slackContextXml}
|
|
7189
7433
|
</context>
|
|
7190
7434
|
|
|
@@ -7212,7 +7456,7 @@ ${customInstructions}
|
|
|
7212
7456
|
</instructions>
|
|
7213
7457
|
|
|
7214
7458
|
<context>
|
|
7215
|
-
${getCurrentDateXml()}
|
|
7459
|
+
${getCurrentDateXml()}${traceIdXml}
|
|
7216
7460
|
${prContext}${slackContextXml}
|
|
7217
7461
|
</context>`;
|
|
7218
7462
|
}
|
|
@@ -7637,7 +7881,7 @@ ${schemaString}`);
|
|
|
7637
7881
|
}
|
|
7638
7882
|
if (process.env.VISOR_DEBUG_AI_SESSIONS === "true") {
|
|
7639
7883
|
try {
|
|
7640
|
-
const
|
|
7884
|
+
const fs21 = require("fs");
|
|
7641
7885
|
const path25 = require("path");
|
|
7642
7886
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
7643
7887
|
const provider = this.config.provider || "auto";
|
|
@@ -7753,19 +7997,19 @@ ${"=".repeat(60)}
|
|
|
7753
7997
|
readableVersion += `${"=".repeat(60)}
|
|
7754
7998
|
`;
|
|
7755
7999
|
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS || path25.join(process.cwd(), "debug-artifacts");
|
|
7756
|
-
if (!
|
|
7757
|
-
|
|
8000
|
+
if (!fs21.existsSync(debugArtifactsDir)) {
|
|
8001
|
+
fs21.mkdirSync(debugArtifactsDir, { recursive: true });
|
|
7758
8002
|
}
|
|
7759
8003
|
const debugFile = path25.join(
|
|
7760
8004
|
debugArtifactsDir,
|
|
7761
8005
|
`prompt-${_checkName || "unknown"}-${timestamp}.json`
|
|
7762
8006
|
);
|
|
7763
|
-
|
|
8007
|
+
fs21.writeFileSync(debugFile, debugJson, "utf-8");
|
|
7764
8008
|
const readableFile = path25.join(
|
|
7765
8009
|
debugArtifactsDir,
|
|
7766
8010
|
`prompt-${_checkName || "unknown"}-${timestamp}.txt`
|
|
7767
8011
|
);
|
|
7768
|
-
|
|
8012
|
+
fs21.writeFileSync(readableFile, readableVersion, "utf-8");
|
|
7769
8013
|
log(`
|
|
7770
8014
|
\u{1F4BE} Full debug info saved to:`);
|
|
7771
8015
|
log(` JSON: ${debugFile}`);
|
|
@@ -7798,7 +8042,7 @@ ${"=".repeat(60)}
|
|
|
7798
8042
|
log(`\u{1F4E4} Response length: ${response.length} characters`);
|
|
7799
8043
|
if (process.env.VISOR_DEBUG_AI_SESSIONS === "true") {
|
|
7800
8044
|
try {
|
|
7801
|
-
const
|
|
8045
|
+
const fs21 = require("fs");
|
|
7802
8046
|
const path25 = require("path");
|
|
7803
8047
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
7804
8048
|
const agentAny2 = agent;
|
|
@@ -7823,7 +8067,7 @@ ${"=".repeat(60)}
|
|
|
7823
8067
|
schema: effectiveSchema,
|
|
7824
8068
|
totalMessages: fullHistory.length
|
|
7825
8069
|
};
|
|
7826
|
-
|
|
8070
|
+
fs21.writeFileSync(sessionBase + ".json", JSON.stringify(sessionData, null, 2), "utf-8");
|
|
7827
8071
|
let readable = `=============================================================
|
|
7828
8072
|
`;
|
|
7829
8073
|
readable += `COMPLETE AI SESSION HISTORY (AFTER RESPONSE)
|
|
@@ -7850,7 +8094,7 @@ ${"=".repeat(60)}
|
|
|
7850
8094
|
`;
|
|
7851
8095
|
readable += content + "\n";
|
|
7852
8096
|
});
|
|
7853
|
-
|
|
8097
|
+
fs21.writeFileSync(sessionBase + ".summary.txt", readable, "utf-8");
|
|
7854
8098
|
log(`\u{1F4BE} Complete session history saved:`);
|
|
7855
8099
|
log(` - Contains ALL ${fullHistory.length} messages (prompts + responses)`);
|
|
7856
8100
|
} catch (error) {
|
|
@@ -7859,7 +8103,7 @@ ${"=".repeat(60)}
|
|
|
7859
8103
|
}
|
|
7860
8104
|
if (process.env.VISOR_DEBUG_AI_SESSIONS === "true") {
|
|
7861
8105
|
try {
|
|
7862
|
-
const
|
|
8106
|
+
const fs21 = require("fs");
|
|
7863
8107
|
const path25 = require("path");
|
|
7864
8108
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
7865
8109
|
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS || path25.join(process.cwd(), "debug-artifacts");
|
|
@@ -7896,7 +8140,7 @@ ${"=".repeat(60)}
|
|
|
7896
8140
|
`;
|
|
7897
8141
|
responseContent += `${"=".repeat(60)}
|
|
7898
8142
|
`;
|
|
7899
|
-
|
|
8143
|
+
fs21.writeFileSync(responseFile, responseContent, "utf-8");
|
|
7900
8144
|
log(`\u{1F4BE} Response saved to: ${responseFile}`);
|
|
7901
8145
|
} catch (error) {
|
|
7902
8146
|
log(`\u26A0\uFE0F Could not save response file: ${error}`);
|
|
@@ -7912,9 +8156,9 @@ ${"=".repeat(60)}
|
|
|
7912
8156
|
await agentAny._telemetryConfig.shutdown();
|
|
7913
8157
|
log(`\u{1F4CA} OpenTelemetry trace saved to: ${agentAny._traceFilePath}`);
|
|
7914
8158
|
if (process.env.GITHUB_ACTIONS) {
|
|
7915
|
-
const
|
|
7916
|
-
if (
|
|
7917
|
-
const stats =
|
|
8159
|
+
const fs21 = require("fs");
|
|
8160
|
+
if (fs21.existsSync(agentAny._traceFilePath)) {
|
|
8161
|
+
const stats = fs21.statSync(agentAny._traceFilePath);
|
|
7918
8162
|
console.log(
|
|
7919
8163
|
`::notice title=AI Trace Saved::${agentAny._traceFilePath} (${stats.size} bytes)`
|
|
7920
8164
|
);
|
|
@@ -8046,6 +8290,9 @@ ${"=".repeat(60)}
|
|
|
8046
8290
|
if (this.config.completionPrompt !== void 0) {
|
|
8047
8291
|
options.completionPrompt = this.config.completionPrompt;
|
|
8048
8292
|
}
|
|
8293
|
+
if (this.config.concurrencyLimiter) {
|
|
8294
|
+
options.concurrencyLimiter = this.config.concurrencyLimiter;
|
|
8295
|
+
}
|
|
8049
8296
|
try {
|
|
8050
8297
|
const cfgAny = this.config;
|
|
8051
8298
|
const allowedFolders = cfgAny.allowedFolders;
|
|
@@ -8109,7 +8356,7 @@ ${schemaString}`);
|
|
|
8109
8356
|
const model = this.config.model || "default";
|
|
8110
8357
|
if (process.env.VISOR_DEBUG_AI_SESSIONS === "true") {
|
|
8111
8358
|
try {
|
|
8112
|
-
const
|
|
8359
|
+
const fs21 = require("fs");
|
|
8113
8360
|
const path25 = require("path");
|
|
8114
8361
|
const os2 = require("os");
|
|
8115
8362
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
@@ -8185,7 +8432,7 @@ ${"=".repeat(60)}
|
|
|
8185
8432
|
`;
|
|
8186
8433
|
const tempDir = os2.tmpdir();
|
|
8187
8434
|
const promptFile = path25.join(tempDir, `visor-prompt-${timestamp}.txt`);
|
|
8188
|
-
|
|
8435
|
+
fs21.writeFileSync(promptFile, prompt, "utf-8");
|
|
8189
8436
|
log(`
|
|
8190
8437
|
\u{1F4BE} Prompt saved to: ${promptFile}`);
|
|
8191
8438
|
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS || path25.join(process.cwd(), "debug-artifacts");
|
|
@@ -8194,8 +8441,8 @@ ${"=".repeat(60)}
|
|
|
8194
8441
|
debugArtifactsDir,
|
|
8195
8442
|
`prompt-${_checkName || "unknown"}-${timestamp}`
|
|
8196
8443
|
);
|
|
8197
|
-
|
|
8198
|
-
|
|
8444
|
+
fs21.writeFileSync(base + ".json", debugJson, "utf-8");
|
|
8445
|
+
fs21.writeFileSync(base + ".summary.txt", readableVersion, "utf-8");
|
|
8199
8446
|
log(`
|
|
8200
8447
|
\u{1F4BE} Full debug info saved to directory: ${debugArtifactsDir}`);
|
|
8201
8448
|
} catch {
|
|
@@ -8240,7 +8487,7 @@ $ ${cliCommand}
|
|
|
8240
8487
|
log(`\u{1F4E4} Response length: ${response.length} characters`);
|
|
8241
8488
|
if (process.env.VISOR_DEBUG_AI_SESSIONS === "true") {
|
|
8242
8489
|
try {
|
|
8243
|
-
const
|
|
8490
|
+
const fs21 = require("fs");
|
|
8244
8491
|
const path25 = require("path");
|
|
8245
8492
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
8246
8493
|
const agentAny = agent;
|
|
@@ -8265,7 +8512,7 @@ $ ${cliCommand}
|
|
|
8265
8512
|
schema: effectiveSchema,
|
|
8266
8513
|
totalMessages: fullHistory.length
|
|
8267
8514
|
};
|
|
8268
|
-
|
|
8515
|
+
fs21.writeFileSync(sessionBase + ".json", JSON.stringify(sessionData, null, 2), "utf-8");
|
|
8269
8516
|
let readable = `=============================================================
|
|
8270
8517
|
`;
|
|
8271
8518
|
readable += `COMPLETE AI SESSION HISTORY (AFTER RESPONSE)
|
|
@@ -8292,7 +8539,7 @@ ${"=".repeat(60)}
|
|
|
8292
8539
|
`;
|
|
8293
8540
|
readable += content + "\n";
|
|
8294
8541
|
});
|
|
8295
|
-
|
|
8542
|
+
fs21.writeFileSync(sessionBase + ".summary.txt", readable, "utf-8");
|
|
8296
8543
|
log(`\u{1F4BE} Complete session history saved:`);
|
|
8297
8544
|
log(` - Contains ALL ${fullHistory.length} messages (prompts + responses)`);
|
|
8298
8545
|
} catch (error) {
|
|
@@ -8301,7 +8548,7 @@ ${"=".repeat(60)}
|
|
|
8301
8548
|
}
|
|
8302
8549
|
if (process.env.VISOR_DEBUG_AI_SESSIONS === "true") {
|
|
8303
8550
|
try {
|
|
8304
|
-
const
|
|
8551
|
+
const fs21 = require("fs");
|
|
8305
8552
|
const path25 = require("path");
|
|
8306
8553
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
8307
8554
|
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS || path25.join(process.cwd(), "debug-artifacts");
|
|
@@ -8338,7 +8585,7 @@ ${"=".repeat(60)}
|
|
|
8338
8585
|
`;
|
|
8339
8586
|
responseContent += `${"=".repeat(60)}
|
|
8340
8587
|
`;
|
|
8341
|
-
|
|
8588
|
+
fs21.writeFileSync(responseFile, responseContent, "utf-8");
|
|
8342
8589
|
log(`\u{1F4BE} Response saved to: ${responseFile}`);
|
|
8343
8590
|
} catch (error) {
|
|
8344
8591
|
log(`\u26A0\uFE0F Could not save response file: ${error}`);
|
|
@@ -8356,9 +8603,9 @@ ${"=".repeat(60)}
|
|
|
8356
8603
|
await telemetry.shutdown();
|
|
8357
8604
|
log(`\u{1F4CA} OpenTelemetry trace saved to: ${traceFilePath}`);
|
|
8358
8605
|
if (process.env.GITHUB_ACTIONS) {
|
|
8359
|
-
const
|
|
8360
|
-
if (
|
|
8361
|
-
const stats =
|
|
8606
|
+
const fs21 = require("fs");
|
|
8607
|
+
if (fs21.existsSync(traceFilePath)) {
|
|
8608
|
+
const stats = fs21.statSync(traceFilePath);
|
|
8362
8609
|
console.log(
|
|
8363
8610
|
`::notice title=AI Trace Saved::OpenTelemetry trace file size: ${stats.size} bytes`
|
|
8364
8611
|
);
|
|
@@ -8396,7 +8643,7 @@ ${"=".repeat(60)}
|
|
|
8396
8643
|
* Load schema content from schema files or inline definitions
|
|
8397
8644
|
*/
|
|
8398
8645
|
async loadSchemaContent(schema) {
|
|
8399
|
-
const
|
|
8646
|
+
const fs21 = require("fs").promises;
|
|
8400
8647
|
const path25 = require("path");
|
|
8401
8648
|
if (typeof schema === "object" && schema !== null) {
|
|
8402
8649
|
log("\u{1F4CB} Using inline schema object from configuration");
|
|
@@ -8417,7 +8664,7 @@ ${"=".repeat(60)}
|
|
|
8417
8664
|
try {
|
|
8418
8665
|
const schemaPath = path25.resolve(process.cwd(), schema);
|
|
8419
8666
|
log(`\u{1F4CB} Loading custom schema from file: ${schemaPath}`);
|
|
8420
|
-
const schemaContent = await
|
|
8667
|
+
const schemaContent = await fs21.readFile(schemaPath, "utf-8");
|
|
8421
8668
|
return schemaContent.trim();
|
|
8422
8669
|
} catch (error) {
|
|
8423
8670
|
throw new Error(
|
|
@@ -8439,7 +8686,7 @@ ${"=".repeat(60)}
|
|
|
8439
8686
|
];
|
|
8440
8687
|
for (const schemaPath of candidatePaths) {
|
|
8441
8688
|
try {
|
|
8442
|
-
const schemaContent = await
|
|
8689
|
+
const schemaContent = await fs21.readFile(schemaPath, "utf-8");
|
|
8443
8690
|
return schemaContent.trim();
|
|
8444
8691
|
} catch {
|
|
8445
8692
|
}
|
|
@@ -8846,11 +9093,11 @@ var issue_filter_exports = {};
|
|
|
8846
9093
|
__export(issue_filter_exports, {
|
|
8847
9094
|
IssueFilter: () => IssueFilter
|
|
8848
9095
|
});
|
|
8849
|
-
var
|
|
9096
|
+
var fs5, path7, IssueFilter;
|
|
8850
9097
|
var init_issue_filter = __esm({
|
|
8851
9098
|
"src/issue-filter.ts"() {
|
|
8852
9099
|
"use strict";
|
|
8853
|
-
|
|
9100
|
+
fs5 = __toESM(require("fs"));
|
|
8854
9101
|
path7 = __toESM(require("path"));
|
|
8855
9102
|
IssueFilter = class {
|
|
8856
9103
|
fileCache = /* @__PURE__ */ new Map();
|
|
@@ -8920,16 +9167,16 @@ var init_issue_filter = __esm({
|
|
|
8920
9167
|
}
|
|
8921
9168
|
try {
|
|
8922
9169
|
const resolvedPath = path7.isAbsolute(filePath) ? filePath : path7.join(workingDir, filePath);
|
|
8923
|
-
if (!
|
|
8924
|
-
if (
|
|
8925
|
-
const content2 =
|
|
9170
|
+
if (!fs5.existsSync(resolvedPath)) {
|
|
9171
|
+
if (fs5.existsSync(filePath)) {
|
|
9172
|
+
const content2 = fs5.readFileSync(filePath, "utf8");
|
|
8926
9173
|
const lines2 = content2.split("\n");
|
|
8927
9174
|
this.fileCache.set(filePath, lines2);
|
|
8928
9175
|
return lines2;
|
|
8929
9176
|
}
|
|
8930
9177
|
return null;
|
|
8931
9178
|
}
|
|
8932
|
-
const content =
|
|
9179
|
+
const content = fs5.readFileSync(resolvedPath, "utf8");
|
|
8933
9180
|
const lines = content.split("\n");
|
|
8934
9181
|
this.fileCache.set(filePath, lines);
|
|
8935
9182
|
return lines;
|
|
@@ -10369,11 +10616,11 @@ var init_config_merger = __esm({
|
|
|
10369
10616
|
});
|
|
10370
10617
|
|
|
10371
10618
|
// src/utils/config-loader.ts
|
|
10372
|
-
var
|
|
10619
|
+
var fs7, path9, yaml2, ConfigLoader;
|
|
10373
10620
|
var init_config_loader = __esm({
|
|
10374
10621
|
"src/utils/config-loader.ts"() {
|
|
10375
10622
|
"use strict";
|
|
10376
|
-
|
|
10623
|
+
fs7 = __toESM(require("fs"));
|
|
10377
10624
|
path9 = __toESM(require("path"));
|
|
10378
10625
|
yaml2 = __toESM(require("js-yaml"));
|
|
10379
10626
|
ConfigLoader = class {
|
|
@@ -10468,7 +10715,7 @@ var init_config_loader = __esm({
|
|
|
10468
10715
|
const resolvedPath = path9.resolve(basePath, filePath);
|
|
10469
10716
|
this.validateLocalPath(resolvedPath);
|
|
10470
10717
|
try {
|
|
10471
|
-
const content =
|
|
10718
|
+
const content = fs7.readFileSync(resolvedPath, "utf8");
|
|
10472
10719
|
const config = yaml2.load(content);
|
|
10473
10720
|
if (!config || typeof config !== "object") {
|
|
10474
10721
|
throw new Error(`Invalid YAML in configuration file: ${resolvedPath}`);
|
|
@@ -10573,14 +10820,14 @@ var init_config_loader = __esm({
|
|
|
10573
10820
|
].filter((p) => p);
|
|
10574
10821
|
let defaultConfigPath;
|
|
10575
10822
|
for (const possiblePath of possiblePaths) {
|
|
10576
|
-
if (
|
|
10823
|
+
if (fs7.existsSync(possiblePath)) {
|
|
10577
10824
|
defaultConfigPath = possiblePath;
|
|
10578
10825
|
break;
|
|
10579
10826
|
}
|
|
10580
10827
|
}
|
|
10581
10828
|
if (defaultConfigPath) {
|
|
10582
10829
|
console.error(`\u{1F4E6} Loading bundled default configuration from ${defaultConfigPath}`);
|
|
10583
|
-
const content =
|
|
10830
|
+
const content = fs7.readFileSync(defaultConfigPath, "utf8");
|
|
10584
10831
|
let config = yaml2.load(content);
|
|
10585
10832
|
if (!config || typeof config !== "object") {
|
|
10586
10833
|
throw new Error("Invalid default configuration");
|
|
@@ -10701,9 +10948,9 @@ var init_config_loader = __esm({
|
|
|
10701
10948
|
const root = path9.parse(currentDir).root;
|
|
10702
10949
|
while (currentDir !== root) {
|
|
10703
10950
|
const packageJsonPath = path9.join(currentDir, "package.json");
|
|
10704
|
-
if (
|
|
10951
|
+
if (fs7.existsSync(packageJsonPath)) {
|
|
10705
10952
|
try {
|
|
10706
|
-
const packageJson = JSON.parse(
|
|
10953
|
+
const packageJson = JSON.parse(fs7.readFileSync(packageJsonPath, "utf8"));
|
|
10707
10954
|
if (packageJson.name === "@probelabs/visor") {
|
|
10708
10955
|
return currentDir;
|
|
10709
10956
|
}
|
|
@@ -11222,6 +11469,10 @@ var init_config_schema = __esm({
|
|
|
11222
11469
|
type: "string",
|
|
11223
11470
|
description: "JavaScript expression to dynamically compute custom tools for this AI check. Expression has access to: outputs, inputs, pr, files, env, memory Must return an array of tool names (strings) or WorkflowToolReference objects ({ workflow: string, args?: Record<string, unknown> })\n\nExample: ``` const tools = []; if (outputs['route-intent'].intent === 'engineer') { tools.push({ workflow: 'engineer', args: { projects: ['tyk'] } }); } return tools; ```"
|
|
11224
11471
|
},
|
|
11472
|
+
ai_bash_config_js: {
|
|
11473
|
+
type: "string",
|
|
11474
|
+
description: "JavaScript expression to dynamically compute bash configuration for this AI check. Expression has access to: outputs, inputs, pr, files, env, memory. Must return a BashConfig object with optional allow/deny string arrays.\n\nExample: ``` return outputs['build-config']?.bash_config ?? {}; ```"
|
|
11475
|
+
},
|
|
11225
11476
|
claude_code: {
|
|
11226
11477
|
$ref: "#/definitions/ClaudeCodeConfig",
|
|
11227
11478
|
description: "Claude Code configuration (for claude-code type checks)"
|
|
@@ -13126,12 +13377,12 @@ __export(config_exports, {
|
|
|
13126
13377
|
ConfigManager: () => ConfigManager,
|
|
13127
13378
|
VALID_EVENT_TRIGGERS: () => VALID_EVENT_TRIGGERS
|
|
13128
13379
|
});
|
|
13129
|
-
var yaml3,
|
|
13380
|
+
var yaml3, fs8, path10, import_simple_git, import_ajv3, import_ajv_formats2, VALID_EVENT_TRIGGERS, ConfigManager, __ajvValidate, __ajvErrors;
|
|
13130
13381
|
var init_config = __esm({
|
|
13131
13382
|
"src/config.ts"() {
|
|
13132
13383
|
"use strict";
|
|
13133
13384
|
yaml3 = __toESM(require("js-yaml"));
|
|
13134
|
-
|
|
13385
|
+
fs8 = __toESM(require("fs"));
|
|
13135
13386
|
path10 = __toESM(require("path"));
|
|
13136
13387
|
init_logger();
|
|
13137
13388
|
import_simple_git = __toESM(require("simple-git"));
|
|
@@ -13180,7 +13431,7 @@ var init_config = __esm({
|
|
|
13180
13431
|
try {
|
|
13181
13432
|
let configContent;
|
|
13182
13433
|
try {
|
|
13183
|
-
configContent =
|
|
13434
|
+
configContent = fs8.readFileSync(resolvedPath, "utf8");
|
|
13184
13435
|
} catch (readErr) {
|
|
13185
13436
|
if (readErr && (readErr.code === "ENOENT" || readErr.code === "ENOTDIR")) {
|
|
13186
13437
|
throw new Error(`Configuration file not found: ${resolvedPath}`);
|
|
@@ -13306,7 +13557,7 @@ var init_config = __esm({
|
|
|
13306
13557
|
);
|
|
13307
13558
|
for (const p of candidates) {
|
|
13308
13559
|
try {
|
|
13309
|
-
const st =
|
|
13560
|
+
const st = fs8.statSync(p);
|
|
13310
13561
|
if (!st.isFile()) continue;
|
|
13311
13562
|
const isLegacy = path10.basename(p).startsWith(".");
|
|
13312
13563
|
if (isLegacy) {
|
|
@@ -13390,7 +13641,7 @@ var init_config = __esm({
|
|
|
13390
13641
|
}
|
|
13391
13642
|
let bundledConfigPath;
|
|
13392
13643
|
for (const possiblePath of possiblePaths) {
|
|
13393
|
-
if (
|
|
13644
|
+
if (fs8.existsSync(possiblePath)) {
|
|
13394
13645
|
bundledConfigPath = possiblePath;
|
|
13395
13646
|
break;
|
|
13396
13647
|
}
|
|
@@ -13398,7 +13649,7 @@ var init_config = __esm({
|
|
|
13398
13649
|
if (bundledConfigPath) {
|
|
13399
13650
|
console.error(`\u{1F4E6} Loading bundled default configuration from ${bundledConfigPath}`);
|
|
13400
13651
|
const readAndParse = (p) => {
|
|
13401
|
-
const raw =
|
|
13652
|
+
const raw = fs8.readFileSync(p, "utf8");
|
|
13402
13653
|
const obj = yaml3.load(raw);
|
|
13403
13654
|
if (!obj || typeof obj !== "object") return {};
|
|
13404
13655
|
if (obj.include && !obj.extends) {
|
|
@@ -13446,9 +13697,9 @@ var init_config = __esm({
|
|
|
13446
13697
|
let currentDir = __dirname;
|
|
13447
13698
|
while (currentDir !== path10.dirname(currentDir)) {
|
|
13448
13699
|
const packageJsonPath = path10.join(currentDir, "package.json");
|
|
13449
|
-
if (
|
|
13700
|
+
if (fs8.existsSync(packageJsonPath)) {
|
|
13450
13701
|
try {
|
|
13451
|
-
const packageJson = JSON.parse(
|
|
13702
|
+
const packageJson = JSON.parse(fs8.readFileSync(packageJsonPath, "utf8"));
|
|
13452
13703
|
if (packageJson.name === "@probelabs/visor") {
|
|
13453
13704
|
return currentDir;
|
|
13454
13705
|
}
|
|
@@ -14212,7 +14463,7 @@ ${errors}`);
|
|
|
14212
14463
|
if (policy.engine === "local" && policy.rules) {
|
|
14213
14464
|
const rulesPath = Array.isArray(policy.rules) ? policy.rules : [policy.rules];
|
|
14214
14465
|
for (const rp of rulesPath) {
|
|
14215
|
-
if (typeof rp === "string" && !
|
|
14466
|
+
if (typeof rp === "string" && !fs8.existsSync(path10.resolve(rp))) {
|
|
14216
14467
|
warnings.push({
|
|
14217
14468
|
field: "policy.rules",
|
|
14218
14469
|
message: `Policy rules path does not exist: ${rp}. It will be resolved at runtime.`,
|
|
@@ -14262,7 +14513,7 @@ ${errors}`);
|
|
|
14262
14513
|
});
|
|
14263
14514
|
}
|
|
14264
14515
|
}
|
|
14265
|
-
if (policy.data && typeof policy.data === "string" && !
|
|
14516
|
+
if (policy.data && typeof policy.data === "string" && !fs8.existsSync(path10.resolve(policy.data))) {
|
|
14266
14517
|
warnings.push({
|
|
14267
14518
|
field: "policy.data",
|
|
14268
14519
|
message: `Policy data file does not exist: ${policy.data}. It will be resolved at runtime.`,
|
|
@@ -15045,6 +15296,31 @@ var init_workflow_check_provider = __esm({
|
|
|
15045
15296
|
`[WorkflowProvider] NO WORKSPACE from parent - nested checkouts won't be added to workspace!`
|
|
15046
15297
|
);
|
|
15047
15298
|
}
|
|
15299
|
+
const stepPrefix = config.checkName || workflow.id;
|
|
15300
|
+
const parentExecCtx = parentContext?.executionContext;
|
|
15301
|
+
let childExecCtx = parentExecCtx;
|
|
15302
|
+
if (parentExecCtx?.hooks) {
|
|
15303
|
+
const parentHooks = parentExecCtx.hooks;
|
|
15304
|
+
childExecCtx = {
|
|
15305
|
+
...parentExecCtx,
|
|
15306
|
+
hooks: {
|
|
15307
|
+
...parentHooks,
|
|
15308
|
+
// Wrap onPromptCaptured: emit with prefixed step name so parent sees "route-intent.classify"
|
|
15309
|
+
onPromptCaptured: parentHooks.onPromptCaptured ? (info) => {
|
|
15310
|
+
parentHooks.onPromptCaptured({
|
|
15311
|
+
...info,
|
|
15312
|
+
step: `${stepPrefix}.${info.step}`
|
|
15313
|
+
});
|
|
15314
|
+
} : void 0,
|
|
15315
|
+
// Wrap mockForStep: try prefixed name first, fall back to unprefixed for backward compat
|
|
15316
|
+
mockForStep: parentHooks.mockForStep ? (step) => {
|
|
15317
|
+
const prefixed = parentHooks.mockForStep(`${stepPrefix}.${step}`);
|
|
15318
|
+
if (prefixed !== void 0) return prefixed;
|
|
15319
|
+
return parentHooks.mockForStep(step);
|
|
15320
|
+
} : void 0
|
|
15321
|
+
}
|
|
15322
|
+
};
|
|
15323
|
+
}
|
|
15048
15324
|
const childContext = {
|
|
15049
15325
|
mode: "state-machine",
|
|
15050
15326
|
config: workflowConfig,
|
|
@@ -15066,9 +15342,9 @@ var init_workflow_check_provider = __esm({
|
|
|
15066
15342
|
debug: parentContext?.debug || false,
|
|
15067
15343
|
maxParallelism: parentContext?.maxParallelism,
|
|
15068
15344
|
failFast: parentContext?.failFast,
|
|
15069
|
-
// Propagate execution hooks (mocks, octokit, etc.) into the child so
|
|
15070
|
-
// nested steps can be mocked/observed by the YAML test runner.
|
|
15071
|
-
executionContext:
|
|
15345
|
+
// Propagate wrapped execution hooks (mocks, octokit, etc.) into the child so
|
|
15346
|
+
// nested steps can be mocked/observed by the YAML test runner with dotted prefixes.
|
|
15347
|
+
executionContext: childExecCtx,
|
|
15072
15348
|
// Ensure all workflow steps are considered requested to avoid tag/event filtering surprises
|
|
15073
15349
|
requestedChecks: Object.keys(checksMetadata)
|
|
15074
15350
|
};
|
|
@@ -15082,6 +15358,26 @@ var init_workflow_check_provider = __esm({
|
|
|
15082
15358
|
`[WorkflowProvider] Executing nested workflow '${workflow.id}' at depth ${currentDepth + 1}`
|
|
15083
15359
|
);
|
|
15084
15360
|
const result = await runner.run();
|
|
15361
|
+
if (parentContext?.journal && parentContext?.sessionId) {
|
|
15362
|
+
const parentJournal = parentContext.journal;
|
|
15363
|
+
const childSnapshot = childJournal.beginSnapshot();
|
|
15364
|
+
const childSessionId = childContext.sessionId;
|
|
15365
|
+
const childEntries = childJournal.readVisible(childSessionId, childSnapshot, void 0);
|
|
15366
|
+
for (const entry of childEntries) {
|
|
15367
|
+
parentJournal.commitEntry({
|
|
15368
|
+
sessionId: parentContext.sessionId,
|
|
15369
|
+
scope: entry.scope,
|
|
15370
|
+
checkId: `${stepPrefix}.${entry.checkId}`,
|
|
15371
|
+
result: entry.result,
|
|
15372
|
+
event: entry.event
|
|
15373
|
+
});
|
|
15374
|
+
}
|
|
15375
|
+
if (childEntries.length > 0) {
|
|
15376
|
+
logger.debug(
|
|
15377
|
+
`[WorkflowProvider] Propagated ${childEntries.length} child journal entries to parent with prefix '${stepPrefix}.'`
|
|
15378
|
+
);
|
|
15379
|
+
}
|
|
15380
|
+
}
|
|
15085
15381
|
const bubbledEvents = childContext._bubbledEvents || [];
|
|
15086
15382
|
if (bubbledEvents.length > 0 && parentContext) {
|
|
15087
15383
|
if (parentContext.debug) {
|
|
@@ -15285,13 +15581,13 @@ var init_workflow_check_provider = __esm({
|
|
|
15285
15581
|
*/
|
|
15286
15582
|
async loadWorkflowFromConfigPath(sourcePath, baseDir) {
|
|
15287
15583
|
const path25 = require("path");
|
|
15288
|
-
const
|
|
15584
|
+
const fs21 = require("fs");
|
|
15289
15585
|
const yaml5 = require("js-yaml");
|
|
15290
15586
|
const resolved = path25.isAbsolute(sourcePath) ? sourcePath : path25.resolve(baseDir, sourcePath);
|
|
15291
|
-
if (!
|
|
15587
|
+
if (!fs21.existsSync(resolved)) {
|
|
15292
15588
|
throw new Error(`Workflow config not found at: ${resolved}`);
|
|
15293
15589
|
}
|
|
15294
|
-
const rawContent =
|
|
15590
|
+
const rawContent = fs21.readFileSync(resolved, "utf8");
|
|
15295
15591
|
const rawData = yaml5.load(rawContent);
|
|
15296
15592
|
if (rawData.imports && Array.isArray(rawData.imports)) {
|
|
15297
15593
|
const configDir = path25.dirname(resolved);
|
|
@@ -15971,7 +16267,7 @@ async function migrateJsonToBackend(jsonPath, backend) {
|
|
|
15971
16267
|
const resolvedPath = import_path5.default.resolve(process.cwd(), jsonPath);
|
|
15972
16268
|
let content;
|
|
15973
16269
|
try {
|
|
15974
|
-
content = await
|
|
16270
|
+
content = await import_promises2.default.readFile(resolvedPath, "utf-8");
|
|
15975
16271
|
} catch (err) {
|
|
15976
16272
|
if (err.code === "ENOENT") {
|
|
15977
16273
|
return 0;
|
|
@@ -16018,7 +16314,7 @@ async function migrateJsonToBackend(jsonPath, backend) {
|
|
|
16018
16314
|
async function renameToMigrated(resolvedPath) {
|
|
16019
16315
|
const migratedPath = `${resolvedPath}.migrated`;
|
|
16020
16316
|
try {
|
|
16021
|
-
await
|
|
16317
|
+
await import_promises2.default.rename(resolvedPath, migratedPath);
|
|
16022
16318
|
logger.info(`[JsonMigrator] Backed up ${resolvedPath} \u2192 ${migratedPath}`);
|
|
16023
16319
|
} catch (err) {
|
|
16024
16320
|
logger.warn(
|
|
@@ -16026,11 +16322,11 @@ async function renameToMigrated(resolvedPath) {
|
|
|
16026
16322
|
);
|
|
16027
16323
|
}
|
|
16028
16324
|
}
|
|
16029
|
-
var
|
|
16325
|
+
var import_promises2, import_path5;
|
|
16030
16326
|
var init_json_migrator = __esm({
|
|
16031
16327
|
"src/scheduler/store/json-migrator.ts"() {
|
|
16032
16328
|
"use strict";
|
|
16033
|
-
|
|
16329
|
+
import_promises2 = __toESM(require("fs/promises"));
|
|
16034
16330
|
import_path5 = __toESM(require("path"));
|
|
16035
16331
|
init_logger();
|
|
16036
16332
|
}
|
|
@@ -16439,7 +16735,7 @@ function formatScheduleList(schedules) {
|
|
|
16439
16735
|
if (schedules.length === 0) {
|
|
16440
16736
|
return `You don't have any active schedules.
|
|
16441
16737
|
|
|
16442
|
-
To create one: "schedule daily-report every Monday at 9am"`;
|
|
16738
|
+
To create one: "remind me every Monday at 9am to check PRs" or "schedule %daily-report every Monday at 9am"`;
|
|
16443
16739
|
}
|
|
16444
16740
|
const lines = schedules.map((s, i) => `${i + 1}. ${formatSchedule(s)}`);
|
|
16445
16741
|
return `**Your active schedules:**
|
|
@@ -16715,6 +17011,12 @@ function getScheduleToolDefinition() {
|
|
|
16715
17011
|
|
|
16716
17012
|
YOU (the AI) must extract and structure all scheduling parameters. Do NOT pass natural language time expressions - convert them to cron or ISO timestamps.
|
|
16717
17013
|
|
|
17014
|
+
CRITICAL WORKFLOW RULE:
|
|
17015
|
+
- To schedule a WORKFLOW, the user MUST use a '%' prefix (e.g., "schedule %my-workflow daily").
|
|
17016
|
+
- If the '%' prefix is present, extract the word following it as the 'workflow' parameter (without the '%').
|
|
17017
|
+
- If the '%' prefix is NOT present, the request is a simple text reminder. The ENTIRE user request (excluding the schedule expression) MUST be placed in the 'reminder_text' parameter.
|
|
17018
|
+
- DO NOT guess or infer a workflow name from a user's request without the '%' prefix.
|
|
17019
|
+
|
|
16718
17020
|
ACTIONS:
|
|
16719
17021
|
- create: Schedule a new reminder or workflow
|
|
16720
17022
|
- list: Show user's active schedules
|
|
@@ -16722,7 +17024,9 @@ ACTIONS:
|
|
|
16722
17024
|
- pause/resume: Temporarily disable/enable a schedule
|
|
16723
17025
|
|
|
16724
17026
|
FOR CREATE ACTION - Extract these from user's request:
|
|
16725
|
-
1. WHAT:
|
|
17027
|
+
1. WHAT:
|
|
17028
|
+
- If user says "schedule %some-workflow ...", populate 'workflow' with "some-workflow".
|
|
17029
|
+
- Otherwise, populate 'reminder_text' with the user's full request text.
|
|
16726
17030
|
2. WHERE: Use the CURRENT channel from context
|
|
16727
17031
|
- target_id: The channel ID from context (C... for channels, D... for DMs)
|
|
16728
17032
|
- target_type: "channel" for public/private channels, "dm" for direct messages
|
|
@@ -16757,7 +17061,7 @@ User in DM: "remind me to check builds every day at 9am"
|
|
|
16757
17061
|
"original_expression": "every day at 9am"
|
|
16758
17062
|
}
|
|
16759
17063
|
|
|
16760
|
-
User in #security channel: "
|
|
17064
|
+
User in #security channel: "schedule %security-scan every Monday at 10am"
|
|
16761
17065
|
\u2192 {
|
|
16762
17066
|
"action": "create",
|
|
16763
17067
|
"workflow": "security-scan",
|
|
@@ -16768,6 +17072,17 @@ User in #security channel: "run security-scan every Monday at 10am"
|
|
|
16768
17072
|
"original_expression": "every Monday at 10am"
|
|
16769
17073
|
}
|
|
16770
17074
|
|
|
17075
|
+
User in #security channel: "run security-scan every Monday at 10am" (NO % prefix!)
|
|
17076
|
+
\u2192 {
|
|
17077
|
+
"action": "create",
|
|
17078
|
+
"reminder_text": "run security-scan every Monday at 10am",
|
|
17079
|
+
"is_recurring": true,
|
|
17080
|
+
"cron": "0 10 * * 1",
|
|
17081
|
+
"target_type": "channel",
|
|
17082
|
+
"target_id": "<channel ID from context, e.g., C05ABC123>",
|
|
17083
|
+
"original_expression": "every Monday at 10am"
|
|
17084
|
+
}
|
|
17085
|
+
|
|
16771
17086
|
User in DM: "remind me in 2 hours to review the PR"
|
|
16772
17087
|
\u2192 {
|
|
16773
17088
|
"action": "create",
|
|
@@ -16811,7 +17126,7 @@ User: "cancel schedule abc123"
|
|
|
16811
17126
|
},
|
|
16812
17127
|
workflow: {
|
|
16813
17128
|
type: "string",
|
|
16814
|
-
description:
|
|
17129
|
+
description: 'For create: workflow ID to run. ONLY populate this if the user used the % prefix (e.g., "%my-workflow"). Extract the name without the % symbol. If no % prefix, use reminder_text instead.'
|
|
16815
17130
|
},
|
|
16816
17131
|
workflow_inputs: {
|
|
16817
17132
|
type: "object",
|
|
@@ -17785,16 +18100,13 @@ var init_mcp_custom_sse_server = __esm({
|
|
|
17785
18100
|
logger.error(
|
|
17786
18101
|
`[CustomToolsSSEServer:${this.sessionId}] Tool execution failed: ${toolName} - ${errorMsg}`
|
|
17787
18102
|
);
|
|
18103
|
+
const isValidationError = errorMsg.startsWith("Invalid workflow inputs:");
|
|
17788
18104
|
return {
|
|
17789
18105
|
jsonrpc: "2.0",
|
|
17790
18106
|
id,
|
|
17791
18107
|
error: {
|
|
17792
|
-
code: -32603,
|
|
17793
|
-
message:
|
|
17794
|
-
data: {
|
|
17795
|
-
tool: toolName,
|
|
17796
|
-
error: errorMsg
|
|
17797
|
-
}
|
|
18108
|
+
code: isValidationError ? -32602 : -32603,
|
|
18109
|
+
message: isValidationError ? `Invalid tool parameters: ${errorMsg}` : `Internal error during tool execution: ${errorMsg}`
|
|
17798
18110
|
}
|
|
17799
18111
|
};
|
|
17800
18112
|
} finally {
|
|
@@ -17831,7 +18143,7 @@ var init_mcp_custom_sse_server = __esm({
|
|
|
17831
18143
|
});
|
|
17832
18144
|
|
|
17833
18145
|
// src/providers/ai-check-provider.ts
|
|
17834
|
-
var
|
|
18146
|
+
var import_promises3, import_path6, AICheckProvider;
|
|
17835
18147
|
var init_ai_check_provider = __esm({
|
|
17836
18148
|
"src/providers/ai-check-provider.ts"() {
|
|
17837
18149
|
"use strict";
|
|
@@ -17840,7 +18152,7 @@ var init_ai_check_provider = __esm({
|
|
|
17840
18152
|
init_env_resolver();
|
|
17841
18153
|
init_issue_filter();
|
|
17842
18154
|
init_liquid_extensions();
|
|
17843
|
-
|
|
18155
|
+
import_promises3 = __toESM(require("fs/promises"));
|
|
17844
18156
|
import_path6 = __toESM(require("path"));
|
|
17845
18157
|
init_lazy_otel();
|
|
17846
18158
|
init_state_capture();
|
|
@@ -18020,9 +18332,9 @@ var init_ai_check_provider = __esm({
|
|
|
18020
18332
|
} else {
|
|
18021
18333
|
resolvedPath = import_path6.default.resolve(process.cwd(), str);
|
|
18022
18334
|
}
|
|
18023
|
-
const
|
|
18335
|
+
const fs21 = require("fs").promises;
|
|
18024
18336
|
try {
|
|
18025
|
-
const stat = await
|
|
18337
|
+
const stat = await fs21.stat(resolvedPath);
|
|
18026
18338
|
return stat.isFile();
|
|
18027
18339
|
} catch {
|
|
18028
18340
|
return hasFileExtension && (isRelativePath || isAbsolutePath || hasPathSeparators);
|
|
@@ -18055,7 +18367,7 @@ var init_ai_check_provider = __esm({
|
|
|
18055
18367
|
throw new Error("Invalid prompt file path: path traversal detected");
|
|
18056
18368
|
}
|
|
18057
18369
|
try {
|
|
18058
|
-
const promptContent = await
|
|
18370
|
+
const promptContent = await import_promises3.default.readFile(resolvedPath, "utf-8");
|
|
18059
18371
|
return promptContent;
|
|
18060
18372
|
} catch (error) {
|
|
18061
18373
|
throw new Error(
|
|
@@ -18560,6 +18872,10 @@ ${preview}`);
|
|
|
18560
18872
|
if (config.ai_max_iterations !== void 0 && aiConfig.maxIterations === void 0) {
|
|
18561
18873
|
aiConfig.maxIterations = config.ai_max_iterations;
|
|
18562
18874
|
}
|
|
18875
|
+
const sharedLimiter = sessionInfo?._parentContext?.sharedConcurrencyLimiter;
|
|
18876
|
+
if (sharedLimiter) {
|
|
18877
|
+
aiConfig.concurrencyLimiter = sharedLimiter;
|
|
18878
|
+
}
|
|
18563
18879
|
const policyEngine = sessionInfo?._parentContext?.policyEngine;
|
|
18564
18880
|
if (policyEngine) {
|
|
18565
18881
|
try {
|
|
@@ -18791,13 +19107,13 @@ ${preview}`);
|
|
|
18791
19107
|
`[AICheckProvider] Started custom tools SSE server '${customToolsServerName}' on port ${port} for ${customTools.size} tools`
|
|
18792
19108
|
);
|
|
18793
19109
|
}
|
|
19110
|
+
const workflowToolTimeout = config.ai?.timeout || 18e5;
|
|
18794
19111
|
mcpServers[customToolsServerName] = {
|
|
18795
19112
|
command: "",
|
|
18796
19113
|
args: [],
|
|
18797
19114
|
url: `http://localhost:${port}/sse`,
|
|
18798
19115
|
transport: "sse",
|
|
18799
|
-
timeout:
|
|
18800
|
-
// 10 minutes for workflow tools
|
|
19116
|
+
timeout: workflowToolTimeout
|
|
18801
19117
|
};
|
|
18802
19118
|
}
|
|
18803
19119
|
} catch (error) {
|
|
@@ -18810,6 +19126,37 @@ ${preview}`);
|
|
|
18810
19126
|
aiConfig.mcpServers = mcpServers;
|
|
18811
19127
|
} else if (config.ai?.disableTools) {
|
|
18812
19128
|
}
|
|
19129
|
+
const bashConfigJsExpr = config.ai_bash_config_js;
|
|
19130
|
+
if (bashConfigJsExpr && _dependencyResults) {
|
|
19131
|
+
try {
|
|
19132
|
+
const dynamicBashConfig = this.evaluateBashConfigJs(
|
|
19133
|
+
bashConfigJsExpr,
|
|
19134
|
+
prInfo,
|
|
19135
|
+
_dependencyResults,
|
|
19136
|
+
config
|
|
19137
|
+
);
|
|
19138
|
+
if (!aiConfig.bashConfig) aiConfig.bashConfig = {};
|
|
19139
|
+
if (dynamicBashConfig.allow?.length) {
|
|
19140
|
+
aiConfig.bashConfig.allow = [
|
|
19141
|
+
...aiConfig.bashConfig.allow || [],
|
|
19142
|
+
...dynamicBashConfig.allow
|
|
19143
|
+
];
|
|
19144
|
+
}
|
|
19145
|
+
if (dynamicBashConfig.deny?.length) {
|
|
19146
|
+
aiConfig.bashConfig.deny = [
|
|
19147
|
+
...aiConfig.bashConfig.deny || [],
|
|
19148
|
+
...dynamicBashConfig.deny
|
|
19149
|
+
];
|
|
19150
|
+
}
|
|
19151
|
+
if (dynamicBashConfig.allow?.length || dynamicBashConfig.deny?.length) {
|
|
19152
|
+
aiConfig.allowBash = true;
|
|
19153
|
+
}
|
|
19154
|
+
} catch (error) {
|
|
19155
|
+
logger.error(
|
|
19156
|
+
`[AICheckProvider] Failed to evaluate ai_bash_config_js: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
19157
|
+
);
|
|
19158
|
+
}
|
|
19159
|
+
}
|
|
18813
19160
|
const templateContext = {
|
|
18814
19161
|
pr: {
|
|
18815
19162
|
number: prInfo.number,
|
|
@@ -18831,6 +19178,10 @@ ${preview}`);
|
|
|
18831
19178
|
const span = trace.getSpan(context.active());
|
|
18832
19179
|
if (span) {
|
|
18833
19180
|
captureCheckInputContext(span, templateContext);
|
|
19181
|
+
const spanTraceId = span.spanContext()?.traceId;
|
|
19182
|
+
if (spanTraceId) {
|
|
19183
|
+
prInfo.otelTraceId = spanTraceId;
|
|
19184
|
+
}
|
|
18834
19185
|
}
|
|
18835
19186
|
} catch {
|
|
18836
19187
|
}
|
|
@@ -19235,6 +19586,80 @@ ${processedPrompt}` : processedPrompt;
|
|
|
19235
19586
|
return {};
|
|
19236
19587
|
}
|
|
19237
19588
|
}
|
|
19589
|
+
/**
|
|
19590
|
+
* Evaluate ai_bash_config_js expression to dynamically compute bash configuration.
|
|
19591
|
+
* Returns a partial BashConfig object with optional allow/deny arrays.
|
|
19592
|
+
*/
|
|
19593
|
+
evaluateBashConfigJs(expression, prInfo, dependencyResults, config) {
|
|
19594
|
+
if (!this.sandbox) {
|
|
19595
|
+
this.sandbox = createSecureSandbox();
|
|
19596
|
+
}
|
|
19597
|
+
const outputs = {};
|
|
19598
|
+
for (const [checkId, result] of dependencyResults.entries()) {
|
|
19599
|
+
const summary = result;
|
|
19600
|
+
outputs[checkId] = summary.output !== void 0 ? summary.output : summary;
|
|
19601
|
+
}
|
|
19602
|
+
const jsContext = {
|
|
19603
|
+
outputs,
|
|
19604
|
+
inputs: config.inputs || {},
|
|
19605
|
+
pr: {
|
|
19606
|
+
number: prInfo.number,
|
|
19607
|
+
title: prInfo.title,
|
|
19608
|
+
description: prInfo.body,
|
|
19609
|
+
author: prInfo.author,
|
|
19610
|
+
branch: prInfo.head,
|
|
19611
|
+
base: prInfo.base,
|
|
19612
|
+
authorAssociation: prInfo.authorAssociation
|
|
19613
|
+
},
|
|
19614
|
+
files: prInfo.files?.map((f) => ({
|
|
19615
|
+
filename: f.filename,
|
|
19616
|
+
status: f.status,
|
|
19617
|
+
additions: f.additions,
|
|
19618
|
+
deletions: f.deletions,
|
|
19619
|
+
changes: f.changes
|
|
19620
|
+
})) || [],
|
|
19621
|
+
env: this.buildSafeEnv(),
|
|
19622
|
+
memory: config.__memoryAccessor || {}
|
|
19623
|
+
};
|
|
19624
|
+
try {
|
|
19625
|
+
const result = compileAndRun(this.sandbox, expression, jsContext, {
|
|
19626
|
+
injectLog: true,
|
|
19627
|
+
wrapFunction: true,
|
|
19628
|
+
logPrefix: "[ai_bash_config_js]"
|
|
19629
|
+
});
|
|
19630
|
+
if (typeof result !== "object" || result === null || Array.isArray(result)) {
|
|
19631
|
+
logger.warn(
|
|
19632
|
+
`[AICheckProvider] ai_bash_config_js must return an object, got ${Array.isArray(result) ? "array" : typeof result}`
|
|
19633
|
+
);
|
|
19634
|
+
return {};
|
|
19635
|
+
}
|
|
19636
|
+
const cfg = result;
|
|
19637
|
+
const validConfig = {};
|
|
19638
|
+
if (cfg.allow !== void 0) {
|
|
19639
|
+
if (Array.isArray(cfg.allow) && cfg.allow.every((item) => typeof item === "string")) {
|
|
19640
|
+
validConfig.allow = cfg.allow;
|
|
19641
|
+
} else {
|
|
19642
|
+
logger.warn(`[AICheckProvider] ai_bash_config_js: 'allow' must be a string array`);
|
|
19643
|
+
}
|
|
19644
|
+
}
|
|
19645
|
+
if (cfg.deny !== void 0) {
|
|
19646
|
+
if (Array.isArray(cfg.deny) && cfg.deny.every((item) => typeof item === "string")) {
|
|
19647
|
+
validConfig.deny = cfg.deny;
|
|
19648
|
+
} else {
|
|
19649
|
+
logger.warn(`[AICheckProvider] ai_bash_config_js: 'deny' must be a string array`);
|
|
19650
|
+
}
|
|
19651
|
+
}
|
|
19652
|
+
logger.debug(
|
|
19653
|
+
`[AICheckProvider] ai_bash_config_js evaluated: allow=${validConfig.allow?.length ?? 0}, deny=${validConfig.deny?.length ?? 0}`
|
|
19654
|
+
);
|
|
19655
|
+
return validConfig;
|
|
19656
|
+
} catch (error) {
|
|
19657
|
+
logger.error(
|
|
19658
|
+
`[AICheckProvider] Failed to evaluate ai_bash_config_js: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
19659
|
+
);
|
|
19660
|
+
return {};
|
|
19661
|
+
}
|
|
19662
|
+
}
|
|
19238
19663
|
/**
|
|
19239
19664
|
* Build a safe subset of environment variables for sandbox access.
|
|
19240
19665
|
* Excludes sensitive keys like API keys, secrets, tokens.
|
|
@@ -19331,6 +19756,7 @@ ${processedPrompt}` : processedPrompt;
|
|
|
19331
19756
|
"ai_mcp_servers_js",
|
|
19332
19757
|
"ai_custom_tools",
|
|
19333
19758
|
"ai_custom_tools_js",
|
|
19759
|
+
"ai_bash_config_js",
|
|
19334
19760
|
"env"
|
|
19335
19761
|
];
|
|
19336
19762
|
}
|
|
@@ -19825,7 +20251,7 @@ var init_template_context = __esm({
|
|
|
19825
20251
|
});
|
|
19826
20252
|
|
|
19827
20253
|
// src/providers/http-client-provider.ts
|
|
19828
|
-
var
|
|
20254
|
+
var fs12, path15, HttpClientProvider;
|
|
19829
20255
|
var init_http_client_provider = __esm({
|
|
19830
20256
|
"src/providers/http-client-provider.ts"() {
|
|
19831
20257
|
"use strict";
|
|
@@ -19835,7 +20261,7 @@ var init_http_client_provider = __esm({
|
|
|
19835
20261
|
init_sandbox();
|
|
19836
20262
|
init_template_context();
|
|
19837
20263
|
init_logger();
|
|
19838
|
-
|
|
20264
|
+
fs12 = __toESM(require("fs"));
|
|
19839
20265
|
path15 = __toESM(require("path"));
|
|
19840
20266
|
HttpClientProvider = class extends CheckProvider {
|
|
19841
20267
|
liquid;
|
|
@@ -19937,8 +20363,8 @@ var init_http_client_provider = __esm({
|
|
|
19937
20363
|
`[http_client] Resolved relative output_file to workspace: ${resolvedOutputFile}`
|
|
19938
20364
|
);
|
|
19939
20365
|
}
|
|
19940
|
-
if (skipIfExists &&
|
|
19941
|
-
const stats =
|
|
20366
|
+
if (skipIfExists && fs12.existsSync(resolvedOutputFile)) {
|
|
20367
|
+
const stats = fs12.statSync(resolvedOutputFile);
|
|
19942
20368
|
logger.verbose(`[http_client] File cached: ${resolvedOutputFile} (${stats.size} bytes)`);
|
|
19943
20369
|
return {
|
|
19944
20370
|
issues: [],
|
|
@@ -20150,12 +20576,12 @@ var init_http_client_provider = __esm({
|
|
|
20150
20576
|
};
|
|
20151
20577
|
}
|
|
20152
20578
|
const parentDir = path15.dirname(outputFile);
|
|
20153
|
-
if (parentDir && !
|
|
20154
|
-
|
|
20579
|
+
if (parentDir && !fs12.existsSync(parentDir)) {
|
|
20580
|
+
fs12.mkdirSync(parentDir, { recursive: true });
|
|
20155
20581
|
}
|
|
20156
20582
|
const arrayBuffer = await response.arrayBuffer();
|
|
20157
20583
|
const buffer = Buffer.from(arrayBuffer);
|
|
20158
|
-
|
|
20584
|
+
fs12.writeFileSync(outputFile, buffer);
|
|
20159
20585
|
const contentType = response.headers.get("content-type") || "application/octet-stream";
|
|
20160
20586
|
logger.verbose(`[http_client] Downloaded: ${outputFile} (${buffer.length} bytes)`);
|
|
20161
20587
|
return {
|
|
@@ -20914,7 +21340,7 @@ var init_claude_code_types = __esm({
|
|
|
20914
21340
|
function isClaudeCodeConstructor(value) {
|
|
20915
21341
|
return typeof value === "function";
|
|
20916
21342
|
}
|
|
20917
|
-
var
|
|
21343
|
+
var import_promises4, import_path7, ClaudeCodeSDKNotInstalledError, ClaudeCodeAPIKeyMissingError, ClaudeCodeCheckProvider;
|
|
20918
21344
|
var init_claude_code_check_provider = __esm({
|
|
20919
21345
|
"src/providers/claude-code-check-provider.ts"() {
|
|
20920
21346
|
"use strict";
|
|
@@ -20922,7 +21348,7 @@ var init_claude_code_check_provider = __esm({
|
|
|
20922
21348
|
init_env_resolver();
|
|
20923
21349
|
init_issue_filter();
|
|
20924
21350
|
init_liquid_extensions();
|
|
20925
|
-
|
|
21351
|
+
import_promises4 = __toESM(require("fs/promises"));
|
|
20926
21352
|
import_path7 = __toESM(require("path"));
|
|
20927
21353
|
init_claude_code_types();
|
|
20928
21354
|
ClaudeCodeSDKNotInstalledError = class extends Error {
|
|
@@ -21087,7 +21513,7 @@ var init_claude_code_check_provider = __esm({
|
|
|
21087
21513
|
resolvedPath = import_path7.default.resolve(process.cwd(), str);
|
|
21088
21514
|
}
|
|
21089
21515
|
try {
|
|
21090
|
-
const stat = await
|
|
21516
|
+
const stat = await import_promises4.default.stat(resolvedPath);
|
|
21091
21517
|
return stat.isFile();
|
|
21092
21518
|
} catch {
|
|
21093
21519
|
return hasFileExtension && (isRelativePath || isAbsolutePath || hasPathSeparators);
|
|
@@ -21120,7 +21546,7 @@ var init_claude_code_check_provider = __esm({
|
|
|
21120
21546
|
throw new Error("Invalid prompt file path: path traversal detected");
|
|
21121
21547
|
}
|
|
21122
21548
|
try {
|
|
21123
|
-
const promptContent = await
|
|
21549
|
+
const promptContent = await import_promises4.default.readFile(resolvedPath, "utf-8");
|
|
21124
21550
|
return promptContent;
|
|
21125
21551
|
} catch (error) {
|
|
21126
21552
|
throw new Error(
|
|
@@ -21678,19 +22104,7 @@ var init_command_check_provider = __esm({
|
|
|
21678
22104
|
}
|
|
21679
22105
|
}
|
|
21680
22106
|
const timeoutMs = config.timeout || 6e4;
|
|
21681
|
-
const
|
|
21682
|
-
const re = /^(?<prefix>\s*(?:\/usr\/bin\/env\s+)?node(?:\.exe)?\s+(?:-e|--eval)\s+)(['"])([\s\S]*?)\2(?<suffix>\s|$)/;
|
|
21683
|
-
const m = cmd.match(re);
|
|
21684
|
-
if (!m || !m.groups) return cmd;
|
|
21685
|
-
const prefix = m.groups.prefix;
|
|
21686
|
-
const quote = m[2];
|
|
21687
|
-
const code = m[3];
|
|
21688
|
-
const suffix = m.groups.suffix || "";
|
|
21689
|
-
if (!code.includes("\n")) return cmd;
|
|
21690
|
-
const escaped = code.replace(/\n/g, "\\n");
|
|
21691
|
-
return cmd.replace(re, `${prefix}${quote}${escaped}${quote}${suffix}`);
|
|
21692
|
-
};
|
|
21693
|
-
const safeCommand = normalizeNodeEval(renderedCommand);
|
|
22107
|
+
const safeCommand = renderedCommand;
|
|
21694
22108
|
const parentContext = context2?._parentContext;
|
|
21695
22109
|
const workingDirectory = parentContext?.workingDirectory;
|
|
21696
22110
|
const workspaceEnabled = parentContext?.workspace?.isEnabled?.();
|
|
@@ -41197,7 +41611,7 @@ var init_stdin_reader = __esm({
|
|
|
41197
41611
|
});
|
|
41198
41612
|
|
|
41199
41613
|
// src/providers/human-input-check-provider.ts
|
|
41200
|
-
var
|
|
41614
|
+
var fs14, path17, HumanInputCheckProvider;
|
|
41201
41615
|
var init_human_input_check_provider = __esm({
|
|
41202
41616
|
"src/providers/human-input-check-provider.ts"() {
|
|
41203
41617
|
"use strict";
|
|
@@ -41206,7 +41620,7 @@ var init_human_input_check_provider = __esm({
|
|
|
41206
41620
|
init_prompt_state();
|
|
41207
41621
|
init_liquid_extensions();
|
|
41208
41622
|
init_stdin_reader();
|
|
41209
|
-
|
|
41623
|
+
fs14 = __toESM(require("fs"));
|
|
41210
41624
|
path17 = __toESM(require("path"));
|
|
41211
41625
|
HumanInputCheckProvider = class _HumanInputCheckProvider extends CheckProvider {
|
|
41212
41626
|
liquid;
|
|
@@ -41388,12 +41802,12 @@ var init_human_input_check_provider = __esm({
|
|
|
41388
41802
|
return null;
|
|
41389
41803
|
}
|
|
41390
41804
|
try {
|
|
41391
|
-
await
|
|
41392
|
-
const stats = await
|
|
41805
|
+
await fs14.promises.access(normalizedPath, fs14.constants.R_OK);
|
|
41806
|
+
const stats = await fs14.promises.stat(normalizedPath);
|
|
41393
41807
|
if (!stats.isFile()) {
|
|
41394
41808
|
return null;
|
|
41395
41809
|
}
|
|
41396
|
-
const content = await
|
|
41810
|
+
const content = await fs14.promises.readFile(normalizedPath, "utf-8");
|
|
41397
41811
|
return content.trim();
|
|
41398
41812
|
} catch {
|
|
41399
41813
|
return null;
|
|
@@ -41835,11 +42249,11 @@ var init_script_check_provider = __esm({
|
|
|
41835
42249
|
});
|
|
41836
42250
|
|
|
41837
42251
|
// src/utils/worktree-manager.ts
|
|
41838
|
-
var
|
|
42252
|
+
var fs15, fsp, path18, crypto, WorktreeManager, worktreeManager;
|
|
41839
42253
|
var init_worktree_manager = __esm({
|
|
41840
42254
|
"src/utils/worktree-manager.ts"() {
|
|
41841
42255
|
"use strict";
|
|
41842
|
-
|
|
42256
|
+
fs15 = __toESM(require("fs"));
|
|
41843
42257
|
fsp = __toESM(require("fs/promises"));
|
|
41844
42258
|
path18 = __toESM(require("path"));
|
|
41845
42259
|
crypto = __toESM(require("crypto"));
|
|
@@ -41894,12 +42308,12 @@ var init_worktree_manager = __esm({
|
|
|
41894
42308
|
}
|
|
41895
42309
|
const reposDir = this.getReposDir();
|
|
41896
42310
|
const worktreesDir = this.getWorktreesDir();
|
|
41897
|
-
if (!
|
|
41898
|
-
|
|
42311
|
+
if (!fs15.existsSync(reposDir)) {
|
|
42312
|
+
fs15.mkdirSync(reposDir, { recursive: true });
|
|
41899
42313
|
logger.debug(`Created repos directory: ${reposDir}`);
|
|
41900
42314
|
}
|
|
41901
|
-
if (!
|
|
41902
|
-
|
|
42315
|
+
if (!fs15.existsSync(worktreesDir)) {
|
|
42316
|
+
fs15.mkdirSync(worktreesDir, { recursive: true });
|
|
41903
42317
|
logger.debug(`Created worktrees directory: ${worktreesDir}`);
|
|
41904
42318
|
}
|
|
41905
42319
|
}
|
|
@@ -41926,7 +42340,7 @@ var init_worktree_manager = __esm({
|
|
|
41926
42340
|
const reposDir = this.getReposDir();
|
|
41927
42341
|
const repoName = repository.replace(/\//g, "-");
|
|
41928
42342
|
const bareRepoPath = path18.join(reposDir, `${repoName}.git`);
|
|
41929
|
-
if (
|
|
42343
|
+
if (fs15.existsSync(bareRepoPath)) {
|
|
41930
42344
|
logger.debug(`Bare repository already exists: ${bareRepoPath}`);
|
|
41931
42345
|
const verifyResult = await this.verifyBareRepoRemote(bareRepoPath, repoUrl);
|
|
41932
42346
|
if (verifyResult === "timeout") {
|
|
@@ -42049,7 +42463,7 @@ var init_worktree_manager = __esm({
|
|
|
42049
42463
|
if (options.workingDirectory) {
|
|
42050
42464
|
worktreePath = this.validatePath(options.workingDirectory);
|
|
42051
42465
|
}
|
|
42052
|
-
if (
|
|
42466
|
+
if (fs15.existsSync(worktreePath)) {
|
|
42053
42467
|
logger.debug(`Worktree already exists: ${worktreePath}`);
|
|
42054
42468
|
const metadata2 = await this.loadMetadata(worktreePath);
|
|
42055
42469
|
if (metadata2) {
|
|
@@ -42290,9 +42704,9 @@ var init_worktree_manager = __esm({
|
|
|
42290
42704
|
const result = await this.executeGitCommand(removeCmd, { timeout: 3e4 });
|
|
42291
42705
|
if (result.exitCode !== 0) {
|
|
42292
42706
|
logger.warn(`Failed to remove worktree via git: ${result.stderr}`);
|
|
42293
|
-
if (
|
|
42707
|
+
if (fs15.existsSync(worktree_path)) {
|
|
42294
42708
|
logger.debug(`Manually removing worktree directory`);
|
|
42295
|
-
|
|
42709
|
+
fs15.rmSync(worktree_path, { recursive: true, force: true });
|
|
42296
42710
|
}
|
|
42297
42711
|
}
|
|
42298
42712
|
this.activeWorktrees.delete(worktreeId);
|
|
@@ -42303,18 +42717,18 @@ var init_worktree_manager = __esm({
|
|
|
42303
42717
|
*/
|
|
42304
42718
|
async saveMetadata(worktreePath, metadata) {
|
|
42305
42719
|
const metadataPath = path18.join(worktreePath, ".visor-metadata.json");
|
|
42306
|
-
|
|
42720
|
+
fs15.writeFileSync(metadataPath, JSON.stringify(metadata, null, 2), "utf8");
|
|
42307
42721
|
}
|
|
42308
42722
|
/**
|
|
42309
42723
|
* Load worktree metadata
|
|
42310
42724
|
*/
|
|
42311
42725
|
async loadMetadata(worktreePath) {
|
|
42312
42726
|
const metadataPath = path18.join(worktreePath, ".visor-metadata.json");
|
|
42313
|
-
if (!
|
|
42727
|
+
if (!fs15.existsSync(metadataPath)) {
|
|
42314
42728
|
return null;
|
|
42315
42729
|
}
|
|
42316
42730
|
try {
|
|
42317
|
-
const content =
|
|
42731
|
+
const content = fs15.readFileSync(metadataPath, "utf8");
|
|
42318
42732
|
return JSON.parse(content);
|
|
42319
42733
|
} catch (error) {
|
|
42320
42734
|
logger.warn(`Failed to load metadata: ${error}`);
|
|
@@ -42326,10 +42740,10 @@ var init_worktree_manager = __esm({
|
|
|
42326
42740
|
*/
|
|
42327
42741
|
async listWorktrees() {
|
|
42328
42742
|
const worktreesDir = this.getWorktreesDir();
|
|
42329
|
-
if (!
|
|
42743
|
+
if (!fs15.existsSync(worktreesDir)) {
|
|
42330
42744
|
return [];
|
|
42331
42745
|
}
|
|
42332
|
-
const entries =
|
|
42746
|
+
const entries = fs15.readdirSync(worktreesDir, { withFileTypes: true });
|
|
42333
42747
|
const worktrees = [];
|
|
42334
42748
|
for (const entry of entries) {
|
|
42335
42749
|
if (!entry.isDirectory()) continue;
|
|
@@ -44492,7 +44906,7 @@ __export(renderer_schema_exports, {
|
|
|
44492
44906
|
});
|
|
44493
44907
|
async function loadRendererSchema(name) {
|
|
44494
44908
|
try {
|
|
44495
|
-
const
|
|
44909
|
+
const fs21 = await import("fs/promises");
|
|
44496
44910
|
const path25 = await import("path");
|
|
44497
44911
|
const sanitized = String(name).replace(/[^a-zA-Z0-9-]/g, "");
|
|
44498
44912
|
if (!sanitized) return void 0;
|
|
@@ -44508,7 +44922,7 @@ async function loadRendererSchema(name) {
|
|
|
44508
44922
|
];
|
|
44509
44923
|
for (const p of candidates) {
|
|
44510
44924
|
try {
|
|
44511
|
-
const raw = await
|
|
44925
|
+
const raw = await fs21.readFile(p, "utf-8");
|
|
44512
44926
|
return JSON.parse(raw);
|
|
44513
44927
|
} catch {
|
|
44514
44928
|
}
|
|
@@ -46927,7 +47341,7 @@ function updateStats2(results, state, isForEachIteration = false) {
|
|
|
46927
47341
|
async function renderTemplateContent2(checkId, checkConfig, reviewSummary) {
|
|
46928
47342
|
try {
|
|
46929
47343
|
const { createExtendedLiquid: createExtendedLiquid2 } = await Promise.resolve().then(() => (init_liquid_extensions(), liquid_extensions_exports));
|
|
46930
|
-
const
|
|
47344
|
+
const fs21 = await import("fs/promises");
|
|
46931
47345
|
const path25 = await import("path");
|
|
46932
47346
|
const schemaRaw = checkConfig.schema || "plain";
|
|
46933
47347
|
const schema = typeof schemaRaw === "string" ? schemaRaw : "code-review";
|
|
@@ -46938,7 +47352,7 @@ async function renderTemplateContent2(checkId, checkConfig, reviewSummary) {
|
|
|
46938
47352
|
} else if (checkConfig.template && checkConfig.template.file) {
|
|
46939
47353
|
const file = String(checkConfig.template.file);
|
|
46940
47354
|
const resolved = path25.resolve(process.cwd(), file);
|
|
46941
|
-
templateContent = await
|
|
47355
|
+
templateContent = await fs21.readFile(resolved, "utf-8");
|
|
46942
47356
|
logger.debug(`[LevelDispatch] Using template file for ${checkId}: ${resolved}`);
|
|
46943
47357
|
} else if (schema && schema !== "plain") {
|
|
46944
47358
|
const sanitized = String(schema).replace(/[^a-zA-Z0-9-]/g, "");
|
|
@@ -46957,7 +47371,7 @@ async function renderTemplateContent2(checkId, checkConfig, reviewSummary) {
|
|
|
46957
47371
|
];
|
|
46958
47372
|
for (const p of candidatePaths) {
|
|
46959
47373
|
try {
|
|
46960
|
-
templateContent = await
|
|
47374
|
+
templateContent = await fs21.readFile(p, "utf-8");
|
|
46961
47375
|
if (templateContent) {
|
|
46962
47376
|
logger.debug(`[LevelDispatch] Using schema template for ${checkId}: ${p}`);
|
|
46963
47377
|
break;
|
|
@@ -47157,6 +47571,9 @@ var init_runner = __esm({
|
|
|
47157
47571
|
break;
|
|
47158
47572
|
}
|
|
47159
47573
|
}
|
|
47574
|
+
if (this.state.currentState === "Completed" && !this.context._parentContext && !process.env.VISOR_TEST_MODE) {
|
|
47575
|
+
logger.info("All workflows finished \u2014 waiting for events");
|
|
47576
|
+
}
|
|
47160
47577
|
return this.buildExecutionResult();
|
|
47161
47578
|
} catch (error) {
|
|
47162
47579
|
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
@@ -48195,12 +48612,12 @@ var init_sandbox_manager = __esm({
|
|
|
48195
48612
|
});
|
|
48196
48613
|
|
|
48197
48614
|
// src/utils/file-exclusion.ts
|
|
48198
|
-
var import_ignore,
|
|
48615
|
+
var import_ignore, fs16, path19, DEFAULT_EXCLUSION_PATTERNS, FileExclusionHelper;
|
|
48199
48616
|
var init_file_exclusion = __esm({
|
|
48200
48617
|
"src/utils/file-exclusion.ts"() {
|
|
48201
48618
|
"use strict";
|
|
48202
48619
|
import_ignore = __toESM(require("ignore"));
|
|
48203
|
-
|
|
48620
|
+
fs16 = __toESM(require("fs"));
|
|
48204
48621
|
path19 = __toESM(require("path"));
|
|
48205
48622
|
DEFAULT_EXCLUSION_PATTERNS = [
|
|
48206
48623
|
"dist/",
|
|
@@ -48246,8 +48663,8 @@ var init_file_exclusion = __esm({
|
|
|
48246
48663
|
if (additionalPatterns && additionalPatterns.length > 0) {
|
|
48247
48664
|
this.gitignore.add(additionalPatterns);
|
|
48248
48665
|
}
|
|
48249
|
-
if (
|
|
48250
|
-
const rawContent =
|
|
48666
|
+
if (fs16.existsSync(gitignorePath)) {
|
|
48667
|
+
const rawContent = fs16.readFileSync(gitignorePath, "utf8");
|
|
48251
48668
|
const gitignoreContent = rawContent.replace(/[\r\n]+/g, "\n").replace(/[\x00-\x09\x0B-\x1F\x7F]/g, "").split("\n").filter((line) => line.length < 1e3).join("\n").trim();
|
|
48252
48669
|
this.gitignore.add(gitignoreContent);
|
|
48253
48670
|
if (process.env.VISOR_DEBUG === "true") {
|
|
@@ -48279,13 +48696,13 @@ var git_repository_analyzer_exports = {};
|
|
|
48279
48696
|
__export(git_repository_analyzer_exports, {
|
|
48280
48697
|
GitRepositoryAnalyzer: () => GitRepositoryAnalyzer
|
|
48281
48698
|
});
|
|
48282
|
-
var import_simple_git2, path20,
|
|
48699
|
+
var import_simple_git2, path20, fs17, MAX_PATCH_SIZE, GitRepositoryAnalyzer;
|
|
48283
48700
|
var init_git_repository_analyzer = __esm({
|
|
48284
48701
|
"src/git-repository-analyzer.ts"() {
|
|
48285
48702
|
"use strict";
|
|
48286
48703
|
import_simple_git2 = require("simple-git");
|
|
48287
48704
|
path20 = __toESM(require("path"));
|
|
48288
|
-
|
|
48705
|
+
fs17 = __toESM(require("fs"));
|
|
48289
48706
|
init_file_exclusion();
|
|
48290
48707
|
MAX_PATCH_SIZE = 50 * 1024;
|
|
48291
48708
|
GitRepositoryAnalyzer = class {
|
|
@@ -48550,7 +48967,7 @@ ${file.patch}`).join("\n\n");
|
|
|
48550
48967
|
let content;
|
|
48551
48968
|
let truncated = false;
|
|
48552
48969
|
try {
|
|
48553
|
-
if (includeContext && status !== "added" &&
|
|
48970
|
+
if (includeContext && status !== "added" && fs17.existsSync(filePath)) {
|
|
48554
48971
|
const diff = await this.git.diff(["--", filename]).catch(() => "");
|
|
48555
48972
|
if (diff) {
|
|
48556
48973
|
const result = this.truncatePatch(diff, filename);
|
|
@@ -48560,7 +48977,7 @@ ${file.patch}`).join("\n\n");
|
|
|
48560
48977
|
additions = lines.filter((line) => line.startsWith("+")).length;
|
|
48561
48978
|
deletions = lines.filter((line) => line.startsWith("-")).length;
|
|
48562
48979
|
}
|
|
48563
|
-
} else if (status !== "added" &&
|
|
48980
|
+
} else if (status !== "added" && fs17.existsSync(filePath)) {
|
|
48564
48981
|
const diff = await this.git.diff(["--", filename]).catch(() => "");
|
|
48565
48982
|
if (diff) {
|
|
48566
48983
|
const lines = diff.split("\n");
|
|
@@ -48568,17 +48985,17 @@ ${file.patch}`).join("\n\n");
|
|
|
48568
48985
|
deletions = lines.filter((line) => line.startsWith("-")).length;
|
|
48569
48986
|
}
|
|
48570
48987
|
}
|
|
48571
|
-
if (status === "added" &&
|
|
48988
|
+
if (status === "added" && fs17.existsSync(filePath)) {
|
|
48572
48989
|
try {
|
|
48573
|
-
const stats =
|
|
48990
|
+
const stats = fs17.statSync(filePath);
|
|
48574
48991
|
if (stats.isFile() && stats.size < 1024 * 1024) {
|
|
48575
48992
|
if (includeContext) {
|
|
48576
|
-
content =
|
|
48993
|
+
content = fs17.readFileSync(filePath, "utf8");
|
|
48577
48994
|
const result = this.truncatePatch(content, filename);
|
|
48578
48995
|
patch = result.patch;
|
|
48579
48996
|
truncated = result.truncated;
|
|
48580
48997
|
}
|
|
48581
|
-
const fileContent = includeContext ? content :
|
|
48998
|
+
const fileContent = includeContext ? content : fs17.readFileSync(filePath, "utf8");
|
|
48582
48999
|
additions = fileContent.split("\n").length;
|
|
48583
49000
|
}
|
|
48584
49001
|
} catch {
|
|
@@ -49082,6 +49499,17 @@ function buildEngineContextForRun(workingDirectory, config, prInfo, debug, maxPa
|
|
|
49082
49499
|
}
|
|
49083
49500
|
const journal = new ExecutionJournal();
|
|
49084
49501
|
const memory = MemoryStore.getInstance(clonedConfig.memory);
|
|
49502
|
+
let sharedConcurrencyLimiter = void 0;
|
|
49503
|
+
if (clonedConfig.max_ai_concurrency && _DelegationManager) {
|
|
49504
|
+
sharedConcurrencyLimiter = new _DelegationManager({
|
|
49505
|
+
maxConcurrent: clonedConfig.max_ai_concurrency,
|
|
49506
|
+
maxPerSession: 999
|
|
49507
|
+
// No per-session limit needed for global AI gating
|
|
49508
|
+
});
|
|
49509
|
+
logger.debug(
|
|
49510
|
+
`[EngineContext] Created shared AI concurrency limiter (max: ${clonedConfig.max_ai_concurrency})`
|
|
49511
|
+
);
|
|
49512
|
+
}
|
|
49085
49513
|
return {
|
|
49086
49514
|
mode: "state-machine",
|
|
49087
49515
|
config: clonedConfig,
|
|
@@ -49094,6 +49522,7 @@ function buildEngineContextForRun(workingDirectory, config, prInfo, debug, maxPa
|
|
|
49094
49522
|
event: prInfo.eventType,
|
|
49095
49523
|
debug,
|
|
49096
49524
|
maxParallelism,
|
|
49525
|
+
sharedConcurrencyLimiter,
|
|
49097
49526
|
failFast,
|
|
49098
49527
|
requestedChecks: requestedChecks && requestedChecks.length > 0 ? requestedChecks : void 0,
|
|
49099
49528
|
// Store prInfo for later access (e.g., in getOutputHistorySnapshot)
|
|
@@ -49140,6 +49569,7 @@ async function initializeWorkspace(context2) {
|
|
|
49140
49569
|
return context2;
|
|
49141
49570
|
}
|
|
49142
49571
|
}
|
|
49572
|
+
var _DelegationManager;
|
|
49143
49573
|
var init_build_engine_context = __esm({
|
|
49144
49574
|
"src/state-machine/context/build-engine-context.ts"() {
|
|
49145
49575
|
"use strict";
|
|
@@ -49148,6 +49578,14 @@ var init_build_engine_context = __esm({
|
|
|
49148
49578
|
init_human_id();
|
|
49149
49579
|
init_logger();
|
|
49150
49580
|
init_workspace_manager();
|
|
49581
|
+
_DelegationManager = null;
|
|
49582
|
+
try {
|
|
49583
|
+
const probe = require("@probelabs/probe");
|
|
49584
|
+
if (probe && typeof probe.DelegationManager === "function") {
|
|
49585
|
+
_DelegationManager = probe.DelegationManager;
|
|
49586
|
+
}
|
|
49587
|
+
} catch {
|
|
49588
|
+
}
|
|
49151
49589
|
}
|
|
49152
49590
|
});
|
|
49153
49591
|
|
|
@@ -50956,7 +51394,7 @@ async function renderMermaidToPng(mermaidCode) {
|
|
|
50956
51394
|
`mermaid-${Date.now()}-${Math.random().toString(36).slice(2)}.png`
|
|
50957
51395
|
);
|
|
50958
51396
|
try {
|
|
50959
|
-
|
|
51397
|
+
fs19.writeFileSync(inputFile, mermaidCode, "utf-8");
|
|
50960
51398
|
const chromiumPaths = [
|
|
50961
51399
|
"/usr/bin/chromium",
|
|
50962
51400
|
"/usr/bin/chromium-browser",
|
|
@@ -50965,7 +51403,7 @@ async function renderMermaidToPng(mermaidCode) {
|
|
|
50965
51403
|
];
|
|
50966
51404
|
let chromiumPath;
|
|
50967
51405
|
for (const p of chromiumPaths) {
|
|
50968
|
-
if (
|
|
51406
|
+
if (fs19.existsSync(p)) {
|
|
50969
51407
|
chromiumPath = p;
|
|
50970
51408
|
break;
|
|
50971
51409
|
}
|
|
@@ -51017,19 +51455,19 @@ async function renderMermaidToPng(mermaidCode) {
|
|
|
51017
51455
|
console.warn(`Mermaid rendering failed: ${result.error}`);
|
|
51018
51456
|
return null;
|
|
51019
51457
|
}
|
|
51020
|
-
if (!
|
|
51458
|
+
if (!fs19.existsSync(outputFile)) {
|
|
51021
51459
|
console.warn("Mermaid output file not created");
|
|
51022
51460
|
return null;
|
|
51023
51461
|
}
|
|
51024
|
-
const pngBuffer =
|
|
51462
|
+
const pngBuffer = fs19.readFileSync(outputFile);
|
|
51025
51463
|
return pngBuffer;
|
|
51026
51464
|
} catch (e) {
|
|
51027
51465
|
console.warn(`Mermaid rendering error: ${e instanceof Error ? e.message : String(e)}`);
|
|
51028
51466
|
return null;
|
|
51029
51467
|
} finally {
|
|
51030
51468
|
try {
|
|
51031
|
-
if (
|
|
51032
|
-
if (
|
|
51469
|
+
if (fs19.existsSync(inputFile)) fs19.unlinkSync(inputFile);
|
|
51470
|
+
if (fs19.existsSync(outputFile)) fs19.unlinkSync(outputFile);
|
|
51033
51471
|
} catch {
|
|
51034
51472
|
}
|
|
51035
51473
|
}
|
|
@@ -51093,12 +51531,12 @@ function markdownToSlack(text) {
|
|
|
51093
51531
|
function formatSlackText(text) {
|
|
51094
51532
|
return markdownToSlack(text);
|
|
51095
51533
|
}
|
|
51096
|
-
var import_child_process5,
|
|
51534
|
+
var import_child_process5, fs19, path23, os;
|
|
51097
51535
|
var init_markdown = __esm({
|
|
51098
51536
|
"src/slack/markdown.ts"() {
|
|
51099
51537
|
"use strict";
|
|
51100
51538
|
import_child_process5 = require("child_process");
|
|
51101
|
-
|
|
51539
|
+
fs19 = __toESM(require("fs"));
|
|
51102
51540
|
path23 = __toESM(require("path"));
|
|
51103
51541
|
os = __toESM(require("os"));
|
|
51104
51542
|
}
|
|
@@ -52040,7 +52478,7 @@ function serializeRunState(state) {
|
|
|
52040
52478
|
])
|
|
52041
52479
|
};
|
|
52042
52480
|
}
|
|
52043
|
-
var path24,
|
|
52481
|
+
var path24, fs20, StateMachineExecutionEngine;
|
|
52044
52482
|
var init_state_machine_execution_engine = __esm({
|
|
52045
52483
|
"src/state-machine-execution-engine.ts"() {
|
|
52046
52484
|
"use strict";
|
|
@@ -52048,7 +52486,7 @@ var init_state_machine_execution_engine = __esm({
|
|
|
52048
52486
|
init_logger();
|
|
52049
52487
|
init_sandbox_manager();
|
|
52050
52488
|
path24 = __toESM(require("path"));
|
|
52051
|
-
|
|
52489
|
+
fs20 = __toESM(require("fs"));
|
|
52052
52490
|
StateMachineExecutionEngine = class _StateMachineExecutionEngine {
|
|
52053
52491
|
workingDirectory;
|
|
52054
52492
|
executionContext;
|
|
@@ -52425,7 +52863,7 @@ var init_state_machine_execution_engine = __esm({
|
|
|
52425
52863
|
const checkId = String(ev?.checkId || "unknown");
|
|
52426
52864
|
const threadKey = ev?.threadKey || (channel && threadTs ? `${channel}:${threadTs}` : "session");
|
|
52427
52865
|
const baseDir = process.env.VISOR_SNAPSHOT_DIR || path24.resolve(process.cwd(), ".visor", "snapshots");
|
|
52428
|
-
|
|
52866
|
+
fs20.mkdirSync(baseDir, { recursive: true });
|
|
52429
52867
|
const filePath = path24.join(baseDir, `${threadKey}-${checkId}.json`);
|
|
52430
52868
|
await this.saveSnapshotToFile(filePath);
|
|
52431
52869
|
logger.info(`[Snapshot] Saved run snapshot: ${filePath}`);
|
|
@@ -52567,7 +53005,7 @@ var init_state_machine_execution_engine = __esm({
|
|
|
52567
53005
|
* Does not include secrets. Intended for debugging and future resume support.
|
|
52568
53006
|
*/
|
|
52569
53007
|
async saveSnapshotToFile(filePath) {
|
|
52570
|
-
const
|
|
53008
|
+
const fs21 = await import("fs/promises");
|
|
52571
53009
|
const ctx = this._lastContext;
|
|
52572
53010
|
const runner = this._lastRunner;
|
|
52573
53011
|
if (!ctx || !runner) {
|
|
@@ -52587,14 +53025,14 @@ var init_state_machine_execution_engine = __esm({
|
|
|
52587
53025
|
journal: entries,
|
|
52588
53026
|
requestedChecks: ctx.requestedChecks || []
|
|
52589
53027
|
};
|
|
52590
|
-
await
|
|
53028
|
+
await fs21.writeFile(filePath, JSON.stringify(payload, null, 2), "utf8");
|
|
52591
53029
|
}
|
|
52592
53030
|
/**
|
|
52593
53031
|
* Load a snapshot JSON from file and return it. Resume support can build on this.
|
|
52594
53032
|
*/
|
|
52595
53033
|
async loadSnapshotFromFile(filePath) {
|
|
52596
|
-
const
|
|
52597
|
-
const raw = await
|
|
53034
|
+
const fs21 = await import("fs/promises");
|
|
53035
|
+
const raw = await fs21.readFile(filePath, "utf8");
|
|
52598
53036
|
return JSON.parse(raw);
|
|
52599
53037
|
}
|
|
52600
53038
|
/**
|