@ai-matrx/agents 0.9.0 → 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.
@@ -131,7 +131,25 @@ declare const SORT_OPTIONS: {
131
131
  type AgentTab = "mine" | "shared" | "all" | "system";
132
132
  /** Favorite filter. */
133
133
  type AgentFavFilter = "all" | "yes" | "no";
134
- /** Archive filter. */
134
+ /**
135
+ * The archive filter — THE ARCHIVED-ITEMS LAW's ONE control, in this
136
+ * package's existing vocabulary.
137
+ *
138
+ * > "everything should have an archive filter, and the default should always
139
+ * > hide archived, but seeing archived items should be one or two clicks
140
+ * > away." — Arman, 2026-09-09 (`common-docs/policies/archived-items.md`)
141
+ *
142
+ * Three states and no more, identical for every entity on the platform:
143
+ *
144
+ * | value | the platform's words | what the list shows |
145
+ * |------------|----------------------|--------------------------|
146
+ * | `active` | hide archived | only un-archived rows |
147
+ * | `both` | show all | every row |
148
+ * | `archived` | archived only | only archived rows |
149
+ *
150
+ * `active` is the platform default, and it is a KNOB — see
151
+ * `AgentCatalogConfig.defaults.archiveFilter`.
152
+ */
135
153
  type AgentArchFilter = "active" | "archived" | "both";
136
154
  /**
137
155
  * Access level filter.
@@ -377,6 +395,14 @@ interface AgentCatalog {
377
395
  readonly notifier: AgentCatalogNotifier | undefined;
378
396
  /** True when this catalog was given a transport and can resolve mandates. */
379
397
  readonly canResolveMandates: boolean;
398
+ /**
399
+ * The consumer state a brand-new consumer starts from, AFTER the host's
400
+ * `defaults` knob is applied. Read it instead of
401
+ * `DEFAULT_AGENT_CONSUMER_STATE` whenever the question is "is this filter at
402
+ * its default?" — a host that legitimately defaults the archive filter to
403
+ * "show all" must not have every control render as though it were modified.
404
+ */
405
+ readonly consumerDefaults: AgentConsumerState;
380
406
  getState(): AgentCatalogState;
381
407
  subscribe(listener: () => void): () => void;
382
408
  getAgent(agentId: string): AgentSummary | undefined;
@@ -515,6 +541,13 @@ interface UseAgentConsumerReturn {
515
541
  includedTags: string[];
516
542
  favFilter: AgentFavFilter;
517
543
  archFilter: AgentArchFilter;
544
+ /**
545
+ * The archive-filter state this catalog starts consumers in — the platform
546
+ * default `"active"` unless the host set the knob. What "not the default
547
+ * state" means on this surface, so the control and the footer can both say
548
+ * it honestly.
549
+ */
550
+ archFilterDefault: AgentArchFilter;
518
551
  accessFilter: AgentAccessFilter;
519
552
  favoritesFirst: boolean;
520
553
  listPage: number;
@@ -561,12 +594,23 @@ declare function useAgentConsumer(consumerId: string, options?: {
561
594
  unregisterOnUnmount?: boolean;
562
595
  /** Applied only when the consumer is first registered (idempotent). */
563
596
  initialTab?: AgentTab;
597
+ /**
598
+ * THE ARCHIVED-ITEMS LAW's per-consumer override of the catalog-wide
599
+ * `defaults.archiveFilter` knob. Applied only at first registration — the
600
+ * state belongs to the person after that.
601
+ */
602
+ initialArchFilter?: AgentArchFilter;
564
603
  }): UseAgentConsumerReturn;
565
604
 
566
605
  /**
567
606
  * The four ownership counts a tab strip prints. Declared HERE, beside the code
568
607
  * that computes them, so both the web tab strip and the native one name the
569
608
  * same shape (0.9.0 — it used to live in the web-only `AgentListTabs`).
609
+ *
610
+ * 🚨 These are the numbers on the BADGES, and since 0.9.1 they count exactly
611
+ * the rows the tab renders under the consumer's own archive filter. A badge
612
+ * that counted rows the list hid was the screen telling the user something
613
+ * untrue about her own agents.
570
614
  */
571
615
  interface AgentListTabCounts {
572
616
  mine: number;
@@ -610,6 +654,13 @@ interface AgentListCoreOptions {
610
654
  * not just at mount — so a restriction that arrives later is enforced later.
611
655
  */
612
656
  visibleTabs?: readonly AgentTab[];
657
+ /**
658
+ * THE ARCHIVED-ITEMS LAW's per-consumer override of the catalog-wide
659
+ * `defaults.archiveFilter` knob, applied once at first registration. Almost
660
+ * nothing should pass it: the platform answer is "hide archived", and the
661
+ * person reveals the archive from the control on the filter bar.
662
+ */
663
+ initialArchFilter?: AgentArchFilter;
613
664
  /** Hide records that are invalid for this call site. */
614
665
  excludeAgentIds?: readonly string[];
615
666
  /**
@@ -635,8 +686,10 @@ declare const HOVER_GRACE_MS = 900;
635
686
  * else the first allowed tab.
636
687
  */
637
688
  declare function coerceVisibleTab(current: AgentTab, allowed: readonly AgentTab[], initialTab?: AgentTab): AgentTab | null;
638
- declare function useAgentListCore({ consumerId, onSelect, navigateTo, activeAgentIdOverride, initialTab, includeSystemInAll, visibleTabs, excludeAgentIds, defaultMandateKey, }: AgentListCoreOptions): {
689
+ declare function useAgentListCore({ consumerId, onSelect, navigateTo, activeAgentIdOverride, initialTab, includeSystemInAll, visibleTabs, initialArchFilter, excludeAgentIds, defaultMandateKey, }: AgentListCoreOptions): {
639
690
  agents: AgentSummary[];
691
+ archivedHiddenCount: number;
692
+ footerLabel: string;
640
693
  isLoading: boolean;
641
694
  activeAgentId: string | null;
642
695
  pinnedAgent: AgentSummary | null;
@@ -800,8 +853,16 @@ interface AgentListContentProps {
800
853
  defaultRow?: DefaultRowState | null | undefined;
801
854
  /** When true, scroll the list to the pinned row (top). */
802
855
  listOpen?: boolean | undefined;
856
+ /**
857
+ * Rows the ARCHIVE FILTER is currently keeping off this screen — from
858
+ * `useAgentListCore`. The footer names them (clause 2 of THE ARCHIVED-ITEMS
859
+ * LAW: a screen never implies the list is everything). 0 means "nothing
860
+ * archived is hidden behind this view", which is also what a host that
861
+ * mounts this component directly and passes nothing gets.
862
+ */
863
+ archivedHiddenCount?: number | undefined;
803
864
  }
804
- declare function AgentListContent({ agents, isLoading, consumer, activeAgentId, allCategories, allTags, inputRef, onSelectAgent, resolveAgentHref, onReset, activeFilterCount, isMobile, hoveredAgent, onAgentHover, onAgentHoverEnd, onDetailPress, onFilterChipClick, rightPanel, tabCounts, visibleTabs, systemTabLabel, pinnedAgent, defaultRow, listOpen, }: AgentListContentProps): react.JSX.Element;
865
+ declare function AgentListContent({ agents, isLoading, consumer, activeAgentId, allCategories, allTags, inputRef, onSelectAgent, resolveAgentHref, onReset, activeFilterCount, isMobile, hoveredAgent, onAgentHover, onAgentHoverEnd, onDetailPress, onFilterChipClick, rightPanel, tabCounts, visibleTabs, systemTabLabel, pinnedAgent, defaultRow, listOpen, archivedHiddenCount, }: AgentListContentProps): react.JSX.Element;
805
866
 
806
867
  interface AgentFilterBarProps {
807
868
  consumer: UseAgentConsumerReturn;
@@ -818,6 +879,14 @@ interface AgentFilterBarProps {
818
879
  * fewer controls than its neighbour is the half-built shape this list exists
819
880
  * to prevent — the system tab's category/tag options simply come from the
820
881
  * builtin population (see `selectAllSystemAgentCategories`).
882
+ *
883
+ * 🚨 THE ARCHIVE CONTROL IS NOT OPTIONAL (0.9.2). It renders here, on every
884
+ * tab, for every consumer — including one whose `visibleTabs` removes the tab
885
+ * strip above it, since this bar is mounted unconditionally by
886
+ * `AgentListContent`. THE ARCHIVED-ITEMS LAW clause 3: revealing archived
887
+ * items is one or two clicks away, "on the surface itself — never zero
888
+ * (impossible) and never buried in another page". One click of this chip
889
+ * shows all; a second shows archived only; a third hides them again.
821
890
  */
822
891
  declare function AgentFilterBar({ consumer, allCategories, allTags, activeFilterCount, isMobile, rightPanel, onFilterChipClick, onReset, }: AgentFilterBarProps): react.JSX.Element;
823
892
 
@@ -892,7 +961,7 @@ declare const SearchInput: ({ ref, value, onChange, placeholder, }: {
892
961
  onChange: (v: string) => void;
893
962
  placeholder: string;
894
963
  }) => react.JSX.Element;
895
- declare function FilterChip({ icon: Icon, label, active, focused, onClick, }: {
964
+ declare function FilterChip({ icon: Icon, label, active, focused, onClick, ariaLabel, testId, }: {
896
965
  icon: ComponentType<{
897
966
  className?: string;
898
967
  }>;
@@ -900,6 +969,10 @@ declare function FilterChip({ icon: Icon, label, active, focused, onClick, }: {
900
969
  active: boolean;
901
970
  focused?: boolean;
902
971
  onClick: () => void;
972
+ /** Accessible name when the visible label alone would not say the state. */
973
+ ariaLabel?: string;
974
+ /** Stable hook so a shell test can measure the control, not a class name. */
975
+ testId?: string;
903
976
  }): react.JSX.Element;
904
977
  declare function OptionRow({ label, selected, onClick, }: {
905
978
  label: string;
@@ -131,7 +131,25 @@ declare const SORT_OPTIONS: {
131
131
  type AgentTab = "mine" | "shared" | "all" | "system";
132
132
  /** Favorite filter. */
133
133
  type AgentFavFilter = "all" | "yes" | "no";
134
- /** Archive filter. */
134
+ /**
135
+ * The archive filter — THE ARCHIVED-ITEMS LAW's ONE control, in this
136
+ * package's existing vocabulary.
137
+ *
138
+ * > "everything should have an archive filter, and the default should always
139
+ * > hide archived, but seeing archived items should be one or two clicks
140
+ * > away." — Arman, 2026-09-09 (`common-docs/policies/archived-items.md`)
141
+ *
142
+ * Three states and no more, identical for every entity on the platform:
143
+ *
144
+ * | value | the platform's words | what the list shows |
145
+ * |------------|----------------------|--------------------------|
146
+ * | `active` | hide archived | only un-archived rows |
147
+ * | `both` | show all | every row |
148
+ * | `archived` | archived only | only archived rows |
149
+ *
150
+ * `active` is the platform default, and it is a KNOB — see
151
+ * `AgentCatalogConfig.defaults.archiveFilter`.
152
+ */
135
153
  type AgentArchFilter = "active" | "archived" | "both";
136
154
  /**
137
155
  * Access level filter.
@@ -377,6 +395,14 @@ interface AgentCatalog {
377
395
  readonly notifier: AgentCatalogNotifier | undefined;
378
396
  /** True when this catalog was given a transport and can resolve mandates. */
379
397
  readonly canResolveMandates: boolean;
398
+ /**
399
+ * The consumer state a brand-new consumer starts from, AFTER the host's
400
+ * `defaults` knob is applied. Read it instead of
401
+ * `DEFAULT_AGENT_CONSUMER_STATE` whenever the question is "is this filter at
402
+ * its default?" — a host that legitimately defaults the archive filter to
403
+ * "show all" must not have every control render as though it were modified.
404
+ */
405
+ readonly consumerDefaults: AgentConsumerState;
380
406
  getState(): AgentCatalogState;
381
407
  subscribe(listener: () => void): () => void;
382
408
  getAgent(agentId: string): AgentSummary | undefined;
@@ -515,6 +541,13 @@ interface UseAgentConsumerReturn {
515
541
  includedTags: string[];
516
542
  favFilter: AgentFavFilter;
517
543
  archFilter: AgentArchFilter;
544
+ /**
545
+ * The archive-filter state this catalog starts consumers in — the platform
546
+ * default `"active"` unless the host set the knob. What "not the default
547
+ * state" means on this surface, so the control and the footer can both say
548
+ * it honestly.
549
+ */
550
+ archFilterDefault: AgentArchFilter;
518
551
  accessFilter: AgentAccessFilter;
519
552
  favoritesFirst: boolean;
520
553
  listPage: number;
@@ -561,12 +594,23 @@ declare function useAgentConsumer(consumerId: string, options?: {
561
594
  unregisterOnUnmount?: boolean;
562
595
  /** Applied only when the consumer is first registered (idempotent). */
563
596
  initialTab?: AgentTab;
597
+ /**
598
+ * THE ARCHIVED-ITEMS LAW's per-consumer override of the catalog-wide
599
+ * `defaults.archiveFilter` knob. Applied only at first registration — the
600
+ * state belongs to the person after that.
601
+ */
602
+ initialArchFilter?: AgentArchFilter;
564
603
  }): UseAgentConsumerReturn;
565
604
 
566
605
  /**
567
606
  * The four ownership counts a tab strip prints. Declared HERE, beside the code
568
607
  * that computes them, so both the web tab strip and the native one name the
569
608
  * same shape (0.9.0 — it used to live in the web-only `AgentListTabs`).
609
+ *
610
+ * 🚨 These are the numbers on the BADGES, and since 0.9.1 they count exactly
611
+ * the rows the tab renders under the consumer's own archive filter. A badge
612
+ * that counted rows the list hid was the screen telling the user something
613
+ * untrue about her own agents.
570
614
  */
571
615
  interface AgentListTabCounts {
572
616
  mine: number;
@@ -610,6 +654,13 @@ interface AgentListCoreOptions {
610
654
  * not just at mount — so a restriction that arrives later is enforced later.
611
655
  */
612
656
  visibleTabs?: readonly AgentTab[];
657
+ /**
658
+ * THE ARCHIVED-ITEMS LAW's per-consumer override of the catalog-wide
659
+ * `defaults.archiveFilter` knob, applied once at first registration. Almost
660
+ * nothing should pass it: the platform answer is "hide archived", and the
661
+ * person reveals the archive from the control on the filter bar.
662
+ */
663
+ initialArchFilter?: AgentArchFilter;
613
664
  /** Hide records that are invalid for this call site. */
614
665
  excludeAgentIds?: readonly string[];
615
666
  /**
@@ -635,8 +686,10 @@ declare const HOVER_GRACE_MS = 900;
635
686
  * else the first allowed tab.
636
687
  */
637
688
  declare function coerceVisibleTab(current: AgentTab, allowed: readonly AgentTab[], initialTab?: AgentTab): AgentTab | null;
638
- declare function useAgentListCore({ consumerId, onSelect, navigateTo, activeAgentIdOverride, initialTab, includeSystemInAll, visibleTabs, excludeAgentIds, defaultMandateKey, }: AgentListCoreOptions): {
689
+ declare function useAgentListCore({ consumerId, onSelect, navigateTo, activeAgentIdOverride, initialTab, includeSystemInAll, visibleTabs, initialArchFilter, excludeAgentIds, defaultMandateKey, }: AgentListCoreOptions): {
639
690
  agents: AgentSummary[];
691
+ archivedHiddenCount: number;
692
+ footerLabel: string;
640
693
  isLoading: boolean;
641
694
  activeAgentId: string | null;
642
695
  pinnedAgent: AgentSummary | null;
@@ -800,8 +853,16 @@ interface AgentListContentProps {
800
853
  defaultRow?: DefaultRowState | null | undefined;
801
854
  /** When true, scroll the list to the pinned row (top). */
802
855
  listOpen?: boolean | undefined;
856
+ /**
857
+ * Rows the ARCHIVE FILTER is currently keeping off this screen — from
858
+ * `useAgentListCore`. The footer names them (clause 2 of THE ARCHIVED-ITEMS
859
+ * LAW: a screen never implies the list is everything). 0 means "nothing
860
+ * archived is hidden behind this view", which is also what a host that
861
+ * mounts this component directly and passes nothing gets.
862
+ */
863
+ archivedHiddenCount?: number | undefined;
803
864
  }
804
- declare function AgentListContent({ agents, isLoading, consumer, activeAgentId, allCategories, allTags, inputRef, onSelectAgent, resolveAgentHref, onReset, activeFilterCount, isMobile, hoveredAgent, onAgentHover, onAgentHoverEnd, onDetailPress, onFilterChipClick, rightPanel, tabCounts, visibleTabs, systemTabLabel, pinnedAgent, defaultRow, listOpen, }: AgentListContentProps): react.JSX.Element;
865
+ declare function AgentListContent({ agents, isLoading, consumer, activeAgentId, allCategories, allTags, inputRef, onSelectAgent, resolveAgentHref, onReset, activeFilterCount, isMobile, hoveredAgent, onAgentHover, onAgentHoverEnd, onDetailPress, onFilterChipClick, rightPanel, tabCounts, visibleTabs, systemTabLabel, pinnedAgent, defaultRow, listOpen, archivedHiddenCount, }: AgentListContentProps): react.JSX.Element;
805
866
 
806
867
  interface AgentFilterBarProps {
807
868
  consumer: UseAgentConsumerReturn;
@@ -818,6 +879,14 @@ interface AgentFilterBarProps {
818
879
  * fewer controls than its neighbour is the half-built shape this list exists
819
880
  * to prevent — the system tab's category/tag options simply come from the
820
881
  * builtin population (see `selectAllSystemAgentCategories`).
882
+ *
883
+ * 🚨 THE ARCHIVE CONTROL IS NOT OPTIONAL (0.9.2). It renders here, on every
884
+ * tab, for every consumer — including one whose `visibleTabs` removes the tab
885
+ * strip above it, since this bar is mounted unconditionally by
886
+ * `AgentListContent`. THE ARCHIVED-ITEMS LAW clause 3: revealing archived
887
+ * items is one or two clicks away, "on the surface itself — never zero
888
+ * (impossible) and never buried in another page". One click of this chip
889
+ * shows all; a second shows archived only; a third hides them again.
821
890
  */
822
891
  declare function AgentFilterBar({ consumer, allCategories, allTags, activeFilterCount, isMobile, rightPanel, onFilterChipClick, onReset, }: AgentFilterBarProps): react.JSX.Element;
823
892
 
@@ -892,7 +961,7 @@ declare const SearchInput: ({ ref, value, onChange, placeholder, }: {
892
961
  onChange: (v: string) => void;
893
962
  placeholder: string;
894
963
  }) => react.JSX.Element;
895
- declare function FilterChip({ icon: Icon, label, active, focused, onClick, }: {
964
+ declare function FilterChip({ icon: Icon, label, active, focused, onClick, ariaLabel, testId, }: {
896
965
  icon: ComponentType<{
897
966
  className?: string;
898
967
  }>;
@@ -900,6 +969,10 @@ declare function FilterChip({ icon: Icon, label, active, focused, onClick, }: {
900
969
  active: boolean;
901
970
  focused?: boolean;
902
971
  onClick: () => void;
972
+ /** Accessible name when the visible label alone would not say the state. */
973
+ ariaLabel?: string;
974
+ /** Stable hook so a shell test can measure the control, not a class name. */
975
+ testId?: string;
903
976
  }): react.JSX.Element;
904
977
  declare function OptionRow({ label, selected, onClick, }: {
905
978
  label: string;