@every-app/sdk 0.1.14 → 0.3.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (167) hide show
  1. package/README.md +608 -2
  2. package/dist/cloudflare/index.d.ts +21 -1
  3. package/dist/cloudflare/index.d.ts.map +1 -1
  4. package/dist/cloudflare/index.js +21 -1
  5. package/dist/cloudflare/sentinel.d.ts +69 -0
  6. package/dist/cloudflare/sentinel.d.ts.map +1 -0
  7. package/dist/cloudflare/sentinel.js +50 -0
  8. package/dist/cloudflare/worker.d.ts +511 -0
  9. package/dist/cloudflare/worker.d.ts.map +1 -0
  10. package/dist/cloudflare/worker.js +738 -0
  11. package/dist/dev/index.d.ts +8 -0
  12. package/dist/dev/index.d.ts.map +1 -0
  13. package/dist/dev/index.js +7 -0
  14. package/dist/dev/keypair.d.ts +24 -0
  15. package/dist/dev/keypair.d.ts.map +1 -0
  16. package/dist/dev/keypair.js +60 -0
  17. package/dist/internal/aiProviders.d.ts +67 -0
  18. package/dist/internal/aiProviders.d.ts.map +1 -0
  19. package/dist/internal/aiProviders.js +220 -0
  20. package/dist/internal/appSettings.d.ts +237 -0
  21. package/dist/internal/appSettings.d.ts.map +1 -0
  22. package/dist/internal/appSettings.js +374 -0
  23. package/dist/internal/capabilities.d.ts +1344 -0
  24. package/dist/internal/capabilities.d.ts.map +1 -0
  25. package/dist/internal/capabilities.js +1521 -0
  26. package/dist/internal/devProviders.d.ts +49 -0
  27. package/dist/internal/devProviders.d.ts.map +1 -0
  28. package/dist/internal/devProviders.js +62 -0
  29. package/dist/internal/email.d.ts +280 -0
  30. package/dist/internal/email.d.ts.map +1 -0
  31. package/dist/internal/email.js +613 -0
  32. package/dist/internal/events.d.ts +182 -0
  33. package/dist/internal/events.d.ts.map +1 -0
  34. package/dist/internal/events.js +324 -0
  35. package/dist/internal/gatewaySettings.d.ts +82 -0
  36. package/dist/internal/gatewaySettings.d.ts.map +1 -0
  37. package/dist/internal/gatewaySettings.js +209 -0
  38. package/dist/internal/identity.d.ts +88 -0
  39. package/dist/internal/identity.d.ts.map +1 -0
  40. package/dist/internal/identity.js +231 -0
  41. package/dist/internal/index.d.ts +19 -0
  42. package/dist/internal/index.d.ts.map +1 -0
  43. package/dist/internal/index.js +18 -0
  44. package/dist/internal/members.d.ts +35 -0
  45. package/dist/internal/members.d.ts.map +1 -0
  46. package/dist/internal/members.js +7 -0
  47. package/dist/internal/oauthClient.d.ts +63 -0
  48. package/dist/internal/oauthClient.d.ts.map +1 -0
  49. package/dist/internal/oauthClient.js +194 -0
  50. package/dist/internal/oauthScopes.d.ts +117 -0
  51. package/dist/internal/oauthScopes.d.ts.map +1 -0
  52. package/dist/internal/oauthScopes.js +416 -0
  53. package/dist/internal/organizationName.d.ts +18 -0
  54. package/dist/internal/organizationName.d.ts.map +1 -0
  55. package/dist/internal/organizationName.js +24 -0
  56. package/dist/internal/protocol.d.ts +195 -0
  57. package/dist/internal/protocol.d.ts.map +1 -0
  58. package/dist/internal/protocol.js +250 -0
  59. package/dist/internal/providerApps.d.ts +75 -0
  60. package/dist/internal/providerApps.d.ts.map +1 -0
  61. package/dist/internal/providerApps.js +59 -0
  62. package/dist/internal/providerRegistry.d.ts +147 -0
  63. package/dist/internal/providerRegistry.d.ts.map +1 -0
  64. package/dist/internal/providerRegistry.js +262 -0
  65. package/dist/internal/providerSpec.d.ts +55 -0
  66. package/dist/internal/providerSpec.d.ts.map +1 -0
  67. package/dist/internal/providerSpec.js +746 -0
  68. package/dist/internal/remoteMcp.d.ts +188 -0
  69. package/dist/internal/remoteMcp.d.ts.map +1 -0
  70. package/dist/internal/remoteMcp.js +543 -0
  71. package/dist/internal/tools.d.ts +115 -0
  72. package/dist/internal/tools.d.ts.map +1 -0
  73. package/dist/internal/tools.js +80 -0
  74. package/dist/server/attribution.d.ts +39 -0
  75. package/dist/server/attribution.d.ts.map +1 -0
  76. package/dist/server/attribution.js +67 -0
  77. package/dist/server/authorizeUrl.d.ts +43 -0
  78. package/dist/server/authorizeUrl.d.ts.map +1 -0
  79. package/dist/server/authorizeUrl.js +110 -0
  80. package/dist/server/emit.d.ts +63 -0
  81. package/dist/server/emit.d.ts.map +1 -0
  82. package/dist/server/emit.js +101 -0
  83. package/dist/server/everyApp.d.ts +81 -0
  84. package/dist/server/everyApp.d.ts.map +1 -0
  85. package/dist/server/everyApp.js +185 -0
  86. package/dist/server/gatewayFetch.d.ts +37 -0
  87. package/dist/server/gatewayFetch.d.ts.map +1 -0
  88. package/dist/server/gatewayFetch.js +115 -0
  89. package/dist/server/index.d.ts +18 -0
  90. package/dist/server/index.d.ts.map +1 -0
  91. package/dist/server/index.js +15 -0
  92. package/dist/server/integrationFetch.d.ts +131 -0
  93. package/dist/server/integrationFetch.d.ts.map +1 -0
  94. package/dist/server/integrationFetch.js +526 -0
  95. package/dist/server/listMembers.d.ts +32 -0
  96. package/dist/server/listMembers.d.ts.map +1 -0
  97. package/dist/server/listMembers.js +74 -0
  98. package/dist/server/nodeServer.d.ts +48 -0
  99. package/dist/server/nodeServer.d.ts.map +1 -0
  100. package/dist/server/nodeServer.js +45 -0
  101. package/dist/server/sendEmail.d.ts +39 -0
  102. package/dist/server/sendEmail.d.ts.map +1 -0
  103. package/dist/server/sendEmail.js +114 -0
  104. package/dist/server/tools.d.ts +184 -0
  105. package/dist/server/tools.d.ts.map +1 -0
  106. package/dist/server/tools.js +347 -0
  107. package/dist/server/toolsEndpoint.d.ts +32 -0
  108. package/dist/server/toolsEndpoint.d.ts.map +1 -0
  109. package/dist/server/toolsEndpoint.js +231 -0
  110. package/package.json +21 -31
  111. package/dist/cloudflare/getLocalD1Url.d.ts +0 -2
  112. package/dist/cloudflare/getLocalD1Url.d.ts.map +0 -1
  113. package/dist/cloudflare/getLocalD1Url.js +0 -40
  114. package/dist/cloudflare/lazyInit.d.ts +0 -22
  115. package/dist/cloudflare/lazyInit.d.ts.map +0 -1
  116. package/dist/cloudflare/lazyInit.js +0 -65
  117. package/dist/cloudflare/server/gateway.d.ts +0 -29
  118. package/dist/cloudflare/server/gateway.d.ts.map +0 -1
  119. package/dist/cloudflare/server/gateway.js +0 -69
  120. package/dist/cloudflare/server/index.d.ts +0 -3
  121. package/dist/cloudflare/server/index.d.ts.map +0 -1
  122. package/dist/cloudflare/server/index.js +0 -2
  123. package/dist/core/authenticatedFetch.d.ts +0 -9
  124. package/dist/core/authenticatedFetch.d.ts.map +0 -1
  125. package/dist/core/authenticatedFetch.js +0 -31
  126. package/dist/core/index.d.ts +0 -4
  127. package/dist/core/index.d.ts.map +0 -1
  128. package/dist/core/index.js +0 -2
  129. package/dist/core/sessionManager.d.ts +0 -58
  130. package/dist/core/sessionManager.d.ts.map +0 -1
  131. package/dist/core/sessionManager.js +0 -357
  132. package/dist/shared/bypassGatewayLocalOnly.d.ts +0 -15
  133. package/dist/shared/bypassGatewayLocalOnly.d.ts.map +0 -1
  134. package/dist/shared/bypassGatewayLocalOnly.js +0 -45
  135. package/dist/shared/parseMessagePayload.d.ts +0 -3
  136. package/dist/shared/parseMessagePayload.d.ts.map +0 -1
  137. package/dist/shared/parseMessagePayload.js +0 -18
  138. package/dist/tanstack/EmbeddedAppProvider.d.ts +0 -30
  139. package/dist/tanstack/EmbeddedAppProvider.d.ts.map +0 -1
  140. package/dist/tanstack/EmbeddedAppProvider.js +0 -57
  141. package/dist/tanstack/GatewayRequiredError.d.ts +0 -20
  142. package/dist/tanstack/GatewayRequiredError.d.ts.map +0 -1
  143. package/dist/tanstack/GatewayRequiredError.js +0 -91
  144. package/dist/tanstack/_internal/useEveryAppSession.d.ts +0 -18
  145. package/dist/tanstack/_internal/useEveryAppSession.d.ts.map +0 -1
  146. package/dist/tanstack/_internal/useEveryAppSession.js +0 -47
  147. package/dist/tanstack/index.d.ts +0 -4
  148. package/dist/tanstack/index.d.ts.map +0 -1
  149. package/dist/tanstack/index.js +0 -3
  150. package/dist/tanstack/server/authConfig.d.ts +0 -3
  151. package/dist/tanstack/server/authConfig.d.ts.map +0 -1
  152. package/dist/tanstack/server/authConfig.js +0 -13
  153. package/dist/tanstack/server/authenticateRequest.d.ts +0 -31
  154. package/dist/tanstack/server/authenticateRequest.d.ts.map +0 -1
  155. package/dist/tanstack/server/authenticateRequest.js +0 -154
  156. package/dist/tanstack/server/index.d.ts +0 -4
  157. package/dist/tanstack/server/index.d.ts.map +0 -1
  158. package/dist/tanstack/server/index.js +0 -2
  159. package/dist/tanstack/server/types.d.ts +0 -5
  160. package/dist/tanstack/server/types.d.ts.map +0 -1
  161. package/dist/tanstack/server/types.js +0 -1
  162. package/dist/tanstack/useEveryAppRouter.d.ts +0 -7
  163. package/dist/tanstack/useEveryAppRouter.d.ts.map +0 -1
  164. package/dist/tanstack/useEveryAppRouter.js +0 -66
  165. package/dist/tanstack/useSessionTokenClientMiddleware.d.ts +0 -2
  166. package/dist/tanstack/useSessionTokenClientMiddleware.d.ts.map +0 -1
  167. package/dist/tanstack/useSessionTokenClientMiddleware.js +0 -29
@@ -0,0 +1,209 @@
1
+ /**
2
+ * The Gateway's settings and the app's own secrets, by name: the Gateway
3
+ * settings an operator changes with `everyapp secret set <NAME>` (plain
4
+ * secrets on the Gateway Worker, read on its next request), the ones the
5
+ * install writes once, and the names an app's own secret can never take.
6
+ * What an app's manifest needs of them is appSettings.ts. One registry serves
7
+ * the CLI (a Gateway name goes to the Gateway, any other to the app in the
8
+ * current directory), the manifest validator (an app's `secrets` may not
9
+ * take a Gateway name, since the app reaches those through `providers` and
10
+ * `capabilities`) and the Gateway's dev config, which a test keeps
11
+ * declaring every settable one.
12
+ */
13
+ import { CAPABILITIES, CAPABILITY_IDS, capabilitySettings, } from "./capabilities.js";
14
+ /**
15
+ * The Gateway's own settings: the install writes them once (`everyapp
16
+ * setup`), or an operator by hand (THIRD_PARTY_DEPLOYS), and `everyapp
17
+ * secret set` never changes them. An app's own Worker may still have a
18
+ * secret of the same name (OpenSEO's BETTER_AUTH_SECRET): the two never meet.
19
+ */
20
+ export const INSTALL_OWNED_GATEWAY_SETTINGS = [
21
+ "GATEWAY_URL",
22
+ "APP_BASE_DOMAIN",
23
+ "BETTER_AUTH_SECRET",
24
+ "JWT_PRIVATE_KEY",
25
+ "JWT_PUBLIC_KEY",
26
+ "GATEWAY_DEPLOYMENT_MODE",
27
+ "CLOUDFLARE_ACCOUNT_ID",
28
+ "THIRD_PARTY_DEPLOYS",
29
+ ];
30
+ const INSTALL_OWNED = new Set(INSTALL_OWNED_GATEWAY_SETTINGS);
31
+ export function isInstallOwnedGatewaySetting(name) {
32
+ return INSTALL_OWNED.has(name);
33
+ }
34
+ /**
35
+ * The settings the catalog's providers read (the AI providers' keys, the
36
+ * API-key providers' keys, the OAuth clients and the Mastodon instance's
37
+ * URL), in catalog order, the install's own left out: what `everyapp
38
+ * secret set` accepts because a provider reads it. A gateway's registered
39
+ * rows add theirs at run time (providerRegistry.settingNames()).
40
+ */
41
+ const PROVIDER_GATEWAY_SETTINGS = [
42
+ ...new Set(CAPABILITY_IDS.flatMap((id) => {
43
+ const capability = CAPABILITIES[id];
44
+ return capability.mode === "service"
45
+ ? []
46
+ : capabilitySettings(capability);
47
+ })),
48
+ ].filter((name) => !INSTALL_OWNED.has(name));
49
+ /** The Gateway's own optional settings `everyapp secret set` changes: nothing a provider reads. */
50
+ export const GATEWAY_OWN_SETTINGS = [
51
+ "AI_PROXY_EXTRA_ROUTES",
52
+ // Email's providers: Cloudflare's REST token, Resend's key, the choice.
53
+ "EMAIL_REST_API_TOKEN",
54
+ "RESEND_API_KEY",
55
+ "EMAIL_PROVIDER",
56
+ "EMAIL_FROM",
57
+ "EMAIL_FROM_NAME",
58
+ "MCP_OAUTH_ENABLED",
59
+ "MCP_DCR_ENABLED",
60
+ "MCP_ALLOWED_ORIGINS",
61
+ "MCP_AUDIT_RETENTION_DAYS",
62
+ "CLOUDFLARE_ACCESS_OIDC_ISSUER",
63
+ "CLOUDFLARE_ACCESS_OIDC_CLIENT_ID",
64
+ "CLOUDFLARE_ACCESS_OIDC_CLIENT_SECRET",
65
+ "CLOUDFLARE_ACCESS_OIDC_LABEL",
66
+ "CLOUDFLARE_ACCESS_TEAM_DOMAIN",
67
+ "CLOUDFLARE_ACCESS_AUD",
68
+ "CLOUDFLARE_ACCESS_APPS_AUD",
69
+ "CLOUDFLARE_ACCESS_AUTO_JOIN_DOMAINS",
70
+ "CLOUDFLARE_ACCESS_OUTER_RING_AUTO_JOIN",
71
+ "EMAIL_PASSWORD_SIGN_IN",
72
+ // "false" keeps the hosted gateway's sign-up invite-only.
73
+ "HOSTED_OPEN_SIGNUP",
74
+ // Release deployers and the hosted third-party domain. The hosted launch
75
+ // gate, THIRD_PARTY_DEPLOYS, is never set from here: it is opened by
76
+ // hand once the launch checks pass (docs/runbooks/hosted-install.md).
77
+ "CF_DEPLOY_TOKEN",
78
+ // Self-hosted browser installs are on by default; "off" opts out.
79
+ "BROWSER_APP_INSTALLS",
80
+ "DISPATCH_NAMESPACE",
81
+ "THIRD_PARTY_DOMAIN",
82
+ // "true" lets event webhooks target http: and private hosts (self-host only).
83
+ "EVENTS_ALLOW_PRIVATE_TARGETS",
84
+ ];
85
+ /**
86
+ * The Gateway's optional settings `everyapp secret set` changes: every
87
+ * setting a catalog provider reads, then the Gateway's own.
88
+ */
89
+ export const SETTABLE_GATEWAY_SETTINGS = [
90
+ ...PROVIDER_GATEWAY_SETTINGS,
91
+ ...GATEWAY_OWN_SETTINGS,
92
+ ];
93
+ const SETTABLE = new Set(SETTABLE_GATEWAY_SETTINGS);
94
+ /**
95
+ * The credential names of remote MCP apps (`everyapp mcp add <url>`,
96
+ * ./remoteMcp.ts): `<ID>_MCP_TOKEN` by default, any name ending in
97
+ * `_MCP_TOKEN` by choice. A family rather than a list, so the names a
98
+ * registry row declares at run time route to the Gateway like the fixed
99
+ * names (`everyapp secret set` reads no registry to decide), an app's own
100
+ * secret can never take one (the manifest validator refuses the family),
101
+ * and a remote server can never be given a fixed provider key.
102
+ */
103
+ export const REMOTE_MCP_SECRET_PATTERN = /^[A-Z][A-Z0-9_]*_MCP_TOKEN$/;
104
+ /** Whether `name` is a remote MCP app's credential name (`TREG_MCP_TOKEN`). */
105
+ export function isRemoteMcpSecretName(name) {
106
+ return REMOTE_MCP_SECRET_PATTERN.test(name);
107
+ }
108
+ /**
109
+ * Whether `everyapp secret set <name>` changes the Gateway: one of the
110
+ * fixed settings, or a remote MCP app's credential name.
111
+ */
112
+ export function isSettableGatewaySetting(name) {
113
+ return SETTABLE.has(name) || isRemoteMcpSecretName(name);
114
+ }
115
+ /**
116
+ * Settable Gateway settings whose value is a plain word, address, list
117
+ * or switch rather than a credential: a sender, a provider choice, a
118
+ * URL, an audience, a flag. `everyapp secret set` may show these as they
119
+ * are typed and check their shape; anything else is a credential and
120
+ * stays hidden.
121
+ */
122
+ export const PLAIN_GATEWAY_SETTINGS = [
123
+ "EMAIL_FROM",
124
+ "EMAIL_FROM_NAME",
125
+ "EMAIL_PROVIDER",
126
+ "EMAIL_PASSWORD_SIGN_IN",
127
+ "MASTODON_URL",
128
+ "AI_PROXY_EXTRA_ROUTES",
129
+ "MCP_OAUTH_ENABLED",
130
+ "MCP_DCR_ENABLED",
131
+ "MCP_ALLOWED_ORIGINS",
132
+ "MCP_AUDIT_RETENTION_DAYS",
133
+ "CLOUDFLARE_ACCESS_OIDC_ISSUER",
134
+ "CLOUDFLARE_ACCESS_OIDC_CLIENT_ID",
135
+ "CLOUDFLARE_ACCESS_OIDC_LABEL",
136
+ "CLOUDFLARE_ACCESS_TEAM_DOMAIN",
137
+ "CLOUDFLARE_ACCESS_AUD",
138
+ "CLOUDFLARE_ACCESS_APPS_AUD",
139
+ "CLOUDFLARE_ACCESS_AUTO_JOIN_DOMAINS",
140
+ "CLOUDFLARE_ACCESS_OUTER_RING_AUTO_JOIN",
141
+ "HOSTED_OPEN_SIGNUP",
142
+ "BROWSER_APP_INSTALLS",
143
+ "DISPATCH_NAMESPACE",
144
+ "THIRD_PARTY_DOMAIN",
145
+ "EVENTS_ALLOW_PRIVATE_TARGETS",
146
+ ];
147
+ const PLAIN = new Set(PLAIN_GATEWAY_SETTINGS);
148
+ /** Whether a settable Gateway setting's value is a plain value, not a credential. */
149
+ export function isPlainGatewaySetting(name) {
150
+ return PLAIN.has(name);
151
+ }
152
+ /**
153
+ * Settable Gateway settings only the hosted gateway reads: a self-hosted
154
+ * install never needs them, so `secret list` leaves them out there.
155
+ */
156
+ export const HOSTED_ONLY_GATEWAY_SETTINGS = [
157
+ "HOSTED_OPEN_SIGNUP",
158
+ "DISPATCH_NAMESPACE",
159
+ "THIRD_PARTY_DOMAIN",
160
+ ];
161
+ const HOSTED_ONLY = new Set(HOSTED_ONLY_GATEWAY_SETTINGS);
162
+ export function isHostedOnlyGatewaySetting(name) {
163
+ return HOSTED_ONLY.has(name);
164
+ }
165
+ /** Gateway settings for local testing only, set in the gateway's `.dev.vars`, never deployed. */
166
+ export const DEV_ONLY_GATEWAY_SETTINGS = [
167
+ "MCP_ACCESS_TOKEN_TTL",
168
+ // "true" sends the DataForSEO provider app's calls to the free sandbox.
169
+ "DATAFORSEO_SANDBOX",
170
+ ];
171
+ export function isDevOnlyGatewaySetting(name) {
172
+ return DEV_ONLY_GATEWAY_SETTINGS.includes(name);
173
+ }
174
+ /**
175
+ * Names an app's own secret can't take: the deploy sets GATEWAY_URL on
176
+ * every Worker and builds in the identity settings, the gateway binding
177
+ * and the platform's own namespaces. Checked without regard to case. The
178
+ * SDK's `everyAppWorker()` keeps the same rule as a regex (its config
179
+ * module can't import this one); a test keeps them in step.
180
+ */
181
+ const RESERVED_APP_SECRET_NAMES = new Set([
182
+ "GATEWAY_URL",
183
+ "CF_VERSION_METADATA",
184
+ ]);
185
+ const RESERVED_APP_SECRET_PREFIXES = [
186
+ "EVERYAPP_",
187
+ "EVERY_APP_",
188
+ "APP__",
189
+ ];
190
+ /** What the reserved names are, for messages. */
191
+ export const RESERVED_APP_SECRET_NAMES_TEXT = "GATEWAY_URL, CF_VERSION_METADATA and the EVERYAPP_*, EVERY_APP_* and APP__* names";
192
+ export function isReservedAppSecretName(name) {
193
+ const upper = name.toUpperCase();
194
+ return (RESERVED_APP_SECRET_NAMES.has(upper) ||
195
+ RESERVED_APP_SECRET_PREFIXES.some((prefix) => upper.startsWith(prefix)));
196
+ }
197
+ /**
198
+ * The AI provider or capability a Gateway setting belongs to: what to list
199
+ * in a manifest instead of holding the key as the app's own.
200
+ */
201
+ export function gatewaySettingOwner(name) {
202
+ for (const id of CAPABILITY_IDS) {
203
+ const capability = CAPABILITIES[id];
204
+ if (capabilitySettings(capability).includes(name)) {
205
+ return { kind: capability.mode === "ai" ? "provider" : "capability", id };
206
+ }
207
+ }
208
+ return null;
209
+ }
@@ -0,0 +1,88 @@
1
+ import { APP_ID_ENV, DEV_ENV, DEV_ISSUER, IDENTITY_ALG, IDENTITY_DEV_KEY_ID, IDENTITY_HEADER, IDENTITY_KEY_ID, ISSUER_ENV, PUBLIC_HEADER, PUBLIC_KEYS_ENV, PUBLIC_MARKER_SUB, type EveryAppUser, type IdentityChannel, type SystemClaims, type SystemTokenPurpose } from "./protocol.js";
2
+ export { APP_ID_ENV, DEV_ENV, DEV_ISSUER, IDENTITY_ALG, IDENTITY_DEV_KEY_ID, IDENTITY_HEADER, IDENTITY_KEY_ID, ISSUER_ENV, PUBLIC_HEADER, PUBLIC_KEYS_ENV, PUBLIC_MARKER_SUB, type EveryAppUser, type IdentityChannel, };
3
+ export declare class IdentityError extends Error {
4
+ readonly status = 401;
5
+ constructor(message: string);
6
+ }
7
+ export declare class ConfigurationError extends Error {
8
+ readonly status = 500;
9
+ constructor(message: string);
10
+ }
11
+ /**
12
+ * Parse the public key set from an env var value. Accepts a JSON array of PEM
13
+ * strings, or a single PEM string. Returns at least one key or throws.
14
+ */
15
+ export declare function parsePublicKeys(envValue: string | undefined | null): string[];
16
+ export interface VerifyOptions {
17
+ /** SPKI PEM public keys (current + next). */
18
+ publicKeys: string[];
19
+ /** Expected `aud` — this app's id. */
20
+ audience: string;
21
+ /** Expected issuer (the gateway URL). Required for user identities. */
22
+ issuer?: string;
23
+ /**
24
+ * Accept the dev identity kid ({@link IDENTITY_DEV_KEY_ID}). Set ONLY in
25
+ * local dev (driven by the {@link DEV_ENV} worker env var). Never true in
26
+ * production. Requires `issuer` to be {@link DEV_ISSUER}.
27
+ */
28
+ allowDevIdentities?: boolean;
29
+ /** Override for tests. */
30
+ now?: number;
31
+ }
32
+ /**
33
+ * Verify an identity JWT fail-closed. Throws {@link IdentityError} on any
34
+ * problem (bad alg/kid, `none`, wrong key, expired, wrong audience, missing
35
+ * claims).
36
+ */
37
+ export declare function verifyIdentityJwt(token: string, options: VerifyOptions): Promise<EveryAppUser>;
38
+ /**
39
+ * Verify the gateway's system token (the value of `x-everyapp-system`)
40
+ * fail-closed, for exactly one purpose. A user identity or public marker is
41
+ * never a system token, and a system token is never an identity.
42
+ */
43
+ export declare function verifySystemJwt(token: string, options: VerifyOptions & {
44
+ purpose: SystemTokenPurpose;
45
+ }): Promise<SystemClaims>;
46
+ /**
47
+ * Verify a public-route marker (the value of `x-everyapp-public`). The marker
48
+ * is a gateway-signed, app-scoped JWT with `pub: true` and `typ: "public"` —
49
+ * a bare header is NEVER a trust source, so a re-exposed app worker cannot be
50
+ * flipped into public mode by anyone who can type a header. Throws on any
51
+ * problem.
52
+ */
53
+ export declare function verifyPublicMarkerJwt(token: string, options: VerifyOptions): Promise<void>;
54
+ export interface IdentityResult {
55
+ /** The verified user, or null for a declared public route. */
56
+ user: EveryAppUser | null;
57
+ /** True when the gateway marked this request as a public route. */
58
+ isPublic: boolean;
59
+ }
60
+ export interface RequestIdentityOptions {
61
+ audience: string;
62
+ /** Provide keys directly, or let {@link getIdentityFromRequest} read env. */
63
+ publicKeys?: string[];
64
+ /** Env bag to read {@link PUBLIC_KEYS_ENV} / {@link DEV_ENV} from. */
65
+ env?: Record<string, unknown>;
66
+ keysEnvVar?: string;
67
+ issuer?: string;
68
+ /** Force dev-kid acceptance. Defaults to reading {@link DEV_ENV} from env. */
69
+ allowDevIdentities?: boolean;
70
+ now?: number;
71
+ }
72
+ /**
73
+ * The verification options for a request: keys from options or env, the
74
+ * expected issuer, and the dev-kid opt-in. Throws {@link ConfigurationError}
75
+ * when no key set is configured, or when the dev opt-in meets an issuer other
76
+ * than {@link DEV_ISSUER}.
77
+ */
78
+ export declare function resolveVerifyOptions(options: RequestIdentityOptions): VerifyOptions;
79
+ /**
80
+ * Resolve identity for an incoming proxied request. Public routes carry a
81
+ * gateway-SIGNED marker in `x-everyapp-public` and resolve to
82
+ * `{ user: null, isPublic: true }` only after the marker verifies. Everything
83
+ * else requires a valid identity JWT. Throws {@link IdentityError} on any
84
+ * problem — including a bare/forged public header — so a re-exposed worker
85
+ * fails closed.
86
+ */
87
+ export declare function getIdentityFromRequest(request: Request, options: RequestIdentityOptions): Promise<IdentityResult>;
88
+ //# sourceMappingURL=identity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../src/internal/identity.ts"],"names":[],"mappings":"AAgBA,OAAO,EACL,UAAU,EACV,OAAO,EACP,UAAU,EACV,YAAY,EACZ,mBAAmB,EACnB,eAAe,EACf,eAAe,EACf,UAAU,EACV,aAAa,EACb,eAAe,EACf,iBAAiB,EAKjB,KAAK,YAAY,EACjB,KAAK,eAAe,EAEpB,KAAK,YAAY,EACjB,KAAK,kBAAkB,EACxB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,UAAU,EACV,OAAO,EACP,UAAU,EACV,YAAY,EACZ,mBAAmB,EACnB,eAAe,EACf,eAAe,EACf,UAAU,EACV,aAAa,EACb,eAAe,EACf,iBAAiB,EACjB,KAAK,YAAY,EACjB,KAAK,eAAe,GACrB,CAAC;AAEF,qBAAa,aAAc,SAAQ,KAAK;IACtC,QAAQ,CAAC,MAAM,OAAO;gBACV,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAa,kBAAmB,SAAQ,KAAK;IAC3C,QAAQ,CAAC,MAAM,OAAO;gBACV,OAAO,EAAE,MAAM;CAI5B;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,EAAE,CA8B7E;AAYD,MAAM,WAAW,aAAa;IAC5B,6CAA6C;IAC7C,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,sCAAsC;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,uEAAuE;IACvE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,0BAA0B;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAeD;;;;GAIG;AACH,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,YAAY,CAAC,CAUvB;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,aAAa,GAAG;IAAE,OAAO,EAAE,kBAAkB,CAAA;CAAE,GACvD,OAAO,CAAC,YAAY,CAAC,CAUvB;AAoED;;;;;;GAMG;AACH,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,IAAI,CAAC,CAUf;AAED,MAAM,WAAW,cAAc;IAC7B,8DAA8D;IAC9D,IAAI,EAAE,YAAY,GAAG,IAAI,CAAC;IAC1B,mEAAmE;IACnE,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,6EAA6E;IAC7E,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,sEAAsE;IACtE,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8EAA8E;IAC9E,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,sBAAsB,GAC9B,aAAa,CAwBf;AAED;;;;;;;GAOG;AACH,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,cAAc,CAAC,CAiBzB"}
@@ -0,0 +1,231 @@
1
+ /**
2
+ * Every App identity JWT verification (the app side of the trust boundary).
3
+ *
4
+ * The gateway injects a short-lived RS256 JWT as `x-everyapp-identity`. This
5
+ * module verifies it **fail-closed**: the algorithm and key id are pinned,
6
+ * `none` is rejected, the audience must equal this app, and the verification
7
+ * key set arrives from an env var (current + next public keys) — never a
8
+ * runtime JWKS fetch. A bare header is never a trust source; only a token that
9
+ * survives verification produces a user.
10
+ */
11
+ import { importSPKI, jwtVerify, decodeProtectedHeader, } from "jose";
12
+ import { APP_ID_ENV, DEV_ENV, DEV_ISSUER, IDENTITY_ALG, IDENTITY_DEV_KEY_ID, IDENTITY_HEADER, IDENTITY_KEY_ID, ISSUER_ENV, PUBLIC_HEADER, PUBLIC_KEYS_ENV, PUBLIC_MARKER_SUB, assertPublicMarkerClaims, assertSystemClaims, identityClaimsToEveryAppUser, ProtocolClaimsError, } from "./protocol.js";
13
+ export { APP_ID_ENV, DEV_ENV, DEV_ISSUER, IDENTITY_ALG, IDENTITY_DEV_KEY_ID, IDENTITY_HEADER, IDENTITY_KEY_ID, ISSUER_ENV, PUBLIC_HEADER, PUBLIC_KEYS_ENV, PUBLIC_MARKER_SUB, };
14
+ export class IdentityError extends Error {
15
+ status = 401;
16
+ constructor(message) {
17
+ super(message);
18
+ this.name = "IdentityError";
19
+ }
20
+ }
21
+ export class ConfigurationError extends Error {
22
+ status = 500;
23
+ constructor(message) {
24
+ super(message);
25
+ this.name = "ConfigurationError";
26
+ }
27
+ }
28
+ /**
29
+ * Parse the public key set from an env var value. Accepts a JSON array of PEM
30
+ * strings, or a single PEM string. Returns at least one key or throws.
31
+ */
32
+ export function parsePublicKeys(envValue) {
33
+ if (!envValue || envValue.trim().length === 0) {
34
+ throw new ConfigurationError(`${PUBLIC_KEYS_ENV} is not set — the gateway must inject the identity public key set.`);
35
+ }
36
+ const trimmed = envValue.trim();
37
+ let keys;
38
+ if (trimmed.startsWith("[")) {
39
+ let parsed;
40
+ try {
41
+ parsed = JSON.parse(trimmed);
42
+ }
43
+ catch (error) {
44
+ throw new ConfigurationError(`${PUBLIC_KEYS_ENV} must be a JSON array of PEM strings: ${error.message}`);
45
+ }
46
+ if (!Array.isArray(parsed) || parsed.some((k) => typeof k !== "string")) {
47
+ throw new ConfigurationError(`${PUBLIC_KEYS_ENV} must be a JSON array of PEM strings.`);
48
+ }
49
+ keys = parsed.map((k) => k.replace(/\\n/g, "\n"));
50
+ }
51
+ else {
52
+ keys = [trimmed.replace(/\\n/g, "\n")];
53
+ }
54
+ if (keys.length === 0) {
55
+ throw new ConfigurationError(`${PUBLIC_KEYS_ENV} contained no keys.`);
56
+ }
57
+ return keys;
58
+ }
59
+ const keyCache = new Map();
60
+ function importKey(pem) {
61
+ let cached = keyCache.get(pem);
62
+ if (!cached) {
63
+ cached = importSPKI(pem, IDENTITY_ALG);
64
+ keyCache.set(pem, cached);
65
+ }
66
+ return cached;
67
+ }
68
+ /**
69
+ * The dev keypair is public (`@every-app/sdk/dev`), so the dev opt-in holds
70
+ * only for the dev issuer: a dev-kid token that names a real gateway as its
71
+ * issuer never verifies, whatever the env says.
72
+ */
73
+ function assertDevIssuer(options) {
74
+ if (options.allowDevIdentities && options.issuer !== DEV_ISSUER) {
75
+ throw new ConfigurationError(`Dev identities are accepted only from the dev issuer ${DEV_ISSUER}, not ${options.issuer ? `"${options.issuer}"` : "an unset issuer"}. ${DEV_ENV} is for \`everyapp dev\` alone.`);
76
+ }
77
+ }
78
+ /**
79
+ * Verify an identity JWT fail-closed. Throws {@link IdentityError} on any
80
+ * problem (bad alg/kid, `none`, wrong key, expired, wrong audience, missing
81
+ * claims).
82
+ */
83
+ export async function verifyIdentityJwt(token, options) {
84
+ const payload = await verifyPinnedJwt(token, options, "user");
85
+ try {
86
+ return identityClaimsToEveryAppUser(payload);
87
+ }
88
+ catch (error) {
89
+ if (error instanceof ProtocolClaimsError) {
90
+ throw new IdentityError(error.message);
91
+ }
92
+ throw error;
93
+ }
94
+ }
95
+ /**
96
+ * Verify the gateway's system token (the value of `x-everyapp-system`)
97
+ * fail-closed, for exactly one purpose. A user identity or public marker is
98
+ * never a system token, and a system token is never an identity.
99
+ */
100
+ export async function verifySystemJwt(token, options) {
101
+ const payload = await verifyPinnedJwt(token, options, "system");
102
+ try {
103
+ return assertSystemClaims(payload, options.purpose);
104
+ }
105
+ catch (error) {
106
+ if (error instanceof ProtocolClaimsError) {
107
+ throw new IdentityError(error.message);
108
+ }
109
+ throw error;
110
+ }
111
+ }
112
+ /**
113
+ * The shared fail-closed verification core: pinned alg/kid, `none` rejected,
114
+ * `aud` checked, multi-key (current + next). Returns the verified payload.
115
+ */
116
+ async function verifyPinnedJwt(token, options, expectedTyp) {
117
+ assertDevIssuer(options);
118
+ if (!token)
119
+ throw new IdentityError("no identity token");
120
+ // Pin the header BEFORE attempting any signature work. This is what defeats
121
+ // `alg: none` and algorithm-confusion (e.g. an HS256 token forged with the
122
+ // public key as the HMAC secret).
123
+ let header;
124
+ try {
125
+ header = decodeProtectedHeader(token);
126
+ }
127
+ catch {
128
+ throw new IdentityError("malformed identity token");
129
+ }
130
+ if (header.alg !== IDENTITY_ALG) {
131
+ throw new IdentityError(`unexpected alg "${header.alg}" (expected ${IDENTITY_ALG})`);
132
+ }
133
+ const allowedKids = options.allowDevIdentities
134
+ ? [IDENTITY_KEY_ID, IDENTITY_DEV_KEY_ID]
135
+ : [IDENTITY_KEY_ID];
136
+ if (!header.kid || !allowedKids.includes(header.kid)) {
137
+ throw new IdentityError(`unexpected kid "${header.kid}"`);
138
+ }
139
+ if (expectedTyp !== "public" && !options.issuer) {
140
+ throw new IdentityError(`${ISSUER_ENV} not configured — deploy with the Every App CLI or provide an explicit issuer.`);
141
+ }
142
+ const verifyOpts = {
143
+ algorithms: [IDENTITY_ALG],
144
+ audience: options.audience,
145
+ requiredClaims: expectedTyp === "system" ? ["exp", "iat"] : ["exp"],
146
+ ...(options.issuer ? { issuer: options.issuer } : {}),
147
+ ...(options.now ? { currentDate: new Date(options.now) } : {}),
148
+ };
149
+ let lastErr;
150
+ for (const pem of options.publicKeys) {
151
+ try {
152
+ const key = await importKey(pem);
153
+ const { payload } = await jwtVerify(token, key, verifyOpts);
154
+ if (payload.typ !== expectedTyp) {
155
+ throw new IdentityError(`unexpected token typ "${payload.typ}" (expected ${expectedTyp})`);
156
+ }
157
+ return payload;
158
+ }
159
+ catch (err) {
160
+ lastErr = err;
161
+ }
162
+ }
163
+ throw new IdentityError(`identity verification failed: ${lastErr?.message ?? "no matching key"}`);
164
+ }
165
+ /**
166
+ * Verify a public-route marker (the value of `x-everyapp-public`). The marker
167
+ * is a gateway-signed, app-scoped JWT with `pub: true` and `typ: "public"` —
168
+ * a bare header is NEVER a trust source, so a re-exposed app worker cannot be
169
+ * flipped into public mode by anyone who can type a header. Throws on any
170
+ * problem.
171
+ */
172
+ export async function verifyPublicMarkerJwt(token, options) {
173
+ const payload = await verifyPinnedJwt(token, options, "public");
174
+ try {
175
+ assertPublicMarkerClaims(payload);
176
+ }
177
+ catch (error) {
178
+ if (error instanceof ProtocolClaimsError) {
179
+ throw new IdentityError(error.message);
180
+ }
181
+ throw error;
182
+ }
183
+ }
184
+ /**
185
+ * The verification options for a request: keys from options or env, the
186
+ * expected issuer, and the dev-kid opt-in. Throws {@link ConfigurationError}
187
+ * when no key set is configured, or when the dev opt-in meets an issuer other
188
+ * than {@link DEV_ISSUER}.
189
+ */
190
+ export function resolveVerifyOptions(options) {
191
+ const publicKeys = options.publicKeys ??
192
+ parsePublicKeys(options.env?.[options.keysEnvVar ?? PUBLIC_KEYS_ENV] ?? null);
193
+ // Dev identities are accepted only when the worker env opts in
194
+ // (everyAppWorker() sets EVERYAPP_DEV in development). A deploy never does.
195
+ const devEnv = options.env?.[DEV_ENV];
196
+ const allowDevIdentities = options.allowDevIdentities ??
197
+ (typeof devEnv === "string" &&
198
+ (devEnv === "1" || devEnv.toLowerCase() === "true"));
199
+ const resolved = {
200
+ publicKeys,
201
+ audience: options.audience,
202
+ issuer: options.issuer ??
203
+ (options.env?.[ISSUER_ENV] || undefined),
204
+ allowDevIdentities,
205
+ now: options.now,
206
+ };
207
+ assertDevIssuer(resolved);
208
+ return resolved;
209
+ }
210
+ /**
211
+ * Resolve identity for an incoming proxied request. Public routes carry a
212
+ * gateway-SIGNED marker in `x-everyapp-public` and resolve to
213
+ * `{ user: null, isPublic: true }` only after the marker verifies. Everything
214
+ * else requires a valid identity JWT. Throws {@link IdentityError} on any
215
+ * problem — including a bare/forged public header — so a re-exposed worker
216
+ * fails closed.
217
+ */
218
+ export async function getIdentityFromRequest(request, options) {
219
+ const verifyOptions = resolveVerifyOptions(options);
220
+ const publicMarker = request.headers.get(PUBLIC_HEADER);
221
+ if (publicMarker) {
222
+ await verifyPublicMarkerJwt(publicMarker, verifyOptions);
223
+ return { user: null, isPublic: true };
224
+ }
225
+ const token = request.headers.get(IDENTITY_HEADER);
226
+ if (!token) {
227
+ throw new IdentityError("request reached the app without an identity token (not proxied through the gateway?)");
228
+ }
229
+ const user = await verifyIdentityJwt(token, verifyOptions);
230
+ return { user, isPublic: false };
231
+ }
@@ -0,0 +1,19 @@
1
+ export * from "./protocol.js";
2
+ export * from "./tools.js";
3
+ export * from "./capabilities.js";
4
+ export * from "./aiProviders.js";
5
+ export * from "./gatewaySettings.js";
6
+ export * from "./appSettings.js";
7
+ export * from "./email.js";
8
+ export * from "./members.js";
9
+ export * from "./organizationName.js";
10
+ export * from "./oauthClient.js";
11
+ export * from "./oauthScopes.js";
12
+ export * from "./providerApps.js";
13
+ export * from "./events.js";
14
+ export * from "./providerSpec.js";
15
+ export * from "./providerRegistry.js";
16
+ export * from "./remoteMcp.js";
17
+ export * from "./devProviders.js";
18
+ export { ConfigurationError, IdentityError, getIdentityFromRequest, parsePublicKeys, resolveVerifyOptions, verifyIdentityJwt, verifyPublicMarkerJwt, verifySystemJwt, type IdentityResult, type RequestIdentityOptions, type VerifyOptions, } from "./identity.js";
19
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/internal/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC;AACtC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,OAAO,EACL,kBAAkB,EAClB,aAAa,EACb,sBAAsB,EACtB,eAAe,EACf,oBAAoB,EACpB,iBAAiB,EACjB,qBAAqB,EACrB,eAAe,EACf,KAAK,cAAc,EACnB,KAAK,sBAAsB,EAC3B,KAAK,aAAa,GACnB,MAAM,eAAe,CAAC"}
@@ -0,0 +1,18 @@
1
+ export * from "./protocol.js";
2
+ export * from "./tools.js";
3
+ export * from "./capabilities.js";
4
+ export * from "./aiProviders.js";
5
+ export * from "./gatewaySettings.js";
6
+ export * from "./appSettings.js";
7
+ export * from "./email.js";
8
+ export * from "./members.js";
9
+ export * from "./organizationName.js";
10
+ export * from "./oauthClient.js";
11
+ export * from "./oauthScopes.js";
12
+ export * from "./providerApps.js";
13
+ export * from "./events.js";
14
+ export * from "./providerSpec.js";
15
+ export * from "./providerRegistry.js";
16
+ export * from "./remoteMcp.js";
17
+ export * from "./devProviders.js";
18
+ export { ConfigurationError, IdentityError, getIdentityFromRequest, parsePublicKeys, resolveVerifyOptions, verifyIdentityJwt, verifyPublicMarkerJwt, verifySystemJwt, } from "./identity.js";
@@ -0,0 +1,35 @@
1
+ /**
2
+ * The `members` capability's wire contract (docs/capabilities.md "Gateway
3
+ * services"): what `GET /api/integrations/members/list` answers. The
4
+ * gateway builds it, the SDK's `listMembers()` returns it, and its local-dev
5
+ * fallback answers in the same shape. Types only.
6
+ */
7
+ /** A member's role in the organization. */
8
+ export type OrganizationMemberRole = "owner" | "admin" | "member";
9
+ /**
10
+ * One member of the organization who can open the app: not deactivated,
11
+ * and, for an organization's own app, granted it.
12
+ */
13
+ export interface OrganizationMember {
14
+ /** The user id, the identity's `sub` (`getEveryAppUser().id`). */
15
+ id: string;
16
+ email: string;
17
+ /** The display name; empty when the person set none. */
18
+ name: string;
19
+ role: OrganizationMemberRole;
20
+ }
21
+ /** What a list answers. */
22
+ export interface ListMembersResult {
23
+ members: OrganizationMember[];
24
+ }
25
+ /** `GET /api/integrations/members`: whether the app may list members. */
26
+ export interface MembersCapabilityStatus {
27
+ capability: "members";
28
+ /** The app's manifest lists `members`. */
29
+ requested: boolean;
30
+ /** Always true: the gateway needs no setting to list its own members. */
31
+ configured: true;
32
+ /** Lists would go through. */
33
+ ready: boolean;
34
+ }
35
+ //# sourceMappingURL=members.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"members.d.ts","sourceRoot":"","sources":["../../src/internal/members.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,2CAA2C;AAC3C,MAAM,MAAM,sBAAsB,GAAG,OAAO,GAAG,OAAO,GAAG,QAAQ,CAAC;AAElE;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,kEAAkE;IAClE,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,wDAAwD;IACxD,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,sBAAsB,CAAC;CAC9B;AAED,2BAA2B;AAC3B,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,kBAAkB,EAAE,CAAC;CAC/B;AAED,yEAAyE;AACzE,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,SAAS,CAAC;IACtB,0CAA0C;IAC1C,SAAS,EAAE,OAAO,CAAC;IACnB,yEAAyE;IACzE,UAAU,EAAE,IAAI,CAAC;IACjB,8BAA8B;IAC9B,KAAK,EAAE,OAAO,CAAC;CAChB"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * The `members` capability's wire contract (docs/capabilities.md "Gateway
3
+ * services"): what `GET /api/integrations/members/list` answers. The
4
+ * gateway builds it, the SDK's `listMembers()` returns it, and its local-dev
5
+ * fallback answers in the same shape. Types only.
6
+ */
7
+ export {};