@openhands/extensions 0.16.0 → 0.18.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 (70) hide show
  1. package/.release-please-manifest.json +1 -1
  2. package/AGENTS.md +1 -0
  3. package/README.md +5 -2
  4. package/automations/README.md +78 -11
  5. package/automations/bundle-index.js +18 -0
  6. package/automations/catalog/github-agents-md-maintainer/manifest.json +96 -0
  7. package/automations/catalog/github-issue-to-pr/manifest.json +107 -0
  8. package/automations/catalog/github-pr-reviewer/manifest.json +24 -7
  9. package/automations/catalog/github-repo-monitor/manifest.json +29 -34
  10. package/automations/catalog/jira-issue-to-pr/manifest.json +3 -3
  11. package/automations/catalog/news-digest/manifest.json +76 -0
  12. package/automations/catalog-index.js +13 -7
  13. package/automations/catalog.schema.json +112 -3
  14. package/automations/index.d.ts +66 -1
  15. package/automations/index.js +14 -0
  16. package/automations/interface.json +6 -2
  17. package/automations/interface.schema.json +6 -2
  18. package/index.d.ts +1 -1
  19. package/index.js +1 -1
  20. package/integrations/catalog/posthog.json +41 -3
  21. package/integrations/catalog/sonarqube.json +78 -0
  22. package/integrations/catalog-index.js +65 -63
  23. package/marketplaces/openhands-extensions.json +49 -0
  24. package/package.json +1 -1
  25. package/plugins/qa-changes/action.yml +1 -1
  26. package/pyproject.toml +1 -1
  27. package/python/openhands_extensions/_version.py +1 -1
  28. package/scripts/build-automation-catalog.mjs +30 -0
  29. package/scripts/build-skills-catalog.mjs +24 -7
  30. package/skills/add-skill/SKILL.md +1 -1
  31. package/skills/github-agents-md-maintainer/.plugin/plugin.json +19 -0
  32. package/skills/github-agents-md-maintainer/README.md +59 -0
  33. package/skills/github-agents-md-maintainer/SKILL.md +271 -0
  34. package/skills/github-agents-md-maintainer/commands/agents-md-setup.md +8 -0
  35. package/skills/github-agents-md-maintainer/references/state-schema.md +113 -0
  36. package/skills/github-agents-md-maintainer/scripts/main.py +1187 -0
  37. package/skills/github-issue-to-pr/.plugin/plugin.json +19 -0
  38. package/skills/github-issue-to-pr/README.md +84 -0
  39. package/skills/github-issue-to-pr/SKILL.md +373 -0
  40. package/skills/github-issue-to-pr/commands/issue-to-pr-setup.md +8 -0
  41. package/skills/github-issue-to-pr/references/state-schema.md +139 -0
  42. package/skills/github-issue-to-pr/scripts/main.py +1305 -0
  43. package/skills/github-pr-reviewer/README.md +12 -6
  44. package/skills/github-pr-reviewer/SKILL.md +93 -31
  45. package/skills/github-pr-reviewer/commands/pr-reviewer-setup.md +1 -1
  46. package/skills/github-pr-reviewer/references/state-schema.md +68 -18
  47. package/skills/github-pr-reviewer/scripts/main.py +540 -103
  48. package/skills/github-pr-reviewer/tests/test_main.py +503 -0
  49. package/skills/index.d.ts +6 -0
  50. package/skills/index.js +56 -17
  51. package/skills/jira-issue-to-pr/scripts/main.py +4 -2
  52. package/skills/news-digest/.plugin/plugin.json +19 -0
  53. package/skills/news-digest/README.md +71 -0
  54. package/skills/news-digest/SKILL.md +284 -0
  55. package/skills/news-digest/commands/news-digest-setup.md +8 -0
  56. package/skills/news-digest/references/state-schema.md +178 -0
  57. package/skills/news-digest/scripts/main.py +1250 -0
  58. package/skills/openhands-sdk/SKILL.md +2 -0
  59. package/skills/skill-creator/SKILL.md +1 -1
  60. package/skills/slack-channel-monitor/scripts/main.py +3 -2
  61. package/tests/fixtures/automations/capabilities.json +30 -0
  62. package/tests/fixtures/automations/github-pr-reviewer.json +319 -55
  63. package/tests/fixtures/automations/github-repo-monitor.json +230 -62
  64. package/tests/test_automation_setup.py +260 -31
  65. package/tests/test_catalogs.py +46 -1
  66. package/tests/test_github_agents_md_maintainer.py +352 -0
  67. package/tests/test_github_issue_to_pr.py +539 -0
  68. package/tests/test_news_digest.py +646 -0
  69. package/tests/test_skills_catalog.py +182 -36
  70. package/tests/test_slack_channel_monitor.py +1 -1
@@ -1,20 +1,20 @@
1
1
  {
2
2
  "automationId": "github-repo-monitor",
3
- "description": "Direct GitHub-event setup. Every create request body below is verified against the live CreatePromptAutomationRequest model, and every filter expression against validate_filter() in OpenHands/automation.",
3
+ "description": "Direct scheduled setup. Every create request body below is verified against the live CreatePromptAutomationRequest model in OpenHands/automation (openhands/automation/preset_router.py).",
4
4
  "capabilities": "supported",
5
5
  "blockedBy": [
6
- "cronOnly",
7
6
  "notReady"
8
7
  ],
9
8
  "scenarios": [
10
9
  {
11
10
  "id": "happy-path",
12
- "description": "Watch issue and pull request comments for the default mention phrase.",
11
+ "description": "Defaults plus a repository and a base branch. Preflight passes, the automation is created.",
13
12
  "formValues": {
14
13
  "repository": "OpenHands/agent-server-gui",
15
14
  "triggerPhrase": "@openhands",
16
- "on": "issue_comment.created",
17
- "ref": "main"
15
+ "ref": "main",
16
+ "schedule": "*/15 * * * *",
17
+ "timezone": "UTC"
18
18
  },
19
19
  "preflight": {
20
20
  "request": {
@@ -25,19 +25,29 @@
25
25
  "endpoint": "/v1/preset/prompt",
26
26
  "draft": {
27
27
  "name": "GitHub repository monitor - OpenHands/agent-server-gui",
28
- "prompt": "A comment in OpenHands/agent-server-gui mentions '@openhands'. Read the surrounding issue or pull request context from the event payload, then post a helpful reply as a comment on the same thread.",
28
+ "prompt": "Poll OpenHands/agent-server-gui for any new issue or pull request comments since the last run. For every comment mentioning '@openhands', read the surrounding issue or pull request context and post a helpful reply as a comment on the same thread.",
29
29
  "repos": [
30
30
  {
31
31
  "url": "OpenHands/agent-server-gui",
32
- "ref": "main",
33
- "provider": "github"
32
+ "provider": "github",
33
+ "ref": "main"
34
34
  }
35
35
  ],
36
36
  "trigger": {
37
- "type": "event",
38
- "source": "github",
39
- "on": "issue_comment.created",
40
- "filter": "icontains(comment.body, '@openhands') && glob(repository.full_name, 'OpenHands/agent-server-gui')"
37
+ "type": "cron",
38
+ "schedule": "*/15 * * * *",
39
+ "timezone": "UTC"
40
+ },
41
+ "template": {
42
+ "id": "github-repo-monitor",
43
+ "version": "1.0.0",
44
+ "config": {
45
+ "repository": "OpenHands/agent-server-gui",
46
+ "triggerPhrase": "@openhands",
47
+ "ref": "main",
48
+ "schedule": "*/15 * * * *",
49
+ "timezone": "UTC"
50
+ }
41
51
  }
42
52
  }
43
53
  }
@@ -56,19 +66,29 @@
56
66
  "path": "/v1/preset/prompt",
57
67
  "body": {
58
68
  "name": "GitHub repository monitor - OpenHands/agent-server-gui",
59
- "prompt": "A comment in OpenHands/agent-server-gui mentions '@openhands'. Read the surrounding issue or pull request context from the event payload, then post a helpful reply as a comment on the same thread.",
69
+ "prompt": "Poll OpenHands/agent-server-gui for any new issue or pull request comments since the last run. For every comment mentioning '@openhands', read the surrounding issue or pull request context and post a helpful reply as a comment on the same thread.",
60
70
  "repos": [
61
71
  {
62
72
  "url": "OpenHands/agent-server-gui",
63
- "ref": "main",
64
- "provider": "github"
73
+ "provider": "github",
74
+ "ref": "main"
65
75
  }
66
76
  ],
67
77
  "trigger": {
68
- "type": "event",
69
- "source": "github",
70
- "on": "issue_comment.created",
71
- "filter": "icontains(comment.body, '@openhands') && glob(repository.full_name, 'OpenHands/agent-server-gui')"
78
+ "type": "cron",
79
+ "schedule": "*/15 * * * *",
80
+ "timezone": "UTC"
81
+ },
82
+ "template": {
83
+ "id": "github-repo-monitor",
84
+ "version": "1.0.0",
85
+ "config": {
86
+ "repository": "OpenHands/agent-server-gui",
87
+ "triggerPhrase": "@openhands",
88
+ "ref": "main",
89
+ "schedule": "*/15 * * * *",
90
+ "timezone": "UTC"
91
+ }
72
92
  }
73
93
  }
74
94
  },
@@ -80,12 +100,33 @@
80
100
  "org_id": "1a2b3c4d-0000-4000-8000-000000000002",
81
101
  "model": null,
82
102
  "name": "GitHub repository monitor - OpenHands/agent-server-gui",
83
- "prompt": "A comment in OpenHands/agent-server-gui mentions '@openhands'. Read the surrounding issue or pull request context from the event payload, then post a helpful reply as a comment on the same thread.",
103
+ "prompt": "Poll OpenHands/agent-server-gui for any new issue or pull request comments since the last run. For every comment mentioning '@openhands', read the surrounding issue or pull request context and post a helpful reply as a comment on the same thread.",
104
+ "preset_metadata": {
105
+ "preset_type": "prompt",
106
+ "prompt": "Poll OpenHands/agent-server-gui for any new issue or pull request comments since the last run. For every comment mentioning '@openhands', read the surrounding issue or pull request context and post a helpful reply as a comment on the same thread.",
107
+ "repos": [
108
+ {
109
+ "url": "OpenHands/agent-server-gui",
110
+ "ref": "main",
111
+ "provider": "github"
112
+ }
113
+ ],
114
+ "template": {
115
+ "id": "github-repo-monitor",
116
+ "version": "1.0.0",
117
+ "config": {
118
+ "repository": "OpenHands/agent-server-gui",
119
+ "triggerPhrase": "@openhands",
120
+ "ref": "main",
121
+ "schedule": "*/15 * * * *",
122
+ "timezone": "UTC"
123
+ }
124
+ }
125
+ },
84
126
  "trigger": {
85
- "type": "event",
86
- "source": "github",
87
- "on": "issue_comment.created",
88
- "filter": "icontains(comment.body, '@openhands') && glob(repository.full_name, 'OpenHands/agent-server-gui')"
127
+ "type": "cron",
128
+ "schedule": "*/15 * * * *",
129
+ "timezone": "UTC"
89
130
  },
90
131
  "tarball_path": "oh-internal://uploads/c41e7b28-9d05-4a6b-8f13-2e5c7a90d146",
91
132
  "setup_script_path": "setup.sh",
@@ -101,36 +142,14 @@
101
142
  }
102
143
  },
103
144
  {
104
- "id": "quote-in-trigger-phrase-blocked-locally",
105
- "description": "The trigger phrase is interpolated into a JMESPath string literal, so an apostrophe would break the expression. The field's safeExpressionLiteral constraint rejects it before any request is made. Without that constraint the service returns 422 with: Bad jmespath expression: Unknown token.",
106
- "formValues": {
107
- "repository": "OpenHands/agent-server-gui",
108
- "triggerPhrase": "@open'hands",
109
- "on": "issue_comment.created",
110
- "ref": "main"
111
- },
112
- "localValidation": {
113
- "valid": false,
114
- "errors": [
115
- {
116
- "field": "triggerPhrase",
117
- "constraint": "format",
118
- "message": "Quotes and backslashes are not allowed in the trigger phrase."
119
- }
120
- ]
121
- },
122
- "expectedFieldErrors": {
123
- "triggerPhrase": "Quotes and backslashes are not allowed in the trigger phrase."
124
- }
125
- },
126
- {
127
- "id": "event-type-not-delivered-by-deployment",
128
- "description": "Preflight rejects an event type the deployment does not receive. Nothing is created, so there is no half-broken automation to clean up.",
145
+ "id": "interval-below-deployment-minimum",
146
+ "description": "A one-minute schedule. The create model accepts it, so only the deployment can reject it - this is precisely why preflight exists and why local validation is not authoritative.",
129
147
  "formValues": {
130
148
  "repository": "OpenHands/agent-server-gui",
131
149
  "triggerPhrase": "@openhands",
132
- "on": "pull_request_review_comment.created",
133
- "ref": "main"
150
+ "ref": "main",
151
+ "schedule": "*/1 * * * *",
152
+ "timezone": "UTC"
134
153
  },
135
154
  "preflight": {
136
155
  "request": {
@@ -141,19 +160,29 @@
141
160
  "endpoint": "/v1/preset/prompt",
142
161
  "draft": {
143
162
  "name": "GitHub repository monitor - OpenHands/agent-server-gui",
144
- "prompt": "A comment in OpenHands/agent-server-gui mentions '@openhands'. Read the surrounding issue or pull request context from the event payload, then post a helpful reply as a comment on the same thread.",
163
+ "prompt": "Poll OpenHands/agent-server-gui for any new issue or pull request comments since the last run. For every comment mentioning '@openhands', read the surrounding issue or pull request context and post a helpful reply as a comment on the same thread.",
145
164
  "repos": [
146
165
  {
147
166
  "url": "OpenHands/agent-server-gui",
148
- "ref": "main",
149
- "provider": "github"
167
+ "provider": "github",
168
+ "ref": "main"
150
169
  }
151
170
  ],
152
171
  "trigger": {
153
- "type": "event",
154
- "source": "github",
155
- "on": "pull_request_review_comment.created",
156
- "filter": "icontains(comment.body, '@openhands') && glob(repository.full_name, 'OpenHands/agent-server-gui')"
172
+ "type": "cron",
173
+ "schedule": "*/1 * * * *",
174
+ "timezone": "UTC"
175
+ },
176
+ "template": {
177
+ "id": "github-repo-monitor",
178
+ "version": "1.0.0",
179
+ "config": {
180
+ "repository": "OpenHands/agent-server-gui",
181
+ "triggerPhrase": "@openhands",
182
+ "ref": "main",
183
+ "schedule": "*/1 * * * *",
184
+ "timezone": "UTC"
185
+ }
157
186
  }
158
187
  }
159
188
  }
@@ -164,16 +193,155 @@
164
193
  "valid": false,
165
194
  "errors": [
166
195
  {
167
- "field": "trigger.on",
168
- "code": "event_type_not_delivered",
169
- "message": "No GitHub webhook delivering pull_request_review_comment.created is registered for this organization."
196
+ "field": "trigger.schedule",
197
+ "code": "interval_too_short",
198
+ "message": "Minimum interval for this deployment is 5 minutes."
199
+ }
200
+ ]
201
+ }
202
+ }
203
+ },
204
+ "expectedFieldErrors": {
205
+ "schedule": "Minimum interval for this deployment is 5 minutes."
206
+ }
207
+ },
208
+ {
209
+ "id": "unfireable-cron-rejected-at-create",
210
+ "description": "31 February. Syntactically valid, so a local check passes, but the service rejects it. Shows the real 422 body: detail is a list and the loc path carries the trigger discriminator tag.",
211
+ "formValues": {
212
+ "repository": "OpenHands/agent-server-gui",
213
+ "triggerPhrase": "@openhands",
214
+ "ref": "main",
215
+ "schedule": "0 0 31 2 *",
216
+ "timezone": "UTC"
217
+ },
218
+ "create": {
219
+ "request": {
220
+ "method": "POST",
221
+ "path": "/v1/preset/prompt",
222
+ "body": {
223
+ "name": "GitHub repository monitor - OpenHands/agent-server-gui",
224
+ "prompt": "Poll OpenHands/agent-server-gui for any new issue or pull request comments since the last run. For every comment mentioning '@openhands', read the surrounding issue or pull request context and post a helpful reply as a comment on the same thread.",
225
+ "repos": [
226
+ {
227
+ "url": "OpenHands/agent-server-gui",
228
+ "provider": "github",
229
+ "ref": "main"
230
+ }
231
+ ],
232
+ "trigger": {
233
+ "type": "cron",
234
+ "schedule": "0 0 31 2 *",
235
+ "timezone": "UTC"
236
+ },
237
+ "template": {
238
+ "id": "github-repo-monitor",
239
+ "version": "1.0.0",
240
+ "config": {
241
+ "repository": "OpenHands/agent-server-gui",
242
+ "triggerPhrase": "@openhands",
243
+ "ref": "main",
244
+ "schedule": "0 0 31 2 *",
245
+ "timezone": "UTC"
246
+ }
247
+ }
248
+ }
249
+ },
250
+ "response": {
251
+ "status": 422,
252
+ "body": {
253
+ "detail": [
254
+ {
255
+ "type": "value_error",
256
+ "loc": [
257
+ "body",
258
+ "trigger",
259
+ "cron",
260
+ "schedule"
261
+ ],
262
+ "msg": "Value error, Cron expression cannot produce any future fire times: 0 0 31 2 *"
170
263
  }
171
264
  ]
172
265
  }
173
266
  }
174
267
  },
175
268
  "expectedFieldErrors": {
176
- "on": "No GitHub webhook delivering pull_request_review_comment.created is registered for this organization."
269
+ "schedule": "Value error, Cron expression cannot produce any future fire times: 0 0 31 2 *"
270
+ }
271
+ },
272
+ {
273
+ "id": "short-repo-url-without-provider-is-rejected",
274
+ "description": "The mapping bug this fixture set exists to prevent. A short owner/repo URL without an explicit provider is a hard 422, because CreatePromptAutomationRequest is extra-forbid and RepoSource requires the provider. The setup block's payload always sets it; this records what happens if that is ever dropped.",
275
+ "formValues": {
276
+ "repository": "OpenHands/agent-server-gui",
277
+ "triggerPhrase": "@openhands",
278
+ "ref": "main",
279
+ "schedule": "*/15 * * * *",
280
+ "timezone": "UTC"
281
+ },
282
+ "create": {
283
+ "request": {
284
+ "method": "POST",
285
+ "path": "/v1/preset/prompt",
286
+ "body": {
287
+ "name": "GitHub repository monitor - OpenHands/agent-server-gui",
288
+ "prompt": "Poll OpenHands/agent-server-gui for any new issue or pull request comments since the last run. For every comment mentioning '@openhands', read the surrounding issue or pull request context and post a helpful reply as a comment on the same thread.",
289
+ "repos": [
290
+ {
291
+ "url": "OpenHands/agent-server-gui"
292
+ }
293
+ ],
294
+ "trigger": {
295
+ "type": "cron",
296
+ "schedule": "*/15 * * * *",
297
+ "timezone": "UTC"
298
+ },
299
+ "template": {
300
+ "id": "github-repo-monitor",
301
+ "version": "1.0.0",
302
+ "config": {
303
+ "repository": "OpenHands/agent-server-gui",
304
+ "triggerPhrase": "@openhands",
305
+ "ref": "main",
306
+ "schedule": "*/15 * * * *",
307
+ "timezone": "UTC"
308
+ }
309
+ }
310
+ }
311
+ },
312
+ "response": {
313
+ "status": 422,
314
+ "body": {
315
+ "detail": [
316
+ {
317
+ "type": "value_error",
318
+ "loc": [
319
+ "body",
320
+ "repos",
321
+ 0
322
+ ],
323
+ "msg": "Value error, Short URL format 'OpenHands/agent-server-gui' requires explicit 'provider' field. Use: {\"url\": \"owner/repo\", \"provider\": \"github\"} or provide a full URL like https://github.com/owner/repo"
324
+ }
325
+ ]
326
+ }
327
+ }
328
+ },
329
+ "matchesSetupPayload": false
330
+ },
331
+ {
332
+ "id": "fallback-conversation-when-direct-unavailable",
333
+ "description": "A deployment that cannot run the scheduled monitor seeds the setup conversation with this message; the agent confirms the repository, trigger phrase, and polling schedule there.",
334
+ "formValues": {
335
+ "repository": "OpenHands/agent-server-gui",
336
+ "triggerPhrase": "@openhands",
337
+ "ref": "main",
338
+ "schedule": "*/15 * * * *",
339
+ "timezone": "UTC"
340
+ },
341
+ "conversation": {
342
+ "request": {
343
+ "message": "This deployment cannot run the scheduled monitor directly. Set it up in this conversation instead: confirm the repository to watch, the trigger phrase, and the polling schedule, then create the automation."
344
+ }
177
345
  }
178
346
  }
179
347
  ]