@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,361 @@
1
+ import type { ConcurrencyMode, PermissionScope } from '@xemahq/kernel-contracts/workflow';
2
+
3
+ /**
4
+ * Authored-shape TypeScript types for a Xema workflow document. These match
5
+ * the JSON Schema at schema/workflow.schema.json — validation is the source
6
+ * of truth, these types are ergonomics for callers that have already
7
+ * validated the input.
8
+ *
9
+ * Do NOT trust unvalidated user input typed as `WorkflowDocument` — always
10
+ * pass through `validateWorkflowDocument(raw)` first, which produces a
11
+ * narrowed value safely typed as this interface.
12
+ */
13
+ export interface WorkflowDocument {
14
+ readonly apiVersion: 'xema.dev/workflow/v1alpha1';
15
+ readonly kind: 'Workflow';
16
+ readonly metadata: WorkflowMetadata;
17
+ readonly on: WorkflowTriggerDeclarations;
18
+ readonly concurrency?: WorkflowConcurrencyDeclaration;
19
+ readonly defaults?: WorkflowDefaults;
20
+ readonly permissions?: WorkflowPermissions;
21
+ readonly vars?: Readonly<Record<string, unknown>>;
22
+ /**
23
+ * Wallets (variable + secret bundles) the workflow needs at dispatch
24
+ * time. A wallet is a named group of project / org variables managed
25
+ * through `project-registry-api`. The engine resolves each declared
26
+ * wallet to its contents before starting the run; missing wallets or
27
+ * missing keys referenced by `${{ vars.X }}` / `${{ secrets.X }}`
28
+ * surface as
29
+ * `WorkflowErrorCode.WORKFLOW_WALLET_NOT_FOUND` /
30
+ * `WorkflowErrorCode.WORKFLOW_VARIABLES_MISSING` respectively, and
31
+ * the run is never started.
32
+ *
33
+ * Dispatch callers may pass additional wallet names on top of this
34
+ * list — additive only.
35
+ */
36
+ readonly requires?: WorkflowRequiresDeclaration;
37
+ readonly jobs: Readonly<Record<string, WorkflowJobDeclaration>>;
38
+ /**
39
+ * Workflow-level named outputs. Each entry references a single
40
+ * `(job, outputName)` pair and declares the kind of value it
41
+ * surfaces — deliverable artifact (the most common), structured
42
+ * JSON value, or plain text.
43
+ *
44
+ * Consumers:
45
+ * - Biome `mcpWorkflowTools[].outputProjection.slug` (cross-
46
+ * referenced at biome boot — the slug MUST match a key here).
47
+ * - Future `workflow_call` reusable composition (consumes outputs
48
+ * declared by the called workflow).
49
+ * - Run-detail projections (`RunResponseDto.deliverables`) — built
50
+ * by walking this map against the producing JobRun outputs.
51
+ *
52
+ * Validation at compile time:
53
+ * - `fromJob` MUST exist in `jobs`.
54
+ * - `fromOutput` MUST appear in that job's `outputs:` map.
55
+ * - For `kind: 'deliverable'`, `deliverableSpecRef` MUST resolve
56
+ * through the spec prefetch path.
57
+ */
58
+ readonly outputs?: Readonly<Record<string, WorkflowOutputDeclaration>>;
59
+ }
60
+
61
+ /**
62
+ * Per-output declaration shape. Discriminated by `kind`. Lives at the
63
+ * workflow document level (`workflow.outputs.<name>`), NOT on a job.
64
+ * Job-level `outputs:` remain the per-step expressions feeding into
65
+ * workflow outputs via `fromJob` / `fromOutput`.
66
+ */
67
+ export type WorkflowOutputDeclaration =
68
+ | WorkflowDeliverableOutputDeclaration
69
+ | WorkflowStructuredOutputDeclaration
70
+ | WorkflowTextOutputDeclaration;
71
+
72
+ interface WorkflowOutputDeclarationBase {
73
+ readonly slug: string;
74
+ readonly fromJob: string;
75
+ readonly fromOutput: string;
76
+ readonly description?: string;
77
+ }
78
+
79
+ export interface WorkflowDeliverableOutputDeclaration
80
+ extends WorkflowOutputDeclarationBase {
81
+ readonly kind: 'deliverable';
82
+ /** Reference to a published `DeliverableSpec` (slug or slug@version). */
83
+ readonly deliverableSpecRef: string;
84
+ }
85
+
86
+ export interface WorkflowStructuredOutputDeclaration
87
+ extends WorkflowOutputDeclarationBase {
88
+ readonly kind: 'structured';
89
+ /** Optional JSON Schema ref the platform validates the value against. */
90
+ readonly schemaRef?: string;
91
+ }
92
+
93
+ export interface WorkflowTextOutputDeclaration extends WorkflowOutputDeclarationBase {
94
+ readonly kind: 'text';
95
+ }
96
+
97
+ export interface WorkflowRequiresDeclaration {
98
+ /** Wallet names; must match `^[a-z][a-z0-9-]{0,62}$`. */
99
+ readonly wallets?: readonly string[];
100
+ /**
101
+ * Integration adapter kinds the workflow consumes. Biome-shipped
102
+ * workflows declare these so `biome-host-api` can cross-validate
103
+ * them against the biome's manifest `integrationRequirements` at
104
+ * boot. Stand-alone workflows (not biome-owned) may also declare
105
+ * them as documentation; dispatch-time enforcement only kicks in
106
+ * for biome-gated runs.
107
+ */
108
+ readonly integrations?: readonly WorkflowIntegrationRequirement[];
109
+ }
110
+
111
+ export interface WorkflowIntegrationRequirement {
112
+ /** Adapter kind slug (e.g. `scm`, `tracker`, `documentation`). */
113
+ readonly adapterKind: string;
114
+ /** Capability slugs the workflow exercises against the adapter. */
115
+ readonly capabilities: readonly string[];
116
+ /** Whether the workflow can degrade if the integration is unbound. */
117
+ readonly optional?: boolean;
118
+ }
119
+
120
+ export interface WorkflowMetadata {
121
+ readonly name: string;
122
+ readonly version: string;
123
+ readonly title?: string;
124
+ readonly description?: string;
125
+ readonly category?: string;
126
+ readonly tags?: readonly string[];
127
+ }
128
+
129
+ export interface WorkflowTriggerDeclarations {
130
+ readonly workflow_dispatch?: WorkflowDispatchDeclaration;
131
+ readonly schedule?: readonly ScheduleDeclaration[];
132
+ readonly webhook?: readonly WebhookDeclaration[];
133
+ readonly workflow_call?: WorkflowCallDeclaration;
134
+ }
135
+
136
+ export interface WorkflowDispatchDeclaration {
137
+ readonly inputs?: Readonly<Record<string, WorkflowInputDeclaration>>;
138
+ }
139
+
140
+ export interface ScheduleDeclaration {
141
+ readonly cron: string;
142
+ readonly timezone?: string;
143
+ readonly inputs?: Readonly<Record<string, unknown>>;
144
+ }
145
+
146
+ export interface WebhookDeclaration {
147
+ readonly event: string;
148
+ readonly secretRef?: string;
149
+ readonly filters?: Readonly<Record<string, string>>;
150
+ }
151
+
152
+ export interface WorkflowCallDeclaration {
153
+ readonly inputs?: Readonly<Record<string, WorkflowInputDeclaration>>;
154
+ readonly outputs?: Readonly<Record<string, string>>;
155
+ }
156
+
157
+ export interface WorkflowInputDeclaration {
158
+ readonly type: 'string' | 'number' | 'integer' | 'boolean' | 'object' | 'array';
159
+ readonly required?: boolean;
160
+ readonly default?: unknown;
161
+ readonly description?: string;
162
+ readonly enum?: readonly unknown[];
163
+ readonly items?: Readonly<Record<string, unknown>>;
164
+ }
165
+
166
+ export interface WorkflowConcurrencyDeclaration {
167
+ readonly group: string;
168
+ readonly mode: ConcurrencyMode;
169
+ }
170
+
171
+ export interface WorkflowDefaults {
172
+ readonly retry?: WorkflowRetryDeclaration;
173
+ readonly timeout?: string;
174
+ }
175
+
176
+ export interface WorkflowRetryDeclaration {
177
+ readonly maxAttempts?: number;
178
+ readonly initialInterval?: string;
179
+ readonly backoffCoefficient?: number;
180
+ readonly maximumInterval?: string;
181
+ readonly nonRetryableErrorTypes?: readonly string[];
182
+ }
183
+
184
+ export type WorkflowPermissions = Partial<Record<'repos' | 'kb' | 'backlog' | 'integrations' | 'artifacts' | 'memory', PermissionScope>>;
185
+
186
+ export interface WorkflowJobDeclaration {
187
+ readonly title?: string;
188
+ readonly needs?: readonly string[];
189
+ readonly if?: string;
190
+ readonly strategy?: WorkflowStrategyDeclaration;
191
+ readonly matrixGather?: readonly string[];
192
+ readonly uses: string;
193
+ readonly with?: Readonly<Record<string, unknown>>;
194
+ readonly outputs?: Readonly<Record<string, string>>;
195
+ readonly retry?: WorkflowRetryDeclaration;
196
+ readonly timeout?: string;
197
+ readonly permissions?: WorkflowPermissions;
198
+ }
199
+
200
+ export type WorkflowStrategyDeclaration =
201
+ | { readonly matrix: Readonly<Record<string, readonly unknown[]>>; readonly maxParallel?: number }
202
+ | { readonly dynamic: WorkflowDynamicStrategyDeclaration; readonly maxParallel?: number };
203
+
204
+ export interface WorkflowDynamicStrategyDeclaration {
205
+ readonly from: string;
206
+ readonly as: string;
207
+ readonly maxEntries?: number;
208
+ /**
209
+ * Optional dotted path on each bound entry whose value becomes the
210
+ * entry's key in `needs.<thisJob>.outputs.byKey`. Enables per-CU
211
+ * downstream consumers to write
212
+ * `needs.X.outputs.byKey[matrix.<binding>.<keyBy>].field`. Validated
213
+ * lexically by the schema; resolved against actual entries at
214
+ * dispatch time.
215
+ */
216
+ readonly keyBy?: string;
217
+ }
218
+
219
+ // ── Action manifest ─────────────────────────────────────────────────────
220
+
221
+ export interface ActionManifest {
222
+ readonly apiVersion: 'xema.dev/workflow/v1alpha1';
223
+ readonly kind: 'Action';
224
+ readonly metadata: ActionManifestMetadata;
225
+ readonly spec: ActionManifestSpec;
226
+ }
227
+
228
+ export interface ActionManifestMetadata {
229
+ readonly id: string;
230
+ readonly version: string;
231
+ readonly title?: string;
232
+ readonly description?: string;
233
+ }
234
+
235
+ export interface ActionManifestSpec {
236
+ readonly executionKind: 'activity' | 'child_workflow';
237
+ readonly taskQueue: 'xema_default' | 'xema_agent' | 'xema_human';
238
+ /**
239
+ * Semantic category — drives consumer presentation (FE canvas
240
+ * shape, badge icon). Optional; omitted manifests fall back to
241
+ * `generic`. Closed values mirror `ActionKind` in
242
+ * `@xemahq/kernel-contracts/workflow`; consumers MUST treat unknown
243
+ * strings as `generic` so newer manifests stay safe with older
244
+ * clients.
245
+ */
246
+ readonly actionKind?:
247
+ | 'agent'
248
+ | 'review'
249
+ | 'wait'
250
+ | 'timer'
251
+ | 'aggregate'
252
+ | 'dispatch'
253
+ | 'branch'
254
+ | 'loop'
255
+ | 'publish'
256
+ | 'notify'
257
+ | 'inquiry'
258
+ | 'fetch'
259
+ | 'transform'
260
+ | 'validate'
261
+ | 'terminate'
262
+ | 'generic';
263
+ readonly inputs: Readonly<Record<string, unknown>>;
264
+ readonly outputs: Readonly<Record<string, unknown>>;
265
+ /**
266
+ * Per-output deliverable-spec bindings (plan §B per-output bindings).
267
+ * Each entry pins a named output to a deliverable-spec ref like
268
+ * `agent-summary@1.0.0`. The DSL compiler consults this first when
269
+ * resolving typed payload reach-in (`outputs.<name>.<field>`); it
270
+ * falls back to the job-level `with.deliverableSpecRef` only when no
271
+ * per-output binding is declared, preserving the current single-spec
272
+ * agent flow.
273
+ *
274
+ * Optional. Activities with no fixed per-output spec (e.g. the agent
275
+ * activity, whose deliverables spec is workflow-author-chosen) omit
276
+ * this. The compiler always proves at least one of (per-output spec,
277
+ * job-level spec) is set before letting a reach-in compile.
278
+ */
279
+ readonly outputBindings?: Readonly<Record<string, ActionOutputBinding>>;
280
+ readonly permissions?: WorkflowPermissions;
281
+ readonly allowedMounts?: readonly string[];
282
+ readonly retryDefaults: ActionManifestRetryDefaults;
283
+ readonly timeoutDefaults: ActionManifestTimeoutDefaults;
284
+ readonly auditEventMapping?: Partial<{ started: string; succeeded: string; failed: string }>;
285
+ /**
286
+ * Declarative contracts the action opts into. The DSL compiler reads
287
+ * this list to decide which validation lanes apply — e.g. the
288
+ * `workspace-manifest@v1` entry enables the manifest-source pair
289
+ * (`compositionRef` XOR inline short-form `mounts`) and the frontend
290
+ * canvas Inspector renders the manifest picker. Closed-set
291
+ * `kind`/`version` pair so biome-shipped agent actions inherit the
292
+ * same lanes without per-action-id branching.
293
+ *
294
+ * Today the only kind is `workspace-manifest`. New kinds extend the
295
+ * closed enum (deliverable-spec, knowledge-base-binding, …) with a
296
+ * single PR that fans out across the compiler, canvas, and runtime.
297
+ */
298
+ readonly consumes?: readonly ActionContract[];
299
+ }
300
+
301
+ /**
302
+ * Per-output binding declaration on an action manifest. Today the only
303
+ * binding field is `deliverableSpecRef`; future bindings (e.g. KB-page
304
+ * slug, custom contracts) extend the type.
305
+ */
306
+ export interface ActionOutputBinding {
307
+ /**
308
+ * Deliverable spec ref governing this output's payload shape, in the
309
+ * canonical `<slug>@<version>` form (e.g. `metrics-snapshot@1.0.0`).
310
+ */
311
+ readonly deliverableSpecRef?: string;
312
+ }
313
+
314
+ /**
315
+ * Versioned consume-contract declaration on an action manifest.
316
+ *
317
+ * `workspace-manifest@v1` — enables the workspace-manifest triplet on
318
+ * `with:` (long-form ref, inline-anonymous envelope, or short-form
319
+ * mounts). Optional fields:
320
+ * - `surfaces`: restricts the surfaces the action can be invoked on
321
+ * (must intersect the manifest's `metadata.surfaceCompat`).
322
+ * - `roleHint`: pins the manifest's `spec.agent.role` to a closed
323
+ * `AgentRunRole`. Compile-time fail when a workflow points the
324
+ * action at a manifest whose role doesn't match.
325
+ *
326
+ * `agent-composition@v1` — enables the `with.composition` field: a
327
+ * `slug@version` reference to an Agent Composition (llm-registry-api
328
+ * composition registry). The composition is the source of truth for the
329
+ * step's agent + sub-agents + skill/tool selection. Resolved at dispatch
330
+ * time by the runtime via the composition resolution endpoint. Optional
331
+ * and additive — existing workflows that point an agent step at a
332
+ * workspace manifest are unaffected.
333
+ */
334
+ export type ActionContract =
335
+ | WorkspaceManifestActionContract
336
+ | AgentCompositionActionContract;
337
+
338
+ export interface WorkspaceManifestActionContract {
339
+ readonly kind: 'workspace-manifest';
340
+ readonly version: 'v1';
341
+ readonly surfaces?: readonly ('workflow' | 'agent-session')[];
342
+ readonly roleHint?: string;
343
+ }
344
+
345
+ export interface AgentCompositionActionContract {
346
+ readonly kind: 'agent-composition';
347
+ readonly version: 'v1';
348
+ }
349
+
350
+ export interface ActionManifestRetryDefaults {
351
+ readonly maxAttempts: number;
352
+ readonly initialInterval: string;
353
+ readonly backoffCoefficient: number;
354
+ readonly maximumInterval: string;
355
+ readonly nonRetryableErrorTypes?: readonly string[];
356
+ }
357
+
358
+ export interface ActionManifestTimeoutDefaults {
359
+ readonly startToClose: string;
360
+ readonly heartbeat?: string;
361
+ }
@@ -0,0 +1,199 @@
1
+ import Ajv2020, { type ErrorObject, type ValidateFunction } from 'ajv/dist/2020';
2
+ import addFormats from 'ajv-formats';
3
+ import { load as parseYaml } from 'js-yaml';
4
+ import { WorkflowErrorCode } from '@xemahq/kernel-contracts/workflow';
5
+ import { WorkflowDslError } from './errors';
6
+ import {
7
+ ACTION_SCHEMA,
8
+ REUSABLE_WORKFLOW_SCHEMA,
9
+ WORKFLOW_SCHEMA,
10
+ } from './schemas-loader';
11
+ import type { ActionManifest, WorkflowDocument } from './types';
12
+
13
+ /**
14
+ * Ajv is constructed exactly once per process (module scope). `strict:true`
15
+ * keeps us honest — we catch schema authoring bugs at module-load time
16
+ * instead of silently coercing them at runtime.
17
+ *
18
+ * Per-request validation is a hot path; re-compiling schemas would burn CPU
19
+ * for no correctness gain. Rule 7 (horizontal scalability): this validator
20
+ * is stateless and safe to share across concurrent requests in a NestJS
21
+ * process.
22
+ *
23
+ * `strictRequired` is explicitly disabled: it conflicts with the standard
24
+ * JSON-Schema-2020-12 `oneOf` discrimination idiom (`oneOf: [{required:[a]},
25
+ * {required:[b]}]`) where the referenced properties are declared in the
26
+ * parent subschema's `properties`. The remaining strict flags
27
+ * (`strictSchema`, `strictTypes`, `strictTuples`) plus
28
+ * `additionalProperties:false` in every object schema already catch the
29
+ * typos `strictRequired` would catch, so the safety tradeoff is zero.
30
+ */
31
+ const ajv = new Ajv2020({
32
+ strict: true,
33
+ strictSchema: true,
34
+ strictTypes: true,
35
+ strictRequired: false,
36
+ strictTuples: true,
37
+ allErrors: true,
38
+ allowUnionTypes: false,
39
+ useDefaults: false,
40
+ validateFormats: true,
41
+ });
42
+ addFormats(ajv);
43
+
44
+ // Register referenced schemas so `$ref` across files resolves. Order
45
+ // matters: reusable-workflow references workflow.schema.json by $id.
46
+ ajv.addSchema(WORKFLOW_SCHEMA);
47
+ ajv.addSchema(REUSABLE_WORKFLOW_SCHEMA);
48
+ ajv.addSchema(ACTION_SCHEMA);
49
+
50
+ const validateWorkflow = compile<WorkflowDocument>(
51
+ 'https://xema.dev/schemas/workflow/v1alpha1/Workflow.json',
52
+ );
53
+ const validateReusableWorkflow = compile<WorkflowDocument>(
54
+ 'https://xema.dev/schemas/workflow/v1alpha1/ReusableWorkflow.json',
55
+ );
56
+ const validateAction = compile<ActionManifest>(
57
+ 'https://xema.dev/schemas/workflow/v1alpha1/Action.json',
58
+ );
59
+
60
+ function compile<T>(schemaId: string): ValidateFunction<T> {
61
+ const fn = ajv.getSchema<T>(schemaId);
62
+ if (!fn) {
63
+ throw new WorkflowDslError(
64
+ WorkflowErrorCode.COMPILE_INTERNAL,
65
+ `Ajv failed to compile schema ${schemaId}. Schema registration order is wrong.`,
66
+ { schemaId },
67
+ );
68
+ }
69
+ return fn;
70
+ }
71
+
72
+ /**
73
+ * Parse a YAML workflow document and validate it against the workflow
74
+ * schema. Returns the narrowed document on success; throws
75
+ * {@link WorkflowDslError} with code DSL_SCHEMA_INVALID on any validation
76
+ * failure (never silent pass-through, never partial validation).
77
+ */
78
+ export function parseAndValidateWorkflowYaml(yaml: string): WorkflowDocument {
79
+ return parseAndValidate(yaml, validateWorkflow, 'workflow');
80
+ }
81
+
82
+ /**
83
+ * Parse a YAML reusable-workflow document and validate it against the
84
+ * reusable-workflow schema.
85
+ */
86
+ export function parseAndValidateReusableWorkflowYaml(yaml: string): WorkflowDocument {
87
+ return parseAndValidate(yaml, validateReusableWorkflow, 'reusable-workflow');
88
+ }
89
+
90
+ /** Parse a YAML action manifest and validate it against the action schema. */
91
+ export function parseAndValidateActionYaml(yaml: string): ActionManifest {
92
+ return parseAndValidate(yaml, validateAction, 'action');
93
+ }
94
+
95
+ /**
96
+ * Validate an already-parsed document object. Useful for programmatic
97
+ * construction (e.g. tests) and for the engine seeding path that reads
98
+ * JSON directly from the DB.
99
+ */
100
+ export function validateWorkflowDocument(doc: unknown): WorkflowDocument {
101
+ if (doc !== null && typeof doc === 'object' && !Array.isArray(doc)) {
102
+ normalizeJobNeedsShorthand(doc);
103
+ }
104
+ return runValidator(doc, validateWorkflow, 'workflow');
105
+ }
106
+
107
+ export function validateReusableWorkflowDocument(doc: unknown): WorkflowDocument {
108
+ if (doc !== null && typeof doc === 'object' && !Array.isArray(doc)) {
109
+ normalizeJobNeedsShorthand(doc);
110
+ }
111
+ return runValidator(doc, validateReusableWorkflow, 'reusable-workflow');
112
+ }
113
+
114
+ export function validateActionManifest(doc: unknown): ActionManifest {
115
+ return runValidator(doc, validateAction, 'action');
116
+ }
117
+
118
+ function parseAndValidate<T>(
119
+ yaml: string,
120
+ validator: ValidateFunction<T>,
121
+ kind: 'workflow' | 'reusable-workflow' | 'action',
122
+ ): T {
123
+ let parsed: unknown;
124
+ try {
125
+ parsed = parseYaml(yaml, { schema: undefined, json: false });
126
+ } catch (err) {
127
+ throw new WorkflowDslError(
128
+ WorkflowErrorCode.DSL_SCHEMA_INVALID,
129
+ `YAML parse failure in ${kind} document: ${(err as Error).message}`,
130
+ { kind },
131
+ );
132
+ }
133
+ if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {
134
+ throw new WorkflowDslError(
135
+ WorkflowErrorCode.DSL_SCHEMA_INVALID,
136
+ `Top-level YAML value in ${kind} document must be a mapping.`,
137
+ { kind },
138
+ );
139
+ }
140
+ // Plan §G shorthand: `needs: <string>` → `[<string>]`. Normalize
141
+ // BEFORE validation so the schema stays strict (one canonical shape)
142
+ // and the rest of the compiler never branches on shorthand. Workflow +
143
+ // reusable-workflow documents both have `jobs: { <key>: { needs?... } }`;
144
+ // action manifests have no `needs`, so this is a no-op there.
145
+ if (kind !== 'action') {
146
+ normalizeJobNeedsShorthand(parsed);
147
+ }
148
+ return runValidator(parsed, validator, kind);
149
+ }
150
+
151
+ /**
152
+ * Mutates `doc.jobs.<key>.needs` from `<string>` to `[<string>]` in
153
+ * place. Authors can write either form; the canonical form is the
154
+ * array. Documented in plan §G under "Simplified DSL".
155
+ */
156
+ function normalizeJobNeedsShorthand(doc: object): void {
157
+ const jobs = (doc as { jobs?: unknown }).jobs;
158
+ if (!jobs || typeof jobs !== 'object' || Array.isArray(jobs)) return;
159
+ for (const job of Object.values(jobs as Record<string, unknown>)) {
160
+ if (!job || typeof job !== 'object' || Array.isArray(job)) continue;
161
+ const rec = job as Record<string, unknown>;
162
+ if (typeof rec.needs === 'string') {
163
+ rec.needs = [rec.needs];
164
+ }
165
+ }
166
+ }
167
+
168
+ function runValidator<T>(
169
+ doc: unknown,
170
+ validator: ValidateFunction<T>,
171
+ kind: 'workflow' | 'reusable-workflow' | 'action',
172
+ ): T {
173
+ if (validator(doc)) {
174
+ return doc;
175
+ }
176
+ const errors = validator.errors ?? [];
177
+ throw new WorkflowDslError(
178
+ WorkflowErrorCode.DSL_SCHEMA_INVALID,
179
+ `Schema validation failed for ${kind} document: ${formatErrors(errors)}`,
180
+ { kind, issues: errors.map(formatIssue) },
181
+ );
182
+ }
183
+
184
+ function formatIssue(err: ErrorObject): Readonly<Record<string, unknown>> {
185
+ return {
186
+ instancePath: err.instancePath,
187
+ schemaPath: err.schemaPath,
188
+ keyword: err.keyword,
189
+ message: err.message ?? '',
190
+ params: err.params,
191
+ };
192
+ }
193
+
194
+ function formatErrors(errors: readonly ErrorObject[]): string {
195
+ if (errors.length === 0) return '(no detail)';
196
+ return errors
197
+ .map((e) => `${e.instancePath || '/'} ${e.message ?? ''} [${e.keyword}]`.trim())
198
+ .join('; ');
199
+ }
@@ -0,0 +1,27 @@
1
+ // ═══════════════════════════════════════════════════════════════════════════
2
+ // ── @xemahq/workspace-manifest-dsl ──
3
+ //
4
+ // Schema, compiler, and interpolation engine for `WorkspaceManifest`
5
+ // YAMLs. A manifest declares the SHAPE of `/workspace/` for an agent
6
+ // invocation — which user-data slots are populated, which agent runs,
7
+ // which seed files are dropped in.
8
+ //
9
+ // Consumers:
10
+ // - `biomes/agent-runtime/api/llm-registry-api` (composition seeder): compiles each
11
+ // biome-shipped manifest and projects it into a published
12
+ // `Composition` row.
13
+ // - `packages/agent-session-runtime` (composer): turns a compiled
14
+ // manifest + bind inputs into a `WorkspaceMountPlan` that gets
15
+ // applied via workspace-proxy `/workspace/mounts/apply`.
16
+ // - `packages/workflow-dsl`: validates inline `mounts:` blocks on
17
+ // `xema/agent` jobs at workflow compile time.
18
+ //
19
+ // Sibling to `@xemahq/workflow-dsl`. Workflow DSL describes the
20
+ // process; workspace manifest describes the environment shape.
21
+ // ═══════════════════════════════════════════════════════════════════════════
22
+
23
+ export * from './lib/types';
24
+ export * from './lib/schema';
25
+ export * from './lib/interpolate';
26
+ export * from './lib/compile';
27
+ export * from './lib/resolve-extends';