@openhands/extensions 0.18.0 → 0.20.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 (62) hide show
  1. package/.agents/skills/custom-codereview-guide.md +7 -0
  2. package/.github/dependabot.yml +24 -0
  3. package/.github/scripts/check_issue_readiness.py +272 -0
  4. package/.github/scripts/check_pr_description.py +226 -0
  5. package/.github/scripts/post-readiness-comment.mjs +184 -0
  6. package/.github/scripts/refresh_linked_pr_checks.py +171 -0
  7. package/.github/workflows/issue-readiness-check.yml +142 -0
  8. package/.github/workflows/pr-description-check.yml +37 -0
  9. package/.pr/custom-automation-event-trigger.png +0 -0
  10. package/.pr/custom-automation-plugin-fields.png +0 -0
  11. package/.pr/custom-automation-prompt-review.png +0 -0
  12. package/.pr/custom-automation-prompt-scheduled.png +0 -0
  13. package/.pr/custom-automation-upload-fields.png +0 -0
  14. package/.release-please-manifest.json +1 -1
  15. package/AGENTS.md +17 -1
  16. package/README.md +10 -2
  17. package/automations/README.md +52 -36
  18. package/automations/bundle-index.js +1 -1
  19. package/automations/catalog/custom-automation/manifest.json +229 -0
  20. package/automations/catalog/github-agents-md-maintainer/manifest.json +5 -0
  21. package/automations/catalog/github-issue-to-pr/manifest.json +6 -1
  22. package/automations/catalog/github-pr-reviewer/manifest.json +6 -1
  23. package/automations/catalog/github-repo-monitor/manifest.json +5 -0
  24. package/automations/catalog/jira-issue-to-bitbucket-pr/manifest.json +23 -0
  25. package/automations/catalog/jira-issue-to-gitlab-mr/manifest.json +23 -0
  26. package/automations/catalog/linear-issue-to-bitbucket-pr/manifest.json +23 -0
  27. package/automations/catalog/linear-issue-to-github-pr/manifest.json +23 -0
  28. package/automations/catalog/linear-issue-to-gitlab-mr/manifest.json +23 -0
  29. package/automations/catalog/news-digest/manifest.json +5 -0
  30. package/automations/catalog/qa-changes/manifest.json +72 -0
  31. package/automations/catalog/slack-github-linear-daily-organization.json +27 -0
  32. package/automations/catalog-index.js +25 -11
  33. package/automations/catalog.schema.json +106 -7
  34. package/automations/index.d.ts +68 -2
  35. package/automations/interface.json +2 -1
  36. package/integrations/catalog/datadog.json +2 -2
  37. package/integrations/catalog/gitlab.json +63 -0
  38. package/integrations/catalog/notion.json +1 -1
  39. package/integrations/catalog-index.js +71 -69
  40. package/integrations/index.d.ts +1 -1
  41. package/marketplaces/openhands-extensions.json +21 -6
  42. package/package.json +1 -1
  43. package/plugins/pr-review/scripts/prompt.py +2 -0
  44. package/pyproject.toml +1 -1
  45. package/python/openhands_extensions/_version.py +1 -1
  46. package/skills/github-pr-reviewer/SKILL.md +2 -1
  47. package/skills/github-pr-reviewer/scripts/main.py +45 -4
  48. package/skills/github-pr-reviewer/tests/test_main.py +74 -0
  49. package/skills/index.js +11 -2
  50. package/skills/openhands-sdk/SKILL.md +1 -0
  51. package/skills/ticket-to-code-change/.plugin/plugin.json +21 -0
  52. package/skills/ticket-to-code-change/README.md +5 -0
  53. package/skills/ticket-to-code-change/SKILL.md +50 -0
  54. package/skills/ticket-to-code-change/commands/ticket-to-code-change-setup.md +8 -0
  55. package/tests/fixtures/automations/custom-automation.json +398 -0
  56. package/tests/fixtures/automations/github-pr-reviewer.json +9 -9
  57. package/tests/test_automation_setup.py +362 -92
  58. package/tests/test_catalogs.py +2 -2
  59. package/tests/test_check_issue_readiness.py +135 -0
  60. package/tests/test_check_pr_description.py +228 -0
  61. package/tests/test_pr_review_prompt.py +10 -0
  62. package/tests/test_refresh_linked_pr_checks.py +130 -0
@@ -0,0 +1,50 @@
1
+ ---
2
+ name: ticket-to-code-change
3
+ description: >
4
+ Set up a ticket-to-code-change automation using Jira or Linear as the issue
5
+ tracker and GitHub, GitLab, or Bitbucket as the source-control provider.
6
+ Watches for implementation-ready tickets, starts an OpenHands conversation
7
+ to implement and test the request, opens a pull or merge request, and links
8
+ the result back to the ticket.
9
+ triggers:
10
+ - /ticket-to-code-change:setup
11
+ ---
12
+
13
+ # Ticket to code change
14
+
15
+ Create an automation that turns implementation-ready tickets into tested pull
16
+ requests or merge requests.
17
+
18
+ ## Information to collect
19
+
20
+ Ask the user for:
21
+
22
+ 1. The issue tracker: Jira Cloud or Linear.
23
+ 2. The source-control provider: GitHub, GitLab, or Bitbucket Cloud.
24
+ 3. The project or team to watch and the label or workflow state that means
25
+ "implementation ready".
26
+ 4. How a ticket identifies its target repository and base branch.
27
+ 5. The polling schedule or issue event to use.
28
+ 6. The ticket state to set when work starts and when the change request opens.
29
+ 7. Whether linked dependencies must be completed before dispatch.
30
+
31
+ ## Setup workflow
32
+
33
+ 1. Verify that both required integrations are connected and can read the
34
+ selected project and repository.
35
+ 2. Prefer an issue event trigger when the deployment can receive events;
36
+ otherwise use cron polling with durable issue-ID deduplication.
37
+ 3. Limit each run to a small configurable number of new tickets. On initial
38
+ deployment, establish a baseline instead of dispatching the entire backlog.
39
+ 4. Build a prompt that includes the full ticket, acceptance criteria,
40
+ dependency status, repository, base branch, and provider-specific request
41
+ terminology. Require the agent to run the repository's tests before opening
42
+ the pull request or merge request.
43
+ 5. Create the automation through the Automation backend described in
44
+ `<RUNTIME_SERVICES>`. Use its prompt-preset endpoint and authenticate with
45
+ the runtime-provided automation API key.
46
+ 6. Configure the automation to post the OpenHands conversation URL immediately
47
+ and the resulting pull-request or merge-request URL back to the ticket.
48
+
49
+ Do not dispatch tickets with unresolved dependencies or without an unambiguous
50
+ target repository; comment on the ticket with the missing information instead.
@@ -0,0 +1,8 @@
1
+ ---
2
+ # auto-generated by sync_extensions.py
3
+ description: Set up a ticket-to-code-change automation using Jira or Linear as the issue tracker and GitHub, GitLab, or Bitbucket as the source-control provider. Watches for implementation-ready tickets, starts an OpenHands conversation to implement and test the request, opens a pull or merge request, and links the result back to the ticket.
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,398 @@
1
+ {
2
+ "automationId": "custom-automation",
3
+ "description": "Direct generic setup. One catalog entry can create prompt, plugin, or uploaded-tarball automations; selectedAction and selectedTrigger record the host UI variants chosen for each scenario.",
4
+ "capabilities": "supported",
5
+ "blockedBy": [
6
+ "notReady"
7
+ ],
8
+ "scenarios": [
9
+ {
10
+ "id": "scheduled-prompt",
11
+ "description": "A custom prompt automation that runs on a weekday schedule and clones one repository.",
12
+ "selectedAction": "prompt",
13
+ "selectedTrigger": "cron",
14
+ "formValues": {
15
+ "name": "Daily extensions summary",
16
+ "prompt": "Summarize recent changes in the OpenHands/extensions repository and save a concise report in the workspace.",
17
+ "repository": "OpenHands/extensions",
18
+ "ref": "main",
19
+ "model": "fast",
20
+ "timeout": 900,
21
+ "schedule": "0 9 * * 1-5",
22
+ "timezone": "UTC"
23
+ },
24
+ "preflight": {
25
+ "request": {
26
+ "method": "POST",
27
+ "path": "/v1/validate",
28
+ "body": {
29
+ "automationId": "custom-automation",
30
+ "endpoint": "/v1/preset/prompt",
31
+ "draft": {
32
+ "name": "Daily extensions summary",
33
+ "prompt": "Summarize recent changes in the OpenHands/extensions repository and save a concise report in the workspace.",
34
+ "model": "fast",
35
+ "timeout": 900,
36
+ "repos": [
37
+ {
38
+ "url": "OpenHands/extensions",
39
+ "provider": "github",
40
+ "ref": "main"
41
+ }
42
+ ],
43
+ "trigger": {
44
+ "type": "cron",
45
+ "schedule": "0 9 * * 1-5",
46
+ "timezone": "UTC"
47
+ }
48
+ }
49
+ }
50
+ },
51
+ "response": {
52
+ "status": 200,
53
+ "body": {
54
+ "valid": true,
55
+ "errors": []
56
+ }
57
+ }
58
+ },
59
+ "create": {
60
+ "request": {
61
+ "method": "POST",
62
+ "path": "/v1/preset/prompt",
63
+ "body": {
64
+ "name": "Daily extensions summary",
65
+ "prompt": "Summarize recent changes in the OpenHands/extensions repository and save a concise report in the workspace.",
66
+ "model": "fast",
67
+ "timeout": 900,
68
+ "repos": [
69
+ {
70
+ "url": "OpenHands/extensions",
71
+ "provider": "github",
72
+ "ref": "main"
73
+ }
74
+ ],
75
+ "trigger": {
76
+ "type": "cron",
77
+ "schedule": "0 9 * * 1-5",
78
+ "timezone": "UTC"
79
+ }
80
+ }
81
+ },
82
+ "response": {
83
+ "status": 201,
84
+ "body": {
85
+ "id": "1c0b7ea0-0000-4000-8000-000000000001",
86
+ "model": "fast",
87
+ "name": "Daily extensions summary",
88
+ "prompt": "Summarize recent changes in the OpenHands/extensions repository and save a concise report in the workspace.",
89
+ "trigger": {
90
+ "type": "cron",
91
+ "schedule": "0 9 * * 1-5",
92
+ "timezone": "UTC"
93
+ },
94
+ "timeout": 900,
95
+ "enabled": true
96
+ }
97
+ }
98
+ }
99
+ },
100
+ {
101
+ "id": "event-prompt",
102
+ "description": "A custom prompt automation that runs on a GitHub comment event.",
103
+ "selectedAction": "prompt",
104
+ "selectedTrigger": "event",
105
+ "formValues": {
106
+ "name": "OpenHands mention responder",
107
+ "prompt": "When triggered, read the GitHub issue or pull request context and draft a helpful response for the user.",
108
+ "repository": "OpenHands/extensions",
109
+ "ref": "main",
110
+ "model": "",
111
+ "timeout": 600,
112
+ "source": "github",
113
+ "on": "issue_comment.created",
114
+ "filter": "glob(repository.full_name, 'OpenHands/extensions') && icontains(comment.body, '@openhands')"
115
+ },
116
+ "preflight": {
117
+ "request": {
118
+ "method": "POST",
119
+ "path": "/v1/validate",
120
+ "body": {
121
+ "automationId": "custom-automation",
122
+ "endpoint": "/v1/preset/prompt",
123
+ "draft": {
124
+ "name": "OpenHands mention responder",
125
+ "prompt": "When triggered, read the GitHub issue or pull request context and draft a helpful response for the user.",
126
+ "timeout": 600,
127
+ "repos": [
128
+ {
129
+ "url": "OpenHands/extensions",
130
+ "provider": "github",
131
+ "ref": "main"
132
+ }
133
+ ],
134
+ "trigger": {
135
+ "type": "event",
136
+ "source": "github",
137
+ "on": "issue_comment.created",
138
+ "filter": "glob(repository.full_name, 'OpenHands/extensions') && icontains(comment.body, '@openhands')"
139
+ }
140
+ }
141
+ }
142
+ },
143
+ "response": {
144
+ "status": 200,
145
+ "body": {
146
+ "valid": true,
147
+ "errors": []
148
+ }
149
+ }
150
+ },
151
+ "create": {
152
+ "request": {
153
+ "method": "POST",
154
+ "path": "/v1/preset/prompt",
155
+ "body": {
156
+ "name": "OpenHands mention responder",
157
+ "prompt": "When triggered, read the GitHub issue or pull request context and draft a helpful response for the user.",
158
+ "timeout": 600,
159
+ "repos": [
160
+ {
161
+ "url": "OpenHands/extensions",
162
+ "provider": "github",
163
+ "ref": "main"
164
+ }
165
+ ],
166
+ "trigger": {
167
+ "type": "event",
168
+ "source": "github",
169
+ "on": "issue_comment.created",
170
+ "filter": "glob(repository.full_name, 'OpenHands/extensions') && icontains(comment.body, '@openhands')"
171
+ }
172
+ }
173
+ },
174
+ "response": {
175
+ "status": 201,
176
+ "body": {
177
+ "id": "1c0b7ea0-0000-4000-8000-000000000002",
178
+ "model": null,
179
+ "name": "OpenHands mention responder",
180
+ "prompt": "When triggered, read the GitHub issue or pull request context and draft a helpful response for the user.",
181
+ "trigger": {
182
+ "type": "event",
183
+ "source": "github",
184
+ "on": "issue_comment.created",
185
+ "filter": "glob(repository.full_name, 'OpenHands/extensions') && icontains(comment.body, '@openhands')"
186
+ },
187
+ "timeout": 600,
188
+ "enabled": true
189
+ }
190
+ }
191
+ }
192
+ },
193
+ {
194
+ "id": "scheduled-plugin",
195
+ "description": "A custom plugin automation that loads an OpenHands plugin and runs a prompt.",
196
+ "selectedAction": "plugin",
197
+ "selectedTrigger": "cron",
198
+ "formValues": {
199
+ "name": "Weekly plugin check",
200
+ "plugins": [
201
+ {
202
+ "source": "github:OpenHands/extensions",
203
+ "repo_path": "plugins/qa-changes",
204
+ "ref": "main"
205
+ }
206
+ ],
207
+ "prompt": "Use the plugin to QA recent changes and produce a concise report.",
208
+ "repository": "OpenHands/OpenHands",
209
+ "ref": "main",
210
+ "model": "balanced",
211
+ "timeout": 1200,
212
+ "schedule": "0 10 * * 1",
213
+ "timezone": "UTC"
214
+ },
215
+ "preflight": {
216
+ "request": {
217
+ "method": "POST",
218
+ "path": "/v1/validate",
219
+ "body": {
220
+ "automationId": "custom-automation",
221
+ "endpoint": "/v1/preset/plugin",
222
+ "draft": {
223
+ "name": "Weekly plugin check",
224
+ "prompt": "Use the plugin to QA recent changes and produce a concise report.",
225
+ "plugins": [
226
+ {
227
+ "source": "github:OpenHands/extensions",
228
+ "repo_path": "plugins/qa-changes",
229
+ "ref": "main"
230
+ }
231
+ ],
232
+ "model": "balanced",
233
+ "timeout": 1200,
234
+ "repos": [
235
+ {
236
+ "url": "OpenHands/OpenHands",
237
+ "provider": "github",
238
+ "ref": "main"
239
+ }
240
+ ],
241
+ "trigger": {
242
+ "type": "cron",
243
+ "schedule": "0 10 * * 1",
244
+ "timezone": "UTC"
245
+ }
246
+ }
247
+ }
248
+ },
249
+ "response": {
250
+ "status": 200,
251
+ "body": {
252
+ "valid": true,
253
+ "errors": []
254
+ }
255
+ }
256
+ },
257
+ "create": {
258
+ "request": {
259
+ "method": "POST",
260
+ "path": "/v1/preset/plugin",
261
+ "body": {
262
+ "name": "Weekly plugin check",
263
+ "prompt": "Use the plugin to QA recent changes and produce a concise report.",
264
+ "plugins": [
265
+ {
266
+ "source": "github:OpenHands/extensions",
267
+ "repo_path": "plugins/qa-changes",
268
+ "ref": "main"
269
+ }
270
+ ],
271
+ "model": "balanced",
272
+ "timeout": 1200,
273
+ "repos": [
274
+ {
275
+ "url": "OpenHands/OpenHands",
276
+ "provider": "github",
277
+ "ref": "main"
278
+ }
279
+ ],
280
+ "trigger": {
281
+ "type": "cron",
282
+ "schedule": "0 10 * * 1",
283
+ "timezone": "UTC"
284
+ }
285
+ }
286
+ },
287
+ "response": {
288
+ "status": 201,
289
+ "body": {
290
+ "id": "1c0b7ea0-0000-4000-8000-000000000003",
291
+ "model": "balanced",
292
+ "name": "Weekly plugin check",
293
+ "prompt": "Use the plugin to QA recent changes and produce a concise report.",
294
+ "trigger": {
295
+ "type": "cron",
296
+ "schedule": "0 10 * * 1",
297
+ "timezone": "UTC"
298
+ },
299
+ "timeout": 1200,
300
+ "enabled": true
301
+ }
302
+ }
303
+ }
304
+ },
305
+ {
306
+ "id": "scheduled-upload",
307
+ "description": "A custom upload automation that uploads a tarball and creates through the raw endpoint.",
308
+ "selectedAction": "upload",
309
+ "selectedTrigger": "cron",
310
+ "formValues": {
311
+ "name": "Uploaded maintenance script",
312
+ "tarball": "oh-internal://uploads/1c0b7ea0-0000-4000-8000-000000000004",
313
+ "entrypoint": "python3 main.py",
314
+ "setupScript": "setup.sh",
315
+ "model": "",
316
+ "timeout": 300,
317
+ "schedule": "30 2 * * *",
318
+ "timezone": "UTC"
319
+ },
320
+ "upload": {
321
+ "request": {
322
+ "method": "POST",
323
+ "path": "/v1/uploads?name=Uploaded%20maintenance%20script"
324
+ },
325
+ "response": {
326
+ "status": 201,
327
+ "body": {
328
+ "id": "1c0b7ea0-0000-4000-8000-000000000004",
329
+ "status": "COMPLETED",
330
+ "tarball_path": "oh-internal://uploads/1c0b7ea0-0000-4000-8000-000000000004"
331
+ }
332
+ }
333
+ },
334
+ "preflight": {
335
+ "request": {
336
+ "method": "POST",
337
+ "path": "/v1/validate",
338
+ "body": {
339
+ "automationId": "custom-automation",
340
+ "endpoint": "/v1",
341
+ "draft": {
342
+ "name": "Uploaded maintenance script",
343
+ "timeout": 300,
344
+ "trigger": {
345
+ "type": "cron",
346
+ "schedule": "30 2 * * *",
347
+ "timezone": "UTC"
348
+ },
349
+ "tarball_path": "oh-internal://uploads/00000000-0000-0000-0000-000000000000",
350
+ "entrypoint": "python3 main.py",
351
+ "setup_script_path": "setup.sh"
352
+ }
353
+ }
354
+ },
355
+ "response": {
356
+ "status": 200,
357
+ "body": {
358
+ "valid": true,
359
+ "errors": []
360
+ }
361
+ }
362
+ },
363
+ "create": {
364
+ "request": {
365
+ "method": "POST",
366
+ "path": "/v1",
367
+ "body": {
368
+ "name": "Uploaded maintenance script",
369
+ "timeout": 300,
370
+ "trigger": {
371
+ "type": "cron",
372
+ "schedule": "30 2 * * *",
373
+ "timezone": "UTC"
374
+ },
375
+ "tarball_path": "oh-internal://uploads/1c0b7ea0-0000-4000-8000-000000000004",
376
+ "entrypoint": "python3 main.py",
377
+ "setup_script_path": "setup.sh"
378
+ }
379
+ },
380
+ "response": {
381
+ "status": 201,
382
+ "body": {
383
+ "id": "1c0b7ea0-0000-4000-8000-000000000004",
384
+ "model": null,
385
+ "name": "Uploaded maintenance script",
386
+ "trigger": {
387
+ "type": "cron",
388
+ "schedule": "30 2 * * *",
389
+ "timezone": "UTC"
390
+ },
391
+ "timeout": 300,
392
+ "enabled": true
393
+ }
394
+ }
395
+ }
396
+ }
397
+ ]
398
+ }
@@ -50,7 +50,7 @@
50
50
  "automationId": "github-pr-reviewer",
51
51
  "endpoint": "/v1",
52
52
  "draft": {
53
- "name": "GitHub Code Review Agent - OpenHands/agent-server-gui",
53
+ "name": "GitHub code review - OpenHands/agent-server-gui",
54
54
  "trigger": {
55
55
  "type": "cron",
56
56
  "schedule": "*/15 * * * *",
@@ -86,7 +86,7 @@
86
86
  "method": "POST",
87
87
  "path": "/v1",
88
88
  "body": {
89
- "name": "GitHub Code Review Agent - OpenHands/agent-server-gui",
89
+ "name": "GitHub code review - OpenHands/agent-server-gui",
90
90
  "trigger": {
91
91
  "type": "cron",
92
92
  "schedule": "*/15 * * * *",
@@ -115,7 +115,7 @@
115
115
  "user_id": "1a2b3c4d-0000-4000-8000-000000000001",
116
116
  "org_id": "1a2b3c4d-0000-4000-8000-000000000002",
117
117
  "model": null,
118
- "name": "GitHub Code Review Agent - OpenHands/agent-server-gui",
118
+ "name": "GitHub code review - OpenHands/agent-server-gui",
119
119
  "prompt": "Review pull requests labeled 'openhands-review' in OpenHands/agent-server-gui. Review tone: thorough.",
120
120
  "trigger": {
121
121
  "type": "cron",
@@ -179,7 +179,7 @@
179
179
  "automationId": "github-pr-reviewer",
180
180
  "endpoint": "/v1",
181
181
  "draft": {
182
- "name": "GitHub Code Review Agent - 2 repositories",
182
+ "name": "GitHub code review - 2 repositories",
183
183
  "trigger": {
184
184
  "type": "cron",
185
185
  "schedule": "*/15 * * * *",
@@ -216,7 +216,7 @@
216
216
  "method": "POST",
217
217
  "path": "/v1",
218
218
  "body": {
219
- "name": "GitHub Code Review Agent - 2 repositories",
219
+ "name": "GitHub code review - 2 repositories",
220
220
  "trigger": {
221
221
  "type": "cron",
222
222
  "schedule": "*/15 * * * *",
@@ -246,7 +246,7 @@
246
246
  "user_id": "1a2b3c4d-0000-4000-8000-000000000001",
247
247
  "org_id": "1a2b3c4d-0000-4000-8000-000000000002",
248
248
  "model": null,
249
- "name": "GitHub Code Review Agent - 2 repositories",
249
+ "name": "GitHub code review - 2 repositories",
250
250
  "prompt": "Review pull requests labeled 'openhands-review' in OpenHands/agent-server-gui. Review tone: thorough.",
251
251
  "trigger": {
252
252
  "type": "cron",
@@ -300,7 +300,7 @@
300
300
  "automationId": "github-pr-reviewer",
301
301
  "endpoint": "/v1",
302
302
  "draft": {
303
- "name": "GitHub Code Review Agent - OpenHands/agent-server-gui",
303
+ "name": "GitHub code review - OpenHands/agent-server-gui",
304
304
  "trigger": {
305
305
  "type": "cron",
306
306
  "schedule": "*/1 * * * *",
@@ -381,7 +381,7 @@
381
381
  "method": "POST",
382
382
  "path": "/v1",
383
383
  "body": {
384
- "name": "GitHub Code Review Agent - OpenHands/agent-server-gui",
384
+ "name": "GitHub code review - OpenHands/agent-server-gui",
385
385
  "trigger": {
386
386
  "type": "cron",
387
387
  "schedule": "0 0 31 2 *",
@@ -465,7 +465,7 @@
465
465
  "method": "POST",
466
466
  "path": "/v1",
467
467
  "body": {
468
- "name": "GitHub Code Review Agent - OpenHands/agent-server-gui",
468
+ "name": "GitHub code review - OpenHands/agent-server-gui",
469
469
  "trigger": {
470
470
  "type": "cron",
471
471
  "schedule": "*/15 * * * *",