@probelabs/visor 0.1.127 → 0.1.129
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 +31 -1
- package/defaults/.visor.yaml +420 -0
- package/dist/ai-review-service.d.ts +1 -0
- package/dist/ai-review-service.d.ts.map +1 -1
- package/dist/cli-main.d.ts.map +1 -1
- package/dist/config.d.ts +4 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/daemon.js +19 -0
- package/dist/defaults/.visor.yaml +420 -0
- package/dist/docs/commands.md +1 -1
- package/dist/docs/debugging.md +133 -0
- package/dist/docs/dev-playbook.md +10 -0
- package/dist/docs/index.md +1 -0
- package/dist/docs/scheduler.md +503 -0
- package/dist/docs/slack-integration.md +21 -0
- package/dist/docs/timeouts.md +1 -1
- package/dist/docs/workflow-creation-guide.md +39 -0
- package/dist/examples/README.md +30 -0
- package/dist/examples/calculator-config.yaml +4 -4
- package/dist/examples/sandbox-basic.yaml +18 -0
- package/dist/examples/sandbox-cache.yaml +32 -0
- package/dist/examples/sandbox-dockerfile-inline.yaml +22 -0
- package/dist/examples/sandbox-env-passthrough.yaml +26 -0
- package/dist/examples/sandbox-multi-env.yaml +27 -0
- package/dist/examples/sandbox-read-only.yaml +33 -0
- package/dist/examples/scheduler-example.yaml +118 -0
- package/dist/frontends/host.d.ts.map +1 -1
- package/dist/frontends/slack-frontend.d.ts.map +1 -1
- package/dist/generated/config-schema.d.ts +230 -9
- package/dist/generated/config-schema.d.ts.map +1 -1
- package/dist/index.js +13676 -1604
- package/dist/mcp-server.d.ts +8 -8
- package/dist/{traces/run-2026-02-01T09-59-08-165Z.ndjson → output/traces/run-2026-02-08T18-16-04-160Z.ndjson} +84 -84
- package/dist/{traces/run-2026-02-01T09-59-52-595Z.ndjson → output/traces/run-2026-02-08T18-16-51-253Z.ndjson} +1029 -1029
- package/dist/providers/ai-check-provider.d.ts +16 -0
- package/dist/providers/ai-check-provider.d.ts.map +1 -1
- package/dist/providers/check-provider.interface.d.ts +5 -0
- package/dist/providers/check-provider.interface.d.ts.map +1 -1
- package/dist/providers/command-check-provider.d.ts.map +1 -1
- package/dist/providers/log-check-provider.d.ts.map +1 -1
- package/dist/providers/mcp-check-provider.d.ts +3 -0
- package/dist/providers/mcp-check-provider.d.ts.map +1 -1
- package/dist/providers/mcp-custom-sse-server.d.ts +22 -2
- package/dist/providers/mcp-custom-sse-server.d.ts.map +1 -1
- package/dist/providers/workflow-check-provider.d.ts.map +1 -1
- package/dist/providers/workflow-tool-executor.d.ts +2 -0
- package/dist/providers/workflow-tool-executor.d.ts.map +1 -1
- package/dist/sandbox/cache-volume-manager.d.ts +48 -0
- package/dist/sandbox/cache-volume-manager.d.ts.map +1 -0
- package/dist/sandbox/check-runner.d.ts +25 -0
- package/dist/sandbox/check-runner.d.ts.map +1 -0
- package/dist/sandbox/docker-compose-sandbox.d.ts +25 -0
- package/dist/sandbox/docker-compose-sandbox.d.ts.map +1 -0
- package/dist/sandbox/docker-image-sandbox.d.ts +32 -0
- package/dist/sandbox/docker-image-sandbox.d.ts.map +1 -0
- package/dist/sandbox/env-filter.d.ts +19 -0
- package/dist/sandbox/env-filter.d.ts.map +1 -0
- package/dist/sandbox/index.d.ts +9 -0
- package/dist/sandbox/index.d.ts.map +1 -0
- package/dist/sandbox/sandbox-manager.d.ts +39 -0
- package/dist/sandbox/sandbox-manager.d.ts.map +1 -0
- package/dist/sandbox/sandbox-telemetry.d.ts +9 -0
- package/dist/sandbox/sandbox-telemetry.d.ts.map +1 -0
- package/dist/sandbox/trace-ingester.d.ts +19 -0
- package/dist/sandbox/trace-ingester.d.ts.map +1 -0
- package/dist/sandbox/types.d.ts +149 -0
- package/dist/sandbox/types.d.ts.map +1 -0
- package/dist/scheduler/cli-handler.d.ts +6 -0
- package/dist/scheduler/cli-handler.d.ts.map +1 -0
- package/dist/scheduler/index.d.ts +14 -0
- package/dist/scheduler/index.d.ts.map +1 -0
- package/dist/scheduler/schedule-parser.d.ts +34 -0
- package/dist/scheduler/schedule-parser.d.ts.map +1 -0
- package/dist/scheduler/schedule-store.d.ts +182 -0
- package/dist/scheduler/schedule-store.d.ts.map +1 -0
- package/dist/scheduler/schedule-tool.d.ts +137 -0
- package/dist/scheduler/schedule-tool.d.ts.map +1 -0
- package/dist/scheduler/scheduler.d.ts +195 -0
- package/dist/scheduler/scheduler.d.ts.map +1 -0
- package/dist/sdk/check-provider-registry-ACRGIYOB.mjs +28 -0
- package/dist/sdk/check-provider-registry-VYHKFHK2.mjs +28 -0
- package/dist/sdk/{chunk-CNX7V5JK.mjs → chunk-25IC7KXZ.mjs} +2 -2
- package/dist/sdk/{chunk-IHZOSIF4.mjs → chunk-2KB35MB7.mjs} +3 -3
- package/dist/sdk/{chunk-HQL734ZI.mjs → chunk-6W75IMDC.mjs} +3 -3
- package/dist/sdk/{chunk-XWJPT5KQ.mjs → chunk-7YSOINAQ.mjs} +392 -18
- package/dist/sdk/chunk-7YSOINAQ.mjs.map +1 -0
- package/dist/sdk/{chunk-3OMWVM6J.mjs → chunk-B7BVQM5K.mjs} +2 -2
- package/dist/sdk/chunk-BDGUM6BA.mjs +38825 -0
- package/dist/sdk/chunk-BDGUM6BA.mjs.map +1 -0
- package/dist/sdk/{chunk-VW2GBXQT.mjs → chunk-D5KI4YQ4.mjs} +3 -3
- package/dist/sdk/chunk-DGZPPGJJ.mjs +38825 -0
- package/dist/sdk/chunk-DGZPPGJJ.mjs.map +1 -0
- package/dist/sdk/chunk-H5BOW5CR.mjs +91 -0
- package/dist/sdk/chunk-H5BOW5CR.mjs.map +1 -0
- package/dist/sdk/{chunk-YSN4G6CI.mjs → chunk-HEX3RL32.mjs} +81 -3
- package/dist/sdk/{chunk-YSN4G6CI.mjs.map → chunk-HEX3RL32.mjs.map} +1 -1
- package/dist/sdk/{chunk-ZYAUYXSW.mjs → chunk-J5RGJQ53.mjs} +14 -3
- package/dist/sdk/{chunk-ZYAUYXSW.mjs.map → chunk-J5RGJQ53.mjs.map} +1 -1
- package/dist/sdk/{chunk-WMJKH4XE.mjs → chunk-J7LXIPZS.mjs} +16 -1
- package/dist/sdk/{chunk-EXFGO4FX.mjs → chunk-KFKHU6CM.mjs} +2 -2
- package/dist/sdk/{chunk-MPS4HVQI.mjs → chunk-N7HO6KKC.mjs} +8 -8
- package/dist/sdk/{chunk-O5EZDNYL.mjs → chunk-NCWIZVOT.mjs} +2 -2
- package/dist/sdk/{chunk-3NMLT3YS.mjs → chunk-PO7X5XI7.mjs} +3 -3
- package/dist/sdk/{chunk-BHOKBQPB.mjs → chunk-R5Z7YWPB.mjs} +5 -5
- package/dist/sdk/{chunk-EORMDOZU.mjs → chunk-SGS2VMEL.mjs} +7 -7
- package/dist/sdk/{chunk-BOVFH3LI.mjs → chunk-VF6XIUE4.mjs} +21 -10
- package/dist/sdk/chunk-VF6XIUE4.mjs.map +1 -0
- package/dist/sdk/{chunk-J2QWVDXK.mjs → chunk-XDLQ3UNF.mjs} +3 -3
- package/dist/sdk/{chunk-S2RUE2RG.mjs → chunk-XR7XXGL7.mjs} +3 -3
- package/dist/sdk/{chunk-NAW3DB3I.mjs → chunk-XXAEN5KU.mjs} +3 -3
- package/dist/sdk/command-executor-DVVXERLR.mjs +14 -0
- package/dist/sdk/config-7VTT64SQ.mjs +16 -0
- package/dist/sdk/config-merger-RKCZJQ44.mjs +10 -0
- package/dist/sdk/event-bus-5K3Y2FCS.mjs +43 -0
- package/dist/sdk/{event-bus-5BEVPQ6T.mjs.map → event-bus-5K3Y2FCS.mjs.map} +1 -1
- package/dist/sdk/failure-condition-evaluator-4WMDF4Q3.mjs +17 -0
- package/dist/sdk/git-repository-analyzer-QFMW6WIS.mjs +471 -0
- package/dist/sdk/git-repository-analyzer-QFMW6WIS.mjs.map +1 -0
- package/dist/sdk/{github-frontend-5PCKKHVC.mjs → github-frontend-3N2NLO66.mjs} +520 -588
- package/dist/sdk/github-frontend-3N2NLO66.mjs.map +1 -0
- package/dist/sdk/host-ONVMEHAA.mjs +63 -0
- package/dist/sdk/host-ONVMEHAA.mjs.map +1 -0
- package/dist/sdk/{liquid-extensions-I7O7KMHF.mjs → liquid-extensions-5IZLTFSZ.mjs} +8 -8
- package/dist/sdk/memory-store-3N4AZCYB.mjs +12 -0
- package/dist/sdk/{metrics-7PP3EJUH.mjs → metrics-GXQ2EDXA.mjs} +4 -4
- package/dist/sdk/ndjson-sink-FD2PSXGD.mjs +52 -0
- package/dist/sdk/{ndjson-sink-B4V4NTAQ.mjs.map → ndjson-sink-FD2PSXGD.mjs.map} +1 -1
- package/dist/sdk/{prompt-state-EZYOUG75.mjs → prompt-state-YHGXB2OA.mjs} +5 -5
- package/dist/sdk/{renderer-schema-CKFB5NDB.mjs → renderer-schema-CMXOLNIG.mjs} +4 -4
- package/dist/sdk/routing-S3Y7T2X3.mjs +24 -0
- package/dist/sdk/sdk.d.mts +212 -4
- package/dist/sdk/sdk.d.ts +212 -4
- package/dist/sdk/sdk.js +26927 -6264
- package/dist/sdk/sdk.js.map +1 -1
- package/dist/sdk/sdk.mjs +23 -1278
- package/dist/sdk/sdk.mjs.map +1 -1
- package/dist/sdk/session-registry-6PV6SGEJ.mjs +10 -0
- package/dist/sdk/slack-frontend-R3M2CACB.mjs +899 -0
- package/dist/sdk/slack-frontend-R3M2CACB.mjs.map +1 -0
- package/dist/sdk/{trace-helpers-VP6QYVBX.mjs → trace-helpers-YHNPC7MR.mjs} +4 -4
- package/dist/sdk/tracer-init-XPRWKMZT.mjs +10 -0
- package/dist/sdk/tui-frontend-S546M7A7.mjs +281 -0
- package/dist/sdk/tui-frontend-S546M7A7.mjs.map +1 -0
- package/dist/sdk/workflow-check-provider-4F3432ZP.mjs +28 -0
- package/dist/sdk/workflow-check-provider-A44PBPG2.mjs +28 -0
- package/dist/sdk/workflow-check-provider-A44PBPG2.mjs.map +1 -0
- package/dist/sdk/workflow-registry-ZAYYXLEP.mjs +12 -0
- package/dist/sdk/workflow-registry-ZAYYXLEP.mjs.map +1 -0
- package/dist/slack/client.d.ts +28 -0
- package/dist/slack/client.d.ts.map +1 -1
- package/dist/slack/schedule-tool-handler.d.ts +46 -0
- package/dist/slack/schedule-tool-handler.d.ts.map +1 -0
- package/dist/slack/slack-output-adapter.d.ts +44 -0
- package/dist/slack/slack-output-adapter.d.ts.map +1 -0
- package/dist/slack/socket-runner.d.ts +22 -0
- package/dist/slack/socket-runner.d.ts.map +1 -1
- package/dist/state-machine/dispatch/execution-invoker.d.ts.map +1 -1
- package/dist/state-machine/dispatch/foreach-processor.d.ts.map +1 -1
- package/dist/state-machine/dispatch/sandbox-routing.d.ts +21 -0
- package/dist/state-machine/dispatch/sandbox-routing.d.ts.map +1 -0
- package/dist/state-machine/states/level-dispatch.d.ts.map +1 -1
- package/dist/state-machine-execution-engine.d.ts.map +1 -1
- package/dist/test-runner/index.d.ts +5 -0
- package/dist/test-runner/index.d.ts.map +1 -1
- package/dist/{output/traces/run-2026-02-01T09-59-08-165Z.ndjson → traces/run-2026-02-08T18-16-04-160Z.ndjson} +84 -84
- package/dist/{output/traces/run-2026-02-01T09-59-52-595Z.ndjson → traces/run-2026-02-08T18-16-51-253Z.ndjson} +1029 -1029
- package/dist/tui/chat-runner.d.ts +39 -0
- package/dist/tui/chat-runner.d.ts.map +1 -0
- package/dist/tui/chat-state.d.ts +56 -0
- package/dist/tui/chat-state.d.ts.map +1 -0
- package/dist/tui/chat-tui.d.ts +69 -0
- package/dist/tui/chat-tui.d.ts.map +1 -0
- package/dist/tui/components/chat-box.d.ts +33 -0
- package/dist/tui/components/chat-box.d.ts.map +1 -0
- package/dist/tui/components/input-bar.d.ts +50 -0
- package/dist/tui/components/input-bar.d.ts.map +1 -0
- package/dist/tui/components/status-bar.d.ts +31 -0
- package/dist/tui/components/status-bar.d.ts.map +1 -0
- package/dist/tui/components/trace-viewer.d.ts +73 -0
- package/dist/tui/components/trace-viewer.d.ts.map +1 -0
- package/dist/tui/index.d.ts +14 -0
- package/dist/tui/index.d.ts.map +1 -0
- package/dist/tui/tui-frontend.d.ts +29 -0
- package/dist/tui/tui-frontend.d.ts.map +1 -0
- package/dist/types/bot.d.ts +35 -0
- package/dist/types/bot.d.ts.map +1 -1
- package/dist/types/config.d.ts +152 -3
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/engine.d.ts +3 -0
- package/dist/types/engine.d.ts.map +1 -1
- package/dist/utils/sandbox.d.ts.map +1 -1
- package/dist/utils/workspace-manager.d.ts +22 -2
- package/dist/utils/workspace-manager.d.ts.map +1 -1
- package/dist/utils/worktree-manager.d.ts +2 -1
- package/dist/utils/worktree-manager.d.ts.map +1 -1
- package/package.json +4 -2
- package/dist/docs/NPM_USAGE.md +0 -281
- package/dist/generated/config-schema.json +0 -2161
- package/dist/sdk/check-provider-registry-CVUONJ5A.mjs +0 -28
- package/dist/sdk/chunk-BOVFH3LI.mjs.map +0 -1
- package/dist/sdk/chunk-TS6BUNAI.mjs +0 -17722
- package/dist/sdk/chunk-TS6BUNAI.mjs.map +0 -1
- package/dist/sdk/chunk-XWJPT5KQ.mjs.map +0 -1
- package/dist/sdk/command-executor-Q7MHJKZJ.mjs +0 -14
- package/dist/sdk/config-DXX64GD3.mjs +0 -16
- package/dist/sdk/config-merger-PX3WIT57.mjs +0 -10
- package/dist/sdk/event-bus-5BEVPQ6T.mjs +0 -35
- package/dist/sdk/failure-condition-evaluator-G4HMJPXF.mjs +0 -17
- package/dist/sdk/git-repository-analyzer-HJC4MYW4.mjs +0 -458
- package/dist/sdk/git-repository-analyzer-HJC4MYW4.mjs.map +0 -1
- package/dist/sdk/github-frontend-5PCKKHVC.mjs.map +0 -1
- package/dist/sdk/host-H3AWNZ2F.mjs +0 -52
- package/dist/sdk/host-H3AWNZ2F.mjs.map +0 -1
- package/dist/sdk/memory-store-RW5N2NGJ.mjs +0 -12
- package/dist/sdk/ndjson-sink-B4V4NTAQ.mjs +0 -44
- package/dist/sdk/routing-QHTGDIXF.mjs +0 -24
- package/dist/sdk/session-registry-4E6YRQ77.mjs +0 -10
- package/dist/sdk/slack-frontend-JUT3TYVC.mjs +0 -821
- package/dist/sdk/slack-frontend-JUT3TYVC.mjs.map +0 -1
- package/dist/sdk/tracer-init-GSLPPLCD.mjs +0 -10
- package/dist/sdk/workflow-check-provider-3IWBAZP7.mjs +0 -28
- package/dist/sdk/workflow-registry-KFWSDSLM.mjs +0 -12
- package/dist/tui.d.ts +0 -51
- package/dist/tui.d.ts.map +0 -1
- /package/dist/sdk/{check-provider-registry-CVUONJ5A.mjs.map → check-provider-registry-ACRGIYOB.mjs.map} +0 -0
- /package/dist/sdk/{chunk-WMJKH4XE.mjs.map → check-provider-registry-VYHKFHK2.mjs.map} +0 -0
- /package/dist/sdk/{chunk-CNX7V5JK.mjs.map → chunk-25IC7KXZ.mjs.map} +0 -0
- /package/dist/sdk/{chunk-IHZOSIF4.mjs.map → chunk-2KB35MB7.mjs.map} +0 -0
- /package/dist/sdk/{chunk-HQL734ZI.mjs.map → chunk-6W75IMDC.mjs.map} +0 -0
- /package/dist/sdk/{chunk-3OMWVM6J.mjs.map → chunk-B7BVQM5K.mjs.map} +0 -0
- /package/dist/sdk/{chunk-VW2GBXQT.mjs.map → chunk-D5KI4YQ4.mjs.map} +0 -0
- /package/dist/sdk/{command-executor-Q7MHJKZJ.mjs.map → chunk-J7LXIPZS.mjs.map} +0 -0
- /package/dist/sdk/{chunk-EXFGO4FX.mjs.map → chunk-KFKHU6CM.mjs.map} +0 -0
- /package/dist/sdk/{chunk-MPS4HVQI.mjs.map → chunk-N7HO6KKC.mjs.map} +0 -0
- /package/dist/sdk/{chunk-O5EZDNYL.mjs.map → chunk-NCWIZVOT.mjs.map} +0 -0
- /package/dist/sdk/{chunk-3NMLT3YS.mjs.map → chunk-PO7X5XI7.mjs.map} +0 -0
- /package/dist/sdk/{chunk-BHOKBQPB.mjs.map → chunk-R5Z7YWPB.mjs.map} +0 -0
- /package/dist/sdk/{chunk-EORMDOZU.mjs.map → chunk-SGS2VMEL.mjs.map} +0 -0
- /package/dist/sdk/{chunk-J2QWVDXK.mjs.map → chunk-XDLQ3UNF.mjs.map} +0 -0
- /package/dist/sdk/{chunk-S2RUE2RG.mjs.map → chunk-XR7XXGL7.mjs.map} +0 -0
- /package/dist/sdk/{chunk-NAW3DB3I.mjs.map → chunk-XXAEN5KU.mjs.map} +0 -0
- /package/dist/sdk/{config-DXX64GD3.mjs.map → command-executor-DVVXERLR.mjs.map} +0 -0
- /package/dist/sdk/{config-merger-PX3WIT57.mjs.map → config-7VTT64SQ.mjs.map} +0 -0
- /package/dist/sdk/{failure-condition-evaluator-G4HMJPXF.mjs.map → config-merger-RKCZJQ44.mjs.map} +0 -0
- /package/dist/sdk/{liquid-extensions-I7O7KMHF.mjs.map → failure-condition-evaluator-4WMDF4Q3.mjs.map} +0 -0
- /package/dist/sdk/{memory-store-RW5N2NGJ.mjs.map → liquid-extensions-5IZLTFSZ.mjs.map} +0 -0
- /package/dist/sdk/{metrics-7PP3EJUH.mjs.map → memory-store-3N4AZCYB.mjs.map} +0 -0
- /package/dist/sdk/{prompt-state-EZYOUG75.mjs.map → metrics-GXQ2EDXA.mjs.map} +0 -0
- /package/dist/sdk/{routing-QHTGDIXF.mjs.map → prompt-state-YHGXB2OA.mjs.map} +0 -0
- /package/dist/sdk/{renderer-schema-CKFB5NDB.mjs.map → renderer-schema-CMXOLNIG.mjs.map} +0 -0
- /package/dist/sdk/{session-registry-4E6YRQ77.mjs.map → routing-S3Y7T2X3.mjs.map} +0 -0
- /package/dist/sdk/{trace-helpers-VP6QYVBX.mjs.map → session-registry-6PV6SGEJ.mjs.map} +0 -0
- /package/dist/sdk/{tracer-init-GSLPPLCD.mjs.map → trace-helpers-YHNPC7MR.mjs.map} +0 -0
- /package/dist/sdk/{workflow-check-provider-3IWBAZP7.mjs.map → tracer-init-XPRWKMZT.mjs.map} +0 -0
- /package/dist/sdk/{workflow-registry-KFWSDSLM.mjs.map → workflow-check-provider-4F3432ZP.mjs.map} +0 -0
package/dist/sdk/sdk.mjs
CHANGED
|
@@ -1,1287 +1,32 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
import
|
|
8
|
-
|
|
9
|
-
init_human_id
|
|
10
|
-
} from "./chunk-EXFGO4FX.mjs";
|
|
11
|
-
import "./chunk-NAW3DB3I.mjs";
|
|
12
|
-
import {
|
|
13
|
-
commandExecutor,
|
|
14
|
-
init_command_executor
|
|
15
|
-
} from "./chunk-J2QWVDXK.mjs";
|
|
16
|
-
import "./chunk-VW2GBXQT.mjs";
|
|
2
|
+
StateMachineExecutionEngine,
|
|
3
|
+
init_state_machine_execution_engine
|
|
4
|
+
} from "./chunk-DGZPPGJJ.mjs";
|
|
5
|
+
import "./chunk-KFKHU6CM.mjs";
|
|
6
|
+
import "./chunk-XXAEN5KU.mjs";
|
|
7
|
+
import "./chunk-XDLQ3UNF.mjs";
|
|
8
|
+
import "./chunk-D5KI4YQ4.mjs";
|
|
17
9
|
import {
|
|
18
10
|
ConfigManager,
|
|
19
11
|
init_config
|
|
20
|
-
} from "./chunk-
|
|
21
|
-
import "./chunk-
|
|
22
|
-
import "./chunk-
|
|
23
|
-
import
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
import "./chunk-
|
|
28
|
-
import "./chunk-
|
|
29
|
-
import "./chunk-
|
|
30
|
-
import "./chunk-
|
|
31
|
-
import "./chunk-
|
|
32
|
-
import "./chunk-
|
|
33
|
-
import
|
|
34
|
-
|
|
35
|
-
init_memory_store
|
|
36
|
-
} from "./chunk-IHZOSIF4.mjs";
|
|
37
|
-
import {
|
|
38
|
-
init_logger,
|
|
39
|
-
logger
|
|
40
|
-
} from "./chunk-3NMLT3YS.mjs";
|
|
41
|
-
import "./chunk-YSN4G6CI.mjs";
|
|
42
|
-
import "./chunk-3OMWVM6J.mjs";
|
|
43
|
-
import {
|
|
44
|
-
__esm,
|
|
45
|
-
__export,
|
|
46
|
-
__toCommonJS
|
|
47
|
-
} from "./chunk-WMJKH4XE.mjs";
|
|
48
|
-
|
|
49
|
-
// src/utils/workspace-manager.ts
|
|
50
|
-
import * as fsp from "fs/promises";
|
|
51
|
-
import * as path from "path";
|
|
52
|
-
function shellEscape(str) {
|
|
53
|
-
return "'" + str.replace(/'/g, "'\\''") + "'";
|
|
54
|
-
}
|
|
55
|
-
function sanitizePathComponent(name) {
|
|
56
|
-
return name.replace(/\.\./g, "").replace(/[\/\\]/g, "-").replace(/^\.+/, "").trim() || "unnamed";
|
|
57
|
-
}
|
|
58
|
-
var WorkspaceManager;
|
|
59
|
-
var init_workspace_manager = __esm({
|
|
60
|
-
"src/utils/workspace-manager.ts"() {
|
|
61
|
-
"use strict";
|
|
62
|
-
init_command_executor();
|
|
63
|
-
init_logger();
|
|
64
|
-
WorkspaceManager = class _WorkspaceManager {
|
|
65
|
-
static instances = /* @__PURE__ */ new Map();
|
|
66
|
-
sessionId;
|
|
67
|
-
basePath;
|
|
68
|
-
workspacePath;
|
|
69
|
-
originalPath;
|
|
70
|
-
config;
|
|
71
|
-
initialized = false;
|
|
72
|
-
mainProjectInfo = null;
|
|
73
|
-
projects = /* @__PURE__ */ new Map();
|
|
74
|
-
cleanupHandlersRegistered = false;
|
|
75
|
-
usedNames = /* @__PURE__ */ new Set();
|
|
76
|
-
constructor(sessionId, originalPath, config) {
|
|
77
|
-
this.sessionId = sessionId;
|
|
78
|
-
this.originalPath = originalPath;
|
|
79
|
-
const configuredName = config?.name || process.env.VISOR_WORKSPACE_NAME;
|
|
80
|
-
const configuredMainProjectName = config?.mainProjectName || process.env.VISOR_WORKSPACE_PROJECT;
|
|
81
|
-
this.config = {
|
|
82
|
-
enabled: true,
|
|
83
|
-
basePath: process.env.VISOR_WORKSPACE_PATH || "/tmp/visor-workspaces",
|
|
84
|
-
cleanupOnExit: true,
|
|
85
|
-
name: configuredName,
|
|
86
|
-
mainProjectName: configuredMainProjectName,
|
|
87
|
-
...config
|
|
88
|
-
};
|
|
89
|
-
this.basePath = this.config.basePath;
|
|
90
|
-
const workspaceDirName = sanitizePathComponent(this.config.name || this.sessionId);
|
|
91
|
-
this.workspacePath = path.join(this.basePath, workspaceDirName);
|
|
92
|
-
}
|
|
93
|
-
/**
|
|
94
|
-
* Get or create a WorkspaceManager instance for a session
|
|
95
|
-
*/
|
|
96
|
-
static getInstance(sessionId, originalPath, config) {
|
|
97
|
-
if (!_WorkspaceManager.instances.has(sessionId)) {
|
|
98
|
-
_WorkspaceManager.instances.set(
|
|
99
|
-
sessionId,
|
|
100
|
-
new _WorkspaceManager(sessionId, originalPath, config)
|
|
101
|
-
);
|
|
102
|
-
}
|
|
103
|
-
return _WorkspaceManager.instances.get(sessionId);
|
|
104
|
-
}
|
|
105
|
-
/**
|
|
106
|
-
* Clear all instances (for testing)
|
|
107
|
-
*/
|
|
108
|
-
static clearInstances() {
|
|
109
|
-
_WorkspaceManager.instances.clear();
|
|
110
|
-
}
|
|
111
|
-
/**
|
|
112
|
-
* Check if workspace isolation is enabled
|
|
113
|
-
*/
|
|
114
|
-
isEnabled() {
|
|
115
|
-
return this.config.enabled;
|
|
116
|
-
}
|
|
117
|
-
/**
|
|
118
|
-
* Get the workspace path
|
|
119
|
-
*/
|
|
120
|
-
getWorkspacePath() {
|
|
121
|
-
return this.workspacePath;
|
|
122
|
-
}
|
|
123
|
-
/**
|
|
124
|
-
* Get the original working directory
|
|
125
|
-
*/
|
|
126
|
-
getOriginalPath() {
|
|
127
|
-
return this.originalPath;
|
|
128
|
-
}
|
|
129
|
-
/**
|
|
130
|
-
* Get workspace info (only available after initialize)
|
|
131
|
-
*/
|
|
132
|
-
getWorkspaceInfo() {
|
|
133
|
-
return this.mainProjectInfo;
|
|
134
|
-
}
|
|
135
|
-
/**
|
|
136
|
-
* Initialize the workspace - creates workspace directory and main project worktree
|
|
137
|
-
*/
|
|
138
|
-
async initialize() {
|
|
139
|
-
if (!this.config.enabled) {
|
|
140
|
-
throw new Error("Workspace isolation is not enabled");
|
|
141
|
-
}
|
|
142
|
-
if (this.initialized && this.mainProjectInfo) {
|
|
143
|
-
return this.mainProjectInfo;
|
|
144
|
-
}
|
|
145
|
-
logger.info(`Initializing workspace: ${this.workspacePath}`);
|
|
146
|
-
await fsp.mkdir(this.workspacePath, { recursive: true });
|
|
147
|
-
logger.debug(`Created workspace directory: ${this.workspacePath}`);
|
|
148
|
-
const configuredMainProjectName = this.config.mainProjectName;
|
|
149
|
-
const mainProjectName = sanitizePathComponent(
|
|
150
|
-
configuredMainProjectName || this.extractProjectName(this.originalPath)
|
|
151
|
-
);
|
|
152
|
-
this.usedNames.add(mainProjectName);
|
|
153
|
-
const mainProjectPath = path.join(this.workspacePath, mainProjectName);
|
|
154
|
-
const isGitRepo = await this.isGitRepository(this.originalPath);
|
|
155
|
-
if (isGitRepo) {
|
|
156
|
-
await this.createMainProjectWorktree(mainProjectPath);
|
|
157
|
-
} else {
|
|
158
|
-
logger.debug(`Original path is not a git repo, creating symlink`);
|
|
159
|
-
try {
|
|
160
|
-
await fsp.symlink(this.originalPath, mainProjectPath);
|
|
161
|
-
} catch (error) {
|
|
162
|
-
throw new Error(`Failed to create symlink for main project: ${error}`);
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
this.registerCleanupHandlers();
|
|
166
|
-
this.mainProjectInfo = {
|
|
167
|
-
sessionId: this.sessionId,
|
|
168
|
-
workspacePath: this.workspacePath,
|
|
169
|
-
mainProjectPath,
|
|
170
|
-
mainProjectName,
|
|
171
|
-
originalPath: this.originalPath
|
|
172
|
-
};
|
|
173
|
-
this.initialized = true;
|
|
174
|
-
logger.info(`Workspace initialized: ${this.workspacePath}`);
|
|
175
|
-
return this.mainProjectInfo;
|
|
176
|
-
}
|
|
177
|
-
/**
|
|
178
|
-
* Add a project to the workspace (creates symlink to worktree)
|
|
179
|
-
*/
|
|
180
|
-
async addProject(repository, worktreePath, description) {
|
|
181
|
-
if (!this.initialized) {
|
|
182
|
-
throw new Error("Workspace not initialized. Call initialize() first.");
|
|
183
|
-
}
|
|
184
|
-
let projectName = sanitizePathComponent(description || this.extractRepoName(repository));
|
|
185
|
-
projectName = this.getUniqueName(projectName);
|
|
186
|
-
this.usedNames.add(projectName);
|
|
187
|
-
const workspacePath = path.join(this.workspacePath, projectName);
|
|
188
|
-
await fsp.rm(workspacePath, { recursive: true, force: true });
|
|
189
|
-
try {
|
|
190
|
-
await fsp.symlink(worktreePath, workspacePath);
|
|
191
|
-
} catch (error) {
|
|
192
|
-
throw new Error(`Failed to create symlink for project ${projectName}: ${error}`);
|
|
193
|
-
}
|
|
194
|
-
this.projects.set(projectName, {
|
|
195
|
-
name: projectName,
|
|
196
|
-
path: workspacePath,
|
|
197
|
-
worktreePath,
|
|
198
|
-
repository
|
|
199
|
-
});
|
|
200
|
-
logger.info(`Added project to workspace: ${projectName} -> ${worktreePath}`);
|
|
201
|
-
return workspacePath;
|
|
202
|
-
}
|
|
203
|
-
/**
|
|
204
|
-
* List all projects in the workspace
|
|
205
|
-
*/
|
|
206
|
-
listProjects() {
|
|
207
|
-
return Array.from(this.projects.values());
|
|
208
|
-
}
|
|
209
|
-
/**
|
|
210
|
-
* Cleanup the workspace
|
|
211
|
-
*/
|
|
212
|
-
async cleanup() {
|
|
213
|
-
logger.info(`Cleaning up workspace: ${this.workspacePath}`);
|
|
214
|
-
try {
|
|
215
|
-
if (this.mainProjectInfo) {
|
|
216
|
-
const mainProjectPath = this.mainProjectInfo.mainProjectPath;
|
|
217
|
-
try {
|
|
218
|
-
const stats = await fsp.lstat(mainProjectPath);
|
|
219
|
-
if (!stats.isSymbolicLink()) {
|
|
220
|
-
await this.removeMainProjectWorktree(mainProjectPath);
|
|
221
|
-
}
|
|
222
|
-
} catch {
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
await fsp.rm(this.workspacePath, { recursive: true, force: true });
|
|
226
|
-
logger.debug(`Removed workspace directory: ${this.workspacePath}`);
|
|
227
|
-
_WorkspaceManager.instances.delete(this.sessionId);
|
|
228
|
-
this.initialized = false;
|
|
229
|
-
this.mainProjectInfo = null;
|
|
230
|
-
this.projects.clear();
|
|
231
|
-
this.usedNames.clear();
|
|
232
|
-
logger.info(`Workspace cleanup completed: ${this.sessionId}`);
|
|
233
|
-
} catch (error) {
|
|
234
|
-
logger.warn(`Failed to cleanup workspace: ${error}`);
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
/**
|
|
238
|
-
* Create worktree for the main project
|
|
239
|
-
*
|
|
240
|
-
* visor-disable: architecture - Not using WorktreeManager here because:
|
|
241
|
-
* 1. WorktreeManager expects remote URLs and clones to bare repos first
|
|
242
|
-
* 2. This operates on the LOCAL repo we're already in (no cloning needed)
|
|
243
|
-
* 3. Adding a "local mode" to WorktreeManager would add complexity for minimal benefit
|
|
244
|
-
* The git commands here are simpler (just rev-parse + worktree add) vs WorktreeManager's
|
|
245
|
-
* full clone/bare-repo/fetch/worktree pipeline.
|
|
246
|
-
*/
|
|
247
|
-
async createMainProjectWorktree(targetPath) {
|
|
248
|
-
logger.debug(`Creating main project worktree: ${targetPath}`);
|
|
249
|
-
const headResult = await commandExecutor.execute(
|
|
250
|
-
`git -C ${shellEscape(this.originalPath)} rev-parse HEAD`,
|
|
251
|
-
{
|
|
252
|
-
timeout: 1e4
|
|
253
|
-
}
|
|
254
|
-
);
|
|
255
|
-
if (headResult.exitCode !== 0) {
|
|
256
|
-
throw new Error(`Failed to get HEAD: ${headResult.stderr}`);
|
|
257
|
-
}
|
|
258
|
-
const headRef = headResult.stdout.trim();
|
|
259
|
-
const createCmd = `git -C ${shellEscape(this.originalPath)} worktree add --detach ${shellEscape(targetPath)} ${shellEscape(headRef)}`;
|
|
260
|
-
const result = await commandExecutor.execute(createCmd, { timeout: 6e4 });
|
|
261
|
-
if (result.exitCode !== 0) {
|
|
262
|
-
throw new Error(`Failed to create main project worktree: ${result.stderr}`);
|
|
263
|
-
}
|
|
264
|
-
logger.debug(`Created main project worktree at ${targetPath}`);
|
|
265
|
-
}
|
|
266
|
-
/**
|
|
267
|
-
* Remove main project worktree
|
|
268
|
-
*/
|
|
269
|
-
async removeMainProjectWorktree(worktreePath) {
|
|
270
|
-
logger.debug(`Removing main project worktree: ${worktreePath}`);
|
|
271
|
-
const removeCmd = `git -C ${shellEscape(this.originalPath)} worktree remove ${shellEscape(worktreePath)} --force`;
|
|
272
|
-
const result = await commandExecutor.execute(removeCmd, { timeout: 3e4 });
|
|
273
|
-
if (result.exitCode !== 0) {
|
|
274
|
-
logger.warn(`Failed to remove worktree via git: ${result.stderr}`);
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
/**
|
|
278
|
-
* Check if a path is a git repository
|
|
279
|
-
*/
|
|
280
|
-
async isGitRepository(dirPath) {
|
|
281
|
-
try {
|
|
282
|
-
const result = await commandExecutor.execute(
|
|
283
|
-
`git -C ${shellEscape(dirPath)} rev-parse --git-dir`,
|
|
284
|
-
{
|
|
285
|
-
timeout: 5e3
|
|
286
|
-
}
|
|
287
|
-
);
|
|
288
|
-
return result.exitCode === 0;
|
|
289
|
-
} catch {
|
|
290
|
-
return false;
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
/**
|
|
294
|
-
* Extract project name from path
|
|
295
|
-
*/
|
|
296
|
-
extractProjectName(dirPath) {
|
|
297
|
-
return path.basename(dirPath);
|
|
298
|
-
}
|
|
299
|
-
/**
|
|
300
|
-
* Extract repository name from owner/repo format
|
|
301
|
-
*/
|
|
302
|
-
extractRepoName(repository) {
|
|
303
|
-
if (repository.includes("://") || repository.startsWith("git@")) {
|
|
304
|
-
const match = repository.match(/[/:]([^/:]+\/[^/:]+?)(?:\.git)?$/);
|
|
305
|
-
if (match) {
|
|
306
|
-
return match[1].split("/").pop() || repository;
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
if (repository.includes("/")) {
|
|
310
|
-
return repository.split("/").pop() || repository;
|
|
311
|
-
}
|
|
312
|
-
return repository;
|
|
313
|
-
}
|
|
314
|
-
/**
|
|
315
|
-
* Get a unique name by appending a number if needed
|
|
316
|
-
*/
|
|
317
|
-
getUniqueName(baseName) {
|
|
318
|
-
if (!this.usedNames.has(baseName)) {
|
|
319
|
-
return baseName;
|
|
320
|
-
}
|
|
321
|
-
let counter = 2;
|
|
322
|
-
let uniqueName = `${baseName}-${counter}`;
|
|
323
|
-
while (this.usedNames.has(uniqueName)) {
|
|
324
|
-
counter++;
|
|
325
|
-
uniqueName = `${baseName}-${counter}`;
|
|
326
|
-
}
|
|
327
|
-
return uniqueName;
|
|
328
|
-
}
|
|
329
|
-
/**
|
|
330
|
-
* Register cleanup handlers for process exit
|
|
331
|
-
*/
|
|
332
|
-
registerCleanupHandlers() {
|
|
333
|
-
if (this.cleanupHandlersRegistered || !this.config.cleanupOnExit) {
|
|
334
|
-
return;
|
|
335
|
-
}
|
|
336
|
-
this.cleanupHandlersRegistered = true;
|
|
337
|
-
}
|
|
338
|
-
};
|
|
339
|
-
}
|
|
340
|
-
});
|
|
341
|
-
|
|
342
|
-
// src/state-machine/context/build-engine-context.ts
|
|
343
|
-
var build_engine_context_exports = {};
|
|
344
|
-
__export(build_engine_context_exports, {
|
|
345
|
-
buildEngineContextForRun: () => buildEngineContextForRun,
|
|
346
|
-
initializeWorkspace: () => initializeWorkspace
|
|
347
|
-
});
|
|
348
|
-
function applyCriticalityDefaults(cfg) {
|
|
349
|
-
const checks = cfg.checks || {};
|
|
350
|
-
for (const id of Object.keys(checks)) {
|
|
351
|
-
const c = checks[id];
|
|
352
|
-
if (!c.criticality) c.criticality = "policy";
|
|
353
|
-
if (c.criticality === "info" && typeof c.continue_on_failure === "undefined")
|
|
354
|
-
c.continue_on_failure = true;
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
|
-
function buildEngineContextForRun(workingDirectory, config, prInfo, debug, maxParallelism, failFast, requestedChecks) {
|
|
358
|
-
const clonedConfig = JSON.parse(JSON.stringify(config));
|
|
359
|
-
const checks = {};
|
|
360
|
-
applyCriticalityDefaults(clonedConfig);
|
|
361
|
-
for (const [checkId, checkConfig] of Object.entries(clonedConfig.checks || {})) {
|
|
362
|
-
checks[checkId] = {
|
|
363
|
-
tags: checkConfig.tags || [],
|
|
364
|
-
triggers: (Array.isArray(checkConfig.on) ? checkConfig.on : [checkConfig.on]).filter(
|
|
365
|
-
Boolean
|
|
366
|
-
),
|
|
367
|
-
group: checkConfig.group,
|
|
368
|
-
providerType: checkConfig.type || "ai",
|
|
369
|
-
// Normalize depends_on to array (supports string | string[])
|
|
370
|
-
dependencies: Array.isArray(checkConfig.depends_on) ? checkConfig.depends_on : checkConfig.depends_on ? [checkConfig.depends_on] : []
|
|
371
|
-
};
|
|
372
|
-
}
|
|
373
|
-
if (requestedChecks && requestedChecks.length > 0) {
|
|
374
|
-
for (const checkName of requestedChecks) {
|
|
375
|
-
if (!checks[checkName] && !clonedConfig.checks?.[checkName]) {
|
|
376
|
-
logger.debug(`[StateMachine] Synthesizing minimal config for legacy check: ${checkName}`);
|
|
377
|
-
if (!clonedConfig.checks) {
|
|
378
|
-
clonedConfig.checks = {};
|
|
379
|
-
}
|
|
380
|
-
clonedConfig.checks[checkName] = {
|
|
381
|
-
type: "ai",
|
|
382
|
-
prompt: `Perform ${checkName} analysis`
|
|
383
|
-
};
|
|
384
|
-
checks[checkName] = {
|
|
385
|
-
tags: [],
|
|
386
|
-
triggers: [],
|
|
387
|
-
group: "default",
|
|
388
|
-
providerType: "ai",
|
|
389
|
-
dependencies: []
|
|
390
|
-
};
|
|
391
|
-
}
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
|
-
const journal = new ExecutionJournal();
|
|
395
|
-
const memory = MemoryStore.getInstance(clonedConfig.memory);
|
|
396
|
-
return {
|
|
397
|
-
mode: "state-machine",
|
|
398
|
-
config: clonedConfig,
|
|
399
|
-
checks,
|
|
400
|
-
journal,
|
|
401
|
-
memory,
|
|
402
|
-
workingDirectory,
|
|
403
|
-
originalWorkingDirectory: workingDirectory,
|
|
404
|
-
sessionId: generateHumanId(),
|
|
405
|
-
event: prInfo.eventType,
|
|
406
|
-
debug,
|
|
407
|
-
maxParallelism,
|
|
408
|
-
failFast,
|
|
409
|
-
requestedChecks: requestedChecks && requestedChecks.length > 0 ? requestedChecks : void 0,
|
|
410
|
-
// Store prInfo for later access (e.g., in getOutputHistorySnapshot)
|
|
411
|
-
prInfo
|
|
412
|
-
};
|
|
413
|
-
}
|
|
414
|
-
async function initializeWorkspace(context) {
|
|
415
|
-
const workspaceConfig = context.config.workspace;
|
|
416
|
-
const isEnabled = workspaceConfig?.enabled !== false && process.env.VISOR_WORKSPACE_ENABLED !== "false";
|
|
417
|
-
if (!isEnabled) {
|
|
418
|
-
logger.debug("[Workspace] Workspace isolation is disabled");
|
|
419
|
-
return context;
|
|
420
|
-
}
|
|
421
|
-
const originalPath = context.workingDirectory || process.cwd();
|
|
422
|
-
try {
|
|
423
|
-
const keepWorkspace = process.env.VISOR_KEEP_WORKSPACE === "true";
|
|
424
|
-
const workspace = WorkspaceManager.getInstance(context.sessionId, originalPath, {
|
|
425
|
-
enabled: true,
|
|
426
|
-
basePath: workspaceConfig?.base_path || process.env.VISOR_WORKSPACE_PATH || "/tmp/visor-workspaces",
|
|
427
|
-
cleanupOnExit: keepWorkspace ? false : workspaceConfig?.cleanup_on_exit !== false,
|
|
428
|
-
name: workspaceConfig?.name || process.env.VISOR_WORKSPACE_NAME,
|
|
429
|
-
mainProjectName: workspaceConfig?.main_project_name || process.env.VISOR_WORKSPACE_PROJECT
|
|
430
|
-
});
|
|
431
|
-
const info = await workspace.initialize();
|
|
432
|
-
context.workspace = workspace;
|
|
433
|
-
context.workingDirectory = info.mainProjectPath;
|
|
434
|
-
context.originalWorkingDirectory = originalPath;
|
|
435
|
-
try {
|
|
436
|
-
process.env.VISOR_WORKSPACE_ROOT = info.workspacePath;
|
|
437
|
-
process.env.VISOR_WORKSPACE_MAIN_PROJECT = info.mainProjectPath;
|
|
438
|
-
process.env.VISOR_WORKSPACE_MAIN_PROJECT_NAME = info.mainProjectName;
|
|
439
|
-
process.env.VISOR_ORIGINAL_WORKDIR = originalPath;
|
|
440
|
-
} catch {
|
|
441
|
-
}
|
|
442
|
-
logger.info(`[Workspace] Initialized workspace: ${info.workspacePath}`);
|
|
443
|
-
logger.debug(`[Workspace] Main project at: ${info.mainProjectPath}`);
|
|
444
|
-
if (keepWorkspace) {
|
|
445
|
-
logger.info(`[Workspace] Keeping workspace after execution (--keep-workspace)`);
|
|
446
|
-
}
|
|
447
|
-
return context;
|
|
448
|
-
} catch (error) {
|
|
449
|
-
logger.warn(`[Workspace] Failed to initialize workspace: ${error}`);
|
|
450
|
-
logger.debug("[Workspace] Continuing without workspace isolation");
|
|
451
|
-
return context;
|
|
452
|
-
}
|
|
453
|
-
}
|
|
454
|
-
var init_build_engine_context = __esm({
|
|
455
|
-
"src/state-machine/context/build-engine-context.ts"() {
|
|
456
|
-
"use strict";
|
|
457
|
-
init_snapshot_store();
|
|
458
|
-
init_memory_store();
|
|
459
|
-
init_human_id();
|
|
460
|
-
init_logger();
|
|
461
|
-
init_workspace_manager();
|
|
462
|
-
}
|
|
463
|
-
});
|
|
464
|
-
|
|
465
|
-
// src/state-machine/execution/summary.ts
|
|
466
|
-
var summary_exports = {};
|
|
467
|
-
__export(summary_exports, {
|
|
468
|
-
convertToReviewSummary: () => convertToReviewSummary
|
|
469
|
-
});
|
|
470
|
-
function convertToReviewSummary(groupedResults, statistics) {
|
|
471
|
-
const allIssues = [];
|
|
472
|
-
for (const checkResults of Object.values(groupedResults)) {
|
|
473
|
-
for (const checkResult of checkResults) {
|
|
474
|
-
if (checkResult.issues && checkResult.issues.length > 0) {
|
|
475
|
-
allIssues.push(...checkResult.issues);
|
|
476
|
-
}
|
|
477
|
-
}
|
|
478
|
-
}
|
|
479
|
-
if (statistics) {
|
|
480
|
-
for (const checkStats of statistics.checks) {
|
|
481
|
-
if (checkStats.errorMessage) {
|
|
482
|
-
allIssues.push({
|
|
483
|
-
file: "system",
|
|
484
|
-
line: 0,
|
|
485
|
-
endLine: void 0,
|
|
486
|
-
ruleId: "system/error",
|
|
487
|
-
message: checkStats.errorMessage,
|
|
488
|
-
severity: "error",
|
|
489
|
-
category: "logic",
|
|
490
|
-
suggestion: void 0,
|
|
491
|
-
replacement: void 0
|
|
492
|
-
});
|
|
493
|
-
}
|
|
494
|
-
}
|
|
495
|
-
}
|
|
496
|
-
return {
|
|
497
|
-
issues: allIssues
|
|
498
|
-
};
|
|
499
|
-
}
|
|
500
|
-
var init_summary = __esm({
|
|
501
|
-
"src/state-machine/execution/summary.ts"() {
|
|
502
|
-
"use strict";
|
|
503
|
-
}
|
|
504
|
-
});
|
|
505
|
-
|
|
506
|
-
// src/state-machine-execution-engine.ts
|
|
507
|
-
init_runner();
|
|
508
|
-
init_logger();
|
|
509
|
-
import * as path2 from "path";
|
|
510
|
-
import * as fs from "fs";
|
|
511
|
-
var StateMachineExecutionEngine = class _StateMachineExecutionEngine {
|
|
512
|
-
workingDirectory;
|
|
513
|
-
executionContext;
|
|
514
|
-
debugServer;
|
|
515
|
-
_lastContext;
|
|
516
|
-
_lastRunner;
|
|
517
|
-
constructor(workingDirectory, octokit, debugServer) {
|
|
518
|
-
this.workingDirectory = workingDirectory || process.cwd();
|
|
519
|
-
this.debugServer = debugServer;
|
|
520
|
-
}
|
|
521
|
-
/**
|
|
522
|
-
* Execute checks using the state machine engine
|
|
523
|
-
*
|
|
524
|
-
* Converts CheckExecutionOptions -> executeGroupedChecks() -> AnalysisResult
|
|
525
|
-
*/
|
|
526
|
-
async executeChecks(options) {
|
|
527
|
-
const startTime = Date.now();
|
|
528
|
-
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
529
|
-
try {
|
|
530
|
-
if (options.config?.memory) {
|
|
531
|
-
const { MemoryStore: MemoryStore2 } = await import("./memory-store-RW5N2NGJ.mjs");
|
|
532
|
-
const memoryStore = MemoryStore2.getInstance(options.config.memory);
|
|
533
|
-
await memoryStore.initialize();
|
|
534
|
-
logger.debug("Memory store initialized");
|
|
535
|
-
}
|
|
536
|
-
const { GitRepositoryAnalyzer } = await import("./git-repository-analyzer-HJC4MYW4.mjs");
|
|
537
|
-
const gitAnalyzer = new GitRepositoryAnalyzer(options.workingDirectory);
|
|
538
|
-
logger.info("Analyzing local git repository...");
|
|
539
|
-
const repositoryInfo = await gitAnalyzer.analyzeRepository();
|
|
540
|
-
if (!repositoryInfo.isGitRepository) {
|
|
541
|
-
return this.createErrorResult(
|
|
542
|
-
repositoryInfo,
|
|
543
|
-
"Not a git repository or no changes found",
|
|
544
|
-
startTime,
|
|
545
|
-
timestamp,
|
|
546
|
-
options.checks
|
|
547
|
-
);
|
|
548
|
-
}
|
|
549
|
-
const prInfo = gitAnalyzer.toPRInfo(repositoryInfo);
|
|
550
|
-
try {
|
|
551
|
-
const evt = options.webhookContext?.eventType;
|
|
552
|
-
if (evt) prInfo.eventType = evt;
|
|
553
|
-
} catch {
|
|
554
|
-
}
|
|
555
|
-
const filteredChecks = this.filterChecksByTags(
|
|
556
|
-
options.checks,
|
|
557
|
-
options.config,
|
|
558
|
-
options.tagFilter || options.config?.tag_filter
|
|
559
|
-
);
|
|
560
|
-
if (filteredChecks.length === 0) {
|
|
561
|
-
logger.warn("No checks match the tag filter criteria");
|
|
562
|
-
return this.createErrorResult(
|
|
563
|
-
repositoryInfo,
|
|
564
|
-
"No checks match the tag filter criteria",
|
|
565
|
-
startTime,
|
|
566
|
-
timestamp,
|
|
567
|
-
options.checks
|
|
568
|
-
);
|
|
569
|
-
}
|
|
570
|
-
try {
|
|
571
|
-
const map = options?.webhookContext?.webhookData;
|
|
572
|
-
if (map) {
|
|
573
|
-
const { CheckProviderRegistry } = await import("./check-provider-registry-CVUONJ5A.mjs");
|
|
574
|
-
const reg = CheckProviderRegistry.getInstance();
|
|
575
|
-
const p = reg.getProvider("http_input");
|
|
576
|
-
if (p && typeof p.setWebhookContext === "function") p.setWebhookContext(map);
|
|
577
|
-
const prev = this.executionContext || {};
|
|
578
|
-
this.setExecutionContext({ ...prev, webhookContext: { webhookData: map } });
|
|
579
|
-
}
|
|
580
|
-
} catch {
|
|
581
|
-
}
|
|
582
|
-
logger.info(`Executing checks: ${filteredChecks.join(", ")}`);
|
|
583
|
-
const executionResult = await this.executeGroupedChecks(
|
|
584
|
-
prInfo,
|
|
585
|
-
filteredChecks,
|
|
586
|
-
options.timeout,
|
|
587
|
-
options.config,
|
|
588
|
-
options.outputFormat,
|
|
589
|
-
options.debug,
|
|
590
|
-
options.maxParallelism,
|
|
591
|
-
options.failFast,
|
|
592
|
-
options.tagFilter
|
|
593
|
-
);
|
|
594
|
-
const executionTime = Date.now() - startTime;
|
|
595
|
-
const reviewSummary = this.convertGroupedResultsToReviewSummary(
|
|
596
|
-
executionResult.results,
|
|
597
|
-
executionResult.statistics
|
|
598
|
-
);
|
|
599
|
-
let debugInfo;
|
|
600
|
-
if (options.debug && reviewSummary.debug) {
|
|
601
|
-
debugInfo = {
|
|
602
|
-
provider: reviewSummary.debug.provider,
|
|
603
|
-
model: reviewSummary.debug.model,
|
|
604
|
-
processingTime: reviewSummary.debug.processingTime,
|
|
605
|
-
parallelExecution: options.checks.length > 1,
|
|
606
|
-
checksExecuted: options.checks,
|
|
607
|
-
totalApiCalls: reviewSummary.debug.totalApiCalls || options.checks.length,
|
|
608
|
-
apiCallDetails: reviewSummary.debug.apiCallDetails
|
|
609
|
-
};
|
|
610
|
-
}
|
|
611
|
-
try {
|
|
612
|
-
const histSnap = this.getOutputHistorySnapshot();
|
|
613
|
-
reviewSummary.history = histSnap;
|
|
614
|
-
} catch {
|
|
615
|
-
}
|
|
616
|
-
return {
|
|
617
|
-
repositoryInfo,
|
|
618
|
-
reviewSummary,
|
|
619
|
-
executionTime,
|
|
620
|
-
timestamp,
|
|
621
|
-
checksExecuted: filteredChecks,
|
|
622
|
-
executionStatistics: executionResult.statistics,
|
|
623
|
-
debug: debugInfo
|
|
624
|
-
};
|
|
625
|
-
} catch (error) {
|
|
626
|
-
const message = error instanceof Error ? error.message : "Unknown error occurred";
|
|
627
|
-
logger.error("Error executing checks: " + message);
|
|
628
|
-
const strictEnv = process.env.VISOR_STRICT_ERRORS === "true";
|
|
629
|
-
if (strictEnv) {
|
|
630
|
-
throw error;
|
|
631
|
-
}
|
|
632
|
-
const fallbackRepositoryInfo = {
|
|
633
|
-
title: "Error during analysis",
|
|
634
|
-
body: `Error: ${message || "Unknown error"}`,
|
|
635
|
-
author: "system",
|
|
636
|
-
base: "main",
|
|
637
|
-
head: "HEAD",
|
|
638
|
-
files: [],
|
|
639
|
-
totalAdditions: 0,
|
|
640
|
-
totalDeletions: 0,
|
|
641
|
-
isGitRepository: false,
|
|
642
|
-
workingDirectory: options.workingDirectory || process.cwd()
|
|
643
|
-
};
|
|
644
|
-
return this.createErrorResult(
|
|
645
|
-
fallbackRepositoryInfo,
|
|
646
|
-
message || "Unknown error occurred",
|
|
647
|
-
startTime,
|
|
648
|
-
timestamp,
|
|
649
|
-
options.checks
|
|
650
|
-
);
|
|
651
|
-
}
|
|
652
|
-
}
|
|
653
|
-
/**
|
|
654
|
-
* Get execution context (used by state machine to propagate hooks)
|
|
655
|
-
*/
|
|
656
|
-
getExecutionContext() {
|
|
657
|
-
return this.executionContext;
|
|
658
|
-
}
|
|
659
|
-
/**
|
|
660
|
-
* Set execution context for external callers
|
|
661
|
-
*/
|
|
662
|
-
setExecutionContext(context) {
|
|
663
|
-
this.executionContext = context;
|
|
664
|
-
}
|
|
665
|
-
/**
|
|
666
|
-
* Reset per-run state (no-op for state machine engine)
|
|
667
|
-
*
|
|
668
|
-
* The state machine engine is stateless per-run by design.
|
|
669
|
-
* Each execution creates a fresh journal and context.
|
|
670
|
-
* This method exists only for backward compatibility with test framework.
|
|
671
|
-
*
|
|
672
|
-
* @deprecated This is a no-op. State machine engine doesn't maintain per-run state.
|
|
673
|
-
*/
|
|
674
|
-
resetPerRunState() {
|
|
675
|
-
}
|
|
676
|
-
/**
|
|
677
|
-
* Execute grouped checks using the state machine engine
|
|
678
|
-
*
|
|
679
|
-
* M4: Production-ready with full telemetry and debug server support
|
|
680
|
-
*/
|
|
681
|
-
async executeGroupedChecks(prInfo, checks, timeout, config, outputFormat, debug, maxParallelism, failFast, tagFilter, _pauseGate) {
|
|
682
|
-
if (debug) {
|
|
683
|
-
logger.info("[StateMachine] Using state machine engine");
|
|
684
|
-
}
|
|
685
|
-
if (!config) {
|
|
686
|
-
const { ConfigManager: ConfigManager2 } = await import("./config-DXX64GD3.mjs");
|
|
687
|
-
const configManager = new ConfigManager2();
|
|
688
|
-
config = await configManager.getDefaultConfig();
|
|
689
|
-
logger.debug("[StateMachine] Using default configuration (no config provided)");
|
|
690
|
-
}
|
|
691
|
-
const configWithTagFilter = tagFilter ? {
|
|
692
|
-
...config,
|
|
693
|
-
tag_filter: tagFilter
|
|
694
|
-
} : config;
|
|
695
|
-
const context = this.buildEngineContext(
|
|
696
|
-
configWithTagFilter,
|
|
697
|
-
prInfo,
|
|
698
|
-
debug,
|
|
699
|
-
maxParallelism,
|
|
700
|
-
failFast,
|
|
701
|
-
checks
|
|
702
|
-
// Pass the explicit checks list
|
|
703
|
-
);
|
|
704
|
-
const { initializeWorkspace: initializeWorkspace2 } = (init_build_engine_context(), __toCommonJS(build_engine_context_exports));
|
|
705
|
-
await initializeWorkspace2(context);
|
|
706
|
-
context.executionContext = this.getExecutionContext();
|
|
707
|
-
this._lastContext = context;
|
|
708
|
-
let frontendsHost;
|
|
709
|
-
if (Array.isArray(configWithTagFilter.frontends) && configWithTagFilter.frontends.length > 0) {
|
|
710
|
-
try {
|
|
711
|
-
const { EventBus } = await import("./event-bus-5BEVPQ6T.mjs");
|
|
712
|
-
const { FrontendsHost } = await import("./host-H3AWNZ2F.mjs");
|
|
713
|
-
const bus = new EventBus();
|
|
714
|
-
context.eventBus = bus;
|
|
715
|
-
frontendsHost = new FrontendsHost(bus, logger);
|
|
716
|
-
if (process.env.VISOR_DEBUG === "true") {
|
|
717
|
-
try {
|
|
718
|
-
const fns = (configWithTagFilter.frontends || []).map((f) => ({
|
|
719
|
-
name: f?.name,
|
|
720
|
-
hasConfig: !!f?.config,
|
|
721
|
-
cfg: f?.config || void 0
|
|
722
|
-
}));
|
|
723
|
-
logger.info(`[Frontends] Loading specs: ${JSON.stringify(fns)}`);
|
|
724
|
-
} catch {
|
|
725
|
-
}
|
|
726
|
-
}
|
|
727
|
-
await frontendsHost.load(configWithTagFilter.frontends);
|
|
728
|
-
let owner;
|
|
729
|
-
let name;
|
|
730
|
-
let prNum;
|
|
731
|
-
let headSha;
|
|
732
|
-
try {
|
|
733
|
-
const anyInfo = prInfo;
|
|
734
|
-
owner = anyInfo?.eventContext?.repository?.owner?.login || process.env.GITHUB_REPOSITORY?.split("/")?.[0];
|
|
735
|
-
name = anyInfo?.eventContext?.repository?.name || process.env.GITHUB_REPOSITORY?.split("/")?.[1];
|
|
736
|
-
prNum = typeof anyInfo?.number === "number" ? anyInfo.number : void 0;
|
|
737
|
-
headSha = anyInfo?.eventContext?.pull_request?.head?.sha || process.env.GITHUB_SHA;
|
|
738
|
-
} catch {
|
|
739
|
-
}
|
|
740
|
-
const repoObj = owner && name ? { owner, name } : void 0;
|
|
741
|
-
const octokit = this.executionContext?.octokit;
|
|
742
|
-
if (!headSha && repoObj && prNum && octokit && typeof octokit.rest?.pulls?.get === "function") {
|
|
743
|
-
try {
|
|
744
|
-
const { data } = await octokit.rest.pulls.get({
|
|
745
|
-
owner: repoObj.owner,
|
|
746
|
-
repo: repoObj.name,
|
|
747
|
-
pull_number: prNum
|
|
748
|
-
});
|
|
749
|
-
headSha = data && data.head && data.head.sha || headSha;
|
|
750
|
-
} catch {
|
|
751
|
-
}
|
|
752
|
-
}
|
|
753
|
-
try {
|
|
754
|
-
const prev = this.getExecutionContext() || {};
|
|
755
|
-
this.setExecutionContext({ ...prev, eventBus: bus });
|
|
756
|
-
try {
|
|
757
|
-
context.executionContext = this.getExecutionContext();
|
|
758
|
-
} catch {
|
|
759
|
-
}
|
|
760
|
-
} catch {
|
|
761
|
-
}
|
|
762
|
-
await frontendsHost.startAll(() => ({
|
|
763
|
-
eventBus: bus,
|
|
764
|
-
logger,
|
|
765
|
-
// Provide the active (possibly tag-filtered) config so frontends can read groups, etc.
|
|
766
|
-
config: configWithTagFilter,
|
|
767
|
-
run: {
|
|
768
|
-
runId: context.sessionId,
|
|
769
|
-
repo: repoObj,
|
|
770
|
-
pr: prNum,
|
|
771
|
-
headSha,
|
|
772
|
-
event: context.event || prInfo?.eventType,
|
|
773
|
-
actor: prInfo?.eventContext?.sender?.login || (typeof process.env.GITHUB_ACTOR === "string" ? process.env.GITHUB_ACTOR : void 0)
|
|
774
|
-
},
|
|
775
|
-
octokit,
|
|
776
|
-
webhookContext: this.executionContext?.webhookContext,
|
|
777
|
-
// Surface any injected test doubles for Slack as well
|
|
778
|
-
slack: this.executionContext?.slack || this.executionContext?.slackClient
|
|
779
|
-
}));
|
|
780
|
-
try {
|
|
781
|
-
bus.on("HumanInputRequested", async (envelope) => {
|
|
782
|
-
try {
|
|
783
|
-
const ev = envelope && envelope.payload || envelope;
|
|
784
|
-
let channel = ev?.channel;
|
|
785
|
-
let threadTs = ev?.threadTs;
|
|
786
|
-
if (!channel || !threadTs) {
|
|
787
|
-
try {
|
|
788
|
-
const anyCfg = configWithTagFilter || {};
|
|
789
|
-
const slackCfg = anyCfg.slack || {};
|
|
790
|
-
const endpoint = slackCfg.endpoint || "/bots/slack/support";
|
|
791
|
-
const map = this.executionContext?.webhookContext?.webhookData;
|
|
792
|
-
const payload = map?.get(endpoint);
|
|
793
|
-
const e = payload?.event;
|
|
794
|
-
const derivedTs = String(e?.thread_ts || e?.ts || e?.event_ts || "");
|
|
795
|
-
const derivedCh = String(e?.channel || "");
|
|
796
|
-
if (derivedCh && derivedTs) {
|
|
797
|
-
channel = channel || derivedCh;
|
|
798
|
-
threadTs = threadTs || derivedTs;
|
|
799
|
-
}
|
|
800
|
-
} catch {
|
|
801
|
-
}
|
|
802
|
-
}
|
|
803
|
-
const checkId = String(ev?.checkId || "unknown");
|
|
804
|
-
const threadKey = ev?.threadKey || (channel && threadTs ? `${channel}:${threadTs}` : "session");
|
|
805
|
-
const baseDir = process.env.VISOR_SNAPSHOT_DIR || path2.resolve(process.cwd(), ".visor", "snapshots");
|
|
806
|
-
fs.mkdirSync(baseDir, { recursive: true });
|
|
807
|
-
const filePath = path2.join(baseDir, `${threadKey}-${checkId}.json`);
|
|
808
|
-
await this.saveSnapshotToFile(filePath);
|
|
809
|
-
logger.info(`[Snapshot] Saved run snapshot: ${filePath}`);
|
|
810
|
-
try {
|
|
811
|
-
await bus.emit({
|
|
812
|
-
type: "SnapshotSaved",
|
|
813
|
-
checkId: ev?.checkId || "unknown",
|
|
814
|
-
channel,
|
|
815
|
-
threadTs,
|
|
816
|
-
threadKey,
|
|
817
|
-
filePath
|
|
818
|
-
});
|
|
819
|
-
} catch {
|
|
820
|
-
}
|
|
821
|
-
} catch (e) {
|
|
822
|
-
logger.warn(
|
|
823
|
-
`[Snapshot] Failed to save snapshot on HumanInputRequested: ${e instanceof Error ? e.message : String(e)}`
|
|
824
|
-
);
|
|
825
|
-
}
|
|
826
|
-
});
|
|
827
|
-
} catch {
|
|
828
|
-
}
|
|
829
|
-
} catch (err) {
|
|
830
|
-
logger.warn(
|
|
831
|
-
`[Frontends] Failed to initialize frontends: ${err instanceof Error ? err.message : String(err)}`
|
|
832
|
-
);
|
|
833
|
-
}
|
|
834
|
-
}
|
|
835
|
-
const runner = new StateMachineRunner(context, this.debugServer);
|
|
836
|
-
this._lastRunner = runner;
|
|
837
|
-
const result = await runner.run();
|
|
838
|
-
if (frontendsHost && typeof frontendsHost.stopAll === "function") {
|
|
839
|
-
try {
|
|
840
|
-
await frontendsHost.stopAll();
|
|
841
|
-
} catch {
|
|
842
|
-
}
|
|
843
|
-
}
|
|
844
|
-
if (debug) {
|
|
845
|
-
logger.info("[StateMachine] Execution complete");
|
|
846
|
-
}
|
|
847
|
-
try {
|
|
848
|
-
const { SessionRegistry } = await import("./session-registry-4E6YRQ77.mjs");
|
|
849
|
-
const sessionRegistry = SessionRegistry.getInstance();
|
|
850
|
-
sessionRegistry.clearAllSessions();
|
|
851
|
-
} catch (error) {
|
|
852
|
-
logger.debug(`[StateMachine] Failed to cleanup sessions: ${error}`);
|
|
853
|
-
}
|
|
854
|
-
if (context.workspace) {
|
|
855
|
-
try {
|
|
856
|
-
await context.workspace.cleanup();
|
|
857
|
-
} catch (error) {
|
|
858
|
-
logger.debug(`[StateMachine] Failed to cleanup workspace: ${error}`);
|
|
859
|
-
}
|
|
860
|
-
}
|
|
861
|
-
return result;
|
|
862
|
-
}
|
|
863
|
-
/**
|
|
864
|
-
* Build the engine context for state machine execution
|
|
865
|
-
*/
|
|
866
|
-
buildEngineContext(config, prInfo, debug, maxParallelism, failFast, requestedChecks) {
|
|
867
|
-
const { buildEngineContextForRun: buildEngineContextForRun2 } = (init_build_engine_context(), __toCommonJS(build_engine_context_exports));
|
|
868
|
-
return buildEngineContextForRun2(
|
|
869
|
-
this.workingDirectory,
|
|
870
|
-
config,
|
|
871
|
-
prInfo,
|
|
872
|
-
debug,
|
|
873
|
-
maxParallelism,
|
|
874
|
-
failFast,
|
|
875
|
-
requestedChecks
|
|
876
|
-
);
|
|
877
|
-
}
|
|
878
|
-
/**
|
|
879
|
-
* Get output history snapshot for test framework compatibility
|
|
880
|
-
* Extracts output history from the journal
|
|
881
|
-
*/
|
|
882
|
-
getOutputHistorySnapshot() {
|
|
883
|
-
const journal = this._lastContext?.journal;
|
|
884
|
-
if (!journal) {
|
|
885
|
-
logger.debug("[StateMachine][DEBUG] getOutputHistorySnapshot: No journal found");
|
|
886
|
-
return {};
|
|
887
|
-
}
|
|
888
|
-
const sessionId = this._lastContext?.sessionId;
|
|
889
|
-
if (!sessionId) {
|
|
890
|
-
logger.debug("[StateMachine][DEBUG] getOutputHistorySnapshot: No sessionId found");
|
|
891
|
-
return {};
|
|
892
|
-
}
|
|
893
|
-
const snapshot = journal.beginSnapshot();
|
|
894
|
-
const allEntries = journal.readVisible(sessionId, snapshot, void 0);
|
|
895
|
-
logger.debug(
|
|
896
|
-
`[StateMachine][DEBUG] getOutputHistorySnapshot: Found ${allEntries.length} journal entries`
|
|
897
|
-
);
|
|
898
|
-
const outputHistory = {};
|
|
899
|
-
for (const entry of allEntries) {
|
|
900
|
-
const checkId = entry.checkId;
|
|
901
|
-
if (!outputHistory[checkId]) {
|
|
902
|
-
outputHistory[checkId] = [];
|
|
903
|
-
}
|
|
904
|
-
try {
|
|
905
|
-
if (entry && typeof entry.result === "object" && entry.result.__skipped) {
|
|
906
|
-
continue;
|
|
907
|
-
}
|
|
908
|
-
} catch {
|
|
909
|
-
}
|
|
910
|
-
const payload = entry.result.output !== void 0 ? entry.result.output : entry.result;
|
|
911
|
-
try {
|
|
912
|
-
if (payload && typeof payload === "object" && payload.forEachItems && Array.isArray(payload.forEachItems)) {
|
|
913
|
-
continue;
|
|
914
|
-
}
|
|
915
|
-
} catch {
|
|
916
|
-
}
|
|
917
|
-
if (payload !== void 0) outputHistory[checkId].push(payload);
|
|
918
|
-
}
|
|
919
|
-
logger.debug(
|
|
920
|
-
`[StateMachine][DEBUG] getOutputHistorySnapshot result: ${JSON.stringify(Object.keys(outputHistory))}`
|
|
921
|
-
);
|
|
922
|
-
for (const [checkId, outputs] of Object.entries(outputHistory)) {
|
|
923
|
-
logger.debug(`[StateMachine][DEBUG] ${checkId}: ${outputs.length} outputs`);
|
|
924
|
-
}
|
|
925
|
-
return outputHistory;
|
|
926
|
-
}
|
|
927
|
-
/**
|
|
928
|
-
* Save a JSON snapshot of the last run's state and journal to a file (experimental).
|
|
929
|
-
* Does not include secrets. Intended for debugging and future resume support.
|
|
930
|
-
*/
|
|
931
|
-
async saveSnapshotToFile(filePath) {
|
|
932
|
-
const fs2 = await import("fs/promises");
|
|
933
|
-
const ctx = this._lastContext;
|
|
934
|
-
const runner = this._lastRunner;
|
|
935
|
-
if (!ctx || !runner) {
|
|
936
|
-
throw new Error("No prior execution context to snapshot");
|
|
937
|
-
}
|
|
938
|
-
const journal = ctx.journal;
|
|
939
|
-
const snapshotId = journal.beginSnapshot();
|
|
940
|
-
const entries = journal.readVisible(ctx.sessionId, snapshotId, void 0);
|
|
941
|
-
const state = runner.getState();
|
|
942
|
-
const serializableState = serializeRunState(state);
|
|
943
|
-
const payload = {
|
|
944
|
-
version: 1,
|
|
945
|
-
sessionId: ctx.sessionId,
|
|
946
|
-
event: ctx.event,
|
|
947
|
-
wave: state.wave,
|
|
948
|
-
state: serializableState,
|
|
949
|
-
journal: entries,
|
|
950
|
-
requestedChecks: ctx.requestedChecks || []
|
|
951
|
-
};
|
|
952
|
-
await fs2.writeFile(filePath, JSON.stringify(payload, null, 2), "utf8");
|
|
953
|
-
}
|
|
954
|
-
/**
|
|
955
|
-
* Load a snapshot JSON from file and return it. Resume support can build on this.
|
|
956
|
-
*/
|
|
957
|
-
async loadSnapshotFromFile(filePath) {
|
|
958
|
-
const fs2 = await import("fs/promises");
|
|
959
|
-
const raw = await fs2.readFile(filePath, "utf8");
|
|
960
|
-
return JSON.parse(raw);
|
|
961
|
-
}
|
|
962
|
-
/**
|
|
963
|
-
* Filter checks by tag filter
|
|
964
|
-
*/
|
|
965
|
-
filterChecksByTags(checks, config, tagFilter) {
|
|
966
|
-
return checks.filter((checkName) => {
|
|
967
|
-
const checkConfig = config?.checks?.[checkName];
|
|
968
|
-
if (!checkConfig) {
|
|
969
|
-
return true;
|
|
970
|
-
}
|
|
971
|
-
const checkTags = checkConfig.tags || [];
|
|
972
|
-
if (!tagFilter || !tagFilter.include && !tagFilter.exclude) {
|
|
973
|
-
return checkTags.length === 0;
|
|
974
|
-
}
|
|
975
|
-
if (checkTags.length === 0) {
|
|
976
|
-
return true;
|
|
977
|
-
}
|
|
978
|
-
if (tagFilter.exclude && tagFilter.exclude.length > 0) {
|
|
979
|
-
const hasExcludedTag = tagFilter.exclude.some((tag) => checkTags.includes(tag));
|
|
980
|
-
if (hasExcludedTag) return false;
|
|
981
|
-
}
|
|
982
|
-
if (tagFilter.include && tagFilter.include.length > 0) {
|
|
983
|
-
const hasIncludedTag = tagFilter.include.some((tag) => checkTags.includes(tag));
|
|
984
|
-
if (!hasIncludedTag) return false;
|
|
985
|
-
}
|
|
986
|
-
return true;
|
|
987
|
-
});
|
|
988
|
-
}
|
|
989
|
-
/**
|
|
990
|
-
* Create an error result in AnalysisResult format
|
|
991
|
-
*/
|
|
992
|
-
createErrorResult(repositoryInfo, errorMessage, startTime, timestamp, checksExecuted) {
|
|
993
|
-
const executionTime = Date.now() - startTime;
|
|
994
|
-
return {
|
|
995
|
-
repositoryInfo,
|
|
996
|
-
reviewSummary: {
|
|
997
|
-
issues: [
|
|
998
|
-
{
|
|
999
|
-
file: "system",
|
|
1000
|
-
line: 0,
|
|
1001
|
-
endLine: void 0,
|
|
1002
|
-
ruleId: "system/error",
|
|
1003
|
-
message: errorMessage,
|
|
1004
|
-
severity: "error",
|
|
1005
|
-
category: "logic",
|
|
1006
|
-
suggestion: void 0,
|
|
1007
|
-
replacement: void 0
|
|
1008
|
-
}
|
|
1009
|
-
]
|
|
1010
|
-
},
|
|
1011
|
-
executionTime,
|
|
1012
|
-
timestamp,
|
|
1013
|
-
checksExecuted
|
|
1014
|
-
};
|
|
1015
|
-
}
|
|
1016
|
-
/**
|
|
1017
|
-
* Convert GroupedCheckResults to ReviewSummary
|
|
1018
|
-
* Aggregates all check results into a single ReviewSummary
|
|
1019
|
-
*/
|
|
1020
|
-
convertGroupedResultsToReviewSummary(groupedResults, statistics) {
|
|
1021
|
-
const { convertToReviewSummary: convertToReviewSummary2 } = (init_summary(), __toCommonJS(summary_exports));
|
|
1022
|
-
return convertToReviewSummary2(groupedResults, statistics);
|
|
1023
|
-
}
|
|
1024
|
-
/**
|
|
1025
|
-
* Evaluate failure conditions for a check result
|
|
1026
|
-
*
|
|
1027
|
-
* This method provides backward compatibility with the legacy engine by
|
|
1028
|
-
* delegating to the FailureConditionEvaluator.
|
|
1029
|
-
*
|
|
1030
|
-
* @param checkName - The name of the check being evaluated
|
|
1031
|
-
* @param reviewSummary - The review summary containing check results
|
|
1032
|
-
* @param config - The Visor configuration containing failure conditions
|
|
1033
|
-
* @param previousOutputs - Optional previous check outputs for cross-check conditions
|
|
1034
|
-
* @param authorAssociation - Optional GitHub author association for permission checks
|
|
1035
|
-
* @returns Array of failure condition evaluation results
|
|
1036
|
-
*/
|
|
1037
|
-
async evaluateFailureConditions(checkName, reviewSummary, config, previousOutputs, authorAssociation) {
|
|
1038
|
-
const { FailureConditionEvaluator } = await import("./failure-condition-evaluator-G4HMJPXF.mjs");
|
|
1039
|
-
const evaluator = new FailureConditionEvaluator();
|
|
1040
|
-
const { addEvent } = await import("./trace-helpers-VP6QYVBX.mjs");
|
|
1041
|
-
const { addFailIfTriggered } = await import("./metrics-7PP3EJUH.mjs");
|
|
1042
|
-
const checkConfig = config.checks?.[checkName];
|
|
1043
|
-
if (!checkConfig) {
|
|
1044
|
-
return [];
|
|
1045
|
-
}
|
|
1046
|
-
const rawSchema = checkConfig.schema || "code-review";
|
|
1047
|
-
const checkSchema = typeof rawSchema === "string" ? rawSchema : "code-review";
|
|
1048
|
-
const checkGroup = checkConfig.group || "default";
|
|
1049
|
-
const results = [];
|
|
1050
|
-
if (config.fail_if) {
|
|
1051
|
-
const failed = await evaluator.evaluateSimpleCondition(
|
|
1052
|
-
checkName,
|
|
1053
|
-
checkSchema,
|
|
1054
|
-
checkGroup,
|
|
1055
|
-
reviewSummary,
|
|
1056
|
-
config.fail_if,
|
|
1057
|
-
previousOutputs || {}
|
|
1058
|
-
);
|
|
1059
|
-
try {
|
|
1060
|
-
addEvent("fail_if.evaluated", {
|
|
1061
|
-
"visor.check.id": checkName,
|
|
1062
|
-
scope: "global",
|
|
1063
|
-
expression: String(config.fail_if),
|
|
1064
|
-
result: failed ? "triggered" : "not_triggered"
|
|
1065
|
-
});
|
|
1066
|
-
if (failed) {
|
|
1067
|
-
addEvent("fail_if.triggered", {
|
|
1068
|
-
"visor.check.id": checkName,
|
|
1069
|
-
scope: "global",
|
|
1070
|
-
expression: String(config.fail_if)
|
|
1071
|
-
});
|
|
1072
|
-
addFailIfTriggered(checkName, "global");
|
|
1073
|
-
}
|
|
1074
|
-
} catch {
|
|
1075
|
-
}
|
|
1076
|
-
results.push({
|
|
1077
|
-
conditionName: "global_fail_if",
|
|
1078
|
-
failed,
|
|
1079
|
-
expression: config.fail_if,
|
|
1080
|
-
message: failed ? `Global failure condition met: ${config.fail_if}` : void 0,
|
|
1081
|
-
severity: "error",
|
|
1082
|
-
haltExecution: false
|
|
1083
|
-
});
|
|
1084
|
-
}
|
|
1085
|
-
if (checkConfig.fail_if) {
|
|
1086
|
-
const failed = await evaluator.evaluateSimpleCondition(
|
|
1087
|
-
checkName,
|
|
1088
|
-
checkSchema,
|
|
1089
|
-
checkGroup,
|
|
1090
|
-
reviewSummary,
|
|
1091
|
-
checkConfig.fail_if,
|
|
1092
|
-
previousOutputs || {}
|
|
1093
|
-
);
|
|
1094
|
-
try {
|
|
1095
|
-
addEvent("fail_if.evaluated", {
|
|
1096
|
-
"visor.check.id": checkName,
|
|
1097
|
-
scope: "check",
|
|
1098
|
-
expression: String(checkConfig.fail_if),
|
|
1099
|
-
result: failed ? "triggered" : "not_triggered"
|
|
1100
|
-
});
|
|
1101
|
-
if (failed) {
|
|
1102
|
-
addEvent("fail_if.triggered", {
|
|
1103
|
-
"visor.check.id": checkName,
|
|
1104
|
-
scope: "check",
|
|
1105
|
-
expression: String(checkConfig.fail_if)
|
|
1106
|
-
});
|
|
1107
|
-
addFailIfTriggered(checkName, "check");
|
|
1108
|
-
}
|
|
1109
|
-
} catch {
|
|
1110
|
-
}
|
|
1111
|
-
results.push({
|
|
1112
|
-
conditionName: `${checkName}_fail_if`,
|
|
1113
|
-
failed,
|
|
1114
|
-
expression: checkConfig.fail_if,
|
|
1115
|
-
message: failed ? `Check failure condition met: ${checkConfig.fail_if}` : void 0,
|
|
1116
|
-
severity: "error",
|
|
1117
|
-
haltExecution: false
|
|
1118
|
-
});
|
|
1119
|
-
}
|
|
1120
|
-
const globalConditions = config.failure_conditions;
|
|
1121
|
-
const checkConditions = checkConfig.failure_conditions;
|
|
1122
|
-
if (globalConditions || checkConditions) {
|
|
1123
|
-
const legacyResults = await evaluator.evaluateConditions(
|
|
1124
|
-
checkName,
|
|
1125
|
-
checkSchema,
|
|
1126
|
-
checkGroup,
|
|
1127
|
-
reviewSummary,
|
|
1128
|
-
globalConditions,
|
|
1129
|
-
checkConditions,
|
|
1130
|
-
previousOutputs,
|
|
1131
|
-
authorAssociation
|
|
1132
|
-
);
|
|
1133
|
-
results.push(...legacyResults);
|
|
1134
|
-
}
|
|
1135
|
-
return results;
|
|
1136
|
-
}
|
|
1137
|
-
/**
|
|
1138
|
-
* Get repository status
|
|
1139
|
-
* @returns Repository status information
|
|
1140
|
-
*/
|
|
1141
|
-
async getRepositoryStatus() {
|
|
1142
|
-
try {
|
|
1143
|
-
const { GitRepositoryAnalyzer } = await import("./git-repository-analyzer-HJC4MYW4.mjs");
|
|
1144
|
-
const analyzer = new GitRepositoryAnalyzer(this.workingDirectory);
|
|
1145
|
-
const info = await analyzer.analyzeRepository();
|
|
1146
|
-
return {
|
|
1147
|
-
isGitRepository: info.isGitRepository,
|
|
1148
|
-
branch: info.head,
|
|
1149
|
-
// Use head as branch name
|
|
1150
|
-
hasChanges: info.isGitRepository && (info.files?.length > 0 || false),
|
|
1151
|
-
filesChanged: info.isGitRepository ? info.files?.length || 0 : 0
|
|
1152
|
-
};
|
|
1153
|
-
} catch {
|
|
1154
|
-
return {
|
|
1155
|
-
isGitRepository: false,
|
|
1156
|
-
hasChanges: false
|
|
1157
|
-
};
|
|
1158
|
-
}
|
|
1159
|
-
}
|
|
1160
|
-
/**
|
|
1161
|
-
* Check if current directory is a git repository
|
|
1162
|
-
* @returns True if git repository, false otherwise
|
|
1163
|
-
*/
|
|
1164
|
-
async isGitRepository() {
|
|
1165
|
-
const status = await this.getRepositoryStatus();
|
|
1166
|
-
return status.isGitRepository;
|
|
1167
|
-
}
|
|
1168
|
-
/**
|
|
1169
|
-
* Get list of available check types
|
|
1170
|
-
* @returns Array of check type names
|
|
1171
|
-
*/
|
|
1172
|
-
static getAvailableCheckTypes() {
|
|
1173
|
-
const { CheckProviderRegistry } = (init_check_provider_registry(), __toCommonJS(check_provider_registry_exports));
|
|
1174
|
-
const registry = CheckProviderRegistry.getInstance();
|
|
1175
|
-
return registry.getAvailableProviders();
|
|
1176
|
-
}
|
|
1177
|
-
/**
|
|
1178
|
-
* Validate check types and return valid/invalid lists
|
|
1179
|
-
* @param checks - Array of check type names to validate
|
|
1180
|
-
* @returns Object with valid and invalid check types
|
|
1181
|
-
*/
|
|
1182
|
-
static validateCheckTypes(checks) {
|
|
1183
|
-
const availableTypes = _StateMachineExecutionEngine.getAvailableCheckTypes();
|
|
1184
|
-
const valid = [];
|
|
1185
|
-
const invalid = [];
|
|
1186
|
-
for (const check of checks) {
|
|
1187
|
-
if (availableTypes.includes(check)) {
|
|
1188
|
-
valid.push(check);
|
|
1189
|
-
} else {
|
|
1190
|
-
invalid.push(check);
|
|
1191
|
-
}
|
|
1192
|
-
}
|
|
1193
|
-
return { valid, invalid };
|
|
1194
|
-
}
|
|
1195
|
-
/**
|
|
1196
|
-
* Format the status column for execution statistics
|
|
1197
|
-
* Used by execution-statistics-formatting tests
|
|
1198
|
-
*/
|
|
1199
|
-
formatStatusColumn(stats) {
|
|
1200
|
-
if (stats.skipped) {
|
|
1201
|
-
if (stats.skipReason === "if_condition") {
|
|
1202
|
-
return "\u23ED if";
|
|
1203
|
-
} else if (stats.skipReason === "fail_fast") {
|
|
1204
|
-
return "\u23ED ff";
|
|
1205
|
-
} else if (stats.skipReason === "dependency_failed") {
|
|
1206
|
-
return "\u23ED dep";
|
|
1207
|
-
}
|
|
1208
|
-
return "\u23ED";
|
|
1209
|
-
}
|
|
1210
|
-
const totalRuns = stats.totalRuns;
|
|
1211
|
-
const successfulRuns = stats.successfulRuns;
|
|
1212
|
-
const failedRuns = stats.failedRuns;
|
|
1213
|
-
if (failedRuns > 0 && successfulRuns > 0) {
|
|
1214
|
-
return `\u2714/\u2716 ${successfulRuns}/${totalRuns}`;
|
|
1215
|
-
} else if (failedRuns > 0) {
|
|
1216
|
-
return totalRuns === 1 ? "\u2716" : `\u2716 \xD7${totalRuns}`;
|
|
1217
|
-
} else {
|
|
1218
|
-
return totalRuns === 1 ? "\u2714" : `\u2714 \xD7${totalRuns}`;
|
|
1219
|
-
}
|
|
1220
|
-
}
|
|
1221
|
-
/**
|
|
1222
|
-
* Format the details column for execution statistics
|
|
1223
|
-
* Used by execution-statistics-formatting tests
|
|
1224
|
-
*/
|
|
1225
|
-
formatDetailsColumn(stats) {
|
|
1226
|
-
const parts = [];
|
|
1227
|
-
if (stats.outputsProduced !== void 0 && stats.outputsProduced > 0) {
|
|
1228
|
-
parts.push(`\u2192${stats.outputsProduced}`);
|
|
1229
|
-
}
|
|
1230
|
-
if (stats.issuesBySeverity.critical > 0) {
|
|
1231
|
-
parts.push(`${stats.issuesBySeverity.critical}\u{1F534}`);
|
|
1232
|
-
}
|
|
1233
|
-
if (stats.issuesBySeverity.error > 0 && stats.issuesBySeverity.critical === 0) {
|
|
1234
|
-
parts.push(`${stats.issuesBySeverity.error}\u274C`);
|
|
1235
|
-
}
|
|
1236
|
-
if (stats.issuesBySeverity.warning > 0) {
|
|
1237
|
-
parts.push(`${stats.issuesBySeverity.warning}\u26A0\uFE0F`);
|
|
1238
|
-
}
|
|
1239
|
-
if (stats.issuesBySeverity.info > 0 && stats.issuesBySeverity.critical === 0 && stats.issuesBySeverity.error === 0 && stats.issuesBySeverity.warning === 0) {
|
|
1240
|
-
parts.push(`${stats.issuesBySeverity.info}\u{1F4A1}`);
|
|
1241
|
-
}
|
|
1242
|
-
if (stats.errorMessage) {
|
|
1243
|
-
parts.push(this.truncate(stats.errorMessage, 40));
|
|
1244
|
-
}
|
|
1245
|
-
if (stats.skipCondition) {
|
|
1246
|
-
parts.push(this.truncate(stats.skipCondition, 40));
|
|
1247
|
-
}
|
|
1248
|
-
return parts.join(" ");
|
|
1249
|
-
}
|
|
1250
|
-
/**
|
|
1251
|
-
* Truncate a string to a maximum length
|
|
1252
|
-
* Used by formatDetailsColumn
|
|
1253
|
-
*/
|
|
1254
|
-
truncate(str, maxLength) {
|
|
1255
|
-
if (str.length <= maxLength) {
|
|
1256
|
-
return str;
|
|
1257
|
-
}
|
|
1258
|
-
return str.substring(0, maxLength - 3) + "...";
|
|
1259
|
-
}
|
|
1260
|
-
};
|
|
1261
|
-
function serializeRunState(state) {
|
|
1262
|
-
return {
|
|
1263
|
-
...state,
|
|
1264
|
-
levelQueue: state.levelQueue,
|
|
1265
|
-
eventQueue: state.eventQueue,
|
|
1266
|
-
activeDispatches: Array.from(state.activeDispatches.entries()),
|
|
1267
|
-
completedChecks: Array.from(state.completedChecks.values()),
|
|
1268
|
-
stats: Array.from(state.stats.entries()),
|
|
1269
|
-
historyLog: state.historyLog,
|
|
1270
|
-
forwardRunGuards: Array.from(state.forwardRunGuards.values()),
|
|
1271
|
-
currentLevelChecks: Array.from(state.currentLevelChecks.values()),
|
|
1272
|
-
currentWaveCompletions: Array.from(
|
|
1273
|
-
state.currentWaveCompletions || []
|
|
1274
|
-
),
|
|
1275
|
-
// failedChecks is an internal Set added by stats/dispatch layers; keep it if present
|
|
1276
|
-
failedChecks: Array.from(state.failedChecks || []),
|
|
1277
|
-
pendingRunScopes: Array.from((state.pendingRunScopes || /* @__PURE__ */ new Map()).entries()).map(([k, v]) => [
|
|
1278
|
-
k,
|
|
1279
|
-
v
|
|
1280
|
-
])
|
|
1281
|
-
};
|
|
1282
|
-
}
|
|
12
|
+
} from "./chunk-7YSOINAQ.mjs";
|
|
13
|
+
import "./chunk-NCWIZVOT.mjs";
|
|
14
|
+
import "./chunk-6W75IMDC.mjs";
|
|
15
|
+
import "./chunk-SGS2VMEL.mjs";
|
|
16
|
+
import "./chunk-N7HO6KKC.mjs";
|
|
17
|
+
import "./chunk-J5RGJQ53.mjs";
|
|
18
|
+
import "./chunk-XR7XXGL7.mjs";
|
|
19
|
+
import "./chunk-R5Z7YWPB.mjs";
|
|
20
|
+
import "./chunk-25IC7KXZ.mjs";
|
|
21
|
+
import "./chunk-VF6XIUE4.mjs";
|
|
22
|
+
import "./chunk-2KB35MB7.mjs";
|
|
23
|
+
import "./chunk-PO7X5XI7.mjs";
|
|
24
|
+
import "./chunk-HEX3RL32.mjs";
|
|
25
|
+
import "./chunk-B7BVQM5K.mjs";
|
|
26
|
+
import "./chunk-J7LXIPZS.mjs";
|
|
1283
27
|
|
|
1284
28
|
// src/sdk.ts
|
|
29
|
+
init_state_machine_execution_engine();
|
|
1285
30
|
init_config();
|
|
1286
31
|
async function loadConfig(configOrPath, options) {
|
|
1287
32
|
const cm = new ConfigManager();
|