@devcxl/opencode-cabbage 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +88 -0
- package/assets/agents/dev-lifecycle.md +135 -0
- package/assets/agents/team/architect.md +36 -0
- package/assets/agents/team/backend.md +44 -0
- package/assets/agents/team/frontend.md +41 -0
- package/assets/agents/team/reviewer.md +56 -0
- package/assets/commands/code.md +4 -0
- package/assets/commands/design.md +4 -0
- package/assets/commands/handoff.md +4 -0
- package/assets/commands/release.md +4 -0
- package/assets/commands/requirements.md +4 -0
- package/assets/commands/review.md +4 -0
- package/assets/commands/setup.md +4 -0
- package/assets/commands/tasks.md +4 -0
- package/assets/commands/test.md +4 -0
- package/assets/context/CONTEXT.md +40 -0
- package/assets/prompts/ADR-FORMAT.md +45 -0
- package/assets/prompts/PRD-FORMAT.md +17 -0
- package/assets/prompts/bootstrap.md +19 -0
- package/assets/skills/flow-code/SKILL.md +93 -0
- package/assets/skills/flow-design/SKILL.md +70 -0
- package/assets/skills/flow-handoff/SKILL.md +47 -0
- package/assets/skills/flow-release/SKILL.md +50 -0
- package/assets/skills/flow-requirements/SKILL.md +48 -0
- package/assets/skills/flow-requirements/references/interview-guide.md +35 -0
- package/assets/skills/flow-review/SKILL.md +88 -0
- package/assets/skills/flow-review/references/smell-baseline.md +18 -0
- package/assets/skills/flow-setup/SKILL.md +43 -0
- package/assets/skills/flow-tasks/SKILL.md +104 -0
- package/assets/skills/flow-test/SKILL.md +44 -0
- package/assets/templates/gitignore +5 -0
- package/dist/flowrun/audit.d.ts +5 -0
- package/dist/flowrun/audit.js +67 -0
- package/dist/flowrun/audit.js.map +1 -0
- package/dist/flowrun/gate.d.ts +18 -0
- package/dist/flowrun/gate.js +130 -0
- package/dist/flowrun/gate.js.map +1 -0
- package/dist/flowrun/github.d.ts +20 -0
- package/dist/flowrun/github.js +134 -0
- package/dist/flowrun/github.js.map +1 -0
- package/dist/flowrun/index.d.ts +7 -0
- package/dist/flowrun/index.js +8 -0
- package/dist/flowrun/index.js.map +1 -0
- package/dist/flowrun/merge.d.ts +24 -0
- package/dist/flowrun/merge.js +116 -0
- package/dist/flowrun/merge.js.map +1 -0
- package/dist/flowrun/resilience.d.ts +18 -0
- package/dist/flowrun/resilience.js +80 -0
- package/dist/flowrun/resilience.js.map +1 -0
- package/dist/flowrun/types.d.ts +81 -0
- package/dist/flowrun/types.js +20 -0
- package/dist/flowrun/types.js.map +1 -0
- package/dist/flowrun/validator.d.ts +9 -0
- package/dist/flowrun/validator.js +97 -0
- package/dist/flowrun/validator.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/plugin/agents.d.ts +15 -0
- package/dist/plugin/agents.js +64 -0
- package/dist/plugin/agents.js.map +1 -0
- package/dist/plugin/bootstrap.d.ts +3 -0
- package/dist/plugin/bootstrap.js +17 -0
- package/dist/plugin/bootstrap.js.map +1 -0
- package/dist/plugin/commands.d.ts +16 -0
- package/dist/plugin/commands.js +62 -0
- package/dist/plugin/commands.js.map +1 -0
- package/dist/plugin/goal.d.ts +41 -0
- package/dist/plugin/goal.js +194 -0
- package/dist/plugin/goal.js.map +1 -0
- package/dist/plugin/prompts.d.ts +3 -0
- package/dist/plugin/prompts.js +26 -0
- package/dist/plugin/prompts.js.map +1 -0
- package/dist/plugin/server.d.ts +2 -0
- package/dist/plugin/server.js +269 -0
- package/dist/plugin/server.js.map +1 -0
- package/dist/plugin/skills.d.ts +1 -0
- package/dist/plugin/skills.js +39 -0
- package/dist/plugin/skills.js.map +1 -0
- package/dist/plugin.d.ts +3 -0
- package/dist/plugin.js +9 -0
- package/dist/plugin.js.map +1 -0
- package/dist/util/fs.d.ts +1 -0
- package/dist/util/fs.js +11 -0
- package/dist/util/fs.js.map +1 -0
- package/dist/util/gh.d.ts +4 -0
- package/dist/util/gh.js +7 -0
- package/dist/util/gh.js.map +1 -0
- package/dist/util/paths.d.ts +17 -0
- package/dist/util/paths.js +78 -0
- package/dist/util/paths.js.map +1 -0
- package/dist/util/shell.d.ts +1 -0
- package/dist/util/shell.js +4 -0
- package/dist/util/shell.js.map +1 -0
- package/package.json +62 -0
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { FLOW_RUN_STAGES, TASK_STATUSES, } from "./types.js";
|
|
2
|
+
function ok() {
|
|
3
|
+
return { allowed: true, missing: [], failedChecks: [] };
|
|
4
|
+
}
|
|
5
|
+
function block(reason, missing = [], failedChecks = []) {
|
|
6
|
+
return { allowed: false, reason, missing, failedChecks };
|
|
7
|
+
}
|
|
8
|
+
export function canStartStage(flowRun, stage) {
|
|
9
|
+
const stageIdx = FLOW_RUN_STAGES.indexOf(stage);
|
|
10
|
+
if (stageIdx === -1)
|
|
11
|
+
return block(`Unknown stage: ${stage}`);
|
|
12
|
+
if (flowRun.status !== "running") {
|
|
13
|
+
return block(`FlowRun is ${flowRun.status}, not running`);
|
|
14
|
+
}
|
|
15
|
+
const prevStages = FLOW_RUN_STAGES.slice(0, stageIdx);
|
|
16
|
+
for (const prev of prevStages) {
|
|
17
|
+
const s = flowRun.stages[prev];
|
|
18
|
+
if (s.status !== "pass") {
|
|
19
|
+
return block(`Prerequisite stage "${prev}" is not complete (status: ${s.status})`, [prev]);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
const stageState = flowRun.stages[stage];
|
|
23
|
+
if (!stageState)
|
|
24
|
+
return block(`Stage state not found: ${stage}`);
|
|
25
|
+
if (stageState.status === "pass") {
|
|
26
|
+
return block(`Stage "${stage}" already completed`);
|
|
27
|
+
}
|
|
28
|
+
return ok();
|
|
29
|
+
}
|
|
30
|
+
export function canCompleteStage(flowRun, stage) {
|
|
31
|
+
const stageState = flowRun.stages[stage];
|
|
32
|
+
if (!stageState)
|
|
33
|
+
return block(`Stage state not found: ${stage}`);
|
|
34
|
+
const missingArtifacts = stageState.requiredArtifacts.filter(a => !a);
|
|
35
|
+
const failedChecks = stageState.checks.filter(c => c.status === "fail").map(c => c.name);
|
|
36
|
+
if (missingArtifacts.length > 0) {
|
|
37
|
+
return block(`Stage "${stage}" has missing required artifacts`, missingArtifacts);
|
|
38
|
+
}
|
|
39
|
+
if (failedChecks.length > 0) {
|
|
40
|
+
return block(`Stage "${stage}" has failed checks`, [], failedChecks);
|
|
41
|
+
}
|
|
42
|
+
const pendingChecks = stageState.checks.filter(c => c.status === "pending");
|
|
43
|
+
if (pendingChecks.length > 0) {
|
|
44
|
+
return block(`Stage "${stage}" has pending checks: ${pendingChecks.map(c => c.name).join(", ")}`);
|
|
45
|
+
}
|
|
46
|
+
if (stage === "merge") {
|
|
47
|
+
return canMerge(flowRun);
|
|
48
|
+
}
|
|
49
|
+
return ok();
|
|
50
|
+
}
|
|
51
|
+
export function canStartTask(flowRun, taskId) {
|
|
52
|
+
const task = flowRun.tasks[taskId];
|
|
53
|
+
if (!task)
|
|
54
|
+
return block(`Task not found: ${taskId}`);
|
|
55
|
+
if (flowRun.status !== "running") {
|
|
56
|
+
return block(`FlowRun is ${flowRun.status}, not running`);
|
|
57
|
+
}
|
|
58
|
+
const codeStage = flowRun.stages.code;
|
|
59
|
+
if (codeStage.status !== "running" && codeStage.status !== "pass") {
|
|
60
|
+
return block("Code stage is not active");
|
|
61
|
+
}
|
|
62
|
+
if (task.status === "merged")
|
|
63
|
+
return block(`Task "${taskId}" already merged`);
|
|
64
|
+
if (task.status === "running")
|
|
65
|
+
return block(`Task "${taskId}" already running`);
|
|
66
|
+
if (task.status === "blocked")
|
|
67
|
+
return block(`Task "${taskId}" is blocked: ${task.blockedReason || "unknown reason"}`);
|
|
68
|
+
for (const dep of task.dependsOn) {
|
|
69
|
+
const depTask = flowRun.tasks[dep];
|
|
70
|
+
if (!depTask)
|
|
71
|
+
return block(`Dependency task "${dep}" not found`);
|
|
72
|
+
if (depTask.status !== "merged") {
|
|
73
|
+
return block(`Dependency "${dep}" is not merged (status: ${depTask.status})`, [], [dep]);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return ok();
|
|
77
|
+
}
|
|
78
|
+
export function canCompleteTask(flowRun, taskId) {
|
|
79
|
+
const task = flowRun.tasks[taskId];
|
|
80
|
+
if (!task)
|
|
81
|
+
return block(`Task not found: ${taskId}`);
|
|
82
|
+
if (task.status !== "running") {
|
|
83
|
+
return block(`Task "${taskId}" is not running (status: ${task.status})`);
|
|
84
|
+
}
|
|
85
|
+
return ok();
|
|
86
|
+
}
|
|
87
|
+
export function canMerge(flowRun) {
|
|
88
|
+
if (flowRun.status !== "running" && flowRun.status !== "merging") {
|
|
89
|
+
return block("FlowRun is not in a mergeable state");
|
|
90
|
+
}
|
|
91
|
+
const reviewStage = flowRun.stages.review;
|
|
92
|
+
if (reviewStage.status !== "pass") {
|
|
93
|
+
return block("Review stage is not complete");
|
|
94
|
+
}
|
|
95
|
+
return ok();
|
|
96
|
+
}
|
|
97
|
+
export function allTasksComplete(flowRun) {
|
|
98
|
+
const taskIds = Object.keys(flowRun.tasks);
|
|
99
|
+
if (taskIds.length === 0)
|
|
100
|
+
return false;
|
|
101
|
+
return taskIds.every(id => flowRun.tasks[id].status === "merged");
|
|
102
|
+
}
|
|
103
|
+
export function getReadyTasks(flowRun) {
|
|
104
|
+
return Object.values(flowRun.tasks).filter(t => {
|
|
105
|
+
if (t.status !== "pending" && t.status !== "ready")
|
|
106
|
+
return false;
|
|
107
|
+
const depsMet = t.dependsOn.every(dep => {
|
|
108
|
+
const depTask = flowRun.tasks[dep];
|
|
109
|
+
return depTask && depTask.status === "merged";
|
|
110
|
+
});
|
|
111
|
+
return depsMet;
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
export function determineNextStage(flowRun) {
|
|
115
|
+
for (const stage of FLOW_RUN_STAGES) {
|
|
116
|
+
const s = flowRun.stages[stage];
|
|
117
|
+
if (s.status === "pending" || s.status === "failed" || s.status === "blocked") {
|
|
118
|
+
const gate = canStartStage(flowRun, stage);
|
|
119
|
+
if (gate.allowed) {
|
|
120
|
+
return { stage, reason: `Stage "${stage}" is ready to start` };
|
|
121
|
+
}
|
|
122
|
+
return { stage: null, reason: `Cannot start "${stage}": ${gate.reason}` };
|
|
123
|
+
}
|
|
124
|
+
if (s.status === "running") {
|
|
125
|
+
return { stage, reason: `Stage "${stage}" is in progress` };
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return { stage: null, reason: "All stages complete" };
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=gate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gate.js","sourceRoot":"","sources":["../../src/flowrun/gate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type FlowRun } from "./types.js";
|
|
2
|
+
export declare function extractFlowRunFromBody(body: string): FlowRun | null;
|
|
3
|
+
export declare function replaceFlowRunInBody(body: string, flowRun: FlowRun): string;
|
|
4
|
+
export declare function readFlowRun(issueNumber: number): Promise<FlowRun | null>;
|
|
5
|
+
export declare function writeFlowRun(issueNumber: number, flowRun: FlowRun): Promise<{
|
|
6
|
+
success: boolean;
|
|
7
|
+
error?: string;
|
|
8
|
+
}>;
|
|
9
|
+
export declare function readFlowRunWithLock(issueNumber: number): Promise<{
|
|
10
|
+
flowRun: FlowRun | null;
|
|
11
|
+
currentBody: string | null;
|
|
12
|
+
}>;
|
|
13
|
+
export declare function writeFlowRunWithLock(issueNumber: number, flowRun: FlowRun, previousBody: string): Promise<{
|
|
14
|
+
success: boolean;
|
|
15
|
+
error?: string;
|
|
16
|
+
conflict: boolean;
|
|
17
|
+
}>;
|
|
18
|
+
export declare function applyLabel(issueNumber: number, label: string): Promise<boolean>;
|
|
19
|
+
export declare function removeLabel(issueNumber: number, label: string): Promise<boolean>;
|
|
20
|
+
export declare function createInitialFlowRun(flowRunId: string, repo: string, parentIssueNumber: number): FlowRun;
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { gh } from "../util/gh.js";
|
|
2
|
+
import { escapeShellArg } from "../util/shell.js";
|
|
3
|
+
import { CABINET_START_MARKER, CABINET_END_MARKER, CURRENT_SCHEMA_VERSION, } from "./types.js";
|
|
4
|
+
import { validateFlowRun } from "./validator.js";
|
|
5
|
+
function buildFlowRunBlock(flowRun) {
|
|
6
|
+
const json = JSON.stringify(flowRun, null, 2);
|
|
7
|
+
return `${CABINET_START_MARKER}\n\`\`\`json\n${json}\n\`\`\`\n${CABINET_END_MARKER}`;
|
|
8
|
+
}
|
|
9
|
+
export function extractFlowRunFromBody(body) {
|
|
10
|
+
const startIdx = body.indexOf(CABINET_START_MARKER);
|
|
11
|
+
const endIdx = body.indexOf(CABINET_END_MARKER);
|
|
12
|
+
if (startIdx === -1 || endIdx === -1)
|
|
13
|
+
return null;
|
|
14
|
+
const block = body.slice(startIdx + CABINET_START_MARKER.length, endIdx).trim();
|
|
15
|
+
const jsonMatch = block.match(/```json\n?([\s\S]*?)```/);
|
|
16
|
+
if (!jsonMatch)
|
|
17
|
+
return null;
|
|
18
|
+
try {
|
|
19
|
+
const parsed = JSON.parse(jsonMatch[1].trim());
|
|
20
|
+
const { data } = validateFlowRun(parsed);
|
|
21
|
+
return data;
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
export function replaceFlowRunInBody(body, flowRun) {
|
|
28
|
+
const startIdx = body.indexOf(CABINET_START_MARKER);
|
|
29
|
+
const endIdx = body.indexOf(CABINET_END_MARKER);
|
|
30
|
+
const block = buildFlowRunBlock(flowRun);
|
|
31
|
+
if (startIdx === -1 || endIdx === -1) {
|
|
32
|
+
return body + "\n\n" + block;
|
|
33
|
+
}
|
|
34
|
+
return body.slice(0, startIdx) + block + body.slice(endIdx + CABINET_END_MARKER.length);
|
|
35
|
+
}
|
|
36
|
+
export async function readFlowRun(issueNumber) {
|
|
37
|
+
try {
|
|
38
|
+
const { stdout } = await gh(`issue view ${issueNumber} --json body --jq .body`);
|
|
39
|
+
return extractFlowRunFromBody(stdout);
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
export async function writeFlowRun(issueNumber, flowRun) {
|
|
46
|
+
try {
|
|
47
|
+
const { stdout } = await gh(`issue view ${issueNumber} --json body --jq .body`);
|
|
48
|
+
const body = stdout;
|
|
49
|
+
const newBody = replaceFlowRunInBody(body, flowRun);
|
|
50
|
+
const escaped = escapeShellArg(newBody);
|
|
51
|
+
await gh(`issue edit ${issueNumber} --body '${escaped}'`);
|
|
52
|
+
return { success: true };
|
|
53
|
+
}
|
|
54
|
+
catch (err) {
|
|
55
|
+
return { success: false, error: String(err) };
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
export async function readFlowRunWithLock(issueNumber) {
|
|
59
|
+
try {
|
|
60
|
+
const { stdout } = await gh(`issue view ${issueNumber} --json body --jq .body`);
|
|
61
|
+
const flowRun = extractFlowRunFromBody(stdout);
|
|
62
|
+
return { flowRun, currentBody: stdout };
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
return { flowRun: null, currentBody: null };
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
export async function writeFlowRunWithLock(issueNumber, flowRun, previousBody) {
|
|
69
|
+
try {
|
|
70
|
+
const { stdout } = await gh(`issue view ${issueNumber} --json body --jq .body`);
|
|
71
|
+
if (previousBody !== stdout) {
|
|
72
|
+
return { success: false, error: "Conflict: body has changed since last read", conflict: true };
|
|
73
|
+
}
|
|
74
|
+
const newBody = replaceFlowRunInBody(stdout, flowRun);
|
|
75
|
+
const escaped = escapeShellArg(newBody);
|
|
76
|
+
await gh(`issue edit ${issueNumber} --body '${escaped}'`);
|
|
77
|
+
return { success: true, conflict: false };
|
|
78
|
+
}
|
|
79
|
+
catch (err) {
|
|
80
|
+
return { success: false, error: String(err), conflict: false };
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
export async function applyLabel(issueNumber, label) {
|
|
84
|
+
try {
|
|
85
|
+
await gh(`issue edit ${issueNumber} --add-label '${label}'`);
|
|
86
|
+
return true;
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
export async function removeLabel(issueNumber, label) {
|
|
93
|
+
try {
|
|
94
|
+
await gh(`issue edit ${issueNumber} --remove-label '${label}'`);
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
export function createInitialFlowRun(flowRunId, repo, parentIssueNumber) {
|
|
102
|
+
const now = new Date().toISOString();
|
|
103
|
+
const emptyStage = () => ({
|
|
104
|
+
status: "pending",
|
|
105
|
+
requiredArtifacts: [],
|
|
106
|
+
checks: [],
|
|
107
|
+
completedAt: null,
|
|
108
|
+
evidence: [],
|
|
109
|
+
});
|
|
110
|
+
return {
|
|
111
|
+
flowRunId,
|
|
112
|
+
repo,
|
|
113
|
+
parentIssueNumber,
|
|
114
|
+
status: "planned",
|
|
115
|
+
schemaVersion: CURRENT_SCHEMA_VERSION,
|
|
116
|
+
revision: 0,
|
|
117
|
+
stages: {
|
|
118
|
+
requirements: emptyStage(),
|
|
119
|
+
design: emptyStage(),
|
|
120
|
+
tasks: emptyStage(),
|
|
121
|
+
code: emptyStage(),
|
|
122
|
+
test: emptyStage(),
|
|
123
|
+
review: emptyStage(),
|
|
124
|
+
merge: emptyStage(),
|
|
125
|
+
},
|
|
126
|
+
tasks: {},
|
|
127
|
+
startedAt: now,
|
|
128
|
+
lastTickAt: now,
|
|
129
|
+
nextTickAfter: null,
|
|
130
|
+
maxRuntime: 86_400_000,
|
|
131
|
+
completedAt: null,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
//# sourceMappingURL=github.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github.js","sourceRoot":"","sources":["../../src/flowrun/github.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { type FlowRun, type FlowRunStatus, type FlowStage, type TaskState, type TaskStatus, type StageState, type StageStatus, type Checkpoint, type CheckpointStatus, type EvidenceEntry, type PRCheckpoints, FLOW_RUN_STAGES, FLOW_RUN_STATUSES, TASK_STATUSES, STAGE_STATUSES, CHECKPOINT_STATUSES, CURRENT_SCHEMA_VERSION, DEFAULT_MAX_RUNTIME_MS, CABINET_START_MARKER, CABINET_END_MARKER, LABEL_PREFIX, FLOW_RUN_LABELS, } from "./types.js";
|
|
2
|
+
export { validateFlowRun, type ValidationError, } from "./validator.js";
|
|
3
|
+
export { extractFlowRunFromBody, replaceFlowRunInBody, readFlowRun, writeFlowRun, readFlowRunWithLock, writeFlowRunWithLock, applyLabel, removeLabel, createInitialFlowRun, } from "./github.js";
|
|
4
|
+
export { canStartStage, canCompleteStage, canStartTask, canCompleteTask, canMerge, allTasksComplete, getReadyTasks, determineNextStage, type GateResult, } from "./gate.js";
|
|
5
|
+
export { checkBranchProtection, validateCheckpoint, validatePRCheckpoints, canAutoMergeTask, mergePR, createRevertPR, type MergeGateResult, } from "./merge.js";
|
|
6
|
+
export { checkRuntime, hasRuntimeExpired, getRuntimeMs, checkBackpressure, buildContinuationContext, type RuntimeCheckResult, type BackpressureStatus, } from "./resilience.js";
|
|
7
|
+
export { postAuditComment, postPRComment, buildStageAudit, buildMergeAudit, } from "./audit.js";
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { FLOW_RUN_STAGES, FLOW_RUN_STATUSES, TASK_STATUSES, STAGE_STATUSES, CHECKPOINT_STATUSES, CURRENT_SCHEMA_VERSION, DEFAULT_MAX_RUNTIME_MS, CABINET_START_MARKER, CABINET_END_MARKER, LABEL_PREFIX, FLOW_RUN_LABELS, } from "./types.js";
|
|
2
|
+
export { validateFlowRun, } from "./validator.js";
|
|
3
|
+
export { extractFlowRunFromBody, replaceFlowRunInBody, readFlowRun, writeFlowRun, readFlowRunWithLock, writeFlowRunWithLock, applyLabel, removeLabel, createInitialFlowRun, } from "./github.js";
|
|
4
|
+
export { canStartStage, canCompleteStage, canStartTask, canCompleteTask, canMerge, allTasksComplete, getReadyTasks, determineNextStage, } from "./gate.js";
|
|
5
|
+
export { checkBranchProtection, validateCheckpoint, validatePRCheckpoints, canAutoMergeTask, mergePR, createRevertPR, } from "./merge.js";
|
|
6
|
+
export { checkRuntime, hasRuntimeExpired, getRuntimeMs, checkBackpressure, buildContinuationContext, } from "./resilience.js";
|
|
7
|
+
export { postAuditComment, postPRComment, buildStageAudit, buildMergeAudit, } from "./audit.js";
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/flowrun/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,eAAe,EAAE,iBAAiB,EAAE,aAAa,EAAE,cAAc,EAAE,mBAAmB,EACtF,sBAAsB,EAAE,sBAAsB,EAC9C,oBAAoB,EAAE,kBAAkB,EAAE,YAAY,EAAE,eAAe,GACxE,MAAM,YAAY,CAAA;AAEnB,OAAO,EACL,eAAe,GAChB,MAAM,gBAAgB,CAAA;AAEvB,OAAO,EACL,sBAAsB,EAAE,oBAAoB,EAC5C,WAAW,EAAE,YAAY,EACzB,mBAAmB,EAAE,oBAAoB,EACzC,UAAU,EAAE,WAAW,EAAE,oBAAoB,GAC9C,MAAM,aAAa,CAAA;AAEpB,OAAO,EACL,aAAa,EAAE,gBAAgB,EAAE,YAAY,EAAE,eAAe,EAC9D,QAAQ,EAAE,gBAAgB,EAAE,aAAa,EAAE,kBAAkB,GAE9D,MAAM,WAAW,CAAA;AAElB,OAAO,EACL,qBAAqB,EAAE,kBAAkB,EAAE,qBAAqB,EAChE,gBAAgB,EAAE,OAAO,EAAE,cAAc,GAE1C,MAAM,YAAY,CAAA;AAEnB,OAAO,EACL,YAAY,EAAE,iBAAiB,EAAE,YAAY,EAC7C,iBAAiB,EAAE,wBAAwB,GAE5C,MAAM,iBAAiB,CAAA;AAExB,OAAO,EACL,gBAAgB,EAAE,aAAa,EAC/B,eAAe,EAAE,eAAe,GACjC,MAAM,YAAY,CAAA"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { FlowRun, PRCheckpoints, Checkpoint, TaskState } from "./types.js";
|
|
2
|
+
export interface BranchProtectionStatus {
|
|
3
|
+
exists: boolean;
|
|
4
|
+
requiredChecks: string[];
|
|
5
|
+
requiresPR: boolean;
|
|
6
|
+
dismissesStale: boolean;
|
|
7
|
+
}
|
|
8
|
+
export interface MergeGateResult {
|
|
9
|
+
allowed: boolean;
|
|
10
|
+
reason?: string;
|
|
11
|
+
checkpointResults: Record<string, "pending" | "pass" | "fail" | "skipped">;
|
|
12
|
+
}
|
|
13
|
+
export declare function checkBranchProtection(owner: string, repo: string): Promise<BranchProtectionStatus>;
|
|
14
|
+
export declare function validateCheckpoint(cp: Checkpoint): "pending" | "pass" | "fail";
|
|
15
|
+
export declare function validatePRCheckpoints(checkpoints: PRCheckpoints): MergeGateResult;
|
|
16
|
+
export declare function canAutoMergeTask(flowRun: FlowRun, task: TaskState, protection: BranchProtectionStatus): MergeGateResult;
|
|
17
|
+
export declare function mergePR(prNumber: number): Promise<{
|
|
18
|
+
success: boolean;
|
|
19
|
+
error?: string;
|
|
20
|
+
}>;
|
|
21
|
+
export declare function createRevertPR(prNumber: number, reason: string): Promise<{
|
|
22
|
+
prNumber?: number;
|
|
23
|
+
error?: string;
|
|
24
|
+
}>;
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { canMerge } from "./gate.js";
|
|
2
|
+
import { gh } from "../util/gh.js";
|
|
3
|
+
export async function checkBranchProtection(owner, repo) {
|
|
4
|
+
try {
|
|
5
|
+
const { stdout } = await gh(`api repos/${owner}/${repo}/branches/main/protection`);
|
|
6
|
+
const data = JSON.parse(stdout);
|
|
7
|
+
const checks = [];
|
|
8
|
+
const requiredPulls = data?.required_pull_request_reviews ?? null;
|
|
9
|
+
const requiredChecks = data?.required_status_checks?.checks ?? [];
|
|
10
|
+
for (const c of requiredChecks) {
|
|
11
|
+
checks.push(c.context);
|
|
12
|
+
}
|
|
13
|
+
return {
|
|
14
|
+
exists: true,
|
|
15
|
+
requiredChecks: checks,
|
|
16
|
+
requiresPR: !!requiredPulls,
|
|
17
|
+
dismissesStale: requiredPulls?.dismiss_stale_reviews ?? false,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return {
|
|
22
|
+
exists: false,
|
|
23
|
+
requiredChecks: [],
|
|
24
|
+
requiresPR: false,
|
|
25
|
+
dismissesStale: false,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
export function validateCheckpoint(cp) {
|
|
30
|
+
if (cp.status === "pass")
|
|
31
|
+
return "pass";
|
|
32
|
+
if (cp.status === "fail")
|
|
33
|
+
return "fail";
|
|
34
|
+
return "pending";
|
|
35
|
+
}
|
|
36
|
+
export function validatePRCheckpoints(checkpoints) {
|
|
37
|
+
const gates = {
|
|
38
|
+
localChecks: checkpoints.localChecks,
|
|
39
|
+
ciChecks: checkpoints.ciChecks,
|
|
40
|
+
reviewerApproval: checkpoints.reviewerApproval,
|
|
41
|
+
goalVerification: checkpoints.goalVerification,
|
|
42
|
+
branchProtection: checkpoints.branchProtection,
|
|
43
|
+
};
|
|
44
|
+
const results = {};
|
|
45
|
+
for (const [name, cp] of Object.entries(gates)) {
|
|
46
|
+
results[name] = validateCheckpoint(cp);
|
|
47
|
+
}
|
|
48
|
+
const failures = Object.entries(gates).filter(([_, cp]) => cp.status === "fail");
|
|
49
|
+
if (failures.length > 0) {
|
|
50
|
+
return {
|
|
51
|
+
allowed: false,
|
|
52
|
+
reason: `Failed checkpoints: ${failures.map(([k]) => k).join(", ")}`,
|
|
53
|
+
checkpointResults: results,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
const pending = Object.entries(gates).filter(([_, cp]) => cp.status === "pending");
|
|
57
|
+
if (pending.length > 0) {
|
|
58
|
+
return {
|
|
59
|
+
allowed: false,
|
|
60
|
+
reason: `Pending checkpoints: ${pending.map(([k]) => k).join(", ")}`,
|
|
61
|
+
checkpointResults: results,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
return { allowed: true, checkpointResults: results };
|
|
65
|
+
}
|
|
66
|
+
export function canAutoMergeTask(flowRun, task, protection) {
|
|
67
|
+
const flowGate = canMerge(flowRun);
|
|
68
|
+
if (!flowGate.allowed) {
|
|
69
|
+
return { allowed: false, reason: flowGate.reason, checkpointResults: {} };
|
|
70
|
+
}
|
|
71
|
+
if (task.status === "merged") {
|
|
72
|
+
return { allowed: false, reason: "Task already merged", checkpointResults: {} };
|
|
73
|
+
}
|
|
74
|
+
if (task.status !== "reviewing") {
|
|
75
|
+
return { allowed: false, reason: `Task status is ${task.status}, expected reviewing`, checkpointResults: {} };
|
|
76
|
+
}
|
|
77
|
+
if (!task.prCheckpoints) {
|
|
78
|
+
return { allowed: false, reason: "No PR checkpoints recorded", checkpointResults: {} };
|
|
79
|
+
}
|
|
80
|
+
const prResult = validatePRCheckpoints(task.prCheckpoints);
|
|
81
|
+
if (!prResult.allowed)
|
|
82
|
+
return prResult;
|
|
83
|
+
if (!protection.exists) {
|
|
84
|
+
prResult.checkpointResults.branchProtection = "fail";
|
|
85
|
+
return {
|
|
86
|
+
allowed: false,
|
|
87
|
+
reason: "Branch protection not enabled on main",
|
|
88
|
+
checkpointResults: prResult.checkpointResults,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
prResult.checkpointResults.branchProtection = "pass";
|
|
92
|
+
return prResult;
|
|
93
|
+
}
|
|
94
|
+
export async function mergePR(prNumber) {
|
|
95
|
+
try {
|
|
96
|
+
await gh(`pr merge ${prNumber} --squash --delete-branch`);
|
|
97
|
+
return { success: true };
|
|
98
|
+
}
|
|
99
|
+
catch (err) {
|
|
100
|
+
return { success: false, error: String(err) };
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
export async function createRevertPR(prNumber, reason) {
|
|
104
|
+
try {
|
|
105
|
+
const { stdout } = await gh(`pr view ${prNumber} --json headRefName,headRepository,body,title`);
|
|
106
|
+
const pr = JSON.parse(stdout);
|
|
107
|
+
const revertTitle = `revert: ${pr.title}`;
|
|
108
|
+
const revertBody = `Reverts #${prNumber}\n\nReason: ${reason}\n\nAuto-generated by opencode-cabbage.`;
|
|
109
|
+
const { stdout: newPR } = await gh(`pr create --title '${revertTitle}' --body '${revertBody}' --base main --head main`);
|
|
110
|
+
return { prNumber: parseInt(newPR.trim().split("/").pop() || "0", 10) };
|
|
111
|
+
}
|
|
112
|
+
catch (err) {
|
|
113
|
+
return { error: String(err) };
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=merge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"merge.js","sourceRoot":"","sources":["../../src/flowrun/merge.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type FlowRun } from "./types.js";
|
|
2
|
+
export declare function getRuntimeMs(flowRun: FlowRun): number;
|
|
3
|
+
export declare function hasRuntimeExpired(flowRun: FlowRun): boolean;
|
|
4
|
+
export interface RuntimeCheckResult {
|
|
5
|
+
expired: boolean;
|
|
6
|
+
runtimeMs: number;
|
|
7
|
+
maxRuntimeMs: number;
|
|
8
|
+
remainingMs: number;
|
|
9
|
+
}
|
|
10
|
+
export declare function checkRuntime(flowRun: FlowRun): RuntimeCheckResult;
|
|
11
|
+
export interface BackpressureStatus {
|
|
12
|
+
canContinue: boolean;
|
|
13
|
+
reason?: string;
|
|
14
|
+
rateLimitRemaining: number | null;
|
|
15
|
+
ciQueueLength: number | null;
|
|
16
|
+
}
|
|
17
|
+
export declare function checkBackpressure(owner: string, repo: string): Promise<BackpressureStatus>;
|
|
18
|
+
export declare function buildContinuationContext(flowRun: FlowRun): string;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { DEFAULT_MAX_RUNTIME_MS, FLOW_RUN_STAGES } from "./types.js";
|
|
2
|
+
import { gh } from "../util/gh.js";
|
|
3
|
+
export function getRuntimeMs(flowRun) {
|
|
4
|
+
if (!flowRun.startedAt)
|
|
5
|
+
return 0;
|
|
6
|
+
return Date.now() - new Date(flowRun.startedAt).getTime();
|
|
7
|
+
}
|
|
8
|
+
export function hasRuntimeExpired(flowRun) {
|
|
9
|
+
const max = flowRun.maxRuntime || DEFAULT_MAX_RUNTIME_MS;
|
|
10
|
+
return getRuntimeMs(flowRun) > max;
|
|
11
|
+
}
|
|
12
|
+
export function checkRuntime(flowRun) {
|
|
13
|
+
const runtimeMs = getRuntimeMs(flowRun);
|
|
14
|
+
const maxRuntimeMs = flowRun.maxRuntime || DEFAULT_MAX_RUNTIME_MS;
|
|
15
|
+
return {
|
|
16
|
+
expired: runtimeMs > maxRuntimeMs,
|
|
17
|
+
runtimeMs,
|
|
18
|
+
maxRuntimeMs,
|
|
19
|
+
remainingMs: Math.max(0, maxRuntimeMs - runtimeMs),
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
export async function checkBackpressure(owner, repo) {
|
|
23
|
+
const status = {
|
|
24
|
+
canContinue: true,
|
|
25
|
+
rateLimitRemaining: null,
|
|
26
|
+
ciQueueLength: null,
|
|
27
|
+
};
|
|
28
|
+
try {
|
|
29
|
+
const { stdout } = await gh(`api rate_limit --jq .rate.remaining`);
|
|
30
|
+
const remaining = parseInt(stdout.trim(), 10);
|
|
31
|
+
status.rateLimitRemaining = remaining;
|
|
32
|
+
if (remaining < 100) {
|
|
33
|
+
status.canContinue = false;
|
|
34
|
+
status.reason = `GitHub API rate limit low: ${remaining} remaining`;
|
|
35
|
+
return status;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
status.rateLimitRemaining = null;
|
|
40
|
+
}
|
|
41
|
+
try {
|
|
42
|
+
const { stdout } = await gh(`run list --repo ${owner}/${repo} --json status --jq '[.[] | select(.status == "queued" or .status == "in_progress")] | length'`);
|
|
43
|
+
const queueLen = parseInt(stdout.trim(), 10);
|
|
44
|
+
status.ciQueueLength = queueLen;
|
|
45
|
+
if (queueLen >= 10) {
|
|
46
|
+
status.canContinue = false;
|
|
47
|
+
status.reason = `CI queue too long: ${queueLen} queued/in_progress`;
|
|
48
|
+
return status;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
status.ciQueueLength = null;
|
|
53
|
+
}
|
|
54
|
+
return status;
|
|
55
|
+
}
|
|
56
|
+
export function buildContinuationContext(flowRun) {
|
|
57
|
+
const parts = [
|
|
58
|
+
`FlowRun: ${flowRun.flowRunId}`,
|
|
59
|
+
`Status: ${flowRun.status}`,
|
|
60
|
+
`Runtime: ${Math.round(getRuntimeMs(flowRun) / 60000)} minutes`,
|
|
61
|
+
"",
|
|
62
|
+
"## Stage Status",
|
|
63
|
+
];
|
|
64
|
+
for (const stage of FLOW_RUN_STAGES) {
|
|
65
|
+
const s = flowRun.stages[stage];
|
|
66
|
+
const checkSummary = s.checks
|
|
67
|
+
.map(c => `${c.name}=${c.status}`)
|
|
68
|
+
.join(", ");
|
|
69
|
+
parts.push(`- ${stage}: ${s.status}${checkSummary ? ` (${checkSummary})` : ""}`);
|
|
70
|
+
}
|
|
71
|
+
const taskEntries = Object.entries(flowRun.tasks);
|
|
72
|
+
if (taskEntries.length > 0) {
|
|
73
|
+
parts.push("", "## Tasks");
|
|
74
|
+
for (const [id, task] of taskEntries) {
|
|
75
|
+
parts.push(`- ${id}: ${task.status}${task.prNumber ? ` PR #${task.prNumber}` : ""}`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return parts.join("\n");
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=resilience.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resilience.js","sourceRoot":"","sources":["../../src/flowrun/resilience.ts"],"names":[],"mappings":"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"}
|