@openhands/extensions 0.21.0 → 0.22.1

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 (267) hide show
  1. package/.claude-plugin/marketplace.json +881 -0
  2. package/.codex-plugin/marketplace.json +881 -0
  3. package/.github/workflows/npm-publish.yml +9 -3
  4. package/.plugin/marketplace.json +881 -0
  5. package/.release-please-manifest.json +1 -1
  6. package/README.md +3 -2
  7. package/automations/bundle-index.js +16 -7
  8. package/automations/catalog/github-delivery-watchdog/manifest.json +79 -0
  9. package/automations/catalog/github-issue-to-pr/manifest.json +23 -15
  10. package/automations/catalog/github-issue-triage/manifest.json +4 -3
  11. package/automations/catalog/github-pr-reviewer/manifest.json +22 -15
  12. package/automations/catalog-index.js +6 -4
  13. package/marketplaces/openhands-extensions.json +6 -0
  14. package/package.json +1 -1
  15. package/plugins/city-weather/.claude-plugin/plugin.json +13 -0
  16. package/plugins/city-weather/.codex-plugin/plugin.json +13 -0
  17. package/plugins/cobol-modernization/.claude-plugin/plugin.json +19 -0
  18. package/plugins/cobol-modernization/.codex-plugin/plugin.json +19 -0
  19. package/plugins/issue-duplicate-checker/.claude-plugin/plugin.json +13 -0
  20. package/plugins/issue-duplicate-checker/.codex-plugin/plugin.json +13 -0
  21. package/plugins/magic-test/.claude-plugin/plugin.json +13 -0
  22. package/plugins/magic-test/.codex-plugin/plugin.json +13 -0
  23. package/plugins/migration-scoring/.claude-plugin/plugin.json +19 -0
  24. package/plugins/migration-scoring/.codex-plugin/plugin.json +19 -0
  25. package/plugins/onboarding/.claude-plugin/plugin.json +20 -0
  26. package/plugins/onboarding/.codex-plugin/plugin.json +20 -0
  27. package/plugins/onboarding/skills/agent-readiness-report/references/criteria.md +144 -0
  28. package/plugins/onboarding/skills/improve-agent-readiness/references/criteria.md +144 -0
  29. package/plugins/openhands/.claude-plugin/plugin.json +13 -0
  30. package/plugins/openhands/.codex-plugin/plugin.json +13 -0
  31. package/plugins/openhands/skills/openhands-api/.claude-plugin/plugin.json +22 -0
  32. package/plugins/openhands/skills/openhands-api/.codex-plugin/plugin.json +22 -0
  33. package/plugins/openhands/skills/openhands-api/.plugin/plugin.json +22 -0
  34. package/plugins/openhands/skills/openhands-api/README.md +52 -0
  35. package/plugins/openhands/skills/openhands-api/SKILL.md +469 -0
  36. package/plugins/openhands/skills/openhands-api/references/README.md +33 -0
  37. package/plugins/openhands/skills/openhands-api/references/TROUBLESHOOTING.md +81 -0
  38. package/plugins/openhands/skills/openhands-api/references/example_prompt.md +12 -0
  39. package/plugins/openhands/skills/openhands-api/references/windows.md +44 -0
  40. package/plugins/openhands/skills/openhands-api/scripts/openhands_api.py +606 -0
  41. package/plugins/openhands/skills/openhands-api/scripts/openhands_api.ts +252 -0
  42. package/plugins/openhands/skills/openhands-automation/.claude-plugin/plugin.json +19 -0
  43. package/plugins/openhands/skills/openhands-automation/.codex-plugin/plugin.json +19 -0
  44. package/plugins/openhands/skills/openhands-automation/.plugin/plugin.json +19 -0
  45. package/plugins/openhands/skills/openhands-automation/README.md +89 -0
  46. package/plugins/openhands/skills/openhands-automation/SKILL.md +899 -0
  47. package/plugins/openhands/skills/openhands-automation/commands/automation-create.md +8 -0
  48. package/plugins/openhands/skills/openhands-automation/references/ab-testing.md +185 -0
  49. package/plugins/openhands/skills/openhands-automation/references/custom-automation.md +832 -0
  50. package/plugins/openhands/skills/openhands-automation/references/security.md +84 -0
  51. package/plugins/openhands/skills/openhands-automation/references/windows.md +57 -0
  52. package/plugins/openhands/skills/openhands-sdk/.claude-plugin/plugin.json +20 -0
  53. package/plugins/openhands/skills/openhands-sdk/.codex-plugin/plugin.json +20 -0
  54. package/plugins/openhands/skills/openhands-sdk/.plugin/plugin.json +20 -0
  55. package/plugins/openhands/skills/openhands-sdk/README.md +22 -0
  56. package/plugins/openhands/skills/openhands-sdk/SKILL.md +245 -0
  57. package/plugins/openhands/skills/openhands-sdk/commands/sdk.md +8 -0
  58. package/plugins/pr-review/.claude-plugin/plugin.json +13 -0
  59. package/plugins/pr-review/.codex-plugin/plugin.json +13 -0
  60. package/plugins/pr-review/skills/code-review/.claude-plugin/plugin.json +19 -0
  61. package/plugins/pr-review/skills/code-review/.codex-plugin/plugin.json +19 -0
  62. package/plugins/pr-review/skills/code-review/.plugin/plugin.json +19 -0
  63. package/plugins/pr-review/skills/code-review/README.md +18 -0
  64. package/plugins/pr-review/skills/code-review/SKILL.md +209 -0
  65. package/plugins/pr-review/skills/code-review/commands/codereview-roasted.md +8 -0
  66. package/plugins/pr-review/skills/code-review/commands/codereview.md +8 -0
  67. package/plugins/pr-review/skills/code-review/references/risk-evaluation.md +41 -0
  68. package/plugins/pr-review/skills/code-review/references/supply-chain-security.md +31 -0
  69. package/plugins/pr-review/skills/github-pr-review/.claude-plugin/plugin.json +18 -0
  70. package/plugins/pr-review/skills/github-pr-review/.codex-plugin/plugin.json +18 -0
  71. package/plugins/pr-review/skills/github-pr-review/.plugin/plugin.json +18 -0
  72. package/plugins/pr-review/skills/github-pr-review/README.md +145 -0
  73. package/plugins/pr-review/skills/github-pr-review/SKILL.md +187 -0
  74. package/plugins/pr-review/skills/github-pr-review/commands/github-pr-review.md +8 -0
  75. package/plugins/pr-review/skills/github-pr-review/references/windows.md +47 -0
  76. package/plugins/qa-changes/.claude-plugin/plugin.json +11 -0
  77. package/plugins/qa-changes/.codex-plugin/plugin.json +11 -0
  78. package/plugins/qa-changes/skills/github-pr-review/.claude-plugin/plugin.json +18 -0
  79. package/plugins/qa-changes/skills/github-pr-review/.codex-plugin/plugin.json +18 -0
  80. package/plugins/qa-changes/skills/github-pr-review/.plugin/plugin.json +18 -0
  81. package/plugins/qa-changes/skills/github-pr-review/README.md +145 -0
  82. package/plugins/qa-changes/skills/github-pr-review/SKILL.md +187 -0
  83. package/plugins/qa-changes/skills/github-pr-review/commands/github-pr-review.md +8 -0
  84. package/plugins/qa-changes/skills/github-pr-review/references/windows.md +47 -0
  85. package/plugins/qa-changes/skills/qa-changes/README.md +18 -0
  86. package/plugins/qa-changes/skills/qa-changes/SKILL.md +229 -0
  87. package/plugins/qa-changes/skills/qa-changes/commands/qa-changes.md +8 -0
  88. package/plugins/release-notes/.claude-plugin/plugin.json +19 -0
  89. package/plugins/release-notes/.codex-plugin/plugin.json +19 -0
  90. package/plugins/release-notes/skills/release-notes/README.md +24 -0
  91. package/plugins/release-notes/skills/release-notes/SKILL.md +19 -0
  92. package/plugins/release-notes/skills/release-notes/commands/release-notes.md +8 -0
  93. package/plugins/vulnerability-remediation/.claude-plugin/plugin.json +19 -0
  94. package/plugins/vulnerability-remediation/.codex-plugin/plugin.json +19 -0
  95. package/plugins/vulnerability-remediation/skills/github/.claude-plugin/plugin.json +19 -0
  96. package/plugins/vulnerability-remediation/skills/github/.codex-plugin/plugin.json +19 -0
  97. package/plugins/vulnerability-remediation/skills/github/.plugin/plugin.json +19 -0
  98. package/plugins/vulnerability-remediation/skills/github/README.md +42 -0
  99. package/plugins/vulnerability-remediation/skills/github/SKILL.md +107 -0
  100. package/plugins/vulnerability-remediation/skills/github/references/windows.md +48 -0
  101. package/plugins/vulnerability-remediation/skills/github/scripts/agent_conversation.py +150 -0
  102. package/plugins/vulnerability-remediation/skills/github/scripts/github_client.py +230 -0
  103. package/plugins/vulnerability-remediation/skills/security/.claude-plugin/plugin.json +18 -0
  104. package/plugins/vulnerability-remediation/skills/security/.codex-plugin/plugin.json +18 -0
  105. package/plugins/vulnerability-remediation/skills/security/.plugin/plugin.json +18 -0
  106. package/plugins/vulnerability-remediation/skills/security/README.md +38 -0
  107. package/plugins/vulnerability-remediation/skills/security/SKILL.md +33 -0
  108. package/pyproject.toml +1 -1
  109. package/python/openhands_extensions/_version.py +1 -1
  110. package/skills/add-javadoc/.claude-plugin/plugin.json +18 -0
  111. package/skills/add-javadoc/.codex-plugin/plugin.json +18 -0
  112. package/skills/add-skill/.claude-plugin/plugin.json +18 -0
  113. package/skills/add-skill/.codex-plugin/plugin.json +18 -0
  114. package/skills/agent-canvas-environment/.claude-plugin/plugin.json +19 -0
  115. package/skills/agent-canvas-environment/.codex-plugin/plugin.json +19 -0
  116. package/skills/agent-creator/.claude-plugin/plugin.json +20 -0
  117. package/skills/agent-creator/.codex-plugin/plugin.json +20 -0
  118. package/skills/agent-memory/.claude-plugin/plugin.json +18 -0
  119. package/skills/agent-memory/.codex-plugin/plugin.json +18 -0
  120. package/skills/agent-sdk-builder/.claude-plugin/plugin.json +18 -0
  121. package/skills/agent-sdk-builder/.codex-plugin/plugin.json +18 -0
  122. package/skills/azure-devops/.claude-plugin/plugin.json +18 -0
  123. package/skills/azure-devops/.codex-plugin/plugin.json +18 -0
  124. package/skills/bitbucket/.claude-plugin/plugin.json +17 -0
  125. package/skills/bitbucket/.codex-plugin/plugin.json +17 -0
  126. package/skills/bitbucket-cloud/.claude-plugin/plugin.json +18 -0
  127. package/skills/bitbucket-cloud/.codex-plugin/plugin.json +18 -0
  128. package/skills/bitbucket-data-center/.claude-plugin/plugin.json +19 -0
  129. package/skills/bitbucket-data-center/.codex-plugin/plugin.json +19 -0
  130. package/skills/code-review/.claude-plugin/plugin.json +19 -0
  131. package/skills/code-review/.codex-plugin/plugin.json +19 -0
  132. package/skills/code-simplifier/.claude-plugin/plugin.json +21 -0
  133. package/skills/code-simplifier/.codex-plugin/plugin.json +21 -0
  134. package/skills/datadog/.claude-plugin/plugin.json +19 -0
  135. package/skills/datadog/.codex-plugin/plugin.json +19 -0
  136. package/skills/deno/.claude-plugin/plugin.json +18 -0
  137. package/skills/deno/.codex-plugin/plugin.json +18 -0
  138. package/skills/discord/.claude-plugin/plugin.json +18 -0
  139. package/skills/discord/.codex-plugin/plugin.json +18 -0
  140. package/skills/docker/.claude-plugin/plugin.json +17 -0
  141. package/skills/docker/.codex-plugin/plugin.json +17 -0
  142. package/skills/evidence-based-citations/.claude-plugin/plugin.json +20 -0
  143. package/skills/evidence-based-citations/.codex-plugin/plugin.json +20 -0
  144. package/skills/flarglebargle/.claude-plugin/plugin.json +16 -0
  145. package/skills/flarglebargle/.codex-plugin/plugin.json +16 -0
  146. package/skills/frontend-design/.claude-plugin/plugin.json +21 -0
  147. package/skills/frontend-design/.codex-plugin/plugin.json +21 -0
  148. package/skills/github/.claude-plugin/plugin.json +19 -0
  149. package/skills/github/.codex-plugin/plugin.json +19 -0
  150. package/skills/github/scripts/agent_conversation.py +150 -0
  151. package/skills/github/scripts/github_client.py +31 -5
  152. package/skills/github-actions/.claude-plugin/plugin.json +19 -0
  153. package/skills/github-actions/.codex-plugin/plugin.json +19 -0
  154. package/skills/github-agents-md-maintainer/.claude-plugin/plugin.json +19 -0
  155. package/skills/github-agents-md-maintainer/.codex-plugin/plugin.json +19 -0
  156. package/skills/github-agents-md-maintainer/scripts/github_client.py +230 -0
  157. package/skills/github-delivery-watchdog/.claude-plugin/plugin.json +9 -0
  158. package/skills/github-delivery-watchdog/.codex-plugin/plugin.json +9 -0
  159. package/skills/github-delivery-watchdog/.plugin/plugin.json +9 -0
  160. package/skills/github-delivery-watchdog/README.md +10 -0
  161. package/skills/github-delivery-watchdog/SKILL.md +35 -0
  162. package/skills/github-delivery-watchdog/commands/github-delivery-watchdog.md +8 -0
  163. package/skills/github-delivery-watchdog/scripts/github_client.py +230 -0
  164. package/skills/github-delivery-watchdog/scripts/worker.py +96 -0
  165. package/skills/github-issue-to-pr/.claude-plugin/plugin.json +19 -0
  166. package/skills/github-issue-to-pr/.codex-plugin/plugin.json +19 -0
  167. package/skills/github-issue-to-pr/SKILL.md +7 -0
  168. package/skills/github-issue-to-pr/scripts/agent_conversation.py +150 -0
  169. package/skills/github-issue-to-pr/scripts/github_client.py +230 -0
  170. package/skills/github-issue-to-pr/scripts/main.py +16 -10
  171. package/skills/github-issue-to-pr/scripts/worker.py +172 -0
  172. package/skills/github-issue-triage/.claude-plugin/plugin.json +9 -0
  173. package/skills/github-issue-triage/.codex-plugin/plugin.json +9 -0
  174. package/skills/github-issue-triage/SKILL.md +15 -18
  175. package/skills/github-issue-triage/scripts/agent_conversation.py +150 -0
  176. package/skills/github-issue-triage/scripts/github_client.py +230 -0
  177. package/skills/github-issue-triage/scripts/worker.py +81 -98
  178. package/skills/github-pr-review/.claude-plugin/plugin.json +18 -0
  179. package/skills/github-pr-review/.codex-plugin/plugin.json +18 -0
  180. package/skills/github-pr-reviewer/.claude-plugin/plugin.json +20 -0
  181. package/skills/github-pr-reviewer/.codex-plugin/plugin.json +20 -0
  182. package/skills/github-pr-reviewer/SKILL.md +7 -0
  183. package/skills/github-pr-reviewer/scripts/agent_conversation.py +150 -0
  184. package/skills/github-pr-reviewer/scripts/github_client.py +230 -0
  185. package/skills/github-pr-reviewer/scripts/main.py +20 -8
  186. package/skills/github-pr-reviewer/scripts/worker.py +94 -0
  187. package/skills/github-repo-monitor/.claude-plugin/plugin.json +22 -0
  188. package/skills/github-repo-monitor/.codex-plugin/plugin.json +22 -0
  189. package/skills/github-repo-monitor/scripts/github_client.py +230 -0
  190. package/skills/gitlab/.claude-plugin/plugin.json +17 -0
  191. package/skills/gitlab/.codex-plugin/plugin.json +17 -0
  192. package/skills/gitlab-issue-to-mr/.claude-plugin/plugin.json +19 -0
  193. package/skills/gitlab-issue-to-mr/.codex-plugin/plugin.json +19 -0
  194. package/skills/incident-retrospective/.claude-plugin/plugin.json +21 -0
  195. package/skills/incident-retrospective/.codex-plugin/plugin.json +21 -0
  196. package/skills/index.js +12 -3
  197. package/skills/iterate/.claude-plugin/plugin.json +13 -0
  198. package/skills/iterate/.codex-plugin/plugin.json +13 -0
  199. package/skills/jira-issue-to-pr/.claude-plugin/plugin.json +19 -0
  200. package/skills/jira-issue-to-pr/.codex-plugin/plugin.json +19 -0
  201. package/skills/jupyter/.claude-plugin/plugin.json +18 -0
  202. package/skills/jupyter/.codex-plugin/plugin.json +18 -0
  203. package/skills/kubernetes/.claude-plugin/plugin.json +18 -0
  204. package/skills/kubernetes/.codex-plugin/plugin.json +18 -0
  205. package/skills/learn-from-code-review/.claude-plugin/plugin.json +19 -0
  206. package/skills/learn-from-code-review/.codex-plugin/plugin.json +19 -0
  207. package/skills/linear/.claude-plugin/plugin.json +19 -0
  208. package/skills/linear/.codex-plugin/plugin.json +19 -0
  209. package/skills/linear-triage/.claude-plugin/plugin.json +21 -0
  210. package/skills/linear-triage/.codex-plugin/plugin.json +21 -0
  211. package/skills/news-digest/.claude-plugin/plugin.json +19 -0
  212. package/skills/news-digest/.codex-plugin/plugin.json +19 -0
  213. package/skills/notion/.claude-plugin/plugin.json +17 -0
  214. package/skills/notion/.codex-plugin/plugin.json +17 -0
  215. package/skills/npm/.claude-plugin/plugin.json +17 -0
  216. package/skills/npm/.codex-plugin/plugin.json +17 -0
  217. package/skills/openhands-api/.claude-plugin/plugin.json +22 -0
  218. package/skills/openhands-api/.codex-plugin/plugin.json +22 -0
  219. package/skills/openhands-automation/.claude-plugin/plugin.json +19 -0
  220. package/skills/openhands-automation/.codex-plugin/plugin.json +19 -0
  221. package/skills/openhands-enterprise-troubleshooting/.claude-plugin/plugin.json +20 -0
  222. package/skills/openhands-enterprise-troubleshooting/.codex-plugin/plugin.json +20 -0
  223. package/skills/openhands-sdk/.claude-plugin/plugin.json +20 -0
  224. package/skills/openhands-sdk/.codex-plugin/plugin.json +20 -0
  225. package/skills/pdflatex/.claude-plugin/plugin.json +18 -0
  226. package/skills/pdflatex/.codex-plugin/plugin.json +18 -0
  227. package/skills/plain-english-content/.claude-plugin/plugin.json +15 -0
  228. package/skills/plain-english-content/.codex-plugin/plugin.json +15 -0
  229. package/skills/prd/.claude-plugin/plugin.json +19 -0
  230. package/skills/prd/.codex-plugin/plugin.json +19 -0
  231. package/skills/research-brief/.claude-plugin/plugin.json +20 -0
  232. package/skills/research-brief/.codex-plugin/plugin.json +20 -0
  233. package/skills/security/.claude-plugin/plugin.json +18 -0
  234. package/skills/security/.codex-plugin/plugin.json +18 -0
  235. package/skills/skill-creator/.claude-plugin/plugin.json +17 -0
  236. package/skills/skill-creator/.codex-plugin/plugin.json +17 -0
  237. package/skills/slack-channel-monitor/.claude-plugin/plugin.json +21 -0
  238. package/skills/slack-channel-monitor/.codex-plugin/plugin.json +21 -0
  239. package/skills/slack-standup-digest/.claude-plugin/plugin.json +21 -0
  240. package/skills/slack-standup-digest/.codex-plugin/plugin.json +21 -0
  241. package/skills/spark-version-upgrade/.claude-plugin/plugin.json +20 -0
  242. package/skills/spark-version-upgrade/.codex-plugin/plugin.json +20 -0
  243. package/skills/ssh/.claude-plugin/plugin.json +18 -0
  244. package/skills/ssh/.codex-plugin/plugin.json +18 -0
  245. package/skills/swift-linux/.claude-plugin/plugin.json +17 -0
  246. package/skills/swift-linux/.codex-plugin/plugin.json +17 -0
  247. package/skills/technical-writing/.claude-plugin/plugin.json +15 -0
  248. package/skills/technical-writing/.codex-plugin/plugin.json +15 -0
  249. package/skills/theme-factory/.claude-plugin/plugin.json +19 -0
  250. package/skills/theme-factory/.codex-plugin/plugin.json +19 -0
  251. package/skills/ticket-to-code-change/.claude-plugin/plugin.json +21 -0
  252. package/skills/ticket-to-code-change/.codex-plugin/plugin.json +21 -0
  253. package/skills/upstream-fork-sync/.claude-plugin/plugin.json +21 -0
  254. package/skills/upstream-fork-sync/.codex-plugin/plugin.json +21 -0
  255. package/skills/uv/.claude-plugin/plugin.json +18 -0
  256. package/skills/uv/.codex-plugin/plugin.json +18 -0
  257. package/skills/vercel/.claude-plugin/plugin.json +18 -0
  258. package/skills/vercel/.codex-plugin/plugin.json +18 -0
  259. package/tests/fixtures/automations/capabilities.json +6 -3
  260. package/tests/fixtures/automations/github-pr-reviewer.json +64 -43
  261. package/tests/github_automation_helpers.py +7 -1
  262. package/tests/test_agent_conversation_dispatch.py +196 -0
  263. package/tests/test_automation_setup.py +3 -3
  264. package/tests/test_github_developer_delivery.py +150 -0
  265. package/tests/test_github_reviewer_delivery.py +110 -0
  266. package/tests/test_github_triage_delivery.py +78 -41
  267. package/tests/test_github_watchdog_delivery.py +233 -0
@@ -0,0 +1,187 @@
1
+ ---
2
+ name: github-pr-review
3
+ description: Post PR review comments using the GitHub API with inline comments, suggestions, and priority labels.
4
+ triggers:
5
+ - /github-pr-review
6
+ ---
7
+
8
+ # GitHub PR Review
9
+
10
+ Post structured code review feedback using the GitHub API with inline comments on specific lines.
11
+ Windows PowerShell equivalents for JSON file creation, temp paths, line lookup, and fallback `curl` are in `references/windows.md`.
12
+
13
+ ## Key Rule: One API Call
14
+
15
+ Bundle ALL comments into a **single review API call**. Do not post comments individually.
16
+
17
+ ## Posting a Review
18
+
19
+ Use the GitHub CLI (`gh`) with a JSON input file. The `GITHUB_TOKEN` is automatically available.
20
+
21
+ **Important**: Always use `--input` with a JSON file instead of `-F` flags. This avoids shell quoting issues with special characters in comment bodies (quotes, backticks, newlines, etc.) and eliminates the need for complex heredoc scripts.
22
+
23
+ ### Step 1: Create a JSON file
24
+
25
+ ```bash
26
+ cat > /tmp/review.json << 'EOF'
27
+ {
28
+ "commit_id": "{commit_sha}",
29
+ "event": "COMMENT",
30
+ "body": "Brief 1-3 sentence summary.",
31
+ "comments": [
32
+ {
33
+ "path": "path/to/file.py",
34
+ "line": 42,
35
+ "side": "RIGHT",
36
+ "body": "🟠 Important: Your comment here."
37
+ },
38
+ {
39
+ "path": "another/file.js",
40
+ "line": 15,
41
+ "side": "RIGHT",
42
+ "body": "🟡 Suggestion: Another comment."
43
+ }
44
+ ]
45
+ }
46
+ EOF
47
+ ```
48
+
49
+ ### Step 2: Post the review
50
+
51
+ ```bash
52
+ gh api -X POST repos/{owner}/{repo}/pulls/{pr_number}/reviews --input /tmp/review.json
53
+ ```
54
+
55
+ ### Parameters
56
+
57
+ | Parameter | Description |
58
+ |-----------|-------------|
59
+ | `commit_id` | Commit SHA to comment on (use `git rev-parse HEAD`) |
60
+ | `event` | `COMMENT`, `APPROVE`, or `REQUEST_CHANGES` |
61
+ | `path` | File path as shown in the diff |
62
+ | `line` | Line number in the NEW version (right side of diff) |
63
+ | `side` | `RIGHT` for new/added lines, `LEFT` for deleted lines |
64
+ | `body` | Comment text with priority label |
65
+
66
+ ### Multi-Line Comments
67
+
68
+ For comments spanning multiple lines, add `start_line` to specify the range:
69
+
70
+ ```json
71
+ {
72
+ "path": "path/to/file.py",
73
+ "start_line": 10,
74
+ "line": 12,
75
+ "side": "RIGHT",
76
+ "body": "🟡 Suggestion: Refactor this block:\n\n```suggestion\nline_one = \"new\"\nline_two = \"code\"\nline_three = \"here\"\n```"
77
+ }
78
+ ```
79
+
80
+ **`start_line`/`line` define the range that will be REPLACED.** The suggestion block may have any number of lines — it does **not** have to match the range size. See the next section for the exact semantics; getting this wrong is how suggestions silently delete or duplicate code.
81
+
82
+ ## Priority Labels
83
+
84
+ Start each comment with a priority label. **Minimize nits** - leave minor style issues to linters.
85
+
86
+ | Label | When to Use |
87
+ |-------|-------------|
88
+ | 🔴 **Critical** | Must fix: security vulnerabilities, bugs, data loss risks |
89
+ | 🟠 **Important** | Should fix: logic errors, performance issues, missing error handling |
90
+ | 🟡 **Suggestion** | Worth considering: significant improvements to clarity or maintainability |
91
+
92
+ **Do NOT post 🟢 Nit or 🟢 Acceptable comments.** If code is fine, simply don't comment on it. Inline comments that say "this looks good" or "acceptable trade-off" are noise — they create review threads that must be resolved without providing actionable value.
93
+
94
+ **Example:**
95
+ ```
96
+ 🟠 Important: This function doesn't handle None, which could cause an AttributeError.
97
+
98
+ ```suggestion
99
+ if user is None:
100
+ raise ValueError("User cannot be None")
101
+ ```
102
+ ```
103
+
104
+ ## GitHub Suggestions
105
+
106
+ For small code changes, use the suggestion syntax for one-click apply:
107
+
108
+ ~~~
109
+ ```suggestion
110
+ improved_code_here()
111
+ ```
112
+ ~~~
113
+
114
+ Use suggestions for: renaming, typos, small refactors (1-5 lines), type hints, docstrings.
115
+
116
+ Avoid for: large refactors, architectural changes, ambiguous improvements.
117
+
118
+ ### How Suggestions Actually Work (READ THIS BEFORE WRITING ONE)
119
+
120
+ A suggestion block **replaces** the targeted range with its contents. The replaced range is:
121
+
122
+ - `line` only → the single line `line` (replaces 1 line)
123
+ - `start_line` + `line` → the inclusive range `start_line..line` (replaces `line - start_line + 1` lines)
124
+
125
+ The suggestion content can be **any number of lines** — 0 (deletion), 1, or many. It does not have to match the range size. Whatever is between the ` ```suggestion ` and closing ` ``` ` fences becomes the new content of those lines.
126
+
127
+ Writing the wrong combination of `start_line`/`line` and suggestion body is what causes accepted suggestions to **duplicate** or **delete** code. Use the table below as your contract:
128
+
129
+ | Intent | `start_line` | `line` | Suggestion body must contain |
130
+ |--------|--------------|--------|-------------------------------|
131
+ | Change line N | omit | N | the new content for line N |
132
+ | Change lines N..M | N | M | the new content for the whole block |
133
+ | **Add** a line **after** line N (keep line N) | omit | N | line N's exact current text, then the new line(s) |
134
+ | **Add** a line **before** line N (keep line N) | omit | N | the new line(s), then line N's exact current text |
135
+ | **Insert** lines inside range N..M (keep N..M) | N | M | every original line in N..M plus the new lines, in the final desired order |
136
+ | **Delete** line N | omit | N | empty body (just an empty ` ```suggestion ``` ` block) |
137
+ | **Delete** lines N..M | N | M | empty body |
138
+
139
+ ### Common Mistakes That Break Code
140
+
141
+ 1. **Duplicated lines.** You copy a neighboring line (N-1 or N+1) into the suggestion body as context — that line is still present in the file outside the replaced range, so accepting the suggestion inserts a second copy of it. Fix: only include lines that fall within the targeted range, plus any genuinely new content.
142
+ 2. **Disappearing lines.** You target `start_line=10, line=12` to comment on a 3-line block, but your suggestion body only contains 1 line because you "only want to change line 11". Accepting that suggestion deletes lines 10 and 12. Fix: either narrow the range to just line 11, or include lines 10 and 12 verbatim in the body.
143
+ 3. **Description does not match the suggestion.** The prose says "rename this variable" but the suggestion replaces an entire function. Or the prose says "add a None check" but the suggestion only contains the check (deleting the original code). Fix: after writing the suggestion, re-read the prose and confirm the resulting file would match it line-for-line.
144
+
145
+ ### Mandatory Verification Before Posting
146
+
147
+ For every comment that contains a ` ```suggestion ``` ` block, do this check before adding it to the review JSON:
148
+
149
+ 1. Read the actual file lines that will be replaced: `sed -n '<start_line>,<line>p' <path>` (or `sed -n '<line>p' <path>` for a single-line target).
150
+ 2. Mentally apply the suggestion: drop those lines, splice in the suggestion body, and look at the result in context.
151
+ 3. Confirm the resulting code matches **exactly** what your prose description promises — no extra duplicated line above/below, no original line accidentally dropped, no off-by-one.
152
+ 4. If the change cannot be expressed cleanly as a contiguous replacement (e.g., it touches non-adjacent lines, or it depends on edits elsewhere in the file), do **not** use a suggestion block — describe the change in prose instead.
153
+
154
+ If you are not 100% sure the suggestion will produce the exact code you described, drop the ` ```suggestion ``` ` block and leave a regular inline comment. A correct prose comment is always better than a one-click suggestion that silently corrupts the file.
155
+
156
+ ## Finding Line Numbers
157
+
158
+ ```bash
159
+ # From diff header: @@ -old_start,old_count +new_start,new_count @@
160
+ # Count from new_start for added/modified lines
161
+
162
+ grep -n "pattern" filename # Find line number
163
+ head -n 42 filename | tail -1 # Verify line content
164
+ ```
165
+
166
+ ## Fallback: curl
167
+
168
+ If `gh` is unavailable, use curl with the JSON file:
169
+
170
+ ```bash
171
+ curl -X POST \
172
+ -H "Authorization: token $GITHUB_TOKEN" \
173
+ -H "Accept: application/vnd.github+json" \
174
+ "https://api.github.com/repos/{owner}/{repo}/pulls/{pr_number}/reviews" \
175
+ -d @/tmp/review.json
176
+ ```
177
+
178
+ ## Summary
179
+
180
+ 1. Analyze the code and identify important issues (minimize nits)
181
+ 2. Write review data to a JSON file (e.g., `/tmp/review.json`)
182
+ 3. Post **ONE** review using `gh api --input /tmp/review.json`
183
+ 4. Use priority labels (🔴🟠🟡) on every comment
184
+ 5. Do NOT post comments for code that is acceptable — only comment when action is needed
185
+ 6. Use suggestion syntax for concrete code changes, but only after verifying the resulting code matches your description (see "How Suggestions Actually Work")
186
+ 7. Keep the review body brief (details go in inline comments)
187
+ 8. If no issues: post a short approval message with no inline comments
@@ -0,0 +1,8 @@
1
+ ---
2
+ # auto-generated by sync_extensions.py
3
+ description: Post PR review comments using the GitHub API with inline comments, suggestions, and priority labels.
4
+ ---
5
+
6
+ Read and follow the complete instructions in the SKILL.md file located in this skill's directory.
7
+
8
+ $ARGUMENTS
@@ -0,0 +1,47 @@
1
+ # Windows Notes for GitHub PR Review Commands
2
+
3
+ Use these PowerShell forms for the JSON-file, line-check, and fallback API snippets.
4
+
5
+ ## Create the Review JSON File
6
+
7
+ ```powershell
8
+ $reviewJson = Join-Path $env:TEMP "review.json"
9
+ @'
10
+ {
11
+ "commit_id": "{commit_sha}",
12
+ "event": "COMMENT",
13
+ "body": "Brief 1-3 sentence summary.",
14
+ "comments": []
15
+ }
16
+ '@ | Set-Content -LiteralPath $reviewJson -Encoding utf8
17
+ ```
18
+
19
+ Then pass the file to `gh`:
20
+
21
+ ```powershell
22
+ gh api -X POST repos/{owner}/{repo}/pulls/{pr_number}/reviews --input $reviewJson
23
+ ```
24
+
25
+ ## Verify File Lines
26
+
27
+ Use `Select-String` for pattern lookup and `Get-Content` for exact ranges.
28
+
29
+ ```powershell
30
+ Select-String -Path filename -Pattern "pattern"
31
+
32
+ $lines = Get-Content -LiteralPath filename
33
+ $lines[41] # line 42, because arrays are zero-based
34
+ $lines[($start - 1)..($end - 1)]
35
+ ```
36
+
37
+ ## Fallback Curl
38
+
39
+ Use `curl.exe` so PowerShell does not resolve `curl` to its alias.
40
+
41
+ ```powershell
42
+ curl.exe -X POST `
43
+ -H "Authorization: token $env:GITHUB_TOKEN" `
44
+ -H "Accept: application/vnd.github+json" `
45
+ "https://api.github.com/repos/{owner}/{repo}/pulls/{pr_number}/reviews" `
46
+ --data-binary "@$reviewJson"
47
+ ```
@@ -0,0 +1,11 @@
1
+ {
2
+ "name": "qa-changes",
3
+ "version": "0.1.0",
4
+ "description": "Automated QA validation of PR changes — sets up the environment, runs tests, exercises changed behavior, and reports results",
5
+ "author": {
6
+ "name": "OpenHands",
7
+ "email": "contact@all-hands.dev"
8
+ },
9
+ "license": "MIT",
10
+ "repository": "https://github.com/OpenHands/extensions"
11
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "name": "qa-changes",
3
+ "version": "0.1.0",
4
+ "description": "Automated QA validation of PR changes — sets up the environment, runs tests, exercises changed behavior, and reports results",
5
+ "author": {
6
+ "name": "OpenHands",
7
+ "email": "contact@all-hands.dev"
8
+ },
9
+ "license": "MIT",
10
+ "repository": "https://github.com/OpenHands/extensions"
11
+ }
@@ -0,0 +1,18 @@
1
+ {
2
+ "name": "github-pr-review",
3
+ "version": "1.0.0",
4
+ "description": "Post structured PR reviews to GitHub with inline comments/suggestions in a single API call.",
5
+ "author": {
6
+ "name": "OpenHands",
7
+ "email": "contact@all-hands.dev"
8
+ },
9
+ "homepage": "https://github.com/OpenHands/extensions",
10
+ "repository": "https://github.com/OpenHands/extensions",
11
+ "license": "MIT",
12
+ "keywords": [
13
+ "github",
14
+ "pull-request",
15
+ "review",
16
+ "code-review"
17
+ ]
18
+ }
@@ -0,0 +1,18 @@
1
+ {
2
+ "name": "github-pr-review",
3
+ "version": "1.0.0",
4
+ "description": "Post structured PR reviews to GitHub with inline comments/suggestions in a single API call.",
5
+ "author": {
6
+ "name": "OpenHands",
7
+ "email": "contact@all-hands.dev"
8
+ },
9
+ "homepage": "https://github.com/OpenHands/extensions",
10
+ "repository": "https://github.com/OpenHands/extensions",
11
+ "license": "MIT",
12
+ "keywords": [
13
+ "github",
14
+ "pull-request",
15
+ "review",
16
+ "code-review"
17
+ ]
18
+ }
@@ -0,0 +1,18 @@
1
+ {
2
+ "name": "github-pr-review",
3
+ "version": "1.0.0",
4
+ "description": "Post structured PR reviews to GitHub with inline comments/suggestions in a single API call.",
5
+ "author": {
6
+ "name": "OpenHands",
7
+ "email": "contact@all-hands.dev"
8
+ },
9
+ "homepage": "https://github.com/OpenHands/extensions",
10
+ "repository": "https://github.com/OpenHands/extensions",
11
+ "license": "MIT",
12
+ "keywords": [
13
+ "github",
14
+ "pull-request",
15
+ "review",
16
+ "code-review"
17
+ ]
18
+ }
@@ -0,0 +1,145 @@
1
+ # Github Pr Review
2
+
3
+ Post PR review comments using the GitHub API with inline comments, suggestions, and priority labels.
4
+
5
+ ## Triggers
6
+
7
+ This skill is activated by the following keywords:
8
+
9
+ - `/github-pr-review`
10
+
11
+ ## Details
12
+
13
+ # GitHub PR Review
14
+
15
+ Post structured code review feedback using the GitHub API with inline comments on specific lines.
16
+
17
+ ## Key Rule: One API Call
18
+
19
+ Bundle ALL comments into a **single review API call**. Do not post comments individually.
20
+
21
+ ## Posting a Review
22
+
23
+ Use the GitHub CLI (`gh`). The `GITHUB_TOKEN` is automatically available.
24
+
25
+ ```bash
26
+ gh api \
27
+ -X POST \
28
+ repos/{owner}/{repo}/pulls/{pr_number}/reviews \
29
+ -f commit_id='{commit_sha}' \
30
+ -f event='COMMENT' \
31
+ -f body='Brief 1-3 sentence summary.' \
32
+ -f comments[][path]='path/to/file.py' \
33
+ -F comments[][line]=42 \
34
+ -f comments[][side]='RIGHT' \
35
+ -f comments[][body]='🟠 Important: Your comment here.' \
36
+ -f comments[][path]='another/file.js' \
37
+ -F comments[][line]=15 \
38
+ -f comments[][side]='RIGHT' \
39
+ -f comments[][body]='🟡 Suggestion: Another comment.'
40
+ ```
41
+
42
+ ### Parameters
43
+
44
+ | Parameter | Description |
45
+ |-----------|-------------|
46
+ | `commit_id` | Commit SHA to comment on (use `git rev-parse HEAD`) |
47
+ | `event` | `COMMENT`, `APPROVE`, or `REQUEST_CHANGES` |
48
+ | `path` | File path as shown in the diff |
49
+ | `line` | Line number in the NEW version (right side of diff) |
50
+ | `side` | `RIGHT` for new/added lines, `LEFT` for deleted lines |
51
+ | `body` | Comment text with priority label |
52
+
53
+ ### Multi-Line Comments
54
+
55
+ For comments spanning multiple lines, add `start_line` to specify the range:
56
+
57
+ ```bash
58
+ -f comments[][path]='path/to/file.py' \
59
+ -F comments[][start_line]=10 \
60
+ -F comments[][line]=12 \
61
+ -f comments[][side]='RIGHT' \
62
+ -f comments[][body]='🟡 Suggestion: Refactor this block:
63
+
64
+ ```suggestion
65
+ line_one = "new"
66
+ line_two = "code"
67
+ line_three = "here"
68
+ ```'
69
+ ```
70
+
71
+ **Important**: The suggestion must have the same number of lines as the range (e.g., lines 10-12 = 3 lines).
72
+
73
+ ## Priority Labels
74
+
75
+ Start each comment with a priority label:
76
+
77
+ | Label | When to Use |
78
+ |-------|-------------|
79
+ | 🔴 **Critical** | Must fix: security vulnerabilities, bugs, data loss risks |
80
+ | 🟠 **Important** | Should fix: logic errors, performance issues, missing error handling |
81
+ | 🟡 **Suggestion** | Nice to have: better naming, code organization |
82
+ | 🟢 **Nit** | Optional: formatting, minor style preferences |
83
+
84
+ **Example:**
85
+ ```
86
+ 🟠 Important: This function doesn't handle None, which could cause an AttributeError.
87
+
88
+ ```suggestion
89
+ if user is None:
90
+ raise ValueError("User cannot be None")
91
+ ```
92
+ ```
93
+
94
+ ## GitHub Suggestions
95
+
96
+ For small code changes, use the suggestion syntax for one-click apply:
97
+
98
+ ~~~
99
+ ```suggestion
100
+ improved_code_here()
101
+ ```
102
+ ~~~
103
+
104
+ Use suggestions for: renaming, typos, small refactors (1-5 lines), type hints, docstrings.
105
+
106
+ Avoid for: large refactors, architectural changes, ambiguous improvements.
107
+
108
+ ## Finding Line Numbers
109
+
110
+ ```bash
111
+ # From diff header: @@ -old_start,old_count +new_start,new_count @@
112
+ # Count from new_start for added/modified lines
113
+
114
+ grep -n "pattern" filename # Find line number
115
+ head -n 42 filename | tail -1 # Verify line content
116
+ ```
117
+
118
+ ## Fallback: curl
119
+
120
+ If `gh` is unavailable:
121
+
122
+ ```bash
123
+ curl -X POST \
124
+ -H "Authorization: token $GITHUB_TOKEN" \
125
+ -H "Accept: application/vnd.github+json" \
126
+ "https://api.github.com/repos/{owner}/{repo}/pulls/{pr_number}/reviews" \
127
+ -d '{
128
+ "commit_id": "{commit_sha}",
129
+ "event": "COMMENT",
130
+ "body": "Review summary.",
131
+ "comments": [
132
+ {"path": "file.py", "line": 42, "side": "RIGHT", "body": "Comment"},
133
+ {"path": "file.py", "start_line": 10, "line": 12, "side": "RIGHT", "body": "Multi-line"}
134
+ ]
135
+ }'
136
+ ```
137
+
138
+ ## Summary
139
+
140
+ 1. Analyze the code and identify issues
141
+ 2. Post **ONE** review with all inline comments bundled
142
+ 3. Use priority labels (🔴🟠🟡🟢) on every comment
143
+ 4. Use suggestion syntax for concrete code changes
144
+ 5. Keep the review body brief (details go in inline comments)
145
+ 6. If no issues: post a short approval message
@@ -0,0 +1,187 @@
1
+ ---
2
+ name: github-pr-review
3
+ description: Post PR review comments using the GitHub API with inline comments, suggestions, and priority labels.
4
+ triggers:
5
+ - /github-pr-review
6
+ ---
7
+
8
+ # GitHub PR Review
9
+
10
+ Post structured code review feedback using the GitHub API with inline comments on specific lines.
11
+ Windows PowerShell equivalents for JSON file creation, temp paths, line lookup, and fallback `curl` are in `references/windows.md`.
12
+
13
+ ## Key Rule: One API Call
14
+
15
+ Bundle ALL comments into a **single review API call**. Do not post comments individually.
16
+
17
+ ## Posting a Review
18
+
19
+ Use the GitHub CLI (`gh`) with a JSON input file. The `GITHUB_TOKEN` is automatically available.
20
+
21
+ **Important**: Always use `--input` with a JSON file instead of `-F` flags. This avoids shell quoting issues with special characters in comment bodies (quotes, backticks, newlines, etc.) and eliminates the need for complex heredoc scripts.
22
+
23
+ ### Step 1: Create a JSON file
24
+
25
+ ```bash
26
+ cat > /tmp/review.json << 'EOF'
27
+ {
28
+ "commit_id": "{commit_sha}",
29
+ "event": "COMMENT",
30
+ "body": "Brief 1-3 sentence summary.",
31
+ "comments": [
32
+ {
33
+ "path": "path/to/file.py",
34
+ "line": 42,
35
+ "side": "RIGHT",
36
+ "body": "🟠 Important: Your comment here."
37
+ },
38
+ {
39
+ "path": "another/file.js",
40
+ "line": 15,
41
+ "side": "RIGHT",
42
+ "body": "🟡 Suggestion: Another comment."
43
+ }
44
+ ]
45
+ }
46
+ EOF
47
+ ```
48
+
49
+ ### Step 2: Post the review
50
+
51
+ ```bash
52
+ gh api -X POST repos/{owner}/{repo}/pulls/{pr_number}/reviews --input /tmp/review.json
53
+ ```
54
+
55
+ ### Parameters
56
+
57
+ | Parameter | Description |
58
+ |-----------|-------------|
59
+ | `commit_id` | Commit SHA to comment on (use `git rev-parse HEAD`) |
60
+ | `event` | `COMMENT`, `APPROVE`, or `REQUEST_CHANGES` |
61
+ | `path` | File path as shown in the diff |
62
+ | `line` | Line number in the NEW version (right side of diff) |
63
+ | `side` | `RIGHT` for new/added lines, `LEFT` for deleted lines |
64
+ | `body` | Comment text with priority label |
65
+
66
+ ### Multi-Line Comments
67
+
68
+ For comments spanning multiple lines, add `start_line` to specify the range:
69
+
70
+ ```json
71
+ {
72
+ "path": "path/to/file.py",
73
+ "start_line": 10,
74
+ "line": 12,
75
+ "side": "RIGHT",
76
+ "body": "🟡 Suggestion: Refactor this block:\n\n```suggestion\nline_one = \"new\"\nline_two = \"code\"\nline_three = \"here\"\n```"
77
+ }
78
+ ```
79
+
80
+ **`start_line`/`line` define the range that will be REPLACED.** The suggestion block may have any number of lines — it does **not** have to match the range size. See the next section for the exact semantics; getting this wrong is how suggestions silently delete or duplicate code.
81
+
82
+ ## Priority Labels
83
+
84
+ Start each comment with a priority label. **Minimize nits** - leave minor style issues to linters.
85
+
86
+ | Label | When to Use |
87
+ |-------|-------------|
88
+ | 🔴 **Critical** | Must fix: security vulnerabilities, bugs, data loss risks |
89
+ | 🟠 **Important** | Should fix: logic errors, performance issues, missing error handling |
90
+ | 🟡 **Suggestion** | Worth considering: significant improvements to clarity or maintainability |
91
+
92
+ **Do NOT post 🟢 Nit or 🟢 Acceptable comments.** If code is fine, simply don't comment on it. Inline comments that say "this looks good" or "acceptable trade-off" are noise — they create review threads that must be resolved without providing actionable value.
93
+
94
+ **Example:**
95
+ ```
96
+ 🟠 Important: This function doesn't handle None, which could cause an AttributeError.
97
+
98
+ ```suggestion
99
+ if user is None:
100
+ raise ValueError("User cannot be None")
101
+ ```
102
+ ```
103
+
104
+ ## GitHub Suggestions
105
+
106
+ For small code changes, use the suggestion syntax for one-click apply:
107
+
108
+ ~~~
109
+ ```suggestion
110
+ improved_code_here()
111
+ ```
112
+ ~~~
113
+
114
+ Use suggestions for: renaming, typos, small refactors (1-5 lines), type hints, docstrings.
115
+
116
+ Avoid for: large refactors, architectural changes, ambiguous improvements.
117
+
118
+ ### How Suggestions Actually Work (READ THIS BEFORE WRITING ONE)
119
+
120
+ A suggestion block **replaces** the targeted range with its contents. The replaced range is:
121
+
122
+ - `line` only → the single line `line` (replaces 1 line)
123
+ - `start_line` + `line` → the inclusive range `start_line..line` (replaces `line - start_line + 1` lines)
124
+
125
+ The suggestion content can be **any number of lines** — 0 (deletion), 1, or many. It does not have to match the range size. Whatever is between the ` ```suggestion ` and closing ` ``` ` fences becomes the new content of those lines.
126
+
127
+ Writing the wrong combination of `start_line`/`line` and suggestion body is what causes accepted suggestions to **duplicate** or **delete** code. Use the table below as your contract:
128
+
129
+ | Intent | `start_line` | `line` | Suggestion body must contain |
130
+ |--------|--------------|--------|-------------------------------|
131
+ | Change line N | omit | N | the new content for line N |
132
+ | Change lines N..M | N | M | the new content for the whole block |
133
+ | **Add** a line **after** line N (keep line N) | omit | N | line N's exact current text, then the new line(s) |
134
+ | **Add** a line **before** line N (keep line N) | omit | N | the new line(s), then line N's exact current text |
135
+ | **Insert** lines inside range N..M (keep N..M) | N | M | every original line in N..M plus the new lines, in the final desired order |
136
+ | **Delete** line N | omit | N | empty body (just an empty ` ```suggestion ``` ` block) |
137
+ | **Delete** lines N..M | N | M | empty body |
138
+
139
+ ### Common Mistakes That Break Code
140
+
141
+ 1. **Duplicated lines.** You copy a neighboring line (N-1 or N+1) into the suggestion body as context — that line is still present in the file outside the replaced range, so accepting the suggestion inserts a second copy of it. Fix: only include lines that fall within the targeted range, plus any genuinely new content.
142
+ 2. **Disappearing lines.** You target `start_line=10, line=12` to comment on a 3-line block, but your suggestion body only contains 1 line because you "only want to change line 11". Accepting that suggestion deletes lines 10 and 12. Fix: either narrow the range to just line 11, or include lines 10 and 12 verbatim in the body.
143
+ 3. **Description does not match the suggestion.** The prose says "rename this variable" but the suggestion replaces an entire function. Or the prose says "add a None check" but the suggestion only contains the check (deleting the original code). Fix: after writing the suggestion, re-read the prose and confirm the resulting file would match it line-for-line.
144
+
145
+ ### Mandatory Verification Before Posting
146
+
147
+ For every comment that contains a ` ```suggestion ``` ` block, do this check before adding it to the review JSON:
148
+
149
+ 1. Read the actual file lines that will be replaced: `sed -n '<start_line>,<line>p' <path>` (or `sed -n '<line>p' <path>` for a single-line target).
150
+ 2. Mentally apply the suggestion: drop those lines, splice in the suggestion body, and look at the result in context.
151
+ 3. Confirm the resulting code matches **exactly** what your prose description promises — no extra duplicated line above/below, no original line accidentally dropped, no off-by-one.
152
+ 4. If the change cannot be expressed cleanly as a contiguous replacement (e.g., it touches non-adjacent lines, or it depends on edits elsewhere in the file), do **not** use a suggestion block — describe the change in prose instead.
153
+
154
+ If you are not 100% sure the suggestion will produce the exact code you described, drop the ` ```suggestion ``` ` block and leave a regular inline comment. A correct prose comment is always better than a one-click suggestion that silently corrupts the file.
155
+
156
+ ## Finding Line Numbers
157
+
158
+ ```bash
159
+ # From diff header: @@ -old_start,old_count +new_start,new_count @@
160
+ # Count from new_start for added/modified lines
161
+
162
+ grep -n "pattern" filename # Find line number
163
+ head -n 42 filename | tail -1 # Verify line content
164
+ ```
165
+
166
+ ## Fallback: curl
167
+
168
+ If `gh` is unavailable, use curl with the JSON file:
169
+
170
+ ```bash
171
+ curl -X POST \
172
+ -H "Authorization: token $GITHUB_TOKEN" \
173
+ -H "Accept: application/vnd.github+json" \
174
+ "https://api.github.com/repos/{owner}/{repo}/pulls/{pr_number}/reviews" \
175
+ -d @/tmp/review.json
176
+ ```
177
+
178
+ ## Summary
179
+
180
+ 1. Analyze the code and identify important issues (minimize nits)
181
+ 2. Write review data to a JSON file (e.g., `/tmp/review.json`)
182
+ 3. Post **ONE** review using `gh api --input /tmp/review.json`
183
+ 4. Use priority labels (🔴🟠🟡) on every comment
184
+ 5. Do NOT post comments for code that is acceptable — only comment when action is needed
185
+ 6. Use suggestion syntax for concrete code changes, but only after verifying the resulting code matches your description (see "How Suggestions Actually Work")
186
+ 7. Keep the review body brief (details go in inline comments)
187
+ 8. If no issues: post a short approval message with no inline comments
@@ -0,0 +1,8 @@
1
+ ---
2
+ # auto-generated by sync_extensions.py
3
+ description: Post PR review comments using the GitHub API with inline comments, suggestions, and priority labels.
4
+ ---
5
+
6
+ Read and follow the complete instructions in the SKILL.md file located in this skill's directory.
7
+
8
+ $ARGUMENTS