@probelabs/visor 0.1.183-ee → 0.1.184-ee
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent-protocol/task-live-update-slack.d.ts +24 -0
- package/dist/agent-protocol/task-live-update-slack.d.ts.map +1 -0
- package/dist/agent-protocol/task-live-update-teams.d.ts +25 -0
- package/dist/agent-protocol/task-live-update-teams.d.ts.map +1 -0
- package/dist/agent-protocol/task-live-update-telegram.d.ts +25 -0
- package/dist/agent-protocol/task-live-update-telegram.d.ts.map +1 -0
- package/dist/agent-protocol/task-live-updates.d.ts +102 -0
- package/dist/agent-protocol/task-live-updates.d.ts.map +1 -0
- package/dist/agent-protocol/task-progress-tool.d.ts.map +1 -1
- package/dist/agent-protocol/task-trace-resolution.d.ts +11 -0
- package/dist/agent-protocol/task-trace-resolution.d.ts.map +1 -0
- package/dist/agent-protocol/trace-serializer.d.ts.map +1 -1
- package/dist/agent-protocol/track-execution.d.ts +8 -0
- package/dist/agent-protocol/track-execution.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.d.ts.map +1 -1
- package/dist/frontends/slack-frontend.d.ts +2 -0
- package/dist/frontends/slack-frontend.d.ts.map +1 -1
- package/dist/frontends/teams-frontend.d.ts.map +1 -1
- package/dist/frontends/telegram-frontend.d.ts.map +1 -1
- package/dist/generated/config-schema.d.ts +110 -6
- package/dist/generated/config-schema.d.ts.map +1 -1
- package/dist/index.js +2239 -261
- package/dist/logger.d.ts +4 -1
- package/dist/logger.d.ts.map +1 -1
- package/dist/mcp-job-manager.d.ts +70 -0
- package/dist/mcp-job-manager.d.ts.map +1 -0
- package/dist/mcp-server.d.ts +6 -0
- package/dist/mcp-server.d.ts.map +1 -1
- package/dist/runners/mcp-server-runner.d.ts +4 -0
- package/dist/runners/mcp-server-runner.d.ts.map +1 -1
- package/dist/runners/runner-factory.d.ts.map +1 -1
- package/dist/sdk/{a2a-frontend-5YDHFQXD.mjs → a2a-frontend-OI4OVSKC.mjs} +4 -4
- package/dist/sdk/check-provider-registry-RITJW67U.mjs +32 -0
- package/dist/sdk/check-provider-registry-ZZ6N4GDP.mjs +32 -0
- package/dist/sdk/{chunk-4BN2XI4X.mjs → chunk-4HIWZA6M.mjs} +2 -2
- package/dist/sdk/{chunk-RI4ONH5X.mjs → chunk-4MHHELVZ.mjs} +2 -2
- package/dist/sdk/{chunk-J27D43HS.mjs → chunk-4ZLYHSN4.mjs} +2 -2
- package/dist/sdk/{chunk-ZPYODGYA.mjs → chunk-6E625R3C.mjs} +19 -4
- package/dist/sdk/chunk-6E625R3C.mjs.map +1 -0
- package/dist/sdk/{chunk-GA2TYKSR.mjs → chunk-7XKHFRPN.mjs} +4 -4
- package/dist/sdk/{chunk-6C3R6E42.mjs → chunk-IY5PQ5EN.mjs} +30 -6
- package/dist/sdk/chunk-IY5PQ5EN.mjs.map +1 -0
- package/dist/sdk/{chunk-MFXPJUUE.mjs → chunk-PUHU6UY6.mjs} +4 -3
- package/dist/sdk/chunk-PUHU6UY6.mjs.map +1 -0
- package/dist/sdk/{chunk-XOAEKFKB.mjs → chunk-QLT42TX7.mjs} +2 -2
- package/dist/sdk/chunk-SRU5TFNY.mjs +620 -0
- package/dist/sdk/chunk-SRU5TFNY.mjs.map +1 -0
- package/dist/sdk/{chunk-P2K4VOMU.mjs → chunk-TSX3YS3F.mjs} +3 -3
- package/dist/sdk/{chunk-WKLJ57WF.mjs → chunk-UM7LGO2P.mjs} +6 -6
- package/dist/sdk/{chunk-7VTZDC2X.mjs → chunk-VPPBOKBQ.mjs} +2 -2
- package/dist/sdk/chunk-WZQMTD7W.mjs +33 -0
- package/dist/sdk/chunk-WZQMTD7W.mjs.map +1 -0
- package/dist/sdk/{chunk-ZOF5QT6U.mjs → chunk-YBXNG75V.mjs} +118 -10
- package/dist/sdk/chunk-YBXNG75V.mjs.map +1 -0
- package/dist/sdk/{chunk-UXB4XWEE.mjs → chunk-YYFSAAD6.mjs} +53 -51
- package/dist/sdk/chunk-YYFSAAD6.mjs.map +1 -0
- package/dist/sdk/{chunk-RHKPFJLG.mjs → chunk-ZNKL6ESZ.mjs} +2 -2
- package/dist/sdk/{chunk-IDL3AA3G.mjs → chunk-ZYDRR6PZ.mjs} +1150 -403
- package/dist/sdk/chunk-ZYDRR6PZ.mjs.map +1 -0
- package/dist/sdk/{command-executor-YNJOS77A.mjs → command-executor-LHUW77GR.mjs} +3 -3
- package/dist/sdk/{config-PCP6O6Y6.mjs → config-TVU5RWR5.mjs} +3 -3
- package/dist/sdk/{dist-3UGGEZB3.mjs → dist-PN5UHL6A.mjs} +429 -429
- package/dist/sdk/dist-PN5UHL6A.mjs.map +1 -0
- package/dist/sdk/{email-frontend-WSNADJPI.mjs → email-frontend-ECHQCFTR.mjs} +2 -2
- package/dist/sdk/{failure-condition-evaluator-IRFKTYZD.mjs → failure-condition-evaluator-USY3ISVA.mjs} +6 -6
- package/dist/sdk/{github-auth-BJQBLK2V.mjs → github-auth-UO4DMNCC.mjs} +2 -2
- package/dist/sdk/{github-frontend-DECYOBRN.mjs → github-frontend-2T5PWYD5.mjs} +6 -6
- package/dist/sdk/{host-CFM2ASDI.mjs → host-OJSMCLKK.mjs} +6 -6
- package/dist/sdk/{host-T4LNVU2H.mjs → host-RM6UJEPP.mjs} +7 -7
- package/dist/sdk/{knex-store-OEWSZEBY.mjs → knex-store-KCMFAMH5.mjs} +2 -2
- package/dist/sdk/{liquid-extensions-E3AKRX7P.mjs → liquid-extensions-KZIRR4OY.mjs} +4 -4
- package/dist/sdk/{loader-WRGI244P.mjs → loader-35YWX5UQ.mjs} +4 -4
- package/dist/sdk/{memory-store-OHUIXCWJ.mjs → memory-store-3JONK7AF.mjs} +3 -3
- package/dist/sdk/{opa-policy-engine-IVMCGVNA.mjs → opa-policy-engine-FY5D45YS.mjs} +2 -2
- package/dist/sdk/{prompt-state-LN57DQF3.mjs → prompt-state-VVJMONT3.mjs} +3 -3
- package/dist/sdk/{renderer-schema-BT2IXMLW.mjs → renderer-schema-JZRRU5CW.mjs} +2 -2
- package/dist/sdk/{routing-H2PQ57OA.mjs → routing-NNQQSLWA.mjs} +8 -8
- package/dist/sdk/{schedule-tool-2DPNSU63.mjs → schedule-tool-ADZ2ON4I.mjs} +15 -14
- package/dist/sdk/schedule-tool-EMNF3FPQ.mjs +38 -0
- package/dist/sdk/{schedule-tool-handler-NBEO46RV.mjs → schedule-tool-handler-3R3IC6VA.mjs} +15 -14
- package/dist/sdk/{schedule-tool-handler-KLHE2SOW.mjs → schedule-tool-handler-F76ZD2WU.mjs} +17 -16
- package/dist/sdk/sdk.d.mts +40 -0
- package/dist/sdk/sdk.d.ts +40 -0
- package/dist/sdk/sdk.js +1154 -176
- package/dist/sdk/sdk.js.map +1 -1
- package/dist/sdk/sdk.mjs +14 -13
- package/dist/sdk/sdk.mjs.map +1 -1
- package/dist/sdk/{slack-frontend-DF5VL4OF.mjs → slack-frontend-K3TPGERM.mjs} +65 -9
- package/dist/sdk/slack-frontend-K3TPGERM.mjs.map +1 -0
- package/dist/sdk/{task-evaluator-OVMG7S56.mjs → task-evaluator-H3BXC7SE.mjs} +3 -3
- package/dist/sdk/{teams-frontend-DNW5GZP3.mjs → teams-frontend-6RRW533K.mjs} +54 -1
- package/dist/sdk/teams-frontend-6RRW533K.mjs.map +1 -0
- package/dist/sdk/{telegram-frontend-GA7OLADB.mjs → telegram-frontend-5UA77YAT.mjs} +48 -1
- package/dist/sdk/telegram-frontend-5UA77YAT.mjs.map +1 -0
- package/dist/sdk/{trace-helpers-26ZCAE2V.mjs → trace-helpers-OMF4C24T.mjs} +3 -3
- package/dist/sdk/{trace-serializer-KKBJHM7J.mjs → trace-serializer-EBHTHZYT.mjs} +3 -3
- package/dist/sdk/track-execution-3CHMGEPH.mjs +249 -0
- package/dist/sdk/track-execution-3CHMGEPH.mjs.map +1 -0
- package/dist/sdk/{utcp-check-provider-WI3QZ3W6.mjs → utcp-check-provider-Q4PD5EP2.mjs} +5 -5
- package/dist/sdk/workflow-check-provider-TC2G33WF.mjs +32 -0
- package/dist/sdk/workflow-check-provider-U4UXZ5YS.mjs +32 -0
- package/dist/sdk/{workflow-registry-YCZ3FCJC.mjs → workflow-registry-K56UTX36.mjs} +3 -3
- package/dist/slack/client.d.ts +14 -0
- package/dist/slack/client.d.ts.map +1 -1
- package/dist/slack/socket-runner.d.ts.map +1 -1
- package/dist/teams/client.d.ts +16 -0
- package/dist/teams/client.d.ts.map +1 -1
- package/dist/teams/webhook-runner.d.ts.map +1 -1
- package/dist/telegram/client.d.ts +17 -0
- package/dist/telegram/client.d.ts.map +1 -1
- package/dist/telegram/polling-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 +40 -0
- package/dist/types/config.d.ts.map +1 -1
- package/package.json +4 -3
- package/dist/generated/config-schema.json +0 -4027
- package/dist/sdk/a2a-frontend-6LWBIPMS.mjs +0 -1734
- package/dist/sdk/a2a-frontend-6LWBIPMS.mjs.map +0 -1
- package/dist/sdk/check-provider-registry-WSEVHJEV.mjs +0 -31
- package/dist/sdk/check-provider-registry-YRADEEQY.mjs +0 -31
- package/dist/sdk/chunk-34QX63WK.mjs +0 -244
- package/dist/sdk/chunk-34QX63WK.mjs.map +0 -1
- package/dist/sdk/chunk-54KOAC4W.mjs +0 -665
- package/dist/sdk/chunk-6C3R6E42.mjs.map +0 -1
- package/dist/sdk/chunk-7W5QCO4Y.mjs +0 -5943
- package/dist/sdk/chunk-7W5QCO4Y.mjs.map +0 -1
- package/dist/sdk/chunk-7XRSCOKE.mjs +0 -825
- package/dist/sdk/chunk-FT3I25QV.mjs +0 -251
- package/dist/sdk/chunk-FT3I25QV.mjs.map +0 -1
- package/dist/sdk/chunk-G7GSN3SK.mjs +0 -390
- package/dist/sdk/chunk-G7GSN3SK.mjs.map +0 -1
- package/dist/sdk/chunk-IDL3AA3G.mjs.map +0 -1
- package/dist/sdk/chunk-J27D43HS.mjs.map +0 -1
- package/dist/sdk/chunk-MEB2TTIE.mjs +0 -157
- package/dist/sdk/chunk-MEB2TTIE.mjs.map +0 -1
- package/dist/sdk/chunk-MFXPJUUE.mjs.map +0 -1
- package/dist/sdk/chunk-NPSLGKXB.mjs +0 -1502
- package/dist/sdk/chunk-P2K4VOMU.mjs.map +0 -1
- package/dist/sdk/chunk-PQWZ6NFL.mjs +0 -459
- package/dist/sdk/chunk-PQWZ6NFL.mjs.map +0 -1
- package/dist/sdk/chunk-S5FSRHMY.mjs +0 -139
- package/dist/sdk/chunk-S5FSRHMY.mjs.map +0 -1
- package/dist/sdk/chunk-TFUQ2D5L.mjs +0 -307
- package/dist/sdk/chunk-TFUQ2D5L.mjs.map +0 -1
- package/dist/sdk/chunk-UCMJJ3IM.mjs +0 -227
- package/dist/sdk/chunk-UCMJJ3IM.mjs.map +0 -1
- package/dist/sdk/chunk-UFHOIB3R.mjs +0 -482
- package/dist/sdk/chunk-UFHOIB3R.mjs.map +0 -1
- package/dist/sdk/chunk-UXB4XWEE.mjs.map +0 -1
- package/dist/sdk/chunk-V45TITKX.mjs +0 -739
- package/dist/sdk/chunk-V45TITKX.mjs.map +0 -1
- package/dist/sdk/chunk-WKLJ57WF.mjs.map +0 -1
- package/dist/sdk/chunk-ZOF5QT6U.mjs.map +0 -1
- package/dist/sdk/chunk-ZPYODGYA.mjs.map +0 -1
- package/dist/sdk/command-executor-3AHGIYQG.mjs +0 -14
- package/dist/sdk/config-JE4HKTWW.mjs +0 -16
- package/dist/sdk/dist-3UGGEZB3.mjs.map +0 -1
- package/dist/sdk/failure-condition-evaluator-H3PBFBYT.mjs +0 -18
- package/dist/sdk/github-auth-27SZGPEC.mjs +0 -196
- package/dist/sdk/github-auth-BJQBLK2V.mjs.map +0 -1
- package/dist/sdk/github-frontend-TZRBOQCN.mjs +0 -1394
- package/dist/sdk/github-frontend-TZRBOQCN.mjs.map +0 -1
- package/dist/sdk/lazy-otel-5NH4ZJJM.mjs +0 -24
- package/dist/sdk/liquid-extensions-P6KDYILF.mjs +0 -25
- package/dist/sdk/memory-store-K5N7MC7U.mjs +0 -12
- package/dist/sdk/metrics-JTOG2HNO.mjs +0 -41
- package/dist/sdk/prompt-state-YPICX7PI.mjs +0 -16
- package/dist/sdk/renderer-schema-KOIH75RZ.mjs +0 -51
- package/dist/sdk/renderer-schema-KOIH75RZ.mjs.map +0 -1
- package/dist/sdk/routing-JMZ7HDCC.mjs +0 -26
- package/dist/sdk/schedule-tool-4M45RK3E.mjs +0 -37
- package/dist/sdk/schedule-tool-4M45RK3E.mjs.map +0 -1
- package/dist/sdk/schedule-tool-handler-KLHE2SOW.mjs.map +0 -1
- package/dist/sdk/schedule-tool-handler-NBEO46RV.mjs.map +0 -1
- package/dist/sdk/slack-frontend-BPWXNIHE.mjs +0 -929
- package/dist/sdk/slack-frontend-BPWXNIHE.mjs.map +0 -1
- package/dist/sdk/slack-frontend-DF5VL4OF.mjs.map +0 -1
- package/dist/sdk/task-evaluator-GQYDOSGT.mjs +0 -1392
- package/dist/sdk/task-evaluator-GQYDOSGT.mjs.map +0 -1
- package/dist/sdk/teams-frontend-DNW5GZP3.mjs.map +0 -1
- package/dist/sdk/telegram-frontend-GA7OLADB.mjs.map +0 -1
- package/dist/sdk/trace-helpers-26ZCAE2V.mjs.map +0 -1
- package/dist/sdk/trace-helpers-XV5GAX5L.mjs +0 -29
- package/dist/sdk/trace-helpers-XV5GAX5L.mjs.map +0 -1
- package/dist/sdk/trace-serializer-KKBJHM7J.mjs.map +0 -1
- package/dist/sdk/track-execution-3EC24C2X.mjs +0 -163
- package/dist/sdk/track-execution-3EC24C2X.mjs.map +0 -1
- package/dist/sdk/track-execution-66RLL6QT.mjs +0 -143
- package/dist/sdk/track-execution-66RLL6QT.mjs.map +0 -1
- package/dist/sdk/utcp-check-provider-JLIYF5HH.mjs +0 -16
- package/dist/sdk/utcp-check-provider-JLIYF5HH.mjs.map +0 -1
- package/dist/sdk/utcp-check-provider-WI3QZ3W6.mjs.map +0 -1
- package/dist/sdk/workflow-check-provider-X2UREEH7.mjs +0 -31
- package/dist/sdk/workflow-check-provider-X2UREEH7.mjs.map +0 -1
- package/dist/sdk/workflow-check-provider-YXALZNAQ.mjs +0 -31
- package/dist/sdk/workflow-check-provider-YXALZNAQ.mjs.map +0 -1
- package/dist/sdk/workflow-registry-X2IPY35M.mjs +0 -12
- package/dist/sdk/workflow-registry-X2IPY35M.mjs.map +0 -1
- package/dist/sdk/workflow-registry-YCZ3FCJC.mjs.map +0 -1
- /package/dist/sdk/{a2a-frontend-5YDHFQXD.mjs.map → a2a-frontend-OI4OVSKC.mjs.map} +0 -0
- /package/dist/sdk/{check-provider-registry-WSEVHJEV.mjs.map → check-provider-registry-RITJW67U.mjs.map} +0 -0
- /package/dist/sdk/{check-provider-registry-YRADEEQY.mjs.map → check-provider-registry-ZZ6N4GDP.mjs.map} +0 -0
- /package/dist/sdk/{chunk-4BN2XI4X.mjs.map → chunk-4HIWZA6M.mjs.map} +0 -0
- /package/dist/sdk/{chunk-RI4ONH5X.mjs.map → chunk-4MHHELVZ.mjs.map} +0 -0
- /package/dist/sdk/{chunk-54KOAC4W.mjs.map → chunk-4ZLYHSN4.mjs.map} +0 -0
- /package/dist/sdk/{chunk-GA2TYKSR.mjs.map → chunk-7XKHFRPN.mjs.map} +0 -0
- /package/dist/sdk/{chunk-XOAEKFKB.mjs.map → chunk-QLT42TX7.mjs.map} +0 -0
- /package/dist/sdk/{chunk-7XRSCOKE.mjs.map → chunk-TSX3YS3F.mjs.map} +0 -0
- /package/dist/sdk/{chunk-NPSLGKXB.mjs.map → chunk-UM7LGO2P.mjs.map} +0 -0
- /package/dist/sdk/{chunk-7VTZDC2X.mjs.map → chunk-VPPBOKBQ.mjs.map} +0 -0
- /package/dist/sdk/{chunk-RHKPFJLG.mjs.map → chunk-ZNKL6ESZ.mjs.map} +0 -0
- /package/dist/sdk/{command-executor-3AHGIYQG.mjs.map → command-executor-LHUW77GR.mjs.map} +0 -0
- /package/dist/sdk/{command-executor-YNJOS77A.mjs.map → config-TVU5RWR5.mjs.map} +0 -0
- /package/dist/sdk/{email-frontend-WSNADJPI.mjs.map → email-frontend-ECHQCFTR.mjs.map} +0 -0
- /package/dist/sdk/{config-JE4HKTWW.mjs.map → failure-condition-evaluator-USY3ISVA.mjs.map} +0 -0
- /package/dist/sdk/{github-auth-27SZGPEC.mjs.map → github-auth-UO4DMNCC.mjs.map} +0 -0
- /package/dist/sdk/{github-frontend-DECYOBRN.mjs.map → github-frontend-2T5PWYD5.mjs.map} +0 -0
- /package/dist/sdk/{host-CFM2ASDI.mjs.map → host-OJSMCLKK.mjs.map} +0 -0
- /package/dist/sdk/{host-T4LNVU2H.mjs.map → host-RM6UJEPP.mjs.map} +0 -0
- /package/dist/sdk/{knex-store-OEWSZEBY.mjs.map → knex-store-KCMFAMH5.mjs.map} +0 -0
- /package/dist/sdk/{config-PCP6O6Y6.mjs.map → liquid-extensions-KZIRR4OY.mjs.map} +0 -0
- /package/dist/sdk/{loader-WRGI244P.mjs.map → loader-35YWX5UQ.mjs.map} +0 -0
- /package/dist/sdk/{failure-condition-evaluator-H3PBFBYT.mjs.map → memory-store-3JONK7AF.mjs.map} +0 -0
- /package/dist/sdk/{opa-policy-engine-IVMCGVNA.mjs.map → opa-policy-engine-FY5D45YS.mjs.map} +0 -0
- /package/dist/sdk/{failure-condition-evaluator-IRFKTYZD.mjs.map → prompt-state-VVJMONT3.mjs.map} +0 -0
- /package/dist/sdk/{renderer-schema-BT2IXMLW.mjs.map → renderer-schema-JZRRU5CW.mjs.map} +0 -0
- /package/dist/sdk/{lazy-otel-5NH4ZJJM.mjs.map → routing-NNQQSLWA.mjs.map} +0 -0
- /package/dist/sdk/{liquid-extensions-E3AKRX7P.mjs.map → schedule-tool-ADZ2ON4I.mjs.map} +0 -0
- /package/dist/sdk/{liquid-extensions-P6KDYILF.mjs.map → schedule-tool-EMNF3FPQ.mjs.map} +0 -0
- /package/dist/sdk/{memory-store-K5N7MC7U.mjs.map → schedule-tool-handler-3R3IC6VA.mjs.map} +0 -0
- /package/dist/sdk/{memory-store-OHUIXCWJ.mjs.map → schedule-tool-handler-F76ZD2WU.mjs.map} +0 -0
- /package/dist/sdk/{task-evaluator-OVMG7S56.mjs.map → task-evaluator-H3BXC7SE.mjs.map} +0 -0
- /package/dist/sdk/{metrics-JTOG2HNO.mjs.map → trace-helpers-OMF4C24T.mjs.map} +0 -0
- /package/dist/sdk/{prompt-state-LN57DQF3.mjs.map → trace-serializer-EBHTHZYT.mjs.map} +0 -0
- /package/dist/sdk/{prompt-state-YPICX7PI.mjs.map → utcp-check-provider-Q4PD5EP2.mjs.map} +0 -0
- /package/dist/sdk/{routing-H2PQ57OA.mjs.map → workflow-check-provider-TC2G33WF.mjs.map} +0 -0
- /package/dist/sdk/{routing-JMZ7HDCC.mjs.map → workflow-check-provider-U4UXZ5YS.mjs.map} +0 -0
- /package/dist/sdk/{schedule-tool-2DPNSU63.mjs.map → workflow-registry-K56UTX36.mjs.map} +0 -0
|
@@ -1,665 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
init_logger,
|
|
3
|
-
logger
|
|
4
|
-
} from "./chunk-ZPYODGYA.mjs";
|
|
5
|
-
import {
|
|
6
|
-
__esm
|
|
7
|
-
} from "./chunk-J7LXIPZS.mjs";
|
|
8
|
-
|
|
9
|
-
// src/dependency-resolver.ts
|
|
10
|
-
var DependencyResolver;
|
|
11
|
-
var init_dependency_resolver = __esm({
|
|
12
|
-
"src/dependency-resolver.ts"() {
|
|
13
|
-
"use strict";
|
|
14
|
-
DependencyResolver = class {
|
|
15
|
-
/**
|
|
16
|
-
* Build dependency graph from check dependencies
|
|
17
|
-
*/
|
|
18
|
-
static buildDependencyGraph(checkDependencies) {
|
|
19
|
-
const nodes = /* @__PURE__ */ new Map();
|
|
20
|
-
for (const checkId of Object.keys(checkDependencies)) {
|
|
21
|
-
nodes.set(checkId, {
|
|
22
|
-
id: checkId,
|
|
23
|
-
dependencies: checkDependencies[checkId] || [],
|
|
24
|
-
dependents: [],
|
|
25
|
-
depth: 0
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
for (const [checkId, dependencies] of Object.entries(checkDependencies)) {
|
|
29
|
-
for (const depId of dependencies || []) {
|
|
30
|
-
if (!nodes.has(depId)) {
|
|
31
|
-
throw new Error(`Check "${checkId}" depends on "${depId}" but "${depId}" is not defined`);
|
|
32
|
-
}
|
|
33
|
-
const depNode = nodes.get(depId);
|
|
34
|
-
depNode.dependents.push(checkId);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
const cycleDetection = this.detectCycles(nodes);
|
|
38
|
-
if (cycleDetection.hasCycles) {
|
|
39
|
-
return {
|
|
40
|
-
nodes,
|
|
41
|
-
executionOrder: [],
|
|
42
|
-
hasCycles: true,
|
|
43
|
-
cycleNodes: cycleDetection.cycleNodes
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
const executionOrder = this.topologicalSort(nodes);
|
|
47
|
-
return {
|
|
48
|
-
nodes,
|
|
49
|
-
executionOrder,
|
|
50
|
-
hasCycles: false
|
|
51
|
-
};
|
|
52
|
-
}
|
|
53
|
-
/**
|
|
54
|
-
* Detect cycles in the dependency graph using DFS
|
|
55
|
-
*/
|
|
56
|
-
static detectCycles(nodes) {
|
|
57
|
-
const visited = /* @__PURE__ */ new Set();
|
|
58
|
-
const recursionStack = /* @__PURE__ */ new Set();
|
|
59
|
-
const cycleNodes = [];
|
|
60
|
-
const dfs = (nodeId) => {
|
|
61
|
-
if (recursionStack.has(nodeId)) {
|
|
62
|
-
cycleNodes.push(nodeId);
|
|
63
|
-
return true;
|
|
64
|
-
}
|
|
65
|
-
if (visited.has(nodeId)) {
|
|
66
|
-
return false;
|
|
67
|
-
}
|
|
68
|
-
visited.add(nodeId);
|
|
69
|
-
recursionStack.add(nodeId);
|
|
70
|
-
const node = nodes.get(nodeId);
|
|
71
|
-
if (node) {
|
|
72
|
-
for (const depId of node.dependencies) {
|
|
73
|
-
if (dfs(depId)) {
|
|
74
|
-
cycleNodes.push(nodeId);
|
|
75
|
-
return true;
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
recursionStack.delete(nodeId);
|
|
80
|
-
return false;
|
|
81
|
-
};
|
|
82
|
-
for (const nodeId of nodes.keys()) {
|
|
83
|
-
if (!visited.has(nodeId)) {
|
|
84
|
-
if (dfs(nodeId)) {
|
|
85
|
-
return { hasCycles: true, cycleNodes: [...new Set(cycleNodes)] };
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
return { hasCycles: false };
|
|
90
|
-
}
|
|
91
|
-
/**
|
|
92
|
-
* Perform topological sort to determine execution order
|
|
93
|
-
* Groups checks that can run in parallel at each level
|
|
94
|
-
*/
|
|
95
|
-
static topologicalSort(nodes) {
|
|
96
|
-
const remainingNodes = new Map(nodes);
|
|
97
|
-
const executionGroups = [];
|
|
98
|
-
let level = 0;
|
|
99
|
-
while (remainingNodes.size > 0) {
|
|
100
|
-
const readyNodes = [];
|
|
101
|
-
for (const [nodeId, node] of remainingNodes.entries()) {
|
|
102
|
-
const unmetDependencies = node.dependencies.filter((depId) => remainingNodes.has(depId));
|
|
103
|
-
if (unmetDependencies.length === 0) {
|
|
104
|
-
readyNodes.push(nodeId);
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
if (readyNodes.length === 0) {
|
|
108
|
-
throw new Error("Unable to resolve dependencies - possible circular dependency detected");
|
|
109
|
-
}
|
|
110
|
-
executionGroups.push({
|
|
111
|
-
parallel: readyNodes,
|
|
112
|
-
level
|
|
113
|
-
});
|
|
114
|
-
for (const nodeId of readyNodes) {
|
|
115
|
-
remainingNodes.delete(nodeId);
|
|
116
|
-
}
|
|
117
|
-
level++;
|
|
118
|
-
}
|
|
119
|
-
return executionGroups;
|
|
120
|
-
}
|
|
121
|
-
/**
|
|
122
|
-
* Validate that all dependencies exist
|
|
123
|
-
*/
|
|
124
|
-
static validateDependencies(checkIds, dependencies) {
|
|
125
|
-
const errors = [];
|
|
126
|
-
const checkIdSet = new Set(checkIds);
|
|
127
|
-
for (const [checkId, deps] of Object.entries(dependencies)) {
|
|
128
|
-
if (!checkIdSet.has(checkId)) {
|
|
129
|
-
errors.push(`Check "${checkId}" is not in the list of available checks`);
|
|
130
|
-
continue;
|
|
131
|
-
}
|
|
132
|
-
for (const depId of deps || []) {
|
|
133
|
-
if (!checkIdSet.has(depId)) {
|
|
134
|
-
errors.push(`Check "${checkId}" depends on "${depId}" which is not available`);
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
return {
|
|
139
|
-
valid: errors.length === 0,
|
|
140
|
-
errors
|
|
141
|
-
};
|
|
142
|
-
}
|
|
143
|
-
/**
|
|
144
|
-
* Get all transitive dependencies (ancestors) for a given check
|
|
145
|
-
* This returns all checks that must complete before the given check can run,
|
|
146
|
-
* not just the direct dependencies.
|
|
147
|
-
*
|
|
148
|
-
* For example, if A -> B -> C, then:
|
|
149
|
-
* - getAllDependencies(C) returns [A, B]
|
|
150
|
-
* - getAllDependencies(B) returns [A]
|
|
151
|
-
* - getAllDependencies(A) returns []
|
|
152
|
-
*
|
|
153
|
-
* @param checkId The check to find dependencies for
|
|
154
|
-
* @param nodes The dependency graph nodes
|
|
155
|
-
* @returns Array of all transitive dependency IDs
|
|
156
|
-
*/
|
|
157
|
-
static getAllDependencies(checkId, nodes) {
|
|
158
|
-
const allDeps = /* @__PURE__ */ new Set();
|
|
159
|
-
const visited = /* @__PURE__ */ new Set();
|
|
160
|
-
const collectDependencies = (currentId) => {
|
|
161
|
-
if (visited.has(currentId)) {
|
|
162
|
-
return;
|
|
163
|
-
}
|
|
164
|
-
visited.add(currentId);
|
|
165
|
-
const node = nodes.get(currentId);
|
|
166
|
-
if (!node) {
|
|
167
|
-
return;
|
|
168
|
-
}
|
|
169
|
-
for (const depId of node.dependencies) {
|
|
170
|
-
allDeps.add(depId);
|
|
171
|
-
collectDependencies(depId);
|
|
172
|
-
}
|
|
173
|
-
};
|
|
174
|
-
collectDependencies(checkId);
|
|
175
|
-
return Array.from(allDeps);
|
|
176
|
-
}
|
|
177
|
-
/**
|
|
178
|
-
* Get execution statistics for debugging
|
|
179
|
-
*/
|
|
180
|
-
static getExecutionStats(graph) {
|
|
181
|
-
const totalChecks = graph.nodes.size;
|
|
182
|
-
const parallelLevels = graph.executionOrder.length;
|
|
183
|
-
const maxParallelism = Math.max(...graph.executionOrder.map((group) => group.parallel.length));
|
|
184
|
-
const averageParallelism = totalChecks / parallelLevels;
|
|
185
|
-
const checksWithDependencies = Array.from(graph.nodes.values()).filter(
|
|
186
|
-
(node) => node.dependencies.length > 0
|
|
187
|
-
).length;
|
|
188
|
-
return {
|
|
189
|
-
totalChecks,
|
|
190
|
-
parallelLevels,
|
|
191
|
-
maxParallelism,
|
|
192
|
-
averageParallelism,
|
|
193
|
-
checksWithDependencies
|
|
194
|
-
};
|
|
195
|
-
}
|
|
196
|
-
};
|
|
197
|
-
}
|
|
198
|
-
});
|
|
199
|
-
|
|
200
|
-
// src/workflow-registry.ts
|
|
201
|
-
import { promises as fs } from "fs";
|
|
202
|
-
import * as path from "path";
|
|
203
|
-
import * as yaml from "js-yaml";
|
|
204
|
-
import Ajv from "ajv";
|
|
205
|
-
import addFormats from "ajv-formats";
|
|
206
|
-
var WorkflowRegistry;
|
|
207
|
-
var init_workflow_registry = __esm({
|
|
208
|
-
"src/workflow-registry.ts"() {
|
|
209
|
-
init_logger();
|
|
210
|
-
init_dependency_resolver();
|
|
211
|
-
WorkflowRegistry = class _WorkflowRegistry {
|
|
212
|
-
static instance;
|
|
213
|
-
workflows = /* @__PURE__ */ new Map();
|
|
214
|
-
ajv;
|
|
215
|
-
constructor() {
|
|
216
|
-
this.ajv = new Ajv({ allErrors: true, strict: false });
|
|
217
|
-
addFormats(this.ajv);
|
|
218
|
-
}
|
|
219
|
-
/**
|
|
220
|
-
* Get the singleton instance of the workflow registry
|
|
221
|
-
*/
|
|
222
|
-
static getInstance() {
|
|
223
|
-
if (!_WorkflowRegistry.instance) {
|
|
224
|
-
_WorkflowRegistry.instance = new _WorkflowRegistry();
|
|
225
|
-
}
|
|
226
|
-
return _WorkflowRegistry.instance;
|
|
227
|
-
}
|
|
228
|
-
/**
|
|
229
|
-
* Register a workflow definition
|
|
230
|
-
*/
|
|
231
|
-
register(workflow, source = "inline", options) {
|
|
232
|
-
const validation = this.validateWorkflow(workflow);
|
|
233
|
-
if (!validation.valid) {
|
|
234
|
-
return validation;
|
|
235
|
-
}
|
|
236
|
-
if (this.workflows.has(workflow.id) && !options?.override) {
|
|
237
|
-
return {
|
|
238
|
-
valid: false,
|
|
239
|
-
errors: [
|
|
240
|
-
{
|
|
241
|
-
path: "id",
|
|
242
|
-
message: `Workflow with ID '${workflow.id}' already exists`,
|
|
243
|
-
value: workflow.id
|
|
244
|
-
}
|
|
245
|
-
]
|
|
246
|
-
};
|
|
247
|
-
}
|
|
248
|
-
this.workflows.set(workflow.id, {
|
|
249
|
-
definition: workflow,
|
|
250
|
-
source,
|
|
251
|
-
registeredAt: /* @__PURE__ */ new Date(),
|
|
252
|
-
usage: {
|
|
253
|
-
count: 0
|
|
254
|
-
}
|
|
255
|
-
});
|
|
256
|
-
logger.debug(`Registered workflow '${workflow.id}' from ${source}`);
|
|
257
|
-
return { valid: true };
|
|
258
|
-
}
|
|
259
|
-
/**
|
|
260
|
-
* Get a workflow by ID
|
|
261
|
-
*/
|
|
262
|
-
get(id) {
|
|
263
|
-
const entry = this.workflows.get(id);
|
|
264
|
-
if (entry) {
|
|
265
|
-
entry.usage = entry.usage || { count: 0 };
|
|
266
|
-
entry.usage.count++;
|
|
267
|
-
entry.usage.lastUsed = /* @__PURE__ */ new Date();
|
|
268
|
-
}
|
|
269
|
-
return entry?.definition;
|
|
270
|
-
}
|
|
271
|
-
/**
|
|
272
|
-
* Check if a workflow exists
|
|
273
|
-
*/
|
|
274
|
-
has(id) {
|
|
275
|
-
return this.workflows.has(id);
|
|
276
|
-
}
|
|
277
|
-
/**
|
|
278
|
-
* List all registered workflows
|
|
279
|
-
*/
|
|
280
|
-
list() {
|
|
281
|
-
return Array.from(this.workflows.values()).map((entry) => entry.definition);
|
|
282
|
-
}
|
|
283
|
-
/**
|
|
284
|
-
* Get workflow metadata
|
|
285
|
-
*/
|
|
286
|
-
getMetadata(id) {
|
|
287
|
-
return this.workflows.get(id);
|
|
288
|
-
}
|
|
289
|
-
/**
|
|
290
|
-
* Remove a workflow from the registry
|
|
291
|
-
*/
|
|
292
|
-
unregister(id) {
|
|
293
|
-
return this.workflows.delete(id);
|
|
294
|
-
}
|
|
295
|
-
/**
|
|
296
|
-
* Clear all workflows
|
|
297
|
-
*/
|
|
298
|
-
clear() {
|
|
299
|
-
this.workflows.clear();
|
|
300
|
-
}
|
|
301
|
-
/**
|
|
302
|
-
* Import workflows from a file or URL
|
|
303
|
-
*/
|
|
304
|
-
async import(source, options) {
|
|
305
|
-
return this.importInternal(source, options, /* @__PURE__ */ new Set());
|
|
306
|
-
}
|
|
307
|
-
async importInternal(source, options, visited) {
|
|
308
|
-
const results = [];
|
|
309
|
-
try {
|
|
310
|
-
const { content, resolvedSource, importBasePath } = await this.loadWorkflowContent(
|
|
311
|
-
source,
|
|
312
|
-
options?.basePath
|
|
313
|
-
);
|
|
314
|
-
const visitKey = resolvedSource || source;
|
|
315
|
-
if (visited.has(visitKey)) {
|
|
316
|
-
return results;
|
|
317
|
-
}
|
|
318
|
-
visited.add(visitKey);
|
|
319
|
-
const data = this.parseWorkflowContent(content, resolvedSource || source);
|
|
320
|
-
const topImports = !Array.isArray(data) ? data?.imports : void 0;
|
|
321
|
-
if (Array.isArray(topImports)) {
|
|
322
|
-
for (const childSource of topImports) {
|
|
323
|
-
const childResults = await this.importInternal(
|
|
324
|
-
childSource,
|
|
325
|
-
{ ...options, basePath: importBasePath },
|
|
326
|
-
visited
|
|
327
|
-
);
|
|
328
|
-
results.push(...childResults);
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
const rawWorkflows = Array.isArray(data) ? data : [data];
|
|
332
|
-
const workflows = [];
|
|
333
|
-
for (const raw of rawWorkflows) {
|
|
334
|
-
if (raw && typeof raw === "object" && typeof raw.extends === "string") {
|
|
335
|
-
const basePath = importBasePath || path.dirname(resolvedSource || source);
|
|
336
|
-
const baseResolved = path.isAbsolute(raw.extends) ? raw.extends : path.resolve(basePath, raw.extends);
|
|
337
|
-
try {
|
|
338
|
-
const baseContent = await fs.readFile(baseResolved, "utf-8");
|
|
339
|
-
const baseData = this.parseWorkflowContent(baseContent, baseResolved);
|
|
340
|
-
const { extends: _extends, ...rest } = raw;
|
|
341
|
-
void _extends;
|
|
342
|
-
const merged = this.deepMergeWorkflow(baseData, rest);
|
|
343
|
-
workflows.push(merged);
|
|
344
|
-
} catch (err) {
|
|
345
|
-
logger.warn(
|
|
346
|
-
`[WorkflowRegistry] Failed to resolve extends '${raw.extends}' for workflow '${raw.id || "?"}': ${err instanceof Error ? err.message : err}`
|
|
347
|
-
);
|
|
348
|
-
workflows.push(raw);
|
|
349
|
-
}
|
|
350
|
-
} else {
|
|
351
|
-
workflows.push(raw);
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
for (const workflow of workflows) {
|
|
355
|
-
const workflowImports = workflow?.imports;
|
|
356
|
-
if (Array.isArray(workflowImports)) {
|
|
357
|
-
for (const childSource of workflowImports) {
|
|
358
|
-
const childResults = await this.importInternal(
|
|
359
|
-
childSource,
|
|
360
|
-
{ ...options, basePath: importBasePath },
|
|
361
|
-
visited
|
|
362
|
-
);
|
|
363
|
-
results.push(...childResults);
|
|
364
|
-
}
|
|
365
|
-
}
|
|
366
|
-
if (options?.validate !== false) {
|
|
367
|
-
const validation = this.validateWorkflow(workflow);
|
|
368
|
-
if (!validation.valid) {
|
|
369
|
-
results.push(validation);
|
|
370
|
-
continue;
|
|
371
|
-
}
|
|
372
|
-
if (options?.validators) {
|
|
373
|
-
for (const validator of options.validators) {
|
|
374
|
-
const customValidation = validator(workflow);
|
|
375
|
-
if (!customValidation.valid) {
|
|
376
|
-
results.push(customValidation);
|
|
377
|
-
continue;
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
}
|
|
382
|
-
const workflowWithoutExtras = { ...workflow };
|
|
383
|
-
delete workflowWithoutExtras.tests;
|
|
384
|
-
delete workflowWithoutExtras.imports;
|
|
385
|
-
const result = this.register(workflowWithoutExtras, source, {
|
|
386
|
-
override: options?.override
|
|
387
|
-
});
|
|
388
|
-
results.push(result);
|
|
389
|
-
}
|
|
390
|
-
} catch (error) {
|
|
391
|
-
results.push({
|
|
392
|
-
valid: false,
|
|
393
|
-
errors: [
|
|
394
|
-
{
|
|
395
|
-
path: "source",
|
|
396
|
-
message: `Failed to import workflows from '${source}': ${error instanceof Error ? error.message : String(error)}`,
|
|
397
|
-
value: source
|
|
398
|
-
}
|
|
399
|
-
]
|
|
400
|
-
});
|
|
401
|
-
}
|
|
402
|
-
return results;
|
|
403
|
-
}
|
|
404
|
-
/**
|
|
405
|
-
* Import multiple workflow sources
|
|
406
|
-
*/
|
|
407
|
-
async importMany(sources, options) {
|
|
408
|
-
const results = /* @__PURE__ */ new Map();
|
|
409
|
-
for (const source of sources) {
|
|
410
|
-
const importResults = await this.import(source, options);
|
|
411
|
-
results.set(source, importResults);
|
|
412
|
-
}
|
|
413
|
-
return results;
|
|
414
|
-
}
|
|
415
|
-
/**
|
|
416
|
-
* Validate a workflow definition
|
|
417
|
-
*/
|
|
418
|
-
validateWorkflow(workflow) {
|
|
419
|
-
const errors = [];
|
|
420
|
-
const warnings = [];
|
|
421
|
-
if (!workflow.id) {
|
|
422
|
-
errors.push({ path: "id", message: "Workflow ID is required" });
|
|
423
|
-
}
|
|
424
|
-
if (!workflow.name) {
|
|
425
|
-
errors.push({ path: "name", message: "Workflow name is required" });
|
|
426
|
-
}
|
|
427
|
-
if (!workflow.steps || Object.keys(workflow.steps).length === 0) {
|
|
428
|
-
errors.push({ path: "steps", message: "Workflow must have at least one step" });
|
|
429
|
-
}
|
|
430
|
-
if (workflow.inputs) {
|
|
431
|
-
for (let i = 0; i < workflow.inputs.length; i++) {
|
|
432
|
-
const input = workflow.inputs[i];
|
|
433
|
-
if (!input.name) {
|
|
434
|
-
errors.push({ path: `inputs[${i}].name`, message: "Input parameter name is required" });
|
|
435
|
-
}
|
|
436
|
-
if (!input.schema) {
|
|
437
|
-
warnings.push({
|
|
438
|
-
path: `inputs[${i}].schema`,
|
|
439
|
-
message: "Input parameter schema is recommended"
|
|
440
|
-
});
|
|
441
|
-
}
|
|
442
|
-
if (input.schema?.type === "array" && !input.schema.items) {
|
|
443
|
-
warnings.push({
|
|
444
|
-
path: `inputs[${i}].schema`,
|
|
445
|
-
message: 'Array schema should define "items" (e.g. items: { type: string }). Some LLM providers (Gemini) reject array schemas without items.'
|
|
446
|
-
});
|
|
447
|
-
}
|
|
448
|
-
}
|
|
449
|
-
}
|
|
450
|
-
if (workflow.outputs) {
|
|
451
|
-
for (let i = 0; i < workflow.outputs.length; i++) {
|
|
452
|
-
const output = workflow.outputs[i];
|
|
453
|
-
if (!output.name) {
|
|
454
|
-
errors.push({ path: `outputs[${i}].name`, message: "Output parameter name is required" });
|
|
455
|
-
}
|
|
456
|
-
if (!output.value && !output.value_js) {
|
|
457
|
-
errors.push({
|
|
458
|
-
path: `outputs[${i}]`,
|
|
459
|
-
message: "Output parameter must have either value or value_js"
|
|
460
|
-
});
|
|
461
|
-
}
|
|
462
|
-
}
|
|
463
|
-
}
|
|
464
|
-
for (const [stepId, step] of Object.entries(workflow.steps || {})) {
|
|
465
|
-
if (step.depends_on) {
|
|
466
|
-
for (const dep of step.depends_on) {
|
|
467
|
-
const orParts = typeof dep === "string" && dep.includes("|") ? dep.split("|").map((s) => s.trim()).filter(Boolean) : [dep];
|
|
468
|
-
for (const part of orParts) {
|
|
469
|
-
if (!workflow.steps[part]) {
|
|
470
|
-
errors.push({
|
|
471
|
-
path: `steps.${stepId}.depends_on`,
|
|
472
|
-
message: `Step '${stepId}' depends on non-existent step '${part}'`,
|
|
473
|
-
value: dep
|
|
474
|
-
});
|
|
475
|
-
}
|
|
476
|
-
}
|
|
477
|
-
}
|
|
478
|
-
}
|
|
479
|
-
if (step.inputs) {
|
|
480
|
-
for (const [inputName, mapping] of Object.entries(step.inputs)) {
|
|
481
|
-
if (typeof mapping === "object" && mapping !== null && "source" in mapping) {
|
|
482
|
-
const typedMapping = mapping;
|
|
483
|
-
if (typedMapping.source === "step" && !typedMapping.stepId) {
|
|
484
|
-
errors.push({
|
|
485
|
-
path: `steps.${stepId}.inputs.${inputName}`,
|
|
486
|
-
message: 'Step input mapping with source "step" must have stepId'
|
|
487
|
-
});
|
|
488
|
-
}
|
|
489
|
-
if (typedMapping.source === "param") {
|
|
490
|
-
const paramExists = workflow.inputs?.some((p) => p.name === typedMapping.value);
|
|
491
|
-
if (!paramExists) {
|
|
492
|
-
errors.push({
|
|
493
|
-
path: `steps.${stepId}.inputs.${inputName}`,
|
|
494
|
-
message: `Step input references non-existent parameter '${typedMapping.value}'`,
|
|
495
|
-
value: typedMapping.value
|
|
496
|
-
});
|
|
497
|
-
}
|
|
498
|
-
}
|
|
499
|
-
}
|
|
500
|
-
}
|
|
501
|
-
}
|
|
502
|
-
}
|
|
503
|
-
const circularDeps = this.detectCircularDependencies(workflow);
|
|
504
|
-
if (circularDeps.length > 0) {
|
|
505
|
-
errors.push({
|
|
506
|
-
path: "steps",
|
|
507
|
-
message: `Circular dependencies detected: ${circularDeps.join(" -> ")}`
|
|
508
|
-
});
|
|
509
|
-
}
|
|
510
|
-
return {
|
|
511
|
-
valid: errors.length === 0,
|
|
512
|
-
errors: errors.length > 0 ? errors : void 0,
|
|
513
|
-
warnings: warnings.length > 0 ? warnings : void 0
|
|
514
|
-
};
|
|
515
|
-
}
|
|
516
|
-
/**
|
|
517
|
-
* Validate input values against workflow input schema
|
|
518
|
-
*/
|
|
519
|
-
validateInputs(workflow, inputs) {
|
|
520
|
-
const errors = [];
|
|
521
|
-
if (!workflow.inputs) {
|
|
522
|
-
return { valid: true };
|
|
523
|
-
}
|
|
524
|
-
for (const param of workflow.inputs) {
|
|
525
|
-
if (param.required !== false && !(param.name in inputs) && param.default === void 0) {
|
|
526
|
-
errors.push({
|
|
527
|
-
path: `inputs.${param.name}`,
|
|
528
|
-
message: `Required input '${param.name}' is missing`
|
|
529
|
-
});
|
|
530
|
-
}
|
|
531
|
-
}
|
|
532
|
-
for (const param of workflow.inputs) {
|
|
533
|
-
if (param.name in inputs && param.schema) {
|
|
534
|
-
const value = inputs[param.name];
|
|
535
|
-
const valid = this.validateAgainstSchema(value, param.schema);
|
|
536
|
-
if (!valid.valid) {
|
|
537
|
-
errors.push({
|
|
538
|
-
path: `inputs.${param.name}`,
|
|
539
|
-
message: valid.error || "Invalid input value",
|
|
540
|
-
value
|
|
541
|
-
});
|
|
542
|
-
}
|
|
543
|
-
}
|
|
544
|
-
}
|
|
545
|
-
return {
|
|
546
|
-
valid: errors.length === 0,
|
|
547
|
-
errors: errors.length > 0 ? errors : void 0
|
|
548
|
-
};
|
|
549
|
-
}
|
|
550
|
-
/**
|
|
551
|
-
* Load workflow content from file or URL
|
|
552
|
-
*/
|
|
553
|
-
async loadWorkflowContent(source, basePath) {
|
|
554
|
-
const baseIsUrl = basePath?.startsWith("http://") || basePath?.startsWith("https://");
|
|
555
|
-
if (source.startsWith("visor://") || source.startsWith("visor-ee://")) {
|
|
556
|
-
const relativePath = source.replace(/^visor(?:-ee)?:\/\//, "");
|
|
557
|
-
const defaultsDir = path.resolve(__dirname, "..", "defaults");
|
|
558
|
-
const filePath2 = path.resolve(defaultsDir, relativePath);
|
|
559
|
-
if (!filePath2.startsWith(defaultsDir + path.sep)) {
|
|
560
|
-
throw new Error(`Invalid visor:// path: resolved path escapes defaults directory`);
|
|
561
|
-
}
|
|
562
|
-
const content2 = await fs.readFile(filePath2, "utf-8");
|
|
563
|
-
return { content: content2, resolvedSource: filePath2, importBasePath: path.dirname(filePath2) };
|
|
564
|
-
}
|
|
565
|
-
if (source.startsWith("http://") || source.startsWith("https://")) {
|
|
566
|
-
const response = await fetch(source);
|
|
567
|
-
if (!response.ok) {
|
|
568
|
-
throw new Error(`Failed to fetch workflow from ${source}: ${response.statusText}`);
|
|
569
|
-
}
|
|
570
|
-
const importBasePath = new URL(".", source).toString();
|
|
571
|
-
return { content: await response.text(), resolvedSource: source, importBasePath };
|
|
572
|
-
}
|
|
573
|
-
if (baseIsUrl) {
|
|
574
|
-
const resolvedUrl = new URL(source, basePath).toString();
|
|
575
|
-
const response = await fetch(resolvedUrl);
|
|
576
|
-
if (!response.ok) {
|
|
577
|
-
throw new Error(`Failed to fetch workflow from ${resolvedUrl}: ${response.statusText}`);
|
|
578
|
-
}
|
|
579
|
-
const importBasePath = new URL(".", resolvedUrl).toString();
|
|
580
|
-
return { content: await response.text(), resolvedSource: resolvedUrl, importBasePath };
|
|
581
|
-
}
|
|
582
|
-
const filePath = path.isAbsolute(source) ? source : path.resolve(basePath || process.cwd(), source);
|
|
583
|
-
const content = await fs.readFile(filePath, "utf-8");
|
|
584
|
-
return { content, resolvedSource: filePath, importBasePath: path.dirname(filePath) };
|
|
585
|
-
}
|
|
586
|
-
/**
|
|
587
|
-
* Parse workflow content (YAML or JSON)
|
|
588
|
-
*/
|
|
589
|
-
parseWorkflowContent(content, source) {
|
|
590
|
-
try {
|
|
591
|
-
return JSON.parse(content);
|
|
592
|
-
} catch {
|
|
593
|
-
try {
|
|
594
|
-
return yaml.load(content);
|
|
595
|
-
} catch (error) {
|
|
596
|
-
throw new Error(
|
|
597
|
-
`Failed to parse workflow file ${source}: ${error instanceof Error ? error.message : String(error)}`
|
|
598
|
-
);
|
|
599
|
-
}
|
|
600
|
-
}
|
|
601
|
-
}
|
|
602
|
-
/**
|
|
603
|
-
* Deep-merge a base workflow config with an override.
|
|
604
|
-
* Objects merge recursively (override wins for leaf values); arrays/primitives override.
|
|
605
|
-
*/
|
|
606
|
-
deepMergeWorkflow(base, override) {
|
|
607
|
-
if (!base || !override || typeof base !== "object" || typeof override !== "object" || Array.isArray(base) || Array.isArray(override)) {
|
|
608
|
-
return override !== void 0 ? override : base;
|
|
609
|
-
}
|
|
610
|
-
const result = { ...base };
|
|
611
|
-
for (const key of Object.keys(override)) {
|
|
612
|
-
if (key in result && result[key] && typeof result[key] === "object" && !Array.isArray(result[key]) && override[key] && typeof override[key] === "object" && !Array.isArray(override[key])) {
|
|
613
|
-
result[key] = this.deepMergeWorkflow(result[key], override[key]);
|
|
614
|
-
} else {
|
|
615
|
-
result[key] = override[key];
|
|
616
|
-
}
|
|
617
|
-
}
|
|
618
|
-
return result;
|
|
619
|
-
}
|
|
620
|
-
/**
|
|
621
|
-
* Detect circular dependencies in workflow steps using DependencyResolver
|
|
622
|
-
*/
|
|
623
|
-
detectCircularDependencies(workflow) {
|
|
624
|
-
const dependencies = {};
|
|
625
|
-
for (const [stepId, step] of Object.entries(workflow.steps || {})) {
|
|
626
|
-
const rawDeps = step.depends_on;
|
|
627
|
-
dependencies[stepId] = Array.isArray(rawDeps) ? rawDeps : rawDeps ? [rawDeps] : [];
|
|
628
|
-
}
|
|
629
|
-
try {
|
|
630
|
-
const graph = DependencyResolver.buildDependencyGraph(dependencies);
|
|
631
|
-
if (graph.hasCycles && graph.cycleNodes) {
|
|
632
|
-
return graph.cycleNodes;
|
|
633
|
-
}
|
|
634
|
-
return [];
|
|
635
|
-
} catch {
|
|
636
|
-
return [];
|
|
637
|
-
}
|
|
638
|
-
}
|
|
639
|
-
/**
|
|
640
|
-
* Validate a value against a JSON schema
|
|
641
|
-
*/
|
|
642
|
-
validateAgainstSchema(value, schema) {
|
|
643
|
-
try {
|
|
644
|
-
const validate = this.ajv.compile(schema);
|
|
645
|
-
const valid = validate(value);
|
|
646
|
-
if (!valid) {
|
|
647
|
-
const errors = validate.errors?.map((e) => `${e.instancePath || "/"}: ${e.message}`).join(", ");
|
|
648
|
-
return { valid: false, error: errors };
|
|
649
|
-
}
|
|
650
|
-
return { valid: true };
|
|
651
|
-
} catch (error) {
|
|
652
|
-
return { valid: false, error: error instanceof Error ? error.message : String(error) };
|
|
653
|
-
}
|
|
654
|
-
}
|
|
655
|
-
};
|
|
656
|
-
}
|
|
657
|
-
});
|
|
658
|
-
|
|
659
|
-
export {
|
|
660
|
-
DependencyResolver,
|
|
661
|
-
init_dependency_resolver,
|
|
662
|
-
WorkflowRegistry,
|
|
663
|
-
init_workflow_registry
|
|
664
|
-
};
|
|
665
|
-
//# sourceMappingURL=chunk-54KOAC4W.mjs.map
|