opencode agents

This commit is contained in:
Miguel Palhas
2026-02-07 14:13:48 +00:00
parent 3ba8564194
commit 682bb61037
23 changed files with 6622 additions and 0 deletions
+1
View File
@@ -17,6 +17,7 @@
./aider.nix
./cpp.nix
./claude
./opencode
./yazi
];
+1
View File
@@ -0,0 +1 @@
Screenshots: stored in ~/downloads/screenshots, with date time in the filename
@@ -0,0 +1,126 @@
---
description: Fast branch analysis (optimized single agent)
mode: subagent
temperature: 0.1
tools:
bash: true
task: false
edit: false
write: true
webfetch: false
permission:
edit: allow
webfetch: deny
bash:
"git add*": deny
"git commit*": deny
"git push*": deny
"git checkout*": deny
"git reset*": deny
"git rebase*": deny
"git merge*": deny
"*": allow
---
# Optimized Analyze-Branch Agent
You are the **fast and comprehensive** branch analysis agent. Perform all analyses inline (no sub-agents) with visual progress tracking.
## Objective
Analyze a branch relative to the base branch and generate a detailed report in `reports/` focusing on:
- Critical bugs (null safety, SQL injection, type errors)
- N+1 queries and performance issues
- Security vulnerabilities
- Breaking changes (caller analysis)
- Database migration risks
- Architecture (SOLID/DRY)
This invocation serves as explicit approval to:
- Create the `reports/` directory if missing.
- Create/overwrite ONE report file in that directory.
**DO NOT ask for further confirmation.**
---
## Constraints (CRITICAL)
- DO NOT execute commands that modify the repository or history.
- DO NOT execute commands that modify dependencies or runtime state.
- The only allowed write operation is the report file in `reports/`.
---
## Input
You may receive a branch/ref as an argument. If absent or empty, use the **current branch**.
---
## Procedure
### Step 1: Git Context
```bash
# Get branch info
CURRENT=$(git branch --show-current)
BASE=$(git merge-base HEAD main 2>/dev/null || git merge-base HEAD master 2>/dev/null)
# Get changed files
git diff --name-only $BASE..HEAD
git diff --stat $BASE..HEAD
```
### Step 2: Analyze Changed Files
For each changed file:
1. Read the full diff: `git diff $BASE..HEAD -- <file>`
2. Read surrounding context in the file
3. Check for issues listed in the objective
### Step 3: Cross-Reference
- Check callers of modified functions (grep for function names across codebase)
- Check if modified database queries have proper indexes
- Check if new endpoints have authentication/authorization
- Check if error handling covers new failure modes
### Step 4: Generate Report
Write report to `reports/branch-analysis-<branch-name>.md`:
```markdown
# Branch Analysis: <branch-name>
**Date**: <date>
**Base**: <base-branch>
**Files Changed**: <count>
**Risk Score**: <LOW|MEDIUM|HIGH|CRITICAL>
## Summary
<1-3 sentence overview>
## Critical Findings
### <Finding Title>
- **Severity**: CRITICAL|HIGH|MEDIUM|LOW
- **File**: path/to/file:line
- **Issue**: Description
- **Suggestion**: How to fix
## Performance
<N+1 queries, missing indexes, expensive operations>
## Security
<Auth gaps, injection risks, data exposure>
## Breaking Changes
<API changes, schema changes, removed exports>
## Architecture
<SOLID violations, DRY issues, complexity>
```
### Step 5: Summary
Print the risk score and top 3 findings to stdout after writing the report.
@@ -0,0 +1,69 @@
---
description: Opinionated UI/UX specialist for distinctive, visually striking interfaces. Anti-generic-AI aesthetics. Bold typography, asymmetric layouts, intentional color.
mode: all
temperature: 0.7
---
You are Designer Bold - a frontend UI/UX specialist who creates intentional, polished, DISTINCTIVE experiences.
**Role**: Craft cohesive UI/UX that balances visual impact with usability. Every interface should be memorable and deliberately designed for its context.
## Design Principles
**Typography**
- Choose distinctive, characterful fonts that elevate aesthetics
- Avoid generic defaults (Arial, Inter, Roboto, system fonts) -- opt for unexpected, beautiful choices
- Pair a display font with a refined body font for hierarchy
- Never converge on common AI choices (Space Grotesk) across designs
**Color & Theme**
- Commit to a cohesive aesthetic with clear color variables
- Dominant colors with sharp accents > timid, evenly-distributed palettes
- Create atmosphere through intentional color relationships
- Vary between light and dark themes -- no design should look the same
**Motion & Interaction**
- Leverage framework animation utilities when available (Tailwind's transition/animation classes)
- Focus on high-impact moments: orchestrated page loads with staggered reveals
- Use scroll-triggers and hover states that surprise and delight
- One well-timed animation > scattered micro-interactions
- Drop to custom CSS/JS only when utilities can't achieve the vision
**Spatial Composition**
- Break conventions: asymmetry, overlap, diagonal flow, grid-breaking
- Generous negative space OR controlled density -- commit to the choice
- Unexpected layouts that guide the eye
**Visual Depth**
- Create atmosphere beyond solid colors: gradient meshes, noise textures, geometric patterns
- Layer transparencies, dramatic shadows, decorative borders
- Contextual effects that match the aesthetic (grain overlays, custom cursors)
**Styling Approach**
- Default to Tailwind CSS utility classes when available -- fast, maintainable, consistent
- Use custom CSS when the vision requires it: complex animations, unique effects, advanced compositions
- Balance utility-first speed with creative freedom where it matters
**Match Vision to Execution**
- Maximalist designs -> elaborate implementation, extensive animations, rich effects
- Minimalist designs -> restraint, precision, careful spacing and typography
- Elegance comes from executing the chosen vision fully, not halfway
## Design Thinking
Before coding, understand the context and commit to a BOLD aesthetic direction:
- **Purpose**: What problem does this interface solve? Who uses it?
- **Tone**: Pick an extreme: brutally minimal, maximalist chaos, retro-futuristic, organic/natural, luxury/refined, playful/toy-like, editorial/magazine, brutalist/raw, art deco/geometric, soft/pastel, industrial/utilitarian
- **Constraints**: Technical requirements (framework, performance, accessibility)
- **Differentiation**: What makes this UNFORGETTABLE? What's the one thing someone will remember?
## Constraints
- Respect existing design systems when present
- Leverage component libraries where available
- Prioritize visual excellence -- code perfection comes second
## Skills
- When implementing React components, invoke the `react-patterns` skill for code examples of composition, compound components, hooks, and accessibility patterns.
- When optimizing performance, invoke the `vercel-react-best-practices` skill for Vercel's 45 prioritized performance rules.
You are capable of extraordinary creative work. Commit fully to distinctive visions and show what's possible when breaking conventions thoughtfully.
@@ -0,0 +1,84 @@
---
description: Conventional frontend specialist. React 18+, Tailwind CSS, TypeScript, accessibility (WCAG 2.1 AA), responsive design, performance optimization.
mode: all
temperature: 0.2
---
You are Designer - a frontend specialist focused on building production-grade, accessible, performant interfaces.
## Core Stack
- **React 18+**: Server Components, Suspense, useTransition, useDeferredValue
- **TypeScript**: Strict mode, no implicit any, explicit return types on exports
- **Tailwind CSS**: Utility-first, design tokens via CSS variables, responsive with mobile-first breakpoints
- **Accessibility**: WCAG 2.1 AA compliance from the start, not bolted on after
## Component Architecture
- **Composition over inheritance**: Build from small, focused components
- **Compound components**: Use Context for implicit state sharing (Tabs, Accordion, Menu)
- **Error boundaries**: Wrap critical UI sections with fallback UIs
- **Single responsibility**: Each component does one thing well
- **Props**: Use TypeScript interfaces, prefer explicit props over spreading
## Accessibility
- Semantic HTML first (button, nav, main, article, aside, header, footer)
- Keyboard navigation for all interactive elements
- Focus management for modals, dialogs, and dynamic content
- ARIA attributes only when semantic HTML is insufficient
- Color contrast: minimum 4.5:1 for normal text, 3:1 for large text
- Touch targets: minimum 44x44px on mobile
- Screen reader testing considerations in component design
## Performance Targets
- Largest Contentful Paint (LCP): < 2.5s
- First Input Delay (FID): < 100ms
- Cumulative Layout Shift (CLS): < 0.1
- Bundle size awareness: code split at route boundaries, lazy load below-the-fold
## Performance Patterns
- `React.memo` for expensive pure components
- `useMemo` for expensive calculations, `useCallback` for stable references passed to children
- Code splitting with `React.lazy` and `Suspense` at route and feature boundaries
- Virtualization for long lists (@tanstack/react-virtual)
- Image optimization: lazy loading, proper dimensions, modern formats (WebP/AVIF)
- Eliminate render waterfalls: parallel data fetching, avoid sequential awaits
## Styling Approach
- Tailwind utility classes as default
- CSS variables for theme tokens (colors, spacing, typography scale)
- Responsive: mobile-first with sm/md/lg/xl breakpoints
- Dark mode via Tailwind's `dark:` variant with system preference detection
- Animation: CSS transitions for simple effects, Framer Motion for complex orchestration
- Consistent spacing scale, consistent border-radius, consistent shadow levels
## State Management
- Local state (`useState`) for component-scoped state
- Context + `useReducer` for shared state within a feature
- URL state for anything that should be shareable/bookmarkable
- Server state via React Query / SWR / Server Components
- Avoid prop drilling beyond 2 levels -- lift to Context or compose differently
## TypeScript Conventions
- PascalCase for components, interfaces, types
- camelCase for functions, variables, hooks
- Props interfaces named `ComponentNameProps`
- Prefer `interface` for component props, `type` for unions/intersections
- No `any` -- use `unknown` and narrow with type guards
## Testing Considerations
- Components should be testable with React Testing Library
- Test behavior, not implementation details
- Accessible queries first: getByRole, getByLabelText, getByText
## Skills
- When implementing React components, invoke the `react-patterns` skill for code examples of composition, compound components, hooks, and accessibility patterns.
- When optimizing performance, invoke the `vercel-react-best-practices` skill for Vercel's 45 prioritized performance rules across 8 categories.
@@ -0,0 +1,48 @@
---
description: Fast codebase navigation specialist. Answers "where is X", "find Y", "which file has Z". READ-ONLY.
mode: all
temperature: 0.1
tools:
write: false
edit: false
bash: false
---
You are Explorer - a fast codebase navigation specialist.
**Role**: Quick contextual grep for codebases. Answer "Where is X?", "Find Y", "Which file has Z".
**Tools Available**:
- **grep**: Fast regex content search (powered by ripgrep). Use for text patterns, function names, strings.
Example: grep(pattern="function handleClick", include="*.ts")
- **glob**: File pattern matching. Use to find files by name/extension.
- **ast_grep_search**: AST-aware structural search (25 languages). Use for code patterns.
- Meta-variables: $VAR (single node), $$$ (multiple nodes)
- Patterns must be complete AST nodes
- Example: ast_grep_search(pattern="console.log($MSG)", lang="typescript")
- Example: ast_grep_search(pattern="async function $NAME($$$) { $$$ }", lang="javascript")
**When to use which**:
- **Text/regex patterns** (strings, comments, variable names): grep
- **Structural patterns** (function shapes, class structures): ast_grep_search
- **File discovery** (find by name/extension): glob
**Behavior**:
- Be fast and thorough
- Fire multiple searches in parallel if needed
- Return file paths with relevant snippets
**Output Format**:
<results>
<files>
- /path/to/file.ts:42 - Brief description of what's there
</files>
<answer>
Concise answer to the question
</answer>
</results>
**Constraints**:
- READ-ONLY: Search and report, don't modify
- Be exhaustive but concise
- Include line numbers when relevant
@@ -0,0 +1,44 @@
---
description: Fast, focused implementation specialist. Receives complete context, executes changes efficiently. No research or delegation.
mode: all
temperature: 0.2
permission:
bash:
"*": allow
webfetch: deny
---
You are Fixer - a fast, focused implementation specialist.
**Role**: Execute code changes efficiently. You receive complete context from research agents and clear task specifications. Your job is to implement, not plan or research.
**Behavior**:
- Execute the task specification provided
- Use the research context (file paths, documentation, patterns) provided
- Read files before using edit/write tools and gather exact content before making changes
- Be fast and direct - no research, no delegation, no multi-step planning
- Run tests/lsp_diagnostics when relevant or requested (otherwise note as skipped with reason)
- Report completion with summary of changes
**Constraints**:
- NO external research (no websearch, context7, grep_app)
- NO delegation (no background_task)
- No multi-step research/planning; minimal execution sequence ok
- If context is insufficient, read the files listed; only ask for missing inputs you cannot retrieve
**Output Format**:
<summary>
Brief summary of what was implemented
</summary>
<changes>
- file1.ts: Changed X to Y
- file2.ts: Added Z function
</changes>
<verification>
- Tests passed: [yes/no/skip reason]
- LSP diagnostics: [clean/errors found/skip reason]
</verification>
**Skills**:
- When implementing React components, invoke the `react-patterns` skill for reference on composition, hooks, and component patterns.
- When optimizing frontend performance, invoke the `vercel-react-best-practices` skill for Vercel's prioritized performance rules.
@@ -0,0 +1,43 @@
---
description: Research specialist for external documentation, library APIs, and open source examples. READ-ONLY.
mode: all
temperature: 0.1
tools:
write: false
edit: false
bash: false
---
You are Librarian - a research specialist for codebases and documentation.
**Role**: Multi-repository analysis, official docs lookup, GitHub examples, library research.
**Capabilities**:
- Search and analyze external repositories
- Find official documentation for libraries
- Locate implementation examples in open source
- Understand library internals and best practices
**Tools to Use**:
- context7: Official documentation lookup
- grep_app: Search GitHub repositories
- websearch: General web search for docs
**Request Types**:
1. **Conceptual**: "How does X work?" - Explain architecture and design decisions
2. **Implementation**: "How do I use X?" - Provide code examples and API signatures
3. **Context**: "What's the best practice for X?" - Compare approaches with tradeoffs
4. **Comprehensive**: "Tell me everything about X" - Full deep-dive with sources
**Behavior**:
- Provide evidence-based answers with sources
- Quote relevant code snippets
- Link to official docs when available
- Distinguish between official and community patterns
- Use GitHub permalinks with commit SHA when referencing code
**Constraints**:
- READ-ONLY: Research and report, don't implement
- Always cite sources
- Distinguish between stable APIs and experimental features
@@ -0,0 +1,34 @@
---
description: Strategic technical advisor. Architecture decisions, debugging strategy, code review guidance. READ-ONLY.
mode: all
temperature: 0.1
tools:
write: false
edit: false
bash: false
---
You are Oracle - a strategic technical advisor.
**Role**: High-IQ debugging, architecture decisions, code review, and engineering guidance.
**Capabilities**:
- Analyze complex codebases and identify root causes
- Propose architectural solutions with tradeoffs
- Review code for correctness, performance, and maintainability
- Guide debugging when standard approaches fail
**Behavior**:
- Be direct and concise
- Provide actionable recommendations
- Explain reasoning briefly
- Acknowledge uncertainty when present
**Constraints**:
- READ-ONLY: You advise, you don't implement
- Focus on strategy, not execution
- Point to specific files/lines when relevant
**Skills**:
- When advising on git strategy, invoke the `git-master` skill for reference on atomic commits, rebase strategy, and history search techniques.
- When planning complex multi-step tasks, invoke the `planning-with-files` skill for structured planning methodology.
@@ -0,0 +1,38 @@
---
description: Analyze and fix a GitHub issue end-to-end (plan, branch, implement, test, PR)
model: claude-sonnet-4-0
---
Please analyze and fix the GitHub issue: $ARGUMENTS.
Follow these steps:
# PLAN
1. Use 'gh issue view' to get the issue details (or open the issue in the browser/API explorer if the GitHub CLI is unavailable)
2. Understand the problem described in the issue
3. Ask clarifying questions if necessary
4. Understand the prior art for this issue
- Search the scratchpads for previous thoughts related to the issue
- Search PRs to see if you can find history on this issue
- Search the codebase for relevant files
5. Think harder about how to break the issue down into a series of small, manageable tasks.
6. Document your plan in a new scratchpad
- include the issue name in the filename
- include a link to the issue in the scratchpad.
# CREATE
- Create a new branch for the issue
- Solve the issue in small, manageable steps, according to your plan.
- Commit your changes after each step.
# TEST
- Use playwright via MCP to test the changes if you have made changes to the UI
- Write tests to describe the expected behavior of your code
- Run the full test suite to ensure you haven't broken anything
- If the tests are failing, fix them
- Ensure that all tests are passing before moving on to the next step
# DEPLOY
- Open a PR and request a review.
Prefer the GitHub CLI (`gh`) for GitHub-related tasks, but fall back to subagents or the GitHub web UI/REST API when the CLI is not installed.
@@ -0,0 +1,23 @@
---
description: Merge a worktree branch back into the base branch
---
Merge a branch from the worktree.
If you're currently working on a worktree, assume that's the one I'm referring to.
Start by committing any staged and unstaged changes. I may have made changes to the worktree manually.
Then merge back the new main branch, since I may have made changes to it.
# Language specific:
## Rust
Ensure cargo check is happy.
Ensure clippy is happy. clean up any new warnings.
## Typescript
Ensure tsc is happy.
# Finally
Squash the commits into a single one, merge into the base branch, and delete the worktree.
@@ -0,0 +1,323 @@
---
description: Remove unused code with LSP-verified safety, atomic commits
---
<command-instruction>
You are a dead code removal specialist. Execute the FULL dead code removal workflow.
Your core weapon: **LSP FindReferences**. If a symbol has ZERO external references, it's dead. Remove it.
## CRITICAL RULES
1. **LSP is law.** Never guess. Always verify with `LspFindReferences` before removing ANYTHING.
2. **One removal = one commit.** Every dead code removal gets its own atomic commit.
3. **Test after every removal.** Run tests after each. If it fails, REVERT and skip.
4. **Leaf-first order.** Remove deepest unused symbols first, then work up the dependency chain. Removing a leaf may expose new dead code upstream.
5. **Never remove entry points.** `src/index.ts`, `src/cli/index.ts`, test files, config files, and files in `packages/` are off-limits unless explicitly targeted.
---
## STEP 0: REGISTER TODO LIST (MANDATORY FIRST ACTION)
```
TodoWrite([
{"id": "scan", "content": "PHASE 1: Scan codebase for dead code candidates using LSP + explore agents", "status": "pending", "priority": "high"},
{"id": "verify", "content": "PHASE 2: Verify each candidate with LspFindReferences - zero false positives", "status": "pending", "priority": "high"},
{"id": "plan", "content": "PHASE 3: Plan removal order (leaf-first dependency order)", "status": "pending", "priority": "high"},
{"id": "remove", "content": "PHASE 4: Remove dead code one-by-one (remove -> test -> commit loop)", "status": "pending", "priority": "high"},
{"id": "final", "content": "PHASE 5: Final verification - full test suite + build + typecheck", "status": "pending", "priority": "high"}
])
```
---
## PHASE 1: SCAN FOR DEAD CODE CANDIDATES
**Mark scan as in_progress.**
### 1.1: Launch Parallel Explore Agents (ALL BACKGROUND)
Fire ALL simultaneously:
```
// Agent 1: Find all exported symbols
delegate_task(subagent_type="explore", run_in_background=true,
prompt="Find ALL exported functions, classes, types, interfaces, and constants across src/.
List each with: file path, line number, symbol name, export type (named/default).
EXCLUDE: src/index.ts root exports, test files.
Return as structured list.")
// Agent 2: Find potentially unused files
delegate_task(subagent_type="explore", run_in_background=true,
prompt="Find files in src/ that are NOT imported by any other file.
Check import/require statements across the entire codebase.
EXCLUDE: index.ts files, test files, entry points, config files, .md files.
Return list of potentially orphaned files.")
// Agent 3: Find unused imports within files
delegate_task(subagent_type="explore", run_in_background=true,
prompt="Find unused imports across src/**/*.ts files.
Look for import statements where the imported symbol is never referenced in the file body.
Return: file path, line number, imported symbol name.")
// Agent 4: Find functions/variables only used in their own declaration
delegate_task(subagent_type="explore", run_in_background=true,
prompt="Find private/non-exported functions, variables, and types in src/**/*.ts that appear
to have zero usage beyond their declaration. Return: file path, line number, symbol name.")
```
### 1.2: Direct AST-Grep Scans (WHILE AGENTS RUN)
```typescript
// Find unused imports pattern
ast_grep_search(pattern="import { $NAME } from '$PATH'", lang="typescript", paths=["src/"])
// Find empty export objects
ast_grep_search(pattern="export {}", lang="typescript", paths=["src/"])
```
### 1.3: Collect All Results
Collect background agent results. Compile into a master candidate list:
```
## DEAD CODE CANDIDATES
| # | File | Line | Symbol | Type | Confidence |
|---|------|------|--------|------|------------|
| 1 | src/foo.ts | 42 | unusedFunc | function | HIGH |
| 2 | src/bar.ts | 10 | OldType | type | MEDIUM |
```
**Mark scan as completed.**
---
## PHASE 2: VERIFY WITH LSP (ZERO FALSE POSITIVES)
**Mark verify as in_progress.**
For EVERY candidate from Phase 1, run this verification:
### 2.1: The LSP Verification Protocol
For each candidate symbol:
```typescript
// Step 1: Find the symbol's exact position
LspDocumentSymbols(filePath) // Get line/character of the symbol
// Step 2: Find ALL references across the ENTIRE workspace
LspFindReferences(filePath, line, character, includeDeclaration=false)
// includeDeclaration=false -> only counts USAGES, not the definition itself
// Step 3: Evaluate
// 0 references -> CONFIRMED DEAD CODE
// 1+ references -> NOT dead, remove from candidate list
```
### 2.2: False Positive Guards
**NEVER mark as dead code if:**
- Symbol is in `src/index.ts` (package entry point)
- Symbol is in any `index.ts` that re-exports (barrel file check: look if it's re-exported)
- Symbol is referenced in test files (tests are valid consumers)
- Symbol has `@public` or `@api` JSDoc tags
- Symbol is in a file listed in `package.json` exports
- Symbol is a hook factory registered in an index file
- Symbol is a tool factory registered in tool loading
- Symbol is an agent definition registered in agent sources
- File is a command template, skill definition, or MCP config
### 2.3: Build Confirmed Dead Code List
After verification, produce:
```
## CONFIRMED DEAD CODE (LSP-verified, 0 external references)
| # | File | Line | Symbol | Type | Safe to Remove |
|---|------|------|--------|------|----------------|
| 1 | src/foo.ts | 42 | unusedFunc | function | YES |
```
**If ZERO confirmed dead code found: Report "No dead code found" and STOP.**
**Mark verify as completed.**
---
## PHASE 3: PLAN REMOVAL ORDER
**Mark plan as in_progress.**
### 3.1: Dependency Analysis
For each confirmed dead symbol:
1. Check if removing it would expose other dead code
2. Check if other dead symbols depend on this one
3. Build removal dependency graph
### 3.2: Order by Leaf-First
```
Removal Order:
1. [Leaf symbols - no other dead code depends on them]
2. [Intermediate symbols - depended on only by already-removed dead code]
3. [Dead files - entire files with no live exports]
```
### 3.3: Register Granular Todos
Create one todo per removal.
**Mark plan as completed.**
---
## PHASE 4: ITERATIVE REMOVAL LOOP
**Mark remove as in_progress.**
For EACH dead code item, execute this exact loop:
### 4.1: Pre-Removal Check
```typescript
// Re-verify it's still dead (previous removals may have changed things)
LspFindReferences(filePath, line, character, includeDeclaration=false)
// If references > 0 now -> SKIP (previous removal exposed a new consumer)
```
### 4.2: Remove the Dead Code
Use appropriate tool:
**For unused imports:**
```typescript
Edit(filePath, oldString="import { deadSymbol } from '...';\n", newString="")
```
**For unused functions/classes/types:**
```typescript
Read(filePath, offset=startLine, limit=endLine-startLine+1)
Edit(filePath, oldString="[full symbol text]", newString="")
```
**For dead files:**
```bash
rm "path/to/dead-file.ts"
```
**After removal, also clean up:**
- Remove any imports that were ONLY used by the removed code
- Remove any now-empty import statements
- Fix any trailing whitespace / double blank lines left behind
### 4.3: Post-Removal Verification
```typescript
// 1. LSP diagnostics on changed file
LspDiagnostics(filePath, severity="error")
// 2. Run tests
bash("npm test") // or bun test, cargo test, etc.
// 3. Typecheck
bash("npm run typecheck") // or equivalent
```
### 4.4: Handle Failures
If ANY verification fails:
1. **REVERT** the change immediately (`git checkout -- [file]`)
2. Mark this removal todo as `cancelled` with note: "Removal caused [error]. Skipped."
3. Proceed to next item
### 4.5: Commit
```bash
git add [changed-files]
git commit -m "refactor: remove unused [symbolType] [symbolName] from [filePath]"
```
Mark this removal todo as `completed`.
### 4.6: Re-scan After Removal
After removing a symbol, check if its removal exposed NEW dead code:
- Were there imports that only existed to serve the removed symbol?
- Are there other symbols in the same file now unreferenced?
If new dead code is found, add it to the removal queue.
**Repeat 4.1-4.6 for every item. Mark remove as completed when done.**
---
## PHASE 5: FINAL VERIFICATION
**Mark final as in_progress.**
### 5.1: Full Test Suite
```bash
npm test
```
### 5.2: Full Typecheck
```bash
npm run typecheck
```
### 5.3: Full Build
```bash
npm run build
```
### 5.4: Summary Report
```markdown
## Dead Code Removal Complete
### Removed
| # | Symbol | File | Type | Commit |
|---|--------|------|------|--------|
| 1 | unusedFunc | src/foo.ts | function | abc1234 |
### Skipped (caused failures)
| # | Symbol | File | Reason |
|---|--------|------|--------|
| 1 | riskyFunc | src/bar.ts | Test failure: [details] |
### Verification
- Tests: PASSED (X/Y passing)
- Typecheck: CLEAN
- Build: SUCCESS
- Total dead code removed: N symbols across M files
- Total commits: K atomic commits
```
**Mark final as completed.**
---
## SCOPE CONTROL
**If $ARGUMENTS is provided**, narrow the scan to the specified scope:
- File path: Only scan that file
- Directory: Only scan that directory
- Symbol name: Only check that specific symbol
- "all" or empty: Full project scan (default)
## ABORT CONDITIONS
**STOP and report to user if:**
- 3 consecutive removals cause test failures
- Build breaks and cannot be fixed by reverting
- More than 50 candidates found (ask user to narrow scope)
</command-instruction>
<user-request>
$ARGUMENTS
</user-request>
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,69 @@
---
description: Debug complex issues with root cause analysis and multiple fix approaches
model: claude-sonnet-4-0
---
Debug complex issues using specialized debugging agents:
## Debugging Approach
### 1. Primary Debug Analysis
Use Task tool with subagent_type="debugger" to:
- Analyze error messages and stack traces
- Identify code paths leading to the issue
- Reproduce the problem systematically
- Isolate the root cause
- Suggest multiple fix approaches
Prompt: "Debug issue: $ARGUMENTS. Provide detailed analysis including:
1. Error reproduction steps
2. Root cause identification
3. Code flow analysis leading to the error
4. Multiple solution approaches with trade-offs
5. Recommended fix with implementation details"
### 2. Performance Debugging (if performance-related)
If the issue involves performance problems, also use Task tool with subagent_type="performance-engineer" to:
- Profile code execution
- Identify bottlenecks
- Analyze resource usage
- Suggest optimization strategies
Prompt: "Profile and debug performance issue: $ARGUMENTS. Include:
1. Performance metrics and profiling data
2. Bottleneck identification
3. Resource usage analysis
4. Optimization recommendations
5. Before/after performance projections"
## Debug Output Structure
### Root Cause Analysis
- Precise identification of the bug source
- Explanation of why the issue occurs
- Impact analysis on other components
### Reproduction Guide
- Step-by-step reproduction instructions
- Required environment setup
- Test data or conditions needed
### Solution Options
1. **Quick Fix** - Minimal change to resolve issue
- Implementation details
- Risk assessment
2. **Proper Fix** - Best long-term solution
- Refactoring requirements
- Testing needs
3. **Preventive Measures** - Avoid similar issues
- Code patterns to adopt
- Tests to add
### Implementation Guide
- Specific code changes needed
- Order of operations for the fix
- Validation steps
Issue to debug: $ARGUMENTS
@@ -0,0 +1,155 @@
---
description: Execute a full TDD red-green-refactor cycle
model: claude-opus-4-1
---
Execute a comprehensive Test-Driven Development (TDD) workflow with strict red-green-refactor discipline:
## Configuration
### Coverage Thresholds
- Minimum line coverage: 80%
- Minimum branch coverage: 75%
- Critical path coverage: 100%
### Refactoring Triggers
- Cyclomatic complexity > 10
- Method length > 20 lines
- Class length > 200 lines
- Duplicate code blocks > 3 lines
## Phase 1: Test Specification and Design
### 1. Requirements Analysis
- Use Task tool with subagent_type="architect-review"
- Prompt: "Analyze requirements for: $ARGUMENTS. Define acceptance criteria, identify edge cases, and create test scenarios. Output a comprehensive test specification."
- Output: Test specification, acceptance criteria, edge case matrix
- Validation: Ensure all requirements have corresponding test scenarios
### 2. Test Architecture Design
- Use Task tool with subagent_type="test-automator"
- Prompt: "Design test architecture for: $ARGUMENTS based on test specification. Define test structure, fixtures, mocks, and test data strategy. Ensure testability and maintainability."
- Output: Test architecture, fixture design, mock strategy
- Validation: Architecture supports isolated, fast, reliable tests
## Phase 2: RED - Write Failing Tests
### 3. Write Unit Tests (Failing)
- Use Task tool with subagent_type="test-automator"
- Prompt: "Write FAILING unit tests for: $ARGUMENTS. Tests must fail initially. Include edge cases, error scenarios, and happy paths. DO NOT implement production code."
- Output: Failing unit tests, test documentation
- **CRITICAL**: Verify all tests fail with expected error messages
### 4. Verify Test Failure
- Use Task tool with subagent_type="code-reviewer"
- Prompt: "Verify that all tests for: $ARGUMENTS are failing correctly. Ensure failures are for the right reasons (missing implementation, not test errors). Confirm no false positives."
- Output: Test failure verification report
- **GATE**: Do not proceed until all tests fail appropriately
## Phase 3: GREEN - Make Tests Pass
### 5. Minimal Implementation
- Use Task tool with subagent_type="backend-architect"
- Prompt: "Implement MINIMAL code to make tests pass for: $ARGUMENTS. Focus only on making tests green. Do not add extra features or optimizations. Keep it simple."
- Output: Minimal working implementation
- Constraint: No code beyond what's needed to pass tests
### 6. Verify Test Success
- Use Task tool with subagent_type="test-automator"
- Prompt: "Run all tests for: $ARGUMENTS and verify they pass. Check test coverage metrics. Ensure no tests were accidentally broken."
- Output: Test execution report, coverage metrics
- **GATE**: All tests must pass before proceeding
## Phase 4: REFACTOR - Improve Code Quality
### 7. Code Refactoring
- Use Task tool with subagent_type="code-reviewer"
- Prompt: "Refactor implementation for: $ARGUMENTS while keeping tests green. Apply SOLID principles, remove duplication, improve naming, and optimize performance. Run tests after each refactoring."
- Output: Refactored code, refactoring report
- Constraint: Tests must remain green throughout
### 8. Test Refactoring
- Use Task tool with subagent_type="test-automator"
- Prompt: "Refactor tests for: $ARGUMENTS. Remove test duplication, improve test names, extract common fixtures, and enhance test readability. Ensure tests still provide same coverage."
- Output: Refactored tests, improved test structure
- Validation: Coverage metrics unchanged or improved
## Phase 5: Integration and System Tests
### 9. Write Integration Tests (Failing First)
- Use Task tool with subagent_type="test-automator"
- Prompt: "Write FAILING integration tests for: $ARGUMENTS. Test component interactions, API contracts, and data flow. Tests must fail initially."
- Output: Failing integration tests
- Validation: Tests fail due to missing integration logic
### 10. Implement Integration
- Use Task tool with subagent_type="backend-architect"
- Prompt: "Implement integration code for: $ARGUMENTS to make integration tests pass. Focus on component interaction and data flow."
- Output: Integration implementation
- Validation: All integration tests pass
## Phase 6: Continuous Improvement Cycle
### 11. Performance and Edge Case Tests
- Use Task tool with subagent_type="test-automator"
- Prompt: "Add performance tests and additional edge case tests for: $ARGUMENTS. Include stress tests, boundary tests, and error recovery tests."
- Output: Extended test suite
- Metric: Increased test coverage and scenario coverage
### 12. Final Code Review
- Use Task tool with subagent_type="architect-review"
- Prompt: "Perform comprehensive review of: $ARGUMENTS. Verify TDD process was followed, check code quality, test quality, and coverage. Suggest improvements."
- Output: Review report, improvement suggestions
- Action: Implement critical suggestions while maintaining green tests
## Validation Checkpoints
### RED Phase Validation
- [ ] All tests written before implementation
- [ ] All tests fail with meaningful error messages
- [ ] Test failures are due to missing implementation
- [ ] No test passes accidentally
### GREEN Phase Validation
- [ ] All tests pass
- [ ] No extra code beyond test requirements
- [ ] Coverage meets minimum thresholds
- [ ] No test was modified to make it pass
### REFACTOR Phase Validation
- [ ] All tests still pass after refactoring
- [ ] Code complexity reduced
- [ ] Duplication eliminated
- [ ] Performance improved or maintained
- [ ] Test readability improved
## Failure Recovery
If TDD discipline is broken:
1. **STOP** immediately
2. Identify which phase was violated
3. Rollback to last valid state
4. Resume from correct phase
5. Document lesson learned
## Anti-Patterns to Avoid
- Writing implementation before tests
- Writing tests that already pass
- Skipping the refactor phase
- Writing multiple features without tests
- Modifying tests to make them pass
- Ignoring failing tests
- Writing tests after implementation
## Success Criteria
- 100% of code written test-first
- All tests pass continuously
- Coverage exceeds thresholds
- Code complexity within limits
- Zero defects in covered code
- Clear test documentation
- Fast test execution (< 5 seconds for unit tests)
TDD implementation for: $ARGUMENTS
@@ -0,0 +1,9 @@
---
description: Rebase/merge upstream changes into the current branch
---
This command should only work while in a secondary branch (not main or master).
Commit any unstaged changes
Fetch updates from the origin repo
If there are new commits on the parent branch (typically origin/main), then merge them back into the current branch
Solve any conflicts, and analyze the incoming changes to see if additional changes are required to the branch's code (e.g.: if something was renamed in the meantime in main, our new code may need to be adjusted)
@@ -0,0 +1,8 @@
---
description: Start a new feature in a git worktree
---
In a worktrees directory inside the git project's root, create a new worktree for the requested feature.
create the directory if it doesn't exist.
keep the branch name concise, and don't include "opencode" in its name.
do all the work for the feature in the new worktree.
run "kitty @ set-tab-title" to set the tab title of this kitty session to "<project>/<feature>"
+40
View File
@@ -0,0 +1,40 @@
{
lib,
pkgs,
config,
...
}:
{
# Global config file
xdg.configFile."opencode/opencode.json".source = ./opencode.json;
# Global rules (equivalent to ~/.claude/CLAUDE.md)
xdg.configFile."opencode/AGENTS.md".source = ./AGENTS.md;
# Custom agents
xdg.configFile."opencode/agents/oracle.md".source = ./agents/oracle.md;
xdg.configFile."opencode/agents/explorer.md".source = ./agents/explorer.md;
xdg.configFile."opencode/agents/librarian.md".source = ./agents/librarian.md;
xdg.configFile."opencode/agents/fixer.md".source = ./agents/fixer.md;
xdg.configFile."opencode/agents/designer.md".source = ./agents/designer.md;
xdg.configFile."opencode/agents/designer-bold.md".source = ./agents/designer-bold.md;
xdg.configFile."opencode/agents/analyze-branch.md".source = ./agents/analyze-branch.md;
# Global commands
xdg.configFile."opencode/commands/work.md".source = ./commands/work.md;
xdg.configFile."opencode/commands/merge.md".source = ./commands/merge.md;
xdg.configFile."opencode/commands/update.md".source = ./commands/update.md;
xdg.configFile."opencode/commands/smart-debug.md".source = ./commands/smart-debug.md;
xdg.configFile."opencode/commands/tdd-cycle.md".source = ./commands/tdd-cycle.md;
xdg.configFile."opencode/commands/security-scan.md".source = ./commands/security-scan.md;
xdg.configFile."opencode/commands/issue.md".source = ./commands/issue.md;
xdg.configFile."opencode/commands/remove-deadcode.md".source = ./commands/remove-deadcode.md;
# Skills
xdg.configFile."opencode/skills/git-master/SKILL.md".source = ./skills/git-master/SKILL.md;
xdg.configFile."opencode/skills/planning-with-files/SKILL.md".source =
./skills/planning-with-files/SKILL.md;
xdg.configFile."opencode/skills/react-patterns/SKILL.md".source = ./skills/react-patterns/SKILL.md;
xdg.configFile."opencode/skills/vercel-react-best-practices/SKILL.md".source =
./skills/vercel-react-best-practices/SKILL.md;
}
@@ -0,0 +1,16 @@
{
"$schema": "https://opencode.ai/config.json",
"autoupdate": false,
"permission": {
"read": "allow",
"edit": "allow",
"write": "allow",
"fetch": "allow",
"glob": "allow",
"grep": "allow",
"bash": "ask",
"skill": {
"*": "allow"
}
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,160 @@
---
name: planning-with-files
description: Transforms workflow to use Manus-style persistent markdown files for planning, progress tracking, and knowledge storage. Use when starting complex tasks, multi-step projects, research tasks, or when the user mentions planning, organizing work, tracking progress, or wants structured output.
---
# Planning with Files
Work like Manus: Use persistent markdown files as your "working memory on disk."
## Quick Start
Before ANY complex task:
1. **Create `task_plan.md`** in the working directory
2. **Define phases** with checkboxes
3. **Update after each phase** - mark [x] and change status
4. **Read before deciding** - refresh goals in attention window
## The 3-File Pattern
For every non-trivial task, create THREE files:
| File | Purpose | When to Update |
|------|---------|----------------|
| `task_plan.md` | Track phases and progress | After each phase |
| `notes.md` | Store findings and research | During research |
| `[deliverable].md` | Final output | At completion |
## Core Workflow
```
Loop 1: Create task_plan.md with goal and phases
Loop 2: Research → save to notes.md → update task_plan.md
Loop 3: Read notes.md → create deliverable → update task_plan.md
Loop 4: Deliver final output
```
### The Loop in Detail
**Before each major action:**
```bash
Read task_plan.md # Refresh goals in attention window
```
**After each phase:**
```bash
Edit task_plan.md # Mark [x], update status
```
**When storing information:**
```bash
Write notes.md # Don't stuff context, store in file
```
## task_plan.md Template
Create this file FIRST for any complex task:
```markdown
# Task Plan: [Brief Description]
## Goal
[One sentence describing the end state]
## Phases
- [ ] Phase 1: Plan and setup
- [ ] Phase 2: Research/gather information
- [ ] Phase 3: Execute/build
- [ ] Phase 4: Review and deliver
## Key Questions
1. [Question to answer]
2. [Question to answer]
## Decisions Made
- [Decision]: [Rationale]
## Errors Encountered
- [Error]: [Resolution]
## Status
**Currently in Phase X** - [What I'm doing now]
```
## notes.md Template
For research and findings:
```markdown
# Notes: [Topic]
## Sources
### Source 1: [Name]
- URL: [link]
- Key points:
- [Finding]
- [Finding]
## Synthesized Findings
### [Category]
- [Finding]
- [Finding]
```
## Critical Rules
### 1. ALWAYS Create Plan First
Never start a complex task without `task_plan.md`. This is non-negotiable.
### 2. Read Before Decide
Before any major decision, read the plan file. This keeps goals in your attention window.
### 3. Update After Act
After completing any phase, immediately update the plan file:
- Mark completed phases with [x]
- Update the Status section
- Log any errors encountered
### 4. Store, Don't Stuff
Large outputs go to files, not context. Keep only paths in working memory.
### 5. Log All Errors
Every error goes in the "Errors Encountered" section. This builds knowledge for future tasks.
## When to Use This Pattern
**Use 3-file pattern for:**
- Multi-step tasks (3+ steps)
- Research tasks
- Building/creating something
- Tasks spanning multiple tool calls
- Anything requiring organization
**Skip for:**
- Simple questions
- Single-file edits
- Quick lookups
## Anti-Patterns to Avoid
| Don't | Do Instead |
|-------|------------|
| Use TodoWrite for persistence | Create `task_plan.md` file |
| State goals once and forget | Re-read plan before each decision |
| Hide errors and retry | Log errors to plan file |
| Stuff everything in context | Store large content in files |
| Start executing immediately | Create plan file FIRST |
## Advanced Patterns
See [reference.md](reference.md) for:
- Attention manipulation techniques
- Error recovery patterns
- Context optimization from Manus
See [examples.md](examples.md) for:
- Real task examples
- Complex workflow patterns
@@ -0,0 +1,631 @@
---
name: react-patterns
description: React component patterns with TypeScript examples. Composition, compound components, custom hooks, Context+Reducer state, memoization, code splitting, virtualization, error boundaries, accessibility (keyboard nav, focus management), and animations.
---
# Frontend Development Patterns
Modern frontend patterns for React, Next.js, and performant user interfaces.
## Component Patterns
### Composition Over Inheritance
```typescript
// ✅ GOOD: Component composition
interface CardProps {
children: React.ReactNode
variant?: 'default' | 'outlined'
}
export function Card({ children, variant = 'default' }: CardProps) {
return <div className={`card card-${variant}`}>{children}</div>
}
export function CardHeader({ children }: { children: React.ReactNode }) {
return <div className="card-header">{children}</div>
}
export function CardBody({ children }: { children: React.ReactNode }) {
return <div className="card-body">{children}</div>
}
// Usage
<Card>
<CardHeader>Title</CardHeader>
<CardBody>Content</CardBody>
</Card>
```
### Compound Components
```typescript
interface TabsContextValue {
activeTab: string
setActiveTab: (tab: string) => void
}
const TabsContext = createContext<TabsContextValue | undefined>(undefined)
export function Tabs({ children, defaultTab }: {
children: React.ReactNode
defaultTab: string
}) {
const [activeTab, setActiveTab] = useState(defaultTab)
return (
<TabsContext.Provider value={{ activeTab, setActiveTab }}>
{children}
</TabsContext.Provider>
)
}
export function TabList({ children }: { children: React.ReactNode }) {
return <div className="tab-list">{children}</div>
}
export function Tab({ id, children }: { id: string, children: React.ReactNode }) {
const context = useContext(TabsContext)
if (!context) throw new Error('Tab must be used within Tabs')
return (
<button
className={context.activeTab === id ? 'active' : ''}
onClick={() => context.setActiveTab(id)}
>
{children}
</button>
)
}
// Usage
<Tabs defaultTab="overview">
<TabList>
<Tab id="overview">Overview</Tab>
<Tab id="details">Details</Tab>
</TabList>
</Tabs>
```
### Render Props Pattern
```typescript
interface DataLoaderProps<T> {
url: string
children: (data: T | null, loading: boolean, error: Error | null) => React.ReactNode
}
export function DataLoader<T>({ url, children }: DataLoaderProps<T>) {
const [data, setData] = useState<T | null>(null)
const [loading, setLoading] = useState(true)
const [error, setError] = useState<Error | null>(null)
useEffect(() => {
fetch(url)
.then(res => res.json())
.then(setData)
.catch(setError)
.finally(() => setLoading(false))
}, [url])
return <>{children(data, loading, error)}</>
}
// Usage
<DataLoader<Market[]> url="/api/markets">
{(markets, loading, error) => {
if (loading) return <Spinner />
if (error) return <Error error={error} />
return <MarketList markets={markets!} />
}}
</DataLoader>
```
## Custom Hooks Patterns
### State Management Hook
```typescript
export function useToggle(initialValue = false): [boolean, () => void] {
const [value, setValue] = useState(initialValue)
const toggle = useCallback(() => {
setValue(v => !v)
}, [])
return [value, toggle]
}
// Usage
const [isOpen, toggleOpen] = useToggle()
```
### Async Data Fetching Hook
```typescript
interface UseQueryOptions<T> {
onSuccess?: (data: T) => void
onError?: (error: Error) => void
enabled?: boolean
}
export function useQuery<T>(
key: string,
fetcher: () => Promise<T>,
options?: UseQueryOptions<T>
) {
const [data, setData] = useState<T | null>(null)
const [error, setError] = useState<Error | null>(null)
const [loading, setLoading] = useState(false)
const refetch = useCallback(async () => {
setLoading(true)
setError(null)
try {
const result = await fetcher()
setData(result)
options?.onSuccess?.(result)
} catch (err) {
const error = err as Error
setError(error)
options?.onError?.(error)
} finally {
setLoading(false)
}
}, [fetcher, options])
useEffect(() => {
if (options?.enabled !== false) {
refetch()
}
}, [key, refetch, options?.enabled])
return { data, error, loading, refetch }
}
// Usage
const { data: markets, loading, error, refetch } = useQuery(
'markets',
() => fetch('/api/markets').then(r => r.json()),
{
onSuccess: data => console.log('Fetched', data.length, 'markets'),
onError: err => console.error('Failed:', err)
}
)
```
### Debounce Hook
```typescript
export function useDebounce<T>(value: T, delay: number): T {
const [debouncedValue, setDebouncedValue] = useState<T>(value)
useEffect(() => {
const handler = setTimeout(() => {
setDebouncedValue(value)
}, delay)
return () => clearTimeout(handler)
}, [value, delay])
return debouncedValue
}
// Usage
const [searchQuery, setSearchQuery] = useState('')
const debouncedQuery = useDebounce(searchQuery, 500)
useEffect(() => {
if (debouncedQuery) {
performSearch(debouncedQuery)
}
}, [debouncedQuery])
```
## State Management Patterns
### Context + Reducer Pattern
```typescript
interface State {
markets: Market[]
selectedMarket: Market | null
loading: boolean
}
type Action =
| { type: 'SET_MARKETS'; payload: Market[] }
| { type: 'SELECT_MARKET'; payload: Market }
| { type: 'SET_LOADING'; payload: boolean }
function reducer(state: State, action: Action): State {
switch (action.type) {
case 'SET_MARKETS':
return { ...state, markets: action.payload }
case 'SELECT_MARKET':
return { ...state, selectedMarket: action.payload }
case 'SET_LOADING':
return { ...state, loading: action.payload }
default:
return state
}
}
const MarketContext = createContext<{
state: State
dispatch: Dispatch<Action>
} | undefined>(undefined)
export function MarketProvider({ children }: { children: React.ReactNode }) {
const [state, dispatch] = useReducer(reducer, {
markets: [],
selectedMarket: null,
loading: false
})
return (
<MarketContext.Provider value={{ state, dispatch }}>
{children}
</MarketContext.Provider>
)
}
export function useMarkets() {
const context = useContext(MarketContext)
if (!context) throw new Error('useMarkets must be used within MarketProvider')
return context
}
```
## Performance Optimization
### Memoization
```typescript
// ✅ useMemo for expensive computations
const sortedMarkets = useMemo(() => {
return markets.sort((a, b) => b.volume - a.volume)
}, [markets])
// ✅ useCallback for functions passed to children
const handleSearch = useCallback((query: string) => {
setSearchQuery(query)
}, [])
// ✅ React.memo for pure components
export const MarketCard = React.memo<MarketCardProps>(({ market }) => {
return (
<div className="market-card">
<h3>{market.name}</h3>
<p>{market.description}</p>
</div>
)
})
```
### Code Splitting & Lazy Loading
```typescript
import { lazy, Suspense } from 'react'
// ✅ Lazy load heavy components
const HeavyChart = lazy(() => import('./HeavyChart'))
const ThreeJsBackground = lazy(() => import('./ThreeJsBackground'))
export function Dashboard() {
return (
<div>
<Suspense fallback={<ChartSkeleton />}>
<HeavyChart data={data} />
</Suspense>
<Suspense fallback={null}>
<ThreeJsBackground />
</Suspense>
</div>
)
}
```
### Virtualization for Long Lists
```typescript
import { useVirtualizer } from '@tanstack/react-virtual'
export function VirtualMarketList({ markets }: { markets: Market[] }) {
const parentRef = useRef<HTMLDivElement>(null)
const virtualizer = useVirtualizer({
count: markets.length,
getScrollElement: () => parentRef.current,
estimateSize: () => 100, // Estimated row height
overscan: 5 // Extra items to render
})
return (
<div ref={parentRef} style={{ height: '600px', overflow: 'auto' }}>
<div
style={{
height: `${virtualizer.getTotalSize()}px`,
position: 'relative'
}}
>
{virtualizer.getVirtualItems().map(virtualRow => (
<div
key={virtualRow.index}
style={{
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: `${virtualRow.size}px`,
transform: `translateY(${virtualRow.start}px)`
}}
>
<MarketCard market={markets[virtualRow.index]} />
</div>
))}
</div>
</div>
)
}
```
## Form Handling Patterns
### Controlled Form with Validation
```typescript
interface FormData {
name: string
description: string
endDate: string
}
interface FormErrors {
name?: string
description?: string
endDate?: string
}
export function CreateMarketForm() {
const [formData, setFormData] = useState<FormData>({
name: '',
description: '',
endDate: ''
})
const [errors, setErrors] = useState<FormErrors>({})
const validate = (): boolean => {
const newErrors: FormErrors = {}
if (!formData.name.trim()) {
newErrors.name = 'Name is required'
} else if (formData.name.length > 200) {
newErrors.name = 'Name must be under 200 characters'
}
if (!formData.description.trim()) {
newErrors.description = 'Description is required'
}
if (!formData.endDate) {
newErrors.endDate = 'End date is required'
}
setErrors(newErrors)
return Object.keys(newErrors).length === 0
}
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault()
if (!validate()) return
try {
await createMarket(formData)
// Success handling
} catch (error) {
// Error handling
}
}
return (
<form onSubmit={handleSubmit}>
<input
value={formData.name}
onChange={e => setFormData(prev => ({ ...prev, name: e.target.value }))}
placeholder="Market name"
/>
{errors.name && <span className="error">{errors.name}</span>}
{/* Other fields */}
<button type="submit">Create Market</button>
</form>
)
}
```
## Error Boundary Pattern
```typescript
interface ErrorBoundaryState {
hasError: boolean
error: Error | null
}
export class ErrorBoundary extends React.Component<
{ children: React.ReactNode },
ErrorBoundaryState
> {
state: ErrorBoundaryState = {
hasError: false,
error: null
}
static getDerivedStateFromError(error: Error): ErrorBoundaryState {
return { hasError: true, error }
}
componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
console.error('Error boundary caught:', error, errorInfo)
}
render() {
if (this.state.hasError) {
return (
<div className="error-fallback">
<h2>Something went wrong</h2>
<p>{this.state.error?.message}</p>
<button onClick={() => this.setState({ hasError: false })}>
Try again
</button>
</div>
)
}
return this.props.children
}
}
// Usage
<ErrorBoundary>
<App />
</ErrorBoundary>
```
## Animation Patterns
### Framer Motion Animations
```typescript
import { motion, AnimatePresence } from 'framer-motion'
// ✅ List animations
export function AnimatedMarketList({ markets }: { markets: Market[] }) {
return (
<AnimatePresence>
{markets.map(market => (
<motion.div
key={market.id}
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: -20 }}
transition={{ duration: 0.3 }}
>
<MarketCard market={market} />
</motion.div>
))}
</AnimatePresence>
)
}
// ✅ Modal animations
export function Modal({ isOpen, onClose, children }: ModalProps) {
return (
<AnimatePresence>
{isOpen && (
<>
<motion.div
className="modal-overlay"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
onClick={onClose}
/>
<motion.div
className="modal-content"
initial={{ opacity: 0, scale: 0.9, y: 20 }}
animate={{ opacity: 1, scale: 1, y: 0 }}
exit={{ opacity: 0, scale: 0.9, y: 20 }}
>
{children}
</motion.div>
</>
)}
</AnimatePresence>
)
}
```
## Accessibility Patterns
### Keyboard Navigation
```typescript
export function Dropdown({ options, onSelect }: DropdownProps) {
const [isOpen, setIsOpen] = useState(false)
const [activeIndex, setActiveIndex] = useState(0)
const handleKeyDown = (e: React.KeyboardEvent) => {
switch (e.key) {
case 'ArrowDown':
e.preventDefault()
setActiveIndex(i => Math.min(i + 1, options.length - 1))
break
case 'ArrowUp':
e.preventDefault()
setActiveIndex(i => Math.max(i - 1, 0))
break
case 'Enter':
e.preventDefault()
onSelect(options[activeIndex])
setIsOpen(false)
break
case 'Escape':
setIsOpen(false)
break
}
}
return (
<div
role="combobox"
aria-expanded={isOpen}
aria-haspopup="listbox"
onKeyDown={handleKeyDown}
>
{/* Dropdown implementation */}
</div>
)
}
```
### Focus Management
```typescript
export function Modal({ isOpen, onClose, children }: ModalProps) {
const modalRef = useRef<HTMLDivElement>(null)
const previousFocusRef = useRef<HTMLElement | null>(null)
useEffect(() => {
if (isOpen) {
// Save currently focused element
previousFocusRef.current = document.activeElement as HTMLElement
// Focus modal
modalRef.current?.focus()
} else {
// Restore focus when closing
previousFocusRef.current?.focus()
}
}, [isOpen])
return isOpen ? (
<div
ref={modalRef}
role="dialog"
aria-modal="true"
tabIndex={-1}
onKeyDown={e => e.key === 'Escape' && onClose()}
>
{children}
</div>
) : null
}
```
**Remember**: Modern frontend patterns enable maintainable, performant user interfaces. Choose patterns that fit your project complexity.
@@ -0,0 +1,121 @@
---
name: vercel-react-best-practices
description: React and Next.js performance optimization guidelines from Vercel Engineering. This skill should be used when writing, reviewing, or refactoring React/Next.js code to ensure optimal performance patterns. Triggers on tasks involving React components, Next.js pages, data fetching, bundle optimization, or performance improvements.
---
# Vercel React Best Practices
Comprehensive performance optimization guide for React and Next.js applications, maintained by Vercel. Contains 45 rules across 8 categories, prioritized by impact to guide automated refactoring and code generation.
## When to Apply
Reference these guidelines when:
- Writing new React components or Next.js pages
- Implementing data fetching (client or server-side)
- Reviewing code for performance issues
- Refactoring existing React/Next.js code
- Optimizing bundle size or load times
## Rule Categories by Priority
| Priority | Category | Impact | Prefix |
|----------|----------|--------|--------|
| 1 | Eliminating Waterfalls | CRITICAL | `async-` |
| 2 | Bundle Size Optimization | CRITICAL | `bundle-` |
| 3 | Server-Side Performance | HIGH | `server-` |
| 4 | Client-Side Data Fetching | MEDIUM-HIGH | `client-` |
| 5 | Re-render Optimization | MEDIUM | `rerender-` |
| 6 | Rendering Performance | MEDIUM | `rendering-` |
| 7 | JavaScript Performance | LOW-MEDIUM | `js-` |
| 8 | Advanced Patterns | LOW | `advanced-` |
## Quick Reference
### 1. Eliminating Waterfalls (CRITICAL)
- `async-defer-await` - Move await into branches where actually used
- `async-parallel` - Use Promise.all() for independent operations
- `async-dependencies` - Use better-all for partial dependencies
- `async-api-routes` - Start promises early, await late in API routes
- `async-suspense-boundaries` - Use Suspense to stream content
### 2. Bundle Size Optimization (CRITICAL)
- `bundle-barrel-imports` - Import directly, avoid barrel files
- `bundle-dynamic-imports` - Use next/dynamic for heavy components
- `bundle-defer-third-party` - Load analytics/logging after hydration
- `bundle-conditional` - Load modules only when feature is activated
- `bundle-preload` - Preload on hover/focus for perceived speed
### 3. Server-Side Performance (HIGH)
- `server-cache-react` - Use React.cache() for per-request deduplication
- `server-cache-lru` - Use LRU cache for cross-request caching
- `server-serialization` - Minimize data passed to client components
- `server-parallel-fetching` - Restructure components to parallelize fetches
- `server-after-nonblocking` - Use after() for non-blocking operations
### 4. Client-Side Data Fetching (MEDIUM-HIGH)
- `client-swr-dedup` - Use SWR for automatic request deduplication
- `client-event-listeners` - Deduplicate global event listeners
### 5. Re-render Optimization (MEDIUM)
- `rerender-defer-reads` - Don't subscribe to state only used in callbacks
- `rerender-memo` - Extract expensive work into memoized components
- `rerender-dependencies` - Use primitive dependencies in effects
- `rerender-derived-state` - Subscribe to derived booleans, not raw values
- `rerender-functional-setstate` - Use functional setState for stable callbacks
- `rerender-lazy-state-init` - Pass function to useState for expensive values
- `rerender-transitions` - Use startTransition for non-urgent updates
### 6. Rendering Performance (MEDIUM)
- `rendering-animate-svg-wrapper` - Animate div wrapper, not SVG element
- `rendering-content-visibility` - Use content-visibility for long lists
- `rendering-hoist-jsx` - Extract static JSX outside components
- `rendering-svg-precision` - Reduce SVG coordinate precision
- `rendering-hydration-no-flicker` - Use inline script for client-only data
- `rendering-activity` - Use Activity component for show/hide
- `rendering-conditional-render` - Use ternary, not && for conditionals
### 7. JavaScript Performance (LOW-MEDIUM)
- `js-batch-dom-css` - Group CSS changes via classes or cssText
- `js-index-maps` - Build Map for repeated lookups
- `js-cache-property-access` - Cache object properties in loops
- `js-cache-function-results` - Cache function results in module-level Map
- `js-cache-storage` - Cache localStorage/sessionStorage reads
- `js-combine-iterations` - Combine multiple filter/map into one loop
- `js-length-check-first` - Check array length before expensive comparison
- `js-early-exit` - Return early from functions
- `js-hoist-regexp` - Hoist RegExp creation outside loops
- `js-min-max-loop` - Use loop for min/max instead of sort
- `js-set-map-lookups` - Use Set/Map for O(1) lookups
- `js-tosorted-immutable` - Use toSorted() for immutability
### 8. Advanced Patterns (LOW)
- `advanced-event-handler-refs` - Store event handlers in refs
- `advanced-use-latest` - useLatest for stable callback refs
## How to Use
Read individual rule files for detailed explanations and code examples:
```
rules/async-parallel.md
rules/bundle-barrel-imports.md
rules/_sections.md
```
Each rule file contains:
- Brief explanation of why it matters
- Incorrect code example with explanation
- Correct code example with explanation
- Additional context and references
## Full Compiled Document
For the complete guide with all rules expanded: `AGENTS.md`