@xemahq/dsl 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (288) hide show
  1. package/LICENSE +201 -0
  2. package/dist/deliverable-spec/index.d.ts +3 -0
  3. package/dist/deliverable-spec/index.d.ts.map +1 -0
  4. package/dist/deliverable-spec/index.js +19 -0
  5. package/dist/deliverable-spec/index.js.map +1 -0
  6. package/dist/deliverable-spec/lib/schema.d.ts +151 -0
  7. package/dist/deliverable-spec/lib/schema.d.ts.map +1 -0
  8. package/dist/deliverable-spec/lib/schema.js +139 -0
  9. package/dist/deliverable-spec/lib/schema.js.map +1 -0
  10. package/dist/deliverable-spec/lib/types.d.ts +8 -0
  11. package/dist/deliverable-spec/lib/types.d.ts.map +1 -0
  12. package/dist/deliverable-spec/lib/types.js +3 -0
  13. package/dist/deliverable-spec/lib/types.js.map +1 -0
  14. package/dist/payload-codec/index.d.ts +8 -0
  15. package/dist/payload-codec/index.d.ts.map +1 -0
  16. package/dist/payload-codec/index.js +27 -0
  17. package/dist/payload-codec/index.js.map +1 -0
  18. package/dist/payload-codec/lib/blob-store.d.ts +37 -0
  19. package/dist/payload-codec/lib/blob-store.d.ts.map +1 -0
  20. package/dist/payload-codec/lib/blob-store.js +0 -0
  21. package/dist/payload-codec/lib/blob-store.js.map +1 -0
  22. package/dist/payload-codec/lib/codec-context.d.ts +6 -0
  23. package/dist/payload-codec/lib/codec-context.d.ts.map +1 -0
  24. package/dist/payload-codec/lib/codec-context.js +16 -0
  25. package/dist/payload-codec/lib/codec-context.js.map +1 -0
  26. package/dist/payload-codec/lib/codec.d.ts +51 -0
  27. package/dist/payload-codec/lib/codec.d.ts.map +1 -0
  28. package/dist/payload-codec/lib/codec.js +330 -0
  29. package/dist/payload-codec/lib/codec.js.map +1 -0
  30. package/dist/payload-codec/lib/enums.d.ts +18 -0
  31. package/dist/payload-codec/lib/enums.d.ts.map +1 -0
  32. package/dist/payload-codec/lib/enums.js +23 -0
  33. package/dist/payload-codec/lib/enums.js.map +1 -0
  34. package/dist/payload-codec/lib/errors.d.ts +18 -0
  35. package/dist/payload-codec/lib/errors.d.ts.map +1 -0
  36. package/dist/payload-codec/lib/errors.js +39 -0
  37. package/dist/payload-codec/lib/errors.js.map +1 -0
  38. package/dist/payload-codec/lib/http-blob-store.d.ts +21 -0
  39. package/dist/payload-codec/lib/http-blob-store.d.ts.map +1 -0
  40. package/dist/payload-codec/lib/http-blob-store.js +139 -0
  41. package/dist/payload-codec/lib/http-blob-store.js.map +1 -0
  42. package/dist/payload-codec/lib/lru-cache.d.ts +12 -0
  43. package/dist/payload-codec/lib/lru-cache.d.ts.map +1 -0
  44. package/dist/payload-codec/lib/lru-cache.js +59 -0
  45. package/dist/payload-codec/lib/lru-cache.js.map +1 -0
  46. package/dist/schema/action.schema.json +181 -0
  47. package/dist/schema/reusable-workflow.schema.json +46 -0
  48. package/dist/schema/workflow.schema.json +373 -0
  49. package/dist/workflow/index.d.ts +14 -0
  50. package/dist/workflow/index.d.ts.map +1 -0
  51. package/dist/workflow/index.js +49 -0
  52. package/dist/workflow/index.js.map +1 -0
  53. package/dist/workflow/lib/action-input-validator.d.ts +10 -0
  54. package/dist/workflow/lib/action-input-validator.d.ts.map +1 -0
  55. package/dist/workflow/lib/action-input-validator.js +69 -0
  56. package/dist/workflow/lib/action-input-validator.js.map +1 -0
  57. package/dist/workflow/lib/compiler/action-shape.d.ts +5 -0
  58. package/dist/workflow/lib/compiler/action-shape.d.ts.map +1 -0
  59. package/dist/workflow/lib/compiler/action-shape.js +43 -0
  60. package/dist/workflow/lib/compiler/action-shape.js.map +1 -0
  61. package/dist/workflow/lib/compiler/canonical-json.d.ts +3 -0
  62. package/dist/workflow/lib/compiler/canonical-json.d.ts.map +1 -0
  63. package/dist/workflow/lib/compiler/canonical-json.js +45 -0
  64. package/dist/workflow/lib/compiler/canonical-json.js.map +1 -0
  65. package/dist/workflow/lib/compiler/compile.d.ts +4 -0
  66. package/dist/workflow/lib/compiler/compile.d.ts.map +1 -0
  67. package/dist/workflow/lib/compiler/compile.js +794 -0
  68. package/dist/workflow/lib/compiler/compile.js.map +1 -0
  69. package/dist/workflow/lib/compiler/concurrency.d.ts +5 -0
  70. package/dist/workflow/lib/compiler/concurrency.d.ts.map +1 -0
  71. package/dist/workflow/lib/compiler/concurrency.js +104 -0
  72. package/dist/workflow/lib/compiler/concurrency.js.map +1 -0
  73. package/dist/workflow/lib/compiler/dag.d.ts +10 -0
  74. package/dist/workflow/lib/compiler/dag.d.ts.map +1 -0
  75. package/dist/workflow/lib/compiler/dag.js +74 -0
  76. package/dist/workflow/lib/compiler/dag.js.map +1 -0
  77. package/dist/workflow/lib/compiler/index.d.ts +6 -0
  78. package/dist/workflow/lib/compiler/index.d.ts.map +1 -0
  79. package/dist/workflow/lib/compiler/index.js +14 -0
  80. package/dist/workflow/lib/compiler/index.js.map +1 -0
  81. package/dist/workflow/lib/compiler/inputs.d.ts +4 -0
  82. package/dist/workflow/lib/compiler/inputs.d.ts.map +1 -0
  83. package/dist/workflow/lib/compiler/inputs.js +108 -0
  84. package/dist/workflow/lib/compiler/inputs.js.map +1 -0
  85. package/dist/workflow/lib/compiler/installation-resource-validator.d.ts +9 -0
  86. package/dist/workflow/lib/compiler/installation-resource-validator.d.ts.map +1 -0
  87. package/dist/workflow/lib/compiler/installation-resource-validator.js +76 -0
  88. package/dist/workflow/lib/compiler/installation-resource-validator.js.map +1 -0
  89. package/dist/workflow/lib/compiler/manifest-source.d.ts +4 -0
  90. package/dist/workflow/lib/compiler/manifest-source.d.ts.map +1 -0
  91. package/dist/workflow/lib/compiler/manifest-source.js +100 -0
  92. package/dist/workflow/lib/compiler/manifest-source.js.map +1 -0
  93. package/dist/workflow/lib/compiler/matrix.d.ts +4 -0
  94. package/dist/workflow/lib/compiler/matrix.d.ts.map +1 -0
  95. package/dist/workflow/lib/compiler/matrix.js +76 -0
  96. package/dist/workflow/lib/compiler/matrix.js.map +1 -0
  97. package/dist/workflow/lib/compiler/mount-plan.d.ts +4 -0
  98. package/dist/workflow/lib/compiler/mount-plan.d.ts.map +1 -0
  99. package/dist/workflow/lib/compiler/mount-plan.js +96 -0
  100. package/dist/workflow/lib/compiler/mount-plan.js.map +1 -0
  101. package/dist/workflow/lib/compiler/payload-reach-in.d.ts +14 -0
  102. package/dist/workflow/lib/compiler/payload-reach-in.d.ts.map +1 -0
  103. package/dist/workflow/lib/compiler/payload-reach-in.js +273 -0
  104. package/dist/workflow/lib/compiler/payload-reach-in.js.map +1 -0
  105. package/dist/workflow/lib/compiler/permissions.d.ts +6 -0
  106. package/dist/workflow/lib/compiler/permissions.d.ts.map +1 -0
  107. package/dist/workflow/lib/compiler/permissions.js +43 -0
  108. package/dist/workflow/lib/compiler/permissions.js.map +1 -0
  109. package/dist/workflow/lib/compiler/retry-timeout.d.ts +6 -0
  110. package/dist/workflow/lib/compiler/retry-timeout.d.ts.map +1 -0
  111. package/dist/workflow/lib/compiler/retry-timeout.js +64 -0
  112. package/dist/workflow/lib/compiler/retry-timeout.js.map +1 -0
  113. package/dist/workflow/lib/compiler/review-step.d.ts +18 -0
  114. package/dist/workflow/lib/compiler/review-step.d.ts.map +1 -0
  115. package/dist/workflow/lib/compiler/review-step.js +247 -0
  116. package/dist/workflow/lib/compiler/review-step.js.map +1 -0
  117. package/dist/workflow/lib/compiler/types.d.ts +42 -0
  118. package/dist/workflow/lib/compiler/types.d.ts.map +1 -0
  119. package/dist/workflow/lib/compiler/types.js +3 -0
  120. package/dist/workflow/lib/compiler/types.js.map +1 -0
  121. package/dist/workflow/lib/compiler/variable-requirements.d.ts +5 -0
  122. package/dist/workflow/lib/compiler/variable-requirements.d.ts.map +1 -0
  123. package/dist/workflow/lib/compiler/variable-requirements.js +119 -0
  124. package/dist/workflow/lib/compiler/variable-requirements.js.map +1 -0
  125. package/dist/workflow/lib/deliverable-spec-keys.d.ts +3 -0
  126. package/dist/workflow/lib/deliverable-spec-keys.d.ts.map +1 -0
  127. package/dist/workflow/lib/deliverable-spec-keys.js +90 -0
  128. package/dist/workflow/lib/deliverable-spec-keys.js.map +1 -0
  129. package/dist/workflow/lib/dispatch-inputs/index.d.ts +23 -0
  130. package/dist/workflow/lib/dispatch-inputs/index.d.ts.map +1 -0
  131. package/dist/workflow/lib/dispatch-inputs/index.js +106 -0
  132. package/dist/workflow/lib/dispatch-inputs/index.js.map +1 -0
  133. package/dist/workflow/lib/dispatch-inputs/to-json-schema.d.ts +3 -0
  134. package/dist/workflow/lib/dispatch-inputs/to-json-schema.d.ts.map +1 -0
  135. package/dist/workflow/lib/dispatch-inputs/to-json-schema.js +43 -0
  136. package/dist/workflow/lib/dispatch-inputs/to-json-schema.js.map +1 -0
  137. package/dist/workflow/lib/duration.d.ts +2 -0
  138. package/dist/workflow/lib/duration.d.ts.map +1 -0
  139. package/dist/workflow/lib/duration.js +26 -0
  140. package/dist/workflow/lib/duration.js.map +1 -0
  141. package/dist/workflow/lib/errors.d.ts +9 -0
  142. package/dist/workflow/lib/errors.d.ts.map +1 -0
  143. package/dist/workflow/lib/errors.js +28 -0
  144. package/dist/workflow/lib/errors.js.map +1 -0
  145. package/dist/workflow/lib/expression/ast.d.ts +61 -0
  146. package/dist/workflow/lib/expression/ast.d.ts.map +1 -0
  147. package/dist/workflow/lib/expression/ast.js +34 -0
  148. package/dist/workflow/lib/expression/ast.js.map +1 -0
  149. package/dist/workflow/lib/expression/context.d.ts +63 -0
  150. package/dist/workflow/lib/expression/context.d.ts.map +1 -0
  151. package/dist/workflow/lib/expression/context.js +32 -0
  152. package/dist/workflow/lib/expression/context.js.map +1 -0
  153. package/dist/workflow/lib/expression/evaluator.d.ts +5 -0
  154. package/dist/workflow/lib/expression/evaluator.d.ts.map +1 -0
  155. package/dist/workflow/lib/expression/evaluator.js +291 -0
  156. package/dist/workflow/lib/expression/evaluator.js.map +1 -0
  157. package/dist/workflow/lib/expression/index.d.ts +9 -0
  158. package/dist/workflow/lib/expression/index.d.ts.map +1 -0
  159. package/dist/workflow/lib/expression/index.js +26 -0
  160. package/dist/workflow/lib/expression/index.js.map +1 -0
  161. package/dist/workflow/lib/expression/interpolation.d.ts +9 -0
  162. package/dist/workflow/lib/expression/interpolation.d.ts.map +1 -0
  163. package/dist/workflow/lib/expression/interpolation.js +51 -0
  164. package/dist/workflow/lib/expression/interpolation.js.map +1 -0
  165. package/dist/workflow/lib/expression/parser.d.ts +4 -0
  166. package/dist/workflow/lib/expression/parser.d.ts.map +1 -0
  167. package/dist/workflow/lib/expression/parser.js +203 -0
  168. package/dist/workflow/lib/expression/parser.js.map +1 -0
  169. package/dist/workflow/lib/expression/template.d.ts +18 -0
  170. package/dist/workflow/lib/expression/template.d.ts.map +1 -0
  171. package/dist/workflow/lib/expression/template.js +63 -0
  172. package/dist/workflow/lib/expression/template.js.map +1 -0
  173. package/dist/workflow/lib/expression/tokenizer.d.ts +3 -0
  174. package/dist/workflow/lib/expression/tokenizer.d.ts.map +1 -0
  175. package/dist/workflow/lib/expression/tokenizer.js +153 -0
  176. package/dist/workflow/lib/expression/tokenizer.js.map +1 -0
  177. package/dist/workflow/lib/expression/tokens.d.ts +25 -0
  178. package/dist/workflow/lib/expression/tokens.d.ts.map +1 -0
  179. package/dist/workflow/lib/expression/tokens.js +24 -0
  180. package/dist/workflow/lib/expression/tokens.js.map +1 -0
  181. package/dist/workflow/lib/expression/walk-artifact-refs.d.ts +5 -0
  182. package/dist/workflow/lib/expression/walk-artifact-refs.d.ts.map +1 -0
  183. package/dist/workflow/lib/expression/walk-artifact-refs.js +138 -0
  184. package/dist/workflow/lib/expression/walk-artifact-refs.js.map +1 -0
  185. package/dist/workflow/lib/installation-resource-kind.d.ts +14 -0
  186. package/dist/workflow/lib/installation-resource-kind.d.ts.map +1 -0
  187. package/dist/workflow/lib/installation-resource-kind.js +59 -0
  188. package/dist/workflow/lib/installation-resource-kind.js.map +1 -0
  189. package/dist/workflow/lib/schemas-loader.d.ts +4 -0
  190. package/dist/workflow/lib/schemas-loader.d.ts.map +1 -0
  191. package/dist/workflow/lib/schemas-loader.js +36 -0
  192. package/dist/workflow/lib/schemas-loader.js.map +1 -0
  193. package/dist/workflow/lib/serializer.d.ts +3 -0
  194. package/dist/workflow/lib/serializer.d.ts.map +1 -0
  195. package/dist/workflow/lib/serializer.js +15 -0
  196. package/dist/workflow/lib/serializer.js.map +1 -0
  197. package/dist/workflow/lib/types.d.ts +179 -0
  198. package/dist/workflow/lib/types.d.ts.map +1 -0
  199. package/dist/workflow/lib/types.js +3 -0
  200. package/dist/workflow/lib/types.js.map +1 -0
  201. package/dist/workflow/lib/validate.d.ts +8 -0
  202. package/dist/workflow/lib/validate.d.ts.map +1 -0
  203. package/dist/workflow/lib/validate.js +119 -0
  204. package/dist/workflow/lib/validate.js.map +1 -0
  205. package/dist/workspace-manifest/index.d.ts +6 -0
  206. package/dist/workspace-manifest/index.d.ts.map +1 -0
  207. package/dist/workspace-manifest/index.js +22 -0
  208. package/dist/workspace-manifest/index.js.map +1 -0
  209. package/dist/workspace-manifest/lib/compile.d.ts +8 -0
  210. package/dist/workspace-manifest/lib/compile.d.ts.map +1 -0
  211. package/dist/workspace-manifest/lib/compile.js +439 -0
  212. package/dist/workspace-manifest/lib/compile.js.map +1 -0
  213. package/dist/workspace-manifest/lib/interpolate.d.ts +12 -0
  214. package/dist/workspace-manifest/lib/interpolate.d.ts.map +1 -0
  215. package/dist/workspace-manifest/lib/interpolate.js +81 -0
  216. package/dist/workspace-manifest/lib/interpolate.js.map +1 -0
  217. package/dist/workspace-manifest/lib/resolve-extends.d.ts +10 -0
  218. package/dist/workspace-manifest/lib/resolve-extends.d.ts.map +1 -0
  219. package/dist/workspace-manifest/lib/resolve-extends.js +108 -0
  220. package/dist/workspace-manifest/lib/resolve-extends.js.map +1 -0
  221. package/dist/workspace-manifest/lib/schema.d.ts +710 -0
  222. package/dist/workspace-manifest/lib/schema.d.ts.map +1 -0
  223. package/dist/workspace-manifest/lib/schema.js +355 -0
  224. package/dist/workspace-manifest/lib/schema.js.map +1 -0
  225. package/dist/workspace-manifest/lib/types.d.ts +153 -0
  226. package/dist/workspace-manifest/lib/types.d.ts.map +1 -0
  227. package/dist/workspace-manifest/lib/types.js +10 -0
  228. package/dist/workspace-manifest/lib/types.js.map +1 -0
  229. package/package.json +79 -0
  230. package/schema/action.schema.json +181 -0
  231. package/schema/reusable-workflow.schema.json +46 -0
  232. package/schema/workflow.schema.json +373 -0
  233. package/src/deliverable-spec/index.ts +19 -0
  234. package/src/deliverable-spec/lib/schema.ts +248 -0
  235. package/src/deliverable-spec/lib/types.ts +26 -0
  236. package/src/payload-codec/index.ts +40 -0
  237. package/src/payload-codec/lib/blob-store.ts +0 -0
  238. package/src/payload-codec/lib/codec-context.ts +38 -0
  239. package/src/payload-codec/lib/codec.ts +593 -0
  240. package/src/payload-codec/lib/enums.ts +58 -0
  241. package/src/payload-codec/lib/errors.ts +54 -0
  242. package/src/payload-codec/lib/http-blob-store.ts +257 -0
  243. package/src/payload-codec/lib/lru-cache.ts +81 -0
  244. package/src/workflow/index.ts +98 -0
  245. package/src/workflow/lib/action-input-validator.ts +160 -0
  246. package/src/workflow/lib/compiler/action-shape.ts +71 -0
  247. package/src/workflow/lib/compiler/canonical-json.ts +53 -0
  248. package/src/workflow/lib/compiler/compile.ts +1518 -0
  249. package/src/workflow/lib/compiler/concurrency.ts +223 -0
  250. package/src/workflow/lib/compiler/dag.ts +108 -0
  251. package/src/workflow/lib/compiler/index.ts +10 -0
  252. package/src/workflow/lib/compiler/inputs.ts +199 -0
  253. package/src/workflow/lib/compiler/installation-resource-validator.ts +114 -0
  254. package/src/workflow/lib/compiler/manifest-source.ts +176 -0
  255. package/src/workflow/lib/compiler/matrix.ts +135 -0
  256. package/src/workflow/lib/compiler/mount-plan.ts +202 -0
  257. package/src/workflow/lib/compiler/payload-reach-in.ts +497 -0
  258. package/src/workflow/lib/compiler/permissions.ts +64 -0
  259. package/src/workflow/lib/compiler/retry-timeout.ts +105 -0
  260. package/src/workflow/lib/compiler/review-step.ts +517 -0
  261. package/src/workflow/lib/compiler/types.ts +170 -0
  262. package/src/workflow/lib/compiler/variable-requirements.ts +208 -0
  263. package/src/workflow/lib/deliverable-spec-keys.ts +109 -0
  264. package/src/workflow/lib/dispatch-inputs/index.ts +160 -0
  265. package/src/workflow/lib/dispatch-inputs/to-json-schema.ts +60 -0
  266. package/src/workflow/lib/duration.ts +48 -0
  267. package/src/workflow/lib/errors.ts +37 -0
  268. package/src/workflow/lib/expression/ast.ts +108 -0
  269. package/src/workflow/lib/expression/context.ts +148 -0
  270. package/src/workflow/lib/expression/evaluator.ts +492 -0
  271. package/src/workflow/lib/expression/index.ts +28 -0
  272. package/src/workflow/lib/expression/interpolation.ts +84 -0
  273. package/src/workflow/lib/expression/parser.ts +264 -0
  274. package/src/workflow/lib/expression/template.ts +117 -0
  275. package/src/workflow/lib/expression/tokenizer.ts +200 -0
  276. package/src/workflow/lib/expression/tokens.ts +30 -0
  277. package/src/workflow/lib/expression/walk-artifact-refs.ts +232 -0
  278. package/src/workflow/lib/installation-resource-kind.ts +107 -0
  279. package/src/workflow/lib/schemas-loader.ts +64 -0
  280. package/src/workflow/lib/serializer.ts +30 -0
  281. package/src/workflow/lib/types.ts +361 -0
  282. package/src/workflow/lib/validate.ts +199 -0
  283. package/src/workspace-manifest/index.ts +27 -0
  284. package/src/workspace-manifest/lib/compile.ts +608 -0
  285. package/src/workspace-manifest/lib/interpolate.ts +140 -0
  286. package/src/workspace-manifest/lib/resolve-extends.ts +260 -0
  287. package/src/workspace-manifest/lib/schema.ts +612 -0
  288. package/src/workspace-manifest/lib/types.ts +392 -0
@@ -0,0 +1,794 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.compileWorkflow = compileWorkflow;
4
+ const workflow_1 = require("@xemahq/kernel-contracts/workflow");
5
+ const errors_1 = require("../errors");
6
+ const expression_1 = require("../expression");
7
+ const canonical_json_1 = require("./canonical-json");
8
+ const concurrency_1 = require("./concurrency");
9
+ const dag_1 = require("./dag");
10
+ const inputs_1 = require("./inputs");
11
+ const matrix_1 = require("./matrix");
12
+ const manifest_source_1 = require("./manifest-source");
13
+ const mount_plan_1 = require("./mount-plan");
14
+ const permissions_1 = require("./permissions");
15
+ const review_step_1 = require("./review-step");
16
+ const retry_timeout_1 = require("./retry-timeout");
17
+ const payload_reach_in_1 = require("./payload-reach-in");
18
+ const installation_resource_validator_1 = require("./installation-resource-validator");
19
+ const variable_requirements_1 = require("./variable-requirements");
20
+ function compileWorkflow(input) {
21
+ const { workflow, workflowRef, trigger, resolvedRefs, workflowDefinitionVersionSha256 } = input;
22
+ const inputs = (0, inputs_1.bindTriggerInputs)(workflow, trigger, input.previewMode ?? false);
23
+ const vars = workflow.vars ?? {};
24
+ const requiredVariables = (0, variable_requirements_1.resolveWalletRequirements)(workflow, input.resolvedWallets);
25
+ const requiredWallets = Object.freeze([
26
+ ...(workflow.requires?.wallets ?? []),
27
+ ]);
28
+ const permissions = (0, permissions_1.normalizePermissions)(workflow.permissions);
29
+ const concurrency = (0, concurrency_1.compileConcurrency)(workflow.concurrency, trigger, inputs, vars);
30
+ const defaults = (0, retry_timeout_1.resolveWorkflowDefaults)(workflow.defaults);
31
+ validateAllAuthoredExpressions(workflow);
32
+ (0, variable_requirements_1.validateVariableReferences)(workflow, requiredVariables, input.resolvedWallets);
33
+ validateAllLiteralReferences(workflow, input.resolvedAgents ?? {}, input.resolvedDeliverableSpecs ?? {});
34
+ (0, review_step_1.validateReviewSteps)(workflow);
35
+ const reviewNeedsExtensions = (0, review_step_1.computeReviewNeedsExtensions)(workflow);
36
+ validateMatrixGather(workflow);
37
+ validateAllNeedsAccessShapes(workflow);
38
+ validateDeliverableValueExpressions(workflow, input.resolvedDeliverableSpecs ?? {});
39
+ (0, payload_reach_in_1.validatePayloadReachIns)(workflow, input.resolvedDeliverableSpecs ?? {}, resolvedRefs);
40
+ const orderedJobs = (0, dag_1.topologicalSort)(Object.entries(workflow.jobs).map(([key, decl]) => {
41
+ const authoredNeeds = decl.needs ?? [];
42
+ const gather = decl.matrixGather ?? [];
43
+ const reviewExt = reviewNeedsExtensions[key] ?? [];
44
+ const merged = gather.length > 0 || reviewExt.length > 0
45
+ ? Array.from(new Set([...authoredNeeds, ...gather, ...reviewExt]))
46
+ : authoredNeeds;
47
+ return { key, payload: decl, needs: merged };
48
+ }));
49
+ const compiledJobs = orderedJobs.map(({ key, payload, needs }) => {
50
+ const resolved = lookupResolvedRef(payload.uses, resolvedRefs);
51
+ const actionRef = {
52
+ id: resolved.id,
53
+ version: resolved.version,
54
+ manifestSha256: resolved.manifestSha256,
55
+ executionKind: resolveJobExecutionKind(key, payload.with, resolved),
56
+ taskQueue: resolved.taskQueue,
57
+ actionKind: resolveActionKind(resolved),
58
+ isReusableWorkflow: resolved.isReusableWorkflow,
59
+ inputsSchema: resolved.isReusableWorkflow
60
+ ? null
61
+ : resolved.actionManifest?.spec.inputs ?? null,
62
+ };
63
+ const jobPermissions = (0, permissions_1.normalizePermissions)(payload.permissions);
64
+ (0, permissions_1.assertJobPermissionsFit)(jobPermissions, permissions, key);
65
+ const strategy = (0, matrix_1.compileStrategy)(payload.strategy, key);
66
+ const mountPlan = resolved.isReusableWorkflow
67
+ ? { readOnly: {}, readWrite: {} }
68
+ : (0, mount_plan_1.compileMountPlan)(key, payload.with, resolved.actionManifest);
69
+ const manifestSource = resolved.isReusableWorkflow
70
+ ? null
71
+ : (0, manifest_source_1.compileManifestSource)(key, payload.with, resolved.actionManifest);
72
+ const retry = (0, retry_timeout_1.resolveJobRetry)(defaults.retry, resolved.actionManifest?.spec.retryDefaults ?? null, payload.retry);
73
+ const timeoutMs = (0, retry_timeout_1.resolveJobTimeout)(defaults.timeoutMs, resolved.actionManifest?.spec.timeoutDefaults ?? null, payload.timeout);
74
+ const ifExpression = payload.if !== undefined
75
+ ? (() => {
76
+ const body = (0, expression_1.stripInterpolation)(payload.if);
77
+ const rewritten = rewriteBareNeedsInIf(body);
78
+ (0, expression_1.compileExpression)(rewritten);
79
+ return rewritten;
80
+ })()
81
+ : null;
82
+ const compiledWith = (0, review_step_1.rewriteReviewStepWith)(key, payload, workflow);
83
+ (0, installation_resource_validator_1.validateInstallationResourceBindings)({
84
+ jobKey: key,
85
+ actionId: actionRef.id,
86
+ inputsSchema: actionRef.inputsSchema,
87
+ withValue: compiledWith,
88
+ scope: input.installationScope,
89
+ });
90
+ return Object.freeze({
91
+ jobKey: key,
92
+ title: payload.title ?? null,
93
+ needs,
94
+ matrixGather: Object.freeze([...(payload.matrixGather ?? [])]),
95
+ ifExpression,
96
+ strategy,
97
+ action: actionRef,
98
+ mountPlan,
99
+ manifestSource,
100
+ with: Object.freeze({ ...compiledWith }),
101
+ outputs: compileOutputsMap(payload.outputs, `jobs.${key}.outputs`),
102
+ retry,
103
+ timeoutMs,
104
+ permissions: jobPermissions,
105
+ reusableCompiledRun: null,
106
+ payloadReachIns: Object.freeze((0, payload_reach_in_1.collectPayloadReachInsForJob)(workflow, key, payload, input.resolvedDeliverableSpecs ?? {}, resolvedRefs)),
107
+ });
108
+ });
109
+ const snapshotCreatedAt = input.trigger.triggeredAt;
110
+ const workflowCallOutputs = compileOutputsMap(workflow.on.workflow_call?.outputs, 'on.workflow_call.outputs');
111
+ const workflowOutputs = compileWorkflowOutputs(workflow);
112
+ const baseCompiled = {
113
+ compiledRunVersion: 1,
114
+ workflowRef,
115
+ trigger,
116
+ inputs,
117
+ vars,
118
+ requiredWallets,
119
+ requiredVariables,
120
+ permissions,
121
+ concurrency,
122
+ defaults,
123
+ jobs: Object.freeze(compiledJobs),
124
+ snapshotCreatedAt,
125
+ workflowDefinitionVersionSha256,
126
+ workflowCallOutputs,
127
+ workflowOutputs,
128
+ ...(input.briefcase !== undefined && { briefcase: input.briefcase }),
129
+ };
130
+ const snapshotSha256 = (0, canonical_json_1.canonicalJsonSha256)(baseCompiled);
131
+ const compiled = {
132
+ ...baseCompiled,
133
+ snapshotSha256,
134
+ };
135
+ assertStrategyInvariants(compiled);
136
+ return compiled;
137
+ }
138
+ function rewriteBareNeedsInIf(body) {
139
+ let ast;
140
+ try {
141
+ ast = (0, expression_1.compileExpression)(body);
142
+ }
143
+ catch {
144
+ return body;
145
+ }
146
+ const upstreamKey = matchBareNeedsRef(ast);
147
+ if (upstreamKey === null)
148
+ return body;
149
+ return `needs.${upstreamKey}.outcome == 'ok'`;
150
+ }
151
+ function matchBareNeedsRef(node) {
152
+ if (node.kind !== expression_1.ExpressionNodeKind.MEMBER)
153
+ return null;
154
+ const target = node.target;
155
+ if (target.kind !== expression_1.ExpressionNodeKind.IDENTIFIER)
156
+ return null;
157
+ if (target.name !== 'needs')
158
+ return null;
159
+ return node.property;
160
+ }
161
+ function resolveJobExecutionKind(jobKey, withBlock, resolved) {
162
+ const inputs = resolved.actionManifest?.spec.inputs;
163
+ const inputProps = inputs && typeof inputs === 'object'
164
+ ? inputs.properties
165
+ : undefined;
166
+ const declaresExecutionKindInput = inputProps !== null &&
167
+ typeof inputProps === 'object' &&
168
+ 'executionKind' in inputProps;
169
+ if (!declaresExecutionKindInput) {
170
+ return resolved.executionKind;
171
+ }
172
+ const raw = withBlock?.executionKind;
173
+ if (raw === undefined) {
174
+ return resolved.executionKind;
175
+ }
176
+ if (raw !== workflow_1.ActionExecutionKind.ACTIVITY &&
177
+ raw !== workflow_1.ActionExecutionKind.CHILD_WORKFLOW) {
178
+ throw new errors_1.WorkflowDslError(workflow_1.WorkflowErrorCode.DSL_SEMANTIC_INVALID, `jobs.${jobKey}.with.executionKind must be the literal '${workflow_1.ActionExecutionKind.ACTIVITY}' or '${workflow_1.ActionExecutionKind.CHILD_WORKFLOW}' — the Temporal dispatch primitive is fixed at compile time, so expressions are not allowed.`, { jobKey, executionKind: raw });
179
+ }
180
+ return raw;
181
+ }
182
+ function resolveActionKind(resolved) {
183
+ if (resolved.isReusableWorkflow)
184
+ return workflow_1.ActionKind.DISPATCH;
185
+ const declared = resolved.actionManifest?.spec.actionKind;
186
+ if (declared === undefined)
187
+ return workflow_1.ActionKind.GENERIC;
188
+ const known = new Set(Object.values(workflow_1.ActionKind));
189
+ return known.has(declared) ? declared : workflow_1.ActionKind.GENERIC;
190
+ }
191
+ function lookupResolvedRef(uses, resolvedRefs) {
192
+ const ref = resolvedRefs[uses];
193
+ if (!ref) {
194
+ const isReusable = uses.startsWith('xema://workflow/');
195
+ throw new errors_1.WorkflowDslError(isReusable
196
+ ? workflow_1.WorkflowErrorCode.DSL_UNKNOWN_REUSABLE_WORKFLOW
197
+ : workflow_1.WorkflowErrorCode.DSL_UNKNOWN_ACTION, `Reference '${uses}' is not present in resolvedRefs map passed to compiler.`, { uses });
198
+ }
199
+ return ref;
200
+ }
201
+ function validateAllAuthoredExpressions(doc) {
202
+ for (const [key, job] of Object.entries(doc.jobs)) {
203
+ validateJobExpressions(key, job);
204
+ }
205
+ const callOutputs = doc.on.workflow_call?.outputs;
206
+ if (callOutputs) {
207
+ for (const expr of Object.values(callOutputs)) {
208
+ const body = (0, expression_1.stripInterpolation)(expr);
209
+ (0, expression_1.compileExpression)(body);
210
+ }
211
+ }
212
+ (0, concurrency_1.validateConcurrencyGroupTemplate)(doc.concurrency);
213
+ }
214
+ function validateAllLiteralReferences(doc, resolvedAgents, resolvedDeliverableSpecs) {
215
+ const agentValidationEnabled = Object.keys(resolvedAgents).length > 0;
216
+ const specValidationEnabled = Object.keys(resolvedDeliverableSpecs).length > 0;
217
+ if (!agentValidationEnabled && !specValidationEnabled) {
218
+ return;
219
+ }
220
+ for (const [jobKey, job] of Object.entries(doc.jobs)) {
221
+ validateJobLiteralReferences(jobKey, job, agentValidationEnabled ? resolvedAgents : null, specValidationEnabled ? resolvedDeliverableSpecs : null);
222
+ }
223
+ }
224
+ function validateJobLiteralReferences(jobKey, job, resolvedAgents, resolvedSpecs) {
225
+ const withMap = job.with;
226
+ if (withMap) {
227
+ if (resolvedAgents) {
228
+ assertLiteralAgent(jobKey, 'with.agentSlug', withMap['agentSlug'], resolvedAgents);
229
+ validateReviewerAgents(jobKey, withMap['reviewers'], resolvedAgents);
230
+ }
231
+ if (resolvedSpecs) {
232
+ assertLiteralDeliverableSpec(jobKey, 'with.deliverableSpecRef', withMap['deliverableSpecRef'], resolvedSpecs);
233
+ }
234
+ assertVersioningMode(jobKey, withMap['versioning']);
235
+ }
236
+ }
237
+ function validateReviewerAgents(jobKey, reviewers, resolvedAgents) {
238
+ if (!Array.isArray(reviewers)) {
239
+ return;
240
+ }
241
+ for (let i = 0; i < reviewers.length; i++) {
242
+ const reviewer = reviewers[i];
243
+ if (reviewer === null ||
244
+ typeof reviewer !== 'object' ||
245
+ Array.isArray(reviewer)) {
246
+ continue;
247
+ }
248
+ assertLiteralAgent(jobKey, `with.reviewers[${i}].agentSlug`, reviewer['agentSlug'], resolvedAgents);
249
+ }
250
+ }
251
+ function isLiteralStringValue(value) {
252
+ return typeof value === 'string' && !value.includes('${{');
253
+ }
254
+ function assertLiteralAgent(jobKey, fieldPath, value, resolvedAgents) {
255
+ if (!isLiteralStringValue(value)) {
256
+ return;
257
+ }
258
+ if (resolvedAgents[value] !== undefined) {
259
+ return;
260
+ }
261
+ const knownPreview = formatKnownPreview(Object.keys(resolvedAgents));
262
+ throw new errors_1.WorkflowDslError(workflow_1.WorkflowErrorCode.DSL_UNKNOWN_AGENT, `Job '${jobKey}' ${fieldPath} = '${value}' is not a registered agent. Known: [${knownPreview}].`, { jobKey, fieldPath, value, knownCount: Object.keys(resolvedAgents).length });
263
+ }
264
+ function assertLiteralDeliverableSpec(jobKey, fieldPath, value, resolvedSpecs) {
265
+ if (!isLiteralStringValue(value)) {
266
+ return;
267
+ }
268
+ if (resolvedSpecs[value] !== undefined) {
269
+ return;
270
+ }
271
+ const knownPreview = formatKnownPreview(Object.keys(resolvedSpecs));
272
+ throw new errors_1.WorkflowDslError(workflow_1.WorkflowErrorCode.DSL_UNKNOWN_DELIVERABLE_SPEC, `Job '${jobKey}' ${fieldPath} = '${value}' is not a registered deliverable spec. Known: [${knownPreview}].`, { jobKey, fieldPath, value, knownCount: Object.keys(resolvedSpecs).length });
273
+ }
274
+ const VALID_VERSIONING_MODES = ['append', 'new', 'replace'];
275
+ function assertVersioningMode(jobKey, value) {
276
+ if (value === undefined || value === null)
277
+ return;
278
+ if (typeof value === 'string' && value.startsWith('${{'))
279
+ return;
280
+ if (typeof value === 'string' &&
281
+ VALID_VERSIONING_MODES.includes(value)) {
282
+ return;
283
+ }
284
+ throw new errors_1.WorkflowDslError(workflow_1.WorkflowErrorCode.DSL_SEMANTIC_INVALID, `Job '${jobKey}' with.versioning = ${JSON.stringify(value)} is not a valid ArtifactVersioningMode. Allowed: [${VALID_VERSIONING_MODES.join(', ')}].`, {
285
+ jobKey,
286
+ fieldPath: 'with.versioning',
287
+ value: typeof value === 'string' ? value : JSON.stringify(value),
288
+ allowed: [...VALID_VERSIONING_MODES],
289
+ });
290
+ }
291
+ function formatKnownPreview(keys) {
292
+ if (keys.length === 0) {
293
+ return '(none)';
294
+ }
295
+ const sorted = [...keys].sort((a, b) => a.localeCompare(b));
296
+ if (sorted.length <= 12) {
297
+ return sorted.join(', ');
298
+ }
299
+ return `${sorted.slice(0, 12).join(', ')}, … (+${sorted.length - 12} more)`;
300
+ }
301
+ function validateJobExpressions(key, job) {
302
+ if (job.if !== undefined) {
303
+ const body = (0, expression_1.stripInterpolation)(job.if);
304
+ (0, expression_1.compileExpression)(body);
305
+ }
306
+ if (job.with) {
307
+ const extracted = (0, expression_1.extractInterpolations)(job.with, [key, 'with']);
308
+ for (const ext of extracted)
309
+ (0, expression_1.compileExpression)(ext.source);
310
+ }
311
+ if (job.outputs) {
312
+ for (const expr of Object.values(job.outputs)) {
313
+ const body = (0, expression_1.stripInterpolation)(expr);
314
+ (0, expression_1.compileExpression)(body);
315
+ }
316
+ }
317
+ if (job.strategy && 'dynamic' in job.strategy) {
318
+ const body = (0, expression_1.stripInterpolation)(job.strategy.dynamic.from);
319
+ (0, expression_1.compileExpression)(body);
320
+ }
321
+ }
322
+ function compileOutputsMap(raw, contextLabel) {
323
+ if (!raw || Object.keys(raw).length === 0) {
324
+ return Object.freeze({});
325
+ }
326
+ const stripped = {};
327
+ for (const [name, expr] of Object.entries(raw)) {
328
+ try {
329
+ stripped[name] = (0, expression_1.stripInterpolation)(expr);
330
+ }
331
+ catch (err) {
332
+ const message = err instanceof Error ? err.message : String(err);
333
+ throw new errors_1.WorkflowDslError(workflow_1.WorkflowErrorCode.DSL_EXPRESSION_INVALID, `${contextLabel}.${name}: ${message}`, { contextLabel, name, expr });
334
+ }
335
+ }
336
+ return Object.freeze(stripped);
337
+ }
338
+ function compileWorkflowOutputs(workflow) {
339
+ const raw = workflow.outputs;
340
+ if (!raw || Object.keys(raw).length === 0) {
341
+ return Object.freeze({});
342
+ }
343
+ const seenSlugs = new Set();
344
+ const compiled = {};
345
+ for (const [name, decl] of Object.entries(raw)) {
346
+ const job = workflow.jobs[decl.fromJob];
347
+ if (!job) {
348
+ throw new errors_1.WorkflowDslError(workflow_1.WorkflowErrorCode.DSL_SEMANTIC_INVALID, `outputs.${name}: fromJob "${decl.fromJob}" is not a declared job`, { outputName: name, fromJob: decl.fromJob });
349
+ }
350
+ if (!job.outputs || !(decl.fromOutput in job.outputs)) {
351
+ throw new errors_1.WorkflowDslError(workflow_1.WorkflowErrorCode.DSL_SEMANTIC_INVALID, `outputs.${name}: job "${decl.fromJob}" does not declare an output named "${decl.fromOutput}"`, { outputName: name, fromJob: decl.fromJob, fromOutput: decl.fromOutput });
352
+ }
353
+ if (seenSlugs.has(decl.slug)) {
354
+ throw new errors_1.WorkflowDslError(workflow_1.WorkflowErrorCode.DSL_SEMANTIC_INVALID, `outputs.${name}: slug "${decl.slug}" is already used by another output`, { outputName: name, slug: decl.slug });
355
+ }
356
+ seenSlugs.add(decl.slug);
357
+ if (decl.kind === 'deliverable') {
358
+ compiled[name] = {
359
+ kind: 'deliverable',
360
+ slug: decl.slug,
361
+ fromJob: decl.fromJob,
362
+ fromOutput: decl.fromOutput,
363
+ deliverableSpecRef: decl.deliverableSpecRef,
364
+ ...(decl.description ? { description: decl.description } : {}),
365
+ };
366
+ }
367
+ else if (decl.kind === 'structured') {
368
+ compiled[name] = {
369
+ kind: 'structured',
370
+ slug: decl.slug,
371
+ fromJob: decl.fromJob,
372
+ fromOutput: decl.fromOutput,
373
+ ...(decl.schemaRef ? { schemaRef: decl.schemaRef } : {}),
374
+ ...(decl.description ? { description: decl.description } : {}),
375
+ };
376
+ }
377
+ else {
378
+ compiled[name] = {
379
+ kind: 'text',
380
+ slug: decl.slug,
381
+ fromJob: decl.fromJob,
382
+ fromOutput: decl.fromOutput,
383
+ ...(decl.description ? { description: decl.description } : {}),
384
+ };
385
+ }
386
+ }
387
+ return Object.freeze(compiled);
388
+ }
389
+ function validateMatrixGather(doc) {
390
+ for (const [jobKey, decl] of Object.entries(doc.jobs)) {
391
+ const gather = decl.matrixGather;
392
+ if (!gather || gather.length === 0)
393
+ continue;
394
+ for (const target of gather) {
395
+ if (target === jobKey) {
396
+ throw new errors_1.WorkflowDslError(workflow_1.WorkflowErrorCode.DSL_SEMANTIC_INVALID, `Job '${jobKey}' matrixGather cannot reference itself.`, { jobKey, target });
397
+ }
398
+ const targetDecl = doc.jobs[target];
399
+ if (!targetDecl) {
400
+ throw new errors_1.WorkflowDslError(workflow_1.WorkflowErrorCode.DSL_SEMANTIC_INVALID, `Job '${jobKey}' matrixGather references unknown job '${target}'.`, { jobKey, target });
401
+ }
402
+ if (!targetDecl.strategy || (!('matrix' in targetDecl.strategy) && !('dynamic' in targetDecl.strategy))) {
403
+ throw new errors_1.WorkflowDslError(workflow_1.WorkflowErrorCode.DSL_SEMANTIC_INVALID, `Job '${jobKey}' matrixGather references '${target}' which has no matrix/dynamic strategy; gathering only makes sense across matrix entries.`, { jobKey, target });
404
+ }
405
+ }
406
+ }
407
+ }
408
+ function validateAllNeedsAccessShapes(doc) {
409
+ for (const [jobKey, job] of Object.entries(doc.jobs)) {
410
+ const consumerBinding = extractConsumerBinding(job);
411
+ const expressions = collectJobExpressions(jobKey, job);
412
+ for (const { source, fieldPath } of expressions) {
413
+ const ast = (0, expression_1.compileExpression)(source);
414
+ walkNeedsAccesses(ast, (access) => {
415
+ validateNeedsAccess(doc, jobKey, fieldPath, consumerBinding, access);
416
+ });
417
+ }
418
+ }
419
+ const callOutputs = doc.on.workflow_call?.outputs;
420
+ if (callOutputs) {
421
+ for (const [outputName, expr] of Object.entries(callOutputs)) {
422
+ const ast = (0, expression_1.compileExpression)((0, expression_1.stripInterpolation)(expr));
423
+ walkNeedsAccesses(ast, (access) => {
424
+ validateNeedsAccess(doc, '<workflow_call.outputs>', `on.workflow_call.outputs.${outputName}`, null, access);
425
+ });
426
+ }
427
+ }
428
+ }
429
+ function collectJobExpressions(jobKey, job) {
430
+ const out = [];
431
+ if (job.if !== undefined) {
432
+ out.push({ source: (0, expression_1.stripInterpolation)(job.if), fieldPath: `${jobKey}.if` });
433
+ }
434
+ if (job.with) {
435
+ for (const ext of (0, expression_1.extractInterpolations)(job.with, [jobKey, 'with'])) {
436
+ out.push({ source: ext.source, fieldPath: ext.path.join('.') });
437
+ }
438
+ }
439
+ if (job.outputs) {
440
+ for (const [name, expr] of Object.entries(job.outputs)) {
441
+ out.push({
442
+ source: (0, expression_1.stripInterpolation)(expr),
443
+ fieldPath: `${jobKey}.outputs.${name}`,
444
+ });
445
+ }
446
+ }
447
+ if (job.strategy && 'dynamic' in job.strategy) {
448
+ out.push({
449
+ source: (0, expression_1.stripInterpolation)(job.strategy.dynamic.from),
450
+ fieldPath: `${jobKey}.strategy.dynamic.from`,
451
+ });
452
+ }
453
+ return out;
454
+ }
455
+ function extractConsumerBinding(job) {
456
+ if (job.strategy && 'dynamic' in job.strategy) {
457
+ return job.strategy.dynamic.as;
458
+ }
459
+ return null;
460
+ }
461
+ function walkNeedsAccesses(node, visit) {
462
+ const access = matchNeedsAccess(node);
463
+ if (access !== null) {
464
+ visit(access);
465
+ for (const step of access.steps) {
466
+ if (step.kind === 'index') {
467
+ walkNeedsAccesses(step.node, visit);
468
+ }
469
+ }
470
+ return;
471
+ }
472
+ switch (node.kind) {
473
+ case expression_1.ExpressionNodeKind.MEMBER:
474
+ walkNeedsAccesses(node.target, visit);
475
+ return;
476
+ case expression_1.ExpressionNodeKind.INDEX:
477
+ walkNeedsAccesses(node.target, visit);
478
+ walkNeedsAccesses(node.index, visit);
479
+ return;
480
+ case expression_1.ExpressionNodeKind.CALL:
481
+ for (const arg of node.args)
482
+ walkNeedsAccesses(arg, visit);
483
+ return;
484
+ case expression_1.ExpressionNodeKind.UNARY_NOT:
485
+ walkNeedsAccesses(node.operand, visit);
486
+ return;
487
+ case expression_1.ExpressionNodeKind.BINARY_EQ:
488
+ case expression_1.ExpressionNodeKind.BINARY_NEQ:
489
+ case expression_1.ExpressionNodeKind.BINARY_AND:
490
+ case expression_1.ExpressionNodeKind.BINARY_OR:
491
+ walkNeedsAccesses(node.left, visit);
492
+ walkNeedsAccesses(node.right, visit);
493
+ return;
494
+ case expression_1.ExpressionNodeKind.LITERAL:
495
+ case expression_1.ExpressionNodeKind.IDENTIFIER:
496
+ return;
497
+ }
498
+ }
499
+ function matchNeedsAccess(node) {
500
+ const reverseSteps = [];
501
+ let cursor = node;
502
+ while (cursor.kind === expression_1.ExpressionNodeKind.MEMBER ||
503
+ cursor.kind === expression_1.ExpressionNodeKind.INDEX) {
504
+ if (cursor.kind === expression_1.ExpressionNodeKind.MEMBER) {
505
+ reverseSteps.push({ kind: 'member', name: cursor.property });
506
+ }
507
+ else {
508
+ reverseSteps.push({ kind: 'index', node: cursor.index });
509
+ }
510
+ cursor = cursor.target;
511
+ }
512
+ if (cursor.kind !== expression_1.ExpressionNodeKind.IDENTIFIER ||
513
+ cursor.name !== 'needs') {
514
+ return null;
515
+ }
516
+ const steps = reverseSteps.toReversed();
517
+ if (steps.length < 2)
518
+ return null;
519
+ const first = steps[0];
520
+ const second = steps[1];
521
+ if (first.kind !== 'member')
522
+ return null;
523
+ if (second.kind !== 'member' || second.name !== 'outputs')
524
+ return null;
525
+ return {
526
+ upstreamJobKey: first.name,
527
+ steps: steps.slice(2),
528
+ };
529
+ }
530
+ function validateNeedsAccess(doc, consumerJobKey, fieldPath, consumerBinding, access) {
531
+ const upstream = doc.jobs[access.upstreamJobKey];
532
+ if (!upstream) {
533
+ return;
534
+ }
535
+ const isDynamicMatrix = !!upstream.strategy && 'dynamic' in upstream.strategy;
536
+ const isStaticMatrix = !!upstream.strategy && 'matrix' in upstream.strategy;
537
+ const isMatrix = isDynamicMatrix || isStaticMatrix;
538
+ if (!isMatrix) {
539
+ if (access.steps.length > 0 &&
540
+ access.steps[0].kind === 'member' &&
541
+ access.steps[0].name === 'byKey') {
542
+ throw new errors_1.WorkflowDslError(workflow_1.WorkflowErrorCode.DSL_INVALID_MATRIX_OUTPUT_ACCESS, `Job '${consumerJobKey}' ${fieldPath}: cannot read 'byKey' on '${access.upstreamJobKey}' because it is not a matrix job. 'byKey' is only available on matrix jobs that declare 'keyBy:'.`, {
543
+ consumerJobKey,
544
+ upstreamJobKey: access.upstreamJobKey,
545
+ fieldPath,
546
+ });
547
+ }
548
+ return;
549
+ }
550
+ const consumerJob = doc.jobs[consumerJobKey];
551
+ if (consumerJob?.matrixGather?.includes(access.upstreamJobKey)) {
552
+ rejectByKeyOnGathered(access, consumerJobKey, fieldPath);
553
+ return;
554
+ }
555
+ const keyBy = isDynamicMatrix
556
+ ? upstream.strategy.dynamic.keyBy ?? null
557
+ : null;
558
+ if (access.steps.length === 0)
559
+ return;
560
+ const head = access.steps[0];
561
+ if (head.kind === 'member' && head.name === 'byKey') {
562
+ validateByKeyChain(access, keyBy, consumerJobKey, consumerBinding, fieldPath);
563
+ return;
564
+ }
565
+ if (head.kind === 'member') {
566
+ if (head.name === 'length')
567
+ return;
568
+ throw new errors_1.WorkflowDslError(workflow_1.WorkflowErrorCode.DSL_INVALID_MATRIX_OUTPUT_ACCESS, `Job '${consumerJobKey}' ${fieldPath}: cannot read 'needs.${access.upstreamJobKey}.outputs.${head.name}' because '${access.upstreamJobKey}' is a matrix job — its outputs are indexed by entry, not by field. Choose one: (1) read positionally with 'outputs[<n>].${head.name}'; (2) flatten with 'matrixGather: [${access.upstreamJobKey}]' on '${consumerJobKey}' and drop the '.${head.name}' suffix; (3) add 'keyBy: <field>' to '${access.upstreamJobKey}' and use 'outputs.byKey[<key>].${head.name}'.`, {
569
+ consumerJobKey,
570
+ upstreamJobKey: access.upstreamJobKey,
571
+ fieldPath,
572
+ offendingProperty: head.name,
573
+ });
574
+ }
575
+ }
576
+ function rejectByKeyOnGathered(access, consumerJobKey, fieldPath) {
577
+ const head = access.steps[0];
578
+ if (head?.kind === 'member' && head.name === 'byKey') {
579
+ throw new errors_1.WorkflowDslError(workflow_1.WorkflowErrorCode.DSL_INVALID_MATRIX_OUTPUT_ACCESS, `Job '${consumerJobKey}' ${fieldPath}: cannot read 'byKey' on '${access.upstreamJobKey}' because the consumer applies 'matrixGather' which flattens the upstream into an array. Drop 'matrixGather' to enable keyed access, or read positional entries via [n].`, {
580
+ consumerJobKey,
581
+ upstreamJobKey: access.upstreamJobKey,
582
+ fieldPath,
583
+ });
584
+ }
585
+ }
586
+ function validateByKeyChain(access, upstreamKeyBy, consumerJobKey, consumerBinding, fieldPath) {
587
+ if (upstreamKeyBy === null) {
588
+ throw new errors_1.WorkflowDslError(workflow_1.WorkflowErrorCode.DSL_MATRIX_KEY_NOT_DECLARED, `Job '${consumerJobKey}' ${fieldPath}: cannot read 'needs.${access.upstreamJobKey}.outputs.byKey' because '${access.upstreamJobKey}' has no 'keyBy:' declared on its matrix strategy. Add 'keyBy: <field>' to '${access.upstreamJobKey}.strategy.dynamic' to expose a keyed map.`, {
589
+ consumerJobKey,
590
+ upstreamJobKey: access.upstreamJobKey,
591
+ fieldPath,
592
+ });
593
+ }
594
+ const indexStep = access.steps[1];
595
+ if (indexStep?.kind !== 'index') {
596
+ throw new errors_1.WorkflowDslError(workflow_1.WorkflowErrorCode.DSL_INVALID_MATRIX_OUTPUT_ACCESS, `Job '${consumerJobKey}' ${fieldPath}: 'needs.${access.upstreamJobKey}.outputs.byKey' must be followed by '[<key>]'. Use a string literal or 'matrix.<binding>.${upstreamKeyBy}'.`, {
597
+ consumerJobKey,
598
+ upstreamJobKey: access.upstreamJobKey,
599
+ fieldPath,
600
+ });
601
+ }
602
+ assertByKeyIndexShape(indexStep.node, upstreamKeyBy, consumerJobKey, consumerBinding, access.upstreamJobKey, fieldPath);
603
+ }
604
+ function assertByKeyIndexShape(indexNode, upstreamKeyBy, consumerJobKey, consumerBinding, upstreamJobKey, fieldPath) {
605
+ if (indexNode.kind === expression_1.ExpressionNodeKind.LITERAL &&
606
+ typeof indexNode.value === 'string') {
607
+ return;
608
+ }
609
+ if (indexNode.kind === expression_1.ExpressionNodeKind.MEMBER ||
610
+ indexNode.kind === expression_1.ExpressionNodeKind.INDEX) {
611
+ const path = collectMatrixMemberPath(indexNode);
612
+ if (path) {
613
+ if (consumerBinding === null) {
614
+ throw new errors_1.WorkflowDslError(workflow_1.WorkflowErrorCode.DSL_INVALID_MATRIX_OUTPUT_ACCESS, `Job '${consumerJobKey}' ${fieldPath}: 'matrix.*' indices into 'needs.${upstreamJobKey}.outputs.byKey' require the consumer job to declare its own 'strategy.dynamic'. Use a string literal key instead, or convert '${consumerJobKey}' into a dynamic matrix.`, { consumerJobKey, upstreamJobKey, fieldPath });
615
+ }
616
+ if (path.binding !== consumerBinding) {
617
+ throw new errors_1.WorkflowDslError(workflow_1.WorkflowErrorCode.DSL_INVALID_MATRIX_OUTPUT_ACCESS, `Job '${consumerJobKey}' ${fieldPath}: 'matrix.${path.binding}' is not bound here — '${consumerJobKey}' binds 'matrix.${consumerBinding}'.`, { consumerJobKey, upstreamJobKey, fieldPath });
618
+ }
619
+ if (path.path !== upstreamKeyBy) {
620
+ throw new errors_1.WorkflowDslError(workflow_1.WorkflowErrorCode.DSL_INVALID_MATRIX_OUTPUT_ACCESS, `Job '${consumerJobKey}' ${fieldPath}: 'byKey' index reads 'matrix.${path.binding}.${path.path}' but '${upstreamJobKey}' is keyed by '${upstreamKeyBy}'. Match the upstream's 'keyBy:' path or change the upstream's 'keyBy:' to '${path.path}'.`, { consumerJobKey, upstreamJobKey, fieldPath });
621
+ }
622
+ return;
623
+ }
624
+ }
625
+ throw new errors_1.WorkflowDslError(workflow_1.WorkflowErrorCode.DSL_INVALID_MATRIX_OUTPUT_ACCESS, `Job '${consumerJobKey}' ${fieldPath}: 'needs.${upstreamJobKey}.outputs.byKey[…]' index must be a string literal or 'matrix.<binding>.${upstreamKeyBy}'.`, { consumerJobKey, upstreamJobKey, fieldPath });
626
+ }
627
+ function collectMatrixMemberPath(node) {
628
+ const reverseProperties = [];
629
+ let cursor = node;
630
+ while (cursor.kind === expression_1.ExpressionNodeKind.MEMBER) {
631
+ reverseProperties.push(cursor.property);
632
+ cursor = cursor.target;
633
+ }
634
+ if (cursor.kind !== expression_1.ExpressionNodeKind.IDENTIFIER ||
635
+ cursor.name !== 'matrix') {
636
+ return null;
637
+ }
638
+ const props = reverseProperties.toReversed();
639
+ if (props.length < 2)
640
+ return null;
641
+ const [binding, ...rest] = props;
642
+ return { binding: binding, path: rest.join('.') };
643
+ }
644
+ function assertStrategyInvariants(compiled) {
645
+ for (const job of compiled.jobs) {
646
+ if (job.strategy.kind === workflow_1.MatrixStrategyKind.STATIC && job.strategy.entries.length === 0) {
647
+ throw new errors_1.WorkflowDslError(workflow_1.WorkflowErrorCode.DSL_SEMANTIC_INVALID, `Job '${job.jobKey}' static strategy expansion produced zero entries.`, { jobKey: job.jobKey });
648
+ }
649
+ }
650
+ const _permissionRef = compiled.permissions;
651
+ void _permissionRef;
652
+ }
653
+ function validateDeliverableValueExpressions(doc, resolvedSpecs) {
654
+ if (Object.keys(resolvedSpecs).length === 0)
655
+ return;
656
+ for (const [jobKey, job] of Object.entries(doc.jobs)) {
657
+ const expressions = collectJobExpressions(jobKey, job);
658
+ for (const { source, fieldPath } of expressions) {
659
+ const ast = (0, expression_1.compileExpression)(source);
660
+ walkDeliverableAccesses(ast, (access) => {
661
+ validateDeliverableAccess(doc, jobKey, fieldPath, access, resolvedSpecs);
662
+ });
663
+ }
664
+ }
665
+ const callOutputs = doc.on.workflow_call?.outputs;
666
+ if (callOutputs) {
667
+ for (const [outputName, expr] of Object.entries(callOutputs)) {
668
+ const ast = (0, expression_1.compileExpression)((0, expression_1.stripInterpolation)(expr));
669
+ walkDeliverableAccesses(ast, (access) => {
670
+ validateDeliverableAccess(doc, '<workflow_call.outputs>', `on.workflow_call.outputs.${outputName}`, access, resolvedSpecs);
671
+ });
672
+ }
673
+ }
674
+ }
675
+ function walkDeliverableAccesses(node, visit) {
676
+ const valueField = matchDeliverableValueFieldAccess(node);
677
+ if (valueField !== null) {
678
+ visit(valueField);
679
+ return;
680
+ }
681
+ switch (node.kind) {
682
+ case expression_1.ExpressionNodeKind.MEMBER:
683
+ walkDeliverableAccesses(node.target, visit);
684
+ return;
685
+ case expression_1.ExpressionNodeKind.INDEX:
686
+ walkDeliverableAccesses(node.target, visit);
687
+ walkDeliverableAccesses(node.index, visit);
688
+ return;
689
+ case expression_1.ExpressionNodeKind.CALL:
690
+ for (const arg of node.args)
691
+ walkDeliverableAccesses(arg, visit);
692
+ return;
693
+ case expression_1.ExpressionNodeKind.UNARY_NOT:
694
+ walkDeliverableAccesses(node.operand, visit);
695
+ return;
696
+ case expression_1.ExpressionNodeKind.BINARY_EQ:
697
+ case expression_1.ExpressionNodeKind.BINARY_NEQ:
698
+ case expression_1.ExpressionNodeKind.BINARY_AND:
699
+ case expression_1.ExpressionNodeKind.BINARY_OR:
700
+ walkDeliverableAccesses(node.left, visit);
701
+ walkDeliverableAccesses(node.right, visit);
702
+ return;
703
+ case expression_1.ExpressionNodeKind.LITERAL:
704
+ case expression_1.ExpressionNodeKind.IDENTIFIER:
705
+ return;
706
+ }
707
+ }
708
+ function matchDeliverableValueFieldAccess(node) {
709
+ if (node.kind !== expression_1.ExpressionNodeKind.MEMBER)
710
+ return null;
711
+ const field = node.property;
712
+ const valueNode = node.target;
713
+ if (valueNode.kind !== expression_1.ExpressionNodeKind.MEMBER)
714
+ return null;
715
+ if (valueNode.property !== 'value')
716
+ return null;
717
+ const contentNode = valueNode.target;
718
+ if (contentNode.kind !== expression_1.ExpressionNodeKind.MEMBER)
719
+ return null;
720
+ if (contentNode.property !== 'content')
721
+ return null;
722
+ const deliverableNode = contentNode.target;
723
+ if (deliverableNode.kind !== expression_1.ExpressionNodeKind.MEMBER)
724
+ return null;
725
+ if (deliverableNode.property !== 'deliverable')
726
+ return null;
727
+ const outputsNode = deliverableNode.target;
728
+ if (outputsNode.kind !== expression_1.ExpressionNodeKind.MEMBER)
729
+ return null;
730
+ if (outputsNode.property !== 'outputs')
731
+ return null;
732
+ const rootNode = outputsNode.target;
733
+ if (rootNode.kind === expression_1.ExpressionNodeKind.IDENTIFIER &&
734
+ rootNode.name === 'job') {
735
+ return { upstreamJobKey: null, field };
736
+ }
737
+ if (rootNode.kind === expression_1.ExpressionNodeKind.MEMBER) {
738
+ const needsRoot = rootNode.target;
739
+ if (needsRoot.kind === expression_1.ExpressionNodeKind.IDENTIFIER &&
740
+ needsRoot.name === 'needs') {
741
+ return {
742
+ upstreamJobKey: rootNode.property,
743
+ field,
744
+ };
745
+ }
746
+ if (needsRoot.kind === expression_1.ExpressionNodeKind.MEMBER) {
747
+ const upstreamRoot = needsRoot.target;
748
+ if (needsRoot.property === 'outputs' &&
749
+ upstreamRoot.kind === expression_1.ExpressionNodeKind.MEMBER) {
750
+ const needsParent = upstreamRoot.target;
751
+ if (upstreamRoot.property === 'byKey' &&
752
+ needsParent.kind === expression_1.ExpressionNodeKind.IDENTIFIER &&
753
+ needsParent.name === 'needs') {
754
+ return null;
755
+ }
756
+ }
757
+ }
758
+ }
759
+ return null;
760
+ }
761
+ function validateDeliverableAccess(doc, consumerJobKey, fieldPath, access, resolvedSpecs) {
762
+ const producingJobKey = access.upstreamJobKey ?? consumerJobKey;
763
+ const producingJob = doc.jobs[producingJobKey];
764
+ if (!producingJob)
765
+ return;
766
+ if (access.upstreamJobKey !== null) {
767
+ if (producingJob.outputs && Object.keys(producingJob.outputs).length > 0) {
768
+ return;
769
+ }
770
+ }
771
+ const withMap = producingJob.with;
772
+ const specRef = withMap?.['deliverableSpecRef'];
773
+ if (typeof specRef !== 'string' || specRef.length === 0)
774
+ return;
775
+ if (specRef.includes('${{'))
776
+ return;
777
+ const spec = resolvedSpecs[specRef];
778
+ if (!spec)
779
+ return;
780
+ if (!spec.topLevelKeys || spec.topLevelKeys.length === 0)
781
+ return;
782
+ if (spec.topLevelKeys.includes(access.field))
783
+ return;
784
+ const knownPreview = formatKnownPreview(spec.topLevelKeys);
785
+ throw new errors_1.WorkflowDslError(workflow_1.WorkflowErrorCode.DSL_UNKNOWN_DELIVERABLE_FIELD, `${fieldPath}: deliverable.content.value.${access.field} is not a top-level field on deliverable spec '${spec.ref}' (produced by job '${producingJobKey}'). Known fields: [${knownPreview}].`, {
786
+ consumerJobKey,
787
+ fieldPath,
788
+ producingJobKey,
789
+ specRef: spec.ref,
790
+ field: access.field,
791
+ knownFields: [...spec.topLevelKeys],
792
+ });
793
+ }
794
+ //# sourceMappingURL=compile.js.map