codehava-agent-kit 1.0.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/README.md +56 -0
- package/bin/cli.js +56 -0
- package/package.json +26 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/charts.csv +26 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/colors.csv +97 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/icons.csv +101 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/landing.csv +31 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/products.csv +97 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/prompts.csv +24 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/react-performance.csv +45 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/stacks/react.csv +54 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/stacks/vue.csv +50 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/styles.csv +59 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/typography.csv +58 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/ui-reasoning.csv +101 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/web-interface.csv +31 -0
- package/templates/.agent/.shared/ui-ux-pro-max/scripts/__pycache__/core.cpython-313.pyc +0 -0
- package/templates/.agent/.shared/ui-ux-pro-max/scripts/__pycache__/design_system.cpython-313.pyc +0 -0
- package/templates/.agent/.shared/ui-ux-pro-max/scripts/core.py +258 -0
- package/templates/.agent/.shared/ui-ux-pro-max/scripts/design_system.py +1067 -0
- package/templates/.agent/.shared/ui-ux-pro-max/scripts/search.py +106 -0
- package/templates/.agent/agents/backend-specialist.md +263 -0
- package/templates/.agent/agents/code-archaeologist.md +106 -0
- package/templates/.agent/agents/database-architect.md +226 -0
- package/templates/.agent/agents/debugger.md +225 -0
- package/templates/.agent/agents/devops-engineer.md +242 -0
- package/templates/.agent/agents/documentation-writer.md +104 -0
- package/templates/.agent/agents/explorer-agent.md +73 -0
- package/templates/.agent/agents/frontend-specialist.md +593 -0
- package/templates/.agent/agents/game-developer.md +162 -0
- package/templates/.agent/agents/mobile-developer.md +377 -0
- package/templates/.agent/agents/orchestrator.md +416 -0
- package/templates/.agent/agents/penetration-tester.md +188 -0
- package/templates/.agent/agents/performance-optimizer.md +187 -0
- package/templates/.agent/agents/product-manager.md +112 -0
- package/templates/.agent/agents/product-owner.md +95 -0
- package/templates/.agent/agents/project-planner.md +406 -0
- package/templates/.agent/agents/qa-automation-engineer.md +103 -0
- package/templates/.agent/agents/security-auditor.md +170 -0
- package/templates/.agent/agents/seo-specialist.md +111 -0
- package/templates/.agent/agents/test-engineer.md +158 -0
- package/templates/.agent/mcp_config.json +129 -0
- package/templates/.agent/rules/GEMINI.md +273 -0
- package/templates/.agent/scripts/auto_preview.py +148 -0
- package/templates/.agent/scripts/checklist.py +217 -0
- package/templates/.agent/scripts/session_manager.py +120 -0
- package/templates/.agent/scripts/verify_all.py +327 -0
- package/templates/.agent/skills/api-patterns/SKILL.md +81 -0
- package/templates/.agent/skills/api-patterns/api-style.md +42 -0
- package/templates/.agent/skills/api-patterns/auth.md +24 -0
- package/templates/.agent/skills/api-patterns/documentation.md +26 -0
- package/templates/.agent/skills/api-patterns/graphql.md +41 -0
- package/templates/.agent/skills/api-patterns/rate-limiting.md +31 -0
- package/templates/.agent/skills/api-patterns/response.md +37 -0
- package/templates/.agent/skills/api-patterns/rest.md +40 -0
- package/templates/.agent/skills/api-patterns/scripts/api_validator.py +211 -0
- package/templates/.agent/skills/api-patterns/security-testing.md +122 -0
- package/templates/.agent/skills/api-patterns/trpc.md +41 -0
- package/templates/.agent/skills/api-patterns/versioning.md +22 -0
- package/templates/.agent/skills/app-builder/SKILL.md +75 -0
- package/templates/.agent/skills/app-builder/agent-coordination.md +71 -0
- package/templates/.agent/skills/app-builder/feature-building.md +53 -0
- package/templates/.agent/skills/app-builder/project-detection.md +34 -0
- package/templates/.agent/skills/app-builder/scaffolding.md +118 -0
- package/templates/.agent/skills/app-builder/tech-stack.md +41 -0
- package/templates/.agent/skills/app-builder/templates/SKILL.md +39 -0
- package/templates/.agent/skills/app-builder/templates/astro-static/TEMPLATE.md +76 -0
- package/templates/.agent/skills/app-builder/templates/chrome-extension/TEMPLATE.md +92 -0
- package/templates/.agent/skills/app-builder/templates/cli-tool/TEMPLATE.md +88 -0
- package/templates/.agent/skills/app-builder/templates/electron-desktop/TEMPLATE.md +88 -0
- package/templates/.agent/skills/app-builder/templates/express-api/TEMPLATE.md +83 -0
- package/templates/.agent/skills/app-builder/templates/flutter-app/TEMPLATE.md +90 -0
- package/templates/.agent/skills/app-builder/templates/monorepo-turborepo/TEMPLATE.md +90 -0
- package/templates/.agent/skills/app-builder/templates/nextjs-fullstack/TEMPLATE.md +122 -0
- package/templates/.agent/skills/app-builder/templates/nextjs-saas/TEMPLATE.md +122 -0
- package/templates/.agent/skills/app-builder/templates/nextjs-static/TEMPLATE.md +169 -0
- package/templates/.agent/skills/app-builder/templates/nuxt-app/TEMPLATE.md +134 -0
- package/templates/.agent/skills/app-builder/templates/python-fastapi/TEMPLATE.md +83 -0
- package/templates/.agent/skills/app-builder/templates/react-native-app/TEMPLATE.md +119 -0
- package/templates/.agent/skills/architecture/SKILL.md +55 -0
- package/templates/.agent/skills/architecture/context-discovery.md +43 -0
- package/templates/.agent/skills/architecture/examples.md +94 -0
- package/templates/.agent/skills/architecture/pattern-selection.md +68 -0
- package/templates/.agent/skills/architecture/patterns-reference.md +50 -0
- package/templates/.agent/skills/architecture/trade-off-analysis.md +77 -0
- package/templates/.agent/skills/bash-linux/SKILL.md +199 -0
- package/templates/.agent/skills/behavioral-modes/SKILL.md +242 -0
- package/templates/.agent/skills/better-auth-patterns/SKILL.md +121 -0
- package/templates/.agent/skills/brainstorming/SKILL.md +163 -0
- package/templates/.agent/skills/brainstorming/dynamic-questioning.md +350 -0
- package/templates/.agent/skills/bullmq-worker/SKILL.md +124 -0
- package/templates/.agent/skills/clean-code/SKILL.md +201 -0
- package/templates/.agent/skills/code-review-checklist/SKILL.md +109 -0
- package/templates/.agent/skills/database-design/SKILL.md +52 -0
- package/templates/.agent/skills/database-design/database-selection.md +43 -0
- package/templates/.agent/skills/database-design/indexing.md +39 -0
- package/templates/.agent/skills/database-design/migrations.md +48 -0
- package/templates/.agent/skills/database-design/optimization.md +36 -0
- package/templates/.agent/skills/database-design/orm-selection.md +30 -0
- package/templates/.agent/skills/database-design/schema-design.md +56 -0
- package/templates/.agent/skills/database-design/scripts/schema_validator.py +172 -0
- package/templates/.agent/skills/deployment-procedures/SKILL.md +241 -0
- package/templates/.agent/skills/doc.md +177 -0
- package/templates/.agent/skills/documentation-templates/SKILL.md +194 -0
- package/templates/.agent/skills/feature-spec-writer/SKILL.md +76 -0
- package/templates/.agent/skills/frontend-design/SKILL.md +452 -0
- package/templates/.agent/skills/frontend-design/animation-guide.md +331 -0
- package/templates/.agent/skills/frontend-design/color-system.md +311 -0
- package/templates/.agent/skills/frontend-design/decision-trees.md +418 -0
- package/templates/.agent/skills/frontend-design/motion-graphics.md +306 -0
- package/templates/.agent/skills/frontend-design/scripts/accessibility_checker.py +183 -0
- package/templates/.agent/skills/frontend-design/scripts/ux_audit.py +722 -0
- package/templates/.agent/skills/frontend-design/typography-system.md +345 -0
- package/templates/.agent/skills/frontend-design/ux-psychology.md +1116 -0
- package/templates/.agent/skills/frontend-design/visual-effects.md +383 -0
- package/templates/.agent/skills/game-development/2d-games/SKILL.md +119 -0
- package/templates/.agent/skills/game-development/3d-games/SKILL.md +135 -0
- package/templates/.agent/skills/game-development/SKILL.md +167 -0
- package/templates/.agent/skills/game-development/game-art/SKILL.md +185 -0
- package/templates/.agent/skills/game-development/game-audio/SKILL.md +190 -0
- package/templates/.agent/skills/game-development/game-design/SKILL.md +129 -0
- package/templates/.agent/skills/game-development/mobile-games/SKILL.md +108 -0
- package/templates/.agent/skills/game-development/multiplayer/SKILL.md +132 -0
- package/templates/.agent/skills/game-development/pc-games/SKILL.md +144 -0
- package/templates/.agent/skills/game-development/vr-ar/SKILL.md +123 -0
- package/templates/.agent/skills/game-development/web-games/SKILL.md +150 -0
- package/templates/.agent/skills/geo-fundamentals/SKILL.md +156 -0
- package/templates/.agent/skills/geo-fundamentals/scripts/geo_checker.py +289 -0
- package/templates/.agent/skills/i18n-localization/SKILL.md +154 -0
- package/templates/.agent/skills/i18n-localization/scripts/i18n_checker.py +241 -0
- package/templates/.agent/skills/intelligent-routing/SKILL.md +335 -0
- package/templates/.agent/skills/lint-and-validate/SKILL.md +45 -0
- package/templates/.agent/skills/lint-and-validate/scripts/lint_runner.py +184 -0
- package/templates/.agent/skills/lint-and-validate/scripts/type_coverage.py +173 -0
- package/templates/.agent/skills/mcp-builder/SKILL.md +176 -0
- package/templates/.agent/skills/mobile-design/SKILL.md +394 -0
- package/templates/.agent/skills/mobile-design/decision-trees.md +516 -0
- package/templates/.agent/skills/mobile-design/mobile-backend.md +491 -0
- package/templates/.agent/skills/mobile-design/mobile-color-system.md +420 -0
- package/templates/.agent/skills/mobile-design/mobile-debugging.md +122 -0
- package/templates/.agent/skills/mobile-design/mobile-design-thinking.md +357 -0
- package/templates/.agent/skills/mobile-design/mobile-navigation.md +458 -0
- package/templates/.agent/skills/mobile-design/mobile-performance.md +767 -0
- package/templates/.agent/skills/mobile-design/mobile-testing.md +356 -0
- package/templates/.agent/skills/mobile-design/mobile-typography.md +433 -0
- package/templates/.agent/skills/mobile-design/platform-android.md +666 -0
- package/templates/.agent/skills/mobile-design/platform-ios.md +561 -0
- package/templates/.agent/skills/mobile-design/scripts/mobile_audit.py +670 -0
- package/templates/.agent/skills/mobile-design/touch-psychology.md +537 -0
- package/templates/.agent/skills/neo-storage/SKILL.md +115 -0
- package/templates/.agent/skills/nextjs-api-route/SKILL.md +134 -0
- package/templates/.agent/skills/nextjs-react-expert/1-async-eliminating-waterfalls.md +351 -0
- package/templates/.agent/skills/nextjs-react-expert/2-bundle-bundle-size-optimization.md +240 -0
- package/templates/.agent/skills/nextjs-react-expert/3-server-server-side-performance.md +490 -0
- package/templates/.agent/skills/nextjs-react-expert/4-client-client-side-data-fetching.md +264 -0
- package/templates/.agent/skills/nextjs-react-expert/5-rerender-re-render-optimization.md +581 -0
- package/templates/.agent/skills/nextjs-react-expert/6-rendering-rendering-performance.md +432 -0
- package/templates/.agent/skills/nextjs-react-expert/7-js-javascript-performance.md +684 -0
- package/templates/.agent/skills/nextjs-react-expert/8-advanced-advanced-patterns.md +150 -0
- package/templates/.agent/skills/nextjs-react-expert/9-cache-components.md +103 -0
- package/templates/.agent/skills/nextjs-react-expert/SKILL.md +293 -0
- package/templates/.agent/skills/nextjs-react-expert/scripts/convert_rules.py +222 -0
- package/templates/.agent/skills/nextjs-react-expert/scripts/react_performance_checker.py +252 -0
- package/templates/.agent/skills/nodejs-best-practices/SKILL.md +333 -0
- package/templates/.agent/skills/parallel-agents/SKILL.md +175 -0
- package/templates/.agent/skills/performance-profiling/SKILL.md +143 -0
- package/templates/.agent/skills/performance-profiling/scripts/lighthouse_audit.py +76 -0
- package/templates/.agent/skills/plan-writing/SKILL.md +152 -0
- package/templates/.agent/skills/powershell-windows/SKILL.md +167 -0
- package/templates/.agent/skills/prisma-7-patterns/SKILL.md +91 -0
- package/templates/.agent/skills/python-patterns/SKILL.md +441 -0
- package/templates/.agent/skills/red-team-tactics/SKILL.md +199 -0
- package/templates/.agent/skills/rust-pro/SKILL.md +176 -0
- package/templates/.agent/skills/seo-fundamentals/SKILL.md +129 -0
- package/templates/.agent/skills/seo-fundamentals/scripts/seo_checker.py +219 -0
- package/templates/.agent/skills/server-management/SKILL.md +161 -0
- package/templates/.agent/skills/systematic-debugging/SKILL.md +109 -0
- package/templates/.agent/skills/tailwind-patterns/SKILL.md +269 -0
- package/templates/.agent/skills/tdd-workflow/SKILL.md +149 -0
- package/templates/.agent/skills/testing-patterns/SKILL.md +178 -0
- package/templates/.agent/skills/testing-patterns/scripts/test_runner.py +219 -0
- package/templates/.agent/skills/uu-pdp-feature-check/SKILL.md +116 -0
- package/templates/.agent/skills/vibe-buildplan/SKILL.md +232 -0
- package/templates/.agent/skills/vibe-prd/SKILL.md +226 -0
- package/templates/.agent/skills/vibe-research/SKILL.md +162 -0
- package/templates/.agent/skills/vibe-techdesign/SKILL.md +195 -0
- package/templates/.agent/skills/vulnerability-scanner/SKILL.md +276 -0
- package/templates/.agent/skills/vulnerability-scanner/checklists.md +121 -0
- package/templates/.agent/skills/vulnerability-scanner/scripts/security_scan.py +458 -0
- package/templates/.agent/skills/web-design-guidelines/SKILL.md +57 -0
- package/templates/.agent/skills/webapp-testing/SKILL.md +187 -0
- package/templates/.agent/skills/webapp-testing/scripts/playwright_runner.py +173 -0
- package/templates/.agent/skills/xendit-integration/SKILL.md +100 -0
- package/templates/.agent/snippets/@react-component-template.tsx +29 -0
- package/templates/.agent/workflows/brainstorm.md +113 -0
- package/templates/.agent/workflows/create.md +59 -0
- package/templates/.agent/workflows/db-migrate.md +26 -0
- package/templates/.agent/workflows/debug.md +103 -0
- package/templates/.agent/workflows/deploy.md +35 -0
- package/templates/.agent/workflows/dev-reset.md +40 -0
- package/templates/.agent/workflows/enhance.md +63 -0
- package/templates/.agent/workflows/git-commit.md +24 -0
- package/templates/.agent/workflows/health-check.md +34 -0
- package/templates/.agent/workflows/new-feature.md +32 -0
- package/templates/.agent/workflows/orchestrate.md +237 -0
- package/templates/.agent/workflows/plan.md +89 -0
- package/templates/.agent/workflows/preview.md +81 -0
- package/templates/.agent/workflows/status.md +86 -0
- package/templates/.agent/workflows/test.md +144 -0
- package/templates/.agent/workflows/ui-ux-pro-max.md +296 -0
- package/templates/.agent/workflows/vibe-plan.md +133 -0
- package/templates/.agent/workflows/vibe-recap.md +17 -0
- package/templates/.antigravity/rules.md +64 -0
- package/templates/AGENTS.md +268 -0
- package/templates/docs/00A-PROJECT-CHARTER.md +33 -0
- package/templates/docs/00B-BRD.md +25 -0
- package/templates/docs/01-PRD.md +122 -0
- package/templates/docs/01B-SRS-LENGKAP.md +60 -0
- package/templates/docs/02-TECH-DESIGN.md +491 -0
- package/templates/docs/03-UI-GUIDELINES.md +301 -0
- package/templates/docs/04-BACKLOG.md +127 -0
- package/templates/docs/05-DEPLOYMENT.md +363 -0
- package/templates/docs/06-DEVELOPMENT-LOG.md +78 -0
- package/templates/specs/README.md +54 -0
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Conversion Script: React Best Practices → .agent Format
|
|
4
|
+
Merges 59 individual rules into 8 grouped section files
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import os
|
|
8
|
+
import re
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
from typing import Dict, List, Tuple
|
|
11
|
+
|
|
12
|
+
# Section metadata from _sections.md
|
|
13
|
+
SECTIONS = {
|
|
14
|
+
'async': {
|
|
15
|
+
'number': 1,
|
|
16
|
+
'title': 'Eliminating Waterfalls',
|
|
17
|
+
'impact': 'CRITICAL',
|
|
18
|
+
'description': 'Waterfalls are the #1 performance killer. Each sequential await adds full network latency. Eliminating them yields the largest gains.'
|
|
19
|
+
},
|
|
20
|
+
'bundle': {
|
|
21
|
+
'number': 2,
|
|
22
|
+
'title': 'Bundle Size Optimization',
|
|
23
|
+
'impact': 'CRITICAL',
|
|
24
|
+
'description': 'Reducing initial bundle size improves Time to Interactive and Largest Contentful Paint.'
|
|
25
|
+
},
|
|
26
|
+
'server': {
|
|
27
|
+
'number': 3,
|
|
28
|
+
'title': 'Server-Side Performance',
|
|
29
|
+
'impact': 'HIGH',
|
|
30
|
+
'description': 'Optimizing server-side rendering and data fetching eliminates server-side waterfalls and reduces response times.'
|
|
31
|
+
},
|
|
32
|
+
'client': {
|
|
33
|
+
'number': 4,
|
|
34
|
+
'title': 'Client-Side Data Fetching',
|
|
35
|
+
'impact': 'MEDIUM-HIGH',
|
|
36
|
+
'description': 'Automatic deduplication and efficient data fetching patterns reduce redundant network requests.'
|
|
37
|
+
},
|
|
38
|
+
'rerender': {
|
|
39
|
+
'number': 5,
|
|
40
|
+
'title': 'Re-render Optimization',
|
|
41
|
+
'impact': 'MEDIUM',
|
|
42
|
+
'description': 'Reducing unnecessary re-renders minimizes wasted computation and improves UI responsiveness.'
|
|
43
|
+
},
|
|
44
|
+
'rendering': {
|
|
45
|
+
'number': 6,
|
|
46
|
+
'title': 'Rendering Performance',
|
|
47
|
+
'impact': 'MEDIUM',
|
|
48
|
+
'description': 'Optimizing the rendering process reduces the work the browser needs to do.'
|
|
49
|
+
},
|
|
50
|
+
'js': {
|
|
51
|
+
'number': 7,
|
|
52
|
+
'title': 'JavaScript Performance',
|
|
53
|
+
'impact': 'LOW-MEDIUM',
|
|
54
|
+
'description': 'Micro-optimizations for hot paths can add up to meaningful improvements.'
|
|
55
|
+
},
|
|
56
|
+
'advanced': {
|
|
57
|
+
'number': 8,
|
|
58
|
+
'title': 'Advanced Patterns',
|
|
59
|
+
'impact': 'VARIABLE',
|
|
60
|
+
'description': 'Advanced patterns for specific cases that require careful implementation.'
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def parse_frontmatter(content: str) -> Tuple[Dict, str]:
|
|
66
|
+
"""Parse markdown frontmatter and body"""
|
|
67
|
+
if not content.startswith('---'):
|
|
68
|
+
return {}, content
|
|
69
|
+
|
|
70
|
+
parts = content.split('---', 2)
|
|
71
|
+
if len(parts) < 3:
|
|
72
|
+
return {}, content
|
|
73
|
+
|
|
74
|
+
# Parse YAML frontmatter manually (simple key: value)
|
|
75
|
+
frontmatter = {}
|
|
76
|
+
for line in parts[1].strip().split('\n'):
|
|
77
|
+
if ':' in line:
|
|
78
|
+
key, value = line.split(':', 1)
|
|
79
|
+
frontmatter[key.strip()] = value.strip()
|
|
80
|
+
|
|
81
|
+
body = parts[2].strip()
|
|
82
|
+
return frontmatter, body
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def parse_rule_file(filepath: Path) -> Dict:
|
|
86
|
+
"""Parse a single rule file"""
|
|
87
|
+
with open(filepath, 'r', encoding='utf-8') as f:
|
|
88
|
+
content = f.read()
|
|
89
|
+
|
|
90
|
+
frontmatter, body = parse_frontmatter(content)
|
|
91
|
+
|
|
92
|
+
# Extract prefix from filename
|
|
93
|
+
filename = filepath.stem
|
|
94
|
+
prefix = filename.split('-')[0]
|
|
95
|
+
|
|
96
|
+
return {
|
|
97
|
+
'filename': filepath.name,
|
|
98
|
+
'prefix': prefix,
|
|
99
|
+
'title': frontmatter.get('title', filename),
|
|
100
|
+
'impact': frontmatter.get('impact', ''),
|
|
101
|
+
'impactDescription': frontmatter.get('impactDescription', ''),
|
|
102
|
+
'tags': frontmatter.get('tags', ''),
|
|
103
|
+
'body': body,
|
|
104
|
+
'frontmatter': frontmatter
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def group_rules_by_section(rules_dir: Path) -> Dict[str, List[Dict]]:
|
|
109
|
+
"""Group all rules by their section prefix"""
|
|
110
|
+
grouped = {prefix: [] for prefix in SECTIONS.keys()}
|
|
111
|
+
|
|
112
|
+
for rule_file in sorted(rules_dir.glob('*.md')):
|
|
113
|
+
# Skip special files
|
|
114
|
+
if rule_file.name.startswith('_'):
|
|
115
|
+
continue
|
|
116
|
+
|
|
117
|
+
rule = parse_rule_file(rule_file)
|
|
118
|
+
prefix = rule['prefix']
|
|
119
|
+
|
|
120
|
+
if prefix in grouped:
|
|
121
|
+
grouped[prefix].append(rule)
|
|
122
|
+
else:
|
|
123
|
+
print(f"[WARNING] Unknown prefix '{prefix}' in file: {rule_file.name}")
|
|
124
|
+
|
|
125
|
+
return grouped
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def generate_section_file(section_prefix: str, rules: List[Dict], output_dir: Path):
|
|
129
|
+
"""Generate a merged section file"""
|
|
130
|
+
if not rules:
|
|
131
|
+
print(f"[WARNING] No rules found for section: {section_prefix}")
|
|
132
|
+
return
|
|
133
|
+
|
|
134
|
+
section_meta = SECTIONS[section_prefix]
|
|
135
|
+
section_num = section_meta['number']
|
|
136
|
+
section_title = section_meta['title']
|
|
137
|
+
impact = section_meta['impact']
|
|
138
|
+
description = section_meta['description']
|
|
139
|
+
|
|
140
|
+
# Sort rules by title
|
|
141
|
+
rules.sort(key=lambda r: r['title'])
|
|
142
|
+
|
|
143
|
+
# Build content
|
|
144
|
+
content = f"""# {section_num}. {section_title}
|
|
145
|
+
|
|
146
|
+
> **Impact:** {impact}
|
|
147
|
+
> **Focus:** {description}
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## Overview
|
|
152
|
+
|
|
153
|
+
This section contains **{len(rules)} rules** focused on {section_title.lower()}.
|
|
154
|
+
|
|
155
|
+
"""
|
|
156
|
+
|
|
157
|
+
# Add each rule
|
|
158
|
+
for i, rule in enumerate(rules, 1):
|
|
159
|
+
rule_id = f"{section_num}.{i}"
|
|
160
|
+
title = rule['title']
|
|
161
|
+
rule_impact = rule['impact']
|
|
162
|
+
tags = rule['tags']
|
|
163
|
+
body = rule['body']
|
|
164
|
+
|
|
165
|
+
content += f"""---
|
|
166
|
+
|
|
167
|
+
## Rule {rule_id}: {title}
|
|
168
|
+
|
|
169
|
+
"""
|
|
170
|
+
|
|
171
|
+
if rule_impact:
|
|
172
|
+
content += f"**Impact:** {rule_impact} \n"
|
|
173
|
+
|
|
174
|
+
if tags:
|
|
175
|
+
content += f"**Tags:** {tags} \n"
|
|
176
|
+
|
|
177
|
+
content += f"\n{body}\n\n"
|
|
178
|
+
|
|
179
|
+
# Write file
|
|
180
|
+
output_file = output_dir / f"{section_num}-{section_prefix}-{section_title.lower().replace(' ', '-')}.md"
|
|
181
|
+
output_file.write_text(content, encoding='utf-8')
|
|
182
|
+
print(f"[OK] Generated: {output_file.name} ({len(rules)} rules)")
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
def main():
|
|
186
|
+
"""Main conversion function"""
|
|
187
|
+
# Paths
|
|
188
|
+
base_dir = Path(__file__).parent.parent.parent.parent.parent
|
|
189
|
+
rules_dir = base_dir / "others/agent-skills/skills/react-best-practices/rules"
|
|
190
|
+
output_dir = base_dir / ".agent/skills/react-best-practices"
|
|
191
|
+
|
|
192
|
+
print(f"[*] Reading rules from: {rules_dir}")
|
|
193
|
+
print(f"[*] Output to: {output_dir}")
|
|
194
|
+
print()
|
|
195
|
+
|
|
196
|
+
# Check if rules directory exists
|
|
197
|
+
if not rules_dir.exists():
|
|
198
|
+
print(f"[ERROR] Rules directory not found: {rules_dir}")
|
|
199
|
+
return
|
|
200
|
+
|
|
201
|
+
# Group rules
|
|
202
|
+
print("[*] Grouping rules by section...")
|
|
203
|
+
grouped_rules = group_rules_by_section(rules_dir)
|
|
204
|
+
|
|
205
|
+
# Stats
|
|
206
|
+
total_rules = sum(len(rules) for rules in grouped_rules.values())
|
|
207
|
+
print(f"[*] Found {total_rules} total rules")
|
|
208
|
+
print()
|
|
209
|
+
|
|
210
|
+
# Generate section files
|
|
211
|
+
print("[*] Generating section files...")
|
|
212
|
+
for section_prefix in SECTIONS.keys():
|
|
213
|
+
rules = grouped_rules[section_prefix]
|
|
214
|
+
generate_section_file(section_prefix, rules, output_dir)
|
|
215
|
+
|
|
216
|
+
print()
|
|
217
|
+
print("[SUCCESS] Conversion complete!")
|
|
218
|
+
print(f"[*] Generated 8 section files from {total_rules} rules")
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
if __name__ == '__main__':
|
|
222
|
+
main()
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
React Performance Checker
|
|
4
|
+
Automated performance audit for React/Next.js projects
|
|
5
|
+
Based on Vercel Engineering best practices
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import os
|
|
9
|
+
import re
|
|
10
|
+
import json
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
from typing import List, Dict, Tuple
|
|
13
|
+
|
|
14
|
+
class PerformanceChecker:
|
|
15
|
+
def __init__(self, project_path: str):
|
|
16
|
+
self.project_path = Path(project_path)
|
|
17
|
+
self.issues = []
|
|
18
|
+
self.warnings = []
|
|
19
|
+
self.passed = []
|
|
20
|
+
|
|
21
|
+
def check_waterfalls(self):
|
|
22
|
+
"""Check for sequential await patterns (Section 1)"""
|
|
23
|
+
print("\n[*] Checking for waterfalls (sequential awaits)...")
|
|
24
|
+
|
|
25
|
+
for filepath in self.project_path.rglob('*.{ts,tsx,js,jsx}'):
|
|
26
|
+
if 'node_modules' in str(filepath):
|
|
27
|
+
continue
|
|
28
|
+
|
|
29
|
+
try:
|
|
30
|
+
content = filepath.read_text(encoding='utf-8')
|
|
31
|
+
|
|
32
|
+
# Pattern: multiple awaits in sequence without Promise.all
|
|
33
|
+
sequential_awaits = re.findall(r'await\s+\w+.*?\n\s*await\s+\w+', content)
|
|
34
|
+
|
|
35
|
+
if sequential_awaits:
|
|
36
|
+
self.issues.append({
|
|
37
|
+
'file': str(filepath.relative_to(self.project_path)),
|
|
38
|
+
'type': 'CRITICAL',
|
|
39
|
+
'issue': 'Sequential awaits detected (waterfall)',
|
|
40
|
+
'fix': 'Use Promise.all() for parallel fetching',
|
|
41
|
+
'section': '1-async-eliminating-waterfalls.md'
|
|
42
|
+
})
|
|
43
|
+
except Exception as e:
|
|
44
|
+
continue
|
|
45
|
+
|
|
46
|
+
def check_barrel_imports(self):
|
|
47
|
+
"""Check for barrel imports (Section 2)"""
|
|
48
|
+
print("[*] Checking for barrel imports...")
|
|
49
|
+
|
|
50
|
+
for filepath in self.project_path.rglob('*.{ts,tsx,js,jsx}'):
|
|
51
|
+
if 'node_modules' in str(filepath):
|
|
52
|
+
continue
|
|
53
|
+
|
|
54
|
+
try:
|
|
55
|
+
content = filepath.read_text(encoding='utf-8')
|
|
56
|
+
|
|
57
|
+
# Pattern: import from index files or barrel exports
|
|
58
|
+
barrel_imports = re.findall(r"import.*from\s+['\"](@/.*?)/index['\"]", content)
|
|
59
|
+
barrel_imports += re.findall(r"import.*from\s+['\"]\.\.?/.*?['\"](?!.*?\.tsx?)", content)
|
|
60
|
+
|
|
61
|
+
if barrel_imports:
|
|
62
|
+
self.warnings.append({
|
|
63
|
+
'file': str(filepath.relative_to(self.project_path)),
|
|
64
|
+
'type': 'CRITICAL',
|
|
65
|
+
'issue': 'Potential barrel imports detected',
|
|
66
|
+
'fix': 'Import directly from specific files',
|
|
67
|
+
'section': '2-bundle-bundle-size-optimization.md'
|
|
68
|
+
})
|
|
69
|
+
except Exception as e:
|
|
70
|
+
continue
|
|
71
|
+
|
|
72
|
+
def check_dynamic_imports(self):
|
|
73
|
+
"""Check if large components use dynamic imports (Section 2)"""
|
|
74
|
+
print("[*] Checking for missing dynamic imports...")
|
|
75
|
+
|
|
76
|
+
for filepath in self.project_path.rglob('*.{ts,tsx}'):
|
|
77
|
+
if 'node_modules' in str(filepath):
|
|
78
|
+
continue
|
|
79
|
+
|
|
80
|
+
try:
|
|
81
|
+
content = filepath.read_text(encoding='utf-8')
|
|
82
|
+
|
|
83
|
+
# Check file size - if > 10KB, should probably use dynamic import
|
|
84
|
+
if len(content) > 10000:
|
|
85
|
+
# Check if it's imported statically somewhere
|
|
86
|
+
filename = filepath.stem
|
|
87
|
+
|
|
88
|
+
# Search for static imports of this component
|
|
89
|
+
for check_file in self.project_path.rglob('*.{ts,tsx}'):
|
|
90
|
+
if check_file == filepath or 'node_modules' in str(check_file):
|
|
91
|
+
continue
|
|
92
|
+
|
|
93
|
+
check_content = check_file.read_text(encoding='utf-8')
|
|
94
|
+
if f"import {filename}" in check_content or f"import {{ {filename}" in check_content:
|
|
95
|
+
if 'dynamic(' not in check_content:
|
|
96
|
+
self.warnings.append({
|
|
97
|
+
'file': str(check_file.relative_to(self.project_path)),
|
|
98
|
+
'type': 'CRITICAL',
|
|
99
|
+
'issue': f'Large component {filename} imported statically',
|
|
100
|
+
'fix': 'Use dynamic() for code splitting',
|
|
101
|
+
'section': '2-bundle-bundle-size-optimization.md'
|
|
102
|
+
})
|
|
103
|
+
break
|
|
104
|
+
except Exception as e:
|
|
105
|
+
continue
|
|
106
|
+
|
|
107
|
+
def check_useEffect_fetching(self):
|
|
108
|
+
"""Check for data fetching in useEffect (Section 4)"""
|
|
109
|
+
print("[*] Checking for useEffect data fetching...")
|
|
110
|
+
|
|
111
|
+
for filepath in self.project_path.rglob('*.{ts,tsx}'):
|
|
112
|
+
if 'node_modules' in str(filepath):
|
|
113
|
+
continue
|
|
114
|
+
|
|
115
|
+
try:
|
|
116
|
+
content = filepath.read_text(encoding='utf-8')
|
|
117
|
+
|
|
118
|
+
# Pattern: fetch or axios in useEffect
|
|
119
|
+
if 'useEffect' in content:
|
|
120
|
+
if re.search(r'useEffect.*?fetch\(', content, re.DOTALL):
|
|
121
|
+
self.warnings.append({
|
|
122
|
+
'file': str(filepath.relative_to(self.project_path)),
|
|
123
|
+
'type': 'MEDIUM-HIGH',
|
|
124
|
+
'issue': 'Data fetching in useEffect',
|
|
125
|
+
'fix': 'Consider using SWR or React Query for deduplication',
|
|
126
|
+
'section': '4-client-client-side-data-fetching.md'
|
|
127
|
+
})
|
|
128
|
+
except Exception as e:
|
|
129
|
+
continue
|
|
130
|
+
|
|
131
|
+
def check_missing_memoization(self):
|
|
132
|
+
"""Check for missing React.memo, useMemo, useCallback (Section 5)"""
|
|
133
|
+
print("[*] Checking for missing memoization...")
|
|
134
|
+
|
|
135
|
+
for filepath in self.project_path.rglob('*.{tsx}'):
|
|
136
|
+
if 'node_modules' in str(filepath):
|
|
137
|
+
continue
|
|
138
|
+
|
|
139
|
+
try:
|
|
140
|
+
content = filepath.read_text(encoding='utf-8')
|
|
141
|
+
|
|
142
|
+
# Check for component definitions without memo
|
|
143
|
+
components = re.findall(r'(?:export\s+)?(?:const|function)\s+([A-Z]\w+)', content)
|
|
144
|
+
|
|
145
|
+
if components and 'React.memo' not in content and 'memo(' not in content:
|
|
146
|
+
# Check if component receives props
|
|
147
|
+
if 'props:' in content or 'Props>' in content:
|
|
148
|
+
self.warnings.append({
|
|
149
|
+
'file': str(filepath.relative_to(self.project_path)),
|
|
150
|
+
'type': 'MEDIUM',
|
|
151
|
+
'issue': 'Component with props not memoized',
|
|
152
|
+
'fix': 'Consider using React.memo if props are stable',
|
|
153
|
+
'section': '5-rerender-re-render-optimization.md'
|
|
154
|
+
})
|
|
155
|
+
except Exception as e:
|
|
156
|
+
continue
|
|
157
|
+
|
|
158
|
+
def check_image_optimization(self):
|
|
159
|
+
"""Check for unoptimized images (Section 6)"""
|
|
160
|
+
print("[*] Checking for image optimization...")
|
|
161
|
+
|
|
162
|
+
for filepath in self.project_path.rglob('*.{ts,tsx,js,jsx}'):
|
|
163
|
+
if 'node_modules' in str(filepath):
|
|
164
|
+
continue
|
|
165
|
+
|
|
166
|
+
try:
|
|
167
|
+
content = filepath.read_text(encoding='utf-8')
|
|
168
|
+
|
|
169
|
+
# Check for <img> tags instead of next/image
|
|
170
|
+
if '<img' in content and 'next/image' not in content:
|
|
171
|
+
self.warnings.append({
|
|
172
|
+
'file': str(filepath.relative_to(self.project_path)),
|
|
173
|
+
'type': 'MEDIUM',
|
|
174
|
+
'issue': 'Using <img> instead of next/image',
|
|
175
|
+
'fix': 'Use next/image for automatic optimization',
|
|
176
|
+
'section': '6-rendering-rendering-performance.md'
|
|
177
|
+
})
|
|
178
|
+
except Exception as e:
|
|
179
|
+
continue
|
|
180
|
+
|
|
181
|
+
def generate_report(self):
|
|
182
|
+
"""Generate final report"""
|
|
183
|
+
print("\n" + "="*60)
|
|
184
|
+
print("REACT PERFORMANCE AUDIT REPORT")
|
|
185
|
+
print("="*60)
|
|
186
|
+
|
|
187
|
+
print(f"\n[CRITICAL ISSUES] ({len([i for i in self.issues if i['type'] == 'CRITICAL'])})")
|
|
188
|
+
for issue in self.issues:
|
|
189
|
+
if issue['type'] == 'CRITICAL':
|
|
190
|
+
print(f" - {issue['file']}")
|
|
191
|
+
print(f" Issue: {issue['issue']}")
|
|
192
|
+
print(f" Fix: {issue['fix']}")
|
|
193
|
+
print(f" Reference: {issue['section']}\n")
|
|
194
|
+
|
|
195
|
+
print(f"\n[WARNINGS] ({len(self.warnings)})")
|
|
196
|
+
for warning in self.warnings[:10]: # Show first 10
|
|
197
|
+
print(f" - {warning['file']}")
|
|
198
|
+
print(f" Issue: {warning['issue']}")
|
|
199
|
+
print(f" Fix: {warning['fix']}")
|
|
200
|
+
print(f" Reference: {warning['section']}\n")
|
|
201
|
+
|
|
202
|
+
if len(self.warnings) > 10:
|
|
203
|
+
print(f" ... and {len(self.warnings) - 10} more warnings")
|
|
204
|
+
|
|
205
|
+
print("\n" + "="*60)
|
|
206
|
+
print(f"SUMMARY:")
|
|
207
|
+
print(f" Critical Issues: {len([i for i in self.issues if i['type'] == 'CRITICAL'])}")
|
|
208
|
+
print(f" Warnings: {len(self.warnings)}")
|
|
209
|
+
print("="*60)
|
|
210
|
+
|
|
211
|
+
if len(self.issues) == 0 and len(self.warnings) == 0:
|
|
212
|
+
print("\n[SUCCESS] No major performance issues detected!")
|
|
213
|
+
else:
|
|
214
|
+
print("\n[ACTION REQUIRED] Review and fix issues above")
|
|
215
|
+
print("Priority: CRITICAL > HIGH > MEDIUM > LOW")
|
|
216
|
+
|
|
217
|
+
def run(self):
|
|
218
|
+
"""Run all checks"""
|
|
219
|
+
print("="*60)
|
|
220
|
+
print("React Performance Checker (Vercel Engineering)")
|
|
221
|
+
print("="*60)
|
|
222
|
+
print(f"Scanning: {self.project_path}")
|
|
223
|
+
|
|
224
|
+
self.check_waterfalls()
|
|
225
|
+
self.check_barrel_imports()
|
|
226
|
+
self.check_dynamic_imports()
|
|
227
|
+
self.check_useEffect_fetching()
|
|
228
|
+
self.check_missing_memoization()
|
|
229
|
+
self.check_image_optimization()
|
|
230
|
+
|
|
231
|
+
self.generate_report()
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
def main():
|
|
235
|
+
import sys
|
|
236
|
+
|
|
237
|
+
if len(sys.argv) < 2:
|
|
238
|
+
print("Usage: python react_performance_checker.py <project_path>")
|
|
239
|
+
sys.exit(1)
|
|
240
|
+
|
|
241
|
+
project_path = sys.argv[1]
|
|
242
|
+
|
|
243
|
+
if not os.path.exists(project_path):
|
|
244
|
+
print(f"[ERROR] Path not found: {project_path}")
|
|
245
|
+
sys.exit(1)
|
|
246
|
+
|
|
247
|
+
checker = PerformanceChecker(project_path)
|
|
248
|
+
checker.run()
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
if __name__ == '__main__':
|
|
252
|
+
main()
|