@oisincoveney/pipeline 2.1.1 → 2.3.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/.agents/skills/orchestrate/SKILL.md +80 -0
- package/defaults/pipeline.yaml +111 -0
- package/defaults/profiles.yaml +215 -0
- package/defaults/runners.yaml +24 -0
- package/dist/argo-graph.js +59 -27
- package/dist/argo-submit.d.ts +0 -1
- package/dist/argo-submit.js +11 -6
- package/dist/argo-workflow.d.ts +1 -2
- package/dist/argo-workflow.js +0 -2
- package/dist/claude-settings-config.js +44 -0
- package/dist/cli/program.js +12 -5
- package/dist/cli/submit-options.js +1 -2
- package/dist/cluster-doctor.js +0 -12
- package/dist/commands/pipeline-command.js +1 -1
- package/dist/config/defaults.js +7 -350
- package/dist/config/schemas.d.ts +9 -9
- package/dist/install-commands/claude-code.js +160 -0
- package/dist/install-commands/opencode.js +56 -39
- package/dist/install-commands/shared.js +32 -5
- package/dist/install-commands.js +26 -15
- package/dist/json-config-merge.js +47 -0
- package/dist/mcp/gateway.js +9 -1
- package/dist/moka-global-config.d.ts +0 -1
- package/dist/moka-global-config.js +0 -1
- package/dist/moka-submit.d.ts +8 -11
- package/dist/moka-submit.js +1 -4
- package/dist/opencode-project-config.js +2 -45
- package/dist/pipeline-runtime.d.ts +9 -0
- package/dist/pipeline-runtime.js +50 -8
- package/dist/planned-node.js +2 -5
- package/dist/{workflow-planner.d.ts → planning/compile.d.ts} +2 -2
- package/dist/{workflow-planner.js → planning/compile.js} +6 -83
- package/dist/{schedule/planner.d.ts → planning/generate.d.ts} +17 -3
- package/dist/{schedule/planner.js → planning/generate.js} +24 -56
- package/dist/planning/graph.js +138 -0
- package/dist/runner-command/lifecycle-context.js +2 -3
- package/dist/runner-command/run.js +2 -3
- package/dist/runner-command-contract.d.ts +2 -2
- package/dist/runner-event-schema.d.ts +349 -0
- package/dist/runner-event-schema.js +185 -0
- package/dist/runner-output.js +2 -2
- package/dist/runner.d.ts +29 -0
- package/dist/runtime/agent-node/agent-node.js +1 -0
- package/dist/runtime/context/context.js +1 -1
- package/dist/runtime/contracts/contracts.d.ts +18 -1
- package/dist/runtime/node-state-store.js +7 -0
- package/dist/runtime/opencode-adapter.js +28 -8
- package/dist/runtime/opencode-agent-name.js +18 -0
- package/dist/runtime/opencode-runtime.js +62 -0
- package/dist/runtime/opencode-server.js +67 -0
- package/dist/runtime/opencode-session-executor.js +206 -0
- package/dist/schedule/passes/coverage.js +7 -51
- package/dist/schedule/passes/ids.js +3 -23
- package/dist/schedule/scheduling-roles.js +19 -0
- package/dist/strings.js +30 -1
- package/docs/adr-opencode-first-goal-loop-runtime.md +1 -1
- package/docs/config-architecture.md +43 -6
- package/docs/mcp-gateway.md +4 -4
- package/docs/operator-guide.md +9 -8
- package/docs/pipeline-console-runner-contract.md +3 -4
- package/docs/slash-command-adapter-contract.md +1 -0
- package/package.json +10 -5
- package/dist/schedule-planner.d.ts +0 -2
- package/dist/schedule-planner.js +0 -2
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { applyJsonEdit, ensureTrailingNewline, formatJson, isRecord, parseJsonRecord, setIfMissing } from "./json-config-merge.js";
|
|
2
|
+
//#region src/claude-settings-config.ts
|
|
3
|
+
function mergeClaudeSettings(currentText, projection) {
|
|
4
|
+
if (currentText === void 0) return {
|
|
5
|
+
content: formatJson(projection),
|
|
6
|
+
ok: true
|
|
7
|
+
};
|
|
8
|
+
const parsed = parseJsonRecord(currentText);
|
|
9
|
+
if (!parsed.ok) return parsed;
|
|
10
|
+
return {
|
|
11
|
+
content: ensureTrailingNewline(applyClaudeProjection(currentText, parsed.value, projection)),
|
|
12
|
+
ok: true
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
function applyClaudeProjection(currentText, parsed, projection) {
|
|
16
|
+
return applyPermissionsAllow(applyMcpServersProjection(currentText, parsed, projection), parsed, projection);
|
|
17
|
+
}
|
|
18
|
+
function applyMcpServersProjection(content, parsed, projection) {
|
|
19
|
+
return Object.entries(projection.mcpServers ?? {}).reduce((nextContent, [name, server]) => setIfMissing(nextContent, parsed, ["mcpServers", name], server), content);
|
|
20
|
+
}
|
|
21
|
+
function applyPermissionsAllow(content, parsed, projection) {
|
|
22
|
+
const existing = permissionAllowList(parsed);
|
|
23
|
+
const merged = unionPreservingOrder(existing, projectedAllowList(projection));
|
|
24
|
+
return sameOrderedList(existing, merged) ? content : applyJsonEdit(content, ["permissions", "allow"], merged);
|
|
25
|
+
}
|
|
26
|
+
function projectedAllowList(projection) {
|
|
27
|
+
return projection.permissions?.allow ?? [];
|
|
28
|
+
}
|
|
29
|
+
function unionPreservingOrder(existing, extra) {
|
|
30
|
+
const merged = [...existing];
|
|
31
|
+
for (const entry of extra) if (!merged.includes(entry)) merged.push(entry);
|
|
32
|
+
return merged;
|
|
33
|
+
}
|
|
34
|
+
function sameOrderedList(a, b) {
|
|
35
|
+
return a.length === b.length && a.every((value, index) => value === b[index]);
|
|
36
|
+
}
|
|
37
|
+
function permissionAllowList(parsed) {
|
|
38
|
+
const permissions = parsed.permissions;
|
|
39
|
+
if (!isRecord(permissions)) return [];
|
|
40
|
+
const allow = permissions.allow;
|
|
41
|
+
return Array.isArray(allow) ? allow.filter((entry) => typeof entry === "string") : [];
|
|
42
|
+
}
|
|
43
|
+
//#endregion
|
|
44
|
+
export { mergeClaudeSettings };
|
package/dist/cli/program.js
CHANGED
|
@@ -2,9 +2,8 @@ import { PipelineConfigError } from "../config/schemas.js";
|
|
|
2
2
|
import { loadPipelineConfig } from "../config/load.js";
|
|
3
3
|
import "../config.js";
|
|
4
4
|
import { createOrchestratorLaunchPlan, createRunnerLaunchPlan } from "../runner.js";
|
|
5
|
-
import { compileWorkflowPlan } from "../
|
|
6
|
-
import { compileScheduleArtifact, generateScheduleArtifact, parseScheduleArtifact } from "../
|
|
7
|
-
import "../schedule-planner.js";
|
|
5
|
+
import { compileWorkflowPlan } from "../planning/compile.js";
|
|
6
|
+
import { compileScheduleArtifact, generateScheduleArtifact, parseScheduleArtifact } from "../planning/generate.js";
|
|
8
7
|
import { loadMokaGlobalConfig } from "../moka-global-config.js";
|
|
9
8
|
import { defaultClusterDoctorNamespace, runClusterDoctor } from "../cluster-doctor.js";
|
|
10
9
|
import { formatCodexAuthSyncResult, syncLocalCodexAuth } from "../codex-auth-sync.js";
|
|
@@ -150,7 +149,7 @@ function createCliProgram() {
|
|
|
150
149
|
const config = loadPipelineConfig(process.env.PIPELINE_TARGET_PATH ?? process.cwd(), { allowMissingLintFileReferences: true });
|
|
151
150
|
console.log(renderGatewayConfig(config));
|
|
152
151
|
});
|
|
153
|
-
gatewayCommand.command("configure-host").description("Rewrite host MCP config to the singleton pipeline gateway").addOption(new Option("--host <host>", "host config to update").choices(["all", "opencode"]).default("all").argParser(
|
|
152
|
+
gatewayCommand.command("configure-host").description("Rewrite host MCP config to the singleton pipeline gateway").addOption(new Option("--host <host>", "host config to update").choices(["all", "opencode"]).default("all").argParser(parseGatewayHost)).addOption(new Option("--scope <scope>", "config scope to update").choices(["project", "global"]).default("project").argParser(parseGatewayHostScope)).action((flags) => {
|
|
154
153
|
const cwd = process.env.PIPELINE_TARGET_PATH ?? process.cwd();
|
|
155
154
|
const result = configureGatewayHosts(loadPipelineConfig(cwd, { allowMissingLintFileReferences: true }), {
|
|
156
155
|
cwd,
|
|
@@ -182,7 +181,11 @@ function createCliProgram() {
|
|
|
182
181
|
const result = await initPipelineProject({ cwd: process.env.PIPELINE_TARGET_PATH ?? process.cwd() });
|
|
183
182
|
console.log(formatPipelineInitResult(result));
|
|
184
183
|
});
|
|
185
|
-
program.command("install-commands").description("Install generated slash-command adapters into this repository").addOption(new Option("--host <host>", "host command set to install").choices([
|
|
184
|
+
program.command("install-commands").description("Install generated slash-command adapters into this repository").addOption(new Option("--host <host>", "host command set to install").choices([
|
|
185
|
+
"all",
|
|
186
|
+
"opencode",
|
|
187
|
+
"claude-code"
|
|
188
|
+
]).default("all").argParser(parseCommandHost)).option("--dry-run", "show planned changes without writing files").option("--check", "fail if generated command files are missing or stale").option("--force", "overwrite manually edited command files").action(async (flags) => {
|
|
186
189
|
const result = await installCommands({
|
|
187
190
|
...flags,
|
|
188
191
|
cwd: process.env.PIPELINE_TARGET_PATH ?? process.cwd()
|
|
@@ -232,6 +235,10 @@ function parseGatewayHostScope(value) {
|
|
|
232
235
|
if (value === "project" || value === "global") return value;
|
|
233
236
|
throw new Error("scope must be project or global");
|
|
234
237
|
}
|
|
238
|
+
function parseGatewayHost(value) {
|
|
239
|
+
if (value === "all" || value === "opencode") return value;
|
|
240
|
+
throw new Error("host must be all or opencode");
|
|
241
|
+
}
|
|
235
242
|
async function runCli(argv) {
|
|
236
243
|
await createCliProgram().parseAsync(argv, { from: "node" });
|
|
237
244
|
}
|
|
@@ -48,7 +48,6 @@ function mokaCommonSubmitOptions(input) {
|
|
|
48
48
|
name: input.flags.name,
|
|
49
49
|
namespace: input.flags.namespace ?? momokaya?.kubernetes.namespace,
|
|
50
50
|
opencodeAuthSecretName: momokaya?.submit.opencodeAuthSecretName,
|
|
51
|
-
queueName: input.flags.queueName ?? momokaya?.submit.queueName,
|
|
52
51
|
serviceAccountName: input.flags.serviceAccount ?? momokaya?.submit.serviceAccountName,
|
|
53
52
|
worktreePath: input.cwd
|
|
54
53
|
};
|
|
@@ -77,7 +76,7 @@ function submitMokaGraphInput(input, flags, commonOptions) {
|
|
|
77
76
|
function addRunnerArgoOptions(command, options = {}) {
|
|
78
77
|
command.option("--name <name>", "Workflow metadata.name").option("--generate-name <prefix>", "Workflow metadata.generateName").option("--namespace <namespace>", "Workflow namespace");
|
|
79
78
|
if (options.kubeconfig) command.option("--kubeconfig <path>", "kubeconfig path");
|
|
80
|
-
return command.option("--
|
|
79
|
+
return command.option("--service-account <name>", "Workflow service account").option("--image <image>", "runner image").addOption(new Option("--image-pull-policy <policy>", "runner image pull policy").choices([
|
|
81
80
|
"Always",
|
|
82
81
|
"IfNotPresent",
|
|
83
82
|
"Never"
|
package/dist/cluster-doctor.js
CHANGED
|
@@ -10,7 +10,6 @@ const DEFAULT_RESOURCES = {
|
|
|
10
10
|
githubAuthSecretName: "oisin-bot-github-auth",
|
|
11
11
|
imagePullSecretName: "ghcr-pull-secret",
|
|
12
12
|
opencodeAuthSecretName: "opencode-auth-1",
|
|
13
|
-
queueName: "pipeline-runner",
|
|
14
13
|
serviceAccountName: "pipeline-runner"
|
|
15
14
|
};
|
|
16
15
|
const FORBIDDEN_RE = /forbidden/i;
|
|
@@ -32,7 +31,6 @@ async function runClusterDoctor(options = {}) {
|
|
|
32
31
|
verb: "create",
|
|
33
32
|
...kubectlOptions
|
|
34
33
|
}),
|
|
35
|
-
checkLocalQueue(namespace, resources.queueName, kubectlOptions),
|
|
36
34
|
checkClusterResource("argo-workflow-crd", [
|
|
37
35
|
"get",
|
|
38
36
|
"crd",
|
|
@@ -63,7 +61,6 @@ function clusterResources() {
|
|
|
63
61
|
githubAuthSecretName: configured.githubAuthSecretName,
|
|
64
62
|
imagePullSecretName: configured.imagePullSecretName,
|
|
65
63
|
opencodeAuthSecretName: configured.opencodeAuthSecretName,
|
|
66
|
-
queueName: configured.queueName,
|
|
67
64
|
serviceAccountName: configured.serviceAccountName
|
|
68
65
|
} : DEFAULT_RESOURCES;
|
|
69
66
|
}
|
|
@@ -169,15 +166,6 @@ async function checkWorkflowSubmitPermission(namespace, options) {
|
|
|
169
166
|
passed: false
|
|
170
167
|
};
|
|
171
168
|
}
|
|
172
|
-
function checkLocalQueue(namespace, queueName, kubectlOptions) {
|
|
173
|
-
return checkNamespacedResource(`localqueue/${queueName}`, [
|
|
174
|
-
"get",
|
|
175
|
-
"localqueue",
|
|
176
|
-
queueName,
|
|
177
|
-
"-n",
|
|
178
|
-
namespace
|
|
179
|
-
], `Kueue LocalQueue ${queueName} missing in ${namespace}; runner Workflow pods cannot be admitted to the expected queue.`, kubectlOptions);
|
|
180
|
-
}
|
|
181
169
|
async function checkClusterResource(name, args, kubectlOptions) {
|
|
182
170
|
const result = await kubectl(args, kubectlOptions);
|
|
183
171
|
return result.ok ? {
|
|
@@ -17,7 +17,7 @@ function registerConfiguredEntrypointCommands(program, config, runEntrypoint) {
|
|
|
17
17
|
for (const [id, entrypoint] of Object.entries(config.entrypoints)) {
|
|
18
18
|
if (reservedCommands.has(id)) continue;
|
|
19
19
|
const command = program.command(id).description(entrypoint.description ?? `Run the ${id} workflow`).argument("<description...>", "task description");
|
|
20
|
-
if ("schedule" in entrypoint) command.option("--namespace <namespace>", "Workflow namespace").option("--schedule <path>", "approved schedule YAML to submit").option("--kubeconfig <path>", "kubeconfig path").option("--
|
|
20
|
+
if ("schedule" in entrypoint) command.option("--namespace <namespace>", "Workflow namespace").option("--schedule <path>", "approved schedule YAML to submit").option("--kubeconfig <path>", "kubeconfig path").option("--service-account <name>", "Workflow service account").option("--image <image>", "runner image").option("--image-pull-policy <policy>", "runner image pull policy").option("--image-pull-secret <name>", "imagePullSecret name").option("--event-url <url>", "runner event sink URL");
|
|
21
21
|
command.action(async (descriptionParts, flags) => {
|
|
22
22
|
await runEntrypoint(id, descriptionParts.join(" "), flags);
|
|
23
23
|
});
|
package/dist/config/defaults.js
CHANGED
|
@@ -7,356 +7,13 @@ const PIPELINE_CONFIG_PATH = ".pipeline/pipeline.yaml";
|
|
|
7
7
|
const RUNNERS_CONFIG_PATH = ".pipeline/runners.yaml";
|
|
8
8
|
const PROFILES_CONFIG_PATH = ".pipeline/profiles.yaml";
|
|
9
9
|
const OPENCODE_ECOSYSTEM_MANIFEST_PATH = "defaults/opencode-ecosystem.yaml";
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
skills: true
|
|
18
|
-
mcp_servers: true
|
|
19
|
-
tools: [read, list, grep, glob, bash, edit, write]
|
|
20
|
-
filesystem: [read-only, workspace-write]
|
|
21
|
-
network: [inherit, disabled]
|
|
22
|
-
output_formats: [text, json, jsonl, json_schema]
|
|
23
|
-
command:
|
|
24
|
-
type: command
|
|
25
|
-
capabilities:
|
|
26
|
-
native_subagents: false
|
|
27
|
-
rules: false
|
|
28
|
-
skills: false
|
|
29
|
-
mcp_servers: false
|
|
30
|
-
tools: [bash]
|
|
31
|
-
filesystem: [read-only, workspace-write]
|
|
32
|
-
network: [inherit, disabled]
|
|
33
|
-
output_formats: [text, json]
|
|
34
|
-
`;
|
|
35
|
-
const PACKAGE_DEFAULT_PROFILES_YAML = `version: 1
|
|
36
|
-
mcp_gateway:
|
|
37
|
-
provider: toolhive
|
|
38
|
-
mode: local
|
|
39
|
-
url: https://pipeline-mcp.momokaya.ee/mcp/
|
|
40
|
-
url_env: PIPELINE_MCP_GATEWAY_URL
|
|
41
|
-
authorization_env: PIPELINE_MCP_GATEWAY_AUTHORIZATION
|
|
42
|
-
default_profile: default
|
|
43
|
-
backends:
|
|
44
|
-
context7:
|
|
45
|
-
locality: shared-remote
|
|
46
|
-
tool_prefixes: [context7]
|
|
47
|
-
uidotsh:
|
|
48
|
-
locality: shared-remote
|
|
49
|
-
tool_prefixes: [uidotsh]
|
|
50
|
-
qdrant:
|
|
51
|
-
locality: repo-scoped-remote
|
|
52
|
-
tool_prefixes: [qdrant]
|
|
53
|
-
fallow:
|
|
54
|
-
locality: repo-local
|
|
55
|
-
workspace_path_source: PIPELINE_TARGET_PATH
|
|
56
|
-
required: false
|
|
57
|
-
tool_prefixes: [fallow]
|
|
58
|
-
serena:
|
|
59
|
-
locality: repo-local
|
|
60
|
-
workspace_path_source: PIPELINE_TARGET_PATH
|
|
61
|
-
tool_prefixes: [serena]
|
|
62
|
-
backlog:
|
|
63
|
-
locality: repo-local
|
|
64
|
-
workspace_path_source: PIPELINE_TARGET_PATH
|
|
65
|
-
tool_prefixes: [backlog]
|
|
66
|
-
skills:
|
|
67
|
-
execute:
|
|
68
|
-
path: .agents/skills/execute/SKILL.md
|
|
69
|
-
source_root: package
|
|
70
|
-
inspect:
|
|
71
|
-
path: .agents/skills/inspect/SKILL.md
|
|
72
|
-
source_root: package
|
|
73
|
-
quick:
|
|
74
|
-
path: .agents/skills/quick/SKILL.md
|
|
75
|
-
source_root: package
|
|
76
|
-
critique:
|
|
77
|
-
path: .agents/skills/critique/SKILL.md
|
|
78
|
-
source_root: package
|
|
79
|
-
doubt:
|
|
80
|
-
path: .agents/skills/doubt/SKILL.md
|
|
81
|
-
source_root: package
|
|
82
|
-
fix:
|
|
83
|
-
path: .agents/skills/fix/SKILL.md
|
|
84
|
-
source_root: package
|
|
85
|
-
library-first-development:
|
|
86
|
-
path: .agents/skills/library-first-development/SKILL.md
|
|
87
|
-
source_root: package
|
|
88
|
-
migrate:
|
|
89
|
-
path: .agents/skills/migrate/SKILL.md
|
|
90
|
-
source_root: package
|
|
91
|
-
optimize:
|
|
92
|
-
path: .agents/skills/optimize/SKILL.md
|
|
93
|
-
source_root: package
|
|
94
|
-
research:
|
|
95
|
-
path: .agents/skills/research/SKILL.md
|
|
96
|
-
source_root: package
|
|
97
|
-
schedule-graph-shaping:
|
|
98
|
-
path: .agents/skills/schedule-graph-shaping/SKILL.md
|
|
99
|
-
source_root: package
|
|
100
|
-
scope:
|
|
101
|
-
path: .agents/skills/scope/SKILL.md
|
|
102
|
-
source_root: package
|
|
103
|
-
secure:
|
|
104
|
-
path: .agents/skills/secure/SKILL.md
|
|
105
|
-
source_root: package
|
|
106
|
-
spec:
|
|
107
|
-
path: .agents/skills/spec/SKILL.md
|
|
108
|
-
source_root: package
|
|
109
|
-
test:
|
|
110
|
-
path: .agents/skills/test/SKILL.md
|
|
111
|
-
source_root: package
|
|
112
|
-
trace:
|
|
113
|
-
path: .agents/skills/trace/SKILL.md
|
|
114
|
-
source_root: package
|
|
115
|
-
verify:
|
|
116
|
-
path: .agents/skills/verify/SKILL.md
|
|
117
|
-
source_root: package
|
|
118
|
-
profiles:
|
|
119
|
-
moka-orchestrator:
|
|
120
|
-
runner: opencode
|
|
121
|
-
description: Orchestrate the configured pipeline and enforce gates.
|
|
122
|
-
instructions: { inline: "Orchestrate the configured pipeline through package-defined entrypoints, native agents, and gates. Do not bypass configured runner subprocesses or package-configured gates." }
|
|
123
|
-
skills: [execute, quick, inspect]
|
|
124
|
-
mcp_servers: [pipeline-gateway]
|
|
125
|
-
tools: [read, list, grep, glob, bash]
|
|
126
|
-
filesystem: { mode: read-only, allow: ["**/*"], deny: ["node_modules/**", "dist/**", ".git/**"] }
|
|
127
|
-
network: { mode: inherit }
|
|
128
|
-
moka-researcher:
|
|
129
|
-
runner: opencode
|
|
130
|
-
description: Research the requested task and produce structured findings.
|
|
131
|
-
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." }
|
|
132
|
-
timeout_ms: 900000
|
|
133
|
-
skills: [research, spec, scope]
|
|
134
|
-
mcp_servers: [pipeline-gateway]
|
|
135
|
-
tools: [read, list, grep, glob, bash]
|
|
136
|
-
filesystem: { mode: read-only, allow: ["**/*"], deny: ["node_modules/**", "dist/**", ".git/**"] }
|
|
137
|
-
network: { mode: inherit }
|
|
138
|
-
output:
|
|
139
|
-
format: json_schema
|
|
140
|
-
schema_path: .pipeline/schemas/research.schema.json
|
|
141
|
-
repair: { enabled: true, max_attempts: 1 }
|
|
142
|
-
moka-inspector:
|
|
143
|
-
runner: opencode
|
|
144
|
-
model: openai/gpt-5.5-low
|
|
145
|
-
description: Inspect the repository without modifying files.
|
|
146
|
-
instructions: { inline: "Inspect the repository without modifying files." }
|
|
147
|
-
skills: [research]
|
|
148
|
-
mcp_servers: [pipeline-gateway]
|
|
149
|
-
tools: [read, list, grep, glob, bash]
|
|
150
|
-
filesystem: { mode: read-only, allow: ["**/*"], deny: ["node_modules/**", "dist/**", ".git/**"] }
|
|
151
|
-
network: { mode: inherit }
|
|
152
|
-
moka-schedule-planner:
|
|
153
|
-
runner: opencode
|
|
154
|
-
model: openai/gpt-5.5-xhigh
|
|
155
|
-
description: Refine a baseline schedule into a specialized approved-plan artifact.
|
|
156
|
-
instructions: { inline: "Generate exactly one workflow named root as an explicit schedule graph. Return YAML only." }
|
|
157
|
-
timeout_ms: 300000
|
|
158
|
-
skills: [schedule-graph-shaping]
|
|
159
|
-
mcp_servers: [pipeline-gateway]
|
|
160
|
-
tools: [read, list, grep, glob, bash]
|
|
161
|
-
filesystem: { mode: read-only, allow: ["**/*"], deny: ["node_modules/**", "dist/**", ".git/**"] }
|
|
162
|
-
network: { mode: inherit }
|
|
163
|
-
moka-test-writer:
|
|
164
|
-
runner: opencode
|
|
165
|
-
scheduling_roles: [implementation]
|
|
166
|
-
description: Add focused failing tests for the requested behavior.
|
|
167
|
-
instructions: { inline: "Add focused failing tests for the requested behavior only. Do not change production code. Only edit files matching test paths such as **/*.test.*, **/*.spec.*, **/*_test.*, **/__tests__/**, test/**, or tests/**. Return only valid JSON with top-level changes and verification. Every changes entry must include summary, why, and files. Include risks, followups, and lessons when present. Do not use Markdown fences or prose outside the JSON object." }
|
|
168
|
-
skills: [test]
|
|
169
|
-
mcp_servers: [pipeline-gateway]
|
|
170
|
-
tools: [read, list, grep, glob, bash, edit, write]
|
|
171
|
-
filesystem: { mode: workspace-write, allow: ["**/*"], deny: ["node_modules/**", "dist/**", ".git/**"] }
|
|
172
|
-
network: { mode: inherit }
|
|
173
|
-
output:
|
|
174
|
-
format: json_schema
|
|
175
|
-
schema_path: .pipeline/schemas/implementation.schema.json
|
|
176
|
-
repair: { enabled: true, max_attempts: 1 }
|
|
177
|
-
moka-code-writer:
|
|
178
|
-
runner: opencode
|
|
179
|
-
scheduling_roles: [implementation]
|
|
180
|
-
description: Implement production code until the failing tests pass.
|
|
181
|
-
instructions: { inline: "Implement the smallest production change that satisfies the failing tests. Return only valid JSON with top-level changes and verification. Every changes entry must include summary, why, and files. Include risks, followups, and lessons when present. Do not use Markdown fences or prose outside the JSON object." }
|
|
182
|
-
skills: [trace, test, fix, library-first-development]
|
|
183
|
-
mcp_servers: [pipeline-gateway]
|
|
184
|
-
tools: [read, list, grep, glob, bash, edit, write]
|
|
185
|
-
filesystem: { mode: workspace-write, allow: ["**/*"], deny: ["node_modules/**", "dist/**", ".git/**"] }
|
|
186
|
-
network: { mode: inherit }
|
|
187
|
-
output:
|
|
188
|
-
format: json_schema
|
|
189
|
-
schema_path: .pipeline/schemas/implementation.schema.json
|
|
190
|
-
repair: { enabled: true, max_attempts: 1 }
|
|
191
|
-
moka-acceptance-reviewer:
|
|
192
|
-
runner: opencode
|
|
193
|
-
scheduling_roles: [coverage]
|
|
194
|
-
description: Audit the finished change against every acceptance criterion.
|
|
195
|
-
instructions: { inline: 'Audit the completed change against each canonical acceptance criterion independently. Return only valid JSON with top-level "verdict", "evidence", "acceptance", and optional "violations". Each "acceptance" entry must include "id", "verdict", and non-empty "evidence". Do not use Markdown fences or prose outside the JSON object.' }
|
|
196
|
-
skills: [critique, doubt]
|
|
197
|
-
mcp_servers: [pipeline-gateway]
|
|
198
|
-
tools: [read, list, grep, glob, bash]
|
|
199
|
-
filesystem: { mode: read-only, allow: ["**/*"], deny: ["node_modules/**", "dist/**", ".git/**"] }
|
|
200
|
-
network: { mode: inherit }
|
|
201
|
-
output:
|
|
202
|
-
format: json_schema
|
|
203
|
-
schema_path: .pipeline/schemas/acceptance.schema.json
|
|
204
|
-
repair: { enabled: true, max_attempts: 1 }
|
|
205
|
-
moka-thermo-nuclear-reviewer:
|
|
206
|
-
runner: opencode
|
|
207
|
-
scheduling_roles: [coverage]
|
|
208
|
-
description: Perform the final thermo-nuclear code quality review of the integration branch.
|
|
209
|
-
instructions: { inline: "Perform the final code quality review of the integration branch." }
|
|
210
|
-
skills: [critique]
|
|
211
|
-
mcp_servers: [pipeline-gateway]
|
|
212
|
-
tools: [read, list, grep, glob, bash]
|
|
213
|
-
filesystem: { mode: read-only, allow: ["**/*"], deny: ["node_modules/**", "dist/**", ".git/**"] }
|
|
214
|
-
network: { mode: inherit }
|
|
215
|
-
output:
|
|
216
|
-
format: json_schema
|
|
217
|
-
schema_path: .pipeline/schemas/review.schema.json
|
|
218
|
-
repair: { enabled: true, max_attempts: 1 }
|
|
219
|
-
moka-verifier:
|
|
220
|
-
runner: opencode
|
|
221
|
-
scheduling_roles: [coverage]
|
|
222
|
-
description: Verify checks, implementation fit, and final evidence.
|
|
223
|
-
instructions: { inline: 'Verify checks, implementation fit, and final evidence. Return only valid JSON with top-level "verdict", "evidence", and optional "violations". Do not use Markdown fences or prose outside the JSON object.' }
|
|
224
|
-
skills: [verify, critique, secure, optimize]
|
|
225
|
-
mcp_servers: [pipeline-gateway]
|
|
226
|
-
tools: [read, list, grep, glob, bash]
|
|
227
|
-
filesystem: { mode: read-only, allow: ["**/*"], deny: ["node_modules/**", "dist/**", ".git/**"] }
|
|
228
|
-
network: { mode: inherit }
|
|
229
|
-
output:
|
|
230
|
-
format: json_schema
|
|
231
|
-
schema_path: .pipeline/schemas/verify.schema.json
|
|
232
|
-
repair: { enabled: true, max_attempts: 1 }
|
|
233
|
-
moka-learner:
|
|
234
|
-
runner: opencode
|
|
235
|
-
model: openai/gpt-5.5-low
|
|
236
|
-
description: Store durable lessons from the completed run.
|
|
237
|
-
instructions: { inline: "Store durable lessons from the completed run when useful." }
|
|
238
|
-
skills: [migrate]
|
|
239
|
-
mcp_servers: [pipeline-gateway]
|
|
240
|
-
tools: [read, list, grep, glob, bash]
|
|
241
|
-
filesystem: { mode: read-only, allow: ["**/*"], deny: ["node_modules/**", "dist/**", ".git/**"] }
|
|
242
|
-
network: { mode: inherit }
|
|
243
|
-
output:
|
|
244
|
-
format: json_schema
|
|
245
|
-
schema_path: .pipeline/schemas/learn.schema.json
|
|
246
|
-
repair: { enabled: true, max_attempts: 1 }
|
|
247
|
-
`;
|
|
248
|
-
const PACKAGE_DEFAULT_PIPELINE_YAML = `version: 1
|
|
249
|
-
default_workflow: inspect
|
|
250
|
-
orchestrator:
|
|
251
|
-
profile: moka-orchestrator
|
|
252
|
-
entrypoints:
|
|
253
|
-
quick:
|
|
254
|
-
schedule: quick-schedule
|
|
255
|
-
description: Compact planner-generated pipeline for small work
|
|
256
|
-
execute:
|
|
257
|
-
schedule: execute-schedule
|
|
258
|
-
description: Full planner-generated pipeline for repository work
|
|
259
|
-
inspect:
|
|
260
|
-
workflow: inspect
|
|
261
|
-
description: Read-only repository inspection
|
|
262
|
-
hooks:
|
|
263
|
-
functions:
|
|
264
|
-
generated-defaults-audit:
|
|
265
|
-
kind: command
|
|
266
|
-
command: [node, -e, "const fs=require('node:fs'); fs.writeFileSync(process.env.PIPELINE_HOOK_RESULT, JSON.stringify({status:'pass',summary:'Generated defaults audit passed'}));"]
|
|
267
|
-
trusted: true
|
|
268
|
-
timeout_ms: 5000
|
|
269
|
-
output_limit_bytes: 4096
|
|
270
|
-
on:
|
|
271
|
-
workflow.start:
|
|
272
|
-
- id: generated-defaults-audit
|
|
273
|
-
function: generated-defaults-audit
|
|
274
|
-
failure: fail
|
|
275
|
-
runner_command:
|
|
276
|
-
environment:
|
|
277
|
-
setup:
|
|
278
|
-
- command: bun
|
|
279
|
-
args: [install, --frozen-lockfile]
|
|
280
|
-
scheduler:
|
|
281
|
-
commands:
|
|
282
|
-
quick:
|
|
283
|
-
schedule: quick-schedule
|
|
284
|
-
catalog: quick
|
|
285
|
-
execute:
|
|
286
|
-
schedule: execute-schedule
|
|
287
|
-
catalog: execute
|
|
288
|
-
node_catalogs:
|
|
289
|
-
quick:
|
|
290
|
-
required_categories: [intake, red, green, mechanical, verification]
|
|
291
|
-
nodes:
|
|
292
|
-
backlog-intake:
|
|
293
|
-
category: intake
|
|
294
|
-
profile: moka-researcher
|
|
295
|
-
models: [openai/gpt-5.5-medium]
|
|
296
|
-
red-tests:
|
|
297
|
-
category: red
|
|
298
|
-
profile: moka-test-writer
|
|
299
|
-
models: [openai/gpt-5.5-high, kimi-for-coding/kimi-k2-thinking]
|
|
300
|
-
green-implementation:
|
|
301
|
-
category: green
|
|
302
|
-
profile: moka-code-writer
|
|
303
|
-
models: [openai/gpt-5.5-high, kimi-for-coding/k2p6, opencode-go/qwen3.7-max]
|
|
304
|
-
verification:
|
|
305
|
-
category: verification
|
|
306
|
-
profile: moka-verifier
|
|
307
|
-
models: [openai/gpt-5.5-medium]
|
|
308
|
-
execute:
|
|
309
|
-
required_categories: [intake, research, red, green, mechanical, acceptance, verification, learn]
|
|
310
|
-
nodes:
|
|
311
|
-
backlog-intake:
|
|
312
|
-
category: intake
|
|
313
|
-
profile: moka-researcher
|
|
314
|
-
models: [openai/gpt-5.5-medium]
|
|
315
|
-
research:
|
|
316
|
-
category: research
|
|
317
|
-
profile: moka-researcher
|
|
318
|
-
models: [openai/gpt-5.5-medium, kimi-for-coding/k2p6]
|
|
319
|
-
red-tests:
|
|
320
|
-
category: red
|
|
321
|
-
profile: moka-test-writer
|
|
322
|
-
models: [openai/gpt-5.5-high, kimi-for-coding/kimi-k2-thinking]
|
|
323
|
-
green-backend:
|
|
324
|
-
category: green
|
|
325
|
-
profile: moka-code-writer
|
|
326
|
-
models: [openai/gpt-5.5-high, kimi-for-coding/k2p6, opencode-go/qwen3.7-max]
|
|
327
|
-
green-frontend:
|
|
328
|
-
category: green
|
|
329
|
-
profile: moka-code-writer
|
|
330
|
-
models: [openai/gpt-5.5-high, kimi-for-coding/k2p6, opencode-go/qwen3.7-max]
|
|
331
|
-
acceptance-review:
|
|
332
|
-
category: acceptance
|
|
333
|
-
profile: moka-acceptance-reviewer
|
|
334
|
-
models: [openai/gpt-5.5-medium]
|
|
335
|
-
verification:
|
|
336
|
-
category: verification
|
|
337
|
-
profile: moka-verifier
|
|
338
|
-
models: [openai/gpt-5.5-medium]
|
|
339
|
-
learn:
|
|
340
|
-
category: learn
|
|
341
|
-
profile: moka-learner
|
|
342
|
-
models: [openai/gpt-5.5-low]
|
|
343
|
-
schedules:
|
|
344
|
-
quick-schedule:
|
|
345
|
-
baseline: quick
|
|
346
|
-
planner_profile: moka-schedule-planner
|
|
347
|
-
node_catalog: quick
|
|
348
|
-
execute-schedule:
|
|
349
|
-
baseline: execute
|
|
350
|
-
planner_profile: moka-schedule-planner
|
|
351
|
-
node_catalog: execute
|
|
352
|
-
workflows:
|
|
353
|
-
inspect:
|
|
354
|
-
description: Read-only repository inspection workflow.
|
|
355
|
-
nodes:
|
|
356
|
-
- id: inspect
|
|
357
|
-
kind: agent
|
|
358
|
-
profile: moka-inspector
|
|
359
|
-
`;
|
|
10
|
+
const DEFAULT_PACKAGE_DEFAULTS_ROOT = new URL("../../defaults/", import.meta.url);
|
|
11
|
+
function loadDefaultYaml(filename) {
|
|
12
|
+
return readFileSync(new URL(filename, DEFAULT_PACKAGE_DEFAULTS_ROOT), "utf8");
|
|
13
|
+
}
|
|
14
|
+
const PACKAGE_DEFAULT_RUNNERS_YAML = loadDefaultYaml("runners.yaml");
|
|
15
|
+
const PACKAGE_DEFAULT_PROFILES_YAML = loadDefaultYaml("profiles.yaml");
|
|
16
|
+
const PACKAGE_DEFAULT_PIPELINE_YAML = loadDefaultYaml("pipeline.yaml");
|
|
360
17
|
const DEFAULT_OPENCODE_ECOSYSTEM_MANIFEST_URL = new URL(`../../${OPENCODE_ECOSYSTEM_MANIFEST_PATH}`, import.meta.url);
|
|
361
18
|
const ecosystemStringArraySchema = z.array(z.string().min(1));
|
|
362
19
|
const ecosystemRuntimeSchema = z.object({
|
package/dist/config/schemas.d.ts
CHANGED
|
@@ -220,8 +220,8 @@ declare const configSchema: z.ZodObject<{
|
|
|
220
220
|
policy: z.ZodOptional<z.ZodObject<{
|
|
221
221
|
commands: z.ZodOptional<z.ZodEnum<{
|
|
222
222
|
allow: "allow";
|
|
223
|
-
"trusted-only": "trusted-only";
|
|
224
223
|
deny: "deny";
|
|
224
|
+
"trusted-only": "trusted-only";
|
|
225
225
|
}>>;
|
|
226
226
|
modules: z.ZodOptional<z.ZodEnum<{
|
|
227
227
|
allow: "allow";
|
|
@@ -245,8 +245,8 @@ declare const configSchema: z.ZodObject<{
|
|
|
245
245
|
}, z.core.$strict>>>;
|
|
246
246
|
default_profile: z.ZodOptional<z.ZodString>;
|
|
247
247
|
mode: z.ZodEnum<{
|
|
248
|
-
hosted: "hosted";
|
|
249
248
|
local: "local";
|
|
249
|
+
hosted: "hosted";
|
|
250
250
|
}>;
|
|
251
251
|
provider: z.ZodLiteral<"toolhive">;
|
|
252
252
|
authorization_env: z.ZodDefault<z.ZodString>;
|
|
@@ -289,10 +289,10 @@ declare const configSchema: z.ZodObject<{
|
|
|
289
289
|
}, z.core.$strict>>;
|
|
290
290
|
output: z.ZodOptional<z.ZodObject<{
|
|
291
291
|
format: z.ZodEnum<{
|
|
292
|
+
json_schema: "json_schema";
|
|
292
293
|
text: "text";
|
|
293
294
|
json: "json";
|
|
294
295
|
jsonl: "jsonl";
|
|
295
|
-
json_schema: "json_schema";
|
|
296
296
|
}>;
|
|
297
297
|
repair: z.ZodOptional<z.ZodObject<{
|
|
298
298
|
enabled: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -310,6 +310,7 @@ declare const configSchema: z.ZodObject<{
|
|
|
310
310
|
skills: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
311
311
|
timeout_ms: z.ZodOptional<z.ZodNumber>;
|
|
312
312
|
tools: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
313
|
+
task: "task";
|
|
313
314
|
read: "read";
|
|
314
315
|
list: "list";
|
|
315
316
|
grep: "grep";
|
|
@@ -317,7 +318,6 @@ declare const configSchema: z.ZodObject<{
|
|
|
317
318
|
bash: "bash";
|
|
318
319
|
edit: "edit";
|
|
319
320
|
write: "write";
|
|
320
|
-
task: "task";
|
|
321
321
|
}>>>;
|
|
322
322
|
}, z.core.$strict>>>;
|
|
323
323
|
runner_command: z.ZodDefault<z.ZodObject<{
|
|
@@ -343,8 +343,8 @@ declare const configSchema: z.ZodObject<{
|
|
|
343
343
|
rules: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
344
344
|
path: z.ZodString;
|
|
345
345
|
source_root: z.ZodDefault<z.ZodEnum<{
|
|
346
|
-
package: "package";
|
|
347
346
|
project: "project";
|
|
347
|
+
package: "package";
|
|
348
348
|
}>>;
|
|
349
349
|
}, z.core.$strict>>>;
|
|
350
350
|
runners: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
@@ -361,14 +361,15 @@ declare const configSchema: z.ZodObject<{
|
|
|
361
361
|
disabled: "disabled";
|
|
362
362
|
}>>>;
|
|
363
363
|
output_formats: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
364
|
+
json_schema: "json_schema";
|
|
364
365
|
text: "text";
|
|
365
366
|
json: "json";
|
|
366
367
|
jsonl: "jsonl";
|
|
367
|
-
json_schema: "json_schema";
|
|
368
368
|
}>>>;
|
|
369
369
|
rules: z.ZodOptional<z.ZodBoolean>;
|
|
370
370
|
skills: z.ZodOptional<z.ZodBoolean>;
|
|
371
371
|
tools: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
372
|
+
task: "task";
|
|
372
373
|
read: "read";
|
|
373
374
|
list: "list";
|
|
374
375
|
grep: "grep";
|
|
@@ -376,7 +377,6 @@ declare const configSchema: z.ZodObject<{
|
|
|
376
377
|
bash: "bash";
|
|
377
378
|
edit: "edit";
|
|
378
379
|
write: "write";
|
|
379
|
-
task: "task";
|
|
380
380
|
}>>>;
|
|
381
381
|
}, z.core.$strict>;
|
|
382
382
|
command: z.ZodOptional<z.ZodString>;
|
|
@@ -471,8 +471,8 @@ declare const configSchema: z.ZodObject<{
|
|
|
471
471
|
schedules: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
472
472
|
description: z.ZodOptional<z.ZodString>;
|
|
473
473
|
baseline: z.ZodEnum<{
|
|
474
|
-
execute: "execute";
|
|
475
474
|
quick: "quick";
|
|
475
|
+
execute: "execute";
|
|
476
476
|
}>;
|
|
477
477
|
max_parallel_nodes: z.ZodOptional<z.ZodNumber>;
|
|
478
478
|
node_catalog: z.ZodOptional<z.ZodString>;
|
|
@@ -484,8 +484,8 @@ declare const configSchema: z.ZodObject<{
|
|
|
484
484
|
skills: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
485
485
|
path: z.ZodString;
|
|
486
486
|
source_root: z.ZodDefault<z.ZodEnum<{
|
|
487
|
-
package: "package";
|
|
488
487
|
project: "project";
|
|
488
|
+
package: "package";
|
|
489
489
|
}>>;
|
|
490
490
|
}, z.core.$strict>>>;
|
|
491
491
|
task_context: z.ZodOptional<z.ZodObject<{
|