@fitlab-ai/agent-infra 0.6.5 → 0.7.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 +51 -25
- package/README.zh-CN.md +49 -23
- package/dist/lib/defaults.json +1 -0
- package/dist/lib/init.js +3 -0
- package/dist/lib/sandbox/commands/create.js +4 -2
- package/dist/lib/sandbox/commands/enter.js +15 -4
- package/dist/lib/sandbox/commands/list-running.js +108 -0
- package/dist/lib/sandbox/commands/ls.js +24 -45
- package/dist/lib/sandbox/commands/rebuild.js +4 -2
- package/dist/lib/sandbox/config.js +3 -0
- package/dist/lib/sandbox/index.js +2 -1
- package/dist/lib/sandbox/runtimes/ai-tools.dockerfile +10 -6
- package/dist/lib/sandbox/tools.js +213 -8
- package/dist/lib/update.js +12 -1
- package/lib/defaults.json +1 -0
- package/lib/init.ts +10 -0
- package/lib/sandbox/commands/create.ts +10 -2
- package/lib/sandbox/commands/enter.ts +14 -4
- package/lib/sandbox/commands/list-running.ts +135 -0
- package/lib/sandbox/commands/ls.ts +28 -49
- package/lib/sandbox/commands/rebuild.ts +9 -2
- package/lib/sandbox/config.ts +7 -0
- package/lib/sandbox/index.ts +2 -1
- package/lib/sandbox/runtimes/ai-tools.dockerfile +10 -6
- package/lib/sandbox/tools.ts +248 -9
- package/lib/update.ts +15 -1
- package/package.json +1 -1
- package/templates/.agents/QUICKSTART.en.md +1 -1
- package/templates/.agents/QUICKSTART.zh-CN.md +1 -1
- package/templates/.agents/README.en.md +79 -2
- package/templates/.agents/README.zh-CN.md +79 -2
- package/templates/.agents/rules/create-issue.en.md +1 -1
- package/templates/.agents/rules/create-issue.github.en.md +1 -1
- package/templates/.agents/rules/create-issue.github.zh-CN.md +1 -1
- package/templates/.agents/rules/create-issue.zh-CN.md +1 -1
- package/templates/.agents/rules/issue-sync.github.en.md +6 -5
- package/templates/.agents/rules/issue-sync.github.zh-CN.md +6 -5
- package/templates/.agents/rules/milestone-inference.github.en.md +2 -2
- package/templates/.agents/rules/milestone-inference.github.zh-CN.md +2 -2
- package/templates/.agents/rules/no-mid-flow-questions.en.md +57 -0
- package/templates/.agents/rules/no-mid-flow-questions.zh-CN.md +57 -0
- package/templates/.agents/rules/pr-sync.github.en.md +4 -5
- package/templates/.agents/rules/pr-sync.github.zh-CN.md +4 -5
- package/templates/.agents/rules/task-management.en.md +9 -6
- package/templates/.agents/rules/task-management.zh-CN.md +9 -6
- package/templates/.agents/rules/testing-discipline.en.md +2 -2
- package/templates/.agents/rules/testing-discipline.zh-CN.md +2 -2
- package/templates/.agents/scripts/validate-artifact.js +1 -1
- package/templates/.agents/skills/analyze-task/SKILL.en.md +16 -4
- package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +16 -4
- package/templates/.agents/skills/check-task/SKILL.en.md +43 -32
- package/templates/.agents/skills/check-task/SKILL.zh-CN.md +42 -31
- package/templates/.agents/skills/code-task/SKILL.en.md +117 -0
- package/templates/.agents/skills/{implement-task → code-task}/SKILL.zh-CN.md +51 -24
- package/templates/.agents/skills/{implement-task → code-task}/config/verify.en.json +4 -4
- package/templates/.agents/skills/{implement-task → code-task}/config/verify.zh-CN.json +4 -4
- package/templates/.agents/skills/{implement-task → code-task}/reference/branch-management.zh-CN.md +2 -2
- package/templates/.agents/skills/{implement-task/reference/implementation-rules.en.md → code-task/reference/code-rules.en.md} +6 -6
- package/templates/.agents/skills/{implement-task/reference/implementation-rules.zh-CN.md → code-task/reference/code-rules.zh-CN.md} +3 -3
- package/templates/.agents/skills/code-task/reference/dual-mode.en.md +69 -0
- package/templates/.agents/skills/code-task/reference/dual-mode.zh-CN.md +69 -0
- package/templates/.agents/skills/{refine-task/reference/fix-workflow.en.md → code-task/reference/fix-mode.en.md} +12 -12
- package/templates/.agents/skills/{refine-task/reference/fix-workflow.zh-CN.md → code-task/reference/fix-mode.zh-CN.md} +8 -8
- package/templates/.agents/skills/code-task/reference/output-template.en.md +20 -0
- package/templates/.agents/skills/code-task/reference/output-template.zh-CN.md +20 -0
- package/templates/.agents/skills/{implement-task → code-task}/reference/report-template.en.md +4 -4
- package/templates/.agents/skills/{implement-task → code-task}/reference/report-template.zh-CN.md +3 -3
- package/templates/.agents/skills/code-task/scripts/detect-mode.js +370 -0
- package/templates/.agents/skills/commit/SKILL.en.md +2 -2
- package/templates/.agents/skills/commit/SKILL.zh-CN.md +2 -2
- package/templates/.agents/skills/commit/reference/task-status-update.en.md +10 -6
- package/templates/.agents/skills/commit/reference/task-status-update.zh-CN.md +10 -6
- package/templates/.agents/skills/complete-task/SKILL.en.md +5 -3
- package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +5 -3
- package/templates/.agents/skills/create-pr/SKILL.en.md +17 -1
- package/templates/.agents/skills/create-pr/SKILL.zh-CN.md +17 -1
- package/templates/.agents/skills/import-codescan/SKILL.en.md +1 -1
- package/templates/.agents/skills/import-codescan/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/import-dependabot/SKILL.en.md +2 -2
- package/templates/.agents/skills/import-dependabot/SKILL.zh-CN.md +2 -2
- package/templates/.agents/skills/import-issue/SKILL.en.md +3 -3
- package/templates/.agents/skills/import-issue/SKILL.zh-CN.md +3 -3
- package/templates/.agents/skills/plan-task/SKILL.en.md +4 -4
- package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +4 -4
- package/templates/.agents/skills/restore-task/SKILL.en.md +4 -3
- package/templates/.agents/skills/restore-task/SKILL.zh-CN.md +4 -3
- package/templates/.agents/skills/review-analysis/SKILL.en.md +76 -0
- package/templates/.agents/skills/review-analysis/SKILL.zh-CN.md +102 -0
- package/templates/.agents/skills/review-analysis/config/verify.en.json +51 -0
- package/templates/.agents/skills/review-analysis/config/verify.zh-CN.json +51 -0
- package/templates/.agents/skills/review-analysis/reference/output-templates.en.md +87 -0
- package/templates/.agents/skills/review-analysis/reference/output-templates.zh-CN.md +87 -0
- package/templates/.agents/skills/review-analysis/reference/report-template.en.md +90 -0
- package/templates/.agents/skills/review-analysis/reference/report-template.zh-CN.md +91 -0
- package/templates/.agents/skills/review-analysis/reference/review-criteria.en.md +47 -0
- package/templates/.agents/skills/review-analysis/reference/review-criteria.zh-CN.md +47 -0
- package/templates/.agents/skills/{review-task → review-code}/SKILL.en.md +11 -9
- package/templates/.agents/skills/{review-task → review-code}/SKILL.zh-CN.md +15 -9
- package/templates/.agents/skills/{review-task → review-code}/config/verify.en.json +7 -5
- package/templates/.agents/skills/{review-task → review-code}/config/verify.zh-CN.json +6 -4
- package/templates/.agents/skills/{review-task → review-code}/reference/output-templates.en.md +21 -17
- package/templates/.agents/skills/{review-task → review-code}/reference/output-templates.zh-CN.md +19 -15
- package/templates/.agents/skills/{review-task → review-code}/reference/report-template.en.md +5 -6
- package/templates/.agents/skills/review-code/reference/report-template.zh-CN.md +91 -0
- package/templates/.agents/skills/review-code/reference/review-criteria.en.md +48 -0
- package/templates/.agents/skills/{review-task → review-code}/reference/review-criteria.zh-CN.md +10 -4
- package/templates/.agents/skills/review-plan/SKILL.en.md +76 -0
- package/templates/.agents/skills/review-plan/SKILL.zh-CN.md +102 -0
- package/templates/.agents/skills/{refine-task → review-plan}/config/verify.en.json +14 -10
- package/templates/.agents/skills/{refine-task → review-plan}/config/verify.zh-CN.json +14 -10
- package/templates/.agents/skills/review-plan/reference/output-templates.en.md +87 -0
- package/templates/.agents/skills/review-plan/reference/output-templates.zh-CN.md +87 -0
- package/templates/.agents/skills/review-plan/reference/report-template.en.md +90 -0
- package/templates/.agents/skills/{review-task → review-plan}/reference/report-template.zh-CN.md +3 -3
- package/templates/.agents/skills/review-plan/reference/review-criteria.en.md +47 -0
- package/templates/.agents/skills/review-plan/reference/review-criteria.zh-CN.md +47 -0
- package/templates/.agents/skills/test/SKILL.en.md +2 -2
- package/templates/.agents/skills/test/SKILL.zh-CN.md +13 -31
- package/templates/.agents/skills/update-agent-infra/scripts/sync-templates.js +1 -0
- package/templates/.agents/templates/task.en.md +3 -3
- package/templates/.agents/templates/task.zh-CN.md +2 -2
- package/templates/.agents/workflows/bug-fix.en.yaml +126 -80
- package/templates/.agents/workflows/bug-fix.zh-CN.yaml +90 -44
- package/templates/.agents/workflows/feature-development.en.yaml +115 -70
- package/templates/.agents/workflows/feature-development.zh-CN.yaml +92 -47
- package/templates/.agents/workflows/refactoring.en.yaml +123 -78
- package/templates/.agents/workflows/refactoring.zh-CN.yaml +89 -44
- package/templates/.claude/commands/code-task.en.md +8 -0
- package/templates/.claude/commands/code-task.zh-CN.md +8 -0
- package/templates/.claude/commands/review-analysis.en.md +8 -0
- package/templates/.claude/commands/review-analysis.zh-CN.md +8 -0
- package/templates/.claude/commands/review-code.en.md +8 -0
- package/templates/.claude/commands/review-code.zh-CN.md +8 -0
- package/templates/.claude/commands/review-plan.en.md +8 -0
- package/templates/.claude/commands/review-plan.zh-CN.md +8 -0
- package/templates/.gemini/commands/_project_/archive-tasks.zh-CN.toml +1 -1
- package/templates/.gemini/commands/_project_/code-task.en.toml +8 -0
- package/templates/.gemini/commands/_project_/code-task.zh-CN.toml +8 -0
- package/templates/.gemini/commands/_project_/init-labels.zh-CN.toml +1 -1
- package/templates/.gemini/commands/_project_/init-milestones.zh-CN.toml +1 -1
- package/templates/.gemini/commands/_project_/review-analysis.en.toml +8 -0
- package/templates/.gemini/commands/_project_/review-analysis.zh-CN.toml +8 -0
- package/templates/.gemini/commands/_project_/review-code.en.toml +8 -0
- package/templates/.gemini/commands/_project_/review-code.zh-CN.toml +8 -0
- package/templates/.gemini/commands/_project_/review-plan.en.toml +8 -0
- package/templates/.gemini/commands/_project_/review-plan.zh-CN.toml +8 -0
- package/templates/.opencode/commands/code-task.en.md +11 -0
- package/templates/.opencode/commands/code-task.zh-CN.md +11 -0
- package/templates/.opencode/commands/review-analysis.en.md +11 -0
- package/templates/.opencode/commands/review-analysis.zh-CN.md +11 -0
- package/templates/.opencode/commands/review-code.en.md +11 -0
- package/templates/.opencode/commands/review-code.zh-CN.md +11 -0
- package/templates/.opencode/commands/review-plan.en.md +11 -0
- package/templates/.opencode/commands/review-plan.zh-CN.md +11 -0
- package/templates/.agents/skills/implement-task/SKILL.en.md +0 -173
- package/templates/.agents/skills/implement-task/reference/output-template.en.md +0 -20
- package/templates/.agents/skills/implement-task/reference/output-template.zh-CN.md +0 -20
- package/templates/.agents/skills/refine-task/SKILL.en.md +0 -153
- package/templates/.agents/skills/refine-task/SKILL.zh-CN.md +0 -153
- package/templates/.agents/skills/refine-task/reference/report-template.en.md +0 -64
- package/templates/.agents/skills/refine-task/reference/report-template.zh-CN.md +0 -64
- package/templates/.agents/skills/review-task/reference/review-criteria.en.md +0 -42
- package/templates/.claude/commands/implement-task.en.md +0 -8
- package/templates/.claude/commands/implement-task.zh-CN.md +0 -8
- package/templates/.claude/commands/refine-task.en.md +0 -8
- package/templates/.claude/commands/refine-task.zh-CN.md +0 -8
- package/templates/.claude/commands/review-task.en.md +0 -8
- package/templates/.claude/commands/review-task.zh-CN.md +0 -8
- package/templates/.gemini/commands/_project_/implement-task.en.toml +0 -8
- package/templates/.gemini/commands/_project_/implement-task.zh-CN.toml +0 -8
- package/templates/.gemini/commands/_project_/refine-task.en.toml +0 -8
- package/templates/.gemini/commands/_project_/refine-task.zh-CN.toml +0 -8
- package/templates/.gemini/commands/_project_/review-task.en.toml +0 -8
- package/templates/.gemini/commands/_project_/review-task.zh-CN.toml +0 -8
- package/templates/.opencode/commands/implement-task.en.md +0 -11
- package/templates/.opencode/commands/implement-task.zh-CN.md +0 -11
- package/templates/.opencode/commands/refine-task.en.md +0 -11
- package/templates/.opencode/commands/refine-task.zh-CN.md +0 -11
- package/templates/.opencode/commands/review-task.en.md +0 -11
- package/templates/.opencode/commands/review-task.zh-CN.md +0 -11
- /package/templates/.agents/skills/{implement-task → code-task}/reference/branch-management.en.md +0 -0
|
@@ -0,0 +1,370 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import process from "node:process";
|
|
4
|
+
|
|
5
|
+
function main() {
|
|
6
|
+
const taskDir = process.argv[2];
|
|
7
|
+
if (!taskDir) {
|
|
8
|
+
writeResult({
|
|
9
|
+
mode: "error",
|
|
10
|
+
code_max: 0,
|
|
11
|
+
rev_max: 0,
|
|
12
|
+
verdict: null,
|
|
13
|
+
next_round: null,
|
|
14
|
+
next_artifact: null,
|
|
15
|
+
review_artifact: null,
|
|
16
|
+
message: "Task directory argument is required."
|
|
17
|
+
}, 2);
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
try {
|
|
22
|
+
const resolvedTaskDir = path.resolve(taskDir);
|
|
23
|
+
const taskId = path.basename(resolvedTaskDir);
|
|
24
|
+
const entries = fs.readdirSync(resolvedTaskDir);
|
|
25
|
+
const codeMax = maxRound(entries, "code");
|
|
26
|
+
const revMax = maxRound(entries, "review-code");
|
|
27
|
+
|
|
28
|
+
if (codeMax === 0) {
|
|
29
|
+
writeResult({
|
|
30
|
+
mode: "init",
|
|
31
|
+
code_max: codeMax,
|
|
32
|
+
rev_max: revMax,
|
|
33
|
+
verdict: null,
|
|
34
|
+
next_round: 1,
|
|
35
|
+
next_artifact: "code.md",
|
|
36
|
+
review_artifact: null,
|
|
37
|
+
message: "No prior code artifact. Starting initial implementation (round 1 -> code.md)."
|
|
38
|
+
}, 0);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// replan-precedes-unreviewed-code:
|
|
43
|
+
// 第 8 分支(replan)必须在第 2 分支(revMax < codeMax → error)之前评估。
|
|
44
|
+
// 依据 task.md 盲区 B 修法 B1:「不论 review-code 状态如何(包括未审)」,
|
|
45
|
+
// 只要最新 review-plan 已批准且 mtime > code,就进入新一轮实现。
|
|
46
|
+
const planMax = maxRound(entries, "plan");
|
|
47
|
+
const reviewPlanMax = maxRound(entries, "review-plan");
|
|
48
|
+
const replanCheck = checkPlanAheadOfCode({
|
|
49
|
+
resolvedTaskDir,
|
|
50
|
+
codeMax,
|
|
51
|
+
planMax,
|
|
52
|
+
reviewPlanMax
|
|
53
|
+
});
|
|
54
|
+
if (replanCheck.replan) {
|
|
55
|
+
const nextRound = codeMax + 1;
|
|
56
|
+
const nextArtifact = artifactName("code", nextRound);
|
|
57
|
+
writeResult({
|
|
58
|
+
mode: "init",
|
|
59
|
+
code_max: codeMax,
|
|
60
|
+
rev_max: revMax,
|
|
61
|
+
verdict: null,
|
|
62
|
+
next_round: nextRound,
|
|
63
|
+
next_artifact: nextArtifact,
|
|
64
|
+
review_artifact: replanCheck.reviewPlanArtifact,
|
|
65
|
+
message: `Latest ${replanCheck.reviewPlanArtifact} is approved and its mtime is newer than the latest code artifact. Entering replan-driven init (round ${nextRound} -> ${nextArtifact}).`
|
|
66
|
+
}, 0);
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (revMax < codeMax) {
|
|
71
|
+
const expected = artifactName("review-code", codeMax);
|
|
72
|
+
writeResult({
|
|
73
|
+
mode: "error",
|
|
74
|
+
code_max: codeMax,
|
|
75
|
+
rev_max: revMax,
|
|
76
|
+
verdict: null,
|
|
77
|
+
next_round: null,
|
|
78
|
+
next_artifact: null,
|
|
79
|
+
review_artifact: expected,
|
|
80
|
+
message: `Code round ${codeMax} has no matching review-code artifact (${expected} expected). Run /review-code ${taskId} first.`
|
|
81
|
+
}, 2);
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (revMax > codeMax) {
|
|
86
|
+
writeResult({
|
|
87
|
+
mode: "error",
|
|
88
|
+
code_max: codeMax,
|
|
89
|
+
rev_max: revMax,
|
|
90
|
+
verdict: null,
|
|
91
|
+
next_round: null,
|
|
92
|
+
next_artifact: null,
|
|
93
|
+
review_artifact: artifactName("review-code", revMax),
|
|
94
|
+
message: `Inconsistent state: review-code round ${revMax} > code round ${codeMax}. Manual inspection required.`
|
|
95
|
+
}, 2);
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const reviewArtifact = artifactName("review-code", revMax);
|
|
100
|
+
const verdictResult = parseVerdict(path.join(resolvedTaskDir, reviewArtifact));
|
|
101
|
+
if (!verdictResult.ok) {
|
|
102
|
+
writeResult({
|
|
103
|
+
mode: "error",
|
|
104
|
+
code_max: codeMax,
|
|
105
|
+
rev_max: revMax,
|
|
106
|
+
verdict: verdictResult.verdict ?? null,
|
|
107
|
+
next_round: null,
|
|
108
|
+
next_artifact: null,
|
|
109
|
+
review_artifact: reviewArtifact,
|
|
110
|
+
message: verdictResult.message
|
|
111
|
+
}, 2);
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const verdict = verdictResult.verdict;
|
|
116
|
+
if (verdict === "Approved") {
|
|
117
|
+
writeResult({
|
|
118
|
+
mode: "refused",
|
|
119
|
+
code_max: codeMax,
|
|
120
|
+
rev_max: revMax,
|
|
121
|
+
verdict,
|
|
122
|
+
next_round: null,
|
|
123
|
+
next_artifact: null,
|
|
124
|
+
review_artifact: reviewArtifact,
|
|
125
|
+
message: `Latest ${reviewArtifact} verdict is Approved with no findings. Nothing to fix. Run /commit to proceed.`
|
|
126
|
+
}, 1);
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
if (verdict === "Rejected") {
|
|
131
|
+
writeResult({
|
|
132
|
+
mode: "refused",
|
|
133
|
+
code_max: codeMax,
|
|
134
|
+
rev_max: revMax,
|
|
135
|
+
verdict,
|
|
136
|
+
next_round: null,
|
|
137
|
+
next_artifact: null,
|
|
138
|
+
review_artifact: reviewArtifact,
|
|
139
|
+
message: `Latest ${reviewArtifact} verdict is Rejected. This requires a fresh implementation strategy; re-plan or discuss with maintainers before re-running /code-task ${taskId}.`
|
|
140
|
+
}, 1);
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const nextRound = codeMax + 1;
|
|
145
|
+
const nextArtifact = artifactName("code", nextRound);
|
|
146
|
+
const optional = verdict === "Approved-with-issues";
|
|
147
|
+
writeResult({
|
|
148
|
+
mode: "fix",
|
|
149
|
+
code_max: codeMax,
|
|
150
|
+
rev_max: revMax,
|
|
151
|
+
verdict,
|
|
152
|
+
next_round: nextRound,
|
|
153
|
+
next_artifact: nextArtifact,
|
|
154
|
+
review_artifact: reviewArtifact,
|
|
155
|
+
message: optional
|
|
156
|
+
? `Latest ${reviewArtifact} approved with non-blocking findings. Entering optional fix mode (round ${nextRound} -> ${nextArtifact}).`
|
|
157
|
+
: `Latest ${reviewArtifact} requests changes. Entering required fix mode (round ${nextRound} -> ${nextArtifact}).`
|
|
158
|
+
}, 0);
|
|
159
|
+
} catch (error) {
|
|
160
|
+
writeResult({
|
|
161
|
+
mode: "error",
|
|
162
|
+
code_max: 0,
|
|
163
|
+
rev_max: 0,
|
|
164
|
+
verdict: null,
|
|
165
|
+
next_round: null,
|
|
166
|
+
next_artifact: null,
|
|
167
|
+
review_artifact: null,
|
|
168
|
+
message: `Mode detection failed: ${error instanceof Error ? error.message : String(error)}`
|
|
169
|
+
}, 2);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
function maxRound(entries, stem) {
|
|
174
|
+
let max = 0;
|
|
175
|
+
for (const entry of entries) {
|
|
176
|
+
if (entry === `${stem}.md`) {
|
|
177
|
+
max = Math.max(max, 1);
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
const match = entry.match(new RegExp(`^${escapeRegExp(stem)}-r(\\d+)\\.md$`));
|
|
182
|
+
if (match) {
|
|
183
|
+
max = Math.max(max, Number(match[1]));
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
return max;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
function artifactName(stem, round) {
|
|
190
|
+
return round === 1 ? `${stem}.md` : `${stem}-r${round}.md`;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function checkPlanAheadOfCode({ resolvedTaskDir, codeMax, planMax, reviewPlanMax }) {
|
|
194
|
+
if (planMax === 0 || reviewPlanMax === 0) {
|
|
195
|
+
return { replan: false };
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// plan 和 review-plan 轮次独立递增(plan-r5 可被 review-plan-r4 批准),不能假设同号。
|
|
199
|
+
// 用最新 review-plan 产物的「审查输入」/「Review Input」段落里引用的 plan 文件名
|
|
200
|
+
// 作为真正被批准的 plan;若该 plan 文件名不等于目录里最新 plan-rN.md,
|
|
201
|
+
// 说明最新 plan 还未被审查,不触发 replan。
|
|
202
|
+
const reviewPlanArtifact = artifactName("review-plan", reviewPlanMax);
|
|
203
|
+
const reviewPlanPath = path.join(resolvedTaskDir, reviewPlanArtifact);
|
|
204
|
+
if (!fs.existsSync(reviewPlanPath)) {
|
|
205
|
+
return { replan: false };
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
const reviewedPlan = parseReviewedPlan(reviewPlanPath);
|
|
209
|
+
if (!reviewedPlan) {
|
|
210
|
+
return { replan: false };
|
|
211
|
+
}
|
|
212
|
+
const latestPlanArtifact = artifactName("plan", planMax);
|
|
213
|
+
if (reviewedPlan !== latestPlanArtifact) {
|
|
214
|
+
return { replan: false };
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// review-plan 的「通过 + 主要/次要建议」(Approved-with-issues)仍是已批准,
|
|
218
|
+
// 区别于 review-code(Approved-with-issues 触发 optional fix)。replan 检测对
|
|
219
|
+
// review-plan 放宽到 Approved + Approved-with-issues 二者均放行。
|
|
220
|
+
const APPROVED_PLAN_VERDICTS = new Set(["Approved", "Approved-with-issues"]);
|
|
221
|
+
const reviewVerdict = parseVerdict(reviewPlanPath);
|
|
222
|
+
if (!reviewVerdict.ok || !APPROVED_PLAN_VERDICTS.has(reviewVerdict.verdict)) {
|
|
223
|
+
return { replan: false };
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
const codeArtifact = artifactName("code", codeMax);
|
|
227
|
+
const codeStat = safeStat(path.join(resolvedTaskDir, codeArtifact));
|
|
228
|
+
const reviewPlanStat = safeStat(reviewPlanPath);
|
|
229
|
+
if (!codeStat || !reviewPlanStat) {
|
|
230
|
+
return { replan: false };
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// 严格 `>`:同秒回退到既有 7 分支逻辑(保守,参见 plan-r5.md Q2 决议)
|
|
234
|
+
if (reviewPlanStat.mtimeMs > codeStat.mtimeMs) {
|
|
235
|
+
return { replan: true, reviewPlanArtifact };
|
|
236
|
+
}
|
|
237
|
+
return { replan: false };
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
function parseReviewedPlan(reviewPlanPath) {
|
|
241
|
+
let content;
|
|
242
|
+
try {
|
|
243
|
+
content = fs.readFileSync(reviewPlanPath, "utf8");
|
|
244
|
+
} catch {
|
|
245
|
+
return null;
|
|
246
|
+
}
|
|
247
|
+
const lines = content.split(/\r?\n/);
|
|
248
|
+
const headerPattern = /^[-*]\s*\*\*(?:审查输入|Review Input)\*\*[::]/;
|
|
249
|
+
const planFilePattern = /`(plan(?:-r\d+)?\.md)`/;
|
|
250
|
+
let inHeader = false;
|
|
251
|
+
for (const line of lines) {
|
|
252
|
+
if (headerPattern.test(line)) {
|
|
253
|
+
inHeader = true;
|
|
254
|
+
const inline = line.match(planFilePattern);
|
|
255
|
+
if (inline) return inline[1];
|
|
256
|
+
continue;
|
|
257
|
+
}
|
|
258
|
+
if (!inHeader) continue;
|
|
259
|
+
if (/^\s*[-*]\s/.test(line)) {
|
|
260
|
+
const match = line.match(planFilePattern);
|
|
261
|
+
if (match) return match[1];
|
|
262
|
+
continue;
|
|
263
|
+
}
|
|
264
|
+
if (line.trim() === "") continue;
|
|
265
|
+
break;
|
|
266
|
+
}
|
|
267
|
+
return null;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
function safeStat(filePath) {
|
|
271
|
+
try {
|
|
272
|
+
return fs.statSync(filePath);
|
|
273
|
+
} catch {
|
|
274
|
+
return null;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
function parseVerdict(reviewPath) {
|
|
279
|
+
if (!fs.existsSync(reviewPath)) {
|
|
280
|
+
return { ok: false, verdict: null, message: `Review artifact not found: ${path.basename(reviewPath)}` };
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
const content = fs.readFileSync(reviewPath, "utf8");
|
|
284
|
+
const summary = extractSection(content, ["审查摘要", "Review Summary"]);
|
|
285
|
+
const fileName = path.basename(reviewPath);
|
|
286
|
+
if (!summary) {
|
|
287
|
+
return { ok: false, verdict: null, message: `cannot locate review summary section in ${fileName}` };
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
const verdictMatch = summary.match(/^[-*]?\s*\*\*(?:总体结论|Overall Verdict)\*\*[::]\s*(.+?)\s*$/im);
|
|
291
|
+
if (!verdictMatch) {
|
|
292
|
+
return { ok: false, verdict: null, message: `cannot parse verdict in ${fileName}` };
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
const verdict = normalizeVerdict(verdictMatch[1]);
|
|
296
|
+
if (!verdict) {
|
|
297
|
+
return {
|
|
298
|
+
ok: false,
|
|
299
|
+
verdict: null,
|
|
300
|
+
message: `unrecognized verdict '${verdictMatch[1].trim()}' in ${fileName}`
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
if (verdict !== "Approved") {
|
|
305
|
+
return { ok: true, verdict };
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
const findingsMatch = summary.match(/^[-*]?\s*\*\*(?:发现(AI 可处理)|Findings \(AI-actionable\))\*\*[::]\s*(.+?)\s*$/im);
|
|
309
|
+
if (!findingsMatch) {
|
|
310
|
+
return { ok: false, verdict, message: `cannot parse findings count in ${fileName}` };
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
const counts = findingsMatch[1].match(/(\d+)\s*(?:阻塞项|blockers?).*?(\d+)\s*(?:主要|majors?).*?(\d+)\s*(?:次要|minors?)/i);
|
|
314
|
+
if (!counts) {
|
|
315
|
+
return { ok: false, verdict, message: `cannot parse findings count in ${fileName}` };
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
const [, blockers, majors, minors] = counts.map(Number);
|
|
319
|
+
return {
|
|
320
|
+
ok: true,
|
|
321
|
+
verdict: blockers === 0 && majors === 0 && minors === 0 ? "Approved" : "Approved-with-issues"
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
function normalizeVerdict(raw) {
|
|
326
|
+
const value = String(raw).trim().toLowerCase();
|
|
327
|
+
if (value === "通过" || value === "approved") {
|
|
328
|
+
return "Approved";
|
|
329
|
+
}
|
|
330
|
+
if (value === "需要修改" || value === "changes requested") {
|
|
331
|
+
return "Changes Requested";
|
|
332
|
+
}
|
|
333
|
+
if (value === "拒绝" || value === "rejected") {
|
|
334
|
+
return "Rejected";
|
|
335
|
+
}
|
|
336
|
+
return "";
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
function extractSection(content, names) {
|
|
340
|
+
const lines = content.split(/\r?\n/);
|
|
341
|
+
const nameSet = new Set(names);
|
|
342
|
+
const start = lines.findIndex((line) => {
|
|
343
|
+
const match = line.trim().match(/^##\s+(.+?)\s*$/);
|
|
344
|
+
return match ? nameSet.has(match[1]) : false;
|
|
345
|
+
});
|
|
346
|
+
|
|
347
|
+
if (start === -1) {
|
|
348
|
+
return "";
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
const sectionLines = [];
|
|
352
|
+
for (let index = start + 1; index < lines.length; index += 1) {
|
|
353
|
+
if (/^##\s+/.test(lines[index])) {
|
|
354
|
+
break;
|
|
355
|
+
}
|
|
356
|
+
sectionLines.push(lines[index]);
|
|
357
|
+
}
|
|
358
|
+
return sectionLines.join("\n");
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
function writeResult(result, code) {
|
|
362
|
+
process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
|
|
363
|
+
process.exitCode = code;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
function escapeRegExp(value) {
|
|
367
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
main();
|
|
@@ -59,8 +59,8 @@ date "+%Y-%m-%d %H:%M:%S%:z"
|
|
|
59
59
|
Append the Commit Activity Log entry and choose exactly one next-step case:
|
|
60
60
|
- final commit -> `complete-task {task-id}`
|
|
61
61
|
- more work remains -> update task.md and stop
|
|
62
|
-
- ready for review -> `review-
|
|
63
|
-
- ready for PR -> `create-pr`
|
|
62
|
+
- ready for review -> `review-code {task-id}`
|
|
63
|
+
- ready for PR (only when the project enables the PR flow, i.e. `requiresPullRequest !== false`) -> `create-pr`
|
|
64
64
|
|
|
65
65
|
## 6. Sync Issue Metadata When Applicable
|
|
66
66
|
|
|
@@ -59,8 +59,8 @@ date "+%Y-%m-%d %H:%M:%S%:z"
|
|
|
59
59
|
追加 Commit 的 Activity Log,并且只能选择一个下一步分支:
|
|
60
60
|
- 最终提交 -> `complete-task {task-id}`
|
|
61
61
|
- 还有后续工作 -> 更新 task.md 后停止
|
|
62
|
-
- 准备审查 -> `review-
|
|
63
|
-
- 准备创建 PR
|
|
62
|
+
- 准备审查 -> `review-code {task-id}`
|
|
63
|
+
- 准备创建 PR(仅项目启用 PR 流程,即 `requiresPullRequest !== false`)-> `create-pr`
|
|
64
64
|
|
|
65
65
|
## 6. 同步 Issue 元数据(按需)
|
|
66
66
|
|
|
@@ -20,9 +20,11 @@ For every task-related commit, append this Activity Log entry in `task.md`:
|
|
|
20
20
|
|
|
21
21
|
Before selecting the next step, verify:
|
|
22
22
|
- `current_step` and the latest workflow progress in `task.md`
|
|
23
|
-
- whether the latest `review.md` / `review-r{N}.md` passed without findings
|
|
23
|
+
- whether the latest `review-code.md` / `review-code-r{N}.md` passed without findings
|
|
24
24
|
- whether there are still pending fixes, review work, or PR creation steps
|
|
25
25
|
|
|
26
|
+
**Gate read (project-level PR flow policy)**: Before running this step, read `.agents/.airc.json`'s `requiresPullRequest` field. Treat missing or `true` as "PR flow enabled" (default); treat explicit `false` as "PR flow disabled". All branches that depend on this field follow the same rule.
|
|
27
|
+
|
|
26
28
|
Choose exactly one case:
|
|
27
29
|
|
|
28
30
|
| Decision Basis | Required Case |
|
|
@@ -30,17 +32,19 @@ Choose exactly one case:
|
|
|
30
32
|
| all workflow steps completed + latest review approved with no findings + all tests passed | Case 1: final commit |
|
|
31
33
|
| unfinished steps, pending fixes, or waiting on others still exist | Case 2: more work remains |
|
|
32
34
|
| this commit prepares the task for code review | Case 3: ready for review |
|
|
33
|
-
| code is committed, review is done, and the
|
|
35
|
+
| code is committed, review is done, **and the project enables the PR flow**, with PR creation as the next step | Case 4: ready for PR |
|
|
34
36
|
|
|
35
37
|
Never apply more than one case. Match the single next-step branch first, then update the task.
|
|
36
38
|
|
|
39
|
+
**Gate downgrade**: When `requiresPullRequest === false`, Case 4 must never be entered; commits that would otherwise fall into Case 4 collapse into Case 1 (final commit -> `/complete-task`).
|
|
40
|
+
|
|
37
41
|
### Case 1: Final Commit
|
|
38
42
|
|
|
39
43
|
Prerequisites:
|
|
40
44
|
- [ ] all code committed
|
|
41
45
|
- [ ] all tests passed
|
|
42
46
|
- [ ] code review approved
|
|
43
|
-
- [ ] all workflow steps completed
|
|
47
|
+
- [ ] all workflow steps completed (for the `pr_tasks` list under each yaml `commit` step, count those items toward completion only when `requiresPullRequest !== false`)
|
|
44
48
|
|
|
45
49
|
Required next-step commands:
|
|
46
50
|
|
|
@@ -71,9 +75,9 @@ Required next-step commands:
|
|
|
71
75
|
|
|
72
76
|
```text
|
|
73
77
|
Next step - code review:
|
|
74
|
-
- Claude Code / OpenCode: /review-
|
|
75
|
-
- Gemini CLI: /agent-infra:review-
|
|
76
|
-
- Codex CLI: $review-
|
|
78
|
+
- Claude Code / OpenCode: /review-code {task-id}
|
|
79
|
+
- Gemini CLI: /agent-infra:review-code {task-id}
|
|
80
|
+
- Codex CLI: $review-code {task-id}
|
|
77
81
|
```
|
|
78
82
|
|
|
79
83
|
### Case 4: Ready for PR
|
|
@@ -20,9 +20,11 @@ date "+%Y-%m-%d %H:%M:%S%:z"
|
|
|
20
20
|
|
|
21
21
|
在决定下一步之前,先确认:
|
|
22
22
|
- `task.md` 中的 `current_step` 和最新工作流进度
|
|
23
|
-
- 最新的 `review.md` / `review-r{N}.md` 是否无问题通过
|
|
23
|
+
- 最新的 `review-code.md` / `review-code-r{N}.md` 是否无问题通过
|
|
24
24
|
- 是否仍然存在待修复项、待审查工作或待创建 PR 的步骤
|
|
25
25
|
|
|
26
|
+
**门控读取(项目级 PR 流程策略)**:在执行本步骤前,读取 `.agents/.airc.json` 的 `requiresPullRequest` 字段;当字段缺失或为 `true` 时视为「启用 PR 流程」(默认),仅当显式为 `false` 时视为「关闭 PR 流程」。所有依赖该字段的分支按此规则判定。
|
|
27
|
+
|
|
26
28
|
必须且只能选择一个分支:
|
|
27
29
|
|
|
28
30
|
| 判断依据 | 必选分支 |
|
|
@@ -30,17 +32,19 @@ date "+%Y-%m-%d %H:%M:%S%:z"
|
|
|
30
32
|
| 所有工作流步骤都已完成 + 最新审查无问题通过 + 所有测试通过 | 场景 1:最终提交 |
|
|
31
33
|
| 仍有未完成步骤、待修复项或等待他人的动作 | 场景 2:还有后续工作 |
|
|
32
34
|
| 这次提交是为了把任务交给代码审查 | 场景 3:准备进入审查 |
|
|
33
|
-
|
|
|
35
|
+
| 代码已提交、审查已完成,且**项目启用 PR 流程**,下一步是创建 PR | 场景 4:准备创建 PR |
|
|
34
36
|
|
|
35
37
|
绝对不要同时套用多个分支。先匹配唯一的下一步分支,再更新任务。
|
|
36
38
|
|
|
39
|
+
**门控降级**:当 `requiresPullRequest === false` 时,场景 4 永远不被进入;原本会落入场景 4 的提交统一收敛到场景 1(最终提交 → `/complete-task`)。
|
|
40
|
+
|
|
37
41
|
### 场景 1:最终提交
|
|
38
42
|
|
|
39
43
|
前置条件:
|
|
40
44
|
- [ ] 所有代码都已提交
|
|
41
45
|
- [ ] 所有测试通过
|
|
42
46
|
- [ ] 代码审查已通过
|
|
43
|
-
- [ ]
|
|
47
|
+
- [ ] 所有工作流步骤已完成(对 yaml `commit` 步骤的 `pr_tasks` 列表,仅在 `requiresPullRequest !== false` 时计入)
|
|
44
48
|
|
|
45
49
|
必带下一步命令:
|
|
46
50
|
|
|
@@ -71,9 +75,9 @@ date "+%Y-%m-%d %H:%M:%S%:z"
|
|
|
71
75
|
|
|
72
76
|
```text
|
|
73
77
|
下一步 - 代码审查:
|
|
74
|
-
- Claude Code / OpenCode: /review-
|
|
75
|
-
- Gemini CLI: /agent-infra:review-
|
|
76
|
-
- Codex CLI: $review-
|
|
78
|
+
- Claude Code / OpenCode: /review-code {task-id}
|
|
79
|
+
- Gemini CLI: /agent-infra:review-code {task-id}
|
|
80
|
+
- Codex CLI: $review-code {task-id}
|
|
77
81
|
```
|
|
78
82
|
|
|
79
83
|
### 场景 4:准备创建 PR
|
|
@@ -40,9 +40,11 @@ If not found in `active/`, check `blocked/` and `completed/`:
|
|
|
40
40
|
|
|
41
41
|
### 2. Verify Completion Prerequisites (Failure Must Stop)
|
|
42
42
|
|
|
43
|
+
**Gate read (project-level PR flow policy)**: Before running this step, read `.agents/.airc.json`'s `requiresPullRequest` field. Treat missing or `true` as "PR flow enabled" (default); treat explicit `false` as "PR flow disabled". The completion check below is pruned accordingly.
|
|
44
|
+
|
|
43
45
|
Before marking complete, verify ALL of these:
|
|
44
|
-
- [ ] All workflow steps are complete (check workflow progress in task.md)
|
|
45
|
-
- [ ] Code has been reviewed (`review.md` or `review-r{N}.md` exists, and the latest review verdict is Approved; or review was done externally)
|
|
46
|
+
- [ ] All workflow steps are complete (check workflow progress in task.md; **for the `pr_tasks` list under each yaml `commit` step, count those items toward the missing-work decision only when `.agents/.airc.json:requiresPullRequest !== false`**)
|
|
47
|
+
- [ ] Code has been reviewed (`review-code.md` or `review-code-r{N}.md` exists, and the latest review verdict is Approved; or review was done externally)
|
|
46
48
|
- [ ] Code has been committed (no uncommitted changes related to this task)
|
|
47
49
|
- [ ] Tests are passing
|
|
48
50
|
|
|
@@ -109,7 +111,7 @@ Check whether `task.md` includes a valid `issue_number`. If not, skip this step
|
|
|
109
111
|
> Issue sync rules live in `.agents/rules/issue-sync.md`. Read that file before syncing, and complete upstream repository detection plus permission detection.
|
|
110
112
|
|
|
111
113
|
If a valid `issue_number` exists:
|
|
112
|
-
- First scan and backfill unpublished `task.md`, `analysis*.md`, `
|
|
114
|
+
- First scan and backfill unpublished `task.md`, `analysis*.md`, `review-analysis*.md`, `plan*.md`, `review-plan*.md`, `code*.md`, and `review-code*.md` comments using the backfill rules in `.agents/rules/issue-sync.md` (`task.md` uses the idempotent update path)
|
|
113
115
|
- Backfill checked `## Requirements` items to the Issue body by following the requirements-checkbox sync steps in issue-sync.md
|
|
114
116
|
- Do not set any `status:` label — status labels are automatically cleared when the Issue is closed
|
|
115
117
|
- Finally create or update the summary comment marked with the summary marker defined in `.agents/rules/issue-sync.md`
|
|
@@ -40,9 +40,11 @@ tail .agents/workspace/active/{task-id}/task.md
|
|
|
40
40
|
|
|
41
41
|
### 2. 验证完成前置条件(未满足则必须停止)
|
|
42
42
|
|
|
43
|
+
**门控读取(项目级 PR 流程策略)**:在执行本步骤前,读取 `.agents/.airc.json` 的 `requiresPullRequest` 字段;当字段缺失或为 `true` 时视为「启用 PR 流程」(默认),仅当显式为 `false` 时视为「关闭 PR 流程」。下面的工作流步骤完成判定按此规则裁剪。
|
|
44
|
+
|
|
43
45
|
标记完成之前,验证以下所有条件:
|
|
44
|
-
- [ ] 所有工作流步骤已完成(检查 task.md
|
|
45
|
-
- [ ] 代码已审查(`review.md` 或 `review-r{N}.md` 存在,且最新审查结论为 Approved;或已在外部完成审查)
|
|
46
|
+
- [ ] 所有工作流步骤已完成(检查 task.md 中的工作流进度;**对 yaml 中 commit 步骤的 `pr_tasks` 列表,仅在 `.agents/.airc.json:requiresPullRequest !== false` 时计入未完成判定**)
|
|
47
|
+
- [ ] 代码已审查(`review-code.md` 或 `review-code-r{N}.md` 存在,且最新审查结论为 Approved;或已在外部完成审查)
|
|
46
48
|
- [ ] 代码已提交(没有与此任务相关的未提交变更)
|
|
47
49
|
- [ ] 测试通过
|
|
48
50
|
|
|
@@ -109,7 +111,7 @@ ls .agents/workspace/completed/{task-id}/task.md
|
|
|
109
111
|
> Issue 同步规则见 `.agents/rules/issue-sync.md`。执行同步前先读取该文件,完成 upstream 仓库检测和权限检测。
|
|
110
112
|
|
|
111
113
|
如果存在有效的 `issue_number`:
|
|
112
|
-
- 先按 `.agents/rules/issue-sync.md` 的补发规则扫描并补发未发布的 `task.md`、`analysis*.md`、`
|
|
114
|
+
- 先按 `.agents/rules/issue-sync.md` 的补发规则扫描并补发未发布的 `task.md`、`analysis*.md`、`review-analysis*.md`、`plan*.md`、`review-plan*.md`、`code*.md`、`review-code*.md` 评论(`task.md` 走幂等更新路径)
|
|
113
115
|
- 按 issue-sync.md 的需求复选框同步步骤,兜底同步 `## 需求` 中已勾选的条目到 Issue body
|
|
114
116
|
- 不要设置 `status:` label — Issue 关闭后 status label 会被自动清除
|
|
115
117
|
- 最后创建或更新 `.agents/rules/issue-sync.md` 中定义的 summary 评论标记对应的 summary 评论
|
|
@@ -13,6 +13,22 @@ Version stamp rule: when creating or updating `task.md` frontmatter, read `.agen
|
|
|
13
13
|
|
|
14
14
|
## Execution Flow
|
|
15
15
|
|
|
16
|
+
### Pre-gate: Project-level PR Flow Check
|
|
17
|
+
|
|
18
|
+
**Gate read (project-level PR flow policy)**: Before running any numbered step, read `.agents/.airc.json`'s `requiresPullRequest` field. Treat missing or `true` as "PR flow enabled" (default); treat explicit `false` as "PR flow disabled".
|
|
19
|
+
|
|
20
|
+
Branch on the result:
|
|
21
|
+
- missing / `true` -> continue to Step 1 below
|
|
22
|
+
- explicit `false` -> output the message below and **stop immediately**. Do not run any subsequent numbered step, do not trigger any PR-creation command, do not modify `pr_number` in `task.md`, and do not publish a PR summary comment:
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
This project does not enable the PR flow (`.agents/.airc.json` sets `requiresPullRequest: false`).
|
|
26
|
+
No Pull Request is required; run instead:
|
|
27
|
+
- Claude Code / OpenCode: /complete-task {task-id}
|
|
28
|
+
- Gemini CLI: /agent-infra:complete-task {task-id}
|
|
29
|
+
- Codex CLI: $complete-task {task-id}
|
|
30
|
+
```
|
|
31
|
+
|
|
16
32
|
### 1. Parse Command Arguments
|
|
17
33
|
|
|
18
34
|
Identify arguments from the command input:
|
|
@@ -57,7 +73,7 @@ For PRs where `{task-id}` is available, sync the core metadata immediately:
|
|
|
57
73
|
|
|
58
74
|
### 7. Publish the Review Summary
|
|
59
75
|
|
|
60
|
-
Read the latest context artifacts when they exist: `plan.md` / `plan-r{N}.md`, `
|
|
76
|
+
Read the latest context artifacts when they exist: `plan.md` / `plan-r{N}.md`, `review-plan.md` / `review-plan-r{N}.md`, `code.md` / `code-r{N}.md`, and `review-code.md` / `review-code-r{N}.md`.
|
|
61
77
|
|
|
62
78
|
Aggregate a reviewer-facing summary from those artifacts and maintain a single idempotent summary comment via the hidden marker.
|
|
63
79
|
|
|
@@ -13,6 +13,22 @@ description: "创建 Pull Request 到目标分支"
|
|
|
13
13
|
|
|
14
14
|
## 执行流程
|
|
15
15
|
|
|
16
|
+
### 前置门控:项目级 PR 流程检查
|
|
17
|
+
|
|
18
|
+
**门控读取(项目级 PR 流程策略)**:在执行编号步骤前,读取 `.agents/.airc.json` 的 `requiresPullRequest` 字段;当字段缺失或为 `true` 时视为「启用 PR 流程」(默认),仅当显式为 `false` 时视为「关闭 PR 流程」。
|
|
19
|
+
|
|
20
|
+
按读取结果分支:
|
|
21
|
+
- 缺失 / `true` → 继续到下方第 1 步
|
|
22
|
+
- 显式 `false` → 输出以下消息后**立即停止**,不要执行任何后续编号步骤、不要触发任何 PR 创建命令、不要修改 `task.md` 的 `pr_number`、不要发布 PR 摘要评论:
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
当前项目未启用 PR 流程(`.agents/.airc.json` 中 `requiresPullRequest: false`)。
|
|
26
|
+
无需创建 Pull Request,请直接运行:
|
|
27
|
+
- Claude Code / OpenCode:/complete-task {task-id}
|
|
28
|
+
- Gemini CLI:/agent-infra:complete-task {task-id}
|
|
29
|
+
- Codex CLI:$complete-task {task-id}
|
|
30
|
+
```
|
|
31
|
+
|
|
16
32
|
### 1. 解析命令参数
|
|
17
33
|
|
|
18
34
|
从命令参数中识别:
|
|
@@ -57,7 +73,7 @@ description: "创建 Pull Request 到目标分支"
|
|
|
57
73
|
|
|
58
74
|
### 7. 发布审查摘要
|
|
59
75
|
|
|
60
|
-
读取最新的上下文产物:`plan.md` / `plan-r{N}.md`、`
|
|
76
|
+
读取最新的上下文产物:`plan.md` / `plan-r{N}.md`、`review-plan.md` / `review-plan-r{N}.md`、`code.md` / `code-r{N}.md`、`review-code.md` / `review-code-r{N}.md`(存在时)。
|
|
61
77
|
|
|
62
78
|
基于这些产物聚合 reviewer 摘要,并使用隐藏标记维护唯一且幂等的摘要评论。
|
|
63
79
|
|
|
@@ -106,5 +106,5 @@ Next step:
|
|
|
106
106
|
## Error Handling
|
|
107
107
|
|
|
108
108
|
- Alert not found: output "Code Scanning alert #{number} not found"
|
|
109
|
-
- Alert already closed:
|
|
109
|
+
- Alert already closed: **proceed with task creation/reuse by default** and surface the alert's current state (dismissed/fixed) in the final notice; the user may archive the task manually if desired
|
|
110
110
|
- Network/permission error: output the corresponding error information
|
|
@@ -29,7 +29,7 @@ Extract key information:
|
|
|
29
29
|
### 2. Create the Task Directory and File
|
|
30
30
|
|
|
31
31
|
Check whether `.agents/workspace/active/` already has a task for this alert.
|
|
32
|
-
- If found, ask the user
|
|
32
|
+
- If found, **reuse the existing task by default**; do not ask the user. State clearly in the final notice: "Reused existing task `{task-id}`; not re-imported." If the user wants to re-import, they must first archive or delete the existing task
|
|
33
33
|
- If not found, create a new task
|
|
34
34
|
|
|
35
35
|
Create directory: `.agents/workspace/active/TASK-{yyyyMMdd-HHmmss}/`
|
|
@@ -110,5 +110,5 @@ Next step:
|
|
|
110
110
|
## Error Handling
|
|
111
111
|
|
|
112
112
|
- Alert not found: output "Security alert #{number} not found"
|
|
113
|
-
- Alert already closed:
|
|
113
|
+
- Alert already closed: **proceed with task creation/reuse by default** and surface the alert's current state (dismissed/fixed) in the final notice; the user may archive the task manually if desired
|
|
114
114
|
- Network/permission error: output the corresponding error information
|
|
@@ -29,7 +29,7 @@ description: "导入 Dependabot 安全告警并创建修复任务"
|
|
|
29
29
|
### 2. 创建任务目录和文件
|
|
30
30
|
|
|
31
31
|
检查 `.agents/workspace/active/` 中是否已存在该告警的任务。
|
|
32
|
-
-
|
|
32
|
+
- 如果找到,**默认复用现有任务**,不询问用户;在最终告知中明确「已复用现有任务 `{task-id}`,未重新导入」。如需重新导入,需先归档/删除已有任务
|
|
33
33
|
- 如果未找到,创建新任务
|
|
34
34
|
|
|
35
35
|
创建目录:`.agents/workspace/active/TASK-{yyyyMMdd-HHmmss}/`
|
|
@@ -110,5 +110,5 @@ node .agents/scripts/validate-artifact.js gate import-dependabot .agents/workspa
|
|
|
110
110
|
## 错误处理
|
|
111
111
|
|
|
112
112
|
- 告警未找到:提示 "Security alert #{number} not found"
|
|
113
|
-
-
|
|
113
|
+
- 告警已关闭:**默认仍继续创建/复用任务**,并在告知用户中明确该告警当前状态(dismissed/fixed);用户可视情况手动归档任务
|
|
114
114
|
- 网络/权限错误:提示相应信息
|