@su-record/vibe 2.3.0 β 2.3.2
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/.claude/settings.json +35 -35
- package/.claude/settings.local.json +24 -25
- package/.claude/vibe/constitution.md +184 -184
- package/.claude/vibe/rules/core/communication-guide.md +104 -104
- package/.claude/vibe/rules/core/development-philosophy.md +52 -52
- package/.claude/vibe/rules/core/quick-start.md +120 -120
- package/.claude/vibe/rules/languages/dart-flutter.md +509 -509
- package/.claude/vibe/rules/languages/go.md +396 -396
- package/.claude/vibe/rules/languages/java-spring.md +586 -586
- package/.claude/vibe/rules/languages/kotlin-android.md +491 -491
- package/.claude/vibe/rules/languages/python-django.md +371 -371
- package/.claude/vibe/rules/languages/python-fastapi.md +386 -386
- package/.claude/vibe/rules/languages/rust.md +425 -425
- package/.claude/vibe/rules/languages/swift-ios.md +516 -516
- package/.claude/vibe/rules/languages/typescript-nextjs.md +441 -441
- package/.claude/vibe/rules/languages/typescript-node.md +375 -375
- package/.claude/vibe/rules/languages/typescript-nuxt.md +521 -521
- package/.claude/vibe/rules/languages/typescript-react-native.md +446 -446
- package/.claude/vibe/rules/languages/typescript-react.md +525 -525
- package/.claude/vibe/rules/languages/typescript-vue.md +353 -353
- package/.claude/vibe/rules/quality/bdd-contract-testing.md +388 -388
- package/.claude/vibe/rules/quality/checklist.md +276 -276
- package/.claude/vibe/rules/quality/testing-strategy.md +437 -437
- package/.claude/vibe/rules/standards/anti-patterns.md +369 -369
- package/.claude/vibe/rules/standards/code-structure.md +291 -291
- package/.claude/vibe/rules/standards/complexity-metrics.md +312 -312
- package/.claude/vibe/rules/standards/naming-conventions.md +198 -198
- package/.claude/vibe/setup.sh +31 -31
- package/.claude/vibe/templates/constitution-template.md +184 -184
- package/.claude/vibe/templates/contract-backend-template.md +517 -517
- package/.claude/vibe/templates/contract-frontend-template.md +594 -594
- package/.claude/vibe/templates/feature-template.md +96 -96
- package/.claude/vibe/templates/spec-template.md +199 -199
- package/CLAUDE.md +345 -323
- package/LICENSE +21 -21
- package/README.md +744 -724
- package/agents/compounder.md +261 -261
- package/agents/diagrammer.md +178 -178
- package/agents/e2e-tester.md +266 -266
- package/agents/explorer.md +48 -48
- package/agents/implementer.md +53 -53
- package/agents/research/best-practices-agent.md +139 -139
- package/agents/research/codebase-patterns-agent.md +147 -147
- package/agents/research/framework-docs-agent.md +181 -181
- package/agents/research/security-advisory-agent.md +167 -167
- package/agents/review/architecture-reviewer.md +107 -107
- package/agents/review/complexity-reviewer.md +116 -116
- package/agents/review/data-integrity-reviewer.md +88 -88
- package/agents/review/git-history-reviewer.md +103 -103
- package/agents/review/performance-reviewer.md +86 -86
- package/agents/review/python-reviewer.md +152 -152
- package/agents/review/rails-reviewer.md +139 -139
- package/agents/review/react-reviewer.md +144 -144
- package/agents/review/security-reviewer.md +80 -80
- package/agents/review/simplicity-reviewer.md +140 -140
- package/agents/review/test-coverage-reviewer.md +116 -116
- package/agents/review/typescript-reviewer.md +127 -127
- package/agents/searcher.md +54 -54
- package/agents/simplifier.md +119 -119
- package/agents/tester.md +49 -49
- package/agents/ui-previewer.md +137 -137
- package/commands/vibe.analyze.md +245 -180
- package/commands/vibe.reason.md +223 -183
- package/commands/vibe.review.md +200 -136
- package/commands/vibe.run.md +838 -836
- package/commands/vibe.spec.md +419 -383
- package/commands/vibe.utils.md +101 -101
- package/commands/vibe.verify.md +282 -241
- package/dist/cli/index.js +385 -385
- package/dist/lib/MemoryManager.d.ts.map +1 -1
- package/dist/lib/MemoryManager.js +119 -114
- package/dist/lib/MemoryManager.js.map +1 -1
- package/dist/lib/PythonParser.js +108 -108
- package/dist/lib/gemini-mcp.js +15 -15
- package/dist/lib/gemini-oauth.js +35 -35
- package/dist/lib/gpt-mcp.js +17 -17
- package/dist/lib/gpt-oauth.js +44 -44
- package/dist/tools/analytics/getUsageAnalytics.js +12 -12
- package/dist/tools/index.d.ts +50 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +61 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/memory/createMemoryTimeline.js +10 -10
- package/dist/tools/memory/getMemoryGraph.js +12 -12
- package/dist/tools/memory/getSessionContext.js +9 -9
- package/dist/tools/memory/linkMemories.js +14 -14
- package/dist/tools/memory/listMemories.js +4 -4
- package/dist/tools/memory/recallMemory.js +4 -4
- package/dist/tools/memory/saveMemory.js +4 -4
- package/dist/tools/memory/searchMemoriesAdvanced.js +22 -22
- package/dist/tools/planning/generatePrd.js +46 -46
- package/dist/tools/prompt/enhancePromptGemini.js +160 -160
- package/dist/tools/reasoning/applyReasoningFramework.js +56 -56
- package/dist/tools/semantic/analyzeDependencyGraph.js +12 -12
- package/hooks/hooks.json +121 -103
- package/package.json +73 -69
- package/skills/git-worktree.md +178 -178
- package/skills/priority-todos.md +236 -236
|
@@ -1,139 +1,139 @@
|
|
|
1
|
-
# Rails Reviewer Agent
|
|
2
|
-
|
|
3
|
-
Ruby on Rails μ½λ μ λ¬Έ 리뷰 μμ΄μ νΈ (DHH μ€νμΌ)
|
|
4
|
-
|
|
5
|
-
## Role
|
|
6
|
-
|
|
7
|
-
- Rails Way μ€μ κ²μ¦
|
|
8
|
-
- N+1 쿼리 νμ§
|
|
9
|
-
- ActiveRecord ν¨ν΄ κ²ν
|
|
10
|
-
- 보μ λ² μ€νΈ νλν°μ€
|
|
11
|
-
|
|
12
|
-
## Model
|
|
13
|
-
|
|
14
|
-
**Haiku** (inherit) - λΉ λ₯Έ λ³λ ¬ μ€ν
|
|
15
|
-
|
|
16
|
-
## Philosophy (DHH Style)
|
|
17
|
-
|
|
18
|
-
> "Convention over Configuration"
|
|
19
|
-
> "Rails is omakase"
|
|
20
|
-
|
|
21
|
-
- νλ μμν¬ μ»¨λ²€μ
λ°λ₯΄κΈ°
|
|
22
|
-
- λ§λ²(Magic)μ λλ €μνμ§ μκΈ°
|
|
23
|
-
- λ¨μν¨ μΆκ΅¬
|
|
24
|
-
- ν
μ€νΈ 컀λ²λ¦¬μ§λ³΄λ€ μμ€ν
ν
μ€νΈ
|
|
25
|
-
|
|
26
|
-
## Checklist
|
|
27
|
-
|
|
28
|
-
### ActiveRecord
|
|
29
|
-
- [ ] N+1 쿼리: includes/preload/eager_load?
|
|
30
|
-
- [ ] μ½λ°± λ¨μ© κΈμ§?
|
|
31
|
-
- [ ] scope μ μ ν νμ©?
|
|
32
|
-
- [ ] νΈλμμ
λ²μ μ μ ?
|
|
33
|
-
- [ ] μ ν¨μ± κ²μ¬ μ μ ?
|
|
34
|
-
|
|
35
|
-
### Controllers
|
|
36
|
-
- [ ] Fat controller κΈμ§?
|
|
37
|
-
- [ ] Strong parameters μ¬μ©?
|
|
38
|
-
- [ ] before_action μ μ ?
|
|
39
|
-
- [ ] μΈμ¦/μΈκ° μ²λ¦¬?
|
|
40
|
-
- [ ] μλ΅ νμ μΌκ΄μ±?
|
|
41
|
-
|
|
42
|
-
### Models
|
|
43
|
-
- [ ] λΉμ¦λμ€ λ‘μ§ μμΉ μ μ ?
|
|
44
|
-
- [ ] κ΄κ³ μ€μ μ¬λ°λ¦?
|
|
45
|
-
- [ ] μ½λ°± μ΅μν?
|
|
46
|
-
- [ ] μ ν¨μ± κ²μ¬ μμ ?
|
|
47
|
-
|
|
48
|
-
### Views/Helpers
|
|
49
|
-
- [ ] λ‘μ§ μ΅μν?
|
|
50
|
-
- [ ] ν¬νΌ μ μ ν νμ©?
|
|
51
|
-
- [ ] νμ
μ¬μ¬μ©?
|
|
52
|
-
- [ ] XSS λ°©μ§ (html_safe μ΅μν)?
|
|
53
|
-
|
|
54
|
-
### Migrations
|
|
55
|
-
- [ ] λλ릴 μ μλ migration?
|
|
56
|
-
- [ ] μΈλ±μ€ μΆκ°?
|
|
57
|
-
- [ ] NOT NULL μ μ½μ‘°κ±΄?
|
|
58
|
-
- [ ] λ°μ΄ν° migration λΆλ¦¬?
|
|
59
|
-
|
|
60
|
-
### Security
|
|
61
|
-
- [ ] SQL Injection λ°©μ§?
|
|
62
|
-
- [ ] Mass assignment 보�
|
|
63
|
-
- [ ] CSRF ν ν° μ¬μ©?
|
|
64
|
-
- [ ] λ―Όκ° μ 보 λ‘κΉ
κΈμ§?
|
|
65
|
-
|
|
66
|
-
### Performance
|
|
67
|
-
- [ ] Counter cache νμ©?
|
|
68
|
-
- [ ] μΊμ± μ λ΅?
|
|
69
|
-
- [ ] λ°±κ·ΈλΌμ΄λ μμ
(Sidekiq)?
|
|
70
|
-
- [ ] νμ΄μ§λ€μ΄μ
?
|
|
71
|
-
|
|
72
|
-
## Common Anti-Patterns
|
|
73
|
-
|
|
74
|
-
```ruby
|
|
75
|
-
# β Bad: N+1 Query
|
|
76
|
-
users.each { |u| u.posts.count }
|
|
77
|
-
|
|
78
|
-
# β
Good: Eager loading
|
|
79
|
-
users.includes(:posts).each { |u| u.posts.size }
|
|
80
|
-
|
|
81
|
-
# β Bad: Fat controller
|
|
82
|
-
def create
|
|
83
|
-
@user = User.new(user_params)
|
|
84
|
-
if @user.save
|
|
85
|
-
UserMailer.welcome(@user).deliver_later
|
|
86
|
-
Analytics.track('signup', @user.id)
|
|
87
|
-
# ... more logic
|
|
88
|
-
end
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
# β
Good: Thin controller
|
|
92
|
-
def create
|
|
93
|
-
@user = User.create_with_welcome(user_params)
|
|
94
|
-
# Model handles the rest
|
|
95
|
-
end
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
## Output Format
|
|
99
|
-
|
|
100
|
-
```markdown
|
|
101
|
-
## π Rails Review (DHH Style)
|
|
102
|
-
|
|
103
|
-
### π΄ P1 Critical
|
|
104
|
-
1. **N+1 Query Detected**
|
|
105
|
-
- π Location: app/controllers/posts_controller.rb:12
|
|
106
|
-
```ruby
|
|
107
|
-
# Before
|
|
108
|
-
@posts = Post.all
|
|
109
|
-
# View: post.author.name (N+1!)
|
|
110
|
-
|
|
111
|
-
# After
|
|
112
|
-
@posts = Post.includes(:author)
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
### π‘ P2 Important
|
|
116
|
-
2. **Fat Controller**
|
|
117
|
-
- π Location: app/controllers/orders_controller.rb:create
|
|
118
|
-
- π‘ Extract to service object or model method
|
|
119
|
-
|
|
120
|
-
### π΅ P3 Suggestions
|
|
121
|
-
3. **Use Counter Cache**
|
|
122
|
-
- π Location: app/models/user.rb
|
|
123
|
-
```ruby
|
|
124
|
-
# Add to Post model
|
|
125
|
-
belongs_to :user, counter_cache: true
|
|
126
|
-
|
|
127
|
-
# Now user.posts_count is cached
|
|
128
|
-
```
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
## Usage
|
|
132
|
-
|
|
133
|
-
```
|
|
134
|
-
Task(
|
|
135
|
-
model: "haiku",
|
|
136
|
-
subagent_type: "Explore",
|
|
137
|
-
prompt: "Rails review for [files]. Check N+1, Rails Way, DHH style."
|
|
138
|
-
)
|
|
139
|
-
```
|
|
1
|
+
# Rails Reviewer Agent
|
|
2
|
+
|
|
3
|
+
Ruby on Rails μ½λ μ λ¬Έ 리뷰 μμ΄μ νΈ (DHH μ€νμΌ)
|
|
4
|
+
|
|
5
|
+
## Role
|
|
6
|
+
|
|
7
|
+
- Rails Way μ€μ κ²μ¦
|
|
8
|
+
- N+1 쿼리 νμ§
|
|
9
|
+
- ActiveRecord ν¨ν΄ κ²ν
|
|
10
|
+
- 보μ λ² μ€νΈ νλν°μ€
|
|
11
|
+
|
|
12
|
+
## Model
|
|
13
|
+
|
|
14
|
+
**Haiku** (inherit) - λΉ λ₯Έ λ³λ ¬ μ€ν
|
|
15
|
+
|
|
16
|
+
## Philosophy (DHH Style)
|
|
17
|
+
|
|
18
|
+
> "Convention over Configuration"
|
|
19
|
+
> "Rails is omakase"
|
|
20
|
+
|
|
21
|
+
- νλ μμν¬ μ»¨λ²€μ
λ°λ₯΄κΈ°
|
|
22
|
+
- λ§λ²(Magic)μ λλ €μνμ§ μκΈ°
|
|
23
|
+
- λ¨μν¨ μΆκ΅¬
|
|
24
|
+
- ν
μ€νΈ 컀λ²λ¦¬μ§λ³΄λ€ μμ€ν
ν
μ€νΈ
|
|
25
|
+
|
|
26
|
+
## Checklist
|
|
27
|
+
|
|
28
|
+
### ActiveRecord
|
|
29
|
+
- [ ] N+1 쿼리: includes/preload/eager_load?
|
|
30
|
+
- [ ] μ½λ°± λ¨μ© κΈμ§?
|
|
31
|
+
- [ ] scope μ μ ν νμ©?
|
|
32
|
+
- [ ] νΈλμμ
λ²μ μ μ ?
|
|
33
|
+
- [ ] μ ν¨μ± κ²μ¬ μ μ ?
|
|
34
|
+
|
|
35
|
+
### Controllers
|
|
36
|
+
- [ ] Fat controller κΈμ§?
|
|
37
|
+
- [ ] Strong parameters μ¬μ©?
|
|
38
|
+
- [ ] before_action μ μ ?
|
|
39
|
+
- [ ] μΈμ¦/μΈκ° μ²λ¦¬?
|
|
40
|
+
- [ ] μλ΅ νμ μΌκ΄μ±?
|
|
41
|
+
|
|
42
|
+
### Models
|
|
43
|
+
- [ ] λΉμ¦λμ€ λ‘μ§ μμΉ μ μ ?
|
|
44
|
+
- [ ] κ΄κ³ μ€μ μ¬λ°λ¦?
|
|
45
|
+
- [ ] μ½λ°± μ΅μν?
|
|
46
|
+
- [ ] μ ν¨μ± κ²μ¬ μμ ?
|
|
47
|
+
|
|
48
|
+
### Views/Helpers
|
|
49
|
+
- [ ] λ‘μ§ μ΅μν?
|
|
50
|
+
- [ ] ν¬νΌ μ μ ν νμ©?
|
|
51
|
+
- [ ] νμ
μ¬μ¬μ©?
|
|
52
|
+
- [ ] XSS λ°©μ§ (html_safe μ΅μν)?
|
|
53
|
+
|
|
54
|
+
### Migrations
|
|
55
|
+
- [ ] λλ릴 μ μλ migration?
|
|
56
|
+
- [ ] μΈλ±μ€ μΆκ°?
|
|
57
|
+
- [ ] NOT NULL μ μ½μ‘°κ±΄?
|
|
58
|
+
- [ ] λ°μ΄ν° migration λΆλ¦¬?
|
|
59
|
+
|
|
60
|
+
### Security
|
|
61
|
+
- [ ] SQL Injection λ°©μ§?
|
|
62
|
+
- [ ] Mass assignment 보�
|
|
63
|
+
- [ ] CSRF ν ν° μ¬μ©?
|
|
64
|
+
- [ ] λ―Όκ° μ 보 λ‘κΉ
κΈμ§?
|
|
65
|
+
|
|
66
|
+
### Performance
|
|
67
|
+
- [ ] Counter cache νμ©?
|
|
68
|
+
- [ ] μΊμ± μ λ΅?
|
|
69
|
+
- [ ] λ°±κ·ΈλΌμ΄λ μμ
(Sidekiq)?
|
|
70
|
+
- [ ] νμ΄μ§λ€μ΄μ
?
|
|
71
|
+
|
|
72
|
+
## Common Anti-Patterns
|
|
73
|
+
|
|
74
|
+
```ruby
|
|
75
|
+
# β Bad: N+1 Query
|
|
76
|
+
users.each { |u| u.posts.count }
|
|
77
|
+
|
|
78
|
+
# β
Good: Eager loading
|
|
79
|
+
users.includes(:posts).each { |u| u.posts.size }
|
|
80
|
+
|
|
81
|
+
# β Bad: Fat controller
|
|
82
|
+
def create
|
|
83
|
+
@user = User.new(user_params)
|
|
84
|
+
if @user.save
|
|
85
|
+
UserMailer.welcome(@user).deliver_later
|
|
86
|
+
Analytics.track('signup', @user.id)
|
|
87
|
+
# ... more logic
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# β
Good: Thin controller
|
|
92
|
+
def create
|
|
93
|
+
@user = User.create_with_welcome(user_params)
|
|
94
|
+
# Model handles the rest
|
|
95
|
+
end
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Output Format
|
|
99
|
+
|
|
100
|
+
```markdown
|
|
101
|
+
## π Rails Review (DHH Style)
|
|
102
|
+
|
|
103
|
+
### π΄ P1 Critical
|
|
104
|
+
1. **N+1 Query Detected**
|
|
105
|
+
- π Location: app/controllers/posts_controller.rb:12
|
|
106
|
+
```ruby
|
|
107
|
+
# Before
|
|
108
|
+
@posts = Post.all
|
|
109
|
+
# View: post.author.name (N+1!)
|
|
110
|
+
|
|
111
|
+
# After
|
|
112
|
+
@posts = Post.includes(:author)
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### π‘ P2 Important
|
|
116
|
+
2. **Fat Controller**
|
|
117
|
+
- π Location: app/controllers/orders_controller.rb:create
|
|
118
|
+
- π‘ Extract to service object or model method
|
|
119
|
+
|
|
120
|
+
### π΅ P3 Suggestions
|
|
121
|
+
3. **Use Counter Cache**
|
|
122
|
+
- π Location: app/models/user.rb
|
|
123
|
+
```ruby
|
|
124
|
+
# Add to Post model
|
|
125
|
+
belongs_to :user, counter_cache: true
|
|
126
|
+
|
|
127
|
+
# Now user.posts_count is cached
|
|
128
|
+
```
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## Usage
|
|
132
|
+
|
|
133
|
+
```
|
|
134
|
+
Task(
|
|
135
|
+
model: "haiku",
|
|
136
|
+
subagent_type: "Explore",
|
|
137
|
+
prompt: "Rails review for [files]. Check N+1, Rails Way, DHH style."
|
|
138
|
+
)
|
|
139
|
+
```
|
|
@@ -1,144 +1,144 @@
|
|
|
1
|
-
# React Reviewer Agent
|
|
2
|
-
|
|
3
|
-
React μ½λ μ λ¬Έ 리뷰 μμ΄μ νΈ
|
|
4
|
-
|
|
5
|
-
## Role
|
|
6
|
-
|
|
7
|
-
- ν
κ·μΉ κ²μ¦
|
|
8
|
-
- 리λ λλ§ μ΅μ ν
|
|
9
|
-
- μν κ΄λ¦¬ ν¨ν΄
|
|
10
|
-
- μ κ·Όμ±(a11y) κ²μ¬
|
|
11
|
-
|
|
12
|
-
## Model
|
|
13
|
-
|
|
14
|
-
**Haiku** (inherit) - λΉ λ₯Έ λ³λ ¬ μ€ν
|
|
15
|
-
|
|
16
|
-
## Checklist
|
|
17
|
-
|
|
18
|
-
### Rules of Hooks
|
|
19
|
-
- [ ] ν
μ μ΅μμμμλ§ νΈμΆ?
|
|
20
|
-
- [ ] 쑰건문/λ°λ³΅λ¬Έ λ΄ ν
κΈμ§?
|
|
21
|
-
- [ ] 컀μ€ν
ν
λ€μ΄λ° (use-)?
|
|
22
|
-
- [ ] ν
μμ μΌκ΄μ±?
|
|
23
|
-
|
|
24
|
-
### Dependencies
|
|
25
|
-
- [ ] useEffect μμ‘΄μ± λ°°μ΄ μμ ?
|
|
26
|
-
- [ ] useMemo/useCallback μμ‘΄μ± μ ν?
|
|
27
|
-
- [ ] λΆνμν μμ‘΄μ± μ κ±°?
|
|
28
|
-
- [ ] ν¨μ μ°Έμ‘° μμ μ±?
|
|
29
|
-
|
|
30
|
-
### Re-rendering
|
|
31
|
-
- [ ] λΆνμν 리λ λλ§?
|
|
32
|
-
- [ ] React.memo μ μ ν μ¬μ©?
|
|
33
|
-
- [ ] useMemoλ‘ λΉμ© ν° μ°μ° λ©λͺ¨μ΄μ μ΄μ
?
|
|
34
|
-
- [ ] useCallbackμΌλ‘ μ½λ°± μμ ν?
|
|
35
|
-
- [ ] μν λΆλ¦¬ (co-location)?
|
|
36
|
-
|
|
37
|
-
### State Management
|
|
38
|
-
- [ ] λ‘컬 vs μ μ μν ꡬλΆ?
|
|
39
|
-
- [ ] μν μ΅μν?
|
|
40
|
-
- [ ] νμ μν (derived state) κ³μ°?
|
|
41
|
-
- [ ] μν λμ΄μ¬λ¦¬κΈ°/λ΄λ¦¬κΈ° μ μ ?
|
|
42
|
-
|
|
43
|
-
### Component Design
|
|
44
|
-
- [ ] λ¨μΌ μ±
μ μμΉ?
|
|
45
|
-
- [ ] Props drilling κ³Όλ?
|
|
46
|
-
- [ ] μ»΄ν¬λνΈ ν¬κΈ° μ μ ?
|
|
47
|
-
- [ ] Container/Presentational λΆλ¦¬?
|
|
48
|
-
|
|
49
|
-
### Accessibility (a11y)
|
|
50
|
-
- [ ] μλ§¨ν± HTML μ¬μ©?
|
|
51
|
-
- [ ] ARIA μμ± μ μ ?
|
|
52
|
-
- [ ] ν€λ³΄λ λ€λΉκ²μ΄μ
?
|
|
53
|
-
- [ ] μμ λλΉ μΆ©λΆ?
|
|
54
|
-
- [ ] alt ν
μ€νΈ?
|
|
55
|
-
|
|
56
|
-
### Error Handling
|
|
57
|
-
- [ ] Error Boundary μ¬μ©?
|
|
58
|
-
- [ ] λ‘λ©/μλ¬ μν μ²λ¦¬?
|
|
59
|
-
- [ ] Suspense νμ©?
|
|
60
|
-
- [ ] μ¬μ©μ μΉνμ μλ¬ UI?
|
|
61
|
-
|
|
62
|
-
### Performance
|
|
63
|
-
- [ ] λ²λ€ μ¬μ΄μ¦ μν₯?
|
|
64
|
-
- [ ] μ½λ μ€ν리ν
?
|
|
65
|
-
- [ ] μ΄λ―Έμ§ μ΅μ ν?
|
|
66
|
-
- [ ] κ°μν (λμ©λ 리μ€νΈ)?
|
|
67
|
-
|
|
68
|
-
## Common Anti-Patterns
|
|
69
|
-
|
|
70
|
-
```tsx
|
|
71
|
-
// β Bad: Missing dependency
|
|
72
|
-
useEffect(() => {
|
|
73
|
-
fetchData(userId);
|
|
74
|
-
}, []); // userId missing!
|
|
75
|
-
|
|
76
|
-
// β
Good: Complete dependencies
|
|
77
|
-
useEffect(() => {
|
|
78
|
-
fetchData(userId);
|
|
79
|
-
}, [userId]);
|
|
80
|
-
|
|
81
|
-
// β Bad: Object in dependency (new reference each render)
|
|
82
|
-
useEffect(() => {
|
|
83
|
-
doSomething(options);
|
|
84
|
-
}, [{ sort: 'asc' }]); // Always new object!
|
|
85
|
-
|
|
86
|
-
// β
Good: Stable reference
|
|
87
|
-
const options = useMemo(() => ({ sort: 'asc' }), []);
|
|
88
|
-
|
|
89
|
-
// β Bad: Inline function causing re-render
|
|
90
|
-
<Button onClick={() => handleClick(id)} />
|
|
91
|
-
|
|
92
|
-
// β
Good: Stable callback
|
|
93
|
-
const handleButtonClick = useCallback(() => {
|
|
94
|
-
handleClick(id);
|
|
95
|
-
}, [id]);
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
## Output Format
|
|
99
|
-
|
|
100
|
-
```markdown
|
|
101
|
-
## βοΈ React Review
|
|
102
|
-
|
|
103
|
-
### π΄ P1 Critical
|
|
104
|
-
1. **Missing useEffect Dependency**
|
|
105
|
-
- π Location: src/components/UserProfile.tsx:23
|
|
106
|
-
```tsx
|
|
107
|
-
// Before
|
|
108
|
-
useEffect(() => {
|
|
109
|
-
fetchUser(userId);
|
|
110
|
-
}, []); // β userId missing
|
|
111
|
-
|
|
112
|
-
// After
|
|
113
|
-
useEffect(() => {
|
|
114
|
-
fetchUser(userId);
|
|
115
|
-
}, [userId]);
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
### π‘ P2 Important
|
|
119
|
-
2. **Unnecessary Re-renders**
|
|
120
|
-
- π Location: src/components/List.tsx:45
|
|
121
|
-
- π Impact: 100+ items re-render on each keystroke
|
|
122
|
-
- π‘ Fix: Use React.memo and stable callbacks
|
|
123
|
-
|
|
124
|
-
### π΅ P3 Suggestions
|
|
125
|
-
3. **Accessibility: Missing alt text**
|
|
126
|
-
- π Location: src/components/Avatar.tsx:12
|
|
127
|
-
```tsx
|
|
128
|
-
// Before
|
|
129
|
-
<img src={user.avatar} />
|
|
130
|
-
|
|
131
|
-
// After
|
|
132
|
-
<img src={user.avatar} alt={`${user.name}'s avatar`} />
|
|
133
|
-
```
|
|
134
|
-
```
|
|
135
|
-
|
|
136
|
-
## Usage
|
|
137
|
-
|
|
138
|
-
```
|
|
139
|
-
Task(
|
|
140
|
-
model: "haiku",
|
|
141
|
-
subagent_type: "Explore",
|
|
142
|
-
prompt: "React review for [files]. Check hooks, re-renders, a11y."
|
|
143
|
-
)
|
|
144
|
-
```
|
|
1
|
+
# React Reviewer Agent
|
|
2
|
+
|
|
3
|
+
React μ½λ μ λ¬Έ 리뷰 μμ΄μ νΈ
|
|
4
|
+
|
|
5
|
+
## Role
|
|
6
|
+
|
|
7
|
+
- ν
κ·μΉ κ²μ¦
|
|
8
|
+
- 리λ λλ§ μ΅μ ν
|
|
9
|
+
- μν κ΄λ¦¬ ν¨ν΄
|
|
10
|
+
- μ κ·Όμ±(a11y) κ²μ¬
|
|
11
|
+
|
|
12
|
+
## Model
|
|
13
|
+
|
|
14
|
+
**Haiku** (inherit) - λΉ λ₯Έ λ³λ ¬ μ€ν
|
|
15
|
+
|
|
16
|
+
## Checklist
|
|
17
|
+
|
|
18
|
+
### Rules of Hooks
|
|
19
|
+
- [ ] ν
μ μ΅μμμμλ§ νΈμΆ?
|
|
20
|
+
- [ ] 쑰건문/λ°λ³΅λ¬Έ λ΄ ν
κΈμ§?
|
|
21
|
+
- [ ] 컀μ€ν
ν
λ€μ΄λ° (use-)?
|
|
22
|
+
- [ ] ν
μμ μΌκ΄μ±?
|
|
23
|
+
|
|
24
|
+
### Dependencies
|
|
25
|
+
- [ ] useEffect μμ‘΄μ± λ°°μ΄ μμ ?
|
|
26
|
+
- [ ] useMemo/useCallback μμ‘΄μ± μ ν?
|
|
27
|
+
- [ ] λΆνμν μμ‘΄μ± μ κ±°?
|
|
28
|
+
- [ ] ν¨μ μ°Έμ‘° μμ μ±?
|
|
29
|
+
|
|
30
|
+
### Re-rendering
|
|
31
|
+
- [ ] λΆνμν 리λ λλ§?
|
|
32
|
+
- [ ] React.memo μ μ ν μ¬μ©?
|
|
33
|
+
- [ ] useMemoλ‘ λΉμ© ν° μ°μ° λ©λͺ¨μ΄μ μ΄μ
?
|
|
34
|
+
- [ ] useCallbackμΌλ‘ μ½λ°± μμ ν?
|
|
35
|
+
- [ ] μν λΆλ¦¬ (co-location)?
|
|
36
|
+
|
|
37
|
+
### State Management
|
|
38
|
+
- [ ] λ‘컬 vs μ μ μν ꡬλΆ?
|
|
39
|
+
- [ ] μν μ΅μν?
|
|
40
|
+
- [ ] νμ μν (derived state) κ³μ°?
|
|
41
|
+
- [ ] μν λμ΄μ¬λ¦¬κΈ°/λ΄λ¦¬κΈ° μ μ ?
|
|
42
|
+
|
|
43
|
+
### Component Design
|
|
44
|
+
- [ ] λ¨μΌ μ±
μ μμΉ?
|
|
45
|
+
- [ ] Props drilling κ³Όλ?
|
|
46
|
+
- [ ] μ»΄ν¬λνΈ ν¬κΈ° μ μ ?
|
|
47
|
+
- [ ] Container/Presentational λΆλ¦¬?
|
|
48
|
+
|
|
49
|
+
### Accessibility (a11y)
|
|
50
|
+
- [ ] μλ§¨ν± HTML μ¬μ©?
|
|
51
|
+
- [ ] ARIA μμ± μ μ ?
|
|
52
|
+
- [ ] ν€λ³΄λ λ€λΉκ²μ΄μ
?
|
|
53
|
+
- [ ] μμ λλΉ μΆ©λΆ?
|
|
54
|
+
- [ ] alt ν
μ€νΈ?
|
|
55
|
+
|
|
56
|
+
### Error Handling
|
|
57
|
+
- [ ] Error Boundary μ¬μ©?
|
|
58
|
+
- [ ] λ‘λ©/μλ¬ μν μ²λ¦¬?
|
|
59
|
+
- [ ] Suspense νμ©?
|
|
60
|
+
- [ ] μ¬μ©μ μΉνμ μλ¬ UI?
|
|
61
|
+
|
|
62
|
+
### Performance
|
|
63
|
+
- [ ] λ²λ€ μ¬μ΄μ¦ μν₯?
|
|
64
|
+
- [ ] μ½λ μ€ν리ν
?
|
|
65
|
+
- [ ] μ΄λ―Έμ§ μ΅μ ν?
|
|
66
|
+
- [ ] κ°μν (λμ©λ 리μ€νΈ)?
|
|
67
|
+
|
|
68
|
+
## Common Anti-Patterns
|
|
69
|
+
|
|
70
|
+
```tsx
|
|
71
|
+
// β Bad: Missing dependency
|
|
72
|
+
useEffect(() => {
|
|
73
|
+
fetchData(userId);
|
|
74
|
+
}, []); // userId missing!
|
|
75
|
+
|
|
76
|
+
// β
Good: Complete dependencies
|
|
77
|
+
useEffect(() => {
|
|
78
|
+
fetchData(userId);
|
|
79
|
+
}, [userId]);
|
|
80
|
+
|
|
81
|
+
// β Bad: Object in dependency (new reference each render)
|
|
82
|
+
useEffect(() => {
|
|
83
|
+
doSomething(options);
|
|
84
|
+
}, [{ sort: 'asc' }]); // Always new object!
|
|
85
|
+
|
|
86
|
+
// β
Good: Stable reference
|
|
87
|
+
const options = useMemo(() => ({ sort: 'asc' }), []);
|
|
88
|
+
|
|
89
|
+
// β Bad: Inline function causing re-render
|
|
90
|
+
<Button onClick={() => handleClick(id)} />
|
|
91
|
+
|
|
92
|
+
// β
Good: Stable callback
|
|
93
|
+
const handleButtonClick = useCallback(() => {
|
|
94
|
+
handleClick(id);
|
|
95
|
+
}, [id]);
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Output Format
|
|
99
|
+
|
|
100
|
+
```markdown
|
|
101
|
+
## βοΈ React Review
|
|
102
|
+
|
|
103
|
+
### π΄ P1 Critical
|
|
104
|
+
1. **Missing useEffect Dependency**
|
|
105
|
+
- π Location: src/components/UserProfile.tsx:23
|
|
106
|
+
```tsx
|
|
107
|
+
// Before
|
|
108
|
+
useEffect(() => {
|
|
109
|
+
fetchUser(userId);
|
|
110
|
+
}, []); // β userId missing
|
|
111
|
+
|
|
112
|
+
// After
|
|
113
|
+
useEffect(() => {
|
|
114
|
+
fetchUser(userId);
|
|
115
|
+
}, [userId]);
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### π‘ P2 Important
|
|
119
|
+
2. **Unnecessary Re-renders**
|
|
120
|
+
- π Location: src/components/List.tsx:45
|
|
121
|
+
- π Impact: 100+ items re-render on each keystroke
|
|
122
|
+
- π‘ Fix: Use React.memo and stable callbacks
|
|
123
|
+
|
|
124
|
+
### π΅ P3 Suggestions
|
|
125
|
+
3. **Accessibility: Missing alt text**
|
|
126
|
+
- π Location: src/components/Avatar.tsx:12
|
|
127
|
+
```tsx
|
|
128
|
+
// Before
|
|
129
|
+
<img src={user.avatar} />
|
|
130
|
+
|
|
131
|
+
// After
|
|
132
|
+
<img src={user.avatar} alt={`${user.name}'s avatar`} />
|
|
133
|
+
```
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## Usage
|
|
137
|
+
|
|
138
|
+
```
|
|
139
|
+
Task(
|
|
140
|
+
model: "haiku",
|
|
141
|
+
subagent_type: "Explore",
|
|
142
|
+
prompt: "React review for [files]. Check hooks, re-renders, a11y."
|
|
143
|
+
)
|
|
144
|
+
```
|