fix(shared): support file-based agents and recursive commands

This commit is contained in:
Tam Nhu Tran committed 2026-02-26 14:57:57 +07:00
1 parent 77a236490d
commit 346fa5fcda
3 files changed
+351 -61

No files matched your search

+33 -5
View File
@@ -1,16 +1,31 @@
import { useState } from 'react';
import { useMemo, useState } from 'react';
import { Card, CardContent } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert';
import { useSharedItems, useSharedSummary } from '@/hooks/use-shared';
import { FileText, Sparkles, Bot, AlertTriangle } from 'lucide-react';
import { FileText, Sparkles, Bot, AlertTriangle, Search } from 'lucide-react';
type TabType = 'commands' | 'skills' | 'agents';
export function SharedPage() {
const [tab, setTab] = useState<TabType>('commands');
const [query, setQuery] = useState('');
const { data: summary } = useSharedSummary();
const { data: items, isLoading } = useSharedItems(tab);
const normalizedQuery = query.trim().toLowerCase();
const filteredItems = useMemo(() => {
const allItems = items?.items ?? [];
if (!normalizedQuery) {
return allItems;
}
return allItems.filter((item) =>
[item.name, item.description, item.path].some((value) =>
value.toLowerCase().includes(normalizedQuery)
)
);
}, [items, normalizedQuery]);
const tabs: { id: TabType; label: string; icon: typeof FileText; count: number }[] = [
{ id: 'commands', label: 'Commands', icon: FileText, count: summary?.commands ?? 0 },
@@ -44,7 +59,10 @@ export function SharedPage() {
key={t.id}
variant={tab === t.id ? 'default' : 'ghost'}
size="sm"
onClick={() => setTab(t.id)}
onClick={() => {
setTab(t.id);
setQuery('');
}}
className="flex items-center gap-2"
>
<t.icon className="w-4 h-4" />
@@ -53,15 +71,25 @@ export function SharedPage() {
))}
</div>
<div className="relative max-w-md">
<Search className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
<Input
value={query}
onChange={(event) => setQuery(event.target.value)}
placeholder={`Filter ${tab} by name, description, or path`}
className="pl-9"
/>
</div>
{/* Content */}
<div className="mt-4">
{isLoading ? (
<div className="text-muted-foreground">Loading...</div>
) : items?.items.length === 0 ? (
) : filteredItems.length === 0 ? (
<div className="text-muted-foreground">No {tab} found</div>
) : (
<div className="grid gap-3">
{items?.items.map((item) => (
{filteredItems.map((item) => (
<Card key={item.name}>
<CardContent>
<div className="font-medium">{item.name}</div>