@opengeni/react 6.1.0 → 7.0.0-canary.35625901699001

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 (214) hide show
  1. package/README.md +83 -2
  2. package/dist/approvals.d.ts +2 -1
  3. package/dist/artifacts-document.js +1 -1
  4. package/dist/artifacts-presentation.js +1 -1
  5. package/dist/artifacts-spreadsheet.js +1 -1
  6. package/dist/artifacts.js +3 -3
  7. package/dist/{browser-viewer-NTD6UIPR.js → browser-viewer-LGH4IP47.js} +3 -3
  8. package/dist/capability-catalog-row.d.ts +20 -0
  9. package/dist/capability-logo-fallback.d.ts +3 -0
  10. package/dist/{chunk-NOSYBS2D.js → chunk-2VHARTBL.js} +2 -1
  11. package/dist/{chunk-VRBL3F5E.js → chunk-5GAL23FF.js} +10 -2
  12. package/dist/{chunk-VRBL3F5E.js.map → chunk-5GAL23FF.js.map} +1 -1
  13. package/dist/chunk-5UONOQ3Y.js +635 -0
  14. package/dist/chunk-5UONOQ3Y.js.map +1 -0
  15. package/dist/{chunk-NYESIADM.js → chunk-AKOMC3VO.js} +3 -3
  16. package/dist/chunk-AKOMC3VO.js.map +1 -0
  17. package/dist/chunk-BRM6FVZA.js +302 -0
  18. package/dist/chunk-BRM6FVZA.js.map +1 -0
  19. package/dist/{chunk-KANFU34B.js → chunk-DBPVUGQT.js} +11 -2
  20. package/dist/chunk-DBPVUGQT.js.map +1 -0
  21. package/dist/chunk-FHIGTPME.js +1589 -0
  22. package/dist/chunk-FHIGTPME.js.map +1 -0
  23. package/dist/{chunk-5M6VTFJ5.js → chunk-GBPCZH3Y.js} +2 -2
  24. package/dist/{chunk-YBM6CQRU.js → chunk-GEN54DU5.js} +4 -4
  25. package/dist/{chunk-UMECRJRV.js → chunk-HJ5VJ4JB.js} +21 -12
  26. package/dist/chunk-HJ5VJ4JB.js.map +1 -0
  27. package/dist/{chunk-R4KRSFGA.js → chunk-IP4BUBKH.js} +3 -3
  28. package/dist/{chunk-NLTS7JHI.js → chunk-JPHDWKZE.js} +5 -5
  29. package/dist/{chunk-TDSEILUH.js → chunk-MI6ALLLD.js} +1297 -1535
  30. package/dist/chunk-MI6ALLLD.js.map +1 -0
  31. package/dist/{chunk-ICA6R6TW.js → chunk-OWHPKAOV.js} +28 -20
  32. package/dist/chunk-OWHPKAOV.js.map +1 -0
  33. package/dist/{chunk-24M4YBCL.js → chunk-PNAVEK2U.js} +4 -4
  34. package/dist/{chunk-L2NBTKRX.js → chunk-TXCBE32L.js} +203 -19
  35. package/dist/chunk-TXCBE32L.js.map +1 -0
  36. package/dist/{chunk-45XEUVTK.js → chunk-UXE5SSNN.js} +293 -463
  37. package/dist/chunk-UXE5SSNN.js.map +1 -0
  38. package/dist/{chunk-PEI6RANI.js → chunk-VR4Z73EU.js} +203 -9
  39. package/dist/chunk-VR4Z73EU.js.map +1 -0
  40. package/dist/{chunk-HUIKIDM5.js → chunk-XMXRI5JK.js} +65 -18
  41. package/dist/chunk-XMXRI5JK.js.map +1 -0
  42. package/dist/client.d.ts +1 -1
  43. package/dist/components/artifacts/spreadsheet-general-display.d.ts +24 -0
  44. package/dist/components/chat-composer.d.ts +13 -3
  45. package/dist/components/markdown.d.ts +6 -3
  46. package/dist/components/message-timeline.d.ts +7 -2
  47. package/dist/components/preview-loading.d.ts +2 -0
  48. package/dist/components/session-capability-frame.d.ts +24 -0
  49. package/dist/components/session-chrome.d.ts +1 -2
  50. package/dist/components/session-commands.d.ts +6 -0
  51. package/dist/components/session-connection-request.d.ts +8 -0
  52. package/dist/components/session-conversation.d.ts +3 -0
  53. package/dist/components/session-mcp-capability-card.d.ts +22 -0
  54. package/dist/components/timeline-search.d.ts +34 -0
  55. package/dist/composer.js +7 -7
  56. package/dist/connect-account-identity.d.ts +8 -0
  57. package/dist/connect-accounts.d.ts +5 -0
  58. package/dist/connect-chooser.d.ts +6 -0
  59. package/dist/connect-panel.d.ts +9 -2
  60. package/dist/connect-setup.d.ts +5 -1
  61. package/dist/connect.d.ts +5 -21
  62. package/dist/connect.js +1268 -584
  63. package/dist/connect.js.map +1 -1
  64. package/dist/connection-catalog.d.ts +6 -1
  65. package/dist/connection-discovery.d.ts +12 -0
  66. package/dist/connection-installed.d.ts +1 -0
  67. package/dist/connection-logo.d.ts +5 -2
  68. package/dist/connection-service-logo.d.ts +8 -0
  69. package/dist/connection-service-presentation.d.ts +13 -0
  70. package/dist/connection-skeleton.d.ts +5 -0
  71. package/dist/discovery-cache.d.ts +5 -0
  72. package/dist/hooks/use-codex-accounts.d.ts +11 -5
  73. package/dist/hooks/use-connect.d.ts +22 -0
  74. package/dist/hooks/use-session-events.d.ts +5 -0
  75. package/dist/hooks/use-session-mcp-approval-policy.d.ts +2 -2
  76. package/dist/hooks/use-workspace-sessions.d.ts +2 -0
  77. package/dist/index.d.ts +8 -2
  78. package/dist/index.js +771 -793
  79. package/dist/index.js.map +1 -1
  80. package/dist/interaction.js +2 -2
  81. package/dist/machines.js +2 -2
  82. package/dist/mcp-connection-status.d.ts +14 -0
  83. package/dist/{model-policy-picker-menu-3R336DP2.js → model-policy-picker-menu-RVOQ4ZZG.js} +4 -4
  84. package/dist/model-policy.d.ts +6 -2
  85. package/dist/model-policy.js +1 -1
  86. package/dist/{platform-activity-row-DUE2W74J.js → platform-activity-row-HLOH7FW4.js} +9 -4
  87. package/dist/platform-activity-row-HLOH7FW4.js.map +1 -0
  88. package/dist/plugin-discovery.d.ts +6 -0
  89. package/dist/{queue-surface-implementation-LK3S4BIW.js → queue-surface-implementation-3RIFK2BS.js} +4 -4
  90. package/dist/realtime.js +22 -22
  91. package/dist/realtime.js.map +1 -1
  92. package/dist/session-auth-recommendation.d.ts +5 -0
  93. package/dist/session-capability-policy.d.ts +12 -0
  94. package/dist/session-ui.d.ts +2 -0
  95. package/dist/session-ui.js +14 -12
  96. package/dist/session.d.ts +1 -0
  97. package/dist/session.js +6 -4
  98. package/dist/skill-discovery.d.ts +11 -0
  99. package/dist/timeline/compaction-copy.d.ts +10 -0
  100. package/dist/timeline/projection.d.ts +3 -1
  101. package/dist/timeline/tool-display-name.d.ts +2 -1
  102. package/dist/timeline/turn-summary.d.ts +2 -2
  103. package/dist/timeline/types.d.ts +24 -2
  104. package/dist/{timeline-annotation-markers-DRSTLEM6.js → timeline-annotation-markers-OY6OWR3V.js} +2 -2
  105. package/dist/{timeline-annotation-selection-IHLUGVND.js → timeline-annotation-selection-BOXA2TIN.js} +2 -2
  106. package/dist/{timeline-annotations-dialog-6Q53N5FG.js → timeline-annotations-dialog-RGY3MHL3.js} +3 -3
  107. package/package.json +3 -3
  108. package/src/approvals.ts +8 -1
  109. package/src/assets/README.md +8 -0
  110. package/src/assets/gmail.ico +0 -0
  111. package/src/assets/outlook.ico +0 -0
  112. package/src/capability-catalog-row.tsx +94 -0
  113. package/src/capability-logo-fallback.ts +22 -0
  114. package/src/client.ts +0 -9
  115. package/src/components/approval-surface.tsx +12 -2
  116. package/src/components/artifacts/document-editor.tsx +63 -6
  117. package/src/components/artifacts/presentation-editor.tsx +214 -9
  118. package/src/components/artifacts/spreadsheet-canvas.ts +3 -8
  119. package/src/components/artifacts/spreadsheet-general-display.ts +43 -0
  120. package/src/components/artifacts/spreadsheet-grid.tsx +10 -11
  121. package/src/components/chat-composer.tsx +26 -3
  122. package/src/components/composer.tsx +10 -4
  123. package/src/components/human-input-form.tsx +12 -2
  124. package/src/components/markdown.tsx +133 -9
  125. package/src/components/message-timeline.tsx +104 -36
  126. package/src/components/model-picker.tsx +11 -3
  127. package/src/components/model-policy-picker-menu.tsx +10 -3
  128. package/src/components/preview-loading.tsx +154 -0
  129. package/src/components/sandbox-workspace.tsx +20 -36
  130. package/src/components/session-capability-frame.tsx +163 -0
  131. package/src/components/session-chrome.tsx +46 -77
  132. package/src/components/session-commands.tsx +18 -0
  133. package/src/components/session-connection-request.tsx +97 -0
  134. package/src/components/session-conversation.tsx +10 -5
  135. package/src/components/session-mcp-capability-card.tsx +532 -0
  136. package/src/components/session-status.tsx +2 -2
  137. package/src/components/timeline-anchor.tsx +9 -8
  138. package/src/components/timeline-search.tsx +168 -0
  139. package/src/components/user-message-body.tsx +7 -0
  140. package/src/connect-account-identity.tsx +34 -0
  141. package/src/connect-accounts.tsx +114 -52
  142. package/src/connect-chooser.tsx +171 -39
  143. package/src/connect-panel.tsx +73 -9
  144. package/src/connect-setup.tsx +72 -25
  145. package/src/connect.ts +13 -22
  146. package/src/connection-assets.d.ts +4 -0
  147. package/src/connection-catalog.tsx +61 -39
  148. package/src/connection-discovery.tsx +235 -0
  149. package/src/connection-installed.tsx +2 -0
  150. package/src/connection-logo.tsx +18 -10
  151. package/src/connection-service-logo.tsx +55 -0
  152. package/src/connection-service-presentation.ts +46 -0
  153. package/src/connection-skeleton.tsx +16 -0
  154. package/src/conversation-timeline.ts +1 -0
  155. package/src/discovery-cache.ts +42 -0
  156. package/src/hooks/use-codex-accounts.ts +33 -14
  157. package/src/hooks/use-composer.ts +4 -5
  158. package/src/hooks/use-connect.ts +23 -0
  159. package/src/hooks/use-session-events.ts +114 -1
  160. package/src/hooks/use-session-mcp-approval-policy.ts +13 -5
  161. package/src/hooks/use-workspace-sessions.ts +10 -0
  162. package/src/index.ts +22 -2
  163. package/src/mcp-connection-status.ts +35 -0
  164. package/src/model-policy.ts +21 -0
  165. package/src/plugin-details.tsx +8 -5
  166. package/src/plugin-discovery.tsx +92 -72
  167. package/src/realtime/realtime-control.tsx +6 -8
  168. package/src/session-auth-recommendation.ts +48 -0
  169. package/src/session-capability-policy.ts +83 -0
  170. package/src/session-ui.ts +2 -0
  171. package/src/session.ts +1 -0
  172. package/src/skill-discovery.tsx +101 -56
  173. package/src/timeline/compaction-copy.ts +40 -0
  174. package/src/timeline/platform-activity-row.tsx +8 -3
  175. package/src/timeline/projection.ts +78 -2
  176. package/src/timeline/rolling-activity.tsx +4 -2
  177. package/src/timeline/shared.tsx +6 -1
  178. package/src/timeline/startup-timings.tsx +1 -1
  179. package/src/timeline/tool-display-name.ts +8 -6
  180. package/src/timeline/tool-renderers.tsx +5 -3
  181. package/src/timeline/turn-summary.tsx +17 -3
  182. package/src/timeline/types.ts +24 -2
  183. package/styles/compiled.css +325 -27
  184. package/styles/connect.css +90 -15
  185. package/styles/index.css +46 -0
  186. package/styles/session-capability.css +42 -0
  187. package/dist/chunk-45XEUVTK.js.map +0 -1
  188. package/dist/chunk-HQV2I5HV.js +0 -124
  189. package/dist/chunk-HQV2I5HV.js.map +0 -1
  190. package/dist/chunk-HUIKIDM5.js.map +0 -1
  191. package/dist/chunk-ICA6R6TW.js.map +0 -1
  192. package/dist/chunk-IHQII5WO.js +0 -886
  193. package/dist/chunk-IHQII5WO.js.map +0 -1
  194. package/dist/chunk-KANFU34B.js.map +0 -1
  195. package/dist/chunk-L2NBTKRX.js.map +0 -1
  196. package/dist/chunk-NYESIADM.js.map +0 -1
  197. package/dist/chunk-PEI6RANI.js.map +0 -1
  198. package/dist/chunk-TDSEILUH.js.map +0 -1
  199. package/dist/chunk-UMECRJRV.js.map +0 -1
  200. package/dist/hooks/use-packs.d.ts +0 -32
  201. package/dist/platform-activity-row-DUE2W74J.js.map +0 -1
  202. package/src/hooks/use-packs.ts +0 -157
  203. /package/dist/{browser-viewer-NTD6UIPR.js.map → browser-viewer-LGH4IP47.js.map} +0 -0
  204. /package/dist/{chunk-NOSYBS2D.js.map → chunk-2VHARTBL.js.map} +0 -0
  205. /package/dist/{chunk-5M6VTFJ5.js.map → chunk-GBPCZH3Y.js.map} +0 -0
  206. /package/dist/{chunk-YBM6CQRU.js.map → chunk-GEN54DU5.js.map} +0 -0
  207. /package/dist/{chunk-R4KRSFGA.js.map → chunk-IP4BUBKH.js.map} +0 -0
  208. /package/dist/{chunk-NLTS7JHI.js.map → chunk-JPHDWKZE.js.map} +0 -0
  209. /package/dist/{chunk-24M4YBCL.js.map → chunk-PNAVEK2U.js.map} +0 -0
  210. /package/dist/{model-policy-picker-menu-3R336DP2.js.map → model-policy-picker-menu-RVOQ4ZZG.js.map} +0 -0
  211. /package/dist/{queue-surface-implementation-LK3S4BIW.js.map → queue-surface-implementation-3RIFK2BS.js.map} +0 -0
  212. /package/dist/{timeline-annotation-markers-DRSTLEM6.js.map → timeline-annotation-markers-OY6OWR3V.js.map} +0 -0
  213. /package/dist/{timeline-annotation-selection-IHLUGVND.js.map → timeline-annotation-selection-BOXA2TIN.js.map} +0 -0
  214. /package/dist/{timeline-annotations-dialog-6Q53N5FG.js.map → timeline-annotations-dialog-RGY3MHL3.js.map} +0 -0
package/dist/connect.js CHANGED
@@ -1,26 +1,132 @@
1
1
  import "./chunk-IWIDV7SB.js";
2
+ import {
3
+ McpConnectionCard,
4
+ mcpConnectionDiscoveryState,
5
+ useConnect
6
+ } from "./chunk-5UONOQ3Y.js";
2
7
  import {
3
8
  Markdown
4
- } from "./chunk-IHQII5WO.js";
9
+ } from "./chunk-FHIGTPME.js";
10
+ import "./chunk-2VHARTBL.js";
5
11
  import {
6
12
  copyTextToClipboard
7
13
  } from "./chunk-JVYQRRC4.js";
8
- import "./chunk-HQV2I5HV.js";
14
+ import "./chunk-BRM6FVZA.js";
9
15
  import "./chunk-VZTQ73XT.js";
16
+ import "./chunk-PLYRL5ER.js";
10
17
  import "./chunk-22KP6LR5.js";
11
18
 
12
- // src/connect.ts
13
- import { useMemo, useSyncExternalStore } from "react";
19
+ // src/capability-catalog-row.tsx
20
+ import { AlertTriangleIcon, CheckIcon, Loader2Icon, PlusIcon } from "lucide-react";
21
+ import { jsx, jsxs } from "react/jsx-runtime";
22
+ var labels = {
23
+ available: "Available to add",
24
+ added: "Added",
25
+ attention: "Needs attention",
26
+ unavailable: "Unavailable",
27
+ loading: "Working"
28
+ };
29
+ function CapabilityCatalogIndicator({
30
+ status = "available",
31
+ label,
32
+ showLabel = false
33
+ }) {
34
+ const Icon = status === "added" ? CheckIcon : status === "attention" || status === "unavailable" ? AlertTriangleIcon : status === "loading" ? Loader2Icon : PlusIcon;
35
+ return /* @__PURE__ */ jsxs("span", { className: "og-capability-catalog-indicator", "data-status": status, children: [
36
+ /* @__PURE__ */ jsx(Icon, { "aria-hidden": "true" }),
37
+ /* @__PURE__ */ jsx(
38
+ "span",
39
+ {
40
+ className: showLabel || status === "attention" || status === "unavailable" ? "og-capability-catalog-notice" : "og-capability-catalog-sr-only",
41
+ children: label ?? labels[status]
42
+ }
43
+ )
44
+ ] });
45
+ }
46
+ function CapabilityCatalogRow({
47
+ name,
48
+ description,
49
+ icon,
50
+ status = "available",
51
+ statusLabel,
52
+ showStatusLabel = false,
53
+ onOpen,
54
+ className = "",
55
+ ...props
56
+ }) {
57
+ return /* @__PURE__ */ jsxs(
58
+ "button",
59
+ {
60
+ ...props,
61
+ type: "button",
62
+ className: `og-capability-catalog-row ${className}`,
63
+ onClick: onOpen,
64
+ children: [
65
+ icon ? /* @__PURE__ */ jsx("span", { className: "og-capability-catalog-icon", children: icon }) : null,
66
+ /* @__PURE__ */ jsxs("span", { className: "og-capability-catalog-copy", children: [
67
+ /* @__PURE__ */ jsx("strong", { children: name }),
68
+ description ? /* @__PURE__ */ jsx("span", { children: description }) : null
69
+ ] }),
70
+ /* @__PURE__ */ jsx(CapabilityCatalogIndicator, { status, label: statusLabel, showLabel: showStatusLabel })
71
+ ]
72
+ }
73
+ );
74
+ }
14
75
 
15
76
  // src/skill-discovery.tsx
16
77
  import { useEffect, useState } from "react";
17
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
78
+
79
+ // src/discovery-cache.ts
80
+ function createDiscoveryCache(ttlMs = 6e4, capacity = 64) {
81
+ const clients = /* @__PURE__ */ new WeakMap();
82
+ return {
83
+ peek(client, key) {
84
+ const entry = clients.get(client)?.get(key);
85
+ return entry && entry.expires > Date.now() ? entry.value : void 0;
86
+ },
87
+ read(client, key, fetch) {
88
+ let entries = clients.get(client);
89
+ if (!entries) {
90
+ entries = /* @__PURE__ */ new Map();
91
+ clients.set(client, entries);
92
+ }
93
+ const existing = entries.get(key);
94
+ if (existing && existing.expires > Date.now()) return existing.pending;
95
+ entries.delete(key);
96
+ while (entries.size >= capacity) entries.delete(entries.keys().next().value);
97
+ const entry = {
98
+ expires: Date.now() + ttlMs,
99
+ value: void 0,
100
+ pending: Promise.resolve().then(fetch)
101
+ };
102
+ entries.set(key, entry);
103
+ entry.pending = entry.pending.then(
104
+ (value) => {
105
+ entry.value = value;
106
+ entry.expires = Date.now() + ttlMs;
107
+ return value;
108
+ },
109
+ (error) => {
110
+ if (entries.get(key) === entry) entries.delete(key);
111
+ throw error;
112
+ }
113
+ );
114
+ return entry.pending;
115
+ }
116
+ };
117
+ }
118
+
119
+ // src/skill-discovery.tsx
120
+ import { BookOpenIcon } from "lucide-react";
121
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
122
+ var discoveryCache = createDiscoveryCache();
18
123
  function SkillDiscovery(props) {
19
124
  const query = props.query.trim();
20
- return /* @__PURE__ */ jsxs("section", { className: "og-skill-discovery", "aria-label": "Discover skills", children: [
21
- /* @__PURE__ */ jsxs("header", { children: [
22
- /* @__PURE__ */ jsx("h3", { children: "Discover skills" }),
23
- /* @__PURE__ */ jsx(
125
+ const discoveryQuery = query || "agent";
126
+ return /* @__PURE__ */ jsxs2("section", { className: "og-skill-discovery", "aria-label": "Discover skills", children: [
127
+ /* @__PURE__ */ jsxs2("header", { children: [
128
+ /* @__PURE__ */ jsx2("h3", { children: props.resultLimit ? "Skills" : query ? "Search skills" : "Browse skills" }),
129
+ !props.resultLimit ? /* @__PURE__ */ jsx2(
24
130
  "a",
25
131
  {
26
132
  href: "https://skills.sh/",
@@ -29,12 +135,20 @@ function SkillDiscovery(props) {
29
135
  className: "og-skill-discovery-browse",
30
136
  children: "Browse skills.sh \u2197"
31
137
  }
32
- )
138
+ ) : null
33
139
  ] }),
34
- !query && props.onSearch ? /* @__PURE__ */ jsx("button", { type: "button", className: "og-skill-discovery-search", onClick: props.onSearch, children: "Search skills" }) : null,
35
- /* @__PURE__ */ jsx(DiscoveryResults, { ...props, query }, `${props.workspaceId}:${query}`)
140
+ !query ? /* @__PURE__ */ jsx2("p", { children: "Agent skills from skills.sh. Search above for another topic." }) : query.length < 2 ? /* @__PURE__ */ jsx2("p", { children: "Enter at least two characters to search skills.sh." }) : null,
141
+ /* @__PURE__ */ jsx2(
142
+ DiscoveryResults,
143
+ {
144
+ ...props,
145
+ query: discoveryQuery
146
+ },
147
+ `${props.workspaceId}:${discoveryQuery}`
148
+ )
36
149
  ] });
37
150
  }
151
+ var EMPTY_LOCAL_SKILLS = [];
38
152
  var EMPTY_INSTALLED_SKILLS = [];
39
153
  function DiscoveryResults({
40
154
  client,
@@ -42,21 +156,31 @@ function DiscoveryResults({
42
156
  query,
43
157
  canManage,
44
158
  onImport,
159
+ resultLimit,
160
+ onShowMore,
161
+ localSkills = EMPTY_LOCAL_SKILLS,
45
162
  installedSkills = EMPTY_INSTALLED_SKILLS
46
163
  }) {
47
- const [result, setResult] = useState(null);
48
- const [loading, setLoading] = useState(query.length >= 2);
164
+ const cacheKey = JSON.stringify([workspaceId, query]);
165
+ const cached = discoveryCache.peek(client, cacheKey);
166
+ const [result, setResult] = useState(cached ?? null);
167
+ const [loading, setLoading] = useState(query.length >= 2 && !cached);
49
168
  const [error, setError] = useState(false);
50
169
  const [retry, setRetry] = useState(0);
51
170
  useEffect(() => {
52
171
  let active = true;
53
172
  setError(false);
54
173
  if (query.length < 2) return;
55
- setLoading(true);
174
+ const existing = discoveryCache.peek(client, cacheKey);
175
+ setLoading(!existing);
56
176
  let timer;
57
177
  const search = async (attempt) => {
58
178
  try {
59
- const data = await client.searchPublicSkills(workspaceId, query);
179
+ const data = await discoveryCache.read(
180
+ client,
181
+ cacheKey,
182
+ () => client.searchPublicSkills(workspaceId, query)
183
+ );
60
184
  if (!active) return;
61
185
  setResult(data);
62
186
  setLoading(false);
@@ -72,54 +196,64 @@ function DiscoveryResults({
72
196
  setLoading(false);
73
197
  }
74
198
  };
75
- timer = setTimeout(() => void search(0), 300);
199
+ timer = setTimeout(() => void search(0), existing ? 0 : 300);
76
200
  return () => {
77
201
  active = false;
78
202
  clearTimeout(timer);
79
203
  };
80
- }, [client, workspaceId, query, retry]);
81
- return /* @__PURE__ */ jsxs("div", { "aria-busy": loading, children: [
82
- /* @__PURE__ */ jsx("div", { className: "og-skill-discovery-grid", children: result?.items.map((skill) => {
83
- const installed = installedSkills.some(
84
- (entry) => entry.sourceUrl.replace(/\/$/, "").toLowerCase() === skill.url.toLowerCase() || entry.repositoryUrl.replace(/\/$/, "").toLowerCase() === `https://github.com/${skill.source}`.toLowerCase() && entry.name.toLowerCase() === skill.name.toLowerCase()
85
- );
86
- return /* @__PURE__ */ jsxs(
87
- "button",
204
+ }, [client, workspaceId, query, cacheKey, retry]);
205
+ const remoteSkills = result?.items.filter(
206
+ (skill) => !localSkills.some((local) => local.name.toLowerCase() === skill.name.toLowerCase())
207
+ ) ?? [];
208
+ return /* @__PURE__ */ jsxs2("div", { "aria-busy": loading, children: [
209
+ /* @__PURE__ */ jsxs2("div", { className: "og-skill-discovery-grid", children: [
210
+ localSkills.slice(0, resultLimit).map((skill) => /* @__PURE__ */ jsx2(
211
+ CapabilityCatalogRow,
88
212
  {
89
- type: "button",
90
- className: "og-skill-discovery-item",
91
- disabled: !canManage,
92
- onClick: () => onImport(skill.url),
93
- children: [
94
- /* @__PURE__ */ jsxs("span", { className: "og-skill-discovery-copy", children: [
95
- /* @__PURE__ */ jsx("strong", { children: skill.name }),
96
- /* @__PURE__ */ jsx("span", { children: skill.source }),
97
- /* @__PURE__ */ jsxs("small", { children: [
98
- skill.installs.toLocaleString(),
99
- " installs"
100
- ] })
101
- ] }),
102
- /* @__PURE__ */ jsx("span", { className: "og-skill-discovery-action", children: installed ? /* @__PURE__ */ jsxs(Fragment, { children: [
103
- /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\u2713 " }),
104
- "Installed"
105
- ] }) : !canManage ? "Admin required" : "Preview \u2192" })
106
- ]
213
+ name: skill.name,
214
+ description: skill.description,
215
+ icon: /* @__PURE__ */ jsx2(BookOpenIcon, { "aria-hidden": "true" }),
216
+ status: skill.status ?? "added",
217
+ statusLabel: skill.statusLabel,
218
+ onOpen: skill.onOpen
107
219
  },
108
220
  skill.id
109
- );
110
- }) }),
111
- loading ? /* @__PURE__ */ jsx("p", { role: "status", children: "Loading skills\u2026" }) : null,
112
- error ? /* @__PURE__ */ jsxs("div", { role: "alert", className: "og-skill-discovery-error", children: [
221
+ )),
222
+ remoteSkills.slice(
223
+ 0,
224
+ resultLimit === void 0 ? void 0 : Math.max(0, resultLimit - localSkills.length)
225
+ ).map((skill) => {
226
+ const installed = installedSkills.some(
227
+ (entry) => entry.sourceUrl.replace(/\/$/, "").toLowerCase() === skill.url.toLowerCase() || entry.repositoryUrl.replace(/\/$/, "").toLowerCase() === `https://github.com/${skill.source}`.toLowerCase() && entry.name.toLowerCase() === skill.name.toLowerCase()
228
+ );
229
+ return /* @__PURE__ */ jsx2(
230
+ CapabilityCatalogRow,
231
+ {
232
+ disabled: !canManage,
233
+ name: skill.name,
234
+ description: skill.source,
235
+ icon: /* @__PURE__ */ jsx2(BookOpenIcon, { "aria-hidden": "true" }),
236
+ status: !canManage ? "unavailable" : installed ? "added" : "available",
237
+ statusLabel: !canManage ? "Admin required" : installed ? "Installed" : "Available to add",
238
+ onOpen: () => onImport(skill.url)
239
+ },
240
+ skill.id
241
+ );
242
+ })
243
+ ] }),
244
+ resultLimit && remoteSkills.length + localSkills.length > resultLimit && !loading ? /* @__PURE__ */ jsx2("button", { className: "og-catalog-more", type: "button", onClick: onShowMore, children: "View all skills" }) : null,
245
+ loading ? /* @__PURE__ */ jsx2("p", { role: "status", children: "Loading skills\u2026" }) : null,
246
+ error ? /* @__PURE__ */ jsxs2("div", { role: "alert", className: "og-skill-discovery-error", children: [
113
247
  "Could not load skills.",
114
- /* @__PURE__ */ jsx("button", { type: "button", onClick: () => setRetry((value) => value + 1), children: "Retry" })
248
+ /* @__PURE__ */ jsx2("button", { type: "button", onClick: () => setRetry((value) => value + 1), children: "Retry" })
115
249
  ] }) : null,
116
- result && !result.items.length && !loading && !error ? /* @__PURE__ */ jsx("p", { role: "status", children: "No skills found. Try a different search." }) : null
250
+ result && !remoteSkills.length && !localSkills.length && !loading && !error ? /* @__PURE__ */ jsx2("p", { role: "status", children: "No skills found. Try a different search." }) : null
117
251
  ] });
118
252
  }
119
253
 
120
254
  // src/connect-setup.tsx
121
255
  import { useState as useState2 } from "react";
122
- import { Fragment as Fragment2, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
256
+ import { Fragment, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
123
257
  var setupStatus = {
124
258
  ready: "Ready to connect",
125
259
  requires_user_action: "Authorize your account",
@@ -127,9 +261,9 @@ var setupStatus = {
127
261
  provider_wait: "Waiting for authorization",
128
262
  account_selection: "Choose an account",
129
263
  resource_selection: "Choose resources",
130
- preview: "Review available operations",
131
- installing: "Installing selected operations\u2026",
132
- connected_but_incomplete: "Account connected \u2014 finish setup",
264
+ preview: "Choose tools",
265
+ installing: "Adding selected tools\u2026",
266
+ connected_but_incomplete: "Choose which tools to add",
133
267
  complete: "Connection ready",
134
268
  cancelled: "Setup cancelled",
135
269
  expired: "Setup expired",
@@ -152,11 +286,19 @@ function ConnectSetup(props) {
152
286
  setScope(props.controller);
153
287
  setGeneration(generation + 1);
154
288
  }
155
- return /* @__PURE__ */ jsx2(ScopedSetup, { ...props }, generation);
289
+ return /* @__PURE__ */ jsx3(ScopedSetup, { ...props }, generation);
156
290
  }
157
- function ScopedSetup({ controller, onAuthorize, onBrowseResources, className }) {
291
+ function ScopedSetup({
292
+ controller,
293
+ onAuthorize,
294
+ onBrowseResources,
295
+ onSelectAccount,
296
+ className,
297
+ authorizeLabel = "Authorize connection"
298
+ }) {
158
299
  const view = useConnect(controller);
159
300
  const [localError, setLocalError] = useState2(false);
301
+ const [navigating, setNavigating] = useState2(false);
160
302
  const invoke = (operation) => {
161
303
  setLocalError(false);
162
304
  try {
@@ -167,7 +309,14 @@ function ScopedSetup({ controller, onAuthorize, onBrowseResources, className })
167
309
  };
168
310
  const attempt = view.attempt;
169
311
  if (!attempt)
170
- return /* @__PURE__ */ jsx2("section", { className, "aria-label": "Connection setup", children: /* @__PURE__ */ jsx2("p", { role: "status", children: "Choose a connection to begin." }) });
312
+ return /* @__PURE__ */ jsx3(
313
+ "section",
314
+ {
315
+ className: ["og-connect-setup", className].filter(Boolean).join(" "),
316
+ "aria-label": "Connection setup",
317
+ children: /* @__PURE__ */ jsx3("p", { role: "status", children: "Choose a connection to begin." })
318
+ }
319
+ );
171
320
  const action = attempt.nextAction;
172
321
  const verificationUrl = deviceVerificationUrl(action);
173
322
  const terminal = ["complete", "cancelled", "expired"].includes(attempt.state);
@@ -175,7 +324,7 @@ function ScopedSetup({ controller, onAuthorize, onBrowseResources, className })
175
324
  event.preventDefault();
176
325
  const form = event.currentTarget;
177
326
  const data = new FormData(form);
178
- if (view.busy) return;
327
+ if (view.busy || navigating) return;
179
328
  const key = crypto.randomUUID();
180
329
  if (action.type === "credentials") {
181
330
  const values = Object.fromEntries(
@@ -186,7 +335,15 @@ function ScopedSetup({ controller, onAuthorize, onBrowseResources, className })
186
335
  } else if (action.type === "select_account") {
187
336
  const accountId = String(data.get("account") ?? "");
188
337
  if (action.accounts.some((account) => account.id === accountId && account.status !== "disabled"))
189
- invoke(() => view.advance({ type: "account", accountId }, key));
338
+ invoke(async () => {
339
+ if (!onSelectAccount) return view.advance({ type: "account", accountId }, key);
340
+ setNavigating(true);
341
+ try {
342
+ await onSelectAccount(accountId);
343
+ } finally {
344
+ setNavigating(false);
345
+ }
346
+ });
190
347
  } else if (action.type === "select_resources") {
191
348
  if (action.cursor) return;
192
349
  const resourceIds = data.getAll("resource").map(String);
@@ -206,185 +363,245 @@ function ScopedSetup({ controller, onAuthorize, onBrowseResources, className })
206
363
  );
207
364
  }
208
365
  };
209
- return /* @__PURE__ */ jsxs2("section", { className, "aria-label": "Connection setup", "aria-busy": view.busy, children: [
210
- /* @__PURE__ */ jsxs2("p", { children: [
211
- "Ownership: ",
212
- attempt.ownership === "personal" ? "Personal" : "Workspace"
213
- ] }),
214
- /* @__PURE__ */ jsx2("p", { role: "status", children: setupStatus[attempt.state] }),
215
- attempt.account && /* @__PURE__ */ jsxs2("p", { children: [
216
- "Account: ",
217
- attempt.account.label
218
- ] }),
219
- (localError || view.error || attempt.error) && /* @__PURE__ */ jsx2("p", { role: "alert", children: attempt.error?.code === "source_changed" ? "The integration source changed. Review the new operations before installing." : "Connection setup could not continue. Refresh its status before trying again." }),
220
- !terminal && /* @__PURE__ */ jsx2("form", { onSubmit: submit, autoComplete: "off", children: /* @__PURE__ */ jsxs2("fieldset", { disabled: view.busy, children: [
221
- /* @__PURE__ */ jsx2("legend", { children: "Connection details" }),
222
- attempt.state === "connected_but_incomplete" && action.type === "none" && /* @__PURE__ */ jsx2(
223
- "button",
224
- {
225
- type: "button",
226
- onClick: () => invoke(() => view.advance({ type: "retry" }, crypto.randomUUID())),
227
- children: "Review integration operations"
228
- }
229
- ),
230
- action.type === "credentials" && action.fields.map((field, i) => /* @__PURE__ */ jsxs2("label", { children: [
231
- field.label,
232
- field.options ? /* @__PURE__ */ jsxs2("select", { name: `field-${i}`, required: field.required, defaultValue: "", children: [
233
- /* @__PURE__ */ jsx2("option", { value: "", children: field.required ? "Choose an option" : "No account (public service)" }),
234
- field.options.map((option) => /* @__PURE__ */ jsx2("option", { value: option.value, children: option.label }, option.value))
235
- ] }) : /* @__PURE__ */ jsx2(
236
- "input",
237
- {
238
- name: `field-${i}`,
239
- type: field.secret ? "password" : "text",
240
- required: field.required,
241
- autoComplete: "off"
242
- }
243
- )
244
- ] }, field.name)),
245
- action.type === "select_account" && /* @__PURE__ */ jsxs2("label", { children: [
246
- "Account",
247
- /* @__PURE__ */ jsxs2("select", { name: "account", required: true, defaultValue: "", children: [
248
- /* @__PURE__ */ jsx2("option", { value: "", disabled: true, children: "Choose an account" }),
249
- action.accounts.map((account) => /* @__PURE__ */ jsxs2(
250
- "option",
251
- {
252
- value: account.id,
253
- disabled: account.status === "disabled",
254
- children: [
255
- account.label,
256
- " \u2014 ",
257
- account.id,
258
- " (",
259
- account.ownership,
260
- ")"
261
- ]
262
- },
263
- account.id
264
- ))
265
- ] })
266
- ] }),
267
- action.type === "select_resources" && action.resources.map((resource) => /* @__PURE__ */ jsxs2("label", { children: [
268
- /* @__PURE__ */ jsx2("input", { type: "checkbox", name: "resource", value: resource.id }),
269
- resource.label,
270
- " (",
271
- resource.kind,
272
- ")"
273
- ] }, resource.id)),
274
- action.type === "select_resources" && action.cursor && /* @__PURE__ */ jsxs2(Fragment2, { children: [
275
- /* @__PURE__ */ jsx2("p", { children: "More resources are available. Review all pages before submitting a selection." }),
276
- onBrowseResources && /* @__PURE__ */ jsx2(
277
- "button",
278
- {
279
- type: "button",
280
- onClick: () => invoke(() => onBrowseResources(structuredClone(attempt))),
281
- children: "Browse all resources"
282
- }
283
- )
284
- ] }),
285
- action.type === "preview" && /* @__PURE__ */ jsxs2(Fragment2, { children: [
286
- /* @__PURE__ */ jsx2("p", { children: "Select the operations to install." }),
287
- action.operations.map((operation) => /* @__PURE__ */ jsxs2("label", { children: [
288
- /* @__PURE__ */ jsx2("input", { type: "checkbox", name: "operation", value: operation.id }),
289
- operation.label,
290
- " (",
291
- operation.kind,
292
- ")"
293
- ] }, operation.id))
294
- ] }),
295
- ["credentials", "select_account", "select_resources", "preview"].includes(
296
- action.type
297
- ) && /* @__PURE__ */ jsx2(
298
- "button",
299
- {
300
- type: "submit",
301
- disabled: action.type === "select_resources" && Boolean(action.cursor),
302
- children: action.type === "preview" ? "Install selected operations" : "Continue"
303
- }
304
- ),
305
- action.type === "authorize" && /* @__PURE__ */ jsx2(
306
- "button",
307
- {
308
- type: "button",
309
- onClick: () => invoke(() => onAuthorize(structuredClone(attempt))),
310
- children: "Authorize connection"
311
- }
312
- ),
313
- action.type === "wait" && /* @__PURE__ */ jsxs2(Fragment2, { children: [
314
- action.userCode && /* @__PURE__ */ jsxs2("p", { children: [
315
- "Verification code: ",
316
- /* @__PURE__ */ jsx2("code", { children: action.userCode })
366
+ return /* @__PURE__ */ jsxs3(
367
+ "section",
368
+ {
369
+ className: ["og-connect-setup", className].filter(Boolean).join(" "),
370
+ "aria-label": "Connection setup",
371
+ "aria-busy": view.busy || navigating,
372
+ children: [
373
+ /* @__PURE__ */ jsxs3("div", { className: "og-connect-setup-summary", children: [
374
+ /* @__PURE__ */ jsx3("p", { className: "og-connect-setup-scope", children: attempt.ownership === "personal" ? "Personal connection" : "Workspace connection" }),
375
+ /* @__PURE__ */ jsx3("p", { role: "status", className: "og-connect-setup-status", children: setupStatus[attempt.state] }),
376
+ /* @__PURE__ */ jsx3("p", { className: "og-connect-setup-description", children: attempt.ownership === "personal" ? "Only your work can use this connection." : "Work in this workspace can use this connection." })
317
377
  ] }),
318
- /* @__PURE__ */ jsx2("p", { children: "Complete provider authorization, then check the connection status." }),
319
- verificationUrl && /* @__PURE__ */ jsx2("a", { href: verificationUrl, target: "_blank", rel: "noopener noreferrer", children: "Open provider verification page (new tab)" })
320
- ] }),
321
- /* @__PURE__ */ jsx2("button", { type: "button", onClick: () => invoke(() => view.refresh()), children: "Check status" }),
322
- /* @__PURE__ */ jsx2("button", { type: "button", onClick: () => invoke(() => view.cancel(crypto.randomUUID())), children: "Cancel setup" })
323
- ] }) }, `${attempt.id}:${attempt.revision}`)
324
- ] });
378
+ attempt.account && /* @__PURE__ */ jsxs3("p", { children: [
379
+ "Account: ",
380
+ attempt.account.label
381
+ ] }),
382
+ (localError || view.error || attempt.error) && /* @__PURE__ */ jsx3("p", { role: "alert", children: attempt.error?.code === "source_changed" ? "The integration source changed. Review the updated tools before adding them." : "Connection setup could not continue. Refresh its status before trying again." }),
383
+ !terminal && /* @__PURE__ */ jsx3("form", { onSubmit: submit, autoComplete: "off", children: /* @__PURE__ */ jsxs3("fieldset", { disabled: view.busy || navigating, children: [
384
+ ["credentials", "select_account", "select_resources", "preview"].includes(
385
+ action.type
386
+ ) ? /* @__PURE__ */ jsx3("legend", { children: "Connection details" }) : null,
387
+ attempt.state === "connected_but_incomplete" && action.type === "none" && /* @__PURE__ */ jsx3(
388
+ "button",
389
+ {
390
+ type: "button",
391
+ className: "og-connect-setup-primary",
392
+ onClick: () => invoke(() => view.advance({ type: "retry" }, crypto.randomUUID())),
393
+ children: "Choose tools"
394
+ }
395
+ ),
396
+ action.type === "credentials" && action.fields.map((field, i) => /* @__PURE__ */ jsxs3("label", { children: [
397
+ field.label,
398
+ field.options ? /* @__PURE__ */ jsxs3("select", { name: `field-${i}`, required: field.required, defaultValue: "", children: [
399
+ /* @__PURE__ */ jsx3("option", { value: "", children: field.required ? "Choose an option" : "No account (public service)" }),
400
+ field.options.map((option) => /* @__PURE__ */ jsx3("option", { value: option.value, children: option.label }, option.value))
401
+ ] }) : /* @__PURE__ */ jsx3(
402
+ "input",
403
+ {
404
+ name: `field-${i}`,
405
+ type: field.secret ? "password" : "text",
406
+ required: field.required,
407
+ autoComplete: "off"
408
+ }
409
+ )
410
+ ] }, field.name)),
411
+ action.type === "select_account" && /* @__PURE__ */ jsxs3("label", { children: [
412
+ "Account",
413
+ /* @__PURE__ */ jsxs3("select", { name: "account", required: true, defaultValue: "", children: [
414
+ /* @__PURE__ */ jsx3("option", { value: "", disabled: true, children: "Choose an account" }),
415
+ action.accounts.map((account) => /* @__PURE__ */ jsxs3(
416
+ "option",
417
+ {
418
+ value: account.id,
419
+ disabled: account.status === "disabled",
420
+ children: [
421
+ account.label,
422
+ " \u2014 ",
423
+ account.id,
424
+ " (",
425
+ account.ownership,
426
+ ")"
427
+ ]
428
+ },
429
+ account.id
430
+ ))
431
+ ] })
432
+ ] }),
433
+ action.type === "select_resources" && action.resources.map((resource) => /* @__PURE__ */ jsxs3("label", { children: [
434
+ /* @__PURE__ */ jsx3("input", { type: "checkbox", name: "resource", value: resource.id }),
435
+ resource.label,
436
+ " (",
437
+ resource.kind,
438
+ ")"
439
+ ] }, resource.id)),
440
+ action.type === "select_resources" && action.cursor && /* @__PURE__ */ jsxs3(Fragment, { children: [
441
+ /* @__PURE__ */ jsx3("p", { children: "More resources are available. Review all pages before submitting a selection." }),
442
+ onBrowseResources && /* @__PURE__ */ jsx3(
443
+ "button",
444
+ {
445
+ type: "button",
446
+ onClick: () => invoke(() => onBrowseResources(structuredClone(attempt))),
447
+ children: "Browse all resources"
448
+ }
449
+ )
450
+ ] }),
451
+ action.type === "preview" && /* @__PURE__ */ jsxs3(Fragment, { children: [
452
+ /* @__PURE__ */ jsx3("p", { children: "Choose the tools agents can use with this account." }),
453
+ action.operations.map((operation) => /* @__PURE__ */ jsxs3("label", { children: [
454
+ /* @__PURE__ */ jsx3("input", { type: "checkbox", name: "operation", value: operation.id }),
455
+ operation.label,
456
+ " (",
457
+ operation.kind,
458
+ ")"
459
+ ] }, operation.id))
460
+ ] }),
461
+ ["credentials", "select_account", "select_resources", "preview"].includes(
462
+ action.type
463
+ ) && /* @__PURE__ */ jsx3(
464
+ "button",
465
+ {
466
+ type: "submit",
467
+ className: "og-connect-setup-primary",
468
+ disabled: action.type === "select_resources" && Boolean(action.cursor),
469
+ children: action.type === "preview" ? "Add selected tools" : "Continue"
470
+ }
471
+ ),
472
+ action.type === "authorize" && /* @__PURE__ */ jsx3(
473
+ "button",
474
+ {
475
+ type: "button",
476
+ className: "og-connect-setup-primary",
477
+ onClick: () => invoke(() => onAuthorize(structuredClone(attempt))),
478
+ children: navigating ? "Waiting for authorization\u2026" : authorizeLabel
479
+ }
480
+ ),
481
+ action.type === "wait" && /* @__PURE__ */ jsxs3(Fragment, { children: [
482
+ action.userCode && /* @__PURE__ */ jsxs3("p", { children: [
483
+ "Verification code: ",
484
+ /* @__PURE__ */ jsx3("code", { children: action.userCode })
485
+ ] }),
486
+ /* @__PURE__ */ jsx3("p", { children: "Complete provider authorization, then check the connection status." }),
487
+ verificationUrl && /* @__PURE__ */ jsx3("a", { href: verificationUrl, target: "_blank", rel: "noopener noreferrer", children: "Open provider verification page (new tab)" })
488
+ ] }),
489
+ /* @__PURE__ */ jsxs3("div", { className: "og-connect-setup-secondary", children: [
490
+ /* @__PURE__ */ jsx3("button", { type: "button", onClick: () => invoke(() => view.refresh()), children: "Check status" }),
491
+ /* @__PURE__ */ jsx3("button", { type: "button", onClick: () => invoke(() => view.cancel(crypto.randomUUID())), children: "Cancel setup" })
492
+ ] })
493
+ ] }) }, `${attempt.id}:${attempt.revision}`)
494
+ ]
495
+ }
496
+ );
325
497
  }
326
498
 
327
- // src/connection-catalog.tsx
328
- import { Fragment as Fragment3, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
329
- function ConnectionDetailsIndicator() {
330
- return /* @__PURE__ */ jsx3("span", { "aria-hidden": true, className: "og-connection-group-chevron", children: "\u203A" });
499
+ // src/assets/gmail.ico
500
+ var gmail_default = "data:image/x-icon;base64,AAABAAQAEBAAAAEAIAAoBQAARgAAACAgAAABACAAKBQAAG4FAAAwMAAAAQAgACgtAACWGQAAAAAAAAEAIAAWHwAAvkYAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/mTMF/4tFFv+LRRb/fyoGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVaoqBlGtORZRrTkWZpkzBQAAAAD/f38C9IRBpPmIQ+r3h0Lq9oVCPQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFOnNj1TqTXqVKw16lKnM6R//wAC/5FIB/OEQdr6iET/+YhE//ODP0QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABSpTREVaw1/1atNf9TqDTaSLYkB/+RSAfzhEHW+IdD//eHQ//zhUBDAAAAAAAAAAA1ROs0NUTrNAAAAAAAAAAAU6c1Q1SqNf9VqzX/U6g01ki2JAf/kUgH84RB1viHQ//3h0P/+4c3QAAAAAA1ROplNkTu8DZE7vA1ROplAAAAAFOrK0BUqjX/Vas1/1OoNNZItiQH/5FIB/OEQdb4h0P/+4g+/td6X1MsP/OVNkTv/zZE7f82RO3/NkTv/zM/85VPk09TVakv/lWrNf9TqDTWSLYkB/+RSAf0hEHW/4s+/8lwWv5HRdDqNETz/zVD6v82RO7/NkTu/zVD6v83QvL/L2PX6kKtW/5Yqi3/U6g01ki2JAf/fz8I94Y/1qVhdv8qJ77/LDnl/zZE6/83RfL/NELp1jRC6dY3RfL/NkDq/ydk9P8HvfD/NbOD/1SmMNZItiQH/38/CGRBmdYeIsn/HCHG/zA74v83RvL/NUTsqDlF5xY5RecWNUTsqDhC8P8pZPD/Ar79/wO///8dtbnWbZFtByQktgcYHsfZICPI/yAjyv8vOuL0NUXtcgB//wIAAAAAAAAAAAB//wI3POpyJ2by9ATC//8Ev///Abv/2gC2/wcAAH8CHyLFrCEk0P8fIsfVKDDWPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABiF8j8EvfzVBMf//wS8+qwAf/8CAAAAABwcxhIfIstKJCTCFQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALb/FQPE+0oAuPASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACgAAAAgAAAAQAAAAAEAIAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACgAAAAwAAAAYAAAAAEAIAAAAAAAAC0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAADM/wUCvvxXA779mwS++6MEv/xwALT0GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA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";
501
+
502
+ // src/assets/outlook.ico
503
+ var outlook_default = "data:image/x-icon;base64,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////////5Ktg/9R4AP/UeAD/1HgA/1EqA/+lWgP/uGQD/7hkA/+4ZAP/uGQD/7hkA/+4ZAP/1HgA/8ZuAf+nVwT/rl8J/9OEEf/fkBT/35AU/9+QFP/UeAD/1HgA/9R4AP/03b///////+/Mn//UeAD/1HgA/9R4AP/UeAD/78yf///////03b//1HgA/9R4AP/UeAD/USoD/6VaA/+4ZAP/uGQD/7hkA/+4ZAP/uGQD/7hkA//UeAD/1HgA/9R4AP+/aQL/oFIF/7ZnC//YiRP/35AU/9R4AP/UeAD/1HgA//fmz///////6ryA/9R4AP/UeAD/1HgA/9R4AP/qvID///////fmz//UeAD/1HgA/9R4AP9qOgL/vmwA/9R4AP/UeAD/1HgA/9R4AP/UeAD/1HgA/+qoKP/qqCj/6qgo/+qoKP/mpCf/yYgh/28uC/+yaRD/1HgA/9R4AP/UeAD/9+bP///////qvID/1HgA/9R4AP/UeAD/1HgA/+q8gP//////9+bP/9R4AP/UeAD/1HgA/2o6Av++bAD/1HgA/9R4AP/UeAD/1HgA/9R4AP/UeAD/6qgo/+qoKP/qqCj/6qgo/+qoKP/qqCj/ZycK/2cnCs/UeAD/1HgA/9R4AP/03b////////LVr//UeAD/1HgA/9R4AP/UeAD/78yf///////03b//1HgA/9R4AP/UeAD/ajoC/75sAP/UeAD/1HgA/9R4AP/UeAD/1HgA/9R4AP/qqCj/6qgo/+qoKP/qqCj/6qgo/+qoKP9nJwpwAAAAANR4AP/UeAD/1HgA/+SrYP///////////+SrYP/UeAD/1HgA/9+aQP///////////+ezcP/UeAD/1HgA/9R4AP9qOgL/vmwA/9R4AP/UeAD/1HgA/9R4AP/UeAD/1HgA/+qoKP/qqCj/6qgo/+qoKP/qqCj/6qgo/wAAAAAAAAAA1HgA/9R4AP/UeAD/1HgA//fmz/////////////fmz//35s/////////////35s//14AQ/9R4AP/UeAD/1HgA/2o6Av++bAD/1HgA/9R4AP/UeAD/1HgA/9R4AP/UeAD/6qgo/+qoKP/qqCj/6qgo/+qoKP/qqCj/AAAAAAAAAADUeAD/1HgA/9R4AP/UeAD/14AQ/+/Mn///////////////////////78yf/9eAEP/UeAD/1HgA/9R4AP/UeAD/ajoC/75sAP/UeAD/1HgA/9R4AP/UeAD/1HgA/9R4AP/qqCj/6qgo/+qoKP/qqCj/6qgo/+qoKP8AAAAAAAAAANR4AP/UeAD/1HgA/9R4AP/UeAD/1HgA/9R4AP/fmkD/35pA/9R4AP/UeAD/1HgA/9R4AP/UeAD/1HgA/9R4AP96RQD/0pck/+qoKP/qqCj/6qgo/+qoKP/qqCj/6qgo///ZUP//2VD//9lQ///ZUP//2VD//9lQ/wAAAAAAAAAA1HgA/9R4AP/UeAD/1HgA/9R4AP/UeAD/1HgA/9R4AP/UeAD/1HgA/9R4AP/UeAD/1HgA/9R4AP/UeAD/1HgA/3pFAP/SlyT/6qgo/+qoKP/qqCj/6qgo/+qoKP/qqCj//9lQ///ZUP//2VD//9lQ///ZUP//2VD/AAAAAAAAAADUeADP1HgA/9R4AP/UeAD/1HgA/9R4AP/UeAD/1HgA/9R4AP/UeAD/1HgA/9R4AP/UeAD/1HgA/9R4AP/DbgD/h0wA/9KXJP/qqCj/6qgo/+qoKP/qqCj/6qgo/+qoKP//2VD//9lQ///ZUP//2VD//9lQ///ZUP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC+bAD/vmwA/75sAP++bAD/vmwA/75sAP++bAD/15ol/+qoKP/qqCj/6qgo/+qoKP/qqCj/6qgo///ZUP//2VD//9lQ///ZUP//2VD//9lQ/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANR4AP/UeAD/1HgA/9R4AP/UeAD/1HgA/9R4AP/qqCj/6qgo/+qoKP/qqCj/6qgo/+qoKP/qqCj//9lQ///ZUP//2VD//9lQ///ZUP//2VD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1HgA/9R4AP/UeAD/1HgA/9R4AP/UeAD/1HgA/+qoKP/qqCj/6qgo/+qoKP/qqCj/6qgo/+qoKP//2VD//9lQ///ZUP//2VD//9lQ///ZUP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACbUAb/m1AG/5tQBv+bUAb/m1AG/5tQBv+bUAb/m1AG/5tQBv+bUAb/m1AG/5tQBv+bUAb/m1AG/5tQBv+bUAb/m1AG/5tQBv+bUAb/m1AG/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJtQBv+bUAb/m1AG/5tQBv+bUAb/m1AG/5tQBv+bUAb/m1AG/5tQBv+bUAb/m1AG/5tQBv+bUAb/m1AG/5tQBv+bUAb/m1AG/5tQBv+bUAb/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAm1AGz5tQBv+bUAb/m1AG/5tQBv+bUAb/m1AG/5tQBv+bUAb/m1AG/5tQBv+bUAb/m1AG/5tQBv+bUAb/m1AG/5tQBv+bUAb/m1AG/5tQBs8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////////8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAADAAAAAwAAAAMAAAADAAAAAwAAAAP/wAAD/8AAA//AAAP/wAAD/8AAA//AAAP//////////ygAAAAYAAAAMAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOqoKO/qqCj/6qgo/+qoKP/qqCj/6qgo/+qo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";
504
+
505
+ // src/connection-service-presentation.ts
506
+ var services = {
507
+ gmail: { name: "Gmail", logo: gmail_default, mcpUrl: "https://gmailmcp.googleapis.com/mcp/v1" },
508
+ "microsoft-outlook-mail": { name: "Outlook Mail", logo: outlook_default },
509
+ "microsoft-outlook-calendar": { name: "Outlook Calendar", logo: outlook_default },
510
+ "microsoft-outlook-contacts": { name: "Outlook Contacts", logo: outlook_default }
511
+ };
512
+ function connectionServicePresentation(provider) {
513
+ return (Object.hasOwn(services, provider.id) ? services[provider.id] : void 0) ?? {
514
+ name: provider.label,
515
+ logo: null
516
+ };
517
+ }
518
+ function capabilityConnectProviderId(item) {
519
+ return Object.entries(services).find(
520
+ ([, service]) => service.mcpUrl && service.mcpUrl === item.mcpUrl
521
+ )?.[0];
522
+ }
523
+ function accountServiceCapability(account, items) {
524
+ const exact = items.filter((item) => item.connectionRef?.connectionId === account.id);
525
+ if (exact.length === 1) return exact[0];
526
+ return items.find((item) => capabilityConnectProviderId(item) === account.providerId);
331
527
  }
528
+ function isServiceConnectProvider(provider) {
529
+ return provider.readiness === "available" && provider.ownership.length > 0 && provider.family !== "mcp" && !provider.setup.some((kind) => ["installation", "openapi", "graphql"].includes(kind));
530
+ }
531
+
532
+ // src/connection-catalog.tsx
533
+ import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
332
534
  function ConnectionOptionRow({ option }) {
333
- return /* @__PURE__ */ jsxs3("div", { className: "og-connection-catalog-action-row og-connection-option", children: [
334
- /* @__PURE__ */ jsxs3("button", { type: "button", className: "og-connection-catalog-row", onClick: option.onOpen, children: [
335
- /* @__PURE__ */ jsxs3("span", { className: "og-connection-catalog-copy", children: [
336
- /* @__PURE__ */ jsx3("strong", { children: option.name }),
337
- /* @__PURE__ */ jsx3("span", { children: option.description })
338
- ] }),
339
- /* @__PURE__ */ jsx3("span", { className: "og-connection-catalog-status", children: option.status }),
340
- !option.action ? /* @__PURE__ */ jsx3(ConnectionDetailsIndicator, {}) : null
341
- ] }),
342
- option.action ? /* @__PURE__ */ jsx3("span", { className: "og-connection-option-action", children: option.action }) : null
535
+ return /* @__PURE__ */ jsxs4("div", { className: "og-connection-catalog-action-row og-connection-option", children: [
536
+ /* @__PURE__ */ jsx4(
537
+ CapabilityCatalogRow,
538
+ {
539
+ name: option.name,
540
+ description: option.description,
541
+ status: option.state ?? (option.connected ? "added" : "available"),
542
+ statusLabel: option.status,
543
+ showStatusLabel: option.state === void 0,
544
+ onOpen: option.onOpen
545
+ }
546
+ ),
547
+ option.action ? /* @__PURE__ */ jsx4("span", { className: "og-connection-option-action", children: option.action }) : null
343
548
  ] });
344
549
  }
345
550
  function ConnectionServiceRow({ service }) {
346
551
  if (!service.options.length) return null;
347
552
  const connected = service.options.filter((option) => option.connected).length;
348
- const identity = /* @__PURE__ */ jsxs3(Fragment3, { children: [
349
- /* @__PURE__ */ jsx3("span", { className: "og-connection-catalog-logo", children: service.logo }),
350
- /* @__PURE__ */ jsxs3("span", { className: "og-connection-catalog-copy", children: [
351
- /* @__PURE__ */ jsx3("strong", { children: service.name }),
352
- /* @__PURE__ */ jsx3("span", { children: service.options.length === 1 ? service.options[0]?.description : service.options.map((option) => option.name).join(" \xB7 ") })
553
+ const attention = service.options.find(
554
+ (option) => option.state === "attention" || option.state === "unavailable"
555
+ );
556
+ const groupState = attention?.state ?? (service.options.some((option) => option.state === "loading") ? "loading" : connected === service.options.length ? "added" : "available");
557
+ const identity = /* @__PURE__ */ jsxs4(Fragment2, { children: [
558
+ /* @__PURE__ */ jsx4("span", { className: "og-capability-catalog-icon", children: service.logo }),
559
+ /* @__PURE__ */ jsxs4("span", { className: "og-capability-catalog-copy", children: [
560
+ /* @__PURE__ */ jsx4("strong", { children: service.name }),
561
+ /* @__PURE__ */ jsx4("span", { children: service.options.length === 1 ? service.options[0]?.description : service.options.map((option) => option.name).join(" \xB7 ") })
353
562
  ] }),
354
- /* @__PURE__ */ jsx3("span", { className: "og-connection-catalog-status", children: service.options.length === 1 ? service.options[0]?.status : `${connected} of ${service.options.length} connected` })
563
+ /* @__PURE__ */ jsx4(
564
+ CapabilityCatalogIndicator,
565
+ {
566
+ status: groupState,
567
+ label: attention?.status ?? `${connected} of ${service.options.length} added`
568
+ }
569
+ )
355
570
  ] });
356
- return service.options.length === 1 ? /* @__PURE__ */ jsxs3("div", { className: "og-connection-catalog-action-row", children: [
357
- /* @__PURE__ */ jsxs3(
358
- "button",
571
+ return service.options.length === 1 ? /* @__PURE__ */ jsxs4("div", { className: "og-connection-catalog-action-row", children: [
572
+ /* @__PURE__ */ jsx4(
573
+ CapabilityCatalogRow,
359
574
  {
360
- type: "button",
361
- className: "og-connection-catalog-row",
362
- onClick: service.options[0].onOpen,
363
- children: [
364
- identity,
365
- !service.options[0]?.action ? /* @__PURE__ */ jsx3(ConnectionDetailsIndicator, {}) : null
366
- ]
575
+ name: service.name,
576
+ description: service.options[0].description,
577
+ icon: service.logo,
578
+ status: service.options[0].state ?? (connected ? "added" : "available"),
579
+ statusLabel: service.options[0].status,
580
+ showStatusLabel: service.options[0].state === void 0,
581
+ onOpen: service.options[0].onOpen
367
582
  }
368
583
  ),
369
584
  service.options[0]?.action
370
- ] }) : /* @__PURE__ */ jsxs3("details", { className: "og-connection-catalog-service", children: [
371
- /* @__PURE__ */ jsxs3("summary", { className: "og-connection-catalog-row", children: [
585
+ ] }) : /* @__PURE__ */ jsxs4("details", { className: "og-connection-catalog-service", children: [
586
+ /* @__PURE__ */ jsxs4("summary", { className: "og-capability-catalog-row", children: [
372
587
  identity,
373
- /* @__PURE__ */ jsx3("span", { "aria-hidden": true, className: "og-connection-group-chevron", children: "\u2304" })
588
+ /* @__PURE__ */ jsx4("span", { "aria-hidden": true, className: "og-connection-group-chevron", children: "\u2304" })
374
589
  ] }),
375
- /* @__PURE__ */ jsx3("div", { className: "og-connection-catalog-options", children: service.options.map((option) => /* @__PURE__ */ jsx3(ConnectionOptionRow, { option }, option.id)) })
590
+ /* @__PURE__ */ jsx4("div", { className: "og-connection-catalog-options", children: service.options.map((option) => /* @__PURE__ */ jsx4(ConnectionOptionRow, { option }, option.id)) })
376
591
  ] });
377
592
  }
378
593
  function ConnectionCatalog({
379
- services,
594
+ services: services2,
380
595
  query = "",
381
596
  columns = 1,
382
597
  grouped = true,
598
+ resultLimit,
599
+ onShowMore,
383
600
  className = "",
384
601
  emptyMessage = "No connections match your search."
385
602
  }) {
386
603
  const search = query.trim().toLowerCase();
387
- const entries = grouped ? services : services.flatMap(
604
+ const entries = grouped ? services2 : services2.flatMap(
388
605
  (service) => service.options.map((option) => ({
389
606
  ...service,
390
607
  id: `${service.id}/${option.id}`,
@@ -395,50 +612,94 @@ function ConnectionCatalog({
395
612
  const visible = entries.filter(
396
613
  (service) => [service.name, ...service.options.flatMap((option) => [option.name, option.description ?? ""])].join(" ").toLowerCase().includes(search)
397
614
  );
398
- return /* @__PURE__ */ jsx3("div", { className: `og-connection-catalog ${className}`, "data-columns": columns, children: visible.length ? visible.map((service) => /* @__PURE__ */ jsx3(ConnectionServiceRow, { service }, service.id)) : /* @__PURE__ */ jsx3("p", { role: "status", children: emptyMessage }) });
615
+ return /* @__PURE__ */ jsxs4(Fragment2, { children: [
616
+ /* @__PURE__ */ jsx4("div", { className: `og-connection-catalog ${className}`, "data-columns": columns, children: visible.length ? visible.slice(0, resultLimit).map((service) => /* @__PURE__ */ jsx4(ConnectionServiceRow, { service }, service.id)) : /* @__PURE__ */ jsx4("p", { role: "status", children: emptyMessage }) }),
617
+ resultLimit && visible.length > resultLimit ? /* @__PURE__ */ jsx4("button", { className: "og-catalog-more", type: "button", onClick: onShowMore, children: "View all connections" }) : null
618
+ ] });
619
+ }
620
+
621
+ // src/connection-logo.tsx
622
+ import { useState as useState3 } from "react";
623
+ import { jsx as jsx5 } from "react/jsx-runtime";
624
+ function ConnectionLogo({
625
+ src,
626
+ name,
627
+ size = 40,
628
+ fallback,
629
+ loading = false
630
+ }) {
631
+ const [failedSrc, setFailedSrc] = useState3(null);
632
+ return /* @__PURE__ */ jsx5("span", { className: "og-connection-logo", "aria-hidden": "true", style: { width: size, height: size }, children: src && src !== failedSrc ? /* @__PURE__ */ jsx5("img", { src, alt: "", loading: "lazy", decoding: "async", onError: () => setFailedSrc(src) }) : loading ? /* @__PURE__ */ jsx5("span", { className: "og-connection-skeleton-mark" }) : fallback ?? /* @__PURE__ */ jsx5("span", { children: name.split(/\s+/).map((part) => part[0]).join("").slice(0, 2).toUpperCase() }) });
399
633
  }
400
634
 
401
635
  // src/connect-chooser.tsx
402
- import { useEffect as useEffect2, useState as useState3 } from "react";
403
- import { Fragment as Fragment4, jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
636
+ import { useEffect as useEffect2, useState as useState4 } from "react";
637
+ import { Fragment as Fragment3, jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
404
638
  function ConnectChooser(props) {
405
- const [scope, setScope] = useState3(props.controller);
406
- const [generation, setGeneration] = useState3(0);
639
+ const [scope, setScope] = useState4(props.controller);
640
+ const [generation, setGeneration] = useState4(0);
407
641
  if (scope !== props.controller) {
408
642
  setScope(props.controller);
409
643
  setGeneration(generation + 1);
410
644
  }
411
- return /* @__PURE__ */ jsx4(ScopedChooser, { ...props }, generation);
645
+ return /* @__PURE__ */ jsx6(ScopedChooser, { ...props }, generation);
412
646
  }
413
647
  function ScopedChooser({
414
648
  controller,
415
649
  returnUrl,
416
650
  className,
417
- presentation = "select"
651
+ presentation = "select",
652
+ customOnly = false,
653
+ providerOnly = false,
654
+ compact = false,
655
+ initialProviderId = ""
418
656
  }) {
419
657
  const view = useConnect(controller);
420
- const [catalog, setCatalog] = useState3(null);
421
- const [failed, setFailed] = useState3(false);
422
- const [load, setLoad] = useState3(0);
423
- const [query, setQuery] = useState3("");
424
- const [providerId, setProviderId] = useState3("");
425
- const [ownership, setOwnership] = useState3("");
658
+ const [catalog, setCatalog] = useState4(null);
659
+ const [accounts, setAccounts] = useState4([]);
660
+ const [failed, setFailed] = useState4(false);
661
+ const [load, setLoad] = useState4(0);
662
+ const [query, setQuery] = useState4("");
663
+ const [providerId, setProviderId] = useState4(initialProviderId);
664
+ const [ownership, setOwnership] = useState4("");
426
665
  useEffect2(() => {
427
666
  const abort = new AbortController();
428
667
  setCatalog(null);
668
+ setAccounts([]);
429
669
  setFailed(false);
430
- setProviderId("");
670
+ setProviderId(initialProviderId);
431
671
  setOwnership("");
432
672
  void Promise.resolve().then(() => {
433
673
  abort.signal.throwIfAborted();
434
- return controller.transport.catalog(controller.workspaceId, { signal: abort.signal });
435
- }).then((providers) => {
436
- if (!abort.signal.aborted) setCatalog(structuredClone(providers));
674
+ return Promise.all([
675
+ controller.transport.catalog(controller.workspaceId, { signal: abort.signal }),
676
+ presentation === "catalog" ? controller.transport.accounts(controller.workspaceId, { signal: abort.signal }) : Promise.resolve([])
677
+ ]);
678
+ }).then(([providers, inventory]) => {
679
+ if (!abort.signal.aborted) {
680
+ setCatalog(
681
+ structuredClone(
682
+ providers.filter(
683
+ (entry) => entry.readiness === "available" && entry.ownership.length > 0 && (!providerOnly || entry.family !== "mcp" && !entry.setup.some(
684
+ (kind) => ["installation", "openapi", "graphql"].includes(kind)
685
+ )) && (!customOnly || entry.family === "mcp" || entry.setup.some(
686
+ (kind) => ["installation", "openapi", "graphql"].includes(kind)
687
+ ))
688
+ )
689
+ )
690
+ );
691
+ setAccounts(structuredClone(inventory));
692
+ const initial = providers.find((entry) => entry.id === initialProviderId);
693
+ if (initial)
694
+ setOwnership(
695
+ initial.ownership.includes("personal") && ["google", "microsoft"].includes(initial.family) ? "personal" : initial.ownership.includes("workspace") ? "workspace" : initial.ownership[0] ?? ""
696
+ );
697
+ }
437
698
  }).catch(() => {
438
699
  if (!abort.signal.aborted) setFailed(true);
439
700
  });
440
701
  return () => abort.abort();
441
- }, [controller, load]);
702
+ }, [controller, load, presentation, customOnly, providerOnly, initialProviderId]);
442
703
  const provider = catalog?.find((entry) => entry.id === providerId);
443
704
  const canBegin = provider?.readiness === "available" && (ownership === "personal" || ownership === "workspace") && provider.ownership.includes(ownership);
444
705
  const submit = (event) => {
@@ -451,57 +712,115 @@ function ScopedChooser({
451
712
  setFailed(true);
452
713
  }
453
714
  };
454
- return /* @__PURE__ */ jsxs4(
715
+ if (compact && (!catalog || catalog.length === 0) && !failed) return null;
716
+ return /* @__PURE__ */ jsxs5(
455
717
  "section",
456
718
  {
457
719
  className,
458
720
  "aria-label": "Choose a connection",
459
721
  "aria-busy": view.busy || !catalog && !failed,
460
722
  children: [
461
- failed && /* @__PURE__ */ jsx4("p", { role: "alert", children: "Connections could not be loaded or started. Check setup status before retrying." }),
462
- !catalog && !failed && /* @__PURE__ */ jsx4("p", { role: "status", children: "Loading connections\u2026" }),
463
- catalog?.length === 0 && /* @__PURE__ */ jsx4("p", { role: "status", children: "No connections are available." }),
464
- Boolean(catalog?.length) && /* @__PURE__ */ jsx4("form", { onSubmit: submit, children: /* @__PURE__ */ jsxs4("fieldset", { disabled: view.busy, children: [
465
- /* @__PURE__ */ jsx4("legend", { children: "Provider and ownership" }),
466
- presentation === "catalog" && !provider ? /* @__PURE__ */ jsxs4(Fragment4, { children: [
467
- /* @__PURE__ */ jsxs4("label", { children: [
723
+ failed && /* @__PURE__ */ jsx6("p", { role: "alert", children: "Connections could not be loaded or started. Check setup status before retrying." }),
724
+ !catalog && !failed && /* @__PURE__ */ jsx6("p", { role: "status", children: "Loading connections\u2026" }),
725
+ catalog?.length === 0 && /* @__PURE__ */ jsx6("p", { role: "status", children: "No connections are available." }),
726
+ Boolean(catalog?.length) && /* @__PURE__ */ jsx6("form", { onSubmit: submit, children: /* @__PURE__ */ jsxs5("fieldset", { disabled: view.busy, children: [
727
+ /* @__PURE__ */ jsx6("legend", { hidden: customOnly || compact, children: presentation === "catalog" ? "Add a connection" : "Provider and ownership" }),
728
+ presentation === "catalog" && !provider ? /* @__PURE__ */ jsxs5(Fragment3, { children: [
729
+ /* @__PURE__ */ jsxs5("label", { hidden: customOnly || compact, children: [
468
730
  "Search connections",
469
- /* @__PURE__ */ jsx4(
731
+ /* @__PURE__ */ jsx6(
470
732
  "input",
471
733
  {
472
734
  type: "search",
735
+ placeholder: "Find a service\u2026",
473
736
  value: query,
474
737
  onChange: (event) => setQuery(event.target.value)
475
738
  }
476
739
  )
477
740
  ] }),
478
- /* @__PURE__ */ jsx4(
479
- ConnectionCatalog,
741
+ [
480
742
  {
481
- query,
482
- services: catalog.map((entry) => ({
483
- id: entry.id,
484
- name: entry.label,
485
- options: [
486
- {
743
+ name: "Services",
744
+ entries: catalog.filter(
745
+ (entry) => entry.readiness === "available" && entry.family !== "mcp" && !entry.setup.some(
746
+ (kind) => ["installation", "openapi", "graphql"].includes(kind)
747
+ )
748
+ ),
749
+ secondary: false
750
+ },
751
+ {
752
+ name: "Custom connections",
753
+ entries: catalog.filter(
754
+ (entry) => entry.readiness === "available" && (entry.family === "mcp" || entry.setup.some(
755
+ (kind) => ["installation", "openapi", "graphql"].includes(kind)
756
+ ))
757
+ ),
758
+ secondary: true
759
+ }
760
+ ].map((group) => {
761
+ const entries = group.entries.filter(
762
+ (entry) => entry.label.toLocaleLowerCase().includes(query.toLocaleLowerCase().trim())
763
+ );
764
+ if (!entries.length) return null;
765
+ const rows = /* @__PURE__ */ jsx6(
766
+ ConnectionCatalog,
767
+ {
768
+ services: entries.map((entry) => {
769
+ const connected = accounts.some(
770
+ (account) => account.providerId === entry.id && account.status === "connected"
771
+ );
772
+ return {
487
773
  id: entry.id,
488
774
  name: entry.label,
489
- description: entry.reason,
490
- status: entry.readiness.replaceAll("_", " "),
491
- connected: false,
492
- onOpen: () => {
493
- if (!view.busy) {
494
- setProviderId(entry.id);
495
- setOwnership(entry.ownership.length === 1 ? entry.ownership[0] : "");
775
+ logo: /* @__PURE__ */ jsx6(
776
+ ConnectionLogo,
777
+ {
778
+ src: connectionServicePresentation(entry).logo,
779
+ name: entry.label
780
+ }
781
+ ),
782
+ options: [
783
+ {
784
+ id: entry.id,
785
+ name: entry.label,
786
+ status: connected ? "Connected" : entry.readiness === "available" ? "Connect" : "Unavailable",
787
+ state: connected ? "added" : entry.readiness === "available" ? "available" : "unavailable",
788
+ connected,
789
+ onOpen: () => {
790
+ if (!view.busy) {
791
+ setProviderId(entry.id);
792
+ setOwnership(
793
+ entry.ownership.length === 1 ? entry.ownership[0] : ""
794
+ );
795
+ }
796
+ }
496
797
  }
497
- }
498
- }
798
+ ]
799
+ };
800
+ })
801
+ }
802
+ );
803
+ return group.secondary && !customOnly ? /* @__PURE__ */ jsxs5(
804
+ "details",
805
+ {
806
+ className: "og-connect-secondary",
807
+ open: query.trim() ? true : void 0,
808
+ children: [
809
+ /* @__PURE__ */ jsxs5("summary", { children: [
810
+ group.name,
811
+ /* @__PURE__ */ jsx6("span", { children: entries.length })
812
+ ] }),
813
+ rows
499
814
  ]
500
- }))
501
- }
502
- )
815
+ },
816
+ group.name
817
+ ) : /* @__PURE__ */ jsx6("div", { children: rows }, group.name);
818
+ }),
819
+ !catalog.some(
820
+ (entry) => entry.label.toLocaleLowerCase().includes(query.toLocaleLowerCase().trim())
821
+ ) && /* @__PURE__ */ jsx6("p", { role: "status", children: "No services match your search." })
503
822
  ] }) : null,
504
- presentation === "catalog" && provider ? /* @__PURE__ */ jsx4(
823
+ presentation === "catalog" && provider && !initialProviderId ? /* @__PURE__ */ jsx6(
505
824
  "button",
506
825
  {
507
826
  type: "button",
@@ -512,9 +831,9 @@ function ScopedChooser({
512
831
  children: "Back to connections"
513
832
  }
514
833
  ) : null,
515
- /* @__PURE__ */ jsxs4("label", { hidden: presentation === "catalog", children: [
834
+ /* @__PURE__ */ jsxs5("label", { hidden: presentation === "catalog", children: [
516
835
  "Provider",
517
- /* @__PURE__ */ jsxs4(
836
+ /* @__PURE__ */ jsxs5(
518
837
  "select",
519
838
  {
520
839
  required: true,
@@ -524,8 +843,8 @@ function ScopedChooser({
524
843
  setOwnership("");
525
844
  },
526
845
  children: [
527
- /* @__PURE__ */ jsx4("option", { value: "", disabled: true, children: "Choose a provider" }),
528
- catalog.map((entry) => /* @__PURE__ */ jsxs4(
846
+ /* @__PURE__ */ jsx6("option", { value: "", disabled: true, children: "Choose a provider" }),
847
+ catalog.map((entry) => /* @__PURE__ */ jsxs5(
529
848
  "option",
530
849
  {
531
850
  value: entry.id,
@@ -545,76 +864,182 @@ function ScopedChooser({
545
864
  }
546
865
  )
547
866
  ] }),
548
- provider && /* @__PURE__ */ jsxs4(Fragment4, { children: [
549
- /* @__PURE__ */ jsx4("strong", { children: presentation === "catalog" ? provider.label : null }),
550
- /* @__PURE__ */ jsxs4("label", { children: [
551
- "Ownership",
552
- /* @__PURE__ */ jsxs4(
867
+ provider && /* @__PURE__ */ jsxs5(Fragment3, { children: [
868
+ /* @__PURE__ */ jsx6("strong", { children: presentation === "catalog" ? provider.label : null }),
869
+ provider.readiness !== "available" && /* @__PURE__ */ jsx6("p", { role: "status", children: provider.reason ?? "This service is not available in this environment. Contact your administrator to enable it." }),
870
+ /* @__PURE__ */ jsxs5("label", { children: [
871
+ "Who can use this connection?",
872
+ /* @__PURE__ */ jsxs5(
553
873
  "select",
554
874
  {
555
875
  required: true,
556
876
  value: ownership,
557
877
  onChange: (event) => setOwnership(event.target.value),
558
878
  children: [
559
- /* @__PURE__ */ jsx4("option", { value: "", disabled: true, children: "Choose ownership" }),
560
- provider.ownership.map((choice) => /* @__PURE__ */ jsx4("option", { value: choice, children: choice === "personal" ? "Personal \u2014 owned by you" : "Workspace \u2014 shared connection" }, choice))
879
+ /* @__PURE__ */ jsx6("option", { value: "", disabled: true, children: "Choose ownership" }),
880
+ provider.ownership.map((choice) => /* @__PURE__ */ jsx6("option", { value: choice, children: choice === "personal" ? "Only me" : "Everyone in this workspace" }, choice))
561
881
  ]
562
882
  }
563
883
  )
564
884
  ] })
565
885
  ] }),
566
- /* @__PURE__ */ jsx4(
886
+ /* @__PURE__ */ jsx6(
567
887
  "button",
568
888
  {
569
889
  hidden: presentation === "catalog" && !provider,
570
890
  type: "submit",
571
891
  disabled: !canBegin,
572
- children: "Start setup"
892
+ children: "Continue"
573
893
  }
574
894
  )
575
895
  ] }) }),
576
- /* @__PURE__ */ jsx4("button", { type: "button", disabled: view.busy, onClick: () => setLoad(load + 1), children: "Reload providers" })
896
+ /* @__PURE__ */ jsx6("button", { hidden: !failed, type: "button", disabled: view.busy, onClick: () => setLoad(load + 1), children: "Reload providers" })
577
897
  ]
578
898
  }
579
899
  );
580
900
  }
581
901
 
582
902
  // src/connect-accounts.tsx
583
- import { useEffect as useEffect3, useRef, useState as useState4 } from "react";
584
- import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
903
+ import { useEffect as useEffect4, useRef, useState as useState6 } from "react";
904
+
905
+ // src/connection-service-logo.tsx
906
+ import { useEffect as useEffect3, useState as useState5 } from "react";
907
+
908
+ // src/capability-logo-fallback.ts
909
+ function capabilityLogoFallback(item) {
910
+ if (item.id.startsWith("mcp:integrations-sh:gmailmcp-googleapis-com-") || item.mcpUrl === "https://gmailmcp.googleapis.com/mcp/v1")
911
+ return gmail_default;
912
+ const original = item.metadata?.originalLogoUrl;
913
+ if (typeof original !== "string") return null;
914
+ try {
915
+ const url = new URL(original);
916
+ return url.protocol === "https:" || url.protocol === "http:" ? url.href : null;
917
+ } catch {
918
+ return null;
919
+ }
920
+ }
921
+
922
+ // src/connection-service-logo.tsx
923
+ import { jsx as jsx7 } from "react/jsx-runtime";
924
+ function ConnectionServiceLogo({
925
+ client,
926
+ item,
927
+ name,
928
+ fallback = null
929
+ }) {
930
+ const path = item?.logoAssetPath;
931
+ const [image, setImage] = useState5(null);
932
+ useEffect3(() => {
933
+ if (!client || !path?.startsWith("catalog-assets/")) return;
934
+ const abort = new AbortController();
935
+ let url = null;
936
+ void client.downloadCatalogAsset(path, { signal: abort.signal }).then((blob) => {
937
+ if (!abort.signal.aborted && blob.type.startsWith("image/") && blob.size <= 2e6)
938
+ url = URL.createObjectURL(blob);
939
+ }).catch(() => {
940
+ }).finally(() => {
941
+ if (!abort.signal.aborted) setImage({ client, path, url });
942
+ });
943
+ return () => {
944
+ abort.abort();
945
+ if (url) URL.revokeObjectURL(url);
946
+ };
947
+ }, [client, path]);
948
+ const current = image && image.client === client && image.path === path ? image : null;
949
+ const loading = Boolean(client && path?.startsWith("catalog-assets/") && !current);
950
+ return /* @__PURE__ */ jsx7(
951
+ ConnectionLogo,
952
+ {
953
+ name,
954
+ loading,
955
+ src: current?.url ?? (loading ? null : (item ? capabilityLogoFallback(item) : null) ?? fallback)
956
+ }
957
+ );
958
+ }
959
+
960
+ // src/connect-account-identity.tsx
961
+ import { Fragment as Fragment4, jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
962
+ function ConnectAccountIdentity({
963
+ account,
964
+ client,
965
+ capabilities
966
+ }) {
967
+ const item = accountServiceCapability(account, capabilities);
968
+ const service = connectionServicePresentation({ id: account.providerId, label: account.label });
969
+ const name = item?.name ?? service.name;
970
+ return /* @__PURE__ */ jsxs6(Fragment4, { children: [
971
+ /* @__PURE__ */ jsx8(ConnectionServiceLogo, { client, item, name, fallback: service.logo }),
972
+ /* @__PURE__ */ jsxs6("div", { children: [
973
+ /* @__PURE__ */ jsx8("strong", { children: name }),
974
+ /* @__PURE__ */ jsxs6("small", { children: [
975
+ account.ownership === "personal" ? "Only you" : "Workspace connection",
976
+ name !== account.label ? ` \xB7 ${account.label}` : ""
977
+ ] })
978
+ ] })
979
+ ] });
980
+ }
981
+
982
+ // src/connection-skeleton.tsx
983
+ import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
984
+ function ConnectionSkeleton({ rows = 1, label }) {
985
+ return /* @__PURE__ */ jsx9("div", { role: "status", "aria-label": label, className: "og-connection-skeleton", children: Array.from({ length: rows }, (_, index) => /* @__PURE__ */ jsxs7("div", { className: "og-connection-skeleton-row", "aria-hidden": "true", children: [
986
+ /* @__PURE__ */ jsx9("span", { className: "og-connection-skeleton-mark" }),
987
+ /* @__PURE__ */ jsxs7("span", { className: "og-connection-skeleton-copy", children: [
988
+ /* @__PURE__ */ jsx9("span", {}),
989
+ /* @__PURE__ */ jsx9("span", {})
990
+ ] })
991
+ ] }, index)) });
992
+ }
993
+
994
+ // src/connect-accounts.tsx
995
+ import { jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
585
996
  function ConnectAccounts(props) {
586
- const [scope, setScope] = useState4(props.controller);
587
- const [generation, setGeneration] = useState4(0);
997
+ const [scope, setScope] = useState6(props.controller);
998
+ const [generation, setGeneration] = useState6(0);
588
999
  if (scope !== props.controller) {
589
1000
  setScope(props.controller);
590
1001
  setGeneration(generation + 1);
591
1002
  }
592
- return /* @__PURE__ */ jsx5(ScopedAccounts, { ...props }, generation);
1003
+ return /* @__PURE__ */ jsx10(ScopedAccounts, { ...props }, generation);
593
1004
  }
594
- function ScopedAccounts({ controller, className, returnUrl }) {
1005
+ function ScopedAccounts({
1006
+ controller,
1007
+ className,
1008
+ returnUrl,
1009
+ client,
1010
+ onDisconnected
1011
+ }) {
595
1012
  const view = useConnect(controller);
596
- const [accounts, setAccounts] = useState4(null);
597
- const [selected, setSelected] = useState4(null);
598
- const [busy, setBusy] = useState4(false);
599
- const [error, setError] = useState4(false);
600
- const [reload, setReload] = useState4(0);
1013
+ const [accounts, setAccounts] = useState6(null);
1014
+ const [selected, setSelected] = useState6(null);
1015
+ const [busy, setBusy] = useState6(false);
1016
+ const [error, setError] = useState6(false);
1017
+ const [reload, setReload] = useState6(0);
1018
+ const [catalog, setCatalog] = useState6(null);
601
1019
  const mutation = useRef(null);
602
- useEffect3(() => () => mutation.current?.abort(), []);
603
- useEffect3(() => {
1020
+ useEffect4(() => () => mutation.current?.abort(), []);
1021
+ useEffect4(() => {
604
1022
  const abort = new AbortController();
605
1023
  setAccounts(null);
1024
+ setCatalog(null);
606
1025
  setSelected(null);
607
1026
  setError(false);
608
1027
  void Promise.resolve().then(() => {
609
1028
  abort.signal.throwIfAborted();
610
- return controller.transport.accounts(controller.workspaceId, { signal: abort.signal });
611
- }).then((result) => {
612
- if (!abort.signal.aborted) setAccounts(structuredClone(result));
1029
+ return Promise.all([
1030
+ controller.transport.accounts(controller.workspaceId, { signal: abort.signal }),
1031
+ client?.listCapabilities(controller.workspaceId).catch(() => null) ?? null
1032
+ ]);
1033
+ }).then(([result, metadata]) => {
1034
+ if (!abort.signal.aborted) {
1035
+ setAccounts(structuredClone(result.filter((account) => account.status !== "disabled")));
1036
+ if (client && metadata) setCatalog({ client, items: metadata.items });
1037
+ }
613
1038
  }).catch(() => {
614
1039
  if (!abort.signal.aborted) setError(true);
615
1040
  });
616
1041
  return () => abort.abort();
617
- }, [controller, reload]);
1042
+ }, [client, controller, reload]);
618
1043
  const disconnect = async (account) => {
619
1044
  const expectedVersion = account.version;
620
1045
  if (mutation.current || view.busy || expectedVersion === void 0 || !Number.isSafeInteger(expectedVersion) || expectedVersion < 1)
@@ -628,7 +1053,10 @@ function ScopedAccounts({ controller, className, returnUrl }) {
628
1053
  expectedVersion,
629
1054
  signal: abort.signal
630
1055
  });
631
- if (!abort.signal.aborted) setReload((value) => value + 1);
1056
+ if (!abort.signal.aborted) {
1057
+ setReload((value) => value + 1);
1058
+ onDisconnected?.();
1059
+ }
632
1060
  } catch {
633
1061
  if (!abort.signal.aborted) {
634
1062
  setAccounts(null);
@@ -657,104 +1085,370 @@ function ScopedAccounts({ controller, className, returnUrl }) {
657
1085
  setError(true);
658
1086
  }
659
1087
  };
660
- return /* @__PURE__ */ jsxs5(
1088
+ return /* @__PURE__ */ jsxs8(
661
1089
  "section",
662
1090
  {
663
1091
  className,
664
1092
  "aria-label": "Connected accounts",
665
1093
  "aria-busy": busy || view.busy || !accounts && !error,
666
1094
  children: [
667
- error && /* @__PURE__ */ jsx5("p", { role: "alert", children: "Account state could not be confirmed. Reload before trying again." }),
668
- !accounts && !error && /* @__PURE__ */ jsx5("p", { role: "status", children: "Loading accounts\u2026" }),
669
- accounts?.length === 0 && /* @__PURE__ */ jsx5("p", { role: "status", children: "No connected accounts." }),
670
- accounts && accounts.length > 0 && /* @__PURE__ */ jsx5("ul", { children: accounts.map((account) => /* @__PURE__ */ jsxs5("li", { children: [
671
- /* @__PURE__ */ jsxs5("span", { children: [
672
- account.label,
673
- " \u2014 ",
674
- account.providerId,
675
- " \u2014 ",
676
- account.ownership,
677
- " \u2014",
678
- " ",
679
- account.status.replaceAll("_", " ")
1095
+ /* @__PURE__ */ jsx10("h3", { children: "Your connections" }),
1096
+ error && /* @__PURE__ */ jsx10("p", { role: "alert", children: "Account state could not be confirmed. Reload before trying again." }),
1097
+ !accounts && !error && /* @__PURE__ */ jsx10(ConnectionSkeleton, { label: "Loading accounts" }),
1098
+ accounts?.length === 0 && /* @__PURE__ */ jsx10("p", { role: "status", children: "No connected accounts." }),
1099
+ accounts && accounts.length > 0 && /* @__PURE__ */ jsx10("ul", { children: accounts.map((account) => /* @__PURE__ */ jsx10("li", { className: "og-connect-account", children: /* @__PURE__ */ jsxs8("details", { className: "og-connect-account-details", children: [
1100
+ /* @__PURE__ */ jsxs8("summary", { className: "og-connect-account-heading", children: [
1101
+ /* @__PURE__ */ jsx10(
1102
+ ConnectAccountIdentity,
1103
+ {
1104
+ account,
1105
+ client,
1106
+ capabilities: catalog?.client === client ? catalog?.items ?? [] : []
1107
+ }
1108
+ ),
1109
+ /* @__PURE__ */ jsx10("span", { className: "og-connect-account-status", "data-status": account.status, children: account.status === "connected" ? "\u2713 Connected" : account.status === "auth_needed" ? "Reconnect needed" : "Disconnected" }),
1110
+ /* @__PURE__ */ jsx10(
1111
+ "svg",
1112
+ {
1113
+ className: "og-connect-account-chevron",
1114
+ "aria-hidden": "true",
1115
+ width: "16",
1116
+ height: "16",
1117
+ viewBox: "0 0 24 24",
1118
+ fill: "none",
1119
+ stroke: "currentColor",
1120
+ strokeWidth: "1.5",
1121
+ children: /* @__PURE__ */ jsx10("path", { d: "m9 6 6 6-6 6" })
1122
+ }
1123
+ )
680
1124
  ] }),
681
- returnUrl && /* @__PURE__ */ jsxs5(
682
- "button",
683
- {
684
- type: "button",
685
- disabled: busy || view.busy || account.status === "disabled",
686
- onClick: () => void reconnect(account),
687
- children: [
688
- "Reconnect ",
689
- account.label
690
- ]
691
- }
692
- ),
693
- selected === `${account.providerId}:${account.id}` ? /* @__PURE__ */ jsxs5("div", { role: "group", "aria-label": `Disconnect ${account.label}`, children: [
694
- /* @__PURE__ */ jsx5("p", { children: "This removes local OpenGeni access. It does not revoke consent at the provider." }),
695
- /* @__PURE__ */ jsx5(
1125
+ /* @__PURE__ */ jsxs8("div", { className: "og-connect-account-actions", children: [
1126
+ returnUrl && account.status === "auth_needed" && /* @__PURE__ */ jsx10(
696
1127
  "button",
697
1128
  {
698
1129
  type: "button",
1130
+ "aria-label": `Reconnect ${account.label}`,
699
1131
  disabled: busy || view.busy,
700
- onClick: () => void disconnect(account),
701
- children: "Confirm disconnect"
1132
+ onClick: () => void reconnect(account),
1133
+ children: "Reconnect"
702
1134
  }
703
1135
  ),
704
- /* @__PURE__ */ jsx5("button", { type: "button", disabled: busy, onClick: () => setSelected(null), children: "Keep account" })
705
- ] }) : /* @__PURE__ */ jsxs5(
706
- "button",
707
- {
708
- type: "button",
709
- disabled: busy || view.busy || account.status === "disabled" || !Number.isSafeInteger(account.version) || account.version < 1,
710
- onClick: () => setSelected(`${account.providerId}:${account.id}`),
711
- children: [
712
- "Disconnect ",
713
- account.label
714
- ]
715
- }
716
- )
717
- ] }, `${account.providerId}:${account.id}`)) }),
718
- /* @__PURE__ */ jsx5("button", { type: "button", disabled: busy, onClick: () => setReload((value) => value + 1), children: "Reload accounts" })
1136
+ selected === `${account.providerId}:${account.id}` ? /* @__PURE__ */ jsxs8("div", { role: "group", "aria-label": `Disconnect ${account.label}`, children: [
1137
+ /* @__PURE__ */ jsx10("p", { children: "This removes local OpenGeni access. It does not revoke consent at the provider." }),
1138
+ /* @__PURE__ */ jsx10(
1139
+ "button",
1140
+ {
1141
+ type: "button",
1142
+ disabled: busy || view.busy,
1143
+ onClick: () => void disconnect(account),
1144
+ children: "Confirm disconnect"
1145
+ }
1146
+ ),
1147
+ /* @__PURE__ */ jsx10("button", { type: "button", disabled: busy, onClick: () => setSelected(null), children: "Keep account" })
1148
+ ] }) : /* @__PURE__ */ jsx10(
1149
+ "button",
1150
+ {
1151
+ type: "button",
1152
+ "aria-label": `Disconnect ${account.label}`,
1153
+ disabled: busy || view.busy || account.status === "disabled" || !Number.isSafeInteger(account.version) || account.version < 1,
1154
+ onClick: () => setSelected(`${account.providerId}:${account.id}`),
1155
+ children: "Disconnect"
1156
+ }
1157
+ )
1158
+ ] })
1159
+ ] }) }, `${account.providerId}:${account.id}`)) }),
1160
+ /* @__PURE__ */ jsx10(
1161
+ "button",
1162
+ {
1163
+ hidden: !error,
1164
+ type: "button",
1165
+ disabled: busy,
1166
+ onClick: () => setReload((value) => value + 1),
1167
+ children: "Reload accounts"
1168
+ }
1169
+ )
719
1170
  ]
720
1171
  }
721
1172
  );
722
1173
  }
723
1174
 
724
1175
  // src/connect-panel.tsx
725
- import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
1176
+ import { useState as useState8 } from "react";
1177
+
1178
+ // src/connection-discovery.tsx
1179
+ import { useEffect as useEffect5, useRef as useRef2, useState as useState7 } from "react";
1180
+ import { jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
1181
+ function ConnectionDiscovery(props) {
1182
+ const [scope, setScope] = useState7({ client: props.client, controller: props.controller });
1183
+ const [generation, setGeneration] = useState7(0);
1184
+ if (scope.client !== props.client || scope.controller !== props.controller) {
1185
+ setScope({ client: props.client, controller: props.controller });
1186
+ setGeneration(generation + 1);
1187
+ }
1188
+ return /* @__PURE__ */ jsx11(ScopedDiscovery, { ...props }, `${generation}:${props.workspaceId}`);
1189
+ }
1190
+ function ScopedDiscovery({
1191
+ client,
1192
+ controller,
1193
+ workspaceId,
1194
+ returnUrl,
1195
+ onConfigured
1196
+ }) {
1197
+ const [providers, setProviders] = useState7(null);
1198
+ const [accounts, setAccounts] = useState7([]);
1199
+ const [selectedProvider, setSelectedProvider] = useState7(null);
1200
+ const [providerFailed, setProviderFailed] = useState7(false);
1201
+ const [items, setItems] = useState7(null);
1202
+ const [failed, setFailed] = useState7(false);
1203
+ const [connections, setConnections] = useState7([]);
1204
+ const [reload, setReload] = useState7(0);
1205
+ const [query, setQuery] = useState7("");
1206
+ const [limit, setLimit] = useState7(12);
1207
+ const [selected, setSelected] = useState7(null);
1208
+ const opener = useRef2(null);
1209
+ useEffect5(() => {
1210
+ const abort = new AbortController();
1211
+ const read = async (operation) => {
1212
+ abort.signal.throwIfAborted();
1213
+ return operation();
1214
+ };
1215
+ setFailed(false);
1216
+ setSelectedProvider(null);
1217
+ setProviders(null);
1218
+ setItems(null);
1219
+ setProviderFailed(false);
1220
+ if (controller)
1221
+ void Promise.all([
1222
+ read(() => controller.transport.catalog(workspaceId, { signal: abort.signal })),
1223
+ read(() => controller.transport.accounts(workspaceId, { signal: abort.signal }))
1224
+ ]).then(([catalog, inventory]) => {
1225
+ if (!abort.signal.aborted) {
1226
+ setProviders(catalog.filter(isServiceConnectProvider));
1227
+ setAccounts(inventory);
1228
+ }
1229
+ }).catch(() => {
1230
+ if (!abort.signal.aborted) setProviderFailed(true);
1231
+ });
1232
+ void Promise.all([
1233
+ read(() => client.listCapabilities(workspaceId)),
1234
+ read(() => client.listConnections(workspaceId))
1235
+ ]).then(([catalog, inventory]) => {
1236
+ if (!abort.signal.aborted) {
1237
+ setConnections(inventory);
1238
+ setItems(
1239
+ catalog.items.filter(
1240
+ (item) => item.kind === "mcp" && item.authKind === "oauth2" && Boolean(item.mcpUrl ?? item.endpointUrl)
1241
+ )
1242
+ );
1243
+ }
1244
+ }).catch(() => {
1245
+ if (!abort.signal.aborted) setFailed(true);
1246
+ });
1247
+ return () => {
1248
+ abort.abort();
1249
+ };
1250
+ }, [client, controller, workspaceId, reload]);
1251
+ const matches = items?.filter(
1252
+ (item) => `${item.name} ${item.description ?? ""} ${item.providerDomain ?? ""}`.toLocaleLowerCase().includes(query.trim().toLocaleLowerCase())
1253
+ ) ?? [];
1254
+ const providerMatches = (providers ?? []).filter(
1255
+ (provider) => !items?.some((item) => capabilityConnectProviderId(item) === provider.id) && provider.label.toLocaleLowerCase().includes(query.trim().toLocaleLowerCase())
1256
+ );
1257
+ const loading = !items && !failed || Boolean(controller && !providers && !providerFailed);
1258
+ if (selectedProvider && controller)
1259
+ return /* @__PURE__ */ jsxs9("section", { "aria-label": `Connect ${selectedProvider.label}`, children: [
1260
+ /* @__PURE__ */ jsx11("button", { type: "button", onClick: () => setSelectedProvider(null), children: "Back to connections" }),
1261
+ /* @__PURE__ */ jsx11(
1262
+ ConnectionLogo,
1263
+ {
1264
+ name: selectedProvider.label,
1265
+ src: connectionServicePresentation(selectedProvider).logo
1266
+ }
1267
+ ),
1268
+ /* @__PURE__ */ jsx11(
1269
+ ConnectChooser,
1270
+ {
1271
+ controller,
1272
+ returnUrl,
1273
+ presentation: "catalog",
1274
+ providerOnly: true,
1275
+ initialProviderId: selectedProvider.id
1276
+ }
1277
+ )
1278
+ ] });
1279
+ return /* @__PURE__ */ jsxs9("section", { className: "og-connection-discovery", "aria-label": "Find a connection", children: [
1280
+ /* @__PURE__ */ jsx11("h3", { children: "Add a connection" }),
1281
+ /* @__PURE__ */ jsxs9("label", { children: [
1282
+ /* @__PURE__ */ jsx11("span", { className: "og-capability-catalog-sr-only", children: "Search services" }),
1283
+ /* @__PURE__ */ jsx11(
1284
+ "input",
1285
+ {
1286
+ type: "search",
1287
+ placeholder: "Search services\u2026",
1288
+ value: query,
1289
+ onChange: (event) => {
1290
+ setQuery(event.target.value);
1291
+ setLimit(12);
1292
+ }
1293
+ }
1294
+ )
1295
+ ] }),
1296
+ (providerFailed || failed) && /* @__PURE__ */ jsxs9("p", { role: "alert", children: [
1297
+ "Some services could not be loaded.",
1298
+ " ",
1299
+ /* @__PURE__ */ jsx11("button", { type: "button", onClick: () => setReload((value) => value + 1), children: "Retry" })
1300
+ ] }),
1301
+ /* @__PURE__ */ jsxs9("div", { className: "og-connection-discovery-results", children: [
1302
+ providerMatches.map((provider) => {
1303
+ const connected = accounts.some(
1304
+ (account) => account.providerId === provider.id && account.status === "connected"
1305
+ );
1306
+ return /* @__PURE__ */ jsx11(
1307
+ CapabilityCatalogRow,
1308
+ {
1309
+ name: provider.label,
1310
+ icon: /* @__PURE__ */ jsx11(
1311
+ ConnectionLogo,
1312
+ {
1313
+ name: provider.label,
1314
+ src: connectionServicePresentation(provider).logo
1315
+ }
1316
+ ),
1317
+ status: connected ? "added" : "available",
1318
+ statusLabel: connected ? "Connected" : "Connect",
1319
+ showStatusLabel: true,
1320
+ onOpen: () => setSelectedProvider(provider)
1321
+ },
1322
+ provider.id
1323
+ );
1324
+ }),
1325
+ matches.slice(0, limit).map((item) => {
1326
+ const state = mcpConnectionDiscoveryState(item, connections);
1327
+ return /* @__PURE__ */ jsx11(
1328
+ CapabilityCatalogRow,
1329
+ {
1330
+ name: item.name,
1331
+ description: item.description ?? void 0,
1332
+ icon: /* @__PURE__ */ jsx11(ConnectionServiceLogo, { client, item, name: item.name }),
1333
+ status: state.status,
1334
+ statusLabel: state.label,
1335
+ showStatusLabel: true,
1336
+ onOpen: () => {
1337
+ opener.current = document.activeElement instanceof HTMLElement ? document.activeElement : null;
1338
+ setSelected(item);
1339
+ }
1340
+ },
1341
+ item.id
1342
+ );
1343
+ }),
1344
+ loading && /* @__PURE__ */ jsx11(ConnectionSkeleton, { rows: 3, label: "Loading services" }),
1345
+ !loading && !failed && !providerFailed && !matches.length && !providerMatches.length && /* @__PURE__ */ jsx11("p", { role: "status", children: "No services match your search." }),
1346
+ matches.length > limit && /* @__PURE__ */ jsx11("button", { type: "button", onClick: () => setLimit((value) => value + 12), children: "Show more services" })
1347
+ ] }),
1348
+ selected ? /* @__PURE__ */ jsx11(
1349
+ McpConnectionCard,
1350
+ {
1351
+ client,
1352
+ workspaceId,
1353
+ capabilityId: selected.id,
1354
+ name: selected.name,
1355
+ returnUrl,
1356
+ dialogOnly: true,
1357
+ onClose: () => {
1358
+ setSelected(null);
1359
+ queueMicrotask(() => {
1360
+ if (opener.current?.isConnected) opener.current.focus();
1361
+ });
1362
+ },
1363
+ onConfigured: async () => {
1364
+ setReload((value) => value + 1);
1365
+ await onConfigured?.();
1366
+ }
1367
+ }
1368
+ ) : null
1369
+ ] });
1370
+ }
1371
+
1372
+ // src/connect-panel.tsx
1373
+ import { Fragment as Fragment5, jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
726
1374
  function ConnectPanel({
727
1375
  returnUrl,
728
1376
  title = "Connections",
729
1377
  showAccounts = true,
1378
+ showCustomConnections = true,
1379
+ showProviderConnections = false,
730
1380
  presentation = "select",
731
1381
  className,
1382
+ client,
732
1383
  ...setup
733
1384
  }) {
734
- return /* @__PURE__ */ jsxs6("div", { className: ["og-connect", className].filter(Boolean).join(" "), children: [
735
- /* @__PURE__ */ jsx6("h2", { children: title }),
736
- /* @__PURE__ */ jsx6(
1385
+ const { attempt } = useConnect(setup.controller);
1386
+ const [inventoryRevision, setInventoryRevision] = useState8(0);
1387
+ const activeSetup = attempt !== null && !["complete", "cancelled", "expired"].includes(attempt.state);
1388
+ const serviceName = attempt ? connectionServicePresentation({ id: attempt.providerId, label: "" }).name : "";
1389
+ return /* @__PURE__ */ jsxs10("div", { className: ["og-connect", className].filter(Boolean).join(" "), children: [
1390
+ title !== null && /* @__PURE__ */ jsx12("h2", { children: title }),
1391
+ showAccounts && !activeSetup && /* @__PURE__ */ jsx12(
1392
+ ConnectAccounts,
1393
+ {
1394
+ controller: setup.controller,
1395
+ returnUrl,
1396
+ client,
1397
+ onDisconnected: () => setInventoryRevision((value) => value + 1)
1398
+ },
1399
+ inventoryRevision
1400
+ ),
1401
+ !activeSetup && (client && presentation === "catalog" ? /* @__PURE__ */ jsxs10(Fragment5, { children: [
1402
+ /* @__PURE__ */ jsx12(
1403
+ ConnectionDiscovery,
1404
+ {
1405
+ controller: showProviderConnections ? setup.controller : void 0,
1406
+ client,
1407
+ workspaceId: setup.controller.workspaceId,
1408
+ returnUrl,
1409
+ onConfigured: () => setInventoryRevision((value) => value + 1)
1410
+ },
1411
+ inventoryRevision
1412
+ ),
1413
+ showCustomConnections && /* @__PURE__ */ jsxs10("details", { className: "og-connect-secondary", children: [
1414
+ /* @__PURE__ */ jsx12("summary", { children: "Custom connection" }),
1415
+ /* @__PURE__ */ jsx12(
1416
+ ConnectChooser,
1417
+ {
1418
+ customOnly: true,
1419
+ presentation,
1420
+ controller: setup.controller,
1421
+ returnUrl
1422
+ }
1423
+ )
1424
+ ] })
1425
+ ] }) : /* @__PURE__ */ jsx12(
737
1426
  ConnectChooser,
738
1427
  {
739
1428
  presentation,
740
1429
  controller: setup.controller,
741
1430
  returnUrl
742
1431
  }
743
- ),
744
- /* @__PURE__ */ jsx6(ConnectSetup, { ...setup }),
745
- showAccounts && /* @__PURE__ */ jsx6(ConnectAccounts, { controller: setup.controller, returnUrl })
1432
+ )),
1433
+ activeSetup && /* @__PURE__ */ jsx12(
1434
+ ConnectSetup,
1435
+ {
1436
+ ...setup,
1437
+ authorizeLabel: setup.authorizeLabel ?? (serviceName ? `Continue to ${serviceName}` : "Authorize connection")
1438
+ }
1439
+ )
746
1440
  ] });
747
1441
  }
748
1442
 
749
1443
  // src/device-authorization.tsx
750
- import { useEffect as useEffect4, useRef as useRef2, useState as useState5 } from "react";
751
- import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
1444
+ import { useEffect as useEffect6, useRef as useRef3, useState as useState9 } from "react";
1445
+ import { jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
752
1446
  function DeviceAuthorization(props) {
753
- const [copied, setCopied] = useState5(false);
754
- const [copyError, setCopyError] = useState5(false);
755
- const generation = useRef2(0);
756
- const timer = useRef2(null);
757
- useEffect4(() => {
1447
+ const [copied, setCopied] = useState9(false);
1448
+ const [copyError, setCopyError] = useState9(false);
1449
+ const generation = useRef3(0);
1450
+ const timer = useRef3(null);
1451
+ useEffect6(() => {
758
1452
  generation.current++;
759
1453
  setCopied(false);
760
1454
  setCopyError(false);
@@ -794,11 +1488,11 @@ function DeviceAuthorization(props) {
794
1488
  } catch {
795
1489
  }
796
1490
  if (props.render) return props.render({ copied, copyError, copy, verificationHref: href });
797
- return /* @__PURE__ */ jsxs7("section", { className: `og-connect ${props.className ?? ""}`, "aria-label": "Device authorization", children: [
798
- /* @__PURE__ */ jsx7("p", { children: props.description ?? `Enter this code at ${props.providerLabel ?? "the provider"}.` }),
799
- /* @__PURE__ */ jsxs7("div", { style: { display: "flex", flexWrap: "wrap", gap: "0.5rem", alignItems: "center" }, children: [
800
- /* @__PURE__ */ jsx7("code", { ...props.codeAttributes, style: { overflowWrap: "anywhere" }, children: props.userCode }),
801
- /* @__PURE__ */ jsx7(
1491
+ return /* @__PURE__ */ jsxs11("section", { className: `og-connect ${props.className ?? ""}`, "aria-label": "Device authorization", children: [
1492
+ /* @__PURE__ */ jsx13("p", { children: props.description ?? `Enter this code at ${props.providerLabel ?? "the provider"}.` }),
1493
+ /* @__PURE__ */ jsxs11("div", { style: { display: "flex", flexWrap: "wrap", gap: "0.5rem", alignItems: "center" }, children: [
1494
+ /* @__PURE__ */ jsx13("code", { ...props.codeAttributes, style: { overflowWrap: "anywhere" }, children: props.userCode }),
1495
+ /* @__PURE__ */ jsx13(
802
1496
  "button",
803
1497
  {
804
1498
  type: "button",
@@ -807,19 +1501,19 @@ function DeviceAuthorization(props) {
807
1501
  children: copied ? "Copied" : "Copy code"
808
1502
  }
809
1503
  ),
810
- href ? /* @__PURE__ */ jsxs7("a", { href, target: "_blank", rel: "noopener noreferrer", children: [
1504
+ href ? /* @__PURE__ */ jsxs11("a", { href, target: "_blank", rel: "noopener noreferrer", children: [
811
1505
  "Open ",
812
1506
  props.providerLabel ?? "auth page"
813
- ] }) : /* @__PURE__ */ jsx7("span", { role: "alert", children: "Authorization address unavailable." })
1507
+ ] }) : /* @__PURE__ */ jsx13("span", { role: "alert", children: "Authorization address unavailable." })
814
1508
  ] }),
815
- copyError ? /* @__PURE__ */ jsx7("p", { role: "alert", children: "Couldn't copy the code. Copy it manually instead." }) : null,
816
- /* @__PURE__ */ jsx7("p", { role: "status", children: "Waiting for authorization\u2026" })
1509
+ copyError ? /* @__PURE__ */ jsx13("p", { role: "alert", children: "Couldn't copy the code. Copy it manually instead." }) : null,
1510
+ /* @__PURE__ */ jsx13("p", { role: "status", children: "Waiting for authorization\u2026" })
817
1511
  ] });
818
1512
  }
819
1513
 
820
1514
  // src/identity-link-consent.tsx
821
- import { useEffect as useEffect5, useRef as useRef3, useState as useState6 } from "react";
822
- import { Fragment as Fragment5, jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
1515
+ import { useEffect as useEffect7, useRef as useRef4, useState as useState10 } from "react";
1516
+ import { Fragment as Fragment6, jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
823
1517
  function IdentityLinkConsent({
824
1518
  client,
825
1519
  workspaceId,
@@ -828,14 +1522,14 @@ function IdentityLinkConsent({
828
1522
  className,
829
1523
  onComplete
830
1524
  }) {
831
- const [link, setLink] = useState6(null);
832
- const [preview, setPreview] = useState6(null);
833
- const [selected, setSelected] = useState6([]);
834
- const [busy, setBusy] = useState6(false);
835
- const [error, setError] = useState6(false);
836
- const [retry, setRetry] = useState6(0);
837
- const generation = useRef3(0);
838
- useEffect5(() => {
1525
+ const [link, setLink] = useState10(null);
1526
+ const [preview, setPreview] = useState10(null);
1527
+ const [selected, setSelected] = useState10([]);
1528
+ const [busy, setBusy] = useState10(false);
1529
+ const [error, setError] = useState10(false);
1530
+ const [retry, setRetry] = useState10(0);
1531
+ const generation = useRef4(0);
1532
+ useEffect7(() => {
839
1533
  const current = ++generation.current;
840
1534
  setLink(null);
841
1535
  setPreview(null);
@@ -879,43 +1573,43 @@ function IdentityLinkConsent({
879
1573
  if (generation.current === current) setBusy(false);
880
1574
  }
881
1575
  }
882
- return /* @__PURE__ */ jsxs8(
1576
+ return /* @__PURE__ */ jsxs12(
883
1577
  "section",
884
1578
  {
885
1579
  className: ["og-connect og-identity-link", className].filter(Boolean).join(" "),
886
1580
  "aria-label": "Link your account",
887
1581
  "aria-busy": busy,
888
1582
  children: [
889
- /* @__PURE__ */ jsx8("h2", { children: "Link your OpenGeni account" }),
890
- /* @__PURE__ */ jsx8("p", { children: "Only continue if you started this request in a product you trust. Linking lets that product act as your account with the permissions you select. It does not merge accounts or move existing work." }),
891
- preview && /* @__PURE__ */ jsxs8("dl", { children: [
892
- /* @__PURE__ */ jsx8("dt", { children: "Organization" }),
893
- /* @__PURE__ */ jsx8("dd", { children: preview.organizationId }),
894
- /* @__PURE__ */ jsx8("dt", { children: "Product user" }),
895
- /* @__PURE__ */ jsxs8("dd", { children: [
1583
+ /* @__PURE__ */ jsx14("h2", { children: "Link your OpenGeni account" }),
1584
+ /* @__PURE__ */ jsx14("p", { children: "Only continue if you started this request in a product you trust. Linking lets that product act as your account with the permissions you select. It does not merge accounts or move existing work." }),
1585
+ preview && /* @__PURE__ */ jsxs12("dl", { children: [
1586
+ /* @__PURE__ */ jsx14("dt", { children: "Organization" }),
1587
+ /* @__PURE__ */ jsx14("dd", { children: preview.organizationId }),
1588
+ /* @__PURE__ */ jsx14("dt", { children: "Product user" }),
1589
+ /* @__PURE__ */ jsxs12("dd", { children: [
896
1590
  preview.externalIdentity.externalId,
897
1591
  " (",
898
1592
  preview.externalIdentity.source,
899
1593
  ")"
900
1594
  ] }),
901
- /* @__PURE__ */ jsx8("dt", { children: "Your OpenGeni identity" }),
902
- /* @__PURE__ */ jsx8("dd", { children: preview.nativeSubjectId })
1595
+ /* @__PURE__ */ jsx14("dt", { children: "Your OpenGeni identity" }),
1596
+ /* @__PURE__ */ jsx14("dd", { children: preview.nativeSubjectId })
903
1597
  ] }),
904
- error && /* @__PURE__ */ jsxs8("div", { role: "alert", children: [
1598
+ error && /* @__PURE__ */ jsxs12("div", { role: "alert", children: [
905
1599
  "This request could not be completed. It may have expired, changed, or require you to sign in to the right organization.",
906
- !link && /* @__PURE__ */ jsx8("button", { type: "button", disabled: busy, onClick: () => setRetry((value) => value + 1), children: "Try again" })
1600
+ !link && /* @__PURE__ */ jsx14("button", { type: "button", disabled: busy, onClick: () => setRetry((value) => value + 1), children: "Try again" })
907
1601
  ] }),
908
- !link && busy && /* @__PURE__ */ jsx8("p", { role: "status", children: "Loading the account-link request\u2026" }),
909
- link?.status === "pending" && /* @__PURE__ */ jsxs8(Fragment5, { children: [
910
- /* @__PURE__ */ jsxs8("p", { children: [
1602
+ !link && busy && /* @__PURE__ */ jsx14("p", { role: "status", children: "Loading the account-link request\u2026" }),
1603
+ link?.status === "pending" && /* @__PURE__ */ jsxs12(Fragment6, { children: [
1604
+ /* @__PURE__ */ jsxs12("p", { children: [
911
1605
  link.expiresAt ? `Access ends ${new Date(link.expiresAt).toLocaleString()}.` : "Access lasts until you or the product revoke this link.",
912
1606
  " ",
913
1607
  "Your current permissions still apply."
914
1608
  ] }),
915
- /* @__PURE__ */ jsxs8("fieldset", { disabled: busy, children: [
916
- /* @__PURE__ */ jsx8("legend", { children: "Allow these permissions" }),
917
- link.permissions.map((permission) => /* @__PURE__ */ jsxs8("label", { children: [
918
- /* @__PURE__ */ jsx8(
1609
+ /* @__PURE__ */ jsxs12("fieldset", { disabled: busy, children: [
1610
+ /* @__PURE__ */ jsx14("legend", { children: "Allow these permissions" }),
1611
+ link.permissions.map((permission) => /* @__PURE__ */ jsxs12("label", { children: [
1612
+ /* @__PURE__ */ jsx14(
919
1613
  "input",
920
1614
  {
921
1615
  type: "checkbox",
@@ -925,10 +1619,10 @@ function IdentityLinkConsent({
925
1619
  )
926
1620
  }
927
1621
  ),
928
- /* @__PURE__ */ jsx8("span", { children: permission.replaceAll(":", " \xB7 ") })
1622
+ /* @__PURE__ */ jsx14("span", { children: permission.replaceAll(":", " \xB7 ") })
929
1623
  ] }, permission))
930
1624
  ] }),
931
- /* @__PURE__ */ jsx8(
1625
+ /* @__PURE__ */ jsx14(
932
1626
  "button",
933
1627
  {
934
1628
  type: "button",
@@ -937,34 +1631,34 @@ function IdentityLinkConsent({
937
1631
  children: busy ? "Saving\u2026" : "Allow selected access"
938
1632
  }
939
1633
  ),
940
- /* @__PURE__ */ jsx8("p", { children: "You can close this page without granting access." })
1634
+ /* @__PURE__ */ jsx14("p", { children: "You can close this page without granting access." })
941
1635
  ] }),
942
- link?.status === "active" && /* @__PURE__ */ jsxs8(Fragment5, { children: [
943
- /* @__PURE__ */ jsx8("p", { role: "status", children: "Account linked. Return to your product to continue." }),
944
- /* @__PURE__ */ jsx8("button", { type: "button", disabled: busy, onClick: () => void mutate(true), children: "Revoke this link" })
1636
+ link?.status === "active" && /* @__PURE__ */ jsxs12(Fragment6, { children: [
1637
+ /* @__PURE__ */ jsx14("p", { role: "status", children: "Account linked. Return to your product to continue." }),
1638
+ /* @__PURE__ */ jsx14("button", { type: "button", disabled: busy, onClick: () => void mutate(true), children: "Revoke this link" })
945
1639
  ] }),
946
- link?.status === "revoked" && /* @__PURE__ */ jsx8("p", { role: "status", children: "Link revoked. Your OpenGeni account and existing work are unchanged." }),
947
- link?.status === "expired" && /* @__PURE__ */ jsx8("p", { role: "status", children: "This request has expired. Start a new request from your product." })
1640
+ link?.status === "revoked" && /* @__PURE__ */ jsx14("p", { role: "status", children: "Link revoked. Your OpenGeni account and existing work are unchanged." }),
1641
+ link?.status === "expired" && /* @__PURE__ */ jsx14("p", { role: "status", children: "This request has expired. Start a new request from your product." })
948
1642
  ]
949
1643
  }
950
1644
  );
951
1645
  }
952
1646
 
953
1647
  // src/identity-link-accounts.tsx
954
- import { useEffect as useEffect6, useRef as useRef4, useState as useState7 } from "react";
955
- import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
1648
+ import { useEffect as useEffect8, useRef as useRef5, useState as useState11 } from "react";
1649
+ import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
956
1650
  function IdentityLinkAccounts({
957
1651
  client,
958
1652
  workspaceId
959
1653
  }) {
960
- const [links, setLinks] = useState7([]);
961
- const [cursor, setCursor] = useState7(null);
962
- const [busy, setBusy] = useState7(true);
963
- const [error, setError] = useState7(false);
964
- const [revision, setRevision] = useState7(0);
965
- const generation = useRef4(0);
966
- const inFlight = useRef4(false);
967
- useEffect6(() => {
1654
+ const [links, setLinks] = useState11([]);
1655
+ const [cursor, setCursor] = useState11(null);
1656
+ const [busy, setBusy] = useState11(true);
1657
+ const [error, setError] = useState11(false);
1658
+ const [revision, setRevision] = useState11(0);
1659
+ const generation = useRef5(0);
1660
+ const inFlight = useRef5(false);
1661
+ useEffect8(() => {
968
1662
  const current = ++generation.current;
969
1663
  inFlight.current = true;
970
1664
  setLinks([]);
@@ -1021,68 +1715,69 @@ function IdentityLinkAccounts({
1021
1715
  }
1022
1716
  }
1023
1717
  }
1024
- return /* @__PURE__ */ jsxs9(
1718
+ return /* @__PURE__ */ jsxs13(
1025
1719
  "section",
1026
1720
  {
1027
1721
  className: "og-connect og-identity-link",
1028
1722
  "aria-label": "Linked product access",
1029
1723
  "aria-busy": busy,
1030
1724
  children: [
1031
- /* @__PURE__ */ jsx9("h2", { children: "Linked product access" }),
1032
- /* @__PURE__ */ jsx9("p", { children: "Manage products allowed to act as your account in this organization. Revoking a link stops future linked access; it does not delete your work or undo an operation already started." }),
1033
- error && /* @__PURE__ */ jsxs9("div", { role: "alert", children: [
1725
+ /* @__PURE__ */ jsx15("h2", { children: "Linked product access" }),
1726
+ /* @__PURE__ */ jsx15("p", { children: "Manage products allowed to act as your account in this organization. Revoking a link stops future linked access; it does not delete your work or undo an operation already started." }),
1727
+ error && /* @__PURE__ */ jsxs13("div", { role: "alert", children: [
1034
1728
  "Could not update account links. Reload to see current access.",
1035
- /* @__PURE__ */ jsx9("button", { type: "button", disabled: busy, onClick: () => setRevision((value) => value + 1), children: "Reload links" })
1729
+ /* @__PURE__ */ jsx15("button", { type: "button", disabled: busy, onClick: () => setRevision((value) => value + 1), children: "Reload links" })
1036
1730
  ] }),
1037
- busy && /* @__PURE__ */ jsx9("p", { role: "status", children: "Loading account links\u2026" }),
1038
- !busy && !error && links.length === 0 && /* @__PURE__ */ jsx9("p", { children: "No products have linked access to this account." }),
1039
- /* @__PURE__ */ jsx9("ul", { children: links.map((link) => /* @__PURE__ */ jsxs9("li", { children: [
1040
- /* @__PURE__ */ jsxs9("p", { children: [
1731
+ busy && /* @__PURE__ */ jsx15("p", { role: "status", children: "Loading account links\u2026" }),
1732
+ !busy && !error && links.length === 0 && /* @__PURE__ */ jsx15("p", { children: "No products have linked access to this account." }),
1733
+ /* @__PURE__ */ jsx15("ul", { children: links.map((link) => /* @__PURE__ */ jsxs13("li", { children: [
1734
+ /* @__PURE__ */ jsxs13("p", { children: [
1041
1735
  link.externalIdentity?.source || "Product identity",
1042
1736
  " ",
1043
- /* @__PURE__ */ jsx9("code", { children: link.externalIdentity?.externalId ?? link.externalIdentityId })
1737
+ /* @__PURE__ */ jsx15("code", { children: link.externalIdentity?.externalId ?? link.externalIdentityId })
1044
1738
  ] }),
1045
- /* @__PURE__ */ jsxs9("p", { children: [
1739
+ /* @__PURE__ */ jsxs13("p", { children: [
1046
1740
  "Status: ",
1047
1741
  link.status,
1048
1742
  ".",
1049
1743
  " ",
1050
1744
  link.expiresAt ? `Expires ${new Date(link.expiresAt).toLocaleString()}.` : "No automatic expiry."
1051
1745
  ] }),
1052
- /* @__PURE__ */ jsx9("p", { children: link.permissions.join(", ") }),
1053
- (link.status === "active" || link.status === "pending") && /* @__PURE__ */ jsx9("button", { type: "button", disabled: busy, onClick: () => void act(link), children: "Revoke access" })
1746
+ /* @__PURE__ */ jsx15("p", { children: link.permissions.join(", ") }),
1747
+ (link.status === "active" || link.status === "pending") && /* @__PURE__ */ jsx15("button", { type: "button", disabled: busy, onClick: () => void act(link), children: "Revoke access" })
1054
1748
  ] }, link.id)) }),
1055
- cursor && /* @__PURE__ */ jsx9("button", { type: "button", disabled: busy, onClick: () => void act(), children: "Load more links" })
1749
+ cursor && /* @__PURE__ */ jsx15("button", { type: "button", disabled: busy, onClick: () => void act(), children: "Load more links" })
1056
1750
  ]
1057
1751
  }
1058
1752
  );
1059
1753
  }
1060
1754
 
1061
1755
  // src/connection-installed.tsx
1062
- import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
1756
+ import { jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
1063
1757
  function ConnectionInstalled({
1064
1758
  items,
1065
1759
  title = "Connected",
1066
1760
  className = ""
1067
1761
  }) {
1068
1762
  if (!items.length) return null;
1069
- return /* @__PURE__ */ jsxs10("section", { "aria-label": title, className: `og-connection-installed ${className}`, children: [
1070
- /* @__PURE__ */ jsxs10("h2", { children: [
1763
+ return /* @__PURE__ */ jsxs14("section", { "aria-label": title, className: `og-connection-installed ${className}`, children: [
1764
+ /* @__PURE__ */ jsxs14("h2", { children: [
1071
1765
  title,
1072
1766
  " ",
1073
- /* @__PURE__ */ jsx10("span", { children: items.length })
1767
+ /* @__PURE__ */ jsx16("span", { children: items.length })
1074
1768
  ] }),
1075
- /* @__PURE__ */ jsx10("div", { children: items.map((item) => /* @__PURE__ */ jsxs10(
1769
+ /* @__PURE__ */ jsx16("div", { children: items.map((item) => /* @__PURE__ */ jsxs14(
1076
1770
  "button",
1077
1771
  {
1078
1772
  type: "button",
1079
1773
  onClick: item.onOpen,
1774
+ disabled: item.disabled,
1080
1775
  title: item.status,
1081
1776
  "aria-label": `${item.name} \xB7 ${item.status}`,
1082
1777
  children: [
1083
1778
  item.icon,
1084
- /* @__PURE__ */ jsx10("span", { children: item.name }),
1085
- item.needsAttention ? /* @__PURE__ */ jsx10("span", { "aria-label": "Needs attention", children: "!" }) : null
1779
+ /* @__PURE__ */ jsx16("span", { children: item.name }),
1780
+ item.needsAttention ? /* @__PURE__ */ jsx16("span", { "aria-label": "Needs attention", children: "!" }) : null
1086
1781
  ]
1087
1782
  },
1088
1783
  item.id
@@ -1092,21 +1787,21 @@ function ConnectionInstalled({
1092
1787
 
1093
1788
  // src/connection-type-picker.tsx
1094
1789
  import { useId } from "react";
1095
- import { jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
1790
+ import { jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
1096
1791
  function ConnectionTypePicker({
1097
1792
  value,
1098
1793
  onChange,
1099
1794
  disabled = false
1100
1795
  }) {
1101
1796
  const name = useId();
1102
- return /* @__PURE__ */ jsxs11("fieldset", { className: "og-connection-type-picker", disabled, children: [
1103
- /* @__PURE__ */ jsx11("legend", { children: "Connection type" }),
1797
+ return /* @__PURE__ */ jsxs15("fieldset", { className: "og-connection-type-picker", disabled, children: [
1798
+ /* @__PURE__ */ jsx17("legend", { children: "Connection type" }),
1104
1799
  [
1105
1800
  ["mcp", "MCP server"],
1106
1801
  ["openapi", "OpenAPI"],
1107
1802
  ["graphql", "GraphQL"]
1108
- ].map(([type, label]) => /* @__PURE__ */ jsxs11("label", { "data-selected": value === type, children: [
1109
- /* @__PURE__ */ jsx11(
1803
+ ].map(([type, label]) => /* @__PURE__ */ jsxs15("label", { "data-selected": value === type, children: [
1804
+ /* @__PURE__ */ jsx17(
1110
1805
  "input",
1111
1806
  {
1112
1807
  type: "radio",
@@ -1121,73 +1816,81 @@ function ConnectionTypePicker({
1121
1816
  ] });
1122
1817
  }
1123
1818
 
1124
- // src/connection-logo.tsx
1125
- import { useState as useState8 } from "react";
1126
- import { jsx as jsx12 } from "react/jsx-runtime";
1127
- function ConnectionLogo({
1128
- src,
1129
- name,
1130
- size = 40
1131
- }) {
1132
- const [failedSrc, setFailedSrc] = useState8(null);
1133
- return /* @__PURE__ */ jsx12("span", { className: "og-connection-logo", "aria-hidden": "true", style: { width: size, height: size }, children: src && src !== failedSrc ? /* @__PURE__ */ jsx12("img", { src, alt: "", loading: "lazy", decoding: "async", onError: () => setFailedSrc(src) }) : /* @__PURE__ */ jsx12("span", { children: name.split(/\s+/).map((part) => part[0]).join("").slice(0, 2).toUpperCase() }) });
1134
- }
1135
-
1136
1819
  // src/plugin-discovery.tsx
1137
- import { useEffect as useEffect7, useRef as useRef5, useState as useState9 } from "react";
1138
- import { Fragment as Fragment6, jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
1820
+ import { useEffect as useEffect9, useRef as useRef6, useState as useState12 } from "react";
1821
+ import { BoxesIcon } from "lucide-react";
1822
+ import { Fragment as Fragment7, jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
1823
+ var discoveryCache2 = createDiscoveryCache();
1824
+ var EMPTY_INSTALLED_IDS = /* @__PURE__ */ new Set();
1139
1825
  function PluginDiscovery(props) {
1140
- const [provider, setProvider] = useState9("");
1141
- return /* @__PURE__ */ jsxs12("section", { className: "og-plugin-discovery", "aria-label": "Discover plugins", children: [
1142
- /* @__PURE__ */ jsxs12("header", { children: [
1143
- /* @__PURE__ */ jsx13("h3", { children: "Browse plugins" }),
1144
- /* @__PURE__ */ jsx13("div", { className: "og-plugin-filters", role: "group", "aria-label": "Plugin registry", children: [
1145
- { value: "", label: "All" },
1146
- { value: "openai", label: "OpenAI plugin registry" },
1147
- { value: "anthropic", label: "Anthropic plugin registry" }
1148
- ].map((option) => /* @__PURE__ */ jsx13(
1149
- "button",
1150
- {
1151
- type: "button",
1152
- "aria-pressed": provider === option.value,
1153
- onClick: () => setProvider(option.value),
1154
- children: option.label
1155
- },
1156
- option.value
1157
- )) })
1158
- ] }),
1159
- /* @__PURE__ */ jsx13(
1160
- Results,
1161
- {
1162
- ...props,
1163
- provider
1164
- },
1165
- `${props.workspaceId}:${props.query}:${provider}`
1166
- )
1167
- ] });
1826
+ const [provider, setProvider] = useState12(props.defaultProvider ?? "");
1827
+ return /* @__PURE__ */ jsxs16(
1828
+ "section",
1829
+ {
1830
+ className: `og-plugin-discovery ${props.resultLimit ? "og-catalog-overview" : ""}`,
1831
+ "aria-label": "Discover plugins",
1832
+ children: [
1833
+ /* @__PURE__ */ jsxs16("header", { children: [
1834
+ /* @__PURE__ */ jsx18("h3", { children: props.resultLimit ? "Plugins" : "Browse plugins" }),
1835
+ !props.resultLimit ? /* @__PURE__ */ jsx18("div", { className: "og-plugin-filters", role: "group", "aria-label": "Plugin registry", children: [
1836
+ { value: "", label: "All" },
1837
+ { value: "openai", label: "OpenAI plugin registry" },
1838
+ { value: "anthropic", label: "Anthropic plugin registry" }
1839
+ ].map((option) => /* @__PURE__ */ jsx18(
1840
+ "button",
1841
+ {
1842
+ type: "button",
1843
+ "aria-pressed": provider === option.value,
1844
+ onClick: () => setProvider(option.value),
1845
+ children: option.label
1846
+ },
1847
+ option.value
1848
+ )) }) : null
1849
+ ] }),
1850
+ /* @__PURE__ */ jsx18(
1851
+ Results,
1852
+ {
1853
+ ...props,
1854
+ provider
1855
+ },
1856
+ `${props.workspaceId}:${props.query}:${provider}`
1857
+ )
1858
+ ]
1859
+ }
1860
+ );
1168
1861
  }
1169
1862
  function Results({
1170
1863
  client,
1171
1864
  workspaceId,
1172
1865
  query,
1173
1866
  provider,
1174
- onOpen
1867
+ installedIds = EMPTY_INSTALLED_IDS,
1868
+ onOpen,
1869
+ resultLimit,
1870
+ onShowMore
1175
1871
  }) {
1176
- const [items, setItems] = useState9([]);
1177
- const [offset, setOffset] = useState9(0);
1178
- const [next, setNext] = useState9(null);
1179
- const [total, setTotal] = useState9(0);
1180
- const [loading, setLoading] = useState9(true);
1181
- const [error, setError] = useState9(false);
1182
- const [retry, setRetry] = useState9(0);
1183
- const sentinel = useRef5(null);
1184
- useEffect7(() => {
1872
+ const initial = discoveryCache2.peek(client, JSON.stringify([workspaceId, query, provider, 0]));
1873
+ const [items, setItems] = useState12(initial?.items ?? []);
1874
+ const [offset, setOffset] = useState12(0);
1875
+ const [next, setNext] = useState12(initial?.nextOffset ?? null);
1876
+ const [total, setTotal] = useState12(initial?.total ?? 0);
1877
+ const [loading, setLoading] = useState12(!initial);
1878
+ const [error, setError] = useState12(false);
1879
+ const [retry, setRetry] = useState12(0);
1880
+ const sentinel = useRef6(null);
1881
+ useEffect9(() => {
1185
1882
  let active = true;
1186
- setLoading(true);
1883
+ const cacheKey = JSON.stringify([workspaceId, query, provider, offset]);
1884
+ const cached = discoveryCache2.peek(client, cacheKey);
1885
+ setLoading(!cached);
1187
1886
  setError(false);
1188
1887
  const timer = setTimeout(
1189
1888
  () => {
1190
- void client.discoverPlugins(workspaceId, { query, provider, offset }).then(
1889
+ void discoveryCache2.read(
1890
+ client,
1891
+ cacheKey,
1892
+ () => client.discoverPlugins(workspaceId, { query, provider, offset })
1893
+ ).then(
1191
1894
  (page) => {
1192
1895
  if (!active) return;
1193
1896
  setItems((previous) => offset ? [...previous, ...page.items] : page.items);
@@ -1203,15 +1906,15 @@ function Results({
1203
1906
  }
1204
1907
  );
1205
1908
  },
1206
- offset ? 0 : 200
1909
+ cached || offset ? 0 : 200
1207
1910
  );
1208
1911
  return () => {
1209
1912
  active = false;
1210
1913
  clearTimeout(timer);
1211
1914
  };
1212
1915
  }, [client, workspaceId, query, provider, offset, retry]);
1213
- useEffect7(() => {
1214
- if (loading || error || next === null || !sentinel.current) return;
1916
+ useEffect9(() => {
1917
+ if (resultLimit || loading || error || next === null || !sentinel.current) return;
1215
1918
  const observer = new IntersectionObserver(
1216
1919
  (entries) => {
1217
1920
  if (entries.some((entry) => entry.isIntersecting)) setOffset(next);
@@ -1220,54 +1923,45 @@ function Results({
1220
1923
  );
1221
1924
  observer.observe(sentinel.current);
1222
1925
  return () => observer.disconnect();
1223
- }, [loading, error, next]);
1224
- return /* @__PURE__ */ jsxs12(Fragment6, { children: [
1225
- !loading && !error ? /* @__PURE__ */ jsx13("p", { role: "status", children: total ? `${total} plugins` : "No matching plugins. Try another search or registry." }) : null,
1226
- /* @__PURE__ */ jsx13("div", { className: "og-plugin-discovery-grid", children: items.map((item) => /* @__PURE__ */ jsxs12(
1227
- "button",
1926
+ }, [loading, error, next, resultLimit]);
1927
+ return /* @__PURE__ */ jsxs16(Fragment7, { children: [
1928
+ !loading && !error ? /* @__PURE__ */ jsx18("p", { role: "status", children: total ? `${total} plugins` : "No matching plugins. Try another search or registry." }) : null,
1929
+ /* @__PURE__ */ jsx18("div", { className: "og-plugin-discovery-grid", children: items.slice(0, resultLimit).map((item) => /* @__PURE__ */ jsx18(
1930
+ CapabilityCatalogRow,
1228
1931
  {
1229
- className: "og-plugin-discovery-row",
1230
- type: "button",
1231
- onClick: () => onOpen(item),
1232
- children: [
1233
- item.logoUrl ? /* @__PURE__ */ jsx13(
1234
- "img",
1235
- {
1236
- src: item.logoUrl,
1237
- alt: "",
1238
- loading: "lazy",
1239
- onError: (event) => {
1240
- event.currentTarget.style.display = "none";
1241
- }
1242
- }
1243
- ) : null,
1244
- /* @__PURE__ */ jsxs12("span", { className: "og-plugin-copy", children: [
1245
- /* @__PURE__ */ jsxs12("span", { className: "og-plugin-title", children: [
1246
- /* @__PURE__ */ jsx13("strong", { children: item.displayName.replace(/-/g, " ") }),
1247
- /* @__PURE__ */ jsx13("small", { children: item.provider === "openai" ? "OpenAI plugin registry" : "Anthropic plugin registry" })
1248
- ] }),
1249
- /* @__PURE__ */ jsx13("span", { className: "og-plugin-description", children: item.description }),
1250
- item.category ? /* @__PURE__ */ jsx13("span", { className: "og-plugin-category", children: item.category }) : null
1251
- ] }),
1252
- /* @__PURE__ */ jsx13("span", { className: "og-plugin-open", "aria-hidden": "true", children: "\u203A" })
1253
- ]
1932
+ "data-plugin-id": item.id,
1933
+ name: item.displayName.replace(/-/g, " "),
1934
+ description: item.description,
1935
+ status: installedIds.has(item.id) ? "added" : "available",
1936
+ statusLabel: installedIds.has(item.id) ? "Installed" : "Available to install",
1937
+ onOpen: () => onOpen(item),
1938
+ icon: /* @__PURE__ */ jsx18(
1939
+ ConnectionLogo,
1940
+ {
1941
+ src: item.logoUrl,
1942
+ name: item.displayName,
1943
+ fallback: /* @__PURE__ */ jsx18(BoxesIcon, { "aria-hidden": "true" })
1944
+ }
1945
+ )
1254
1946
  },
1255
1947
  item.id
1256
1948
  )) }),
1257
- loading ? /* @__PURE__ */ jsx13("p", { role: "status", children: "Loading plugins\u2026" }) : null,
1258
- error ? /* @__PURE__ */ jsxs12("p", { role: "alert", children: [
1949
+ loading ? /* @__PURE__ */ jsx18("p", { role: "status", children: "Loading plugins\u2026" }) : null,
1950
+ error ? /* @__PURE__ */ jsxs16("p", { role: "alert", children: [
1259
1951
  "Couldn\u2019t load plugins.",
1260
1952
  " ",
1261
- /* @__PURE__ */ jsx13("button", { type: "button", onClick: () => setRetry((value) => value + 1), children: "Retry" })
1953
+ /* @__PURE__ */ jsx18("button", { type: "button", onClick: () => setRetry((value) => value + 1), children: "Retry" })
1262
1954
  ] }) : null,
1263
- /* @__PURE__ */ jsx13("div", { ref: sentinel, children: next !== null && !loading && !error ? /* @__PURE__ */ jsx13("button", { className: "og-plugin-more", type: "button", onClick: () => setOffset(next), children: "Show more plugins" }) : null })
1955
+ resultLimit && !loading && !error && total > resultLimit ? /* @__PURE__ */ jsx18("button", { className: "og-catalog-more", type: "button", onClick: onShowMore, children: "View all plugins" }) : null,
1956
+ /* @__PURE__ */ jsx18("div", { ref: sentinel, children: !resultLimit && next !== null && !loading && !error ? /* @__PURE__ */ jsx18("button", { className: "og-plugin-more", type: "button", onClick: () => setOffset(next), children: "Show more plugins" }) : null })
1264
1957
  ] });
1265
1958
  }
1266
1959
 
1267
1960
  // src/plugin-details.tsx
1268
- import { useState as useState10 } from "react";
1961
+ import { useState as useState13 } from "react";
1269
1962
  import { pluginMcpUnavailableReason } from "@opengeni/sdk";
1270
- import { jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
1963
+ import { BoxesIcon as BoxesIcon2 } from "lucide-react";
1964
+ import { jsx as jsx19, jsxs as jsxs17 } from "react/jsx-runtime";
1271
1965
  var componentLabels = {
1272
1966
  skills: "Skills",
1273
1967
  mcp: "MCP connections",
@@ -1291,57 +1985,63 @@ function PluginDetails({
1291
1985
  const contentsUnknown = item.skills == null || item.mcpServers == null;
1292
1986
  const installableCount = (item.skills?.length ?? 0) + (item.mcpServers?.filter(supported).length ?? 0);
1293
1987
  const exceedsInstallLimit = installableCount > 64;
1294
- const installable = installableCount > 0 && !exceedsInstallLimit;
1295
- const [expanded, setExpanded] = useState10(false);
1296
- const [logoFailed, setLogoFailed] = useState10(false);
1988
+ const installable = !contentsUnknown && installableCount > 0 && !exceedsInstallLimit;
1989
+ const [expanded, setExpanded] = useState13(false);
1297
1990
  const description = item.longDescription || item.description;
1298
1991
  const lengthy = description.length > 700;
1299
1992
  const registryLabel = item.provider === "openai" ? "OpenAI plugin registry" : item.provider === "anthropic" ? "Anthropic plugin registry" : "Custom source";
1300
- return /* @__PURE__ */ jsxs13("article", { className: "og-plugin-details", children: [
1301
- /* @__PURE__ */ jsxs13("header", { className: "og-plugin-details-header", children: [
1302
- item.logoUrl && !logoFailed ? /* @__PURE__ */ jsx14("img", { src: item.logoUrl, alt: "", onError: () => setLogoFailed(true) }) : null,
1303
- /* @__PURE__ */ jsxs13("div", { children: [
1304
- /* @__PURE__ */ jsx14("h2", { children: item.displayName.replace(/-/g, " ") }),
1305
- item.author?.name ? /* @__PURE__ */ jsxs13("p", { children: [
1993
+ return /* @__PURE__ */ jsxs17("article", { className: "og-plugin-details", children: [
1994
+ /* @__PURE__ */ jsxs17("header", { className: "og-plugin-details-header", children: [
1995
+ /* @__PURE__ */ jsx19(
1996
+ ConnectionLogo,
1997
+ {
1998
+ src: item.logoUrl,
1999
+ name: item.displayName,
2000
+ fallback: /* @__PURE__ */ jsx19(BoxesIcon2, { "aria-hidden": "true" })
2001
+ }
2002
+ ),
2003
+ /* @__PURE__ */ jsxs17("div", { children: [
2004
+ /* @__PURE__ */ jsx19("h2", { children: item.displayName.replace(/-/g, " ") }),
2005
+ item.author?.name ? /* @__PURE__ */ jsxs17("p", { children: [
1306
2006
  "By ",
1307
2007
  item.author.name
1308
2008
  ] }) : null
1309
2009
  ] })
1310
2010
  ] }),
1311
- /* @__PURE__ */ jsxs13("div", { className: "og-plugin-details-meta", children: [
1312
- /* @__PURE__ */ jsx14("span", { children: registryLabel }),
1313
- item.category ? /* @__PURE__ */ jsx14("span", { children: item.category }) : null,
1314
- item.version ? /* @__PURE__ */ jsxs13("span", { children: [
2011
+ /* @__PURE__ */ jsxs17("div", { className: "og-plugin-details-meta", children: [
2012
+ /* @__PURE__ */ jsx19("span", { children: registryLabel }),
2013
+ item.category ? /* @__PURE__ */ jsx19("span", { children: item.category }) : null,
2014
+ item.version ? /* @__PURE__ */ jsxs17("span", { children: [
1315
2015
  "v",
1316
2016
  item.version
1317
2017
  ] }) : null
1318
2018
  ] }),
1319
- /* @__PURE__ */ jsxs13("section", { className: "og-plugin-details-members", children: [
1320
- /* @__PURE__ */ jsxs13("h3", { children: [
2019
+ /* @__PURE__ */ jsxs17("section", { className: "og-plugin-details-members", children: [
2020
+ /* @__PURE__ */ jsxs17("h3", { children: [
1321
2021
  "Skills ",
1322
- /* @__PURE__ */ jsx14("span", { children: item.skills?.length ?? "\u2014" })
2022
+ /* @__PURE__ */ jsx19("span", { children: item.skills?.length ?? "\u2014" })
1323
2023
  ] }),
1324
- item.skills?.length ? /* @__PURE__ */ jsx14("ul", { children: item.skills.map((skill) => /* @__PURE__ */ jsx14("li", { children: /* @__PURE__ */ jsxs13("a", { href: skill.sourceUrl, target: "_blank", rel: "noopener noreferrer", children: [
1325
- /* @__PURE__ */ jsx14("strong", { children: skill.name }),
1326
- /* @__PURE__ */ jsx14("span", { "aria-hidden": "true", children: "\u2197" })
1327
- ] }) }, skill.sourceUrl)) }) : /* @__PURE__ */ jsx14("p", { children: item.skills ? "No bundled skills." : "Contents haven\u2019t been indexed for this repository." }),
1328
- /* @__PURE__ */ jsxs13("h3", { children: [
2024
+ item.skills?.length ? /* @__PURE__ */ jsx19("ul", { children: item.skills.map((skill) => /* @__PURE__ */ jsx19("li", { children: /* @__PURE__ */ jsxs17("a", { href: skill.sourceUrl, target: "_blank", rel: "noopener noreferrer", children: [
2025
+ /* @__PURE__ */ jsx19("strong", { children: skill.name }),
2026
+ /* @__PURE__ */ jsx19("span", { "aria-hidden": "true", children: "\u2197" })
2027
+ ] }) }, skill.sourceUrl)) }) : /* @__PURE__ */ jsx19("p", { children: item.skills ? "No bundled skills." : "Contents haven\u2019t been indexed for this repository." }),
2028
+ /* @__PURE__ */ jsxs17("h3", { children: [
1329
2029
  "MCP servers ",
1330
- /* @__PURE__ */ jsx14("span", { children: item.mcpServers?.length ?? "\u2014" })
2030
+ /* @__PURE__ */ jsx19("span", { children: item.mcpServers?.length ?? "\u2014" })
1331
2031
  ] }),
1332
- item.mcpServers?.length ? /* @__PURE__ */ jsx14("ul", { children: item.mcpServers.map((server) => {
2032
+ item.mcpServers?.length ? /* @__PURE__ */ jsx19("ul", { children: item.mcpServers.map((server) => {
1333
2033
  const connected = Boolean(server.endpoint && connections[server.endpoint]);
1334
2034
  const unavailableReason = connected ? null : pluginMcpUnavailableReason(server);
1335
- return /* @__PURE__ */ jsxs13(
2035
+ return /* @__PURE__ */ jsxs17(
1336
2036
  "li",
1337
2037
  {
1338
2038
  className: unavailableReason ? "og-plugin-member-disabled" : void 0,
1339
2039
  children: [
1340
- /* @__PURE__ */ jsxs13("div", { className: "og-plugin-server-heading", children: [
1341
- /* @__PURE__ */ jsx14("strong", { children: server.name }),
1342
- !unavailableReason && onConnect ? /* @__PURE__ */ jsx14("button", { type: "button", disabled: busy, onClick: () => onConnect(server), children: connected ? "Manage" : "Connect" }) : null
2040
+ /* @__PURE__ */ jsxs17("div", { className: "og-plugin-server-heading", children: [
2041
+ /* @__PURE__ */ jsx19("strong", { children: server.name }),
2042
+ !unavailableReason && onConnect ? /* @__PURE__ */ jsx19("button", { type: "button", disabled: busy, onClick: () => onConnect(server), children: connected ? "Manage" : "Connect" }) : null
1343
2043
  ] }),
1344
- /* @__PURE__ */ jsxs13("small", { children: [
2044
+ /* @__PURE__ */ jsxs17("small", { children: [
1345
2045
  connected ? "Connected \xB7 " : "",
1346
2046
  unavailableReason ?? server.endpoint
1347
2047
  ] })
@@ -1349,16 +2049,16 @@ function PluginDetails({
1349
2049
  },
1350
2050
  server.name
1351
2051
  );
1352
- }) }) : /* @__PURE__ */ jsx14("p", { children: item.mcpServers ? "No bundled MCP servers." : "Server details haven\u2019t been indexed." }),
1353
- item.components?.some((component) => !["skills", "mcp"].includes(component)) ? /* @__PURE__ */ jsxs13("div", { className: "og-plugin-details-other", children: [
2052
+ }) }) : /* @__PURE__ */ jsx19("p", { children: item.mcpServers ? "No bundled MCP servers." : "Server details haven\u2019t been indexed." }),
2053
+ item.components?.some((component) => !["skills", "mcp"].includes(component)) ? /* @__PURE__ */ jsxs17("div", { className: "og-plugin-details-other", children: [
1354
2054
  "Not installed here:",
1355
2055
  " ",
1356
2056
  item.components.filter((component) => !["skills", "mcp"].includes(component)).map((component) => componentLabels[component] ?? component).join(", ")
1357
2057
  ] }) : null
1358
2058
  ] }),
1359
- /* @__PURE__ */ jsxs13("section", { className: "og-plugin-details-overview", "aria-label": "Overview", children: [
1360
- /* @__PURE__ */ jsx14("div", { className: lengthy && !expanded ? "og-plugin-details-excerpt" : void 0, children: /* @__PURE__ */ jsx14(Markdown, { children: description }) }),
1361
- lengthy ? /* @__PURE__ */ jsx14(
2059
+ /* @__PURE__ */ jsxs17("section", { className: "og-plugin-details-overview", "aria-label": "Overview", children: [
2060
+ /* @__PURE__ */ jsx19("div", { className: lengthy && !expanded ? "og-plugin-details-excerpt" : void 0, children: /* @__PURE__ */ jsx19(Markdown, { children: description }) }),
2061
+ lengthy ? /* @__PURE__ */ jsx19(
1362
2062
  "button",
1363
2063
  {
1364
2064
  type: "button",
@@ -1369,12 +2069,12 @@ function PluginDetails({
1369
2069
  }
1370
2070
  ) : null
1371
2071
  ] }),
1372
- /* @__PURE__ */ jsxs13("footer", { children: [
1373
- item.sourceUrl ? /* @__PURE__ */ jsxs13("a", { href: item.sourceUrl, target: "_blank", rel: "noopener noreferrer", children: [
2072
+ /* @__PURE__ */ jsxs17("footer", { children: [
2073
+ item.sourceUrl ? /* @__PURE__ */ jsxs17("a", { href: item.sourceUrl, target: "_blank", rel: "noopener noreferrer", children: [
1374
2074
  "View repository ",
1375
- /* @__PURE__ */ jsx14("span", { "aria-hidden": "true", children: "\u2197" })
2075
+ /* @__PURE__ */ jsx19("span", { "aria-hidden": "true", children: "\u2197" })
1376
2076
  ] }) : null,
1377
- onInstall ? /* @__PURE__ */ jsx14(
2077
+ onInstall ? /* @__PURE__ */ jsx19(
1378
2078
  "button",
1379
2079
  {
1380
2080
  className: "og-plugin-install",
@@ -1384,38 +2084,20 @@ function PluginDetails({
1384
2084
  children: installed ? "Installed" : busy ? "Installing\u2026" : "Install plugin"
1385
2085
  }
1386
2086
  ) : null,
1387
- error ? /* @__PURE__ */ jsx14("p", { role: "alert", children: error }) : null,
1388
- exceedsInstallLimit ? /* @__PURE__ */ jsx14("p", { children: "This plugin exceeds the current 64-component installation limit." }) : contentsUnknown ? /* @__PURE__ */ jsx14("p", { children: "Plugin contents are unavailable. Installation is disabled until the repository can be inspected." }) : !installable ? /* @__PURE__ */ jsx14("p", { children: "No installable skills or remote MCP servers." }) : /* @__PURE__ */ jsx14("p", { children: "Installs skills and adds connection references. Connect each server separately." })
2087
+ error ? /* @__PURE__ */ jsx19("p", { role: "alert", children: error }) : null,
2088
+ exceedsInstallLimit ? /* @__PURE__ */ jsx19("p", { children: "This plugin exceeds the current 64-component installation limit." }) : contentsUnknown ? /* @__PURE__ */ jsx19("p", { children: "Plugin contents are unavailable. Installation is disabled until the repository can be inspected." }) : !installable ? /* @__PURE__ */ jsx19("p", { children: "No installable skills or remote MCP servers." }) : /* @__PURE__ */ jsx19("p", { children: "Installs skills and adds connection references. Connect each server separately." })
1389
2089
  ] })
1390
2090
  ] });
1391
2091
  }
1392
-
1393
- // src/connect.ts
1394
- function useConnect(controller) {
1395
- const snapshot = useSyncExternalStore(
1396
- controller.subscribe,
1397
- controller.getSnapshot,
1398
- controller.getSnapshot
1399
- );
1400
- const actions = useMemo(
1401
- () => ({
1402
- begin: controller.begin.bind(controller),
1403
- recover: controller.recover.bind(controller),
1404
- refresh: controller.refresh.bind(controller),
1405
- waitForAction: controller.waitForAction.bind(controller),
1406
- advance: controller.advance.bind(controller),
1407
- cancel: controller.cancel.bind(controller)
1408
- }),
1409
- [controller]
1410
- );
1411
- return useMemo(() => ({ ...snapshot, ...actions }), [snapshot, actions]);
1412
- }
1413
2092
  export {
2093
+ CapabilityCatalogIndicator,
2094
+ CapabilityCatalogRow,
1414
2095
  ConnectAccounts,
1415
2096
  ConnectChooser,
1416
2097
  ConnectPanel,
1417
2098
  ConnectSetup,
1418
2099
  ConnectionCatalog,
2100
+ ConnectionDiscovery,
1419
2101
  ConnectionInstalled,
1420
2102
  ConnectionLogo,
1421
2103
  ConnectionOptionRow,
@@ -1424,9 +2106,11 @@ export {
1424
2106
  DeviceAuthorization,
1425
2107
  IdentityLinkAccounts,
1426
2108
  IdentityLinkConsent,
2109
+ McpConnectionCard,
1427
2110
  PluginDetails,
1428
2111
  PluginDiscovery,
1429
2112
  SkillDiscovery,
2113
+ capabilityLogoFallback,
1430
2114
  useConnect
1431
2115
  };
1432
2116
  //# sourceMappingURL=connect.js.map