@ai-matrx/agents 0.8.0 → 0.9.0

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,2802 @@
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 applyAgentSortComparator(a, b, sortBy) {
529
+ switch (sortBy) {
530
+ case "name-asc":
531
+ return (a.name ?? "").localeCompare(b.name ?? "");
532
+ case "name-desc":
533
+ return (b.name ?? "").localeCompare(a.name ?? "");
534
+ case "created-desc":
535
+ return +new Date(b.createdAt ?? 0) - +new Date(a.createdAt ?? 0);
536
+ case "category-asc":
537
+ return (a.category ?? "").localeCompare(b.category ?? "");
538
+ case "updated-desc":
539
+ default:
540
+ return +new Date(b.updatedAt ?? 0) - +new Date(a.updatedAt ?? 0);
541
+ }
542
+ }
543
+ var selectAllAgentCategories = memoize1(
544
+ (agents) => {
545
+ const cats = /* @__PURE__ */ new Set();
546
+ for (const a of agents) {
547
+ if (a.agentType === "user" && a.category) cats.add(a.category);
548
+ }
549
+ return Array.from(cats).sort();
550
+ }
551
+ );
552
+ var selectAllSystemAgentCategories = memoize1(
553
+ (agents) => {
554
+ const cats = /* @__PURE__ */ new Set();
555
+ for (const a of agents) {
556
+ if (a.agentType === "builtin" && a.category) cats.add(a.category);
557
+ }
558
+ return Array.from(cats).sort();
559
+ }
560
+ );
561
+ var selectAllAgentTags = memoize1(
562
+ (agents) => {
563
+ const tags = /* @__PURE__ */ new Set();
564
+ for (const a of agents) {
565
+ if (a.agentType === "user") a.tags?.forEach((t) => tags.add(t));
566
+ }
567
+ return Array.from(tags).sort();
568
+ }
569
+ );
570
+ var selectAllSystemAgentTags = memoize1(
571
+ (agents) => {
572
+ const tags = /* @__PURE__ */ new Set();
573
+ for (const a of agents) {
574
+ if (a.agentType === "builtin") a.tags?.forEach((t) => tags.add(t));
575
+ }
576
+ return Array.from(tags).sort();
577
+ }
578
+ );
579
+ var selectUserTypeAgents = memoize1(
580
+ (agents) => agents.filter((a) => a.agentType === "user")
581
+ );
582
+ var selectBuiltinTypeAgents = memoize1(
583
+ (agents) => agents.filter((a) => a.agentType === "builtin")
584
+ );
585
+ function sortFilteredAgents(filtered, consumer) {
586
+ const { searchTerm, sortBy, favFilter, favoritesFirst } = consumer;
587
+ if (searchTerm) {
588
+ const scores = /* @__PURE__ */ new Map();
589
+ filtered.forEach((a) => {
590
+ scores.set(a.id, computeAgentSearchScore(a, searchTerm));
591
+ });
592
+ const serverRank = /* @__PURE__ */ new Map();
593
+ consumer.serverMatchedIds.forEach((id, i) => serverRank.set(id, i));
594
+ return [...filtered].sort((a, b) => {
595
+ const sa = scores.get(a.id) ?? 0;
596
+ const sb = scores.get(b.id) ?? 0;
597
+ if (sb !== sa) return sb - sa;
598
+ if (sa === 0) {
599
+ const ra = serverRank.get(a.id);
600
+ const rb = serverRank.get(b.id);
601
+ if (ra !== void 0 && rb !== void 0 && ra !== rb) return ra - rb;
602
+ }
603
+ return applyAgentSortComparator(a, b, sortBy);
604
+ });
605
+ }
606
+ return [...filtered].sort((a, b) => {
607
+ if (favoritesFirst && favFilter === "all") {
608
+ const aFav = a.isFavorite ? 1 : 0;
609
+ const bFav = b.isFavorite ? 1 : 0;
610
+ if (bFav !== aFav) return bFav - aFav;
611
+ }
612
+ return applyAgentSortComparator(a, b, sortBy);
613
+ });
614
+ }
615
+ function filterUserTypeAgents(agents, consumer) {
616
+ const {
617
+ searchTerm,
618
+ includedCats,
619
+ includedTags,
620
+ favFilter,
621
+ archFilter,
622
+ accessFilter,
623
+ tab
624
+ } = consumer;
625
+ const serverMatched = new Set(consumer.serverMatchedIds);
626
+ const filtered = agents.filter((agent) => {
627
+ if (tab === "mine" && agent.isOwner !== true) return false;
628
+ if (tab === "shared" && !(agent.isOwner === false && agent.accessLevel != null))
629
+ return false;
630
+ if (archFilter === "active" && agent.isArchived) return false;
631
+ if (archFilter === "archived" && !agent.isArchived) return false;
632
+ if (favFilter === "yes" && !agent.isFavorite) return false;
633
+ if (favFilter === "no" && agent.isFavorite) return false;
634
+ if (accessFilter === "owned" && agent.isOwner !== true) return false;
635
+ if (accessFilter === "shared" && agent.isOwner !== false) return false;
636
+ if (accessFilter === "editable" && agent.accessLevel !== "owner" && agent.accessLevel !== "admin" && agent.accessLevel !== "editor")
637
+ return false;
638
+ if (includedCats.length > 0) {
639
+ const category = agent.category;
640
+ if (!category) {
641
+ if (!includedCats.includes(AGENT_NONE_SENTINEL)) return false;
642
+ } else if (!includedCats.includes(category)) {
643
+ return false;
644
+ }
645
+ }
646
+ if (includedTags.length > 0) {
647
+ const isUntagged = !agent.tags?.length;
648
+ if (isUntagged) {
649
+ if (!includedTags.includes(AGENT_NONE_SENTINEL)) return false;
650
+ } else if (!agent.tags?.some((t) => includedTags.includes(t))) {
651
+ return false;
652
+ }
653
+ }
654
+ if (searchTerm && !agentMatchesSearch(agent, searchTerm) && !serverMatched.has(agent.id))
655
+ return false;
656
+ return true;
657
+ });
658
+ return sortFilteredAgents(filtered, consumer);
659
+ }
660
+ function filterBuiltinTypeAgents(agents, consumer) {
661
+ const { searchTerm, favFilter, includedCats, includedTags } = consumer;
662
+ const serverMatched = new Set(consumer.serverMatchedIds);
663
+ const filtered = agents.filter((agent) => {
664
+ if (favFilter === "yes" && !agent.isFavorite) return false;
665
+ if (favFilter === "no" && agent.isFavorite) return false;
666
+ if (includedCats.length > 0) {
667
+ const category = agent.category;
668
+ if (!category) {
669
+ if (!includedCats.includes(AGENT_NONE_SENTINEL)) return false;
670
+ } else if (!includedCats.includes(category)) {
671
+ return false;
672
+ }
673
+ }
674
+ if (includedTags.length > 0) {
675
+ const isUntagged = !agent.tags?.length;
676
+ if (isUntagged) {
677
+ if (!includedTags.includes(AGENT_NONE_SENTINEL)) return false;
678
+ } else if (!agent.tags?.some((t) => includedTags.includes(t))) {
679
+ return false;
680
+ }
681
+ }
682
+ if (searchTerm && !agentMatchesSearch(agent, searchTerm) && !serverMatched.has(agent.id))
683
+ return false;
684
+ return true;
685
+ });
686
+ return sortFilteredAgents(filtered, consumer);
687
+ }
688
+ var makeSelectFilteredAgents = (includeSystemInAll = false) => memoize2(
689
+ (agents, consumer) => {
690
+ const userAgents = selectUserTypeAgents(agents);
691
+ const builtinAgents = selectBuiltinTypeAgents(agents);
692
+ if (consumer.tab === "system") {
693
+ return filterBuiltinTypeAgents(builtinAgents, consumer);
694
+ }
695
+ if (includeSystemInAll && consumer.tab === "all") {
696
+ return [
697
+ ...filterUserTypeAgents(userAgents, consumer),
698
+ ...filterBuiltinTypeAgents(builtinAgents, consumer)
699
+ ];
700
+ }
701
+ return filterUserTypeAgents(userAgents, consumer);
702
+ }
703
+ );
704
+ var selectTotalUserAgentsCount = memoize1(
705
+ (agents) => selectUserTypeAgents(agents).length
706
+ );
707
+ var selectTotalOwnedAgentsCount = memoize1(
708
+ (agents) => selectUserTypeAgents(agents).filter((a) => a.isOwner === true).length
709
+ );
710
+ var selectTotalSharedAgentsCount = memoize1(
711
+ (agents) => selectUserTypeAgents(agents).filter(
712
+ (a) => a.isOwner === false && a.accessLevel != null
713
+ ).length
714
+ );
715
+ var selectTotalBuiltinAgentsCount = memoize1(
716
+ (agents) => selectBuiltinTypeAgents(agents).length
717
+ );
718
+ var selectTotalFavoriteAgentsCount = memoize1(
719
+ (agents) => selectUserTypeAgents(agents).filter((a) => a.isFavorite).length
720
+ );
721
+
722
+ // catalog/shared/useAgentListCore.ts
723
+ var HOVER_GRACE_MS = 900;
724
+ function coerceVisibleTab(current, allowed, initialTab) {
725
+ if (allowed.length === 0) return null;
726
+ if (allowed.includes(current)) return null;
727
+ return initialTab && allowed.includes(initialTab) ? initialTab : allowed[0] ?? null;
728
+ }
729
+ var EMPTY_EXCLUDES = [];
730
+ function useAgentListCore({
731
+ consumerId,
732
+ onSelect,
733
+ navigateTo,
734
+ activeAgentIdOverride,
735
+ initialTab,
736
+ includeSystemInAll = false,
737
+ visibleTabs,
738
+ excludeAgentIds = EMPTY_EXCLUDES,
739
+ defaultMandateKey
740
+ }) {
741
+ const catalog = useAgentCatalog();
742
+ const { navigate } = useAgentCatalogUiPorts();
743
+ const hasFetchedRef = useRef2(false);
744
+ const [hoveredAgent, setHoveredAgent] = useState2(null);
745
+ const hoverLeaveTimerRef = useRef2(null);
746
+ const defaultTabAppliedRef = useRef2(false);
747
+ const consumer = useAgentConsumer(consumerId, { unregisterOnUnmount: true });
748
+ const rows = useAgentCatalogRows();
749
+ const userId = catalog.getUserIdOrNull();
750
+ const ownedCount = selectTotalOwnedAgentsCount(rows);
751
+ const selectFiltered = useMemo3(
752
+ () => makeSelectFilteredAgents(includeSystemInAll),
753
+ [includeSystemInAll]
754
+ );
755
+ const filteredAgents = selectFiltered(rows, consumer.state);
756
+ const excludedAgentIds = useMemo3(
757
+ () => new Set(excludeAgentIds),
758
+ [excludeAgentIds]
759
+ );
760
+ const agents = excludedAgentIds.size === 0 ? filteredAgents : filteredAgents.filter((agent) => !excludedAgentIds.has(agent.id));
761
+ const status = useAgentCatalogState(selectStatus);
762
+ const activeAgentId = activeAgentIdOverride ?? null;
763
+ const pinnedAgent = activeAgentId ? catalog.getAgent(activeAgentId) : void 0;
764
+ const onSystemTab = consumer.tab === "system";
765
+ const allCategories = onSystemTab ? selectAllSystemAgentCategories(rows) : selectAllAgentCategories(rows);
766
+ const allTags = onSystemTab ? selectAllSystemAgentTags(rows) : selectAllAgentTags(rows);
767
+ const tabCounts = {
768
+ mine: ownedCount,
769
+ shared: selectTotalSharedAgentsCount(rows),
770
+ all: selectTotalUserAgentsCount(rows),
771
+ system: selectTotalBuiltinAgentsCount(rows)
772
+ };
773
+ const isLoading = status === "loading";
774
+ const agentsLoaded = status === "succeeded" || status === "failed";
775
+ const ensureLoaded = useCallback3(() => {
776
+ if (!hasFetchedRef.current) {
777
+ hasFetchedRef.current = true;
778
+ void catalog.ensureLoaded().catch(() => {
779
+ });
780
+ }
781
+ }, [catalog]);
782
+ const selectDefaultRow = useCallback3(
783
+ (state) => defaultMandateKey ? state.defaultRows[defaultMandateKey] : void 0,
784
+ [defaultMandateKey]
785
+ );
786
+ const defaultRow = useAgentCatalogState(selectDefaultRow);
787
+ useEffect2(() => {
788
+ if (!defaultMandateKey) return;
789
+ catalog.ensureDefaultRow(defaultMandateKey);
790
+ }, [catalog, defaultMandateKey]);
791
+ useEffect2(() => {
792
+ if (defaultTabAppliedRef.current) return;
793
+ if (initialTab) {
794
+ defaultTabAppliedRef.current = true;
795
+ if (consumer.tab !== initialTab) consumer.setTab(initialTab);
796
+ return;
797
+ }
798
+ if (consumer.tab !== "mine") {
799
+ defaultTabAppliedRef.current = true;
800
+ return;
801
+ }
802
+ const wantsPublic = shouldDefaultAgentListToPublicTab({
803
+ userId,
804
+ ownedCount,
805
+ agentsLoaded
806
+ });
807
+ if (!wantsPublic) {
808
+ if (!userId || agentsLoaded) {
809
+ defaultTabAppliedRef.current = true;
810
+ }
811
+ return;
812
+ }
813
+ consumer.setTab("system");
814
+ defaultTabAppliedRef.current = true;
815
+ }, [
816
+ userId,
817
+ ownedCount,
818
+ agentsLoaded,
819
+ initialTab,
820
+ consumer.tab,
821
+ consumer.setTab
822
+ ]);
823
+ const allowedTabsKey = visibleTabs ? visibleTabs.join(",") : "";
824
+ useEffect2(() => {
825
+ if (!allowedTabsKey) return;
826
+ const next = coerceVisibleTab(
827
+ consumer.tab,
828
+ allowedTabsKey.split(","),
829
+ initialTab
830
+ );
831
+ if (next) consumer.setTab(next);
832
+ }, [allowedTabsKey, initialTab, consumer.tab, consumer.setTab]);
833
+ useEffect2(() => {
834
+ ensureLoaded();
835
+ }, [ensureLoaded]);
836
+ const handleSelectAgent = useCallback3(
837
+ (agent) => {
838
+ if (onSelect) {
839
+ onSelect(agent.id);
840
+ } else if (navigateTo) {
841
+ navigate(navigateTo.replace("{id}", agent.id));
842
+ } else {
843
+ catalog.errorSink({
844
+ code: "select_has_nowhere_to_go",
845
+ message: "an agent was chosen but this picker was given neither onSelect nor navigateTo, so the choice went nowhere.",
846
+ context: { consumerId, agentId: agent.id }
847
+ });
848
+ }
849
+ },
850
+ [onSelect, navigateTo, navigate, catalog, consumerId]
851
+ );
852
+ 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);
853
+ const handleAgentHover = useCallback3(
854
+ (agent, panelOpen) => {
855
+ if (panelOpen) return;
856
+ if (hoverLeaveTimerRef.current) {
857
+ clearTimeout(hoverLeaveTimerRef.current);
858
+ hoverLeaveTimerRef.current = null;
859
+ }
860
+ setHoveredAgent(agent);
861
+ },
862
+ []
863
+ );
864
+ const handleAgentHoverEnd = useCallback3(
865
+ (agent, onClear) => {
866
+ if (hoveredAgent?.id === agent.id) {
867
+ hoverLeaveTimerRef.current = setTimeout(() => {
868
+ setHoveredAgent(null);
869
+ onClear();
870
+ }, HOVER_GRACE_MS);
871
+ }
872
+ },
873
+ [hoveredAgent]
874
+ );
875
+ const handleDetailPanelMouseEnter = useCallback3(() => {
876
+ if (hoverLeaveTimerRef.current) {
877
+ clearTimeout(hoverLeaveTimerRef.current);
878
+ hoverLeaveTimerRef.current = null;
879
+ }
880
+ }, []);
881
+ const handleDetailPanelMouseLeave = useCallback3((onClear) => {
882
+ hoverLeaveTimerRef.current = setTimeout(() => {
883
+ setHoveredAgent(null);
884
+ onClear();
885
+ }, HOVER_GRACE_MS);
886
+ }, []);
887
+ useEffect2(
888
+ () => () => {
889
+ if (hoverLeaveTimerRef.current) clearTimeout(hoverLeaveTimerRef.current);
890
+ },
891
+ []
892
+ );
893
+ return {
894
+ agents,
895
+ isLoading,
896
+ activeAgentId,
897
+ pinnedAgent: pinnedAgent ?? null,
898
+ defaultRow: defaultRow ?? null,
899
+ allCategories,
900
+ allTags,
901
+ consumer,
902
+ tabCounts,
903
+ activeFilterCount,
904
+ hoveredAgent,
905
+ setHoveredAgent,
906
+ ensureLoaded,
907
+ handleSelectAgent,
908
+ handleAgentHover,
909
+ handleAgentHoverEnd,
910
+ handleDetailPanelMouseEnter,
911
+ handleDetailPanelMouseLeave
912
+ };
913
+ }
914
+ var selectStatus = (state) => state.status;
915
+
916
+ // catalog/native/AgentDetailCard.tsx
917
+ import { Pressable as Pressable3, ScrollView, StyleSheet, Text as Text3, View } from "react-native";
918
+
919
+ // catalog/orchestra.ts
920
+ var ORCHESTRA_MODE_LABEL = {
921
+ supervisor: "supervisor",
922
+ sequential: "in order",
923
+ parallel: "together",
924
+ dag: "custom flow"
925
+ };
926
+ function orchestraModeLabel(mode) {
927
+ return ORCHESTRA_MODE_LABEL[mode] ?? mode;
928
+ }
929
+ function orchestraLabel(badge) {
930
+ const n = badge.memberCount;
931
+ return `Orchestra \xB7 ${orchestraModeLabel(badge.mode)} \xB7 ${n} ${n === 1 ? "member" : "members"}`;
932
+ }
933
+ function orchestraDepthLine(badge) {
934
+ const n = badge.depthBudget;
935
+ if (typeof n !== "number" || n <= 0) return null;
936
+ return `Team members can call helpers up to ${n} ${n === 1 ? "level" : "levels"} deep`;
937
+ }
938
+ function orchestraDelegatesLine(badge, limit = 3) {
939
+ const titles = badge.memberTitles;
940
+ if (titles.length === 0) return null;
941
+ const shown = titles.slice(0, limit);
942
+ const extra = titles.length - shown.length;
943
+ return `Delegates to: ${shown.join(", ")}${extra > 0 ? ` +${extra} more` : ""}`;
944
+ }
945
+
946
+ // catalog/native/icons.tsx
947
+ import { Text as Text2 } from "react-native";
948
+
949
+ // catalog/shared/icon-paths.ts
950
+ var SHAPES = {
951
+ star: {
952
+ paths: [
953
+ "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"
954
+ ],
955
+ fillable: true
956
+ },
957
+ chevronRight: { paths: ["m9 18 6-6-6-6"] },
958
+ chevronDown: { paths: ["m6 9 6 6 6-6"] },
959
+ search: {
960
+ paths: ["m21 21-4.3-4.3"],
961
+ circles: [{ cx: 11, cy: 11, r: 8 }]
962
+ },
963
+ x: { paths: ["M18 6 6 18", "m6 6 12 12"] },
964
+ check: { paths: ["M20 6 9 17l-5-5"] },
965
+ arrowUpDown: {
966
+ paths: ["m21 16-4 4-4-4", "M17 20V4", "m3 8 4-4 4 4", "M7 4v16"]
967
+ },
968
+ folder: {
969
+ paths: [
970
+ "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"
971
+ ]
972
+ },
973
+ tag: {
974
+ paths: [
975
+ "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"
976
+ ],
977
+ circles: [{ cx: 7.5, cy: 7.5, r: 0.5, filled: true }]
978
+ },
979
+ rotateCcw: {
980
+ paths: [
981
+ "M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8",
982
+ "M3 3v5h5"
983
+ ]
984
+ },
985
+ loader: { paths: ["M21 12a9 9 0 1 1-6.219-8.56"] },
986
+ alertTriangle: {
987
+ paths: [
988
+ "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",
989
+ "M12 9v4",
990
+ "M12 17h.01"
991
+ ]
992
+ },
993
+ /**
994
+ * The Orchestra marker (Lucide `music-4`): the glyph the Workflow Studio's
995
+ * picker used for a conductor, kept identical so the same agent wears the
996
+ * same mark in every client.
997
+ */
998
+ music4: {
999
+ paths: ["M9 18V5l12-2v13", "m9 9 12-2"],
1000
+ circles: [
1001
+ { cx: 6, cy: 18, r: 3 },
1002
+ { cx: 18, cy: 16, r: 3 }
1003
+ ]
1004
+ },
1005
+ clock: {
1006
+ paths: ["M12 6v6l4 2"],
1007
+ circles: [{ cx: 12, cy: 12, r: 10 }]
1008
+ },
1009
+ globe: {
1010
+ paths: ["M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20", "M2 12h20"],
1011
+ circles: [{ cx: 12, cy: 12, r: 10 }]
1012
+ },
1013
+ users: {
1014
+ paths: [
1015
+ "M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2",
1016
+ "M22 21v-2a4 4 0 0 0-3-3.87",
1017
+ "M16 3.13a4 4 0 0 1 0 7.75"
1018
+ ],
1019
+ circles: [{ cx: 9, cy: 7, r: 4 }]
1020
+ },
1021
+ externalLink: {
1022
+ paths: [
1023
+ "M15 3h6v6",
1024
+ "M10 14 21 3",
1025
+ "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"
1026
+ ]
1027
+ },
1028
+ messageCircle: { paths: ["M7.9 20A9 9 0 1 0 4 16.1L2 22Z"] },
1029
+ rocket: {
1030
+ paths: [
1031
+ "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",
1032
+ "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",
1033
+ "M9 12H4s.55-3.03 2-4c1.62-1.08 5 0 5 0",
1034
+ "M12 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5"
1035
+ ]
1036
+ },
1037
+ circleCheck: {
1038
+ paths: ["m9 12 2 2 4-4"],
1039
+ circles: [{ cx: 12, cy: 12, r: 10 }]
1040
+ }
1041
+ };
1042
+ var ICON_PATHS = SHAPES;
1043
+ var ICON_NAMES = Object.keys(ICON_PATHS);
1044
+
1045
+ // catalog/native/icons.tsx
1046
+ import { jsx as jsx3, jsxs } from "react/jsx-runtime";
1047
+ var STATE_KEY = /* @__PURE__ */ Symbol.for("ai-matrx.agents.catalog.native.icons");
1048
+ function getIconsGlobalState() {
1049
+ const store = globalThis;
1050
+ const existing = store[STATE_KEY];
1051
+ if (existing) return existing;
1052
+ const created = { svg: void 0, announced: false };
1053
+ store[STATE_KEY] = created;
1054
+ return created;
1055
+ }
1056
+ function _resetNativeIconState(svg) {
1057
+ const state = getIconsGlobalState();
1058
+ state.svg = svg === void 0 ? void 0 : svg;
1059
+ state.announced = false;
1060
+ }
1061
+ function isSvgModule(value) {
1062
+ if (typeof value !== "object" || value === null) return false;
1063
+ const record = value;
1064
+ return Boolean(record["Path"] && record["Circle"] && record["default"]);
1065
+ }
1066
+ function resolveSvgModule() {
1067
+ const state = getIconsGlobalState();
1068
+ if (state.svg !== void 0) return state.svg;
1069
+ let resolved = null;
1070
+ try {
1071
+ const required = globalThis.require?.("react-native-svg");
1072
+ if (isSvgModule(required)) resolved = required;
1073
+ else {
1074
+ const viaModule = __require("react-native-svg");
1075
+ if (isSvgModule(viaModule)) resolved = viaModule;
1076
+ }
1077
+ } catch {
1078
+ resolved = null;
1079
+ }
1080
+ state.svg = resolved;
1081
+ return resolved;
1082
+ }
1083
+ function announceMissingSvgOnce(report) {
1084
+ const state = getIconsGlobalState();
1085
+ if (state.announced) return;
1086
+ state.announced = true;
1087
+ report({
1088
+ code: "native_icons_degraded_to_text",
1089
+ 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.",
1090
+ context: {
1091
+ remedy: "run `npx expo install react-native-svg` (it is an optional peer of @ai-matrx/agents) and reload to get the real icons"
1092
+ }
1093
+ });
1094
+ }
1095
+ var TEXT_GLYPHS = {
1096
+ star: "\u2605",
1097
+ chevronRight: "\u203A",
1098
+ chevronDown: "\u2304",
1099
+ search: "\u2315",
1100
+ x: "\u2715",
1101
+ check: "\u2713",
1102
+ arrowUpDown: "\u21C5",
1103
+ folder: "\u25A4",
1104
+ tag: "\u2317",
1105
+ rotateCcw: "\u21BA",
1106
+ loader: "\u25CC",
1107
+ alertTriangle: "\u26A0",
1108
+ music4: "\u266A",
1109
+ clock: "\u25F7",
1110
+ globe: "\u2295",
1111
+ users: "\u2687",
1112
+ externalLink: "\u2197",
1113
+ messageCircle: "\u2709",
1114
+ rocket: "\u27A4",
1115
+ circleCheck: "\u2713"
1116
+ };
1117
+ function AgentIcon({
1118
+ name,
1119
+ size = 14,
1120
+ color,
1121
+ filled = false,
1122
+ report
1123
+ }) {
1124
+ const svg = resolveSvgModule();
1125
+ if (!svg) {
1126
+ announceMissingSvgOnce(report);
1127
+ return /* @__PURE__ */ jsx3(
1128
+ Text2,
1129
+ {
1130
+ accessible: false,
1131
+ style: { color, fontSize: size, lineHeight: size * 1.2 },
1132
+ children: TEXT_GLYPHS[name]
1133
+ }
1134
+ );
1135
+ }
1136
+ const Svg = svg.default;
1137
+ const Path = svg.Path;
1138
+ const Circle = svg.Circle;
1139
+ const shape = ICON_PATHS[name];
1140
+ return /* @__PURE__ */ jsxs(
1141
+ Svg,
1142
+ {
1143
+ width: size,
1144
+ height: size,
1145
+ viewBox: "0 0 24 24",
1146
+ fill: "none",
1147
+ stroke: color,
1148
+ strokeWidth: 2,
1149
+ strokeLinecap: "round",
1150
+ strokeLinejoin: "round",
1151
+ children: [
1152
+ shape.paths.map((d, index) => /* @__PURE__ */ jsx3(
1153
+ Path,
1154
+ {
1155
+ d,
1156
+ ...filled && shape.fillable ? { fill: color } : {}
1157
+ },
1158
+ `p${index}`
1159
+ )),
1160
+ (shape.circles ?? []).map((circle, index) => /* @__PURE__ */ jsx3(
1161
+ Circle,
1162
+ {
1163
+ cx: circle.cx,
1164
+ cy: circle.cy,
1165
+ r: circle.r,
1166
+ ...circle.filled ? { fill: color } : {}
1167
+ },
1168
+ `c${index}`
1169
+ ))
1170
+ ]
1171
+ }
1172
+ );
1173
+ }
1174
+
1175
+ // catalog/native/FavoriteAgentButton.tsx
1176
+ import { useCallback as useCallback4 } from "react";
1177
+ import { Pressable as Pressable2 } from "react-native";
1178
+ import { jsx as jsx4 } from "react/jsx-runtime";
1179
+ function FavoriteAgentButton({
1180
+ id,
1181
+ size = 18,
1182
+ disabled
1183
+ }) {
1184
+ const catalog = useAgentCatalog();
1185
+ const theme = useAgentCatalogNativeTheme();
1186
+ const select = useCallback4((state) => state.byId[id], [id]);
1187
+ const record = useAgentCatalogState(select);
1188
+ const isFavorite = record?.isFavorite ?? false;
1189
+ const isOwner = record?.isOwner ?? true;
1190
+ const inert = Boolean(disabled) || !isOwner;
1191
+ const title = isOwner ? isFavorite ? "Remove from favorites" : "Add to favorites" : "Shared \u2014 cannot favorite";
1192
+ return /* @__PURE__ */ jsx4(
1193
+ Pressable2,
1194
+ {
1195
+ onPress: () => {
1196
+ if (inert) return;
1197
+ void catalog.setFavorite(id, !isFavorite).catch(() => {
1198
+ });
1199
+ },
1200
+ disabled: inert,
1201
+ hitSlop: 8,
1202
+ accessibilityRole: "button",
1203
+ accessibilityLabel: title,
1204
+ accessibilityState: { disabled: inert, selected: isFavorite },
1205
+ style: { opacity: inert ? 0.4 : 1 },
1206
+ children: /* @__PURE__ */ jsx4(
1207
+ AgentIcon,
1208
+ {
1209
+ name: "star",
1210
+ size,
1211
+ filled: isFavorite,
1212
+ color: isFavorite ? theme.colors.favorite : theme.colors.textFaint,
1213
+ report: catalog.errorSink
1214
+ }
1215
+ )
1216
+ }
1217
+ );
1218
+ }
1219
+
1220
+ // catalog/native/AgentDetailCard.tsx
1221
+ import { jsx as jsx5, jsxs as jsxs2 } from "react/jsx-runtime";
1222
+ function formatDate(value) {
1223
+ if (!value) return null;
1224
+ const date = new Date(value);
1225
+ if (Number.isNaN(date.getTime())) return null;
1226
+ return date.toLocaleDateString(void 0, {
1227
+ month: "short",
1228
+ day: "numeric",
1229
+ year: "numeric"
1230
+ });
1231
+ }
1232
+ function AgentDetailCard({ agent, onSelect }) {
1233
+ const { errorSink } = useAgentCatalog();
1234
+ const { renderModelRef, openPeek } = useAgentCatalogUiPorts();
1235
+ const theme = useAgentCatalogNativeTheme();
1236
+ const isDefaultRow = isMandateAgentId(agent.id);
1237
+ const updated = formatDate(agent.updatedAt);
1238
+ const created = formatDate(agent.createdAt);
1239
+ return /* @__PURE__ */ jsxs2(View, { style: styles.container, children: [
1240
+ /* @__PURE__ */ jsxs2(View, { style: [styles.header, { padding: theme.spacing.md }], children: [
1241
+ /* @__PURE__ */ jsxs2(View, { style: { flex: 1, minWidth: 0 }, children: [
1242
+ /* @__PURE__ */ jsx5(
1243
+ Text3,
1244
+ {
1245
+ numberOfLines: 2,
1246
+ style: {
1247
+ color: theme.colors.text,
1248
+ fontSize: theme.fontSize.lg,
1249
+ fontWeight: "600"
1250
+ },
1251
+ children: agent.name || "Untitled"
1252
+ }
1253
+ ),
1254
+ agent.isFavorite && /* @__PURE__ */ jsx5(
1255
+ Text3,
1256
+ {
1257
+ style: { color: theme.colors.favorite, fontSize: theme.fontSize.sm },
1258
+ children: "Pinned to favorites"
1259
+ }
1260
+ )
1261
+ ] }),
1262
+ !isDefaultRow && /* @__PURE__ */ jsx5(FavoriteAgentButton, { id: agent.id })
1263
+ ] }),
1264
+ /* @__PURE__ */ jsx5(View, { style: { height: StyleSheet.hairlineWidth, backgroundColor: theme.colors.border } }),
1265
+ /* @__PURE__ */ jsxs2(
1266
+ ScrollView,
1267
+ {
1268
+ style: styles.body,
1269
+ contentContainerStyle: { padding: theme.spacing.md, gap: theme.spacing.md },
1270
+ children: [
1271
+ agent.orchestra && /* @__PURE__ */ jsxs2(
1272
+ View,
1273
+ {
1274
+ style: [
1275
+ styles.orchestra,
1276
+ {
1277
+ borderColor: theme.colors.primary,
1278
+ backgroundColor: theme.colors.primarySoft,
1279
+ borderRadius: theme.radius.md,
1280
+ padding: theme.spacing.sm
1281
+ }
1282
+ ],
1283
+ children: [
1284
+ /* @__PURE__ */ jsxs2(View, { style: styles.inline, children: [
1285
+ /* @__PURE__ */ jsx5(
1286
+ AgentIcon,
1287
+ {
1288
+ name: "music4",
1289
+ size: 14,
1290
+ color: theme.colors.primary,
1291
+ report: errorSink
1292
+ }
1293
+ ),
1294
+ /* @__PURE__ */ jsx5(
1295
+ Text3,
1296
+ {
1297
+ style: {
1298
+ color: theme.colors.primary,
1299
+ fontSize: theme.fontSize.sm,
1300
+ fontWeight: "600"
1301
+ },
1302
+ children: orchestraLabel(agent.orchestra)
1303
+ }
1304
+ )
1305
+ ] }),
1306
+ agent.orchestra.tagline && /* @__PURE__ */ jsx5(Text3, { style: { color: theme.colors.text, fontSize: theme.fontSize.md }, children: agent.orchestra.tagline }),
1307
+ orchestraDelegatesLine(agent.orchestra) && /* @__PURE__ */ jsx5(
1308
+ Text3,
1309
+ {
1310
+ style: { color: theme.colors.textMuted, fontSize: theme.fontSize.sm },
1311
+ children: orchestraDelegatesLine(agent.orchestra)
1312
+ }
1313
+ ),
1314
+ orchestraDepthLine(agent.orchestra) && /* @__PURE__ */ jsx5(
1315
+ Text3,
1316
+ {
1317
+ style: { color: theme.colors.textMuted, fontSize: theme.fontSize.sm },
1318
+ children: orchestraDepthLine(agent.orchestra)
1319
+ }
1320
+ )
1321
+ ]
1322
+ }
1323
+ ),
1324
+ agent.description && /* @__PURE__ */ jsxs2(View, { style: { gap: 4 }, children: [
1325
+ /* @__PURE__ */ jsx5(
1326
+ Text3,
1327
+ {
1328
+ style: {
1329
+ color: theme.colors.textMuted,
1330
+ fontSize: theme.fontSize.sm,
1331
+ fontWeight: "600",
1332
+ textTransform: "uppercase"
1333
+ },
1334
+ children: "Description"
1335
+ }
1336
+ ),
1337
+ /* @__PURE__ */ jsx5(Text3, { style: { color: theme.colors.text, fontSize: theme.fontSize.md }, children: agent.description })
1338
+ ] }),
1339
+ agent.category && /* @__PURE__ */ jsxs2(View, { style: styles.inline, children: [
1340
+ /* @__PURE__ */ jsx5(
1341
+ AgentIcon,
1342
+ {
1343
+ name: "folder",
1344
+ size: 14,
1345
+ color: theme.colors.textMuted,
1346
+ report: errorSink
1347
+ }
1348
+ ),
1349
+ /* @__PURE__ */ jsx5(Text3, { style: { color: theme.colors.text, fontSize: theme.fontSize.md }, children: agent.category })
1350
+ ] }),
1351
+ agent.tags.length > 0 && /* @__PURE__ */ jsxs2(View, { style: { gap: 6 }, children: [
1352
+ /* @__PURE__ */ jsxs2(View, { style: styles.inline, children: [
1353
+ /* @__PURE__ */ jsx5(
1354
+ AgentIcon,
1355
+ {
1356
+ name: "tag",
1357
+ size: 14,
1358
+ color: theme.colors.textMuted,
1359
+ report: errorSink
1360
+ }
1361
+ ),
1362
+ /* @__PURE__ */ jsx5(
1363
+ Text3,
1364
+ {
1365
+ style: { color: theme.colors.textMuted, fontSize: theme.fontSize.sm },
1366
+ children: "Tags"
1367
+ }
1368
+ )
1369
+ ] }),
1370
+ /* @__PURE__ */ jsx5(View, { style: styles.tagWrap, children: agent.tags.map((tag) => /* @__PURE__ */ jsx5(
1371
+ Text3,
1372
+ {
1373
+ style: {
1374
+ color: theme.colors.textMuted,
1375
+ backgroundColor: theme.colors.surface,
1376
+ borderRadius: theme.radius.sm,
1377
+ overflow: "hidden",
1378
+ paddingHorizontal: 6,
1379
+ paddingVertical: 2,
1380
+ fontSize: theme.fontSize.xs
1381
+ },
1382
+ children: tag
1383
+ },
1384
+ tag
1385
+ )) })
1386
+ ] }),
1387
+ agent.accessLevel && /* @__PURE__ */ jsxs2(View, { style: styles.inline, children: [
1388
+ /* @__PURE__ */ jsx5(
1389
+ AgentIcon,
1390
+ {
1391
+ name: agent.isOwner === false ? "users" : "globe",
1392
+ size: 14,
1393
+ color: theme.colors.textMuted,
1394
+ report: errorSink
1395
+ }
1396
+ ),
1397
+ /* @__PURE__ */ jsxs2(View, { children: [
1398
+ /* @__PURE__ */ jsx5(Text3, { style: { color: theme.colors.text, fontSize: theme.fontSize.md }, children: agent.accessLevel === "owner" ? "You own this" : `Shared \u2014 ${agent.accessLevel}` }),
1399
+ agent.sharedByEmail && /* @__PURE__ */ jsxs2(
1400
+ Text3,
1401
+ {
1402
+ style: { color: theme.colors.textMuted, fontSize: theme.fontSize.xs },
1403
+ children: [
1404
+ "by ",
1405
+ agent.sharedByEmail
1406
+ ]
1407
+ }
1408
+ )
1409
+ ] })
1410
+ ] }),
1411
+ agent.modelId && /* @__PURE__ */ jsx5(View, { children: renderModelRef({ modelId: agent.modelId }) }),
1412
+ (updated || created) && /* @__PURE__ */ jsxs2(View, { style: { gap: 4 }, children: [
1413
+ updated && /* @__PURE__ */ jsxs2(View, { style: styles.inline, children: [
1414
+ /* @__PURE__ */ jsx5(
1415
+ AgentIcon,
1416
+ {
1417
+ name: "clock",
1418
+ size: 13,
1419
+ color: theme.colors.textMuted,
1420
+ report: errorSink
1421
+ }
1422
+ ),
1423
+ /* @__PURE__ */ jsxs2(
1424
+ Text3,
1425
+ {
1426
+ style: { color: theme.colors.textMuted, fontSize: theme.fontSize.sm },
1427
+ children: [
1428
+ "Updated ",
1429
+ updated
1430
+ ]
1431
+ }
1432
+ )
1433
+ ] }),
1434
+ created && /* @__PURE__ */ jsxs2(View, { style: styles.inline, children: [
1435
+ /* @__PURE__ */ jsx5(
1436
+ AgentIcon,
1437
+ {
1438
+ name: "clock",
1439
+ size: 13,
1440
+ color: theme.colors.textFaint,
1441
+ report: errorSink
1442
+ }
1443
+ ),
1444
+ /* @__PURE__ */ jsxs2(
1445
+ Text3,
1446
+ {
1447
+ style: { color: theme.colors.textFaint, fontSize: theme.fontSize.sm },
1448
+ children: [
1449
+ "Created ",
1450
+ created
1451
+ ]
1452
+ }
1453
+ )
1454
+ ] })
1455
+ ] })
1456
+ ]
1457
+ }
1458
+ ),
1459
+ /* @__PURE__ */ jsx5(View, { style: { height: StyleSheet.hairlineWidth, backgroundColor: theme.colors.border } }),
1460
+ /* @__PURE__ */ jsxs2(View, { style: [styles.footer, { padding: theme.spacing.sm }], children: [
1461
+ /* @__PURE__ */ jsx5(
1462
+ Pressable3,
1463
+ {
1464
+ onPress: onSelect,
1465
+ accessibilityRole: "button",
1466
+ accessibilityLabel: `Select ${agent.name || "Untitled"}`,
1467
+ style: ({ pressed }) => [
1468
+ styles.selectButton,
1469
+ {
1470
+ borderRadius: theme.radius.md,
1471
+ backgroundColor: theme.colors.primary,
1472
+ opacity: pressed ? 0.85 : 1
1473
+ }
1474
+ ],
1475
+ children: /* @__PURE__ */ jsx5(
1476
+ Text3,
1477
+ {
1478
+ style: {
1479
+ color: theme.colors.primaryForeground,
1480
+ fontSize: theme.fontSize.md,
1481
+ fontWeight: "600"
1482
+ },
1483
+ children: "Select"
1484
+ }
1485
+ )
1486
+ }
1487
+ ),
1488
+ openPeek && /* @__PURE__ */ jsx5(
1489
+ Pressable3,
1490
+ {
1491
+ onPress: () => openPeek(agent),
1492
+ accessibilityRole: "button",
1493
+ accessibilityLabel: "Sneak Peek",
1494
+ style: ({ pressed }) => [
1495
+ styles.iconButton,
1496
+ {
1497
+ borderRadius: theme.radius.md,
1498
+ borderColor: theme.colors.border,
1499
+ backgroundColor: pressed ? theme.colors.surfacePressed : theme.colors.surface
1500
+ }
1501
+ ],
1502
+ children: /* @__PURE__ */ jsx5(
1503
+ AgentIcon,
1504
+ {
1505
+ name: "rocket",
1506
+ size: 14,
1507
+ color: theme.colors.textMuted,
1508
+ report: errorSink
1509
+ }
1510
+ )
1511
+ }
1512
+ )
1513
+ ] })
1514
+ ] });
1515
+ }
1516
+ var styles = StyleSheet.create({
1517
+ container: { flex: 1, minHeight: 0 },
1518
+ header: { flexDirection: "row", alignItems: "flex-start", gap: 12 },
1519
+ body: { flex: 1, minHeight: 0 },
1520
+ inline: { flexDirection: "row", alignItems: "center", gap: 8 },
1521
+ orchestra: { borderWidth: StyleSheet.hairlineWidth, gap: 4 },
1522
+ tagWrap: { flexDirection: "row", flexWrap: "wrap", gap: 4 },
1523
+ footer: { flexDirection: "row", alignItems: "center", gap: 8 },
1524
+ selectButton: {
1525
+ flex: 1,
1526
+ height: 40,
1527
+ alignItems: "center",
1528
+ justifyContent: "center"
1529
+ },
1530
+ iconButton: {
1531
+ width: 40,
1532
+ height: 40,
1533
+ alignItems: "center",
1534
+ justifyContent: "center",
1535
+ borderWidth: StyleSheet.hairlineWidth
1536
+ }
1537
+ });
1538
+
1539
+ // catalog/native/AgentListContent.tsx
1540
+ import { FlatList, Pressable as Pressable8, StyleSheet as StyleSheet6, Text as Text7, View as View4 } from "react-native";
1541
+
1542
+ // catalog/native/AgentFilterBar.tsx
1543
+ import { Pressable as Pressable5, ScrollView as ScrollView2, StyleSheet as StyleSheet3 } from "react-native";
1544
+
1545
+ // catalog/native/primitives.tsx
1546
+ import { Pressable as Pressable4, StyleSheet as StyleSheet2, Text as Text4, TextInput, View as View2 } from "react-native";
1547
+ import { jsx as jsx6, jsxs as jsxs3 } from "react/jsx-runtime";
1548
+ function SearchInput({
1549
+ value,
1550
+ onChange,
1551
+ placeholder,
1552
+ autoFocus = false
1553
+ }) {
1554
+ const theme = useAgentCatalogNativeTheme();
1555
+ const { errorSink } = useAgentCatalog();
1556
+ return /* @__PURE__ */ jsxs3(
1557
+ View2,
1558
+ {
1559
+ style: [
1560
+ styles2.searchWrap,
1561
+ {
1562
+ backgroundColor: theme.colors.surface,
1563
+ borderColor: theme.colors.border,
1564
+ borderRadius: theme.radius.md,
1565
+ paddingHorizontal: theme.spacing.sm
1566
+ }
1567
+ ],
1568
+ children: [
1569
+ /* @__PURE__ */ jsx6(
1570
+ AgentIcon,
1571
+ {
1572
+ name: "search",
1573
+ size: 14,
1574
+ color: theme.colors.textMuted,
1575
+ report: errorSink
1576
+ }
1577
+ ),
1578
+ /* @__PURE__ */ jsx6(
1579
+ TextInput,
1580
+ {
1581
+ value,
1582
+ onChangeText: onChange,
1583
+ placeholder,
1584
+ placeholderTextColor: theme.colors.textFaint,
1585
+ autoFocus,
1586
+ autoCorrect: false,
1587
+ autoCapitalize: "none",
1588
+ returnKeyType: "search",
1589
+ accessibilityLabel: placeholder,
1590
+ style: [styles2.searchInput, { color: theme.colors.text }]
1591
+ }
1592
+ ),
1593
+ value.length > 0 && /* @__PURE__ */ jsx6(
1594
+ Pressable4,
1595
+ {
1596
+ onPress: () => onChange(""),
1597
+ accessibilityRole: "button",
1598
+ accessibilityLabel: "Clear search",
1599
+ hitSlop: 8,
1600
+ children: /* @__PURE__ */ jsx6(
1601
+ AgentIcon,
1602
+ {
1603
+ name: "x",
1604
+ size: 13,
1605
+ color: theme.colors.textMuted,
1606
+ report: errorSink
1607
+ }
1608
+ )
1609
+ }
1610
+ )
1611
+ ]
1612
+ }
1613
+ );
1614
+ }
1615
+ function FilterChip({
1616
+ icon,
1617
+ label,
1618
+ active,
1619
+ onPress
1620
+ }) {
1621
+ const theme = useAgentCatalogNativeTheme();
1622
+ const { errorSink } = useAgentCatalog();
1623
+ const tint = active ? theme.colors.primary : theme.colors.textMuted;
1624
+ return /* @__PURE__ */ jsxs3(
1625
+ Pressable4,
1626
+ {
1627
+ onPress,
1628
+ accessibilityRole: "button",
1629
+ accessibilityState: { selected: active },
1630
+ accessibilityLabel: label,
1631
+ style: ({ pressed }) => [
1632
+ styles2.chip,
1633
+ {
1634
+ borderRadius: theme.radius.sm,
1635
+ backgroundColor: active ? theme.colors.primarySoft : pressed ? theme.colors.surfacePressed : "transparent",
1636
+ borderColor: active ? theme.colors.primary : "transparent"
1637
+ }
1638
+ ],
1639
+ children: [
1640
+ /* @__PURE__ */ jsx6(AgentIcon, { name: icon, size: 12, color: tint, report: errorSink }),
1641
+ /* @__PURE__ */ jsx6(Text4, { style: { color: tint, fontSize: theme.fontSize.sm, fontWeight: "500" }, children: label })
1642
+ ]
1643
+ }
1644
+ );
1645
+ }
1646
+ function OptionRow({
1647
+ label,
1648
+ selected,
1649
+ onPress
1650
+ }) {
1651
+ const theme = useAgentCatalogNativeTheme();
1652
+ const { errorSink } = useAgentCatalog();
1653
+ return /* @__PURE__ */ jsxs3(
1654
+ Pressable4,
1655
+ {
1656
+ onPress,
1657
+ accessibilityRole: "button",
1658
+ accessibilityState: { selected },
1659
+ style: ({ pressed }) => [
1660
+ styles2.optionRow,
1661
+ {
1662
+ paddingHorizontal: theme.spacing.md,
1663
+ backgroundColor: pressed ? theme.colors.surfacePressed : "transparent"
1664
+ }
1665
+ ],
1666
+ children: [
1667
+ /* @__PURE__ */ jsx6(
1668
+ Text4,
1669
+ {
1670
+ style: {
1671
+ flex: 1,
1672
+ color: selected ? theme.colors.primary : theme.colors.text,
1673
+ fontSize: theme.fontSize.md,
1674
+ fontWeight: selected ? "600" : "400"
1675
+ },
1676
+ children: label
1677
+ }
1678
+ ),
1679
+ selected && /* @__PURE__ */ jsx6(
1680
+ AgentIcon,
1681
+ {
1682
+ name: "check",
1683
+ size: 14,
1684
+ color: theme.colors.primary,
1685
+ report: errorSink
1686
+ }
1687
+ )
1688
+ ]
1689
+ }
1690
+ );
1691
+ }
1692
+ function CheckRow({
1693
+ label,
1694
+ checked,
1695
+ onPress
1696
+ }) {
1697
+ const theme = useAgentCatalogNativeTheme();
1698
+ const { errorSink } = useAgentCatalog();
1699
+ return /* @__PURE__ */ jsxs3(
1700
+ Pressable4,
1701
+ {
1702
+ onPress,
1703
+ accessibilityRole: "checkbox",
1704
+ accessibilityState: { checked },
1705
+ style: ({ pressed }) => [
1706
+ styles2.checkRow,
1707
+ {
1708
+ paddingHorizontal: theme.spacing.md,
1709
+ backgroundColor: pressed ? theme.colors.surfacePressed : "transparent"
1710
+ }
1711
+ ],
1712
+ children: [
1713
+ /* @__PURE__ */ jsx6(
1714
+ View2,
1715
+ {
1716
+ style: [
1717
+ styles2.checkBox,
1718
+ {
1719
+ borderRadius: theme.radius.sm,
1720
+ borderColor: checked ? theme.colors.primary : theme.colors.border,
1721
+ backgroundColor: checked ? theme.colors.primary : "transparent"
1722
+ }
1723
+ ],
1724
+ children: checked && /* @__PURE__ */ jsx6(
1725
+ AgentIcon,
1726
+ {
1727
+ name: "check",
1728
+ size: 10,
1729
+ color: theme.colors.primaryForeground,
1730
+ report: errorSink
1731
+ }
1732
+ )
1733
+ }
1734
+ ),
1735
+ /* @__PURE__ */ jsx6(
1736
+ Text4,
1737
+ {
1738
+ numberOfLines: 1,
1739
+ style: { flex: 1, color: theme.colors.text, fontSize: theme.fontSize.md },
1740
+ children: label
1741
+ }
1742
+ )
1743
+ ]
1744
+ }
1745
+ );
1746
+ }
1747
+ function SidePanelHeader({
1748
+ title,
1749
+ onClose
1750
+ }) {
1751
+ const theme = useAgentCatalogNativeTheme();
1752
+ const { errorSink } = useAgentCatalog();
1753
+ return /* @__PURE__ */ jsxs3(
1754
+ View2,
1755
+ {
1756
+ style: [
1757
+ styles2.panelHeader,
1758
+ {
1759
+ paddingHorizontal: theme.spacing.md,
1760
+ borderBottomColor: theme.colors.border
1761
+ }
1762
+ ],
1763
+ children: [
1764
+ /* @__PURE__ */ jsx6(
1765
+ Text4,
1766
+ {
1767
+ style: {
1768
+ color: theme.colors.text,
1769
+ fontSize: theme.fontSize.md,
1770
+ fontWeight: "600"
1771
+ },
1772
+ children: title
1773
+ }
1774
+ ),
1775
+ /* @__PURE__ */ jsx6(
1776
+ Pressable4,
1777
+ {
1778
+ onPress: onClose,
1779
+ accessibilityRole: "button",
1780
+ accessibilityLabel: "Close",
1781
+ hitSlop: 8,
1782
+ children: /* @__PURE__ */ jsx6(
1783
+ AgentIcon,
1784
+ {
1785
+ name: "x",
1786
+ size: 14,
1787
+ color: theme.colors.textMuted,
1788
+ report: errorSink
1789
+ }
1790
+ )
1791
+ }
1792
+ )
1793
+ ]
1794
+ }
1795
+ );
1796
+ }
1797
+ var styles2 = StyleSheet2.create({
1798
+ searchWrap: {
1799
+ flexDirection: "row",
1800
+ alignItems: "center",
1801
+ gap: 6,
1802
+ height: 36,
1803
+ borderWidth: StyleSheet2.hairlineWidth
1804
+ },
1805
+ searchInput: {
1806
+ flex: 1,
1807
+ minWidth: 0,
1808
+ padding: 0,
1809
+ fontSize: 15
1810
+ },
1811
+ chip: {
1812
+ flexDirection: "row",
1813
+ alignItems: "center",
1814
+ gap: 4,
1815
+ height: 28,
1816
+ paddingHorizontal: 8,
1817
+ borderWidth: StyleSheet2.hairlineWidth
1818
+ },
1819
+ optionRow: {
1820
+ flexDirection: "row",
1821
+ alignItems: "center",
1822
+ paddingVertical: 10
1823
+ },
1824
+ checkRow: {
1825
+ flexDirection: "row",
1826
+ alignItems: "center",
1827
+ gap: 8,
1828
+ paddingVertical: 8
1829
+ },
1830
+ checkBox: {
1831
+ width: 18,
1832
+ height: 18,
1833
+ alignItems: "center",
1834
+ justifyContent: "center",
1835
+ borderWidth: 1
1836
+ },
1837
+ panelHeader: {
1838
+ flexDirection: "row",
1839
+ alignItems: "center",
1840
+ justifyContent: "space-between",
1841
+ paddingVertical: 10,
1842
+ borderBottomWidth: StyleSheet2.hairlineWidth
1843
+ }
1844
+ });
1845
+
1846
+ // catalog/native/AgentFilterBar.tsx
1847
+ import { jsx as jsx7, jsxs as jsxs4 } from "react/jsx-runtime";
1848
+ function AgentFilterBar({
1849
+ consumer,
1850
+ allCategories,
1851
+ allTags,
1852
+ activeFilterCount,
1853
+ onFilterChipPress,
1854
+ onReset
1855
+ }) {
1856
+ const theme = useAgentCatalogNativeTheme();
1857
+ const { errorSink } = useAgentCatalog();
1858
+ return /* @__PURE__ */ jsxs4(
1859
+ ScrollView2,
1860
+ {
1861
+ horizontal: true,
1862
+ showsHorizontalScrollIndicator: false,
1863
+ contentContainerStyle: [
1864
+ styles3.bar,
1865
+ { paddingHorizontal: theme.spacing.sm }
1866
+ ],
1867
+ children: [
1868
+ /* @__PURE__ */ jsx7(
1869
+ FilterChip,
1870
+ {
1871
+ icon: "arrowUpDown",
1872
+ label: SORT_OPTIONS.find((o) => o.value === consumer.sortBy)?.label ?? "Sort",
1873
+ active: consumer.sortBy !== "updated-desc",
1874
+ onPress: () => onFilterChipPress("sort")
1875
+ }
1876
+ ),
1877
+ /* @__PURE__ */ jsx7(
1878
+ FilterChip,
1879
+ {
1880
+ icon: "star",
1881
+ label: consumer.favFilter === "no" ? "No Favs" : "Favs",
1882
+ active: consumer.favFilter !== "all",
1883
+ onPress: () => {
1884
+ const next = consumer.favFilter === "all" ? "yes" : consumer.favFilter === "yes" ? "no" : "all";
1885
+ consumer.setFavFilter(next);
1886
+ }
1887
+ }
1888
+ ),
1889
+ allCategories.length > 0 && /* @__PURE__ */ jsx7(
1890
+ FilterChip,
1891
+ {
1892
+ icon: "folder",
1893
+ label: consumer.includedCats.length > 0 ? `${consumer.includedCats.length}` : "Category",
1894
+ active: consumer.includedCats.length > 0,
1895
+ onPress: () => onFilterChipPress("categories")
1896
+ }
1897
+ ),
1898
+ allTags.length > 0 && /* @__PURE__ */ jsx7(
1899
+ FilterChip,
1900
+ {
1901
+ icon: "tag",
1902
+ label: consumer.includedTags.length > 0 ? `${consumer.includedTags.length}` : "Tags",
1903
+ active: consumer.includedTags.length > 0,
1904
+ onPress: () => onFilterChipPress("tags")
1905
+ }
1906
+ ),
1907
+ activeFilterCount > 0 && /* @__PURE__ */ jsx7(
1908
+ Pressable5,
1909
+ {
1910
+ onPress: onReset,
1911
+ accessibilityRole: "button",
1912
+ accessibilityLabel: "Reset filters",
1913
+ hitSlop: 8,
1914
+ style: ({ pressed }) => [
1915
+ styles3.reset,
1916
+ {
1917
+ borderRadius: theme.radius.sm,
1918
+ backgroundColor: pressed ? theme.colors.surfacePressed : "transparent"
1919
+ }
1920
+ ],
1921
+ children: /* @__PURE__ */ jsx7(
1922
+ AgentIcon,
1923
+ {
1924
+ name: "rotateCcw",
1925
+ size: 12,
1926
+ color: theme.colors.textMuted,
1927
+ report: errorSink
1928
+ }
1929
+ )
1930
+ }
1931
+ )
1932
+ ]
1933
+ }
1934
+ );
1935
+ }
1936
+ var styles3 = StyleSheet3.create({
1937
+ bar: { flexDirection: "row", alignItems: "center", gap: 4, paddingBottom: 6 },
1938
+ reset: {
1939
+ height: 28,
1940
+ paddingHorizontal: 8,
1941
+ alignItems: "center",
1942
+ justifyContent: "center"
1943
+ }
1944
+ });
1945
+
1946
+ // catalog/native/AgentListTabs.tsx
1947
+ import { Pressable as Pressable6, ScrollView as ScrollView3, StyleSheet as StyleSheet4, Text as Text5 } from "react-native";
1948
+ import { jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
1949
+ function AgentListTabs({
1950
+ consumer,
1951
+ tabCounts,
1952
+ visibleTabs,
1953
+ systemTabLabel
1954
+ }) {
1955
+ const { labels } = useAgentCatalog();
1956
+ const theme = useAgentCatalogNativeTheme();
1957
+ const tabs = [
1958
+ { value: "mine", label: "Mine", countKey: "mine" },
1959
+ { value: "shared", label: "Shared", countKey: "shared" },
1960
+ { value: "all", label: "All", countKey: "all" },
1961
+ { value: "system", label: labels.publicTab, countKey: "system" }
1962
+ ];
1963
+ return /* @__PURE__ */ jsx8(
1964
+ ScrollView3,
1965
+ {
1966
+ horizontal: true,
1967
+ showsHorizontalScrollIndicator: false,
1968
+ accessibilityRole: "tablist",
1969
+ accessibilityLabel: "Agent ownership",
1970
+ contentContainerStyle: [
1971
+ styles4.strip,
1972
+ { paddingHorizontal: theme.spacing.sm }
1973
+ ],
1974
+ children: tabs.filter(({ value }) => !visibleTabs || visibleTabs.includes(value)).map(({ value, label: baseLabel, countKey }) => {
1975
+ const label = value === "system" ? systemTabLabel ?? baseLabel : baseLabel;
1976
+ const active = consumer.tab === value;
1977
+ const count = tabCounts[countKey];
1978
+ return /* @__PURE__ */ jsxs5(
1979
+ Pressable6,
1980
+ {
1981
+ onPress: () => consumer.setTab(value),
1982
+ accessibilityRole: "tab",
1983
+ accessibilityState: { selected: active },
1984
+ accessibilityLabel: `${label}, ${count}`,
1985
+ style: ({ pressed }) => [
1986
+ styles4.tab,
1987
+ {
1988
+ borderRadius: theme.radius.md,
1989
+ backgroundColor: active ? theme.colors.primary : pressed ? theme.colors.surfacePressed : "transparent"
1990
+ }
1991
+ ],
1992
+ children: [
1993
+ /* @__PURE__ */ jsx8(
1994
+ Text5,
1995
+ {
1996
+ style: {
1997
+ color: active ? theme.colors.primaryForeground : theme.colors.textMuted,
1998
+ fontSize: theme.fontSize.sm,
1999
+ fontWeight: "500"
2000
+ },
2001
+ children: label
2002
+ }
2003
+ ),
2004
+ /* @__PURE__ */ jsx8(
2005
+ Text5,
2006
+ {
2007
+ style: {
2008
+ color: active ? theme.colors.primaryForeground : theme.colors.textMuted,
2009
+ fontSize: theme.fontSize.sm,
2010
+ opacity: 0.8,
2011
+ fontVariant: ["tabular-nums"]
2012
+ },
2013
+ children: count
2014
+ }
2015
+ )
2016
+ ]
2017
+ },
2018
+ value
2019
+ );
2020
+ })
2021
+ }
2022
+ );
2023
+ }
2024
+ var styles4 = StyleSheet4.create({
2025
+ strip: { flexDirection: "row", alignItems: "center", gap: 4, paddingBottom: 6 },
2026
+ tab: {
2027
+ flexDirection: "row",
2028
+ alignItems: "center",
2029
+ gap: 4,
2030
+ paddingHorizontal: 10,
2031
+ paddingVertical: 6
2032
+ }
2033
+ });
2034
+
2035
+ // catalog/native/AgentRow.tsx
2036
+ import { Pressable as Pressable7, StyleSheet as StyleSheet5, Text as Text6, View as View3 } from "react-native";
2037
+ import { jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
2038
+ function AgentRow({
2039
+ agent,
2040
+ isActive,
2041
+ onPress,
2042
+ onDetailPress
2043
+ }) {
2044
+ const { labels, errorSink } = useAgentCatalog();
2045
+ const theme = useAgentCatalogNativeTheme();
2046
+ return /* @__PURE__ */ jsxs6(
2047
+ View3,
2048
+ {
2049
+ testID: `agent-row-${agent.id}`,
2050
+ style: [
2051
+ styles5.row,
2052
+ isActive ? { backgroundColor: theme.colors.primarySoft } : null
2053
+ ],
2054
+ children: [
2055
+ /* @__PURE__ */ jsxs6(
2056
+ Pressable7,
2057
+ {
2058
+ onPress,
2059
+ accessibilityRole: "button",
2060
+ accessibilityState: { selected: isActive },
2061
+ accessibilityLabel: agent.name || "Untitled",
2062
+ style: ({ pressed }) => [
2063
+ styles5.main,
2064
+ {
2065
+ paddingHorizontal: theme.spacing.md,
2066
+ backgroundColor: pressed ? theme.colors.surfacePressed : "transparent"
2067
+ }
2068
+ ],
2069
+ children: [
2070
+ agent.isFavorite && /* @__PURE__ */ jsx9(
2071
+ AgentIcon,
2072
+ {
2073
+ name: "star",
2074
+ size: 12,
2075
+ filled: true,
2076
+ color: theme.colors.favorite,
2077
+ report: errorSink
2078
+ }
2079
+ ),
2080
+ /* @__PURE__ */ jsx9(
2081
+ Text6,
2082
+ {
2083
+ numberOfLines: 1,
2084
+ style: {
2085
+ flexShrink: 1,
2086
+ color: isActive ? theme.colors.primary : theme.colors.text,
2087
+ fontSize: theme.fontSize.md,
2088
+ fontWeight: "500"
2089
+ },
2090
+ children: agent.name || "Untitled"
2091
+ }
2092
+ ),
2093
+ agent.orchestra && /* @__PURE__ */ jsxs6(
2094
+ View3,
2095
+ {
2096
+ accessibilityLabel: orchestraDelegatesLine(agent.orchestra) ?? orchestraLabel(agent.orchestra),
2097
+ style: [
2098
+ styles5.badge,
2099
+ {
2100
+ backgroundColor: theme.colors.primarySoft,
2101
+ borderRadius: theme.radius.sm
2102
+ }
2103
+ ],
2104
+ children: [
2105
+ /* @__PURE__ */ jsx9(
2106
+ AgentIcon,
2107
+ {
2108
+ name: "music4",
2109
+ size: 10,
2110
+ color: theme.colors.primary,
2111
+ report: errorSink
2112
+ }
2113
+ ),
2114
+ /* @__PURE__ */ jsx9(
2115
+ Text6,
2116
+ {
2117
+ style: { color: theme.colors.primary, fontSize: theme.fontSize.xs },
2118
+ children: agent.orchestra.memberCount
2119
+ }
2120
+ )
2121
+ ]
2122
+ }
2123
+ ),
2124
+ /* @__PURE__ */ jsx9(View3, { style: styles5.spacer }),
2125
+ agent.agentType === "builtin" ? /* @__PURE__ */ jsx9(
2126
+ Text6,
2127
+ {
2128
+ style: [
2129
+ styles5.originBadge,
2130
+ {
2131
+ color: theme.colors.primary,
2132
+ backgroundColor: theme.colors.primarySoft,
2133
+ borderRadius: theme.radius.sm,
2134
+ fontSize: theme.fontSize.xs
2135
+ }
2136
+ ],
2137
+ children: labels.systemBadge
2138
+ }
2139
+ ) : agent.isOwner === false ? /* @__PURE__ */ jsx9(
2140
+ Text6,
2141
+ {
2142
+ style: [
2143
+ styles5.originBadge,
2144
+ {
2145
+ color: theme.colors.textMuted,
2146
+ backgroundColor: theme.colors.surface,
2147
+ borderRadius: theme.radius.sm,
2148
+ fontSize: theme.fontSize.xs
2149
+ }
2150
+ ],
2151
+ children: "shared"
2152
+ }
2153
+ ) : null
2154
+ ]
2155
+ }
2156
+ ),
2157
+ /* @__PURE__ */ jsx9(
2158
+ Pressable7,
2159
+ {
2160
+ onPress: onDetailPress,
2161
+ accessibilityRole: "button",
2162
+ accessibilityLabel: `Show details for ${agent.name || "Untitled"}`,
2163
+ hitSlop: 6,
2164
+ style: ({ pressed }) => [
2165
+ styles5.detailButton,
2166
+ {
2167
+ backgroundColor: pressed ? theme.colors.surfacePressed : "transparent"
2168
+ }
2169
+ ],
2170
+ children: /* @__PURE__ */ jsx9(
2171
+ AgentIcon,
2172
+ {
2173
+ name: "chevronRight",
2174
+ size: 16,
2175
+ color: theme.colors.textFaint,
2176
+ report: errorSink
2177
+ }
2178
+ )
2179
+ }
2180
+ )
2181
+ ]
2182
+ }
2183
+ );
2184
+ }
2185
+ var styles5 = StyleSheet5.create({
2186
+ row: { flexDirection: "row", alignItems: "stretch" },
2187
+ main: {
2188
+ flex: 1,
2189
+ flexDirection: "row",
2190
+ alignItems: "center",
2191
+ gap: 6,
2192
+ paddingVertical: 10,
2193
+ minWidth: 0
2194
+ },
2195
+ spacer: { flex: 1 },
2196
+ badge: {
2197
+ flexDirection: "row",
2198
+ alignItems: "center",
2199
+ gap: 2,
2200
+ paddingHorizontal: 4,
2201
+ paddingVertical: 1
2202
+ },
2203
+ originBadge: {
2204
+ overflow: "hidden",
2205
+ paddingHorizontal: 4,
2206
+ paddingVertical: 1,
2207
+ fontWeight: "500"
2208
+ },
2209
+ detailButton: {
2210
+ width: 40,
2211
+ alignItems: "center",
2212
+ justifyContent: "center"
2213
+ }
2214
+ });
2215
+
2216
+ // catalog/native/AgentListContent.tsx
2217
+ import { jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
2218
+ function AgentListContent({
2219
+ agents,
2220
+ isLoading,
2221
+ consumer,
2222
+ activeAgentId,
2223
+ allCategories,
2224
+ allTags,
2225
+ onSelectAgent,
2226
+ onDetailPress,
2227
+ onFilterChipPress,
2228
+ onReset,
2229
+ activeFilterCount,
2230
+ tabCounts,
2231
+ visibleTabs,
2232
+ systemTabLabel,
2233
+ pinnedAgent = null,
2234
+ defaultRow = null,
2235
+ autoFocusSearch = false
2236
+ }) {
2237
+ const catalog = useAgentCatalog();
2238
+ const theme = useAgentCatalogNativeTheme();
2239
+ const { labels, errorSink } = catalog;
2240
+ const emptyLabel = agentListEmptyLabel(consumer.tab, labels);
2241
+ const defaultAgent = defaultRow?.row ?? null;
2242
+ const items = [];
2243
+ if (defaultAgent) {
2244
+ items.push({ key: "label-default", kind: "label", text: "Default" });
2245
+ items.push({
2246
+ key: `default-${defaultAgent.id}`,
2247
+ kind: "row",
2248
+ agent: defaultAgent,
2249
+ forceActive: defaultAgent.id === activeAgentId
2250
+ });
2251
+ items.push({ key: "divider-default", kind: "divider" });
2252
+ }
2253
+ if (pinnedAgent) {
2254
+ items.push({
2255
+ key: "label-pinned",
2256
+ kind: "label",
2257
+ text: labels.currentAgentHeading
2258
+ });
2259
+ items.push({
2260
+ key: `pinned-${pinnedAgent.id}`,
2261
+ kind: "row",
2262
+ agent: pinnedAgent,
2263
+ forceActive: true
2264
+ });
2265
+ items.push({ key: "divider-pinned", kind: "divider" });
2266
+ }
2267
+ for (const agent of agents) {
2268
+ items.push({
2269
+ key: agent.id,
2270
+ kind: "row",
2271
+ agent,
2272
+ forceActive: agent.id === activeAgentId
2273
+ });
2274
+ }
2275
+ const hairline = {
2276
+ height: StyleSheet6.hairlineWidth,
2277
+ backgroundColor: theme.colors.border
2278
+ };
2279
+ return /* @__PURE__ */ jsxs7(View4, { style: [styles6.container, { backgroundColor: theme.colors.background }], children: [
2280
+ /* @__PURE__ */ jsx10(View4, { style: { paddingHorizontal: theme.spacing.sm, paddingBottom: 6 }, children: /* @__PURE__ */ jsx10(
2281
+ SearchInput,
2282
+ {
2283
+ value: consumer.searchTerm,
2284
+ onChange: consumer.setSearchTerm,
2285
+ placeholder: labels.searchPlaceholder,
2286
+ autoFocus: autoFocusSearch
2287
+ }
2288
+ ) }),
2289
+ /* @__PURE__ */ jsx10(
2290
+ AgentListTabs,
2291
+ {
2292
+ consumer,
2293
+ tabCounts,
2294
+ visibleTabs,
2295
+ systemTabLabel
2296
+ }
2297
+ ),
2298
+ /* @__PURE__ */ jsx10(
2299
+ AgentFilterBar,
2300
+ {
2301
+ consumer,
2302
+ allCategories,
2303
+ allTags,
2304
+ activeFilterCount,
2305
+ onFilterChipPress,
2306
+ onReset
2307
+ }
2308
+ ),
2309
+ defaultRow?.drift && /* @__PURE__ */ jsxs7(
2310
+ View4,
2311
+ {
2312
+ accessibilityRole: "alert",
2313
+ style: [
2314
+ styles6.banner,
2315
+ {
2316
+ marginHorizontal: theme.spacing.sm,
2317
+ borderRadius: theme.radius.md,
2318
+ backgroundColor: theme.colors.driftBackground,
2319
+ borderColor: theme.colors.driftBorder
2320
+ }
2321
+ ],
2322
+ children: [
2323
+ /* @__PURE__ */ jsx10(
2324
+ AgentIcon,
2325
+ {
2326
+ name: "alertTriangle",
2327
+ size: 14,
2328
+ color: theme.colors.driftForeground,
2329
+ report: errorSink
2330
+ }
2331
+ ),
2332
+ /* @__PURE__ */ jsx10(
2333
+ Text7,
2334
+ {
2335
+ style: {
2336
+ flex: 1,
2337
+ color: theme.colors.driftForeground,
2338
+ fontSize: theme.fontSize.sm
2339
+ },
2340
+ children: defaultRow.drift
2341
+ }
2342
+ ),
2343
+ /* @__PURE__ */ jsx10(
2344
+ Pressable8,
2345
+ {
2346
+ onPress: () => catalog.dismissDefaultRowDrift(defaultRow.mandateKey),
2347
+ accessibilityRole: "button",
2348
+ accessibilityLabel: "Dismiss",
2349
+ hitSlop: 8,
2350
+ children: /* @__PURE__ */ jsx10(
2351
+ AgentIcon,
2352
+ {
2353
+ name: "x",
2354
+ size: 12,
2355
+ color: theme.colors.driftForeground,
2356
+ report: errorSink
2357
+ }
2358
+ )
2359
+ }
2360
+ )
2361
+ ]
2362
+ }
2363
+ ),
2364
+ defaultRow?.error && /* @__PURE__ */ jsxs7(
2365
+ View4,
2366
+ {
2367
+ accessibilityRole: "alert",
2368
+ style: [
2369
+ styles6.banner,
2370
+ {
2371
+ marginHorizontal: theme.spacing.sm,
2372
+ borderRadius: theme.radius.md,
2373
+ backgroundColor: theme.colors.driftBackground,
2374
+ borderColor: theme.colors.driftBorder
2375
+ }
2376
+ ],
2377
+ children: [
2378
+ /* @__PURE__ */ jsx10(
2379
+ AgentIcon,
2380
+ {
2381
+ name: "alertTriangle",
2382
+ size: 14,
2383
+ color: theme.colors.driftForeground,
2384
+ report: errorSink
2385
+ }
2386
+ ),
2387
+ /* @__PURE__ */ jsx10(
2388
+ Text7,
2389
+ {
2390
+ style: {
2391
+ flex: 1,
2392
+ color: theme.colors.driftForeground,
2393
+ fontSize: theme.fontSize.sm
2394
+ },
2395
+ children: defaultRow.error
2396
+ }
2397
+ )
2398
+ ]
2399
+ }
2400
+ ),
2401
+ /* @__PURE__ */ jsx10(View4, { style: hairline }),
2402
+ isLoading ? /* @__PURE__ */ jsxs7(View4, { style: styles6.centered, children: [
2403
+ /* @__PURE__ */ jsx10(
2404
+ AgentIcon,
2405
+ {
2406
+ name: "loader",
2407
+ size: 16,
2408
+ color: theme.colors.textMuted,
2409
+ report: errorSink
2410
+ }
2411
+ ),
2412
+ /* @__PURE__ */ jsx10(Text7, { style: { color: theme.colors.textMuted, fontSize: theme.fontSize.md }, children: labels.loading })
2413
+ ] }) : 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(
2414
+ FlatList,
2415
+ {
2416
+ style: styles6.list,
2417
+ data: items,
2418
+ keyExtractor: (item) => item.key,
2419
+ keyboardShouldPersistTaps: "handled",
2420
+ renderItem: ({ item }) => {
2421
+ if (item.kind === "divider") return /* @__PURE__ */ jsx10(View4, { style: hairline });
2422
+ if (item.kind === "label") {
2423
+ return /* @__PURE__ */ jsx10(
2424
+ Text7,
2425
+ {
2426
+ style: {
2427
+ color: theme.colors.textMuted,
2428
+ fontSize: theme.fontSize.xs,
2429
+ fontWeight: "600",
2430
+ textTransform: "uppercase",
2431
+ paddingHorizontal: theme.spacing.md,
2432
+ paddingTop: 8,
2433
+ paddingBottom: 2
2434
+ },
2435
+ children: item.text
2436
+ }
2437
+ );
2438
+ }
2439
+ return /* @__PURE__ */ jsx10(
2440
+ AgentRow,
2441
+ {
2442
+ agent: item.agent,
2443
+ isActive: item.forceActive,
2444
+ onPress: () => onSelectAgent(item.agent),
2445
+ onDetailPress: () => onDetailPress(item.agent)
2446
+ }
2447
+ );
2448
+ },
2449
+ ListFooterComponent: agents.length === 0 && (pinnedAgent || defaultAgent) ? /* @__PURE__ */ jsx10(View4, { style: styles6.centered, children: /* @__PURE__ */ jsx10(
2450
+ Text7,
2451
+ {
2452
+ style: {
2453
+ color: theme.colors.textMuted,
2454
+ fontSize: theme.fontSize.md
2455
+ },
2456
+ children: emptyLabel
2457
+ }
2458
+ ) }) : null
2459
+ }
2460
+ ),
2461
+ /* @__PURE__ */ jsx10(View4, { style: hairline }),
2462
+ /* @__PURE__ */ jsxs7(View4, { style: [styles6.footer, { paddingHorizontal: theme.spacing.md }], children: [
2463
+ /* @__PURE__ */ jsxs7(
2464
+ Text7,
2465
+ {
2466
+ style: {
2467
+ color: theme.colors.textMuted,
2468
+ fontSize: theme.fontSize.xs,
2469
+ fontVariant: ["tabular-nums"]
2470
+ },
2471
+ children: [
2472
+ agents.length,
2473
+ " agent",
2474
+ agents.length !== 1 ? "s" : ""
2475
+ ]
2476
+ }
2477
+ ),
2478
+ consumer.searchTerm.length > 0 && /* @__PURE__ */ jsx10(
2479
+ Pressable8,
2480
+ {
2481
+ onPress: () => consumer.setSearchTerm(""),
2482
+ accessibilityRole: "button",
2483
+ accessibilityLabel: "Clear search",
2484
+ hitSlop: 8,
2485
+ children: /* @__PURE__ */ jsx10(
2486
+ Text7,
2487
+ {
2488
+ style: { color: theme.colors.textMuted, fontSize: theme.fontSize.xs },
2489
+ children: "Clear search"
2490
+ }
2491
+ )
2492
+ }
2493
+ )
2494
+ ] })
2495
+ ] });
2496
+ }
2497
+ var styles6 = StyleSheet6.create({
2498
+ container: { flex: 1, minHeight: 0 },
2499
+ list: { flex: 1, minHeight: 0 },
2500
+ banner: {
2501
+ flexDirection: "row",
2502
+ alignItems: "flex-start",
2503
+ gap: 8,
2504
+ marginBottom: 6,
2505
+ paddingHorizontal: 8,
2506
+ paddingVertical: 6,
2507
+ borderWidth: StyleSheet6.hairlineWidth
2508
+ },
2509
+ centered: {
2510
+ alignItems: "center",
2511
+ justifyContent: "center",
2512
+ gap: 8,
2513
+ paddingVertical: 32
2514
+ },
2515
+ footer: {
2516
+ flexDirection: "row",
2517
+ alignItems: "center",
2518
+ justifyContent: "space-between",
2519
+ paddingVertical: 8
2520
+ }
2521
+ });
2522
+
2523
+ // catalog/native/AgentSubView.tsx
2524
+ import { Pressable as Pressable9, ScrollView as ScrollView4, StyleSheet as StyleSheet7, Text as Text8, View as View5 } from "react-native";
2525
+ import { Fragment, jsx as jsx11, jsxs as jsxs8 } from "react/jsx-runtime";
2526
+ function AgentSubView({
2527
+ view,
2528
+ consumer,
2529
+ allCategories,
2530
+ allTags,
2531
+ search,
2532
+ setSearch,
2533
+ onBack
2534
+ }) {
2535
+ const theme = useAgentCatalogNativeTheme();
2536
+ const title = view === "sort" ? "Sort" : view === "categories" ? "Categories" : "Tags";
2537
+ const values = view === "categories" ? allCategories : allTags;
2538
+ const included = view === "categories" ? consumer.includedCats : consumer.includedTags;
2539
+ const filtered = values.filter(
2540
+ (value) => !search || value.toLowerCase().includes(search.toLowerCase())
2541
+ );
2542
+ return /* @__PURE__ */ jsxs8(View5, { style: styles7.container, children: [
2543
+ /* @__PURE__ */ jsx11(SidePanelHeader, { title, onClose: onBack }),
2544
+ view === "sort" ? /* @__PURE__ */ jsx11(ScrollView4, { style: styles7.list, children: SORT_OPTIONS.map((option) => /* @__PURE__ */ jsx11(
2545
+ OptionRow,
2546
+ {
2547
+ label: option.label,
2548
+ selected: consumer.sortBy === option.value,
2549
+ onPress: () => {
2550
+ consumer.setSortBy(option.value);
2551
+ onBack();
2552
+ }
2553
+ },
2554
+ option.value
2555
+ )) }) : /* @__PURE__ */ jsxs8(Fragment, { children: [
2556
+ /* @__PURE__ */ jsx11(View5, { style: { paddingHorizontal: theme.spacing.sm, paddingVertical: 6 }, children: /* @__PURE__ */ jsx11(
2557
+ SearchInput,
2558
+ {
2559
+ value: search,
2560
+ onChange: setSearch,
2561
+ placeholder: view === "categories" ? "Filter categories..." : "Filter tags..."
2562
+ }
2563
+ ) }),
2564
+ included.length > 0 && /* @__PURE__ */ jsx11(
2565
+ Pressable9,
2566
+ {
2567
+ onPress: () => view === "categories" ? consumer.setIncludedCats([]) : consumer.setIncludedTags([]),
2568
+ accessibilityRole: "button",
2569
+ accessibilityLabel: `Clear ${included.length} filters`,
2570
+ style: {
2571
+ marginHorizontal: theme.spacing.sm,
2572
+ marginBottom: 4,
2573
+ paddingVertical: 6
2574
+ },
2575
+ children: /* @__PURE__ */ jsxs8(
2576
+ Text8,
2577
+ {
2578
+ style: {
2579
+ color: theme.colors.primary,
2580
+ fontSize: theme.fontSize.sm,
2581
+ fontWeight: "600"
2582
+ },
2583
+ children: [
2584
+ "Clear (",
2585
+ included.length,
2586
+ ")"
2587
+ ]
2588
+ }
2589
+ )
2590
+ }
2591
+ ),
2592
+ /* @__PURE__ */ jsx11(ScrollView4, { style: styles7.list, children: filtered.length === 0 ? /* @__PURE__ */ jsx11(
2593
+ Text8,
2594
+ {
2595
+ style: {
2596
+ color: theme.colors.textMuted,
2597
+ fontSize: theme.fontSize.md,
2598
+ textAlign: "center",
2599
+ paddingVertical: 24
2600
+ },
2601
+ children: view === "categories" ? "No categories" : "No tags"
2602
+ }
2603
+ ) : filtered.map((value) => /* @__PURE__ */ jsx11(
2604
+ CheckRow,
2605
+ {
2606
+ label: value,
2607
+ checked: included.includes(value),
2608
+ onPress: () => view === "categories" ? consumer.toggleCategory(value) : consumer.toggleTag(value)
2609
+ },
2610
+ value
2611
+ )) })
2612
+ ] })
2613
+ ] });
2614
+ }
2615
+ var styles7 = StyleSheet7.create({
2616
+ container: { flex: 1, minHeight: 0 },
2617
+ list: { flex: 1, minHeight: 0 }
2618
+ });
2619
+
2620
+ // catalog/native/AgentPickerBody.tsx
2621
+ import { jsx as jsx12 } from "react/jsx-runtime";
2622
+ function AgentPickerBody({
2623
+ consumerId,
2624
+ onSelect,
2625
+ activeAgentId = null,
2626
+ autoFocusSearch = false,
2627
+ initialTab,
2628
+ includeSystemInAll = false,
2629
+ visibleTabs,
2630
+ systemTabLabel,
2631
+ showPinnedAgent = true,
2632
+ excludeAgentIds,
2633
+ defaultMandateKey,
2634
+ compact = false,
2635
+ onAfterSelect
2636
+ }) {
2637
+ const [detailAgent, setDetailAgent] = useState3(null);
2638
+ const [subView, setSubView] = useState3(null);
2639
+ const [panelSearch, setPanelSearch] = useState3("");
2640
+ const {
2641
+ agents,
2642
+ isLoading,
2643
+ allCategories,
2644
+ allTags,
2645
+ consumer,
2646
+ tabCounts,
2647
+ activeFilterCount,
2648
+ pinnedAgent,
2649
+ defaultRow,
2650
+ ensureLoaded,
2651
+ handleSelectAgent: coreSelectAgent
2652
+ } = useAgentListCore({
2653
+ consumerId,
2654
+ onSelect,
2655
+ activeAgentIdOverride: activeAgentId,
2656
+ ...initialTab ? { initialTab } : {},
2657
+ includeSystemInAll,
2658
+ // The restriction has to reach the CORE, not just the tab strip.
2659
+ ...visibleTabs ? { visibleTabs } : {},
2660
+ ...excludeAgentIds ? { excludeAgentIds } : {},
2661
+ ...defaultMandateKey ? { defaultMandateKey } : {}
2662
+ });
2663
+ useEffect3(() => {
2664
+ ensureLoaded();
2665
+ }, [ensureLoaded]);
2666
+ const selectAgent = (agent) => {
2667
+ coreSelectAgent(agent);
2668
+ setDetailAgent(null);
2669
+ setSubView(null);
2670
+ onAfterSelect?.();
2671
+ };
2672
+ if (detailAgent) {
2673
+ return /* @__PURE__ */ jsx12(View6, { style: styles8.fill, children: /* @__PURE__ */ jsx12(
2674
+ AgentDetailCard,
2675
+ {
2676
+ agent: detailAgent,
2677
+ onSelect: () => selectAgent(detailAgent)
2678
+ }
2679
+ ) });
2680
+ }
2681
+ if (subView) {
2682
+ return /* @__PURE__ */ jsx12(View6, { style: styles8.fill, children: /* @__PURE__ */ jsx12(
2683
+ AgentSubView,
2684
+ {
2685
+ view: subView,
2686
+ consumer,
2687
+ allCategories,
2688
+ allTags,
2689
+ search: panelSearch,
2690
+ setSearch: setPanelSearch,
2691
+ onBack: () => {
2692
+ setSubView(null);
2693
+ setPanelSearch("");
2694
+ }
2695
+ }
2696
+ ) });
2697
+ }
2698
+ return /* @__PURE__ */ jsx12(View6, { style: [styles8.fill, compact ? styles8.compact : null], children: /* @__PURE__ */ jsx12(
2699
+ AgentListContent,
2700
+ {
2701
+ agents,
2702
+ isLoading,
2703
+ consumer,
2704
+ activeAgentId,
2705
+ allCategories,
2706
+ allTags,
2707
+ onSelectAgent: selectAgent,
2708
+ onDetailPress: setDetailAgent,
2709
+ onFilterChipPress: setSubView,
2710
+ onReset: consumer.resetFilters,
2711
+ activeFilterCount,
2712
+ tabCounts,
2713
+ ...visibleTabs ? { visibleTabs } : {},
2714
+ ...systemTabLabel ?? (includeSystemInAll ? "System" : void 0) ? {
2715
+ systemTabLabel: systemTabLabel ?? (includeSystemInAll ? "System" : void 0)
2716
+ } : {},
2717
+ pinnedAgent: showPinnedAgent ? pinnedAgent : null,
2718
+ defaultRow,
2719
+ autoFocusSearch
2720
+ }
2721
+ ) });
2722
+ }
2723
+ var styles8 = StyleSheet8.create({
2724
+ fill: { flex: 1, minHeight: 0 },
2725
+ compact: { paddingTop: 0 }
2726
+ });
2727
+
2728
+ // catalog/native/AgentListSheet.tsx
2729
+ import { jsx as jsx13, jsxs as jsxs9 } from "react/jsx-runtime";
2730
+ function AgentListSheet({ title, ...props }) {
2731
+ const theme = useAgentCatalogNativeTheme();
2732
+ return /* @__PURE__ */ jsxs9(View7, { style: [styles9.sheet, { backgroundColor: theme.colors.background }], children: [
2733
+ title ? /* @__PURE__ */ jsx13(
2734
+ Text9,
2735
+ {
2736
+ accessibilityRole: "header",
2737
+ style: {
2738
+ color: theme.colors.text,
2739
+ fontSize: theme.fontSize.lg + 3,
2740
+ fontWeight: "700",
2741
+ paddingHorizontal: theme.spacing.md,
2742
+ paddingTop: theme.spacing.sm,
2743
+ paddingBottom: theme.spacing.sm
2744
+ },
2745
+ children: title
2746
+ }
2747
+ ) : null,
2748
+ /* @__PURE__ */ jsx13(AgentPickerBody, { ...props })
2749
+ ] });
2750
+ }
2751
+ var styles9 = StyleSheet9.create({
2752
+ sheet: { flex: 1, minHeight: 0 }
2753
+ });
2754
+
2755
+ // catalog/native/AgentListInlinePicker.tsx
2756
+ import { StyleSheet as StyleSheet10, View as View8 } from "react-native";
2757
+ import { jsx as jsx14 } from "react/jsx-runtime";
2758
+ function AgentListInlinePicker(props) {
2759
+ return /* @__PURE__ */ jsx14(View8, { style: styles10.fill, children: /* @__PURE__ */ jsx14(AgentPickerBody, { ...props }) });
2760
+ }
2761
+ var styles10 = StyleSheet10.create({
2762
+ fill: { flex: 1, minHeight: 0 }
2763
+ });
2764
+ export {
2765
+ AgentCatalogProvider,
2766
+ AgentDetailCard,
2767
+ AgentFilterBar,
2768
+ AgentIcon,
2769
+ AgentListContent,
2770
+ AgentListInlinePicker,
2771
+ AgentListSheet,
2772
+ AgentListTabs,
2773
+ AgentPickerBody,
2774
+ AgentRow,
2775
+ AgentSubView,
2776
+ CheckRow,
2777
+ DEFAULT_AGENT_CATALOG_NATIVE_THEME,
2778
+ FavoriteAgentButton,
2779
+ FilterChip,
2780
+ HOVER_GRACE_MS,
2781
+ LIGHT_AGENT_CATALOG_NATIVE_THEME,
2782
+ OptionRow,
2783
+ SearchInput,
2784
+ SidePanelHeader,
2785
+ _resetNativeIconState,
2786
+ announceMissingSvgOnce,
2787
+ coerceVisibleTab,
2788
+ orchestraDelegatesLine,
2789
+ orchestraDepthLine,
2790
+ orchestraLabel,
2791
+ orchestraModeLabel,
2792
+ resolveAgentCatalogNativeTheme,
2793
+ resolveSvgModule,
2794
+ useAgentCatalog,
2795
+ useAgentCatalogNativeTheme,
2796
+ useAgentCatalogRows,
2797
+ useAgentCatalogState,
2798
+ useAgentCatalogUiPorts,
2799
+ useAgentConsumer,
2800
+ useAgentListCore
2801
+ };
2802
+ //# sourceMappingURL=index.js.map