@openhands/extensions 0.1.0 → 0.2.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 (347) hide show
  1. package/.agents/skills/custom-codereview-guide.md +25 -0
  2. package/.github/pull_request_template.md +38 -0
  3. package/.github/release.yml +14 -0
  4. package/.github/workflows/check-extensions.yml +72 -0
  5. package/.github/workflows/npm-publish.yml +89 -0
  6. package/.github/workflows/pr.yml +30 -0
  7. package/.github/workflows/release.yml +24 -0
  8. package/.github/workflows/tests.yml +25 -0
  9. package/.github/workflows/vulnerability-scan.yml +87 -0
  10. package/.release-please-manifest.json +3 -0
  11. package/AGENTS.md +132 -0
  12. package/README.md +10 -0
  13. package/analysis_results.md +162 -0
  14. package/marketplaces/large-codebase.json +66 -0
  15. package/marketplaces/openhands-extensions.json +682 -0
  16. package/package.json +4 -10
  17. package/plugins/README.md +30 -0
  18. package/plugins/city-weather/.plugin/plugin.json +13 -0
  19. package/plugins/city-weather/README.md +145 -0
  20. package/plugins/city-weather/commands/now.md +56 -0
  21. package/plugins/cobol-modernization/.plugin/plugin.json +19 -0
  22. package/plugins/cobol-modernization/README.md +201 -0
  23. package/plugins/cobol-modernization/references/troubleshooting.md +18 -0
  24. package/plugins/cobol-modernization/skills/build-setup/SKILL.md +78 -0
  25. package/plugins/cobol-modernization/skills/build-setup/scripts/install-gnucobol.sh +32 -0
  26. package/plugins/cobol-modernization/skills/cobol-modernization-overview/SKILL.md +113 -0
  27. package/plugins/cobol-modernization/skills/mainfraime-removal/SKILL.md +62 -0
  28. package/plugins/cobol-modernization/skills/mainfraime-removal/references/cics-transformation-examples.md +45 -0
  29. package/plugins/cobol-modernization/skills/mainframe-planning/SKILL.md +78 -0
  30. package/plugins/cobol-modernization/skills/to-java-migration/SKILL.md +59 -0
  31. package/plugins/cobol-modernization/skills/to-java-migration/references/cobol-to-java-example.md +58 -0
  32. package/plugins/cobol-modernization/skills/to-java-migration/references/datatype-mappings.md +19 -0
  33. package/plugins/issue-duplicate-checker/.plugin/plugin.json +13 -0
  34. package/plugins/issue-duplicate-checker/README.md +51 -0
  35. package/plugins/issue-duplicate-checker/action.yml +349 -0
  36. package/plugins/issue-duplicate-checker/scripts/auto_close_duplicate_issues.py +569 -0
  37. package/plugins/issue-duplicate-checker/scripts/issue_duplicate_check_openhands.py +681 -0
  38. package/plugins/issue-duplicate-checker/scripts/post_duplicate_notice.js +220 -0
  39. package/plugins/issue-duplicate-checker/scripts/remove_duplicate_candidate_label.js +27 -0
  40. package/plugins/magic-test/.plugin/plugin.json +13 -0
  41. package/plugins/magic-test/skills/magic-word/SKILL.md +33 -0
  42. package/plugins/migration-scoring/.plugin/plugin.json +19 -0
  43. package/plugins/migration-scoring/README.md +244 -0
  44. package/plugins/migration-scoring/skills/migration-mapping/SKILL.md +72 -0
  45. package/plugins/migration-scoring/skills/migration-report/SKILL.md +118 -0
  46. package/plugins/migration-scoring/skills/migration-scoring-overview/SKILL.md +126 -0
  47. package/plugins/migration-scoring/skills/score-quality/SKILL.md +54 -0
  48. package/plugins/migration-scoring/skills/score-quality/references/scoring-criteria.md +30 -0
  49. package/plugins/migration-scoring/skills/score-style/SKILL.md +106 -0
  50. package/plugins/onboarding/.plugin/plugin.json +20 -0
  51. package/plugins/onboarding/README.md +30 -0
  52. package/plugins/onboarding/references/criteria.md +144 -0
  53. package/plugins/onboarding/skills/agent-readiness-report/README.md +23 -0
  54. package/plugins/onboarding/skills/agent-readiness-report/SKILL.md +122 -0
  55. package/plugins/onboarding/skills/agent-readiness-report/scripts/scan_agent_instructions.sh +88 -0
  56. package/plugins/onboarding/skills/agent-readiness-report/scripts/scan_build_env.sh +114 -0
  57. package/plugins/onboarding/skills/agent-readiness-report/scripts/scan_feedback_loops.sh +133 -0
  58. package/plugins/onboarding/skills/agent-readiness-report/scripts/scan_policy.sh +113 -0
  59. package/plugins/onboarding/skills/agent-readiness-report/scripts/scan_workflows.sh +127 -0
  60. package/plugins/onboarding/skills/improve-agent-readiness/README.md +19 -0
  61. package/plugins/onboarding/skills/improve-agent-readiness/SKILL.md +167 -0
  62. package/plugins/onboarding/skills/setup-agents-md/README.md +15 -0
  63. package/plugins/onboarding/skills/setup-agents-md/SKILL.md +150 -0
  64. package/plugins/onboarding/skills/setup-openhands/README.md +20 -0
  65. package/plugins/onboarding/skills/setup-openhands/SKILL.md +56 -0
  66. package/plugins/onboarding/skills/setup-pr-review/README.md +23 -0
  67. package/plugins/onboarding/skills/setup-pr-review/SKILL.md +72 -0
  68. package/plugins/openhands/.plugin/plugin.json +13 -0
  69. package/plugins/openhands/README.md +52 -0
  70. package/plugins/openhands/SKILL.md +61 -0
  71. package/plugins/openhands/commands/create.md +55 -0
  72. package/plugins/openhands/commands/openhands-cloud.md +8 -0
  73. package/plugins/openhands/scripts/run.sh +69 -0
  74. package/plugins/pr-review/.plugin/plugin.json +13 -0
  75. package/plugins/pr-review/README.md +393 -0
  76. package/plugins/pr-review/action.yml +298 -0
  77. package/plugins/pr-review/scripts/agent_script.py +1282 -0
  78. package/plugins/pr-review/scripts/evaluate_review.py +655 -0
  79. package/plugins/pr-review/scripts/prompt.py +260 -0
  80. package/plugins/pr-review/workflows/pr-review-by-openhands.yml +51 -0
  81. package/plugins/pr-review/workflows/pr-review-evaluation.yml +85 -0
  82. package/plugins/qa-changes/.plugin/plugin.json +11 -0
  83. package/plugins/qa-changes/README.md +185 -0
  84. package/plugins/qa-changes/action.yml +181 -0
  85. package/plugins/qa-changes/scripts/agent_script.py +406 -0
  86. package/plugins/qa-changes/scripts/evaluate_qa_changes.py +385 -0
  87. package/plugins/qa-changes/scripts/prompt.py +174 -0
  88. package/plugins/qa-changes/workflows/qa-changes-by-openhands.yml +50 -0
  89. package/plugins/qa-changes/workflows/qa-changes-evaluation.yml +85 -0
  90. package/plugins/release-notes/.plugin/plugin.json +19 -0
  91. package/plugins/release-notes/README.md +283 -0
  92. package/plugins/release-notes/SKILL.md +83 -0
  93. package/plugins/release-notes/action.yml +117 -0
  94. package/plugins/release-notes/commands/release-notes.md +8 -0
  95. package/plugins/release-notes/scripts/agent_script.py +292 -0
  96. package/plugins/release-notes/scripts/generate_release_notes.py +733 -0
  97. package/plugins/release-notes/scripts/prompt.py +90 -0
  98. package/plugins/release-notes/scripts/validate_release_notes.py +328 -0
  99. package/plugins/release-notes/workflows/release-notes.yml +76 -0
  100. package/plugins/vulnerability-remediation/.plugin/plugin.json +19 -0
  101. package/plugins/vulnerability-remediation/README.md +217 -0
  102. package/plugins/vulnerability-remediation/action.yml +187 -0
  103. package/plugins/vulnerability-remediation/scripts/scan_and_remediate.py +561 -0
  104. package/plugins/vulnerability-remediation/workflows/vulnerability-scan.yml +87 -0
  105. package/pyproject.toml +12 -0
  106. package/release-please-config.json +16 -0
  107. package/scripts/sync_extensions.py +494 -0
  108. package/scripts/sync_openhands_sdk_skill.py +264 -0
  109. package/skills/README.md +159 -0
  110. package/skills/add-javadoc/.plugin/plugin.json +18 -0
  111. package/skills/add-javadoc/README.md +40 -0
  112. package/skills/add-javadoc/SKILL.md +35 -0
  113. package/skills/add-javadoc/references/example.md +32 -0
  114. package/skills/add-skill/.plugin/plugin.json +18 -0
  115. package/skills/add-skill/README.md +67 -0
  116. package/skills/add-skill/SKILL.md +47 -0
  117. package/skills/add-skill/scripts/fetch_skill.py +259 -0
  118. package/skills/agent-creator/.plugin/plugin.json +20 -0
  119. package/skills/agent-creator/README.md +104 -0
  120. package/skills/agent-creator/SKILL.md +190 -0
  121. package/skills/agent-creator/commands/agent-creator.md +8 -0
  122. package/skills/agent-creator/references/fallback.md +117 -0
  123. package/skills/agent-memory/.plugin/plugin.json +18 -0
  124. package/skills/agent-memory/README.md +35 -0
  125. package/skills/agent-memory/SKILL.md +30 -0
  126. package/skills/agent-memory/commands/remember.md +8 -0
  127. package/skills/agent-sdk-builder/.plugin/plugin.json +18 -0
  128. package/skills/agent-sdk-builder/README.md +40 -0
  129. package/skills/agent-sdk-builder/SKILL.md +37 -0
  130. package/skills/agent-sdk-builder/commands/agent-builder.md +8 -0
  131. package/skills/azure-devops/.plugin/plugin.json +18 -0
  132. package/skills/azure-devops/README.md +55 -0
  133. package/skills/azure-devops/SKILL.md +50 -0
  134. package/skills/bitbucket/.plugin/plugin.json +17 -0
  135. package/skills/bitbucket/README.md +50 -0
  136. package/skills/bitbucket/SKILL.md +45 -0
  137. package/skills/code-review/.plugin/plugin.json +19 -0
  138. package/skills/code-review/README.md +18 -0
  139. package/skills/code-review/SKILL.md +208 -0
  140. package/skills/code-review/commands/codereview-roasted.md +8 -0
  141. package/skills/code-review/commands/codereview.md +8 -0
  142. package/skills/code-review/references/risk-evaluation.md +41 -0
  143. package/skills/code-review/references/supply-chain-security.md +31 -0
  144. package/skills/code-simplifier/.plugin/plugin.json +21 -0
  145. package/skills/code-simplifier/README.md +30 -0
  146. package/skills/code-simplifier/SKILL.md +91 -0
  147. package/skills/code-simplifier/commands/simplify.md +8 -0
  148. package/skills/code-simplifier/references/code-quality-review.md +86 -0
  149. package/skills/code-simplifier/references/code-reuse-review.md +63 -0
  150. package/skills/code-simplifier/references/efficiency-review.md +81 -0
  151. package/skills/datadog/.plugin/plugin.json +19 -0
  152. package/skills/datadog/README.md +100 -0
  153. package/skills/datadog/SKILL.md +95 -0
  154. package/skills/deno/.plugin/plugin.json +18 -0
  155. package/skills/deno/README.md +5 -0
  156. package/skills/deno/SKILL.md +99 -0
  157. package/skills/deno/references/README.md +6 -0
  158. package/skills/discord/.plugin/plugin.json +18 -0
  159. package/skills/discord/README.md +31 -0
  160. package/skills/discord/SKILL.md +109 -0
  161. package/skills/discord/__init__.py +0 -0
  162. package/skills/discord/references/REFERENCE.md +78 -0
  163. package/skills/discord/scripts/__init__.py +0 -0
  164. package/skills/discord/scripts/_http.py +127 -0
  165. package/skills/discord/scripts/post_webhook.py +106 -0
  166. package/skills/discord/scripts/send_message.py +102 -0
  167. package/skills/docker/.plugin/plugin.json +17 -0
  168. package/skills/docker/README.md +34 -0
  169. package/skills/docker/SKILL.md +29 -0
  170. package/skills/evidence-based-citations/.plugin/plugin.json +20 -0
  171. package/skills/evidence-based-citations/README.md +31 -0
  172. package/skills/evidence-based-citations/SKILL.md +59 -0
  173. package/skills/flarglebargle/.plugin/plugin.json +16 -0
  174. package/skills/flarglebargle/README.md +14 -0
  175. package/skills/flarglebargle/SKILL.md +9 -0
  176. package/skills/frontend-design/.plugin/plugin.json +21 -0
  177. package/skills/frontend-design/LICENSE.txt +177 -0
  178. package/skills/frontend-design/README.md +42 -0
  179. package/skills/frontend-design/SKILL.md +42 -0
  180. package/skills/github/.plugin/plugin.json +19 -0
  181. package/skills/github/README.md +42 -0
  182. package/skills/github/SKILL.md +106 -0
  183. package/skills/github-pr-review/.plugin/plugin.json +18 -0
  184. package/skills/github-pr-review/README.md +145 -0
  185. package/skills/github-pr-review/SKILL.md +148 -0
  186. package/skills/github-pr-review/commands/github-pr-review.md +8 -0
  187. package/skills/github-pr-reviewer/.plugin/plugin.json +20 -0
  188. package/skills/github-pr-reviewer/README.md +34 -0
  189. package/skills/github-pr-reviewer/SKILL.md +89 -0
  190. package/skills/github-pr-reviewer/commands/pr-reviewer:setup.md +8 -0
  191. package/skills/github-repo-monitor/.plugin/plugin.json +22 -0
  192. package/skills/github-repo-monitor/README.md +70 -0
  193. package/skills/github-repo-monitor/SKILL.md +316 -0
  194. package/skills/github-repo-monitor/commands/github-monitor:poll.md +8 -0
  195. package/skills/github-repo-monitor/references/github-api.md +241 -0
  196. package/skills/github-repo-monitor/references/state-schema.md +160 -0
  197. package/skills/github-repo-monitor/scripts/main.py +915 -0
  198. package/skills/github-repo-monitor/tests/test_main.py +400 -0
  199. package/skills/gitlab/.plugin/plugin.json +17 -0
  200. package/skills/gitlab/README.md +37 -0
  201. package/skills/gitlab/SKILL.md +32 -0
  202. package/skills/incident-retrospective/.plugin/plugin.json +21 -0
  203. package/skills/incident-retrospective/README.md +34 -0
  204. package/skills/incident-retrospective/SKILL.md +98 -0
  205. package/skills/incident-retrospective/commands/incident-retro:setup.md +8 -0
  206. package/skills/iterate/.plugin/plugin.json +13 -0
  207. package/skills/iterate/README.md +25 -0
  208. package/skills/iterate/SKILL.md +399 -0
  209. package/skills/iterate/commands/babysit.md +8 -0
  210. package/skills/iterate/commands/iterate.md +8 -0
  211. package/skills/iterate/commands/verify.md +8 -0
  212. package/skills/iterate/references/heuristics.md +58 -0
  213. package/skills/iterate/references/verification.md +96 -0
  214. package/skills/jupyter/.plugin/plugin.json +18 -0
  215. package/skills/jupyter/README.md +55 -0
  216. package/skills/jupyter/SKILL.md +50 -0
  217. package/skills/kubernetes/.plugin/plugin.json +18 -0
  218. package/skills/kubernetes/README.md +53 -0
  219. package/skills/kubernetes/SKILL.md +48 -0
  220. package/skills/learn-from-code-review/.plugin/plugin.json +19 -0
  221. package/skills/learn-from-code-review/README.md +64 -0
  222. package/skills/learn-from-code-review/SKILL.md +186 -0
  223. package/skills/learn-from-code-review/commands/learn-from-reviews.md +8 -0
  224. package/skills/linear/.plugin/plugin.json +19 -0
  225. package/skills/linear/README.md +58 -0
  226. package/skills/linear/SKILL.md +213 -0
  227. package/skills/linear-triage/.plugin/plugin.json +21 -0
  228. package/skills/linear-triage/README.md +34 -0
  229. package/skills/linear-triage/SKILL.md +91 -0
  230. package/skills/linear-triage/commands/linear-triage:setup.md +8 -0
  231. package/skills/notion/.plugin/plugin.json +17 -0
  232. package/skills/notion/README.md +114 -0
  233. package/skills/notion/SKILL.md +109 -0
  234. package/skills/npm/.plugin/plugin.json +17 -0
  235. package/skills/npm/README.md +14 -0
  236. package/skills/npm/SKILL.md +9 -0
  237. package/skills/openhands-api/.plugin/plugin.json +22 -0
  238. package/skills/openhands-api/README.md +48 -0
  239. package/skills/openhands-api/SKILL.md +399 -0
  240. package/skills/openhands-api/references/README.md +33 -0
  241. package/skills/openhands-api/references/TROUBLESHOOTING.md +81 -0
  242. package/skills/openhands-api/references/example_prompt.md +12 -0
  243. package/skills/openhands-api/scripts/openhands_api.py +606 -0
  244. package/skills/openhands-api/scripts/openhands_api.ts +252 -0
  245. package/skills/openhands-automation/.plugin/plugin.json +19 -0
  246. package/skills/openhands-automation/README.md +89 -0
  247. package/skills/openhands-automation/SKILL.md +875 -0
  248. package/skills/openhands-automation/commands/automation:create.md +8 -0
  249. package/skills/openhands-automation/references/ab-testing.md +185 -0
  250. package/skills/openhands-automation/references/custom-automation.md +644 -0
  251. package/skills/openhands-sdk/.plugin/plugin.json +20 -0
  252. package/skills/openhands-sdk/README.md +22 -0
  253. package/skills/openhands-sdk/SKILL.md +229 -0
  254. package/skills/openhands-sdk/commands/sdk.md +8 -0
  255. package/skills/pdflatex/.plugin/plugin.json +18 -0
  256. package/skills/pdflatex/README.md +39 -0
  257. package/skills/pdflatex/SKILL.md +34 -0
  258. package/skills/prd/.plugin/plugin.json +19 -0
  259. package/skills/prd/README.md +28 -0
  260. package/skills/prd/SKILL.md +237 -0
  261. package/skills/prd/commands/prd.md +8 -0
  262. package/skills/qa-changes/README.md +18 -0
  263. package/skills/qa-changes/SKILL.md +229 -0
  264. package/skills/qa-changes/commands/qa-changes.md +8 -0
  265. package/skills/release-notes/README.md +24 -0
  266. package/skills/release-notes/SKILL.md +19 -0
  267. package/skills/release-notes/commands/release-notes.md +8 -0
  268. package/skills/research-brief/.plugin/plugin.json +20 -0
  269. package/skills/research-brief/README.md +34 -0
  270. package/skills/research-brief/SKILL.md +99 -0
  271. package/skills/research-brief/commands/research-brief:setup.md +8 -0
  272. package/skills/security/.plugin/plugin.json +18 -0
  273. package/skills/security/README.md +38 -0
  274. package/skills/security/SKILL.md +33 -0
  275. package/skills/skill-creator/.plugin/plugin.json +17 -0
  276. package/skills/skill-creator/LICENSE.txt +202 -0
  277. package/skills/skill-creator/README.md +182 -0
  278. package/skills/skill-creator/SKILL.md +545 -0
  279. package/skills/skill-creator/references/output-patterns.md +82 -0
  280. package/skills/skill-creator/references/workflows.md +28 -0
  281. package/skills/skill-creator/scripts/init_skill.py +303 -0
  282. package/skills/skill-creator/scripts/quick_validate.py +95 -0
  283. package/skills/slack-channel-monitor/.plugin/plugin.json +21 -0
  284. package/skills/slack-channel-monitor/README.md +91 -0
  285. package/skills/slack-channel-monitor/SKILL.md +276 -0
  286. package/skills/slack-channel-monitor/commands/slack-monitor:poll.md +8 -0
  287. package/skills/slack-channel-monitor/references/slack-api.md +207 -0
  288. package/skills/slack-channel-monitor/references/state-schema.md +180 -0
  289. package/skills/slack-channel-monitor/scripts/main.py +962 -0
  290. package/skills/slack-standup-digest/.plugin/plugin.json +21 -0
  291. package/skills/slack-standup-digest/README.md +34 -0
  292. package/skills/slack-standup-digest/SKILL.md +92 -0
  293. package/skills/slack-standup-digest/commands/standup-digest:setup.md +8 -0
  294. package/skills/spark-version-upgrade/.plugin/plugin.json +20 -0
  295. package/skills/spark-version-upgrade/README.md +54 -0
  296. package/skills/spark-version-upgrade/SKILL.md +233 -0
  297. package/skills/ssh/.plugin/plugin.json +18 -0
  298. package/skills/ssh/README.md +140 -0
  299. package/skills/ssh/SKILL.md +135 -0
  300. package/skills/swift-linux/.plugin/plugin.json +17 -0
  301. package/skills/swift-linux/README.md +86 -0
  302. package/skills/swift-linux/SKILL.md +81 -0
  303. package/skills/theme-factory/.plugin/plugin.json +19 -0
  304. package/skills/theme-factory/LICENSE.txt +202 -0
  305. package/skills/theme-factory/README.md +58 -0
  306. package/skills/theme-factory/SKILL.md +59 -0
  307. package/skills/theme-factory/theme-showcase.pdf +0 -0
  308. package/skills/theme-factory/themes/arctic-frost.md +19 -0
  309. package/skills/theme-factory/themes/botanical-garden.md +19 -0
  310. package/skills/theme-factory/themes/desert-rose.md +19 -0
  311. package/skills/theme-factory/themes/forest-canopy.md +19 -0
  312. package/skills/theme-factory/themes/golden-hour.md +19 -0
  313. package/skills/theme-factory/themes/midnight-galaxy.md +19 -0
  314. package/skills/theme-factory/themes/modern-minimalist.md +19 -0
  315. package/skills/theme-factory/themes/ocean-depths.md +19 -0
  316. package/skills/theme-factory/themes/sunset-boulevard.md +19 -0
  317. package/skills/theme-factory/themes/tech-innovation.md +19 -0
  318. package/skills/uv/.plugin/plugin.json +18 -0
  319. package/skills/uv/README.md +5 -0
  320. package/skills/uv/SKILL.md +95 -0
  321. package/skills/uv/references/README.md +5 -0
  322. package/skills/vercel/.plugin/plugin.json +18 -0
  323. package/skills/vercel/README.md +108 -0
  324. package/skills/vercel/SKILL.md +103 -0
  325. package/tests/test_add_skill_installs_to_agents_dir.py +42 -0
  326. package/tests/test_catalogs.py +109 -0
  327. package/tests/test_code_review_risk_evaluation.py +94 -0
  328. package/tests/test_issue_duplicate_checker.py +240 -0
  329. package/tests/test_openhands_api_python.py +152 -0
  330. package/tests/test_plugin_manifest.py +83 -0
  331. package/tests/test_pr_review_diff_payload.py +202 -0
  332. package/tests/test_pr_review_feedback.py +263 -0
  333. package/tests/test_pr_review_prompt.py +152 -0
  334. package/tests/test_pr_review_review_context.py +253 -0
  335. package/tests/test_qa_changes.py +232 -0
  336. package/tests/test_qa_changes_evaluation.py +259 -0
  337. package/tests/test_release_notes_generator.py +990 -0
  338. package/tests/test_sdk_loading.py +150 -0
  339. package/tests/test_skill_plugin_loading.py +149 -0
  340. package/tests/test_skills_have_readme.py +66 -0
  341. package/tests/test_sync_extensions.py +292 -0
  342. package/tests/test_workflow_sync.py +46 -0
  343. package/utils/analysis/README.md +7 -0
  344. package/utils/analysis/laminar_signals/README.md +211 -0
  345. package/utils/analysis/laminar_signals/analyze.py +780 -0
  346. package/utils/analysis/laminar_signals/templates/default.j2 +49 -0
  347. package/utils/analysis/laminar_signals/templates/pr_review.j2 +61 -0
@@ -0,0 +1,316 @@
1
+ ---
2
+ name: github-repo-monitor
3
+ description: >
4
+ This skill should be used when the user asks to "monitor a GitHub repository",
5
+ "watch GitHub for issues or PRs", "respond to @OpenHands mentions on GitHub",
6
+ "set up an OpenHands GitHub integration", "trigger OpenHands from a GitHub
7
+ comment", or "poll a GitHub repo for a trigger phrase". Guides the user
8
+ through creating a cron automation that polls a single repository and starts
9
+ an OpenHands conversation whenever a configurable trigger phrase is detected
10
+ in an issue or PR comment.
11
+ triggers:
12
+ - /github-monitor:poll
13
+ ---
14
+
15
+ # GitHub Repository Monitor
16
+
17
+ Create a cron automation that polls a single GitHub repository on a
18
+ configurable schedule (default: every minute).
19
+
20
+ When a comment on an issue or PR contains the **trigger phrase**
21
+ (default: `@OpenHands`) it:
22
+
23
+ 1. Posts a GitHub comment acknowledging the request with a conversation link.
24
+ 2. Creates an OpenHands conversation pre-loaded with the issue/PR title, body,
25
+ labels, and recent comment history for full context.
26
+ 3. Posts a summary GitHub comment when the conversation finishes.
27
+
28
+ On every subsequent run:
29
+ - New trigger comments on an already-tracked issue/PR are forwarded to the
30
+ running conversation (or re-open a previously closed one).
31
+ - When a conversation goes idle/finished/error the agent's final response
32
+ is posted back as a GitHub comment.
33
+
34
+ > **Local mode only.** This automation targets the local OpenHands setup
35
+ > (`dev:automation` stack). A cloud/webhook variant is out of scope here.
36
+
37
+ ---
38
+
39
+ ## Prerequisites
40
+
41
+ ### Required secret
42
+
43
+ Verify that the following secret is set in **OpenHands Settings → Secrets**
44
+ before proceeding:
45
+
46
+ | Secret name | Token type | Minimum permissions |
47
+ |---|---|---|
48
+ | `GITHUB_TOKEN` | Classic PAT | `repo` (private repos) or `public_repo` (public repos) |
49
+ | `GITHUB_TOKEN` | Fine-grained PAT | Issues: Read and Write |
50
+
51
+ Check with:
52
+ ```bash
53
+ curl -s https://api.github.com/user \
54
+ -H "Authorization: Bearer $GITHUB_TOKEN" \
55
+ -H "Accept: application/vnd.github+json" \
56
+ | python3 -c "import json,sys; d=json.load(sys.stdin); print(d.get('login') or d.get('message'))"
57
+ ```
58
+
59
+ If the token is missing, inform the user and stop — the automation cannot
60
+ function without GitHub credentials.
61
+
62
+ ### Optional secret
63
+
64
+ | Secret name | Default | Purpose |
65
+ |---|---|---|
66
+ | `OPENHANDS_URL` | `http://localhost:8000` | Base URL used to build conversation links in GitHub comments |
67
+
68
+ ---
69
+
70
+ ## Setup Workflow
71
+
72
+ Follow these steps in order.
73
+
74
+ ### Step 1 - Verify GITHUB_TOKEN
75
+
76
+ Fetch the secret and run the `curl` check above.
77
+
78
+ - If the secret is absent: tell the user
79
+ *"GITHUB_TOKEN is not set. Please add it in OpenHands Settings → Secrets
80
+ (classic PAT with `repo` or `public_repo` scope, or a fine-grained PAT
81
+ with Issues: Read and Write)."* Then stop.
82
+
83
+ - If the API returns a non-200 or `{"message": "Bad credentials"}`:
84
+ tell the user the token is invalid and ask them to update it.
85
+
86
+ ### Step 2 - Collect repository
87
+
88
+ Ask the user: *"Which GitHub repository should be monitored?
89
+ (Format: `owner/repo`, e.g. `microsoft/vscode`)"*
90
+
91
+ Validate access and write permissions:
92
+
93
+ ```bash
94
+ curl -s "https://api.github.com/repos/{owner}/{repo}" \
95
+ -H "Authorization: Bearer $GITHUB_TOKEN" \
96
+ -H "Accept: application/vnd.github+json" \
97
+ | python3 -c "
98
+ import json, sys
99
+ d = json.load(sys.stdin)
100
+ if 'message' in d:
101
+ print('ERROR:', d['message'])
102
+ else:
103
+ perms = d.get('permissions', {})
104
+ print(f\"Accessible. Private: {d.get('private')}. Permissions: {perms}\")
105
+ "
106
+ ```
107
+
108
+ - If `message: Not Found` or `message: Bad credentials` →
109
+ inform the user and ask them to check the repo name and token.
110
+ - If the repo is private and `permissions.push` is `false` →
111
+ inform the user the token does not have write access and comments will fail.
112
+ - If the check passes, record `REPO = "{owner}/{repo}"`.
113
+
114
+ ### Step 3 - Collect trigger phrase
115
+
116
+ Ask the user: *"What trigger phrase should OpenHands respond to?
117
+ (Press Enter to use the default: `@OpenHands`)"*
118
+
119
+ Accepted values: any non-empty string unlikely to appear by accident.
120
+
121
+ Record as `TRIGGER_PHRASE`. Default: `"@openhands"`.
122
+
123
+ ### Step 4 - Collect allowed GitHub logins
124
+
125
+ Ask the user: *"Which GitHub users may trigger this automation?
126
+ Press Enter to allow only the authenticated `GITHUB_TOKEN` owner.
127
+ You may also provide comma-separated GitHub logins, or `*` to allow any
128
+ non-bot commenter on the monitored repository."*
129
+
130
+ Map the answer to `ALLOWED_GITHUB_LOGINS`:
131
+
132
+ | User answer | `ALLOWED_GITHUB_LOGINS` value |
133
+ |---|---|
134
+ | Empty/default | `["<TOKEN_OWNER>"]` |
135
+ | `enyst,tofarr` | `["enyst", "tofarr"]` |
136
+ | `*` | `["*"]` |
137
+
138
+ Default to token-owner-only unless the user explicitly chooses a broader
139
+ allowlist. Record as `ALLOWED_GITHUB_LOGINS`.
140
+
141
+ ### Step 5 - Collect event types
142
+
143
+ Ask the user: *"Which event types should be monitored?
144
+ Choose one or more:*
145
+ *1. Issue and PR comments (default)*
146
+ *2. PR inline review comments*
147
+ *3. Both*
148
+ *(Press Enter to accept the default: issue and PR comments.)"*
149
+
150
+ Map the choice to the `EVENT_TYPES` list:
151
+
152
+ | Choice | `EVENT_TYPES` value |
153
+ |---|---|
154
+ | 1 (default) | `["issue_comment"]` |
155
+ | 2 | `["pr_review_comment"]` |
156
+ | 3 | `["issue_comment", "pr_review_comment"]` |
157
+
158
+ ### Step 6 - Collect cron schedule
159
+
160
+ Ask the user: *"How often should the automation poll GitHub?
161
+ (Press Enter for the default: every minute.
162
+ Use a cron expression for a different interval, e.g.:
163
+ `*/5 * * * *` = every 5 minutes,
164
+ `0 * * * *` = every hour)"*
165
+
166
+ Default: `* * * * *` (every minute).
167
+
168
+ Record as `CRON_SCHEDULE`.
169
+
170
+ ### Step 7 - Generate the automation script
171
+
172
+ Read `scripts/main.py` from this skill's directory. Apply exactly five
173
+ constant substitutions near the top of the file:
174
+
175
+ | Placeholder | Replace with |
176
+ |---|---|
177
+ | `REPO = "owner/repo"` | `REPO = "{owner_repo}"` |
178
+ | `TRIGGER_PHRASE = "@openhands"` | `TRIGGER_PHRASE = "{trigger_phrase_lower}"` |
179
+ | `EVENT_TYPES = ["issue_comment"]` | `EVENT_TYPES = {event_types_list}` |
180
+ | `ALLOWED_GITHUB_LOGINS = ["<TOKEN_OWNER>"]` | `ALLOWED_GITHUB_LOGINS = {allowed_logins_list}` |
181
+ | `DEFAULT_OPENHANDS_URL = "http://localhost:8000"` | `DEFAULT_OPENHANDS_URL = "{url}"` (keep default if the user has no preference) |
182
+
183
+ Write the customised script to a temporary build directory:
184
+ ```bash
185
+ mkdir -p /tmp/github-monitor-build
186
+ # (write the customised main.py to /tmp/github-monitor-build/main.py)
187
+ ```
188
+
189
+ Validate syntax before packaging:
190
+ ```bash
191
+ python3 -m py_compile /tmp/github-monitor-build/main.py && echo "Syntax OK"
192
+ ```
193
+
194
+ Fix any syntax errors before proceeding.
195
+
196
+ ### Step 8 - Package and upload
197
+
198
+ Determine the Automation backend URL and auth from the `<RUNTIME_SERVICES>`
199
+ block in your system context:
200
+ - Use the **Automation backend** `url_from_agent` as `OPENHANDS_HOST`
201
+ - Auth: `X-Session-API-Key: $OPENHANDS_AUTOMATION_API_KEY`
202
+
203
+ If no Automation backend is listed in `<RUNTIME_SERVICES>`, stop and tell
204
+ the user to start the full automation stack.
205
+
206
+ ```bash
207
+ tar -czf /tmp/github-monitor.tar.gz -C /tmp/github-monitor-build .
208
+
209
+ # OPENHANDS_HOST: read from <RUNTIME_SERVICES> Automation backend url_from_agent
210
+ OPENHANDS_HOST="<automation-url-from-runtime-services>"
211
+
212
+ TARBALL_PATH=$(curl -s -X POST \
213
+ "${OPENHANDS_HOST}/api/automation/v1/uploads?name=github-repo-monitor" \
214
+ -H "X-Session-API-Key: $OPENHANDS_AUTOMATION_API_KEY" \
215
+ -H "Content-Type: application/gzip" \
216
+ --data-binary @/tmp/github-monitor.tar.gz \
217
+ | python3 -c "import json,sys; print(json.load(sys.stdin)['tarball_path'])")
218
+
219
+ echo "Uploaded: $TARBALL_PATH"
220
+ ```
221
+
222
+ ### Step 9 - Create the automation
223
+
224
+ ```bash
225
+ curl -s -X POST "${OPENHANDS_HOST}/api/automation/v1" \
226
+ -H "X-Session-API-Key: $OPENHANDS_AUTOMATION_API_KEY" \
227
+ -H "Content-Type: application/json" \
228
+ -d "{
229
+ \"name\": \"GitHub Monitor: {owner}/{repo}\",
230
+ \"trigger\": {\"type\": \"cron\", \"schedule\": \"{cron_schedule}\"},
231
+ \"tarball_path\": \"$TARBALL_PATH\",
232
+ \"entrypoint\": \"python3 main.py\",
233
+ \"timeout\": 55
234
+ }" | python3 -m json.tool
235
+ ```
236
+
237
+ Record the returned `id`.
238
+
239
+ ### Step 10 - Confirm
240
+
241
+ Tell the user:
242
+
243
+ > ✅ **GitHub Repository Monitor** is running!
244
+ >
245
+ > - Automation ID: `{id}`
246
+ > - Repository: `{owner}/{repo}`
247
+ > - Trigger phrase: `{phrase}`
248
+ > - Event types: `{event_types}`
249
+ > - Allowed GitHub logins: `{allowed_logins}`
250
+ > - Polling schedule: `{cron_schedule}`
251
+ > - State file: `~/.openhands/workspaces/automation-state/github_poller_{id}.json`
252
+ >
253
+ > From an allowed GitHub login, post a comment containing `{phrase}` on any
254
+ > issue or PR in `{owner}/{repo}` to test it. OpenHands will acknowledge with
255
+ > a comment and a link to the new conversation.
256
+
257
+ ---
258
+
259
+ ## Runtime Behaviour (per poll)
260
+
261
+ Each cron run executes `main.py`, which:
262
+
263
+ 1. **Loads state** from the JSON file (see `references/state-schema.md`).
264
+ 2. **Resolves and validates GITHUB_TOKEN** — aborts immediately if absent or invalid.
265
+ 3. **Polls for new events** since the previous `last_poll` timestamp:
266
+ - `GET /repos/{owner}/{repo}/issues/comments?since=…` for `issue_comment`
267
+ - `GET /repos/{owner}/{repo}/pulls/comments?since=…` for `pr_review_comment`
268
+ 4. **Processes matching comments** in chronological order:
269
+ - Skips bot accounts (login ending in `[bot]`) to avoid feedback loops.
270
+ - Skips already-processed comment IDs.
271
+ - Skips comments from logins outside `ALLOWED_GITHUB_LOGINS`.
272
+ - Checks body for the trigger phrase (case-insensitive).
273
+ - Extracts the issue/PR number from the comment URL.
274
+ 5. **For each trigger comment**, per issue/PR:
275
+ - **Active conversation** → forwards the new comment directly.
276
+ - **Closed conversation** → tries to re-open it; falls back to creating
277
+ a new conversation if the old one is unreachable.
278
+ - **No conversation** → fetches full context (title, body, labels, last
279
+ 10 comments) and creates a new conversation with a detailed prompt.
280
+ - Posts a GitHub comment: *"🤖 OpenHands is on it! View progress: {url}"*
281
+ 6. **Checks active conversations** for completion:
282
+ - If `status ∈ {idle, finished, error, stuck}` and enough time has passed
283
+ since creation (debounce), fetches the agent's final response and posts
284
+ it as a GitHub comment. Marks the conversation `closed`.
285
+ 7. **Saves state** and fires the completion callback.
286
+
287
+ ---
288
+
289
+ ## Additional Resources
290
+
291
+ ### Reference Files
292
+
293
+ - **`references/state-schema.md`** - State JSON schema, field definitions,
294
+ and conversation lifecycle diagram.
295
+ - **`references/github-api.md`** - GitHub API endpoint reference, token
296
+ scopes, rate limits, and common error codes.
297
+
298
+ ### Script Template
299
+
300
+ - **`scripts/main.py`** - The complete automation script. Customise the four
301
+ constants at the top (`REPO`, `TRIGGER_PHRASE`, `EVENT_TYPES`,
302
+ `DEFAULT_OPENHANDS_URL`) before packaging.
303
+
304
+ ---
305
+
306
+ ## Troubleshooting
307
+
308
+ | Symptom | Likely cause | Fix |
309
+ |---|---|---|
310
+ | Bot doesn't respond to comments | `GITHUB_TOKEN` missing or wrong scopes | Verify token with `curl /user`; check scopes in Step 1 |
311
+ | "Bad credentials" in run logs | Token expired | Rotate token and update the secret in Settings |
312
+ | 404 on repo access | Repo name wrong or token has no access | Re-check `owner/repo` spelling; add token as collaborator |
313
+ | Comments posted but no conversation created | Agent server URL wrong | Check `OPENHANDS_URL` secret and `AGENT_SERVER_URL` env var |
314
+ | Same comment processed twice | `processed_comment_ids` cleared | State file was deleted; harmless but duplicate comment may appear |
315
+ | Summary never posted | Conversation stuck in `running` | Open the conversation in the OpenHands UI; agent may need input |
316
+ | No events detected after first run | `last_poll` in the future | Delete the state file to reset; it will be recreated on next run |
@@ -0,0 +1,8 @@
1
+ ---
2
+ # auto-generated by sync_extensions.py
3
+ description: This skill should be used when the user asks to "monitor a GitHub repository", "watch GitHub for issues or PRs", "respond to @OpenHands mentions on GitHub", "set up an OpenHands GitHub integration", "trigger OpenHands from a GitHub comment", or "poll a GitHub repo for a trigger phrase". Guides the user through creating a cron automation that polls a single repository and starts an OpenHands conversation whenever a configurable trigger phrase is detected in an issue or PR comment.
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,241 @@
1
+ # GitHub API Reference
2
+
3
+ Quick reference for the endpoints, authentication, and rate limits used by
4
+ the GitHub Repository Monitor automation.
5
+
6
+ ---
7
+
8
+ ## Authentication
9
+
10
+ All requests use Bearer authentication:
11
+
12
+ ```
13
+ Authorization: Bearer {GITHUB_TOKEN}
14
+ Accept: application/vnd.github+json
15
+ X-GitHub-Api-Version: 2022-11-28
16
+ ```
17
+
18
+ ---
19
+
20
+ ## Token Types and Required Scopes
21
+
22
+ ### Classic Personal Access Token
23
+
24
+ | Scope | Grants |
25
+ |-------|--------|
26
+ | `repo` | Full access to private and public repos (read + write issues/PRs) |
27
+ | `public_repo` | Write access to public repos only (sufficient for public repos) |
28
+
29
+ ### Fine-Grained Personal Access Token
30
+
31
+ | Permission | Level |
32
+ |------------|-------|
33
+ | Issues | Read and Write |
34
+ | Pull requests | Read (optional, for fetching PR metadata) |
35
+
36
+ ### Checking Token Scopes
37
+
38
+ ```bash
39
+ curl -I https://api.github.com/user \
40
+ -H "Authorization: Bearer $GITHUB_TOKEN" \
41
+ | grep -i x-oauth-scopes
42
+ # X-OAuth-Scopes: repo, public_repo
43
+ ```
44
+
45
+ Fine-grained PATs do not return `X-OAuth-Scopes`; the script relies on the
46
+ `permissions` field in the repo response instead.
47
+
48
+ ---
49
+
50
+ ## Endpoints Used
51
+
52
+ ### Verify token identity
53
+
54
+ ```
55
+ GET /user
56
+ ```
57
+
58
+ Returns the authenticated user. Use to verify the token is valid.
59
+
60
+ ---
61
+
62
+ ### Verify repo access and permissions
63
+
64
+ ```
65
+ GET /repos/{owner}/{repo}
66
+ ```
67
+
68
+ Key fields in the response:
69
+
70
+ | Field | Type | Description |
71
+ |-------|------|-------------|
72
+ | `private` | bool | Whether the repo is private |
73
+ | `permissions.push` | bool | Token has write access (required for private repos) |
74
+ | `permissions.pull` | bool | Token has read access |
75
+ | `full_name` | string | `owner/repo` |
76
+
77
+ Error codes:
78
+ - `404` — Repo not found or token has no read access.
79
+ - `403` — Token exists but is blocked from this resource.
80
+
81
+ ---
82
+
83
+ ### Poll issue and PR comments
84
+
85
+ ```
86
+ GET /repos/{owner}/{repo}/issues/comments
87
+ ?since={ISO 8601 UTC}
88
+ &sort=created
89
+ &direction=asc
90
+ &per_page=100
91
+ &page={n}
92
+ ```
93
+
94
+ Returns all comments on issues **and** PRs (PRs are a superset of issues in
95
+ GitHub's API). The `since` parameter filters to comments created **at or
96
+ after** the given timestamp.
97
+
98
+ Key fields per comment:
99
+
100
+ | Field | Description |
101
+ |-------|-------------|
102
+ | `id` | Integer comment ID (used for deduplication) |
103
+ | `body` | Comment text |
104
+ | `user.login` | Author username |
105
+ | `user.type` | `"User"` or `"Bot"` |
106
+ | `created_at` | ISO 8601 UTC creation timestamp |
107
+ | `html_url` | Direct link to the comment |
108
+ | `issue_url` | API URL of the parent issue/PR (extract number from last path segment) |
109
+
110
+ ---
111
+
112
+ ### Poll PR inline review comments
113
+
114
+ ```
115
+ GET /repos/{owner}/{repo}/pulls/comments
116
+ ?since={ISO 8601 UTC}
117
+ &sort=created
118
+ &direction=asc
119
+ &per_page=100
120
+ &page={n}
121
+ ```
122
+
123
+ Returns inline review comments on PR diffs.
124
+
125
+ Key fields per comment:
126
+
127
+ | Field | Description |
128
+ |-------|-------------|
129
+ | `id` | Integer comment ID |
130
+ | `body` | Comment text |
131
+ | `user.login` | Author username |
132
+ | `pull_request_url` | API URL of the parent PR (extract number from last path segment) |
133
+ | `path` | File path the comment was left on |
134
+ | `line` | Line number in the file (nullable) |
135
+ | `created_at` | ISO 8601 UTC creation timestamp |
136
+
137
+ ---
138
+
139
+ ### Fetch issue/PR metadata
140
+
141
+ ```
142
+ GET /repos/{owner}/{repo}/issues/{issue_number}
143
+ ```
144
+
145
+ Works for both issues and pull requests. To distinguish:
146
+ - Response contains `pull_request` key → it's a PR.
147
+ - No `pull_request` key → it's a regular issue.
148
+
149
+ Key fields:
150
+
151
+ | Field | Description |
152
+ |-------|-------------|
153
+ | `number` | Issue/PR number |
154
+ | `title` | Title string |
155
+ | `body` | Description text (can be null) |
156
+ | `state` | `"open"` or `"closed"` |
157
+ | `html_url` | Browser URL |
158
+ | `labels[].name` | Label names |
159
+ | `pull_request.url` | Present only if this is a PR |
160
+
161
+ ---
162
+
163
+ ### Fetch recent comments for context
164
+
165
+ ```
166
+ GET /repos/{owner}/{repo}/issues/{issue_number}/comments
167
+ ?per_page=100
168
+ ```
169
+
170
+ Returns all issue/PR comments in chronological order. The script fetches
171
+ all pages and takes the last `CONTEXT_COMMENT_LIMIT` (default 10) entries.
172
+
173
+ ---
174
+
175
+ ### Post a comment
176
+
177
+ ```
178
+ POST /repos/{owner}/{repo}/issues/{issue_number}/comments
179
+
180
+ Body: { "body": "comment text (Markdown supported)" }
181
+ ```
182
+
183
+ Works for both issues and PRs. Returns the created comment object including
184
+ its `id` and `html_url`.
185
+
186
+ Error codes:
187
+ - `403` — Token lacks write permission.
188
+ - `404` — Repo or issue not found.
189
+ - `410` — Issue is locked; comments are disabled.
190
+
191
+ ---
192
+
193
+ ## Rate Limits
194
+
195
+ | Tier | Limit | Notes |
196
+ |------|-------|-------|
197
+ | Authenticated requests | 5,000 / hour | Per token |
198
+ | Search API | 30 / minute | Not used by this script |
199
+ | Secondary rate limit | Varies | Triggered by rapid POST bursts; unlikely at 1-min polling |
200
+
201
+ At one poll per minute on a moderately active repo:
202
+ - ~2 GET calls per run baseline (user + repo)
203
+ - ~1–3 additional GETs per trigger event (issue context + comment history)
204
+ - ~1–2 POSTs per trigger event (acknowledgement comment + optional summary)
205
+
206
+ Typical usage: **< 20 requests/hour** for a quiet repo,
207
+ **< 300 requests/hour** for a very active repo (still well within the 5,000 limit).
208
+
209
+ Check remaining quota with:
210
+ ```bash
211
+ curl -s https://api.github.com/rate_limit \
212
+ -H "Authorization: Bearer $GITHUB_TOKEN" \
213
+ | python3 -c "
214
+ import json, sys
215
+ d = json.load(sys.stdin)
216
+ core = d['resources']['core']
217
+ print(f\"Remaining: {core['remaining']}/{core['limit']} Reset: {core['reset']}\")
218
+ "
219
+ ```
220
+
221
+ ---
222
+
223
+ ## Common Error Codes
224
+
225
+ | Code | Meaning | Typical fix |
226
+ |------|---------|-------------|
227
+ | 401 | Bad credentials / token expired | Rotate token; update the secret |
228
+ | 403 | Forbidden (scope missing or repo blocked) | Add required scope; check org SSO |
229
+ | 404 | Resource not found or no read access | Check repo name; ensure token has access |
230
+ | 410 | Gone (issue locked or deleted) | Harmless — skip this issue |
231
+ | 422 | Unprocessable entity (e.g., body too long) | Truncate comment body |
232
+ | 429 | Rate limit hit (secondary) | Slow down; add sleep between requests |
233
+
234
+ ---
235
+
236
+ ## Bot Detection
237
+
238
+ GitHub sets `user.type = "Bot"` for GitHub Apps and some bots. Classic bot
239
+ accounts (created as regular users) may instead have logins ending in
240
+ `[bot]` (e.g. `dependabot[bot]`). The script skips both patterns to avoid
241
+ feedback loops with other automation.