@shipfox/api-definitions 2.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 (401) hide show
  1. package/.turbo/turbo-build.log +2 -0
  2. package/.turbo/turbo-type$colon$emit.log +1 -0
  3. package/.turbo/turbo-type.log +1 -0
  4. package/CHANGELOG.md +215 -0
  5. package/LICENSE +21 -0
  6. package/dist/config.d.ts +10 -0
  7. package/dist/config.d.ts.map +1 -0
  8. package/dist/config.js +35 -0
  9. package/dist/config.js.map +1 -0
  10. package/dist/core/entities/index.d.ts +5 -0
  11. package/dist/core/entities/index.d.ts.map +1 -0
  12. package/dist/core/entities/index.js +6 -0
  13. package/dist/core/entities/index.js.map +1 -0
  14. package/dist/core/entities/integration-context.d.ts +11 -0
  15. package/dist/core/entities/integration-context.d.ts.map +1 -0
  16. package/dist/core/entities/integration-context.js +3 -0
  17. package/dist/core/entities/integration-context.js.map +1 -0
  18. package/dist/core/entities/sync-state.d.ts +19 -0
  19. package/dist/core/entities/sync-state.d.ts.map +1 -0
  20. package/dist/core/entities/sync-state.js +20 -0
  21. package/dist/core/entities/sync-state.js.map +1 -0
  22. package/dist/core/entities/workflow-definition.d.ts +35 -0
  23. package/dist/core/entities/workflow-definition.d.ts.map +1 -0
  24. package/dist/core/entities/workflow-definition.js +3 -0
  25. package/dist/core/entities/workflow-definition.js.map +1 -0
  26. package/dist/core/entities/workflow-model.d.ts +138 -0
  27. package/dist/core/entities/workflow-model.d.ts.map +1 -0
  28. package/dist/core/entities/workflow-model.js +3 -0
  29. package/dist/core/entities/workflow-model.js.map +1 -0
  30. package/dist/core/errors.d.ts +10 -0
  31. package/dist/core/errors.d.ts.map +1 -0
  32. package/dist/core/errors.js +14 -0
  33. package/dist/core/errors.js.map +1 -0
  34. package/dist/core/has-agent-step-integrations.d.ts +3 -0
  35. package/dist/core/has-agent-step-integrations.d.ts.map +1 -0
  36. package/dist/core/has-agent-step-integrations.js +5 -0
  37. package/dist/core/has-agent-step-integrations.js.map +1 -0
  38. package/dist/core/index.d.ts +9 -0
  39. package/dist/core/index.d.ts.map +1 -0
  40. package/dist/core/index.js +9 -0
  41. package/dist/core/index.js.map +1 -0
  42. package/dist/core/parse-definition.d.ts +9 -0
  43. package/dist/core/parse-definition.d.ts.map +1 -0
  44. package/dist/core/parse-definition.js +17 -0
  45. package/dist/core/parse-definition.js.map +1 -0
  46. package/dist/core/sync-definitions.d.ts +44 -0
  47. package/dist/core/sync-definitions.d.ts.map +1 -0
  48. package/dist/core/sync-definitions.js +140 -0
  49. package/dist/core/sync-definitions.js.map +1 -0
  50. package/dist/core/validate-definition.d.ts +20 -0
  51. package/dist/core/validate-definition.d.ts.map +1 -0
  52. package/dist/core/validate-definition.js +61 -0
  53. package/dist/core/validate-definition.js.map +1 -0
  54. package/dist/core/workflow-model/constants.d.ts +2 -0
  55. package/dist/core/workflow-model/constants.d.ts.map +1 -0
  56. package/dist/core/workflow-model/constants.js +3 -0
  57. package/dist/core/workflow-model/constants.js.map +1 -0
  58. package/dist/core/workflow-model/cron-trigger.d.ts +16 -0
  59. package/dist/core/workflow-model/cron-trigger.d.ts.map +1 -0
  60. package/dist/core/workflow-model/cron-trigger.js +85 -0
  61. package/dist/core/workflow-model/cron-trigger.js.map +1 -0
  62. package/dist/core/workflow-model/index.d.ts +4 -0
  63. package/dist/core/workflow-model/index.d.ts.map +1 -0
  64. package/dist/core/workflow-model/index.js +5 -0
  65. package/dist/core/workflow-model/index.js.map +1 -0
  66. package/dist/core/workflow-model/invalid-workflow-model-error.d.ts +15 -0
  67. package/dist/core/workflow-model/invalid-workflow-model-error.d.ts.map +1 -0
  68. package/dist/core/workflow-model/invalid-workflow-model-error.js +9 -0
  69. package/dist/core/workflow-model/invalid-workflow-model-error.js.map +1 -0
  70. package/dist/core/workflow-model/map-job-ids.d.ts +4 -0
  71. package/dist/core/workflow-model/map-job-ids.d.ts.map +1 -0
  72. package/dist/core/workflow-model/map-job-ids.js +33 -0
  73. package/dist/core/workflow-model/map-job-ids.js.map +1 -0
  74. package/dist/core/workflow-model/normalize-agent-integrations.d.ts +12 -0
  75. package/dist/core/workflow-model/normalize-agent-integrations.d.ts.map +1 -0
  76. package/dist/core/workflow-model/normalize-agent-integrations.js +157 -0
  77. package/dist/core/workflow-model/normalize-agent-integrations.js.map +1 -0
  78. package/dist/core/workflow-model/normalize-dependencies.d.ts +6 -0
  79. package/dist/core/workflow-model/normalize-dependencies.d.ts.map +1 -0
  80. package/dist/core/workflow-model/normalize-dependencies.js +119 -0
  81. package/dist/core/workflow-model/normalize-dependencies.js.map +1 -0
  82. package/dist/core/workflow-model/normalize-env.d.ts +17 -0
  83. package/dist/core/workflow-model/normalize-env.d.ts.map +1 -0
  84. package/dist/core/workflow-model/normalize-env.js +40 -0
  85. package/dist/core/workflow-model/normalize-env.js.map +1 -0
  86. package/dist/core/workflow-model/normalize-if-condition.d.ts +14 -0
  87. package/dist/core/workflow-model/normalize-if-condition.d.ts.map +1 -0
  88. package/dist/core/workflow-model/normalize-if-condition.js +75 -0
  89. package/dist/core/workflow-model/normalize-if-condition.js.map +1 -0
  90. package/dist/core/workflow-model/normalize-job-checkout.d.ts +5 -0
  91. package/dist/core/workflow-model/normalize-job-checkout.d.ts.map +1 -0
  92. package/dist/core/workflow-model/normalize-job-checkout.js +16 -0
  93. package/dist/core/workflow-model/normalize-job-checkout.js.map +1 -0
  94. package/dist/core/workflow-model/normalize-job-listening.d.ts +10 -0
  95. package/dist/core/workflow-model/normalize-job-listening.d.ts.map +1 -0
  96. package/dist/core/workflow-model/normalize-job-listening.js +125 -0
  97. package/dist/core/workflow-model/normalize-job-listening.js.map +1 -0
  98. package/dist/core/workflow-model/normalize-job-success.d.ts +11 -0
  99. package/dist/core/workflow-model/normalize-job-success.d.ts.map +1 -0
  100. package/dist/core/workflow-model/normalize-job-success.js +23 -0
  101. package/dist/core/workflow-model/normalize-job-success.js.map +1 -0
  102. package/dist/core/workflow-model/normalize-jobs.d.ts +12 -0
  103. package/dist/core/workflow-model/normalize-jobs.d.ts.map +1 -0
  104. package/dist/core/workflow-model/normalize-jobs.js +935 -0
  105. package/dist/core/workflow-model/normalize-jobs.js.map +1 -0
  106. package/dist/core/workflow-model/normalize-needs.d.ts +2 -0
  107. package/dist/core/workflow-model/normalize-needs.d.ts.map +1 -0
  108. package/dist/core/workflow-model/normalize-needs.js +16 -0
  109. package/dist/core/workflow-model/normalize-needs.js.map +1 -0
  110. package/dist/core/workflow-model/normalize-step-gate.d.ts +15 -0
  111. package/dist/core/workflow-model/normalize-step-gate.d.ts.map +1 -0
  112. package/dist/core/workflow-model/normalize-step-gate.js +89 -0
  113. package/dist/core/workflow-model/normalize-step-gate.js.map +1 -0
  114. package/dist/core/workflow-model/normalize-step-outputs.d.ts +10 -0
  115. package/dist/core/workflow-model/normalize-step-outputs.d.ts.map +1 -0
  116. package/dist/core/workflow-model/normalize-step-outputs.js +32 -0
  117. package/dist/core/workflow-model/normalize-step-outputs.js.map +1 -0
  118. package/dist/core/workflow-model/normalize-triggers.d.ts +11 -0
  119. package/dist/core/workflow-model/normalize-triggers.d.ts.map +1 -0
  120. package/dist/core/workflow-model/normalize-triggers.js +128 -0
  121. package/dist/core/workflow-model/normalize-triggers.js.map +1 -0
  122. package/dist/core/workflow-model/normalize-workflow-document.d.ts +11 -0
  123. package/dist/core/workflow-model/normalize-workflow-document.d.ts.map +1 -0
  124. package/dist/core/workflow-model/normalize-workflow-document.js +43 -0
  125. package/dist/core/workflow-model/normalize-workflow-document.js.map +1 -0
  126. package/dist/core/workflow-model/parse-duration-ms.d.ts +11 -0
  127. package/dist/core/workflow-model/parse-duration-ms.d.ts.map +1 -0
  128. package/dist/core/workflow-model/parse-duration-ms.js +47 -0
  129. package/dist/core/workflow-model/parse-duration-ms.js.map +1 -0
  130. package/dist/core/workflow-model/parse-interpolation-field.d.ts +14 -0
  131. package/dist/core/workflow-model/parse-interpolation-field.d.ts.map +1 -0
  132. package/dist/core/workflow-model/parse-interpolation-field.js +377 -0
  133. package/dist/core/workflow-model/parse-interpolation-field.js.map +1 -0
  134. package/dist/core/workflow-model/stable-id.d.ts +2 -0
  135. package/dist/core/workflow-model/stable-id.d.ts.map +1 -0
  136. package/dist/core/workflow-model/stable-id.js +8 -0
  137. package/dist/core/workflow-model/stable-id.js.map +1 -0
  138. package/dist/core/workflow-model/validate-job-references.d.ts +10 -0
  139. package/dist/core/workflow-model/validate-job-references.d.ts.map +1 -0
  140. package/dist/core/workflow-model/validate-job-references.js +42 -0
  141. package/dist/core/workflow-model/validate-job-references.js.map +1 -0
  142. package/dist/core/workflow-model/validate-predicate-expression.d.ts +14 -0
  143. package/dist/core/workflow-model/validate-predicate-expression.d.ts.map +1 -0
  144. package/dist/core/workflow-model/validate-predicate-expression.js +273 -0
  145. package/dist/core/workflow-model/validate-predicate-expression.js.map +1 -0
  146. package/dist/core/workflow-model/validation-issue.d.ts +8 -0
  147. package/dist/core/workflow-model/validation-issue.d.ts.map +1 -0
  148. package/dist/core/workflow-model/validation-issue.js +17 -0
  149. package/dist/core/workflow-model/validation-issue.js.map +1 -0
  150. package/dist/core/workflow-model/workflow-field-label.d.ts +3 -0
  151. package/dist/core/workflow-model/workflow-field-label.d.ts.map +1 -0
  152. package/dist/core/workflow-model/workflow-field-label.js +47 -0
  153. package/dist/core/workflow-model/workflow-field-label.js.map +1 -0
  154. package/dist/core/workflow-yaml/index.d.ts +3 -0
  155. package/dist/core/workflow-yaml/index.d.ts.map +1 -0
  156. package/dist/core/workflow-yaml/index.js +4 -0
  157. package/dist/core/workflow-yaml/index.js.map +1 -0
  158. package/dist/core/workflow-yaml/invalid-workflow-yaml-error.d.ts +16 -0
  159. package/dist/core/workflow-yaml/invalid-workflow-yaml-error.d.ts.map +1 -0
  160. package/dist/core/workflow-yaml/invalid-workflow-yaml-error.js +12 -0
  161. package/dist/core/workflow-yaml/invalid-workflow-yaml-error.js.map +1 -0
  162. package/dist/core/workflow-yaml/parse-workflow-yaml.d.ts +9 -0
  163. package/dist/core/workflow-yaml/parse-workflow-yaml.d.ts.map +1 -0
  164. package/dist/core/workflow-yaml/parse-workflow-yaml.js +52 -0
  165. package/dist/core/workflow-yaml/parse-workflow-yaml.js.map +1 -0
  166. package/dist/core/workflow-yaml/source-locations.d.ts +3 -0
  167. package/dist/core/workflow-yaml/source-locations.d.ts.map +1 -0
  168. package/dist/core/workflow-yaml/source-locations.js +48 -0
  169. package/dist/core/workflow-yaml/source-locations.js.map +1 -0
  170. package/dist/db/db.d.ts +1277 -0
  171. package/dist/db/db.d.ts.map +1 -0
  172. package/dist/db/db.js +22 -0
  173. package/dist/db/db.js.map +1 -0
  174. package/dist/db/definition-triggers.d.ts +4 -0
  175. package/dist/db/definition-triggers.d.ts.map +1 -0
  176. package/dist/db/definition-triggers.js +17 -0
  177. package/dist/db/definition-triggers.js.map +1 -0
  178. package/dist/db/definitions.d.ts +63 -0
  179. package/dist/db/definitions.d.ts.map +1 -0
  180. package/dist/db/definitions.js +208 -0
  181. package/dist/db/definitions.js.map +1 -0
  182. package/dist/db/index.d.ts +8 -0
  183. package/dist/db/index.d.ts.map +1 -0
  184. package/dist/db/index.js +10 -0
  185. package/dist/db/index.js.map +1 -0
  186. package/dist/db/schema/common.d.ts +2 -0
  187. package/dist/db/schema/common.d.ts.map +1 -0
  188. package/dist/db/schema/common.js +4 -0
  189. package/dist/db/schema/common.js.map +1 -0
  190. package/dist/db/schema/definitions.d.ts +237 -0
  191. package/dist/db/schema/definitions.d.ts.map +1 -0
  192. package/dist/db/schema/definitions.js +63 -0
  193. package/dist/db/schema/definitions.js.map +1 -0
  194. package/dist/db/schema/outbox.d.ts +195 -0
  195. package/dist/db/schema/outbox.d.ts.map +1 -0
  196. package/dist/db/schema/outbox.js +5 -0
  197. package/dist/db/schema/outbox.js.map +1 -0
  198. package/dist/db/schema/sync-states.d.ts +218 -0
  199. package/dist/db/schema/sync-states.d.ts.map +1 -0
  200. package/dist/db/schema/sync-states.js +68 -0
  201. package/dist/db/schema/sync-states.js.map +1 -0
  202. package/dist/db/sync-states.d.ts +21 -0
  203. package/dist/db/sync-states.d.ts.map +1 -0
  204. package/dist/db/sync-states.js +47 -0
  205. package/dist/db/sync-states.js.map +1 -0
  206. package/dist/index.d.ts +14 -0
  207. package/dist/index.d.ts.map +1 -0
  208. package/dist/index.js +63 -0
  209. package/dist/index.js.map +1 -0
  210. package/dist/presentation/dto/definition.d.ts +6 -0
  211. package/dist/presentation/dto/definition.d.ts.map +1 -0
  212. package/dist/presentation/dto/definition.js +35 -0
  213. package/dist/presentation/dto/definition.js.map +1 -0
  214. package/dist/presentation/dto/index.d.ts +2 -0
  215. package/dist/presentation/dto/index.d.ts.map +1 -0
  216. package/dist/presentation/dto/index.js +3 -0
  217. package/dist/presentation/dto/index.js.map +1 -0
  218. package/dist/presentation/index.d.ts +2 -0
  219. package/dist/presentation/index.d.ts.map +1 -0
  220. package/dist/presentation/index.js +3 -0
  221. package/dist/presentation/index.js.map +1 -0
  222. package/dist/presentation/routes/create-definition.d.ts +9 -0
  223. package/dist/presentation/routes/create-definition.d.ts.map +1 -0
  224. package/dist/presentation/routes/create-definition.js +76 -0
  225. package/dist/presentation/routes/create-definition.js.map +1 -0
  226. package/dist/presentation/routes/get-definition.d.ts +2 -0
  227. package/dist/presentation/routes/get-definition.d.ts.map +1 -0
  228. package/dist/presentation/routes/get-definition.js +43 -0
  229. package/dist/presentation/routes/get-definition.js.map +1 -0
  230. package/dist/presentation/routes/index.d.ts +7 -0
  231. package/dist/presentation/routes/index.d.ts.map +1 -0
  232. package/dist/presentation/routes/index.js +22 -0
  233. package/dist/presentation/routes/index.js.map +1 -0
  234. package/dist/presentation/routes/list-definitions.d.ts +2 -0
  235. package/dist/presentation/routes/list-definitions.d.ts.map +1 -0
  236. package/dist/presentation/routes/list-definitions.js +56 -0
  237. package/dist/presentation/routes/list-definitions.js.map +1 -0
  238. package/dist/presentation/routes/validate-definition.d.ts +2 -0
  239. package/dist/presentation/routes/validate-definition.d.ts.map +1 -0
  240. package/dist/presentation/routes/validate-definition.js +43 -0
  241. package/dist/presentation/routes/validate-definition.js.map +1 -0
  242. package/dist/presentation/subscribers/index.d.ts +3 -0
  243. package/dist/presentation/subscribers/index.d.ts.map +1 -0
  244. package/dist/presentation/subscribers/index.js +4 -0
  245. package/dist/presentation/subscribers/index.js.map +1 -0
  246. package/dist/presentation/subscribers/on-project-source-bound.d.ts +3 -0
  247. package/dist/presentation/subscribers/on-project-source-bound.d.ts.map +1 -0
  248. package/dist/presentation/subscribers/on-project-source-bound.js +11 -0
  249. package/dist/presentation/subscribers/on-project-source-bound.js.map +1 -0
  250. package/dist/presentation/subscribers/on-project-source-commit-observed.d.ts +3 -0
  251. package/dist/presentation/subscribers/on-project-source-commit-observed.d.ts.map +1 -0
  252. package/dist/presentation/subscribers/on-project-source-commit-observed.js +13 -0
  253. package/dist/presentation/subscribers/on-project-source-commit-observed.js.map +1 -0
  254. package/dist/presentation/subscribers/start-definition-sync.d.ts +10 -0
  255. package/dist/presentation/subscribers/start-definition-sync.d.ts.map +1 -0
  256. package/dist/presentation/subscribers/start-definition-sync.js +26 -0
  257. package/dist/presentation/subscribers/start-definition-sync.js.map +1 -0
  258. package/dist/temporal/activities/index.d.ts +3 -0
  259. package/dist/temporal/activities/index.d.ts.map +1 -0
  260. package/dist/temporal/activities/index.js +3 -0
  261. package/dist/temporal/activities/index.js.map +1 -0
  262. package/dist/temporal/activities/sync-activities.d.ts +47 -0
  263. package/dist/temporal/activities/sync-activities.d.ts.map +1 -0
  264. package/dist/temporal/activities/sync-activities.js +128 -0
  265. package/dist/temporal/activities/sync-activities.js.map +1 -0
  266. package/dist/temporal/constants.d.ts +3 -0
  267. package/dist/temporal/constants.d.ts.map +1 -0
  268. package/dist/temporal/constants.js +4 -0
  269. package/dist/temporal/constants.js.map +1 -0
  270. package/dist/temporal/index.d.ts +3 -0
  271. package/dist/temporal/index.d.ts.map +1 -0
  272. package/dist/temporal/index.js +4 -0
  273. package/dist/temporal/index.js.map +1 -0
  274. package/dist/temporal/workflows/definition-sync.d.ts +20 -0
  275. package/dist/temporal/workflows/definition-sync.d.ts.map +1 -0
  276. package/dist/temporal/workflows/definition-sync.js +95 -0
  277. package/dist/temporal/workflows/definition-sync.js.map +1 -0
  278. package/dist/temporal/workflows/index.d.ts +2 -0
  279. package/dist/temporal/workflows/index.d.ts.map +1 -0
  280. package/dist/temporal/workflows/index.js +3 -0
  281. package/dist/temporal/workflows/index.js.map +1 -0
  282. package/dist/tsconfig.test.tsbuildinfo +1 -0
  283. package/drizzle/0000_initial.sql +64 -0
  284. package/drizzle/0001_definition_list_pagination.sql +1 -0
  285. package/drizzle/meta/0000_snapshot.json +527 -0
  286. package/drizzle/meta/_journal.json +20 -0
  287. package/drizzle.config.ts +11 -0
  288. package/package.json +89 -0
  289. package/src/config.test.ts +23 -0
  290. package/src/config.ts +50 -0
  291. package/src/core/entities/index.ts +4 -0
  292. package/src/core/entities/integration-context.ts +21 -0
  293. package/src/core/entities/sync-state.ts +40 -0
  294. package/src/core/entities/workflow-definition.ts +38 -0
  295. package/src/core/entities/workflow-model.ts +162 -0
  296. package/src/core/errors.ts +21 -0
  297. package/src/core/has-agent-step-integrations.ts +7 -0
  298. package/src/core/index.ts +23 -0
  299. package/src/core/parse-definition.test.ts +200 -0
  300. package/src/core/parse-definition.ts +28 -0
  301. package/src/core/sync-definitions.test.ts +390 -0
  302. package/src/core/sync-definitions.ts +216 -0
  303. package/src/core/validate-definition.test.ts +152 -0
  304. package/src/core/validate-definition.ts +72 -0
  305. package/src/core/workflow-model/README.md +129 -0
  306. package/src/core/workflow-model/constants.ts +1 -0
  307. package/src/core/workflow-model/cron-trigger.test.ts +29 -0
  308. package/src/core/workflow-model/cron-trigger.ts +83 -0
  309. package/src/core/workflow-model/index.ts +9 -0
  310. package/src/core/workflow-model/invalid-workflow-model-error.ts +71 -0
  311. package/src/core/workflow-model/map-job-ids.ts +33 -0
  312. package/src/core/workflow-model/normalize-agent-integrations.ts +208 -0
  313. package/src/core/workflow-model/normalize-dependencies.ts +139 -0
  314. package/src/core/workflow-model/normalize-env.ts +48 -0
  315. package/src/core/workflow-model/normalize-if-condition.ts +126 -0
  316. package/src/core/workflow-model/normalize-job-checkout.ts +19 -0
  317. package/src/core/workflow-model/normalize-job-listening.ts +121 -0
  318. package/src/core/workflow-model/normalize-job-success.ts +28 -0
  319. package/src/core/workflow-model/normalize-jobs.ts +1010 -0
  320. package/src/core/workflow-model/normalize-needs.ts +12 -0
  321. package/src/core/workflow-model/normalize-step-gate.ts +90 -0
  322. package/src/core/workflow-model/normalize-step-outputs.ts +36 -0
  323. package/src/core/workflow-model/normalize-triggers.ts +130 -0
  324. package/src/core/workflow-model/normalize-workflow-document.test.ts +4463 -0
  325. package/src/core/workflow-model/normalize-workflow-document.ts +63 -0
  326. package/src/core/workflow-model/parse-duration-ms.ts +58 -0
  327. package/src/core/workflow-model/parse-interpolation-field.ts +566 -0
  328. package/src/core/workflow-model/stable-id.ts +12 -0
  329. package/src/core/workflow-model/validate-job-references.ts +54 -0
  330. package/src/core/workflow-model/validate-predicate-expression.test.ts +161 -0
  331. package/src/core/workflow-model/validate-predicate-expression.ts +406 -0
  332. package/src/core/workflow-model/validation-issue.ts +27 -0
  333. package/src/core/workflow-model/workflow-field-label.ts +50 -0
  334. package/src/core/workflow-yaml/README.md +77 -0
  335. package/src/core/workflow-yaml/index.ts +11 -0
  336. package/src/core/workflow-yaml/invalid-workflow-yaml-error.ts +23 -0
  337. package/src/core/workflow-yaml/parse-workflow-yaml.test.ts +71 -0
  338. package/src/core/workflow-yaml/parse-workflow-yaml.ts +74 -0
  339. package/src/core/workflow-yaml/source-locations.ts +62 -0
  340. package/src/db/db.ts +18 -0
  341. package/src/db/definition-triggers.test.ts +95 -0
  342. package/src/db/definition-triggers.ts +17 -0
  343. package/src/db/definitions.test.ts +1309 -0
  344. package/src/db/definitions.ts +357 -0
  345. package/src/db/index.ts +31 -0
  346. package/src/db/schema/common.ts +3 -0
  347. package/src/db/schema/definitions.test.ts +36 -0
  348. package/src/db/schema/definitions.ts +76 -0
  349. package/src/db/schema/outbox.ts +4 -0
  350. package/src/db/schema/sync-states.ts +79 -0
  351. package/src/db/sync-states.test.ts +90 -0
  352. package/src/db/sync-states.ts +86 -0
  353. package/src/index.ts +104 -0
  354. package/src/presentation/dto/definition.test.ts +59 -0
  355. package/src/presentation/dto/definition.ts +41 -0
  356. package/src/presentation/dto/index.ts +1 -0
  357. package/src/presentation/index.ts +1 -0
  358. package/src/presentation/routes/create-definition.test.ts +356 -0
  359. package/src/presentation/routes/create-definition.ts +101 -0
  360. package/src/presentation/routes/get-definition.test.ts +79 -0
  361. package/src/presentation/routes/get-definition.ts +37 -0
  362. package/src/presentation/routes/index.test.ts +41 -0
  363. package/src/presentation/routes/index.ts +28 -0
  364. package/src/presentation/routes/list-definitions.test.ts +195 -0
  365. package/src/presentation/routes/list-definitions.ts +49 -0
  366. package/src/presentation/routes/validate-definition.test.ts +63 -0
  367. package/src/presentation/routes/validate-definition.ts +46 -0
  368. package/src/presentation/subscribers/index.ts +2 -0
  369. package/src/presentation/subscribers/on-project-source-bound.test.ts +65 -0
  370. package/src/presentation/subscribers/on-project-source-bound.ts +11 -0
  371. package/src/presentation/subscribers/on-project-source-commit-observed.test.ts +56 -0
  372. package/src/presentation/subscribers/on-project-source-commit-observed.ts +15 -0
  373. package/src/presentation/subscribers/start-definition-sync.ts +38 -0
  374. package/src/temporal/activities/index.ts +10 -0
  375. package/src/temporal/activities/sync-activities.test.ts +337 -0
  376. package/src/temporal/activities/sync-activities.ts +206 -0
  377. package/src/temporal/constants.ts +2 -0
  378. package/src/temporal/index.ts +2 -0
  379. package/src/temporal/workflows/definition-sync.test.ts +59 -0
  380. package/src/temporal/workflows/definition-sync.ts +116 -0
  381. package/src/temporal/workflows/index.ts +1 -0
  382. package/test/env.ts +7 -0
  383. package/test/factories/definition.ts +66 -0
  384. package/test/fixtures/invalid-cycle.yml +13 -0
  385. package/test/fixtures/invalid-missing-name.yml +4 -0
  386. package/test/fixtures/invalid-yaml-syntax.yml +6 -0
  387. package/test/fixtures/valid-dag.yml +25 -0
  388. package/test/fixtures/valid-listening-job.yml +21 -0
  389. package/test/fixtures/valid-simple.yml +18 -0
  390. package/test/fixtures/workflow-yaml/invalid/invalid-yaml-syntax.yaml +6 -0
  391. package/test/fixtures/workflow-yaml/invalid/missing-step-run.yaml +5 -0
  392. package/test/fixtures/workflow-yaml/valid/simple-build.document.json +26 -0
  393. package/test/fixtures/workflow-yaml/valid/simple-build.yaml +14 -0
  394. package/test/globalSetup.ts +25 -0
  395. package/test/index.ts +1 -0
  396. package/test/setup.ts +17 -0
  397. package/tsconfig.build.json +9 -0
  398. package/tsconfig.build.tsbuildinfo +1 -0
  399. package/tsconfig.json +3 -0
  400. package/tsconfig.test.json +8 -0
  401. package/vitest.config.ts +11 -0
@@ -0,0 +1,935 @@
1
+ import { agentThinkingByHarness, getHarnessDescriptor, getModelProviderEntry, listEnabledHarnessTools } from '@shipfox/api-agent-dto';
2
+ import { buildTypedRootsEnvironment } from '@shipfox/expression';
3
+ import { canonicalizeLabels, findInvalidLabels, MAX_RUNNER_LABEL_LENGTH, MAX_RUNNER_LABELS, RUNNER_LABEL_PATTERN } from '@shipfox/runner-labels';
4
+ import { normalizeAgentIntegrations } from './normalize-agent-integrations.js';
5
+ import { normalizeEnv } from './normalize-env.js';
6
+ import { normalizeIfCondition } from './normalize-if-condition.js';
7
+ import { normalizeJobCheckout } from './normalize-job-checkout.js';
8
+ import { normalizeJobListening } from './normalize-job-listening.js';
9
+ import { normalizeJobSuccess } from './normalize-job-success.js';
10
+ import { normalizeNeeds } from './normalize-needs.js';
11
+ import { normalizeStepGate } from './normalize-step-gate.js';
12
+ import { normalizeStepOutputs } from './normalize-step-outputs.js';
13
+ import { parseDurationMs } from './parse-duration-ms.js';
14
+ import { parseInterpolationField } from './parse-interpolation-field.js';
15
+ import { stableId } from './stable-id.js';
16
+ import { issue } from './validation-issue.js';
17
+ export function normalizeJobs(document, jobIdBySourceName, issues, stepSourceLocations, context) {
18
+ const entries = Object.entries(document.jobs);
19
+ const pending = new Set(entries.map(([sourceName])=>sourceName));
20
+ const modelsBySourceName = new Map();
21
+ const jobOutputTypesBySourceName = new Map();
22
+ const issuesBySourceName = new Map();
23
+ while(pending.size > 0){
24
+ let progressed = false;
25
+ for (const [sourceName, job] of entries){
26
+ if (!pending.has(sourceName)) continue;
27
+ const dependencySourceNames = normalizeNeeds(job.needs).filter((dependency)=>jobIdBySourceName.has(dependency));
28
+ if (dependencySourceNames.some((dependency)=>pending.has(dependency))) continue;
29
+ const model = normalizeJob({
30
+ document,
31
+ sourceName,
32
+ job,
33
+ jobIdBySourceName,
34
+ issues: issuesForSourceName(issuesBySourceName, sourceName),
35
+ stepSourceLocations,
36
+ context,
37
+ jobOutputTypesBySourceName
38
+ });
39
+ if (model !== undefined) modelsBySourceName.set(sourceName, model);
40
+ pending.delete(sourceName);
41
+ progressed = true;
42
+ }
43
+ if (progressed) continue;
44
+ for (const sourceName of pending){
45
+ const job = document.jobs[sourceName];
46
+ if (job === undefined) continue;
47
+ const model = normalizeJob({
48
+ document,
49
+ sourceName,
50
+ job,
51
+ jobIdBySourceName,
52
+ issues: issuesForSourceName(issuesBySourceName, sourceName),
53
+ stepSourceLocations,
54
+ context,
55
+ jobOutputTypesBySourceName
56
+ });
57
+ if (model !== undefined) modelsBySourceName.set(sourceName, model);
58
+ }
59
+ break;
60
+ }
61
+ for (const [sourceName] of entries){
62
+ issues.push(...issuesBySourceName.get(sourceName) ?? []);
63
+ }
64
+ return entries.flatMap(([sourceName])=>{
65
+ const model = modelsBySourceName.get(sourceName);
66
+ return model === undefined ? [] : [
67
+ model
68
+ ];
69
+ });
70
+ }
71
+ function issuesForSourceName(issuesBySourceName, sourceName) {
72
+ const existing = issuesBySourceName.get(sourceName);
73
+ if (existing !== undefined) return existing;
74
+ const issues = [];
75
+ issuesBySourceName.set(sourceName, issues);
76
+ return issues;
77
+ }
78
+ function normalizeJob(params) {
79
+ const id = params.jobIdBySourceName.get(params.sourceName);
80
+ if (id === undefined) return undefined;
81
+ const dependencies = normalizeJobDependencies({
82
+ sourceName: params.sourceName,
83
+ job: params.job,
84
+ jobIdBySourceName: params.jobIdBySourceName
85
+ });
86
+ const allowedJobReferences = directNeedSourceNames({
87
+ sourceName: params.sourceName,
88
+ job: params.job,
89
+ jobIdBySourceName: params.jobIdBySourceName
90
+ });
91
+ const upstreamJobs = upstreamJobTypeOverlays({
92
+ allowedJobReferences,
93
+ jobOutputTypesBySourceName: params.jobOutputTypesBySourceName
94
+ });
95
+ const directNeedJobs = directNeedJobTypeOverlays({
96
+ allowedJobReferences,
97
+ jobOutputTypesBySourceName: params.jobOutputTypesBySourceName
98
+ });
99
+ const upstreamJobsTypeOverlay = upstreamJobs.length === 0 ? undefined : buildTypedRootsEnvironment({
100
+ jobs: upstreamJobs
101
+ });
102
+ const jobConditionTypeOverlay = buildTypedRootsEnvironment({
103
+ jobs: directNeedJobs,
104
+ needs: directNeedJobs
105
+ });
106
+ // Step config can reference peer step outputs, which are completed at dispatch.
107
+ const stepFillSite = 'step-dispatch';
108
+ const stepTypeOverlay = params.job.steps.some((step)=>step.outputs !== undefined) ? {} : undefined;
109
+ const steps = normalizeJobSteps({
110
+ sourceName: params.sourceName,
111
+ jobId: id,
112
+ job: params.job,
113
+ issues: params.issues,
114
+ stepSourceLocations: params.stepSourceLocations,
115
+ fillSite: stepFillSite,
116
+ allowedJobReferences,
117
+ typeOverlay: stepTypeOverlay,
118
+ upstreamJobs,
119
+ directNeedJobs,
120
+ context: params.context
121
+ });
122
+ const runner = normalizeRunner({
123
+ document: params.document,
124
+ job: params.job,
125
+ sourceName: params.sourceName,
126
+ issues: params.issues,
127
+ defaultRunnerLabels: params.context.defaultRunnerLabels
128
+ });
129
+ const checkout = normalizeJobCheckout(params.job.checkout);
130
+ const jobEnv = normalizeEnv({
131
+ env: params.job.env,
132
+ path: [
133
+ 'jobs',
134
+ params.sourceName,
135
+ 'env'
136
+ ],
137
+ issues: params.issues,
138
+ allowedJobReferences,
139
+ typeOverlay: upstreamJobsTypeOverlay
140
+ });
141
+ const success = normalizeJobSuccess({
142
+ source: params.job.success,
143
+ sourceName: params.sourceName,
144
+ issues: params.issues,
145
+ allowedJobReferences,
146
+ typeOverlay: upstreamJobsTypeOverlay
147
+ });
148
+ const condition = normalizeIfCondition({
149
+ field: 'job.if',
150
+ source: params.job.if,
151
+ site: 'job-activation',
152
+ path: [
153
+ 'jobs',
154
+ params.sourceName,
155
+ 'if'
156
+ ],
157
+ invalidCode: 'invalid-job-if',
158
+ invalidMessage: 'Job if must be a valid wrapped CEL boolean expression.',
159
+ issues: params.issues,
160
+ allowedJobReferences,
161
+ typeOverlay: jobConditionTypeOverlay
162
+ });
163
+ const outputs = normalizeJobOutputs({
164
+ sourceName: params.sourceName,
165
+ outputs: params.job.outputs,
166
+ issues: params.issues,
167
+ allowedJobReferences,
168
+ steps: params.job.steps,
169
+ upstreamJobs
170
+ });
171
+ if (outputs?.types !== undefined) {
172
+ params.jobOutputTypesBySourceName.set(params.sourceName, outputs.types);
173
+ }
174
+ const executionTimeoutMs = parseDurationMs({
175
+ source: params.job.execution_timeout,
176
+ path: [
177
+ 'jobs',
178
+ params.sourceName,
179
+ 'execution_timeout'
180
+ ],
181
+ issues: params.issues
182
+ });
183
+ const listening = normalizeJobListening({
184
+ job: params.job,
185
+ sourceName: params.sourceName,
186
+ issues: params.issues,
187
+ allowedJobReferences
188
+ });
189
+ const name = params.job.name === undefined ? undefined : parseInterpolationField({
190
+ field: 'job.name',
191
+ source: params.job.name,
192
+ path: [
193
+ 'jobs',
194
+ params.sourceName,
195
+ 'name'
196
+ ],
197
+ issues: params.issues,
198
+ allowedJobReferences,
199
+ typeOverlay: upstreamJobsTypeOverlay
200
+ }) ?? [
201
+ {
202
+ kind: 'literal',
203
+ value: params.job.name
204
+ }
205
+ ];
206
+ return {
207
+ id,
208
+ key: params.sourceName,
209
+ mode: listening === undefined ? 'one_shot' : 'listening',
210
+ runner: runner.labels,
211
+ ...runner.templates.length === 0 ? {} : {
212
+ runnerTemplates: runner.templates
213
+ },
214
+ checkout,
215
+ ...condition === undefined ? {} : {
216
+ if: condition
217
+ },
218
+ ...success === undefined ? {} : {
219
+ success
220
+ },
221
+ ...outputs === undefined ? {} : {
222
+ outputs: outputs.templates
223
+ },
224
+ ...outputs?.types === undefined ? {} : {
225
+ outputTypes: outputs.types
226
+ },
227
+ ...executionTimeoutMs === undefined ? {} : {
228
+ executionTimeoutMs
229
+ },
230
+ ...listening === undefined ? {} : {
231
+ listening
232
+ },
233
+ ...name === undefined ? {} : {
234
+ name
235
+ },
236
+ ...jobEnv,
237
+ dependencies,
238
+ steps
239
+ };
240
+ }
241
+ function normalizeJobDependencies(params) {
242
+ return normalizeNeeds(params.job.needs).flatMap((dependencySourceName)=>{
243
+ const dependencyId = params.jobIdBySourceName.get(dependencySourceName);
244
+ if (dependencyId === undefined || dependencySourceName === params.sourceName) return [];
245
+ return [
246
+ dependencyId
247
+ ];
248
+ });
249
+ }
250
+ function directNeedSourceNames(params) {
251
+ return new Set(normalizeNeeds(params.job.needs).filter((dependencySourceName)=>dependencySourceName !== params.sourceName && params.jobIdBySourceName.has(dependencySourceName)));
252
+ }
253
+ function previousStepOverlays(steps, index) {
254
+ return steps.slice(0, index).flatMap((step)=>{
255
+ if (step.key === undefined) return [];
256
+ return [
257
+ {
258
+ key: step.key,
259
+ ...step.outputs === undefined ? {} : {
260
+ outputs: step.outputs
261
+ }
262
+ }
263
+ ];
264
+ });
265
+ }
266
+ function allStepOverlays(steps) {
267
+ return previousStepOverlays(steps, steps.length);
268
+ }
269
+ function upstreamJobTypeOverlays(params) {
270
+ const overlays = [
271
+ ...params.allowedJobReferences
272
+ ].map((sourceName)=>{
273
+ const outputs = params.jobOutputTypesBySourceName.get(sourceName);
274
+ return {
275
+ key: sourceName,
276
+ ...outputs === undefined ? {} : {
277
+ outputs
278
+ }
279
+ };
280
+ });
281
+ return overlays.some((overlay)=>overlay.outputs !== undefined) ? overlays : [];
282
+ }
283
+ function directNeedJobTypeOverlays(params) {
284
+ return [
285
+ ...params.allowedJobReferences
286
+ ].map((sourceName)=>{
287
+ const outputs = params.jobOutputTypesBySourceName.get(sourceName);
288
+ return {
289
+ key: sourceName,
290
+ ...outputs === undefined ? {} : {
291
+ outputs
292
+ }
293
+ };
294
+ });
295
+ }
296
+ function normalizeJobOutputs(params) {
297
+ if (params.outputs === undefined) return undefined;
298
+ const templates = Object.create(null);
299
+ const types = Object.create(null);
300
+ const hasStepOutputDeclarations = params.steps.some((step)=>step.outputs !== undefined);
301
+ const typeOverlay = hasStepOutputDeclarations || params.upstreamJobs.length > 0 ? buildTypedRootsEnvironment({
302
+ ...hasStepOutputDeclarations ? {
303
+ steps: allStepOverlays(params.steps)
304
+ } : {},
305
+ ...params.upstreamJobs.length === 0 ? {} : {
306
+ jobs: params.upstreamJobs
307
+ }
308
+ }) : undefined;
309
+ for (const [key, source] of Object.entries(params.outputs)){
310
+ const template = parseInterpolationField({
311
+ field: 'job.outputs',
312
+ source,
313
+ path: [
314
+ 'jobs',
315
+ params.sourceName,
316
+ 'outputs',
317
+ key
318
+ ],
319
+ issues: params.issues,
320
+ fillSite: 'execution-resolution',
321
+ allowedJobReferences: params.allowedJobReferences,
322
+ typeOverlay
323
+ }) ?? [
324
+ {
325
+ kind: 'literal',
326
+ value: source
327
+ }
328
+ ];
329
+ templates[key] = template;
330
+ types[key] = inferJobOutputType({
331
+ sourceName: params.sourceName,
332
+ key,
333
+ source,
334
+ template,
335
+ issues: params.issues
336
+ });
337
+ }
338
+ return {
339
+ templates,
340
+ types
341
+ };
342
+ }
343
+ function inferJobOutputType(params) {
344
+ if (params.template.length !== 1) return 'string';
345
+ const [segment] = params.template;
346
+ if (segment?.kind !== 'deferred') return 'string';
347
+ const resultType = segment.expression.resultType;
348
+ if (resultType === undefined) return 'string';
349
+ if (isScalarExpressionType(resultType)) return resultType;
350
+ params.issues.push(issue({
351
+ code: 'invalid-job-output',
352
+ message: `Job output "${params.key}" must resolve to a scalar value.`,
353
+ path: [
354
+ 'jobs',
355
+ params.sourceName,
356
+ 'outputs',
357
+ params.key
358
+ ],
359
+ details: {
360
+ output: params.key,
361
+ source: params.source
362
+ }
363
+ }));
364
+ return 'string';
365
+ }
366
+ function isScalarExpressionType(type) {
367
+ return type === 'string' || type === 'int' || type === 'double' || type === 'bool' || type === 'null' || type === 'timestamp';
368
+ }
369
+ function normalizeJobSteps(params) {
370
+ const usedStepIds = new Map();
371
+ return params.job.steps.map((step, index)=>normalizeStep({
372
+ step,
373
+ index,
374
+ sourceName: params.sourceName,
375
+ jobId: params.jobId,
376
+ allSteps: params.job.steps,
377
+ usedStepIds,
378
+ issues: params.issues,
379
+ stepSourceLocations: params.stepSourceLocations,
380
+ fillSite: params.fillSite,
381
+ allowedJobReferences: params.allowedJobReferences,
382
+ typeOverlay: params.typeOverlay,
383
+ upstreamJobs: params.upstreamJobs,
384
+ directNeedJobs: params.directNeedJobs,
385
+ context: params.context
386
+ }));
387
+ }
388
+ function normalizeStep(params) {
389
+ const stepKey = params.step.key;
390
+ const stepId = stepKey === undefined ? `${params.jobId}-step-${params.index + 1}` : `${params.jobId}-${stableId(stepKey)}`;
391
+ const existingIndex = params.usedStepIds.get(stepId);
392
+ if (existingIndex !== undefined) {
393
+ params.issues.push(issue({
394
+ code: 'duplicate-step-id',
395
+ message: `Steps ${existingIndex} and ${params.index} in job "${params.sourceName}" resolve to the same stable id "${stepId}".`,
396
+ path: [
397
+ 'jobs',
398
+ params.sourceName,
399
+ 'steps',
400
+ params.index
401
+ ],
402
+ details: {
403
+ id: stepId,
404
+ indexes: [
405
+ existingIndex,
406
+ params.index
407
+ ]
408
+ }
409
+ }));
410
+ } else {
411
+ params.usedStepIds.set(stepId, params.index);
412
+ }
413
+ const outputs = normalizeStepOutputs({
414
+ step: params.step,
415
+ sourceName: params.sourceName,
416
+ stepIndex: params.index,
417
+ issues: params.issues
418
+ });
419
+ const currentStepOverlay = stepKey === undefined ? undefined : {
420
+ key: stepKey,
421
+ ...outputs === undefined ? {} : {
422
+ outputs
423
+ }
424
+ };
425
+ const shouldBuildTypeOverlay = params.typeOverlay !== undefined || params.upstreamJobs.length > 0;
426
+ const typeOverlay = !shouldBuildTypeOverlay ? undefined : buildTypedRootsEnvironment({
427
+ steps: previousStepOverlays(params.allSteps, params.index),
428
+ ...currentStepOverlay === undefined ? {} : {
429
+ currentStep: currentStepOverlay
430
+ },
431
+ ...params.upstreamJobs.length === 0 ? {} : {
432
+ jobs: params.upstreamJobs
433
+ }
434
+ });
435
+ const conditionTypeOverlay = buildTypedRootsEnvironment({
436
+ steps: previousStepOverlays(params.allSteps, params.index),
437
+ ...currentStepOverlay === undefined ? {} : {
438
+ currentStep: currentStepOverlay
439
+ },
440
+ jobs: params.directNeedJobs,
441
+ needs: params.directNeedJobs
442
+ });
443
+ const condition = normalizeIfCondition({
444
+ field: 'step.if',
445
+ source: params.step.if,
446
+ site: 'step-dispatch',
447
+ path: [
448
+ 'jobs',
449
+ params.sourceName,
450
+ 'steps',
451
+ params.index,
452
+ 'if'
453
+ ],
454
+ invalidCode: 'invalid-step-if',
455
+ invalidMessage: 'Step if must be a valid wrapped CEL boolean expression.',
456
+ issues: params.issues,
457
+ allowedJobReferences: params.allowedJobReferences,
458
+ typeOverlay: conditionTypeOverlay
459
+ });
460
+ const gate = normalizeStepGate({
461
+ step: params.step,
462
+ sourceName: params.sourceName,
463
+ stepIndex: params.index,
464
+ stepId,
465
+ previousStepKeys: new Set(params.allSteps.slice(0, params.index).flatMap((candidate)=>candidate.key ? [
466
+ candidate.key
467
+ ] : [])),
468
+ issues: params.issues,
469
+ allowedJobReferences: params.allowedJobReferences,
470
+ typeOverlay
471
+ });
472
+ const sourceLocation = params.stepSourceLocations?.get(params.sourceName)?.get(params.index);
473
+ const name = params.step.name === undefined ? undefined : parseInterpolationField({
474
+ field: 'step.name',
475
+ source: params.step.name,
476
+ path: [
477
+ 'jobs',
478
+ params.sourceName,
479
+ 'steps',
480
+ params.index,
481
+ 'name'
482
+ ],
483
+ issues: params.issues,
484
+ fillSite: params.fillSite,
485
+ allowedJobReferences: params.allowedJobReferences,
486
+ typeOverlay
487
+ });
488
+ const stepBase = {
489
+ id: stepId,
490
+ ...stepKey === undefined ? {} : {
491
+ key: stepKey
492
+ },
493
+ ...params.step.name === undefined ? {} : {
494
+ name: params.step.name
495
+ },
496
+ ...outputs === undefined ? {} : {
497
+ outputs
498
+ },
499
+ ...sourceLocation === undefined ? {} : {
500
+ sourceLocation
501
+ },
502
+ ...condition === undefined ? {} : {
503
+ if: condition
504
+ },
505
+ ...gate === undefined ? {} : {
506
+ gate
507
+ }
508
+ };
509
+ if (params.step.run !== undefined) {
510
+ return normalizeRunStep({
511
+ step: params.step,
512
+ stepBase,
513
+ sourceName: params.sourceName,
514
+ stepIndex: params.index,
515
+ name,
516
+ issues: params.issues,
517
+ fillSite: params.fillSite,
518
+ allowedJobReferences: params.allowedJobReferences,
519
+ typeOverlay
520
+ });
521
+ }
522
+ if (params.step.prompt !== undefined) {
523
+ return normalizeAgentStep({
524
+ step: params.step,
525
+ stepBase,
526
+ sourceName: params.sourceName,
527
+ stepIndex: params.index,
528
+ name,
529
+ issues: params.issues,
530
+ fillSite: params.fillSite,
531
+ allowedJobReferences: params.allowedJobReferences,
532
+ typeOverlay,
533
+ context: params.context
534
+ });
535
+ }
536
+ // workflowDocumentStepSchema requires either `run` or an agent `prompt`; this
537
+ // keeps the model-step union honest if callers bypass the document parser.
538
+ throw new Error(`Workflow step "${stepId}" is neither a run nor an agent step`);
539
+ }
540
+ function normalizeRunStep(params) {
541
+ if (params.step.run === undefined) {
542
+ throw new Error('Run step normalization requires a run command');
543
+ }
544
+ const commandTemplate = parseInterpolationField({
545
+ field: 'run',
546
+ source: params.step.run,
547
+ path: [
548
+ 'jobs',
549
+ params.sourceName,
550
+ 'steps',
551
+ params.stepIndex,
552
+ 'run'
553
+ ],
554
+ issues: params.issues,
555
+ fillSite: params.fillSite,
556
+ allowedJobReferences: params.allowedJobReferences,
557
+ typeOverlay: params.typeOverlay
558
+ });
559
+ const stepEnv = normalizeEnv({
560
+ env: params.step.env,
561
+ path: [
562
+ 'jobs',
563
+ params.sourceName,
564
+ 'steps',
565
+ params.stepIndex,
566
+ 'env'
567
+ ],
568
+ issues: params.issues,
569
+ fillSite: params.fillSite,
570
+ allowedJobReferences: params.allowedJobReferences,
571
+ typeOverlay: params.typeOverlay
572
+ });
573
+ const templates = optionalRunStepTemplates({
574
+ command: commandTemplate,
575
+ name: params.name,
576
+ env: stepEnv.templates?.env
577
+ });
578
+ return {
579
+ ...params.stepBase,
580
+ kind: 'run',
581
+ command: {
582
+ kind: 'shell',
583
+ value: params.step.run
584
+ },
585
+ ...stepEnv.env === undefined ? {} : {
586
+ env: stepEnv.env
587
+ },
588
+ ...templates === undefined ? {} : {
589
+ templates
590
+ }
591
+ };
592
+ }
593
+ function normalizeAgentStep(params) {
594
+ if (params.step.prompt === undefined) {
595
+ throw new Error('Agent step normalization requires a prompt');
596
+ }
597
+ const promptTemplate = parseInterpolationField({
598
+ field: 'agent.prompt',
599
+ source: params.step.prompt,
600
+ path: [
601
+ 'jobs',
602
+ params.sourceName,
603
+ 'steps',
604
+ params.stepIndex,
605
+ 'prompt'
606
+ ],
607
+ issues: params.issues,
608
+ fillSite: params.fillSite,
609
+ allowedJobReferences: params.allowedJobReferences,
610
+ typeOverlay: params.typeOverlay
611
+ });
612
+ const modelTemplate = params.step.model === undefined ? undefined : parseInterpolationField({
613
+ field: 'agent.model',
614
+ source: params.step.model,
615
+ path: [
616
+ 'jobs',
617
+ params.sourceName,
618
+ 'steps',
619
+ params.stepIndex,
620
+ 'model'
621
+ ],
622
+ issues: params.issues,
623
+ fillSite: params.fillSite,
624
+ allowedJobReferences: params.allowedJobReferences,
625
+ typeOverlay: params.typeOverlay
626
+ });
627
+ const providerTemplate = params.step.provider === undefined ? undefined : parseInterpolationField({
628
+ field: 'agent.provider',
629
+ source: params.step.provider,
630
+ path: [
631
+ 'jobs',
632
+ params.sourceName,
633
+ 'steps',
634
+ params.stepIndex,
635
+ 'provider'
636
+ ],
637
+ issues: params.issues,
638
+ fillSite: params.fillSite,
639
+ allowedJobReferences: params.allowedJobReferences,
640
+ typeOverlay: params.typeOverlay
641
+ });
642
+ validateAgentStep({
643
+ step: params.step,
644
+ sourceName: params.sourceName,
645
+ stepIndex: params.stepIndex,
646
+ issues: params.issues,
647
+ validateLiteralProvider: providerTemplate === undefined,
648
+ harnessToolDeploymentConfig: params.context.harnessToolDeploymentConfig
649
+ });
650
+ const integrations = normalizeAgentIntegrations({
651
+ integrations: params.step.integrations,
652
+ sourceName: params.sourceName,
653
+ stepIndex: params.stepIndex,
654
+ issues: params.issues,
655
+ integrationValidationContext: params.context.integrationValidationContext
656
+ });
657
+ const templates = optionalAgentStepTemplates({
658
+ prompt: promptTemplate,
659
+ model: modelTemplate,
660
+ provider: providerTemplate,
661
+ name: params.name
662
+ });
663
+ return {
664
+ ...params.stepBase,
665
+ kind: 'agent',
666
+ ...params.step.harness === undefined ? {} : {
667
+ harness: params.step.harness
668
+ },
669
+ ...params.step.model === undefined ? {} : {
670
+ model: params.step.model
671
+ },
672
+ ...params.step.provider === undefined ? {} : {
673
+ provider: params.step.provider
674
+ },
675
+ prompt: params.step.prompt,
676
+ ...params.step.thinking === undefined ? {} : {
677
+ thinking: params.step.thinking
678
+ },
679
+ ...params.step.tools === undefined ? {} : {
680
+ tools: params.step.tools
681
+ },
682
+ ...integrations === undefined ? {} : {
683
+ integrations
684
+ },
685
+ ...templates === undefined ? {} : {
686
+ templates
687
+ }
688
+ };
689
+ }
690
+ function validateAgentStep(params) {
691
+ validateHarnessThinking(params);
692
+ validateHarnessTools(params);
693
+ if (!params.validateLiteralProvider) return;
694
+ const providerId = params.step.provider;
695
+ if (providerId === undefined) return;
696
+ const provider = getModelProviderEntry(providerId);
697
+ const harness = params.step.harness;
698
+ if (provider === undefined && harness === 'pi') return;
699
+ if (provider === undefined || provider.support_status !== 'supported') {
700
+ params.issues.push(issue({
701
+ code: 'invalid-provider',
702
+ message: `Provider "${providerId}" is not supported.`,
703
+ path: [
704
+ 'jobs',
705
+ params.sourceName,
706
+ 'steps',
707
+ params.stepIndex,
708
+ 'provider'
709
+ ],
710
+ details: {
711
+ provider: providerId
712
+ }
713
+ }));
714
+ return;
715
+ }
716
+ if (harness === undefined) return;
717
+ const descriptor = getHarnessDescriptor(harness);
718
+ if (descriptor.supportedProviderIds.includes(providerId)) return;
719
+ params.issues.push(issue({
720
+ code: 'harness-provider-incompatible',
721
+ message: `Harness "${harness}" does not support provider: ${providerId}. Supported providers: ${descriptor.supportedProviderIds.join(', ')}.`,
722
+ path: [
723
+ 'jobs',
724
+ params.sourceName,
725
+ 'steps',
726
+ params.stepIndex,
727
+ 'provider'
728
+ ],
729
+ details: {
730
+ harness,
731
+ provider: providerId,
732
+ supportedProviders: descriptor.supportedProviderIds
733
+ }
734
+ }));
735
+ }
736
+ function validateHarnessTools(params) {
737
+ const { harness, tools } = params.step;
738
+ if (tools === undefined) return;
739
+ if (harness === undefined) {
740
+ params.issues.push(issue({
741
+ code: 'missing-harness-for-tools',
742
+ message: 'Agent step tools require an explicit harness because tool names are harness-specific.',
743
+ path: [
744
+ 'jobs',
745
+ params.sourceName,
746
+ 'steps',
747
+ params.stepIndex,
748
+ 'tools'
749
+ ],
750
+ details: {
751
+ tools
752
+ }
753
+ }));
754
+ return;
755
+ }
756
+ const supportedTools = listEnabledHarnessTools(harness, params.harnessToolDeploymentConfig).map((tool)=>tool.name);
757
+ const supportedToolSet = new Set(supportedTools);
758
+ tools.forEach((tool, toolIndex)=>{
759
+ if (supportedToolSet.has(tool)) return;
760
+ params.issues.push(issue({
761
+ code: 'harness-tool-incompatible',
762
+ message: `Harness "${harness}" does not support tool: ${tool}. Supported tools: ${supportedTools.join(', ')}.`,
763
+ path: [
764
+ 'jobs',
765
+ params.sourceName,
766
+ 'steps',
767
+ params.stepIndex,
768
+ 'tools',
769
+ toolIndex
770
+ ],
771
+ details: {
772
+ harness,
773
+ tool,
774
+ supportedTools
775
+ }
776
+ }));
777
+ });
778
+ }
779
+ function validateHarnessThinking(params) {
780
+ const { harness, thinking } = params.step;
781
+ if (harness === undefined || thinking === undefined) return;
782
+ const thinkingSchema = agentThinkingByHarness[harness];
783
+ if (thinkingSchema.safeParse(thinking).success) return;
784
+ const supportedLevels = thinkingSchema.options;
785
+ params.issues.push(issue({
786
+ code: 'harness-thinking-incompatible',
787
+ message: `Harness "${harness}" does not support thinking: ${thinking}. Supported levels: ${supportedLevels.join(', ')}.`,
788
+ path: [
789
+ 'jobs',
790
+ params.sourceName,
791
+ 'steps',
792
+ params.stepIndex,
793
+ 'thinking'
794
+ ],
795
+ details: {
796
+ harness,
797
+ thinking,
798
+ supportedLevels
799
+ }
800
+ }));
801
+ }
802
+ function normalizeRunner(params) {
803
+ const rawRunner = params.job.runner ?? params.document.runner;
804
+ if (rawRunner === undefined) {
805
+ const runnerLabels = params.defaultRunnerLabels;
806
+ validateRunnerLabels({
807
+ ...params,
808
+ runnerLabels,
809
+ allowEmpty: false
810
+ });
811
+ return {
812
+ labels: runnerLabels,
813
+ templates: []
814
+ };
815
+ }
816
+ const runnerValues = typeof rawRunner === 'string' ? [
817
+ rawRunner
818
+ ] : rawRunner;
819
+ const literalLabels = [];
820
+ const templates = [];
821
+ let templateValueCount = 0;
822
+ for (const [index, value] of runnerValues.entries()){
823
+ const template = parseInterpolationField({
824
+ field: 'job.runner',
825
+ source: value,
826
+ path: [
827
+ 'jobs',
828
+ params.sourceName,
829
+ 'runner',
830
+ index
831
+ ],
832
+ issues: params.issues,
833
+ fillSite: 'execution-creation'
834
+ });
835
+ const hasTemplateSyntax = hasInterpolationSyntax(value);
836
+ if (hasTemplateSyntax) templateValueCount += 1;
837
+ if (template === undefined && !hasTemplateSyntax) {
838
+ literalLabels.push(value);
839
+ } else if (template !== undefined) {
840
+ templates.push(template);
841
+ }
842
+ }
843
+ const runnerLabels = canonicalizeLabels(literalLabels);
844
+ validateRunnerLabels({
845
+ ...params,
846
+ runnerLabels,
847
+ runnerLabelCount: runnerLabels.length + templates.length,
848
+ allowEmpty: templateValueCount > 0
849
+ });
850
+ return {
851
+ labels: runnerLabels,
852
+ templates
853
+ };
854
+ }
855
+ function hasInterpolationSyntax(value) {
856
+ return value.includes('${{');
857
+ }
858
+ function validateRunnerLabels(params) {
859
+ const runnerLabels = params.runnerLabels;
860
+ const runnerLabelCount = params.runnerLabelCount ?? runnerLabels.length;
861
+ const invalid = findInvalidLabels(runnerLabels);
862
+ if (invalid.length > 0) {
863
+ params.issues.push(issue({
864
+ code: 'invalid-runner-label',
865
+ message: `Job "${params.sourceName}" has invalid runner label(s): ${invalid.join(', ')}. Labels must match ${RUNNER_LABEL_PATTERN} and be at most ${MAX_RUNNER_LABEL_LENGTH} chars.`,
866
+ path: [
867
+ 'jobs',
868
+ params.sourceName,
869
+ 'runner'
870
+ ],
871
+ details: {
872
+ labels: invalid
873
+ }
874
+ }));
875
+ }
876
+ if (runnerLabels.length === 0 && !params.allowEmpty) {
877
+ params.issues.push(issue({
878
+ code: 'missing-runner-label',
879
+ message: `Job "${params.sourceName}" must declare at least one runner label. Set "runner" on the job or the workflow, or configure DEFINITION_DEFAULT_RUNNER_LABEL.`,
880
+ path: [
881
+ 'jobs',
882
+ params.sourceName,
883
+ 'runner'
884
+ ]
885
+ }));
886
+ }
887
+ if (runnerLabelCount > MAX_RUNNER_LABELS) {
888
+ params.issues.push(issue({
889
+ code: 'too-many-runner-labels',
890
+ message: `Job "${params.sourceName}" declares ${runnerLabelCount} runner labels; the maximum is ${MAX_RUNNER_LABELS}.`,
891
+ path: [
892
+ 'jobs',
893
+ params.sourceName,
894
+ 'runner'
895
+ ]
896
+ }));
897
+ }
898
+ }
899
+ function optionalRunStepTemplates(params) {
900
+ if (params.command === undefined && params.name === undefined && params.env === undefined) {
901
+ return undefined;
902
+ }
903
+ return {
904
+ ...params.command === undefined ? {} : {
905
+ command: params.command
906
+ },
907
+ ...params.name === undefined ? {} : {
908
+ name: params.name
909
+ },
910
+ ...params.env === undefined ? {} : {
911
+ env: params.env
912
+ }
913
+ };
914
+ }
915
+ function optionalAgentStepTemplates(params) {
916
+ if (params.prompt === undefined && params.model === undefined && params.provider === undefined && params.name === undefined) {
917
+ return undefined;
918
+ }
919
+ return {
920
+ ...params.prompt === undefined ? {} : {
921
+ prompt: params.prompt
922
+ },
923
+ ...params.model === undefined ? {} : {
924
+ model: params.model
925
+ },
926
+ ...params.provider === undefined ? {} : {
927
+ provider: params.provider
928
+ },
929
+ ...params.name === undefined ? {} : {
930
+ name: params.name
931
+ }
932
+ };
933
+ }
934
+
935
+ //# sourceMappingURL=normalize-jobs.js.map