@truefoundry/trueforge-ui 0.3.0-rc.2 → 0.3.0-rc.3

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 (107) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/README.md +17 -9
  3. package/dist/{AgentCodeSnippets-637HQUXD.js → AgentCodeSnippets-N546FNNS.js} +38 -23
  4. package/dist/AgentCodeSnippets-N546FNNS.js.map +1 -0
  5. package/dist/AgentMetricChart-YWJYVYYA.js +15 -0
  6. package/dist/{AgentOverview-3FJ5EE6N.js → AgentOverview-VF74XC7I.js} +7 -7
  7. package/dist/{AgentSessionEventTimeline-VELWUYPR.js → AgentSessionEventTimeline-RFR6LQMY.js} +8 -8
  8. package/dist/{AgentSessionEventTimeline-VELWUYPR.js.map → AgentSessionEventTimeline-RFR6LQMY.js.map} +1 -1
  9. package/dist/{AgentSessionEventTimelineChart-CUKETHWM.js → AgentSessionEventTimelineChart-27CQF6FX.js} +12 -12
  10. package/dist/AgentSessionEventTimelineChart-27CQF6FX.js.map +1 -0
  11. package/dist/{AgentSessions-T7MOGOTZ.js → AgentSessions-4IVX2SGD.js} +36 -12
  12. package/dist/AgentSessions-4IVX2SGD.js.map +1 -0
  13. package/dist/{ConnectorSettings-ESZ2RSRG.js → ConnectorSettings-R5VEP7BO.js} +156 -116
  14. package/dist/ConnectorSettings-R5VEP7BO.js.map +1 -0
  15. package/dist/{DockLayout-NLFNU6F2.js → DockLayout-F44RWGEY.js} +10 -10
  16. package/dist/{DrawerLayout-PR3SMKA6.js → DrawerLayout-SQ323AVM.js} +13 -11
  17. package/dist/DrawerLayout-SQ323AVM.js.map +1 -0
  18. package/dist/{ModelSettings-LYW64IRR.js → ModelSettings-6QLS63HM.js} +10 -10
  19. package/dist/{ModelSettings-LYW64IRR.js.map → ModelSettings-6QLS63HM.js.map} +1 -1
  20. package/dist/OpenUiFenceBlock-4ROX3G4X.js +9 -0
  21. package/dist/{SandboxSettings-DF64LHYI.js → SandboxSettings-OLKDXIQS.js} +9 -9
  22. package/dist/SchedulesPage-TMOTK6DR.js +15 -0
  23. package/dist/{SettingsBuilder-LSXK2VN4.js → SettingsBuilder-GISAH2WU.js} +8 -8
  24. package/dist/{ShellRouteSync-B22IAV2W.js → ShellRouteSync-EN33DUQ7.js} +157 -22
  25. package/dist/ShellRouteSync-EN33DUQ7.js.map +1 -0
  26. package/dist/{SidebarLayout-XW6LXB7R.js → SidebarLayout-35K4AKTC.js} +74 -53
  27. package/dist/SidebarLayout-35K4AKTC.js.map +1 -0
  28. package/dist/{SkillSettings-64VXUO6J.js → SkillSettings-JSX2BTII.js} +18 -13
  29. package/dist/SkillSettings-JSX2BTII.js.map +1 -0
  30. package/dist/{TrueForgeUIWithRouter-3TSLV22Q.js → TrueForgeUIWithRouter-6VCR7ES3.js} +9 -9
  31. package/dist/{WidgetLayout-Q5P7PYSJ.js → WidgetLayout-RKBSN2FZ.js} +10 -10
  32. package/dist/{chunk-YQO2NMJ3.js → chunk-2O5EJ6QS.js} +4096 -2825
  33. package/dist/chunk-2O5EJ6QS.js.map +1 -0
  34. package/dist/chunk-6WCIL3H2.js +517 -0
  35. package/dist/chunk-6WCIL3H2.js.map +1 -0
  36. package/dist/{chunk-SQGT43Z3.js → chunk-73FQVITT.js} +21 -4
  37. package/dist/chunk-73FQVITT.js.map +1 -0
  38. package/dist/{chunk-QC42MLAK.js → chunk-7AAO4UDQ.js} +4 -3
  39. package/dist/chunk-7AAO4UDQ.js.map +1 -0
  40. package/dist/{chunk-LGRHHFHN.js → chunk-F5QVQIBH.js} +166 -45
  41. package/dist/chunk-F5QVQIBH.js.map +1 -0
  42. package/dist/{chunk-I3AL54MA.js → chunk-GIPFF6FZ.js} +28 -24
  43. package/dist/chunk-GIPFF6FZ.js.map +1 -0
  44. package/dist/{chunk-GXYAOAK5.js → chunk-GSJAYYLR.js} +219 -162
  45. package/dist/chunk-GSJAYYLR.js.map +1 -0
  46. package/dist/{chunk-VJ7BZGAF.js → chunk-J5BPHEDT.js} +2 -2
  47. package/dist/chunk-KR7WYHVF.js +195 -0
  48. package/dist/chunk-KR7WYHVF.js.map +1 -0
  49. package/dist/{chunk-VUMGMGKZ.js → chunk-LUG7E6BL.js} +52 -8
  50. package/dist/chunk-LUG7E6BL.js.map +1 -0
  51. package/dist/chunk-LXJMINS6.js +587 -0
  52. package/dist/chunk-LXJMINS6.js.map +1 -0
  53. package/dist/{chunk-FQK2XVVE.js → chunk-PT4EENB3.js} +224 -72
  54. package/dist/chunk-PT4EENB3.js.map +1 -0
  55. package/dist/{chunk-H6WTY5PM.js → chunk-Q6TCT7ZJ.js} +17 -227
  56. package/dist/chunk-Q6TCT7ZJ.js.map +1 -0
  57. package/dist/{chunk-5I2COQNL.js → chunk-XLFOXQKZ.js} +13 -11
  58. package/dist/chunk-XLFOXQKZ.js.map +1 -0
  59. package/dist/{chunk-G2TUAD65.js → chunk-XY6LZQES.js} +235 -108
  60. package/dist/chunk-XY6LZQES.js.map +1 -0
  61. package/dist/{createTrueFoundryServer-CmZnBh_l.d.ts → createTrueFoundryServer-B_FYhSdn.d.ts} +8 -5
  62. package/dist/index.d.ts +291 -89
  63. package/dist/index.js +63 -488
  64. package/dist/index.js.map +1 -1
  65. package/dist/plugins/trueforge-agent-server-adapter/index.d.ts +36 -13
  66. package/dist/plugins/trueforge-agent-server-adapter/index.js +69 -35
  67. package/dist/plugins/trueforge-agent-server-adapter/index.js.map +1 -1
  68. package/dist/styles.css +1 -1
  69. package/package.json +3 -3
  70. package/dist/AgentCodeSnippets-637HQUXD.js.map +0 -1
  71. package/dist/AgentMetricChart-4FYECRIN.js +0 -15
  72. package/dist/AgentSessionEventTimelineChart-CUKETHWM.js.map +0 -1
  73. package/dist/AgentSessions-T7MOGOTZ.js.map +0 -1
  74. package/dist/ConnectorSettings-ESZ2RSRG.js.map +0 -1
  75. package/dist/DrawerLayout-PR3SMKA6.js.map +0 -1
  76. package/dist/OpenUiFenceBlock-JEPNPJ7U.js +0 -9
  77. package/dist/SchedulesPage-WQU4H25F.js +0 -15
  78. package/dist/ShellRouteSync-B22IAV2W.js.map +0 -1
  79. package/dist/SidebarLayout-XW6LXB7R.js.map +0 -1
  80. package/dist/SkillSettings-64VXUO6J.js.map +0 -1
  81. package/dist/chunk-5I2COQNL.js.map +0 -1
  82. package/dist/chunk-BWHOZFIV.js +0 -587
  83. package/dist/chunk-BWHOZFIV.js.map +0 -1
  84. package/dist/chunk-FQK2XVVE.js.map +0 -1
  85. package/dist/chunk-G2TUAD65.js.map +0 -1
  86. package/dist/chunk-GXYAOAK5.js.map +0 -1
  87. package/dist/chunk-H6WTY5PM.js.map +0 -1
  88. package/dist/chunk-I3AL54MA.js.map +0 -1
  89. package/dist/chunk-LGRHHFHN.js.map +0 -1
  90. package/dist/chunk-NHHSZB5N.js +0 -74
  91. package/dist/chunk-NHHSZB5N.js.map +0 -1
  92. package/dist/chunk-QC42MLAK.js.map +0 -1
  93. package/dist/chunk-SFZNIO6U.js +0 -18
  94. package/dist/chunk-SFZNIO6U.js.map +0 -1
  95. package/dist/chunk-SQGT43Z3.js.map +0 -1
  96. package/dist/chunk-VUMGMGKZ.js.map +0 -1
  97. package/dist/chunk-YQO2NMJ3.js.map +0 -1
  98. /package/dist/{AgentMetricChart-4FYECRIN.js.map → AgentMetricChart-YWJYVYYA.js.map} +0 -0
  99. /package/dist/{AgentOverview-3FJ5EE6N.js.map → AgentOverview-VF74XC7I.js.map} +0 -0
  100. /package/dist/{DockLayout-NLFNU6F2.js.map → DockLayout-F44RWGEY.js.map} +0 -0
  101. /package/dist/{OpenUiFenceBlock-JEPNPJ7U.js.map → OpenUiFenceBlock-4ROX3G4X.js.map} +0 -0
  102. /package/dist/{SandboxSettings-DF64LHYI.js.map → SandboxSettings-OLKDXIQS.js.map} +0 -0
  103. /package/dist/{SchedulesPage-WQU4H25F.js.map → SchedulesPage-TMOTK6DR.js.map} +0 -0
  104. /package/dist/{SettingsBuilder-LSXK2VN4.js.map → SettingsBuilder-GISAH2WU.js.map} +0 -0
  105. /package/dist/{TrueForgeUIWithRouter-3TSLV22Q.js.map → TrueForgeUIWithRouter-6VCR7ES3.js.map} +0 -0
  106. /package/dist/{WidgetLayout-Q5P7PYSJ.js.map → WidgetLayout-RKBSN2FZ.js.map} +0 -0
  107. /package/dist/{chunk-VJ7BZGAF.js.map → chunk-J5BPHEDT.js.map} +0 -0
@@ -1,10 +1,11 @@
1
1
  import {
2
+ getErrorMessage,
2
3
  useOptionalServer
3
- } from "./chunk-FQK2XVVE.js";
4
+ } from "./chunk-PT4EENB3.js";
4
5
  import {
5
6
  ThemeContext,
6
7
  cn
7
- } from "./chunk-BWHOZFIV.js";
8
+ } from "./chunk-LXJMINS6.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,
@@ -142,10 +145,12 @@ var defaults = {
142
145
  "chevron-down": ChevronDown,
143
146
  "chevron-left": ChevronLeft,
144
147
  "chevron-right": ChevronRight,
148
+ "chevrons-up-down": ChevronsUpDown,
145
149
  loader: Loader2,
146
150
  file: File,
147
151
  clone: Copy,
148
152
  copy: Copy,
153
+ "dollar-sign": DollarSign,
149
154
  bars: Menu,
150
155
  "panel-left-close": PanelLeftClose,
151
156
  "panel-left-open": PanelLeftOpen,
@@ -283,7 +288,7 @@ var baseClasses = "inline-flex cursor-pointer items-center justify-center whites
283
288
  var sidebarButtonRadiusClassName = "rounded-[0.75rem]";
284
289
  var sidebarRailButtonClassName = cn(
285
290
  sidebarButtonRadiusClassName,
286
- "h-[3.375rem] w-[3.625rem] 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"
291
+ "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"
287
292
  );
288
293
  function auiButtonClass({
289
294
  variant = "primary",
@@ -293,143 +298,6 @@ function auiButtonClass({
293
298
  return cn(baseClasses, variantClasses[variant], sizeClasses[size], className);
294
299
  }
295
300
 
296
- // src/utils/getErrorMessage.ts
297
- function isRecord(value) {
298
- return value != null && typeof value === "object";
299
- }
300
- function readNonEmptyString(value) {
301
- return typeof value === "string" && value.trim() !== "" ? value : void 0;
302
- }
303
- var LITERAL_ESCAPE_PATTERN = /\\(?:[nrtbfv0'"\\]|u[0-9a-fA-F]{4}|x[0-9a-fA-F]{2})/;
304
- var REAL_CONTROL_PATTERN = /[\n\t\b\f\v]/;
305
- function decodeLiteralEscapes(text) {
306
- let out = "";
307
- for (let i = 0; i < text.length; i += 1) {
308
- const char = text[i];
309
- if (char !== "\\" || i + 1 >= text.length) {
310
- out += char;
311
- continue;
312
- }
313
- const next = text[i + 1];
314
- switch (next) {
315
- case "n":
316
- out += "\n";
317
- i += 1;
318
- break;
319
- case "t":
320
- out += " ";
321
- i += 1;
322
- break;
323
- case "r":
324
- out += "\r";
325
- i += 1;
326
- break;
327
- case "b":
328
- out += "\b";
329
- i += 1;
330
- break;
331
- case "f":
332
- out += "\f";
333
- i += 1;
334
- break;
335
- case "v":
336
- out += "\v";
337
- i += 1;
338
- break;
339
- case "0":
340
- out += "\0";
341
- i += 1;
342
- break;
343
- case "\\":
344
- out += "\\";
345
- i += 1;
346
- break;
347
- case '"':
348
- out += '"';
349
- i += 1;
350
- break;
351
- case "'":
352
- out += "'";
353
- i += 1;
354
- break;
355
- case "u": {
356
- const hex = text.slice(i + 2, i + 6);
357
- if (/^[0-9a-fA-F]{4}$/.test(hex)) {
358
- out += String.fromCharCode(Number.parseInt(hex, 16));
359
- i += 5;
360
- } else {
361
- out += char;
362
- }
363
- break;
364
- }
365
- case "x": {
366
- const hex = text.slice(i + 2, i + 4);
367
- if (/^[0-9a-fA-F]{2}$/.test(hex)) {
368
- out += String.fromCharCode(Number.parseInt(hex, 16));
369
- i += 3;
370
- } else {
371
- out += char;
372
- }
373
- break;
374
- }
375
- default:
376
- out += char;
377
- break;
378
- }
379
- }
380
- return out;
381
- }
382
- function decodeErrorMessageEscapes(text) {
383
- const normalized = text.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
384
- if (REAL_CONTROL_PATTERN.test(normalized) || !LITERAL_ESCAPE_PATTERN.test(normalized)) {
385
- return normalized;
386
- }
387
- return decodeLiteralEscapes(normalized).replace(/\r\n/g, "\n").replace(/\r/g, "\n");
388
- }
389
- function messageFromErrorShaped(value) {
390
- if (!isRecord(value)) return void 0;
391
- const direct = readNonEmptyString(value.message);
392
- if (direct != null) return direct;
393
- if (isRecord(value.error)) {
394
- return readNonEmptyString(value.error.message);
395
- }
396
- return void 0;
397
- }
398
- function stringifyError(error) {
399
- if (typeof error === "string") return error;
400
- if (isRecord(error)) {
401
- try {
402
- return JSON.stringify(error);
403
- } catch {
404
- return Object.prototype.toString.call(error);
405
- }
406
- }
407
- return String(error);
408
- }
409
- function getErrorMessage(error, fallback) {
410
- if (typeof error === "string") {
411
- const trimmed = error.trim();
412
- if (trimmed !== "") return decodeErrorMessageEscapes(error);
413
- return fallback != null ? decodeErrorMessageEscapes(fallback) : decodeErrorMessageEscapes(error);
414
- }
415
- if (isRecord(error) && "body" in error) {
416
- const fromBody = messageFromErrorShaped(error.body);
417
- if (fromBody != null) return decodeErrorMessageEscapes(fromBody);
418
- if (error.body != null) {
419
- if (typeof error.body === "string") {
420
- const trimmed = error.body.trim();
421
- if (trimmed !== "") return decodeErrorMessageEscapes(error.body);
422
- } else {
423
- return stringifyError(error.body);
424
- }
425
- }
426
- }
427
- const fromShape = messageFromErrorShaped(error);
428
- if (fromShape != null) return decodeErrorMessageEscapes(fromShape);
429
- if (fallback != null) return decodeErrorMessageEscapes(fallback);
430
- return stringifyError(error);
431
- }
432
-
433
301
  // src/atoms/PageHeader.tsx
434
302
  import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
435
303
  var pageHeaderTitleClassName = "text-text-primary min-w-0 truncate text-md font-semibold";
@@ -437,10 +305,7 @@ function PageHeader({ title, start, end, children, className }) {
437
305
  return /* @__PURE__ */ jsxs2(
438
306
  "header",
439
307
  {
440
- className: cn(
441
- "flex min-h-14 shrink-0 flex-wrap items-center gap-2 border-b border-border px-4 md:px-6",
442
- className
443
- ),
308
+ className: cn("flex min-h-14 shrink-0 flex-wrap items-center gap-2 border-b border-border px-4", className),
444
309
  children: [
445
310
  start,
446
311
  typeof title === "string" ? /* @__PURE__ */ jsx4("h1", { className: pageHeaderTitleClassName, children: title }) : title,
@@ -463,9 +328,8 @@ function useCompactLayout() {
463
328
  }
464
329
 
465
330
  // src/atoms/draft/DraftCatalogProvider.tsx
466
- import { createContext as createContext2, useCallback, useContext as useContext3, useEffect, useMemo, useRef, useState } from "react";
331
+ import { createContext as createContext2, useCallback, useContext as useContext3, useEffect, useMemo, useState } from "react";
467
332
  import { jsx as jsx6 } from "react/jsx-runtime";
468
- var MCP_CONNECTORS_PAGE_SIZE = 50;
469
333
  var DraftCatalogContext = createContext2(null);
470
334
  var IDLE_ENSURE = () => void 0;
471
335
  var IDLE_REFRESH = async () => void 0;
@@ -477,28 +341,6 @@ function toConnectorLogos(entries) {
477
341
  }
478
342
  return logos;
479
343
  }
480
- function appendConnectors({
481
- previous,
482
- next
483
- }) {
484
- if (next.length === 0) return previous;
485
- const seen = new Set(previous.map((connector) => connector.id));
486
- const appended = next.filter((connector) => !seen.has(connector.id));
487
- return appended.length === 0 ? previous : [...previous, ...appended];
488
- }
489
- async function fetchMcpPage({
490
- server,
491
- pageToken
492
- }) {
493
- if (server.listMcp != null) {
494
- return server.listMcp({
495
- limit: MCP_CONNECTORS_PAGE_SIZE,
496
- ...pageToken === void 0 ? {} : { pageToken }
497
- });
498
- }
499
- const data = await server.getMcp();
500
- return { data };
501
- }
502
344
  function DraftCatalogProvider({ children }) {
503
345
  const server = useOptionalServer();
504
346
  const existing = useContext3(DraftCatalogContext);
@@ -513,74 +355,37 @@ function DraftCatalogStore({ server, children }) {
513
355
  const [skills, setSkills] = useState([]);
514
356
  const [connectors, setConnectors] = useState([]);
515
357
  const [connectorLogos, setConnectorLogos] = useState(EMPTY_LOGOS);
516
- const [connectorsNextPageToken, setConnectorsNextPageToken] = useState(void 0);
517
- const [connectorsLoadMoreFailed, setConnectorsLoadMoreFailed] = useState(false);
518
- const [connectorsLoadingMore, setConnectorsLoadingMore] = useState(false);
519
358
  const [completedEpoch, setCompletedEpoch] = useState(null);
520
359
  const [loading, setLoading] = useState(false);
521
360
  const [error, setError] = useState(null);
522
- const connectorsNextPageTokenRef = useRef(connectorsNextPageToken);
523
- const connectorsLoadingMoreRef = useRef(connectorsLoadingMore);
524
- const loadMoreFailedRef = useRef(false);
525
- connectorsNextPageTokenRef.current = connectorsNextPageToken;
526
- connectorsLoadingMoreRef.current = connectorsLoadingMore;
527
361
  const ensureLoaded = useCallback(() => {
528
362
  setRequestEpoch((current) => current ?? 0);
529
363
  }, []);
530
364
  const refresh = useCallback(() => {
531
- loadMoreFailedRef.current = false;
532
- setConnectorsLoadMoreFailed(false);
533
365
  setRequestEpoch((current) => (current ?? -1) + 1);
534
366
  }, []);
535
367
  const refreshConnectors = useCallback(async () => {
536
368
  if (!server) return;
537
369
  setLoading(true);
538
370
  setError(null);
539
- loadMoreFailedRef.current = false;
540
- setConnectorsLoadMoreFailed(false);
541
371
  try {
542
- const page = await fetchMcpPage({ server });
543
- setConnectors(page.data);
544
- setConnectorsNextPageToken(page.nextPageToken);
372
+ setConnectors(await server.getMcp());
545
373
  } catch (reason) {
546
374
  setError(getErrorMessage(reason, "Failed to load connectors."));
547
375
  } finally {
548
376
  setLoading(false);
549
377
  }
550
378
  }, [server]);
551
- const loadMoreConnectors = useCallback(() => {
552
- if (!server) return;
553
- const pageToken = connectorsNextPageTokenRef.current;
554
- if (pageToken == null || pageToken.length === 0 || connectorsLoadingMoreRef.current) return;
555
- setConnectorsLoadMoreFailed(false);
556
- setConnectorsLoadingMore(true);
557
- void fetchMcpPage({ server, pageToken }).then((page) => {
558
- setConnectors((previous) => appendConnectors({ previous, next: page.data }));
559
- setConnectorsNextPageToken(page.nextPageToken);
560
- if (loadMoreFailedRef.current) {
561
- loadMoreFailedRef.current = false;
562
- setError(null);
563
- }
564
- }).catch((reason) => {
565
- loadMoreFailedRef.current = true;
566
- setConnectorsLoadMoreFailed(true);
567
- setError(getErrorMessage(reason, "Failed to load more connectors."));
568
- }).finally(() => {
569
- setConnectorsLoadingMore(false);
570
- });
571
- }, [server]);
572
379
  useEffect(() => {
573
380
  if (requestEpoch === null || !server) return;
574
381
  let cancelled = false;
575
382
  setLoading(true);
576
383
  setError(null);
577
- loadMoreFailedRef.current = false;
578
- setConnectorsLoadMoreFailed(false);
579
384
  const connectorCatalog = server.catalog?.connectorCatalog;
580
385
  void Promise.allSettled([
581
386
  server.getModels(),
582
387
  server.getSkills(),
583
- fetchMcpPage({ server }),
388
+ server.getMcp(),
584
389
  connectorCatalog ? connectorCatalog.getConnectorCatalog() : Promise.resolve([])
585
390
  ]).then(([modelsResult, skillsResult, mcpResult, catalogResult]) => {
586
391
  if (cancelled) return;
@@ -597,8 +402,7 @@ function DraftCatalogStore({ server, children }) {
597
402
  errors.push(getErrorMessage(skillsResult.reason, "Failed to load skills."));
598
403
  }
599
404
  if (mcpResult.status === "fulfilled") {
600
- setConnectors(mcpResult.value.data);
601
- setConnectorsNextPageToken(mcpResult.value.nextPageToken);
405
+ setConnectors(mcpResult.value);
602
406
  } else {
603
407
  errors.push(getErrorMessage(mcpResult.reason, "Failed to load connectors."));
604
408
  }
@@ -610,7 +414,6 @@ function DraftCatalogStore({ server, children }) {
610
414
  cancelled = true;
611
415
  };
612
416
  }, [requestEpoch, server]);
613
- const connectorsHasMore = connectorsNextPageToken != null && connectorsNextPageToken.length > 0;
614
417
  const loaded = requestEpoch !== null && completedEpoch === requestEpoch;
615
418
  const value = useMemo(
616
419
  () => ({
@@ -619,16 +422,12 @@ function DraftCatalogStore({ server, children }) {
619
422
  skills,
620
423
  connectors,
621
424
  connectorLogos,
622
- connectorsHasMore,
623
- connectorsLoadMoreFailed,
624
- connectorsLoadingMore,
625
425
  loaded,
626
426
  loading,
627
427
  error,
628
428
  ensureLoaded,
629
429
  refresh,
630
- refreshConnectors,
631
- loadMoreConnectors
430
+ refreshConnectors
632
431
  }),
633
432
  [
634
433
  server,
@@ -636,16 +435,12 @@ function DraftCatalogStore({ server, children }) {
636
435
  skills,
637
436
  connectors,
638
437
  connectorLogos,
639
- connectorsHasMore,
640
- connectorsLoadMoreFailed,
641
- connectorsLoadingMore,
642
438
  loaded,
643
439
  loading,
644
440
  error,
645
441
  ensureLoaded,
646
442
  refresh,
647
- refreshConnectors,
648
- loadMoreConnectors
443
+ refreshConnectors
649
444
  ]
650
445
  );
651
446
  return /* @__PURE__ */ jsx6(DraftCatalogContext.Provider, { value, children });
@@ -658,16 +453,12 @@ function useDraftCatalog() {
658
453
  skills: [],
659
454
  connectors: [],
660
455
  connectorLogos: EMPTY_LOGOS,
661
- connectorsHasMore: false,
662
- connectorsLoadMoreFailed: false,
663
- connectorsLoadingMore: false,
664
456
  loaded: false,
665
457
  loading: false,
666
458
  error: null,
667
459
  ensureLoaded: IDLE_ENSURE,
668
460
  refresh: IDLE_ENSURE,
669
- refreshConnectors: IDLE_REFRESH,
670
- loadMoreConnectors: IDLE_ENSURE
461
+ refreshConnectors: IDLE_REFRESH
671
462
  };
672
463
  }
673
464
  return ctx;
@@ -680,7 +471,6 @@ export {
680
471
  sidebarButtonRadiusClassName,
681
472
  sidebarRailButtonClassName,
682
473
  auiButtonClass,
683
- getErrorMessage,
684
474
  pageHeaderTitleClassName,
685
475
  PageHeader,
686
476
  CompactLayoutProvider,
@@ -688,4 +478,4 @@ export {
688
478
  DraftCatalogProvider,
689
479
  useDraftCatalog
690
480
  };
691
- //# sourceMappingURL=chunk-H6WTY5PM.js.map
481
+ //# sourceMappingURL=chunk-Q6TCT7ZJ.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 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 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"]}
@@ -2,7 +2,7 @@ import {
2
2
  formatCostUsd,
3
3
  formatDurationMs,
4
4
  useThemeMode
5
- } from "./chunk-YQO2NMJ3.js";
5
+ } from "./chunk-2O5EJ6QS.js";
6
6
 
7
7
  // src/atoms/agent-details/AgentMetricChart.tsx
8
8
  import {
@@ -18,8 +18,8 @@ import { useMemo } from "react";
18
18
  import { Line } from "react-chartjs-2";
19
19
  import { jsx, jsxs } from "react/jsx-runtime";
20
20
  ChartJS.register(CategoryScale, LinearScale, LineElement, PointElement, Legend, Tooltip);
21
- var LIGHT_COLORS = ["#2563eb", "#16a34a", "#9333ea", "#ea580c", "#0891b2"];
22
- var DARK_COLORS = ["#60a5fa", "#4ade80", "#c084fc", "#fb923c", "#22d3ee"];
21
+ var LIGHT_COLORS = ["#6366F1", "#2563eb", "#0EA5E9"];
22
+ var DARK_COLORS = ["#6366F1", "#60a5fa", "#38BDF8"];
23
23
  var numberFormatter = new Intl.NumberFormat(void 0, { maximumFractionDigits: 4 });
24
24
  var timestampFormatter = new Intl.DateTimeFormat(void 0, {
25
25
  month: "short",
@@ -36,10 +36,10 @@ function formatTimestamp(timestamp) {
36
36
  const date = new Date(timestamp);
37
37
  return Number.isNaN(date.getTime()) ? timestamp : timestampFormatter.format(date);
38
38
  }
39
- function AgentMetricChart({ graph, definition, error }) {
39
+ function AgentMetricChart({ graph, definition, error, colorIndex = 0 }) {
40
40
  const mode = useThemeMode();
41
41
  const colors = mode === "dark" ? DARK_COLORS : LIGHT_COLORS;
42
- const axisColor = mode === "dark" ? "#a1a1aa" : "#71717a";
42
+ const axisColor = mode === "dark" ? "#71717a" : "#a1a1aa";
43
43
  const gridColor = mode === "dark" ? "#27272a" : "#e4e4e7";
44
44
  const labels = useMemo(
45
45
  () => graph == null ? [] : [...new Set(graph.graphLines.flatMap((line) => line.values.map((point) => point.timestamp)))].sort(),
@@ -50,21 +50,23 @@ function AgentMetricChart({ graph, definition, error }) {
50
50
  labels: labels.map(formatTimestamp),
51
51
  datasets: graph?.graphLines.map((line, index) => {
52
52
  const valuesByTimestamp = new Map(line.values.map((point) => [point.timestamp, point.value]));
53
- const color = colors[index % colors.length];
53
+ const color = colors[(colorIndex + index) % colors.length];
54
54
  return {
55
55
  label: line.name,
56
56
  data: labels.map((timestamp) => valuesByTimestamp.get(timestamp) ?? null),
57
57
  borderColor: color,
58
58
  backgroundColor: color,
59
- pointRadius: 2,
60
- pointHoverRadius: 4,
59
+ pointRadius: 0,
60
+ pointHoverRadius: 0,
61
61
  borderWidth: 2,
62
- tension: 0.25,
62
+ borderCapStyle: "butt",
63
+ borderJoinStyle: "miter",
64
+ tension: 0,
63
65
  spanGaps: true
64
66
  };
65
67
  }) ?? []
66
68
  }),
67
- [colors, graph, labels]
69
+ [colorIndex, colors, graph, labels]
68
70
  );
69
71
  const options = useMemo(
70
72
  () => ({
@@ -116,4 +118,4 @@ function AgentMetricChart({ graph, definition, error }) {
116
118
  export {
117
119
  AgentMetricChart
118
120
  };
119
- //# sourceMappingURL=chunk-5I2COQNL.js.map
121
+ //# sourceMappingURL=chunk-XLFOXQKZ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/atoms/agent-details/AgentMetricChart.tsx"],"sourcesContent":["'use client';\n\nimport {\n CategoryScale,\n Chart as ChartJS,\n Legend,\n LinearScale,\n LineElement,\n PointElement,\n Tooltip,\n type ChartData,\n type ChartOptions,\n} from 'chart.js';\nimport { useMemo, type ComponentType } from 'react';\nimport { Line } from 'react-chartjs-2';\n\nimport { useThemeMode } from '../../theme/SlotsProvider.js';\nimport { formatCostUsd, formatDurationMs } from '../../utils/sessionDisplayFormat.js';\nimport type { AgentMetricChartProps } from './types.js';\n\nChartJS.register(CategoryScale, LinearScale, LineElement, PointElement, Legend, Tooltip);\n\nconst LIGHT_COLORS = ['#6366F1', '#2563eb', '#0EA5E9'];\nconst DARK_COLORS = ['#6366F1', '#60a5fa', '#38BDF8'];\nconst numberFormatter = new Intl.NumberFormat(undefined, { maximumFractionDigits: 4 });\nconst timestampFormatter = new Intl.DateTimeFormat(undefined, {\n month: 'short',\n day: 'numeric',\n hour: 'numeric',\n minute: '2-digit',\n});\n\nfunction formatValue(value: number, unit: string): string {\n if (unit === '$') return formatCostUsd(value);\n if (unit === 'ms') return formatDurationMs(value);\n return `${numberFormatter.format(value)}${unit === 'count' || unit.length === 0 ? '' : ` ${unit}`}`;\n}\n\nfunction formatTimestamp(timestamp: string): string {\n const date = new Date(timestamp);\n return Number.isNaN(date.getTime()) ? timestamp : timestampFormatter.format(date);\n}\n\nexport function AgentMetricChart({ graph, definition, error, colorIndex = 0 }: AgentMetricChartProps) {\n const mode = useThemeMode();\n const colors = mode === 'dark' ? DARK_COLORS : LIGHT_COLORS;\n const axisColor = mode === 'dark' ? '#71717a' : '#a1a1aa';\n const gridColor = mode === 'dark' ? '#27272a' : '#e4e4e7';\n const labels = useMemo(\n () =>\n graph == null\n ? []\n : [...new Set(graph.graphLines.flatMap(line => line.values.map(point => point.timestamp)))].sort(),\n [graph],\n );\n const data = useMemo<ChartData<'line', Array<number | null>, string>>(\n () => ({\n labels: labels.map(formatTimestamp),\n datasets:\n graph?.graphLines.map((line, index) => {\n const valuesByTimestamp = new Map(line.values.map(point => [point.timestamp, point.value]));\n const color = colors[(colorIndex + index) % colors.length];\n return {\n label: line.name,\n data: labels.map(timestamp => valuesByTimestamp.get(timestamp) ?? null),\n borderColor: color,\n backgroundColor: color,\n pointRadius: 0,\n pointHoverRadius: 0,\n borderWidth: 2,\n borderCapStyle: 'butt',\n borderJoinStyle: 'miter',\n tension: 0,\n spanGaps: true,\n };\n }) ?? [],\n }),\n [colorIndex, colors, graph, labels],\n );\n const options = useMemo<ChartOptions<'line'>>(\n () => ({\n responsive: true,\n maintainAspectRatio: false,\n animation: false,\n interaction: { intersect: false, mode: 'index' },\n plugins: {\n legend: {\n display: (graph?.graphLines.length ?? 0) > 1,\n labels: { color: axisColor, boxWidth: 10, boxHeight: 2 },\n },\n tooltip: {\n callbacks: {\n label: context => {\n const value = context.parsed.y;\n return `${context.dataset.label ?? ''}: ${value == null ? '—' : formatValue(value, graph?.unit ?? '')}`;\n },\n },\n },\n },\n scales: {\n x: {\n grid: { display: false },\n border: { color: gridColor },\n ticks: { color: axisColor, maxRotation: 0, autoSkip: true, maxTicksLimit: 8 },\n },\n y: {\n beginAtZero: true,\n grid: { color: gridColor },\n border: { display: false },\n ticks: {\n color: axisColor,\n callback: value => formatValue(Number(value), graph?.unit ?? ''),\n },\n },\n },\n }),\n [axisColor, graph, gridColor],\n );\n const hasData = graph?.graphLines.some(line => line.values.length > 0) === true;\n\n return (\n <section className=\"min-w-0 rounded-lg border border-border bg-card-bg p-4\" data-slot=\"agent-metric-chart\">\n <h3 className=\"text-sm font-semibold text-text-primary\">{graph?.displayName ?? definition.displayName}</h3>\n <p className=\"mt-1 text-xs text-text-secondary\">{graph?.description ?? definition.description}</p>\n <div className=\"mt-4 h-64\">\n {error != null ? (\n <div className=\"flex h-full items-center justify-center text-sm text-failure-bg\">{error}</div>\n ) : hasData ? (\n <Line data={data} options={options} />\n ) : (\n <div className=\"flex h-full items-center justify-center text-sm text-text-secondary\">No data</div>\n )}\n </div>\n </section>\n );\n}\n\ndeclare module '../../theme/SlotsProvider.js' {\n interface AtomSlots {\n AgentMetricChart: ComponentType<AgentMetricChartProps>;\n }\n}\n"],"mappings":"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","names":[]}