@oisincoveney/pipeline 2.0.0 → 2.0.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/dist/argo-workflow.js +0 -19
- package/dist/cli/program.d.ts +1 -0
- package/dist/cli/program.js +7 -4
- package/dist/cluster-doctor.js +69 -48
- package/dist/config/schemas.d.ts +2 -2
- package/dist/install-commands/opencode.js +422 -0
- package/dist/install-commands/shared.js +23 -0
- package/dist/install-commands.js +7 -440
- package/dist/schedule/backlog-context.js +114 -0
- package/dist/schedule/baseline.js +267 -0
- package/dist/schedule/planner.js +3 -373
- package/package.json +1 -1
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
//#region src/schedule/baseline.ts
|
|
2
|
+
const SCHEDULE_KIND = "pipeline-schedule";
|
|
3
|
+
function baselineScheduleArtifact(input) {
|
|
4
|
+
const scheduleId = input.runId ?? defaultScheduleId(input.generatedAt);
|
|
5
|
+
const baseline = baselineWorkflows(input.baseline, input.config);
|
|
6
|
+
return {
|
|
7
|
+
generated_at: input.generatedAt.toISOString(),
|
|
8
|
+
kind: SCHEDULE_KIND,
|
|
9
|
+
root_workflow: baseline.rootWorkflow,
|
|
10
|
+
schedule_id: scheduleId,
|
|
11
|
+
source_entrypoint: input.entrypointId,
|
|
12
|
+
task: input.task,
|
|
13
|
+
version: 1,
|
|
14
|
+
workflows: baseline.workflows
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
function baselineWorkflows(baseline, _config) {
|
|
18
|
+
if (baseline === "quick") return {
|
|
19
|
+
rootWorkflow: "root",
|
|
20
|
+
workflows: quickBaselineWorkflow()
|
|
21
|
+
};
|
|
22
|
+
return {
|
|
23
|
+
rootWorkflow: "root",
|
|
24
|
+
workflows: executeBaselineWorkflow()
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
function quickBaselineWorkflow() {
|
|
28
|
+
return { root: {
|
|
29
|
+
description: "Compact generated quick schedule seed.",
|
|
30
|
+
nodes: [
|
|
31
|
+
{
|
|
32
|
+
id: "backlog-intake",
|
|
33
|
+
kind: "agent",
|
|
34
|
+
profile: "moka-researcher"
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
id: "red-tests",
|
|
38
|
+
kind: "agent",
|
|
39
|
+
needs: ["backlog-intake"],
|
|
40
|
+
profile: "moka-test-writer"
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
id: "implement",
|
|
44
|
+
kind: "agent",
|
|
45
|
+
needs: ["red-tests"],
|
|
46
|
+
profile: "moka-code-writer"
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
builtin: "test",
|
|
50
|
+
id: "mechanical-tests",
|
|
51
|
+
kind: "builtin",
|
|
52
|
+
needs: ["implement"]
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
builtin: "typecheck",
|
|
56
|
+
id: "mechanical-typecheck",
|
|
57
|
+
kind: "builtin",
|
|
58
|
+
needs: ["implement"]
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
gates: [
|
|
62
|
+
{
|
|
63
|
+
builtin: "typecheck",
|
|
64
|
+
id: "verify-typecheck",
|
|
65
|
+
kind: "builtin"
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
builtin: "test",
|
|
69
|
+
id: "verify-tests",
|
|
70
|
+
kind: "builtin"
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
builtin: "lint",
|
|
74
|
+
id: "verify-lint",
|
|
75
|
+
kind: "builtin"
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
builtin: "fallow",
|
|
79
|
+
id: "verify-fallow",
|
|
80
|
+
kind: "builtin"
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
kind: "verdict",
|
|
84
|
+
id: "verify-verdict",
|
|
85
|
+
target: "stdout"
|
|
86
|
+
}
|
|
87
|
+
],
|
|
88
|
+
id: "verify",
|
|
89
|
+
kind: "agent",
|
|
90
|
+
needs: ["mechanical-tests", "mechanical-typecheck"],
|
|
91
|
+
profile: "moka-verifier"
|
|
92
|
+
}
|
|
93
|
+
]
|
|
94
|
+
} };
|
|
95
|
+
}
|
|
96
|
+
function executeBaselineWorkflow() {
|
|
97
|
+
return { root: {
|
|
98
|
+
description: "Full generated execute schedule seed.",
|
|
99
|
+
nodes: [
|
|
100
|
+
{
|
|
101
|
+
id: "backlog-intake",
|
|
102
|
+
kind: "agent",
|
|
103
|
+
profile: "moka-researcher"
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
id: "research",
|
|
107
|
+
kind: "agent",
|
|
108
|
+
needs: ["backlog-intake"],
|
|
109
|
+
profile: "moka-researcher"
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
gates: [{
|
|
113
|
+
changed_files: {
|
|
114
|
+
allow: [
|
|
115
|
+
"**/*.test.*",
|
|
116
|
+
"**/*.spec.*",
|
|
117
|
+
"**/*_test.*",
|
|
118
|
+
"**/__tests__/**",
|
|
119
|
+
"test/**",
|
|
120
|
+
"tests/**",
|
|
121
|
+
"**/*.snap"
|
|
122
|
+
],
|
|
123
|
+
require_any: [
|
|
124
|
+
"**/*.test.*",
|
|
125
|
+
"**/*.spec.*",
|
|
126
|
+
"**/*_test.*",
|
|
127
|
+
"**/__tests__/**",
|
|
128
|
+
"test/**",
|
|
129
|
+
"tests/**"
|
|
130
|
+
]
|
|
131
|
+
},
|
|
132
|
+
id: "red-test-file-policy",
|
|
133
|
+
kind: "changed_files"
|
|
134
|
+
}],
|
|
135
|
+
id: "red-tests",
|
|
136
|
+
kind: "agent",
|
|
137
|
+
needs: ["research"],
|
|
138
|
+
profile: "moka-test-writer"
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
id: "green-implementation",
|
|
142
|
+
kind: "agent",
|
|
143
|
+
needs: ["red-tests"],
|
|
144
|
+
profile: "moka-code-writer"
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
builtin: "test",
|
|
148
|
+
id: "mechanical-green-tests",
|
|
149
|
+
kind: "builtin",
|
|
150
|
+
needs: ["green-implementation"]
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
builtin: "typecheck",
|
|
154
|
+
id: "mechanical-green-typecheck",
|
|
155
|
+
kind: "builtin",
|
|
156
|
+
needs: ["green-implementation"]
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
builtin: "lint",
|
|
160
|
+
id: "mechanical-green-lint",
|
|
161
|
+
kind: "builtin",
|
|
162
|
+
needs: ["green-implementation"]
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
builtin: "fallow",
|
|
166
|
+
id: "mechanical-green-fallow",
|
|
167
|
+
kind: "builtin",
|
|
168
|
+
needs: ["green-implementation"]
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
gates: [{
|
|
172
|
+
id: "acceptance-coverage",
|
|
173
|
+
kind: "acceptance",
|
|
174
|
+
required: false,
|
|
175
|
+
target: "stdout"
|
|
176
|
+
}, {
|
|
177
|
+
id: "acceptance-verdict",
|
|
178
|
+
kind: "verdict",
|
|
179
|
+
target: "stdout"
|
|
180
|
+
}],
|
|
181
|
+
id: "acceptance-review",
|
|
182
|
+
kind: "agent",
|
|
183
|
+
needs: [
|
|
184
|
+
"mechanical-green-tests",
|
|
185
|
+
"mechanical-green-typecheck",
|
|
186
|
+
"mechanical-green-lint",
|
|
187
|
+
"mechanical-green-fallow"
|
|
188
|
+
],
|
|
189
|
+
profile: "moka-acceptance-reviewer"
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
gates: [
|
|
193
|
+
{
|
|
194
|
+
builtin: "typecheck",
|
|
195
|
+
id: "verify-typecheck",
|
|
196
|
+
kind: "builtin"
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
builtin: "test",
|
|
200
|
+
id: "verify-tests",
|
|
201
|
+
kind: "builtin"
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
builtin: "lint",
|
|
205
|
+
id: "verify-lint",
|
|
206
|
+
kind: "builtin"
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
builtin: "fallow",
|
|
210
|
+
id: "verify-fallow",
|
|
211
|
+
kind: "builtin"
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
builtin: "semgrep",
|
|
215
|
+
id: "verify-semgrep",
|
|
216
|
+
kind: "builtin"
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
builtin: "duplication",
|
|
220
|
+
id: "verify-duplication",
|
|
221
|
+
kind: "builtin"
|
|
222
|
+
},
|
|
223
|
+
{
|
|
224
|
+
id: "verify-verdict",
|
|
225
|
+
kind: "verdict",
|
|
226
|
+
target: "stdout"
|
|
227
|
+
}
|
|
228
|
+
],
|
|
229
|
+
id: "verification",
|
|
230
|
+
kind: "agent",
|
|
231
|
+
needs: [
|
|
232
|
+
"mechanical-green-tests",
|
|
233
|
+
"mechanical-green-typecheck",
|
|
234
|
+
"mechanical-green-lint",
|
|
235
|
+
"mechanical-green-fallow"
|
|
236
|
+
],
|
|
237
|
+
profile: "moka-verifier"
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
id: "code-quality-review",
|
|
241
|
+
kind: "agent",
|
|
242
|
+
needs: [
|
|
243
|
+
"mechanical-green-tests",
|
|
244
|
+
"mechanical-green-typecheck",
|
|
245
|
+
"mechanical-green-lint",
|
|
246
|
+
"mechanical-green-fallow"
|
|
247
|
+
],
|
|
248
|
+
profile: "moka-thermo-nuclear-reviewer"
|
|
249
|
+
},
|
|
250
|
+
{
|
|
251
|
+
id: "learn",
|
|
252
|
+
kind: "agent",
|
|
253
|
+
needs: [
|
|
254
|
+
"acceptance-review",
|
|
255
|
+
"verification",
|
|
256
|
+
"code-quality-review"
|
|
257
|
+
],
|
|
258
|
+
profile: "moka-learner"
|
|
259
|
+
}
|
|
260
|
+
]
|
|
261
|
+
} };
|
|
262
|
+
}
|
|
263
|
+
function defaultScheduleId(date) {
|
|
264
|
+
return `run-${date.toISOString().replaceAll(/[-:.TZ]/g, "").slice(0, 14)}`;
|
|
265
|
+
}
|
|
266
|
+
//#endregion
|
|
267
|
+
export { baselineScheduleArtifact };
|
package/dist/schedule/planner.js
CHANGED
|
@@ -3,8 +3,9 @@ import { validatePipelineConfig } from "../config/validate.js";
|
|
|
3
3
|
import "../config.js";
|
|
4
4
|
import { createRunnerLaunchPlan, runLaunchPlan } from "../runner.js";
|
|
5
5
|
import { normalizeRunnerOutput } from "../runner-output.js";
|
|
6
|
-
import { extractTicketIds } from "../task-ref.js";
|
|
7
6
|
import { compileWorkflowPlan } from "../workflow-planner.js";
|
|
7
|
+
import { loadBacklogPlanningContext } from "./backlog-context.js";
|
|
8
|
+
import { baselineScheduleArtifact } from "./baseline.js";
|
|
8
9
|
import { addGeneratedImplementationCoverage } from "./passes/coverage.js";
|
|
9
10
|
import { canonicalizeGeneratedScheduleIds } from "./passes/ids.js";
|
|
10
11
|
import { SCHEDULE_PASS_ORDER } from "./passes/index.js";
|
|
@@ -13,18 +14,12 @@ import { namespaceScheduleWorkflows } from "./passes/references.js";
|
|
|
13
14
|
import { plannerPrompt, plannerRepairPrompt } from "./prompts.js";
|
|
14
15
|
import { parseDocument, stringify } from "yaml";
|
|
15
16
|
import { z } from "zod";
|
|
16
|
-
import {
|
|
17
|
+
import { mkdirSync, writeFileSync } from "node:fs";
|
|
17
18
|
import { join } from "node:path";
|
|
18
|
-
import { Graph, alg } from "@dagrejs/graphlib";
|
|
19
|
-
import matter from "gray-matter";
|
|
20
19
|
//#region src/schedule/planner.ts
|
|
21
20
|
const SCHEDULE_KIND = "pipeline-schedule";
|
|
22
21
|
const ID_RE = /^[a-z][a-z0-9-]*$/;
|
|
23
22
|
const SCHEDULE_ID_RE = /^[A-Za-z0-9][A-Za-z0-9_.-]*$/;
|
|
24
|
-
const DESCRIPTION_SECTION_RE = /## Description\s+([\s\S]*?)(?=\n## |\s*$)/;
|
|
25
|
-
const ACCEPTANCE_SECTION_RE = /## Acceptance Criteria\s+([\s\S]*?)(?=\n## |\s*$)/;
|
|
26
|
-
const ACCEPTANCE_ITEM_RE = /^\s*-\s*\[[ xX]\]\s*#?([\w.-]+)\s+(.+)$/;
|
|
27
|
-
const LINE_RE = /\r?\n/;
|
|
28
23
|
const MARKDOWN_YAML_FENCE_RE = /```(?:ya?ml)?\s*\r?\n([\s\S]*?)\r?\n```/i;
|
|
29
24
|
const SCHEDULE_PLANNER_REPAIR_ATTEMPTS = 1;
|
|
30
25
|
const SCHEDULE_BUILTINS = [
|
|
@@ -120,266 +115,6 @@ function persistScheduleArtifact(worktreePath, artifact) {
|
|
|
120
115
|
function scheduleArtifactPath(worktreePath, scheduleId) {
|
|
121
116
|
return join(worktreePath, ".pipeline", "runs", scheduleId, "schedule.yaml");
|
|
122
117
|
}
|
|
123
|
-
function baselineScheduleArtifact(input) {
|
|
124
|
-
const scheduleId = input.runId ?? defaultScheduleId(input.generatedAt);
|
|
125
|
-
const baseline = baselineWorkflows(input.baseline, input.config);
|
|
126
|
-
return {
|
|
127
|
-
generated_at: input.generatedAt.toISOString(),
|
|
128
|
-
kind: SCHEDULE_KIND,
|
|
129
|
-
root_workflow: baseline.rootWorkflow,
|
|
130
|
-
schedule_id: scheduleId,
|
|
131
|
-
source_entrypoint: input.entrypointId,
|
|
132
|
-
task: input.task,
|
|
133
|
-
version: 1,
|
|
134
|
-
workflows: baseline.workflows
|
|
135
|
-
};
|
|
136
|
-
}
|
|
137
|
-
function baselineWorkflows(baseline, _config) {
|
|
138
|
-
if (baseline === "quick") return {
|
|
139
|
-
rootWorkflow: "root",
|
|
140
|
-
workflows: quickBaselineWorkflow()
|
|
141
|
-
};
|
|
142
|
-
return {
|
|
143
|
-
rootWorkflow: "root",
|
|
144
|
-
workflows: executeBaselineWorkflow()
|
|
145
|
-
};
|
|
146
|
-
}
|
|
147
|
-
function quickBaselineWorkflow() {
|
|
148
|
-
return { root: {
|
|
149
|
-
description: "Compact generated quick schedule seed.",
|
|
150
|
-
nodes: [
|
|
151
|
-
{
|
|
152
|
-
id: "backlog-intake",
|
|
153
|
-
kind: "agent",
|
|
154
|
-
profile: "moka-researcher"
|
|
155
|
-
},
|
|
156
|
-
{
|
|
157
|
-
id: "red-tests",
|
|
158
|
-
kind: "agent",
|
|
159
|
-
needs: ["backlog-intake"],
|
|
160
|
-
profile: "moka-test-writer"
|
|
161
|
-
},
|
|
162
|
-
{
|
|
163
|
-
id: "implement",
|
|
164
|
-
kind: "agent",
|
|
165
|
-
needs: ["red-tests"],
|
|
166
|
-
profile: "moka-code-writer"
|
|
167
|
-
},
|
|
168
|
-
{
|
|
169
|
-
builtin: "test",
|
|
170
|
-
id: "mechanical-tests",
|
|
171
|
-
kind: "builtin",
|
|
172
|
-
needs: ["implement"]
|
|
173
|
-
},
|
|
174
|
-
{
|
|
175
|
-
builtin: "typecheck",
|
|
176
|
-
id: "mechanical-typecheck",
|
|
177
|
-
kind: "builtin",
|
|
178
|
-
needs: ["implement"]
|
|
179
|
-
},
|
|
180
|
-
{
|
|
181
|
-
gates: [
|
|
182
|
-
{
|
|
183
|
-
builtin: "typecheck",
|
|
184
|
-
id: "verify-typecheck",
|
|
185
|
-
kind: "builtin"
|
|
186
|
-
},
|
|
187
|
-
{
|
|
188
|
-
builtin: "test",
|
|
189
|
-
id: "verify-tests",
|
|
190
|
-
kind: "builtin"
|
|
191
|
-
},
|
|
192
|
-
{
|
|
193
|
-
builtin: "lint",
|
|
194
|
-
id: "verify-lint",
|
|
195
|
-
kind: "builtin"
|
|
196
|
-
},
|
|
197
|
-
{
|
|
198
|
-
builtin: "fallow",
|
|
199
|
-
id: "verify-fallow",
|
|
200
|
-
kind: "builtin"
|
|
201
|
-
},
|
|
202
|
-
{
|
|
203
|
-
kind: "verdict",
|
|
204
|
-
id: "verify-verdict",
|
|
205
|
-
target: "stdout"
|
|
206
|
-
}
|
|
207
|
-
],
|
|
208
|
-
id: "verify",
|
|
209
|
-
kind: "agent",
|
|
210
|
-
needs: ["mechanical-tests", "mechanical-typecheck"],
|
|
211
|
-
profile: "moka-verifier"
|
|
212
|
-
}
|
|
213
|
-
]
|
|
214
|
-
} };
|
|
215
|
-
}
|
|
216
|
-
function executeBaselineWorkflow() {
|
|
217
|
-
return { root: {
|
|
218
|
-
description: "Full generated execute schedule seed.",
|
|
219
|
-
nodes: [
|
|
220
|
-
{
|
|
221
|
-
id: "backlog-intake",
|
|
222
|
-
kind: "agent",
|
|
223
|
-
profile: "moka-researcher"
|
|
224
|
-
},
|
|
225
|
-
{
|
|
226
|
-
id: "research",
|
|
227
|
-
kind: "agent",
|
|
228
|
-
needs: ["backlog-intake"],
|
|
229
|
-
profile: "moka-researcher"
|
|
230
|
-
},
|
|
231
|
-
{
|
|
232
|
-
gates: [{
|
|
233
|
-
changed_files: {
|
|
234
|
-
allow: [
|
|
235
|
-
"**/*.test.*",
|
|
236
|
-
"**/*.spec.*",
|
|
237
|
-
"**/*_test.*",
|
|
238
|
-
"**/__tests__/**",
|
|
239
|
-
"test/**",
|
|
240
|
-
"tests/**",
|
|
241
|
-
"**/*.snap"
|
|
242
|
-
],
|
|
243
|
-
require_any: [
|
|
244
|
-
"**/*.test.*",
|
|
245
|
-
"**/*.spec.*",
|
|
246
|
-
"**/*_test.*",
|
|
247
|
-
"**/__tests__/**",
|
|
248
|
-
"test/**",
|
|
249
|
-
"tests/**"
|
|
250
|
-
]
|
|
251
|
-
},
|
|
252
|
-
id: "red-test-file-policy",
|
|
253
|
-
kind: "changed_files"
|
|
254
|
-
}],
|
|
255
|
-
id: "red-tests",
|
|
256
|
-
kind: "agent",
|
|
257
|
-
needs: ["research"],
|
|
258
|
-
profile: "moka-test-writer"
|
|
259
|
-
},
|
|
260
|
-
{
|
|
261
|
-
id: "green-implementation",
|
|
262
|
-
kind: "agent",
|
|
263
|
-
needs: ["red-tests"],
|
|
264
|
-
profile: "moka-code-writer"
|
|
265
|
-
},
|
|
266
|
-
{
|
|
267
|
-
builtin: "test",
|
|
268
|
-
id: "mechanical-green-tests",
|
|
269
|
-
kind: "builtin",
|
|
270
|
-
needs: ["green-implementation"]
|
|
271
|
-
},
|
|
272
|
-
{
|
|
273
|
-
builtin: "typecheck",
|
|
274
|
-
id: "mechanical-green-typecheck",
|
|
275
|
-
kind: "builtin",
|
|
276
|
-
needs: ["green-implementation"]
|
|
277
|
-
},
|
|
278
|
-
{
|
|
279
|
-
builtin: "lint",
|
|
280
|
-
id: "mechanical-green-lint",
|
|
281
|
-
kind: "builtin",
|
|
282
|
-
needs: ["green-implementation"]
|
|
283
|
-
},
|
|
284
|
-
{
|
|
285
|
-
builtin: "fallow",
|
|
286
|
-
id: "mechanical-green-fallow",
|
|
287
|
-
kind: "builtin",
|
|
288
|
-
needs: ["green-implementation"]
|
|
289
|
-
},
|
|
290
|
-
{
|
|
291
|
-
gates: [{
|
|
292
|
-
id: "acceptance-coverage",
|
|
293
|
-
kind: "acceptance",
|
|
294
|
-
required: false,
|
|
295
|
-
target: "stdout"
|
|
296
|
-
}, {
|
|
297
|
-
id: "acceptance-verdict",
|
|
298
|
-
kind: "verdict",
|
|
299
|
-
target: "stdout"
|
|
300
|
-
}],
|
|
301
|
-
id: "acceptance-review",
|
|
302
|
-
kind: "agent",
|
|
303
|
-
needs: [
|
|
304
|
-
"mechanical-green-tests",
|
|
305
|
-
"mechanical-green-typecheck",
|
|
306
|
-
"mechanical-green-lint",
|
|
307
|
-
"mechanical-green-fallow"
|
|
308
|
-
],
|
|
309
|
-
profile: "moka-acceptance-reviewer"
|
|
310
|
-
},
|
|
311
|
-
{
|
|
312
|
-
gates: [
|
|
313
|
-
{
|
|
314
|
-
builtin: "typecheck",
|
|
315
|
-
id: "verify-typecheck",
|
|
316
|
-
kind: "builtin"
|
|
317
|
-
},
|
|
318
|
-
{
|
|
319
|
-
builtin: "test",
|
|
320
|
-
id: "verify-tests",
|
|
321
|
-
kind: "builtin"
|
|
322
|
-
},
|
|
323
|
-
{
|
|
324
|
-
builtin: "lint",
|
|
325
|
-
id: "verify-lint",
|
|
326
|
-
kind: "builtin"
|
|
327
|
-
},
|
|
328
|
-
{
|
|
329
|
-
builtin: "fallow",
|
|
330
|
-
id: "verify-fallow",
|
|
331
|
-
kind: "builtin"
|
|
332
|
-
},
|
|
333
|
-
{
|
|
334
|
-
builtin: "semgrep",
|
|
335
|
-
id: "verify-semgrep",
|
|
336
|
-
kind: "builtin"
|
|
337
|
-
},
|
|
338
|
-
{
|
|
339
|
-
builtin: "duplication",
|
|
340
|
-
id: "verify-duplication",
|
|
341
|
-
kind: "builtin"
|
|
342
|
-
},
|
|
343
|
-
{
|
|
344
|
-
id: "verify-verdict",
|
|
345
|
-
kind: "verdict",
|
|
346
|
-
target: "stdout"
|
|
347
|
-
}
|
|
348
|
-
],
|
|
349
|
-
id: "verification",
|
|
350
|
-
kind: "agent",
|
|
351
|
-
needs: [
|
|
352
|
-
"mechanical-green-tests",
|
|
353
|
-
"mechanical-green-typecheck",
|
|
354
|
-
"mechanical-green-lint",
|
|
355
|
-
"mechanical-green-fallow"
|
|
356
|
-
],
|
|
357
|
-
profile: "moka-verifier"
|
|
358
|
-
},
|
|
359
|
-
{
|
|
360
|
-
id: "code-quality-review",
|
|
361
|
-
kind: "agent",
|
|
362
|
-
needs: [
|
|
363
|
-
"mechanical-green-tests",
|
|
364
|
-
"mechanical-green-typecheck",
|
|
365
|
-
"mechanical-green-lint",
|
|
366
|
-
"mechanical-green-fallow"
|
|
367
|
-
],
|
|
368
|
-
profile: "moka-thermo-nuclear-reviewer"
|
|
369
|
-
},
|
|
370
|
-
{
|
|
371
|
-
id: "learn",
|
|
372
|
-
kind: "agent",
|
|
373
|
-
needs: [
|
|
374
|
-
"acceptance-review",
|
|
375
|
-
"verification",
|
|
376
|
-
"code-quality-review"
|
|
377
|
-
],
|
|
378
|
-
profile: "moka-learner"
|
|
379
|
-
}
|
|
380
|
-
]
|
|
381
|
-
} };
|
|
382
|
-
}
|
|
383
118
|
async function planScheduleArtifact(baseline, plannerProfile, options, planningContext) {
|
|
384
119
|
const requiredPlannerProfile = requireSchedulePlannerProfile(plannerProfile, options.entrypointId);
|
|
385
120
|
const source = requireSchedulePlannerSource(await runSchedulePlanner(requiredPlannerProfile, plannerPrompt(options.entrypointId, options.task, baseline, options.config, planningContext), options));
|
|
@@ -662,110 +397,5 @@ function allWorkflowNodes(workflows) {
|
|
|
662
397
|
function flattenWorkflowNode(node) {
|
|
663
398
|
return node.kind === "parallel" ? [node, ...node.nodes.flatMap(flattenWorkflowNode)] : [node];
|
|
664
399
|
}
|
|
665
|
-
function loadBacklogPlanningContext(task, worktreePath) {
|
|
666
|
-
const ticketIds = extractTicketIds(task);
|
|
667
|
-
if (ticketIds.length === 0) return {
|
|
668
|
-
parentWorkUnits: [],
|
|
669
|
-
workUnits: []
|
|
670
|
-
};
|
|
671
|
-
const tasks = readBacklogTasks(worktreePath);
|
|
672
|
-
const tasksById = new Map(tasks.map((taskFile) => [taskFile.id, taskFile]));
|
|
673
|
-
const taskGraph = backlogTaskGraph(tasks);
|
|
674
|
-
const parentWorkUnits = [];
|
|
675
|
-
const workUnits = [];
|
|
676
|
-
const parentIds = /* @__PURE__ */ new Set();
|
|
677
|
-
const workUnitIds = /* @__PURE__ */ new Set();
|
|
678
|
-
for (const ticketId of ticketIds) {
|
|
679
|
-
const taskFile = tasksById.get(ticketId);
|
|
680
|
-
if (!taskFile) continue;
|
|
681
|
-
const descendants = descendantBacklogTasks(ticketId, taskGraph);
|
|
682
|
-
if (descendants.length === 0) {
|
|
683
|
-
addUniqueWorkUnit(taskFile.workUnit, workUnits, workUnitIds);
|
|
684
|
-
continue;
|
|
685
|
-
}
|
|
686
|
-
addUniqueWorkUnit(taskFile.workUnit, parentWorkUnits, parentIds);
|
|
687
|
-
for (const descendant of descendants) addUniqueWorkUnit(descendant.workUnit, workUnits, workUnitIds);
|
|
688
|
-
}
|
|
689
|
-
return {
|
|
690
|
-
parentWorkUnits,
|
|
691
|
-
workUnits
|
|
692
|
-
};
|
|
693
|
-
}
|
|
694
|
-
function backlogTaskGraph(tasks) {
|
|
695
|
-
const graph = new Graph();
|
|
696
|
-
const sortedTasks = [...tasks].sort(compareBacklogTaskIds);
|
|
697
|
-
for (const task of sortedTasks) graph.setNode(task.id, task);
|
|
698
|
-
for (const task of sortedTasks) if (task.parentTaskId && graph.hasNode(task.parentTaskId)) graph.setEdge(task.parentTaskId, task.id);
|
|
699
|
-
return graph;
|
|
700
|
-
}
|
|
701
|
-
function descendantBacklogTasks(taskId, taskGraph) {
|
|
702
|
-
if (!taskGraph.hasNode(taskId)) return [];
|
|
703
|
-
return alg.preorder(taskGraph, taskId).slice(1).map((id) => taskGraph.node(id)).filter((task) => Boolean(task));
|
|
704
|
-
}
|
|
705
|
-
function compareBacklogTaskIds(a, b) {
|
|
706
|
-
return a.id.localeCompare(b.id, void 0, { numeric: true });
|
|
707
|
-
}
|
|
708
|
-
function addUniqueWorkUnit(workUnit, target, seen) {
|
|
709
|
-
if (seen.has(workUnit.id)) return;
|
|
710
|
-
seen.add(workUnit.id);
|
|
711
|
-
target.push(workUnit);
|
|
712
|
-
}
|
|
713
|
-
function readBacklogTasks(worktreePath) {
|
|
714
|
-
const tasksDir = join(worktreePath, "backlog", "tasks");
|
|
715
|
-
if (!existsSync(tasksDir)) return [];
|
|
716
|
-
return readdirSync(tasksDir, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".md")).flatMap((entry) => readBacklogTaskFile(join(tasksDir, entry.name)));
|
|
717
|
-
}
|
|
718
|
-
function readBacklogTaskFile(path) {
|
|
719
|
-
const parsed = matter(readFileSync(path, "utf8"));
|
|
720
|
-
const id = stringFrontmatter(parsed.data.id);
|
|
721
|
-
if (!id) return [];
|
|
722
|
-
return [{
|
|
723
|
-
id,
|
|
724
|
-
parentTaskId: stringFrontmatter(parsed.data.parent_task_id),
|
|
725
|
-
workUnit: {
|
|
726
|
-
acceptance_criteria: acceptanceCriteriaFromMarkdown(parsed.content),
|
|
727
|
-
...optionalStringArrayField("dependencies", stringArrayFrontmatter(parsed.data.dependencies)),
|
|
728
|
-
...optionalStringField("description", descriptionFromMarkdown(parsed.content)),
|
|
729
|
-
id,
|
|
730
|
-
...optionalStringField("title", stringFrontmatter(parsed.data.title))
|
|
731
|
-
}
|
|
732
|
-
}];
|
|
733
|
-
}
|
|
734
|
-
function stringFrontmatter(value) {
|
|
735
|
-
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
736
|
-
}
|
|
737
|
-
function stringArrayFrontmatter(value) {
|
|
738
|
-
if (!Array.isArray(value)) return [];
|
|
739
|
-
return value.filter((item) => typeof item === "string").map((item) => item.trim()).filter(Boolean);
|
|
740
|
-
}
|
|
741
|
-
function optionalStringField(key, value) {
|
|
742
|
-
return value ? { [key]: value } : {};
|
|
743
|
-
}
|
|
744
|
-
function optionalStringArrayField(key, value) {
|
|
745
|
-
return value.length > 0 ? { [key]: value } : {};
|
|
746
|
-
}
|
|
747
|
-
function descriptionFromMarkdown(content) {
|
|
748
|
-
const marked = betweenMarkers(content, "<!-- SECTION:DESCRIPTION:BEGIN -->", "<!-- SECTION:DESCRIPTION:END -->");
|
|
749
|
-
if (marked) return marked;
|
|
750
|
-
return cleanupMarkdownSection(content.match(DESCRIPTION_SECTION_RE)?.[1]);
|
|
751
|
-
}
|
|
752
|
-
function acceptanceCriteriaFromMarkdown(content) {
|
|
753
|
-
return (betweenMarkers(content, "<!-- AC:BEGIN -->", "<!-- AC:END -->") ?? content.match(ACCEPTANCE_SECTION_RE)?.[1] ?? "").split(LINE_RE).map((line) => line.match(ACCEPTANCE_ITEM_RE)).filter((match) => Boolean(match)).map((match) => ({
|
|
754
|
-
id: match[1] ?? "",
|
|
755
|
-
text: (match[2] ?? "").trim()
|
|
756
|
-
})).filter((criterion) => criterion.id && criterion.text);
|
|
757
|
-
}
|
|
758
|
-
function betweenMarkers(content, start, end) {
|
|
759
|
-
const startIndex = content.indexOf(start);
|
|
760
|
-
const endIndex = content.indexOf(end);
|
|
761
|
-
if (startIndex === -1 || endIndex === -1 || endIndex <= startIndex) return;
|
|
762
|
-
return cleanupMarkdownSection(content.slice(startIndex + start.length, endIndex));
|
|
763
|
-
}
|
|
764
|
-
function cleanupMarkdownSection(value) {
|
|
765
|
-
return value?.split(LINE_RE).map((line) => line.trim()).filter(Boolean).join("\n") || void 0;
|
|
766
|
-
}
|
|
767
|
-
function defaultScheduleId(date) {
|
|
768
|
-
return `run-${date.toISOString().replaceAll(/[-:.TZ]/g, "").slice(0, 14)}`;
|
|
769
|
-
}
|
|
770
400
|
//#endregion
|
|
771
401
|
export { ScheduleArtifactError, compileScheduleArtifact, generateScheduleArtifact, parseScheduleArtifact, scheduleArtifactPath };
|
package/package.json
CHANGED
|
@@ -115,7 +115,7 @@
|
|
|
115
115
|
"prepack": "bun run build:cli"
|
|
116
116
|
},
|
|
117
117
|
"type": "module",
|
|
118
|
-
"version": "2.0.
|
|
118
|
+
"version": "2.0.1",
|
|
119
119
|
"description": "Config-driven multi-agent pipeline runner for repository work",
|
|
120
120
|
"main": "./dist/index.js",
|
|
121
121
|
"types": "./dist/index.d.ts",
|