opencode-magi 0.9.0 → 0.11.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.
Files changed (126) hide show
  1. package/README.ja.md +254 -0
  2. package/README.md +37 -34
  3. package/dist/commands.js +11 -9
  4. package/dist/config/index.js +2 -0
  5. package/dist/config/resolve.js +120 -248
  6. package/dist/config/validate.js +103 -1100
  7. package/dist/constant.js +135 -0
  8. package/dist/graphql/index.generated.js +125 -0
  9. package/dist/graphql/index.js +49 -0
  10. package/dist/index.js +12 -800
  11. package/dist/magi.js +357 -0
  12. package/dist/permissions/common.json +22 -22
  13. package/dist/permissions/editor.json +12 -12
  14. package/dist/prompts/index.js +98 -0
  15. package/dist/prompts/merge/ci-classification/output-contract.md +22 -0
  16. package/dist/prompts/merge/ci-classification/task.md +10 -0
  17. package/dist/prompts/merge/ci-classification/validate.json +20 -0
  18. package/dist/prompts/merge/conflict/output-contract.md +12 -0
  19. package/dist/prompts/merge/conflict/task.md +9 -0
  20. package/dist/prompts/merge/conflict/validate.json +4 -0
  21. package/dist/prompts/merge/edit/output-contract.md +26 -0
  22. package/dist/prompts/merge/edit/task.md +10 -0
  23. package/dist/prompts/merge/edit/validate.json +60 -0
  24. package/dist/prompts/review/ci-classification/output-contract.md +21 -0
  25. package/dist/prompts/review/ci-classification/task.md +7 -0
  26. package/dist/prompts/review/ci-classification/validate.json +20 -0
  27. package/dist/prompts/review/close-reconsideration/output-contract.md +21 -0
  28. package/dist/prompts/review/close-reconsideration/task.md +6 -0
  29. package/dist/prompts/review/close-reconsideration/validate.json +44 -0
  30. package/dist/prompts/review/comment/output-contract.md +11 -0
  31. package/dist/prompts/review/comment/task.md +3 -0
  32. package/dist/prompts/review/comment/validate.json +8 -0
  33. package/dist/prompts/review/finding-validation/output-contract.md +25 -0
  34. package/dist/prompts/{templates/review/finding-validation.md → review/finding-validation/task.md} +2 -3
  35. package/dist/prompts/review/finding-validation/validate.json +21 -0
  36. package/dist/prompts/review/rereview/output-contract.md +30 -0
  37. package/dist/prompts/{templates/review/rereview.md → review/rereview/task.md} +8 -11
  38. package/dist/prompts/review/rereview/validate.json +87 -0
  39. package/dist/prompts/review/review/output-contract.md +25 -0
  40. package/dist/prompts/{templates/review/review.md → review/review/task.md} +2 -5
  41. package/dist/prompts/review/review/validate.json +54 -0
  42. package/dist/prompts/triage/acceptance/output-contract.md +16 -0
  43. package/dist/prompts/triage/acceptance/validate.json +23 -0
  44. package/dist/prompts/triage/category/output-contract.md +16 -0
  45. package/dist/prompts/triage/category/validate.json +23 -0
  46. package/dist/prompts/triage/comment-classification/output-contract.md +15 -0
  47. package/dist/prompts/triage/comment-classification/validate.json +28 -0
  48. package/dist/prompts/triage/create/output-contract.md +28 -0
  49. package/dist/prompts/triage/create/validate.json +73 -0
  50. package/dist/prompts/triage/deplicate/output-contract.md +16 -0
  51. package/dist/prompts/triage/deplicate/validate.json +20 -0
  52. package/dist/prompts/triage/existing/output-contract.md +16 -0
  53. package/dist/prompts/triage/existing/validate.json +13 -0
  54. package/dist/prompts/triage/reconsider/output-contract.md +16 -0
  55. package/dist/prompts/triage/reconsider/validate.json +23 -0
  56. package/dist/prompts/triage/signal/output-contract.md +19 -0
  57. package/dist/prompts/triage/signal/validate.json +18 -0
  58. package/dist/tools/clear/index.js +21 -0
  59. package/dist/tools/index.js +12 -0
  60. package/dist/tools/merge/action.js +47 -0
  61. package/dist/tools/merge/context.js +118 -0
  62. package/dist/tools/merge/editor.js +264 -0
  63. package/dist/tools/merge/index.js +151 -0
  64. package/dist/tools/merge/index.type.js +1 -0
  65. package/dist/tools/merge/merge.js +42 -0
  66. package/dist/tools/merge/report.js +73 -0
  67. package/dist/tools/review/action.js +429 -0
  68. package/dist/tools/review/check.js +295 -0
  69. package/dist/tools/review/context.js +258 -0
  70. package/dist/tools/review/index.js +104 -0
  71. package/dist/tools/review/index.type.js +1 -0
  72. package/dist/tools/review/report.js +143 -0
  73. package/dist/tools/review/review.js +145 -0
  74. package/dist/tools/review/reviewer.js +409 -0
  75. package/dist/tools/triage/index.js +16 -0
  76. package/dist/tools/validate/index.js +28 -0
  77. package/dist/utils/array.js +6 -0
  78. package/dist/utils/assertion.js +38 -0
  79. package/dist/utils/exec.js +14 -0
  80. package/dist/utils/fs.js +24 -0
  81. package/dist/utils/function.js +37 -0
  82. package/dist/utils/github.js +63 -0
  83. package/dist/utils/index.js +10 -0
  84. package/dist/utils/index.type.js +1 -0
  85. package/dist/utils/object.js +21 -0
  86. package/dist/utils/opencode.js +25 -0
  87. package/dist/utils/string.js +38 -0
  88. package/dist/utils/worker.js +30 -0
  89. package/package.json +20 -8
  90. package/schema.json +9 -7
  91. package/dist/config/load.js +0 -62
  92. package/dist/config/output.js +0 -25
  93. package/dist/config/worktree.js +0 -25
  94. package/dist/github/commands.js +0 -905
  95. package/dist/github/retry.js +0 -44
  96. package/dist/orchestrator/abort.js +0 -9
  97. package/dist/orchestrator/ci.js +0 -579
  98. package/dist/orchestrator/findings.js +0 -88
  99. package/dist/orchestrator/inline-comments.js +0 -73
  100. package/dist/orchestrator/majority.js +0 -62
  101. package/dist/orchestrator/merge.js +0 -1260
  102. package/dist/orchestrator/model.js +0 -216
  103. package/dist/orchestrator/pool.js +0 -15
  104. package/dist/orchestrator/report.js +0 -175
  105. package/dist/orchestrator/review-context.js +0 -342
  106. package/dist/orchestrator/review.js +0 -1478
  107. package/dist/orchestrator/run-manager.js +0 -2132
  108. package/dist/orchestrator/safety.js +0 -44
  109. package/dist/orchestrator/triage.js +0 -1370
  110. package/dist/prompts/compose.js +0 -473
  111. package/dist/prompts/contracts.js +0 -300
  112. package/dist/prompts/output.js +0 -401
  113. package/dist/prompts/templates/merge/ci-classification.md +0 -16
  114. package/dist/prompts/templates/merge/conflict.md +0 -10
  115. package/dist/prompts/templates/merge/edit.md +0 -15
  116. package/dist/prompts/templates/review/ci-classification.md +0 -9
  117. package/dist/prompts/templates/review/close-reconsideration.md +0 -6
  118. /package/dist/{types.js → config/index.type.js} +0 -0
  119. /package/dist/prompts/{templates/triage/acceptance.md → triage/acceptance/task.md} +0 -0
  120. /package/dist/prompts/{templates/triage/category.md → triage/category/task.md} +0 -0
  121. /package/dist/prompts/{templates/triage/comment-classification.md → triage/comment-classification/task.md} +0 -0
  122. /package/dist/prompts/{templates/triage/create.md → triage/create/task.md} +0 -0
  123. /package/dist/prompts/{templates/triage/duplicate.md → triage/deplicate/task.md} +0 -0
  124. /package/dist/prompts/{templates/triage/existing-pr.md → triage/existing/task.md} +0 -0
  125. /package/dist/prompts/{templates/triage/reconsider.md → triage/reconsider/task.md} +0 -0
  126. /package/dist/prompts/{templates/triage/signal.md → triage/signal/task.md} +0 -0
@@ -0,0 +1,60 @@
1
+ {
2
+ "type": "object",
3
+ "required": ["mode", "responses"],
4
+ "additionalProperties": false,
5
+ "properties": {
6
+ "mode": { "enum": ["EDITED", "REPLIED"] },
7
+ "commitSha": { "type": "string", "minLength": 1 },
8
+ "commitMessage": { "type": "string", "minLength": 1 },
9
+ "filesTouched": {
10
+ "type": "array",
11
+ "items": { "type": "string", "minLength": 1 }
12
+ },
13
+ "responses": {
14
+ "type": "array",
15
+ "items": {
16
+ "type": "object",
17
+ "required": ["commentId", "action", "body"],
18
+ "additionalProperties": false,
19
+ "properties": {
20
+ "commentId": { "type": "integer" },
21
+ "action": { "enum": ["FIXED", "DISAGREE", "ASK"] },
22
+ "body": { "type": "string", "minLength": 1 }
23
+ }
24
+ }
25
+ }
26
+ },
27
+ "allOf": [
28
+ {
29
+ "if": { "properties": { "mode": { "const": "EDITED" } } },
30
+ "then": {
31
+ "required": ["commitSha", "commitMessage", "filesTouched"],
32
+ "properties": {
33
+ "filesTouched": { "type": "array", "minItems": 1 },
34
+ "responses": { "type": "array", "minItems": 1 }
35
+ }
36
+ }
37
+ },
38
+ {
39
+ "if": { "properties": { "mode": { "const": "REPLIED" } } },
40
+ "then": {
41
+ "not": {
42
+ "anyOf": [
43
+ { "required": ["commitSha"] },
44
+ { "required": ["commitMessage"] }
45
+ ]
46
+ },
47
+ "properties": {
48
+ "filesTouched": { "type": "array", "maxItems": 0 },
49
+ "responses": {
50
+ "type": "array",
51
+ "minItems": 1,
52
+ "items": {
53
+ "properties": { "action": { "enum": ["DISAGREE", "ASK"] } }
54
+ }
55
+ }
56
+ }
57
+ }
58
+ }
59
+ ]
60
+ }
@@ -0,0 +1,21 @@
1
+ Return exactly one JSON object and nothing else. Do not wrap it in markdown.
2
+
3
+ ```json
4
+ {
5
+ "checks": [
6
+ {
7
+ "id": "exact failed check ID",
8
+ "classification": "SCOPE_IN" | "SCOPE_OUT",
9
+ "comment": "Short reason."
10
+ }
11
+ ]
12
+ }
13
+ ```
14
+
15
+ Rules:
16
+
17
+ - Return one item for every failed check.
18
+ - `"id"` is the ID of the failed check.
19
+ - `"SCOPE_IN"` means the failure should be treated as caused by the PR changes and passed to creator.
20
+ - `"SCOPE_OUT"` means the failure is likely flaky, external, or infrastructure-related and may be rerun.
21
+ - `"comment"` is a short reason for the classification.
@@ -0,0 +1,7 @@
1
+ Classify failed CI jobs for pull request #{pr} in {owner}/{repo}.
2
+ Decide whether each failure is caused by the PR changes or is likely flaky, external, or infrastructure-related.
3
+ The PR worktree is {worktreePath}.
4
+ Review only the diff from {baseSha} to {headSha}.
5
+ Use: git -C "{worktreePath}" diff {baseSha}...{headSha}
6
+
7
+ Failed checks with structured failure evidence are provided in `<failed_checks>`.
@@ -0,0 +1,20 @@
1
+ {
2
+ "type": "object",
3
+ "required": ["checks"],
4
+ "additionalProperties": false,
5
+ "properties": {
6
+ "checks": {
7
+ "type": "array",
8
+ "items": {
9
+ "type": "object",
10
+ "required": ["id", "classification", "comment"],
11
+ "additionalProperties": false,
12
+ "properties": {
13
+ "id": { "type": "string", "minLength": 1 },
14
+ "classification": { "enum": ["SCOPE_IN", "SCOPE_OUT"] },
15
+ "comment": { "type": "string", "minLength": 1 }
16
+ }
17
+ }
18
+ }
19
+ }
20
+ }
@@ -0,0 +1,21 @@
1
+ Return exactly one JSON object and nothing else. Do not wrap it in markdown.
2
+
3
+ ```json
4
+ {
5
+ "verdict": "APPROVED" | "CHANGES_REQUESTED",
6
+ "findings": [{ "path": "relative/path.ext", "line": 123, "startLine": 120, "body": "..." }],
7
+ "comment": "Required only for CHANGES_REQUESTED."
8
+ }
9
+ ```
10
+
11
+ Rules:
12
+
13
+ - `"verdict"` must be `"APPROVED"` or `"CHANGES_REQUESTED"`.
14
+ - `"APPROVED"` may omit `"findings"`. If present, it must be empty.
15
+ - `"APPROVED"` may omit `"comment"`. If present, it must be an empty string.
16
+ - `"CHANGES_REQUESTED"` requires `"comment"` and at least one `"finding"`.
17
+ - `"comment"` for `"CHANGES_REQUESTED"` must be a concise prose review summary, not a bullet list of findings.
18
+ - `"CLOSED"` is not allowed in this reconsideration step.
19
+ - `"line"` is required and must target a valid right-side line inside the PR diff hunk.
20
+ - `"startLine"` is optional and must also target a valid right-side line inside the same PR diff hunk range.
21
+ - Do not omit `"line"`. Do not create file-level or body-only findings.
@@ -0,0 +1,6 @@
1
+ You requested `"CLOSED"` for pull request #{pr} in {owner}/{repo}, but your `"CLOSED"` verdict was rejected by majority vote.
2
+ Reconsider your decision and choose `"APPROVED"` or `"CHANGES_REQUESTED"` instead.
3
+
4
+ Every finding must target a valid right-side line in the PR diff.
5
+ If the problem itself does not have an exact changed line, choose the nearest changed line that represents the cause, responsibility, missing implementation, or affected behavior. This includes but is not limited to missing validation, missing wiring, missing requirements, missing tests, missing documentation, affected configuration, or relevant call sites.
6
+ Do not omit line. Do not create file-level or body-only findings.
@@ -0,0 +1,44 @@
1
+ {
2
+ "type": "object",
3
+ "required": ["verdict"],
4
+ "additionalProperties": false,
5
+ "properties": {
6
+ "verdict": { "enum": ["APPROVED", "CHANGES_REQUESTED"] },
7
+ "findings": {
8
+ "type": "array",
9
+ "items": {
10
+ "type": "object",
11
+ "required": ["path", "line", "body"],
12
+ "additionalProperties": false,
13
+ "properties": {
14
+ "path": { "type": "string", "minLength": 1 },
15
+ "line": { "type": "integer" },
16
+ "startLine": { "type": "integer" },
17
+ "body": { "type": "string", "minLength": 1 }
18
+ }
19
+ }
20
+ },
21
+ "comment": { "type": "string" }
22
+ },
23
+ "allOf": [
24
+ {
25
+ "if": { "properties": { "verdict": { "const": "APPROVED" } } },
26
+ "then": {
27
+ "properties": {
28
+ "findings": { "type": "array", "maxItems": 0 },
29
+ "comment": { "const": "" }
30
+ }
31
+ }
32
+ },
33
+ {
34
+ "if": { "properties": { "verdict": { "const": "CHANGES_REQUESTED" } } },
35
+ "then": {
36
+ "required": ["comment", "findings"],
37
+ "properties": {
38
+ "findings": { "type": "array", "minItems": 1 },
39
+ "comment": { "type": "string", "minLength": 1 }
40
+ }
41
+ }
42
+ }
43
+ ]
44
+ }
@@ -0,0 +1,11 @@
1
+ Return exactly one JSON object and nothing else. Do not wrap it in markdown.
2
+
3
+ ```json
4
+ {
5
+ "comment": "Natural pull request review comment."
6
+ }
7
+ ```
8
+
9
+ Rules:
10
+
11
+ - `"comment"` must be natural prose suitable for posting as a pull request review body.
@@ -0,0 +1,3 @@
1
+ This pull request #{pr} in {owner}/{repo} was judged as `{verdict}`.
2
+
3
+ Summarize the JSON contents provided in `<contents>` into a natural review comment for posting this verdict. Do not repeat the individual findings; write a concise overall comment that explains the result.
@@ -0,0 +1,8 @@
1
+ {
2
+ "type": "object",
3
+ "required": ["comment"],
4
+ "additionalProperties": false,
5
+ "properties": {
6
+ "comment": { "type": "string", "minLength": 1 }
7
+ }
8
+ }
@@ -0,0 +1,25 @@
1
+ Return exactly one JSON object and nothing else. Do not wrap it in markdown.
2
+
3
+ ```json
4
+ {
5
+ "votes": [
6
+ {
7
+ "reviewer": "reviewer-key-that-authored-the-finding",
8
+ "index": 0,
9
+ "vote": "AGREE" | "DISAGREE",
10
+ "comment": "Short rationale."
11
+ }
12
+ ]
13
+ }
14
+ ```
15
+
16
+ Rules:
17
+
18
+ - `"votes"` must include one vote for every finding listed in the task.
19
+ - Do not vote on your own findings.
20
+ - `"reviewer"` is the reviewer key that authored the finding.
21
+ - `"index"` is the zero-based index of the finding in that reviewer's listed findings.
22
+ - `"vote"` must be `"AGREE"` or `"DISAGREE"`.
23
+ - `"AGREE"` means the finding should remain posted.
24
+ - `"DISAGREE"` means the finding should be discarded.
25
+ - `"comment"` is a short rationale for the vote.
@@ -1,7 +1,6 @@
1
1
  Validate review findings for pull request #{pr} in {owner}/{repo}.
2
2
  Use the existing review session context.
3
3
  Vote on whether each listed finding is a valid reason to request changes.
4
- Do not edit files or perform write operations.
4
+ Each finding's `body` contains the proposed review comment text.
5
5
 
6
- Findings to validate:
7
- {findings}
6
+ Findings to validate are provided in `<findings>`.
@@ -0,0 +1,21 @@
1
+ {
2
+ "type": "object",
3
+ "required": ["votes"],
4
+ "additionalProperties": false,
5
+ "properties": {
6
+ "votes": {
7
+ "type": "array",
8
+ "items": {
9
+ "type": "object",
10
+ "required": ["reviewer", "index", "vote", "comment"],
11
+ "additionalProperties": false,
12
+ "properties": {
13
+ "reviewer": { "type": "string", "minLength": 1 },
14
+ "index": { "type": "integer", "minimum": 0 },
15
+ "vote": { "enum": ["AGREE", "DISAGREE"] },
16
+ "comment": { "type": "string", "minLength": 1 }
17
+ }
18
+ }
19
+ }
20
+ }
21
+ }
@@ -0,0 +1,30 @@
1
+ Return exactly one JSON object and nothing else. Do not wrap it in markdown.
2
+
3
+ ```json
4
+ {
5
+ "verdict": "APPROVED" | "CHANGES_REQUESTED" | "CLOSED",
6
+ "resolves": [{ "commentId": 123, "threadId": "..." }],
7
+ "followUps": [{ "commentId": 123, "body": "..." }],
8
+ "newFindings": [{ "path": "relative/path.ext", "line": 123, "startLine": 120, "body": "..." }],
9
+ "comment": "Required for CHANGES_REQUESTED and CLOSED."
10
+ }
11
+ ```
12
+
13
+ Rules:
14
+
15
+ - `"verdict"` must be `"APPROVED"`, `"CHANGES_REQUESTED"`, or `"CLOSED"`.
16
+ - `"resolves"` contains threads that should be resolved because the issue is fixed or the user's explanation is acceptable.
17
+ - Each `"resolves"` item must use the exact `"commentId"` and `"threadId"` from `<unresolved_threads>`.
18
+ - Each `"followUps"` item must use a `"commentId"` from `<unresolved_threads>`.
19
+ - Omit `"resolves"` when no thread should be resolved.
20
+ - `"APPROVED"` may omit `"followUps"` and `"newFindings"`. If present, they must be empty.
21
+ - `"APPROVED"` may omit `"comment"`. If present, it must be an empty string.
22
+ - `"CHANGES_REQUESTED"` requires `"comment"` and at least one `"followUp"` or `"newFinding"`.
23
+ - `"comment"` for `"CHANGES_REQUESTED"` must be a concise prose review summary, not a bullet list of findings.
24
+ - `"CLOSED"` requires `"comment"` and may omit `"followUps"` and `"newFindings"`. If present, they must be empty.
25
+ - `"line"` is required and must target a valid right-side line inside the latest PR diff hunk.
26
+ - `"startLine"` is optional and must also target a valid right-side line inside the same latest PR diff hunk range.
27
+ - Omit `"startLine"` for single-line findings.
28
+ - Do not omit `"line"`. Do not create file-level or body-only findings.
29
+ - Missing closing-issue requirements must be normal newFindings anchored to the nearest responsible changed line.
30
+ - If the problem itself does not have an exact changed line, choose the nearest changed line that represents the cause, responsibility, missing implementation, or affected behavior. This includes but is not limited to missing validation, missing wiring, missing requirements, missing tests, missing documentation, affected configuration, or relevant call sites.
@@ -1,21 +1,18 @@
1
1
  Re-review pull request #{pr} for {owner}/{repo}.
2
2
  The PR worktree is {worktreePath}.
3
3
  Validate whether your unresolved comments are fixed in the diff from {previousHeadSha} to {headSha} and in the review thread conversation.
4
- Use: git -C {jsonEncodedWorktreePath} diff {previousHeadSha}...{headSha}
5
- Your unresolved threads are provided as JSON below.
6
- {unresolvedThreads}
4
+ Use: git -C "{worktreePath}" diff {previousHeadSha}...{headSha}
5
+ Your unresolved threads are provided in `<unresolved_threads>`.
6
+ All review threads are provided in `<review>` for context, but only your unresolved threads may be resolved or receive followUps.
7
7
 
8
8
  If there is no new commit, still reconsider the thread when a user replied after your latest comment.
9
- If you agree with the user's explanation or the code is fixed, resolve the thread.
10
- If you do not agree, reply in the same thread with a followUp explaining why the issue still needs changes and keep CHANGES_REQUESTED.
11
- Do not duplicate an existing unresolved thread as a newFinding. Use newFindings only for separate new issues.
9
+ If you agree with the user's explanation or the code is fixed, add the thread to `resolves`.
10
+ If you do not agree, reply in the same thread with a followUp explaining why the issue still needs changes and keep `"CHANGES_REQUESTED"`.
11
+ Do not duplicate an issue already raised in any review thread as a newFinding. Use newFindings only for separate new issues.
12
12
  Every newFinding must target a valid right-side line in the PR diff.
13
13
  If the problem itself does not have an exact changed line, choose the nearest changed line that represents the cause, responsibility, missing implementation, or affected behavior. This includes but is not limited to missing validation, missing wiring, missing requirements, missing tests, missing documentation, affected configuration, or relevant call sites.
14
14
  Do not omit line. Do not create file-level or body-only newFindings.
15
15
 
16
- If `<merge_conflict_context>` is present, treat unresolved merge conflicts as review findings. Request changes when a conflict makes the PR unsafe or impossible to merge, and prefer the provided `suggestedLine` when it is present.
16
+ If `<ci_failure>` is present, treat in-scope CI failures as review context. Request changes when a failure is caused by the PR and can be anchored to a changed line.
17
17
 
18
- {ciFailureContextBlock}
19
- Do not edit files or perform write operations.
20
-
21
- {previousReviewBlock}
18
+ Your previous review is provided in `<previous_review>`.
@@ -0,0 +1,87 @@
1
+ {
2
+ "type": "object",
3
+ "required": ["verdict"],
4
+ "additionalProperties": false,
5
+ "properties": {
6
+ "verdict": { "enum": ["APPROVED", "CHANGES_REQUESTED", "CLOSED"] },
7
+ "resolves": {
8
+ "type": "array",
9
+ "items": {
10
+ "type": "object",
11
+ "required": ["commentId", "threadId"],
12
+ "additionalProperties": false,
13
+ "properties": {
14
+ "commentId": { "type": "integer" },
15
+ "threadId": { "type": "string", "minLength": 1 }
16
+ }
17
+ }
18
+ },
19
+ "followUps": {
20
+ "type": "array",
21
+ "items": {
22
+ "type": "object",
23
+ "required": ["commentId", "body"],
24
+ "additionalProperties": false,
25
+ "properties": {
26
+ "commentId": { "type": "integer" },
27
+ "body": { "type": "string", "minLength": 1 }
28
+ }
29
+ }
30
+ },
31
+ "newFindings": {
32
+ "type": "array",
33
+ "items": {
34
+ "type": "object",
35
+ "required": ["path", "line", "body"],
36
+ "additionalProperties": false,
37
+ "properties": {
38
+ "path": { "type": "string", "minLength": 1 },
39
+ "line": { "type": "integer" },
40
+ "startLine": { "type": "integer" },
41
+ "body": { "type": "string", "minLength": 1 }
42
+ }
43
+ }
44
+ },
45
+ "comment": { "type": "string" }
46
+ },
47
+ "allOf": [
48
+ {
49
+ "if": { "properties": { "verdict": { "const": "APPROVED" } } },
50
+ "then": {
51
+ "properties": {
52
+ "followUps": { "type": "array", "maxItems": 0 },
53
+ "newFindings": { "type": "array", "maxItems": 0 },
54
+ "comment": { "const": "" }
55
+ }
56
+ }
57
+ },
58
+ {
59
+ "if": { "properties": { "verdict": { "const": "CHANGES_REQUESTED" } } },
60
+ "then": {
61
+ "required": ["comment"],
62
+ "anyOf": [
63
+ {
64
+ "required": ["followUps"],
65
+ "properties": { "followUps": { "type": "array", "minItems": 1 } }
66
+ },
67
+ {
68
+ "required": ["newFindings"],
69
+ "properties": { "newFindings": { "type": "array", "minItems": 1 } }
70
+ }
71
+ ],
72
+ "properties": { "comment": { "type": "string", "minLength": 1 } }
73
+ }
74
+ },
75
+ {
76
+ "if": { "properties": { "verdict": { "const": "CLOSED" } } },
77
+ "then": {
78
+ "required": ["comment"],
79
+ "properties": {
80
+ "followUps": { "type": "array", "maxItems": 0 },
81
+ "newFindings": { "type": "array", "maxItems": 0 },
82
+ "comment": { "type": "string", "minLength": 1 }
83
+ }
84
+ }
85
+ }
86
+ ]
87
+ }
@@ -0,0 +1,25 @@
1
+ Return exactly one JSON object and nothing else. Do not wrap it in markdown.
2
+
3
+ ```json
4
+ {
5
+ "verdict": "APPROVED" | "CHANGES_REQUESTED" | "CLOSED",
6
+ "findings": [{ "path": "relative/path.ext", "line": 123, "startLine": 120, "body": "..." }],
7
+ "comment": "Required for CHANGES_REQUESTED and CLOSED."
8
+ }
9
+ ```
10
+
11
+ Rules:
12
+
13
+ - `"verdict"` must be `"APPROVED"`, `"CHANGES_REQUESTED"`, or `"CLOSED"`.
14
+ - `"APPROVED"` may omit `"findings"`. If present, it must be empty.
15
+ - `"APPROVED"` may omit `"comment"`. If present, it must be an empty string.
16
+ - `"CHANGES_REQUESTED"` requires `"comment"` and at least one `"finding"`.
17
+ - `"comment"` for `"CHANGES_REQUESTED"` must be a concise prose review summary, not a bullet list of findings.
18
+ - `"CLOSED"` requires `"comment"` and may omit `"findings"`. If present, `"findings"` must be empty.
19
+ - `"path"` must be repository-relative.
20
+ - `"line"` is required and must target a valid right-side line inside the PR diff hunk.
21
+ - `"startLine"` is optional and must also target a valid right-side line inside the same PR diff hunk range.
22
+ - Omit `"startLine"` for single-line findings.
23
+ - Do not omit `"line"`. Do not create file-level or body-only findings.
24
+ - Missing closing-issue requirements must be normal findings anchored to the nearest responsible changed line.
25
+ - If the problem itself does not have an exact changed line, choose the nearest changed line that represents the cause, responsibility, missing implementation, or affected behavior. This includes but is not limited to missing validation, missing wiring, missing requirements, missing tests, missing documentation, affected configuration, or relevant call sites.
@@ -1,8 +1,7 @@
1
1
  Review pull request #{pr} for {owner}/{repo}.
2
2
  The PR worktree is {worktreePath}.
3
3
  Review only the diff from {baseSha} to {headSha}.
4
- Use: git -C {jsonEncodedWorktreePath} diff {baseSha}...{headSha}
5
- Do not edit files or perform write operations.
4
+ Use: git -C "{worktreePath}" diff {baseSha}...{headSha}
6
5
 
7
6
  This PR may include closing issue references.
8
7
  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.
@@ -14,6 +13,4 @@ Every finding must target a valid right-side line in the PR diff.
14
13
  If the problem itself does not have an exact changed line, choose the nearest changed line that represents the cause, responsibility, missing implementation, or affected behavior. This includes but is not limited to missing validation, missing wiring, missing requirements, missing tests, missing documentation, affected configuration, or relevant call sites.
15
14
  Do not omit line. Do not create file-level or body-only findings.
16
15
 
17
- If `<merge_conflict_context>` is present, treat unresolved merge conflicts as review findings. Request changes when a conflict makes the PR unsafe or impossible to merge, and prefer the provided `suggestedLine` when it is present.
18
-
19
- {ciFailureContextBlock}
16
+ If `<ci_failure>` is present, treat in-scope CI failures as review context. Request changes when a failure is caused by the PR and can be anchored to a changed line.
@@ -0,0 +1,54 @@
1
+ {
2
+ "type": "object",
3
+ "required": ["verdict"],
4
+ "additionalProperties": false,
5
+ "properties": {
6
+ "verdict": { "enum": ["APPROVED", "CHANGES_REQUESTED", "CLOSED"] },
7
+ "findings": {
8
+ "type": "array",
9
+ "items": {
10
+ "type": "object",
11
+ "required": ["path", "line", "body"],
12
+ "additionalProperties": false,
13
+ "properties": {
14
+ "path": { "type": "string", "minLength": 1 },
15
+ "line": { "type": "integer" },
16
+ "startLine": { "type": "integer" },
17
+ "body": { "type": "string", "minLength": 1 }
18
+ }
19
+ }
20
+ },
21
+ "comment": { "type": "string" }
22
+ },
23
+ "allOf": [
24
+ {
25
+ "if": { "properties": { "verdict": { "const": "APPROVED" } } },
26
+ "then": {
27
+ "properties": {
28
+ "findings": { "type": "array", "maxItems": 0 },
29
+ "comment": { "const": "" }
30
+ }
31
+ }
32
+ },
33
+ {
34
+ "if": { "properties": { "verdict": { "const": "CHANGES_REQUESTED" } } },
35
+ "then": {
36
+ "required": ["comment", "findings"],
37
+ "properties": {
38
+ "findings": { "type": "array", "minItems": 1 },
39
+ "comment": { "type": "string", "minLength": 1 }
40
+ }
41
+ }
42
+ },
43
+ {
44
+ "if": { "properties": { "verdict": { "const": "CLOSED" } } },
45
+ "then": {
46
+ "required": ["comment"],
47
+ "properties": {
48
+ "findings": { "type": "array", "maxItems": 0 },
49
+ "comment": { "type": "string", "minLength": 1 }
50
+ }
51
+ }
52
+ }
53
+ ]
54
+ }
@@ -0,0 +1,16 @@
1
+ Return exactly one JSON object and nothing else. Do not wrap it in markdown.
2
+
3
+ The object must match this shape:
4
+
5
+ ```json
6
+ {
7
+ "vote": "YES" | "NO" | "INVALID" | "ASK",
8
+ "reason": "Short rationale.",
9
+ "body": "Required only when vote is ASK. Public issue comment body asking for the missing information."
10
+ }
11
+ ```
12
+
13
+ Rules:
14
+
15
+ - body is required when vote is ASK and must be written for the issue author.
16
+ - Omit body when vote is not ASK.
@@ -0,0 +1,23 @@
1
+ {
2
+ "type": "object",
3
+ "required": ["vote", "reason"],
4
+ "additionalProperties": false,
5
+ "properties": {
6
+ "vote": { "enum": ["YES", "NO", "INVALID", "ASK"] },
7
+ "reason": { "type": "string", "minLength": 1 },
8
+ "body": { "type": "string", "minLength": 1 }
9
+ },
10
+ "allOf": [
11
+ {
12
+ "if": { "properties": { "vote": { "const": "ASK" } } },
13
+ "then": { "required": ["body"] }
14
+ },
15
+ {
16
+ "if": {
17
+ "properties": { "vote": { "not": { "const": "ASK" } } },
18
+ "required": ["vote"]
19
+ },
20
+ "then": { "not": { "required": ["body"] } }
21
+ }
22
+ ]
23
+ }
@@ -0,0 +1,16 @@
1
+ Return exactly one JSON object and nothing else. Do not wrap it in markdown.
2
+
3
+ The object must match this shape:
4
+
5
+ ```json
6
+ {
7
+ "vote": "ASK" or one of the configured category IDs,
8
+ "reason": "Short rationale.",
9
+ "body": "Required only when vote is ASK. Public issue comment body asking for the missing information."
10
+ }
11
+ ```
12
+
13
+ Rules:
14
+
15
+ - body is required when vote is ASK and must be written for the issue author.
16
+ - Omit body when vote is not ASK.
@@ -0,0 +1,23 @@
1
+ {
2
+ "type": "object",
3
+ "required": ["vote", "reason"],
4
+ "additionalProperties": false,
5
+ "properties": {
6
+ "vote": { "type": "string", "minLength": 1 },
7
+ "reason": { "type": "string", "minLength": 1 },
8
+ "body": { "type": "string", "minLength": 1 }
9
+ },
10
+ "allOf": [
11
+ {
12
+ "if": { "properties": { "vote": { "const": "ASK" } } },
13
+ "then": { "required": ["body"] }
14
+ },
15
+ {
16
+ "if": {
17
+ "properties": { "vote": { "not": { "const": "ASK" } } },
18
+ "required": ["vote"]
19
+ },
20
+ "then": { "not": { "required": ["body"] } }
21
+ }
22
+ ]
23
+ }
@@ -0,0 +1,15 @@
1
+ Return exactly one JSON object and nothing else. Do not wrap it in markdown.
2
+
3
+ The object must match this shape:
4
+
5
+ ```json
6
+ {
7
+ "comments": [
8
+ {
9
+ "commentId": 123,
10
+ "classification": "OBJECTION" | "NEW_EVIDENCE" | "CLARIFICATION" | "ACKNOWLEDGEMENT" | "UNRELATED",
11
+ "reason": "Short rationale."
12
+ }
13
+ ]
14
+ }
15
+ ```