opencode-magi 0.0.0-dev-20260520165753 → 0.0.0-dev-20260520173258
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/config/resolve.js +29 -10
- package/dist/config/validate.js +42 -17
- package/dist/github/commands.js +98 -6
- package/dist/index.js +133 -24
- package/dist/orchestrator/findings.js +4 -3
- package/dist/orchestrator/report.js +8 -1
- package/dist/orchestrator/review-context.js +309 -0
- package/dist/orchestrator/review.js +26 -5
- package/dist/orchestrator/run-manager.js +5 -3
- package/dist/orchestrator/triage.js +151 -88
- package/dist/prompts/compose.js +28 -16
- package/dist/prompts/contracts.js +28 -16
- package/dist/prompts/output.js +36 -24
- package/dist/prompts/templates/review/review.md +6 -0
- package/dist/prompts/templates/triage/acceptance.md +7 -0
- package/dist/prompts/templates/triage/category.md +10 -0
- package/package.json +1 -1
- package/schema.json +16 -15
- package/dist/prompts/templates/triage/bug.md +0 -7
- package/dist/prompts/templates/triage/feature.md +0 -7
- package/dist/prompts/templates/triage/kind.md +0 -7
package/dist/prompts/output.js
CHANGED
|
@@ -71,6 +71,17 @@ function requireNumber(value, path) {
|
|
|
71
71
|
throw new Error(`${path} must be an integer`);
|
|
72
72
|
return value;
|
|
73
73
|
}
|
|
74
|
+
function parseRequirementFindings(value) {
|
|
75
|
+
return (value == null ? [] : requireArray(value, "requirementFindings")).map((finding, index) => {
|
|
76
|
+
const item = finding;
|
|
77
|
+
return {
|
|
78
|
+
evidence: requireString(item.evidence, `requirementFindings[${index}].evidence`),
|
|
79
|
+
fix: requireString(item.fix, `requirementFindings[${index}].fix`),
|
|
80
|
+
issueNumber: requireNumber(item.issueNumber, `requirementFindings[${index}].issueNumber`),
|
|
81
|
+
requirement: requireString(item.requirement, `requirementFindings[${index}].requirement`),
|
|
82
|
+
};
|
|
83
|
+
});
|
|
84
|
+
}
|
|
74
85
|
function requireOneOf(value, path, values) {
|
|
75
86
|
const text = requireString(value, path);
|
|
76
87
|
if (!values.includes(text)) {
|
|
@@ -93,18 +104,8 @@ export function parseTriageExistingPrOutput(text) {
|
|
|
93
104
|
"RELATED_PR_HANDLES_ISSUE",
|
|
94
105
|
]);
|
|
95
106
|
}
|
|
96
|
-
export function
|
|
97
|
-
return parseTriageVote(text, ["ASK",
|
|
98
|
-
}
|
|
99
|
-
export function parseTriageFinalOutput(text) {
|
|
100
|
-
return parseTriageVote(text, [
|
|
101
|
-
"ASK",
|
|
102
|
-
"BUG_ACCEPTED",
|
|
103
|
-
"BUG_REJECTED",
|
|
104
|
-
"DUPLICATE",
|
|
105
|
-
"FEATURE_ACCEPTED",
|
|
106
|
-
"FEATURE_REJECTED",
|
|
107
|
-
]);
|
|
107
|
+
export function parseTriageCategoryOutput(text, categories) {
|
|
108
|
+
return parseTriageVote(text, ["ASK", ...categories]);
|
|
108
109
|
}
|
|
109
110
|
export function parseTriageBinaryOutput(text) {
|
|
110
111
|
return parseTriageVote(text, ["ASK", "NO", "YES"]);
|
|
@@ -185,12 +186,17 @@ export function parseReviewOutput(text) {
|
|
|
185
186
|
: requireNumber(item.startLine, `findings[${index}].startLine`),
|
|
186
187
|
};
|
|
187
188
|
});
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
throw new Error("
|
|
192
|
-
if (data.verdict === "
|
|
193
|
-
|
|
189
|
+
const requirementFindings = parseRequirementFindings(data.requirementFindings);
|
|
190
|
+
if (data.verdict === "MERGE" &&
|
|
191
|
+
(findings.length || requirementFindings.length))
|
|
192
|
+
throw new Error("MERGE requires no findings or requirementFindings");
|
|
193
|
+
if (data.verdict === "CHANGES_REQUESTED" &&
|
|
194
|
+
!findings.length &&
|
|
195
|
+
!requirementFindings.length)
|
|
196
|
+
throw new Error("CHANGES_REQUESTED requires findings or requirementFindings");
|
|
197
|
+
if (data.verdict === "CLOSE" &&
|
|
198
|
+
(findings.length || requirementFindings.length))
|
|
199
|
+
throw new Error("CLOSE requires no findings or requirementFindings");
|
|
194
200
|
const reason = typeof data.reason === "string" && data.reason.trim()
|
|
195
201
|
? data.reason
|
|
196
202
|
: undefined;
|
|
@@ -199,6 +205,7 @@ export function parseReviewOutput(text) {
|
|
|
199
205
|
return {
|
|
200
206
|
findings,
|
|
201
207
|
reason,
|
|
208
|
+
requirementFindings,
|
|
202
209
|
verdict: data.verdict,
|
|
203
210
|
};
|
|
204
211
|
}
|
|
@@ -231,24 +238,29 @@ export function parseRereviewOutput(text) {
|
|
|
231
238
|
: requireNumber(value.startLine, `newFindings[${index}].startLine`),
|
|
232
239
|
};
|
|
233
240
|
});
|
|
234
|
-
|
|
235
|
-
|
|
241
|
+
const requirementFindings = parseRequirementFindings(data.requirementFindings);
|
|
242
|
+
if (data.verdict === "MERGE" &&
|
|
243
|
+
(followUps.length || newFindings.length || requirementFindings.length)) {
|
|
244
|
+
throw new Error("MERGE requires no followUps, newFindings, or requirementFindings");
|
|
236
245
|
}
|
|
237
|
-
if (data.verdict === "CLOSE" &&
|
|
238
|
-
|
|
246
|
+
if (data.verdict === "CLOSE" &&
|
|
247
|
+
(followUps.length || newFindings.length || requirementFindings.length)) {
|
|
248
|
+
throw new Error("CLOSE requires no followUps, newFindings, or requirementFindings");
|
|
239
249
|
}
|
|
240
250
|
if (data.verdict === "CLOSE" && !data.reason) {
|
|
241
251
|
throw new Error("CLOSE requires reason");
|
|
242
252
|
}
|
|
243
253
|
if (data.verdict === "CHANGES_REQUESTED" &&
|
|
244
254
|
!followUps.length &&
|
|
245
|
-
!newFindings.length
|
|
246
|
-
|
|
255
|
+
!newFindings.length &&
|
|
256
|
+
!requirementFindings.length) {
|
|
257
|
+
throw new Error("CHANGES_REQUESTED requires followUps, newFindings, or requirementFindings");
|
|
247
258
|
}
|
|
248
259
|
return {
|
|
249
260
|
followUps,
|
|
250
261
|
newFindings,
|
|
251
262
|
reason: data.reason == null ? undefined : requireString(data.reason, "reason"),
|
|
263
|
+
requirementFindings,
|
|
252
264
|
resolve,
|
|
253
265
|
verdict: data.verdict,
|
|
254
266
|
};
|
|
@@ -4,4 +4,10 @@ Review only the diff from {baseSha} to {headSha}.
|
|
|
4
4
|
Use: git -C {jsonEncodedWorktreePath} diff {baseSha}...{headSha}
|
|
5
5
|
Do not edit files or perform write operations.
|
|
6
6
|
|
|
7
|
+
This PR may include closing issue references.
|
|
8
|
+
For each closing issue, review whether the PR fully satisfies the issue body, acceptance criteria, required behavior, required tests, required documentation, and bounded issue comments.
|
|
9
|
+
Request changes if a closing issue requirement is missing, only documented, only schema-exposed, or not wired into runtime behavior.
|
|
10
|
+
Do not approve solely because the PR improves the codebase if it claims to close an issue that remains incomplete.
|
|
11
|
+
For referenced non-closing issues, use them as context only unless the PR body explicitly claims to complete them.
|
|
12
|
+
|
|
7
13
|
{ciFailureContextBlock}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
Evaluate issue #{issue} in {owner}/{repo} for the selected category.
|
|
2
|
+
|
|
3
|
+
Choose YES when the issue should be accepted for the project. Choose NO when it should be rejected, is not actionable, or is not appropriate for this project. Choose ASK when specific missing information is required before deciding.
|
|
4
|
+
|
|
5
|
+
<context>
|
|
6
|
+
{context}
|
|
7
|
+
</context>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
Classify issue #{issue} in {owner}/{repo}.
|
|
2
|
+
|
|
3
|
+
Choose ASK when more information is required to classify what should be done. Otherwise choose exactly one configured category ID.
|
|
4
|
+
|
|
5
|
+
Configured categories:
|
|
6
|
+
{categoryOptions}
|
|
7
|
+
|
|
8
|
+
<context>
|
|
9
|
+
{context}
|
|
10
|
+
</context>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-magi",
|
|
3
|
-
"version": "0.0.0-dev-
|
|
3
|
+
"version": "0.0.0-dev-20260520173258",
|
|
4
4
|
"description": "Multi-agent PR review and merge orchestration plugin for OpenCode.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Hirotomo Yamada <hirotomo.yamada@avap.co.jp>",
|
package/schema.json
CHANGED
|
@@ -194,9 +194,8 @@
|
|
|
194
194
|
"properties": {
|
|
195
195
|
"existingPr": { "type": "string" },
|
|
196
196
|
"duplicate": { "type": "string" },
|
|
197
|
-
"
|
|
198
|
-
"
|
|
199
|
-
"feature": { "type": "string" },
|
|
197
|
+
"category": { "type": "string" },
|
|
198
|
+
"acceptance": { "type": "string" },
|
|
200
199
|
"action": { "type": "string" },
|
|
201
200
|
"question": { "type": "string" },
|
|
202
201
|
"comment": { "type": "string" },
|
|
@@ -205,20 +204,19 @@
|
|
|
205
204
|
"createPr": { "type": "string" }
|
|
206
205
|
}
|
|
207
206
|
},
|
|
208
|
-
"
|
|
207
|
+
"triageCategory": {
|
|
209
208
|
"type": "object",
|
|
210
209
|
"additionalProperties": false,
|
|
210
|
+
"required": ["id"],
|
|
211
211
|
"properties": {
|
|
212
|
-
"
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
"bug": { "$ref": "#/$defs/triageKindRule" },
|
|
221
|
-
"feature": { "$ref": "#/$defs/triageKindRule" }
|
|
212
|
+
"id": {
|
|
213
|
+
"type": "string",
|
|
214
|
+
"pattern": "^[A-Za-z0-9_-]+$",
|
|
215
|
+
"not": { "enum": ["ASK", "none"] }
|
|
216
|
+
},
|
|
217
|
+
"labels": { "type": "array", "items": { "type": "string" } },
|
|
218
|
+
"types": { "type": "array", "items": { "type": "string" } },
|
|
219
|
+
"description": { "type": "string" }
|
|
222
220
|
}
|
|
223
221
|
},
|
|
224
222
|
"triageAutomation": {
|
|
@@ -308,7 +306,10 @@
|
|
|
308
306
|
"items": { "$ref": "#/$defs/triageAgent" }
|
|
309
307
|
},
|
|
310
308
|
"creator": { "$ref": "#/$defs/triageCreator" },
|
|
311
|
-
"
|
|
309
|
+
"categories": {
|
|
310
|
+
"type": "array",
|
|
311
|
+
"items": { "$ref": "#/$defs/triageCategory" }
|
|
312
|
+
},
|
|
312
313
|
"automation": { "$ref": "#/$defs/triageAutomation" },
|
|
313
314
|
"safety": { "$ref": "#/$defs/triageSafety" },
|
|
314
315
|
"concurrency": { "$ref": "#/$defs/triageConcurrency" },
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
Evaluate bug issue #{issue} in {owner}/{repo}.
|
|
2
|
-
|
|
3
|
-
Choose YES when the bug is reproduced or otherwise valid based on strong evidence. Choose NO when it is not reproduced, invalid, a misunderstanding, or not actionable as a bug. Choose ASK when specific missing information is required.
|
|
4
|
-
|
|
5
|
-
<context>
|
|
6
|
-
{context}
|
|
7
|
-
</context>
|