@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,3 +1,3 @@
1
1
  {
2
- ".": "0.16.0"
2
+ ".": "0.18.0"
3
3
  }
package/AGENTS.md CHANGED
@@ -87,6 +87,7 @@ When editing or adding skills in this repo, follow these rules (and add new skil
87
87
  ## Repository conventions
88
88
 
89
89
  - **Punctuation style**: Use plain hyphens (`-`) instead of em dashes (`—` / `\u2014`) in skill descriptions, SKILL.md content, and marketplace JSON entries.
90
+ - **`defaultEnabled` on marketplace skill entries**: a skill entry may carry `"defaultEnabled": true`, which means the skill is enabled for every **new** workspace. Omit the field for everything else - absence already means off, so `"defaultEnabled": false` is not written. Keep the set small and provider-agnostic; anything language-, vendor- or workflow-specific should start off and be opted into from the catalog UI. `npm run build:skills` joins the flag into `skills/index.js` and exports `DEFAULT_ENABLED_SKILL_NAMES` for hosts to seed a workspace from. Seeding is all it does: the contract hosts implement is that a workspace which already saved a selection keeps it, so adding the flag to a skill later will not retroactively enable it for existing users.
90
91
  - Keep formatting consistent across skills.
91
92
  - If you change a skill’s behavior or scope, update its `README.md` (if present) accordingly.
92
93
  - If you change top-level documentation, ensure links still resolve.
package/README.md CHANGED
@@ -89,7 +89,7 @@ The JS and Python versions are kept in lock-step by `release-please` and guarded
89
89
  ## Extensions Catalog
90
90
 
91
91
  <!-- BEGIN AUTO-GENERATED CATALOG -->
92
- This repository contains **2 marketplace(s)** with **64 extensions** (54 skills, 10 plugins).
92
+ This repository contains **2 marketplace(s)** with **67 extensions** (57 skills, 10 plugins).
93
93
 
94
94
  ### large-codebase
95
95
 
@@ -108,7 +108,7 @@ OpenHands skills for interacting, improving, and refactoring large codebases
108
108
 
109
109
  Official skills and plugins for OpenHands — the open-source AI software engineer.
110
110
 
111
- **60 extensions** (52 skills, 8 plugins)
111
+ **63 extensions** (55 skills, 8 plugins)
112
112
 
113
113
  | Name | Type | Description | Commands |
114
114
  |------|------|-------------|----------|
@@ -133,6 +133,8 @@ Official skills and plugins for OpenHands — the open-source AI software engine
133
133
  | frontend-design | skill | Create distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks ... | — |
134
134
  | github | skill | Interact with GitHub repositories, pull requests, issues, and workflows using the GITHUB_TOKEN environment variable a... | — |
135
135
  | github-actions | skill | Create, debug, and test GitHub Actions workflows and custom actions. Use when building CI/CD pipelines, automating wo... | — |
136
+ | github-agents-md-maintainer | skill | Create an automation that keeps AGENTS.md current in one or more GitHub repositories. On a schedule an agent reads th... | `/agents-md:setup` |
137
+ | github-issue-to-pr | skill | Create an automation that implements GitHub issues when a configurable trigger label is applied. Clones the default b... | `/issue-to-pr:setup` |
136
138
  | github-pr-review | skill | Post structured PR reviews to GitHub with inline comments/suggestions in a single API call. | `/github-pr-review` |
137
139
  | github-pr-reviewer | skill | Create an automation that reviews GitHub pull requests when they are opened or updated. Inspects the diff, changed fi... | `/pr-reviewer:setup` |
138
140
  | github-repo-monitor | skill | Create a cron automation that polls a GitHub repository for issue and PR comments containing a configurable trigger p... | `/github-monitor:poll` |
@@ -146,6 +148,7 @@ Official skills and plugins for OpenHands — the open-source AI software engine
146
148
  | linear | skill | Interact with Linear project management - query issues, update status, create tickets using the Linear GraphQL API. | — |
147
149
  | linear-triage | skill | Create an automation that triages new Linear issues by inspecting title, description, team, and recent related issues... | `/linear-triage:setup` |
148
150
  | magic-test | plugin | A simple test plugin for verifying plugin loading. Triggers on magic words (alakazam, abracadabra) and returns a spec... | — |
151
+ | news-digest | skill | Create an automation that reads public RSS and Atom feeds on a schedule, keeps what is new and matches the configured... | `/news-digest:setup` |
149
152
  | notion | skill | Create, search, and update Notion pages/databases using the Notion API. Use for documenting work, generating runbooks... | — |
150
153
  | npm | skill | Handle npm package installation in non-interactive environments by piping confirmations. Use when installing Node.js ... | — |
151
154
  | onboarding | plugin | Assess repository agent-readiness across five pillars, propose high-impact fixes, and generate repo-specific AGENTS.m... | — |
@@ -2,8 +2,9 @@
2
2
 
3
3
  `catalog/<id>/` is one automation. Its `manifest.json` is the single hand-authored source of truth: the
4
4
  card metadata Agent Canvas renders today and, optionally, a nested `setup` block, the extension-owned
5
- configuration experience for that automation. Anything else an automation ships, such as a script that is
6
- uploaded to the automations service as a `.tar.gz`, belongs in the same directory.
5
+ configuration experience for that automation. It is the only file there. A script an automation uploads as
6
+ a `.tar.gz` is not copied into this directory: `setup.bundle.files` names where it already lives, so a
7
+ script shipped by both a skill and the catalog has one copy rather than two.
7
8
 
8
9
  ```
9
10
  catalog/<id>/manifest.json one automation per directory - card metadata plus an optional `setup` block
@@ -50,7 +51,8 @@ two records of the same fact from drifting apart, and it is why the file is as s
50
51
  | `trigger` in the create request | The key under `form.triggers`, and the fields under it named after trigger properties |
51
52
  | Which input a rejected payload path belongs to | Rebuilding that body with each field standing in for its own value |
52
53
  | The review screen | The fields and their labels |
53
- | The create endpoint | `POST /v1/preset/prompt` |
54
+ | The create endpoint | `POST /v1/preset/prompt`, or `POST /v1` for an entry that ships a bundle |
55
+ | The files a bundle packs | `setup.bundle.files`, read from this repository at build time |
54
56
  | Where a success navigates | The created automation, or the started conversation |
55
57
  | The analytics stages | The same stages for every automation |
56
58
 
@@ -103,8 +105,7 @@ That way a skill can rename its trigger without leaving a stale copy behind in t
103
105
  `form` separates the two things a user is configuring, and both are keyed by field name:
104
106
 
105
107
  - **`form.triggers`** decides *when* the automation runs, keyed by trigger kind (`cron` or `event`).
106
- `github-pr-reviewer` asks for a schedule and a timezone; `github-repo-monitor` asks which GitHub event to
107
- answer and which phrase to match.
108
+ `github-pr-reviewer` and `github-repo-monitor` each ask for a schedule and a timezone.
108
109
  - **`form.args`** is everything else: the arguments to the automation itself, such as the repository to
109
110
  clone and the tone of the review.
110
111
 
@@ -124,11 +125,71 @@ when the deployment cannot run the direct path - a deployment whose capabilities
124
125
  kind or required features. The same 2000-character cap applies, and because the fallback fires before the
125
126
  form is trustworthy, a direct `message` should not reference `{{form.*}}`.
126
127
 
128
+ A `repo-picker` may declare `multiple: true`, and then it collects several
129
+ repositories and its value is a list. A placeholder that is the *whole* value
130
+ resolves to that list rather than to text, which is what lets `"repos":
131
+ "{{form.repositories}}"` produce an array; the same placeholder inside a
132
+ sentence still reads as text. On the preset path the list becomes one `repos[]`
133
+ entry per repository. The created automation is named after the single
134
+ repository when there is one and after the count when there are several, since a
135
+ list of names does not fit a name.
136
+
127
137
  A form field is named after the property it fills. `schedule` and `timezone` under `triggers.cron` become
128
138
  `trigger.schedule` and `trigger.timezone`; `on` under `triggers.event` becomes `trigger.on`; a field named
129
139
  `ref` becomes `repos[].ref`. Any other field under a trigger kind, such as a phrase to match, is an input
130
140
  to `filter` rather than a trigger property.
131
141
 
142
+ ### Entries that ship a script
143
+
144
+ `mode: "direct"` produces either a `prompt` or a `bundle`, never both. A prompt
145
+ is the right shape when the automation *is* the judgement: the agent reads the
146
+ prompt and does the work. A bundle is the right shape when most of what the
147
+ automation does is deterministic machinery - polling, dedupe, state, fixed API
148
+ calls - and the agent is needed only for the part that genuinely needs judgement.
149
+ `github-pr-reviewer` is the first: its script owns discovery, label-event
150
+ dedupe, per-repo state and the review checkout, and starts a conversation only
151
+ once a pull request actually needs reviewing.
152
+
153
+ ```jsonc
154
+ "bundle": {
155
+ "version": "1.0.0", // provenance; bump when the files or config shape change
156
+ "entrypoint": "python3 main.py", // run inside the extracted tarball
157
+ "timeout": 600, // when the service default is not enough
158
+ "files": { // packed path -> where it lives in this repo
159
+ "main.py": "skills/github-pr-reviewer/scripts/main.py"
160
+ },
161
+ "config": { // rendered from the form, packed as config.json
162
+ "repos": "{{form.repositories}}", // a whole-value placeholder, so this is a list
163
+ "trigger_label": "{{form.triggerLabel}}",
164
+ "review_tone": "{{form.reviewTone}}"
165
+ }
166
+ }
167
+ ```
168
+
169
+ The host packs those files plus the rendered `config.json`, `POST`s the archive
170
+ to `uploads`, and creates from the `oh-internal://` path that comes back. What it
171
+ sends is otherwise the same restatement of the form as the preset path, plus the
172
+ `template` provenance that makes enabling an entry twice return the automation
173
+ that already exists rather than a duplicate (`OpenHands/automation#344`).
174
+
175
+ Two things follow from the archetype rather than being stated:
176
+
177
+ - **`files` names paths, not contents.** The reviewer script is shipped by both
178
+ its skill and this catalog, and a second copy would drift. `npm run
179
+ build:automations` inlines the contents into `automations/bundle-index.js`,
180
+ which is what `getAutomationBundleFiles(id)` returns - a host packing the
181
+ archive has the published package, not this repository.
182
+ - **`config` is the bundle's `prompt`.** Everything else in the create request is
183
+ read off the form; only the entry knows which key of its own script each field
184
+ fills. The script reads that file over its own defaults, so the agent-driven
185
+ skill path, which substitutes the same values as constants, keeps working
186
+ unchanged.
187
+
188
+ A bundle declares `requires.features: ["customTarball"]`: a deployment that
189
+ cannot run a client-supplied tarball cannot run the entry, whatever trigger kinds
190
+ it offers. It never declares `repos` - the raw create endpoint has no such field,
191
+ and a bundle fetches what it needs itself.
192
+
132
193
  ### Format constraints
133
194
 
134
195
  A setup block is data that instructs another repo to render copy and build a request, so the schema is the
@@ -151,10 +212,14 @@ entered and `{{automation.*}}` for the entry itself. There is deliberately no se
151
212
 
152
213
  | Entry | Archetype | Trigger | Produces |
153
214
  | --- | --- | --- | --- |
154
- | `github-pr-reviewer` | Direct scheduled | `cron` | a create payload |
155
- | `github-repo-monitor` | Direct GitHub-event | `event` on `github` with a JMESPath filter | a create payload |
215
+ | `github-pr-reviewer` | Direct scheduled, script bundle | `cron` | an upload, then a create payload |
216
+ | `github-repo-monitor` | Direct scheduled | `cron` | a create payload |
156
217
  | `incident-retrospective-drafter` | Assisted conversation | decided during the conversation | a seed message |
157
218
 
219
+ An event archetype is still expressible - `github-repo-monitor` used one until its deployment could no
220
+ longer receive webhooks, and was converted to the polled `cron` form. The schema keeps supporting `event`
221
+ triggers for deployments that can. See the `event` key under `setup.form.triggers` in `catalog.schema.json`.
222
+
158
223
  The assisted archetype has no payload and no preflight, because at the end of its flow no automation exists
159
224
  yet. The agent creates it during the conversation, and the service validates it there. That is the defining
160
225
  property of the archetype, not an omission.
@@ -164,10 +229,10 @@ property of the archetype, not an omission.
164
229
  `skill` and `exampleImplementation` describe the **current** path: Agent Canvas launches that skill, and the
165
230
  agent builds the automation. `setup` describes the **declarative** path that replaces it.
166
231
 
167
- They can differ in more than wording. `github-repo-monitor`'s skill polls GitHub on a cron and states that
168
- a webhook variant is out of scope, while its `setup` block creates the webhook form the service already
169
- supports. Both statements are accurate about their own generation. Retiring the skill path for entries that
170
- ship a `setup` block belongs to whoever promotes this to production.
232
+ They can differ in more than wording. `github-repo-monitor`'s skill polls GitHub on a cron, and its `setup`
233
+ block declares the same polled `cron` form, so the two generations agree. (It once declared an `event`
234
+ form; when the deployment stopped receiving webhooks it was converted to this polling one.) Retiring the
235
+ skill path for entries that ship a `setup` block belongs to whoever promotes this to production.
171
236
 
172
237
  ## The interface manifest (`interface.json`)
173
238
 
@@ -260,6 +325,8 @@ Two findings came out of that check and are baked into the entries:
260
325
  | Endpoint | Status |
261
326
  | --- | --- |
262
327
  | `POST /v1/preset/prompt` | Exists |
328
+ | `POST /v1/uploads` | Exists |
329
+ | `POST /v1` | Exists; accepts `template` provenance from OpenHands/automation#344 |
263
330
  | `GET /v1/capabilities` | Exists (OpenHands/automation#270) |
264
331
  | `POST /v1/validate` | Exists (OpenHands/automation#270) |
265
332