@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.
- package/.release-please-manifest.json +1 -1
- package/AGENTS.md +1 -0
- package/README.md +5 -2
- package/automations/README.md +78 -11
- package/automations/bundle-index.js +18 -0
- package/automations/catalog/github-agents-md-maintainer/manifest.json +96 -0
- package/automations/catalog/github-issue-to-pr/manifest.json +107 -0
- package/automations/catalog/github-pr-reviewer/manifest.json +24 -7
- package/automations/catalog/github-repo-monitor/manifest.json +29 -34
- package/automations/catalog/jira-issue-to-pr/manifest.json +3 -3
- package/automations/catalog/news-digest/manifest.json +76 -0
- package/automations/catalog-index.js +13 -7
- package/automations/catalog.schema.json +112 -3
- package/automations/index.d.ts +66 -1
- package/automations/index.js +14 -0
- package/automations/interface.json +6 -2
- package/automations/interface.schema.json +6 -2
- package/index.d.ts +1 -1
- package/index.js +1 -1
- package/integrations/catalog/posthog.json +41 -3
- package/integrations/catalog/sonarqube.json +78 -0
- package/integrations/catalog-index.js +65 -63
- package/marketplaces/openhands-extensions.json +49 -0
- package/package.json +1 -1
- package/plugins/qa-changes/action.yml +1 -1
- package/pyproject.toml +1 -1
- package/python/openhands_extensions/_version.py +1 -1
- package/scripts/build-automation-catalog.mjs +30 -0
- package/scripts/build-skills-catalog.mjs +24 -7
- package/skills/add-skill/SKILL.md +1 -1
- package/skills/github-agents-md-maintainer/.plugin/plugin.json +19 -0
- package/skills/github-agents-md-maintainer/README.md +59 -0
- package/skills/github-agents-md-maintainer/SKILL.md +271 -0
- package/skills/github-agents-md-maintainer/commands/agents-md-setup.md +8 -0
- package/skills/github-agents-md-maintainer/references/state-schema.md +113 -0
- package/skills/github-agents-md-maintainer/scripts/main.py +1187 -0
- package/skills/github-issue-to-pr/.plugin/plugin.json +19 -0
- package/skills/github-issue-to-pr/README.md +84 -0
- package/skills/github-issue-to-pr/SKILL.md +373 -0
- package/skills/github-issue-to-pr/commands/issue-to-pr-setup.md +8 -0
- package/skills/github-issue-to-pr/references/state-schema.md +139 -0
- package/skills/github-issue-to-pr/scripts/main.py +1305 -0
- package/skills/github-pr-reviewer/README.md +12 -6
- package/skills/github-pr-reviewer/SKILL.md +93 -31
- package/skills/github-pr-reviewer/commands/pr-reviewer-setup.md +1 -1
- package/skills/github-pr-reviewer/references/state-schema.md +68 -18
- package/skills/github-pr-reviewer/scripts/main.py +540 -103
- package/skills/github-pr-reviewer/tests/test_main.py +503 -0
- package/skills/index.d.ts +6 -0
- package/skills/index.js +56 -17
- package/skills/jira-issue-to-pr/scripts/main.py +4 -2
- package/skills/news-digest/.plugin/plugin.json +19 -0
- package/skills/news-digest/README.md +71 -0
- package/skills/news-digest/SKILL.md +284 -0
- package/skills/news-digest/commands/news-digest-setup.md +8 -0
- package/skills/news-digest/references/state-schema.md +178 -0
- package/skills/news-digest/scripts/main.py +1250 -0
- package/skills/openhands-sdk/SKILL.md +2 -0
- package/skills/skill-creator/SKILL.md +1 -1
- package/skills/slack-channel-monitor/scripts/main.py +3 -2
- package/tests/fixtures/automations/capabilities.json +30 -0
- package/tests/fixtures/automations/github-pr-reviewer.json +319 -55
- package/tests/fixtures/automations/github-repo-monitor.json +230 -62
- package/tests/test_automation_setup.py +260 -31
- package/tests/test_catalogs.py +46 -1
- package/tests/test_github_agents_md_maintainer.py +352 -0
- package/tests/test_github_issue_to_pr.py +539 -0
- package/tests/test_news_digest.py +646 -0
- package/tests/test_skills_catalog.py +182 -36
- package/tests/test_slack_channel_monitor.py +1 -1
|
@@ -21,8 +21,17 @@
|
|
|
21
21
|
"pattern": "^[a-z0-9]+(-[a-z0-9]+)*$",
|
|
22
22
|
"description": "Stable identifier. Must equal the name of the directory holding this manifest."
|
|
23
23
|
},
|
|
24
|
+
"version": {
|
|
25
|
+
"type": "string",
|
|
26
|
+
"pattern": "^\\d+\\.\\d+\\.\\d+$",
|
|
27
|
+
"description": "Semantic version of this template. Present only on entries whose direct setup sends provenance to the automation service; bump it when the prompt, form, or filter changes meaningfully."
|
|
28
|
+
},
|
|
24
29
|
"name": { "type": "string", "minLength": 1 },
|
|
25
30
|
"category": { "type": "string", "minLength": 1 },
|
|
31
|
+
"icon": {
|
|
32
|
+
"description": "The glyph the card shows, named from the same closed set the interface manifest's navigation uses. Absent means the host derives one from requires.integrations, which is right for an automation whose identity is the service it talks to and wrong for one whose identity is the work itself.",
|
|
33
|
+
"enum": ["layout-dashboard", "sparkles", "bot", "circle-alert", "activity", "timer"]
|
|
34
|
+
},
|
|
26
35
|
"description": { "type": "string", "minLength": 1 },
|
|
27
36
|
"requires": { "$ref": "#/$defs/requires" },
|
|
28
37
|
"popularityRank": { "type": "integer", "minimum": 0 },
|
|
@@ -63,6 +72,10 @@
|
|
|
63
72
|
"description": "direct only. What the automation is told to do. The rest of the create request restates the form, so it is not written here: the automation's name comes from this entry, the repository from the repo-picker field, and the trigger from the key and fields under form.triggers.",
|
|
64
73
|
"$ref": "#/$defs/templateValue"
|
|
65
74
|
},
|
|
75
|
+
"bundle": {
|
|
76
|
+
"description": "direct only, and the alternative to prompt. The script tarball this entry ships: the automation is deterministic machinery rather than judgement, so it runs as its own code and the host creates it through the raw create endpoint instead of a preset. The rest of the create request still restates the form, so it is not written here either.",
|
|
77
|
+
"$ref": "#/$defs/bundle"
|
|
78
|
+
},
|
|
66
79
|
"filter": {
|
|
67
80
|
"description": "direct only, and only for an event trigger. The expression deciding whether a delivered event belongs to this automation. It composes form values into a JMESPath expression, which is the one part of an event trigger that cannot be read off the form.",
|
|
68
81
|
"$ref": "#/$defs/templateValue"
|
|
@@ -79,7 +92,10 @@
|
|
|
79
92
|
"required": ["mode"]
|
|
80
93
|
},
|
|
81
94
|
"then": {
|
|
82
|
-
"
|
|
95
|
+
"oneOf": [
|
|
96
|
+
{ "required": ["prompt"], "not": { "required": ["bundle"] } },
|
|
97
|
+
{ "required": ["bundle"], "not": { "required": ["prompt"] } }
|
|
98
|
+
]
|
|
83
99
|
}
|
|
84
100
|
},
|
|
85
101
|
{
|
|
@@ -91,6 +107,7 @@
|
|
|
91
107
|
"required": ["message"],
|
|
92
108
|
"allOf": [
|
|
93
109
|
{ "not": { "required": ["prompt"] } },
|
|
110
|
+
{ "not": { "required": ["bundle"] } },
|
|
94
111
|
{ "not": { "required": ["filter"] } }
|
|
95
112
|
]
|
|
96
113
|
}
|
|
@@ -108,6 +125,88 @@
|
|
|
108
125
|
"required": ["form"]
|
|
109
126
|
},
|
|
110
127
|
"then": { "not": { "required": ["filter"] } }
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
"if": { "required": ["bundle"] },
|
|
131
|
+
"then": { "not": { "required": ["filter"] } }
|
|
132
|
+
}
|
|
133
|
+
]
|
|
134
|
+
},
|
|
135
|
+
"bundle": {
|
|
136
|
+
"description": "What the host packs into a .tar.gz and uploads before creating the automation. It names files inside this repository and the command that runs them - never a host, a URL, or code to evaluate.",
|
|
137
|
+
"type": "object",
|
|
138
|
+
"additionalProperties": false,
|
|
139
|
+
"required": ["version", "entrypoint", "files", "config"],
|
|
140
|
+
"properties": {
|
|
141
|
+
"version": {
|
|
142
|
+
"description": "The version of this bundle, recorded as the created automation's template provenance. Bump it when the shipped files or the config shape change: it is what tells an already-enabled deployment that what it installed is no longer current. Not the package version, which moves for reasons that have nothing to do with this entry.",
|
|
143
|
+
"type": "string",
|
|
144
|
+
"minLength": 1,
|
|
145
|
+
"maxLength": 50,
|
|
146
|
+
"pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$"
|
|
147
|
+
},
|
|
148
|
+
"entrypoint": {
|
|
149
|
+
"description": "The command the automation service runs inside the extracted tarball, such as `python3 main.py`. No shell metacharacters: the service rejects them, and a bundle has no reason to need one.",
|
|
150
|
+
"type": "string",
|
|
151
|
+
"minLength": 1,
|
|
152
|
+
"maxLength": 500,
|
|
153
|
+
"pattern": "^[A-Za-z0-9 ._/-]+$"
|
|
154
|
+
},
|
|
155
|
+
"setupScript": {
|
|
156
|
+
"description": "Path inside the tarball to a script run once before the entrypoint, such as `setup.sh`. Absent when the bundle needs no installation step, which is the case for a standard-library script.",
|
|
157
|
+
"type": "string",
|
|
158
|
+
"minLength": 1,
|
|
159
|
+
"maxLength": 255,
|
|
160
|
+
"pattern": "^[A-Za-z0-9._-]+(/[A-Za-z0-9._-]+)*$",
|
|
161
|
+
"not": { "pattern": "(^|/)\\.\\.?(/|$)" }
|
|
162
|
+
},
|
|
163
|
+
"timeout": {
|
|
164
|
+
"description": "Seconds a single run may take, when this entry needs more than the service default. A poll that fetches an archive per queued item needs longer than one that only calls an API.",
|
|
165
|
+
"type": "integer",
|
|
166
|
+
"minimum": 1,
|
|
167
|
+
"maximum": 86400
|
|
168
|
+
},
|
|
169
|
+
"files": {
|
|
170
|
+
"description": "The tarball's contents, keyed by the path each file takes inside the archive and valued by where it lives in this repository. Stated rather than derived from the entry directory, so a script shipped by both a skill and the catalog has one copy rather than two.",
|
|
171
|
+
"type": "object",
|
|
172
|
+
"minProperties": 1,
|
|
173
|
+
"maxProperties": 32,
|
|
174
|
+
"propertyNames": {
|
|
175
|
+
"pattern": "^[A-Za-z0-9._-]+(/[A-Za-z0-9._-]+)*$",
|
|
176
|
+
"not": { "pattern": "(^|/)\\.\\.?(/|$)" },
|
|
177
|
+
"maxLength": 255
|
|
178
|
+
},
|
|
179
|
+
"additionalProperties": { "$ref": "#/$defs/bundleSource" }
|
|
180
|
+
},
|
|
181
|
+
"config": {
|
|
182
|
+
"description": "The config.json packed beside the entrypoint, rendered from the form. This is the bundle's analogue of prompt: the one thing that cannot be read off the form, because only the entry knows which key of its own script each field fills.",
|
|
183
|
+
"$ref": "#/$defs/bundleConfig"
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
},
|
|
187
|
+
"bundleSource": {
|
|
188
|
+
"description": "A file in this repository, as a repository-relative path under skills/ or automations/. No absolute path, no traversal, and no scheme, so a bundle cannot name anything outside the published package.",
|
|
189
|
+
"type": "string",
|
|
190
|
+
"minLength": 1,
|
|
191
|
+
"maxLength": 255,
|
|
192
|
+
"pattern": "^(skills|automations)/[A-Za-z0-9._-]+(/[A-Za-z0-9._-]+)*$",
|
|
193
|
+
"not": { "pattern": "(^|/)\\.\\.?(/|$)" }
|
|
194
|
+
},
|
|
195
|
+
"bundleConfig": {
|
|
196
|
+
"description": "The JSON document written to config.json. Its string leaves may embed the same placeholders every other value uses. It carries no markup rule, because it is written to a file rather than rendered.",
|
|
197
|
+
"type": "object",
|
|
198
|
+
"minProperties": 1,
|
|
199
|
+
"additionalProperties": { "$ref": "#/$defs/bundleConfigValue" }
|
|
200
|
+
},
|
|
201
|
+
"bundleConfigValue": {
|
|
202
|
+
"description": "A config leaf: a templated string, a number, a boolean, null, or an array or object of the same.",
|
|
203
|
+
"anyOf": [
|
|
204
|
+
{ "$ref": "#/$defs/templateValue" },
|
|
205
|
+
{ "type": ["number", "boolean", "null"] },
|
|
206
|
+
{ "type": "array", "items": { "$ref": "#/$defs/bundleConfigValue" } },
|
|
207
|
+
{
|
|
208
|
+
"type": "object",
|
|
209
|
+
"additionalProperties": { "$ref": "#/$defs/bundleConfigValue" }
|
|
111
210
|
}
|
|
112
211
|
]
|
|
113
212
|
},
|
|
@@ -143,9 +242,8 @@
|
|
|
143
242
|
"required": ["integrations"],
|
|
144
243
|
"properties": {
|
|
145
244
|
"integrations": {
|
|
146
|
-
"description": "Keyed by integration id, each of which must resolve to an integrations/catalog entry.",
|
|
245
|
+
"description": "Keyed by integration id, each of which must resolve to an integrations/catalog entry. Empty when the automation connects to nothing and needs no credential - a requirement worth stating, and the reason the key stays required rather than becoming optional.",
|
|
147
246
|
"type": "object",
|
|
148
|
-
"minProperties": 1,
|
|
149
247
|
"propertyNames": { "type": "string", "minLength": 1 },
|
|
150
248
|
"additionalProperties": {
|
|
151
249
|
"type": "object",
|
|
@@ -224,6 +322,10 @@
|
|
|
224
322
|
"default": { "type": "string" },
|
|
225
323
|
"required": { "type": "boolean" },
|
|
226
324
|
"provider": { "enum": ["github", "gitlab", "bitbucket"] },
|
|
325
|
+
"multiple": {
|
|
326
|
+
"description": "repo-picker only. The field collects several repositories rather than one, and its value is a list. A whole-value placeholder resolves to that list, so a payload can state `\"repos\": \"{{form.repositories}}\"` and get an array.",
|
|
327
|
+
"const": true
|
|
328
|
+
},
|
|
227
329
|
"options": {
|
|
228
330
|
"type": "array",
|
|
229
331
|
"minItems": 1,
|
|
@@ -259,6 +361,13 @@
|
|
|
259
361
|
},
|
|
260
362
|
"then": { "required": ["provider"] }
|
|
261
363
|
},
|
|
364
|
+
{
|
|
365
|
+
"if": {
|
|
366
|
+
"properties": { "type": { "not": { "const": "repo-picker" } } },
|
|
367
|
+
"required": ["type"]
|
|
368
|
+
},
|
|
369
|
+
"then": { "not": { "required": ["multiple"] } }
|
|
370
|
+
},
|
|
262
371
|
{
|
|
263
372
|
"if": {
|
|
264
373
|
"properties": { "type": { "not": { "const": "select" } } },
|
package/automations/index.d.ts
CHANGED
|
@@ -1,7 +1,24 @@
|
|
|
1
1
|
export interface RecommendedAutomation {
|
|
2
2
|
id: string;
|
|
3
|
+
/**
|
|
4
|
+
* Semantic version of this template. Present only on entries whose direct
|
|
5
|
+
* setup sends provenance to the automation service; bumped when the prompt,
|
|
6
|
+
* form, or filter changes meaningfully.
|
|
7
|
+
*/
|
|
8
|
+
version?: string;
|
|
3
9
|
name: string;
|
|
4
10
|
category: string;
|
|
11
|
+
/**
|
|
12
|
+
* The glyph the card shows, from the closed set the interface manifest's
|
|
13
|
+
* navigation uses. Absent means the host derives one from the integrations.
|
|
14
|
+
*/
|
|
15
|
+
icon?:
|
|
16
|
+
| "layout-dashboard"
|
|
17
|
+
| "sparkles"
|
|
18
|
+
| "bot"
|
|
19
|
+
| "circle-alert"
|
|
20
|
+
| "activity"
|
|
21
|
+
| "timer";
|
|
5
22
|
description: string;
|
|
6
23
|
requires: AutomationPrerequisites;
|
|
7
24
|
popularityRank: number;
|
|
@@ -63,6 +80,11 @@ export interface AutomationFormField {
|
|
|
63
80
|
default?: string;
|
|
64
81
|
required: boolean;
|
|
65
82
|
provider?: AutomationGitProvider;
|
|
83
|
+
/**
|
|
84
|
+
* repo-picker only. The field collects several repositories rather than one,
|
|
85
|
+
* and its value is a list. A whole-value placeholder resolves to that list.
|
|
86
|
+
*/
|
|
87
|
+
multiple?: true;
|
|
66
88
|
options?: AutomationFieldOption[];
|
|
67
89
|
constraints?: AutomationFieldConstraints;
|
|
68
90
|
}
|
|
@@ -78,7 +100,7 @@ export interface AutomationIntegrationRequirement {
|
|
|
78
100
|
}
|
|
79
101
|
|
|
80
102
|
export interface AutomationPrerequisites {
|
|
81
|
-
/** Keyed by integration catalog id. */
|
|
103
|
+
/** Keyed by integration catalog id. Empty when the automation needs nothing connected. */
|
|
82
104
|
integrations: Record<string, AutomationIntegrationRequirement>;
|
|
83
105
|
/** Deployment capabilities this automation cannot run without. */
|
|
84
106
|
features?: string[];
|
|
@@ -96,12 +118,40 @@ export interface AutomationForm {
|
|
|
96
118
|
args: AutomationFormFields;
|
|
97
119
|
}
|
|
98
120
|
|
|
121
|
+
/** A config.json leaf: templated string, number, boolean, null, or a nesting of those. */
|
|
122
|
+
export type AutomationBundleConfigValue =
|
|
123
|
+
| string
|
|
124
|
+
| number
|
|
125
|
+
| boolean
|
|
126
|
+
| null
|
|
127
|
+
| AutomationBundleConfigValue[]
|
|
128
|
+
| { [key: string]: AutomationBundleConfigValue };
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* The script tarball a direct entry may ship instead of a prompt, for an
|
|
132
|
+
* automation that is deterministic machinery rather than judgement.
|
|
133
|
+
*/
|
|
134
|
+
export interface AutomationBundle {
|
|
135
|
+
/** The command run inside the extracted tarball. */
|
|
136
|
+
entrypoint: string;
|
|
137
|
+
/** Script run once before the entrypoint. Absent when nothing to install. */
|
|
138
|
+
setupScript?: string;
|
|
139
|
+
/** Seconds a run may take, when the service default is not enough. */
|
|
140
|
+
timeout?: number;
|
|
141
|
+
/** Packed path -> the repository path the file is read from at build time. */
|
|
142
|
+
files: Record<string, string>;
|
|
143
|
+
/** Rendered from the form and packed as config.json beside the entrypoint. */
|
|
144
|
+
config: Record<string, AutomationBundleConfigValue>;
|
|
145
|
+
}
|
|
146
|
+
|
|
99
147
|
export interface AutomationSetup {
|
|
100
148
|
version: "1.0";
|
|
101
149
|
mode: AutomationSetupMode;
|
|
102
150
|
form: AutomationForm;
|
|
103
151
|
/** direct only. What the automation is told to do. */
|
|
104
152
|
prompt?: string;
|
|
153
|
+
/** direct only, and the alternative to `prompt`. Exactly one is present. */
|
|
154
|
+
bundle?: AutomationBundle;
|
|
105
155
|
/** direct only, event trigger only. Which delivered events belong to it. */
|
|
106
156
|
filter?: string;
|
|
107
157
|
/**
|
|
@@ -337,6 +387,10 @@ export interface AutomationInterfaceEndpoints {
|
|
|
337
387
|
validate: string;
|
|
338
388
|
createPrompt: string;
|
|
339
389
|
createPlugin: string;
|
|
390
|
+
/** The raw create endpoint, which a bundle entry is created through. */
|
|
391
|
+
createBundle: string;
|
|
392
|
+
/** Where a bundle's tarball is uploaded before that create call. */
|
|
393
|
+
uploads: string;
|
|
340
394
|
}
|
|
341
395
|
|
|
342
396
|
export interface AutomationInterfaceManifest {
|
|
@@ -365,4 +419,15 @@ export function listAutomationCatalog(): RecommendedAutomation[];
|
|
|
365
419
|
export function getAutomationCatalogEntry(
|
|
366
420
|
id: string,
|
|
367
421
|
): RecommendedAutomation | undefined;
|
|
422
|
+
/**
|
|
423
|
+
* Return the files a bundle entry ships, keyed by the path each takes inside
|
|
424
|
+
* the tarball, as an independent copy. Undefined for an entry with no bundle.
|
|
425
|
+
*
|
|
426
|
+
* The contents are inlined at build time from the repository paths
|
|
427
|
+
* `setup.bundle.files` names, because a host packing the tarball has the
|
|
428
|
+
* published package but not the repository.
|
|
429
|
+
*/
|
|
430
|
+
export function getAutomationBundleFiles(
|
|
431
|
+
id: string,
|
|
432
|
+
): Record<string, string> | undefined;
|
|
368
433
|
export default AUTOMATION_CATALOG;
|
package/automations/index.js
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* directory. `catalog-index.js` is generated from that directory so the JS
|
|
6
6
|
* package can statically import each JSON file without an aggregate JSON asset.
|
|
7
7
|
*/
|
|
8
|
+
import { AUTOMATION_BUNDLE_FILES } from "./bundle-index.js";
|
|
8
9
|
import { AUTOMATION_CATALOG_ENTRIES } from "./catalog-index.js";
|
|
9
10
|
import interfaceManifest from "./interface.json" with { type: "json" };
|
|
10
11
|
|
|
@@ -21,6 +22,19 @@ export const getAutomationCatalogEntry = (id) => {
|
|
|
21
22
|
|
|
22
23
|
export const AUTOMATION_CATALOG = clone(AUTOMATIONS);
|
|
23
24
|
|
|
25
|
+
/**
|
|
26
|
+
* The files a bundle entry ships, keyed by entry id and then by the path each
|
|
27
|
+
* file takes inside the tarball. Generated from the repository paths the
|
|
28
|
+
* entry's `setup.bundle.files` names, because a host packing the tarball has
|
|
29
|
+
* the package but not the repository.
|
|
30
|
+
*
|
|
31
|
+
* Absent for every entry that does not ship a bundle.
|
|
32
|
+
*/
|
|
33
|
+
export const getAutomationBundleFiles = (id) => {
|
|
34
|
+
const files = AUTOMATION_BUNDLE_FILES[id];
|
|
35
|
+
return files ? clone(files) : undefined;
|
|
36
|
+
};
|
|
37
|
+
|
|
24
38
|
/**
|
|
25
39
|
* The production Automation interface manifest: the domain-level facts of the
|
|
26
40
|
* interface, hand-authored in `automations/interface.json`.
|
|
@@ -144,11 +144,15 @@
|
|
|
144
144
|
"capabilities": "/v1/capabilities",
|
|
145
145
|
"validate": "/v1/validate",
|
|
146
146
|
"createPrompt": "/v1/preset/prompt",
|
|
147
|
-
"createPlugin": "/v1/preset/plugin"
|
|
147
|
+
"createPlugin": "/v1/preset/plugin",
|
|
148
|
+
"createBundle": "/v1",
|
|
149
|
+
"uploads": "/v1/uploads"
|
|
148
150
|
},
|
|
149
151
|
"featuredAutomationIds": [
|
|
150
152
|
"github-pr-reviewer",
|
|
151
|
-
"github-
|
|
153
|
+
"github-agents-md-maintainer",
|
|
154
|
+
"news-digest",
|
|
155
|
+
"github-issue-to-pr",
|
|
152
156
|
"slack-channel-monitor"
|
|
153
157
|
],
|
|
154
158
|
"responderIntegrationIds": ["github", "slack"]
|
|
@@ -178,7 +178,9 @@
|
|
|
178
178
|
"capabilities",
|
|
179
179
|
"validate",
|
|
180
180
|
"createPrompt",
|
|
181
|
-
"createPlugin"
|
|
181
|
+
"createPlugin",
|
|
182
|
+
"createBundle",
|
|
183
|
+
"uploads"
|
|
182
184
|
],
|
|
183
185
|
"properties": {
|
|
184
186
|
"list": { "$ref": "#/$defs/plainEndpoint" },
|
|
@@ -190,7 +192,9 @@
|
|
|
190
192
|
"capabilities": { "$ref": "#/$defs/plainEndpoint" },
|
|
191
193
|
"validate": { "$ref": "#/$defs/plainEndpoint" },
|
|
192
194
|
"createPrompt": { "$ref": "#/$defs/plainEndpoint" },
|
|
193
|
-
"createPlugin": { "$ref": "#/$defs/plainEndpoint" }
|
|
195
|
+
"createPlugin": { "$ref": "#/$defs/plainEndpoint" },
|
|
196
|
+
"createBundle": { "$ref": "#/$defs/plainEndpoint" },
|
|
197
|
+
"uploads": { "$ref": "#/$defs/plainEndpoint" }
|
|
194
198
|
}
|
|
195
199
|
},
|
|
196
200
|
"featuredAutomationIds": {
|
package/index.d.ts
CHANGED
|
@@ -42,5 +42,5 @@ export type {
|
|
|
42
42
|
AutomationInterfacePages,
|
|
43
43
|
AutomationInterfaceRoutes,
|
|
44
44
|
} from "./automations/index.js";
|
|
45
|
-
export { SKILLS_CATALOG } from "./skills/index.js";
|
|
45
|
+
export { SKILLS_CATALOG, DEFAULT_ENABLED_SKILL_NAMES } from "./skills/index.js";
|
|
46
46
|
export type { SkillCatalogEntry } from "./skills/index.js";
|
package/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { INTEGRATION_CATALOG } from "./integrations/index.js";
|
|
2
2
|
export { AUTOMATION_CATALOG, AUTOMATION_INTERFACE } from "./automations/index.js";
|
|
3
|
-
export { SKILLS_CATALOG } from "./skills/index.js";
|
|
3
|
+
export { SKILLS_CATALOG, DEFAULT_ENABLED_SKILL_NAMES } from "./skills/index.js";
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
],
|
|
9
9
|
"appUrl": "https://posthog.com",
|
|
10
10
|
"docsUrl": "https://posthog.com/docs/model-context-protocol",
|
|
11
|
-
"notes": "
|
|
11
|
+
"notes": "Uses PostHog's official hosted MCP server. OAuth is preferred; the bearer-token option remains for clients or deployments that require a personal API key. The OAuth URL defaults to read-only mode; remove readonly=true only when write access has been approved.",
|
|
12
12
|
"popularityRank": 37,
|
|
13
13
|
"iconBg": "#1D4AFF",
|
|
14
14
|
"logoUrl": "https://cdn.simpleicons.org/posthog/FFFFFF",
|
|
@@ -18,8 +18,44 @@
|
|
|
18
18
|
"product",
|
|
19
19
|
"experiments"
|
|
20
20
|
],
|
|
21
|
-
"installHint": "
|
|
21
|
+
"installHint": "Prefer OAuth. The default OAuth connection uses read-only MCP mode; edit the URL or use the bearer-key fallback only when a workflow needs approved write access. For API keys, create a PostHog personal API key with the MCP Server preset.",
|
|
22
22
|
"connectionOptions": [
|
|
23
|
+
{
|
|
24
|
+
"id": "oauth",
|
|
25
|
+
"provider": "mcp",
|
|
26
|
+
"auth": {
|
|
27
|
+
"strategy": "oauth2",
|
|
28
|
+
"oauth": {
|
|
29
|
+
"authorizationUrl": "https://oauth.posthog.com/oauth/authorize/",
|
|
30
|
+
"tokenUrl": "https://oauth.posthog.com/oauth/token/",
|
|
31
|
+
"registrationUrl": "https://oauth.posthog.com/oauth/register/",
|
|
32
|
+
"scopes": [
|
|
33
|
+
"openid",
|
|
34
|
+
"profile",
|
|
35
|
+
"email",
|
|
36
|
+
"organization:read",
|
|
37
|
+
"project:read",
|
|
38
|
+
"dashboard:read",
|
|
39
|
+
"insight:read",
|
|
40
|
+
"query:read",
|
|
41
|
+
"event_definition:read"
|
|
42
|
+
],
|
|
43
|
+
"pkce": true,
|
|
44
|
+
"clientAuthentication": "none",
|
|
45
|
+
"additionalAuthorizationParams": {
|
|
46
|
+
"resource": "https://mcp.posthog.com/mcp"
|
|
47
|
+
},
|
|
48
|
+
"additionalTokenParams": {
|
|
49
|
+
"resource": "https://mcp.posthog.com/mcp"
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
"transport": {
|
|
54
|
+
"kind": "shttp",
|
|
55
|
+
"url": "https://mcp.posthog.com/mcp?readonly=true",
|
|
56
|
+
"urlEditable": true
|
|
57
|
+
}
|
|
58
|
+
},
|
|
23
59
|
{
|
|
24
60
|
"id": "api-key",
|
|
25
61
|
"provider": "mcp",
|
|
@@ -31,7 +67,9 @@
|
|
|
31
67
|
"strategy": "bearer",
|
|
32
68
|
"credentialLabel": "PostHog personal API key",
|
|
33
69
|
"credentialPlaceholder": "Paste your PostHog personal API key",
|
|
34
|
-
"credentialHelp": "Create one under PostHog
|
|
70
|
+
"credentialHelp": "Create one under PostHog > User settings > API keys using the MCP Server preset. Sent as Authorization: Bearer <token>.",
|
|
71
|
+
"credentialSecretName": "POSTHOG_PERSONAL_API_KEY",
|
|
72
|
+
"saveCredentialAsSecretByDefault": true
|
|
35
73
|
}
|
|
36
74
|
}
|
|
37
75
|
]
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "sonarqube",
|
|
3
|
+
"name": "SonarQube",
|
|
4
|
+
"description": "Inspect code quality and security findings, quality gates, and analyze code snippets from SonarQube Server or Cloud.",
|
|
5
|
+
"categories": [
|
|
6
|
+
"Engineering",
|
|
7
|
+
"Security"
|
|
8
|
+
],
|
|
9
|
+
"appUrl": "https://www.sonarsource.com/products/sonarqube/mcp-server/",
|
|
10
|
+
"docsUrl": "https://github.com/SonarSource/sonarqube-mcp-server",
|
|
11
|
+
"notes": "Uses SonarSource's official SonarQube MCP Server, run locally as a Docker container. Provide a SonarQube user token. Set SONARQUBE_ORG for SonarQube Cloud, or SONARQUBE_URL for a self-managed SonarQube Server (or https://sonarqube.us for SonarQube Cloud US).",
|
|
12
|
+
"popularityRank": 43,
|
|
13
|
+
"installHint": "SONARQUBE_TOKEN is always required. For SonarQube Cloud, set your organization key in SONARQUBE_ORG. For a self-managed SonarQube Server, set SONARQUBE_URL to your server URL; for SonarQube Cloud US, set SONARQUBE_URL to https://sonarqube.us. Requires a container runtime such as Docker.",
|
|
14
|
+
"connectionOptions": [
|
|
15
|
+
{
|
|
16
|
+
"id": "api",
|
|
17
|
+
"provider": "mcp",
|
|
18
|
+
"transport": {
|
|
19
|
+
"kind": "stdio",
|
|
20
|
+
"serverName": "sonarqube",
|
|
21
|
+
"command": "docker",
|
|
22
|
+
"args": [
|
|
23
|
+
"run",
|
|
24
|
+
"--init",
|
|
25
|
+
"--pull=always",
|
|
26
|
+
"-i",
|
|
27
|
+
"--rm",
|
|
28
|
+
"-e",
|
|
29
|
+
"SONARQUBE_TOKEN",
|
|
30
|
+
"-e",
|
|
31
|
+
"SONARQUBE_ORG",
|
|
32
|
+
"-e",
|
|
33
|
+
"SONARQUBE_URL",
|
|
34
|
+
"sonarsource/sonarqube-mcp"
|
|
35
|
+
],
|
|
36
|
+
"envFields": [
|
|
37
|
+
{
|
|
38
|
+
"key": "SONARQUBE_TOKEN",
|
|
39
|
+
"label": "SonarQube token",
|
|
40
|
+
"type": "password",
|
|
41
|
+
"required": true,
|
|
42
|
+
"helperText": "User token generated in your SonarQube Server or Cloud account settings.",
|
|
43
|
+
"helperLink": "https://docs.sonarsource.com/sonarqube-cloud/managing-your-account/managing-tokens/"
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"key": "SONARQUBE_ORG",
|
|
47
|
+
"label": "Organization key (SonarQube Cloud)",
|
|
48
|
+
"type": "text",
|
|
49
|
+
"required": false,
|
|
50
|
+
"placeholder": "my-org",
|
|
51
|
+
"helperText": "Required for SonarQube Cloud. Your organization key, found in SonarQube Cloud."
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"key": "SONARQUBE_URL",
|
|
55
|
+
"label": "Server URL (SonarQube Server)",
|
|
56
|
+
"type": "text",
|
|
57
|
+
"required": false,
|
|
58
|
+
"placeholder": "https://sonarqube.example.com",
|
|
59
|
+
"helperText": "Required for a self-managed SonarQube Server. For SonarQube Cloud US, use https://sonarqube.us."
|
|
60
|
+
}
|
|
61
|
+
]
|
|
62
|
+
},
|
|
63
|
+
"auth": {
|
|
64
|
+
"strategy": "api_key"
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
],
|
|
68
|
+
"iconBg": "#126ED3",
|
|
69
|
+
"logoUrl": "https://cdn.simpleicons.org/sonarqubeserver/FFFFFF",
|
|
70
|
+
"keywords": [
|
|
71
|
+
"code quality",
|
|
72
|
+
"static analysis",
|
|
73
|
+
"security",
|
|
74
|
+
"sast",
|
|
75
|
+
"quality gate",
|
|
76
|
+
"sonarcloud"
|
|
77
|
+
]
|
|
78
|
+
}
|