@oisincoveney/pipeline 3.13.0 → 3.15.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/defaults/opencode-ecosystem.yaml +2 -12
- package/defaults/pipeline.yaml +0 -4
- package/dist/argo-submit.d.ts +2 -4
- package/dist/argo-submit.js +2 -6
- package/dist/argo-workflow.d.ts +2 -7
- package/dist/argo-workflow.js +16 -48
- package/dist/broker-auth.js +4 -3
- package/dist/cli/doctor.js +2 -2
- package/dist/cli/program.d.ts +1 -1
- package/dist/cli/program.js +72 -59
- package/dist/cli/submit-options.js +7 -4
- package/dist/cluster-doctor.js +4 -5
- package/dist/codex-auth-sync.js +16 -51
- package/dist/commands/ticket/complete.js +61 -0
- package/dist/commands/ticket/create.js +115 -0
- package/dist/commands/ticket/graph-check.js +16 -0
- package/dist/commands/ticket/next.js +43 -0
- package/dist/commands/ticket/sequence.js +18 -0
- package/dist/commands/ticket/shared.d.ts +14 -0
- package/dist/commands/ticket/shared.js +77 -0
- package/dist/commands/ticket/start.js +94 -0
- package/dist/commands/ticket-command.d.ts +2 -15
- package/dist/commands/ticket-command.js +14 -319
- package/dist/config/load.js +28 -7
- package/dist/config/schemas.d.ts +18 -21
- package/dist/config/schemas.js +2 -7
- package/dist/gates.js +1 -1
- package/dist/install-commands/claude-code.js +1 -1
- package/dist/install-commands/opencode.js +20 -2
- package/dist/install-commands.js +2 -2
- package/dist/install-hooks.js +2 -2
- package/dist/install-rules.js +1 -1
- package/dist/loop/controller-deps.js +1 -2
- package/dist/loop/loop-command.js +0 -2
- package/dist/loop/loop-controller-entrypoint.js +7 -4
- package/dist/moka-global-config.d.ts +19 -5
- package/dist/moka-global-config.js +43 -6
- package/dist/moka-submit.d.ts +6 -12
- package/dist/moka-submit.js +2 -6
- package/dist/pipeline-runtime.d.ts +22 -1
- package/dist/pipeline-runtime.js +55 -20
- package/dist/planning/generate.d.ts +20 -20
- package/dist/planning/generate.js +2 -2
- package/dist/run-control/commands.js +78 -40
- package/dist/run-control/contracts.js +1 -0
- package/dist/run-control/detach.js +1 -1
- package/dist/run-control/next-node.js +118 -0
- package/dist/run-control/postgres/postgres-run-control-store.js +244 -0
- package/dist/run-control/postgres/schema.js +52 -0
- package/dist/run-control/run-control-store.js +62 -0
- package/dist/run-control/runtime-reporter.js +10 -12
- package/dist/run-control/store.js +20 -8
- package/dist/run-control/submit-result.js +59 -0
- package/dist/run-control/supervisor.js +20 -16
- package/dist/run-state/opencode-accounts.js +8 -94
- package/dist/runner-command/lifecycle-context.js +1 -1
- package/dist/runner-command/run.js +30 -14
- package/dist/runner-command-contract.d.ts +2 -2
- package/dist/runner-event-schema.d.ts +4 -4
- package/dist/runner.d.ts +7 -0
- package/dist/runner.js +53 -19
- package/dist/runtime/agent-node/agent-node.js +2 -2
- package/dist/runtime/context/context.js +1 -1
- package/dist/runtime/contracts/contracts.d.ts +20 -1
- package/dist/runtime/contracts/index.d.ts +1 -1
- package/dist/runtime/durable-store/durable-store.js +53 -0
- package/dist/runtime/durable-store/postgres/postgres-store.js +133 -0
- package/dist/runtime/durable-store/postgres/schema.js +31 -0
- package/dist/runtime/events/events.js +1 -1
- package/dist/runtime/gates/adjudication/llm-judge.js +56 -0
- package/dist/runtime/gates/adjudication/structured-claim.js +52 -0
- package/dist/runtime/gates/adjudicator/adjudicator.js +69 -0
- package/dist/runtime/gates/adjudicator/index.js +39 -0
- package/dist/runtime/gates/contract.js +25 -0
- package/dist/runtime/gates/gates.js +15 -368
- package/dist/runtime/gates/index.js +3 -0
- package/dist/runtime/gates/kinds/acceptance/acceptance.js +109 -0
- package/dist/runtime/gates/kinds/acceptance/index.js +9 -0
- package/dist/runtime/gates/kinds/artifact/artifact.js +20 -0
- package/dist/runtime/gates/kinds/artifact/index.js +9 -0
- package/dist/runtime/gates/kinds/builtin/builtin.js +21 -0
- package/dist/runtime/gates/kinds/builtin/index.js +9 -0
- package/dist/runtime/gates/kinds/changed-files/changed-files.js +61 -0
- package/dist/runtime/gates/kinds/changed-files/index.js +9 -0
- package/dist/runtime/gates/kinds/command/command.js +21 -0
- package/dist/runtime/gates/kinds/command/index.js +9 -0
- package/dist/runtime/gates/kinds/json-schema/index.js +9 -0
- package/dist/runtime/gates/kinds/json-schema/json-schema.js +32 -0
- package/dist/runtime/gates/kinds/verdict/index.js +9 -0
- package/dist/runtime/gates/kinds/verdict/verdict.js +32 -0
- package/dist/runtime/gates/orchestrator.js +161 -0
- package/dist/runtime/gates/registry.js +47 -0
- package/dist/runtime/json-validation/json-validation.js +1 -1
- package/dist/runtime/node-protocol/node-protocol.js +83 -0
- package/dist/runtime/opencode-session-executor.js +48 -8
- package/dist/runtime/protected-paths/protected-paths.js +97 -0
- package/dist/runtime/run-journal.d.ts +21 -0
- package/dist/runtime/scheduler.js +13 -8
- package/dist/runtime/services/opencode-sdk-service.js +4 -0
- package/dist/runtime/services/repo-io-service.d.ts +2 -0
- package/dist/runtime/services/runner-command-io-service.js +1 -1
- package/dist/tickets/backlog-task-store.d.ts +2 -0
- package/dist/tickets/completion/complete-ticket.js +96 -0
- package/dist/tickets/ticket-graph.d.ts +2 -0
- package/dist/tickets/ticket-selection.d.ts +1 -0
- package/docs/mcp-gateway.md +6 -6
- package/docs/moka-orchestrator-design.md +79 -0
- package/docs/okteto-runner.md +1 -1
- package/docs/operator-guide.md +8 -5
- package/docs/pipeline-console-runner-contract.md +8 -7
- package/package.json +5 -2
- package/dist/runtime/run-journal.js +0 -28
- package/dist/runtime/services/run-journal-file-service.js +0 -20
|
@@ -59,15 +59,6 @@ ecosystem_code:
|
|
|
59
59
|
role: long-running goal mode with /goal slash command, persistent state, evidence-gated completion, and TUI sidebar
|
|
60
60
|
default_stack: true
|
|
61
61
|
source: https://www.npmjs.com/package/@prevalentware/opencode-goal-plugin
|
|
62
|
-
- id: oc-codex-multi-auth
|
|
63
|
-
name: oc-codex-multi-auth
|
|
64
|
-
package: oc-codex-multi-auth
|
|
65
|
-
plugin:
|
|
66
|
-
kind: npm
|
|
67
|
-
package: oc-codex-multi-auth@6.3.2
|
|
68
|
-
role: ChatGPT Plus/Pro OAuth with multi-account rotation, health checks, and Codex/GPT-5 routing for OpenCode
|
|
69
|
-
default_stack: true
|
|
70
|
-
source: https://github.com/ndycode/oc-codex-multi-auth
|
|
71
62
|
- id: opencode-snip
|
|
72
63
|
name: opencode-snip
|
|
73
64
|
role: prompt snippet and command-discipline helper patterns
|
|
@@ -86,9 +77,8 @@ ecosystem_code:
|
|
|
86
77
|
# Reasoning effort is no longer expressed as synthetic per-effort model ids.
|
|
87
78
|
# Pipeline config carries `reasoning_effort` as data on each node/profile and the
|
|
88
79
|
# runner applies it as the opencode model variant (`--variant` / prompt body
|
|
89
|
-
# `variant`) for the selected GPT-5 model.
|
|
90
|
-
#
|
|
91
|
-
# reasoning.encrypted_content), so moka registers no provider models here.
|
|
80
|
+
# `variant`) for the selected GPT-5 model. Broker auth owns Codex request
|
|
81
|
+
# options, so moka registers no provider models here.
|
|
92
82
|
mcp_backends:
|
|
93
83
|
- id: pipeline-gateway
|
|
94
84
|
locality: project-remote
|
package/defaults/pipeline.yaml
CHANGED
|
@@ -11,10 +11,6 @@ context_handoff:
|
|
|
11
11
|
# seeded by the node's task + handoff artifacts, within token_budget.
|
|
12
12
|
repo_map:
|
|
13
13
|
enabled: true
|
|
14
|
-
# durability: journal each terminal node result so a killed run resumes from the
|
|
15
|
-
# last passed node without re-running (or re-spending tokens on) finished work.
|
|
16
|
-
durability:
|
|
17
|
-
enabled: true
|
|
18
14
|
# parallel_worktrees: opt-in git-worktree isolation for parallel child nodes —
|
|
19
15
|
# each parallel child runs on its own branch with its own per-worktree opencode
|
|
20
16
|
# server so concurrent edits and sessions can't collide. OFF by default; enable
|
package/dist/argo-submit.d.ts
CHANGED
|
@@ -20,13 +20,11 @@ declare const submitRunnerArgoWorkflowOptionsSchema: z.ZodObject<{
|
|
|
20
20
|
kubeconfigPath: z.ZodOptional<z.ZodString>;
|
|
21
21
|
name: z.ZodOptional<z.ZodString>;
|
|
22
22
|
namespace: z.ZodString;
|
|
23
|
-
brokerAuth: z.
|
|
23
|
+
brokerAuth: z.ZodObject<{
|
|
24
24
|
secretKey: z.ZodDefault<z.ZodString>;
|
|
25
25
|
secretName: z.ZodString;
|
|
26
26
|
url: z.ZodDefault<z.ZodString>;
|
|
27
|
-
}, z.core.$strict
|
|
28
|
-
opencodeAuthSecretName: z.ZodOptional<z.ZodString>;
|
|
29
|
-
opencodeOpenaiAccountsSecretName: z.ZodOptional<z.ZodString>;
|
|
27
|
+
}, z.core.$strict>;
|
|
30
28
|
payloadJson: z.ZodString;
|
|
31
29
|
scheduleYaml: z.ZodString;
|
|
32
30
|
serviceAccountName: z.ZodOptional<z.ZodString>;
|
package/dist/argo-submit.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { ArgoGraphCompilerError, compileArgoExecutionGraph } from "./argo-graph.js";
|
|
2
2
|
import { brokerAuthOptionSchema } from "./broker-auth.js";
|
|
3
|
+
import { compileScheduleArtifact, parseScheduleArtifact } from "./planning/generate.js";
|
|
3
4
|
import { parseRunnerCommandPayload, runnerCommandPayloadSchema } from "./runner-command-contract.js";
|
|
4
5
|
import { buildRunnerTaskDescriptor } from "./runner-command/task-descriptor.js";
|
|
5
6
|
import { buildRunnerArgoWorkflowManifest, runnerArgoWorkflowManifestSchema } from "./argo-workflow.js";
|
|
6
7
|
import { normalizeRunnerRepositoryForSubmit } from "./git-remote-url.js";
|
|
7
|
-
import { compileScheduleArtifact, parseScheduleArtifact } from "./planning/generate.js";
|
|
8
8
|
import { KubernetesArgoService, KubernetesArgoServiceLive } from "./runtime/services/kubernetes-argo-service.js";
|
|
9
9
|
import { workflowSubmitResultSchema } from "./workflow-submit-contract.js";
|
|
10
10
|
import { stringify } from "yaml";
|
|
@@ -39,9 +39,7 @@ const submitRunnerArgoWorkflowOptionsSchema = z.object({
|
|
|
39
39
|
kubeconfigPath: z.string().min(1).optional(),
|
|
40
40
|
name: z.string().min(1).optional(),
|
|
41
41
|
namespace: z.string().min(1),
|
|
42
|
-
brokerAuth: brokerAuthOptionSchema
|
|
43
|
-
opencodeAuthSecretName: z.string().min(1).optional(),
|
|
44
|
-
opencodeOpenaiAccountsSecretName: z.string().min(1).optional(),
|
|
42
|
+
brokerAuth: brokerAuthOptionSchema,
|
|
45
43
|
payloadJson: z.string().min(1),
|
|
46
44
|
scheduleYaml: z.string().min(1),
|
|
47
45
|
serviceAccountName: z.string().min(1).optional()
|
|
@@ -92,8 +90,6 @@ function submitRunnerArgoWorkflowEffect(rawOptions, dependencies) {
|
|
|
92
90
|
name: options.name,
|
|
93
91
|
namespace: options.namespace,
|
|
94
92
|
brokerAuth: options.brokerAuth,
|
|
95
|
-
opencodeAuthSecretName: options.opencodeAuthSecretName,
|
|
96
|
-
opencodeOpenaiAccountsSecret: options.opencodeOpenaiAccountsSecretName ? { name: options.opencodeOpenaiAccountsSecretName } : void 0,
|
|
97
93
|
payloadConfigMapName,
|
|
98
94
|
plan: compiled.plan,
|
|
99
95
|
scheduleConfigMapName: scheduleArtifactConfigMapName,
|
package/dist/argo-workflow.d.ts
CHANGED
|
@@ -145,16 +145,11 @@ declare const buildRunnerArgoWorkflowOptionsSchema: z.ZodObject<{
|
|
|
145
145
|
labels: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodOptional<z.ZodString>>>;
|
|
146
146
|
name: z.ZodOptional<z.ZodString>;
|
|
147
147
|
namespace: z.ZodString;
|
|
148
|
-
brokerAuth: z.
|
|
148
|
+
brokerAuth: z.ZodObject<{
|
|
149
149
|
secretKey: z.ZodDefault<z.ZodString>;
|
|
150
150
|
secretName: z.ZodString;
|
|
151
151
|
url: z.ZodDefault<z.ZodString>;
|
|
152
|
-
}, z.core.$strict
|
|
153
|
-
opencodeAuthSecretName: z.ZodOptional<z.ZodString>;
|
|
154
|
-
opencodeOpenaiAccountsSecret: z.ZodOptional<z.ZodObject<{
|
|
155
|
-
key: z.ZodOptional<z.ZodString>;
|
|
156
|
-
name: z.ZodString;
|
|
157
|
-
}, z.core.$strict>>;
|
|
152
|
+
}, z.core.$strict>;
|
|
158
153
|
payloadConfigMapKey: z.ZodDefault<z.ZodString>;
|
|
159
154
|
payloadConfigMapName: z.ZodString;
|
|
160
155
|
resources: z.ZodOptional<z.ZodObject<{
|
package/dist/argo-workflow.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { compileArgoExecutionGraph } from "./argo-graph.js";
|
|
2
|
-
import { OPENCODE_AUTH_STAGING_DIR, OPENCODE_OPENAI_ACCOUNTS_STAGING_DIR } from "./run-state/opencode-accounts.js";
|
|
3
2
|
import { DEFAULT_RUNNER_TASK_DESCRIPTOR_PATH } from "./runner-command/task-descriptor.js";
|
|
4
3
|
import { stringify } from "yaml";
|
|
5
4
|
import { z } from "zod";
|
|
@@ -27,6 +26,10 @@ const RUNNER_OPENCODE_ENV = [
|
|
|
27
26
|
name: "PIPELINE_AGENT_TIMEOUT_MS",
|
|
28
27
|
value: "600000"
|
|
29
28
|
},
|
|
29
|
+
{
|
|
30
|
+
name: "PIPELINE_AGENT_IDLE_TIMEOUT_MS",
|
|
31
|
+
value: "180000"
|
|
32
|
+
},
|
|
30
33
|
{
|
|
31
34
|
name: "PIPELINE_DISABLED_MODELS",
|
|
32
35
|
value: "opencode-go/qwen3.7-max"
|
|
@@ -180,12 +183,7 @@ const buildRunnerArgoWorkflowOptionsSchema = z.object({
|
|
|
180
183
|
secretKey: z.string().min(1).default("api-key"),
|
|
181
184
|
secretName: kubernetesNameSchema,
|
|
182
185
|
url: z.string().min(1).default("https://cliproxy.momokaya.ee")
|
|
183
|
-
}).strict()
|
|
184
|
-
opencodeAuthSecretName: kubernetesNameSchema.optional(),
|
|
185
|
-
opencodeOpenaiAccountsSecret: z.object({
|
|
186
|
-
key: z.string().min(1).optional(),
|
|
187
|
-
name: kubernetesNameSchema
|
|
188
|
-
}).strict().optional(),
|
|
186
|
+
}).strict(),
|
|
189
187
|
payloadConfigMapKey: z.string().min(1).default("payload.json"),
|
|
190
188
|
payloadConfigMapName: kubernetesNameSchema,
|
|
191
189
|
resources: argoWorkflowResourceRequirementsSchema.optional(),
|
|
@@ -312,43 +310,6 @@ function runnerWorkflowStorage(options, tasks) {
|
|
|
312
310
|
readOnly: true
|
|
313
311
|
});
|
|
314
312
|
}
|
|
315
|
-
if (options.opencodeAuthSecretName) {
|
|
316
|
-
volumes.push({
|
|
317
|
-
name: "opencode-auth",
|
|
318
|
-
secret: {
|
|
319
|
-
defaultMode: 256,
|
|
320
|
-
items: [{
|
|
321
|
-
key: "auth.json",
|
|
322
|
-
path: "auth.json"
|
|
323
|
-
}],
|
|
324
|
-
secretName: options.opencodeAuthSecretName
|
|
325
|
-
}
|
|
326
|
-
});
|
|
327
|
-
volumeMounts.push({
|
|
328
|
-
mountPath: OPENCODE_AUTH_STAGING_DIR,
|
|
329
|
-
name: "opencode-auth",
|
|
330
|
-
readOnly: true
|
|
331
|
-
});
|
|
332
|
-
}
|
|
333
|
-
if (options.opencodeOpenaiAccountsSecret) {
|
|
334
|
-
const accountsKey = options.opencodeOpenaiAccountsSecret.key ?? "accounts.json";
|
|
335
|
-
volumes.push({
|
|
336
|
-
name: "opencode-openai-accounts",
|
|
337
|
-
secret: {
|
|
338
|
-
defaultMode: 256,
|
|
339
|
-
items: [{
|
|
340
|
-
key: accountsKey,
|
|
341
|
-
path: "accounts.json"
|
|
342
|
-
}],
|
|
343
|
-
secretName: options.opencodeOpenaiAccountsSecret.name
|
|
344
|
-
}
|
|
345
|
-
});
|
|
346
|
-
volumeMounts.push({
|
|
347
|
-
mountPath: OPENCODE_OPENAI_ACCOUNTS_STAGING_DIR,
|
|
348
|
-
name: "opencode-openai-accounts",
|
|
349
|
-
readOnly: true
|
|
350
|
-
});
|
|
351
|
-
}
|
|
352
313
|
if (options.gitCredentialsSecretName) {
|
|
353
314
|
volumes.push({
|
|
354
315
|
name: "runner-git-credentials",
|
|
@@ -387,18 +348,25 @@ function runnerWorkflowStorage(options, tasks) {
|
|
|
387
348
|
};
|
|
388
349
|
}
|
|
389
350
|
/**
|
|
390
|
-
* The runner container env:
|
|
391
|
-
*
|
|
392
|
-
*
|
|
351
|
+
* The runner container env: static opencode/agent tuning plus BROKER_URL
|
|
352
|
+
* (literal) and BROKER_API_KEY (sourced from the broker secret key, never
|
|
353
|
+
* inlined into the manifest).
|
|
393
354
|
*/
|
|
394
355
|
function runnerContainerEnv(options) {
|
|
395
|
-
if (!options.brokerAuth) return [...RUNNER_OPENCODE_ENV];
|
|
396
356
|
return [
|
|
397
357
|
...RUNNER_OPENCODE_ENV,
|
|
398
358
|
{
|
|
399
359
|
name: "BROKER_URL",
|
|
400
360
|
value: options.brokerAuth.url
|
|
401
361
|
},
|
|
362
|
+
{
|
|
363
|
+
name: "PIPELINE_BROKER_SECRET_NAME",
|
|
364
|
+
value: options.brokerAuth.secretName
|
|
365
|
+
},
|
|
366
|
+
{
|
|
367
|
+
name: "PIPELINE_BROKER_SECRET_KEY",
|
|
368
|
+
value: options.brokerAuth.secretKey
|
|
369
|
+
},
|
|
402
370
|
{
|
|
403
371
|
name: "BROKER_API_KEY",
|
|
404
372
|
valueFrom: { secretKeyRef: {
|
package/dist/broker-auth.js
CHANGED
|
@@ -39,9 +39,10 @@ const brokerAuthOptionSchema = z.object({
|
|
|
39
39
|
url: z.string().min(1).default(DEFAULT_BROKER_URL)
|
|
40
40
|
}).strict();
|
|
41
41
|
/**
|
|
42
|
-
* Resolve broker credentials from the environment, or `undefined` when
|
|
43
|
-
* runner
|
|
44
|
-
* `BROKER_URL` env is optional and defaults to the
|
|
42
|
+
* Resolve broker credentials from the environment, or `undefined` when a
|
|
43
|
+
* non-runner caller has not supplied broker auth. Remote runner manifests always
|
|
44
|
+
* inject BROKER_API_KEY. The `BROKER_URL` env is optional and defaults to the
|
|
45
|
+
* production broker origin.
|
|
45
46
|
*/
|
|
46
47
|
function resolveBrokerCredentials(env = process.env) {
|
|
47
48
|
const apiKey = env[BROKER_API_KEY_ENV];
|
package/dist/cli/doctor.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { PipelineConfigError } from "../config/schemas.js";
|
|
2
2
|
import { loadPipelineConfig } from "../config/load.js";
|
|
3
3
|
import "../config.js";
|
|
4
|
-
import { opencodeAgentName } from "../runtime/opencode-agent-name.js";
|
|
5
4
|
import { loadMokaGlobalConfig } from "../moka-global-config.js";
|
|
5
|
+
import { opencodeAgentName } from "../runtime/opencode-agent-name.js";
|
|
6
6
|
import { defaultClusterDoctorNamespace, runClusterDoctor } from "../cluster-doctor.js";
|
|
7
7
|
import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
|
|
8
|
-
import { join } from "node:path";
|
|
9
8
|
import { execa } from "execa";
|
|
9
|
+
import { join } from "node:path";
|
|
10
10
|
import matter from "gray-matter";
|
|
11
11
|
//#region src/cli/doctor.ts
|
|
12
12
|
const HEADLESS_AGENT_PERMISSION_VALUES = new Set(["ask"]);
|
package/dist/cli/program.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { RunEffort, RunMode, RunTarget } from "../run-control/contracts.js";
|
|
2
2
|
import { RunCommand } from "./run-command.js";
|
|
3
|
-
import { TicketCommandOptions } from "../commands/ticket
|
|
3
|
+
import { TicketCommandOptions } from "../commands/ticket/shared.js";
|
|
4
4
|
import { runPipelineFromConfig } from "../pipeline-runtime.js";
|
|
5
5
|
import { Effect } from "effect";
|
|
6
6
|
import { Command } from "commander";
|
package/dist/cli/program.js
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import { loadPipelineConfig } from "../config/load.js";
|
|
2
2
|
import "../config.js";
|
|
3
|
+
import { loadMokaGlobalConfig } from "../moka-global-config.js";
|
|
3
4
|
import { flattenNodes } from "../planning/graph.js";
|
|
4
|
-
import { configureGatewayHosts, localGatewayStatus, reconcileGateway, renderGatewayConfig, runGatewayDoctor, startLocalGateway } from "../mcp/gateway.js";
|
|
5
5
|
import { createOrchestratorLaunchPlan, createRunnerLaunchPlan } from "../runner.js";
|
|
6
6
|
import { compileWorkflowPlan } from "../planning/compile.js";
|
|
7
|
+
import { compileScheduleArtifact, generateScheduleArtifact, parseScheduleArtifact } from "../planning/generate.js";
|
|
8
|
+
import { withRunControlStoreScoped } from "../run-control/run-control-store.js";
|
|
9
|
+
import { configureGatewayHosts, localGatewayStatus, reconcileGateway, renderGatewayConfig, runGatewayDoctor, startLocalGateway } from "../mcp/gateway.js";
|
|
7
10
|
import { generateRuntimeRunId, resolveWorkflowSelection } from "../runtime/context/context.js";
|
|
8
11
|
import "../runtime/context/index.js";
|
|
9
12
|
import { runPipelineFromConfig } from "../pipeline-runtime.js";
|
|
10
|
-
import { compileScheduleArtifact, generateScheduleArtifact, parseScheduleArtifact } from "../planning/generate.js";
|
|
11
13
|
import { formatCodexAuthSyncResult, syncLocalCodexAuth } from "../codex-auth-sync.js";
|
|
12
14
|
import { registerBenchCommand } from "../commands/bench-command.js";
|
|
13
15
|
import { registerConfiguredEntrypointCommands } from "../commands/pipeline-command.js";
|
|
@@ -17,9 +19,7 @@ import { registerTicketCommand } from "../commands/ticket-command.js";
|
|
|
17
19
|
import { formatConfigLintWarning, lintPipelineConfig } from "../config/lint.js";
|
|
18
20
|
import { parseLoopFlags, runLoopSubmit } from "../loop/loop-command.js";
|
|
19
21
|
import { runLoopControllerEntrypoint } from "../loop/loop-controller-entrypoint.js";
|
|
20
|
-
import { loadMokaGlobalConfig } from "../moka-global-config.js";
|
|
21
22
|
import { formatPipelineInitResult, initPipelineProject } from "../pipeline-init.js";
|
|
22
|
-
import { createRun, runControlStatusPaths, updateRunController } from "../run-control/store.js";
|
|
23
23
|
import { registerRunControlCommands } from "../run-control/commands.js";
|
|
24
24
|
import { startDetachedRunController } from "../run-control/detach.js";
|
|
25
25
|
import { createRunStoreRuntimeReporter } from "../run-control/runtime-reporter.js";
|
|
@@ -78,10 +78,12 @@ async function runConfiguredPipeline(rawInputs) {
|
|
|
78
78
|
const inputs = withRunId(rawInputs);
|
|
79
79
|
const config = loadPipelineConfig(inputs.worktreePath, { allowMissingLintFileReferences: true });
|
|
80
80
|
if (inputs.schedule) {
|
|
81
|
-
const
|
|
81
|
+
const scheduleYaml = readFileSync(inputs.schedule, "utf8");
|
|
82
|
+
const compiled = compileScheduleArtifact(config, parseScheduleArtifact(scheduleYaml, inputs.schedule), inputs.worktreePath);
|
|
82
83
|
await runAndPrintPipeline({
|
|
83
84
|
...inputs,
|
|
84
85
|
config: compiled.config,
|
|
86
|
+
scheduleArtifact: scheduleYaml,
|
|
85
87
|
workflow: compiled.workflowId
|
|
86
88
|
});
|
|
87
89
|
return;
|
|
@@ -103,10 +105,12 @@ async function runConfiguredPipeline(rawInputs) {
|
|
|
103
105
|
worktreePath: inputs.worktreePath
|
|
104
106
|
});
|
|
105
107
|
console.log(`Schedule generated: ${result.path}`);
|
|
106
|
-
const
|
|
108
|
+
const scheduleYaml = readFileSync(resolve(inputs.worktreePath, result.path), "utf8");
|
|
109
|
+
const compiled = compileScheduleArtifact(config, parseScheduleArtifact(scheduleYaml, result.path), inputs.worktreePath);
|
|
107
110
|
await runAndPrintPipeline({
|
|
108
111
|
...inputs,
|
|
109
112
|
config: compiled.config,
|
|
113
|
+
scheduleArtifact: scheduleYaml,
|
|
110
114
|
workflow: compiled.workflowId
|
|
111
115
|
});
|
|
112
116
|
return;
|
|
@@ -117,8 +121,14 @@ async function runConfiguredPipeline(rawInputs) {
|
|
|
117
121
|
});
|
|
118
122
|
}
|
|
119
123
|
async function runAndPrintPipeline(inputs) {
|
|
124
|
+
await Effect.runPromise(withRunControlStoreScoped(inputs.worktreePath, (store) => Effect.tryPromise({
|
|
125
|
+
catch: (error) => error,
|
|
126
|
+
try: () => runAndPrintPipelineWithStore(inputs, store)
|
|
127
|
+
})));
|
|
128
|
+
}
|
|
129
|
+
async function runAndPrintPipelineWithStore(inputs, store) {
|
|
120
130
|
const runner = inputs.pipelineRunner ?? runPipelineFromConfig;
|
|
121
|
-
const runStoreReporter = await createRunStoreReporter(inputs, createTerminalRuntimeReporter());
|
|
131
|
+
const runStoreReporter = await createRunStoreReporter(inputs, createTerminalRuntimeReporter(), store);
|
|
122
132
|
if (inputs.supervised) console.log(formatSupervisedRunFollowUp(requireRunId(inputs.runId)));
|
|
123
133
|
let result;
|
|
124
134
|
try {
|
|
@@ -144,27 +154,29 @@ async function runWithFlushedReporter(flush, run) {
|
|
|
144
154
|
await flush();
|
|
145
155
|
}
|
|
146
156
|
}
|
|
147
|
-
async function createLocalRunStoreRuntimeReporter(inputs, reporter) {
|
|
157
|
+
async function createLocalRunStoreRuntimeReporter(inputs, reporter, store) {
|
|
148
158
|
const runId = requireRunId(inputs.runId);
|
|
149
|
-
await createRun({
|
|
159
|
+
await Effect.runPromise(store.createRun({
|
|
150
160
|
...resolvedRunControlOptions(inputs.runControl),
|
|
151
161
|
nodeIds: plannedRunStoreNodeIds(inputs),
|
|
152
162
|
runId,
|
|
153
|
-
|
|
154
|
-
});
|
|
163
|
+
...inputs.scheduleArtifact ? { schedule: inputs.scheduleArtifact } : {}
|
|
164
|
+
}));
|
|
155
165
|
return createRunStoreRuntimeReporter({
|
|
156
166
|
reporter,
|
|
157
167
|
runId,
|
|
168
|
+
store,
|
|
158
169
|
workspaceRoot: inputs.worktreePath
|
|
159
170
|
});
|
|
160
171
|
}
|
|
161
|
-
function createRunStoreReporter(inputs, reporter) {
|
|
172
|
+
function createRunStoreReporter(inputs, reporter, store) {
|
|
162
173
|
if (inputs.runStoreMode === "reuse") {
|
|
163
174
|
const runId = requireRunId(inputs.runId);
|
|
164
175
|
if (inputs.supervisor) {
|
|
165
176
|
const supervisor = createRunControlSupervisor({
|
|
166
177
|
reporter,
|
|
167
178
|
runId,
|
|
179
|
+
store,
|
|
168
180
|
workspaceRoot: inputs.worktreePath
|
|
169
181
|
});
|
|
170
182
|
supervisor.start();
|
|
@@ -176,10 +188,11 @@ function createRunStoreReporter(inputs, reporter) {
|
|
|
176
188
|
return createRunStoreRuntimeReporter({
|
|
177
189
|
reporter,
|
|
178
190
|
runId,
|
|
191
|
+
store,
|
|
179
192
|
workspaceRoot: inputs.worktreePath
|
|
180
193
|
});
|
|
181
194
|
}
|
|
182
|
-
return createLocalRunStoreRuntimeReporter(inputs, reporter);
|
|
195
|
+
return createLocalRunStoreRuntimeReporter(inputs, reporter, store);
|
|
183
196
|
}
|
|
184
197
|
function requireRunId(runId) {
|
|
185
198
|
if (!runId) throw new Error("Run id is required for local run-control persistence.");
|
|
@@ -343,7 +356,7 @@ function createCliProgram(options = {}) {
|
|
|
343
356
|
dryRun: flags.dryRun
|
|
344
357
|
}));
|
|
345
358
|
});
|
|
346
|
-
program.command("codex-auth").description("Manage local Codex
|
|
359
|
+
program.command("codex-auth").description("Manage local Codex broker auth integration").command("sync-local").description("Point local dev repos' opencode openai provider at the central CLIProxyAPI broker").option("--root <path>", "directory containing repositories to sync").option("--dry-run", "show planned changes without writing files").option("--check", "fail if local Codex auth config is not synced").action((flags) => {
|
|
347
360
|
const result = syncLocalCodexAuth({
|
|
348
361
|
check: flags.check,
|
|
349
362
|
dryRun: flags.dryRun,
|
|
@@ -352,12 +365,7 @@ function createCliProgram(options = {}) {
|
|
|
352
365
|
console.log(formatCodexAuthSyncResult(result));
|
|
353
366
|
if (!result.ok) process.exitCode = 1;
|
|
354
367
|
});
|
|
355
|
-
addMokaSubmitOptions(program.command("submit").description([
|
|
356
|
-
"Submit work to Momokaya as an Argo Workflow.",
|
|
357
|
-
"Compatibility alias for `moka run \"<task>\" --target remote --effort thorough`.",
|
|
358
|
-
"Quick equivalent: `moka run \"<task>\" --target remote --effort quick`.",
|
|
359
|
-
"Command equivalent: `moka run --target remote --command -- <argv...>`."
|
|
360
|
-
].join("\n")).argument("[input...]", "task description, or command argv with --command")).action(async (input, flags) => {
|
|
368
|
+
addMokaSubmitOptions(program.command("submit").description("Submit work to Momokaya as an Argo Workflow.").argument("[input...]", "task description, or command argv with --command")).action(async (input, flags) => {
|
|
361
369
|
printMokaSubmitResult(await runMokaSubmitFromCli(input, flags));
|
|
362
370
|
});
|
|
363
371
|
registerLoopCommand(program);
|
|
@@ -407,7 +415,10 @@ function buildLoopSubmitInput(options) {
|
|
|
407
415
|
const cwd = process.env.PIPELINE_TARGET_PATH ?? process.cwd();
|
|
408
416
|
const config = loadPipelineConfig(cwd, { allowMissingLintFileReferences: true });
|
|
409
417
|
const momokaya = loadMokaGlobalConfig()?.momokaya;
|
|
418
|
+
const brokerAuth = momokaya?.submit.brokerAuth;
|
|
419
|
+
if (!brokerAuth) throw new Error("momokaya.submit.brokerAuth is required for moka loop submit");
|
|
410
420
|
return {
|
|
421
|
+
brokerAuth,
|
|
411
422
|
config,
|
|
412
423
|
eventUrl: momokaya?.submit.eventUrl,
|
|
413
424
|
flags: parseLoopFlags(options),
|
|
@@ -415,9 +426,6 @@ function buildLoopSubmitInput(options) {
|
|
|
415
426
|
githubAuthSecretName: momokaya?.submit.githubAuthSecretName,
|
|
416
427
|
kubeconfigPath: momokaya?.kubernetes.kubeconfig,
|
|
417
428
|
namespace: momokaya?.kubernetes.namespace,
|
|
418
|
-
brokerAuth: momokaya?.submit.brokerAuth,
|
|
419
|
-
opencodeAuthSecretName: momokaya?.submit.opencodeAuthSecretName,
|
|
420
|
-
opencodeOpenaiAccountsSecretName: momokaya?.submit.opencodeOpenaiAccountsSecretName,
|
|
421
429
|
serviceAccountName: momokaya?.submit.serviceAccountName,
|
|
422
430
|
worktreePath: cwd
|
|
423
431
|
};
|
|
@@ -441,52 +449,55 @@ async function runDetachedResolvedTask(task, execution, runControl) {
|
|
|
441
449
|
task,
|
|
442
450
|
worktreePath
|
|
443
451
|
});
|
|
444
|
-
await
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
452
|
+
await Effect.runPromise(withRunControlStoreScoped(worktreePath, (store) => Effect.gen(function* () {
|
|
453
|
+
yield* store.createRun({
|
|
454
|
+
...resolvedRunControlOptions(runControl),
|
|
455
|
+
nodeIds: plannedRunStoreNodeIds({
|
|
456
|
+
config: prepared.config,
|
|
457
|
+
entrypoint: prepared.entrypoint,
|
|
458
|
+
runId,
|
|
459
|
+
runControl,
|
|
460
|
+
schedule: prepared.schedule,
|
|
461
|
+
task,
|
|
462
|
+
workflow: prepared.workflow,
|
|
463
|
+
worktreePath
|
|
464
|
+
}),
|
|
449
465
|
runId,
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
runId,
|
|
457
|
-
workspaceRoot: worktreePath
|
|
458
|
-
});
|
|
459
|
-
const launch = await startDetachedRunController({
|
|
460
|
-
entrypoint: prepared.entrypoint,
|
|
461
|
-
runId,
|
|
462
|
-
schedule: prepared.schedule,
|
|
463
|
-
task,
|
|
464
|
-
workflow: prepared.workflow,
|
|
465
|
-
workspaceRoot: worktreePath
|
|
466
|
-
});
|
|
467
|
-
await updateRunController({
|
|
468
|
-
controller: {
|
|
469
|
-
argv: launch.argv,
|
|
470
|
-
cwd: worktreePath,
|
|
471
|
-
paths: runControlStatusPaths({
|
|
466
|
+
...prepared.scheduleArtifact ? { schedule: prepared.scheduleArtifact } : {}
|
|
467
|
+
});
|
|
468
|
+
const launch = yield* Effect.tryPromise({
|
|
469
|
+
catch: (error) => error,
|
|
470
|
+
try: () => startDetachedRunController({
|
|
471
|
+
entrypoint: prepared.entrypoint,
|
|
472
472
|
runId,
|
|
473
|
+
schedule: prepared.schedule,
|
|
474
|
+
task,
|
|
475
|
+
workflow: prepared.workflow,
|
|
473
476
|
workspaceRoot: worktreePath
|
|
474
|
-
})
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
477
|
+
})
|
|
478
|
+
});
|
|
479
|
+
yield* store.updateRunController({
|
|
480
|
+
controller: {
|
|
481
|
+
argv: launch.argv,
|
|
482
|
+
cwd: worktreePath,
|
|
483
|
+
paths: store.statusPaths({ runId }),
|
|
484
|
+
pid: launch.pid,
|
|
485
|
+
startedAt: launch.startedAt
|
|
486
|
+
},
|
|
487
|
+
runId
|
|
488
|
+
});
|
|
489
|
+
})));
|
|
481
490
|
console.log(formatDetachedRunFollowUp(runId));
|
|
482
491
|
}
|
|
483
492
|
async function prepareDetachedRun(input) {
|
|
484
493
|
if (input.execution.schedule) {
|
|
485
494
|
const schedule = resolve(input.execution.schedule);
|
|
486
|
-
const
|
|
495
|
+
const scheduleYaml = readFileSync(schedule, "utf8");
|
|
496
|
+
const compiled = compileScheduleArtifact(input.config, parseScheduleArtifact(scheduleYaml, schedule), input.worktreePath);
|
|
487
497
|
return {
|
|
488
498
|
config: compiled.config,
|
|
489
499
|
schedule,
|
|
500
|
+
scheduleArtifact: scheduleYaml,
|
|
490
501
|
workflow: compiled.workflowId
|
|
491
502
|
};
|
|
492
503
|
}
|
|
@@ -505,10 +516,12 @@ async function prepareDetachedRun(input) {
|
|
|
505
516
|
});
|
|
506
517
|
console.log(`Schedule generated: ${result.path}`);
|
|
507
518
|
const schedule = resolve(input.worktreePath, result.path);
|
|
508
|
-
const
|
|
519
|
+
const scheduleYaml = readFileSync(schedule, "utf8");
|
|
520
|
+
const compiled = compileScheduleArtifact(input.config, parseScheduleArtifact(scheduleYaml, result.path), input.worktreePath);
|
|
509
521
|
return {
|
|
510
522
|
config: compiled.config,
|
|
511
523
|
schedule,
|
|
524
|
+
scheduleArtifact: scheduleYaml,
|
|
512
525
|
workflow: compiled.workflowId
|
|
513
526
|
};
|
|
514
527
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { loadPipelineConfig } from "../config/load.js";
|
|
2
2
|
import "../config.js";
|
|
3
|
-
import { submitMoka } from "../moka-submit.js";
|
|
4
3
|
import { loadMokaGlobalConfig } from "../moka-global-config.js";
|
|
4
|
+
import { submitMoka } from "../moka-submit.js";
|
|
5
5
|
import { Option } from "commander";
|
|
6
6
|
//#region src/cli/submit-options.ts
|
|
7
7
|
function addMokaSubmitOptions(command) {
|
|
@@ -34,6 +34,7 @@ function resolveMokaEventUrl(flags, globalConfig) {
|
|
|
34
34
|
function mokaCommonSubmitOptions(input) {
|
|
35
35
|
const momokaya = input.globalConfig?.momokaya;
|
|
36
36
|
return {
|
|
37
|
+
brokerAuth: resolveMokaBrokerAuth(input.globalConfig),
|
|
37
38
|
config: input.config,
|
|
38
39
|
delivery: { pullRequest: input.flags.openPr === true },
|
|
39
40
|
eventUrl: input.eventUrl,
|
|
@@ -48,13 +49,15 @@ function mokaCommonSubmitOptions(input) {
|
|
|
48
49
|
kubeconfigPath: input.flags.kubeconfig ?? momokaya?.kubernetes.kubeconfig,
|
|
49
50
|
name: input.flags.name,
|
|
50
51
|
namespace: input.flags.namespace ?? momokaya?.kubernetes.namespace,
|
|
51
|
-
brokerAuth: momokaya?.submit.brokerAuth,
|
|
52
|
-
opencodeAuthSecretName: momokaya?.submit.opencodeAuthSecretName,
|
|
53
|
-
opencodeOpenaiAccountsSecretName: momokaya?.submit.opencodeOpenaiAccountsSecretName,
|
|
54
52
|
serviceAccountName: input.flags.serviceAccount ?? momokaya?.submit.serviceAccountName,
|
|
55
53
|
worktreePath: input.cwd
|
|
56
54
|
};
|
|
57
55
|
}
|
|
56
|
+
function resolveMokaBrokerAuth(globalConfig) {
|
|
57
|
+
const brokerAuth = globalConfig?.momokaya.submit.brokerAuth;
|
|
58
|
+
if (!brokerAuth) throw new Error("momokaya.submit.brokerAuth is required for remote submit");
|
|
59
|
+
return brokerAuth;
|
|
60
|
+
}
|
|
58
61
|
function submitMokaCommandInput(input, flags, commonOptions) {
|
|
59
62
|
if (flags.quick || flags.schedule) throw new Error("--command cannot be combined with --quick or --schedule");
|
|
60
63
|
if (input.length === 0) throw new Error("Command argv is required when --command is set");
|
package/dist/cluster-doctor.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import { KubernetesArgoService, KubernetesArgoServiceLive } from "./runtime/services/kubernetes-argo-service.js";
|
|
2
1
|
import { loadMokaGlobalConfig } from "./moka-global-config.js";
|
|
2
|
+
import { KubernetesArgoService, KubernetesArgoServiceLive } from "./runtime/services/kubernetes-argo-service.js";
|
|
3
3
|
import { Effect } from "effect";
|
|
4
4
|
//#region src/cluster-doctor.ts
|
|
5
5
|
const DEFAULT_NAMESPACE = "momokaya-pipeline";
|
|
6
6
|
const DEFAULT_RESOURCES = {
|
|
7
|
+
brokerAuthSecretName: "broker-api-key",
|
|
7
8
|
eventAuthSecretName: "pipeline-runner-event-auth",
|
|
8
9
|
eventAuthExternalSecretName: "pipeline-runner-event-auth",
|
|
9
10
|
externalSecretRemoteRef: "agent-runtime/pipeline-runner/event-auth",
|
|
10
11
|
gitCredentialsSecretName: "oisin-bot-git-credentials",
|
|
11
12
|
githubAuthSecretName: "oisin-bot-github-auth",
|
|
12
13
|
imagePullSecretName: "ghcr-pull-secret",
|
|
13
|
-
opencodeAuthSecretName: "opencode-auth-1",
|
|
14
14
|
serviceAccountName: "pipeline-runner"
|
|
15
15
|
};
|
|
16
16
|
const FORBIDDEN_RE = /forbidden/i;
|
|
@@ -62,17 +62,16 @@ function clusterResources() {
|
|
|
62
62
|
const configured = loadMokaGlobalConfig()?.momokaya.submit;
|
|
63
63
|
return configured ? {
|
|
64
64
|
...DEFAULT_RESOURCES,
|
|
65
|
-
brokerAuthSecretName: configured.brokerAuth?.secretName,
|
|
65
|
+
brokerAuthSecretName: configured.brokerAuth?.secretName ?? DEFAULT_RESOURCES.brokerAuthSecretName,
|
|
66
66
|
eventAuthSecretName: configured.eventAuthSecretName,
|
|
67
67
|
gitCredentialsSecretName: configured.gitCredentialsSecretName,
|
|
68
68
|
githubAuthSecretName: configured.githubAuthSecretName,
|
|
69
69
|
imagePullSecretName: configured.imagePullSecretName,
|
|
70
|
-
opencodeAuthSecretName: configured.opencodeAuthSecretName ?? DEFAULT_RESOURCES.opencodeAuthSecretName,
|
|
71
70
|
serviceAccountName: configured.serviceAccountName
|
|
72
71
|
} : DEFAULT_RESOURCES;
|
|
73
72
|
}
|
|
74
73
|
function secretChecks(namespace, kubectlOptions, resources) {
|
|
75
|
-
const authSecretCheck =
|
|
74
|
+
const authSecretCheck = [resources.brokerAuthSecretName, `Secret ${resources.brokerAuthSecretName} missing in ${namespace}; expected broker api-key mount by name.`];
|
|
76
75
|
return [
|
|
77
76
|
[resources.eventAuthSecretName, eventAuthMissingDetail(namespace)],
|
|
78
77
|
[resources.imagePullSecretName, `Secret ${resources.imagePullSecretName} missing in ${namespace}; expected imagePullSecret for ghcr.io/oisin-ee/pipeline-runner.`],
|