@makemind/sdk 0.1.0

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.
@@ -0,0 +1,3080 @@
1
+ import { FirebaseApp } from 'firebase/app';
2
+
3
+ interface ApiClientConfig {
4
+ baseUrl: string;
5
+ apiKey: string;
6
+ applicationId: string;
7
+ /** Gateway API version segment. Defaults to 'v1'. */
8
+ apiVersion?: string;
9
+ getAuthToken: () => string | null;
10
+ getTenantId: () => string | null;
11
+ /**
12
+ * Optional App Check token provider. When set, its resolved value is attached
13
+ * as the `X-Firebase-AppCheck` header on every request so first-party apps can
14
+ * pass App Check enforcement on the pre-login gateway endpoints. Async because
15
+ * the Firebase App Check SDK returns the token as a promise; returns null when
16
+ * App Check is not configured (the header is then simply omitted).
17
+ */
18
+ getAppCheckToken?: () => Promise<string | null>;
19
+ }
20
+ interface ApiRequestOptions {
21
+ method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
22
+ body?: unknown;
23
+ headers?: Record<string, string>;
24
+ skipAuth?: boolean;
25
+ }
26
+ declare class ApiClient {
27
+ private baseUrl;
28
+ private apiVersion;
29
+ private apiKey;
30
+ private applicationId;
31
+ private getAuthToken;
32
+ private getTenantId;
33
+ private getAppCheckToken?;
34
+ constructor(config: ApiClientConfig);
35
+ request<T>(endpoint: string, options?: ApiRequestOptions): Promise<T>;
36
+ private handleErrorResponse;
37
+ private mapStatusToCode;
38
+ get<T>(endpoint: string, options?: Omit<ApiRequestOptions, 'method' | 'body'>): Promise<T>;
39
+ post<T>(endpoint: string, body?: unknown, options?: Omit<ApiRequestOptions, 'method' | 'body'>): Promise<T>;
40
+ put<T>(endpoint: string, body?: unknown, options?: Omit<ApiRequestOptions, 'method' | 'body'>): Promise<T>;
41
+ patch<T>(endpoint: string, body?: unknown, options?: Omit<ApiRequestOptions, 'method' | 'body'>): Promise<T>;
42
+ delete<T>(endpoint: string, options?: Omit<ApiRequestOptions, 'method' | 'body'>): Promise<T>;
43
+ /**
44
+ * Execute a tenant-defined logic function by name via the logic service.
45
+ * This is NOT the gateway RPC dispatch — use `dispatch()` for Callable operations.
46
+ */
47
+ call<T>(functionName: string, data?: unknown): Promise<T>;
48
+ /**
49
+ * Invoke a platform Callable operation through the gateway RPC dispatch route
50
+ * (`POST /api/v<version>/call/:operation`). The operation key is the deployed
51
+ * Callable name (`<domain>-<name>` for namespaced groups, bare name for flat
52
+ * exports). The gateway expects the payload under a `data` envelope.
53
+ */
54
+ dispatch<T>(operation: string, payload?: unknown): Promise<T>;
55
+ /**
56
+ * Get the version-qualified base URL for direct API calls (e.g. streaming),
57
+ * including the `/api/<version>` segment.
58
+ */
59
+ getBaseUrl(): string;
60
+ /**
61
+ * Get auth headers for direct API calls (e.g., streaming)
62
+ */
63
+ getAuthHeaders(): Record<string, string>;
64
+ }
65
+
66
+ interface MAKEMINDSettlementConfig extends MAKEMINDConfig {
67
+ apiClient: ApiClient;
68
+ tenantId: () => string | null;
69
+ }
70
+ type SubscriptionStatus = 'active' | 'trialing' | 'past_due' | 'paused' | 'cancelled' | 'expired';
71
+ type BillingCycle = 'daily' | 'weekly' | 'monthly' | 'yearly' | 'oneTime';
72
+ interface Subscription {
73
+ id: string;
74
+ tenantId: string;
75
+ planId: string;
76
+ planName: string;
77
+ status: SubscriptionStatus;
78
+ billingCycle: BillingCycle;
79
+ currentPeriodStart: Date;
80
+ currentPeriodEnd: Date;
81
+ cancelAtPeriodEnd: boolean;
82
+ canceledAt?: Date;
83
+ pausedAt?: Date;
84
+ pauseUntil?: Date;
85
+ trialEnd?: Date;
86
+ discount?: {
87
+ couponCode: string;
88
+ percentOff?: number;
89
+ amountOff?: number;
90
+ expiresAt?: Date;
91
+ };
92
+ createdAt: Date;
93
+ updatedAt: Date;
94
+ }
95
+ interface SubscribeOptions {
96
+ planId: string;
97
+ billingCycle?: BillingCycle;
98
+ paymentMethodId?: string;
99
+ couponCode?: string;
100
+ startImmediately?: boolean;
101
+ trialDays?: number;
102
+ }
103
+ interface UpdateSubscriptionOptions {
104
+ planId?: string;
105
+ billingCycle?: BillingCycle;
106
+ prorate?: boolean;
107
+ }
108
+ interface CancelSubscriptionOptions {
109
+ reason?: string;
110
+ /** When false, cancels immediately. When true (default), cancels at period end. */
111
+ cancelAtPeriodEnd?: boolean;
112
+ }
113
+ interface PauseSubscriptionOptions {
114
+ reason?: string;
115
+ }
116
+ interface SubscriptionHistoryEntry {
117
+ id: string;
118
+ action: 'created' | 'updated' | 'canceled' | 'paused' | 'resumed' | 'reactivated';
119
+ previousPlanId?: string;
120
+ newPlanId?: string;
121
+ previousStatus?: SubscriptionStatus;
122
+ newStatus?: SubscriptionStatus;
123
+ reason?: string;
124
+ metadata?: Record<string, unknown>;
125
+ createdAt: Date;
126
+ }
127
+ interface SubscriptionChangePreview {
128
+ currentPlan: {
129
+ id: string;
130
+ name: string;
131
+ price: number;
132
+ };
133
+ newPlan: {
134
+ id: string;
135
+ name: string;
136
+ price: number;
137
+ };
138
+ proratedCredit: number;
139
+ proratedCharge: number;
140
+ immediateCharge: number;
141
+ nextBillingAmount: number;
142
+ nextBillingDate: Date;
143
+ }
144
+ type PaymentProvider = 'stripe' | 'paypal' | 'toss' | 'kakaoPay' | 'lemonSqueezy' | 'paddle' | 'apple' | 'google' | 'manual';
145
+ interface AddPaymentMethodData {
146
+ provider: PaymentProvider;
147
+ stripe?: {
148
+ customerId: string;
149
+ accountId: string;
150
+ };
151
+ manual?: {
152
+ externalRef: string;
153
+ label?: string;
154
+ metadata?: Record<string, unknown>;
155
+ };
156
+ toss?: {
157
+ customerKey: string;
158
+ authKey: string;
159
+ };
160
+ kakaoPay?: {
161
+ pgToken: string;
162
+ tid: string;
163
+ partnerUserId: string;
164
+ };
165
+ }
166
+ type AddPaymentMethodResponse = {
167
+ kind: 'stripeSetupIntent';
168
+ clientSecret: string;
169
+ setupIntentId: string;
170
+ customerId: string;
171
+ } | {
172
+ kind: 'redirect';
173
+ url: string;
174
+ provider: PaymentProvider;
175
+ } | {
176
+ kind: 'billingKey';
177
+ paymentAccountId: string;
178
+ provider: PaymentProvider;
179
+ } | {
180
+ kind: 'manualCreated';
181
+ paymentAccountId: string;
182
+ } | {
183
+ kind: 'inAppPurchase';
184
+ provider: 'apple' | 'google';
185
+ message: string;
186
+ };
187
+ declare class MAKEMINDSettlement {
188
+ private apiClient;
189
+ private getTenantId;
190
+ constructor(config: MAKEMINDSettlementConfig);
191
+ private get tenantId();
192
+ recordUsage(options: UsageEventOptions): Promise<void>;
193
+ /**
194
+ * Record a sale and distribute it to n recipients in one atomic posting.
195
+ *
196
+ * The revenue leg and every share leg commit together or not at all. Do not
197
+ * emulate this by recording the sale and then each share separately — that
198
+ * makes every partial-failure combination yours to recover, and a
199
+ * half-distributed sale cannot be repaired from outside the ledger.
200
+ *
201
+ * The split rule is the caller's: send the recipients and amounts you
202
+ * computed. Each cut is either a percentage or a fixed amount, and the two
203
+ * may be mixed; the combined claim may not exceed the sale. Recipients are settlement accounts, so the same call serves an
204
+ * End User seller, another party in the tenant, or a platform cut.
205
+ *
206
+ * Shares are floored to the currency's minor unit; the remainder stays with
207
+ * the receiving party. A share too small to express posts no leg and comes
208
+ * back as `0` / `null`.
209
+ */
210
+ recordSaleWithShares(options: {
211
+ provider: string;
212
+ providerTransactionId: string;
213
+ amount: number;
214
+ currency: string;
215
+ referenceType?: string;
216
+ referenceId?: string;
217
+ idempotencyKey?: string;
218
+ shares?: Array<{
219
+ toAccountId: string;
220
+ /** A proportional cut, `(0, 100]`. Exactly one of this or shareAmount. */
221
+ sharePercent?: number;
222
+ /** A fixed amount in the sale's currency. Does not scale with the sale. */
223
+ shareAmount?: number;
224
+ description?: string;
225
+ metadata?: Record<string, unknown>;
226
+ }>;
227
+ }): Promise<{
228
+ transactionId: string;
229
+ shareTransactionIds: (string | null)[];
230
+ shareAmounts: number[];
231
+ residue: number;
232
+ idempotent: boolean;
233
+ }>;
234
+ /**
235
+ * Reverse a split sale, clawing back each recipient's share in the same
236
+ * posting. Partial refunds claw back proportionally (floored, so a claw-back
237
+ * never exceeds what the recipient received; the difference is yours).
238
+ *
239
+ * Use this rather than a plain refund for anything recorded with
240
+ * `recordSaleWithShares` — otherwise the buyer is refunded while the shares
241
+ * stay paid out, and the ledger is short by exactly the shares.
242
+ */
243
+ reverseSaleWithShares(options: {
244
+ transactionId: string;
245
+ amount?: number;
246
+ reason?: string;
247
+ idempotencyKey: string;
248
+ }): Promise<{
249
+ refundTransactionId: string;
250
+ shareReversalIds: string[];
251
+ shareReversalAmounts: number[];
252
+ tenantBorne: number;
253
+ idempotent: boolean;
254
+ }>;
255
+ getUsageStats(options?: {
256
+ startDate?: string;
257
+ endDate?: string;
258
+ metric?: string;
259
+ }): Promise<UsageStats>;
260
+ getBillingSummary(): Promise<BillingSummary>;
261
+ getQuotaStatus(_resourceType?: string): Promise<{
262
+ quotas: Array<{
263
+ resource: string;
264
+ limit: number;
265
+ used: number;
266
+ remaining: number;
267
+ usagePercent: number;
268
+ }>;
269
+ }>;
270
+ listInvoices(options?: {
271
+ status?: 'draft' | 'pending' | 'paid' | 'overdue' | 'cancelled' | 'refunded';
272
+ limit?: number;
273
+ }): Promise<Invoice[]>;
274
+ getInvoice(invoiceId: string): Promise<Invoice>;
275
+ downloadInvoice(_invoiceId: string): Promise<{
276
+ url: string;
277
+ expiresIn: number;
278
+ }>;
279
+ getCurrentPlan(): Promise<{
280
+ id: string;
281
+ name: string;
282
+ features: string[];
283
+ limits: Record<string, number>;
284
+ }>;
285
+ listPlans(): Promise<Array<{
286
+ id: string;
287
+ name: string;
288
+ description: string;
289
+ price: number;
290
+ currency: string;
291
+ features: string[];
292
+ limits: Record<string, number>;
293
+ }>>;
294
+ changePlan(planId: string): Promise<void>;
295
+ /**
296
+ * Get current subscription details
297
+ */
298
+ getCurrentSubscription(): Promise<Subscription | null>;
299
+ /**
300
+ * Subscribe to a plan
301
+ */
302
+ subscribe(options: SubscribeOptions): Promise<Subscription>;
303
+ /**
304
+ * Update current subscription (e.g., change plan, billing cycle).
305
+ * The backend has no in-place PATCH; a plan update is implemented by creating
306
+ * a new subscription (which cancels the current one server-side). billingCycle
307
+ * and prorate are forwarded as metadata but only planId is acted upon today.
308
+ */
309
+ updateSubscription(options: UpdateSubscriptionOptions): Promise<Subscription>;
310
+ /**
311
+ * Cancel current subscription.
312
+ * Resolves the active subscriptionId first, then dispatches to
313
+ * settlement-cancelSubscription. Backend field is cancelImmediately (not
314
+ * cancelAtPeriodEnd); meaning is inverted — SDK default cancelAtPeriodEnd=true
315
+ * maps to cancelImmediately=false.
316
+ */
317
+ cancelSubscription(options?: CancelSubscriptionOptions): Promise<void>;
318
+ /**
319
+ * Pause subscription (if supported by plan).
320
+ * Backend accepts only { subscriptionId }; pauseUntil is not supported yet.
321
+ */
322
+ pauseSubscription(_options?: PauseSubscriptionOptions): Promise<void>;
323
+ /**
324
+ * Resume a paused subscription.
325
+ */
326
+ resumeSubscription(): Promise<Subscription>;
327
+ /**
328
+ * Reactivate a canceled subscription (before period end).
329
+ * Routes to settlement-resumeSubscription: fetches the most-recently-canceled
330
+ * subscription and resumes it. This is semantically equivalent for the
331
+ * cancel-at-period-end case where the subscription is still within its period.
332
+ */
333
+ reactivateSubscription(): Promise<Subscription>;
334
+ /**
335
+ * Get subscription history.
336
+ * TODO(gateway): no dedicated subscription history table/function exists in the
337
+ * backend. Requires a new settlement_subscription_events table or equivalent
338
+ * audit trail (scope: schema + backfill trigger + query function).
339
+ */
340
+ getSubscriptionHistory(_options?: {
341
+ limit?: number;
342
+ offset?: number;
343
+ }): Promise<SubscriptionHistoryEntry[]>;
344
+ /**
345
+ * Preview subscription change (get prorated amounts).
346
+ * TODO(gateway): proration calculation requires billing period overlap logic
347
+ * that is not yet implemented in the backend (scope: period credits, immediate
348
+ * charge delta, next-billing projection — needs a new onCall or REST endpoint).
349
+ */
350
+ previewSubscriptionChange(_newPlanId: string): Promise<SubscriptionChangePreview>;
351
+ /**
352
+ * Apply a coupon to current subscription.
353
+ * TODO(gateway): coupon engine (validation, redemption ledger, discount
354
+ * application) is not yet implemented (scope: coupon collection + validation
355
+ * function + subscription discount field update).
356
+ */
357
+ applyCoupon(_couponCode: string): Promise<{
358
+ success: boolean;
359
+ discount: number;
360
+ message: string;
361
+ }>;
362
+ getPaymentMethods(): Promise<Array<{
363
+ id: string;
364
+ type: 'card' | 'bankAccount';
365
+ last4: string;
366
+ isDefault: boolean;
367
+ }>>;
368
+ addPaymentMethod(data: AddPaymentMethodData): Promise<AddPaymentMethodResponse>;
369
+ removePaymentMethod(paymentAccountId: string): Promise<void>;
370
+ setDefaultPaymentMethod(paymentAccountId: string): Promise<void>;
371
+ recordProductCreation(productId: string): Promise<void>;
372
+ recordDocumentUpload(documentId: string, fileSizeMb: number): Promise<void>;
373
+ recordEcoSubmission(ecoId: string): Promise<void>;
374
+ recordMarketplaceBid(bidId: string, requestId: string): Promise<void>;
375
+ recordParticipantAdded(productId: string, participantTenantId: string): Promise<void>;
376
+ }
377
+
378
+ interface MAKEMINDConfig {
379
+ applicationId: string;
380
+ environment?: 'development' | 'staging' | 'production';
381
+ }
382
+ interface AuthUser {
383
+ uid: string;
384
+ email: string | null;
385
+ displayName: string | null;
386
+ photoURL: string | null;
387
+ tenantId: string;
388
+ roles: string[];
389
+ scopes: string[];
390
+ }
391
+ interface TenantClaims {
392
+ id: string;
393
+ roles: string[];
394
+ scopes: string[];
395
+ }
396
+ interface AuthStateCallback {
397
+ (user: AuthUser | null): void;
398
+ }
399
+ interface Tenant {
400
+ id: string;
401
+ name: string;
402
+ plan: string;
403
+ status: 'active' | 'suspended' | 'deleted';
404
+ settings?: Record<string, unknown>;
405
+ createdAt?: Date;
406
+ updatedAt?: Date;
407
+ }
408
+ interface TenantMember {
409
+ id: string;
410
+ userId: string;
411
+ tenantId: string;
412
+ role: string;
413
+ scopes: string[];
414
+ status: 'active' | 'invited' | 'suspended';
415
+ joinedAt?: Date;
416
+ }
417
+ interface Workspace {
418
+ id: string;
419
+ name: string;
420
+ description?: string;
421
+ parentId?: string;
422
+ createdAt?: Date;
423
+ }
424
+ interface QueryCondition {
425
+ field: string;
426
+ op: '==' | '!=' | '<' | '<=' | '>' | '>=' | 'in' | 'not-in' | 'array-contains' | 'array-contains-any';
427
+ value: unknown;
428
+ }
429
+ interface OrderBy {
430
+ field: string;
431
+ direction: 'asc' | 'desc';
432
+ }
433
+ interface QueryOptions {
434
+ collection: string;
435
+ where?: QueryCondition[];
436
+ orderBy?: OrderBy[];
437
+ limit?: number;
438
+ startAfter?: string;
439
+ }
440
+ interface QueryResult<T> {
441
+ data: T[];
442
+ metadata?: {
443
+ hasMore: boolean;
444
+ lastDocId?: string;
445
+ totalCount?: number;
446
+ };
447
+ }
448
+ interface DocumentResult<T> {
449
+ data: T;
450
+ id: string;
451
+ }
452
+ interface CreateOptions {
453
+ collection: string;
454
+ data: Record<string, unknown>;
455
+ documentId?: string;
456
+ }
457
+ interface UpdateOptions {
458
+ collection: string;
459
+ documentId: string;
460
+ data: Record<string, unknown>;
461
+ }
462
+ interface DeleteOptions {
463
+ collection: string;
464
+ documentId: string;
465
+ }
466
+ interface GetOptions {
467
+ collection: string;
468
+ documentId: string;
469
+ }
470
+ type SnapshotCallback<T> = (data: T | null) => void;
471
+ type CollectionSnapshotCallback<T> = (data: T[]) => void;
472
+ type Unsubscribe = () => void;
473
+ interface LogicCallResult {
474
+ executionId: string;
475
+ status: 'completed' | 'running' | 'failed';
476
+ output?: unknown;
477
+ error?: {
478
+ code: string;
479
+ message: string;
480
+ };
481
+ }
482
+ interface WorkflowTransitionOptions {
483
+ workflowName: string;
484
+ documentId: string;
485
+ action: string;
486
+ data?: Record<string, unknown>;
487
+ }
488
+ interface SendMessageOptions {
489
+ template: string;
490
+ recipients: string[];
491
+ data: Record<string, unknown>;
492
+ channels?: ('push' | 'email' | 'sms')[];
493
+ }
494
+ interface Notification {
495
+ id: string;
496
+ title: string;
497
+ body: string;
498
+ data?: Record<string, unknown>;
499
+ read: boolean;
500
+ createdAt: Date;
501
+ }
502
+ interface UsageEventOptions {
503
+ eventType: string;
504
+ resourceId: string;
505
+ quantity?: number;
506
+ metadata?: Record<string, unknown>;
507
+ }
508
+ interface UsageStats {
509
+ period: string;
510
+ events: Record<string, number>;
511
+ totalUsage: number;
512
+ }
513
+ interface BillingSummary {
514
+ currentBalance: number;
515
+ pendingCharges: number;
516
+ currency: string;
517
+ plan: string;
518
+ }
519
+ interface Invoice {
520
+ id: string;
521
+ amount: number;
522
+ currency: string;
523
+ status: 'draft' | 'pending' | 'paid' | 'overdue' | 'cancelled' | 'refunded';
524
+ periodStart: Date;
525
+ periodEnd: Date;
526
+ createdAt: Date;
527
+ }
528
+ interface PlatformErrorDetails {
529
+ code: string;
530
+ message: string;
531
+ details?: Record<string, unknown>;
532
+ }
533
+
534
+ interface MAKEMINDAuthConfig extends MAKEMINDConfig {
535
+ apiClient: ApiClient;
536
+ onAuthStateChange: (user: AuthUser | null) => void;
537
+ setAuthToken: (token: string | null) => void;
538
+ }
539
+ interface TenantMembership {
540
+ tenantId: string;
541
+ tenantName: string;
542
+ tenantDisplayName: string;
543
+ roles: string[];
544
+ status: string;
545
+ }
546
+ declare class MAKEMINDAuth {
547
+ private apiClient;
548
+ private applicationId;
549
+ private onAuthStateChange;
550
+ private setAuthToken;
551
+ private _currentUser;
552
+ private _memberships;
553
+ private refreshToken;
554
+ private authStateCallbacks;
555
+ constructor(config: MAKEMINDAuthConfig);
556
+ private restoreSession;
557
+ private persistSession;
558
+ private clearStoredSession;
559
+ get currentUser(): AuthUser | null;
560
+ get memberships(): TenantMembership[];
561
+ /**
562
+ * Set the session directly from an externally-obtained token — e.g. a Firebase
563
+ * ID token from Google sign-in, which the gateway accepts as a Bearer. Mirrors
564
+ * the post-authentication state update of signInWithEmail (set token, persist
565
+ * to localStorage, notify auth-state listeners) without a /auth/signin
566
+ * round-trip. Also used by the console's token-refresh bridge to swap in a
567
+ * freshly-refreshed Firebase token. Existing memberships are preserved when
568
+ * `memberships` is omitted.
569
+ */
570
+ setSession(user: AuthUser, token: string, refreshToken: string, memberships?: TenantMembership[]): void;
571
+ /**
572
+ * Load the caller's tenant memberships into the session.
573
+ *
574
+ * `signInWithEmail` gets them in its response, but a session established from
575
+ * an external credential (a Firebase ID token from a Google popup) has no
576
+ * such response — it arrives with claims only. Claims carry the *current*
577
+ * tenant, not the list, and a platform admin's claims carry no tenant roles
578
+ * at all, so a console that gates its navigation on `admin`/`owner` shows an
579
+ * almost empty menu until this runs.
580
+ *
581
+ * @return {Promise<TenantMembership[]>} The loaded memberships.
582
+ */
583
+ loadMemberships(): Promise<TenantMembership[]>;
584
+ signInWithEmail(email: string, password: string): Promise<AuthUser>;
585
+ signInWithEmailAndPassword(email: string, password: string): Promise<AuthUser>;
586
+ signUp(email: string, password: string, options?: {
587
+ displayName?: string;
588
+ phoneNumber?: string;
589
+ }): Promise<AuthUser>;
590
+ signOut(): Promise<void>;
591
+ sendPasswordResetEmail(email: string): Promise<void>;
592
+ onAuthStateChanged(callback: AuthStateCallback): () => void;
593
+ private notifyAuthStateCallbacks;
594
+ refreshAuthToken(): Promise<void>;
595
+ switchTenant(tenantId: string): Promise<AuthUser>;
596
+ getUserMemberships(): Promise<{
597
+ tenantId: string;
598
+ tenantName: string;
599
+ roles: string[];
600
+ status: string;
601
+ }[]>;
602
+ hasScope(scope: string): boolean;
603
+ hasRole(role: string): boolean;
604
+ hasAnyRole(roles: string[]): boolean;
605
+ hasAllScopes(scopes: string[]): boolean;
606
+ /**
607
+ * Get the current ID token for use with external services
608
+ */
609
+ getIdToken(forceRefresh?: boolean): Promise<string | null>;
610
+ /**
611
+ * Update the current user's password.
612
+ * Backend dispatch 'updatePassword' → data { currentPassword, newPassword }.
613
+ */
614
+ updatePassword(currentPassword: string, newPassword: string): Promise<void>;
615
+ /**
616
+ * Send email verification.
617
+ * Backend dispatch 'resendVerificationEmail' — uid resolved from auth context, no payload needed.
618
+ */
619
+ sendEmailVerification(): Promise<void>;
620
+ /**
621
+ * Verify email with code
622
+ */
623
+ verifyEmail(code: string): Promise<void>;
624
+ /**
625
+ * Confirm password reset with code
626
+ */
627
+ confirmPasswordReset(code: string, newPassword: string): Promise<void>;
628
+ /**
629
+ * OAuth redirect-based sign-in is NOT supported by this backend.
630
+ * The backend has no /oauth/initiate or /oauth/callback routes.
631
+ * Use signInWithOAuthToken() with a provider-issued ID token instead,
632
+ * or use the Firebase Client SDK directly for OAuth redirect flows.
633
+ */
634
+ signInWithOAuth(_provider: 'google' | 'apple' | 'github' | 'microsoft'): Promise<{
635
+ redirectUrl: string;
636
+ }>;
637
+ /**
638
+ * OAuth redirect callback handling is NOT supported by this backend.
639
+ * Use signInWithOAuthToken() with a provider-issued ID token instead,
640
+ * or use the Firebase Client SDK directly for OAuth redirect flows.
641
+ */
642
+ handleOAuthCallback(_code: string, _state: string): Promise<AuthUser>;
643
+ /**
644
+ * Sign in with OAuth ID token directly (for native apps)
645
+ * Use this when you have already obtained the ID token from the OAuth provider
646
+ */
647
+ signInWithOAuthToken(provider: 'google' | 'apple' | 'github' | 'microsoft', idToken: string): Promise<AuthUser>;
648
+ /**
649
+ * OAuth redirect-based account linking is NOT supported by this backend.
650
+ * The backend has no /oauth/link/initiate route.
651
+ * Use the Firebase Client SDK linkWithRedirect() or linkWithPopup() instead.
652
+ */
653
+ linkWithOAuth(_provider: 'google' | 'apple' | 'github' | 'microsoft'): Promise<{
654
+ redirectUrl: string;
655
+ }>;
656
+ /**
657
+ * OAuth redirect link callback is NOT supported by this backend.
658
+ * The backend has no /oauth/link/callback route.
659
+ * Use the Firebase Client SDK for OAuth redirect link flows.
660
+ */
661
+ handleOAuthLinkCallback(_code: string, _state: string): Promise<void>;
662
+ /**
663
+ * Unlink OAuth provider from current account
664
+ */
665
+ unlinkOAuth(provider: 'google' | 'apple' | 'github' | 'microsoft'): Promise<void>;
666
+ /**
667
+ * Get linked OAuth providers for current user
668
+ */
669
+ getLinkedProviders(): Promise<string[]>;
670
+ updateCurrentUser(userData: {
671
+ uid: string;
672
+ email: string;
673
+ displayName?: string | null;
674
+ tenantId: string;
675
+ roles: string[];
676
+ scopes: string[];
677
+ }, membership?: TenantMembership): void;
678
+ }
679
+
680
+ interface MAKEMINDDataConfig extends MAKEMINDConfig {
681
+ apiClient: ApiClient;
682
+ tenantId: () => string | null;
683
+ }
684
+ declare class MAKEMINDData {
685
+ private apiClient;
686
+ private applicationId;
687
+ private getTenantId;
688
+ private subscriptions;
689
+ constructor(config: MAKEMINDDataConfig);
690
+ private get tenantId();
691
+ query<T = Record<string, unknown>>(options: QueryOptions): Promise<QueryResult<T>>;
692
+ get<T = Record<string, unknown>>(options: GetOptions): Promise<DocumentResult<T> | null>;
693
+ create<T = Record<string, unknown>>(options: CreateOptions): Promise<DocumentResult<T>>;
694
+ update(options: UpdateOptions): Promise<void>;
695
+ delete(options: DeleteOptions): Promise<void>;
696
+ onSnapshot<T = Record<string, unknown>>(options: GetOptions, callback: SnapshotCallback<T>): Unsubscribe;
697
+ onCollectionSnapshot<T = Record<string, unknown>>(options: QueryOptions, callback: CollectionSnapshotCallback<T>): Unsubscribe;
698
+ private createSubscription;
699
+ private createCollectionSubscription;
700
+ private pollForUpdates;
701
+ private closeSubscription;
702
+ collectionGroupQuery<T = Record<string, unknown>>(_options: Omit<QueryOptions, 'collection'> & {
703
+ collection: string;
704
+ }): Promise<QueryResult<T>>;
705
+ queryTenant<T = Record<string, unknown>>(collectionName: string, additionalConditions?: QueryCondition[], orderByOptions?: OrderBy[], limitCount?: number): Promise<QueryResult<T>>;
706
+ batchCreate<T = Record<string, unknown>>(collection: string, documents: Array<{
707
+ data: Record<string, unknown>;
708
+ documentId?: string;
709
+ }>): Promise<Array<DocumentResult<T>>>;
710
+ batchUpdate(collection: string, updates: Array<{
711
+ documentId: string;
712
+ data: Record<string, unknown>;
713
+ }>): Promise<void>;
714
+ batchDelete(collection: string, documentIds: string[]): Promise<void>;
715
+ exportCollection(options: {
716
+ collection: string;
717
+ format?: 'json' | 'csv';
718
+ filter?: Record<string, unknown>;
719
+ }): Promise<{
720
+ jobId: string;
721
+ status: string;
722
+ }>;
723
+ importCollection(options: {
724
+ collection: string;
725
+ sourcePath: string;
726
+ format?: 'json' | 'csv';
727
+ upsert?: boolean;
728
+ }): Promise<{
729
+ jobId: string;
730
+ status: string;
731
+ }>;
732
+ getExportStatus(jobId: string): Promise<{
733
+ jobId: string;
734
+ status: 'pending' | 'running' | 'completed' | 'failed';
735
+ documentCount?: number;
736
+ downloadUrl?: string;
737
+ error?: string;
738
+ completedAt?: unknown;
739
+ }>;
740
+ getImportStatus(jobId: string): Promise<{
741
+ jobId: string;
742
+ status: 'pending' | 'validating' | 'running' | 'completed' | 'failed';
743
+ totalRecords?: number;
744
+ processedRecords?: number;
745
+ skippedRecords?: number;
746
+ failedRecords?: number;
747
+ error?: string;
748
+ completedAt?: unknown;
749
+ }>;
750
+ aggregate(options: {
751
+ collection: string;
752
+ filters?: QueryCondition[];
753
+ aggregations: Array<{
754
+ type: 'count' | 'sum' | 'avg' | 'min' | 'max';
755
+ field?: string;
756
+ alias: string;
757
+ }>;
758
+ }): Promise<{
759
+ results: Record<string, unknown>;
760
+ documentCount: number;
761
+ }>;
762
+ search<T = Record<string, unknown>>(options: {
763
+ collection: string;
764
+ query: string;
765
+ fields: string[];
766
+ limit?: number;
767
+ }): Promise<{
768
+ results: Array<T & {
769
+ _score: number;
770
+ }>;
771
+ total: number;
772
+ }>;
773
+ }
774
+
775
+ interface MAKEMINDLogicConfig extends MAKEMINDConfig {
776
+ apiClient: ApiClient;
777
+ tenantId: () => string | null;
778
+ }
779
+ interface FlowDefinition {
780
+ id?: string;
781
+ name: string;
782
+ description: string;
783
+ mode: 'form' | 'code';
784
+ trigger: {
785
+ type: 'event' | 'schedule' | 'manual' | 'webhook' | 'data';
786
+ [key: string]: unknown;
787
+ };
788
+ definition: unknown;
789
+ variables?: Record<string, unknown>;
790
+ }
791
+ /**
792
+ * A row of `GET /logic/flows`, as the gateway actually answers it.
793
+ *
794
+ * This declared six fields while the route returns eighteen, so every consumer
795
+ * that needed `publicExecution` or `mode` cast the row to read them — the
796
+ * portal does exactly that. A type that under-describes a payload does not
797
+ * protect the caller; it just moves the reading of it out of the type system.
798
+ *
799
+ * `status` said `'active'`, which the route never sends: a published flow is
800
+ * stored and returned as `'published'` (logic/service/flows.ts). Consumers
801
+ * translating `'active' -> 'published'` were translating a value that never
802
+ * arrives.
803
+ */
804
+ interface ListFlowsParams {
805
+ status?: 'draft' | 'published' | 'disabled' | 'archived';
806
+ mode?: 'form' | 'code' | 'hybrid';
807
+ /** Rows per page. The gateway caps this at 100 and defaults to it. */
808
+ limit?: number;
809
+ /** `nextCursor` from a previous page. */
810
+ cursor?: string;
811
+ }
812
+ interface ListFlowsResult {
813
+ flows: FlowListItem[];
814
+ /** True when the server had more rows than this page carries. */
815
+ hasMore: boolean;
816
+ nextCursor?: string;
817
+ }
818
+ interface FlowListItem {
819
+ id: string;
820
+ name: string;
821
+ description: string;
822
+ status: 'draft' | 'published' | 'archived';
823
+ mode?: 'form' | 'code' | 'hybrid';
824
+ trigger?: unknown;
825
+ definition?: unknown;
826
+ variables?: unknown;
827
+ isSubflow?: boolean;
828
+ inputSchema?: unknown;
829
+ outputSchema?: unknown;
830
+ /** Whether the flow may be executed from a published app without a session. */
831
+ publicExecution?: boolean;
832
+ partyInput?: unknown;
833
+ durable?: boolean;
834
+ currentVersion?: number;
835
+ publishedVersion?: number;
836
+ createdAt: Date;
837
+ updatedAt: Date;
838
+ }
839
+ declare class MAKEMINDLogic {
840
+ private apiClient;
841
+ private getTenantId;
842
+ constructor(config: MAKEMINDLogicConfig);
843
+ transition(options: WorkflowTransitionOptions): Promise<LogicCallResult>;
844
+ call(functionName: string, input?: unknown): Promise<LogicCallResult>;
845
+ executeFlow(flowId: string, input?: unknown, options?: {
846
+ idempotencyKey?: string;
847
+ }): Promise<LogicCallResult>;
848
+ getExecution(executionId: string): Promise<{
849
+ id: string;
850
+ flowId: string;
851
+ status: string;
852
+ startedAt: Date;
853
+ completedAt?: Date;
854
+ output?: unknown;
855
+ error?: {
856
+ code: string;
857
+ message: string;
858
+ };
859
+ }>;
860
+ listExecutions(options?: {
861
+ flowId?: string;
862
+ status?: string;
863
+ limit?: number;
864
+ startAfter?: string;
865
+ }): Promise<{
866
+ executions: Array<{
867
+ id: string;
868
+ flowId: string;
869
+ status: string;
870
+ startedAt: Date;
871
+ completedAt?: Date;
872
+ }>;
873
+ nextCursor?: string;
874
+ hasMore: boolean;
875
+ }>;
876
+ sendSignal(executionId: string, signalName: string, payload?: unknown): Promise<{
877
+ success: boolean;
878
+ }>;
879
+ /**
880
+ * Cancel a running workflow execution
881
+ */
882
+ cancelWorkflow(executionId: string, reason?: string): Promise<{
883
+ success: boolean;
884
+ }>;
885
+ /**
886
+ * Retry a failed workflow execution
887
+ */
888
+ retryWorkflow(executionId: string): Promise<{
889
+ success: boolean;
890
+ newExecutionId: string;
891
+ }>;
892
+ /**
893
+ * Pause a running workflow execution
894
+ */
895
+ pauseWorkflow(executionId: string): Promise<{
896
+ success: boolean;
897
+ }>;
898
+ /**
899
+ * Resume a paused workflow execution
900
+ */
901
+ resumeWorkflow(executionId: string): Promise<{
902
+ success: boolean;
903
+ }>;
904
+ ecoTransition(ecoId: string, action: 'submit' | 'approve' | 'reject' | 'implement' | 'recall', data?: Record<string, unknown>): Promise<LogicCallResult>;
905
+ ncrTransition(issueId: string, action: 'assignContainment' | 'analyze' | 'defineCorrective' | 'implement' | 'verifyEffective' | 'close', data?: Record<string, unknown>): Promise<LogicCallResult>;
906
+ bidTransition(requestId: string, bidId: string, action: 'submit' | 'approve' | 'reject' | 'withdraw', data?: Record<string, unknown>): Promise<LogicCallResult>;
907
+ gateApproval(productId: string, gate: 'production' | 'sales' | 'custom', action: 'approve' | 'reject', comment?: string): Promise<LogicCallResult>;
908
+ accessDocument(documentId: string, action: 'view' | 'download' | 'print'): Promise<{
909
+ url: string;
910
+ expiresIn: number;
911
+ }>;
912
+ createFlow(flow: Omit<FlowDefinition, 'id'>): Promise<{
913
+ id: string;
914
+ }>;
915
+ updateFlow(flowId: string, updates: Partial<FlowDefinition>): Promise<void>;
916
+ publishFlow(flowId: string): Promise<void>;
917
+ archiveFlow(flowId: string): Promise<void>;
918
+ /**
919
+ * A page of the tenant's flows.
920
+ *
921
+ * Took no arguments and returned a bare array, so a caller wanting one
922
+ * state — published flows, to offer as event handlers — pulled every state
923
+ * and filtered locally. The server has always been able to filter; asking
924
+ * it to means the page is spent on rows the caller wants.
925
+ *
926
+ * `hasMore` is returned rather than implied. A full page and a truncated
927
+ * one are the same array, and a caller that cannot tell them apart quietly
928
+ * drops whatever did not fit.
929
+ */
930
+ listFlows(params?: ListFlowsParams): Promise<ListFlowsResult>;
931
+ getFlow(flowId: string): Promise<FlowDefinition>;
932
+ testFlow(flowId: string, testInput: unknown): Promise<LogicCallResult>;
933
+ cloneFlow(flowId: string, newName: string): Promise<{
934
+ id: string;
935
+ }>;
936
+ listVariables(): Promise<Array<{
937
+ id: string;
938
+ name: string;
939
+ type: 'string' | 'number' | 'boolean' | 'json' | 'secret';
940
+ value?: unknown;
941
+ isSecret: boolean;
942
+ createdAt: Date;
943
+ updatedAt: Date;
944
+ }>>;
945
+ getVariable(variableId: string): Promise<{
946
+ id: string;
947
+ name: string;
948
+ type: 'string' | 'number' | 'boolean' | 'json' | 'secret';
949
+ value?: unknown;
950
+ isSecret: boolean;
951
+ }>;
952
+ createVariable(data: {
953
+ name: string;
954
+ type: 'string' | 'number' | 'boolean' | 'json' | 'secret';
955
+ value: unknown;
956
+ description?: string;
957
+ }): Promise<{
958
+ id: string;
959
+ }>;
960
+ updateVariable(variableId: string, data: {
961
+ value?: unknown;
962
+ description?: string;
963
+ }): Promise<void>;
964
+ deleteVariable(variableId: string): Promise<void>;
965
+ listTemplates(): Promise<Array<{
966
+ id: string;
967
+ name: string;
968
+ description: string;
969
+ category: string;
970
+ isPublic: boolean;
971
+ createdAt: Date;
972
+ }>>;
973
+ getTemplate(templateId: string): Promise<{
974
+ id: string;
975
+ name: string;
976
+ description: string;
977
+ definition: unknown;
978
+ variables: Array<{
979
+ name: string;
980
+ type: string;
981
+ defaultValue?: unknown;
982
+ }>;
983
+ }>;
984
+ createFlowFromTemplate(templateId: string, data: {
985
+ name: string;
986
+ description?: string;
987
+ variables?: Record<string, unknown>;
988
+ }): Promise<{
989
+ flowId: string;
990
+ }>;
991
+ listWebhooks(): Promise<Array<{
992
+ id: string;
993
+ name: string;
994
+ url: string;
995
+ flowId: string;
996
+ isActive: boolean;
997
+ createdAt: Date;
998
+ }>>;
999
+ createWebhook(data: {
1000
+ name: string;
1001
+ flowId: string;
1002
+ description?: string;
1003
+ }): Promise<{
1004
+ id: string;
1005
+ url: string;
1006
+ secret: string;
1007
+ }>;
1008
+ deleteWebhook(webhookId: string): Promise<void>;
1009
+ rotateWebhookSecret(webhookId: string): Promise<{
1010
+ secret: string;
1011
+ }>;
1012
+ listPendingApprovals(): Promise<Array<{
1013
+ id: string;
1014
+ executionId: string;
1015
+ flowName: string;
1016
+ requestedBy: string;
1017
+ requestedAt: Date;
1018
+ expiresAt?: Date;
1019
+ }>>;
1020
+ approveRequest(approvalId: string, comment?: string): Promise<void>;
1021
+ rejectRequest(approvalId: string, reason: string): Promise<void>;
1022
+ listDataTriggers(): Promise<Array<{
1023
+ id: string;
1024
+ name: string;
1025
+ collection: string;
1026
+ operation: 'create' | 'update' | 'delete';
1027
+ flowId: string;
1028
+ isActive: boolean;
1029
+ }>>;
1030
+ createDataTrigger(data: {
1031
+ name: string;
1032
+ collection: string;
1033
+ operation: 'create' | 'update' | 'delete';
1034
+ flowId: string;
1035
+ conditions?: Array<{
1036
+ field: string;
1037
+ operator: string;
1038
+ value: unknown;
1039
+ }>;
1040
+ }): Promise<{
1041
+ id: string;
1042
+ }>;
1043
+ deleteDataTrigger(triggerId: string): Promise<void>;
1044
+ toggleDataTrigger(triggerId: string, isActive: boolean): Promise<void>;
1045
+ generateFlowFromPrompt(prompt: string): Promise<{
1046
+ suggestedFlow: FlowDefinition;
1047
+ explanation: string;
1048
+ }>;
1049
+ explainFlow(flowId: string): Promise<{
1050
+ summary: string;
1051
+ steps: Array<{
1052
+ step: number;
1053
+ description: string;
1054
+ }>;
1055
+ suggestedImprovements?: string[];
1056
+ }>;
1057
+ }
1058
+
1059
+ interface MAKEMINDTenantConfig extends MAKEMINDConfig {
1060
+ apiClient: ApiClient;
1061
+ tenantId: () => string | null;
1062
+ /**
1063
+ * Called after a tenant is created so the client can activate the new tenant
1064
+ * context (set the active tenant id and refresh the session token so the new
1065
+ * tenant's claims take effect immediately).
1066
+ */
1067
+ onTenantCreated?: (tenantId: string, customToken?: string) => Promise<void>;
1068
+ }
1069
+ declare class MAKEMINDTenant {
1070
+ private apiClient;
1071
+ private getTenantId;
1072
+ private onTenantCreated?;
1073
+ constructor(config: MAKEMINDTenantConfig);
1074
+ private get tenantId();
1075
+ createTenant(data: {
1076
+ name: string;
1077
+ plan?: string;
1078
+ industryType?: string;
1079
+ /**
1080
+ * 'test' creates a sandbox tenant: usage is recorded non-billable and rate
1081
+ * limits are capped at the sandbox tier — use it to run conformance/
1082
+ * integration checks without incurring cost. Defaults to 'live'.
1083
+ */
1084
+ mode?: 'test' | 'live';
1085
+ settings?: {
1086
+ displayName?: string;
1087
+ type?: string;
1088
+ [key: string]: unknown;
1089
+ };
1090
+ }): Promise<{
1091
+ id: string;
1092
+ name: string;
1093
+ workspaceId: string;
1094
+ status: string;
1095
+ user?: {
1096
+ uid: string;
1097
+ email: string;
1098
+ displayName: string | null;
1099
+ tenantId: string;
1100
+ roles: string[];
1101
+ scopes: string[];
1102
+ };
1103
+ customToken?: string;
1104
+ }>;
1105
+ getCurrent(): Promise<Tenant | null>;
1106
+ getTenant(tenantId: string): Promise<Tenant | null>;
1107
+ onTenantSnapshot(callback: (tenant: Tenant | null) => void): Unsubscribe;
1108
+ updateTenant(updates: {
1109
+ displayName?: string;
1110
+ settings?: Record<string, unknown>;
1111
+ }): Promise<void>;
1112
+ listMembers(): Promise<TenantMember[]>;
1113
+ inviteMember(data: {
1114
+ email: string;
1115
+ roles: string[];
1116
+ scopes?: string[];
1117
+ }): Promise<void>;
1118
+ updateMember(userId: string, updates: {
1119
+ roles?: string[];
1120
+ scopes?: string[];
1121
+ }): Promise<void>;
1122
+ removeMember(userId: string): Promise<void>;
1123
+ listWorkspaces(): Promise<Workspace[]>;
1124
+ createWorkspace(data: {
1125
+ name: string;
1126
+ displayName: string;
1127
+ settings?: Record<string, unknown>;
1128
+ type?: 'default' | 'development' | 'staging' | 'production';
1129
+ }): Promise<{
1130
+ workspaceId: string;
1131
+ }>;
1132
+ updateWorkspace(workspaceId: string, updates: {
1133
+ displayName?: string;
1134
+ settings?: Record<string, unknown>;
1135
+ }): Promise<{
1136
+ success: boolean;
1137
+ }>;
1138
+ deleteWorkspace(workspaceId: string): Promise<{
1139
+ success: boolean;
1140
+ }>;
1141
+ }
1142
+
1143
+ interface RegisterDeviceOptions {
1144
+ platform: 'ios' | 'android' | 'web';
1145
+ deviceId?: string;
1146
+ }
1147
+ interface PushMessage {
1148
+ messageId: string;
1149
+ title?: string;
1150
+ body: string;
1151
+ data?: Record<string, string>;
1152
+ }
1153
+ interface MAKEMINDMessagingConfig extends MAKEMINDConfig {
1154
+ apiClient: ApiClient;
1155
+ tenantId: () => string | null;
1156
+ userId: () => string | null;
1157
+ firebaseApp?: FirebaseApp;
1158
+ vapidKey?: string;
1159
+ }
1160
+ declare class MAKEMINDMessaging {
1161
+ private apiClient;
1162
+ private applicationId;
1163
+ private getTenantId;
1164
+ private getUserId;
1165
+ private firebaseApp?;
1166
+ private vapidKey?;
1167
+ private messaging?;
1168
+ private currentDeviceId?;
1169
+ constructor(config: MAKEMINDMessagingConfig);
1170
+ private get tenantId();
1171
+ private get userId();
1172
+ private getMessaging;
1173
+ private generateDeviceId;
1174
+ /**
1175
+ * Send a message using a template via the sendBatchMessages onCall.
1176
+ * Maps SDK SendMessageOptions to the batch service: one call per channel.
1177
+ */
1178
+ send(options: SendMessageOptions): Promise<{
1179
+ messageId: string;
1180
+ }>;
1181
+ /**
1182
+ * Send notification to specific users across channels.
1183
+ * Uses sendBatchMessages onCall (one dispatch per channel).
1184
+ */
1185
+ notify(userIds: string[], notification: {
1186
+ title: string;
1187
+ body: string;
1188
+ data?: Record<string, unknown>;
1189
+ channels?: ('push' | 'email' | 'sms')[];
1190
+ }): Promise<{
1191
+ messageId: string;
1192
+ }>;
1193
+ /**
1194
+ * Register device for push notifications.
1195
+ * SDK internally handles token acquisition (Firebase FCM).
1196
+ * Uses the REST /messaging/devices route (already correct).
1197
+ */
1198
+ registerDevice(options: RegisterDeviceOptions): Promise<{
1199
+ deviceId: string;
1200
+ }>;
1201
+ /**
1202
+ * Internal: Acquire push token from the platform's push service.
1203
+ * Currently uses Firebase FCM, abstracted for future cloud-agnostic support.
1204
+ */
1205
+ private acquirePushToken;
1206
+ /**
1207
+ * Unregister device from push notifications.
1208
+ * Uses the REST DELETE /messaging/devices/:token route.
1209
+ * The route key is the raw FCM token (server base64-encodes it to deviceId).
1210
+ */
1211
+ unregisterDevice(deviceId: string): Promise<void>;
1212
+ /**
1213
+ * Listen for foreground push messages.
1214
+ */
1215
+ onPushMessage(callback: (message: PushMessage) => void): Unsubscribe;
1216
+ /**
1217
+ * Get in-app notifications for the current user.
1218
+ * Dispatch op: messaging-getInAppNotifications
1219
+ * Service contract: { userId?, unreadOnly?, limit?, cursor? }
1220
+ * Response: { notifications, hasMore, nextCursor }
1221
+ */
1222
+ getNotifications(options?: {
1223
+ unreadOnly?: boolean;
1224
+ limit?: number;
1225
+ cursor?: string;
1226
+ }): Promise<{
1227
+ notifications: Notification[];
1228
+ nextCursor?: string;
1229
+ }>;
1230
+ /**
1231
+ * Get in-app notifications stream (polling-based).
1232
+ */
1233
+ onNotifications(callback: (notifications: Notification[]) => void, options?: {
1234
+ unreadOnly?: boolean;
1235
+ limitCount?: number;
1236
+ }): Unsubscribe;
1237
+ /**
1238
+ * Get unread notification count.
1239
+ * Dispatch op: messaging-getUnreadNotificationCount (the verified onCall service).
1240
+ * Response: { userId, unreadCount }
1241
+ */
1242
+ getUnreadCount(): Promise<number>;
1243
+ /**
1244
+ * Get unread notification count stream (polling-based).
1245
+ */
1246
+ onUnreadCount(callback: (count: number) => void): Unsubscribe;
1247
+ /**
1248
+ * Mark a notification as read.
1249
+ * Dispatch op: messaging-markNotificationRead
1250
+ * Service contract: { notificationId } or { notificationIds }
1251
+ */
1252
+ markAsRead(notificationId: string): Promise<void>;
1253
+ /**
1254
+ * Mark all notifications as read for the current user.
1255
+ * Dispatch op: messaging-markAllNotificationsRead (new onCall — no existing match).
1256
+ * Implemented in backend send.ts + service/send.ts below.
1257
+ */
1258
+ markAllAsRead(): Promise<void>;
1259
+ /**
1260
+ * Notify ECO reviewers.
1261
+ */
1262
+ notifyEcoReviewers(eco: {
1263
+ requestNumber: string;
1264
+ title: string;
1265
+ priority: string;
1266
+ productCode?: string;
1267
+ }, reviewerIds: string[]): Promise<{
1268
+ messageId: string;
1269
+ }>;
1270
+ /**
1271
+ * Notify quality issue critical.
1272
+ */
1273
+ notifyQualityCritical(issue: {
1274
+ issueNumber: string;
1275
+ title: string;
1276
+ severity: string;
1277
+ }, recipientIds: string[]): Promise<{
1278
+ messageId: string;
1279
+ }>;
1280
+ /**
1281
+ * Notify bid received.
1282
+ */
1283
+ notifyBidReceived(request: {
1284
+ requestNumber: string;
1285
+ title: string;
1286
+ }, bidder: {
1287
+ name: string;
1288
+ }, ownerId: string): Promise<{
1289
+ messageId: string;
1290
+ }>;
1291
+ /**
1292
+ * List available message templates.
1293
+ * Dispatch op: messaging-msgGetTemplates (the verified onCall service).
1294
+ * Service contract: { channelType? }
1295
+ * Response: { templates }
1296
+ */
1297
+ listTemplates(options?: {
1298
+ channel?: 'push' | 'email' | 'sms';
1299
+ status?: 'active' | 'draft';
1300
+ }): Promise<MessageTemplate[]>;
1301
+ /**
1302
+ * Get a specific template by ID.
1303
+ * Dispatch op: messaging-msgGetTemplate
1304
+ * Service contract: { templateId }
1305
+ * Response: template document (FirebaseFirestore.DocumentData)
1306
+ */
1307
+ getTemplate(templateId: string): Promise<MessageTemplate>;
1308
+ /**
1309
+ * Create a new message template.
1310
+ * Dispatch op: messaging-msgCreateTemplate
1311
+ * Service contract: { name, channelType, subject?, body, bodyHtml?, language?, variables?, description? }
1312
+ * Response: { templateId }
1313
+ * Note: backend returns { templateId }; SDK surface returns full MessageTemplate.
1314
+ * We re-fetch the created template to satisfy the return type.
1315
+ */
1316
+ createTemplate(template: CreateTemplateOptions): Promise<MessageTemplate>;
1317
+ /**
1318
+ * Update an existing template.
1319
+ * Dispatch op: messaging-msgUpdateTemplate
1320
+ * Service contract: { templateId, subject?, body?, bodyHtml?, language?, variables?, description? }
1321
+ * Response: { success }
1322
+ * We re-fetch the updated template to satisfy the return type.
1323
+ */
1324
+ updateTemplate(templateId: string, updates: Partial<CreateTemplateOptions>): Promise<MessageTemplate>;
1325
+ /**
1326
+ * Delete a template.
1327
+ * Dispatch op: messaging-msgDeleteTemplate
1328
+ * Service contract: { templateId }
1329
+ * Response: { success }
1330
+ */
1331
+ deleteTemplate(templateId: string): Promise<void>;
1332
+ /**
1333
+ * Subscribe to a topic for push notifications.
1334
+ * Dispatch op: messaging-subscribeToTopic
1335
+ * Service contract: { token, topic, tenantId }
1336
+ * Token is acquired from the current device registration.
1337
+ * If no token is available, the subscription request is sent with userId context only.
1338
+ */
1339
+ subscribeToTopic(topic: string): Promise<void>;
1340
+ /**
1341
+ * Unsubscribe from a topic.
1342
+ * Dispatch op: messaging-unsubscribeFromTopic
1343
+ * Service contract: { token, topic, tenantId }
1344
+ */
1345
+ unsubscribeFromTopic(topic: string): Promise<void>;
1346
+ /**
1347
+ * List subscribed topics for the current user.
1348
+ * Dispatch op: messaging-getMyTopics
1349
+ * Service contract: { tenantId? }
1350
+ * Response: { topics: Array<{ topic, fullTopic, tenantId, subscribedAt }> }
1351
+ */
1352
+ listSubscribedTopics(): Promise<string[]>;
1353
+ /**
1354
+ * Send message to a topic.
1355
+ * Dispatch op: messaging-sendTopicMessage
1356
+ * Service contract: { topic, subject?, body, imageUrl?, data? }
1357
+ * Response: { messageId, fcmMessageId }
1358
+ */
1359
+ sendToTopic(topic: string, message: {
1360
+ title: string;
1361
+ body: string;
1362
+ data?: Record<string, string>;
1363
+ }): Promise<{
1364
+ messageId: string;
1365
+ }>;
1366
+ /**
1367
+ * Get message history for this tenant.
1368
+ * Dispatch op: messaging-getMessages
1369
+ * Service contract: { channelType?, status?, limit? }
1370
+ * Response: { messages }
1371
+ */
1372
+ getMessageHistory(options?: {
1373
+ channel?: 'push' | 'email' | 'sms';
1374
+ status?: 'sent' | 'delivered' | 'failed';
1375
+ limit?: number;
1376
+ cursor?: string;
1377
+ }): Promise<{
1378
+ messages: MessageHistoryItem[];
1379
+ nextCursor?: string;
1380
+ }>;
1381
+ /**
1382
+ * Get full details of a single message.
1383
+ * Dispatch op: messaging-getMessage
1384
+ * Service contract: { messageId }
1385
+ * Response: full message document (FirebaseFirestore.DocumentData)
1386
+ */
1387
+ getMessageDetails(messageId: string): Promise<MessageDetails>;
1388
+ /**
1389
+ * Retry a failed message.
1390
+ * No backend messaging onCall exists for retry (confirmed: two searches — grep
1391
+ * across messaging/service/* and messaging/*.ts both returned no match).
1392
+ * Dispatch op: messaging-retryFailedMessage (new onCall implemented below).
1393
+ */
1394
+ retryMessage(messageId: string): Promise<{
1395
+ messageId: string;
1396
+ }>;
1397
+ }
1398
+ interface MessageTemplate {
1399
+ id: string;
1400
+ name: string;
1401
+ channel: 'push' | 'email' | 'sms';
1402
+ subject?: string;
1403
+ body: string;
1404
+ variables: string[];
1405
+ status: 'active' | 'draft';
1406
+ language?: string;
1407
+ createdAt: Date;
1408
+ updatedAt: Date;
1409
+ }
1410
+ interface CreateTemplateOptions {
1411
+ name: string;
1412
+ channel: 'push' | 'email' | 'sms';
1413
+ subject?: string;
1414
+ body: string;
1415
+ variables?: string[];
1416
+ status?: 'active' | 'draft';
1417
+ language?: string;
1418
+ }
1419
+ interface MessageHistoryItem {
1420
+ id: string;
1421
+ channel: 'push' | 'email' | 'sms';
1422
+ template?: string;
1423
+ recipientCount: number;
1424
+ status: 'sent' | 'delivered' | 'failed' | 'partial';
1425
+ sentAt: Date;
1426
+ }
1427
+ interface MessageDetails {
1428
+ id: string;
1429
+ channel: 'push' | 'email' | 'sms';
1430
+ template?: string;
1431
+ recipients: Array<{
1432
+ userId: string;
1433
+ status: 'sent' | 'delivered' | 'failed';
1434
+ deliveredAt?: Date;
1435
+ error?: string;
1436
+ }>;
1437
+ subject?: string;
1438
+ body: string;
1439
+ data?: Record<string, unknown>;
1440
+ sentAt: Date;
1441
+ }
1442
+
1443
+ interface MAKEMINDPartnersConfig extends MAKEMINDConfig {
1444
+ apiClient: ApiClient;
1445
+ tenantId: () => string | null;
1446
+ }
1447
+ type CommissionRate = {
1448
+ kind: 'flatPercent';
1449
+ percent: number;
1450
+ } | {
1451
+ kind: 'fixedPerTransaction';
1452
+ amount: number;
1453
+ currency: string;
1454
+ } | {
1455
+ kind: 'excluded';
1456
+ };
1457
+ /** One row of a partner's rate card. revenueType '*' is the default. */
1458
+ interface CommissionTerm {
1459
+ revenueType: string;
1460
+ rate: CommissionRate;
1461
+ }
1462
+ interface PartnerAttribution {
1463
+ scope: 'tenantMargin' | 'layer1';
1464
+ base: 'margin' | 'gmv';
1465
+ /** Rate card: per-product rates, with an optional '*' default and exclusions. */
1466
+ terms: CommissionTerm[];
1467
+ validFrom: string | Date;
1468
+ validUntil: string | Date | null;
1469
+ status: 'active' | 'paused' | 'ended';
1470
+ }
1471
+ interface CommissionStatementLine {
1472
+ sourceId: string;
1473
+ sourceName: string | null;
1474
+ currency: string;
1475
+ accrued: number;
1476
+ paid: number;
1477
+ owed: number;
1478
+ }
1479
+ interface PartnerCommissionStatement {
1480
+ partnerId: string;
1481
+ lines: CommissionStatementLine[];
1482
+ totalsByCurrency: Array<{
1483
+ currency: string;
1484
+ accrued: number;
1485
+ paid: number;
1486
+ owed: number;
1487
+ }>;
1488
+ }
1489
+ /**
1490
+ * Partner commission overlay client. The same API backs both the central portal
1491
+ * and a tenant's own admin (a tenant embeds partner management in its SaaS via
1492
+ * these tenant-admin methods); Guild consumes the platform-admin methods to
1493
+ * manage the partners of our own SaaSes.
1494
+ */
1495
+ declare class MAKEMINDPartners {
1496
+ private apiClient;
1497
+ constructor(config: MAKEMINDPartnersConfig);
1498
+ /** Register the signed-in individual as a partner (requires a verified email). */
1499
+ registerSelf(displayName?: string): Promise<{
1500
+ partnerId: string;
1501
+ }>;
1502
+ /** Browse the open partner-program directory. */
1503
+ listPrograms(): Promise<{
1504
+ programs: unknown[];
1505
+ }>;
1506
+ /** Apply to a tenant's program (creates a pending registration). */
1507
+ apply(tenantId: string): Promise<{
1508
+ registration: unknown;
1509
+ }>;
1510
+ /** Auto-attribute a subject to a partner via a referral code (at checkout/entry). */
1511
+ registerReferral(input: {
1512
+ code: string;
1513
+ subjectType: 'endCustomer' | 'tenant' | 'sale';
1514
+ subjectId: string;
1515
+ expiresAt?: string | null;
1516
+ }): Promise<{
1517
+ referral: unknown;
1518
+ }>;
1519
+ /** Derive commission for a settled sale for any partner that referred the subject. */
1520
+ deriveCommission(input: {
1521
+ subjectId: string;
1522
+ revenueType: string;
1523
+ baseAmount: number;
1524
+ currency: string;
1525
+ saleId: string;
1526
+ tenantId?: string;
1527
+ }): Promise<{
1528
+ entries: unknown[];
1529
+ }>;
1530
+ /**
1531
+ * Canonical settlement intake: report a revenue event; the engine derives the
1532
+ * full line set (tax + commission + net waterfall) and records partner
1533
+ * commissions when a saleId is given.
1534
+ */
1535
+ deriveSettlementForEvent(input: {
1536
+ revenue: {
1537
+ category: string;
1538
+ amount: number;
1539
+ currency: string;
1540
+ priceTaxMode: 'inclusive' | 'exclusive';
1541
+ supplyType?: string;
1542
+ recognition?: 'pointInTime' | 'overTime';
1543
+ };
1544
+ seller: {
1545
+ role: 'seller';
1546
+ country?: string;
1547
+ };
1548
+ buyer: {
1549
+ role: 'buyer';
1550
+ country?: string;
1551
+ isBusiness?: boolean;
1552
+ taxId?: string;
1553
+ taxIdValidated?: boolean;
1554
+ };
1555
+ fees?: Array<{
1556
+ category: string;
1557
+ amount: number;
1558
+ treatment: 'deductFromProceeds' | 'addToCost';
1559
+ }>;
1560
+ platformFee?: number;
1561
+ saleId?: string;
1562
+ subjectId?: string;
1563
+ at?: string;
1564
+ tenantId?: string;
1565
+ }): Promise<{
1566
+ lines: unknown[];
1567
+ waterfall: unknown;
1568
+ taxRate: number;
1569
+ reverseCharge: boolean;
1570
+ }>;
1571
+ /** Publish/update the tenant's partner program (directory listing). */
1572
+ publishProgram(input: {
1573
+ description: string;
1574
+ offeredTerms: CommissionTerm[];
1575
+ status?: 'open' | 'closed';
1576
+ scope?: 'tenantMargin' | 'layer1';
1577
+ tenantId?: string;
1578
+ }): Promise<{
1579
+ program: unknown;
1580
+ }>;
1581
+ /** Approve a pending/invited registration (optionally overriding the rate). */
1582
+ approve(input: {
1583
+ partnerId: string;
1584
+ attribution?: PartnerAttribution;
1585
+ tenantId?: string;
1586
+ }): Promise<{
1587
+ ok: true;
1588
+ }>;
1589
+ /** Add an already-registered partner directly by id (arranged relationship). */
1590
+ addById(input: {
1591
+ partnerId: string;
1592
+ attribution: PartnerAttribution;
1593
+ tenantId?: string;
1594
+ }): Promise<{
1595
+ ok: true;
1596
+ }>;
1597
+ /** Invite a partner by email (fallback for someone not yet self-registered). */
1598
+ invite(input: {
1599
+ email: string;
1600
+ attribution: PartnerAttribution;
1601
+ tenantId?: string;
1602
+ }): Promise<{
1603
+ partnerId: string;
1604
+ }>;
1605
+ /** List the partners registered in the current tenant. */
1606
+ list(tenantId?: string): Promise<{
1607
+ registrations: unknown[];
1608
+ }>;
1609
+ /** Update a registration's rate and/or status. */
1610
+ update(input: {
1611
+ partnerId: string;
1612
+ attribution?: PartnerAttribution;
1613
+ status?: 'active' | 'paused' | 'ended';
1614
+ tenantId?: string;
1615
+ }): Promise<{
1616
+ ok: true;
1617
+ }>;
1618
+ /** Record a commission accrual for the current tenant (idempotent on idempotencyKey). */
1619
+ recordCommission(input: {
1620
+ partnerId: string;
1621
+ amount: number;
1622
+ currency: string;
1623
+ idempotencyKey: string;
1624
+ scope?: 'tenantMargin' | 'layer1';
1625
+ sourceRef?: string | null;
1626
+ tenantId?: string;
1627
+ }): Promise<{
1628
+ entry: unknown;
1629
+ }>;
1630
+ /** Claw back a commission entry. */
1631
+ reverseCommission(entryId: string): Promise<{
1632
+ reversal: unknown;
1633
+ }>;
1634
+ /** Record a manual payout against a partner's owed commission. */
1635
+ recordPayout(input: {
1636
+ partnerId: string;
1637
+ tenantId: string | null;
1638
+ amount: number;
1639
+ currency: string;
1640
+ ref?: string | null;
1641
+ }): Promise<{
1642
+ payout: unknown;
1643
+ }>;
1644
+ /** Accept an invitation, claiming the partner identity (requires a verified email). */
1645
+ acceptInvitation(partnerId: string, tenantId: string): Promise<{
1646
+ partnerId: string;
1647
+ tenantId: string;
1648
+ }>;
1649
+ /** The signed-in partner's own cross-tenant commission statement (union). */
1650
+ myCommissions(): Promise<{
1651
+ statement: PartnerCommissionStatement;
1652
+ }>;
1653
+ /** Any partner's statement (platform admin only). */
1654
+ commissionsOf(partnerId: string): Promise<{
1655
+ statement: PartnerCommissionStatement;
1656
+ }>;
1657
+ }
1658
+
1659
+ interface MAKEMINDStorageConfig extends MAKEMINDConfig {
1660
+ apiClient: ApiClient;
1661
+ tenantId: () => string | null;
1662
+ }
1663
+ interface UploadOptions {
1664
+ path: string;
1665
+ file: File | Blob;
1666
+ metadata?: Record<string, string>;
1667
+ onProgress?: (progress: number) => void;
1668
+ }
1669
+ interface UploadResult {
1670
+ path: string;
1671
+ url: string;
1672
+ size: number;
1673
+ contentType: string;
1674
+ metadata?: Record<string, string>;
1675
+ }
1676
+ interface FileMetadata {
1677
+ name: string;
1678
+ path: string;
1679
+ size: number;
1680
+ contentType: string;
1681
+ createdAt: Date;
1682
+ updatedAt: Date;
1683
+ metadata?: Record<string, string>;
1684
+ }
1685
+ interface ListFilesOptions {
1686
+ prefix?: string;
1687
+ maxResults?: number;
1688
+ pageToken?: string;
1689
+ }
1690
+ interface ListFilesResult {
1691
+ files: FileMetadata[];
1692
+ nextPageToken?: string;
1693
+ }
1694
+ declare class MAKEMINDStorage {
1695
+ private apiClient;
1696
+ private getTenantId;
1697
+ constructor(config: MAKEMINDStorageConfig);
1698
+ private get tenantId();
1699
+ /**
1700
+ * Encode a storage object path for use as a path parameter, preserving the
1701
+ * `/` separators (the gateway captures the full sub-path via a wildcard).
1702
+ */
1703
+ private encodePath;
1704
+ /**
1705
+ * Upload a file
1706
+ */
1707
+ upload(options: UploadOptions): Promise<UploadResult>;
1708
+ private uploadToSignedUrl;
1709
+ /**
1710
+ * Get download URL for a file
1711
+ */
1712
+ getDownloadUrl(path: string): Promise<string>;
1713
+ /**
1714
+ * Download a file directly
1715
+ * Returns the file as a Blob
1716
+ */
1717
+ download(path: string): Promise<Blob>;
1718
+ /**
1719
+ * Download a file and trigger browser download
1720
+ */
1721
+ downloadToFile(path: string, filename?: string): Promise<void>;
1722
+ /**
1723
+ * Get file metadata
1724
+ */
1725
+ getMetadata(path: string): Promise<FileMetadata>;
1726
+ /**
1727
+ * Update file metadata
1728
+ */
1729
+ updateMetadata(path: string, metadata: Record<string, string>): Promise<void>;
1730
+ /**
1731
+ * List files in a directory
1732
+ */
1733
+ listFiles(options?: ListFilesOptions): Promise<ListFilesResult>;
1734
+ /**
1735
+ * Delete a file
1736
+ */
1737
+ delete(path: string): Promise<void>;
1738
+ /**
1739
+ * Delete multiple files
1740
+ */
1741
+ deleteMany(paths: string[]): Promise<void>;
1742
+ /**
1743
+ * Copy a file
1744
+ */
1745
+ copy(sourcePath: string, destinationPath: string): Promise<UploadResult>;
1746
+ /**
1747
+ * Move a file
1748
+ */
1749
+ move(sourcePath: string, destinationPath: string): Promise<UploadResult>;
1750
+ /**
1751
+ * Upload a document for a product
1752
+ */
1753
+ uploadProductDocument(productId: string, file: File, options?: {
1754
+ documentType?: string;
1755
+ version?: string;
1756
+ onProgress?: (progress: number) => void;
1757
+ }): Promise<UploadResult>;
1758
+ /**
1759
+ * Upload an ECO attachment
1760
+ */
1761
+ uploadEcoAttachment(ecoId: string, file: File, onProgress?: (progress: number) => void): Promise<UploadResult>;
1762
+ /**
1763
+ * Upload a quality issue attachment
1764
+ */
1765
+ uploadQualityAttachment(issueId: string, file: File, onProgress?: (progress: number) => void): Promise<UploadResult>;
1766
+ /**
1767
+ * Get all documents for a product
1768
+ */
1769
+ getProductDocuments(productId: string): Promise<FileMetadata[]>;
1770
+ /**
1771
+ * List all buckets for the tenant
1772
+ */
1773
+ listBuckets(): Promise<BucketInfo[]>;
1774
+ /**
1775
+ * Create a new bucket.
1776
+ *
1777
+ * The REST route expects { name, settings } where settings carries the
1778
+ * bucket policy fields. publicAccess, corsConfig, and lifecycleRules from
1779
+ * CreateBucketOptions are folded into the settings envelope so the backend
1780
+ * handler can read them from req.body.settings.
1781
+ */
1782
+ createBucket(options: CreateBucketOptions): Promise<BucketInfo>;
1783
+ /**
1784
+ * Get bucket info
1785
+ */
1786
+ getBucket(bucketId: string): Promise<BucketInfo>;
1787
+ /**
1788
+ * Update bucket settings.
1789
+ *
1790
+ * The REST route reads { settings } from req.body. Flatten the
1791
+ * CreateBucketOptions partial into a settings envelope so the backend
1792
+ * merges the diff correctly.
1793
+ */
1794
+ updateBucket(bucketId: string, updates: Partial<CreateBucketOptions>): Promise<BucketInfo>;
1795
+ /**
1796
+ * Delete a bucket (must be empty)
1797
+ */
1798
+ deleteBucket(bucketId: string): Promise<void>;
1799
+ /**
1800
+ * Get a pre-signed URL for direct upload (bypassing SDK)
1801
+ */
1802
+ getUploadUrl(path: string, options?: {
1803
+ contentType?: string;
1804
+ expiresIn?: number;
1805
+ }): Promise<{
1806
+ uploadUrl: string;
1807
+ fileId: string;
1808
+ }>;
1809
+ /**
1810
+ * Check if a file exists
1811
+ */
1812
+ exists(path: string): Promise<boolean>;
1813
+ /**
1814
+ * Get storage usage statistics
1815
+ */
1816
+ getUsageStats(): Promise<StorageUsageStats>;
1817
+ }
1818
+ interface BucketInfo {
1819
+ id: string;
1820
+ name: string;
1821
+ tenantId: string;
1822
+ publicAccess: boolean;
1823
+ createdAt: Date;
1824
+ updatedAt: Date;
1825
+ storageUsed: number;
1826
+ fileCount: number;
1827
+ }
1828
+ interface CreateBucketOptions {
1829
+ name: string;
1830
+ publicAccess?: boolean;
1831
+ corsConfig?: CorsConfig;
1832
+ lifecycleRules?: LifecycleRule[];
1833
+ }
1834
+ interface CorsConfig {
1835
+ allowedOrigins: string[];
1836
+ allowedMethods: string[];
1837
+ allowedHeaders?: string[];
1838
+ maxAgeSeconds?: number;
1839
+ }
1840
+ interface LifecycleRule {
1841
+ action: 'delete' | 'archive';
1842
+ conditions: {
1843
+ ageInDays?: number;
1844
+ prefix?: string;
1845
+ };
1846
+ }
1847
+ interface StorageUsageStats {
1848
+ totalBytes: number;
1849
+ fileCount: number;
1850
+ bucketCount: number;
1851
+ lastUpdated: Date;
1852
+ }
1853
+
1854
+ interface MAKEMINDAIConfig extends MAKEMINDConfig {
1855
+ apiClient: ApiClient;
1856
+ tenantId: () => string | null;
1857
+ }
1858
+ interface ChatMessage {
1859
+ role: 'user' | 'assistant' | 'system';
1860
+ content: string;
1861
+ }
1862
+ interface ChatOptions {
1863
+ model?: string;
1864
+ temperature?: number;
1865
+ maxTokens?: number;
1866
+ systemPrompt?: string;
1867
+ }
1868
+ interface ChatResponse {
1869
+ message: ChatMessage;
1870
+ usage: {
1871
+ promptTokens: number;
1872
+ completionTokens: number;
1873
+ totalTokens: number;
1874
+ };
1875
+ }
1876
+ interface EmbeddingOptions {
1877
+ model?: string;
1878
+ }
1879
+ interface VisionOptions {
1880
+ model?: string;
1881
+ maxTokens?: number;
1882
+ }
1883
+ interface ToolCall {
1884
+ name: string;
1885
+ arguments: Record<string, unknown>;
1886
+ }
1887
+ interface ToolDefinition {
1888
+ name: string;
1889
+ description: string;
1890
+ parameters: Record<string, unknown>;
1891
+ }
1892
+ declare class MAKEMINDAI {
1893
+ private apiClient;
1894
+ private getTenantId;
1895
+ constructor(config: MAKEMINDAIConfig);
1896
+ chat(messages: ChatMessage[], options?: ChatOptions): Promise<ChatResponse>;
1897
+ /**
1898
+ * Stream chat completion via the aiStreamChat onCall backend.
1899
+ *
1900
+ * The backend writes chunks progressively to Firestore
1901
+ * (aiStreamChunks/{streamId}/chunks). This method polls the stream
1902
+ * document until the status reaches 'completed' or 'failed', invoking
1903
+ * onChunk for each content chunk in order. Callers that need real-time
1904
+ * granularity should subscribe to the Firestore collection directly using
1905
+ * the returned streamId from aiStreamChat.
1906
+ *
1907
+ * @param messages - Chat messages
1908
+ * @param onChunk - Callback for each streamed content chunk
1909
+ * @param options - Chat options and optional onDone callback
1910
+ * @returns Promise that resolves when streaming is complete
1911
+ */
1912
+ chatStream(messages: ChatMessage[], onChunk: (chunk: string) => void, options?: ChatOptions & {
1913
+ onDone?: (response: ChatResponse) => void;
1914
+ }): Promise<ChatResponse>;
1915
+ /**
1916
+ * Stream chat using async generator for easier consumption.
1917
+ * Yields content deltas via polling on aiGetStreamResult.
1918
+ */
1919
+ streamChat(messages: ChatMessage[], options?: ChatOptions): AsyncGenerator<string, ChatResponse, unknown>;
1920
+ createEmbedding(text: string | string[], options?: EmbeddingOptions): Promise<{
1921
+ embeddings: number[][];
1922
+ usage: {
1923
+ totalTokens: number;
1924
+ };
1925
+ }>;
1926
+ /**
1927
+ * Vector search over a tenant knowledge collection.
1928
+ * Routes to the knowledge domain dispatch (knowledge-knowledgeSearch),
1929
+ * which performs semantic search with embeddings over indexed documents.
1930
+ */
1931
+ vectorSearch(collection: string, query: string, options?: {
1932
+ limit?: number;
1933
+ filter?: Record<string, unknown>;
1934
+ }): Promise<Array<{
1935
+ id: string;
1936
+ score: number;
1937
+ data: Record<string, unknown>;
1938
+ }>>;
1939
+ /**
1940
+ * Vision analysis for a publicly accessible image URL.
1941
+ * Routes to ai-aiVision (aiVision onCall). The image is passed as a
1942
+ * ChatCompletionRequest message using the imageUrl ContentPart type.
1943
+ */
1944
+ analyzeImage(imageUrl: string, prompt: string, options?: VisionOptions): Promise<{
1945
+ content: string;
1946
+ usage: {
1947
+ totalTokens: number;
1948
+ };
1949
+ }>;
1950
+ /**
1951
+ * Vision analysis for a base64-encoded image.
1952
+ * The image is embedded as a data URI in the imageUrl ContentPart.
1953
+ */
1954
+ analyzeImageBase64(base64Image: string, mimeType: string, prompt: string, options?: VisionOptions): Promise<{
1955
+ content: string;
1956
+ usage: {
1957
+ totalTokens: number;
1958
+ };
1959
+ }>;
1960
+ /**
1961
+ * Chat completion with tool definitions (function calling).
1962
+ * Routes to ai-aiChat — the aiChat onCall natively supports the tools field
1963
+ * in ChatCompletionRequest, no separate endpoint required.
1964
+ */
1965
+ chatWithTools(messages: ChatMessage[], tools: ToolDefinition[], options?: ChatOptions): Promise<{
1966
+ message: ChatMessage;
1967
+ toolCalls?: ToolCall[];
1968
+ usage: {
1969
+ promptTokens: number;
1970
+ completionTokens: number;
1971
+ totalTokens: number;
1972
+ };
1973
+ }>;
1974
+ /**
1975
+ * Document analysis (summary, field extraction, or QA).
1976
+ * No dedicated onCall exists in the ai domain; implemented via ai-aiChat
1977
+ * with a structured system prompt that targets the requested analysis type.
1978
+ * The document content must be fetched by the caller and passed as text —
1979
+ * the backend has no URL-fetch / OCR pipeline for onCall yet.
1980
+ */
1981
+ analyzeDocument(documentUrl: string, analysisType: 'summary' | 'extract' | 'qa', options?: {
1982
+ question?: string;
1983
+ extractFields?: string[];
1984
+ }): Promise<{
1985
+ result: string | Record<string, unknown>;
1986
+ usage: {
1987
+ totalTokens: number;
1988
+ };
1989
+ }>;
1990
+ generate(prompt: string, options?: ChatOptions): Promise<{
1991
+ text: string;
1992
+ usage: {
1993
+ totalTokens: number;
1994
+ };
1995
+ }>;
1996
+ /**
1997
+ * Text summarization via ai-aiChat.
1998
+ * No dedicated onCall exists; implemented as a structured chat request
1999
+ * with a summarization system prompt.
2000
+ */
2001
+ summarize(text: string, options?: {
2002
+ maxLength?: number;
2003
+ style?: 'bullet' | 'paragraph';
2004
+ }): Promise<{
2005
+ summary: string;
2006
+ usage: {
2007
+ totalTokens: number;
2008
+ };
2009
+ }>;
2010
+ /**
2011
+ * Text translation via ai-aiChat.
2012
+ * No dedicated onCall exists; implemented as a structured chat request
2013
+ * with a translation system prompt.
2014
+ */
2015
+ translate(text: string, targetLanguage: string, sourceLanguage?: string): Promise<{
2016
+ translation: string;
2017
+ detectedLanguage?: string;
2018
+ usage: {
2019
+ totalTokens: number;
2020
+ };
2021
+ }>;
2022
+ }
2023
+
2024
+ interface MAKEMINDSearchConfig extends MAKEMINDConfig {
2025
+ apiClient: ApiClient;
2026
+ tenantId: () => string | null;
2027
+ }
2028
+ interface SearchResult {
2029
+ hits: Array<{
2030
+ document: Record<string, unknown>;
2031
+ highlights?: Array<{
2032
+ field: string;
2033
+ snippet: string;
2034
+ }>;
2035
+ score: number;
2036
+ }>;
2037
+ found: number;
2038
+ page: number;
2039
+ totalPages: number;
2040
+ }
2041
+ interface SearchQueryOptions {
2042
+ q: string;
2043
+ collections?: string[];
2044
+ page?: number;
2045
+ perPage?: number;
2046
+ }
2047
+ interface AdvancedSearchOptions {
2048
+ query: string;
2049
+ collection: string;
2050
+ facets?: string[];
2051
+ filters?: Record<string, unknown>;
2052
+ sortBy?: string;
2053
+ page?: number;
2054
+ perPage?: number;
2055
+ highlightFields?: string[];
2056
+ groupBy?: string;
2057
+ }
2058
+ interface SearchSuggestionOptions {
2059
+ prefix: string;
2060
+ collection: string;
2061
+ limit?: number;
2062
+ }
2063
+ interface BulkReindexOptions {
2064
+ collection?: string;
2065
+ recreateCollections?: boolean;
2066
+ }
2067
+ interface ReindexStatus {
2068
+ jobId: string;
2069
+ status: 'queued' | 'processing' | 'completed' | 'failed';
2070
+ progress?: number;
2071
+ error?: string;
2072
+ }
2073
+ declare class MAKEMINDSearch {
2074
+ private apiClient;
2075
+ private getTenantId;
2076
+ constructor(config: MAKEMINDSearchConfig);
2077
+ query(options: SearchQueryOptions): Promise<SearchResult>;
2078
+ advanced(options: AdvancedSearchOptions): Promise<SearchResult>;
2079
+ suggestions(options: SearchSuggestionOptions): Promise<string[]>;
2080
+ getAnalytics(options?: {
2081
+ startDate?: string;
2082
+ endDate?: string;
2083
+ }): Promise<Record<string, unknown>>;
2084
+ bulkReindex(options?: BulkReindexOptions): Promise<{
2085
+ jobId: string;
2086
+ }>;
2087
+ getBulkReindexStatus(options: {
2088
+ jobId: string;
2089
+ }): Promise<ReindexStatus>;
2090
+ }
2091
+
2092
+ /**
2093
+ * MAKEMINDApps - App Builder SDK Service
2094
+ *
2095
+ * SDK service for the App Builder feature.
2096
+ * Provides methods for managing apps, pages, publishing, and domains.
2097
+ *
2098
+ * @see docs/03_DDD/ui-tenant-portal/08-app-builder.md
2099
+ */
2100
+
2101
+ type AppStatus = 'draft' | 'published' | 'archived';
2102
+ type LayoutType = 'blank' | 'sidebar' | 'topnav' | 'dashboard' | 'centered';
2103
+ type SSLStatus = 'pending' | 'provisioning' | 'active' | 'expired' | 'failed';
2104
+ type CustomDomainStatus = 'pending' | 'verifying' | 'active' | 'failed';
2105
+ /** Where a hostname's traffic is routed once it reaches the domain-serving edge. */
2106
+ type DomainTargetKind = 'marketplace-server' | 'tenant-home' | 'external-url' | 'relay';
2107
+ /**
2108
+ * Optional generic reverse-proxy routing target for a hostname: a
2109
+ * marketplace server, a tenant's own home app, an external URL, or a relay.
2110
+ * Passed to `addSubdomain`, `addCustomDomain`, and
2111
+ * `registerDomainForSubTenant`; a registered domain with no `target` is
2112
+ * still a valid entry, just unresolvable for proxying until one is set.
2113
+ *
2114
+ * Requires domain-service activation. The control-plane call is live, but a
2115
+ * registered domain/target does not serve traffic until the domain-serving
2116
+ * edge is provisioned (Phase 2). Custom and nested (sub-tenant) domains
2117
+ * additionally require an active domain entitlement (paid SKU); pricing is
2118
+ * not yet set. Subdomains are free.
2119
+ */
2120
+ /** An address that opens an MCP origin, as returned by the entry operations. */
2121
+ interface WebEntrySummary {
2122
+ /** The hostname the platform minted and reserved. */
2123
+ host: string;
2124
+ /** The address a visitor opens. */
2125
+ url: string;
2126
+ /** What the renderer connects to once it boots. */
2127
+ origin: {
2128
+ kind: 'app' | 'server' | 'bundle';
2129
+ ref: string;
2130
+ };
2131
+ /** Who owns the entry. A parameter, not a fixed scope. */
2132
+ party: {
2133
+ kind: 'tenant' | 'euid' | 'ref';
2134
+ id: string;
2135
+ };
2136
+ /** Feeds both the share metadata and the boot declaration. */
2137
+ display?: {
2138
+ name?: string;
2139
+ description?: string;
2140
+ iconUrl?: string;
2141
+ };
2142
+ status: string;
2143
+ }
2144
+ interface DomainTarget {
2145
+ kind: DomainTargetKind;
2146
+ ref: string;
2147
+ }
2148
+ interface ThemeConfig {
2149
+ mode: 'light' | 'dark' | 'system';
2150
+ primaryColor: string;
2151
+ secondaryColor: string;
2152
+ fontFamily: string;
2153
+ borderRadius: 'none' | 'sm' | 'md' | 'lg' | 'full';
2154
+ density: 'compact' | 'normal' | 'comfortable';
2155
+ logoUrl?: string;
2156
+ faviconUrl?: string;
2157
+ customCss?: string;
2158
+ }
2159
+ interface AuthConfig {
2160
+ enabled: boolean;
2161
+ providers: ('email' | 'google' | 'apple' | 'microsoft' | 'saml')[];
2162
+ signupEnabled: boolean;
2163
+ requireEmailVerification: boolean;
2164
+ mfaEnabled: boolean;
2165
+ sessionTimeout: number;
2166
+ }
2167
+ interface PWAConfig {
2168
+ enabled: boolean;
2169
+ name: string;
2170
+ shortName: string;
2171
+ description: string;
2172
+ themeColor: string;
2173
+ backgroundColor: string;
2174
+ display: 'standalone' | 'fullscreen' | 'minimal-ui' | 'browser';
2175
+ orientation: 'portrait' | 'landscape' | 'any';
2176
+ offlineEnabled: boolean;
2177
+ pushEnabled: boolean;
2178
+ }
2179
+ interface AppSettings {
2180
+ theme?: Partial<ThemeConfig>;
2181
+ auth?: Partial<AuthConfig>;
2182
+ pwa?: Partial<PWAConfig>;
2183
+ seo?: {
2184
+ title?: string;
2185
+ description?: string;
2186
+ ogImage?: string;
2187
+ };
2188
+ localization?: {
2189
+ defaultLocale?: string;
2190
+ supportedLocales?: string[];
2191
+ };
2192
+ }
2193
+ interface DomainConfig {
2194
+ subdomain: string;
2195
+ customDomain: string | null;
2196
+ customDomainStatus: CustomDomainStatus;
2197
+ sslStatus: SSLStatus;
2198
+ }
2199
+ interface App {
2200
+ id: string;
2201
+ tenantId: string;
2202
+ name: string;
2203
+ displayName: string;
2204
+ description: string;
2205
+ icon: string;
2206
+ status: AppStatus;
2207
+ version: number;
2208
+ publishedVersion: number | null;
2209
+ domain: DomainConfig;
2210
+ settings: AppSettings;
2211
+ createdAt: string;
2212
+ createdBy: string;
2213
+ updatedAt: string;
2214
+ updatedBy: string;
2215
+ }
2216
+ interface LayoutConfig {
2217
+ sidebarWidth?: number;
2218
+ sidebarCollapsible?: boolean;
2219
+ headerHeight?: number;
2220
+ footerHeight?: number;
2221
+ contentMaxWidth?: number;
2222
+ }
2223
+ interface PageSEO {
2224
+ title: string;
2225
+ description: string;
2226
+ ogImage?: string;
2227
+ noIndex?: boolean;
2228
+ }
2229
+ /**
2230
+ * A node of a builder page, as stored and as the API returns it.
2231
+ *
2232
+ * This described nine of the tree's fields while the editor writes fifteen:
2233
+ * `dataBinding`, `validation`, `a11y` and `conditions.className` were absent
2234
+ * entirely. TypeScript does not delete what it cannot see, so a round trip
2235
+ * through `getPage`/`updatePage` kept them — but a consumer BUILDING a node
2236
+ * from this type had no way to express a binding or a validation rule, and
2237
+ * one rebuilding a node field-by-field dropped them silently.
2238
+ *
2239
+ * `type` stays `string` rather than the editor's 108-member union: this
2240
+ * describes a REST payload, and the palette must be able to grow without
2241
+ * every SDK consumer needing a new release to accept the new type.
2242
+ *
2243
+ * Kept in step with `@makemind/app-builder-ui`'s `ComponentNode` by
2244
+ * `src/__tests__/component-node-parity.test.ts`.
2245
+ */
2246
+ interface ComponentNode {
2247
+ id: string;
2248
+ type: string;
2249
+ name: string;
2250
+ props: Record<string, unknown>;
2251
+ styles: Record<string, unknown>;
2252
+ children?: ComponentNode[];
2253
+ conditions?: {
2254
+ visible?: string;
2255
+ enabled?: string;
2256
+ className?: string;
2257
+ };
2258
+ events?: Record<string, unknown[]>;
2259
+ dataBinding?: {
2260
+ source: string;
2261
+ field: string;
2262
+ transform?: string;
2263
+ };
2264
+ validation?: Array<{
2265
+ type: string;
2266
+ value?: unknown;
2267
+ message: string;
2268
+ }>;
2269
+ a11y?: {
2270
+ label?: string;
2271
+ description?: string;
2272
+ role?: string;
2273
+ };
2274
+ }
2275
+ interface DataSource {
2276
+ id: string;
2277
+ name: string;
2278
+ type: 'query' | 'document' | 'api' | 'flow' | 'variable' | 'realtime';
2279
+ config: Record<string, unknown>;
2280
+ }
2281
+ interface PageVariable {
2282
+ name: string;
2283
+ type: 'string' | 'number' | 'boolean' | 'object' | 'array';
2284
+ defaultValue: unknown;
2285
+ }
2286
+ interface Page {
2287
+ id: string;
2288
+ appId: string;
2289
+ name: string;
2290
+ path: string;
2291
+ title: string;
2292
+ description: string;
2293
+ isHomePage: boolean;
2294
+ isPublic: boolean;
2295
+ accessRoles: string[];
2296
+ layout: {
2297
+ type: LayoutType;
2298
+ config: LayoutConfig;
2299
+ };
2300
+ components: ComponentNode[];
2301
+ dataSources: DataSource[];
2302
+ variables: PageVariable[];
2303
+ seo: PageSEO;
2304
+ order: number;
2305
+ createdAt: string;
2306
+ updatedAt: string;
2307
+ }
2308
+ interface AppVersion {
2309
+ id: string;
2310
+ appId: string;
2311
+ version: number;
2312
+ changelog: string;
2313
+ createdAt: string;
2314
+ createdBy: string;
2315
+ }
2316
+ interface DNSRecord {
2317
+ type: 'CNAME' | 'TXT' | 'A' | 'AAAA';
2318
+ name: string;
2319
+ value: string;
2320
+ ttl: number;
2321
+ }
2322
+ interface DomainStatus {
2323
+ domain: string;
2324
+ type: 'subdomain' | 'custom';
2325
+ status: string;
2326
+ sslStatus: SSLStatus;
2327
+ }
2328
+ /** Registry status of a delegated (sub-tenant) domain entry. */
2329
+ type SubTenantDomainStatus = 'pending' | 'verifying' | 'active' | 'suspended' | 'deleted';
2330
+ /**
2331
+ * A Firestore Timestamp as it crosses the wire — JSON has no native
2332
+ * timestamp type, so the Admin SDK's `Timestamp` class serializes to this
2333
+ * `{ _seconds, _nanoseconds }` shape.
2334
+ */
2335
+ interface SerializedTimestamp {
2336
+ _seconds: number;
2337
+ _nanoseconds: number;
2338
+ }
2339
+ /** One entry returned by `listSubTenantDomains`. */
2340
+ interface SubTenantDomainSummary {
2341
+ domain: string;
2342
+ type: 'subdomain' | 'custom';
2343
+ appId: string;
2344
+ subTenantId?: string;
2345
+ status: SubTenantDomainStatus;
2346
+ sslStatus: SSLStatus;
2347
+ createdAt: SerializedTimestamp;
2348
+ }
2349
+ interface AppAnalytics {
2350
+ appId: string;
2351
+ period: string;
2352
+ pageViews: number;
2353
+ uniqueVisitors: number;
2354
+ apiCalls: number;
2355
+ errors: number;
2356
+ avgLoadTime: number;
2357
+ topPages: Array<{
2358
+ path: string;
2359
+ views: number;
2360
+ }>;
2361
+ }
2362
+ interface CreateAppParams {
2363
+ name: string;
2364
+ displayName?: string;
2365
+ description?: string;
2366
+ icon?: string;
2367
+ type?: 'web' | 'mobile' | 'backend' | 'agent';
2368
+ }
2369
+ interface UpdateAppParams {
2370
+ name?: string;
2371
+ displayName?: string;
2372
+ description?: string;
2373
+ icon?: string;
2374
+ status?: AppStatus;
2375
+ settings?: AppSettings;
2376
+ }
2377
+ interface ListAppsParams {
2378
+ status?: AppStatus;
2379
+ limit?: number;
2380
+ startAfter?: string;
2381
+ }
2382
+ interface CreatePageParams {
2383
+ name: string;
2384
+ path: string;
2385
+ title?: string;
2386
+ description?: string;
2387
+ isHomePage?: boolean;
2388
+ isPublic?: boolean;
2389
+ layout?: {
2390
+ type: LayoutType;
2391
+ config?: LayoutConfig;
2392
+ };
2393
+ }
2394
+ interface UpdatePageParams {
2395
+ name?: string;
2396
+ path?: string;
2397
+ title?: string;
2398
+ description?: string;
2399
+ isHomePage?: boolean;
2400
+ isPublic?: boolean;
2401
+ accessRoles?: string[];
2402
+ layout?: {
2403
+ type: LayoutType;
2404
+ config?: LayoutConfig;
2405
+ };
2406
+ components?: ComponentNode[];
2407
+ dataSources?: DataSource[];
2408
+ variables?: PageVariable[];
2409
+ seo?: PageSEO;
2410
+ }
2411
+ interface MAKEMINDAppsConfig extends MAKEMINDConfig {
2412
+ apiClient: ApiClient;
2413
+ tenantId: () => string | null;
2414
+ }
2415
+ declare class MAKEMINDApps {
2416
+ private apiClient;
2417
+ private getTenantId;
2418
+ constructor(config: MAKEMINDAppsConfig);
2419
+ private get tenantId();
2420
+ createApp(params: CreateAppParams): Promise<{
2421
+ appId: string;
2422
+ }>;
2423
+ getApp(appId: string): Promise<App | null>;
2424
+ listApps(params?: ListAppsParams): Promise<{
2425
+ apps: App[];
2426
+ hasMore: boolean;
2427
+ nextCursor?: string;
2428
+ }>;
2429
+ updateApp(appId: string, params: UpdateAppParams): Promise<void>;
2430
+ deleteApp(appId: string, hardDelete?: boolean): Promise<void>;
2431
+ duplicateApp(appId: string, newName: string): Promise<{
2432
+ appId: string;
2433
+ }>;
2434
+ onAppSnapshot(appId: string, callback: (app: App | null) => void): Unsubscribe;
2435
+ createPage(appId: string, params: CreatePageParams): Promise<{
2436
+ pageId: string;
2437
+ }>;
2438
+ getPage(appId: string, pageId: string): Promise<Page | null>;
2439
+ listPages(appId: string): Promise<Page[]>;
2440
+ updatePage(appId: string, pageId: string, params: UpdatePageParams): Promise<void>;
2441
+ deletePage(appId: string, pageId: string): Promise<void>;
2442
+ reorderPages(appId: string, order: string[]): Promise<void>;
2443
+ duplicatePage(appId: string, pageId: string, newName?: string, newPath?: string): Promise<{
2444
+ pageId: string;
2445
+ }>;
2446
+ publish(appId: string, changelog?: string): Promise<{
2447
+ success: boolean;
2448
+ version: number;
2449
+ publishedAt: string;
2450
+ }>;
2451
+ unpublish(appId: string): Promise<void>;
2452
+ rollback(appId: string, targetVersion: number): Promise<{
2453
+ success: boolean;
2454
+ currentVersion: number;
2455
+ }>;
2456
+ getVersions(appId: string, limit?: number): Promise<AppVersion[]>;
2457
+ getVersionDetail(appId: string, versionId: string): Promise<AppVersion & {
2458
+ snapshot: Record<string, unknown>;
2459
+ }>;
2460
+ compareVersions(appId: string, version1: number, version2: number): Promise<{
2461
+ version1: {
2462
+ version: number;
2463
+ changelog: string;
2464
+ createdAt: string;
2465
+ };
2466
+ version2: {
2467
+ version: number;
2468
+ changelog: string;
2469
+ createdAt: string;
2470
+ };
2471
+ changes: {
2472
+ pagesAdded: number;
2473
+ pagesRemoved: number;
2474
+ pagesModified: number;
2475
+ addedPageNames: string[];
2476
+ removedPageNames: string[];
2477
+ };
2478
+ }>;
2479
+ /**
2480
+ * Add a platform subdomain (`<subdomain>.<platform-host>`) for an app.
2481
+ * `target` is an optional generic reverse-proxy routing target.
2482
+ *
2483
+ * Requires domain-service activation. The control-plane call is live, but
2484
+ * a registered domain/target does not serve traffic until the
2485
+ * domain-serving edge is provisioned (Phase 2). Custom and nested
2486
+ * (sub-tenant) domains additionally require an active domain entitlement
2487
+ * (paid SKU); pricing is not yet set. Subdomains are free.
2488
+ */
2489
+ addSubdomain(appId: string, subdomain: string, target?: DomainTarget): Promise<{
2490
+ success: boolean;
2491
+ domain: string;
2492
+ }>;
2493
+ /**
2494
+ * Add a custom (BYO) domain for an app. Returns a verification token and
2495
+ * DNS records the caller must publish before `verifyDomain` will pass.
2496
+ * `target` is an optional generic reverse-proxy routing target.
2497
+ *
2498
+ * Requires domain-service activation. The control-plane call is live, but
2499
+ * a registered domain/target does not serve traffic until the
2500
+ * domain-serving edge is provisioned (Phase 2). Custom and nested
2501
+ * (sub-tenant) domains additionally require an active domain entitlement
2502
+ * (paid SKU); pricing is not yet set. Subdomains are free.
2503
+ */
2504
+ addCustomDomain(appId: string, domain: string, target?: DomainTarget): Promise<{
2505
+ success: boolean;
2506
+ verificationToken: string;
2507
+ dnsRecords: DNSRecord[];
2508
+ }>;
2509
+ verifyDomain(appId: string, domain: string): Promise<{
2510
+ verified: boolean;
2511
+ sslStatus: SSLStatus;
2512
+ error?: string;
2513
+ }>;
2514
+ removeDomain(appId: string, domain: string): Promise<void>;
2515
+ getDomainStatus(appId: string): Promise<DomainStatus[]>;
2516
+ /**
2517
+ * Mint an address for an app.
2518
+ *
2519
+ * The caller proposes a **label**, not a hostname: the platform derives and
2520
+ * reserves the host under its own uniqueness and reserved-name rules. A
2521
+ * caller cannot claim a hostname it does not own, and the origin is derived
2522
+ * from the app being bound rather than supplied — the whole capability rests
2523
+ * on the issuer deciding the origin, and a free-text URL field is exactly how
2524
+ * that property gets lost.
2525
+ *
2526
+ * `display` feeds both the share metadata (`og:*`) and the boot declaration,
2527
+ * so a link preview and the running app cannot disagree.
2528
+ */
2529
+ mintWebEntry(params: {
2530
+ label: string;
2531
+ /**
2532
+ * `app` is the resident case: `ref` is an appId and the platform derives
2533
+ * its own MCP endpoint from it, so there is no address for a caller to
2534
+ * supply — and therefore none to point elsewhere. `server` binds an
2535
+ * external endpoint the party has proven it controls.
2536
+ */
2537
+ origin: {
2538
+ kind: 'app' | 'server' | 'bundle';
2539
+ ref: string;
2540
+ };
2541
+ /**
2542
+ * Who the address is for. **Required, and not defaulted anywhere.**
2543
+ *
2544
+ * An address states its party, and a payment served from it pays that
2545
+ * party. The platform used to fill this in from the calling tenant, which
2546
+ * meant an address selling on a seller's behalf collected for the tenant
2547
+ * because nobody said otherwise. Sending nothing is refused; a shop
2548
+ * selling its own goods says `{ kind: 'tenant', id: '<its id>' }`.
2549
+ */
2550
+ party: {
2551
+ kind: 'tenant' | 'euid' | 'ref';
2552
+ id: string;
2553
+ };
2554
+ display?: {
2555
+ name?: string;
2556
+ description?: string;
2557
+ iconUrl?: string;
2558
+ };
2559
+ }): Promise<WebEntrySummary>;
2560
+ /** Read one entry the caller owns. Requires `domains:read`. */
2561
+ getWebEntry(host: string): Promise<WebEntrySummary>;
2562
+ /** List the caller's entries, optionally narrowed to one party. Requires `domains:read`. */
2563
+ listWebEntries(params?: {
2564
+ party?: {
2565
+ kind: 'tenant' | 'euid' | 'ref';
2566
+ id: string;
2567
+ };
2568
+ }): Promise<{
2569
+ entries: WebEntrySummary[];
2570
+ }>;
2571
+ /**
2572
+ * Repoint an entry at a different (still proven) origin, or change how it
2573
+ * appears when shared. The address itself is immutable — a different address
2574
+ * is a different entry.
2575
+ */
2576
+ updateWebEntry(params: {
2577
+ host: string;
2578
+ origin?: {
2579
+ kind: 'app' | 'server' | 'bundle';
2580
+ ref: string;
2581
+ };
2582
+ display?: {
2583
+ name?: string;
2584
+ description?: string;
2585
+ iconUrl?: string;
2586
+ };
2587
+ }): Promise<WebEntrySummary>;
2588
+ /** Retire an entry — the address stops serving immediately. Requires `domains:write`. */
2589
+ retireWebEntry(host: string): Promise<{
2590
+ success: true;
2591
+ host: string;
2592
+ }>;
2593
+ /**
2594
+ * Register a custom domain on behalf of one of the caller tenant's
2595
+ * sub-tenants ("custom domains for your customers"). `parentTenantId`,
2596
+ * when provided, must equal the caller's own tenantId — the server never
2597
+ * trusts a client-supplied parent tenant for cross-tenant registration.
2598
+ * Requires API key scope `domains:write`.
2599
+ *
2600
+ * Requires domain-service activation. The control-plane call is live, but
2601
+ * a registered domain/target does not serve traffic until the
2602
+ * domain-serving edge is provisioned (Phase 2). Custom and nested
2603
+ * (sub-tenant) domains additionally require an active domain entitlement
2604
+ * (paid SKU); pricing is not yet set. Subdomains are free.
2605
+ */
2606
+ registerDomainForSubTenant(params: {
2607
+ appId: string;
2608
+ domain: string;
2609
+ subTenantId: string;
2610
+ parentTenantId?: string;
2611
+ target?: DomainTarget;
2612
+ }): Promise<{
2613
+ success: boolean;
2614
+ domain: string;
2615
+ subTenantId: string;
2616
+ verificationToken: string;
2617
+ dnsRecords: DNSRecord[];
2618
+ }>;
2619
+ /**
2620
+ * Verify a delegated sub-tenant domain's DNS configuration.
2621
+ * Requires API key scope `domains:write`.
2622
+ *
2623
+ * Requires domain-service activation. The control-plane call is live, but
2624
+ * a registered domain/target does not serve traffic until the
2625
+ * domain-serving edge is provisioned (Phase 2). Custom and nested
2626
+ * (sub-tenant) domains additionally require an active domain entitlement
2627
+ * (paid SKU); pricing is not yet set. Subdomains are free.
2628
+ */
2629
+ verifyDomainForSubTenant(domain: string): Promise<{
2630
+ verified: boolean;
2631
+ sslStatus: SSLStatus;
2632
+ error?: string;
2633
+ }>;
2634
+ /**
2635
+ * List the caller tenant's delegated sub-tenant domains, optionally
2636
+ * filtered to one `subTenantId`. Requires API key scope `domains:read`.
2637
+ *
2638
+ * Requires domain-service activation. The control-plane call is live, but
2639
+ * a registered domain/target does not serve traffic until the
2640
+ * domain-serving edge is provisioned (Phase 2). Custom and nested
2641
+ * (sub-tenant) domains additionally require an active domain entitlement
2642
+ * (paid SKU); pricing is not yet set. Subdomains are free.
2643
+ */
2644
+ listSubTenantDomains(subTenantId?: string): Promise<{
2645
+ domains: SubTenantDomainSummary[];
2646
+ }>;
2647
+ /**
2648
+ * Remove a delegated sub-tenant domain. Requires API key scope
2649
+ * `domains:write`.
2650
+ *
2651
+ * Requires domain-service activation. The control-plane call is live, but
2652
+ * a registered domain/target does not serve traffic until the
2653
+ * domain-serving edge is provisioned (Phase 2). Custom and nested
2654
+ * (sub-tenant) domains additionally require an active domain entitlement
2655
+ * (paid SKU); pricing is not yet set. Subdomains are free.
2656
+ */
2657
+ removeSubTenantDomain(domain: string): Promise<{
2658
+ success: boolean;
2659
+ }>;
2660
+ getAnalytics(appId: string, params?: {
2661
+ startDate?: string;
2662
+ endDate?: string;
2663
+ }): Promise<AppAnalytics>;
2664
+ generateUI(prompt: string, context?: Record<string, unknown>, appId?: string): Promise<{
2665
+ components: ComponentNode[];
2666
+ }>;
2667
+ suggestActions(appId: string, componentType?: string, context?: Record<string, unknown>): Promise<{
2668
+ actions: unknown[];
2669
+ }>;
2670
+ startSession(appId: string, pageId: string): Promise<{
2671
+ sessionToken: string;
2672
+ wsEndpoint: string;
2673
+ }>;
2674
+ addComment(appId: string, pageId: string, componentId: string, content: string, threadId?: string): Promise<{
2675
+ commentId: string;
2676
+ }>;
2677
+ resolveComment(appId: string, pageId: string, commentId: string): Promise<void>;
2678
+ }
2679
+
2680
+ /**
2681
+ * MAKEMIND SDK - Marketplace Service
2682
+ *
2683
+ * Client-side SDK for the SaaS Marketplace feature.
2684
+ * Provides methods for browsing, installing, and publishing marketplace apps.
2685
+ *
2686
+ * @see docs/03_DDD/infra-sdk.md
2687
+ */
2688
+
2689
+ interface MAKEMINDMarketplaceConfig extends MAKEMINDConfig {
2690
+ apiClient: ApiClient;
2691
+ tenantId: () => string | null;
2692
+ }
2693
+ interface SearchOptions {
2694
+ query?: string;
2695
+ category?: string;
2696
+ tags?: string[];
2697
+ pricingModel?: string[];
2698
+ sortBy?: 'relevance' | 'rating' | 'installs' | 'newest' | 'price_asc' | 'price_desc';
2699
+ page?: number;
2700
+ limit?: number;
2701
+ }
2702
+ interface InstallResult {
2703
+ bindingId: string;
2704
+ status: string;
2705
+ trialExpiresAt?: string;
2706
+ }
2707
+ interface ReviewInput {
2708
+ listingId: string;
2709
+ rating: number;
2710
+ title?: string;
2711
+ body?: string;
2712
+ }
2713
+ interface PublisherProfileInput {
2714
+ displayName: string;
2715
+ description: string;
2716
+ logoUrl: string;
2717
+ websiteUrl?: string;
2718
+ supportEmail: string;
2719
+ }
2720
+ declare class MAKEMINDMarketplace {
2721
+ private apiClient;
2722
+ private getTenantId;
2723
+ constructor(config: MAKEMINDMarketplaceConfig);
2724
+ search(options?: SearchOptions): Promise<unknown>;
2725
+ getDetail(listingId: string): Promise<unknown>;
2726
+ browseCategory(categorySlug: string, options?: Omit<SearchOptions, 'category'>): Promise<unknown>;
2727
+ getFeatured(): Promise<unknown>;
2728
+ getTrending(): Promise<unknown>;
2729
+ getRecommendations(): Promise<unknown>;
2730
+ listCategories(): Promise<unknown>;
2731
+ install(listingId: string): Promise<InstallResult>;
2732
+ uninstall(listingId: string, cleanupData?: boolean): Promise<unknown>;
2733
+ listInstalled(options?: {
2734
+ status?: string;
2735
+ page?: number;
2736
+ limit?: number;
2737
+ }): Promise<unknown>;
2738
+ updateApp(listingId: string): Promise<unknown>;
2739
+ proxy(bindingId: string, options: {
2740
+ method: string;
2741
+ path: string;
2742
+ body?: unknown;
2743
+ query?: Record<string, string>;
2744
+ }): Promise<unknown>;
2745
+ getApiSpec(bindingId: string): Promise<unknown>;
2746
+ getConfig(bindingId: string): Promise<unknown>;
2747
+ updateConfig(bindingId: string, updates: Record<string, unknown>): Promise<unknown>;
2748
+ issueCredentials(bindingId: string): Promise<unknown>;
2749
+ revokeCredentials(bindingId: string): Promise<unknown>;
2750
+ createReview(input: ReviewInput): Promise<unknown>;
2751
+ updateReview(reviewId: string, listingId: string, updates: {
2752
+ rating?: number;
2753
+ title?: string;
2754
+ body?: string;
2755
+ }): Promise<unknown>;
2756
+ deleteReview(reviewId: string, listingId: string): Promise<unknown>;
2757
+ listReviews(listingId: string, options?: {
2758
+ sortBy?: string;
2759
+ page?: number;
2760
+ limit?: number;
2761
+ }): Promise<unknown>;
2762
+ replyToReview(reviewId: string, listingId: string, body: string): Promise<unknown>;
2763
+ reportReview(reviewId: string, listingId: string, reason: string): Promise<unknown>;
2764
+ voteHelpful(reviewId: string, listingId: string): Promise<unknown>;
2765
+ createPublisherProfile(input: PublisherProfileInput): Promise<unknown>;
2766
+ updatePublisherProfile(updates: Partial<PublisherProfileInput>): Promise<unknown>;
2767
+ getDashboard(): Promise<unknown>;
2768
+ createListing(input: Record<string, unknown>): Promise<unknown>;
2769
+ updateListing(listingId: string, updates: Record<string, unknown>): Promise<unknown>;
2770
+ submitForReview(listingId: string): Promise<unknown>;
2771
+ publishListing(listingId: string): Promise<unknown>;
2772
+ archiveListing(listingId: string): Promise<unknown>;
2773
+ reactivateListing(listingId: string): Promise<unknown>;
2774
+ createVersion(listingId: string, version: string, changelog: string, appVersionId: string, breakingChanges?: boolean): Promise<unknown>;
2775
+ approveListing(listingId: string): Promise<unknown>;
2776
+ rejectListing(listingId: string, reason: string): Promise<unknown>;
2777
+ suspendListing(listingId: string, reason: string): Promise<unknown>;
2778
+ approveVersion(listingId: string, versionId: string): Promise<unknown>;
2779
+ verifyPublisher(tenantId: string): Promise<unknown>;
2780
+ suspendPublisher(tenantId: string, reason: string): Promise<unknown>;
2781
+ reactivatePublisher(tenantId: string): Promise<unknown>;
2782
+ adminCreateCategory(data: {
2783
+ name: string;
2784
+ slug: string;
2785
+ parentId?: string;
2786
+ sortOrder?: number;
2787
+ }): Promise<unknown>;
2788
+ adminUpdateCategory(categoryId: string, data: Record<string, unknown>): Promise<unknown>;
2789
+ adminDeleteCategory(categoryId: string): Promise<unknown>;
2790
+ getAnalytics(params?: {
2791
+ startDate?: string;
2792
+ endDate?: string;
2793
+ granularity?: string;
2794
+ }): Promise<unknown>;
2795
+ getPendingListings(params?: {
2796
+ status?: string;
2797
+ page?: number;
2798
+ limit?: number;
2799
+ }): Promise<unknown>;
2800
+ listPublishers(params?: {
2801
+ status?: string;
2802
+ page?: number;
2803
+ limit?: number;
2804
+ }): Promise<unknown>;
2805
+ }
2806
+
2807
+ interface MAKEMINDClientConfig {
2808
+ apiKey: string;
2809
+ applicationId: string;
2810
+ environment?: 'development' | 'staging' | 'production';
2811
+ baseUrl?: string;
2812
+ /** Gateway API version segment. Defaults to 'v1'. */
2813
+ apiVersion?: string;
2814
+ /**
2815
+ * Optional App Check token provider (first-party apps only). When set, its
2816
+ * token is attached as `X-Firebase-AppCheck` on every gateway call so the app
2817
+ * passes App Check enforcement on pre-login endpoints. Omit for M2M/API-key
2818
+ * integrations — those are exempt from App Check server-side.
2819
+ */
2820
+ getAppCheckToken?: () => Promise<string | null>;
2821
+ }
2822
+ declare class MAKEMINDClient {
2823
+ private apiClient;
2824
+ private applicationId;
2825
+ private environment;
2826
+ private _auth;
2827
+ private _data;
2828
+ private _logic;
2829
+ private _tenant;
2830
+ private _messaging;
2831
+ private _settlement;
2832
+ private _partners;
2833
+ private _storage;
2834
+ private _ai;
2835
+ private _search;
2836
+ private _apps;
2837
+ private _marketplace;
2838
+ private currentTenantId;
2839
+ private currentUserId;
2840
+ private authToken;
2841
+ constructor(config: MAKEMINDClientConfig);
2842
+ setAuthToken(token: string): void;
2843
+ setUserContext(userId: string, tenantId: string | null): void;
2844
+ get tenantId(): string | null;
2845
+ get userId(): string | null;
2846
+ setTenantContext(tenantId: string): void;
2847
+ getApiClient(): ApiClient;
2848
+ /**
2849
+ * Invoke a platform Callable operation through the gateway RPC dispatch
2850
+ * (`POST /api/v1/call/:operation`). The operation name matches the deployed
2851
+ * Callable key (namespaced groups use `<prefix>-<name>`, e.g.
2852
+ * `settlement-getMRR`; flat exports use the bare name, e.g. `createTenant`).
2853
+ *
2854
+ * This is the platform-operation channel, distinct from `logic.call()` which
2855
+ * runs a tenant-defined logic function. Each operation enforces its own
2856
+ * authorization server-side (platform roles / tenant scopes), so exposing
2857
+ * this method does not bypass access control. Returns the operation's result
2858
+ * value directly (the `{ data }` envelope is already unwrapped).
2859
+ */
2860
+ call<T = unknown>(operation: string, input?: unknown): Promise<T>;
2861
+ get auth(): MAKEMINDAuth;
2862
+ get data(): MAKEMINDData;
2863
+ get logic(): MAKEMINDLogic;
2864
+ get tenant(): MAKEMINDTenant;
2865
+ get messaging(): MAKEMINDMessaging;
2866
+ get settlement(): MAKEMINDSettlement;
2867
+ get partners(): MAKEMINDPartners;
2868
+ get storage(): MAKEMINDStorage;
2869
+ get ai(): MAKEMINDAI;
2870
+ get search(): MAKEMINDSearch;
2871
+ get apps(): MAKEMINDApps;
2872
+ get marketplace(): MAKEMINDMarketplace;
2873
+ }
2874
+ declare function initializeMAKEMIND(config: MAKEMINDClientConfig): MAKEMINDClient;
2875
+ declare function getMAKEMIND(): MAKEMINDClient;
2876
+
2877
+ /**
2878
+ * The expert guest door — the one SDK surface that carries no credential.
2879
+ *
2880
+ * Deliberately not built on `ApiClient`. That client attaches `X-API-Key` to
2881
+ * every request by construction, and a key in a browser carries
2882
+ * `expert:execute` over the tenant's whole budget. A page embedding an expert
2883
+ * must not be able to ship one by accident, so this talks to the public routes
2884
+ * with its own fetch that has no credential to attach.
2885
+ *
2886
+ * The only attestation is App Check, which the tenant's own web app produces.
2887
+ *
2888
+ * What a guest holds instead of an account is a capability: a token minted on
2889
+ * the first turn and returned once. Whoever holds it holds the thread; losing
2890
+ * it loses the thread, and nothing recovers it — there is no account to recover
2891
+ * into. Say that on any page that opens one.
2892
+ *
2893
+ * @see docs/03_DDD/feat-expert/20-public-consumption-surfaces.md
2894
+ */
2895
+ interface MAKEMINDExpertsConfig {
2896
+ /** Gateway origin, e.g. `https://api.makemind.app`. */
2897
+ baseUrl: string;
2898
+ /** The tenant whose expert is being consulted. */
2899
+ tenantId: string;
2900
+ /** Supplies an App Check token. Omit only where the tenant has none configured. */
2901
+ appCheck?: () => string | null | Promise<string | null>;
2902
+ /** Injected in tests; defaults to the global. */
2903
+ fetchImpl?: typeof fetch;
2904
+ }
2905
+ interface ExpertAccess {
2906
+ token: string;
2907
+ expiresAt?: unknown;
2908
+ }
2909
+ interface ConsultationConclusion {
2910
+ value: string;
2911
+ origin: 'rule' | 'model';
2912
+ }
2913
+ interface ExpertConsultation {
2914
+ id: string;
2915
+ status: string;
2916
+ /** Present when the expert declined; it is an answer, not a failure. */
2917
+ refusal?: string;
2918
+ synthesis?: {
2919
+ answer?: string;
2920
+ confidence?: number;
2921
+ conclusions?: Record<string, ConsultationConclusion>;
2922
+ };
2923
+ budget?: {
2924
+ tokensUsed: number;
2925
+ tokensMax: number;
2926
+ };
2927
+ [key: string]: unknown;
2928
+ }
2929
+ interface ConsultResult extends ExpertConsultation {
2930
+ access?: ExpertAccess;
2931
+ }
2932
+ interface ExpertTurn {
2933
+ question: string;
2934
+ answer?: string;
2935
+ consultationId: string;
2936
+ }
2937
+ interface ExpertSession {
2938
+ id: string;
2939
+ turns: ExpertTurn[];
2940
+ [key: string]: unknown;
2941
+ }
2942
+ /** The platform's refusal, surfaced with its own name rather than a generic failure. */
2943
+ declare class ExpertDoorError extends Error {
2944
+ readonly code: string;
2945
+ readonly status: number;
2946
+ constructor(code: string, message: string, status: number);
2947
+ }
2948
+ declare class MAKEMINDExperts {
2949
+ private readonly baseUrl;
2950
+ private readonly tenantId;
2951
+ private readonly appCheck?;
2952
+ private readonly fetchImpl;
2953
+ constructor(config: MAKEMINDExpertsConfig);
2954
+ private post;
2955
+ /** One question, one answer, and the capability to read it back. */
2956
+ consult(options: {
2957
+ expertId: string;
2958
+ question: string;
2959
+ facts?: Record<string, unknown>;
2960
+ }): Promise<ConsultResult>;
2961
+ /**
2962
+ * Open a conversation, or resume one whose capability the caller kept.
2963
+ * @param {Object} options The expert to open, or a thread to resume.
2964
+ * @return {ExpertChat} A thread that carries its own capability.
2965
+ */
2966
+ chat(options: {
2967
+ expertId: string;
2968
+ sessionId?: string;
2969
+ accessToken?: string;
2970
+ }): ExpertChat;
2971
+ /** @internal */
2972
+ converse(body: Record<string, unknown>): Promise<{
2973
+ sessionId: string;
2974
+ consultation: ExpertConsultation;
2975
+ access?: ExpertAccess;
2976
+ }>;
2977
+ getConsultation(options: {
2978
+ consultationId: string;
2979
+ accessToken: string;
2980
+ }): Promise<ExpertConsultation>;
2981
+ getSession(options: {
2982
+ sessionId: string;
2983
+ accessToken: string;
2984
+ }): Promise<ExpertSession>;
2985
+ }
2986
+ /**
2987
+ * A thread and the capability that names it.
2988
+ *
2989
+ * The first `ask` opens the thread and takes the token from the answer; every
2990
+ * later one presents it. Callers that want a visitor's thread to survive a
2991
+ * reload persist `sessionId` and `accessToken` themselves and hand them back to
2992
+ * `chat()` — the SDK does not reach into storage on its own.
2993
+ */
2994
+ declare class ExpertChat {
2995
+ private readonly api;
2996
+ private readonly expertId;
2997
+ private session?;
2998
+ private token?;
2999
+ private readonly turns;
3000
+ constructor(api: MAKEMINDExperts, options: {
3001
+ expertId: string;
3002
+ sessionId?: string;
3003
+ accessToken?: string;
3004
+ });
3005
+ get sessionId(): string | undefined;
3006
+ get accessToken(): string | undefined;
3007
+ get history(): ExpertTurn[];
3008
+ /**
3009
+ * Ask, and keep whatever the thread needs to be continued.
3010
+ * @param {string} question What the visitor asked.
3011
+ * @param {Object} [facts] Structured facts the rules read.
3012
+ * @return {Promise<ExpertConsultation>} The turn's record. A refusal comes
3013
+ * back as an answer with `refusal` set; only a closed door throws.
3014
+ */
3015
+ ask(question: string, facts?: Record<string, unknown>): Promise<ExpertConsultation>;
3016
+ }
3017
+
3018
+ interface ExpertChatWidgetOptions extends MAKEMINDExpertsConfig {
3019
+ expertId: string;
3020
+ /** Shown above the thread. */
3021
+ title?: string;
3022
+ placeholder?: string;
3023
+ /**
3024
+ * Where the thread is remembered across reloads. Defaults to `localStorage`
3025
+ * when the page has one. Pass `null` to remember nothing — a visitor on a
3026
+ * shared machine leaves nothing behind, at the cost of the thread.
3027
+ */
3028
+ storage?: Pick<Storage, 'getItem' | 'setItem' | 'removeItem'> | null;
3029
+ /**
3030
+ * The line that tells a visitor the link is the only way back. Overridable
3031
+ * for wording and translation; removing it is the embedder's decision to
3032
+ * make, and their visitor's to regret.
3033
+ */
3034
+ bearerNotice?: string;
3035
+ }
3036
+ interface ExpertChatWidget {
3037
+ /** Ask programmatically — the same path the input takes. */
3038
+ ask(question: string): Promise<void>;
3039
+ /** Remove the UI and stop. The remembered thread is left alone. */
3040
+ destroy(): void;
3041
+ /** What the page would need to re-open this thread elsewhere. */
3042
+ readonly thread: {
3043
+ sessionId?: string;
3044
+ accessToken?: string;
3045
+ };
3046
+ }
3047
+ /**
3048
+ * Mount a chat into an element.
3049
+ * @param {HTMLElement} el Where it goes. Its contents are replaced.
3050
+ * @param {ExpertChatWidgetOptions} options Tenant, expert and presentation.
3051
+ * @return {ExpertChatWidget} A handle to ask, read the thread, or remove it.
3052
+ */
3053
+ declare function mountExpertChat(el: HTMLElement, options: ExpertChatWidgetOptions): ExpertChatWidget;
3054
+
3055
+ declare class MAKEMINDError extends Error {
3056
+ code: string;
3057
+ details?: Record<string, unknown>;
3058
+ constructor(code: string, message: string, details?: Record<string, unknown>);
3059
+ static fromApiError(error: unknown): MAKEMINDError;
3060
+ static fromHttpStatus(status: number, body?: unknown): MAKEMINDError;
3061
+ toJSON(): PlatformErrorDetails;
3062
+ }
3063
+ declare const ErrorCodes: {
3064
+ readonly UNAUTHENTICATED: "UNAUTHENTICATED";
3065
+ readonly PERMISSION_DENIED: "PERMISSION_DENIED";
3066
+ readonly INVALID_TOKEN: "INVALID_TOKEN";
3067
+ readonly NOT_FOUND: "NOT_FOUND";
3068
+ readonly ALREADY_EXISTS: "ALREADY_EXISTS";
3069
+ readonly VALIDATION_ERROR: "VALIDATION_ERROR";
3070
+ readonly TENANT_NOT_FOUND: "TENANT_NOT_FOUND";
3071
+ readonly TENANT_SUSPENDED: "TENANT_SUSPENDED";
3072
+ readonly NOT_A_MEMBER: "NOT_A_MEMBER";
3073
+ readonly QUOTA_EXCEEDED: "QUOTA_EXCEEDED";
3074
+ readonly STORAGE_ERROR: "STORAGE_ERROR";
3075
+ readonly INTERNAL_ERROR: "INTERNAL_ERROR";
3076
+ readonly SERVICE_UNAVAILABLE: "SERVICE_UNAVAILABLE";
3077
+ readonly UNKNOWN_ERROR: "UNKNOWN_ERROR";
3078
+ };
3079
+
3080
+ export { ApiClient, type ApiClientConfig, type ApiRequestOptions, type AuthStateCallback, type AuthUser, type BillingSummary, type CollectionSnapshotCallback, type ConsultResult, type ConsultationConclusion, type CreateOptions, type DeleteOptions, type DocumentResult, ErrorCodes, type ExpertAccess, ExpertChat, type ExpertChatWidget, type ExpertChatWidgetOptions, type ExpertConsultation, ExpertDoorError, type ExpertSession, type ExpertTurn, type FileMetadata, type FlowListItem, type GetOptions, type Invoice, type ListFilesOptions, type ListFilesResult, type ListFlowsParams, type ListFlowsResult, type LogicCallResult, MAKEMINDAI, type MAKEMINDAIConfig, MAKEMINDApps, type MAKEMINDAppsConfig, MAKEMINDAuth, type MAKEMINDAuthConfig, MAKEMINDClient, type MAKEMINDClientConfig, type MAKEMINDConfig, MAKEMINDData, type MAKEMINDDataConfig, MAKEMINDError, MAKEMINDExperts, type MAKEMINDExpertsConfig, MAKEMINDLogic, type MAKEMINDLogicConfig, MAKEMINDMarketplace, type MAKEMINDMarketplaceConfig, MAKEMINDMessaging, type MAKEMINDMessagingConfig, MAKEMINDSearch, type MAKEMINDSearchConfig, MAKEMINDSettlement, type MAKEMINDSettlementConfig, MAKEMINDStorage, type MAKEMINDStorageConfig, MAKEMINDTenant, type MAKEMINDTenantConfig, type Notification, type OrderBy, type PlatformErrorDetails, type QueryCondition, type QueryOptions, type QueryResult, type SendMessageOptions, type SnapshotCallback, type Tenant, type TenantClaims, type TenantMember, type Unsubscribe, type UpdateOptions, type UploadOptions, type UploadResult, type UsageEventOptions, type UsageStats, type WorkflowTransitionOptions, type Workspace, getMAKEMIND, initializeMAKEMIND, mountExpertChat };