@ai-matrx/agents 0.59.229 → 0.59.231

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.
@@ -401,85 +401,6 @@ function useAgentConsumer(consumerId, options) {
401
401
  // catalog/shared/useAgentListCore.ts
402
402
  var import_react5 = require("react");
403
403
 
404
- // quick/shape.ts
405
- var QUICK_AGENT_TAG = "kind:quick";
406
- var QUICK_AGENT_DEFAULT_SETTINGS = Object.freeze({
407
- temperature: 0.7,
408
- topP: 1,
409
- maxOutputTokens: 4096
410
- });
411
- function isQuickAgentSummary(row) {
412
- return row.tags.includes(QUICK_AGENT_TAG);
413
- }
414
- function withoutQuickAgents(rows) {
415
- return rows.filter((row) => !isQuickAgentSummary(row));
416
- }
417
-
418
- // catalog/types.ts
419
- function isMandateAgentId(id) {
420
- return id.startsWith("mandate:");
421
- }
422
- var SORT_OPTIONS = [
423
- { value: "updated-desc", label: "Recent" },
424
- { value: "created-desc", label: "Created" },
425
- { value: "name-asc", label: "A \u2192 Z" },
426
- { value: "name-desc", label: "Z \u2192 A" },
427
- { value: "category-asc", label: "Category" }
428
- ];
429
- var ARCHIVE_FILTER_ORDER = [
430
- "active",
431
- "both",
432
- "archived"
433
- ];
434
- var ARCHIVE_FILTER_OPTIONS = [
435
- { value: "active", label: "Hide archived", chip: "Archive" },
436
- { value: "both", label: "Show all", chip: "All + archived" },
437
- { value: "archived", label: "Archived only", chip: "Archived only" }
438
- ];
439
- function nextArchFilter(current) {
440
- const index = ARCHIVE_FILTER_ORDER.indexOf(current);
441
- if (index < 0) return ARCHIVE_FILTER_ORDER[0];
442
- return ARCHIVE_FILTER_ORDER[(index + 1) % ARCHIVE_FILTER_ORDER.length];
443
- }
444
- var AGENT_NONE_SENTINEL = "__none__";
445
-
446
- // catalog/labels.ts
447
- function agentListEmptyLabel(tab, labels) {
448
- switch (tab) {
449
- case "system":
450
- return labels.emptySystem;
451
- case "shared":
452
- return labels.emptyShared;
453
- default:
454
- return labels.emptyDefault;
455
- }
456
- }
457
- function shouldDefaultAgentListToPublicTab(args) {
458
- if (!args.userId) return true;
459
- if (!args.agentsLoaded) return false;
460
- return args.ownedCount === 0;
461
- }
462
- function agentArchiveFilterChipLabel(archFilter) {
463
- return ARCHIVE_FILTER_OPTIONS.find((o) => o.value === archFilter)?.chip ?? "Archive";
464
- }
465
- function agentArchiveFilterStateLabel(archFilter) {
466
- return ARCHIVE_FILTER_OPTIONS.find((o) => o.value === archFilter)?.label ?? "Hide archived";
467
- }
468
- function agentArchiveFilterControlLabel(archFilter) {
469
- return `Archive filter: ${agentArchiveFilterStateLabel(
470
- archFilter
471
- ).toLowerCase()}. Click for ${agentArchiveFilterStateLabel(
472
- nextArchFilter(archFilter)
473
- ).toLowerCase()}`;
474
- }
475
- function agentListFooterLabel(args) {
476
- const { count, archFilter, archivedHiddenCount } = args;
477
- if (archFilter === "archived") return `${count} archived shown`;
478
- const base = `${count} agent${count !== 1 ? "s" : ""}`;
479
- if (archFilter === "both") return `${base} \xB7 archived shown`;
480
- return archivedHiddenCount > 0 ? `${base} \xB7 ${archivedHiddenCount} archived hidden` : base;
481
- }
482
-
483
404
  // catalog/score.ts
484
405
  function computeAgentSearchScore(agent, query) {
485
406
  const q = query.trim().toLowerCase();
@@ -526,6 +447,34 @@ function agentMatchesSearch(agent, query) {
526
447
  return computeAgentSearchScore(agent, query) > 0;
527
448
  }
528
449
 
450
+ // catalog/types.ts
451
+ function isMandateAgentId(id) {
452
+ return id.startsWith("mandate:");
453
+ }
454
+ var SORT_OPTIONS = [
455
+ { value: "updated-desc", label: "Recent" },
456
+ { value: "created-desc", label: "Created" },
457
+ { value: "name-asc", label: "A \u2192 Z" },
458
+ { value: "name-desc", label: "Z \u2192 A" },
459
+ { value: "category-asc", label: "Category" }
460
+ ];
461
+ var ARCHIVE_FILTER_ORDER = [
462
+ "active",
463
+ "both",
464
+ "archived"
465
+ ];
466
+ var ARCHIVE_FILTER_OPTIONS = [
467
+ { value: "active", label: "Hide archived", chip: "Archive" },
468
+ { value: "both", label: "Show all", chip: "All + archived" },
469
+ { value: "archived", label: "Archived only", chip: "Archived only" }
470
+ ];
471
+ function nextArchFilter(current) {
472
+ const index = ARCHIVE_FILTER_ORDER.indexOf(current);
473
+ if (index < 0) return ARCHIVE_FILTER_ORDER[0];
474
+ return ARCHIVE_FILTER_ORDER[(index + 1) % ARCHIVE_FILTER_ORDER.length];
475
+ }
476
+ var AGENT_NONE_SENTINEL = "__none__";
477
+
529
478
  // catalog/selectors.ts
530
479
  function memoize1(fn) {
531
480
  let lastA;
@@ -794,6 +743,52 @@ var selectTotalFavoriteAgentsCount = memoize1(
794
743
  (agents) => countUserRows(agents, "active", isFavorite)
795
744
  );
796
745
 
746
+ // quick/shape.ts
747
+ var QUICK_AGENT_TAG = "kind:quick";
748
+ function isQuickAgentSummary(row) {
749
+ return row.tags.includes(QUICK_AGENT_TAG);
750
+ }
751
+ function withoutQuickAgents(rows) {
752
+ return rows.filter((row) => !isQuickAgentSummary(row));
753
+ }
754
+
755
+ // catalog/labels.ts
756
+ function agentListEmptyLabel(tab, labels) {
757
+ switch (tab) {
758
+ case "system":
759
+ return labels.emptySystem;
760
+ case "shared":
761
+ return labels.emptyShared;
762
+ default:
763
+ return labels.emptyDefault;
764
+ }
765
+ }
766
+ function shouldDefaultAgentListToPublicTab(args) {
767
+ if (!args.userId) return true;
768
+ if (!args.agentsLoaded) return false;
769
+ return args.ownedCount === 0;
770
+ }
771
+ function agentArchiveFilterChipLabel(archFilter) {
772
+ return ARCHIVE_FILTER_OPTIONS.find((o) => o.value === archFilter)?.chip ?? "Archive";
773
+ }
774
+ function agentArchiveFilterStateLabel(archFilter) {
775
+ return ARCHIVE_FILTER_OPTIONS.find((o) => o.value === archFilter)?.label ?? "Hide archived";
776
+ }
777
+ function agentArchiveFilterControlLabel(archFilter) {
778
+ return `Archive filter: ${agentArchiveFilterStateLabel(
779
+ archFilter
780
+ ).toLowerCase()}. Click for ${agentArchiveFilterStateLabel(
781
+ nextArchFilter(archFilter)
782
+ ).toLowerCase()}`;
783
+ }
784
+ function agentListFooterLabel(args) {
785
+ const { count, archFilter, archivedHiddenCount } = args;
786
+ if (archFilter === "archived") return `${count} archived shown`;
787
+ const base = `${count} agent${count !== 1 ? "s" : ""}`;
788
+ if (archFilter === "both") return `${base} \xB7 archived shown`;
789
+ return archivedHiddenCount > 0 ? `${base} \xB7 ${archivedHiddenCount} archived hidden` : base;
790
+ }
791
+
797
792
  // catalog/shared/useAgentListCore.ts
798
793
  var HOVER_GRACE_MS = 900;
799
794
  function coerceVisibleTab(current, allowed, initialTab) {
@@ -1045,7 +1040,9 @@ var SearchInput = ({
1045
1040
  ref,
1046
1041
  value,
1047
1042
  onChange,
1048
- placeholder
1043
+ placeholder,
1044
+ onKeyDown,
1045
+ inputProps
1049
1046
  }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "flex items-center gap-1.5 h-7 px-2 rounded-md bg-muted/40 border border-border/50", children: [
1050
1047
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_icons.SearchIcon, { className: "w-3 h-3 text-muted-foreground shrink-0" }),
1051
1048
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
@@ -1055,6 +1052,8 @@ var SearchInput = ({
1055
1052
  type: "text",
1056
1053
  value,
1057
1054
  onChange: (e) => onChange(e.target.value),
1055
+ onKeyDown,
1056
+ ...inputProps,
1058
1057
  placeholder,
1059
1058
  className: "flex-1 bg-transparent text-xs text-foreground placeholder:text-muted-foreground/50 outline-none min-w-0",
1060
1059
  style: { fontSize: "16px" }
@@ -1373,11 +1372,8 @@ function makeIcon(name) {
1373
1372
  return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Svg, { ...props, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Shape, { name, filled: false }) });
1374
1373
  };
1375
1374
  }
1376
- var ArrowUpDownIcon = makeIcon("arrowUpDown");
1377
1375
  var LoaderIcon = makeIcon("loader");
1378
1376
  var UsersIcon = makeIcon("users");
1379
- var MessageCircleIcon = makeIcon("messageCircle");
1380
- var RocketIcon = makeIcon("rocket");
1381
1377
  var CircleCheckIcon = makeIcon("circleCheck");
1382
1378
  var AlertTriangleIcon = makeIcon("alertTriangle");
1383
1379
  var Music4Icon = makeIcon("music4");
@@ -1513,6 +1509,7 @@ function AgentDetailCard({ agent, onSelect, duplicate, onHoldChange }) {
1513
1509
 
1514
1510
  // catalog/react/AgentListContent.tsx
1515
1511
  var import_design_system5 = require("@ai-matrx/design-system");
1512
+ var import_virtual_window = require("@ai-matrx/design-system/data-table/virtual-window");
1516
1513
  var import_react7 = require("react");
1517
1514
 
1518
1515
  // catalog/react/AgentFilterBar.tsx
@@ -1558,7 +1555,7 @@ function AgentFilterBar({
1558
1555
  /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1559
1556
  FilterChip,
1560
1557
  {
1561
- icon: ArrowUpDownIcon,
1558
+ icon: import_icons2.ArrowUpDownIcon,
1562
1559
  label: SORT_OPTIONS.find((o) => o.value === consumer.sortBy)?.label ?? "Sort",
1563
1560
  active: consumer.sortBy !== "updated-desc",
1564
1561
  focused: !isMobile && rightPanel === "sort",
@@ -1783,6 +1780,10 @@ function AgentRow({
1783
1780
  // catalog/react/AgentListContent.tsx
1784
1781
  var import_icons10 = require("@ai-matrx/design-system/icons");
1785
1782
  var import_jsx_runtime10 = require("react/jsx-runtime");
1783
+ var AGENT_ROW_HEIGHT = 36;
1784
+ var UNMEASURED_VIEWPORT = 480;
1785
+ var ROW_OVERSCAN = 8;
1786
+ var WINDOW_ABOVE = 50;
1786
1787
  function AgentListContent({
1787
1788
  agents,
1788
1789
  isLoading,
@@ -1814,11 +1815,104 @@ function AgentListContent({
1814
1815
  }) {
1815
1816
  const catalog = useAgentCatalog();
1816
1817
  const listScrollRef = (0, import_react7.useRef)(null);
1818
+ const windowRef = (0, import_react7.useRef)(null);
1819
+ const listboxId = (0, import_react7.useId)();
1820
+ const [scrollTop, setScrollTop] = (0, import_react7.useState)(0);
1821
+ const [viewport, setViewport] = (0, import_react7.useState)(0);
1822
+ const [listStart, setListStart] = (0, import_react7.useState)(0);
1823
+ const [activeIndex, setActiveIndex] = (0, import_react7.useState)(-1);
1824
+ const [resetKey, setResetKey] = (0, import_react7.useState)(
1825
+ `${consumer.tab}\0${consumer.searchTerm}`
1826
+ );
1827
+ const nextResetKey = `${consumer.tab}\0${consumer.searchTerm}`;
1828
+ if (nextResetKey !== resetKey) {
1829
+ setResetKey(nextResetKey);
1830
+ setActiveIndex(-1);
1831
+ }
1832
+ const defaultAgentId = defaultRow?.row?.id ?? null;
1833
+ (0, import_react7.useLayoutEffect)(() => {
1834
+ const scroller = listScrollRef.current;
1835
+ if (!scroller) return void 0;
1836
+ const measure = () => {
1837
+ setViewport(scroller.clientHeight);
1838
+ setListStart(windowRef.current?.offsetTop ?? 0);
1839
+ };
1840
+ measure();
1841
+ if (typeof ResizeObserver === "undefined") return void 0;
1842
+ const observer = new ResizeObserver(measure);
1843
+ observer.observe(scroller);
1844
+ return () => observer.disconnect();
1845
+ }, [isLoading, pinnedAgent?.id, defaultAgentId, agents.length === 0]);
1817
1846
  (0, import_react7.useEffect)(() => {
1818
- if (listOpen && pinnedAgent) {
1819
- listScrollRef.current?.scrollTo({ top: 0 });
1847
+ const scroller = listScrollRef.current;
1848
+ if (!listOpen || !scroller) return;
1849
+ if (pinnedAgent) {
1850
+ scroller.scrollTo({ top: 0 });
1851
+ return;
1820
1852
  }
1821
- }, [listOpen, pinnedAgent?.id]);
1853
+ const index = activeAgentId ? agents.findIndex((a) => a.id === activeAgentId) : -1;
1854
+ if (index < 0) return;
1855
+ const view = scroller.clientHeight || UNMEASURED_VIEWPORT;
1856
+ const top = Math.max(
1857
+ 0,
1858
+ (windowRef.current?.offsetTop ?? 0) + index * AGENT_ROW_HEIGHT - (view - AGENT_ROW_HEIGHT) / 2
1859
+ );
1860
+ scroller.scrollTo({ top });
1861
+ setScrollTop(top);
1862
+ }, [listOpen, pinnedAgent?.id, activeAgentId, isLoading]);
1863
+ const win = agents.length <= WINDOW_ABOVE ? { start: 0, end: agents.length, padStart: 0, padEnd: 0 } : (0, import_virtual_window.computeWindow)({
1864
+ count: agents.length,
1865
+ itemSize: AGENT_ROW_HEIGHT,
1866
+ viewport: viewport > 0 ? viewport : UNMEASURED_VIEWPORT,
1867
+ offset: Math.max(0, scrollTop - listStart),
1868
+ overscan: ROW_OVERSCAN
1869
+ });
1870
+ const visibleAgents = agents.slice(win.start, win.end);
1871
+ const optionId = (index) => `${listboxId}-option-${index}`;
1872
+ const revealIndex = (index) => {
1873
+ const scroller = listScrollRef.current;
1874
+ if (!scroller) return;
1875
+ const view = scroller.clientHeight || UNMEASURED_VIEWPORT;
1876
+ const top = listStart + index * AGENT_ROW_HEIGHT;
1877
+ const bottom = top + AGENT_ROW_HEIGHT;
1878
+ let next = null;
1879
+ if (top < scroller.scrollTop) next = top;
1880
+ else if (bottom > scroller.scrollTop + view) next = bottom - view;
1881
+ if (next === null) return;
1882
+ scroller.scrollTop = next;
1883
+ setScrollTop(next);
1884
+ };
1885
+ const handleListKeyDown = (event) => {
1886
+ if (agents.length === 0) return;
1887
+ const last = agents.length - 1;
1888
+ let next = null;
1889
+ switch (event.key) {
1890
+ case "ArrowDown":
1891
+ next = activeIndex < 0 ? 0 : Math.min(last, activeIndex + 1);
1892
+ break;
1893
+ case "ArrowUp":
1894
+ next = activeIndex <= 0 ? 0 : activeIndex - 1;
1895
+ break;
1896
+ case "PageDown":
1897
+ next = Math.min(last, Math.max(0, activeIndex) + 10);
1898
+ break;
1899
+ case "PageUp":
1900
+ next = Math.max(0, activeIndex - 10);
1901
+ break;
1902
+ case "Enter": {
1903
+ const agent = activeIndex >= 0 ? agents[activeIndex] : void 0;
1904
+ if (!agent) return;
1905
+ event.preventDefault();
1906
+ onSelectAgent(agent);
1907
+ return;
1908
+ }
1909
+ default:
1910
+ return;
1911
+ }
1912
+ event.preventDefault();
1913
+ setActiveIndex(next);
1914
+ revealIndex(next);
1915
+ };
1822
1916
  const { labels } = catalog;
1823
1917
  const emptyLabel = catalog.getUserIdOrNull() === null ? labels.emptySignedOut : agentListEmptyLabel(consumer.tab, labels);
1824
1918
  const defaultAgent = defaultRow?.row ?? null;
@@ -1829,7 +1923,15 @@ function AgentListContent({
1829
1923
  ref: inputRef,
1830
1924
  value: consumer.searchTerm,
1831
1925
  onChange: consumer.setSearchTerm,
1832
- placeholder: labels.searchPlaceholder
1926
+ placeholder: labels.searchPlaceholder,
1927
+ onKeyDown: handleListKeyDown,
1928
+ inputProps: {
1929
+ role: "combobox",
1930
+ "aria-controls": listboxId,
1931
+ "aria-expanded": true,
1932
+ "aria-autocomplete": "list",
1933
+ ...activeIndex >= 0 && activeIndex < agents.length ? { "aria-activedescendant": optionId(activeIndex) } : {}
1934
+ }
1833
1935
  }
1834
1936
  ) }),
1835
1937
  /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
@@ -1918,65 +2020,106 @@ function AgentListContent({
1918
2020
  }
1919
2021
  ),
1920
2022
  /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "h-px bg-border shrink-0" }),
1921
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { ref: listScrollRef, className: "overflow-y-auto flex-1 min-h-0", children: isLoading ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center justify-center py-8 gap-2 text-muted-foreground", children: [
1922
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(LoaderIcon, { className: "w-4 h-4 matrx-agent-spin" }),
1923
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-xs", children: labels.loading })
1924
- ] }) : agents.length === 0 && !pinnedAgent && !defaultAgent ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "flex flex-col items-center py-8 text-muted-foreground", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-xs", children: emptyLabel }) }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "py-0.5", children: [
1925
- defaultAgent && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
1926
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "px-3 pt-1.5 pb-0.5", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-[10px] font-medium uppercase tracking-wide text-muted-foreground", children: "Default" }) }),
1927
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1928
- AgentRow,
1929
- {
1930
- agent: defaultAgent,
1931
- isActive: defaultAgent.id === activeAgentId,
1932
- isHovered: hoveredAgent?.id === defaultAgent.id,
1933
- isMobile,
1934
- onClick: () => onSelectAgent(defaultAgent),
1935
- href: resolveAgentHref?.(defaultAgent),
1936
- onHover: () => onAgentHover(defaultAgent),
1937
- onHoverEnd: () => onAgentHoverEnd(defaultAgent),
1938
- onDetailPress: () => onDetailPress(defaultAgent)
1939
- },
1940
- `default-${defaultAgent.id}`
1941
- ),
1942
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "mx-2 my-0.5 h-px bg-border" })
1943
- ] }),
1944
- pinnedAgent && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
1945
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "px-3 pt-1.5 pb-0.5", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-[10px] font-medium uppercase tracking-wide text-muted-foreground", children: labels.currentAgentHeading }) }),
1946
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1947
- AgentRow,
1948
- {
1949
- agent: pinnedAgent,
1950
- isActive: true,
1951
- isHovered: hoveredAgent?.id === pinnedAgent.id,
1952
- isMobile,
1953
- onClick: () => onSelectAgent(pinnedAgent),
1954
- href: resolveAgentHref?.(pinnedAgent),
1955
- onHover: () => onAgentHover(pinnedAgent),
1956
- onHoverEnd: () => onAgentHoverEnd(pinnedAgent),
1957
- onDetailPress: () => onDetailPress(pinnedAgent)
1958
- },
1959
- `pinned-${pinnedAgent.id}`
1960
- ),
1961
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "mx-2 my-0.5 h-px bg-border" })
1962
- ] }),
1963
- agents.map((agent) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1964
- AgentRow,
1965
- {
1966
- agent,
1967
- isActive: agent.id === activeAgentId,
1968
- isHovered: hoveredAgent?.id === agent.id,
1969
- isMobile,
1970
- onClick: () => onSelectAgent(agent),
1971
- href: resolveAgentHref?.(agent),
1972
- onHover: () => onAgentHover(agent),
1973
- onHoverEnd: () => onAgentHoverEnd(agent),
1974
- onDetailPress: () => onDetailPress(agent)
1975
- },
1976
- agent.id
1977
- )),
1978
- agents.length === 0 && (pinnedAgent || defaultAgent) && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "flex flex-col items-center py-4 text-muted-foreground", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-xs", children: emptyLabel }) })
1979
- ] }) }),
2023
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2024
+ "div",
2025
+ {
2026
+ ref: listScrollRef,
2027
+ "data-agent-list-scroll": "",
2028
+ onScroll: (e) => setScrollTop(e.currentTarget.scrollTop),
2029
+ className: "relative overflow-y-auto flex-1 min-h-0",
2030
+ children: isLoading ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center justify-center py-8 gap-2 text-muted-foreground", children: [
2031
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(LoaderIcon, { className: "w-4 h-4 matrx-agent-spin" }),
2032
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-xs", children: labels.loading })
2033
+ ] }) : agents.length === 0 && !pinnedAgent && !defaultAgent ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "flex flex-col items-center py-8 text-muted-foreground", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-xs", children: emptyLabel }) }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "py-0.5", children: [
2034
+ defaultAgent && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
2035
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "px-3 pt-1.5 pb-0.5", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-[10px] font-medium uppercase tracking-wide text-muted-foreground", children: "Default" }) }),
2036
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2037
+ AgentRow,
2038
+ {
2039
+ agent: defaultAgent,
2040
+ isActive: defaultAgent.id === activeAgentId,
2041
+ isHovered: hoveredAgent?.id === defaultAgent.id,
2042
+ isMobile,
2043
+ onClick: () => onSelectAgent(defaultAgent),
2044
+ href: resolveAgentHref?.(defaultAgent),
2045
+ onHover: () => onAgentHover(defaultAgent),
2046
+ onHoverEnd: () => onAgentHoverEnd(defaultAgent),
2047
+ onDetailPress: () => onDetailPress(defaultAgent)
2048
+ },
2049
+ `default-${defaultAgent.id}`
2050
+ ),
2051
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "mx-2 my-0.5 h-px bg-border" })
2052
+ ] }),
2053
+ pinnedAgent && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
2054
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "px-3 pt-1.5 pb-0.5", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-[10px] font-medium uppercase tracking-wide text-muted-foreground", children: labels.currentAgentHeading }) }),
2055
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2056
+ AgentRow,
2057
+ {
2058
+ agent: pinnedAgent,
2059
+ isActive: true,
2060
+ isHovered: hoveredAgent?.id === pinnedAgent.id,
2061
+ isMobile,
2062
+ onClick: () => onSelectAgent(pinnedAgent),
2063
+ href: resolveAgentHref?.(pinnedAgent),
2064
+ onHover: () => onAgentHover(pinnedAgent),
2065
+ onHoverEnd: () => onAgentHoverEnd(pinnedAgent),
2066
+ onDetailPress: () => onDetailPress(pinnedAgent)
2067
+ },
2068
+ `pinned-${pinnedAgent.id}`
2069
+ ),
2070
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "mx-2 my-0.5 h-px bg-border" })
2071
+ ] }),
2072
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
2073
+ "div",
2074
+ {
2075
+ ref: windowRef,
2076
+ id: listboxId,
2077
+ role: "listbox",
2078
+ "aria-label": labels.searchPlaceholder,
2079
+ children: [
2080
+ win.padStart > 0 && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { "aria-hidden": true, style: { height: win.padStart } }),
2081
+ visibleAgents.map((agent, offset) => {
2082
+ const index = win.start + offset;
2083
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2084
+ "div",
2085
+ {
2086
+ id: optionId(index),
2087
+ role: "option",
2088
+ "aria-selected": agent.id === activeAgentId,
2089
+ "aria-posinset": index + 1,
2090
+ "aria-setsize": agents.length,
2091
+ "data-agent-index": index,
2092
+ style: { height: AGENT_ROW_HEIGHT },
2093
+ className: (0, import_design_system5.cn)(
2094
+ "flex overflow-hidden",
2095
+ index === activeIndex && "bg-muted/60"
2096
+ ),
2097
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2098
+ AgentRow,
2099
+ {
2100
+ agent,
2101
+ isActive: agent.id === activeAgentId,
2102
+ isHovered: hoveredAgent?.id === agent.id,
2103
+ isMobile,
2104
+ onClick: () => onSelectAgent(agent),
2105
+ href: resolveAgentHref?.(agent),
2106
+ onHover: () => onAgentHover(agent),
2107
+ onHoverEnd: () => onAgentHoverEnd(agent),
2108
+ onDetailPress: () => onDetailPress(agent)
2109
+ }
2110
+ )
2111
+ },
2112
+ agent.id
2113
+ );
2114
+ }),
2115
+ win.padEnd > 0 && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { "aria-hidden": true, style: { height: win.padEnd } })
2116
+ ]
2117
+ }
2118
+ ),
2119
+ agents.length === 0 && (pinnedAgent || defaultAgent) && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "flex flex-col items-center py-4 text-muted-foreground", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-xs", children: emptyLabel }) })
2120
+ ] })
2121
+ }
2122
+ ),
1980
2123
  /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "h-px bg-border shrink-0" }),
1981
2124
  /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center justify-between px-2.5 py-1.5 shrink-0", children: [
1982
2125
  /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
@@ -1,5 +1,5 @@
1
1
  import * as react from 'react';
2
- import { ComponentType, ReactNode, Ref, SVGProps } from 'react';
2
+ import { ComponentType, ReactNode, Ref, KeyboardEventHandler, InputHTMLAttributes, SVGProps } from 'react';
3
3
 
4
4
  /**
5
5
  * `@ai-matrx/agents/catalog` — the row shape and the per-consumer view state.
@@ -1174,11 +1174,15 @@ interface FavoriteAgentButtonProps {
1174
1174
  }
1175
1175
  declare function FavoriteAgentButton({ id, variant, disabled, }: FavoriteAgentButtonProps): react.JSX.Element;
1176
1176
 
1177
- declare const SearchInput: ({ ref, value, onChange, placeholder, }: {
1177
+ declare const SearchInput: ({ ref, value, onChange, placeholder, onKeyDown, inputProps, }: {
1178
1178
  ref?: Ref<HTMLInputElement>;
1179
1179
  value: string;
1180
1180
  onChange: (v: string) => void;
1181
1181
  placeholder: string;
1182
+ /** Keyboard handler — the agent list drives its listbox from the field. */
1183
+ onKeyDown?: KeyboardEventHandler<HTMLInputElement>;
1184
+ /** ARIA wiring (combobox role, aria-controls, aria-activedescendant). */
1185
+ inputProps?: Pick<InputHTMLAttributes<HTMLInputElement>, "role" | "aria-controls" | "aria-activedescendant" | "aria-expanded" | "aria-autocomplete" | "aria-label">;
1182
1186
  }) => react.JSX.Element;
1183
1187
  declare function FilterChip({ icon: Icon, label, active, focused, onClick, ariaLabel, testId, }: {
1184
1188
  icon: ComponentType<{
@@ -1,5 +1,5 @@
1
1
  import * as react from 'react';
2
- import { ComponentType, ReactNode, Ref, SVGProps } from 'react';
2
+ import { ComponentType, ReactNode, Ref, KeyboardEventHandler, InputHTMLAttributes, SVGProps } from 'react';
3
3
 
4
4
  /**
5
5
  * `@ai-matrx/agents/catalog` — the row shape and the per-consumer view state.
@@ -1174,11 +1174,15 @@ interface FavoriteAgentButtonProps {
1174
1174
  }
1175
1175
  declare function FavoriteAgentButton({ id, variant, disabled, }: FavoriteAgentButtonProps): react.JSX.Element;
1176
1176
 
1177
- declare const SearchInput: ({ ref, value, onChange, placeholder, }: {
1177
+ declare const SearchInput: ({ ref, value, onChange, placeholder, onKeyDown, inputProps, }: {
1178
1178
  ref?: Ref<HTMLInputElement>;
1179
1179
  value: string;
1180
1180
  onChange: (v: string) => void;
1181
1181
  placeholder: string;
1182
+ /** Keyboard handler — the agent list drives its listbox from the field. */
1183
+ onKeyDown?: KeyboardEventHandler<HTMLInputElement>;
1184
+ /** ARIA wiring (combobox role, aria-controls, aria-activedescendant). */
1185
+ inputProps?: Pick<InputHTMLAttributes<HTMLInputElement>, "role" | "aria-controls" | "aria-activedescendant" | "aria-expanded" | "aria-autocomplete" | "aria-label">;
1182
1186
  }) => react.JSX.Element;
1183
1187
  declare function FilterChip({ icon: Icon, label, active, focused, onClick, ariaLabel, testId, }: {
1184
1188
  icon: ComponentType<{