@cosmoops/connect-sdk 0.6.0 → 0.9.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.
Files changed (138) hide show
  1. package/CHANGELOG.md +165 -0
  2. package/README.md +273 -91
  3. package/dist/cjs/cli/doctor.js +3 -3
  4. package/dist/cjs/cli/init.js +3 -3
  5. package/dist/cjs/client/components/access-gate.js +42 -7
  6. package/dist/cjs/client/components/account-sessions.js +3 -3
  7. package/dist/cjs/client/components/ai-format.js +135 -0
  8. package/dist/cjs/client/components/ai-widgets.js +232 -0
  9. package/dist/cjs/client/components/app-shell.js +9 -8
  10. package/dist/cjs/client/components/apps-grid.js +3 -3
  11. package/dist/cjs/client/components/ask-ai.js +334 -0
  12. package/dist/cjs/client/components/feature-gate.js +2 -2
  13. package/dist/cjs/client/components/integrations-modal.js +1 -1
  14. package/dist/cjs/client/components/logo.js +3 -3
  15. package/dist/cjs/client/components/nav.js +1 -1
  16. package/dist/cjs/client/components/plan-pricing.js +1 -1
  17. package/dist/cjs/client/components/plans.js +6 -6
  18. package/dist/cjs/client/components/readiness.js +3 -3
  19. package/dist/cjs/client/components/side-nav.js +1 -1
  20. package/dist/cjs/client/components/subscribe-dialog.js +2 -2
  21. package/dist/cjs/client/components/subscription.js +1 -1
  22. package/dist/cjs/client/components/usage-meter.js +1 -1
  23. package/dist/cjs/client/components/user-menu.js +31 -8
  24. package/dist/cjs/client/components/workspace-type-gate.js +48 -0
  25. package/dist/cjs/client/index.js +32 -4
  26. package/dist/cjs/client/mark.js +1 -1
  27. package/dist/cjs/client/provider.js +50 -7
  28. package/dist/cjs/client/use-checkout.js +3 -3
  29. package/dist/cjs/errors.js +4 -4
  30. package/dist/cjs/helpers.js +1 -1
  31. package/dist/cjs/index.js +1 -1
  32. package/dist/cjs/next/index.js +2 -2
  33. package/dist/cjs/server/client.js +15 -15
  34. package/dist/cjs/server/handler.js +56 -13
  35. package/dist/cjs/server/http.js +47 -25
  36. package/dist/cjs/server/resources/access.js +3 -3
  37. package/dist/cjs/server/resources/ai.js +1 -1
  38. package/dist/cjs/server/resources/analytics.js +2 -2
  39. package/dist/cjs/server/resources/apps.js +4 -4
  40. package/dist/cjs/server/resources/billing.js +5 -5
  41. package/dist/cjs/server/resources/drive.js +4 -4
  42. package/dist/cjs/server/resources/entitlements.js +48 -7
  43. package/dist/cjs/server/resources/identity.js +6 -4
  44. package/dist/cjs/server/resources/integrations.js +13 -13
  45. package/dist/cjs/server/resources/logs.js +3 -3
  46. package/dist/cjs/server/resources/sessions.js +6 -6
  47. package/dist/cjs/server/webhooks.js +4 -4
  48. package/dist/cjs/types.js +1 -1
  49. package/dist/esm/cli/doctor.js +3 -3
  50. package/dist/esm/cli/init.js +3 -3
  51. package/dist/esm/client/components/access-gate.js +43 -8
  52. package/dist/esm/client/components/account-sessions.js +3 -3
  53. package/dist/esm/client/components/ai-format.js +129 -0
  54. package/dist/esm/client/components/ai-widgets.js +223 -0
  55. package/dist/esm/client/components/app-shell.js +8 -7
  56. package/dist/esm/client/components/apps-grid.js +3 -3
  57. package/dist/esm/client/components/ask-ai.js +331 -0
  58. package/dist/esm/client/components/feature-gate.js +2 -2
  59. package/dist/esm/client/components/integrations-modal.js +1 -1
  60. package/dist/esm/client/components/logo.js +3 -3
  61. package/dist/esm/client/components/nav.js +1 -1
  62. package/dist/esm/client/components/plan-pricing.js +1 -1
  63. package/dist/esm/client/components/plans.js +6 -6
  64. package/dist/esm/client/components/readiness.js +3 -3
  65. package/dist/esm/client/components/side-nav.js +1 -1
  66. package/dist/esm/client/components/subscribe-dialog.js +2 -2
  67. package/dist/esm/client/components/subscription.js +1 -1
  68. package/dist/esm/client/components/usage-meter.js +1 -1
  69. package/dist/esm/client/components/user-menu.js +31 -8
  70. package/dist/esm/client/components/workspace-type-gate.js +45 -0
  71. package/dist/esm/client/index.js +14 -3
  72. package/dist/esm/client/mark.js +1 -1
  73. package/dist/esm/client/provider.js +48 -7
  74. package/dist/esm/client/use-checkout.js +3 -3
  75. package/dist/esm/errors.js +4 -4
  76. package/dist/esm/helpers.js +1 -1
  77. package/dist/esm/index.js +1 -1
  78. package/dist/esm/next/index.js +2 -2
  79. package/dist/esm/server/client.js +15 -15
  80. package/dist/esm/server/handler.js +56 -13
  81. package/dist/esm/server/http.js +47 -25
  82. package/dist/esm/server/resources/access.js +3 -3
  83. package/dist/esm/server/resources/ai.js +1 -1
  84. package/dist/esm/server/resources/analytics.js +2 -2
  85. package/dist/esm/server/resources/apps.js +4 -4
  86. package/dist/esm/server/resources/billing.js +5 -5
  87. package/dist/esm/server/resources/drive.js +4 -4
  88. package/dist/esm/server/resources/entitlements.js +48 -7
  89. package/dist/esm/server/resources/identity.js +6 -4
  90. package/dist/esm/server/resources/integrations.js +13 -13
  91. package/dist/esm/server/resources/logs.js +3 -3
  92. package/dist/esm/server/resources/sessions.js +6 -6
  93. package/dist/esm/server/webhooks.js +4 -4
  94. package/dist/esm/types.js +1 -1
  95. package/dist/theme.css +87 -0
  96. package/dist/types/client/components/access-gate.d.ts +18 -4
  97. package/dist/types/client/components/account-sessions.d.ts +1 -1
  98. package/dist/types/client/components/ai-format.d.ts +24 -0
  99. package/dist/types/client/components/ai-widgets.d.ts +42 -0
  100. package/dist/types/client/components/app-shell.d.ts +25 -9
  101. package/dist/types/client/components/apps-grid.d.ts +1 -1
  102. package/dist/types/client/components/ask-ai.d.ts +73 -0
  103. package/dist/types/client/components/feature-gate.d.ts +1 -1
  104. package/dist/types/client/components/integrations-modal.d.ts +1 -1
  105. package/dist/types/client/components/logo.d.ts +5 -5
  106. package/dist/types/client/components/nav.d.ts +3 -3
  107. package/dist/types/client/components/plan-pricing.d.ts +2 -2
  108. package/dist/types/client/components/readiness.d.ts +2 -2
  109. package/dist/types/client/components/side-nav.d.ts +1 -1
  110. package/dist/types/client/components/subscribe-dialog.d.ts +3 -3
  111. package/dist/types/client/components/usage-meter.d.ts +1 -1
  112. package/dist/types/client/components/user-menu.d.ts +4 -3
  113. package/dist/types/client/components/workspace-type-gate.d.ts +48 -0
  114. package/dist/types/client/index.d.ts +11 -4
  115. package/dist/types/client/mark.d.ts +1 -1
  116. package/dist/types/client/provider.d.ts +52 -9
  117. package/dist/types/client/use-checkout.d.ts +3 -3
  118. package/dist/types/errors.d.ts +4 -4
  119. package/dist/types/helpers.d.ts +1 -1
  120. package/dist/types/index.d.ts +1 -1
  121. package/dist/types/next/index.d.ts +1 -1
  122. package/dist/types/server/client.d.ts +13 -13
  123. package/dist/types/server/handler.d.ts +2 -2
  124. package/dist/types/server/http.d.ts +6 -1
  125. package/dist/types/server/resources/access.d.ts +3 -3
  126. package/dist/types/server/resources/ai.d.ts +2 -2
  127. package/dist/types/server/resources/analytics.d.ts +2 -2
  128. package/dist/types/server/resources/apps.d.ts +4 -4
  129. package/dist/types/server/resources/billing.d.ts +4 -4
  130. package/dist/types/server/resources/drive.d.ts +4 -4
  131. package/dist/types/server/resources/entitlements.d.ts +37 -5
  132. package/dist/types/server/resources/identity.d.ts +2 -2
  133. package/dist/types/server/resources/integrations.d.ts +9 -9
  134. package/dist/types/server/resources/logs.d.ts +3 -3
  135. package/dist/types/server/resources/sessions.d.ts +5 -5
  136. package/dist/types/server/webhooks.d.ts +4 -4
  137. package/dist/types/types.d.ts +235 -61
  138. package/package.json +8 -2
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Wire types for the `/api/v1/service/*` surface - the service-partner API,
2
+ * Wire types for the `/api/v1/application/*` surface - the application-partner API,
3
3
  * and the only thing this SDK covers.
4
4
  *
5
5
  * Hand-written rather than generated so the published package carries no
@@ -25,11 +25,59 @@ export interface ConnectUser {
25
25
  * failing outright - so pair the two rather than branching on `null`.
26
26
  */
27
27
  photoUrl: string | null;
28
- organizationId: string;
29
- organizationName: string;
28
+ workspaceId: string;
29
+ workspaceName: string;
30
+ /**
31
+ * Whether this is a one-seat personal account or a team.
32
+ *
33
+ * The one fact about the signed-in workspace you cannot look up yourself -
34
+ * the application API has no workspace read - so branch on it rather than
35
+ * inferring an account's shape from whether it happens to have a second
36
+ * member. An `"individual"` workspace has exactly one seat and can never
37
+ * have another, so a members table, an invite button or a seat-count meter
38
+ * is dead UI for it.
39
+ *
40
+ * Re-read it from `identity.getUser()`; do not cache it past the sign-in.
41
+ * An `"individual"` workspace can convert to `"business"` under a live
42
+ * session (the reverse never happens).
43
+ */
44
+ workspaceType: WorkspaceType;
45
+ }
46
+ export type WorkspaceType = "individual" | "business";
47
+ export type ApplicationAudience = "b2b" | "b2c" | "both";
48
+ /**
49
+ * Whether the signed-in workspace is inside your application's audience -
50
+ * returned alongside `user` by both `exchangeCode()` and `getUser()`.
51
+ *
52
+ * `user.workspaceType` answers what the account *is*; this answers what your
53
+ * application is *sold to*, and whether the two agree. Both ship together so
54
+ * the check stays `!audience.matches` rather than a hardcoded audience
55
+ * constant in your own code that goes stale the moment the catalogue entry
56
+ * changes.
57
+ *
58
+ * `matches: false` means readiness will report an `audience_mismatch` blocker
59
+ * and any attempt to subscribe will be refused, so treat it as a hard block:
60
+ * `<ConnectAccessGate>` already does. What it is NOT is a reason to sign the
61
+ * user out - they have a valid Connect account, just the wrong kind of one
62
+ * for this application.
63
+ */
64
+ export interface SessionAudience {
65
+ /** Your catalogue entry's setting - `"both"` if you have never narrowed it. */
66
+ application: ApplicationAudience;
67
+ /** The single `workspaceType` `application` demands - `null` for `"both"`, which accepts either. */
68
+ requiredWorkspaceType: WorkspaceType | null;
69
+ /** `false` means this user is outside your audience. */
70
+ matches: boolean;
71
+ /**
72
+ * Whether Connect refuses the sign-in itself on a mismatch. When `true`,
73
+ * a `matches: false` can only reach you on a session minted before the
74
+ * setting was turned on. When `false`, gating is entirely yours to do -
75
+ * which is what `<ConnectAccessGate>` is for.
76
+ */
77
+ enforcedAtSignIn: boolean;
30
78
  }
31
79
  export type SubscriptionStatus = "created" | "authenticated" | "active" | "paused" | "cancelled";
32
- /** The compact subscription block returned alongside identity - `null` when the org has never subscribed to this service. */
80
+ /** The compact subscription block returned alongside identity - `null` when the workspace has never subscribed to this application. */
33
81
  export interface SessionSubscription {
34
82
  planId: string;
35
83
  status: SubscriptionStatus;
@@ -38,11 +86,11 @@ export interface SessionSubscription {
38
86
  isTrialing: boolean;
39
87
  }
40
88
  /**
41
- * What this member may do on *your* service - resolved for your `client_id`,
42
- * not their org-wide roles. `role` is `null` when their granted permissions
89
+ * What this member may do on *your* application - resolved for your `client_id`,
90
+ * not their workspace-wide roles. `role` is `null` when their granted permissions
43
91
  * match no single defined role, including when they have no access at all.
44
92
  */
45
- export interface ServiceRole {
93
+ export interface ApplicationRole {
46
94
  role: string | null;
47
95
  granted: string[];
48
96
  }
@@ -57,12 +105,16 @@ export interface TokenResponse {
57
105
  sessionTokenExpiresIn: number;
58
106
  user: ConnectUser;
59
107
  subscription: SessionSubscription | null;
60
- serviceRole: ServiceRole;
108
+ applicationRole: ApplicationRole;
109
+ /** Whether this account is the kind your application serves - see `SessionAudience`. */
110
+ audience: SessionAudience;
61
111
  }
62
112
  export interface UserResponse {
63
113
  user: ConnectUser;
64
114
  subscription: SessionSubscription | null;
65
- serviceRole: ServiceRole;
115
+ applicationRole: ApplicationRole;
116
+ /** Live, like `subscription` and `applicationRole` - a workspace that converted to a business since sign-in matches here without another sign-in. */
117
+ audience: SessionAudience;
66
118
  /** ISO 8601. Refresh proactively off this rather than waiting for a 401. */
67
119
  sessionExpiresAt: string;
68
120
  }
@@ -83,28 +135,28 @@ export interface IdTokenClaims {
83
135
  export type LogoutScope = "device" | "all";
84
136
  export interface UserRolesResponse {
85
137
  userId: string;
86
- organizationId: string;
138
+ workspaceId: string;
87
139
  role: string | null;
88
140
  granted: string[];
89
141
  }
90
- export interface ServicePermission {
142
+ export interface ApplicationPermission {
91
143
  id: string;
92
144
  label: string;
93
145
  description: string;
94
146
  }
95
- export interface ServiceRoleDefinition {
147
+ export interface ApplicationRoleDefinition {
96
148
  key: string;
97
149
  name: string;
98
150
  description: string;
99
151
  permissions: string[];
100
152
  }
101
153
  export interface RolesResponse {
102
- serviceId: string;
103
- serviceKey: string | null;
104
- permissionCatalog: ServicePermission[];
105
- roles: ServiceRoleDefinition[];
154
+ applicationId: string;
155
+ applicationKey: string | null;
156
+ permissionCatalog: ApplicationPermission[];
157
+ roles: ApplicationRoleDefinition[];
106
158
  }
107
- export type ReadinessBlockerCode = "subscription_missing" | "subscription_inactive" | "audience_mismatch" | "verification_required" | "verification_pending" | "verification_rejected" | "verification_expired" | "payment_method_missing" | "seat_limit_reached" | "organization_not_found" | "onboarding_approval_pending" | "onboarding_approval_rejected" | "organization_suspended" | "payment_retry_pending";
159
+ export type ReadinessBlockerCode = "subscription_missing" | "subscription_inactive" | "audience_mismatch" | "verification_required" | "verification_pending" | "verification_rejected" | "verification_expired" | "payment_method_missing" | "seat_limit_reached" | "workspace_not_found" | "onboarding_approval_pending" | "onboarding_approval_rejected" | "workspace_suspended" | "payment_retry_pending";
108
160
  export interface ReadinessBlocker {
109
161
  /**
110
162
  * Branch on this. Typed as a union for the codes that exist today, widened
@@ -119,10 +171,12 @@ export interface ReadinessBlocker {
119
171
  resolveUrl: string | null;
120
172
  /** When this blocker resolves itself automatically - currently only set on `payment_retry_pending`, the deadline dunning suspends the subscription. `undefined`/`null` for every other code. */
121
173
  graceEndsAt?: string | null;
174
+ /** The account type this application requires - set only on `audience_mismatch`, `undefined`/`null` otherwise. Branch on this rather than reading it out of `message`. */
175
+ requiredWorkspaceType?: "individual" | "business" | null;
122
176
  }
123
177
  export interface ReadinessResponse {
124
- organizationId: string;
125
- serviceId: string;
178
+ workspaceId: string;
179
+ applicationId: string;
126
180
  /** `false` if any blocker is `"blocking"`. */
127
181
  ready: boolean;
128
182
  readiness: {
@@ -159,7 +213,7 @@ export interface PlanAddon {
159
213
  *
160
214
  * Note the asymmetry with `SubscribedPlan.features`, which is bare
161
215
  * `string[]` and stays that way. That field is a gating contract - your
162
- * backend calls `hasFeature(orgId, "campaign-module")` against it, and
216
+ * backend calls `hasFeature(workspaceId, "campaign-module")` against it, and
163
217
  * `ConnectFeatureGate` matches on it - so turning it into objects would break
164
218
  * every check for a label nobody gates on. This one exists to be rendered,
165
219
  * and rendering a bare key puts "campaign-module" on a pricing card where it
@@ -170,7 +224,7 @@ export interface PlanAddon {
170
224
  export interface PlanFeature {
171
225
  /** The same value `SubscribedPlan.features` holds and `hasFeature` gates on. */
172
226
  key: string;
173
- /** Human label. Falls back to `key` for a plan predating the service's feature catalog. */
227
+ /** Human label. Falls back to `key` for a plan predating the application's feature catalog. */
174
228
  name: string;
175
229
  /** Empty string when the catalog carries no description. */
176
230
  description: string;
@@ -253,15 +307,42 @@ export interface SubscriptionDetail {
253
307
  appliedDiscount: AppliedDiscount | null;
254
308
  }
255
309
  export interface SubscriptionResponse {
256
- organizationId: string;
257
- serviceId: string;
310
+ workspaceId: string;
311
+ applicationId: string;
258
312
  /** Equivalent to `subscription?.status === "active"`. */
259
313
  hasActiveSubscription: boolean;
260
314
  subscription: SubscriptionDetail | null;
261
315
  /** `null` exactly when `subscription` is. */
262
316
  plan: SubscribedPlan | null;
263
317
  }
264
- /** One consumable add-on's remaining balance on an organization's subscription. */
318
+ /** One row of `subscribers.list()` - a workspace subscribed to your application. */
319
+ export interface ApplicationSubscriber {
320
+ subscriptionId: string;
321
+ workspaceId: string;
322
+ /** `null` when the workspace has been purged and only its tombstone remains. */
323
+ workspaceName: string | null;
324
+ /** `"active"`, `"suspended"`, `"pending_deletion"`, `"deleted"` - or `null` alongside a null `workspaceName`. */
325
+ workspaceStatus: string | null;
326
+ planId: string;
327
+ /** `null` if the plan was hard-deleted rather than archived. */
328
+ planName: string | null;
329
+ status: "created" | "authenticated" | "active" | "paused" | "cancelled";
330
+ seatCount: number;
331
+ /** ISO 8601. */
332
+ subscribedAt: string;
333
+ /** ISO 8601, or `null` for a cancelled/paused subscription. */
334
+ nextBillingDate: string | null;
335
+ }
336
+ export interface SubscribersResponse {
337
+ items: ApplicationSubscriber[];
338
+ /**
339
+ * Pass back as `before` for the next page. `null` on the last page - which
340
+ * is the only reliable end-of-list signal, since a full page can still be
341
+ * the last one.
342
+ */
343
+ nextBefore: string | null;
344
+ }
345
+ /** One consumable add-on's remaining balance on a workspace's subscription. */
265
346
  export interface AddonUsage {
266
347
  addonId: string;
267
348
  name: string;
@@ -284,10 +365,10 @@ export interface AddonUsage {
284
365
  maxOverageUnits: number | null;
285
366
  }
286
367
  export interface AddonUsageResponse {
287
- organizationId: string;
288
- serviceId: string;
368
+ workspaceId: string;
369
+ applicationId: string;
289
370
  /**
290
- * Empty when the organization has no subscription, the plan has no
371
+ * Empty when the workspace has no subscription, the plan has no
291
372
  * consumable add-ons, or none are selected. All three mean "nothing to
292
373
  * meter" and none is an error.
293
374
  *
@@ -301,7 +382,7 @@ export interface AddonUsageResponse {
301
382
  resetsAt: string | null;
302
383
  }
303
384
  export interface ConsumeAddonInput {
304
- organizationId: string;
385
+ workspaceId: string;
305
386
  addonId: string;
306
387
  /** Whole units of the add-on's `unit`. */
307
388
  quantity: number;
@@ -358,8 +439,8 @@ export interface WriteLogInput {
358
439
  * `sessionToken` - the same one the token exchange handed you.
359
440
  *
360
441
  * **There is no `userId` to send, deliberately.** The token is verified and
361
- * checked to have been minted for *your* service before anything is
362
- * attributed, exactly as `serviceId` comes from your API key rather than
442
+ * checked to have been minted for *your* application before anything is
443
+ * attributed, exactly as `applicationId` comes from your API key rather than
363
444
  * your body. An actor a caller could type is not an actor worth recording.
364
445
  *
365
446
  * Omit it for genuine server-to-server events with no user behind them.
@@ -384,10 +465,10 @@ export interface ChatMessage {
384
465
  role: "user" | "assistant" | "system";
385
466
  [field: string]: unknown;
386
467
  }
387
- export interface OrganizationApp {
388
- serviceId: string;
389
- /** Stable, human-readable key - branch on this, not `serviceId`, which is per-environment. */
390
- serviceKey: string | null;
468
+ export interface WorkspaceApp {
469
+ applicationId: string;
470
+ /** Stable, human-readable key - branch on this, not `applicationId`, which is per-environment. */
471
+ applicationKey: string | null;
391
472
  name: string;
392
473
  /** Plain text, HTML already stripped server-side. */
393
474
  description: string;
@@ -395,9 +476,9 @@ export interface OrganizationApp {
395
476
  iconUrl: string | null;
396
477
  /** A `lucide-react` icon name from Connect's curated set. */
397
478
  icon: string;
398
- /** Where a tile navigates. `null` when the service registered no site. */
479
+ /** Where a tile navigates. `null` when the application registered no site. */
399
480
  launchUrl: string | null;
400
- /** True for the service whose API key made the call - render it as the active tile. */
481
+ /** True for the application whose API key made the call - render it as the active tile. */
401
482
  isCurrent: boolean;
402
483
  /** Launchable but not healthy (paused, or cancelling at period end) - badge it, do not hide it. */
403
484
  needsAttention: boolean;
@@ -413,9 +494,9 @@ export interface SessionDevice {
413
494
  }
414
495
  /**
415
496
  * One login to the Connect account behind the `sessionToken` you called with -
416
- * not scoped to this service. A Connect session is one browser's login to
417
- * Connect itself, and it fans out to every partner service's own session -
418
- * Connect has no per-service session concept to filter by. `sessions.list()`
497
+ * not scoped to this application. A Connect session is one browser's login to
498
+ * Connect itself, and it fans out to every partner application's own session -
499
+ * Connect has no per-application session concept to filter by. `sessions.list()`
419
500
  * returns every one of them, exactly like Connect's own account settings
420
501
  * page does for the user themselves.
421
502
  */
@@ -445,15 +526,15 @@ export interface RevokeOtherSessionsResponse {
445
526
  export type ThemeMode = "light" | "dark" | "system";
446
527
  /**
447
528
  * `not_connected` never travels over the wire as a persisted state - it's
448
- * what `ListOrganizationIntegrationsUseCase` reports for a toolkit this
449
- * organization has no `IntegrationConnection` record for at all.
529
+ * what `ListWorkspaceIntegrationsUseCase` reports for a toolkit this
530
+ * workspace has no `IntegrationConnection` record for at all.
450
531
  */
451
532
  export type IntegrationConnectionStatus = "not_connected" | "pending" | "active" | "failed" | "disconnected" | "expired";
452
533
  /**
453
534
  * A Composio-hosted third-party toolkit (Google Calendar, Slack, Twitter/X,
454
- * ...) this organization can see - only ever one a platform admin enabled in
455
- * Connect's own Console, joined with this org's own connection status.
456
- * Connections are org-shared: one covers every member, the way a Slack app
535
+ * ...) this workspace can see - only ever one a platform admin enabled in
536
+ * Connect's own Console, joined with this workspace's own connection status.
537
+ * Connections are workspace-shared: one covers every member, the way a Slack app
457
538
  * install is shared rather than per-user.
458
539
  */
459
540
  export interface IntegrationToolkit {
@@ -481,7 +562,7 @@ export interface ExecuteIntegrationActionResponse {
481
562
  successful: boolean;
482
563
  }
483
564
  /**
484
- * The metrics Connect can report for your service.
565
+ * The metrics Connect can report for your application.
485
566
  *
486
567
  * Hand-written here rather than imported from Connect's own registry, like
487
568
  * every other wire type in this file, so the published package carries none of
@@ -530,7 +611,7 @@ export interface EmitEventInput {
530
611
  name: string;
531
612
  /** Defaults to now. Clamped server-side to within 48 hours. */
532
613
  occurredAt?: string | Date;
533
- /** Attributes the event to the signed-in user and their organization. */
614
+ /** Attributes the event to the signed-in user and their workspace. */
534
615
  sessionToken?: string;
535
616
  /** A whole number in the smallest unit of `unit` - paise, bytes, milliseconds. */
536
617
  value?: number;
@@ -551,18 +632,18 @@ export interface EmitEventsResponse {
551
632
  * `createConnectWebhookHandler` simply ignores anything you have not
552
633
  * registered a handler for.
553
634
  */
554
- export type ConnectWebhookEventType = "organization.deletion_scheduled" | "organization.deletion_cancelled" | "organization.deleted" | "subscription.cancelled";
635
+ export type ConnectWebhookEventType = "workspace.deletion_scheduled" | "workspace.deletion_cancelled" | "workspace.deleted" | "subscription.cancelled";
555
636
  /**
556
637
  * A workspace's deletion has been confirmed and the grace window is running.
557
638
  *
558
639
  * Access is *already* denied - readiness reports
559
- * `organization_pending_deletion` from this moment - so treat this as "stop
640
+ * `workspace_pending_deletion` from this moment - so treat this as "stop
560
641
  * writing", not "start planning". `purgeAfter` is what makes this event worth
561
642
  * having: the customer's data still exists until then, so an export or a
562
643
  * wind-down can run on the same clock rather than after everything is gone.
563
644
  */
564
- export interface OrganizationDeletionScheduledEvent {
565
- organizationId: string;
645
+ export interface WorkspaceDeletionScheduledEvent {
646
+ workspaceId: string;
566
647
  /** ISO-8601. When Connect destroys the workspace. */
567
648
  purgeAfter: string;
568
649
  requestedBy: "owner" | "platform_admin";
@@ -572,30 +653,30 @@ export interface OrganizationDeletionScheduledEvent {
572
653
  * The deletion was withdrawn and the workspace is live again.
573
654
  *
574
655
  * **Handle this one.** It is the event integrations forget, and its absence
575
- * is the worst failure of the set: a service that froze a workspace on
576
- * `organization.deletion_scheduled` and never unfreezes leaves a paying
656
+ * is the worst failure of the set: an application that froze a workspace on
657
+ * `workspace.deletion_scheduled` and never unfreezes leaves a paying
577
658
  * customer locked out of something that has no idea anything changed.
578
659
  */
579
- export interface OrganizationDeletionCancelledEvent {
580
- organizationId: string;
660
+ export interface WorkspaceDeletionCancelledEvent {
661
+ workspaceId: string;
581
662
  }
582
663
  /** The grace window closed and Connect purged the workspace. Purge your own copy. */
583
- export interface OrganizationDeletedEvent {
584
- organizationId: string;
664
+ export interface WorkspaceDeletedEvent {
665
+ workspaceId: string;
585
666
  /** ISO-8601. */
586
667
  purgedAt: string;
587
668
  }
588
669
  /** A subscription ended. Fires on its own, not only as part of a deletion. */
589
670
  export interface SubscriptionCancelledEvent {
590
- organizationId: string;
671
+ workspaceId: string;
591
672
  subscriptionId: string;
592
- serviceId: string;
673
+ applicationId: string;
593
674
  }
594
675
  /** Maps each event type to the shape of its `data`. */
595
676
  export interface ConnectWebhookEventMap {
596
- "organization.deletion_scheduled": OrganizationDeletionScheduledEvent;
597
- "organization.deletion_cancelled": OrganizationDeletionCancelledEvent;
598
- "organization.deleted": OrganizationDeletedEvent;
677
+ "workspace.deletion_scheduled": WorkspaceDeletionScheduledEvent;
678
+ "workspace.deletion_cancelled": WorkspaceDeletionCancelledEvent;
679
+ "workspace.deleted": WorkspaceDeletedEvent;
599
680
  "subscription.cancelled": SubscriptionCancelledEvent;
600
681
  }
601
682
  /** The envelope, as it arrives on the wire. */
@@ -613,3 +694,96 @@ export interface ConnectWebhookEnvelope<T extends ConnectWebhookEventType = Conn
613
694
  apiVersion: string;
614
695
  data: ConnectWebhookEventMap[T];
615
696
  }
697
+ /** How a scalar should be presented. See `AiValue` for what each one expects. */
698
+ export type AiValueFormat = "text" | "number"
699
+ /** A number in rupees - `12500`, not paise and not a formatted string. */
700
+ | "currency"
701
+ /** A fraction - `0.42` renders as 42%. */
702
+ | "percent"
703
+ /** An ISO 8601 date string. */
704
+ | "date"
705
+ /** An ISO 8601 datetime string. */
706
+ | "datetime"
707
+ /** A number of seconds. */
708
+ | "duration"
709
+ /** A number of bytes. */
710
+ | "bytes"
711
+ /** A short state word, drawn as a chip. */
712
+ | "status";
713
+ export type AiTone = "neutral" | "positive" | "warning" | "danger";
714
+ /** One cell. `null` is "no value" and renders as an em dash. */
715
+ export type AiValue = string | number | null;
716
+ export interface AiTableInput {
717
+ title?: string;
718
+ columns: {
719
+ label: string;
720
+ format: AiValueFormat;
721
+ }[];
722
+ /** Positional: one array per row, values in the same order as `columns`. */
723
+ rows: AiValue[][];
724
+ caption?: string;
725
+ }
726
+ export interface AiChartInput {
727
+ title?: string;
728
+ kind: "bar" | "line" | "area" | "pie";
729
+ xLabel?: string;
730
+ yLabel?: string;
731
+ valueFormat: AiValueFormat;
732
+ /** Every series shares the same x values, in the same order. */
733
+ series: {
734
+ name: string;
735
+ points: {
736
+ x: string;
737
+ y: number | null;
738
+ }[];
739
+ }[];
740
+ caption?: string;
741
+ }
742
+ export interface AiMetricsInput {
743
+ title?: string;
744
+ metrics: {
745
+ label: string;
746
+ value: AiValue;
747
+ format: AiValueFormat;
748
+ /** Signed change against the previous period, as a fraction. */
749
+ delta?: number | null;
750
+ /** Whether a rise is good - churn is `"down-is-good"`. Colouring a delta by sign alone gets this wrong half the time. */
751
+ deltaMeaning: "up-is-good" | "down-is-good" | "neutral";
752
+ hint?: string;
753
+ }[];
754
+ }
755
+ export interface AiTimelineInput {
756
+ title?: string;
757
+ /** Oldest first. */
758
+ events: {
759
+ at: string;
760
+ title: string;
761
+ detail?: string;
762
+ tone: AiTone;
763
+ }[];
764
+ }
765
+ export interface AiDetailsInput {
766
+ title?: string;
767
+ fields: {
768
+ label: string;
769
+ value: AiValue;
770
+ format: AiValueFormat;
771
+ tone: AiTone;
772
+ }[];
773
+ }
774
+ export interface AiStepsInput {
775
+ title?: string;
776
+ steps: {
777
+ title: string;
778
+ detail?: string;
779
+ }[];
780
+ }
781
+ export interface AiSourcesInput {
782
+ sources: {
783
+ title: string;
784
+ uri?: string;
785
+ snippet?: string;
786
+ }[];
787
+ }
788
+ /** The tools this client knows how to draw. Anything else in the stream is ignored. */
789
+ export type AiToolName = "showTable" | "showChart" | "showMetrics" | "showTimeline" | "showDetails" | "showSteps" | "showSources";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cosmoops/connect-sdk",
3
- "version": "0.6.0",
3
+ "version": "0.9.0",
4
4
  "description": "Official server-side SDK for the CosmoOps Connect platform API - Login with Connect, entitlements, billing and metering.",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "type": "commonjs",
@@ -73,6 +73,7 @@
73
73
  "build:storybook": "storybook build -o storybook-static"
74
74
  },
75
75
  "devDependencies": {
76
+ "@connect/ai": "workspace:*",
76
77
  "@connect/data": "workspace:*",
77
78
  "@heroui/react": "^3.2.2",
78
79
  "@heroui/styles": "^3.2.2",
@@ -87,6 +88,7 @@
87
88
  "react": "19.2.8",
88
89
  "react-dom": "19.2.8",
89
90
  "storybook": "^10.5.10",
91
+ "streamdown": "^2.5.0",
90
92
  "tailwindcss": "^4.3.3",
91
93
  "typedoc": "^0.28.20",
92
94
  "typedoc-plugin-markdown": "^4.12.0",
@@ -98,7 +100,8 @@
98
100
  "lucide-react": ">=0.400.0",
99
101
  "motion": ">=12",
100
102
  "react": ">=19",
101
- "react-dom": ">=19"
103
+ "react-dom": ">=19",
104
+ "streamdown": ">=2.5.0"
102
105
  },
103
106
  "peerDependenciesMeta": {
104
107
  "@heroui/react": {
@@ -115,6 +118,9 @@
115
118
  },
116
119
  "react-dom": {
117
120
  "optional": true
121
+ },
122
+ "streamdown": {
123
+ "optional": true
118
124
  }
119
125
  }
120
126
  }