@cosmoops/connect-sdk 0.6.0 → 0.7.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 (116) hide show
  1. package/dist/cjs/cli/doctor.js +3 -3
  2. package/dist/cjs/cli/init.js +3 -3
  3. package/dist/cjs/client/components/access-gate.js +3 -3
  4. package/dist/cjs/client/components/account-sessions.js +3 -3
  5. package/dist/cjs/client/components/app-shell.js +2 -2
  6. package/dist/cjs/client/components/apps-grid.js +3 -3
  7. package/dist/cjs/client/components/feature-gate.js +2 -2
  8. package/dist/cjs/client/components/integrations-modal.js +1 -1
  9. package/dist/cjs/client/components/logo.js +3 -3
  10. package/dist/cjs/client/components/plan-pricing.js +1 -1
  11. package/dist/cjs/client/components/plans.js +6 -6
  12. package/dist/cjs/client/components/readiness.js +3 -3
  13. package/dist/cjs/client/components/subscribe-dialog.js +2 -2
  14. package/dist/cjs/client/components/subscription.js +1 -1
  15. package/dist/cjs/client/components/usage-meter.js +1 -1
  16. package/dist/cjs/client/components/user-menu.js +4 -4
  17. package/dist/cjs/client/index.js +1 -1
  18. package/dist/cjs/client/mark.js +1 -1
  19. package/dist/cjs/client/provider.js +7 -7
  20. package/dist/cjs/client/use-checkout.js +3 -3
  21. package/dist/cjs/errors.js +4 -4
  22. package/dist/cjs/helpers.js +1 -1
  23. package/dist/cjs/index.js +1 -1
  24. package/dist/cjs/next/index.js +2 -2
  25. package/dist/cjs/server/client.js +15 -15
  26. package/dist/cjs/server/handler.js +13 -13
  27. package/dist/cjs/server/http.js +1 -1
  28. package/dist/cjs/server/resources/access.js +3 -3
  29. package/dist/cjs/server/resources/ai.js +1 -1
  30. package/dist/cjs/server/resources/analytics.js +2 -2
  31. package/dist/cjs/server/resources/apps.js +4 -4
  32. package/dist/cjs/server/resources/billing.js +5 -5
  33. package/dist/cjs/server/resources/drive.js +4 -4
  34. package/dist/cjs/server/resources/entitlements.js +7 -7
  35. package/dist/cjs/server/resources/identity.js +4 -4
  36. package/dist/cjs/server/resources/integrations.js +13 -13
  37. package/dist/cjs/server/resources/logs.js +3 -3
  38. package/dist/cjs/server/resources/sessions.js +6 -6
  39. package/dist/cjs/server/webhooks.js +4 -4
  40. package/dist/cjs/types.js +1 -1
  41. package/dist/esm/cli/doctor.js +3 -3
  42. package/dist/esm/cli/init.js +3 -3
  43. package/dist/esm/client/components/access-gate.js +3 -3
  44. package/dist/esm/client/components/account-sessions.js +3 -3
  45. package/dist/esm/client/components/app-shell.js +2 -2
  46. package/dist/esm/client/components/apps-grid.js +3 -3
  47. package/dist/esm/client/components/feature-gate.js +2 -2
  48. package/dist/esm/client/components/integrations-modal.js +1 -1
  49. package/dist/esm/client/components/logo.js +3 -3
  50. package/dist/esm/client/components/plan-pricing.js +1 -1
  51. package/dist/esm/client/components/plans.js +6 -6
  52. package/dist/esm/client/components/readiness.js +3 -3
  53. package/dist/esm/client/components/subscribe-dialog.js +2 -2
  54. package/dist/esm/client/components/subscription.js +1 -1
  55. package/dist/esm/client/components/usage-meter.js +1 -1
  56. package/dist/esm/client/components/user-menu.js +4 -4
  57. package/dist/esm/client/index.js +1 -1
  58. package/dist/esm/client/mark.js +1 -1
  59. package/dist/esm/client/provider.js +7 -7
  60. package/dist/esm/client/use-checkout.js +3 -3
  61. package/dist/esm/errors.js +4 -4
  62. package/dist/esm/helpers.js +1 -1
  63. package/dist/esm/index.js +1 -1
  64. package/dist/esm/next/index.js +2 -2
  65. package/dist/esm/server/client.js +15 -15
  66. package/dist/esm/server/handler.js +13 -13
  67. package/dist/esm/server/http.js +1 -1
  68. package/dist/esm/server/resources/access.js +3 -3
  69. package/dist/esm/server/resources/ai.js +1 -1
  70. package/dist/esm/server/resources/analytics.js +2 -2
  71. package/dist/esm/server/resources/apps.js +4 -4
  72. package/dist/esm/server/resources/billing.js +5 -5
  73. package/dist/esm/server/resources/drive.js +4 -4
  74. package/dist/esm/server/resources/entitlements.js +7 -7
  75. package/dist/esm/server/resources/identity.js +4 -4
  76. package/dist/esm/server/resources/integrations.js +13 -13
  77. package/dist/esm/server/resources/logs.js +3 -3
  78. package/dist/esm/server/resources/sessions.js +6 -6
  79. package/dist/esm/server/webhooks.js +4 -4
  80. package/dist/esm/types.js +1 -1
  81. package/dist/types/client/components/access-gate.d.ts +1 -1
  82. package/dist/types/client/components/account-sessions.d.ts +1 -1
  83. package/dist/types/client/components/app-shell.d.ts +4 -4
  84. package/dist/types/client/components/apps-grid.d.ts +1 -1
  85. package/dist/types/client/components/feature-gate.d.ts +1 -1
  86. package/dist/types/client/components/integrations-modal.d.ts +1 -1
  87. package/dist/types/client/components/logo.d.ts +5 -5
  88. package/dist/types/client/components/plan-pricing.d.ts +2 -2
  89. package/dist/types/client/components/readiness.d.ts +2 -2
  90. package/dist/types/client/components/subscribe-dialog.d.ts +3 -3
  91. package/dist/types/client/components/usage-meter.d.ts +1 -1
  92. package/dist/types/client/components/user-menu.d.ts +2 -2
  93. package/dist/types/client/index.d.ts +1 -1
  94. package/dist/types/client/mark.d.ts +1 -1
  95. package/dist/types/client/provider.d.ts +9 -9
  96. package/dist/types/client/use-checkout.d.ts +3 -3
  97. package/dist/types/errors.d.ts +4 -4
  98. package/dist/types/helpers.d.ts +1 -1
  99. package/dist/types/index.d.ts +1 -1
  100. package/dist/types/next/index.d.ts +1 -1
  101. package/dist/types/server/client.d.ts +13 -13
  102. package/dist/types/server/handler.d.ts +2 -2
  103. package/dist/types/server/resources/access.d.ts +3 -3
  104. package/dist/types/server/resources/ai.d.ts +2 -2
  105. package/dist/types/server/resources/analytics.d.ts +2 -2
  106. package/dist/types/server/resources/apps.d.ts +4 -4
  107. package/dist/types/server/resources/billing.d.ts +4 -4
  108. package/dist/types/server/resources/drive.d.ts +4 -4
  109. package/dist/types/server/resources/entitlements.d.ts +4 -4
  110. package/dist/types/server/resources/identity.d.ts +2 -2
  111. package/dist/types/server/resources/integrations.d.ts +9 -9
  112. package/dist/types/server/resources/logs.d.ts +3 -3
  113. package/dist/types/server/resources/sessions.d.ts +5 -5
  114. package/dist/types/server/webhooks.d.ts +4 -4
  115. package/dist/types/types.d.ts +61 -61
  116. package/package.json +1 -1
@@ -162,8 +162,8 @@ function checkEnv(root) {
162
162
  status: "fail",
163
163
  title: `${name} set`,
164
164
  detail: declaredEmpty
165
- ? `Declared but empty in .env.local. The value is in your service's Integration tab in Connect.`
166
- : `Not found in .env.local or the environment. Both values are in your service's Integration tab in Connect.`,
165
+ ? `Declared but empty in .env.local. The value is in your application's Integration tab in Connect.`
166
+ : `Not found in .env.local or the environment. Both values are in your application's Integration tab in Connect.`,
167
167
  };
168
168
  });
169
169
  }
@@ -176,7 +176,7 @@ function checkRedirectUri() {
176
176
  return {
177
177
  status: "warn",
178
178
  title: "Redirect URI registered in Connect",
179
- detail: "Not checkable from here. Confirm {your origin}/api/connect/callback is listed as a redirect URI in your service's Integration tab - including the deployed origin, not just http://localhost:3000.",
179
+ detail: "Not checkable from here. Confirm {your origin}/api/connect/callback is listed as a redirect URI in your application's Integration tab - including the deployed origin, not just http://localhost:3000.",
180
180
  };
181
181
  }
182
182
  const MARKER = { pass: " ok ", warn: " note ", fail: " FAIL " };
@@ -44,7 +44,7 @@ const PLANS_PAGE = `"use client";
44
44
  // with the other exports) whenever you want your own copy or layout.
45
45
  export { ConnectPlansPage as default } from "@cosmoops/connect-sdk/client";
46
46
  `;
47
- const ENV_TEMPLATE = `# CosmoOps Connect - values come from your service's Integration tab.
47
+ const ENV_TEMPLATE = `# CosmoOps Connect - values come from your application's Integration tab.
48
48
  CONNECT_API_KEY=
49
49
  CONNECT_CLIENT_ID=
50
50
  `;
@@ -111,7 +111,7 @@ function runInit(argv = []) {
111
111
  console.log(` ${marker} ${(0, node_path_1.relative)(root, target)} - ${scaffold.description}`);
112
112
  }
113
113
  const env = ensureEnv(root);
114
- console.log(` ${env === "skipped" ? "exists " : env === "appended" ? "updated" : "created"} .env.local - fill in the two values from your service's Integration tab`);
114
+ console.log(` ${env === "skipped" ? "exists " : env === "appended" ? "updated" : "created"} .env.local - fill in the two values from your application's Integration tab`);
115
115
  // The two steps a scaffolder must not do for you: editing an existing layout
116
116
  // means parsing and rewriting JSX someone else wrote, and the redirect URI
117
117
  // lives in Connect, not in this repo.
@@ -137,7 +137,7 @@ Three things left, all one-time:
137
137
  Tailwind roots its content scan inside node_modules and skips your app.
138
138
 
139
139
  3. Register {your origin}/api/connect/callback as a redirect URI in your
140
- service's Integration tab in Connect.
140
+ application's Integration tab in Connect.
141
141
 
142
142
  No next.config.ts changes needed - not even transpilePackages: dist/ is
143
143
  already ES2022 with "use client" hoisted, so Turbopack and webpack consume it
@@ -47,7 +47,7 @@ function useConnectAccessGate() {
47
47
  }
48
48
  const readiness = data.readiness;
49
49
  const blocking = (0, helpers_js_1.blockingBlockers)(readiness);
50
- const suspended = blocking.find((b) => b.code === "organization_suspended");
50
+ const suspended = blocking.find((b) => b.code === "workspace_suspended");
51
51
  if (suspended)
52
52
  return { state: "suspended", blocker: suspended, paymentRetry: null };
53
53
  const noSubscription = blocking.find((b) => b.code === "subscription_missing");
@@ -110,13 +110,13 @@ function ConnectAccessGate({ children, fallback, loading, className }) {
110
110
  }
111
111
  function AccessGateFallback({ state, blocker, className, }) {
112
112
  if (state === "no_subscription") {
113
- return ((0, jsx_runtime_1.jsx)(GateCard, { icon: lucide_react_1.CreditCard, iconClassName: "text-accent", title: "Choose a plan to continue", message: blocker?.message ?? "This workspace isn't subscribed to this service yet.", actionLabel: "See plans", resolveUrl: blocker?.resolveUrl ?? null, className: className }));
113
+ return ((0, jsx_runtime_1.jsx)(GateCard, { icon: lucide_react_1.CreditCard, iconClassName: "text-accent", title: "Choose a plan to continue", message: blocker?.message ?? "This workspace isn't subscribed to this application yet.", actionLabel: "See plans", resolveUrl: blocker?.resolveUrl ?? null, className: className }));
114
114
  }
115
115
  if (state === "suspended") {
116
116
  return ((0, jsx_runtime_1.jsx)(GateCard, { icon: lucide_react_1.Ban, iconClassName: "text-danger", title: "Workspace suspended", message: blocker?.message ?? "This workspace has been suspended.", resolveUrl: null, className: className }));
117
117
  }
118
118
  if (state === "onboarding_pending") {
119
- return ((0, jsx_runtime_1.jsx)(GateCard, { icon: lucide_react_1.Clock, iconClassName: "text-muted", title: "Waiting on approval", message: blocker?.message ?? "This workspace is waiting on approval before it can use this service.", resolveUrl: null, className: className }));
119
+ return ((0, jsx_runtime_1.jsx)(GateCard, { icon: lucide_react_1.Clock, iconClassName: "text-muted", title: "Waiting on approval", message: blocker?.message ?? "This workspace is waiting on approval before it can use this application.", resolveUrl: null, className: className }));
120
120
  }
121
121
  // "blocked" - any other blocking code (verification, audience, seats, ...).
122
122
  // Full fidelity for a code this component doesn't special-case: the same
@@ -44,7 +44,7 @@ function ordered(sessions) {
44
44
  }
45
45
  /**
46
46
  * One row's revoke action, confirmed before it fires - revoking a session
47
- * ends every partner-service sign-in from that same browser, not just this
47
+ * ends every partner-application sign-in from that same browser, not just this
48
48
  * one. Closes on confirm, not on response - the same convention every
49
49
  * destructive confirmation in this codebase follows - so the dialog itself
50
50
  * needs no async/pending state of its own; the row simply disappears once
@@ -58,11 +58,11 @@ function ordered(sessions) {
58
58
  */
59
59
  function RevokeRow({ session, onRevoke }) {
60
60
  const label = deviceLabel(session);
61
- return ((0, jsx_runtime_1.jsxs)(react_2.AlertDialog, { children: [(0, jsx_runtime_1.jsx)(react_2.Button, { isIconOnly: true, size: "sm", variant: "tertiary", className: "shrink-0 text-muted hover:text-danger", "aria-label": `Sign out ${label}`, children: (0, jsx_runtime_1.jsx)(lucide_react_1.LogOut, { className: "size-4" }) }), (0, jsx_runtime_1.jsx)(react_2.AlertDialog.Backdrop, { children: (0, jsx_runtime_1.jsx)(react_2.AlertDialog.Container, { children: (0, jsx_runtime_1.jsxs)(react_2.AlertDialog.Dialog, { className: "sm:max-w-100", children: [(0, jsx_runtime_1.jsx)(react_2.AlertDialog.CloseTrigger, {}), (0, jsx_runtime_1.jsxs)(react_2.AlertDialog.Header, { children: [(0, jsx_runtime_1.jsx)(react_2.AlertDialog.Icon, { status: "danger" }), (0, jsx_runtime_1.jsx)(react_2.AlertDialog.Heading, { children: "Sign out this device?" })] }), (0, jsx_runtime_1.jsx)(react_2.AlertDialog.Body, { children: (0, jsx_runtime_1.jsxs)("p", { className: "text-sm text-muted", children: ["This ends every sign-in from ", label, ", on every service, not just this one."] }) }), (0, jsx_runtime_1.jsxs)(react_2.AlertDialog.Footer, { children: [(0, jsx_runtime_1.jsx)(react_2.Button, { slot: "close", variant: "secondary", className: "text-xs", children: "Cancel" }), (0, jsx_runtime_1.jsx)(react_2.Button, { slot: "close", variant: "danger", className: "text-xs", onPress: onRevoke, children: "Sign out" })] })] }) }) })] }));
61
+ return ((0, jsx_runtime_1.jsxs)(react_2.AlertDialog, { children: [(0, jsx_runtime_1.jsx)(react_2.Button, { isIconOnly: true, size: "sm", variant: "tertiary", className: "shrink-0 text-muted hover:text-danger", "aria-label": `Sign out ${label}`, children: (0, jsx_runtime_1.jsx)(lucide_react_1.LogOut, { className: "size-4" }) }), (0, jsx_runtime_1.jsx)(react_2.AlertDialog.Backdrop, { children: (0, jsx_runtime_1.jsx)(react_2.AlertDialog.Container, { children: (0, jsx_runtime_1.jsxs)(react_2.AlertDialog.Dialog, { className: "sm:max-w-100", children: [(0, jsx_runtime_1.jsx)(react_2.AlertDialog.CloseTrigger, {}), (0, jsx_runtime_1.jsxs)(react_2.AlertDialog.Header, { children: [(0, jsx_runtime_1.jsx)(react_2.AlertDialog.Icon, { status: "danger" }), (0, jsx_runtime_1.jsx)(react_2.AlertDialog.Heading, { children: "Sign out this device?" })] }), (0, jsx_runtime_1.jsx)(react_2.AlertDialog.Body, { children: (0, jsx_runtime_1.jsxs)("p", { className: "text-sm text-muted", children: ["This ends every sign-in from ", label, ", on every application, not just this one."] }) }), (0, jsx_runtime_1.jsxs)(react_2.AlertDialog.Footer, { children: [(0, jsx_runtime_1.jsx)(react_2.Button, { slot: "close", variant: "secondary", className: "text-xs", children: "Cancel" }), (0, jsx_runtime_1.jsx)(react_2.Button, { slot: "close", variant: "danger", className: "text-xs", onPress: onRevoke, children: "Sign out" })] })] }) }) })] }));
62
62
  }
63
63
  /**
64
64
  * Every device signed into this Connect account - not scoped to this
65
- * service, see `ConnectUserSession`'s doc comment. Owns the one
65
+ * application, see `ConnectUserSession`'s doc comment. Owns the one
66
66
  * `useConnectSessions()` call for this modal; every revoke action here
67
67
  * mutates through it and re-reads the list itself, since nothing else
68
68
  * invalidates it automatically - see `mutateResource`'s doc comment.
@@ -67,12 +67,12 @@ function BrandLink({ name, icon, homeHref, collapsed, renderLink, }) {
67
67
  });
68
68
  }
69
69
  /**
70
- * The application frame every CosmoOps service platform runs inside: a
70
+ * The application frame every CosmoOps application platform runs inside: a
71
71
  * collapsible sidebar, a top bar carrying the app launcher and the account
72
72
  * menu, and your pages in the middle.
73
73
  *
74
74
  * This is the piece each partner was otherwise writing by hand, and writing
75
- * slightly differently - which is how a family of services stops looking like
75
+ * slightly differently - which is how a family of applications stops looking like
76
76
  * one product. Everything that should be identical across platforms (the
77
77
  * lockup, the rail geometry, the active-route treatment, the launcher, the
78
78
  * account menu, the access gate) lives here; everything that genuinely
@@ -22,7 +22,7 @@ function AppTile({ app }) {
22
22
  }
23
23
  /**
24
24
  * The Google-style app launcher: a grid icon in your top bar that opens a
25
- * modal of every Connect service this organization can actually open.
25
+ * modal of every Connect application this workspace can actually open.
26
26
  *
27
27
  * Only launchable apps appear, so no tile is a dead end - a paused
28
28
  * subscription still shows, badged, because a dunning cycle should not make a
@@ -39,9 +39,9 @@ function ConnectAppsGrid({ className, label = "Switch app" }) {
39
39
  if (sessionLoading || !session?.user)
40
40
  return null;
41
41
  const apps = data?.apps ?? [];
42
- return ((0, jsx_runtime_1.jsx)(motion_js_1.MotionProvider, { children: (0, jsx_runtime_1.jsxs)(react_1.Modal, { children: [(0, jsx_runtime_1.jsx)(react_1.Button, { isIconOnly: true, variant: "primary", "aria-label": label, className: className, children: (0, jsx_runtime_1.jsx)(lucide_react_1.LayoutGrid, { className: "size-5" }) }), (0, jsx_runtime_1.jsx)(react_1.Modal.Backdrop, { children: (0, jsx_runtime_1.jsx)(react_1.Modal.Container, { children: (0, jsx_runtime_1.jsxs)(react_1.Modal.Dialog, { className: "sm:max-w-md", children: [(0, jsx_runtime_1.jsx)(react_1.Modal.CloseTrigger, {}), (0, jsx_runtime_1.jsx)(react_1.Modal.Header, { children: (0, jsx_runtime_1.jsx)(react_1.Modal.Heading, { children: "Your apps" }) }), (0, jsx_runtime_1.jsxs)(react_1.Modal.Body, { children: [isLoading && ((0, jsx_runtime_1.jsx)("div", { className: "grid grid-cols-3 gap-2", children: Array.from({ length: 6 }, (_, index) => ((0, jsx_runtime_1.jsxs)("div", { className: "flex flex-col items-center gap-2 p-3", children: [(0, jsx_runtime_1.jsx)(react_1.Skeleton, { className: "size-12 rounded-xl" }), (0, jsx_runtime_1.jsx)(react_1.Skeleton, { className: "h-3 w-14" })] }, index))) })), !isLoading && error && ((0, jsx_runtime_1.jsx)("p", { className: "py-6 text-center text-sm text-danger", children: "Could not load your apps." })), !isLoading && !error && apps.length === 0 && ((0, jsx_runtime_1.jsx)("p", { className: "py-6 text-center text-sm text-muted", children: "No other apps yet. Anything this workspace subscribes to shows up here." })), !isLoading && !error && apps.length > 0 && ((0, jsx_runtime_1.jsx)(motion_js_1.m.div, { className: "grid grid-cols-3 gap-2", variants: { show: { transition: { staggerChildren: 0.04 } } }, initial: "hidden", animate: "show", children: apps.map((app) => ((0, jsx_runtime_1.jsx)(motion_js_1.m.div, { variants: { hidden: { opacity: 0, y: 8 }, show: { opacity: 1, y: 0, transition: motion_js_1.ENTER } }, children: (0, jsx_runtime_1.jsx)(AppTile, { app: app }) }, app.serviceId))) }))] }), (0, jsx_runtime_1.jsx)(react_1.Modal.Footer, { children: (0, jsx_runtime_1.jsx)(ConnectBrowseAllLink, {}) })] }) }) })] }) }));
42
+ return ((0, jsx_runtime_1.jsx)(motion_js_1.MotionProvider, { children: (0, jsx_runtime_1.jsxs)(react_1.Modal, { children: [(0, jsx_runtime_1.jsx)(react_1.Button, { isIconOnly: true, variant: "primary", "aria-label": label, className: className, children: (0, jsx_runtime_1.jsx)(lucide_react_1.LayoutGrid, { className: "size-5" }) }), (0, jsx_runtime_1.jsx)(react_1.Modal.Backdrop, { children: (0, jsx_runtime_1.jsx)(react_1.Modal.Container, { children: (0, jsx_runtime_1.jsxs)(react_1.Modal.Dialog, { className: "sm:max-w-md", children: [(0, jsx_runtime_1.jsx)(react_1.Modal.CloseTrigger, {}), (0, jsx_runtime_1.jsx)(react_1.Modal.Header, { children: (0, jsx_runtime_1.jsx)(react_1.Modal.Heading, { children: "Your apps" }) }), (0, jsx_runtime_1.jsxs)(react_1.Modal.Body, { children: [isLoading && ((0, jsx_runtime_1.jsx)("div", { className: "grid grid-cols-3 gap-2", children: Array.from({ length: 6 }, (_, index) => ((0, jsx_runtime_1.jsxs)("div", { className: "flex flex-col items-center gap-2 p-3", children: [(0, jsx_runtime_1.jsx)(react_1.Skeleton, { className: "size-12 rounded-xl" }), (0, jsx_runtime_1.jsx)(react_1.Skeleton, { className: "h-3 w-14" })] }, index))) })), !isLoading && error && ((0, jsx_runtime_1.jsx)("p", { className: "py-6 text-center text-sm text-danger", children: "Could not load your apps." })), !isLoading && !error && apps.length === 0 && ((0, jsx_runtime_1.jsx)("p", { className: "py-6 text-center text-sm text-muted", children: "No other apps yet. Anything this workspace subscribes to shows up here." })), !isLoading && !error && apps.length > 0 && ((0, jsx_runtime_1.jsx)(motion_js_1.m.div, { className: "grid grid-cols-3 gap-2", variants: { show: { transition: { staggerChildren: 0.04 } } }, initial: "hidden", animate: "show", children: apps.map((app) => ((0, jsx_runtime_1.jsx)(motion_js_1.m.div, { variants: { hidden: { opacity: 0, y: 8 }, show: { opacity: 1, y: 0, transition: motion_js_1.ENTER } }, children: (0, jsx_runtime_1.jsx)(AppTile, { app: app }) }, app.applicationId))) }))] }), (0, jsx_runtime_1.jsx)(react_1.Modal.Footer, { children: (0, jsx_runtime_1.jsx)(ConnectBrowseAllLink, {}) })] }) }) })] }) }));
43
43
  }
44
44
  function ConnectBrowseAllLink() {
45
45
  const { appUrl } = (0, provider_js_1.useConnect)();
46
- return ((0, jsx_runtime_1.jsxs)(react_1.Button, { variant: "tertiary", className: "w-full", onPress: () => window.open(`${appUrl}/services`, "_blank", "noopener,noreferrer"), children: ["Browse all services", (0, jsx_runtime_1.jsx)(lucide_react_1.ExternalLink, { className: "size-3.5 text-muted" })] }));
46
+ return ((0, jsx_runtime_1.jsxs)(react_1.Button, { variant: "tertiary", className: "w-full", onPress: () => window.open(`${appUrl}/applications`, "_blank", "noopener,noreferrer"), children: ["Browse all applications", (0, jsx_runtime_1.jsx)(lucide_react_1.ExternalLink, { className: "size-3.5 text-muted" })] }));
47
47
  }
@@ -42,7 +42,7 @@ function useConnectFeature(feature) {
42
42
  *
43
43
  * Like every gate in this package, it is a **UX gate, not a security
44
44
  * boundary**: the entitlement is read through your own origin and the browser
45
- * can ignore it. Check `client.entitlements.hasFeature(orgId, feature)` on the
45
+ * can ignore it. Check `client.entitlements.hasFeature(workspaceId, feature)` on the
46
46
  * server before doing the thing the feature unlocks.
47
47
  *
48
48
  * Renders `loading` - not `fallback` - while the answer is unknown, so a paying
@@ -57,5 +57,5 @@ function ConnectFeatureGate({ feature, children, fallback, loading = null, plans
57
57
  return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: children });
58
58
  if (fallback !== undefined)
59
59
  return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: fallback });
60
- return ((0, jsx_runtime_1.jsx)(subscription_js_1.ConnectNoSubscriptionCard, { plansHref: plansHref, title: title ?? "Not included in your plan", description: description ?? "This part of the service is on a higher plan. Compare plans to see what unlocks it.", className: className }));
60
+ return ((0, jsx_runtime_1.jsx)(subscription_js_1.ConnectNoSubscriptionCard, { plansHref: plansHref, title: title ?? "Not included in your plan", description: description ?? "This part of the application is on a higher plan. Compare plans to see what unlocks it.", className: className }));
61
61
  }
@@ -45,7 +45,7 @@ function ToolkitTile({ toolkit, isPending, onConnect, onDisconnect }) {
45
45
  (0, jsx_runtime_1.jsx)("img", { src: toolkit.logoUrl, alt: "", className: "size-full object-cover" })) : ((0, jsx_runtime_1.jsx)(lucide_react_1.Puzzle, { className: "size-6 text-muted", "aria-hidden": "true" })), toolkit.status === "failed" && ((0, jsx_runtime_1.jsx)("span", { className: "absolute -right-0.5 -top-0.5 flex size-4 items-center justify-center rounded-full bg-danger text-danger-foreground", children: (0, jsx_runtime_1.jsx)(lucide_react_1.AlertCircle, { className: "size-3", "aria-hidden": "true" }) }))] }), (0, jsx_runtime_1.jsx)("span", { className: "line-clamp-2 text-center text-xs font-medium text-foreground", children: toolkit.name }), (0, jsx_runtime_1.jsx)(react_2.Chip, { size: "sm", variant: "soft", color: STATUS_COLOR[toolkit.status], children: STATUS_LABEL[toolkit.status] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex w-full flex-col gap-1.5 pt-1", children: [CAN_CONNECT.has(toolkit.status) && ((0, jsx_runtime_1.jsx)(react_2.Button, { size: "sm", variant: "secondary", className: "w-full text-xs", isPending: isPending, isDisabled: isPending, onPress: onConnect, children: "Connect" })), toolkit.status === "active" && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(react_2.Button, { size: "sm", variant: "secondary", className: "w-full text-xs", isPending: isPending, isDisabled: isPending, onPress: onConnect, children: "Reconnect" }), (0, jsx_runtime_1.jsxs)(react_2.AlertDialog, { isOpen: confirmingDisconnect, onOpenChange: setConfirmingDisconnect, children: [(0, jsx_runtime_1.jsx)(react_2.Button, { size: "sm", variant: "tertiary", className: "w-full text-xs text-danger", isDisabled: isPending, children: "Disconnect" }), (0, jsx_runtime_1.jsx)(react_2.AlertDialog.Backdrop, { children: (0, jsx_runtime_1.jsx)(react_2.AlertDialog.Container, { children: (0, jsx_runtime_1.jsxs)(react_2.AlertDialog.Dialog, { className: "sm:max-w-100", children: [(0, jsx_runtime_1.jsx)(react_2.AlertDialog.CloseTrigger, {}), (0, jsx_runtime_1.jsxs)(react_2.AlertDialog.Header, { children: [(0, jsx_runtime_1.jsx)(react_2.AlertDialog.Icon, { status: "danger" }), (0, jsx_runtime_1.jsxs)(react_2.AlertDialog.Heading, { children: ["Disconnect ", toolkit.name, "?"] })] }), (0, jsx_runtime_1.jsx)(react_2.AlertDialog.Body, { children: (0, jsx_runtime_1.jsx)("p", { className: "text-sm text-muted", children: "Every member loses this connection immediately - it can be reconnected later." }) }), (0, jsx_runtime_1.jsxs)(react_2.AlertDialog.Footer, { children: [(0, jsx_runtime_1.jsx)(react_2.Button, { slot: "close", variant: "secondary", className: "text-xs", children: "Cancel" }), (0, jsx_runtime_1.jsx)(react_2.Button, { slot: "close", variant: "danger", className: "text-xs", onPress: onDisconnect, children: "Disconnect" })] })] }) }) })] })] })), toolkit.status === "pending" && ((0, jsx_runtime_1.jsx)(react_2.Button, { size: "sm", variant: "tertiary", className: "w-full text-xs text-danger", isDisabled: isPending, onPress: onDisconnect, children: "Cancel" }))] })] }));
46
46
  }
47
47
  /**
48
- * A grid of every Composio-hosted toolkit this organization can connect -
48
+ * A grid of every Composio-hosted toolkit this workspace can connect -
49
49
  * Google Calendar, Slack, Twitter/X, whatever a platform admin enabled in
50
50
  * Connect's own Console. Each tile carries its own connect/reconnect/
51
51
  * disconnect action and its own pending state, independent of every other
@@ -5,10 +5,10 @@ exports.ConnectLogo = ConnectLogo;
5
5
  const jsx_runtime_1 = require("react/jsx-runtime");
6
6
  const mark_js_1 = require("../mark.js");
7
7
  /**
8
- * The shared platform lockup: a service's own glyph on the CosmoOps badge,
9
- * `cosmo·ops` beside it, and the service name underneath.
8
+ * The shared platform lockup: an application's own glyph on the CosmoOps badge,
9
+ * `cosmo·ops` beside it, and the application name underneath.
10
10
  *
11
- * This is what makes a family of service platforms look like one product. Each
11
+ * This is what makes a family of application platforms look like one product. Each
12
12
  * platform passes only what differs - its `name` and its `icon` - and inherits
13
13
  * the mark geometry, the wordmark treatment, the separator, and the accent from
14
14
  * one place. Change the lockup here and every platform follows.
@@ -5,7 +5,7 @@
5
5
  * an upgrade while the card behind it said downgrade would be worse than
6
6
  * either label being wrong on its own.
7
7
  *
8
- * Mirrors `packages/data/src/services/catalog.ts` and
8
+ * Mirrors `packages/data/src/applications/catalog.ts` and
9
9
  * `packages/data/src/payments/plan-change.ts`, which are the copies Connect's
10
10
  * own UI uses and which decide which use-case actually runs. The duplication
11
11
  * is deliberate and load-bearing: this package carries no dependency on
@@ -47,7 +47,7 @@ function ConnectPlans({ planIds, hideCoupon = false, className }) {
47
47
  /** The plan under review in the confirmation dialog, or `null` when it is closed. */
48
48
  const [pending, setPending] = (0, react_2.useState)(null);
49
49
  const subscription = entitlements?.subscription ?? null;
50
- const serviceId = subscription?.serviceId ?? null;
50
+ const applicationId = subscription?.applicationId ?? null;
51
51
  const allPlans = (0, react_2.useMemo)(() => {
52
52
  const plans = catalog?.plans ?? [];
53
53
  if (!planIds)
@@ -85,12 +85,12 @@ function ConnectPlans({ planIds, hideCoupon = false, className }) {
85
85
  * then would misreport a completed checkout as an abandoned one.
86
86
  */
87
87
  function startCheckout(plan) {
88
- if (!serviceId)
88
+ if (!applicationId)
89
89
  return;
90
90
  checkout.start({
91
91
  url: (0, use_checkout_js_1.buildCheckoutUrl)({
92
92
  appUrl,
93
- serviceId,
93
+ applicationId,
94
94
  planId: plan.id,
95
95
  subscriptionId: subscription?.subscription?.id ?? null,
96
96
  coupon,
@@ -119,7 +119,7 @@ function ConnectPlans({ planIds, hideCoupon = false, className }) {
119
119
  return null;
120
120
  const action = (0, plan_pricing_js_1.resolveAction)(plan, subscription);
121
121
  // "Current" belongs to the tier, not just the exact price point: an
122
- // org on Growth annual looking at monthly pricing is still on the
122
+ // workspace on Growth annual looking at monthly pricing is still on the
123
123
  // Growth tier, and marking only the row it literally subscribes to
124
124
  // would leave its own card unmarked half the time.
125
125
  const isCurrentTier = subscription?.plan != null &&
@@ -137,8 +137,8 @@ function ConnectPlans({ planIds, hideCoupon = false, className }) {
137
137
  ? "primary"
138
138
  : "secondary",
139
139
  // Disabled while a hand-off is in flight, not just on the
140
- // card that started it: the org has one subscription per
141
- // service, so a second checkout opened against a different
140
+ // card that started it: the workspace has one subscription per
141
+ // application, so a second checkout opened against a different
142
142
  // plan would race the first and one of them would be
143
143
  // rejected on arrival.
144
144
  isDisabled: isCurrent || checkout.status === "waiting", onPress: () => setPending({ plan, action }), children: [plan_pricing_js_1.ACTION_LABEL[action], !isCurrent && (0, jsx_runtime_1.jsx)(lucide_react_1.ExternalLink, { className: "size-3.5" })] }) })] }) }, tier.planGroup));
@@ -33,7 +33,7 @@ function actionLabel(blocker) {
33
33
  return ACTION_LABELS[blocker.code] ?? "Resolve on Connect";
34
34
  }
35
35
  /**
36
- * Every gate between this workspace and your service, with the way out of each.
36
+ * Every gate between this workspace and your application, with the way out of each.
37
37
  *
38
38
  * This is the component that keeps a blocked customer from staring at a broken
39
39
  * app. `getReadiness` resolves subscription state, KYC/KYB, a chargeable
@@ -41,7 +41,7 @@ function actionLabel(blocker) {
41
41
  * `resolveUrl` into the exact Connect screen that fixes it** - so being blocked
42
42
  * comes with somewhere to go rather than a refusal.
43
43
  *
44
- * Render it high on any page your service gates. It draws nothing at all when
44
+ * Render it high on any page your application gates. It draws nothing at all when
45
45
  * the workspace is ready, so it is safe to leave mounted permanently.
46
46
  *
47
47
  * Two deliberate refusals:
@@ -76,7 +76,7 @@ function BlockerRow({ blocker }) {
76
76
  return ((0, jsx_runtime_1.jsxs)("div", { className: `flex flex-wrap items-center justify-between gap-3 rounded-lg px-3 py-2 text-sm ${inProgress || !isBlocking ? "bg-surface text-muted" : "bg-danger-soft text-danger"}`, children: [(0, jsx_runtime_1.jsxs)("span", { className: "flex items-center gap-2", children: [inProgress || !isBlocking ? ((0, jsx_runtime_1.jsx)(lucide_react_1.Info, { className: "size-4 shrink-0", "aria-hidden": "true" })) : ((0, jsx_runtime_1.jsx)(lucide_react_1.AlertTriangle, { className: "size-4 shrink-0", "aria-hidden": "true" })), blocker.message] }), blocker.resolveUrl && !inProgress && ((0, jsx_runtime_1.jsxs)(react_1.Button, { variant: "secondary", onPress: () => window.open(blocker.resolveUrl, "_blank", "noopener,noreferrer"), children: [actionLabel(blocker), (0, jsx_runtime_1.jsx)(lucide_react_1.ExternalLink, { className: "size-3.5" })] }))] }));
77
77
  }
78
78
  function ReadyRow({ className }) {
79
- return ((0, jsx_runtime_1.jsx)("p", { className: `text-sm text-muted ${className ?? ""}`, children: "This workspace is cleared to use every part of the service." }));
79
+ return ((0, jsx_runtime_1.jsx)("p", { className: `text-sm text-muted ${className ?? ""}`, children: "This workspace is cleared to use every part of the application." }));
80
80
  }
81
81
  /**
82
82
  * Renders `children` only once the workspace clears every blocking gate.
@@ -37,7 +37,7 @@ const HEADING = {
37
37
  * The authoritative price is computed by Connect against the real cart:
38
38
  * proration is priced against the actual cycle, a coupon is validated
39
39
  * against the plan it is being applied to, trial eligibility depends on
40
- * whether this organization has ever subscribed to this service before, and
40
+ * whether this workspace has ever subscribed to this application before, and
41
41
  * an accumulated credit is deducted. None of that is knowable from the
42
42
  * partner's origin, so this component states the list price and says where
43
43
  * the final figure comes from rather than quietly guessing at one.
@@ -50,7 +50,7 @@ function ConnectSubscribeDialog({ plan, action, current, coupon, onClose, onConf
50
50
  // member and the one most in need of it: the two prices differ by an order
51
51
  // of magnitude, and showing only the new one reads as a price rise.
52
52
  const isChange = action === "upgrade" || action === "downgrade" || isIntervalSwitch;
53
- return ((0, jsx_runtime_1.jsx)(react_1.Modal.Backdrop, { isOpen: plan !== null, onOpenChange: (open) => !open && onClose(), children: (0, jsx_runtime_1.jsx)(react_1.Modal.Container, { size: "sm", children: (0, jsx_runtime_1.jsxs)(react_1.Modal.Dialog, { children: [(0, jsx_runtime_1.jsx)(react_1.Modal.CloseTrigger, { onPress: onClose }), (0, jsx_runtime_1.jsx)(react_1.Modal.Header, { children: (0, jsx_runtime_1.jsx)(react_1.Modal.Heading, { children: HEADING[action] }) }), plan && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)(react_1.Modal.Body, { className: "flex flex-col gap-4", children: [isChange && currentPlan ? ((0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-3 text-sm", children: [(0, jsx_runtime_1.jsxs)("div", { className: "min-w-0", children: [(0, jsx_runtime_1.jsx)("p", { className: "truncate text-muted", children: currentPlan.name }), (0, jsx_runtime_1.jsxs)("p", { className: "text-xs text-muted", children: [(0, plan_pricing_js_1.formatPrice)(currentPlan.price), "/", currentPlan.billingInterval === "annual" ? "yr" : "mo"] })] }), (0, jsx_runtime_1.jsx)(lucide_react_1.ArrowRight, { className: "size-4 shrink-0 text-muted", "aria-hidden": "true" }), (0, jsx_runtime_1.jsxs)("div", { className: "min-w-0", children: [(0, jsx_runtime_1.jsx)("p", { className: "truncate font-medium text-foreground", children: plan.name }), (0, jsx_runtime_1.jsxs)("p", { className: "text-xs text-muted", children: [(0, plan_pricing_js_1.formatPrice)(plan.price), "/", plan.billingInterval === "annual" ? "yr" : "mo"] })] })] })) : ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("p", { className: "font-medium text-foreground", children: plan.name }), plan.description && (0, jsx_runtime_1.jsx)("p", { className: "text-xs text-muted", children: plan.description })] })), (0, jsx_runtime_1.jsxs)("div", { className: "flex flex-col gap-1 border-t border-separator pt-3 text-sm", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex justify-between text-muted", children: [(0, jsx_runtime_1.jsx)("span", { children: plan.name }), (0, jsx_runtime_1.jsx)("span", { children: (0, plan_pricing_js_1.formatPrice)(plan.price) })] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex justify-between text-muted", children: [(0, jsx_runtime_1.jsxs)("span", { children: ["GST (", plan.gstRate, "%)"] }), (0, jsx_runtime_1.jsx)("span", { children: (0, plan_pricing_js_1.formatPrice)(withGst(plan.price, plan.gstRate) - plan.price) })] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex justify-between border-t border-separator pt-1 font-semibold text-foreground", children: [(0, jsx_runtime_1.jsxs)("span", { children: ["Per ", cadenceOf(plan)] }), (0, jsx_runtime_1.jsx)("span", { children: (0, plan_pricing_js_1.formatPrice)(withGst(plan.price, plan.gstRate)) })] }), plan.billingInterval === "annual" && ((0, jsx_runtime_1.jsxs)("p", { className: "text-xs text-muted", children: ["Works out to ", (0, plan_pricing_js_1.formatPrice)((0, plan_pricing_js_1.monthlyOf)(withGst(plan.price, plan.gstRate), "annual")), " a month, billed yearly."] }))] }), plan.trialDays ? ((0, jsx_runtime_1.jsxs)("p", { className: "text-xs text-accent", children: [plan.trialDays, "-day free trial, if this workspace has not subscribed to this service before."] })) : null, coupon?.trim() ? ((0, jsx_runtime_1.jsxs)("p", { className: "text-xs text-muted", children: ["Coupon ", (0, jsx_runtime_1.jsx)("span", { className: "font-mono text-foreground", children: coupon.trim() }), " is carried over and validated on Connect."] })) : null, (0, jsx_runtime_1.jsxs)("div", { className: "flex gap-2 rounded-lg bg-surface p-3 text-xs text-muted", children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Info, { className: "mt-0.5 size-4 shrink-0", "aria-hidden": "true" }), (0, jsx_runtime_1.jsxs)("div", { className: "flex flex-col gap-1", children: [action === "subscribe" && ((0, jsx_runtime_1.jsx)("p", { children: "Payment is completed on Connect, where your card or UPI mandate is set up and the tax invoice is issued. This page updates by itself once it is done." })), action === "upgrade" && ((0, jsx_runtime_1.jsxs)("p", { children: ["Connect prices the difference for the days left in your current cycle and collects just that amount now. From the next cycle you are billed the ", plan.name, " rate."] })), action === "downgrade" && ((0, jsx_runtime_1.jsx)("p", { children: "You keep what you have paid for. Connect works out the unused part of this cycle and applies it as credit or a refund, depending on how this service is configured." })), isIntervalSwitch && (
53
+ return ((0, jsx_runtime_1.jsx)(react_1.Modal.Backdrop, { isOpen: plan !== null, onOpenChange: (open) => !open && onClose(), children: (0, jsx_runtime_1.jsx)(react_1.Modal.Container, { size: "sm", children: (0, jsx_runtime_1.jsxs)(react_1.Modal.Dialog, { children: [(0, jsx_runtime_1.jsx)(react_1.Modal.CloseTrigger, { onPress: onClose }), (0, jsx_runtime_1.jsx)(react_1.Modal.Header, { children: (0, jsx_runtime_1.jsx)(react_1.Modal.Heading, { children: HEADING[action] }) }), plan && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)(react_1.Modal.Body, { className: "flex flex-col gap-4", children: [isChange && currentPlan ? ((0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-3 text-sm", children: [(0, jsx_runtime_1.jsxs)("div", { className: "min-w-0", children: [(0, jsx_runtime_1.jsx)("p", { className: "truncate text-muted", children: currentPlan.name }), (0, jsx_runtime_1.jsxs)("p", { className: "text-xs text-muted", children: [(0, plan_pricing_js_1.formatPrice)(currentPlan.price), "/", currentPlan.billingInterval === "annual" ? "yr" : "mo"] })] }), (0, jsx_runtime_1.jsx)(lucide_react_1.ArrowRight, { className: "size-4 shrink-0 text-muted", "aria-hidden": "true" }), (0, jsx_runtime_1.jsxs)("div", { className: "min-w-0", children: [(0, jsx_runtime_1.jsx)("p", { className: "truncate font-medium text-foreground", children: plan.name }), (0, jsx_runtime_1.jsxs)("p", { className: "text-xs text-muted", children: [(0, plan_pricing_js_1.formatPrice)(plan.price), "/", plan.billingInterval === "annual" ? "yr" : "mo"] })] })] })) : ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("p", { className: "font-medium text-foreground", children: plan.name }), plan.description && (0, jsx_runtime_1.jsx)("p", { className: "text-xs text-muted", children: plan.description })] })), (0, jsx_runtime_1.jsxs)("div", { className: "flex flex-col gap-1 border-t border-separator pt-3 text-sm", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex justify-between text-muted", children: [(0, jsx_runtime_1.jsx)("span", { children: plan.name }), (0, jsx_runtime_1.jsx)("span", { children: (0, plan_pricing_js_1.formatPrice)(plan.price) })] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex justify-between text-muted", children: [(0, jsx_runtime_1.jsxs)("span", { children: ["GST (", plan.gstRate, "%)"] }), (0, jsx_runtime_1.jsx)("span", { children: (0, plan_pricing_js_1.formatPrice)(withGst(plan.price, plan.gstRate) - plan.price) })] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex justify-between border-t border-separator pt-1 font-semibold text-foreground", children: [(0, jsx_runtime_1.jsxs)("span", { children: ["Per ", cadenceOf(plan)] }), (0, jsx_runtime_1.jsx)("span", { children: (0, plan_pricing_js_1.formatPrice)(withGst(plan.price, plan.gstRate)) })] }), plan.billingInterval === "annual" && ((0, jsx_runtime_1.jsxs)("p", { className: "text-xs text-muted", children: ["Works out to ", (0, plan_pricing_js_1.formatPrice)((0, plan_pricing_js_1.monthlyOf)(withGst(plan.price, plan.gstRate), "annual")), " a month, billed yearly."] }))] }), plan.trialDays ? ((0, jsx_runtime_1.jsxs)("p", { className: "text-xs text-accent", children: [plan.trialDays, "-day free trial, if this workspace has not subscribed to this application before."] })) : null, coupon?.trim() ? ((0, jsx_runtime_1.jsxs)("p", { className: "text-xs text-muted", children: ["Coupon ", (0, jsx_runtime_1.jsx)("span", { className: "font-mono text-foreground", children: coupon.trim() }), " is carried over and validated on Connect."] })) : null, (0, jsx_runtime_1.jsxs)("div", { className: "flex gap-2 rounded-lg bg-surface p-3 text-xs text-muted", children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Info, { className: "mt-0.5 size-4 shrink-0", "aria-hidden": "true" }), (0, jsx_runtime_1.jsxs)("div", { className: "flex flex-col gap-1", children: [action === "subscribe" && ((0, jsx_runtime_1.jsx)("p", { children: "Payment is completed on Connect, where your card or UPI mandate is set up and the tax invoice is issued. This page updates by itself once it is done." })), action === "upgrade" && ((0, jsx_runtime_1.jsxs)("p", { children: ["Connect prices the difference for the days left in your current cycle and collects just that amount now. From the next cycle you are billed the ", plan.name, " rate."] })), action === "downgrade" && ((0, jsx_runtime_1.jsx)("p", { children: "You keep what you have paid for. Connect works out the unused part of this cycle and applies it as credit or a refund, depending on how this application is configured." })), isIntervalSwitch && (
54
54
  // Not a proration. The cycle you are on ends, so this is
55
55
  // the one action where the amount collected can exceed a
56
56
  // single cycle's list price - or be nothing at all, with
@@ -63,7 +63,7 @@ function useSubscriptionState() {
63
63
  * Rendered on its own it is just a card; `ConnectSubscriptionGate` is the usual
64
64
  * way in, since it picks this only when there is genuinely nothing to show.
65
65
  */
66
- function ConnectNoSubscriptionCard({ plansHref = DEFAULT_PLANS_HREF, title = "You're not on a plan yet", description = "Pick a plan to unlock the full service. You can change or cancel it whenever you like.", className, }) {
66
+ function ConnectNoSubscriptionCard({ plansHref = DEFAULT_PLANS_HREF, title = "You're not on a plan yet", description = "Pick a plan to unlock the full application. You can change or cancel it whenever you like.", className, }) {
67
67
  return ((0, jsx_runtime_1.jsxs)(react_1.Card, { className: className, children: [(0, jsx_runtime_1.jsxs)(react_1.Card.Header, { children: [(0, jsx_runtime_1.jsx)(react_1.Card.Title, { children: title }), (0, jsx_runtime_1.jsx)(react_1.Card.Description, { children: description })] }), (0, jsx_runtime_1.jsx)(react_1.Card.Footer, { children: (0, jsx_runtime_1.jsxs)(link_button_js_1.ConnectLinkButton, { href: plansHref, variant: "primary", children: ["See plans", (0, jsx_runtime_1.jsx)(lucide_react_1.ArrowRight, { className: "size-3.5" })] }) })] }));
68
68
  }
69
69
  /**
@@ -19,7 +19,7 @@ function formatDate(iso) {
19
19
  *
20
20
  * Reads the balance Connect actually debits, so the number here and the number
21
21
  * `consumeAddon` enforces cannot disagree. Before the `addons:read` endpoint
22
- * existed this component was impossible to write honestly: a service could
22
+ * existed this component was impossible to write honestly: an application could
23
23
  * spend an allowance down on every request and the only thing the API exposed
24
24
  * was the list of add-on *ids* on the subscription.
25
25
  *
@@ -105,7 +105,7 @@ function DestinationTile({ icon, label, url, }) {
105
105
  * in place, which is why it sits alone in the footer rather than as a fourth
106
106
  * item in the same list as three navigations.
107
107
  *
108
- * The session list is account-wide, not scoped to this service - see
108
+ * The session list is account-wide, not scoped to this application - see
109
109
  * `ConnectUserSession`'s doc comment in `types.ts`. Appearance only renders
110
110
  * when both `theme` and `onThemeChange` are supplied.
111
111
  *
@@ -130,13 +130,13 @@ function ConnectUserMenu({ compact = false, onSignOut, className, theme, onTheme
130
130
  if (!user)
131
131
  return null;
132
132
  const label = user.displayName ?? user.email ?? "Account";
133
- const role = session?.serviceRole?.role;
133
+ const role = session?.applicationRole?.role;
134
134
  const planChip = subscriptionChip(session?.subscription ?? null);
135
135
  return ((0, jsx_runtime_1.jsxs)(react_1.Modal, { children: [(0, jsx_runtime_1.jsxs)(react_1.Button, { variant: "tertiary", "aria-label": `Account: ${label}`,
136
136
  // `pl-1` against the default right padding is optical, not sloppy: a
137
137
  // circular avatar needs less inset than a text label to look evenly
138
138
  // seated in the button.
139
- className: `gap-2 pl-1 ${className ?? ""}`, children: [(0, jsx_runtime_1.jsx)(UserAvatar, { user: user, size: "sm" }), !compact && (0, jsx_runtime_1.jsx)("span", { className: "text-sm font-medium text-foreground", children: label })] }), (0, jsx_runtime_1.jsx)(react_1.Modal.Backdrop, { children: (0, jsx_runtime_1.jsx)(react_1.Modal.Container, { size: "md", scroll: "inside", children: (0, jsx_runtime_1.jsxs)(react_1.Modal.Dialog, { children: [(0, jsx_runtime_1.jsx)(react_1.Modal.CloseTrigger, {}), (0, jsx_runtime_1.jsx)(react_1.Modal.Header, { children: (0, jsx_runtime_1.jsx)(react_1.Modal.Heading, { children: "Account" }) }), (0, jsx_runtime_1.jsxs)(react_1.Modal.Body, { className: "flex flex-col gap-5", children: [(0, jsx_runtime_1.jsxs)("div", { className: `flex items-start gap-3 rounded-xl border border-border ${surfaces_js_1.PANEL_FILL} p-4`, children: [(0, jsx_runtime_1.jsx)(UserAvatar, { user: user, size: "lg" }), (0, jsx_runtime_1.jsxs)("div", { className: "flex min-w-0 flex-1 flex-col gap-0.5", children: [(0, jsx_runtime_1.jsx)("p", { className: "truncate text-sm font-semibold text-foreground", children: label }), user.email && (0, jsx_runtime_1.jsx)("p", { className: "truncate text-xs text-muted", children: user.email }), (0, jsx_runtime_1.jsx)("p", { className: "truncate text-xs text-muted", children: user.organizationName }), (role || planChip || !user.emailVerified) && ((0, jsx_runtime_1.jsxs)("div", { className: "mt-1.5 flex flex-wrap items-center gap-1.5", children: [role && ((0, jsx_runtime_1.jsx)(react_1.Chip, { size: "sm", variant: "soft", color: "accent", children: humanizeRole(role) })), planChip, !user.emailVerified && ((0, jsx_runtime_1.jsx)(react_1.Chip, { size: "sm", variant: "soft", color: "warning", children: "Email unverified" }))] }))] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "grid grid-cols-3 gap-2", children: [(0, jsx_runtime_1.jsx)(DestinationTile, { icon: (0, jsx_runtime_1.jsx)(lucide_react_1.UserRound, { className: surfaces_js_1.ICON, "aria-hidden": "true" }), label: "Profile", url: `${appUrl}/profile` }), (0, jsx_runtime_1.jsx)(DestinationTile, { icon: (0, jsx_runtime_1.jsx)(lucide_react_1.CreditCard, { className: surfaces_js_1.ICON, "aria-hidden": "true" }), label: "Billing", url: `${appUrl}/billing` }), (0, jsx_runtime_1.jsx)(DestinationTile, { icon: (0, jsx_runtime_1.jsx)(mark_js_1.ConnectMark, { className: surfaces_js_1.ICON }), label: "Connect", url: appUrl })] }), theme && onThemeChange && ((0, jsx_runtime_1.jsxs)("div", { className: "flex flex-col gap-2", children: [(0, jsx_runtime_1.jsx)("p", { className: "text-sm font-medium text-foreground", children: "Appearance" }), (0, jsx_runtime_1.jsx)(react_1.ToggleButtonGroup, { fullWidth: true, "aria-label": "Theme", selectionMode: "single", disallowEmptySelection: true, selectedKeys: [theme], onSelectionChange: (keys) => {
139
+ className: `gap-2 pl-1 ${className ?? ""}`, children: [(0, jsx_runtime_1.jsx)(UserAvatar, { user: user, size: "sm" }), !compact && (0, jsx_runtime_1.jsx)("span", { className: "text-sm font-medium text-foreground", children: label })] }), (0, jsx_runtime_1.jsx)(react_1.Modal.Backdrop, { children: (0, jsx_runtime_1.jsx)(react_1.Modal.Container, { size: "md", scroll: "inside", children: (0, jsx_runtime_1.jsxs)(react_1.Modal.Dialog, { children: [(0, jsx_runtime_1.jsx)(react_1.Modal.CloseTrigger, {}), (0, jsx_runtime_1.jsx)(react_1.Modal.Header, { children: (0, jsx_runtime_1.jsx)(react_1.Modal.Heading, { children: "Account" }) }), (0, jsx_runtime_1.jsxs)(react_1.Modal.Body, { className: "flex flex-col gap-5", children: [(0, jsx_runtime_1.jsxs)("div", { className: `flex items-start gap-3 rounded-xl border border-border ${surfaces_js_1.PANEL_FILL} p-4`, children: [(0, jsx_runtime_1.jsx)(UserAvatar, { user: user, size: "lg" }), (0, jsx_runtime_1.jsxs)("div", { className: "flex min-w-0 flex-1 flex-col gap-0.5", children: [(0, jsx_runtime_1.jsx)("p", { className: "truncate text-sm font-semibold text-foreground", children: label }), user.email && (0, jsx_runtime_1.jsx)("p", { className: "truncate text-xs text-muted", children: user.email }), (0, jsx_runtime_1.jsx)("p", { className: "truncate text-xs text-muted", children: user.workspaceName }), (role || planChip || !user.emailVerified) && ((0, jsx_runtime_1.jsxs)("div", { className: "mt-1.5 flex flex-wrap items-center gap-1.5", children: [role && ((0, jsx_runtime_1.jsx)(react_1.Chip, { size: "sm", variant: "soft", color: "accent", children: humanizeRole(role) })), planChip, !user.emailVerified && ((0, jsx_runtime_1.jsx)(react_1.Chip, { size: "sm", variant: "soft", color: "warning", children: "Email unverified" }))] }))] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "grid grid-cols-3 gap-2", children: [(0, jsx_runtime_1.jsx)(DestinationTile, { icon: (0, jsx_runtime_1.jsx)(lucide_react_1.UserRound, { className: surfaces_js_1.ICON, "aria-hidden": "true" }), label: "Profile", url: `${appUrl}/profile` }), (0, jsx_runtime_1.jsx)(DestinationTile, { icon: (0, jsx_runtime_1.jsx)(lucide_react_1.CreditCard, { className: surfaces_js_1.ICON, "aria-hidden": "true" }), label: "Billing", url: `${appUrl}/billing` }), (0, jsx_runtime_1.jsx)(DestinationTile, { icon: (0, jsx_runtime_1.jsx)(mark_js_1.ConnectMark, { className: surfaces_js_1.ICON }), label: "Connect", url: appUrl })] }), theme && onThemeChange && ((0, jsx_runtime_1.jsxs)("div", { className: "flex flex-col gap-2", children: [(0, jsx_runtime_1.jsx)("p", { className: "text-sm font-medium text-foreground", children: "Appearance" }), (0, jsx_runtime_1.jsx)(react_1.ToggleButtonGroup, { fullWidth: true, "aria-label": "Theme", selectionMode: "single", disallowEmptySelection: true, selectedKeys: [theme], onSelectionChange: (keys) => {
140
140
  const [next] = [...keys];
141
141
  if (typeof next === "string")
142
142
  onThemeChange(next);
@@ -157,7 +157,7 @@ function ConnectManageSubscriptionButton({ className }) {
157
157
  * Invoices and payment history, on Connect.
158
158
  *
159
159
  * A deep link rather than a component that lists them, and that is not a
160
- * placeholder: nothing in `/api/v1/service/*` exposes invoices, so an SDK-side
160
+ * placeholder: nothing in `/api/v1/application/*` exposes invoices, so an SDK-side
161
161
  * list would have nothing to read. It is also the right answer regardless -
162
162
  * a GST tax invoice is a legal document with a fixed format, downloadable and
163
163
  * emailed from one place, and a partner-rendered copy of one would be a second
@@ -12,7 +12,7 @@ exports.resolvePlanGroup = exports.groupPlansByTier = exports.ACTION_LABEL = exp
12
12
  *
13
13
  * Styling is HeroUI v3 semantic tokens only (`accent`, `muted`, `surface`,
14
14
  * `separator`, ...), never a hardcoded colour - so these components inherit
15
- * whatever theme the host service platform already configured, and one theme
15
+ * whatever theme the host application platform already configured, and one theme
16
16
  * change lands identically in all of them.
17
17
  */
18
18
  var provider_js_1 = require("./provider.js");
@@ -7,7 +7,7 @@ const jsx_runtime_1 = require("react/jsx-runtime");
7
7
  * The Connect mark - concentric rings on a solid accent badge.
8
8
  *
9
9
  * Painted from `--accent` / `--accent-foreground`, the same HeroUI tokens the
10
- * host app themes, so the badge tracks whatever palette a service platform has
10
+ * host app themes, so the badge tracks whatever palette an application platform has
11
11
  * configured rather than carrying a hardcoded CosmoOps green into someone
12
12
  * else's brand.
13
13
  */
@@ -135,7 +135,7 @@ function ConnectProvider({ clientId = "", basePath = "/api/connect", redirectUri
135
135
  // error, so a Login button still renders rather than the UI hanging on
136
136
  // skeletons forever.
137
137
  setResult({
138
- session: { user: null, subscription: null, serviceRole: null },
138
+ session: { user: null, subscription: null, applicationRole: null },
139
139
  error: cause instanceof Error ? cause.message : "Could not reach Connect",
140
140
  });
141
141
  }
@@ -184,7 +184,7 @@ function ConnectProvider({ clientId = "", basePath = "/api/connect", redirectUri
184
184
  credentials: "same-origin",
185
185
  }).catch(() => { });
186
186
  cache.current.clear();
187
- setResult({ session: { user: null, subscription: null, serviceRole: null }, error: null });
187
+ setResult({ session: { user: null, subscription: null, applicationRole: null }, error: null });
188
188
  }, [basePath, fetchImpl]);
189
189
  const value = (0, react_1.useMemo)(() => ({
190
190
  clientId,
@@ -231,28 +231,28 @@ function useConnectEntitlements() {
231
231
  /**
232
232
  * What is left of every consumable add-on on this workspace's subscription.
233
233
  *
234
- * The read half of `client.billing.consumeAddon` - a service that meters its
234
+ * The read half of `client.billing.consumeAddon` - an application that meters its
235
235
  * own end users had no way to show them what remained until this existed.
236
236
  * Empty `addons` means there is nothing to meter, which is not an error.
237
237
  */
238
238
  function useConnectAddonUsage() {
239
239
  return useConnectResource("/addons");
240
240
  }
241
- /** This service's plan catalog. */
241
+ /** This application's plan catalog. */
242
242
  function useConnectPlans() {
243
243
  return useConnectResource("/plans");
244
244
  }
245
- /** The apps this organization can open. */
245
+ /** The apps this workspace can open. */
246
246
  function useConnectApps() {
247
247
  return useConnectResource("/apps");
248
248
  }
249
- /** Enabled Composio-hosted toolkits and this organization's connection status for each. */
249
+ /** Enabled Composio-hosted toolkits and this workspace's connection status for each. */
250
250
  function useConnectIntegrations() {
251
251
  return useConnectResource("/integrations");
252
252
  }
253
253
  /**
254
254
  * This Connect account's own login sessions - account-wide, not scoped to
255
- * this service, see `SessionsListResponse`'s doc comment. The component
255
+ * this application, see `SessionsListResponse`'s doc comment. The component
256
256
  * that calls this is also the one that must own any revoke actions and call
257
257
  * the returned `refetch()` afterward - see `mutateResource`'s doc comment
258
258
  * for why nothing does that automatically.
@@ -157,15 +157,15 @@ function buildCancelUrl({ appUrl, subscriptionId }) {
157
157
  * The Connect URL that completes a subscribe or a plan change.
158
158
  *
159
159
  * Both land on a modal Connect renders over the relevant page (an intercepted
160
- * parallel route - `app/@modal/(.)services/...` and
160
+ * parallel route - `app/@modal/(.)applications/...` and
161
161
  * `app/@modal/(.)billing/...`), so the customer arrives already looking at the
162
162
  * confirmation for the plan they picked here, not at a catalogue they have to
163
163
  * find it in again.
164
164
  */
165
- function buildCheckoutUrl({ appUrl, serviceId, planId, subscriptionId, coupon, }) {
165
+ function buildCheckoutUrl({ appUrl, applicationId, planId, subscriptionId, coupon, }) {
166
166
  const path = subscriptionId
167
167
  ? `/billing/subscriptions/${encodeURIComponent(subscriptionId)}/change-plan/${encodeURIComponent(planId)}`
168
- : `/services/${encodeURIComponent(serviceId)}/subscribe/${encodeURIComponent(planId)}`;
168
+ : `/applications/${encodeURIComponent(applicationId)}/subscribe/${encodeURIComponent(planId)}`;
169
169
  const url = new URL(path, appUrl);
170
170
  if (coupon?.trim())
171
171
  url.searchParams.set("coupon", coupon.trim());
@@ -3,10 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ConnectError = void 0;
4
4
  exports.isConnectError = isConnectError;
5
5
  /**
6
- * Every failure the Connect service API can report, as one class.
6
+ * Every failure the Connect application API can report, as one class.
7
7
  *
8
8
  * The API speaks two error dialects and this collapses them: the
9
- * `/api/v1/service/*` endpoints use `{ error: { code, message } }`, while the
9
+ * `/api/v1/application/*` endpoints use `{ error: { code, message } }`, while the
10
10
  * three `/sso/*` ones use OAuth2's `{ error, error_description }` (RFC 6749
11
11
  * §5.2). Both land here with `code` populated, so integrating code branches on
12
12
  * one field either way.
@@ -45,7 +45,7 @@ class ConnectError extends Error {
45
45
  * Whether the user's Connect sign-in is over and they need to go back
46
46
  * through `identity.authorizeUrl()`. Collapses every session-side failure,
47
47
  * matching how the API reports them - unknown, expired, revoked, or issued
48
- * to a different service all arrive as one `invalid_token`.
48
+ * to a different application all arrive as one `invalid_token`.
49
49
  */
50
50
  get isSessionExpired() {
51
51
  return this.code === "invalid_token";
@@ -59,7 +59,7 @@ class ConnectError extends Error {
59
59
  * guessing keys. These two are the exception: reaching them required
60
60
  * presenting a key whose hash matched, so you already hold it, and what you
61
61
  * need to know is that no retry and no scope change will fix this - the key
62
- * has to be reissued from the service's Integration tab.
62
+ * has to be reissued from the application's Integration tab.
63
63
  *
64
64
  * Worth alerting on. It is the one failure that will not resolve itself and
65
65
  * takes down every call your integration makes.
@@ -16,7 +16,7 @@ function blockingBlockers(readiness) {
16
16
  * Coerces either wire shape into `PlanFeature[]`.
17
17
  *
18
18
  * A bare key becomes `{ key, name: key, description: "" }` - the same
19
- * fallback the server applies for a plan older than its service's feature
19
+ * fallback the server applies for a plan older than its application's feature
20
20
  * catalog, so an un-upgraded Connect renders exactly what it always did
21
21
  * rather than a column of blanks.
22
22
  *
package/dist/cjs/index.js CHANGED
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.normalizePlanFeatures = exports.blockingBlockers = exports.isConnectError = exports.ConnectError = void 0;
4
4
  /**
5
5
  * `@cosmoops/connect-sdk` - the official client for the CosmoOps Connect
6
- * **service-partner API** (`/api/v1/service/*`).
6
+ * **application-partner API** (`/api/v1/application/*`).
7
7
  *
8
8
  * This root entry is the isomorphic surface: wire types, the error class, and
9
9
  * pure helpers. It pulls in neither Node-only code nor React, so it is safe to
@@ -82,7 +82,7 @@ const handler_js_1 = require("../server/handler.js");
82
82
  * | `CONNECT_SESSION_COOKIE` | no | session cookie name |
83
83
  *
84
84
  * Register `{your origin}/api/connect/callback` as a redirect URI in the
85
- * service's Integration tab. That is the only step this cannot do for you.
85
+ * application's Integration tab. That is the only step this cannot do for you.
86
86
  *
87
87
  * No `next.config.ts` changes needed either, including `transpilePackages`:
88
88
  * `dist/` is already ES2022 with `"use client"` hoisted to the top of every
@@ -317,7 +317,7 @@ async function getConnectSession(request, options = {}) {
317
317
  * A thin wrapper, not a framework of its own - reach for `getConnectSession`
318
318
  * plus your own check when "not signed in" isn't "redirect to sign-in"
319
319
  * (an API route returning 401, say). Role and entitlement checks stay
320
- * outside this function on purpose: `session.serviceRole.granted` and
320
+ * outside this function on purpose: `session.applicationRole.granted` and
321
321
  * `connect.entitlements.*` are one line each on top of the session this
322
322
  * already gives you, and where that line redirects (a plans page, a
323
323
  * "forbidden" screen) is a decision only your app can make - see