@ai-matrx/agents 0.59.230 → 0.59.232

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.
package/CHANGELOG.md CHANGED
@@ -1,10 +1,32 @@
1
1
  # Changelog
2
2
 
3
- ## 0.59.230
3
+ ## 0.59.232
4
4
 
5
5
  UNVERIFIED: this release has no Unreleased entry and the source comparison could not be made (the caller supplied no source comparison). Whether source changed is unknown; consumer action is unknown.
6
6
  Check the package's gitHead on npm against this version's gitHead: `git diff <previous gitHead> <this gitHead> -- apps/shared/matrx-agents/src`.
7
7
 
8
+ ## 0.59.231
9
+
10
+ Automatic changed-only republish (docs/metadata drift since the last published version; verified: `git diff 35a306a12e 93aada8319 -- apps/shared/matrx-agents/src`
11
+ has no shipped-source changes outside tests, fixtures and docs). No consumer action required.
12
+
13
+ ## 0.59.230
14
+
15
+ The agent picker windows its list. `AgentListContent` (the body of
16
+ `AgentListInlinePicker`, `AgentListDropdown` and `AgentListPanel`) mounted every
17
+ agent as a row — measured live on a 605-agent tab: ~5,000 extra DOM nodes and a
18
+ 0.8–2.8 s main-thread block on every open. Past 50 rows it now renders only the
19
+ rows the viewport shows plus overscan (`computeWindow` from
20
+ `@ai-matrx/design-system/data-table/virtual-window`), with spacers keeping the
21
+ scroll height exact; rows are a fixed `AGENT_ROW_HEIGHT` (36 px, exported).
22
+ The list is a `listbox` of `option`s (`aria-setsize`/`aria-posinset`), and the
23
+ search field is its `combobox`: ArrowUp/ArrowDown/PageUp/PageDown move the
24
+ highlight (`aria-activedescendant`), scrolling unmounted rows into view, and
25
+ Enter picks. Opening with a selected agent that is not pinned scrolls it into
26
+ view. `SearchInput` takes optional `onKeyDown` and `inputProps`. Proof:
27
+ `catalog/react/picker-virtualized.test.tsx` (600 agents; red on the old list).
28
+ No consumer action required.
29
+
8
30
  ## 0.59.229
9
31
 
10
32
  Automatic changed-only republish (docs/metadata drift since the last published version; verified: `git diff b18bc55fba 3a8fce70c3 -- apps/shared/matrx-agents/src`
@@ -2364,6 +2386,8 @@ No source changes intended and no consumer action required.
2364
2386
 
2365
2387
  ## Unreleased
2366
2388
 
2389
+ - **`@ai-matrx/agents/mandates` re-exports the mandate keys from `@ai-matrx/api/intelligence`** (their one home; the identical `mandates/keys.generated.ts` copy is gone and the generator writes only the api file). The snapshots stay here. Consumer action: none.
2390
+
2367
2391
 
2368
2392
  - **`ArrowUpDownIcon`, `MessageCircleIcon` and `RocketIcon` (catalog/react/icons) are re-exports of `@ai-matrx/design-system/icons`**, like `FolderIcon`/`TagIcon`/`RotateCcwIcon` before them, so the web picker draws the lucide 1.48 glyphs. The shared `icon-paths` table is untouched, the native entry still draws from it. Consumer action: none.
2369
2393
  - **The mandate key module has one home (packages-copies lane, 2026-10-21).** `mandates/keys.generated.ts` is deleted; the generator writes only `@ai-matrx/api`'s `intelligence/keys.generated.ts` and `@ai-matrx/agents/mandates` re-exports from it. Consumer action: none.
@@ -1040,7 +1040,9 @@ var SearchInput = ({
1040
1040
  ref,
1041
1041
  value,
1042
1042
  onChange,
1043
- placeholder
1043
+ placeholder,
1044
+ onKeyDown,
1045
+ inputProps
1044
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: [
1045
1047
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_icons.SearchIcon, { className: "w-3 h-3 text-muted-foreground shrink-0" }),
1046
1048
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
@@ -1050,6 +1052,8 @@ var SearchInput = ({
1050
1052
  type: "text",
1051
1053
  value,
1052
1054
  onChange: (e) => onChange(e.target.value),
1055
+ onKeyDown,
1056
+ ...inputProps,
1053
1057
  placeholder,
1054
1058
  className: "flex-1 bg-transparent text-xs text-foreground placeholder:text-muted-foreground/50 outline-none min-w-0",
1055
1059
  style: { fontSize: "16px" }
@@ -1505,6 +1509,7 @@ function AgentDetailCard({ agent, onSelect, duplicate, onHoldChange }) {
1505
1509
 
1506
1510
  // catalog/react/AgentListContent.tsx
1507
1511
  var import_design_system5 = require("@ai-matrx/design-system");
1512
+ var import_virtual_window = require("@ai-matrx/design-system/data-table/virtual-window");
1508
1513
  var import_react7 = require("react");
1509
1514
 
1510
1515
  // catalog/react/AgentFilterBar.tsx
@@ -1775,6 +1780,10 @@ function AgentRow({
1775
1780
  // catalog/react/AgentListContent.tsx
1776
1781
  var import_icons10 = require("@ai-matrx/design-system/icons");
1777
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;
1778
1787
  function AgentListContent({
1779
1788
  agents,
1780
1789
  isLoading,
@@ -1806,11 +1815,104 @@ function AgentListContent({
1806
1815
  }) {
1807
1816
  const catalog = useAgentCatalog();
1808
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]);
1809
1846
  (0, import_react7.useEffect)(() => {
1810
- if (listOpen && pinnedAgent) {
1811
- 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;
1852
+ }
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;
1812
1911
  }
1813
- }, [listOpen, pinnedAgent?.id]);
1912
+ event.preventDefault();
1913
+ setActiveIndex(next);
1914
+ revealIndex(next);
1915
+ };
1814
1916
  const { labels } = catalog;
1815
1917
  const emptyLabel = catalog.getUserIdOrNull() === null ? labels.emptySignedOut : agentListEmptyLabel(consumer.tab, labels);
1816
1918
  const defaultAgent = defaultRow?.row ?? null;
@@ -1821,7 +1923,15 @@ function AgentListContent({
1821
1923
  ref: inputRef,
1822
1924
  value: consumer.searchTerm,
1823
1925
  onChange: consumer.setSearchTerm,
1824
- 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
+ }
1825
1935
  }
1826
1936
  ) }),
1827
1937
  /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
@@ -1910,65 +2020,106 @@ function AgentListContent({
1910
2020
  }
1911
2021
  ),
1912
2022
  /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "h-px bg-border shrink-0" }),
1913
- /* @__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: [
1914
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(LoaderIcon, { className: "w-4 h-4 matrx-agent-spin" }),
1915
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-xs", children: labels.loading })
1916
- ] }) : 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: [
1917
- defaultAgent && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
1918
- /* @__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" }) }),
1919
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1920
- AgentRow,
1921
- {
1922
- agent: defaultAgent,
1923
- isActive: defaultAgent.id === activeAgentId,
1924
- isHovered: hoveredAgent?.id === defaultAgent.id,
1925
- isMobile,
1926
- onClick: () => onSelectAgent(defaultAgent),
1927
- href: resolveAgentHref?.(defaultAgent),
1928
- onHover: () => onAgentHover(defaultAgent),
1929
- onHoverEnd: () => onAgentHoverEnd(defaultAgent),
1930
- onDetailPress: () => onDetailPress(defaultAgent)
1931
- },
1932
- `default-${defaultAgent.id}`
1933
- ),
1934
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "mx-2 my-0.5 h-px bg-border" })
1935
- ] }),
1936
- pinnedAgent && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
1937
- /* @__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 }) }),
1938
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1939
- AgentRow,
1940
- {
1941
- agent: pinnedAgent,
1942
- isActive: true,
1943
- isHovered: hoveredAgent?.id === pinnedAgent.id,
1944
- isMobile,
1945
- onClick: () => onSelectAgent(pinnedAgent),
1946
- href: resolveAgentHref?.(pinnedAgent),
1947
- onHover: () => onAgentHover(pinnedAgent),
1948
- onHoverEnd: () => onAgentHoverEnd(pinnedAgent),
1949
- onDetailPress: () => onDetailPress(pinnedAgent)
1950
- },
1951
- `pinned-${pinnedAgent.id}`
1952
- ),
1953
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "mx-2 my-0.5 h-px bg-border" })
1954
- ] }),
1955
- agents.map((agent) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1956
- AgentRow,
1957
- {
1958
- agent,
1959
- isActive: agent.id === activeAgentId,
1960
- isHovered: hoveredAgent?.id === agent.id,
1961
- isMobile,
1962
- onClick: () => onSelectAgent(agent),
1963
- href: resolveAgentHref?.(agent),
1964
- onHover: () => onAgentHover(agent),
1965
- onHoverEnd: () => onAgentHoverEnd(agent),
1966
- onDetailPress: () => onDetailPress(agent)
1967
- },
1968
- agent.id
1969
- )),
1970
- 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 }) })
1971
- ] }) }),
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
+ ),
1972
2123
  /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "h-px bg-border shrink-0" }),
1973
2124
  /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center justify-between px-2.5 py-1.5 shrink-0", children: [
1974
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<{