install
source · Clone the upstream repo
git clone https://github.com/dlupiak/claude-session-dashboard
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/dlupiak/claude-session-dashboard "$T" && mkdir -p ~/.claude/skills && cp -r "$T/.claude/skills/react-rules" ~/.claude/skills/dlupiak-claude-session-dashboard-react-rules && rm -rf "$T"
manifest:
.claude/skills/react-rules/SKILL.mdsource content
React Rules
Components
- Use named exports, not default exports:
export function AgentCard() {} - One component per file for route-level components
- Co-locate small helper components in the same file
- Use
with Tailwind — no CSS modules or styled-componentsclassName
Data Fetching
- Use TanStack Query (
,useQuery
) for all data fetchinguseSuspenseQuery - Server Functions for mutations via
useMutation - Never use
for data fetchinguseEffect - Prefetch on the server with
in route loadersqueryClient.prefetchQuery
State
- URL state first (search params via TanStack Router)
- Server state via TanStack Query (no Redux, no Zustand)
- Local UI state only with
— keep it minimaluseState - Form state with controlled components or
useForm
Patterns
- Suspense boundaries at route level, not per-component
- Error boundaries for slice-level error handling
- Compose with props, not render props or HOCs
- Use shadcn/ui components — don't build custom UI primitives
File Naming
- Route files:
(TanStack Router file-based routing)route.tsx - UI components:
or grouped inPascalCase.tsx
within a sliceui.tsx - Hooks:
(must start withuse-kebab-case.ts
prefix — enforced by architecture tests)use
Slice Boundaries (enforced by automated tests)
- Never import a component from another feature's
directory directlyui/ - Shared UI primitives go in
(shadcn convention)src/components/ui/ - Cross-slice data: import hooks/types from the other slice's
facade, not from internal filesmodel.ts - Route files must be thin — compose from slice hooks and components, don't import from
ordomain/
directlyinfra/ - Example:
(correct) vsimport { useAgents } from '@/features/registry/model'
(wrong from outside registry)import { useAgents } from '@/features/registry/hooks/useAgents'