@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.
@@ -1,7 +1,7 @@
1
1
  import * as react from 'react';
2
2
  import { ComponentType, ReactNode } from 'react';
3
- import { t as AgentCatalogNavigate, v as AgentCatalogOpenPeek, n as AgentCatalog, A as AgentSummary, z as AgentCatalogState, f as AgentTab, j as AgentSortOption, E as AgentFavFilter, i as AgentArchFilter, l as AgentAccessFilter, h as AgentConsumerState, J as DefaultRowState } from '../../orchestra-CID-rsu8.cjs';
4
- export { O as OrchestraBadge, W as orchestraDelegatesLine, X as orchestraDepthLine, Y as orchestraLabel, Z as orchestraModeLabel } from '../../orchestra-CID-rsu8.cjs';
3
+ import { x as AgentCatalogNavigate, z as AgentCatalogOpenPeek, q as AgentCatalog, A as AgentSummary, E as AgentCatalogState, g as AgentTab, j as AgentSortOption, I as AgentFavFilter, f as AgentArchFilter, n as AgentAccessFilter, i as AgentConsumerState, O as DefaultRowState } from '../../orchestra-DljbEiks.cjs';
4
+ export { P as OrchestraBadge, a0 as orchestraDelegatesLine, a1 as orchestraDepthLine, a2 as orchestraLabel, a3 as orchestraModeLabel } from '../../orchestra-DljbEiks.cjs';
5
5
 
6
6
  /**
7
7
  * The anchor a row renders for cmd/ctrl-click. DEFAULT (web): a plain `<a>` —
@@ -249,6 +249,13 @@ interface UseAgentConsumerReturn {
249
249
  includedTags: string[];
250
250
  favFilter: AgentFavFilter;
251
251
  archFilter: AgentArchFilter;
252
+ /**
253
+ * The archive-filter state this catalog starts consumers in — the platform
254
+ * default `"active"` unless the host set the knob. What "not the default
255
+ * state" means on this surface, so the control and the footer can both say
256
+ * it honestly.
257
+ */
258
+ archFilterDefault: AgentArchFilter;
252
259
  accessFilter: AgentAccessFilter;
253
260
  favoritesFirst: boolean;
254
261
  listPage: number;
@@ -295,6 +302,12 @@ declare function useAgentConsumer(consumerId: string, options?: {
295
302
  unregisterOnUnmount?: boolean;
296
303
  /** Applied only when the consumer is first registered (idempotent). */
297
304
  initialTab?: AgentTab;
305
+ /**
306
+ * THE ARCHIVED-ITEMS LAW's per-consumer override of the catalog-wide
307
+ * `defaults.archiveFilter` knob. Applied only at first registration — the
308
+ * state belongs to the person after that.
309
+ */
310
+ initialArchFilter?: AgentArchFilter;
298
311
  }): UseAgentConsumerReturn;
299
312
 
300
313
  /**
@@ -349,6 +362,13 @@ interface AgentListCoreOptions {
349
362
  * not just at mount — so a restriction that arrives later is enforced later.
350
363
  */
351
364
  visibleTabs?: readonly AgentTab[];
365
+ /**
366
+ * THE ARCHIVED-ITEMS LAW's per-consumer override of the catalog-wide
367
+ * `defaults.archiveFilter` knob, applied once at first registration. Almost
368
+ * nothing should pass it: the platform answer is "hide archived", and the
369
+ * person reveals the archive from the control on the filter bar.
370
+ */
371
+ initialArchFilter?: AgentArchFilter;
352
372
  /** Hide records that are invalid for this call site. */
353
373
  excludeAgentIds?: readonly string[];
354
374
  /**
@@ -374,8 +394,10 @@ declare const HOVER_GRACE_MS = 900;
374
394
  * else the first allowed tab.
375
395
  */
376
396
  declare function coerceVisibleTab(current: AgentTab, allowed: readonly AgentTab[], initialTab?: AgentTab): AgentTab | null;
377
- declare function useAgentListCore({ consumerId, onSelect, navigateTo, activeAgentIdOverride, initialTab, includeSystemInAll, visibleTabs, excludeAgentIds, defaultMandateKey, }: AgentListCoreOptions): {
397
+ declare function useAgentListCore({ consumerId, onSelect, navigateTo, activeAgentIdOverride, initialTab, includeSystemInAll, visibleTabs, initialArchFilter, excludeAgentIds, defaultMandateKey, }: AgentListCoreOptions): {
378
398
  agents: AgentSummary[];
399
+ archivedHiddenCount: number;
400
+ footerLabel: string;
379
401
  isLoading: boolean;
380
402
  activeAgentId: string | null;
381
403
  pinnedAgent: AgentSummary | null;
@@ -413,8 +435,13 @@ interface AgentListContentProps {
413
435
  pinnedAgent?: AgentSummary | null | undefined;
414
436
  defaultRow?: DefaultRowState | null | undefined;
415
437
  autoFocusSearch?: boolean;
438
+ /**
439
+ * Rows the ARCHIVE FILTER is keeping off this screen — from
440
+ * `useAgentListCore`. The footer names them, exactly as on the web.
441
+ */
442
+ archivedHiddenCount?: number | undefined;
416
443
  }
417
- declare function AgentListContent({ agents, isLoading, consumer, activeAgentId, allCategories, allTags, onSelectAgent, onDetailPress, onFilterChipPress, onReset, activeFilterCount, tabCounts, visibleTabs, systemTabLabel, pinnedAgent, defaultRow, autoFocusSearch, }: AgentListContentProps): react.JSX.Element;
444
+ declare function AgentListContent({ agents, isLoading, consumer, activeAgentId, allCategories, allTags, onSelectAgent, onDetailPress, onFilterChipPress, onReset, activeFilterCount, tabCounts, visibleTabs, systemTabLabel, pinnedAgent, defaultRow, autoFocusSearch, archivedHiddenCount, }: AgentListContentProps): react.JSX.Element;
418
445
 
419
446
  interface AgentListTabsProps {
420
447
  consumer: UseAgentConsumerReturn;
@@ -570,6 +597,14 @@ declare const SHAPES: {
570
597
  rocket: {
571
598
  paths: string[];
572
599
  };
600
+ /**
601
+ * THE ARCHIVE GLYPH (Lucide `archive`) — the ONE mark of the platform
602
+ * archive filter, drawn identically in every Matrx client so the control a
603
+ * person learns on one surface is recognisable on all of them.
604
+ */
605
+ archive: {
606
+ paths: string[];
607
+ };
573
608
  circleCheck: {
574
609
  paths: string[];
575
610
  circles: {
@@ -636,11 +671,15 @@ declare function SearchInput({ value, onChange, placeholder, autoFocus, }: {
636
671
  placeholder: string;
637
672
  autoFocus?: boolean;
638
673
  }): react.JSX.Element;
639
- declare function FilterChip({ icon, label, active, onPress, }: {
674
+ declare function FilterChip({ icon, label, active, onPress, accessibilityLabel, testID, }: {
640
675
  icon: AgentCatalogIconName;
641
676
  label: string;
642
677
  active: boolean;
643
678
  onPress: () => void;
679
+ /** Accessible name when the visible label alone would not say the state. */
680
+ accessibilityLabel?: string;
681
+ /** Stable hook so a shell test can measure the control, not a style. */
682
+ testID?: string;
644
683
  }): react.JSX.Element;
645
684
  declare function OptionRow({ label, selected, onPress, }: {
646
685
  label: string;
@@ -1,7 +1,7 @@
1
1
  import * as react from 'react';
2
2
  import { ComponentType, ReactNode } from 'react';
3
- import { t as AgentCatalogNavigate, v as AgentCatalogOpenPeek, n as AgentCatalog, A as AgentSummary, z as AgentCatalogState, f as AgentTab, j as AgentSortOption, E as AgentFavFilter, i as AgentArchFilter, l as AgentAccessFilter, h as AgentConsumerState, J as DefaultRowState } from '../../orchestra-CID-rsu8.js';
4
- export { O as OrchestraBadge, W as orchestraDelegatesLine, X as orchestraDepthLine, Y as orchestraLabel, Z as orchestraModeLabel } from '../../orchestra-CID-rsu8.js';
3
+ import { x as AgentCatalogNavigate, z as AgentCatalogOpenPeek, q as AgentCatalog, A as AgentSummary, E as AgentCatalogState, g as AgentTab, j as AgentSortOption, I as AgentFavFilter, f as AgentArchFilter, n as AgentAccessFilter, i as AgentConsumerState, O as DefaultRowState } from '../../orchestra-DljbEiks.js';
4
+ export { P as OrchestraBadge, a0 as orchestraDelegatesLine, a1 as orchestraDepthLine, a2 as orchestraLabel, a3 as orchestraModeLabel } from '../../orchestra-DljbEiks.js';
5
5
 
6
6
  /**
7
7
  * The anchor a row renders for cmd/ctrl-click. DEFAULT (web): a plain `<a>` —
@@ -249,6 +249,13 @@ interface UseAgentConsumerReturn {
249
249
  includedTags: string[];
250
250
  favFilter: AgentFavFilter;
251
251
  archFilter: AgentArchFilter;
252
+ /**
253
+ * The archive-filter state this catalog starts consumers in — the platform
254
+ * default `"active"` unless the host set the knob. What "not the default
255
+ * state" means on this surface, so the control and the footer can both say
256
+ * it honestly.
257
+ */
258
+ archFilterDefault: AgentArchFilter;
252
259
  accessFilter: AgentAccessFilter;
253
260
  favoritesFirst: boolean;
254
261
  listPage: number;
@@ -295,6 +302,12 @@ declare function useAgentConsumer(consumerId: string, options?: {
295
302
  unregisterOnUnmount?: boolean;
296
303
  /** Applied only when the consumer is first registered (idempotent). */
297
304
  initialTab?: AgentTab;
305
+ /**
306
+ * THE ARCHIVED-ITEMS LAW's per-consumer override of the catalog-wide
307
+ * `defaults.archiveFilter` knob. Applied only at first registration — the
308
+ * state belongs to the person after that.
309
+ */
310
+ initialArchFilter?: AgentArchFilter;
298
311
  }): UseAgentConsumerReturn;
299
312
 
300
313
  /**
@@ -349,6 +362,13 @@ interface AgentListCoreOptions {
349
362
  * not just at mount — so a restriction that arrives later is enforced later.
350
363
  */
351
364
  visibleTabs?: readonly AgentTab[];
365
+ /**
366
+ * THE ARCHIVED-ITEMS LAW's per-consumer override of the catalog-wide
367
+ * `defaults.archiveFilter` knob, applied once at first registration. Almost
368
+ * nothing should pass it: the platform answer is "hide archived", and the
369
+ * person reveals the archive from the control on the filter bar.
370
+ */
371
+ initialArchFilter?: AgentArchFilter;
352
372
  /** Hide records that are invalid for this call site. */
353
373
  excludeAgentIds?: readonly string[];
354
374
  /**
@@ -374,8 +394,10 @@ declare const HOVER_GRACE_MS = 900;
374
394
  * else the first allowed tab.
375
395
  */
376
396
  declare function coerceVisibleTab(current: AgentTab, allowed: readonly AgentTab[], initialTab?: AgentTab): AgentTab | null;
377
- declare function useAgentListCore({ consumerId, onSelect, navigateTo, activeAgentIdOverride, initialTab, includeSystemInAll, visibleTabs, excludeAgentIds, defaultMandateKey, }: AgentListCoreOptions): {
397
+ declare function useAgentListCore({ consumerId, onSelect, navigateTo, activeAgentIdOverride, initialTab, includeSystemInAll, visibleTabs, initialArchFilter, excludeAgentIds, defaultMandateKey, }: AgentListCoreOptions): {
378
398
  agents: AgentSummary[];
399
+ archivedHiddenCount: number;
400
+ footerLabel: string;
379
401
  isLoading: boolean;
380
402
  activeAgentId: string | null;
381
403
  pinnedAgent: AgentSummary | null;
@@ -413,8 +435,13 @@ interface AgentListContentProps {
413
435
  pinnedAgent?: AgentSummary | null | undefined;
414
436
  defaultRow?: DefaultRowState | null | undefined;
415
437
  autoFocusSearch?: boolean;
438
+ /**
439
+ * Rows the ARCHIVE FILTER is keeping off this screen — from
440
+ * `useAgentListCore`. The footer names them, exactly as on the web.
441
+ */
442
+ archivedHiddenCount?: number | undefined;
416
443
  }
417
- declare function AgentListContent({ agents, isLoading, consumer, activeAgentId, allCategories, allTags, onSelectAgent, onDetailPress, onFilterChipPress, onReset, activeFilterCount, tabCounts, visibleTabs, systemTabLabel, pinnedAgent, defaultRow, autoFocusSearch, }: AgentListContentProps): react.JSX.Element;
444
+ declare function AgentListContent({ agents, isLoading, consumer, activeAgentId, allCategories, allTags, onSelectAgent, onDetailPress, onFilterChipPress, onReset, activeFilterCount, tabCounts, visibleTabs, systemTabLabel, pinnedAgent, defaultRow, autoFocusSearch, archivedHiddenCount, }: AgentListContentProps): react.JSX.Element;
418
445
 
419
446
  interface AgentListTabsProps {
420
447
  consumer: UseAgentConsumerReturn;
@@ -570,6 +597,14 @@ declare const SHAPES: {
570
597
  rocket: {
571
598
  paths: string[];
572
599
  };
600
+ /**
601
+ * THE ARCHIVE GLYPH (Lucide `archive`) — the ONE mark of the platform
602
+ * archive filter, drawn identically in every Matrx client so the control a
603
+ * person learns on one surface is recognisable on all of them.
604
+ */
605
+ archive: {
606
+ paths: string[];
607
+ };
573
608
  circleCheck: {
574
609
  paths: string[];
575
610
  circles: {
@@ -636,11 +671,15 @@ declare function SearchInput({ value, onChange, placeholder, autoFocus, }: {
636
671
  placeholder: string;
637
672
  autoFocus?: boolean;
638
673
  }): react.JSX.Element;
639
- declare function FilterChip({ icon, label, active, onPress, }: {
674
+ declare function FilterChip({ icon, label, active, onPress, accessibilityLabel, testID, }: {
640
675
  icon: AgentCatalogIconName;
641
676
  label: string;
642
677
  active: boolean;
643
678
  onPress: () => void;
679
+ /** Accessible name when the visible label alone would not say the state. */
680
+ accessibilityLabel?: string;
681
+ /** Stable hook so a shell test can measure the control, not a style. */
682
+ testID?: string;
644
683
  }): react.JSX.Element;
645
684
  declare function OptionRow({ label, selected, onPress, }: {
646
685
  label: string;
@@ -229,53 +229,27 @@ import {
229
229
 
230
230
  // catalog/shared/useAgentConsumer.ts
231
231
  import { useCallback as useCallback2, useEffect, useRef, useState } from "react";
232
-
233
- // catalog/types.ts
234
- function isMandateAgentId(id) {
235
- return id.startsWith("mandate:");
236
- }
237
- var SORT_OPTIONS = [
238
- { value: "updated-desc", label: "Recent" },
239
- { value: "created-desc", label: "Created" },
240
- { value: "name-asc", label: "A \u2192 Z" },
241
- { value: "name-desc", label: "Z \u2192 A" },
242
- { value: "category-asc", label: "Category" }
243
- ];
244
- var AGENT_NONE_SENTINEL = "__none__";
245
- var DEFAULT_AGENT_CONSUMER_STATE = {
246
- tab: "mine",
247
- sortBy: "updated-desc",
248
- searchTerm: "",
249
- includedCats: [],
250
- includedTags: [],
251
- favFilter: "all",
252
- archFilter: "active",
253
- accessFilter: "any",
254
- favoritesFirst: true,
255
- listPage: 1,
256
- sharedPage: 1,
257
- serverMatchedIds: [],
258
- isServerSearching: false,
259
- deepSearch: false
260
- };
261
-
262
- // catalog/shared/useAgentConsumer.ts
263
232
  var DEBOUNCE_MS = 250;
264
233
  var MIN_QUERY_LENGTH = 2;
265
234
  function useAgentConsumer(consumerId, options) {
266
235
  const catalog = useAgentCatalog();
236
+ const defaults = catalog.consumerDefaults;
267
237
  const selectConsumer = useCallback2(
268
- (state) => state.consumers[consumerId] ?? DEFAULT_AGENT_CONSUMER_STATE,
269
- [consumerId]
238
+ (state) => state.consumers[consumerId] ?? defaults,
239
+ [consumerId, defaults]
270
240
  );
271
241
  const consumer = useAgentCatalogState(selectConsumer);
272
242
  const optionsRef = useRef(options);
273
243
  optionsRef.current = options;
274
244
  useEffect(() => {
275
245
  const opts = optionsRef.current;
246
+ const initial = {
247
+ ...opts?.initialTab ? { tab: opts.initialTab } : {},
248
+ ...opts?.initialArchFilter ? { archFilter: opts.initialArchFilter } : {}
249
+ };
276
250
  catalog.registerConsumer(
277
251
  consumerId,
278
- opts?.initialTab ? { tab: opts.initialTab } : void 0
252
+ Object.keys(initial).length > 0 ? initial : void 0
279
253
  );
280
254
  return () => {
281
255
  if (optionsRef.current?.unregisterOnUnmount) {
@@ -398,7 +372,10 @@ function useAgentConsumer(consumerId, options) {
398
372
  isSearching
399
373
  });
400
374
  }, [consumerId, catalog, matchedIds, isSearching]);
401
- const hasActiveFilters = consumer.searchTerm !== "" || consumer.includedCats.length > 0 || consumer.includedTags.length > 0 || consumer.favFilter !== "all" || consumer.archFilter !== "active" || consumer.accessFilter !== "any" || !consumer.favoritesFirst;
375
+ 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
376
+ // hardcoded platform one: a host that legitimately defaults to "show all"
377
+ // must not have the reset control permanently lit.
378
+ consumer.archFilter !== defaults.archFilter || consumer.accessFilter !== "any" || !consumer.favoritesFirst;
402
379
  return {
403
380
  tab: consumer.tab,
404
381
  sortBy: consumer.sortBy,
@@ -407,6 +384,7 @@ function useAgentConsumer(consumerId, options) {
407
384
  includedTags: consumer.includedTags,
408
385
  favFilter: consumer.favFilter,
409
386
  archFilter: consumer.archFilter,
387
+ archFilterDefault: defaults.archFilter,
410
388
  accessFilter: consumer.accessFilter,
411
389
  favoritesFirst: consumer.favoritesFirst,
412
390
  listPage: consumer.listPage,
@@ -433,6 +411,34 @@ function useAgentConsumer(consumerId, options) {
433
411
  };
434
412
  }
435
413
 
414
+ // catalog/types.ts
415
+ function isMandateAgentId(id) {
416
+ return id.startsWith("mandate:");
417
+ }
418
+ var SORT_OPTIONS = [
419
+ { value: "updated-desc", label: "Recent" },
420
+ { value: "created-desc", label: "Created" },
421
+ { value: "name-asc", label: "A \u2192 Z" },
422
+ { value: "name-desc", label: "Z \u2192 A" },
423
+ { value: "category-asc", label: "Category" }
424
+ ];
425
+ var ARCHIVE_FILTER_ORDER = [
426
+ "active",
427
+ "both",
428
+ "archived"
429
+ ];
430
+ var ARCHIVE_FILTER_OPTIONS = [
431
+ { value: "active", label: "Hide archived", chip: "Archive" },
432
+ { value: "both", label: "Show all", chip: "All + archived" },
433
+ { value: "archived", label: "Archived only", chip: "Archived only" }
434
+ ];
435
+ function nextArchFilter(current) {
436
+ const index = ARCHIVE_FILTER_ORDER.indexOf(current);
437
+ if (index < 0) return ARCHIVE_FILTER_ORDER[0];
438
+ return ARCHIVE_FILTER_ORDER[(index + 1) % ARCHIVE_FILTER_ORDER.length];
439
+ }
440
+ var AGENT_NONE_SENTINEL = "__none__";
441
+
436
442
  // catalog/labels.ts
437
443
  function agentListEmptyLabel(tab, labels) {
438
444
  switch (tab) {
@@ -449,6 +455,26 @@ function shouldDefaultAgentListToPublicTab(args) {
449
455
  if (!args.agentsLoaded) return false;
450
456
  return args.ownedCount === 0;
451
457
  }
458
+ function agentArchiveFilterChipLabel(archFilter) {
459
+ return ARCHIVE_FILTER_OPTIONS.find((o) => o.value === archFilter)?.chip ?? "Archive";
460
+ }
461
+ function agentArchiveFilterStateLabel(archFilter) {
462
+ return ARCHIVE_FILTER_OPTIONS.find((o) => o.value === archFilter)?.label ?? "Hide archived";
463
+ }
464
+ function agentArchiveFilterControlLabel(archFilter) {
465
+ return `Archive filter: ${agentArchiveFilterStateLabel(
466
+ archFilter
467
+ ).toLowerCase()}. Click for ${agentArchiveFilterStateLabel(
468
+ nextArchFilter(archFilter)
469
+ ).toLowerCase()}`;
470
+ }
471
+ function agentListFooterLabel(args) {
472
+ const { count, archFilter, archivedHiddenCount } = args;
473
+ if (archFilter === "archived") return `${count} archived shown`;
474
+ const base = `${count} agent${count !== 1 ? "s" : ""}`;
475
+ if (archFilter === "both") return `${base} \xB7 archived shown`;
476
+ return archivedHiddenCount > 0 ? `${base} \xB7 ${archivedHiddenCount} archived hidden` : base;
477
+ }
452
478
 
453
479
  // catalog/score.ts
454
480
  function computeAgentSearchScore(agent, query) {
@@ -639,8 +665,7 @@ function filterUserTypeAgents(agents, consumer) {
639
665
  if (tab === "mine" && agent.isOwner !== true) return false;
640
666
  if (tab === "shared" && !(agent.isOwner === false && agent.accessLevel != null))
641
667
  return false;
642
- if (archFilter === "active" && agent.isArchived) return false;
643
- if (archFilter === "archived" && !agent.isArchived) return false;
668
+ if (!agentMatchesArchiveFilter(agent, archFilter)) return false;
644
669
  if (favFilter === "yes" && !agent.isFavorite) return false;
645
670
  if (favFilter === "no" && agent.isFavorite) return false;
646
671
  if (accessFilter === "owned" && agent.isOwner !== true) return false;
@@ -670,9 +695,10 @@ function filterUserTypeAgents(agents, consumer) {
670
695
  return sortFilteredAgents(filtered, consumer);
671
696
  }
672
697
  function filterBuiltinTypeAgents(agents, consumer) {
673
- const { searchTerm, favFilter, includedCats, includedTags } = consumer;
698
+ const { searchTerm, favFilter, archFilter, includedCats, includedTags } = consumer;
674
699
  const serverMatched = new Set(consumer.serverMatchedIds);
675
700
  const filtered = agents.filter((agent) => {
701
+ if (!agentMatchesArchiveFilter(agent, archFilter)) return false;
676
702
  if (favFilter === "yes" && !agent.isFavorite) return false;
677
703
  if (favFilter === "no" && agent.isFavorite) return false;
678
704
  if (includedCats.length > 0) {
@@ -718,6 +744,15 @@ function agentMatchesArchiveFilter(agent, archFilter) {
718
744
  if (archFilter === "archived") return Boolean(agent.isArchived);
719
745
  return true;
720
746
  }
747
+ function countBuiltinRows(agents, archFilter) {
748
+ let n = 0;
749
+ for (const a of agents) {
750
+ if (a.agentType !== "builtin") continue;
751
+ if (!agentMatchesArchiveFilter(a, archFilter)) continue;
752
+ n += 1;
753
+ }
754
+ return n;
755
+ }
721
756
  function countUserRows(agents, archFilter, predicate) {
722
757
  let n = 0;
723
758
  for (const a of agents) {
@@ -736,7 +771,7 @@ var selectAgentTabCounts = memoize2(
736
771
  mine: countUserRows(agents, archFilter, isOwned),
737
772
  shared: countUserRows(agents, archFilter, isShared),
738
773
  all: countUserRows(agents, archFilter, isAny),
739
- system: selectBuiltinTypeAgents(agents).length
774
+ system: countBuiltinRows(agents, archFilter)
740
775
  })
741
776
  );
742
777
  var selectTotalUserAgentsCount = memoize1(
@@ -749,7 +784,7 @@ var selectTotalSharedAgentsCount = memoize1(
749
784
  (agents) => countUserRows(agents, "active", isShared)
750
785
  );
751
786
  var selectTotalBuiltinAgentsCount = memoize1(
752
- (agents) => selectBuiltinTypeAgents(agents).length
787
+ (agents) => countBuiltinRows(agents, "active")
753
788
  );
754
789
  var selectTotalFavoriteAgentsCount = memoize1(
755
790
  (agents) => countUserRows(agents, "active", isFavorite)
@@ -771,6 +806,7 @@ function useAgentListCore({
771
806
  initialTab,
772
807
  includeSystemInAll = false,
773
808
  visibleTabs,
809
+ initialArchFilter,
774
810
  excludeAgentIds = EMPTY_EXCLUDES,
775
811
  defaultMandateKey
776
812
  }) {
@@ -780,7 +816,10 @@ function useAgentListCore({
780
816
  const [hoveredAgent, setHoveredAgent] = useState2(null);
781
817
  const hoverLeaveTimerRef = useRef2(null);
782
818
  const defaultTabAppliedRef = useRef2(false);
783
- const consumer = useAgentConsumer(consumerId, { unregisterOnUnmount: true });
819
+ const consumer = useAgentConsumer(consumerId, {
820
+ unregisterOnUnmount: true,
821
+ ...initialArchFilter ? { initialArchFilter } : {}
822
+ });
784
823
  const rows = useAgentCatalogRows();
785
824
  const userId = catalog.getUserIdOrNull();
786
825
  const tabCountsForFilter = selectAgentTabCounts(rows, consumer.state.archFilter);
@@ -794,7 +833,20 @@ function useAgentListCore({
794
833
  () => new Set(excludeAgentIds),
795
834
  [excludeAgentIds]
796
835
  );
797
- const agents = excludedAgentIds.size === 0 ? filteredAgents : filteredAgents.filter((agent) => !excludedAgentIds.has(agent.id));
836
+ const applyExcludes = useCallback3(
837
+ (list) => excludedAgentIds.size === 0 ? list : list.filter((agent) => !excludedAgentIds.has(agent.id)),
838
+ [excludedAgentIds]
839
+ );
840
+ const agents = applyExcludes(filteredAgents);
841
+ const selectArchivedProbe = useMemo3(
842
+ () => makeSelectFilteredAgents(includeSystemInAll),
843
+ [includeSystemInAll]
844
+ );
845
+ const archiveProbeState = useMemo3(
846
+ () => ({ ...consumer.state, archFilter: "archived" }),
847
+ [consumer.state]
848
+ );
849
+ const archivedHiddenCount = consumer.archFilter === "active" ? applyExcludes(selectArchivedProbe(rows, archiveProbeState)).length : 0;
798
850
  const status = useAgentCatalogState(selectStatus);
799
851
  const activeAgentId = activeAgentIdOverride ?? null;
800
852
  const pinnedAgent = activeAgentId ? catalog.getAgent(activeAgentId) : void 0;
@@ -881,7 +933,9 @@ function useAgentListCore({
881
933
  },
882
934
  [onSelect, navigateTo, navigate, catalog, consumerId]
883
935
  );
884
- 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);
936
+ 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
937
+ // archived rows offers the reset control that puts them away again.
938
+ (consumer.archFilter !== consumer.archFilterDefault ? 1 : 0);
885
939
  const handleAgentHover = useCallback3(
886
940
  (agent, panelOpen) => {
887
941
  if (panelOpen) return;
@@ -922,8 +976,15 @@ function useAgentListCore({
922
976
  },
923
977
  []
924
978
  );
979
+ const footerLabel = agentListFooterLabel({
980
+ count: agents.length,
981
+ archFilter: consumer.archFilter,
982
+ archivedHiddenCount
983
+ });
925
984
  return {
926
985
  agents,
986
+ archivedHiddenCount,
987
+ footerLabel,
927
988
  isLoading,
928
989
  activeAgentId,
929
990
  pinnedAgent: pinnedAgent ?? null,
@@ -1066,6 +1127,18 @@ var SHAPES = {
1066
1127
  "M12 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5"
1067
1128
  ]
1068
1129
  },
1130
+ /**
1131
+ * THE ARCHIVE GLYPH (Lucide `archive`) — the ONE mark of the platform
1132
+ * archive filter, drawn identically in every Matrx client so the control a
1133
+ * person learns on one surface is recognisable on all of them.
1134
+ */
1135
+ archive: {
1136
+ paths: [
1137
+ "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",
1138
+ "M4 8v11a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8",
1139
+ "M10 12h4"
1140
+ ]
1141
+ },
1069
1142
  circleCheck: {
1070
1143
  paths: ["m9 12 2 2 4-4"],
1071
1144
  circles: [{ cx: 12, cy: 12, r: 10 }]
@@ -1135,6 +1208,7 @@ var TEXT_GLYPHS = {
1135
1208
  folder: "\u25A4",
1136
1209
  tag: "\u2317",
1137
1210
  rotateCcw: "\u21BA",
1211
+ archive: "\u25A3",
1138
1212
  loader: "\u25CC",
1139
1213
  alertTriangle: "\u26A0",
1140
1214
  music4: "\u266A",
@@ -1648,7 +1722,9 @@ function FilterChip({
1648
1722
  icon,
1649
1723
  label,
1650
1724
  active,
1651
- onPress
1725
+ onPress,
1726
+ accessibilityLabel,
1727
+ testID
1652
1728
  }) {
1653
1729
  const theme = useAgentCatalogNativeTheme();
1654
1730
  const { errorSink } = useAgentCatalog();
@@ -1659,7 +1735,8 @@ function FilterChip({
1659
1735
  onPress,
1660
1736
  accessibilityRole: "button",
1661
1737
  accessibilityState: { selected: active },
1662
- accessibilityLabel: label,
1738
+ accessibilityLabel: accessibilityLabel ?? label,
1739
+ ...testID ? { testID } : {},
1663
1740
  style: ({ pressed }) => [
1664
1741
  styles2.chip,
1665
1742
  {
@@ -1918,6 +1995,17 @@ function AgentFilterBar({
1918
1995
  }
1919
1996
  }
1920
1997
  ),
1998
+ /* @__PURE__ */ jsx7(
1999
+ FilterChip,
2000
+ {
2001
+ icon: "archive",
2002
+ label: agentArchiveFilterChipLabel(consumer.archFilter),
2003
+ active: consumer.archFilter !== consumer.archFilterDefault,
2004
+ accessibilityLabel: agentArchiveFilterControlLabel(consumer.archFilter),
2005
+ testID: "agent-archive-filter",
2006
+ onPress: () => consumer.setArchFilter(nextArchFilter(consumer.archFilter))
2007
+ }
2008
+ ),
1921
2009
  allCategories.length > 0 && /* @__PURE__ */ jsx7(
1922
2010
  FilterChip,
1923
2011
  {
@@ -2264,7 +2352,8 @@ function AgentListContent({
2264
2352
  systemTabLabel,
2265
2353
  pinnedAgent = null,
2266
2354
  defaultRow = null,
2267
- autoFocusSearch = false
2355
+ autoFocusSearch = false,
2356
+ archivedHiddenCount = 0
2268
2357
  }) {
2269
2358
  const catalog = useAgentCatalog();
2270
2359
  const theme = useAgentCatalogNativeTheme();
@@ -2492,19 +2581,20 @@ function AgentListContent({
2492
2581
  ),
2493
2582
  /* @__PURE__ */ jsx10(View4, { style: hairline }),
2494
2583
  /* @__PURE__ */ jsxs7(View4, { style: [styles6.footer, { paddingHorizontal: theme.spacing.md }], children: [
2495
- /* @__PURE__ */ jsxs7(
2584
+ /* @__PURE__ */ jsx10(
2496
2585
  Text7,
2497
2586
  {
2587
+ testID: "agent-list-footer",
2498
2588
  style: {
2499
2589
  color: theme.colors.textMuted,
2500
2590
  fontSize: theme.fontSize.xs,
2501
2591
  fontVariant: ["tabular-nums"]
2502
2592
  },
2503
- children: [
2504
- agents.length,
2505
- " agent",
2506
- agents.length !== 1 ? "s" : ""
2507
- ]
2593
+ children: agentListFooterLabel({
2594
+ count: agents.length,
2595
+ archFilter: consumer.archFilter,
2596
+ archivedHiddenCount
2597
+ })
2508
2598
  }
2509
2599
  ),
2510
2600
  consumer.searchTerm.length > 0 && /* @__PURE__ */ jsx10(
@@ -2671,6 +2761,7 @@ function AgentPickerBody({
2671
2761
  const [panelSearch, setPanelSearch] = useState3("");
2672
2762
  const {
2673
2763
  agents,
2764
+ archivedHiddenCount,
2674
2765
  isLoading,
2675
2766
  allCategories,
2676
2767
  allTags,
@@ -2742,6 +2833,7 @@ function AgentPickerBody({
2742
2833
  onReset: consumer.resetFilters,
2743
2834
  activeFilterCount,
2744
2835
  tabCounts,
2836
+ archivedHiddenCount,
2745
2837
  ...visibleTabs ? { visibleTabs } : {},
2746
2838
  ...systemTabLabel ?? (includeSystemInAll ? "System" : void 0) ? {
2747
2839
  systemTabLabel: systemTabLabel ?? (includeSystemInAll ? "System" : void 0)