@shipfox/api-workflows 5.0.0 → 6.0.0

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 (277) hide show
  1. package/.turbo/turbo-build.log +4 -4
  2. package/CHANGELOG.md +72 -0
  3. package/dist/core/agent-defaults.d.ts +17 -0
  4. package/dist/core/agent-defaults.d.ts.map +1 -0
  5. package/dist/core/agent-defaults.js +21 -0
  6. package/dist/core/agent-defaults.js.map +1 -0
  7. package/dist/core/agent-tool-capability-warning.d.ts +4 -0
  8. package/dist/core/agent-tool-capability-warning.d.ts.map +1 -1
  9. package/dist/core/agent-tool-capability-warning.js +15 -17
  10. package/dist/core/agent-tool-capability-warning.js.map +1 -1
  11. package/dist/core/agent-tools.d.ts +11 -9
  12. package/dist/core/agent-tools.d.ts.map +1 -1
  13. package/dist/core/agent-tools.js +23 -18
  14. package/dist/core/agent-tools.js.map +1 -1
  15. package/dist/core/checkout.d.ts +21 -7
  16. package/dist/core/checkout.d.ts.map +1 -1
  17. package/dist/core/checkout.js +23 -11
  18. package/dist/core/checkout.js.map +1 -1
  19. package/dist/core/entities/workflow-run-attempt.d.ts +1 -1
  20. package/dist/core/entities/workflow-run-attempt.d.ts.map +1 -1
  21. package/dist/core/entities/workflow-run-attempt.js.map +1 -1
  22. package/dist/core/job-execution.d.ts +3 -1
  23. package/dist/core/job-execution.d.ts.map +1 -1
  24. package/dist/core/job-execution.js +14 -12
  25. package/dist/core/job-execution.js.map +1 -1
  26. package/dist/core/job-transition/derive-job-execution-outputs.d.ts +1 -1
  27. package/dist/core/job-transition/derive-job-execution-outputs.d.ts.map +1 -1
  28. package/dist/core/job-transition/derive-job-execution-outputs.js.map +1 -1
  29. package/dist/core/job-transition/derive-job-success.js +1 -1
  30. package/dist/core/job-transition/derive-job-success.js.map +1 -1
  31. package/dist/core/listener-execution-materialization.d.ts +3 -3
  32. package/dist/core/listener-execution-materialization.d.ts.map +1 -1
  33. package/dist/core/listener-execution-materialization.js +3 -4
  34. package/dist/core/listener-execution-materialization.js.map +1 -1
  35. package/dist/core/run-workflow.d.ts +12 -1
  36. package/dist/core/run-workflow.d.ts.map +1 -1
  37. package/dist/core/run-workflow.js +13 -8
  38. package/dist/core/run-workflow.js.map +1 -1
  39. package/dist/core/step-config/agent.d.ts +8 -8
  40. package/dist/core/step-config/agent.d.ts.map +1 -1
  41. package/dist/core/step-config/agent.js +12 -10
  42. package/dist/core/step-config/agent.js.map +1 -1
  43. package/dist/core/step-config/complete-step-dispatch-config.d.ts +4 -4
  44. package/dist/core/step-config/complete-step-dispatch-config.d.ts.map +1 -1
  45. package/dist/core/step-config/complete-step-dispatch-config.js +2 -2
  46. package/dist/core/step-config/complete-step-dispatch-config.js.map +1 -1
  47. package/dist/core/step-config/materialize-job-execution-steps.d.ts +3 -3
  48. package/dist/core/step-config/materialize-job-execution-steps.d.ts.map +1 -1
  49. package/dist/core/step-config/materialize-job-execution-steps.js +5 -6
  50. package/dist/core/step-config/materialize-job-execution-steps.js.map +1 -1
  51. package/dist/core/step-config/materialize-workflow-model.d.ts +3 -3
  52. package/dist/core/step-config/materialize-workflow-model.d.ts.map +1 -1
  53. package/dist/core/step-config/materialize-workflow-model.js +4 -4
  54. package/dist/core/step-config/materialize-workflow-model.js.map +1 -1
  55. package/dist/core/step-config/resolve-job-execution-name.d.ts +1 -1
  56. package/dist/core/step-config/resolve-job-execution-name.d.ts.map +1 -1
  57. package/dist/core/step-config/resolve-job-execution-name.js.map +1 -1
  58. package/dist/core/step-config/resolve-step-config.d.ts +4 -4
  59. package/dist/core/step-config/resolve-step-config.d.ts.map +1 -1
  60. package/dist/core/step-config/resolve-step-config.js +6 -6
  61. package/dist/core/step-config/resolve-step-config.js.map +1 -1
  62. package/dist/core/step-config/run.d.ts +1 -1
  63. package/dist/core/step-config/run.d.ts.map +1 -1
  64. package/dist/core/step-config/run.js.map +1 -1
  65. package/dist/core/workflow-run-creation.d.ts +3 -3
  66. package/dist/core/workflow-run-creation.d.ts.map +1 -1
  67. package/dist/core/workflow-run-creation.js +3 -4
  68. package/dist/core/workflow-run-creation.js.map +1 -1
  69. package/dist/db/db.d.ts +16 -4
  70. package/dist/db/db.d.ts.map +1 -1
  71. package/dist/db/job-listeners.d.ts +7 -1
  72. package/dist/db/job-listeners.d.ts.map +1 -1
  73. package/dist/db/job-listeners.js +10 -5
  74. package/dist/db/job-listeners.js.map +1 -1
  75. package/dist/db/runner-lease-table.d.ts +5 -5
  76. package/dist/db/runner-lease-table.d.ts.map +1 -1
  77. package/dist/db/runner-lease-table.js +3 -2
  78. package/dist/db/runner-lease-table.js.map +1 -1
  79. package/dist/db/schema/workflow-run-attempts.d.ts +9 -3
  80. package/dist/db/schema/workflow-run-attempts.d.ts.map +1 -1
  81. package/dist/db/schema/workflow-run-attempts.js +2 -1
  82. package/dist/db/schema/workflow-run-attempts.js.map +1 -1
  83. package/dist/db/schema/workflow-runs.js +1 -1
  84. package/dist/db/schema/workflow-runs.js.map +1 -1
  85. package/dist/db/workflow-runs/job-executions.d.ts +5 -0
  86. package/dist/db/workflow-runs/job-executions.d.ts.map +1 -1
  87. package/dist/db/workflow-runs/job-executions.js +14 -7
  88. package/dist/db/workflow-runs/job-executions.js.map +1 -1
  89. package/dist/db/workflow-runs/jobs.d.ts.map +1 -1
  90. package/dist/db/workflow-runs/jobs.js +3 -1
  91. package/dist/db/workflow-runs/jobs.js.map +1 -1
  92. package/dist/db/workflow-runs/run-create.d.ts +9 -2
  93. package/dist/db/workflow-runs/run-create.d.ts.map +1 -1
  94. package/dist/db/workflow-runs/run-create.js +12 -9
  95. package/dist/db/workflow-runs/run-create.js.map +1 -1
  96. package/dist/db/workflow-runs/run-rerun.d.ts.map +1 -1
  97. package/dist/db/workflow-runs/run-rerun.js +3 -1
  98. package/dist/db/workflow-runs/run-rerun.js.map +1 -1
  99. package/dist/index.d.ts +18 -4
  100. package/dist/index.d.ts.map +1 -1
  101. package/dist/index.js +61 -37
  102. package/dist/index.js.map +1 -1
  103. package/dist/presentation/dto/checkout-token.d.ts +14 -1
  104. package/dist/presentation/dto/checkout-token.d.ts.map +1 -1
  105. package/dist/presentation/dto/checkout-token.js.map +1 -1
  106. package/dist/presentation/index.d.ts +1 -1
  107. package/dist/presentation/index.d.ts.map +1 -1
  108. package/dist/presentation/index.js +1 -1
  109. package/dist/presentation/index.js.map +1 -1
  110. package/dist/presentation/inter-module.d.ts +18 -0
  111. package/dist/presentation/inter-module.d.ts.map +1 -0
  112. package/dist/presentation/inter-module.js +113 -0
  113. package/dist/presentation/inter-module.js.map +1 -0
  114. package/dist/presentation/routes/agent-runtime-config.d.ts +6 -1
  115. package/dist/presentation/routes/agent-runtime-config.d.ts.map +1 -1
  116. package/dist/presentation/routes/agent-runtime-config.js +59 -57
  117. package/dist/presentation/routes/agent-runtime-config.js.map +1 -1
  118. package/dist/presentation/routes/cancel-run.d.ts +2 -1
  119. package/dist/presentation/routes/cancel-run.d.ts.map +1 -1
  120. package/dist/presentation/routes/cancel-run.js +37 -34
  121. package/dist/presentation/routes/cancel-run.js.map +1 -1
  122. package/dist/presentation/routes/checkout-token.d.ts +8 -1
  123. package/dist/presentation/routes/checkout-token.d.ts.map +1 -1
  124. package/dist/presentation/routes/checkout-token.js +65 -47
  125. package/dist/presentation/routes/checkout-token.js.map +1 -1
  126. package/dist/presentation/routes/get-run-aggregates.d.ts +2 -1
  127. package/dist/presentation/routes/get-run-aggregates.d.ts.map +1 -1
  128. package/dist/presentation/routes/get-run-aggregates.js +44 -53
  129. package/dist/presentation/routes/get-run-aggregates.js.map +1 -1
  130. package/dist/presentation/routes/get-run.d.ts +2 -1
  131. package/dist/presentation/routes/get-run.d.ts.map +1 -1
  132. package/dist/presentation/routes/get-run.js +53 -50
  133. package/dist/presentation/routes/get-run.js.map +1 -1
  134. package/dist/presentation/routes/get-step-secrets.d.ts +3 -1
  135. package/dist/presentation/routes/get-step-secrets.d.ts.map +1 -1
  136. package/dist/presentation/routes/get-step-secrets.js +72 -68
  137. package/dist/presentation/routes/get-step-secrets.js.map +1 -1
  138. package/dist/presentation/routes/index.d.ts +19 -2
  139. package/dist/presentation/routes/index.d.ts.map +1 -1
  140. package/dist/presentation/routes/index.js +38 -30
  141. package/dist/presentation/routes/index.js.map +1 -1
  142. package/dist/presentation/routes/leased-step.d.ts +2 -0
  143. package/dist/presentation/routes/leased-step.d.ts.map +1 -1
  144. package/dist/presentation/routes/leased-step.js +1 -2
  145. package/dist/presentation/routes/leased-step.js.map +1 -1
  146. package/dist/presentation/routes/list-run-attempts.d.ts +2 -1
  147. package/dist/presentation/routes/list-run-attempts.d.ts.map +1 -1
  148. package/dist/presentation/routes/list-run-attempts.js +29 -26
  149. package/dist/presentation/routes/list-run-attempts.js.map +1 -1
  150. package/dist/presentation/routes/list-runs.d.ts +2 -1
  151. package/dist/presentation/routes/list-runs.d.ts.map +1 -1
  152. package/dist/presentation/routes/list-runs.js +51 -60
  153. package/dist/presentation/routes/list-runs.js.map +1 -1
  154. package/dist/presentation/routes/next-step.d.ts +10 -1
  155. package/dist/presentation/routes/next-step.d.ts.map +1 -1
  156. package/dist/presentation/routes/next-step.js +64 -50
  157. package/dist/presentation/routes/next-step.js.map +1 -1
  158. package/dist/presentation/routes/project-access.d.ts +10 -0
  159. package/dist/presentation/routes/project-access.d.ts.map +1 -0
  160. package/dist/presentation/routes/project-access.js +17 -0
  161. package/dist/presentation/routes/project-access.js.map +1 -0
  162. package/dist/presentation/routes/report-step.d.ts +2 -1
  163. package/dist/presentation/routes/report-step.d.ts.map +1 -1
  164. package/dist/presentation/routes/report-step.js +62 -61
  165. package/dist/presentation/routes/report-step.js.map +1 -1
  166. package/dist/presentation/routes/require-accessible-run.d.ts +3 -1
  167. package/dist/presentation/routes/require-accessible-run.d.ts.map +1 -1
  168. package/dist/presentation/routes/require-accessible-run.js +3 -6
  169. package/dist/presentation/routes/require-accessible-run.js.map +1 -1
  170. package/dist/presentation/routes/rerun-run.d.ts +2 -1
  171. package/dist/presentation/routes/rerun-run.d.ts.map +1 -1
  172. package/dist/presentation/routes/rerun-run.js +46 -43
  173. package/dist/presentation/routes/rerun-run.js.map +1 -1
  174. package/dist/temporal/activities/index.d.ts +44 -9
  175. package/dist/temporal/activities/index.d.ts.map +1 -1
  176. package/dist/temporal/activities/index.js +13 -9
  177. package/dist/temporal/activities/index.js.map +1 -1
  178. package/dist/temporal/activities/orchestration-activities.d.ts +20 -11
  179. package/dist/temporal/activities/orchestration-activities.d.ts.map +1 -1
  180. package/dist/temporal/activities/orchestration-activities.js +48 -33
  181. package/dist/temporal/activities/orchestration-activities.js.map +1 -1
  182. package/dist/tsconfig.test.tsbuildinfo +1 -1
  183. package/package.json +28 -21
  184. package/src/core/agent-defaults.test.ts +28 -0
  185. package/src/core/agent-defaults.ts +36 -0
  186. package/src/core/agent-tool-capability-warning.test.ts +36 -11
  187. package/src/core/agent-tool-capability-warning.ts +27 -25
  188. package/src/core/agent-tools.ts +33 -36
  189. package/src/core/checkout.test.ts +38 -25
  190. package/src/core/checkout.ts +41 -14
  191. package/src/core/entities/workflow-run-attempt.ts +1 -1
  192. package/src/core/job-execution.ts +19 -9
  193. package/src/core/job-transition/derive-job-execution-outputs.ts +1 -1
  194. package/src/core/job-transition/derive-job-success.ts +1 -1
  195. package/src/core/listener-execution-materialization.test.ts +4 -2
  196. package/src/core/listener-execution-materialization.ts +6 -9
  197. package/src/core/run-workflow.test.ts +43 -38
  198. package/src/core/run-workflow.ts +26 -9
  199. package/src/core/step-config/agent.ts +24 -26
  200. package/src/core/step-config/complete-step-dispatch-config.test.ts +22 -23
  201. package/src/core/step-config/complete-step-dispatch-config.ts +6 -6
  202. package/src/core/step-config/materialize-job-execution-steps.test.ts +34 -23
  203. package/src/core/step-config/materialize-job-execution-steps.ts +38 -39
  204. package/src/core/step-config/materialize-workflow-model.test.ts +94 -82
  205. package/src/core/step-config/materialize-workflow-model.ts +31 -29
  206. package/src/core/step-config/resolve-job-execution-name.ts +1 -1
  207. package/src/core/step-config/resolve-step-config.ts +11 -9
  208. package/src/core/step-config/run.ts +1 -1
  209. package/src/core/workflow-run-creation.test.ts +14 -10
  210. package/src/core/workflow-run-creation.ts +6 -9
  211. package/src/db/job-listeners.ts +20 -5
  212. package/src/db/runner-lease-table.ts +2 -2
  213. package/src/db/schema/workflow-run-attempts.ts +7 -3
  214. package/src/db/schema/workflow-runs.ts +1 -1
  215. package/src/db/workflow-runs/job-executions.ts +15 -1
  216. package/src/db/workflow-runs/jobs.ts +4 -1
  217. package/src/db/workflow-runs/run-create.test.ts +7 -1
  218. package/src/db/workflow-runs/run-create.ts +25 -15
  219. package/src/db/workflow-runs/run-rerun.test.ts +1 -1
  220. package/src/db/workflow-runs/run-rerun.ts +6 -3
  221. package/src/index.ts +75 -33
  222. package/src/presentation/dto/checkout-token.ts +7 -1
  223. package/src/presentation/index.ts +1 -1
  224. package/src/presentation/inter-module.test.ts +149 -0
  225. package/src/presentation/inter-module.ts +132 -0
  226. package/src/presentation/routes/agent-runtime-config.test.ts +53 -10
  227. package/src/presentation/routes/agent-runtime-config.ts +89 -64
  228. package/src/presentation/routes/cancel-run.test.ts +10 -20
  229. package/src/presentation/routes/cancel-run.ts +30 -27
  230. package/src/presentation/routes/checkout-token.test.ts +52 -33
  231. package/src/presentation/routes/checkout-token.ts +109 -49
  232. package/src/presentation/routes/get-run-aggregates.test.ts +13 -7
  233. package/src/presentation/routes/get-run-aggregates.ts +54 -57
  234. package/src/presentation/routes/get-run.test.ts +10 -18
  235. package/src/presentation/routes/get-run.ts +51 -48
  236. package/src/presentation/routes/get-step-secrets.test.ts +29 -7
  237. package/src/presentation/routes/get-step-secrets.ts +72 -61
  238. package/src/presentation/routes/index.test.ts +16 -1
  239. package/src/presentation/routes/index.ts +54 -29
  240. package/src/presentation/routes/leased-step.ts +3 -2
  241. package/src/presentation/routes/list-run-attempts.test.ts +9 -19
  242. package/src/presentation/routes/list-run-attempts.ts +21 -18
  243. package/src/presentation/routes/list-runs.test.ts +13 -7
  244. package/src/presentation/routes/list-runs.ts +64 -67
  245. package/src/presentation/routes/next-step.test.ts +30 -11
  246. package/src/presentation/routes/next-step.ts +68 -48
  247. package/src/presentation/routes/project-access.ts +16 -0
  248. package/src/presentation/routes/report-step.test.ts +18 -2
  249. package/src/presentation/routes/report-step.ts +51 -49
  250. package/src/presentation/routes/require-accessible-run.ts +5 -2
  251. package/src/presentation/routes/rerun-run.test.ts +9 -19
  252. package/src/presentation/routes/rerun-run.ts +39 -36
  253. package/src/temporal/activities/index.ts +32 -12
  254. package/src/temporal/activities/orchestration-activities.test.ts +10 -8
  255. package/src/temporal/activities/orchestration-activities.ts +74 -50
  256. package/src/temporal/workflows/job-execution-orchestration.test.ts +47 -2
  257. package/test/env.ts +1 -3
  258. package/test/factories/project.ts +10 -5
  259. package/test/factories/workflow-model.test.ts +5 -1
  260. package/test/factories/workflow-model.ts +1 -1
  261. package/test/factories/workflow-run.ts +1 -1
  262. package/test/fixtures/agent-inter-module.ts +27 -0
  263. package/test/fixtures/annotations-inter-module.ts +5 -0
  264. package/test/fixtures/auth-inter-module.ts +22 -0
  265. package/test/fixtures/lease-token.ts +2 -1
  266. package/test/fixtures/projects-inter-module.ts +8 -0
  267. package/test/fixtures/runners-inter-module.ts +52 -0
  268. package/test/fixtures/secrets-inter-module.ts +61 -0
  269. package/test/globalSetup.ts +11 -11
  270. package/tsconfig.build.tsbuildinfo +1 -1
  271. package/dist/core/source-control.d.ts +0 -5
  272. package/dist/core/source-control.d.ts.map +0 -1
  273. package/dist/core/source-control.js +0 -19
  274. package/dist/core/source-control.js.map +0 -1
  275. package/src/core/source-control.test.ts +0 -17
  276. package/src/core/source-control.ts +0 -22
  277. package/src/temporal/workflows/job-execution-orchestration-timeout.test.ts +0 -165
@@ -1,18 +1,17 @@
1
- import {
2
- InvalidAgentModelError,
3
- UnsupportedModelProviderError,
4
- } from '@shipfox/api-agent/core/errors';
5
- import type {AgentDefaultsResolver} from '@shipfox/api-agent/core/resolve-agent-config';
1
+ import {agentInterModuleContract} from '@shipfox/api-agent-dto/inter-module';
6
2
  import {
7
3
  DEFAULT_JOB_CHECKOUT,
8
4
  normalizeWorkflowDocument,
9
5
  type WorkflowModel,
10
6
  } from '@shipfox/api-definitions';
7
+ import {createInterModuleKnownError} from '@shipfox/inter-module';
8
+ import type {AgentDefaultsResolver} from '#core/agent-defaults.js';
11
9
  import {AgentConfigUnresolvableError, InterpolationUnresolvableError} from '#core/errors.js';
10
+ import {resolveTestAgentDefaults} from '#test/fixtures/agent-inter-module.js';
12
11
  import {workflowModel} from '#test/index.js';
13
12
  import {
14
13
  materializeJobRunner,
15
- materializeWorkflowModel,
14
+ materializeWorkflowModel as materializeWorkflowModelImpl,
16
15
  modelHasAgentStep,
17
16
  } from './materialize-workflow-model.js';
18
17
  import type {WorkflowEvaluationContext} from './workflow-evaluation-context.js';
@@ -21,6 +20,12 @@ type TestWorkflowExpression = NonNullable<
21
20
  NonNullable<WorkflowModel['jobs'][number]['steps'][number]['gate']>['success']
22
21
  >;
23
22
 
23
+ function materializeWorkflowModel(
24
+ params: Parameters<typeof materializeWorkflowModelImpl>[0],
25
+ ): ReturnType<typeof materializeWorkflowModelImpl> {
26
+ return materializeWorkflowModelImpl({resolveAgentDefaults: resolveTestAgentDefaults, ...params});
27
+ }
28
+
24
29
  function expression(source: string): TestWorkflowExpression {
25
30
  return {language: 'cel', check: 'typed', source: source as TestWorkflowExpression['source']};
26
31
  }
@@ -57,7 +62,7 @@ function creationContext(
57
62
  }
58
63
 
59
64
  describe('materializeWorkflowModel', () => {
60
- it('converts workflow model jobs and steps to runtime rows', () => {
65
+ it('converts workflow model jobs and steps to runtime rows', async () => {
61
66
  const model = workflowModel({
62
67
  runner: 'ubuntu-latest',
63
68
  jobs: {
@@ -87,7 +92,7 @@ describe('materializeWorkflowModel', () => {
87
92
  },
88
93
  });
89
94
 
90
- const rows = materializeWorkflowModel({model});
95
+ const rows = await materializeWorkflowModel({model});
91
96
 
92
97
  const setupStep = {
93
98
  key: null,
@@ -162,7 +167,7 @@ describe('materializeWorkflowModel', () => {
162
167
  ]);
163
168
  });
164
169
 
165
- it('materializes an agent step as type "agent" with its config, alongside run steps', () => {
170
+ it('materializes an agent step as type "agent" with its config, alongside run steps', async () => {
166
171
  const model = workflowModel({
167
172
  jobs: {
168
173
  fix: {
@@ -191,7 +196,7 @@ describe('materializeWorkflowModel', () => {
191
196
  },
192
197
  });
193
198
 
194
- const rows = materializeWorkflowModel({model});
199
+ const rows = await materializeWorkflowModel({model});
195
200
 
196
201
  expect(rows[0]?.steps[2]).toEqual({
197
202
  key: 'implement',
@@ -231,7 +236,7 @@ describe('materializeWorkflowModel', () => {
231
236
  });
232
237
  });
233
238
 
234
- it('materializes prompt-only agent steps with catalog defaults before runner execution', () => {
239
+ it('materializes prompt-only agent steps with catalog defaults before runner execution', async () => {
235
240
  const model = workflowModel({
236
241
  jobs: {
237
242
  fix: {
@@ -240,7 +245,7 @@ describe('materializeWorkflowModel', () => {
240
245
  },
241
246
  });
242
247
 
243
- const rows = materializeWorkflowModel({model});
248
+ const rows = await materializeWorkflowModel({model});
244
249
 
245
250
  expect(rows[0]?.steps[1]).toEqual({
246
251
  key: null,
@@ -260,7 +265,7 @@ describe('materializeWorkflowModel', () => {
260
265
  });
261
266
  });
262
267
 
263
- it('materializes agent step tools into resolved config', () => {
268
+ it('materializes agent step tools into resolved config', async () => {
264
269
  const model = workflowModel({
265
270
  jobs: {
266
271
  fix: {
@@ -278,7 +283,7 @@ describe('materializeWorkflowModel', () => {
278
283
  },
279
284
  });
280
285
 
281
- const rows = materializeWorkflowModel({model});
286
+ const rows = await materializeWorkflowModel({model});
282
287
 
283
288
  expect(rows[0]?.steps[1]?.config).toEqual({
284
289
  harness: 'pi',
@@ -290,7 +295,7 @@ describe('materializeWorkflowModel', () => {
290
295
  });
291
296
  });
292
297
 
293
- it('materializes provider-only agent steps with that provider catalog default model', () => {
298
+ it('materializes provider-only agent steps with that provider catalog default model', async () => {
294
299
  const model = workflowModel({
295
300
  jobs: {
296
301
  fix: {
@@ -299,7 +304,7 @@ describe('materializeWorkflowModel', () => {
299
304
  },
300
305
  });
301
306
 
302
- const rows = materializeWorkflowModel({model});
307
+ const rows = await materializeWorkflowModel({model});
303
308
 
304
309
  expect(rows[0]?.steps[1]?.config).toEqual({
305
310
  harness: 'pi',
@@ -310,7 +315,7 @@ describe('materializeWorkflowModel', () => {
310
315
  });
311
316
  });
312
317
 
313
- it('passes checkout through to materialized jobs', () => {
318
+ it('passes checkout through to materialized jobs', async () => {
314
319
  const model = workflowModel({
315
320
  jobs: {
316
321
  build: {
@@ -323,7 +328,7 @@ describe('materializeWorkflowModel', () => {
323
328
  },
324
329
  });
325
330
 
326
- const rows = materializeWorkflowModel({model});
331
+ const rows = await materializeWorkflowModel({model});
327
332
 
328
333
  expect(rows[0]?.checkout).toEqual({
329
334
  permissions: {contents: 'write'},
@@ -331,15 +336,15 @@ describe('materializeWorkflowModel', () => {
331
336
  });
332
337
  });
333
338
 
334
- it('passes default checkout through to materialized jobs', () => {
339
+ it('passes default checkout through to materialized jobs', async () => {
335
340
  const model = workflowModel();
336
341
 
337
- const rows = materializeWorkflowModel({model});
342
+ const rows = await materializeWorkflowModel({model});
338
343
 
339
344
  expect(rows[0]?.checkout).toEqual(DEFAULT_JOB_CHECKOUT);
340
345
  });
341
346
 
342
- it('routes agent steps through the provided resolver', () => {
347
+ it('routes agent steps through the provided resolver', async () => {
343
348
  const model = workflowModel({
344
349
  jobs: {
345
350
  fix: {
@@ -354,7 +359,11 @@ describe('materializeWorkflowModel', () => {
354
359
  thinking: 'medium',
355
360
  });
356
361
 
357
- const rows = materializeWorkflowModel({model, resolveAgentDefaults, definitionId: 'def-1'});
362
+ const rows = await materializeWorkflowModel({
363
+ model,
364
+ resolveAgentDefaults,
365
+ definitionId: 'def-1',
366
+ });
358
367
 
359
368
  expect(resolveAgentDefaults).toHaveBeenCalledWith({
360
369
  harness: undefined,
@@ -374,27 +383,30 @@ describe('materializeWorkflowModel', () => {
374
383
  });
375
384
  });
376
385
 
377
- it.each([
378
- new UnsupportedModelProviderError('unknown-provider'),
379
- new InvalidAgentModelError('pi', 'anthropic', 'missing-model'),
380
- ])('wraps known resolver errors as permanent agent config errors', (cause) => {
386
+ it('wraps known resolver errors as permanent agent config errors', async () => {
381
387
  const model = workflowModel({
382
388
  jobs: {
383
389
  fix: {steps: [{prompt: 'Fix the failing tests.'}]},
384
390
  },
385
391
  });
386
392
  const resolveAgentDefaults = vi.fn<AgentDefaultsResolver>().mockImplementation(() => {
387
- throw cause;
393
+ throw createInterModuleKnownError(
394
+ agentInterModuleContract.methods.resolveAgentConfig,
395
+ 'agent-config-invalid',
396
+ {},
397
+ );
388
398
  });
389
399
 
390
400
  const materialize = () =>
391
401
  materializeWorkflowModel({model, resolveAgentDefaults, definitionId: 'def-1'});
392
402
 
393
- expect(materialize).toThrow(AgentConfigUnresolvableError);
394
- expect(materialize).toThrow('Agent configuration cannot be resolved for definition def-1');
403
+ await expect(materialize()).rejects.toThrow(AgentConfigUnresolvableError);
404
+ await expect(materialize()).rejects.toThrow(
405
+ 'Agent configuration cannot be resolved for definition def-1',
406
+ );
395
407
  });
396
408
 
397
- it('re-throws unknown resolver errors unchanged', () => {
409
+ it('re-throws unknown resolver errors unchanged', async () => {
398
410
  const model = workflowModel({
399
411
  jobs: {
400
412
  fix: {steps: [{prompt: 'Fix the failing tests.'}]},
@@ -408,10 +420,10 @@ describe('materializeWorkflowModel', () => {
408
420
  const materialize = () =>
409
421
  materializeWorkflowModel({model, resolveAgentDefaults, definitionId: 'def-1'});
410
422
 
411
- expect(materialize).toThrow(error);
423
+ await expect(materialize()).rejects.toThrow(error);
412
424
  });
413
425
 
414
- it('materializes merged env for run steps only', () => {
426
+ it('materializes merged env for run steps only', async () => {
415
427
  const model = workflowModel({
416
428
  env: {SHARED: 'workflow', WORKFLOW_ONLY: 'yes'},
417
429
  jobs: {
@@ -431,7 +443,7 @@ describe('materializeWorkflowModel', () => {
431
443
  },
432
444
  });
433
445
 
434
- const rows = materializeWorkflowModel({model});
446
+ const rows = await materializeWorkflowModel({model});
435
447
 
436
448
  expect(rows[0]?.steps[0]?.config).toEqual({});
437
449
  expect(rows[0]?.steps[1]?.config).toEqual({
@@ -452,7 +464,7 @@ describe('materializeWorkflowModel', () => {
452
464
  });
453
465
  });
454
466
 
455
- it('omits env from run-step config when the merge is empty', () => {
467
+ it('omits env from run-step config when the merge is empty', async () => {
456
468
  const model = workflowModel({
457
469
  jobs: {
458
470
  build: {
@@ -461,12 +473,12 @@ describe('materializeWorkflowModel', () => {
461
473
  },
462
474
  });
463
475
 
464
- const rows = materializeWorkflowModel({model});
476
+ const rows = await materializeWorkflowModel({model});
465
477
 
466
478
  expect(rows[0]?.steps[1]?.config).toEqual({run: 'npm test'});
467
479
  });
468
480
 
469
- it('hoists run interpolation into generated env vars with shell references', () => {
481
+ it('hoists run interpolation into generated env vars with shell references', async () => {
470
482
  const model = workflowModel({
471
483
  jobs: {
472
484
  build: {
@@ -475,7 +487,7 @@ describe('materializeWorkflowModel', () => {
475
487
  },
476
488
  });
477
489
 
478
- const rows = materializeWorkflowModel({model, context: creationContext()});
490
+ const rows = await materializeWorkflowModel({model, context: creationContext()});
479
491
 
480
492
  expect(rows[0]?.steps[1]?.config).toEqual({
481
493
  run: `echo "${shellRef('__sf_0')}" && echo "${shellRef('__sf_1')}"`,
@@ -489,7 +501,7 @@ describe('materializeWorkflowModel', () => {
489
501
  });
490
502
  });
491
503
 
492
- it('hoists command secret assignments outside command substitutions', () => {
504
+ it('hoists command secret assignments outside command substitutions', async () => {
493
505
  const command = [
494
506
  `COMMAND_SECRET='${template('secrets.RUNTIME_TOKEN')}'`,
495
507
  'export COMMAND_SECRET',
@@ -503,7 +515,7 @@ describe('materializeWorkflowModel', () => {
503
515
  },
504
516
  });
505
517
 
506
- const rows = materializeWorkflowModel({model, context: creationContext()});
518
+ const rows = await materializeWorkflowModel({model, context: creationContext()});
507
519
 
508
520
  expect(rows[0]?.steps[1]?.config).toEqual({
509
521
  run: [
@@ -526,7 +538,7 @@ describe('materializeWorkflowModel', () => {
526
538
  });
527
539
  });
528
540
 
529
- it('freezes vars from the run-creation context into step config', () => {
541
+ it('freezes vars from the run-creation context into step config', async () => {
530
542
  const model = normalizeWorkflowDocument({
531
543
  name: 'vars workflow',
532
544
  runner: 'ubuntu-latest',
@@ -542,7 +554,7 @@ describe('materializeWorkflowModel', () => {
542
554
  },
543
555
  });
544
556
 
545
- const rows = materializeWorkflowModel({
557
+ const rows = await materializeWorkflowModel({
546
558
  model,
547
559
  context: creationContext({...runContext(), vars: {REGION: 'west'}}),
548
560
  });
@@ -565,7 +577,7 @@ describe('materializeWorkflowModel', () => {
565
577
  });
566
578
  });
567
579
 
568
- it('merges env before resolving and only resolves the winning values', () => {
580
+ it('merges env before resolving and only resolves the winning values', async () => {
569
581
  const model = workflowModel({
570
582
  env: {SHARED: template('event.missing'), WORKFLOW_ONLY: template('run.id')},
571
583
  jobs: {
@@ -581,7 +593,7 @@ describe('materializeWorkflowModel', () => {
581
593
  },
582
594
  });
583
595
 
584
- const rows = materializeWorkflowModel({model, context: creationContext()});
596
+ const rows = await materializeWorkflowModel({model, context: creationContext()});
585
597
 
586
598
  expect(rows[0]?.steps[1]?.config).toEqual({
587
599
  run: 'echo ok',
@@ -604,7 +616,7 @@ describe('materializeWorkflowModel', () => {
604
616
  expect(rows[0]?.steps[1]?.diagnostics).toBeUndefined();
605
617
  });
606
618
 
607
- it('throws a permanent interpolation error for available missing untrusted env paths', () => {
619
+ it('throws a permanent interpolation error for available missing untrusted env paths', async () => {
608
620
  const model = workflowModel({
609
621
  jobs: {
610
622
  build: {
@@ -615,7 +627,7 @@ describe('materializeWorkflowModel', () => {
615
627
 
616
628
  let error: unknown;
617
629
  try {
618
- materializeWorkflowModel({
630
+ await materializeWorkflowModel({
619
631
  model,
620
632
  context: creationContext({...runContext(), event: {}}),
621
633
  definitionId: 'def-1',
@@ -633,7 +645,7 @@ describe('materializeWorkflowModel', () => {
633
645
  expect((error as Error).message).toContain("Use has(x) ? x : ''");
634
646
  });
635
647
 
636
- it('preserves dispatch-time execution paths in the config plan at creation', () => {
648
+ it('preserves dispatch-time execution paths in the config plan at creation', async () => {
637
649
  const model = workflowModel({
638
650
  jobs: {
639
651
  build: {
@@ -642,7 +654,7 @@ describe('materializeWorkflowModel', () => {
642
654
  },
643
655
  });
644
656
 
645
- const rows = materializeWorkflowModel({
657
+ const rows = await materializeWorkflowModel({
646
658
  model,
647
659
  context: creationContext(),
648
660
  definitionId: 'def-1',
@@ -661,7 +673,7 @@ describe('materializeWorkflowModel', () => {
661
673
  expect(rows[0]?.steps[1]?.diagnostics).toBeUndefined();
662
674
  });
663
675
 
664
- it('reserves user env names when generating run interpolation env vars', () => {
676
+ it('reserves user env names when generating run interpolation env vars', async () => {
665
677
  const model = workflowModel({
666
678
  jobs: {
667
679
  build: {
@@ -670,7 +682,7 @@ describe('materializeWorkflowModel', () => {
670
682
  },
671
683
  });
672
684
 
673
- const rows = materializeWorkflowModel({model, context: creationContext()});
685
+ const rows = await materializeWorkflowModel({model, context: creationContext()});
674
686
 
675
687
  expect(rows[0]?.steps[1]?.config).toEqual({
676
688
  run: `echo "${shellRef('__sf_1')}"`,
@@ -678,7 +690,7 @@ describe('materializeWorkflowModel', () => {
678
690
  });
679
691
  });
680
692
 
681
- it('reserves deferred user env names when generating run interpolation env vars', () => {
693
+ it('reserves deferred user env names when generating run interpolation env vars', async () => {
682
694
  const model = workflowModel({
683
695
  jobs: {
684
696
  build: {
@@ -692,7 +704,7 @@ describe('materializeWorkflowModel', () => {
692
704
  },
693
705
  });
694
706
 
695
- const rows = materializeWorkflowModel({model, context: creationContext()});
707
+ const rows = await materializeWorkflowModel({model, context: creationContext()});
696
708
 
697
709
  expect(rows[0]?.steps[1]?.config).toEqual({
698
710
  run: `echo "${shellRef('__sf_1')}"`,
@@ -711,7 +723,7 @@ describe('materializeWorkflowModel', () => {
711
723
  });
712
724
  });
713
725
 
714
- it('resolves agent prompt, model, and provider before catalog defaults', () => {
726
+ it('resolves agent prompt, model, and provider before catalog defaults', async () => {
715
727
  const model = workflowModel({
716
728
  jobs: {
717
729
  fix: {
@@ -734,7 +746,7 @@ describe('materializeWorkflowModel', () => {
734
746
  thinking: 'medium',
735
747
  });
736
748
 
737
- const rows = materializeWorkflowModel({
749
+ const rows = await materializeWorkflowModel({
738
750
  model,
739
751
  context: creationContext({
740
752
  ...runContext({name: 'gpt-5.5-pro'}),
@@ -767,7 +779,7 @@ describe('materializeWorkflowModel', () => {
767
779
  });
768
780
  });
769
781
 
770
- it('keeps agent tools in the dispatch plan while config is deferred', () => {
782
+ it('keeps agent tools in the dispatch plan while config is deferred', async () => {
771
783
  const model = workflowModel({
772
784
  jobs: {
773
785
  fix: {
@@ -784,7 +796,7 @@ describe('materializeWorkflowModel', () => {
784
796
  },
785
797
  });
786
798
 
787
- const rows = materializeWorkflowModel({
799
+ const rows = await materializeWorkflowModel({
788
800
  model,
789
801
  context: creationContext(),
790
802
  definitionId: 'def-1',
@@ -810,7 +822,7 @@ describe('materializeWorkflowModel', () => {
810
822
  ]);
811
823
  });
812
824
 
813
- it('throws a permanent interpolation error for unsafe run interpolation', () => {
825
+ it('throws a permanent interpolation error for unsafe run interpolation', async () => {
814
826
  const model = workflowModel({
815
827
  jobs: {
816
828
  build: {steps: [{run: `echo \`${template('run.id')}\``}]},
@@ -820,10 +832,10 @@ describe('materializeWorkflowModel', () => {
820
832
  const materialize = () =>
821
833
  materializeWorkflowModel({model, context: creationContext(), definitionId: 'def-1'});
822
834
 
823
- expect(materialize).toThrow(InterpolationUnresolvableError);
835
+ await expect(materialize()).rejects.toThrow(InterpolationUnresolvableError);
824
836
  });
825
837
 
826
- it('throws a permanent interpolation error for a missing trusted run path', () => {
838
+ it('throws a permanent interpolation error for a missing trusted run path', async () => {
827
839
  const model = workflowModel({
828
840
  jobs: {
829
841
  build: {steps: [{run: `echo "${template('run.id')}"`}]},
@@ -833,10 +845,10 @@ describe('materializeWorkflowModel', () => {
833
845
  const materialize = () =>
834
846
  materializeWorkflowModel({model, context: creationContext({}), definitionId: 'def-1'});
835
847
 
836
- expect(materialize).toThrow(InterpolationUnresolvableError);
848
+ await expect(materialize()).rejects.toThrow(InterpolationUnresolvableError);
837
849
  });
838
850
 
839
- it('throws a permanent interpolation error for missing available agent prompt paths', () => {
851
+ it('throws a permanent interpolation error for missing available agent prompt paths', async () => {
840
852
  const model = workflowModel({
841
853
  jobs: {
842
854
  fix: {steps: [{prompt: template('inputs.ticket')}]},
@@ -845,7 +857,7 @@ describe('materializeWorkflowModel', () => {
845
857
 
846
858
  let error: unknown;
847
859
  try {
848
- materializeWorkflowModel({
860
+ await materializeWorkflowModel({
849
861
  model,
850
862
  context: creationContext({...runContext(), inputs: {}}),
851
863
  definitionId: 'def-1',
@@ -861,7 +873,7 @@ describe('materializeWorkflowModel', () => {
861
873
  });
862
874
  });
863
875
 
864
- it('throws a permanent interpolation error for a missing trusted agent model path', () => {
876
+ it('throws a permanent interpolation error for a missing trusted agent model path', async () => {
865
877
  const model = workflowModel({
866
878
  jobs: {
867
879
  fix: {steps: [{model: template('run.missing'), prompt: 'Fix it.'}]},
@@ -870,7 +882,7 @@ describe('materializeWorkflowModel', () => {
870
882
 
871
883
  let error: unknown;
872
884
  try {
873
- materializeWorkflowModel({
885
+ await materializeWorkflowModel({
874
886
  model,
875
887
  context: creationContext(),
876
888
  definitionId: 'def-1',
@@ -886,7 +898,7 @@ describe('materializeWorkflowModel', () => {
886
898
  });
887
899
  });
888
900
 
889
- it('degrades missing execution paths in step names', () => {
901
+ it('degrades missing execution paths in step names', async () => {
890
902
  const model = workflowModel({
891
903
  jobs: {
892
904
  review: {
@@ -900,7 +912,7 @@ describe('materializeWorkflowModel', () => {
900
912
  },
901
913
  });
902
914
 
903
- const rows = materializeWorkflowModel({
915
+ const rows = await materializeWorkflowModel({
904
916
  model,
905
917
  context: creationContext(),
906
918
  definitionId: 'def-1',
@@ -919,7 +931,7 @@ describe('materializeWorkflowModel', () => {
919
931
  });
920
932
  });
921
933
 
922
- it('degrades missing available untrusted paths in step names', () => {
934
+ it('degrades missing available untrusted paths in step names', async () => {
923
935
  const model = workflowModel({
924
936
  jobs: {
925
937
  review: {
@@ -933,7 +945,7 @@ describe('materializeWorkflowModel', () => {
933
945
  },
934
946
  });
935
947
 
936
- const rows = materializeWorkflowModel({
948
+ const rows = await materializeWorkflowModel({
937
949
  model,
938
950
  context: creationContext({...runContext(), event: {}}),
939
951
  definitionId: 'def-1',
@@ -952,7 +964,7 @@ describe('materializeWorkflowModel', () => {
952
964
  });
953
965
  });
954
966
 
955
- it('uses the display-name fallback when a degraded step name resolves empty', () => {
967
+ it('uses the display-name fallback when a degraded step name resolves empty', async () => {
956
968
  const model = workflowModel({
957
969
  jobs: {
958
970
  build: {
@@ -966,7 +978,7 @@ describe('materializeWorkflowModel', () => {
966
978
  },
967
979
  });
968
980
 
969
- const rows = materializeWorkflowModel({
981
+ const rows = await materializeWorkflowModel({
970
982
  model,
971
983
  context: creationContext({...runContext(), event: {}}),
972
984
  definitionId: 'def-1',
@@ -985,7 +997,7 @@ describe('materializeWorkflowModel', () => {
985
997
  });
986
998
  });
987
999
 
988
- it('skips listening job steps at workflow-run creation', () => {
1000
+ it('skips listening job steps at workflow-run creation', async () => {
989
1001
  const stepNameSource = `Review ${template('execution.index')}`;
990
1002
  const model = normalizeWorkflowDocument({
991
1003
  name: 'Listening workflow',
@@ -1001,7 +1013,7 @@ describe('materializeWorkflowModel', () => {
1001
1013
  },
1002
1014
  });
1003
1015
 
1004
- const rows = materializeWorkflowModel({
1016
+ const rows = await materializeWorkflowModel({
1005
1017
  model,
1006
1018
  context: creationContext(),
1007
1019
  definitionId: 'def-1',
@@ -1014,7 +1026,7 @@ describe('materializeWorkflowModel', () => {
1014
1026
  });
1015
1027
  });
1016
1028
 
1017
- it('materializes one-shot siblings while skipping listening steps', () => {
1029
+ it('materializes one-shot siblings while skipping listening steps', async () => {
1018
1030
  const model = normalizeWorkflowDocument({
1019
1031
  name: 'Mixed workflow',
1020
1032
  runner: 'ubuntu-latest',
@@ -1032,7 +1044,7 @@ describe('materializeWorkflowModel', () => {
1032
1044
  },
1033
1045
  });
1034
1046
 
1035
- const rows = materializeWorkflowModel({model, context: creationContext()});
1047
+ const rows = await materializeWorkflowModel({model, context: creationContext()});
1036
1048
 
1037
1049
  const review = rows.find((job) => job.key === 'review');
1038
1050
  const build = rows.find((job) => job.key === 'build');
@@ -1042,18 +1054,18 @@ describe('materializeWorkflowModel', () => {
1042
1054
  expect(build?.steps[1]).toMatchObject({type: 'run', config: {run: 'npm test'}, position: 1});
1043
1055
  });
1044
1056
 
1045
- it('uses the supplied context for each materialization call', () => {
1057
+ it('uses the supplied context for each materialization call', async () => {
1046
1058
  const model = workflowModel({
1047
1059
  jobs: {
1048
1060
  build: {steps: [{run: `echo "${template('run.id')}"`}]},
1049
1061
  },
1050
1062
  });
1051
1063
 
1052
- const first = materializeWorkflowModel({
1064
+ const first = await materializeWorkflowModel({
1053
1065
  model,
1054
1066
  context: creationContext(runContext({id: 'run-a'})),
1055
1067
  });
1056
- const second = materializeWorkflowModel({
1068
+ const second = await materializeWorkflowModel({
1057
1069
  model,
1058
1070
  context: creationContext(runContext({id: 'run-b'})),
1059
1071
  });
@@ -1062,10 +1074,10 @@ describe('materializeWorkflowModel', () => {
1062
1074
  expect(second[0]?.steps[1]?.config).toMatchObject({env: {__sf_0: 'run-b'}});
1063
1075
  });
1064
1076
 
1065
- it('gives a job with no user steps just the synthetic setup step', () => {
1077
+ it('gives a job with no user steps just the synthetic setup step', async () => {
1066
1078
  const model = workflowModel({jobs: {noop: {steps: []}}});
1067
1079
 
1068
- const rows = materializeWorkflowModel({model});
1080
+ const rows = await materializeWorkflowModel({model});
1069
1081
 
1070
1082
  expect(rows[0]?.steps).toEqual([
1071
1083
  {
@@ -1082,7 +1094,7 @@ describe('materializeWorkflowModel', () => {
1082
1094
  expect(rows[0]?.checkout).toEqual(DEFAULT_JOB_CHECKOUT);
1083
1095
  });
1084
1096
 
1085
- it('materializes step if as server-owned condition outside runner config', () => {
1097
+ it('materializes step if as server-owned condition outside runner config', async () => {
1086
1098
  const model = normalizeWorkflowDocument({
1087
1099
  name: 'Conditional workflow',
1088
1100
  runner: 'ubuntu-latest',
@@ -1093,7 +1105,7 @@ describe('materializeWorkflowModel', () => {
1093
1105
  },
1094
1106
  });
1095
1107
 
1096
- const rows = materializeWorkflowModel({model});
1108
+ const rows = await materializeWorkflowModel({model});
1097
1109
 
1098
1110
  const step = rows[0]?.steps[1];
1099
1111
  expect(step?.condition).toEqual({
@@ -1105,7 +1117,7 @@ describe('materializeWorkflowModel', () => {
1105
1117
  expect(step?.config).toEqual({run: 'npm test'});
1106
1118
  });
1107
1119
 
1108
- it('fails fast when the model contains an unresolved dependency id', () => {
1120
+ it('fails fast when the model contains an unresolved dependency id', async () => {
1109
1121
  const model: WorkflowModel = {
1110
1122
  ...workflowModel(),
1111
1123
  jobs: [
@@ -1122,7 +1134,7 @@ describe('materializeWorkflowModel', () => {
1122
1134
  dependencies: [{from: 'missing', to: 'test'}],
1123
1135
  };
1124
1136
 
1125
- expect(() => materializeWorkflowModel({model})).toThrow(
1137
+ await expect(materializeWorkflowModel({model})).rejects.toThrow(
1126
1138
  'Unresolved workflow model dependency "missing" for job "test"',
1127
1139
  );
1128
1140
  });