@ai-matrx/agents 0.8.0 → 0.9.1

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.
@@ -0,0 +1,2834 @@
1
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
+ }) : x)(function(x) {
4
+ if (typeof require !== "undefined") return require.apply(this, arguments);
5
+ throw Error('Dynamic require of "' + x + '" is not supported');
6
+ });
7
+
8
+ // catalog/native/context.tsx
9
+ import { createContext as createContext2, useContext as useContext2, useMemo as useMemo2 } from "react";
10
+ import { Pressable, Text } from "react-native";
11
+
12
+ // catalog/shared/context.tsx
13
+ import {
14
+ createContext,
15
+ useCallback,
16
+ useContext,
17
+ useMemo,
18
+ useSyncExternalStore
19
+ } from "react";
20
+ import { jsx } from "react/jsx-runtime";
21
+ var AgentCatalogContext = createContext(null);
22
+ function AgentCatalogProviderCore({
23
+ catalog,
24
+ platform,
25
+ children,
26
+ ...ports
27
+ }) {
28
+ const value = useMemo(
29
+ () => ({ catalog, platform, ...ports }),
30
+ // The ports are plain values a host declares once; re-binding on identity
31
+ // change is correct and cheap.
32
+ [
33
+ catalog,
34
+ platform,
35
+ ports.navigate,
36
+ ports.LinkComponent,
37
+ ports.renderModelRef,
38
+ ports.openPeek,
39
+ ports.popoverContainer
40
+ ]
41
+ );
42
+ return /* @__PURE__ */ jsx(AgentCatalogContext.Provider, { value, children });
43
+ }
44
+ function useBinding() {
45
+ const binding = useContext(AgentCatalogContext);
46
+ if (!binding) {
47
+ throw new Error(
48
+ "@ai-matrx/agents/catalog: no <AgentCatalogProvider> is mounted above this component. Create the catalog once with createAgentCatalog({ client, identity }) and mount <AgentCatalogProvider catalog={catalog}> at the top of your tree."
49
+ );
50
+ }
51
+ return binding;
52
+ }
53
+ function useAgentCatalog() {
54
+ return useBinding().catalog;
55
+ }
56
+ function useAgentCatalogUiPorts() {
57
+ const binding = useBinding();
58
+ const hostNavigate = binding.navigate;
59
+ const platformNavigate = binding.platform.navigate;
60
+ const navigate = useCallback(
61
+ (href) => {
62
+ if (hostNavigate) {
63
+ hostNavigate(href);
64
+ return;
65
+ }
66
+ platformNavigate(href);
67
+ },
68
+ [hostNavigate, platformNavigate]
69
+ );
70
+ return {
71
+ navigate,
72
+ LinkComponent: binding.LinkComponent ?? binding.platform.LinkComponent,
73
+ renderModelRef: binding.renderModelRef ?? binding.platform.renderModelRef,
74
+ openPeek: binding.openPeek,
75
+ popoverContainer: binding.popoverContainer
76
+ };
77
+ }
78
+ function useAgentCatalogState(select) {
79
+ const catalog = useAgentCatalog();
80
+ const getSnapshot = useCallback(
81
+ () => select(catalog.getState()),
82
+ [catalog, select]
83
+ );
84
+ return useSyncExternalStore(catalog.subscribe, getSnapshot, getSnapshot);
85
+ }
86
+ function useAgentCatalogRows() {
87
+ return useAgentCatalogState(selectRows);
88
+ }
89
+ var selectRows = (state) => state.rows;
90
+
91
+ // catalog/native/theme.ts
92
+ var DEFAULT_AGENT_CATALOG_NATIVE_THEME = {
93
+ colors: {
94
+ background: "#0b0b0f",
95
+ surface: "#17171d",
96
+ surfacePressed: "#22222b",
97
+ text: "#f5f5f7",
98
+ textMuted: "#9b9ba5",
99
+ textFaint: "#6e6e78",
100
+ border: "#2a2a33",
101
+ primary: "#3b82f6",
102
+ primaryForeground: "#ffffff",
103
+ primarySoft: "#1c2a44",
104
+ // The web sheet's dark value for --matrx-agent-favorite.
105
+ favorite: "#fbbf24",
106
+ driftBackground: "#451a03",
107
+ driftForeground: "#fcd34d",
108
+ driftBorder: "#78350f"
109
+ },
110
+ radius: { sm: 4, md: 8, lg: 12 },
111
+ spacing: { xs: 4, sm: 8, md: 12, lg: 16 },
112
+ fontSize: { xs: 10, sm: 11, md: 13, lg: 15 }
113
+ };
114
+ var LIGHT_AGENT_CATALOG_NATIVE_THEME = {
115
+ ...DEFAULT_AGENT_CATALOG_NATIVE_THEME,
116
+ colors: {
117
+ background: "#ffffff",
118
+ surface: "#f4f4f6",
119
+ surfacePressed: "#e9e9ee",
120
+ text: "#0b0b0f",
121
+ textMuted: "#61616b",
122
+ textFaint: "#8c8c96",
123
+ border: "#e2e2e8",
124
+ primary: "#2563eb",
125
+ primaryForeground: "#ffffff",
126
+ primarySoft: "#e5edfd",
127
+ favorite: "#f59e0b",
128
+ driftBackground: "#fef3c7",
129
+ driftForeground: "#92400e",
130
+ driftBorder: "#fcd34d"
131
+ }
132
+ };
133
+ function resolveAgentCatalogNativeTheme(override, base = DEFAULT_AGENT_CATALOG_NATIVE_THEME) {
134
+ if (!override) return base;
135
+ return {
136
+ colors: { ...base.colors, ...override.colors ?? {} },
137
+ radius: { ...base.radius, ...override.radius ?? {} },
138
+ spacing: { ...base.spacing, ...override.spacing ?? {} },
139
+ fontSize: { ...base.fontSize, ...override.fontSize ?? {} }
140
+ };
141
+ }
142
+
143
+ // catalog/native/context.tsx
144
+ import { jsx as jsx2 } from "react/jsx-runtime";
145
+ var ThemeContext = createContext2(
146
+ DEFAULT_AGENT_CATALOG_NATIVE_THEME
147
+ );
148
+ function useAgentCatalogNativeTheme() {
149
+ return useContext2(ThemeContext);
150
+ }
151
+ var NativeLink = ({ children, onClick, title }) => /* @__PURE__ */ jsx2(
152
+ Pressable,
153
+ {
154
+ accessibilityRole: "link",
155
+ ...title ? { accessibilityLabel: title } : {},
156
+ onPress: () => onClick?.({
157
+ preventDefault: () => {
158
+ },
159
+ stopPropagation: () => {
160
+ }
161
+ }),
162
+ children
163
+ }
164
+ );
165
+ var nativeRenderModelRef = ({ modelId }) => /* @__PURE__ */ jsx2(Text, { children: modelId });
166
+ function AgentCatalogProvider({
167
+ catalog,
168
+ theme,
169
+ children,
170
+ ...ports
171
+ }) {
172
+ const resolvedTheme = useMemo2(
173
+ () => resolveAgentCatalogNativeTheme(theme),
174
+ // A theme object is declared once by a host; re-resolving on identity
175
+ // change is correct and cheap.
176
+ [theme]
177
+ );
178
+ const platform = useMemo2(
179
+ () => ({
180
+ /**
181
+ * 🚨 THE NATIVE `navigate` DEFAULT. There is no `window.location` to
182
+ * assign, and there is no router this package may assume — Expo Router,
183
+ * React Navigation and a custom stack all differ. So the default is a
184
+ * no-op that REPORTS, with the remedy, through the catalog's own
185
+ * errorSink. It never fails silently, and it never pretends to have
186
+ * navigated. A host that wants working links passes `navigate`.
187
+ */
188
+ navigate: (href) => {
189
+ catalog.errorSink({
190
+ code: "native_navigate_not_bound",
191
+ message: "the agent picker was asked to navigate, but this native host bound no `navigate` port, so nothing moved.",
192
+ context: {
193
+ href,
194
+ remedy: "pass navigate={(href) => router.push(href)} (Expo Router) or your navigator's equivalent to <AgentCatalogProvider>"
195
+ }
196
+ });
197
+ },
198
+ LinkComponent: NativeLink,
199
+ renderModelRef: nativeRenderModelRef
200
+ }),
201
+ [catalog]
202
+ );
203
+ return /* @__PURE__ */ jsx2(ThemeContext.Provider, { value: resolvedTheme, children: /* @__PURE__ */ jsx2(
204
+ AgentCatalogProviderCore,
205
+ {
206
+ catalog,
207
+ platform,
208
+ ...ports,
209
+ children
210
+ }
211
+ ) });
212
+ }
213
+
214
+ // catalog/native/AgentListSheet.tsx
215
+ import { StyleSheet as StyleSheet9, Text as Text9, View as View7 } from "react-native";
216
+
217
+ // catalog/native/AgentPickerBody.tsx
218
+ import { useEffect as useEffect3, useState as useState3 } from "react";
219
+ import { StyleSheet as StyleSheet8, View as View6 } from "react-native";
220
+
221
+ // catalog/shared/useAgentListCore.ts
222
+ import {
223
+ useCallback as useCallback3,
224
+ useEffect as useEffect2,
225
+ useMemo as useMemo3,
226
+ useRef as useRef2,
227
+ useState as useState2
228
+ } from "react";
229
+
230
+ // catalog/shared/useAgentConsumer.ts
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
+ var DEBOUNCE_MS = 250;
264
+ var MIN_QUERY_LENGTH = 2;
265
+ function useAgentConsumer(consumerId, options) {
266
+ const catalog = useAgentCatalog();
267
+ const selectConsumer = useCallback2(
268
+ (state) => state.consumers[consumerId] ?? DEFAULT_AGENT_CONSUMER_STATE,
269
+ [consumerId]
270
+ );
271
+ const consumer = useAgentCatalogState(selectConsumer);
272
+ const optionsRef = useRef(options);
273
+ optionsRef.current = options;
274
+ useEffect(() => {
275
+ const opts = optionsRef.current;
276
+ catalog.registerConsumer(
277
+ consumerId,
278
+ opts?.initialTab ? { tab: opts.initialTab } : void 0
279
+ );
280
+ return () => {
281
+ if (optionsRef.current?.unregisterOnUnmount) {
282
+ catalog.unregisterConsumer(consumerId);
283
+ }
284
+ };
285
+ }, [consumerId, catalog]);
286
+ const setSearchTerm = useCallback2(
287
+ (value) => catalog.setConsumerFilter(consumerId, { searchTerm: value }),
288
+ [consumerId, catalog]
289
+ );
290
+ const setDeepSearch = useCallback2(
291
+ (value) => catalog.setConsumerFilter(consumerId, { deepSearch: value }),
292
+ [consumerId, catalog]
293
+ );
294
+ const setSortBy = useCallback2(
295
+ (value) => catalog.setConsumerFilter(consumerId, { sortBy: value }),
296
+ [consumerId, catalog]
297
+ );
298
+ const setTab = useCallback2(
299
+ (value) => catalog.setConsumerFilter(consumerId, { tab: value }),
300
+ [consumerId, catalog]
301
+ );
302
+ const setFavFilter = useCallback2(
303
+ (value) => catalog.setConsumerFilter(consumerId, { favFilter: value }),
304
+ [consumerId, catalog]
305
+ );
306
+ const setArchFilter = useCallback2(
307
+ (value) => catalog.setConsumerFilter(consumerId, { archFilter: value }),
308
+ [consumerId, catalog]
309
+ );
310
+ const setAccessFilter = useCallback2(
311
+ (value) => catalog.setConsumerFilter(consumerId, { accessFilter: value }),
312
+ [consumerId, catalog]
313
+ );
314
+ const toggleCategory = useCallback2(
315
+ (cat) => {
316
+ const current = catalog.getConsumer(consumerId).includedCats;
317
+ const next = current.includes(cat) ? current.filter((c) => c !== cat) : [...current, cat];
318
+ catalog.setConsumerFilter(consumerId, { includedCats: next });
319
+ },
320
+ [consumerId, catalog]
321
+ );
322
+ const toggleTag = useCallback2(
323
+ (tag) => {
324
+ const current = catalog.getConsumer(consumerId).includedTags;
325
+ const next = current.includes(tag) ? current.filter((t) => t !== tag) : [...current, tag];
326
+ catalog.setConsumerFilter(consumerId, { includedTags: next });
327
+ },
328
+ [consumerId, catalog]
329
+ );
330
+ const setIncludedCats = useCallback2(
331
+ (next) => catalog.setConsumerFilter(consumerId, { includedCats: next }),
332
+ [consumerId, catalog]
333
+ );
334
+ const setIncludedTags = useCallback2(
335
+ (next) => catalog.setConsumerFilter(consumerId, { includedTags: next }),
336
+ [consumerId, catalog]
337
+ );
338
+ const toggleFavoritesFirst = useCallback2(
339
+ () => catalog.setConsumerFilter(consumerId, {
340
+ favoritesFirst: !catalog.getConsumer(consumerId).favoritesFirst
341
+ }),
342
+ [consumerId, catalog]
343
+ );
344
+ const loadMoreList = useCallback2(
345
+ () => catalog.setConsumerPage(
346
+ consumerId,
347
+ "list",
348
+ catalog.getConsumer(consumerId).listPage + 1
349
+ ),
350
+ [consumerId, catalog]
351
+ );
352
+ const loadMoreShared = useCallback2(
353
+ () => catalog.setConsumerPage(
354
+ consumerId,
355
+ "shared",
356
+ catalog.getConsumer(consumerId).sharedPage + 1
357
+ ),
358
+ [consumerId, catalog]
359
+ );
360
+ const resetFilters = useCallback2(
361
+ () => catalog.resetConsumerFilters(consumerId),
362
+ [consumerId, catalog]
363
+ );
364
+ const [isSearching, setIsSearching] = useState(false);
365
+ const [matchedIds, setMatchedIds] = useState(null);
366
+ const requestSeq = useRef(0);
367
+ const query = consumer.searchTerm;
368
+ const deep = consumer.deepSearch;
369
+ useEffect(() => {
370
+ const q = query.trim();
371
+ if (q.length < MIN_QUERY_LENGTH) {
372
+ setIsSearching(false);
373
+ setMatchedIds(null);
374
+ return void 0;
375
+ }
376
+ const seq = ++requestSeq.current;
377
+ setIsSearching(true);
378
+ const timer = setTimeout(() => {
379
+ void catalog.searchServer(q, deep).then((ids) => {
380
+ if (seq !== requestSeq.current) return;
381
+ setMatchedIds(ids);
382
+ setIsSearching(false);
383
+ }).catch((e) => {
384
+ if (seq !== requestSeq.current) return;
385
+ catalog.errorSink({
386
+ code: "server_search_failed",
387
+ message: `agent search failed: ${e instanceof Error ? e.message : String(e)}`,
388
+ context: { query: q, deep }
389
+ });
390
+ setIsSearching(false);
391
+ });
392
+ }, DEBOUNCE_MS);
393
+ return () => clearTimeout(timer);
394
+ }, [query, deep, catalog]);
395
+ useEffect(() => {
396
+ catalog.setConsumerServerSearch(consumerId, {
397
+ matchedIds: matchedIds ?? [],
398
+ isSearching
399
+ });
400
+ }, [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;
402
+ return {
403
+ tab: consumer.tab,
404
+ sortBy: consumer.sortBy,
405
+ searchTerm: consumer.searchTerm,
406
+ includedCats: consumer.includedCats,
407
+ includedTags: consumer.includedTags,
408
+ favFilter: consumer.favFilter,
409
+ archFilter: consumer.archFilter,
410
+ accessFilter: consumer.accessFilter,
411
+ favoritesFirst: consumer.favoritesFirst,
412
+ listPage: consumer.listPage,
413
+ sharedPage: consumer.sharedPage,
414
+ state: consumer,
415
+ hasActiveFilters,
416
+ deepSearch: consumer.deepSearch,
417
+ isServerSearching: consumer.isServerSearching,
418
+ setSearchTerm,
419
+ setDeepSearch,
420
+ setSortBy,
421
+ setTab,
422
+ setFavFilter,
423
+ setArchFilter,
424
+ setAccessFilter,
425
+ toggleCategory,
426
+ toggleTag,
427
+ setIncludedCats,
428
+ setIncludedTags,
429
+ toggleFavoritesFirst,
430
+ loadMoreList,
431
+ loadMoreShared,
432
+ resetFilters
433
+ };
434
+ }
435
+
436
+ // catalog/labels.ts
437
+ function agentListEmptyLabel(tab, labels) {
438
+ switch (tab) {
439
+ case "system":
440
+ return labels.emptySystem;
441
+ case "shared":
442
+ return labels.emptyShared;
443
+ default:
444
+ return labels.emptyDefault;
445
+ }
446
+ }
447
+ function shouldDefaultAgentListToPublicTab(args) {
448
+ if (!args.userId) return true;
449
+ if (!args.agentsLoaded) return false;
450
+ return args.ownedCount === 0;
451
+ }
452
+
453
+ // catalog/score.ts
454
+ function computeAgentSearchScore(agent, query) {
455
+ const q = query.trim().toLowerCase();
456
+ if (!q) return 0;
457
+ let score = 0;
458
+ const name = (agent.name ?? "").toLowerCase();
459
+ const desc = (agent.description ?? "").toLowerCase();
460
+ if (name === q) score += 1e4;
461
+ else if (name.startsWith(q)) score += 5e3;
462
+ else if (matchesWholeWord(name, q)) score += 3e3;
463
+ else if (name.includes(q)) score += 2e3;
464
+ if (desc === q) score += 1e3;
465
+ else if (desc.includes(q)) score += 500;
466
+ if (agent.category?.toLowerCase().includes(q)) score += 300;
467
+ if (agent.tags?.some((t) => t.toLowerCase().includes(q))) score += 300;
468
+ if (agent.modelId?.toLowerCase().includes(q)) score += 100;
469
+ if (agent.agentType?.toLowerCase().includes(q)) score += 100;
470
+ if (agent.outputFormat?.toLowerCase().includes(q)) score += 100;
471
+ const id = agent.id.toLowerCase();
472
+ if (id === q) score += 1e5;
473
+ else if (id.includes(q)) score += 5e3;
474
+ if (agent.sharedByEmail?.toLowerCase().includes(q)) score += 200;
475
+ if (score === 0 && q.includes(" ")) {
476
+ const terms = q.split(/\s+/).filter(Boolean);
477
+ let hits = 0;
478
+ let termScore = 0;
479
+ for (const term of terms) {
480
+ const inName = name.includes(term);
481
+ const matched = inName || desc.includes(term) || (agent.category?.toLowerCase().includes(term) ?? false) || (agent.tags?.some((t) => t.toLowerCase().includes(term)) ?? false);
482
+ if (matched) {
483
+ hits += 1;
484
+ termScore += inName ? 400 : 100;
485
+ }
486
+ }
487
+ if (hits === terms.length) score += termScore;
488
+ }
489
+ return score;
490
+ }
491
+ function matchesWholeWord(haystack, q) {
492
+ const escaped = q.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
493
+ return new RegExp(`\\b${escaped}\\b`).test(haystack);
494
+ }
495
+ function agentMatchesSearch(agent, query) {
496
+ return computeAgentSearchScore(agent, query) > 0;
497
+ }
498
+
499
+ // catalog/selectors.ts
500
+ function memoize1(fn) {
501
+ let lastA;
502
+ let last;
503
+ let has = false;
504
+ return (a) => {
505
+ if (!has || lastA !== a) {
506
+ last = fn(a);
507
+ lastA = a;
508
+ has = true;
509
+ }
510
+ return last;
511
+ };
512
+ }
513
+ function memoize2(fn) {
514
+ let lastA;
515
+ let lastB;
516
+ let last;
517
+ let has = false;
518
+ return (a, b) => {
519
+ if (!has || lastA !== a || lastB !== b) {
520
+ last = fn(a, b);
521
+ lastA = a;
522
+ lastB = b;
523
+ has = true;
524
+ }
525
+ return last;
526
+ };
527
+ }
528
+ function compareAgentIds(a, b) {
529
+ const idA = a.id ?? "";
530
+ const idB = b.id ?? "";
531
+ if (idA < idB) return -1;
532
+ if (idA > idB) return 1;
533
+ return 0;
534
+ }
535
+ function applyAgentSortComparator(a, b, sortBy) {
536
+ const primary = compareAgentSortKey(a, b, sortBy);
537
+ if (!Number.isFinite(primary) || primary === 0) return compareAgentIds(a, b);
538
+ return primary;
539
+ }
540
+ function compareAgentSortKey(a, b, sortBy) {
541
+ switch (sortBy) {
542
+ case "name-asc":
543
+ return (a.name ?? "").localeCompare(b.name ?? "");
544
+ case "name-desc":
545
+ return (b.name ?? "").localeCompare(a.name ?? "");
546
+ case "created-desc":
547
+ return +new Date(b.createdAt ?? 0) - +new Date(a.createdAt ?? 0);
548
+ case "category-asc":
549
+ return (a.category ?? "").localeCompare(b.category ?? "");
550
+ case "updated-desc":
551
+ default:
552
+ return +new Date(b.updatedAt ?? 0) - +new Date(a.updatedAt ?? 0);
553
+ }
554
+ }
555
+ var selectAllAgentCategories = memoize1(
556
+ (agents) => {
557
+ const cats = /* @__PURE__ */ new Set();
558
+ for (const a of agents) {
559
+ if (a.agentType === "user" && a.category) cats.add(a.category);
560
+ }
561
+ return Array.from(cats).sort();
562
+ }
563
+ );
564
+ var selectAllSystemAgentCategories = memoize1(
565
+ (agents) => {
566
+ const cats = /* @__PURE__ */ new Set();
567
+ for (const a of agents) {
568
+ if (a.agentType === "builtin" && a.category) cats.add(a.category);
569
+ }
570
+ return Array.from(cats).sort();
571
+ }
572
+ );
573
+ var selectAllAgentTags = memoize1(
574
+ (agents) => {
575
+ const tags = /* @__PURE__ */ new Set();
576
+ for (const a of agents) {
577
+ if (a.agentType === "user") a.tags?.forEach((t) => tags.add(t));
578
+ }
579
+ return Array.from(tags).sort();
580
+ }
581
+ );
582
+ var selectAllSystemAgentTags = memoize1(
583
+ (agents) => {
584
+ const tags = /* @__PURE__ */ new Set();
585
+ for (const a of agents) {
586
+ if (a.agentType === "builtin") a.tags?.forEach((t) => tags.add(t));
587
+ }
588
+ return Array.from(tags).sort();
589
+ }
590
+ );
591
+ var selectUserTypeAgents = memoize1(
592
+ (agents) => agents.filter((a) => a.agentType === "user")
593
+ );
594
+ var selectBuiltinTypeAgents = memoize1(
595
+ (agents) => agents.filter((a) => a.agentType === "builtin")
596
+ );
597
+ function sortFilteredAgents(filtered, consumer) {
598
+ const { searchTerm, sortBy, favFilter, favoritesFirst } = consumer;
599
+ if (searchTerm) {
600
+ const scores = /* @__PURE__ */ new Map();
601
+ filtered.forEach((a) => {
602
+ scores.set(a.id, computeAgentSearchScore(a, searchTerm));
603
+ });
604
+ const serverRank = /* @__PURE__ */ new Map();
605
+ consumer.serverMatchedIds.forEach((id, i) => serverRank.set(id, i));
606
+ return [...filtered].sort((a, b) => {
607
+ const sa = scores.get(a.id) ?? 0;
608
+ const sb = scores.get(b.id) ?? 0;
609
+ if (sb !== sa) return sb - sa;
610
+ if (sa === 0) {
611
+ const ra = serverRank.get(a.id);
612
+ const rb = serverRank.get(b.id);
613
+ if (ra !== void 0 && rb !== void 0 && ra !== rb) return ra - rb;
614
+ }
615
+ return applyAgentSortComparator(a, b, sortBy);
616
+ });
617
+ }
618
+ return [...filtered].sort((a, b) => {
619
+ if (favoritesFirst && favFilter === "all") {
620
+ const aFav = a.isFavorite ? 1 : 0;
621
+ const bFav = b.isFavorite ? 1 : 0;
622
+ if (bFav !== aFav) return bFav - aFav;
623
+ }
624
+ return applyAgentSortComparator(a, b, sortBy);
625
+ });
626
+ }
627
+ function filterUserTypeAgents(agents, consumer) {
628
+ const {
629
+ searchTerm,
630
+ includedCats,
631
+ includedTags,
632
+ favFilter,
633
+ archFilter,
634
+ accessFilter,
635
+ tab
636
+ } = consumer;
637
+ const serverMatched = new Set(consumer.serverMatchedIds);
638
+ const filtered = agents.filter((agent) => {
639
+ if (tab === "mine" && agent.isOwner !== true) return false;
640
+ if (tab === "shared" && !(agent.isOwner === false && agent.accessLevel != null))
641
+ return false;
642
+ if (archFilter === "active" && agent.isArchived) return false;
643
+ if (archFilter === "archived" && !agent.isArchived) return false;
644
+ if (favFilter === "yes" && !agent.isFavorite) return false;
645
+ if (favFilter === "no" && agent.isFavorite) return false;
646
+ if (accessFilter === "owned" && agent.isOwner !== true) return false;
647
+ if (accessFilter === "shared" && agent.isOwner !== false) return false;
648
+ if (accessFilter === "editable" && agent.accessLevel !== "owner" && agent.accessLevel !== "admin" && agent.accessLevel !== "editor")
649
+ return false;
650
+ if (includedCats.length > 0) {
651
+ const category = agent.category;
652
+ if (!category) {
653
+ if (!includedCats.includes(AGENT_NONE_SENTINEL)) return false;
654
+ } else if (!includedCats.includes(category)) {
655
+ return false;
656
+ }
657
+ }
658
+ if (includedTags.length > 0) {
659
+ const isUntagged = !agent.tags?.length;
660
+ if (isUntagged) {
661
+ if (!includedTags.includes(AGENT_NONE_SENTINEL)) return false;
662
+ } else if (!agent.tags?.some((t) => includedTags.includes(t))) {
663
+ return false;
664
+ }
665
+ }
666
+ if (searchTerm && !agentMatchesSearch(agent, searchTerm) && !serverMatched.has(agent.id))
667
+ return false;
668
+ return true;
669
+ });
670
+ return sortFilteredAgents(filtered, consumer);
671
+ }
672
+ function filterBuiltinTypeAgents(agents, consumer) {
673
+ const { searchTerm, favFilter, includedCats, includedTags } = consumer;
674
+ const serverMatched = new Set(consumer.serverMatchedIds);
675
+ const filtered = agents.filter((agent) => {
676
+ if (favFilter === "yes" && !agent.isFavorite) return false;
677
+ if (favFilter === "no" && agent.isFavorite) return false;
678
+ if (includedCats.length > 0) {
679
+ const category = agent.category;
680
+ if (!category) {
681
+ if (!includedCats.includes(AGENT_NONE_SENTINEL)) return false;
682
+ } else if (!includedCats.includes(category)) {
683
+ return false;
684
+ }
685
+ }
686
+ if (includedTags.length > 0) {
687
+ const isUntagged = !agent.tags?.length;
688
+ if (isUntagged) {
689
+ if (!includedTags.includes(AGENT_NONE_SENTINEL)) return false;
690
+ } else if (!agent.tags?.some((t) => includedTags.includes(t))) {
691
+ return false;
692
+ }
693
+ }
694
+ if (searchTerm && !agentMatchesSearch(agent, searchTerm) && !serverMatched.has(agent.id))
695
+ return false;
696
+ return true;
697
+ });
698
+ return sortFilteredAgents(filtered, consumer);
699
+ }
700
+ var makeSelectFilteredAgents = (includeSystemInAll = false) => memoize2(
701
+ (agents, consumer) => {
702
+ const userAgents = selectUserTypeAgents(agents);
703
+ const builtinAgents = selectBuiltinTypeAgents(agents);
704
+ if (consumer.tab === "system") {
705
+ return filterBuiltinTypeAgents(builtinAgents, consumer);
706
+ }
707
+ if (includeSystemInAll && consumer.tab === "all") {
708
+ return [
709
+ ...filterUserTypeAgents(userAgents, consumer),
710
+ ...filterBuiltinTypeAgents(builtinAgents, consumer)
711
+ ];
712
+ }
713
+ return filterUserTypeAgents(userAgents, consumer);
714
+ }
715
+ );
716
+ function agentMatchesArchiveFilter(agent, archFilter) {
717
+ if (archFilter === "active") return !agent.isArchived;
718
+ if (archFilter === "archived") return Boolean(agent.isArchived);
719
+ return true;
720
+ }
721
+ function countUserRows(agents, archFilter, predicate) {
722
+ let n = 0;
723
+ for (const a of agents) {
724
+ if (a.agentType !== "user") continue;
725
+ if (!agentMatchesArchiveFilter(a, archFilter)) continue;
726
+ if (predicate(a)) n += 1;
727
+ }
728
+ return n;
729
+ }
730
+ var isOwned = (a) => a.isOwner === true;
731
+ var isShared = (a) => a.isOwner === false && a.accessLevel != null;
732
+ var isAny = () => true;
733
+ var isFavorite = (a) => Boolean(a.isFavorite);
734
+ var selectAgentTabCounts = memoize2(
735
+ (agents, archFilter) => ({
736
+ mine: countUserRows(agents, archFilter, isOwned),
737
+ shared: countUserRows(agents, archFilter, isShared),
738
+ all: countUserRows(agents, archFilter, isAny),
739
+ system: selectBuiltinTypeAgents(agents).length
740
+ })
741
+ );
742
+ var selectTotalUserAgentsCount = memoize1(
743
+ (agents) => countUserRows(agents, "active", isAny)
744
+ );
745
+ var selectTotalOwnedAgentsCount = memoize1(
746
+ (agents) => countUserRows(agents, "active", isOwned)
747
+ );
748
+ var selectTotalSharedAgentsCount = memoize1(
749
+ (agents) => countUserRows(agents, "active", isShared)
750
+ );
751
+ var selectTotalBuiltinAgentsCount = memoize1(
752
+ (agents) => selectBuiltinTypeAgents(agents).length
753
+ );
754
+ var selectTotalFavoriteAgentsCount = memoize1(
755
+ (agents) => countUserRows(agents, "active", isFavorite)
756
+ );
757
+
758
+ // catalog/shared/useAgentListCore.ts
759
+ var HOVER_GRACE_MS = 900;
760
+ function coerceVisibleTab(current, allowed, initialTab) {
761
+ if (allowed.length === 0) return null;
762
+ if (allowed.includes(current)) return null;
763
+ return initialTab && allowed.includes(initialTab) ? initialTab : allowed[0] ?? null;
764
+ }
765
+ var EMPTY_EXCLUDES = [];
766
+ function useAgentListCore({
767
+ consumerId,
768
+ onSelect,
769
+ navigateTo,
770
+ activeAgentIdOverride,
771
+ initialTab,
772
+ includeSystemInAll = false,
773
+ visibleTabs,
774
+ excludeAgentIds = EMPTY_EXCLUDES,
775
+ defaultMandateKey
776
+ }) {
777
+ const catalog = useAgentCatalog();
778
+ const { navigate } = useAgentCatalogUiPorts();
779
+ const hasFetchedRef = useRef2(false);
780
+ const [hoveredAgent, setHoveredAgent] = useState2(null);
781
+ const hoverLeaveTimerRef = useRef2(null);
782
+ const defaultTabAppliedRef = useRef2(false);
783
+ const consumer = useAgentConsumer(consumerId, { unregisterOnUnmount: true });
784
+ const rows = useAgentCatalogRows();
785
+ const userId = catalog.getUserIdOrNull();
786
+ const tabCountsForFilter = selectAgentTabCounts(rows, consumer.state.archFilter);
787
+ const ownedCount = tabCountsForFilter.mine;
788
+ const selectFiltered = useMemo3(
789
+ () => makeSelectFilteredAgents(includeSystemInAll),
790
+ [includeSystemInAll]
791
+ );
792
+ const filteredAgents = selectFiltered(rows, consumer.state);
793
+ const excludedAgentIds = useMemo3(
794
+ () => new Set(excludeAgentIds),
795
+ [excludeAgentIds]
796
+ );
797
+ const agents = excludedAgentIds.size === 0 ? filteredAgents : filteredAgents.filter((agent) => !excludedAgentIds.has(agent.id));
798
+ const status = useAgentCatalogState(selectStatus);
799
+ const activeAgentId = activeAgentIdOverride ?? null;
800
+ const pinnedAgent = activeAgentId ? catalog.getAgent(activeAgentId) : void 0;
801
+ const onSystemTab = consumer.tab === "system";
802
+ const allCategories = onSystemTab ? selectAllSystemAgentCategories(rows) : selectAllAgentCategories(rows);
803
+ const allTags = onSystemTab ? selectAllSystemAgentTags(rows) : selectAllAgentTags(rows);
804
+ const tabCounts = tabCountsForFilter;
805
+ const isLoading = status === "loading";
806
+ const agentsLoaded = status === "succeeded" || status === "failed";
807
+ const ensureLoaded = useCallback3(() => {
808
+ if (!hasFetchedRef.current) {
809
+ hasFetchedRef.current = true;
810
+ void catalog.ensureLoaded().catch(() => {
811
+ });
812
+ }
813
+ }, [catalog]);
814
+ const selectDefaultRow = useCallback3(
815
+ (state) => defaultMandateKey ? state.defaultRows[defaultMandateKey] : void 0,
816
+ [defaultMandateKey]
817
+ );
818
+ const defaultRow = useAgentCatalogState(selectDefaultRow);
819
+ useEffect2(() => {
820
+ if (!defaultMandateKey) return;
821
+ catalog.ensureDefaultRow(defaultMandateKey);
822
+ }, [catalog, defaultMandateKey]);
823
+ useEffect2(() => {
824
+ if (defaultTabAppliedRef.current) return;
825
+ if (initialTab) {
826
+ defaultTabAppliedRef.current = true;
827
+ if (consumer.tab !== initialTab) consumer.setTab(initialTab);
828
+ return;
829
+ }
830
+ if (consumer.tab !== "mine") {
831
+ defaultTabAppliedRef.current = true;
832
+ return;
833
+ }
834
+ const wantsPublic = shouldDefaultAgentListToPublicTab({
835
+ userId,
836
+ ownedCount,
837
+ agentsLoaded
838
+ });
839
+ if (!wantsPublic) {
840
+ if (!userId || agentsLoaded) {
841
+ defaultTabAppliedRef.current = true;
842
+ }
843
+ return;
844
+ }
845
+ consumer.setTab("system");
846
+ defaultTabAppliedRef.current = true;
847
+ }, [
848
+ userId,
849
+ ownedCount,
850
+ agentsLoaded,
851
+ initialTab,
852
+ consumer.tab,
853
+ consumer.setTab
854
+ ]);
855
+ const allowedTabsKey = visibleTabs ? visibleTabs.join(",") : "";
856
+ useEffect2(() => {
857
+ if (!allowedTabsKey) return;
858
+ const next = coerceVisibleTab(
859
+ consumer.tab,
860
+ allowedTabsKey.split(","),
861
+ initialTab
862
+ );
863
+ if (next) consumer.setTab(next);
864
+ }, [allowedTabsKey, initialTab, consumer.tab, consumer.setTab]);
865
+ useEffect2(() => {
866
+ ensureLoaded();
867
+ }, [ensureLoaded]);
868
+ const handleSelectAgent = useCallback3(
869
+ (agent) => {
870
+ if (onSelect) {
871
+ onSelect(agent.id);
872
+ } else if (navigateTo) {
873
+ navigate(navigateTo.replace("{id}", agent.id));
874
+ } else {
875
+ catalog.errorSink({
876
+ code: "select_has_nowhere_to_go",
877
+ message: "an agent was chosen but this picker was given neither onSelect nor navigateTo, so the choice went nowhere.",
878
+ context: { consumerId, agentId: agent.id }
879
+ });
880
+ }
881
+ },
882
+ [onSelect, navigateTo, navigate, catalog, consumerId]
883
+ );
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);
885
+ const handleAgentHover = useCallback3(
886
+ (agent, panelOpen) => {
887
+ if (panelOpen) return;
888
+ if (hoverLeaveTimerRef.current) {
889
+ clearTimeout(hoverLeaveTimerRef.current);
890
+ hoverLeaveTimerRef.current = null;
891
+ }
892
+ setHoveredAgent(agent);
893
+ },
894
+ []
895
+ );
896
+ const handleAgentHoverEnd = useCallback3(
897
+ (agent, onClear) => {
898
+ if (hoveredAgent?.id === agent.id) {
899
+ hoverLeaveTimerRef.current = setTimeout(() => {
900
+ setHoveredAgent(null);
901
+ onClear();
902
+ }, HOVER_GRACE_MS);
903
+ }
904
+ },
905
+ [hoveredAgent]
906
+ );
907
+ const handleDetailPanelMouseEnter = useCallback3(() => {
908
+ if (hoverLeaveTimerRef.current) {
909
+ clearTimeout(hoverLeaveTimerRef.current);
910
+ hoverLeaveTimerRef.current = null;
911
+ }
912
+ }, []);
913
+ const handleDetailPanelMouseLeave = useCallback3((onClear) => {
914
+ hoverLeaveTimerRef.current = setTimeout(() => {
915
+ setHoveredAgent(null);
916
+ onClear();
917
+ }, HOVER_GRACE_MS);
918
+ }, []);
919
+ useEffect2(
920
+ () => () => {
921
+ if (hoverLeaveTimerRef.current) clearTimeout(hoverLeaveTimerRef.current);
922
+ },
923
+ []
924
+ );
925
+ return {
926
+ agents,
927
+ isLoading,
928
+ activeAgentId,
929
+ pinnedAgent: pinnedAgent ?? null,
930
+ defaultRow: defaultRow ?? null,
931
+ allCategories,
932
+ allTags,
933
+ consumer,
934
+ tabCounts,
935
+ activeFilterCount,
936
+ hoveredAgent,
937
+ setHoveredAgent,
938
+ ensureLoaded,
939
+ handleSelectAgent,
940
+ handleAgentHover,
941
+ handleAgentHoverEnd,
942
+ handleDetailPanelMouseEnter,
943
+ handleDetailPanelMouseLeave
944
+ };
945
+ }
946
+ var selectStatus = (state) => state.status;
947
+
948
+ // catalog/native/AgentDetailCard.tsx
949
+ import { Pressable as Pressable3, ScrollView, StyleSheet, Text as Text3, View } from "react-native";
950
+
951
+ // catalog/orchestra.ts
952
+ var ORCHESTRA_MODE_LABEL = {
953
+ supervisor: "supervisor",
954
+ sequential: "in order",
955
+ parallel: "together",
956
+ dag: "custom flow"
957
+ };
958
+ function orchestraModeLabel(mode) {
959
+ return ORCHESTRA_MODE_LABEL[mode] ?? mode;
960
+ }
961
+ function orchestraLabel(badge) {
962
+ const n = badge.memberCount;
963
+ return `Orchestra \xB7 ${orchestraModeLabel(badge.mode)} \xB7 ${n} ${n === 1 ? "member" : "members"}`;
964
+ }
965
+ function orchestraDepthLine(badge) {
966
+ const n = badge.depthBudget;
967
+ if (typeof n !== "number" || n <= 0) return null;
968
+ return `Team members can call helpers up to ${n} ${n === 1 ? "level" : "levels"} deep`;
969
+ }
970
+ function orchestraDelegatesLine(badge, limit = 3) {
971
+ const titles = badge.memberTitles;
972
+ if (titles.length === 0) return null;
973
+ const shown = titles.slice(0, limit);
974
+ const extra = titles.length - shown.length;
975
+ return `Delegates to: ${shown.join(", ")}${extra > 0 ? ` +${extra} more` : ""}`;
976
+ }
977
+
978
+ // catalog/native/icons.tsx
979
+ import { Text as Text2 } from "react-native";
980
+
981
+ // catalog/shared/icon-paths.ts
982
+ var SHAPES = {
983
+ star: {
984
+ paths: [
985
+ "M11.5 3.2a.6.6 0 0 1 1 0l2.3 4.7 5.2.8a.6.6 0 0 1 .3 1l-3.8 3.7.9 5.2a.6.6 0 0 1-.9.6L12 16.8l-4.6 2.4a.6.6 0 0 1-.9-.6l.9-5.2-3.8-3.7a.6.6 0 0 1 .3-1l5.2-.8Z"
986
+ ],
987
+ fillable: true
988
+ },
989
+ chevronRight: { paths: ["m9 18 6-6-6-6"] },
990
+ chevronDown: { paths: ["m6 9 6 6 6-6"] },
991
+ search: {
992
+ paths: ["m21 21-4.3-4.3"],
993
+ circles: [{ cx: 11, cy: 11, r: 8 }]
994
+ },
995
+ x: { paths: ["M18 6 6 18", "m6 6 12 12"] },
996
+ check: { paths: ["M20 6 9 17l-5-5"] },
997
+ arrowUpDown: {
998
+ paths: ["m21 16-4 4-4-4", "M17 20V4", "m3 8 4-4 4 4", "M7 4v16"]
999
+ },
1000
+ folder: {
1001
+ paths: [
1002
+ "M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z"
1003
+ ]
1004
+ },
1005
+ tag: {
1006
+ paths: [
1007
+ "M12.586 2.586A2 2 0 0 0 11.172 2H4a2 2 0 0 0-2 2v7.172a2 2 0 0 0 .586 1.414l8.704 8.704a2.426 2.426 0 0 0 3.42 0l6.58-6.58a2.426 2.426 0 0 0 0-3.42z"
1008
+ ],
1009
+ circles: [{ cx: 7.5, cy: 7.5, r: 0.5, filled: true }]
1010
+ },
1011
+ rotateCcw: {
1012
+ paths: [
1013
+ "M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8",
1014
+ "M3 3v5h5"
1015
+ ]
1016
+ },
1017
+ loader: { paths: ["M21 12a9 9 0 1 1-6.219-8.56"] },
1018
+ alertTriangle: {
1019
+ paths: [
1020
+ "m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3",
1021
+ "M12 9v4",
1022
+ "M12 17h.01"
1023
+ ]
1024
+ },
1025
+ /**
1026
+ * The Orchestra marker (Lucide `music-4`): the glyph the Workflow Studio's
1027
+ * picker used for a conductor, kept identical so the same agent wears the
1028
+ * same mark in every client.
1029
+ */
1030
+ music4: {
1031
+ paths: ["M9 18V5l12-2v13", "m9 9 12-2"],
1032
+ circles: [
1033
+ { cx: 6, cy: 18, r: 3 },
1034
+ { cx: 18, cy: 16, r: 3 }
1035
+ ]
1036
+ },
1037
+ clock: {
1038
+ paths: ["M12 6v6l4 2"],
1039
+ circles: [{ cx: 12, cy: 12, r: 10 }]
1040
+ },
1041
+ globe: {
1042
+ paths: ["M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20", "M2 12h20"],
1043
+ circles: [{ cx: 12, cy: 12, r: 10 }]
1044
+ },
1045
+ users: {
1046
+ paths: [
1047
+ "M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2",
1048
+ "M22 21v-2a4 4 0 0 0-3-3.87",
1049
+ "M16 3.13a4 4 0 0 1 0 7.75"
1050
+ ],
1051
+ circles: [{ cx: 9, cy: 7, r: 4 }]
1052
+ },
1053
+ externalLink: {
1054
+ paths: [
1055
+ "M15 3h6v6",
1056
+ "M10 14 21 3",
1057
+ "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"
1058
+ ]
1059
+ },
1060
+ messageCircle: { paths: ["M7.9 20A9 9 0 1 0 4 16.1L2 22Z"] },
1061
+ rocket: {
1062
+ paths: [
1063
+ "M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91 0",
1064
+ "m12 15-3-3a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22.35 22.35 0 0 1-4 2",
1065
+ "M9 12H4s.55-3.03 2-4c1.62-1.08 5 0 5 0",
1066
+ "M12 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5"
1067
+ ]
1068
+ },
1069
+ circleCheck: {
1070
+ paths: ["m9 12 2 2 4-4"],
1071
+ circles: [{ cx: 12, cy: 12, r: 10 }]
1072
+ }
1073
+ };
1074
+ var ICON_PATHS = SHAPES;
1075
+ var ICON_NAMES = Object.keys(ICON_PATHS);
1076
+
1077
+ // catalog/native/icons.tsx
1078
+ import { jsx as jsx3, jsxs } from "react/jsx-runtime";
1079
+ var STATE_KEY = /* @__PURE__ */ Symbol.for("ai-matrx.agents.catalog.native.icons");
1080
+ function getIconsGlobalState() {
1081
+ const store = globalThis;
1082
+ const existing = store[STATE_KEY];
1083
+ if (existing) return existing;
1084
+ const created = { svg: void 0, announced: false };
1085
+ store[STATE_KEY] = created;
1086
+ return created;
1087
+ }
1088
+ function _resetNativeIconState(svg) {
1089
+ const state = getIconsGlobalState();
1090
+ state.svg = svg === void 0 ? void 0 : svg;
1091
+ state.announced = false;
1092
+ }
1093
+ function isSvgModule(value) {
1094
+ if (typeof value !== "object" || value === null) return false;
1095
+ const record = value;
1096
+ return Boolean(record["Path"] && record["Circle"] && record["default"]);
1097
+ }
1098
+ function resolveSvgModule() {
1099
+ const state = getIconsGlobalState();
1100
+ if (state.svg !== void 0) return state.svg;
1101
+ let resolved = null;
1102
+ try {
1103
+ const required = globalThis.require?.("react-native-svg");
1104
+ if (isSvgModule(required)) resolved = required;
1105
+ else {
1106
+ const viaModule = __require("react-native-svg");
1107
+ if (isSvgModule(viaModule)) resolved = viaModule;
1108
+ }
1109
+ } catch {
1110
+ resolved = null;
1111
+ }
1112
+ state.svg = resolved;
1113
+ return resolved;
1114
+ }
1115
+ function announceMissingSvgOnce(report) {
1116
+ const state = getIconsGlobalState();
1117
+ if (state.announced) return;
1118
+ state.announced = true;
1119
+ report({
1120
+ code: "native_icons_degraded_to_text",
1121
+ message: "react-native-svg is not installed, so the agent picker is drawing its icons as text glyphs. Every control still works and every label is still correct \u2014 only the glyphs are plainer.",
1122
+ context: {
1123
+ remedy: "run `npx expo install react-native-svg` (it is an optional peer of @ai-matrx/agents) and reload to get the real icons"
1124
+ }
1125
+ });
1126
+ }
1127
+ var TEXT_GLYPHS = {
1128
+ star: "\u2605",
1129
+ chevronRight: "\u203A",
1130
+ chevronDown: "\u2304",
1131
+ search: "\u2315",
1132
+ x: "\u2715",
1133
+ check: "\u2713",
1134
+ arrowUpDown: "\u21C5",
1135
+ folder: "\u25A4",
1136
+ tag: "\u2317",
1137
+ rotateCcw: "\u21BA",
1138
+ loader: "\u25CC",
1139
+ alertTriangle: "\u26A0",
1140
+ music4: "\u266A",
1141
+ clock: "\u25F7",
1142
+ globe: "\u2295",
1143
+ users: "\u2687",
1144
+ externalLink: "\u2197",
1145
+ messageCircle: "\u2709",
1146
+ rocket: "\u27A4",
1147
+ circleCheck: "\u2713"
1148
+ };
1149
+ function AgentIcon({
1150
+ name,
1151
+ size = 14,
1152
+ color,
1153
+ filled = false,
1154
+ report
1155
+ }) {
1156
+ const svg = resolveSvgModule();
1157
+ if (!svg) {
1158
+ announceMissingSvgOnce(report);
1159
+ return /* @__PURE__ */ jsx3(
1160
+ Text2,
1161
+ {
1162
+ accessible: false,
1163
+ style: { color, fontSize: size, lineHeight: size * 1.2 },
1164
+ children: TEXT_GLYPHS[name]
1165
+ }
1166
+ );
1167
+ }
1168
+ const Svg = svg.default;
1169
+ const Path = svg.Path;
1170
+ const Circle = svg.Circle;
1171
+ const shape = ICON_PATHS[name];
1172
+ return /* @__PURE__ */ jsxs(
1173
+ Svg,
1174
+ {
1175
+ width: size,
1176
+ height: size,
1177
+ viewBox: "0 0 24 24",
1178
+ fill: "none",
1179
+ stroke: color,
1180
+ strokeWidth: 2,
1181
+ strokeLinecap: "round",
1182
+ strokeLinejoin: "round",
1183
+ children: [
1184
+ shape.paths.map((d, index) => /* @__PURE__ */ jsx3(
1185
+ Path,
1186
+ {
1187
+ d,
1188
+ ...filled && shape.fillable ? { fill: color } : {}
1189
+ },
1190
+ `p${index}`
1191
+ )),
1192
+ (shape.circles ?? []).map((circle, index) => /* @__PURE__ */ jsx3(
1193
+ Circle,
1194
+ {
1195
+ cx: circle.cx,
1196
+ cy: circle.cy,
1197
+ r: circle.r,
1198
+ ...circle.filled ? { fill: color } : {}
1199
+ },
1200
+ `c${index}`
1201
+ ))
1202
+ ]
1203
+ }
1204
+ );
1205
+ }
1206
+
1207
+ // catalog/native/FavoriteAgentButton.tsx
1208
+ import { useCallback as useCallback4 } from "react";
1209
+ import { Pressable as Pressable2 } from "react-native";
1210
+ import { jsx as jsx4 } from "react/jsx-runtime";
1211
+ function FavoriteAgentButton({
1212
+ id,
1213
+ size = 18,
1214
+ disabled
1215
+ }) {
1216
+ const catalog = useAgentCatalog();
1217
+ const theme = useAgentCatalogNativeTheme();
1218
+ const select = useCallback4((state) => state.byId[id], [id]);
1219
+ const record = useAgentCatalogState(select);
1220
+ const isFavorite2 = record?.isFavorite ?? false;
1221
+ const isOwner = record?.isOwner ?? true;
1222
+ const inert = Boolean(disabled) || !isOwner;
1223
+ const title = isOwner ? isFavorite2 ? "Remove from favorites" : "Add to favorites" : "Shared \u2014 cannot favorite";
1224
+ return /* @__PURE__ */ jsx4(
1225
+ Pressable2,
1226
+ {
1227
+ onPress: () => {
1228
+ if (inert) return;
1229
+ void catalog.setFavorite(id, !isFavorite2).catch(() => {
1230
+ });
1231
+ },
1232
+ disabled: inert,
1233
+ hitSlop: 8,
1234
+ accessibilityRole: "button",
1235
+ accessibilityLabel: title,
1236
+ accessibilityState: { disabled: inert, selected: isFavorite2 },
1237
+ style: { opacity: inert ? 0.4 : 1 },
1238
+ children: /* @__PURE__ */ jsx4(
1239
+ AgentIcon,
1240
+ {
1241
+ name: "star",
1242
+ size,
1243
+ filled: isFavorite2,
1244
+ color: isFavorite2 ? theme.colors.favorite : theme.colors.textFaint,
1245
+ report: catalog.errorSink
1246
+ }
1247
+ )
1248
+ }
1249
+ );
1250
+ }
1251
+
1252
+ // catalog/native/AgentDetailCard.tsx
1253
+ import { jsx as jsx5, jsxs as jsxs2 } from "react/jsx-runtime";
1254
+ function formatDate(value) {
1255
+ if (!value) return null;
1256
+ const date = new Date(value);
1257
+ if (Number.isNaN(date.getTime())) return null;
1258
+ return date.toLocaleDateString(void 0, {
1259
+ month: "short",
1260
+ day: "numeric",
1261
+ year: "numeric"
1262
+ });
1263
+ }
1264
+ function AgentDetailCard({ agent, onSelect }) {
1265
+ const { errorSink } = useAgentCatalog();
1266
+ const { renderModelRef, openPeek } = useAgentCatalogUiPorts();
1267
+ const theme = useAgentCatalogNativeTheme();
1268
+ const isDefaultRow = isMandateAgentId(agent.id);
1269
+ const updated = formatDate(agent.updatedAt);
1270
+ const created = formatDate(agent.createdAt);
1271
+ return /* @__PURE__ */ jsxs2(View, { style: styles.container, children: [
1272
+ /* @__PURE__ */ jsxs2(View, { style: [styles.header, { padding: theme.spacing.md }], children: [
1273
+ /* @__PURE__ */ jsxs2(View, { style: { flex: 1, minWidth: 0 }, children: [
1274
+ /* @__PURE__ */ jsx5(
1275
+ Text3,
1276
+ {
1277
+ numberOfLines: 2,
1278
+ style: {
1279
+ color: theme.colors.text,
1280
+ fontSize: theme.fontSize.lg,
1281
+ fontWeight: "600"
1282
+ },
1283
+ children: agent.name || "Untitled"
1284
+ }
1285
+ ),
1286
+ agent.isFavorite && /* @__PURE__ */ jsx5(
1287
+ Text3,
1288
+ {
1289
+ style: { color: theme.colors.favorite, fontSize: theme.fontSize.sm },
1290
+ children: "Pinned to favorites"
1291
+ }
1292
+ )
1293
+ ] }),
1294
+ !isDefaultRow && /* @__PURE__ */ jsx5(FavoriteAgentButton, { id: agent.id })
1295
+ ] }),
1296
+ /* @__PURE__ */ jsx5(View, { style: { height: StyleSheet.hairlineWidth, backgroundColor: theme.colors.border } }),
1297
+ /* @__PURE__ */ jsxs2(
1298
+ ScrollView,
1299
+ {
1300
+ style: styles.body,
1301
+ contentContainerStyle: { padding: theme.spacing.md, gap: theme.spacing.md },
1302
+ children: [
1303
+ agent.orchestra && /* @__PURE__ */ jsxs2(
1304
+ View,
1305
+ {
1306
+ style: [
1307
+ styles.orchestra,
1308
+ {
1309
+ borderColor: theme.colors.primary,
1310
+ backgroundColor: theme.colors.primarySoft,
1311
+ borderRadius: theme.radius.md,
1312
+ padding: theme.spacing.sm
1313
+ }
1314
+ ],
1315
+ children: [
1316
+ /* @__PURE__ */ jsxs2(View, { style: styles.inline, children: [
1317
+ /* @__PURE__ */ jsx5(
1318
+ AgentIcon,
1319
+ {
1320
+ name: "music4",
1321
+ size: 14,
1322
+ color: theme.colors.primary,
1323
+ report: errorSink
1324
+ }
1325
+ ),
1326
+ /* @__PURE__ */ jsx5(
1327
+ Text3,
1328
+ {
1329
+ style: {
1330
+ color: theme.colors.primary,
1331
+ fontSize: theme.fontSize.sm,
1332
+ fontWeight: "600"
1333
+ },
1334
+ children: orchestraLabel(agent.orchestra)
1335
+ }
1336
+ )
1337
+ ] }),
1338
+ agent.orchestra.tagline && /* @__PURE__ */ jsx5(Text3, { style: { color: theme.colors.text, fontSize: theme.fontSize.md }, children: agent.orchestra.tagline }),
1339
+ orchestraDelegatesLine(agent.orchestra) && /* @__PURE__ */ jsx5(
1340
+ Text3,
1341
+ {
1342
+ style: { color: theme.colors.textMuted, fontSize: theme.fontSize.sm },
1343
+ children: orchestraDelegatesLine(agent.orchestra)
1344
+ }
1345
+ ),
1346
+ orchestraDepthLine(agent.orchestra) && /* @__PURE__ */ jsx5(
1347
+ Text3,
1348
+ {
1349
+ style: { color: theme.colors.textMuted, fontSize: theme.fontSize.sm },
1350
+ children: orchestraDepthLine(agent.orchestra)
1351
+ }
1352
+ )
1353
+ ]
1354
+ }
1355
+ ),
1356
+ agent.description && /* @__PURE__ */ jsxs2(View, { style: { gap: 4 }, children: [
1357
+ /* @__PURE__ */ jsx5(
1358
+ Text3,
1359
+ {
1360
+ style: {
1361
+ color: theme.colors.textMuted,
1362
+ fontSize: theme.fontSize.sm,
1363
+ fontWeight: "600",
1364
+ textTransform: "uppercase"
1365
+ },
1366
+ children: "Description"
1367
+ }
1368
+ ),
1369
+ /* @__PURE__ */ jsx5(Text3, { style: { color: theme.colors.text, fontSize: theme.fontSize.md }, children: agent.description })
1370
+ ] }),
1371
+ agent.category && /* @__PURE__ */ jsxs2(View, { style: styles.inline, children: [
1372
+ /* @__PURE__ */ jsx5(
1373
+ AgentIcon,
1374
+ {
1375
+ name: "folder",
1376
+ size: 14,
1377
+ color: theme.colors.textMuted,
1378
+ report: errorSink
1379
+ }
1380
+ ),
1381
+ /* @__PURE__ */ jsx5(Text3, { style: { color: theme.colors.text, fontSize: theme.fontSize.md }, children: agent.category })
1382
+ ] }),
1383
+ agent.tags.length > 0 && /* @__PURE__ */ jsxs2(View, { style: { gap: 6 }, children: [
1384
+ /* @__PURE__ */ jsxs2(View, { style: styles.inline, children: [
1385
+ /* @__PURE__ */ jsx5(
1386
+ AgentIcon,
1387
+ {
1388
+ name: "tag",
1389
+ size: 14,
1390
+ color: theme.colors.textMuted,
1391
+ report: errorSink
1392
+ }
1393
+ ),
1394
+ /* @__PURE__ */ jsx5(
1395
+ Text3,
1396
+ {
1397
+ style: { color: theme.colors.textMuted, fontSize: theme.fontSize.sm },
1398
+ children: "Tags"
1399
+ }
1400
+ )
1401
+ ] }),
1402
+ /* @__PURE__ */ jsx5(View, { style: styles.tagWrap, children: agent.tags.map((tag) => /* @__PURE__ */ jsx5(
1403
+ Text3,
1404
+ {
1405
+ style: {
1406
+ color: theme.colors.textMuted,
1407
+ backgroundColor: theme.colors.surface,
1408
+ borderRadius: theme.radius.sm,
1409
+ overflow: "hidden",
1410
+ paddingHorizontal: 6,
1411
+ paddingVertical: 2,
1412
+ fontSize: theme.fontSize.xs
1413
+ },
1414
+ children: tag
1415
+ },
1416
+ tag
1417
+ )) })
1418
+ ] }),
1419
+ agent.accessLevel && /* @__PURE__ */ jsxs2(View, { style: styles.inline, children: [
1420
+ /* @__PURE__ */ jsx5(
1421
+ AgentIcon,
1422
+ {
1423
+ name: agent.isOwner === false ? "users" : "globe",
1424
+ size: 14,
1425
+ color: theme.colors.textMuted,
1426
+ report: errorSink
1427
+ }
1428
+ ),
1429
+ /* @__PURE__ */ jsxs2(View, { children: [
1430
+ /* @__PURE__ */ jsx5(Text3, { style: { color: theme.colors.text, fontSize: theme.fontSize.md }, children: agent.accessLevel === "owner" ? "You own this" : `Shared \u2014 ${agent.accessLevel}` }),
1431
+ agent.sharedByEmail && /* @__PURE__ */ jsxs2(
1432
+ Text3,
1433
+ {
1434
+ style: { color: theme.colors.textMuted, fontSize: theme.fontSize.xs },
1435
+ children: [
1436
+ "by ",
1437
+ agent.sharedByEmail
1438
+ ]
1439
+ }
1440
+ )
1441
+ ] })
1442
+ ] }),
1443
+ agent.modelId && /* @__PURE__ */ jsx5(View, { children: renderModelRef({ modelId: agent.modelId }) }),
1444
+ (updated || created) && /* @__PURE__ */ jsxs2(View, { style: { gap: 4 }, children: [
1445
+ updated && /* @__PURE__ */ jsxs2(View, { style: styles.inline, children: [
1446
+ /* @__PURE__ */ jsx5(
1447
+ AgentIcon,
1448
+ {
1449
+ name: "clock",
1450
+ size: 13,
1451
+ color: theme.colors.textMuted,
1452
+ report: errorSink
1453
+ }
1454
+ ),
1455
+ /* @__PURE__ */ jsxs2(
1456
+ Text3,
1457
+ {
1458
+ style: { color: theme.colors.textMuted, fontSize: theme.fontSize.sm },
1459
+ children: [
1460
+ "Updated ",
1461
+ updated
1462
+ ]
1463
+ }
1464
+ )
1465
+ ] }),
1466
+ created && /* @__PURE__ */ jsxs2(View, { style: styles.inline, children: [
1467
+ /* @__PURE__ */ jsx5(
1468
+ AgentIcon,
1469
+ {
1470
+ name: "clock",
1471
+ size: 13,
1472
+ color: theme.colors.textFaint,
1473
+ report: errorSink
1474
+ }
1475
+ ),
1476
+ /* @__PURE__ */ jsxs2(
1477
+ Text3,
1478
+ {
1479
+ style: { color: theme.colors.textFaint, fontSize: theme.fontSize.sm },
1480
+ children: [
1481
+ "Created ",
1482
+ created
1483
+ ]
1484
+ }
1485
+ )
1486
+ ] })
1487
+ ] })
1488
+ ]
1489
+ }
1490
+ ),
1491
+ /* @__PURE__ */ jsx5(View, { style: { height: StyleSheet.hairlineWidth, backgroundColor: theme.colors.border } }),
1492
+ /* @__PURE__ */ jsxs2(View, { style: [styles.footer, { padding: theme.spacing.sm }], children: [
1493
+ /* @__PURE__ */ jsx5(
1494
+ Pressable3,
1495
+ {
1496
+ onPress: onSelect,
1497
+ accessibilityRole: "button",
1498
+ accessibilityLabel: `Select ${agent.name || "Untitled"}`,
1499
+ style: ({ pressed }) => [
1500
+ styles.selectButton,
1501
+ {
1502
+ borderRadius: theme.radius.md,
1503
+ backgroundColor: theme.colors.primary,
1504
+ opacity: pressed ? 0.85 : 1
1505
+ }
1506
+ ],
1507
+ children: /* @__PURE__ */ jsx5(
1508
+ Text3,
1509
+ {
1510
+ style: {
1511
+ color: theme.colors.primaryForeground,
1512
+ fontSize: theme.fontSize.md,
1513
+ fontWeight: "600"
1514
+ },
1515
+ children: "Select"
1516
+ }
1517
+ )
1518
+ }
1519
+ ),
1520
+ openPeek && /* @__PURE__ */ jsx5(
1521
+ Pressable3,
1522
+ {
1523
+ onPress: () => openPeek(agent),
1524
+ accessibilityRole: "button",
1525
+ accessibilityLabel: "Sneak Peek",
1526
+ style: ({ pressed }) => [
1527
+ styles.iconButton,
1528
+ {
1529
+ borderRadius: theme.radius.md,
1530
+ borderColor: theme.colors.border,
1531
+ backgroundColor: pressed ? theme.colors.surfacePressed : theme.colors.surface
1532
+ }
1533
+ ],
1534
+ children: /* @__PURE__ */ jsx5(
1535
+ AgentIcon,
1536
+ {
1537
+ name: "rocket",
1538
+ size: 14,
1539
+ color: theme.colors.textMuted,
1540
+ report: errorSink
1541
+ }
1542
+ )
1543
+ }
1544
+ )
1545
+ ] })
1546
+ ] });
1547
+ }
1548
+ var styles = StyleSheet.create({
1549
+ container: { flex: 1, minHeight: 0 },
1550
+ header: { flexDirection: "row", alignItems: "flex-start", gap: 12 },
1551
+ body: { flex: 1, minHeight: 0 },
1552
+ inline: { flexDirection: "row", alignItems: "center", gap: 8 },
1553
+ orchestra: { borderWidth: StyleSheet.hairlineWidth, gap: 4 },
1554
+ tagWrap: { flexDirection: "row", flexWrap: "wrap", gap: 4 },
1555
+ footer: { flexDirection: "row", alignItems: "center", gap: 8 },
1556
+ selectButton: {
1557
+ flex: 1,
1558
+ height: 40,
1559
+ alignItems: "center",
1560
+ justifyContent: "center"
1561
+ },
1562
+ iconButton: {
1563
+ width: 40,
1564
+ height: 40,
1565
+ alignItems: "center",
1566
+ justifyContent: "center",
1567
+ borderWidth: StyleSheet.hairlineWidth
1568
+ }
1569
+ });
1570
+
1571
+ // catalog/native/AgentListContent.tsx
1572
+ import { FlatList, Pressable as Pressable8, StyleSheet as StyleSheet6, Text as Text7, View as View4 } from "react-native";
1573
+
1574
+ // catalog/native/AgentFilterBar.tsx
1575
+ import { Pressable as Pressable5, ScrollView as ScrollView2, StyleSheet as StyleSheet3 } from "react-native";
1576
+
1577
+ // catalog/native/primitives.tsx
1578
+ import { Pressable as Pressable4, StyleSheet as StyleSheet2, Text as Text4, TextInput, View as View2 } from "react-native";
1579
+ import { jsx as jsx6, jsxs as jsxs3 } from "react/jsx-runtime";
1580
+ function SearchInput({
1581
+ value,
1582
+ onChange,
1583
+ placeholder,
1584
+ autoFocus = false
1585
+ }) {
1586
+ const theme = useAgentCatalogNativeTheme();
1587
+ const { errorSink } = useAgentCatalog();
1588
+ return /* @__PURE__ */ jsxs3(
1589
+ View2,
1590
+ {
1591
+ style: [
1592
+ styles2.searchWrap,
1593
+ {
1594
+ backgroundColor: theme.colors.surface,
1595
+ borderColor: theme.colors.border,
1596
+ borderRadius: theme.radius.md,
1597
+ paddingHorizontal: theme.spacing.sm
1598
+ }
1599
+ ],
1600
+ children: [
1601
+ /* @__PURE__ */ jsx6(
1602
+ AgentIcon,
1603
+ {
1604
+ name: "search",
1605
+ size: 14,
1606
+ color: theme.colors.textMuted,
1607
+ report: errorSink
1608
+ }
1609
+ ),
1610
+ /* @__PURE__ */ jsx6(
1611
+ TextInput,
1612
+ {
1613
+ value,
1614
+ onChangeText: onChange,
1615
+ placeholder,
1616
+ placeholderTextColor: theme.colors.textFaint,
1617
+ autoFocus,
1618
+ autoCorrect: false,
1619
+ autoCapitalize: "none",
1620
+ returnKeyType: "search",
1621
+ accessibilityLabel: placeholder,
1622
+ style: [styles2.searchInput, { color: theme.colors.text }]
1623
+ }
1624
+ ),
1625
+ value.length > 0 && /* @__PURE__ */ jsx6(
1626
+ Pressable4,
1627
+ {
1628
+ onPress: () => onChange(""),
1629
+ accessibilityRole: "button",
1630
+ accessibilityLabel: "Clear search",
1631
+ hitSlop: 8,
1632
+ children: /* @__PURE__ */ jsx6(
1633
+ AgentIcon,
1634
+ {
1635
+ name: "x",
1636
+ size: 13,
1637
+ color: theme.colors.textMuted,
1638
+ report: errorSink
1639
+ }
1640
+ )
1641
+ }
1642
+ )
1643
+ ]
1644
+ }
1645
+ );
1646
+ }
1647
+ function FilterChip({
1648
+ icon,
1649
+ label,
1650
+ active,
1651
+ onPress
1652
+ }) {
1653
+ const theme = useAgentCatalogNativeTheme();
1654
+ const { errorSink } = useAgentCatalog();
1655
+ const tint = active ? theme.colors.primary : theme.colors.textMuted;
1656
+ return /* @__PURE__ */ jsxs3(
1657
+ Pressable4,
1658
+ {
1659
+ onPress,
1660
+ accessibilityRole: "button",
1661
+ accessibilityState: { selected: active },
1662
+ accessibilityLabel: label,
1663
+ style: ({ pressed }) => [
1664
+ styles2.chip,
1665
+ {
1666
+ borderRadius: theme.radius.sm,
1667
+ backgroundColor: active ? theme.colors.primarySoft : pressed ? theme.colors.surfacePressed : "transparent",
1668
+ borderColor: active ? theme.colors.primary : "transparent"
1669
+ }
1670
+ ],
1671
+ children: [
1672
+ /* @__PURE__ */ jsx6(AgentIcon, { name: icon, size: 12, color: tint, report: errorSink }),
1673
+ /* @__PURE__ */ jsx6(Text4, { style: { color: tint, fontSize: theme.fontSize.sm, fontWeight: "500" }, children: label })
1674
+ ]
1675
+ }
1676
+ );
1677
+ }
1678
+ function OptionRow({
1679
+ label,
1680
+ selected,
1681
+ onPress
1682
+ }) {
1683
+ const theme = useAgentCatalogNativeTheme();
1684
+ const { errorSink } = useAgentCatalog();
1685
+ return /* @__PURE__ */ jsxs3(
1686
+ Pressable4,
1687
+ {
1688
+ onPress,
1689
+ accessibilityRole: "button",
1690
+ accessibilityState: { selected },
1691
+ style: ({ pressed }) => [
1692
+ styles2.optionRow,
1693
+ {
1694
+ paddingHorizontal: theme.spacing.md,
1695
+ backgroundColor: pressed ? theme.colors.surfacePressed : "transparent"
1696
+ }
1697
+ ],
1698
+ children: [
1699
+ /* @__PURE__ */ jsx6(
1700
+ Text4,
1701
+ {
1702
+ style: {
1703
+ flex: 1,
1704
+ color: selected ? theme.colors.primary : theme.colors.text,
1705
+ fontSize: theme.fontSize.md,
1706
+ fontWeight: selected ? "600" : "400"
1707
+ },
1708
+ children: label
1709
+ }
1710
+ ),
1711
+ selected && /* @__PURE__ */ jsx6(
1712
+ AgentIcon,
1713
+ {
1714
+ name: "check",
1715
+ size: 14,
1716
+ color: theme.colors.primary,
1717
+ report: errorSink
1718
+ }
1719
+ )
1720
+ ]
1721
+ }
1722
+ );
1723
+ }
1724
+ function CheckRow({
1725
+ label,
1726
+ checked,
1727
+ onPress
1728
+ }) {
1729
+ const theme = useAgentCatalogNativeTheme();
1730
+ const { errorSink } = useAgentCatalog();
1731
+ return /* @__PURE__ */ jsxs3(
1732
+ Pressable4,
1733
+ {
1734
+ onPress,
1735
+ accessibilityRole: "checkbox",
1736
+ accessibilityState: { checked },
1737
+ style: ({ pressed }) => [
1738
+ styles2.checkRow,
1739
+ {
1740
+ paddingHorizontal: theme.spacing.md,
1741
+ backgroundColor: pressed ? theme.colors.surfacePressed : "transparent"
1742
+ }
1743
+ ],
1744
+ children: [
1745
+ /* @__PURE__ */ jsx6(
1746
+ View2,
1747
+ {
1748
+ style: [
1749
+ styles2.checkBox,
1750
+ {
1751
+ borderRadius: theme.radius.sm,
1752
+ borderColor: checked ? theme.colors.primary : theme.colors.border,
1753
+ backgroundColor: checked ? theme.colors.primary : "transparent"
1754
+ }
1755
+ ],
1756
+ children: checked && /* @__PURE__ */ jsx6(
1757
+ AgentIcon,
1758
+ {
1759
+ name: "check",
1760
+ size: 10,
1761
+ color: theme.colors.primaryForeground,
1762
+ report: errorSink
1763
+ }
1764
+ )
1765
+ }
1766
+ ),
1767
+ /* @__PURE__ */ jsx6(
1768
+ Text4,
1769
+ {
1770
+ numberOfLines: 1,
1771
+ style: { flex: 1, color: theme.colors.text, fontSize: theme.fontSize.md },
1772
+ children: label
1773
+ }
1774
+ )
1775
+ ]
1776
+ }
1777
+ );
1778
+ }
1779
+ function SidePanelHeader({
1780
+ title,
1781
+ onClose
1782
+ }) {
1783
+ const theme = useAgentCatalogNativeTheme();
1784
+ const { errorSink } = useAgentCatalog();
1785
+ return /* @__PURE__ */ jsxs3(
1786
+ View2,
1787
+ {
1788
+ style: [
1789
+ styles2.panelHeader,
1790
+ {
1791
+ paddingHorizontal: theme.spacing.md,
1792
+ borderBottomColor: theme.colors.border
1793
+ }
1794
+ ],
1795
+ children: [
1796
+ /* @__PURE__ */ jsx6(
1797
+ Text4,
1798
+ {
1799
+ style: {
1800
+ color: theme.colors.text,
1801
+ fontSize: theme.fontSize.md,
1802
+ fontWeight: "600"
1803
+ },
1804
+ children: title
1805
+ }
1806
+ ),
1807
+ /* @__PURE__ */ jsx6(
1808
+ Pressable4,
1809
+ {
1810
+ onPress: onClose,
1811
+ accessibilityRole: "button",
1812
+ accessibilityLabel: "Close",
1813
+ hitSlop: 8,
1814
+ children: /* @__PURE__ */ jsx6(
1815
+ AgentIcon,
1816
+ {
1817
+ name: "x",
1818
+ size: 14,
1819
+ color: theme.colors.textMuted,
1820
+ report: errorSink
1821
+ }
1822
+ )
1823
+ }
1824
+ )
1825
+ ]
1826
+ }
1827
+ );
1828
+ }
1829
+ var styles2 = StyleSheet2.create({
1830
+ searchWrap: {
1831
+ flexDirection: "row",
1832
+ alignItems: "center",
1833
+ gap: 6,
1834
+ height: 36,
1835
+ borderWidth: StyleSheet2.hairlineWidth
1836
+ },
1837
+ searchInput: {
1838
+ flex: 1,
1839
+ minWidth: 0,
1840
+ padding: 0,
1841
+ fontSize: 15
1842
+ },
1843
+ chip: {
1844
+ flexDirection: "row",
1845
+ alignItems: "center",
1846
+ gap: 4,
1847
+ height: 28,
1848
+ paddingHorizontal: 8,
1849
+ borderWidth: StyleSheet2.hairlineWidth
1850
+ },
1851
+ optionRow: {
1852
+ flexDirection: "row",
1853
+ alignItems: "center",
1854
+ paddingVertical: 10
1855
+ },
1856
+ checkRow: {
1857
+ flexDirection: "row",
1858
+ alignItems: "center",
1859
+ gap: 8,
1860
+ paddingVertical: 8
1861
+ },
1862
+ checkBox: {
1863
+ width: 18,
1864
+ height: 18,
1865
+ alignItems: "center",
1866
+ justifyContent: "center",
1867
+ borderWidth: 1
1868
+ },
1869
+ panelHeader: {
1870
+ flexDirection: "row",
1871
+ alignItems: "center",
1872
+ justifyContent: "space-between",
1873
+ paddingVertical: 10,
1874
+ borderBottomWidth: StyleSheet2.hairlineWidth
1875
+ }
1876
+ });
1877
+
1878
+ // catalog/native/AgentFilterBar.tsx
1879
+ import { jsx as jsx7, jsxs as jsxs4 } from "react/jsx-runtime";
1880
+ function AgentFilterBar({
1881
+ consumer,
1882
+ allCategories,
1883
+ allTags,
1884
+ activeFilterCount,
1885
+ onFilterChipPress,
1886
+ onReset
1887
+ }) {
1888
+ const theme = useAgentCatalogNativeTheme();
1889
+ const { errorSink } = useAgentCatalog();
1890
+ return /* @__PURE__ */ jsxs4(
1891
+ ScrollView2,
1892
+ {
1893
+ horizontal: true,
1894
+ showsHorizontalScrollIndicator: false,
1895
+ contentContainerStyle: [
1896
+ styles3.bar,
1897
+ { paddingHorizontal: theme.spacing.sm }
1898
+ ],
1899
+ children: [
1900
+ /* @__PURE__ */ jsx7(
1901
+ FilterChip,
1902
+ {
1903
+ icon: "arrowUpDown",
1904
+ label: SORT_OPTIONS.find((o) => o.value === consumer.sortBy)?.label ?? "Sort",
1905
+ active: consumer.sortBy !== "updated-desc",
1906
+ onPress: () => onFilterChipPress("sort")
1907
+ }
1908
+ ),
1909
+ /* @__PURE__ */ jsx7(
1910
+ FilterChip,
1911
+ {
1912
+ icon: "star",
1913
+ label: consumer.favFilter === "no" ? "No Favs" : "Favs",
1914
+ active: consumer.favFilter !== "all",
1915
+ onPress: () => {
1916
+ const next = consumer.favFilter === "all" ? "yes" : consumer.favFilter === "yes" ? "no" : "all";
1917
+ consumer.setFavFilter(next);
1918
+ }
1919
+ }
1920
+ ),
1921
+ allCategories.length > 0 && /* @__PURE__ */ jsx7(
1922
+ FilterChip,
1923
+ {
1924
+ icon: "folder",
1925
+ label: consumer.includedCats.length > 0 ? `${consumer.includedCats.length}` : "Category",
1926
+ active: consumer.includedCats.length > 0,
1927
+ onPress: () => onFilterChipPress("categories")
1928
+ }
1929
+ ),
1930
+ allTags.length > 0 && /* @__PURE__ */ jsx7(
1931
+ FilterChip,
1932
+ {
1933
+ icon: "tag",
1934
+ label: consumer.includedTags.length > 0 ? `${consumer.includedTags.length}` : "Tags",
1935
+ active: consumer.includedTags.length > 0,
1936
+ onPress: () => onFilterChipPress("tags")
1937
+ }
1938
+ ),
1939
+ activeFilterCount > 0 && /* @__PURE__ */ jsx7(
1940
+ Pressable5,
1941
+ {
1942
+ onPress: onReset,
1943
+ accessibilityRole: "button",
1944
+ accessibilityLabel: "Reset filters",
1945
+ hitSlop: 8,
1946
+ style: ({ pressed }) => [
1947
+ styles3.reset,
1948
+ {
1949
+ borderRadius: theme.radius.sm,
1950
+ backgroundColor: pressed ? theme.colors.surfacePressed : "transparent"
1951
+ }
1952
+ ],
1953
+ children: /* @__PURE__ */ jsx7(
1954
+ AgentIcon,
1955
+ {
1956
+ name: "rotateCcw",
1957
+ size: 12,
1958
+ color: theme.colors.textMuted,
1959
+ report: errorSink
1960
+ }
1961
+ )
1962
+ }
1963
+ )
1964
+ ]
1965
+ }
1966
+ );
1967
+ }
1968
+ var styles3 = StyleSheet3.create({
1969
+ bar: { flexDirection: "row", alignItems: "center", gap: 4, paddingBottom: 6 },
1970
+ reset: {
1971
+ height: 28,
1972
+ paddingHorizontal: 8,
1973
+ alignItems: "center",
1974
+ justifyContent: "center"
1975
+ }
1976
+ });
1977
+
1978
+ // catalog/native/AgentListTabs.tsx
1979
+ import { Pressable as Pressable6, ScrollView as ScrollView3, StyleSheet as StyleSheet4, Text as Text5 } from "react-native";
1980
+ import { jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
1981
+ function AgentListTabs({
1982
+ consumer,
1983
+ tabCounts,
1984
+ visibleTabs,
1985
+ systemTabLabel
1986
+ }) {
1987
+ const { labels } = useAgentCatalog();
1988
+ const theme = useAgentCatalogNativeTheme();
1989
+ const tabs = [
1990
+ { value: "mine", label: "Mine", countKey: "mine" },
1991
+ { value: "shared", label: "Shared", countKey: "shared" },
1992
+ { value: "all", label: "All", countKey: "all" },
1993
+ { value: "system", label: labels.publicTab, countKey: "system" }
1994
+ ];
1995
+ return /* @__PURE__ */ jsx8(
1996
+ ScrollView3,
1997
+ {
1998
+ horizontal: true,
1999
+ showsHorizontalScrollIndicator: false,
2000
+ accessibilityRole: "tablist",
2001
+ accessibilityLabel: "Agent ownership",
2002
+ contentContainerStyle: [
2003
+ styles4.strip,
2004
+ { paddingHorizontal: theme.spacing.sm }
2005
+ ],
2006
+ children: tabs.filter(({ value }) => !visibleTabs || visibleTabs.includes(value)).map(({ value, label: baseLabel, countKey }) => {
2007
+ const label = value === "system" ? systemTabLabel ?? baseLabel : baseLabel;
2008
+ const active = consumer.tab === value;
2009
+ const count = tabCounts[countKey];
2010
+ return /* @__PURE__ */ jsxs5(
2011
+ Pressable6,
2012
+ {
2013
+ onPress: () => consumer.setTab(value),
2014
+ accessibilityRole: "tab",
2015
+ accessibilityState: { selected: active },
2016
+ accessibilityLabel: `${label}, ${count}`,
2017
+ style: ({ pressed }) => [
2018
+ styles4.tab,
2019
+ {
2020
+ borderRadius: theme.radius.md,
2021
+ backgroundColor: active ? theme.colors.primary : pressed ? theme.colors.surfacePressed : "transparent"
2022
+ }
2023
+ ],
2024
+ children: [
2025
+ /* @__PURE__ */ jsx8(
2026
+ Text5,
2027
+ {
2028
+ style: {
2029
+ color: active ? theme.colors.primaryForeground : theme.colors.textMuted,
2030
+ fontSize: theme.fontSize.sm,
2031
+ fontWeight: "500"
2032
+ },
2033
+ children: label
2034
+ }
2035
+ ),
2036
+ /* @__PURE__ */ jsx8(
2037
+ Text5,
2038
+ {
2039
+ style: {
2040
+ color: active ? theme.colors.primaryForeground : theme.colors.textMuted,
2041
+ fontSize: theme.fontSize.sm,
2042
+ opacity: 0.8,
2043
+ fontVariant: ["tabular-nums"]
2044
+ },
2045
+ children: count
2046
+ }
2047
+ )
2048
+ ]
2049
+ },
2050
+ value
2051
+ );
2052
+ })
2053
+ }
2054
+ );
2055
+ }
2056
+ var styles4 = StyleSheet4.create({
2057
+ strip: { flexDirection: "row", alignItems: "center", gap: 4, paddingBottom: 6 },
2058
+ tab: {
2059
+ flexDirection: "row",
2060
+ alignItems: "center",
2061
+ gap: 4,
2062
+ paddingHorizontal: 10,
2063
+ paddingVertical: 6
2064
+ }
2065
+ });
2066
+
2067
+ // catalog/native/AgentRow.tsx
2068
+ import { Pressable as Pressable7, StyleSheet as StyleSheet5, Text as Text6, View as View3 } from "react-native";
2069
+ import { jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
2070
+ function AgentRow({
2071
+ agent,
2072
+ isActive,
2073
+ onPress,
2074
+ onDetailPress
2075
+ }) {
2076
+ const { labels, errorSink } = useAgentCatalog();
2077
+ const theme = useAgentCatalogNativeTheme();
2078
+ return /* @__PURE__ */ jsxs6(
2079
+ View3,
2080
+ {
2081
+ testID: `agent-row-${agent.id}`,
2082
+ style: [
2083
+ styles5.row,
2084
+ isActive ? { backgroundColor: theme.colors.primarySoft } : null
2085
+ ],
2086
+ children: [
2087
+ /* @__PURE__ */ jsxs6(
2088
+ Pressable7,
2089
+ {
2090
+ onPress,
2091
+ accessibilityRole: "button",
2092
+ accessibilityState: { selected: isActive },
2093
+ accessibilityLabel: agent.name || "Untitled",
2094
+ style: ({ pressed }) => [
2095
+ styles5.main,
2096
+ {
2097
+ paddingHorizontal: theme.spacing.md,
2098
+ backgroundColor: pressed ? theme.colors.surfacePressed : "transparent"
2099
+ }
2100
+ ],
2101
+ children: [
2102
+ agent.isFavorite && /* @__PURE__ */ jsx9(
2103
+ AgentIcon,
2104
+ {
2105
+ name: "star",
2106
+ size: 12,
2107
+ filled: true,
2108
+ color: theme.colors.favorite,
2109
+ report: errorSink
2110
+ }
2111
+ ),
2112
+ /* @__PURE__ */ jsx9(
2113
+ Text6,
2114
+ {
2115
+ numberOfLines: 1,
2116
+ style: {
2117
+ flexShrink: 1,
2118
+ color: isActive ? theme.colors.primary : theme.colors.text,
2119
+ fontSize: theme.fontSize.md,
2120
+ fontWeight: "500"
2121
+ },
2122
+ children: agent.name || "Untitled"
2123
+ }
2124
+ ),
2125
+ agent.orchestra && /* @__PURE__ */ jsxs6(
2126
+ View3,
2127
+ {
2128
+ accessibilityLabel: orchestraDelegatesLine(agent.orchestra) ?? orchestraLabel(agent.orchestra),
2129
+ style: [
2130
+ styles5.badge,
2131
+ {
2132
+ backgroundColor: theme.colors.primarySoft,
2133
+ borderRadius: theme.radius.sm
2134
+ }
2135
+ ],
2136
+ children: [
2137
+ /* @__PURE__ */ jsx9(
2138
+ AgentIcon,
2139
+ {
2140
+ name: "music4",
2141
+ size: 10,
2142
+ color: theme.colors.primary,
2143
+ report: errorSink
2144
+ }
2145
+ ),
2146
+ /* @__PURE__ */ jsx9(
2147
+ Text6,
2148
+ {
2149
+ style: { color: theme.colors.primary, fontSize: theme.fontSize.xs },
2150
+ children: agent.orchestra.memberCount
2151
+ }
2152
+ )
2153
+ ]
2154
+ }
2155
+ ),
2156
+ /* @__PURE__ */ jsx9(View3, { style: styles5.spacer }),
2157
+ agent.agentType === "builtin" ? /* @__PURE__ */ jsx9(
2158
+ Text6,
2159
+ {
2160
+ style: [
2161
+ styles5.originBadge,
2162
+ {
2163
+ color: theme.colors.primary,
2164
+ backgroundColor: theme.colors.primarySoft,
2165
+ borderRadius: theme.radius.sm,
2166
+ fontSize: theme.fontSize.xs
2167
+ }
2168
+ ],
2169
+ children: labels.systemBadge
2170
+ }
2171
+ ) : agent.isOwner === false ? /* @__PURE__ */ jsx9(
2172
+ Text6,
2173
+ {
2174
+ style: [
2175
+ styles5.originBadge,
2176
+ {
2177
+ color: theme.colors.textMuted,
2178
+ backgroundColor: theme.colors.surface,
2179
+ borderRadius: theme.radius.sm,
2180
+ fontSize: theme.fontSize.xs
2181
+ }
2182
+ ],
2183
+ children: "shared"
2184
+ }
2185
+ ) : null
2186
+ ]
2187
+ }
2188
+ ),
2189
+ /* @__PURE__ */ jsx9(
2190
+ Pressable7,
2191
+ {
2192
+ onPress: onDetailPress,
2193
+ accessibilityRole: "button",
2194
+ accessibilityLabel: `Show details for ${agent.name || "Untitled"}`,
2195
+ hitSlop: 6,
2196
+ style: ({ pressed }) => [
2197
+ styles5.detailButton,
2198
+ {
2199
+ backgroundColor: pressed ? theme.colors.surfacePressed : "transparent"
2200
+ }
2201
+ ],
2202
+ children: /* @__PURE__ */ jsx9(
2203
+ AgentIcon,
2204
+ {
2205
+ name: "chevronRight",
2206
+ size: 16,
2207
+ color: theme.colors.textFaint,
2208
+ report: errorSink
2209
+ }
2210
+ )
2211
+ }
2212
+ )
2213
+ ]
2214
+ }
2215
+ );
2216
+ }
2217
+ var styles5 = StyleSheet5.create({
2218
+ row: { flexDirection: "row", alignItems: "stretch" },
2219
+ main: {
2220
+ flex: 1,
2221
+ flexDirection: "row",
2222
+ alignItems: "center",
2223
+ gap: 6,
2224
+ paddingVertical: 10,
2225
+ minWidth: 0
2226
+ },
2227
+ spacer: { flex: 1 },
2228
+ badge: {
2229
+ flexDirection: "row",
2230
+ alignItems: "center",
2231
+ gap: 2,
2232
+ paddingHorizontal: 4,
2233
+ paddingVertical: 1
2234
+ },
2235
+ originBadge: {
2236
+ overflow: "hidden",
2237
+ paddingHorizontal: 4,
2238
+ paddingVertical: 1,
2239
+ fontWeight: "500"
2240
+ },
2241
+ detailButton: {
2242
+ width: 40,
2243
+ alignItems: "center",
2244
+ justifyContent: "center"
2245
+ }
2246
+ });
2247
+
2248
+ // catalog/native/AgentListContent.tsx
2249
+ import { jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
2250
+ function AgentListContent({
2251
+ agents,
2252
+ isLoading,
2253
+ consumer,
2254
+ activeAgentId,
2255
+ allCategories,
2256
+ allTags,
2257
+ onSelectAgent,
2258
+ onDetailPress,
2259
+ onFilterChipPress,
2260
+ onReset,
2261
+ activeFilterCount,
2262
+ tabCounts,
2263
+ visibleTabs,
2264
+ systemTabLabel,
2265
+ pinnedAgent = null,
2266
+ defaultRow = null,
2267
+ autoFocusSearch = false
2268
+ }) {
2269
+ const catalog = useAgentCatalog();
2270
+ const theme = useAgentCatalogNativeTheme();
2271
+ const { labels, errorSink } = catalog;
2272
+ const emptyLabel = agentListEmptyLabel(consumer.tab, labels);
2273
+ const defaultAgent = defaultRow?.row ?? null;
2274
+ const items = [];
2275
+ if (defaultAgent) {
2276
+ items.push({ key: "label-default", kind: "label", text: "Default" });
2277
+ items.push({
2278
+ key: `default-${defaultAgent.id}`,
2279
+ kind: "row",
2280
+ agent: defaultAgent,
2281
+ forceActive: defaultAgent.id === activeAgentId
2282
+ });
2283
+ items.push({ key: "divider-default", kind: "divider" });
2284
+ }
2285
+ if (pinnedAgent) {
2286
+ items.push({
2287
+ key: "label-pinned",
2288
+ kind: "label",
2289
+ text: labels.currentAgentHeading
2290
+ });
2291
+ items.push({
2292
+ key: `pinned-${pinnedAgent.id}`,
2293
+ kind: "row",
2294
+ agent: pinnedAgent,
2295
+ forceActive: true
2296
+ });
2297
+ items.push({ key: "divider-pinned", kind: "divider" });
2298
+ }
2299
+ for (const agent of agents) {
2300
+ items.push({
2301
+ key: agent.id,
2302
+ kind: "row",
2303
+ agent,
2304
+ forceActive: agent.id === activeAgentId
2305
+ });
2306
+ }
2307
+ const hairline = {
2308
+ height: StyleSheet6.hairlineWidth,
2309
+ backgroundColor: theme.colors.border
2310
+ };
2311
+ return /* @__PURE__ */ jsxs7(View4, { style: [styles6.container, { backgroundColor: theme.colors.background }], children: [
2312
+ /* @__PURE__ */ jsx10(View4, { style: { paddingHorizontal: theme.spacing.sm, paddingBottom: 6 }, children: /* @__PURE__ */ jsx10(
2313
+ SearchInput,
2314
+ {
2315
+ value: consumer.searchTerm,
2316
+ onChange: consumer.setSearchTerm,
2317
+ placeholder: labels.searchPlaceholder,
2318
+ autoFocus: autoFocusSearch
2319
+ }
2320
+ ) }),
2321
+ /* @__PURE__ */ jsx10(
2322
+ AgentListTabs,
2323
+ {
2324
+ consumer,
2325
+ tabCounts,
2326
+ visibleTabs,
2327
+ systemTabLabel
2328
+ }
2329
+ ),
2330
+ /* @__PURE__ */ jsx10(
2331
+ AgentFilterBar,
2332
+ {
2333
+ consumer,
2334
+ allCategories,
2335
+ allTags,
2336
+ activeFilterCount,
2337
+ onFilterChipPress,
2338
+ onReset
2339
+ }
2340
+ ),
2341
+ defaultRow?.drift && /* @__PURE__ */ jsxs7(
2342
+ View4,
2343
+ {
2344
+ accessibilityRole: "alert",
2345
+ style: [
2346
+ styles6.banner,
2347
+ {
2348
+ marginHorizontal: theme.spacing.sm,
2349
+ borderRadius: theme.radius.md,
2350
+ backgroundColor: theme.colors.driftBackground,
2351
+ borderColor: theme.colors.driftBorder
2352
+ }
2353
+ ],
2354
+ children: [
2355
+ /* @__PURE__ */ jsx10(
2356
+ AgentIcon,
2357
+ {
2358
+ name: "alertTriangle",
2359
+ size: 14,
2360
+ color: theme.colors.driftForeground,
2361
+ report: errorSink
2362
+ }
2363
+ ),
2364
+ /* @__PURE__ */ jsx10(
2365
+ Text7,
2366
+ {
2367
+ style: {
2368
+ flex: 1,
2369
+ color: theme.colors.driftForeground,
2370
+ fontSize: theme.fontSize.sm
2371
+ },
2372
+ children: defaultRow.drift
2373
+ }
2374
+ ),
2375
+ /* @__PURE__ */ jsx10(
2376
+ Pressable8,
2377
+ {
2378
+ onPress: () => catalog.dismissDefaultRowDrift(defaultRow.mandateKey),
2379
+ accessibilityRole: "button",
2380
+ accessibilityLabel: "Dismiss",
2381
+ hitSlop: 8,
2382
+ children: /* @__PURE__ */ jsx10(
2383
+ AgentIcon,
2384
+ {
2385
+ name: "x",
2386
+ size: 12,
2387
+ color: theme.colors.driftForeground,
2388
+ report: errorSink
2389
+ }
2390
+ )
2391
+ }
2392
+ )
2393
+ ]
2394
+ }
2395
+ ),
2396
+ defaultRow?.error && /* @__PURE__ */ jsxs7(
2397
+ View4,
2398
+ {
2399
+ accessibilityRole: "alert",
2400
+ style: [
2401
+ styles6.banner,
2402
+ {
2403
+ marginHorizontal: theme.spacing.sm,
2404
+ borderRadius: theme.radius.md,
2405
+ backgroundColor: theme.colors.driftBackground,
2406
+ borderColor: theme.colors.driftBorder
2407
+ }
2408
+ ],
2409
+ children: [
2410
+ /* @__PURE__ */ jsx10(
2411
+ AgentIcon,
2412
+ {
2413
+ name: "alertTriangle",
2414
+ size: 14,
2415
+ color: theme.colors.driftForeground,
2416
+ report: errorSink
2417
+ }
2418
+ ),
2419
+ /* @__PURE__ */ jsx10(
2420
+ Text7,
2421
+ {
2422
+ style: {
2423
+ flex: 1,
2424
+ color: theme.colors.driftForeground,
2425
+ fontSize: theme.fontSize.sm
2426
+ },
2427
+ children: defaultRow.error
2428
+ }
2429
+ )
2430
+ ]
2431
+ }
2432
+ ),
2433
+ /* @__PURE__ */ jsx10(View4, { style: hairline }),
2434
+ isLoading ? /* @__PURE__ */ jsxs7(View4, { style: styles6.centered, children: [
2435
+ /* @__PURE__ */ jsx10(
2436
+ AgentIcon,
2437
+ {
2438
+ name: "loader",
2439
+ size: 16,
2440
+ color: theme.colors.textMuted,
2441
+ report: errorSink
2442
+ }
2443
+ ),
2444
+ /* @__PURE__ */ jsx10(Text7, { style: { color: theme.colors.textMuted, fontSize: theme.fontSize.md }, children: labels.loading })
2445
+ ] }) : items.length === 0 ? /* @__PURE__ */ jsx10(View4, { style: styles6.centered, children: /* @__PURE__ */ jsx10(Text7, { style: { color: theme.colors.textMuted, fontSize: theme.fontSize.md }, children: emptyLabel }) }) : /* @__PURE__ */ jsx10(
2446
+ FlatList,
2447
+ {
2448
+ style: styles6.list,
2449
+ data: items,
2450
+ keyExtractor: (item) => item.key,
2451
+ keyboardShouldPersistTaps: "handled",
2452
+ renderItem: ({ item }) => {
2453
+ if (item.kind === "divider") return /* @__PURE__ */ jsx10(View4, { style: hairline });
2454
+ if (item.kind === "label") {
2455
+ return /* @__PURE__ */ jsx10(
2456
+ Text7,
2457
+ {
2458
+ style: {
2459
+ color: theme.colors.textMuted,
2460
+ fontSize: theme.fontSize.xs,
2461
+ fontWeight: "600",
2462
+ textTransform: "uppercase",
2463
+ paddingHorizontal: theme.spacing.md,
2464
+ paddingTop: 8,
2465
+ paddingBottom: 2
2466
+ },
2467
+ children: item.text
2468
+ }
2469
+ );
2470
+ }
2471
+ return /* @__PURE__ */ jsx10(
2472
+ AgentRow,
2473
+ {
2474
+ agent: item.agent,
2475
+ isActive: item.forceActive,
2476
+ onPress: () => onSelectAgent(item.agent),
2477
+ onDetailPress: () => onDetailPress(item.agent)
2478
+ }
2479
+ );
2480
+ },
2481
+ ListFooterComponent: agents.length === 0 && (pinnedAgent || defaultAgent) ? /* @__PURE__ */ jsx10(View4, { style: styles6.centered, children: /* @__PURE__ */ jsx10(
2482
+ Text7,
2483
+ {
2484
+ style: {
2485
+ color: theme.colors.textMuted,
2486
+ fontSize: theme.fontSize.md
2487
+ },
2488
+ children: emptyLabel
2489
+ }
2490
+ ) }) : null
2491
+ }
2492
+ ),
2493
+ /* @__PURE__ */ jsx10(View4, { style: hairline }),
2494
+ /* @__PURE__ */ jsxs7(View4, { style: [styles6.footer, { paddingHorizontal: theme.spacing.md }], children: [
2495
+ /* @__PURE__ */ jsxs7(
2496
+ Text7,
2497
+ {
2498
+ style: {
2499
+ color: theme.colors.textMuted,
2500
+ fontSize: theme.fontSize.xs,
2501
+ fontVariant: ["tabular-nums"]
2502
+ },
2503
+ children: [
2504
+ agents.length,
2505
+ " agent",
2506
+ agents.length !== 1 ? "s" : ""
2507
+ ]
2508
+ }
2509
+ ),
2510
+ consumer.searchTerm.length > 0 && /* @__PURE__ */ jsx10(
2511
+ Pressable8,
2512
+ {
2513
+ onPress: () => consumer.setSearchTerm(""),
2514
+ accessibilityRole: "button",
2515
+ accessibilityLabel: "Clear search",
2516
+ hitSlop: 8,
2517
+ children: /* @__PURE__ */ jsx10(
2518
+ Text7,
2519
+ {
2520
+ style: { color: theme.colors.textMuted, fontSize: theme.fontSize.xs },
2521
+ children: "Clear search"
2522
+ }
2523
+ )
2524
+ }
2525
+ )
2526
+ ] })
2527
+ ] });
2528
+ }
2529
+ var styles6 = StyleSheet6.create({
2530
+ container: { flex: 1, minHeight: 0 },
2531
+ list: { flex: 1, minHeight: 0 },
2532
+ banner: {
2533
+ flexDirection: "row",
2534
+ alignItems: "flex-start",
2535
+ gap: 8,
2536
+ marginBottom: 6,
2537
+ paddingHorizontal: 8,
2538
+ paddingVertical: 6,
2539
+ borderWidth: StyleSheet6.hairlineWidth
2540
+ },
2541
+ centered: {
2542
+ alignItems: "center",
2543
+ justifyContent: "center",
2544
+ gap: 8,
2545
+ paddingVertical: 32
2546
+ },
2547
+ footer: {
2548
+ flexDirection: "row",
2549
+ alignItems: "center",
2550
+ justifyContent: "space-between",
2551
+ paddingVertical: 8
2552
+ }
2553
+ });
2554
+
2555
+ // catalog/native/AgentSubView.tsx
2556
+ import { Pressable as Pressable9, ScrollView as ScrollView4, StyleSheet as StyleSheet7, Text as Text8, View as View5 } from "react-native";
2557
+ import { Fragment, jsx as jsx11, jsxs as jsxs8 } from "react/jsx-runtime";
2558
+ function AgentSubView({
2559
+ view,
2560
+ consumer,
2561
+ allCategories,
2562
+ allTags,
2563
+ search,
2564
+ setSearch,
2565
+ onBack
2566
+ }) {
2567
+ const theme = useAgentCatalogNativeTheme();
2568
+ const title = view === "sort" ? "Sort" : view === "categories" ? "Categories" : "Tags";
2569
+ const values = view === "categories" ? allCategories : allTags;
2570
+ const included = view === "categories" ? consumer.includedCats : consumer.includedTags;
2571
+ const filtered = values.filter(
2572
+ (value) => !search || value.toLowerCase().includes(search.toLowerCase())
2573
+ );
2574
+ return /* @__PURE__ */ jsxs8(View5, { style: styles7.container, children: [
2575
+ /* @__PURE__ */ jsx11(SidePanelHeader, { title, onClose: onBack }),
2576
+ view === "sort" ? /* @__PURE__ */ jsx11(ScrollView4, { style: styles7.list, children: SORT_OPTIONS.map((option) => /* @__PURE__ */ jsx11(
2577
+ OptionRow,
2578
+ {
2579
+ label: option.label,
2580
+ selected: consumer.sortBy === option.value,
2581
+ onPress: () => {
2582
+ consumer.setSortBy(option.value);
2583
+ onBack();
2584
+ }
2585
+ },
2586
+ option.value
2587
+ )) }) : /* @__PURE__ */ jsxs8(Fragment, { children: [
2588
+ /* @__PURE__ */ jsx11(View5, { style: { paddingHorizontal: theme.spacing.sm, paddingVertical: 6 }, children: /* @__PURE__ */ jsx11(
2589
+ SearchInput,
2590
+ {
2591
+ value: search,
2592
+ onChange: setSearch,
2593
+ placeholder: view === "categories" ? "Filter categories..." : "Filter tags..."
2594
+ }
2595
+ ) }),
2596
+ included.length > 0 && /* @__PURE__ */ jsx11(
2597
+ Pressable9,
2598
+ {
2599
+ onPress: () => view === "categories" ? consumer.setIncludedCats([]) : consumer.setIncludedTags([]),
2600
+ accessibilityRole: "button",
2601
+ accessibilityLabel: `Clear ${included.length} filters`,
2602
+ style: {
2603
+ marginHorizontal: theme.spacing.sm,
2604
+ marginBottom: 4,
2605
+ paddingVertical: 6
2606
+ },
2607
+ children: /* @__PURE__ */ jsxs8(
2608
+ Text8,
2609
+ {
2610
+ style: {
2611
+ color: theme.colors.primary,
2612
+ fontSize: theme.fontSize.sm,
2613
+ fontWeight: "600"
2614
+ },
2615
+ children: [
2616
+ "Clear (",
2617
+ included.length,
2618
+ ")"
2619
+ ]
2620
+ }
2621
+ )
2622
+ }
2623
+ ),
2624
+ /* @__PURE__ */ jsx11(ScrollView4, { style: styles7.list, children: filtered.length === 0 ? /* @__PURE__ */ jsx11(
2625
+ Text8,
2626
+ {
2627
+ style: {
2628
+ color: theme.colors.textMuted,
2629
+ fontSize: theme.fontSize.md,
2630
+ textAlign: "center",
2631
+ paddingVertical: 24
2632
+ },
2633
+ children: view === "categories" ? "No categories" : "No tags"
2634
+ }
2635
+ ) : filtered.map((value) => /* @__PURE__ */ jsx11(
2636
+ CheckRow,
2637
+ {
2638
+ label: value,
2639
+ checked: included.includes(value),
2640
+ onPress: () => view === "categories" ? consumer.toggleCategory(value) : consumer.toggleTag(value)
2641
+ },
2642
+ value
2643
+ )) })
2644
+ ] })
2645
+ ] });
2646
+ }
2647
+ var styles7 = StyleSheet7.create({
2648
+ container: { flex: 1, minHeight: 0 },
2649
+ list: { flex: 1, minHeight: 0 }
2650
+ });
2651
+
2652
+ // catalog/native/AgentPickerBody.tsx
2653
+ import { jsx as jsx12 } from "react/jsx-runtime";
2654
+ function AgentPickerBody({
2655
+ consumerId,
2656
+ onSelect,
2657
+ activeAgentId = null,
2658
+ autoFocusSearch = false,
2659
+ initialTab,
2660
+ includeSystemInAll = false,
2661
+ visibleTabs,
2662
+ systemTabLabel,
2663
+ showPinnedAgent = true,
2664
+ excludeAgentIds,
2665
+ defaultMandateKey,
2666
+ compact = false,
2667
+ onAfterSelect
2668
+ }) {
2669
+ const [detailAgent, setDetailAgent] = useState3(null);
2670
+ const [subView, setSubView] = useState3(null);
2671
+ const [panelSearch, setPanelSearch] = useState3("");
2672
+ const {
2673
+ agents,
2674
+ isLoading,
2675
+ allCategories,
2676
+ allTags,
2677
+ consumer,
2678
+ tabCounts,
2679
+ activeFilterCount,
2680
+ pinnedAgent,
2681
+ defaultRow,
2682
+ ensureLoaded,
2683
+ handleSelectAgent: coreSelectAgent
2684
+ } = useAgentListCore({
2685
+ consumerId,
2686
+ onSelect,
2687
+ activeAgentIdOverride: activeAgentId,
2688
+ ...initialTab ? { initialTab } : {},
2689
+ includeSystemInAll,
2690
+ // The restriction has to reach the CORE, not just the tab strip.
2691
+ ...visibleTabs ? { visibleTabs } : {},
2692
+ ...excludeAgentIds ? { excludeAgentIds } : {},
2693
+ ...defaultMandateKey ? { defaultMandateKey } : {}
2694
+ });
2695
+ useEffect3(() => {
2696
+ ensureLoaded();
2697
+ }, [ensureLoaded]);
2698
+ const selectAgent = (agent) => {
2699
+ coreSelectAgent(agent);
2700
+ setDetailAgent(null);
2701
+ setSubView(null);
2702
+ onAfterSelect?.();
2703
+ };
2704
+ if (detailAgent) {
2705
+ return /* @__PURE__ */ jsx12(View6, { style: styles8.fill, children: /* @__PURE__ */ jsx12(
2706
+ AgentDetailCard,
2707
+ {
2708
+ agent: detailAgent,
2709
+ onSelect: () => selectAgent(detailAgent)
2710
+ }
2711
+ ) });
2712
+ }
2713
+ if (subView) {
2714
+ return /* @__PURE__ */ jsx12(View6, { style: styles8.fill, children: /* @__PURE__ */ jsx12(
2715
+ AgentSubView,
2716
+ {
2717
+ view: subView,
2718
+ consumer,
2719
+ allCategories,
2720
+ allTags,
2721
+ search: panelSearch,
2722
+ setSearch: setPanelSearch,
2723
+ onBack: () => {
2724
+ setSubView(null);
2725
+ setPanelSearch("");
2726
+ }
2727
+ }
2728
+ ) });
2729
+ }
2730
+ return /* @__PURE__ */ jsx12(View6, { style: [styles8.fill, compact ? styles8.compact : null], children: /* @__PURE__ */ jsx12(
2731
+ AgentListContent,
2732
+ {
2733
+ agents,
2734
+ isLoading,
2735
+ consumer,
2736
+ activeAgentId,
2737
+ allCategories,
2738
+ allTags,
2739
+ onSelectAgent: selectAgent,
2740
+ onDetailPress: setDetailAgent,
2741
+ onFilterChipPress: setSubView,
2742
+ onReset: consumer.resetFilters,
2743
+ activeFilterCount,
2744
+ tabCounts,
2745
+ ...visibleTabs ? { visibleTabs } : {},
2746
+ ...systemTabLabel ?? (includeSystemInAll ? "System" : void 0) ? {
2747
+ systemTabLabel: systemTabLabel ?? (includeSystemInAll ? "System" : void 0)
2748
+ } : {},
2749
+ pinnedAgent: showPinnedAgent ? pinnedAgent : null,
2750
+ defaultRow,
2751
+ autoFocusSearch
2752
+ }
2753
+ ) });
2754
+ }
2755
+ var styles8 = StyleSheet8.create({
2756
+ fill: { flex: 1, minHeight: 0 },
2757
+ compact: { paddingTop: 0 }
2758
+ });
2759
+
2760
+ // catalog/native/AgentListSheet.tsx
2761
+ import { jsx as jsx13, jsxs as jsxs9 } from "react/jsx-runtime";
2762
+ function AgentListSheet({ title, ...props }) {
2763
+ const theme = useAgentCatalogNativeTheme();
2764
+ return /* @__PURE__ */ jsxs9(View7, { style: [styles9.sheet, { backgroundColor: theme.colors.background }], children: [
2765
+ title ? /* @__PURE__ */ jsx13(
2766
+ Text9,
2767
+ {
2768
+ accessibilityRole: "header",
2769
+ style: {
2770
+ color: theme.colors.text,
2771
+ fontSize: theme.fontSize.lg + 3,
2772
+ fontWeight: "700",
2773
+ paddingHorizontal: theme.spacing.md,
2774
+ paddingTop: theme.spacing.sm,
2775
+ paddingBottom: theme.spacing.sm
2776
+ },
2777
+ children: title
2778
+ }
2779
+ ) : null,
2780
+ /* @__PURE__ */ jsx13(AgentPickerBody, { ...props })
2781
+ ] });
2782
+ }
2783
+ var styles9 = StyleSheet9.create({
2784
+ sheet: { flex: 1, minHeight: 0 }
2785
+ });
2786
+
2787
+ // catalog/native/AgentListInlinePicker.tsx
2788
+ import { StyleSheet as StyleSheet10, View as View8 } from "react-native";
2789
+ import { jsx as jsx14 } from "react/jsx-runtime";
2790
+ function AgentListInlinePicker(props) {
2791
+ return /* @__PURE__ */ jsx14(View8, { style: styles10.fill, children: /* @__PURE__ */ jsx14(AgentPickerBody, { ...props }) });
2792
+ }
2793
+ var styles10 = StyleSheet10.create({
2794
+ fill: { flex: 1, minHeight: 0 }
2795
+ });
2796
+ export {
2797
+ AgentCatalogProvider,
2798
+ AgentDetailCard,
2799
+ AgentFilterBar,
2800
+ AgentIcon,
2801
+ AgentListContent,
2802
+ AgentListInlinePicker,
2803
+ AgentListSheet,
2804
+ AgentListTabs,
2805
+ AgentPickerBody,
2806
+ AgentRow,
2807
+ AgentSubView,
2808
+ CheckRow,
2809
+ DEFAULT_AGENT_CATALOG_NATIVE_THEME,
2810
+ FavoriteAgentButton,
2811
+ FilterChip,
2812
+ HOVER_GRACE_MS,
2813
+ LIGHT_AGENT_CATALOG_NATIVE_THEME,
2814
+ OptionRow,
2815
+ SearchInput,
2816
+ SidePanelHeader,
2817
+ _resetNativeIconState,
2818
+ announceMissingSvgOnce,
2819
+ coerceVisibleTab,
2820
+ orchestraDelegatesLine,
2821
+ orchestraDepthLine,
2822
+ orchestraLabel,
2823
+ orchestraModeLabel,
2824
+ resolveAgentCatalogNativeTheme,
2825
+ resolveSvgModule,
2826
+ useAgentCatalog,
2827
+ useAgentCatalogNativeTheme,
2828
+ useAgentCatalogRows,
2829
+ useAgentCatalogState,
2830
+ useAgentCatalogUiPorts,
2831
+ useAgentConsumer,
2832
+ useAgentListCore
2833
+ };
2834
+ //# sourceMappingURL=index.js.map