@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
@@ -1012,7 +1012,7 @@ interface ISettings {
1012
1012
  /** Auto-create workspace on first login */
1013
1013
  autoCreateFirst: boolean;
1014
1014
  };
1015
- [key: string]: any;
1015
+ [key: string]: unknown;
1016
1016
  }
1017
1017
 
1018
1018
  /**
@@ -1026,9 +1026,14 @@ interface IOsConfig {
1026
1026
  version: ApiVersion;
1027
1027
  orgId: string;
1028
1028
  }
1029
+ /** Lifecycle of the one-time org-settings fetch. */
1030
+ type SettingsStatus = 'idle' | 'loading' | 'loaded' | 'error';
1029
1031
  interface IOsState extends IOsConfig {
1030
1032
  auth?: IAuthConfig;
1031
1033
  settings?: ISettings | null;
1034
+ /** State of the settings fetch — lets UI wait instead of guessing with `?? true` defaults. */
1035
+ settingsStatus?: SettingsStatus;
1036
+ settingsError?: string | null;
1032
1037
  }
1033
1038
 
1034
1039
  /**
@@ -1091,6 +1096,7 @@ interface IBaseApiConfig {
1091
1096
  * - getAuthHeaders()
1092
1097
  * - fetchJson<T>(path, init, errorMessage): GET/POST/etc. with handleApiResponse
1093
1098
  * - fetchResponse(path, init): raw Response for custom parsing (e.g. non-JSON or custom error handling)
1099
+ * - fetchUnwrapped<T>(path, init, errorMessage): fetch → throw on !ok → unwrap { success, data } envelope
1094
1100
  */
1095
1101
  declare abstract class BaseApi {
1096
1102
  protected readonly serverUrl: string;
@@ -1125,6 +1131,8 @@ declare abstract class BaseApi {
1125
1131
  private reportError;
1126
1132
  /** Execute fetch with timeout, retries, debug logging, and error callback. */
1127
1133
  private executeFetch;
1134
+ /** Backoff sleep that ends early (with an AbortError) when the signal fires. */
1135
+ private static delay;
1128
1136
  /** Internal: execute fetch against a resolved URL with timeout, retries, debug logging, and error callback. */
1129
1137
  private executeFetchUrl;
1130
1138
  /**
@@ -1137,6 +1145,12 @@ declare abstract class BaseApi {
1137
1145
  * Caller is responsible for checking response.ok and parsing body.
1138
1146
  */
1139
1147
  protected fetchResponse(path: string, init?: RequestInit): Promise<Response>;
1148
+ /**
1149
+ * Execute request, throw a parsed error on !response.ok, and unwrap the
1150
+ * `{ success, data }` envelope. Shorthand for the common
1151
+ * fetchResponse → throwResponseError → unwrapResponse sequence.
1152
+ */
1153
+ protected fetchUnwrapped<T>(path: string, init?: RequestInit, errorMessage?: string): Promise<T>;
1140
1154
  /**
1141
1155
  * Execute request against an absolute URL (bypasses baseUrl).
1142
1156
  * Useful for endpoints outside the default basePath (e.g. /auth vs /public).
@@ -1178,21 +1192,26 @@ interface AuthRequestParams {
1178
1192
  };
1179
1193
  state?: string;
1180
1194
  }
1195
+ /**
1196
+ * Unwrapped payload of a successful auth request.
1197
+ * ⚠️ Prior to the envelope unification this type described the raw
1198
+ * `{ success, data, message }` wire envelope; `requestAuth` now unwraps the
1199
+ * envelope like every other SDK method and resolves with the payload only.
1200
+ */
1181
1201
  interface AuthRequestResponse {
1182
- success: boolean;
1183
- data: {
1184
- redirectUrl: string;
1185
- };
1186
- message: string;
1202
+ redirectUrl: string;
1187
1203
  }
1188
1204
  declare class AuthApi extends BaseApi {
1189
1205
  constructor(config: Pick<IOsConfig, 'serverUrl' | 'version'> & {
1190
1206
  sessionId?: string;
1191
1207
  });
1192
1208
  /**
1193
- * Initiate OAuth sign-in flow. Returns redirect URL to the auth provider.
1209
+ * Initiate OAuth sign-in flow. Resolves with the redirect URL to the auth provider.
1194
1210
  * Auth endpoints sit at /api/v1/auth/ (outside the /public basePath),
1195
- * so we use fetchAbsoluteUrl to get timeout, retry, and error handling via BaseApi.
1211
+ * so we use fetchAbsoluteUrl to get timeout, retry, and error handling via
1212
+ * BaseApi, then apply the standard throwResponseError → unwrapResponse
1213
+ * sequence (the fetchUnwrapped convention). Non-2xx responses and 2xx
1214
+ * envelopes with `success: false` both throw a structured Error.
1196
1215
  */
1197
1216
  requestAuth(params: AuthRequestParams): Promise<AuthRequestResponse>;
1198
1217
  /** Fetch user profile with the given session ID (used after OAuth redirect or from storage). */
@@ -1343,7 +1362,7 @@ interface NotificationData {
1343
1362
  push?: boolean;
1344
1363
  };
1345
1364
  /** Any additional merge tags available as {{key}} in the email template. */
1346
- [key: string]: any;
1365
+ [key: string]: unknown;
1347
1366
  }
1348
1367
  /** Result of sending a notification. */
1349
1368
  interface NotificationResult {
@@ -1374,64 +1393,64 @@ declare class WorkspaceApi extends BaseApi {
1374
1393
  sessionId?: string;
1375
1394
  onUnauthorized?: () => void;
1376
1395
  });
1377
- getWorkspaces(): Promise<IWorkspace[]>;
1396
+ getWorkspaces(signal?: AbortSignal): Promise<IWorkspace[]>;
1378
1397
  createWorkspace(data: {
1379
1398
  name: string;
1380
1399
  image?: string;
1381
- }): Promise<IWorkspace>;
1382
- updateWorkspace(id: string, data: Partial<IWorkspace>): Promise<IWorkspace>;
1383
- deleteWorkspace(id: string): Promise<{
1400
+ }, signal?: AbortSignal): Promise<IWorkspace>;
1401
+ updateWorkspace(id: string, data: Partial<IWorkspace>, signal?: AbortSignal): Promise<IWorkspace>;
1402
+ deleteWorkspace(id: string, signal?: AbortSignal): Promise<{
1384
1403
  success: boolean;
1385
1404
  }>;
1386
- getWorkspaceUsers(workspaceId: string): Promise<IWorkspaceUser[]>;
1405
+ getWorkspaceUsers(workspaceId: string, signal?: AbortSignal): Promise<IWorkspaceUser[]>;
1387
1406
  addUser(workspaceId: string, config: {
1388
1407
  email: string;
1389
1408
  role: string;
1390
- }): Promise<{
1409
+ }, signal?: AbortSignal): Promise<{
1391
1410
  userId: string;
1392
1411
  workspace: IWorkspace;
1393
1412
  message: string;
1394
1413
  }>;
1395
- removeUser(workspaceId: string, userId: string): Promise<{
1414
+ removeUser(workspaceId: string, userId: string, signal?: AbortSignal): Promise<{
1396
1415
  userId: string;
1397
1416
  workspace: IWorkspace;
1398
1417
  message: string;
1399
1418
  }>;
1400
- updateUser(workspaceId: string, userId: string, data: Partial<IWorkspaceUser>): Promise<{
1419
+ updateUser(workspaceId: string, userId: string, data: Partial<IWorkspaceUser>, signal?: AbortSignal): Promise<{
1401
1420
  userId: string;
1402
1421
  workspace: IWorkspace;
1403
1422
  message: string;
1404
1423
  }>;
1405
1424
  updateSettings(data: {
1406
1425
  permissions: Record<string, string[]>;
1407
- }): Promise<any>;
1408
- updateWorkspacePermissions(workspaceId: string, permissions: Record<string, string[]>): Promise<any>;
1409
- getFeatures(): Promise<IWorkspaceFeature[]>;
1410
- updateFeature(workspaceId: string, key: string, value: boolean): Promise<IWorkspace>;
1411
- getWorkspace(workspaceId: string): Promise<IWorkspace>;
1412
- getProfile(): Promise<IUser>;
1413
- updateUserProfile(config: Partial<IUser>): Promise<IUser>;
1414
- getPasskeys(): Promise<IPasskeySummary[]>;
1415
- renamePasskey(passkeyId: string, name: string): Promise<void>;
1416
- deletePasskey(passkeyId: string): Promise<void>;
1426
+ }, signal?: AbortSignal): Promise<any>;
1427
+ updateWorkspacePermissions(workspaceId: string, permissions: Record<string, string[]>, signal?: AbortSignal): Promise<any>;
1428
+ getFeatures(signal?: AbortSignal): Promise<IWorkspaceFeature[]>;
1429
+ updateFeature(workspaceId: string, key: string, value: boolean, signal?: AbortSignal): Promise<IWorkspace>;
1430
+ getWorkspace(workspaceId: string, signal?: AbortSignal): Promise<IWorkspace>;
1431
+ getProfile(signal?: AbortSignal): Promise<IUser>;
1432
+ updateUserProfile(config: Partial<IUser>, signal?: AbortSignal): Promise<IUser>;
1433
+ getPasskeys(signal?: AbortSignal): Promise<IPasskeySummary[]>;
1434
+ renamePasskey(passkeyId: string, name: string, signal?: AbortSignal): Promise<void>;
1435
+ deletePasskey(passkeyId: string, signal?: AbortSignal): Promise<void>;
1417
1436
  /**
1418
1437
  * Get current subscription for a workspace
1419
1438
  * Returns subscription details including plan, plan version, and group information
1420
1439
  */
1421
- getCurrentSubscription(workspaceId: string): Promise<ISubscriptionResponse>;
1440
+ getCurrentSubscription(workspaceId: string, signal?: AbortSignal): Promise<ISubscriptionResponse>;
1422
1441
  /**
1423
1442
  * Get plan group for a workspace
1424
1443
  * Returns the plan group containing the current plan if subscription exists,
1425
1444
  * otherwise returns the latest published group
1426
1445
  */
1427
- getPlanGroup(workspaceId: string): Promise<IPlanGroupResponse>;
1446
+ getPlanGroup(workspaceId: string, signal?: AbortSignal): Promise<IPlanGroupResponse>;
1428
1447
  /**
1429
1448
  * Get plan group for a workspace with a specific version
1430
1449
  * @param workspaceId - The workspace ID
1431
1450
  * @param groupVersionId - The plan group version ID to fetch
1432
1451
  * @returns Plan group response with the specified version
1433
1452
  */
1434
- getPlanGroupByVersion(workspaceId: string, groupVersionId: string): Promise<IPlanGroupResponse>;
1453
+ getPlanGroupByVersion(workspaceId: string, groupVersionId: string, signal?: AbortSignal): Promise<IPlanGroupResponse>;
1435
1454
  /**
1436
1455
  * Get current group version and available newer versions of the same group
1437
1456
  * - If user has active subscription: returns their current group version + newer versions
@@ -1441,7 +1460,7 @@ declare class WorkspaceApi extends BaseApi {
1441
1460
  * @param workspaceId - The workspace ID
1442
1461
  * @returns Plan group versions response with currentVersion and availableVersions
1443
1462
  */
1444
- getPlanGroupVersions(workspaceId: string): Promise<IPlanGroupVersionsResponse>;
1463
+ getPlanGroupVersions(workspaceId: string, signal?: AbortSignal): Promise<IPlanGroupVersionsResponse>;
1445
1464
  /**
1446
1465
  * Get plan group versions by slug (public, no auth required).
1447
1466
  * Returns the latest published plan group versions for the given plan group slug.
@@ -1450,7 +1469,7 @@ declare class WorkspaceApi extends BaseApi {
1450
1469
  * @param slug - Plan group slug (e.g. 'default', 'enterprise')
1451
1470
  * @returns Plan group versions response with currentVersion and availableVersions
1452
1471
  */
1453
- getPublicPlans(slug: string): Promise<IPublicPlansResponse>;
1472
+ getPublicPlans(slug: string, signal?: AbortSignal): Promise<IPublicPlansResponse>;
1454
1473
  /**
1455
1474
  * Get credit packages (public, no auth required).
1456
1475
  * Returns active credit packages for the org with pricing info.
@@ -1458,7 +1477,7 @@ declare class WorkspaceApi extends BaseApi {
1458
1477
  *
1459
1478
  * @returns Credit packages with pricing variants
1460
1479
  */
1461
- getPublicCreditPackages(): Promise<IPublicCreditPackagesResponse>;
1480
+ getPublicCreditPackages(signal?: AbortSignal): Promise<IPublicCreditPackagesResponse>;
1462
1481
  /**
1463
1482
  * Get plan group version details by ID (public, no auth required).
1464
1483
  * Returns the full plan group version with populated plan versions.
@@ -1467,15 +1486,24 @@ declare class WorkspaceApi extends BaseApi {
1467
1486
  * @param groupVersionId - The plan group version ID to fetch
1468
1487
  * @returns Plan group version with populated plan versions
1469
1488
  */
1470
- getPlanGroupVersion(groupVersionId: string): Promise<IPlanGroupVersion>;
1489
+ getPlanGroupVersion(groupVersionId: string, signal?: AbortSignal): Promise<IPlanGroupVersion>;
1471
1490
  /**
1472
1491
  * Create checkout session for new subscription
1473
1492
  * @param workspaceId - The workspace ID
1474
1493
  * @param request - Checkout session request with planVersionId and optional billing interval/URLs
1475
1494
  * @returns Checkout session response with checkoutUrl to redirect user
1476
1495
  */
1477
- createCheckoutSession(workspaceId: string, request: ICheckoutSessionRequest): Promise<CheckoutResult>;
1478
- selectFreePlan(workspaceId: string, planVersionId: string): Promise<{
1496
+ createCheckoutSession(workspaceId: string, request: ICheckoutSessionRequest, signal?: AbortSignal): Promise<CheckoutResult>;
1497
+ /**
1498
+ * Assign a free (freemium) plan to the workspace without a Stripe checkout.
1499
+ *
1500
+ * This endpoint's envelope carries no `data` payload — it is
1501
+ * `{ success, message }` — so `fetchUnwrapped` resolves with the envelope
1502
+ * itself (its unwrap only extracts `data` when present). On resolution
1503
+ * `success` is therefore always `true`: non-2xx responses and 2xx envelopes
1504
+ * with `success: false` both throw a structured Error.
1505
+ */
1506
+ selectFreePlan(workspaceId: string, planVersionId: string, signal?: AbortSignal): Promise<{
1479
1507
  success: boolean;
1480
1508
  message: string;
1481
1509
  }>;
@@ -1484,12 +1512,12 @@ declare class WorkspaceApi extends BaseApi {
1484
1512
  * Only allows plan changes within the same plan group
1485
1513
  * Returns checkout session if payment is required, otherwise returns subscription update response
1486
1514
  */
1487
- updateSubscription(workspaceId: string, request: ISubscriptionUpdateRequest): Promise<ISubscriptionUpdateResponse | ICheckoutSessionResponse>;
1515
+ updateSubscription(workspaceId: string, request: ISubscriptionUpdateRequest, signal?: AbortSignal): Promise<ISubscriptionUpdateResponse | ICheckoutSessionResponse>;
1488
1516
  /**
1489
1517
  * Create a Stripe Customer Portal session for managing payment methods, invoices, etc.
1490
1518
  * Returns the portal URL — redirect user to it.
1491
1519
  */
1492
- createBillingPortalSession(workspaceId: string, returnUrl?: string): Promise<{
1520
+ createBillingPortalSession(workspaceId: string, returnUrl?: string, signal?: AbortSignal): Promise<{
1493
1521
  url: string;
1494
1522
  }>;
1495
1523
  /**
@@ -1499,35 +1527,35 @@ declare class WorkspaceApi extends BaseApi {
1499
1527
  * @param startingAfter - Invoice ID to start after (for pagination)
1500
1528
  * @returns List of invoices with pagination info
1501
1529
  */
1502
- listInvoices(workspaceId: string, limit?: number, startingAfter?: string): Promise<IInvoiceListResponse>;
1530
+ listInvoices(workspaceId: string, limit?: number, startingAfter?: string, signal?: AbortSignal): Promise<IInvoiceListResponse>;
1503
1531
  /**
1504
1532
  * Get a single invoice by ID
1505
1533
  * @param workspaceId - The workspace ID
1506
1534
  * @param invoiceId - The invoice ID
1507
1535
  * @returns Invoice details
1508
1536
  */
1509
- getInvoice(workspaceId: string, invoiceId: string): Promise<IInvoiceResponse>;
1537
+ getInvoice(workspaceId: string, invoiceId: string, signal?: AbortSignal): Promise<IInvoiceResponse>;
1510
1538
  /**
1511
1539
  * Cancel subscription at the end of the current billing period
1512
1540
  * Sets cancelAtPeriodEnd: true - subscription remains active until period ends
1513
1541
  * @param workspaceId - The workspace ID
1514
1542
  * @returns Updated subscription with cancelAtPeriodEnd and stripeCurrentPeriodEnd
1515
1543
  */
1516
- cancelSubscriptionAtPeriodEnd(workspaceId: string): Promise<ISubscriptionResponse>;
1544
+ cancelSubscriptionAtPeriodEnd(workspaceId: string, signal?: AbortSignal): Promise<ISubscriptionResponse>;
1517
1545
  /**
1518
1546
  * Resume a subscription that was scheduled for cancellation
1519
1547
  * Sets cancelAtPeriodEnd: false - subscription will continue after period ends
1520
1548
  * @param workspaceId - The workspace ID
1521
1549
  * @returns Updated subscription with cancelAtPeriodEnd set to false
1522
1550
  */
1523
- resumeSubscription(workspaceId: string): Promise<ISubscriptionResponse>;
1551
+ resumeSubscription(workspaceId: string, signal?: AbortSignal): Promise<ISubscriptionResponse>;
1524
1552
  /**
1525
1553
  * Record quota usage for a workspace
1526
1554
  * @param workspaceId - The workspace ID
1527
1555
  * @param request - Usage request with quotaSlug, quantity, and optional metadata/source
1528
1556
  * @returns Usage result with consumed/included/available/overage
1529
1557
  */
1530
- recordUsage(workspaceId: string, request: IRecordUsageRequest): Promise<IRecordUsageResponse>;
1558
+ recordUsage(workspaceId: string, request: IRecordUsageRequest, signal?: AbortSignal): Promise<IRecordUsageResponse>;
1531
1559
  /**
1532
1560
  * Record multiple quota usage entries in a single request.
1533
1561
  * Designed for backend-to-backend high-volume scenarios (bulk exports, batch jobs).
@@ -1551,7 +1579,7 @@ declare class WorkspaceApi extends BaseApi {
1551
1579
  source?: string;
1552
1580
  idempotencyKey?: string;
1553
1581
  }>;
1554
- }): Promise<{
1582
+ }, signal?: AbortSignal): Promise<{
1555
1583
  success: boolean;
1556
1584
  total: number;
1557
1585
  succeeded: number;
@@ -1569,20 +1597,20 @@ declare class WorkspaceApi extends BaseApi {
1569
1597
  * @param quotaSlug - The quota slug to check
1570
1598
  * @returns Quota usage status with consumed/included/available/overage/hasOverage
1571
1599
  */
1572
- getQuotaUsageStatus(workspaceId: string, quotaSlug: string): Promise<IQuotaUsageStatusResponse>;
1600
+ getQuotaUsageStatus(workspaceId: string, quotaSlug: string, signal?: AbortSignal): Promise<IQuotaUsageStatusResponse>;
1573
1601
  /**
1574
1602
  * Get usage status for all quotas in the workspace's current plan
1575
1603
  * @param workspaceId - The workspace ID
1576
1604
  * @returns All quota usage statuses keyed by quota slug
1577
1605
  */
1578
- getAllQuotaUsage(workspaceId: string): Promise<IAllQuotaUsageResponse>;
1606
+ getAllQuotaUsage(workspaceId: string, signal?: AbortSignal): Promise<IAllQuotaUsageResponse>;
1579
1607
  /**
1580
1608
  * Get paginated usage logs for a workspace
1581
1609
  * @param workspaceId - The workspace ID
1582
1610
  * @param query - Optional filters: quotaSlug, from, to, source, page, limit
1583
1611
  * @returns Paginated usage log entries
1584
1612
  */
1585
- getUsageLogs(workspaceId: string, query?: IUsageLogsQuery): Promise<IUsageLogsResponse>;
1613
+ getUsageLogs(workspaceId: string, query?: IUsageLogsQuery, signal?: AbortSignal): Promise<IUsageLogsResponse>;
1586
1614
  /**
1587
1615
  * Trigger a notification event for a workspace.
1588
1616
  * Respects all notification gates (org settings, event config, workspace preferences).
@@ -1605,16 +1633,16 @@ declare class WorkspaceApi extends BaseApi {
1605
1633
  * });
1606
1634
  * ```
1607
1635
  */
1608
- sendNotification(workspaceId: string, event: string, userId?: string, data?: NotificationData): Promise<NotificationResult>;
1609
- getNotificationEvents(workspaceId: string): Promise<NotificationEvent[]>;
1610
- getNotificationPreferences(workspaceId: string): Promise<Record<string, {
1636
+ sendNotification(workspaceId: string, event: string, userId?: string, data?: NotificationData, signal?: AbortSignal): Promise<NotificationResult>;
1637
+ getNotificationEvents(workspaceId: string, signal?: AbortSignal): Promise<NotificationEvent[]>;
1638
+ getNotificationPreferences(workspaceId: string, signal?: AbortSignal): Promise<Record<string, {
1611
1639
  email?: boolean;
1612
1640
  push?: boolean;
1613
1641
  }>>;
1614
1642
  updateNotificationPreferences(workspaceId: string, preferences: Record<string, {
1615
1643
  email?: boolean;
1616
1644
  push?: boolean;
1617
- }>): Promise<Record<string, {
1645
+ }>, signal?: AbortSignal): Promise<Record<string, {
1618
1646
  email?: boolean;
1619
1647
  push?: boolean;
1620
1648
  }>>;
@@ -1623,7 +1651,7 @@ declare class WorkspaceApi extends BaseApi {
1623
1651
  * @param workspaceId - The workspace ID
1624
1652
  * @returns Credit balance with available, totalGranted, totalConsumed, totalExpired, totalRefunded
1625
1653
  */
1626
- getCreditBalance(workspaceId: string): Promise<ICreditBalance>;
1654
+ getCreditBalance(workspaceId: string, signal?: AbortSignal): Promise<ICreditBalance>;
1627
1655
  /**
1628
1656
  * Consume credits from a workspace balance.
1629
1657
  * Throws an error with `code: 'INSUFFICIENT_CREDITS'` and `available`/`requested` fields on 402.
@@ -1631,7 +1659,7 @@ declare class WorkspaceApi extends BaseApi {
1631
1659
  * @param request - Consume request with amount, optional description, idempotencyKey, metadata
1632
1660
  * @returns Consume result with consumed amount and balanceAfter
1633
1661
  */
1634
- consumeCredits(workspaceId: string, request: IConsumeCreditsRequest): Promise<IConsumeCreditsResponse>;
1662
+ consumeCredits(workspaceId: string, request: IConsumeCreditsRequest, signal?: AbortSignal): Promise<IConsumeCreditsResponse>;
1635
1663
  /**
1636
1664
  * Create a Stripe checkout session for purchasing a credit package.
1637
1665
  * Returns a checkout URL to redirect the user to.
@@ -1639,35 +1667,35 @@ declare class WorkspaceApi extends BaseApi {
1639
1667
  * @param request - Purchase request with creditPackageId, successUrl, cancelUrl, optional currency
1640
1668
  * @returns Checkout session ID and URL
1641
1669
  */
1642
- purchaseCredits(workspaceId: string, request: ICreditPurchaseRequest): Promise<ICreditPurchaseResponse>;
1670
+ purchaseCredits(workspaceId: string, request: ICreditPurchaseRequest, signal?: AbortSignal): Promise<ICreditPurchaseResponse>;
1643
1671
  /**
1644
1672
  * List available credit packages for purchase.
1645
1673
  * Returns active, non-archived packages sorted by sortOrder then creditAmount.
1646
1674
  * @param workspaceId - The workspace ID
1647
1675
  * @returns Array of credit packages
1648
1676
  */
1649
- getCreditPackages(workspaceId: string): Promise<ICreditPackage[]>;
1677
+ getCreditPackages(workspaceId: string, signal?: AbortSignal): Promise<ICreditPackage[]>;
1650
1678
  /**
1651
1679
  * Get paginated credit transaction history.
1652
1680
  * @param workspaceId - The workspace ID
1653
1681
  * @param query - Optional filters: type, page, limit
1654
1682
  * @returns Paginated credit transactions
1655
1683
  */
1656
- getCreditTransactions(workspaceId: string, query?: ICreditTransactionsQuery): Promise<ICreditTransactionsResponse>;
1684
+ getCreditTransactions(workspaceId: string, query?: ICreditTransactionsQuery, signal?: AbortSignal): Promise<ICreditTransactionsResponse>;
1657
1685
  /**
1658
1686
  * Get paginated credit buckets.
1659
1687
  * @param workspaceId - The workspace ID
1660
1688
  * @param query - Optional filters: status, source, page, limit
1661
1689
  * @returns Paginated credit buckets
1662
1690
  */
1663
- getCreditBuckets(workspaceId: string, query?: ICreditBucketsQuery): Promise<ICreditBucketsResponse>;
1691
+ getCreditBuckets(workspaceId: string, query?: ICreditBucketsQuery, signal?: AbortSignal): Promise<ICreditBucketsResponse>;
1664
1692
  /**
1665
1693
  * Get credits expiring within N days.
1666
1694
  * @param workspaceId - The workspace ID
1667
1695
  * @param days - Look-ahead window in days (1-90, default 7)
1668
1696
  * @returns Expiring credits summary with bucket list
1669
1697
  */
1670
- getExpiringCredits(workspaceId: string, days?: number): Promise<IExpiringCreditsResponse>;
1698
+ getExpiringCredits(workspaceId: string, days?: number, signal?: AbortSignal): Promise<IExpiringCreditsResponse>;
1671
1699
  }
1672
1700
 
1673
1701
  /**
@@ -1794,6 +1822,7 @@ declare const BBAction: {
1794
1822
  readonly SelectPlan: "selectPlan";
1795
1823
  readonly CreditPurchase: "creditPurchase";
1796
1824
  readonly OpenCreditStore: "openCreditStore";
1825
+ readonly OpenConnectGuide: "openConnectGuide";
1797
1826
  readonly Invite: "invite";
1798
1827
  };
1799
1828
  type BBActionType = (typeof BBAction)[keyof typeof BBAction];
@@ -1869,15 +1898,40 @@ declare function cleanBBParams(): void;
1869
1898
  /**
1870
1899
  * Security utilities for the SDK.
1871
1900
  */
1901
+ /** Options for {@link validateRedirectUrl}. */
1902
+ interface RedirectValidationOptions {
1903
+ /**
1904
+ * Require absolute URLs to be same-origin with the current page
1905
+ * (`window.location.origin`). Relative paths always pass. Use for any
1906
+ * user-controllable target (return URLs, `?next=` params) — it turns an
1907
+ * open redirect into a same-site navigation. Outside a browser there is no
1908
+ * origin to compare against, so absolute URLs are rejected.
1909
+ */
1910
+ sameOrigin?: boolean;
1911
+ /**
1912
+ * Origins additionally allowed for absolute URLs, e.g.
1913
+ * `['https://checkout.stripe.com']`. Matched against `URL.origin` exactly.
1914
+ */
1915
+ allowedOrigins?: string[];
1916
+ }
1872
1917
  /**
1873
- * Validate that a URL is safe to redirect to.
1874
- * Prevents open redirect attacks by ensuring the URL uses https (or http on localhost).
1875
- * Returns the URL if safe, or null if not.
1918
+ * Validate that a URL is safe to redirect to. Returns the URL if safe, null if
1919
+ * not.
1920
+ *
1921
+ * - **Relative paths** (`/dashboard`) are safe and always allowed —
1922
+ * protocol-relative (`//evil.com`) and backslash (`/\evil.com`) forms are
1923
+ * not treated as relative.
1924
+ * - **Absolute URLs** must be `https:` (or `http:` on localhost). By default
1925
+ * any such URL passes (needed for cross-origin targets like Stripe checkout);
1926
+ * pass `sameOrigin` and/or `allowedOrigins` to restrict — then the URL must
1927
+ * match at least one of them. Always restrict user-controllable targets.
1876
1928
  */
1877
- declare function validateRedirectUrl(url: string | null | undefined): string | null;
1929
+ declare function validateRedirectUrl(url: string | null | undefined, options?: RedirectValidationOptions): string | null;
1878
1930
  /**
1879
1931
  * Safely redirect to a URL after validating it.
1880
- * Falls back to fallbackUrl if the target URL is invalid.
1932
+ * Falls back to fallbackUrl (itself validated — else `/`) if the target URL is
1933
+ * invalid. Pass `options` to restrict user-controllable targets (see
1934
+ * {@link validateRedirectUrl}).
1881
1935
  *
1882
1936
  * Browser-only: navigation requires `window.location`. On non-browser runtimes
1883
1937
  * (Node, edge, Deno, Bun) there is nothing to navigate, so this is a no-op that
@@ -1885,7 +1939,7 @@ declare function validateRedirectUrl(url: string | null | undefined): string | n
1885
1939
  * that needs the resolved target should call {@link validateRedirectUrl} and
1886
1940
  * issue the redirect with its own framework (e.g. `Response.redirect`).
1887
1941
  */
1888
- declare function safeRedirect(url: string | null | undefined, fallbackUrl?: string): boolean;
1942
+ declare function safeRedirect(url: string | null | undefined, fallbackUrl?: string, options?: RedirectValidationOptions): boolean;
1889
1943
 
1890
1944
  /**
1891
1945
  * Auth intent preservation — saves and restores the URL the user was on
@@ -1893,7 +1947,8 @@ declare function safeRedirect(url: string | null | undefined, fallbackUrl?: stri
1893
1947
  */
1894
1948
  /**
1895
1949
  * Save the current URL as the post-auth redirect target.
1896
- * Validates the URL before storing — rejects unsafe URLs silently.
1950
+ * Validates the URL before storing — rejects unsafe URLs silently. Same-origin
1951
+ * only: the return URL is "where the user was", never another site.
1897
1952
  */
1898
1953
  declare function saveAuthIntent(returnUrl: string): void;
1899
1954
  /**
@@ -1925,7 +1980,34 @@ declare const PLAN_CURRENCY_OPTIONS: {
1925
1980
  value: "usd" | "eur" | "gbp" | "jpy" | "cad" | "aud" | "chf" | "cny" | "hkd" | "sgd" | "inr" | "mxn" | "brl" | "nzd" | "sek" | "nok" | "dkk" | "pln" | "thb";
1926
1981
  label: string;
1927
1982
  }[];
1928
- /** Format cents as money string (e.g. 1999, "usd" -> "$19.99"). Caller must pass currency (e.g. from plan or workspace). */
1983
+ /**
1984
+ * Minor-unit digits for a currency per ISO 4217: 0 (JPY, KRW, …), 2 (most),
1985
+ * or 3 (KWD, BHD, …). The zero- and three-decimal sets are pinned to Stripe's
1986
+ * treatment (the billing backend defines amount semantics); ISK is pinned to 2
1987
+ * (Stripe legacy — ISO 4217 says 0). Any other code defers to the runtime's
1988
+ * CLDR data (IQD/LYD → 3, CLF/UYW → 4, UYI → 0), falling back to 2 for codes
1989
+ * unknown to Intl or malformed.
1990
+ */
1991
+ declare function getCurrencyDecimals(currency: string | null | undefined): number;
1992
+ /** True when `currency` has no minor unit (JPY, KRW, …) — amounts are whole units, not cents. */
1993
+ declare function isZeroDecimalCurrency(currency: string | null | undefined): boolean;
1994
+ /**
1995
+ * Convert a minor-unit amount to its display number for `currency`:
1996
+ * `minorAmountToDisplay(1999, 'usd')` → `"19.99"`,
1997
+ * `minorAmountToDisplay(1000, 'jpy')` → `"1,000"` (zero-decimal — no division),
1998
+ * `minorAmountToDisplay(12345, 'kwd')` → `"12.345"` (three-decimal — ÷1000).
1999
+ */
2000
+ declare function minorAmountToDisplay(amount: number, currency: string): string;
2001
+ /**
2002
+ * Locale-aware currency formatting of a minor-unit amount via `Intl.NumberFormat`
2003
+ * (`(1999, 'usd', 'en-US')` → `"$19.99"`; `(1000, 'jpy', 'ja-JP')` → `"¥1,000"`;
2004
+ * `(12345, 'kwd')` → `"KWD 12.345"`). The divisor follows the currency's ISO 4217
2005
+ * minor-unit digits (see `getCurrencyDecimals`) — zero-decimal currencies are
2006
+ * never divided, three-decimal divide by 1000. Falls back to the symbol table
2007
+ * when the currency code is empty or malformed.
2008
+ */
2009
+ declare function formatMinorAmountIntl(amount: number, currency: string, locale?: string): string;
2010
+ /** 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). */
1929
2011
  declare function formatCents(cents: number, currency: string): string;
1930
2012
  /** Translatable labels for overage/quota formatting */
1931
2013
  interface OverageLabels {
@@ -1944,15 +2026,16 @@ interface OverageLabels {
1944
2026
  }
1945
2027
  /**
1946
2028
  * Format overage rate for display. When unitSize > 1: "$1.00/1,000 units"; else "$1.00/unit".
1947
- * Pass `labels` for i18n support.
2029
+ * Pass `labels` for i18n support and `locale` to group numbers in the display locale.
1948
2030
  */
1949
- declare function formatOverageRate(overageCents: number | undefined, unitSize: number | undefined, currency: string, labels?: Partial<OverageLabels>): string | null;
2031
+ declare function formatOverageRate(overageCents: number | undefined, unitSize: number | undefined, currency: string, labels?: Partial<OverageLabels>, locale?: string): string | null;
1950
2032
  /**
1951
2033
  * Format overage rate with optional unit label for comparison/preview UIs.
1952
2034
  * e.g. formatOverageRateWithLabel(50, 1000, "video", "usd") -> "$0.50/1,000 videos"
1953
2035
  * Pass `labels` for i18n support. Pass `pluralUnitLabel` to avoid English "s" pluralization.
2036
+ * Pass `locale` to group numbers in the display locale.
1954
2037
  */
1955
- declare function formatOverageRateWithLabel(overageCents: number | undefined, unitSize: number | undefined, unitLabel: string | undefined, currency: string, pluralUnitLabel?: string, labels?: Partial<OverageLabels>): string | null;
2038
+ declare function formatOverageRateWithLabel(overageCents: number | undefined, unitSize: number | undefined, unitLabel: string | undefined, currency: string, pluralUnitLabel?: string, labels?: Partial<OverageLabels>, locale?: string): string | null;
1956
2039
  /**
1957
2040
  * Get singular unit label from item name or slug (e.g. "Videos" -> "video", "reels" -> "reel").
1958
2041
  * Used for quota display in comparison and preview.
@@ -1961,9 +2044,10 @@ declare function formatOverageRateWithLabel(overageCents: number | undefined, un
1961
2044
  declare function getQuotaUnitLabelFromName(nameOrSlug: string, fallback?: string): string;
1962
2045
  /**
1963
2046
  * Format quota "included + overage" for display.
1964
- * Pass `labels` and `pluralUnitLabel` for i18n support.
2047
+ * Pass `labels` and `pluralUnitLabel` for i18n support, and `locale` to group
2048
+ * numbers in the display locale.
1965
2049
  */
1966
- declare function formatQuotaIncludedOverage(included: number | undefined, overageCents: number | undefined, unitLabel: string, currency: string, unitSize?: number, pluralUnitLabel?: string, labels?: Partial<OverageLabels>, allowOverage?: boolean): string;
2050
+ 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;
1967
2051
 
1968
2052
  type QuotaDisplayValue = {
1969
2053
  included: number;
@@ -1995,6 +2079,8 @@ interface QuotaLabels {
1995
2079
  included: string;
1996
2080
  /** e.g. "then" — separator between included and price */
1997
2081
  then: string;
2082
+ /** e.g. "hard limit" — shown when overage is not allowed */
2083
+ hardLimit?: string;
1998
2084
  }
1999
2085
  /**
2000
2086
  * Format a quota display value as "X included, then $Y.YY / unit".
@@ -2122,6 +2208,18 @@ declare function validateInvite(opts: {
2122
2208
  requireSubscription?: boolean;
2123
2209
  }): InviteValidation;
2124
2210
 
2211
+ /** Minimal workspace shape needed for ownership/role checks. Extended by `permissions.WorkspaceLike`. */
2212
+ interface WorkspaceLike$1 {
2213
+ _id: string;
2214
+ createdBy: string | {
2215
+ _id: string;
2216
+ } | null | undefined;
2217
+ users?: Array<string | {
2218
+ _id: string;
2219
+ role?: string;
2220
+ }>;
2221
+ }
2222
+
2125
2223
  /**
2126
2224
  * Role-based permission system.
2127
2225
  * Framework-agnostic — used by both React hooks and server-side BuildBase.
@@ -2139,6 +2237,7 @@ declare function validateInvite(opts: {
2139
2237
  * Both are resolved from the same role→permission map. Owner always gets all
2140
2238
  * platform permissions + any app permissions defined in the config.
2141
2239
  */
2240
+
2142
2241
  declare const Permission: {
2143
2242
  readonly WORKSPACE_SETTINGS_VIEW: "workspace:settings:view";
2144
2243
  readonly WORKSPACE_SETTINGS_EDIT: "workspace:settings:edit";
@@ -2156,15 +2255,7 @@ declare const Permission: {
2156
2255
  type PermissionKey = (typeof Permission)[keyof typeof Permission];
2157
2256
  type RolePermissionMap = Record<string, string[]>;
2158
2257
  declare const DEFAULT_ROLE_PERMISSIONS: RolePermissionMap;
2159
- interface WorkspaceLike {
2160
- _id: string;
2161
- createdBy: string | {
2162
- _id: string;
2163
- } | null | undefined;
2164
- users?: Array<string | {
2165
- _id: string;
2166
- role?: string;
2167
- }>;
2258
+ interface WorkspaceLike extends WorkspaceLike$1 {
2168
2259
  permissions?: Record<string, string[]>;
2169
2260
  }
2170
2261
  interface SettingsLike {
@@ -2221,7 +2312,7 @@ declare function hasPermission(permission: string | string[], ctx: PermissionCon
2221
2312
  *
2222
2313
  * Or manually create `public/push-sw.js` with this content.
2223
2314
  */
2224
- 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";
2315
+ 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";
2225
2316
 
2226
2317
  interface BetaFormData {
2227
2318
  name?: string;
@@ -2244,6 +2335,24 @@ interface SDKMessages {
2244
2335
  connectedAgentsEmpty: string;
2245
2336
  connectedAgentsAccess: string;
2246
2337
  connectedAgentsGranted: string;
2338
+ connectedAgentsLoadFailed: string;
2339
+ connectedAgentsRevokeFailed: string;
2340
+ mcpConnectAction: string;
2341
+ mcpGuideTitle: string;
2342
+ mcpGuideDescription: string;
2343
+ mcpServerUrlLabel: string;
2344
+ mcpServerUrlHint: string;
2345
+ mcpPromptLabel: string;
2346
+ mcpPromptHint: string;
2347
+ mcpPromptTemplate: string;
2348
+ mcpClientsLabel: string;
2349
+ mcpAddToConfigFile: string;
2350
+ mcpClientChatgptInstructions: string;
2351
+ mcpClientClaudeInstructions: string;
2352
+ mcpClientClineInstructions: string;
2353
+ mcpCopy: string;
2354
+ mcpCopied: string;
2355
+ mcpLearnMore: string;
2247
2356
  inactive: string;
2248
2357
  inactiveHint: string;
2249
2358
  passkeysTitle: string;
@@ -2307,6 +2416,7 @@ interface SDKMessages {
2307
2416
  billingManageOnly: string;
2308
2417
  openSettings: string;
2309
2418
  back: string;
2419
+ close: string;
2310
2420
  };
2311
2421
  };
2312
2422
  subscription: {
@@ -2593,6 +2703,7 @@ interface SDKMessages {
2593
2703
  featureSuccess: string;
2594
2704
  updateSuccess: string;
2595
2705
  actionStatus: string;
2706
+ fallbackName: string;
2596
2707
  };
2597
2708
  danger: {
2598
2709
  title: string;
@@ -2813,6 +2924,7 @@ interface SDKMessages {
2813
2924
  purchaseFailed: string;
2814
2925
  errorLoading: string;
2815
2926
  insufficientCredits: string;
2927
+ insufficientDetail: string;
2816
2928
  };
2817
2929
  loading: {
2818
2930
  restoringSession: string;
@@ -2848,6 +2960,7 @@ interface SDKMessages {
2848
2960
  fetchCreditPackages: string;
2849
2961
  fetchCreditTransactions: string;
2850
2962
  fetchExpiringCredits: string;
2963
+ fetchWorkspaces: string;
2851
2964
  };
2852
2965
  }
2853
2966
  /** Supported locale codes */
@@ -2918,6 +3031,88 @@ interface FullScreenLoaderContextValue {
2918
3031
  */
2919
3032
  declare function useFullScreenLoader(): FullScreenLoaderContextValue;
2920
3033
 
3034
+ /**
3035
+ * Setup steps for one app/tool a person can connect to the server, shown as an
3036
+ * expandable row in the connect guide. In `instructions` and `snippet` you can
3037
+ * use these placeholders, filled in at render time:
3038
+ * `{{url}}` (server address), `{{name}}` (display name), `{{key}}` (a short
3039
+ * safe id used as the key inside config files).
3040
+ */
3041
+ interface McpClientGuide {
3042
+ /** Stable identifier (React key). */
3043
+ id: string;
3044
+ /** Display name shown on the row, e.g. `"Cursor"`. Not translated (proper noun). */
3045
+ name: string;
3046
+ /** Plain-language steps shown above the snippet (what to click / where to paste). */
3047
+ instructions?: string;
3048
+ /** A config snippet the person copies and pastes. Usually JSON. */
3049
+ snippet?: string;
3050
+ /** Optional button link (e.g. a one-click install deep link). */
3051
+ actionUrl?: string;
3052
+ /** Label for {@link actionUrl}. */
3053
+ actionLabel?: string;
3054
+ }
3055
+ /**
3056
+ * MCP connection info passed to `SaaSOSProvider` via the `mcp` prop. Drives the
3057
+ * "Connect an agent" guide on the Connected Agents screen. The guide only
3058
+ * renders when `url` is set.
3059
+ *
3060
+ * @example
3061
+ * ```tsx
3062
+ * <SaaSOSProvider
3063
+ * mcp={{
3064
+ * url: 'https://app.example.com/api/mcp',
3065
+ * name: 'Acme',
3066
+ * docsUrl: 'https://docs.example.com/agents',
3067
+ * }}
3068
+ * >
3069
+ * ```
3070
+ */
3071
+ interface McpConnectionConfig {
3072
+ /** MCP server endpoint URL. Required — the guide renders only when set. */
3073
+ url: string;
3074
+ /** Friendly server name used in prose and snippets. Defaults to `'app'`. */
3075
+ name?: string;
3076
+ /** "Learn more" docs link shown at the bottom of the guide. */
3077
+ docsUrl?: string;
3078
+ /**
3079
+ * The app/tool setup rows. When omitted, a translated built-in set covering
3080
+ * the major AI apps (ChatGPT, Claude, Cursor, VS Code, Windsurf, Cline) is
3081
+ * used. Provide your own to override or extend.
3082
+ */
3083
+ clients?: McpClientGuide[];
3084
+ /**
3085
+ * The copy-and-paste prompt shown for chat-style AIs ("paste this to connect").
3086
+ * Defaults to a translated sentence; pass a string to customize (supports
3087
+ * `{{url}}`/`{{name}}`), or `false` (or an empty string) to hide the prompt
3088
+ * block entirely.
3089
+ */
3090
+ prompt?: string | false;
3091
+ }
3092
+ /**
3093
+ * Fill `{{url}}` / `{{name}}` / `{{key}}` (and any extra vars) placeholders in a
3094
+ * guide template. Single pass, so a value that itself contains `{{…}}` text is
3095
+ * never re-substituted; unknown placeholders are left untouched.
3096
+ *
3097
+ * Values are inserted **verbatim** — when a template is JSON (a client
3098
+ * `snippet`), pass values that are already valid inside a JSON string (the
3099
+ * built-in snippets only interpolate the URL and the JSON-safe {@link mcpServerKey}).
3100
+ */
3101
+ declare function fillMcpTemplate(template: string | undefined, vars: Record<string, string>): string | undefined;
3102
+ /**
3103
+ * A short, file-safe id derived from a display name — used as the `{{key}}`
3104
+ * (the JSON key inside config-file snippets). Always `[a-z0-9-]+`, so it is
3105
+ * safe to drop into JSON unescaped; falls back to `'app'` when the name has no
3106
+ * ASCII alphanumerics (e.g. a non-Latin name).
3107
+ */
3108
+ declare function mcpServerKey(name: string): string;
3109
+ /**
3110
+ * The MCP connection config passed to `SaaSOSProvider`, or `null` when none was
3111
+ * provided. Use it to build a custom connect guide; the ready-made UI is
3112
+ * `<ConnectMcpGuide />` (and it's embedded in `<ConnectedAgents />`).
3113
+ */
3114
+ declare function useMcpConnection(): McpConnectionConfig | null;
3115
+
2921
3116
  /**
2922
3117
  * Settings screen identifiers — kept in a leaf module (no component imports)
2923
3118
  * so consumers of `SettingsScreen` don't pull the whole settings dialog
@@ -3191,6 +3386,23 @@ interface SaaSOSProviderProps extends IOsState {
3191
3386
  * ```
3192
3387
  */
3193
3388
  ui?: SDKUIConfig;
3389
+ /**
3390
+ * MCP server connection info. When set, the Connected Agents screen shows a
3391
+ * "How to connect an agent" guide (copyable server URL + per-client setup
3392
+ * snippets). Read anywhere via `useMcpConnection()`.
3393
+ *
3394
+ * @example
3395
+ * ```tsx
3396
+ * <SaaSOSProvider
3397
+ * mcp={{
3398
+ * url: 'https://app.example.com/api/mcp',
3399
+ * name: 'Acme',
3400
+ * docsUrl: 'https://docs.example.com/agents',
3401
+ * }}
3402
+ * >
3403
+ * ```
3404
+ */
3405
+ mcp?: McpConnectionConfig;
3194
3406
  }
3195
3407
  declare const SaaSOSProvider: React__default.FC<SaaSOSProviderProps>;
3196
3408
 
@@ -3481,16 +3693,49 @@ interface ConnectedAgentsProps {
3481
3693
  disconnectLabel?: string;
3482
3694
  /** Text shown when the user has no connected agents. Defaults to the translated label. */
3483
3695
  emptyLabel?: string;
3696
+ /**
3697
+ * Show the "Connect an agent" action (a header button + empty-state CTA that
3698
+ * open the setup guide in a dialog). Defaults to `true` when an `mcp` config
3699
+ * is passed to `SaaSOSProvider`; set `false` to hide it even when configured.
3700
+ */
3701
+ showConnectGuide?: boolean;
3484
3702
  }
3485
3703
  /**
3486
3704
  * A ready-made "Connected agents" screen: lists the AI agents the signed-in user
3487
- * has authorized to access their account, with a per-row Disconnect action.
3488
- * Session-authed and scoped to the current user — no config beyond having the
3489
- * app wrapped in <SaaSOSProvider>.
3705
+ * has authorized to access their account, with a per-row Disconnect action. When
3706
+ * an `mcp` config is set on `SaaSOSProvider`, a "Connect an agent" button (header
3707
+ * + empty state) opens a setup-guide dialog. Session-authed and scoped to the
3708
+ * current user — no config beyond having the app wrapped in <SaaSOSProvider>.
3490
3709
  *
3491
- * For a fully custom UI, use the `useConnectedAgents()` hook instead.
3710
+ * As a workspace settings screen, open it programmatically with
3711
+ * `openWorkspaceSettings('connected-agents')`; add `{ action: 'openConnectGuide' }`
3712
+ * (or `?bb=action:openConnectGuide`) to land straight on the setup dialog.
3713
+ *
3714
+ * For a fully custom UI, use the `useConnectedAgents()` hook and `<ConnectMcpGuide />`.
3492
3715
  */
3493
- declare function ConnectedAgents({ className, title, description, disconnectLabel, emptyLabel, }: ConnectedAgentsProps): react_jsx_runtime.JSX.Element;
3716
+ declare function ConnectedAgents({ className, title, description, disconnectLabel, emptyLabel, showConnectGuide, }: ConnectedAgentsProps): react_jsx_runtime.JSX.Element;
3717
+
3718
+ interface ConnectMcpGuideProps {
3719
+ /**
3720
+ * Connection config. Defaults to the `mcp` prop passed to `SaaSOSProvider`
3721
+ * (via `useMcpConnection()`); pass explicitly to render a guide elsewhere.
3722
+ */
3723
+ config?: McpConnectionConfig | null;
3724
+ /** Heading. Defaults to the translated title; `null` hides it. */
3725
+ title?: string | null;
3726
+ /** Sub-heading. Defaults to the translated description; `null` hides it. */
3727
+ description?: string | null;
3728
+ className?: string;
3729
+ }
3730
+ /**
3731
+ * A friendly "Connect an agent" guide: the server address, a copy-and-paste
3732
+ * prompt for chat assistants, and step-by-step setup for the major AI apps
3733
+ * (ChatGPT, Claude, Cursor, VS Code, Windsurf, Cline by default; override via
3734
+ * `config.clients`). Renders `null` when no MCP `url` is configured.
3735
+ *
3736
+ * Shown inside `<ConnectedAgents />`; also exported for standalone use.
3737
+ */
3738
+ declare function ConnectMcpGuide({ config, title, description, className }: ConnectMcpGuideProps): react_jsx_runtime.JSX.Element | null;
3494
3739
 
3495
3740
  interface IProps {
3496
3741
  slug: string;
@@ -3582,9 +3827,9 @@ declare const WhenWorkspaceFeatureDisabled: {
3582
3827
  * ```tsx
3583
3828
  * // Edge case: Feature not loaded yet
3584
3829
  * function FeatureContent() {
3585
- * const { isLoading } = useUserFeatures();
3830
+ * const { loading } = useUserFeatures();
3586
3831
  *
3587
- * if (isLoading) return <Loading />;
3832
+ * if (loading) return <Loading />;
3588
3833
  *
3589
3834
  * return (
3590
3835
  * <WhenUserFeatureEnabled slug="feature-x">
@@ -3993,7 +4238,7 @@ interface CreditActionsProviderProps {
3993
4238
  *
3994
4239
  * {packages.map(pkg => (
3995
4240
  * <button key={pkg._id} onClick={() => purchase(pkg)} disabled={purchasing}>
3996
- * Buy {pkg.creditAmount} for ${pkg.pricingVariants[0]?.amount / 100}
4241
+ * Buy {pkg.creditAmount} for {formatCents(pkg.pricingVariants[0]?.amount ?? 0, pkg.pricingVariants[0]?.currency ?? 'usd')}
3997
4242
  * </button>
3998
4243
  * ))}
3999
4244
  * </div>
@@ -4109,7 +4354,7 @@ interface CreditStorePageProps {
4109
4354
  * <div key={pkg._id}>
4110
4355
  * <h3>{pkg.name}</h3>
4111
4356
  * <p>{pkg.creditAmount} credits</p>
4112
- * <p>${(pkg.pricingVariants[0]?.amount / 100).toFixed(2)}</p>
4357
+ * <p>{formatCents(pkg.pricingVariants[0]?.amount ?? 0, pkg.pricingVariants[0]?.currency ?? 'usd')}</p>
4113
4358
  * <button onClick={() => selectPackage(pkg._id)}>Buy</button>
4114
4359
  * </div>
4115
4360
  * ))}
@@ -4323,41 +4568,40 @@ declare function useSaaSOs(): IOsState;
4323
4568
  * Hook to access organization settings from the OS context.
4324
4569
  * Automatically fetches settings once when OS config is ready.
4325
4570
  * Safe to call from multiple components — only one fetch is made.
4571
+ *
4572
+ * @returns `{ settings, loading, error, refetch }` — `loading` is true from
4573
+ * mount until the one-time fetch settles (so UI can wait instead of guessing
4574
+ * with `?? true` defaults); `error` carries the failure message; `refetch`
4575
+ * re-runs the fetch (deduped across components).
4326
4576
  */
4327
4577
  declare function useSaaSSettings(): {
4328
4578
  settings: ISettings | null | undefined;
4329
- getSettings: (signal?: AbortSignal) => Promise<ISettings | null>;
4579
+ loading: boolean;
4580
+ error: string | null;
4581
+ refetch: (_signal?: AbortSignal) => Promise<ISettings | null>;
4582
+ getSettings: (_signal?: AbortSignal) => Promise<ISettings | null>;
4330
4583
  };
4331
4584
 
4332
- interface UserContextValue {
4333
- attributes: Record<string, string | number | boolean>;
4334
- features: Record<string, boolean>;
4335
- isLoading: boolean;
4336
- error: Error | null;
4337
- updateAttributes: (updates: Record<string, string | number | boolean>) => Promise<IUser>;
4338
- updateAttribute: (attributeKey: string, value: string | number | boolean) => Promise<IUser>;
4339
- refreshAttributes: () => Promise<void>;
4340
- refreshFeatures: () => Promise<void>;
4341
- }
4342
-
4343
4585
  /**
4344
4586
  * Hook to access user attributes from the UserProvider.
4345
4587
  * Must be used within a UserProvider component.
4346
4588
  *
4347
- * @returns User context object containing:
4589
+ * @returns An object containing:
4348
4590
  * - `attributes`: Record of user attribute key-value pairs
4349
- * - `isLoading`: Boolean indicating if attributes are being loaded
4350
- * - `error`: Error message string (null if no error)
4351
- * - `refreshAttributes()`: Function to manually refresh attributes
4591
+ * - `loading`: Boolean indicating if attributes are being loaded (attributes pipeline only)
4592
+ * - `error`: Last attributes fetch/update error (null if no error)
4593
+ * - `refetch()`: Function to manually refresh attributes
4594
+ * - `updateAttributes(updates)`: Function to update multiple attributes
4595
+ * - `updateAttribute(key, value)`: Function to update one attribute
4352
4596
  *
4353
4597
  * @throws {Error} If used outside of UserProvider
4354
4598
  *
4355
4599
  * @example
4356
4600
  * ```tsx
4357
4601
  * function UserProfile() {
4358
- * const { attributes, isLoading } = useUserAttributes();
4602
+ * const { attributes, loading } = useUserAttributes();
4359
4603
  *
4360
- * if (isLoading) return <Loading />;
4604
+ * if (loading) return <Loading />;
4361
4605
  *
4362
4606
  * return (
4363
4607
  * <div>
@@ -4368,16 +4612,27 @@ interface UserContextValue {
4368
4612
  * }
4369
4613
  * ```
4370
4614
  */
4371
- declare function useUserAttributes(): UserContextValue;
4615
+ declare function useUserAttributes(): {
4616
+ attributes: Record<string, string | number | boolean>;
4617
+ loading: boolean;
4618
+ error: Error | null;
4619
+ refetch: () => Promise<void>;
4620
+ updateAttributes: (updates: Record<string, string | number | boolean>) => Promise<IUser>;
4621
+ updateAttribute: (attributeKey: string, value: string | number | boolean) => Promise<IUser>;
4622
+ /** @deprecated Use `loading` (note: this legacy flag combines BOTH pipelines). */
4623
+ isLoading: boolean;
4624
+ /** @deprecated Use `refetch`. */
4625
+ refreshAttributes: () => Promise<void>;
4626
+ };
4372
4627
  /**
4373
4628
  * Hook to access user feature flags from the UserProvider.
4374
4629
  * Must be used within a UserProvider component.
4375
4630
  *
4376
4631
  * @returns An object containing:
4377
4632
  * - `features`: Record of feature flag key-value pairs (boolean values)
4378
- * - `isLoading`: Boolean indicating if features are being loaded
4379
- * - `error`: Error message string (null if no error)
4380
- * - `refreshFeatures()`: Function to manually refresh features
4633
+ * - `loading`: Boolean indicating if features are being loaded (features pipeline only)
4634
+ * - `error`: Last features fetch error (null if no error)
4635
+ * - `refetch()`: Function to manually refresh features
4381
4636
  * - `isFeatureEnabled(featureId)`: Function to check if a specific feature is enabled
4382
4637
  *
4383
4638
  * @throws {Error} If used outside of UserProvider
@@ -4385,9 +4640,9 @@ declare function useUserAttributes(): UserContextValue;
4385
4640
  * @example
4386
4641
  * ```tsx
4387
4642
  * function FeatureContent() {
4388
- * const { isFeatureEnabled, isLoading } = useUserFeatures();
4643
+ * const { isFeatureEnabled, loading } = useUserFeatures();
4389
4644
  *
4390
- * if (isLoading) return <Loading />;
4645
+ * if (loading) return <Loading />;
4391
4646
  *
4392
4647
  * if (isFeatureEnabled('premium-feature')) {
4393
4648
  * return <PremiumFeature />;
@@ -4414,20 +4669,130 @@ declare function useUserAttributes(): UserContextValue;
4414
4669
  */
4415
4670
  declare function useUserFeatures(): {
4416
4671
  features: Record<string, boolean>;
4417
- isLoading: boolean;
4672
+ loading: boolean;
4418
4673
  error: Error | null;
4419
- refreshFeatures: () => Promise<void>;
4674
+ refetch: () => Promise<void>;
4420
4675
  isFeatureEnabled: (featureId: string) => boolean;
4676
+ /** @deprecated Use `loading`. */
4677
+ isLoading: boolean;
4678
+ /** @deprecated Use `refetch`. */
4679
+ refreshFeatures: () => Promise<void>;
4421
4680
  };
4422
4681
 
4682
+ /**
4683
+ * Main workspace management hook for the SDK.
4684
+ * Provides workspace state, CRUD operations, and user management.
4685
+ *
4686
+ * State selection is per-consumer; the lifecycle (fetch dedup, storage
4687
+ * restore, switch versioning, current-workspace sync) lives in the single
4688
+ * `WorkspaceProvider` instance mounted by `SaaSOSProvider`, so
4689
+ * `onWorkspaceChange` / `workspace:changed` fire exactly once per switch no
4690
+ * matter how many components use this hook.
4691
+ *
4692
+ * @returns An object containing:
4693
+ * - `workspaces`: Array of all workspaces the user has access to
4694
+ * - `currentWorkspace`: Currently selected workspace (null if none selected)
4695
+ * - `loading`: Boolean indicating if workspaces are being fetched
4696
+ * - `error`: Error message string (null if no error)
4697
+ * - `refreshing`: Boolean indicating if workspaces are being refreshed in background
4698
+ * - `switching`: Boolean - true when a workspace switch is in progress
4699
+ * - `fetchWorkspaces()`: Function to fetch all workspaces
4700
+ * - `refreshWorkspaces()`: Function to refresh workspaces in background (non-blocking)
4701
+ * - `setCurrentWorkspace(workspace)`: Function to set the current workspace (direct, no callback)
4702
+ * - `switchToWorkspace(workspace)`: Centralized switch - calls onWorkspaceChange first, then sets workspace
4703
+ * - `resetCurrentWorkspace()`: Function to clear the current workspace
4704
+ * - `createWorkspace(name, image?)`: Function to create a new workspace
4705
+ * - `updateWorkspace(workspace, data)`: Function to update a workspace
4706
+ * - `deleteWorkspace(workspaceId)`: Function to delete a workspace (owner only)
4707
+ * - `getWorkspace(workspaceId)`: Function to fetch a specific workspace
4708
+ * - `getUsers(workspaceId)`: Function to fetch users in a workspace
4709
+ * - `addUser(workspaceId, email, role)`: Function to add a user to a workspace
4710
+ * - `removeUser(workspaceId, userId)`: Function to remove a user from a workspace
4711
+ * - `updateUser(workspaceId, userId, config)`: Function to update a user in a workspace
4712
+ * - `getProfile()`: Function to fetch current user profile
4713
+ * - `updateUserProfile(config)`: Function to update current user profile
4714
+ * - `allFeatures`: Array of all available feature flags
4715
+ * - `getFeatures()`: Function to fetch all available features
4716
+ * - `updateFeature(workspaceId, key, value)`: Function to update a feature flag
4717
+ *
4718
+ * @example
4719
+ * ```tsx
4720
+ * function WorkspaceList() {
4721
+ * const { workspaces, loading, fetchWorkspaces } = useSaaSWorkspaces();
4722
+ *
4723
+ * useEffect(() => {
4724
+ * fetchWorkspaces();
4725
+ * }, [fetchWorkspaces]);
4726
+ *
4727
+ * if (loading) return <Loading />;
4728
+ *
4729
+ * return (
4730
+ * <ul>
4731
+ * {workspaces.map(ws => (
4732
+ * <li key={ws._id}>{ws.name}</li>
4733
+ * ))}
4734
+ * </ul>
4735
+ * );
4736
+ * }
4737
+ * ```
4738
+ *
4739
+ * @example
4740
+ * ```tsx
4741
+ * // Create a new workspace
4742
+ * function CreateWorkspace() {
4743
+ * const { createWorkspace } = useSaaSWorkspaces();
4744
+ *
4745
+ * const handleCreate = async () => {
4746
+ * try {
4747
+ * await createWorkspace('My Workspace', 'https://example.com/logo.png');
4748
+ * } catch (error) {
4749
+ * console.error('Failed to create workspace:', error);
4750
+ * }
4751
+ * };
4752
+ *
4753
+ * return <button onClick={handleCreate}>Create Workspace</button>;
4754
+ * }
4755
+ * ```
4756
+ *
4757
+ * @example
4758
+ * ```tsx
4759
+ * // Delete workspace (owner only)
4760
+ * function DeleteWorkspaceButton({ workspaceId }) {
4761
+ * const { deleteWorkspace } = useSaaSWorkspaces();
4762
+ *
4763
+ * const handleDelete = async () => {
4764
+ * if (!confirm('Are you sure?')) return;
4765
+ * try {
4766
+ * await deleteWorkspace(workspaceId);
4767
+ * } catch (error) {
4768
+ * // Error: "Only the workspace creator can delete the workspace"
4769
+ * alert(error.message);
4770
+ * }
4771
+ * };
4772
+ *
4773
+ * return <button onClick={handleDelete}>Delete</button>;
4774
+ * }
4775
+ * ```
4776
+ *
4777
+ * @example
4778
+ * ```tsx
4779
+ * // Edge case: Workspace removed from user's access
4780
+ * function WorkspaceContent() {
4781
+ * const { currentWorkspace, workspaces } = useSaaSWorkspaces();
4782
+ *
4783
+ * // If current workspace is not in the list, it was removed
4784
+ * // The hook automatically switches to first available workspace
4785
+ * if (!currentWorkspace) {
4786
+ * return <p>No workspace selected</p>;
4787
+ * }
4788
+ *
4789
+ * return <div>{currentWorkspace.name}</div>;
4790
+ * }
4791
+ * ```
4792
+ */
4423
4793
  declare const useSaaSWorkspaces: () => {
4424
- workspaces: IWorkspace[];
4425
- loading: boolean;
4426
- error: string | null;
4427
4794
  fetchWorkspaces: () => Promise<void>;
4428
4795
  refreshWorkspaces: () => Promise<void>;
4429
- refreshing: boolean;
4430
- currentWorkspace: IWorkspace | null;
4431
4796
  setCurrentWorkspace: (ws: IWorkspace, options?: {
4432
4797
  forceEmit?: boolean;
4433
4798
  }) => void;
@@ -4436,25 +4801,15 @@ declare const useSaaSWorkspaces: () => {
4436
4801
  }) => Promise<void>;
4437
4802
  resetCurrentWorkspace: () => void;
4438
4803
  createWorkspace: (name: string, image?: string) => Promise<void>;
4439
- allFeatures: IWorkspaceFeature[];
4440
- getFeatures: () => Promise<IWorkspaceFeature[] | null>;
4441
- updateFeature: (workspaceId: string, key: string, value: boolean) => Promise<IWorkspace>;
4442
- updateWorkspaceSettings: (data: {
4443
- permissions: Record<string, string[]>;
4444
- }) => Promise<any>;
4445
- updateWorkspacePermissions: (workspaceId: string, permissions: Record<string, string[]>) => Promise<any>;
4804
+ updateWorkspace: (ws: IWorkspace, data: Partial<IWorkspace>) => Promise<void>;
4805
+ deleteWorkspace: (workspaceId: string) => Promise<unknown>;
4446
4806
  getWorkspace: (workspaceId: string) => Promise<IWorkspace>;
4447
- updateWorkspace: (ws: IWorkspace, _data: Partial<IWorkspace>) => Promise<void>;
4448
4807
  getUsers: (workspaceId: string) => Promise<IWorkspaceUser[]>;
4449
4808
  addUser: (workspaceId: string, email: string, role: string) => Promise<{
4450
4809
  userId: string;
4451
- workspace: IWorkspace;
4452
- message: string;
4453
4810
  }>;
4454
4811
  removeUser: (workspaceId: string, userId: string) => Promise<{
4455
4812
  userId: string;
4456
- workspace: IWorkspace;
4457
- message: string;
4458
4813
  }>;
4459
4814
  updateUser: (workspaceId: string, userId: string, config: Partial<IWorkspaceUser>) => Promise<{
4460
4815
  userId: string;
@@ -4463,9 +4818,18 @@ declare const useSaaSWorkspaces: () => {
4463
4818
  }>;
4464
4819
  getProfile: () => Promise<IUser>;
4465
4820
  updateUserProfile: (config: Partial<IUser>) => Promise<IUser>;
4466
- deleteWorkspace: (workspaceId: string) => Promise<{
4467
- success: boolean;
4468
- }>;
4821
+ getFeatures: () => Promise<IWorkspaceFeature[] | null>;
4822
+ updateFeature: (workspaceId: string, key: string, value: boolean) => Promise<IWorkspace>;
4823
+ updateWorkspaceSettings: (data: {
4824
+ permissions: Record<string, string[]>;
4825
+ }) => Promise<unknown>;
4826
+ updateWorkspacePermissions: (workspaceId: string, permissions: Record<string, string[]>) => Promise<unknown>;
4827
+ workspaces: IWorkspace[];
4828
+ loading: boolean;
4829
+ error: string | null;
4830
+ refreshing: boolean;
4831
+ currentWorkspace: IWorkspace | null;
4832
+ allFeatures: IWorkspaceFeature[];
4469
4833
  switching: boolean;
4470
4834
  switchingToId: string | null;
4471
4835
  };
@@ -5656,7 +6020,7 @@ declare function EmptyState({ icon, title, description, action, className }: Emp
5656
6020
  interface FullScreenLoaderProps {
5657
6021
  /** Content to display centered on screen. Falls back to a default spinner + message. */
5658
6022
  children?: React__default.ReactNode;
5659
- /** Message shown below the default spinner (only used when no children are provided). Defaults to "Loading..." */
6023
+ /** Message shown below the default spinner (only used when no children are provided). Defaults to the translated "Loading..." */
5660
6024
  message?: string;
5661
6025
  /** Background color of the overlay. Defaults to white (dark mode: near-black). */
5662
6026
  backgroundColor?: string;
@@ -5680,7 +6044,7 @@ interface FullScreenLoaderProps {
5680
6044
  * ```
5681
6045
  */
5682
6046
  declare const FullScreenLoader: {
5683
- ({ children, message, backgroundColor, }: FullScreenLoaderProps): react_jsx_runtime.JSX.Element;
6047
+ ({ children, message: messageProp, backgroundColor, }: FullScreenLoaderProps): react_jsx_runtime.JSX.Element;
5684
6048
  displayName: string;
5685
6049
  };
5686
6050
 
@@ -5842,7 +6206,9 @@ declare class WorkspaceSettingsManager {
5842
6206
  */
5843
6207
  subscribe(listener: (state: SettingsManagerState) => void): () => void;
5844
6208
  /**
5845
- * Get current state
6209
+ * Get current state. Returns the internal immutable snapshot (every change
6210
+ * replaces the object, never mutates it) so the reference is stable between
6211
+ * changes — a `useSyncExternalStore.getSnapshot` requirement.
5846
6212
  */
5847
6213
  getState(): SettingsManagerState;
5848
6214
  /**
@@ -5867,5 +6233,5 @@ declare class WorkspaceSettingsManager {
5867
6233
  }
5868
6234
  declare const workspaceSettingsManager: WorkspaceSettingsManager;
5869
6235
 
5870
- export { ApiVersion, AuthApi, AuthStatus, BBAction, BBScreen, BBStatus, BB_PARAM, BaseApi, BetaForm, BillingIntervals, CURRENCY_DISPLAY, CURRENCY_FLAG, ConnectedAgents, ConnectedAgentsApi, CreditActionsProvider, CreditBalance, CreditBalanceContextProvider, CreditBucketSource, CreditBucketStatus, CreditStorePage, CreditTransactionType, DEFAULT_ROLE_PERMISSIONS, DunningState, EmptyState, EventEmitter, FullScreenLoader, InvoiceStatuses, LoadingState, PLAN_CURRENCY_CODES, PLAN_CURRENCY_OPTIONS, PUSH_SERVICE_WORKER_SCRIPT, Permission, PricingPage, PushApi, PushNotificationProvider, QuotaUsageContextProvider, SDKEvent, SETTINGS_SCREENS, SUPPORTED_LOCALES, SaaSOSProvider, SectionHeader, SettingsApi, SettingsScreen, SidebarNavItem, SidebarNavSection, StatusBanner, SubscriptionContextProvider, SubscriptionItemType, SubscriptionStatus, UserApi, WhenAuthenticated, WhenCreditsAvailable, WhenCreditsExhausted, WhenCreditsLow, WhenNoSubscription, WhenNotTrialing, WhenPermission, WhenQuotaAvailable, WhenQuotaExhausted, WhenQuotaOverage, WhenQuotaThreshold, WhenRoles, WhenSubscription, WhenSubscriptionToPlans, WhenTrialEnding, WhenTrialing, WhenUnauthenticated, WhenUserFeatureDisabled, WhenUserFeatureEnabled, WhenWorkspaceFeatureDisabled, WhenWorkspaceFeatureEnabled, WhenWorkspaceRoles, WorkspaceApi, WorkspaceSwitcher, calculateBillableSeats, calculateSeatOverageCents, calculateTotalSubscriptionCents, cleanBBParams, clearAuthIntent, consumeAuthIntent, createBBUrl, createCheckoutRedirectUrls, createCreditPurchaseRedirectUrls, eventEmitter, formatCents, formatOverageRate, formatOverageRateWithLabel, formatQuotaIncludedOverage, formatQuotaWithPrice, getAvailableCurrenciesFromPlans, getBasePriceCents, getBillingIntervalAndCurrencyFromPriceId, getCurrencyFlag, getCurrencySymbol, getDisplayCurrency, getPerSeatPriceCents, getPricingVariant, getQuotaDisplayValue, getQuotaDisplayWithVariant, getQuotaOverageCents, getQuotaUnitLabelFromName, getSeatPricing, getStripePriceIdForInterval, hasPermission, invalidateCreditBalance, invalidateQuotaUsage, invalidateSubscription, mergeUIConfig, readBBParams, resolveMaxUsers, resolvePermissions, safeRedirect, saveAuthIntent, useAllQuotaUsage, useBillingPortal, useCancelSubscription, useConnectedAgents, useConnectedAgentsApi, useConsumeCredits, useCreateCheckoutSession, useCreditBalance, useCreditBalanceContext, useCreditPackages, useCreditTransactions, useExpiringCredits, useFullScreenLoader, useInvoice, useInvoices, usePermissions, usePlanGroup, usePlanGroupVersions, usePublicCreditPackages, usePublicPlanGroupVersion, usePublicPlans, usePurchaseCredits, usePushNotifications, useQuotaUsageContext, useQuotaUsageStatus, useRecordUsage, useResumeSubscription, useSaaSAuth, useSaaSOs, useSaaSSettings, useSaaSWorkspaces, useSeatStatus, useSubscription, useSubscriptionContext, useSubscriptionManagement, useTranslation, useTrialStatus, useUIConfig, useUIVisibility, useUpdateSubscription, useUsageLogs, useUserAttributes, useUserFeatures, validateInvite, validateRedirectUrl, workspaceSettingsManager };
5871
- export type { BBActionType, BBScreenType, BBStatusType, BetaFormData, BetaFormResponse, BillingInterval, CheckoutResult, ConnectedAgentsProps, CreditActionsDetails, CreditBalanceContextValue, CreditBalanceDetails, CreditBucketSourceType, CreditBucketStatusType, CreditStorePageDetails, CreditTransactionTypeValue, DunningStateType, EmptyStateProps, EventData, EventType, FormatQuotaWithPriceOptions, FullScreenLoaderProps, GetCheckoutStripeParams, IAllQuotaUsageResponse, IBaseApiConfig, IBasePricing, IBetaConfig, ICheckoutSessionRequest, ICheckoutSessionResponse, ICheckoutStripeOptions, IConnectedAgent, 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, InvoiceStatus, InvoiceStatusType, LoadingProps, LoadingStateProps, MaxUsersConfig, NotificationData, NotificationEvent, NotificationResult, OnWorkspaceChangeParams, PartialSDKMessages, PermissionContext, PermissionKey, PlanVersionWithPricingVariants, PricingPageDetails, PricingPageProps, QuotaDisplayValue, QuotaDisplayWithOverage, QuotaUsageContextValue, RolePermissionMap, SDKLocale, SDKMessages, SDKUIConfig, SaaSOSProviderProps, SeatStatus, SectionHeaderProps, SettingsManagerState, SidebarNavItemProps, SidebarNavSectionProps, StatusBannerProps, StatusBannerVariant, SubscriptionContextValue, SubscriptionItemTypeValue, SubscriptionStatusType, TranslationKey, TrialStatus, UseConnectedAgents, UserCreatedEventData, UserUpdatedEventData, WorkspaceChangedEventData, WorkspaceCreatedEventData, WorkspaceDeletedEventData, WorkspaceSettingsSection, WorkspaceUpdatedEventData, WorkspaceUserAddedEventData, WorkspaceUserRemovedEventData, WorkspaceUserRoleChangedEventData };
6236
+ export { ApiVersion, AuthApi, AuthStatus, BBAction, BBScreen, BBStatus, BB_PARAM, BaseApi, BetaForm, BillingIntervals, SaaSOSProvider as BuildBaseProvider, CURRENCY_DISPLAY, CURRENCY_FLAG, ConnectMcpGuide, ConnectedAgents, ConnectedAgentsApi, CreditActionsProvider, CreditBalance, CreditBalanceContextProvider, CreditBucketSource, CreditBucketStatus, CreditStorePage, CreditTransactionType, DEFAULT_ROLE_PERMISSIONS, DunningState, EmptyState, EventEmitter, FullScreenLoader, InvoiceStatuses, LoadingState, PLAN_CURRENCY_CODES, PLAN_CURRENCY_OPTIONS, PUSH_SERVICE_WORKER_SCRIPT, Permission, PricingPage, PushApi, PushNotificationProvider, QuotaUsageContextProvider, SDKEvent, SETTINGS_SCREENS, SUPPORTED_LOCALES, SaaSOSProvider, SectionHeader, SettingsApi, SettingsScreen, SidebarNavItem, SidebarNavSection, StatusBanner, SubscriptionContextProvider, SubscriptionItemType, SubscriptionStatus, UserApi, WhenAuthenticated, WhenCreditsAvailable, WhenCreditsExhausted, WhenCreditsLow, WhenNoSubscription, WhenNotTrialing, WhenPermission, WhenQuotaAvailable, WhenQuotaExhausted, WhenQuotaOverage, WhenQuotaThreshold, WhenRoles, WhenSubscription, WhenSubscriptionToPlans, WhenTrialEnding, WhenTrialing, WhenUnauthenticated, WhenUserFeatureDisabled, WhenUserFeatureEnabled, WhenWorkspaceFeatureDisabled, WhenWorkspaceFeatureEnabled, WhenWorkspaceRoles, WorkspaceApi, WorkspaceSwitcher, calculateBillableSeats, calculateSeatOverageCents, calculateTotalSubscriptionCents, cleanBBParams, clearAuthIntent, consumeAuthIntent, createBBUrl, createCheckoutRedirectUrls, createCreditPurchaseRedirectUrls, eventEmitter, fillMcpTemplate, formatCents, formatMinorAmountIntl, formatOverageRate, formatOverageRateWithLabel, formatQuotaIncludedOverage, formatQuotaWithPrice, getAvailableCurrenciesFromPlans, getBasePriceCents, getBillingIntervalAndCurrencyFromPriceId, getCurrencyDecimals, getCurrencyFlag, getCurrencySymbol, getDisplayCurrency, getPerSeatPriceCents, getPricingVariant, getQuotaDisplayValue, getQuotaDisplayWithVariant, getQuotaOverageCents, getQuotaUnitLabelFromName, getSeatPricing, getStripePriceIdForInterval, hasPermission, invalidateCreditBalance, invalidateQuotaUsage, invalidateSubscription, isZeroDecimalCurrency, mcpServerKey, mergeUIConfig, minorAmountToDisplay, readBBParams, resolveMaxUsers, resolvePermissions, safeRedirect, saveAuthIntent, useAllQuotaUsage, useBillingPortal, useCancelSubscription, useConnectedAgents, useConnectedAgentsApi, useConsumeCredits, useCreateCheckoutSession, useCreditBalance, useCreditBalanceContext, useCreditPackages, useCreditTransactions, useExpiringCredits, useFullScreenLoader, useInvoice, useInvoices, useMcpConnection, usePermissions, usePlanGroup, usePlanGroupVersions, usePublicCreditPackages, usePublicPlanGroupVersion, usePublicPlans, usePurchaseCredits, usePushNotifications, useQuotaUsageContext, useQuotaUsageStatus, useRecordUsage, useResumeSubscription, useSaaSAuth, useSaaSOs, useSaaSSettings, useSaaSWorkspaces, useSeatStatus, useSubscription, useSubscriptionContext, useSubscriptionManagement, useTranslation, useTrialStatus, useUIConfig, useUIVisibility, useUpdateSubscription, useUsageLogs, useUserAttributes, useUserFeatures, validateInvite, validateRedirectUrl, workspaceSettingsManager };
6237
+ export type { BBActionType, BBScreenType, BBStatusType, BetaFormData, BetaFormResponse, BillingInterval, SaaSOSProviderProps as BuildBaseProviderProps, CheckoutResult, ConnectMcpGuideProps, ConnectedAgentsProps, CreditActionsDetails, CreditBalanceContextValue, CreditBalanceDetails, CreditBucketSourceType, CreditBucketStatusType, CreditStorePageDetails, CreditTransactionTypeValue, DunningStateType, EmptyStateProps, EventData, EventType, FormatQuotaWithPriceOptions, FullScreenLoaderProps, GetCheckoutStripeParams, IAllQuotaUsageResponse, IBaseApiConfig, IBasePricing, IBetaConfig, ICheckoutSessionRequest, ICheckoutSessionResponse, ICheckoutStripeOptions, IConnectedAgent, 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, InvoiceStatus, InvoiceStatusType, LoadingProps, LoadingStateProps, MaxUsersConfig, McpClientGuide, McpConnectionConfig, NotificationData, NotificationEvent, NotificationResult, OnWorkspaceChangeParams, PartialSDKMessages, PermissionContext, PermissionKey, PlanVersionWithPricingVariants, PricingPageDetails, PricingPageProps, QuotaDisplayValue, QuotaDisplayWithOverage, QuotaUsageContextValue, RedirectValidationOptions, RolePermissionMap, SDKLocale, SDKMessages, SDKUIConfig, SaaSOSProviderProps, SeatStatus, SectionHeaderProps, SettingsManagerState, SidebarNavItemProps, SidebarNavSectionProps, StatusBannerProps, StatusBannerVariant, SubscriptionContextValue, SubscriptionItemTypeValue, SubscriptionStatusType, TranslationKey, TrialStatus, UseConnectedAgents, UserCreatedEventData, UserUpdatedEventData, WorkspaceChangedEventData, WorkspaceCreatedEventData, WorkspaceDeletedEventData, WorkspaceSettingsSection, WorkspaceUpdatedEventData, WorkspaceUserAddedEventData, WorkspaceUserRemovedEventData, WorkspaceUserRoleChangedEventData };