@tangle-network/agent-integrations 0.25.1 → 0.25.3
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 +28 -5
- package/dist/bin/tangle-catalog-runtime.js +5 -1
- package/dist/bin/tangle-catalog-runtime.js.map +1 -1
- package/dist/catalog.d.ts +4 -0
- package/dist/catalog.js +15 -0
- package/dist/catalog.js.map +1 -0
- package/dist/chunk-376UBTNB.js +1 -0
- package/dist/chunk-376UBTNB.js.map +1 -0
- package/dist/chunk-6KWCC42J.js +120 -0
- package/dist/chunk-6KWCC42J.js.map +1 -0
- package/dist/chunk-FQAT4IEE.js +246 -0
- package/dist/chunk-FQAT4IEE.js.map +1 -0
- package/dist/chunk-IDX3KIPA.js +3233 -0
- package/dist/chunk-IDX3KIPA.js.map +1 -0
- package/dist/{chunk-VJ57GPYO.js → chunk-MU3UTIOX.js} +3234 -6787
- package/dist/chunk-MU3UTIOX.js.map +1 -0
- package/dist/connectors/adapters/index.d.ts +1 -0
- package/dist/connectors/adapters/index.js +39 -0
- package/dist/connectors/adapters/index.js.map +1 -0
- package/dist/connectors/index.d.ts +180 -0
- package/dist/connectors/index.js +74 -0
- package/dist/connectors/index.js.map +1 -0
- package/dist/index-BNb1A0Id.d.ts +810 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.js +51 -44
- package/dist/registry.d.ts +1982 -0
- package/dist/registry.js +20 -0
- package/dist/registry.js.map +1 -0
- package/dist/runtime.d.ts +4 -0
- package/dist/runtime.js +12 -0
- package/dist/runtime.js.map +1 -0
- package/dist/specs.d.ts +4 -2962
- package/dist/tangle-catalog-runtime.d.ts +4 -0
- package/dist/tangle-catalog-runtime.js +22 -0
- package/dist/tangle-catalog-runtime.js.map +1 -0
- package/docs/adapter-triage.md +1 -1
- package/docs/platform-control-plane.md +54 -0
- package/docs/product-hub-ownership.md +126 -0
- package/docs/production-completion-checklist.md +2 -0
- package/docs/provider-decision-matrix.md +3 -3
- package/examples/calendar-exercise-app.ts +3 -3
- package/package.json +40 -12
- package/dist/chunk-VJ57GPYO.js.map +0 -1
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { T as TangleCatalogAuthResolverOptions, w as TangleCatalogHttpAuthResolverOptions, x as TangleCatalogHttpAuthResolverRequest, y as TangleCatalogInstalledPackageExecutorOptions, z as TangleCatalogRuntimeHandlerOptions, A as TangleCatalogRuntimeHttpRequest, B as TangleCatalogRuntimeHttpResponse, C as TangleCatalogRuntimeInvocation, D as TangleCatalogRuntimeModuleAction, E as TangleCatalogRuntimePackageCoverageOptions, F as TangleCatalogRuntimePackageCoverageRow, G as auditTangleCatalogRuntimePackages, H as createTangleCatalogCredentialAuthResolver, J as createTangleCatalogHttpAuthResolver, K as createTangleCatalogInstalledPackageExecutor, L as createTangleCatalogRuntimeHandler, N as tangleCatalogAuthValue } from './registry.js';
|
|
2
|
+
import './index-BNb1A0Id.js';
|
|
3
|
+
import './connectors/index.js';
|
|
4
|
+
import 'node:http';
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import {
|
|
2
|
+
auditTangleCatalogRuntimePackages,
|
|
3
|
+
createTangleCatalogCredentialAuthResolver,
|
|
4
|
+
createTangleCatalogHttpAuthResolver,
|
|
5
|
+
createTangleCatalogInstalledPackageExecutor,
|
|
6
|
+
createTangleCatalogRuntimeHandler,
|
|
7
|
+
tangleCatalogAuthValue
|
|
8
|
+
} from "./chunk-MU3UTIOX.js";
|
|
9
|
+
import "./chunk-FQAT4IEE.js";
|
|
10
|
+
import "./chunk-6KWCC42J.js";
|
|
11
|
+
import "./chunk-4JQ754PA.js";
|
|
12
|
+
import "./chunk-376UBTNB.js";
|
|
13
|
+
import "./chunk-IDX3KIPA.js";
|
|
14
|
+
export {
|
|
15
|
+
auditTangleCatalogRuntimePackages,
|
|
16
|
+
createTangleCatalogCredentialAuthResolver,
|
|
17
|
+
createTangleCatalogHttpAuthResolver,
|
|
18
|
+
createTangleCatalogInstalledPackageExecutor,
|
|
19
|
+
createTangleCatalogRuntimeHandler,
|
|
20
|
+
tangleCatalogAuthValue
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=tangle-catalog-runtime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/docs/adapter-triage.md
CHANGED
|
@@ -63,7 +63,7 @@ import {
|
|
|
63
63
|
|
|
64
64
|
const provider = createTangleCatalogExecutorProvider({
|
|
65
65
|
executeAction: createTangleCatalogHttpExecutor({
|
|
66
|
-
endpoint: 'https://
|
|
66
|
+
endpoint: 'https://integrations.example.com/integration-runtime',
|
|
67
67
|
secret: process.env.TANGLE_CATALOG_RUNTIME_SECRET,
|
|
68
68
|
}),
|
|
69
69
|
})
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Platform Control Plane Adoption
|
|
2
|
+
|
|
3
|
+
Use this package when one product owns user connections and many runtimes need
|
|
4
|
+
safe access to those connections.
|
|
5
|
+
|
|
6
|
+
```txt
|
|
7
|
+
central platform
|
|
8
|
+
owns OAuth apps, connection storage, grants, approvals, audit, healthchecks
|
|
9
|
+
|
|
10
|
+
sandbox / generated app / agent runtime
|
|
11
|
+
receives a short-lived capability bundle
|
|
12
|
+
calls /v1/integrations/invoke
|
|
13
|
+
never receives provider refresh tokens or API keys
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Required Flow
|
|
17
|
+
|
|
18
|
+
1. Product code turns app requirements into an `IntegrationManifest`.
|
|
19
|
+
2. Platform resolves the manifest against the user's active connections.
|
|
20
|
+
3. Missing connections or scopes return a user-facing connect/consent action.
|
|
21
|
+
4. Platform creates `IntegrationGrant` records for the approved grantee.
|
|
22
|
+
5. Platform issues a short-lived bundle with `buildSandboxBundle()`.
|
|
23
|
+
6. Runtime receives only `TANGLE_INTEGRATION_BUNDLE`.
|
|
24
|
+
7. Generated app code calls `createTangleIntegrationsClient()`.
|
|
25
|
+
8. Platform verifies capability, policy, approval, idempotency, and audit before
|
|
26
|
+
invoking the provider.
|
|
27
|
+
|
|
28
|
+
## Durable Installs
|
|
29
|
+
|
|
30
|
+
Preview runs can build bundles by `manifestId` and `grantee`. Installed apps and
|
|
31
|
+
published templates often need a narrower path: bind one app instance to known
|
|
32
|
+
pre-created grants. Use explicit grant ids:
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
const bundle = await runtime.buildSandboxBundle({
|
|
36
|
+
grantIds: ['grant_calendar_read'],
|
|
37
|
+
subject: { type: 'sandbox', id: 'sandbox_123' },
|
|
38
|
+
grantee: { type: 'app', id: 'installed_app_123' },
|
|
39
|
+
ttlMs: 15 * 60_000,
|
|
40
|
+
})
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
The runtime fails closed if a grant id is unknown, belongs to another grantee, or
|
|
44
|
+
belongs to a different manifest than the requested `manifestId`.
|
|
45
|
+
|
|
46
|
+
## Production Gates
|
|
47
|
+
|
|
48
|
+
- Catalog-only connectors are discoverable, not executable.
|
|
49
|
+
- Runtime code receives capability tokens only.
|
|
50
|
+
- Writes require approval unless product policy explicitly allows them.
|
|
51
|
+
- Destructive actions are denied by default.
|
|
52
|
+
- Every invoke has an audit event and an idempotency key.
|
|
53
|
+
- Revoke deletes credentials and stops future bundles from including the grant.
|
|
54
|
+
- Resume/long-running runtimes refresh bundles before expiry.
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# Integration Hub Ownership
|
|
2
|
+
|
|
3
|
+
Status: deployment guidance
|
|
4
|
+
|
|
5
|
+
This document describes where integration custody should live when a product
|
|
6
|
+
uses `@tangle-network/agent-integrations`.
|
|
7
|
+
|
|
8
|
+
## Decision
|
|
9
|
+
|
|
10
|
+
Use one contract everywhere, not one deployment everywhere.
|
|
11
|
+
|
|
12
|
+
- Products that share identity, billing, and consent can use a hosted platform
|
|
13
|
+
hub.
|
|
14
|
+
- Standalone products can run a product-owned hub.
|
|
15
|
+
- Both modes must use `@tangle-network/agent-integrations` contracts:
|
|
16
|
+
`IntegrationSpec`, `IntegrationManifest`, `IntegrationGrant`, capability
|
|
17
|
+
bundles, `/v1/integrations/invoke`, approvals, healthchecks, audit, webhooks,
|
|
18
|
+
and provider/runtime adapters.
|
|
19
|
+
- Product-owned hubs may federate to a hosted platform hub when the deployment
|
|
20
|
+
wants a shared connection wallet.
|
|
21
|
+
|
|
22
|
+
The package defines the shared protocol. Each deployment decides where to store
|
|
23
|
+
connections, secrets, grants, approvals, audit records, and workflow state.
|
|
24
|
+
|
|
25
|
+
## Ownership Modes
|
|
26
|
+
|
|
27
|
+
| Mode | Use When | Owns OAuth, Vault, Audit | Invocation Path |
|
|
28
|
+
|---|---|---:|---|
|
|
29
|
+
| Hosted platform hub | Multiple apps share account, consent, billing, and connection custody | Platform service | App/sandbox calls platform hub or product proxy with scoped capability |
|
|
30
|
+
| Product-owned hub | Standalone SaaS, private deployment, or customer-owned data boundary | Product app | App/sandbox calls product `/v1/integrations/invoke` |
|
|
31
|
+
| Federated product hub | Product wants local policy with remote connection custody | Product policy + hosted custody | Product issues local grants over remote platform connections |
|
|
32
|
+
|
|
33
|
+
The important invariant: sandboxes and generated apps never receive provider
|
|
34
|
+
refresh tokens, API keys, or raw OAuth credentials in any mode.
|
|
35
|
+
|
|
36
|
+
## Where Duplication Is Bad
|
|
37
|
+
|
|
38
|
+
Fully duplicating hubs is bad when apps are intentionally part of the same
|
|
39
|
+
account system:
|
|
40
|
+
|
|
41
|
+
- Users reconnect Gmail, Slack, GitHub, and Drive in every app.
|
|
42
|
+
- OAuth app verification, scopes, redirect configuration, and consent review
|
|
43
|
+
are repeated.
|
|
44
|
+
- Revocation, audit, healthchecks, and billing attribution fragment.
|
|
45
|
+
- Generated apps cannot inherit a user's already-approved connection.
|
|
46
|
+
|
|
47
|
+
For those deployments, use a hosted hub as the connection source of truth and
|
|
48
|
+
pass scoped grants down to apps, sandboxes, and agents.
|
|
49
|
+
|
|
50
|
+
## Where Centralization Is Bad
|
|
51
|
+
|
|
52
|
+
Forcing every deployment through a hosted platform hub is bad when the product
|
|
53
|
+
needs a separate customer, compliance, or operational boundary:
|
|
54
|
+
|
|
55
|
+
- The buyer may not want shared identity or billing in their end-user flow.
|
|
56
|
+
- Enterprise deployments may require product-branded OAuth apps, product-owned
|
|
57
|
+
vaults, customer-managed keys, private networking, or data residency.
|
|
58
|
+
- Product-specific subscriptions and compliance boundaries may not match the
|
|
59
|
+
platform account model.
|
|
60
|
+
- A central platform outage should not necessarily take down a standalone app.
|
|
61
|
+
|
|
62
|
+
For those products, run a product-owned hub using the same package contracts.
|
|
63
|
+
Optionally add federation to a hosted platform hub as a deployment choice.
|
|
64
|
+
|
|
65
|
+
## Execution Checklist
|
|
66
|
+
|
|
67
|
+
- [x] One stable contract for specs, manifests, grants, capabilities, invocation,
|
|
68
|
+
approvals, healthchecks, webhooks, audit, and bridge payloads.
|
|
69
|
+
- [x] Long-tail connector contracts and runtime-backed execution path are
|
|
70
|
+
represented without leaking external catalog names into product UX.
|
|
71
|
+
- [x] External product adoption guide documents product-owned deployment.
|
|
72
|
+
- [x] This ownership decision documents platform versus product-owned custody.
|
|
73
|
+
|
|
74
|
+
### Hosted Hub Bar
|
|
75
|
+
|
|
76
|
+
- [ ] The hosted hub has production stores for connections, grants, approvals,
|
|
77
|
+
audit, healthchecks, workflows, webhook events, and idempotency.
|
|
78
|
+
- [ ] The hosted hub vault/KMS stores raw OAuth/API-key credentials behind
|
|
79
|
+
secret refs.
|
|
80
|
+
- [ ] The hosted hub exposes connect, callback, revoke, rotate, approve, audit,
|
|
81
|
+
healthcheck, and `/v1/integrations/invoke`.
|
|
82
|
+
- [ ] Sandbox and generated-app launches receive
|
|
83
|
+
`buildIntegrationBridgeEnvironment()` output.
|
|
84
|
+
- [ ] Browser E2E covers connect, consent, preview, invoke read, approval write,
|
|
85
|
+
revoke, expired token recovery, and missing-connection recovery.
|
|
86
|
+
|
|
87
|
+
### Product-Owned Hub Bar
|
|
88
|
+
|
|
89
|
+
- [ ] The product chooses local hub or federated platform hub per deployment.
|
|
90
|
+
- [ ] Local hubs use `IntegrationHub`; custom provider switch statements are
|
|
91
|
+
removed or wrapped as `IntegrationProvider` implementations.
|
|
92
|
+
- [ ] The product stores connections, grants, approvals, audit, healthchecks,
|
|
93
|
+
workflows, events, and idempotency in its own database.
|
|
94
|
+
- [ ] The product uses its own vault/KMS or explicitly delegates secret custody
|
|
95
|
+
to a hosted hub.
|
|
96
|
+
- [ ] The product has live OAuth/API-key setup UI generated from
|
|
97
|
+
`IntegrationSpec`.
|
|
98
|
+
- [ ] The product has browser E2E personas using real product UX and live
|
|
99
|
+
integration secrets where available.
|
|
100
|
+
|
|
101
|
+
## Product E2E Gates
|
|
102
|
+
|
|
103
|
+
Run these before launch for every product adopting integrations:
|
|
104
|
+
|
|
105
|
+
1. Existing connection: user asks for a task requiring Gmail, Calendar, Slack,
|
|
106
|
+
GitHub, Drive, Sheets, or CRM data; agent detects the existing connection and
|
|
107
|
+
uses it without asking for manual copy/paste.
|
|
108
|
+
2. Missing connection: user asks for the same task without a connection; product
|
|
109
|
+
renders connect/consent in flow, resumes the task after OAuth, and does not
|
|
110
|
+
lose conversation state.
|
|
111
|
+
3. Generated app preview: generated software declares an
|
|
112
|
+
`IntegrationManifest`; preview requests user consent, receives scoped
|
|
113
|
+
capabilities, and reads provider data through the invoke endpoint.
|
|
114
|
+
4. Write approval: generated app or agent proposes a write/send/update action;
|
|
115
|
+
product requires approval, records audit, and executes once with idempotency.
|
|
116
|
+
5. Revocation: user revokes a connection; existing grants fail closed and the UI
|
|
117
|
+
explains how to reconnect.
|
|
118
|
+
6. Healthcheck failure: expired or revoked upstream credentials surface in admin
|
|
119
|
+
UI and task UX without exposing secrets in logs or traces.
|
|
120
|
+
|
|
121
|
+
## Recommendation
|
|
122
|
+
|
|
123
|
+
Do not fork integration semantics by product. Make hub custody a deployment
|
|
124
|
+
choice while keeping the protocol stable. Hosted hubs, product-owned hubs, and
|
|
125
|
+
federated hubs should all expose the same manifest, grant, capability, approval,
|
|
126
|
+
audit, webhook, and invocation shapes.
|
|
@@ -20,6 +20,8 @@ provider credentials.
|
|
|
20
20
|
- [x] Persistent grants from user-owned connections to apps, agents, sandboxes,
|
|
21
21
|
and generated software.
|
|
22
22
|
- [x] Sandbox bundles with short-lived capability tokens and tool definitions.
|
|
23
|
+
- [x] Explicit grant-id bundle issuance for installed apps, published templates,
|
|
24
|
+
and durable app instances.
|
|
23
25
|
- [x] Bridge payload/env helpers for sandbox processes and executor-style CLIs.
|
|
24
26
|
- [x] Sandbox invocation host that validates envelopes before hub invocation and
|
|
25
27
|
normalizes success, failure, and approval-required results.
|
|
@@ -74,9 +74,9 @@ Use gateway-backed coverage for the next large tranche:
|
|
|
74
74
|
- long-tail CRM/support/helpdesk systems
|
|
75
75
|
- vendor-specific workflow triggers
|
|
76
76
|
|
|
77
|
-
This gives
|
|
78
|
-
hundreds of OAuth apps, refresh-token edge cases, webhook subscription
|
|
79
|
-
rate-limit policies, and provider-specific APIs on day one.
|
|
77
|
+
This gives products useful breadth immediately without forcing every team to
|
|
78
|
+
own hundreds of OAuth apps, refresh-token edge cases, webhook subscription
|
|
79
|
+
models, rate-limit policies, and provider-specific APIs on day one.
|
|
80
80
|
|
|
81
81
|
## When To Roll Our Own
|
|
82
82
|
|
|
@@ -12,8 +12,8 @@ const consent = renderConsentSummary(manifest, { appName: 'Exercise Planner' })
|
|
|
12
12
|
|
|
13
13
|
console.log(consent.body)
|
|
14
14
|
|
|
15
|
-
// In production this bundle comes from
|
|
16
|
-
// the generated app access to their Google Calendar connection.
|
|
15
|
+
// In production this bundle comes from the product integration hub after the
|
|
16
|
+
// user grants the generated app access to their Google Calendar connection.
|
|
17
17
|
const bundle: IntegrationSandboxBundle = {
|
|
18
18
|
manifestId: manifest.id,
|
|
19
19
|
subject: { type: 'sandbox', id: 'sandbox_preview_1' },
|
|
@@ -64,7 +64,7 @@ const bundle: IntegrationSandboxBundle = {
|
|
|
64
64
|
|
|
65
65
|
const env = buildIntegrationBridgeEnvironment(bundle)
|
|
66
66
|
const client = createTangleIntegrationsClient({
|
|
67
|
-
endpoint: 'https://
|
|
67
|
+
endpoint: 'https://integrations.example.com',
|
|
68
68
|
env,
|
|
69
69
|
})
|
|
70
70
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tangle-network/agent-integrations",
|
|
3
|
-
"version": "0.25.
|
|
3
|
+
"version": "0.25.3",
|
|
4
4
|
"description": "Vendor-neutral integration contracts and runtime helpers for sandbox and agent apps.",
|
|
5
5
|
"homepage": "https://github.com/tangle-network/agent-integrations#readme",
|
|
6
6
|
"repository": {
|
|
@@ -19,10 +19,40 @@
|
|
|
19
19
|
"import": "./dist/index.js",
|
|
20
20
|
"default": "./dist/index.js"
|
|
21
21
|
},
|
|
22
|
+
"./catalog": {
|
|
23
|
+
"types": "./dist/catalog.d.ts",
|
|
24
|
+
"import": "./dist/catalog.js",
|
|
25
|
+
"default": "./dist/catalog.js"
|
|
26
|
+
},
|
|
27
|
+
"./connectors": {
|
|
28
|
+
"types": "./dist/connectors/index.d.ts",
|
|
29
|
+
"import": "./dist/connectors/index.js",
|
|
30
|
+
"default": "./dist/connectors/index.js"
|
|
31
|
+
},
|
|
32
|
+
"./connectors/adapters": {
|
|
33
|
+
"types": "./dist/connectors/adapters/index.d.ts",
|
|
34
|
+
"import": "./dist/connectors/adapters/index.js",
|
|
35
|
+
"default": "./dist/connectors/adapters/index.js"
|
|
36
|
+
},
|
|
37
|
+
"./registry": {
|
|
38
|
+
"types": "./dist/registry.d.ts",
|
|
39
|
+
"import": "./dist/registry.js",
|
|
40
|
+
"default": "./dist/registry.js"
|
|
41
|
+
},
|
|
42
|
+
"./runtime": {
|
|
43
|
+
"types": "./dist/runtime.d.ts",
|
|
44
|
+
"import": "./dist/runtime.js",
|
|
45
|
+
"default": "./dist/runtime.js"
|
|
46
|
+
},
|
|
22
47
|
"./specs": {
|
|
23
48
|
"types": "./dist/specs.d.ts",
|
|
24
49
|
"import": "./dist/specs.js",
|
|
25
50
|
"default": "./dist/specs.js"
|
|
51
|
+
},
|
|
52
|
+
"./tangle-catalog-runtime": {
|
|
53
|
+
"types": "./dist/tangle-catalog-runtime.d.ts",
|
|
54
|
+
"import": "./dist/tangle-catalog-runtime.js",
|
|
55
|
+
"default": "./dist/tangle-catalog-runtime.js"
|
|
26
56
|
}
|
|
27
57
|
},
|
|
28
58
|
"bin": {
|
|
@@ -38,15 +68,6 @@
|
|
|
38
68
|
"publishConfig": {
|
|
39
69
|
"access": "public"
|
|
40
70
|
},
|
|
41
|
-
"scripts": {
|
|
42
|
-
"build": "tsup",
|
|
43
|
-
"dev": "tsup --watch",
|
|
44
|
-
"audit:execution": "pnpm build >/dev/null && node scripts/audit-integration-execution.mjs",
|
|
45
|
-
"prepare": "tsup",
|
|
46
|
-
"test": "vitest run",
|
|
47
|
-
"test:watch": "vitest",
|
|
48
|
-
"typecheck": "tsc --noEmit"
|
|
49
|
-
},
|
|
50
71
|
"devDependencies": {
|
|
51
72
|
"@types/node": "^25.6.0",
|
|
52
73
|
"tsup": "^8.0.0",
|
|
@@ -57,5 +78,12 @@
|
|
|
57
78
|
"node": ">=20"
|
|
58
79
|
},
|
|
59
80
|
"license": "MIT",
|
|
60
|
-
"
|
|
61
|
-
|
|
81
|
+
"scripts": {
|
|
82
|
+
"build": "tsup",
|
|
83
|
+
"dev": "tsup --watch",
|
|
84
|
+
"audit:execution": "pnpm build >/dev/null && node scripts/audit-integration-execution.mjs",
|
|
85
|
+
"test": "vitest run",
|
|
86
|
+
"test:watch": "vitest",
|
|
87
|
+
"typecheck": "tsc --noEmit"
|
|
88
|
+
}
|
|
89
|
+
}
|