contextos-agents 1.5.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.
- package/.agents/AGENTS.md +421 -0
- package/.agents/adapters/aider/export.js +137 -0
- package/.agents/adapters/claude/export.js +55 -0
- package/.agents/adapters/copilot/export.js +107 -0
- package/.agents/adapters/cursor/export.js +210 -0
- package/.agents/adapters/gemini/export.js +115 -0
- package/.agents/adapters/shared.js +119 -0
- package/.agents/adapters/zed/export.js +111 -0
- package/.agents/core/profiles/backend.yaml +47 -0
- package/.agents/core/profiles/enterprise.yaml +46 -0
- package/.agents/core/profiles/frontend.yaml +46 -0
- package/.agents/core/profiles/hackathon.yaml +45 -0
- package/.agents/core/profiles/mvp.yaml +43 -0
- package/.agents/core/profiles/startup.yaml +48 -0
- package/.agents/core/skills/adapters/EXAMPLES.md +19 -0
- package/.agents/core/skills/adapters/SKILL.md +105 -0
- package/.agents/core/skills/adapters/TROUBLESHOOTING.md +7 -0
- package/.agents/core/skills/adapters/VALIDATION.json +12 -0
- package/.agents/core/skills/adapters/skill.yaml +10 -0
- package/.agents/core/skills/architecture-diagrams/SKILL.md +108 -0
- package/.agents/core/skills/architecture-diagrams/VALIDATION.json +12 -0
- package/.agents/core/skills/architecture-diagrams/skill.yaml +8 -0
- package/.agents/core/skills/brutalist-design/SKILL.md +150 -0
- package/.agents/core/skills/brutalist-design/VALIDATION.json +12 -0
- package/.agents/core/skills/brutalist-design/skill.yaml +8 -0
- package/.agents/core/skills/context-manager/EXAMPLES.md +19 -0
- package/.agents/core/skills/context-manager/SKILL.md +126 -0
- package/.agents/core/skills/context-manager/TROUBLESHOOTING.md +7 -0
- package/.agents/core/skills/context-manager/VALIDATION.json +12 -0
- package/.agents/core/skills/context-manager/skill.yaml +10 -0
- package/.agents/core/skills/context-os/EXAMPLES.md +21 -0
- package/.agents/core/skills/context-os/SKILL.md +169 -0
- package/.agents/core/skills/context-os/TROUBLESHOOTING.md +7 -0
- package/.agents/core/skills/context-os/VALIDATION.json +12 -0
- package/.agents/core/skills/context-os/packs.yaml +59 -0
- package/.agents/core/skills/context-os/references/context-rules.md +68 -0
- package/.agents/core/skills/context-os/references/pipeline.md +119 -0
- package/.agents/core/skills/context-os/references/project-graph.md +103 -0
- package/.agents/core/skills/context-os/rules.yaml +135 -0
- package/.agents/core/skills/context-os/skill.yaml +10 -0
- package/.agents/core/skills/database/EXAMPLES.md +74 -0
- package/.agents/core/skills/database/SKILL.md +101 -0
- package/.agents/core/skills/database/TROUBLESHOOTING.md +18 -0
- package/.agents/core/skills/database/VALIDATION.json +11 -0
- package/.agents/core/skills/database/skill.yaml +25 -0
- package/.agents/core/skills/ddd/EXAMPLES.md +42 -0
- package/.agents/core/skills/ddd/SKILL.md +247 -0
- package/.agents/core/skills/ddd/TROUBLESHOOTING.md +19 -0
- package/.agents/core/skills/ddd/VALIDATION.json +12 -0
- package/.agents/core/skills/ddd/ddd.md +178 -0
- package/.agents/core/skills/ddd/skill.yaml +10 -0
- package/.agents/core/skills/decisions/EXAMPLES.md +35 -0
- package/.agents/core/skills/decisions/SKILL.md +90 -0
- package/.agents/core/skills/decisions/TROUBLESHOOTING.md +13 -0
- package/.agents/core/skills/decisions/VALIDATION.json +12 -0
- package/.agents/core/skills/decisions/skill.yaml +10 -0
- package/.agents/core/skills/docker/EXAMPLES.md +56 -0
- package/.agents/core/skills/docker/SKILL.md +63 -0
- package/.agents/core/skills/docker/TROUBLESHOOTING.md +18 -0
- package/.agents/core/skills/docker/VALIDATION.json +11 -0
- package/.agents/core/skills/docker/skill.yaml +23 -0
- package/.agents/core/skills/engineering-workflow/EXAMPLES.md +57 -0
- package/.agents/core/skills/engineering-workflow/SKILL.md +343 -0
- package/.agents/core/skills/engineering-workflow/TROUBLESHOOTING.md +19 -0
- package/.agents/core/skills/engineering-workflow/VALIDATION.json +12 -0
- package/.agents/core/skills/engineering-workflow/skill.yaml +13 -0
- package/.agents/core/skills/fastapi/EXAMPLES.md +36 -0
- package/.agents/core/skills/fastapi/SKILL.md +148 -0
- package/.agents/core/skills/fastapi/TROUBLESHOOTING.md +19 -0
- package/.agents/core/skills/fastapi/VALIDATION.json +12 -0
- package/.agents/core/skills/fastapi/fastapi.md +112 -0
- package/.agents/core/skills/fastapi/skill.yaml +10 -0
- package/.agents/core/skills/gemini-precision/SKILL.md +169 -0
- package/.agents/core/skills/gemini-precision/VALIDATION.json +12 -0
- package/.agents/core/skills/gemini-precision/skill.yaml +9 -0
- package/.agents/core/skills/generators/EXAMPLES.md +19 -0
- package/.agents/core/skills/generators/SKILL.md +112 -0
- package/.agents/core/skills/generators/TROUBLESHOOTING.md +7 -0
- package/.agents/core/skills/generators/VALIDATION.json +12 -0
- package/.agents/core/skills/generators/skill.yaml +10 -0
- package/.agents/core/skills/generators/templates/API.md +77 -0
- package/.agents/core/skills/generators/templates/ARCHITECTURE.md +70 -0
- package/.agents/core/skills/generators/templates/DATABASE.md +42 -0
- package/.agents/core/skills/generators/templates/DECISION.md +46 -0
- package/.agents/core/skills/generators/templates/PRD.md +67 -0
- package/.agents/core/skills/generators/templates/PROJECT_GRAPH.md +56 -0
- package/.agents/core/skills/generators/templates/ROADMAP.md +51 -0
- package/.agents/core/skills/generators/templates/TASKS.md +43 -0
- package/.agents/core/skills/generators/templates/UI.md +73 -0
- package/.agents/core/skills/graphify/EXAMPLES.md +73 -0
- package/.agents/core/skills/graphify/SKILL.md +130 -0
- package/.agents/core/skills/graphify/VALIDATION.json +12 -0
- package/.agents/core/skills/graphify/skill.yaml +13 -0
- package/.agents/core/skills/gstack-roles/EXAMPLES.md +23 -0
- package/.agents/core/skills/gstack-roles/SKILL.md +152 -0
- package/.agents/core/skills/gstack-roles/TROUBLESHOOTING.md +13 -0
- package/.agents/core/skills/gstack-roles/VALIDATION.json +12 -0
- package/.agents/core/skills/gstack-roles/skill.yaml +12 -0
- package/.agents/core/skills/impeccable-design/EXAMPLES.md +26 -0
- package/.agents/core/skills/impeccable-design/SKILL.md +201 -0
- package/.agents/core/skills/impeccable-design/TROUBLESHOOTING.md +19 -0
- package/.agents/core/skills/impeccable-design/VALIDATION.json +12 -0
- package/.agents/core/skills/impeccable-design/skill.yaml +14 -0
- package/.agents/core/skills/interview-me/SKILL.md +97 -0
- package/.agents/core/skills/interview-me/VALIDATION.json +12 -0
- package/.agents/core/skills/interview-me/skill.yaml +8 -0
- package/.agents/core/skills/microservices/EXAMPLES.md +38 -0
- package/.agents/core/skills/microservices/SKILL.md +164 -0
- package/.agents/core/skills/microservices/TROUBLESHOOTING.md +19 -0
- package/.agents/core/skills/microservices/VALIDATION.json +12 -0
- package/.agents/core/skills/microservices/microservices.md +119 -0
- package/.agents/core/skills/microservices/skill.yaml +10 -0
- package/.agents/core/skills/minimalist-design/SKILL.md +113 -0
- package/.agents/core/skills/minimalist-design/VALIDATION.json +12 -0
- package/.agents/core/skills/minimalist-design/skill.yaml +8 -0
- package/.agents/core/skills/nestjs/EXAMPLES.md +40 -0
- package/.agents/core/skills/nestjs/SKILL.md +139 -0
- package/.agents/core/skills/nestjs/TROUBLESHOOTING.md +19 -0
- package/.agents/core/skills/nestjs/VALIDATION.json +12 -0
- package/.agents/core/skills/nestjs/nestjs.md +103 -0
- package/.agents/core/skills/nestjs/skill.yaml +10 -0
- package/.agents/core/skills/nextjs/EXAMPLES.md +40 -0
- package/.agents/core/skills/nextjs/SKILL.md +163 -0
- package/.agents/core/skills/nextjs/TROUBLESHOOTING.md +19 -0
- package/.agents/core/skills/nextjs/VALIDATION.json +12 -0
- package/.agents/core/skills/nextjs/nextjs.md +67 -0
- package/.agents/core/skills/nextjs/skill.yaml +10 -0
- package/.agents/core/skills/node/EXAMPLES.md +80 -0
- package/.agents/core/skills/node/SKILL.md +128 -0
- package/.agents/core/skills/node/TROUBLESHOOTING.md +19 -0
- package/.agents/core/skills/node/VALIDATION.json +12 -0
- package/.agents/core/skills/node/node.md +87 -0
- package/.agents/core/skills/node/skill.yaml +10 -0
- package/.agents/core/skills/performance/EXAMPLES.md +30 -0
- package/.agents/core/skills/performance/SKILL.md +75 -0
- package/.agents/core/skills/performance/TROUBLESHOOTING.md +19 -0
- package/.agents/core/skills/performance/VALIDATION.json +12 -0
- package/.agents/core/skills/performance/performance.md +52 -0
- package/.agents/core/skills/performance/skill.yaml +10 -0
- package/.agents/core/skills/ponytail-mindset/EXAMPLES.md +45 -0
- package/.agents/core/skills/ponytail-mindset/SKILL.md +193 -0
- package/.agents/core/skills/ponytail-mindset/TROUBLESHOOTING.md +19 -0
- package/.agents/core/skills/ponytail-mindset/VALIDATION.json +12 -0
- package/.agents/core/skills/ponytail-mindset/skill.yaml +14 -0
- package/.agents/core/skills/react/EXAMPLES.md +79 -0
- package/.agents/core/skills/react/SKILL.md +132 -0
- package/.agents/core/skills/react/TROUBLESHOOTING.md +19 -0
- package/.agents/core/skills/react/VALIDATION.json +12 -0
- package/.agents/core/skills/react/react.md +93 -0
- package/.agents/core/skills/react/skill.yaml +10 -0
- package/.agents/core/skills/react-best-practices/SKILL.md +155 -0
- package/.agents/core/skills/react-best-practices/VALIDATION.json +12 -0
- package/.agents/core/skills/react-best-practices/skill.yaml +10 -0
- package/.agents/core/skills/redesign-audit/SKILL.md +117 -0
- package/.agents/core/skills/redesign-audit/VALIDATION.json +12 -0
- package/.agents/core/skills/redesign-audit/skill.yaml +8 -0
- package/.agents/core/skills/security/EXAMPLES.md +64 -0
- package/.agents/core/skills/security/SKILL.md +158 -0
- package/.agents/core/skills/security/TROUBLESHOOTING.md +19 -0
- package/.agents/core/skills/security/VALIDATION.json +12 -0
- package/.agents/core/skills/security/security.md +106 -0
- package/.agents/core/skills/security/skill.yaml +10 -0
- package/.agents/core/skills/soft-design/SKILL.md +108 -0
- package/.agents/core/skills/soft-design/VALIDATION.json +12 -0
- package/.agents/core/skills/soft-design/skill.yaml +8 -0
- package/.agents/core/skills/state-management/EXAMPLES.md +56 -0
- package/.agents/core/skills/state-management/SKILL.md +48 -0
- package/.agents/core/skills/state-management/TROUBLESHOOTING.md +18 -0
- package/.agents/core/skills/state-management/VALIDATION.json +11 -0
- package/.agents/core/skills/state-management/skill.yaml +22 -0
- package/.agents/core/skills/subagent-orchestrator/SKILL.md +100 -0
- package/.agents/core/skills/subagent-orchestrator/VALIDATION.json +12 -0
- package/.agents/core/skills/subagent-orchestrator/skill.yaml +8 -0
- package/.agents/core/skills/system-design/EXAMPLES.md +75 -0
- package/.agents/core/skills/system-design/SKILL.md +419 -0
- package/.agents/core/skills/system-design/TROUBLESHOOTING.md +19 -0
- package/.agents/core/skills/system-design/VALIDATION.json +12 -0
- package/.agents/core/skills/system-design/skill.yaml +13 -0
- package/.agents/core/skills/system-design/system-design.md +112 -0
- package/.agents/core/skills/testing/EXAMPLES.md +71 -0
- package/.agents/core/skills/testing/SKILL.md +70 -0
- package/.agents/core/skills/testing/TROUBLESHOOTING.md +18 -0
- package/.agents/core/skills/testing/VALIDATION.json +11 -0
- package/.agents/core/skills/testing/skill.yaml +26 -0
- package/.agents/core/skills/typescript/EXAMPLES.md +64 -0
- package/.agents/core/skills/typescript/SKILL.md +112 -0
- package/.agents/core/skills/typescript/TROUBLESHOOTING.md +19 -0
- package/.agents/core/skills/typescript/VALIDATION.json +12 -0
- package/.agents/core/skills/typescript/skill.yaml +10 -0
- package/.agents/core/skills/typescript/typescript.md +71 -0
- package/.agents/core/skills/ui-design/EXAMPLES.md +21 -0
- package/.agents/core/skills/ui-design/SKILL.md +124 -0
- package/.agents/core/skills/ui-design/TROUBLESHOOTING.md +19 -0
- package/.agents/core/skills/ui-design/VALIDATION.json +12 -0
- package/.agents/core/skills/ui-design/skill.yaml +10 -0
- package/.agents/core/skills/ui-design/ui.md +88 -0
- package/.agents/core/skills/ui-ux-pro/EXAMPLES.md +62 -0
- package/.agents/core/skills/ui-ux-pro/SKILL.md +375 -0
- package/.agents/core/skills/ui-ux-pro/TROUBLESHOOTING.md +19 -0
- package/.agents/core/skills/ui-ux-pro/VALIDATION.json +12 -0
- package/.agents/core/skills/ui-ux-pro/skill.yaml +13 -0
- package/.agents/core/skills/ux-design/EXAMPLES.md +36 -0
- package/.agents/core/skills/ux-design/SKILL.md +116 -0
- package/.agents/core/skills/ux-design/TROUBLESHOOTING.md +19 -0
- package/.agents/core/skills/ux-design/VALIDATION.json +12 -0
- package/.agents/core/skills/ux-design/skill.yaml +10 -0
- package/.agents/core/skills/ux-design/ux.md +80 -0
- package/.agents/core/skills/vercel-optimize/SKILL.md +83 -0
- package/.agents/core/skills/vercel-optimize/VALIDATION.json +12 -0
- package/.agents/core/skills/vercel-optimize/skill.yaml +10 -0
- package/.agents/core/skills/web-accessibility/EXAMPLES.md +39 -0
- package/.agents/core/skills/web-accessibility/SKILL.md +170 -0
- package/.agents/core/skills/web-accessibility/TROUBLESHOOTING.md +19 -0
- package/.agents/core/skills/web-accessibility/VALIDATION.json +12 -0
- package/.agents/core/skills/web-accessibility/accessibility.md +63 -0
- package/.agents/core/skills/web-accessibility/skill.yaml +10 -0
- package/.agents/ctx.js +370 -0
- package/.agents/generated/claude/skills/adapters/SKILL.md +126 -0
- package/.agents/generated/claude/skills/architecture-diagrams/SKILL.md +101 -0
- package/.agents/generated/claude/skills/brutalist-design/SKILL.md +145 -0
- package/.agents/generated/claude/skills/context-manager/SKILL.md +147 -0
- package/.agents/generated/claude/skills/context-os/SKILL.md +191 -0
- package/.agents/generated/claude/skills/database/SKILL.md +191 -0
- package/.agents/generated/claude/skills/ddd/SKILL.md +305 -0
- package/.agents/generated/claude/skills/decisions/SKILL.md +134 -0
- package/.agents/generated/claude/skills/docker/SKILL.md +135 -0
- package/.agents/generated/claude/skills/engineering-workflow/SKILL.md +414 -0
- package/.agents/generated/claude/skills/fastapi/SKILL.md +200 -0
- package/.agents/generated/claude/skills/gemini-precision/SKILL.md +161 -0
- package/.agents/generated/claude/skills/generators/SKILL.md +133 -0
- package/.agents/generated/claude/skills/graphify/SKILL.md +198 -0
- package/.agents/generated/claude/skills/gstack-roles/SKILL.md +184 -0
- package/.agents/generated/claude/skills/impeccable-design/SKILL.md +241 -0
- package/.agents/generated/claude/skills/interview-me/SKILL.md +90 -0
- package/.agents/generated/claude/skills/microservices/SKILL.md +218 -0
- package/.agents/generated/claude/skills/minimalist-design/SKILL.md +108 -0
- package/.agents/generated/claude/skills/nestjs/SKILL.md +195 -0
- package/.agents/generated/claude/skills/nextjs/SKILL.md +219 -0
- package/.agents/generated/claude/skills/node/SKILL.md +224 -0
- package/.agents/generated/claude/skills/performance/SKILL.md +121 -0
- package/.agents/generated/claude/skills/ponytail-mindset/SKILL.md +252 -0
- package/.agents/generated/claude/skills/react/SKILL.md +227 -0
- package/.agents/generated/claude/skills/react-best-practices/SKILL.md +146 -0
- package/.agents/generated/claude/skills/redesign-audit/SKILL.md +112 -0
- package/.agents/generated/claude/skills/security/SKILL.md +237 -0
- package/.agents/generated/claude/skills/soft-design/SKILL.md +103 -0
- package/.agents/generated/claude/skills/state-management/SKILL.md +120 -0
- package/.agents/generated/claude/skills/subagent-orchestrator/SKILL.md +93 -0
- package/.agents/generated/claude/skills/system-design/SKILL.md +507 -0
- package/.agents/generated/claude/skills/testing/SKILL.md +157 -0
- package/.agents/generated/claude/skills/typescript/SKILL.md +192 -0
- package/.agents/generated/claude/skills/ui-design/SKILL.md +161 -0
- package/.agents/generated/claude/skills/ui-ux-pro/SKILL.md +451 -0
- package/.agents/generated/claude/skills/ux-design/SKILL.md +168 -0
- package/.agents/generated/claude/skills/vercel-optimize/SKILL.md +76 -0
- package/.agents/generated/claude/skills/web-accessibility/SKILL.md +225 -0
- package/.agents/generated/gemini/skills/adapters/SKILL.md +135 -0
- package/.agents/generated/gemini/skills/architecture-diagrams/SKILL.md +107 -0
- package/.agents/generated/gemini/skills/brutalist-design/SKILL.md +151 -0
- package/.agents/generated/gemini/skills/context-manager/SKILL.md +156 -0
- package/.agents/generated/gemini/skills/context-os/SKILL.md +200 -0
- package/.agents/generated/gemini/skills/database/SKILL.md +200 -0
- package/.agents/generated/gemini/skills/ddd/SKILL.md +314 -0
- package/.agents/generated/gemini/skills/decisions/SKILL.md +143 -0
- package/.agents/generated/gemini/skills/docker/SKILL.md +144 -0
- package/.agents/generated/gemini/skills/engineering-workflow/SKILL.md +423 -0
- package/.agents/generated/gemini/skills/fastapi/SKILL.md +209 -0
- package/.agents/generated/gemini/skills/gemini-precision/SKILL.md +167 -0
- package/.agents/generated/gemini/skills/generators/SKILL.md +142 -0
- package/.agents/generated/gemini/skills/graphify/SKILL.md +205 -0
- package/.agents/generated/gemini/skills/gstack-roles/SKILL.md +193 -0
- package/.agents/generated/gemini/skills/impeccable-design/SKILL.md +250 -0
- package/.agents/generated/gemini/skills/interview-me/SKILL.md +96 -0
- package/.agents/generated/gemini/skills/microservices/SKILL.md +227 -0
- package/.agents/generated/gemini/skills/minimalist-design/SKILL.md +114 -0
- package/.agents/generated/gemini/skills/nestjs/SKILL.md +204 -0
- package/.agents/generated/gemini/skills/nextjs/SKILL.md +298 -0
- package/.agents/generated/gemini/skills/node/SKILL.md +323 -0
- package/.agents/generated/gemini/skills/performance/SKILL.md +185 -0
- package/.agents/generated/gemini/skills/ponytail-mindset/SKILL.md +261 -0
- package/.agents/generated/gemini/skills/react/SKILL.md +332 -0
- package/.agents/generated/gemini/skills/react-best-practices/SKILL.md +152 -0
- package/.agents/generated/gemini/skills/redesign-audit/SKILL.md +118 -0
- package/.agents/generated/gemini/skills/security/SKILL.md +355 -0
- package/.agents/generated/gemini/skills/soft-design/SKILL.md +109 -0
- package/.agents/generated/gemini/skills/state-management/SKILL.md +129 -0
- package/.agents/generated/gemini/skills/subagent-orchestrator/SKILL.md +99 -0
- package/.agents/generated/gemini/skills/system-design/SKILL.md +631 -0
- package/.agents/generated/gemini/skills/testing/SKILL.md +166 -0
- package/.agents/generated/gemini/skills/typescript/SKILL.md +275 -0
- package/.agents/generated/gemini/skills/ui-design/SKILL.md +170 -0
- package/.agents/generated/gemini/skills/ui-ux-pro/SKILL.md +460 -0
- package/.agents/generated/gemini/skills/ux-design/SKILL.md +177 -0
- package/.agents/generated/gemini/skills/vercel-optimize/SKILL.md +82 -0
- package/.agents/generated/gemini/skills/web-accessibility/SKILL.md +300 -0
- package/.agents/mcp/runtime.py +454 -0
- package/.agents/mcp/server.mjs +189373 -0
- package/.agents/plugins.js +574 -0
- package/.agents/profiles.js +267 -0
- package/.agents/resolver.js +336 -0
- package/.agents/skills-index.json +200 -0
- package/.agents/skills.json +6 -0
- package/.agents/validate.js +500 -0
- package/LICENSE +21 -0
- package/README.md +415 -0
- package/benchmarks/gemini-issues.js +533 -0
- package/bin/index.js +458 -0
- package/package.json +70 -0
- package/registry.json +53 -0
- package/registry.schema.json +32 -0
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ponytail-mindset
|
|
3
|
+
description: >
|
|
4
|
+
Minimalist coding mindset. Write only what is strictly necessary for the task.
|
|
5
|
+
7-rung decision ladder before writing any code. Eliminates premature abstraction
|
|
6
|
+
while keeping all safety, validation, error handling, and security guards intact.
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# ponytail-mindset
|
|
10
|
+
|
|
11
|
+
## Overview
|
|
12
|
+
|
|
13
|
+
Minimalist engineering discipline that eliminates over-engineering and premature abstraction while maintaining 100% of required validation, type safety, error boundaries, and security invariants.
|
|
14
|
+
|
|
15
|
+
## When to Use
|
|
16
|
+
|
|
17
|
+
Activate on all BUILD phases to prevent bloated implementations and enforce concise, focused solutions.
|
|
18
|
+
|
|
19
|
+
## Rules & Patterns
|
|
20
|
+
|
|
21
|
+
Based on [DietrichGebert/ponytail](https://github.com/DietrichGebert/ponytail).
|
|
22
|
+
|
|
23
|
+
> _He says nothing. He writes one line. It works._
|
|
24
|
+
|
|
25
|
+
**Core Impact**: Dramatically reduces code footprint by eliminating premature abstraction, YAGNI violations, and boilerplate, while keeping all safety invariants (validation, error handling, security) 100% intact.
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
### Core Principle
|
|
30
|
+
|
|
31
|
+
> **The best code is code you don't write.**
|
|
32
|
+
> Write only what the task strictly needs. Lazy about the solution, never about reading and understanding.
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
### The 7-Rung Decision Ladder
|
|
37
|
+
|
|
38
|
+
**Before writing ANY code**, stop and check each rung in order. Stop at the first rung that holds:
|
|
39
|
+
|
|
40
|
+
```text
|
|
41
|
+
1. Does this need to exist?
|
|
42
|
+
→ No: YAGNI — skip it entirely. Don't build for "future use."
|
|
43
|
+
|
|
44
|
+
2. Already in this codebase or component library?
|
|
45
|
+
→ Yes: Reuse it. Don't rewrite. Call the existing function/component/module.
|
|
46
|
+
→ For UI: Check shadcn/ui FIRST. Before building a complex UI element from scratch, check if it exists in the component library. If yes, generate the install command: npx shadcn@latest add dialog — never manually rewrite what shadcn already provides.
|
|
47
|
+
|
|
48
|
+
3. Standard library does it?
|
|
49
|
+
→ Yes: Use it. Don't write formatDate() — use Intl.DateTimeFormat or dayjs.
|
|
50
|
+
|
|
51
|
+
4. Native platform feature?
|
|
52
|
+
→ Yes: Use it. Don't install flatpickr when <input type="date"> exists.
|
|
53
|
+
→ Exception for UI Components: If a native HTML element (like <input type="date"> or <select>) CANNOT be styled consistently across Chrome, Safari, and Firefox to match the premium design system — use the established component library (e.g., shadcn/ui <DatePicker>, <Select>) instead. Cross-browser inconsistency is a legitimate reason to NOT use native.
|
|
54
|
+
|
|
55
|
+
5. Already-installed dependency?
|
|
56
|
+
→ Yes: Use it. Don't install a new library to do what an existing one can.
|
|
57
|
+
|
|
58
|
+
6. Can it be done in one line?
|
|
59
|
+
→ Yes: One line. No abstraction layer needed.
|
|
60
|
+
|
|
61
|
+
7. Only then: write the MINIMUM that works.
|
|
62
|
+
→ No classes when a function works. No module when an inline does.
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
### The Rule of Three (Do Not Abstract Early)
|
|
68
|
+
|
|
69
|
+
- **First occurrence**: Write it inline directly where it is needed.
|
|
70
|
+
- **Second occurrence**: Duplicate it cleanly. Duplication is cheaper than the wrong abstraction.
|
|
71
|
+
- **Third occurrence**: Only now extract a shared helper or utility.
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
### 10 Concrete Over-Engineering Red Flags
|
|
76
|
+
|
|
77
|
+
1. Creating a `GenericRepository<T>` when you only have 2 database tables.
|
|
78
|
+
2. Creating a custom state machine or complex reducer for 2 boolean flags.
|
|
79
|
+
3. Adding a configuration file or environment variables for values that never change.
|
|
80
|
+
4. Writing custom retry/circuit-breaker logic when native `fetch` or SDK already handles it.
|
|
81
|
+
5. Building a generic `BaseService` with 15 hook methods implemented by only one class.
|
|
82
|
+
6. Wrapping every standard library call in a custom helper class (`StringUtils`, `DateUtils`, `ObjectUtils`).
|
|
83
|
+
7. Creating a multi-level folder structure (`domains/auth/adapters/driving/rest/controllers/dto/`) for a 30-line microservice.
|
|
84
|
+
8. Writing custom mock frameworks when Vitest/Jest/Node test runner provide standard mocks.
|
|
85
|
+
9. Installing a 50KB npm package for a 3-line utility (e.g. `left-pad`, `is-number`, `deep-clone`).
|
|
86
|
+
10. Pre-optimizing caching and indexing for endpoints serving 10 requests a day.
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
### The Sacred Exceptions (NEVER Cut These)
|
|
91
|
+
|
|
92
|
+
The ladder applies to features and abstractions. These 4 areas are **non-negotiable** and **never simplified away**:
|
|
93
|
+
|
|
94
|
+
#### 1. Input Validation
|
|
95
|
+
|
|
96
|
+
```javascript
|
|
97
|
+
// [GOOD] Always validate — even if "internal" API
|
|
98
|
+
function createUser(data) {
|
|
99
|
+
if (!data.email || !isValidEmail(data.email)) {
|
|
100
|
+
throw new ValidationError('Invalid email');
|
|
101
|
+
}
|
|
102
|
+
return db.insert('users', data);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// [BAD] Never skip validation for "speed"
|
|
106
|
+
function createUser(data) {
|
|
107
|
+
return db.insert('users', data); // NEVER
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
#### 2. Error Handling
|
|
112
|
+
|
|
113
|
+
```javascript
|
|
114
|
+
// [GOOD] Always handle errors explicitly
|
|
115
|
+
async function fetchUser(id) {
|
|
116
|
+
try {
|
|
117
|
+
const user = await db.findById(id);
|
|
118
|
+
if (!user) throw new NotFoundError(`User ${id} not found`);
|
|
119
|
+
return user;
|
|
120
|
+
} catch (err) {
|
|
121
|
+
logger.error('fetchUser failed', { id, err });
|
|
122
|
+
throw err;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
#### 3. Security Checks
|
|
128
|
+
|
|
129
|
+
- Authorization check BEFORE every query or mutation.
|
|
130
|
+
- Parameterized queries everywhere — zero string concatenation in SQL.
|
|
131
|
+
- Strict sanitization of all rendered HTML and markdown.
|
|
132
|
+
|
|
133
|
+
#### 4. Type Safety & Behavioral Tests
|
|
134
|
+
|
|
135
|
+
- Strict TypeScript types — no `any` evasion.
|
|
136
|
+
- Tests covering happy path, 4xx, and 5xx edge cases.
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## Code Examples
|
|
141
|
+
|
|
142
|
+
### Native Platform vs Over-Built Package
|
|
143
|
+
|
|
144
|
+
**Over-build**:
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
npm install flatpickr
|
|
148
|
+
# Creates DatePickerWrapper.jsx (45 lines) + useDatePicker.js (30 lines) + styles (60 lines)
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
**Ponytail approach (rung 4)**:
|
|
152
|
+
|
|
153
|
+
```html
|
|
154
|
+
<input type="date" name="date" aria-label="Appointment date" />
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Next.js App Router Server Action vs REST Endpoint
|
|
158
|
+
|
|
159
|
+
```typescript
|
|
160
|
+
// Instead of /api/users/[id]/route.ts + custom fetch wrapper:
|
|
161
|
+
"use server";
|
|
162
|
+
|
|
163
|
+
export async function updateUser(id: string, data: UpdateUserInput) {
|
|
164
|
+
const session = await getSession(); // auth check — never skip
|
|
165
|
+
if (session?.userId !== id) throw new Error("Forbidden");
|
|
166
|
+
return db.users.update(id, data);
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## Validation Checklist
|
|
173
|
+
|
|
174
|
+
- [ ] Every new dependency has been verified: cannot be solved with native platform or existing dependencies.
|
|
175
|
+
- [ ] No single-use abstractions, wrappers, or interfaces created.
|
|
176
|
+
- [ ] Sacred exceptions preserved: 100% input validation, explicit error handling, security checks intact.
|
|
177
|
+
- [ ] All code written passes all existing unit and integration tests.
|
|
178
|
+
|
|
179
|
+
---
|
|
180
|
+
|
|
181
|
+
## Common Mistakes
|
|
182
|
+
|
|
183
|
+
- **Cutting validation to write less code**: The goal is less architecture/boilerplate, never less safety.
|
|
184
|
+
- **Creating utilities "for future use"**: Only write utilities when used 3+ times.
|
|
185
|
+
- **Rewriting component libraries**: Building custom modals, tabs, or tooltips from scratch when shadcn/ui or Radix is already in the project.
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
## Integration Notes
|
|
190
|
+
|
|
191
|
+
- Runs at the start of every `[PHASE: Build]` and `[PHASE: Review]`.
|
|
192
|
+
- Enforces minimalism alongside `system-design` (think at scale, implement minimally).
|
|
193
|
+
- Pairs with `impeccable-design` for UI tasks.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# ponytail-mindset Troubleshooting & Common Mistakes
|
|
2
|
+
|
|
3
|
+
## 1. Conflating Minimalism with Cutting Safety Guards
|
|
4
|
+
|
|
5
|
+
- **Symptom**: Agent removes input validation, error handling, or security checks in the name of "less code".
|
|
6
|
+
- **Root Cause**: Misunderstanding the Ponytail principle. Ponytail cuts unnecessary abstractions, never safety invariants.
|
|
7
|
+
- **Fix**: Invariant: Always retain 100% of input sanitization, error boundaries, and type safety checks.
|
|
8
|
+
|
|
9
|
+
## 2. "Just In Case" Speculative Coding (YAGNI Violation)
|
|
10
|
+
|
|
11
|
+
- **Symptom**: Adding config options, generics, and plugin interfaces for features not requested.
|
|
12
|
+
- **Root Cause**: Premature future-proofing.
|
|
13
|
+
- **Fix**: Apply Rung 1 of the ladder: If it doesn't solve the immediate requirement, do not write it.
|
|
14
|
+
|
|
15
|
+
## 3. Reinventing Installed Dependencies
|
|
16
|
+
|
|
17
|
+
- **Symptom**: Writing a deep-clone helper when Lodash or native structuredClone is available.
|
|
18
|
+
- **Root Cause**: Skipping inspection of package.json and runtime environment.
|
|
19
|
+
- **Fix**: Inspect installed dependencies before writing utility functions.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
name: ponytail-mindset
|
|
2
|
+
description: >
|
|
3
|
+
Minimalist coding mindset based on DietrichGebert/ponytail.
|
|
4
|
+
Teaches the AI to write only what is strictly necessary.
|
|
5
|
+
Uses a 7-rung ladder: YAGNI → reuse → stdlib → platform → deps → one-liner → minimum.
|
|
6
|
+
Minimizes unnecessary boilerplate and over-engineering while keeping all safety, validation and security guards.
|
|
7
|
+
tags:
|
|
8
|
+
- minimalism
|
|
9
|
+
- efficiency
|
|
10
|
+
- quality
|
|
11
|
+
- yagni
|
|
12
|
+
- refactoring
|
|
13
|
+
version: 1.0.0
|
|
14
|
+
source: https://github.com/DietrichGebert/ponytail
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# React Examples — Anti-patterns vs ContextOS Standard
|
|
2
|
+
|
|
3
|
+
## Example 1: Derived State vs. useEffect
|
|
4
|
+
|
|
5
|
+
### Anti-pattern: Anti-pattern (Redundant state + extra render with useEffect)
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
// BAD: causes an unnecessary extra render cycle and potential state desync
|
|
9
|
+
function OrderSummary({ items }: { items: CartItem[] }) {
|
|
10
|
+
const [total, setTotal] = useState(0);
|
|
11
|
+
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
const calculated = items.reduce((sum, item) => sum + item.price * item.quantity, 0);
|
|
14
|
+
setTotal(calculated);
|
|
15
|
+
}, [items]);
|
|
16
|
+
|
|
17
|
+
return <div>Total: ${total}</div>;
|
|
18
|
+
}
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### Best practice: ContextOS Standard (Inline derived calculation / useMemo)
|
|
22
|
+
|
|
23
|
+
```tsx
|
|
24
|
+
// GOOD: calculated instantly during render with zero extra render pass
|
|
25
|
+
function OrderSummary({ items }: { items: CartItem[] }) {
|
|
26
|
+
const total = useMemo(
|
|
27
|
+
() => items.reduce((sum, item) => sum + item.price * item.quantity, 0),
|
|
28
|
+
[items]
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
return <div>Total: ${total.toFixed(2)}</div>;
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Example 2: Custom Hook Encapsulation
|
|
38
|
+
|
|
39
|
+
### Anti-pattern: Anti-pattern (Scattered listener logic inside component)
|
|
40
|
+
|
|
41
|
+
```tsx
|
|
42
|
+
// BAD: window listener logic cluttering UI component
|
|
43
|
+
function NavHeader() {
|
|
44
|
+
const [isScrolled, setIsScrolled] = useState(false);
|
|
45
|
+
useEffect(() => {
|
|
46
|
+
const handleScroll = () => setIsScrolled(window.scrollY > 50);
|
|
47
|
+
window.addEventListener('scroll', handleScroll);
|
|
48
|
+
return () => window.removeEventListener('scroll', handleScroll);
|
|
49
|
+
}, []);
|
|
50
|
+
return <header className={isScrolled ? 'scrolled' : ''}>Header</header>;
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Best practice: ContextOS Standard (Reusable Custom Hook)
|
|
55
|
+
|
|
56
|
+
```tsx
|
|
57
|
+
// GOOD: extracted into a reusable, testable custom hook
|
|
58
|
+
export function useScrollThreshold(threshold = 50): boolean {
|
|
59
|
+
const [isPassed, setIsPassed] = useState(() => typeof window !== 'undefined' && window.scrollY > threshold);
|
|
60
|
+
|
|
61
|
+
useEffect(() => {
|
|
62
|
+
let ticking = false;
|
|
63
|
+
const handleScroll = () => {
|
|
64
|
+
if (!ticking) {
|
|
65
|
+
window.requestAnimationFrame(() => {
|
|
66
|
+
setIsPassed(window.scrollY > threshold);
|
|
67
|
+
ticking = false;
|
|
68
|
+
});
|
|
69
|
+
ticking = true;
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
window.addEventListener('scroll', handleScroll, { passive: true });
|
|
74
|
+
return () => window.removeEventListener('scroll', handleScroll);
|
|
75
|
+
}, [threshold]);
|
|
76
|
+
|
|
77
|
+
return isPassed;
|
|
78
|
+
}
|
|
79
|
+
```
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: React
|
|
3
|
+
description: >
|
|
4
|
+
ContextOS skill for modern React (v18/v19), component architecture, state colocation, render optimization, and Vercel performance rules.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# React Engineering & Performance Best Practices
|
|
8
|
+
|
|
9
|
+
## Overview
|
|
10
|
+
|
|
11
|
+
Enforces declarative, component-driven UI architecture with optimal re-render cycles, state colocation, responsive optimistic updates, and robust accessibility standards.
|
|
12
|
+
|
|
13
|
+
## When to Use
|
|
14
|
+
|
|
15
|
+
Activate whenever creating, refactoring, or optimizing React functional components, custom hooks, context providers, or UI interaction states.
|
|
16
|
+
|
|
17
|
+
## Negative Constraints (What NOT to Do)
|
|
18
|
+
|
|
19
|
+
1. **NEVER use `useEffect` to synchronize or compute derived state**: Calculate derived state inline during render. Use `useMemo` only for computationally intensive derivations.
|
|
20
|
+
2. **NEVER use array indices as `key` props on dynamic or reorderable lists**: Always use stable, unique entity identifiers (`item.id`).
|
|
21
|
+
3. **NEVER mutate React state directly**: Always return new immutable references (`[...prev, newItem]` or `{ ...prev, key: value }`).
|
|
22
|
+
4. **NEVER declare subcomponents inside the render body of parent components**: Declare components at module scope or in dedicated files to prevent DOM node remounting and lost focus state.
|
|
23
|
+
5. **NEVER create memory leaks in `useEffect`**: Always provide clean-up functions for event listeners, `AbortController`, timers, and websocket subscriptions.
|
|
24
|
+
6. **NEVER lift state higher than necessary**: Colocate state to the nearest common ancestor or leaf component to prevent wasteful re-renders of unrelated subtrees.
|
|
25
|
+
|
|
26
|
+
## Rules & Patterns
|
|
27
|
+
|
|
28
|
+
### 1. State Colocation & Re-render Optimization
|
|
29
|
+
|
|
30
|
+
- **State Colocation**: Keep state as close as possible to the components that consume it.
|
|
31
|
+
- **Composition to Prevent Re-renders**: Pass expensive static subtrees as `children` to wrapper components holding state so the children do not re-render when the wrapper updates.
|
|
32
|
+
|
|
33
|
+
```tsx
|
|
34
|
+
export function ExpandableCard({ title, children }: { title: string; children: React.ReactNode }) {
|
|
35
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
36
|
+
|
|
37
|
+
return (
|
|
38
|
+
<div className="rounded-xl border p-4">
|
|
39
|
+
<button
|
|
40
|
+
type="button"
|
|
41
|
+
onClick={() => setIsOpen(v => !v)}
|
|
42
|
+
className="flex w-full justify-between font-semibold"
|
|
43
|
+
aria-expanded={isOpen}
|
|
44
|
+
>
|
|
45
|
+
<span>{title}</span>
|
|
46
|
+
<span>{isOpen ? '−' : '+'}</span>
|
|
47
|
+
</button>
|
|
48
|
+
{isOpen && <div className="mt-3 pt-3 border-t">{children}</div>}
|
|
49
|
+
</div>
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### 2. Optimistic UI Updates & Concurrent Actions (`useOptimistic`, `useTransition`)
|
|
55
|
+
|
|
56
|
+
- Provide instantaneous visual feedback for user actions without waiting for server network roundtrips.
|
|
57
|
+
|
|
58
|
+
```tsx
|
|
59
|
+
import { useOptimistic, useTransition } from 'react';
|
|
60
|
+
|
|
61
|
+
export function TodoList({ todos, onAdd }: { todos: Todo[]; onAdd: (text: string) => Promise<void> }) {
|
|
62
|
+
const [isPending, startTransition] = useTransition();
|
|
63
|
+
const [optimisticTodos, addOptimisticTodo] = useOptimistic(
|
|
64
|
+
todos,
|
|
65
|
+
(state, newText: string) => [...state, { id: 'temp-' + Date.now(), text: newText, isPending: true }]
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
const handleAction = async (formData: FormData) => {
|
|
69
|
+
const text = formData.get('todo') as string;
|
|
70
|
+
if (!text?.trim()) return;
|
|
71
|
+
|
|
72
|
+
startTransition(async () => {
|
|
73
|
+
addOptimisticTodo(text);
|
|
74
|
+
await onAdd(text);
|
|
75
|
+
});
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
return (
|
|
79
|
+
<form action={handleAction} className="space-y-4">
|
|
80
|
+
<input name="todo" placeholder="Add a new task..." className="border p-2 rounded" />
|
|
81
|
+
<button type="submit" disabled={isPending} className="bg-primary text-white px-4 py-2 rounded">
|
|
82
|
+
{isPending ? 'Saving...' : 'Add'}
|
|
83
|
+
</button>
|
|
84
|
+
<ul className="divide-y">
|
|
85
|
+
{optimisticTodos.map(todo => (
|
|
86
|
+
<li key={todo.id} className={todo.isPending ? 'opacity-50 italic' : ''}>
|
|
87
|
+
{todo.text}
|
|
88
|
+
</li>
|
|
89
|
+
))}
|
|
90
|
+
</ul>
|
|
91
|
+
</form>
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### 3. Derived State vs. Effects Anti-Pattern
|
|
97
|
+
|
|
98
|
+
```tsx
|
|
99
|
+
// [GOOD] Computed directly during render (or memoized if expensive)
|
|
100
|
+
function SearchResults({ query, items }: { query: string; items: Item[] }) {
|
|
101
|
+
const filtered = useMemo(() => {
|
|
102
|
+
const q = query.trim().toLowerCase();
|
|
103
|
+
if (!q) return items;
|
|
104
|
+
return items.filter(i => i.title.toLowerCase().includes(q));
|
|
105
|
+
}, [query, items]);
|
|
106
|
+
|
|
107
|
+
return <List items={filtered} />;
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Code Examples
|
|
112
|
+
|
|
113
|
+
See `EXAMPLES.md` for detailed code examples and hook implementations.
|
|
114
|
+
|
|
115
|
+
## Validation Checklist
|
|
116
|
+
|
|
117
|
+
- [ ] Zero `useEffect` hooks used for derived calculations.
|
|
118
|
+
- [ ] Every list mapping has a unique, non-index entity ID key.
|
|
119
|
+
- [ ] Subcomponents declared in parent render functions are extracted to top-level scope.
|
|
120
|
+
- [ ] Effects with event listeners, timers, or abortable requests include clean-up returns.
|
|
121
|
+
- [ ] Reusable components are composed cleanly via `children` or render props.
|
|
122
|
+
|
|
123
|
+
## Common Mistakes
|
|
124
|
+
|
|
125
|
+
- Setting state inside `useEffect` based on prop changes rather than deriving values inline.
|
|
126
|
+
- Declaring nested components within component bodies.
|
|
127
|
+
- Using index keys causing input focus loss or animations breaking on list mutations.
|
|
128
|
+
|
|
129
|
+
## Integration Notes
|
|
130
|
+
|
|
131
|
+
- Pairs with `typescript` for type safety on props, generics, and ref forwarding.
|
|
132
|
+
- Pairs with `ui-ux-pro` and `web-accessibility` for UI tokens and ARIA standards.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# react Troubleshooting & Common Mistakes
|
|
2
|
+
|
|
3
|
+
## 1. Infinite Render Loops in useEffect
|
|
4
|
+
|
|
5
|
+
- **Symptom**: Browser freezes, "Maximum update depth exceeded" error.
|
|
6
|
+
- **Root Cause**: Creating new object or array literals inside component body and passing them to useEffect dependency array.
|
|
7
|
+
- **Fix**: Colocate state, compute derived state during render without useEffect, or use primitive dependency values.
|
|
8
|
+
|
|
9
|
+
## 2. Stale Closures in Callbacks
|
|
10
|
+
|
|
11
|
+
- **Symptom**: Event handler or setTimeout accesses outdated state values.
|
|
12
|
+
- **Root Cause**: Callback closing over initial state without updated dependency.
|
|
13
|
+
- **Fix**: Use functional state updates (`setCount(c => c + 1)`) or `useRef` for mutable references.
|
|
14
|
+
|
|
15
|
+
## 3. Prop Drilling vs Context Performance
|
|
16
|
+
|
|
17
|
+
- **Symptom**: Changing a small state variable causes the entire component tree to re-render.
|
|
18
|
+
- **Root Cause**: Storing rapidly changing state in a single monolithic React Context.
|
|
19
|
+
- **Fix**: Split contexts by domain or migrate client UI state to Zustand with granular selectors.
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# React — Best Practices
|
|
2
|
+
|
|
3
|
+
## Component Architecture
|
|
4
|
+
|
|
5
|
+
- **Prefer function components** with hooks over class components
|
|
6
|
+
- **One component per file** — name file same as component
|
|
7
|
+
- **Composition over inheritance** — use children and render props
|
|
8
|
+
- **Keep components small** — if > 150 lines, split it
|
|
9
|
+
|
|
10
|
+
## Hooks
|
|
11
|
+
|
|
12
|
+
- **useState** for local state, **useReducer** for complex state
|
|
13
|
+
- **useEffect** — always specify dependencies, clean up subscriptions
|
|
14
|
+
- **Custom hooks** — extract reusable logic into `use*` functions
|
|
15
|
+
- **useMemo/useCallback** — only when you have measured a performance problem
|
|
16
|
+
|
|
17
|
+
## State Management
|
|
18
|
+
|
|
19
|
+
- **Local state first** — don't reach for global state until you need it
|
|
20
|
+
- **Lift state up** — find the closest common ancestor
|
|
21
|
+
- **Context** — for cross-cutting concerns (theme, auth, locale)
|
|
22
|
+
- **External store** (Zustand, Jotai) — for truly global, frequently updated state
|
|
23
|
+
|
|
24
|
+
## Patterns
|
|
25
|
+
|
|
26
|
+
### Container/Presenter
|
|
27
|
+
|
|
28
|
+
```tsx
|
|
29
|
+
// Container — handles logic
|
|
30
|
+
function UserListContainer() {
|
|
31
|
+
const users = useUsers();
|
|
32
|
+
return <UserList users={users} />;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Presenter — handles display
|
|
36
|
+
function UserList({ users }: { users: User[] }) {
|
|
37
|
+
return <ul>{users.map(u => <UserItem key={u.id} user={u} />)}</ul>;
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Error Boundaries
|
|
42
|
+
|
|
43
|
+
- Wrap major sections in Error Boundaries
|
|
44
|
+
- Provide meaningful fallback UI
|
|
45
|
+
- Log errors to monitoring service
|
|
46
|
+
|
|
47
|
+
### Loading States
|
|
48
|
+
|
|
49
|
+
- Always handle: `loading`, `error`, `empty`, `data` states
|
|
50
|
+
- Use Suspense where supported
|
|
51
|
+
- Show skeleton screens, not spinners
|
|
52
|
+
|
|
53
|
+
## Performance
|
|
54
|
+
|
|
55
|
+
- **React.memo** — only for expensive renders with stable props
|
|
56
|
+
- **Code splitting** — lazy load routes and heavy components
|
|
57
|
+
- **Virtualization** — for lists > 100 items
|
|
58
|
+
- **Image optimization** — use next/image or lazy loading
|
|
59
|
+
- **Avoid** — inline object/array creation in JSX props
|
|
60
|
+
|
|
61
|
+
## Anti-Patterns (Avoid)
|
|
62
|
+
|
|
63
|
+
- [FAIL] Props drilling more than 2 levels — use Context or state management
|
|
64
|
+
- [FAIL] useEffect for derived state — use useMemo instead
|
|
65
|
+
- [FAIL] Index as key — use stable unique IDs
|
|
66
|
+
- [FAIL] Mutating state directly — always create new references
|
|
67
|
+
- [FAIL] God components — split into smaller, focused components
|
|
68
|
+
- [FAIL] Business logic in components — extract to hooks or services
|
|
69
|
+
|
|
70
|
+
## Testing
|
|
71
|
+
|
|
72
|
+
- **React Testing Library** — test behavior, not implementation
|
|
73
|
+
- Test user interactions, not component internals
|
|
74
|
+
- Mock API calls, not React hooks
|
|
75
|
+
- Use `screen.getByRole` over `getByTestId`
|
|
76
|
+
|
|
77
|
+
## File Structure
|
|
78
|
+
|
|
79
|
+
```
|
|
80
|
+
components/
|
|
81
|
+
Button/
|
|
82
|
+
Button.tsx
|
|
83
|
+
Button.test.tsx
|
|
84
|
+
Button.module.css
|
|
85
|
+
index.ts
|
|
86
|
+
hooks/
|
|
87
|
+
useAuth.ts
|
|
88
|
+
useDebounce.ts
|
|
89
|
+
services/
|
|
90
|
+
api.ts
|
|
91
|
+
types/
|
|
92
|
+
user.ts
|
|
93
|
+
```
|