@buildbase/sdk 0.0.89 → 0.0.90
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/AGENTS.md +7 -3
- package/CHANGELOG.md +505 -0
- package/README.md +120 -3
- package/dist/cli.mjs +1 -1
- package/dist/css/styles.css +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +1350 -11
- package/dist/index.mjs +1 -1
- package/dist/mcp/index.cjs +1 -1
- package/dist/mcp/index.d.ts +120 -2
- package/dist/mcp/index.mjs +1 -1
- package/dist/react/chunks/SettingsDialog-BVyV5Zfm.mjs +2 -0
- package/dist/react/chunks/SettingsDialog-Ch8X6WXy.cjs +2 -0
- package/dist/react/chunks/{SubscriptionDialog-B8FTFRtp.cjs → SubscriptionDialog-CGIvMKpT.cjs} +1 -1
- package/dist/react/chunks/SubscriptionDialog-g0LwHhbe.mjs +2 -0
- package/dist/react/chunks/ar-3aqWucom.mjs +2 -0
- package/dist/react/chunks/ar-DQVB89r8.cjs +2 -0
- package/dist/react/chunks/de-DO10bhnU.cjs +2 -0
- package/dist/react/chunks/de-HXQk5D6k.mjs +2 -0
- package/dist/react/chunks/es-BZsmhBN3.mjs +2 -0
- package/dist/react/chunks/es-Cxg-qhUh.cjs +2 -0
- package/dist/react/chunks/fr-COCMy3vW.cjs +2 -0
- package/dist/react/chunks/fr-rdnNHzxy.mjs +2 -0
- package/dist/react/chunks/hi-BB0Z-Dgn.cjs +2 -0
- package/dist/react/chunks/hi-t3RH7ITu.mjs +2 -0
- package/dist/react/chunks/ja-CDyla2g0.mjs +2 -0
- package/dist/react/chunks/ja-D92JgUlk.cjs +2 -0
- package/dist/react/chunks/react-DTq7A_PT.mjs +2 -0
- package/dist/react/chunks/react-DeapSbq6.cjs +2 -0
- package/dist/react/chunks/zh-C5HABZZV.mjs +2 -0
- package/dist/react/chunks/zh-DK2yA5wB.cjs +2 -0
- package/dist/react/index.cjs +1 -1
- package/dist/react/index.d.ts +1517 -14
- package/dist/react/index.mjs +1 -1
- package/docs/ERROR_CODES.md +218 -0
- package/docs/THEMING.md +89 -21
- package/docs/UI-CONFIG.md +23 -4
- package/docs/USER-IMPORT.md +320 -0
- package/package.json +2 -1
- package/dist/react/chunks/SettingsDialog-CKVE1PpH.mjs +0 -2
- package/dist/react/chunks/SettingsDialog-DrDmxFEj.cjs +0 -2
- package/dist/react/chunks/SubscriptionDialog-UN7o9Hqb.mjs +0 -2
- package/dist/react/chunks/ar-B2l90OZJ.cjs +0 -2
- package/dist/react/chunks/ar-DVVNZhXD.mjs +0 -2
- package/dist/react/chunks/de-BspJtvAC.mjs +0 -2
- package/dist/react/chunks/de-dURUqbl0.cjs +0 -2
- package/dist/react/chunks/es-DArjREi5.cjs +0 -2
- package/dist/react/chunks/es-vu4BmI3g.mjs +0 -2
- package/dist/react/chunks/fr-DVm5WCvZ.mjs +0 -2
- package/dist/react/chunks/fr-DhYDaYrX.cjs +0 -2
- package/dist/react/chunks/hi-C_nv_c1T.cjs +0 -2
- package/dist/react/chunks/hi-VW8xCj_K.mjs +0 -2
- package/dist/react/chunks/ja-C-b88dvw.mjs +0 -2
- package/dist/react/chunks/ja-CqtDkLHr.cjs +0 -2
- package/dist/react/chunks/react-CHivaJhA.mjs +0 -2
- package/dist/react/chunks/react-Ch_Suxxy.cjs +0 -2
- package/dist/react/chunks/zh-D1yfhUf0.mjs +0 -2
- package/dist/react/chunks/zh-D_tMpsNt.cjs +0 -2
package/dist/mcp/index.d.ts
CHANGED
|
@@ -370,7 +370,116 @@ interface IUser extends IDocument {
|
|
|
370
370
|
/** Currency code. May be omitted. */
|
|
371
371
|
currency?: string;
|
|
372
372
|
attributes?: Record<string, string | number | boolean>;
|
|
373
|
+
/**
|
|
374
|
+
* The user has a confirmed authenticator app, so sign-in asks for a second
|
|
375
|
+
* step. Read-only: it changes through the two-step sign-in calls on
|
|
376
|
+
* `WorkspaceApi`, never through `updateUserProfile`. Absent from a server
|
|
377
|
+
* that predates two-step sign-in.
|
|
378
|
+
*/
|
|
379
|
+
mfaEnabled?: boolean;
|
|
380
|
+
/**
|
|
381
|
+
* The user can change their email address with `requestEmailChange` and
|
|
382
|
+
* `confirmEmailChange`. Read-only, from the profile. Absent from a server
|
|
383
|
+
* that predates changing email, which reads as `false`.
|
|
384
|
+
*/
|
|
385
|
+
canChangeEmail?: boolean;
|
|
386
|
+
/**
|
|
387
|
+
* Why `canChangeEmail` is false, when the user should be told. Absent when
|
|
388
|
+
* the change is allowed or no reason is given.
|
|
389
|
+
*/
|
|
390
|
+
changeEmailBlockedBy?: ChangeEmailBlockedBy;
|
|
391
|
+
/**
|
|
392
|
+
* The user's id in the system they were imported from (`buildbase import`),
|
|
393
|
+
* so an app can map its own rows to this account. Read-only, from the
|
|
394
|
+
* profile. Absent for anyone who was not imported.
|
|
395
|
+
*/
|
|
396
|
+
externalId?: string;
|
|
397
|
+
/**
|
|
398
|
+
* The user's phone number, as E.164 (`+14155550123`). Read-only: it changes
|
|
399
|
+
* through `addPhone`, `confirmPhone` and `removePhone` on `WorkspaceApi`,
|
|
400
|
+
* never through `updateUserProfile`. Absent until the user adds one, signs
|
|
401
|
+
* up by phone or is imported with one, and from a server that predates
|
|
402
|
+
* phone numbers.
|
|
403
|
+
*/
|
|
404
|
+
phone?: string;
|
|
405
|
+
/** The phone was proven with a code sent to it. Read-only, from the profile. */
|
|
406
|
+
phoneVerified?: boolean;
|
|
407
|
+
/**
|
|
408
|
+
* The user's username, lower case, while the app has usernames on: `''`
|
|
409
|
+
* when they have none. Changes through `setUsername` and `removeUsername` on
|
|
410
|
+
* `WorkspaceApi`. Absent from a server that predates usernames.
|
|
411
|
+
*/
|
|
412
|
+
username?: string;
|
|
413
|
+
/**
|
|
414
|
+
* Custom claims the app owner set for this user, from the console or with
|
|
415
|
+
* an API token; `{}` when there are none. Read-only to the user, who cannot
|
|
416
|
+
* change them. The same object reaches the app's backend as `claims` on the
|
|
417
|
+
* app-token request (`AppTokenRequestClaims.claims`).
|
|
418
|
+
*/
|
|
419
|
+
claims?: Record<string, unknown>;
|
|
420
|
+
/**
|
|
421
|
+
* A guest: someone who continued without an account. Their name is `Guest`
|
|
422
|
+
* and their email a placeholder ending in `@anonymous.invalid` that must
|
|
423
|
+
* never be shown. They become a real account, keeping their id and data,
|
|
424
|
+
* with `requestGuestUpgrade` and `confirmGuestUpgrade`.
|
|
425
|
+
*/
|
|
426
|
+
isAnonymous?: boolean;
|
|
427
|
+
/**
|
|
428
|
+
* When the account deletion the user asked for runs (ISO 8601). Absent
|
|
429
|
+
* unless one is scheduled; `cancelAccountDeletion` takes it back until then.
|
|
430
|
+
*/
|
|
431
|
+
deleteAfter?: string;
|
|
432
|
+
/**
|
|
433
|
+
* When this session last proved who its person is (ISO 8601): the sign-in,
|
|
434
|
+
* or the latest re-confirmation. `null` for a session nobody signed in to
|
|
435
|
+
* (an API-key exchange), which never counts as recent.
|
|
436
|
+
*/
|
|
437
|
+
authTime?: string | null;
|
|
438
|
+
/** How this session proved it (`amr`, RFC 8176), such as `['pwd', 'mfa']`. */
|
|
439
|
+
amr?: string[];
|
|
440
|
+
/**
|
|
441
|
+
* Present while an app owner is viewing the app as this person: who, until
|
|
442
|
+
* when, and whether the session can change anything.
|
|
443
|
+
*/
|
|
444
|
+
impersonation?: IImpersonation;
|
|
445
|
+
/**
|
|
446
|
+
* The person has a password they know, so `changePassword` can work. False
|
|
447
|
+
* for an account made by social sign-up, a wallet, or a code or link sent
|
|
448
|
+
* by email or text, which holds a random password nobody knows: they set
|
|
449
|
+
* one with Forgot password? on the sign-in page. Absent from a server that
|
|
450
|
+
* predates it.
|
|
451
|
+
*/
|
|
452
|
+
passwordSet?: boolean;
|
|
453
|
+
/**
|
|
454
|
+
* The app this session signed in to offers password sign-in. Absent when
|
|
455
|
+
* the session names no app, and from a server that predates it.
|
|
456
|
+
*/
|
|
457
|
+
passwordSignIn?: boolean;
|
|
373
458
|
}
|
|
459
|
+
/**
|
|
460
|
+
* An app owner signed in as this person from the console, to see what they
|
|
461
|
+
* see. Every change in a read-only session is refused with
|
|
462
|
+
* `read_only_session`, and in any such session a change to how the person
|
|
463
|
+
* signs in is refused with `impersonation_sign_in_locked`.
|
|
464
|
+
*/
|
|
465
|
+
interface IImpersonation {
|
|
466
|
+
/** The owner's name, as the console has it. */
|
|
467
|
+
actorName: string;
|
|
468
|
+
/** The session can only read. The default; full access needs the owner role. */
|
|
469
|
+
readOnly: boolean;
|
|
470
|
+
/** When the session ends (ISO 8601), at most an hour after it began. */
|
|
471
|
+
expiresAt: string;
|
|
472
|
+
}
|
|
473
|
+
/**
|
|
474
|
+
* Why the signed-in user cannot change their email address.
|
|
475
|
+
*
|
|
476
|
+
* `linked_social_account`: the account signs in with Google or another
|
|
477
|
+
* provider, which finds the account by its email address, so changing it would
|
|
478
|
+
* create a second account at the next such sign-in. Only an older server says
|
|
479
|
+
* so: social sign-in now finds the account by the provider's own ID, and a
|
|
480
|
+
* current server always answers `canChangeEmail: true`.
|
|
481
|
+
*/
|
|
482
|
+
type ChangeEmailBlockedBy = 'linked_social_account';
|
|
374
483
|
type BillingInterval = 'monthly' | 'yearly' | 'quarterly';
|
|
375
484
|
/** Subscription status constants */
|
|
376
485
|
declare const SubscriptionStatus: {
|
|
@@ -2150,14 +2259,23 @@ interface AppTokenRequestClaims {
|
|
|
2150
2259
|
blocked?: boolean;
|
|
2151
2260
|
blockedReason?: string;
|
|
2152
2261
|
blockedAt?: string;
|
|
2153
|
-
/**
|
|
2154
|
-
|
|
2262
|
+
/**
|
|
2263
|
+
* Which grant triggered this mint. `device_code` is a CLI or TV that signed
|
|
2264
|
+
* in with a code the person entered on another device (RFC 8628).
|
|
2265
|
+
*/
|
|
2266
|
+
grantType?: 'authorization_code' | 'refresh_token' | 'device_code';
|
|
2155
2267
|
/** Scopes granted at authorization time. */
|
|
2156
2268
|
scope?: string[];
|
|
2157
2269
|
/** RFC 8707 resource indicator(s) — bind the minted token's `aud` to these. */
|
|
2158
2270
|
resource?: string[];
|
|
2159
2271
|
/** The OAuth2 client's display title. */
|
|
2160
2272
|
clientTitle?: string;
|
|
2273
|
+
/**
|
|
2274
|
+
* Custom claims the app owner set for this user (console or API token),
|
|
2275
|
+
* `{}` when there are none. Namespaced here, so a custom claim can never
|
|
2276
|
+
* shadow a standard one. Absent from a server that predates them.
|
|
2277
|
+
*/
|
|
2278
|
+
claims?: Record<string, unknown>;
|
|
2161
2279
|
/**
|
|
2162
2280
|
* Per-user BuildBase session bound to this grant. Embed it ENCRYPTED in the
|
|
2163
2281
|
* token you mint (JWTs are signed, not encrypted) and never store it — your
|
package/dist/mcp/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{z as e}from"zod";function t(e){let t="";for(let n=0;n<e.length;n++)t+=String.fromCharCode(e[n]);return btoa(t).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function n(e){const t=e.replace(/-/g,"+").replace(/_/g,"/"),n=t.length%4==0?"":"=".repeat(4-t.length%4),r=atob(t+n),s=new Uint8Array(r.length);for(let e=0;e<r.length;e++)s[e]=r.charCodeAt(e);return s}const r=new Uint32Array([1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298]),s=(e,t)=>e>>>t|e<<32-t;function i(e){let t=1779033703,n=3144134277,i=1013904242,o=2773480762,a=1359893119,c=2600822924,u=528734635,l=1541459225;const p=e.length,d=p+1,h=d+(56-d%64+64)%64+8,g=new Uint8Array(h);g.set(e,0),g[p]=128;const m=8*p,f=Math.floor(m/4294967296),w=m>>>0;g[h-8]=f>>>24&255,g[h-7]=f>>>16&255,g[h-6]=f>>>8&255,g[h-5]=255&f,g[h-4]=w>>>24&255,g[h-3]=w>>>16&255,g[h-2]=w>>>8&255,g[h-1]=255&w;const y=new Uint32Array(64);for(let e=0;e<h;e+=64){for(let t=0;t<16;t++){const n=e+4*t;y[t]=g[n]<<24|g[n+1]<<16|g[n+2]<<8|g[n+3]}for(let e=16;e<64;e++){const t=s(y[e-15],7)^s(y[e-15],18)^y[e-15]>>>3,n=s(y[e-2],17)^s(y[e-2],19)^y[e-2]>>>10;y[e]=y[e-16]+t+y[e-7]+n>>>0}let p=t,d=n,h=i,m=o,f=a,w=c,b=u,k=l;for(let e=0;e<64;e++){const t=k+(s(f,6)^s(f,11)^s(f,25))+(f&w^~f&b)+r[e]+y[e]>>>0,n=p&d^p&h^d&h;k=b,b=w,w=f,f=m+t>>>0,m=h,h=d,d=p,p=t+((s(p,2)^s(p,13)^s(p,22))+n>>>0)>>>0}t=t+p>>>0,n=n+d>>>0,i=i+h>>>0,o=o+m>>>0,a=a+f>>>0,c=c+w>>>0,u=u+b>>>0,l=l+k>>>0}const b=new Uint8Array(32),k=[t,n,i,o,a,c,u,l];for(let e=0;e<8;e++)b[4*e]=k[e]>>>24&255,b[4*e+1]=k[e]>>>16&255,b[4*e+2]=k[e]>>>8&255,b[4*e+3]=255&k[e];return b}function o(e){return(new TextEncoder).encode(e)}function a(e,t){let n=e;n.length>64&&(n=i(n));const r=new Uint8Array(64),s=new Uint8Array(64);for(let e=0;e<64;e++){const t=e<n.length?n[e]:0;r[e]=54^t,s[e]=92^t}const o=i(c(r,t));return i(c(s,o))}function c(e,t){const n=new Uint8Array(e.length+t.length);return n.set(e,0),n.set(t,e.length),n}class u extends Error{constructor(e,t){super(t),this.name="AppBridgeError",this.code=e}}function l(e){const t=JSON.parse((new TextDecoder).decode(n(e)));if("object"!=typeof t||null===t||Array.isArray(t))throw new Error("JWT segment is not a JSON object");return t}function p(e,t,r={}){const s=r.clockToleranceSec??60,i=r.requireExp??!0;if(!e||!t)throw new u("invalid_token","Missing token or client secret");const c=e.split(".");if(3!==c.length)throw new u("invalid_token","Malformed JWT");const[p,d,h]=c;let g,m;try{g=l(p),m=l(d)}catch{throw new u("invalid_token","Unreadable JWT segments")}if("HS256"!==g.alg)throw new u("invalid_algorithm",`Unexpected JWT alg: ${String(g.alg)}`);const f=a(o(t),o(`${p}.${d}`));let w;try{w=n(h)}catch{throw new u("invalid_signature","Unreadable JWT signature")}if(!function(e,t){if(e.length!==t.length)return!1;let n=0;for(let r=0;r<e.length;r++)n|=e[r]^t[r];return 0===n}(f,w))throw new u("invalid_signature","JWT signature verification failed");!function(e){for(const t of["iss","sub","jti"])if(void 0!==e[t]&&"string"!=typeof e[t])throw new u("invalid_token",`JWT ${t} claim must be a string`);for(const t of["exp","nbf","iat"]){const n=e[t];if(void 0!==n&&("number"!=typeof n||!Number.isFinite(n)))throw new u("invalid_token",`JWT ${t} claim must be a finite number`)}const t=e.aud;if(!(void 0===t||"string"==typeof t||Array.isArray(t)&&t.every(e=>"string"==typeof e)))throw new u("invalid_token","JWT aud claim must be a string or string array")}(m);const y=Math.floor(Date.now()/1e3);if(i&&"number"!=typeof m.exp)throw new u("invalid_token","JWT is missing a numeric exp claim");if("number"==typeof m.exp&&y>m.exp+s)throw new u("token_expired","JWT has expired");if("number"==typeof m.nbf&&y+s<m.nbf)throw new u("token_not_yet_valid","JWT is not yet valid");if(void 0!==r.issuer&&m.iss!==r.issuer)throw new u("invalid_issuer","JWT issuer mismatch");if(void 0!==r.audience){const e=m.aud;if(!(Array.isArray(e)?e.includes(r.audience):e===r.audience))throw new u("invalid_audience","JWT audience mismatch")}return m}function d(e){if(!e)return null;const t=/^Bearer\s+(.+)$/i.exec(e.trim());return t?t[1].trim():null}function h(e){return t(o(JSON.stringify(e)))}function g(e,n,r){if(!n)throw new u("invalid_secret","Missing signing secret");const s=Math.floor(Date.now()/1e3),i={iat:s,exp:s+(r?.expiresInSec??3600),...e},c=`${h({alg:"HS256",typ:"JWT"})}.${h(i)}`;return`${c}.${t(a(o(n),o(c)))}`}function m(e){return e.replace(/[\x00-\x1f\x7f]/g,"").replace(/([\\"])/g,"\\$1")}function f(e){const t=[`Bearer resource_metadata="${m(e.resourceMetadataUrl)}"`];return e.error&&t.push(`error="${m(e.error)}"`),e.errorDescription&&t.push(`error_description="${m(e.errorDescription)}"`),{status:401,headers:{"WWW-Authenticate":t.join(", "),"Content-Type":"application/json"},body:JSON.stringify({error:e.error??"invalid_token"})}}const w=e.string().optional().describe("Workspace id. Omit to use the workspace bound to your token.");function y(e,t){const n=e.workspaceId??t.workspaceId;if(!n)throw new Error("workspaceId is required — call list_workspaces to find one.");return n}function b(e){return{title:e,readOnlyHint:!0}}function k(e,t){return{title:e,readOnlyHint:!1,destructiveHint:t.destructive,...void 0!==t.idempotent?{idempotentHint:t.idempotent}:{},...void 0!==t.openWorld?{openWorldHint:t.openWorld}:{}}}const v=[{name:"list_workspaces",description:"List the authenticated user's workspaces (id, name, roles).",inputSchema:e.object({}),annotations:b("List Workspaces"),execute:(e,t)=>t.bb.workspace.list()},{name:"get_workspace",description:"Get one workspace: name, members, feature flags, quota snapshot.",inputSchema:e.object({workspaceId:w}),annotations:b("Get Workspace Details"),execute:(e,t)=>t.bb.workspace.get(y(e,t))},{name:"get_user_profile",description:"Get the authenticated user's profile.",inputSchema:e.object({}),annotations:b("Get My Profile"),execute:(e,t)=>t.bb.users.getProfile()},{name:"list_workspace_users",description:"List the members of a workspace with their roles.",inputSchema:e.object({workspaceId:w}),annotations:b("List Workspace Members"),execute:(e,t)=>t.bb.users.list(y(e,t))},{name:"get_subscription",description:"Get a workspace's subscription: plan, status, interval, seats.",inputSchema:e.object({workspaceId:w}),annotations:b("Get Subscription"),execute:(e,t)=>t.bb.subscription.get(y(e,t))},{name:"get_plans",description:"Get the plan group available to a workspace (plans, prices, quotas).",inputSchema:e.object({workspaceId:w}),annotations:b("List Available Plans"),execute:(e,t)=>t.bb.plans.getGroup(y(e,t))},{name:"list_invoices",description:"List a workspace's invoices (newest first).",inputSchema:e.object({workspaceId:w,limit:e.number().int().min(1).max(100).optional().describe("Max invoices to return."),startingAfter:e.string().optional().describe("Invoice id to paginate after.")}),annotations:b("List Invoices"),execute:(e,t)=>t.bb.invoices.list(y(e,t),e.limit,e.startingAfter)},{name:"get_quota_usage",description:"Get usage vs. limit for one quota in a workspace.",inputSchema:e.object({workspaceId:w,quotaSlug:e.string().describe('The quota slug, e.g. "api-calls".')}),annotations:b("Get Quota Usage"),execute:(e,t)=>t.bb.usage.getQuota(y(e,t),e.quotaSlug)},{name:"get_all_quota_usage",description:"Get usage vs. limit for every quota in a workspace.",inputSchema:e.object({workspaceId:w}),annotations:b("Get All Quota Usage"),execute:(e,t)=>t.bb.usage.getAll(y(e,t))},{name:"get_credit_balance",description:"Get a workspace's prepaid credit balance.",inputSchema:e.object({workspaceId:w}),annotations:b("Get Credit Balance"),execute:(e,t)=>t.bb.credits.getBalance(y(e,t))},{name:"list_credit_transactions",description:"Get a workspace's credit transaction history (paginated).",inputSchema:e.object({workspaceId:w,limit:e.number().int().min(1).max(100).optional(),page:e.number().int().min(1).optional()}),annotations:b("List Credit Transactions"),execute:(e,t)=>t.bb.credits.getTransactions(y(e,t),{...void 0!==e.limit?{limit:e.limit}:{},...void 0!==e.page?{page:e.page}:{}})},{name:"check_feature_flag",description:"Check whether a feature flag is enabled for a workspace.",inputSchema:e.object({workspaceId:w,key:e.string().describe("The feature slug.")}),annotations:b("Check Feature Flag"),execute:async(e,t)=>{const n=y(e,t),r=await t.bb.workspace.get(n),s=r.features?.[e.key];if(void 0!==s)return{key:e.key,enabled:s,source:"workspace"};const i=(await t.bb.features.list()).find(t=>t.slug===e.key);if(!i)throw new Error(`Unknown feature flag: ${e.key}`);return{key:e.key,enabled:i.defaultValue,source:"default"}}},{name:"check_permission",description:"Check whether a user has permission(s) in a workspace.",inputSchema:e.object({workspaceId:w,permission:e.union([e.string(),e.array(e.string())]).describe("A permission (or list — all must hold), platform or app-defined."),userId:e.string().optional().describe("Defaults to the authenticated user.")}),annotations:b("Check Permission"),execute:async(e,t)=>{const n=e.userId??t.auth.userId;if(!n)throw new Error("userId is required — the token carries no user identity.");const r=await t.bb.permissions.check(y(e,t),n,e.permission);return{userId:n,permission:e.permission,allowed:r}}},{name:"resolve_permissions",description:"List every permission a user holds in a workspace.",inputSchema:e.object({workspaceId:w,userId:e.string().optional().describe("Defaults to the authenticated user.")}),annotations:b("List User Permissions"),execute:async(e,t)=>{const n=e.userId??t.auth.userId;if(!n)throw new Error("userId is required — the token carries no user identity.");const r=await t.bb.permissions.resolve(y(e,t),n);return{userId:n,permissions:Array.from(r)}}},{name:"get_invoice",description:"Get one invoice by id.",inputSchema:e.object({workspaceId:w,invoiceId:e.string().describe("The invoice id.")}),annotations:b("Get Invoice"),execute:(e,t)=>t.bb.invoices.get(y(e,t),e.invoiceId)},{name:"get_plan_versions",description:"List the plan-group versions available to a workspace.",inputSchema:e.object({workspaceId:w}),annotations:b("List Plan Versions"),execute:(e,t)=>t.bb.plans.getVersions(y(e,t))},{name:"get_public_plans",description:"Get a public plan group by slug (no workspace / auth needed).",inputSchema:e.object({slug:e.string().describe("The plan-group slug.")}),annotations:b("Get Public Plans"),execute:(e,t)=>t.bb.plans.getPublic(e.slug)},{name:"get_plan_version",description:"Get one public plan-group version by id (no auth needed).",inputSchema:e.object({groupVersionId:e.string().describe("The plan-group version id.")}),annotations:b("Get Plan Version"),execute:(e,t)=>t.bb.plans.getVersion(e.groupVersionId)},{name:"get_usage_logs",description:"Get a workspace's usage log entries (paginated, filterable).",inputSchema:e.object({workspaceId:w,quotaSlug:e.string().optional(),from:e.string().optional().describe("ISO date lower bound."),to:e.string().optional().describe("ISO date upper bound."),source:e.string().optional(),page:e.number().int().min(1).optional(),limit:e.number().int().min(1).max(100).optional()}).strict(),annotations:b("List Usage Logs"),execute:(e,t)=>{const{workspaceId:n,...r}=e;return t.bb.usage.getLogs(y(e,t),r)}},{name:"get_settings",description:"Get the organization settings.",inputSchema:e.object({}),annotations:b("Get Organization Settings"),execute:(e,t)=>t.bb.settings.get()},{name:"get_credit_packages",description:"List the credit packages a workspace can purchase.",inputSchema:e.object({workspaceId:w}),annotations:b("List Credit Packages"),execute:(e,t)=>t.bb.credits.getPackages(y(e,t))},{name:"get_credit_buckets",description:"Get a workspace's credit buckets (paginated).",inputSchema:e.object({workspaceId:w,status:e.string().optional(),source:e.string().optional(),page:e.number().int().min(1).optional(),limit:e.number().int().min(1).max(100).optional()}).strict(),annotations:b("List Credit Buckets"),execute:(e,t)=>{const{workspaceId:n,...r}=e;return t.bb.credits.getBuckets(y(e,t),r)}},{name:"get_expiring_credits",description:"Get credits expiring within N days (default 7).",inputSchema:e.object({workspaceId:w,days:e.number().int().min(1).optional()}),annotations:b("List Expiring Credits"),execute:(e,t)=>t.bb.credits.getExpiring(y(e,t),e.days)},{name:"get_public_credit_packages",description:"List credit packages publicly (no workspace / auth needed).",inputSchema:e.object({}),annotations:b("List Public Credit Packages"),execute:(e,t)=>t.bb.credits.getPublicPackages()}],S=[{name:"record_usage",description:"Record quota usage for a workspace (metered billing).",inputSchema:e.object({workspaceId:w,quotaSlug:e.string().describe("The quota slug to record against."),quantity:e.number().positive().describe("Amount of usage to record."),idempotencyKey:e.string().optional().describe("Dedupe key for safe retries."),metadata:e.record(e.string(),e.unknown()).optional()}),annotations:k("Record Usage",{destructive:!1,idempotent:!1}),execute:(e,t)=>t.bb.usage.record(y(e,t),{quotaSlug:e.quotaSlug,quantity:e.quantity,source:"mcp",...e.idempotencyKey?{idempotencyKey:e.idempotencyKey}:{},...e.metadata?{metadata:e.metadata}:{}})},{name:"consume_credits",description:"Consume prepaid credits from a workspace's balance.",inputSchema:e.object({workspaceId:w,amount:e.number().positive().describe("Credits to consume."),description:e.string().optional().describe("What the credits were spent on."),idempotencyKey:e.string().optional().describe("Dedupe key for safe retries.")}),annotations:k("Consume Credits",{destructive:!0}),execute:(e,t)=>t.bb.credits.consume(y(e,t),{amount:e.amount,...e.description?{description:e.description}:{},...e.idempotencyKey?{idempotencyKey:e.idempotencyKey}:{}})},{name:"send_notification",description:"Send a notification event to a workspace user (or all members when userId is omitted).",inputSchema:e.object({workspaceId:w,event:e.string().describe('The event slug, e.g. "comment_added".'),userId:e.string().optional().describe("Recipient. Omit to notify all members."),message:e.string().optional().describe("Message body (used for push).")}),annotations:k("Send Notification",{destructive:!1,openWorld:!0}),execute:(e,t)=>t.bb.notification.send(y(e,t),e.event,e.userId,e.message?{message:e.message}:void 0)},{name:"record_usage_batch",description:"Record multiple usage entries in one call (max 100 items).",inputSchema:e.object({workspaceId:w,items:e.array(e.object({quotaSlug:e.string(),quantity:e.number().positive(),idempotencyKey:e.string().optional(),metadata:e.record(e.string(),e.unknown()).optional()})).min(1).max(100)}),annotations:k("Record Usage (Batch)",{destructive:!1}),execute:(e,t)=>t.bb.usage.recordBatch(y(e,t),{items:e.items.map(e=>({...e,source:"mcp"}))})},{name:"create_workspace",description:"Create a new workspace.",inputSchema:e.object({name:e.string().describe("Workspace name."),image:e.string().optional().describe("Image URL.")}),annotations:k("Create Workspace",{destructive:!1}),execute:(e,t)=>t.bb.workspace.create({name:e.name,...e.image?{image:e.image}:{}})},{name:"update_workspace",description:"Update a workspace's editable fields (name, image).",inputSchema:e.object({workspaceId:w,name:e.string().min(1).optional().describe("New workspace name."),image:e.string().optional().describe("New image URL.")}).strict(),annotations:k("Update Workspace",{destructive:!1}),execute:(e,t)=>{const n={};return void 0!==e.name&&(n.name=e.name),void 0!==e.image&&(n.image=e.image),t.bb.workspace.update(y(e,t),n)}},{name:"delete_workspace",description:"Delete a workspace. Irreversible.",inputSchema:e.object({workspaceId:w}),annotations:k("Delete Workspace",{destructive:!0}),execute:(e,t)=>t.bb.workspace.delete(y(e,t))},{name:"invite_workspace_user",description:"Invite a user to a workspace with a role.",inputSchema:e.object({workspaceId:w,email:e.string().describe("Invitee email."),role:e.string().describe("Role to grant.")}),annotations:k("Invite Member",{destructive:!1,openWorld:!0}),execute:(e,t)=>t.bb.users.invite(y(e,t),e.email,e.role)},{name:"remove_workspace_user",description:"Remove a user from a workspace. Irreversible.",inputSchema:e.object({workspaceId:w,userId:e.string().describe("The user to remove.")}),annotations:k("Remove Member",{destructive:!0}),execute:(e,t)=>t.bb.users.remove(y(e,t),e.userId)},{name:"update_workspace_user_role",description:"Change a workspace member's role.",inputSchema:e.object({workspaceId:w,userId:e.string(),role:e.string().describe("The new role.")}),annotations:k("Change Member Role",{destructive:!1}),execute:(e,t)=>t.bb.users.updateRole(y(e,t),e.userId,e.role)},{name:"update_user_profile",description:"Update the authenticated user's own profile (name, image, country, timezone, language, currency).",inputSchema:e.object({name:e.string().min(1).optional(),image:e.string().optional().describe("Profile image URL."),country:e.string().optional().describe("ISO country code."),timezone:e.string().optional().describe("IANA timezone."),language:e.string().optional().describe("Language code."),currency:e.string().optional().describe("Currency code.")}).strict(),annotations:k("Update My Profile",{destructive:!1}),execute:(e,t)=>{const n={};for(const t of["name","image","country","timezone","language","currency"]){const r=e[t];void 0!==r&&(n[t]=r)}return t.bb.users.updateProfile(n)}},{name:"update_feature_flag",description:"Set a feature flag on/off for a workspace.",inputSchema:e.object({workspaceId:w,key:e.string().describe("The feature slug."),value:e.boolean().describe("Enabled?")}),annotations:k("Set Feature Flag",{destructive:!1}),execute:(e,t)=>t.bb.features.update(y(e,t),e.key,e.value)},{name:"create_subscription_checkout",description:"Create a Stripe checkout session to subscribe a workspace to a plan.",inputSchema:e.object({workspaceId:w,planVersionId:e.string(),billingInterval:e.string().optional(),currency:e.string().optional(),successUrl:e.string().optional(),cancelUrl:e.string().optional()}).strict(),annotations:k("Start Subscription Checkout",{destructive:!1,openWorld:!0}),execute:(e,t)=>{const{workspaceId:n,...r}=e;return t.bb.subscription.checkout(y(e,t),r)}},{name:"update_subscription",description:"Change a workspace's subscription plan.",inputSchema:e.object({workspaceId:w,planVersionId:e.string(),billingInterval:e.string().optional(),successUrl:e.string().optional(),cancelUrl:e.string().optional()}).strict(),annotations:k("Change Subscription Plan",{destructive:!0}),execute:(e,t)=>{const{workspaceId:n,...r}=e;return t.bb.subscription.update(y(e,t),r)}},{name:"cancel_subscription",description:"Cancel a workspace's subscription.",inputSchema:e.object({workspaceId:w}),annotations:k("Cancel Subscription",{destructive:!0}),execute:(e,t)=>t.bb.subscription.cancel(y(e,t))},{name:"resume_subscription",description:"Resume a workspace's canceled subscription.",inputSchema:e.object({workspaceId:w}),annotations:k("Resume Subscription",{destructive:!1}),execute:(e,t)=>t.bb.subscription.resume(y(e,t))},{name:"get_billing_portal_url",description:"Get a Stripe billing-portal URL for a workspace.",inputSchema:e.object({workspaceId:w,returnUrl:e.string().optional()}),annotations:k("Open Billing Portal",{destructive:!1,openWorld:!0}),execute:(e,t)=>t.bb.subscription.getBillingPortalUrl(y(e,t),e.returnUrl)},{name:"purchase_credits",description:"Create a Stripe checkout session to buy a credit package.",inputSchema:e.object({workspaceId:w,creditPackageId:e.string(),currency:e.string().optional(),successUrl:e.string().describe("Redirect URL on success."),cancelUrl:e.string().describe("Redirect URL on cancel.")}).strict(),annotations:k("Buy Credits",{destructive:!1,openWorld:!0}),execute:(e,t)=>{const{workspaceId:n,...r}=e;return t.bb.credits.purchase(y(e,t),r)}}],E=new Map([...v,...S].map(e=>[e.name,e]));function I(e){if(!1===e)return[];if("readonly"===e)return[...v];if("all"===e)return[...v,...S];const t=e.include?e.include.map(e=>{const t=E.get(e);if(!t)throw new Error(`Unknown built-in MCP tool: ${e}`);return t}):[...v],n=new Set(e.exclude??[]);return t.filter(e=>!n.has(e.name))}const P=e=>({type:"text",text:e}),T=(e,t)=>({type:"image",data:e,mimeType:t}),_=(e,t)=>({type:"audio",data:e,mimeType:t}),U=(e,t,n)=>({type:"resource_link",uri:e,name:t,...n}),$=e=>({type:"resource",resource:e}),C=e=>{if("object"!=typeof e||null===e)return!1;const t=e;switch(t.type){case"text":return"string"==typeof t.text;case"image":case"audio":return"string"==typeof t.data&&"string"==typeof t.mimeType;case"resource_link":return"string"==typeof t.uri&&"string"==typeof t.name;case"resource":{const e=t.resource;return"object"==typeof e&&null!==e&&"string"==typeof e.uri&&("string"==typeof e.text||"string"==typeof e.blob)}default:return!1}},x=e=>e,A=e=>e,O=e=>e,R=["2025-11-25","2025-06-18","2025-03-26","2024-11-05"],j=R[0],N="application/json",F=/^[a-zA-Z0-9_-]{1,128}$/,J=-32002,W=-32700,M=-32600,L=-32601,q=-32602,B=-32603;function D(e,t){const n=t.toLowerCase();for(const t of Object.keys(e))if(t.toLowerCase()===n)return e[t]}function G(e,t){return{status:e,headers:{"Content-Type":N},body:JSON.stringify(t)}}function V(e,t){return G(200,{jsonrpc:"2.0",id:e??null,result:t})}function K(e,t,n,r=200,s){return G(r,{jsonrpc:"2.0",id:e??null,error:{code:t,message:n,...void 0!==s?{data:s}:{}}})}function z(e){return"object"==typeof e&&null!==e&&"function"==typeof e.safeParse}function H(e){return e instanceof Error?e.message:"string"==typeof e?e:JSON.stringify(e)}function Q(t){const n=t.serverInfo??{name:"buildbase-mcp",version:"1.0.0"};t.auth&&!t.auth.resourceMetadataUrl&&console.warn("[buildbase/mcp] auth is enabled but `auth.resourceMetadataUrl` is unset — 401 responses will carry no WWW-Authenticate/resource_metadata pointer, so MCP clients cannot discover your authorization server. Set it to your /.well-known/oauth-protected-resource URL.");const r=e=>e.trim().toLowerCase().replace(/\/+$/,""),s=t.allowedOrigins?new Set(t.allowedOrigins.map(r)):null,i=e=>!!e&&!!s&&s.has(r(e)),o=t.builtinTools??(!!t.buildbase&&"readonly"),a=t.maxRequestBytes??1048576;if(!1!==o&&!t.buildbase)throw new Error("builtinTools require a `buildbase` client — pass one to createMcpHandler, or set builtinTools: false.");const c=new Map;for(const e of I(o))c.set(e.name,e);const u=new Set;for(const e of t.tools??[]){if(!F.test(e.name))throw new Error(`Invalid MCP tool name: "${e.name}" (want ${String(F)})`);if(u.has(e.name))throw new Error(`Duplicate MCP tool name: "${e.name}"`);u.add(e.name),c.set(e.name,e)}if(t.builtinResources&&!t.buildbase)throw new Error("builtinResources requires a `buildbase` client — pass one to createMcpHandler.");const l=new Map,p=[];t.builtinResources&&(l.set("buildbase://profile",{uri:"buildbase://profile",name:"profile",title:"Your profile",description:"The authenticated user's BuildBase profile.",mimeType:"application/json",read:e=>e.bb.users.getProfile()}),l.set("buildbase://workspaces",{uri:"buildbase://workspaces",name:"workspaces",title:"Your workspaces",description:"The authenticated user's workspaces (id, name, roles).",mimeType:"application/json",read:e=>e.bb.workspace.list()}),p.push({uriTemplate:"buildbase://workspace/{workspaceId}",name:"workspace",title:"One workspace",description:"A single workspace: name, members, feature flags, quota snapshot.",mimeType:"application/json",read:(e,t,n)=>n.bb.workspace.get(e.workspaceId)}));for(const e of t.resources??[])l.set(e.uri,e);p.push(...t.resourceTemplates??[]);const h=new Map;for(const e of t.prompts??[]){if(!F.test(e.name))throw new Error(`Invalid MCP prompt name: "${e.name}" (want ${String(F)})`);if(h.has(e.name))throw new Error(`Duplicate MCP prompt name: "${e.name}"`);h.set(e.name,e)}const g=l.size>0||p.length>0,m=h.size>0,w=(e,t)=>{const n=new Set(t?.scopes??[]);return(e??[]).every(e=>n.has(e))};function y(e,n){const r=e?.sessionId??"";return{bb:t.buildbase?r?t.buildbase.withSession(r):S:v,auth:e??{sessionId:""},workspaceId:e?.workspaceId,custom:n}}function b(e,t){const n=[],r=e.replace(/[.*+?^$()|[\]\\]/g,e=>"\\"+e).replace(/\{([a-zA-Z0-9_]+)\}/g,(e,t)=>(n.push(t),"([^/]+)")),s=new RegExp(`^${r}$`).exec(t);if(!s)return null;const i={};return n.forEach((e,t)=>{try{i[e]=decodeURIComponent(s[t+1])}catch{i[e]=s[t+1]}}),i}function k(e,t,n){if("string"==typeof n)return{uri:e,mimeType:t??"text/plain",text:n};if(n&&"object"==typeof n){const r=n;if("string"==typeof r.text)return{uri:e,mimeType:"string"==typeof r.mimeType?r.mimeType:t??"text/plain",text:r.text};if("string"==typeof r.blob)return{uri:e,mimeType:"string"==typeof r.mimeType?r.mimeType:t??"application/octet-stream",blob:r.blob}}return{uri:e,mimeType:t??"application/json",text:JSON.stringify(n,null,2)}}const v=new Proxy({},{get(e,t){if("string"==typeof t)throw new Error(`No \`buildbase\` client configured — pass one to createMcpHandler to use bb.${t} in tools.`)}}),S=new Proxy({},{get(e,t){if("string"==typeof t)throw new Error(`This tool needs an authenticated BuildBase session, but the token carried none (bb.${t}). Re-authenticate.`)}}),E=new Map;function T(t){const n=E.get(t.name);if(n)return n;let r;try{r=z(t.inputSchema)?e.toJSONSchema(t.inputSchema,{target:"draft-2020-12"}):t.inputSchema}catch(e){U(e,{method:"tools/list",tool:t.name}),r={type:"object",additionalProperties:!0}}return E.set(t.name,r),r}function _(e){const t=new Set(e?.scopes??[]);return Array.from(c.values()).filter(e=>(e.requiredScopes??[]).every(e=>t.has(e)))}function U(e,n){try{t.onError?.(e instanceof Error?e:new Error(H(e)),n)}catch{}}function $(){if(t.auth&&t.auth.resourceMetadataUrl){const e=f({resourceMetadataUrl:t.auth.resourceMetadataUrl});return{status:e.status,headers:e.headers,body:e.body}}return G(401,{error:"unauthorized"})}const x=Array.isArray(t.cors)?new Set(t.cors.map(r)):null;async function A(e){const o=function(e){if(!1===t.cors)return{};const n=D(e.headers,"origin");let o;return o=x?n&&x.has(r(n))?n:null:s?i(n)?n:null:"*",o?{"Access-Control-Allow-Origin":o,"Access-Control-Allow-Methods":"POST, OPTIONS","Access-Control-Allow-Headers":"Content-Type, Authorization, MCP-Protocol-Version, Mcp-Session-Id, Last-Event-ID","Access-Control-Expose-Headers":"MCP-Protocol-Version, Mcp-Session-Id, WWW-Authenticate","Access-Control-Max-Age":"86400",..."*"!==o?{Vary:"Origin"}:{}}:{}}(e);if("OPTIONS"===e.method.toUpperCase())return{status:204,headers:o,body:""};const c=await async function(e){const r=e.method.toUpperCase();if(s){const t=D(e.headers,"origin");if(t&&!i(t))return G(403,{error:"origin_not_allowed"})}if("POST"!==r)return{status:405,headers:{"Content-Type":N,Allow:"POST, OPTIONS"},body:JSON.stringify({error:"method_not_allowed"})};if(a>0&&"string"==typeof e.body&&e.body.length>a)return G(413,{error:"payload_too_large"});let o=null;if(!1!==t.auth){const n=d(D(e.headers,"authorization"));if(!n)return $();try{o=await t.auth.verify(n,e)}catch(e){U(e,{method:"auth"}),o=null}if(!o)return $()}if(t.rateLimit){let n;try{n=await t.rateLimit(o,e)}catch(e){U(e,{method:"rateLimit"}),n=!1}if(!("boolean"==typeof n?n:n.ok)){const e="object"==typeof n?n.retryAfter:void 0;return{status:429,headers:{"Content-Type":N,...void 0!==e?{"Retry-After":String(e)}:{}},body:JSON.stringify({error:"rate_limited"})}}}let c=e.body;if("string"==typeof e.body)try{c=JSON.parse(e.body)}catch{return K(null,W,"Invalid JSON",400)}if(Array.isArray(c))return K(null,M,"Batch requests are not supported",400);if("object"!=typeof c||null===c)return K(null,M,"Expected a JSON-RPC request object",400);const u=c,f=u.id,v="string"==typeof u.method?u.method:null;if(!v)return K(f,M,"Missing method",400);if(null==f)return{status:202,headers:{"Content-Type":N},body:""};const S=u.params??{};switch(v){case"initialize":{const e=S.protocolVersion;return V(f,{protocolVersion:"string"==typeof e&&R.includes(e)?e:j,capabilities:{tools:{listChanged:!1},...g?{resources:{}}:{},...m?{prompts:{}}:{}},serverInfo:n,...t.instructions?{instructions:t.instructions}:{}})}case"ping":return V(f,{});case"tools/list":return V(f,{tools:_(o).map(e=>({name:e.name,description:e.description,inputSchema:T(e),...e.annotations?{annotations:e.annotations}:{},...e.icons?{icons:e.icons}:{}}))});case"tools/call":{const n="string"==typeof S.name?S.name:"",r=_(o).find(e=>e.name===n);if(!r)return K(f,q,`Unknown tool: ${n||"(missing name)"}`);let s,i=S.arguments??{};if(z(r.inputSchema)){const e=r.inputSchema.safeParse(i);if(!e.success){const t=e.error.issues.map(e=>`${e.path.join(".")||"(root)"}: ${e.message}`).join("; ");return V(f,{content:[{type:"text",text:`Invalid arguments for ${n}: ${t}`}],isError:!0})}i=e.data}if(t.context)try{s=await t.context(o,e)}catch(e){return U(e,{method:v,tool:n}),K(f,B,"Context initialization failed")}const a=y(o,s);try{const e=await r.execute(i,a);if("object"==typeof(E=e)&&null!==E&&Array.isArray(E.content)&&E.content.length>0&&E.content.every(C))return V(f,{content:e.content,...void 0!==e.structuredContent?{structuredContent:e.structuredContent}:{},isError:e.isError??!1});const t="object"==typeof e&&null!==e&&!Array.isArray(e);return V(f,{content:[{type:"text",text:"string"==typeof e?e:JSON.stringify(e,null,2)}],...t?{structuredContent:e}:{},isError:!1})}catch(e){U(e,{method:v,tool:n});const r=e instanceof Error?e:new Error(H(e));return V(f,{content:[{type:"text",text:t.formatToolError?t.formatToolError(r,{tool:n}):r.message}],isError:!0})}}case"resources/list":if(!g)break;return V(f,{resources:Array.from(l.values()).filter(e=>w(e.requiredScopes,o)).map(e=>({uri:e.uri,name:e.name,...e.title?{title:e.title}:{},...e.description?{description:e.description}:{},...e.mimeType?{mimeType:e.mimeType}:{},...e.icons?{icons:e.icons}:{}}))});case"resources/templates/list":if(!g)break;return V(f,{resourceTemplates:p.filter(e=>w(e.requiredScopes,o)).map(e=>({uriTemplate:e.uriTemplate,name:e.name,...e.title?{title:e.title}:{},...e.description?{description:e.description}:{},...e.mimeType?{mimeType:e.mimeType}:{},...e.icons?{icons:e.icons}:{}}))});case"resources/read":{if(!g)break;if("string"!=typeof S.uri||""===S.uri)return K(f,q,"Missing required parameter: uri");const n=S.uri;let r,s=null;const i=l.get(n);if(i){if(!w(i.requiredScopes,o))return K(f,J,"Resource not found",200,{uri:n});r=i.mimeType,s=async e=>i.read(e)}else for(const e of p){if(!w(e.requiredScopes,o))continue;const t=b(e.uriTemplate,n);if(t){r=e.mimeType,s=async r=>e.read(t,n,r);break}}if(!s)return K(f,J,"Resource not found",200,{uri:n});let a;if(t.context)try{a=await t.context(o,e)}catch(e){return U(e,{method:v}),K(f,B,"Context initialization failed")}try{const e=await s(y(o,a));return V(f,{contents:[k(n,r,e)]})}catch(e){return U(e,{method:v}),K(f,B,"Resource read failed",200,{uri:n})}}case"prompts/list":if(!m)break;return V(f,{prompts:Array.from(h.values()).filter(e=>w(e.requiredScopes,o)).map(e=>({name:e.name,...e.title?{title:e.title}:{},...e.description?{description:e.description}:{},...e.arguments?{arguments:e.arguments}:{},...e.icons?{icons:e.icons}:{}}))});case"prompts/get":{if(!m)break;const n="string"==typeof S.name?S.name:"",r=h.get(n);if(!r||!w(r.requiredScopes,o))return K(f,q,`Unknown prompt: ${n||"(missing name)"}`);const s="object"==typeof S.arguments&&null!==S.arguments?S.arguments:{},i={};for(const[e,t]of Object.entries(s))"string"==typeof t&&(i[e]=t);const a=(r.arguments??[]).filter(e=>e.required&&!(e.name in i)).map(e=>e.name);if(a.length)return K(f,q,`Missing required arguments: ${a.join(", ")}`);let c;if(t.context)try{c=await t.context(o,e)}catch(e){return U(e,{method:v}),K(f,B,"Context initialization failed")}try{const e=await r.get(i,y(o,c)),t="string"==typeof e?{messages:[{role:"user",content:P(e)}]}:Array.isArray(e)?{messages:e}:e,n=t.description??r.description;return V(f,{...n?{description:n}:{},messages:t.messages})}catch(e){return U(e,{method:v}),K(f,B,"Prompt rendering failed")}}}var E;return K(f,L,`Method not found: ${v}`)}(e);return Object.keys(o).length?{...c,headers:{...c.headers,...o}}:c}return{handle:A,fetch:async function(e){const t={};if(e.headers.forEach((e,n)=>{t[n]=e}),a>0){const t=Number(e.headers.get("content-length"));if(Number.isFinite(t)&&t>a)return new Response(JSON.stringify({error:"payload_too_large"}),{status:413,headers:{"Content-Type":N}})}const n="POST"===e.method.toUpperCase()?await e.text():void 0,r=await A({method:e.method,headers:t,body:n});return new Response(""===r.body?null:r.body,{status:r.status,headers:r.headers})},listTools:()=>Array.from(c.values()).map(e=>({name:e.name,description:e.description,...e.annotations?{annotations:e.annotations}:{}})),serverCard:e=>({name:n.name,version:n.version,endpoint:e.endpoint,transport:"streamable-http",capabilities:{tools:{listChanged:!1},...g?{resources:{}}:{},...m?{prompts:{}}:{}},...e.description?{description:e.description}:{},...e.documentationUrl?{documentationUrl:e.documentationUrl}:{}})}}function Y(e){return e}const Z=12,X=16;function ee(){const e=globalThis.crypto;if(!e?.subtle)throw new Error("WebCrypto is unavailable in this runtime — agent-auth session encryption requires globalThis.crypto.subtle (Node 18+, Bun, Deno, edge, browsers).");return e.subtle}const te=new Map;function ne(e){let t=te.get(e);return t||(t=(async()=>{const t=await ee().digest("SHA-256",(new TextEncoder).encode(`${e}:bb-session`));return ee().importKey("raw",t,{name:"AES-GCM"},!1,["encrypt","decrypt"])})(),te.set(e,t)),t}function re(e){if(!e)throw new Error("createSessionRefCrypto: missing secret");return{async encryptSessionRef(n){const r=globalThis.crypto.getRandomValues(new Uint8Array(Z)),s=await ne(e),i=new Uint8Array(await ee().encrypt({name:"AES-GCM",iv:r},s,(new TextEncoder).encode(n))),o=i.subarray(i.length-X),a=i.subarray(0,i.length-X),c=new Uint8Array(28+a.length);return c.set(r,0),c.set(o,Z),c.set(a,28),t(c)},async decryptSessionRef(t){try{const r=n(t);if(r.length<=28)return null;const s=r.slice(0,Z),i=r.subarray(Z,28),o=r.subarray(28),a=new Uint8Array(o.length+X);a.set(o,0),a.set(i,o.length);const c=await ne(e),u=await ee().decrypt({name:"AES-GCM",iv:s},c,a);return(new TextDecoder).decode(u)}catch{return null}}}}async function se(e){const{claims:t,secret:n}=e,r=e.expiresInSec??3600,s=t.resource&&t.resource.length?1===t.resource.length?t.resource[0]:t.resource:void 0,i=t.sessionId?await re(n).encryptSessionRef(t.sessionId):void 0;return{token:g({sub:t.id,userId:t.id,email:t.email,...t.name?{name:t.name}:{},...t.scope?{scope:t.scope}:{},...s?{aud:s}:{},...i?{sid:i}:{},...e.extraClaims},n,{expiresInSec:r}),expiresIn:r}}function ie(e,t,n){const r=globalThis.process?.env;"1"===r?.MCP_AUTH_DEBUG&&console.warn(`[buildbase/mcp-auth] audience rejected (${n}): received aud=${JSON.stringify(e)} expected one of ${JSON.stringify(t)}`)}function oe(e){const{secret:t}=e;if(!t)throw new Error("buildbaseAuth: missing secret");const n=re(t),r=e.resource?Array.isArray(e.resource)?e.resource:[e.resource]:[];let s=e.resourceMetadataUrl;if(!s&&r.length)try{const e=new URL(r[0]),t="/"===e.pathname?"":e.pathname.replace(/\/+$/,"");s=`${e.origin}/.well-known/oauth-protected-resource${t}`}catch{}return{resourceMetadataUrl:s,verify:async s=>{let i;try{i=p(s,t,{...e.verify})}catch{return null}if(r.length){const t=i.aud?Array.isArray(i.aud)?i.aud:[i.aud]:[];if(!t.length&&e.requireAudience)return ie(t,r,"token carries no aud claim"),null;if(t.length&&!t.some(e=>r.includes(e)))return ie(t,r,"aud does not include this resource"),null}const o="string"==typeof i.sid?await n.decryptSessionRef(i.sid):null,a=Array.isArray(i.scope)?i.scope.filter(e=>"string"==typeof e):"string"==typeof i.scope?i.scope.split(" ").filter(Boolean):void 0;return{sessionId:o??"",userId:"string"==typeof i.userId?i.userId:"string"==typeof i.sub?i.sub:void 0,workspaceId:"string"==typeof i.workspaceId?i.workspaceId:void 0,scopes:a,claims:i}}}}const ae=300,ce="/.well-known/oauth-protected-resource",ue="/.well-known/agent-skills",le="/.well-known/api-catalog",pe="/.well-known/mcp/server-card.json",de="/.well-known/agent-card.json",he="application/json",ge="application/linkset+json",me="text/markdown; charset=utf-8",fe="text/plain; charset=utf-8",we="application/xml; charset=utf-8",ye=["GPTBot","OAI-SearchBot","ChatGPT-User","ClaudeBot","Claude-User","Claude-SearchBot","PerplexityBot","Perplexity-User","Google-Extended","Applebot-Extended","CCBot","Bytespider","meta-externalagent","Amazonbot"];function be(e){return e.replace(/\/+$/,"")}function ke(e){return`public, max-age=${e}, s-maxage=${e}`}function ve(e){return"sha256:"+function(e){let t="";for(let n=0;n<e.length;n++)t+=e[n].toString(16).padStart(2,"0");return t}(i(o(e)))}const Se=function(){const e=new Map;return{get(t){const n=e.get(t);if(n){if(!(n.expiresAt<=Date.now()))return n.value;e.delete(t)}},set(t,n,r){e.set(t,{value:n,expiresAt:Date.now()+1e3*r})},delete(t){e.delete(t)},clear(){e.clear()}}}(),Ee=new Set;function Ie(e){return e.cache??Se}function Pe(e){let t;const n=new Promise((e,n)=>{t=setTimeout(()=>n(new Error("discovery cache timed out")),500)});return Promise.race([Promise.resolve(e),n]).finally(()=>clearTimeout(t))}async function Te(e,t){try{const n=await Pe(e.get(t));return null==n?{hit:!1}:{hit:!0,value:JSON.parse(n)}}catch{return{hit:!1}}}async function _e(e,t,n,r){try{await Pe(e.set(t,JSON.stringify(n),r)),e!==Se&&Ee.add(t)}catch{}}async function Ue(e,t,n,r){if(!r||r<=0)return e(t,n);const s=new AbortController,i=setTimeout(()=>s.abort(),r);try{return await e(t,{...n,signal:s.signal})}finally{clearTimeout(i)}}async function $e(e){const t=e.cacheTtlSeconds??ae,n=Ie(e),r=`buildbase:agent-readiness:${be(e.serverUrl)}::${e.orgId}`,s=await Te(n,r);if(s.hit)return s.value;const i=e.fetch??fetch,o=`${be(e.serverUrl)}/api/v1/public/${e.orgId}/agent-readiness`;let a={enabled:!1};try{const t=await Ue(i,o,{headers:{Accept:he}},e.fetchTimeoutMs??5e3);if(t.ok){const e=await t.json();e&&"object"==typeof e&&(a=e)}}catch{}return await _e(n,r,a,t),a}function Ce(e){let t="/";try{t=new URL(e).pathname}catch{t=e.startsWith("/")?e:`/${e}`}const n="/"===t?"":t.replace(/\/+$/,"");return ce+n}function xe(e){return e.path??`${ue}/${e.name}/SKILL.md`}function Ae(e){if(!e.security)return null;const t=(Array.isArray(e.security.contact)?e.security.contact:[e.security.contact]).map(e=>`Contact: ${e}`);return e.security.expires&&t.push(`Expires: ${e.security.expires}`),e.security.policy&&t.push(`Policy: ${e.security.policy}`),{status:200,contentType:fe,body:t.join("\n")+"\n",cacheControl:ke(e.cacheTtlSeconds??ae)}}function Oe(e){return e.endsWith(".json")||e.includes(".well-known/")?he:e.endsWith(".md")?me:e.endsWith(".xml")?we:fe}function Re(e){const t=e??{tools:!0},n={tools:!1,resources:!1,prompts:!1};for(const[e,r]of Object.entries(t))n[e]=!1!==r&&null!=r;return n}function je(e,t){return{status:200,contentType:he,body:JSON.stringify(e,null,2),cacheControl:ke(t.cacheTtlSeconds??ae)}}function Ne(e){return String(e).replace(/[\x00-\x1f\x7f]/g,"")}function Fe(e,t){const n=(Array.isArray(e.userAgent)?e.userAgent:[e.userAgent]).map(e=>`User-agent: ${Ne(e)}`);if(t){const e=[...void 0!==t.search?["search="+(t.search?"yes":"no")]:[],...void 0!==t.aiInput?["ai-input="+(t.aiInput?"yes":"no")]:[],...void 0!==t.aiTrain?["ai-train="+(t.aiTrain?"yes":"no")]:[]];e.length&&n.push(`Content-Signal: ${e.join(", ")}`)}for(const t of e.allow??[])n.push(`Allow: ${Ne(t)}`);for(const t of e.disallow??[])n.push(`Disallow: ${Ne(t)}`);return void 0!==e.crawlDelay&&n.push(`Crawl-delay: ${Ne(e.crawlDelay)}`),n.join("\n")}function Je(e){const t="number"==typeof e&&Number.isFinite(e)?e:.5;return String(Math.min(1,Math.max(0,t)))}function We(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function Me(e){const t=be(e.siteUrl),n=[`<${t}/llms.txt>; rel="describedby"; type="text/plain"`,`<${t}/.well-known/agent.json>; rel="describedby"; type="application/json"`];if(!1!==e.a2aCard&&n.push(`<${t}${de}>; rel="describedby"; type="application/json"`),e.sitemap||e.robots?.sitemaps?.length){const r=e.robots?.sitemaps?.[0]??`${t}/sitemap.xml`;n.push(`<${r}>; rel="sitemap"; type="application/xml"`)}return e.apiCatalog?.length&&n.push(`<${t}${le}>; rel="api-catalog"; type="${ge}"`),e.mcpServerCard&&n.push(`<${t}${pe}>; rel="mcp-server"; type="application/json"`),n.join(", ")}async function Le(e,t){const n=e.replace(/\/+$/,"")||e;if("/.well-known/agent.json"===n){return function(e,t){const n=be(e.siteUrl),r={llms_txt:"/llms.txt",sitemap:"/sitemap.xml",robots:"/robots.txt",oauth_protected_resource:ce};return t.authorizationServer?.metadataUrl&&(r.oauth_authorization_server=t.authorizationServer.metadataUrl,r.openid_configuration="/.well-known/openid-configuration"),(t.authorizationServer||e.authMd)&&(r.auth="/auth.md"),e.skills?.length&&(r.agent_skills=`${ue}/index.json`),e.apiCatalog?.length&&(r.api_catalog=le),e.mcpServerCard&&(r.mcp_server_card=pe),!1!==e.a2aCard&&(r.a2a_agent_card=de),e.llmsFullTxt&&(r.llms_full_txt="/llms-full.txt"),je({schema_version:"1.0",name:e.site.name,...e.site.description?{description:e.site.description}:{},url:n,...e.site.documentationUrl?{documentation_url:e.site.documentationUrl}:{},provider:e.site.provider??{name:e.site.name,url:n},capabilities:r,...e.site.contactEmail?{contact:{email:e.site.contactEmail}}:{}},e)}(t,await $e(t))}if(n===de)return function(e){if(!1===e.a2aCard)return null;const t=e.a2aCard??{},n=be(e.siteUrl),r=t.serviceUrl??n,s=t.transportProtocol??"http",i=t.skills??((e.skills??[]).length?(e.skills??[]).map(e=>({id:e.name,name:e.name,description:e.description,tags:["discovery"]})):[{id:"site-content",name:"Site content",description:`Read ${e.site.name}'s public content and machine-readable discovery documents (llms.txt, sitemap, API catalog).`,tags:["content"]}]);return je({protocolVersion:"0.3.0",name:t.name??e.site.name,version:t.version??"1.0.0",description:t.description??e.site.description??`${e.site.name} — agent-accessible web application.`,url:r,preferredTransport:s,supportedInterfaces:[{serviceUrl:r,transportProtocol:s}],provider:e.site.provider?{organization:e.site.provider.name,url:e.site.provider.url}:{organization:e.site.name,url:n},capabilities:t.capabilities??{streaming:!1,pushNotifications:!1},defaultInputModes:["text/plain","application/json"],defaultOutputModes:["text/plain","application/json"],skills:i,...e.site.documentationUrl?{documentationUrl:e.site.documentationUrl}:{}},e)}(t);if("/.well-known/http-message-signatures-directory"===n)return function(e){const t=e.webBotAuth?.keys;return t?.length?{status:200,contentType:"application/http-message-signatures-directory+json",body:JSON.stringify({keys:t},null,2),cacheControl:ke(e.cacheTtlSeconds??ae)}:null}(t);if("/.well-known/security.txt"===n)return Ae(t);if(n===`${ue}/index.json`)return function(e){const t=e.skills??[];if(!t.length)return null;const n=be(e.siteUrl);return je({$schema:"https://schemas.agentskills.io/discovery/0.2.0/schema.json",skills:t.map(e=>({name:e.name,type:e.type??"skill-md",description:e.description,url:`${n}${xe(e)}`,digest:ve(e.content)}))},e)}(t);if(n.startsWith(`${ue}/`)&&n.endsWith("SKILL.md"))return function(e,t){const n=(t.skills??[]).find(t=>xe(t)===e);return n?{status:200,contentType:"text/markdown; charset=utf-8",body:n.content,cacheControl:ke(t.cacheTtlSeconds??ae)}:null}(n,t);if("/.well-known/oauth-authorization-server"===n||"/.well-known/openid-configuration"===n){const e=(await $e(t)).authorizationServer;if(!e?.metadataUrl)return null;const n=await async function(e,t){const n=t.cacheTtlSeconds??ae,r=Ie(t),s=`buildbase:as-metadata:${e}`,i=await Te(r,s);if(i.hit)return i.value;const o=t.fetch??fetch;let a=null;try{const n=await Ue(o,e,{headers:{Accept:he}},t.fetchTimeoutMs??5e3);if(n.ok){const e=await n.json();e&&"object"==typeof e&&(a=e)}}catch{}return await _e(r,s,a,n),a}(e.metadataUrl,t);return je(n?n:{...e.issuer?{issuer:e.issuer}:{},oauth_authorization_server_metadata:e.metadataUrl},t)}if(n===le)return function(e){const t=e.apiCatalog??[];if(!t.length)return null;const n=t.map(e=>({anchor:e.anchor,...e.title?{title:e.title}:{},...e.serviceDesc?{"service-desc":[{href:e.serviceDesc}]}:{},...e.serviceDoc?{"service-doc":[{href:e.serviceDoc}]}:{},...e.status?{status:[{href:e.status}]}:{}}));return{status:200,contentType:ge,body:JSON.stringify({linkset:n},null,2),cacheControl:ke(e.cacheTtlSeconds??ae)}}(t);if(n===pe)return function(e){const t=e.mcpServerCard;return t?je({$schema:"https://modelcontextprotocol.io/schemas/server-card/v1.0",version:"1.0",protocolVersion:t.protocolVersion??"2025-11-25",serverInfo:{name:t.name,version:t.version},...t.description?{description:t.description}:{},transport:{type:t.transport??"streamable-http",url:t.endpoint},capabilities:Re(t.capabilities),...t.documentationUrl?{documentation_url:t.documentationUrl}:{}},e):null}(t);if("/.well-known/mcp.json"===n)return function(e){const t=e.mcpServerCard;if(!t)return null;const n=be(e.siteUrl);let r;try{r={type:"oauth2",protected_resource_metadata:`${new URL(t.endpoint).origin}${Ce(t.endpoint)}`}}catch{}return je({$schema:"https://modelcontextprotocol.io/schemas/mcp-discovery/v1.0",version:"1.0",servers:[{name:t.name,...t.description?{description:t.description}:{},transport:{type:t.transport??"streamable-http",url:t.endpoint},version:t.version,capabilities:Re(t.capabilities),...t.documentationUrl?{documentation_url:t.documentationUrl}:{},server_card:`${n}${pe}`,...r?{authentication:r}:{}}]},e)}(t);if(n.startsWith(ce)){const e=await $e(t);return function(e,t,n){const r=t.protectedResources??[];if(!r.length)return null;const s=e.replace(/\/+$/,"")||ce,i=n??`${be(t.serverUrl)}/org/${t.orgId}`,o=t.scopes?.map(e=>e.name),a=r.map(e=>{const n=e.resource??be(t.siteUrl),r=e.scopes??o;return{path:Ce(n),metadata:{resource:n,authorization_servers:[i],bearer_methods_supported:e.bearerMethods??["header"],...r?.length?{scopes_supported:r}:{},...e.documentationUrl?{resource_documentation:e.documentationUrl}:{}}}}),c=a.find(e=>e.path===s);return c?je(c.metadata,t):s===ce&&1===a.length?je(a[0].metadata,t):null}(n,t,e.authorizationServer?.issuer)}return null}async function qe(e,t){const n=e.replace(/\/+$/,"")||e,r=function(e,t){const n=t.extraPaths?.[e];if(void 0===n)return null;const r="string"==typeof n?{body:n}:n;return{status:r.status??200,contentType:r.contentType??Oe(e),body:r.body,cacheControl:r.cacheControl??ke(t.cacheTtlSeconds??ae)}}(n,t);return r||("/robots.txt"===n?function(e){const t=e.robots??{},n=be(e.siteUrl),r=t.policies??[{userAgent:"*",allow:["/"]}],s=t.aiBots??"allow",i="allow"===s?[{userAgent:[...ye],allow:["/"]}]:"deny"===s?[{userAgent:[...ye],disallow:["/"]}]:s,o=t.sitemaps??(e.sitemap?[`${n}/sitemap.xml`]:[]),a=[`# robots.txt — agent-ready. See ${n}/llms.txt and ${n}/.well-known/agent.json`,...r.map((e,n)=>Fe(e,0===n?t.contentSignals:void 0)),...i.map(e=>Fe(e)),...o.length?[o.map(e=>`Sitemap: ${Ne(e)}`).join("\n")]:[]];return{status:200,contentType:fe,body:a.join("\n\n")+"\n",cacheControl:ke(e.cacheTtlSeconds??ae)}}(t):"/llms-full.txt"===n?function(e){return e.llmsFullTxt?{status:200,contentType:fe,body:e.llmsFullTxt,cacheControl:ke(e.cacheTtlSeconds??ae)}:null}(t):"/sitemap.xml"===n?function(e){const t=e.sitemap?.urls;if(!t?.length)return null;const n=be(e.siteUrl),r='<?xml version="1.0" encoding="UTF-8"?>\n<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">\n'+t.map(e=>{const t="string"==typeof e?{loc:e}:e;return` <url>\n${[` <loc>${We(/^https?:\/\//.test(t.loc)?t.loc:`${n}${t.loc.startsWith("/")?"":"/"}${t.loc}`)}</loc>`,...t.lastmod?[` <lastmod>${We(t.lastmod)}</lastmod>`]:[],...t.changefreq?[` <changefreq>${We(String(t.changefreq))}</changefreq>`]:[],...void 0!==t.priority?[` <priority>${Je(t.priority)}</priority>`]:[]].join("\n")}\n </url>`}).join("\n")+"\n</urlset>\n";return{status:200,contentType:we,body:r,cacheControl:ke(e.cacheTtlSeconds??ae)}}(t):"/llms.txt"===n?function(e){return e.llmsTxt?{status:200,contentType:fe,body:e.llmsTxt,cacheControl:ke(e.cacheTtlSeconds??ae)}:null}(t):"/auth.md"===n?function(e,t){const n=ke(e.cacheTtlSeconds??ae);if(e.authMd)return{status:200,contentType:me,body:e.authMd,cacheControl:n};const r=t.authorizationServer;if(!r)return null;const s=`# Agent Authentication\n\n${e.site.name} supports AI-agent access via OAuth 2.0 (authorization code + PKCE).\n\n## Authorization server\n- Issuer: \`${r.issuer}\`\n- Metadata (RFC 8414): ${r.metadataUrl}\n\nFetch the metadata document above for the \`authorization_endpoint\`, \`token_endpoint\`, supported grant types / PKCE methods, and — when the app allows it — the dynamic client \`registration_endpoint\` (RFC 7591).\n\n## Protected resources (RFC 9728)\nSee \`/.well-known/oauth-protected-resource\`, which lists the resource, its supported scopes, and the authorization server(s) that can issue tokens for it.\n\n## How an agent authenticates\n1. Discover this document and \`/.well-known/oauth-protected-resource\`.\n2. Fetch the authorization-server metadata for the endpoints.\n3. Register a client (dynamic registration) or use a pre-issued client_id.\n4. Run the authorization-code flow with PKCE (S256), requesting the scopes and target \`resource\`.\n5. Exchange the code for an access token and call the API with \`Authorization: Bearer <token>\`.\n\nDocumentation: ${e.site.documentationUrl??e.siteUrl}\n`;return{status:200,contentType:me,body:s,cacheControl:n}}(t,await $e(t)):"/security.txt"===n?Ae(t):n.startsWith("/.well-known")?Le(n,t):null)}let Be=!0;function De(e,...t){Be&&function(){try{const e="undefined"!=typeof globalThis?globalThis:null;return"development"===e?.process?.env?.NODE_ENV}catch{return!1}}()&&console.error(e,...t)}function Ge(e,...t){console.error(e,...t)}function Ve(e,t){const n=AbortSignal.any;if("function"==typeof n)return n([e,t]);const r=new AbortController,s=e=>{r.signal.aborted||r.abort(e.reason)};for(const n of[e,t]){if(n.aborted){s(n);break}n.addEventListener("abort",()=>s(n),{once:!0})}return r.signal}async function Ke(e){const t=await e.text();if(!t)throw new Error("Empty response body");try{return JSON.parse(t)}catch(e){throw new Error(`Invalid JSON response: ${t.substring(0,100)}${t.length>100?"...":""}`)}}async function ze(e,t="Request failed"){if(!e.ok){let n,r=t;try{const t=await Ke(e);r=t.message||t.error||r,"string"==typeof t.code&&(n=t.code)}catch{r=function(e,t){const n={400:"Bad Request",401:"Unauthorized - Please check your session",403:"Forbidden - You do not have permission",404:"Resource not found",500:"Internal server error",502:"Bad Gateway",503:"Service unavailable"}[e.status]||e.statusText||t;return new Error(`${t} (${e.status}: ${n})`)}(e,t).message}throw Object.assign(new Error(r),{status:e.status,...n?{code:n}:{}})}try{return await Ke(e)}catch(e){if(e instanceof Error&&e.message.includes("Invalid JSON"))throw e;throw new Error("Failed to parse response as JSON")}}class He extends Error{constructor(e,t,n,r){super(e),this.code=t,this.context=n,this.originalError=r,this.name="SDKError","undefined"!=typeof Error&&"captureStackTrace"in Error&&Error.captureStackTrace(this,He)}}const Qe=new class{constructor(){this.config={enableConsoleLogging:!0,showUserNotifications:!1},this.listeners=new Set}subscribe(e){return this.listeners.add(e),()=>{this.listeners.delete(e)}}configure(e){this.config={...this.config,...e},void 0!==e.enableConsoleLogging&&function(e){void 0!==e.enableLogging&&(Be=e.enableLogging)}({enableLogging:e.enableConsoleLogging})}handleError(e,t={}){if(function(e){return e instanceof Error&&("AbortError"===e.name||"ERR_CANCELED"===e.code)}(e))return;const n=e instanceof Error?e:new He("string"==typeof e?e:"An unknown error occurred","UNKNOWN_ERROR",t),r=n instanceof He?n:new He(n.message,"SDK_ERROR",t,n);if(this.config.enableConsoleLogging&&De(`[SDK Error] ${t.component||"Unknown"}:`,{message:r.message,code:r.code,context:r.context,originalError:r.originalError,stack:r.stack}),this.config.onError)try{this.config.onError(r,t)}catch(e){Ge("[SDK Error Handler] Error in custom error callback:",e)}for(const e of this.listeners)try{e(r,t)}catch(e){Ge("[SDK Error Handler] Error in error listener:",e)}this.config.showUserNotifications&&this.notifyUser(r,t)}notifyUser(e,t){"undefined"!=typeof window&&window.dispatchEvent&&window.dispatchEvent(new CustomEvent("sdk-error",{detail:{error:e,context:t}}))}wrapAsync(e,t){return(...n)=>e(...n).catch(e=>{throw this.handleError(e,t),e})}wrapSync(e,t){return(...n)=>{try{return e(...n)}catch(e){throw this.handleError(e,t),e}}}};function Ye(e,t={}){Qe.handleError(e,t)}function Ze(e){if("undefined"==typeof window)return null;try{return localStorage.getItem(e)}catch(t){return Ye(t,{component:"storage",action:"getStorageItem",metadata:{key:e}}),null}}const Xe="saas-session-id",et="saas-device-id";function tt(){return function(){if("undefined"==typeof window)return null;try{return Ze(Xe)}catch(e){return Ye(e,{component:"auth-utils",action:"getSessionId",metadata:{key:Xe}}),null}}()}function nt(){const e=tt(),t={};e&&(t["x-session-id"]=e);const n=function(){if("undefined"==typeof window)return null;try{return Ze(et)??null}catch(e){return Ye(e,{component:"auth-utils",action:"getOrCreateDeviceId",metadata:{key:et}}),null}}();return n&&(t["x-device-id"]=n),t}const rt=new WeakSet,st=new Set(["GET","HEAD","OPTIONS","PUT","DELETE"]),it="SDK is not ready (missing serverUrl, version, or orgId)";class ot{constructor(e){this.serverUrl=e.serverUrl,this.version=e.version,this.orgId=e.orgId,this.requireOrgId=e.requireOrgId??!1,this.basePath=e.basePath??"public",this._sessionId=e.sessionId,this._timeout=e.timeout??3e4,this._maxRetries=e.maxRetries??0,this._debug=e.debug??!1,this._customHeaders=e.headers??{},this._onError=e.onError,this._onUnauthorized=e.onUnauthorized,this._fetch=e.fetch??globalThis.fetch}ensureReady(){if(!this.serverUrl?.trim()||!this.version)throw new Error(it);if(this.requireOrgId&&!this.orgId?.trim())throw new Error(it)}get baseUrl(){return this.ensureReady(),`${this.serverUrl}/api/${this.version}/${this.basePath}`}getAuthHeaders(){return this._sessionId?{"x-session-id":this._sessionId}:nt()}url(e){const t=e.startsWith("/")?e.slice(1):e;return`${this.baseUrl.endsWith("/")?this.baseUrl.slice(0,-1):this.baseUrl}/${t}`}buildHeaders(e){const t={...this._customHeaders,...this.getAuthHeaders()};return e.headers&&Object.assign(t,e.headers),null==e.body||t["Content-Type"]||(t["Content-Type"]="application/json"),t}reportError(e,t){rt.has(e)||(rt.add(e),this._onError?.(e,t))}async executeFetch(e,t){return this.executeFetchUrl(this.url(e),t,e)}static delay(e,t){return new Promise((n,r)=>{const s=()=>{clearTimeout(i),r(new DOMException("The operation was aborted.","AbortError"))};if(t?.aborted)return s();const i=setTimeout(()=>{t?.removeEventListener("abort",s),n()},e);t?.addEventListener("abort",s,{once:!0})})}async executeFetchUrl(e,t,n){const r=(t.method??"GET").toUpperCase(),s=n??e,i=this.buildHeaders(t),o={...t,headers:i},a=st.has(r);let c,u;if(this._timeout>0){u=new AbortController;const e=u;c=setTimeout(()=>e.abort(),this._timeout),o.signal=t.signal?Ve(t.signal,e.signal):e.signal}const l=e=>{if(u?.signal.aborted&&!t.signal?.aborted){const e=new Error(`Request timeout after ${this._timeout}ms: ${r} ${s}`);return this.reportError(e,{method:r,path:s}),e}return e},p=async t=>{try{if("function"!=typeof this._fetch)throw new Error("No fetch implementation available. Global fetch requires Node 18+; on older runtimes pass a `fetch` in the SDK config (e.g. from `undici` or `node-fetch`).");const n=this._fetch.bind(globalThis),s=await n(e,o);if(this._debug&&console.log(`[BuildBase] ${r} ${e} → ${s.status}`),401===s.status&&this._onUnauthorized&&this._onUnauthorized(),s.status>=500&&a&&t<this._maxRetries){const e=Math.min(1e3*Math.pow(2,t),1e4);return this._debug&&console.log(`[BuildBase] Retrying in ${e}ms (attempt ${t+1}/${this._maxRetries})`),await ot.delay(e,o.signal),p(t+1)}return s}catch(e){if(e instanceof Error&&"AbortError"===e.name)throw l(e);if(a&&t<this._maxRetries){const e=Math.min(1e3*Math.pow(2,t),1e4);this._debug&&console.log(`[BuildBase] Network error, retrying in ${e}ms (attempt ${t+1}/${this._maxRetries})`);try{await ot.delay(e,o.signal)}catch(e){throw l(e)}return p(t+1)}throw e instanceof Error&&this.reportError(e,{method:r,path:s}),e}};try{return await p(0)}finally{void 0!==c&&clearTimeout(c)}}async fetchJson(e,t={},n="Request failed"){this.ensureReady();try{const r=await this.executeFetch(e,t);return await ze(r,n)}catch(n){throw n instanceof Error&&this.reportError(n,{method:(t.method??"GET").toUpperCase(),path:e}),n}}async fetchResponse(e,t={}){return this.ensureReady(),this.executeFetch(e,t)}async fetchUnwrapped(e,t={},n="Request failed"){const r=await this.fetchResponse(e,t);return r.ok||await this.throwResponseError(r,n),this.unwrapResponse(r,n)}async fetchAbsoluteUrl(e,t={}){return this.ensureReady(),this.executeFetchUrl(e,t)}async fetchForeign(e,t={}){return this._fetch.call(globalThis,e,t)}async throwResponseError(e,t){let n=t;try{n=(await e.json()).message||n}catch{n=`${t} (${e.status}: ${e.statusText})`}throw Object.assign(new Error(n),{status:e.status})}apiPath(e,...t){return e.reduce((e,n,r)=>e+n+(r<t.length?encodeURIComponent(String(t[r])):""),"")}async unwrapResponse(e,t){const n=await e.json();if(void 0!==n.success){if(!n.success)throw new Error(n.message||t);return void 0!==n.data?n.data:n}return n}}class at extends ot{constructor(e){super(e)}async list(e){const t=await this.fetchJson("devices",{signal:e},"Failed to load devices");return t?.devices??[]}async rename(e,t,n){await this.fetchJson(this.apiPath`devices/${e}`,{method:"PATCH",body:JSON.stringify({name:t}),signal:n},"Failed to rename device")}async signOut(e,t){return this.fetchJson(this.apiPath`devices/${e}`,{method:"DELETE",signal:t},"Failed to sign out device")}async forget(e,t){return this.fetchJson(`${this.apiPath`devices/${e}`}?forget=true`,{method:"DELETE",signal:t},"Failed to forget device")}}class ct extends ot{constructor(e){super({...e,requireOrgId:!0})}async getVapidPublicKey(){return this.fetchJson("push/vapid-public-key")}async subscribe(e,t){await this.fetchJson("push/subscribe",{method:"POST",body:JSON.stringify({endpoint:e.endpoint,keys:e.keys,userAgent:t})})}async unsubscribe(e){await this.fetchJson("push/unsubscribe",{method:"DELETE",body:JSON.stringify({endpoint:e})})}}class ut extends ot{constructor(e){super(e)}async list(e){const t=await this.fetchJson("sessions",{signal:e},"Failed to load sessions");return t?.sessions??[]}async revoke(e,t){await this.fetchJson(this.apiPath`sessions/${e}`,{method:"DELETE",signal:t},"Failed to sign out session")}}class lt extends ot{constructor(e){super({...e,requireOrgId:!0})}async getSettings(e){return this.fetchJson(`${this.orgId}/settings`,{signal:e},"Failed to fetch settings")}}const pt={png:"image/png",jpg:"image/jpeg",jpeg:"image/jpeg",gif:"image/gif",webp:"image/webp",svg:"image/svg+xml"};function dt(e){if(e.type)return e.type;const t=(e.name??"").split(".").pop()?.toLowerCase()??"";return pt[t]??""}class ht extends ot{constructor(e){super(e)}async upload(e,t){const{purpose:n,signal:r}=t,s=await this.fetchJson("uploads",{method:"POST",body:JSON.stringify({purpose:n,name:e.name??"file",size:e.size,contentType:dt(e)}),signal:r},"Could not start the upload");let i;const o=new AbortController,a=setTimeout(()=>o.abort(),12e4);try{i=await this.fetchForeign(s.url,{method:"PUT",headers:s.headers,body:e,signal:r?Ve(r,o.signal):o.signal})}catch(e){if(r?.aborted)throw e;throw new Error("The upload to storage did not finish. Check the connection and try again.")}finally{clearTimeout(a)}if(!i.ok)throw Object.assign(new Error(`The upload to storage was refused (HTTP ${i.status}). Try again.`),{status:i.status});return this.fetchJson(this.apiPath`uploads/${s.uploadId}/complete`,{method:"POST",body:"{}",signal:r},"Could not finish the upload")}}class gt extends ot{constructor(e){super(e)}async getAttributes(e){const t=await this.fetchResponse("users/attributes",{signal:e});t.ok||await this.throwResponseError(t,"Failed to fetch user attributes");const n=await this.unwrapResponse(t,"Failed to fetch user attributes");return n&&"object"==typeof n&&!Array.isArray(n)?n:{}}async updateAttributes(e){return this.fetchJson("users/attributes",{method:"PATCH",body:JSON.stringify({attributes:e})},"Failed to update user attributes")}async updateAttribute(e,t){return this.fetchJson(this.apiPath`users/attributes/${e}`,{method:"PATCH",body:JSON.stringify({value:t})},"Failed to update user attribute")}async getFeatures(e){const t=await this.fetchResponse("users/features",{signal:e});t.ok||await this.throwResponseError(t,"Failed to fetch user features");const n=await this.unwrapResponse(t,"Failed to fetch user features");return"object"==typeof n&&null!==n?n:{}}}const mt={402:"SEAT_LIMIT_REACHED",404:"INVITATION_NOT_FOUND",409:"INVITATION_ALREADY_HANDLED",410:"INVITATION_EXPIRED",429:"INVITATION_RATE_LIMITED",502:"INVITATION_EMAIL_FAILED",503:"NO_SENDER_CONFIGURED"};function ft(e){return"number"==typeof e&&Number.isFinite(e)?e:void 0}function wt(e){return"string"==typeof e&&e?e:void 0}async function yt(e,t){let n=null;try{n=await e.json()}catch{n=null}return function(e,t,n){const r=t&&"object"==typeof t?t:{},s=wt(r.message)??wt(r.error)??n,i={status:e,code:wt(r.code)??mt[e]??`HTTP_${e}`,currentUserCount:ft(r.currentUserCount),limit:ft(r.limit),retryAfterSeconds:ft(r.retryAfterSeconds),invitedEmail:wt(r.invitedEmail),invitationId:wt(r.invitationId),invitationStatus:wt(r.status)};return Object.assign(new Error(s),i)}(e.status,n,t)}class bt extends ot{constructor(e){super({...e,requireOrgId:!0})}async getWorkspaces(e){return this.fetchJson("workspaces",{signal:e},"Failed to fetch workspaces")}async createWorkspace(e,t){try{return await this.fetchJson("workspaces",{method:"POST",body:JSON.stringify(e),signal:t},"Failed to create workspace")}catch(n){const r=n?.status;if(400===r&&e.trackingAttribution){const{trackingAttribution:n,...r}=e;return this.fetchJson("workspaces",{method:"POST",body:JSON.stringify(r),signal:t},"Failed to create workspace")}throw n}}async updateWorkspace(e,t,n){return this.fetchJson(this.apiPath`workspaces/${e}`,{method:"PUT",body:JSON.stringify(t),signal:n},"Failed to update workspace")}async deleteWorkspace(e,t){return this.fetchJson(this.apiPath`workspaces/${e}`,{method:"DELETE",signal:t},"Failed to delete workspace")}async getWorkspaceUsers(e,t){return this.fetchJson(this.apiPath`workspaces/${e}/users`,{signal:t},"Failed to fetch workspace users")}async addUser(e,t,n){return this.fetchJson(this.apiPath`workspaces/${e}/users/add`,{method:"POST",body:JSON.stringify(t),signal:n},"Failed to invite member")}async fetchInvitation(e,t={},n="Request failed"){const r=await this.fetchResponse(e,t);if(!r.ok)throw await yt(r,n);return ze(r,n)}async listInvitations(e,t){return this.fetchInvitation(this.apiPath`workspaces/${e}/invitations`,{signal:t},"Failed to fetch invitations")}async inviteMember(e,t,n){const r={email:t.email,role:t.role};return t.landingUrl&&(r.landingUrl=t.landingUrl),this.fetchInvitation(this.apiPath`workspaces/${e}/invitations`,{method:"POST",body:JSON.stringify(r),signal:n},"Failed to send invitation")}async resendInvitation(e,t,n){return this.fetchInvitation(this.apiPath`workspaces/${e}/invitations/${t}/resend`,{method:"POST",signal:n},"Failed to resend invitation")}async revokeInvitation(e,t,n){return this.fetchInvitation(this.apiPath`workspaces/${e}/invitations/${t}`,{method:"DELETE",signal:n},"Failed to revoke invitation")}async myInvitations(e){return this.fetchInvitation("invitations",{signal:e},"Failed to fetch your invitations")}async acceptInvitation(e,t,n){return this.fetchInvitation(this.apiPath`invitations/${e}/accept`,{method:"PATCH",signal:n,...t?.token?{body:JSON.stringify({token:t.token})}:{}},"Failed to accept invitation")}async declineInvitation(e,t){return this.fetchInvitation(this.apiPath`invitations/${e}/reject`,{method:"PATCH",signal:t},"Failed to decline invitation")}async previewInvitation(e,t){if(!this.orgId)throw new Error("orgId is required for previewInvitation");return this.fetchInvitation(this.apiPath`${this.orgId}/invitations/preview/${e}`,{signal:t},"Failed to load invitation")}async removeUser(e,t,n){return this.fetchJson(this.apiPath`workspaces/${e}/users/${t}`,{method:"DELETE",signal:n},"Failed to remove user")}async updateUser(e,t,n,r){return this.fetchJson(this.apiPath`workspaces/${e}/users/${t}`,{method:"PATCH",body:JSON.stringify(n),signal:r},"Failed to update user")}async updateSettings(e,t){return this.fetchJson("workspaces/settings",{method:"PATCH",body:JSON.stringify(e),signal:t},"Failed to update workspace settings")}async updateWorkspacePermissions(e,t,n){return this.fetchJson(this.apiPath`workspaces/${e}/permissions`,{method:"PATCH",body:JSON.stringify({permissions:t}),signal:n},"Failed to update workspace permissions")}async getMyPermissions(e,t){return this.fetchUnwrapped(this.apiPath`workspaces/${e}/permissions/me`,{signal:t},"Failed to fetch workspace permissions")}async getFeatures(e){return this.fetchJson("workspaces/features",{signal:e},"Failed to fetch features")}async updateFeature(e,t,n,r){return this.fetchJson(this.apiPath`workspaces/${e}/features`,{method:"PATCH",body:JSON.stringify({features:{[t]:n}}),signal:r},"Failed to update feature")}async getWorkspace(e,t){return this.fetchJson(this.apiPath`workspaces/${e}`,{signal:t},"Failed to fetch workspace")}async getProfile(e){return this.fetchJson("profile",{signal:e},"Failed to fetch profile")}async updateUserProfile(e,t){return this.fetchJson("profile",{method:"PATCH",body:JSON.stringify(e),signal:t},"Failed to update user profile")}async getPasskeys(e){const t=await this.fetchJson("passkeys",{signal:e},"Failed to fetch passkeys");return t?.passkeys??[]}async renamePasskey(e,t,n){await this.fetchJson(this.apiPath`passkeys/${e}`,{method:"PATCH",body:JSON.stringify({name:t}),signal:n},"Failed to rename passkey")}async deletePasskey(e,t){await this.fetchJson(this.apiPath`passkeys/${e}`,{method:"DELETE",signal:t},"Failed to remove passkey")}async getCurrentSubscription(e,t){return this.fetchUnwrapped(this.apiPath`workspaces/${e}/subscription`,{signal:t},"Failed to fetch subscription")}async getPlanGroup(e,t){return this.fetchUnwrapped(this.apiPath`workspaces/${e}/subscription/plan-group`,{signal:t},"Failed to fetch plan group")}async getPlanGroupByVersion(e,t,n){return this.fetchUnwrapped(this.apiPath`workspaces/${e}/subscription/plan-group`+`?groupVersionId=${encodeURIComponent(t)}`,{signal:n},"Failed to fetch plan group version")}async getPlanGroupVersions(e,t){return this.fetchUnwrapped(this.apiPath`workspaces/${e}/subscription/plan-group/versions`,{signal:t},"Failed to fetch plan group versions")}async getPublicPlans(e,t){if(!this.orgId)throw new Error("orgId is required for getPublicPlans");return this.fetchUnwrapped(this.apiPath`${this.orgId}/plans/${encodeURIComponent(e)}`,{signal:t},"Failed to fetch plans")}async getPublicCreditPackages(e){if(!this.orgId)throw new Error("orgId is required for getPublicCreditPackages");return this.fetchUnwrapped(this.apiPath`${this.orgId}/credit-packages`,{signal:e},"Failed to fetch credit packages")}async getPlanGroupVersion(e,t){return this.fetchUnwrapped(this.apiPath`plan-group-versions/${e}`,{signal:t},"Failed to fetch plan group version")}async createCheckoutSession(e,t,n){return this.fetchUnwrapped(this.apiPath`workspaces/${e}/subscription/checkout`,{method:"POST",body:JSON.stringify(t),signal:n},"Failed to create checkout session")}async selectFreePlan(e,t,n){return this.fetchUnwrapped(this.apiPath`workspaces/${e}/subscription/select-free-plan`,{method:"POST",body:JSON.stringify({planVersionId:t}),signal:n},"Failed to select free plan")}async updateSubscription(e,t,n){return this.fetchUnwrapped(this.apiPath`workspaces/${e}/subscription`,{method:"PATCH",body:JSON.stringify(t),signal:n},"Failed to update subscription")}async createBillingPortalSession(e,t,n){return this.fetchJson(this.apiPath`workspaces/${e}/subscription/billing-portal`,{method:"POST",body:JSON.stringify(t?{returnUrl:t}:{}),signal:n})}async listInvoices(e,t=10,n,r){const s=new URLSearchParams;return s.append("limit",t.toString()),n&&s.append("starting_after",n),this.fetchUnwrapped(this.apiPath`workspaces/${e}/subscription/invoices`+`?${s.toString()}`,{signal:r},"Failed to fetch invoices")}async getInvoice(e,t,n){return this.fetchUnwrapped(this.apiPath`workspaces/${e}/subscription/invoices/${t}`,{signal:n},"Failed to fetch invoice")}async cancelSubscriptionAtPeriodEnd(e,t){return this.fetchUnwrapped(this.apiPath`workspaces/${e}/subscription/cancel-at-period-end`,{method:"POST",signal:t},"Failed to cancel subscription")}async resumeSubscription(e,t){return this.fetchUnwrapped(this.apiPath`workspaces/${e}/subscription/resume`,{method:"POST",signal:t},"Failed to resume subscription")}async recordUsage(e,t,n){return this.fetchUnwrapped(this.apiPath`workspaces/${e}/subscription/usage`,{method:"POST",body:JSON.stringify(t),signal:n},"Failed to record usage")}async recordUsageBatch(e,t,n){return this.fetchUnwrapped(this.apiPath`workspaces/${e}/subscription/usage/batch`,{method:"POST",body:JSON.stringify(t),signal:n},"Failed to record batch usage")}async getQuotaUsageStatus(e,t,n){return this.fetchUnwrapped(this.apiPath`workspaces/${e}/subscription/usage/status`+`?quotaSlug=${encodeURIComponent(t)}`,{signal:n},"Failed to fetch quota usage status")}async getAllQuotaUsage(e,t){return this.fetchUnwrapped(this.apiPath`workspaces/${e}/subscription/usage/all`,{signal:t},"Failed to fetch all quota usage")}async getUsageLogs(e,t,n){const r=new URLSearchParams;t?.quotaSlug&&r.append("quotaSlug",t.quotaSlug),t?.from&&r.append("from",t.from),t?.to&&r.append("to",t.to),t?.source&&r.append("source",t.source),t?.page&&r.append("page",t.page.toString()),t?.limit&&r.append("limit",t.limit.toString());const s=r.toString(),i=this.apiPath`workspaces/${e}/subscription/usage/logs`+(s?`?${s}`:"");return this.fetchUnwrapped(i,{signal:n},"Failed to fetch usage logs")}async sendNotification(e,t,n,r,s){const i={event:t};return n&&(i.userId=n),r&&(i.data=r),this.fetchJson(this.apiPath`workspaces/${e}/notifications/send`,{method:"POST",body:JSON.stringify(i),signal:s},"Failed to send notification")}async getNotificationEvents(e,t){return this.fetchJson(this.apiPath`workspaces/${e}/notification-events`,{signal:t},"Failed to fetch notification events")}async getNotificationPreferences(e,t){return(await this.fetchJson(this.apiPath`workspaces/${e}/notification-preferences`,{signal:t},"Failed to fetch notification preferences")).notificationPreferences??{}}async updateNotificationPreferences(e,t,n){return(await this.fetchJson(this.apiPath`workspaces/${e}/notification-preferences`,{method:"PATCH",body:JSON.stringify({notificationPreferences:t}),signal:n},"Failed to update notification preferences")).notificationPreferences??{}}async getMyNotificationPreferences(e,t){const n=await this.fetchJson(this.apiPath`workspaces/${e}/notification-preferences/me`,{signal:t},"Failed to fetch your notification preferences");return{defaults:n?.defaults??{},mine:n?.mine??{}}}async updateMyNotificationPreferences(e,t,n){const r=await this.fetchJson(this.apiPath`workspaces/${e}/notification-preferences/me`,{method:"PATCH",body:JSON.stringify({notificationPreferences:t}),signal:n},"Failed to update your notification preferences");return{defaults:r?.defaults??{},mine:r?.mine??{}}}async getCreditBalance(e,t){return this.fetchUnwrapped(this.apiPath`workspaces/${e}/credits`,{signal:t},"Failed to fetch credit balance")}async consumeCredits(e,t,n){const r=await this.fetchResponse(this.apiPath`workspaces/${e}/credits/consume`,{method:"POST",body:JSON.stringify(t),signal:n});if(!r.ok){if(402===r.status){const e=await r.json().catch(()=>({})),t=new Error(e.message||"Insufficient credits");throw t.available=e.available,t.requested=e.requested,t.code="INSUFFICIENT_CREDITS",t}await this.throwResponseError(r,"Failed to consume credits")}return this.unwrapResponse(r,"Failed to consume credits")}async purchaseCredits(e,t,n){return this.fetchUnwrapped(this.apiPath`workspaces/${e}/credits/purchase`,{method:"POST",body:JSON.stringify(t),signal:n},"Failed to create credit purchase checkout")}async getCreditPackages(e,t){const n=await this.fetchUnwrapped(this.apiPath`workspaces/${e}/credits/packages`,{signal:t},"Failed to fetch credit packages");return n.docs??n}async getCreditTransactions(e,t,n){const r=new URLSearchParams;t?.type&&r.append("type",t.type),t?.page&&r.append("page",t.page.toString()),t?.limit&&r.append("limit",t.limit.toString());const s=r.toString(),i=this.apiPath`workspaces/${e}/credits/transactions`+(s?`?${s}`:"");return this.fetchUnwrapped(i,{signal:n},"Failed to fetch credit transactions")}async getCreditBuckets(e,t,n){const r=new URLSearchParams;t?.status&&r.append("status",t.status),t?.source&&r.append("source",t.source),t?.page&&r.append("page",t.page.toString()),t?.limit&&r.append("limit",t.limit.toString());const s=r.toString(),i=this.apiPath`workspaces/${e}/credits/buckets`+(s?`?${s}`:"");return this.fetchUnwrapped(i,{signal:n},"Failed to fetch credit buckets")}async getExpiringCredits(e,t,n){const r=t?`?days=${t}`:"";return this.fetchUnwrapped(this.apiPath`workspaces/${e}/credits/expiring`+r,{signal:n},"Failed to fetch expiring credits")}}const kt={WORKSPACE_SETTINGS_VIEW:"workspace:settings:view",WORKSPACE_SETTINGS_EDIT:"workspace:settings:edit",WORKSPACE_DELETE:"workspace:delete",WORKSPACE_MEMBERS_VIEW:"workspace:members:view",WORKSPACE_MEMBERS_INVITE:"workspace:members:invite",WORKSPACE_MEMBERS_REMOVE:"workspace:members:remove",WORKSPACE_MEMBERS_ROLE_CHANGE:"workspace:members:role-change",WORKSPACE_FEATURES_VIEW:"workspace:features:view",WORKSPACE_FEATURES_EDIT:"workspace:features:edit",WORKSPACE_BILLING_VIEW:"workspace:billing:view",WORKSPACE_BILLING_MANAGE:"workspace:billing:manage",WORKSPACE_USAGE_VIEW:"workspace:usage:view",WORKSPACE_USAGE_RECORD:"workspace:usage:record"},vt=Object.values(kt),St={admin:vt.filter(e=>e!==kt.WORKSPACE_DELETE),editor:[kt.WORKSPACE_SETTINGS_VIEW,kt.WORKSPACE_MEMBERS_VIEW,kt.WORKSPACE_FEATURES_VIEW,kt.WORKSPACE_BILLING_VIEW,kt.WORKSPACE_USAGE_VIEW,kt.WORKSPACE_USAGE_RECORD],viewer:[kt.WORKSPACE_SETTINGS_VIEW,kt.WORKSPACE_MEMBERS_VIEW]};function Et(e){const t=new Set;for(const n of Object.values(e))for(const e of n)t.add(e);return Array.from(t)}function It(e){const{userId:t,workspace:n,settings:r,appPermissions:s}=e;if(!n||!t)return new Set;if(function(e,t){if(!t)return!1;const n=(r=e.createdBy)?"string"==typeof r?r:"object"==typeof r&&"_id"in r&&"string"==typeof r._id?r._id:null:null;var r;return null!==n&&n===t}(n,t)){const e=new Set(vt);if(s)for(const t of Et(s))e.add(t);if(n.permissions)for(const t of Et(n.permissions))e.add(t);if(r?.workspace?.permissions)for(const t of Et(r.workspace.permissions))e.add(t);return e}const i=e.workspaceRole??function(e,t){if(!t||!e.users||!Array.isArray(e.users))return null;const n=e.users.find(e=>"string"==typeof e?e===t:"object"==typeof e&&null!==e&&"_id"in e&&e._id===t);return n&&"object"==typeof n&&"role"in n&&"string"==typeof n.role?n.role:null}(n,t);return i?function(e,t,n={}){const{workspace:r,settings:s,appPermissions:i}=t;if(!r)return new Set;const o=r.permissions,a=s?.workspace?.permissions,c=e=>e.filter(e=>e.startsWith("workspace:")),u=e=>e.filter(e=>!e.startsWith("workspace:")),l=e=>!!o&&e in o,p=e=>!!a&&e in a,d=e=>l(e)||p(e)||e in St;let h,g=e;if(!d(e)){const e=s?.workspace?.defaultRole;if(!e||"admin"===e||!d(e))return new Set;g=e}h=l(g)?c(o[g]):p(g)?c(a[g]):St[g]??[];const m=new Set(h),f=new Set((s?.workspace?.customPermissions??[]).map(e=>e.key)),w=i?.[g]?u(i[g]).filter(e=>!f.has(e)):[];let y;y=l(g)?u(o[g]):p(g)?[...u(a[g]),...w]:i?.[g]?u(i[g]):[];for(const e of y)m.add(e);if("admin"===g){for(const e of St.admin)m.add(e);for(const e of f)m.add(e);if(i)for(const e of u(Et(i)))m.add(e)}!1!==n.applyRestrictions&&function(e,t,n){if(!n?.workspace)return;const{canInviteMembers:r}=n.workspace;(!1===r||"admin-only"===r&&"admin"!==t)&&e.delete(kt.WORKSPACE_MEMBERS_INVITE)}(m,g,s);return m}(i,e):new Set}function Pt(e){const{serverUrl:t,orgId:n,version:r="v1",region:s,getSessionId:i,timeout:o,maxRetries:a,debug:c,headers:u,onError:l,fetch:p}=e;if(!t)throw new Error("BuildBase: serverUrl is required");if(!n)throw new Error("BuildBase: orgId is required");const d={...void 0!==o&&{timeout:o},...void 0!==a&&{maxRetries:a},...void 0!==c&&{debug:c},...u&&{headers:u},...l&&{onError:l},...p&&{fetch:p}},h=e=>{const s={serverUrl:t,version:r,orgId:n,sessionId:e,...d};return{workspace:new bt(s),user:new gt(s),settings:new lt(s),push:new ct(s),devices:new at(s),uploads:new ht(s),sessions:new ut(s)}},g=new bt({serverUrl:t,version:r,orgId:n,...d}),m=e=>({workspace:{list:async()=>(await e()).workspace.getWorkspaces(),get:async t=>(await e()).workspace.getWorkspace(t),create:async t=>(await e()).workspace.createWorkspace(t),update:async(t,n)=>(await e()).workspace.updateWorkspace(t,n),delete:async t=>(await e()).workspace.deleteWorkspace(t),permissions:async t=>(await e()).workspace.getMyPermissions(t),can:async(t,n)=>{const{permissions:r}=await(await e()).workspace.getMyPermissions(t),s=new Set(r);return(Array.isArray(n)?n:[n]).every(e=>s.has(e))}},invitations:{list:async t=>(await e()).workspace.listInvitations(t),create:async(t,n,r,s)=>(await e()).workspace.inviteMember(t,{email:n,role:r,landingUrl:s}),resend:async(t,n)=>(await e()).workspace.resendInvitation(t,n),revoke:async(t,n)=>(await e()).workspace.revokeInvitation(t,n)},users:{list:async t=>(await e()).workspace.getWorkspaceUsers(t),invite:async(t,n,r)=>(await e()).workspace.addUser(t,{email:n,role:r}),remove:async(t,n)=>(await e()).workspace.removeUser(t,n),updateRole:async(t,n,r)=>(await e()).workspace.updateUser(t,n,{role:r}),getProfile:async()=>(await e()).workspace.getProfile(),updateProfile:async t=>(await e()).workspace.updateUserProfile(t)},subscription:{get:async t=>(await e()).workspace.getCurrentSubscription(t),checkout:async(t,n)=>(await e()).workspace.createCheckoutSession(t,n),update:async(t,n)=>(await e()).workspace.updateSubscription(t,n),cancel:async t=>(await e()).workspace.cancelSubscriptionAtPeriodEnd(t),resume:async t=>(await e()).workspace.resumeSubscription(t),getBillingPortalUrl:async(t,n)=>(await e()).workspace.createBillingPortalSession(t,n)},plans:{getGroup:async t=>(await e()).workspace.getPlanGroup(t),getVersions:async t=>(await e()).workspace.getPlanGroupVersions(t),getPublic:e=>g.getPublicPlans(e),getVersion:e=>g.getPlanGroupVersion(e)},invoices:{list:async(t,n,r)=>(await e()).workspace.listInvoices(t,n,r),get:async(t,n)=>(await e()).workspace.getInvoice(t,n)},usage:{record:async(t,n)=>(await e()).workspace.recordUsage(t,n),recordBatch:async(t,n)=>(await e()).workspace.recordUsageBatch(t,n),getQuota:async(t,n)=>(await e()).workspace.getQuotaUsageStatus(t,n),getAll:async t=>(await e()).workspace.getAllQuotaUsage(t),getLogs:async(t,n)=>(await e()).workspace.getUsageLogs(t,n)},settings:{get:async()=>(await e()).settings.getSettings()},features:{list:async()=>(await e()).workspace.getFeatures(),update:async(t,n,r)=>(await e()).workspace.updateFeature(t,n,r)},notification:{send:async(t,n,r,s)=>(await e()).workspace.sendNotification(t,n,r,s)},credits:{getBalance:async t=>(await e()).workspace.getCreditBalance(t),consume:async(t,n)=>(await e()).workspace.consumeCredits(t,n),purchase:async(t,n)=>(await e()).workspace.purchaseCredits(t,n),getPackages:async t=>(await e()).workspace.getCreditPackages(t),getTransactions:async(t,n)=>(await e()).workspace.getCreditTransactions(t,n),getBuckets:async(t,n)=>(await e()).workspace.getCreditBuckets(t,n),getExpiring:async(t,n)=>(await e()).workspace.getExpiringCredits(t,n),getPublicPackages:()=>g.getPublicCreditPackages()},permissions:{check:async(t,n,r)=>{const s=await e(),[i,o,a]=await Promise.all([s.workspace.getWorkspace(t),s.settings.getSettings(),s.workspace.getWorkspaceUsers(t)]),c=a.find(e=>("string"==typeof e.user?e.user:e.user._id)===n);return function(e,t){const n=It(t);return Array.isArray(e)?e.every(e=>n.has(e)):n.has(e)}(r,{userId:n,workspaceRole:c?.role??null,workspace:i,settings:o})},resolve:async(t,n)=>{const r=await e(),[s,i,o]=await Promise.all([r.workspace.getWorkspace(t),r.settings.getSettings(),r.workspace.getWorkspaceUsers(t)]),a=o.find(e=>("string"==typeof e.user?e.user:e.user._id)===n);return It({userId:n,workspaceRole:a?.role??null,workspace:s,settings:i})}},devices:{list:async()=>(await e()).devices.list(),rename:async(t,n)=>(await e()).devices.rename(t,n),signOut:async t=>(await e()).devices.signOut(t),forget:async t=>(await e()).devices.forget(t)},sessions:{list:async()=>(await e()).sessions.list(),revoke:async t=>(await e()).sessions.revoke(t)}}),f=m(async()=>h(await(async()=>{if(!i)throw new Error("BuildBase: getSessionId callback is required for authenticated calls. Pass it in BuildBase({ getSessionId: ... }) or use withSession(id) / client.forSession(id).");const e=await i();if(!e)throw new Error("BuildBase: Not authenticated (getSessionId returned null)");return e})()));return{...void 0!==s&&{region:s},auth:async()=>{if(!i)return null;const e=await i();return e?{sessionId:e}:null},withSession:e=>{const t=h(e);return m(async()=>t)},client:{forSession:h},...f}}function Tt(e){const t=be(e.siteUrl),n=e.mcp?.path??"/api/mcp",r=`${t}${n.startsWith("/")?n:`/${n}`}`,s=e.mcp?.serverInfo??{name:e.site.name,version:"1.0.0"},i=`${t}/mcp`,o=Array.from(new Set([i,r])),a=e.mcp?.auth??(e.secret?oe({secret:e.secret,resource:o,resourceMetadataUrl:`${t}/.well-known/oauth-protected-resource/mcp`,requireAudience:!0}):void 0);if(void 0===a)throw new Error("createAgentStack: pass `secret` (the app token-signing secret) to derive auth, or set `mcp.auth` yourself (`false` disables auth — local development only).");const c=Q({buildbase:e.mcp?.buildbase??Pt({serverUrl:e.serverUrl,orgId:e.orgId}),serverInfo:s,auth:a,tools:e.mcp?.tools,builtinTools:e.mcp?.builtinTools??"readonly",...e.mcp?.handler}),u={serverUrl:e.serverUrl,orgId:e.orgId,siteUrl:e.siteUrl,site:e.site,mcpServerCard:c.serverCard({endpoint:r,...e.site.description?{description:e.site.description}:{},...e.site.documentationUrl?{documentationUrl:e.site.documentationUrl}:{}}),...e.scopes?{scopes:e.scopes}:{},protectedResources:o.map(t=>({resource:t,...e.mcp?.scopes?.length?{scopes:e.mcp.scopes}:{},...e.site.documentationUrl?{documentationUrl:e.site.documentationUrl}:{}})).concat([{resource:t,...e.site.documentationUrl?{documentationUrl:e.site.documentationUrl}:{}}]),apiCatalog:[{anchor:r,title:`${e.site.name} MCP server`,serviceDesc:`${t}/.well-known/mcp/server-card.json`}],...e.discovery},l={"Access-Control-Allow-Origin":"*","Access-Control-Allow-Methods":"GET, OPTIONS"};const p=e=>c.fetch(e);return{mcp:c,mcpEndpoint:r,config:u,linkHeader:Me(u),resolvePath:e=>qe(e,u),serveAgentPath:async function(e){if("OPTIONS"===e.method.toUpperCase())return new Response(null,{status:204,headers:l});const t=await qe(new URL(e.url).pathname,u);return t?new Response(t.body,{status:t.status,headers:{"Content-Type":t.contentType,"Cache-Control":t.cacheControl,...t.vary?{Vary:t.vary}:{},...l}}):new Response(JSON.stringify({error:"not_found"}),{status:404,headers:{"Content-Type":"application/json",...l}})},routes:{GET:p,POST:p,DELETE:p,OPTIONS:p}}}export{u as AppBridgeError,f as bearerChallenge,oe as buildbaseAuth,E as builtinMcpTools,Tt as createAgentStack,Q as createMcpHandler,re as createSessionRefCrypto,O as defineMcpPrompt,x as defineMcpResource,A as defineMcpResourceTemplate,Y as defineMcpTool,d as extractBearerToken,_ as mcpAudio,$ as mcpEmbeddedResource,T as mcpImage,U as mcpResourceLink,P as mcpText,se as mintAgentToken,I as selectBuiltinTools,g as signClientJwt,p as verifyClientJwt};
|
|
1
|
+
import{z as e}from"zod";function t(e){let t="";for(let n=0;n<e.length;n++)t+=String.fromCharCode(e[n]);return btoa(t).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function n(e){const t=e.replace(/-/g,"+").replace(/_/g,"/"),n=t.length%4==0?"":"=".repeat(4-t.length%4),r=atob(t+n),s=new Uint8Array(r.length);for(let e=0;e<r.length;e++)s[e]=r.charCodeAt(e);return s}const r=new Uint32Array([1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298]),s=(e,t)=>e>>>t|e<<32-t;function i(e){let t=1779033703,n=3144134277,i=1013904242,o=2773480762,a=1359893119,c=2600822924,u=528734635,l=1541459225;const d=e.length,p=d+1,h=p+(56-p%64+64)%64+8,g=new Uint8Array(h);g.set(e,0),g[d]=128;const f=8*d,m=Math.floor(f/4294967296),y=f>>>0;g[h-8]=m>>>24&255,g[h-7]=m>>>16&255,g[h-6]=m>>>8&255,g[h-5]=255&m,g[h-4]=y>>>24&255,g[h-3]=y>>>16&255,g[h-2]=y>>>8&255,g[h-1]=255&y;const w=new Uint32Array(64);for(let e=0;e<h;e+=64){for(let t=0;t<16;t++){const n=e+4*t;w[t]=g[n]<<24|g[n+1]<<16|g[n+2]<<8|g[n+3]}for(let e=16;e<64;e++){const t=s(w[e-15],7)^s(w[e-15],18)^w[e-15]>>>3,n=s(w[e-2],17)^s(w[e-2],19)^w[e-2]>>>10;w[e]=w[e-16]+t+w[e-7]+n>>>0}let d=t,p=n,h=i,f=o,m=a,y=c,b=u,k=l;for(let e=0;e<64;e++){const t=k+(s(m,6)^s(m,11)^s(m,25))+(m&y^~m&b)+r[e]+w[e]>>>0,n=d&p^d&h^p&h;k=b,b=y,y=m,m=f+t>>>0,f=h,h=p,p=d,d=t+((s(d,2)^s(d,13)^s(d,22))+n>>>0)>>>0}t=t+d>>>0,n=n+p>>>0,i=i+h>>>0,o=o+f>>>0,a=a+m>>>0,c=c+y>>>0,u=u+b>>>0,l=l+k>>>0}const b=new Uint8Array(32),k=[t,n,i,o,a,c,u,l];for(let e=0;e<8;e++)b[4*e]=k[e]>>>24&255,b[4*e+1]=k[e]>>>16&255,b[4*e+2]=k[e]>>>8&255,b[4*e+3]=255&k[e];return b}function o(e){return(new TextEncoder).encode(e)}function a(e,t){let n=e;n.length>64&&(n=i(n));const r=new Uint8Array(64),s=new Uint8Array(64);for(let e=0;e<64;e++){const t=e<n.length?n[e]:0;r[e]=54^t,s[e]=92^t}const o=i(c(r,t));return i(c(s,o))}function c(e,t){const n=new Uint8Array(e.length+t.length);return n.set(e,0),n.set(t,e.length),n}class u extends Error{constructor(e,t){super(t),this.name="AppBridgeError",this.code=e}}function l(e){const t=JSON.parse((new TextDecoder).decode(n(e)));if("object"!=typeof t||null===t||Array.isArray(t))throw new Error("JWT segment is not a JSON object");return t}function d(e,t,r={}){const s=r.clockToleranceSec??60,i=r.requireExp??!0;if(!e||!t)throw new u("invalid_token","Missing token or client secret");const c=e.split(".");if(3!==c.length)throw new u("invalid_token","Malformed JWT");const[d,p,h]=c;let g,f;try{g=l(d),f=l(p)}catch{throw new u("invalid_token","Unreadable JWT segments")}if("HS256"!==g.alg)throw new u("invalid_algorithm",`Unexpected JWT alg: ${String(g.alg)}`);const m=a(o(t),o(`${d}.${p}`));let y;try{y=n(h)}catch{throw new u("invalid_signature","Unreadable JWT signature")}if(!function(e,t){if(e.length!==t.length)return!1;let n=0;for(let r=0;r<e.length;r++)n|=e[r]^t[r];return 0===n}(m,y))throw new u("invalid_signature","JWT signature verification failed");!function(e){for(const t of["iss","sub","jti"])if(void 0!==e[t]&&"string"!=typeof e[t])throw new u("invalid_token",`JWT ${t} claim must be a string`);for(const t of["exp","nbf","iat"]){const n=e[t];if(void 0!==n&&("number"!=typeof n||!Number.isFinite(n)))throw new u("invalid_token",`JWT ${t} claim must be a finite number`)}const t=e.aud;if(!(void 0===t||"string"==typeof t||Array.isArray(t)&&t.every(e=>"string"==typeof e)))throw new u("invalid_token","JWT aud claim must be a string or string array")}(f);const w=Math.floor(Date.now()/1e3);if(i&&"number"!=typeof f.exp)throw new u("invalid_token","JWT is missing a numeric exp claim");if("number"==typeof f.exp&&w>f.exp+s)throw new u("token_expired","JWT has expired");if("number"==typeof f.nbf&&w+s<f.nbf)throw new u("token_not_yet_valid","JWT is not yet valid");if(void 0!==r.issuer&&f.iss!==r.issuer)throw new u("invalid_issuer","JWT issuer mismatch");if(void 0!==r.audience){const e=f.aud;if(!(Array.isArray(e)?e.includes(r.audience):e===r.audience))throw new u("invalid_audience","JWT audience mismatch")}return f}function p(e){if(!e)return null;const t=/^Bearer\s+(.+)$/i.exec(e.trim());return t?t[1].trim():null}function h(e){return t(o(JSON.stringify(e)))}function g(e,n,r){if(!n)throw new u("invalid_secret","Missing signing secret");const s=Math.floor(Date.now()/1e3),i={iat:s,exp:s+(r?.expiresInSec??3600),...e},c=`${h({alg:"HS256",typ:"JWT"})}.${h(i)}`;return`${c}.${t(a(o(n),o(c)))}`}function f(e){return e.replace(/[\x00-\x1f\x7f]/g,"").replace(/([\\"])/g,"\\$1")}function m(e){const t=[`Bearer resource_metadata="${f(e.resourceMetadataUrl)}"`];return e.error&&t.push(`error="${f(e.error)}"`),e.errorDescription&&t.push(`error_description="${f(e.errorDescription)}"`),{status:401,headers:{"WWW-Authenticate":t.join(", "),"Content-Type":"application/json"},body:JSON.stringify({error:e.error??"invalid_token"})}}const y=e.string().optional().describe("Workspace id. Omit to use the workspace bound to your token.");function w(e,t){const n=e.workspaceId??t.workspaceId;if(!n)throw new Error("workspaceId is required. Call list_workspaces to find one.");return n}function b(e){return{title:e,readOnlyHint:!0}}function k(e,t){return{title:e,readOnlyHint:!1,destructiveHint:t.destructive,...void 0!==t.idempotent?{idempotentHint:t.idempotent}:{},...void 0!==t.openWorld?{openWorldHint:t.openWorld}:{}}}const v=[{name:"list_workspaces",description:"List the authenticated user's workspaces (id, name, roles).",inputSchema:e.object({}),annotations:b("List Workspaces"),execute:(e,t)=>t.bb.workspace.list()},{name:"get_workspace",description:"Get one workspace: name, members, feature flags, quota snapshot.",inputSchema:e.object({workspaceId:y}),annotations:b("Get Workspace Details"),execute:(e,t)=>t.bb.workspace.get(w(e,t))},{name:"get_user_profile",description:"Get the authenticated user's profile.",inputSchema:e.object({}),annotations:b("Get My Profile"),execute:(e,t)=>t.bb.users.getProfile()},{name:"list_workspace_users",description:"List the members of a workspace with their roles.",inputSchema:e.object({workspaceId:y}),annotations:b("List Workspace Members"),execute:(e,t)=>t.bb.users.list(w(e,t))},{name:"get_subscription",description:"Get a workspace's subscription: plan, status, interval, seats.",inputSchema:e.object({workspaceId:y}),annotations:b("Get Subscription"),execute:(e,t)=>t.bb.subscription.get(w(e,t))},{name:"get_plans",description:"Get the plan group available to a workspace (plans, prices, quotas).",inputSchema:e.object({workspaceId:y}),annotations:b("List Available Plans"),execute:(e,t)=>t.bb.plans.getGroup(w(e,t))},{name:"list_invoices",description:"List a workspace's invoices (newest first).",inputSchema:e.object({workspaceId:y,limit:e.number().int().min(1).max(100).optional().describe("Max invoices to return."),startingAfter:e.string().optional().describe("Invoice id to paginate after.")}),annotations:b("List Invoices"),execute:(e,t)=>t.bb.invoices.list(w(e,t),e.limit,e.startingAfter)},{name:"get_quota_usage",description:"Get usage vs. limit for one quota in a workspace.",inputSchema:e.object({workspaceId:y,quotaSlug:e.string().describe('The quota slug, e.g. "api-calls".')}),annotations:b("Get Quota Usage"),execute:(e,t)=>t.bb.usage.getQuota(w(e,t),e.quotaSlug)},{name:"get_all_quota_usage",description:"Get usage vs. limit for every quota in a workspace.",inputSchema:e.object({workspaceId:y}),annotations:b("Get All Quota Usage"),execute:(e,t)=>t.bb.usage.getAll(w(e,t))},{name:"get_credit_balance",description:"Get a workspace's prepaid credit balance.",inputSchema:e.object({workspaceId:y}),annotations:b("Get Credit Balance"),execute:(e,t)=>t.bb.credits.getBalance(w(e,t))},{name:"list_credit_transactions",description:"Get a workspace's credit transaction history (paginated).",inputSchema:e.object({workspaceId:y,limit:e.number().int().min(1).max(100).optional(),page:e.number().int().min(1).optional()}),annotations:b("List Credit Transactions"),execute:(e,t)=>t.bb.credits.getTransactions(w(e,t),{...void 0!==e.limit?{limit:e.limit}:{},...void 0!==e.page?{page:e.page}:{}})},{name:"check_feature_flag",description:"Check whether a feature flag is enabled for a workspace.",inputSchema:e.object({workspaceId:y,key:e.string().describe("The feature slug.")}),annotations:b("Check Feature Flag"),execute:async(e,t)=>{const n=w(e,t),r=await t.bb.workspace.get(n),s=r.features?.[e.key];if(void 0!==s)return{key:e.key,enabled:s,source:"workspace"};const i=(await t.bb.features.list()).find(t=>t.slug===e.key);if(!i)throw new Error(`Unknown feature flag: ${e.key}`);return{key:e.key,enabled:i.defaultValue,source:"default"}}},{name:"check_permission",description:"Check whether a user has permission(s) in a workspace.",inputSchema:e.object({workspaceId:y,permission:e.union([e.string(),e.array(e.string())]).describe("A permission (or a list, all of which must hold), platform or app-defined."),userId:e.string().optional().describe("Defaults to the authenticated user.")}),annotations:b("Check Permission"),execute:async(e,t)=>{const n=e.userId??t.auth.userId;if(!n)throw new Error("userId is required: the token carries no user identity.");const r=await t.bb.permissions.check(w(e,t),n,e.permission);return{userId:n,permission:e.permission,allowed:r}}},{name:"resolve_permissions",description:"List every permission a user holds in a workspace.",inputSchema:e.object({workspaceId:y,userId:e.string().optional().describe("Defaults to the authenticated user.")}),annotations:b("List User Permissions"),execute:async(e,t)=>{const n=e.userId??t.auth.userId;if(!n)throw new Error("userId is required: the token carries no user identity.");const r=await t.bb.permissions.resolve(w(e,t),n);return{userId:n,permissions:Array.from(r)}}},{name:"get_invoice",description:"Get one invoice by id.",inputSchema:e.object({workspaceId:y,invoiceId:e.string().describe("The invoice id.")}),annotations:b("Get Invoice"),execute:(e,t)=>t.bb.invoices.get(w(e,t),e.invoiceId)},{name:"get_plan_versions",description:"List the plan-group versions available to a workspace.",inputSchema:e.object({workspaceId:y}),annotations:b("List Plan Versions"),execute:(e,t)=>t.bb.plans.getVersions(w(e,t))},{name:"get_public_plans",description:"Get a public plan group by slug (no workspace / auth needed).",inputSchema:e.object({slug:e.string().describe("The plan-group slug.")}),annotations:b("Get Public Plans"),execute:(e,t)=>t.bb.plans.getPublic(e.slug)},{name:"get_plan_version",description:"Get one public plan-group version by id (no auth needed).",inputSchema:e.object({groupVersionId:e.string().describe("The plan-group version id.")}),annotations:b("Get Plan Version"),execute:(e,t)=>t.bb.plans.getVersion(e.groupVersionId)},{name:"get_usage_logs",description:"Get a workspace's usage log entries (paginated, filterable).",inputSchema:e.object({workspaceId:y,quotaSlug:e.string().optional(),from:e.string().optional().describe("ISO date lower bound."),to:e.string().optional().describe("ISO date upper bound."),source:e.string().optional(),page:e.number().int().min(1).optional(),limit:e.number().int().min(1).max(100).optional()}).strict(),annotations:b("List Usage Logs"),execute:(e,t)=>{const{workspaceId:n,...r}=e;return t.bb.usage.getLogs(w(e,t),r)}},{name:"get_settings",description:"Get the organization settings.",inputSchema:e.object({}),annotations:b("Get Organization Settings"),execute:(e,t)=>t.bb.settings.get()},{name:"get_credit_packages",description:"List the credit packages a workspace can purchase.",inputSchema:e.object({workspaceId:y}),annotations:b("List Credit Packages"),execute:(e,t)=>t.bb.credits.getPackages(w(e,t))},{name:"get_credit_buckets",description:"Get a workspace's credit buckets (paginated).",inputSchema:e.object({workspaceId:y,status:e.string().optional(),source:e.string().optional(),page:e.number().int().min(1).optional(),limit:e.number().int().min(1).max(100).optional()}).strict(),annotations:b("List Credit Buckets"),execute:(e,t)=>{const{workspaceId:n,...r}=e;return t.bb.credits.getBuckets(w(e,t),r)}},{name:"get_expiring_credits",description:"Get credits expiring within N days (default 7).",inputSchema:e.object({workspaceId:y,days:e.number().int().min(1).optional()}),annotations:b("List Expiring Credits"),execute:(e,t)=>t.bb.credits.getExpiring(w(e,t),e.days)},{name:"get_public_credit_packages",description:"List credit packages publicly (no workspace / auth needed).",inputSchema:e.object({}),annotations:b("List Public Credit Packages"),execute:(e,t)=>t.bb.credits.getPublicPackages()}],S=[{name:"record_usage",description:"Record quota usage for a workspace (metered billing).",inputSchema:e.object({workspaceId:y,quotaSlug:e.string().describe("The quota slug to record against."),quantity:e.number().positive().describe("Amount of usage to record."),idempotencyKey:e.string().optional().describe("Dedupe key for safe retries."),metadata:e.record(e.string(),e.unknown()).optional()}),annotations:k("Record Usage",{destructive:!1,idempotent:!1}),execute:(e,t)=>t.bb.usage.record(w(e,t),{quotaSlug:e.quotaSlug,quantity:e.quantity,source:"mcp",...e.idempotencyKey?{idempotencyKey:e.idempotencyKey}:{},...e.metadata?{metadata:e.metadata}:{}})},{name:"consume_credits",description:"Consume prepaid credits from a workspace's balance.",inputSchema:e.object({workspaceId:y,amount:e.number().positive().describe("Credits to consume."),description:e.string().optional().describe("What the credits were spent on."),idempotencyKey:e.string().optional().describe("Dedupe key for safe retries.")}),annotations:k("Consume Credits",{destructive:!0}),execute:(e,t)=>t.bb.credits.consume(w(e,t),{amount:e.amount,...e.description?{description:e.description}:{},...e.idempotencyKey?{idempotencyKey:e.idempotencyKey}:{}})},{name:"send_notification",description:"Send a notification event to a workspace user (or all members when userId is omitted).",inputSchema:e.object({workspaceId:y,event:e.string().describe('The event slug, e.g. "comment_added".'),userId:e.string().optional().describe("Recipient. Omit to notify all members."),message:e.string().optional().describe("Message body (used for push).")}),annotations:k("Send Notification",{destructive:!1,openWorld:!0}),execute:(e,t)=>t.bb.notification.send(w(e,t),e.event,e.userId,e.message?{message:e.message}:void 0)},{name:"record_usage_batch",description:"Record multiple usage entries in one call (max 100 items).",inputSchema:e.object({workspaceId:y,items:e.array(e.object({quotaSlug:e.string(),quantity:e.number().positive(),idempotencyKey:e.string().optional(),metadata:e.record(e.string(),e.unknown()).optional()})).min(1).max(100)}),annotations:k("Record Usage (Batch)",{destructive:!1}),execute:(e,t)=>t.bb.usage.recordBatch(w(e,t),{items:e.items.map(e=>({...e,source:"mcp"}))})},{name:"create_workspace",description:"Create a new workspace.",inputSchema:e.object({name:e.string().describe("Workspace name."),image:e.string().optional().describe("Image URL.")}),annotations:k("Create Workspace",{destructive:!1}),execute:(e,t)=>t.bb.workspace.create({name:e.name,...e.image?{image:e.image}:{}})},{name:"update_workspace",description:"Update a workspace's editable fields (name, image).",inputSchema:e.object({workspaceId:y,name:e.string().min(1).optional().describe("New workspace name."),image:e.string().optional().describe("New image URL.")}).strict(),annotations:k("Update Workspace",{destructive:!1}),execute:(e,t)=>{const n={};return void 0!==e.name&&(n.name=e.name),void 0!==e.image&&(n.image=e.image),t.bb.workspace.update(w(e,t),n)}},{name:"delete_workspace",description:"Delete a workspace. Irreversible.",inputSchema:e.object({workspaceId:y}),annotations:k("Delete Workspace",{destructive:!0}),execute:(e,t)=>t.bb.workspace.delete(w(e,t))},{name:"invite_workspace_user",description:"Invite a user to a workspace with a role.",inputSchema:e.object({workspaceId:y,email:e.string().describe("Invitee email."),role:e.string().describe("Role to grant.")}),annotations:k("Invite Member",{destructive:!1,openWorld:!0}),execute:(e,t)=>t.bb.users.invite(w(e,t),e.email,e.role)},{name:"remove_workspace_user",description:"Remove a user from a workspace. Irreversible.",inputSchema:e.object({workspaceId:y,userId:e.string().describe("The user to remove.")}),annotations:k("Remove Member",{destructive:!0}),execute:(e,t)=>t.bb.users.remove(w(e,t),e.userId)},{name:"update_workspace_user_role",description:"Change a workspace member's role.",inputSchema:e.object({workspaceId:y,userId:e.string(),role:e.string().describe("The new role.")}),annotations:k("Change Member Role",{destructive:!1}),execute:(e,t)=>t.bb.users.updateRole(w(e,t),e.userId,e.role)},{name:"update_user_profile",description:"Update the authenticated user's own profile (name, image, country, timezone, language, currency).",inputSchema:e.object({name:e.string().min(1).optional(),image:e.string().optional().describe("Profile image URL."),country:e.string().optional().describe("ISO country code."),timezone:e.string().optional().describe("IANA timezone."),language:e.string().optional().describe("Language code."),currency:e.string().optional().describe("Currency code.")}).strict(),annotations:k("Update My Profile",{destructive:!1}),execute:(e,t)=>{const n={};for(const t of["name","image","country","timezone","language","currency"]){const r=e[t];void 0!==r&&(n[t]=r)}return t.bb.users.updateProfile(n)}},{name:"update_feature_flag",description:"Set a feature flag on/off for a workspace.",inputSchema:e.object({workspaceId:y,key:e.string().describe("The feature slug."),value:e.boolean().describe("Enabled?")}),annotations:k("Set Feature Flag",{destructive:!1}),execute:(e,t)=>t.bb.features.update(w(e,t),e.key,e.value)},{name:"create_subscription_checkout",description:"Create a Stripe checkout session to subscribe a workspace to a plan.",inputSchema:e.object({workspaceId:y,planVersionId:e.string(),billingInterval:e.string().optional(),currency:e.string().optional(),successUrl:e.string().optional(),cancelUrl:e.string().optional()}).strict(),annotations:k("Start Subscription Checkout",{destructive:!1,openWorld:!0}),execute:(e,t)=>{const{workspaceId:n,...r}=e;return t.bb.subscription.checkout(w(e,t),r)}},{name:"update_subscription",description:"Change a workspace's subscription plan.",inputSchema:e.object({workspaceId:y,planVersionId:e.string(),billingInterval:e.string().optional(),successUrl:e.string().optional(),cancelUrl:e.string().optional()}).strict(),annotations:k("Change Subscription Plan",{destructive:!0}),execute:(e,t)=>{const{workspaceId:n,...r}=e;return t.bb.subscription.update(w(e,t),r)}},{name:"cancel_subscription",description:"Cancel a workspace's subscription.",inputSchema:e.object({workspaceId:y}),annotations:k("Cancel Subscription",{destructive:!0}),execute:(e,t)=>t.bb.subscription.cancel(w(e,t))},{name:"resume_subscription",description:"Resume a workspace's canceled subscription.",inputSchema:e.object({workspaceId:y}),annotations:k("Resume Subscription",{destructive:!1}),execute:(e,t)=>t.bb.subscription.resume(w(e,t))},{name:"get_billing_portal_url",description:"Get a Stripe billing-portal URL for a workspace.",inputSchema:e.object({workspaceId:y,returnUrl:e.string().optional()}),annotations:k("Open Billing Portal",{destructive:!1,openWorld:!0}),execute:(e,t)=>t.bb.subscription.getBillingPortalUrl(w(e,t),e.returnUrl)},{name:"purchase_credits",description:"Create a Stripe checkout session to buy a credit package.",inputSchema:e.object({workspaceId:y,creditPackageId:e.string(),currency:e.string().optional(),successUrl:e.string().describe("Redirect URL on success."),cancelUrl:e.string().describe("Redirect URL on cancel.")}).strict(),annotations:k("Buy Credits",{destructive:!1,openWorld:!0}),execute:(e,t)=>{const{workspaceId:n,...r}=e;return t.bb.credits.purchase(w(e,t),r)}}],E=new Map([...v,...S].map(e=>[e.name,e]));function P(e){if(!1===e)return[];if("readonly"===e)return[...v];if("all"===e)return[...v,...S];const t=e.include?e.include.map(e=>{const t=E.get(e);if(!t)throw new Error(`Unknown built-in MCP tool: ${e}`);return t}):[...v],n=new Set(e.exclude??[]);return t.filter(e=>!n.has(e.name))}const I=e=>({type:"text",text:e}),T=(e,t)=>({type:"image",data:e,mimeType:t}),_=(e,t)=>({type:"audio",data:e,mimeType:t}),U=(e,t,n)=>({type:"resource_link",uri:e,name:t,...n}),A=e=>({type:"resource",resource:e}),C=e=>{if("object"!=typeof e||null===e)return!1;const t=e;switch(t.type){case"text":return"string"==typeof t.text;case"image":case"audio":return"string"==typeof t.data&&"string"==typeof t.mimeType;case"resource_link":return"string"==typeof t.uri&&"string"==typeof t.name;case"resource":{const e=t.resource;return"object"==typeof e&&null!==e&&"string"==typeof e.uri&&("string"==typeof e.text||"string"==typeof e.blob)}default:return!1}},$=e=>e,x=e=>e,O=e=>e,R=["2025-11-25","2025-06-18","2025-03-26","2024-11-05"],F=R[0],W="application/json",N=/^[a-zA-Z0-9_-]{1,128}$/,j=-32002,J=-32700,M=-32600,L=-32601,q=-32602,B=-32603;function D(e,t){const n=t.toLowerCase();for(const t of Object.keys(e))if(t.toLowerCase()===n)return e[t]}function G(e,t){return{status:e,headers:{"Content-Type":W},body:JSON.stringify(t)}}function z(e,t){return G(200,{jsonrpc:"2.0",id:e??null,result:t})}function V(e,t,n,r=200,s){return G(r,{jsonrpc:"2.0",id:e??null,error:{code:t,message:n,...void 0!==s?{data:s}:{}}})}function K(e){return"object"==typeof e&&null!==e&&"function"==typeof e.safeParse}function H(e){return e instanceof Error?e.message:"string"==typeof e?e:JSON.stringify(e)}function Q(t){const n=t.serverInfo??{name:"buildbase-mcp",version:"1.0.0"};t.auth&&!t.auth.resourceMetadataUrl&&console.warn("[buildbase/mcp] auth is enabled but `auth.resourceMetadataUrl` is unset — 401 responses will carry no WWW-Authenticate/resource_metadata pointer, so MCP clients cannot discover your authorization server. Set it to your /.well-known/oauth-protected-resource URL.");const r=e=>e.trim().toLowerCase().replace(/\/+$/,""),s=t.allowedOrigins?new Set(t.allowedOrigins.map(r)):null,i=e=>!!e&&!!s&&s.has(r(e)),o=t.builtinTools??(!!t.buildbase&&"readonly"),a=t.maxRequestBytes??1048576;if(!1!==o&&!t.buildbase)throw new Error("builtinTools require a `buildbase` client — pass one to createMcpHandler, or set builtinTools: false.");const c=new Map;for(const e of P(o))c.set(e.name,e);const u=new Set;for(const e of t.tools??[]){if(!N.test(e.name))throw new Error(`Invalid MCP tool name: "${e.name}" (want ${String(N)})`);if(u.has(e.name))throw new Error(`Duplicate MCP tool name: "${e.name}"`);u.add(e.name),c.set(e.name,e)}if(t.builtinResources&&!t.buildbase)throw new Error("builtinResources requires a `buildbase` client — pass one to createMcpHandler.");const l=new Map,d=[];t.builtinResources&&(l.set("buildbase://profile",{uri:"buildbase://profile",name:"profile",title:"Your profile",description:"The authenticated user's BuildBase profile.",mimeType:"application/json",read:e=>e.bb.users.getProfile()}),l.set("buildbase://workspaces",{uri:"buildbase://workspaces",name:"workspaces",title:"Your workspaces",description:"The authenticated user's workspaces (id, name, roles).",mimeType:"application/json",read:e=>e.bb.workspace.list()}),d.push({uriTemplate:"buildbase://workspace/{workspaceId}",name:"workspace",title:"One workspace",description:"A single workspace: name, members, feature flags, quota snapshot.",mimeType:"application/json",read:(e,t,n)=>n.bb.workspace.get(e.workspaceId)}));for(const e of t.resources??[])l.set(e.uri,e);d.push(...t.resourceTemplates??[]);const h=new Map;for(const e of t.prompts??[]){if(!N.test(e.name))throw new Error(`Invalid MCP prompt name: "${e.name}" (want ${String(N)})`);if(h.has(e.name))throw new Error(`Duplicate MCP prompt name: "${e.name}"`);h.set(e.name,e)}const g=l.size>0||d.length>0,f=h.size>0,y=(e,t)=>{const n=new Set(t?.scopes??[]);return(e??[]).every(e=>n.has(e))};function w(e,n){const r=e?.sessionId??"";return{bb:t.buildbase?r?t.buildbase.withSession(r):S:v,auth:e??{sessionId:""},workspaceId:e?.workspaceId,custom:n}}function b(e,t){const n=[],r=e.replace(/[.*+?^$()|[\]\\]/g,e=>"\\"+e).replace(/\{([a-zA-Z0-9_]+)\}/g,(e,t)=>(n.push(t),"([^/]+)")),s=new RegExp(`^${r}$`).exec(t);if(!s)return null;const i={};return n.forEach((e,t)=>{try{i[e]=decodeURIComponent(s[t+1])}catch{i[e]=s[t+1]}}),i}function k(e,t,n){if("string"==typeof n)return{uri:e,mimeType:t??"text/plain",text:n};if(n&&"object"==typeof n){const r=n;if("string"==typeof r.text)return{uri:e,mimeType:"string"==typeof r.mimeType?r.mimeType:t??"text/plain",text:r.text};if("string"==typeof r.blob)return{uri:e,mimeType:"string"==typeof r.mimeType?r.mimeType:t??"application/octet-stream",blob:r.blob}}return{uri:e,mimeType:t??"application/json",text:JSON.stringify(n,null,2)}}const v=new Proxy({},{get(e,t){if("string"==typeof t)throw new Error(`No \`buildbase\` client configured — pass one to createMcpHandler to use bb.${t} in tools.`)}}),S=new Proxy({},{get(e,t){if("string"==typeof t)throw new Error(`This tool needs an authenticated BuildBase session, but the token carried none (bb.${t}). Re-authenticate.`)}}),E=new Map;function T(t){const n=E.get(t.name);if(n)return n;let r;try{r=K(t.inputSchema)?e.toJSONSchema(t.inputSchema,{target:"draft-2020-12"}):t.inputSchema}catch(e){U(e,{method:"tools/list",tool:t.name}),r={type:"object",additionalProperties:!0}}return E.set(t.name,r),r}function _(e){const t=new Set(e?.scopes??[]);return Array.from(c.values()).filter(e=>(e.requiredScopes??[]).every(e=>t.has(e)))}function U(e,n){try{t.onError?.(e instanceof Error?e:new Error(H(e)),n)}catch{}}function A(){if(t.auth&&t.auth.resourceMetadataUrl){const e=m({resourceMetadataUrl:t.auth.resourceMetadataUrl});return{status:e.status,headers:e.headers,body:e.body}}return G(401,{error:"unauthorized"})}const $=Array.isArray(t.cors)?new Set(t.cors.map(r)):null;async function x(e){const o=function(e){if(!1===t.cors)return{};const n=D(e.headers,"origin");let o;return o=$?n&&$.has(r(n))?n:null:s?i(n)?n:null:"*",o?{"Access-Control-Allow-Origin":o,"Access-Control-Allow-Methods":"POST, OPTIONS","Access-Control-Allow-Headers":"Content-Type, Authorization, MCP-Protocol-Version, Mcp-Session-Id, Last-Event-ID","Access-Control-Expose-Headers":"MCP-Protocol-Version, Mcp-Session-Id, WWW-Authenticate","Access-Control-Max-Age":"86400",..."*"!==o?{Vary:"Origin"}:{}}:{}}(e);if("OPTIONS"===e.method.toUpperCase())return{status:204,headers:o,body:""};const c=await async function(e){const r=e.method.toUpperCase();if(s){const t=D(e.headers,"origin");if(t&&!i(t))return G(403,{error:"origin_not_allowed"})}if("POST"!==r)return{status:405,headers:{"Content-Type":W,Allow:"POST, OPTIONS"},body:JSON.stringify({error:"method_not_allowed"})};if(a>0&&"string"==typeof e.body&&e.body.length>a)return G(413,{error:"payload_too_large"});let o=null;if(!1!==t.auth){const n=p(D(e.headers,"authorization"));if(!n)return A();try{o=await t.auth.verify(n,e)}catch(e){U(e,{method:"auth"}),o=null}if(!o)return A()}if(t.rateLimit){let n;try{n=await t.rateLimit(o,e)}catch(e){U(e,{method:"rateLimit"}),n=!1}if(!("boolean"==typeof n?n:n.ok)){const e="object"==typeof n?n.retryAfter:void 0;return{status:429,headers:{"Content-Type":W,...void 0!==e?{"Retry-After":String(e)}:{}},body:JSON.stringify({error:"rate_limited"})}}}let c=e.body;if("string"==typeof e.body)try{c=JSON.parse(e.body)}catch{return V(null,J,"Invalid JSON",400)}if(Array.isArray(c))return V(null,M,"Batch requests are not supported",400);if("object"!=typeof c||null===c)return V(null,M,"Expected a JSON-RPC request object",400);const u=c,m=u.id,v="string"==typeof u.method?u.method:null;if(!v)return V(m,M,"Missing method",400);if(null==m)return{status:202,headers:{"Content-Type":W},body:""};const S=u.params??{};switch(v){case"initialize":{const e=S.protocolVersion;return z(m,{protocolVersion:"string"==typeof e&&R.includes(e)?e:F,capabilities:{tools:{listChanged:!1},...g?{resources:{}}:{},...f?{prompts:{}}:{}},serverInfo:n,...t.instructions?{instructions:t.instructions}:{}})}case"ping":return z(m,{});case"tools/list":return z(m,{tools:_(o).map(e=>({name:e.name,description:e.description,inputSchema:T(e),...e.annotations?{annotations:e.annotations}:{},...e.icons?{icons:e.icons}:{}}))});case"tools/call":{const n="string"==typeof S.name?S.name:"",r=_(o).find(e=>e.name===n);if(!r)return V(m,q,`Unknown tool: ${n||"(missing name)"}`);let s,i=S.arguments??{};if(K(r.inputSchema)){const e=r.inputSchema.safeParse(i);if(!e.success){const t=e.error.issues.map(e=>`${e.path.join(".")||"(root)"}: ${e.message}`).join("; ");return z(m,{content:[{type:"text",text:`Invalid arguments for ${n}: ${t}`}],isError:!0})}i=e.data}if(t.context)try{s=await t.context(o,e)}catch(e){return U(e,{method:v,tool:n}),V(m,B,"Context initialization failed")}const a=w(o,s);try{const e=await r.execute(i,a);if("object"==typeof(E=e)&&null!==E&&Array.isArray(E.content)&&E.content.length>0&&E.content.every(C))return z(m,{content:e.content,...void 0!==e.structuredContent?{structuredContent:e.structuredContent}:{},isError:e.isError??!1});const t="object"==typeof e&&null!==e&&!Array.isArray(e);return z(m,{content:[{type:"text",text:"string"==typeof e?e:JSON.stringify(e,null,2)}],...t?{structuredContent:e}:{},isError:!1})}catch(e){U(e,{method:v,tool:n});const r=e instanceof Error?e:new Error(H(e));return z(m,{content:[{type:"text",text:t.formatToolError?t.formatToolError(r,{tool:n}):r.message}],isError:!0})}}case"resources/list":if(!g)break;return z(m,{resources:Array.from(l.values()).filter(e=>y(e.requiredScopes,o)).map(e=>({uri:e.uri,name:e.name,...e.title?{title:e.title}:{},...e.description?{description:e.description}:{},...e.mimeType?{mimeType:e.mimeType}:{},...e.icons?{icons:e.icons}:{}}))});case"resources/templates/list":if(!g)break;return z(m,{resourceTemplates:d.filter(e=>y(e.requiredScopes,o)).map(e=>({uriTemplate:e.uriTemplate,name:e.name,...e.title?{title:e.title}:{},...e.description?{description:e.description}:{},...e.mimeType?{mimeType:e.mimeType}:{},...e.icons?{icons:e.icons}:{}}))});case"resources/read":{if(!g)break;if("string"!=typeof S.uri||""===S.uri)return V(m,q,"Missing required parameter: uri");const n=S.uri;let r,s=null;const i=l.get(n);if(i){if(!y(i.requiredScopes,o))return V(m,j,"Resource not found",200,{uri:n});r=i.mimeType,s=async e=>i.read(e)}else for(const e of d){if(!y(e.requiredScopes,o))continue;const t=b(e.uriTemplate,n);if(t){r=e.mimeType,s=async r=>e.read(t,n,r);break}}if(!s)return V(m,j,"Resource not found",200,{uri:n});let a;if(t.context)try{a=await t.context(o,e)}catch(e){return U(e,{method:v}),V(m,B,"Context initialization failed")}try{const e=await s(w(o,a));return z(m,{contents:[k(n,r,e)]})}catch(e){return U(e,{method:v}),V(m,B,"Resource read failed",200,{uri:n})}}case"prompts/list":if(!f)break;return z(m,{prompts:Array.from(h.values()).filter(e=>y(e.requiredScopes,o)).map(e=>({name:e.name,...e.title?{title:e.title}:{},...e.description?{description:e.description}:{},...e.arguments?{arguments:e.arguments}:{},...e.icons?{icons:e.icons}:{}}))});case"prompts/get":{if(!f)break;const n="string"==typeof S.name?S.name:"",r=h.get(n);if(!r||!y(r.requiredScopes,o))return V(m,q,`Unknown prompt: ${n||"(missing name)"}`);const s="object"==typeof S.arguments&&null!==S.arguments?S.arguments:{},i={};for(const[e,t]of Object.entries(s))"string"==typeof t&&(i[e]=t);const a=(r.arguments??[]).filter(e=>e.required&&!(e.name in i)).map(e=>e.name);if(a.length)return V(m,q,`Missing required arguments: ${a.join(", ")}`);let c;if(t.context)try{c=await t.context(o,e)}catch(e){return U(e,{method:v}),V(m,B,"Context initialization failed")}try{const e=await r.get(i,w(o,c)),t="string"==typeof e?{messages:[{role:"user",content:I(e)}]}:Array.isArray(e)?{messages:e}:e,n=t.description??r.description;return z(m,{...n?{description:n}:{},messages:t.messages})}catch(e){return U(e,{method:v}),V(m,B,"Prompt rendering failed")}}}var E;return V(m,L,`Method not found: ${v}`)}(e);return Object.keys(o).length?{...c,headers:{...c.headers,...o}}:c}return{handle:x,fetch:async function(e){const t={};if(e.headers.forEach((e,n)=>{t[n]=e}),a>0){const t=Number(e.headers.get("content-length"));if(Number.isFinite(t)&&t>a)return new Response(JSON.stringify({error:"payload_too_large"}),{status:413,headers:{"Content-Type":W}})}const n="POST"===e.method.toUpperCase()?await e.text():void 0,r=await x({method:e.method,headers:t,body:n});return new Response(""===r.body?null:r.body,{status:r.status,headers:r.headers})},listTools:()=>Array.from(c.values()).map(e=>({name:e.name,description:e.description,...e.annotations?{annotations:e.annotations}:{}})),serverCard:e=>({name:n.name,version:n.version,endpoint:e.endpoint,transport:"streamable-http",capabilities:{tools:{listChanged:!1},...g?{resources:{}}:{},...f?{prompts:{}}:{}},...e.description?{description:e.description}:{},...e.documentationUrl?{documentationUrl:e.documentationUrl}:{}})}}function Y(e){return e}const Z=12,X=16;function ee(){const e=globalThis.crypto;if(!e?.subtle)throw new Error("WebCrypto is unavailable in this runtime — agent-auth session encryption requires globalThis.crypto.subtle (Node 18+, Bun, Deno, edge, browsers).");return e.subtle}const te=new Map;function ne(e){let t=te.get(e);return t||(t=(async()=>{const t=await ee().digest("SHA-256",(new TextEncoder).encode(`${e}:bb-session`));return ee().importKey("raw",t,{name:"AES-GCM"},!1,["encrypt","decrypt"])})(),te.set(e,t)),t}function re(e){if(!e)throw new Error("createSessionRefCrypto: missing secret");return{async encryptSessionRef(n){const r=globalThis.crypto.getRandomValues(new Uint8Array(Z)),s=await ne(e),i=new Uint8Array(await ee().encrypt({name:"AES-GCM",iv:r},s,(new TextEncoder).encode(n))),o=i.subarray(i.length-X),a=i.subarray(0,i.length-X),c=new Uint8Array(28+a.length);return c.set(r,0),c.set(o,Z),c.set(a,28),t(c)},async decryptSessionRef(t){try{const r=n(t);if(r.length<=28)return null;const s=r.slice(0,Z),i=r.subarray(Z,28),o=r.subarray(28),a=new Uint8Array(o.length+X);a.set(o,0),a.set(i,o.length);const c=await ne(e),u=await ee().decrypt({name:"AES-GCM",iv:s},c,a);return(new TextDecoder).decode(u)}catch{return null}}}}async function se(e){const{claims:t,secret:n}=e,r=e.expiresInSec??3600,s=t.resource&&t.resource.length?1===t.resource.length?t.resource[0]:t.resource:void 0,i=t.sessionId?await re(n).encryptSessionRef(t.sessionId):void 0;return{token:g({sub:t.id,userId:t.id,email:t.email,...t.name?{name:t.name}:{},...t.scope?{scope:t.scope}:{},...s?{aud:s}:{},...i?{sid:i}:{},...e.extraClaims},n,{expiresInSec:r}),expiresIn:r}}function ie(e,t,n){const r=globalThis.process?.env;"1"===r?.MCP_AUTH_DEBUG&&console.warn(`[buildbase/mcp-auth] audience rejected (${n}): received aud=${JSON.stringify(e)} expected one of ${JSON.stringify(t)}`)}function oe(e){const{secret:t}=e;if(!t)throw new Error("buildbaseAuth: missing secret");const n=re(t),r=e.resource?Array.isArray(e.resource)?e.resource:[e.resource]:[];let s=e.resourceMetadataUrl;if(!s&&r.length)try{const e=new URL(r[0]),t="/"===e.pathname?"":e.pathname.replace(/\/+$/,"");s=`${e.origin}/.well-known/oauth-protected-resource${t}`}catch{}return{resourceMetadataUrl:s,verify:async s=>{let i;try{i=d(s,t,{...e.verify})}catch{return null}if(r.length){const t=i.aud?Array.isArray(i.aud)?i.aud:[i.aud]:[];if(!t.length&&e.requireAudience)return ie(t,r,"token carries no aud claim"),null;if(t.length&&!t.some(e=>r.includes(e)))return ie(t,r,"aud does not include this resource"),null}const o="string"==typeof i.sid?await n.decryptSessionRef(i.sid):null,a=Array.isArray(i.scope)?i.scope.filter(e=>"string"==typeof e):"string"==typeof i.scope?i.scope.split(" ").filter(Boolean):void 0;return{sessionId:o??"",userId:"string"==typeof i.userId?i.userId:"string"==typeof i.sub?i.sub:void 0,workspaceId:"string"==typeof i.workspaceId?i.workspaceId:void 0,scopes:a,claims:i}}}}const ae=300,ce="/.well-known/oauth-protected-resource",ue="/.well-known/agent-skills",le="/.well-known/api-catalog",de="/.well-known/mcp/server-card.json",pe="/.well-known/agent-card.json",he="application/json",ge="application/linkset+json",fe="text/markdown; charset=utf-8",me="text/plain; charset=utf-8",ye="application/xml; charset=utf-8",we=["GPTBot","OAI-SearchBot","ChatGPT-User","ClaudeBot","Claude-User","Claude-SearchBot","PerplexityBot","Perplexity-User","Google-Extended","Applebot-Extended","CCBot","Bytespider","meta-externalagent","Amazonbot"];function be(e){return e.replace(/\/+$/,"")}function ke(e){return`public, max-age=${e}, s-maxage=${e}`}function ve(e){return"sha256:"+function(e){let t="";for(let n=0;n<e.length;n++)t+=e[n].toString(16).padStart(2,"0");return t}(i(o(e)))}const Se=function(){const e=new Map;return{get(t){const n=e.get(t);if(n){if(!(n.expiresAt<=Date.now()))return n.value;e.delete(t)}},set(t,n,r){e.set(t,{value:n,expiresAt:Date.now()+1e3*r})},delete(t){e.delete(t)},clear(){e.clear()}}}(),Ee=new Set;function Pe(e){return e.cache??Se}function Ie(e){let t;const n=new Promise((e,n)=>{t=setTimeout(()=>n(new Error("discovery cache timed out")),500)});return Promise.race([Promise.resolve(e),n]).finally(()=>clearTimeout(t))}async function Te(e,t){try{const n=await Ie(e.get(t));return null==n?{hit:!1}:{hit:!0,value:JSON.parse(n)}}catch{return{hit:!1}}}async function _e(e,t,n,r){try{await Ie(e.set(t,JSON.stringify(n),r)),e!==Se&&Ee.add(t)}catch{}}async function Ue(e,t,n,r){if(!r||r<=0)return e(t,n);const s=new AbortController,i=setTimeout(()=>s.abort(),r);try{return await e(t,{...n,signal:s.signal})}finally{clearTimeout(i)}}async function Ae(e){const t=e.cacheTtlSeconds??ae,n=Pe(e),r=`buildbase:agent-readiness:${be(e.serverUrl)}::${e.orgId}`,s=await Te(n,r);if(s.hit)return s.value;const i=e.fetch??fetch,o=`${be(e.serverUrl)}/api/v1/public/${e.orgId}/agent-readiness`;let a={enabled:!1};try{const t=await Ue(i,o,{headers:{Accept:he}},e.fetchTimeoutMs??5e3);if(t.ok){const e=await t.json();e&&"object"==typeof e&&(a=e)}}catch{}return await _e(n,r,a,t),a}function Ce(e){let t="/";try{t=new URL(e).pathname}catch{t=e.startsWith("/")?e:`/${e}`}const n="/"===t?"":t.replace(/\/+$/,"");return ce+n}function $e(e){return e.path??`${ue}/${e.name}/SKILL.md`}function xe(e){if(!e.security)return null;const t=(Array.isArray(e.security.contact)?e.security.contact:[e.security.contact]).map(e=>`Contact: ${e}`);return e.security.expires&&t.push(`Expires: ${e.security.expires}`),e.security.policy&&t.push(`Policy: ${e.security.policy}`),{status:200,contentType:me,body:t.join("\n")+"\n",cacheControl:ke(e.cacheTtlSeconds??ae)}}function Oe(e){return e.endsWith(".json")||e.includes(".well-known/")?he:e.endsWith(".md")?fe:e.endsWith(".xml")?ye:me}function Re(e){const t=e??{tools:!0},n={tools:!1,resources:!1,prompts:!1};for(const[e,r]of Object.entries(t))n[e]=!1!==r&&null!=r;return n}function Fe(e,t){return{status:200,contentType:he,body:JSON.stringify(e,null,2),cacheControl:ke(t.cacheTtlSeconds??ae)}}function We(e){return String(e).replace(/[\x00-\x1f\x7f]/g,"")}function Ne(e,t){const n=(Array.isArray(e.userAgent)?e.userAgent:[e.userAgent]).map(e=>`User-agent: ${We(e)}`);if(t){const e=[...void 0!==t.search?["search="+(t.search?"yes":"no")]:[],...void 0!==t.aiInput?["ai-input="+(t.aiInput?"yes":"no")]:[],...void 0!==t.aiTrain?["ai-train="+(t.aiTrain?"yes":"no")]:[]];e.length&&n.push(`Content-Signal: ${e.join(", ")}`)}for(const t of e.allow??[])n.push(`Allow: ${We(t)}`);for(const t of e.disallow??[])n.push(`Disallow: ${We(t)}`);return void 0!==e.crawlDelay&&n.push(`Crawl-delay: ${We(e.crawlDelay)}`),n.join("\n")}function je(e){const t="number"==typeof e&&Number.isFinite(e)?e:.5;return String(Math.min(1,Math.max(0,t)))}function Je(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function Me(e){const t=be(e.siteUrl),n=[`<${t}/llms.txt>; rel="describedby"; type="text/plain"`,`<${t}/.well-known/agent.json>; rel="describedby"; type="application/json"`];if(!1!==e.a2aCard&&n.push(`<${t}${pe}>; rel="describedby"; type="application/json"`),e.sitemap||e.robots?.sitemaps?.length){const r=e.robots?.sitemaps?.[0]??`${t}/sitemap.xml`;n.push(`<${r}>; rel="sitemap"; type="application/xml"`)}return e.apiCatalog?.length&&n.push(`<${t}${le}>; rel="api-catalog"; type="${ge}"`),e.mcpServerCard&&n.push(`<${t}${de}>; rel="mcp-server"; type="application/json"`),n.join(", ")}async function Le(e,t){const n=e.replace(/\/+$/,"")||e;if("/.well-known/agent.json"===n){return function(e,t){const n=be(e.siteUrl),r={llms_txt:"/llms.txt",sitemap:"/sitemap.xml",robots:"/robots.txt",oauth_protected_resource:ce};return t.authorizationServer?.metadataUrl&&(r.oauth_authorization_server=t.authorizationServer.metadataUrl,r.openid_configuration="/.well-known/openid-configuration"),(t.authorizationServer||e.authMd)&&(r.auth="/auth.md"),e.skills?.length&&(r.agent_skills=`${ue}/index.json`),e.apiCatalog?.length&&(r.api_catalog=le),e.mcpServerCard&&(r.mcp_server_card=de),!1!==e.a2aCard&&(r.a2a_agent_card=pe),e.llmsFullTxt&&(r.llms_full_txt="/llms-full.txt"),Fe({schema_version:"1.0",name:e.site.name,...e.site.description?{description:e.site.description}:{},url:n,...e.site.documentationUrl?{documentation_url:e.site.documentationUrl}:{},provider:e.site.provider??{name:e.site.name,url:n},capabilities:r,...e.site.contactEmail?{contact:{email:e.site.contactEmail}}:{}},e)}(t,await Ae(t))}if(n===pe)return function(e){if(!1===e.a2aCard)return null;const t=e.a2aCard??{},n=be(e.siteUrl),r=t.serviceUrl??n,s=t.transportProtocol??"http",i=t.skills??((e.skills??[]).length?(e.skills??[]).map(e=>({id:e.name,name:e.name,description:e.description,tags:["discovery"]})):[{id:"site-content",name:"Site content",description:`Read ${e.site.name}'s public content and machine-readable discovery documents (llms.txt, sitemap, API catalog).`,tags:["content"]}]);return Fe({protocolVersion:"0.3.0",name:t.name??e.site.name,version:t.version??"1.0.0",description:t.description??e.site.description??`${e.site.name}: an agent-accessible web application.`,url:r,preferredTransport:s,supportedInterfaces:[{serviceUrl:r,transportProtocol:s}],provider:e.site.provider?{organization:e.site.provider.name,url:e.site.provider.url}:{organization:e.site.name,url:n},capabilities:t.capabilities??{streaming:!1,pushNotifications:!1},defaultInputModes:["text/plain","application/json"],defaultOutputModes:["text/plain","application/json"],skills:i,...e.site.documentationUrl?{documentationUrl:e.site.documentationUrl}:{}},e)}(t);if("/.well-known/http-message-signatures-directory"===n)return function(e){const t=e.webBotAuth?.keys;return t?.length?{status:200,contentType:"application/http-message-signatures-directory+json",body:JSON.stringify({keys:t},null,2),cacheControl:ke(e.cacheTtlSeconds??ae)}:null}(t);if("/.well-known/security.txt"===n)return xe(t);if(n===`${ue}/index.json`)return function(e){const t=e.skills??[];if(!t.length)return null;const n=be(e.siteUrl);return Fe({$schema:"https://schemas.agentskills.io/discovery/0.2.0/schema.json",skills:t.map(e=>({name:e.name,type:e.type??"skill-md",description:e.description,url:`${n}${$e(e)}`,digest:ve(e.content)}))},e)}(t);if(n.startsWith(`${ue}/`)&&n.endsWith("SKILL.md"))return function(e,t){const n=(t.skills??[]).find(t=>$e(t)===e);return n?{status:200,contentType:"text/markdown; charset=utf-8",body:n.content,cacheControl:ke(t.cacheTtlSeconds??ae)}:null}(n,t);if("/.well-known/oauth-authorization-server"===n||"/.well-known/openid-configuration"===n){const e=(await Ae(t)).authorizationServer;if(!e?.metadataUrl)return null;const n=await async function(e,t){const n=t.cacheTtlSeconds??ae,r=Pe(t),s=`buildbase:as-metadata:${e}`,i=await Te(r,s);if(i.hit)return i.value;const o=t.fetch??fetch;let a=null;try{const n=await Ue(o,e,{headers:{Accept:he}},t.fetchTimeoutMs??5e3);if(n.ok){const e=await n.json();e&&"object"==typeof e&&(a=e)}}catch{}return await _e(r,s,a,n),a}(e.metadataUrl,t);return Fe(n?n:{...e.issuer?{issuer:e.issuer}:{},oauth_authorization_server_metadata:e.metadataUrl},t)}if(n===le)return function(e){const t=e.apiCatalog??[];if(!t.length)return null;const n=t.map(e=>({anchor:e.anchor,...e.title?{title:e.title}:{},...e.serviceDesc?{"service-desc":[{href:e.serviceDesc}]}:{},...e.serviceDoc?{"service-doc":[{href:e.serviceDoc}]}:{},...e.status?{status:[{href:e.status}]}:{}}));return{status:200,contentType:ge,body:JSON.stringify({linkset:n},null,2),cacheControl:ke(e.cacheTtlSeconds??ae)}}(t);if(n===de)return function(e){const t=e.mcpServerCard;return t?Fe({$schema:"https://modelcontextprotocol.io/schemas/server-card/v1.0",version:"1.0",protocolVersion:t.protocolVersion??"2025-11-25",serverInfo:{name:t.name,version:t.version},...t.description?{description:t.description}:{},transport:{type:t.transport??"streamable-http",url:t.endpoint},capabilities:Re(t.capabilities),...t.documentationUrl?{documentation_url:t.documentationUrl}:{}},e):null}(t);if("/.well-known/mcp.json"===n)return function(e){const t=e.mcpServerCard;if(!t)return null;const n=be(e.siteUrl);let r;try{r={type:"oauth2",protected_resource_metadata:`${new URL(t.endpoint).origin}${Ce(t.endpoint)}`}}catch{}return Fe({$schema:"https://modelcontextprotocol.io/schemas/mcp-discovery/v1.0",version:"1.0",servers:[{name:t.name,...t.description?{description:t.description}:{},transport:{type:t.transport??"streamable-http",url:t.endpoint},version:t.version,capabilities:Re(t.capabilities),...t.documentationUrl?{documentation_url:t.documentationUrl}:{},server_card:`${n}${de}`,...r?{authentication:r}:{}}]},e)}(t);if(n.startsWith(ce)){const e=await Ae(t);return function(e,t,n){const r=t.protectedResources??[];if(!r.length)return null;const s=e.replace(/\/+$/,"")||ce,i=n??`${be(t.serverUrl)}/org/${t.orgId}`,o=t.scopes?.map(e=>e.name),a=r.map(e=>{const n=e.resource??be(t.siteUrl),r=e.scopes??o;return{path:Ce(n),metadata:{resource:n,authorization_servers:[i],bearer_methods_supported:e.bearerMethods??["header"],...r?.length?{scopes_supported:r}:{},...e.documentationUrl?{resource_documentation:e.documentationUrl}:{}}}}),c=a.find(e=>e.path===s);return c?Fe(c.metadata,t):s===ce&&1===a.length?Fe(a[0].metadata,t):null}(n,t,e.authorizationServer?.issuer)}return null}async function qe(e,t){const n=e.replace(/\/+$/,"")||e,r=function(e,t){const n=t.extraPaths?.[e];if(void 0===n)return null;const r="string"==typeof n?{body:n}:n;return{status:r.status??200,contentType:r.contentType??Oe(e),body:r.body,cacheControl:r.cacheControl??ke(t.cacheTtlSeconds??ae)}}(n,t);return r||("/robots.txt"===n?function(e){const t=e.robots??{},n=be(e.siteUrl),r=t.policies??[{userAgent:"*",allow:["/"]}],s=t.aiBots??"allow",i="allow"===s?[{userAgent:[...we],allow:["/"]}]:"deny"===s?[{userAgent:[...we],disallow:["/"]}]:s,o=t.sitemaps??(e.sitemap?[`${n}/sitemap.xml`]:[]),a=[`# robots.txt, agent-ready. See ${n}/llms.txt and ${n}/.well-known/agent.json`,...r.map((e,n)=>Ne(e,0===n?t.contentSignals:void 0)),...i.map(e=>Ne(e)),...o.length?[o.map(e=>`Sitemap: ${We(e)}`).join("\n")]:[]];return{status:200,contentType:me,body:a.join("\n\n")+"\n",cacheControl:ke(e.cacheTtlSeconds??ae)}}(t):"/llms-full.txt"===n?function(e){return e.llmsFullTxt?{status:200,contentType:me,body:e.llmsFullTxt,cacheControl:ke(e.cacheTtlSeconds??ae)}:null}(t):"/sitemap.xml"===n?function(e){const t=e.sitemap?.urls;if(!t?.length)return null;const n=be(e.siteUrl),r='<?xml version="1.0" encoding="UTF-8"?>\n<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">\n'+t.map(e=>{const t="string"==typeof e?{loc:e}:e;return` <url>\n${[` <loc>${Je(/^https?:\/\//.test(t.loc)?t.loc:`${n}${t.loc.startsWith("/")?"":"/"}${t.loc}`)}</loc>`,...t.lastmod?[` <lastmod>${Je(t.lastmod)}</lastmod>`]:[],...t.changefreq?[` <changefreq>${Je(String(t.changefreq))}</changefreq>`]:[],...void 0!==t.priority?[` <priority>${je(t.priority)}</priority>`]:[]].join("\n")}\n </url>`}).join("\n")+"\n</urlset>\n";return{status:200,contentType:ye,body:r,cacheControl:ke(e.cacheTtlSeconds??ae)}}(t):"/llms.txt"===n?function(e){return e.llmsTxt?{status:200,contentType:me,body:e.llmsTxt,cacheControl:ke(e.cacheTtlSeconds??ae)}:null}(t):"/auth.md"===n?function(e,t){const n=ke(e.cacheTtlSeconds??ae);if(e.authMd)return{status:200,contentType:fe,body:e.authMd,cacheControl:n};const r=t.authorizationServer;if(!r)return null;const s=`# Agent Authentication\n\n${e.site.name} supports AI-agent access via OAuth 2.0 (authorization code + PKCE).\n\n## Authorization server\n- Issuer: \`${r.issuer}\`\n- Metadata (RFC 8414): ${r.metadataUrl}\n\nFetch the metadata document above for the \`authorization_endpoint\`, \`token_endpoint\`, supported grant types / PKCE methods, and, when the app allows it, the dynamic client \`registration_endpoint\` (RFC 7591).\n\n## Protected resources (RFC 9728)\nSee \`/.well-known/oauth-protected-resource\`, which lists the resource, its supported scopes, and the authorization server(s) that can issue tokens for it.\n\n## How an agent authenticates\n1. Discover this document and \`/.well-known/oauth-protected-resource\`.\n2. Fetch the authorization-server metadata for the endpoints.\n3. Register a client (dynamic registration) or use a pre-issued client_id.\n4. Run the authorization-code flow with PKCE (S256), requesting the scopes and target \`resource\`.\n5. Exchange the code for an access token and call the API with \`Authorization: Bearer <token>\`.\n\nDocumentation: ${e.site.documentationUrl??e.siteUrl}\n`;return{status:200,contentType:fe,body:s,cacheControl:n}}(t,await Ae(t)):"/security.txt"===n?xe(t):n.startsWith("/.well-known")?Le(n,t):null)}let Be=!0;function De(e,...t){Be&&function(){try{const e="undefined"!=typeof globalThis?globalThis:null;return"development"===e?.process?.env?.NODE_ENV}catch{return!1}}()&&console.error(e,...t)}function Ge(e,...t){console.error(e,...t)}function ze(e,t){const n=AbortSignal.any;if("function"==typeof n)return n([e,t]);const r=new AbortController,s=e=>{r.signal.aborted||r.abort(e.reason)};for(const n of[e,t]){if(n.aborted){s(n);break}n.addEventListener("abort",()=>s(n),{once:!0})}return r.signal}async function Ve(e){const t=await e.text();if(!t)throw new Error("Empty response body");try{return JSON.parse(t)}catch(e){throw new Error(`Invalid JSON response: ${t.substring(0,100)}${t.length>100?"...":""}`)}}async function Ke(e,t="Request failed"){if(!e.ok){let n,r=t;try{const t=await Ve(e);r=t.message||t.error||r,"string"==typeof t.code&&(n=t.code)}catch{r=function(e,t){const n={400:"Bad Request",401:"Unauthorized - Please check your session",403:"Forbidden - You do not have permission",404:"Resource not found",500:"Internal server error",502:"Bad Gateway",503:"Service unavailable"}[e.status]||e.statusText||t;return new Error(`${t} (${e.status}: ${n})`)}(e,t).message}throw Object.assign(new Error(r),{status:e.status,...n?{code:n}:{}})}try{return await Ve(e)}catch(e){if(e instanceof Error&&e.message.includes("Invalid JSON"))throw e;throw new Error("Failed to parse response as JSON")}}class He extends Error{constructor(e,t,n,r){super(e),this.code=t,this.context=n,this.originalError=r,this.name="SDKError","undefined"!=typeof Error&&"captureStackTrace"in Error&&Error.captureStackTrace(this,He)}}const Qe=new class{constructor(){this.config={enableConsoleLogging:!0,showUserNotifications:!1},this.listeners=new Set}subscribe(e){return this.listeners.add(e),()=>{this.listeners.delete(e)}}configure(e){this.config={...this.config,...e},void 0!==e.enableConsoleLogging&&function(e){void 0!==e.enableLogging&&(Be=e.enableLogging)}({enableLogging:e.enableConsoleLogging})}handleError(e,t={}){if(function(e){return e instanceof Error&&("AbortError"===e.name||"ERR_CANCELED"===e.code)}(e))return;const n=e instanceof Error?e:new He("string"==typeof e?e:"An unknown error occurred","UNKNOWN_ERROR",t),r=n instanceof He?n:new He(n.message,"SDK_ERROR",t,n);if(this.config.enableConsoleLogging&&De(`[SDK Error] ${t.component||"Unknown"}:`,{message:r.message,code:r.code,context:r.context,originalError:r.originalError,stack:r.stack}),this.config.onError)try{this.config.onError(r,t)}catch(e){Ge("[SDK Error Handler] Error in custom error callback:",e)}for(const e of this.listeners)try{e(r,t)}catch(e){Ge("[SDK Error Handler] Error in error listener:",e)}this.config.showUserNotifications&&this.notifyUser(r,t)}notifyUser(e,t){"undefined"!=typeof window&&window.dispatchEvent&&window.dispatchEvent(new CustomEvent("sdk-error",{detail:{error:e,context:t}}))}wrapAsync(e,t){return(...n)=>e(...n).catch(e=>{throw this.handleError(e,t),e})}wrapSync(e,t){return(...n)=>{try{return e(...n)}catch(e){throw this.handleError(e,t),e}}}};function Ye(e,t={}){Qe.handleError(e,t)}function Ze(e){if("undefined"==typeof window)return null;try{return localStorage.getItem(e)}catch(t){return Ye(t,{component:"storage",action:"getStorageItem",metadata:{key:e}}),null}}const Xe="saas-session-id",et="saas-device-id";function tt(){return function(){if("undefined"==typeof window)return null;try{return Ze(Xe)}catch(e){return Ye(e,{component:"auth-utils",action:"getSessionId",metadata:{key:Xe}}),null}}()}function nt(){const e=tt(),t={};e&&(t["x-session-id"]=e);const n=function(){if("undefined"==typeof window)return null;try{return Ze(et)??null}catch(e){return Ye(e,{component:"auth-utils",action:"getOrCreateDeviceId",metadata:{key:et}}),null}}();return n&&(t["x-device-id"]=n),t}const rt=Symbol.for("@buildbase/sdk/unreachable");function st(e){return Object.defineProperty(e,rt,{value:!0}),e}const it=new WeakSet,ot=new Set(["GET","HEAD","OPTIONS","PUT","DELETE"]),at="SDK is not ready (missing serverUrl, version, or orgId)";class ct{constructor(e){this.serverUrl=e.serverUrl,this.version=e.version,this.orgId=e.orgId,this.requireOrgId=e.requireOrgId??!1,this.basePath=e.basePath??"public",this._sessionId=e.sessionId,this._timeout=e.timeout??3e4,this._maxRetries=e.maxRetries??0,this._debug=e.debug??!1,this._customHeaders=e.headers??{},this._onError=e.onError,this._onUnauthorized=e.onUnauthorized,this._fetch=e.fetch??globalThis.fetch}ensureReady(){if(!this.serverUrl?.trim()||!this.version)throw new Error(at);if(this.requireOrgId&&!this.orgId?.trim())throw new Error(at)}get baseUrl(){return this.ensureReady(),`${this.serverUrl}/api/${this.version}/${this.basePath}`}getAuthHeaders(){return this._sessionId?{"x-session-id":this._sessionId}:nt()}url(e){const t=e.startsWith("/")?e.slice(1):e;return`${this.baseUrl.endsWith("/")?this.baseUrl.slice(0,-1):this.baseUrl}/${t}`}buildHeaders(e){const t={...this._customHeaders,...this.getAuthHeaders()};return e.headers&&Object.assign(t,e.headers),null==e.body||t["Content-Type"]||(t["Content-Type"]="application/json"),t}reportError(e,t){it.has(e)||(it.add(e),this._onError?.(e,t))}async executeFetch(e,t,n={}){return this.executeFetchUrl(this.url(e),t,e,n)}notifyUnauthorized(){this._onUnauthorized?.()}static delay(e,t){return new Promise((n,r)=>{const s=()=>{clearTimeout(i),r(new DOMException("The operation was aborted.","AbortError"))};if(t?.aborted)return s();const i=setTimeout(()=>{t?.removeEventListener("abort",s),n()},e);t?.addEventListener("abort",s,{once:!0})})}async executeFetchUrl(e,t,n,r={}){const s=(t.method??"GET").toUpperCase(),i=n??e,o=this.buildHeaders(t),a={...t,headers:o},c=ot.has(s);let u,l;if(this._timeout>0){l=new AbortController;const e=l;u=setTimeout(()=>e.abort(),this._timeout),a.signal=t.signal?ze(t.signal,e.signal):e.signal}const d=e=>{if(l?.signal.aborted&&!t.signal?.aborted){const e=st(new Error(`Request timeout after ${this._timeout}ms: ${s} ${i}`));return this.reportError(e,{method:s,path:i}),e}return e},p=async t=>{try{if("function"!=typeof this._fetch)throw new Error("No fetch implementation available. Global fetch requires Node 18+; on older runtimes pass a `fetch` in the SDK config (e.g. from `undici` or `node-fetch`).");const n=this._fetch.bind(globalThis),i=await n(e,a);if(this._debug&&console.log(`[BuildBase] ${s} ${e} → ${i.status}`),401===i.status&&this._onUnauthorized&&!r.deferUnauthorized&&this._onUnauthorized(),i.status>=500&&c&&t<this._maxRetries){const e=Math.min(1e3*Math.pow(2,t),1e4);return this._debug&&console.log(`[BuildBase] Retrying in ${e}ms (attempt ${t+1}/${this._maxRetries})`),await ct.delay(e,a.signal),p(t+1)}return i}catch(e){if(e instanceof Error&&"AbortError"===e.name)throw d(e);if(c&&t<this._maxRetries){const e=Math.min(1e3*Math.pow(2,t),1e4);this._debug&&console.log(`[BuildBase] Network error, retrying in ${e}ms (attempt ${t+1}/${this._maxRetries})`);try{await ct.delay(e,a.signal)}catch(e){throw d(e)}return p(t+1)}throw e instanceof TypeError&&st(e),e instanceof Error&&this.reportError(e,{method:s,path:i}),e}};try{return await p(0)}finally{void 0!==u&&clearTimeout(u)}}async fetchJson(e,t={},n="Request failed"){this.ensureReady();try{const r=await this.executeFetch(e,t);return await Ke(r,n)}catch(n){throw n instanceof Error&&this.reportError(n,{method:(t.method??"GET").toUpperCase(),path:e}),n}}async fetchResponse(e,t={},n={}){return this.ensureReady(),this.executeFetch(e,t,n)}async fetchUnwrapped(e,t={},n="Request failed"){const r=await this.fetchResponse(e,t);return r.ok||await this.throwResponseError(r,n),this.unwrapResponse(r,n)}async fetchAbsoluteUrl(e,t={}){return this.ensureReady(),this.executeFetchUrl(e,t)}async fetchForeign(e,t={}){return this._fetch.call(globalThis,e,t)}async throwResponseError(e,t){let n=t,r=!1;try{n=(await e.json()).message||n}catch{n=`${t} (${e.status}: ${e.statusText})`,r=!0}const s=Object.assign(new Error(n),{status:e.status});throw r?st(s):s}apiPath(e,...t){return e.reduce((e,n,r)=>e+n+(r<t.length?encodeURIComponent(String(t[r])):""),"")}async unwrapResponse(e,t){const n=await e.json();if(void 0!==n.success){if(!n.success)throw new Error(n.message||t);return void 0!==n.data?n.data:n}return n}}class ut extends ct{constructor(e){super(e)}async list(e){const t=await this.fetchJson("devices",{signal:e},"Failed to load devices");return t?.devices??[]}async rename(e,t,n){await this.fetchJson(this.apiPath`devices/${e}`,{method:"PATCH",body:JSON.stringify({name:t}),signal:n},"Failed to rename device")}async signOut(e,t){return this.fetchJson(this.apiPath`devices/${e}`,{method:"DELETE",signal:t},"Failed to sign out device")}async forget(e,t){return this.fetchJson(`${this.apiPath`devices/${e}`}?forget=true`,{method:"DELETE",signal:t},"Failed to forget device")}}class lt extends ct{constructor(e){super({...e,requireOrgId:!0})}async getVapidPublicKey(){return this.fetchJson("push/vapid-public-key")}async subscribe(e,t){await this.fetchJson("push/subscribe",{method:"POST",body:JSON.stringify({endpoint:e.endpoint,keys:e.keys,userAgent:t})})}async unsubscribe(e){await this.fetchJson("push/unsubscribe",{method:"DELETE",body:JSON.stringify({endpoint:e})})}}class dt extends ct{constructor(e){super(e)}async list(e){const t=await this.fetchJson("sessions",{signal:e},"Failed to load sessions");return t?.sessions??[]}async revoke(e,t){await this.fetchJson(this.apiPath`sessions/${e}`,{method:"DELETE",signal:t},"Failed to sign out session")}}class pt extends ct{constructor(e){super({...e,requireOrgId:!0})}async getSettings(e){return this.fetchJson(`${this.orgId}/settings`,{signal:e},"Failed to fetch settings")}}const ht={png:"image/png",jpg:"image/jpeg",jpeg:"image/jpeg",gif:"image/gif",webp:"image/webp",svg:"image/svg+xml"};function gt(e){if(e.type)return e.type;const t=(e.name??"").split(".").pop()?.toLowerCase()??"";return ht[t]??""}class ft extends ct{constructor(e){super(e)}async upload(e,t){const{purpose:n,signal:r}=t,s=await this.fetchJson("uploads",{method:"POST",body:JSON.stringify({purpose:n,name:e.name??"file",size:e.size,contentType:gt(e)}),signal:r},"Could not start the upload");let i;const o=new AbortController,a=setTimeout(()=>o.abort(),12e4);try{i=await this.fetchForeign(s.url,{method:"PUT",headers:s.headers,body:e,signal:r?ze(r,o.signal):o.signal})}catch(e){if(r?.aborted)throw e;throw new Error("The upload to storage did not finish. Check the connection and try again.")}finally{clearTimeout(a)}if(!i.ok)throw Object.assign(new Error(`The upload to storage was refused (HTTP ${i.status}). Try again.`),{status:i.status});return this.fetchJson(this.apiPath`uploads/${s.uploadId}/complete`,{method:"POST",body:"{}",signal:r},"Could not finish the upload")}}class mt extends ct{constructor(e){super(e)}async getAttributes(e){const t=await this.fetchResponse("users/attributes",{signal:e});t.ok||await this.throwResponseError(t,"Failed to fetch user attributes");const n=await this.unwrapResponse(t,"Failed to fetch user attributes");return n&&"object"==typeof n&&!Array.isArray(n)?n:{}}async updateAttributes(e){return this.fetchJson("users/attributes",{method:"PATCH",body:JSON.stringify({attributes:e})},"Failed to update user attributes")}async updateAttribute(e,t){return this.fetchJson(this.apiPath`users/attributes/${e}`,{method:"PATCH",body:JSON.stringify({value:t})},"Failed to update user attribute")}async getFeatures(e){const t=await this.fetchResponse("users/features",{signal:e});t.ok||await this.throwResponseError(t,"Failed to fetch user features");const n=await this.unwrapResponse(t,"Failed to fetch user features");return"object"==typeof n&&null!==n?n:{}}}const yt={402:"SEAT_LIMIT_REACHED",404:"INVITATION_NOT_FOUND",409:"INVITATION_ALREADY_HANDLED",410:"INVITATION_EXPIRED",429:"INVITATION_RATE_LIMITED",502:"INVITATION_EMAIL_FAILED",503:"NO_SENDER_CONFIGURED"};function wt(e){return"number"==typeof e&&Number.isFinite(e)?e:void 0}function bt(e){return"string"==typeof e&&e?e:void 0}async function kt(e,t){let n=null;try{n=await e.json()}catch{n=null}return function(e,t,n){const r=t&&"object"==typeof t?t:{},s=bt(r.message)??bt(r.error)??n,i={status:e,code:bt(r.code)??yt[e]??`HTTP_${e}`,currentUserCount:wt(r.currentUserCount),limit:wt(r.limit),retryAfterSeconds:wt(r.retryAfterSeconds),invitedEmail:bt(r.invitedEmail),invitationId:bt(r.invitationId),invitationStatus:bt(r.status)};return Object.assign(new Error(s),i)}(e.status,n,t)}function vt(e){return"string"==typeof e&&e.length>0}function St(e){return"number"==typeof e&&Number.isInteger(e)&&e>0}function Et(e){return"number"==typeof e&&Number.isFinite(e)?Math.max(0,Math.ceil(e)):void 0}class Pt extends ct{constructor(e){super({...e,requireOrgId:!0})}async getWorkspaces(e){return this.fetchJson("workspaces",{signal:e},"Failed to fetch workspaces")}async createWorkspace(e,t){try{return await this.fetchJson("workspaces",{method:"POST",body:JSON.stringify(e),signal:t},"Failed to create workspace")}catch(n){const r=n?.status;if(400===r&&e.trackingAttribution){const{trackingAttribution:n,...r}=e;return this.fetchJson("workspaces",{method:"POST",body:JSON.stringify(r),signal:t},"Failed to create workspace")}throw n}}async updateWorkspace(e,t,n){return this.fetchJson(this.apiPath`workspaces/${e}`,{method:"PUT",body:JSON.stringify(t),signal:n},"Failed to update workspace")}async deleteWorkspace(e,t){return this.fetchJson(this.apiPath`workspaces/${e}`,{method:"DELETE",signal:t},"Failed to delete workspace")}async getWorkspaceUsers(e,t){return this.fetchJson(this.apiPath`workspaces/${e}/users`,{signal:t},"Failed to fetch workspace users")}async addUser(e,t,n){return this.fetchJson(this.apiPath`workspaces/${e}/users/add`,{method:"POST",body:JSON.stringify(t),signal:n},"Failed to invite member")}async fetchInvitation(e,t={},n="Request failed"){const r=await this.fetchResponse(e,t);if(!r.ok)throw await kt(r,n);return Ke(r,n)}async listInvitations(e,t){return this.fetchInvitation(this.apiPath`workspaces/${e}/invitations`,{signal:t},"Failed to fetch invitations")}async inviteMember(e,t,n){const r={email:t.email,role:t.role};return t.landingUrl&&(r.landingUrl=t.landingUrl),this.fetchInvitation(this.apiPath`workspaces/${e}/invitations`,{method:"POST",body:JSON.stringify(r),signal:n},"Failed to send invitation")}async resendInvitation(e,t,n){return this.fetchInvitation(this.apiPath`workspaces/${e}/invitations/${t}/resend`,{method:"POST",signal:n},"Failed to resend invitation")}async revokeInvitation(e,t,n){return this.fetchInvitation(this.apiPath`workspaces/${e}/invitations/${t}`,{method:"DELETE",signal:n},"Failed to revoke invitation")}async myInvitations(e){return this.fetchInvitation("invitations",{signal:e},"Failed to fetch your invitations")}async acceptInvitation(e,t,n){return this.fetchInvitation(this.apiPath`invitations/${e}/accept`,{method:"PATCH",signal:n,...t?.token?{body:JSON.stringify({token:t.token})}:{}},"Failed to accept invitation")}async declineInvitation(e,t){return this.fetchInvitation(this.apiPath`invitations/${e}/reject`,{method:"PATCH",signal:t},"Failed to decline invitation")}async previewInvitation(e,t){if(!this.orgId)throw new Error("orgId is required for previewInvitation");return this.fetchInvitation(this.apiPath`${this.orgId}/invitations/preview/${e}`,{signal:t},"Failed to load invitation")}async removeUser(e,t,n){return this.fetchJson(this.apiPath`workspaces/${e}/users/${t}`,{method:"DELETE",signal:n},"Failed to remove user")}async updateUser(e,t,n,r){return this.fetchJson(this.apiPath`workspaces/${e}/users/${t}`,{method:"PATCH",body:JSON.stringify(n),signal:r},"Failed to update user")}async updateSettings(e,t){return this.fetchJson("workspaces/settings",{method:"PATCH",body:JSON.stringify(e),signal:t},"Failed to update workspace settings")}async updateWorkspacePermissions(e,t,n){return this.fetchJson(this.apiPath`workspaces/${e}/permissions`,{method:"PATCH",body:JSON.stringify({permissions:t}),signal:n},"Failed to update workspace permissions")}async getMyPermissions(e,t){return this.fetchUnwrapped(this.apiPath`workspaces/${e}/permissions/me`,{signal:t},"Failed to fetch workspace permissions")}async getFeatures(e){return this.fetchJson("workspaces/features",{signal:e},"Failed to fetch features")}async updateFeature(e,t,n,r){return this.fetchJson(this.apiPath`workspaces/${e}/features`,{method:"PATCH",body:JSON.stringify({features:{[t]:n}}),signal:r},"Failed to update feature")}async getWorkspace(e,t){return this.fetchJson(this.apiPath`workspaces/${e}`,{signal:t},"Failed to fetch workspace")}async getProfile(e){return this.fetchJson("profile",{signal:e},"Failed to fetch profile")}async updateUserProfile(e,t){return this.fetchJson("profile",{method:"PATCH",body:JSON.stringify(e),signal:t},"Failed to update user profile")}async changePassword(e,t,n){await this.fetchWithReason("profile/password",{method:"POST",body:JSON.stringify({currentPassword:e,newPassword:t}),signal:n},"Failed to change password")}async fetchWithReason(e,t,n,r=[]){const s=r.length>0,i=await this.fetchResponse(e,t,{deferUnauthorized:s});if(!i.ok){let e,t,o=n,a={},c=!1;try{const n=await i.json();"string"==typeof n?.message&&n.message&&(o=n.message),"string"==typeof n?.reason&&n.reason&&(e=n.reason),t=Et(n?.retryAfter),a=function(e){if(!e||"object"!=typeof e)return{};const{maxAgeSeconds:t,factors:n,workspaces:r}=e,s={},i=Et(t);if(void 0!==i&&(s.maxAgeSeconds=i),Array.isArray(n)){const e=n.filter(e=>"mfa"===e);e.length&&(s.factors=e)}return Array.isArray(r)&&(s.workspaces=r.filter(e=>!!e&&"object"==typeof e&&"string"==typeof e.id&&"string"==typeof e.name).map(({id:e,name:t})=>({id:e,name:t}))),s}(n)}catch{o=`${n} (${i.status}: ${i.statusText})`,c=!0}!s||401!==i.status||void 0!==e&&r.includes(e)||this.notifyUnauthorized();const u=Object.assign(new Error(o),{status:i.status,...e?{code:e}:{},...void 0!==t?{retryAfter:t}:{},...a});throw c?st(u):u}return this.unwrapResponse(i,n)}static compactCode(e){return e.replace(/\s+/g,"")}async requestEmailChange(e,t){const n=await this.fetchWithReason("profile/email",{method:"POST",body:JSON.stringify({newEmail:e.trim()}),signal:t},"Failed to send the code");return{retryAfter:Et(n?.retryAfter)??0}}async confirmEmailChange(e,t){return this.fetchWithReason("profile/email/confirm",{method:"POST",body:JSON.stringify({code:Pt.compactCode(e)}),signal:t},"Failed to change email",["code_expired"])}async addPhone(e,t,n){const r=await this.fetchWithReason("profile/phone",{method:"POST",body:JSON.stringify({phone:e.trim(),...t?{channel:t}:{}}),signal:n},"Failed to send the code");return{retryAfter:Et(r?.retryAfter)??0}}async confirmPhone(e,t){const n=await this.fetchWithReason("profile/phone/confirm",{method:"POST",body:JSON.stringify({code:Pt.compactCode(e)}),signal:t},"Failed to verify the phone number");return{phone:"string"==typeof n?.phone?n.phone:"",phoneVerified:!0}}async removePhone(e){await this.fetchWithReason("profile/phone",{method:"DELETE",signal:e},"Failed to remove the phone number")}async getMfaStatus(e){return this.fetchWithReason("mfa",{signal:e},"Failed to fetch two-step sign-in status")}async startTotpEnrollment(e){return this.fetchWithReason("mfa/totp/enroll",{method:"POST",signal:e},"Failed to start authenticator app setup")}async confirmTotpEnrollment(e,t){return this.fetchWithReason("mfa/totp/confirm",{method:"POST",body:JSON.stringify({code:Pt.compactCode(e)}),signal:t},"Failed to confirm authenticator app")}async disableTotp(e,t){await this.fetchWithReason("mfa/totp/disable",{method:"POST",body:JSON.stringify({code:Pt.compactCode(e)}),signal:t},"Failed to turn off two-step sign-in")}async regenerateBackupCodes(e,t){return this.fetchWithReason("mfa/backup-codes/regenerate",{method:"POST",body:JSON.stringify({code:Pt.compactCode(e)}),signal:t},"Failed to make new backup codes")}async startSmsEnrollment(e){const t=await this.fetchWithReason("mfa/sms/enroll",{method:"POST",signal:e},"Failed to send the code");return{retryAfter:Et(t?.retryAfter)??0,..."string"==typeof t?.phone&&t.phone?{phone:t.phone}:{}}}async confirmSmsEnrollment(e,t){const n=await this.fetchWithReason("mfa/sms/enroll/confirm",{method:"POST",body:JSON.stringify({code:Pt.compactCode(e)}),signal:t},"Failed to turn on text message codes"),r=n?.backupCodes;return Array.isArray(r)&&r.length>0&&r.every(e=>"string"==typeof e)?{backupCodes:r}:{}}async disableSms(e){await this.fetchWithReason("mfa/sms/disable",{method:"POST",signal:e},"Failed to turn off text message codes")}async getPasskeys(e){const t=await this.fetchJson("passkeys",{signal:e},"Failed to fetch passkeys");return t?.passkeys??[]}async renamePasskey(e,t,n){await this.fetchWithReason(this.apiPath`passkeys/${e}`,{method:"PATCH",body:JSON.stringify({name:t}),signal:n},"Failed to rename passkey")}async deletePasskey(e,t){await this.fetchWithReason(this.apiPath`passkeys/${e}`,{method:"DELETE",signal:t},"Failed to remove passkey")}async getConnectedAccounts(e){const t=await this.fetchWithReason("accounts",{signal:e},"Failed to fetch connected accounts"),n=Array.isArray(t?.accounts)?t.accounts:[],r=Array.isArray(t?.available)?t.available:[],s=function(e){if(!e||"object"!=typeof e)return;const{ethereumChainIds:t,solana:n}=e,r=Array.isArray(t)?t.filter(St):[];return 0!==r.length||!0===n?{ethereumChainIds:r,solana:!0===n}:void 0}(t?.wallet);return{accounts:n.filter(e=>"string"==typeof e?._id&&!!e._id).map(({detail:e,...t})=>({...t,label:"string"==typeof t.label&&t.label?t.label:t.provider,..."string"==typeof e&&e?{detail:e}:{},canUnlink:!0===t.canUnlink})),available:r.filter(e=>"string"==typeof e?.methodId&&!!e.methodId).map(e=>({...e,label:"string"==typeof e.label&&e.label?e.label:e.provider})),...s?{wallet:s}:{},signInWays:"number"==typeof t?.signInWays&&Number.isFinite(t.signInWays)?t.signInWays:0,recentSignIn:!0===t?.recentSignIn}}async linkAccount(e,t,n){const r=await this.fetchWithReason("accounts",{method:"POST",body:JSON.stringify({methodId:e,redirect:t}),signal:n},"Failed to start connecting the account");if("string"!=typeof r?.url||!r.url)throw new Error("Failed to start connecting the account: the server sent no URL");return{url:r.url}}async unlinkAccount(e,t){await this.fetchWithReason(this.apiPath`accounts/${e}`,{method:"DELETE",signal:t},"Failed to remove the connected account")}async requestWalletNonce(e,t){const n=await this.fetchWithReason("accounts/wallet/nonce",{method:"POST",body:JSON.stringify({chain:e}),signal:t},"Failed to start connecting the wallet"),{nonce:r,domain:s,uri:i,issuedAt:o}=n??{};if(!(vt(r)&&vt(s)&&vt(i)&&vt(o)))throw new Error("Failed to start connecting the wallet: the server sent no nonce");const a=Array.isArray(n?.chainIds)?n.chainIds.filter(St):void 0;return{nonce:r,domain:s,uri:i,issuedAt:o,...a?{chainIds:a}:{}}}async linkWallet(e,t){const{chain:n,message:r,signature:s}=e,i=await this.fetchWithReason("accounts/wallet",{method:"POST",body:JSON.stringify({chain:n,message:r,signature:s}),signal:t},"Failed to connect the wallet",["nonce_expired"]);if(!vt(i?._id))throw new Error("Failed to connect the wallet: the server sent no account");const o=vt(i.provider)?i.provider:n;return{_id:i._id,provider:o,label:vt(i.label)?i.label:o,...vt(i.icon)?{icon:i.icon}:{},...vt(i.detail)?{detail:i.detail}:{},canUnlink:!1}}async startReverification(e,t){const{returnUrl:n,factors:r}=e,s=await this.fetchWithReason("session/reverify",{method:"POST",body:JSON.stringify({returnUrl:n,...r?.length?{factors:r}:{}}),signal:t},"Failed to start confirming it is you");if(!vt(s?.url))throw new Error("Failed to start confirming it is you: the server sent no URL");return{url:s.url}}async requestAccountDeletion(e){const t=await this.fetchWithReason("account/delete",{method:"POST",signal:e},"Failed to delete the account");return{deleteAfter:vt(t?.deleteAfter)?t.deleteAfter:null,deleted:!0===t?.deleted||null===t?.deleteAfter}}async cancelAccountDeletion(e){const t=await this.fetchWithReason("account/delete/cancel",{method:"POST",signal:e},"Failed to cancel the deletion");return{cancelled:!0===t?.cancelled}}async setUsername(e,t){const n=e.trim(),r=await this.fetchWithReason("profile/username",{method:"PUT",body:JSON.stringify({username:n}),signal:t},"Failed to save the username");return{username:vt(r?.username)?r.username:n.toLowerCase()}}async removeUsername(e){await this.fetchWithReason("profile/username",{method:"DELETE",signal:e},"Failed to remove the username")}async requestGuestUpgrade(e,t){const n=e.name?.trim(),r=await this.fetchWithReason("guest/upgrade",{method:"POST",body:JSON.stringify({email:e.email.trim(),...n?{name:n}:{},...e.password?{password:e.password}:{}}),signal:t},"Failed to send the code");return{retryAfter:Et(r?.retryAfter)??0}}async confirmGuestUpgrade(e,t){return this.fetchWithReason("guest/upgrade/confirm",{method:"POST",body:JSON.stringify({code:Pt.compactCode(e)}),signal:t},"Failed to create your account")}async getCurrentSubscription(e,t){return this.fetchUnwrapped(this.apiPath`workspaces/${e}/subscription`,{signal:t},"Failed to fetch subscription")}async getPlanGroup(e,t){return this.fetchUnwrapped(this.apiPath`workspaces/${e}/subscription/plan-group`,{signal:t},"Failed to fetch plan group")}async getPlanGroupByVersion(e,t,n){return this.fetchUnwrapped(this.apiPath`workspaces/${e}/subscription/plan-group`+`?groupVersionId=${encodeURIComponent(t)}`,{signal:n},"Failed to fetch plan group version")}async getPlanGroupVersions(e,t){return this.fetchUnwrapped(this.apiPath`workspaces/${e}/subscription/plan-group/versions`,{signal:t},"Failed to fetch plan group versions")}async getPublicPlans(e,t){if(!this.orgId)throw new Error("orgId is required for getPublicPlans");return this.fetchUnwrapped(this.apiPath`${this.orgId}/plans/${encodeURIComponent(e)}`,{signal:t},"Failed to fetch plans")}async getPublicCreditPackages(e){if(!this.orgId)throw new Error("orgId is required for getPublicCreditPackages");return this.fetchUnwrapped(this.apiPath`${this.orgId}/credit-packages`,{signal:e},"Failed to fetch credit packages")}async getPlanGroupVersion(e,t){return this.fetchUnwrapped(this.apiPath`plan-group-versions/${e}`,{signal:t},"Failed to fetch plan group version")}async createCheckoutSession(e,t,n){return this.fetchUnwrapped(this.apiPath`workspaces/${e}/subscription/checkout`,{method:"POST",body:JSON.stringify(t),signal:n},"Failed to create checkout session")}async selectFreePlan(e,t,n){return this.fetchUnwrapped(this.apiPath`workspaces/${e}/subscription/select-free-plan`,{method:"POST",body:JSON.stringify({planVersionId:t}),signal:n},"Failed to select free plan")}async updateSubscription(e,t,n){return this.fetchUnwrapped(this.apiPath`workspaces/${e}/subscription`,{method:"PATCH",body:JSON.stringify(t),signal:n},"Failed to update subscription")}async createBillingPortalSession(e,t,n){return this.fetchJson(this.apiPath`workspaces/${e}/subscription/billing-portal`,{method:"POST",body:JSON.stringify(t?{returnUrl:t}:{}),signal:n})}async listInvoices(e,t=10,n,r){const s=new URLSearchParams;return s.append("limit",t.toString()),n&&s.append("starting_after",n),this.fetchUnwrapped(this.apiPath`workspaces/${e}/subscription/invoices`+`?${s.toString()}`,{signal:r},"Failed to fetch invoices")}async getInvoice(e,t,n){return this.fetchUnwrapped(this.apiPath`workspaces/${e}/subscription/invoices/${t}`,{signal:n},"Failed to fetch invoice")}async cancelSubscriptionAtPeriodEnd(e,t){return this.fetchUnwrapped(this.apiPath`workspaces/${e}/subscription/cancel-at-period-end`,{method:"POST",signal:t},"Failed to cancel subscription")}async resumeSubscription(e,t){return this.fetchUnwrapped(this.apiPath`workspaces/${e}/subscription/resume`,{method:"POST",signal:t},"Failed to resume subscription")}async recordUsage(e,t,n){return this.fetchUnwrapped(this.apiPath`workspaces/${e}/subscription/usage`,{method:"POST",body:JSON.stringify(t),signal:n},"Failed to record usage")}async recordUsageBatch(e,t,n){return this.fetchUnwrapped(this.apiPath`workspaces/${e}/subscription/usage/batch`,{method:"POST",body:JSON.stringify(t),signal:n},"Failed to record batch usage")}async getQuotaUsageStatus(e,t,n){return this.fetchUnwrapped(this.apiPath`workspaces/${e}/subscription/usage/status`+`?quotaSlug=${encodeURIComponent(t)}`,{signal:n},"Failed to fetch quota usage status")}async getAllQuotaUsage(e,t){return this.fetchUnwrapped(this.apiPath`workspaces/${e}/subscription/usage/all`,{signal:t},"Failed to fetch all quota usage")}async getUsageLogs(e,t,n){const r=new URLSearchParams;t?.quotaSlug&&r.append("quotaSlug",t.quotaSlug),t?.from&&r.append("from",t.from),t?.to&&r.append("to",t.to),t?.source&&r.append("source",t.source),t?.page&&r.append("page",t.page.toString()),t?.limit&&r.append("limit",t.limit.toString());const s=r.toString(),i=this.apiPath`workspaces/${e}/subscription/usage/logs`+(s?`?${s}`:"");return this.fetchUnwrapped(i,{signal:n},"Failed to fetch usage logs")}async sendNotification(e,t,n,r,s){const i={event:t};return n&&(i.userId=n),r&&(i.data=r),this.fetchJson(this.apiPath`workspaces/${e}/notifications/send`,{method:"POST",body:JSON.stringify(i),signal:s},"Failed to send notification")}async getNotificationEvents(e,t){return this.fetchJson(this.apiPath`workspaces/${e}/notification-events`,{signal:t},"Failed to fetch notification events")}async getNotificationPreferences(e,t){return(await this.fetchJson(this.apiPath`workspaces/${e}/notification-preferences`,{signal:t},"Failed to fetch notification preferences")).notificationPreferences??{}}async updateNotificationPreferences(e,t,n){return(await this.fetchJson(this.apiPath`workspaces/${e}/notification-preferences`,{method:"PATCH",body:JSON.stringify({notificationPreferences:t}),signal:n},"Failed to update notification preferences")).notificationPreferences??{}}async getMyNotificationPreferences(e,t){const n=await this.fetchJson(this.apiPath`workspaces/${e}/notification-preferences/me`,{signal:t},"Failed to fetch your notification preferences");return{defaults:n?.defaults??{},mine:n?.mine??{}}}async updateMyNotificationPreferences(e,t,n){const r=await this.fetchJson(this.apiPath`workspaces/${e}/notification-preferences/me`,{method:"PATCH",body:JSON.stringify({notificationPreferences:t}),signal:n},"Failed to update your notification preferences");return{defaults:r?.defaults??{},mine:r?.mine??{}}}async getCreditBalance(e,t){return this.fetchUnwrapped(this.apiPath`workspaces/${e}/credits`,{signal:t},"Failed to fetch credit balance")}async consumeCredits(e,t,n){const r=await this.fetchResponse(this.apiPath`workspaces/${e}/credits/consume`,{method:"POST",body:JSON.stringify(t),signal:n});if(!r.ok){if(402===r.status){const e=await r.json().catch(()=>({})),t=new Error(e.message||"Insufficient credits");throw t.available=e.available,t.requested=e.requested,t.code="INSUFFICIENT_CREDITS",t}await this.throwResponseError(r,"Failed to consume credits")}return this.unwrapResponse(r,"Failed to consume credits")}async purchaseCredits(e,t,n){return this.fetchUnwrapped(this.apiPath`workspaces/${e}/credits/purchase`,{method:"POST",body:JSON.stringify(t),signal:n},"Failed to create credit purchase checkout")}async getCreditPackages(e,t){const n=await this.fetchUnwrapped(this.apiPath`workspaces/${e}/credits/packages`,{signal:t},"Failed to fetch credit packages");return n.docs??n}async getCreditTransactions(e,t,n){const r=new URLSearchParams;t?.type&&r.append("type",t.type),t?.page&&r.append("page",t.page.toString()),t?.limit&&r.append("limit",t.limit.toString());const s=r.toString(),i=this.apiPath`workspaces/${e}/credits/transactions`+(s?`?${s}`:"");return this.fetchUnwrapped(i,{signal:n},"Failed to fetch credit transactions")}async getCreditBuckets(e,t,n){const r=new URLSearchParams;t?.status&&r.append("status",t.status),t?.source&&r.append("source",t.source),t?.page&&r.append("page",t.page.toString()),t?.limit&&r.append("limit",t.limit.toString());const s=r.toString(),i=this.apiPath`workspaces/${e}/credits/buckets`+(s?`?${s}`:"");return this.fetchUnwrapped(i,{signal:n},"Failed to fetch credit buckets")}async getExpiringCredits(e,t,n){const r=t?`?days=${t}`:"";return this.fetchUnwrapped(this.apiPath`workspaces/${e}/credits/expiring`+r,{signal:n},"Failed to fetch expiring credits")}}const It={WORKSPACE_SETTINGS_VIEW:"workspace:settings:view",WORKSPACE_SETTINGS_EDIT:"workspace:settings:edit",WORKSPACE_DELETE:"workspace:delete",WORKSPACE_MEMBERS_VIEW:"workspace:members:view",WORKSPACE_MEMBERS_INVITE:"workspace:members:invite",WORKSPACE_MEMBERS_REMOVE:"workspace:members:remove",WORKSPACE_MEMBERS_ROLE_CHANGE:"workspace:members:role-change",WORKSPACE_FEATURES_VIEW:"workspace:features:view",WORKSPACE_FEATURES_EDIT:"workspace:features:edit",WORKSPACE_BILLING_VIEW:"workspace:billing:view",WORKSPACE_BILLING_MANAGE:"workspace:billing:manage",WORKSPACE_USAGE_VIEW:"workspace:usage:view",WORKSPACE_USAGE_RECORD:"workspace:usage:record"},Tt=Object.values(It),_t={admin:Tt.filter(e=>e!==It.WORKSPACE_DELETE),editor:[It.WORKSPACE_SETTINGS_VIEW,It.WORKSPACE_MEMBERS_VIEW,It.WORKSPACE_FEATURES_VIEW,It.WORKSPACE_BILLING_VIEW,It.WORKSPACE_USAGE_VIEW,It.WORKSPACE_USAGE_RECORD],viewer:[It.WORKSPACE_SETTINGS_VIEW,It.WORKSPACE_MEMBERS_VIEW]};function Ut(e){const t=new Set;for(const n of Object.values(e))for(const e of n)t.add(e);return Array.from(t)}function At(e){const{userId:t,workspace:n,settings:r,appPermissions:s}=e;if(!n||!t)return new Set;if(function(e,t){if(!t)return!1;const n=(r=e.createdBy)?"string"==typeof r?r:"object"==typeof r&&"_id"in r&&"string"==typeof r._id?r._id:null:null;var r;return null!==n&&n===t}(n,t)){const e=new Set(Tt);if(s)for(const t of Ut(s))e.add(t);if(n.permissions)for(const t of Ut(n.permissions))e.add(t);if(r?.workspace?.permissions)for(const t of Ut(r.workspace.permissions))e.add(t);return e}const i=e.workspaceRole??function(e,t){if(!t||!e.users||!Array.isArray(e.users))return null;const n=e.users.find(e=>"string"==typeof e?e===t:"object"==typeof e&&null!==e&&"_id"in e&&e._id===t);return n&&"object"==typeof n&&"role"in n&&"string"==typeof n.role?n.role:null}(n,t);return i?function(e,t,n={}){const{workspace:r,settings:s,appPermissions:i}=t;if(!r)return new Set;const o=r.permissions,a=s?.workspace?.permissions,c=e=>e.filter(e=>e.startsWith("workspace:")),u=e=>e.filter(e=>!e.startsWith("workspace:")),l=e=>!!o&&e in o,d=e=>!!a&&e in a,p=e=>l(e)||d(e)||e in _t;let h,g=e;if(!p(e)){const e=s?.workspace?.defaultRole;if(!e||"admin"===e||!p(e))return new Set;g=e}h=l(g)?c(o[g]):d(g)?c(a[g]):_t[g]??[];const f=new Set(h),m=new Set((s?.workspace?.customPermissions??[]).map(e=>e.key)),y=i?.[g]?u(i[g]).filter(e=>!m.has(e)):[];let w;w=l(g)?u(o[g]):d(g)?[...u(a[g]),...y]:i?.[g]?u(i[g]):[];for(const e of w)f.add(e);if("admin"===g){for(const e of _t.admin)f.add(e);for(const e of m)f.add(e);if(i)for(const e of u(Ut(i)))f.add(e)}!1!==n.applyRestrictions&&function(e,t,n){if(!n?.workspace)return;const{canInviteMembers:r}=n.workspace;(!1===r||"admin-only"===r&&"admin"!==t)&&e.delete(It.WORKSPACE_MEMBERS_INVITE)}(f,g,s);return f}(i,e):new Set}function Ct(e){const{serverUrl:t,orgId:n,version:r="v1",region:s,getSessionId:i,timeout:o,maxRetries:a,debug:c,headers:u,onError:l,fetch:d}=e;if(!t)throw new Error("BuildBase: serverUrl is required");if(!n)throw new Error("BuildBase: orgId is required");const p={...void 0!==o&&{timeout:o},...void 0!==a&&{maxRetries:a},...void 0!==c&&{debug:c},...u&&{headers:u},...l&&{onError:l},...d&&{fetch:d}},h=e=>{const s={serverUrl:t,version:r,orgId:n,sessionId:e,...p};return{workspace:new Pt(s),user:new mt(s),settings:new pt(s),push:new lt(s),devices:new ut(s),uploads:new ft(s),sessions:new dt(s)}},g=new Pt({serverUrl:t,version:r,orgId:n,...p}),f=e=>({workspace:{list:async()=>(await e()).workspace.getWorkspaces(),get:async t=>(await e()).workspace.getWorkspace(t),create:async t=>(await e()).workspace.createWorkspace(t),update:async(t,n)=>(await e()).workspace.updateWorkspace(t,n),delete:async t=>(await e()).workspace.deleteWorkspace(t),permissions:async t=>(await e()).workspace.getMyPermissions(t),can:async(t,n)=>{const{permissions:r}=await(await e()).workspace.getMyPermissions(t),s=new Set(r);return(Array.isArray(n)?n:[n]).every(e=>s.has(e))}},invitations:{list:async t=>(await e()).workspace.listInvitations(t),create:async(t,n,r,s)=>(await e()).workspace.inviteMember(t,{email:n,role:r,landingUrl:s}),resend:async(t,n)=>(await e()).workspace.resendInvitation(t,n),revoke:async(t,n)=>(await e()).workspace.revokeInvitation(t,n)},users:{list:async t=>(await e()).workspace.getWorkspaceUsers(t),invite:async(t,n,r)=>(await e()).workspace.addUser(t,{email:n,role:r}),remove:async(t,n)=>(await e()).workspace.removeUser(t,n),updateRole:async(t,n,r)=>(await e()).workspace.updateUser(t,n,{role:r}),getProfile:async()=>(await e()).workspace.getProfile(),updateProfile:async t=>(await e()).workspace.updateUserProfile(t)},subscription:{get:async t=>(await e()).workspace.getCurrentSubscription(t),checkout:async(t,n)=>(await e()).workspace.createCheckoutSession(t,n),update:async(t,n)=>(await e()).workspace.updateSubscription(t,n),cancel:async t=>(await e()).workspace.cancelSubscriptionAtPeriodEnd(t),resume:async t=>(await e()).workspace.resumeSubscription(t),getBillingPortalUrl:async(t,n)=>(await e()).workspace.createBillingPortalSession(t,n)},plans:{getGroup:async t=>(await e()).workspace.getPlanGroup(t),getVersions:async t=>(await e()).workspace.getPlanGroupVersions(t),getPublic:e=>g.getPublicPlans(e),getVersion:e=>g.getPlanGroupVersion(e)},invoices:{list:async(t,n,r)=>(await e()).workspace.listInvoices(t,n,r),get:async(t,n)=>(await e()).workspace.getInvoice(t,n)},usage:{record:async(t,n)=>(await e()).workspace.recordUsage(t,n),recordBatch:async(t,n)=>(await e()).workspace.recordUsageBatch(t,n),getQuota:async(t,n)=>(await e()).workspace.getQuotaUsageStatus(t,n),getAll:async t=>(await e()).workspace.getAllQuotaUsage(t),getLogs:async(t,n)=>(await e()).workspace.getUsageLogs(t,n)},settings:{get:async()=>(await e()).settings.getSettings()},features:{list:async()=>(await e()).workspace.getFeatures(),update:async(t,n,r)=>(await e()).workspace.updateFeature(t,n,r)},notification:{send:async(t,n,r,s)=>(await e()).workspace.sendNotification(t,n,r,s)},credits:{getBalance:async t=>(await e()).workspace.getCreditBalance(t),consume:async(t,n)=>(await e()).workspace.consumeCredits(t,n),purchase:async(t,n)=>(await e()).workspace.purchaseCredits(t,n),getPackages:async t=>(await e()).workspace.getCreditPackages(t),getTransactions:async(t,n)=>(await e()).workspace.getCreditTransactions(t,n),getBuckets:async(t,n)=>(await e()).workspace.getCreditBuckets(t,n),getExpiring:async(t,n)=>(await e()).workspace.getExpiringCredits(t,n),getPublicPackages:()=>g.getPublicCreditPackages()},permissions:{check:async(t,n,r)=>{const s=await e(),[i,o,a]=await Promise.all([s.workspace.getWorkspace(t),s.settings.getSettings(),s.workspace.getWorkspaceUsers(t)]),c=a.find(e=>("string"==typeof e.user?e.user:e.user._id)===n);return function(e,t){const n=At(t);return Array.isArray(e)?e.every(e=>n.has(e)):n.has(e)}(r,{userId:n,workspaceRole:c?.role??null,workspace:i,settings:o})},resolve:async(t,n)=>{const r=await e(),[s,i,o]=await Promise.all([r.workspace.getWorkspace(t),r.settings.getSettings(),r.workspace.getWorkspaceUsers(t)]),a=o.find(e=>("string"==typeof e.user?e.user:e.user._id)===n);return At({userId:n,workspaceRole:a?.role??null,workspace:s,settings:i})}},devices:{list:async()=>(await e()).devices.list(),rename:async(t,n)=>(await e()).devices.rename(t,n),signOut:async t=>(await e()).devices.signOut(t),forget:async t=>(await e()).devices.forget(t)},sessions:{list:async()=>(await e()).sessions.list(),revoke:async t=>(await e()).sessions.revoke(t)}}),m=f(async()=>h(await(async()=>{if(!i)throw new Error("BuildBase: getSessionId callback is required for authenticated calls. Pass it in BuildBase({ getSessionId: ... }) or use withSession(id) / client.forSession(id).");const e=await i();if(!e)throw new Error("BuildBase: Not authenticated (getSessionId returned null)");return e})()));return{...void 0!==s&&{region:s},auth:async()=>{if(!i)return null;const e=await i();return e?{sessionId:e}:null},withSession:e=>{const t=h(e);return f(async()=>t)},client:{forSession:h},...m}}function $t(e){const t=be(e.siteUrl),n=e.mcp?.path??"/api/mcp",r=`${t}${n.startsWith("/")?n:`/${n}`}`,s=e.mcp?.serverInfo??{name:e.site.name,version:"1.0.0"},i=`${t}/mcp`,o=Array.from(new Set([i,r])),a=e.mcp?.auth??(e.secret?oe({secret:e.secret,resource:o,resourceMetadataUrl:`${t}/.well-known/oauth-protected-resource/mcp`,requireAudience:!0}):void 0);if(void 0===a)throw new Error("createAgentStack: pass `secret` (the app token-signing secret) to derive auth, or set `mcp.auth` yourself (`false` disables auth — local development only).");const c=Q({buildbase:e.mcp?.buildbase??Ct({serverUrl:e.serverUrl,orgId:e.orgId}),serverInfo:s,auth:a,tools:e.mcp?.tools,builtinTools:e.mcp?.builtinTools??"readonly",...e.mcp?.handler}),u={serverUrl:e.serverUrl,orgId:e.orgId,siteUrl:e.siteUrl,site:e.site,mcpServerCard:c.serverCard({endpoint:r,...e.site.description?{description:e.site.description}:{},...e.site.documentationUrl?{documentationUrl:e.site.documentationUrl}:{}}),...e.scopes?{scopes:e.scopes}:{},protectedResources:o.map(t=>({resource:t,...e.mcp?.scopes?.length?{scopes:e.mcp.scopes}:{},...e.site.documentationUrl?{documentationUrl:e.site.documentationUrl}:{}})).concat([{resource:t,...e.site.documentationUrl?{documentationUrl:e.site.documentationUrl}:{}}]),apiCatalog:[{anchor:r,title:`${e.site.name} MCP server`,serviceDesc:`${t}/.well-known/mcp/server-card.json`}],...e.discovery},l={"Access-Control-Allow-Origin":"*","Access-Control-Allow-Methods":"GET, OPTIONS"};const d=e=>c.fetch(e);return{mcp:c,mcpEndpoint:r,config:u,linkHeader:Me(u),resolvePath:e=>qe(e,u),serveAgentPath:async function(e){if("OPTIONS"===e.method.toUpperCase())return new Response(null,{status:204,headers:l});const t=await qe(new URL(e.url).pathname,u);return t?new Response(t.body,{status:t.status,headers:{"Content-Type":t.contentType,"Cache-Control":t.cacheControl,...t.vary?{Vary:t.vary}:{},...l}}):new Response(JSON.stringify({error:"not_found"}),{status:404,headers:{"Content-Type":"application/json",...l}})},routes:{GET:d,POST:d,DELETE:d,OPTIONS:d}}}export{u as AppBridgeError,m as bearerChallenge,oe as buildbaseAuth,E as builtinMcpTools,$t as createAgentStack,Q as createMcpHandler,re as createSessionRefCrypto,O as defineMcpPrompt,$ as defineMcpResource,x as defineMcpResourceTemplate,Y as defineMcpTool,p as extractBearerToken,_ as mcpAudio,A as mcpEmbeddedResource,T as mcpImage,U as mcpResourceLink,I as mcpText,se as mintAgentToken,P as selectBuiltinTools,g as signClientJwt,d as verifyClientJwt};
|