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.
@@ -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 parseTriageKindOutput(text) {
97
- return parseTriageVote(text, ["ASK", "BUG", "FEATURE"]);
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
- if (data.verdict === "MERGE" && findings.length)
189
- throw new Error("MERGE requires no findings");
190
- if (data.verdict === "CHANGES_REQUESTED" && !findings.length)
191
- throw new Error("CHANGES_REQUESTED requires findings");
192
- if (data.verdict === "CLOSE" && findings.length)
193
- throw new Error("CLOSE requires no findings");
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
- if (data.verdict === "MERGE" && (followUps.length || newFindings.length)) {
235
- throw new Error("MERGE requires no followUps or newFindings");
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" && (followUps.length || newFindings.length)) {
238
- throw new Error("CLOSE requires no followUps or newFindings");
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
- throw new Error("CHANGES_REQUESTED requires followUps or newFindings");
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-20260520165753",
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
- "kind": { "type": "string" },
198
- "bug": { "type": "string" },
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
- "triageKindRule": {
207
+ "triageCategory": {
209
208
  "type": "object",
210
209
  "additionalProperties": false,
210
+ "required": ["id"],
211
211
  "properties": {
212
- "label": { "type": "array", "items": { "type": "string" } },
213
- "type": { "type": "array", "items": { "type": "string" } }
214
- }
215
- },
216
- "triageKind": {
217
- "type": "object",
218
- "additionalProperties": false,
219
- "properties": {
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
- "kind": { "$ref": "#/$defs/triageKind" },
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>
@@ -1,7 +0,0 @@
1
- Evaluate feature issue #{issue} in {owner}/{repo}.
2
-
3
- Choose YES when the feature should be implemented. Choose NO when it should not be implemented for this project. Choose ASK when specific missing information is required.
4
-
5
- <context>
6
- {context}
7
- </context>
@@ -1,7 +0,0 @@
1
- Classify issue #{issue} in {owner}/{repo}.
2
-
3
- Choose BUG when it reports broken existing behavior. Choose FEATURE when it requests new behavior or enhancement. Choose ASK when more information is required to classify it.
4
-
5
- <context>
6
- {context}
7
- </context>