Skip to content

Commit 383ca7c

Browse files
committed
Add code review agents.
1 parent dee8bbf commit 383ca7c

14 files changed

+1902
-0
lines changed

.cursor/agents/review-async.md

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
---
2+
name: review-async
3+
description: Reviews code for async patterns including timers, data loading, and background services. Use when reviewing files with setInterval, async functions, or service components.
4+
---
5+
6+
Review the branch/pull request in context for async pattern conventions.
7+
8+
## Context Expected
9+
10+
You will receive:
11+
- Repository name
12+
- Branch name
13+
- List of changed files to review
14+
15+
## How to Review
16+
17+
1. Read the changed files provided in context
18+
2. Look for setInterval, async data loading, background work
19+
3. Verify async patterns follow conventions
20+
4. Report findings with specific file:line references
21+
22+
---
23+
24+
## Never Use setInterval
25+
26+
Always use `makePeriodicTask` instead, especially when async work is involved:
27+
28+
```typescript
29+
// Incorrect
30+
setInterval(() => fetchData(), 5000)
31+
32+
// Correct
33+
const task = makePeriodicTask(async () => {
34+
await fetchData()
35+
}, 5000)
36+
task.start()
37+
// ... later
38+
task.stop()
39+
```
40+
41+
---
42+
43+
## Use TanStack Query or useAsyncValue
44+
45+
For async data loading in components, use TanStack Query:
46+
47+
```typescript
48+
import { useQuery } from '@tanstack/react-query'
49+
50+
const { data, isLoading } = useQuery({
51+
queryKey: ['myData'],
52+
queryFn: fetchMyData
53+
})
54+
```
55+
56+
Or use existing `useAsyncValue` hook. Don't re-implement async loading patterns.
57+
58+
---
59+
60+
## Background Services
61+
62+
Background services go in `components/services/` directory:
63+
64+
> "If we did want a persistent background service, it would go in components/services. Making it a component means it gets mounted/unmounted cleanly when we log in/out, and we can also see all the background stuff in one place."
65+
66+
Avoid too much background work. Consider:
67+
- Triggering only when the user has pending items
68+
- Running only when on the relevant scene

.cursor/agents/review-cleaners.md

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
---
2+
name: review-cleaners
3+
description: Reviews code for cleaner library usage and data validation patterns. Use when reviewing files that handle external data (API responses, disk reads).
4+
---
5+
6+
Review the branch/pull request in context for cleaner usage conventions.
7+
8+
## Context Expected
9+
10+
You will receive:
11+
- Repository name
12+
- Branch name
13+
- List of changed files to review
14+
15+
## How to Review
16+
17+
1. Read the changed files provided in context
18+
2. Look for `fetch`, API calls, file reads, or external data sources
19+
3. Verify cleaners are applied before data is used
20+
4. Check for type/cleaner duplication
21+
5. Report findings with specific file:line references
22+
23+
---
24+
25+
## Clean All External Data
26+
27+
All network requests and data reads from disk must be cleaned with the cleaners library. Code must access the cleaned values, not the original raw/untyped data object.
28+
29+
---
30+
31+
## Let Cleaners Handle Parsing
32+
33+
Use cleaners for JSON parsing instead of double-parsing:
34+
35+
```typescript
36+
// Incorrect
37+
const data = JSON.parse(response)
38+
const cleaned = asMyType(data)
39+
40+
// Correct - let cleaners handle it
41+
const asMyResponse = asJSON(asObject({
42+
field: asString
43+
}))
44+
const cleaned = asMyResponse(response)
45+
```
46+
47+
---
48+
49+
## No Duplicate Types
50+
51+
Types should be derived from cleaners using `ReturnType` syntax. Do not duplicate type definitions:
52+
53+
```typescript
54+
// Incorrect - duplicated type
55+
interface MyData {
56+
name: string
57+
value: number
58+
}
59+
const asMyData = asObject({
60+
name: asString,
61+
value: asNumber
62+
})
63+
64+
// Correct - derive type from cleaner
65+
const asMyData = asObject({
66+
name: asString,
67+
value: asNumber
68+
})
69+
type MyData = ReturnType<typeof asMyData>
70+
```
71+
72+
---
73+
74+
## Remove Unused Fields
75+
76+
Remove or comment out any fields in a cleaner that are unused in the codebase.
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
---
2+
name: review-code-quality
3+
description: Reviews code for general quality patterns including naming, dead code, and code organization. Use for general code quality review.
4+
---
5+
6+
Review the branch/pull request in context for code quality conventions.
7+
8+
## Context Expected
9+
10+
You will receive:
11+
- Repository name
12+
- Branch name
13+
- List of changed files to review
14+
15+
## How to Review
16+
17+
1. Read the changed files provided in context
18+
2. Check for naming, dead code, organization issues
19+
3. Verify code quality follows conventions
20+
4. Report findings with specific file:line references
21+
22+
---
23+
24+
## Delete Unnecessary Code
25+
26+
Don't leave dead or unused code in the codebase:
27+
28+
```typescript
29+
// Incorrect - leaving unused code "just in case"
30+
const unusedVariable = calculateSomething()
31+
// Maybe useful later?
32+
33+
// Correct - delete it
34+
// (If needed later, git history has it)
35+
```
36+
37+
---
38+
39+
## Use Meaningful Variable Names
40+
41+
Avoid abbreviations that aren't immediately clear:
42+
43+
```typescript
44+
// Incorrect - unclear abbreviation
45+
const kavProps = { ... }
46+
47+
// Correct - descriptive name
48+
const avoidKeyboard = { ... }
49+
// or
50+
const keyboardAvoidingProps = { ... }
51+
```
52+
53+
---
54+
55+
## Put Parameters Inline
56+
57+
Don't declare variables just to pass them to a function:
58+
59+
```typescript
60+
// Incorrect - old pattern
61+
const params = {
62+
txid: transaction.txid,
63+
tokenId: tokenId,
64+
metadata: metadataToSave
65+
}
66+
await wallet.saveTxMetadata(params)
67+
68+
// Correct - inline parameters
69+
await wallet.saveTxMetadata({
70+
txid: transaction.txid,
71+
tokenId: tokenId,
72+
metadata: metadataToSave
73+
})
74+
```
75+
76+
Only exception is when calling a function that has unknown type parameters. Use a typed constant to ensure the call provides the correct parameters:
77+
78+
```typescript
79+
interface CreateUserBody {
80+
username: string
81+
email: string
82+
role: 'admin' | 'user'
83+
}
84+
85+
// Correct - typed constant ensures body matches expected schema
86+
const body: CreateUserBody = {
87+
username: 'john',
88+
email: 'john@example.com',
89+
role: 'admin'
90+
}
91+
await fetch('/api/users', {
92+
method: 'POST',
93+
body: JSON.stringify(body)
94+
})
95+
```
96+
97+
This pattern catches type errors at compile time when the API contract changes.
98+
99+
---
100+
101+
## Use Existing Helpers
102+
103+
Use existing helper functions instead of creating new ones:
104+
105+
```typescript
106+
// Incorrect - creating redundant helper
107+
const getCurrencyCodeMultiplier = (config, code) => { ... }
108+
109+
// Correct - use existing helper
110+
const { multiplier } = getExchangeDenom(currencyConfig, tokenId)
111+
```
112+
113+
Before creating a new utility, check if an existing one serves the purpose:
114+
- `getTokenId` / `getTokenIdForced` instead of `getWalletTokenId`
115+
- `getExchangeDenom` instead of custom multiplier lookups
116+
117+
---
118+
119+
## Avoid Duplicated Mock Data
120+
121+
Use existing mock data from `src/util/fake/` or consolidate new mocks there:
122+
123+
> "We have been plagued by lots of duplicated, half-baked mock data. This makes it hard to perform core changes without breaking things. Our goal is to reduce the duplication over time, not add to it."
124+
125+
---
126+
127+
## Optimize Search Functions
128+
129+
Move expensive operations outside loops:
130+
131+
```typescript
132+
// Incorrect - calls normalizeForSearch for each term
133+
searchTerms.every(term => {
134+
const normalCurrencyCode = normalizeForSearch(currencyCode)
135+
return normalCurrencyCode.startsWith(term)
136+
})
137+
138+
// Correct - normalize once outside the loop
139+
const normalCurrencyCode = normalizeForSearch(currencyCode)
140+
const normalDisplayName = normalizeForSearch(displayName)
141+
142+
return searchTerms.every(term =>
143+
normalCurrencyCode.startsWith(term) ||
144+
normalDisplayName.startsWith(term)
145+
)
146+
```
147+
148+
Combine conditions into single `||` chains instead of nested `if`/`return` blocks.

.cursor/agents/review-comments.md

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
---
2+
name: review-comments
3+
description: Reviews code for comment quality and documentation patterns. Use when reviewing files for documentation accuracy.
4+
---
5+
6+
Review the branch/pull request in context for comment conventions.
7+
8+
## Context Expected
9+
10+
You will receive:
11+
- Repository name
12+
- Branch name
13+
- List of changed files to review
14+
15+
## How to Review
16+
17+
1. Read the changed files provided in context
18+
2. Check comments for accuracy and necessity
19+
3. Look for missing documentation on non-obvious code
20+
4. Report findings with specific file:line references
21+
22+
---
23+
24+
## Add Non-Obvious Constraints
25+
26+
Document constraints that aren't obvious from the code:
27+
28+
```typescript
29+
// EVM-only: This conversion assumes EVM contract address format
30+
const tokenId = contractAddress.toLowerCase()
31+
```
32+
33+
---
34+
35+
## Remove Stale Comments
36+
37+
Remove comments when the context they describe has changed:
38+
39+
```typescript
40+
// Incorrect - comment no longer needed after refactor
41+
// This is a workaround for bug XYZ
42+
const result = normalFunction()
43+
44+
// Correct - just remove the comment
45+
const result = normalFunction()
46+
```
47+
48+
---
49+
50+
## Comments Should Explain Why, Not What
51+
52+
Good comments explain the reasoning, not the mechanics:
53+
54+
```typescript
55+
// Incorrect - describes what code does (obvious)
56+
// Loop through items and filter by status
57+
const filtered = items.filter(item => item.status === 'active')
58+
59+
// Correct - explains why
60+
// Only active items can be edited; archived items are read-only
61+
const filtered = items.filter(item => item.status === 'active')
62+
```
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
---
2+
name: review-edge-exchange-plugins
3+
description: Reviews edge-exchange-plugins code for compliance with provider API requirements. Use when reviewing exchange plugin implementations.
4+
---
5+
6+
Review the branch/pull request for compliance with Edge exchange provider API requirements.
7+
8+
## Context Expected
9+
10+
You will receive:
11+
- Repository name (edge-exchange-plugins)
12+
- Branch name
13+
- List of changed files to review
14+
15+
## How to Review
16+
17+
1. Read the API requirements document: `docs/exchange_plugin_api_requirements.md`
18+
2. Read the changed plugin files provided in context
19+
3. Verify the plugin implementation meets each applicable requirement
20+
4. Report findings with specific file:line references

0 commit comments

Comments
 (0)