@truefoundry/trueforge-ui 0.3.0-rc.1 → 0.3.0-rc.11

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 (112) hide show
  1. package/CHANGELOG.md +156 -0
  2. package/README.md +23 -8
  3. package/dist/{AgentCodeSnippets-NZOFJE57.js → AgentCodeSnippets-CHDVZHHK.js} +38 -23
  4. package/dist/AgentCodeSnippets-CHDVZHHK.js.map +1 -0
  5. package/dist/AgentMetricChart-6RGWFMJE.js +15 -0
  6. package/dist/AgentOverview-3LJZ6MO7.js +311 -0
  7. package/dist/AgentOverview-3LJZ6MO7.js.map +1 -0
  8. package/dist/{AgentSessionEventTimeline-26Z6IB3B.js → AgentSessionEventTimeline-5GOJKT7D.js} +19 -10
  9. package/dist/AgentSessionEventTimeline-5GOJKT7D.js.map +1 -0
  10. package/dist/{AgentSessionEventTimelineChart-CGCU7WBK.js → AgentSessionEventTimelineChart-UYG3JQMP.js} +144 -57
  11. package/dist/AgentSessionEventTimelineChart-UYG3JQMP.js.map +1 -0
  12. package/dist/{AgentSessions-3MPDZASK.js → AgentSessions-KUABCQ4W.js} +140 -27
  13. package/dist/AgentSessions-KUABCQ4W.js.map +1 -0
  14. package/dist/{ConnectorSettings-MXFRWWR6.js → ConnectorSettings-PED5C2P7.js} +162 -126
  15. package/dist/ConnectorSettings-PED5C2P7.js.map +1 -0
  16. package/dist/{DockLayout-LM4AFMFY.js → DockLayout-ACM7BVIH.js} +10 -10
  17. package/dist/{DrawerLayout-JR3O6RRB.js → DrawerLayout-SGBYRKHI.js} +14 -12
  18. package/dist/DrawerLayout-SGBYRKHI.js.map +1 -0
  19. package/dist/{ModelSettings-G7IFNC2Y.js → ModelSettings-GJTVFXFY.js} +22 -28
  20. package/dist/ModelSettings-GJTVFXFY.js.map +1 -0
  21. package/dist/OpenUiFenceBlock-MJTC2VJ5.js +9 -0
  22. package/dist/{SandboxSettings-NXAANMAX.js → SandboxSettings-VETQ7UPE.js} +17 -21
  23. package/dist/SandboxSettings-VETQ7UPE.js.map +1 -0
  24. package/dist/SchedulesPage-LHJ3U2VM.js +15 -0
  25. package/dist/{SettingsBuilder-L34IQ56S.js → SettingsBuilder-5ZCU66FF.js} +9 -9
  26. package/dist/{SettingsBuilder-L34IQ56S.js.map → SettingsBuilder-5ZCU66FF.js.map} +1 -1
  27. package/dist/{ShellRouteSync-CEBETGEJ.js → ShellRouteSync-SJXFKUAJ.js} +171 -26
  28. package/dist/ShellRouteSync-SJXFKUAJ.js.map +1 -0
  29. package/dist/{SidebarLayout-A2HJPPHS.js → SidebarLayout-TR5CAB6Q.js} +80 -58
  30. package/dist/SidebarLayout-TR5CAB6Q.js.map +1 -0
  31. package/dist/{SkillSettings-FGGMSUNO.js → SkillSettings-TRTY2YH3.js} +24 -22
  32. package/dist/SkillSettings-TRTY2YH3.js.map +1 -0
  33. package/dist/{TrueForgeUIWithRouter-MZVJWJMB.js → TrueForgeUIWithRouter-GZUSRZIR.js} +9 -9
  34. package/dist/{WidgetLayout-6QM45OQQ.js → WidgetLayout-2TM6I4LJ.js} +10 -10
  35. package/dist/{chunk-U7KURWW3.js → chunk-2GIZY3JJ.js} +276 -54
  36. package/dist/chunk-2GIZY3JJ.js.map +1 -0
  37. package/dist/{chunk-ZKNUMH2M.js → chunk-2MUK3SMR.js} +13 -11
  38. package/dist/chunk-2MUK3SMR.js.map +1 -0
  39. package/dist/{chunk-WVE3F724.js → chunk-2QTH6JHX.js} +21 -4
  40. package/dist/chunk-2QTH6JHX.js.map +1 -0
  41. package/dist/{chunk-XAU7QFG3.js → chunk-5N5V7YLO.js} +72 -256
  42. package/dist/chunk-5N5V7YLO.js.map +1 -0
  43. package/dist/{chunk-CYHJDKFB.js → chunk-75YEQUUD.js} +189 -52
  44. package/dist/chunk-75YEQUUD.js.map +1 -0
  45. package/dist/{chunk-QC42MLAK.js → chunk-7AAO4UDQ.js} +4 -3
  46. package/dist/chunk-7AAO4UDQ.js.map +1 -0
  47. package/dist/{chunk-M62XY4NC.js → chunk-BXG6XN2S.js} +235 -108
  48. package/dist/chunk-BXG6XN2S.js.map +1 -0
  49. package/dist/chunk-GKXDRULM.js +587 -0
  50. package/dist/chunk-GKXDRULM.js.map +1 -0
  51. package/dist/{chunk-ZTMKFZQ3.js → chunk-OH357IHR.js} +5572 -3367
  52. package/dist/chunk-OH357IHR.js.map +1 -0
  53. package/dist/{chunk-DMMZSZTN.js → chunk-P6MZDITS.js} +60 -16
  54. package/dist/chunk-P6MZDITS.js.map +1 -0
  55. package/dist/{chunk-MPNSO7E6.js → chunk-SLMFEG7X.js} +2 -2
  56. package/dist/chunk-T6QQV5LK.js +238 -0
  57. package/dist/chunk-T6QQV5LK.js.map +1 -0
  58. package/dist/{chunk-6O6FWUDW.js → chunk-UWLL327M.js} +641 -388
  59. package/dist/chunk-UWLL327M.js.map +1 -0
  60. package/dist/{chunk-FJW36PD7.js → chunk-VAOCM3QQ.js} +28 -24
  61. package/dist/chunk-VAOCM3QQ.js.map +1 -0
  62. package/dist/chunk-Y7O6CMC7.js +517 -0
  63. package/dist/chunk-Y7O6CMC7.js.map +1 -0
  64. package/dist/{createTrueFoundryServer-CmZnBh_l.d.ts → createTrueFoundryServer-B_FYhSdn.d.ts} +8 -5
  65. package/dist/index.d.ts +377 -108
  66. package/dist/index.js +69 -488
  67. package/dist/index.js.map +1 -1
  68. package/dist/plugins/trueforge-agent-server-adapter/index.d.ts +49 -14
  69. package/dist/plugins/trueforge-agent-server-adapter/index.js +161 -60
  70. package/dist/plugins/trueforge-agent-server-adapter/index.js.map +1 -1
  71. package/dist/styles.css +1 -1
  72. package/package.json +5 -4
  73. package/dist/AgentCodeSnippets-NZOFJE57.js.map +0 -1
  74. package/dist/AgentMetricChart-JPU3MFQ2.js +0 -15
  75. package/dist/AgentOverview-EEBHJC32.js +0 -167
  76. package/dist/AgentOverview-EEBHJC32.js.map +0 -1
  77. package/dist/AgentSessionEventTimeline-26Z6IB3B.js.map +0 -1
  78. package/dist/AgentSessionEventTimelineChart-CGCU7WBK.js.map +0 -1
  79. package/dist/AgentSessions-3MPDZASK.js.map +0 -1
  80. package/dist/ConnectorSettings-MXFRWWR6.js.map +0 -1
  81. package/dist/DrawerLayout-JR3O6RRB.js.map +0 -1
  82. package/dist/ModelSettings-G7IFNC2Y.js.map +0 -1
  83. package/dist/OpenUiFenceBlock-2TV5TQ6P.js +0 -9
  84. package/dist/SandboxSettings-NXAANMAX.js.map +0 -1
  85. package/dist/SchedulesPage-KKLUDO6B.js +0 -15
  86. package/dist/ShellRouteSync-CEBETGEJ.js.map +0 -1
  87. package/dist/SidebarLayout-A2HJPPHS.js.map +0 -1
  88. package/dist/SkillSettings-FGGMSUNO.js.map +0 -1
  89. package/dist/chunk-2XPPBEYF.js +0 -74
  90. package/dist/chunk-2XPPBEYF.js.map +0 -1
  91. package/dist/chunk-6O6FWUDW.js.map +0 -1
  92. package/dist/chunk-7Z2C2K7F.js +0 -578
  93. package/dist/chunk-7Z2C2K7F.js.map +0 -1
  94. package/dist/chunk-CYHJDKFB.js.map +0 -1
  95. package/dist/chunk-DMMZSZTN.js.map +0 -1
  96. package/dist/chunk-FJW36PD7.js.map +0 -1
  97. package/dist/chunk-M62XY4NC.js.map +0 -1
  98. package/dist/chunk-QC42MLAK.js.map +0 -1
  99. package/dist/chunk-SFZNIO6U.js +0 -18
  100. package/dist/chunk-SFZNIO6U.js.map +0 -1
  101. package/dist/chunk-U7KURWW3.js.map +0 -1
  102. package/dist/chunk-WVE3F724.js.map +0 -1
  103. package/dist/chunk-XAU7QFG3.js.map +0 -1
  104. package/dist/chunk-ZKNUMH2M.js.map +0 -1
  105. package/dist/chunk-ZTMKFZQ3.js.map +0 -1
  106. /package/dist/{AgentMetricChart-JPU3MFQ2.js.map → AgentMetricChart-6RGWFMJE.js.map} +0 -0
  107. /package/dist/{DockLayout-LM4AFMFY.js.map → DockLayout-ACM7BVIH.js.map} +0 -0
  108. /package/dist/{OpenUiFenceBlock-2TV5TQ6P.js.map → OpenUiFenceBlock-MJTC2VJ5.js.map} +0 -0
  109. /package/dist/{SchedulesPage-KKLUDO6B.js.map → SchedulesPage-LHJ3U2VM.js.map} +0 -0
  110. /package/dist/{TrueForgeUIWithRouter-MZVJWJMB.js.map → TrueForgeUIWithRouter-GZUSRZIR.js.map} +0 -0
  111. /package/dist/{WidgetLayout-6QM45OQQ.js.map → WidgetLayout-2TM6I4LJ.js.map} +0 -0
  112. /package/dist/{chunk-MPNSO7E6.js.map → chunk-SLMFEG7X.js.map} +0 -0
@@ -1,10 +1,11 @@
1
1
  import {
2
+ getErrorMessage,
2
3
  useOptionalServer
3
- } from "./chunk-U7KURWW3.js";
4
+ } from "./chunk-2GIZY3JJ.js";
4
5
  import {
5
6
  ThemeContext,
6
7
  cn
7
- } from "./chunk-7Z2C2K7F.js";
8
+ } from "./chunk-GKXDRULM.js";
8
9
 
9
10
  // src/icons/Icon.tsx
10
11
  import { createElement, isValidElement, useContext } from "react";
@@ -26,6 +27,7 @@ import {
26
27
  ChevronDown,
27
28
  ChevronLeft,
28
29
  ChevronRight,
30
+ ChevronsUpDown,
29
31
  CircleAlert,
30
32
  CircleCheck,
31
33
  CircleX,
@@ -33,6 +35,7 @@ import {
33
35
  Code2,
34
36
  Copy,
35
37
  Cpu,
38
+ DollarSign,
36
39
  Download,
37
40
  Ellipsis,
38
41
  EllipsisVertical,
@@ -69,6 +72,8 @@ import {
69
72
  Save,
70
73
  Search,
71
74
  Settings,
75
+ Shield,
76
+ ShieldCheck,
72
77
  SlidersHorizontal,
73
78
  Sparkle,
74
79
  SquareArrowOutUpRight,
@@ -142,10 +147,12 @@ var defaults = {
142
147
  "chevron-down": ChevronDown,
143
148
  "chevron-left": ChevronLeft,
144
149
  "chevron-right": ChevronRight,
150
+ "chevrons-up-down": ChevronsUpDown,
145
151
  loader: Loader2,
146
152
  file: File,
147
153
  clone: Copy,
148
154
  copy: Copy,
155
+ "dollar-sign": DollarSign,
149
156
  bars: Menu,
150
157
  "panel-left-close": PanelLeftClose,
151
158
  "panel-left-open": PanelLeftOpen,
@@ -153,6 +160,8 @@ var defaults = {
153
160
  sun: Sun,
154
161
  moon: Moon,
155
162
  settings: Settings,
163
+ shield: Shield,
164
+ "shield-check": ShieldCheck,
156
165
  sliders: SlidersHorizontal,
157
166
  "log-out": LogOut,
158
167
  search: Search,
@@ -269,164 +278,30 @@ function Spinner({ size = 16, className, ...props }) {
269
278
 
270
279
  // src/atoms/lib/buttonClasses.ts
271
280
  var variantClasses = {
272
- default: "bg-primary-button-bg text-primary-button-text shadow hover:bg-primary-button-hover",
273
- secondary: "border border-input-border bg-secondary-button-bg text-secondary-button-text shadow-sm hover:bg-secondary-button-hover",
281
+ primary: "bg-primary-button-bg text-primary-button-text shadow hover:bg-primary-button-hover",
282
+ secondary: "border border-input-border bg-secondary-button-bg text-secondary-button-text hover:bg-secondary-button-hover",
274
283
  ghost: "bg-ghost-button-bg text-ghost-button-text hover:bg-ghost-button-hover",
275
- destructive: "bg-failure-bg text-failure-text shadow-sm hover:bg-failure-bg/90",
276
- outline: "border border-input-border bg-secondary-button-bg text-secondary-button-text shadow-sm hover:bg-secondary-button-hover"
284
+ destructive: "bg-failure-bg text-failure-text shadow-sm hover:bg-failure-bg/90"
277
285
  };
278
286
  var sizeClasses = {
279
- default: "h-9 px-4 py-2 text-sm",
280
- sm: "h-8 rounded-md px-2 text-xs",
281
- lg: "h-10 rounded-md px-8 text-base",
282
- icon: "h-8 w-8"
287
+ large: "h-8 gap-2 px-2.5 text-sm [&_svg]:size-3.5",
288
+ small: "h-6 gap-1 px-1.5 text-xs [&_svg]:size-3",
289
+ icon: "h-8 w-8 shrink-0 gap-0 p-0 [&_svg]:size-3.5"
283
290
  };
284
- var baseClasses = "inline-flex cursor-pointer items-center justify-center gap-1 whitespace-nowrap rounded-md font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-focus-ring disabled:cursor-not-allowed disabled:opacity-50";
291
+ var baseClasses = "inline-flex cursor-pointer items-center justify-center whitespace-nowrap rounded-md font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-focus-ring disabled:cursor-not-allowed disabled:opacity-50";
292
+ var sidebarButtonRadiusClassName = "rounded-[0.75rem]";
293
+ var sidebarRailButtonClassName = cn(
294
+ sidebarButtonRadiusClassName,
295
+ "h-[3.375rem] w-[4rem] shrink-0 flex-col gap-1 whitespace-normal px-0.5 text-[0.625rem] font-normal leading-tight !justify-center shadow-none hover:bg-secondary-button-hover hover:text-ghost-button-text [&_svg]:size-3.5"
296
+ );
285
297
  function auiButtonClass({
286
- variant = "default",
287
- size = "default",
298
+ variant = "primary",
299
+ size = "large",
288
300
  className
289
301
  } = {}) {
290
302
  return cn(baseClasses, variantClasses[variant], sizeClasses[size], className);
291
303
  }
292
304
 
293
- // src/utils/getErrorMessage.ts
294
- function isRecord(value) {
295
- return value != null && typeof value === "object";
296
- }
297
- function readNonEmptyString(value) {
298
- return typeof value === "string" && value.trim() !== "" ? value : void 0;
299
- }
300
- var LITERAL_ESCAPE_PATTERN = /\\(?:[nrtbfv0'"\\]|u[0-9a-fA-F]{4}|x[0-9a-fA-F]{2})/;
301
- var REAL_CONTROL_PATTERN = /[\n\t\b\f\v]/;
302
- function decodeLiteralEscapes(text) {
303
- let out = "";
304
- for (let i = 0; i < text.length; i += 1) {
305
- const char = text[i];
306
- if (char !== "\\" || i + 1 >= text.length) {
307
- out += char;
308
- continue;
309
- }
310
- const next = text[i + 1];
311
- switch (next) {
312
- case "n":
313
- out += "\n";
314
- i += 1;
315
- break;
316
- case "t":
317
- out += " ";
318
- i += 1;
319
- break;
320
- case "r":
321
- out += "\r";
322
- i += 1;
323
- break;
324
- case "b":
325
- out += "\b";
326
- i += 1;
327
- break;
328
- case "f":
329
- out += "\f";
330
- i += 1;
331
- break;
332
- case "v":
333
- out += "\v";
334
- i += 1;
335
- break;
336
- case "0":
337
- out += "\0";
338
- i += 1;
339
- break;
340
- case "\\":
341
- out += "\\";
342
- i += 1;
343
- break;
344
- case '"':
345
- out += '"';
346
- i += 1;
347
- break;
348
- case "'":
349
- out += "'";
350
- i += 1;
351
- break;
352
- case "u": {
353
- const hex = text.slice(i + 2, i + 6);
354
- if (/^[0-9a-fA-F]{4}$/.test(hex)) {
355
- out += String.fromCharCode(Number.parseInt(hex, 16));
356
- i += 5;
357
- } else {
358
- out += char;
359
- }
360
- break;
361
- }
362
- case "x": {
363
- const hex = text.slice(i + 2, i + 4);
364
- if (/^[0-9a-fA-F]{2}$/.test(hex)) {
365
- out += String.fromCharCode(Number.parseInt(hex, 16));
366
- i += 3;
367
- } else {
368
- out += char;
369
- }
370
- break;
371
- }
372
- default:
373
- out += char;
374
- break;
375
- }
376
- }
377
- return out;
378
- }
379
- function decodeErrorMessageEscapes(text) {
380
- const normalized = text.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
381
- if (REAL_CONTROL_PATTERN.test(normalized) || !LITERAL_ESCAPE_PATTERN.test(normalized)) {
382
- return normalized;
383
- }
384
- return decodeLiteralEscapes(normalized).replace(/\r\n/g, "\n").replace(/\r/g, "\n");
385
- }
386
- function messageFromErrorShaped(value) {
387
- if (!isRecord(value)) return void 0;
388
- const direct = readNonEmptyString(value.message);
389
- if (direct != null) return direct;
390
- if (isRecord(value.error)) {
391
- return readNonEmptyString(value.error.message);
392
- }
393
- return void 0;
394
- }
395
- function stringifyError(error) {
396
- if (typeof error === "string") return error;
397
- if (isRecord(error)) {
398
- try {
399
- return JSON.stringify(error);
400
- } catch {
401
- return Object.prototype.toString.call(error);
402
- }
403
- }
404
- return String(error);
405
- }
406
- function getErrorMessage(error, fallback) {
407
- if (typeof error === "string") {
408
- const trimmed = error.trim();
409
- if (trimmed !== "") return decodeErrorMessageEscapes(error);
410
- return fallback != null ? decodeErrorMessageEscapes(fallback) : decodeErrorMessageEscapes(error);
411
- }
412
- if (isRecord(error) && "body" in error) {
413
- const fromBody = messageFromErrorShaped(error.body);
414
- if (fromBody != null) return decodeErrorMessageEscapes(fromBody);
415
- if (error.body != null) {
416
- if (typeof error.body === "string") {
417
- const trimmed = error.body.trim();
418
- if (trimmed !== "") return decodeErrorMessageEscapes(error.body);
419
- } else {
420
- return stringifyError(error.body);
421
- }
422
- }
423
- }
424
- const fromShape = messageFromErrorShaped(error);
425
- if (fromShape != null) return decodeErrorMessageEscapes(fromShape);
426
- if (fallback != null) return decodeErrorMessageEscapes(fallback);
427
- return stringifyError(error);
428
- }
429
-
430
305
  // src/atoms/PageHeader.tsx
431
306
  import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
432
307
  var pageHeaderTitleClassName = "text-text-primary min-w-0 truncate text-md font-semibold";
@@ -434,10 +309,7 @@ function PageHeader({ title, start, end, children, className }) {
434
309
  return /* @__PURE__ */ jsxs2(
435
310
  "header",
436
311
  {
437
- className: cn(
438
- "flex min-h-14 shrink-0 flex-wrap items-center gap-2 border-b border-border px-4 md:px-6",
439
- className
440
- ),
312
+ className: cn("flex min-h-14 shrink-0 flex-wrap items-center gap-2 border-b border-border px-4", className),
441
313
  children: [
442
314
  start,
443
315
  typeof title === "string" ? /* @__PURE__ */ jsx4("h1", { className: pageHeaderTitleClassName, children: title }) : title,
@@ -460,33 +332,18 @@ function useCompactLayout() {
460
332
  }
461
333
 
462
334
  // src/atoms/draft/DraftCatalogProvider.tsx
463
- import { createContext as createContext2, useCallback, useContext as useContext3, useEffect, useMemo, useRef, useState } from "react";
335
+ import { createContext as createContext2, useCallback, useContext as useContext3, useEffect, useMemo, useState } from "react";
464
336
  import { jsx as jsx6 } from "react/jsx-runtime";
465
- var MCP_CONNECTORS_PAGE_SIZE = 50;
466
337
  var DraftCatalogContext = createContext2(null);
467
338
  var IDLE_ENSURE = () => void 0;
468
339
  var IDLE_REFRESH = async () => void 0;
469
- function appendConnectors({
470
- previous,
471
- next
472
- }) {
473
- if (next.length === 0) return previous;
474
- const seen = new Set(previous.map((connector) => connector.id));
475
- const appended = next.filter((connector) => !seen.has(connector.id));
476
- return appended.length === 0 ? previous : [...previous, ...appended];
477
- }
478
- async function fetchMcpPage({
479
- server,
480
- pageToken
481
- }) {
482
- if (server.listMcp != null) {
483
- return server.listMcp({
484
- limit: MCP_CONNECTORS_PAGE_SIZE,
485
- ...pageToken === void 0 ? {} : { pageToken }
486
- });
340
+ var EMPTY_LOGOS = {};
341
+ function toConnectorLogos(entries) {
342
+ const logos = {};
343
+ for (const entry of entries) {
344
+ if (entry.logo) logos[entry.name] = entry.logo;
487
345
  }
488
- const data = await server.getMcp();
489
- return { data };
346
+ return logos;
490
347
  }
491
348
  function DraftCatalogProvider({ children }) {
492
349
  const server = useOptionalServer();
@@ -501,99 +358,66 @@ function DraftCatalogStore({ server, children }) {
501
358
  const [models, setModels] = useState([]);
502
359
  const [skills, setSkills] = useState([]);
503
360
  const [connectors, setConnectors] = useState([]);
504
- const [connectorsNextPageToken, setConnectorsNextPageToken] = useState(void 0);
505
- const [connectorsLoadMoreFailed, setConnectorsLoadMoreFailed] = useState(false);
506
- const [connectorsLoadingMore, setConnectorsLoadingMore] = useState(false);
361
+ const [connectorLogos, setConnectorLogos] = useState(EMPTY_LOGOS);
507
362
  const [completedEpoch, setCompletedEpoch] = useState(null);
508
363
  const [loading, setLoading] = useState(false);
509
364
  const [error, setError] = useState(null);
510
- const connectorsNextPageTokenRef = useRef(connectorsNextPageToken);
511
- const connectorsLoadingMoreRef = useRef(connectorsLoadingMore);
512
- const loadMoreFailedRef = useRef(false);
513
- connectorsNextPageTokenRef.current = connectorsNextPageToken;
514
- connectorsLoadingMoreRef.current = connectorsLoadingMore;
515
365
  const ensureLoaded = useCallback(() => {
516
366
  setRequestEpoch((current) => current ?? 0);
517
367
  }, []);
518
368
  const refresh = useCallback(() => {
519
- loadMoreFailedRef.current = false;
520
- setConnectorsLoadMoreFailed(false);
521
369
  setRequestEpoch((current) => (current ?? -1) + 1);
522
370
  }, []);
523
371
  const refreshConnectors = useCallback(async () => {
524
372
  if (!server) return;
525
373
  setLoading(true);
526
374
  setError(null);
527
- loadMoreFailedRef.current = false;
528
- setConnectorsLoadMoreFailed(false);
529
375
  try {
530
- const page = await fetchMcpPage({ server });
531
- setConnectors(page.data);
532
- setConnectorsNextPageToken(page.nextPageToken);
376
+ setConnectors(await server.getMcp());
533
377
  } catch (reason) {
534
378
  setError(getErrorMessage(reason, "Failed to load connectors."));
535
379
  } finally {
536
380
  setLoading(false);
537
381
  }
538
382
  }, [server]);
539
- const loadMoreConnectors = useCallback(() => {
540
- if (!server) return;
541
- const pageToken = connectorsNextPageTokenRef.current;
542
- if (pageToken == null || pageToken.length === 0 || connectorsLoadingMoreRef.current) return;
543
- setConnectorsLoadMoreFailed(false);
544
- setConnectorsLoadingMore(true);
545
- void fetchMcpPage({ server, pageToken }).then((page) => {
546
- setConnectors((previous) => appendConnectors({ previous, next: page.data }));
547
- setConnectorsNextPageToken(page.nextPageToken);
548
- if (loadMoreFailedRef.current) {
549
- loadMoreFailedRef.current = false;
550
- setError(null);
551
- }
552
- }).catch((reason) => {
553
- loadMoreFailedRef.current = true;
554
- setConnectorsLoadMoreFailed(true);
555
- setError(getErrorMessage(reason, "Failed to load more connectors."));
556
- }).finally(() => {
557
- setConnectorsLoadingMore(false);
558
- });
559
- }, [server]);
560
383
  useEffect(() => {
561
384
  if (requestEpoch === null || !server) return;
562
385
  let cancelled = false;
563
386
  setLoading(true);
564
387
  setError(null);
565
- loadMoreFailedRef.current = false;
566
- setConnectorsLoadMoreFailed(false);
567
- void Promise.allSettled([server.getModels(), server.getSkills(), fetchMcpPage({ server })]).then(
568
- ([modelsResult, skillsResult, mcpResult]) => {
569
- if (cancelled) return;
570
- const errors = [];
571
- if (modelsResult.status === "fulfilled") {
572
- setModels(modelsResult.value);
573
- } else {
574
- errors.push(getErrorMessage(modelsResult.reason, "Failed to load models."));
575
- }
576
- if (skillsResult.status === "fulfilled") {
577
- setSkills(skillsResult.value);
578
- } else {
579
- errors.push(getErrorMessage(skillsResult.reason, "Failed to load skills."));
580
- }
581
- if (mcpResult.status === "fulfilled") {
582
- setConnectors(mcpResult.value.data);
583
- setConnectorsNextPageToken(mcpResult.value.nextPageToken);
584
- } else {
585
- errors.push(getErrorMessage(mcpResult.reason, "Failed to load connectors."));
586
- }
587
- setError(errors[0] ?? null);
588
- setCompletedEpoch(requestEpoch);
589
- setLoading(false);
388
+ const connectorCatalog = server.catalog?.connectorCatalog;
389
+ void Promise.allSettled([
390
+ server.getModels(),
391
+ server.getSkills(),
392
+ server.getMcp(),
393
+ connectorCatalog ? connectorCatalog.getConnectorCatalog() : Promise.resolve([])
394
+ ]).then(([modelsResult, skillsResult, mcpResult, catalogResult]) => {
395
+ if (cancelled) return;
396
+ setConnectorLogos(catalogResult.status === "fulfilled" ? toConnectorLogos(catalogResult.value) : EMPTY_LOGOS);
397
+ const errors = [];
398
+ if (modelsResult.status === "fulfilled") {
399
+ setModels(modelsResult.value);
400
+ } else {
401
+ errors.push(getErrorMessage(modelsResult.reason, "Failed to load models."));
402
+ }
403
+ if (skillsResult.status === "fulfilled") {
404
+ setSkills(skillsResult.value);
405
+ } else {
406
+ errors.push(getErrorMessage(skillsResult.reason, "Failed to load skills."));
590
407
  }
591
- );
408
+ if (mcpResult.status === "fulfilled") {
409
+ setConnectors(mcpResult.value);
410
+ } else {
411
+ errors.push(getErrorMessage(mcpResult.reason, "Failed to load connectors."));
412
+ }
413
+ setError(errors[0] ?? null);
414
+ setCompletedEpoch(requestEpoch);
415
+ setLoading(false);
416
+ });
592
417
  return () => {
593
418
  cancelled = true;
594
419
  };
595
420
  }, [requestEpoch, server]);
596
- const connectorsHasMore = connectorsNextPageToken != null && connectorsNextPageToken.length > 0;
597
421
  const loaded = requestEpoch !== null && completedEpoch === requestEpoch;
598
422
  const value = useMemo(
599
423
  () => ({
@@ -601,32 +425,26 @@ function DraftCatalogStore({ server, children }) {
601
425
  models,
602
426
  skills,
603
427
  connectors,
604
- connectorsHasMore,
605
- connectorsLoadMoreFailed,
606
- connectorsLoadingMore,
428
+ connectorLogos,
607
429
  loaded,
608
430
  loading,
609
431
  error,
610
432
  ensureLoaded,
611
433
  refresh,
612
- refreshConnectors,
613
- loadMoreConnectors
434
+ refreshConnectors
614
435
  }),
615
436
  [
616
437
  server,
617
438
  models,
618
439
  skills,
619
440
  connectors,
620
- connectorsHasMore,
621
- connectorsLoadMoreFailed,
622
- connectorsLoadingMore,
441
+ connectorLogos,
623
442
  loaded,
624
443
  loading,
625
444
  error,
626
445
  ensureLoaded,
627
446
  refresh,
628
- refreshConnectors,
629
- loadMoreConnectors
447
+ refreshConnectors
630
448
  ]
631
449
  );
632
450
  return /* @__PURE__ */ jsx6(DraftCatalogContext.Provider, { value, children });
@@ -638,16 +456,13 @@ function useDraftCatalog() {
638
456
  models: [],
639
457
  skills: [],
640
458
  connectors: [],
641
- connectorsHasMore: false,
642
- connectorsLoadMoreFailed: false,
643
- connectorsLoadingMore: false,
459
+ connectorLogos: EMPTY_LOGOS,
644
460
  loaded: false,
645
461
  loading: false,
646
462
  error: null,
647
463
  ensureLoaded: IDLE_ENSURE,
648
464
  refresh: IDLE_ENSURE,
649
- refreshConnectors: IDLE_REFRESH,
650
- loadMoreConnectors: IDLE_ENSURE
465
+ refreshConnectors: IDLE_REFRESH
651
466
  };
652
467
  }
653
468
  return ctx;
@@ -657,8 +472,9 @@ export {
657
472
  registerIcons,
658
473
  Icon,
659
474
  Spinner,
475
+ sidebarButtonRadiusClassName,
476
+ sidebarRailButtonClassName,
660
477
  auiButtonClass,
661
- getErrorMessage,
662
478
  pageHeaderTitleClassName,
663
479
  PageHeader,
664
480
  CompactLayoutProvider,
@@ -666,4 +482,4 @@ export {
666
482
  DraftCatalogProvider,
667
483
  useDraftCatalog
668
484
  };
669
- //# sourceMappingURL=chunk-XAU7QFG3.js.map
485
+ //# sourceMappingURL=chunk-5N5V7YLO.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/icons/Icon.tsx","../src/icons/IconRegistry.tsx","../src/atoms/primitives/Spinner.tsx","../src/atoms/lib/buttonClasses.ts","../src/atoms/PageHeader.tsx","../src/atoms/lib/CompactLayoutContext.tsx","../src/atoms/draft/DraftCatalogProvider.tsx"],"sourcesContent":["import { createElement, isValidElement, useContext, type CSSProperties, type ReactNode } from 'react';\n\nimport { cn } from '../atoms/lib/cn.js';\nimport { ThemeContext } from '../theme/ThemeProvider.js';\nimport type { IconComponent, IconEntry, IconProps as ThemeIconProps } from '../theme/types.js';\nimport { lookupIcon, resolveIconName } from './IconRegistry.js';\n\nexport type IconProps = ThemeIconProps & {\n name: string | readonly string[];\n};\n\ntype IconRenderProps = {\n className?: string;\n style?: CSSProperties;\n size?: string | number;\n width?: string | number;\n height?: string | number;\n role?: string;\n} & Pick<IconProps, 'aria-hidden' | 'aria-label' | 'data-testid'>;\n\nfunction isComponent(entry: IconEntry): entry is IconComponent {\n if (typeof entry === 'function') return true;\n // Lucide (and other) icons are forwardRef objects, not functions\n return (\n typeof entry === 'object' &&\n entry !== null &&\n !isValidElement(entry) &&\n !Array.isArray(entry) &&\n '$$typeof' in entry\n );\n}\n\nfunction renderEntry(entry: IconEntry, props: IconRenderProps): ReactNode {\n if (isComponent(entry)) {\n const { size, className, style, ...aria } = props;\n return createElement(entry, {\n className: cn('inline-block shrink-0', className),\n style,\n size,\n width: size,\n height: size,\n 'aria-hidden': aria['aria-label'] ? undefined : (aria['aria-hidden'] ?? true),\n 'aria-label': aria['aria-label'],\n ...(aria['data-testid'] === undefined ? {} : { 'data-testid': aria['data-testid'] }),\n role: aria['aria-label'] ? 'img' : undefined,\n });\n }\n return entry;\n}\n\nexport function Icon({ name, className, style, size = '1em', ...aria }: IconProps) {\n const themeIcons = useContext(ThemeContext)?.icons;\n const resolved = resolveIconName(name);\n const entry = lookupIcon(resolved, themeIcons);\n if (!entry) return null;\n return <>{renderEntry(entry, { className, style, size, ...aria })}</>;\n}\n\nexport function useIcon(name: string | readonly string[]): IconEntry | undefined {\n const themeIcons = useContext(ThemeContext)?.icons;\n return lookupIcon(resolveIconName(name), themeIcons);\n}\n","import {\n Archive,\n ArrowDown,\n ArrowLeft,\n ArrowUp,\n BookOpen,\n Bot,\n Box,\n Brain,\n Calendar,\n CalendarClock,\n CalendarPlus,\n Check,\n ChevronDown,\n ChevronLeft,\n ChevronRight,\n ChevronsUpDown,\n CircleAlert,\n CircleCheck,\n CircleX,\n Clock,\n Code2,\n Copy,\n Cpu,\n DollarSign,\n Download,\n Ellipsis,\n EllipsisVertical,\n ExternalLink,\n File,\n Github,\n GripVertical,\n History,\n Info,\n LibraryBig,\n Lightbulb,\n LineChart,\n Link2,\n ListChecks,\n ListFilter,\n ListOrdered,\n Loader2,\n Lock,\n LogOut,\n Maximize2,\n Menu,\n MessageSquareText,\n Minimize2,\n Moon,\n PanelLeftClose,\n PanelLeftOpen,\n Paperclip,\n Pause,\n Pencil,\n Play,\n Plug,\n Plus,\n RotateCw,\n Save,\n Search,\n Settings,\n Shield,\n ShieldCheck,\n SlidersHorizontal,\n Sparkle,\n SquareArrowOutUpRight,\n SquarePen,\n Sun,\n Terminal,\n Trash2,\n TriangleAlert,\n Wrench,\n X,\n} from 'lucide-react';\nimport type { SVGProps } from 'react';\n\nimport type { IconEntry, IconMap } from '../theme/types.js';\n\n/** Lucide `broom` (https://lucide.dev/icons/broom) — not in lucide-react 0.x. */\nfunction Broom({ size = 24, ...props }: SVGProps<SVGSVGElement> & { size?: string | number }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n {...props}\n >\n <path d=\"M13.5 10.5 22 2\" />\n <path d=\"M14.734 13.841a2 2 0 00-.314-2.42L12.58 9.58a2 2 0 00-2.421-.314l-7.657 4.461A1 1 0 002.3 15.3l6.403 6.403a1 1 0 001.571-.204z\" />\n <path d=\"m5 18 2-2\" />\n <path d=\"m7.699 10.7 5.602 5.601\" />\n </svg>\n );\n}\n\nconst registry = new Map<string, IconEntry>();\n\nexport function registerIcon(name: string, icon: IconEntry): void {\n registry.set(name, icon);\n}\n\nexport function registerIcons(icons: IconMap): void {\n for (const [name, icon] of Object.entries(icons)) {\n registry.set(name, icon);\n }\n}\n\nexport function getIcon(name: string): IconEntry | undefined {\n return registry.get(name);\n}\n\nexport function resolveIconName(icon: string | readonly string[]): string {\n if (typeof icon === 'string') return icon;\n // e.g. [\"far\", \"clone\"] → \"clone\"\n return icon[icon.length - 1] ?? '';\n}\n\nconst defaults: Record<string, IconEntry> = {\n paperclip: Paperclip,\n 'arrow-up': ArrowUp,\n 'arrow-down': ArrowDown,\n 'arrow-left': ArrowLeft,\n xmark: X,\n check: Check,\n pencil: Pencil,\n play: Play,\n pause: Pause,\n calendar: Calendar,\n 'calendar-clock': CalendarClock,\n 'calendar-plus': CalendarPlus,\n 'grip-vertical': GripVertical,\n 'square-pen': SquarePen,\n 'rotate-right': RotateCw,\n broom: Broom,\n ellipsis: Ellipsis,\n 'ellipsis-vertical': EllipsisVertical,\n trash: Trash2,\n 'box-archive': Archive,\n 'clock-rotate-left': History,\n 'circle-exclamation': CircleAlert,\n info: Info,\n 'triangle-exclamation': TriangleAlert,\n 'chevron-down': ChevronDown,\n 'chevron-left': ChevronLeft,\n 'chevron-right': ChevronRight,\n 'chevrons-up-down': ChevronsUpDown,\n loader: Loader2,\n file: File,\n clone: Copy,\n copy: Copy,\n 'dollar-sign': DollarSign,\n bars: Menu,\n 'panel-left-close': PanelLeftClose,\n 'panel-left-open': PanelLeftOpen,\n plus: Plus,\n sun: Sun,\n moon: Moon,\n settings: Settings,\n shield: Shield,\n 'shield-check': ShieldCheck,\n sliders: SlidersHorizontal,\n 'log-out': LogOut,\n search: Search,\n clock: Clock,\n 'circle-check': CircleCheck,\n 'circle-xmark': CircleX,\n 'oauth-success': CircleCheck,\n 'oauth-error': CircleX,\n 'oauth-loading': Loader2,\n 'welcome-sparkle': Sparkle,\n robot: Bot,\n bot: Bot,\n 'library-big': LibraryBig,\n 'message-square-text': MessageSquareText,\n 'book-open': BookOpen,\n funnel: ListFilter,\n plug: Plug,\n 'list-check': ListChecks,\n lock: Lock,\n lightbulb: Lightbulb,\n link: Link2,\n wrench: Wrench,\n cpu: Cpu,\n cube: Box,\n 'list-ol': ListOrdered,\n download: Download,\n save: Save,\n brain: Brain,\n terminal: Terminal,\n code: Code2,\n chart: LineChart,\n expand: Maximize2,\n 'expand-alt': Maximize2,\n compress: Minimize2,\n 'external-link': ExternalLink,\n 'square-arrow-out-up-right': SquareArrowOutUpRight,\n github: Github,\n};\n\nfor (const [name, icon] of Object.entries(defaults)) {\n registry.set(name, icon);\n}\n\n/** Merge host `theme.icons` over the registry for a single lookup (does not mutate). */\nexport function lookupIcon(name: string, themeIcons?: IconMap): IconEntry | undefined {\n if (themeIcons && name in themeIcons) {\n return themeIcons[name];\n }\n return registry.get(name);\n}\n","import React from 'react';\n\nimport { cn } from '../lib/cn.js';\n\nexport type SpinnerProps = React.SVGProps<SVGSVGElement> & {\n size?: number;\n};\n\nexport function Spinner({ size = 16, className, ...props }: SpinnerProps) {\n const r = (size / 2) * 0.75;\n const cx = size / 2;\n const circumference = 2 * Math.PI * r;\n\n return (\n <svg\n role=\"status\"\n aria-label=\"Loading\"\n width={size}\n height={size}\n viewBox={`0 0 ${size} ${size}`}\n fill=\"none\"\n className={cn('animate-spin', className)}\n {...props}\n >\n <circle\n cx={cx}\n cy={cx}\n r={r}\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n strokeDasharray={`${circumference * 0.75} ${circumference * 0.25}`}\n opacity={0.8}\n />\n </svg>\n );\n}\n","import { cn } from './cn.js';\n\nexport type AuiButtonVariant = 'primary' | 'secondary' | 'ghost' | 'destructive';\nexport type AuiButtonSize = 'large' | 'small' | 'icon';\n\nconst variantClasses: Record<AuiButtonVariant, string> = {\n primary: 'bg-primary-button-bg text-primary-button-text shadow hover:bg-primary-button-hover',\n secondary:\n 'border border-input-border bg-secondary-button-bg text-secondary-button-text hover:bg-secondary-button-hover',\n ghost: 'bg-ghost-button-bg text-ghost-button-text hover:bg-ghost-button-hover',\n destructive: 'bg-failure-bg text-failure-text shadow-sm hover:bg-failure-bg/90',\n};\n\n/** Glyph sizes match the shared design-system Button (`iconSizeMap`: large 0.875rem, small 0.75rem). */\nconst sizeClasses: Record<AuiButtonSize, string> = {\n large: 'h-8 gap-2 px-2.5 text-sm [&_svg]:size-3.5',\n small: 'h-6 gap-1 px-1.5 text-xs [&_svg]:size-3',\n icon: 'h-8 w-8 shrink-0 gap-0 p-0 [&_svg]:size-3.5',\n};\n\nconst baseClasses =\n 'inline-flex cursor-pointer items-center justify-center whitespace-nowrap rounded-md font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-focus-ring disabled:cursor-not-allowed disabled:opacity-50';\n\n/** Sidebar / rail nav control corner radius: 12px. */\nexport const sidebarButtonRadiusClassName = 'rounded-[0.75rem]';\n\n/** Compact sidebar rail control: 66×54px → 4.125rem × 3.375rem. */\nexport const sidebarRailButtonClassName = cn(\n sidebarButtonRadiusClassName,\n 'h-[3.375rem] w-[4rem] shrink-0 flex-col gap-1 whitespace-normal px-0.5 text-[0.625rem] font-normal leading-tight !justify-center shadow-none hover:bg-secondary-button-hover hover:text-ghost-button-text [&_svg]:size-3.5',\n);\n\n/** Shared Button / native `<button>` className helper (SDK utilities are layered). */\nexport function auiButtonClass({\n variant = 'primary',\n size = 'large',\n className,\n}: {\n variant?: AuiButtonVariant;\n size?: AuiButtonSize;\n className?: string;\n} = {}): string {\n return cn(baseClasses, variantClasses[variant], sizeClasses[size], className);\n}\n","'use client';\n\nimport type { ReactNode } from 'react';\n\nimport { cn } from './lib/cn.js';\n\n/** Shared title styles for page / chat chrome headers. */\nexport const pageHeaderTitleClassName = 'text-text-primary min-w-0 truncate text-md font-semibold';\n\nexport type PageHeaderProps = {\n /** Page name, or a custom title node (e.g. `NamedAgentHeaderLabel`). Strings use the shared h1 styles. */\n title?: ReactNode;\n /** Leading chrome (back / menu). */\n start?: ReactNode;\n /** Trailing actions; pushed to the end. */\n end?: ReactNode;\n /** Extra content between title and end (prefer `start` / `end` when possible). */\n children?: ReactNode;\n className?: string;\n};\n\n/** Shared shell/page header bar used by chat chrome and list pages.\n * `min-h-14` keeps a single-row bar aligned with Agent Config; wrapping end actions can grow the bar.\n */\nexport function PageHeader({ title, start, end, children, className }: PageHeaderProps) {\n return (\n <header\n className={cn('flex min-h-14 shrink-0 flex-wrap items-center gap-2 border-b border-border px-4', className)}\n >\n {start}\n {typeof title === 'string' ? <h1 className={pageHeaderTitleClassName}>{title}</h1> : title}\n {children}\n {end != null ? <div className=\"ml-auto flex min-w-0 flex-wrap items-center gap-2\">{end}</div> : null}\n </header>\n );\n}\n","'use client';\n\nimport { createContext, useContext, type ReactNode } from 'react';\n\nconst CompactLayoutContext = createContext(false);\n\nexport function CompactLayoutProvider({ children }: { children: ReactNode }) {\n return <CompactLayoutContext.Provider value>{children}</CompactLayoutContext.Provider>;\n}\n\nexport function useCompactLayout() {\n return useContext(CompactLayoutContext);\n}\n","'use client';\n\nimport { createContext, useCallback, useContext, useEffect, useMemo, useState, type ReactNode } from 'react';\n\nimport { useOptionalServer } from '../../server/ServerContext.js';\nimport type {\n AgentSkill,\n AgentUIServer,\n ConnectorCatalogEntry,\n ConnectorState,\n ModelSelection,\n} from '../../server/types.js';\nimport { getErrorMessage } from '../../utils/getErrorMessage.js';\n\ntype DraftCatalogValue = {\n models: ModelSelection[];\n skills: AgentSkill[];\n connectors: ConnectorState[];\n /** Connector logo URL keyed by connector name, sourced from the discovery catalog. */\n connectorLogos: Record<string, string>;\n loaded: boolean;\n loading: boolean;\n error: string | null;\n /** Kick off catalog fetch (idempotent). Call when a picker opens. */\n ensureLoaded: () => void;\n /** Reload all collections after settings mutate catalog-backed configuration. */\n refresh: () => void;\n /** Refresh connector auth state without reloading unrelated catalogs. */\n refreshConnectors: () => Promise<void>;\n};\n\ntype DraftCatalogContextValue = DraftCatalogValue & {\n server: AgentUIServer | null;\n};\n\nconst DraftCatalogContext = createContext<DraftCatalogContextValue | null>(null);\n\nconst IDLE_ENSURE = () => undefined;\nconst IDLE_REFRESH = async () => undefined;\nconst EMPTY_LOGOS: Record<string, string> = {};\n\nfunction toConnectorLogos(entries: ConnectorCatalogEntry[]): Record<string, string> {\n const logos: Record<string, string> = {};\n for (const entry of entries) {\n if (entry.logo) logos[entry.name] = entry.logo;\n }\n return logos;\n}\n\nexport function DraftCatalogProvider({ children }: { children: ReactNode }) {\n const server = useOptionalServer();\n const existing = useContext(DraftCatalogContext);\n if (existing?.server === server) {\n return children;\n }\n return <DraftCatalogStore server={server}>{children}</DraftCatalogStore>;\n}\n\nfunction DraftCatalogStore({ server, children }: { server: AgentUIServer | null; children: ReactNode }) {\n const [requestEpoch, setRequestEpoch] = useState<number | null>(null);\n const [models, setModels] = useState<ModelSelection[]>([]);\n const [skills, setSkills] = useState<AgentSkill[]>([]);\n const [connectors, setConnectors] = useState<ConnectorState[]>([]);\n const [connectorLogos, setConnectorLogos] = useState<Record<string, string>>(EMPTY_LOGOS);\n const [completedEpoch, setCompletedEpoch] = useState<number | null>(null);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n const ensureLoaded = useCallback(() => {\n setRequestEpoch(current => current ?? 0);\n }, []);\n\n const refresh = useCallback(() => {\n setRequestEpoch(current => (current ?? -1) + 1);\n }, []);\n\n const refreshConnectors = useCallback(async () => {\n if (!server) return;\n setLoading(true);\n setError(null);\n try {\n setConnectors(await server.getMcp());\n } catch (reason: unknown) {\n setError(getErrorMessage(reason, 'Failed to load connectors.'));\n } finally {\n setLoading(false);\n }\n }, [server]);\n\n useEffect(() => {\n if (requestEpoch === null || !server) return;\n let cancelled = false;\n setLoading(true);\n setError(null);\n // Settle each list alone so one failing picker does not blank the others.\n // Logos are cosmetic: a missing catalog port or a failed fetch just falls back to icons.\n const connectorCatalog = server.catalog?.connectorCatalog;\n void Promise.allSettled([\n server.getModels(),\n server.getSkills(),\n server.getMcp(),\n connectorCatalog ? connectorCatalog.getConnectorCatalog() : Promise.resolve([]),\n ]).then(([modelsResult, skillsResult, mcpResult, catalogResult]) => {\n if (cancelled) return;\n setConnectorLogos(catalogResult.status === 'fulfilled' ? toConnectorLogos(catalogResult.value) : EMPTY_LOGOS);\n const errors: string[] = [];\n if (modelsResult.status === 'fulfilled') {\n setModels(modelsResult.value);\n } else {\n errors.push(getErrorMessage(modelsResult.reason, 'Failed to load models.'));\n }\n if (skillsResult.status === 'fulfilled') {\n setSkills(skillsResult.value);\n } else {\n errors.push(getErrorMessage(skillsResult.reason, 'Failed to load skills.'));\n }\n if (mcpResult.status === 'fulfilled') {\n setConnectors(mcpResult.value);\n } else {\n errors.push(getErrorMessage(mcpResult.reason, 'Failed to load connectors.'));\n }\n setError(errors[0] ?? null);\n setCompletedEpoch(requestEpoch);\n setLoading(false);\n });\n return () => {\n cancelled = true;\n };\n }, [requestEpoch, server]);\n\n const loaded = requestEpoch !== null && completedEpoch === requestEpoch;\n const value = useMemo(\n () => ({\n server,\n models,\n skills,\n connectors,\n connectorLogos,\n loaded,\n loading,\n error,\n ensureLoaded,\n refresh,\n refreshConnectors,\n }),\n [\n server,\n models,\n skills,\n connectors,\n connectorLogos,\n loaded,\n loading,\n error,\n ensureLoaded,\n refresh,\n refreshConnectors,\n ],\n );\n\n return <DraftCatalogContext.Provider value={value}>{children}</DraftCatalogContext.Provider>;\n}\n\nexport function useDraftCatalog(): DraftCatalogValue {\n const ctx = useContext(DraftCatalogContext);\n if (ctx == null) {\n return {\n models: [],\n skills: [],\n connectors: [],\n connectorLogos: EMPTY_LOGOS,\n loaded: false,\n loading: false,\n error: null,\n ensureLoaded: IDLE_ENSURE,\n refresh: IDLE_ENSURE,\n refreshConnectors: IDLE_REFRESH,\n };\n }\n return ctx;\n}\n"],"mappings":"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","names":["jsx","jsx","jsx","jsxs","useContext","jsx","createContext","useContext","jsx","createContext","useContext"]}