@openhands/extensions 0.4.2 → 0.6.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 (134) hide show
  1. package/.github/workflows/pypi-publish.yml +104 -0
  2. package/.github/workflows/tests.yml +6 -0
  3. package/.release-please-manifest.json +1 -1
  4. package/AGENTS.md +1 -1
  5. package/README.md +31 -3
  6. package/automations/catalog/slack-channel-monitor.json +2 -2
  7. package/integrations/README.md +17 -7
  8. package/integrations/catalog/airtable.json +40 -10
  9. package/integrations/catalog/apify.json +0 -2
  10. package/integrations/catalog/asana.json +38 -0
  11. package/integrations/catalog/atlassian.json +5 -8
  12. package/integrations/catalog/bitbucket.json +39 -0
  13. package/integrations/catalog/box.json +39 -0
  14. package/integrations/catalog/brave-search.json +1 -2
  15. package/integrations/catalog/browser-mcp.json +0 -3
  16. package/integrations/catalog/canva.json +35 -0
  17. package/integrations/catalog/clickhouse.json +1 -2
  18. package/integrations/catalog/clickup.json +36 -0
  19. package/integrations/catalog/cloudflare-bindings.json +5 -8
  20. package/integrations/catalog/cloudflare-browser-rendering.json +5 -8
  21. package/integrations/catalog/cloudflare-builds.json +6 -9
  22. package/integrations/catalog/cloudflare-docs.json +4 -7
  23. package/integrations/catalog/cloudflare-observability.json +5 -8
  24. package/integrations/catalog/confluence.json +38 -0
  25. package/integrations/catalog/datadog.json +34 -0
  26. package/integrations/catalog/deepwiki.json +3 -7
  27. package/integrations/catalog/discord.json +39 -0
  28. package/integrations/catalog/dropbox.json +38 -0
  29. package/integrations/catalog/elevenlabs.json +27 -28
  30. package/integrations/catalog/everything.json +0 -2
  31. package/integrations/catalog/exa.json +0 -2
  32. package/integrations/catalog/fetch.json +0 -2
  33. package/integrations/catalog/figma.json +41 -9
  34. package/integrations/catalog/filesystem.json +0 -3
  35. package/integrations/catalog/firecrawl.json +0 -2
  36. package/integrations/catalog/freshdesk.json +38 -0
  37. package/integrations/catalog/git.json +0 -3
  38. package/integrations/catalog/github.json +51 -34
  39. package/integrations/catalog/gitlab.json +38 -0
  40. package/integrations/catalog/gmail.json +38 -0
  41. package/integrations/catalog/google-calendar.json +38 -0
  42. package/integrations/catalog/google-docs.json +38 -0
  43. package/integrations/catalog/google-drive.json +38 -0
  44. package/integrations/catalog/google-sheets.json +38 -0
  45. package/integrations/catalog/hubspot.json +34 -0
  46. package/integrations/catalog/huggingface.json +1 -2
  47. package/integrations/catalog/intercom.json +39 -0
  48. package/integrations/catalog/jira.json +38 -0
  49. package/integrations/catalog/kagi.json +2 -3
  50. package/integrations/catalog/linear.json +47 -16
  51. package/integrations/catalog/mailchimp.json +38 -0
  52. package/integrations/catalog/memory.json +0 -2
  53. package/integrations/catalog/microsoft-outlook.json +38 -0
  54. package/integrations/catalog/microsoft-teams.json +38 -0
  55. package/integrations/catalog/miro.json +38 -0
  56. package/integrations/catalog/monday.json +38 -0
  57. package/integrations/catalog/mongodb.json +1 -2
  58. package/integrations/catalog/neon.json +0 -2
  59. package/integrations/catalog/netlify.json +38 -0
  60. package/integrations/catalog/notion.json +37 -10
  61. package/integrations/catalog/obsidian.json +1 -3
  62. package/integrations/catalog/okta.json +38 -0
  63. package/integrations/catalog/onedrive.json +38 -0
  64. package/integrations/catalog/ordinal.json +33 -0
  65. package/integrations/catalog/paypal.json +5 -8
  66. package/integrations/catalog/pipedrive.json +39 -0
  67. package/integrations/catalog/plaid.json +31 -0
  68. package/integrations/catalog/playwright.json +0 -2
  69. package/integrations/catalog/posthog.json +38 -0
  70. package/integrations/catalog/quickbooks.json +38 -0
  71. package/integrations/catalog/redis.json +1 -3
  72. package/integrations/catalog/resend.json +1 -2
  73. package/integrations/catalog/salesforce.json +38 -0
  74. package/integrations/catalog/sentry.json +52 -14
  75. package/integrations/catalog/sequential-thinking.json +0 -2
  76. package/integrations/catalog/servicenow.json +39 -0
  77. package/integrations/catalog/sharepoint.json +38 -0
  78. package/integrations/catalog/shopify.json +38 -0
  79. package/integrations/catalog/slack.json +49 -10
  80. package/integrations/catalog/stripe.json +44 -14
  81. package/integrations/catalog/supabase.json +36 -9
  82. package/integrations/catalog/tavily.json +0 -2
  83. package/integrations/catalog/time.json +0 -2
  84. package/integrations/catalog/trello.json +31 -0
  85. package/integrations/catalog/vercel.json +38 -0
  86. package/integrations/catalog/webflow.json +34 -0
  87. package/integrations/catalog/xero.json +38 -0
  88. package/integrations/catalog/zendesk.json +38 -0
  89. package/integrations/catalog/zoom.json +38 -0
  90. package/integrations/catalog-index.js +171 -0
  91. package/integrations/index.d.ts +26 -60
  92. package/integrations/index.js +29 -207
  93. package/marketplaces/openhands-extensions.json +14 -1
  94. package/package.json +4 -7
  95. package/plugins/cobol-modernization/README.md +3 -3
  96. package/plugins/cobol-modernization/skills/{cobol-modernization-overview → cobol-modernization}/SKILL.md +1 -1
  97. package/plugins/magic-test/skills/magic-word/SKILL.md +1 -0
  98. package/plugins/migration-scoring/README.md +1 -1
  99. package/pyproject.toml +17 -3
  100. package/python/openhands_extensions/__init__.py +24 -0
  101. package/python/openhands_extensions/_version.py +24 -0
  102. package/python/openhands_extensions/integrations.py +92 -0
  103. package/release-please-config.json +2 -1
  104. package/scripts/build-integration-catalog.mjs +45 -0
  105. package/skills/agent-canvas-environment/.plugin/plugin.json +19 -0
  106. package/skills/agent-canvas-environment/README.md +5 -0
  107. package/skills/agent-canvas-environment/SKILL.md +141 -0
  108. package/skills/github-pr-reviewer/references/state-schema.md +18 -4
  109. package/skills/github-pr-reviewer/scripts/main.py +66 -12
  110. package/skills/github-repo-monitor/references/state-schema.md +11 -4
  111. package/skills/github-repo-monitor/scripts/main.py +67 -19
  112. package/skills/github-repo-monitor/tests/test_main.py +67 -8
  113. package/skills/index.js +19 -5
  114. package/skills/openhands-api/README.md +5 -1
  115. package/skills/openhands-api/SKILL.md +74 -5
  116. package/skills/openhands-automation/SKILL.md +3 -1
  117. package/skills/openhands-automation/references/custom-automation.md +166 -0
  118. package/skills/openhands-sdk/SKILL.md +8 -2
  119. package/skills/slack-channel-monitor/README.md +9 -5
  120. package/skills/slack-channel-monitor/SKILL.md +16 -6
  121. package/skills/slack-channel-monitor/references/slack-api.md +5 -3
  122. package/skills/slack-channel-monitor/references/state-schema.md +70 -36
  123. package/skills/slack-channel-monitor/scripts/main.py +335 -63
  124. package/tests/test_catalogs.py +21 -3
  125. package/tests/test_integration_catalog_in_sync.py +204 -0
  126. package/tests/test_slack_channel_monitor.py +142 -0
  127. package/tests/test_version_alignment.py +64 -0
  128. package/integrations/logos.d.ts +0 -5
  129. package/integrations/logos.js +0 -94
  130. package/integrations/oauth-provider-catalog.js +0 -553
  131. package/integrations/oauth-provider-registration-defaults.js +0 -610
  132. /package/plugins/cobol-modernization/skills/{mainfraime-removal → mainframe-removal}/SKILL.md +0 -0
  133. /package/plugins/cobol-modernization/skills/{mainfraime-removal → mainframe-removal}/references/cics-transformation-examples.md +0 -0
  134. /package/plugins/migration-scoring/skills/{migration-scoring-overview → migration-scoring}/SKILL.md +0 -0
@@ -0,0 +1,171 @@
1
+ // This file is auto-generated by scripts/build-integration-catalog.mjs.
2
+ // Do not edit it manually. To update it after changing integrations/catalog/*.json,
3
+ // run: npm run build:integrations
4
+
5
+ import entry0 from "./catalog/github.json" with { type: "json" };
6
+ import entry1 from "./catalog/slack.json" with { type: "json" };
7
+ import entry2 from "./catalog/tavily.json" with { type: "json" };
8
+ import entry3 from "./catalog/linear.json" with { type: "json" };
9
+ import entry4 from "./catalog/notion.json" with { type: "json" };
10
+ import entry5 from "./catalog/ordinal.json" with { type: "json" };
11
+ import entry6 from "./catalog/elevenlabs.json" with { type: "json" };
12
+ import entry7 from "./catalog/bitbucket.json" with { type: "json" };
13
+ import entry8 from "./catalog/gitlab.json" with { type: "json" };
14
+ import entry9 from "./catalog/xero.json" with { type: "json" };
15
+ import entry10 from "./catalog/quickbooks.json" with { type: "json" };
16
+ import entry11 from "./catalog/mailchimp.json" with { type: "json" };
17
+ import entry12 from "./catalog/pipedrive.json" with { type: "json" };
18
+ import entry13 from "./catalog/freshdesk.json" with { type: "json" };
19
+ import entry14 from "./catalog/servicenow.json" with { type: "json" };
20
+ import entry15 from "./catalog/okta.json" with { type: "json" };
21
+ import entry16 from "./catalog/plaid.json" with { type: "json" };
22
+ import entry17 from "./catalog/netlify.json" with { type: "json" };
23
+ import entry18 from "./catalog/vercel.json" with { type: "json" };
24
+ import entry19 from "./catalog/supabase.json" with { type: "json" };
25
+ import entry20 from "./catalog/posthog.json" with { type: "json" };
26
+ import entry21 from "./catalog/sentry.json" with { type: "json" };
27
+ import entry22 from "./catalog/datadog.json" with { type: "json" };
28
+ import entry23 from "./catalog/canva.json" with { type: "json" };
29
+ import entry24 from "./catalog/miro.json" with { type: "json" };
30
+ import entry25 from "./catalog/webflow.json" with { type: "json" };
31
+ import entry26 from "./catalog/zoom.json" with { type: "json" };
32
+ import entry27 from "./catalog/discord.json" with { type: "json" };
33
+ import entry28 from "./catalog/shopify.json" with { type: "json" };
34
+ import entry29 from "./catalog/stripe.json" with { type: "json" };
35
+ import entry30 from "./catalog/intercom.json" with { type: "json" };
36
+ import entry31 from "./catalog/zendesk.json" with { type: "json" };
37
+ import entry32 from "./catalog/hubspot.json" with { type: "json" };
38
+ import entry33 from "./catalog/salesforce.json" with { type: "json" };
39
+ import entry34 from "./catalog/sharepoint.json" with { type: "json" };
40
+ import entry35 from "./catalog/onedrive.json" with { type: "json" };
41
+ import entry36 from "./catalog/microsoft-teams.json" with { type: "json" };
42
+ import entry37 from "./catalog/microsoft-outlook.json" with { type: "json" };
43
+ import entry38 from "./catalog/box.json" with { type: "json" };
44
+ import entry39 from "./catalog/dropbox.json" with { type: "json" };
45
+ import entry40 from "./catalog/airtable.json" with { type: "json" };
46
+ import entry41 from "./catalog/monday.json" with { type: "json" };
47
+ import entry42 from "./catalog/clickup.json" with { type: "json" };
48
+ import entry43 from "./catalog/trello.json" with { type: "json" };
49
+ import entry44 from "./catalog/asana.json" with { type: "json" };
50
+ import entry45 from "./catalog/confluence.json" with { type: "json" };
51
+ import entry46 from "./catalog/jira.json" with { type: "json" };
52
+ import entry47 from "./catalog/google-calendar.json" with { type: "json" };
53
+ import entry48 from "./catalog/gmail.json" with { type: "json" };
54
+ import entry49 from "./catalog/google-sheets.json" with { type: "json" };
55
+ import entry50 from "./catalog/google-drive.json" with { type: "json" };
56
+ import entry51 from "./catalog/figma.json" with { type: "json" };
57
+ import entry52 from "./catalog/google-docs.json" with { type: "json" };
58
+ import entry53 from "./catalog/apify.json" with { type: "json" };
59
+ import entry54 from "./catalog/atlassian.json" with { type: "json" };
60
+ import entry55 from "./catalog/brave-search.json" with { type: "json" };
61
+ import entry56 from "./catalog/browser-mcp.json" with { type: "json" };
62
+ import entry57 from "./catalog/clickhouse.json" with { type: "json" };
63
+ import entry58 from "./catalog/cloudflare-bindings.json" with { type: "json" };
64
+ import entry59 from "./catalog/cloudflare-browser-rendering.json" with { type: "json" };
65
+ import entry60 from "./catalog/cloudflare-builds.json" with { type: "json" };
66
+ import entry61 from "./catalog/cloudflare-docs.json" with { type: "json" };
67
+ import entry62 from "./catalog/cloudflare-observability.json" with { type: "json" };
68
+ import entry63 from "./catalog/deepwiki.json" with { type: "json" };
69
+ import entry64 from "./catalog/everything.json" with { type: "json" };
70
+ import entry65 from "./catalog/exa.json" with { type: "json" };
71
+ import entry66 from "./catalog/fetch.json" with { type: "json" };
72
+ import entry67 from "./catalog/filesystem.json" with { type: "json" };
73
+ import entry68 from "./catalog/firecrawl.json" with { type: "json" };
74
+ import entry69 from "./catalog/git.json" with { type: "json" };
75
+ import entry70 from "./catalog/huggingface.json" with { type: "json" };
76
+ import entry71 from "./catalog/kagi.json" with { type: "json" };
77
+ import entry72 from "./catalog/memory.json" with { type: "json" };
78
+ import entry73 from "./catalog/mongodb.json" with { type: "json" };
79
+ import entry74 from "./catalog/neon.json" with { type: "json" };
80
+ import entry75 from "./catalog/obsidian.json" with { type: "json" };
81
+ import entry76 from "./catalog/paypal.json" with { type: "json" };
82
+ import entry77 from "./catalog/playwright.json" with { type: "json" };
83
+ import entry78 from "./catalog/redis.json" with { type: "json" };
84
+ import entry79 from "./catalog/resend.json" with { type: "json" };
85
+ import entry80 from "./catalog/sequential-thinking.json" with { type: "json" };
86
+ import entry81 from "./catalog/time.json" with { type: "json" };
87
+
88
+ export const INTEGRATION_CATALOG_ENTRIES = [
89
+ entry0,
90
+ entry1,
91
+ entry2,
92
+ entry3,
93
+ entry4,
94
+ entry5,
95
+ entry6,
96
+ entry7,
97
+ entry8,
98
+ entry9,
99
+ entry10,
100
+ entry11,
101
+ entry12,
102
+ entry13,
103
+ entry14,
104
+ entry15,
105
+ entry16,
106
+ entry17,
107
+ entry18,
108
+ entry19,
109
+ entry20,
110
+ entry21,
111
+ entry22,
112
+ entry23,
113
+ entry24,
114
+ entry25,
115
+ entry26,
116
+ entry27,
117
+ entry28,
118
+ entry29,
119
+ entry30,
120
+ entry31,
121
+ entry32,
122
+ entry33,
123
+ entry34,
124
+ entry35,
125
+ entry36,
126
+ entry37,
127
+ entry38,
128
+ entry39,
129
+ entry40,
130
+ entry41,
131
+ entry42,
132
+ entry43,
133
+ entry44,
134
+ entry45,
135
+ entry46,
136
+ entry47,
137
+ entry48,
138
+ entry49,
139
+ entry50,
140
+ entry51,
141
+ entry52,
142
+ entry53,
143
+ entry54,
144
+ entry55,
145
+ entry56,
146
+ entry57,
147
+ entry58,
148
+ entry59,
149
+ entry60,
150
+ entry61,
151
+ entry62,
152
+ entry63,
153
+ entry64,
154
+ entry65,
155
+ entry66,
156
+ entry67,
157
+ entry68,
158
+ entry69,
159
+ entry70,
160
+ entry71,
161
+ entry72,
162
+ entry73,
163
+ entry74,
164
+ entry75,
165
+ entry76,
166
+ entry77,
167
+ entry78,
168
+ entry79,
169
+ entry80,
170
+ entry81,
171
+ ];
@@ -59,6 +59,8 @@ export interface IntegrationAuthConfig {
59
59
  credentialLabel?: string;
60
60
  credentialPlaceholder?: string;
61
61
  credentialHelp?: string;
62
+ credentialSecretName?: string;
63
+ saveCredentialAsSecretByDefault?: boolean;
62
64
  apiKeyHeaderName?: string;
63
65
  apiKeyOptional?: boolean;
64
66
  oauth?: IntegrationOAuthConfig;
@@ -86,52 +88,9 @@ export interface IntegrationConnectionOption {
86
88
  auth: IntegrationAuthConfig;
87
89
  }
88
90
 
89
- export interface OAuthProviderRegistrationDefaults {
90
- provider?: IntegrationProvider;
91
- authModes?: IntegrationAuthStrategy[];
92
- authStrategy?: IntegrationAuthStrategy;
93
- credentialLabel?: string;
94
- credentialPlaceholder?: string;
95
- credentialHelp?: string;
96
- apiKeyHeaderName?: string;
97
- apiBaseUrl?: string;
98
- serverUrl?: string;
99
- openApiUrl?: string;
100
- authorizationUrl?: string;
101
- tokenUrl?: string;
102
- scopes?: string[];
103
- optionalScopes?: string[];
104
- toolScopes?: string[];
105
- scopeSeparator?: "space" | "comma";
106
- pkce?: boolean;
107
- clientAuthentication?: "basic" | "body" | "none";
108
- registrationUrl?: string;
109
- additionalAuthorizationParams?: Record<string, string>;
110
- additionalTokenParams?: Record<string, string>;
111
- toolName?: string;
112
- toolDescription?: string;
113
- requestMethod?: string;
114
- requestPath?: string;
115
- }
116
-
117
- export interface OAuthProviderCatalogOption {
118
- slug: string;
119
- name: string;
120
- description: string;
121
- categories: string[];
122
- authStrategy: IntegrationAuthStrategy;
123
- availability: "oauth_ready" | "manual_token" | "planned";
124
- managedConnectorSlug?: string;
125
- appUrl?: string;
126
- docsUrl?: string;
127
- notes: string;
128
- popularityRank: number;
129
- registrationDefaults?: OAuthProviderRegistrationDefaults;
130
- }
131
91
 
132
92
  export interface IntegrationCatalogEntry {
133
93
  id: string;
134
- kind: IntegrationProvider;
135
94
  name: string;
136
95
  description: string;
137
96
  categories?: string[];
@@ -140,28 +99,35 @@ export interface IntegrationCatalogEntry {
140
99
  notes?: string;
141
100
  iconBg?: string;
142
101
  iconColor?: string;
102
+ logoUrl?: string;
143
103
  keywords?: string[];
144
104
  popularityRank?: number;
145
- runtimeAvailability?: "all" | "local";
146
- catalogStatus?: "oauth_ready" | "manual_token" | "planned";
147
- managedConnectorSlug?: string;
148
- authStrategy?: IntegrationAuthStrategy;
149
105
  installHint?: string;
150
- defaultConnectionOptionId?: string;
151
106
  connectionOptions: IntegrationConnectionOption[];
152
- registrationDefaults?: OAuthProviderRegistrationDefaults;
153
107
  }
154
108
 
155
- export const INTEGRATION_CATALOG: IntegrationCatalogEntry[];
156
- export function listOAuthProviderCatalog(): OAuthProviderCatalogOption[];
157
- export function getOAuthProviderRegistrationDefaults(
158
- slug: string,
159
- ): OAuthProviderRegistrationDefaults | undefined;
160
-
161
- export const hubspotMcpServerUrl: string;
162
- export const hubspotMcpAuthorizationUrl: string;
163
- export const hubspotMcpTokenUrl: string;
164
- export const hubspotRequiredScopes: readonly string[];
165
- export const hubspotOptionalScopes: readonly string[];
109
+ /**
110
+ * Filter for {@link listIntegrationCatalog}. Each dimension is tri-state:
111
+ * `true` keeps only entries that support that connector type, `false` keeps
112
+ * only entries that do not, and `undefined` leaves that dimension unfiltered.
113
+ */
114
+ export interface IntegrationCatalogFilter {
115
+ /** Filter on whether the entry exposes at least one `mcp` connector. */
116
+ mcp?: boolean;
117
+ /** Filter on whether the entry exposes at least one `oauth2` connector. */
118
+ oauth?: boolean;
119
+ }
166
120
 
121
+ export const INTEGRATION_CATALOG: IntegrationCatalogEntry[];
122
+ /**
123
+ * Return the full integration catalog, optionally filtered by connector type.
124
+ * Reads the generated static import index over `integrations/catalog/<id>.json`.
125
+ * Returns the cached array; callers must treat it as read-only.
126
+ */
127
+ export function listIntegrationCatalog(
128
+ filter?: IntegrationCatalogFilter,
129
+ ): IntegrationCatalogEntry[];
130
+ export function getIntegrationCatalogEntry(
131
+ id: string,
132
+ ): IntegrationCatalogEntry | undefined;
167
133
  export default INTEGRATION_CATALOG;
@@ -1,212 +1,34 @@
1
- import airtable from "./catalog/airtable.json" with { type: "json" };
2
- import apify from "./catalog/apify.json" with { type: "json" };
3
- import atlassian from "./catalog/atlassian.json" with { type: "json" };
4
- import brave_search from "./catalog/brave-search.json" with { type: "json" };
5
- import browser_mcp from "./catalog/browser-mcp.json" with { type: "json" };
6
- import clickhouse from "./catalog/clickhouse.json" with { type: "json" };
7
- import cloudflare_bindings from "./catalog/cloudflare-bindings.json" with { type: "json" };
8
- import cloudflare_browser_rendering from "./catalog/cloudflare-browser-rendering.json" with { type: "json" };
9
- import cloudflare_builds from "./catalog/cloudflare-builds.json" with { type: "json" };
10
- import cloudflare_docs from "./catalog/cloudflare-docs.json" with { type: "json" };
11
- import cloudflare_observability from "./catalog/cloudflare-observability.json" with { type: "json" };
12
- import deepwiki from "./catalog/deepwiki.json" with { type: "json" };
13
- import elevenlabs from "./catalog/elevenlabs.json" with { type: "json" };
14
- import everything from "./catalog/everything.json" with { type: "json" };
15
- import exa from "./catalog/exa.json" with { type: "json" };
16
- import fetch from "./catalog/fetch.json" with { type: "json" };
17
- import figma from "./catalog/figma.json" with { type: "json" };
18
- import filesystem from "./catalog/filesystem.json" with { type: "json" };
19
- import firecrawl from "./catalog/firecrawl.json" with { type: "json" };
20
- import git from "./catalog/git.json" with { type: "json" };
21
- import github from "./catalog/github.json" with { type: "json" };
22
- import huggingface from "./catalog/huggingface.json" with { type: "json" };
23
- import kagi from "./catalog/kagi.json" with { type: "json" };
24
- import linear from "./catalog/linear.json" with { type: "json" };
25
- import memory from "./catalog/memory.json" with { type: "json" };
26
- import mongodb from "./catalog/mongodb.json" with { type: "json" };
27
- import neon from "./catalog/neon.json" with { type: "json" };
28
- import notion from "./catalog/notion.json" with { type: "json" };
29
- import obsidian from "./catalog/obsidian.json" with { type: "json" };
30
- import paypal from "./catalog/paypal.json" with { type: "json" };
31
- import playwright from "./catalog/playwright.json" with { type: "json" };
32
- import redis from "./catalog/redis.json" with { type: "json" };
33
- import resend from "./catalog/resend.json" with { type: "json" };
34
- import sentry from "./catalog/sentry.json" with { type: "json" };
35
- import sequential_thinking from "./catalog/sequential-thinking.json" with { type: "json" };
36
- import slack from "./catalog/slack.json" with { type: "json" };
37
- import stripe from "./catalog/stripe.json" with { type: "json" };
38
- import supabase from "./catalog/supabase.json" with { type: "json" };
39
- import tavily from "./catalog/tavily.json" with { type: "json" };
40
- import time from "./catalog/time.json" with { type: "json" };
41
- import { listOAuthProviderCatalog } from "./oauth-provider-catalog.js";
42
- export { listOAuthProviderCatalog } from "./oauth-provider-catalog.js";
43
- export {
44
- getOAuthProviderRegistrationDefaults,
45
- hubspotMcpAuthorizationUrl,
46
- hubspotMcpServerUrl,
47
- hubspotMcpTokenUrl,
48
- hubspotOptionalScopes,
49
- hubspotRequiredScopes,
50
- } from "./oauth-provider-registration-defaults.js";
51
-
52
- const DIRECT_INTEGRATIONS = [
53
- airtable,
54
- apify,
55
- atlassian,
56
- brave_search,
57
- browser_mcp,
58
- clickhouse,
59
- cloudflare_bindings,
60
- cloudflare_browser_rendering,
61
- cloudflare_builds,
62
- cloudflare_docs,
63
- cloudflare_observability,
64
- deepwiki,
65
- elevenlabs,
66
- everything,
67
- exa,
68
- fetch,
69
- figma,
70
- filesystem,
71
- firecrawl,
72
- git,
73
- github,
74
- huggingface,
75
- kagi,
76
- linear,
77
- memory,
78
- mongodb,
79
- neon,
80
- notion,
81
- obsidian,
82
- paypal,
83
- playwright,
84
- redis,
85
- resend,
86
- sentry,
87
- sequential_thinking,
88
- slack,
89
- stripe,
90
- supabase,
91
- tavily,
92
- time,
93
- ];
94
-
95
- const optionIdForDefaults = (defaults) => {
96
- const strategy = defaults?.authStrategy ?? (defaults?.authorizationUrl || defaults?.tokenUrl ? "oauth2" : "oauth2");
97
- if (strategy === "oauth2") return "oauth";
98
- if (strategy === "none") return "none";
99
- return "api";
100
- };
101
-
102
- const providerConnectionOption = (provider) => {
103
- const defaults = provider.registrationDefaults;
104
- if (!defaults) return null;
105
- const option = {
106
- id: optionIdForDefaults(defaults),
107
- provider: defaults.provider ?? (defaults.serverUrl ? "mcp" : "http"),
108
- auth: {
109
- strategy: defaults.authStrategy ?? provider.authStrategy ?? "oauth2",
110
- authModes: defaults.authModes,
111
- credentialLabel: defaults.credentialLabel,
112
- credentialPlaceholder: defaults.credentialPlaceholder,
113
- credentialHelp: defaults.credentialHelp,
114
- apiKeyHeaderName: defaults.apiKeyHeaderName,
115
- oauth: defaults.authorizationUrl || defaults.tokenUrl ? {
116
- authorizationUrl: defaults.authorizationUrl,
117
- tokenUrl: defaults.tokenUrl,
118
- scopes: defaults.scopes ?? [],
119
- optionalScopes: defaults.optionalScopes,
120
- toolScopes: defaults.toolScopes,
121
- scopeSeparator: defaults.scopeSeparator,
122
- pkce: defaults.pkce,
123
- clientAuthentication: defaults.clientAuthentication,
124
- registrationUrl: defaults.registrationUrl,
125
- additionalAuthorizationParams: defaults.additionalAuthorizationParams,
126
- additionalTokenParams: defaults.additionalTokenParams,
127
- } : undefined,
128
- },
129
- };
130
-
131
- if (option.provider === "mcp") {
132
- option.transport = { kind: "shttp", url: defaults.serverUrl };
133
- } else {
134
- option.http = {
135
- apiBaseUrl: defaults.apiBaseUrl,
136
- openApiUrl: defaults.openApiUrl,
137
- defaultTool: defaults.toolName ? {
138
- name: defaults.toolName,
139
- description: defaults.toolDescription,
140
- method: defaults.requestMethod,
141
- path: defaults.requestPath,
142
- scopes: defaults.toolScopes,
143
- } : undefined,
144
- };
145
- }
146
-
147
- return option;
148
- };
149
-
150
- const providerIntegration = (provider) => {
151
- const option = providerConnectionOption(provider);
152
- return {
153
- id: provider.slug,
154
- kind: option?.provider ?? "http",
155
- name: provider.name,
156
- description: provider.description,
157
- categories: provider.categories,
158
- appUrl: provider.appUrl,
159
- docsUrl: provider.docsUrl,
160
- notes: provider.notes,
161
- catalogStatus: provider.availability,
162
- managedConnectorSlug: provider.managedConnectorSlug,
163
- authStrategy: provider.authStrategy,
164
- popularityRank: provider.popularityRank,
165
- registrationDefaults: provider.registrationDefaults,
166
- ...(option ? { defaultConnectionOptionId: option.id, connectionOptions: [option] } : { connectionOptions: [] }),
167
- };
168
- };
169
-
170
- const mergeOptions = (left = [], right = []) => {
171
- const options = new Map();
172
- for (const option of left) options.set(option.id, option);
173
- for (const option of right) {
174
- if (!options.has(option.id)) options.set(option.id, option);
175
- }
176
- return [...options.values()];
177
- };
178
-
179
- const mergeIntegration = (base, override) => {
180
- const connectionOptions = mergeOptions(base.connectionOptions, override.connectionOptions);
181
- return {
182
- ...base,
183
- ...override,
184
- catalogStatus: base.catalogStatus ?? override.catalogStatus,
185
- managedConnectorSlug: base.managedConnectorSlug ?? override.managedConnectorSlug,
186
- authStrategy: base.authStrategy ?? override.authStrategy,
187
- registrationDefaults: base.registrationDefaults ?? override.registrationDefaults,
188
- connectionOptions,
189
- defaultConnectionOptionId:
190
- base.defaultConnectionOptionId ?? override.defaultConnectionOptionId ?? connectionOptions[0]?.id,
191
- };
1
+ /**
2
+ * Runtime integration catalog.
3
+ *
4
+ * The source of truth is the hand-authored `integrations/catalog/<id>.json`
5
+ * directory. `catalog-index.js` is generated from that directory so the JS
6
+ * package can statically import each JSON file without an aggregate JSON asset.
7
+ */
8
+ import { INTEGRATION_CATALOG_ENTRIES } from "./catalog-index.js";
9
+
10
+ const INTEGRATIONS = INTEGRATION_CATALOG_ENTRIES;
11
+ const INTEGRATION_BY_ID = new Map(INTEGRATIONS.map((entry) => [entry.id, entry]));
12
+
13
+ const entrySupportsMcp = (entry) =>
14
+ entry.connectionOptions.some((option) => option.provider === "mcp");
15
+
16
+ const entrySupportsOauth = (entry) =>
17
+ entry.connectionOptions.some((option) => option.auth?.strategy === "oauth2");
18
+
19
+ export const listIntegrationCatalog = (filter) => {
20
+ if (!filter) return INTEGRATIONS;
21
+ const { mcp, oauth } = filter;
22
+ if (mcp === undefined && oauth === undefined) return INTEGRATIONS;
23
+ return INTEGRATIONS.filter((entry) => {
24
+ const mcpOk = mcp === undefined || entrySupportsMcp(entry) === mcp;
25
+ const oauthOk = oauth === undefined || entrySupportsOauth(entry) === oauth;
26
+ return mcpOk && oauthOk;
27
+ });
192
28
  };
193
29
 
194
- const entriesById = new Map();
195
- for (const provider of listOAuthProviderCatalog().map(providerIntegration)) {
196
- entriesById.set(provider.id, provider);
197
- }
198
- for (const direct of DIRECT_INTEGRATIONS) {
199
- entriesById.set(
200
- direct.id,
201
- entriesById.has(direct.id)
202
- ? mergeIntegration(entriesById.get(direct.id), direct)
203
- : direct,
204
- );
205
- }
30
+ export const getIntegrationCatalogEntry = (id) => INTEGRATION_BY_ID.get(id);
206
31
 
207
- export const INTEGRATION_CATALOG = [...entriesById.values()].sort((a, b) => {
208
- const rankDelta = (b.popularityRank ?? 0) - (a.popularityRank ?? 0);
209
- return rankDelta || a.name.localeCompare(b.name);
210
- });
32
+ export const INTEGRATION_CATALOG = INTEGRATIONS;
211
33
 
212
34
  export default INTEGRATION_CATALOG;
@@ -88,6 +88,19 @@
88
88
  "openhands"
89
89
  ]
90
90
  },
91
+ {
92
+ "name": "agent-canvas-environment",
93
+ "source": "./skills/agent-canvas-environment",
94
+ "description": "Work effectively inside a local Agent Canvas environment, including local agent-server auth, safe workspace hygiene, and local conversation delegation.",
95
+ "category": "development",
96
+ "keywords": [
97
+ "agent-canvas",
98
+ "openhands",
99
+ "local",
100
+ "conversation",
101
+ "delegation"
102
+ ]
103
+ },
91
104
  {
92
105
  "name": "openhands-sdk",
93
106
  "source": "./skills/openhands-sdk",
@@ -404,7 +417,7 @@
404
417
  {
405
418
  "name": "openhands-api",
406
419
  "source": "./skills/openhands-api",
407
- "description": "Use the OpenHands Cloud REST API (V1) to create and manage app conversations, including multi-conversation delegation workflows, and to access sandbox agent-server endpoints. Includes minimal Python and TypeScript clients under scripts/.",
420
+ "description": "Use the OpenHands Cloud REST API (V1) and agent-server APIs to create and manage Cloud or local backend conversations, including multi-conversation delegation workflows. Includes minimal Python and TypeScript clients under scripts/.",
408
421
  "category": "development",
409
422
  "keywords": [
410
423
  "openhands",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openhands/extensions",
3
- "version": "0.4.2",
3
+ "version": "0.6.0",
4
4
  "description": "Public OpenHands extension catalogs for skills, plugins, integrations, and automation templates.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -9,7 +9,9 @@
9
9
  "url": "https://github.com/OpenHands/extensions"
10
10
  },
11
11
  "scripts": {
12
- "build:skills": "node scripts/build-skills-catalog.mjs"
12
+ "build:skills": "node scripts/build-skills-catalog.mjs",
13
+ "build:integrations": "node scripts/build-integration-catalog.mjs",
14
+ "build": "npm run build:skills && npm run build:integrations"
13
15
  },
14
16
  "engines": {
15
17
  "node": ">=18.20.0"
@@ -39,11 +41,6 @@
39
41
  "import": "./integrations/index.js",
40
42
  "default": "./integrations/index.js"
41
43
  },
42
- "./integrations/logos": {
43
- "types": "./integrations/logos.d.ts",
44
- "import": "./integrations/logos.js",
45
- "default": "./integrations/logos.js"
46
- },
47
44
  "./integrations/catalog/*.json": "./integrations/catalog/*.json",
48
45
  "./skills": {
49
46
  "types": "./skills/index.d.ts",
@@ -36,11 +36,11 @@ plugins/cobol-modernization/
36
36
  └── skills/ # Workflow phase skills
37
37
  ├── build-setup/ # Phase 1: Build environment
38
38
  │ └── SKILL.md
39
- ├── cobol-modernization-overview/ # Plugin overview
39
+ ├── cobol-modernization/ # Plugin overview
40
40
  │ └── SKILL.md
41
41
  ├── mainframe-planning/ # Phase 2: Transformation planning
42
42
  │ └── SKILL.md
43
- ├── mainfraime-removal/ # Phase 3: Mainframe dependency removal
43
+ ├── mainframe-removal/ # Phase 3: Mainframe dependency removal
44
44
  │ ├── SKILL.md
45
45
  │ └── references/
46
46
  │ └── cics-transformation-examples.md
@@ -139,7 +139,7 @@ You can also run individual phases by using the specific skill definitions:
139
139
 
140
140
  - See [skills/build-setup/SKILL.md](skills/build-setup/SKILL.md) for build setup only
141
141
  - See [skills/mainframe-planning/SKILL.md](skills/mainframe-planning/SKILL.md) for planning
142
- - See [skills/mainfraime-removal/SKILL.md](skills/mainfraime-removal/SKILL.md) for mainframe removal
142
+ - See [skills/mainframe-removal/SKILL.md](skills/mainframe-removal/SKILL.md) for mainframe removal
143
143
  - See [skills/to-java-migration/SKILL.md](skills/to-java-migration/SKILL.md) for Java translation
144
144
 
145
145
  ## Troubleshooting
@@ -67,7 +67,7 @@ Creates a transformation guide without modifying code:
67
67
 
68
68
  ### Phase 3: Mainframe Removal
69
69
 
70
- See [../mainfraime-removal/SKILL.md](../mainfraime-removal/SKILL.md)
70
+ See [../mainframe-removal/SKILL.md](../mainframe-removal/SKILL.md)
71
71
 
72
72
  Applies the transformation guide:
73
73
  - Replaces EXEC CICS commands with file I/O
@@ -1,4 +1,5 @@
1
1
  ---
2
+ name: magic-word
2
3
  description: A test skill that responds to the magic word "alakazam" with a specific phrase
3
4
  triggers:
4
5
  - alakazam
@@ -34,7 +34,7 @@ uv run python -m lc_sdk_examples.migration_scoring \
34
34
  plugins/migration-scoring/
35
35
  ├── README.md # This file
36
36
  └── skills/ # Workflow phase skills
37
- ├── migration-scoring-overview/ # Plugin overview
37
+ ├── migration-scoring/ # Plugin overview
38
38
  │ └── SKILL.md
39
39
  ├── migration-mapping/ # Phase 1: Source-to-target mapping
40
40
  │ └── SKILL.md