@oisincoveney/pipeline 1.26.1 → 1.27.1
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/.agents/skills/inspect/SKILL.md +1 -1
- package/README.md +10 -3
- package/defaults/opencode-ecosystem.yaml +14 -14
- package/dist/config.d.ts +5 -5
- package/dist/config.js +54 -34
- package/dist/hooks.d.ts +1 -1
- package/dist/install-commands.js +23 -10
- package/dist/moka-submit.d.ts +174 -1
- package/dist/moka-submit.js +127 -9
- package/dist/runner-command/run.js +1 -1
- package/dist/runner-command-contract.d.ts +20 -2
- package/dist/runner-command-contract.js +11 -1
- package/dist/runner.js +1 -1
- package/dist/runtime/goal-loop.js +1 -1
- package/dist/schedule-planner.js +14 -14
- package/docs/config-architecture.md +4 -4
- package/docs/mcp-gateway.md +2 -2
- package/docs/operator-guide.md +12 -2
- package/package.json +1 -1
|
@@ -23,7 +23,7 @@ Orchestrate package-owned pipeline config.
|
|
|
23
23
|
Run workflow `inspect` for the user task.
|
|
24
24
|
These nodes are not Codex native routes.
|
|
25
25
|
CLI routes:
|
|
26
|
-
- inspect: opencode CLI profile=
|
|
26
|
+
- inspect: opencode CLI profile=moka-inspector command=`opencode run --agent "MoKa Inspector" --format json --dir <repo-root> <node prompt>` needs=none
|
|
27
27
|
|
|
28
28
|
For each CLI node prompt include:
|
|
29
29
|
- user task
|
package/README.md
CHANGED
|
@@ -164,10 +164,17 @@ validation, contract-version checks, and JSON Schema generation.
|
|
|
164
164
|
|
|
165
165
|
Pipeline Console submits hosted runs through `@oisincoveney/pipeline/moka-submit`.
|
|
166
166
|
The subpath exports `mokaSubmitOptionsSchema`, `mokaSubmitResultSchema`,
|
|
167
|
-
`
|
|
167
|
+
`mokaSubmitDirectHooksSchema`, `mokaSubmitHookPolicySchema`,
|
|
168
|
+
`MokaSubmitOptionsInput`, `MokaSubmitOptionsOutput`,
|
|
169
|
+
`MokaSubmitDirectHooksInput`, `MokaSubmitHookPolicyInput`, `MokaSubmitInput`,
|
|
168
170
|
`MokaSubmitOutput`, and `submitMoka` so callers can validate prompt or ticket
|
|
169
|
-
tasks with explicit repository, run, delivery, event sink,
|
|
170
|
-
without importing Argo, Kubernetes, or
|
|
171
|
+
tasks with explicit repository, run, delivery, event sink, lifecycle hooks, hook
|
|
172
|
+
policy, and runner settings without importing Argo, Kubernetes, or
|
|
173
|
+
runner-command internals. `eventSink` is runner event transport; direct `hooks`
|
|
174
|
+
configure runner-side lifecycle behavior and are normalized into internal
|
|
175
|
+
runtime hook config by the package. Direct hook function ids are generated as
|
|
176
|
+
`moka-submit-<event-name-with-dashes>`; existing package hooks are preserved,
|
|
177
|
+
and a generated id that already exists in the supplied config is rejected.
|
|
171
178
|
|
|
172
179
|
## Configuration Model
|
|
173
180
|
|
|
@@ -148,50 +148,50 @@ skills:
|
|
|
148
148
|
used_by: [orchestrator]
|
|
149
149
|
- id: inspect
|
|
150
150
|
path: .agents/skills/inspect/SKILL.md
|
|
151
|
-
used_by: [
|
|
151
|
+
used_by: [moka-inspector]
|
|
152
152
|
- id: epic
|
|
153
153
|
path: .agents/skills/epic/SKILL.md
|
|
154
|
-
used_by: [
|
|
154
|
+
used_by: [moka-epic-router]
|
|
155
155
|
- id: execute
|
|
156
156
|
path: .agents/skills/execute/SKILL.md
|
|
157
|
-
used_by: [
|
|
157
|
+
used_by: [moka-code-writer]
|
|
158
158
|
- id: research
|
|
159
159
|
path: .agents/skills/research/SKILL.md
|
|
160
|
-
used_by: [
|
|
160
|
+
used_by: [moka-researcher]
|
|
161
161
|
- id: library-first-development
|
|
162
162
|
path: .agents/skills/library-first-development/SKILL.md
|
|
163
|
-
used_by: [
|
|
163
|
+
used_by: [moka-researcher, moka-code-writer]
|
|
164
164
|
- id: critique
|
|
165
165
|
path: .agents/skills/critique/SKILL.md
|
|
166
|
-
used_by: [
|
|
166
|
+
used_by: [moka-thermo-nuclear-reviewer]
|
|
167
167
|
- id: verify
|
|
168
168
|
path: .agents/skills/verify/SKILL.md
|
|
169
|
-
used_by: [
|
|
169
|
+
used_by: [moka-verifier]
|
|
170
170
|
prompts:
|
|
171
171
|
- id: orchestrator
|
|
172
172
|
source: package-default-profile
|
|
173
173
|
used_by: [orchestrator]
|
|
174
174
|
- id: researcher
|
|
175
175
|
source: package-default-profile
|
|
176
|
-
used_by: [
|
|
176
|
+
used_by: [moka-researcher]
|
|
177
177
|
- id: inspector
|
|
178
178
|
source: package-default-profile
|
|
179
|
-
used_by: [
|
|
179
|
+
used_by: [moka-inspector]
|
|
180
180
|
- id: schedule-planner
|
|
181
181
|
source: package-default-profile
|
|
182
|
-
used_by: [
|
|
182
|
+
used_by: [moka-schedule-planner]
|
|
183
183
|
- id: test-writer
|
|
184
184
|
source: package-default-profile
|
|
185
|
-
used_by: [
|
|
185
|
+
used_by: [moka-test-writer]
|
|
186
186
|
- id: code-writer
|
|
187
187
|
source: package-default-profile
|
|
188
|
-
used_by: [
|
|
188
|
+
used_by: [moka-code-writer]
|
|
189
189
|
- id: acceptance-reviewer
|
|
190
190
|
source: package-default-profile
|
|
191
|
-
used_by: [
|
|
191
|
+
used_by: [moka-acceptance-reviewer]
|
|
192
192
|
- id: verifier
|
|
193
193
|
source: package-default-profile
|
|
194
|
-
used_by: [
|
|
194
|
+
used_by: [moka-verifier]
|
|
195
195
|
host_capabilities:
|
|
196
196
|
agents: true
|
|
197
197
|
subagents: true
|
package/dist/config.d.ts
CHANGED
|
@@ -362,8 +362,8 @@ declare const configSchema: z.ZodObject<{
|
|
|
362
362
|
policy: z.ZodOptional<z.ZodObject<{
|
|
363
363
|
commands: z.ZodOptional<z.ZodEnum<{
|
|
364
364
|
allow: "allow";
|
|
365
|
-
deny: "deny";
|
|
366
365
|
"trusted-only": "trusted-only";
|
|
366
|
+
deny: "deny";
|
|
367
367
|
}>>;
|
|
368
368
|
modules: z.ZodOptional<z.ZodEnum<{
|
|
369
369
|
allow: "allow";
|
|
@@ -387,8 +387,8 @@ declare const configSchema: z.ZodObject<{
|
|
|
387
387
|
}, z.core.$strict>>>;
|
|
388
388
|
default_profile: z.ZodOptional<z.ZodString>;
|
|
389
389
|
mode: z.ZodEnum<{
|
|
390
|
-
local: "local";
|
|
391
390
|
hosted: "hosted";
|
|
391
|
+
local: "local";
|
|
392
392
|
}>;
|
|
393
393
|
provider: z.ZodLiteral<"toolhive">;
|
|
394
394
|
authorization_env: z.ZodDefault<z.ZodString>;
|
|
@@ -431,10 +431,10 @@ declare const configSchema: z.ZodObject<{
|
|
|
431
431
|
}, z.core.$strict>>;
|
|
432
432
|
output: z.ZodOptional<z.ZodObject<{
|
|
433
433
|
format: z.ZodEnum<{
|
|
434
|
-
json_schema: "json_schema";
|
|
435
434
|
text: "text";
|
|
436
435
|
json: "json";
|
|
437
436
|
jsonl: "jsonl";
|
|
437
|
+
json_schema: "json_schema";
|
|
438
438
|
}>;
|
|
439
439
|
repair: z.ZodOptional<z.ZodObject<{
|
|
440
440
|
enabled: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -503,10 +503,10 @@ declare const configSchema: z.ZodObject<{
|
|
|
503
503
|
disabled: "disabled";
|
|
504
504
|
}>>>;
|
|
505
505
|
output_formats: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
506
|
-
json_schema: "json_schema";
|
|
507
506
|
text: "text";
|
|
508
507
|
json: "json";
|
|
509
508
|
jsonl: "jsonl";
|
|
509
|
+
json_schema: "json_schema";
|
|
510
510
|
}>>>;
|
|
511
511
|
rules: z.ZodOptional<z.ZodBoolean>;
|
|
512
512
|
skills: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -525,8 +525,8 @@ declare const configSchema: z.ZodObject<{
|
|
|
525
525
|
host_models: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
526
526
|
model: z.ZodOptional<z.ZodString>;
|
|
527
527
|
type: z.ZodEnum<{
|
|
528
|
-
opencode: "opencode";
|
|
529
528
|
command: "command";
|
|
529
|
+
opencode: "opencode";
|
|
530
530
|
}>;
|
|
531
531
|
}, z.core.$strict>>>;
|
|
532
532
|
scheduler: z.ZodDefault<z.ZodObject<{
|
package/dist/config.js
CHANGED
|
@@ -70,7 +70,7 @@ const PACKAGE_DEFAULT_RUNNERS_YAML = `version: 1
|
|
|
70
70
|
runners:
|
|
71
71
|
opencode:
|
|
72
72
|
type: opencode
|
|
73
|
-
model:
|
|
73
|
+
model: gpt-5.5
|
|
74
74
|
capabilities:
|
|
75
75
|
native_subagents: true
|
|
76
76
|
rules: true
|
|
@@ -124,6 +124,15 @@ mcp_gateway:
|
|
|
124
124
|
workspace_path_source: PIPELINE_TARGET_PATH
|
|
125
125
|
tool_prefixes: [backlog]
|
|
126
126
|
skills:
|
|
127
|
+
execute:
|
|
128
|
+
path: .agents/skills/execute/SKILL.md
|
|
129
|
+
source_root: package
|
|
130
|
+
inspect:
|
|
131
|
+
path: .agents/skills/inspect/SKILL.md
|
|
132
|
+
source_root: package
|
|
133
|
+
quick:
|
|
134
|
+
path: .agents/skills/quick/SKILL.md
|
|
135
|
+
source_root: package
|
|
127
136
|
critique:
|
|
128
137
|
path: .agents/skills/critique/SKILL.md
|
|
129
138
|
source_root: package
|
|
@@ -167,7 +176,16 @@ skills:
|
|
|
167
176
|
path: .agents/skills/verify/SKILL.md
|
|
168
177
|
source_root: package
|
|
169
178
|
profiles:
|
|
170
|
-
|
|
179
|
+
moka-orchestrator:
|
|
180
|
+
runner: opencode
|
|
181
|
+
description: Orchestrate the configured pipeline and enforce gates.
|
|
182
|
+
instructions: { inline: "Orchestrate the configured pipeline through package-defined entrypoints, native agents, and gates. Do not bypass configured runner subprocesses or package-configured gates." }
|
|
183
|
+
skills: [execute, quick, inspect]
|
|
184
|
+
mcp_servers: [pipeline-gateway]
|
|
185
|
+
tools: [read, list, grep, glob, bash]
|
|
186
|
+
filesystem: { mode: read-only, allow: ["**/*"], deny: ["node_modules/**", "dist/**", ".git/**"] }
|
|
187
|
+
network: { mode: inherit }
|
|
188
|
+
moka-researcher:
|
|
171
189
|
runner: opencode
|
|
172
190
|
description: Research the requested task and produce structured findings.
|
|
173
191
|
instructions: { inline: "Inspect first-party source, tests, docs, and task context for the current task only. Produce concise findings with file references and stop; do not perform open-ended repository exploration." }
|
|
@@ -181,7 +199,7 @@ profiles:
|
|
|
181
199
|
format: json_schema
|
|
182
200
|
schema_path: .pipeline/schemas/research.schema.json
|
|
183
201
|
repair: { enabled: true, max_attempts: 1 }
|
|
184
|
-
|
|
202
|
+
moka-inspector:
|
|
185
203
|
runner: opencode
|
|
186
204
|
description: Inspect the repository without modifying files.
|
|
187
205
|
instructions: { inline: "Inspect the repository without modifying files." }
|
|
@@ -190,7 +208,7 @@ profiles:
|
|
|
190
208
|
tools: [read, list, grep, glob, bash]
|
|
191
209
|
filesystem: { mode: read-only, allow: ["**/*"], deny: ["node_modules/**", "dist/**", ".git/**"] }
|
|
192
210
|
network: { mode: inherit }
|
|
193
|
-
|
|
211
|
+
moka-schedule-planner:
|
|
194
212
|
runner: opencode
|
|
195
213
|
description: Refine a baseline schedule into a specialized approved-plan artifact.
|
|
196
214
|
instructions: { inline: "Generate exactly one workflow named root as an explicit schedule graph. Return YAML only." }
|
|
@@ -200,7 +218,7 @@ profiles:
|
|
|
200
218
|
tools: [read, list, grep, glob, bash]
|
|
201
219
|
filesystem: { mode: read-only, allow: ["**/*"], deny: ["node_modules/**", "dist/**", ".git/**"] }
|
|
202
220
|
network: { mode: inherit }
|
|
203
|
-
|
|
221
|
+
moka-test-writer:
|
|
204
222
|
runner: opencode
|
|
205
223
|
scheduling_roles: [implementation]
|
|
206
224
|
description: Add focused failing tests for the requested behavior.
|
|
@@ -214,7 +232,7 @@ profiles:
|
|
|
214
232
|
format: json_schema
|
|
215
233
|
schema_path: .pipeline/schemas/implementation.schema.json
|
|
216
234
|
repair: { enabled: true, max_attempts: 1 }
|
|
217
|
-
|
|
235
|
+
moka-code-writer:
|
|
218
236
|
runner: opencode
|
|
219
237
|
scheduling_roles: [implementation]
|
|
220
238
|
description: Implement production code until the failing tests pass.
|
|
@@ -228,7 +246,7 @@ profiles:
|
|
|
228
246
|
format: json_schema
|
|
229
247
|
schema_path: .pipeline/schemas/implementation.schema.json
|
|
230
248
|
repair: { enabled: true, max_attempts: 1 }
|
|
231
|
-
|
|
249
|
+
moka-acceptance-reviewer:
|
|
232
250
|
runner: opencode
|
|
233
251
|
scheduling_roles: [coverage]
|
|
234
252
|
description: Audit the finished change against every acceptance criterion.
|
|
@@ -242,7 +260,7 @@ profiles:
|
|
|
242
260
|
format: json_schema
|
|
243
261
|
schema_path: .pipeline/schemas/acceptance.schema.json
|
|
244
262
|
repair: { enabled: true, max_attempts: 1 }
|
|
245
|
-
|
|
263
|
+
moka-thermo-nuclear-reviewer:
|
|
246
264
|
runner: opencode
|
|
247
265
|
scheduling_roles: [coverage]
|
|
248
266
|
description: Perform the final thermo-nuclear code quality review of the integration branch.
|
|
@@ -256,7 +274,7 @@ profiles:
|
|
|
256
274
|
format: json_schema
|
|
257
275
|
schema_path: .pipeline/schemas/review.schema.json
|
|
258
276
|
repair: { enabled: true, max_attempts: 1 }
|
|
259
|
-
|
|
277
|
+
moka-verifier:
|
|
260
278
|
runner: opencode
|
|
261
279
|
scheduling_roles: [coverage]
|
|
262
280
|
description: Verify checks, implementation fit, and final evidence.
|
|
@@ -270,7 +288,7 @@ profiles:
|
|
|
270
288
|
format: json_schema
|
|
271
289
|
schema_path: .pipeline/schemas/verify.schema.json
|
|
272
290
|
repair: { enabled: true, max_attempts: 1 }
|
|
273
|
-
|
|
291
|
+
moka-learner:
|
|
274
292
|
runner: opencode
|
|
275
293
|
description: Store durable lessons from the completed run.
|
|
276
294
|
instructions: { inline: "Store durable lessons from the completed run when useful." }
|
|
@@ -286,6 +304,8 @@ profiles:
|
|
|
286
304
|
`;
|
|
287
305
|
const PACKAGE_DEFAULT_PIPELINE_YAML = `version: 1
|
|
288
306
|
default_workflow: inspect
|
|
307
|
+
orchestrator:
|
|
308
|
+
profile: moka-orchestrator
|
|
289
309
|
entrypoints:
|
|
290
310
|
quick:
|
|
291
311
|
schedule: quick-schedule
|
|
@@ -323,63 +343,63 @@ scheduler:
|
|
|
323
343
|
nodes:
|
|
324
344
|
backlog-intake:
|
|
325
345
|
category: intake
|
|
326
|
-
profile:
|
|
327
|
-
models: [zai-coding-plan/glm-5-turbo,
|
|
346
|
+
profile: moka-researcher
|
|
347
|
+
models: [zai-coding-plan/glm-5-turbo, gpt-5.5-fast]
|
|
328
348
|
red-tests:
|
|
329
349
|
category: red
|
|
330
|
-
profile:
|
|
331
|
-
models: [
|
|
350
|
+
profile: moka-test-writer
|
|
351
|
+
models: [gpt-5.5, zai-coding-plan/glm-5.1, kimi-for-coding/kimi-k2-thinking]
|
|
332
352
|
green-implementation:
|
|
333
353
|
category: green
|
|
334
|
-
profile:
|
|
354
|
+
profile: moka-code-writer
|
|
335
355
|
models: [opencode-go/qwen3.7-max, kimi-for-coding/k2p6, opencode-go/deepseek-v4-pro]
|
|
336
356
|
verification:
|
|
337
357
|
category: verification
|
|
338
|
-
profile:
|
|
339
|
-
models: [
|
|
358
|
+
profile: moka-verifier
|
|
359
|
+
models: [gpt-5.5, zai-coding-plan/glm-5.1]
|
|
340
360
|
execute:
|
|
341
361
|
required_categories: [intake, research, red, green, mechanical, acceptance, verification, learn]
|
|
342
362
|
nodes:
|
|
343
363
|
backlog-intake:
|
|
344
364
|
category: intake
|
|
345
|
-
profile:
|
|
346
|
-
models: [zai-coding-plan/glm-5-turbo,
|
|
365
|
+
profile: moka-researcher
|
|
366
|
+
models: [zai-coding-plan/glm-5-turbo, gpt-5.5-fast]
|
|
347
367
|
research:
|
|
348
368
|
category: research
|
|
349
|
-
profile:
|
|
350
|
-
models: [
|
|
369
|
+
profile: moka-researcher
|
|
370
|
+
models: [gpt-5.5-fast, zai-coding-plan/glm-5.1, kimi-for-coding/k2p6]
|
|
351
371
|
red-tests:
|
|
352
372
|
category: red
|
|
353
|
-
profile:
|
|
354
|
-
models: [
|
|
373
|
+
profile: moka-test-writer
|
|
374
|
+
models: [gpt-5.5, zai-coding-plan/glm-5.1, kimi-for-coding/kimi-k2-thinking]
|
|
355
375
|
green-backend:
|
|
356
376
|
category: green
|
|
357
|
-
profile:
|
|
377
|
+
profile: moka-code-writer
|
|
358
378
|
models: [opencode-go/qwen3.7-max, kimi-for-coding/k2p6, opencode-go/deepseek-v4-pro]
|
|
359
379
|
green-frontend:
|
|
360
380
|
category: green
|
|
361
|
-
profile:
|
|
381
|
+
profile: moka-code-writer
|
|
362
382
|
models: [opencode-go/qwen3.7-max, kimi-for-coding/k2p6, opencode-go/deepseek-v4-pro]
|
|
363
383
|
acceptance-review:
|
|
364
384
|
category: acceptance
|
|
365
|
-
profile:
|
|
366
|
-
models: [
|
|
385
|
+
profile: moka-acceptance-reviewer
|
|
386
|
+
models: [gpt-5.5, zai-coding-plan/glm-5.1]
|
|
367
387
|
verification:
|
|
368
388
|
category: verification
|
|
369
|
-
profile:
|
|
370
|
-
models: [
|
|
389
|
+
profile: moka-verifier
|
|
390
|
+
models: [gpt-5.5, zai-coding-plan/glm-5.1]
|
|
371
391
|
learn:
|
|
372
392
|
category: learn
|
|
373
|
-
profile:
|
|
374
|
-
models: [zai-coding-plan/glm-5-turbo,
|
|
393
|
+
profile: moka-learner
|
|
394
|
+
models: [zai-coding-plan/glm-5-turbo, gpt-5.5-fast]
|
|
375
395
|
schedules:
|
|
376
396
|
quick-schedule:
|
|
377
397
|
baseline: quick
|
|
378
|
-
planner_profile:
|
|
398
|
+
planner_profile: moka-schedule-planner
|
|
379
399
|
node_catalog: quick
|
|
380
400
|
execute-schedule:
|
|
381
401
|
baseline: execute
|
|
382
|
-
planner_profile:
|
|
402
|
+
planner_profile: moka-schedule-planner
|
|
383
403
|
node_catalog: execute
|
|
384
404
|
workflows:
|
|
385
405
|
inspect:
|
|
@@ -387,7 +407,7 @@ workflows:
|
|
|
387
407
|
nodes:
|
|
388
408
|
- id: inspect
|
|
389
409
|
kind: agent
|
|
390
|
-
profile:
|
|
410
|
+
profile: moka-inspector
|
|
391
411
|
`;
|
|
392
412
|
const DEFAULT_OPENCODE_ECOSYSTEM_MANIFEST_URL = new URL(`../${OPENCODE_ECOSYSTEM_MANIFEST_PATH}`, import.meta.url);
|
|
393
413
|
const PACKAGE_ASSET_ROOT = new URL("..", import.meta.url);
|
package/dist/hooks.d.ts
CHANGED
|
@@ -13,8 +13,8 @@ declare const hookResultSchema: z.ZodObject<{
|
|
|
13
13
|
taskContext: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
14
14
|
}, z.core.$strict>>;
|
|
15
15
|
status: z.ZodEnum<{
|
|
16
|
-
fail: "fail";
|
|
17
16
|
pass: "pass";
|
|
17
|
+
fail: "fail";
|
|
18
18
|
skip: "skip";
|
|
19
19
|
}>;
|
|
20
20
|
summary: z.ZodOptional<z.ZodString>;
|
package/dist/install-commands.js
CHANGED
|
@@ -21,6 +21,8 @@ const SINGLE_OPENCODE_PLUGIN_ARRAY_RE = /\n {2}"plugin": \[\n {4}("[^"]+")\n {2}
|
|
|
21
21
|
const OPENCODE_PROJECT_CONFIG_PATH = ".opencode/opencode.json";
|
|
22
22
|
const ENTRYPOINT_PATH_PATTERNS = { opencode: [/^\.opencode\/commands\/([^/]+)\.md$/] };
|
|
23
23
|
const COMMAND_HOSTS = ["opencode"];
|
|
24
|
+
const OPENCODE_ORCHESTRATOR_AGENT_ID = "MoKa Orchestrator";
|
|
25
|
+
const MOKA_PROFILE_PREFIX = "moka-";
|
|
24
26
|
function header(host) {
|
|
25
27
|
return [
|
|
26
28
|
GENERATED_MARKER,
|
|
@@ -32,9 +34,7 @@ function markdown(data, body) {
|
|
|
32
34
|
return `${matter.stringify(body.trimEnd(), data).trimEnd()}\n`;
|
|
33
35
|
}
|
|
34
36
|
function profileEntries(config) {
|
|
35
|
-
|
|
36
|
-
for (const workflow of Object.values(config.workflows)) for (const node of workflow.nodes) if (node.kind === "agent" && node.profile) profileIds.add(node.profile);
|
|
37
|
-
return [...profileIds].sort((a, b) => a.localeCompare(b)).map((id) => [id, config.profiles[id]]);
|
|
37
|
+
return Object.entries(config.profiles).sort(([a], [b]) => a.localeCompare(b));
|
|
38
38
|
}
|
|
39
39
|
function entrypointEntries(config) {
|
|
40
40
|
const entries = Object.entries(config.entrypoints);
|
|
@@ -50,7 +50,7 @@ function entrypointCommandDefinitions(_host, config, makeDefinition) {
|
|
|
50
50
|
return entrypointEntries(config).map(([id, entrypoint]) => makeDefinition(id, entrypoint));
|
|
51
51
|
}
|
|
52
52
|
function nativeProfileEntries(host, config) {
|
|
53
|
-
return profileEntries(config).filter(([
|
|
53
|
+
return profileEntries(config).filter(([id, profile]) => id !== config.orchestrator?.profile && canRunNatively(host, profile));
|
|
54
54
|
}
|
|
55
55
|
function orchestratorProfile(config) {
|
|
56
56
|
if (!config.orchestrator) return;
|
|
@@ -94,7 +94,7 @@ function dispatchRouteForAgent(host, config, route) {
|
|
|
94
94
|
...route,
|
|
95
95
|
kind: "native-named-agent",
|
|
96
96
|
...model ? { model } : {},
|
|
97
|
-
nativeAgentId: route.profileId,
|
|
97
|
+
nativeAgentId: nativeAgentIdForHost(host, route.profileId),
|
|
98
98
|
runnerId
|
|
99
99
|
};
|
|
100
100
|
}
|
|
@@ -104,7 +104,7 @@ function dispatchRouteForAgent(host, config, route) {
|
|
|
104
104
|
...route,
|
|
105
105
|
kind: "native-model-agent",
|
|
106
106
|
...model ? { model } : {},
|
|
107
|
-
nativeAgentId: route.profileId,
|
|
107
|
+
nativeAgentId: nativeAgentIdForHost(host, route.profileId),
|
|
108
108
|
runnerId
|
|
109
109
|
};
|
|
110
110
|
}
|
|
@@ -114,6 +114,17 @@ function dispatchRouteForAgent(host, config, route) {
|
|
|
114
114
|
runnerId
|
|
115
115
|
};
|
|
116
116
|
}
|
|
117
|
+
function nativeAgentIdForHost(host, profileId) {
|
|
118
|
+
return host === "opencode" ? opencodeAgentName(profileId) : profileId;
|
|
119
|
+
}
|
|
120
|
+
function opencodeAgentName(profileId) {
|
|
121
|
+
if (!profileId.startsWith(MOKA_PROFILE_PREFIX)) return profileId;
|
|
122
|
+
return `MoKa ${profileId.slice(5).split("-").map(opencodeAgentNamePart).join(" ")}`;
|
|
123
|
+
}
|
|
124
|
+
function opencodeAgentNamePart(part) {
|
|
125
|
+
if (part === "opencode") return "OpenCode";
|
|
126
|
+
return `${part.charAt(0).toUpperCase()}${part.slice(1)}`;
|
|
127
|
+
}
|
|
117
128
|
function grants(actor) {
|
|
118
129
|
return [
|
|
119
130
|
`model: ${actor.model ?? "default"}`,
|
|
@@ -201,7 +212,7 @@ function cliDispatchLine(route) {
|
|
|
201
212
|
return `- ${route.nodeId}: ${route.runnerId} CLI profile=${route.profileId} command=\`${runnerCliCommand(route)}\` needs=${needsSummary(route.needs)}`;
|
|
202
213
|
}
|
|
203
214
|
function runnerCliCommand(route) {
|
|
204
|
-
if (route.runnerId === "opencode") return `opencode run --agent ${route.profileId} --format json --dir <repo-root> <node prompt>`;
|
|
215
|
+
if (route.runnerId === "opencode") return `opencode run --agent "${opencodeAgentName(route.profileId)}" --format json --dir <repo-root> <node prompt>`;
|
|
205
216
|
throw new Error(`runner '${route.runnerId}' cannot be represented as a supported native or CLI route`);
|
|
206
217
|
}
|
|
207
218
|
function nodePromptContract(workflowId, routes) {
|
|
@@ -352,7 +363,7 @@ function opencodeDefinitions(config, cwd) {
|
|
|
352
363
|
return [
|
|
353
364
|
...entrypointCommandDefinitions("opencode", config, (id, entrypoint) => ({
|
|
354
365
|
content: markdown({
|
|
355
|
-
...orchestrator ? { agent:
|
|
366
|
+
...orchestrator ? { agent: OPENCODE_ORCHESTRATOR_AGENT_ID } : {},
|
|
356
367
|
description: entrypointDescription(id, entrypoint)
|
|
357
368
|
}, compactLines([
|
|
358
369
|
header("opencode").trimEnd(),
|
|
@@ -379,6 +390,7 @@ function opencodeDefinitions(config, cwd) {
|
|
|
379
390
|
content: markdown({
|
|
380
391
|
description: "Orchestrate the configured pipeline and enforce gates.",
|
|
381
392
|
mode: "primary",
|
|
393
|
+
name: OPENCODE_ORCHESTRATOR_AGENT_ID,
|
|
382
394
|
permission: opencodePermission(orchestrator, { allowedTaskAgents: agentDispatchRoutes("opencode", config).filter((route) => route.kind !== "cli").map((route) => route.nativeAgentId).filter((id) => Boolean(id)) })
|
|
383
395
|
}, compactLines([
|
|
384
396
|
header("opencode").trimEnd(),
|
|
@@ -389,10 +401,11 @@ function opencodeDefinitions(config, cwd) {
|
|
|
389
401
|
]).join("\n")),
|
|
390
402
|
host: "opencode",
|
|
391
403
|
invocation: invocationForHost("opencode"),
|
|
392
|
-
path:
|
|
404
|
+
path: `.opencode/agents/${OPENCODE_ORCHESTRATOR_AGENT_ID}.md`
|
|
393
405
|
}] : [],
|
|
394
406
|
...nativeProfileEntries("opencode", config).map(([id, profile]) => ({
|
|
395
407
|
content: markdown({
|
|
408
|
+
name: nativeAgentIdForHost("opencode", id),
|
|
396
409
|
description: profile.description ?? id,
|
|
397
410
|
hidden: false,
|
|
398
411
|
mode: "subagent",
|
|
@@ -410,7 +423,7 @@ function opencodeDefinitions(config, cwd) {
|
|
|
410
423
|
].join("\n")),
|
|
411
424
|
host: "opencode",
|
|
412
425
|
invocation: invocationForHost("opencode"),
|
|
413
|
-
path: `.opencode/agents/${id}.md`
|
|
426
|
+
path: `.opencode/agents/${nativeAgentIdForHost("opencode", id)}.md`
|
|
414
427
|
})),
|
|
415
428
|
...opencodeSkillProjections(config, cwd).map(opencodeSkillDefinition),
|
|
416
429
|
...localPluginDefinitions(),
|
package/dist/moka-submit.d.ts
CHANGED
|
@@ -3,6 +3,59 @@ import { generateScheduleArtifact } from "./schedule-planner.js";
|
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
|
|
5
5
|
//#region src/moka-submit.d.ts
|
|
6
|
+
declare const mokaSubmitDirectHooksSchema: z.ZodRecord<z.ZodEnum<{
|
|
7
|
+
"workflow.start": "workflow.start";
|
|
8
|
+
"workflow.success": "workflow.success";
|
|
9
|
+
"workflow.failure": "workflow.failure";
|
|
10
|
+
"workflow.complete": "workflow.complete";
|
|
11
|
+
"node.start": "node.start";
|
|
12
|
+
"node.success": "node.success";
|
|
13
|
+
"node.error": "node.error";
|
|
14
|
+
"node.finish": "node.finish";
|
|
15
|
+
"gate.failure": "gate.failure";
|
|
16
|
+
}> & z.core.$partial, z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
17
|
+
failure: z.ZodDefault<z.ZodEnum<{
|
|
18
|
+
fail: "fail";
|
|
19
|
+
ignore: "ignore";
|
|
20
|
+
}>>;
|
|
21
|
+
input: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
22
|
+
publishResult: z.ZodOptional<z.ZodBoolean>;
|
|
23
|
+
saveResultAs: z.ZodOptional<z.ZodString>;
|
|
24
|
+
timeoutMs: z.ZodOptional<z.ZodNumber>;
|
|
25
|
+
where: z.ZodOptional<z.ZodObject<{
|
|
26
|
+
gate: z.ZodOptional<z.ZodString>;
|
|
27
|
+
node: z.ZodOptional<z.ZodString>;
|
|
28
|
+
workflow: z.ZodOptional<z.ZodString>;
|
|
29
|
+
}, z.core.$strict>>;
|
|
30
|
+
command: z.ZodArray<z.ZodString>;
|
|
31
|
+
kind: z.ZodLiteral<"command">;
|
|
32
|
+
outputLimitBytes: z.ZodOptional<z.ZodNumber>;
|
|
33
|
+
trusted: z.ZodOptional<z.ZodBoolean>;
|
|
34
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
35
|
+
failure: z.ZodDefault<z.ZodEnum<{
|
|
36
|
+
fail: "fail";
|
|
37
|
+
ignore: "ignore";
|
|
38
|
+
}>>;
|
|
39
|
+
input: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
40
|
+
publishResult: z.ZodOptional<z.ZodBoolean>;
|
|
41
|
+
saveResultAs: z.ZodOptional<z.ZodString>;
|
|
42
|
+
timeoutMs: z.ZodOptional<z.ZodNumber>;
|
|
43
|
+
where: z.ZodOptional<z.ZodObject<{
|
|
44
|
+
gate: z.ZodOptional<z.ZodString>;
|
|
45
|
+
node: z.ZodOptional<z.ZodString>;
|
|
46
|
+
workflow: z.ZodOptional<z.ZodString>;
|
|
47
|
+
}, z.core.$strict>>;
|
|
48
|
+
kind: z.ZodLiteral<"module">;
|
|
49
|
+
module: z.ZodString;
|
|
50
|
+
}, z.core.$strict>], "kind">>;
|
|
51
|
+
declare const mokaSubmitHookPolicySchema: z.ZodObject<{
|
|
52
|
+
allowCommandHooks: z.ZodOptional<z.ZodBoolean>;
|
|
53
|
+
allowUntrustedCommandHooks: z.ZodOptional<z.ZodBoolean>;
|
|
54
|
+
env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
55
|
+
envPassthrough: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
56
|
+
outputLimitBytes: z.ZodOptional<z.ZodNumber>;
|
|
57
|
+
timeoutMs: z.ZodOptional<z.ZodNumber>;
|
|
58
|
+
}, z.core.$strict>;
|
|
6
59
|
declare const mokaSubmitResultSchema: z.ZodObject<{
|
|
7
60
|
namespace: z.ZodString;
|
|
8
61
|
payloadConfigMapName: z.ZodString;
|
|
@@ -15,6 +68,11 @@ declare const mokaSubmitOptionsSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
15
68
|
delivery: z.ZodDefault<z.ZodObject<{
|
|
16
69
|
pullRequest: z.ZodDefault<z.ZodBoolean>;
|
|
17
70
|
}, z.core.$strict>>;
|
|
71
|
+
eventSink: z.ZodOptional<z.ZodObject<{
|
|
72
|
+
authHeader: z.ZodDefault<z.ZodString>;
|
|
73
|
+
authTokenFile: z.ZodOptional<z.ZodString>;
|
|
74
|
+
url: z.ZodString;
|
|
75
|
+
}, z.core.$strict>>;
|
|
18
76
|
eventAuthSecretKey: z.ZodDefault<z.ZodString>;
|
|
19
77
|
eventAuthSecretName: z.ZodDefault<z.ZodString>;
|
|
20
78
|
eventUrl: z.ZodDefault<z.ZodString>;
|
|
@@ -25,6 +83,59 @@ declare const mokaSubmitOptionsSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
25
83
|
}, z.core.$strict>>;
|
|
26
84
|
generateName: z.ZodOptional<z.ZodString>;
|
|
27
85
|
githubAuthSecretName: z.ZodDefault<z.ZodString>;
|
|
86
|
+
hookPolicy: z.ZodOptional<z.ZodObject<{
|
|
87
|
+
allowCommandHooks: z.ZodOptional<z.ZodBoolean>;
|
|
88
|
+
allowUntrustedCommandHooks: z.ZodOptional<z.ZodBoolean>;
|
|
89
|
+
env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
90
|
+
envPassthrough: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
91
|
+
outputLimitBytes: z.ZodOptional<z.ZodNumber>;
|
|
92
|
+
timeoutMs: z.ZodOptional<z.ZodNumber>;
|
|
93
|
+
}, z.core.$strict>>;
|
|
94
|
+
hooks: z.ZodOptional<z.ZodRecord<z.ZodEnum<{
|
|
95
|
+
"workflow.start": "workflow.start";
|
|
96
|
+
"workflow.success": "workflow.success";
|
|
97
|
+
"workflow.failure": "workflow.failure";
|
|
98
|
+
"workflow.complete": "workflow.complete";
|
|
99
|
+
"node.start": "node.start";
|
|
100
|
+
"node.success": "node.success";
|
|
101
|
+
"node.error": "node.error";
|
|
102
|
+
"node.finish": "node.finish";
|
|
103
|
+
"gate.failure": "gate.failure";
|
|
104
|
+
}> & z.core.$partial, z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
105
|
+
failure: z.ZodDefault<z.ZodEnum<{
|
|
106
|
+
fail: "fail";
|
|
107
|
+
ignore: "ignore";
|
|
108
|
+
}>>;
|
|
109
|
+
input: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
110
|
+
publishResult: z.ZodOptional<z.ZodBoolean>;
|
|
111
|
+
saveResultAs: z.ZodOptional<z.ZodString>;
|
|
112
|
+
timeoutMs: z.ZodOptional<z.ZodNumber>;
|
|
113
|
+
where: z.ZodOptional<z.ZodObject<{
|
|
114
|
+
gate: z.ZodOptional<z.ZodString>;
|
|
115
|
+
node: z.ZodOptional<z.ZodString>;
|
|
116
|
+
workflow: z.ZodOptional<z.ZodString>;
|
|
117
|
+
}, z.core.$strict>>;
|
|
118
|
+
command: z.ZodArray<z.ZodString>;
|
|
119
|
+
kind: z.ZodLiteral<"command">;
|
|
120
|
+
outputLimitBytes: z.ZodOptional<z.ZodNumber>;
|
|
121
|
+
trusted: z.ZodOptional<z.ZodBoolean>;
|
|
122
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
123
|
+
failure: z.ZodDefault<z.ZodEnum<{
|
|
124
|
+
fail: "fail";
|
|
125
|
+
ignore: "ignore";
|
|
126
|
+
}>>;
|
|
127
|
+
input: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
128
|
+
publishResult: z.ZodOptional<z.ZodBoolean>;
|
|
129
|
+
saveResultAs: z.ZodOptional<z.ZodString>;
|
|
130
|
+
timeoutMs: z.ZodOptional<z.ZodNumber>;
|
|
131
|
+
where: z.ZodOptional<z.ZodObject<{
|
|
132
|
+
gate: z.ZodOptional<z.ZodString>;
|
|
133
|
+
node: z.ZodOptional<z.ZodString>;
|
|
134
|
+
workflow: z.ZodOptional<z.ZodString>;
|
|
135
|
+
}, z.core.$strict>>;
|
|
136
|
+
kind: z.ZodLiteral<"module">;
|
|
137
|
+
module: z.ZodString;
|
|
138
|
+
}, z.core.$strict>], "kind">>>;
|
|
28
139
|
image: z.ZodOptional<z.ZodString>;
|
|
29
140
|
imagePullPolicy: z.ZodDefault<z.ZodEnum<{
|
|
30
141
|
Always: "Always";
|
|
@@ -69,6 +180,11 @@ declare const mokaSubmitOptionsSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
69
180
|
delivery: z.ZodDefault<z.ZodObject<{
|
|
70
181
|
pullRequest: z.ZodDefault<z.ZodBoolean>;
|
|
71
182
|
}, z.core.$strict>>;
|
|
183
|
+
eventSink: z.ZodOptional<z.ZodObject<{
|
|
184
|
+
authHeader: z.ZodDefault<z.ZodString>;
|
|
185
|
+
authTokenFile: z.ZodOptional<z.ZodString>;
|
|
186
|
+
url: z.ZodString;
|
|
187
|
+
}, z.core.$strict>>;
|
|
72
188
|
eventAuthSecretKey: z.ZodDefault<z.ZodString>;
|
|
73
189
|
eventAuthSecretName: z.ZodDefault<z.ZodString>;
|
|
74
190
|
eventUrl: z.ZodDefault<z.ZodString>;
|
|
@@ -79,6 +195,59 @@ declare const mokaSubmitOptionsSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
79
195
|
}, z.core.$strict>>;
|
|
80
196
|
generateName: z.ZodOptional<z.ZodString>;
|
|
81
197
|
githubAuthSecretName: z.ZodDefault<z.ZodString>;
|
|
198
|
+
hookPolicy: z.ZodOptional<z.ZodObject<{
|
|
199
|
+
allowCommandHooks: z.ZodOptional<z.ZodBoolean>;
|
|
200
|
+
allowUntrustedCommandHooks: z.ZodOptional<z.ZodBoolean>;
|
|
201
|
+
env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
202
|
+
envPassthrough: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
203
|
+
outputLimitBytes: z.ZodOptional<z.ZodNumber>;
|
|
204
|
+
timeoutMs: z.ZodOptional<z.ZodNumber>;
|
|
205
|
+
}, z.core.$strict>>;
|
|
206
|
+
hooks: z.ZodOptional<z.ZodRecord<z.ZodEnum<{
|
|
207
|
+
"workflow.start": "workflow.start";
|
|
208
|
+
"workflow.success": "workflow.success";
|
|
209
|
+
"workflow.failure": "workflow.failure";
|
|
210
|
+
"workflow.complete": "workflow.complete";
|
|
211
|
+
"node.start": "node.start";
|
|
212
|
+
"node.success": "node.success";
|
|
213
|
+
"node.error": "node.error";
|
|
214
|
+
"node.finish": "node.finish";
|
|
215
|
+
"gate.failure": "gate.failure";
|
|
216
|
+
}> & z.core.$partial, z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
217
|
+
failure: z.ZodDefault<z.ZodEnum<{
|
|
218
|
+
fail: "fail";
|
|
219
|
+
ignore: "ignore";
|
|
220
|
+
}>>;
|
|
221
|
+
input: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
222
|
+
publishResult: z.ZodOptional<z.ZodBoolean>;
|
|
223
|
+
saveResultAs: z.ZodOptional<z.ZodString>;
|
|
224
|
+
timeoutMs: z.ZodOptional<z.ZodNumber>;
|
|
225
|
+
where: z.ZodOptional<z.ZodObject<{
|
|
226
|
+
gate: z.ZodOptional<z.ZodString>;
|
|
227
|
+
node: z.ZodOptional<z.ZodString>;
|
|
228
|
+
workflow: z.ZodOptional<z.ZodString>;
|
|
229
|
+
}, z.core.$strict>>;
|
|
230
|
+
command: z.ZodArray<z.ZodString>;
|
|
231
|
+
kind: z.ZodLiteral<"command">;
|
|
232
|
+
outputLimitBytes: z.ZodOptional<z.ZodNumber>;
|
|
233
|
+
trusted: z.ZodOptional<z.ZodBoolean>;
|
|
234
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
235
|
+
failure: z.ZodDefault<z.ZodEnum<{
|
|
236
|
+
fail: "fail";
|
|
237
|
+
ignore: "ignore";
|
|
238
|
+
}>>;
|
|
239
|
+
input: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
240
|
+
publishResult: z.ZodOptional<z.ZodBoolean>;
|
|
241
|
+
saveResultAs: z.ZodOptional<z.ZodString>;
|
|
242
|
+
timeoutMs: z.ZodOptional<z.ZodNumber>;
|
|
243
|
+
where: z.ZodOptional<z.ZodObject<{
|
|
244
|
+
gate: z.ZodOptional<z.ZodString>;
|
|
245
|
+
node: z.ZodOptional<z.ZodString>;
|
|
246
|
+
workflow: z.ZodOptional<z.ZodString>;
|
|
247
|
+
}, z.core.$strict>>;
|
|
248
|
+
kind: z.ZodLiteral<"module">;
|
|
249
|
+
module: z.ZodString;
|
|
250
|
+
}, z.core.$strict>], "kind">>>;
|
|
82
251
|
image: z.ZodOptional<z.ZodString>;
|
|
83
252
|
imagePullPolicy: z.ZodDefault<z.ZodEnum<{
|
|
84
253
|
Always: "Always";
|
|
@@ -117,6 +286,10 @@ declare const mokaSubmitOptionsSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
117
286
|
}, z.core.$strict>], "type">;
|
|
118
287
|
type MokaSubmitOptionsInput = z.input<typeof mokaSubmitOptionsSchema>;
|
|
119
288
|
type MokaSubmitOptionsOutput = z.output<typeof mokaSubmitOptionsSchema>;
|
|
289
|
+
type MokaSubmitDirectHooksInput = z.input<typeof mokaSubmitDirectHooksSchema>;
|
|
290
|
+
type MokaSubmitDirectHooksOutput = z.output<typeof mokaSubmitDirectHooksSchema>;
|
|
291
|
+
type MokaSubmitHookPolicyInput = z.input<typeof mokaSubmitHookPolicySchema>;
|
|
292
|
+
type MokaSubmitHookPolicyOutput = z.output<typeof mokaSubmitHookPolicySchema>;
|
|
120
293
|
type MokaSubmitInput = MokaSubmitOptionsInput & {
|
|
121
294
|
config: PipelineConfig;
|
|
122
295
|
worktreePath?: string;
|
|
@@ -157,4 +330,4 @@ interface MokaWorkflowSubmitOptions {
|
|
|
157
330
|
}
|
|
158
331
|
declare function submitMoka(rawOptions: MokaSubmitInput, dependencies?: SubmitMokaDependencies): Promise<MokaSubmitOutput>;
|
|
159
332
|
//#endregion
|
|
160
|
-
export { MokaSubmitInput, MokaSubmitOptions, MokaSubmitOptionsInput, MokaSubmitOptionsOutput, MokaSubmitOutput, MokaSubmitResult, mokaSubmitOptionsSchema, mokaSubmitResultSchema, submitMoka };
|
|
333
|
+
export { MokaSubmitDirectHooksInput, MokaSubmitDirectHooksOutput, MokaSubmitHookPolicyInput, MokaSubmitHookPolicyOutput, MokaSubmitInput, MokaSubmitOptions, MokaSubmitOptionsInput, MokaSubmitOptionsOutput, MokaSubmitOutput, MokaSubmitResult, mokaSubmitDirectHooksSchema, mokaSubmitHookPolicySchema, mokaSubmitOptionsSchema, mokaSubmitResultSchema, submitMoka };
|
package/dist/moka-submit.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { buildRunnerCommandPayload, runnerDeliverySchema, runnerRepositoryContextSchema, runnerRunIdentitySchema, runnerTaskSchema } from "./runner-command-contract.js";
|
|
1
|
+
import { buildRunnerCommandPayload, runnerDeliverySchema, runnerHookPolicySchema, runnerRepositoryContextSchema, runnerRunIdentitySchema, runnerTaskSchema } from "./runner-command-contract.js";
|
|
2
2
|
import { compileScheduleArtifact, generateScheduleArtifact, parseScheduleArtifact } from "./schedule-planner.js";
|
|
3
3
|
import { workflowSubmitResultSchema } from "./workflow-submit-contract.js";
|
|
4
4
|
import { buildCommandScheduleYaml, submitRunnerArgoWorkflow } from "./argo-submit.js";
|
|
@@ -28,15 +28,55 @@ const mokaSubmitEventsSchema = z.object({
|
|
|
28
28
|
authTokenFile: z.string().min(1).optional(),
|
|
29
29
|
url: z.string().url()
|
|
30
30
|
}).strict();
|
|
31
|
+
const MOKA_SUBMIT_HOOK_EVENTS = [
|
|
32
|
+
"workflow.start",
|
|
33
|
+
"workflow.success",
|
|
34
|
+
"workflow.failure",
|
|
35
|
+
"workflow.complete",
|
|
36
|
+
"node.start",
|
|
37
|
+
"node.success",
|
|
38
|
+
"node.error",
|
|
39
|
+
"node.finish",
|
|
40
|
+
"gate.failure"
|
|
41
|
+
];
|
|
42
|
+
const mokaSubmitHookWhereSchema = z.object({
|
|
43
|
+
gate: z.string().min(1).optional(),
|
|
44
|
+
node: z.string().min(1).optional(),
|
|
45
|
+
workflow: z.string().min(1).optional()
|
|
46
|
+
}).strict();
|
|
47
|
+
const mokaSubmitHookBaseSchema = z.object({
|
|
48
|
+
failure: z.enum(["fail", "ignore"]).default("ignore"),
|
|
49
|
+
input: z.record(z.string(), z.unknown()).optional(),
|
|
50
|
+
publishResult: z.boolean().optional(),
|
|
51
|
+
saveResultAs: z.string().min(1).optional(),
|
|
52
|
+
timeoutMs: z.number().int().positive().optional(),
|
|
53
|
+
where: mokaSubmitHookWhereSchema.optional()
|
|
54
|
+
}).strict();
|
|
55
|
+
const mokaSubmitCommandHookSchema = mokaSubmitHookBaseSchema.extend({
|
|
56
|
+
command: z.array(z.string().min(1)).min(1),
|
|
57
|
+
kind: z.literal("command"),
|
|
58
|
+
outputLimitBytes: z.number().int().positive().optional(),
|
|
59
|
+
trusted: z.boolean().optional()
|
|
60
|
+
}).strict();
|
|
61
|
+
const mokaSubmitModuleHookSchema = mokaSubmitHookBaseSchema.extend({
|
|
62
|
+
kind: z.literal("module"),
|
|
63
|
+
module: z.string().min(1)
|
|
64
|
+
}).strict();
|
|
65
|
+
const mokaSubmitDirectHookSchema = z.discriminatedUnion("kind", [mokaSubmitCommandHookSchema, mokaSubmitModuleHookSchema]);
|
|
66
|
+
const mokaSubmitDirectHooksSchema = z.partialRecord(z.enum(MOKA_SUBMIT_HOOK_EVENTS), mokaSubmitDirectHookSchema);
|
|
67
|
+
const mokaSubmitHookPolicySchema = runnerHookPolicySchema;
|
|
31
68
|
const mokaSubmitResultSchema = workflowSubmitResultSchema;
|
|
32
69
|
const mokaSubmitBaseOptionsSchema = z.object({
|
|
33
70
|
delivery: runnerDeliverySchema.default({ pullRequest: false }),
|
|
71
|
+
eventSink: mokaSubmitEventsSchema.optional(),
|
|
34
72
|
eventAuthSecretKey: z.string().min(1).default(MOMOKAYA_EVENT_AUTH_SECRET_KEY),
|
|
35
73
|
eventAuthSecretName: z.string().min(1).default(MOMOKAYA_EVENT_AUTH_SECRET_NAME),
|
|
36
74
|
eventUrl: z.string().url().default(MOMOKAYA_EVENT_URL),
|
|
37
75
|
events: mokaSubmitEventsSchema.optional(),
|
|
38
76
|
generateName: z.string().min(1).optional(),
|
|
39
77
|
githubAuthSecretName: z.string().min(1).default(MOMOKAYA_GITHUB_AUTH_SECRET_NAME),
|
|
78
|
+
hookPolicy: mokaSubmitHookPolicySchema.optional(),
|
|
79
|
+
hooks: mokaSubmitDirectHooksSchema.optional(),
|
|
40
80
|
image: z.string().min(1).optional(),
|
|
41
81
|
imagePullPolicy: imagePullPolicySchema,
|
|
42
82
|
imagePullSecretName: z.string().min(1).default(MOMOKAYA_IMAGE_PULL_SECRET_NAME),
|
|
@@ -61,12 +101,88 @@ const mokaCommandSubmitOptionsSchema = mokaSubmitBaseOptionsSchema.extend({
|
|
|
61
101
|
task: mokaSubmitTaskInputSchema.optional(),
|
|
62
102
|
type: z.literal("command")
|
|
63
103
|
}).strict();
|
|
64
|
-
const mokaSubmitOptionsSchema = z.discriminatedUnion("type", [mokaGraphSubmitOptionsSchema, mokaCommandSubmitOptionsSchema])
|
|
104
|
+
const mokaSubmitOptionsSchema = z.discriminatedUnion("type", [mokaGraphSubmitOptionsSchema, mokaCommandSubmitOptionsSchema]).superRefine((data, ctx) => {
|
|
105
|
+
if (data.eventSink !== void 0 && data.events !== void 0) ctx.addIssue({
|
|
106
|
+
code: "custom",
|
|
107
|
+
message: "Choose either eventSink or events, not both",
|
|
108
|
+
path: ["eventSink"]
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
const submitHookId = (event) => `moka-submit-${event.replaceAll(".", "-")}`;
|
|
112
|
+
function objectWithoutUndefined(value) {
|
|
113
|
+
return Object.fromEntries(Object.entries(value).filter(([, entry]) => entry !== void 0));
|
|
114
|
+
}
|
|
115
|
+
function hookFunctionForSubmitHook(hook) {
|
|
116
|
+
if (hook.kind === "module") return objectWithoutUndefined({
|
|
117
|
+
kind: "module",
|
|
118
|
+
module: hook.module,
|
|
119
|
+
timeout_ms: hook.timeoutMs
|
|
120
|
+
});
|
|
121
|
+
return objectWithoutUndefined({
|
|
122
|
+
command: hook.command,
|
|
123
|
+
kind: "command",
|
|
124
|
+
output_limit_bytes: hook.outputLimitBytes,
|
|
125
|
+
protocol: {
|
|
126
|
+
input: "file",
|
|
127
|
+
result: "file"
|
|
128
|
+
},
|
|
129
|
+
timeout_ms: hook.timeoutMs,
|
|
130
|
+
trusted: hook.trusted
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
function hookBindingForSubmitHook(event, hook) {
|
|
134
|
+
const id = submitHookId(event);
|
|
135
|
+
const result = hook.publishResult === void 0 && hook.saveResultAs === void 0 ? void 0 : objectWithoutUndefined({
|
|
136
|
+
publish: hook.publishResult,
|
|
137
|
+
save_as: hook.saveResultAs
|
|
138
|
+
});
|
|
139
|
+
return objectWithoutUndefined({
|
|
140
|
+
failure: hook.failure,
|
|
141
|
+
function: id,
|
|
142
|
+
id,
|
|
143
|
+
result,
|
|
144
|
+
where: hook.where,
|
|
145
|
+
with: hook.input
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
function submitHookEntries(hooks) {
|
|
149
|
+
return Object.entries(hooks ?? {}).filter((entry) => entry[1] !== void 0).map(([event, hook]) => ({
|
|
150
|
+
event,
|
|
151
|
+
hook
|
|
152
|
+
}));
|
|
153
|
+
}
|
|
154
|
+
function cloneHookBindings(on) {
|
|
155
|
+
return Object.fromEntries(Object.entries(on).map(([event, bindings]) => [event, [...bindings]]));
|
|
156
|
+
}
|
|
157
|
+
function appendSubmitHook(event, hook, target) {
|
|
158
|
+
const id = submitHookId(event);
|
|
159
|
+
if (target.functions[id] !== void 0) throw new Error(`Moka submit hook id already exists in config: ${id}`);
|
|
160
|
+
target.functions[id] = hookFunctionForSubmitHook(hook);
|
|
161
|
+
target.on[event] = [...target.on[event] ?? [], hookBindingForSubmitHook(event, hook)];
|
|
162
|
+
}
|
|
163
|
+
function configWithSubmitHooks(config, hooks) {
|
|
164
|
+
const entries = submitHookEntries(hooks);
|
|
165
|
+
if (entries.length === 0) return config;
|
|
166
|
+
const target = {
|
|
167
|
+
functions: { ...config.hooks.functions },
|
|
168
|
+
on: cloneHookBindings(config.hooks.on)
|
|
169
|
+
};
|
|
170
|
+
for (const { event, hook } of entries) appendSubmitHook(event, hook, target);
|
|
171
|
+
return {
|
|
172
|
+
...config,
|
|
173
|
+
hooks: {
|
|
174
|
+
...config.hooks,
|
|
175
|
+
functions: target.functions,
|
|
176
|
+
on: target.on
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
}
|
|
65
180
|
function submitMoka(rawOptions, dependencies = {}) {
|
|
66
181
|
const { config, worktreePath, ...schemaOptions } = rawOptions;
|
|
182
|
+
const options = mokaSubmitOptionsSchema.parse(schemaOptions);
|
|
67
183
|
const parsedOptions = {
|
|
68
|
-
...
|
|
69
|
-
config,
|
|
184
|
+
...options,
|
|
185
|
+
config: configWithSubmitHooks(config, options.hooks),
|
|
70
186
|
worktreePath
|
|
71
187
|
};
|
|
72
188
|
return parsedOptions.type === "command" ? submitMokaCommand(parsedOptions, dependencies) : submitMokaGraph(parsedOptions, dependencies);
|
|
@@ -184,6 +300,7 @@ function runnerPayloadJson(input) {
|
|
|
184
300
|
return JSON.stringify(buildRunnerCommandPayload({
|
|
185
301
|
delivery: input.options.delivery,
|
|
186
302
|
events: runnerEvents(input.options),
|
|
303
|
+
hookPolicy: input.options.hookPolicy,
|
|
187
304
|
repository: {
|
|
188
305
|
baseBranch: input.context.repository.baseBranch,
|
|
189
306
|
sha: input.context.repository.sha,
|
|
@@ -200,10 +317,11 @@ function runnerPayloadJson(input) {
|
|
|
200
317
|
}));
|
|
201
318
|
}
|
|
202
319
|
function runnerEvents(options) {
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
320
|
+
const eventSink = options.eventSink ?? options.events;
|
|
321
|
+
if (eventSink) return {
|
|
322
|
+
authHeader: eventSink.authHeader,
|
|
323
|
+
authTokenFile: eventSink.authTokenFile ?? eventAuthTokenFile(options),
|
|
324
|
+
url: eventSink.url
|
|
207
325
|
};
|
|
208
326
|
return {
|
|
209
327
|
authHeader: "Authorization",
|
|
@@ -279,4 +397,4 @@ function generateRunId(dependencies) {
|
|
|
279
397
|
return dependencies.generateRunId?.() ?? `run-${randomBytes(8).toString("hex")}`;
|
|
280
398
|
}
|
|
281
399
|
//#endregion
|
|
282
|
-
export { mokaSubmitOptionsSchema, mokaSubmitResultSchema, submitMoka };
|
|
400
|
+
export { mokaSubmitDirectHooksSchema, mokaSubmitHookPolicySchema, mokaSubmitOptionsSchema, mokaSubmitResultSchema, submitMoka };
|
|
@@ -64,7 +64,7 @@ async function runRunnerCommand(rawOptions = {}) {
|
|
|
64
64
|
});
|
|
65
65
|
const result = await runScheduledWorkflowTask({
|
|
66
66
|
config: compiled.config,
|
|
67
|
-
hookPolicy:
|
|
67
|
+
hookPolicy: payload.hookPolicy,
|
|
68
68
|
nodeId: descriptor.nodeId,
|
|
69
69
|
reporter: (event) => sink.recordRuntimeEvent(event),
|
|
70
70
|
runId: payload.run.id,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PipelineRuntimeEvent } from "./runtime/contracts/contracts.js";
|
|
1
|
+
import { HookRuntimePolicy, PipelineRuntimeEvent } from "./runtime/contracts/contracts.js";
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
|
|
4
4
|
//#region src/runner-command-contract.d.ts
|
|
@@ -55,6 +55,14 @@ declare const runnerEventsSchema: z.ZodObject<{
|
|
|
55
55
|
authTokenFile: z.ZodString;
|
|
56
56
|
url: z.ZodString;
|
|
57
57
|
}, z.core.$strict>;
|
|
58
|
+
declare const runnerHookPolicySchema: z.ZodObject<{
|
|
59
|
+
allowCommandHooks: z.ZodOptional<z.ZodBoolean>;
|
|
60
|
+
allowUntrustedCommandHooks: z.ZodOptional<z.ZodBoolean>;
|
|
61
|
+
env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
62
|
+
envPassthrough: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
63
|
+
outputLimitBytes: z.ZodOptional<z.ZodNumber>;
|
|
64
|
+
timeoutMs: z.ZodOptional<z.ZodNumber>;
|
|
65
|
+
}, z.core.$strict>;
|
|
58
66
|
declare const runnerMomokayaContextSchema: z.ZodObject<{
|
|
59
67
|
automationNamespace: z.ZodOptional<z.ZodString>;
|
|
60
68
|
previewEnabled: z.ZodBoolean;
|
|
@@ -70,6 +78,14 @@ declare const runnerCommandPayloadSchema: z.ZodObject<{
|
|
|
70
78
|
authTokenFile: z.ZodString;
|
|
71
79
|
url: z.ZodString;
|
|
72
80
|
}, z.core.$strict>;
|
|
81
|
+
hookPolicy: z.ZodOptional<z.ZodObject<{
|
|
82
|
+
allowCommandHooks: z.ZodOptional<z.ZodBoolean>;
|
|
83
|
+
allowUntrustedCommandHooks: z.ZodOptional<z.ZodBoolean>;
|
|
84
|
+
env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
85
|
+
envPassthrough: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
86
|
+
outputLimitBytes: z.ZodOptional<z.ZodNumber>;
|
|
87
|
+
timeoutMs: z.ZodOptional<z.ZodNumber>;
|
|
88
|
+
}, z.core.$strict>>;
|
|
73
89
|
momokaya: z.ZodOptional<z.ZodObject<{
|
|
74
90
|
automationNamespace: z.ZodOptional<z.ZodString>;
|
|
75
91
|
previewEnabled: z.ZodBoolean;
|
|
@@ -111,6 +127,7 @@ declare const runnerCommandPayloadSchema: z.ZodObject<{
|
|
|
111
127
|
}, z.core.$strict>;
|
|
112
128
|
type RunnerDelivery = z.infer<typeof runnerDeliverySchema>;
|
|
113
129
|
type RunnerEvents = z.infer<typeof runnerEventsSchema>;
|
|
130
|
+
type RunnerHookPolicy = z.infer<typeof runnerHookPolicySchema>;
|
|
114
131
|
type MokaSubmission = z.infer<typeof mokaSubmissionSchema>;
|
|
115
132
|
type RunnerCommandPayload = z.infer<typeof runnerCommandPayloadSchema>;
|
|
116
133
|
type RunnerMomokayaContext = z.infer<typeof runnerMomokayaContextSchema>;
|
|
@@ -130,6 +147,7 @@ declare class RunnerCommandPayloadValidationError extends Error {
|
|
|
130
147
|
interface BuildRunnerCommandPayloadOptions {
|
|
131
148
|
delivery?: RunnerDelivery;
|
|
132
149
|
events: RunnerEvents;
|
|
150
|
+
hookPolicy?: HookRuntimePolicy;
|
|
133
151
|
momokaya?: RunnerMomokayaContext;
|
|
134
152
|
repository: RunnerRepositoryContext;
|
|
135
153
|
run: RunnerRunIdentity;
|
|
@@ -271,4 +289,4 @@ declare function buildRunnerCommandPayload(options: BuildRunnerCommandPayloadOpt
|
|
|
271
289
|
declare function parseRunnerCommandPayload(rawPayload: string): RunnerCommandPayload;
|
|
272
290
|
declare function mapRuntimeEventToRunnerEventRecords(event: PipelineRuntimeEvent, context: RunnerEventMappingContext): RunnerEventRecord[];
|
|
273
291
|
//#endregion
|
|
274
|
-
export { BuildRunnerCommandPayloadOptions, MokaSubmission, ResolveRunnerEventSinkAuthTokenOptions, RunnerArtifactDetails, RunnerArtifactStatus, RunnerCommandPayload, RunnerCommandPayloadValidationError, RunnerCommandPayloadValidationIssue, RunnerDelivery, RunnerEventMappingContext, RunnerEventRecord, RunnerEvents, RunnerFinalResultDetails, RunnerGateDetails, RunnerGateStatus, RunnerHookResultDetails, RunnerLogDetails, RunnerLogLevel, RunnerMomokayaContext, RunnerNodeDetails, RunnerNodeStatus, RunnerRepositoryContext, RunnerRunIdentity, RunnerTask, RunnerWorkflowEdgeDetails, RunnerWorkflowEdgeRecordDetails, RunnerWorkflowIdentity, RunnerWorkflowNodeDetails, RunnerWorkflowPlanDetails, buildRunnerCommandPayload, gitRemoteUrlSchema, mapRuntimeEventToRunnerEventRecords, parseRunnerCommandPayload, resolveRunnerEventSinkAuthToken, runnerCommandPayloadSchema, runnerDeliverySchema, runnerEventsSchema, runnerRepositoryContextSchema, runnerRunIdentitySchema, runnerTaskPromptSchema, runnerTaskSchema, runnerTaskTicketSchema, runnerWorkflowIdentitySchema };
|
|
292
|
+
export { BuildRunnerCommandPayloadOptions, MokaSubmission, ResolveRunnerEventSinkAuthTokenOptions, RunnerArtifactDetails, RunnerArtifactStatus, RunnerCommandPayload, RunnerCommandPayloadValidationError, RunnerCommandPayloadValidationIssue, RunnerDelivery, RunnerEventMappingContext, RunnerEventRecord, RunnerEvents, RunnerFinalResultDetails, RunnerGateDetails, RunnerGateStatus, RunnerHookPolicy, RunnerHookResultDetails, RunnerLogDetails, RunnerLogLevel, RunnerMomokayaContext, RunnerNodeDetails, RunnerNodeStatus, RunnerRepositoryContext, RunnerRunIdentity, RunnerTask, RunnerWorkflowEdgeDetails, RunnerWorkflowEdgeRecordDetails, RunnerWorkflowIdentity, RunnerWorkflowNodeDetails, RunnerWorkflowPlanDetails, buildRunnerCommandPayload, gitRemoteUrlSchema, mapRuntimeEventToRunnerEventRecords, parseRunnerCommandPayload, resolveRunnerEventSinkAuthToken, runnerCommandPayloadSchema, runnerDeliverySchema, runnerEventsSchema, runnerHookPolicySchema, runnerRepositoryContextSchema, runnerRunIdentitySchema, runnerTaskPromptSchema, runnerTaskSchema, runnerTaskTicketSchema, runnerWorkflowIdentitySchema };
|
|
@@ -43,6 +43,14 @@ const runnerEventsSchema = z.object({
|
|
|
43
43
|
authTokenFile: z.string().min(1),
|
|
44
44
|
url: z.string().url()
|
|
45
45
|
}).strict();
|
|
46
|
+
const runnerHookPolicySchema = z.object({
|
|
47
|
+
allowCommandHooks: z.boolean().optional(),
|
|
48
|
+
allowUntrustedCommandHooks: z.boolean().optional(),
|
|
49
|
+
env: z.record(z.string(), z.string()).optional(),
|
|
50
|
+
envPassthrough: z.array(z.string().min(1)).optional(),
|
|
51
|
+
outputLimitBytes: z.number().int().positive().optional(),
|
|
52
|
+
timeoutMs: z.number().int().positive().optional()
|
|
53
|
+
}).strict();
|
|
46
54
|
const runnerMomokayaContextSchema = z.object({
|
|
47
55
|
automationNamespace: z.string().min(1).optional(),
|
|
48
56
|
previewEnabled: z.boolean(),
|
|
@@ -52,6 +60,7 @@ const runnerCommandPayloadSchema = z.object({
|
|
|
52
60
|
contractVersion: z.literal(RUNNER_COMMAND_CONTRACT_VERSION, { error: "runner command payload contract version must be 1" }).default(RUNNER_COMMAND_CONTRACT_VERSION),
|
|
53
61
|
delivery: runnerDeliverySchema.default({ pullRequest: false }),
|
|
54
62
|
events: runnerEventsSchema,
|
|
63
|
+
hookPolicy: runnerHookPolicySchema.optional(),
|
|
55
64
|
momokaya: runnerMomokayaContextSchema.optional(),
|
|
56
65
|
repository: runnerRepositoryContextSchema,
|
|
57
66
|
run: runnerRunIdentitySchema,
|
|
@@ -79,6 +88,7 @@ function buildRunnerCommandPayload(options) {
|
|
|
79
88
|
contractVersion: RUNNER_COMMAND_CONTRACT_VERSION,
|
|
80
89
|
delivery: options.delivery,
|
|
81
90
|
events: options.events,
|
|
91
|
+
hookPolicy: options.hookPolicy,
|
|
82
92
|
...options.momokaya ? { momokaya: options.momokaya } : {},
|
|
83
93
|
repository: options.repository,
|
|
84
94
|
run: options.run,
|
|
@@ -433,4 +443,4 @@ function throwUnhandledRuntimeEvent(value) {
|
|
|
433
443
|
throw new Error(`Unhandled runtime event: ${value.type}`);
|
|
434
444
|
}
|
|
435
445
|
//#endregion
|
|
436
|
-
export { RunnerCommandPayloadValidationError, buildRunnerCommandPayload, gitRemoteUrlSchema, mapRuntimeEventToRunnerEventRecords, parseRunnerCommandPayload, resolveRunnerEventSinkAuthToken, runnerCommandPayloadSchema, runnerDeliverySchema, runnerEventsSchema, runnerRepositoryContextSchema, runnerRunIdentitySchema, runnerTaskPromptSchema, runnerTaskSchema, runnerTaskTicketSchema, runnerWorkflowIdentitySchema };
|
|
446
|
+
export { RunnerCommandPayloadValidationError, buildRunnerCommandPayload, gitRemoteUrlSchema, mapRuntimeEventToRunnerEventRecords, parseRunnerCommandPayload, resolveRunnerEventSinkAuthToken, runnerCommandPayloadSchema, runnerDeliverySchema, runnerEventsSchema, runnerHookPolicySchema, runnerRepositoryContextSchema, runnerRunIdentitySchema, runnerTaskPromptSchema, runnerTaskSchema, runnerTaskTicketSchema, runnerWorkflowIdentitySchema };
|
package/dist/runner.js
CHANGED
|
@@ -27,7 +27,7 @@ function ensureOpencodeGitExcludes(worktreePath) {
|
|
|
27
27
|
appendFileSync(excludePath, `${existing.endsWith("\n") ? "" : "\n"}# oisin-pipeline opencode excludes\n${missing.join("\n")}\n`);
|
|
28
28
|
}
|
|
29
29
|
function optionalModelArgs(runner, actor, selectedModel) {
|
|
30
|
-
const model = selectedModel ?? actor?.model ?? runner?.model ?? process.env.PIPELINE_OPENCODE_MODEL ?? "
|
|
30
|
+
const model = selectedModel ?? actor?.model ?? runner?.model ?? process.env.PIPELINE_OPENCODE_MODEL ?? "gpt-5.5";
|
|
31
31
|
return model ? ["--model", model] : [];
|
|
32
32
|
}
|
|
33
33
|
/**
|
|
@@ -67,7 +67,7 @@ function noProgressResult(state, prompts) {
|
|
|
67
67
|
function createGoalContinuationLaunchPlan(input) {
|
|
68
68
|
return createRunnerLaunchPlan(input.config, {
|
|
69
69
|
nodeId: input.nodeId ?? "goal-continuation",
|
|
70
|
-
profileId: input.profileId ?? "
|
|
70
|
+
profileId: input.profileId ?? "moka-code-writer",
|
|
71
71
|
prompt: input.prompt,
|
|
72
72
|
worktreePath: input.worktreePath
|
|
73
73
|
});
|
package/dist/schedule-planner.js
CHANGED
|
@@ -30,9 +30,9 @@ const SCHEDULE_BUILTINS = [
|
|
|
30
30
|
"typecheck"
|
|
31
31
|
];
|
|
32
32
|
const DEFAULT_GENERATED_COVERAGE_PROFILE_PREFERENCE = [
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
"
|
|
33
|
+
"moka-verifier",
|
|
34
|
+
"moka-acceptance-reviewer",
|
|
35
|
+
"moka-thermo-nuclear-reviewer"
|
|
36
36
|
];
|
|
37
37
|
const scheduleArtifactSchema = z.object({
|
|
38
38
|
generated_at: z.string().datetime(),
|
|
@@ -273,19 +273,19 @@ function quickBaselineWorkflow() {
|
|
|
273
273
|
{
|
|
274
274
|
id: "backlog-intake",
|
|
275
275
|
kind: "agent",
|
|
276
|
-
profile: "
|
|
276
|
+
profile: "moka-researcher"
|
|
277
277
|
},
|
|
278
278
|
{
|
|
279
279
|
id: "red-tests",
|
|
280
280
|
kind: "agent",
|
|
281
281
|
needs: ["backlog-intake"],
|
|
282
|
-
profile: "
|
|
282
|
+
profile: "moka-test-writer"
|
|
283
283
|
},
|
|
284
284
|
{
|
|
285
285
|
id: "implement",
|
|
286
286
|
kind: "agent",
|
|
287
287
|
needs: ["red-tests"],
|
|
288
|
-
profile: "
|
|
288
|
+
profile: "moka-code-writer"
|
|
289
289
|
},
|
|
290
290
|
{
|
|
291
291
|
builtin: "test",
|
|
@@ -330,7 +330,7 @@ function quickBaselineWorkflow() {
|
|
|
330
330
|
id: "verify",
|
|
331
331
|
kind: "agent",
|
|
332
332
|
needs: ["mechanical-tests", "mechanical-typecheck"],
|
|
333
|
-
profile: "
|
|
333
|
+
profile: "moka-verifier"
|
|
334
334
|
}
|
|
335
335
|
]
|
|
336
336
|
} };
|
|
@@ -342,13 +342,13 @@ function executeBaselineWorkflow() {
|
|
|
342
342
|
{
|
|
343
343
|
id: "backlog-intake",
|
|
344
344
|
kind: "agent",
|
|
345
|
-
profile: "
|
|
345
|
+
profile: "moka-researcher"
|
|
346
346
|
},
|
|
347
347
|
{
|
|
348
348
|
id: "research",
|
|
349
349
|
kind: "agent",
|
|
350
350
|
needs: ["backlog-intake"],
|
|
351
|
-
profile: "
|
|
351
|
+
profile: "moka-researcher"
|
|
352
352
|
},
|
|
353
353
|
{
|
|
354
354
|
gates: [{
|
|
@@ -377,13 +377,13 @@ function executeBaselineWorkflow() {
|
|
|
377
377
|
id: "red-tests",
|
|
378
378
|
kind: "agent",
|
|
379
379
|
needs: ["research"],
|
|
380
|
-
profile: "
|
|
380
|
+
profile: "moka-test-writer"
|
|
381
381
|
},
|
|
382
382
|
{
|
|
383
383
|
id: "green-implementation",
|
|
384
384
|
kind: "agent",
|
|
385
385
|
needs: ["red-tests"],
|
|
386
|
-
profile: "
|
|
386
|
+
profile: "moka-code-writer"
|
|
387
387
|
},
|
|
388
388
|
{
|
|
389
389
|
builtin: "test",
|
|
@@ -428,7 +428,7 @@ function executeBaselineWorkflow() {
|
|
|
428
428
|
"mechanical-green-lint",
|
|
429
429
|
"mechanical-green-fallow"
|
|
430
430
|
],
|
|
431
|
-
profile: "
|
|
431
|
+
profile: "moka-acceptance-reviewer"
|
|
432
432
|
},
|
|
433
433
|
{
|
|
434
434
|
gates: [
|
|
@@ -471,13 +471,13 @@ function executeBaselineWorkflow() {
|
|
|
471
471
|
id: "verification",
|
|
472
472
|
kind: "agent",
|
|
473
473
|
needs: ["acceptance-review"],
|
|
474
|
-
profile: "
|
|
474
|
+
profile: "moka-verifier"
|
|
475
475
|
},
|
|
476
476
|
{
|
|
477
477
|
id: "learn",
|
|
478
478
|
kind: "agent",
|
|
479
479
|
needs: ["verification"],
|
|
480
|
-
profile: "
|
|
480
|
+
profile: "moka-learner"
|
|
481
481
|
}
|
|
482
482
|
]
|
|
483
483
|
} };
|
|
@@ -22,7 +22,7 @@ runners:
|
|
|
22
22
|
opencode:
|
|
23
23
|
type: opencode
|
|
24
24
|
command: opencode
|
|
25
|
-
model:
|
|
25
|
+
model: gpt-5.5
|
|
26
26
|
capabilities:
|
|
27
27
|
native_subagents: true
|
|
28
28
|
rules: true
|
|
@@ -55,7 +55,7 @@ profiles:
|
|
|
55
55
|
tools: [read, list, grep, glob, bash]
|
|
56
56
|
filesystem:
|
|
57
57
|
mode: read-only
|
|
58
|
-
|
|
58
|
+
moka-researcher:
|
|
59
59
|
runner: opencode
|
|
60
60
|
instructions:
|
|
61
61
|
path: .pipeline/prompts/researcher.md
|
|
@@ -106,12 +106,12 @@ workflows:
|
|
|
106
106
|
nodes:
|
|
107
107
|
- id: inspect
|
|
108
108
|
kind: agent
|
|
109
|
-
profile:
|
|
109
|
+
profile: moka-inspector
|
|
110
110
|
default:
|
|
111
111
|
nodes:
|
|
112
112
|
- id: research
|
|
113
113
|
kind: agent
|
|
114
|
-
profile:
|
|
114
|
+
profile: moka-researcher
|
|
115
115
|
- id: verify
|
|
116
116
|
kind: builtin
|
|
117
117
|
builtin: test
|
package/docs/mcp-gateway.md
CHANGED
package/docs/operator-guide.md
CHANGED
|
@@ -148,6 +148,16 @@ moka submit "fix the login bug" --quick --kubeconfig ~/.kube/config --namespace
|
|
|
148
148
|
There is no separate workstation-local `submit` path; local submission means
|
|
149
149
|
submitting to a local Kubernetes cluster.
|
|
150
150
|
|
|
151
|
+
Pipeline Console and other TypeScript control planes should use
|
|
152
|
+
`@oisincoveney/pipeline/moka-submit` instead of shelling out or importing Argo
|
|
153
|
+
internals. The public API accepts `eventSink` for runner event delivery,
|
|
154
|
+
`hooks` for direct lifecycle hook declarations, and `hookPolicy` for per-run
|
|
155
|
+
hook execution policy. `eventSink` is not a hook mechanism; it is the transport
|
|
156
|
+
used by runner pods to POST durable events back to the control plane. Direct
|
|
157
|
+
submit hooks are normalized into deterministic internal function ids like
|
|
158
|
+
`moka-submit-node-finish`; non-conflicting package hooks remain intact, and a
|
|
159
|
+
generated id collision is rejected before submission.
|
|
160
|
+
|
|
151
161
|
### Runner Workflow Shape
|
|
152
162
|
|
|
153
163
|
The runner container entrypoint is `moka runner-command`. Validation errors exit
|
|
@@ -371,7 +381,7 @@ skills:
|
|
|
371
381
|
path: .agents/skills/accessibility-review/SKILL.md
|
|
372
382
|
|
|
373
383
|
profiles:
|
|
374
|
-
|
|
384
|
+
moka-frontend-reviewer:
|
|
375
385
|
runner: opencode
|
|
376
386
|
instructions:
|
|
377
387
|
path: .pipeline/prompts/frontend-reviewer.md
|
|
@@ -390,7 +400,7 @@ mcp_gateway:
|
|
|
390
400
|
authorization_env: PIPELINE_MCP_GATEWAY_AUTHORIZATION
|
|
391
401
|
|
|
392
402
|
profiles:
|
|
393
|
-
|
|
403
|
+
moka-router:
|
|
394
404
|
runner: opencode
|
|
395
405
|
instructions:
|
|
396
406
|
path: .pipeline/prompts/router.md
|
package/package.json
CHANGED
|
@@ -120,7 +120,7 @@
|
|
|
120
120
|
"prepack": "bun run build:cli"
|
|
121
121
|
},
|
|
122
122
|
"type": "module",
|
|
123
|
-
"version": "1.
|
|
123
|
+
"version": "1.27.1",
|
|
124
124
|
"description": "Config-driven multi-agent pipeline runner for repository work",
|
|
125
125
|
"main": "./dist/index.js",
|
|
126
126
|
"types": "./dist/index.d.ts",
|