@tangle-network/agent-integrations 0.24.0 → 0.25.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/README.md +6 -4
- package/dist/bin/tangle-catalog-runtime.js +23 -2
- package/dist/bin/tangle-catalog-runtime.js.map +1 -1
- package/dist/{chunk-L6WBPDUP.js → chunk-4JQ754PA.js} +2 -2
- package/dist/chunk-4JQ754PA.js.map +1 -0
- package/dist/{chunk-6SSYWA3J.js → chunk-VJ57GPYO.js} +110 -9
- package/dist/chunk-VJ57GPYO.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +8 -2
- package/dist/specs.d.ts +93 -31
- package/dist/specs.js +1 -1
- package/docs/adapter-triage.md +19 -10
- package/docs/catalog-registry.md +6 -3
- package/docs/generated-integration-coverage-checklist.md +3 -3
- package/docs/integration-coverage-checklist.md +3 -3
- package/docs/integration-execution-audit.md +18 -20
- package/docs/integration-execution-matrix.json +675 -675
- package/docs/production-completion-checklist.md +3 -2
- package/docs/repo-structure.md +2 -2
- package/docs/third-party/activepieces.md +6 -2
- package/package.json +1 -1
- package/dist/chunk-6SSYWA3J.js.map +0 -1
- package/dist/chunk-L6WBPDUP.js.map +0 -1
package/README.md
CHANGED
|
@@ -110,11 +110,12 @@ pnpm add @tangle-network/agent-integrations
|
|
|
110
110
|
| `composeIntegrationRegistry` | Merges arbitrary catalog sources with explicit aliases, precedence, support tiers, and conflict diagnostics. |
|
|
111
111
|
| `buildIntegrationCoverageConnectors` | Planning catalog for 100+ high-value integrations. |
|
|
112
112
|
| `buildTangleIntegrationCatalogConnectors` | Broad normalized Tangle Integrations Catalog inventory for long-tail connection discovery. |
|
|
113
|
-
| `listTangleIntegrationContracts` | First-class Tangle-owned action/trigger/auth/runtime contracts for every catalog connector. |
|
|
114
|
-
| `createTangleCatalogExecutorProvider` |
|
|
113
|
+
| `listTangleIntegrationContracts` | First-class Tangle-owned action/trigger/auth/runtime contracts for every catalog connector, including package-runtime-backed entries. |
|
|
114
|
+
| `createTangleCatalogExecutorProvider` | Routes catalog contracts through an explicitly supplied Tangle runtime executor. |
|
|
115
115
|
| `createTangleCatalogHttpExecutor` | Signed HTTP executor client for Tangle-hosted catalog runtimes. |
|
|
116
116
|
| `createTangleCatalogRuntimeHandler` | Server-side `/v1/integration-catalog/actions/invoke` handler with signature, connector, and action validation. |
|
|
117
117
|
| `createTangleCatalogInstalledPackageExecutor` | Runtime-side dispatcher for installed long-tail connector packages with explicit action aliasing and credential resolution hooks. |
|
|
118
|
+
| `auditTangleCatalogRuntimePackages` | Runtime-image audit for installed package loads, piece exports, exact action mappings, and trigger surfaces. |
|
|
118
119
|
| `auditTangleIntegrationCatalogFreshness` | Release gate for catalog breadth, executable promotion, registry conflicts, and stale external ingestion. |
|
|
119
120
|
| `createGatewayCatalogProvider` | Normalizes 500+ gateway-backed connectors into the same provider contract. |
|
|
120
121
|
| `buildIntegrationInvocationEnvelope` | Sandbox-safe action envelope. |
|
|
@@ -135,7 +136,7 @@ should route through `IntegrationHub` either way.
|
|
|
135
136
|
Use `buildDefaultIntegrationRegistry()` before creating tool catalogs or
|
|
136
137
|
connection pickers. It produces one canonical connector per integration,
|
|
137
138
|
dedupes aliases such as `notion -> notion-database`, keeps source provenance in
|
|
138
|
-
metadata, and marks
|
|
139
|
+
metadata, and marks the configured execution state for each connector:
|
|
139
140
|
|
|
140
141
|
```txt
|
|
141
142
|
catalogOnly < setupReady < gatewayExecutable < firstPartyExecutable < sandboxExecutable
|
|
@@ -143,7 +144,8 @@ catalogOnly < setupReady < gatewayExecutable < firstPartyExecutable < sandboxExe
|
|
|
143
144
|
|
|
144
145
|
Use `buildDefaultIntegrationRegistry({ tangleCatalogRuntimeExecutable: true })`
|
|
145
146
|
when the Tangle catalog runtime is deployed and should be exposed as executable
|
|
146
|
-
tools.
|
|
147
|
+
tools. These states describe the backend currently wired into a product, not
|
|
148
|
+
whether the connector has a first-class Tangle contract.
|
|
147
149
|
|
|
148
150
|
See [Catalog Registry](./docs/catalog-registry.md).
|
|
149
151
|
|
|
@@ -1,10 +1,31 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
+
auditTangleCatalogRuntimePackages,
|
|
4
|
+
buildTangleCatalogRuntimePackageManifest,
|
|
5
|
+
renderTangleCatalogRuntimePnpmAddCommand,
|
|
3
6
|
startTangleCatalogRuntimeNodeServer
|
|
4
|
-
} from "../chunk-
|
|
5
|
-
import "../chunk-
|
|
7
|
+
} from "../chunk-VJ57GPYO.js";
|
|
8
|
+
import "../chunk-4JQ754PA.js";
|
|
6
9
|
|
|
7
10
|
// src/bin/tangle-catalog-runtime.ts
|
|
11
|
+
var args = new Set(process.argv.slice(2));
|
|
12
|
+
if (args.has("--print-package-json")) {
|
|
13
|
+
console.log(JSON.stringify(buildTangleCatalogRuntimePackageManifest({
|
|
14
|
+
agentIntegrationsVersion: process.env.TANGLE_AGENT_INTEGRATIONS_VERSION
|
|
15
|
+
}), null, 2));
|
|
16
|
+
process.exit(0);
|
|
17
|
+
}
|
|
18
|
+
if (args.has("--print-pnpm-add")) {
|
|
19
|
+
console.log(renderTangleCatalogRuntimePnpmAddCommand({
|
|
20
|
+
agentIntegrationsVersion: process.env.TANGLE_AGENT_INTEGRATIONS_VERSION
|
|
21
|
+
}));
|
|
22
|
+
process.exit(0);
|
|
23
|
+
}
|
|
24
|
+
if (args.has("--audit-packages")) {
|
|
25
|
+
const connectorIds = process.env.TANGLE_CATALOG_AUDIT_CONNECTORS?.split(",").map((id) => id.trim()).filter(Boolean);
|
|
26
|
+
console.log(JSON.stringify(await auditTangleCatalogRuntimePackages({ connectorIds }), null, 2));
|
|
27
|
+
process.exit(0);
|
|
28
|
+
}
|
|
8
29
|
var secret = process.env.TANGLE_CATALOG_RUNTIME_SECRET;
|
|
9
30
|
if (!secret || secret.length < 32) {
|
|
10
31
|
console.error("TANGLE_CATALOG_RUNTIME_SECRET must be set to at least 32 characters.");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/bin/tangle-catalog-runtime.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { startTangleCatalogRuntimeNodeServer } from '../tangle-catalog-runtime-server.js'\n\nconst secret = process.env.TANGLE_CATALOG_RUNTIME_SECRET\nif (!secret || secret.length < 32) {\n console.error('TANGLE_CATALOG_RUNTIME_SECRET must be set to at least 32 characters.')\n process.exit(1)\n}\n\nconst authResolverUrl = process.env.TANGLE_CATALOG_AUTH_RESOLVER_URL\nconst authResolverSecret = process.env.TANGLE_CATALOG_AUTH_RESOLVER_SECRET\nif (Boolean(authResolverUrl) !== Boolean(authResolverSecret)) {\n console.error('TANGLE_CATALOG_AUTH_RESOLVER_URL and TANGLE_CATALOG_AUTH_RESOLVER_SECRET must be set together.')\n process.exit(1)\n}\n\nconst port = Number(process.env.PORT ?? process.env.TANGLE_CATALOG_RUNTIME_PORT ?? 4109)\nif (!Number.isInteger(port) || port < 1 || port > 65_535) {\n console.error('PORT must be an integer between 1 and 65535.')\n process.exit(1)\n}\n\nconst server = await startTangleCatalogRuntimeNodeServer({\n secret,\n host: process.env.HOST ?? process.env.TANGLE_CATALOG_RUNTIME_HOST ?? '0.0.0.0',\n port,\n authResolver: authResolverUrl && authResolverSecret\n ? {\n endpoint: authResolverUrl,\n secret: authResolverSecret,\n }\n : false,\n onLog: (event) => {\n const line = JSON.stringify({\n level: event.level,\n message: event.message,\n ...event.metadata,\n })\n if (event.level === 'error') console.error(line)\n else console.log(line)\n },\n})\n\nconsole.log(JSON.stringify({\n level: 'info',\n message: 'Tangle catalog runtime listening.',\n url: server.url,\n}))\n\nfor (const signal of ['SIGINT', 'SIGTERM'] as const) {\n process.once(signal, async () => {\n await server.close()\n process.exit(0)\n })\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../src/bin/tangle-catalog-runtime.ts"],"sourcesContent":["#!/usr/bin/env node\nimport {\n buildTangleCatalogRuntimePackageManifest,\n renderTangleCatalogRuntimePnpmAddCommand,\n} from '../tangle-catalog.js'\nimport { auditTangleCatalogRuntimePackages } from '../tangle-catalog-runtime.js'\nimport { startTangleCatalogRuntimeNodeServer } from '../tangle-catalog-runtime-server.js'\n\nconst args = new Set(process.argv.slice(2))\nif (args.has('--print-package-json')) {\n console.log(JSON.stringify(buildTangleCatalogRuntimePackageManifest({\n agentIntegrationsVersion: process.env.TANGLE_AGENT_INTEGRATIONS_VERSION,\n }), null, 2))\n process.exit(0)\n}\n\nif (args.has('--print-pnpm-add')) {\n console.log(renderTangleCatalogRuntimePnpmAddCommand({\n agentIntegrationsVersion: process.env.TANGLE_AGENT_INTEGRATIONS_VERSION,\n }))\n process.exit(0)\n}\n\nif (args.has('--audit-packages')) {\n const connectorIds = process.env.TANGLE_CATALOG_AUDIT_CONNECTORS\n ?.split(',')\n .map((id) => id.trim())\n .filter(Boolean)\n console.log(JSON.stringify(await auditTangleCatalogRuntimePackages({ connectorIds }), null, 2))\n process.exit(0)\n}\n\nconst secret = process.env.TANGLE_CATALOG_RUNTIME_SECRET\nif (!secret || secret.length < 32) {\n console.error('TANGLE_CATALOG_RUNTIME_SECRET must be set to at least 32 characters.')\n process.exit(1)\n}\n\nconst authResolverUrl = process.env.TANGLE_CATALOG_AUTH_RESOLVER_URL\nconst authResolverSecret = process.env.TANGLE_CATALOG_AUTH_RESOLVER_SECRET\nif (Boolean(authResolverUrl) !== Boolean(authResolverSecret)) {\n console.error('TANGLE_CATALOG_AUTH_RESOLVER_URL and TANGLE_CATALOG_AUTH_RESOLVER_SECRET must be set together.')\n process.exit(1)\n}\n\nconst port = Number(process.env.PORT ?? process.env.TANGLE_CATALOG_RUNTIME_PORT ?? 4109)\nif (!Number.isInteger(port) || port < 1 || port > 65_535) {\n console.error('PORT must be an integer between 1 and 65535.')\n process.exit(1)\n}\n\nconst server = await startTangleCatalogRuntimeNodeServer({\n secret,\n host: process.env.HOST ?? process.env.TANGLE_CATALOG_RUNTIME_HOST ?? '0.0.0.0',\n port,\n authResolver: authResolverUrl && authResolverSecret\n ? {\n endpoint: authResolverUrl,\n secret: authResolverSecret,\n }\n : false,\n onLog: (event) => {\n const line = JSON.stringify({\n level: event.level,\n message: event.message,\n ...event.metadata,\n })\n if (event.level === 'error') console.error(line)\n else console.log(line)\n },\n})\n\nconsole.log(JSON.stringify({\n level: 'info',\n message: 'Tangle catalog runtime listening.',\n url: server.url,\n}))\n\nfor (const signal of ['SIGINT', 'SIGTERM'] as const) {\n process.once(signal, async () => {\n await server.close()\n process.exit(0)\n })\n}\n"],"mappings":";;;;;;;;;;AAQA,IAAM,OAAO,IAAI,IAAI,QAAQ,KAAK,MAAM,CAAC,CAAC;AAC1C,IAAI,KAAK,IAAI,sBAAsB,GAAG;AACpC,UAAQ,IAAI,KAAK,UAAU,yCAAyC;AAAA,IAClE,0BAA0B,QAAQ,IAAI;AAAA,EACxC,CAAC,GAAG,MAAM,CAAC,CAAC;AACZ,UAAQ,KAAK,CAAC;AAChB;AAEA,IAAI,KAAK,IAAI,kBAAkB,GAAG;AAChC,UAAQ,IAAI,yCAAyC;AAAA,IACnD,0BAA0B,QAAQ,IAAI;AAAA,EACxC,CAAC,CAAC;AACF,UAAQ,KAAK,CAAC;AAChB;AAEA,IAAI,KAAK,IAAI,kBAAkB,GAAG;AAChC,QAAM,eAAe,QAAQ,IAAI,iCAC7B,MAAM,GAAG,EACV,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,EACrB,OAAO,OAAO;AACjB,UAAQ,IAAI,KAAK,UAAU,MAAM,kCAAkC,EAAE,aAAa,CAAC,GAAG,MAAM,CAAC,CAAC;AAC9F,UAAQ,KAAK,CAAC;AAChB;AAEA,IAAM,SAAS,QAAQ,IAAI;AAC3B,IAAI,CAAC,UAAU,OAAO,SAAS,IAAI;AACjC,UAAQ,MAAM,sEAAsE;AACpF,UAAQ,KAAK,CAAC;AAChB;AAEA,IAAM,kBAAkB,QAAQ,IAAI;AACpC,IAAM,qBAAqB,QAAQ,IAAI;AACvC,IAAI,QAAQ,eAAe,MAAM,QAAQ,kBAAkB,GAAG;AAC5D,UAAQ,MAAM,gGAAgG;AAC9G,UAAQ,KAAK,CAAC;AAChB;AAEA,IAAM,OAAO,OAAO,QAAQ,IAAI,QAAQ,QAAQ,IAAI,+BAA+B,IAAI;AACvF,IAAI,CAAC,OAAO,UAAU,IAAI,KAAK,OAAO,KAAK,OAAO,OAAQ;AACxD,UAAQ,MAAM,8CAA8C;AAC5D,UAAQ,KAAK,CAAC;AAChB;AAEA,IAAM,SAAS,MAAM,oCAAoC;AAAA,EACvD;AAAA,EACA,MAAM,QAAQ,IAAI,QAAQ,QAAQ,IAAI,+BAA+B;AAAA,EACrE;AAAA,EACA,cAAc,mBAAmB,qBAC7B;AAAA,IACE,UAAU;AAAA,IACV,QAAQ;AAAA,EACV,IACA;AAAA,EACJ,OAAO,CAAC,UAAU;AAChB,UAAM,OAAO,KAAK,UAAU;AAAA,MAC1B,OAAO,MAAM;AAAA,MACb,SAAS,MAAM;AAAA,MACf,GAAG,MAAM;AAAA,IACX,CAAC;AACD,QAAI,MAAM,UAAU,QAAS,SAAQ,MAAM,IAAI;AAAA,QAC1C,SAAQ,IAAI,IAAI;AAAA,EACvB;AACF,CAAC;AAED,QAAQ,IAAI,KAAK,UAAU;AAAA,EACzB,OAAO;AAAA,EACP,SAAS;AAAA,EACT,KAAK,OAAO;AACd,CAAC,CAAC;AAEF,WAAW,UAAU,CAAC,UAAU,SAAS,GAAY;AACnD,UAAQ,KAAK,QAAQ,YAAY;AAC/B,UAAM,OAAO,MAAM;AACnB,YAAQ,KAAK,CAAC;AAAA,EAChB,CAAC;AACH;","names":[]}
|
|
@@ -381,7 +381,7 @@ function integrationCoverageChecklistMarkdown() {
|
|
|
381
381
|
const lines = [
|
|
382
382
|
"# Agent Integrations Coverage Checklist",
|
|
383
383
|
"",
|
|
384
|
-
"Generated from `listIntegrationCoverageSpecs()`. Catalog presence means the product can plan/request/connect the integration;
|
|
384
|
+
"Generated from `listIntegrationCoverageSpecs()`. Catalog presence means the product can plan/request/connect the integration; native adapters and runtime backends execute behind the same provider contract.",
|
|
385
385
|
"",
|
|
386
386
|
"## Summary",
|
|
387
387
|
"",
|
|
@@ -997,4 +997,4 @@ export {
|
|
|
997
997
|
validateCredentialFormat,
|
|
998
998
|
validateCredentialSet
|
|
999
999
|
};
|
|
1000
|
-
//# sourceMappingURL=chunk-
|
|
1000
|
+
//# sourceMappingURL=chunk-4JQ754PA.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/specs/types.ts","../src/specs/families.ts","../src/coverage-catalog.ts","../src/specs/overrides.ts","../src/specs/registry.ts","../src/specs/renderers.ts","../src/specs/validation.ts"],"sourcesContent":["import type {\n IntegrationActionRisk,\n IntegrationConnector,\n IntegrationConnectorAction,\n IntegrationConnectorCategory,\n IntegrationConnectorTrigger,\n IntegrationDataClass,\n} from '../index.js'\n\nexport type IntegrationAuthMode = 'oauth2' | 'api_key' | 'hmac' | 'none' | 'custom'\n\nexport type IntegrationSpecStatus = 'catalog' | 'executable' | 'deprecated'\n\nexport type IntegrationFamilyId =\n | 'google'\n | 'microsoft-graph'\n | 'atlassian'\n | 'salesforce'\n | 'hubspot'\n | 'slack'\n | 'notion'\n | 'standard-oauth2'\n | 'api-key'\n | 'hmac'\n | 'none'\n\nexport type NormalizedPermission =\n | `${string}.read`\n | `${string}.write`\n | `${string}.delete`\n | `${string}.admin`\n\nexport interface IntegrationSpec {\n kind: string\n title: string\n category: IntegrationConnectorCategory\n status: IntegrationSpecStatus\n family: IntegrationFamilyId\n auth: IntegrationAuthSpec\n permissions: PermissionDescriptor[]\n actions: IntegrationConnectorAction[]\n triggers?: IntegrationConnectorTrigger[]\n setup: IntegrationSetupSpec\n lifecycle?: IntegrationLifecycleSpec\n plannerHints?: IntegrationPlannerHints\n metadata?: Record<string, unknown>\n}\n\nexport type IntegrationAuthSpec =\n | OAuth2AuthSpec\n | ApiKeyAuthSpec\n | HmacAuthSpec\n | NoneAuthSpec\n | CustomAuthSpec\n\nexport interface OAuth2AuthSpec {\n mode: 'oauth2'\n authorizationUrl: string\n tokenUrl: string\n clientIdEnv?: string\n clientSecretEnv?: string\n scopes: ScopeDescriptor[]\n extraAuthParams?: Record<string, string>\n redirectUriTemplate: string\n pkce?: 'required' | 'supported' | 'unsupported'\n}\n\nexport interface ApiKeyAuthSpec {\n mode: 'api_key'\n credential: CredentialFieldSpec\n placement?: 'bearer' | 'header' | 'query' | 'basic'\n}\n\nexport interface HmacAuthSpec {\n mode: 'hmac'\n credential: CredentialFieldSpec\n signatureHeader?: string\n}\n\nexport interface NoneAuthSpec {\n mode: 'none'\n}\n\nexport interface CustomAuthSpec {\n mode: 'custom'\n description: string\n}\n\nexport interface ScopeDescriptor {\n normalized: NormalizedPermission\n providerScope: string\n title: string\n reason: string\n risk: IntegrationActionRisk\n dataClass: IntegrationDataClass\n}\n\nexport interface PermissionDescriptor {\n normalized: NormalizedPermission\n providerScopes: string[]\n title: string\n risk: IntegrationActionRisk\n dataClass: IntegrationDataClass\n reason: string\n}\n\nexport interface CredentialFieldSpec {\n label: string\n description: string\n env?: string\n example?: string\n regex?: string\n secret: boolean\n}\n\nexport interface ConsoleStep {\n id: string\n title: string\n detail: string\n copyValue?: string\n}\n\nexport interface Quirk {\n id: string\n severity: 'info' | 'warning' | 'critical'\n message: string\n}\n\nexport interface PostSetupCheck {\n id: string\n title: string\n detail: string\n}\n\nexport interface HealthcheckSpec {\n id: string\n level: 'client_config' | 'connection' | 'webhook' | 'static'\n method?: 'GET' | 'POST'\n url?: string\n expectedStatus?: number[]\n description: string\n}\n\nexport interface IntegrationSetupSpec {\n consoleUrl?: string\n consoleSteps: ConsoleStep[]\n credentialFields: CredentialFieldSpec[]\n redirectUriTemplate?: string\n knownQuirks?: Quirk[]\n postSetup?: PostSetupCheck[]\n healthcheck?: HealthcheckSpec\n}\n\nexport interface IntegrationLifecycleSpec {\n supportsRefresh: boolean\n supportsRevoke: boolean\n supportsIncrementalAuth: boolean\n recommendedHealthcheckIntervalHours?: number\n freshnessSloMinutes?: number\n}\n\nexport interface IntegrationPlannerHints {\n useFor: string[]\n avoidFor?: string[]\n dataFreshness: 'realtime' | 'near_realtime' | 'eventual' | 'manual'\n writeRisk: 'low' | 'medium' | 'high'\n}\n\nexport interface IntegrationFamilySpec {\n id: IntegrationFamilyId\n title: string\n authMode: IntegrationAuthMode\n consoleUrl?: string\n authorizationUrl?: string\n tokenUrl?: string\n redirectUriTemplate?: string\n credentialFields: CredentialFieldSpec[]\n consoleSteps: ConsoleStep[]\n knownQuirks?: Quirk[]\n lifecycle: IntegrationLifecycleSpec\n}\n\nexport interface IntegrationSpecValidationIssue {\n path: string\n message: string\n}\n\nexport interface IntegrationSpecValidationResult {\n ok: boolean\n issues: IntegrationSpecValidationIssue[]\n}\n\nexport interface RenderSpecOptions {\n host: string\n callbackPath?: string\n}\n\nexport interface RenderedConsoleStep extends ConsoleStep {\n detail: string\n copyValue?: string\n}\n\nexport interface CredentialValidationInput {\n field: CredentialFieldSpec\n value: string\n}\n\nexport interface CredentialValidationResult {\n ok: boolean\n field: string\n message?: string\n}\n\nexport interface HealthcheckPlan {\n kind: string\n healthcheck: HealthcheckSpec\n requires: Array<'client_id' | 'client_secret' | 'api_key' | 'hmac_secret' | 'connection_credentials'>\n message: string\n}\n\nexport function specAuthToConnectorAuth(auth: IntegrationAuthSpec): IntegrationConnector['auth'] {\n if (auth.mode === 'api_key') return 'api_key'\n if (auth.mode === 'oauth2') return 'oauth2'\n if (auth.mode === 'none') return 'none'\n return 'custom'\n}\n","import type { IntegrationFamilyId, IntegrationFamilySpec } from './types.js'\n\nexport const INTEGRATION_FAMILIES: Record<IntegrationFamilyId, IntegrationFamilySpec> = {\n google: {\n id: 'google',\n title: 'Google OAuth',\n authMode: 'oauth2',\n consoleUrl: 'https://console.cloud.google.com/apis/credentials',\n authorizationUrl: 'https://accounts.google.com/o/oauth2/v2/auth',\n tokenUrl: 'https://oauth2.googleapis.com/token',\n redirectUriTemplate: 'https://{host}/api/integrations/oauth/google/callback',\n credentialFields: [\n { label: 'Client ID', env: 'GOOGLE_OAUTH_CLIENT_ID', description: 'Google OAuth client ID.', example: '1234567890-abc.apps.googleusercontent.com', regex: '^[0-9]+-[a-zA-Z0-9_-]+\\\\.apps\\\\.googleusercontent\\\\.com$', secret: false },\n { label: 'Client Secret', env: 'GOOGLE_OAUTH_CLIENT_SECRET', description: 'Google OAuth client secret.', example: 'GOCSPX-...', secret: true },\n ],\n consoleSteps: [\n { id: 'project', title: 'Select project', detail: 'Open Google Cloud Console and select the project that owns the OAuth client.' },\n { id: 'consent', title: 'Configure consent screen', detail: 'Configure OAuth consent, app name, support email, and publishing status appropriate for the deployment.' },\n { id: 'client', title: 'Create web client', detail: 'Create an OAuth client of type Web application.' },\n { id: 'redirect', title: 'Add redirect URI', detail: 'Add {redirectUri} as an authorized redirect URI.', copyValue: '{redirectUri}' },\n { id: 'scopes', title: 'Add scopes', detail: 'Add the provider scopes listed in this spec.' },\n ],\n knownQuirks: [\n { id: 'offline-access', severity: 'warning', message: 'Use access_type=offline and prompt=consent when refresh tokens are required.' },\n { id: 'verification', severity: 'warning', message: 'Sensitive or restricted scopes may require Google verification before broad external use.' },\n ],\n lifecycle: { supportsRefresh: true, supportsRevoke: true, supportsIncrementalAuth: true, recommendedHealthcheckIntervalHours: 24 },\n },\n 'microsoft-graph': {\n id: 'microsoft-graph',\n title: 'Microsoft Graph OAuth',\n authMode: 'oauth2',\n consoleUrl: 'https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationsListBlade',\n authorizationUrl: 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize',\n tokenUrl: 'https://login.microsoftonline.com/common/oauth2/v2.0/token',\n redirectUriTemplate: 'https://{host}/api/integrations/oauth/microsoft/callback',\n credentialFields: [\n { label: 'Client ID', env: 'MS_OAUTH_CLIENT_ID', description: 'Microsoft Entra application client ID.', example: '00000000-0000-0000-0000-000000000000', regex: '^[0-9a-fA-F-]{36}$', secret: false },\n { label: 'Client Secret', env: 'MS_OAUTH_CLIENT_SECRET', description: 'Microsoft Entra client secret value.', secret: true },\n ],\n consoleSteps: [\n { id: 'app', title: 'Register app', detail: 'Create or open an app registration in Microsoft Entra.' },\n { id: 'redirect', title: 'Add redirect URI', detail: 'Add {redirectUri} as a Web redirect URI.', copyValue: '{redirectUri}' },\n { id: 'secret', title: 'Create secret', detail: 'Create a client secret and store the secret value, not the secret ID.' },\n { id: 'permissions', title: 'Add Graph permissions', detail: 'Add the delegated Graph scopes listed in this spec and grant admin consent where required.' },\n ],\n knownQuirks: [\n { id: 'tenant-common', severity: 'info', message: 'The common tenant supports multi-tenant OAuth; single-tenant deployments should override the tenant segment.' },\n { id: 'admin-consent', severity: 'warning', message: 'Some Graph scopes require tenant admin consent.' },\n ],\n lifecycle: { supportsRefresh: true, supportsRevoke: true, supportsIncrementalAuth: true, recommendedHealthcheckIntervalHours: 24 },\n },\n atlassian: {\n id: 'atlassian',\n title: 'Atlassian OAuth',\n authMode: 'oauth2',\n consoleUrl: 'https://developer.atlassian.com/console/myapps/',\n authorizationUrl: 'https://auth.atlassian.com/authorize',\n tokenUrl: 'https://auth.atlassian.com/oauth/token',\n redirectUriTemplate: 'https://{host}/api/integrations/oauth/atlassian/callback',\n credentialFields: [\n { label: 'Client ID', description: 'Atlassian OAuth client ID.', secret: false },\n { label: 'Client Secret', description: 'Atlassian OAuth client secret.', secret: true },\n ],\n consoleSteps: [\n { id: 'app', title: 'Create OAuth app', detail: 'Create an OAuth 2.0 app in the Atlassian developer console.' },\n { id: 'redirect', title: 'Add callback URL', detail: 'Add {redirectUri} as the callback URL.', copyValue: '{redirectUri}' },\n { id: 'apis', title: 'Enable APIs', detail: 'Enable the Jira or Confluence APIs required by this connector.' },\n ],\n lifecycle: { supportsRefresh: true, supportsRevoke: false, supportsIncrementalAuth: false, recommendedHealthcheckIntervalHours: 24 },\n },\n salesforce: {\n id: 'salesforce',\n title: 'Salesforce OAuth',\n authMode: 'oauth2',\n consoleUrl: 'https://login.salesforce.com',\n authorizationUrl: 'https://login.salesforce.com/services/oauth2/authorize',\n tokenUrl: 'https://login.salesforce.com/services/oauth2/token',\n redirectUriTemplate: 'https://{host}/api/integrations/oauth/salesforce/callback',\n credentialFields: [\n { label: 'Client ID', env: 'SALESFORCE_OAUTH_CLIENT_ID', description: 'Salesforce connected app consumer key.', secret: false },\n { label: 'Client Secret', env: 'SALESFORCE_OAUTH_CLIENT_SECRET', description: 'Salesforce connected app consumer secret.', secret: true },\n ],\n consoleSteps: [\n { id: 'connected-app', title: 'Create connected app', detail: 'Create a Salesforce connected app with OAuth enabled.' },\n { id: 'callback', title: 'Add callback URL', detail: 'Add {redirectUri} as the callback URL.', copyValue: '{redirectUri}' },\n { id: 'scopes', title: 'Select scopes', detail: 'Add api and refresh_token/offline_access, plus any connector-specific scopes.' },\n ],\n knownQuirks: [\n { id: 'instance-url', severity: 'critical', message: 'Runtime calls must use the instance_url returned by the token response.' },\n ],\n lifecycle: { supportsRefresh: true, supportsRevoke: true, supportsIncrementalAuth: false, recommendedHealthcheckIntervalHours: 24 },\n },\n hubspot: {\n id: 'hubspot',\n title: 'HubSpot OAuth',\n authMode: 'oauth2',\n consoleUrl: 'https://developers.hubspot.com/',\n authorizationUrl: 'https://app.hubspot.com/oauth/authorize',\n tokenUrl: 'https://api.hubapi.com/oauth/v1/token',\n redirectUriTemplate: 'https://{host}/api/integrations/oauth/hubspot/callback',\n credentialFields: [\n { label: 'Client ID', env: 'HUBSPOT_OAUTH_CLIENT_ID', description: 'HubSpot app client ID.', secret: false },\n { label: 'Client Secret', env: 'HUBSPOT_OAUTH_CLIENT_SECRET', description: 'HubSpot app client secret.', secret: true },\n ],\n consoleSteps: [\n { id: 'app', title: 'Create private/public app', detail: 'Create a HubSpot app and configure OAuth.' },\n { id: 'redirect', title: 'Add redirect URL', detail: 'Add {redirectUri} to the app redirect URLs.', copyValue: '{redirectUri}' },\n { id: 'scopes', title: 'Add CRM scopes', detail: 'Add the CRM object scopes listed in this spec.' },\n ],\n lifecycle: { supportsRefresh: true, supportsRevoke: true, supportsIncrementalAuth: false, recommendedHealthcheckIntervalHours: 24 },\n },\n slack: {\n id: 'slack',\n title: 'Slack OAuth',\n authMode: 'oauth2',\n consoleUrl: 'https://api.slack.com/apps',\n authorizationUrl: 'https://slack.com/oauth/v2/authorize',\n tokenUrl: 'https://slack.com/api/oauth.v2.access',\n redirectUriTemplate: 'https://{host}/api/integrations/oauth/slack/callback',\n credentialFields: [\n { label: 'Client ID', env: 'SLACK_OAUTH_CLIENT_ID', description: 'Slack app client ID.', secret: false },\n { label: 'Client Secret', env: 'SLACK_OAUTH_CLIENT_SECRET', description: 'Slack app client secret.', secret: true },\n ],\n consoleSteps: [\n { id: 'app', title: 'Create Slack app', detail: 'Create or open a Slack app.' },\n { id: 'redirect', title: 'Add redirect URL', detail: 'Add {redirectUri} under OAuth & Permissions.', copyValue: '{redirectUri}' },\n { id: 'scopes', title: 'Add bot scopes', detail: 'Add the bot token scopes listed in this spec and reinstall the app.' },\n ],\n knownQuirks: [\n { id: 'bot-token', severity: 'info', message: 'Slack usually returns a bot access token; refresh tokens require token rotation.' },\n ],\n lifecycle: { supportsRefresh: false, supportsRevoke: true, supportsIncrementalAuth: false, recommendedHealthcheckIntervalHours: 24 },\n },\n notion: {\n id: 'notion',\n title: 'Notion OAuth',\n authMode: 'oauth2',\n consoleUrl: 'https://www.notion.so/my-integrations',\n authorizationUrl: 'https://api.notion.com/v1/oauth/authorize',\n tokenUrl: 'https://api.notion.com/v1/oauth/token',\n redirectUriTemplate: 'https://{host}/api/integrations/oauth/notion/callback',\n credentialFields: [\n { label: 'Client ID', env: 'NOTION_OAUTH_CLIENT_ID', description: 'Notion integration OAuth client ID.', secret: false },\n { label: 'Client Secret', env: 'NOTION_OAUTH_CLIENT_SECRET', description: 'Notion integration OAuth client secret.', secret: true },\n ],\n consoleSteps: [\n { id: 'integration', title: 'Create integration', detail: 'Create a Notion public integration.' },\n { id: 'redirect', title: 'Add redirect URI', detail: 'Add {redirectUri} as the redirect URI.', copyValue: '{redirectUri}' },\n { id: 'capabilities', title: 'Select capabilities', detail: 'Enable read/update/insert capabilities matching this connector.' },\n ],\n lifecycle: { supportsRefresh: true, supportsRevoke: true, supportsIncrementalAuth: false, recommendedHealthcheckIntervalHours: 24 },\n },\n 'standard-oauth2': {\n id: 'standard-oauth2',\n title: 'Standard OAuth 2.0',\n authMode: 'oauth2',\n redirectUriTemplate: 'https://{host}/api/integrations/oauth/{kind}/callback',\n credentialFields: [\n { label: 'Client ID', description: 'OAuth client ID.', secret: false },\n { label: 'Client Secret', description: 'OAuth client secret.', secret: true },\n ],\n consoleSteps: [\n { id: 'app', title: 'Create OAuth app', detail: 'Create an OAuth app in the provider console.' },\n { id: 'redirect', title: 'Add redirect URI', detail: 'Add {redirectUri} as an allowed redirect URI.', copyValue: '{redirectUri}' },\n { id: 'scopes', title: 'Add scopes', detail: 'Add the scopes listed in this spec.' },\n ],\n lifecycle: { supportsRefresh: true, supportsRevoke: false, supportsIncrementalAuth: false, recommendedHealthcheckIntervalHours: 24 },\n },\n 'api-key': {\n id: 'api-key',\n title: 'API key',\n authMode: 'api_key',\n credentialFields: [\n { label: 'API Key', description: 'Provider API key or token.', example: 'sk_...', secret: true },\n ],\n consoleSteps: [\n { id: 'token', title: 'Create token', detail: 'Create an API key/token in the provider console with the minimum required permissions.' },\n ],\n lifecycle: { supportsRefresh: false, supportsRevoke: true, supportsIncrementalAuth: false, recommendedHealthcheckIntervalHours: 24 },\n },\n hmac: {\n id: 'hmac',\n title: 'HMAC secret',\n authMode: 'hmac',\n credentialFields: [\n { label: 'Signing Secret', description: 'Webhook signing secret.', secret: true },\n ],\n consoleSteps: [\n { id: 'secret', title: 'Configure signing secret', detail: 'Configure the shared signing secret in the sender and receiver.' },\n ],\n lifecycle: { supportsRefresh: false, supportsRevoke: true, supportsIncrementalAuth: false, recommendedHealthcheckIntervalHours: 24 },\n },\n none: {\n id: 'none',\n title: 'No authentication',\n authMode: 'none',\n credentialFields: [],\n consoleSteps: [\n { id: 'configure', title: 'Configure endpoint', detail: 'No provider credentials are required.' },\n ],\n lifecycle: { supportsRefresh: false, supportsRevoke: false, supportsIncrementalAuth: false },\n },\n}\n\nexport function getIntegrationFamily(id: IntegrationFamilyId): IntegrationFamilySpec {\n return INTEGRATION_FAMILIES[id]\n}\n","import type {\n IntegrationConnector,\n IntegrationConnectorAction,\n IntegrationConnectorCategory,\n IntegrationConnectorTrigger,\n IntegrationProviderKind,\n} from './index.js'\n\nexport type IntegrationCoveragePriority = 'tier_0' | 'tier_1' | 'tier_2' | 'long_tail'\n\nexport interface IntegrationCoverageSpec {\n id: string\n title: string\n category: IntegrationConnectorCategory\n auth: IntegrationConnector['auth']\n priority: IntegrationCoveragePriority\n providerKinds: IntegrationProviderKind[]\n domains: string[]\n actionPack: IntegrationActionPack\n scopes?: string[]\n}\n\nexport type IntegrationActionPack =\n | 'email'\n | 'calendar'\n | 'chat'\n | 'crm'\n | 'storage'\n | 'docs'\n | 'database'\n | 'project'\n | 'support'\n | 'marketing'\n | 'sales'\n | 'commerce'\n | 'finance'\n | 'hr'\n | 'dev'\n | 'ai'\n | 'analytics'\n | 'workflow'\n | 'webhook'\n\ntype SpecTuple = [\n id: string,\n title: string,\n category: IntegrationConnectorCategory,\n actionPack: IntegrationActionPack,\n priority: IntegrationCoveragePriority,\n domains: string,\n auth?: IntegrationConnector['auth'],\n]\n\nconst DEFAULT_PROVIDER_KINDS: IntegrationProviderKind[] = ['first_party', 'nango', 'pipedream', 'tangle_catalog', 'custom']\n\nconst COVERAGE_SPECS: SpecTuple[] = [\n ['gmail', 'Gmail', 'email', 'email', 'tier_0', 'email,google,workspace,inbox'],\n ['outlook-mail', 'Outlook Mail', 'email', 'email', 'tier_0', 'email,microsoft,office,inbox'],\n ['google-calendar', 'Google Calendar', 'calendar', 'calendar', 'tier_0', 'calendar,google,workspace,scheduling'],\n ['outlook-calendar', 'Outlook Calendar', 'calendar', 'calendar', 'tier_0', 'calendar,microsoft,office,scheduling'],\n ['slack', 'Slack', 'chat', 'chat', 'tier_0', 'chat,collaboration,internal-comms'],\n ['microsoft-teams', 'Microsoft Teams', 'chat', 'chat', 'tier_0', 'chat,microsoft,collaboration'],\n ['google-drive', 'Google Drive', 'storage', 'storage', 'tier_0', 'files,google,workspace,storage'],\n ['onedrive', 'OneDrive', 'storage', 'storage', 'tier_0', 'files,microsoft,office,storage'],\n ['dropbox', 'Dropbox', 'storage', 'storage', 'tier_1', 'files,storage'],\n ['box', 'Box', 'storage', 'storage', 'tier_1', 'files,enterprise,storage'],\n ['google-docs', 'Google Docs', 'docs', 'docs', 'tier_0', 'docs,google,workspace'],\n ['google-sheets', 'Google Sheets', 'database', 'database', 'tier_0', 'sheets,spreadsheet,google,database'],\n ['microsoft-excel', 'Microsoft Excel', 'database', 'database', 'tier_0', 'sheets,spreadsheet,microsoft,database'],\n ['notion', 'Notion', 'docs', 'docs', 'tier_0', 'docs,wiki,knowledge'],\n ['airtable', 'Airtable', 'database', 'database', 'tier_0', 'database,spreadsheet,ops'],\n ['coda', 'Coda', 'docs', 'docs', 'tier_1', 'docs,wiki,ops'],\n ['confluence', 'Confluence', 'docs', 'docs', 'tier_1', 'docs,wiki,atlassian'],\n ['sharepoint', 'SharePoint', 'storage', 'storage', 'tier_1', 'files,microsoft,enterprise'],\n ['hubspot', 'HubSpot', 'crm', 'crm', 'tier_0', 'crm,sales,marketing'],\n ['salesforce', 'Salesforce', 'crm', 'crm', 'tier_0', 'crm,sales,enterprise'],\n ['pipedrive', 'Pipedrive', 'crm', 'crm', 'tier_1', 'crm,sales'],\n ['zoho-crm', 'Zoho CRM', 'crm', 'crm', 'tier_1', 'crm,sales'],\n ['close', 'Close', 'crm', 'crm', 'tier_1', 'crm,sales'],\n ['attio', 'Attio', 'crm', 'crm', 'tier_1', 'crm,sales,startups'],\n ['linear', 'Linear', 'workflow', 'project', 'tier_0', 'project,engineering,tickets'],\n ['jira', 'Jira', 'workflow', 'project', 'tier_0', 'project,engineering,tickets,atlassian'],\n ['github', 'GitHub', 'workflow', 'dev', 'tier_0', 'code,dev,issues,git'],\n ['gitlab', 'GitLab', 'workflow', 'dev', 'tier_1', 'code,dev,issues,git'],\n ['bitbucket', 'Bitbucket', 'workflow', 'dev', 'tier_2', 'code,dev,git,atlassian'],\n ['asana', 'Asana', 'workflow', 'project', 'tier_1', 'project,tasks'],\n ['trello', 'Trello', 'workflow', 'project', 'tier_1', 'project,tasks,atlassian'],\n ['monday', 'monday.com', 'workflow', 'project', 'tier_1', 'project,tasks,ops'],\n ['clickup', 'ClickUp', 'workflow', 'project', 'tier_1', 'project,tasks,ops'],\n ['basecamp', 'Basecamp', 'workflow', 'project', 'tier_2', 'project,tasks'],\n ['zendesk', 'Zendesk', 'crm', 'support', 'tier_0', 'support,tickets,customer-success'],\n ['intercom', 'Intercom', 'crm', 'support', 'tier_0', 'support,chat,customer-success'],\n ['freshdesk', 'Freshdesk', 'crm', 'support', 'tier_1', 'support,tickets'],\n ['helpscout', 'Help Scout', 'crm', 'support', 'tier_1', 'support,tickets'],\n ['front', 'Front', 'email', 'support', 'tier_1', 'support,email,shared-inbox'],\n ['gorgias', 'Gorgias', 'crm', 'support', 'tier_1', 'support,ecommerce'],\n ['stripe', 'Stripe', 'workflow', 'finance', 'tier_0', 'payments,billing,finance'],\n ['quickbooks', 'QuickBooks', 'workflow', 'finance', 'tier_0', 'accounting,finance'],\n ['xero', 'Xero', 'workflow', 'finance', 'tier_1', 'accounting,finance'],\n ['netsuite', 'NetSuite', 'workflow', 'finance', 'tier_1', 'erp,finance,enterprise'],\n ['sage', 'Sage', 'workflow', 'finance', 'tier_2', 'accounting,finance'],\n ['plaid', 'Plaid', 'workflow', 'finance', 'tier_1', 'banking,finance'],\n ['shopify', 'Shopify', 'workflow', 'commerce', 'tier_0', 'ecommerce,orders,commerce'],\n ['woocommerce', 'WooCommerce', 'workflow', 'commerce', 'tier_1', 'ecommerce,orders,wordpress'],\n ['bigcommerce', 'BigCommerce', 'workflow', 'commerce', 'tier_1', 'ecommerce,orders'],\n ['amazon-seller-central', 'Amazon Seller Central', 'workflow', 'commerce', 'tier_1', 'marketplace,ecommerce'],\n ['ebay', 'eBay', 'workflow', 'commerce', 'tier_2', 'marketplace,ecommerce'],\n ['etsy', 'Etsy', 'workflow', 'commerce', 'tier_2', 'marketplace,ecommerce'],\n ['mailchimp', 'Mailchimp', 'workflow', 'marketing', 'tier_0', 'email-marketing,marketing'],\n ['klaviyo', 'Klaviyo', 'workflow', 'marketing', 'tier_0', 'email-marketing,ecommerce,marketing'],\n ['marketo', 'Marketo', 'workflow', 'marketing', 'tier_1', 'marketing,enterprise'],\n ['braze', 'Braze', 'workflow', 'marketing', 'tier_1', 'marketing,lifecycle'],\n ['customer-io', 'Customer.io', 'workflow', 'marketing', 'tier_1', 'marketing,lifecycle'],\n ['sendgrid', 'SendGrid', 'email', 'email', 'tier_1', 'email,transactional'],\n ['postmark', 'Postmark', 'email', 'email', 'tier_1', 'email,transactional'],\n ['twilio', 'Twilio', 'chat', 'chat', 'tier_0', 'sms,voice,communications'],\n ['discord', 'Discord', 'chat', 'chat', 'tier_1', 'chat,community'],\n ['telegram', 'Telegram', 'chat', 'chat', 'tier_1', 'chat,community'],\n ['whatsapp-business', 'WhatsApp Business', 'chat', 'chat', 'tier_1', 'chat,meta,customer-comms'],\n ['facebook-pages', 'Facebook Pages', 'workflow', 'marketing', 'tier_1', 'social,meta,marketing'],\n ['instagram-business', 'Instagram Business', 'workflow', 'marketing', 'tier_1', 'social,meta,marketing'],\n ['linkedin', 'LinkedIn', 'workflow', 'sales', 'tier_1', 'social,sales,gtm'],\n ['x-twitter', 'X / Twitter', 'workflow', 'marketing', 'tier_1', 'social,marketing'],\n ['youtube', 'YouTube', 'storage', 'storage', 'tier_1', 'video,content'],\n ['tiktok', 'TikTok', 'workflow', 'marketing', 'tier_2', 'social,video,marketing'],\n ['google-analytics', 'Google Analytics', 'database', 'analytics', 'tier_0', 'analytics,web,marketing'],\n ['mixpanel', 'Mixpanel', 'database', 'analytics', 'tier_1', 'analytics,product'],\n ['amplitude', 'Amplitude', 'database', 'analytics', 'tier_1', 'analytics,product'],\n ['segment', 'Segment', 'database', 'analytics', 'tier_1', 'analytics,cdp'],\n ['snowflake', 'Snowflake', 'database', 'database', 'tier_0', 'warehouse,data'],\n ['bigquery', 'BigQuery', 'database', 'database', 'tier_0', 'warehouse,google,data'],\n ['redshift', 'Redshift', 'database', 'database', 'tier_1', 'warehouse,aws,data'],\n ['postgres', 'Postgres', 'database', 'database', 'tier_0', 'database,sql'],\n ['mysql', 'MySQL', 'database', 'database', 'tier_1', 'database,sql'],\n ['mongodb', 'MongoDB', 'database', 'database', 'tier_1', 'database,nosql'],\n ['supabase', 'Supabase', 'database', 'database', 'tier_1', 'database,postgres'],\n ['firebase', 'Firebase', 'database', 'database', 'tier_1', 'database,google,app'],\n ['redis', 'Redis', 'database', 'database', 'tier_2', 'database,cache'],\n ['aws-s3', 'Amazon S3', 'storage', 'storage', 'tier_0', 'files,aws,storage'],\n ['aws-lambda', 'AWS Lambda', 'workflow', 'dev', 'tier_1', 'aws,serverless,dev'],\n ['aws-cloudwatch', 'AWS CloudWatch', 'database', 'analytics', 'tier_1', 'aws,logs,observability'],\n ['google-cloud-storage', 'Google Cloud Storage', 'storage', 'storage', 'tier_1', 'files,gcp,storage'],\n ['azure-blob-storage', 'Azure Blob Storage', 'storage', 'storage', 'tier_1', 'files,azure,storage'],\n ['vercel', 'Vercel', 'workflow', 'dev', 'tier_1', 'deployments,dev'],\n ['netlify', 'Netlify', 'workflow', 'dev', 'tier_2', 'deployments,dev'],\n ['cloudflare', 'Cloudflare', 'workflow', 'dev', 'tier_1', 'edge,dev,dns'],\n ['sentry', 'Sentry', 'workflow', 'dev', 'tier_1', 'errors,observability,dev'],\n ['datadog', 'Datadog', 'database', 'analytics', 'tier_1', 'observability,logs,metrics'],\n ['new-relic', 'New Relic', 'database', 'analytics', 'tier_2', 'observability,logs,metrics'],\n ['pagerduty', 'PagerDuty', 'workflow', 'project', 'tier_1', 'incident,on-call'],\n ['opsgenie', 'Opsgenie', 'workflow', 'project', 'tier_2', 'incident,on-call,atlassian'],\n ['okta', 'Okta', 'internal', 'workflow', 'tier_1', 'identity,security'],\n ['auth0', 'Auth0', 'internal', 'workflow', 'tier_1', 'identity,security'],\n ['workday', 'Workday', 'workflow', 'hr', 'tier_1', 'hr,finance,enterprise'],\n ['bamboohr', 'BambooHR', 'workflow', 'hr', 'tier_1', 'hr,people'],\n ['greenhouse', 'Greenhouse', 'workflow', 'hr', 'tier_1', 'recruiting,hr'],\n ['lever', 'Lever', 'workflow', 'hr', 'tier_1', 'recruiting,hr'],\n ['gusto', 'Gusto', 'workflow', 'hr', 'tier_1', 'payroll,hr'],\n ['rippling', 'Rippling', 'workflow', 'hr', 'tier_1', 'hr,it,identity'],\n ['docusign', 'DocuSign', 'docs', 'docs', 'tier_1', 'contracts,signature,legal'],\n ['pandadoc', 'PandaDoc', 'docs', 'docs', 'tier_1', 'contracts,signature,sales'],\n ['hellosign', 'Dropbox Sign', 'docs', 'docs', 'tier_2', 'contracts,signature'],\n ['clio', 'Clio', 'workflow', 'project', 'tier_1', 'legal,practice-management'],\n ['ironclad', 'Ironclad', 'docs', 'docs', 'tier_1', 'legal,contracts'],\n ['lexisnexis', 'LexisNexis', 'docs', 'docs', 'tier_2', 'legal,research'],\n ['calendly', 'Calendly', 'calendar', 'calendar', 'tier_0', 'scheduling,calendar'],\n ['cal-com', 'Cal.com', 'calendar', 'calendar', 'tier_1', 'scheduling,calendar'],\n ['zoom', 'Zoom', 'calendar', 'calendar', 'tier_0', 'meetings,video,calendar'],\n ['google-meet', 'Google Meet', 'calendar', 'calendar', 'tier_1', 'meetings,google,video'],\n ['microsoft-graph', 'Microsoft Graph', 'internal', 'workflow', 'tier_0', 'microsoft,enterprise,identity'],\n ['openai', 'OpenAI', 'workflow', 'ai', 'tier_0', 'ai,llm'],\n ['anthropic', 'Anthropic', 'workflow', 'ai', 'tier_1', 'ai,llm'],\n ['gemini', 'Google Gemini', 'workflow', 'ai', 'tier_1', 'ai,llm,google'],\n ['huggingface', 'Hugging Face', 'workflow', 'ai', 'tier_1', 'ai,models'],\n ['pinecone', 'Pinecone', 'database', 'database', 'tier_1', 'vector,database,ai'],\n ['weaviate', 'Weaviate', 'database', 'database', 'tier_1', 'vector,database,ai'],\n ['qdrant', 'Qdrant', 'database', 'database', 'tier_1', 'vector,database,ai'],\n ['zapier', 'Zapier', 'workflow', 'workflow', 'tier_1', 'automation,workflow'],\n ['make', 'Make', 'workflow', 'workflow', 'tier_1', 'automation,workflow'],\n ['nango', 'Nango', 'workflow', 'workflow', 'tier_1', 'integration-platform,oauth'],\n ['pipedream', 'Pipedream', 'workflow', 'workflow', 'tier_1', 'integration-platform,workflow'],\n ['open-automation-catalog', 'Open Automation Catalog', 'workflow', 'workflow', 'tier_1', 'automation,workflow,open-source'],\n ['webhook', 'Generic Webhook', 'webhook', 'webhook', 'tier_0', 'webhook,http,events', 'none'],\n ['http', 'HTTP Request', 'workflow', 'webhook', 'tier_0', 'http,api,webhook', 'none'],\n ['rss', 'RSS', 'webhook', 'webhook', 'tier_1', 'feeds,content', 'none'],\n ['zapier-transfer', 'Zapier Transfer', 'workflow', 'workflow', 'long_tail', 'automation,migration'],\n ['typeform', 'Typeform', 'workflow', 'marketing', 'tier_1', 'forms,marketing'],\n ['google-forms', 'Google Forms', 'workflow', 'marketing', 'tier_1', 'forms,google'],\n ['jotform', 'Jotform', 'workflow', 'marketing', 'tier_2', 'forms'],\n ['webflow', 'Webflow', 'workflow', 'marketing', 'tier_1', 'cms,website'],\n ['wordpress', 'WordPress', 'workflow', 'marketing', 'tier_1', 'cms,website'],\n ['contentful', 'Contentful', 'docs', 'docs', 'tier_1', 'cms,content'],\n ['sanity', 'Sanity', 'docs', 'docs', 'tier_1', 'cms,content'],\n ['figma', 'Figma', 'docs', 'docs', 'tier_0', 'design,creative'],\n ['canva', 'Canva', 'docs', 'docs', 'tier_1', 'design,creative'],\n ['adobe-creative-cloud', 'Adobe Creative Cloud', 'storage', 'storage', 'tier_1', 'design,creative,files'],\n ['miro', 'Miro', 'docs', 'docs', 'tier_1', 'whiteboard,collaboration'],\n ['figjam', 'FigJam', 'docs', 'docs', 'tier_2', 'whiteboard,design'],\n]\n\nexport function listIntegrationCoverageSpecs(): IntegrationCoverageSpec[] {\n return COVERAGE_SPECS.map(([id, title, category, actionPack, priority, domains, auth = 'oauth2']) => ({\n id,\n title,\n category,\n actionPack,\n priority,\n auth,\n providerKinds: providerKindsFor(auth),\n domains: domains.split(',').map((domain) => domain.trim()).filter(Boolean),\n scopes: scopesFor(id, actionPack),\n }))\n}\n\nexport function buildIntegrationCoverageConnectors(options: {\n providerId?: string\n priorities?: IntegrationCoveragePriority[]\n categories?: IntegrationConnectorCategory[]\n actionPacks?: IntegrationActionPack[]\n} = {}): IntegrationConnector[] {\n const providerId = options.providerId ?? 'coverage'\n return listIntegrationCoverageSpecs()\n .filter((spec) => !options.priorities || options.priorities.includes(spec.priority))\n .filter((spec) => !options.categories || options.categories.includes(spec.category))\n .filter((spec) => !options.actionPacks || options.actionPacks.includes(spec.actionPack))\n .map((spec) => specToConnector(spec, providerId))\n}\n\nexport function integrationCoverageChecklistMarkdown(): string {\n const specs = listIntegrationCoverageSpecs()\n const lines = [\n '# Agent Integrations Coverage Checklist',\n '',\n 'Generated from `listIntegrationCoverageSpecs()`. Catalog presence means the product can plan/request/connect the integration; native adapters and runtime backends execute behind the same provider contract.',\n '',\n '## Summary',\n '',\n `- Total cataloged integrations: ${specs.length}`,\n `- Tier 0: ${specs.filter((spec) => spec.priority === 'tier_0').length}`,\n `- Tier 1: ${specs.filter((spec) => spec.priority === 'tier_1').length}`,\n `- Tier 2: ${specs.filter((spec) => spec.priority === 'tier_2').length}`,\n `- Long tail: ${specs.filter((spec) => spec.priority === 'long_tail').length}`,\n '',\n '## Checklist',\n '',\n ]\n for (const spec of specs) {\n lines.push(`- [ ] ${spec.priority} / ${spec.category} / ${spec.title} (${spec.id}) - ${spec.domains.join(', ')}`)\n }\n return `${lines.join('\\n')}\\n`\n}\n\nfunction specToConnector(spec: IntegrationCoverageSpec, providerId: string): IntegrationConnector {\n const actions = actionPack(spec.actionPack, spec.scopes ?? [])\n return {\n id: spec.id,\n providerId,\n title: spec.title,\n category: spec.category,\n auth: spec.auth,\n scopes: spec.scopes ?? [],\n actions,\n triggers: triggersFor(spec.actionPack, spec.scopes ?? []),\n metadata: {\n source: 'coverage-catalog',\n priority: spec.priority,\n domains: spec.domains,\n providerKinds: spec.providerKinds,\n executable: false,\n },\n }\n}\n\nfunction actionPack(pack: IntegrationActionPack, scopes: string[]): IntegrationConnectorAction[] {\n const readScope = scopes.find((scope) => scope.endsWith('.read')) ?? scopes[0]\n const writeScope = scopes.find((scope) => scope.endsWith('.write')) ?? scopes[1] ?? readScope\n const scope = (value?: string) => value ? [value] : []\n const read = (id: string, title: string, description: string): IntegrationConnectorAction => ({\n id,\n title,\n description,\n risk: 'read',\n requiredScopes: scope(readScope),\n dataClass: dataClassFor(pack),\n inputSchema: objectSchema(),\n })\n const write = (id: string, title: string, description: string): IntegrationConnectorAction => ({\n id,\n title,\n description,\n risk: 'write',\n requiredScopes: scope(writeScope),\n dataClass: dataClassFor(pack),\n approvalRequired: true,\n inputSchema: objectSchema(),\n })\n const destructive = (id: string, title: string, description: string): IntegrationConnectorAction => ({\n id,\n title,\n description,\n risk: 'destructive',\n requiredScopes: scope(writeScope),\n dataClass: dataClassFor(pack),\n approvalRequired: true,\n inputSchema: objectSchema(),\n })\n switch (pack) {\n case 'email': return [read('messages.search', 'Search messages', 'Search messages and threads.'), read('messages.read', 'Read message', 'Read a message by id.'), write('drafts.create', 'Create draft', 'Create an email draft.'), write('messages.send', 'Send message', 'Send or reply to an email message.')]\n case 'calendar': return [read('events.search', 'Search events', 'Search calendar events.'), read('availability.read', 'Read availability', 'Read availability windows.'), write('events.create', 'Create event', 'Create a calendar event.'), write('events.update', 'Update event', 'Update a calendar event.'), destructive('events.cancel', 'Cancel event', 'Cancel a calendar event.')]\n case 'chat': return [read('messages.search', 'Search messages', 'Search channel or direct messages.'), read('channels.list', 'List channels', 'List channels or rooms.'), write('messages.post', 'Send message', 'Send a message to a channel or direct message.'), write('threads.reply', 'Reply in thread', 'Reply to a thread or conversation.')]\n case 'crm': return [read('records.search', 'Search records', 'Search contacts, companies, and deals.'), read('records.read', 'Read record', 'Read a CRM record.'), write('records.upsert', 'Upsert record', 'Create or update a CRM record.'), write('notes.create', 'Create note', 'Add a note or activity.')]\n case 'storage': return [read('files.search', 'Search files', 'Search files and folders.'), read('files.read', 'Read file', 'Read file metadata or content.'), write('files.upload', 'Upload file', 'Upload a file.'), write('files.update', 'Update file', 'Update file metadata or content.')]\n case 'docs': return [read('documents.search', 'Search documents', 'Search documents or pages.'), read('documents.read', 'Read document', 'Read a document.'), write('documents.create', 'Create document', 'Create a document or page.'), write('documents.update', 'Update document', 'Update a document or page.')]\n case 'database': return [read('records.query', 'Query records', 'Query rows, records, or objects.'), read('records.read', 'Read record', 'Read one row, record, or object.'), write('records.upsert', 'Upsert record', 'Create or update a row, record, or object.'), destructive('records.delete', 'Delete record', 'Delete a row, record, or object.')]\n case 'project': return [read('tasks.search', 'Search tasks', 'Search tasks, tickets, or issues.'), read('tasks.read', 'Read task', 'Read a task, ticket, or issue.'), write('tasks.create', 'Create task', 'Create a task, ticket, or issue.'), write('tasks.update', 'Update task', 'Update a task, ticket, or issue.')]\n case 'support': return [read('tickets.search', 'Search tickets', 'Search support tickets or conversations.'), read('customers.read', 'Read customer', 'Read a customer profile.'), write('tickets.reply', 'Reply to ticket', 'Reply to a support ticket.'), write('tickets.update', 'Update ticket', 'Update ticket status, tags, or assignee.')]\n case 'marketing': return [read('contacts.search', 'Search contacts', 'Search marketing contacts or audiences.'), read('campaigns.read', 'Read campaign', 'Read campaign metadata and performance.'), write('contacts.upsert', 'Upsert contact', 'Create or update a contact.'), write('campaigns.create', 'Create campaign', 'Create a campaign draft.')]\n case 'sales': return [read('prospects.search', 'Search prospects', 'Search prospects, leads, or accounts.'), read('activities.read', 'Read activities', 'Read sales activity history.'), write('prospects.upsert', 'Upsert prospect', 'Create or update a prospect.'), write('sequence.enqueue', 'Enroll in sequence', 'Enroll a prospect in a sales sequence.')]\n case 'commerce': return [read('orders.search', 'Search orders', 'Search orders.'), read('customers.read', 'Read customer', 'Read customer and purchase history.'), write('orders.update', 'Update order', 'Update order metadata or fulfillment state.'), write('products.update', 'Update product', 'Update product metadata.')]\n case 'finance': return [read('transactions.search', 'Search transactions', 'Search transactions, invoices, or payments.'), read('accounts.read', 'Read account', 'Read account or customer financial record.'), write('invoices.create', 'Create invoice', 'Create an invoice or payment object.'), write('records.sync', 'Sync record', 'Sync a finance or accounting record.')]\n case 'hr': return [read('people.search', 'Search people', 'Search employees, candidates, or contractors.'), read('people.read', 'Read person', 'Read a person profile.'), write('people.update', 'Update person', 'Update a person profile.'), write('events.create', 'Create HR event', 'Create a recruiting or HR event.')]\n case 'dev': return [read('resources.search', 'Search resources', 'Search issues, repos, deployments, logs, or incidents.'), read('resources.read', 'Read resource', 'Read a developer resource.'), write('resources.create', 'Create resource', 'Create an issue, deployment, incident, or config.'), write('resources.update', 'Update resource', 'Update a developer resource.')]\n case 'ai': return [read('models.list', 'List models', 'List available models or endpoints.'), write('responses.create', 'Create response', 'Create an AI response or job.'), write('embeddings.create', 'Create embeddings', 'Create embeddings or vector jobs.'), read('usage.read', 'Read usage', 'Read usage metadata.')]\n case 'analytics': return [read('reports.query', 'Query reports', 'Query analytics reports.'), read('events.search', 'Search events', 'Search analytics events.'), write('events.track', 'Track event', 'Track an analytics event.'), write('audiences.sync', 'Sync audience', 'Sync an audience or cohort.')]\n case 'workflow': return [read('runs.search', 'Search runs', 'Search workflow runs or jobs.'), read('templates.list', 'List templates', 'List workflow templates.'), write('runs.start', 'Start run', 'Start a workflow run.'), write('webhooks.dispatch', 'Dispatch webhook', 'Dispatch a workflow webhook.')]\n case 'webhook': return [write('requests.send', 'Send request', 'Send an HTTP request or webhook event.'), read('events.search', 'Search events', 'Search received webhook events.'), write('subscriptions.create', 'Create subscription', 'Create a webhook subscription.'), destructive('subscriptions.delete', 'Delete subscription', 'Delete a webhook subscription.')]\n }\n}\n\nfunction triggersFor(pack: IntegrationActionPack, scopes: string[]): IntegrationConnectorTrigger[] | undefined {\n const readScope = scopes.find((scope) => scope.endsWith('.read')) ?? scopes[0]\n const requiredScopes = readScope ? [readScope] : []\n if (pack === 'email') return [{ id: 'message.received', title: 'Message received', requiredScopes, dataClass: 'private' }]\n if (pack === 'calendar') return [{ id: 'event.changed', title: 'Event changed', requiredScopes, dataClass: 'private' }]\n if (pack === 'chat') return [{ id: 'message.posted', title: 'Message posted', requiredScopes, dataClass: 'private' }]\n if (pack === 'crm') return [{ id: 'record.changed', title: 'Record changed', requiredScopes, dataClass: 'private' }]\n if (pack === 'support') return [{ id: 'ticket.changed', title: 'Ticket changed', requiredScopes, dataClass: 'private' }]\n if (pack === 'commerce') return [{ id: 'order.changed', title: 'Order changed', requiredScopes, dataClass: 'sensitive' }]\n if (pack === 'finance') return [{ id: 'transaction.changed', title: 'Transaction changed', requiredScopes, dataClass: 'sensitive' }]\n if (pack === 'workflow' || pack === 'webhook') return [{ id: 'event.received', title: 'Event received', requiredScopes, dataClass: 'internal' }]\n return undefined\n}\n\nfunction scopesFor(id: string, pack: IntegrationActionPack): string[] {\n if (pack === 'webhook') return []\n return [`${id}.read`, `${id}.write`]\n}\n\nfunction providerKindsFor(auth: IntegrationConnector['auth']): IntegrationProviderKind[] {\n if (auth === 'none') return ['first_party', 'pipedream', 'tangle_catalog', 'custom']\n return DEFAULT_PROVIDER_KINDS\n}\n\nfunction dataClassFor(pack: IntegrationActionPack): 'public' | 'internal' | 'private' | 'sensitive' {\n if (pack === 'finance' || pack === 'commerce' || pack === 'hr') return 'sensitive'\n if (pack === 'workflow' || pack === 'webhook' || pack === 'dev' || pack === 'analytics') return 'internal'\n return 'private'\n}\n\nfunction objectSchema(): unknown {\n return { type: 'object', additionalProperties: true, properties: {} }\n}\n","/**\n * Per-kind overrides on top of family defaults.\n *\n * The family layer (`families.ts`) carries the auth-shape defaults — generic\n * \"API Key\" or \"Client ID + Client Secret\" credential fields, generic console\n * steps. Most kinds are happy with that. But some have provider-specific\n * shape that the family can't capture: Twilio's auth is two-part (Account\n * SID + Auth Token); Stripe's preferred path is restricted keys with specific\n * granted permissions; SendGrid demands a verified sender domain in the\n * console before keys work.\n *\n * `INTEGRATION_OVERRIDES` is the seam for that. The registry merges the\n * override on top of the family defaults at spec-build time. Override\n * fields are purely additive — set what you want to customize, leave the\n * rest absent and the family defaults apply.\n *\n * Adding a new override:\n * 1. Author the override entry below.\n * 2. The next spec build picks it up automatically; no other registry\n * change needed. Coverage catalog stays compact.\n *\n * Why a separate map and not inline on `IntegrationCoverageSpec`: the\n * coverage catalog is a flat tuple list optimized for fast iteration over\n * 142 specs. Bloating the tuple with optional override fields hurts\n * readability of the catalog AND scatters provider knowledge across two\n * data shapes. Keeping overrides in their own keyed map means contributors\n * looking for \"how does Stripe credential setup work\" find it in one place.\n */\n\nimport type {\n ConsoleStep,\n CredentialFieldSpec,\n HealthcheckSpec,\n PostSetupCheck,\n Quirk,\n} from './types.js'\n\nexport interface IntegrationOverride {\n /** Replaces `setup.consoleUrl` from the family default. */\n consoleUrl?: string\n /** Replaces `setup.consoleSteps`. Specify the full list — overrides do\n * not deep-merge step arrays because step ordering is meaningful. */\n consoleSteps?: ConsoleStep[]\n /** Replaces `setup.credentialFields`. Use to add a second field (e.g.\n * Twilio Account SID + Auth Token), tighten validation regex, or\n * enrich field descriptions with provider-specific guidance. */\n credentialFields?: CredentialFieldSpec[]\n /** Appended to `setup.knownQuirks`. */\n knownQuirks?: Quirk[]\n /** Replaces `setup.postSetup`. */\n postSetup?: PostSetupCheck[]\n /** Replaces the healthcheck the registry would otherwise infer. */\n healthcheck?: HealthcheckSpec\n}\n\nexport const INTEGRATION_OVERRIDES: Record<string, IntegrationOverride> = {\n // ── Stripe pack ────────────────────────────────────────────────────\n // Stripe issues two key types: secret keys (sk_*) and restricted keys\n // (rk_*). For voice-agent workloads, restricted keys are the right call\n // — least-privilege scoped to the specific resources the agent can\n // touch. The hint nudges operators toward that path.\n 'stripe-pack': {\n consoleUrl: 'https://dashboard.stripe.com/apikeys',\n credentialFields: [\n {\n label: 'Stripe secret key',\n description:\n 'Restricted key recommended. Dashboard → Developers → API keys → Create restricted key. ' +\n 'Grant write access on Customers, Invoices, and Checkout Sessions.',\n example: 'sk_live_… or rk_live_… (use sk_test_… / rk_test_… for staging)',\n regex: '^(sk|rk)_(live|test)_[A-Za-z0-9]+$',\n secret: true,\n },\n ],\n consoleSteps: [\n {\n id: 'open-keys',\n title: 'Open Stripe API keys',\n detail: 'Visit https://dashboard.stripe.com/apikeys',\n copyValue: 'https://dashboard.stripe.com/apikeys',\n },\n {\n id: 'create-restricted',\n title: 'Create a restricted key',\n detail:\n 'Click \"Create restricted key\". Name it something descriptive ' +\n '(e.g. \"ph0ny voice agent — prod\"). Grant WRITE on Customers, ' +\n 'Invoices, and Checkout Sessions. Leave everything else NONE.',\n },\n {\n id: 'paste',\n title: 'Paste the key',\n detail:\n 'Copy the key Stripe shows once (rk_live_… or sk_live_…). ' +\n 'Paste it into ph0ny. The key is sealed before persistence.',\n },\n ],\n },\n\n // ── Twilio SMS ─────────────────────────────────────────────────────\n // Twilio's REST API uses Basic auth with two parts: Account SID\n // (public-ish, AC…) + Auth Token (secret). The default api-key family\n // only exposes one field, which doesn't fit. Providing both fields\n // explicitly lets the consumer's UI render two inputs.\n 'twilio-sms': {\n consoleUrl: 'https://console.twilio.com/',\n credentialFields: [\n {\n label: 'Account SID',\n description: 'Your Twilio Account SID. Console → Account → API keys & tokens.',\n example: 'AC… (34 hex chars)',\n regex: '^AC[a-f0-9]{32}$',\n secret: false,\n },\n {\n label: 'Auth Token',\n description:\n 'Your Twilio Auth Token (or Standard API Key secret). ' +\n 'Use a non-primary auth token in production so rotating it ' +\n \"won't break other Twilio integrations.\",\n secret: true,\n },\n ],\n consoleSteps: [\n {\n id: 'open',\n title: 'Open Twilio console',\n detail: 'Visit https://console.twilio.com/',\n copyValue: 'https://console.twilio.com/',\n },\n {\n id: 'find',\n title: 'Find your Account SID + Auth Token',\n detail:\n 'Account info is on the dashboard home. For better security, ' +\n 'create a Standard API Key (Account → API keys & tokens → Create ' +\n 'API Key) and use the SID + Secret pair instead of the primary ' +\n 'auth token.',\n },\n {\n id: 'paste',\n title: 'Paste both values',\n detail: 'Account SID is non-secret; Auth Token is sealed before persistence.',\n },\n ],\n knownQuirks: [\n {\n id: 'subaccount-tokens',\n severity: 'info',\n message:\n 'If you use Twilio subaccounts, paste the SID/Token of the ' +\n 'subaccount that owns the phone numbers your agent calls — not ' +\n 'the master account.',\n },\n ],\n },\n}\n\n/** Public read — undefined when no override exists for the kind. */\nexport function getIntegrationOverride(kind: string): IntegrationOverride | undefined {\n return INTEGRATION_OVERRIDES[kind]\n}\n","import {\n buildIntegrationCoverageConnectors,\n listIntegrationCoverageSpecs,\n type IntegrationCoverageSpec,\n} from '../coverage-catalog.js'\nimport type {\n IntegrationConnector,\n IntegrationConnectorAction,\n IntegrationConnectorTrigger,\n IntegrationDataClass,\n} from '../index.js'\nimport { INTEGRATION_FAMILIES, getIntegrationFamily } from './families.js'\nimport { getIntegrationOverride } from './overrides.js'\nimport type {\n ApiKeyAuthSpec,\n HealthcheckSpec,\n HmacAuthSpec,\n IntegrationAuthSpec,\n IntegrationFamilyId,\n IntegrationPlannerHints,\n IntegrationSpec,\n IntegrationSpecStatus,\n NoneAuthSpec,\n NormalizedPermission,\n OAuth2AuthSpec,\n PermissionDescriptor,\n ScopeDescriptor,\n} from './types.js'\n\nconst EXECUTABLE_KINDS = new Set([\n 'google-calendar',\n 'google-sheets',\n 'outlook-calendar',\n 'microsoft-calendar',\n 'slack',\n 'hubspot',\n 'notion',\n 'notion-database',\n 'salesforce',\n 'github',\n 'gitlab',\n 'airtable',\n 'asana',\n 'stripe',\n 'stripe-pack',\n 'twilio',\n 'twilio-sms',\n 'webhook',\n])\n\nconst KIND_ALIASES: Record<string, string> = {\n 'outlook-calendar': 'microsoft-calendar',\n notion: 'notion-database',\n stripe: 'stripe-pack',\n twilio: 'twilio-sms',\n}\n\nexport function listIntegrationSpecs(): IntegrationSpec[] {\n const connectors = new Map(buildIntegrationCoverageConnectors({ providerId: 'spec' }).map((c) => [c.id, c]))\n return listIntegrationCoverageSpecs().map((coverage) => {\n const connector = connectors.get(coverage.id)\n if (!connector) throw new Error(`missing coverage connector for ${coverage.id}`)\n return specFromCoverage(coverage, connector)\n })\n}\n\nexport function getIntegrationSpec(kind: string): IntegrationSpec | undefined {\n const canonical = KIND_ALIASES[kind] ?? kind\n return listIntegrationSpecs().find((spec) => spec.kind === canonical || KIND_ALIASES[spec.kind] === canonical)\n}\n\nexport function listExecutableIntegrationSpecs(): IntegrationSpec[] {\n return listIntegrationSpecs().filter((spec) => spec.status === 'executable')\n}\n\nexport function integrationSpecToConnector(spec: IntegrationSpec, providerId = 'spec'): IntegrationConnector {\n return {\n id: spec.kind,\n providerId,\n title: spec.title,\n category: spec.category,\n auth: spec.auth.mode === 'api_key' ? 'api_key' : spec.auth.mode === 'oauth2' ? 'oauth2' : spec.auth.mode === 'none' ? 'none' : 'custom',\n scopes: spec.permissions.flatMap((permission) => permission.providerScopes),\n actions: spec.actions,\n triggers: spec.triggers,\n metadata: {\n ...(spec.metadata ?? {}),\n source: 'integration-spec',\n status: spec.status,\n family: spec.family,\n plannerHints: spec.plannerHints,\n },\n }\n}\n\nfunction specFromCoverage(coverage: IntegrationCoverageSpec, connector: IntegrationConnector): IntegrationSpec {\n const kind = KIND_ALIASES[coverage.id] ?? coverage.id\n const family = familyFor(coverage)\n const familySpec = getIntegrationFamily(family)\n const permissions = permissionsFor(coverage, connector.actions)\n const auth = authFor(coverage, family, permissions)\n const status = statusFor(kind)\n // Per-kind overrides layer in here — see specs/overrides.ts. The override\n // is consulted under the canonical kind AND the original coverage id so\n // alias-collapsed kinds (e.g. notion → notion-database) can carry an\n // override under either name.\n const override =\n getIntegrationOverride(kind) ?? getIntegrationOverride(coverage.id)\n // Family quirks + override quirks are concatenated; everything else is\n // a replace (override fields take precedence when present).\n const knownQuirks = override?.knownQuirks\n ? [...(familySpec.knownQuirks ?? []), ...override.knownQuirks]\n : familySpec.knownQuirks\n return {\n kind,\n title: connector.title,\n category: connector.category,\n status,\n family,\n auth,\n permissions,\n actions: connector.actions,\n triggers: connector.triggers,\n setup: {\n consoleUrl: override?.consoleUrl ?? familySpec.consoleUrl,\n consoleSteps: override?.consoleSteps ?? familySpec.consoleSteps,\n credentialFields: override?.credentialFields ?? credentialFieldsFor(auth),\n redirectUriTemplate: auth.mode === 'oauth2' ? auth.redirectUriTemplate : familySpec.redirectUriTemplate,\n knownQuirks,\n postSetup: override?.postSetup,\n healthcheck: override?.healthcheck ?? healthcheckFor(kind, status, auth),\n },\n lifecycle: familySpec.lifecycle,\n plannerHints: plannerHintsFor(coverage, connector.actions),\n metadata: { priority: coverage.priority, domains: coverage.domains },\n }\n}\n\nfunction familyFor(spec: IntegrationCoverageSpec): IntegrationFamilyId {\n if (hmacKinds.has(spec.id)) return 'hmac'\n if (spec.auth === 'none') return 'none'\n if (spec.id.startsWith('google-') || spec.domains.includes('google')) return 'google'\n if (spec.id.startsWith('microsoft-') || ['outlook-mail', 'outlook-calendar', 'onedrive', 'sharepoint'].includes(spec.id)) return 'microsoft-graph'\n if (['jira', 'confluence', 'trello', 'bitbucket'].includes(spec.id)) return 'atlassian'\n if (spec.id === 'salesforce') return 'salesforce'\n if (spec.id === 'hubspot') return 'hubspot'\n if (spec.id === 'slack') return 'slack'\n if (spec.id === 'notion') return 'notion'\n if (apiKeyKinds.has(spec.id)) return 'api-key'\n return 'standard-oauth2'\n}\n\nconst apiKeyKinds = new Set(['github', 'gitlab', 'airtable', 'asana', 'stripe', 'twilio', 'sendgrid', 'postmark'])\nconst hmacKinds = new Set(['webhook'])\n\nfunction authFor(\n spec: IntegrationCoverageSpec,\n family: IntegrationFamilyId,\n permissions: PermissionDescriptor[],\n): IntegrationAuthSpec {\n const f = INTEGRATION_FAMILIES[family]\n if (family === 'none') return { mode: 'none' } satisfies NoneAuthSpec\n if (family === 'hmac') {\n return { mode: 'hmac', credential: f.credentialFields[0]!, signatureHeader: `${spec.id}-signature` } satisfies HmacAuthSpec\n }\n if (family === 'api-key') {\n return { mode: 'api_key', credential: apiKeyFieldFor(spec.id), placement: apiKeyPlacementFor(spec.id) } satisfies ApiKeyAuthSpec\n }\n const scopes = permissions.flatMap((permission) =>\n permission.providerScopes.map((providerScope): ScopeDescriptor => ({\n normalized: permission.normalized,\n providerScope,\n title: permission.title,\n reason: permission.reason,\n risk: permission.risk,\n dataClass: permission.dataClass,\n })),\n )\n return {\n mode: 'oauth2',\n authorizationUrl: f.authorizationUrl ?? `https://example.invalid/${spec.id}/authorize`,\n tokenUrl: f.tokenUrl ?? `https://example.invalid/${spec.id}/token`,\n clientIdEnv: f.credentialFields.find((field) => !field.secret)?.env,\n clientSecretEnv: f.credentialFields.find((field) => field.secret)?.env,\n scopes,\n extraAuthParams: extraAuthParamsFor(family),\n redirectUriTemplate: (f.redirectUriTemplate ?? 'https://{host}/api/integrations/oauth/{kind}/callback').replace('{kind}', spec.id),\n pkce: family === 'google' || family === 'microsoft-graph' ? 'supported' : 'unsupported',\n } satisfies OAuth2AuthSpec\n}\n\nfunction credentialFieldsFor(auth: IntegrationAuthSpec) {\n if (auth.mode === 'api_key' || auth.mode === 'hmac') return [auth.credential]\n if (auth.mode === 'oauth2') {\n return [\n { label: 'Client ID', env: auth.clientIdEnv, description: 'OAuth client ID.', secret: false },\n { label: 'Client Secret', env: auth.clientSecretEnv, description: 'OAuth client secret.', secret: true },\n ]\n }\n return []\n}\n\nfunction permissionsFor(spec: IntegrationCoverageSpec, actions: IntegrationConnectorAction[]): PermissionDescriptor[] {\n const dataClass = dataClassFor(actions)\n const readScope = providerScopeFor(spec, 'read')\n const writeScope = providerScopeFor(spec, 'write')\n const permissions: PermissionDescriptor[] = [\n {\n normalized: `${spec.actionPack}.read` as NormalizedPermission,\n providerScopes: readScope ? [readScope] : [],\n title: `${spec.title} read`,\n risk: 'read',\n dataClass,\n reason: `Read ${spec.title} data for user-authorized agent workflows.`,\n },\n ]\n if (actions.some((a) => a.risk !== 'read')) {\n permissions.push({\n normalized: `${spec.actionPack}.write` as NormalizedPermission,\n providerScopes: writeScope ? [writeScope] : [],\n title: `${spec.title} write`,\n risk: 'write',\n dataClass,\n reason: `Create or update ${spec.title} resources after policy approval.`,\n })\n }\n return permissions\n}\n\nfunction providerScopeFor(spec: IntegrationCoverageSpec, mode: 'read' | 'write'): string {\n const explicit = explicitScopes[spec.id]?.[mode]\n if (explicit) return explicit\n if (spec.auth === 'none') return ''\n return `${spec.id}.${mode}`\n}\n\nconst explicitScopes: Record<string, Partial<Record<'read' | 'write', string>>> = {\n gmail: { read: 'https://www.googleapis.com/auth/gmail.readonly', write: 'https://www.googleapis.com/auth/gmail.modify' },\n 'google-calendar': { read: 'https://www.googleapis.com/auth/calendar.readonly', write: 'https://www.googleapis.com/auth/calendar' },\n 'google-sheets': { read: 'https://www.googleapis.com/auth/spreadsheets.readonly', write: 'https://www.googleapis.com/auth/spreadsheets' },\n 'google-drive': { read: 'https://www.googleapis.com/auth/drive.readonly', write: 'https://www.googleapis.com/auth/drive.file' },\n 'google-docs': { read: 'https://www.googleapis.com/auth/documents.readonly', write: 'https://www.googleapis.com/auth/documents' },\n 'outlook-mail': { read: 'Mail.Read', write: 'Mail.Send' },\n 'outlook-calendar': { read: 'Calendars.Read', write: 'Calendars.ReadWrite' },\n 'microsoft-teams': { read: 'ChannelMessage.Read.All', write: 'ChannelMessage.Send' },\n onedrive: { read: 'Files.Read', write: 'Files.ReadWrite' },\n sharepoint: { read: 'Sites.Read.All', write: 'Sites.ReadWrite.All' },\n slack: { read: 'channels:read', write: 'chat:write' },\n hubspot: { read: 'crm.objects.contacts.read', write: 'crm.objects.contacts.write' },\n salesforce: { read: 'api', write: 'api' },\n notion: { read: '', write: '' },\n github: { read: 'repo:read', write: 'repo' },\n gitlab: { read: 'read_api', write: 'api' },\n airtable: { read: 'data.records:read', write: 'data.records:write' },\n asana: { read: 'default', write: 'default' },\n stripe: { read: 'read_only', write: 'standard' },\n twilio: { read: 'api_key', write: 'api_key' },\n}\n\nfunction plannerHintsFor(spec: IntegrationCoverageSpec, actions: IntegrationConnectorAction[]): IntegrationPlannerHints {\n return {\n useFor: spec.domains.map((domain) => domain.replace(/-/g, ' ')),\n dataFreshness: ['calendar', 'chat', 'commerce', 'finance', 'support'].includes(spec.actionPack) ? 'near_realtime' : 'eventual',\n writeRisk: actions.some((a) => a.risk === 'destructive') ? 'high' : actions.some((a) => a.risk === 'write') ? 'medium' : 'low',\n }\n}\n\nfunction healthcheckFor(kind: string, status: IntegrationSpecStatus, auth: IntegrationAuthSpec): HealthcheckSpec {\n if (status !== 'executable') {\n return { id: `${kind}.static`, level: 'static', description: 'Catalog-only integration; no executable connector healthcheck is available yet.' }\n }\n if (auth.mode === 'oauth2') {\n return { id: `${kind}.connection`, level: 'connection', description: 'Validate a user connection by calling the connector test endpoint.' }\n }\n if (auth.mode === 'api_key') {\n return { id: `${kind}.connection`, level: 'connection', description: 'Validate API credentials by calling the connector test endpoint.' }\n }\n if (auth.mode === 'hmac') {\n return { id: `${kind}.webhook`, level: 'webhook', description: 'Validate webhook signing configuration with a signed test payload.' }\n }\n return { id: `${kind}.static`, level: 'static', description: 'No credentials are required.' }\n}\n\nfunction statusFor(kind: string): IntegrationSpecStatus {\n return EXECUTABLE_KINDS.has(kind) ? 'executable' : 'catalog'\n}\n\nfunction dataClassFor(actions: IntegrationConnectorAction[]): IntegrationDataClass {\n if (actions.some((a) => a.dataClass === 'secret')) return 'secret'\n if (actions.some((a) => a.dataClass === 'sensitive')) return 'sensitive'\n if (actions.some((a) => a.dataClass === 'private')) return 'private'\n if (actions.some((a) => a.dataClass === 'internal')) return 'internal'\n return 'public'\n}\n\nfunction apiKeyFieldFor(kind: string) {\n return {\n label: `${kind} API key`,\n description: `API key or token for ${kind}.`,\n example: kind === 'stripe' ? 'sk_live_...' : undefined,\n secret: true,\n }\n}\n\nfunction apiKeyPlacementFor(kind: string): ApiKeyAuthSpec['placement'] {\n if (kind === 'gitlab') return 'header'\n return 'bearer'\n}\n\nfunction extraAuthParamsFor(family: IntegrationFamilyId): Record<string, string> | undefined {\n if (family === 'google') return { access_type: 'offline', prompt: 'consent', include_granted_scopes: 'true' }\n if (family === 'notion') return { owner: 'user' }\n return undefined\n}\n","import type {\n ConsoleStep,\n HealthcheckPlan,\n IntegrationSpec,\n RenderSpecOptions,\n RenderedConsoleStep,\n} from './types.js'\n\nexport function renderConsoleSteps(spec: IntegrationSpec, options: RenderSpecOptions): RenderedConsoleStep[] {\n const redirectUri = renderRedirectUri(spec, options)\n return spec.setup.consoleSteps.map((step) => ({\n ...step,\n detail: renderTemplate(step.detail, spec, options, redirectUri),\n copyValue: step.copyValue ? renderTemplate(step.copyValue, spec, options, redirectUri) : undefined,\n }))\n}\n\nexport function renderRunbookMarkdown(spec: IntegrationSpec, options: RenderSpecOptions): string {\n const steps = renderConsoleSteps(spec, options)\n const lines = [\n `# ${spec.title} Integration Setup`,\n '',\n `- Kind: \\`${spec.kind}\\``,\n `- Status: \\`${spec.status}\\``,\n `- Auth: \\`${spec.auth.mode}\\``,\n `- Family: \\`${spec.family}\\``,\n ]\n if (spec.setup.consoleUrl) lines.push(`- Console: ${spec.setup.consoleUrl}`)\n if (spec.setup.redirectUriTemplate) lines.push(`- Redirect URI: \\`${renderRedirectUri(spec, options)}\\``)\n lines.push('', '## Credentials', '')\n for (const field of spec.setup.credentialFields) {\n lines.push(`- ${field.secret ? '[secret] ' : ''}${field.label}${field.env ? ` (\\`${field.env}\\`)` : ''}: ${field.description}`)\n }\n lines.push('', '## Permissions', '')\n for (const permission of spec.permissions) {\n lines.push(`- \\`${permission.normalized}\\`: ${permission.providerScopes.length ? permission.providerScopes.map((scope) => `\\`${scope}\\``).join(', ') : 'no provider scope'} - ${permission.reason}`)\n }\n lines.push('', '## Console Steps', '')\n for (const [i, step] of steps.entries()) {\n lines.push(`${i + 1}. ${step.title}: ${step.detail}`)\n }\n if (spec.setup.knownQuirks?.length) {\n lines.push('', '## Known Quirks', '')\n for (const quirk of spec.setup.knownQuirks) lines.push(`- ${quirk.severity}: ${quirk.message}`)\n }\n return `${lines.join('\\n')}\\n`\n}\n\nexport function renderAgentToolDescription(spec: IntegrationSpec): string {\n const hints = spec.plannerHints\n const useFor = hints?.useFor?.length ? `Use for ${hints.useFor.join(', ')}.` : `Use for ${spec.title} workflows.`\n const risk = hints ? `Freshness: ${hints.dataFreshness}. Write risk: ${hints.writeRisk}.` : ''\n return `${spec.title} (${spec.kind}). ${useFor} ${risk}`.trim()\n}\n\nexport function buildHealthcheckPlan(spec: IntegrationSpec): HealthcheckPlan {\n const healthcheck = spec.setup.healthcheck ?? { id: `${spec.kind}.static`, level: 'static', description: 'No healthcheck defined.' as const }\n const requires: HealthcheckPlan['requires'] = []\n if (healthcheck.level === 'connection') requires.push('connection_credentials')\n if (healthcheck.level === 'client_config' && spec.auth.mode === 'oauth2') requires.push('client_id', 'client_secret')\n if (spec.auth.mode === 'api_key') requires.push('api_key')\n if (spec.auth.mode === 'hmac') requires.push('hmac_secret')\n return {\n kind: spec.kind,\n healthcheck,\n requires,\n message: healthcheck.description,\n }\n}\n\nfunction renderTemplate(template: string, spec: IntegrationSpec, options: RenderSpecOptions, redirectUri?: string): string {\n return template\n .replaceAll('{host}', options.host)\n .replaceAll('{kind}', spec.kind)\n .replaceAll('{redirectUri}', redirectUri ?? renderRedirectUri(spec, options))\n}\n\nfunction renderRedirectUri(spec: IntegrationSpec, options: RenderSpecOptions): string {\n return (options.callbackPath ?? spec.setup.redirectUriTemplate ?? '')\n .replaceAll('{host}', options.host)\n .replaceAll('{kind}', spec.kind)\n}\n\nexport function consoleStepsToText(steps: ConsoleStep[]): string {\n return steps.map((step, index) => `${index + 1}. ${step.title}: ${step.detail}`).join('\\n')\n}\n","import type {\n CredentialFieldSpec,\n CredentialValidationResult,\n IntegrationSpec,\n IntegrationSpecValidationIssue,\n IntegrationSpecValidationResult,\n} from './types.js'\n\nexport function validateIntegrationSpec(spec: IntegrationSpec): IntegrationSpecValidationResult {\n const issues: IntegrationSpecValidationIssue[] = []\n if (!spec.kind.trim()) issues.push({ path: 'kind', message: 'kind is required' })\n if (!spec.title.trim()) issues.push({ path: 'title', message: 'title is required' })\n if (!spec.actions.length) issues.push({ path: 'actions', message: 'at least one action is required' })\n if (!spec.permissions.length) issues.push({ path: 'permissions', message: 'at least one permission is required' })\n if (spec.auth.mode === 'oauth2') {\n if (!spec.auth.authorizationUrl) issues.push({ path: 'auth.authorizationUrl', message: 'authorizationUrl is required' })\n if (!spec.auth.tokenUrl) issues.push({ path: 'auth.tokenUrl', message: 'tokenUrl is required' })\n if (!spec.auth.redirectUriTemplate) issues.push({ path: 'auth.redirectUriTemplate', message: 'redirectUriTemplate is required' })\n }\n const actionIds = new Set<string>()\n for (const [index, action] of spec.actions.entries()) {\n if (actionIds.has(action.id)) issues.push({ path: `actions[${index}].id`, message: `duplicate action id ${action.id}` })\n actionIds.add(action.id)\n }\n return { ok: issues.length === 0, issues }\n}\n\nexport function assertValidIntegrationSpec(spec: IntegrationSpec): void {\n const result = validateIntegrationSpec(spec)\n if (!result.ok) {\n throw new Error(`Invalid integration spec ${spec.kind}: ${result.issues.map((i) => `${i.path}: ${i.message}`).join('; ')}`)\n }\n}\n\nexport function validateCredentialFormat(field: CredentialFieldSpec, value: string): CredentialValidationResult {\n if (!value.trim()) return { ok: false, field: field.label, message: `${field.label} is required` }\n if (field.regex && !new RegExp(field.regex).test(value)) {\n return { ok: false, field: field.label, message: `${field.label} does not match expected format` }\n }\n return { ok: true, field: field.label }\n}\n\nexport function validateCredentialSet(spec: IntegrationSpec, values: Record<string, string>): CredentialValidationResult[] {\n return spec.setup.credentialFields.map((field) => {\n const key = field.env ?? field.label\n return validateCredentialFormat(field, values[key] ?? '')\n })\n}\n"],"mappings":"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","names":["actionPack","scope","dataClassFor"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
integrationSpecToConnector,
|
|
3
3
|
listIntegrationSpecs
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-4JQ754PA.js";
|
|
5
5
|
|
|
6
6
|
// src/index.ts
|
|
7
7
|
import { createHmac as createHmac4, randomUUID as randomUUID5, timingSafeEqual as timingSafeEqual3 } from "crypto";
|
|
@@ -240,7 +240,7 @@ function createCatalogExecutorProvider(options) {
|
|
|
240
240
|
},
|
|
241
241
|
async subscribeTrigger(connection, triggerId, targetUrl) {
|
|
242
242
|
if (!options.subscribeTrigger) {
|
|
243
|
-
throw new IntegrationError(`Provider ${options.id} does not support trigger subscriptions.`, "
|
|
243
|
+
throw new IntegrationError(`Provider ${options.id} does not support trigger subscriptions.`, "trigger_not_found");
|
|
244
244
|
}
|
|
245
245
|
const connector = byConnector.get(connection.connectorId);
|
|
246
246
|
if (!connector) {
|
|
@@ -248,7 +248,7 @@ function createCatalogExecutorProvider(options) {
|
|
|
248
248
|
}
|
|
249
249
|
const trigger2 = connector.triggers?.find((candidate) => candidate.id === triggerId);
|
|
250
250
|
if (!trigger2) {
|
|
251
|
-
throw new IntegrationError(`Trigger ${triggerId} is not defined by connector ${connector.id}.`, "
|
|
251
|
+
throw new IntegrationError(`Trigger ${triggerId} is not defined by connector ${connector.id}.`, "trigger_not_found");
|
|
252
252
|
}
|
|
253
253
|
return options.subscribeTrigger(connection, trigger2, targetUrl);
|
|
254
254
|
},
|
|
@@ -739,6 +739,38 @@ function listTangleIntegrationCatalogRuntimePackages() {
|
|
|
739
739
|
version: entry.version
|
|
740
740
|
}));
|
|
741
741
|
}
|
|
742
|
+
function buildTangleCatalogRuntimePackageManifest(options = {}) {
|
|
743
|
+
const dependencies = {};
|
|
744
|
+
if (options.includeAgentIntegrationsPackage ?? true) {
|
|
745
|
+
dependencies["@tangle-network/agent-integrations"] = options.agentIntegrationsVersion ?? "latest";
|
|
746
|
+
}
|
|
747
|
+
for (const pkg of listTangleIntegrationCatalogRuntimePackages()) {
|
|
748
|
+
dependencies[pkg.packageName] = pkg.version ?? "latest";
|
|
749
|
+
}
|
|
750
|
+
Object.assign(dependencies, options.additionalDependencies);
|
|
751
|
+
return {
|
|
752
|
+
name: options.name ?? "@tangle-network/agent-integrations-runtime-bundle",
|
|
753
|
+
private: true,
|
|
754
|
+
type: "module",
|
|
755
|
+
dependencies: Object.fromEntries(Object.entries(dependencies).sort(([a], [b]) => a.localeCompare(b))),
|
|
756
|
+
tangle: {
|
|
757
|
+
integrationContracts: listTangleIntegrationContracts().length,
|
|
758
|
+
packageRuntimeBackends: listTangleIntegrationContracts().filter((contract) => contract.implementation.kind === "package_runtime").length,
|
|
759
|
+
generatedFrom: TANGLE_INTEGRATIONS_CATALOG_SOURCE
|
|
760
|
+
}
|
|
761
|
+
};
|
|
762
|
+
}
|
|
763
|
+
function renderTangleCatalogRuntimePnpmAddCommand(options = {}) {
|
|
764
|
+
const manifest = buildTangleCatalogRuntimePackageManifest({
|
|
765
|
+
includeAgentIntegrationsPackage: options.includeAgentIntegrationsPackage,
|
|
766
|
+
agentIntegrationsVersion: options.agentIntegrationsVersion
|
|
767
|
+
});
|
|
768
|
+
return [
|
|
769
|
+
"pnpm",
|
|
770
|
+
"add",
|
|
771
|
+
...Object.entries(manifest.dependencies).map(([name, version]) => `${name}@${version}`)
|
|
772
|
+
].join(" ");
|
|
773
|
+
}
|
|
742
774
|
function buildTangleIntegrationCatalogConnectors(options = {}) {
|
|
743
775
|
const providerId = options.providerId ?? TANGLE_INTEGRATIONS_CATALOG_PROVIDER_ID;
|
|
744
776
|
return buildActivepiecesConnectors({
|
|
@@ -773,6 +805,7 @@ function createTangleCatalogExecutorProvider(options) {
|
|
|
773
805
|
catalogEntry: sanitizeEntry(importedEntry),
|
|
774
806
|
piece: {
|
|
775
807
|
id: importedEntry.id,
|
|
808
|
+
packageName: importedEntry.npmPackage,
|
|
776
809
|
version: importedEntry.version,
|
|
777
810
|
actionId: action.id,
|
|
778
811
|
upstreamActionName: catalogAction?.upstreamName
|
|
@@ -794,6 +827,7 @@ function createTangleCatalogExecutorProvider(options) {
|
|
|
794
827
|
targetUrl,
|
|
795
828
|
piece: {
|
|
796
829
|
id: importedEntry.id,
|
|
830
|
+
packageName: importedEntry.npmPackage,
|
|
797
831
|
version: importedEntry.version,
|
|
798
832
|
triggerId: trigger2.id,
|
|
799
833
|
upstreamTriggerName: catalogTrigger?.upstreamName
|
|
@@ -1679,7 +1713,7 @@ function statusForCode(code) {
|
|
|
1679
1713
|
if (code === "approval_denied") return 403;
|
|
1680
1714
|
if (code === "connection_revoked" || code === "connection_expired" || code === "provider_auth_failed") return 401;
|
|
1681
1715
|
if (code === "scope_missing" || code === "action_denied" || code === "passthrough_disabled") return 403;
|
|
1682
|
-
if (code === "action_not_found" || code === "manifest_invalid" || code === "input_invalid") return 400;
|
|
1716
|
+
if (code === "action_not_found" || code === "trigger_not_found" || code === "manifest_invalid" || code === "input_invalid") return 400;
|
|
1683
1717
|
if (code === "provider_rate_limited") return 429;
|
|
1684
1718
|
if (code === "provider_unavailable") return 503;
|
|
1685
1719
|
if (code === "capability_expired" || code === "capability_invalid") return 401;
|
|
@@ -6340,6 +6374,9 @@ function createTangleCatalogRuntimeHandler(options) {
|
|
|
6340
6374
|
const parsed = parseRuntimeRequest(serialized);
|
|
6341
6375
|
if (!parsed.ok) return parsed.response;
|
|
6342
6376
|
const request = parsed.request;
|
|
6377
|
+
if (request.providerId !== request.connection.providerId) {
|
|
6378
|
+
return errorResponse(400, request.action.id, "provider_mismatch", "Request providerId does not match connection providerId.");
|
|
6379
|
+
}
|
|
6343
6380
|
const connector = byConnector.get(request.connector.id);
|
|
6344
6381
|
if (!connector) {
|
|
6345
6382
|
return errorResponse(404, request.action.id, "connector_not_found", `Connector ${request.connector.id} is not in the Tangle catalog runtime.`);
|
|
@@ -6378,6 +6415,13 @@ function createTangleCatalogInstalledPackageExecutor(options = {}) {
|
|
|
6378
6415
|
if (!packageName) {
|
|
6379
6416
|
return runtimeFailure(invocation.action.id, "runtime_not_available", `No installed runtime package is known for connector ${invocation.connector.id}.`);
|
|
6380
6417
|
}
|
|
6418
|
+
if (invocation.request.piece.packageName && invocation.request.piece.packageName !== packageName) {
|
|
6419
|
+
return runtimeFailure(
|
|
6420
|
+
invocation.action.id,
|
|
6421
|
+
"runtime_package_mismatch",
|
|
6422
|
+
`Runtime package ${invocation.request.piece.packageName} does not match catalog package ${packageName}.`
|
|
6423
|
+
);
|
|
6424
|
+
}
|
|
6381
6425
|
const loaded = await loadRuntimeModule(packageName, options.moduleLoader, moduleCache);
|
|
6382
6426
|
if (!loaded.ok) {
|
|
6383
6427
|
return runtimeFailure(invocation.action.id, "runtime_not_installed", loaded.message);
|
|
@@ -6386,7 +6430,7 @@ function createTangleCatalogInstalledPackageExecutor(options = {}) {
|
|
|
6386
6430
|
if (!piece) {
|
|
6387
6431
|
return runtimeFailure(invocation.action.id, "runtime_invalid", `Runtime package ${packageName} does not export a recognizable piece for ${invocation.connector.id}.`);
|
|
6388
6432
|
}
|
|
6389
|
-
const action = findRuntimeAction(piece, invocation, options.actionAliases);
|
|
6433
|
+
const action = findRuntimeAction(piece, invocation, options.actionAliases, options.allowFuzzyActionMatch ?? false);
|
|
6390
6434
|
if (!action?.run) {
|
|
6391
6435
|
return runtimeFailure(invocation.action.id, "action_not_implemented", `Runtime package ${packageName} does not expose executable action ${invocation.action.id}.`);
|
|
6392
6436
|
}
|
|
@@ -6412,6 +6456,56 @@ function createTangleCatalogInstalledPackageExecutor(options = {}) {
|
|
|
6412
6456
|
}
|
|
6413
6457
|
};
|
|
6414
6458
|
}
|
|
6459
|
+
async function auditTangleCatalogRuntimePackages(options = {}) {
|
|
6460
|
+
const only = options.connectorIds ? new Set(options.connectorIds) : void 0;
|
|
6461
|
+
const rows = [];
|
|
6462
|
+
const moduleCache = /* @__PURE__ */ new Map();
|
|
6463
|
+
const entries = listActivepiecesCatalogEntries().filter((entry) => entry.npmPackage && (!only || only.has(entry.id)));
|
|
6464
|
+
for (const entry of entries) {
|
|
6465
|
+
const packageName = entry.npmPackage;
|
|
6466
|
+
const base = {
|
|
6467
|
+
connectorId: entry.id,
|
|
6468
|
+
packageName,
|
|
6469
|
+
actionMappingsTotal: entry.actions.length,
|
|
6470
|
+
triggerMappingsTotal: entry.triggers.length
|
|
6471
|
+
};
|
|
6472
|
+
const loaded = await loadRuntimeModule(packageName, options.moduleLoader, moduleCache);
|
|
6473
|
+
if (!loaded.ok) {
|
|
6474
|
+
rows.push({
|
|
6475
|
+
...base,
|
|
6476
|
+
packageInstalled: false,
|
|
6477
|
+
packageLoads: false,
|
|
6478
|
+
pieceExportFound: false,
|
|
6479
|
+
actionMappingsVerified: 0,
|
|
6480
|
+
triggerMappingsFound: 0,
|
|
6481
|
+
triggerHostingSupported: false,
|
|
6482
|
+
error: loaded.message
|
|
6483
|
+
});
|
|
6484
|
+
continue;
|
|
6485
|
+
}
|
|
6486
|
+
const piece = findPieceExport(loaded.module, entry.id);
|
|
6487
|
+
const actions = piece?.actions ?? [];
|
|
6488
|
+
const triggers = piece?.triggers ?? [];
|
|
6489
|
+
rows.push({
|
|
6490
|
+
...base,
|
|
6491
|
+
packageInstalled: true,
|
|
6492
|
+
packageLoads: true,
|
|
6493
|
+
pieceExportFound: Boolean(piece),
|
|
6494
|
+
actionMappingsVerified: entry.actions.filter((action) => hasRuntimeName(actions, [
|
|
6495
|
+
action.id,
|
|
6496
|
+
action.title,
|
|
6497
|
+
action.upstreamName
|
|
6498
|
+
])).length,
|
|
6499
|
+
triggerMappingsFound: entry.triggers.filter((trigger2) => hasRuntimeName(triggers, [
|
|
6500
|
+
trigger2.id,
|
|
6501
|
+
trigger2.title,
|
|
6502
|
+
trigger2.upstreamName
|
|
6503
|
+
])).length,
|
|
6504
|
+
triggerHostingSupported: entry.triggers.length === 0 || triggers.length > 0
|
|
6505
|
+
});
|
|
6506
|
+
}
|
|
6507
|
+
return rows;
|
|
6508
|
+
}
|
|
6415
6509
|
function createTangleCatalogCredentialAuthResolver(options) {
|
|
6416
6510
|
return async function resolveTangleCatalogAuth(connection) {
|
|
6417
6511
|
if (!connection.secretRef) return void 0;
|
|
@@ -6498,7 +6592,11 @@ function findPieceExport(moduleValue, connectorId) {
|
|
|
6498
6592
|
];
|
|
6499
6593
|
return values.find((value) => Boolean(value) && typeof value === "object" && Array.isArray(value.actions));
|
|
6500
6594
|
}
|
|
6501
|
-
function
|
|
6595
|
+
function hasRuntimeName(values, candidates) {
|
|
6596
|
+
const expected = new Set(candidates.filter((value) => Boolean(value)));
|
|
6597
|
+
return values.filter((value) => Boolean(value) && typeof value === "object").some((value) => [value.name, value.displayName].some((name) => typeof name === "string" && expected.has(name)));
|
|
6598
|
+
}
|
|
6599
|
+
function findRuntimeAction(piece, invocation, aliases = {}, allowFuzzyActionMatch = false) {
|
|
6502
6600
|
const actions = (piece.actions ?? []).filter((action) => Boolean(action) && typeof action === "object");
|
|
6503
6601
|
const explicit = aliases[invocation.connector.id]?.[invocation.action.id];
|
|
6504
6602
|
const candidates = new Set([
|
|
@@ -6510,7 +6608,7 @@ function findRuntimeAction(piece, invocation, aliases = {}) {
|
|
|
6510
6608
|
for (const action of actions) {
|
|
6511
6609
|
const names = [action.name, action.displayName].filter((value) => Boolean(value));
|
|
6512
6610
|
if (names.some((name) => candidates.has(name))) return action;
|
|
6513
|
-
if (names.some((name) => [...candidates].some((candidate) => comparable(name) === comparable(candidate)))) return action;
|
|
6611
|
+
if (allowFuzzyActionMatch && names.some((name) => [...candidates].some((candidate) => comparable(name) === comparable(candidate)))) return action;
|
|
6514
6612
|
}
|
|
6515
6613
|
return void 0;
|
|
6516
6614
|
}
|
|
@@ -7097,7 +7195,7 @@ var IntegrationHub = class {
|
|
|
7097
7195
|
const provider = this.requireProvider(connection.providerId);
|
|
7098
7196
|
const connector = await this.requireConnector(provider, connection.connectorId);
|
|
7099
7197
|
const spec = connector.triggers?.find((candidate) => candidate.id === trigger2);
|
|
7100
|
-
if (!spec) throw new IntegrationError(`Trigger ${trigger2} is not defined by connector ${connector.id}.`, "
|
|
7198
|
+
if (!spec) throw new IntegrationError(`Trigger ${trigger2} is not defined by connector ${connector.id}.`, "trigger_not_found");
|
|
7101
7199
|
assertScopes(connection, spec.requiredScopes);
|
|
7102
7200
|
if (!provider.subscribeTrigger) {
|
|
7103
7201
|
throw new IntegrationError(`Provider ${provider.id} does not support triggers.`, "auth_not_supported");
|
|
@@ -7318,6 +7416,8 @@ export {
|
|
|
7318
7416
|
listTangleIntegrationCatalogEntries,
|
|
7319
7417
|
listTangleIntegrationContracts,
|
|
7320
7418
|
listTangleIntegrationCatalogRuntimePackages,
|
|
7419
|
+
buildTangleCatalogRuntimePackageManifest,
|
|
7420
|
+
renderTangleCatalogRuntimePnpmAddCommand,
|
|
7321
7421
|
buildTangleIntegrationCatalogConnectors,
|
|
7322
7422
|
createTangleCatalogExecutorProvider,
|
|
7323
7423
|
extractExternalCatalogPublicCount,
|
|
@@ -7432,6 +7532,7 @@ export {
|
|
|
7432
7532
|
normalizeGatewayCatalog,
|
|
7433
7533
|
createTangleCatalogRuntimeHandler,
|
|
7434
7534
|
createTangleCatalogInstalledPackageExecutor,
|
|
7535
|
+
auditTangleCatalogRuntimePackages,
|
|
7435
7536
|
createTangleCatalogCredentialAuthResolver,
|
|
7436
7537
|
createTangleCatalogHttpAuthResolver,
|
|
7437
7538
|
tangleCatalogAuthValue,
|
|
@@ -7452,4 +7553,4 @@ export {
|
|
|
7452
7553
|
signCapability,
|
|
7453
7554
|
verifyCapabilityToken
|
|
7454
7555
|
};
|
|
7455
|
-
//# sourceMappingURL=chunk-
|
|
7556
|
+
//# sourceMappingURL=chunk-VJ57GPYO.js.map
|