@buildbase/sdk 0.0.53 → 0.0.55

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 (60) hide show
  1. package/AGENTS.md +16 -6
  2. package/CHANGELOG.md +99 -0
  3. package/LICENSE +21 -0
  4. package/README.md +278 -85
  5. package/dist/css/styles.css +1 -1
  6. package/dist/index.cjs +1 -1
  7. package/dist/index.d.ts +582 -114
  8. package/dist/index.mjs +1 -1
  9. package/dist/mcp/index.cjs +1 -1
  10. package/dist/mcp/index.d.ts +780 -16
  11. package/dist/mcp/index.mjs +1 -1
  12. package/dist/react/chunks/SettingsDialog-B6DhyNae.cjs +2 -0
  13. package/dist/react/chunks/SettingsDialog-K38BI74F.mjs +2 -0
  14. package/dist/react/chunks/SubscriptionDialog-BidcQ_vc.mjs +2 -0
  15. package/dist/react/chunks/SubscriptionDialog-CfDLoOzW.cjs +2 -0
  16. package/dist/react/chunks/ar-CCKONfUU.mjs +2 -0
  17. package/dist/react/chunks/ar-DrHMtT1E.cjs +2 -0
  18. package/dist/react/chunks/de-Dhtorn10.cjs +2 -0
  19. package/dist/react/chunks/de-X9mfnMFM.mjs +2 -0
  20. package/dist/react/chunks/es--8iZ7Trv.mjs +2 -0
  21. package/dist/react/chunks/es-CUR7LB6a.cjs +2 -0
  22. package/dist/react/chunks/fr-BqMs_F5g.cjs +2 -0
  23. package/dist/react/chunks/fr-rUp34NG7.mjs +2 -0
  24. package/dist/react/chunks/hi-B_IiucJZ.mjs +2 -0
  25. package/dist/react/chunks/hi-C2i1_hdv.cjs +2 -0
  26. package/dist/react/chunks/ja-4hLI6wMX.cjs +2 -0
  27. package/dist/react/chunks/ja-CIGOj3vV.mjs +2 -0
  28. package/dist/react/chunks/react-BXTDLnE8.cjs +2 -0
  29. package/dist/react/chunks/react-CXCk05WI.mjs +2 -0
  30. package/dist/react/chunks/zh-BSgd6ai5.cjs +2 -0
  31. package/dist/react/chunks/zh-DyVvcYFC.mjs +2 -0
  32. package/dist/react/index.cjs +1 -1
  33. package/dist/react/index.d.ts +507 -141
  34. package/dist/react/index.mjs +1 -1
  35. package/docs/ARCHITECTURE.md +419 -0
  36. package/docs/ERROR_CODES.md +96 -0
  37. package/docs/MCP-AND-AGENT-READINESS.md +893 -0
  38. package/docs/THEMING.md +67 -0
  39. package/docs/UI-CONFIG.md +207 -0
  40. package/package.json +17 -4
  41. package/dist/react/chunks/SettingsDialog-BxDYsie6.mjs +0 -2
  42. package/dist/react/chunks/SettingsDialog-Dy8W3NA6.cjs +0 -2
  43. package/dist/react/chunks/SubscriptionDialog-6c5dHoQd.mjs +0 -2
  44. package/dist/react/chunks/SubscriptionDialog-CpVnnXJg.cjs +0 -2
  45. package/dist/react/chunks/ar-1Z1MOGAP.mjs +0 -2
  46. package/dist/react/chunks/ar-VGzBv3AZ.cjs +0 -2
  47. package/dist/react/chunks/de-BjdDg60Y.cjs +0 -2
  48. package/dist/react/chunks/de-CXUItplO.mjs +0 -2
  49. package/dist/react/chunks/es-BBPsSZUp.cjs +0 -2
  50. package/dist/react/chunks/es-BTbzVutz.mjs +0 -2
  51. package/dist/react/chunks/fr-Cax48X_S.cjs +0 -2
  52. package/dist/react/chunks/fr-DPMeOQu3.mjs +0 -2
  53. package/dist/react/chunks/hi-BJqvpG6d.cjs +0 -2
  54. package/dist/react/chunks/hi-JfJx-LV7.mjs +0 -2
  55. package/dist/react/chunks/ja-CDGtLzTk.mjs +0 -2
  56. package/dist/react/chunks/ja-DvVyj5xX.cjs +0 -2
  57. package/dist/react/chunks/react-4SlWxHdh.cjs +0 -2
  58. package/dist/react/chunks/react-OL1uSkpr.mjs +0 -2
  59. package/dist/react/chunks/zh-BAcqxkxk.cjs +0 -2
  60. package/dist/react/chunks/zh-BNZ2Ooe8.mjs +0 -2
package/dist/index.d.ts CHANGED
@@ -1003,7 +1003,7 @@ interface ISettings {
1003
1003
  /** Auto-create workspace on first login */
1004
1004
  autoCreateFirst: boolean;
1005
1005
  };
1006
- [key: string]: any;
1006
+ [key: string]: unknown;
1007
1007
  }
1008
1008
 
1009
1009
  /**
@@ -1017,9 +1017,14 @@ interface IOsConfig {
1017
1017
  version: ApiVersion;
1018
1018
  orgId: string;
1019
1019
  }
1020
+ /** Lifecycle of the one-time org-settings fetch. */
1021
+ type SettingsStatus = 'idle' | 'loading' | 'loaded' | 'error';
1020
1022
  interface IOsState extends IOsConfig {
1021
1023
  auth?: IAuthConfig;
1022
1024
  settings?: ISettings | null;
1025
+ /** State of the settings fetch — lets UI wait instead of guessing with `?? true` defaults. */
1026
+ settingsStatus?: SettingsStatus;
1027
+ settingsError?: string | null;
1023
1028
  }
1024
1029
 
1025
1030
  /**
@@ -1082,6 +1087,7 @@ interface IBaseApiConfig {
1082
1087
  * - getAuthHeaders()
1083
1088
  * - fetchJson<T>(path, init, errorMessage): GET/POST/etc. with handleApiResponse
1084
1089
  * - fetchResponse(path, init): raw Response for custom parsing (e.g. non-JSON or custom error handling)
1090
+ * - fetchUnwrapped<T>(path, init, errorMessage): fetch → throw on !ok → unwrap { success, data } envelope
1085
1091
  */
1086
1092
  declare abstract class BaseApi {
1087
1093
  protected readonly serverUrl: string;
@@ -1116,6 +1122,8 @@ declare abstract class BaseApi {
1116
1122
  private reportError;
1117
1123
  /** Execute fetch with timeout, retries, debug logging, and error callback. */
1118
1124
  private executeFetch;
1125
+ /** Backoff sleep that ends early (with an AbortError) when the signal fires. */
1126
+ private static delay;
1119
1127
  /** Internal: execute fetch against a resolved URL with timeout, retries, debug logging, and error callback. */
1120
1128
  private executeFetchUrl;
1121
1129
  /**
@@ -1128,6 +1136,12 @@ declare abstract class BaseApi {
1128
1136
  * Caller is responsible for checking response.ok and parsing body.
1129
1137
  */
1130
1138
  protected fetchResponse(path: string, init?: RequestInit): Promise<Response>;
1139
+ /**
1140
+ * Execute request, throw a parsed error on !response.ok, and unwrap the
1141
+ * `{ success, data }` envelope. Shorthand for the common
1142
+ * fetchResponse → throwResponseError → unwrapResponse sequence.
1143
+ */
1144
+ protected fetchUnwrapped<T>(path: string, init?: RequestInit, errorMessage?: string): Promise<T>;
1131
1145
  /**
1132
1146
  * Execute request against an absolute URL (bypasses baseUrl).
1133
1147
  * Useful for endpoints outside the default basePath (e.g. /auth vs /public).
@@ -1169,21 +1183,26 @@ interface AuthRequestParams {
1169
1183
  };
1170
1184
  state?: string;
1171
1185
  }
1186
+ /**
1187
+ * Unwrapped payload of a successful auth request.
1188
+ * ⚠️ Prior to the envelope unification this type described the raw
1189
+ * `{ success, data, message }` wire envelope; `requestAuth` now unwraps the
1190
+ * envelope like every other SDK method and resolves with the payload only.
1191
+ */
1172
1192
  interface AuthRequestResponse {
1173
- success: boolean;
1174
- data: {
1175
- redirectUrl: string;
1176
- };
1177
- message: string;
1193
+ redirectUrl: string;
1178
1194
  }
1179
1195
  declare class AuthApi extends BaseApi {
1180
1196
  constructor(config: Pick<IOsConfig, 'serverUrl' | 'version'> & {
1181
1197
  sessionId?: string;
1182
1198
  });
1183
1199
  /**
1184
- * Initiate OAuth sign-in flow. Returns redirect URL to the auth provider.
1200
+ * Initiate OAuth sign-in flow. Resolves with the redirect URL to the auth provider.
1185
1201
  * Auth endpoints sit at /api/v1/auth/ (outside the /public basePath),
1186
- * so we use fetchAbsoluteUrl to get timeout, retry, and error handling via BaseApi.
1202
+ * so we use fetchAbsoluteUrl to get timeout, retry, and error handling via
1203
+ * BaseApi, then apply the standard throwResponseError → unwrapResponse
1204
+ * sequence (the fetchUnwrapped convention). Non-2xx responses and 2xx
1205
+ * envelopes with `success: false` both throw a structured Error.
1187
1206
  */
1188
1207
  requestAuth(params: AuthRequestParams): Promise<AuthRequestResponse>;
1189
1208
  /** Fetch user profile with the given session ID (used after OAuth redirect or from storage). */
@@ -1334,7 +1353,7 @@ interface NotificationData {
1334
1353
  push?: boolean;
1335
1354
  };
1336
1355
  /** Any additional merge tags available as {{key}} in the email template. */
1337
- [key: string]: any;
1356
+ [key: string]: unknown;
1338
1357
  }
1339
1358
  /** Result of sending a notification. */
1340
1359
  interface NotificationResult {
@@ -1365,64 +1384,64 @@ declare class WorkspaceApi extends BaseApi {
1365
1384
  sessionId?: string;
1366
1385
  onUnauthorized?: () => void;
1367
1386
  });
1368
- getWorkspaces(): Promise<IWorkspace[]>;
1387
+ getWorkspaces(signal?: AbortSignal): Promise<IWorkspace[]>;
1369
1388
  createWorkspace(data: {
1370
1389
  name: string;
1371
1390
  image?: string;
1372
- }): Promise<IWorkspace>;
1373
- updateWorkspace(id: string, data: Partial<IWorkspace>): Promise<IWorkspace>;
1374
- deleteWorkspace(id: string): Promise<{
1391
+ }, signal?: AbortSignal): Promise<IWorkspace>;
1392
+ updateWorkspace(id: string, data: Partial<IWorkspace>, signal?: AbortSignal): Promise<IWorkspace>;
1393
+ deleteWorkspace(id: string, signal?: AbortSignal): Promise<{
1375
1394
  success: boolean;
1376
1395
  }>;
1377
- getWorkspaceUsers(workspaceId: string): Promise<IWorkspaceUser[]>;
1396
+ getWorkspaceUsers(workspaceId: string, signal?: AbortSignal): Promise<IWorkspaceUser[]>;
1378
1397
  addUser(workspaceId: string, config: {
1379
1398
  email: string;
1380
1399
  role: string;
1381
- }): Promise<{
1400
+ }, signal?: AbortSignal): Promise<{
1382
1401
  userId: string;
1383
1402
  workspace: IWorkspace;
1384
1403
  message: string;
1385
1404
  }>;
1386
- removeUser(workspaceId: string, userId: string): Promise<{
1405
+ removeUser(workspaceId: string, userId: string, signal?: AbortSignal): Promise<{
1387
1406
  userId: string;
1388
1407
  workspace: IWorkspace;
1389
1408
  message: string;
1390
1409
  }>;
1391
- updateUser(workspaceId: string, userId: string, data: Partial<IWorkspaceUser>): Promise<{
1410
+ updateUser(workspaceId: string, userId: string, data: Partial<IWorkspaceUser>, signal?: AbortSignal): Promise<{
1392
1411
  userId: string;
1393
1412
  workspace: IWorkspace;
1394
1413
  message: string;
1395
1414
  }>;
1396
1415
  updateSettings(data: {
1397
1416
  permissions: Record<string, string[]>;
1398
- }): Promise<any>;
1399
- updateWorkspacePermissions(workspaceId: string, permissions: Record<string, string[]>): Promise<any>;
1400
- getFeatures(): Promise<IWorkspaceFeature[]>;
1401
- updateFeature(workspaceId: string, key: string, value: boolean): Promise<IWorkspace>;
1402
- getWorkspace(workspaceId: string): Promise<IWorkspace>;
1403
- getProfile(): Promise<IUser>;
1404
- updateUserProfile(config: Partial<IUser>): Promise<IUser>;
1405
- getPasskeys(): Promise<IPasskeySummary[]>;
1406
- renamePasskey(passkeyId: string, name: string): Promise<void>;
1407
- deletePasskey(passkeyId: string): Promise<void>;
1417
+ }, signal?: AbortSignal): Promise<any>;
1418
+ updateWorkspacePermissions(workspaceId: string, permissions: Record<string, string[]>, signal?: AbortSignal): Promise<any>;
1419
+ getFeatures(signal?: AbortSignal): Promise<IWorkspaceFeature[]>;
1420
+ updateFeature(workspaceId: string, key: string, value: boolean, signal?: AbortSignal): Promise<IWorkspace>;
1421
+ getWorkspace(workspaceId: string, signal?: AbortSignal): Promise<IWorkspace>;
1422
+ getProfile(signal?: AbortSignal): Promise<IUser>;
1423
+ updateUserProfile(config: Partial<IUser>, signal?: AbortSignal): Promise<IUser>;
1424
+ getPasskeys(signal?: AbortSignal): Promise<IPasskeySummary[]>;
1425
+ renamePasskey(passkeyId: string, name: string, signal?: AbortSignal): Promise<void>;
1426
+ deletePasskey(passkeyId: string, signal?: AbortSignal): Promise<void>;
1408
1427
  /**
1409
1428
  * Get current subscription for a workspace
1410
1429
  * Returns subscription details including plan, plan version, and group information
1411
1430
  */
1412
- getCurrentSubscription(workspaceId: string): Promise<ISubscriptionResponse>;
1431
+ getCurrentSubscription(workspaceId: string, signal?: AbortSignal): Promise<ISubscriptionResponse>;
1413
1432
  /**
1414
1433
  * Get plan group for a workspace
1415
1434
  * Returns the plan group containing the current plan if subscription exists,
1416
1435
  * otherwise returns the latest published group
1417
1436
  */
1418
- getPlanGroup(workspaceId: string): Promise<IPlanGroupResponse>;
1437
+ getPlanGroup(workspaceId: string, signal?: AbortSignal): Promise<IPlanGroupResponse>;
1419
1438
  /**
1420
1439
  * Get plan group for a workspace with a specific version
1421
1440
  * @param workspaceId - The workspace ID
1422
1441
  * @param groupVersionId - The plan group version ID to fetch
1423
1442
  * @returns Plan group response with the specified version
1424
1443
  */
1425
- getPlanGroupByVersion(workspaceId: string, groupVersionId: string): Promise<IPlanGroupResponse>;
1444
+ getPlanGroupByVersion(workspaceId: string, groupVersionId: string, signal?: AbortSignal): Promise<IPlanGroupResponse>;
1426
1445
  /**
1427
1446
  * Get current group version and available newer versions of the same group
1428
1447
  * - If user has active subscription: returns their current group version + newer versions
@@ -1432,7 +1451,7 @@ declare class WorkspaceApi extends BaseApi {
1432
1451
  * @param workspaceId - The workspace ID
1433
1452
  * @returns Plan group versions response with currentVersion and availableVersions
1434
1453
  */
1435
- getPlanGroupVersions(workspaceId: string): Promise<IPlanGroupVersionsResponse>;
1454
+ getPlanGroupVersions(workspaceId: string, signal?: AbortSignal): Promise<IPlanGroupVersionsResponse>;
1436
1455
  /**
1437
1456
  * Get plan group versions by slug (public, no auth required).
1438
1457
  * Returns the latest published plan group versions for the given plan group slug.
@@ -1441,7 +1460,7 @@ declare class WorkspaceApi extends BaseApi {
1441
1460
  * @param slug - Plan group slug (e.g. 'default', 'enterprise')
1442
1461
  * @returns Plan group versions response with currentVersion and availableVersions
1443
1462
  */
1444
- getPublicPlans(slug: string): Promise<IPublicPlansResponse>;
1463
+ getPublicPlans(slug: string, signal?: AbortSignal): Promise<IPublicPlansResponse>;
1445
1464
  /**
1446
1465
  * Get credit packages (public, no auth required).
1447
1466
  * Returns active credit packages for the org with pricing info.
@@ -1449,7 +1468,7 @@ declare class WorkspaceApi extends BaseApi {
1449
1468
  *
1450
1469
  * @returns Credit packages with pricing variants
1451
1470
  */
1452
- getPublicCreditPackages(): Promise<IPublicCreditPackagesResponse>;
1471
+ getPublicCreditPackages(signal?: AbortSignal): Promise<IPublicCreditPackagesResponse>;
1453
1472
  /**
1454
1473
  * Get plan group version details by ID (public, no auth required).
1455
1474
  * Returns the full plan group version with populated plan versions.
@@ -1458,15 +1477,24 @@ declare class WorkspaceApi extends BaseApi {
1458
1477
  * @param groupVersionId - The plan group version ID to fetch
1459
1478
  * @returns Plan group version with populated plan versions
1460
1479
  */
1461
- getPlanGroupVersion(groupVersionId: string): Promise<IPlanGroupVersion>;
1480
+ getPlanGroupVersion(groupVersionId: string, signal?: AbortSignal): Promise<IPlanGroupVersion>;
1462
1481
  /**
1463
1482
  * Create checkout session for new subscription
1464
1483
  * @param workspaceId - The workspace ID
1465
1484
  * @param request - Checkout session request with planVersionId and optional billing interval/URLs
1466
1485
  * @returns Checkout session response with checkoutUrl to redirect user
1467
1486
  */
1468
- createCheckoutSession(workspaceId: string, request: ICheckoutSessionRequest): Promise<CheckoutResult>;
1469
- selectFreePlan(workspaceId: string, planVersionId: string): Promise<{
1487
+ createCheckoutSession(workspaceId: string, request: ICheckoutSessionRequest, signal?: AbortSignal): Promise<CheckoutResult>;
1488
+ /**
1489
+ * Assign a free (freemium) plan to the workspace without a Stripe checkout.
1490
+ *
1491
+ * This endpoint's envelope carries no `data` payload — it is
1492
+ * `{ success, message }` — so `fetchUnwrapped` resolves with the envelope
1493
+ * itself (its unwrap only extracts `data` when present). On resolution
1494
+ * `success` is therefore always `true`: non-2xx responses and 2xx envelopes
1495
+ * with `success: false` both throw a structured Error.
1496
+ */
1497
+ selectFreePlan(workspaceId: string, planVersionId: string, signal?: AbortSignal): Promise<{
1470
1498
  success: boolean;
1471
1499
  message: string;
1472
1500
  }>;
@@ -1475,12 +1503,12 @@ declare class WorkspaceApi extends BaseApi {
1475
1503
  * Only allows plan changes within the same plan group
1476
1504
  * Returns checkout session if payment is required, otherwise returns subscription update response
1477
1505
  */
1478
- updateSubscription(workspaceId: string, request: ISubscriptionUpdateRequest): Promise<ISubscriptionUpdateResponse | ICheckoutSessionResponse>;
1506
+ updateSubscription(workspaceId: string, request: ISubscriptionUpdateRequest, signal?: AbortSignal): Promise<ISubscriptionUpdateResponse | ICheckoutSessionResponse>;
1479
1507
  /**
1480
1508
  * Create a Stripe Customer Portal session for managing payment methods, invoices, etc.
1481
1509
  * Returns the portal URL — redirect user to it.
1482
1510
  */
1483
- createBillingPortalSession(workspaceId: string, returnUrl?: string): Promise<{
1511
+ createBillingPortalSession(workspaceId: string, returnUrl?: string, signal?: AbortSignal): Promise<{
1484
1512
  url: string;
1485
1513
  }>;
1486
1514
  /**
@@ -1490,35 +1518,35 @@ declare class WorkspaceApi extends BaseApi {
1490
1518
  * @param startingAfter - Invoice ID to start after (for pagination)
1491
1519
  * @returns List of invoices with pagination info
1492
1520
  */
1493
- listInvoices(workspaceId: string, limit?: number, startingAfter?: string): Promise<IInvoiceListResponse>;
1521
+ listInvoices(workspaceId: string, limit?: number, startingAfter?: string, signal?: AbortSignal): Promise<IInvoiceListResponse>;
1494
1522
  /**
1495
1523
  * Get a single invoice by ID
1496
1524
  * @param workspaceId - The workspace ID
1497
1525
  * @param invoiceId - The invoice ID
1498
1526
  * @returns Invoice details
1499
1527
  */
1500
- getInvoice(workspaceId: string, invoiceId: string): Promise<IInvoiceResponse>;
1528
+ getInvoice(workspaceId: string, invoiceId: string, signal?: AbortSignal): Promise<IInvoiceResponse>;
1501
1529
  /**
1502
1530
  * Cancel subscription at the end of the current billing period
1503
1531
  * Sets cancelAtPeriodEnd: true - subscription remains active until period ends
1504
1532
  * @param workspaceId - The workspace ID
1505
1533
  * @returns Updated subscription with cancelAtPeriodEnd and stripeCurrentPeriodEnd
1506
1534
  */
1507
- cancelSubscriptionAtPeriodEnd(workspaceId: string): Promise<ISubscriptionResponse>;
1535
+ cancelSubscriptionAtPeriodEnd(workspaceId: string, signal?: AbortSignal): Promise<ISubscriptionResponse>;
1508
1536
  /**
1509
1537
  * Resume a subscription that was scheduled for cancellation
1510
1538
  * Sets cancelAtPeriodEnd: false - subscription will continue after period ends
1511
1539
  * @param workspaceId - The workspace ID
1512
1540
  * @returns Updated subscription with cancelAtPeriodEnd set to false
1513
1541
  */
1514
- resumeSubscription(workspaceId: string): Promise<ISubscriptionResponse>;
1542
+ resumeSubscription(workspaceId: string, signal?: AbortSignal): Promise<ISubscriptionResponse>;
1515
1543
  /**
1516
1544
  * Record quota usage for a workspace
1517
1545
  * @param workspaceId - The workspace ID
1518
1546
  * @param request - Usage request with quotaSlug, quantity, and optional metadata/source
1519
1547
  * @returns Usage result with consumed/included/available/overage
1520
1548
  */
1521
- recordUsage(workspaceId: string, request: IRecordUsageRequest): Promise<IRecordUsageResponse>;
1549
+ recordUsage(workspaceId: string, request: IRecordUsageRequest, signal?: AbortSignal): Promise<IRecordUsageResponse>;
1522
1550
  /**
1523
1551
  * Record multiple quota usage entries in a single request.
1524
1552
  * Designed for backend-to-backend high-volume scenarios (bulk exports, batch jobs).
@@ -1542,7 +1570,7 @@ declare class WorkspaceApi extends BaseApi {
1542
1570
  source?: string;
1543
1571
  idempotencyKey?: string;
1544
1572
  }>;
1545
- }): Promise<{
1573
+ }, signal?: AbortSignal): Promise<{
1546
1574
  success: boolean;
1547
1575
  total: number;
1548
1576
  succeeded: number;
@@ -1560,20 +1588,20 @@ declare class WorkspaceApi extends BaseApi {
1560
1588
  * @param quotaSlug - The quota slug to check
1561
1589
  * @returns Quota usage status with consumed/included/available/overage/hasOverage
1562
1590
  */
1563
- getQuotaUsageStatus(workspaceId: string, quotaSlug: string): Promise<IQuotaUsageStatusResponse>;
1591
+ getQuotaUsageStatus(workspaceId: string, quotaSlug: string, signal?: AbortSignal): Promise<IQuotaUsageStatusResponse>;
1564
1592
  /**
1565
1593
  * Get usage status for all quotas in the workspace's current plan
1566
1594
  * @param workspaceId - The workspace ID
1567
1595
  * @returns All quota usage statuses keyed by quota slug
1568
1596
  */
1569
- getAllQuotaUsage(workspaceId: string): Promise<IAllQuotaUsageResponse>;
1597
+ getAllQuotaUsage(workspaceId: string, signal?: AbortSignal): Promise<IAllQuotaUsageResponse>;
1570
1598
  /**
1571
1599
  * Get paginated usage logs for a workspace
1572
1600
  * @param workspaceId - The workspace ID
1573
1601
  * @param query - Optional filters: quotaSlug, from, to, source, page, limit
1574
1602
  * @returns Paginated usage log entries
1575
1603
  */
1576
- getUsageLogs(workspaceId: string, query?: IUsageLogsQuery): Promise<IUsageLogsResponse>;
1604
+ getUsageLogs(workspaceId: string, query?: IUsageLogsQuery, signal?: AbortSignal): Promise<IUsageLogsResponse>;
1577
1605
  /**
1578
1606
  * Trigger a notification event for a workspace.
1579
1607
  * Respects all notification gates (org settings, event config, workspace preferences).
@@ -1596,16 +1624,16 @@ declare class WorkspaceApi extends BaseApi {
1596
1624
  * });
1597
1625
  * ```
1598
1626
  */
1599
- sendNotification(workspaceId: string, event: string, userId?: string, data?: NotificationData): Promise<NotificationResult>;
1600
- getNotificationEvents(workspaceId: string): Promise<NotificationEvent[]>;
1601
- getNotificationPreferences(workspaceId: string): Promise<Record<string, {
1627
+ sendNotification(workspaceId: string, event: string, userId?: string, data?: NotificationData, signal?: AbortSignal): Promise<NotificationResult>;
1628
+ getNotificationEvents(workspaceId: string, signal?: AbortSignal): Promise<NotificationEvent[]>;
1629
+ getNotificationPreferences(workspaceId: string, signal?: AbortSignal): Promise<Record<string, {
1602
1630
  email?: boolean;
1603
1631
  push?: boolean;
1604
1632
  }>>;
1605
1633
  updateNotificationPreferences(workspaceId: string, preferences: Record<string, {
1606
1634
  email?: boolean;
1607
1635
  push?: boolean;
1608
- }>): Promise<Record<string, {
1636
+ }>, signal?: AbortSignal): Promise<Record<string, {
1609
1637
  email?: boolean;
1610
1638
  push?: boolean;
1611
1639
  }>>;
@@ -1614,7 +1642,7 @@ declare class WorkspaceApi extends BaseApi {
1614
1642
  * @param workspaceId - The workspace ID
1615
1643
  * @returns Credit balance with available, totalGranted, totalConsumed, totalExpired, totalRefunded
1616
1644
  */
1617
- getCreditBalance(workspaceId: string): Promise<ICreditBalance>;
1645
+ getCreditBalance(workspaceId: string, signal?: AbortSignal): Promise<ICreditBalance>;
1618
1646
  /**
1619
1647
  * Consume credits from a workspace balance.
1620
1648
  * Throws an error with `code: 'INSUFFICIENT_CREDITS'` and `available`/`requested` fields on 402.
@@ -1622,7 +1650,7 @@ declare class WorkspaceApi extends BaseApi {
1622
1650
  * @param request - Consume request with amount, optional description, idempotencyKey, metadata
1623
1651
  * @returns Consume result with consumed amount and balanceAfter
1624
1652
  */
1625
- consumeCredits(workspaceId: string, request: IConsumeCreditsRequest): Promise<IConsumeCreditsResponse>;
1653
+ consumeCredits(workspaceId: string, request: IConsumeCreditsRequest, signal?: AbortSignal): Promise<IConsumeCreditsResponse>;
1626
1654
  /**
1627
1655
  * Create a Stripe checkout session for purchasing a credit package.
1628
1656
  * Returns a checkout URL to redirect the user to.
@@ -1630,35 +1658,35 @@ declare class WorkspaceApi extends BaseApi {
1630
1658
  * @param request - Purchase request with creditPackageId, successUrl, cancelUrl, optional currency
1631
1659
  * @returns Checkout session ID and URL
1632
1660
  */
1633
- purchaseCredits(workspaceId: string, request: ICreditPurchaseRequest): Promise<ICreditPurchaseResponse>;
1661
+ purchaseCredits(workspaceId: string, request: ICreditPurchaseRequest, signal?: AbortSignal): Promise<ICreditPurchaseResponse>;
1634
1662
  /**
1635
1663
  * List available credit packages for purchase.
1636
1664
  * Returns active, non-archived packages sorted by sortOrder then creditAmount.
1637
1665
  * @param workspaceId - The workspace ID
1638
1666
  * @returns Array of credit packages
1639
1667
  */
1640
- getCreditPackages(workspaceId: string): Promise<ICreditPackage[]>;
1668
+ getCreditPackages(workspaceId: string, signal?: AbortSignal): Promise<ICreditPackage[]>;
1641
1669
  /**
1642
1670
  * Get paginated credit transaction history.
1643
1671
  * @param workspaceId - The workspace ID
1644
1672
  * @param query - Optional filters: type, page, limit
1645
1673
  * @returns Paginated credit transactions
1646
1674
  */
1647
- getCreditTransactions(workspaceId: string, query?: ICreditTransactionsQuery): Promise<ICreditTransactionsResponse>;
1675
+ getCreditTransactions(workspaceId: string, query?: ICreditTransactionsQuery, signal?: AbortSignal): Promise<ICreditTransactionsResponse>;
1648
1676
  /**
1649
1677
  * Get paginated credit buckets.
1650
1678
  * @param workspaceId - The workspace ID
1651
1679
  * @param query - Optional filters: status, source, page, limit
1652
1680
  * @returns Paginated credit buckets
1653
1681
  */
1654
- getCreditBuckets(workspaceId: string, query?: ICreditBucketsQuery): Promise<ICreditBucketsResponse>;
1682
+ getCreditBuckets(workspaceId: string, query?: ICreditBucketsQuery, signal?: AbortSignal): Promise<ICreditBucketsResponse>;
1655
1683
  /**
1656
1684
  * Get credits expiring within N days.
1657
1685
  * @param workspaceId - The workspace ID
1658
1686
  * @param days - Look-ahead window in days (1-90, default 7)
1659
1687
  * @returns Expiring credits summary with bucket list
1660
1688
  */
1661
- getExpiringCredits(workspaceId: string, days?: number): Promise<IExpiringCreditsResponse>;
1689
+ getExpiringCredits(workspaceId: string, days?: number, signal?: AbortSignal): Promise<IExpiringCreditsResponse>;
1662
1690
  }
1663
1691
 
1664
1692
  /**
@@ -1785,6 +1813,7 @@ declare const BBAction: {
1785
1813
  readonly SelectPlan: "selectPlan";
1786
1814
  readonly CreditPurchase: "creditPurchase";
1787
1815
  readonly OpenCreditStore: "openCreditStore";
1816
+ readonly OpenConnectGuide: "openConnectGuide";
1788
1817
  readonly Invite: "invite";
1789
1818
  };
1790
1819
  type BBActionType = (typeof BBAction)[keyof typeof BBAction];
@@ -1860,15 +1889,40 @@ declare function cleanBBParams(): void;
1860
1889
  /**
1861
1890
  * Security utilities for the SDK.
1862
1891
  */
1892
+ /** Options for {@link validateRedirectUrl}. */
1893
+ interface RedirectValidationOptions {
1894
+ /**
1895
+ * Require absolute URLs to be same-origin with the current page
1896
+ * (`window.location.origin`). Relative paths always pass. Use for any
1897
+ * user-controllable target (return URLs, `?next=` params) — it turns an
1898
+ * open redirect into a same-site navigation. Outside a browser there is no
1899
+ * origin to compare against, so absolute URLs are rejected.
1900
+ */
1901
+ sameOrigin?: boolean;
1902
+ /**
1903
+ * Origins additionally allowed for absolute URLs, e.g.
1904
+ * `['https://checkout.stripe.com']`. Matched against `URL.origin` exactly.
1905
+ */
1906
+ allowedOrigins?: string[];
1907
+ }
1863
1908
  /**
1864
- * Validate that a URL is safe to redirect to.
1865
- * Prevents open redirect attacks by ensuring the URL uses https (or http on localhost).
1866
- * Returns the URL if safe, or null if not.
1909
+ * Validate that a URL is safe to redirect to. Returns the URL if safe, null if
1910
+ * not.
1911
+ *
1912
+ * - **Relative paths** (`/dashboard`) are safe and always allowed —
1913
+ * protocol-relative (`//evil.com`) and backslash (`/\evil.com`) forms are
1914
+ * not treated as relative.
1915
+ * - **Absolute URLs** must be `https:` (or `http:` on localhost). By default
1916
+ * any such URL passes (needed for cross-origin targets like Stripe checkout);
1917
+ * pass `sameOrigin` and/or `allowedOrigins` to restrict — then the URL must
1918
+ * match at least one of them. Always restrict user-controllable targets.
1867
1919
  */
1868
- declare function validateRedirectUrl(url: string | null | undefined): string | null;
1920
+ declare function validateRedirectUrl(url: string | null | undefined, options?: RedirectValidationOptions): string | null;
1869
1921
  /**
1870
1922
  * Safely redirect to a URL after validating it.
1871
- * Falls back to fallbackUrl if the target URL is invalid.
1923
+ * Falls back to fallbackUrl (itself validated — else `/`) if the target URL is
1924
+ * invalid. Pass `options` to restrict user-controllable targets (see
1925
+ * {@link validateRedirectUrl}).
1872
1926
  *
1873
1927
  * Browser-only: navigation requires `window.location`. On non-browser runtimes
1874
1928
  * (Node, edge, Deno, Bun) there is nothing to navigate, so this is a no-op that
@@ -1876,7 +1930,7 @@ declare function validateRedirectUrl(url: string | null | undefined): string | n
1876
1930
  * that needs the resolved target should call {@link validateRedirectUrl} and
1877
1931
  * issue the redirect with its own framework (e.g. `Response.redirect`).
1878
1932
  */
1879
- declare function safeRedirect(url: string | null | undefined, fallbackUrl?: string): boolean;
1933
+ declare function safeRedirect(url: string | null | undefined, fallbackUrl?: string, options?: RedirectValidationOptions): boolean;
1880
1934
 
1881
1935
  /**
1882
1936
  * Auth intent preservation — saves and restores the URL the user was on
@@ -1884,7 +1938,8 @@ declare function safeRedirect(url: string | null | undefined, fallbackUrl?: stri
1884
1938
  */
1885
1939
  /**
1886
1940
  * Save the current URL as the post-auth redirect target.
1887
- * Validates the URL before storing — rejects unsafe URLs silently.
1941
+ * Validates the URL before storing — rejects unsafe URLs silently. Same-origin
1942
+ * only: the return URL is "where the user was", never another site.
1888
1943
  */
1889
1944
  declare function saveAuthIntent(returnUrl: string): void;
1890
1945
  /**
@@ -1916,7 +1971,34 @@ declare const PLAN_CURRENCY_OPTIONS: {
1916
1971
  value: "usd" | "eur" | "gbp" | "jpy" | "cad" | "aud" | "chf" | "cny" | "hkd" | "sgd" | "inr" | "mxn" | "brl" | "nzd" | "sek" | "nok" | "dkk" | "pln" | "thb";
1917
1972
  label: string;
1918
1973
  }[];
1919
- /** Format cents as money string (e.g. 1999, "usd" -> "$19.99"). Caller must pass currency (e.g. from plan or workspace). */
1974
+ /**
1975
+ * Minor-unit digits for a currency per ISO 4217: 0 (JPY, KRW, …), 2 (most),
1976
+ * or 3 (KWD, BHD, …). The zero- and three-decimal sets are pinned to Stripe's
1977
+ * treatment (the billing backend defines amount semantics); ISK is pinned to 2
1978
+ * (Stripe legacy — ISO 4217 says 0). Any other code defers to the runtime's
1979
+ * CLDR data (IQD/LYD → 3, CLF/UYW → 4, UYI → 0), falling back to 2 for codes
1980
+ * unknown to Intl or malformed.
1981
+ */
1982
+ declare function getCurrencyDecimals(currency: string | null | undefined): number;
1983
+ /** True when `currency` has no minor unit (JPY, KRW, …) — amounts are whole units, not cents. */
1984
+ declare function isZeroDecimalCurrency(currency: string | null | undefined): boolean;
1985
+ /**
1986
+ * Convert a minor-unit amount to its display number for `currency`:
1987
+ * `minorAmountToDisplay(1999, 'usd')` → `"19.99"`,
1988
+ * `minorAmountToDisplay(1000, 'jpy')` → `"1,000"` (zero-decimal — no division),
1989
+ * `minorAmountToDisplay(12345, 'kwd')` → `"12.345"` (three-decimal — ÷1000).
1990
+ */
1991
+ declare function minorAmountToDisplay(amount: number, currency: string): string;
1992
+ /**
1993
+ * Locale-aware currency formatting of a minor-unit amount via `Intl.NumberFormat`
1994
+ * (`(1999, 'usd', 'en-US')` → `"$19.99"`; `(1000, 'jpy', 'ja-JP')` → `"¥1,000"`;
1995
+ * `(12345, 'kwd')` → `"KWD 12.345"`). The divisor follows the currency's ISO 4217
1996
+ * minor-unit digits (see `getCurrencyDecimals`) — zero-decimal currencies are
1997
+ * never divided, three-decimal divide by 1000. Falls back to the symbol table
1998
+ * when the currency code is empty or malformed.
1999
+ */
2000
+ declare function formatMinorAmountIntl(amount: number, currency: string, locale?: string): string;
2001
+ /** Format cents as money string (e.g. 1999, "usd" -> "$19.99"; 1000, "jpy" -> "¥1,000"). Caller must pass currency (e.g. from plan or workspace). */
1920
2002
  declare function formatCents(cents: number, currency: string): string;
1921
2003
  /** Translatable labels for overage/quota formatting */
1922
2004
  interface OverageLabels {
@@ -1935,15 +2017,16 @@ interface OverageLabels {
1935
2017
  }
1936
2018
  /**
1937
2019
  * Format overage rate for display. When unitSize > 1: "$1.00/1,000 units"; else "$1.00/unit".
1938
- * Pass `labels` for i18n support.
2020
+ * Pass `labels` for i18n support and `locale` to group numbers in the display locale.
1939
2021
  */
1940
- declare function formatOverageRate(overageCents: number | undefined, unitSize: number | undefined, currency: string, labels?: Partial<OverageLabels>): string | null;
2022
+ declare function formatOverageRate(overageCents: number | undefined, unitSize: number | undefined, currency: string, labels?: Partial<OverageLabels>, locale?: string): string | null;
1941
2023
  /**
1942
2024
  * Format overage rate with optional unit label for comparison/preview UIs.
1943
2025
  * e.g. formatOverageRateWithLabel(50, 1000, "video", "usd") -> "$0.50/1,000 videos"
1944
2026
  * Pass `labels` for i18n support. Pass `pluralUnitLabel` to avoid English "s" pluralization.
2027
+ * Pass `locale` to group numbers in the display locale.
1945
2028
  */
1946
- declare function formatOverageRateWithLabel(overageCents: number | undefined, unitSize: number | undefined, unitLabel: string | undefined, currency: string, pluralUnitLabel?: string, labels?: Partial<OverageLabels>): string | null;
2029
+ declare function formatOverageRateWithLabel(overageCents: number | undefined, unitSize: number | undefined, unitLabel: string | undefined, currency: string, pluralUnitLabel?: string, labels?: Partial<OverageLabels>, locale?: string): string | null;
1947
2030
  /**
1948
2031
  * Get singular unit label from item name or slug (e.g. "Videos" -> "video", "reels" -> "reel").
1949
2032
  * Used for quota display in comparison and preview.
@@ -1952,9 +2035,10 @@ declare function formatOverageRateWithLabel(overageCents: number | undefined, un
1952
2035
  declare function getQuotaUnitLabelFromName(nameOrSlug: string, fallback?: string): string;
1953
2036
  /**
1954
2037
  * Format quota "included + overage" for display.
1955
- * Pass `labels` and `pluralUnitLabel` for i18n support.
2038
+ * Pass `labels` and `pluralUnitLabel` for i18n support, and `locale` to group
2039
+ * numbers in the display locale.
1956
2040
  */
1957
- declare function formatQuotaIncludedOverage(included: number | undefined, overageCents: number | undefined, unitLabel: string, currency: string, unitSize?: number, pluralUnitLabel?: string, labels?: Partial<OverageLabels>, allowOverage?: boolean): string;
2041
+ declare function formatQuotaIncludedOverage(included: number | undefined, overageCents: number | undefined, unitLabel: string, currency: string, unitSize?: number, pluralUnitLabel?: string, labels?: Partial<OverageLabels>, allowOverage?: boolean, locale?: string): string;
1958
2042
 
1959
2043
  type QuotaDisplayValue = {
1960
2044
  included: number;
@@ -1986,6 +2070,8 @@ interface QuotaLabels {
1986
2070
  included: string;
1987
2071
  /** e.g. "then" — separator between included and price */
1988
2072
  then: string;
2073
+ /** e.g. "hard limit" — shown when overage is not allowed */
2074
+ hardLimit?: string;
1989
2075
  }
1990
2076
  /**
1991
2077
  * Format a quota display value as "X included, then $Y.YY / unit".
@@ -2113,6 +2199,18 @@ declare function validateInvite(opts: {
2113
2199
  requireSubscription?: boolean;
2114
2200
  }): InviteValidation;
2115
2201
 
2202
+ /** Minimal workspace shape needed for ownership/role checks. Extended by `permissions.WorkspaceLike`. */
2203
+ interface WorkspaceLike$1 {
2204
+ _id: string;
2205
+ createdBy: string | {
2206
+ _id: string;
2207
+ } | null | undefined;
2208
+ users?: Array<string | {
2209
+ _id: string;
2210
+ role?: string;
2211
+ }>;
2212
+ }
2213
+
2116
2214
  /**
2117
2215
  * Role-based permission system.
2118
2216
  * Framework-agnostic — used by both React hooks and server-side BuildBase.
@@ -2130,6 +2228,7 @@ declare function validateInvite(opts: {
2130
2228
  * Both are resolved from the same role→permission map. Owner always gets all
2131
2229
  * platform permissions + any app permissions defined in the config.
2132
2230
  */
2231
+
2133
2232
  declare const Permission: {
2134
2233
  readonly WORKSPACE_SETTINGS_VIEW: "workspace:settings:view";
2135
2234
  readonly WORKSPACE_SETTINGS_EDIT: "workspace:settings:edit";
@@ -2147,15 +2246,7 @@ declare const Permission: {
2147
2246
  type PermissionKey = (typeof Permission)[keyof typeof Permission];
2148
2247
  type RolePermissionMap = Record<string, string[]>;
2149
2248
  declare const DEFAULT_ROLE_PERMISSIONS: RolePermissionMap;
2150
- interface WorkspaceLike {
2151
- _id: string;
2152
- createdBy: string | {
2153
- _id: string;
2154
- } | null | undefined;
2155
- users?: Array<string | {
2156
- _id: string;
2157
- role?: string;
2158
- }>;
2249
+ interface WorkspaceLike extends WorkspaceLike$1 {
2159
2250
  permissions?: Record<string, string[]>;
2160
2251
  }
2161
2252
  interface SettingsLike {
@@ -2212,7 +2303,7 @@ declare function hasPermission(permission: string | string[], ctx: PermissionCon
2212
2303
  *
2213
2304
  * Or manually create `public/push-sw.js` with this content.
2214
2305
  */
2215
- declare const PUSH_SERVICE_WORKER_SCRIPT = "\n// BuildBase Push Notification Service Worker\n// Place this file in your app's public directory (e.g. public/push-sw.js)\n\nself.addEventListener('push', function(event) {\n if (!event.data) return;\n\n try {\n const payload = event.data.json();\n const title = payload.title || 'Notification';\n const options = {\n body: payload.body || '',\n icon: payload.icon || undefined,\n badge: payload.icon || undefined,\n data: { url: payload.url, ...(payload.data || {}) },\n tag: 'buildbase-push-' + Date.now(),\n };\n\n event.waitUntil(\n self.registration.showNotification(title, options)\n );\n } catch (e) {\n console.error('[PushSW] Failed to show notification:', e);\n }\n});\n\nself.addEventListener('notificationclick', function(event) {\n event.notification.close();\n\n const url = event.notification.data && event.notification.data.url;\n if (url) {\n event.waitUntil(\n clients.matchAll({ type: 'window', includeUncontrolled: true }).then(function(clientList) {\n for (let i = 0; i < clientList.length; i++) {\n const client = clientList[i];\n if (client.url === url && 'focus' in client) {\n return client.focus();\n }\n }\n if (clients.openWindow) {\n return clients.openWindow(url);\n }\n })\n );\n }\n});\n";
2306
+ declare const PUSH_SERVICE_WORKER_SCRIPT = "\n// BuildBase Push Notification Service Worker\n// Place this file in your app's public directory (e.g. public/push-sw.js)\n\nself.addEventListener('push', function(event) {\n if (!event.data) return;\n\n try {\n const payload = event.data.json();\n // i18n exception: service workers run outside the SDK's translation\n // provider, so this last-resort fallback stays English. The server should\n // always send a localized payload.title.\n const title = payload.title || 'Notification';\n const options = {\n body: payload.body || '',\n icon: payload.icon || undefined,\n badge: payload.icon || undefined,\n data: { url: payload.url, ...(payload.data || {}) },\n tag: 'buildbase-push-' + Date.now(),\n };\n\n event.waitUntil(\n self.registration.showNotification(title, options)\n );\n } catch (e) {\n console.error('[PushSW] Failed to show notification:', e);\n }\n});\n\nself.addEventListener('notificationclick', function(event) {\n event.notification.close();\n\n const url = event.notification.data && event.notification.data.url;\n if (url) {\n event.waitUntil(\n clients.matchAll({ type: 'window', includeUncontrolled: true }).then(function(clientList) {\n for (let i = 0; i < clientList.length; i++) {\n const client = clientList[i];\n if (client.url === url && 'focus' in client) {\n return client.focus();\n }\n }\n if (clients.openWindow) {\n return clients.openWindow(url);\n }\n })\n );\n }\n});\n";
2216
2307
 
2217
2308
  interface BetaFormData {
2218
2309
  name?: string;
@@ -2235,6 +2326,24 @@ interface SDKMessages {
2235
2326
  connectedAgentsEmpty: string;
2236
2327
  connectedAgentsAccess: string;
2237
2328
  connectedAgentsGranted: string;
2329
+ connectedAgentsLoadFailed: string;
2330
+ connectedAgentsRevokeFailed: string;
2331
+ mcpConnectAction: string;
2332
+ mcpGuideTitle: string;
2333
+ mcpGuideDescription: string;
2334
+ mcpServerUrlLabel: string;
2335
+ mcpServerUrlHint: string;
2336
+ mcpPromptLabel: string;
2337
+ mcpPromptHint: string;
2338
+ mcpPromptTemplate: string;
2339
+ mcpClientsLabel: string;
2340
+ mcpAddToConfigFile: string;
2341
+ mcpClientChatgptInstructions: string;
2342
+ mcpClientClaudeInstructions: string;
2343
+ mcpClientClineInstructions: string;
2344
+ mcpCopy: string;
2345
+ mcpCopied: string;
2346
+ mcpLearnMore: string;
2238
2347
  inactive: string;
2239
2348
  inactiveHint: string;
2240
2349
  passkeysTitle: string;
@@ -2298,6 +2407,7 @@ interface SDKMessages {
2298
2407
  billingManageOnly: string;
2299
2408
  openSettings: string;
2300
2409
  back: string;
2410
+ close: string;
2301
2411
  };
2302
2412
  };
2303
2413
  subscription: {
@@ -2584,6 +2694,7 @@ interface SDKMessages {
2584
2694
  featureSuccess: string;
2585
2695
  updateSuccess: string;
2586
2696
  actionStatus: string;
2697
+ fallbackName: string;
2587
2698
  };
2588
2699
  danger: {
2589
2700
  title: string;
@@ -2804,6 +2915,7 @@ interface SDKMessages {
2804
2915
  purchaseFailed: string;
2805
2916
  errorLoading: string;
2806
2917
  insufficientCredits: string;
2918
+ insufficientDetail: string;
2807
2919
  };
2808
2920
  loading: {
2809
2921
  restoringSession: string;
@@ -2839,6 +2951,7 @@ interface SDKMessages {
2839
2951
  fetchCreditPackages: string;
2840
2952
  fetchCreditTransactions: string;
2841
2953
  fetchExpiringCredits: string;
2954
+ fetchWorkspaces: string;
2842
2955
  };
2843
2956
  }
2844
2957
  /**
@@ -2957,17 +3070,17 @@ declare function parseWebhookEvent(options: {
2957
3070
  *
2958
3071
  * Makes a consuming app "agent ready" (see https://isitagentready.com) by
2959
3072
  * serving the standard machine-readable discovery documents an AI agent looks
2960
- * for — with the BuildBase server as the source of truth.
2961
- *
2962
- * The heavy lifting already lives on the platform: an org admin configures
2963
- * agent readiness once (protected resources, scopes, llms.txt) and the server
2964
- * publishes the OAuth2 authorization-server metadata (RFC 8414) and the
2965
- * per-resource protected-resource metadata (RFC 9728). This module lets an app
2966
- * re-serve those documents from its own origin — where agents actually look —
2967
- * plus generate the static discovery documents (Agent Card, Agent Skills,
2968
- * security.txt) from local config. The result: an org admin adds full agent
2969
- * support to their app in a couple of lines, and never hand-writes a
2970
- * `.well-known` route.
3073
+ * for.
3074
+ *
3075
+ * Ownership is split: the platform owns AUTH — it publishes the OAuth2
3076
+ * authorization-server metadata (RFC 8414) and this module re-serves it from
3077
+ * the app's origin, where agents actually look. Everything else (protected
3078
+ * resources and their scopes, RFC 9728 metadata, llms.txt, sitemap, Agent
3079
+ * Card, Agent Skills, security.txt) is CONTENT the app owns — declared locally
3080
+ * in {@link AgentReadyConfig} and generated here; the shared authorization
3081
+ * server stays scope- and resource-agnostic. The result: an org admin adds
3082
+ * full agent support to their app in a couple of lines, and never hand-writes
3083
+ * a `.well-known` route.
2971
3084
  *
2972
3085
  * Zero React and no framework types — every function returns plain data. The
2973
3086
  * only runtime dependency is `fetch`; SHA-256 (for Agent Skills digests) is a
@@ -2983,8 +3096,8 @@ declare function parseWebhookEvent(options: {
2983
3096
  * export const agentConfig: AgentReadyConfig = {
2984
3097
  * serverUrl: process.env.BUILDBASE_URL!,
2985
3098
  * orgId: process.env.BUILDBASE_ORG_ID!,
2986
- * siteUrl: "https://imejis.io",
2987
- * site: { name: "Imejis", description: "Generate images from templates via API." },
3099
+ * siteUrl: "https://example.com",
3100
+ * site: { name: "Acme", description: "Generate images from templates via API." },
2988
3101
  * robots: { contentSignals: { search: true, aiInput: true, aiTrain: false } },
2989
3102
  * };
2990
3103
  * export async function serveAgentPath(req: Request): Promise<Response> {
@@ -3027,7 +3140,7 @@ interface AgentReadinessBundle {
3027
3140
  }
3028
3141
  /** An Agent Skill (Agent Skills Discovery RFC v0.2.0) published by this app. */
3029
3142
  interface AgentSkill {
3030
- /** Stable slug, e.g. `imejis-api`. */
3143
+ /** Stable slug, e.g. `acme-api`. */
3031
3144
  name: string;
3032
3145
  /** One-line human/agent-readable summary. */
3033
3146
  description: string;
@@ -3043,7 +3156,7 @@ interface AgentSkill {
3043
3156
  }
3044
3157
  /** One API described in an API Catalog (RFC 9727 / RFC 9264 linkset). */
3045
3158
  interface ApiCatalogApi {
3046
- /** Anchor URL identifying the API, e.g. `https://api.imejis.io`. */
3159
+ /** Anchor URL identifying the API, e.g. `https://api.example.com`. */
3047
3160
  anchor: string;
3048
3161
  /** OpenAPI / machine-readable description URL (link rel `service-desc`). */
3049
3162
  serviceDesc?: string;
@@ -3054,7 +3167,7 @@ interface ApiCatalogApi {
3054
3167
  /** Optional human title for the API. */
3055
3168
  title?: string;
3056
3169
  }
3057
- /** MCP Server Card (SEP-1649 / SEP-2127), advertising a live MCP server. */
3170
+ /** MCP Server Card (SEP-1649 v1.0), advertising a live MCP server. */
3058
3171
  interface McpServerCard {
3059
3172
  /** Server name. */
3060
3173
  name: string;
@@ -3064,13 +3177,50 @@ interface McpServerCard {
3064
3177
  endpoint: string;
3065
3178
  /** Transport type. Defaults to `"streamable-http"`. */
3066
3179
  transport?: string;
3067
- /** Capabilities object, e.g. `{ tools: {}, resources: {} }`. */
3180
+ /** MCP protocol version the server speaks. Defaults to `"2025-11-25"`. */
3181
+ protocolVersion?: string;
3182
+ /**
3183
+ * Capability flags. Booleans per SEP-1649 v1.0; a legacy object value
3184
+ * (e.g. `{ tools: {} }`) is normalized to booleans by presence.
3185
+ */
3068
3186
  capabilities?: Record<string, unknown>;
3069
3187
  /** Optional human description. */
3070
3188
  description?: string;
3071
3189
  /** Documentation URL. */
3072
3190
  documentationUrl?: string;
3073
3191
  }
3192
+ /** One OAuth scope an app declares in its scope catalog. */
3193
+ interface AppScope {
3194
+ /** Scope name, e.g. `designs:read`. */
3195
+ name: string;
3196
+ /** Human-readable description, shown on the consent screen. */
3197
+ description: string;
3198
+ }
3199
+ /** One skill advertised on the A2A Agent Card. */
3200
+ interface A2ACardSkill {
3201
+ id: string;
3202
+ name: string;
3203
+ description: string;
3204
+ tags?: string[];
3205
+ }
3206
+ /**
3207
+ * Overrides for the A2A Agent Card (`/.well-known/agent-card.json`). Every
3208
+ * field is optional — the card is fully derived from `site` + `skills` by
3209
+ * default. See {@link buildA2AAgentCard}.
3210
+ */
3211
+ interface A2ACardConfig {
3212
+ name?: string;
3213
+ version?: string;
3214
+ description?: string;
3215
+ /** The endpoint agents connect to. Defaults to `siteUrl`. */
3216
+ serviceUrl?: string;
3217
+ /** Transport protocol advertised for `serviceUrl`. Defaults to `'http'`. */
3218
+ transportProtocol?: string;
3219
+ /** A2A capability flags. Defaults to `{ streaming: false, pushNotifications: false }`. */
3220
+ capabilities?: Record<string, unknown>;
3221
+ /** Skills; defaults to a mapping of `config.skills` (or a generic site skill). */
3222
+ skills?: A2ACardSkill[];
3223
+ }
3074
3224
  /** One robots.txt policy group (a `User-agent:` block). */
3075
3225
  interface RobotsPolicy {
3076
3226
  /** User-agent(s) this group applies to, e.g. `'*'` or `'GPTBot'`. */
@@ -3131,7 +3281,7 @@ interface AgentReadyConfig {
3131
3281
  /** The org id (24-hex) whose agent-readiness config to serve. */
3132
3282
  orgId: string;
3133
3283
  /**
3134
- * This app's public origin, e.g. `https://imejis.io`. Used to build absolute
3284
+ * This app's public origin, e.g. `https://example.com`. Used to build absolute
3135
3285
  * URLs in the Agent Card and to match RFC 9728 resource paths.
3136
3286
  */
3137
3287
  siteUrl: string;
@@ -3151,6 +3301,15 @@ interface AgentReadyConfig {
3151
3301
  };
3152
3302
  /** Agent Skills to publish. Omit to skip the Agent Skills documents. */
3153
3303
  skills?: AgentSkill[];
3304
+ /**
3305
+ * The app's OAuth scope catalog — the source of truth for `scopes_supported`
3306
+ * in this app's RFC 9728 protected-resource metadata (served from your own
3307
+ * origin). Declare real, per-app scopes here (`designs:read`,
3308
+ * `render:execute`, …) instead of placeholders. A `protectedResources` entry
3309
+ * without its own `scopes` list inherits every catalog scope name. Scopes are
3310
+ * app-owned: the shared BuildBase authorization server stays scope-agnostic.
3311
+ */
3312
+ scopes?: AppScope[];
3154
3313
  /** security.txt fields (RFC 9116). Omit to skip serving security.txt. */
3155
3314
  security?: {
3156
3315
  /** Contact URI(s) — email (`mailto:`) or URL. */
@@ -3181,6 +3340,41 @@ interface AgentReadyConfig {
3181
3340
  * from the platform bundle — use when the app owns richer llms.txt content.
3182
3341
  */
3183
3342
  llmsTxt?: string;
3343
+ /**
3344
+ * Local `/llms-full.txt` content (llmstxt.org expanded document). Omit to
3345
+ * skip serving it (or serve your own static file, which then wins).
3346
+ */
3347
+ llmsFullTxt?: string;
3348
+ /**
3349
+ * A2A Agent Card served at `/.well-known/agent-card.json`. Served by
3350
+ * DEFAULT, derived from `site` + `skills`, so readiness scanners find a
3351
+ * valid card with zero config. Pass `false` to disable, or an object to
3352
+ * override any derived field.
3353
+ */
3354
+ a2aCard?: false | A2ACardConfig;
3355
+ /**
3356
+ * Web Bot Auth key directory (IETF WebBotAuth) served at
3357
+ * `/.well-known/http-message-signatures-directory`. Only for apps whose own
3358
+ * outbound bot/agent signs its requests — publish the JWKS public keys here
3359
+ * so receiving sites can verify the signatures. Omitted = not served.
3360
+ */
3361
+ webBotAuth?: {
3362
+ keys: Array<Record<string, unknown>>;
3363
+ };
3364
+ /**
3365
+ * Extra literal documents served by {@link resolveAgentPath}, keyed by exact
3366
+ * request path. The escape hatch for anything the SDK has no builder for —
3367
+ * commerce discovery (x402, UCP, ACP, MPP), `/openapi.json`, future
3368
+ * `.well-known` documents. A string value infers its content type from the
3369
+ * path extension. Extra paths take precedence over built-in documents, so
3370
+ * they can also override any SDK-generated document.
3371
+ */
3372
+ extraPaths?: Record<string, string | {
3373
+ body: string;
3374
+ contentType?: string;
3375
+ status?: number;
3376
+ cacheControl?: string;
3377
+ }>;
3184
3378
  /** robots.txt generation (`buildRobotsTxt`). Omitted = sane defaults. */
3185
3379
  robots?: RobotsConfig;
3186
3380
  /**
@@ -3258,11 +3452,12 @@ declare function buildAgentCard(config: AgentReadyConfig, bundle: AgentReadiness
3258
3452
  * Resolve the RFC 9728 protected-resource metadata for a request path, or null
3259
3453
  * if no configured resource maps to it.
3260
3454
  *
3261
- * App-owned and local: built entirely from `config.protectedResources`, with
3262
- * `authorization_servers` derived from `serverUrl`/`orgId` (the BuildBase
3263
- * issuer). No platform round-trip.
3455
+ * App-owned. `authorization_servers` uses the platform bundle's real
3456
+ * `authorizationServer.issuer` when provided (so this doc can't advertise a
3457
+ * different issuer than the AS metadata / agent card / auth.md), falling back
3458
+ * to the `serverUrl`/`orgId` heuristic when the bundle isn't available.
3264
3459
  */
3265
- declare function buildProtectedResourceMetadata(requestPath: string, config: AgentReadyConfig): DiscoveryDocument | null;
3460
+ declare function buildProtectedResourceMetadata(requestPath: string, config: AgentReadyConfig, authServerIssuer?: string): DiscoveryDocument | null;
3266
3461
  /** Agent Skills discovery index (Agent Skills Discovery RFC v0.2.0). */
3267
3462
  declare function buildAgentSkillsIndex(config: AgentReadyConfig): DiscoveryDocument | null;
3268
3463
  /** Serve a single skill's SKILL.md by request path, or null if none matches. */
@@ -3275,16 +3470,68 @@ declare function buildSecurityTxt(config: AgentReadyConfig): DiscoveryDocument |
3275
3470
  * not platform-managed.
3276
3471
  */
3277
3472
  declare function buildLlmsTxt(config: AgentReadyConfig): DiscoveryDocument | null;
3473
+ /**
3474
+ * The `/llms-full.txt` document from `config.llmsFullTxt` (app-authored).
3475
+ * Returns null when not set — serve your own static file instead.
3476
+ */
3477
+ declare function buildLlmsFullTxt(config: AgentReadyConfig): DiscoveryDocument | null;
3478
+ /**
3479
+ * A2A Agent Card (https://a2a-protocol.org) for `/.well-known/agent-card.json`.
3480
+ * Served by default, fully derived from `site` + `skills`, so a consumer is
3481
+ * A2A-discoverable with zero config; `config.a2aCard` overrides any field or
3482
+ * disables the card entirely (`false`). Skills fall back to a generic
3483
+ * site-content skill when none are configured — the card must carry at least
3484
+ * one skill to validate.
3485
+ */
3486
+ declare function buildA2AAgentCard(config: AgentReadyConfig): DiscoveryDocument | null;
3487
+ /**
3488
+ * Web Bot Auth key directory (JWKS) for
3489
+ * `/.well-known/http-message-signatures-directory`. Returns null unless
3490
+ * `config.webBotAuth.keys` is set — signing keys are the app's own and can't
3491
+ * be derived.
3492
+ */
3493
+ declare function buildWebBotAuthDirectory(config: AgentReadyConfig): DiscoveryDocument | null;
3494
+ /** One DNS record the org should publish for DNS-AID agent discovery. */
3495
+ interface DnsAidRecord {
3496
+ /** Fully-qualified record name, e.g. `_a2a._agents.example.com`. */
3497
+ name: string;
3498
+ /** Record type — HTTPS for HTTPS endpoints, SVCB otherwise. */
3499
+ type: 'HTTPS' | 'SVCB';
3500
+ ttl: number;
3501
+ /** Record data, e.g. `1 example.com. alpn="h2" port=443`. */
3502
+ data: string;
3503
+ }
3504
+ /**
3505
+ * DNS-AID (DNS for AI Discovery) records this app should publish under its
3506
+ * domain's `_agents` namespace. DNS records can't be served over HTTP — hand
3507
+ * these to the org's DNS provider (and DNSSEC-sign the zone). Derived from the
3508
+ * same config as the HTTP discovery surface, so the two never disagree.
3509
+ */
3510
+ declare function buildDnsAidRecords(config: AgentReadyConfig): DnsAidRecord[];
3278
3511
  /**
3279
3512
  * API Catalog (RFC 9727) as a `linkset+json` document for
3280
3513
  * `/.well-known/api-catalog`. Returns null when no APIs are configured.
3281
3514
  */
3282
3515
  declare function buildApiCatalog(config: AgentReadyConfig): DiscoveryDocument | null;
3283
3516
  /**
3284
- * MCP Server Card (SEP-1649) for `/.well-known/mcp/server-card.json`. Returns
3285
- * null when no card is configured (i.e. no MCP server is running).
3517
+ * MCP Server Card (SEP-1649 v1.0) for `/.well-known/mcp/server-card.json`.
3518
+ * Returns null when no card is configured (i.e. no MCP server is running).
3286
3519
  */
3287
3520
  declare function buildMcpServerCard(config: AgentReadyConfig): DiscoveryDocument | null;
3521
+ /**
3522
+ * MCP discovery manifest (SEP-1960) for `/.well-known/mcp.json` — the
3523
+ * origin-level index of every MCP server this app exposes. Complements the
3524
+ * per-server card (SEP-1649): scanners and agents probe this path first, then
3525
+ * follow `server_card` for detail. Returns null when no MCP server is
3526
+ * configured.
3527
+ *
3528
+ * The transport endpoint may live on a different origin than the app serving
3529
+ * this manifest (e.g. card on `www.`, server on `api.`); the `authentication`
3530
+ * pointer is derived from the ENDPOINT's origin per RFC 9728 path derivation,
3531
+ * so agents land on the metadata the server's own WWW-Authenticate challenge
3532
+ * advertises.
3533
+ */
3534
+ declare function buildMcpDiscoveryManifest(config: AgentReadyConfig): DiscoveryDocument | null;
3288
3535
  /**
3289
3536
  * The `/auth.md` document (agent registration + authentication instructions).
3290
3537
  * Uses `config.authMd` verbatim when provided; otherwise generates one from the
@@ -3348,14 +3595,20 @@ declare function resolveWellKnown(requestPath: string, config: AgentReadyConfig)
3348
3595
  * agent-readiness surface. Returns null for paths this app doesn't serve.
3349
3596
  */
3350
3597
  declare function resolveAgentPath(requestPath: string, config: AgentReadyConfig): Promise<DiscoveryDocument | null>;
3351
- /** A WebMCP tool definition exposed to in-page agents via `navigator.modelContext`. */
3352
- interface WebMcpTool {
3598
+ /**
3599
+ * A WebMCP tool definition exposed to in-page agents via `navigator.modelContext`.
3600
+ * `TInput` is the shape your `inputSchema` describes — type your `execute`
3601
+ * parameter inline (`execute: (input: { path: string }) => …`) or pin it with
3602
+ * `WebMcpTool<{ path: string }>`. The default is deliberately loose: the input
3603
+ * arrives from the agent unvalidated, so treat it as untrusted regardless.
3604
+ */
3605
+ interface WebMcpTool<TInput = any> {
3353
3606
  name: string;
3354
3607
  description: string;
3355
3608
  /** JSON Schema for the tool's input. */
3356
3609
  inputSchema: Record<string, unknown>;
3357
3610
  /** Called when an agent invokes the tool. */
3358
- execute: (input: any) => unknown | Promise<unknown>;
3611
+ execute: (input: TInput) => unknown | Promise<unknown>;
3359
3612
  }
3360
3613
  /**
3361
3614
  * Register WebMCP tools with the browser so in-page AI agents can invoke your
@@ -3450,6 +3703,24 @@ interface AppRevokeRequestClaims {
3450
3703
  reason: string;
3451
3704
  [claim: string]: unknown;
3452
3705
  }
3706
+ /**
3707
+ * A verified JWT payload: registered claims (RFC 7519) are typed AND
3708
+ * runtime-validated by {@link verifyClientJwt} (a signed token whose `sub` is
3709
+ * a number is rejected, so the types here are real guarantees). Every other
3710
+ * claim is `unknown` — custom claims are attacker-influenced input until you
3711
+ * narrow them (`typeof payload.sid === 'string'`), even after the signature
3712
+ * checks out.
3713
+ */
3714
+ interface VerifiedJwtPayload {
3715
+ iss?: string;
3716
+ sub?: string;
3717
+ aud?: string | string[];
3718
+ exp?: number;
3719
+ nbf?: number;
3720
+ iat?: number;
3721
+ jti?: string;
3722
+ [claim: string]: unknown;
3723
+ }
3453
3724
  /** Options for {@link verifyClientJwt} (all optional; secure defaults). */
3454
3725
  interface VerifyClientJwtOptions {
3455
3726
  /** Allowed clock skew in seconds for `exp`/`nbf`. Default 60. */
@@ -3470,11 +3741,8 @@ interface VerifyClientJwtOptions {
3470
3741
  * its payload. Checks the signature (timing-safe), the algorithm, `exp`/`nbf`,
3471
3742
  * and — by default — that an `exp` is present at all. Optionally pins `iss`/`aud`.
3472
3743
  * Throws {@link AppBridgeError} on any failure.
3473
- *
3474
- * The third argument accepts either the legacy `clockToleranceSec` number or a
3475
- * {@link VerifyClientJwtOptions} object.
3476
3744
  */
3477
- declare function verifyClientJwt(token: string, clientSecret: string, optionsOrTolerance?: number | VerifyClientJwtOptions): Record<string, any>;
3745
+ declare function verifyClientJwt(token: string, clientSecret: string, options?: VerifyClientJwtOptions): VerifiedJwtPayload;
3478
3746
  /** Extract the token from an `Authorization: Bearer <token>` header. */
3479
3747
  declare function extractBearerToken(authorization: string | null | undefined): string | null;
3480
3748
  /**
@@ -3855,5 +4123,205 @@ interface BuildBaseResult extends ScopedActions {
3855
4123
  }
3856
4124
  declare function BuildBase(config: BuildBaseConfig): BuildBaseResult;
3857
4125
 
3858
- export { AI_BOT_USER_AGENTS, ApiVersion, AppBridgeError, AuthApi, AuthStatus, BBAction, BBScreen, BBStatus, BB_PARAM, BaseApi, BetaForm, BillingIntervals, BuildBase, CURRENCY_DISPLAY, CURRENCY_FLAG, CreditBucketSource, CreditBucketStatus, CreditTransactionType, DEFAULT_ROLE_PERMISSIONS, DunningState, EventEmitter, InvoiceStatuses, PLAN_CURRENCY_CODES, PLAN_CURRENCY_OPTIONS, PUSH_SERVICE_WORKER_SCRIPT, Permission, PushApi, SDKEvent, SettingsApi, SubscriptionItemType, SubscriptionStatus, UserApi, WorkspaceApi, appTokenFailure, appTokenSuccess, bearerChallenge, buildAgentCard, buildAgentSkillsIndex, buildApiCatalog, buildAuthMd, buildDiscoveryLinkHeader, buildLlmsTxt, buildMcpServerCard, buildProtectedResourceMetadata, buildRobotsTxt, buildSecurityTxt, buildSitemap, buildSkillMd, calculateBillableSeats, calculateSeatOverageCents, calculateTotalSubscriptionCents, cleanBBParams, clearAgentReadinessCache, clearAuthIntent, consumeAuthIntent, createBBUrl, createCheckoutRedirectUrls, createCreditPurchaseRedirectUrls, BuildBase as default, eventEmitter, extractBearerToken, fetchAgentReadiness, formatCents, formatOverageRate, formatOverageRateWithLabel, formatQuotaIncludedOverage, formatQuotaWithPrice, getAvailableCurrenciesFromPlans, getBasePriceCents, getBillingIntervalAndCurrencyFromPriceId, getCurrencyFlag, getCurrencySymbol, getDisplayCurrency, getPerSeatPriceCents, getPricingVariant, getQuotaDisplayValue, getQuotaDisplayWithVariant, getQuotaOverageCents, getQuotaUnitLabelFromName, getSeatPricing, getStripePriceIdForInterval, handleAppRevokeRequest, handleAppTokenRequest, hasPermission, invalidateCreditBalance, invalidateQuotaUsage, invalidateSubscription, negotiateMarkdown, parseWebhookEvent, provideWebMcpTools, readBBParams, resolveAgentPath, resolveMaxUsers, resolvePermissions, resolveWellKnown, safeRedirect, saveAuthIntent, sha256Digest, signClientJwt, validateInvite, validateRedirectUrl, verifyAppRevokeRequest, verifyAppTokenRequest, verifyClientJwt, verifyWebhookSignature, wantsMarkdown };
3859
- export type { AgentReadinessBundle, AgentReadyConfig, AgentSkill, ApiCatalogApi, AppRevokeRequestClaims, AppTokenRequestClaims, AppTokenResponseBody, AppTokenResult, BBActionType, BBScreenType, BBStatusType, BetaFormData, BetaFormResponse, BillingInterval, BuildBaseConfig, BuildBaseResult, BuildBaseSession, CheckoutResult, ContentSignals, CreditActions, CreditBucketSourceType, CreditBucketStatusType, CreditTransactionTypeValue, DiscoveryDocument, DunningStateType, EventData, EventType, FeatureActions, FormatQuotaWithPriceOptions, GetCheckoutStripeParams, HandlerResult, IAllQuotaUsageResponse, IBaseApiConfig, IBasePricing, IBetaConfig, ICheckoutSessionRequest, ICheckoutSessionResponse, ICheckoutStripeOptions, IConsumeCreditsRequest, IConsumeCreditsResponse, ICreditBalance, ICreditBucket, ICreditBucketsQuery, ICreditBucketsResponse, ICreditPackage, ICreditPackagePricingVariant, ICreditPurchaseRequest, ICreditPurchaseResponse, ICreditTransaction, ICreditTransactionsQuery, ICreditTransactionsResponse, IEventCallbacks, IExpiringCreditsResponse, IInvoice, IInvoiceListResponse, IInvoiceResponse, IOsConfig, IOsState, IPlan, IPlanGroup, IPlanGroupInfo, IPlanGroupLatestVersion, IPlanGroupResponse, IPlanGroupVersion, IPlanGroupVersionWithPlans, IPlanGroupVersionsResponse, IPlanVersion, IPlanVersionSummary, IPlanVersionWithPlan, IPricingVariant, IPublicCreditPackage, IPublicCreditPackagesResponse, IPublicPlanItem, IPublicPlanItemCategory, IPublicPlanVersion, IPublicPlansResponse, IQuotaByInterval, IQuotaIntervalValue, IQuotaOveragePriceIdsByInterval, IQuotaOveragesByInterval, IQuotaUsageStatus, IQuotaUsageStatusResponse, IRecordUsageRequest, IRecordUsageResponse, ISettings, IStripePricesByInterval, ISubscription, ISubscriptionItem, ISubscriptionResponse, ISubscriptionUpdateRequest, ISubscriptionUpdateResponse, IUsageLogEntry, IUsageLogsQuery, IUsageLogsResponse, IUser, IWorkspace, InviteBlockReason, InviteValidation, InvoiceActions, InvoiceStatus, InvoiceStatusType, MaxUsersConfig, McpServerCard, NotificationData, NotificationEvent, NotificationResult, OnWorkspaceChangeParams, PermissionActions, PermissionContext, PermissionKey, PlanActions, PlanVersionWithPricingVariants, QuotaDisplayValue, QuotaDisplayWithOverage, RobotsConfig, RobotsPolicy, RolePermissionMap, ScopedActions, SettingsActions, SitemapUrl, SubscriptionActions, SubscriptionItemTypeValue, SubscriptionStatusType, TranslationKey, UsageActions, UserActions, UserCreatedEventData, UserUpdatedEventData, WebMcpTool, WorkspaceActions, WorkspaceChangedEventData, WorkspaceCreatedEventData, WorkspaceDeletedEventData, WorkspaceUpdatedEventData, WorkspaceUserAddedEventData, WorkspaceUserRemovedEventData, WorkspaceUserRoleChangedEventData };
4126
+ /**
4127
+ * MCP server toolkit (server-side, framework-agnostic).
4128
+ *
4129
+ * Turns a consuming app into a live MCP (Model Context Protocol) server so AI
4130
+ * agents can operate its BuildBase capabilities — workspaces, subscriptions,
4131
+ * quotas, credits, feature flags, permissions — plus any custom tools the app
4132
+ * defines. The transport is stateless Streamable HTTP: a single JSON-RPC
4133
+ * message per POST, no sessions and no SSE, which keeps the handler pure and
4134
+ * identical on Node 18+, edge, Deno, and Bun.
4135
+ *
4136
+ * Zero framework types: the core `handle()` takes a plain
4137
+ * `{ method, headers, body }` and returns `{ status, headers, body }` (wire it
4138
+ * into Express/Fastify/Hono yourself), while `fetch()` adapts Web-standard
4139
+ * `Request` → `Response` for Next.js App Router and edge runtimes.
4140
+ *
4141
+ * Agents authenticate with the Bearer tokens the app mints via the OAuth2
4142
+ * app-bridge (`handleAppTokenRequest` + `signClientJwt`); the `auth.verify`
4143
+ * callback maps a verified token to the BuildBase session the tools run under.
4144
+ *
4145
+ * @example Next.js App Router — the entire integration:
4146
+ * ```ts
4147
+ * // lib/mcp.ts
4148
+ * import BuildBase from '@buildbase/sdk';
4149
+ * import { createMcpHandler, verifyClientJwt } from '@buildbase/sdk/mcp';
4150
+ *
4151
+ * const buildbase = BuildBase({
4152
+ * serverUrl: process.env.BUILDBASE_URL!,
4153
+ * orgId: process.env.BUILDBASE_ORG_ID!,
4154
+ * });
4155
+ *
4156
+ * export const mcp = createMcpHandler({
4157
+ * buildbase,
4158
+ * serverInfo: { name: 'acme', version: '1.0.0' },
4159
+ * auth: {
4160
+ * verify: (token) => {
4161
+ * const c = verifyClientJwt(token, process.env.BUILDBASE_CLIENT_SECRET!);
4162
+ * // Claims beyond RFC 7519 are `unknown` — narrow before use.
4163
+ * return {
4164
+ * sessionId: typeof c.sid === 'string' ? c.sid : '',
4165
+ * userId: c.sub,
4166
+ * scopes: Array.isArray(c.scope)
4167
+ * ? c.scope.filter((s): s is string => typeof s === 'string')
4168
+ * : undefined,
4169
+ * };
4170
+ * },
4171
+ * resourceMetadataUrl: 'https://example.com/.well-known/oauth-protected-resource',
4172
+ * },
4173
+ * });
4174
+ *
4175
+ * // app/api/mcp/route.ts
4176
+ * import { mcp } from '@/lib/mcp';
4177
+ * export const POST = (req: Request) => mcp.fetch(req);
4178
+ * export const GET = (req: Request) => mcp.fetch(req); // 405 per spec (no SSE)
4179
+ * export const DELETE = (req: Request) => mcp.fetch(req); // 405 (stateless)
4180
+ * ```
4181
+ */
4182
+
4183
+ /** A transport-agnostic HTTP request (mirror of the DiscoveryDocument idea). */
4184
+ interface McpHttpRequest {
4185
+ /** HTTP method, e.g. `'POST'`. */
4186
+ method: string;
4187
+ /** Header map. Keys are matched case-insensitively. */
4188
+ headers: Record<string, string | undefined>;
4189
+ /** Raw JSON body string, or an already-parsed value (e.g. Express req.body). */
4190
+ body?: string | unknown;
4191
+ }
4192
+ /** The identity a verified Bearer token resolves to. */
4193
+ interface McpAuthInfo {
4194
+ /** BuildBase session all tool calls run under (`buildbase.withSession(...)`). */
4195
+ sessionId: string;
4196
+ /** The acting BuildBase user id — default subject for permission checks. */
4197
+ userId?: string;
4198
+ /** Pin tools to one workspace; used when the agent omits `workspaceId`. */
4199
+ workspaceId?: string;
4200
+ /** OAuth scopes granted to the agent; filters tools with `requiredScopes`. */
4201
+ scopes?: string[];
4202
+ /** Raw verified claims, passed through to tool context. */
4203
+ claims?: Record<string, unknown>;
4204
+ }
4205
+
4206
+ /**
4207
+ * BuildBase agent-auth presets (server-side, framework-agnostic).
4208
+ *
4209
+ * The BuildBase security model: the platform runs the OAuth2 flow (login,
4210
+ * consent, PKCE, refresh) but the APP mints and verifies its own user tokens,
4211
+ * signed with the app's own secret. The platform only relays the minted token
4212
+ * to the agent — it never sees the secret, so it can neither forge nor decode
4213
+ * an app token. The per-user BuildBase session travels inside the token only
4214
+ * as an AES-256-GCM-encrypted `sid` claim, so it is never stored and never
4215
+ * plaintext anywhere; access to it expires with the token.
4216
+ *
4217
+ * These presets make that model a one-liner on each side of the flow, and run
4218
+ * entirely in the app's process — pure local crypto, zero platform calls:
4219
+ *
4220
+ * • {@link mintAgentToken} — inside your `applicationTokenUrl` handler:
4221
+ * signs the app JWT (HS256) with your secret, stamps `aud` from the RFC
4222
+ * 8707 resource, and embeds the encrypted `sid` automatically.
4223
+ * • {@link buildbaseAuth} — the `auth` config for `createMcpHandler`:
4224
+ * verifies the JWT, enforces audience binding, decrypts the `sid`, and
4225
+ * maps the claims to `McpAuthInfo`.
4226
+ *
4227
+ * @example The full loop:
4228
+ * ```ts
4229
+ * // applicationTokenUrl route — the platform calls this on every grant
4230
+ * const { status, body } = await handleAppTokenRequest({
4231
+ * authorization: req.headers.get("authorization"),
4232
+ * clientSecret: process.env.BUILDBASE_CLIENT_SECRET!,
4233
+ * mintToken: (claims) => mintAgentToken({ claims, secret: process.env.SYSTEM_SECRET! }),
4234
+ * });
4235
+ *
4236
+ * // MCP server — verifies what the route above minted
4237
+ * const mcp = createMcpHandler({
4238
+ * buildbase,
4239
+ * auth: buildbaseAuth({ secret: process.env.SYSTEM_SECRET!, resource: "https://app.example.com/api/mcp" }),
4240
+ * });
4241
+ * ```
4242
+ *
4243
+ * AES-GCM comes from WebCrypto (`globalThis.crypto.subtle`) — Node 18+, Bun,
4244
+ * Deno, edge runtimes, browsers. The wire format is
4245
+ * `base64url(iv(12) || authTag(16) || ciphertext)` with the key derived as
4246
+ * `SHA-256(secret + ":bb-session")`, byte-compatible with Node
4247
+ * `createCipheriv("aes-256-gcm", ...)` implementations of the same layout.
4248
+ */
4249
+
4250
+ /** Encrypt/decrypt pair for the `sid` claim, bound to one app secret. */
4251
+ interface SessionRefCrypto {
4252
+ /** Encrypt a BuildBase session id for embedding in an app JWT. */
4253
+ encryptSessionRef(sessionId: string): Promise<string>;
4254
+ /** Decrypt a `sid` claim. Returns null on any failure (wrong key, garbage). */
4255
+ decryptSessionRef(ref: string): Promise<string | null>;
4256
+ }
4257
+ /**
4258
+ * Session-ref crypto derived from the app's secret. Both sides of the loop
4259
+ * ({@link mintAgentToken}, {@link buildbaseAuth}) use this internally — reach
4260
+ * for it directly only when minting or verifying tokens by hand.
4261
+ */
4262
+ declare function createSessionRefCrypto(secret: string): SessionRefCrypto;
4263
+ /** Options for {@link mintAgentToken}. */
4264
+ interface MintAgentTokenOptions {
4265
+ /** The verified platform claims (from `handleAppTokenRequest`'s callback). */
4266
+ claims: AppTokenRequestClaims;
4267
+ /** The APP's token-signing secret. Never leaves this process. */
4268
+ secret: string;
4269
+ /** Token lifetime in seconds. Default 3600 — keep agent tokens short-lived. */
4270
+ expiresInSec?: number;
4271
+ /**
4272
+ * App-specific claims merged into the token — e.g. a `workspaceId` resolved
4273
+ * by your own user sync. Merged last, so they can override the defaults.
4274
+ */
4275
+ extraClaims?: Record<string, unknown>;
4276
+ }
4277
+ /**
4278
+ * Mint the app's agent access token from a platform grant: HS256-signed with
4279
+ * YOUR secret, `aud` bound to the granted RFC 8707 resource(s), scopes carried
4280
+ * through, and the per-user BuildBase session embedded as an encrypted `sid`
4281
+ * claim. The result plugs straight into `handleAppTokenRequest`'s `mintToken`.
4282
+ */
4283
+ declare function mintAgentToken(options: MintAgentTokenOptions): Promise<{
4284
+ token: string;
4285
+ expiresIn: number;
4286
+ }>;
4287
+ /** Options for {@link buildbaseAuth}. */
4288
+ interface BuildBaseAuthOptions {
4289
+ /** The APP's token-signing secret — the same one `mintAgentToken` used. */
4290
+ secret: string;
4291
+ /**
4292
+ * The protected resource(s) this server IS. Enforces RFC 8707 audience
4293
+ * binding — the token's `aud` must include one of these URIs. Pass an array
4294
+ * when the server is addressable under more than one resource identifier
4295
+ * (e.g. the canonical `<host>/mcp` plus the literal endpoint URL); the
4296
+ * FIRST entry is the canonical one used to derive `resourceMetadataUrl`.
4297
+ */
4298
+ resource?: string | string[];
4299
+ /**
4300
+ * Explicit RFC 9728 metadata URL for the 401 challenge. Defaults to the
4301
+ * path-derived `/.well-known/oauth-protected-resource<path>` of the first
4302
+ * `resource`.
4303
+ */
4304
+ resourceMetadataUrl?: string;
4305
+ /**
4306
+ * Reject tokens that carry no `aud` claim at all. Default false: audience is
4307
+ * enforced when present, and legacy audience-less tokens still work. Turn
4308
+ * this on once every minted token is audience-bound.
4309
+ */
4310
+ requireAudience?: boolean;
4311
+ /** Extra JWT verification options (clock tolerance, issuer pinning). */
4312
+ verify?: Pick<VerifyClientJwtOptions, 'clockToleranceSec' | 'issuer'>;
4313
+ }
4314
+ /**
4315
+ * The `auth` config for `createMcpHandler`, prewired for BuildBase-minted app
4316
+ * tokens: HS256 verification with your secret, RFC 8707 audience binding,
4317
+ * `sid` decryption to the BuildBase session, claim mapping to `McpAuthInfo`,
4318
+ * and the derived RFC 9728 `resourceMetadataUrl`. Entirely local — the token
4319
+ * and secret never leave this process.
4320
+ */
4321
+ declare function buildbaseAuth(options: BuildBaseAuthOptions): {
4322
+ verify: (token: string, req: McpHttpRequest) => Promise<McpAuthInfo | null>;
4323
+ resourceMetadataUrl?: string;
4324
+ };
4325
+
4326
+ export { AI_BOT_USER_AGENTS, ApiVersion, AppBridgeError, AuthApi, AuthStatus, BBAction, BBScreen, BBStatus, BB_PARAM, BaseApi, BetaForm, BillingIntervals, BuildBase, CURRENCY_DISPLAY, CURRENCY_FLAG, CreditBucketSource, CreditBucketStatus, CreditTransactionType, DEFAULT_ROLE_PERMISSIONS, DunningState, EventEmitter, InvoiceStatuses, PLAN_CURRENCY_CODES, PLAN_CURRENCY_OPTIONS, PUSH_SERVICE_WORKER_SCRIPT, Permission, PushApi, SDKEvent, SettingsApi, SubscriptionItemType, SubscriptionStatus, UserApi, WorkspaceApi, appTokenFailure, appTokenSuccess, bearerChallenge, buildA2AAgentCard, buildAgentCard, buildAgentSkillsIndex, buildApiCatalog, buildAuthMd, buildDiscoveryLinkHeader, buildDnsAidRecords, buildLlmsFullTxt, buildLlmsTxt, buildMcpDiscoveryManifest, buildMcpServerCard, buildProtectedResourceMetadata, buildRobotsTxt, buildSecurityTxt, buildSitemap, buildSkillMd, buildWebBotAuthDirectory, buildbaseAuth, calculateBillableSeats, calculateSeatOverageCents, calculateTotalSubscriptionCents, cleanBBParams, clearAgentReadinessCache, clearAuthIntent, consumeAuthIntent, createBBUrl, createCheckoutRedirectUrls, createCreditPurchaseRedirectUrls, createSessionRefCrypto, BuildBase as default, eventEmitter, extractBearerToken, fetchAgentReadiness, formatCents, formatMinorAmountIntl, formatOverageRate, formatOverageRateWithLabel, formatQuotaIncludedOverage, formatQuotaWithPrice, getAvailableCurrenciesFromPlans, getBasePriceCents, getBillingIntervalAndCurrencyFromPriceId, getCurrencyDecimals, getCurrencyFlag, getCurrencySymbol, getDisplayCurrency, getPerSeatPriceCents, getPricingVariant, getQuotaDisplayValue, getQuotaDisplayWithVariant, getQuotaOverageCents, getQuotaUnitLabelFromName, getSeatPricing, getStripePriceIdForInterval, handleAppRevokeRequest, handleAppTokenRequest, hasPermission, invalidateCreditBalance, invalidateQuotaUsage, invalidateSubscription, isZeroDecimalCurrency, minorAmountToDisplay, mintAgentToken, negotiateMarkdown, parseWebhookEvent, provideWebMcpTools, readBBParams, resolveAgentPath, resolveMaxUsers, resolvePermissions, resolveWellKnown, safeRedirect, saveAuthIntent, sha256Digest, signClientJwt, validateInvite, validateRedirectUrl, verifyAppRevokeRequest, verifyAppTokenRequest, verifyClientJwt, verifyWebhookSignature, wantsMarkdown };
4327
+ export type { A2ACardConfig, A2ACardSkill, AgentReadinessBundle, AgentReadyConfig, AgentSkill, ApiCatalogApi, AppRevokeRequestClaims, AppScope, AppTokenRequestClaims, AppTokenResponseBody, AppTokenResult, BBActionType, BBScreenType, BBStatusType, BetaFormData, BetaFormResponse, BillingInterval, BuildBaseAuthOptions, BuildBaseConfig, BuildBaseResult, BuildBaseSession, CheckoutResult, ContentSignals, CreditActions, CreditBucketSourceType, CreditBucketStatusType, CreditTransactionTypeValue, DiscoveryDocument, DnsAidRecord, DunningStateType, EventData, EventType, FeatureActions, FormatQuotaWithPriceOptions, GetCheckoutStripeParams, HandlerResult, IAllQuotaUsageResponse, IBaseApiConfig, IBasePricing, IBetaConfig, ICheckoutSessionRequest, ICheckoutSessionResponse, ICheckoutStripeOptions, IConsumeCreditsRequest, IConsumeCreditsResponse, ICreditBalance, ICreditBucket, ICreditBucketsQuery, ICreditBucketsResponse, ICreditPackage, ICreditPackagePricingVariant, ICreditPurchaseRequest, ICreditPurchaseResponse, ICreditTransaction, ICreditTransactionsQuery, ICreditTransactionsResponse, IEventCallbacks, IExpiringCreditsResponse, IInvoice, IInvoiceListResponse, IInvoiceResponse, IOsConfig, IOsState, IPlan, IPlanGroup, IPlanGroupInfo, IPlanGroupLatestVersion, IPlanGroupResponse, IPlanGroupVersion, IPlanGroupVersionWithPlans, IPlanGroupVersionsResponse, IPlanVersion, IPlanVersionSummary, IPlanVersionWithPlan, IPricingVariant, IPublicCreditPackage, IPublicCreditPackagesResponse, IPublicPlanItem, IPublicPlanItemCategory, IPublicPlanVersion, IPublicPlansResponse, IQuotaByInterval, IQuotaIntervalValue, IQuotaOveragePriceIdsByInterval, IQuotaOveragesByInterval, IQuotaUsageStatus, IQuotaUsageStatusResponse, IRecordUsageRequest, IRecordUsageResponse, ISettings, IStripePricesByInterval, ISubscription, ISubscriptionItem, ISubscriptionResponse, ISubscriptionUpdateRequest, ISubscriptionUpdateResponse, IUsageLogEntry, IUsageLogsQuery, IUsageLogsResponse, IUser, IWorkspace, InviteBlockReason, InviteValidation, InvoiceActions, InvoiceStatus, InvoiceStatusType, MaxUsersConfig, McpServerCard, MintAgentTokenOptions, NotificationData, NotificationEvent, NotificationResult, OnWorkspaceChangeParams, PermissionActions, PermissionContext, PermissionKey, PlanActions, PlanVersionWithPricingVariants, QuotaDisplayValue, QuotaDisplayWithOverage, RedirectValidationOptions, RobotsConfig, RobotsPolicy, RolePermissionMap, ScopedActions, SessionRefCrypto, SettingsActions, SitemapUrl, SubscriptionActions, SubscriptionItemTypeValue, SubscriptionStatusType, TranslationKey, UsageActions, UserActions, UserCreatedEventData, UserUpdatedEventData, WebMcpTool, WorkspaceActions, WorkspaceChangedEventData, WorkspaceCreatedEventData, WorkspaceDeletedEventData, WorkspaceUpdatedEventData, WorkspaceUserAddedEventData, WorkspaceUserRemovedEventData, WorkspaceUserRoleChangedEventData };