agent-health
Reads production/traces/agent-metrics.jsonl and displays a per-agent performance summary table for the current or a specified…
Framework-agnostic React/Vue patterns — component composition, hooks, TanStack Query, memoization, error boundaries. Use for generic React/Vue work (Vite, CRA, Storybook). For Next.js App Router / Server Components specifically, use `senior-frontend` instead.
Claude Code
$ npx -y skills add tranhieutt/software_development_department --skill frontend-patterns --agent claude-code
Codex
$ npx skills add tranhieutt/software_development_department --skill frontend-patterns -a codex -y
Cursor
$ npx skills add tranhieutt/software_development_department --skill frontend-patterns -a cursor -y
Gemini CLI
$ npx skills add tranhieutt/software_development_department --skill frontend-patterns -a gemini-cli -y
GitHub Copilot
$ npx skills add tranhieutt/software_development_department --skill frontend-patterns -a github-copilot -y
OpenCode
$ npx skills add tranhieutt/software_development_department --skill frontend-patterns -a opencode -y
Windsurf
$ npx skills add tranhieutt/software_development_department --skill frontend-patterns -a windsurf -y
name: frontend-patterns type: reference description: "Framework-agnostic React/Vue patterns — component composition, hooks, TanStack Query, memoization, error boundaries. Use for generic React/Vue work (Vite, CRA, Storybook). For Next.js App Router / Server Components specifically, use `senior-frontend` instead." paths: ["**/*.tsx", "**/*.jsx", "**/*.vue", "**/components/**"] effort: 3 allowed-tools: Read, Glob, Grep, Write, Edit, Bash user-invocable: true when_to_use: "When building React/Vue components, hooks, state management, or client-side performance — NOT for Next.js App Router (see `senior-frontend`)"
// Compound component with Context
const TabsContext = createContext<{ active: string; setActive: (v: string) => void } | null>(null);
function Tabs({ children, defaultValue }: { children: React.ReactNode; defaultValue: string }) {
const [active, setActive] = useState(defaultValue);
return <TabsContext.Provider value={{ active, setActive }}>{children}</TabsContext.Provider>;
}
Tabs.Trigger = function TabsTrigger({ value, children }: { value: string; children: React.ReactNode }) {
const ctx = useContext(TabsContext)!;
return <button onClick={() => ctx.setActive(value)} aria-selected={ctx.active === value}>{children}</button>;
};
Tabs.Content = function TabsContent({ value, children }: { value: string; children: React.ReactNode }) {
const { active } = useContext(TabsContext)!;
return active === value ? <>{children}</> : null;
};| Scope | Solution | |---|---| | Single component | `useState`, `useReducer` | | Subtree | Context + `useContext` | | Client global (UI) | Zustand / Jotai | | Server state (API) | TanStack Query | | Form state | React Hook Form | | URL state | `useSearchParams` (Next.js) |
// Fetch
const { data, isLoading, error } = useQuery({
queryKey: ["products", filters], // filters in key → auto-refetch on change
queryFn: () => api.getProducts(filters),
staleTime: 5 * 60 * 1000, // don't refetch for 5 min
});
// Mutate with optimistic update
const mutation = useMutation({
mutationFn: api.updateProduct,
onMutate: async (newProduct) => {
await queryClient.cancelQueries({ queryKey: ["products"] });
const prev = queryClient.getQueryData(["products"]);
queryClient.setQueryData(["products"], (old) => old.map(p => p.id === newProduct.id ? newProduct : p));
return { prev };
},
onError: (_, __, ctx) => queryClient.setQueryData(["products"], ctx?.prev),
onSettled: () => queryClient.invalidateQueries({ queryKey: ["products"] }),
});// Memoize expensive component
const ExpensiveList = memo(({ items }: { items: Item[] }) => (
<ul>{items.map(item => <li key={item.id}>{item.name}</li>)}</ul>
));
// Stable callback reference
const handleClick = useCallback((id: string) => {
onSelect(id);
}, [onSelect]); // only recreate if onSelect changes
// Expensive calculation
const sorted = useMemo(() =>
items.sort((a, b) => b.score - a.score),
[items]);const HeavyChart = lazy(() => import("./HeavyChart"));
function Dashboard() {
return (
<Suspense fallback={<Skeleton />}>
<HeavyChart data={data} />
</Suspense>
);
}function useDebounce<T>(value: T, delay: number): T {
const [debounced, setDebounced] = useState(value);
useEffect(() => {
const timer = setTimeout(() => setDebounced(value), delay);
return () => clearTimeout(timer);
}, [value, delay]);
return debounced;
}
function useLocalStorage<T>(key: string, initial: T) {
const [value, setValue] = useState<T>(() => {
try { return JSON.parse(localStorage.getItem(key) ?? "") ?? initial; }
catch { return initial; }
});
const set = useCallback((v: T) => {
setValue(v); localStorage.setItem(key, JSON.stringify(v));
}, [key]);
return [value, set] as const;
}class ErrorBoundary extends React.Component<{ fallback: React.ReactNode; children: React.ReactNode }> {
state = { hasError: false };
static getDerivedStateFromError() { return { hasError: true }; }
componentDidCatch(error: Error) { console.error(error); }
render() { return this.state.hasError ? this.props.fallback : this.props.children; }
}
// Usage: wrap async/complex sections, not entire app| Pitfall | Fix | |---|---| | Fetching in `useEffect` without cleanup | Use TanStack Query or abort controller | | Context causes full tree re-render | Split context by domain; memoize value object | | `useEffect` runs twice (StrictMode) | Design effects to be idempotent; use cleanup fn | | Prop drilling > 3 levels | Lift to Context or state manager | | Missing `loading` / `error` states | Always handle all 3 states: loading, error, data |
Reads production/traces/agent-metrics.jsonl and displays a per-agent performance summary table for the current or a specified…
Provides the vendored agent-style v0.3.5 prose rule pack as a portable Claude skill. Use when installing, syncing, applying, or…
Provides Angular best practices for components, modules, services, and reactive patterns. Use when working with Angular…
Records unexpected API behaviors, undocumented caveats, version bugs, or non-obvious workarounds into…
Defines REST and GraphQL API contracts including endpoints, request/response schemas, auth flows, and versioning strategy. Use…
Manages the ADR (Architecture Decision Record) registry. Use when recording tech-stack choices, design patterns, or…
You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…
Ask which skill or flow fits your situation. A router over the skills in this repo.