@ai-matrx/agents 0.9.1 → 0.9.2

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.
@@ -169,53 +169,27 @@ function AgentCatalogProvider({
169
169
 
170
170
  // catalog/shared/useAgentConsumer.ts
171
171
  var import_react3 = require("react");
172
-
173
- // catalog/types.ts
174
- function isMandateAgentId(id) {
175
- return id.startsWith("mandate:");
176
- }
177
- var SORT_OPTIONS = [
178
- { value: "updated-desc", label: "Recent" },
179
- { value: "created-desc", label: "Created" },
180
- { value: "name-asc", label: "A \u2192 Z" },
181
- { value: "name-desc", label: "Z \u2192 A" },
182
- { value: "category-asc", label: "Category" }
183
- ];
184
- var AGENT_NONE_SENTINEL = "__none__";
185
- var DEFAULT_AGENT_CONSUMER_STATE = {
186
- tab: "mine",
187
- sortBy: "updated-desc",
188
- searchTerm: "",
189
- includedCats: [],
190
- includedTags: [],
191
- favFilter: "all",
192
- archFilter: "active",
193
- accessFilter: "any",
194
- favoritesFirst: true,
195
- listPage: 1,
196
- sharedPage: 1,
197
- serverMatchedIds: [],
198
- isServerSearching: false,
199
- deepSearch: false
200
- };
201
-
202
- // catalog/shared/useAgentConsumer.ts
203
172
  var DEBOUNCE_MS = 250;
204
173
  var MIN_QUERY_LENGTH = 2;
205
174
  function useAgentConsumer(consumerId, options) {
206
175
  const catalog = useAgentCatalog();
176
+ const defaults = catalog.consumerDefaults;
207
177
  const selectConsumer = (0, import_react3.useCallback)(
208
- (state) => state.consumers[consumerId] ?? DEFAULT_AGENT_CONSUMER_STATE,
209
- [consumerId]
178
+ (state) => state.consumers[consumerId] ?? defaults,
179
+ [consumerId, defaults]
210
180
  );
211
181
  const consumer = useAgentCatalogState(selectConsumer);
212
182
  const optionsRef = (0, import_react3.useRef)(options);
213
183
  optionsRef.current = options;
214
184
  (0, import_react3.useEffect)(() => {
215
185
  const opts = optionsRef.current;
186
+ const initial = {
187
+ ...opts?.initialTab ? { tab: opts.initialTab } : {},
188
+ ...opts?.initialArchFilter ? { archFilter: opts.initialArchFilter } : {}
189
+ };
216
190
  catalog.registerConsumer(
217
191
  consumerId,
218
- opts?.initialTab ? { tab: opts.initialTab } : void 0
192
+ Object.keys(initial).length > 0 ? initial : void 0
219
193
  );
220
194
  return () => {
221
195
  if (optionsRef.current?.unregisterOnUnmount) {
@@ -338,7 +312,10 @@ function useAgentConsumer(consumerId, options) {
338
312
  isSearching
339
313
  });
340
314
  }, [consumerId, catalog, matchedIds, isSearching]);
341
- const hasActiveFilters = consumer.searchTerm !== "" || consumer.includedCats.length > 0 || consumer.includedTags.length > 0 || consumer.favFilter !== "all" || consumer.archFilter !== "active" || consumer.accessFilter !== "any" || !consumer.favoritesFirst;
315
+ const hasActiveFilters = consumer.searchTerm !== "" || consumer.includedCats.length > 0 || consumer.includedTags.length > 0 || consumer.favFilter !== "all" || // The archive filter is compared to THIS CATALOG'S default, not to the
316
+ // hardcoded platform one: a host that legitimately defaults to "show all"
317
+ // must not have the reset control permanently lit.
318
+ consumer.archFilter !== defaults.archFilter || consumer.accessFilter !== "any" || !consumer.favoritesFirst;
342
319
  return {
343
320
  tab: consumer.tab,
344
321
  sortBy: consumer.sortBy,
@@ -347,6 +324,7 @@ function useAgentConsumer(consumerId, options) {
347
324
  includedTags: consumer.includedTags,
348
325
  favFilter: consumer.favFilter,
349
326
  archFilter: consumer.archFilter,
327
+ archFilterDefault: defaults.archFilter,
350
328
  accessFilter: consumer.accessFilter,
351
329
  favoritesFirst: consumer.favoritesFirst,
352
330
  listPage: consumer.listPage,
@@ -376,6 +354,34 @@ function useAgentConsumer(consumerId, options) {
376
354
  // catalog/shared/useAgentListCore.ts
377
355
  var import_react4 = require("react");
378
356
 
357
+ // catalog/types.ts
358
+ function isMandateAgentId(id) {
359
+ return id.startsWith("mandate:");
360
+ }
361
+ var SORT_OPTIONS = [
362
+ { value: "updated-desc", label: "Recent" },
363
+ { value: "created-desc", label: "Created" },
364
+ { value: "name-asc", label: "A \u2192 Z" },
365
+ { value: "name-desc", label: "Z \u2192 A" },
366
+ { value: "category-asc", label: "Category" }
367
+ ];
368
+ var ARCHIVE_FILTER_ORDER = [
369
+ "active",
370
+ "both",
371
+ "archived"
372
+ ];
373
+ var ARCHIVE_FILTER_OPTIONS = [
374
+ { value: "active", label: "Hide archived", chip: "Archive" },
375
+ { value: "both", label: "Show all", chip: "All + archived" },
376
+ { value: "archived", label: "Archived only", chip: "Archived only" }
377
+ ];
378
+ function nextArchFilter(current) {
379
+ const index = ARCHIVE_FILTER_ORDER.indexOf(current);
380
+ if (index < 0) return ARCHIVE_FILTER_ORDER[0];
381
+ return ARCHIVE_FILTER_ORDER[(index + 1) % ARCHIVE_FILTER_ORDER.length];
382
+ }
383
+ var AGENT_NONE_SENTINEL = "__none__";
384
+
379
385
  // catalog/labels.ts
380
386
  function agentListEmptyLabel(tab, labels) {
381
387
  switch (tab) {
@@ -392,6 +398,26 @@ function shouldDefaultAgentListToPublicTab(args) {
392
398
  if (!args.agentsLoaded) return false;
393
399
  return args.ownedCount === 0;
394
400
  }
401
+ function agentArchiveFilterChipLabel(archFilter) {
402
+ return ARCHIVE_FILTER_OPTIONS.find((o) => o.value === archFilter)?.chip ?? "Archive";
403
+ }
404
+ function agentArchiveFilterStateLabel(archFilter) {
405
+ return ARCHIVE_FILTER_OPTIONS.find((o) => o.value === archFilter)?.label ?? "Hide archived";
406
+ }
407
+ function agentArchiveFilterControlLabel(archFilter) {
408
+ return `Archive filter: ${agentArchiveFilterStateLabel(
409
+ archFilter
410
+ ).toLowerCase()}. Click for ${agentArchiveFilterStateLabel(
411
+ nextArchFilter(archFilter)
412
+ ).toLowerCase()}`;
413
+ }
414
+ function agentListFooterLabel(args) {
415
+ const { count, archFilter, archivedHiddenCount } = args;
416
+ if (archFilter === "archived") return `${count} archived shown`;
417
+ const base = `${count} agent${count !== 1 ? "s" : ""}`;
418
+ if (archFilter === "both") return `${base} \xB7 archived shown`;
419
+ return archivedHiddenCount > 0 ? `${base} \xB7 ${archivedHiddenCount} archived hidden` : base;
420
+ }
395
421
 
396
422
  // catalog/score.ts
397
423
  function computeAgentSearchScore(agent, query) {
@@ -582,8 +608,7 @@ function filterUserTypeAgents(agents, consumer) {
582
608
  if (tab === "mine" && agent.isOwner !== true) return false;
583
609
  if (tab === "shared" && !(agent.isOwner === false && agent.accessLevel != null))
584
610
  return false;
585
- if (archFilter === "active" && agent.isArchived) return false;
586
- if (archFilter === "archived" && !agent.isArchived) return false;
611
+ if (!agentMatchesArchiveFilter(agent, archFilter)) return false;
587
612
  if (favFilter === "yes" && !agent.isFavorite) return false;
588
613
  if (favFilter === "no" && agent.isFavorite) return false;
589
614
  if (accessFilter === "owned" && agent.isOwner !== true) return false;
@@ -613,9 +638,10 @@ function filterUserTypeAgents(agents, consumer) {
613
638
  return sortFilteredAgents(filtered, consumer);
614
639
  }
615
640
  function filterBuiltinTypeAgents(agents, consumer) {
616
- const { searchTerm, favFilter, includedCats, includedTags } = consumer;
641
+ const { searchTerm, favFilter, archFilter, includedCats, includedTags } = consumer;
617
642
  const serverMatched = new Set(consumer.serverMatchedIds);
618
643
  const filtered = agents.filter((agent) => {
644
+ if (!agentMatchesArchiveFilter(agent, archFilter)) return false;
619
645
  if (favFilter === "yes" && !agent.isFavorite) return false;
620
646
  if (favFilter === "no" && agent.isFavorite) return false;
621
647
  if (includedCats.length > 0) {
@@ -661,6 +687,15 @@ function agentMatchesArchiveFilter(agent, archFilter) {
661
687
  if (archFilter === "archived") return Boolean(agent.isArchived);
662
688
  return true;
663
689
  }
690
+ function countBuiltinRows(agents, archFilter) {
691
+ let n = 0;
692
+ for (const a of agents) {
693
+ if (a.agentType !== "builtin") continue;
694
+ if (!agentMatchesArchiveFilter(a, archFilter)) continue;
695
+ n += 1;
696
+ }
697
+ return n;
698
+ }
664
699
  function countUserRows(agents, archFilter, predicate) {
665
700
  let n = 0;
666
701
  for (const a of agents) {
@@ -679,7 +714,7 @@ var selectAgentTabCounts = memoize2(
679
714
  mine: countUserRows(agents, archFilter, isOwned),
680
715
  shared: countUserRows(agents, archFilter, isShared),
681
716
  all: countUserRows(agents, archFilter, isAny),
682
- system: selectBuiltinTypeAgents(agents).length
717
+ system: countBuiltinRows(agents, archFilter)
683
718
  })
684
719
  );
685
720
  var selectTotalUserAgentsCount = memoize1(
@@ -692,7 +727,7 @@ var selectTotalSharedAgentsCount = memoize1(
692
727
  (agents) => countUserRows(agents, "active", isShared)
693
728
  );
694
729
  var selectTotalBuiltinAgentsCount = memoize1(
695
- (agents) => selectBuiltinTypeAgents(agents).length
730
+ (agents) => countBuiltinRows(agents, "active")
696
731
  );
697
732
  var selectTotalFavoriteAgentsCount = memoize1(
698
733
  (agents) => countUserRows(agents, "active", isFavorite)
@@ -714,6 +749,7 @@ function useAgentListCore({
714
749
  initialTab,
715
750
  includeSystemInAll = false,
716
751
  visibleTabs,
752
+ initialArchFilter,
717
753
  excludeAgentIds = EMPTY_EXCLUDES,
718
754
  defaultMandateKey
719
755
  }) {
@@ -723,7 +759,10 @@ function useAgentListCore({
723
759
  const [hoveredAgent, setHoveredAgent] = (0, import_react4.useState)(null);
724
760
  const hoverLeaveTimerRef = (0, import_react4.useRef)(null);
725
761
  const defaultTabAppliedRef = (0, import_react4.useRef)(false);
726
- const consumer = useAgentConsumer(consumerId, { unregisterOnUnmount: true });
762
+ const consumer = useAgentConsumer(consumerId, {
763
+ unregisterOnUnmount: true,
764
+ ...initialArchFilter ? { initialArchFilter } : {}
765
+ });
727
766
  const rows = useAgentCatalogRows();
728
767
  const userId = catalog.getUserIdOrNull();
729
768
  const tabCountsForFilter = selectAgentTabCounts(rows, consumer.state.archFilter);
@@ -737,7 +776,20 @@ function useAgentListCore({
737
776
  () => new Set(excludeAgentIds),
738
777
  [excludeAgentIds]
739
778
  );
740
- const agents = excludedAgentIds.size === 0 ? filteredAgents : filteredAgents.filter((agent) => !excludedAgentIds.has(agent.id));
779
+ const applyExcludes = (0, import_react4.useCallback)(
780
+ (list) => excludedAgentIds.size === 0 ? list : list.filter((agent) => !excludedAgentIds.has(agent.id)),
781
+ [excludedAgentIds]
782
+ );
783
+ const agents = applyExcludes(filteredAgents);
784
+ const selectArchivedProbe = (0, import_react4.useMemo)(
785
+ () => makeSelectFilteredAgents(includeSystemInAll),
786
+ [includeSystemInAll]
787
+ );
788
+ const archiveProbeState = (0, import_react4.useMemo)(
789
+ () => ({ ...consumer.state, archFilter: "archived" }),
790
+ [consumer.state]
791
+ );
792
+ const archivedHiddenCount = consumer.archFilter === "active" ? applyExcludes(selectArchivedProbe(rows, archiveProbeState)).length : 0;
741
793
  const status = useAgentCatalogState(selectStatus);
742
794
  const activeAgentId = activeAgentIdOverride ?? null;
743
795
  const pinnedAgent = activeAgentId ? catalog.getAgent(activeAgentId) : void 0;
@@ -824,7 +876,9 @@ function useAgentListCore({
824
876
  },
825
877
  [onSelect, navigateTo, navigate, catalog, consumerId]
826
878
  );
827
- const activeFilterCount = (consumer.sortBy !== "updated-desc" ? 1 : 0) + (consumer.includedCats.length > 0 ? 1 : 0) + (consumer.includedTags.length > 0 ? 1 : 0) + (consumer.favFilter !== "all" ? 1 : 0);
879
+ const activeFilterCount = (consumer.sortBy !== "updated-desc" ? 1 : 0) + (consumer.includedCats.length > 0 ? 1 : 0) + (consumer.includedTags.length > 0 ? 1 : 0) + (consumer.favFilter !== "all" ? 1 : 0) + // The archive filter counts like every other filter, so a list showing
880
+ // archived rows offers the reset control that puts them away again.
881
+ (consumer.archFilter !== consumer.archFilterDefault ? 1 : 0);
828
882
  const handleAgentHover = (0, import_react4.useCallback)(
829
883
  (agent, panelOpen) => {
830
884
  if (panelOpen) return;
@@ -865,8 +919,15 @@ function useAgentListCore({
865
919
  },
866
920
  []
867
921
  );
922
+ const footerLabel = agentListFooterLabel({
923
+ count: agents.length,
924
+ archFilter: consumer.archFilter,
925
+ archivedHiddenCount
926
+ });
868
927
  return {
869
928
  agents,
929
+ archivedHiddenCount,
930
+ footerLabel,
870
931
  isLoading,
871
932
  activeAgentId,
872
933
  pinnedAgent: pinnedAgent ?? null,
@@ -983,6 +1044,18 @@ var SHAPES = {
983
1044
  "M12 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5"
984
1045
  ]
985
1046
  },
1047
+ /**
1048
+ * THE ARCHIVE GLYPH (Lucide `archive`) — the ONE mark of the platform
1049
+ * archive filter, drawn identically in every Matrx client so the control a
1050
+ * person learns on one surface is recognisable on all of them.
1051
+ */
1052
+ archive: {
1053
+ paths: [
1054
+ "M3 3h18a1 1 0 0 1 1 1v3a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1z",
1055
+ "M4 8v11a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8",
1056
+ "M10 12h4"
1057
+ ]
1058
+ },
986
1059
  circleCheck: {
987
1060
  paths: ["m9 12 2 2 4-4"],
988
1061
  circles: [{ cx: 12, cy: 12, r: 10 }]
@@ -1053,6 +1126,7 @@ var ArrowUpDownIcon = makeIcon("arrowUpDown");
1053
1126
  var FolderIcon = makeIcon("folder");
1054
1127
  var TagIcon = makeIcon("tag");
1055
1128
  var RotateCcwIcon = makeIcon("rotateCcw");
1129
+ var ArchiveIcon = makeIcon("archive");
1056
1130
  var LoaderIcon = makeIcon("loader");
1057
1131
  var UsersIcon = makeIcon("users");
1058
1132
  var ClockIcon = makeIcon("clock");
@@ -1110,13 +1184,17 @@ function FilterChip({
1110
1184
  label,
1111
1185
  active,
1112
1186
  focused,
1113
- onClick
1187
+ onClick,
1188
+ ariaLabel,
1189
+ testId
1114
1190
  }) {
1115
1191
  return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
1116
1192
  "button",
1117
1193
  {
1118
1194
  type: "button",
1119
1195
  onClick,
1196
+ ...ariaLabel ? { "aria-label": ariaLabel } : {},
1197
+ ...testId ? { "data-testid": testId } : {},
1120
1198
  className: (0, import_design_system.cn)(
1121
1199
  "inline-flex items-center gap-1 h-6 px-1.5 rounded text-[11px] font-medium shrink-0 transition-colors",
1122
1200
  focused ? "bg-primary/15 text-primary border border-primary/30 ring-1 ring-primary/20" : active ? "bg-primary/10 text-primary border border-primary/20" : "text-muted-foreground hover:text-foreground hover:bg-muted/50 border border-transparent"
@@ -1539,6 +1617,17 @@ function AgentFilterBar({
1539
1617
  }
1540
1618
  }
1541
1619
  ),
1620
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1621
+ FilterChip,
1622
+ {
1623
+ icon: ArchiveIcon,
1624
+ label: agentArchiveFilterChipLabel(consumer.archFilter),
1625
+ active: consumer.archFilter !== consumer.archFilterDefault,
1626
+ ariaLabel: agentArchiveFilterControlLabel(consumer.archFilter),
1627
+ testId: "agent-archive-filter",
1628
+ onClick: () => consumer.setArchFilter(nextArchFilter(consumer.archFilter))
1629
+ }
1630
+ ),
1542
1631
  allCategories.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1543
1632
  FilterChip,
1544
1633
  {
@@ -1738,7 +1827,8 @@ function AgentListContent({
1738
1827
  systemTabLabel,
1739
1828
  pinnedAgent = null,
1740
1829
  defaultRow = null,
1741
- listOpen = false
1830
+ listOpen = false,
1831
+ archivedHiddenCount = 0
1742
1832
  }) {
1743
1833
  const catalog = useAgentCatalog();
1744
1834
  const listScrollRef = (0, import_react6.useRef)(null);
@@ -1876,11 +1966,18 @@ function AgentListContent({
1876
1966
  ] }) }),
1877
1967
  /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "h-px bg-border shrink-0" }),
1878
1968
  /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center justify-between px-2.5 py-1.5 shrink-0", children: [
1879
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "text-[10px] text-muted-foreground tabular-nums", children: [
1880
- agents.length,
1881
- " agent",
1882
- agents.length !== 1 ? "s" : ""
1883
- ] }),
1969
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1970
+ "span",
1971
+ {
1972
+ "data-testid": "agent-list-footer",
1973
+ className: "text-[10px] text-muted-foreground tabular-nums",
1974
+ children: agentListFooterLabel({
1975
+ count: agents.length,
1976
+ archFilter: consumer.archFilter,
1977
+ archivedHiddenCount
1978
+ })
1979
+ }
1980
+ ),
1884
1981
  consumer.searchTerm && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1885
1982
  "button",
1886
1983
  {
@@ -2103,6 +2200,7 @@ function AgentListDropdown({
2103
2200
  const inputRef = (0, import_react7.useRef)(null);
2104
2201
  const {
2105
2202
  agents,
2203
+ archivedHiddenCount,
2106
2204
  isLoading,
2107
2205
  activeAgentId,
2108
2206
  pinnedAgent,
@@ -2238,6 +2336,7 @@ function AgentListDropdown({
2238
2336
  onFilterChipClick: handleFilterChipClick,
2239
2337
  rightPanel,
2240
2338
  tabCounts,
2339
+ archivedHiddenCount,
2241
2340
  ...visibleTabs ? { visibleTabs } : {},
2242
2341
  ...systemTabLabel ?? (includeSystemInAll ? "System" : void 0) ? {
2243
2342
  systemTabLabel: systemTabLabel ?? (includeSystemInAll ? "System" : void 0)
@@ -2394,6 +2493,7 @@ function AgentListInlinePicker({
2394
2493
  const [mobileSubView, setMobileSubView] = (0, import_react8.useState)(null);
2395
2494
  const {
2396
2495
  agents,
2496
+ archivedHiddenCount,
2397
2497
  isLoading,
2398
2498
  allCategories,
2399
2499
  allTags,
@@ -2500,6 +2600,7 @@ function AgentListInlinePicker({
2500
2600
  onFilterChipClick: handleFilterChipClick,
2501
2601
  rightPanel: null,
2502
2602
  tabCounts,
2603
+ archivedHiddenCount,
2503
2604
  ...visibleTabs ? { visibleTabs } : {},
2504
2605
  ...systemTabLabel ?? (includeSystemInAll ? "System" : void 0) ? {
2505
2606
  systemTabLabel: systemTabLabel ?? (includeSystemInAll ? "System" : void 0)