@oisincoveney/pipeline 3.24.2 → 4.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.
- package/README.md +14 -2
- package/defaults/pipeline.yaml +23 -5
- package/defaults/profiles.yaml +104 -21
- package/dist/argo-graph.js +90 -88
- package/dist/argo-submit.d.ts +110 -138
- package/dist/argo-submit.js +363 -378
- package/dist/argo-workflow.d.ts +156 -177
- package/dist/argo-workflow.js +96 -138
- package/dist/backlog.js +5 -4
- package/dist/bench/eval-report.js +21 -12
- package/dist/claude-settings-config.js +23 -31
- package/dist/claude-user-config.js +6 -16
- package/dist/cli/bootstrap-commands.js +3 -3
- package/dist/cli/doctor.d.ts +1 -1
- package/dist/cli/doctor.js +176 -171
- package/dist/cli/factory-commands.js +13 -13
- package/dist/cli/format.js +92 -86
- package/dist/cli/loop-commands.js +21 -21
- package/dist/cli/mcp-gateway-commands.js +12 -12
- package/dist/cli/plan-commands.js +85 -116
- package/dist/cli/program.d.ts +3 -3
- package/dist/cli/program.js +41 -43
- package/dist/cli/run-command.d.ts +1 -1
- package/dist/cli/run-command.js +25 -25
- package/dist/cli/run-commands.js +31 -29
- package/dist/cli/run-resolver.d.ts +1 -1
- package/dist/cli/run-resolver.js +30 -32
- package/dist/cli/run-service.d.ts +2 -3
- package/dist/cli/run-service.js +229 -239
- package/dist/cli/submit-options.js +85 -83
- package/dist/cluster-doctor.js +147 -175
- package/dist/codex-config.js +24 -30
- package/dist/commands/bench-command.js +9 -7
- package/dist/commands/coordinator-command.js +35 -0
- package/dist/commands/pipeline-command.js +13 -7
- package/dist/commands/runner-command-command.js +39 -24
- package/dist/commands/runner-node-command.js +31 -0
- package/dist/commands/ticket/complete.js +29 -33
- package/dist/commands/ticket/create.js +84 -82
- package/dist/commands/ticket/graph-check.js +11 -11
- package/dist/commands/ticket/next.js +36 -36
- package/dist/commands/ticket/sequence.js +11 -12
- package/dist/commands/ticket/shared.d.ts +5 -2
- package/dist/commands/ticket/shared.js +63 -66
- package/dist/commands/ticket/start.js +58 -67
- package/dist/commands/ticket-command.js +2 -2
- package/dist/config/defaults.d.ts +139 -140
- package/dist/config/defaults.js +81 -80
- package/dist/config/lint.js +52 -64
- package/dist/config/load.d.ts +4 -5
- package/dist/config/load.js +64 -74
- package/dist/config/schema/catalog.d.ts +2 -1
- package/dist/config/schema/catalog.js +3 -2
- package/dist/config/schema/mcp.js +46 -52
- package/dist/config/schemas.d.ts +382 -528
- package/dist/config/schemas.js +400 -398
- package/dist/config/validate.d.ts +1 -2
- package/dist/config/validate.js +236 -201
- package/dist/config.d.ts +2 -2
- package/dist/context/repo-map.js +105 -119
- package/dist/coordinator/composition.js +169 -0
- package/dist/coordinator/config.js +71 -0
- package/dist/coordinator/run-owner.js +64 -0
- package/dist/coordinator/wave-advance.js +148 -0
- package/dist/coordinator/wave-scheduler.js +50 -0
- package/dist/credentials/broker.d.ts +6 -8
- package/dist/credentials/broker.js +17 -16
- package/dist/credentials/codex-config.js +15 -19
- package/dist/credentials/file-targets.js +9 -15
- package/dist/credentials/local-codex-auth-sync.js +55 -58
- package/dist/credentials/opencode-config.js +28 -32
- package/dist/credentials/runner.js +13 -13
- package/dist/effect-sync-errors.js +28 -0
- package/dist/factory/create-experiment.js +285 -121
- package/dist/factory/exec.js +10 -12
- package/dist/factory/git-credentials.js +4 -4
- package/dist/factory/stamp-answers.js +10 -11
- package/dist/factory/template-update.js +65 -44
- package/dist/factory-lane.d.ts +26 -40
- package/dist/factory-lane.js +26 -25
- package/dist/gates.js +3 -3
- package/dist/git-remote-url.js +17 -19
- package/dist/hooks.d.ts +26 -26
- package/dist/hooks.js +20 -22
- package/dist/index.d.ts +4 -3
- package/dist/index.js +27 -36
- package/dist/install-commands/claude-code.js +100 -92
- package/dist/install-commands/host-selection.js +3 -6
- package/dist/install-commands/opencode.js +264 -259
- package/dist/install-commands/planner.js +163 -181
- package/dist/install-commands/result-format.js +1 -3
- package/dist/install-commands/shared.js +25 -42
- package/dist/install-commands/writer.js +22 -25
- package/dist/install-commands.js +8 -8
- package/dist/jscpd-output.js +29 -0
- package/dist/json-config-merge.js +14 -20
- package/dist/json-line-values.js +17 -6
- package/dist/loop/argo-poll.d.ts +0 -1
- package/dist/loop/argo-poll.js +15 -95
- package/dist/loop/backlog-records.js +1 -3
- package/dist/loop/controller-deps.js +150 -161
- package/dist/loop/controller.js +164 -186
- package/dist/loop/gh-checks.js +62 -61
- package/dist/loop/gh-runner.js +22 -25
- package/dist/loop/loop-command.js +66 -58
- package/dist/loop/loop-controller-entrypoint.js +29 -30
- package/dist/loop/merge.js +36 -40
- package/dist/loop/run-terminal-poll.js +69 -0
- package/dist/mcp/gateway-config.js +25 -29
- package/dist/mcp/gateway-doctor.js +77 -119
- package/dist/mcp/gateway-reconcile.js +17 -22
- package/dist/mcp/gateway-runtime.js +1 -3
- package/dist/mcp/host-config.js +37 -40
- package/dist/mcp/host-renderers.js +10 -18
- package/dist/mcp/repo-local-backends.js +51 -54
- package/dist/mcp/toolhive-vmcp.js +39 -39
- package/dist/model-resolver.js +29 -33
- package/dist/moka-global-config.d.ts +78 -55
- package/dist/moka-global-config.js +93 -92
- package/dist/moka-submit.d.ts +2179 -866
- package/dist/moka-submit.js +97 -99
- package/dist/opencode-project-config.js +34 -40
- package/dist/package-assets.js +1 -3
- package/dist/path-refs.js +2 -2
- package/dist/pipeline-init.js +25 -25
- package/dist/pipeline-runtime.d.ts +15 -14
- package/dist/pipeline-runtime.js +51 -50
- package/dist/planned-node.js +6 -3
- package/dist/planning/compile.d.ts +5 -5
- package/dist/planning/compile.js +140 -139
- package/dist/planning/dependency-refs.js +5 -5
- package/dist/planning/generate.d.ts +1296 -1296
- package/dist/planning/generate.js +307 -314
- package/dist/planning/graph.d.ts +0 -1
- package/dist/planning/graph.js +131 -149
- package/dist/remote/argo/model.d.ts +104 -122
- package/dist/remote/argo/model.js +205 -197
- package/dist/remote/argo/policy.js +39 -47
- package/dist/remote/argo/storage.js +81 -85
- package/dist/remote/jobs/execution-identity.js +70 -0
- package/dist/remote/jobs/job-outcome.js +108 -0
- package/dist/remote/jobs/manifest.js +96 -0
- package/dist/remote/jobs/model.d.ts +158 -0
- package/dist/remote/jobs/model.js +162 -0
- package/dist/remote/jobs/node-bootstrap.js +213 -0
- package/dist/remote/jobs/policy.js +123 -0
- package/dist/remote/jobs/reconcile.js +100 -0
- package/dist/remote/jobs/run-spec-client.js +64 -0
- package/dist/remote/jobs/run-spec-path.js +31 -0
- package/dist/remote/jobs/run-spec-server.d.ts +34 -0
- package/dist/remote/jobs/run-spec-server.js +116 -0
- package/dist/remote/jobs/submit.d.ts +23 -0
- package/dist/remote/jobs/submit.js +116 -0
- package/dist/remote/jobs/watch.js +59 -0
- package/dist/remote/submit/argo-submission.d.ts +3 -1
- package/dist/remote/submit/argo-submission.js +53 -58
- package/dist/remote/submit/compilation.d.ts +2 -0
- package/dist/remote/submit/compilation.js +46 -49
- package/dist/remote/submit/event-boundary.js +62 -76
- package/dist/remote/submit/hook-events.d.ts +6 -0
- package/dist/remote/submit/io.d.ts +7 -1
- package/dist/remote/submit/io.js +40 -43
- package/dist/remote/submit/jobs-submission.d.ts +59 -0
- package/dist/remote/submit/jobs-submission.js +97 -0
- package/dist/remote/submit/jobs-submit-result.d.ts +25 -0
- package/dist/remote/submit/jobs-submit-result.js +34 -0
- package/dist/remote/submit/options.d.ts +49 -0
- package/dist/remote/submit/options.js +27 -0
- package/dist/remote/submit/service.d.ts +40 -1
- package/dist/remote/submit/service.js +67 -49
- package/dist/run-control/command-context.js +6 -8
- package/dist/run-control/commands.js +10 -10
- package/dist/run-control/contracts.d.ts +52 -101
- package/dist/run-control/contracts.js +83 -69
- package/dist/run-control/detach.js +66 -72
- package/dist/run-control/execution-store.js +0 -0
- package/dist/run-control/file-errors.js +1 -3
- package/dist/run-control/logical-segment.js +3 -3
- package/dist/run-control/next-node.js +67 -78
- package/dist/run-control/postgres/postgres-run-control-store.js +196 -225
- package/dist/run-control/resume-command.js +34 -41
- package/dist/run-control/run-artifacts-command.js +84 -105
- package/dist/run-control/run-command-domain.js +7 -11
- package/dist/run-control/run-control-store.js +9 -9
- package/dist/run-control/run-query-command.js +73 -100
- package/dist/run-control/run-record.js +5 -3
- package/dist/run-control/run-state-lock.js +5 -5
- package/dist/run-control/runtime-event-projection.js +38 -50
- package/dist/run-control/runtime-reporter.js +86 -102
- package/dist/run-control/stop-command.js +42 -53
- package/dist/run-control/store-fs-effects.js +3 -1
- package/dist/run-control/store-manifest.js +38 -13
- package/dist/run-control/store-paths.js +3 -3
- package/dist/run-control/store.js +1 -1
- package/dist/run-control/submit-result.js +21 -21
- package/dist/run-control/supervisor.js +78 -68
- package/dist/run-control/workspace.js +2 -2
- package/dist/run-state/git-refs.js +258 -307
- package/dist/runner/opencode-excludes.js +4 -4
- package/dist/runner/subprocess-result.js +28 -37
- package/dist/runner/subprocess.js +41 -41
- package/dist/runner/timeouts.js +14 -13
- package/dist/runner-command/dynamic-command.js +46 -39
- package/dist/runner-command/environment-commands.js +91 -0
- package/dist/runner-command/finalize.js +174 -153
- package/dist/runner-command/lifecycle-context.js +115 -130
- package/dist/runner-command/lifecycle.js +78 -72
- package/dist/runner-command/pre-schedule.js +203 -223
- package/dist/runner-command/run.js +450 -448
- package/dist/runner-command/schedule-source-options.js +8 -10
- package/dist/runner-command/select-ready-wave.js +39 -30
- package/dist/runner-command/task-descriptor.js +11 -17
- package/dist/runner-command-contract.d.ts +147 -157
- package/dist/runner-command-contract.js +403 -411
- package/dist/runner-event-schema.d.ts +364 -505
- package/dist/runner-event-schema.js +187 -175
- package/dist/runner-event-sink.js +37 -43
- package/dist/runner-output.js +6 -6
- package/dist/runner.d.ts +57 -37
- package/dist/runner.js +176 -127
- package/dist/runtime/actor-ids.d.ts +1 -0
- package/dist/runtime/actor-ids.js +2 -2
- package/dist/runtime/agent-node/agent-node.js +99 -110
- package/dist/runtime/agent-node/handoff-finalization.js +23 -24
- package/dist/runtime/agent-node/model-selection.js +19 -22
- package/dist/runtime/agent-node/output-finalization.js +174 -204
- package/dist/runtime/agent-node/prompt-rendering.js +208 -251
- package/dist/runtime/agent-node/session-execution.js +43 -39
- package/dist/runtime/builtins/builtins.js +218 -284
- package/dist/runtime/changed-files/changed-files.js +29 -34
- package/dist/runtime/command-executor/command-executor.js +31 -23
- package/dist/runtime/config-error.js +1 -3
- package/dist/runtime/context/context.js +35 -37
- package/dist/runtime/contracts/contracts.d.ts +3 -0
- package/dist/runtime/contracts/index.d.ts +1 -1
- package/dist/runtime/detached-race.js +11 -14
- package/dist/runtime/drain-merge/drain-merge.js +139 -164
- package/dist/runtime/durable-store/acquisition.js +5 -3
- package/dist/runtime/durable-store/durable-store.d.ts +3 -1
- package/dist/runtime/durable-store/postgres/client.js +29 -0
- package/dist/runtime/durable-store/postgres/migrate-substrate.js +34 -29
- package/dist/runtime/durable-store/postgres/postgres-store.js +18 -20
- package/dist/runtime/events/events.js +273 -331
- package/dist/runtime/events/index.js +2 -2
- package/dist/runtime/execution-envelope.js +44 -0
- package/dist/runtime/gates/adjudication/llm-judge.js +21 -24
- package/dist/runtime/gates/adjudication/structured-claim.js +15 -16
- package/dist/runtime/gates/adjudicator/adjudicator.js +27 -27
- package/dist/runtime/gates/adjudicator/index.js +2 -2
- package/dist/runtime/gates/contract.js +5 -9
- package/dist/runtime/gates/gates.js +9 -8
- package/dist/runtime/gates/kinds/acceptance/acceptance.js +68 -71
- package/dist/runtime/gates/kinds/acceptance/index.js +2 -2
- package/dist/runtime/gates/kinds/artifact/artifact.js +4 -4
- package/dist/runtime/gates/kinds/artifact/index.js +2 -2
- package/dist/runtime/gates/kinds/builtin/builtin.js +4 -4
- package/dist/runtime/gates/kinds/builtin/index.js +2 -2
- package/dist/runtime/gates/kinds/changed-files/changed-files.js +31 -35
- package/dist/runtime/gates/kinds/changed-files/index.js +2 -2
- package/dist/runtime/gates/kinds/command/command.js +3 -3
- package/dist/runtime/gates/kinds/command/index.js +2 -2
- package/dist/runtime/gates/kinds/json-schema/index.js +2 -2
- package/dist/runtime/gates/kinds/json-schema/json-schema.js +7 -6
- package/dist/runtime/gates/kinds/verdict/index.js +2 -2
- package/dist/runtime/gates/kinds/verdict/verdict.js +3 -3
- package/dist/runtime/gates/orchestrator.js +72 -86
- package/dist/runtime/gates/registry.js +1 -3
- package/dist/runtime/handoff.d.ts +2 -1
- package/dist/runtime/handoff.js +43 -46
- package/dist/runtime/hooks/command-hook.js +57 -71
- package/dist/runtime/hooks/context.js +21 -25
- package/dist/runtime/hooks/events.js +84 -100
- package/dist/runtime/hooks/execution.js +6 -12
- package/dist/runtime/hooks/hooks.js +34 -23
- package/dist/runtime/hooks/invocation.js +23 -29
- package/dist/runtime/hooks/module-hook.js +36 -35
- package/dist/runtime/hooks/policy.js +32 -29
- package/dist/runtime/hooks/results.js +56 -66
- package/dist/runtime/journal-acquisition.d.ts +3 -2
- package/dist/runtime/journal-acquisition.js +14 -14
- package/dist/runtime/json-validation/json-validation.js +51 -72
- package/dist/runtime/launch-plan-args.js +39 -0
- package/dist/runtime/local-scheduler.js +46 -48
- package/dist/runtime/node-execution.js +376 -445
- package/dist/runtime/node-protocol/node-protocol.js +36 -79
- package/dist/runtime/node-state-store.d.ts +4 -1
- package/dist/runtime/node-state-store.js +13 -57
- package/dist/runtime/node-state-tracker.js +46 -54
- package/dist/runtime/open-pull-request/open-pull-request.js +201 -187
- package/dist/runtime/opencode-adapter.js +23 -24
- package/dist/runtime/opencode-agent-name.js +6 -6
- package/dist/runtime/opencode-runtime.js +115 -93
- package/dist/runtime/opencode-server.js +39 -53
- package/dist/runtime/opencode-session-executor.js +312 -344
- package/dist/runtime/parallel-node/parallel-node.js +123 -134
- package/dist/runtime/parallel-worktrees/parallel-worktrees.js +90 -73
- package/dist/runtime/protected-paths/protected-paths.js +70 -71
- package/dist/runtime/remediation/remediation.js +202 -231
- package/dist/runtime/retry.js +8 -10
- package/dist/runtime/run-journal.d.ts +2 -0
- package/dist/runtime/run-journal.js +7 -7
- package/dist/runtime/runtime-results.js +54 -69
- package/dist/runtime/scheduled-dependencies.d.ts +2 -1
- package/dist/runtime/scheduled-dependencies.js +61 -75
- package/dist/runtime/scheduler.js +179 -202
- package/dist/runtime/services/agent-node-runtime-service.js +3 -3
- package/dist/runtime/services/backlog-service.d.ts +1 -2
- package/dist/runtime/services/backlog-service.js +8 -14
- package/dist/runtime/services/command-executor-service.js +1 -1
- package/dist/runtime/services/config-io-service.js +24 -21
- package/dist/runtime/services/drain-merge-git-service.js +1 -1
- package/dist/runtime/services/file-system-service.js +9 -7
- package/dist/runtime/services/git-porcelain-service.js +6 -6
- package/dist/runtime/services/kubernetes-argo-service.d.ts +10 -3
- package/dist/runtime/services/kubernetes-argo-service.js +90 -84
- package/dist/runtime/services/kubernetes-jobs-read-service.js +115 -0
- package/dist/runtime/services/kubernetes-jobs-service.d.ts +37 -0
- package/dist/runtime/services/kubernetes-jobs-service.js +45 -0
- package/dist/runtime/services/kubernetes-jobs-watch-service.js +61 -0
- package/dist/runtime/services/kubernetes-lease-service.js +21 -0
- package/dist/runtime/services/mcp-gateway-service.js +143 -94
- package/dist/runtime/services/open-pull-request-git-service.js +1 -3
- package/dist/runtime/services/opencode-runtime-server-service.js +10 -12
- package/dist/runtime/services/opencode-sdk-service.js +7 -7
- package/dist/runtime/services/repo-io-service.js +10 -12
- package/dist/runtime/services/run-journal-file-service.js +2 -2
- package/dist/runtime/services/runner-command-io-service.js +48 -52
- package/dist/runtime/services/runner-event-sink-http-service.js +32 -39
- package/dist/runtime/step/step-node.js +15 -15
- package/dist/runtime/workflow-execution.js +56 -57
- package/dist/runtime/workflow-lifecycle.js +82 -101
- package/dist/runtime/yeet-event-record.js +104 -0
- package/dist/runtime/yeet-executor.js +184 -0
- package/dist/safe-json.js +16 -16
- package/dist/schedule/backlog-context.js +122 -116
- package/dist/schedule/baseline.js +249 -255
- package/dist/schedule/passes/coverage.js +63 -68
- package/dist/schedule/passes/drain-merge.js +34 -40
- package/dist/schedule/passes/ids.js +15 -17
- package/dist/schedule/passes/models.js +40 -37
- package/dist/schedule/passes/open-pull-request.js +16 -20
- package/dist/schedule/passes/references.js +18 -22
- package/dist/schedule/prompts.js +135 -141
- package/dist/schedule/scheduling-roles.js +8 -14
- package/dist/schema-boundary.d.ts +4 -0
- package/dist/schema-boundary.js +145 -0
- package/dist/serialized-write-queue.js +2 -2
- package/dist/standard-output-schemas.js +61 -59
- package/dist/strings.js +12 -12
- package/dist/task-ref.js +5 -5
- package/dist/tickets/apply-ticket-plan.js +52 -61
- package/dist/tickets/backlog-task-store.d.ts +15 -23
- package/dist/tickets/backlog-task-store.js +82 -94
- package/dist/tickets/completion/complete-ticket.js +53 -59
- package/dist/tickets/ticket-graph-dto.d.ts +24 -48
- package/dist/tickets/ticket-graph-dto.js +40 -40
- package/dist/tickets/ticket-graph.d.ts +7 -2
- package/dist/tickets/ticket-graph.js +36 -50
- package/dist/tickets/ticket-plan-command-args.js +6 -10
- package/dist/tickets/ticket-plan-render.js +10 -16
- package/dist/tickets/ticket-plan.d.ts +32 -41
- package/dist/tickets/ticket-plan.js +97 -77
- package/dist/tickets/ticket-selection.d.ts +3 -1
- package/dist/tickets/ticket-selection.js +37 -52
- package/dist/tickets/ticket-task-index.js +13 -17
- package/dist/tickets/validation-error-format.js +3 -10
- package/dist/token-estimator.js +12 -7
- package/dist/unknown-fields.js +21 -0
- package/dist/workflow-submit-contract.d.ts +9 -10
- package/dist/workflow-submit-contract.js +10 -9
- package/docs/adr-moka-postgres-schema-isolation.md +48 -0
- package/docs/adr-opencode-first-goal-loop-runtime.md +11 -11
- package/docs/config-architecture.md +13 -13
- package/docs/mcp-host-isolation.md +1 -0
- package/docs/moka-orchestrator-design.md +3 -3
- package/docs/operator-guide.md +1 -1
- package/docs/pipeline-console-runner-contract.md +10 -6
- package/docs/runtime-actor-model.md +18 -18
- package/docs/runtime-test-subsystems.md +200 -0
- package/docs/slash-command-adapter-contract.md +3 -3
- package/package.json +49 -85
- package/dist/config/schema/reference-validation.js +0 -83
|
@@ -1,81 +1,69 @@
|
|
|
1
1
|
import { MOKA_SUBMIT_HOOK_EVENTS } from "./hook-events.js";
|
|
2
|
+
import * as Option$1 from "effect/Option";
|
|
2
3
|
//#region src/remote/submit/event-boundary.ts
|
|
3
4
|
const submitHookId = (event) => `moka-submit-${event.replaceAll(".", "-")}`;
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
return
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const result = {};
|
|
32
|
-
addSubmitHookResultFields(result, hook);
|
|
33
|
-
return result;
|
|
34
|
-
}
|
|
35
|
-
function submitHookHasResult(hook) {
|
|
36
|
-
return hook.publishResult !== void 0 || hook.saveResultAs !== void 0;
|
|
37
|
-
}
|
|
38
|
-
function addSubmitHookResultFields(result, hook) {
|
|
39
|
-
if (hook.publishResult !== void 0) result.publish = hook.publishResult;
|
|
40
|
-
if (hook.saveResultAs !== void 0) result.save_as = hook.saveResultAs;
|
|
41
|
-
}
|
|
42
|
-
function hookBindingForSubmitHook(event, hook) {
|
|
5
|
+
const moduleHookFunctionForSubmitHook = (hook) => ({
|
|
6
|
+
kind: "module",
|
|
7
|
+
module: hook.module,
|
|
8
|
+
...hook.timeoutMs !== void 0 ? { timeout_ms: hook.timeoutMs } : {}
|
|
9
|
+
});
|
|
10
|
+
const commandHookFunctionForSubmitHook = (hook) => ({
|
|
11
|
+
command: hook.command,
|
|
12
|
+
kind: "command",
|
|
13
|
+
...hook.outputLimitBytes !== void 0 ? { output_limit_bytes: hook.outputLimitBytes } : {},
|
|
14
|
+
protocol: {
|
|
15
|
+
input: "file",
|
|
16
|
+
result: "file"
|
|
17
|
+
},
|
|
18
|
+
...hook.timeoutMs !== void 0 ? { timeout_ms: hook.timeoutMs } : {},
|
|
19
|
+
...hook.trusted !== void 0 ? { trusted: hook.trusted } : {}
|
|
20
|
+
});
|
|
21
|
+
const hookFunctionForSubmitHook = (hook) => hook.kind === "module" ? moduleHookFunctionForSubmitHook(hook) : commandHookFunctionForSubmitHook(hook);
|
|
22
|
+
const submitHookHasResult = (hook) => hook.publishResult !== void 0 || hook.saveResultAs !== void 0;
|
|
23
|
+
const addSubmitHookResultFields = (hook) => ({
|
|
24
|
+
...hook.publishResult !== void 0 ? { publish: hook.publishResult } : {},
|
|
25
|
+
...hook.saveResultAs !== void 0 ? { save_as: hook.saveResultAs } : {}
|
|
26
|
+
});
|
|
27
|
+
const submitHookBindingResult = (hook) => {
|
|
28
|
+
if (!submitHookHasResult(hook)) return Option$1.none();
|
|
29
|
+
return Option$1.some(addSubmitHookResultFields(hook));
|
|
30
|
+
};
|
|
31
|
+
const hookBindingForSubmitHook = (event, hook) => {
|
|
43
32
|
const id = submitHookId(event);
|
|
44
|
-
const
|
|
33
|
+
const result = submitHookBindingResult(hook);
|
|
34
|
+
return {
|
|
45
35
|
failure: hook.failure,
|
|
46
36
|
function: id,
|
|
47
|
-
id
|
|
37
|
+
id,
|
|
38
|
+
...Option$1.isSome(result) ? { result: result.value } : {},
|
|
39
|
+
...hook.where !== void 0 ? { where: hook.where } : {},
|
|
40
|
+
...hook.input !== void 0 ? { with: hook.input } : {}
|
|
48
41
|
};
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
if (hook.where !== void 0) binding.where = hook.where;
|
|
52
|
-
if (hook.input !== void 0) binding.with = hook.input;
|
|
53
|
-
return binding;
|
|
54
|
-
}
|
|
55
|
-
function submitHookEntries(hooks) {
|
|
42
|
+
};
|
|
43
|
+
const submitHookEntries = (hooks) => {
|
|
56
44
|
const entries = [];
|
|
57
45
|
for (const event of MOKA_SUBMIT_HOOK_EVENTS) {
|
|
58
|
-
const hook = hooks
|
|
46
|
+
const hook = Option$1.isSome(hooks) ? hooks.value[event] : void 0;
|
|
59
47
|
if (hook !== void 0) entries.push({
|
|
60
48
|
event,
|
|
61
49
|
hook
|
|
62
50
|
});
|
|
63
51
|
}
|
|
64
52
|
return entries;
|
|
65
|
-
}
|
|
66
|
-
|
|
53
|
+
};
|
|
54
|
+
const cloneHookBindings = (on) => {
|
|
67
55
|
const cloned = {};
|
|
68
56
|
for (const [event, bindings] of Object.entries(on)) cloned[event] = [...bindings];
|
|
69
57
|
return cloned;
|
|
70
|
-
}
|
|
71
|
-
|
|
58
|
+
};
|
|
59
|
+
const appendSubmitHook = (event, hook, target) => {
|
|
72
60
|
const id = submitHookId(event);
|
|
73
|
-
if (target.functions
|
|
61
|
+
if (Object.hasOwn(target.functions, id)) throw new Error(`Moka submit hook id already exists in config: ${id}`);
|
|
74
62
|
target.functions[id] = hookFunctionForSubmitHook(hook);
|
|
75
63
|
target.on[event] = [...target.on[event] ?? [], hookBindingForSubmitHook(event, hook)];
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
const entries = submitHookEntries(hooks);
|
|
64
|
+
};
|
|
65
|
+
const configWithSubmitHooks = (config, hooks) => {
|
|
66
|
+
const entries = submitHookEntries(Option$1.fromUndefinedOr(hooks));
|
|
79
67
|
if (entries.length === 0) return config;
|
|
80
68
|
const target = {
|
|
81
69
|
functions: { ...config.hooks.functions },
|
|
@@ -90,29 +78,27 @@ function configWithSubmitHooks(config, hooks) {
|
|
|
90
78
|
on: target.on
|
|
91
79
|
}
|
|
92
80
|
};
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
return
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
function runnerEventsFromUrl(options) {
|
|
106
|
-
if (!options.eventUrl) throw new Error("eventUrl is required unless eventSink or events is provided");
|
|
81
|
+
};
|
|
82
|
+
const eventAuthTokenFile = (options) => {
|
|
83
|
+
if (options.eventAuthSecretKey === void 0 || options.eventAuthSecretKey.length === 0) throw new Error("eventAuthSecretKey is required unless eventSink.authTokenFile is provided");
|
|
84
|
+
return `/etc/pipeline/event-auth/${options.eventAuthSecretKey}`;
|
|
85
|
+
};
|
|
86
|
+
const runnerEventsFromSink = (options, eventSink) => ({
|
|
87
|
+
authHeader: eventSink.authHeader,
|
|
88
|
+
authTokenFile: eventSink.authTokenFile ?? eventAuthTokenFile(options),
|
|
89
|
+
url: eventSink.url
|
|
90
|
+
});
|
|
91
|
+
const runnerEventsFromUrl = (options) => {
|
|
92
|
+
if (options.eventUrl === void 0 || options.eventUrl.length === 0) throw new Error("eventUrl is required unless eventSink or events is provided");
|
|
107
93
|
return {
|
|
108
94
|
authHeader: "Authorization",
|
|
109
95
|
authTokenFile: eventAuthTokenFile(options),
|
|
110
96
|
url: options.eventUrl
|
|
111
97
|
};
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
return
|
|
116
|
-
}
|
|
98
|
+
};
|
|
99
|
+
const runnerEvents = (options) => {
|
|
100
|
+
const eventSink = options.eventSink ?? options.events;
|
|
101
|
+
return eventSink === void 0 ? runnerEventsFromUrl(options) : runnerEventsFromSink(options, eventSink);
|
|
102
|
+
};
|
|
117
103
|
//#endregion
|
|
118
104
|
export { configWithSubmitHooks, runnerEvents };
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { RunnerRepositoryContext, RunnerRunIdentity } from "../../runner-command-contract.js";
|
|
2
|
+
import "../../moka-submit.js";
|
|
1
3
|
//#region src/remote/submit/io.d.ts
|
|
2
4
|
interface MokaGitContext {
|
|
3
5
|
baseBranch: string;
|
|
@@ -5,9 +7,13 @@ interface MokaGitContext {
|
|
|
5
7
|
sha: string;
|
|
6
8
|
url: string;
|
|
7
9
|
}
|
|
10
|
+
interface MokaSubmissionContext {
|
|
11
|
+
repository: RunnerRepositoryContext;
|
|
12
|
+
run: RunnerRunIdentity;
|
|
13
|
+
}
|
|
8
14
|
interface MokaSubmitIoDependencies {
|
|
9
15
|
readFile?: (path: string) => string;
|
|
10
16
|
resolveGitContext?: (worktreePath: string) => Promise<MokaGitContext>;
|
|
11
17
|
}
|
|
12
18
|
//#endregion
|
|
13
|
-
export { MokaSubmitIoDependencies };
|
|
19
|
+
export { MokaSubmissionContext, MokaSubmitIoDependencies };
|
package/dist/remote/submit/io.js
CHANGED
|
@@ -1,52 +1,34 @@
|
|
|
1
1
|
import { normalizeRunnerRepositoryForSubmit } from "../../git-remote-url.js";
|
|
2
2
|
import { readFileSync } from "node:fs";
|
|
3
|
+
import { Option } from "effect";
|
|
3
4
|
import { simpleGit as simpleGit$1 } from "simple-git";
|
|
4
5
|
import parseGitUrl from "git-url-parse";
|
|
5
6
|
//#region src/remote/submit/io.ts
|
|
6
|
-
|
|
7
|
-
return (dependencies.readFile ?? ((filePath) => readFileSync(filePath, "
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}
|
|
20
|
-
function explicitSubmissionContext(options) {
|
|
21
|
-
if (!(options.repository && options.run)) return null;
|
|
7
|
+
const readScheduleFile = (dependencies, path) => {
|
|
8
|
+
return (dependencies.readFile ?? ((filePath) => readFileSync(filePath, "utf-8")))(path);
|
|
9
|
+
};
|
|
10
|
+
const repositoryContext = (options, git) => normalizeRunnerRepositoryForSubmit(options.repository ?? {
|
|
11
|
+
baseBranch: git.baseBranch,
|
|
12
|
+
sha: git.sha,
|
|
13
|
+
url: git.url
|
|
14
|
+
});
|
|
15
|
+
const assertRepositoryCredentialConfiguration = (options) => {
|
|
16
|
+
if (options.gitCredentialsSecretName === void 0 || options.gitCredentialsSecretName.length === 0) throw new Error("gitCredentialsSecretName is required for runner git clone, fetch, and push operations");
|
|
17
|
+
};
|
|
18
|
+
const explicitSubmissionContext = (options) => {
|
|
19
|
+
if (options.repository === void 0 || options.run === void 0) return Option.none();
|
|
22
20
|
assertRepositoryCredentialConfiguration(options);
|
|
23
|
-
return {
|
|
21
|
+
return Option.some({
|
|
24
22
|
repository: normalizeRunnerRepositoryForSubmit(options.repository),
|
|
25
23
|
run: options.run
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
function resolveRequiredGit(options, dependencies) {
|
|
29
|
-
if (!options.worktreePath) throw new Error("worktreePath is required when moka submit must resolve repository or run context");
|
|
30
|
-
return resolveGit(options.worktreePath, dependencies);
|
|
31
|
-
}
|
|
32
|
-
function repositoryContext(options, git) {
|
|
33
|
-
return normalizeRunnerRepositoryForSubmit(options.repository ?? {
|
|
34
|
-
baseBranch: git.baseBranch,
|
|
35
|
-
sha: git.sha,
|
|
36
|
-
url: git.url
|
|
37
24
|
});
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
project: git.project
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
async function resolveGit(worktreePath, dependencies) {
|
|
49
|
-
if (dependencies.resolveGitContext) return dependencies.resolveGitContext(worktreePath);
|
|
25
|
+
};
|
|
26
|
+
const runContext = (options, git, runId) => options.run ?? {
|
|
27
|
+
id: runId,
|
|
28
|
+
project: git.project
|
|
29
|
+
};
|
|
30
|
+
const resolveGit = async (worktreePath, dependencies) => {
|
|
31
|
+
if (dependencies.resolveGitContext !== void 0) return await dependencies.resolveGitContext(worktreePath);
|
|
50
32
|
const git = simpleGit$1({ baseDir: worktreePath });
|
|
51
33
|
const [branchResult, sha, remoteConfig] = await Promise.all([
|
|
52
34
|
git.branch(),
|
|
@@ -54,13 +36,28 @@ async function resolveGit(worktreePath, dependencies) {
|
|
|
54
36
|
git.getConfig("remote.origin.url")
|
|
55
37
|
]);
|
|
56
38
|
const url = remoteConfig.value;
|
|
57
|
-
if (
|
|
39
|
+
if (url === null || url.length === 0) throw new Error("Could not resolve git remote origin URL. Ensure the repository has a remote configured.");
|
|
58
40
|
return {
|
|
59
41
|
baseBranch: branchResult.current,
|
|
60
|
-
project: parseGitUrl(url).name
|
|
42
|
+
project: parseGitUrl(url).name.length > 0 ? parseGitUrl(url).name : "unknown",
|
|
61
43
|
sha: sha.trim(),
|
|
62
44
|
url
|
|
63
45
|
};
|
|
64
|
-
}
|
|
46
|
+
};
|
|
47
|
+
const resolveRequiredGit = async (options, dependencies) => {
|
|
48
|
+
if (options.worktreePath === void 0 || options.worktreePath.length === 0) throw new Error("worktreePath is required when moka submit must resolve repository or run context");
|
|
49
|
+
return await resolveGit(options.worktreePath, dependencies);
|
|
50
|
+
};
|
|
51
|
+
const resolveSubmissionContext = async (options, dependencies, runId) => {
|
|
52
|
+
const explicitContext = explicitSubmissionContext(options);
|
|
53
|
+
if (Option.isSome(explicitContext)) return explicitContext.value;
|
|
54
|
+
const git = await resolveRequiredGit(options, dependencies);
|
|
55
|
+
const repository = repositoryContext(options, git);
|
|
56
|
+
assertRepositoryCredentialConfiguration(options);
|
|
57
|
+
return {
|
|
58
|
+
repository,
|
|
59
|
+
run: runContext(options, git, runId)
|
|
60
|
+
};
|
|
61
|
+
};
|
|
65
62
|
//#endregion
|
|
66
63
|
export { readScheduleFile, resolveSubmissionContext };
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { PlannedWorkflowNode } from "../../planning/compile.js";
|
|
2
|
+
import "./jobs-submit-result.js";
|
|
3
|
+
import { JobOwnerReference } from "../jobs/model.js";
|
|
4
|
+
import { KubernetesJobsIoDependencies } from "../../runtime/services/kubernetes-jobs-service.js";
|
|
5
|
+
import { RunSpecRegistry } from "../jobs/run-spec-server.js";
|
|
6
|
+
import { CompiledMokaSubmitPlan } from "./compilation.js";
|
|
7
|
+
import { MokaSubmissionContext } from "./io.js";
|
|
8
|
+
import { SubmitRunnerNodeJobsOptions, SubmittedNodeJob } from "../jobs/submit.js";
|
|
9
|
+
import { ParsedMokaBaseOptions } from "../../moka-submit.js";
|
|
10
|
+
import { RunSpec } from "@oisin-ee/yeet-api";
|
|
11
|
+
//#region src/remote/submit/jobs-submission.d.ts
|
|
12
|
+
/**
|
|
13
|
+
* Whole-run Jobs submission (doc-1 decision 3, ENG-56) — the replacement for the
|
|
14
|
+
* retired Argo whole-run submission. It turns a COMPILED multi-node schedule into
|
|
15
|
+
* a dependency-ordered wave of per-node `batch/v1` Jobs through the ENG-18 Jobs
|
|
16
|
+
* transport, and registers each node's self-contained {@link RunSpec} with the
|
|
17
|
+
* coordinator's serving side so the node's pod fetches it at start (no per-run
|
|
18
|
+
* ConfigMap). The waves are the planner's `parallelBatches` (a topological
|
|
19
|
+
* grouping), so Jobs are created dependency-order — every node in a wave depends
|
|
20
|
+
* only on nodes in earlier waves. Finalization is the ENG-19 reconcile/watch
|
|
21
|
+
* loop, keyed on the run-id label these Jobs carry.
|
|
22
|
+
*
|
|
23
|
+
* Dynamic scheduling (a graph planned INSIDE the pod, no schedule at submit) has
|
|
24
|
+
* no node ids to wave at submit time; it is a coordinator-runtime concern (plan,
|
|
25
|
+
* then submit waves) and is rejected here with a typed error rather than guessed.
|
|
26
|
+
*/
|
|
27
|
+
/** Injectable per-wave Job submit — defaults to the ENG-18 {@link submitRunnerNodeJobs}. */
|
|
28
|
+
type NodeJobsSubmit = (options: SubmitRunnerNodeJobsOptions, dependencies: KubernetesJobsIoDependencies) => Promise<readonly SubmittedNodeJob[]>;
|
|
29
|
+
/** Injectable per-node RunSpec builder — the coordinator's projection of a
|
|
30
|
+
* planned node onto the yeet run contract. Defaults to {@link defaultBuildNodeRunSpec}. */
|
|
31
|
+
type BuildNodeRunSpec = (input: {
|
|
32
|
+
context: MokaSubmissionContext;
|
|
33
|
+
node: PlannedWorkflowNode;
|
|
34
|
+
nodeCwd: string;
|
|
35
|
+
plan: CompiledMokaSubmitPlan;
|
|
36
|
+
}) => RunSpec;
|
|
37
|
+
interface SubmitCompiledMokaJobsInput {
|
|
38
|
+
readonly buildRunSpec?: BuildNodeRunSpec;
|
|
39
|
+
readonly context: MokaSubmissionContext;
|
|
40
|
+
/** Secret names projected into each runner container via `envFrom` (ENG-18 AC#3). */
|
|
41
|
+
readonly envFromSecretNames: readonly string[];
|
|
42
|
+
/** Cluster client injection for the Jobs transport (tests pass a fake `batchApi`). */
|
|
43
|
+
readonly jobsDependencies?: KubernetesJobsIoDependencies;
|
|
44
|
+
/** Working directory each node's pod runs yeet in (the in-pod clone path). */
|
|
45
|
+
readonly nodeCwd?: string;
|
|
46
|
+
readonly options: ParsedMokaBaseOptions;
|
|
47
|
+
/** Run-scoped owner every Job points at so a run's Jobs GC together. */
|
|
48
|
+
readonly ownerReference: JobOwnerReference;
|
|
49
|
+
readonly plan: CompiledMokaSubmitPlan;
|
|
50
|
+
/** The serving side each node's pod fetches its RunSpec from. */
|
|
51
|
+
readonly registry: RunSpecRegistry;
|
|
52
|
+
/** Base URL of the coordinator RunSpec API the pods fetch from. */
|
|
53
|
+
readonly runSpecBaseUrl: string;
|
|
54
|
+
readonly submitNodeJobs?: NodeJobsSubmit;
|
|
55
|
+
/** Optional project root for schedule compilation (lint file resolution). */
|
|
56
|
+
readonly worktreePath?: string;
|
|
57
|
+
}
|
|
58
|
+
//#endregion
|
|
59
|
+
export { BuildNodeRunSpec, NodeJobsSubmit, SubmitCompiledMokaJobsInput };
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { compileScheduleArtifact, parseScheduleArtifact } from "../../planning/generate.js";
|
|
2
|
+
import { submitRunnerNodeJobs } from "../jobs/submit.js";
|
|
3
|
+
import { parseJobsSubmitResult } from "./jobs-submit-result.js";
|
|
4
|
+
//#region src/remote/submit/jobs-submission.ts
|
|
5
|
+
var DynamicScheduleJobsSubmitError = class extends Error {
|
|
6
|
+
constructor(runId) {
|
|
7
|
+
super(`Run ${runId} has no compiled schedule; the Jobs transport waves a compiled multi-node schedule. Dynamic (in-pod planned) scheduling must plan first, then submit waves.`);
|
|
8
|
+
this.name = "DynamicScheduleJobsSubmitError";
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
const requireSubmitNamespace = (options) => {
|
|
12
|
+
if (options.namespace === void 0 || options.namespace.length === 0) throw new Error("namespace is required for moka submit");
|
|
13
|
+
return options.namespace;
|
|
14
|
+
};
|
|
15
|
+
const requireCompiledSchedule = (plan) => {
|
|
16
|
+
if (plan.dynamicScheduling || plan.scheduleYaml === void 0 || plan.scheduleYaml.length === 0) throw new DynamicScheduleJobsSubmitError(plan.runId);
|
|
17
|
+
return plan.scheduleYaml;
|
|
18
|
+
};
|
|
19
|
+
const taskPromptText = (task) => {
|
|
20
|
+
if (task.kind === "prompt") return task.prompt;
|
|
21
|
+
return task.title !== void 0 && task.title.length > 0 ? `${task.id} ${task.title}` : task.id;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Default projection of a planned node onto a {@link RunSpec}. The prompt is the
|
|
25
|
+
* node's own task-context description when present (its slice of the work), else
|
|
26
|
+
* the run's task. The harness is `opencode` — the executor seam the Jobs
|
|
27
|
+
* transport runs (see `remote/jobs/node-bootstrap`); refining per-node harness
|
|
28
|
+
* resolution from the node's profile is left to the injectable builder.
|
|
29
|
+
*/
|
|
30
|
+
const defaultBuildNodeRunSpec = ({ node, nodeCwd, plan }) => ({
|
|
31
|
+
cwd: nodeCwd,
|
|
32
|
+
harness: "opencode",
|
|
33
|
+
name: node.id,
|
|
34
|
+
prompt: node.taskContext?.description ?? taskPromptText(plan.task)
|
|
35
|
+
});
|
|
36
|
+
const waveNodeSpecs = (input, waves) => {
|
|
37
|
+
const buildRunSpec = input.buildRunSpec ?? defaultBuildNodeRunSpec;
|
|
38
|
+
const nodeCwd = input.nodeCwd ?? "/workspace";
|
|
39
|
+
return Object.fromEntries(waves.flatMap((wave) => wave.map((node) => [node.id, buildRunSpec({
|
|
40
|
+
context: input.context,
|
|
41
|
+
node,
|
|
42
|
+
nodeCwd,
|
|
43
|
+
plan: input.plan
|
|
44
|
+
})])));
|
|
45
|
+
};
|
|
46
|
+
const sharedJobOptions = (input, namespace) => ({
|
|
47
|
+
envFromSecretNames: [...input.envFromSecretNames],
|
|
48
|
+
namespace,
|
|
49
|
+
ownerReference: input.ownerReference,
|
|
50
|
+
runId: input.plan.runId,
|
|
51
|
+
runSpecBaseUrl: input.runSpecBaseUrl,
|
|
52
|
+
generateName: input.plan.generateName,
|
|
53
|
+
imagePullPolicy: input.options.imagePullPolicy,
|
|
54
|
+
workflowId: input.plan.workflowId,
|
|
55
|
+
...input.options.image === void 0 ? {} : { image: input.options.image },
|
|
56
|
+
...input.options.imagePullSecretName === void 0 ? {} : { imagePullSecretName: input.options.imagePullSecretName },
|
|
57
|
+
...input.options.serviceAccountName === void 0 ? {} : { serviceAccountName: input.options.serviceAccountName },
|
|
58
|
+
...input.options.activeDeadlineSeconds === void 0 ? {} : { activeDeadlineSeconds: input.options.activeDeadlineSeconds }
|
|
59
|
+
});
|
|
60
|
+
/**
|
|
61
|
+
* Submit a compiled run as dependency-ordered waves of per-node Jobs, serving
|
|
62
|
+
* each node's RunSpec from the coordinator registry. Waves are submitted in
|
|
63
|
+
* topological order (a wave's Jobs are created only after all earlier waves'),
|
|
64
|
+
* so the sequence of cluster writes respects the dependency graph. Returns the
|
|
65
|
+
* created Job identities plus the wave structure, validated through the result
|
|
66
|
+
* schema at the boundary.
|
|
67
|
+
*/
|
|
68
|
+
const submitCompiledMokaJobs = async (input) => {
|
|
69
|
+
const scheduleYaml = requireCompiledSchedule(input.plan);
|
|
70
|
+
const namespace = requireSubmitNamespace(input.options);
|
|
71
|
+
const waves = compileScheduleArtifact(input.plan.config, parseScheduleArtifact(scheduleYaml, "schedule.yaml"), input.worktreePath).plan.parallelBatches;
|
|
72
|
+
input.registry.register({
|
|
73
|
+
runId: input.plan.runId,
|
|
74
|
+
specs: waveNodeSpecs(input, waves)
|
|
75
|
+
});
|
|
76
|
+
const submitNodeJobs = input.submitNodeJobs ?? submitRunnerNodeJobs;
|
|
77
|
+
const shared = sharedJobOptions(input, namespace);
|
|
78
|
+
const jobsDependencies = input.jobsDependencies ?? {};
|
|
79
|
+
const submittedWaves = [];
|
|
80
|
+
for (const wave of waves) {
|
|
81
|
+
const submitted = await submitNodeJobs({
|
|
82
|
+
...shared,
|
|
83
|
+
nodeIds: wave.map((node) => node.id)
|
|
84
|
+
}, jobsDependencies);
|
|
85
|
+
submittedWaves.push([...submitted]);
|
|
86
|
+
}
|
|
87
|
+
return parseJobsSubmitResult({
|
|
88
|
+
jobs: submittedWaves.flat(),
|
|
89
|
+
namespace,
|
|
90
|
+
runId: input.plan.runId,
|
|
91
|
+
waves: waves.map((wave) => ({ nodeIds: wave.map((node) => node.id) })),
|
|
92
|
+
workflowName: input.plan.workflowId,
|
|
93
|
+
...input.ownerReference.uid.length === 0 ? {} : { workflowUid: input.ownerReference.uid }
|
|
94
|
+
});
|
|
95
|
+
};
|
|
96
|
+
//#endregion
|
|
97
|
+
export { DynamicScheduleJobsSubmitError, defaultBuildNodeRunSpec, requireCompiledSchedule, requireSubmitNamespace, sharedJobOptions, submitCompiledMokaJobs };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import * as Schema from "effect/Schema";
|
|
2
|
+
//#region src/remote/submit/jobs-submit-result.d.ts
|
|
3
|
+
declare const jobsSubmitResultSchema: Schema.Struct<{
|
|
4
|
+
readonly jobs: Schema.mutable<Schema.$Array<Schema.Struct<{
|
|
5
|
+
readonly jobName: Schema.NonEmptyString;
|
|
6
|
+
readonly namespace: Schema.NonEmptyString;
|
|
7
|
+
readonly nodeId: Schema.NonEmptyString;
|
|
8
|
+
/** ENG-57.6: true when the node's Job was OBSERVED (already existed) rather than
|
|
9
|
+
* freshly created — the idempotent replay/restart path of create-or-observe. */
|
|
10
|
+
readonly observed: Schema.optional<Schema.Boolean>;
|
|
11
|
+
readonly uid: Schema.optional<Schema.NonEmptyString>;
|
|
12
|
+
}>>>;
|
|
13
|
+
readonly namespace: Schema.NonEmptyString;
|
|
14
|
+
readonly runId: Schema.NonEmptyString;
|
|
15
|
+
readonly waves: Schema.mutable<Schema.$Array<Schema.Struct<{
|
|
16
|
+
readonly nodeIds: Schema.mutable<Schema.$Array<Schema.NonEmptyString>>;
|
|
17
|
+
}>>>;
|
|
18
|
+
/** The run's schedule workflow id — the run handle the loop controller polls. */
|
|
19
|
+
readonly workflowName: Schema.NonEmptyString;
|
|
20
|
+
/** The run-scoped owner uid, when the coordinator supplied one. */
|
|
21
|
+
readonly workflowUid: Schema.optional<Schema.NonEmptyString>;
|
|
22
|
+
}>;
|
|
23
|
+
type MokaJobsSubmitOutput = typeof jobsSubmitResultSchema.Type;
|
|
24
|
+
//#endregion
|
|
25
|
+
export { MokaJobsSubmitOutput, jobsSubmitResultSchema };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { mutableArray, parseStrictWithSchema, requiredString, struct } from "../../schema-boundary.js";
|
|
2
|
+
import * as Schema from "effect/Schema";
|
|
3
|
+
//#region src/remote/submit/jobs-submit-result.ts
|
|
4
|
+
/**
|
|
5
|
+
* The Jobs whole-run submission result (doc-1 decision 3, ENG-56) — what
|
|
6
|
+
* `submitCompiledMokaJobs` returns and the value `submitParsedMoka` yields on the
|
|
7
|
+
* Jobs path. It replaces the Argo `workflowSubmitResultSchema`, dropping the
|
|
8
|
+
* per-run ConfigMap names (there are none) and adding the created per-node Job
|
|
9
|
+
* identities and the wave structure. `workflowName` and `namespace` are retained
|
|
10
|
+
* (the loop controller and CLI print them) so downstream consumers are unchanged.
|
|
11
|
+
*/
|
|
12
|
+
const submittedNodeJobResultSchema = struct({
|
|
13
|
+
jobName: requiredString,
|
|
14
|
+
namespace: requiredString,
|
|
15
|
+
nodeId: requiredString,
|
|
16
|
+
/** ENG-57.6: true when the node's Job was OBSERVED (already existed) rather than
|
|
17
|
+
* freshly created — the idempotent replay/restart path of create-or-observe. */
|
|
18
|
+
observed: Schema.optional(Schema.Boolean),
|
|
19
|
+
uid: Schema.optional(requiredString)
|
|
20
|
+
});
|
|
21
|
+
const jobsSubmitWaveSchema = struct({ nodeIds: mutableArray(requiredString) });
|
|
22
|
+
const jobsSubmitResultSchema = struct({
|
|
23
|
+
jobs: mutableArray(submittedNodeJobResultSchema),
|
|
24
|
+
namespace: requiredString,
|
|
25
|
+
runId: requiredString,
|
|
26
|
+
waves: mutableArray(jobsSubmitWaveSchema),
|
|
27
|
+
/** The run's schedule workflow id — the run handle the loop controller polls. */
|
|
28
|
+
workflowName: requiredString,
|
|
29
|
+
/** The run-scoped owner uid, when the coordinator supplied one. */
|
|
30
|
+
workflowUid: Schema.optional(requiredString)
|
|
31
|
+
});
|
|
32
|
+
const parseJobsSubmitResult = (value) => parseStrictWithSchema(jobsSubmitResultSchema, value);
|
|
33
|
+
//#endregion
|
|
34
|
+
export { jobsSubmitResultSchema, parseJobsSubmitResult };
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import * as Schema from "effect/Schema";
|
|
2
|
+
//#region src/remote/submit/options.d.ts
|
|
3
|
+
declare const runnerPodSubmitOptionShape: {
|
|
4
|
+
activeDeadlineSeconds: Schema.optional<Schema.Number>;
|
|
5
|
+
brokerAuth: Schema.Struct<{
|
|
6
|
+
readonly secretKey: Schema.withDecodingDefault<Schema.NonEmptyString, never>;
|
|
7
|
+
readonly secretName: Schema.NonEmptyString;
|
|
8
|
+
readonly url: Schema.withDecodingDefault<Schema.NonEmptyString, never>;
|
|
9
|
+
}>;
|
|
10
|
+
dbAuth: Schema.optional<Schema.Struct<{
|
|
11
|
+
readonly secretKey: Schema.withDecodingDefault<Schema.NonEmptyString, never>;
|
|
12
|
+
readonly secretName: Schema.NonEmptyString;
|
|
13
|
+
}>>;
|
|
14
|
+
eventAuthSecretKey: Schema.optional<Schema.NonEmptyString>;
|
|
15
|
+
eventAuthSecretName: Schema.optional<Schema.NonEmptyString>;
|
|
16
|
+
generateName: Schema.optional<Schema.NonEmptyString>;
|
|
17
|
+
gitCredentialsSecretName: Schema.optional<Schema.NonEmptyString>;
|
|
18
|
+
githubAuthSecretName: Schema.optional<Schema.NonEmptyString>;
|
|
19
|
+
image: Schema.optional<Schema.NonEmptyString>;
|
|
20
|
+
imagePullSecretName: Schema.optional<Schema.NonEmptyString>;
|
|
21
|
+
kubeContext: Schema.optional<Schema.NonEmptyString>;
|
|
22
|
+
kubeconfigPath: Schema.optional<Schema.NonEmptyString>;
|
|
23
|
+
mcpGatewayAuth: Schema.optional<Schema.Struct<{
|
|
24
|
+
readonly secretKey: Schema.withDecodingDefault<Schema.NonEmptyString, never>;
|
|
25
|
+
readonly secretName: Schema.NonEmptyString;
|
|
26
|
+
}>>;
|
|
27
|
+
name: Schema.optional<Schema.NonEmptyString>;
|
|
28
|
+
npmRegistryAuthSecretName: Schema.optional<Schema.NonEmptyString>;
|
|
29
|
+
podGC: Schema.optional<Schema.Struct<{
|
|
30
|
+
readonly deleteDelayDuration: Schema.optional<Schema.NonEmptyString>;
|
|
31
|
+
readonly labelSelector: Schema.optional<Schema.Struct<{
|
|
32
|
+
readonly matchExpressions: Schema.optional<Schema.mutable<Schema.$Array<Schema.Struct<{
|
|
33
|
+
readonly key: Schema.NonEmptyString;
|
|
34
|
+
readonly operator: Schema.Literals<readonly ["In", "NotIn", "Exists", "DoesNotExist"]>;
|
|
35
|
+
readonly values: Schema.optional<Schema.mutable<Schema.$Array<Schema.String>>>;
|
|
36
|
+
}>>>>;
|
|
37
|
+
readonly matchLabels: Schema.optional<Schema.$Record<Schema.NonEmptyString, Schema.String>>;
|
|
38
|
+
}>>;
|
|
39
|
+
readonly strategy: Schema.optional<Schema.Literals<readonly ["OnPodCompletion", "OnPodSuccess", "OnWorkflowCompletion", "OnWorkflowSuccess"]>>;
|
|
40
|
+
}>>;
|
|
41
|
+
serviceAccountName: Schema.optional<Schema.NonEmptyString>;
|
|
42
|
+
ttlStrategy: Schema.optional<Schema.Struct<{
|
|
43
|
+
readonly secondsAfterCompletion: Schema.optional<Schema.Number>;
|
|
44
|
+
readonly secondsAfterFailure: Schema.optional<Schema.Number>;
|
|
45
|
+
readonly secondsAfterSuccess: Schema.optional<Schema.Number>;
|
|
46
|
+
}>>;
|
|
47
|
+
};
|
|
48
|
+
//#endregion
|
|
49
|
+
export { runnerPodSubmitOptionShape };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { requiredString } from "../../schema-boundary.js";
|
|
2
|
+
import { argoWorkflowActiveDeadlineSecondsSchema, argoWorkflowPodGcSchema, argoWorkflowTtlStrategySchema, dbAuthOptionSchema, mcpGatewayAuthOptionSchema } from "../argo/model.js";
|
|
3
|
+
import { brokerAuthOptionSchema } from "../../credentials/broker.js";
|
|
4
|
+
import * as Schema from "effect/Schema";
|
|
5
|
+
//#region src/remote/submit/options.ts
|
|
6
|
+
const runnerPodSubmitOptionShape = {
|
|
7
|
+
activeDeadlineSeconds: Schema.optional(argoWorkflowActiveDeadlineSecondsSchema),
|
|
8
|
+
brokerAuth: brokerAuthOptionSchema,
|
|
9
|
+
dbAuth: Schema.optional(dbAuthOptionSchema),
|
|
10
|
+
eventAuthSecretKey: Schema.optional(requiredString),
|
|
11
|
+
eventAuthSecretName: Schema.optional(requiredString),
|
|
12
|
+
generateName: Schema.optional(requiredString),
|
|
13
|
+
gitCredentialsSecretName: Schema.optional(requiredString),
|
|
14
|
+
githubAuthSecretName: Schema.optional(requiredString),
|
|
15
|
+
image: Schema.optional(requiredString),
|
|
16
|
+
imagePullSecretName: Schema.optional(requiredString),
|
|
17
|
+
kubeContext: Schema.optional(requiredString),
|
|
18
|
+
kubeconfigPath: Schema.optional(requiredString),
|
|
19
|
+
mcpGatewayAuth: Schema.optional(mcpGatewayAuthOptionSchema),
|
|
20
|
+
name: Schema.optional(requiredString),
|
|
21
|
+
npmRegistryAuthSecretName: Schema.optional(requiredString),
|
|
22
|
+
podGC: Schema.optional(argoWorkflowPodGcSchema),
|
|
23
|
+
serviceAccountName: Schema.optional(requiredString),
|
|
24
|
+
ttlStrategy: Schema.optional(argoWorkflowTtlStrategySchema)
|
|
25
|
+
};
|
|
26
|
+
//#endregion
|
|
27
|
+
export { runnerPodSubmitOptionShape };
|