@buildbase/sdk 0.0.79 → 0.0.81

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/dist/index.d.ts +2 -0
  3. package/dist/mcp/index.cjs +1 -1
  4. package/dist/mcp/index.mjs +1 -1
  5. package/dist/react/chunks/{SettingsDialog-jJxOT6-j.mjs → SettingsDialog-BOCot3J_.mjs} +1 -1
  6. package/dist/react/chunks/{SettingsDialog-oJ031H7P.cjs → SettingsDialog-CUBciXwN.cjs} +1 -1
  7. package/dist/react/chunks/SubscriptionDialog-0FsCZJTS.cjs +2 -0
  8. package/dist/react/chunks/SubscriptionDialog-DLAas784.mjs +2 -0
  9. package/dist/react/chunks/ar-CY5Dq0by.cjs +2 -0
  10. package/dist/react/chunks/ar-Dex5Ufml.mjs +2 -0
  11. package/dist/react/chunks/de-3FhmseQO.mjs +2 -0
  12. package/dist/react/chunks/de-DNxAYrVz.cjs +2 -0
  13. package/dist/react/chunks/es-CkPgg0z3.cjs +2 -0
  14. package/dist/react/chunks/es-D24eERya.mjs +2 -0
  15. package/dist/react/chunks/fr-BFy3cJkq.mjs +2 -0
  16. package/dist/react/chunks/fr-CtjhOWPB.cjs +2 -0
  17. package/dist/react/chunks/hi-B_O-ka_f.cjs +2 -0
  18. package/dist/react/chunks/hi-B_enIYaV.mjs +2 -0
  19. package/dist/react/chunks/ja-DvcJc9aC.mjs +2 -0
  20. package/dist/react/chunks/ja-DxP_yPZv.cjs +2 -0
  21. package/dist/react/chunks/react-BE4DCscY.cjs +2 -0
  22. package/dist/react/chunks/react-CDLs_iVH.mjs +2 -0
  23. package/dist/react/chunks/zh-Ca0rUF4N.cjs +2 -0
  24. package/dist/react/chunks/zh-CsEL_Cc6.mjs +2 -0
  25. package/dist/react/index.cjs +1 -1
  26. package/dist/react/index.d.ts +2 -0
  27. package/dist/react/index.mjs +1 -1
  28. package/package.json +2 -2
  29. package/dist/react/chunks/SubscriptionDialog-CDBtbbJi.mjs +0 -2
  30. package/dist/react/chunks/SubscriptionDialog-DgBEfcU8.cjs +0 -2
  31. package/dist/react/chunks/ar-CRVhjpVE.cjs +0 -2
  32. package/dist/react/chunks/ar-DFPDdu2U.mjs +0 -2
  33. package/dist/react/chunks/de-BGhzn711.cjs +0 -2
  34. package/dist/react/chunks/de-Bqi8scew.mjs +0 -2
  35. package/dist/react/chunks/es-D_Eqhob3.mjs +0 -2
  36. package/dist/react/chunks/es-DyrMaeUp.cjs +0 -2
  37. package/dist/react/chunks/fr-C0SkloRr.cjs +0 -2
  38. package/dist/react/chunks/fr-DkZpFQ1Q.mjs +0 -2
  39. package/dist/react/chunks/hi-B9TK87T8.cjs +0 -2
  40. package/dist/react/chunks/hi-DrTcPkiY.mjs +0 -2
  41. package/dist/react/chunks/ja-Dgahn--0.mjs +0 -2
  42. package/dist/react/chunks/ja-LjzlAhAT.cjs +0 -2
  43. package/dist/react/chunks/react-4qMM6kB7.mjs +0 -2
  44. package/dist/react/chunks/react-6MIS8oUC.cjs +0 -2
  45. package/dist/react/chunks/zh-BezRHDHs.mjs +0 -2
  46. package/dist/react/chunks/zh-CcodKi4U.cjs +0 -2
package/CHANGELOG.md CHANGED
@@ -5,6 +5,58 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.0.81] - 2026-10-10
9
+
10
+ ### Fixed
11
+
12
+ - **A freemium plan's call to action no longer reads "Subscribe".** The pricing
13
+ table gave the $0 column the same button as a paid plan without a trial, and
14
+ there is nothing to subscribe to there: no Stripe object, no payment method
15
+ and nothing to cancel. It is also the first word a free customer reads, on
16
+ the one column meant to feel like no commitment. `startFree` is added across
17
+ all eight locales and used when the plan is freemium and there is no current
18
+ subscription. The paid columns are unchanged - a plan with a trial still
19
+ reads "Start 7-day Free Trial", and one without still reads "Subscribe",
20
+ which for them is accurate.
21
+
22
+ ## [0.0.80] - 2026-10-09
23
+
24
+ ### Fixed
25
+
26
+ - **Every built-in MCP tool now carries a `title` and an explicit read-only or
27
+ destructive annotation.** Anthropic's Claude Connectors Directory review
28
+ requires both on every exposed tool, and neither was there. All 42 built-ins
29
+ shared a bare `{ readOnlyHint: true }` constant or an inline object, so not
30
+ one had a human-readable title — a client had only the snake_case name to
31
+ show. Twelve writes declared no `destructiveHint` at all, and the MCP schema
32
+ defaults that hint to **true** whenever `readOnlyHint` is false, so additive
33
+ writes — creating a workspace, inviting a member, recording usage, setting a
34
+ feature flag — were advertised to clients as destructive and prompted for a
35
+ confirmation they never needed. All 42 built-ins are now titled
36
+ (`List Workspaces`, `Get Subscription`, `Invite Member`, and so on), all 18
37
+ writes state `destructiveHint` outright, and the 24 read-only tools carry
38
+ nothing beyond the title and `readOnlyHint: true`. Existing `idempotentHint` and
39
+ `openWorldHint` values are unchanged. Nothing in the handler changed:
40
+ `McpToolAnnotations` already allowed `title` and `tools/list` already passed
41
+ annotations through verbatim.
42
+
43
+ ### Changed
44
+
45
+ - **`consume_credits` is annotated `destructiveHint: true`.** It debits a
46
+ prepaid balance with no reverse operation, which is precisely what the hint
47
+ exists to warn about; it previously claimed `false`. An agent client that
48
+ confirms destructive calls will now prompt before credits are spent — the one
49
+ behavior change in this release. `update_subscription` also reads `true` now,
50
+ but that is only the schema default it already resolved to, written out.
51
+
52
+ - Built-in annotations are built by two typed helpers, `readOnly(title)` and
53
+ `mutating(title, { destructive, idempotent?, openWorld? })`, rather than 42
54
+ repeated literals. Both take the title positionally and `mutating` requires
55
+ `destructive`, so a new built-in cannot ship untitled or with an implicit
56
+ destructive hint. Note for anyone auditing the published bundle: titles are
57
+ now helper arguments, so `grep 'title:' dist/mcp/index.cjs` under-counts them
58
+ — load `builtinMcpTools` and read `tool.annotations` instead.
59
+
8
60
  ## [0.0.79] - 2026-10-08
9
61
 
10
62
  ### Added
package/dist/index.d.ts CHANGED
@@ -3053,6 +3053,8 @@ interface SDKMessages {
3053
3053
  viewPlans: string;
3054
3054
  upgradePlan: string;
3055
3055
  subscribe: string;
3056
+ /** CTA for a freemium plan: $0, no Stripe object, nothing to cancel. */
3057
+ startFree: string;
3056
3058
  currentPlan: string;
3057
3059
  noSubscription: string;
3058
3060
  choosePlan: string;
@@ -1 +1 @@
1
- "use strict";var e=require("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.z.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}const b={readOnlyHint:!0},k=[{name:"list_workspaces",description:"List the authenticated user's workspaces (id, name, roles).",inputSchema:e.z.object({}),annotations:b,execute:(e,t)=>t.bb.workspace.list()},{name:"get_workspace",description:"Get one workspace: name, members, feature flags, quota snapshot.",inputSchema:e.z.object({workspaceId:w}),annotations:b,execute:(e,t)=>t.bb.workspace.get(y(e,t))},{name:"get_user_profile",description:"Get the authenticated user's profile.",inputSchema:e.z.object({}),annotations:b,execute:(e,t)=>t.bb.users.getProfile()},{name:"list_workspace_users",description:"List the members of a workspace with their roles.",inputSchema:e.z.object({workspaceId:w}),annotations:b,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.z.object({workspaceId:w}),annotations:b,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.z.object({workspaceId:w}),annotations:b,execute:(e,t)=>t.bb.plans.getGroup(y(e,t))},{name:"list_invoices",description:"List a workspace's invoices (newest first).",inputSchema:e.z.object({workspaceId:w,limit:e.z.number().int().min(1).max(100).optional().describe("Max invoices to return."),startingAfter:e.z.string().optional().describe("Invoice id to paginate after.")}),annotations:b,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.z.object({workspaceId:w,quotaSlug:e.z.string().describe('The quota slug, e.g. "api-calls".')}),annotations:b,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.z.object({workspaceId:w}),annotations:b,execute:(e,t)=>t.bb.usage.getAll(y(e,t))},{name:"get_credit_balance",description:"Get a workspace's prepaid credit balance.",inputSchema:e.z.object({workspaceId:w}),annotations:b,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.z.object({workspaceId:w,limit:e.z.number().int().min(1).max(100).optional(),page:e.z.number().int().min(1).optional()}),annotations:b,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.z.object({workspaceId:w,key:e.z.string().describe("The feature slug.")}),annotations:b,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.z.object({workspaceId:w,permission:e.z.union([e.z.string(),e.z.array(e.z.string())]).describe("A permission (or list — all must hold), platform or app-defined."),userId:e.z.string().optional().describe("Defaults to the authenticated user.")}),annotations:b,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.z.object({workspaceId:w,userId:e.z.string().optional().describe("Defaults to the authenticated user.")}),annotations:b,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.z.object({workspaceId:w,invoiceId:e.z.string().describe("The invoice id.")}),annotations:b,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.z.object({workspaceId:w}),annotations:b,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.z.object({slug:e.z.string().describe("The plan-group slug.")}),annotations:b,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.z.object({groupVersionId:e.z.string().describe("The plan-group version id.")}),annotations:b,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.z.object({workspaceId:w,quotaSlug:e.z.string().optional(),from:e.z.string().optional().describe("ISO date lower bound."),to:e.z.string().optional().describe("ISO date upper bound."),source:e.z.string().optional(),page:e.z.number().int().min(1).optional(),limit:e.z.number().int().min(1).max(100).optional()}).strict(),annotations:b,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.z.object({}),annotations:b,execute:(e,t)=>t.bb.settings.get()},{name:"get_credit_packages",description:"List the credit packages a workspace can purchase.",inputSchema:e.z.object({workspaceId:w}),annotations:b,execute:(e,t)=>t.bb.credits.getPackages(y(e,t))},{name:"get_credit_buckets",description:"Get a workspace's credit buckets (paginated).",inputSchema:e.z.object({workspaceId:w,status:e.z.string().optional(),source:e.z.string().optional(),page:e.z.number().int().min(1).optional(),limit:e.z.number().int().min(1).max(100).optional()}).strict(),annotations:b,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.z.object({workspaceId:w,days:e.z.number().int().min(1).optional()}),annotations:b,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.z.object({}),annotations:b,execute:(e,t)=>t.bb.credits.getPublicPackages()}],v=[{name:"record_usage",description:"Record quota usage for a workspace (metered billing).",inputSchema:e.z.object({workspaceId:w,quotaSlug:e.z.string().describe("The quota slug to record against."),quantity:e.z.number().positive().describe("Amount of usage to record."),idempotencyKey:e.z.string().optional().describe("Dedupe key for safe retries."),metadata:e.z.record(e.z.string(),e.z.unknown()).optional()}),annotations:{readOnlyHint:!1,destructiveHint:!1,idempotentHint:!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.z.object({workspaceId:w,amount:e.z.number().positive().describe("Credits to consume."),description:e.z.string().optional().describe("What the credits were spent on."),idempotencyKey:e.z.string().optional().describe("Dedupe key for safe retries.")}),annotations:{readOnlyHint:!1,destructiveHint:!1},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.z.object({workspaceId:w,event:e.z.string().describe('The event slug, e.g. "comment_added".'),userId:e.z.string().optional().describe("Recipient. Omit to notify all members."),message:e.z.string().optional().describe("Message body (used for push).")}),annotations:{readOnlyHint:!1,openWorldHint:!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.z.object({workspaceId:w,items:e.z.array(e.z.object({quotaSlug:e.z.string(),quantity:e.z.number().positive(),idempotencyKey:e.z.string().optional(),metadata:e.z.record(e.z.string(),e.z.unknown()).optional()})).min(1).max(100)}),annotations:{readOnlyHint:!1,destructiveHint:!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.z.object({name:e.z.string().describe("Workspace name."),image:e.z.string().optional().describe("Image URL.")}),annotations:{readOnlyHint:!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.z.object({workspaceId:w,name:e.z.string().min(1).optional().describe("New workspace name."),image:e.z.string().optional().describe("New image URL.")}).strict(),annotations:{readOnlyHint:!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.z.object({workspaceId:w}),annotations:{readOnlyHint:!1,destructiveHint:!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.z.object({workspaceId:w,email:e.z.string().describe("Invitee email."),role:e.z.string().describe("Role to grant.")}),annotations:{readOnlyHint:!1,openWorldHint:!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.z.object({workspaceId:w,userId:e.z.string().describe("The user to remove.")}),annotations:{readOnlyHint:!1,destructiveHint:!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.z.object({workspaceId:w,userId:e.z.string(),role:e.z.string().describe("The new role.")}),annotations:{readOnlyHint:!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.z.object({name:e.z.string().min(1).optional(),image:e.z.string().optional().describe("Profile image URL."),country:e.z.string().optional().describe("ISO country code."),timezone:e.z.string().optional().describe("IANA timezone."),language:e.z.string().optional().describe("Language code."),currency:e.z.string().optional().describe("Currency code.")}).strict(),annotations:{readOnlyHint:!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.z.object({workspaceId:w,key:e.z.string().describe("The feature slug."),value:e.z.boolean().describe("Enabled?")}),annotations:{readOnlyHint:!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.z.object({workspaceId:w,planVersionId:e.z.string(),billingInterval:e.z.string().optional(),currency:e.z.string().optional(),successUrl:e.z.string().optional(),cancelUrl:e.z.string().optional()}).strict(),annotations:{readOnlyHint:!1,openWorldHint:!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.z.object({workspaceId:w,planVersionId:e.z.string(),billingInterval:e.z.string().optional(),successUrl:e.z.string().optional(),cancelUrl:e.z.string().optional()}).strict(),annotations:{readOnlyHint:!1},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.z.object({workspaceId:w}),annotations:{readOnlyHint:!1,destructiveHint:!0},execute:(e,t)=>t.bb.subscription.cancel(y(e,t))},{name:"resume_subscription",description:"Resume a workspace's canceled subscription.",inputSchema:e.z.object({workspaceId:w}),annotations:{readOnlyHint:!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.z.object({workspaceId:w,returnUrl:e.z.string().optional()}),annotations:{readOnlyHint:!1,openWorldHint:!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.z.object({workspaceId:w,creditPackageId:e.z.string(),currency:e.z.string().optional(),successUrl:e.z.string().describe("Redirect URL on success."),cancelUrl:e.z.string().describe("Redirect URL on cancel.")}).strict(),annotations:{readOnlyHint:!1,openWorldHint:!0},execute:(e,t)=>{const{workspaceId:n,...r}=e;return t.bb.credits.purchase(y(e,t),r)}}],S=new Map([...k,...v].map(e=>[e.name,e]));function E(e){if(!1===e)return[];if("readonly"===e)return[...k];if("all"===e)return[...k,...v];const t=e.include?e.include.map(e=>{const t=S.get(e);if(!t)throw new Error(`Unknown built-in MCP tool: ${e}`);return t}):[...k],n=new Set(e.exclude??[]);return t.filter(e=>!n.has(e.name))}const I=e=>({type:"text",text:e}),T=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}},P=["2025-11-25","2025-06-18","2025-03-26","2024-11-05"],_=P[0],x="application/json",U=/^[a-zA-Z0-9_-]{1,128}$/,$=-32002,A=-32700,C=-32600,O=-32601,z=-32602,R=-32603;function j(e,t){const n=t.toLowerCase();for(const t of Object.keys(e))if(t.toLowerCase()===n)return e[t]}function N(e,t){return{status:e,headers:{"Content-Type":x},body:JSON.stringify(t)}}function F(e,t){return N(200,{jsonrpc:"2.0",id:e??null,result:t})}function J(e,t,n,r=200,s){return N(r,{jsonrpc:"2.0",id:e??null,error:{code:t,message:n,...void 0!==s?{data:s}:{}}})}function W(e){return"object"==typeof e&&null!==e&&"function"==typeof e.safeParse}function M(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 E(o))c.set(e.name,e);const u=new Set;for(const e of t.tools??[]){if(!U.test(e.name))throw new Error(`Invalid MCP tool name: "${e.name}" (want ${String(U)})`);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(!U.test(e.name))throw new Error(`Invalid MCP prompt name: "${e.name}" (want ${String(U)})`);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.`)}}),q=new Map;function L(t){const n=q.get(t.name);if(n)return n;let r;try{r=W(t.inputSchema)?e.z.toJSONSchema(t.inputSchema,{target:"draft-2020-12"}):t.inputSchema}catch(e){H(e,{method:"tools/list",tool:t.name}),r={type:"object",additionalProperties:!0}}return q.set(t.name,r),r}function B(e){const t=new Set(e?.scopes??[]);return Array.from(c.values()).filter(e=>(e.requiredScopes??[]).every(e=>t.has(e)))}function H(e,n){try{t.onError?.(e instanceof Error?e:new Error(M(e)),n)}catch{}}function D(){if(t.auth&&t.auth.resourceMetadataUrl){const e=f({resourceMetadataUrl:t.auth.resourceMetadataUrl});return{status:e.status,headers:e.headers,body:e.body}}return N(401,{error:"unauthorized"})}const G=Array.isArray(t.cors)?new Set(t.cors.map(r)):null;async function V(e){const o=function(e){if(!1===t.cors)return{};const n=j(e.headers,"origin");let o;return o=G?n&&G.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=j(e.headers,"origin");if(t&&!i(t))return N(403,{error:"origin_not_allowed"})}if("POST"!==r)return{status:405,headers:{"Content-Type":x,Allow:"POST, OPTIONS"},body:JSON.stringify({error:"method_not_allowed"})};if(a>0&&"string"==typeof e.body&&e.body.length>a)return N(413,{error:"payload_too_large"});let o=null;if(!1!==t.auth){const n=d(j(e.headers,"authorization"));if(!n)return D();try{o=await t.auth.verify(n,e)}catch(e){H(e,{method:"auth"}),o=null}if(!o)return D()}if(t.rateLimit){let n;try{n=await t.rateLimit(o,e)}catch(e){H(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":x,...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 J(null,A,"Invalid JSON",400)}if(Array.isArray(c))return J(null,C,"Batch requests are not supported",400);if("object"!=typeof c||null===c)return J(null,C,"Expected a JSON-RPC request object",400);const u=c,f=u.id,v="string"==typeof u.method?u.method:null;if(!v)return J(f,C,"Missing method",400);if(null==f)return{status:202,headers:{"Content-Type":x},body:""};const S=u.params??{};switch(v){case"initialize":{const e=S.protocolVersion;return F(f,{protocolVersion:"string"==typeof e&&P.includes(e)?e:_,capabilities:{tools:{listChanged:!1},...g?{resources:{}}:{},...m?{prompts:{}}:{}},serverInfo:n,...t.instructions?{instructions:t.instructions}:{}})}case"ping":return F(f,{});case"tools/list":return F(f,{tools:B(o).map(e=>({name:e.name,description:e.description,inputSchema:L(e),...e.annotations?{annotations:e.annotations}:{},...e.icons?{icons:e.icons}:{}}))});case"tools/call":{const n="string"==typeof S.name?S.name:"",r=B(o).find(e=>e.name===n);if(!r)return J(f,z,`Unknown tool: ${n||"(missing name)"}`);let s,i=S.arguments??{};if(W(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 F(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 H(e,{method:v,tool:n}),J(f,R,"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(T))return F(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 F(f,{content:[{type:"text",text:"string"==typeof e?e:JSON.stringify(e,null,2)}],...t?{structuredContent:e}:{},isError:!1})}catch(e){H(e,{method:v,tool:n});const r=e instanceof Error?e:new Error(M(e));return F(f,{content:[{type:"text",text:t.formatToolError?t.formatToolError(r,{tool:n}):r.message}],isError:!0})}}case"resources/list":if(!g)break;return F(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 F(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 J(f,z,"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 J(f,$,"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 J(f,$,"Resource not found",200,{uri:n});let a;if(t.context)try{a=await t.context(o,e)}catch(e){return H(e,{method:v}),J(f,R,"Context initialization failed")}try{const e=await s(y(o,a));return F(f,{contents:[k(n,r,e)]})}catch(e){return H(e,{method:v}),J(f,R,"Resource read failed",200,{uri:n})}}case"prompts/list":if(!m)break;return F(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 J(f,z,`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 J(f,z,`Missing required arguments: ${a.join(", ")}`);let c;if(t.context)try{c=await t.context(o,e)}catch(e){return H(e,{method:v}),J(f,R,"Context initialization failed")}try{const e=await r.get(i,y(o,c)),t="string"==typeof e?{messages:[{role:"user",content:I(e)}]}:Array.isArray(e)?{messages:e}:e,n=t.description??r.description;return F(f,{...n?{description:n}:{},messages:t.messages})}catch(e){return H(e,{method:v}),J(f,R,"Prompt rendering failed")}}}var E;return J(f,O,`Method not found: ${v}`)}(e);return Object.keys(o).length?{...c,headers:{...c.headers,...o}}:c}return{handle:V,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":x}})}const n="POST"===e.method.toUpperCase()?await e.text():void 0,r=await V({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}:{}})}}const L=12,B=16;function H(){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 D=new Map;function G(e){let t=D.get(e);return t||(t=(async()=>{const t=await H().digest("SHA-256",(new TextEncoder).encode(`${e}:bb-session`));return H().importKey("raw",t,{name:"AES-GCM"},!1,["encrypt","decrypt"])})(),D.set(e,t)),t}function V(e){if(!e)throw new Error("createSessionRefCrypto: missing secret");return{async encryptSessionRef(n){const r=globalThis.crypto.getRandomValues(new Uint8Array(L)),s=await G(e),i=new Uint8Array(await H().encrypt({name:"AES-GCM",iv:r},s,(new TextEncoder).encode(n))),o=i.subarray(i.length-B),a=i.subarray(0,i.length-B),c=new Uint8Array(28+a.length);return c.set(r,0),c.set(o,L),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,L),i=r.subarray(L,28),o=r.subarray(28),a=new Uint8Array(o.length+B);a.set(o,0),a.set(i,o.length);const c=await G(e),u=await H().decrypt({name:"AES-GCM",iv:s},c,a);return(new TextDecoder).decode(u)}catch{return null}}}}function K(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 Q(e){const{secret:t}=e;if(!t)throw new Error("buildbaseAuth: missing secret");const n=V(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 K(t,r,"token carries no aud claim"),null;if(t.length&&!t.some(e=>r.includes(e)))return K(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 Y=300,Z="/.well-known/oauth-protected-resource",X="/.well-known/agent-skills",ee="/.well-known/api-catalog",te="/.well-known/mcp/server-card.json",ne="/.well-known/agent-card.json",re="application/json",se="application/linkset+json",ie="text/markdown; charset=utf-8",oe="text/plain; charset=utf-8",ae="application/xml; charset=utf-8",ce=["GPTBot","OAI-SearchBot","ChatGPT-User","ClaudeBot","Claude-User","Claude-SearchBot","PerplexityBot","Perplexity-User","Google-Extended","Applebot-Extended","CCBot","Bytespider","meta-externalagent","Amazonbot"];function ue(e){return e.replace(/\/+$/,"")}function le(e){return`public, max-age=${e}, s-maxage=${e}`}function pe(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 de=new Map;async function he(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 ge(e){const t=e.cacheTtlSeconds??Y,n=`${ue(e.serverUrl)}::${e.orgId}`,r=de.get(n);if(r&&r.expiresAt>Date.now())return r.value;const s=e.fetch??fetch,i=`${ue(e.serverUrl)}/api/v1/public/${e.orgId}/agent-readiness`;let o={enabled:!1};try{const t=await he(s,i,{headers:{Accept:re}},e.fetchTimeoutMs??5e3);if(t.ok){const e=await t.json();e&&"object"==typeof e&&(o=e)}}catch{}return de.set(n,{value:o,expiresAt:Date.now()+1e3*t}),o}const me=new Map;function fe(e){let t="/";try{t=new URL(e).pathname}catch{t=e.startsWith("/")?e:`/${e}`}const n="/"===t?"":t.replace(/\/+$/,"");return Z+n}function we(e){return e.path??`${X}/${e.name}/SKILL.md`}function ye(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:oe,body:t.join("\n")+"\n",cacheControl:le(e.cacheTtlSeconds??Y)}}function be(e){return e.endsWith(".json")||e.includes(".well-known/")?re:e.endsWith(".md")?ie:e.endsWith(".xml")?ae:oe}function ke(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 ve(e,t){return{status:200,contentType:re,body:JSON.stringify(e,null,2),cacheControl:le(t.cacheTtlSeconds??Y)}}function Se(e){return String(e).replace(/[\x00-\x1f\x7f]/g,"")}function Ee(e,t){const n=(Array.isArray(e.userAgent)?e.userAgent:[e.userAgent]).map(e=>`User-agent: ${Se(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: ${Se(t)}`);for(const t of e.disallow??[])n.push(`Disallow: ${Se(t)}`);return void 0!==e.crawlDelay&&n.push(`Crawl-delay: ${Se(e.crawlDelay)}`),n.join("\n")}function Ie(e){const t="number"==typeof e&&Number.isFinite(e)?e:.5;return String(Math.min(1,Math.max(0,t)))}function Te(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&apos;")}function Pe(e){const t=ue(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}${ne}>; 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}${ee}>; rel="api-catalog"; type="${se}"`),e.mcpServerCard&&n.push(`<${t}${te}>; rel="mcp-server"; type="application/json"`),n.join(", ")}async function _e(e,t){const n=e.replace(/\/+$/,"")||e;if("/.well-known/agent.json"===n){return function(e,t){const n=ue(e.siteUrl),r={llms_txt:"/llms.txt",sitemap:"/sitemap.xml",robots:"/robots.txt",oauth_protected_resource:Z};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=`${X}/index.json`),e.apiCatalog?.length&&(r.api_catalog=ee),e.mcpServerCard&&(r.mcp_server_card=te),!1!==e.a2aCard&&(r.a2a_agent_card=ne),e.llmsFullTxt&&(r.llms_full_txt="/llms-full.txt"),ve({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 ge(t))}if(n===ne)return function(e){if(!1===e.a2aCard)return null;const t=e.a2aCard??{},n=ue(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 ve({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:le(e.cacheTtlSeconds??Y)}:null}(t);if("/.well-known/security.txt"===n)return ye(t);if(n===`${X}/index.json`)return function(e){const t=e.skills??[];if(!t.length)return null;const n=ue(e.siteUrl);return ve({$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}${we(e)}`,digest:pe(e.content)}))},e)}(t);if(n.startsWith(`${X}/`)&&n.endsWith("SKILL.md"))return function(e,t){const n=(t.skills??[]).find(t=>we(t)===e);return n?{status:200,contentType:"text/markdown; charset=utf-8",body:n.content,cacheControl:le(t.cacheTtlSeconds??Y)}:null}(n,t);if("/.well-known/oauth-authorization-server"===n||"/.well-known/openid-configuration"===n){const e=(await ge(t)).authorizationServer;if(!e?.metadataUrl)return null;const n=await async function(e,t){const n=t.cacheTtlSeconds??Y,r=me.get(e);if(r&&r.expiresAt>Date.now())return r.value;const s=t.fetch??fetch;let i=null;try{const n=await he(s,e,{headers:{Accept:re}},t.fetchTimeoutMs??5e3);if(n.ok){const e=await n.json();e&&"object"==typeof e&&(i=e)}}catch{}return me.set(e,{value:i,expiresAt:Date.now()+1e3*n}),i}(e.metadataUrl,t);return ve(n?n:{...e.issuer?{issuer:e.issuer}:{},oauth_authorization_server_metadata:e.metadataUrl},t)}if(n===ee)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:se,body:JSON.stringify({linkset:n},null,2),cacheControl:le(e.cacheTtlSeconds??Y)}}(t);if(n===te)return function(e){const t=e.mcpServerCard;return t?ve({$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:ke(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=ue(e.siteUrl);let r;try{r={type:"oauth2",protected_resource_metadata:`${new URL(t.endpoint).origin}${fe(t.endpoint)}`}}catch{}return ve({$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:ke(t.capabilities),...t.documentationUrl?{documentation_url:t.documentationUrl}:{},server_card:`${n}${te}`,...r?{authentication:r}:{}}]},e)}(t);if(n.startsWith(Z)){const e=await ge(t);return function(e,t,n){const r=t.protectedResources??[];if(!r.length)return null;const s=e.replace(/\/+$/,"")||Z,i=n??`${ue(t.serverUrl)}/org/${t.orgId}`,o=t.scopes?.map(e=>e.name),a=r.map(e=>{const n=e.resource??ue(t.siteUrl),r=e.scopes??o;return{path:fe(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?ve(c.metadata,t):s===Z&&1===a.length?ve(a[0].metadata,t):null}(n,t,e.authorizationServer?.issuer)}return null}async function xe(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??be(e),body:r.body,cacheControl:r.cacheControl??le(t.cacheTtlSeconds??Y)}}(n,t);return r||("/robots.txt"===n?function(e){const t=e.robots??{},n=ue(e.siteUrl),r=t.policies??[{userAgent:"*",allow:["/"]}],s=t.aiBots??"allow",i="allow"===s?[{userAgent:[...ce],allow:["/"]}]:"deny"===s?[{userAgent:[...ce],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)=>Ee(e,0===n?t.contentSignals:void 0)),...i.map(e=>Ee(e)),...o.length?[o.map(e=>`Sitemap: ${Se(e)}`).join("\n")]:[]];return{status:200,contentType:oe,body:a.join("\n\n")+"\n",cacheControl:le(e.cacheTtlSeconds??Y)}}(t):"/llms-full.txt"===n?function(e){return e.llmsFullTxt?{status:200,contentType:oe,body:e.llmsFullTxt,cacheControl:le(e.cacheTtlSeconds??Y)}:null}(t):"/sitemap.xml"===n?function(e){const t=e.sitemap?.urls;if(!t?.length)return null;const n=ue(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>${Te(/^https?:\/\//.test(t.loc)?t.loc:`${n}${t.loc.startsWith("/")?"":"/"}${t.loc}`)}</loc>`,...t.lastmod?[` <lastmod>${Te(t.lastmod)}</lastmod>`]:[],...t.changefreq?[` <changefreq>${Te(String(t.changefreq))}</changefreq>`]:[],...void 0!==t.priority?[` <priority>${Ie(t.priority)}</priority>`]:[]].join("\n")}\n </url>`}).join("\n")+"\n</urlset>\n";return{status:200,contentType:ae,body:r,cacheControl:le(e.cacheTtlSeconds??Y)}}(t):"/llms.txt"===n?function(e){return e.llmsTxt?{status:200,contentType:oe,body:e.llmsTxt,cacheControl:le(e.cacheTtlSeconds??Y)}:null}(t):"/auth.md"===n?function(e,t){const n=le(e.cacheTtlSeconds??Y);if(e.authMd)return{status:200,contentType:ie,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:ie,body:s,cacheControl:n}}(t,await ge(t)):"/security.txt"===n?ye(t):n.startsWith("/.well-known")?_e(n,t):null)}let Ue=!0;function $e(e,...t){Ue&&function(){try{const e="undefined"!=typeof globalThis?globalThis:null;return"development"===e?.process?.env?.NODE_ENV}catch{return!1}}()&&console.error(e,...t)}function Ae(e,...t){console.error(e,...t)}async function Ce(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 Oe(e,t="Request failed"){if(!e.ok){let n,r=t;try{const t=await Ce(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 Ce(e)}catch(e){if(e instanceof Error&&e.message.includes("Invalid JSON"))throw e;throw new Error("Failed to parse response as JSON")}}class ze 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,ze)}}const Re=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&&(Ue=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 ze("string"==typeof e?e:"An unknown error occurred","UNKNOWN_ERROR",t),r=n instanceof ze?n:new ze(n.message,"SDK_ERROR",t,n);if(this.config.enableConsoleLogging&&$e(`[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){Ae("[SDK Error Handler] Error in custom error callback:",e)}for(const e of this.listeners)try{e(r,t)}catch(e){Ae("[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 je(e,t={}){Re.handleError(e,t)}function Ne(e){if("undefined"==typeof window)return null;try{return localStorage.getItem(e)}catch(t){return je(t,{component:"storage",action:"getStorageItem",metadata:{key:e}}),null}}const Fe="saas-session-id",Je="saas-device-id";function We(){return function(){if("undefined"==typeof window)return null;try{return Ne(Fe)}catch(e){return je(e,{component:"auth-utils",action:"getSessionId",metadata:{key:Fe}}),null}}()}function Me(){const e=We(),t={};e&&(t["x-session-id"]=e);const n=function(){if("undefined"==typeof window)return null;try{return Ne(Je)??null}catch(e){return je(e,{component:"auth-utils",action:"getOrCreateDeviceId",metadata:{key:Je}}),null}}();return n&&(t["x-device-id"]=n),t}const qe=new WeakSet,Le=new Set(["GET","HEAD","OPTIONS","PUT","DELETE"]),Be="SDK is not ready (missing serverUrl, version, or orgId)";class He{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(Be);if(this.requireOrgId&&!this.orgId?.trim())throw new Error(Be)}get baseUrl(){return this.ensureReady(),`${this.serverUrl}/api/${this.version}/${this.basePath}`}getAuthHeaders(){return this._sessionId?{"x-session-id":this._sessionId}:Me()}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){qe.has(e)||(qe.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=Le.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?function(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}(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 He.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 He.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 Oe(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 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 De extends He{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 Ge extends He{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 Ve extends He{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 Ke extends He{constructor(e){super({...e,requireOrgId:!0})}async getSettings(e){return this.fetchJson(`${this.orgId}/settings`,{signal:e},"Failed to fetch settings")}}class Qe extends He{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 Ye={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 Ze(e){return"number"==typeof e&&Number.isFinite(e)?e:void 0}function Xe(e){return"string"==typeof e&&e?e:void 0}async function et(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=Xe(r.message)??Xe(r.error)??n,i={status:e,code:Xe(r.code)??Ye[e]??`HTTP_${e}`,currentUserCount:Ze(r.currentUserCount),limit:Ze(r.limit),retryAfterSeconds:Ze(r.retryAfterSeconds),invitedEmail:Xe(r.invitedEmail),invitationId:Xe(r.invitationId),invitationStatus:Xe(r.status)};return Object.assign(new Error(s),i)}(e.status,n,t)}class tt extends He{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 et(r,n);return Oe(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 nt={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"},rt=Object.values(nt),st={admin:rt.filter(e=>e!==nt.WORKSPACE_DELETE),editor:[nt.WORKSPACE_SETTINGS_VIEW,nt.WORKSPACE_MEMBERS_VIEW,nt.WORKSPACE_FEATURES_VIEW,nt.WORKSPACE_BILLING_VIEW,nt.WORKSPACE_USAGE_VIEW,nt.WORKSPACE_USAGE_RECORD],viewer:[nt.WORKSPACE_SETTINGS_VIEW,nt.WORKSPACE_MEMBERS_VIEW]};function it(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 ot(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(rt);if(s)for(const t of it(s))e.add(t);if(n.permissions)for(const t of it(n.permissions))e.add(t);if(r?.workspace?.permissions)for(const t of it(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(it(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(nt.WORKSPACE_MEMBERS_INVITE)}(m,g,s);return m}(i,e):new Set}function at(e){const{serverUrl:t,orgId:n,version:r="v1",getSessionId:s,timeout:i,maxRetries:o,debug:a,headers:c,onError:u,fetch:l}=e;if(!t)throw new Error("BuildBase: serverUrl is required");if(!n)throw new Error("BuildBase: orgId is required");const p={...void 0!==i&&{timeout:i},...void 0!==o&&{maxRetries:o},...void 0!==a&&{debug:a},...c&&{headers:c},...u&&{onError:u},...l&&{fetch:l}},d=e=>{const s={serverUrl:t,version:r,orgId:n,sessionId:e,...p};return{workspace:new tt(s),user:new Qe(s),settings:new Ke(s),push:new Ge(s),devices:new De(s),sessions:new Ve(s)}},h=new tt({serverUrl:t,version:r,orgId:n,...p}),g=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=>h.getPublicPlans(e),getVersion:e=>h.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:()=>h.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=ot(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 ot({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=g(async()=>d(await(async()=>{if(!s)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 s();if(!e)throw new Error("BuildBase: Not authenticated (getSessionId returned null)");return e})()));return{auth:async()=>{if(!s)return null;const e=await s();return e?{sessionId:e}:null},withSession:e=>{const t=d(e);return g(async()=>t)},client:{forSession:d},...m}}exports.AppBridgeError=u,exports.bearerChallenge=f,exports.buildbaseAuth=Q,exports.builtinMcpTools=S,exports.createAgentStack=function(e){const t=ue(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?Q({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??at({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"},p=e=>c.fetch(e);return{mcp:c,mcpEndpoint:r,config:u,linkHeader:Pe(u),resolvePath:e=>xe(e,u),serveAgentPath:async function(e){if("OPTIONS"===e.method.toUpperCase())return new Response(null,{status:204,headers:l});const t=await xe(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}}},exports.createMcpHandler=q,exports.createSessionRefCrypto=V,exports.defineMcpPrompt=e=>e,exports.defineMcpResource=e=>e,exports.defineMcpResourceTemplate=e=>e,exports.defineMcpTool=function(e){return e},exports.extractBearerToken=d,exports.mcpAudio=(e,t)=>({type:"audio",data:e,mimeType:t}),exports.mcpEmbeddedResource=e=>({type:"resource",resource:e}),exports.mcpImage=(e,t)=>({type:"image",data:e,mimeType:t}),exports.mcpResourceLink=(e,t,n)=>({type:"resource_link",uri:e,name:t,...n}),exports.mcpText=I,exports.mintAgentToken=async function(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 V(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}},exports.selectBuiltinTools=E,exports.signClientJwt=g,exports.verifyClientJwt=p;
1
+ "use strict";var e=require("zod");function t(e){let t="";for(let r=0;r<e.length;r++)t+=String.fromCharCode(e[r]);return btoa(t).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function r(e){const t=e.replace(/-/g,"+").replace(/_/g,"/"),r=t.length%4==0?"":"=".repeat(4-t.length%4),n=atob(t+r),s=new Uint8Array(n.length);for(let e=0;e<n.length;e++)s[e]=n.charCodeAt(e);return s}const n=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,r=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 r=e+4*t;y[t]=g[r]<<24|g[r+1]<<16|g[r+2]<<8|g[r+3]}for(let e=16;e<64;e++){const t=s(y[e-15],7)^s(y[e-15],18)^y[e-15]>>>3,r=s(y[e-2],17)^s(y[e-2],19)^y[e-2]>>>10;y[e]=y[e-16]+t+y[e-7]+r>>>0}let p=t,d=r,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)+n[e]+y[e]>>>0,r=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))+r>>>0)>>>0}t=t+p>>>0,r=r+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,r,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 r=e;r.length>64&&(r=i(r));const n=new Uint8Array(64),s=new Uint8Array(64);for(let e=0;e<64;e++){const t=e<r.length?r[e]:0;n[e]=54^t,s[e]=92^t}const o=i(c(n,t));return i(c(s,o))}function c(e,t){const r=new Uint8Array(e.length+t.length);return r.set(e,0),r.set(t,e.length),r}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(r(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,n={}){const s=n.clockToleranceSec??60,i=n.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=r(h)}catch{throw new u("invalid_signature","Unreadable JWT signature")}if(!function(e,t){if(e.length!==t.length)return!1;let r=0;for(let n=0;n<e.length;n++)r|=e[n]^t[n];return 0===r}(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 r=e[t];if(void 0!==r&&("number"!=typeof r||!Number.isFinite(r)))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!==n.issuer&&m.iss!==n.issuer)throw new u("invalid_issuer","JWT issuer mismatch");if(void 0!==n.audience){const e=m.aud;if(!(Array.isArray(e)?e.includes(n.audience):e===n.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,r,n){if(!r)throw new u("invalid_secret","Missing signing secret");const s=Math.floor(Date.now()/1e3),i={iat:s,exp:s+(n?.expiresInSec??3600),...e},c=`${h({alg:"HS256",typ:"JWT"})}.${h(i)}`;return`${c}.${t(a(o(r),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.z.string().optional().describe("Workspace id. Omit to use the workspace bound to your token.");function y(e,t){const r=e.workspaceId??t.workspaceId;if(!r)throw new Error("workspaceId is required — call list_workspaces to find one.");return r}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.z.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.z.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.z.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.z.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.z.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.z.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.z.object({workspaceId:w,limit:e.z.number().int().min(1).max(100).optional().describe("Max invoices to return."),startingAfter:e.z.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.z.object({workspaceId:w,quotaSlug:e.z.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.z.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.z.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.z.object({workspaceId:w,limit:e.z.number().int().min(1).max(100).optional(),page:e.z.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.z.object({workspaceId:w,key:e.z.string().describe("The feature slug.")}),annotations:b("Check Feature Flag"),execute:async(e,t)=>{const r=y(e,t),n=await t.bb.workspace.get(r),s=n.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.z.object({workspaceId:w,permission:e.z.union([e.z.string(),e.z.array(e.z.string())]).describe("A permission (or list — all must hold), platform or app-defined."),userId:e.z.string().optional().describe("Defaults to the authenticated user.")}),annotations:b("Check Permission"),execute:async(e,t)=>{const r=e.userId??t.auth.userId;if(!r)throw new Error("userId is required — the token carries no user identity.");const n=await t.bb.permissions.check(y(e,t),r,e.permission);return{userId:r,permission:e.permission,allowed:n}}},{name:"resolve_permissions",description:"List every permission a user holds in a workspace.",inputSchema:e.z.object({workspaceId:w,userId:e.z.string().optional().describe("Defaults to the authenticated user.")}),annotations:b("List User Permissions"),execute:async(e,t)=>{const r=e.userId??t.auth.userId;if(!r)throw new Error("userId is required — the token carries no user identity.");const n=await t.bb.permissions.resolve(y(e,t),r);return{userId:r,permissions:Array.from(n)}}},{name:"get_invoice",description:"Get one invoice by id.",inputSchema:e.z.object({workspaceId:w,invoiceId:e.z.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.z.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.z.object({slug:e.z.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.z.object({groupVersionId:e.z.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.z.object({workspaceId:w,quotaSlug:e.z.string().optional(),from:e.z.string().optional().describe("ISO date lower bound."),to:e.z.string().optional().describe("ISO date upper bound."),source:e.z.string().optional(),page:e.z.number().int().min(1).optional(),limit:e.z.number().int().min(1).max(100).optional()}).strict(),annotations:b("List Usage Logs"),execute:(e,t)=>{const{workspaceId:r,...n}=e;return t.bb.usage.getLogs(y(e,t),n)}},{name:"get_settings",description:"Get the organization settings.",inputSchema:e.z.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.z.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.z.object({workspaceId:w,status:e.z.string().optional(),source:e.z.string().optional(),page:e.z.number().int().min(1).optional(),limit:e.z.number().int().min(1).max(100).optional()}).strict(),annotations:b("List Credit Buckets"),execute:(e,t)=>{const{workspaceId:r,...n}=e;return t.bb.credits.getBuckets(y(e,t),n)}},{name:"get_expiring_credits",description:"Get credits expiring within N days (default 7).",inputSchema:e.z.object({workspaceId:w,days:e.z.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.z.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.z.object({workspaceId:w,quotaSlug:e.z.string().describe("The quota slug to record against."),quantity:e.z.number().positive().describe("Amount of usage to record."),idempotencyKey:e.z.string().optional().describe("Dedupe key for safe retries."),metadata:e.z.record(e.z.string(),e.z.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.z.object({workspaceId:w,amount:e.z.number().positive().describe("Credits to consume."),description:e.z.string().optional().describe("What the credits were spent on."),idempotencyKey:e.z.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.z.object({workspaceId:w,event:e.z.string().describe('The event slug, e.g. "comment_added".'),userId:e.z.string().optional().describe("Recipient. Omit to notify all members."),message:e.z.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.z.object({workspaceId:w,items:e.z.array(e.z.object({quotaSlug:e.z.string(),quantity:e.z.number().positive(),idempotencyKey:e.z.string().optional(),metadata:e.z.record(e.z.string(),e.z.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.z.object({name:e.z.string().describe("Workspace name."),image:e.z.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.z.object({workspaceId:w,name:e.z.string().min(1).optional().describe("New workspace name."),image:e.z.string().optional().describe("New image URL.")}).strict(),annotations:k("Update Workspace",{destructive:!1}),execute:(e,t)=>{const r={};return void 0!==e.name&&(r.name=e.name),void 0!==e.image&&(r.image=e.image),t.bb.workspace.update(y(e,t),r)}},{name:"delete_workspace",description:"Delete a workspace. Irreversible.",inputSchema:e.z.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.z.object({workspaceId:w,email:e.z.string().describe("Invitee email."),role:e.z.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.z.object({workspaceId:w,userId:e.z.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.z.object({workspaceId:w,userId:e.z.string(),role:e.z.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.z.object({name:e.z.string().min(1).optional(),image:e.z.string().optional().describe("Profile image URL."),country:e.z.string().optional().describe("ISO country code."),timezone:e.z.string().optional().describe("IANA timezone."),language:e.z.string().optional().describe("Language code."),currency:e.z.string().optional().describe("Currency code.")}).strict(),annotations:k("Update My Profile",{destructive:!1}),execute:(e,t)=>{const r={};for(const t of["name","image","country","timezone","language","currency"]){const n=e[t];void 0!==n&&(r[t]=n)}return t.bb.users.updateProfile(r)}},{name:"update_feature_flag",description:"Set a feature flag on/off for a workspace.",inputSchema:e.z.object({workspaceId:w,key:e.z.string().describe("The feature slug."),value:e.z.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.z.object({workspaceId:w,planVersionId:e.z.string(),billingInterval:e.z.string().optional(),currency:e.z.string().optional(),successUrl:e.z.string().optional(),cancelUrl:e.z.string().optional()}).strict(),annotations:k("Start Subscription Checkout",{destructive:!1,openWorld:!0}),execute:(e,t)=>{const{workspaceId:r,...n}=e;return t.bb.subscription.checkout(y(e,t),n)}},{name:"update_subscription",description:"Change a workspace's subscription plan.",inputSchema:e.z.object({workspaceId:w,planVersionId:e.z.string(),billingInterval:e.z.string().optional(),successUrl:e.z.string().optional(),cancelUrl:e.z.string().optional()}).strict(),annotations:k("Change Subscription Plan",{destructive:!0}),execute:(e,t)=>{const{workspaceId:r,...n}=e;return t.bb.subscription.update(y(e,t),n)}},{name:"cancel_subscription",description:"Cancel a workspace's subscription.",inputSchema:e.z.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.z.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.z.object({workspaceId:w,returnUrl:e.z.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.z.object({workspaceId:w,creditPackageId:e.z.string(),currency:e.z.string().optional(),successUrl:e.z.string().describe("Redirect URL on success."),cancelUrl:e.z.string().describe("Redirect URL on cancel.")}).strict(),annotations:k("Buy Credits",{destructive:!1,openWorld:!0}),execute:(e,t)=>{const{workspaceId:r,...n}=e;return t.bb.credits.purchase(y(e,t),n)}}],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],r=new Set(e.exclude??[]);return t.filter(e=>!r.has(e.name))}const P=e=>({type:"text",text:e}),T=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}},_=["2025-11-25","2025-06-18","2025-03-26","2024-11-05"],x=_[0],U="application/json",$=/^[a-zA-Z0-9_-]{1,128}$/,C=-32002,A=-32700,O=-32600,R=-32601,z=-32602,j=-32603;function N(e,t){const r=t.toLowerCase();for(const t of Object.keys(e))if(t.toLowerCase()===r)return e[t]}function F(e,t){return{status:e,headers:{"Content-Type":U},body:JSON.stringify(t)}}function W(e,t){return F(200,{jsonrpc:"2.0",id:e??null,result:t})}function J(e,t,r,n=200,s){return F(n,{jsonrpc:"2.0",id:e??null,error:{code:t,message:r,...void 0!==s?{data:s}:{}}})}function M(e){return"object"==typeof e&&null!==e&&"function"==typeof e.safeParse}function L(e){return e instanceof Error?e.message:"string"==typeof e?e:JSON.stringify(e)}function q(t){const r=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 n=e=>e.trim().toLowerCase().replace(/\/+$/,""),s=t.allowedOrigins?new Set(t.allowedOrigins.map(n)):null,i=e=>!!e&&!!s&&s.has(n(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(!$.test(e.name))throw new Error(`Invalid MCP tool name: "${e.name}" (want ${String($)})`);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,r)=>r.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(!$.test(e.name))throw new Error(`Invalid MCP prompt name: "${e.name}" (want ${String($)})`);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 r=new Set(t?.scopes??[]);return(e??[]).every(e=>r.has(e))};function y(e,r){const n=e?.sessionId??"";return{bb:t.buildbase?n?t.buildbase.withSession(n):S:v,auth:e??{sessionId:""},workspaceId:e?.workspaceId,custom:r}}function b(e,t){const r=[],n=e.replace(/[.*+?^$()|[\]\\]/g,e=>"\\"+e).replace(/\{([a-zA-Z0-9_]+)\}/g,(e,t)=>(r.push(t),"([^/]+)")),s=new RegExp(`^${n}$`).exec(t);if(!s)return null;const i={};return r.forEach((e,t)=>{try{i[e]=decodeURIComponent(s[t+1])}catch{i[e]=s[t+1]}}),i}function k(e,t,r){if("string"==typeof r)return{uri:e,mimeType:t??"text/plain",text:r};if(r&&"object"==typeof r){const n=r;if("string"==typeof n.text)return{uri:e,mimeType:"string"==typeof n.mimeType?n.mimeType:t??"text/plain",text:n.text};if("string"==typeof n.blob)return{uri:e,mimeType:"string"==typeof n.mimeType?n.mimeType:t??"application/octet-stream",blob:n.blob}}return{uri:e,mimeType:t??"application/json",text:JSON.stringify(r,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 q(t){const r=E.get(t.name);if(r)return r;let n;try{n=M(t.inputSchema)?e.z.toJSONSchema(t.inputSchema,{target:"draft-2020-12"}):t.inputSchema}catch(e){D(e,{method:"tools/list",tool:t.name}),n={type:"object",additionalProperties:!0}}return E.set(t.name,n),n}function B(e){const t=new Set(e?.scopes??[]);return Array.from(c.values()).filter(e=>(e.requiredScopes??[]).every(e=>t.has(e)))}function D(e,r){try{t.onError?.(e instanceof Error?e:new Error(L(e)),r)}catch{}}function G(){if(t.auth&&t.auth.resourceMetadataUrl){const e=f({resourceMetadataUrl:t.auth.resourceMetadataUrl});return{status:e.status,headers:e.headers,body:e.body}}return F(401,{error:"unauthorized"})}const V=Array.isArray(t.cors)?new Set(t.cors.map(n)):null;async function K(e){const o=function(e){if(!1===t.cors)return{};const r=N(e.headers,"origin");let o;return o=V?r&&V.has(n(r))?r:null:s?i(r)?r: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 n=e.method.toUpperCase();if(s){const t=N(e.headers,"origin");if(t&&!i(t))return F(403,{error:"origin_not_allowed"})}if("POST"!==n)return{status:405,headers:{"Content-Type":U,Allow:"POST, OPTIONS"},body:JSON.stringify({error:"method_not_allowed"})};if(a>0&&"string"==typeof e.body&&e.body.length>a)return F(413,{error:"payload_too_large"});let o=null;if(!1!==t.auth){const r=d(N(e.headers,"authorization"));if(!r)return G();try{o=await t.auth.verify(r,e)}catch(e){D(e,{method:"auth"}),o=null}if(!o)return G()}if(t.rateLimit){let r;try{r=await t.rateLimit(o,e)}catch(e){D(e,{method:"rateLimit"}),r=!1}if(!("boolean"==typeof r?r:r.ok)){const e="object"==typeof r?r.retryAfter:void 0;return{status:429,headers:{"Content-Type":U,...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 J(null,A,"Invalid JSON",400)}if(Array.isArray(c))return J(null,O,"Batch requests are not supported",400);if("object"!=typeof c||null===c)return J(null,O,"Expected a JSON-RPC request object",400);const u=c,f=u.id,v="string"==typeof u.method?u.method:null;if(!v)return J(f,O,"Missing method",400);if(null==f)return{status:202,headers:{"Content-Type":U},body:""};const S=u.params??{};switch(v){case"initialize":{const e=S.protocolVersion;return W(f,{protocolVersion:"string"==typeof e&&_.includes(e)?e:x,capabilities:{tools:{listChanged:!1},...g?{resources:{}}:{},...m?{prompts:{}}:{}},serverInfo:r,...t.instructions?{instructions:t.instructions}:{}})}case"ping":return W(f,{});case"tools/list":return W(f,{tools:B(o).map(e=>({name:e.name,description:e.description,inputSchema:q(e),...e.annotations?{annotations:e.annotations}:{},...e.icons?{icons:e.icons}:{}}))});case"tools/call":{const r="string"==typeof S.name?S.name:"",n=B(o).find(e=>e.name===r);if(!n)return J(f,z,`Unknown tool: ${r||"(missing name)"}`);let s,i=S.arguments??{};if(M(n.inputSchema)){const e=n.inputSchema.safeParse(i);if(!e.success){const t=e.error.issues.map(e=>`${e.path.join(".")||"(root)"}: ${e.message}`).join("; ");return W(f,{content:[{type:"text",text:`Invalid arguments for ${r}: ${t}`}],isError:!0})}i=e.data}if(t.context)try{s=await t.context(o,e)}catch(e){return D(e,{method:v,tool:r}),J(f,j,"Context initialization failed")}const a=y(o,s);try{const e=await n.execute(i,a);if("object"==typeof(E=e)&&null!==E&&Array.isArray(E.content)&&E.content.length>0&&E.content.every(T))return W(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 W(f,{content:[{type:"text",text:"string"==typeof e?e:JSON.stringify(e,null,2)}],...t?{structuredContent:e}:{},isError:!1})}catch(e){D(e,{method:v,tool:r});const n=e instanceof Error?e:new Error(L(e));return W(f,{content:[{type:"text",text:t.formatToolError?t.formatToolError(n,{tool:r}):n.message}],isError:!0})}}case"resources/list":if(!g)break;return W(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 W(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 J(f,z,"Missing required parameter: uri");const r=S.uri;let n,s=null;const i=l.get(r);if(i){if(!w(i.requiredScopes,o))return J(f,C,"Resource not found",200,{uri:r});n=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,r);if(t){n=e.mimeType,s=async n=>e.read(t,r,n);break}}if(!s)return J(f,C,"Resource not found",200,{uri:r});let a;if(t.context)try{a=await t.context(o,e)}catch(e){return D(e,{method:v}),J(f,j,"Context initialization failed")}try{const e=await s(y(o,a));return W(f,{contents:[k(r,n,e)]})}catch(e){return D(e,{method:v}),J(f,j,"Resource read failed",200,{uri:r})}}case"prompts/list":if(!m)break;return W(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 r="string"==typeof S.name?S.name:"",n=h.get(r);if(!n||!w(n.requiredScopes,o))return J(f,z,`Unknown prompt: ${r||"(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=(n.arguments??[]).filter(e=>e.required&&!(e.name in i)).map(e=>e.name);if(a.length)return J(f,z,`Missing required arguments: ${a.join(", ")}`);let c;if(t.context)try{c=await t.context(o,e)}catch(e){return D(e,{method:v}),J(f,j,"Context initialization failed")}try{const e=await n.get(i,y(o,c)),t="string"==typeof e?{messages:[{role:"user",content:P(e)}]}:Array.isArray(e)?{messages:e}:e,r=t.description??n.description;return W(f,{...r?{description:r}:{},messages:t.messages})}catch(e){return D(e,{method:v}),J(f,j,"Prompt rendering failed")}}}var E;return J(f,R,`Method not found: ${v}`)}(e);return Object.keys(o).length?{...c,headers:{...c.headers,...o}}:c}return{handle:K,fetch:async function(e){const t={};if(e.headers.forEach((e,r)=>{t[r]=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":U}})}const r="POST"===e.method.toUpperCase()?await e.text():void 0,n=await K({method:e.method,headers:t,body:r});return new Response(""===n.body?null:n.body,{status:n.status,headers:n.headers})},listTools:()=>Array.from(c.values()).map(e=>({name:e.name,description:e.description,...e.annotations?{annotations:e.annotations}:{}})),serverCard:e=>({name:r.name,version:r.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}:{}})}}const B=12,D=16;function G(){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 V=new Map;function K(e){let t=V.get(e);return t||(t=(async()=>{const t=await G().digest("SHA-256",(new TextEncoder).encode(`${e}:bb-session`));return G().importKey("raw",t,{name:"AES-GCM"},!1,["encrypt","decrypt"])})(),V.set(e,t)),t}function H(e){if(!e)throw new Error("createSessionRefCrypto: missing secret");return{async encryptSessionRef(r){const n=globalThis.crypto.getRandomValues(new Uint8Array(B)),s=await K(e),i=new Uint8Array(await G().encrypt({name:"AES-GCM",iv:n},s,(new TextEncoder).encode(r))),o=i.subarray(i.length-D),a=i.subarray(0,i.length-D),c=new Uint8Array(28+a.length);return c.set(n,0),c.set(o,B),c.set(a,28),t(c)},async decryptSessionRef(t){try{const n=r(t);if(n.length<=28)return null;const s=n.slice(0,B),i=n.subarray(B,28),o=n.subarray(28),a=new Uint8Array(o.length+D);a.set(o,0),a.set(i,o.length);const c=await K(e),u=await G().decrypt({name:"AES-GCM",iv:s},c,a);return(new TextDecoder).decode(u)}catch{return null}}}}function Q(e,t,r){const n=globalThis.process?.env;"1"===n?.MCP_AUTH_DEBUG&&console.warn(`[buildbase/mcp-auth] audience rejected (${r}): received aud=${JSON.stringify(e)} expected one of ${JSON.stringify(t)}`)}function Y(e){const{secret:t}=e;if(!t)throw new Error("buildbaseAuth: missing secret");const r=H(t),n=e.resource?Array.isArray(e.resource)?e.resource:[e.resource]:[];let s=e.resourceMetadataUrl;if(!s&&n.length)try{const e=new URL(n[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(n.length){const t=i.aud?Array.isArray(i.aud)?i.aud:[i.aud]:[];if(!t.length&&e.requireAudience)return Q(t,n,"token carries no aud claim"),null;if(t.length&&!t.some(e=>n.includes(e)))return Q(t,n,"aud does not include this resource"),null}const o="string"==typeof i.sid?await r.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 Z=300,X="/.well-known/oauth-protected-resource",ee="/.well-known/agent-skills",te="/.well-known/api-catalog",re="/.well-known/mcp/server-card.json",ne="/.well-known/agent-card.json",se="application/json",ie="application/linkset+json",oe="text/markdown; charset=utf-8",ae="text/plain; charset=utf-8",ce="application/xml; charset=utf-8",ue=["GPTBot","OAI-SearchBot","ChatGPT-User","ClaudeBot","Claude-User","Claude-SearchBot","PerplexityBot","Perplexity-User","Google-Extended","Applebot-Extended","CCBot","Bytespider","meta-externalagent","Amazonbot"];function le(e){return e.replace(/\/+$/,"")}function pe(e){return`public, max-age=${e}, s-maxage=${e}`}function de(e){return"sha256:"+function(e){let t="";for(let r=0;r<e.length;r++)t+=e[r].toString(16).padStart(2,"0");return t}(i(o(e)))}const he=new Map;async function ge(e,t,r,n){if(!n||n<=0)return e(t,r);const s=new AbortController,i=setTimeout(()=>s.abort(),n);try{return await e(t,{...r,signal:s.signal})}finally{clearTimeout(i)}}async function me(e){const t=e.cacheTtlSeconds??Z,r=`${le(e.serverUrl)}::${e.orgId}`,n=he.get(r);if(n&&n.expiresAt>Date.now())return n.value;const s=e.fetch??fetch,i=`${le(e.serverUrl)}/api/v1/public/${e.orgId}/agent-readiness`;let o={enabled:!1};try{const t=await ge(s,i,{headers:{Accept:se}},e.fetchTimeoutMs??5e3);if(t.ok){const e=await t.json();e&&"object"==typeof e&&(o=e)}}catch{}return he.set(r,{value:o,expiresAt:Date.now()+1e3*t}),o}const fe=new Map;function we(e){let t="/";try{t=new URL(e).pathname}catch{t=e.startsWith("/")?e:`/${e}`}const r="/"===t?"":t.replace(/\/+$/,"");return X+r}function ye(e){return e.path??`${ee}/${e.name}/SKILL.md`}function be(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:ae,body:t.join("\n")+"\n",cacheControl:pe(e.cacheTtlSeconds??Z)}}function ke(e){return e.endsWith(".json")||e.includes(".well-known/")?se:e.endsWith(".md")?oe:e.endsWith(".xml")?ce:ae}function ve(e){const t=e??{tools:!0},r={tools:!1,resources:!1,prompts:!1};for(const[e,n]of Object.entries(t))r[e]=!1!==n&&null!=n;return r}function Se(e,t){return{status:200,contentType:se,body:JSON.stringify(e,null,2),cacheControl:pe(t.cacheTtlSeconds??Z)}}function Ee(e){return String(e).replace(/[\x00-\x1f\x7f]/g,"")}function Ie(e,t){const r=(Array.isArray(e.userAgent)?e.userAgent:[e.userAgent]).map(e=>`User-agent: ${Ee(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&&r.push(`Content-Signal: ${e.join(", ")}`)}for(const t of e.allow??[])r.push(`Allow: ${Ee(t)}`);for(const t of e.disallow??[])r.push(`Disallow: ${Ee(t)}`);return void 0!==e.crawlDelay&&r.push(`Crawl-delay: ${Ee(e.crawlDelay)}`),r.join("\n")}function Pe(e){const t="number"==typeof e&&Number.isFinite(e)?e:.5;return String(Math.min(1,Math.max(0,t)))}function Te(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&apos;")}function _e(e){const t=le(e.siteUrl),r=[`<${t}/llms.txt>; rel="describedby"; type="text/plain"`,`<${t}/.well-known/agent.json>; rel="describedby"; type="application/json"`];if(!1!==e.a2aCard&&r.push(`<${t}${ne}>; rel="describedby"; type="application/json"`),e.sitemap||e.robots?.sitemaps?.length){const n=e.robots?.sitemaps?.[0]??`${t}/sitemap.xml`;r.push(`<${n}>; rel="sitemap"; type="application/xml"`)}return e.apiCatalog?.length&&r.push(`<${t}${te}>; rel="api-catalog"; type="${ie}"`),e.mcpServerCard&&r.push(`<${t}${re}>; rel="mcp-server"; type="application/json"`),r.join(", ")}async function xe(e,t){const r=e.replace(/\/+$/,"")||e;if("/.well-known/agent.json"===r){return function(e,t){const r=le(e.siteUrl),n={llms_txt:"/llms.txt",sitemap:"/sitemap.xml",robots:"/robots.txt",oauth_protected_resource:X};return t.authorizationServer?.metadataUrl&&(n.oauth_authorization_server=t.authorizationServer.metadataUrl,n.openid_configuration="/.well-known/openid-configuration"),(t.authorizationServer||e.authMd)&&(n.auth="/auth.md"),e.skills?.length&&(n.agent_skills=`${ee}/index.json`),e.apiCatalog?.length&&(n.api_catalog=te),e.mcpServerCard&&(n.mcp_server_card=re),!1!==e.a2aCard&&(n.a2a_agent_card=ne),e.llmsFullTxt&&(n.llms_full_txt="/llms-full.txt"),Se({schema_version:"1.0",name:e.site.name,...e.site.description?{description:e.site.description}:{},url:r,...e.site.documentationUrl?{documentation_url:e.site.documentationUrl}:{},provider:e.site.provider??{name:e.site.name,url:r},capabilities:n,...e.site.contactEmail?{contact:{email:e.site.contactEmail}}:{}},e)}(t,await me(t))}if(r===ne)return function(e){if(!1===e.a2aCard)return null;const t=e.a2aCard??{},r=le(e.siteUrl),n=t.serviceUrl??r,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 Se({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:n,preferredTransport:s,supportedInterfaces:[{serviceUrl:n,transportProtocol:s}],provider:e.site.provider?{organization:e.site.provider.name,url:e.site.provider.url}:{organization:e.site.name,url:r},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"===r)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:pe(e.cacheTtlSeconds??Z)}:null}(t);if("/.well-known/security.txt"===r)return be(t);if(r===`${ee}/index.json`)return function(e){const t=e.skills??[];if(!t.length)return null;const r=le(e.siteUrl);return Se({$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:`${r}${ye(e)}`,digest:de(e.content)}))},e)}(t);if(r.startsWith(`${ee}/`)&&r.endsWith("SKILL.md"))return function(e,t){const r=(t.skills??[]).find(t=>ye(t)===e);return r?{status:200,contentType:"text/markdown; charset=utf-8",body:r.content,cacheControl:pe(t.cacheTtlSeconds??Z)}:null}(r,t);if("/.well-known/oauth-authorization-server"===r||"/.well-known/openid-configuration"===r){const e=(await me(t)).authorizationServer;if(!e?.metadataUrl)return null;const r=await async function(e,t){const r=t.cacheTtlSeconds??Z,n=fe.get(e);if(n&&n.expiresAt>Date.now())return n.value;const s=t.fetch??fetch;let i=null;try{const r=await ge(s,e,{headers:{Accept:se}},t.fetchTimeoutMs??5e3);if(r.ok){const e=await r.json();e&&"object"==typeof e&&(i=e)}}catch{}return fe.set(e,{value:i,expiresAt:Date.now()+1e3*r}),i}(e.metadataUrl,t);return Se(r?r:{...e.issuer?{issuer:e.issuer}:{},oauth_authorization_server_metadata:e.metadataUrl},t)}if(r===te)return function(e){const t=e.apiCatalog??[];if(!t.length)return null;const r=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:ie,body:JSON.stringify({linkset:r},null,2),cacheControl:pe(e.cacheTtlSeconds??Z)}}(t);if(r===re)return function(e){const t=e.mcpServerCard;return t?Se({$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:ve(t.capabilities),...t.documentationUrl?{documentation_url:t.documentationUrl}:{}},e):null}(t);if("/.well-known/mcp.json"===r)return function(e){const t=e.mcpServerCard;if(!t)return null;const r=le(e.siteUrl);let n;try{n={type:"oauth2",protected_resource_metadata:`${new URL(t.endpoint).origin}${we(t.endpoint)}`}}catch{}return Se({$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:ve(t.capabilities),...t.documentationUrl?{documentation_url:t.documentationUrl}:{},server_card:`${r}${re}`,...n?{authentication:n}:{}}]},e)}(t);if(r.startsWith(X)){const e=await me(t);return function(e,t,r){const n=t.protectedResources??[];if(!n.length)return null;const s=e.replace(/\/+$/,"")||X,i=r??`${le(t.serverUrl)}/org/${t.orgId}`,o=t.scopes?.map(e=>e.name),a=n.map(e=>{const r=e.resource??le(t.siteUrl),n=e.scopes??o;return{path:we(r),metadata:{resource:r,authorization_servers:[i],bearer_methods_supported:e.bearerMethods??["header"],...n?.length?{scopes_supported:n}:{},...e.documentationUrl?{resource_documentation:e.documentationUrl}:{}}}}),c=a.find(e=>e.path===s);return c?Se(c.metadata,t):s===X&&1===a.length?Se(a[0].metadata,t):null}(r,t,e.authorizationServer?.issuer)}return null}async function Ue(e,t){const r=e.replace(/\/+$/,"")||e,n=function(e,t){const r=t.extraPaths?.[e];if(void 0===r)return null;const n="string"==typeof r?{body:r}:r;return{status:n.status??200,contentType:n.contentType??ke(e),body:n.body,cacheControl:n.cacheControl??pe(t.cacheTtlSeconds??Z)}}(r,t);return n||("/robots.txt"===r?function(e){const t=e.robots??{},r=le(e.siteUrl),n=t.policies??[{userAgent:"*",allow:["/"]}],s=t.aiBots??"allow",i="allow"===s?[{userAgent:[...ue],allow:["/"]}]:"deny"===s?[{userAgent:[...ue],disallow:["/"]}]:s,o=t.sitemaps??(e.sitemap?[`${r}/sitemap.xml`]:[]),a=[`# robots.txt — agent-ready. See ${r}/llms.txt and ${r}/.well-known/agent.json`,...n.map((e,r)=>Ie(e,0===r?t.contentSignals:void 0)),...i.map(e=>Ie(e)),...o.length?[o.map(e=>`Sitemap: ${Ee(e)}`).join("\n")]:[]];return{status:200,contentType:ae,body:a.join("\n\n")+"\n",cacheControl:pe(e.cacheTtlSeconds??Z)}}(t):"/llms-full.txt"===r?function(e){return e.llmsFullTxt?{status:200,contentType:ae,body:e.llmsFullTxt,cacheControl:pe(e.cacheTtlSeconds??Z)}:null}(t):"/sitemap.xml"===r?function(e){const t=e.sitemap?.urls;if(!t?.length)return null;const r=le(e.siteUrl),n='<?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>${Te(/^https?:\/\//.test(t.loc)?t.loc:`${r}${t.loc.startsWith("/")?"":"/"}${t.loc}`)}</loc>`,...t.lastmod?[` <lastmod>${Te(t.lastmod)}</lastmod>`]:[],...t.changefreq?[` <changefreq>${Te(String(t.changefreq))}</changefreq>`]:[],...void 0!==t.priority?[` <priority>${Pe(t.priority)}</priority>`]:[]].join("\n")}\n </url>`}).join("\n")+"\n</urlset>\n";return{status:200,contentType:ce,body:n,cacheControl:pe(e.cacheTtlSeconds??Z)}}(t):"/llms.txt"===r?function(e){return e.llmsTxt?{status:200,contentType:ae,body:e.llmsTxt,cacheControl:pe(e.cacheTtlSeconds??Z)}:null}(t):"/auth.md"===r?function(e,t){const r=pe(e.cacheTtlSeconds??Z);if(e.authMd)return{status:200,contentType:oe,body:e.authMd,cacheControl:r};const n=t.authorizationServer;if(!n)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: \`${n.issuer}\`\n- Metadata (RFC 8414): ${n.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:oe,body:s,cacheControl:r}}(t,await me(t)):"/security.txt"===r?be(t):r.startsWith("/.well-known")?xe(r,t):null)}let $e=!0;function Ce(e,...t){$e&&function(){try{const e="undefined"!=typeof globalThis?globalThis:null;return"development"===e?.process?.env?.NODE_ENV}catch{return!1}}()&&console.error(e,...t)}function Ae(e,...t){console.error(e,...t)}async function Oe(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 Re(e,t="Request failed"){if(!e.ok){let r,n=t;try{const t=await Oe(e);n=t.message||t.error||n,"string"==typeof t.code&&(r=t.code)}catch{n=function(e,t){const r={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}: ${r})`)}(e,t).message}throw Object.assign(new Error(n),{status:e.status,...r?{code:r}:{}})}try{return await Oe(e)}catch(e){if(e instanceof Error&&e.message.includes("Invalid JSON"))throw e;throw new Error("Failed to parse response as JSON")}}class ze extends Error{constructor(e,t,r,n){super(e),this.code=t,this.context=r,this.originalError=n,this.name="SDKError","undefined"!=typeof Error&&"captureStackTrace"in Error&&Error.captureStackTrace(this,ze)}}const je=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&&($e=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 r=e instanceof Error?e:new ze("string"==typeof e?e:"An unknown error occurred","UNKNOWN_ERROR",t),n=r instanceof ze?r:new ze(r.message,"SDK_ERROR",t,r);if(this.config.enableConsoleLogging&&Ce(`[SDK Error] ${t.component||"Unknown"}:`,{message:n.message,code:n.code,context:n.context,originalError:n.originalError,stack:n.stack}),this.config.onError)try{this.config.onError(n,t)}catch(e){Ae("[SDK Error Handler] Error in custom error callback:",e)}for(const e of this.listeners)try{e(n,t)}catch(e){Ae("[SDK Error Handler] Error in error listener:",e)}this.config.showUserNotifications&&this.notifyUser(n,t)}notifyUser(e,t){"undefined"!=typeof window&&window.dispatchEvent&&window.dispatchEvent(new CustomEvent("sdk-error",{detail:{error:e,context:t}}))}wrapAsync(e,t){return(...r)=>e(...r).catch(e=>{throw this.handleError(e,t),e})}wrapSync(e,t){return(...r)=>{try{return e(...r)}catch(e){throw this.handleError(e,t),e}}}};function Ne(e,t={}){je.handleError(e,t)}function Fe(e){if("undefined"==typeof window)return null;try{return localStorage.getItem(e)}catch(t){return Ne(t,{component:"storage",action:"getStorageItem",metadata:{key:e}}),null}}const We="saas-session-id",Je="saas-device-id";function Me(){return function(){if("undefined"==typeof window)return null;try{return Fe(We)}catch(e){return Ne(e,{component:"auth-utils",action:"getSessionId",metadata:{key:We}}),null}}()}function Le(){const e=Me(),t={};e&&(t["x-session-id"]=e);const r=function(){if("undefined"==typeof window)return null;try{return Fe(Je)??null}catch(e){return Ne(e,{component:"auth-utils",action:"getOrCreateDeviceId",metadata:{key:Je}}),null}}();return r&&(t["x-device-id"]=r),t}const qe=new WeakSet,Be=new Set(["GET","HEAD","OPTIONS","PUT","DELETE"]),De="SDK is not ready (missing serverUrl, version, or orgId)";class Ge{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(De);if(this.requireOrgId&&!this.orgId?.trim())throw new Error(De)}get baseUrl(){return this.ensureReady(),`${this.serverUrl}/api/${this.version}/${this.basePath}`}getAuthHeaders(){return this._sessionId?{"x-session-id":this._sessionId}:Le()}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){qe.has(e)||(qe.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((r,n)=>{const s=()=>{clearTimeout(i),n(new DOMException("The operation was aborted.","AbortError"))};if(t?.aborted)return s();const i=setTimeout(()=>{t?.removeEventListener("abort",s),r()},e);t?.addEventListener("abort",s,{once:!0})})}async executeFetchUrl(e,t,r){const n=(t.method??"GET").toUpperCase(),s=r??e,i=this.buildHeaders(t),o={...t,headers:i},a=Be.has(n);let c,u;if(this._timeout>0){u=new AbortController;const e=u;c=setTimeout(()=>e.abort(),this._timeout),o.signal=t.signal?function(e,t){const r=AbortSignal.any;if("function"==typeof r)return r([e,t]);const n=new AbortController,s=e=>{n.signal.aborted||n.abort(e.reason)};for(const r of[e,t]){if(r.aborted){s(r);break}r.addEventListener("abort",()=>s(r),{once:!0})}return n.signal}(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: ${n} ${s}`);return this.reportError(e,{method:n,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 r=this._fetch.bind(globalThis),s=await r(e,o);if(this._debug&&console.log(`[BuildBase] ${n} ${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 Ge.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 Ge.delay(e,o.signal)}catch(e){throw l(e)}return p(t+1)}throw e instanceof Error&&this.reportError(e,{method:n,path:s}),e}};try{return await p(0)}finally{void 0!==c&&clearTimeout(c)}}async fetchJson(e,t={},r="Request failed"){this.ensureReady();try{const n=await this.executeFetch(e,t);return await Re(n,r)}catch(r){throw r instanceof Error&&this.reportError(r,{method:(t.method??"GET").toUpperCase(),path:e}),r}}async fetchResponse(e,t={}){return this.ensureReady(),this.executeFetch(e,t)}async fetchUnwrapped(e,t={},r="Request failed"){const n=await this.fetchResponse(e,t);return n.ok||await this.throwResponseError(n,r),this.unwrapResponse(n,r)}async fetchAbsoluteUrl(e,t={}){return this.ensureReady(),this.executeFetchUrl(e,t)}async throwResponseError(e,t){let r=t;try{r=(await e.json()).message||r}catch{r=`${t} (${e.status}: ${e.statusText})`}throw Object.assign(new Error(r),{status:e.status})}apiPath(e,...t){return e.reduce((e,r,n)=>e+r+(n<t.length?encodeURIComponent(String(t[n])):""),"")}async unwrapResponse(e,t){const r=await e.json();if(void 0!==r.success){if(!r.success)throw new Error(r.message||t);return void 0!==r.data?r.data:r}return r}}class Ve extends Ge{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,r){await this.fetchJson(this.apiPath`devices/${e}`,{method:"PATCH",body:JSON.stringify({name:t}),signal:r},"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 Ke extends Ge{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 He extends Ge{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 Qe extends Ge{constructor(e){super({...e,requireOrgId:!0})}async getSettings(e){return this.fetchJson(`${this.orgId}/settings`,{signal:e},"Failed to fetch settings")}}class Ye extends Ge{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 r=await this.unwrapResponse(t,"Failed to fetch user attributes");return r&&"object"==typeof r&&!Array.isArray(r)?r:{}}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 r=await this.unwrapResponse(t,"Failed to fetch user features");return"object"==typeof r&&null!==r?r:{}}}const Ze={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 Xe(e){return"number"==typeof e&&Number.isFinite(e)?e:void 0}function et(e){return"string"==typeof e&&e?e:void 0}async function tt(e,t){let r=null;try{r=await e.json()}catch{r=null}return function(e,t,r){const n=t&&"object"==typeof t?t:{},s=et(n.message)??et(n.error)??r,i={status:e,code:et(n.code)??Ze[e]??`HTTP_${e}`,currentUserCount:Xe(n.currentUserCount),limit:Xe(n.limit),retryAfterSeconds:Xe(n.retryAfterSeconds),invitedEmail:et(n.invitedEmail),invitationId:et(n.invitationId),invitationStatus:et(n.status)};return Object.assign(new Error(s),i)}(e.status,r,t)}class rt extends Ge{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(r){const n=r?.status;if(400===n&&e.trackingAttribution){const{trackingAttribution:r,...n}=e;return this.fetchJson("workspaces",{method:"POST",body:JSON.stringify(n),signal:t},"Failed to create workspace")}throw r}}async updateWorkspace(e,t,r){return this.fetchJson(this.apiPath`workspaces/${e}`,{method:"PUT",body:JSON.stringify(t),signal:r},"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,r){return this.fetchJson(this.apiPath`workspaces/${e}/users/add`,{method:"POST",body:JSON.stringify(t),signal:r},"Failed to invite member")}async fetchInvitation(e,t={},r="Request failed"){const n=await this.fetchResponse(e,t);if(!n.ok)throw await tt(n,r);return Re(n,r)}async listInvitations(e,t){return this.fetchInvitation(this.apiPath`workspaces/${e}/invitations`,{signal:t},"Failed to fetch invitations")}async inviteMember(e,t,r){const n={email:t.email,role:t.role};return t.landingUrl&&(n.landingUrl=t.landingUrl),this.fetchInvitation(this.apiPath`workspaces/${e}/invitations`,{method:"POST",body:JSON.stringify(n),signal:r},"Failed to send invitation")}async resendInvitation(e,t,r){return this.fetchInvitation(this.apiPath`workspaces/${e}/invitations/${t}/resend`,{method:"POST",signal:r},"Failed to resend invitation")}async revokeInvitation(e,t,r){return this.fetchInvitation(this.apiPath`workspaces/${e}/invitations/${t}`,{method:"DELETE",signal:r},"Failed to revoke invitation")}async myInvitations(e){return this.fetchInvitation("invitations",{signal:e},"Failed to fetch your invitations")}async acceptInvitation(e,t,r){return this.fetchInvitation(this.apiPath`invitations/${e}/accept`,{method:"PATCH",signal:r,...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,r){return this.fetchJson(this.apiPath`workspaces/${e}/users/${t}`,{method:"DELETE",signal:r},"Failed to remove user")}async updateUser(e,t,r,n){return this.fetchJson(this.apiPath`workspaces/${e}/users/${t}`,{method:"PATCH",body:JSON.stringify(r),signal:n},"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,r){return this.fetchJson(this.apiPath`workspaces/${e}/permissions`,{method:"PATCH",body:JSON.stringify({permissions:t}),signal:r},"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,r,n){return this.fetchJson(this.apiPath`workspaces/${e}/features`,{method:"PATCH",body:JSON.stringify({features:{[t]:r}}),signal:n},"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,r){await this.fetchJson(this.apiPath`passkeys/${e}`,{method:"PATCH",body:JSON.stringify({name:t}),signal:r},"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,r){return this.fetchUnwrapped(this.apiPath`workspaces/${e}/subscription/plan-group`+`?groupVersionId=${encodeURIComponent(t)}`,{signal:r},"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,r){return this.fetchUnwrapped(this.apiPath`workspaces/${e}/subscription/checkout`,{method:"POST",body:JSON.stringify(t),signal:r},"Failed to create checkout session")}async selectFreePlan(e,t,r){return this.fetchUnwrapped(this.apiPath`workspaces/${e}/subscription/select-free-plan`,{method:"POST",body:JSON.stringify({planVersionId:t}),signal:r},"Failed to select free plan")}async updateSubscription(e,t,r){return this.fetchUnwrapped(this.apiPath`workspaces/${e}/subscription`,{method:"PATCH",body:JSON.stringify(t),signal:r},"Failed to update subscription")}async createBillingPortalSession(e,t,r){return this.fetchJson(this.apiPath`workspaces/${e}/subscription/billing-portal`,{method:"POST",body:JSON.stringify(t?{returnUrl:t}:{}),signal:r})}async listInvoices(e,t=10,r,n){const s=new URLSearchParams;return s.append("limit",t.toString()),r&&s.append("starting_after",r),this.fetchUnwrapped(this.apiPath`workspaces/${e}/subscription/invoices`+`?${s.toString()}`,{signal:n},"Failed to fetch invoices")}async getInvoice(e,t,r){return this.fetchUnwrapped(this.apiPath`workspaces/${e}/subscription/invoices/${t}`,{signal:r},"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,r){return this.fetchUnwrapped(this.apiPath`workspaces/${e}/subscription/usage`,{method:"POST",body:JSON.stringify(t),signal:r},"Failed to record usage")}async recordUsageBatch(e,t,r){return this.fetchUnwrapped(this.apiPath`workspaces/${e}/subscription/usage/batch`,{method:"POST",body:JSON.stringify(t),signal:r},"Failed to record batch usage")}async getQuotaUsageStatus(e,t,r){return this.fetchUnwrapped(this.apiPath`workspaces/${e}/subscription/usage/status`+`?quotaSlug=${encodeURIComponent(t)}`,{signal:r},"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,r){const n=new URLSearchParams;t?.quotaSlug&&n.append("quotaSlug",t.quotaSlug),t?.from&&n.append("from",t.from),t?.to&&n.append("to",t.to),t?.source&&n.append("source",t.source),t?.page&&n.append("page",t.page.toString()),t?.limit&&n.append("limit",t.limit.toString());const s=n.toString(),i=this.apiPath`workspaces/${e}/subscription/usage/logs`+(s?`?${s}`:"");return this.fetchUnwrapped(i,{signal:r},"Failed to fetch usage logs")}async sendNotification(e,t,r,n,s){const i={event:t};return r&&(i.userId=r),n&&(i.data=n),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,r){return(await this.fetchJson(this.apiPath`workspaces/${e}/notification-preferences`,{method:"PATCH",body:JSON.stringify({notificationPreferences:t}),signal:r},"Failed to update notification preferences")).notificationPreferences??{}}async getMyNotificationPreferences(e,t){const r=await this.fetchJson(this.apiPath`workspaces/${e}/notification-preferences/me`,{signal:t},"Failed to fetch your notification preferences");return{defaults:r?.defaults??{},mine:r?.mine??{}}}async updateMyNotificationPreferences(e,t,r){const n=await this.fetchJson(this.apiPath`workspaces/${e}/notification-preferences/me`,{method:"PATCH",body:JSON.stringify({notificationPreferences:t}),signal:r},"Failed to update your notification preferences");return{defaults:n?.defaults??{},mine:n?.mine??{}}}async getCreditBalance(e,t){return this.fetchUnwrapped(this.apiPath`workspaces/${e}/credits`,{signal:t},"Failed to fetch credit balance")}async consumeCredits(e,t,r){const n=await this.fetchResponse(this.apiPath`workspaces/${e}/credits/consume`,{method:"POST",body:JSON.stringify(t),signal:r});if(!n.ok){if(402===n.status){const e=await n.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(n,"Failed to consume credits")}return this.unwrapResponse(n,"Failed to consume credits")}async purchaseCredits(e,t,r){return this.fetchUnwrapped(this.apiPath`workspaces/${e}/credits/purchase`,{method:"POST",body:JSON.stringify(t),signal:r},"Failed to create credit purchase checkout")}async getCreditPackages(e,t){const r=await this.fetchUnwrapped(this.apiPath`workspaces/${e}/credits/packages`,{signal:t},"Failed to fetch credit packages");return r.docs??r}async getCreditTransactions(e,t,r){const n=new URLSearchParams;t?.type&&n.append("type",t.type),t?.page&&n.append("page",t.page.toString()),t?.limit&&n.append("limit",t.limit.toString());const s=n.toString(),i=this.apiPath`workspaces/${e}/credits/transactions`+(s?`?${s}`:"");return this.fetchUnwrapped(i,{signal:r},"Failed to fetch credit transactions")}async getCreditBuckets(e,t,r){const n=new URLSearchParams;t?.status&&n.append("status",t.status),t?.source&&n.append("source",t.source),t?.page&&n.append("page",t.page.toString()),t?.limit&&n.append("limit",t.limit.toString());const s=n.toString(),i=this.apiPath`workspaces/${e}/credits/buckets`+(s?`?${s}`:"");return this.fetchUnwrapped(i,{signal:r},"Failed to fetch credit buckets")}async getExpiringCredits(e,t,r){const n=t?`?days=${t}`:"";return this.fetchUnwrapped(this.apiPath`workspaces/${e}/credits/expiring`+n,{signal:r},"Failed to fetch expiring credits")}}const nt={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"},st=Object.values(nt),it={admin:st.filter(e=>e!==nt.WORKSPACE_DELETE),editor:[nt.WORKSPACE_SETTINGS_VIEW,nt.WORKSPACE_MEMBERS_VIEW,nt.WORKSPACE_FEATURES_VIEW,nt.WORKSPACE_BILLING_VIEW,nt.WORKSPACE_USAGE_VIEW,nt.WORKSPACE_USAGE_RECORD],viewer:[nt.WORKSPACE_SETTINGS_VIEW,nt.WORKSPACE_MEMBERS_VIEW]};function ot(e){const t=new Set;for(const r of Object.values(e))for(const e of r)t.add(e);return Array.from(t)}function at(e){const{userId:t,workspace:r,settings:n,appPermissions:s}=e;if(!r||!t)return new Set;if(function(e,t){if(!t)return!1;const r=(n=e.createdBy)?"string"==typeof n?n:"object"==typeof n&&"_id"in n&&"string"==typeof n._id?n._id:null:null;var n;return null!==r&&r===t}(r,t)){const e=new Set(st);if(s)for(const t of ot(s))e.add(t);if(r.permissions)for(const t of ot(r.permissions))e.add(t);if(n?.workspace?.permissions)for(const t of ot(n.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 r=e.users.find(e=>"string"==typeof e?e===t:"object"==typeof e&&null!==e&&"_id"in e&&e._id===t);return r&&"object"==typeof r&&"role"in r&&"string"==typeof r.role?r.role:null}(r,t);return i?function(e,t,r={}){const{workspace:n,settings:s,appPermissions:i}=t;if(!n)return new Set;const o=n.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 it;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]):it[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 it.admin)m.add(e);for(const e of f)m.add(e);if(i)for(const e of u(ot(i)))m.add(e)}!1!==r.applyRestrictions&&function(e,t,r){if(!r?.workspace)return;const{canInviteMembers:n}=r.workspace;(!1===n||"admin-only"===n&&"admin"!==t)&&e.delete(nt.WORKSPACE_MEMBERS_INVITE)}(m,g,s);return m}(i,e):new Set}function ct(e){const{serverUrl:t,orgId:r,version:n="v1",getSessionId:s,timeout:i,maxRetries:o,debug:a,headers:c,onError:u,fetch:l}=e;if(!t)throw new Error("BuildBase: serverUrl is required");if(!r)throw new Error("BuildBase: orgId is required");const p={...void 0!==i&&{timeout:i},...void 0!==o&&{maxRetries:o},...void 0!==a&&{debug:a},...c&&{headers:c},...u&&{onError:u},...l&&{fetch:l}},d=e=>{const s={serverUrl:t,version:n,orgId:r,sessionId:e,...p};return{workspace:new rt(s),user:new Ye(s),settings:new Qe(s),push:new Ke(s),devices:new Ve(s),sessions:new He(s)}},h=new rt({serverUrl:t,version:n,orgId:r,...p}),g=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,r)=>(await e()).workspace.updateWorkspace(t,r),delete:async t=>(await e()).workspace.deleteWorkspace(t),permissions:async t=>(await e()).workspace.getMyPermissions(t),can:async(t,r)=>{const{permissions:n}=await(await e()).workspace.getMyPermissions(t),s=new Set(n);return(Array.isArray(r)?r:[r]).every(e=>s.has(e))}},invitations:{list:async t=>(await e()).workspace.listInvitations(t),create:async(t,r,n,s)=>(await e()).workspace.inviteMember(t,{email:r,role:n,landingUrl:s}),resend:async(t,r)=>(await e()).workspace.resendInvitation(t,r),revoke:async(t,r)=>(await e()).workspace.revokeInvitation(t,r)},users:{list:async t=>(await e()).workspace.getWorkspaceUsers(t),invite:async(t,r,n)=>(await e()).workspace.addUser(t,{email:r,role:n}),remove:async(t,r)=>(await e()).workspace.removeUser(t,r),updateRole:async(t,r,n)=>(await e()).workspace.updateUser(t,r,{role:n}),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,r)=>(await e()).workspace.createCheckoutSession(t,r),update:async(t,r)=>(await e()).workspace.updateSubscription(t,r),cancel:async t=>(await e()).workspace.cancelSubscriptionAtPeriodEnd(t),resume:async t=>(await e()).workspace.resumeSubscription(t),getBillingPortalUrl:async(t,r)=>(await e()).workspace.createBillingPortalSession(t,r)},plans:{getGroup:async t=>(await e()).workspace.getPlanGroup(t),getVersions:async t=>(await e()).workspace.getPlanGroupVersions(t),getPublic:e=>h.getPublicPlans(e),getVersion:e=>h.getPlanGroupVersion(e)},invoices:{list:async(t,r,n)=>(await e()).workspace.listInvoices(t,r,n),get:async(t,r)=>(await e()).workspace.getInvoice(t,r)},usage:{record:async(t,r)=>(await e()).workspace.recordUsage(t,r),recordBatch:async(t,r)=>(await e()).workspace.recordUsageBatch(t,r),getQuota:async(t,r)=>(await e()).workspace.getQuotaUsageStatus(t,r),getAll:async t=>(await e()).workspace.getAllQuotaUsage(t),getLogs:async(t,r)=>(await e()).workspace.getUsageLogs(t,r)},settings:{get:async()=>(await e()).settings.getSettings()},features:{list:async()=>(await e()).workspace.getFeatures(),update:async(t,r,n)=>(await e()).workspace.updateFeature(t,r,n)},notification:{send:async(t,r,n,s)=>(await e()).workspace.sendNotification(t,r,n,s)},credits:{getBalance:async t=>(await e()).workspace.getCreditBalance(t),consume:async(t,r)=>(await e()).workspace.consumeCredits(t,r),purchase:async(t,r)=>(await e()).workspace.purchaseCredits(t,r),getPackages:async t=>(await e()).workspace.getCreditPackages(t),getTransactions:async(t,r)=>(await e()).workspace.getCreditTransactions(t,r),getBuckets:async(t,r)=>(await e()).workspace.getCreditBuckets(t,r),getExpiring:async(t,r)=>(await e()).workspace.getExpiringCredits(t,r),getPublicPackages:()=>h.getPublicCreditPackages()},permissions:{check:async(t,r,n)=>{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)===r);return function(e,t){const r=at(t);return Array.isArray(e)?e.every(e=>r.has(e)):r.has(e)}(n,{userId:r,workspaceRole:c?.role??null,workspace:i,settings:o})},resolve:async(t,r)=>{const n=await e(),[s,i,o]=await Promise.all([n.workspace.getWorkspace(t),n.settings.getSettings(),n.workspace.getWorkspaceUsers(t)]),a=o.find(e=>("string"==typeof e.user?e.user:e.user._id)===r);return at({userId:r,workspaceRole:a?.role??null,workspace:s,settings:i})}},devices:{list:async()=>(await e()).devices.list(),rename:async(t,r)=>(await e()).devices.rename(t,r),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=g(async()=>d(await(async()=>{if(!s)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 s();if(!e)throw new Error("BuildBase: Not authenticated (getSessionId returned null)");return e})()));return{auth:async()=>{if(!s)return null;const e=await s();return e?{sessionId:e}:null},withSession:e=>{const t=d(e);return g(async()=>t)},client:{forSession:d},...m}}exports.AppBridgeError=u,exports.bearerChallenge=f,exports.buildbaseAuth=Y,exports.builtinMcpTools=E,exports.createAgentStack=function(e){const t=le(e.siteUrl),r=e.mcp?.path??"/api/mcp",n=`${t}${r.startsWith("/")?r:`/${r}`}`,s=e.mcp?.serverInfo??{name:e.site.name,version:"1.0.0"},i=`${t}/mcp`,o=Array.from(new Set([i,n])),a=e.mcp?.auth??(e.secret?Y({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:n,...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:n,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"},p=e=>c.fetch(e);return{mcp:c,mcpEndpoint:n,config:u,linkHeader:_e(u),resolvePath:e=>Ue(e,u),serveAgentPath:async function(e){if("OPTIONS"===e.method.toUpperCase())return new Response(null,{status:204,headers:l});const t=await Ue(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}}},exports.createMcpHandler=q,exports.createSessionRefCrypto=H,exports.defineMcpPrompt=e=>e,exports.defineMcpResource=e=>e,exports.defineMcpResourceTemplate=e=>e,exports.defineMcpTool=function(e){return e},exports.extractBearerToken=d,exports.mcpAudio=(e,t)=>({type:"audio",data:e,mimeType:t}),exports.mcpEmbeddedResource=e=>({type:"resource",resource:e}),exports.mcpImage=(e,t)=>({type:"image",data:e,mimeType:t}),exports.mcpResourceLink=(e,t,r)=>({type:"resource_link",uri:e,name:t,...r}),exports.mcpText=P,exports.mintAgentToken=async function(e){const{claims:t,secret:r}=e,n=e.expiresInSec??3600,s=t.resource&&t.resource.length?1===t.resource.length?t.resource[0]:t.resource:void 0,i=t.sessionId?await H(r).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},r,{expiresInSec:n}),expiresIn:n}},exports.selectBuiltinTools=I,exports.signClientJwt=g,exports.verifyClientJwt=p;