@oisincoveney/pipeline 3.24.2 → 3.24.3

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 (326) hide show
  1. package/README.md +2 -2
  2. package/defaults/pipeline.yaml +23 -5
  3. package/defaults/profiles.yaml +104 -21
  4. package/dist/argo-graph.js +88 -88
  5. package/dist/argo-submit.d.ts +109 -137
  6. package/dist/argo-submit.js +337 -360
  7. package/dist/argo-workflow.d.ts +156 -176
  8. package/dist/argo-workflow.js +96 -138
  9. package/dist/backlog.js +5 -4
  10. package/dist/bench/eval-report.js +21 -12
  11. package/dist/claude-settings-config.js +23 -31
  12. package/dist/claude-user-config.js +6 -16
  13. package/dist/cli/bootstrap-commands.js +3 -3
  14. package/dist/cli/doctor.d.ts +1 -1
  15. package/dist/cli/doctor.js +172 -169
  16. package/dist/cli/factory-commands.js +12 -11
  17. package/dist/cli/format.js +92 -86
  18. package/dist/cli/loop-commands.js +21 -21
  19. package/dist/cli/mcp-gateway-commands.js +12 -12
  20. package/dist/cli/plan-commands.js +85 -116
  21. package/dist/cli/program.d.ts +2 -2
  22. package/dist/cli/program.js +35 -43
  23. package/dist/cli/run-command.js +25 -25
  24. package/dist/cli/run-commands.js +25 -25
  25. package/dist/cli/run-resolver.d.ts +1 -1
  26. package/dist/cli/run-resolver.js +30 -32
  27. package/dist/cli/run-service.d.ts +2 -2
  28. package/dist/cli/run-service.js +226 -239
  29. package/dist/cli/submit-options.js +78 -82
  30. package/dist/cluster-doctor.js +147 -175
  31. package/dist/codex-config.js +24 -30
  32. package/dist/commands/bench-command.js +9 -7
  33. package/dist/commands/pipeline-command.js +9 -5
  34. package/dist/commands/runner-command-command.js +28 -18
  35. package/dist/commands/ticket/complete.js +29 -33
  36. package/dist/commands/ticket/create.js +82 -82
  37. package/dist/commands/ticket/graph-check.js +11 -11
  38. package/dist/commands/ticket/next.js +36 -36
  39. package/dist/commands/ticket/sequence.js +10 -12
  40. package/dist/commands/ticket/shared.d.ts +1 -1
  41. package/dist/commands/ticket/shared.js +63 -66
  42. package/dist/commands/ticket/start.js +58 -67
  43. package/dist/commands/ticket-command.js +2 -2
  44. package/dist/config/defaults.d.ts +139 -139
  45. package/dist/config/defaults.js +81 -80
  46. package/dist/config/lint.js +52 -64
  47. package/dist/config/load.d.ts +4 -4
  48. package/dist/config/load.js +62 -74
  49. package/dist/config/schema/catalog.js +1 -1
  50. package/dist/config/schema/mcp.js +46 -52
  51. package/dist/config/schemas.d.ts +375 -525
  52. package/dist/config/schemas.js +397 -397
  53. package/dist/config/validate.d.ts +1 -1
  54. package/dist/config/validate.js +236 -201
  55. package/dist/context/repo-map.js +102 -119
  56. package/dist/credentials/broker.d.ts +6 -8
  57. package/dist/credentials/broker.js +17 -16
  58. package/dist/credentials/codex-config.js +15 -19
  59. package/dist/credentials/file-targets.js +9 -15
  60. package/dist/credentials/local-codex-auth-sync.js +55 -58
  61. package/dist/credentials/opencode-config.js +28 -32
  62. package/dist/credentials/runner.js +13 -13
  63. package/dist/effect-sync-errors.js +28 -0
  64. package/dist/factory/create-experiment.js +38 -42
  65. package/dist/factory/exec.js +10 -12
  66. package/dist/factory/git-credentials.js +4 -4
  67. package/dist/factory/stamp-answers.js +10 -11
  68. package/dist/factory/template-update.js +65 -44
  69. package/dist/factory-lane.d.ts +26 -40
  70. package/dist/factory-lane.js +26 -25
  71. package/dist/gates.js +3 -3
  72. package/dist/git-remote-url.js +17 -19
  73. package/dist/hooks.d.ts +26 -25
  74. package/dist/hooks.js +20 -22
  75. package/dist/index.d.ts +1 -1
  76. package/dist/index.js +21 -35
  77. package/dist/install-commands/claude-code.js +96 -92
  78. package/dist/install-commands/host-selection.js +3 -6
  79. package/dist/install-commands/opencode.js +263 -259
  80. package/dist/install-commands/planner.js +159 -180
  81. package/dist/install-commands/result-format.js +1 -3
  82. package/dist/install-commands/shared.js +25 -42
  83. package/dist/install-commands/writer.js +22 -25
  84. package/dist/install-commands.js +8 -8
  85. package/dist/jscpd-output.js +29 -0
  86. package/dist/json-config-merge.js +14 -20
  87. package/dist/json-line-values.js +17 -6
  88. package/dist/loop/argo-poll.js +52 -71
  89. package/dist/loop/backlog-records.js +1 -3
  90. package/dist/loop/controller-deps.js +146 -159
  91. package/dist/loop/controller.js +162 -186
  92. package/dist/loop/gh-checks.js +62 -61
  93. package/dist/loop/gh-runner.js +22 -25
  94. package/dist/loop/loop-command.js +66 -58
  95. package/dist/loop/loop-controller-entrypoint.js +28 -30
  96. package/dist/loop/merge.js +36 -40
  97. package/dist/mcp/gateway-config.js +25 -29
  98. package/dist/mcp/gateway-doctor.js +104 -116
  99. package/dist/mcp/gateway-reconcile.js +17 -22
  100. package/dist/mcp/gateway-runtime.js +1 -3
  101. package/dist/mcp/host-config.js +37 -40
  102. package/dist/mcp/host-renderers.js +10 -18
  103. package/dist/mcp/repo-local-backends.js +50 -54
  104. package/dist/mcp/toolhive-vmcp.js +39 -39
  105. package/dist/model-resolver.js +29 -33
  106. package/dist/moka-global-config.d.ts +78 -54
  107. package/dist/moka-global-config.js +90 -92
  108. package/dist/moka-submit.d.ts +2163 -864
  109. package/dist/moka-submit.js +97 -99
  110. package/dist/opencode-project-config.js +34 -40
  111. package/dist/package-assets.js +1 -3
  112. package/dist/path-refs.js +2 -2
  113. package/dist/pipeline-init.js +25 -25
  114. package/dist/pipeline-runtime.d.ts +11 -11
  115. package/dist/pipeline-runtime.js +49 -50
  116. package/dist/planned-node.js +6 -3
  117. package/dist/planning/compile.d.ts +3 -3
  118. package/dist/planning/compile.js +140 -139
  119. package/dist/planning/dependency-refs.js +5 -5
  120. package/dist/planning/generate.d.ts +1293 -1293
  121. package/dist/planning/generate.js +305 -314
  122. package/dist/planning/graph.js +131 -149
  123. package/dist/remote/argo/model.d.ts +103 -121
  124. package/dist/remote/argo/model.js +205 -197
  125. package/dist/remote/argo/policy.js +39 -47
  126. package/dist/remote/argo/storage.js +81 -85
  127. package/dist/remote/submit/argo-submission.js +53 -58
  128. package/dist/remote/submit/compilation.js +46 -49
  129. package/dist/remote/submit/event-boundary.js +62 -76
  130. package/dist/remote/submit/hook-events.d.ts +5 -0
  131. package/dist/remote/submit/io.js +40 -43
  132. package/dist/remote/submit/options.d.ts +50 -0
  133. package/dist/remote/submit/options.js +27 -0
  134. package/dist/remote/submit/service.js +45 -49
  135. package/dist/run-control/command-context.js +6 -8
  136. package/dist/run-control/commands.js +10 -10
  137. package/dist/run-control/contracts.d.ts +40 -100
  138. package/dist/run-control/contracts.js +56 -69
  139. package/dist/run-control/detach.js +66 -72
  140. package/dist/run-control/file-errors.js +1 -3
  141. package/dist/run-control/logical-segment.js +3 -3
  142. package/dist/run-control/next-node.js +66 -78
  143. package/dist/run-control/postgres/postgres-run-control-store.js +195 -224
  144. package/dist/run-control/resume-command.js +33 -41
  145. package/dist/run-control/run-artifacts-command.js +83 -105
  146. package/dist/run-control/run-command-domain.js +7 -11
  147. package/dist/run-control/run-control-store.js +9 -9
  148. package/dist/run-control/run-query-command.js +73 -100
  149. package/dist/run-control/run-record.js +2 -2
  150. package/dist/run-control/run-state-lock.js +5 -5
  151. package/dist/run-control/runtime-event-projection.js +38 -50
  152. package/dist/run-control/runtime-reporter.js +84 -102
  153. package/dist/run-control/stop-command.js +42 -53
  154. package/dist/run-control/store-fs-effects.js +3 -1
  155. package/dist/run-control/store-manifest.js +38 -13
  156. package/dist/run-control/store-paths.js +3 -3
  157. package/dist/run-control/store.js +1 -1
  158. package/dist/run-control/submit-result.js +21 -21
  159. package/dist/run-control/supervisor.js +77 -68
  160. package/dist/run-control/workspace.js +2 -2
  161. package/dist/run-state/git-refs.js +257 -307
  162. package/dist/runner/opencode-excludes.js +4 -4
  163. package/dist/runner/subprocess-result.js +28 -37
  164. package/dist/runner/subprocess.js +41 -41
  165. package/dist/runner/timeouts.js +14 -13
  166. package/dist/runner-command/dynamic-command.js +46 -39
  167. package/dist/runner-command/finalize.js +174 -153
  168. package/dist/runner-command/lifecycle-context.js +112 -130
  169. package/dist/runner-command/lifecycle.js +77 -71
  170. package/dist/runner-command/pre-schedule.js +201 -222
  171. package/dist/runner-command/run.js +432 -447
  172. package/dist/runner-command/schedule-source-options.js +8 -10
  173. package/dist/runner-command/select-ready-wave.js +38 -29
  174. package/dist/runner-command/task-descriptor.js +11 -17
  175. package/dist/runner-command-contract.d.ts +147 -156
  176. package/dist/runner-command-contract.js +401 -410
  177. package/dist/runner-event-schema.d.ts +364 -504
  178. package/dist/runner-event-schema.js +187 -175
  179. package/dist/runner-event-sink.js +37 -43
  180. package/dist/runner-output.js +6 -6
  181. package/dist/runner.d.ts +56 -36
  182. package/dist/runner.js +175 -127
  183. package/dist/runtime/actor-ids.js +2 -2
  184. package/dist/runtime/agent-node/agent-node.js +99 -111
  185. package/dist/runtime/agent-node/handoff-finalization.js +23 -24
  186. package/dist/runtime/agent-node/model-selection.js +19 -22
  187. package/dist/runtime/agent-node/output-finalization.js +174 -205
  188. package/dist/runtime/agent-node/prompt-rendering.js +207 -251
  189. package/dist/runtime/agent-node/session-execution.js +34 -38
  190. package/dist/runtime/builtins/builtins.js +212 -284
  191. package/dist/runtime/changed-files/changed-files.js +26 -34
  192. package/dist/runtime/command-executor/command-executor.js +31 -23
  193. package/dist/runtime/config-error.js +1 -3
  194. package/dist/runtime/context/context.js +35 -37
  195. package/dist/runtime/contracts/index.d.ts +1 -1
  196. package/dist/runtime/detached-race.js +11 -14
  197. package/dist/runtime/drain-merge/drain-merge.js +137 -163
  198. package/dist/runtime/durable-store/acquisition.js +5 -3
  199. package/dist/runtime/durable-store/durable-store.d.ts +1 -1
  200. package/dist/runtime/durable-store/postgres/migrate-substrate.js +36 -33
  201. package/dist/runtime/durable-store/postgres/postgres-store.js +17 -18
  202. package/dist/runtime/events/events.js +255 -323
  203. package/dist/runtime/gates/adjudication/llm-judge.js +21 -24
  204. package/dist/runtime/gates/adjudication/structured-claim.js +15 -16
  205. package/dist/runtime/gates/adjudicator/adjudicator.js +27 -27
  206. package/dist/runtime/gates/adjudicator/index.js +2 -2
  207. package/dist/runtime/gates/contract.js +5 -9
  208. package/dist/runtime/gates/gates.js +9 -8
  209. package/dist/runtime/gates/kinds/acceptance/acceptance.js +66 -70
  210. package/dist/runtime/gates/kinds/acceptance/index.js +2 -2
  211. package/dist/runtime/gates/kinds/artifact/artifact.js +4 -4
  212. package/dist/runtime/gates/kinds/artifact/index.js +2 -2
  213. package/dist/runtime/gates/kinds/builtin/builtin.js +4 -4
  214. package/dist/runtime/gates/kinds/builtin/index.js +2 -2
  215. package/dist/runtime/gates/kinds/changed-files/changed-files.js +31 -35
  216. package/dist/runtime/gates/kinds/changed-files/index.js +2 -2
  217. package/dist/runtime/gates/kinds/command/command.js +3 -3
  218. package/dist/runtime/gates/kinds/command/index.js +2 -2
  219. package/dist/runtime/gates/kinds/json-schema/index.js +2 -2
  220. package/dist/runtime/gates/kinds/json-schema/json-schema.js +7 -6
  221. package/dist/runtime/gates/kinds/verdict/index.js +2 -2
  222. package/dist/runtime/gates/kinds/verdict/verdict.js +3 -3
  223. package/dist/runtime/gates/orchestrator.js +72 -86
  224. package/dist/runtime/gates/registry.js +1 -3
  225. package/dist/runtime/handoff.d.ts +1 -1
  226. package/dist/runtime/handoff.js +43 -46
  227. package/dist/runtime/hooks/command-hook.js +57 -71
  228. package/dist/runtime/hooks/context.js +21 -25
  229. package/dist/runtime/hooks/events.js +84 -100
  230. package/dist/runtime/hooks/execution.js +6 -12
  231. package/dist/runtime/hooks/hooks.js +34 -23
  232. package/dist/runtime/hooks/invocation.js +23 -29
  233. package/dist/runtime/hooks/module-hook.js +35 -35
  234. package/dist/runtime/hooks/policy.js +32 -29
  235. package/dist/runtime/hooks/results.js +56 -66
  236. package/dist/runtime/journal-acquisition.d.ts +1 -1
  237. package/dist/runtime/journal-acquisition.js +14 -14
  238. package/dist/runtime/json-validation/json-validation.js +50 -72
  239. package/dist/runtime/local-scheduler.js +46 -48
  240. package/dist/runtime/node-execution.js +375 -446
  241. package/dist/runtime/node-protocol/node-protocol.js +36 -79
  242. package/dist/runtime/node-state-store.d.ts +1 -1
  243. package/dist/runtime/node-state-store.js +13 -57
  244. package/dist/runtime/node-state-tracker.js +46 -54
  245. package/dist/runtime/open-pull-request/open-pull-request.js +143 -187
  246. package/dist/runtime/opencode-adapter.js +23 -24
  247. package/dist/runtime/opencode-agent-name.js +6 -6
  248. package/dist/runtime/opencode-runtime.js +92 -92
  249. package/dist/runtime/opencode-server.js +39 -53
  250. package/dist/runtime/opencode-session-executor.js +315 -334
  251. package/dist/runtime/parallel-node/parallel-node.js +122 -134
  252. package/dist/runtime/parallel-worktrees/parallel-worktrees.js +90 -73
  253. package/dist/runtime/protected-paths/protected-paths.js +70 -71
  254. package/dist/runtime/remediation/remediation.js +202 -231
  255. package/dist/runtime/retry.js +8 -10
  256. package/dist/runtime/run-journal.js +7 -7
  257. package/dist/runtime/runtime-results.js +54 -69
  258. package/dist/runtime/scheduled-dependencies.d.ts +1 -1
  259. package/dist/runtime/scheduled-dependencies.js +59 -74
  260. package/dist/runtime/scheduler.js +177 -202
  261. package/dist/runtime/services/agent-node-runtime-service.js +3 -3
  262. package/dist/runtime/services/backlog-service.js +8 -14
  263. package/dist/runtime/services/command-executor-service.js +1 -1
  264. package/dist/runtime/services/config-io-service.js +24 -21
  265. package/dist/runtime/services/drain-merge-git-service.js +1 -1
  266. package/dist/runtime/services/file-system-service.js +9 -7
  267. package/dist/runtime/services/git-porcelain-service.js +6 -6
  268. package/dist/runtime/services/kubernetes-argo-service.d.ts +10 -2
  269. package/dist/runtime/services/kubernetes-argo-service.js +90 -84
  270. package/dist/runtime/services/mcp-gateway-service.js +82 -81
  271. package/dist/runtime/services/open-pull-request-git-service.js +1 -3
  272. package/dist/runtime/services/opencode-runtime-server-service.js +10 -12
  273. package/dist/runtime/services/opencode-sdk-service.js +7 -7
  274. package/dist/runtime/services/repo-io-service.js +10 -12
  275. package/dist/runtime/services/run-journal-file-service.js +2 -2
  276. package/dist/runtime/services/runner-command-io-service.js +48 -52
  277. package/dist/runtime/services/runner-event-sink-http-service.js +31 -39
  278. package/dist/runtime/step/step-node.js +15 -15
  279. package/dist/runtime/workflow-execution.js +55 -57
  280. package/dist/runtime/workflow-lifecycle.js +81 -101
  281. package/dist/safe-json.js +16 -16
  282. package/dist/schedule/backlog-context.js +120 -116
  283. package/dist/schedule/baseline.js +249 -255
  284. package/dist/schedule/passes/coverage.js +63 -68
  285. package/dist/schedule/passes/drain-merge.js +34 -40
  286. package/dist/schedule/passes/ids.js +15 -17
  287. package/dist/schedule/passes/models.js +40 -37
  288. package/dist/schedule/passes/open-pull-request.js +12 -18
  289. package/dist/schedule/passes/references.js +18 -22
  290. package/dist/schedule/prompts.js +134 -141
  291. package/dist/schedule/scheduling-roles.js +8 -14
  292. package/dist/schema-boundary.d.ts +1 -0
  293. package/dist/schema-boundary.js +145 -0
  294. package/dist/serialized-write-queue.js +2 -2
  295. package/dist/standard-output-schemas.js +61 -59
  296. package/dist/strings.js +12 -12
  297. package/dist/task-ref.js +5 -5
  298. package/dist/tickets/apply-ticket-plan.js +51 -61
  299. package/dist/tickets/backlog-task-store.d.ts +13 -22
  300. package/dist/tickets/backlog-task-store.js +80 -94
  301. package/dist/tickets/completion/complete-ticket.js +53 -59
  302. package/dist/tickets/ticket-graph-dto.d.ts +24 -47
  303. package/dist/tickets/ticket-graph-dto.js +40 -40
  304. package/dist/tickets/ticket-graph.d.ts +7 -1
  305. package/dist/tickets/ticket-graph.js +36 -50
  306. package/dist/tickets/ticket-plan-command-args.js +6 -10
  307. package/dist/tickets/ticket-plan-render.js +10 -16
  308. package/dist/tickets/ticket-plan.d.ts +31 -40
  309. package/dist/tickets/ticket-plan.js +97 -77
  310. package/dist/tickets/ticket-selection.d.ts +1 -1
  311. package/dist/tickets/ticket-selection.js +37 -52
  312. package/dist/tickets/ticket-task-index.js +13 -17
  313. package/dist/tickets/validation-error-format.js +3 -10
  314. package/dist/token-estimator.js +12 -7
  315. package/dist/unknown-fields.js +21 -0
  316. package/dist/workflow-submit-contract.d.ts +9 -9
  317. package/dist/workflow-submit-contract.js +10 -9
  318. package/docs/adr-opencode-first-goal-loop-runtime.md +11 -11
  319. package/docs/config-architecture.md +13 -13
  320. package/docs/mcp-host-isolation.md +1 -0
  321. package/docs/moka-orchestrator-design.md +3 -3
  322. package/docs/operator-guide.md +1 -1
  323. package/docs/runtime-actor-model.md +18 -18
  324. package/docs/slash-command-adapter-contract.md +3 -3
  325. package/package.json +73 -76
  326. package/dist/config/schema/reference-validation.js +0 -83
@@ -1,121 +1,321 @@
1
+ import { nonEmptyMutableArray, parseStrictWithSchema, parseWithSchema, requiredString, stringRecord, struct, withDefault } from "./schema-boundary.js";
1
2
  import { ArgoGraphCompilerError, compileArgoExecutionGraph } from "./argo-graph.js";
2
- import { argoWorkflowActiveDeadlineSecondsSchema, argoWorkflowPodGcSchema, argoWorkflowTtlStrategySchema, dbAuthOptionSchema, mcpGatewayAuthOptionSchema } from "./remote/argo/model.js";
3
- import { brokerAuthOptionSchema } from "./credentials/broker.js";
4
3
  import { appendPullRequestDelivery } from "./schedule/passes/open-pull-request.js";
5
4
  import { compileScheduleArtifact, parseScheduleArtifact } from "./planning/generate.js";
6
5
  import { parseRunnerCommandPayload, runnerCommandPayloadSchema } from "./runner-command-contract.js";
7
6
  import { buildRunnerTaskDescriptor } from "./runner-command/task-descriptor.js";
8
7
  import { buildDynamicRunnerArgoWorkflowManifest, buildRunnerArgoWorkflowManifest, runnerArgoWorkflowManifestSchema } from "./argo-workflow.js";
9
8
  import { normalizeRunnerRepositoryForSubmit } from "./git-remote-url.js";
9
+ import { runnerPodSubmitOptionShape } from "./remote/submit/options.js";
10
10
  import { KubernetesArgoService, KubernetesArgoServiceLive } from "./runtime/services/kubernetes-argo-service.js";
11
11
  import { workflowSubmitResultSchema } from "./workflow-submit-contract.js";
12
+ import * as DateTime from "effect/DateTime";
13
+ import * as Effect from "effect/Effect";
14
+ import * as ManagedRuntime from "effect/ManagedRuntime";
15
+ import * as Option$1 from "effect/Option";
16
+ import * as R from "effect/Record";
17
+ import * as Schema from "effect/Schema";
12
18
  import { stringify } from "yaml";
13
- import { Effect } from "effect";
14
- import { z } from "zod";
15
- import { randomBytes } from "node:crypto";
16
19
  //#region src/argo-submit.ts
17
- const scheduleIdSchema = z.string().regex(/^[a-z][a-z0-9-]*$/);
18
- const configMapSchema = z.object({
19
- apiVersion: z.literal("v1"),
20
- data: z.record(z.string().min(1), z.string()),
21
- kind: z.literal("ConfigMap"),
22
- metadata: z.object({
23
- labels: z.record(z.string().min(1), z.string().min(1)).optional(),
24
- name: z.string().min(1),
25
- namespace: z.string().min(1)
26
- }).strict()
27
- }).strict();
28
- const workflowOwnerReferenceSchema = z.object({
29
- apiVersion: z.literal("argoproj.io/v1alpha1"),
30
- kind: z.literal("Workflow"),
31
- name: z.string().min(1),
32
- uid: z.string().min(1)
33
- }).strict();
34
- const configMapOwnerReferencesPatchSchema = z.object({ metadata: z.object({ ownerReferences: z.tuple([workflowOwnerReferenceSchema]) }).strict() }).strict();
35
- const createdWorkflowSchema = z.object({ metadata: z.object({
36
- name: z.string().min(1).optional(),
37
- uid: z.string().min(1).optional()
38
- }).passthrough() }).passthrough();
20
+ const scheduleId = Schema.String.check(Schema.isPattern(/^[a-z][a-z0-9-]*$/u));
21
+ const configMapSchema = struct({
22
+ apiVersion: Schema.Literal("v1"),
23
+ data: stringRecord,
24
+ kind: Schema.Literal("ConfigMap"),
25
+ metadata: struct({
26
+ labels: Schema.optional(stringRecord),
27
+ name: requiredString,
28
+ namespace: requiredString
29
+ })
30
+ });
31
+ const workflowOwnerReferenceSchema = struct({
32
+ apiVersion: Schema.Literal("argoproj.io/v1alpha1"),
33
+ kind: Schema.Literal("Workflow"),
34
+ name: requiredString,
35
+ uid: requiredString
36
+ });
37
+ const configMapOwnerReferencesPatchSchema = struct({ metadata: struct({ ownerReferences: Schema.mutable(Schema.Tuple([workflowOwnerReferenceSchema])) }) });
38
+ const createdWorkflowSchema = struct({ metadata: struct({
39
+ name: Schema.optional(requiredString),
40
+ uid: Schema.optional(requiredString)
41
+ }) });
42
+ const runnerTaskDescriptorJson = Schema.fromJsonString(struct({ nodeId: requiredString }));
43
+ const encodeRunnerTaskDescriptorJson = Schema.encodeSync(runnerTaskDescriptorJson);
44
+ const runnerCommandPayloadJson = Schema.fromJsonString(runnerCommandPayloadSchema);
45
+ const encodeRunnerCommandPayloadJson = Schema.encodeSync(runnerCommandPayloadJson);
46
+ const errorMessageShape = struct({ message: Schema.String });
47
+ const randomHex = (byteLength) => globalThis.crypto.randomUUID().replaceAll("-", "").slice(0, byteLength * 2);
48
+ var ArgoSubmitError = class extends Schema.TaggedErrorClass()("ArgoSubmitError", { message: Schema.String }) {};
39
49
  const submitRunnerArgoWorkflowBaseOptionShape = {
40
- activeDeadlineSeconds: argoWorkflowActiveDeadlineSecondsSchema.optional(),
41
- brokerAuth: brokerAuthOptionSchema,
42
- dbAuth: dbAuthOptionSchema.optional(),
43
- eventAuthSecretKey: z.string().min(1).optional(),
44
- eventAuthSecretName: z.string().min(1).optional(),
45
- generateName: z.string().min(1).optional(),
46
- gitCredentialsSecretName: z.string().min(1).optional(),
47
- githubAuthSecretName: z.string().min(1).optional(),
48
- image: z.string().min(1).optional(),
49
- imagePullPolicy: z.enum([
50
+ ...runnerPodSubmitOptionShape,
51
+ imagePullPolicy: Schema.optional(Schema.Literals([
50
52
  "Always",
51
53
  "IfNotPresent",
52
54
  "Never"
53
- ]).optional(),
54
- imagePullSecretName: z.string().min(1).optional(),
55
- kubeContext: z.string().min(1).optional(),
56
- kubeconfigPath: z.string().min(1).optional(),
57
- mcpGatewayAuth: mcpGatewayAuthOptionSchema.optional(),
58
- name: z.string().min(1).optional(),
59
- namespace: z.string().min(1),
60
- npmRegistryAuthSecretName: z.string().min(1).optional(),
61
- payloadJson: z.string().min(1),
62
- podGC: argoWorkflowPodGcSchema.optional(),
63
- serviceAccountName: z.string().min(1).optional(),
64
- ttlStrategy: argoWorkflowTtlStrategySchema.optional()
55
+ ])),
56
+ namespace: requiredString,
57
+ payloadJson: requiredString
65
58
  };
66
- const submitRunnerArgoWorkflowOptionsSchema = z.object({
59
+ const commandScheduleOptionsSchema = struct({
60
+ command: nonEmptyMutableArray(requiredString),
61
+ deliverPullRequest: withDefault(Schema.Boolean, false),
62
+ generatedAt: Schema.optional(Schema.DateTimeUtcFromDate),
63
+ scheduleId: Schema.optional(scheduleId),
64
+ task: requiredString
65
+ });
66
+ const hasWorkflowName = (options) => options.name !== void 0 || options.generateName !== void 0;
67
+ const submitRunnerArgoWorkflowOptionsSchema = struct({
67
68
  ...submitRunnerArgoWorkflowBaseOptionShape,
68
- scheduleYaml: z.string().min(1)
69
- }).strict().refine(hasWorkflowName, { message: "Argo submit options must declare name or generateName" });
70
- const submitDynamicRunnerArgoWorkflowOptionsSchema = z.object({
69
+ scheduleYaml: requiredString
70
+ }).check(Schema.makeFilter((options) => hasWorkflowName(options) || "Argo submit options must declare name or generateName", {
71
+ description: "Static Argo submit options must include name or generateName.",
72
+ identifier: "SubmitRunnerArgoWorkflowName",
73
+ title: "Submit runner Argo workflow name"
74
+ }));
75
+ const submitDynamicRunnerArgoWorkflowOptionsSchema = struct({
71
76
  ...submitRunnerArgoWorkflowBaseOptionShape,
72
- workflowId: z.string().min(1)
73
- }).strict().refine(hasWorkflowName, { message: "Argo submit options must declare name or generateName" });
74
- const commandScheduleOptionsSchema = z.object({
75
- command: z.array(z.string().min(1)).min(1),
76
- deliverPullRequest: z.boolean().default(false),
77
- generatedAt: z.date().default(() => /* @__PURE__ */ new Date()),
78
- scheduleId: scheduleIdSchema.optional(),
79
- task: z.string().min(1)
80
- }).strict();
81
- function hasWorkflowName(options) {
82
- return options.name !== void 0 || options.generateName !== void 0;
83
- }
84
- function submitRunnerArgoWorkflow(rawOptions, dependencies = {}) {
85
- return Effect.runPromise(Effect.provide(Effect.suspend(() => submitRunnerArgoWorkflowEffect(rawOptions, dependencies)), KubernetesArgoServiceLive));
86
- }
87
- function submitDynamicRunnerArgoWorkflow(rawOptions, dependencies = {}) {
88
- return Effect.runPromise(Effect.provide(Effect.suspend(() => submitDynamicRunnerArgoWorkflowEffect(rawOptions, dependencies)), KubernetesArgoServiceLive));
89
- }
90
- function submitRunnerArgoWorkflowEffect(rawOptions, dependencies) {
91
- const { config, ...schemaOptions } = rawOptions;
92
- const options = submitRunnerArgoWorkflowOptionsSchema.parse(schemaOptions);
77
+ workflowId: requiredString
78
+ }).check(Schema.makeFilter((options) => hasWorkflowName(options) || "Argo submit options must declare name or generateName", {
79
+ description: "Dynamic Argo submit options must include name or generateName.",
80
+ identifier: "SubmitDynamicRunnerArgoWorkflowName",
81
+ title: "Submit dynamic runner Argo workflow name"
82
+ }));
83
+ const kubernetesArgoRuntime = ManagedRuntime.make(KubernetesArgoServiceLive);
84
+ const runKubernetesArgoEffect = async (effect) => await kubernetesArgoRuntime.runPromise(effect);
85
+ const runConfigMap = (input) => {
86
+ return {
87
+ body: parseStrictWithSchema(configMapSchema, {
88
+ apiVersion: "v1",
89
+ data: input.data,
90
+ kind: "ConfigMap",
91
+ metadata: {
92
+ labels: input.labels,
93
+ name: input.name,
94
+ namespace: input.namespace
95
+ }
96
+ }),
97
+ name: input.name
98
+ };
99
+ };
100
+ const staticRunConfigMaps = (input) => [
101
+ runConfigMap({
102
+ data: { "payload.json": input.payloadJson },
103
+ labels: input.labels,
104
+ name: input.payloadConfigMapName,
105
+ namespace: input.namespace
106
+ }),
107
+ runConfigMap({
108
+ data: R.fromEntries(input.tasks.map((task) => [`${task.taskName}.json`, `${encodeRunnerTaskDescriptorJson(buildRunnerTaskDescriptor(task.nodeId))}\n`])),
109
+ labels: input.labels,
110
+ name: input.taskDescriptorConfigMapName,
111
+ namespace: input.namespace
112
+ }),
113
+ runConfigMap({
114
+ data: { "schedule.yaml": input.scheduleYaml },
115
+ labels: input.labels,
116
+ name: input.scheduleConfigMapName,
117
+ namespace: input.namespace
118
+ })
119
+ ];
120
+ const dynamicRunConfigMaps = (input) => [runConfigMap({
121
+ data: { "payload.json": input.payloadJson },
122
+ labels: input.labels,
123
+ name: input.payloadConfigMapName,
124
+ namespace: input.namespace
125
+ })];
126
+ const runConfigMapEffects = (configMapNames, effectForName) => Effect.all(configMapNames.map(effectForName), { concurrency: "unbounded" });
127
+ const patchRunConfigMapOwnerReferences = (input) => Effect.gen(function* effectBody() {
128
+ const service = yield* KubernetesArgoService;
129
+ yield* runConfigMapEffects(input.configMapNames, (name) => service.patchConfigMapOwnerReferences({
130
+ body: input.body,
131
+ dependencies: input.dependencies,
132
+ name,
133
+ namespace: input.namespace,
134
+ options: input.options
135
+ }));
136
+ });
137
+ const deleteRunConfigMaps = (input) => Effect.gen(function* effectBody() {
138
+ const service = yield* KubernetesArgoService;
139
+ yield* runConfigMapEffects(input.configMapNames, (name) => service.deleteConfigMap({
140
+ dependencies: input.dependencies,
141
+ name,
142
+ namespace: input.namespace,
143
+ options: input.options
144
+ }));
145
+ });
146
+ const workflowOwnerReference = (result) => {
147
+ if (result.workflowUid === void 0) return Option$1.none();
148
+ return Option$1.some(parseStrictWithSchema(workflowOwnerReferenceSchema, {
149
+ apiVersion: "argoproj.io/v1alpha1",
150
+ kind: "Workflow",
151
+ name: result.workflowName,
152
+ uid: result.workflowUid
153
+ }));
154
+ };
155
+ const missingWorkflowUidMessage = (result) => `Created Argo Workflow '${result.workflowName}' did not include metadata.uid; cannot own ConfigMaps`;
156
+ const configMapOwnerReferencesPatch = (ownerReference) => parseStrictWithSchema(configMapOwnerReferencesPatchSchema, { metadata: { ownerReferences: [ownerReference] } });
157
+ const errorMessage = (error) => Option$1.match(Schema.decodeUnknownOption(errorMessageShape)(error), {
158
+ onNone: () => String(error),
159
+ onSome: (value) => value.message
160
+ });
161
+ const warnRunConfigMapOwnershipSkipped = (input) => Effect.sync(() => {
162
+ const reason = errorMessage(input.error);
163
+ const message = `moka submit: failed to set Workflow ownerReference for ConfigMaps after Argo Workflow '${input.result.workflowName}' was created; leaving ConfigMaps for TTL/sweeper cleanup: ${reason}\n`;
164
+ process.stderr.write(message);
165
+ });
166
+ const ownRunConfigMaps = (input) => {
167
+ const ownerReference = workflowOwnerReference(input.result);
168
+ if (Option$1.isNone(ownerReference)) return warnRunConfigMapOwnershipSkipped({
169
+ error: new ArgoSubmitError({ message: missingWorkflowUidMessage(input.result) }),
170
+ result: input.result
171
+ }).pipe(Effect.as(input.result));
172
+ return patchRunConfigMapOwnerReferences({
173
+ body: configMapOwnerReferencesPatch(ownerReference.value),
174
+ configMapNames: input.configMapNames,
175
+ dependencies: input.dependencies,
176
+ namespace: input.namespace,
177
+ options: input.options
178
+ }).pipe(Effect.as(input.result));
179
+ };
180
+ const ownRunConfigMapsBestEffort = (input) => ownRunConfigMaps(input).pipe(Effect.catch((error) => warnRunConfigMapOwnershipSkipped({
181
+ error,
182
+ result: input.result
183
+ }).pipe(Effect.as(input.result))));
184
+ const cleanupRunConfigMapsOnFailure = (input) => deleteRunConfigMaps({
185
+ configMapNames: input.configMapNames,
186
+ dependencies: input.dependencies,
187
+ namespace: input.namespace,
188
+ options: input.options
189
+ }).pipe(Effect.catch((cleanupError) => Effect.fail(new ArgoSubmitError({ message: `Failed to clean up ConfigMaps after submit failure: ${errorMessage(input.error)}; cleanup failed: ${errorMessage(cleanupError)}` }))), Effect.flatMap(() => Effect.fail(input.error)));
190
+ const createRunConfigMaps = (input) => {
191
+ const createdConfigMapNames = [];
192
+ return Effect.gen(function* effectBody() {
193
+ const service = yield* KubernetesArgoService;
194
+ yield* Effect.all(input.configMaps.map((configMap) => service.createConfigMap({
195
+ body: configMap.body,
196
+ dependencies: input.dependencies,
197
+ namespace: input.namespace,
198
+ options: input.options
199
+ }).pipe(Effect.tap(() => Effect.sync(() => {
200
+ createdConfigMapNames.push(configMap.name);
201
+ })))), { concurrency: "unbounded" });
202
+ return createdConfigMapNames;
203
+ }).pipe(Effect.catch((error) => cleanupRunConfigMapsOnFailure({
204
+ configMapNames: createdConfigMapNames,
205
+ dependencies: input.dependencies,
206
+ error,
207
+ namespace: input.namespace,
208
+ options: input.options
209
+ })));
210
+ };
211
+ const applyWorkflowFieldOverrides = (workflow, overrides = {}) => {
212
+ if (overrides.podGC === void 0) return workflow;
213
+ return parseStrictWithSchema(runnerArgoWorkflowManifestSchema, {
214
+ ...workflow,
215
+ spec: {
216
+ ...workflow.spec,
217
+ podGC: overrides.podGC
218
+ }
219
+ });
220
+ };
221
+ const workflowSubmitResult = (response, workflow, base) => {
222
+ const created = parseWithSchema(createdWorkflowSchema, response, { onExcessProperty: "preserve" });
223
+ return parseStrictWithSchema(workflowSubmitResultSchema, {
224
+ ...base,
225
+ workflowName: created.metadata.name ?? workflow.metadata.name,
226
+ workflowUid: created.metadata.uid
227
+ });
228
+ };
229
+ const submitWorkflowManifest = (input) => Effect.gen(function* effectBody() {
230
+ const service = yield* KubernetesArgoService;
231
+ const workflow = applyWorkflowFieldOverrides(input.workflow, input.workflowFieldOverrides);
232
+ return workflowSubmitResult(yield* service.createWorkflow({
233
+ body: parseStrictWithSchema(runnerArgoWorkflowManifestSchema, workflow),
234
+ dependencies: input.dependencies,
235
+ namespace: input.namespace,
236
+ options: input.options
237
+ }), workflow, {
238
+ namespace: input.namespace,
239
+ ...input.resultExtras
240
+ });
241
+ });
242
+ const submitWorkflowWithRunConfigMaps = (input) => submitWorkflowManifest({
243
+ dependencies: input.dependencies,
244
+ namespace: input.namespace,
245
+ options: input.options,
246
+ resultExtras: input.resultExtras,
247
+ workflow: input.workflow,
248
+ workflowFieldOverrides: input.workflowFieldOverrides
249
+ }).pipe(Effect.catch((error) => cleanupRunConfigMapsOnFailure({
250
+ configMapNames: input.configMapNames,
251
+ dependencies: input.dependencies,
252
+ error,
253
+ namespace: input.namespace,
254
+ options: input.options
255
+ })), Effect.flatMap((result) => ownRunConfigMapsBestEffort({
256
+ configMapNames: input.configMapNames,
257
+ dependencies: input.dependencies,
258
+ namespace: input.namespace,
259
+ options: input.options,
260
+ result
261
+ })));
262
+ const buildCommandScheduleYaml = (rawOptions) => {
263
+ const options = parseStrictWithSchema(commandScheduleOptionsSchema, rawOptions);
264
+ const scheduleId = options.scheduleId ?? `custom-${randomHex(8)}`;
265
+ const generatedAt = options.generatedAt ?? DateTime.nowUnsafe();
266
+ const artifact = {
267
+ generated_at: DateTime.formatIso(generatedAt),
268
+ kind: "pipeline-schedule",
269
+ root_workflow: "root",
270
+ schedule_id: scheduleId,
271
+ source_entrypoint: "custom",
272
+ task: options.task,
273
+ version: 1,
274
+ workflows: { root: { nodes: [{
275
+ command: options.command,
276
+ id: "command",
277
+ kind: "command"
278
+ }] } }
279
+ };
280
+ return stringify(appendPullRequestDelivery(options.deliverPullRequest, artifact));
281
+ };
282
+ const normalizeRunnerPayloadForSubmit = (input) => {
283
+ const repository = normalizeRunnerRepositoryForSubmit(input.payload.repository);
284
+ if (repository === input.payload.repository) return input;
285
+ const payload = parseStrictWithSchema(runnerCommandPayloadSchema, {
286
+ ...input.payload,
287
+ repository
288
+ });
289
+ return {
290
+ payload,
291
+ payloadJson: encodeRunnerCommandPayloadJson(payload)
292
+ };
293
+ };
294
+ const submitDynamicRunnerArgoWorkflowEffect = (rawOptions, dependencies) => {
295
+ const { config: _config, ...schemaOptions } = rawOptions;
296
+ const options = parseStrictWithSchema(submitDynamicRunnerArgoWorkflowOptionsSchema, schemaOptions);
93
297
  const { payload, payloadJson } = normalizeRunnerPayloadForSubmit({
94
- payload: runnerCommandPayloadSchema.parse(parseRunnerCommandPayload(options.payloadJson)),
298
+ payload: parseStrictWithSchema(runnerCommandPayloadSchema, parseRunnerCommandPayload(options.payloadJson)),
95
299
  payloadJson: options.payloadJson
96
300
  });
97
- const compiled = compileScheduleArtifact(config, parseScheduleArtifact(options.scheduleYaml, "schedule.yaml"));
98
- const payloadConfigMapName = `pipeline-payload-${randomBytes(6).toString("hex")}`;
99
- const scheduleArtifactConfigMapName = `pipeline-schedule-${randomBytes(6).toString("hex")}`;
100
- const taskDescriptorConfigMapName = `pipeline-task-descriptors-${randomBytes(6).toString("hex")}`;
101
- if (payload.workflow.id !== compiled.workflowId) throw new Error(`Runner payload workflow '${payload.workflow.id}' does not match schedule workflow '${compiled.workflowId}'`);
102
- const graphEffect = compileSubmitArgoGraph(compiled).pipe(Effect.mapError((error) => /* @__PURE__ */ new Error(`Schedule '${compiled.workflowId}' cannot be submitted: ${error.message}`)));
301
+ if (payload.workflow.id !== options.workflowId) return Effect.fail(new ArgoSubmitError({ message: `Runner payload workflow '${payload.workflow.id}' does not match dynamic workflow '${options.workflowId}'` }));
302
+ const payloadConfigMapName = `pipeline-payload-${randomHex(6)}`;
103
303
  const labels = {
104
304
  "pipeline.oisin.dev/project": payload.run.project,
105
305
  "pipeline.oisin.dev/run-id": payload.run.id,
106
306
  "pipeline.oisin.dev/source": "argo-workflow",
107
- "pipeline.oisin.dev/workflow": compiled.workflowId
307
+ "pipeline.oisin.dev/workflow": options.workflowId
108
308
  };
109
- const workflow = buildRunnerArgoWorkflowManifest({
110
- annotations: payload.task.kind === "ticket" ? {
111
- "pipeline.oisin.dev/ticket-id": payload.task.id,
112
- "pipeline.oisin.dev/ticket-project": payload.run.project,
113
- "pipeline.oisin.dev/ticket-title": payload.task.title
114
- } : {},
309
+ const annotations = payload.task.kind === "ticket" ? {
310
+ "pipeline.oisin.dev/ticket-id": payload.task.id,
311
+ "pipeline.oisin.dev/ticket-project": payload.run.project,
312
+ "pipeline.oisin.dev/ticket-title": payload.task.title
313
+ } : {};
314
+ const workflow = buildDynamicRunnerArgoWorkflowManifest({
115
315
  activeDeadlineSeconds: options.activeDeadlineSeconds,
316
+ annotations,
116
317
  brokerAuth: options.brokerAuth,
117
318
  dbAuth: options.dbAuth,
118
- mcpGatewayAuth: options.mcpGatewayAuth,
119
319
  eventAuthSecretKey: options.eventAuthSecretKey,
120
320
  eventAuthSecretName: options.eventAuthSecretName,
121
321
  generateName: options.generateName,
@@ -125,29 +325,23 @@ function submitRunnerArgoWorkflowEffect(rawOptions, dependencies) {
125
325
  imagePullPolicy: options.imagePullPolicy,
126
326
  imagePullSecretName: options.imagePullSecretName,
127
327
  labels,
328
+ mcpGatewayAuth: options.mcpGatewayAuth,
128
329
  name: options.name,
129
330
  namespace: options.namespace,
130
331
  npmRegistryAuthSecretName: options.npmRegistryAuthSecretName,
131
332
  payloadConfigMapName,
132
- plan: compiled.plan,
133
- scheduleConfigMapName: scheduleArtifactConfigMapName,
134
333
  serviceAccountName: options.serviceAccountName,
135
- taskDescriptorConfigMapName,
136
- ttlStrategy: options.ttlStrategy
334
+ ttlStrategy: options.ttlStrategy,
335
+ workflowId: options.workflowId
137
336
  });
138
- return Effect.gen(function* () {
139
- const graph = yield* graphEffect;
337
+ return Effect.gen(function* effectBody() {
140
338
  return yield* submitWorkflowWithRunConfigMaps({
141
339
  configMapNames: yield* createRunConfigMaps({
142
- configMaps: staticRunConfigMaps({
340
+ configMaps: dynamicRunConfigMaps({
143
341
  labels,
144
342
  namespace: options.namespace,
145
343
  payloadConfigMapName,
146
- payloadJson,
147
- scheduleConfigMapName: scheduleArtifactConfigMapName,
148
- scheduleYaml: options.scheduleYaml,
149
- taskDescriptorConfigMapName,
150
- tasks: graph.tasks
344
+ payloadJson
151
345
  }),
152
346
  dependencies,
153
347
  namespace: options.namespace,
@@ -156,37 +350,45 @@ function submitRunnerArgoWorkflowEffect(rawOptions, dependencies) {
156
350
  dependencies,
157
351
  namespace: options.namespace,
158
352
  options,
159
- resultExtras: {
160
- payloadConfigMapName,
161
- scheduleConfigMapName: scheduleArtifactConfigMapName,
162
- taskDescriptorConfigMapName
163
- },
353
+ resultExtras: { payloadConfigMapName },
164
354
  workflow,
165
355
  workflowFieldOverrides: { podGC: options.podGC }
166
356
  });
167
357
  });
168
- }
169
- function submitDynamicRunnerArgoWorkflowEffect(rawOptions, dependencies) {
170
- const { config: _config, ...schemaOptions } = rawOptions;
171
- const options = submitDynamicRunnerArgoWorkflowOptionsSchema.parse(schemaOptions);
358
+ };
359
+ const submitDynamicRunnerArgoWorkflow = async (rawOptions, dependencies = {}) => await runKubernetesArgoEffect(Effect.suspend(() => submitDynamicRunnerArgoWorkflowEffect(rawOptions, dependencies)));
360
+ const compileSubmitArgoGraph = (compiled) => Effect.try({
361
+ catch: (error) => {
362
+ if (error instanceof ArgoGraphCompilerError) return error;
363
+ throw error;
364
+ },
365
+ try: () => compileArgoExecutionGraph(compiled.plan)
366
+ });
367
+ const submitRunnerArgoWorkflowEffect = (rawOptions, dependencies) => {
368
+ const { config, ...schemaOptions } = rawOptions;
369
+ const options = parseStrictWithSchema(submitRunnerArgoWorkflowOptionsSchema, schemaOptions);
172
370
  const { payload, payloadJson } = normalizeRunnerPayloadForSubmit({
173
- payload: runnerCommandPayloadSchema.parse(parseRunnerCommandPayload(options.payloadJson)),
371
+ payload: parseStrictWithSchema(runnerCommandPayloadSchema, parseRunnerCommandPayload(options.payloadJson)),
174
372
  payloadJson: options.payloadJson
175
373
  });
176
- if (payload.workflow.id !== options.workflowId) throw new Error(`Runner payload workflow '${payload.workflow.id}' does not match dynamic workflow '${options.workflowId}'`);
177
- const payloadConfigMapName = `pipeline-payload-${randomBytes(6).toString("hex")}`;
374
+ const compiled = compileScheduleArtifact(config, parseScheduleArtifact(options.scheduleYaml, "schedule.yaml"));
375
+ const payloadConfigMapName = `pipeline-payload-${randomHex(6)}`;
376
+ const scheduleArtifactConfigMapName = `pipeline-schedule-${randomHex(6)}`;
377
+ const taskDescriptorConfigMapName = `pipeline-task-descriptors-${randomHex(6)}`;
378
+ if (payload.workflow.id !== compiled.workflowId) return Effect.fail(new ArgoSubmitError({ message: `Runner payload workflow '${payload.workflow.id}' does not match schedule workflow '${compiled.workflowId}'` }));
379
+ const graphEffect = compileSubmitArgoGraph(compiled).pipe(Effect.mapError((error) => new ArgoSubmitError({ message: `Schedule '${compiled.workflowId}' cannot be submitted: ${error.message}` })));
178
380
  const labels = {
179
381
  "pipeline.oisin.dev/project": payload.run.project,
180
382
  "pipeline.oisin.dev/run-id": payload.run.id,
181
383
  "pipeline.oisin.dev/source": "argo-workflow",
182
- "pipeline.oisin.dev/workflow": options.workflowId
384
+ "pipeline.oisin.dev/workflow": compiled.workflowId
183
385
  };
184
386
  const annotations = payload.task.kind === "ticket" ? {
185
387
  "pipeline.oisin.dev/ticket-id": payload.task.id,
186
388
  "pipeline.oisin.dev/ticket-project": payload.run.project,
187
389
  "pipeline.oisin.dev/ticket-title": payload.task.title
188
390
  } : {};
189
- const workflow = buildDynamicRunnerArgoWorkflowManifest({
391
+ const workflow = buildRunnerArgoWorkflowManifest({
190
392
  activeDeadlineSeconds: options.activeDeadlineSeconds,
191
393
  annotations,
192
394
  brokerAuth: options.brokerAuth,
@@ -199,24 +401,31 @@ function submitDynamicRunnerArgoWorkflowEffect(rawOptions, dependencies) {
199
401
  image: options.image,
200
402
  imagePullPolicy: options.imagePullPolicy,
201
403
  imagePullSecretName: options.imagePullSecretName,
202
- mcpGatewayAuth: options.mcpGatewayAuth,
203
404
  labels,
405
+ mcpGatewayAuth: options.mcpGatewayAuth,
204
406
  name: options.name,
205
407
  namespace: options.namespace,
206
408
  npmRegistryAuthSecretName: options.npmRegistryAuthSecretName,
207
409
  payloadConfigMapName,
410
+ plan: compiled.plan,
411
+ scheduleConfigMapName: scheduleArtifactConfigMapName,
208
412
  serviceAccountName: options.serviceAccountName,
209
- ttlStrategy: options.ttlStrategy,
210
- workflowId: options.workflowId
413
+ taskDescriptorConfigMapName,
414
+ ttlStrategy: options.ttlStrategy
211
415
  });
212
- return Effect.gen(function* () {
416
+ return Effect.gen(function* effectBody() {
417
+ const graph = yield* graphEffect;
213
418
  return yield* submitWorkflowWithRunConfigMaps({
214
419
  configMapNames: yield* createRunConfigMaps({
215
- configMaps: dynamicRunConfigMaps({
420
+ configMaps: staticRunConfigMaps({
216
421
  labels,
217
422
  namespace: options.namespace,
218
423
  payloadConfigMapName,
219
- payloadJson
424
+ payloadJson,
425
+ scheduleConfigMapName: scheduleArtifactConfigMapName,
426
+ scheduleYaml: options.scheduleYaml,
427
+ taskDescriptorConfigMapName,
428
+ tasks: graph.tasks
220
429
  }),
221
430
  dependencies,
222
431
  namespace: options.namespace,
@@ -225,248 +434,16 @@ function submitDynamicRunnerArgoWorkflowEffect(rawOptions, dependencies) {
225
434
  dependencies,
226
435
  namespace: options.namespace,
227
436
  options,
228
- resultExtras: { payloadConfigMapName },
437
+ resultExtras: {
438
+ payloadConfigMapName,
439
+ scheduleConfigMapName: scheduleArtifactConfigMapName,
440
+ taskDescriptorConfigMapName
441
+ },
229
442
  workflow,
230
443
  workflowFieldOverrides: { podGC: options.podGC }
231
444
  });
232
445
  });
233
- }
234
- function staticRunConfigMaps(input) {
235
- return [
236
- runConfigMap({
237
- data: { "payload.json": input.payloadJson },
238
- labels: input.labels,
239
- name: input.payloadConfigMapName,
240
- namespace: input.namespace
241
- }),
242
- runConfigMap({
243
- data: Object.fromEntries(input.tasks.map((task) => [`${task.taskName}.json`, `${JSON.stringify(buildRunnerTaskDescriptor(task.nodeId))}\n`])),
244
- labels: input.labels,
245
- name: input.taskDescriptorConfigMapName,
246
- namespace: input.namespace
247
- }),
248
- runConfigMap({
249
- data: { "schedule.yaml": input.scheduleYaml },
250
- labels: input.labels,
251
- name: input.scheduleConfigMapName,
252
- namespace: input.namespace
253
- })
254
- ];
255
- }
256
- function dynamicRunConfigMaps(input) {
257
- return [runConfigMap({
258
- data: { "payload.json": input.payloadJson },
259
- labels: input.labels,
260
- name: input.payloadConfigMapName,
261
- namespace: input.namespace
262
- })];
263
- }
264
- function runConfigMap(input) {
265
- return {
266
- body: configMapSchema.parse({
267
- apiVersion: "v1",
268
- data: input.data,
269
- kind: "ConfigMap",
270
- metadata: {
271
- labels: input.labels,
272
- name: input.name,
273
- namespace: input.namespace
274
- }
275
- }),
276
- name: input.name
277
- };
278
- }
279
- function createRunConfigMaps(input) {
280
- const createdConfigMapNames = [];
281
- return Effect.gen(function* () {
282
- const service = yield* KubernetesArgoService;
283
- yield* Effect.forEach(input.configMaps, (configMap) => service.createConfigMap({
284
- body: configMap.body,
285
- dependencies: input.dependencies,
286
- namespace: input.namespace,
287
- options: input.options
288
- }).pipe(Effect.tap(() => Effect.sync(() => {
289
- createdConfigMapNames.push(configMap.name);
290
- }))));
291
- return createdConfigMapNames;
292
- }).pipe(Effect.catch((error) => cleanupRunConfigMapsOnFailure({
293
- configMapNames: createdConfigMapNames,
294
- dependencies: input.dependencies,
295
- error,
296
- namespace: input.namespace,
297
- options: input.options
298
- })));
299
- }
300
- function ownRunConfigMaps(input) {
301
- const ownerReference = workflowOwnerReference(input.result);
302
- if (ownerReference === void 0) return warnRunConfigMapOwnershipSkipped({
303
- error: new Error(missingWorkflowUidMessage(input.result)),
304
- result: input.result
305
- }).pipe(Effect.as(input.result));
306
- return patchRunConfigMapOwnerReferences({
307
- body: configMapOwnerReferencesPatch(ownerReference),
308
- configMapNames: input.configMapNames,
309
- dependencies: input.dependencies,
310
- namespace: input.namespace,
311
- options: input.options
312
- }).pipe(Effect.as(input.result));
313
- }
314
- function ownRunConfigMapsBestEffort(input) {
315
- return ownRunConfigMaps(input).pipe(Effect.catch((error) => warnRunConfigMapOwnershipSkipped({
316
- error,
317
- result: input.result
318
- }).pipe(Effect.as(input.result))));
319
- }
320
- function warnRunConfigMapOwnershipSkipped(input) {
321
- return Effect.sync(() => {
322
- const reason = errorMessage(input.error);
323
- const message = `moka submit: failed to set Workflow ownerReference for ConfigMaps after Argo Workflow '${input.result.workflowName}' was created; leaving ConfigMaps for TTL/sweeper cleanup: ${reason}\n`;
324
- process.stderr.write(message);
325
- });
326
- }
327
- function cleanupRunConfigMapsOnFailure(input) {
328
- return deleteRunConfigMaps({
329
- configMapNames: input.configMapNames,
330
- dependencies: input.dependencies,
331
- namespace: input.namespace,
332
- options: input.options
333
- }).pipe(Effect.catch((cleanupError) => Effect.fail(/* @__PURE__ */ new Error(`Failed to clean up ConfigMaps after submit failure: ${errorMessage(input.error)}; cleanup failed: ${errorMessage(cleanupError)}`))), Effect.flatMap(() => Effect.fail(input.error)));
334
- }
335
- function patchRunConfigMapOwnerReferences(input) {
336
- return Effect.gen(function* () {
337
- const service = yield* KubernetesArgoService;
338
- return yield* Effect.all(input.configMapNames.map((name) => service.patchConfigMapOwnerReferences({
339
- body: input.body,
340
- dependencies: input.dependencies,
341
- name,
342
- namespace: input.namespace,
343
- options: input.options
344
- })), { concurrency: "unbounded" });
345
- });
346
- }
347
- function deleteRunConfigMaps(input) {
348
- return Effect.gen(function* () {
349
- const service = yield* KubernetesArgoService;
350
- return yield* Effect.all(input.configMapNames.map((name) => service.deleteConfigMap({
351
- dependencies: input.dependencies,
352
- name,
353
- namespace: input.namespace,
354
- options: input.options
355
- })), { concurrency: "unbounded" });
356
- });
357
- }
358
- function workflowOwnerReference(result) {
359
- if (result.workflowUid === void 0) return;
360
- return workflowOwnerReferenceSchema.parse({
361
- apiVersion: "argoproj.io/v1alpha1",
362
- kind: "Workflow",
363
- name: result.workflowName,
364
- uid: result.workflowUid
365
- });
366
- }
367
- function missingWorkflowUidMessage(result) {
368
- return `Created Argo Workflow '${result.workflowName}' did not include metadata.uid; cannot own ConfigMaps`;
369
- }
370
- function configMapOwnerReferencesPatch(ownerReference) {
371
- return configMapOwnerReferencesPatchSchema.parse({ metadata: { ownerReferences: [ownerReference] } });
372
- }
373
- function errorMessage(error) {
374
- return error instanceof Error ? error.message : String(error);
375
- }
376
- function submitWorkflowManifest(input) {
377
- return Effect.gen(function* () {
378
- const service = yield* KubernetesArgoService;
379
- const workflow = applyWorkflowFieldOverrides(input.workflow, input.workflowFieldOverrides);
380
- return workflowSubmitResult(yield* service.createWorkflow({
381
- body: runnerArgoWorkflowManifestSchema.parse(workflow),
382
- dependencies: input.dependencies,
383
- namespace: input.namespace,
384
- options: input.options
385
- }), workflow, {
386
- namespace: input.namespace,
387
- ...input.resultExtras
388
- });
389
- });
390
- }
391
- function submitWorkflowWithRunConfigMaps(input) {
392
- return submitWorkflowManifest({
393
- dependencies: input.dependencies,
394
- namespace: input.namespace,
395
- options: input.options,
396
- resultExtras: input.resultExtras,
397
- workflow: input.workflow,
398
- workflowFieldOverrides: input.workflowFieldOverrides
399
- }).pipe(Effect.catch((error) => cleanupRunConfigMapsOnFailure({
400
- configMapNames: input.configMapNames,
401
- dependencies: input.dependencies,
402
- error,
403
- namespace: input.namespace,
404
- options: input.options
405
- })), Effect.flatMap((result) => ownRunConfigMapsBestEffort({
406
- configMapNames: input.configMapNames,
407
- dependencies: input.dependencies,
408
- namespace: input.namespace,
409
- options: input.options,
410
- result
411
- })));
412
- }
413
- function applyWorkflowFieldOverrides(workflow, overrides) {
414
- if (overrides?.podGC === void 0) return workflow;
415
- return runnerArgoWorkflowManifestSchema.parse({
416
- ...workflow,
417
- spec: {
418
- ...workflow.spec,
419
- podGC: overrides.podGC
420
- }
421
- });
422
- }
423
- function workflowSubmitResult(response, workflow, base) {
424
- const created = createdWorkflowSchema.parse(response);
425
- return workflowSubmitResultSchema.parse({
426
- ...base,
427
- workflowName: created.metadata.name ?? workflow.metadata.name,
428
- workflowUid: created.metadata.uid
429
- });
430
- }
431
- function buildCommandScheduleYaml(rawOptions) {
432
- const options = commandScheduleOptionsSchema.parse(rawOptions);
433
- const scheduleId = options.scheduleId ?? `custom-${randomBytes(8).toString("hex")}`;
434
- const artifact = {
435
- generated_at: options.generatedAt.toISOString(),
436
- kind: "pipeline-schedule",
437
- root_workflow: "root",
438
- schedule_id: scheduleId,
439
- source_entrypoint: "custom",
440
- task: options.task,
441
- version: 1,
442
- workflows: { root: { nodes: [{
443
- command: options.command,
444
- id: "command",
445
- kind: "command"
446
- }] } }
447
- };
448
- return stringify(appendPullRequestDelivery(options.deliverPullRequest, artifact));
449
- }
450
- function normalizeRunnerPayloadForSubmit(input) {
451
- const repository = normalizeRunnerRepositoryForSubmit(input.payload.repository);
452
- if (repository === input.payload.repository) return input;
453
- const payload = runnerCommandPayloadSchema.parse({
454
- ...input.payload,
455
- repository
456
- });
457
- return {
458
- payload,
459
- payloadJson: JSON.stringify(payload)
460
- };
461
- }
462
- function compileSubmitArgoGraph(compiled) {
463
- return Effect.try({
464
- try: () => compileArgoExecutionGraph(compiled.plan),
465
- catch: (error) => {
466
- if (error instanceof ArgoGraphCompilerError) return error;
467
- throw error;
468
- }
469
- });
470
- }
446
+ };
447
+ const submitRunnerArgoWorkflow = async (rawOptions, dependencies = {}) => await runKubernetesArgoEffect(Effect.suspend(() => submitRunnerArgoWorkflowEffect(rawOptions, dependencies)));
471
448
  //#endregion
472
449
  export { buildCommandScheduleYaml, submitDynamicRunnerArgoWorkflow, submitRunnerArgoWorkflow };