mirror of
https://github.com/affaan-m/everything-claude-code.git
synced 2026-03-30 21:53:28 +08:00
Compare commits
223 Commits
8e55f4f117
...
fix/deskto
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2595c92983 | ||
|
|
99ff568c0e | ||
|
|
3d5ae70c74 | ||
|
|
4ea72dec99 | ||
|
|
02206e87a5 | ||
|
|
76c13ac5fb | ||
|
|
2c1ae27a3a | ||
|
|
d9d16a0d4a | ||
|
|
a57c3c5dd5 | ||
|
|
cff28efb34 | ||
|
|
b575f2e3eb | ||
|
|
0f065af311 | ||
|
|
ded5d826a4 | ||
|
|
ae272da28d | ||
|
|
c39aa22c5a | ||
|
|
7483d646e4 | ||
|
|
432a45274e | ||
|
|
866d9ebb53 | ||
|
|
dd675d4258 | ||
|
|
db12d3d838 | ||
|
|
46f37ae4fb | ||
|
|
0c166e14da | ||
|
|
527c79350c | ||
|
|
0ebcfc368e | ||
|
|
bec1ebf76d | ||
|
|
be76918850 | ||
|
|
99a154a908 | ||
|
|
ebf0f135bb | ||
|
|
2d27da52e2 | ||
|
|
65c4a0f6ba | ||
|
|
ab49c9adf5 | ||
|
|
b7a82cf240 | ||
|
|
9a55fd069b | ||
|
|
d9e8305aa1 | ||
|
|
f2bf72c005 | ||
|
|
3ae0df781f | ||
|
|
a346a304b0 | ||
|
|
81acf0c928 | ||
|
|
06a77911e6 | ||
|
|
9406f35fab | ||
|
|
c5e3658ba6 | ||
|
|
eeeea506a6 | ||
|
|
fc1ea4fbea | ||
|
|
00787d68e4 | ||
|
|
1e3572becf | ||
|
|
7462168377 | ||
|
|
3c3781ca43 | ||
|
|
27d71c9548 | ||
|
|
6f16e75f9d | ||
|
|
0d30da1fc7 | ||
|
|
e686bcbc82 | ||
|
|
25c8a5de08 | ||
|
|
ec104c94c5 | ||
|
|
14a51404c0 | ||
|
|
666c639206 | ||
|
|
a8e088a54e | ||
|
|
eac0228f88 | ||
|
|
b6e3434ff4 | ||
|
|
4eaee83448 | ||
|
|
1e43639cc7 | ||
|
|
766f846478 | ||
|
|
dd38518afe | ||
|
|
c1d98b071e | ||
|
|
70b98f3178 | ||
|
|
dcc4d914d2 | ||
|
|
71219ff656 | ||
|
|
e815f0d05c | ||
|
|
b3a43f34e6 | ||
|
|
0d26f5295d | ||
|
|
9181382065 | ||
|
|
9434e07749 | ||
|
|
9cde3427e2 | ||
|
|
c6b4c719b2 | ||
|
|
f98207feea | ||
|
|
52e9bd58f1 | ||
|
|
4257c093ca | ||
|
|
23d743b92c | ||
|
|
414ea90e11 | ||
|
|
d473cf87e6 | ||
|
|
64847d0a21 | ||
|
|
c865d4c676 | ||
|
|
72de19effd | ||
|
|
56076edd48 | ||
|
|
04d7eeb16f | ||
|
|
4e7773c2ce | ||
|
|
a3fc90f7ac | ||
|
|
55efeb7f20 | ||
|
|
1e7c299706 | ||
|
|
47aa415b06 | ||
|
|
d7e6bb242a | ||
|
|
9f37a5d8c7 | ||
|
|
d9ec51c9e9 | ||
|
|
9033f2a997 | ||
|
|
67660540ac | ||
|
|
432788d0b5 | ||
|
|
6a7a115e18 | ||
|
|
1181d93498 | ||
|
|
80d6a89f12 | ||
|
|
28a1fbc3f2 | ||
|
|
4fcaaf8a89 | ||
|
|
7a4cb8c570 | ||
|
|
4b4f077d18 | ||
|
|
78c98dd4fd | ||
|
|
f07797533d | ||
|
|
87d883eb1b | ||
|
|
652f87c5b6 | ||
|
|
70b65a9d06 | ||
|
|
24674a7bd6 | ||
|
|
d49c95a5ec | ||
|
|
70a96bd363 | ||
|
|
8f7445a260 | ||
|
|
9ad4351f53 | ||
|
|
451732164f | ||
|
|
ebd14cde7d | ||
|
|
ae21a8df85 | ||
|
|
d8e3b9d593 | ||
|
|
7148d9006f | ||
|
|
c14765e701 | ||
|
|
194bc0000b | ||
|
|
1e44475458 | ||
|
|
31af1adcc8 | ||
|
|
c80631fc1d | ||
|
|
00f8628b83 | ||
|
|
ba09a34432 | ||
|
|
27e0d53f6d | ||
|
|
8b6140dedc | ||
|
|
7633386e04 | ||
|
|
b4296c7095 | ||
|
|
17f6f95090 | ||
|
|
1e226ba556 | ||
|
|
cc60bf6b65 | ||
|
|
160624d0ed | ||
|
|
73c10122fe | ||
|
|
9b24bedf85 | ||
|
|
e3f2bda9fc | ||
|
|
fe6a6fc106 | ||
|
|
63737544a1 | ||
|
|
dafc9bcd60 | ||
|
|
2d0fddf174 | ||
|
|
f471f27658 | ||
|
|
925d830c53 | ||
|
|
2243f15581 | ||
|
|
6408511611 | ||
|
|
9348751b8e | ||
|
|
c96c4d2742 | ||
|
|
da74f85c10 | ||
|
|
c146fae2ce | ||
|
|
3f5e042b40 | ||
|
|
b5148f184a | ||
|
|
b44ba7096f | ||
|
|
45baaa1ea5 | ||
|
|
4da1fb388c | ||
|
|
917c35bb6f | ||
|
|
ee3f348dcb | ||
|
|
e6eb99271f | ||
|
|
7cabf77142 | ||
|
|
9cfcfac665 | ||
|
|
0284f60871 | ||
|
|
7a17ec9b14 | ||
|
|
243fae8476 | ||
|
|
dc92b5c62b | ||
|
|
3fbfd7f7ff | ||
|
|
a6a81490f6 | ||
|
|
d170cdd175 | ||
|
|
57e9983c88 | ||
|
|
d952a07c73 | ||
|
|
369f66297a | ||
|
|
9cc5d085e1 | ||
|
|
678fb6f0d3 | ||
|
|
401e26a45a | ||
|
|
eb934afbb5 | ||
|
|
8303970258 | ||
|
|
319f9efafb | ||
|
|
6c2a3a2bae | ||
|
|
adaeab9dba | ||
|
|
8981dd6067 | ||
|
|
7229e09df1 | ||
|
|
4105a2f36c | ||
|
|
0166231ddb | ||
|
|
cf439dd481 | ||
|
|
9903ae528b | ||
|
|
44c2bf6f7b | ||
|
|
e78c092499 | ||
|
|
61f70de479 | ||
|
|
776ac439f3 | ||
|
|
b19b4c6b5e | ||
|
|
b5157f4ed1 | ||
|
|
2d1e384eef | ||
|
|
9c5ca92e6e | ||
|
|
7b510c886e | ||
|
|
c1b47ac9db | ||
|
|
3f02fa439a | ||
|
|
f6b10481f3 | ||
|
|
d3699f9010 | ||
|
|
445ae5099d | ||
|
|
00bc7f30be | ||
|
|
1d0aa5ac2a | ||
|
|
7f7e319d9f | ||
|
|
d7bcc92007 | ||
|
|
e883385ab0 | ||
|
|
e7d827548c | ||
|
|
bf7ed1fce2 | ||
|
|
fee93f2dab | ||
|
|
a61947bb5c | ||
|
|
3c59d8dc60 | ||
|
|
46f6e3644b | ||
|
|
39a34e46db | ||
|
|
95a1435f61 | ||
|
|
e57ad5c33d | ||
|
|
f7d589ce21 | ||
|
|
2787b8e92f | ||
|
|
2166d80d58 | ||
|
|
9c381b4469 | ||
|
|
e3510f62a8 | ||
|
|
7726c25e46 | ||
|
|
6af7ca1afc | ||
|
|
d6061cf937 | ||
|
|
ec921e5202 | ||
|
|
d016e68cee | ||
|
|
aed18eb571 | ||
|
|
f3cf808814 | ||
|
|
e22cb57718 | ||
|
|
4811e8c73b |
20
.agents/plugins/marketplace.json
Normal file
20
.agents/plugins/marketplace.json
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"name": "everything-claude-code",
|
||||
"interface": {
|
||||
"displayName": "Everything Claude Code"
|
||||
},
|
||||
"plugins": [
|
||||
{
|
||||
"name": "everything-claude-code",
|
||||
"source": {
|
||||
"source": "local",
|
||||
"path": "../.."
|
||||
},
|
||||
"policy": {
|
||||
"installation": "AVAILABLE",
|
||||
"authentication": "ON_INSTALL"
|
||||
},
|
||||
"category": "Productivity"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -23,7 +23,7 @@ Backend architecture patterns and best practices for scalable server-side applic
|
||||
### RESTful API Structure
|
||||
|
||||
```typescript
|
||||
// ✅ Resource-based URLs
|
||||
// PASS: Resource-based URLs
|
||||
GET /api/markets # List resources
|
||||
GET /api/markets/:id # Get single resource
|
||||
POST /api/markets # Create resource
|
||||
@@ -31,7 +31,7 @@ PUT /api/markets/:id # Replace resource
|
||||
PATCH /api/markets/:id # Update resource
|
||||
DELETE /api/markets/:id # Delete resource
|
||||
|
||||
// ✅ Query parameters for filtering, sorting, pagination
|
||||
// PASS: Query parameters for filtering, sorting, pagination
|
||||
GET /api/markets?status=active&sort=volume&limit=20&offset=0
|
||||
```
|
||||
|
||||
@@ -131,7 +131,7 @@ export default withAuth(async (req, res) => {
|
||||
### Query Optimization
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Select only needed columns
|
||||
// PASS: GOOD: Select only needed columns
|
||||
const { data } = await supabase
|
||||
.from('markets')
|
||||
.select('id, name, status, volume')
|
||||
@@ -139,7 +139,7 @@ const { data } = await supabase
|
||||
.order('volume', { ascending: false })
|
||||
.limit(10)
|
||||
|
||||
// ❌ BAD: Select everything
|
||||
// FAIL: BAD: Select everything
|
||||
const { data } = await supabase
|
||||
.from('markets')
|
||||
.select('*')
|
||||
@@ -148,13 +148,13 @@ const { data } = await supabase
|
||||
### N+1 Query Prevention
|
||||
|
||||
```typescript
|
||||
// ❌ BAD: N+1 query problem
|
||||
// FAIL: BAD: N+1 query problem
|
||||
const markets = await getMarkets()
|
||||
for (const market of markets) {
|
||||
market.creator = await getUser(market.creator_id) // N queries
|
||||
}
|
||||
|
||||
// ✅ GOOD: Batch fetch
|
||||
// PASS: GOOD: Batch fetch
|
||||
const markets = await getMarkets()
|
||||
const creatorIds = markets.map(m => m.creator_id)
|
||||
const creators = await getUsers(creatorIds) // 1 query
|
||||
|
||||
@@ -48,12 +48,12 @@ Universal coding standards applicable across all projects.
|
||||
### Variable Naming
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Descriptive names
|
||||
// PASS: GOOD: Descriptive names
|
||||
const marketSearchQuery = 'election'
|
||||
const isUserAuthenticated = true
|
||||
const totalRevenue = 1000
|
||||
|
||||
// ❌ BAD: Unclear names
|
||||
// FAIL: BAD: Unclear names
|
||||
const q = 'election'
|
||||
const flag = true
|
||||
const x = 1000
|
||||
@@ -62,12 +62,12 @@ const x = 1000
|
||||
### Function Naming
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Verb-noun pattern
|
||||
// PASS: GOOD: Verb-noun pattern
|
||||
async function fetchMarketData(marketId: string) { }
|
||||
function calculateSimilarity(a: number[], b: number[]) { }
|
||||
function isValidEmail(email: string): boolean { }
|
||||
|
||||
// ❌ BAD: Unclear or noun-only
|
||||
// FAIL: BAD: Unclear or noun-only
|
||||
async function market(id: string) { }
|
||||
function similarity(a, b) { }
|
||||
function email(e) { }
|
||||
@@ -76,7 +76,7 @@ function email(e) { }
|
||||
### Immutability Pattern (CRITICAL)
|
||||
|
||||
```typescript
|
||||
// ✅ ALWAYS use spread operator
|
||||
// PASS: ALWAYS use spread operator
|
||||
const updatedUser = {
|
||||
...user,
|
||||
name: 'New Name'
|
||||
@@ -84,7 +84,7 @@ const updatedUser = {
|
||||
|
||||
const updatedArray = [...items, newItem]
|
||||
|
||||
// ❌ NEVER mutate directly
|
||||
// FAIL: NEVER mutate directly
|
||||
user.name = 'New Name' // BAD
|
||||
items.push(newItem) // BAD
|
||||
```
|
||||
@@ -92,7 +92,7 @@ items.push(newItem) // BAD
|
||||
### Error Handling
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Comprehensive error handling
|
||||
// PASS: GOOD: Comprehensive error handling
|
||||
async function fetchData(url: string) {
|
||||
try {
|
||||
const response = await fetch(url)
|
||||
@@ -108,7 +108,7 @@ async function fetchData(url: string) {
|
||||
}
|
||||
}
|
||||
|
||||
// ❌ BAD: No error handling
|
||||
// FAIL: BAD: No error handling
|
||||
async function fetchData(url) {
|
||||
const response = await fetch(url)
|
||||
return response.json()
|
||||
@@ -118,14 +118,14 @@ async function fetchData(url) {
|
||||
### Async/Await Best Practices
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Parallel execution when possible
|
||||
// PASS: GOOD: Parallel execution when possible
|
||||
const [users, markets, stats] = await Promise.all([
|
||||
fetchUsers(),
|
||||
fetchMarkets(),
|
||||
fetchStats()
|
||||
])
|
||||
|
||||
// ❌ BAD: Sequential when unnecessary
|
||||
// FAIL: BAD: Sequential when unnecessary
|
||||
const users = await fetchUsers()
|
||||
const markets = await fetchMarkets()
|
||||
const stats = await fetchStats()
|
||||
@@ -134,7 +134,7 @@ const stats = await fetchStats()
|
||||
### Type Safety
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Proper types
|
||||
// PASS: GOOD: Proper types
|
||||
interface Market {
|
||||
id: string
|
||||
name: string
|
||||
@@ -146,7 +146,7 @@ function getMarket(id: string): Promise<Market> {
|
||||
// Implementation
|
||||
}
|
||||
|
||||
// ❌ BAD: Using 'any'
|
||||
// FAIL: BAD: Using 'any'
|
||||
function getMarket(id: any): Promise<any> {
|
||||
// Implementation
|
||||
}
|
||||
@@ -157,7 +157,7 @@ function getMarket(id: any): Promise<any> {
|
||||
### Component Structure
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Functional component with types
|
||||
// PASS: GOOD: Functional component with types
|
||||
interface ButtonProps {
|
||||
children: React.ReactNode
|
||||
onClick: () => void
|
||||
@@ -182,7 +182,7 @@ export function Button({
|
||||
)
|
||||
}
|
||||
|
||||
// ❌ BAD: No types, unclear structure
|
||||
// FAIL: BAD: No types, unclear structure
|
||||
export function Button(props) {
|
||||
return <button onClick={props.onClick}>{props.children}</button>
|
||||
}
|
||||
@@ -191,7 +191,7 @@ export function Button(props) {
|
||||
### Custom Hooks
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Reusable custom hook
|
||||
// PASS: GOOD: Reusable custom hook
|
||||
export function useDebounce<T>(value: T, delay: number): T {
|
||||
const [debouncedValue, setDebouncedValue] = useState<T>(value)
|
||||
|
||||
@@ -213,25 +213,25 @@ const debouncedQuery = useDebounce(searchQuery, 500)
|
||||
### State Management
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Proper state updates
|
||||
// PASS: GOOD: Proper state updates
|
||||
const [count, setCount] = useState(0)
|
||||
|
||||
// Functional update for state based on previous state
|
||||
setCount(prev => prev + 1)
|
||||
|
||||
// ❌ BAD: Direct state reference
|
||||
// FAIL: BAD: Direct state reference
|
||||
setCount(count + 1) // Can be stale in async scenarios
|
||||
```
|
||||
|
||||
### Conditional Rendering
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Clear conditional rendering
|
||||
// PASS: GOOD: Clear conditional rendering
|
||||
{isLoading && <Spinner />}
|
||||
{error && <ErrorMessage error={error} />}
|
||||
{data && <DataDisplay data={data} />}
|
||||
|
||||
// ❌ BAD: Ternary hell
|
||||
// FAIL: BAD: Ternary hell
|
||||
{isLoading ? <Spinner /> : error ? <ErrorMessage error={error} /> : data ? <DataDisplay data={data} /> : null}
|
||||
```
|
||||
|
||||
@@ -254,7 +254,7 @@ GET /api/markets?status=active&limit=10&offset=0
|
||||
### Response Format
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Consistent response structure
|
||||
// PASS: GOOD: Consistent response structure
|
||||
interface ApiResponse<T> {
|
||||
success: boolean
|
||||
data?: T
|
||||
@@ -285,7 +285,7 @@ return NextResponse.json({
|
||||
```typescript
|
||||
import { z } from 'zod'
|
||||
|
||||
// ✅ GOOD: Schema validation
|
||||
// PASS: GOOD: Schema validation
|
||||
const CreateMarketSchema = z.object({
|
||||
name: z.string().min(1).max(200),
|
||||
description: z.string().min(1).max(2000),
|
||||
@@ -348,14 +348,14 @@ types/market.types.ts # camelCase with .types suffix
|
||||
### When to Comment
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Explain WHY, not WHAT
|
||||
// PASS: GOOD: Explain WHY, not WHAT
|
||||
// Use exponential backoff to avoid overwhelming the API during outages
|
||||
const delay = Math.min(1000 * Math.pow(2, retryCount), 30000)
|
||||
|
||||
// Deliberately using mutation here for performance with large arrays
|
||||
items.push(newItem)
|
||||
|
||||
// ❌ BAD: Stating the obvious
|
||||
// FAIL: BAD: Stating the obvious
|
||||
// Increment counter by 1
|
||||
count++
|
||||
|
||||
@@ -395,12 +395,12 @@ export async function searchMarkets(
|
||||
```typescript
|
||||
import { useMemo, useCallback } from 'react'
|
||||
|
||||
// ✅ GOOD: Memoize expensive computations
|
||||
// PASS: GOOD: Memoize expensive computations
|
||||
const sortedMarkets = useMemo(() => {
|
||||
return markets.sort((a, b) => b.volume - a.volume)
|
||||
}, [markets])
|
||||
|
||||
// ✅ GOOD: Memoize callbacks
|
||||
// PASS: GOOD: Memoize callbacks
|
||||
const handleSearch = useCallback((query: string) => {
|
||||
setSearchQuery(query)
|
||||
}, [])
|
||||
@@ -411,7 +411,7 @@ const handleSearch = useCallback((query: string) => {
|
||||
```typescript
|
||||
import { lazy, Suspense } from 'react'
|
||||
|
||||
// ✅ GOOD: Lazy load heavy components
|
||||
// PASS: GOOD: Lazy load heavy components
|
||||
const HeavyChart = lazy(() => import('./HeavyChart'))
|
||||
|
||||
export function Dashboard() {
|
||||
@@ -426,13 +426,13 @@ export function Dashboard() {
|
||||
### Database Queries
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Select only needed columns
|
||||
// PASS: GOOD: Select only needed columns
|
||||
const { data } = await supabase
|
||||
.from('markets')
|
||||
.select('id, name, status')
|
||||
.limit(10)
|
||||
|
||||
// ❌ BAD: Select everything
|
||||
// FAIL: BAD: Select everything
|
||||
const { data } = await supabase
|
||||
.from('markets')
|
||||
.select('*')
|
||||
@@ -459,12 +459,12 @@ test('calculates similarity correctly', () => {
|
||||
### Test Naming
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Descriptive test names
|
||||
// PASS: GOOD: Descriptive test names
|
||||
test('returns empty array when no markets match query', () => { })
|
||||
test('throws error when OpenAI API key is missing', () => { })
|
||||
test('falls back to substring search when Redis unavailable', () => { })
|
||||
|
||||
// ❌ BAD: Vague test names
|
||||
// FAIL: BAD: Vague test names
|
||||
test('works', () => { })
|
||||
test('test search', () => { })
|
||||
```
|
||||
@@ -475,12 +475,12 @@ Watch for these anti-patterns:
|
||||
|
||||
### 1. Long Functions
|
||||
```typescript
|
||||
// ❌ BAD: Function > 50 lines
|
||||
// FAIL: BAD: Function > 50 lines
|
||||
function processMarketData() {
|
||||
// 100 lines of code
|
||||
}
|
||||
|
||||
// ✅ GOOD: Split into smaller functions
|
||||
// PASS: GOOD: Split into smaller functions
|
||||
function processMarketData() {
|
||||
const validated = validateData()
|
||||
const transformed = transformData(validated)
|
||||
@@ -490,7 +490,7 @@ function processMarketData() {
|
||||
|
||||
### 2. Deep Nesting
|
||||
```typescript
|
||||
// ❌ BAD: 5+ levels of nesting
|
||||
// FAIL: BAD: 5+ levels of nesting
|
||||
if (user) {
|
||||
if (user.isAdmin) {
|
||||
if (market) {
|
||||
@@ -503,7 +503,7 @@ if (user) {
|
||||
}
|
||||
}
|
||||
|
||||
// ✅ GOOD: Early returns
|
||||
// PASS: GOOD: Early returns
|
||||
if (!user) return
|
||||
if (!user.isAdmin) return
|
||||
if (!market) return
|
||||
@@ -515,11 +515,11 @@ if (!hasPermission) return
|
||||
|
||||
### 3. Magic Numbers
|
||||
```typescript
|
||||
// ❌ BAD: Unexplained numbers
|
||||
// FAIL: BAD: Unexplained numbers
|
||||
if (retryCount > 3) { }
|
||||
setTimeout(callback, 500)
|
||||
|
||||
// ✅ GOOD: Named constants
|
||||
// PASS: GOOD: Named constants
|
||||
const MAX_RETRIES = 3
|
||||
const DEBOUNCE_DELAY_MS = 500
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ Modern frontend patterns for React, Next.js, and performant user interfaces.
|
||||
### Composition Over Inheritance
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Component composition
|
||||
// PASS: GOOD: Component composition
|
||||
interface CardProps {
|
||||
children: React.ReactNode
|
||||
variant?: 'default' | 'outlined'
|
||||
@@ -294,17 +294,17 @@ export function useMarkets() {
|
||||
### Memoization
|
||||
|
||||
```typescript
|
||||
// ✅ useMemo for expensive computations
|
||||
// PASS: useMemo for expensive computations
|
||||
const sortedMarkets = useMemo(() => {
|
||||
return markets.sort((a, b) => b.volume - a.volume)
|
||||
}, [markets])
|
||||
|
||||
// ✅ useCallback for functions passed to children
|
||||
// PASS: useCallback for functions passed to children
|
||||
const handleSearch = useCallback((query: string) => {
|
||||
setSearchQuery(query)
|
||||
}, [])
|
||||
|
||||
// ✅ React.memo for pure components
|
||||
// PASS: React.memo for pure components
|
||||
export const MarketCard = React.memo<MarketCardProps>(({ market }) => {
|
||||
return (
|
||||
<div className="market-card">
|
||||
@@ -320,7 +320,7 @@ export const MarketCard = React.memo<MarketCardProps>(({ market }) => {
|
||||
```typescript
|
||||
import { lazy, Suspense } from 'react'
|
||||
|
||||
// ✅ Lazy load heavy components
|
||||
// PASS: Lazy load heavy components
|
||||
const HeavyChart = lazy(() => import('./HeavyChart'))
|
||||
const ThreeJsBackground = lazy(() => import('./ThreeJsBackground'))
|
||||
|
||||
@@ -515,7 +515,7 @@ export class ErrorBoundary extends React.Component<
|
||||
```typescript
|
||||
import { motion, AnimatePresence } from 'framer-motion'
|
||||
|
||||
// ✅ List animations
|
||||
// PASS: List animations
|
||||
export function AnimatedMarketList({ markets }: { markets: Market[] }) {
|
||||
return (
|
||||
<AnimatePresence>
|
||||
@@ -534,7 +534,7 @@ export function AnimatedMarketList({ markets }: { markets: Market[] }) {
|
||||
)
|
||||
}
|
||||
|
||||
// ✅ Modal animations
|
||||
// PASS: Modal animations
|
||||
export function Modal({ isOpen, onClose, children }: ModalProps) {
|
||||
return (
|
||||
<AnimatePresence>
|
||||
|
||||
@@ -22,13 +22,13 @@ This skill ensures all code follows security best practices and identifies poten
|
||||
|
||||
### 1. Secrets Management
|
||||
|
||||
#### ❌ NEVER Do This
|
||||
#### FAIL: NEVER Do This
|
||||
```typescript
|
||||
const apiKey = "sk-proj-xxxxx" // Hardcoded secret
|
||||
const dbPassword = "password123" // In source code
|
||||
```
|
||||
|
||||
#### ✅ ALWAYS Do This
|
||||
#### PASS: ALWAYS Do This
|
||||
```typescript
|
||||
const apiKey = process.env.OPENAI_API_KEY
|
||||
const dbUrl = process.env.DATABASE_URL
|
||||
@@ -108,14 +108,14 @@ function validateFileUpload(file: File) {
|
||||
|
||||
### 3. SQL Injection Prevention
|
||||
|
||||
#### ❌ NEVER Concatenate SQL
|
||||
#### FAIL: NEVER Concatenate SQL
|
||||
```typescript
|
||||
// DANGEROUS - SQL Injection vulnerability
|
||||
const query = `SELECT * FROM users WHERE email = '${userEmail}'`
|
||||
await db.query(query)
|
||||
```
|
||||
|
||||
#### ✅ ALWAYS Use Parameterized Queries
|
||||
#### PASS: ALWAYS Use Parameterized Queries
|
||||
```typescript
|
||||
// Safe - parameterized query
|
||||
const { data } = await supabase
|
||||
@@ -140,10 +140,10 @@ await db.query(
|
||||
|
||||
#### JWT Token Handling
|
||||
```typescript
|
||||
// ❌ WRONG: localStorage (vulnerable to XSS)
|
||||
// FAIL: WRONG: localStorage (vulnerable to XSS)
|
||||
localStorage.setItem('token', token)
|
||||
|
||||
// ✅ CORRECT: httpOnly cookies
|
||||
// PASS: CORRECT: httpOnly cookies
|
||||
res.setHeader('Set-Cookie',
|
||||
`token=${token}; HttpOnly; Secure; SameSite=Strict; Max-Age=3600`)
|
||||
```
|
||||
@@ -300,18 +300,18 @@ app.use('/api/search', searchLimiter)
|
||||
|
||||
#### Logging
|
||||
```typescript
|
||||
// ❌ WRONG: Logging sensitive data
|
||||
// FAIL: WRONG: Logging sensitive data
|
||||
console.log('User login:', { email, password })
|
||||
console.log('Payment:', { cardNumber, cvv })
|
||||
|
||||
// ✅ CORRECT: Redact sensitive data
|
||||
// PASS: CORRECT: Redact sensitive data
|
||||
console.log('User login:', { email, userId })
|
||||
console.log('Payment:', { last4: card.last4, userId })
|
||||
```
|
||||
|
||||
#### Error Messages
|
||||
```typescript
|
||||
// ❌ WRONG: Exposing internal details
|
||||
// FAIL: WRONG: Exposing internal details
|
||||
catch (error) {
|
||||
return NextResponse.json(
|
||||
{ error: error.message, stack: error.stack },
|
||||
@@ -319,7 +319,7 @@ catch (error) {
|
||||
)
|
||||
}
|
||||
|
||||
// ✅ CORRECT: Generic error messages
|
||||
// PASS: CORRECT: Generic error messages
|
||||
catch (error) {
|
||||
console.error('Internal error:', error)
|
||||
return NextResponse.json(
|
||||
|
||||
@@ -314,39 +314,39 @@ npm run test:coverage
|
||||
|
||||
## Common Testing Mistakes to Avoid
|
||||
|
||||
### ❌ WRONG: Testing Implementation Details
|
||||
### FAIL: WRONG: Testing Implementation Details
|
||||
```typescript
|
||||
// Don't test internal state
|
||||
expect(component.state.count).toBe(5)
|
||||
```
|
||||
|
||||
### ✅ CORRECT: Test User-Visible Behavior
|
||||
### PASS: CORRECT: Test User-Visible Behavior
|
||||
```typescript
|
||||
// Test what users see
|
||||
expect(screen.getByText('Count: 5')).toBeInTheDocument()
|
||||
```
|
||||
|
||||
### ❌ WRONG: Brittle Selectors
|
||||
### FAIL: WRONG: Brittle Selectors
|
||||
```typescript
|
||||
// Breaks easily
|
||||
await page.click('.css-class-xyz')
|
||||
```
|
||||
|
||||
### ✅ CORRECT: Semantic Selectors
|
||||
### PASS: CORRECT: Semantic Selectors
|
||||
```typescript
|
||||
// Resilient to changes
|
||||
await page.click('button:has-text("Submit")')
|
||||
await page.click('[data-testid="submit-button"]')
|
||||
```
|
||||
|
||||
### ❌ WRONG: No Test Isolation
|
||||
### FAIL: WRONG: No Test Isolation
|
||||
```typescript
|
||||
// Tests depend on each other
|
||||
test('creates user', () => { /* ... */ })
|
||||
test('updates same user', () => { /* depends on previous test */ })
|
||||
```
|
||||
|
||||
### ✅ CORRECT: Independent Tests
|
||||
### PASS: CORRECT: Independent Tests
|
||||
```typescript
|
||||
// Each test sets up its own data
|
||||
test('creates user', () => {
|
||||
|
||||
@@ -120,7 +120,7 @@ Assume the validator is hostile and literal.
|
||||
|
||||
## The `hooks` Field: DO NOT ADD
|
||||
|
||||
> ⚠️ **CRITICAL:** Do NOT add a `"hooks"` field to `plugin.json`. This is enforced by a regression test.
|
||||
> WARNING: **CRITICAL:** Do NOT add a `"hooks"` field to `plugin.json`. This is enforced by a regression test.
|
||||
|
||||
### Why This Matters
|
||||
|
||||
|
||||
@@ -21,5 +21,37 @@
|
||||
"workflow",
|
||||
"automation",
|
||||
"best-practices"
|
||||
]
|
||||
],
|
||||
"agents": [
|
||||
"./agents/architect.md",
|
||||
"./agents/build-error-resolver.md",
|
||||
"./agents/chief-of-staff.md",
|
||||
"./agents/code-reviewer.md",
|
||||
"./agents/cpp-build-resolver.md",
|
||||
"./agents/cpp-reviewer.md",
|
||||
"./agents/database-reviewer.md",
|
||||
"./agents/doc-updater.md",
|
||||
"./agents/docs-lookup.md",
|
||||
"./agents/e2e-runner.md",
|
||||
"./agents/flutter-reviewer.md",
|
||||
"./agents/go-build-resolver.md",
|
||||
"./agents/go-reviewer.md",
|
||||
"./agents/harness-optimizer.md",
|
||||
"./agents/java-build-resolver.md",
|
||||
"./agents/java-reviewer.md",
|
||||
"./agents/kotlin-build-resolver.md",
|
||||
"./agents/kotlin-reviewer.md",
|
||||
"./agents/loop-operator.md",
|
||||
"./agents/planner.md",
|
||||
"./agents/python-reviewer.md",
|
||||
"./agents/pytorch-build-resolver.md",
|
||||
"./agents/refactor-cleaner.md",
|
||||
"./agents/rust-build-resolver.md",
|
||||
"./agents/rust-reviewer.md",
|
||||
"./agents/security-reviewer.md",
|
||||
"./agents/tdd-guide.md",
|
||||
"./agents/typescript-reviewer.md"
|
||||
],
|
||||
"skills": ["./skills/"],
|
||||
"commands": ["./commands/"]
|
||||
}
|
||||
|
||||
47
.claude/rules/node.md
Normal file
47
.claude/rules/node.md
Normal file
@@ -0,0 +1,47 @@
|
||||
# Node.js Rules for everything-claude-code
|
||||
|
||||
> Project-specific rules for the ECC codebase. Extends common rules.
|
||||
|
||||
## Stack
|
||||
|
||||
- **Runtime**: Node.js >=18 (no transpilation, plain CommonJS)
|
||||
- **Test runner**: `node tests/run-all.js` — individual files via `node tests/**/*.test.js`
|
||||
- **Linter**: ESLint (`@eslint/js`, flat config)
|
||||
- **Coverage**: c8
|
||||
- **Lint**: markdownlint-cli for `.md` files
|
||||
|
||||
## File Conventions
|
||||
|
||||
- `scripts/` — Node.js utilities, hooks. CommonJS (`require`/`module.exports`)
|
||||
- `agents/`, `commands/`, `skills/`, `rules/` — Markdown with YAML frontmatter
|
||||
- `tests/` — Mirror the `scripts/` structure. Test files named `*.test.js`
|
||||
- File naming: **lowercase with hyphens** (e.g. `session-start.js`, `post-edit-format.js`)
|
||||
|
||||
## Code Style
|
||||
|
||||
- CommonJS only — no ESM (`import`/`export`) unless file ends in `.mjs`
|
||||
- No TypeScript — plain `.js` throughout
|
||||
- Prefer `const` over `let`; never `var`
|
||||
- Keep hook scripts under 200 lines — extract helpers to `scripts/lib/`
|
||||
- All hooks must `exit 0` on non-critical errors (never block tool execution unexpectedly)
|
||||
|
||||
## Hook Development
|
||||
|
||||
- Hook scripts normally receive JSON on stdin, but hooks routed through `scripts/hooks/run-with-flags.js` can export `run(rawInput)` and let the wrapper handle parsing/gating
|
||||
- Async hooks: mark `"async": true` in `settings.json` with a timeout ≤30s
|
||||
- Blocking hooks (PreToolUse, stop): keep fast (<200ms) — no network calls
|
||||
- Use `run-with-flags.js` wrapper for all hooks so `ECC_HOOK_PROFILE` and `ECC_DISABLED_HOOKS` runtime gating works
|
||||
- Always exit 0 on parse errors; log to stderr with `[HookName]` prefix
|
||||
|
||||
## Testing Requirements
|
||||
|
||||
- Run `node tests/run-all.js` before committing
|
||||
- New scripts in `scripts/lib/` require a matching test in `tests/lib/`
|
||||
- New hooks require at least one integration test in `tests/hooks/`
|
||||
|
||||
## Markdown / Agent Files
|
||||
|
||||
- Agents: YAML frontmatter with `name`, `description`, `tools`, `model`
|
||||
- Skills: sections — When to Use, How It Works, Examples
|
||||
- Commands: `description:` frontmatter line required
|
||||
- Run `npx markdownlint-cli '**/*.md' --ignore node_modules` before committing
|
||||
49
.codex-plugin/README.md
Normal file
49
.codex-plugin/README.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# .codex-plugin — Codex Native Plugin for ECC
|
||||
|
||||
This directory contains the **Codex plugin manifest** for Everything Claude Code.
|
||||
|
||||
## Structure
|
||||
|
||||
```
|
||||
.codex-plugin/
|
||||
└── plugin.json — Codex plugin manifest (name, version, skills ref, MCP ref)
|
||||
.mcp.json — MCP server configurations at plugin root (NOT inside .codex-plugin/)
|
||||
```
|
||||
|
||||
## What This Provides
|
||||
|
||||
- **125 skills** from `./skills/` — reusable Codex workflows for TDD, security,
|
||||
code review, architecture, and more
|
||||
- **6 MCP servers** — GitHub, Context7, Exa, Memory, Playwright, Sequential Thinking
|
||||
|
||||
## Installation
|
||||
|
||||
Codex plugin support is currently in preview. Once generally available:
|
||||
|
||||
```bash
|
||||
# Install from Codex CLI
|
||||
codex plugin install affaan-m/everything-claude-code
|
||||
|
||||
# Or reference locally during development
|
||||
codex plugin install ./
|
||||
|
||||
Run this from the repository root so `./` points to the repo root and `.mcp.json` resolves correctly.
|
||||
```
|
||||
|
||||
## MCP Servers Included
|
||||
|
||||
| Server | Purpose |
|
||||
|---|---|
|
||||
| `github` | GitHub API access |
|
||||
| `context7` | Live documentation lookup |
|
||||
| `exa` | Neural web search |
|
||||
| `memory` | Persistent memory across sessions |
|
||||
| `playwright` | Browser automation & E2E testing |
|
||||
| `sequential-thinking` | Step-by-step reasoning |
|
||||
|
||||
## Notes
|
||||
|
||||
- The `skills/` directory at the repo root is shared between Claude Code (`.claude-plugin/`)
|
||||
and Codex (`.codex-plugin/`) — same source of truth, no duplication
|
||||
- MCP server credentials are inherited from the launching environment (env vars)
|
||||
- This manifest does **not** override `~/.codex/config.toml` settings
|
||||
30
.codex-plugin/plugin.json
Normal file
30
.codex-plugin/plugin.json
Normal file
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"name": "everything-claude-code",
|
||||
"version": "1.9.0",
|
||||
"description": "Battle-tested Codex workflows — 125 skills, production-ready MCP configs, and agent definitions for TDD, security scanning, code review, and autonomous development.",
|
||||
"author": {
|
||||
"name": "Affaan Mustafa",
|
||||
"email": "me@affaanmustafa.com",
|
||||
"url": "https://x.com/affaanmustafa"
|
||||
},
|
||||
"homepage": "https://github.com/affaan-m/everything-claude-code",
|
||||
"repository": "https://github.com/affaan-m/everything-claude-code",
|
||||
"license": "MIT",
|
||||
"keywords": ["codex", "agents", "skills", "tdd", "code-review", "security", "workflow", "automation"],
|
||||
"skills": "./skills/",
|
||||
"mcpServers": "./.mcp.json",
|
||||
"interface": {
|
||||
"displayName": "Everything Claude Code",
|
||||
"shortDescription": "125 battle-tested skills for TDD, security, code review, and autonomous development.",
|
||||
"longDescription": "Everything Claude Code (ECC) is a community-maintained collection of Codex skills and MCP configs evolved over 10+ months of intensive daily use. It covers TDD workflows, security scanning, code review, architecture decisions, and more — all in one installable plugin.",
|
||||
"developerName": "Affaan Mustafa",
|
||||
"category": "Productivity",
|
||||
"capabilities": ["Read", "Write"],
|
||||
"websiteURL": "https://github.com/affaan-m/everything-claude-code",
|
||||
"defaultPrompt": [
|
||||
"Use the tdd-workflow skill to write tests before implementation.",
|
||||
"Use the security-review skill to scan for OWASP Top 10 vulnerabilities.",
|
||||
"Use the code-review skill to review this PR for correctness and security."
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -46,12 +46,15 @@ Available skills:
|
||||
|
||||
Treat the project-local `.codex/config.toml` as the default Codex baseline for ECC. The current ECC baseline enables GitHub, Context7, Exa, Memory, Playwright, and Sequential Thinking; add heavier extras in `~/.codex/config.toml` only when a task actually needs them.
|
||||
|
||||
ECC's canonical Codex section name is `[mcp_servers.context7]`. The launcher package remains `@upstash/context7-mcp`; only the TOML section name is normalized for consistency with `codex mcp list` and the reference config.
|
||||
|
||||
### Automatic config.toml merging
|
||||
|
||||
The sync script (`scripts/sync-ecc-to-codex.sh`) uses a Node-based TOML parser to safely merge ECC MCP servers into `~/.codex/config.toml`:
|
||||
|
||||
- **Add-only by default** — missing ECC servers are appended; existing servers are never modified or removed.
|
||||
- **7 managed servers** — Supabase, Playwright, Context7, Exa, GitHub, Memory, Sequential Thinking.
|
||||
- **Canonical naming** — ECC manages Context7 as `[mcp_servers.context7]`; legacy `[mcp_servers.context7-mcp]` entries are treated as aliases during updates.
|
||||
- **Package-manager aware** — uses the project's configured package manager (npm/pnpm/yarn/bun) instead of hardcoding `pnpm`.
|
||||
- **Drift warnings** — if an existing server's config differs from the ECC recommendation, the script logs a warning.
|
||||
- **`--update-mcp`** — explicitly replaces all ECC-managed servers with the latest recommended config (safely removes subtables like `[mcp_servers.supabase.env]`).
|
||||
|
||||
@@ -27,7 +27,10 @@ notify = [
|
||||
"-sound", "default",
|
||||
]
|
||||
|
||||
# Prefer AGENTS.md and project-local .codex/AGENTS.md for instructions.
|
||||
# Persistent instructions are appended to every prompt (additive, unlike
|
||||
# model_instructions_file which replaces AGENTS.md).
|
||||
persistent_instructions = "Follow project AGENTS.md guidelines. Use available MCP servers when they can help."
|
||||
|
||||
# model_instructions_file replaces built-in instructions instead of AGENTS.md,
|
||||
# so leave it unset unless you intentionally want a single override file.
|
||||
# model_instructions_file = "/absolute/path/to/instructions.md"
|
||||
@@ -38,10 +41,14 @@ notify = [
|
||||
[mcp_servers.github]
|
||||
command = "npx"
|
||||
args = ["-y", "@modelcontextprotocol/server-github"]
|
||||
startup_timeout_sec = 30
|
||||
|
||||
[mcp_servers.context7]
|
||||
command = "npx"
|
||||
# Canonical Codex section name is `context7`; the package itself remains
|
||||
# `@upstash/context7-mcp`.
|
||||
args = ["-y", "@upstash/context7-mcp@latest"]
|
||||
startup_timeout_sec = 30
|
||||
|
||||
[mcp_servers.exa]
|
||||
url = "https://mcp.exa.ai/mcp"
|
||||
@@ -49,14 +56,17 @@ url = "https://mcp.exa.ai/mcp"
|
||||
[mcp_servers.memory]
|
||||
command = "npx"
|
||||
args = ["-y", "@modelcontextprotocol/server-memory"]
|
||||
startup_timeout_sec = 30
|
||||
|
||||
[mcp_servers.playwright]
|
||||
command = "npx"
|
||||
args = ["-y", "@playwright/mcp@latest", "--extension"]
|
||||
startup_timeout_sec = 30
|
||||
|
||||
[mcp_servers.sequential-thinking]
|
||||
command = "npx"
|
||||
args = ["-y", "@modelcontextprotocol/server-sequential-thinking"]
|
||||
startup_timeout_sec = 30
|
||||
|
||||
# Additional MCP servers (uncomment as needed):
|
||||
# [mcp_servers.supabase]
|
||||
@@ -76,7 +86,8 @@ args = ["-y", "@modelcontextprotocol/server-sequential-thinking"]
|
||||
# args = ["-y", "@cloudflare/mcp-server-cloudflare"]
|
||||
|
||||
[features]
|
||||
# Codex multi-agent support is experimental as of March 2026.
|
||||
# Codex multi-agent collaboration is stable and on by default in current builds.
|
||||
# Keep the explicit toggle here so the repo documents its expectation clearly.
|
||||
multi_agent = true
|
||||
|
||||
# Profiles — switch with `codex -p <name>`
|
||||
@@ -91,6 +102,9 @@ sandbox_mode = "workspace-write"
|
||||
web_search = "live"
|
||||
|
||||
[agents]
|
||||
[agents]
|
||||
# Multi-agent role limits and local role definitions.
|
||||
# These map to `.codex/agents/*.toml` and mirror the repo's explorer/reviewer/docs workflow.
|
||||
max_threads = 6
|
||||
max_depth = 1
|
||||
|
||||
|
||||
55
.github/workflows/ci.yml
vendored
55
.github/workflows/ci.yml
vendored
@@ -34,23 +34,30 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
||||
|
||||
- name: Setup Node.js ${{ matrix.node }}
|
||||
uses: actions/setup-node@v4
|
||||
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
||||
with:
|
||||
node-version: ${{ matrix.node }}
|
||||
|
||||
# Package manager setup
|
||||
- name: Setup pnpm
|
||||
if: matrix.pm == 'pnpm'
|
||||
uses: pnpm/action-setup@v4
|
||||
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v4
|
||||
with:
|
||||
version: latest
|
||||
|
||||
- name: Setup Yarn (via Corepack)
|
||||
if: matrix.pm == 'yarn'
|
||||
shell: bash
|
||||
run: |
|
||||
corepack enable
|
||||
corepack prepare yarn@stable --activate
|
||||
|
||||
- name: Setup Bun
|
||||
if: matrix.pm == 'bun'
|
||||
uses: oven-sh/setup-bun@v2
|
||||
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2
|
||||
|
||||
# Cache configuration
|
||||
- name: Get npm cache directory
|
||||
@@ -61,7 +68,7 @@ jobs:
|
||||
|
||||
- name: Cache npm
|
||||
if: matrix.pm == 'npm'
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
|
||||
with:
|
||||
path: ${{ steps.npm-cache-dir.outputs.dir }}
|
||||
key: ${{ runner.os }}-node-${{ matrix.node }}-npm-${{ hashFiles('**/package-lock.json') }}
|
||||
@@ -76,7 +83,7 @@ jobs:
|
||||
|
||||
- name: Cache pnpm
|
||||
if: matrix.pm == 'pnpm'
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
|
||||
with:
|
||||
path: ${{ steps.pnpm-cache-dir.outputs.dir }}
|
||||
key: ${{ runner.os }}-node-${{ matrix.node }}-pnpm-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
@@ -97,7 +104,7 @@ jobs:
|
||||
|
||||
- name: Cache yarn
|
||||
if: matrix.pm == 'yarn'
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
|
||||
with:
|
||||
path: ${{ steps.yarn-cache-dir.outputs.dir }}
|
||||
key: ${{ runner.os }}-node-${{ matrix.node }}-yarn-${{ hashFiles('**/yarn.lock') }}
|
||||
@@ -106,7 +113,7 @@ jobs:
|
||||
|
||||
- name: Cache bun
|
||||
if: matrix.pm == 'bun'
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
|
||||
with:
|
||||
path: ~/.bun/install/cache
|
||||
key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lockb') }}
|
||||
@@ -114,14 +121,18 @@ jobs:
|
||||
${{ runner.os }}-bun-
|
||||
|
||||
# Install dependencies
|
||||
# COREPACK_ENABLE_STRICT=0 allows pnpm to install even though
|
||||
# package.json declares "packageManager": "yarn@..."
|
||||
- name: Install dependencies
|
||||
shell: bash
|
||||
env:
|
||||
COREPACK_ENABLE_STRICT: '0'
|
||||
run: |
|
||||
case "${{ matrix.pm }}" in
|
||||
npm) npm ci ;;
|
||||
pnpm) pnpm install ;;
|
||||
# --ignore-engines required for Node 18 compat with some devDependencies (e.g., markdownlint-cli)
|
||||
yarn) yarn install --ignore-engines ;;
|
||||
pnpm) pnpm install --no-frozen-lockfile ;;
|
||||
# Yarn Berry (v4+) removed --ignore-engines; engine checking is no longer a core feature
|
||||
yarn) yarn install ;;
|
||||
bun) bun install ;;
|
||||
*) echo "Unsupported package manager: ${{ matrix.pm }}" && exit 1 ;;
|
||||
esac
|
||||
@@ -135,7 +146,7 @@ jobs:
|
||||
# Upload test artifacts on failure
|
||||
- name: Upload test artifacts
|
||||
if: failure()
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
||||
with:
|
||||
name: test-results-${{ matrix.os }}-node${{ matrix.node }}-${{ matrix.pm }}
|
||||
path: |
|
||||
@@ -149,10 +160,10 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
||||
with:
|
||||
node-version: '20.x'
|
||||
|
||||
@@ -175,6 +186,10 @@ jobs:
|
||||
run: node scripts/ci/validate-skills.js
|
||||
continue-on-error: false
|
||||
|
||||
- name: Validate install manifests
|
||||
run: node scripts/ci/validate-install-manifests.js
|
||||
continue-on-error: false
|
||||
|
||||
- name: Validate rules
|
||||
run: node scripts/ci/validate-rules.js
|
||||
continue-on-error: false
|
||||
@@ -183,6 +198,10 @@ jobs:
|
||||
run: node scripts/ci/catalog.js --text
|
||||
continue-on-error: false
|
||||
|
||||
- name: Check unicode safety
|
||||
run: node scripts/ci/check-unicode-safety.js
|
||||
continue-on-error: false
|
||||
|
||||
security:
|
||||
name: Security Scan
|
||||
runs-on: ubuntu-latest
|
||||
@@ -190,10 +209,10 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
||||
with:
|
||||
node-version: '20.x'
|
||||
|
||||
@@ -208,10 +227,10 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
||||
with:
|
||||
node-version: '20.x'
|
||||
|
||||
|
||||
10
.github/workflows/maintenance.yml
vendored
10
.github/workflows/maintenance.yml
vendored
@@ -15,8 +15,8 @@ jobs:
|
||||
name: Check Dependencies
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
||||
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
||||
with:
|
||||
node-version: '20.x'
|
||||
- name: Check for outdated packages
|
||||
@@ -26,8 +26,8 @@ jobs:
|
||||
name: Security Audit
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
||||
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
||||
with:
|
||||
node-version: '20.x'
|
||||
- name: Run security audit
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
name: Stale Issues/PRs
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/stale@v9
|
||||
- uses: actions/stale@5bef64f19d7facfb25b37b414482c7164d639639 # v9
|
||||
with:
|
||||
stale-issue-message: 'This issue is stale due to inactivity.'
|
||||
stale-pr-message: 'This PR is stale due to inactivity.'
|
||||
|
||||
8
.github/workflows/release.yml
vendored
8
.github/workflows/release.yml
vendored
@@ -14,17 +14,19 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Validate version tag
|
||||
run: |
|
||||
if ! [[ "${{ github.ref_name }}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
||||
if ! [[ "${REF_NAME}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
||||
echo "Invalid version tag format. Expected vX.Y.Z"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
env:
|
||||
REF_NAME: ${{ github.ref_name }}
|
||||
- name: Verify plugin.json version matches tag
|
||||
env:
|
||||
TAG_NAME: ${{ github.ref_name }}
|
||||
@@ -61,7 +63,7 @@ jobs:
|
||||
EOF
|
||||
|
||||
- name: Create GitHub Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
uses: softprops/action-gh-release@153bb8e04406b158c6c84fc1615b65b24149a1fe # v2
|
||||
with:
|
||||
body_path: release_body.md
|
||||
generate_release_notes: true
|
||||
|
||||
4
.github/workflows/reusable-release.yml
vendored
4
.github/workflows/reusable-release.yml
vendored
@@ -23,7 +23,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
@@ -49,7 +49,7 @@ jobs:
|
||||
EOF
|
||||
|
||||
- name: Create GitHub Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
uses: softprops/action-gh-release@153bb8e04406b158c6c84fc1615b65b24149a1fe # v2
|
||||
with:
|
||||
tag_name: ${{ inputs.tag }}
|
||||
body_path: release_body.md
|
||||
|
||||
34
.github/workflows/reusable-test.yml
vendored
34
.github/workflows/reusable-test.yml
vendored
@@ -27,22 +27,29 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
||||
with:
|
||||
node-version: ${{ inputs.node-version }}
|
||||
|
||||
- name: Setup pnpm
|
||||
if: inputs.package-manager == 'pnpm'
|
||||
uses: pnpm/action-setup@v4
|
||||
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v4
|
||||
with:
|
||||
version: latest
|
||||
|
||||
- name: Setup Yarn (via Corepack)
|
||||
if: inputs.package-manager == 'yarn'
|
||||
shell: bash
|
||||
run: |
|
||||
corepack enable
|
||||
corepack prepare yarn@stable --activate
|
||||
|
||||
- name: Setup Bun
|
||||
if: inputs.package-manager == 'bun'
|
||||
uses: oven-sh/setup-bun@v2
|
||||
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2
|
||||
|
||||
- name: Get npm cache directory
|
||||
if: inputs.package-manager == 'npm'
|
||||
@@ -52,7 +59,7 @@ jobs:
|
||||
|
||||
- name: Cache npm
|
||||
if: inputs.package-manager == 'npm'
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
|
||||
with:
|
||||
path: ${{ steps.npm-cache-dir.outputs.dir }}
|
||||
key: ${{ runner.os }}-node-${{ inputs.node-version }}-npm-${{ hashFiles('**/package-lock.json') }}
|
||||
@@ -67,7 +74,7 @@ jobs:
|
||||
|
||||
- name: Cache pnpm
|
||||
if: inputs.package-manager == 'pnpm'
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
|
||||
with:
|
||||
path: ${{ steps.pnpm-cache-dir.outputs.dir }}
|
||||
key: ${{ runner.os }}-node-${{ inputs.node-version }}-pnpm-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
@@ -88,7 +95,7 @@ jobs:
|
||||
|
||||
- name: Cache yarn
|
||||
if: inputs.package-manager == 'yarn'
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
|
||||
with:
|
||||
path: ${{ steps.yarn-cache-dir.outputs.dir }}
|
||||
key: ${{ runner.os }}-node-${{ inputs.node-version }}-yarn-${{ hashFiles('**/yarn.lock') }}
|
||||
@@ -97,20 +104,25 @@ jobs:
|
||||
|
||||
- name: Cache bun
|
||||
if: inputs.package-manager == 'bun'
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
|
||||
with:
|
||||
path: ~/.bun/install/cache
|
||||
key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lockb') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-bun-
|
||||
|
||||
# COREPACK_ENABLE_STRICT=0 allows pnpm to install even though
|
||||
# package.json declares "packageManager": "yarn@..."
|
||||
- name: Install dependencies
|
||||
shell: bash
|
||||
env:
|
||||
COREPACK_ENABLE_STRICT: '0'
|
||||
run: |
|
||||
case "${{ inputs.package-manager }}" in
|
||||
npm) npm ci ;;
|
||||
pnpm) pnpm install ;;
|
||||
yarn) yarn install --ignore-engines ;;
|
||||
pnpm) pnpm install --no-frozen-lockfile ;;
|
||||
# Yarn Berry (v4+) removed --ignore-engines; engine checking is no longer a core feature
|
||||
yarn) yarn install ;;
|
||||
bun) bun install ;;
|
||||
*) echo "Unsupported package manager: ${{ inputs.package-manager }}" && exit 1 ;;
|
||||
esac
|
||||
@@ -122,7 +134,7 @@ jobs:
|
||||
|
||||
- name: Upload test artifacts
|
||||
if: failure()
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
||||
with:
|
||||
name: test-results-${{ inputs.os }}-node${{ inputs.node-version }}-${{ inputs.package-manager }}
|
||||
path: |
|
||||
|
||||
10
.github/workflows/reusable-validate.yml
vendored
10
.github/workflows/reusable-validate.yml
vendored
@@ -17,10 +17,10 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
||||
with:
|
||||
node-version: ${{ inputs.node-version }}
|
||||
|
||||
@@ -39,5 +39,11 @@ jobs:
|
||||
- name: Validate skills
|
||||
run: node scripts/ci/validate-skills.js
|
||||
|
||||
- name: Validate install manifests
|
||||
run: node scripts/ci/validate-install-manifests.js
|
||||
|
||||
- name: Validate rules
|
||||
run: node scripts/ci/validate-rules.js
|
||||
|
||||
- name: Check unicode safety
|
||||
run: node scripts/ci/check-unicode-safety.js
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -83,6 +83,9 @@ temp/
|
||||
*.bak
|
||||
*.backup
|
||||
|
||||
# Observer temp files (continuous-learning-v2)
|
||||
.observer-tmp/
|
||||
|
||||
# Rust build artifacts
|
||||
ecc2/target/
|
||||
|
||||
|
||||
@@ -597,7 +597,7 @@ For more detailed information, see the `docs/` directory:
|
||||
|
||||
## Contributers
|
||||
|
||||
- Himanshu Sharma [@ihimanss](https://github.com/ihimanss)
|
||||
- Himanshu Sharma [@ihimanss](https://github.com/ihimanss)
|
||||
- Sungmin Hong [@aws-hsungmin](https://github.com/aws-hsungmin)
|
||||
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ detect_pm() {
|
||||
}
|
||||
|
||||
PM=$(detect_pm)
|
||||
echo "📦 Package manager: $PM"
|
||||
echo "Package manager: $PM"
|
||||
echo ""
|
||||
|
||||
# ── Helper: run a check ─────────────────────────────────────
|
||||
|
||||
@@ -62,10 +62,10 @@ Choose model tier based on task complexity:
|
||||
|
||||
- **Haiku**: Classification, boilerplate transforms, narrow edits
|
||||
- Example: Rename variable, add type annotation, format code
|
||||
|
||||
|
||||
- **Sonnet**: Implementation and refactors
|
||||
- Example: Implement feature, refactor module, write tests
|
||||
|
||||
|
||||
- **Opus**: Architecture, root-cause analysis, multi-file invariants
|
||||
- Example: Design system, debug complex issue, review architecture
|
||||
|
||||
@@ -75,10 +75,10 @@ Choose model tier based on task complexity:
|
||||
|
||||
- **Continue session** for closely-coupled units
|
||||
- Example: Implementing related functions in same module
|
||||
|
||||
|
||||
- **Start fresh session** after major phase transitions
|
||||
- Example: Moving from implementation to testing
|
||||
|
||||
|
||||
- **Compact after milestone completion**, not during active debugging
|
||||
- Example: After feature complete, before starting next feature
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ Backend architecture patterns and best practices for scalable server-side applic
|
||||
### RESTful API Structure
|
||||
|
||||
```typescript
|
||||
// ✅ Resource-based URLs
|
||||
// PASS: Resource-based URLs
|
||||
GET /api/markets # List resources
|
||||
GET /api/markets/:id # Get single resource
|
||||
POST /api/markets # Create resource
|
||||
@@ -33,7 +33,7 @@ PUT /api/markets/:id # Replace resource
|
||||
PATCH /api/markets/:id # Update resource
|
||||
DELETE /api/markets/:id # Delete resource
|
||||
|
||||
// ✅ Query parameters for filtering, sorting, pagination
|
||||
// PASS: Query parameters for filtering, sorting, pagination
|
||||
GET /api/markets?status=active&sort=volume&limit=20&offset=0
|
||||
```
|
||||
|
||||
@@ -133,7 +133,7 @@ export default withAuth(async (req, res) => {
|
||||
### Query Optimization
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Select only needed columns
|
||||
// PASS: GOOD: Select only needed columns
|
||||
const { data } = await supabase
|
||||
.from('markets')
|
||||
.select('id, name, status, volume')
|
||||
@@ -141,7 +141,7 @@ const { data } = await supabase
|
||||
.order('volume', { ascending: false })
|
||||
.limit(10)
|
||||
|
||||
// ❌ BAD: Select everything
|
||||
// FAIL: BAD: Select everything
|
||||
const { data } = await supabase
|
||||
.from('markets')
|
||||
.select('*')
|
||||
@@ -150,13 +150,13 @@ const { data } = await supabase
|
||||
### N+1 Query Prevention
|
||||
|
||||
```typescript
|
||||
// ❌ BAD: N+1 query problem
|
||||
// FAIL: BAD: N+1 query problem
|
||||
const markets = await getMarkets()
|
||||
for (const market of markets) {
|
||||
market.creator = await getUser(market.creator_id) // N queries
|
||||
}
|
||||
|
||||
// ✅ GOOD: Batch fetch
|
||||
// PASS: GOOD: Batch fetch
|
||||
const markets = await getMarkets()
|
||||
const creatorIds = markets.map(m => m.creator_id)
|
||||
const creators = await getUsers(creatorIds) // 1 query
|
||||
|
||||
@@ -50,12 +50,12 @@ Universal coding standards applicable across all projects.
|
||||
### Variable Naming
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Descriptive names
|
||||
// PASS: GOOD: Descriptive names
|
||||
const marketSearchQuery = 'election'
|
||||
const isUserAuthenticated = true
|
||||
const totalRevenue = 1000
|
||||
|
||||
// ❌ BAD: Unclear names
|
||||
// FAIL: BAD: Unclear names
|
||||
const q = 'election'
|
||||
const flag = true
|
||||
const x = 1000
|
||||
@@ -64,12 +64,12 @@ const x = 1000
|
||||
### Function Naming
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Verb-noun pattern
|
||||
// PASS: GOOD: Verb-noun pattern
|
||||
async function fetchMarketData(marketId: string) { }
|
||||
function calculateSimilarity(a: number[], b: number[]) { }
|
||||
function isValidEmail(email: string): boolean { }
|
||||
|
||||
// ❌ BAD: Unclear or noun-only
|
||||
// FAIL: BAD: Unclear or noun-only
|
||||
async function market(id: string) { }
|
||||
function similarity(a, b) { }
|
||||
function email(e) { }
|
||||
@@ -78,7 +78,7 @@ function email(e) { }
|
||||
### Immutability Pattern (CRITICAL)
|
||||
|
||||
```typescript
|
||||
// ✅ ALWAYS use spread operator
|
||||
// PASS: ALWAYS use spread operator
|
||||
const updatedUser = {
|
||||
...user,
|
||||
name: 'New Name'
|
||||
@@ -86,7 +86,7 @@ const updatedUser = {
|
||||
|
||||
const updatedArray = [...items, newItem]
|
||||
|
||||
// ❌ NEVER mutate directly
|
||||
// FAIL: NEVER mutate directly
|
||||
user.name = 'New Name' // BAD
|
||||
items.push(newItem) // BAD
|
||||
```
|
||||
@@ -94,7 +94,7 @@ items.push(newItem) // BAD
|
||||
### Error Handling
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Comprehensive error handling
|
||||
// PASS: GOOD: Comprehensive error handling
|
||||
async function fetchData(url: string) {
|
||||
try {
|
||||
const response = await fetch(url)
|
||||
@@ -110,7 +110,7 @@ async function fetchData(url: string) {
|
||||
}
|
||||
}
|
||||
|
||||
// ❌ BAD: No error handling
|
||||
// FAIL: BAD: No error handling
|
||||
async function fetchData(url) {
|
||||
const response = await fetch(url)
|
||||
return response.json()
|
||||
@@ -120,14 +120,14 @@ async function fetchData(url) {
|
||||
### Async/Await Best Practices
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Parallel execution when possible
|
||||
// PASS: GOOD: Parallel execution when possible
|
||||
const [users, markets, stats] = await Promise.all([
|
||||
fetchUsers(),
|
||||
fetchMarkets(),
|
||||
fetchStats()
|
||||
])
|
||||
|
||||
// ❌ BAD: Sequential when unnecessary
|
||||
// FAIL: BAD: Sequential when unnecessary
|
||||
const users = await fetchUsers()
|
||||
const markets = await fetchMarkets()
|
||||
const stats = await fetchStats()
|
||||
@@ -136,7 +136,7 @@ const stats = await fetchStats()
|
||||
### Type Safety
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Proper types
|
||||
// PASS: GOOD: Proper types
|
||||
interface Market {
|
||||
id: string
|
||||
name: string
|
||||
@@ -148,7 +148,7 @@ function getMarket(id: string): Promise<Market> {
|
||||
// Implementation
|
||||
}
|
||||
|
||||
// ❌ BAD: Using 'any'
|
||||
// FAIL: BAD: Using 'any'
|
||||
function getMarket(id: any): Promise<any> {
|
||||
// Implementation
|
||||
}
|
||||
@@ -159,7 +159,7 @@ function getMarket(id: any): Promise<any> {
|
||||
### Component Structure
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Functional component with types
|
||||
// PASS: GOOD: Functional component with types
|
||||
interface ButtonProps {
|
||||
children: React.ReactNode
|
||||
onClick: () => void
|
||||
@@ -184,7 +184,7 @@ export function Button({
|
||||
)
|
||||
}
|
||||
|
||||
// ❌ BAD: No types, unclear structure
|
||||
// FAIL: BAD: No types, unclear structure
|
||||
export function Button(props) {
|
||||
return <button onClick={props.onClick}>{props.children}</button>
|
||||
}
|
||||
@@ -193,7 +193,7 @@ export function Button(props) {
|
||||
### Custom Hooks
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Reusable custom hook
|
||||
// PASS: GOOD: Reusable custom hook
|
||||
export function useDebounce<T>(value: T, delay: number): T {
|
||||
const [debouncedValue, setDebouncedValue] = useState<T>(value)
|
||||
|
||||
@@ -215,25 +215,25 @@ const debouncedQuery = useDebounce(searchQuery, 500)
|
||||
### State Management
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Proper state updates
|
||||
// PASS: GOOD: Proper state updates
|
||||
const [count, setCount] = useState(0)
|
||||
|
||||
// Functional update for state based on previous state
|
||||
setCount(prev => prev + 1)
|
||||
|
||||
// ❌ BAD: Direct state reference
|
||||
// FAIL: BAD: Direct state reference
|
||||
setCount(count + 1) // Can be stale in async scenarios
|
||||
```
|
||||
|
||||
### Conditional Rendering
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Clear conditional rendering
|
||||
// PASS: GOOD: Clear conditional rendering
|
||||
{isLoading && <Spinner />}
|
||||
{error && <ErrorMessage error={error} />}
|
||||
{data && <DataDisplay data={data} />}
|
||||
|
||||
// ❌ BAD: Ternary hell
|
||||
// FAIL: BAD: Ternary hell
|
||||
{isLoading ? <Spinner /> : error ? <ErrorMessage error={error} /> : data ? <DataDisplay data={data} /> : null}
|
||||
```
|
||||
|
||||
@@ -256,7 +256,7 @@ GET /api/markets?status=active&limit=10&offset=0
|
||||
### Response Format
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Consistent response structure
|
||||
// PASS: GOOD: Consistent response structure
|
||||
interface ApiResponse<T> {
|
||||
success: boolean
|
||||
data?: T
|
||||
@@ -287,7 +287,7 @@ return NextResponse.json({
|
||||
```typescript
|
||||
import { z } from 'zod'
|
||||
|
||||
// ✅ GOOD: Schema validation
|
||||
// PASS: GOOD: Schema validation
|
||||
const CreateMarketSchema = z.object({
|
||||
name: z.string().min(1).max(200),
|
||||
description: z.string().min(1).max(2000),
|
||||
@@ -350,14 +350,14 @@ types/market.types.ts # camelCase with .types suffix
|
||||
### When to Comment
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Explain WHY, not WHAT
|
||||
// PASS: GOOD: Explain WHY, not WHAT
|
||||
// Use exponential backoff to avoid overwhelming the API during outages
|
||||
const delay = Math.min(1000 * Math.pow(2, retryCount), 30000)
|
||||
|
||||
// Deliberately using mutation here for performance with large arrays
|
||||
items.push(newItem)
|
||||
|
||||
// ❌ BAD: Stating the obvious
|
||||
// FAIL: BAD: Stating the obvious
|
||||
// Increment counter by 1
|
||||
count++
|
||||
|
||||
@@ -397,12 +397,12 @@ export async function searchMarkets(
|
||||
```typescript
|
||||
import { useMemo, useCallback } from 'react'
|
||||
|
||||
// ✅ GOOD: Memoize expensive computations
|
||||
// PASS: GOOD: Memoize expensive computations
|
||||
const sortedMarkets = useMemo(() => {
|
||||
return markets.sort((a, b) => b.volume - a.volume)
|
||||
}, [markets])
|
||||
|
||||
// ✅ GOOD: Memoize callbacks
|
||||
// PASS: GOOD: Memoize callbacks
|
||||
const handleSearch = useCallback((query: string) => {
|
||||
setSearchQuery(query)
|
||||
}, [])
|
||||
@@ -413,7 +413,7 @@ const handleSearch = useCallback((query: string) => {
|
||||
```typescript
|
||||
import { lazy, Suspense } from 'react'
|
||||
|
||||
// ✅ GOOD: Lazy load heavy components
|
||||
// PASS: GOOD: Lazy load heavy components
|
||||
const HeavyChart = lazy(() => import('./HeavyChart'))
|
||||
|
||||
export function Dashboard() {
|
||||
@@ -428,13 +428,13 @@ export function Dashboard() {
|
||||
### Database Queries
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Select only needed columns
|
||||
// PASS: GOOD: Select only needed columns
|
||||
const { data } = await supabase
|
||||
.from('markets')
|
||||
.select('id, name, status')
|
||||
.limit(10)
|
||||
|
||||
// ❌ BAD: Select everything
|
||||
// FAIL: BAD: Select everything
|
||||
const { data } = await supabase
|
||||
.from('markets')
|
||||
.select('*')
|
||||
@@ -461,12 +461,12 @@ test('calculates similarity correctly', () => {
|
||||
### Test Naming
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Descriptive test names
|
||||
// PASS: GOOD: Descriptive test names
|
||||
test('returns empty array when no markets match query', () => { })
|
||||
test('throws error when OpenAI API key is missing', () => { })
|
||||
test('falls back to substring search when Redis unavailable', () => { })
|
||||
|
||||
// ❌ BAD: Vague test names
|
||||
// FAIL: BAD: Vague test names
|
||||
test('works', () => { })
|
||||
test('test search', () => { })
|
||||
```
|
||||
@@ -477,12 +477,12 @@ Watch for these anti-patterns:
|
||||
|
||||
### 1. Long Functions
|
||||
```typescript
|
||||
// ❌ BAD: Function > 50 lines
|
||||
// FAIL: BAD: Function > 50 lines
|
||||
function processMarketData() {
|
||||
// 100 lines of code
|
||||
}
|
||||
|
||||
// ✅ GOOD: Split into smaller functions
|
||||
// PASS: GOOD: Split into smaller functions
|
||||
function processMarketData() {
|
||||
const validated = validateData()
|
||||
const transformed = transformData(validated)
|
||||
@@ -492,7 +492,7 @@ function processMarketData() {
|
||||
|
||||
### 2. Deep Nesting
|
||||
```typescript
|
||||
// ❌ BAD: 5+ levels of nesting
|
||||
// FAIL: BAD: 5+ levels of nesting
|
||||
if (user) {
|
||||
if (user.isAdmin) {
|
||||
if (market) {
|
||||
@@ -505,7 +505,7 @@ if (user) {
|
||||
}
|
||||
}
|
||||
|
||||
// ✅ GOOD: Early returns
|
||||
// PASS: GOOD: Early returns
|
||||
if (!user) return
|
||||
if (!user.isAdmin) return
|
||||
if (!market) return
|
||||
@@ -517,11 +517,11 @@ if (!hasPermission) return
|
||||
|
||||
### 3. Magic Numbers
|
||||
```typescript
|
||||
// ❌ BAD: Unexplained numbers
|
||||
// FAIL: BAD: Unexplained numbers
|
||||
if (retryCount > 3) { }
|
||||
setTimeout(callback, 500)
|
||||
|
||||
// ✅ GOOD: Named constants
|
||||
// PASS: GOOD: Named constants
|
||||
const MAX_RETRIES = 3
|
||||
const DEBOUNCE_DELAY_MS = 500
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ Modern frontend patterns for React, Next.js, and performant user interfaces.
|
||||
### Composition Over Inheritance
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Component composition
|
||||
// PASS: GOOD: Component composition
|
||||
interface CardProps {
|
||||
children: React.ReactNode
|
||||
variant?: 'default' | 'outlined'
|
||||
@@ -296,17 +296,17 @@ export function useMarkets() {
|
||||
### Memoization
|
||||
|
||||
```typescript
|
||||
// ✅ useMemo for expensive computations
|
||||
// PASS: useMemo for expensive computations
|
||||
const sortedMarkets = useMemo(() => {
|
||||
return markets.sort((a, b) => b.volume - a.volume)
|
||||
}, [markets])
|
||||
|
||||
// ✅ useCallback for functions passed to children
|
||||
// PASS: useCallback for functions passed to children
|
||||
const handleSearch = useCallback((query: string) => {
|
||||
setSearchQuery(query)
|
||||
}, [])
|
||||
|
||||
// ✅ React.memo for pure components
|
||||
// PASS: React.memo for pure components
|
||||
export const MarketCard = React.memo<MarketCardProps>(({ market }) => {
|
||||
return (
|
||||
<div className="market-card">
|
||||
@@ -322,7 +322,7 @@ export const MarketCard = React.memo<MarketCardProps>(({ market }) => {
|
||||
```typescript
|
||||
import { lazy, Suspense } from 'react'
|
||||
|
||||
// ✅ Lazy load heavy components
|
||||
// PASS: Lazy load heavy components
|
||||
const HeavyChart = lazy(() => import('./HeavyChart'))
|
||||
const ThreeJsBackground = lazy(() => import('./ThreeJsBackground'))
|
||||
|
||||
@@ -517,7 +517,7 @@ export class ErrorBoundary extends React.Component<
|
||||
```typescript
|
||||
import { motion, AnimatePresence } from 'framer-motion'
|
||||
|
||||
// ✅ List animations
|
||||
// PASS: List animations
|
||||
export function AnimatedMarketList({ markets }: { markets: Market[] }) {
|
||||
return (
|
||||
<AnimatePresence>
|
||||
@@ -536,7 +536,7 @@ export function AnimatedMarketList({ markets }: { markets: Market[] }) {
|
||||
)
|
||||
}
|
||||
|
||||
// ✅ Modal animations
|
||||
// PASS: Modal animations
|
||||
export function Modal({ isOpen, onClose, children }: ModalProps) {
|
||||
return (
|
||||
<AnimatePresence>
|
||||
|
||||
@@ -192,7 +192,7 @@ func TestValidate(t *testing.T) {
|
||||
{"valid", "test@example.com", false},
|
||||
{"invalid", "not-an-email", true},
|
||||
}
|
||||
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
err := Validate(tt.input)
|
||||
|
||||
@@ -49,7 +49,7 @@ func TestValidateEmail(t *testing.T) {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
err := ValidateEmail(tt.email)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("ValidateEmail(%q) error = %v, wantErr %v",
|
||||
t.Errorf("ValidateEmail(%q) error = %v, wantErr %v",
|
||||
tt.email, err, tt.wantErr)
|
||||
}
|
||||
})
|
||||
@@ -95,19 +95,19 @@ Use `t.Cleanup()` for resource cleanup:
|
||||
```go
|
||||
func testDB(t *testing.T) *sql.DB {
|
||||
t.Helper()
|
||||
|
||||
|
||||
db, err := sql.Open("sqlite3", ":memory:")
|
||||
if err != nil {
|
||||
t.Fatalf("failed to open test db: %v", err)
|
||||
}
|
||||
|
||||
|
||||
// Cleanup runs after test completes
|
||||
t.Cleanup(func() {
|
||||
if err := db.Close(); err != nil {
|
||||
t.Errorf("failed to close db: %v", err)
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
return db
|
||||
}
|
||||
|
||||
@@ -164,7 +164,7 @@ go test -cover ./... | grep -E 'coverage: [0-7][0-9]\.[0-9]%' && exit 1
|
||||
```go
|
||||
func BenchmarkValidateEmail(b *testing.B) {
|
||||
email := "user@example.com"
|
||||
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
ValidateEmail(email)
|
||||
@@ -212,7 +212,7 @@ func TestUserService(t *testing.T) {
|
||||
"1": {ID: "1", Name: "Alice"},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
service := NewUserService(mock)
|
||||
// ... test logic
|
||||
}
|
||||
@@ -245,16 +245,16 @@ func TestWithPostgres(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("skipping integration test")
|
||||
}
|
||||
|
||||
|
||||
// Setup test container
|
||||
ctx := context.Background()
|
||||
container, err := testcontainers.GenericContainer(ctx, ...)
|
||||
assertNoError(t, err)
|
||||
|
||||
|
||||
t.Cleanup(func() {
|
||||
container.Terminate(ctx)
|
||||
})
|
||||
|
||||
|
||||
// ... test logic
|
||||
}
|
||||
```
|
||||
@@ -290,10 +290,10 @@ package user
|
||||
func TestUserHandler(t *testing.T) {
|
||||
req := httptest.NewRequest("GET", "/users/1", nil)
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
|
||||
handler := NewUserHandler(mockRepo)
|
||||
handler.ServeHTTP(rec, req)
|
||||
|
||||
|
||||
assertEqual(t, rec.Code, http.StatusOK)
|
||||
}
|
||||
```
|
||||
@@ -304,7 +304,7 @@ func TestUserHandler(t *testing.T) {
|
||||
func TestWithTimeout(t *testing.T) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
|
||||
defer cancel()
|
||||
|
||||
|
||||
err := SlowOperation(ctx)
|
||||
if !errors.Is(err, context.DeadlineExceeded) {
|
||||
t.Errorf("expected timeout error, got %v", err)
|
||||
|
||||
@@ -30,7 +30,7 @@ class UserRepository:
|
||||
def find_by_id(self, id: str) -> dict | None:
|
||||
# implementation
|
||||
pass
|
||||
|
||||
|
||||
def save(self, entity: dict) -> dict:
|
||||
# implementation
|
||||
pass
|
||||
@@ -104,11 +104,11 @@ class FileProcessor:
|
||||
def __init__(self, filename: str):
|
||||
self.filename = filename
|
||||
self.file = None
|
||||
|
||||
|
||||
def __enter__(self):
|
||||
self.file = open(self.filename, 'r')
|
||||
return self.file
|
||||
|
||||
|
||||
def __exit__(self, exc_type, exc_val, exc_tb):
|
||||
if self.file:
|
||||
self.file.close()
|
||||
@@ -173,13 +173,13 @@ def slow_function():
|
||||
def singleton(cls):
|
||||
"""Decorator to make a class a singleton"""
|
||||
instances = {}
|
||||
|
||||
|
||||
@wraps(cls)
|
||||
def get_instance(*args, **kwargs):
|
||||
if cls not in instances:
|
||||
instances[cls] = cls(*args, **kwargs)
|
||||
return instances[cls]
|
||||
|
||||
|
||||
return get_instance
|
||||
|
||||
@singleton
|
||||
@@ -216,7 +216,7 @@ class AsyncDatabase:
|
||||
async def __aenter__(self):
|
||||
await self.connect()
|
||||
return self
|
||||
|
||||
|
||||
async def __aexit__(self, exc_type, exc_val, exc_tb):
|
||||
await self.disconnect()
|
||||
|
||||
@@ -238,7 +238,7 @@ class Repository(Generic[T]):
|
||||
"""Generic repository pattern"""
|
||||
def __init__(self, entity_type: type[T]):
|
||||
self.entity_type = entity_type
|
||||
|
||||
|
||||
def find_by_id(self, id: str) -> T | None:
|
||||
# implementation
|
||||
pass
|
||||
@@ -280,17 +280,17 @@ class UserService:
|
||||
self.repository = repository
|
||||
self.logger = logger
|
||||
self.cache = cache
|
||||
|
||||
|
||||
def get_user(self, user_id: str) -> User | None:
|
||||
if self.cache:
|
||||
cached = self.cache.get(user_id)
|
||||
if cached:
|
||||
return cached
|
||||
|
||||
|
||||
user = self.repository.find_by_id(user_id)
|
||||
if user and self.cache:
|
||||
self.cache.set(user_id, user)
|
||||
|
||||
|
||||
return user
|
||||
```
|
||||
|
||||
@@ -375,16 +375,16 @@ class User:
|
||||
def __init__(self, name: str):
|
||||
self._name = name
|
||||
self._email = None
|
||||
|
||||
|
||||
@property
|
||||
def name(self) -> str:
|
||||
"""Read-only property"""
|
||||
return self._name
|
||||
|
||||
|
||||
@property
|
||||
def email(self) -> str | None:
|
||||
return self._email
|
||||
|
||||
|
||||
@email.setter
|
||||
def email(self, value: str) -> None:
|
||||
if '@' not in value:
|
||||
|
||||
@@ -23,7 +23,7 @@ Use **pytest** as the testing framework for its powerful features and clean synt
|
||||
def test_user_creation():
|
||||
"""Test that a user can be created with valid data"""
|
||||
user = User(name="Alice", email="alice@example.com")
|
||||
|
||||
|
||||
assert user.name == "Alice"
|
||||
assert user.email == "alice@example.com"
|
||||
assert user.is_active is True
|
||||
@@ -52,12 +52,12 @@ def db_session():
|
||||
engine = create_engine("sqlite:///:memory:")
|
||||
Session = sessionmaker(bind=engine)
|
||||
session = Session()
|
||||
|
||||
|
||||
# Setup
|
||||
Base.metadata.create_all(engine)
|
||||
|
||||
|
||||
yield session
|
||||
|
||||
|
||||
# Teardown
|
||||
session.close()
|
||||
|
||||
@@ -65,7 +65,7 @@ def test_user_repository(db_session):
|
||||
"""Test using the db_session fixture"""
|
||||
repo = UserRepository(db_session)
|
||||
user = repo.create(name="Alice", email="alice@example.com")
|
||||
|
||||
|
||||
assert user.id is not None
|
||||
```
|
||||
|
||||
@@ -206,10 +206,10 @@ def test_user_service_with_mock():
|
||||
"""Test with mock repository"""
|
||||
mock_repo = Mock()
|
||||
mock_repo.find_by_id.return_value = User(id="1", name="Alice")
|
||||
|
||||
|
||||
service = UserService(mock_repo)
|
||||
user = service.get_user("1")
|
||||
|
||||
|
||||
assert user.name == "Alice"
|
||||
mock_repo.find_by_id.assert_called_once_with("1")
|
||||
|
||||
@@ -218,7 +218,7 @@ def test_send_notification(mock_email_service):
|
||||
"""Test with patched dependency"""
|
||||
service = NotificationService()
|
||||
service.send("user@example.com", "Hello")
|
||||
|
||||
|
||||
mock_email_service.send.assert_called_once()
|
||||
```
|
||||
|
||||
@@ -229,10 +229,10 @@ def test_with_mocker(mocker):
|
||||
"""Using pytest-mock plugin"""
|
||||
mock_repo = mocker.Mock()
|
||||
mock_repo.find_by_id.return_value = User(id="1", name="Alice")
|
||||
|
||||
|
||||
service = UserService(mock_repo)
|
||||
user = service.get_user("1")
|
||||
|
||||
|
||||
assert user.name == "Alice"
|
||||
```
|
||||
|
||||
@@ -357,7 +357,7 @@ def test_with_context():
|
||||
"""pytest provides detailed assertion introspection"""
|
||||
result = calculate_total([1, 2, 3])
|
||||
expected = 6
|
||||
|
||||
|
||||
# pytest shows: assert 5 == 6
|
||||
assert result == expected
|
||||
```
|
||||
@@ -378,7 +378,7 @@ import pytest
|
||||
def test_float_comparison():
|
||||
result = 0.1 + 0.2
|
||||
assert result == pytest.approx(0.3)
|
||||
|
||||
|
||||
# With tolerance
|
||||
assert result == pytest.approx(0.3, abs=1e-9)
|
||||
```
|
||||
@@ -402,7 +402,7 @@ def test_exception_details():
|
||||
"""Capture and inspect exception"""
|
||||
with pytest.raises(ValidationError) as exc_info:
|
||||
validate_user(name="", age=-1)
|
||||
|
||||
|
||||
assert "name" in exc_info.value.errors
|
||||
assert "age" in exc_info.value.errors
|
||||
```
|
||||
|
||||
@@ -24,13 +24,13 @@ This skill ensures all code follows security best practices and identifies poten
|
||||
|
||||
### 1. Secrets Management
|
||||
|
||||
#### ❌ NEVER Do This
|
||||
#### FAIL: NEVER Do This
|
||||
```typescript
|
||||
const apiKey = "sk-proj-xxxxx" // Hardcoded secret
|
||||
const dbPassword = "password123" // In source code
|
||||
```
|
||||
|
||||
#### ✅ ALWAYS Do This
|
||||
#### PASS: ALWAYS Do This
|
||||
```typescript
|
||||
const apiKey = process.env.OPENAI_API_KEY
|
||||
const dbUrl = process.env.DATABASE_URL
|
||||
@@ -110,14 +110,14 @@ function validateFileUpload(file: File) {
|
||||
|
||||
### 3. SQL Injection Prevention
|
||||
|
||||
#### ❌ NEVER Concatenate SQL
|
||||
#### FAIL: NEVER Concatenate SQL
|
||||
```typescript
|
||||
// DANGEROUS - SQL Injection vulnerability
|
||||
const query = `SELECT * FROM users WHERE email = '${userEmail}'`
|
||||
await db.query(query)
|
||||
```
|
||||
|
||||
#### ✅ ALWAYS Use Parameterized Queries
|
||||
#### PASS: ALWAYS Use Parameterized Queries
|
||||
```typescript
|
||||
// Safe - parameterized query
|
||||
const { data } = await supabase
|
||||
@@ -142,10 +142,10 @@ await db.query(
|
||||
|
||||
#### JWT Token Handling
|
||||
```typescript
|
||||
// ❌ WRONG: localStorage (vulnerable to XSS)
|
||||
// FAIL: WRONG: localStorage (vulnerable to XSS)
|
||||
localStorage.setItem('token', token)
|
||||
|
||||
// ✅ CORRECT: httpOnly cookies
|
||||
// PASS: CORRECT: httpOnly cookies
|
||||
res.setHeader('Set-Cookie',
|
||||
`token=${token}; HttpOnly; Secure; SameSite=Strict; Max-Age=3600`)
|
||||
```
|
||||
@@ -302,18 +302,18 @@ app.use('/api/search', searchLimiter)
|
||||
|
||||
#### Logging
|
||||
```typescript
|
||||
// ❌ WRONG: Logging sensitive data
|
||||
// FAIL: WRONG: Logging sensitive data
|
||||
console.log('User login:', { email, password })
|
||||
console.log('Payment:', { cardNumber, cvv })
|
||||
|
||||
// ✅ CORRECT: Redact sensitive data
|
||||
// PASS: CORRECT: Redact sensitive data
|
||||
console.log('User login:', { email, userId })
|
||||
console.log('Payment:', { last4: card.last4, userId })
|
||||
```
|
||||
|
||||
#### Error Messages
|
||||
```typescript
|
||||
// ❌ WRONG: Exposing internal details
|
||||
// FAIL: WRONG: Exposing internal details
|
||||
catch (error) {
|
||||
return NextResponse.json(
|
||||
{ error: error.message, stack: error.stack },
|
||||
@@ -321,7 +321,7 @@ catch (error) {
|
||||
)
|
||||
}
|
||||
|
||||
// ✅ CORRECT: Generic error messages
|
||||
// PASS: CORRECT: Generic error messages
|
||||
catch (error) {
|
||||
console.error('Internal error:', error)
|
||||
return NextResponse.json(
|
||||
|
||||
@@ -318,39 +318,39 @@ npm run test:coverage
|
||||
|
||||
## Common Testing Mistakes to Avoid
|
||||
|
||||
### ❌ WRONG: Testing Implementation Details
|
||||
### FAIL: WRONG: Testing Implementation Details
|
||||
```typescript
|
||||
// Don't test internal state
|
||||
expect(component.state.count).toBe(5)
|
||||
```
|
||||
|
||||
### ✅ CORRECT: Test User-Visible Behavior
|
||||
### PASS: CORRECT: Test User-Visible Behavior
|
||||
```typescript
|
||||
// Test what users see
|
||||
expect(screen.getByText('Count: 5')).toBeInTheDocument()
|
||||
```
|
||||
|
||||
### ❌ WRONG: Brittle Selectors
|
||||
### FAIL: WRONG: Brittle Selectors
|
||||
```typescript
|
||||
// Breaks easily
|
||||
await page.click('.css-class-xyz')
|
||||
```
|
||||
|
||||
### ✅ CORRECT: Semantic Selectors
|
||||
### PASS: CORRECT: Semantic Selectors
|
||||
```typescript
|
||||
// Resilient to changes
|
||||
await page.click('button:has-text("Submit")')
|
||||
await page.click('[data-testid="submit-button"]')
|
||||
```
|
||||
|
||||
### ❌ WRONG: No Test Isolation
|
||||
### FAIL: WRONG: No Test Isolation
|
||||
```typescript
|
||||
// Tests depend on each other
|
||||
test('creates user', () => { /* ... */ })
|
||||
test('updates same user', () => { /* depends on previous test */ })
|
||||
```
|
||||
|
||||
### ✅ CORRECT: Independent Tests
|
||||
### PASS: CORRECT: Independent Tests
|
||||
```typescript
|
||||
// Each test sets up its own data
|
||||
test('creates user', () => {
|
||||
|
||||
28
.mcp.json
Normal file
28
.mcp.json
Normal file
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"mcpServers": {
|
||||
"github": {
|
||||
"command": "npx",
|
||||
"args": ["-y", "@modelcontextprotocol/server-github"]
|
||||
},
|
||||
"context7": {
|
||||
"command": "npx",
|
||||
"args": ["-y", "@upstash/context7-mcp@2.1.4"]
|
||||
},
|
||||
"exa": {
|
||||
"type": "http",
|
||||
"url": "https://mcp.exa.ai/mcp"
|
||||
},
|
||||
"memory": {
|
||||
"command": "npx",
|
||||
"args": ["-y", "@modelcontextprotocol/server-memory"]
|
||||
},
|
||||
"playwright": {
|
||||
"command": "npx",
|
||||
"args": ["-y", "@playwright/mcp@0.0.68", "--extension"]
|
||||
},
|
||||
"sequential-thinking": {
|
||||
"command": "npx",
|
||||
"args": ["-y", "@modelcontextprotocol/server-sequential-thinking"]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -353,13 +353,13 @@ If you need to switch back:
|
||||
|
||||
| Feature | Claude Code | OpenCode | Status |
|
||||
|---------|-------------|----------|--------|
|
||||
| Agents | ✅ 12 agents | ✅ 12 agents | **Full parity** |
|
||||
| Commands | ✅ 23 commands | ✅ 23 commands | **Full parity** |
|
||||
| Skills | ✅ 16 skills | ✅ 16 skills | **Full parity** |
|
||||
| Hooks | ✅ 3 phases | ✅ 20+ events | **OpenCode has MORE** |
|
||||
| Rules | ✅ 8 rules | ✅ 8 rules | **Full parity** |
|
||||
| MCP Servers | ✅ Full | ✅ Full | **Full parity** |
|
||||
| Custom Tools | ✅ Via hooks | ✅ Native support | **OpenCode is better** |
|
||||
| Agents | PASS: 12 agents | PASS: 12 agents | **Full parity** |
|
||||
| Commands | PASS: 23 commands | PASS: 23 commands | **Full parity** |
|
||||
| Skills | PASS: 16 skills | PASS: 16 skills | **Full parity** |
|
||||
| Hooks | PASS: 3 phases | PASS: 20+ events | **OpenCode has MORE** |
|
||||
| Rules | PASS: 8 rules | PASS: 8 rules | **Full parity** |
|
||||
| MCP Servers | PASS: Full | PASS: Full | **Full parity** |
|
||||
| Custom Tools | PASS: Via hooks | PASS: Native support | **OpenCode is better** |
|
||||
|
||||
## Feedback
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# OpenCode ECC Plugin
|
||||
|
||||
> ⚠️ This README is specific to OpenCode usage.
|
||||
> WARNING: This README is specific to OpenCode usage.
|
||||
> If you installed ECC via npm (e.g. `npm install opencode-ecc`), refer to the root README instead.
|
||||
|
||||
Everything Claude Code (ECC) plugin for OpenCode - agents, commands, hooks, and skills.
|
||||
@@ -11,10 +11,10 @@ Everything Claude Code (ECC) plugin for OpenCode - agents, commands, hooks, and
|
||||
|
||||
There are two ways to use Everything Claude Code (ECC):
|
||||
|
||||
1. **npm package (recommended for most users)**
|
||||
1. **npm package (recommended for most users)**
|
||||
Install via npm/bun/yarn and use the `ecc-install` CLI to set up rules and agents.
|
||||
|
||||
2. **Direct clone / plugin mode**
|
||||
2. **Direct clone / plugin mode**
|
||||
Clone the repository and run OpenCode directly inside it.
|
||||
|
||||
Choose the method that matches your workflow below.
|
||||
|
||||
@@ -19,20 +19,20 @@ Fix build and TypeScript errors with minimal changes: $ARGUMENTS
|
||||
## Approach
|
||||
|
||||
### DO:
|
||||
- ✅ Fix type errors with correct types
|
||||
- ✅ Add missing imports
|
||||
- ✅ Fix syntax errors
|
||||
- ✅ Make minimal changes
|
||||
- ✅ Preserve existing behavior
|
||||
- ✅ Run `tsc --noEmit` after each change
|
||||
- PASS: Fix type errors with correct types
|
||||
- PASS: Add missing imports
|
||||
- PASS: Fix syntax errors
|
||||
- PASS: Make minimal changes
|
||||
- PASS: Preserve existing behavior
|
||||
- PASS: Run `tsc --noEmit` after each change
|
||||
|
||||
### DON'T:
|
||||
- ❌ Refactor code
|
||||
- ❌ Add new features
|
||||
- ❌ Change architecture
|
||||
- ❌ Use `any` type (unless absolutely necessary)
|
||||
- ❌ Add `@ts-ignore` comments
|
||||
- ❌ Change business logic
|
||||
- FAIL: Refactor code
|
||||
- FAIL: Add new features
|
||||
- FAIL: Change architecture
|
||||
- FAIL: Use `any` type (unless absolutely necessary)
|
||||
- FAIL: Add `@ts-ignore` comments
|
||||
- FAIL: Change business logic
|
||||
|
||||
## Common Error Fixes
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ Create a snapshot of current progress including:
|
||||
- Coverage: XX%
|
||||
|
||||
**Build**
|
||||
- Status: ✅ Passing / ❌ Failing
|
||||
- Status: PASS: Passing / FAIL: Failing
|
||||
- Errors: [if any]
|
||||
|
||||
**Changes Since Last Checkpoint**
|
||||
|
||||
@@ -90,9 +90,9 @@ test.describe('Feature: [Name]', () => {
|
||||
```
|
||||
E2E Test Results
|
||||
================
|
||||
✅ Passed: X
|
||||
❌ Failed: Y
|
||||
⏭️ Skipped: Z
|
||||
PASS: Passed: X
|
||||
FAIL: Failed: Y
|
||||
SKIPPED: Skipped: Z
|
||||
|
||||
Failed Tests:
|
||||
- test-name: Error message
|
||||
|
||||
@@ -47,17 +47,17 @@ Execute comprehensive verification:
|
||||
## Verification Report
|
||||
|
||||
### Summary
|
||||
- Status: ✅ PASS / ❌ FAIL
|
||||
- Status: PASS: PASS / FAIL: FAIL
|
||||
- Score: X/Y checks passed
|
||||
|
||||
### Details
|
||||
| Check | Status | Notes |
|
||||
|-------|--------|-------|
|
||||
| TypeScript | ✅/❌ | [details] |
|
||||
| Lint | ✅/❌ | [details] |
|
||||
| Tests | ✅/❌ | [details] |
|
||||
| Coverage | ✅/❌ | XX% (target: 80%) |
|
||||
| Build | ✅/❌ | [details] |
|
||||
| TypeScript | PASS:/FAIL: | [details] |
|
||||
| Lint | PASS:/FAIL: | [details] |
|
||||
| Tests | PASS:/FAIL: | [details] |
|
||||
| Coverage | PASS:/FAIL: | XX% (target: 80%) |
|
||||
| Build | PASS:/FAIL: | [details] |
|
||||
|
||||
### Action Items
|
||||
[If FAIL, list what needs to be fixed]
|
||||
|
||||
184
.trae/README.md
Normal file
184
.trae/README.md
Normal file
@@ -0,0 +1,184 @@
|
||||
# Everything Claude Code for Trae
|
||||
|
||||
Bring Everything Claude Code (ECC) workflows to Trae IDE. This repository provides custom commands, agents, skills, and rules that can be installed into any Trae project with a single command.
|
||||
|
||||
## Quick Start
|
||||
|
||||
### Option 1: Local Installation (Current Project Only)
|
||||
|
||||
```bash
|
||||
# Install to current project
|
||||
cd /path/to/your/project
|
||||
TRAE_ENV=cn .trae/install.sh
|
||||
```
|
||||
|
||||
This creates `.trae-cn/` in your project directory.
|
||||
|
||||
### Option 2: Global Installation (All Projects)
|
||||
|
||||
```bash
|
||||
# Install globally to ~/.trae-cn/
|
||||
cd /path/to/your/project
|
||||
TRAE_ENV=cn .trae/install.sh ~
|
||||
|
||||
# Or from the .trae folder directly
|
||||
cd /path/to/your/project/.trae
|
||||
TRAE_ENV=cn ./install.sh ~
|
||||
```
|
||||
|
||||
This creates `~/.trae-cn/` which applies to all Trae projects.
|
||||
|
||||
### Option 3: Quick Install to Current Directory
|
||||
|
||||
```bash
|
||||
# If already in project directory with .trae folder
|
||||
cd .trae
|
||||
./install.sh
|
||||
```
|
||||
|
||||
The installer uses non-destructive copy - it will not overwrite your existing files.
|
||||
|
||||
## Installation Modes
|
||||
|
||||
### Local Installation
|
||||
|
||||
Install to the current project's `.trae-cn` directory:
|
||||
|
||||
```bash
|
||||
cd /path/to/your/project
|
||||
TRAE_ENV=cn .trae/install.sh
|
||||
```
|
||||
|
||||
This creates `/path/to/your/project/.trae-cn/` with all ECC components.
|
||||
|
||||
### Global Installation
|
||||
|
||||
Install to your home directory's `.trae-cn` directory (applies to all Trae projects):
|
||||
|
||||
```bash
|
||||
# From project directory
|
||||
TRAE_ENV=cn .trae/install.sh ~
|
||||
|
||||
# Or directly from .trae folder
|
||||
cd .trae
|
||||
TRAE_ENV=cn ./install.sh ~
|
||||
```
|
||||
|
||||
This creates `~/.trae-cn/` with all ECC components. All Trae projects will use these global installations.
|
||||
|
||||
**Note**: Global installation is useful when you want to maintain a single copy of ECC across all your projects.
|
||||
|
||||
## Environment Support
|
||||
|
||||
- **Default**: Uses `.trae` directory
|
||||
- **CN Environment**: Uses `.trae-cn` directory (set via `TRAE_ENV=cn`)
|
||||
|
||||
### Force Environment
|
||||
|
||||
```bash
|
||||
# From project root, force the CN environment
|
||||
TRAE_ENV=cn .trae/install.sh
|
||||
|
||||
# From inside the .trae folder
|
||||
cd .trae
|
||||
TRAE_ENV=cn ./install.sh
|
||||
```
|
||||
|
||||
**Note**: `TRAE_ENV` is a global environment variable that applies to the entire installation session.
|
||||
|
||||
## Uninstall
|
||||
|
||||
The uninstaller uses a manifest file (`.ecc-manifest`) to track installed files, ensuring safe removal:
|
||||
|
||||
```bash
|
||||
# Uninstall from current directory (if already inside .trae or .trae-cn)
|
||||
cd .trae-cn
|
||||
./uninstall.sh
|
||||
|
||||
# Or uninstall from project root
|
||||
cd /path/to/your/project
|
||||
TRAE_ENV=cn .trae/uninstall.sh
|
||||
|
||||
# Uninstall globally from home directory
|
||||
TRAE_ENV=cn .trae/uninstall.sh ~
|
||||
|
||||
# Will ask for confirmation before uninstalling
|
||||
```
|
||||
|
||||
### Uninstall Behavior
|
||||
|
||||
- **Safe removal**: Only removes files tracked in the manifest (installed by ECC)
|
||||
- **User files preserved**: Any files you added manually are kept
|
||||
- **Non-empty directories**: Directories containing user-added files are skipped
|
||||
- **Manifest-based**: Requires `.ecc-manifest` file (created during install)
|
||||
|
||||
### Environment Support
|
||||
|
||||
Uninstall respects the same `TRAE_ENV` environment variable as install:
|
||||
|
||||
```bash
|
||||
# Uninstall from .trae-cn (CN environment)
|
||||
TRAE_ENV=cn ./uninstall.sh
|
||||
|
||||
# Uninstall from .trae (default environment)
|
||||
./uninstall.sh
|
||||
```
|
||||
|
||||
**Note**: If no manifest file is found (old installation), the uninstaller will ask whether to remove the entire directory.
|
||||
|
||||
## What's Included
|
||||
|
||||
### Commands
|
||||
|
||||
Commands are on-demand workflows invocable via the `/` menu in Trae chat. All commands are reused directly from the project root's `commands/` folder.
|
||||
|
||||
### Agents
|
||||
|
||||
Agents are specialized AI assistants with specific tool configurations. All agents are reused directly from the project root's `agents/` folder.
|
||||
|
||||
### Skills
|
||||
|
||||
Skills are on-demand workflows invocable via the `/` menu in chat. All skills are reused directly from the project's `skills/` folder.
|
||||
|
||||
### Rules
|
||||
|
||||
Rules provide always-on rules and context that shape how the agent works with your code. All rules are reused directly from the project root's `rules/` folder.
|
||||
|
||||
## Usage
|
||||
|
||||
1. Type `/` in chat to open the commands menu
|
||||
2. Select a command or skill
|
||||
3. The agent will guide you through the workflow with specific instructions and checklists
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
.trae/ (or .trae-cn/)
|
||||
├── commands/ # Command files (reused from project root)
|
||||
├── agents/ # Agent files (reused from project root)
|
||||
├── skills/ # Skill files (reused from skills/)
|
||||
├── rules/ # Rule files (reused from project root)
|
||||
├── install.sh # Install script
|
||||
├── uninstall.sh # Uninstall script
|
||||
└── README.md # This file
|
||||
```
|
||||
|
||||
## Customization
|
||||
|
||||
All files are yours to modify after installation. The installer never overwrites existing files, so your customizations are safe across re-installs.
|
||||
|
||||
**Note**: The `install.sh` and `uninstall.sh` scripts are automatically copied to the target directory during installation, so you can run these commands directly from your project.
|
||||
|
||||
## Recommended Workflow
|
||||
|
||||
1. **Start with planning**: Use `/plan` command to break down complex features
|
||||
2. **Write tests first**: Invoke `/tdd` command before implementing
|
||||
3. **Review your code**: Use `/code-review` after writing code
|
||||
4. **Check security**: Use `/code-review` again for auth, API endpoints, or sensitive data handling
|
||||
5. **Fix build errors**: Use `/build-fix` if there are build errors
|
||||
|
||||
## Next Steps
|
||||
|
||||
- Open your project in Trae
|
||||
- Type `/` to see available commands
|
||||
- Enjoy the ECC workflows!
|
||||
192
.trae/README.zh-CN.md
Normal file
192
.trae/README.zh-CN.md
Normal file
@@ -0,0 +1,192 @@
|
||||
# Everything Claude Code for Trae
|
||||
|
||||
为 Trae IDE 带来 Everything Claude Code (ECC) 工作流。此仓库提供自定义命令、智能体、技能和规则,可以通过单个命令安装到任何 Trae 项目中。
|
||||
|
||||
## 快速开始
|
||||
|
||||
### 方式一:本地安装到 `.trae` 目录(默认环境)
|
||||
|
||||
```bash
|
||||
# 安装到当前项目的 .trae 目录
|
||||
cd /path/to/your/project
|
||||
.trae/install.sh
|
||||
```
|
||||
|
||||
这将在您的项目目录中创建 `.trae/`。
|
||||
|
||||
### 方式二:本地安装到 `.trae-cn` 目录(CN 环境)
|
||||
|
||||
```bash
|
||||
# 安装到当前项目的 .trae-cn 目录
|
||||
cd /path/to/your/project
|
||||
TRAE_ENV=cn .trae/install.sh
|
||||
```
|
||||
|
||||
这将在您的项目目录中创建 `.trae-cn/`。
|
||||
|
||||
### 方式三:全局安装到 `~/.trae` 目录(默认环境)
|
||||
|
||||
```bash
|
||||
# 全局安装到 ~/.trae/
|
||||
cd /path/to/your/project
|
||||
.trae/install.sh ~
|
||||
```
|
||||
|
||||
这将创建 `~/.trae/`,适用于所有 Trae 项目。
|
||||
|
||||
### 方式四:全局安装到 `~/.trae-cn` 目录(CN 环境)
|
||||
|
||||
```bash
|
||||
# 全局安装到 ~/.trae-cn/
|
||||
cd /path/to/your/project
|
||||
TRAE_ENV=cn .trae/install.sh ~
|
||||
```
|
||||
|
||||
这将创建 `~/.trae-cn/`,适用于所有 Trae 项目。
|
||||
|
||||
安装程序使用非破坏性复制 - 它不会覆盖您现有的文件。
|
||||
|
||||
## 安装模式
|
||||
|
||||
### 本地安装
|
||||
|
||||
安装到当前项目的 `.trae` 或 `.trae-cn` 目录:
|
||||
|
||||
```bash
|
||||
# 安装到当前项目的 .trae 目录(默认)
|
||||
cd /path/to/your/project
|
||||
.trae/install.sh
|
||||
|
||||
# 安装到当前项目的 .trae-cn 目录(CN 环境)
|
||||
cd /path/to/your/project
|
||||
TRAE_ENV=cn .trae/install.sh
|
||||
```
|
||||
|
||||
### 全局安装
|
||||
|
||||
安装到您主目录的 `.trae` 或 `.trae-cn` 目录(适用于所有 Trae 项目):
|
||||
|
||||
```bash
|
||||
# 全局安装到 ~/.trae/(默认)
|
||||
.trae/install.sh ~
|
||||
|
||||
# 全局安装到 ~/.trae-cn/(CN 环境)
|
||||
TRAE_ENV=cn .trae/install.sh ~
|
||||
```
|
||||
|
||||
**注意**:全局安装适用于希望在所有项目之间维护单个 ECC 副本的场景。
|
||||
|
||||
## 环境支持
|
||||
|
||||
- **默认**:使用 `.trae` 目录
|
||||
- **CN 环境**:使用 `.trae-cn` 目录(通过 `TRAE_ENV=cn` 设置)
|
||||
|
||||
### 强制指定环境
|
||||
|
||||
```bash
|
||||
# 从项目根目录强制使用 CN 环境
|
||||
TRAE_ENV=cn .trae/install.sh
|
||||
|
||||
# 进入 .trae 目录后使用默认环境
|
||||
cd .trae
|
||||
./install.sh
|
||||
```
|
||||
|
||||
**注意**:`TRAE_ENV` 是一个全局环境变量,适用于整个安装会话。
|
||||
|
||||
## 卸载
|
||||
|
||||
卸载程序使用清单文件(`.ecc-manifest`)跟踪已安装的文件,确保安全删除:
|
||||
|
||||
```bash
|
||||
# 从当前目录卸载(如果已经在 .trae 或 .trae-cn 目录中)
|
||||
cd .trae-cn
|
||||
./uninstall.sh
|
||||
|
||||
# 或者从项目根目录卸载
|
||||
cd /path/to/your/project
|
||||
TRAE_ENV=cn .trae/uninstall.sh
|
||||
|
||||
# 从主目录全局卸载
|
||||
TRAE_ENV=cn .trae/uninstall.sh ~
|
||||
|
||||
# 卸载前会询问确认
|
||||
```
|
||||
|
||||
### 卸载行为
|
||||
|
||||
- **安全删除**:仅删除清单中跟踪的文件(由 ECC 安装的文件)
|
||||
- **保留用户文件**:您手动添加的任何文件都会被保留
|
||||
- **非空目录**:包含用户添加文件的目录会被跳过
|
||||
- **基于清单**:需要 `.ecc-manifest` 文件(在安装时创建)
|
||||
|
||||
### 环境支持
|
||||
|
||||
卸载程序遵循与安装程序相同的 `TRAE_ENV` 环境变量:
|
||||
|
||||
```bash
|
||||
# 从 .trae-cn 卸载(CN 环境)
|
||||
TRAE_ENV=cn ./uninstall.sh
|
||||
|
||||
# 从 .trae 卸载(默认环境)
|
||||
./uninstall.sh
|
||||
```
|
||||
|
||||
**注意**:如果找不到清单文件(旧版本安装),卸载程序将询问是否删除整个目录。
|
||||
|
||||
## 包含的内容
|
||||
|
||||
### 命令
|
||||
|
||||
命令是通过 Trae 聊天中的 `/` 菜单调用的按需工作流。所有命令都直接复用自项目根目录的 `commands/` 文件夹。
|
||||
|
||||
### 智能体
|
||||
|
||||
智能体是具有特定工具配置的专门 AI 助手。所有智能体都直接复用自项目根目录的 `agents/` 文件夹。
|
||||
|
||||
### 技能
|
||||
|
||||
技能是通过聊天中的 `/` 菜单调用的按需工作流。所有技能都直接复用自项目的 `skills/` 文件夹。
|
||||
|
||||
### 规则
|
||||
|
||||
规则提供始终适用的规则和上下文,塑造智能体处理代码的方式。所有规则都直接复用自项目根目录的 `rules/` 文件夹。
|
||||
|
||||
## 使用方法
|
||||
|
||||
1. 在聊天中输入 `/` 以打开命令菜单
|
||||
2. 选择一个命令或技能
|
||||
3. 智能体将通过具体说明和检查清单指导您完成工作流
|
||||
|
||||
## 项目结构
|
||||
|
||||
```
|
||||
.trae/ (或 .trae-cn/)
|
||||
├── commands/ # 命令文件(复用自项目根目录)
|
||||
├── agents/ # 智能体文件(复用自项目根目录)
|
||||
├── skills/ # 技能文件(复用自 skills/)
|
||||
├── rules/ # 规则文件(复用自项目根目录)
|
||||
├── install.sh # 安装脚本
|
||||
├── uninstall.sh # 卸载脚本
|
||||
└── README.md # 此文件
|
||||
```
|
||||
|
||||
## 自定义
|
||||
|
||||
安装后,所有文件都归您修改。安装程序永远不会覆盖现有文件,因此您的自定义在重新安装时是安全的。
|
||||
|
||||
**注意**:安装时会自动将 `install.sh` 和 `uninstall.sh` 脚本复制到目标目录,这样您可以在项目本地直接运行这些命令。
|
||||
|
||||
## 推荐的工作流
|
||||
|
||||
1. **从计划开始**:使用 `/plan` 命令分解复杂功能
|
||||
2. **先写测试**:在实现之前调用 `/tdd` 命令
|
||||
3. **审查您的代码**:编写代码后使用 `/code-review`
|
||||
4. **检查安全性**:对于身份验证、API 端点或敏感数据处理,再次使用 `/code-review`
|
||||
5. **修复构建错误**:如果有构建错误,使用 `/build-fix`
|
||||
|
||||
## 下一步
|
||||
|
||||
- 在 Trae 中打开您的项目
|
||||
- 输入 `/` 以查看可用命令
|
||||
- 享受 ECC 工作流!
|
||||
221
.trae/install.sh
Executable file
221
.trae/install.sh
Executable file
@@ -0,0 +1,221 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# ECC Trae Installer
|
||||
# Installs Everything Claude Code workflows into a Trae project.
|
||||
#
|
||||
# Usage:
|
||||
# ./install.sh # Install to current directory
|
||||
# ./install.sh ~ # Install globally to ~/.trae/ or ~/.trae-cn/
|
||||
#
|
||||
# Environment:
|
||||
# TRAE_ENV=cn # Force use .trae-cn directory
|
||||
#
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# When globs match nothing, expand to empty list instead of the literal pattern
|
||||
shopt -s nullglob
|
||||
|
||||
# Resolve the directory where this script lives (the repo root)
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
REPO_ROOT="$(dirname "$SCRIPT_DIR")"
|
||||
|
||||
# Get the trae directory name (.trae or .trae-cn)
|
||||
get_trae_dir() {
|
||||
if [ "${TRAE_ENV:-}" = "cn" ]; then
|
||||
echo ".trae-cn"
|
||||
else
|
||||
echo ".trae"
|
||||
fi
|
||||
}
|
||||
|
||||
ensure_manifest_entry() {
|
||||
local manifest="$1"
|
||||
local entry="$2"
|
||||
|
||||
touch "$manifest"
|
||||
if ! grep -Fqx "$entry" "$manifest"; then
|
||||
echo "$entry" >> "$manifest"
|
||||
fi
|
||||
}
|
||||
|
||||
# Install function
|
||||
do_install() {
|
||||
local target_dir="$PWD"
|
||||
local trae_dir="$(get_trae_dir)"
|
||||
|
||||
# Check if ~ was specified (or expanded to $HOME)
|
||||
if [ "$#" -ge 1 ]; then
|
||||
if [ "$1" = "~" ] || [ "$1" = "$HOME" ]; then
|
||||
target_dir="$HOME"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check if we're already inside a .trae or .trae-cn directory
|
||||
local current_dir_name="$(basename "$target_dir")"
|
||||
local trae_full_path
|
||||
|
||||
if [ "$current_dir_name" = ".trae" ] || [ "$current_dir_name" = ".trae-cn" ]; then
|
||||
# Already inside the trae directory, use it directly
|
||||
trae_full_path="$target_dir"
|
||||
else
|
||||
# Normal case: append trae_dir to target_dir
|
||||
trae_full_path="$target_dir/$trae_dir"
|
||||
fi
|
||||
|
||||
echo "ECC Trae Installer"
|
||||
echo "=================="
|
||||
echo ""
|
||||
echo "Source: $REPO_ROOT"
|
||||
echo "Target: $trae_full_path/"
|
||||
echo ""
|
||||
|
||||
# Subdirectories to create
|
||||
SUBDIRS="commands agents skills rules"
|
||||
|
||||
# Create all required trae subdirectories
|
||||
for dir in $SUBDIRS; do
|
||||
mkdir -p "$trae_full_path/$dir"
|
||||
done
|
||||
|
||||
# Manifest file to track installed files
|
||||
MANIFEST="$trae_full_path/.ecc-manifest"
|
||||
touch "$MANIFEST"
|
||||
|
||||
# Counters for summary
|
||||
commands=0
|
||||
agents=0
|
||||
skills=0
|
||||
rules=0
|
||||
other=0
|
||||
|
||||
# Copy commands from repo root
|
||||
if [ -d "$REPO_ROOT/commands" ]; then
|
||||
for f in "$REPO_ROOT/commands"/*.md; do
|
||||
[ -f "$f" ] || continue
|
||||
local_name=$(basename "$f")
|
||||
target_path="$trae_full_path/commands/$local_name"
|
||||
if [ ! -f "$target_path" ]; then
|
||||
cp "$f" "$target_path"
|
||||
ensure_manifest_entry "$MANIFEST" "commands/$local_name"
|
||||
commands=$((commands + 1))
|
||||
else
|
||||
ensure_manifest_entry "$MANIFEST" "commands/$local_name"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# Copy agents from repo root
|
||||
if [ -d "$REPO_ROOT/agents" ]; then
|
||||
for f in "$REPO_ROOT/agents"/*.md; do
|
||||
[ -f "$f" ] || continue
|
||||
local_name=$(basename "$f")
|
||||
target_path="$trae_full_path/agents/$local_name"
|
||||
if [ ! -f "$target_path" ]; then
|
||||
cp "$f" "$target_path"
|
||||
ensure_manifest_entry "$MANIFEST" "agents/$local_name"
|
||||
agents=$((agents + 1))
|
||||
else
|
||||
ensure_manifest_entry "$MANIFEST" "agents/$local_name"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# Copy skills from repo root (if available)
|
||||
if [ -d "$REPO_ROOT/skills" ]; then
|
||||
for d in "$REPO_ROOT/skills"/*/; do
|
||||
[ -d "$d" ] || continue
|
||||
skill_name="$(basename "$d")"
|
||||
target_skill_dir="$trae_full_path/skills/$skill_name"
|
||||
skill_copied=0
|
||||
|
||||
while IFS= read -r source_file; do
|
||||
relative_path="${source_file#$d}"
|
||||
target_path="$target_skill_dir/$relative_path"
|
||||
|
||||
mkdir -p "$(dirname "$target_path")"
|
||||
if [ ! -f "$target_path" ]; then
|
||||
cp "$source_file" "$target_path"
|
||||
skill_copied=1
|
||||
fi
|
||||
ensure_manifest_entry "$MANIFEST" "skills/$skill_name/$relative_path"
|
||||
done < <(find "$d" -type f | sort)
|
||||
|
||||
if [ "$skill_copied" -eq 1 ]; then
|
||||
skills=$((skills + 1))
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# Copy rules from repo root
|
||||
if [ -d "$REPO_ROOT/rules" ]; then
|
||||
while IFS= read -r rule_file; do
|
||||
relative_path="${rule_file#$REPO_ROOT/rules/}"
|
||||
target_path="$trae_full_path/rules/$relative_path"
|
||||
|
||||
mkdir -p "$(dirname "$target_path")"
|
||||
if [ ! -f "$target_path" ]; then
|
||||
cp "$rule_file" "$target_path"
|
||||
rules=$((rules + 1))
|
||||
fi
|
||||
ensure_manifest_entry "$MANIFEST" "rules/$relative_path"
|
||||
done < <(find "$REPO_ROOT/rules" -type f | sort)
|
||||
fi
|
||||
|
||||
# Copy README files from this directory
|
||||
for readme_file in "$SCRIPT_DIR/README.md" "$SCRIPT_DIR/README.zh-CN.md"; do
|
||||
if [ -f "$readme_file" ]; then
|
||||
local_name=$(basename "$readme_file")
|
||||
target_path="$trae_full_path/$local_name"
|
||||
if [ ! -f "$target_path" ]; then
|
||||
cp "$readme_file" "$target_path"
|
||||
ensure_manifest_entry "$MANIFEST" "$local_name"
|
||||
other=$((other + 1))
|
||||
else
|
||||
ensure_manifest_entry "$MANIFEST" "$local_name"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
# Copy install and uninstall scripts
|
||||
for script_file in "$SCRIPT_DIR/install.sh" "$SCRIPT_DIR/uninstall.sh"; do
|
||||
if [ -f "$script_file" ]; then
|
||||
local_name=$(basename "$script_file")
|
||||
target_path="$trae_full_path/$local_name"
|
||||
if [ ! -f "$target_path" ]; then
|
||||
cp "$script_file" "$target_path"
|
||||
chmod +x "$target_path"
|
||||
ensure_manifest_entry "$MANIFEST" "$local_name"
|
||||
other=$((other + 1))
|
||||
else
|
||||
ensure_manifest_entry "$MANIFEST" "$local_name"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
# Add manifest file itself to manifest
|
||||
ensure_manifest_entry "$MANIFEST" ".ecc-manifest"
|
||||
|
||||
# Installation summary
|
||||
echo "Installation complete!"
|
||||
echo ""
|
||||
echo "Components installed:"
|
||||
echo " Commands: $commands"
|
||||
echo " Agents: $agents"
|
||||
echo " Skills: $skills"
|
||||
echo " Rules: $rules"
|
||||
echo ""
|
||||
echo "Directory: $(basename "$trae_full_path")"
|
||||
echo ""
|
||||
echo "Next steps:"
|
||||
echo " 1. Open your project in Trae"
|
||||
echo " 2. Type / to see available commands"
|
||||
echo " 3. Enjoy the ECC workflows!"
|
||||
echo ""
|
||||
echo "To uninstall later:"
|
||||
echo " cd $trae_full_path"
|
||||
echo " ./uninstall.sh"
|
||||
}
|
||||
|
||||
# Main logic
|
||||
do_install "$@"
|
||||
194
.trae/uninstall.sh
Executable file
194
.trae/uninstall.sh
Executable file
@@ -0,0 +1,194 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# ECC Trae Uninstaller
|
||||
# Uninstalls Everything Claude Code workflows from a Trae project.
|
||||
#
|
||||
# Usage:
|
||||
# ./uninstall.sh # Uninstall from current directory
|
||||
# ./uninstall.sh ~ # Uninstall globally from ~/.trae/
|
||||
#
|
||||
# Environment:
|
||||
# TRAE_ENV=cn # Force use .trae-cn directory
|
||||
#
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Resolve the directory where this script lives
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
|
||||
# Get the trae directory name (.trae or .trae-cn)
|
||||
get_trae_dir() {
|
||||
# Check environment variable first
|
||||
if [ "${TRAE_ENV:-}" = "cn" ]; then
|
||||
echo ".trae-cn"
|
||||
else
|
||||
echo ".trae"
|
||||
fi
|
||||
}
|
||||
|
||||
resolve_path() {
|
||||
python3 -c 'import os, sys; print(os.path.realpath(sys.argv[1]))' "$1"
|
||||
}
|
||||
|
||||
is_valid_manifest_entry() {
|
||||
local file_path="$1"
|
||||
|
||||
case "$file_path" in
|
||||
""|/*|~*|*/../*|../*|*/..|..)
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
# Main uninstall function
|
||||
do_uninstall() {
|
||||
local target_dir="$PWD"
|
||||
local trae_dir="$(get_trae_dir)"
|
||||
|
||||
# Check if ~ was specified (or expanded to $HOME)
|
||||
if [ "$#" -ge 1 ]; then
|
||||
if [ "$1" = "~" ] || [ "$1" = "$HOME" ]; then
|
||||
target_dir="$HOME"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check if we're already inside a .trae or .trae-cn directory
|
||||
local current_dir_name="$(basename "$target_dir")"
|
||||
local trae_full_path
|
||||
|
||||
if [ "$current_dir_name" = ".trae" ] || [ "$current_dir_name" = ".trae-cn" ]; then
|
||||
# Already inside the trae directory, use it directly
|
||||
trae_full_path="$target_dir"
|
||||
else
|
||||
# Normal case: append trae_dir to target_dir
|
||||
trae_full_path="$target_dir/$trae_dir"
|
||||
fi
|
||||
|
||||
echo "ECC Trae Uninstaller"
|
||||
echo "===================="
|
||||
echo ""
|
||||
echo "Target: $trae_full_path/"
|
||||
echo ""
|
||||
|
||||
if [ ! -d "$trae_full_path" ]; then
|
||||
echo "Error: $trae_dir directory not found at $target_dir"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
trae_root_resolved="$(resolve_path "$trae_full_path")"
|
||||
|
||||
# Manifest file path
|
||||
MANIFEST="$trae_full_path/.ecc-manifest"
|
||||
|
||||
if [ ! -f "$MANIFEST" ]; then
|
||||
echo "Warning: No manifest file found (.ecc-manifest)"
|
||||
echo ""
|
||||
echo "This could mean:"
|
||||
echo " 1. ECC was installed with an older version without manifest support"
|
||||
echo " 2. The manifest file was manually deleted"
|
||||
echo ""
|
||||
read -p "Do you want to remove the entire $trae_dir directory? (y/N) " -n 1 -r
|
||||
echo
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
echo "Uninstall cancelled."
|
||||
exit 0
|
||||
fi
|
||||
rm -rf "$trae_full_path"
|
||||
echo "Uninstall complete!"
|
||||
echo ""
|
||||
echo "Removed: $trae_full_path/"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "Found manifest file - will only remove files installed by ECC"
|
||||
echo ""
|
||||
read -p "Are you sure you want to uninstall ECC from $trae_dir? (y/N) " -n 1 -r
|
||||
echo
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
echo "Uninstall cancelled."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Counters
|
||||
removed=0
|
||||
skipped=0
|
||||
|
||||
# Read manifest and remove files
|
||||
while IFS= read -r file_path; do
|
||||
[ -z "$file_path" ] && continue
|
||||
|
||||
if ! is_valid_manifest_entry "$file_path"; then
|
||||
echo "Skipped: $file_path (invalid manifest entry)"
|
||||
skipped=$((skipped + 1))
|
||||
continue
|
||||
fi
|
||||
|
||||
full_path="$trae_full_path/$file_path"
|
||||
resolved_full="$(resolve_path "$full_path")"
|
||||
|
||||
case "$resolved_full" in
|
||||
"$trae_root_resolved"|"$trae_root_resolved"/*)
|
||||
;;
|
||||
*)
|
||||
echo "Skipped: $file_path (invalid manifest entry)"
|
||||
skipped=$((skipped + 1))
|
||||
continue
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -f "$resolved_full" ]; then
|
||||
rm -f "$resolved_full"
|
||||
echo "Removed: $file_path"
|
||||
removed=$((removed + 1))
|
||||
elif [ -d "$resolved_full" ]; then
|
||||
# Only remove directory if it's empty
|
||||
if [ -z "$(ls -A "$resolved_full" 2>/dev/null)" ]; then
|
||||
rmdir "$resolved_full" 2>/dev/null || true
|
||||
if [ ! -d "$resolved_full" ]; then
|
||||
echo "Removed: $file_path/"
|
||||
removed=$((removed + 1))
|
||||
fi
|
||||
else
|
||||
echo "Skipped: $file_path/ (not empty - contains user files)"
|
||||
skipped=$((skipped + 1))
|
||||
fi
|
||||
else
|
||||
skipped=$((skipped + 1))
|
||||
fi
|
||||
done < "$MANIFEST"
|
||||
|
||||
while IFS= read -r empty_dir; do
|
||||
[ "$empty_dir" = "$trae_full_path" ] && continue
|
||||
relative_dir="${empty_dir#$trae_full_path/}"
|
||||
rmdir "$empty_dir" 2>/dev/null || true
|
||||
if [ ! -d "$empty_dir" ]; then
|
||||
echo "Removed: $relative_dir/"
|
||||
removed=$((removed + 1))
|
||||
fi
|
||||
done < <(find "$trae_full_path" -depth -type d -empty 2>/dev/null | sort -r)
|
||||
|
||||
# Try to remove the main trae directory if it's empty
|
||||
if [ -d "$trae_full_path" ] && [ -z "$(ls -A "$trae_full_path" 2>/dev/null)" ]; then
|
||||
rmdir "$trae_full_path" 2>/dev/null || true
|
||||
if [ ! -d "$trae_full_path" ]; then
|
||||
echo "Removed: $trae_dir/"
|
||||
removed=$((removed + 1))
|
||||
fi
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Uninstall complete!"
|
||||
echo ""
|
||||
echo "Summary:"
|
||||
echo " Removed: $removed items"
|
||||
echo " Skipped: $skipped items (not found or user-modified)"
|
||||
echo ""
|
||||
if [ -d "$trae_full_path" ]; then
|
||||
echo "Note: $trae_dir directory still exists (contains user-added files)"
|
||||
fi
|
||||
}
|
||||
|
||||
# Execute uninstall
|
||||
do_uninstall "$@"
|
||||
1
.yarnrc.yml
Normal file
1
.yarnrc.yml
Normal file
@@ -0,0 +1 @@
|
||||
nodeLinker: node-modules
|
||||
@@ -1,6 +1,6 @@
|
||||
# Everything Claude Code (ECC) — Agent Instructions
|
||||
|
||||
This is a **production-ready AI coding plugin** providing 28 specialized agents, 125 skills, 60 commands, and automated hook workflows for software development.
|
||||
This is a **production-ready AI coding plugin** providing 30 specialized agents, 135 skills, 60 commands, and automated hook workflows for software development.
|
||||
|
||||
**Version:** 1.9.0
|
||||
|
||||
@@ -141,8 +141,8 @@ Troubleshoot failures: check test isolation → verify mocks → fix implementat
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
agents/ — 28 specialized subagents
|
||||
skills/ — 117 workflow skills and domain knowledge
|
||||
agents/ — 30 specialized subagents
|
||||
skills/ — 135 workflow skills and domain knowledge
|
||||
commands/ — 60 slash commands
|
||||
hooks/ — Trigger-based automations
|
||||
rules/ — Always-follow guidelines (common + per-language)
|
||||
|
||||
11
CLAUDE.md
11
CLAUDE.md
@@ -59,3 +59,14 @@ Follow the formats in CONTRIBUTING.md:
|
||||
- Hooks: JSON with matcher and hooks array
|
||||
|
||||
File naming: lowercase with hyphens (e.g., `python-reviewer.md`, `tdd-workflow.md`)
|
||||
|
||||
## Skills
|
||||
|
||||
Use the following skills when working on related files:
|
||||
|
||||
| File(s) | Skill |
|
||||
|---------|-------|
|
||||
| `README.md` | `/readme` |
|
||||
| `.github/workflows/*.yml` | `/ci-workflow` |
|
||||
|
||||
When spawning subagents, always pass conventions from the respective skill into the agent's prompt.
|
||||
|
||||
159
COMMANDS-QUICK-REF.md
Normal file
159
COMMANDS-QUICK-REF.md
Normal file
@@ -0,0 +1,159 @@
|
||||
# Commands Quick Reference
|
||||
|
||||
> 59 slash commands installed globally. Type `/` in any Claude Code session to invoke.
|
||||
|
||||
---
|
||||
|
||||
## Core Workflow
|
||||
|
||||
| Command | What it does |
|
||||
|---------|-------------|
|
||||
| `/plan` | Restate requirements, assess risks, write step-by-step implementation plan — **waits for your confirm before touching code** |
|
||||
| `/tdd` | Enforce test-driven development: scaffold interface → write failing test → implement → verify 80%+ coverage |
|
||||
| `/code-review` | Full code quality, security, and maintainability review of changed files |
|
||||
| `/build-fix` | Detect and fix build errors — delegates to the right build-resolver agent automatically |
|
||||
| `/verify` | Run the full verification loop: build → lint → test → type-check |
|
||||
| `/quality-gate` | Quality gate check against project standards |
|
||||
|
||||
---
|
||||
|
||||
## Testing
|
||||
|
||||
| Command | What it does |
|
||||
|---------|-------------|
|
||||
| `/tdd` | Universal TDD workflow (any language) |
|
||||
| `/e2e` | Generate + run Playwright end-to-end tests, capture screenshots/videos/traces |
|
||||
| `/test-coverage` | Report test coverage, identify gaps |
|
||||
| `/go-test` | TDD workflow for Go (table-driven, 80%+ coverage with `go test -cover`) |
|
||||
| `/kotlin-test` | TDD for Kotlin (Kotest + Kover) |
|
||||
| `/rust-test` | TDD for Rust (cargo test, integration tests) |
|
||||
| `/cpp-test` | TDD for C++ (GoogleTest + gcov/lcov) |
|
||||
|
||||
---
|
||||
|
||||
## Code Review
|
||||
|
||||
| Command | What it does |
|
||||
|---------|-------------|
|
||||
| `/code-review` | Universal code review |
|
||||
| `/python-review` | Python — PEP 8, type hints, security, idiomatic patterns |
|
||||
| `/go-review` | Go — idiomatic patterns, concurrency safety, error handling |
|
||||
| `/kotlin-review` | Kotlin — null safety, coroutine safety, clean architecture |
|
||||
| `/rust-review` | Rust — ownership, lifetimes, unsafe usage |
|
||||
| `/cpp-review` | C++ — memory safety, modern idioms, concurrency |
|
||||
|
||||
---
|
||||
|
||||
## Build Fixers
|
||||
|
||||
| Command | What it does |
|
||||
|---------|-------------|
|
||||
| `/build-fix` | Auto-detect language and fix build errors |
|
||||
| `/go-build` | Fix Go build errors and `go vet` warnings |
|
||||
| `/kotlin-build` | Fix Kotlin/Gradle compiler errors |
|
||||
| `/rust-build` | Fix Rust build + borrow checker issues |
|
||||
| `/cpp-build` | Fix C++ CMake and linker problems |
|
||||
| `/gradle-build` | Fix Gradle errors for Android / KMP |
|
||||
|
||||
---
|
||||
|
||||
## Planning & Architecture
|
||||
|
||||
| Command | What it does |
|
||||
|---------|-------------|
|
||||
| `/plan` | Implementation plan with risk assessment |
|
||||
| `/multi-plan` | Multi-model collaborative planning |
|
||||
| `/multi-workflow` | Multi-model collaborative development |
|
||||
| `/multi-backend` | Backend-focused multi-model development |
|
||||
| `/multi-frontend` | Frontend-focused multi-model development |
|
||||
| `/multi-execute` | Multi-model collaborative execution |
|
||||
| `/orchestrate` | Guide for tmux/worktree multi-agent orchestration |
|
||||
| `/devfleet` | Orchestrate parallel Claude Code agents via DevFleet |
|
||||
|
||||
---
|
||||
|
||||
## Session Management
|
||||
|
||||
| Command | What it does |
|
||||
|---------|-------------|
|
||||
| `/save-session` | Save current session state to `~/.claude/session-data/` |
|
||||
| `/resume-session` | Load the most recent saved session from the canonical session store and resume from where you left off |
|
||||
| `/sessions` | Browse, search, and manage session history with aliases from `~/.claude/session-data/` (with legacy reads from `~/.claude/sessions/`) |
|
||||
| `/checkpoint` | Mark a checkpoint in the current session |
|
||||
| `/aside` | Answer a quick side question without losing current task context |
|
||||
| `/context-budget` | Analyse context window usage — find token overhead, optimise |
|
||||
|
||||
---
|
||||
|
||||
## Learning & Improvement
|
||||
|
||||
| Command | What it does |
|
||||
|---------|-------------|
|
||||
| `/learn` | Extract reusable patterns from the current session |
|
||||
| `/learn-eval` | Extract patterns + self-evaluate quality before saving |
|
||||
| `/evolve` | Analyse learned instincts, suggest evolved skill structures |
|
||||
| `/promote` | Promote project-scoped instincts to global scope |
|
||||
| `/instinct-status` | Show all learned instincts (project + global) with confidence scores |
|
||||
| `/instinct-export` | Export instincts to a file |
|
||||
| `/instinct-import` | Import instincts from a file or URL |
|
||||
| `/skill-create` | Analyse local git history → generate a reusable skill |
|
||||
| `/skill-health` | Skill portfolio health dashboard with analytics |
|
||||
| `/rules-distill` | Scan skills, extract cross-cutting principles, distill into rules |
|
||||
|
||||
---
|
||||
|
||||
## Refactoring & Cleanup
|
||||
|
||||
| Command | What it does |
|
||||
|---------|-------------|
|
||||
| `/refactor-clean` | Remove dead code, consolidate duplicates, clean up structure |
|
||||
| `/prompt-optimize` | Analyse a draft prompt and output an optimised ECC-enriched version |
|
||||
|
||||
---
|
||||
|
||||
## Docs & Research
|
||||
|
||||
| Command | What it does |
|
||||
|---------|-------------|
|
||||
| `/docs` | Look up current library/API documentation via Context7 |
|
||||
| `/update-docs` | Update project documentation |
|
||||
| `/update-codemaps` | Regenerate codemaps for the codebase |
|
||||
|
||||
---
|
||||
|
||||
## Loops & Automation
|
||||
|
||||
| Command | What it does |
|
||||
|---------|-------------|
|
||||
| `/loop-start` | Start a recurring agent loop on an interval |
|
||||
| `/loop-status` | Check status of running loops |
|
||||
| `/claw` | Start NanoClaw v2 — persistent REPL with model routing, skill hot-load, branching, and metrics |
|
||||
|
||||
---
|
||||
|
||||
## Project & Infrastructure
|
||||
|
||||
| Command | What it does |
|
||||
|---------|-------------|
|
||||
| `/projects` | List known projects and their instinct statistics |
|
||||
| `/harness-audit` | Audit the agent harness configuration for reliability and cost |
|
||||
| `/eval` | Run the evaluation harness |
|
||||
| `/model-route` | Route a task to the right model (Haiku / Sonnet / Opus) |
|
||||
| `/pm2` | PM2 process manager initialisation |
|
||||
| `/setup-pm` | Configure package manager (npm / pnpm / yarn / bun) |
|
||||
|
||||
---
|
||||
|
||||
## Quick Decision Guide
|
||||
|
||||
```
|
||||
Starting a new feature? → /plan first, then /tdd
|
||||
Code just written? → /code-review
|
||||
Build broken? → /build-fix
|
||||
Need live docs? → /docs <library>
|
||||
Session about to end? → /save-session or /learn-eval
|
||||
Resuming next day? → /resume-session
|
||||
Context getting heavy? → /context-budget then /checkpoint
|
||||
Want to extract what you learned? → /learn-eval then /evolve
|
||||
Running repeated tasks? → /loop-start
|
||||
```
|
||||
@@ -73,6 +73,13 @@ git add . && git commit -m "feat: add my-skill" && git push -u origin feat/my-co
|
||||
|
||||
Skills are knowledge modules that Claude Code loads based on context.
|
||||
|
||||
> ** Comprehensive Guide:** For detailed guidance on creating effective skills, see [Skill Development Guide](docs/SKILL-DEVELOPMENT-GUIDE.md). It covers:
|
||||
> - Skill architecture and categories
|
||||
> - Writing effective content with examples
|
||||
> - Best practices and common patterns
|
||||
> - Testing and validation
|
||||
> - Complete examples gallery
|
||||
|
||||
### Directory Structure
|
||||
|
||||
```
|
||||
@@ -86,7 +93,7 @@ skills/
|
||||
```markdown
|
||||
---
|
||||
name: your-skill-name
|
||||
description: Brief description shown in skill list
|
||||
description: Brief description shown in skill list and used for auto-activation
|
||||
origin: ECC
|
||||
---
|
||||
|
||||
@@ -94,6 +101,10 @@ origin: ECC
|
||||
|
||||
Brief overview of what this skill covers.
|
||||
|
||||
## When to Activate
|
||||
|
||||
Describe scenarios where Claude should use this skill. This is critical for auto-activation.
|
||||
|
||||
## Core Concepts
|
||||
|
||||
Explain key patterns and guidelines.
|
||||
@@ -107,33 +118,54 @@ function example() {
|
||||
}
|
||||
\`\`\`
|
||||
|
||||
## Anti-Patterns
|
||||
|
||||
Show what NOT to do with examples.
|
||||
|
||||
## Best Practices
|
||||
|
||||
- Actionable guidelines
|
||||
- Do's and don'ts
|
||||
- Common pitfalls to avoid
|
||||
|
||||
## When to Use
|
||||
## Related Skills
|
||||
|
||||
Describe scenarios where this skill applies.
|
||||
Link to complementary skills (e.g., `related-skill-1`, `related-skill-2`).
|
||||
```
|
||||
|
||||
### Skill Categories
|
||||
|
||||
| Category | Purpose | Examples |
|
||||
|----------|---------|----------|
|
||||
| **Language Standards** | Idioms, conventions, best practices | `python-patterns`, `golang-patterns` |
|
||||
| **Framework Patterns** | Framework-specific guidance | `django-patterns`, `nextjs-patterns` |
|
||||
| **Workflow** | Step-by-step processes | `tdd-workflow`, `refactoring-workflow` |
|
||||
| **Domain Knowledge** | Specialized domains | `security-review`, `api-design` |
|
||||
| **Tool Integration** | Tool/library usage | `docker-patterns`, `supabase-patterns` |
|
||||
| **Template** | Project-specific skill templates | `project-guidelines-example` |
|
||||
|
||||
### Skill Checklist
|
||||
|
||||
- [ ] Focused on one domain/technology
|
||||
- [ ] Includes practical code examples
|
||||
- [ ] Under 500 lines
|
||||
- [ ] Focused on one domain/technology (not too broad)
|
||||
- [ ] Includes "When to Activate" section for auto-activation
|
||||
- [ ] Includes practical, copy-pasteable code examples
|
||||
- [ ] Shows anti-patterns (what NOT to do)
|
||||
- [ ] Under 500 lines (800 max)
|
||||
- [ ] Uses clear section headers
|
||||
- [ ] Tested with Claude Code
|
||||
- [ ] Links to related skills
|
||||
- [ ] No sensitive data (API keys, tokens, paths)
|
||||
|
||||
### Example Skills
|
||||
|
||||
| Skill | Purpose |
|
||||
|-------|---------|
|
||||
| `coding-standards/` | TypeScript/JavaScript patterns |
|
||||
| `frontend-patterns/` | React and Next.js best practices |
|
||||
| `backend-patterns/` | API and database patterns |
|
||||
| `security-review/` | Security checklist |
|
||||
| Skill | Category | Purpose |
|
||||
|-------|----------|---------|
|
||||
| `coding-standards/` | Language Standards | TypeScript/JavaScript patterns |
|
||||
| `frontend-patterns/` | Framework Patterns | React and Next.js best practices |
|
||||
| `backend-patterns/` | Framework Patterns | API and database patterns |
|
||||
| `security-review/` | Domain Knowledge | Security checklist |
|
||||
| `tdd-workflow/` | Workflow | Test-driven development process |
|
||||
| `project-guidelines-example/` | Template | Project-specific skill template |
|
||||
|
||||
---
|
||||
|
||||
|
||||
122
EVALUATION.md
Normal file
122
EVALUATION.md
Normal file
@@ -0,0 +1,122 @@
|
||||
# Repo Evaluation vs Current Setup
|
||||
|
||||
**Date:** 2026-03-21
|
||||
**Branch:** `claude/evaluate-repo-comparison-ASZ9Y`
|
||||
|
||||
---
|
||||
|
||||
## Current Setup (`~/.claude/`)
|
||||
|
||||
The active Claude Code installation is near-minimal:
|
||||
|
||||
| Component | Current |
|
||||
|-----------|---------|
|
||||
| Agents | 0 |
|
||||
| Skills | 0 installed |
|
||||
| Commands | 0 |
|
||||
| Hooks | 1 (Stop: git check) |
|
||||
| Rules | 0 |
|
||||
| MCP configs | 0 |
|
||||
|
||||
**Installed hooks:**
|
||||
- `Stop` → `stop-hook-git-check.sh` — blocks session end if there are uncommitted changes or unpushed commits
|
||||
|
||||
**Installed permissions:**
|
||||
- `Skill` — allows skill invocations
|
||||
|
||||
**Plugins:** Only `blocklist.json` (no active plugins installed)
|
||||
|
||||
---
|
||||
|
||||
## This Repo (`everything-claude-code` v1.9.0)
|
||||
|
||||
| Component | Repo |
|
||||
|-----------|------|
|
||||
| Agents | 28 |
|
||||
| Skills | 116 |
|
||||
| Commands | 59 |
|
||||
| Rules sets | 12 languages + common (60+ rule files) |
|
||||
| Hooks | Comprehensive system (PreToolUse, PostToolUse, SessionStart, Stop) |
|
||||
| MCP configs | 1 (Context7 + others) |
|
||||
| Schemas | 9 JSON validators |
|
||||
| Scripts/CLI | 46+ Node.js modules + multiple CLIs |
|
||||
| Tests | 58 test files |
|
||||
| Install profiles | core, developer, security, research, full |
|
||||
| Supported harnesses | Claude Code, Codex, Cursor, OpenCode |
|
||||
|
||||
---
|
||||
|
||||
## Gap Analysis
|
||||
|
||||
### Hooks
|
||||
- **Current:** 1 Stop hook (git hygiene check)
|
||||
- **Repo:** Full hook matrix covering:
|
||||
- Dangerous command blocking (`rm -rf`, force pushes)
|
||||
- Auto-formatting on file edits
|
||||
- Dev server tmux enforcement
|
||||
- Cost tracking
|
||||
- Session evaluation and governance capture
|
||||
- MCP health monitoring
|
||||
|
||||
### Agents (28 missing)
|
||||
The repo provides specialized agents for every major workflow:
|
||||
- Language reviewers: TypeScript, Python, Go, Java, Kotlin, Rust, C++, Flutter
|
||||
- Build resolvers: Go, Java, Kotlin, Rust, C++, PyTorch
|
||||
- Workflow agents: planner, tdd-guide, code-reviewer, security-reviewer, architect
|
||||
- Automation: loop-operator, doc-updater, refactor-cleaner, harness-optimizer
|
||||
|
||||
### Skills (116 missing)
|
||||
Domain knowledge modules covering:
|
||||
- Language patterns (Python, Go, Kotlin, Rust, C++, Java, Swift, Perl, Laravel, Django)
|
||||
- Testing strategies (TDD, E2E, coverage)
|
||||
- Architecture patterns (backend, frontend, API design, database migrations)
|
||||
- AI/ML workflows (Claude API, eval harness, agent loops, cost-aware pipelines)
|
||||
- Business workflows (investor materials, market research, content engine)
|
||||
|
||||
### Commands (59 missing)
|
||||
- `/tdd`, `/plan`, `/e2e`, `/code-review` — core dev workflows
|
||||
- `/sessions`, `/save-session`, `/resume-session` — session persistence
|
||||
- `/orchestrate`, `/multi-plan`, `/multi-execute` — multi-agent coordination
|
||||
- `/learn`, `/skill-create`, `/evolve` — continuous improvement
|
||||
- `/build-fix`, `/verify`, `/quality-gate` — build/quality automation
|
||||
|
||||
### Rules (60+ files missing)
|
||||
Language-specific coding style, patterns, testing, and security guidelines for:
|
||||
TypeScript, Python, Go, Java, Kotlin, Rust, C++, C#, Swift, Perl, PHP, and common/cross-language rules.
|
||||
|
||||
---
|
||||
|
||||
## Recommendations
|
||||
|
||||
### Immediate value (core install)
|
||||
Run `ecc install --profile core` to get:
|
||||
- Core agents (code-reviewer, planner, tdd-guide, security-reviewer)
|
||||
- Essential skills (tdd-workflow, coding-standards, security-review)
|
||||
- Key commands (/tdd, /plan, /code-review, /build-fix)
|
||||
|
||||
### Full install
|
||||
Run `ecc install --profile full` to get all 28 agents, 116 skills, and 59 commands.
|
||||
|
||||
### Hooks upgrade
|
||||
The current Stop hook is solid. The repo's `hooks.json` adds:
|
||||
- Dangerous command blocking (safety)
|
||||
- Auto-formatting (quality)
|
||||
- Cost tracking (observability)
|
||||
- Session evaluation (learning)
|
||||
|
||||
### Rules
|
||||
Adding language rules (e.g., TypeScript, Python) provides always-on coding guidelines without relying on per-session prompts.
|
||||
|
||||
---
|
||||
|
||||
## What the Current Setup Does Well
|
||||
|
||||
- The `stop-hook-git-check.sh` Stop hook is production-quality and already enforces good git hygiene
|
||||
- The `Skill` permission is correctly configured
|
||||
- The setup is clean with no conflicts or cruft
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
The current setup is essentially a blank slate with one well-implemented git hygiene hook. This repo provides a complete, production-tested enhancement layer covering agents, skills, commands, hooks, and rules — with a selective install system so you can add exactly what you need without bloating the configuration.
|
||||
128
README.md
128
README.md
@@ -1,6 +1,4 @@
|
||||
**Language:** English | [Português (Brasil)](docs/pt-BR/README.md) | [简体中文](README.zh-CN.md) | [繁體中文](docs/zh-TW/README.md) | [日本語](docs/ja-JP/README.md) | [한국어](docs/ko-KR/README.md)
|
||||
[Türkçe](docs/tr/README.md)
|
||||
|
||||
**Language:** English | [Português (Brasil)](docs/pt-BR/README.md) | [简体中文](README.zh-CN.md) | [繁體中文](docs/zh-TW/README.md) | [日本語](docs/ja-JP/README.md) | [한국어](docs/ko-KR/README.md) | [Türkçe](docs/tr/README.md)
|
||||
|
||||
# Everything Claude Code
|
||||
|
||||
@@ -25,7 +23,7 @@
|
||||
|
||||
<div align="center">
|
||||
|
||||
**🌐 Language / 语言 / 語言 / Dil**
|
||||
**Language / 语言 / 語言 / Dil**
|
||||
|
||||
[**English**](README.md) | [Português (Brasil)](docs/pt-BR/README.md) | [简体中文](README.zh-CN.md) | [繁體中文](docs/zh-TW/README.md) | [日本語](docs/ja-JP/README.md) | [한국어](docs/ko-KR/README.md)
|
||||
| [Türkçe](docs/tr/README.md)
|
||||
@@ -153,7 +151,7 @@ See the full changelog in [Releases](https://github.com/affaan-m/everything-clau
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Quick Start
|
||||
## Quick Start
|
||||
|
||||
Get up and running in under 2 minutes:
|
||||
|
||||
@@ -169,7 +167,7 @@ Get up and running in under 2 minutes:
|
||||
|
||||
### Step 2: Install Rules (Required)
|
||||
|
||||
> ⚠️ **Important:** Claude Code plugins cannot distribute `rules` automatically. Install them manually:
|
||||
> WARNING: **Important:** Claude Code plugins cannot distribute `rules` automatically. Install them manually:
|
||||
|
||||
```bash
|
||||
# Clone the repo first
|
||||
@@ -180,6 +178,11 @@ cd everything-claude-code
|
||||
npm install # or: pnpm install | yarn install | bun install
|
||||
|
||||
# macOS/Linux
|
||||
|
||||
# Recommended: install everything (full profile)
|
||||
./install.sh --profile full
|
||||
|
||||
# Or install for specific languages only
|
||||
./install.sh typescript # or python or golang or swift or php
|
||||
# ./install.sh typescript python golang swift php
|
||||
# ./install.sh --target cursor typescript
|
||||
@@ -188,6 +191,11 @@ npm install # or: pnpm install | yarn install | bun install
|
||||
|
||||
```powershell
|
||||
# Windows PowerShell
|
||||
|
||||
# Recommended: install everything (full profile)
|
||||
.\install.ps1 --profile full
|
||||
|
||||
# Or install for specific languages only
|
||||
.\install.ps1 typescript # or python or golang or swift or php
|
||||
# .\install.ps1 typescript python golang swift php
|
||||
# .\install.ps1 --target cursor typescript
|
||||
@@ -197,7 +205,7 @@ npm install # or: pnpm install | yarn install | bun install
|
||||
npx ecc-install typescript
|
||||
```
|
||||
|
||||
For manual install instructions see the README in the `rules/` folder.
|
||||
For manual install instructions see the README in the `rules/` folder. When copying rules manually, copy the whole language directory (for example `rules/common` or `rules/golang`), not the files inside it, so relative references keep working and filenames do not collide.
|
||||
|
||||
### Step 3: Start Using
|
||||
|
||||
@@ -212,11 +220,25 @@ For manual install instructions see the README in the `rules/` folder.
|
||||
/plugin list everything-claude-code@everything-claude-code
|
||||
```
|
||||
|
||||
✨ **That's it!** You now have access to 28 agents, 125 skills, and 60 commands.
|
||||
**That's it!** You now have access to 30 agents, 135 skills, and 60 commands.
|
||||
|
||||
### Multi-model commands require additional setup
|
||||
|
||||
> WARNING: `multi-*` commands are **not** covered by the base plugin/rules install above.
|
||||
>
|
||||
> To use `/multi-plan`, `/multi-execute`, `/multi-backend`, `/multi-frontend`, and `/multi-workflow`, you must also install the `ccg-workflow` runtime.
|
||||
>
|
||||
> Initialize it with `npx ccg-workflow`.
|
||||
>
|
||||
> That runtime provides the external dependencies these commands expect, including:
|
||||
> - `~/.claude/bin/codeagent-wrapper`
|
||||
> - `~/.claude/.ccg/prompts/*`
|
||||
>
|
||||
> Without `ccg-workflow`, these `multi-*` commands will not run correctly.
|
||||
|
||||
---
|
||||
|
||||
## 🌐 Cross-Platform Support
|
||||
## Cross-Platform Support
|
||||
|
||||
This plugin now fully supports **Windows, macOS, and Linux**, alongside tight integration across major IDEs (Cursor, OpenCode, Antigravity) and CLI harnesses. All hooks and scripts have been rewritten in Node.js for maximum compatibility.
|
||||
|
||||
@@ -263,7 +285,7 @@ export ECC_DISABLED_HOOKS="pre:bash:tmux-reminder,post:edit:typecheck"
|
||||
|
||||
---
|
||||
|
||||
## 📦 What's Inside
|
||||
## What's Inside
|
||||
|
||||
This repo is a **Claude Code plugin** - install it directly or copy components manually.
|
||||
|
||||
@@ -273,7 +295,7 @@ everything-claude-code/
|
||||
| |-- plugin.json # Plugin metadata and component paths
|
||||
| |-- marketplace.json # Marketplace catalog for /plugin marketplace add
|
||||
|
|
||||
|-- agents/ # 28 specialized subagents for delegation
|
||||
|-- agents/ # 30 specialized subagents for delegation
|
||||
| |-- planner.md # Feature implementation planning
|
||||
| |-- architect.md # System design decisions
|
||||
| |-- tdd-guide.md # Test-driven development
|
||||
@@ -465,7 +487,7 @@ everything-claude-code/
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ Ecosystem Tools
|
||||
## Ecosystem Tools
|
||||
|
||||
### Skill Creator
|
||||
|
||||
@@ -530,7 +552,7 @@ Use `/security-scan` in Claude Code to run it, or add to CI with the [GitHub Act
|
||||
|
||||
[GitHub](https://github.com/affaan-m/agentshield) | [npm](https://www.npmjs.com/package/ecc-agentshield)
|
||||
|
||||
### 🧠 Continuous Learning v2
|
||||
### Continuous Learning v2
|
||||
|
||||
The instinct-based learning system automatically learns your patterns:
|
||||
|
||||
@@ -545,7 +567,7 @@ See `skills/continuous-learning-v2/` for full documentation.
|
||||
|
||||
---
|
||||
|
||||
## 📋 Requirements
|
||||
## Requirements
|
||||
|
||||
### Claude Code CLI Version
|
||||
|
||||
@@ -560,7 +582,7 @@ claude --version
|
||||
|
||||
### Important: Hooks Auto-Loading Behavior
|
||||
|
||||
> ⚠️ **For Contributors:** Do NOT add a `"hooks"` field to `.claude-plugin/plugin.json`. This is enforced by a regression test.
|
||||
> WARNING: **For Contributors:** Do NOT add a `"hooks"` field to `.claude-plugin/plugin.json`. This is enforced by a regression test.
|
||||
|
||||
Claude Code v2.1+ **automatically loads** `hooks/hooks.json` from any installed plugin by convention. Explicitly declaring it in `plugin.json` causes a duplicate detection error:
|
||||
|
||||
@@ -572,7 +594,7 @@ Duplicate hooks file detected: ./hooks/hooks.json resolves to already-loaded fil
|
||||
|
||||
---
|
||||
|
||||
## 📥 Installation
|
||||
## Installation
|
||||
|
||||
### Option 1: Install as Plugin (Recommended)
|
||||
|
||||
@@ -614,21 +636,21 @@ This gives you instant access to all commands, agents, skills, and hooks.
|
||||
>
|
||||
> # Option A: User-level rules (applies to all projects)
|
||||
> mkdir -p ~/.claude/rules
|
||||
> cp -r everything-claude-code/rules/common/* ~/.claude/rules/
|
||||
> cp -r everything-claude-code/rules/typescript/* ~/.claude/rules/ # pick your stack
|
||||
> cp -r everything-claude-code/rules/python/* ~/.claude/rules/
|
||||
> cp -r everything-claude-code/rules/golang/* ~/.claude/rules/
|
||||
> cp -r everything-claude-code/rules/php/* ~/.claude/rules/
|
||||
> cp -r everything-claude-code/rules/common ~/.claude/rules/
|
||||
> cp -r everything-claude-code/rules/typescript ~/.claude/rules/ # pick your stack
|
||||
> cp -r everything-claude-code/rules/python ~/.claude/rules/
|
||||
> cp -r everything-claude-code/rules/golang ~/.claude/rules/
|
||||
> cp -r everything-claude-code/rules/php ~/.claude/rules/
|
||||
>
|
||||
> # Option B: Project-level rules (applies to current project only)
|
||||
> mkdir -p .claude/rules
|
||||
> cp -r everything-claude-code/rules/common/* .claude/rules/
|
||||
> cp -r everything-claude-code/rules/typescript/* .claude/rules/ # pick your stack
|
||||
> cp -r everything-claude-code/rules/common .claude/rules/
|
||||
> cp -r everything-claude-code/rules/typescript .claude/rules/ # pick your stack
|
||||
> ```
|
||||
|
||||
---
|
||||
|
||||
### 🔧 Option 2: Manual Installation
|
||||
### Option 2: Manual Installation
|
||||
|
||||
If you prefer manual control over what's installed:
|
||||
|
||||
@@ -639,12 +661,13 @@ git clone https://github.com/affaan-m/everything-claude-code.git
|
||||
# Copy agents to your Claude config
|
||||
cp everything-claude-code/agents/*.md ~/.claude/agents/
|
||||
|
||||
# Copy rules (common + language-specific)
|
||||
cp -r everything-claude-code/rules/common/* ~/.claude/rules/
|
||||
cp -r everything-claude-code/rules/typescript/* ~/.claude/rules/ # pick your stack
|
||||
cp -r everything-claude-code/rules/python/* ~/.claude/rules/
|
||||
cp -r everything-claude-code/rules/golang/* ~/.claude/rules/
|
||||
cp -r everything-claude-code/rules/php/* ~/.claude/rules/
|
||||
# Copy rules directories (common + language-specific)
|
||||
mkdir -p ~/.claude/rules
|
||||
cp -r everything-claude-code/rules/common ~/.claude/rules/
|
||||
cp -r everything-claude-code/rules/typescript ~/.claude/rules/ # pick your stack
|
||||
cp -r everything-claude-code/rules/python ~/.claude/rules/
|
||||
cp -r everything-claude-code/rules/golang ~/.claude/rules/
|
||||
cp -r everything-claude-code/rules/php ~/.claude/rules/
|
||||
|
||||
# Copy commands
|
||||
cp everything-claude-code/commands/*.md ~/.claude/commands/
|
||||
@@ -656,7 +679,7 @@ cp -r everything-claude-code/skills/search-first ~/.claude/skills/
|
||||
|
||||
# Optional: add niche/framework-specific skills only when needed
|
||||
# for s in django-patterns django-tdd laravel-patterns springboot-patterns; do
|
||||
# cp -r everything-claude-code/skills/$s ~/.claude/skills/
|
||||
# cp -r everything-claude-code/skills/$s ~/.claude/skills/
|
||||
# done
|
||||
```
|
||||
|
||||
@@ -672,7 +695,7 @@ Copy desired MCP servers from `mcp-configs/mcp-servers.json` to your `~/.claude.
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Key Concepts
|
||||
## Key Concepts
|
||||
|
||||
### Agents
|
||||
|
||||
@@ -735,7 +758,7 @@ See [`rules/README.md`](rules/README.md) for installation and structure details.
|
||||
|
||||
---
|
||||
|
||||
## 🗺️ Which Agent Should I Use?
|
||||
## Which Agent Should I Use?
|
||||
|
||||
Not sure where to start? Use this quick reference:
|
||||
|
||||
@@ -781,7 +804,7 @@ Not sure where to start? Use this quick reference:
|
||||
|
||||
---
|
||||
|
||||
## ❓ FAQ
|
||||
## FAQ
|
||||
|
||||
<details>
|
||||
<summary><b>How do I check which agents/commands are installed?</b></summary>
|
||||
@@ -850,7 +873,8 @@ Yes. Use Option 2 (manual installation) and copy only what you need:
|
||||
cp everything-claude-code/agents/*.md ~/.claude/agents/
|
||||
|
||||
# Just rules
|
||||
cp -r everything-claude-code/rules/common/* ~/.claude/rules/
|
||||
mkdir -p ~/.claude/rules/
|
||||
cp -r everything-claude-code/rules/common ~/.claude/rules/
|
||||
```
|
||||
|
||||
Each component is fully independent.
|
||||
@@ -879,7 +903,7 @@ See [CONTRIBUTING.md](CONTRIBUTING.md). The short version:
|
||||
|
||||
---
|
||||
|
||||
## 🧪 Running Tests
|
||||
## Running Tests
|
||||
|
||||
The plugin includes a comprehensive test suite:
|
||||
|
||||
@@ -895,7 +919,7 @@ node tests/hooks/hooks.test.js
|
||||
|
||||
---
|
||||
|
||||
## 🤝 Contributing
|
||||
## Contributing
|
||||
|
||||
**Contributions are welcome and encouraged.**
|
||||
|
||||
@@ -999,6 +1023,8 @@ cp .codex/config.toml ~/.codex/config.toml
|
||||
|
||||
The sync script safely merges ECC MCP servers into your existing `~/.codex/config.toml` using an **add-only** strategy — it never removes or modifies your existing servers. Run with `--dry-run` to preview changes, or `--update-mcp` to force-refresh ECC servers to the latest recommended config.
|
||||
|
||||
For Context7, ECC uses the canonical Codex section name `[mcp_servers.context7]` while still launching the `@upstash/context7-mcp` package. If you already have a legacy `[mcp_servers.context7-mcp]` entry, `--update-mcp` migrates it to the canonical section name.
|
||||
|
||||
Codex macOS app:
|
||||
- Open this repository as your workspace.
|
||||
- The root `AGENTS.md` is auto-detected.
|
||||
@@ -1063,7 +1089,7 @@ ECC ships three sample role configs:
|
||||
|
||||
---
|
||||
|
||||
## 🔌 OpenCode Support
|
||||
## OpenCode Support
|
||||
|
||||
ECC provides **full OpenCode support** including plugins and hooks.
|
||||
|
||||
@@ -1083,13 +1109,13 @@ The configuration is automatically detected from `.opencode/opencode.json`.
|
||||
|
||||
| Feature | Claude Code | OpenCode | Status |
|
||||
|---------|-------------|----------|--------|
|
||||
| Agents | ✅ 28 agents | ✅ 12 agents | **Claude Code leads** |
|
||||
| Commands | ✅ 60 commands | ✅ 31 commands | **Claude Code leads** |
|
||||
| Skills | ✅ 125 skills | ✅ 37 skills | **Claude Code leads** |
|
||||
| Hooks | ✅ 8 event types | ✅ 11 events | **OpenCode has more!** |
|
||||
| Rules | ✅ 29 rules | ✅ 13 instructions | **Claude Code leads** |
|
||||
| MCP Servers | ✅ 14 servers | ✅ Full | **Full parity** |
|
||||
| Custom Tools | ✅ Via hooks | ✅ 6 native tools | **OpenCode is better** |
|
||||
| Agents | PASS: 30 agents | PASS: 12 agents | **Claude Code leads** |
|
||||
| Commands | PASS: 60 commands | PASS: 31 commands | **Claude Code leads** |
|
||||
| Skills | PASS: 135 skills | PASS: 37 skills | **Claude Code leads** |
|
||||
| Hooks | PASS: 8 event types | PASS: 11 events | **OpenCode has more!** |
|
||||
| Rules | PASS: 29 rules | PASS: 13 instructions | **Claude Code leads** |
|
||||
| MCP Servers | PASS: 14 servers | PASS: Full | **Full parity** |
|
||||
| Custom Tools | PASS: Via hooks | PASS: 6 native tools | **OpenCode is better** |
|
||||
|
||||
### Hook Support via Plugins
|
||||
|
||||
@@ -1214,7 +1240,7 @@ ECC is the **first plugin to maximize every major AI coding tool**. Here's how e
|
||||
|
||||
---
|
||||
|
||||
## 📖 Background
|
||||
## Background
|
||||
|
||||
I've been using Claude Code since the experimental rollout. Won the Anthropic x Forum Ventures hackathon in Sep 2025 with [@DRodriguezFX](https://x.com/DRodriguezFX) — built [zenith.chat](https://zenith.chat) entirely using Claude Code.
|
||||
|
||||
@@ -1288,7 +1314,7 @@ Agent Teams spawns multiple context windows. Each teammate consumes tokens indep
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ Important Notes
|
||||
## WARNING: Important Notes
|
||||
|
||||
### Token Optimization
|
||||
|
||||
@@ -1320,7 +1346,7 @@ These configs work for my workflow. You should:
|
||||
|
||||
---
|
||||
|
||||
## 💜 Sponsors
|
||||
## Sponsors
|
||||
|
||||
This project is free and open source. Sponsors help keep it maintained and growing.
|
||||
|
||||
@@ -1328,13 +1354,13 @@ This project is free and open source. Sponsors help keep it maintained and growi
|
||||
|
||||
---
|
||||
|
||||
## 🌟 Star History
|
||||
## Star History
|
||||
|
||||
[](https://star-history.com/#affaan-m/everything-claude-code&Date)
|
||||
|
||||
---
|
||||
|
||||
## 🔗 Links
|
||||
## Links
|
||||
|
||||
- **Shorthand Guide (Start Here):** [The Shorthand Guide to Everything Claude Code](https://x.com/affaanmustafa/status/2012378465664745795)
|
||||
- **Longform Guide (Advanced):** [The Longform Guide to Everything Claude Code](https://x.com/affaanmustafa/status/2014040193557471352)
|
||||
@@ -1343,7 +1369,7 @@ This project is free and open source. Sponsors help keep it maintained and growi
|
||||
|
||||
---
|
||||
|
||||
## 📄 License
|
||||
## License
|
||||
|
||||
MIT - Use freely, modify as needed, contribute back if you can.
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
<div align="center">
|
||||
|
||||
**🌐 Language / 语言 / 語言**
|
||||
**Language / 语言 / 語言**
|
||||
|
||||
[**English**](README.md) | [简体中文](README.zh-CN.md) | [繁體中文](docs/zh-TW/README.md) | [日本語](docs/ja-JP/README.md) | [한국어](docs/ko-KR/README.md)
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
|
||||
---
|
||||
|
||||
## 🚀 快速开始
|
||||
## 快速开始
|
||||
|
||||
在 2 分钟内快速上手:
|
||||
|
||||
@@ -76,20 +76,23 @@
|
||||
|
||||
### 第二步:安装规则(必需)
|
||||
|
||||
> ⚠️ **重要提示:** Claude Code 插件无法自动分发 `rules`,需要手动安装:
|
||||
> WARNING: **重要提示:** Claude Code 插件无法自动分发 `rules`,需要手动安装:
|
||||
|
||||
```bash
|
||||
# 首先克隆仓库
|
||||
git clone https://github.com/affaan-m/everything-claude-code.git
|
||||
|
||||
# 复制规则(通用 + 语言特定)
|
||||
cp -r everything-claude-code/rules/common/* ~/.claude/rules/
|
||||
cp -r everything-claude-code/rules/typescript/* ~/.claude/rules/ # 选择你的技术栈
|
||||
cp -r everything-claude-code/rules/python/* ~/.claude/rules/
|
||||
cp -r everything-claude-code/rules/golang/* ~/.claude/rules/
|
||||
cp -r everything-claude-code/rules/perl/* ~/.claude/rules/
|
||||
# 复制规则目录(通用 + 语言特定)
|
||||
mkdir -p ~/.claude/rules
|
||||
cp -r everything-claude-code/rules/common ~/.claude/rules/
|
||||
cp -r everything-claude-code/rules/typescript ~/.claude/rules/ # 选择你的技术栈
|
||||
cp -r everything-claude-code/rules/python ~/.claude/rules/
|
||||
cp -r everything-claude-code/rules/golang ~/.claude/rules/
|
||||
cp -r everything-claude-code/rules/perl ~/.claude/rules/
|
||||
```
|
||||
|
||||
复制规则时,请复制整个目录(例如 `rules/common`、`rules/golang`),而不是复制目录内的文件;这样可以保留相对引用,并避免不同规则集中的同名文件互相覆盖。
|
||||
|
||||
### 第三步:开始使用
|
||||
|
||||
```bash
|
||||
@@ -103,11 +106,25 @@ cp -r everything-claude-code/rules/perl/* ~/.claude/rules/
|
||||
/plugin list everything-claude-code@everything-claude-code
|
||||
```
|
||||
|
||||
✨ **完成!** 你现在可以使用 13 个代理、43 个技能和 31 个命令。
|
||||
**完成!** 你现在可以使用 13 个代理、43 个技能和 31 个命令。
|
||||
|
||||
### multi-* 命令需要额外配置
|
||||
|
||||
> WARNING: 上面的基础插件 / rules 安装**不包含** `multi-*` 命令所需的运行时。
|
||||
>
|
||||
> 如果要使用 `/multi-plan`、`/multi-execute`、`/multi-backend`、`/multi-frontend` 和 `/multi-workflow`,还需要额外安装 `ccg-workflow` 运行时。
|
||||
>
|
||||
> 可通过 `npx ccg-workflow` 完成初始化安装。
|
||||
>
|
||||
> 该运行时会提供这些命令依赖的关键组件,包括:
|
||||
> - `~/.claude/bin/codeagent-wrapper`
|
||||
> - `~/.claude/.ccg/prompts/*`
|
||||
>
|
||||
> 未安装 `ccg-workflow` 时,这些 `multi-*` 命令将无法正常运行。
|
||||
|
||||
---
|
||||
|
||||
## 🌐 跨平台支持
|
||||
## 跨平台支持
|
||||
|
||||
此插件现在完全支持 **Windows、macOS 和 Linux**。所有钩子和脚本都已用 Node.js 重写,以实现最大的兼容性。
|
||||
|
||||
@@ -142,7 +159,7 @@ node scripts/setup-package-manager.js --detect
|
||||
|
||||
---
|
||||
|
||||
## 📦 里面有什么
|
||||
## 里面有什么
|
||||
|
||||
这个仓库是一个 **Claude Code 插件** - 直接安装或手动复制组件。
|
||||
|
||||
@@ -259,7 +276,7 @@ everything-claude-code/
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ 生态系统工具
|
||||
## 生态系统工具
|
||||
|
||||
### 技能创建器
|
||||
|
||||
@@ -294,7 +311,7 @@ everything-claude-code/
|
||||
- **直觉集合** - 用于 continuous-learning-v2
|
||||
- **模式提取** - 从你的提交历史中学习
|
||||
|
||||
### 🧠 持续学习 v2
|
||||
### 持续学习 v2
|
||||
|
||||
基于直觉的学习系统自动学习你的模式:
|
||||
|
||||
@@ -311,7 +328,7 @@ everything-claude-code/
|
||||
|
||||
---
|
||||
|
||||
## 📥 安装
|
||||
## 安装
|
||||
|
||||
### 选项 1:作为插件安装(推荐)
|
||||
|
||||
@@ -352,16 +369,25 @@ everything-claude-code/
|
||||
> git clone https://github.com/affaan-m/everything-claude-code.git
|
||||
>
|
||||
> # 选项 A:用户级规则(应用于所有项目)
|
||||
> cp -r everything-claude-code/rules/* ~/.claude/rules/
|
||||
> mkdir -p ~/.claude/rules
|
||||
> cp -r everything-claude-code/rules/common ~/.claude/rules/
|
||||
> cp -r everything-claude-code/rules/typescript ~/.claude/rules/
|
||||
> cp -r everything-claude-code/rules/python ~/.claude/rules/
|
||||
> cp -r everything-claude-code/rules/golang ~/.claude/rules/
|
||||
> cp -r everything-claude-code/rules/perl ~/.claude/rules/
|
||||
>
|
||||
> # 选项 B:项目级规则(仅应用于当前项目)
|
||||
> mkdir -p .claude/rules
|
||||
> cp -r everything-claude-code/rules/* .claude/rules/
|
||||
> cp -r everything-claude-code/rules/common .claude/rules/
|
||||
> cp -r everything-claude-code/rules/typescript .claude/rules/
|
||||
> cp -r everything-claude-code/rules/python .claude/rules/
|
||||
> cp -r everything-claude-code/rules/golang .claude/rules/
|
||||
> cp -r everything-claude-code/rules/perl .claude/rules/
|
||||
> ```
|
||||
|
||||
---
|
||||
|
||||
### 🔧 选项 2:手动安装
|
||||
### 选项 2:手动安装
|
||||
|
||||
如果你希望对安装的内容进行手动控制:
|
||||
|
||||
@@ -372,12 +398,13 @@ git clone https://github.com/affaan-m/everything-claude-code.git
|
||||
# 将代理复制到你的 Claude 配置
|
||||
cp everything-claude-code/agents/*.md ~/.claude/agents/
|
||||
|
||||
# 复制规则(通用 + 语言特定)
|
||||
cp -r everything-claude-code/rules/common/* ~/.claude/rules/
|
||||
cp -r everything-claude-code/rules/typescript/* ~/.claude/rules/ # 选择你的技术栈
|
||||
cp -r everything-claude-code/rules/python/* ~/.claude/rules/
|
||||
cp -r everything-claude-code/rules/golang/* ~/.claude/rules/
|
||||
cp -r everything-claude-code/rules/perl/* ~/.claude/rules/
|
||||
# 复制规则目录(通用 + 语言特定)
|
||||
mkdir -p ~/.claude/rules
|
||||
cp -r everything-claude-code/rules/common ~/.claude/rules/
|
||||
cp -r everything-claude-code/rules/typescript ~/.claude/rules/ # 选择你的技术栈
|
||||
cp -r everything-claude-code/rules/python ~/.claude/rules/
|
||||
cp -r everything-claude-code/rules/golang ~/.claude/rules/
|
||||
cp -r everything-claude-code/rules/perl ~/.claude/rules/
|
||||
|
||||
# 复制命令
|
||||
cp everything-claude-code/commands/*.md ~/.claude/commands/
|
||||
@@ -398,7 +425,7 @@ cp -r everything-claude-code/skills/* ~/.claude/skills/
|
||||
|
||||
---
|
||||
|
||||
## 🎯 关键概念
|
||||
## 关键概念
|
||||
|
||||
### 代理
|
||||
|
||||
@@ -458,7 +485,7 @@ model: opus
|
||||
|
||||
---
|
||||
|
||||
## 🧪 运行测试
|
||||
## 运行测试
|
||||
|
||||
插件包含一个全面的测试套件:
|
||||
|
||||
@@ -474,7 +501,7 @@ node tests/hooks/hooks.test.js
|
||||
|
||||
---
|
||||
|
||||
## 🤝 贡献
|
||||
## 贡献
|
||||
|
||||
**欢迎并鼓励贡献。**
|
||||
|
||||
@@ -496,7 +523,7 @@ node tests/hooks/hooks.test.js
|
||||
|
||||
---
|
||||
|
||||
## 📖 背景
|
||||
## 背景
|
||||
|
||||
自实验性推出以来,我一直在使用 Claude Code。2025 年 9 月,与 [@DRodriguezFX](https://x.com/DRodriguezFX) 一起使用 Claude Code 构建 [zenith.chat](https://zenith.chat),赢得了 Anthropic x Forum Ventures 黑客马拉松。
|
||||
|
||||
@@ -504,7 +531,7 @@ node tests/hooks/hooks.test.js
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ 重要说明
|
||||
## WARNING: 重要说明
|
||||
|
||||
### 上下文窗口管理
|
||||
|
||||
@@ -527,13 +554,13 @@ node tests/hooks/hooks.test.js
|
||||
|
||||
---
|
||||
|
||||
## 🌟 Star 历史
|
||||
## Star 历史
|
||||
|
||||
[](https://star-history.com/#affaan-m/everything-claude-code&Date)
|
||||
|
||||
---
|
||||
|
||||
## 🔗 链接
|
||||
## 链接
|
||||
|
||||
- **精简指南(从这里开始):** [The Shorthand Guide to Everything Claude Code](https://x.com/affaanmustafa/status/2012378465664745795)
|
||||
- **详细指南(高级):** [The Longform Guide to Everything Claude Code](https://x.com/affaanmustafa/status/2014040193557471352)
|
||||
@@ -543,7 +570,7 @@ node tests/hooks/hooks.test.js
|
||||
|
||||
---
|
||||
|
||||
## 📄 许可证
|
||||
## 许可证
|
||||
|
||||
MIT - 自由使用,根据需要修改,如果可以请回馈。
|
||||
|
||||
|
||||
196
REPO-ASSESSMENT.md
Normal file
196
REPO-ASSESSMENT.md
Normal file
@@ -0,0 +1,196 @@
|
||||
# Repo & Fork Assessment + Setup Recommendations
|
||||
|
||||
**Date:** 2026-03-21
|
||||
|
||||
---
|
||||
|
||||
## What's Available
|
||||
|
||||
### Repo: `Infiniteyieldai/everything-claude-code`
|
||||
|
||||
This is a **fork of `affaan-m/everything-claude-code`** (the upstream project with 50K+ stars, 6K+ forks).
|
||||
|
||||
| Attribute | Value |
|
||||
|-----------|-------|
|
||||
| Version | 1.9.0 (current) |
|
||||
| Status | Clean fork — 1 commit ahead of upstream `main` (the EVALUATION.md doc added in this session) |
|
||||
| Remote branches | `main`, `claude/evaluate-repo-comparison-ASZ9Y` |
|
||||
| Upstream sync | Fully synced — last upstream commit merged was the zh-CN docs PR (#728) |
|
||||
| License | MIT |
|
||||
|
||||
**This is the right repo to work from.** It's the latest upstream version with no divergence or merge conflicts.
|
||||
|
||||
---
|
||||
|
||||
### Current `~/.claude/` Installation
|
||||
|
||||
| Component | Installed | Available in Repo |
|
||||
|-----------|-----------|-------------------|
|
||||
| Agents | 0 | 28 |
|
||||
| Skills | 0 | 116 |
|
||||
| Commands | 0 | 59 |
|
||||
| Rules | 0 | 60+ files (12 languages) |
|
||||
| Hooks | 1 (git Stop check) | Full PreToolUse/PostToolUse matrix |
|
||||
| MCP configs | 0 | 1 (Context7) |
|
||||
|
||||
The existing Stop hook (`stop-hook-git-check.sh`) is solid — blocks session end on uncommitted/unpushed work. Keep it.
|
||||
|
||||
---
|
||||
|
||||
## Install Profile Recommendations
|
||||
|
||||
The repo ships 5 install profiles. Choose based on your primary use case:
|
||||
|
||||
### Profile: `core` (Minimum viable setup)
|
||||
> Fastest to install. Gets you commands, core agents, hooks runtime, and quality workflow.
|
||||
|
||||
**Best for:** Trying ECC out, minimal footprint, or a constrained environment.
|
||||
|
||||
```bash
|
||||
node scripts/install-plan.js --profile core
|
||||
node scripts/install-apply.js
|
||||
```
|
||||
|
||||
**Installs:** rules-core, agents-core, commands-core, hooks-runtime, platform-configs, workflow-quality
|
||||
|
||||
---
|
||||
|
||||
### Profile: `developer` (Recommended for daily dev work)
|
||||
> The default engineering profile for most ECC users.
|
||||
|
||||
**Best for:** General software development across app codebases.
|
||||
|
||||
```bash
|
||||
node scripts/install-plan.js --profile developer
|
||||
node scripts/install-apply.js
|
||||
```
|
||||
|
||||
**Adds over core:** framework-language skills, database patterns, orchestration commands
|
||||
|
||||
---
|
||||
|
||||
### Profile: `security`
|
||||
> Baseline runtime + security-specific agents and rules.
|
||||
|
||||
**Best for:** Security-focused workflows, code audits, vulnerability reviews.
|
||||
|
||||
---
|
||||
|
||||
### Profile: `research`
|
||||
> Investigation, synthesis, and publishing workflows.
|
||||
|
||||
**Best for:** Content creation, investor materials, market research, cross-posting.
|
||||
|
||||
---
|
||||
|
||||
### Profile: `full`
|
||||
> Everything — all 18 modules.
|
||||
|
||||
**Best for:** Power users who want the complete toolkit.
|
||||
|
||||
```bash
|
||||
node scripts/install-plan.js --profile full
|
||||
node scripts/install-apply.js
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Priority Additions (High Value, Low Risk)
|
||||
|
||||
Regardless of profile, these components add immediate value:
|
||||
|
||||
### 1. Core Agents (highest ROI)
|
||||
|
||||
| Agent | Why it matters |
|
||||
|-------|----------------|
|
||||
| `planner.md` | Breaks complex tasks into implementation plans |
|
||||
| `code-reviewer.md` | Quality and maintainability review |
|
||||
| `tdd-guide.md` | TDD workflow (RED→GREEN→IMPROVE) |
|
||||
| `security-reviewer.md` | Vulnerability detection |
|
||||
| `architect.md` | System design & scalability decisions |
|
||||
|
||||
### 2. Key Commands
|
||||
|
||||
| Command | Why it matters |
|
||||
|---------|----------------|
|
||||
| `/plan` | Implementation planning before coding |
|
||||
| `/tdd` | Test-driven workflow |
|
||||
| `/code-review` | On-demand review |
|
||||
| `/build-fix` | Automated build error resolution |
|
||||
| `/learn` | Extract patterns from current session |
|
||||
|
||||
### 3. Hook Upgrades (from `hooks/hooks.json`)
|
||||
The repo's hook system adds these over the current single Stop hook:
|
||||
|
||||
| Hook | Trigger | Value |
|
||||
|------|---------|-------|
|
||||
| `block-no-verify` | PreToolUse: Bash | Blocks `--no-verify` git flag abuse |
|
||||
| `pre-bash-git-push-reminder` | PreToolUse: Bash | Pre-push review reminder |
|
||||
| `doc-file-warning` | PreToolUse: Write | Warns on non-standard doc files |
|
||||
| `suggest-compact` | PreToolUse: Edit/Write | Suggests compaction at logical intervals |
|
||||
| Continuous learning observer | PreToolUse: * | Captures tool use patterns for skill improvement |
|
||||
|
||||
### 4. Rules (Always-on guidelines)
|
||||
The `rules/common/` directory provides baseline guidelines that fire on every session:
|
||||
- `security.md` — Security guardrails
|
||||
- `testing.md` — 80%+ coverage requirement
|
||||
- `git-workflow.md` — Conventional commits, branch strategy
|
||||
- `coding-style.md` — Cross-language style standards
|
||||
|
||||
---
|
||||
|
||||
## What to Do With the Fork
|
||||
|
||||
### Option A: Use as upstream tracker (current state)
|
||||
Keep the fork synced with `affaan-m/everything-claude-code` upstream. Periodically merge upstream changes:
|
||||
```bash
|
||||
git fetch upstream
|
||||
git merge upstream/main
|
||||
```
|
||||
Install from the local clone. This is clean and maintainable.
|
||||
|
||||
### Option B: Customize the fork
|
||||
Add personal skills, agents, or commands to the fork. Good for:
|
||||
- Business-specific domain skills (your vertical)
|
||||
- Team-specific coding conventions
|
||||
- Custom hooks for your stack
|
||||
|
||||
The fork already has the EVALUATION.md and REPO-ASSESSMENT.md docs — that's fine for a working fork.
|
||||
|
||||
### Option C: Install from npm (simplest for fresh machines)
|
||||
```bash
|
||||
npx ecc-universal install --profile developer
|
||||
```
|
||||
No need to clone the repo. This is the recommended install method for most users.
|
||||
|
||||
---
|
||||
|
||||
## Recommended Setup Steps
|
||||
|
||||
1. **Keep the existing Stop hook** — it's doing its job
|
||||
2. **Run the developer profile install** from the local fork:
|
||||
```bash
|
||||
cd /path/to/everything-claude-code
|
||||
node scripts/install-plan.js --profile developer
|
||||
node scripts/install-apply.js
|
||||
```
|
||||
3. **Add language rules** for your primary stack (TypeScript, Python, Go, etc.):
|
||||
```bash
|
||||
node scripts/install-plan.js --add rules/typescript
|
||||
node scripts/install-apply.js
|
||||
```
|
||||
4. **Enable MCP Context7** for live documentation lookup:
|
||||
- Copy `mcp-configs/mcp-servers.json` into your project's `.claude/` dir
|
||||
5. **Review hooks** — enable the `hooks/hooks.json` additions selectively, starting with `block-no-verify` and `pre-bash-git-push-reminder`
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
| Question | Answer |
|
||||
|----------|--------|
|
||||
| Is the fork healthy? | Yes — fully synced with upstream v1.9.0 |
|
||||
| Other forks to consider? | None visible in this environment; upstream `affaan-m/everything-claude-code` is the source of truth |
|
||||
| Best install profile? | `developer` for day-to-day dev work |
|
||||
| Biggest gap in current setup? | 0 agents installed — add at minimum: planner, code-reviewer, tdd-guide, security-reviewer |
|
||||
| Quickest win? | Run `node scripts/install-plan.js --profile core && node scripts/install-apply.js` |
|
||||
83
agents/healthcare-reviewer.md
Normal file
83
agents/healthcare-reviewer.md
Normal file
@@ -0,0 +1,83 @@
|
||||
---
|
||||
name: healthcare-reviewer
|
||||
description: Reviews healthcare application code for clinical safety, CDSS accuracy, PHI compliance, and medical data integrity. Specialized for EMR/EHR, clinical decision support, and health information systems.
|
||||
tools: ["Read", "Grep", "Glob"]
|
||||
model: opus
|
||||
---
|
||||
|
||||
# Healthcare Reviewer — Clinical Safety & PHI Compliance
|
||||
|
||||
You are a clinical informatics reviewer for healthcare software. Patient safety is your top priority. You review code for clinical accuracy, data protection, and regulatory compliance.
|
||||
|
||||
## Your Responsibilities
|
||||
|
||||
1. **CDSS accuracy** — Verify drug interaction logic, dose validation rules, and clinical scoring implementations match published medical standards
|
||||
2. **PHI/PII protection** — Scan for patient data exposure in logs, errors, responses, URLs, and client storage
|
||||
3. **Clinical data integrity** — Ensure audit trails, locked records, and cascade protection
|
||||
4. **Medical data correctness** — Verify ICD-10/SNOMED mappings, lab reference ranges, and drug database entries
|
||||
5. **Integration compliance** — Validate HL7/FHIR message handling and error recovery
|
||||
|
||||
## Critical Checks
|
||||
|
||||
### CDSS Engine
|
||||
|
||||
- [ ] All drug interaction pairs produce correct alerts (both directions)
|
||||
- [ ] Dose validation rules fire on out-of-range values
|
||||
- [ ] Clinical scoring matches published specification (NEWS2 = Royal College of Physicians, qSOFA = Sepsis-3)
|
||||
- [ ] No false negatives (missed interaction = patient safety event)
|
||||
- [ ] Malformed inputs produce errors, NOT silent passes
|
||||
|
||||
### PHI Protection
|
||||
|
||||
- [ ] No patient data in `console.log`, `console.error`, or error messages
|
||||
- [ ] No PHI in URL parameters or query strings
|
||||
- [ ] No PHI in browser localStorage/sessionStorage
|
||||
- [ ] No `service_role` key in client-side code
|
||||
- [ ] RLS enabled on all tables with patient data
|
||||
- [ ] Cross-facility data isolation verified
|
||||
|
||||
### Clinical Workflow
|
||||
|
||||
- [ ] Encounter lock prevents edits (addendum only)
|
||||
- [ ] Audit trail entry on every create/read/update/delete of clinical data
|
||||
- [ ] Critical alerts are non-dismissable (not toast notifications)
|
||||
- [ ] Override reasons logged when clinician proceeds past critical alert
|
||||
- [ ] Red flag symptoms trigger visible alerts
|
||||
|
||||
### Data Integrity
|
||||
|
||||
- [ ] No CASCADE DELETE on patient records
|
||||
- [ ] Concurrent edit detection (optimistic locking or conflict resolution)
|
||||
- [ ] No orphaned records across clinical tables
|
||||
- [ ] Timestamps use consistent timezone
|
||||
|
||||
## Output Format
|
||||
|
||||
```
|
||||
## Healthcare Review: [module/feature]
|
||||
|
||||
### Patient Safety Impact: [CRITICAL / HIGH / MEDIUM / LOW / NONE]
|
||||
|
||||
### Clinical Accuracy
|
||||
- CDSS: [checks passed/failed]
|
||||
- Drug DB: [verified/issues]
|
||||
- Scoring: [matches spec/deviates]
|
||||
|
||||
### PHI Compliance
|
||||
- Exposure vectors checked: [list]
|
||||
- Issues found: [list or none]
|
||||
|
||||
### Issues
|
||||
1. [PATIENT SAFETY / CLINICAL / PHI / TECHNICAL] Description
|
||||
- Impact: [potential harm or exposure]
|
||||
- Fix: [required change]
|
||||
|
||||
### Verdict: [SAFE TO DEPLOY / NEEDS FIXES / BLOCK — PATIENT SAFETY RISK]
|
||||
```
|
||||
|
||||
## Rules
|
||||
|
||||
- When in doubt about clinical accuracy, flag as NEEDS REVIEW — never approve uncertain clinical logic
|
||||
- A single missed drug interaction is worse than a hundred false alarms
|
||||
- PHI exposure is always CRITICAL severity, regardless of how small the leak
|
||||
- Never approve code that silently catches CDSS errors
|
||||
446
agents/performance-optimizer.md
Normal file
446
agents/performance-optimizer.md
Normal file
@@ -0,0 +1,446 @@
|
||||
---
|
||||
name: performance-optimizer
|
||||
description: Performance analysis and optimization specialist. Use PROACTIVELY for identifying bottlenecks, optimizing slow code, reducing bundle sizes, and improving runtime performance. Profiling, memory leaks, render optimization, and algorithmic improvements.
|
||||
tools: ["Read", "Write", "Edit", "Bash", "Grep", "Glob"]
|
||||
model: sonnet
|
||||
---
|
||||
|
||||
# Performance Optimizer
|
||||
|
||||
You are an expert performance specialist focused on identifying bottlenecks and optimizing application speed, memory usage, and efficiency. Your mission is to make code faster, lighter, and more responsive.
|
||||
|
||||
## Core Responsibilities
|
||||
|
||||
1. **Performance Profiling** — Identify slow code paths, memory leaks, and bottlenecks
|
||||
2. **Bundle Optimization** — Reduce JavaScript bundle sizes, lazy loading, code splitting
|
||||
3. **Runtime Optimization** — Improve algorithmic efficiency, reduce unnecessary computations
|
||||
4. **React/Rendering Optimization** — Prevent unnecessary re-renders, optimize component trees
|
||||
5. **Database & Network** — Optimize queries, reduce API calls, implement caching
|
||||
6. **Memory Management** — Detect leaks, optimize memory usage, cleanup resources
|
||||
|
||||
## Analysis Commands
|
||||
|
||||
```bash
|
||||
# Bundle analysis
|
||||
npx bundle-analyzer
|
||||
npx source-map-explorer build/static/js/*.js
|
||||
|
||||
# Lighthouse performance audit
|
||||
npx lighthouse https://your-app.com --view
|
||||
|
||||
# Node.js profiling
|
||||
node --prof your-app.js
|
||||
node --prof-process isolate-*.log
|
||||
|
||||
# Memory analysis
|
||||
node --inspect your-app.js # Then use Chrome DevTools
|
||||
|
||||
# React profiling (in browser)
|
||||
# React DevTools > Profiler tab
|
||||
|
||||
# Network analysis
|
||||
npx webpack-bundle-analyzer
|
||||
```
|
||||
|
||||
## Performance Review Workflow
|
||||
|
||||
### 1. Identify Performance Issues
|
||||
|
||||
**Critical Performance Indicators:**
|
||||
|
||||
| Metric | Target | Action if Exceeded |
|
||||
|--------|--------|-------------------|
|
||||
| First Contentful Paint | < 1.8s | Optimize critical path, inline critical CSS |
|
||||
| Largest Contentful Paint | < 2.5s | Lazy load images, optimize server response |
|
||||
| Time to Interactive | < 3.8s | Code splitting, reduce JavaScript |
|
||||
| Cumulative Layout Shift | < 0.1 | Reserve space for images, avoid layout thrashing |
|
||||
| Total Blocking Time | < 200ms | Break up long tasks, use web workers |
|
||||
| Bundle Size (gzipped) | < 200KB | Tree shaking, lazy loading, code splitting |
|
||||
|
||||
### 2. Algorithmic Analysis
|
||||
|
||||
Check for inefficient algorithms:
|
||||
|
||||
| Pattern | Complexity | Better Alternative |
|
||||
|---------|------------|-------------------|
|
||||
| Nested loops on same data | O(n²) | Use Map/Set for O(1) lookups |
|
||||
| Repeated array searches | O(n) per search | Convert to Map for O(1) |
|
||||
| Sorting inside loop | O(n² log n) | Sort once outside loop |
|
||||
| String concatenation in loop | O(n²) | Use array.join() |
|
||||
| Deep cloning large objects | O(n) each time | Use shallow copy or immer |
|
||||
| Recursion without memoization | O(2^n) | Add memoization |
|
||||
|
||||
```typescript
|
||||
// BAD: O(n²) - searching array in loop
|
||||
for (const user of users) {
|
||||
const posts = allPosts.filter(p => p.userId === user.id); // O(n) per user
|
||||
}
|
||||
|
||||
// GOOD: O(n) - group once with Map
|
||||
const postsByUser = new Map<number, Post[]>();
|
||||
for (const post of allPosts) {
|
||||
const userPosts = postsByUser.get(post.userId) || [];
|
||||
userPosts.push(post);
|
||||
postsByUser.set(post.userId, userPosts);
|
||||
}
|
||||
// Now O(1) lookup per user
|
||||
```
|
||||
|
||||
### 3. React Performance Optimization
|
||||
|
||||
**Common React Anti-patterns:**
|
||||
|
||||
```tsx
|
||||
// BAD: Inline function creation in render
|
||||
<Button onClick={() => handleClick(id)}>Submit</Button>
|
||||
|
||||
// GOOD: Stable callback with useCallback
|
||||
const handleButtonClick = useCallback(() => handleClick(id), [handleClick, id]);
|
||||
<Button onClick={handleButtonClick}>Submit</Button>
|
||||
|
||||
// BAD: Object creation in render
|
||||
<Child style={{ color: 'red' }} />
|
||||
|
||||
// GOOD: Stable object reference
|
||||
const style = useMemo(() => ({ color: 'red' }), []);
|
||||
<Child style={style} />
|
||||
|
||||
// BAD: Expensive computation on every render
|
||||
const sortedItems = items.sort((a, b) => a.name.localeCompare(b.name));
|
||||
|
||||
// GOOD: Memoize expensive computations
|
||||
const sortedItems = useMemo(
|
||||
() => [...items].sort((a, b) => a.name.localeCompare(b.name)),
|
||||
[items]
|
||||
);
|
||||
|
||||
// BAD: List without keys or with index
|
||||
{items.map((item, index) => <Item key={index} />)}
|
||||
|
||||
// GOOD: Stable unique keys
|
||||
{items.map(item => <Item key={item.id} item={item} />)}
|
||||
```
|
||||
|
||||
**React Performance Checklist:**
|
||||
|
||||
- [ ] `useMemo` for expensive computations
|
||||
- [ ] `useCallback` for functions passed to children
|
||||
- [ ] `React.memo` for frequently re-rendered components
|
||||
- [ ] Proper dependency arrays in hooks
|
||||
- [ ] Virtualization for long lists (react-window, react-virtualized)
|
||||
- [ ] Lazy loading for heavy components (`React.lazy`)
|
||||
- [ ] Code splitting at route level
|
||||
|
||||
### 4. Bundle Size Optimization
|
||||
|
||||
**Bundle Analysis Checklist:**
|
||||
|
||||
```bash
|
||||
# Analyze bundle composition
|
||||
npx webpack-bundle-analyzer build/static/js/*.js
|
||||
|
||||
# Check for duplicate dependencies
|
||||
npx duplicate-package-checker-analyzer
|
||||
|
||||
# Find largest files
|
||||
du -sh node_modules/* | sort -hr | head -20
|
||||
```
|
||||
|
||||
**Optimization Strategies:**
|
||||
|
||||
| Issue | Solution |
|
||||
|-------|----------|
|
||||
| Large vendor bundle | Tree shaking, smaller alternatives |
|
||||
| Duplicate code | Extract to shared module |
|
||||
| Unused exports | Remove dead code with knip |
|
||||
| Moment.js | Use date-fns or dayjs (smaller) |
|
||||
| Lodash | Use lodash-es or native methods |
|
||||
| Large icons library | Import only needed icons |
|
||||
|
||||
```javascript
|
||||
// BAD: Import entire library
|
||||
import _ from 'lodash';
|
||||
import moment from 'moment';
|
||||
|
||||
// GOOD: Import only what you need
|
||||
import debounce from 'lodash/debounce';
|
||||
import { format, addDays } from 'date-fns';
|
||||
|
||||
// Or use lodash-es with tree shaking
|
||||
import { debounce, throttle } from 'lodash-es';
|
||||
```
|
||||
|
||||
### 5. Database & Query Optimization
|
||||
|
||||
**Query Optimization Patterns:**
|
||||
|
||||
```sql
|
||||
-- BAD: Select all columns
|
||||
SELECT * FROM users WHERE active = true;
|
||||
|
||||
-- GOOD: Select only needed columns
|
||||
SELECT id, name, email FROM users WHERE active = true;
|
||||
|
||||
-- BAD: N+1 queries (in application loop)
|
||||
-- 1 query for users, then N queries for each user's orders
|
||||
|
||||
-- GOOD: Single query with JOIN or batch fetch
|
||||
SELECT u.*, o.id as order_id, o.total
|
||||
FROM users u
|
||||
LEFT JOIN orders o ON u.id = o.user_id
|
||||
WHERE u.active = true;
|
||||
|
||||
-- Add index for frequently queried columns
|
||||
CREATE INDEX idx_users_active ON users(active);
|
||||
CREATE INDEX idx_orders_user_id ON orders(user_id);
|
||||
```
|
||||
|
||||
**Database Performance Checklist:**
|
||||
|
||||
- [ ] Indexes on frequently queried columns
|
||||
- [ ] Composite indexes for multi-column queries
|
||||
- [ ] Avoid SELECT * in production code
|
||||
- [ ] Use connection pooling
|
||||
- [ ] Implement query result caching
|
||||
- [ ] Use pagination for large result sets
|
||||
- [ ] Monitor slow query logs
|
||||
|
||||
### 6. Network & API Optimization
|
||||
|
||||
**Network Optimization Strategies:**
|
||||
|
||||
```typescript
|
||||
// BAD: Multiple sequential requests
|
||||
const user = await fetchUser(id);
|
||||
const posts = await fetchPosts(user.id);
|
||||
const comments = await fetchComments(posts[0].id);
|
||||
|
||||
// GOOD: Parallel requests when independent
|
||||
const [user, posts] = await Promise.all([
|
||||
fetchUser(id),
|
||||
fetchPosts(id)
|
||||
]);
|
||||
|
||||
// GOOD: Batch requests when possible
|
||||
const results = await batchFetch(['user1', 'user2', 'user3']);
|
||||
|
||||
// Implement request caching
|
||||
const fetchWithCache = async (url: string, ttl = 300000) => {
|
||||
const cached = cache.get(url);
|
||||
if (cached) return cached;
|
||||
|
||||
const data = await fetch(url).then(r => r.json());
|
||||
cache.set(url, data, ttl);
|
||||
return data;
|
||||
};
|
||||
|
||||
// Debounce rapid API calls
|
||||
const debouncedSearch = debounce(async (query: string) => {
|
||||
const results = await searchAPI(query);
|
||||
setResults(results);
|
||||
}, 300);
|
||||
```
|
||||
|
||||
**Network Optimization Checklist:**
|
||||
|
||||
- [ ] Parallel independent requests with `Promise.all`
|
||||
- [ ] Implement request caching
|
||||
- [ ] Debounce rapid-fire requests
|
||||
- [ ] Use streaming for large responses
|
||||
- [ ] Implement pagination for large datasets
|
||||
- [ ] Use GraphQL or API batching to reduce requests
|
||||
- [ ] Enable compression (gzip/brotli) on server
|
||||
|
||||
### 7. Memory Leak Detection
|
||||
|
||||
**Common Memory Leak Patterns:**
|
||||
|
||||
```typescript
|
||||
// BAD: Event listener without cleanup
|
||||
useEffect(() => {
|
||||
window.addEventListener('resize', handleResize);
|
||||
// Missing cleanup!
|
||||
}, []);
|
||||
|
||||
// GOOD: Clean up event listeners
|
||||
useEffect(() => {
|
||||
window.addEventListener('resize', handleResize);
|
||||
return () => window.removeEventListener('resize', handleResize);
|
||||
}, []);
|
||||
|
||||
// BAD: Timer without cleanup
|
||||
useEffect(() => {
|
||||
setInterval(() => pollData(), 1000);
|
||||
// Missing cleanup!
|
||||
}, []);
|
||||
|
||||
// GOOD: Clean up timers
|
||||
useEffect(() => {
|
||||
const interval = setInterval(() => pollData(), 1000);
|
||||
return () => clearInterval(interval);
|
||||
}, []);
|
||||
|
||||
// BAD: Holding references in closures
|
||||
const Component = () => {
|
||||
const largeData = useLargeData();
|
||||
useEffect(() => {
|
||||
eventEmitter.on('update', () => {
|
||||
console.log(largeData); // Closure keeps reference
|
||||
});
|
||||
}, [largeData]);
|
||||
};
|
||||
|
||||
// GOOD: Use refs or proper dependencies
|
||||
const largeDataRef = useRef(largeData);
|
||||
useEffect(() => {
|
||||
largeDataRef.current = largeData;
|
||||
}, [largeData]);
|
||||
|
||||
useEffect(() => {
|
||||
const handleUpdate = () => {
|
||||
console.log(largeDataRef.current);
|
||||
};
|
||||
eventEmitter.on('update', handleUpdate);
|
||||
return () => eventEmitter.off('update', handleUpdate);
|
||||
}, []);
|
||||
```
|
||||
|
||||
**Memory Leak Detection:**
|
||||
|
||||
```bash
|
||||
# Chrome DevTools Memory tab:
|
||||
# 1. Take heap snapshot
|
||||
# 2. Perform action
|
||||
# 3. Take another snapshot
|
||||
# 4. Compare to find objects that shouldn't exist
|
||||
# 5. Look for detached DOM nodes, event listeners, closures
|
||||
|
||||
# Node.js memory debugging
|
||||
node --inspect app.js
|
||||
# Open chrome://inspect
|
||||
# Take heap snapshots and compare
|
||||
```
|
||||
|
||||
## Performance Testing
|
||||
|
||||
### Lighthouse Audits
|
||||
|
||||
```bash
|
||||
# Run full lighthouse audit
|
||||
npx lighthouse https://your-app.com --view --preset=desktop
|
||||
|
||||
# CI mode for automated checks
|
||||
npx lighthouse https://your-app.com --output=json --output-path=./lighthouse.json
|
||||
|
||||
# Check specific metrics
|
||||
npx lighthouse https://your-app.com --only-categories=performance
|
||||
```
|
||||
|
||||
### Performance Budgets
|
||||
|
||||
```json
|
||||
// package.json
|
||||
{
|
||||
"bundlesize": [
|
||||
{
|
||||
"path": "./build/static/js/*.js",
|
||||
"maxSize": "200 kB"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Web Vitals Monitoring
|
||||
|
||||
```typescript
|
||||
// Track Core Web Vitals
|
||||
import { getCLS, getFID, getLCP, getFCP, getTTFB } from 'web-vitals';
|
||||
|
||||
getCLS(console.log); // Cumulative Layout Shift
|
||||
getFID(console.log); // First Input Delay
|
||||
getLCP(console.log); // Largest Contentful Paint
|
||||
getFCP(console.log); // First Contentful Paint
|
||||
getTTFB(console.log); // Time to First Byte
|
||||
```
|
||||
|
||||
## Performance Report Template
|
||||
|
||||
````markdown
|
||||
# Performance Audit Report
|
||||
|
||||
## Executive Summary
|
||||
- **Overall Score**: X/100
|
||||
- **Critical Issues**: X
|
||||
- **Recommendations**: X
|
||||
|
||||
## Bundle Analysis
|
||||
| Metric | Current | Target | Status |
|
||||
|--------|---------|--------|--------|
|
||||
| Total Size (gzip) | XXX KB | < 200 KB | WARNING: |
|
||||
| Main Bundle | XXX KB | < 100 KB | PASS: |
|
||||
| Vendor Bundle | XXX KB | < 150 KB | WARNING: |
|
||||
|
||||
## Web Vitals
|
||||
| Metric | Current | Target | Status |
|
||||
|--------|---------|--------|--------|
|
||||
| LCP | X.Xs | < 2.5s | PASS: |
|
||||
| FID | XXms | < 100ms | PASS: |
|
||||
| CLS | X.XX | < 0.1 | WARNING: |
|
||||
|
||||
## Critical Issues
|
||||
|
||||
### 1. [Issue Title]
|
||||
**File**: path/to/file.ts:42
|
||||
**Impact**: High - Causes XXXms delay
|
||||
**Fix**: [Description of fix]
|
||||
|
||||
```typescript
|
||||
// Before (slow)
|
||||
const slowCode = ...;
|
||||
|
||||
// After (optimized)
|
||||
const fastCode = ...;
|
||||
```
|
||||
|
||||
### 2. [Issue Title]
|
||||
...
|
||||
|
||||
## Recommendations
|
||||
1. [Priority recommendation]
|
||||
2. [Priority recommendation]
|
||||
3. [Priority recommendation]
|
||||
|
||||
## Estimated Impact
|
||||
- Bundle size reduction: XX KB (XX%)
|
||||
- LCP improvement: XXms
|
||||
- Time to Interactive improvement: XXms
|
||||
````
|
||||
|
||||
## When to Run
|
||||
|
||||
**ALWAYS:** Before major releases, after adding new features, when users report slowness, during performance regression testing.
|
||||
|
||||
**IMMEDIATELY:** Lighthouse score drops, bundle size increases >10%, memory usage grows, slow page loads.
|
||||
|
||||
## Red Flags - Act Immediately
|
||||
|
||||
| Issue | Action |
|
||||
|-------|--------|
|
||||
| Bundle > 500KB gzip | Code split, lazy load, tree shake |
|
||||
| LCP > 4s | Optimize critical path, preload resources |
|
||||
| Memory usage growing | Check for leaks, review useEffect cleanup |
|
||||
| CPU spikes | Profile with Chrome DevTools |
|
||||
| Database query > 1s | Add index, optimize query, cache results |
|
||||
|
||||
## Success Metrics
|
||||
|
||||
- Lighthouse performance score > 90
|
||||
- All Core Web Vitals in "good" range
|
||||
- Bundle size under budget
|
||||
- No memory leaks detected
|
||||
- Test suite still passing
|
||||
- No performance regressions
|
||||
|
||||
---
|
||||
|
||||
**Remember**: Performance is a feature. Users notice speed. Every 100ms of improvement matters. Optimize for the 90th percentile, not the average.
|
||||
@@ -78,7 +78,7 @@ Flag it clearly before resuming:
|
||||
```
|
||||
ASIDE: [answer]
|
||||
|
||||
⚠️ Note: This answer suggests [issue] with the current approach. Want to address this before continuing, or proceed as planned?
|
||||
WARNING: Note: This answer suggests [issue] with the current approach. Want to address this before continuing, or proceed as planned?
|
||||
```
|
||||
Wait for the user's decision before resuming.
|
||||
|
||||
@@ -119,7 +119,7 @@ Note the change needed but do not make it during the aside:
|
||||
```
|
||||
ASIDE: [answer]
|
||||
|
||||
📝 Worth fixing: [what should be changed]. I'll flag this after the current task unless you want to address it now.
|
||||
Worth fixing: [what should be changed]. I'll flag this after the current task unless you want to address it now.
|
||||
```
|
||||
|
||||
**Question is ambiguous or too vague:**
|
||||
@@ -150,7 +150,7 @@ No — the shared cache object in src/cache/store.ts:34 is mutated without locki
|
||||
Under concurrent requests this is a race condition. It's low risk in a single-process
|
||||
Node.js server but would be a real problem with worker threads or clustering.
|
||||
|
||||
⚠️ Note: This could affect the feature we're building. Want to address this now or continue and fix it in a follow-up?
|
||||
WARNING: Note: This could affect the feature we're building. Want to address this now or continue and fix it in a follow-up?
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
@@ -9,7 +9,7 @@ Comprehensive security and quality review of uncommitted changes:
|
||||
**Security Issues (CRITICAL):**
|
||||
- Hardcoded credentials, API keys, tokens
|
||||
- SQL injection vulnerabilities
|
||||
- XSS vulnerabilities
|
||||
- XSS vulnerabilities
|
||||
- Missing input validation
|
||||
- Insecure dependencies
|
||||
- Path traversal risks
|
||||
|
||||
@@ -129,7 +129,7 @@ All tests passed.
|
||||
| Files modified | 2 |
|
||||
| Remaining issues | 0 |
|
||||
|
||||
Build Status: ✅ SUCCESS
|
||||
Build Status: PASS: SUCCESS
|
||||
```
|
||||
|
||||
## Common Errors Fixed
|
||||
|
||||
@@ -108,16 +108,16 @@ void processUser(const User& user) {
|
||||
- HIGH: 1
|
||||
- MEDIUM: 0
|
||||
|
||||
Recommendation: ❌ Block merge until CRITICAL issue is fixed
|
||||
Recommendation: FAIL: Block merge until CRITICAL issue is fixed
|
||||
```
|
||||
|
||||
## Approval Criteria
|
||||
|
||||
| Status | Condition |
|
||||
|--------|-----------|
|
||||
| ✅ Approve | No CRITICAL or HIGH issues |
|
||||
| ⚠️ Warning | Only MEDIUM issues (merge with caution) |
|
||||
| ❌ Block | CRITICAL or HIGH issues found |
|
||||
| PASS: Approve | No CRITICAL or HIGH issues |
|
||||
| WARNING: Warning | Only MEDIUM issues (merge with caution) |
|
||||
| FAIL: Block | CRITICAL or HIGH issues found |
|
||||
|
||||
## Integration with Other Commands
|
||||
|
||||
|
||||
@@ -182,7 +182,7 @@ Artifacts generated:
|
||||
╔══════════════════════════════════════════════════════════════╗
|
||||
║ E2E Test Results ║
|
||||
╠══════════════════════════════════════════════════════════════╣
|
||||
║ Status: ✅ ALL TESTS PASSED ║
|
||||
║ Status: PASS: ALL TESTS PASSED ║
|
||||
║ Total: 3 tests ║
|
||||
║ Passed: 3 (100%) ║
|
||||
║ Failed: 0 ║
|
||||
@@ -191,15 +191,15 @@ Artifacts generated:
|
||||
╚══════════════════════════════════════════════════════════════╝
|
||||
|
||||
Artifacts:
|
||||
📸 Screenshots: 2 files
|
||||
📹 Videos: 0 files (only on failure)
|
||||
🔍 Traces: 0 files (only on failure)
|
||||
📊 HTML Report: playwright-report/index.html
|
||||
Screenshots: 2 files
|
||||
Videos: 0 files (only on failure)
|
||||
Traces: 0 files (only on failure)
|
||||
HTML Report: playwright-report/index.html
|
||||
|
||||
View report: npx playwright show-report
|
||||
```
|
||||
|
||||
✅ E2E test suite ready for CI/CD integration!
|
||||
PASS: E2E test suite ready for CI/CD integration!
|
||||
```
|
||||
|
||||
## Test Artifacts
|
||||
@@ -235,7 +235,7 @@ open artifacts/search-results.png
|
||||
If a test fails intermittently:
|
||||
|
||||
```
|
||||
⚠️ FLAKY TEST DETECTED: tests/e2e/markets/trade.spec.ts
|
||||
WARNING: FLAKY TEST DETECTED: tests/e2e/markets/trade.spec.ts
|
||||
|
||||
Test passed 7/10 runs (70% pass rate)
|
||||
|
||||
@@ -254,10 +254,10 @@ Quarantine recommendation: Mark as test.fixme() until fixed
|
||||
## Browser Configuration
|
||||
|
||||
Tests run on multiple browsers by default:
|
||||
- ✅ Chromium (Desktop Chrome)
|
||||
- ✅ Firefox (Desktop)
|
||||
- ✅ WebKit (Desktop Safari)
|
||||
- ✅ Mobile Chrome (optional)
|
||||
- PASS: Chromium (Desktop Chrome)
|
||||
- PASS: Firefox (Desktop)
|
||||
- PASS: WebKit (Desktop Safari)
|
||||
- PASS: Mobile Chrome (optional)
|
||||
|
||||
Configure in `playwright.config.ts` to adjust browsers.
|
||||
|
||||
@@ -285,7 +285,7 @@ Add to your CI pipeline:
|
||||
|
||||
For PMX, prioritize these E2E tests:
|
||||
|
||||
**🔴 CRITICAL (Must Always Pass):**
|
||||
**CRITICAL (Must Always Pass):**
|
||||
1. User can connect wallet
|
||||
2. User can browse markets
|
||||
3. User can search markets (semantic search)
|
||||
@@ -294,7 +294,7 @@ For PMX, prioritize these E2E tests:
|
||||
6. Market resolves correctly
|
||||
7. User can withdraw funds
|
||||
|
||||
**🟡 IMPORTANT:**
|
||||
**IMPORTANT:**
|
||||
1. Market creation flow
|
||||
2. User profile updates
|
||||
3. Real-time price updates
|
||||
@@ -305,20 +305,20 @@ For PMX, prioritize these E2E tests:
|
||||
## Best Practices
|
||||
|
||||
**DO:**
|
||||
- ✅ Use Page Object Model for maintainability
|
||||
- ✅ Use data-testid attributes for selectors
|
||||
- ✅ Wait for API responses, not arbitrary timeouts
|
||||
- ✅ Test critical user journeys end-to-end
|
||||
- ✅ Run tests before merging to main
|
||||
- ✅ Review artifacts when tests fail
|
||||
- PASS: Use Page Object Model for maintainability
|
||||
- PASS: Use data-testid attributes for selectors
|
||||
- PASS: Wait for API responses, not arbitrary timeouts
|
||||
- PASS: Test critical user journeys end-to-end
|
||||
- PASS: Run tests before merging to main
|
||||
- PASS: Review artifacts when tests fail
|
||||
|
||||
**DON'T:**
|
||||
- ❌ Use brittle selectors (CSS classes can change)
|
||||
- ❌ Test implementation details
|
||||
- ❌ Run tests against production
|
||||
- ❌ Ignore flaky tests
|
||||
- ❌ Skip artifact review on failures
|
||||
- ❌ Test every edge case with E2E (use unit tests)
|
||||
- FAIL: Use brittle selectors (CSS classes can change)
|
||||
- FAIL: Test implementation details
|
||||
- FAIL: Run tests against production
|
||||
- FAIL: Ignore flaky tests
|
||||
- FAIL: Skip artifact review on failures
|
||||
- FAIL: Test every edge case with E2E (use unit tests)
|
||||
|
||||
## Important Notes
|
||||
|
||||
|
||||
@@ -140,7 +140,7 @@ ok project/internal/handler 0.023s
|
||||
| Files modified | 2 |
|
||||
| Remaining issues | 0 |
|
||||
|
||||
Build Status: ✅ SUCCESS
|
||||
Build Status: PASS: SUCCESS
|
||||
```
|
||||
|
||||
## Common Errors Fixed
|
||||
|
||||
@@ -124,16 +124,16 @@ return fmt.Errorf("get user %s: %w", userID, err)
|
||||
- HIGH: 1
|
||||
- MEDIUM: 0
|
||||
|
||||
Recommendation: ❌ Block merge until CRITICAL issue is fixed
|
||||
Recommendation: FAIL: Block merge until CRITICAL issue is fixed
|
||||
```
|
||||
|
||||
## Approval Criteria
|
||||
|
||||
| Status | Condition |
|
||||
|--------|-----------|
|
||||
| ✅ Approve | No CRITICAL or HIGH issues |
|
||||
| ⚠️ Warning | Only MEDIUM issues (merge with caution) |
|
||||
| ❌ Block | CRITICAL or HIGH issues found |
|
||||
| PASS: Approve | No CRITICAL or HIGH issues |
|
||||
| WARNING: Warning | Only MEDIUM issues (merge with caution) |
|
||||
| FAIL: Block | CRITICAL or HIGH issues found |
|
||||
|
||||
## Integration with Other Commands
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ Import instincts from local file paths or HTTP(S) URLs.
|
||||
## Import Process
|
||||
|
||||
```
|
||||
📥 Importing instincts from: team-instincts.yaml
|
||||
Importing instincts from: team-instincts.yaml
|
||||
================================================
|
||||
|
||||
Found 12 instincts to import.
|
||||
@@ -60,12 +60,12 @@ These will be added:
|
||||
|
||||
## Duplicate Instincts (3)
|
||||
Already have similar instincts:
|
||||
⚠️ prefer-functional-style
|
||||
WARNING: prefer-functional-style
|
||||
Local: 0.8 confidence, 12 observations
|
||||
Import: 0.7 confidence
|
||||
→ Keep local (higher confidence)
|
||||
|
||||
⚠️ test-first-workflow
|
||||
WARNING: test-first-workflow
|
||||
Local: 0.75 confidence
|
||||
Import: 0.9 confidence
|
||||
→ Update to import (higher confidence)
|
||||
@@ -102,7 +102,7 @@ project_name: "my-project"
|
||||
|
||||
After import:
|
||||
```
|
||||
✅ Import complete!
|
||||
PASS: Import complete!
|
||||
|
||||
Added: 8 instincts
|
||||
Updated: 1 instinct
|
||||
|
||||
@@ -131,7 +131,7 @@ $ ./gradlew test
|
||||
| Files modified | 2 |
|
||||
| Remaining issues | 0 |
|
||||
|
||||
Build Status: ✅ SUCCESS
|
||||
Build Status: PASS: SUCCESS
|
||||
````
|
||||
|
||||
## Common Errors Fixed
|
||||
|
||||
@@ -80,7 +80,7 @@ Agent:
|
||||
## Static Analysis Results
|
||||
✓ Build: Successful
|
||||
✓ detekt: No issues
|
||||
⚠ ktlint: 2 formatting warnings
|
||||
WARNING: ktlint: 2 formatting warnings
|
||||
|
||||
## Issues Found
|
||||
|
||||
@@ -116,16 +116,16 @@ launch {
|
||||
- HIGH: 1
|
||||
- MEDIUM: 0
|
||||
|
||||
Recommendation: ❌ Block merge until CRITICAL issue is fixed
|
||||
Recommendation: FAIL: Block merge until CRITICAL issue is fixed
|
||||
````
|
||||
|
||||
## Approval Criteria
|
||||
|
||||
| Status | Condition |
|
||||
|--------|-----------|
|
||||
| ✅ Approve | No CRITICAL or HIGH issues |
|
||||
| ⚠️ Warning | Only MEDIUM issues (merge with caution) |
|
||||
| ❌ Block | CRITICAL or HIGH issues found |
|
||||
| PASS: Approve | No CRITICAL or HIGH issues |
|
||||
| WARNING: Warning | Only MEDIUM issues (merge with caution) |
|
||||
| FAIL: Block | CRITICAL or HIGH issues found |
|
||||
|
||||
## Integration with Other Commands
|
||||
|
||||
|
||||
@@ -73,7 +73,7 @@ origin: auto-extracted
|
||||
| **Absorb into [X]** | Should be appended to an existing skill | Show target skill and additions → Step 6 |
|
||||
| **Drop** | Trivial, redundant, or too abstract | Explain reasoning and stop |
|
||||
|
||||
**Guideline dimensions** (informing the verdict, not scored):
|
||||
**Guideline dimensions** (informing the verdict, not scored):
|
||||
|
||||
- **Specificity & Actionability**: Contains code examples or commands that are immediately usable
|
||||
- **Scope Fit**: Name, trigger conditions, and content are aligned and focused on a single pattern
|
||||
|
||||
@@ -204,9 +204,9 @@ Synthesize both analyses, generate **Step-by-step Implementation Plan**:
|
||||
3. Output prompt in **bold text** (MUST use actual saved file path):
|
||||
|
||||
---
|
||||
**Plan generated and saved to `.claude/plan/actual-feature-name.md`**
|
||||
**Plan generated and saved to `.claude/plan/actual-feature-name.md`**
|
||||
|
||||
**Please review the plan above. You can:**
|
||||
**Please review the plan above. You can:**
|
||||
- **Modify plan**: Tell me what needs adjustment, I'll update the plan
|
||||
- **Execute plan**: Copy the following command to a new session
|
||||
|
||||
@@ -215,7 +215,7 @@ Synthesize both analyses, generate **Step-by-step Implementation Plan**:
|
||||
```
|
||||
---
|
||||
|
||||
**NOTE**: The `actual-feature-name.md` above MUST be replaced with the actual saved filename!
|
||||
**NOTE**: The `actual-feature-name.md` above MUST be replaced with the actual saved filename!
|
||||
|
||||
4. **Immediately terminate current response** (Stop here. No more tool calls.)
|
||||
|
||||
|
||||
@@ -89,7 +89,7 @@ Agent:
|
||||
## Static Analysis Results
|
||||
✓ ruff: No issues
|
||||
✓ mypy: No errors
|
||||
⚠️ black: 2 files need reformatting
|
||||
WARNING: black: 2 files need reformatting
|
||||
✓ bandit: No security issues
|
||||
|
||||
## Issues Found
|
||||
@@ -155,7 +155,7 @@ with open("config.json") as f: # Good
|
||||
- HIGH: 1
|
||||
- MEDIUM: 2
|
||||
|
||||
Recommendation: ❌ Block merge until CRITICAL issue is fixed
|
||||
Recommendation: FAIL: Block merge until CRITICAL issue is fixed
|
||||
|
||||
## Formatting Required
|
||||
Run: `black app/routes/user.py app/services/auth.py`
|
||||
@@ -165,9 +165,9 @@ Run: `black app/routes/user.py app/services/auth.py`
|
||||
|
||||
| Status | Condition |
|
||||
|--------|-----------|
|
||||
| ✅ Approve | No CRITICAL or HIGH issues |
|
||||
| ⚠️ Warning | Only MEDIUM issues (merge with caution) |
|
||||
| ❌ Block | CRITICAL or HIGH issues found |
|
||||
| PASS: Approve | No CRITICAL or HIGH issues |
|
||||
| WARNING: Warning | Only MEDIUM issues (merge with caution) |
|
||||
| FAIL: Block | CRITICAL or HIGH issues found |
|
||||
|
||||
## Integration with Other Commands
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@ Deleted: 12 unused functions
|
||||
Skipped: 2 items (tests failed)
|
||||
Saved: ~450 lines removed
|
||||
──────────────────────────────
|
||||
All tests passing ✅
|
||||
All tests passing PASS:
|
||||
```
|
||||
|
||||
## Rules
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
description: Load the most recent session file from ~/.claude/sessions/ and resume work with full context from where the last session ended.
|
||||
description: Load the most recent session file from ~/.claude/session-data/ and resume work with full context from where the last session ended.
|
||||
---
|
||||
|
||||
# Resume Session Command
|
||||
@@ -17,10 +17,10 @@ This command is the counterpart to `/save-session`.
|
||||
## Usage
|
||||
|
||||
```
|
||||
/resume-session # loads most recent file in ~/.claude/sessions/
|
||||
/resume-session # loads most recent file in ~/.claude/session-data/
|
||||
/resume-session 2024-01-15 # loads most recent session for that date
|
||||
/resume-session ~/.claude/sessions/2024-01-15-session.tmp # loads a specific legacy-format file
|
||||
/resume-session ~/.claude/sessions/2024-01-15-abc123de-session.tmp # loads a current short-id session file
|
||||
/resume-session ~/.claude/session-data/2024-01-15-abc123de-session.tmp # loads a current short-id session file
|
||||
/resume-session ~/.claude/sessions/2024-01-15-session.tmp # loads a specific legacy-format file
|
||||
```
|
||||
|
||||
## Process
|
||||
@@ -29,19 +29,20 @@ This command is the counterpart to `/save-session`.
|
||||
|
||||
If no argument provided:
|
||||
|
||||
1. Check `~/.claude/sessions/`
|
||||
1. Check `~/.claude/session-data/`
|
||||
2. Pick the most recently modified `*-session.tmp` file
|
||||
3. If the folder does not exist or has no matching files, tell the user:
|
||||
```
|
||||
No session files found in ~/.claude/sessions/
|
||||
No session files found in ~/.claude/session-data/
|
||||
Run /save-session at the end of a session to create one.
|
||||
```
|
||||
Then stop.
|
||||
|
||||
If an argument is provided:
|
||||
|
||||
- If it looks like a date (`YYYY-MM-DD`), search `~/.claude/sessions/` for files matching
|
||||
`YYYY-MM-DD-session.tmp` (legacy format) or `YYYY-MM-DD-<shortid>-session.tmp` (current format)
|
||||
- If it looks like a date (`YYYY-MM-DD`), search `~/.claude/session-data/` first, then the legacy
|
||||
`~/.claude/sessions/`, for files matching `YYYY-MM-DD-session.tmp` (legacy format) or
|
||||
`YYYY-MM-DD-<shortid>-session.tmp` (current format)
|
||||
and load the most recently modified variant for that date
|
||||
- If it looks like a file path, read that file directly
|
||||
- If not found, report clearly and stop
|
||||
@@ -64,9 +65,9 @@ WHAT WE'RE BUILDING:
|
||||
[2-3 sentence summary in your own words]
|
||||
|
||||
CURRENT STATE:
|
||||
✅ Working: [count] items confirmed
|
||||
🔄 In Progress: [list files that are in progress]
|
||||
🗒️ Not Started: [list planned but untouched]
|
||||
PASS: Working: [count] items confirmed
|
||||
In Progress: [list files that are in progress]
|
||||
Not Started: [list planned but untouched]
|
||||
|
||||
WHAT NOT TO RETRY:
|
||||
[list every failed approach with its reason — this is critical]
|
||||
@@ -98,10 +99,10 @@ If no next step is defined — ask the user where to start, and optionally sugge
|
||||
Load the most recently modified matching file for that date, regardless of whether it uses the legacy no-id format or the current short-id format.
|
||||
|
||||
**Session file references files that no longer exist:**
|
||||
Note this during the briefing — "⚠️ `path/to/file.ts` referenced in session but not found on disk."
|
||||
Note this during the briefing — "WARNING: `path/to/file.ts` referenced in session but not found on disk."
|
||||
|
||||
**Session file is from more than 7 days ago:**
|
||||
Note the gap — "⚠️ This session is from N days ago (threshold: 7 days). Things may have changed." — then proceed normally.
|
||||
Note the gap — "WARNING: This session is from N days ago (threshold: 7 days). Things may have changed." — then proceed normally.
|
||||
|
||||
**User provides a file path directly (e.g., forwarded from a teammate):**
|
||||
Read it and follow the same briefing process — the format is the same regardless of source.
|
||||
@@ -114,7 +115,7 @@ Report: "Session file found but appears empty or unreadable. You may need to cre
|
||||
## Example Output
|
||||
|
||||
```
|
||||
SESSION LOADED: /Users/you/.claude/sessions/2024-01-15-abc123de-session.tmp
|
||||
SESSION LOADED: /Users/you/.claude/session-data/2024-01-15-abc123de-session.tmp
|
||||
════════════════════════════════════════════════
|
||||
|
||||
PROJECT: my-app — JWT Authentication
|
||||
@@ -125,13 +126,13 @@ Register and login endpoints are partially done. Route protection
|
||||
via middleware hasn't been started yet.
|
||||
|
||||
CURRENT STATE:
|
||||
✅ Working: 3 items (register endpoint, JWT generation, password hashing)
|
||||
🔄 In Progress: app/api/auth/login/route.ts (token works, cookie not set yet)
|
||||
🗒️ Not Started: middleware.ts, app/login/page.tsx
|
||||
PASS: Working: 3 items (register endpoint, JWT generation, password hashing)
|
||||
In Progress: app/api/auth/login/route.ts (token works, cookie not set yet)
|
||||
Not Started: middleware.ts, app/login/page.tsx
|
||||
|
||||
WHAT NOT TO RETRY:
|
||||
❌ Next-Auth — conflicts with custom Prisma adapter, threw adapter error on every request
|
||||
❌ localStorage for JWT — causes SSR hydration mismatch, incompatible with Next.js
|
||||
FAIL: Next-Auth — conflicts with custom Prisma adapter, threw adapter error on every request
|
||||
FAIL: localStorage for JWT — causes SSR hydration mismatch, incompatible with Next.js
|
||||
|
||||
OPEN QUESTIONS / BLOCKERS:
|
||||
- Does cookies().set() work inside a Route Handler or only Server Actions?
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
description: Save current session state to a dated file in ~/.claude/sessions/ so work can be resumed in a future session with full context.
|
||||
description: Save current session state to a dated file in ~/.claude/session-data/ so work can be resumed in a future session with full context.
|
||||
---
|
||||
|
||||
# Save Session Command
|
||||
@@ -29,19 +29,19 @@ Before writing the file, collect:
|
||||
Create the canonical sessions folder in the user's Claude home directory:
|
||||
|
||||
```bash
|
||||
mkdir -p ~/.claude/sessions
|
||||
mkdir -p ~/.claude/session-data
|
||||
```
|
||||
|
||||
### Step 3: Write the session file
|
||||
|
||||
Create `~/.claude/sessions/YYYY-MM-DD-<short-id>-session.tmp`, using today's actual date and a short-id that satisfies the rules enforced by `SESSION_FILENAME_REGEX` in `session-manager.js`:
|
||||
Create `~/.claude/session-data/YYYY-MM-DD-<short-id>-session.tmp`, using today's actual date and a short-id that satisfies the rules enforced by `SESSION_FILENAME_REGEX` in `session-manager.js`:
|
||||
|
||||
- Allowed characters: lowercase `a-z`, digits `0-9`, hyphens `-`
|
||||
- Minimum length: 8 characters
|
||||
- No uppercase letters, no underscores, no spaces
|
||||
- Compatibility characters: letters `a-z` / `A-Z`, digits `0-9`, hyphens `-`, underscores `_`
|
||||
- Compatibility minimum length: 1 character
|
||||
- Recommended style for new files: lowercase letters, digits, and hyphens with 8+ characters to avoid collisions
|
||||
|
||||
Valid examples: `abc123de`, `a1b2c3d4`, `frontend-worktree-1`
|
||||
Invalid examples: `ABC123de` (uppercase), `short` (under 8 chars), `test_id1` (underscore)
|
||||
Valid examples: `abc123de`, `a1b2c3d4`, `frontend-worktree-1`, `ChezMoi_2`
|
||||
Avoid for new files: `A`, `test_id1`, `ABC123de`
|
||||
|
||||
Full valid filename example: `2024-01-15-abc123de-session.tmp`
|
||||
|
||||
@@ -130,10 +130,10 @@ If nothing is queued: "No specific untried approaches identified."
|
||||
|
||||
| File | Status | Notes |
|
||||
| ----------------- | -------------- | -------------------------- |
|
||||
| `path/to/file.ts` | ✅ Complete | [what it does] |
|
||||
| `path/to/file.ts` | 🔄 In Progress | [what's done, what's left] |
|
||||
| `path/to/file.ts` | ❌ Broken | [what's wrong] |
|
||||
| `path/to/file.ts` | 🗒️ Not Started | [planned but not touched] |
|
||||
| `path/to/file.ts` | PASS: Complete | [what it does] |
|
||||
| `path/to/file.ts` | In Progress | [what's done, what's left] |
|
||||
| `path/to/file.ts` | FAIL: Broken | [what's wrong] |
|
||||
| `path/to/file.ts` | Not Started | [planned but not touched] |
|
||||
|
||||
If no files were touched: "No files modified this session."
|
||||
|
||||
@@ -235,11 +235,11 @@ refreshes without exposing the token to JavaScript.
|
||||
|
||||
| File | Status | Notes |
|
||||
| -------------------------------- | -------------- | ----------------------------------------------- |
|
||||
| `app/api/auth/register/route.ts` | ✅ Complete | Works, tested |
|
||||
| `app/api/auth/login/route.ts` | 🔄 In Progress | Token generates but not setting cookie yet |
|
||||
| `lib/auth.ts` | ✅ Complete | JWT helpers, all tested |
|
||||
| `middleware.ts` | 🗒️ Not Started | Route protection, needs cookie read logic first |
|
||||
| `app/login/page.tsx` | 🗒️ Not Started | UI not started |
|
||||
| `app/api/auth/register/route.ts` | PASS: Complete | Works, tested |
|
||||
| `app/api/auth/login/route.ts` | In Progress | Token generates but not setting cookie yet |
|
||||
| `lib/auth.ts` | PASS: Complete | JWT helpers, all tested |
|
||||
| `middleware.ts` | Not Started | Route protection, needs cookie read logic first |
|
||||
| `app/login/page.tsx` | Not Started | UI not started |
|
||||
|
||||
---
|
||||
|
||||
@@ -271,5 +271,5 @@ Then test with Postman — the response should include a `Set-Cookie` header.
|
||||
- The "What Did NOT Work" section is the most critical — future sessions will blindly retry failed approaches without it
|
||||
- If the user asks to save mid-session (not just at the end), save what's known so far and mark in-progress items clearly
|
||||
- The file is meant to be read by Claude at the start of the next session via `/resume-session`
|
||||
- Use the canonical global session store: `~/.claude/sessions/`
|
||||
- Use the canonical global session store: `~/.claude/session-data/`
|
||||
- Prefer the short-id filename form (`YYYY-MM-DD-<short-id>-session.tmp`) for any new session file
|
||||
|
||||
@@ -4,7 +4,7 @@ description: Manage Claude Code session history, aliases, and session metadata.
|
||||
|
||||
# Sessions Command
|
||||
|
||||
Manage Claude Code session history - list, load, alias, and edit sessions stored in `~/.claude/sessions/`.
|
||||
Manage Claude Code session history - list, load, alias, and edit sessions stored in `~/.claude/session-data/` with legacy reads from `~/.claude/sessions/`.
|
||||
|
||||
## Usage
|
||||
|
||||
@@ -89,7 +89,7 @@ const size = sm.getSessionSize(session.sessionPath);
|
||||
const aliases = aa.getAliasesForSession(session.filename);
|
||||
|
||||
console.log('Session: ' + session.filename);
|
||||
console.log('Path: ~/.claude/sessions/' + session.filename);
|
||||
console.log('Path: ' + session.sessionPath);
|
||||
console.log('');
|
||||
console.log('Statistics:');
|
||||
console.log(' Lines: ' + stats.lineCount);
|
||||
@@ -327,7 +327,7 @@ $ARGUMENTS:
|
||||
|
||||
## Notes
|
||||
|
||||
- Sessions are stored as markdown files in `~/.claude/sessions/`
|
||||
- Sessions are stored as markdown files in `~/.claude/session-data/` with legacy reads from `~/.claude/sessions/`
|
||||
- Aliases are stored in `~/.claude/session-aliases.json`
|
||||
- Session IDs can be shortened (first 4-8 characters usually unique enough)
|
||||
- Use aliases for frequently referenced sessions
|
||||
|
||||
@@ -133,7 +133,7 @@ FAIL lib/liquidity.test.ts
|
||||
1 test failed, 0 passed
|
||||
```
|
||||
|
||||
✅ Tests fail as expected. Ready to implement.
|
||||
PASS: Tests fail as expected. Ready to implement.
|
||||
|
||||
## Step 4: Implement Minimal Code (GREEN)
|
||||
|
||||
@@ -179,7 +179,7 @@ PASS lib/liquidity.test.ts
|
||||
3 tests passed
|
||||
```
|
||||
|
||||
✅ All tests passing!
|
||||
PASS: All tests passing!
|
||||
|
||||
## Step 6: Refactor (IMPROVE)
|
||||
|
||||
@@ -236,7 +236,7 @@ PASS lib/liquidity.test.ts
|
||||
3 tests passed
|
||||
```
|
||||
|
||||
✅ Refactoring complete, tests still passing!
|
||||
PASS: Refactoring complete, tests still passing!
|
||||
|
||||
## Step 8: Check Coverage
|
||||
|
||||
@@ -247,29 +247,29 @@ File | % Stmts | % Branch | % Funcs | % Lines
|
||||
---------------|---------|----------|---------|--------
|
||||
liquidity.ts | 100 | 100 | 100 | 100
|
||||
|
||||
Coverage: 100% ✅ (Target: 80%)
|
||||
Coverage: 100% PASS: (Target: 80%)
|
||||
```
|
||||
|
||||
✅ TDD session complete!
|
||||
PASS: TDD session complete!
|
||||
```
|
||||
|
||||
## TDD Best Practices
|
||||
|
||||
**DO:**
|
||||
- ✅ Write the test FIRST, before any implementation
|
||||
- ✅ Run tests and verify they FAIL before implementing
|
||||
- ✅ Write minimal code to make tests pass
|
||||
- ✅ Refactor only after tests are green
|
||||
- ✅ Add edge cases and error scenarios
|
||||
- ✅ Aim for 80%+ coverage (100% for critical code)
|
||||
- PASS: Write the test FIRST, before any implementation
|
||||
- PASS: Run tests and verify they FAIL before implementing
|
||||
- PASS: Write minimal code to make tests pass
|
||||
- PASS: Refactor only after tests are green
|
||||
- PASS: Add edge cases and error scenarios
|
||||
- PASS: Aim for 80%+ coverage (100% for critical code)
|
||||
|
||||
**DON'T:**
|
||||
- ❌ Write implementation before tests
|
||||
- ❌ Skip running tests after each change
|
||||
- ❌ Write too much code at once
|
||||
- ❌ Ignore failing tests
|
||||
- ❌ Test implementation details (test behavior)
|
||||
- ❌ Mock everything (prefer integration tests)
|
||||
- FAIL: Write implementation before tests
|
||||
- FAIL: Skip running tests after each change
|
||||
- FAIL: Write too much code at once
|
||||
- FAIL: Ignore failing tests
|
||||
- FAIL: Test implementation details (test behavior)
|
||||
- FAIL: Mock everything (prefer integration tests)
|
||||
|
||||
## Test Types to Include
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ File Before After
|
||||
src/services/auth.ts 45% 88%
|
||||
src/utils/validation.ts 32% 82%
|
||||
──────────────────────────────
|
||||
Overall: 67% 84% ✅
|
||||
Overall: 67% 84% PASS:
|
||||
```
|
||||
|
||||
## Focus Areas
|
||||
|
||||
919
docs/SKILL-DEVELOPMENT-GUIDE.md
Normal file
919
docs/SKILL-DEVELOPMENT-GUIDE.md
Normal file
@@ -0,0 +1,919 @@
|
||||
# Skill Development Guide
|
||||
|
||||
A comprehensive guide to creating effective skills for Everything Claude Code (ECC).
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [What Are Skills?](#what-are-skills)
|
||||
- [Skill Architecture](#skill-architecture)
|
||||
- [Creating Your First Skill](#creating-your-first-skill)
|
||||
- [Skill Categories](#skill-categories)
|
||||
- [Writing Effective Skill Content](#writing-effective-skill-content)
|
||||
- [Best Practices](#best-practices)
|
||||
- [Common Patterns](#common-patterns)
|
||||
- [Testing Your Skill](#testing-your-skill)
|
||||
- [Submitting Your Skill](#submitting-your-skill)
|
||||
- [Examples Gallery](#examples-gallery)
|
||||
|
||||
---
|
||||
|
||||
## What Are Skills?
|
||||
|
||||
Skills are **knowledge modules** that Claude Code loads based on context. They provide:
|
||||
|
||||
- **Domain expertise**: Framework patterns, language idioms, best practices
|
||||
- **Workflow definitions**: Step-by-step processes for common tasks
|
||||
- **Reference material**: Code snippets, checklists, decision trees
|
||||
- **Context injection**: Activate when specific conditions are met
|
||||
|
||||
Unlike **agents** (specialized subassistants) or **commands** (user-triggered actions), skills are passive knowledge that Claude Code references when relevant.
|
||||
|
||||
### When Skills Activate
|
||||
|
||||
Skills activate when:
|
||||
- The user's task matches the skill's domain
|
||||
- Claude Code detects relevant context
|
||||
- A command references a skill
|
||||
- An agent needs domain knowledge
|
||||
|
||||
### Skill vs Agent vs Command
|
||||
|
||||
| Component | Purpose | Activation |
|
||||
|-----------|---------|------------|
|
||||
| **Skill** | Knowledge repository | Context-based (automatic) |
|
||||
| **Agent** | Task executor | Explicit delegation |
|
||||
| **Command** | User action | User-invoked (`/command`) |
|
||||
| **Hook** | Automation | Event-triggered |
|
||||
| **Rule** | Always-on guidelines | Always active |
|
||||
|
||||
---
|
||||
|
||||
## Skill Architecture
|
||||
|
||||
### File Structure
|
||||
|
||||
```
|
||||
skills/
|
||||
└── your-skill-name/
|
||||
├── SKILL.md # Required: Main skill definition
|
||||
├── examples/ # Optional: Code examples
|
||||
│ ├── basic.ts
|
||||
│ └── advanced.ts
|
||||
└── references/ # Optional: External references
|
||||
└── links.md
|
||||
```
|
||||
|
||||
### SKILL.md Format
|
||||
|
||||
```markdown
|
||||
---
|
||||
name: skill-name
|
||||
description: Brief description shown in skill list and used for auto-activation
|
||||
origin: ECC
|
||||
---
|
||||
|
||||
# Skill Title
|
||||
|
||||
Brief overview of what this skill covers.
|
||||
|
||||
## When to Activate
|
||||
|
||||
Describe scenarios where Claude should use this skill.
|
||||
|
||||
## Core Concepts
|
||||
|
||||
Main patterns and guidelines.
|
||||
|
||||
## Code Examples
|
||||
|
||||
\`\`\`typescript
|
||||
// Practical, tested examples
|
||||
\`\`\`
|
||||
|
||||
## Anti-Patterns
|
||||
|
||||
Show what NOT to do with concrete examples.
|
||||
|
||||
## Best Practices
|
||||
|
||||
- Actionable guidelines
|
||||
- Do's and don'ts
|
||||
|
||||
## Related Skills
|
||||
|
||||
Link to complementary skills.
|
||||
```
|
||||
|
||||
### YAML Frontmatter Fields
|
||||
|
||||
| Field | Required | Description |
|
||||
|-------|----------|-------------|
|
||||
| `name` | Yes | Lowercase, hyphenated identifier (e.g., `react-patterns`) |
|
||||
| `description` | Yes | One-line description for skill list and auto-activation |
|
||||
| `origin` | No | Source identifier (e.g., `ECC`, `community`, project name) |
|
||||
| `tags` | No | Array of tags for categorization |
|
||||
| `version` | No | Skill version for tracking updates |
|
||||
|
||||
---
|
||||
|
||||
## Creating Your First Skill
|
||||
|
||||
### Step 1: Choose a Focus
|
||||
|
||||
Good skills are **focused and actionable**:
|
||||
|
||||
| PASS: Good Focus | FAIL: Too Broad |
|
||||
|---------------|--------------|
|
||||
| `react-hook-patterns` | `react` |
|
||||
| `postgresql-indexing` | `databases` |
|
||||
| `pytest-fixtures` | `python-testing` |
|
||||
| `nextjs-app-router` | `nextjs` |
|
||||
|
||||
### Step 2: Create the Directory
|
||||
|
||||
```bash
|
||||
mkdir -p skills/your-skill-name
|
||||
```
|
||||
|
||||
### Step 3: Write SKILL.md
|
||||
|
||||
Here's a minimal template:
|
||||
|
||||
```markdown
|
||||
---
|
||||
name: your-skill-name
|
||||
description: Brief description of when to use this skill
|
||||
---
|
||||
|
||||
# Your Skill Title
|
||||
|
||||
Brief overview (1-2 sentences).
|
||||
|
||||
## When to Activate
|
||||
|
||||
- Scenario 1
|
||||
- Scenario 2
|
||||
- Scenario 3
|
||||
|
||||
## Core Concepts
|
||||
|
||||
### Concept 1
|
||||
|
||||
Explanation with examples.
|
||||
|
||||
### Concept 2
|
||||
|
||||
Another pattern with code.
|
||||
|
||||
## Code Examples
|
||||
|
||||
\`\`\`typescript
|
||||
// Practical example
|
||||
\`\`\`
|
||||
|
||||
## Best Practices
|
||||
|
||||
- Do this
|
||||
- Avoid that
|
||||
|
||||
## Related Skills
|
||||
|
||||
- `related-skill-1`
|
||||
- `related-skill-2`
|
||||
```
|
||||
|
||||
### Step 4: Add Content
|
||||
|
||||
Write content that Claude can **immediately use**:
|
||||
|
||||
- PASS: Copy-pasteable code examples
|
||||
- PASS: Clear decision trees
|
||||
- PASS: Checklists for verification
|
||||
- FAIL: Vague explanations without examples
|
||||
- FAIL: Long prose without actionable guidance
|
||||
|
||||
---
|
||||
|
||||
## Skill Categories
|
||||
|
||||
### Language Standards
|
||||
|
||||
Focus on idiomatic code, naming conventions, and language-specific patterns.
|
||||
|
||||
**Examples:** `python-patterns`, `golang-patterns`, `typescript-standards`
|
||||
|
||||
```markdown
|
||||
---
|
||||
name: python-patterns
|
||||
description: Python idioms, best practices, and patterns for clean, idiomatic code.
|
||||
---
|
||||
|
||||
# Python Patterns
|
||||
|
||||
## When to Activate
|
||||
|
||||
- Writing Python code
|
||||
- Refactoring Python modules
|
||||
- Python code review
|
||||
|
||||
## Core Concepts
|
||||
|
||||
### Context Managers
|
||||
|
||||
\`\`\`python
|
||||
# Always use context managers for resources
|
||||
with open('file.txt') as f:
|
||||
content = f.read()
|
||||
\`\`\`
|
||||
```
|
||||
|
||||
### Framework Patterns
|
||||
|
||||
Focus on framework-specific conventions, common patterns, and anti-patterns.
|
||||
|
||||
**Examples:** `django-patterns`, `nextjs-patterns`, `springboot-patterns`
|
||||
|
||||
```markdown
|
||||
---
|
||||
name: django-patterns
|
||||
description: Django best practices for models, views, URLs, and templates.
|
||||
---
|
||||
|
||||
# Django Patterns
|
||||
|
||||
## When to Activate
|
||||
|
||||
- Building Django applications
|
||||
- Creating models and views
|
||||
- Django URL configuration
|
||||
```
|
||||
|
||||
### Workflow Skills
|
||||
|
||||
Define step-by-step processes for common development tasks.
|
||||
|
||||
**Examples:** `tdd-workflow`, `code-review-workflow`, `deployment-checklist`
|
||||
|
||||
```markdown
|
||||
---
|
||||
name: code-review-workflow
|
||||
description: Systematic code review process for quality and security.
|
||||
---
|
||||
|
||||
# Code Review Workflow
|
||||
|
||||
## Steps
|
||||
|
||||
1. **Understand Context** - Read PR description and linked issues
|
||||
2. **Check Tests** - Verify test coverage and quality
|
||||
3. **Review Logic** - Analyze implementation for correctness
|
||||
4. **Check Security** - Look for vulnerabilities
|
||||
5. **Verify Style** - Ensure code follows conventions
|
||||
```
|
||||
|
||||
### Domain Knowledge
|
||||
|
||||
Specialized knowledge for specific domains (security, performance, etc.).
|
||||
|
||||
**Examples:** `security-review`, `performance-optimization`, `api-design`
|
||||
|
||||
```markdown
|
||||
---
|
||||
name: api-design
|
||||
description: REST and GraphQL API design patterns, versioning, and best practices.
|
||||
---
|
||||
|
||||
# API Design Patterns
|
||||
|
||||
## RESTful Conventions
|
||||
|
||||
| Method | Endpoint | Purpose |
|
||||
|--------|----------|---------|
|
||||
| GET | /resources | List all |
|
||||
| GET | /resources/:id | Get one |
|
||||
| POST | /resources | Create |
|
||||
```
|
||||
|
||||
### Tool Integration
|
||||
|
||||
Guidance for using specific tools, libraries, or services.
|
||||
|
||||
**Examples:** `supabase-patterns`, `docker-patterns`, `mcp-server-patterns`
|
||||
|
||||
---
|
||||
|
||||
## Writing Effective Skill Content
|
||||
|
||||
### 1. Start with "When to Activate"
|
||||
|
||||
This section is **critical** for auto-activation. Be specific:
|
||||
|
||||
```markdown
|
||||
## When to Activate
|
||||
|
||||
- Creating new React components
|
||||
- Refactoring existing components
|
||||
- Debugging React state issues
|
||||
- Reviewing React code for best practices
|
||||
```
|
||||
|
||||
### 2. Use "Show, Don't Tell"
|
||||
|
||||
Bad:
|
||||
```markdown
|
||||
## Error Handling
|
||||
|
||||
Always handle errors properly in async functions.
|
||||
```
|
||||
|
||||
Good:
|
||||
```markdown
|
||||
## Error Handling
|
||||
|
||||
\`\`\`typescript
|
||||
async function fetchData(url: string) {
|
||||
try {
|
||||
const response = await fetch(url)
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(\`HTTP \${response.status}: \${response.statusText}\`)
|
||||
}
|
||||
|
||||
return await response.json()
|
||||
} catch (error) {
|
||||
console.error('Fetch failed:', error)
|
||||
throw new Error('Failed to fetch data')
|
||||
}
|
||||
}
|
||||
\`\`\`
|
||||
|
||||
### Key Points
|
||||
|
||||
- Check \`response.ok\` before parsing
|
||||
- Log errors for debugging
|
||||
- Re-throw with user-friendly message
|
||||
```
|
||||
|
||||
### 3. Include Anti-Patterns
|
||||
|
||||
Show what NOT to do:
|
||||
|
||||
```markdown
|
||||
## Anti-Patterns
|
||||
|
||||
### FAIL: Direct State Mutation
|
||||
|
||||
\`\`\`typescript
|
||||
// NEVER do this
|
||||
user.name = 'New Name'
|
||||
items.push(newItem)
|
||||
\`\`\`
|
||||
|
||||
### PASS: Immutable Updates
|
||||
|
||||
\`\`\`typescript
|
||||
// ALWAYS do this
|
||||
const updatedUser = { ...user, name: 'New Name' }
|
||||
const updatedItems = [...items, newItem]
|
||||
\`\`\`
|
||||
```
|
||||
|
||||
### 4. Provide Checklists
|
||||
|
||||
Checklists are actionable and easy to follow:
|
||||
|
||||
```markdown
|
||||
## Pre-Deployment Checklist
|
||||
|
||||
- [ ] All tests passing
|
||||
- [ ] No console.log in production code
|
||||
- [ ] Environment variables documented
|
||||
- [ ] Secrets not hardcoded
|
||||
- [ ] Error handling complete
|
||||
- [ ] Input validation in place
|
||||
```
|
||||
|
||||
### 5. Use Decision Trees
|
||||
|
||||
For complex decisions:
|
||||
|
||||
```markdown
|
||||
## Choosing the Right Approach
|
||||
|
||||
\`\`\`
|
||||
Need to fetch data?
|
||||
├── Single request → use fetch directly
|
||||
├── Multiple independent → Promise.all()
|
||||
├── Multiple dependent → await sequentially
|
||||
└── With caching → use SWR or React Query
|
||||
\`\`\`
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Best Practices
|
||||
|
||||
### DO
|
||||
|
||||
| Practice | Example |
|
||||
|----------|---------|
|
||||
| **Be specific** | "Use \`useCallback\` for event handlers passed to child components" |
|
||||
| **Show examples** | Include copy-pasteable code |
|
||||
| **Explain WHY** | "Immutability prevents unexpected side effects in React state" |
|
||||
| **Link related skills** | "See also: \`react-performance\`" |
|
||||
| **Keep focused** | One skill = one domain/concept |
|
||||
| **Use sections** | Clear headers for easy scanning |
|
||||
|
||||
### DON'T
|
||||
|
||||
| Practice | Why It's Bad |
|
||||
|----------|--------------|
|
||||
| **Be vague** | "Write good code" - not actionable |
|
||||
| **Long prose** | Hard to parse, better as code |
|
||||
| **Cover too much** | "Python, Django, and Flask patterns" - too broad |
|
||||
| **Skip examples** | Theory without practice is less useful |
|
||||
| **Ignore anti-patterns** | Learning what NOT to do is valuable |
|
||||
|
||||
### Content Guidelines
|
||||
|
||||
1. **Length**: 200-500 lines typical, 800 lines maximum
|
||||
2. **Code blocks**: Include language identifier
|
||||
3. **Headers**: Use `##` and `###` hierarchy
|
||||
4. **Lists**: Use `-` for unordered, `1.` for ordered
|
||||
5. **Tables**: For comparisons and references
|
||||
|
||||
---
|
||||
|
||||
## Common Patterns
|
||||
|
||||
### Pattern 1: Standards Skill
|
||||
|
||||
```markdown
|
||||
---
|
||||
name: language-standards
|
||||
description: Coding standards and best practices for [language].
|
||||
---
|
||||
|
||||
# [Language] Coding Standards
|
||||
|
||||
## When to Activate
|
||||
|
||||
- Writing [language] code
|
||||
- Code review
|
||||
- Setting up linting
|
||||
|
||||
## Naming Conventions
|
||||
|
||||
| Element | Convention | Example |
|
||||
|---------|------------|---------|
|
||||
| Variables | camelCase | userName |
|
||||
| Constants | SCREAMING_SNAKE | MAX_RETRY |
|
||||
| Functions | camelCase | fetchUser |
|
||||
| Classes | PascalCase | UserService |
|
||||
|
||||
## Code Examples
|
||||
|
||||
[Include practical examples]
|
||||
|
||||
## Linting Setup
|
||||
|
||||
[Include configuration]
|
||||
|
||||
## Related Skills
|
||||
|
||||
- `language-testing`
|
||||
- `language-security`
|
||||
```
|
||||
|
||||
### Pattern 2: Workflow Skill
|
||||
|
||||
```markdown
|
||||
---
|
||||
name: task-workflow
|
||||
description: Step-by-step workflow for [task].
|
||||
---
|
||||
|
||||
# [Task] Workflow
|
||||
|
||||
## When to Activate
|
||||
|
||||
- [Trigger 1]
|
||||
- [Trigger 2]
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- [Requirement 1]
|
||||
- [Requirement 2]
|
||||
|
||||
## Steps
|
||||
|
||||
### Step 1: [Name]
|
||||
|
||||
[Description]
|
||||
|
||||
\`\`\`bash
|
||||
[Commands]
|
||||
\`\`\`
|
||||
|
||||
### Step 2: [Name]
|
||||
|
||||
[Description]
|
||||
|
||||
## Verification
|
||||
|
||||
- [ ] [Check 1]
|
||||
- [ ] [Check 2]
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
| Problem | Solution |
|
||||
|---------|----------|
|
||||
| [Issue] | [Fix] |
|
||||
```
|
||||
|
||||
### Pattern 3: Reference Skill
|
||||
|
||||
```markdown
|
||||
---
|
||||
name: api-reference
|
||||
description: Quick reference for [API/Library].
|
||||
---
|
||||
|
||||
# [API/Library] Reference
|
||||
|
||||
## When to Activate
|
||||
|
||||
- Using [API/Library]
|
||||
- Looking up [API/Library] syntax
|
||||
|
||||
## Common Operations
|
||||
|
||||
### Operation 1
|
||||
|
||||
\`\`\`typescript
|
||||
// Basic usage
|
||||
\`\`\`
|
||||
|
||||
### Operation 2
|
||||
|
||||
\`\`\`typescript
|
||||
// Advanced usage
|
||||
\`\`\`
|
||||
|
||||
## Configuration
|
||||
|
||||
[Include config examples]
|
||||
|
||||
## Error Handling
|
||||
|
||||
[Include error patterns]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Testing Your Skill
|
||||
|
||||
### Local Testing
|
||||
|
||||
1. **Copy to Claude Code skills directory**:
|
||||
```bash
|
||||
cp -r skills/your-skill-name ~/.claude/skills/
|
||||
```
|
||||
|
||||
2. **Test with Claude Code**:
|
||||
```
|
||||
You: "I need to [task that should trigger your skill]"
|
||||
|
||||
Claude should reference your skill's patterns.
|
||||
```
|
||||
|
||||
3. **Verify activation**:
|
||||
- Ask Claude to explain a concept from your skill
|
||||
- Check if it uses your examples and patterns
|
||||
- Ensure it follows your guidelines
|
||||
|
||||
### Validation Checklist
|
||||
|
||||
- [ ] **YAML frontmatter valid** - No syntax errors
|
||||
- [ ] **Name follows convention** - lowercase-with-hyphens
|
||||
- [ ] **Description is clear** - Tells when to use
|
||||
- [ ] **Examples work** - Code compiles and runs
|
||||
- [ ] **Links valid** - Related skills exist
|
||||
- [ ] **No sensitive data** - No API keys, tokens, paths
|
||||
|
||||
### Code Example Testing
|
||||
|
||||
Test all code examples:
|
||||
|
||||
```bash
|
||||
# From the repo root
|
||||
npx tsc --noEmit skills/your-skill-name/examples/*.ts
|
||||
|
||||
# Or from inside the skill directory
|
||||
npx tsc --noEmit examples/*.ts
|
||||
|
||||
# From the repo root
|
||||
python -m py_compile skills/your-skill-name/examples/*.py
|
||||
|
||||
# Or from inside the skill directory
|
||||
python -m py_compile examples/*.py
|
||||
|
||||
# From the repo root
|
||||
go build ./skills/your-skill-name/examples/...
|
||||
|
||||
# Or from inside the skill directory
|
||||
go build ./examples/...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Submitting Your Skill
|
||||
|
||||
### 1. Fork and Clone
|
||||
|
||||
```bash
|
||||
gh repo fork affaan-m/everything-claude-code --clone
|
||||
cd everything-claude-code
|
||||
```
|
||||
|
||||
### 2. Create Branch
|
||||
|
||||
```bash
|
||||
git checkout -b feat/skill-your-skill-name
|
||||
```
|
||||
|
||||
### 3. Add Your Skill
|
||||
|
||||
```bash
|
||||
mkdir -p skills/your-skill-name
|
||||
# Create SKILL.md
|
||||
```
|
||||
|
||||
### 4. Validate
|
||||
|
||||
```bash
|
||||
# Check YAML frontmatter
|
||||
head -10 skills/your-skill-name/SKILL.md
|
||||
|
||||
# Verify structure
|
||||
ls -la skills/your-skill-name/
|
||||
|
||||
# Run tests if available
|
||||
npm test
|
||||
```
|
||||
|
||||
### 5. Commit and Push
|
||||
|
||||
```bash
|
||||
git add skills/your-skill-name/
|
||||
git commit -m "feat(skills): add your-skill-name skill"
|
||||
git push -u origin feat/skill-your-skill-name
|
||||
```
|
||||
|
||||
### 6. Create Pull Request
|
||||
|
||||
Use this PR template:
|
||||
|
||||
```markdown
|
||||
## Summary
|
||||
|
||||
Brief description of the skill and why it's valuable.
|
||||
|
||||
## Skill Type
|
||||
|
||||
- [ ] Language standards
|
||||
- [ ] Framework patterns
|
||||
- [ ] Workflow
|
||||
- [ ] Domain knowledge
|
||||
- [ ] Tool integration
|
||||
|
||||
## Testing
|
||||
|
||||
How I tested this skill locally.
|
||||
|
||||
## Checklist
|
||||
|
||||
- [ ] YAML frontmatter valid
|
||||
- [ ] Code examples tested
|
||||
- [ ] Follows skill guidelines
|
||||
- [ ] No sensitive data
|
||||
- [ ] Clear activation triggers
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Examples Gallery
|
||||
|
||||
### Example 1: Language Standards
|
||||
|
||||
**File:** `skills/rust-patterns/SKILL.md`
|
||||
|
||||
```markdown
|
||||
---
|
||||
name: rust-patterns
|
||||
description: Rust idioms, ownership patterns, and best practices for safe, idiomatic code.
|
||||
origin: ECC
|
||||
---
|
||||
|
||||
# Rust Patterns
|
||||
|
||||
## When to Activate
|
||||
|
||||
- Writing Rust code
|
||||
- Handling ownership and borrowing
|
||||
- Error handling with Result/Option
|
||||
- Implementing traits
|
||||
|
||||
## Ownership Patterns
|
||||
|
||||
### Borrowing Rules
|
||||
|
||||
\`\`\`rust
|
||||
// PASS: CORRECT: Borrow when you don't need ownership
|
||||
fn process_data(data: &str) -> usize {
|
||||
data.len()
|
||||
}
|
||||
|
||||
// PASS: CORRECT: Take ownership when you need to modify or consume
|
||||
fn consume_data(data: Vec<u8>) -> String {
|
||||
String::from_utf8(data).unwrap()
|
||||
}
|
||||
\`\`\`
|
||||
|
||||
## Error Handling
|
||||
|
||||
### Result Pattern
|
||||
|
||||
\`\`\`rust
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum AppError {
|
||||
#[error("IO error: {0}")]
|
||||
Io(#[from] std::io::Error),
|
||||
|
||||
#[error("Parse error: {0}")]
|
||||
Parse(#[from] std::num::ParseIntError),
|
||||
}
|
||||
|
||||
pub type AppResult<T> = Result<T, AppError>;
|
||||
\`\`\`
|
||||
|
||||
## Related Skills
|
||||
|
||||
- `rust-testing`
|
||||
- `rust-security`
|
||||
```
|
||||
|
||||
### Example 2: Framework Patterns
|
||||
|
||||
**File:** `skills/fastapi-patterns/SKILL.md`
|
||||
|
||||
```markdown
|
||||
---
|
||||
name: fastapi-patterns
|
||||
description: FastAPI patterns for routing, dependency injection, validation, and async operations.
|
||||
origin: ECC
|
||||
---
|
||||
|
||||
# FastAPI Patterns
|
||||
|
||||
## When to Activate
|
||||
|
||||
- Building FastAPI applications
|
||||
- Creating API endpoints
|
||||
- Implementing dependency injection
|
||||
- Handling async database operations
|
||||
|
||||
## Project Structure
|
||||
|
||||
\`\`\`
|
||||
app/
|
||||
├── main.py # FastAPI app entry point
|
||||
├── routers/ # Route handlers
|
||||
│ ├── users.py
|
||||
│ └── items.py
|
||||
├── models/ # Pydantic models
|
||||
│ ├── user.py
|
||||
│ └── item.py
|
||||
├── services/ # Business logic
|
||||
│ └── user_service.py
|
||||
└── dependencies.py # Shared dependencies
|
||||
\`\`\`
|
||||
|
||||
## Dependency Injection
|
||||
|
||||
\`\`\`python
|
||||
from fastapi import Depends
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
async def get_db() -> AsyncSession:
|
||||
async with AsyncSessionLocal() as session:
|
||||
yield session
|
||||
|
||||
@router.get("/users/{user_id}")
|
||||
async def get_user(
|
||||
user_id: int,
|
||||
db: AsyncSession = Depends(get_db)
|
||||
):
|
||||
# Use db session
|
||||
pass
|
||||
\`\`\`
|
||||
|
||||
## Related Skills
|
||||
|
||||
- `python-patterns`
|
||||
- `pydantic-validation`
|
||||
```
|
||||
|
||||
### Example 3: Workflow Skill
|
||||
|
||||
**File:** `skills/refactoring-workflow/SKILL.md`
|
||||
|
||||
```markdown
|
||||
---
|
||||
name: refactoring-workflow
|
||||
description: Systematic refactoring workflow for improving code quality without changing behavior.
|
||||
origin: ECC
|
||||
---
|
||||
|
||||
# Refactoring Workflow
|
||||
|
||||
## When to Activate
|
||||
|
||||
- Improving code structure
|
||||
- Reducing technical debt
|
||||
- Simplifying complex code
|
||||
- Extracting reusable components
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- All tests passing
|
||||
- Git working directory clean
|
||||
- Feature branch created
|
||||
|
||||
## Workflow Steps
|
||||
|
||||
### Step 1: Identify Refactoring Target
|
||||
|
||||
- Look for code smells (long methods, duplicate code, large classes)
|
||||
- Check test coverage for target area
|
||||
- Document current behavior
|
||||
|
||||
### Step 2: Ensure Tests Exist
|
||||
|
||||
\`\`\`bash
|
||||
# Run tests to verify current behavior
|
||||
npm test
|
||||
|
||||
# Check coverage for target files
|
||||
npm run test:coverage
|
||||
\`\`\`
|
||||
|
||||
### Step 3: Make Small Changes
|
||||
|
||||
- One refactoring at a time
|
||||
- Run tests after each change
|
||||
- Commit frequently
|
||||
|
||||
### Step 4: Verify Behavior Unchanged
|
||||
|
||||
\`\`\`bash
|
||||
# Run full test suite
|
||||
npm test
|
||||
|
||||
# Run E2E tests
|
||||
npm run test:e2e
|
||||
\`\`\`
|
||||
|
||||
## Common Refactorings
|
||||
|
||||
| Smell | Refactoring |
|
||||
|-------|-------------|
|
||||
| Long method | Extract method |
|
||||
| Duplicate code | Extract to shared function |
|
||||
| Large class | Extract class |
|
||||
| Long parameter list | Introduce parameter object |
|
||||
|
||||
## Checklist
|
||||
|
||||
- [ ] Tests exist for target code
|
||||
- [ ] Made small, focused changes
|
||||
- [ ] Tests pass after each change
|
||||
- [ ] Behavior unchanged
|
||||
- [ ] Committed with clear message
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Additional Resources
|
||||
|
||||
- [CONTRIBUTING.md](../CONTRIBUTING.md) - General contribution guidelines
|
||||
- [project-guidelines-example](../skills/project-guidelines-example/SKILL.md) - Project-specific skill template
|
||||
- [coding-standards](../skills/coding-standards/SKILL.md) - Example of standards skill
|
||||
- [tdd-workflow](../skills/tdd-workflow/SKILL.md) - Example of workflow skill
|
||||
- [security-review](../skills/security-review/SKILL.md) - Example of domain knowledge skill
|
||||
|
||||
---
|
||||
|
||||
**Remember**: A good skill is focused, actionable, and immediately useful. Write skills you'd want to use yourself.
|
||||
@@ -66,9 +66,9 @@ Use these as starting points in negotiation:
|
||||
|
||||
Use this on calls:
|
||||
|
||||
> ECC is now positioned as an agent harness performance system, not a config repo.
|
||||
> We track adoption through npm distribution, GitHub App installs, and repository growth.
|
||||
> Claude plugin installs are structurally undercounted publicly, so we use a blended metrics model.
|
||||
> ECC is now positioned as an agent harness performance system, not a config repo.
|
||||
> We track adoption through npm distribution, GitHub App installs, and repository growth.
|
||||
> Claude plugin installs are structurally undercounted publicly, so we use a blended metrics model.
|
||||
> The project supports Claude Code, Cursor, OpenCode, and Codex app/CLI with production-grade hook reliability and a large passing test suite.
|
||||
|
||||
For launch-ready social copy snippets, see [`social-launch-copy.md`](./social-launch-copy.md).
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
<div align="center">
|
||||
|
||||
**🌐 言語 / Language / 語言**
|
||||
**言語 / Language / 語言**
|
||||
|
||||
[**English**](README.md) | [简体中文](README.zh-CN.md) | [繁體中文](docs/zh-TW/README.md) | [日本語](docs/ja-JP/README.md)
|
||||
|
||||
@@ -99,7 +99,7 @@
|
||||
|
||||
---
|
||||
|
||||
## 🚀 クイックスタート
|
||||
## クイックスタート
|
||||
|
||||
2分以内に起動できます:
|
||||
|
||||
@@ -115,7 +115,7 @@
|
||||
|
||||
### ステップ2:ルールをインストール(必須)
|
||||
|
||||
> ⚠️ **重要:** Claude Codeプラグインは`rules`を自動配布できません。手動でインストールしてください:
|
||||
> WARNING: **重要:** Claude Codeプラグインは`rules`を自動配布できません。手動でインストールしてください:
|
||||
|
||||
```bash
|
||||
# まずリポジトリをクローン
|
||||
@@ -143,11 +143,11 @@ cp -r everything-claude-code/rules/golang/* ~/.claude/rules/
|
||||
/plugin list everything-claude-code@everything-claude-code
|
||||
```
|
||||
|
||||
✨ **完了です!** これで13のエージェント、43のスキル、31のコマンドにアクセスできます。
|
||||
**完了です!** これで13のエージェント、43のスキル、31のコマンドにアクセスできます。
|
||||
|
||||
---
|
||||
|
||||
## 🌐 クロスプラットフォーム対応
|
||||
## クロスプラットフォーム対応
|
||||
|
||||
このプラグインは **Windows、macOS、Linux** を完全にサポートしています。すべてのフックとスクリプトが Node.js で書き直され、最大の互換性を実現しています。
|
||||
|
||||
@@ -182,7 +182,7 @@ node scripts/setup-package-manager.js --detect
|
||||
|
||||
---
|
||||
|
||||
## 📦 含まれるもの
|
||||
## 含まれるもの
|
||||
|
||||
このリポジトリは**Claude Codeプラグイン**です - 直接インストールするか、コンポーネントを手動でコピーできます。
|
||||
|
||||
@@ -315,7 +315,7 @@ everything-claude-code/
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ エコシステムツール
|
||||
## エコシステムツール
|
||||
|
||||
### スキル作成ツール
|
||||
|
||||
@@ -374,7 +374,7 @@ Claude Codeで`/security-scan`を実行、または[GitHub Action](https://githu
|
||||
|
||||
[GitHub](https://github.com/affaan-m/agentshield) | [npm](https://www.npmjs.com/package/ecc-agentshield)
|
||||
|
||||
### 🧠 継続的学習 v2
|
||||
### 継続的学習 v2
|
||||
|
||||
instinctベースの学習システムがパターンを自動学習:
|
||||
|
||||
@@ -389,7 +389,7 @@ instinctベースの学習システムがパターンを自動学習:
|
||||
|
||||
---
|
||||
|
||||
## 📋 要件
|
||||
## 要件
|
||||
|
||||
### Claude Code CLI バージョン
|
||||
|
||||
@@ -404,19 +404,19 @@ claude --version
|
||||
|
||||
### 重要: フック自動読み込み動作
|
||||
|
||||
> ⚠️ **貢献者向け:** `.claude-plugin/plugin.json`に`"hooks"`フィールドを追加しないでください。これは回帰テストで強制されます。
|
||||
> WARNING: **貢献者向け:** `.claude-plugin/plugin.json`に`"hooks"`フィールドを追加しないでください。これは回帰テストで強制されます。
|
||||
|
||||
Claude Code v2.1+は、インストール済みプラグインの`hooks/hooks.json`(規約)を自動読み込みします。`plugin.json`で明示的に宣言するとエラーが発生します:
|
||||
|
||||
```
|
||||
Duplicate hooks file detected: ./hooks/hooks.json resolves to already-loaded file
|
||||
Duplicate hook file detected: ./hooks/hooks.json is already resolved to a loaded file
|
||||
```
|
||||
|
||||
**背景:** これは本リポジトリで複数の修正/リバート循環を引き起こしました([#29](https://github.com/affaan-m/everything-claude-code/issues/29), [#52](https://github.com/affaan-m/everything-claude-code/issues/52), [#103](https://github.com/affaan-m/everything-claude-code/issues/103))。Claude Codeバージョン間で動作が変わったため混乱がありました。今後を防ぐため回帰テストがあります。
|
||||
|
||||
---
|
||||
|
||||
## 📥 インストール
|
||||
## インストール
|
||||
|
||||
### オプション1:プラグインとしてインストール(推奨)
|
||||
|
||||
@@ -471,7 +471,7 @@ Duplicate hooks file detected: ./hooks/hooks.json resolves to already-loaded fil
|
||||
|
||||
---
|
||||
|
||||
### 🔧 オプション2:手動インストール
|
||||
### オプション2:手動インストール
|
||||
|
||||
インストール内容を手動で制御したい場合:
|
||||
|
||||
@@ -507,7 +507,7 @@ cp -r everything-claude-code/skills/* ~/.claude/skills/
|
||||
|
||||
---
|
||||
|
||||
## 🎯 主要概念
|
||||
## 主要概念
|
||||
|
||||
### エージェント
|
||||
|
||||
@@ -569,7 +569,7 @@ rules/
|
||||
|
||||
---
|
||||
|
||||
## 🧪 テストを実行
|
||||
## テストを実行
|
||||
|
||||
プラグインには包括的なテストスイートが含まれています:
|
||||
|
||||
@@ -585,7 +585,7 @@ node tests/hooks/hooks.test.js
|
||||
|
||||
---
|
||||
|
||||
## 🤝 貢献
|
||||
## 貢献
|
||||
|
||||
**貢献は大歓迎で、奨励されています。**
|
||||
|
||||
@@ -637,7 +637,7 @@ npm install ecc-universal
|
||||
|
||||
---
|
||||
|
||||
## 🔌 OpenCodeサポート
|
||||
## OpenCodeサポート
|
||||
|
||||
ECCは**フルOpenCodeサポート**をプラグインとフック含めて提供。
|
||||
|
||||
@@ -657,13 +657,13 @@ opencode
|
||||
|
||||
| 機能 | Claude Code | OpenCode | ステータス |
|
||||
|---------|-------------|----------|--------|
|
||||
| Agents | ✅ 14 エージェント | ✅ 12 エージェント | **Claude Code がリード** |
|
||||
| Commands | ✅ 30 コマンド | ✅ 24 コマンド | **Claude Code がリード** |
|
||||
| Skills | ✅ 28 スキル | ✅ 16 スキル | **Claude Code がリード** |
|
||||
| Hooks | ✅ 3 フェーズ | ✅ 20+ イベント | **OpenCode が多い!** |
|
||||
| Rules | ✅ 8 ルール | ✅ 8 ルール | **完全パリティ** |
|
||||
| MCP Servers | ✅ 完全 | ✅ 完全 | **完全パリティ** |
|
||||
| Custom Tools | ✅ フック経由 | ✅ ネイティブサポート | **OpenCode がより良い** |
|
||||
| Agents | PASS: 14 エージェント | PASS: 12 エージェント | **Claude Code がリード** |
|
||||
| Commands | PASS: 30 コマンド | PASS: 24 コマンド | **Claude Code がリード** |
|
||||
| Skills | PASS: 28 スキル | PASS: 16 スキル | **Claude Code がリード** |
|
||||
| Hooks | PASS: 3 フェーズ | PASS: 20+ イベント | **OpenCode が多い!** |
|
||||
| Rules | PASS: 8 ルール | PASS: 8 ルール | **完全パリティ** |
|
||||
| MCP Servers | PASS: 完全 | PASS: 完全 | **完全パリティ** |
|
||||
| Custom Tools | PASS: フック経由 | PASS: ネイティブサポート | **OpenCode がより良い** |
|
||||
|
||||
### プラグイン経由のフックサポート
|
||||
|
||||
@@ -737,7 +737,7 @@ npm install ecc-universal
|
||||
|
||||
---
|
||||
|
||||
## 📖 背景
|
||||
## 背景
|
||||
|
||||
実験的なリリース以来、Claude Codeを使用してきました。2025年9月、[@DRodriguezFX](https://x.com/DRodriguezFX)と一緒にClaude Codeで[zenith.chat](https://zenith.chat)を構築し、Anthropic x Forum Venturesハッカソンで優勝しました。
|
||||
|
||||
@@ -745,7 +745,7 @@ npm install ecc-universal
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ 重要な注記
|
||||
## WARNING: 重要な注記
|
||||
|
||||
### コンテキストウィンドウ管理
|
||||
|
||||
@@ -768,13 +768,13 @@ npm install ecc-universal
|
||||
|
||||
---
|
||||
|
||||
## 🌟 Star 履歴
|
||||
## Star 履歴
|
||||
|
||||
[](https://star-history.com/#affaan-m/everything-claude-code&Date)
|
||||
|
||||
---
|
||||
|
||||
## 🔗 リンク
|
||||
## リンク
|
||||
|
||||
- **簡潔ガイド(まずはこれ):** [Everything Claude Code 簡潔ガイド](https://x.com/affaanmustafa/status/2012378465664745795)
|
||||
- **詳細ガイド(高度):** [Everything Claude Code 詳細ガイド](https://x.com/affaanmustafa/status/2014040193557471352)
|
||||
@@ -784,7 +784,7 @@ npm install ecc-universal
|
||||
|
||||
---
|
||||
|
||||
## 📄 ライセンス
|
||||
## ライセンス
|
||||
|
||||
MIT - 自由に使用、必要に応じて修正、可能であれば貢献してください。
|
||||
|
||||
|
||||
@@ -103,12 +103,12 @@ c) 影響度別に優先順位付け
|
||||
|
||||
**パターン 1: 型推論の失敗**
|
||||
```typescript
|
||||
// ❌ エラー: Parameter 'x' implicitly has an 'any' type
|
||||
// FAIL: エラー: Parameter 'x' implicitly has an 'any' type
|
||||
function add(x, y) {
|
||||
return x + y
|
||||
}
|
||||
|
||||
// ✅ 修正: 型アノテーションを追加
|
||||
// PASS: 修正: 型アノテーションを追加
|
||||
function add(x: number, y: number): number {
|
||||
return x + y
|
||||
}
|
||||
@@ -116,25 +116,25 @@ function add(x: number, y: number): number {
|
||||
|
||||
**パターン 2: Null/Undefinedエラー**
|
||||
```typescript
|
||||
// ❌ エラー: Object is possibly 'undefined'
|
||||
// FAIL: エラー: Object is possibly 'undefined'
|
||||
const name = user.name.toUpperCase()
|
||||
|
||||
// ✅ 修正: オプショナルチェーン
|
||||
// PASS: 修正: オプショナルチェーン
|
||||
const name = user?.name?.toUpperCase()
|
||||
|
||||
// ✅ または: Nullチェック
|
||||
// PASS: または: Nullチェック
|
||||
const name = user && user.name ? user.name.toUpperCase() : ''
|
||||
```
|
||||
|
||||
**パターン 3: プロパティの欠落**
|
||||
```typescript
|
||||
// ❌ エラー: Property 'age' does not exist on type 'User'
|
||||
// FAIL: エラー: Property 'age' does not exist on type 'User'
|
||||
interface User {
|
||||
name: string
|
||||
}
|
||||
const user: User = { name: 'John', age: 30 }
|
||||
|
||||
// ✅ 修正: インターフェースにプロパティを追加
|
||||
// PASS: 修正: インターフェースにプロパティを追加
|
||||
interface User {
|
||||
name: string
|
||||
age?: number // 常に存在しない場合はオプショナル
|
||||
@@ -143,10 +143,10 @@ interface User {
|
||||
|
||||
**パターン 4: インポートエラー**
|
||||
```typescript
|
||||
// ❌ エラー: Cannot find module '@/lib/utils'
|
||||
// FAIL: エラー: Cannot find module '@/lib/utils'
|
||||
import { formatDate } from '@/lib/utils'
|
||||
|
||||
// ✅ 修正1: tsconfigのパスが正しいか確認
|
||||
// PASS: 修正1: tsconfigのパスが正しいか確認
|
||||
{
|
||||
"compilerOptions": {
|
||||
"paths": {
|
||||
@@ -155,38 +155,38 @@ import { formatDate } from '@/lib/utils'
|
||||
}
|
||||
}
|
||||
|
||||
// ✅ 修正2: 相対インポートを使用
|
||||
// PASS: 修正2: 相対インポートを使用
|
||||
import { formatDate } from '../lib/utils'
|
||||
|
||||
// ✅ 修正3: 欠落しているパッケージをインストール
|
||||
// PASS: 修正3: 欠落しているパッケージをインストール
|
||||
npm install @/lib/utils
|
||||
```
|
||||
|
||||
**パターン 5: 型の不一致**
|
||||
```typescript
|
||||
// ❌ エラー: Type 'string' is not assignable to type 'number'
|
||||
// FAIL: エラー: Type 'string' is not assignable to type 'number'
|
||||
const age: number = "30"
|
||||
|
||||
// ✅ 修正: 文字列を数値にパース
|
||||
// PASS: 修正: 文字列を数値にパース
|
||||
const age: number = parseInt("30", 10)
|
||||
|
||||
// ✅ または: 型を変更
|
||||
// PASS: または: 型を変更
|
||||
const age: string = "30"
|
||||
```
|
||||
|
||||
**パターン 6: ジェネリック制約**
|
||||
```typescript
|
||||
// ❌ エラー: Type 'T' is not assignable to type 'string'
|
||||
// FAIL: エラー: Type 'T' is not assignable to type 'string'
|
||||
function getLength<T>(item: T): number {
|
||||
return item.length
|
||||
}
|
||||
|
||||
// ✅ 修正: 制約を追加
|
||||
// PASS: 修正: 制約を追加
|
||||
function getLength<T extends { length: number }>(item: T): number {
|
||||
return item.length
|
||||
}
|
||||
|
||||
// ✅ または: より具体的な制約
|
||||
// PASS: または: より具体的な制約
|
||||
function getLength<T extends string | any[]>(item: T): number {
|
||||
return item.length
|
||||
}
|
||||
@@ -194,14 +194,14 @@ function getLength<T extends string | any[]>(item: T): number {
|
||||
|
||||
**パターン 7: React Hookエラー**
|
||||
```typescript
|
||||
// ❌ エラー: React Hook "useState" cannot be called in a function
|
||||
// FAIL: エラー: React Hook "useState" cannot be called in a function
|
||||
function MyComponent() {
|
||||
if (condition) {
|
||||
const [state, setState] = useState(0) // エラー!
|
||||
}
|
||||
}
|
||||
|
||||
// ✅ 修正: フックをトップレベルに移動
|
||||
// PASS: 修正: フックをトップレベルに移動
|
||||
function MyComponent() {
|
||||
const [state, setState] = useState(0)
|
||||
|
||||
@@ -215,12 +215,12 @@ function MyComponent() {
|
||||
|
||||
**パターン 8: Async/Awaitエラー**
|
||||
```typescript
|
||||
// ❌ エラー: 'await' expressions are only allowed within async functions
|
||||
// FAIL: エラー: 'await' expressions are only allowed within async functions
|
||||
function fetchData() {
|
||||
const data = await fetch('/api/data')
|
||||
}
|
||||
|
||||
// ✅ 修正: asyncキーワードを追加
|
||||
// PASS: 修正: asyncキーワードを追加
|
||||
async function fetchData() {
|
||||
const data = await fetch('/api/data')
|
||||
}
|
||||
@@ -228,14 +228,14 @@ async function fetchData() {
|
||||
|
||||
**パターン 9: モジュールが見つからない**
|
||||
```typescript
|
||||
// ❌ エラー: Cannot find module 'react' or its corresponding type declarations
|
||||
// FAIL: エラー: Cannot find module 'react' or its corresponding type declarations
|
||||
import React from 'react'
|
||||
|
||||
// ✅ 修正: 依存関係をインストール
|
||||
// PASS: 修正: 依存関係をインストール
|
||||
npm install react
|
||||
npm install --save-dev @types/react
|
||||
|
||||
// ✅ 確認: package.jsonに依存関係があることを確認
|
||||
// PASS: 確認: package.jsonに依存関係があることを確認
|
||||
{
|
||||
"dependencies": {
|
||||
"react": "^19.0.0"
|
||||
@@ -248,18 +248,18 @@ npm install --save-dev @types/react
|
||||
|
||||
**パターン 10: Next.js固有のエラー**
|
||||
```typescript
|
||||
// ❌ エラー: Fast Refresh had to perform a full reload
|
||||
// FAIL: エラー: Fast Refresh had to perform a full reload
|
||||
// 通常、コンポーネント以外のエクスポートが原因
|
||||
|
||||
// ✅ 修正: エクスポートを分離
|
||||
// ❌ 間違い: file.tsx
|
||||
// PASS: 修正: エクスポートを分離
|
||||
// FAIL: 間違い: file.tsx
|
||||
export const MyComponent = () => <div />
|
||||
export const someConstant = 42 // フルリロードの原因
|
||||
|
||||
// ✅ 正しい: component.tsx
|
||||
// PASS: 正しい: component.tsx
|
||||
export const MyComponent = () => <div />
|
||||
|
||||
// ✅ 正しい: constants.ts
|
||||
// PASS: 正しい: constants.ts
|
||||
export const someConstant = 42
|
||||
```
|
||||
|
||||
@@ -267,7 +267,7 @@ export const someConstant = 42
|
||||
|
||||
### Next.js 15 + React 19の互換性
|
||||
```typescript
|
||||
// ❌ エラー: React 19の型変更
|
||||
// FAIL: エラー: React 19の型変更
|
||||
import { FC } from 'react'
|
||||
|
||||
interface Props {
|
||||
@@ -278,7 +278,7 @@ const Component: FC<Props> = ({ children }) => {
|
||||
return <div>{children}</div>
|
||||
}
|
||||
|
||||
// ✅ 修正: React 19ではFCは不要
|
||||
// PASS: 修正: React 19ではFCは不要
|
||||
interface Props {
|
||||
children: React.ReactNode
|
||||
}
|
||||
@@ -290,12 +290,12 @@ const Component = ({ children }: Props) => {
|
||||
|
||||
### Supabaseクライアントの型
|
||||
```typescript
|
||||
// ❌ エラー: Type 'any' not assignable
|
||||
// FAIL: エラー: Type 'any' not assignable
|
||||
const { data } = await supabase
|
||||
.from('markets')
|
||||
.select('*')
|
||||
|
||||
// ✅ 修正: 型アノテーションを追加
|
||||
// PASS: 修正: 型アノテーションを追加
|
||||
interface Market {
|
||||
id: string
|
||||
name: string
|
||||
@@ -310,10 +310,10 @@ const { data } = await supabase
|
||||
|
||||
### Redis Stackの型
|
||||
```typescript
|
||||
// ❌ エラー: Property 'ft' does not exist on type 'RedisClientType'
|
||||
// FAIL: エラー: Property 'ft' does not exist on type 'RedisClientType'
|
||||
const results = await client.ft.search('idx:markets', query)
|
||||
|
||||
// ✅ 修正: 適切なRedis Stackの型を使用
|
||||
// PASS: 修正: 適切なRedis Stackの型を使用
|
||||
import { createClient } from 'redis'
|
||||
|
||||
const client = createClient({
|
||||
@@ -328,10 +328,10 @@ const results = await client.ft.search('idx:markets', query)
|
||||
|
||||
### Solana Web3.jsの型
|
||||
```typescript
|
||||
// ❌ エラー: Argument of type 'string' not assignable to 'PublicKey'
|
||||
// FAIL: エラー: Argument of type 'string' not assignable to 'PublicKey'
|
||||
const publicKey = wallet.address
|
||||
|
||||
// ✅ 修正: PublicKeyコンストラクタを使用
|
||||
// PASS: 修正: PublicKeyコンストラクタを使用
|
||||
import { PublicKey } from '@solana/web3.js'
|
||||
const publicKey = new PublicKey(wallet.address)
|
||||
```
|
||||
@@ -341,34 +341,34 @@ const publicKey = new PublicKey(wallet.address)
|
||||
**重要: できる限り最小限の変更を行う**
|
||||
|
||||
### すべきこと:
|
||||
✅ 欠落している型アノテーションを追加
|
||||
✅ 必要な箇所にnullチェックを追加
|
||||
✅ インポート/エクスポートを修正
|
||||
✅ 欠落している依存関係を追加
|
||||
✅ 型定義を更新
|
||||
✅ 設定ファイルを修正
|
||||
PASS: 欠落している型アノテーションを追加
|
||||
PASS: 必要な箇所にnullチェックを追加
|
||||
PASS: インポート/エクスポートを修正
|
||||
PASS: 欠落している依存関係を追加
|
||||
PASS: 型定義を更新
|
||||
PASS: 設定ファイルを修正
|
||||
|
||||
### してはいけないこと:
|
||||
❌ 関連のないコードをリファクタリング
|
||||
❌ アーキテクチャを変更
|
||||
❌ 変数/関数の名前を変更(エラーの原因でない限り)
|
||||
❌ 新機能を追加
|
||||
❌ ロジックフローを変更(エラー修正以外)
|
||||
❌ パフォーマンスを最適化
|
||||
❌ コードスタイルを改善
|
||||
FAIL: 関連のないコードをリファクタリング
|
||||
FAIL: アーキテクチャを変更
|
||||
FAIL: 変数/関数の名前を変更(エラーの原因でない限り)
|
||||
FAIL: 新機能を追加
|
||||
FAIL: ロジックフローを変更(エラー修正以外)
|
||||
FAIL: パフォーマンスを最適化
|
||||
FAIL: コードスタイルを改善
|
||||
|
||||
**最小差分の例:**
|
||||
|
||||
```typescript
|
||||
// ファイルは200行あり、45行目にエラーがある
|
||||
|
||||
// ❌ 間違い: ファイル全体をリファクタリング
|
||||
// FAIL: 間違い: ファイル全体をリファクタリング
|
||||
// - 変数の名前変更
|
||||
// - 関数の抽出
|
||||
// - パターンの変更
|
||||
// 結果: 50行変更
|
||||
|
||||
// ✅ 正しい: エラーのみを修正
|
||||
// PASS: 正しい: エラーのみを修正
|
||||
// - 45行目に型アノテーションを追加
|
||||
// 結果: 1行変更
|
||||
|
||||
@@ -376,12 +376,12 @@ function processData(data) { // 45行目 - エラー: 'data' implicitly has 'any
|
||||
return data.map(item => item.value)
|
||||
}
|
||||
|
||||
// ✅ 最小限の修正:
|
||||
// PASS: 最小限の修正:
|
||||
function processData(data: any[]) { // この行のみを変更
|
||||
return data.map(item => item.value)
|
||||
}
|
||||
|
||||
// ✅ より良い最小限の修正(型が既知の場合):
|
||||
// PASS: より良い最小限の修正(型が既知の場合):
|
||||
function processData(data: Array<{ value: number }>) {
|
||||
return data.map(item => item.value)
|
||||
}
|
||||
@@ -396,7 +396,7 @@ function processData(data: Array<{ value: number }>) {
|
||||
**ビルド対象:** Next.jsプロダクション / TypeScriptチェック / ESLint
|
||||
**初期エラー数:** X
|
||||
**修正済みエラー数:** Y
|
||||
**ビルドステータス:** ✅ 成功 / ❌ 失敗
|
||||
**ビルドステータス:** PASS: 成功 / FAIL: 失敗
|
||||
|
||||
## 修正済みエラー
|
||||
|
||||
@@ -430,17 +430,17 @@ Parameter 'market' implicitly has an 'any' type.
|
||||
|
||||
## 検証手順
|
||||
|
||||
1. ✅ TypeScriptチェック成功: `npx tsc --noEmit`
|
||||
2. ✅ Next.jsビルド成功: `npm run build`
|
||||
3. ✅ ESLintチェック成功: `npx eslint .`
|
||||
4. ✅ 新しいエラーが導入されていない
|
||||
5. ✅ 開発サーバー起動: `npm run dev`
|
||||
1. PASS: TypeScriptチェック成功: `npx tsc --noEmit`
|
||||
2. PASS: Next.jsビルド成功: `npm run build`
|
||||
3. PASS: ESLintチェック成功: `npx eslint .`
|
||||
4. PASS: 新しいエラーが導入されていない
|
||||
5. PASS: 開発サーバー起動: `npm run dev`
|
||||
|
||||
## まとめ
|
||||
|
||||
- 解決されたエラー総数: X
|
||||
- 変更行数総数: Y
|
||||
- ビルドステータス: ✅ 成功
|
||||
- ビルドステータス: PASS: 成功
|
||||
- 修正時間: Z 分
|
||||
- ブロッキング問題: 0 件残存
|
||||
|
||||
@@ -470,19 +470,19 @@ Parameter 'market' implicitly has an 'any' type.
|
||||
|
||||
## ビルドエラーの優先度レベル
|
||||
|
||||
### 🔴 クリティカル(即座に修正)
|
||||
### クリティカル(即座に修正)
|
||||
- ビルドが完全に壊れている
|
||||
- 開発サーバーが起動しない
|
||||
- プロダクションデプロイがブロックされている
|
||||
- 複数のファイルが失敗している
|
||||
|
||||
### 🟡 高(早急に修正)
|
||||
### 高(早急に修正)
|
||||
- 単一ファイルの失敗
|
||||
- 新しいコードの型エラー
|
||||
- インポートエラー
|
||||
- 重要でないビルド警告
|
||||
|
||||
### 🟢 中(可能な時に修正)
|
||||
### 中(可能な時に修正)
|
||||
- リンター警告
|
||||
- 非推奨APIの使用
|
||||
- 非厳格な型の問題
|
||||
@@ -521,13 +521,13 @@ npm install
|
||||
## 成功指標
|
||||
|
||||
ビルドエラー解決後:
|
||||
- ✅ `npx tsc --noEmit` が終了コード0で終了
|
||||
- ✅ `npm run build` が正常に完了
|
||||
- ✅ 新しいエラーが導入されていない
|
||||
- ✅ 最小限の行数変更(影響を受けたファイルの5%未満)
|
||||
- ✅ ビルド時間が大幅に増加していない
|
||||
- ✅ 開発サーバーがエラーなく動作
|
||||
- ✅ テストが依然として成功
|
||||
- PASS: `npx tsc --noEmit` が終了コード0で終了
|
||||
- PASS: `npm run build` が正常に完了
|
||||
- PASS: 新しいエラーが導入されていない
|
||||
- PASS: 最小限の行数変更(影響を受けたファイルの5%未満)
|
||||
- PASS: ビルド時間が大幅に増加していない
|
||||
- PASS: 開発サーバーがエラーなく動作
|
||||
- PASS: テストが依然として成功
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -77,19 +77,19 @@ model: opus
|
||||
各問題について:
|
||||
```
|
||||
[CRITICAL] ハードコードされたAPIキー
|
||||
File: src/api/client.ts:42
|
||||
Issue: APIキーがソースコードに公開されている
|
||||
Fix: 環境変数に移動
|
||||
ファイル: src/api/client.ts:42
|
||||
問題: APIキーがソースコードに公開されている
|
||||
修正: 環境変数に移動
|
||||
|
||||
const apiKey = "sk-abc123"; // ❌ Bad
|
||||
const apiKey = "sk-abc123"; // FAIL: Bad
|
||||
const apiKey = process.env.API_KEY; // ✓ Good
|
||||
```
|
||||
|
||||
## 承認基準
|
||||
|
||||
- ✅ 承認: CRITICALまたはHIGH問題なし
|
||||
- ⚠️ 警告: MEDIUM問題のみ(注意してマージ可能)
|
||||
- ❌ ブロック: CRITICALまたはHIGH問題が見つかった
|
||||
- PASS: 承認: CRITICALまたはHIGH問題なし
|
||||
- WARNING: 警告: MEDIUM問題のみ(注意してマージ可能)
|
||||
- FAIL: ブロック: CRITICALまたはHIGH問題が見つかった
|
||||
|
||||
## プロジェクト固有のガイドライン(例)
|
||||
|
||||
|
||||
@@ -112,14 +112,14 @@ c) データ保護
|
||||
**影響:** 大きなテーブルで100〜1000倍高速なクエリ
|
||||
|
||||
```sql
|
||||
-- ❌ 悪い: 外部キーにインデックスがない
|
||||
-- FAIL: 悪い: 外部キーにインデックスがない
|
||||
CREATE TABLE orders (
|
||||
id bigint PRIMARY KEY,
|
||||
customer_id bigint REFERENCES customers(id)
|
||||
-- インデックスが欠落!
|
||||
);
|
||||
|
||||
-- ✅ 良い: 外部キーにインデックス
|
||||
-- PASS: 良い: 外部キーにインデックス
|
||||
CREATE TABLE orders (
|
||||
id bigint PRIMARY KEY,
|
||||
customer_id bigint REFERENCES customers(id)
|
||||
@@ -137,11 +137,11 @@ CREATE INDEX orders_customer_id_idx ON orders (customer_id);
|
||||
| **Hash** | 等価のみ | `=`(B-treeより若干高速) |
|
||||
|
||||
```sql
|
||||
-- ❌ 悪い: JSONB包含のためのB-tree
|
||||
-- FAIL: 悪い: JSONB包含のためのB-tree
|
||||
CREATE INDEX products_attrs_idx ON products (attributes);
|
||||
SELECT * FROM products WHERE attributes @> '{"color": "red"}';
|
||||
|
||||
-- ✅ 良い: JSONBのためのGIN
|
||||
-- PASS: 良い: JSONBのためのGIN
|
||||
CREATE INDEX products_attrs_idx ON products USING gin (attributes);
|
||||
```
|
||||
|
||||
@@ -150,11 +150,11 @@ CREATE INDEX products_attrs_idx ON products USING gin (attributes);
|
||||
**影響:** 複数列クエリで5〜10倍高速
|
||||
|
||||
```sql
|
||||
-- ❌ 悪い: 個別のインデックス
|
||||
-- FAIL: 悪い: 個別のインデックス
|
||||
CREATE INDEX orders_status_idx ON orders (status);
|
||||
CREATE INDEX orders_created_idx ON orders (created_at);
|
||||
|
||||
-- ✅ 良い: 複合インデックス(等価列を最初に、次に範囲)
|
||||
-- PASS: 良い: 複合インデックス(等価列を最初に、次に範囲)
|
||||
CREATE INDEX orders_status_created_idx ON orders (status, created_at);
|
||||
```
|
||||
|
||||
@@ -170,11 +170,11 @@ CREATE INDEX orders_status_created_idx ON orders (status, created_at);
|
||||
**影響:** テーブルルックアップを回避することで2〜5倍高速なクエリ
|
||||
|
||||
```sql
|
||||
-- ❌ 悪い: テーブルからnameを取得する必要がある
|
||||
-- FAIL: 悪い: テーブルからnameを取得する必要がある
|
||||
CREATE INDEX users_email_idx ON users (email);
|
||||
SELECT email, name FROM users WHERE email = 'user@example.com';
|
||||
|
||||
-- ✅ 良い: すべての列がインデックスに含まれる
|
||||
-- PASS: 良い: すべての列がインデックスに含まれる
|
||||
CREATE INDEX users_email_idx ON users (email) INCLUDE (name, created_at);
|
||||
```
|
||||
|
||||
@@ -183,10 +183,10 @@ CREATE INDEX users_email_idx ON users (email) INCLUDE (name, created_at);
|
||||
**影響:** 5〜20倍小さいインデックス、高速な書き込みとクエリ
|
||||
|
||||
```sql
|
||||
-- ❌ 悪い: 完全なインデックスには削除された行が含まれる
|
||||
-- FAIL: 悪い: 完全なインデックスには削除された行が含まれる
|
||||
CREATE INDEX users_email_idx ON users (email);
|
||||
|
||||
-- ✅ 良い: 部分インデックスは削除された行を除外
|
||||
-- PASS: 良い: 部分インデックスは削除された行を除外
|
||||
CREATE INDEX users_active_email_idx ON users (email) WHERE deleted_at IS NULL;
|
||||
```
|
||||
|
||||
@@ -202,7 +202,7 @@ CREATE INDEX users_active_email_idx ON users (email) WHERE deleted_at IS NULL;
|
||||
### 1. データ型の選択
|
||||
|
||||
```sql
|
||||
-- ❌ 悪い: 不適切な型選択
|
||||
-- FAIL: 悪い: 不適切な型選択
|
||||
CREATE TABLE users (
|
||||
id int, -- 21億でオーバーフロー
|
||||
email varchar(255), -- 人為的な制限
|
||||
@@ -211,7 +211,7 @@ CREATE TABLE users (
|
||||
balance float -- 精度の損失
|
||||
);
|
||||
|
||||
-- ✅ 良い: 適切な型
|
||||
-- PASS: 良い: 適切な型
|
||||
CREATE TABLE users (
|
||||
id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||||
email text NOT NULL,
|
||||
@@ -224,18 +224,18 @@ CREATE TABLE users (
|
||||
### 2. 主キー戦略
|
||||
|
||||
```sql
|
||||
-- ✅ 単一データベース: IDENTITY(デフォルト、推奨)
|
||||
-- PASS: 単一データベース: IDENTITY(デフォルト、推奨)
|
||||
CREATE TABLE users (
|
||||
id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY
|
||||
);
|
||||
|
||||
-- ✅ 分散システム: UUIDv7(時間順)
|
||||
-- PASS: 分散システム: UUIDv7(時間順)
|
||||
CREATE EXTENSION IF NOT EXISTS pg_uuidv7;
|
||||
CREATE TABLE orders (
|
||||
id uuid DEFAULT uuid_generate_v7() PRIMARY KEY
|
||||
);
|
||||
|
||||
-- ❌ 避ける: ランダムUUIDはインデックスの断片化を引き起こす
|
||||
-- FAIL: 避ける: ランダムUUIDはインデックスの断片化を引き起こす
|
||||
CREATE TABLE events (
|
||||
id uuid DEFAULT gen_random_uuid() PRIMARY KEY -- 断片化した挿入!
|
||||
);
|
||||
@@ -246,7 +246,7 @@ CREATE TABLE events (
|
||||
**使用する場合:** テーブル > 1億行、時系列データ、古いデータを削除する必要がある
|
||||
|
||||
```sql
|
||||
-- ✅ 良い: 月ごとにパーティション化
|
||||
-- PASS: 良い: 月ごとにパーティション化
|
||||
CREATE TABLE events (
|
||||
id bigint GENERATED ALWAYS AS IDENTITY,
|
||||
created_at timestamptz NOT NULL,
|
||||
@@ -266,11 +266,11 @@ DROP TABLE events_2023_01; -- 数時間かかるDELETEではなく即座に
|
||||
### 4. 小文字の識別子を使用
|
||||
|
||||
```sql
|
||||
-- ❌ 悪い: 引用符付きの混合ケースは至る所で引用符が必要
|
||||
-- FAIL: 悪い: 引用符付きの混合ケースは至る所で引用符が必要
|
||||
CREATE TABLE "Users" ("userId" bigint, "firstName" text);
|
||||
SELECT "firstName" FROM "Users"; -- 引用符が必須!
|
||||
|
||||
-- ✅ 良い: 小文字は引用符なしで機能
|
||||
-- PASS: 良い: 小文字は引用符なしで機能
|
||||
CREATE TABLE users (user_id bigint, first_name text);
|
||||
SELECT first_name FROM users;
|
||||
```
|
||||
@@ -284,11 +284,11 @@ SELECT first_name FROM users;
|
||||
**影響:** 重要 - データベースで強制されるテナント分離
|
||||
|
||||
```sql
|
||||
-- ❌ 悪い: アプリケーションのみのフィルタリング
|
||||
-- FAIL: 悪い: アプリケーションのみのフィルタリング
|
||||
SELECT * FROM orders WHERE user_id = $current_user_id;
|
||||
-- バグはすべての注文が露出することを意味する!
|
||||
|
||||
-- ✅ 良い: データベースで強制されるRLS
|
||||
-- PASS: 良い: データベースで強制されるRLS
|
||||
ALTER TABLE orders ENABLE ROW LEVEL SECURITY;
|
||||
ALTER TABLE orders FORCE ROW LEVEL SECURITY;
|
||||
|
||||
@@ -308,11 +308,11 @@ CREATE POLICY orders_user_policy ON orders
|
||||
**影響:** 5〜10倍高速なRLSクエリ
|
||||
|
||||
```sql
|
||||
-- ❌ 悪い: 関数が行ごとに呼び出される
|
||||
-- FAIL: 悪い: 関数が行ごとに呼び出される
|
||||
CREATE POLICY orders_policy ON orders
|
||||
USING (auth.uid() = user_id); -- 100万行に対して100万回呼び出される!
|
||||
|
||||
-- ✅ 良い: SELECTでラップ(キャッシュされ、一度だけ呼び出される)
|
||||
-- PASS: 良い: SELECTでラップ(キャッシュされ、一度だけ呼び出される)
|
||||
CREATE POLICY orders_policy ON orders
|
||||
USING ((SELECT auth.uid()) = user_id); -- 100倍高速
|
||||
|
||||
@@ -323,10 +323,10 @@ CREATE INDEX orders_user_id_idx ON orders (user_id);
|
||||
### 3. 最小権限アクセス
|
||||
|
||||
```sql
|
||||
-- ❌ 悪い: 過度に許可的
|
||||
-- FAIL: 悪い: 過度に許可的
|
||||
GRANT ALL PRIVILEGES ON ALL TABLES TO app_user;
|
||||
|
||||
-- ✅ 良い: 最小限の権限
|
||||
-- PASS: 良い: 最小限の権限
|
||||
CREATE ROLE app_readonly NOLOGIN;
|
||||
GRANT USAGE ON SCHEMA public TO app_readonly;
|
||||
GRANT SELECT ON public.products, public.categories TO app_readonly;
|
||||
@@ -378,14 +378,14 @@ SELECT pg_reload_conf();
|
||||
### 1. トランザクションを短く保つ
|
||||
|
||||
```sql
|
||||
-- ❌ 悪い: 外部APIコール中にロックを保持
|
||||
-- FAIL: 悪い: 外部APIコール中にロックを保持
|
||||
BEGIN;
|
||||
SELECT * FROM orders WHERE id = 1 FOR UPDATE;
|
||||
-- HTTPコールに5秒かかる...
|
||||
UPDATE orders SET status = 'paid' WHERE id = 1;
|
||||
COMMIT;
|
||||
|
||||
-- ✅ 良い: 最小限のロック期間
|
||||
-- PASS: 良い: 最小限のロック期間
|
||||
-- トランザクション外で最初にAPIコールを実行
|
||||
BEGIN;
|
||||
UPDATE orders SET status = 'paid', payment_id = $1
|
||||
@@ -397,12 +397,12 @@ COMMIT; -- ミリ秒でロックを保持
|
||||
### 2. デッドロックを防ぐ
|
||||
|
||||
```sql
|
||||
-- ❌ 悪い: 一貫性のないロック順序がデッドロックを引き起こす
|
||||
-- FAIL: 悪い: 一貫性のないロック順序がデッドロックを引き起こす
|
||||
-- トランザクションA: 行1をロック、次に行2
|
||||
-- トランザクションB: 行2をロック、次に行1
|
||||
-- デッドロック!
|
||||
|
||||
-- ✅ 良い: 一貫したロック順序
|
||||
-- PASS: 良い: 一貫したロック順序
|
||||
BEGIN;
|
||||
SELECT * FROM accounts WHERE id IN (1, 2) ORDER BY id FOR UPDATE;
|
||||
-- これで両方の行がロックされ、任意の順序で更新可能
|
||||
@@ -416,10 +416,10 @@ COMMIT;
|
||||
**影響:** ワーカーキューで10倍のスループット
|
||||
|
||||
```sql
|
||||
-- ❌ 悪い: ワーカーが互いを待つ
|
||||
-- FAIL: 悪い: ワーカーが互いを待つ
|
||||
SELECT * FROM jobs WHERE status = 'pending' LIMIT 1 FOR UPDATE;
|
||||
|
||||
-- ✅ 良い: ワーカーはロックされた行をスキップ
|
||||
-- PASS: 良い: ワーカーはロックされた行をスキップ
|
||||
UPDATE jobs
|
||||
SET status = 'processing', worker_id = $1, started_at = now()
|
||||
WHERE id = (
|
||||
@@ -441,36 +441,36 @@ RETURNING *;
|
||||
**影響:** バルク挿入が10〜50倍高速
|
||||
|
||||
```sql
|
||||
-- ❌ 悪い: 個別の挿入
|
||||
-- FAIL: 悪い: 個別の挿入
|
||||
INSERT INTO events (user_id, action) VALUES (1, 'click');
|
||||
INSERT INTO events (user_id, action) VALUES (2, 'view');
|
||||
-- 1000回のラウンドトリップ
|
||||
|
||||
-- ✅ 良い: バッチ挿入
|
||||
-- PASS: 良い: バッチ挿入
|
||||
INSERT INTO events (user_id, action) VALUES
|
||||
(1, 'click'),
|
||||
(2, 'view'),
|
||||
(3, 'click');
|
||||
-- 1回のラウンドトリップ
|
||||
|
||||
-- ✅ 最良: 大きなデータセットにはCOPY
|
||||
-- PASS: 最良: 大きなデータセットにはCOPY
|
||||
COPY events (user_id, action) FROM '/path/to/data.csv' WITH (FORMAT csv);
|
||||
```
|
||||
|
||||
### 2. N+1クエリの排除
|
||||
|
||||
```sql
|
||||
-- ❌ 悪い: N+1パターン
|
||||
-- FAIL: 悪い: N+1パターン
|
||||
SELECT id FROM users WHERE active = true; -- 100件のIDを返す
|
||||
-- 次に100回のクエリ:
|
||||
SELECT * FROM orders WHERE user_id = 1;
|
||||
SELECT * FROM orders WHERE user_id = 2;
|
||||
-- ... 98回以上
|
||||
|
||||
-- ✅ 良い: ANYを使用した単一クエリ
|
||||
-- PASS: 良い: ANYを使用した単一クエリ
|
||||
SELECT * FROM orders WHERE user_id = ANY(ARRAY[1, 2, 3, ...]);
|
||||
|
||||
-- ✅ 良い: JOIN
|
||||
-- PASS: 良い: JOIN
|
||||
SELECT u.id, u.name, o.*
|
||||
FROM users u
|
||||
LEFT JOIN orders o ON o.user_id = u.id
|
||||
@@ -482,11 +482,11 @@ WHERE u.active = true;
|
||||
**影響:** ページの深さに関係なく一貫したO(1)パフォーマンス
|
||||
|
||||
```sql
|
||||
-- ❌ 悪い: OFFSETは深さとともに遅くなる
|
||||
-- FAIL: 悪い: OFFSETは深さとともに遅くなる
|
||||
SELECT * FROM products ORDER BY id LIMIT 20 OFFSET 199980;
|
||||
-- 200,000行をスキャン!
|
||||
|
||||
-- ✅ 良い: カーソルベース(常に高速)
|
||||
-- PASS: 良い: カーソルベース(常に高速)
|
||||
SELECT * FROM products WHERE id > 199980 ORDER BY id LIMIT 20;
|
||||
-- インデックスを使用、O(1)
|
||||
```
|
||||
@@ -494,11 +494,11 @@ SELECT * FROM products WHERE id > 199980 ORDER BY id LIMIT 20;
|
||||
### 4. 挿入または更新のためのUPSERT
|
||||
|
||||
```sql
|
||||
-- ❌ 悪い: 競合状態
|
||||
-- FAIL: 悪い: 競合状態
|
||||
SELECT * FROM settings WHERE user_id = 123 AND key = 'theme';
|
||||
-- 両方のスレッドが何も見つけず、両方が挿入、一方が失敗
|
||||
|
||||
-- ✅ 良い: アトミックなUPSERT
|
||||
-- PASS: 良い: アトミックなUPSERT
|
||||
INSERT INTO settings (user_id, key, value)
|
||||
VALUES (123, 'theme', 'dark')
|
||||
ON CONFLICT (user_id, key)
|
||||
@@ -605,27 +605,27 @@ ORDER BY rank DESC;
|
||||
|
||||
## フラグを立てるべきアンチパターン
|
||||
|
||||
### ❌ クエリアンチパターン
|
||||
### FAIL: クエリアンチパターン
|
||||
- 本番コードでの`SELECT *`
|
||||
- WHERE/JOIN列にインデックスがない
|
||||
- 大きなテーブルでのOFFSETページネーション
|
||||
- N+1クエリパターン
|
||||
- パラメータ化されていないクエリ(SQLインジェクションリスク)
|
||||
|
||||
### ❌ スキーマアンチパターン
|
||||
### FAIL: スキーマアンチパターン
|
||||
- IDに`int`(`bigint`を使用)
|
||||
- 理由なく`varchar(255)`(`text`を使用)
|
||||
- タイムゾーンなしの`timestamp`(`timestamptz`を使用)
|
||||
- 主キーとしてのランダムUUID(UUIDv7またはIDENTITYを使用)
|
||||
- 引用符を必要とする混合ケースの識別子
|
||||
|
||||
### ❌ セキュリティアンチパターン
|
||||
### FAIL: セキュリティアンチパターン
|
||||
- アプリケーションユーザーへの`GRANT ALL`
|
||||
- マルチテナントテーブルでRLSが欠落
|
||||
- 行ごとに関数を呼び出すRLSポリシー(SELECTでラップされていない)
|
||||
- RLSポリシー列にインデックスがない
|
||||
|
||||
### ❌ 接続アンチパターン
|
||||
### FAIL: 接続アンチパターン
|
||||
- 接続プーリングなし
|
||||
- アイドルタイムアウトなし
|
||||
- トランザクションモードプーリングでのプリペアドステートメント
|
||||
|
||||
@@ -386,7 +386,7 @@ function extractJSDoc(pattern: string) {
|
||||
- [x] 古い参照なし
|
||||
|
||||
### 影響
|
||||
🟢 低 - ドキュメントのみ、コード変更なし
|
||||
低 - ドキュメントのみ、コード変更なし
|
||||
|
||||
完全なアーキテクチャ概要についてはdocs/CODEMAPS/INDEX.mdを参照してください。
|
||||
```
|
||||
|
||||
@@ -428,28 +428,28 @@ test('market search with complex query', async ({ page }) => {
|
||||
|
||||
**1. 競合状態**
|
||||
```typescript
|
||||
// ❌ 不安定: 要素が準備完了であると仮定しない
|
||||
// FAIL: 不安定: 要素が準備完了であると仮定しない
|
||||
await page.click('[data-testid="button"]')
|
||||
|
||||
// ✅ 安定: 要素が準備完了になるのを待つ
|
||||
// PASS: 安定: 要素が準備完了になるのを待つ
|
||||
await page.locator('[data-testid="button"]').click() // 組み込みの自動待機
|
||||
```
|
||||
|
||||
**2. ネットワークタイミング**
|
||||
```typescript
|
||||
// ❌ 不安定: 任意のタイムアウト
|
||||
// FAIL: 不安定: 任意のタイムアウト
|
||||
await page.waitForTimeout(5000)
|
||||
|
||||
// ✅ 安定: 特定の条件を待つ
|
||||
// PASS: 安定: 特定の条件を待つ
|
||||
await page.waitForResponse(resp => resp.url().includes('/api/markets'))
|
||||
```
|
||||
|
||||
**3. アニメーションタイミング**
|
||||
```typescript
|
||||
// ❌ 不安定: アニメーション中にクリック
|
||||
// FAIL: 不安定: アニメーション中にクリック
|
||||
await page.click('[data-testid="menu-item"]')
|
||||
|
||||
// ✅ 安定: アニメーションが完了するのを待つ
|
||||
// PASS: 安定: アニメーションが完了するのを待つ
|
||||
await page.locator('[data-testid="menu-item"]').waitFor({ state: 'visible' })
|
||||
await page.waitForLoadState('networkidle')
|
||||
await page.click('[data-testid="menu-item"]')
|
||||
@@ -548,7 +548,7 @@ jobs:
|
||||
|
||||
**日付:** YYYY-MM-DD HH:MM
|
||||
**期間:** Xm Ys
|
||||
**ステータス:** ✅ 成功 / ❌ 失敗
|
||||
**ステータス:** PASS: 成功 / FAIL: 失敗
|
||||
|
||||
## まとめ
|
||||
|
||||
@@ -561,20 +561,20 @@ jobs:
|
||||
## スイート別テスト結果
|
||||
|
||||
### Markets - ブラウズと検索
|
||||
- ✅ user can browse markets (2.3s)
|
||||
- ✅ semantic search returns relevant results (1.8s)
|
||||
- ✅ search handles no results (1.2s)
|
||||
- ❌ search with special characters (0.9s)
|
||||
- PASS: user can browse markets (2.3s)
|
||||
- PASS: semantic search returns relevant results (1.8s)
|
||||
- PASS: search handles no results (1.2s)
|
||||
- FAIL: search with special characters (0.9s)
|
||||
|
||||
### Wallet - 接続
|
||||
- ✅ user can connect MetaMask (3.1s)
|
||||
- ⚠️ user can connect Phantom (2.8s) - 不安定
|
||||
- ✅ user can disconnect wallet (1.5s)
|
||||
- PASS: user can connect MetaMask (3.1s)
|
||||
- WARNING: user can connect Phantom (2.8s) - 不安定
|
||||
- PASS: user can disconnect wallet (1.5s)
|
||||
|
||||
### Trading - コアフロー
|
||||
- ✅ user can place buy order (5.2s)
|
||||
- ❌ user can place sell order (4.8s)
|
||||
- ✅ insufficient balance shows error (1.9s)
|
||||
- PASS: user can place buy order (5.2s)
|
||||
- FAIL: user can place sell order (4.8s)
|
||||
- PASS: insufficient balance shows error (1.9s)
|
||||
|
||||
## 失敗したテスト
|
||||
|
||||
@@ -623,13 +623,13 @@ jobs:
|
||||
## 成功指標
|
||||
|
||||
E2Eテスト実行後:
|
||||
- ✅ すべての重要なジャーニーが成功(100%)
|
||||
- ✅ 全体の成功率 > 95%
|
||||
- ✅ 不安定率 < 5%
|
||||
- ✅ デプロイをブロックする失敗したテストなし
|
||||
- ✅ アーティファクトがアップロードされアクセス可能
|
||||
- ✅ テスト時間 < 10分
|
||||
- ✅ HTMLレポートが生成された
|
||||
- PASS: すべての重要なジャーニーが成功(100%)
|
||||
- PASS: 全体の成功率 > 95%
|
||||
- PASS: 不安定率 < 5%
|
||||
- PASS: デプロイをブロックする失敗したテストなし
|
||||
- PASS: アーティファクトがアップロードされアクセス可能
|
||||
- PASS: テスト時間 < 10分
|
||||
- PASS: HTMLレポートが生成された
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -341,20 +341,20 @@ x = x // 無意味な代入を削除
|
||||
各修正試行後:
|
||||
|
||||
```text
|
||||
[FIXED] internal/handler/user.go:42
|
||||
Error: undefined: UserService
|
||||
Fix: Added import "project/internal/service"
|
||||
[修正済] internal/handler/user.go:42
|
||||
エラー: undefined: UserService
|
||||
修正: import を追加 "project/internal/service"
|
||||
|
||||
Remaining errors: 3
|
||||
残りのエラー: 3
|
||||
```
|
||||
|
||||
最終サマリー:
|
||||
```text
|
||||
Build Status: SUCCESS/FAILED
|
||||
Errors Fixed: N
|
||||
Vet Warnings Fixed: N
|
||||
Files Modified: list
|
||||
Remaining Issues: list (if any)
|
||||
ビルドステータス: SUCCESS/FAILED
|
||||
修正済みエラー: N
|
||||
Vet 警告修正済み: N
|
||||
変更ファイル: list
|
||||
残りの問題: list (ある場合)
|
||||
```
|
||||
|
||||
## 重要な注意事項
|
||||
|
||||
@@ -228,9 +228,9 @@ model: opus
|
||||
各問題について:
|
||||
```text
|
||||
[CRITICAL] SQLインジェクション脆弱性
|
||||
File: internal/repository/user.go:42
|
||||
Issue: ユーザー入力がSQLクエリに直接連結されている
|
||||
Fix: パラメータ化クエリを使用
|
||||
ファイル: internal/repository/user.go:42
|
||||
問題: ユーザー入力がSQLクエリに直接連結されている
|
||||
修正: パラメータ化クエリを使用
|
||||
|
||||
query := "SELECT * FROM users WHERE id = " + userID // Bad
|
||||
query := "SELECT * FROM users WHERE id = $1" // Good
|
||||
|
||||
@@ -399,9 +399,9 @@ model: opus
|
||||
各問題について:
|
||||
```text
|
||||
[CRITICAL] SQLインジェクション脆弱性
|
||||
File: app/routes/user.py:42
|
||||
Issue: ユーザー入力がSQLクエリに直接補間されている
|
||||
Fix: パラメータ化クエリを使用
|
||||
ファイル: app/routes/user.py:42
|
||||
問題: ユーザー入力がSQLクエリに直接補間されている
|
||||
修正: パラメータ化クエリを使用
|
||||
|
||||
query = f"SELECT * FROM users WHERE id = {user_id}" # Bad
|
||||
query = "SELECT * FROM users WHERE id = %s" # Good
|
||||
|
||||
@@ -146,22 +146,22 @@ e) テストがまだ合格することを確認
|
||||
|
||||
### 1. 未使用のインポート
|
||||
```typescript
|
||||
// ❌ 未使用のインポートを削除
|
||||
// FAIL: 未使用のインポートを削除
|
||||
import { useState, useEffect, useMemo } from 'react' // useStateのみ使用
|
||||
|
||||
// ✅ 使用されているもののみを保持
|
||||
// PASS: 使用されているもののみを保持
|
||||
import { useState } from 'react'
|
||||
```
|
||||
|
||||
### 2. デッドコードブランチ
|
||||
```typescript
|
||||
// ❌ 到達不可能なコードを削除
|
||||
// FAIL: 到達不可能なコードを削除
|
||||
if (false) {
|
||||
// これは決して実行されない
|
||||
doSomething()
|
||||
}
|
||||
|
||||
// ❌ 未使用の関数を削除
|
||||
// FAIL: 未使用の関数を削除
|
||||
export function unusedHelper() {
|
||||
// コードベースに参照なし
|
||||
}
|
||||
@@ -169,18 +169,18 @@ export function unusedHelper() {
|
||||
|
||||
### 3. 重複コンポーネント
|
||||
```typescript
|
||||
// ❌ 複数の類似コンポーネント
|
||||
// FAIL: 複数の類似コンポーネント
|
||||
components/Button.tsx
|
||||
components/PrimaryButton.tsx
|
||||
components/NewButton.tsx
|
||||
|
||||
// ✅ 1つに統合
|
||||
// PASS: 1つに統合
|
||||
components/Button.tsx (variantプロップ付き)
|
||||
```
|
||||
|
||||
### 4. 未使用の依存関係
|
||||
```json
|
||||
// ❌ インストールされているがインポートされていないパッケージ
|
||||
// FAIL: インストールされているがインポートされていないパッケージ
|
||||
{
|
||||
"dependencies": {
|
||||
"lodash": "^4.17.21", // どこでも使用されていない
|
||||
@@ -240,7 +240,7 @@ components/Button.tsx (variantプロップ付き)
|
||||
- 依存関係: -Xパッケージ
|
||||
|
||||
### リスクレベル
|
||||
🟢 低 - 検証可能な未使用コードのみを削除
|
||||
低 - 検証可能な未使用コードのみを削除
|
||||
|
||||
詳細はDELETION_LOG.mdを参照してください。
|
||||
```
|
||||
@@ -294,12 +294,12 @@ components/Button.tsx (variantプロップ付き)
|
||||
## 成功指標
|
||||
|
||||
クリーンアップセッション後:
|
||||
- ✅ すべてのテストが合格
|
||||
- ✅ ビルドが成功
|
||||
- ✅ コンソールエラーなし
|
||||
- ✅ DELETION_LOG.mdが更新された
|
||||
- ✅ バンドルサイズが削減された
|
||||
- ✅ 本番環境で回帰なし
|
||||
- PASS: すべてのテストが合格
|
||||
- PASS: ビルドが成功
|
||||
- PASS: コンソールエラーなし
|
||||
- PASS: DELETION_LOG.mdが更新された
|
||||
- PASS: バンドルサイズが削減された
|
||||
- PASS: 本番環境で回帰なし
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -184,12 +184,12 @@ APIセキュリティ:
|
||||
### 1. ハードコードされたシークレット(重要)
|
||||
|
||||
```javascript
|
||||
// ❌ 重要: ハードコードされたシークレット
|
||||
// FAIL: 重要: ハードコードされたシークレット
|
||||
const apiKey = "sk-proj-xxxxx"
|
||||
const password = "admin123"
|
||||
const token = "ghp_xxxxxxxxxxxx"
|
||||
|
||||
// ✅ 正しい: 環境変数
|
||||
// PASS: 正しい: 環境変数
|
||||
const apiKey = process.env.OPENAI_API_KEY
|
||||
if (!apiKey) {
|
||||
throw new Error('OPENAI_API_KEY not configured')
|
||||
@@ -199,11 +199,11 @@ if (!apiKey) {
|
||||
### 2. SQLインジェクション(重要)
|
||||
|
||||
```javascript
|
||||
// ❌ 重要: SQLインジェクションの脆弱性
|
||||
// FAIL: 重要: SQLインジェクションの脆弱性
|
||||
const query = `SELECT * FROM users WHERE id = ${userId}`
|
||||
await db.query(query)
|
||||
|
||||
// ✅ 正しい: パラメータ化されたクエリ
|
||||
// PASS: 正しい: パラメータ化されたクエリ
|
||||
const { data } = await supabase
|
||||
.from('users')
|
||||
.select('*')
|
||||
@@ -213,11 +213,11 @@ const { data } = await supabase
|
||||
### 3. コマンドインジェクション(重要)
|
||||
|
||||
```javascript
|
||||
// ❌ 重要: コマンドインジェクション
|
||||
// FAIL: 重要: コマンドインジェクション
|
||||
const { exec } = require('child_process')
|
||||
exec(`ping ${userInput}`, callback)
|
||||
|
||||
// ✅ 正しい: シェルコマンドではなくライブラリを使用
|
||||
// PASS: 正しい: シェルコマンドではなくライブラリを使用
|
||||
const dns = require('dns')
|
||||
dns.lookup(userInput, callback)
|
||||
```
|
||||
@@ -225,10 +225,10 @@ dns.lookup(userInput, callback)
|
||||
### 4. クロスサイトスクリプティング(XSS)(高)
|
||||
|
||||
```javascript
|
||||
// ❌ 高: XSS脆弱性
|
||||
// FAIL: 高: XSS脆弱性
|
||||
element.innerHTML = userInput
|
||||
|
||||
// ✅ 正しい: textContentを使用またはサニタイズ
|
||||
// PASS: 正しい: textContentを使用またはサニタイズ
|
||||
element.textContent = userInput
|
||||
// または
|
||||
import DOMPurify from 'dompurify'
|
||||
@@ -238,10 +238,10 @@ element.innerHTML = DOMPurify.sanitize(userInput)
|
||||
### 5. サーバーサイドリクエストフォージェリ(SSRF)(高)
|
||||
|
||||
```javascript
|
||||
// ❌ 高: SSRF脆弱性
|
||||
// FAIL: 高: SSRF脆弱性
|
||||
const response = await fetch(userProvidedUrl)
|
||||
|
||||
// ✅ 正しい: URLを検証してホワイトリスト
|
||||
// PASS: 正しい: URLを検証してホワイトリスト
|
||||
const allowedDomains = ['api.example.com', 'cdn.example.com']
|
||||
const url = new URL(userProvidedUrl)
|
||||
if (!allowedDomains.includes(url.hostname)) {
|
||||
@@ -253,10 +253,10 @@ const response = await fetch(url.toString())
|
||||
### 6. 安全でない認証(重要)
|
||||
|
||||
```javascript
|
||||
// ❌ 重要: 平文パスワード比較
|
||||
// FAIL: 重要: 平文パスワード比較
|
||||
if (password === storedPassword) { /* ログイン */ }
|
||||
|
||||
// ✅ 正しい: ハッシュ化されたパスワード比較
|
||||
// PASS: 正しい: ハッシュ化されたパスワード比較
|
||||
import bcrypt from 'bcrypt'
|
||||
const isValid = await bcrypt.compare(password, hashedPassword)
|
||||
```
|
||||
@@ -264,13 +264,13 @@ const isValid = await bcrypt.compare(password, hashedPassword)
|
||||
### 7. 不十分な認可(重要)
|
||||
|
||||
```javascript
|
||||
// ❌ 重要: 認可チェックなし
|
||||
// FAIL: 重要: 認可チェックなし
|
||||
app.get('/api/user/:id', async (req, res) => {
|
||||
const user = await getUser(req.params.id)
|
||||
res.json(user)
|
||||
})
|
||||
|
||||
// ✅ 正しい: ユーザーがリソースにアクセスできることを確認
|
||||
// PASS: 正しい: ユーザーがリソースにアクセスできることを確認
|
||||
app.get('/api/user/:id', authenticateUser, async (req, res) => {
|
||||
if (req.user.id !== req.params.id && !req.user.isAdmin) {
|
||||
return res.status(403).json({ error: 'Forbidden' })
|
||||
@@ -283,13 +283,13 @@ app.get('/api/user/:id', authenticateUser, async (req, res) => {
|
||||
### 8. 金融操作の競合状態(重要)
|
||||
|
||||
```javascript
|
||||
// ❌ 重要: 残高チェックの競合状態
|
||||
// FAIL: 重要: 残高チェックの競合状態
|
||||
const balance = await getBalance(userId)
|
||||
if (balance >= amount) {
|
||||
await withdraw(userId, amount) // 別のリクエストが並行して出金できる!
|
||||
}
|
||||
|
||||
// ✅ 正しい: ロック付きアトミックトランザクション
|
||||
// PASS: 正しい: ロック付きアトミックトランザクション
|
||||
await db.transaction(async (trx) => {
|
||||
const balance = await trx('balances')
|
||||
.where({ user_id: userId })
|
||||
@@ -309,13 +309,13 @@ await db.transaction(async (trx) => {
|
||||
### 9. 不十分なレート制限(高)
|
||||
|
||||
```javascript
|
||||
// ❌ 高: レート制限なし
|
||||
// FAIL: 高: レート制限なし
|
||||
app.post('/api/trade', async (req, res) => {
|
||||
await executeTrade(req.body)
|
||||
res.json({ success: true })
|
||||
})
|
||||
|
||||
// ✅ 正しい: レート制限
|
||||
// PASS: 正しい: レート制限
|
||||
import rateLimit from 'express-rate-limit'
|
||||
|
||||
const tradeLimiter = rateLimit({
|
||||
@@ -333,10 +333,10 @@ app.post('/api/trade', tradeLimiter, async (req, res) => {
|
||||
### 10. 機密データのロギング(中)
|
||||
|
||||
```javascript
|
||||
// ❌ 中: 機密データのロギング
|
||||
// FAIL: 中: 機密データのロギング
|
||||
console.log('User login:', { email, password, apiKey })
|
||||
|
||||
// ✅ 正しい: ログをサニタイズ
|
||||
// PASS: 正しい: ログをサニタイズ
|
||||
console.log('User login:', {
|
||||
email: email.replace(/(?<=.).(?=.*@)/g, '*'),
|
||||
passwordProvided: !!password
|
||||
@@ -358,7 +358,7 @@ console.log('User login:', {
|
||||
- **高い問題:** Y
|
||||
- **中程度の問題:** Z
|
||||
- **低い問題:** W
|
||||
- **リスクレベル:** 🔴 高 / 🟡 中 / 🟢 低
|
||||
- **リスクレベル:** 高 / 中 / 低
|
||||
|
||||
## 重要な問題(即座に修正)
|
||||
|
||||
@@ -380,7 +380,7 @@ console.log('User login:', {
|
||||
|
||||
**修復:**
|
||||
```javascript
|
||||
// ✅ 安全な実装
|
||||
// PASS: 安全な実装
|
||||
```
|
||||
|
||||
**参考資料:**
|
||||
@@ -433,7 +433,7 @@ PRをレビューする際、インラインコメントを投稿:
|
||||
## セキュリティレビュー
|
||||
|
||||
**レビューアー:** security-reviewer agent
|
||||
**リスクレベル:** 🔴 高 / 🟡 中 / 🟢 低
|
||||
**リスクレベル:** 高 / 中 / 低
|
||||
|
||||
### ブロッキング問題
|
||||
- [ ] **重要**: [説明] @ `file:line`
|
||||
@@ -532,13 +532,13 @@ npm install --save-dev audit-ci
|
||||
## 成功指標
|
||||
|
||||
セキュリティレビュー後:
|
||||
- ✅ 重要な問題が見つからない
|
||||
- ✅ すべての高い問題が対処されている
|
||||
- ✅ セキュリティチェックリストが完了
|
||||
- ✅ コードにシークレットがない
|
||||
- ✅ 依存関係が最新
|
||||
- ✅ テストにセキュリティシナリオが含まれている
|
||||
- ✅ ドキュメントが更新されている
|
||||
- PASS: 重要な問題が見つからない
|
||||
- PASS: すべての高い問題が対処されている
|
||||
- PASS: セキュリティチェックリストが完了
|
||||
- PASS: コードにシークレットがない
|
||||
- PASS: 依存関係が最新
|
||||
- PASS: テストにセキュリティシナリオが含まれている
|
||||
- PASS: ドキュメントが更新されている
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -220,26 +220,26 @@ jest.mock('@/lib/openai', () => ({
|
||||
|
||||
## テストの悪臭(アンチパターン)
|
||||
|
||||
### ❌ 実装の詳細をテスト
|
||||
### FAIL: 実装の詳細をテスト
|
||||
```typescript
|
||||
// 内部状態をテストしない
|
||||
expect(component.state.count).toBe(5)
|
||||
```
|
||||
|
||||
### ✅ ユーザーに見える動作をテスト
|
||||
### PASS: ユーザーに見える動作をテスト
|
||||
```typescript
|
||||
// ユーザーが見るものをテストする
|
||||
expect(screen.getByText('Count: 5')).toBeInTheDocument()
|
||||
```
|
||||
|
||||
### ❌ テストが互いに依存
|
||||
### FAIL: テストが互いに依存
|
||||
```typescript
|
||||
// 前のテストに依存しない
|
||||
test('creates user', () => { /* ... */ })
|
||||
test('updates same user', () => { /* 前のテストが必要 */ })
|
||||
```
|
||||
|
||||
### ✅ 独立したテスト
|
||||
### PASS: 独立したテスト
|
||||
```typescript
|
||||
// 各テストでデータをセットアップ
|
||||
test('updates user', () => {
|
||||
|
||||
@@ -35,12 +35,12 @@ echo "$(date +%Y-%m-%d-%H:%M) | $CHECKPOINT_NAME | $(git rev-parse --short HEAD)
|
||||
3. レポート:
|
||||
|
||||
```
|
||||
CHECKPOINT COMPARISON: $NAME
|
||||
チェックポイント比較: $NAME
|
||||
============================
|
||||
Files changed: X
|
||||
Tests: +Y passed / -Z failed
|
||||
Coverage: +X% / -Y%
|
||||
Build: [PASS/FAIL]
|
||||
変更されたファイル: X
|
||||
テスト: +Y 合格 / -Z 失敗
|
||||
カバレッジ: +X% / -Y%
|
||||
ビルド: [PASS/FAIL]
|
||||
```
|
||||
|
||||
## チェックポイント一覧表示
|
||||
@@ -57,13 +57,13 @@ Build: [PASS/FAIL]
|
||||
一般的なチェックポイント流:
|
||||
|
||||
```
|
||||
[Start] --> /checkpoint create "feature-start"
|
||||
[開始] --> /checkpoint create "feature-start"
|
||||
|
|
||||
[Implement] --> /checkpoint create "core-done"
|
||||
[実装] --> /checkpoint create "core-done"
|
||||
|
|
||||
[Test] --> /checkpoint verify "core-done"
|
||||
[テスト] --> /checkpoint verify "core-done"
|
||||
|
|
||||
[Refactor] --> /checkpoint create "refactor-done"
|
||||
[リファクタリング] --> /checkpoint create "refactor-done"
|
||||
|
|
||||
[PR] --> /checkpoint verify "feature-start"
|
||||
```
|
||||
|
||||
@@ -38,24 +38,24 @@ e2e-runner エージェントは:
|
||||
## 使用します示例
|
||||
|
||||
````
|
||||
User: /e2e Test the market search and view flow
|
||||
User: /e2e マーケット検索と表示フローをテスト
|
||||
|
||||
Agent (e2e-runner):
|
||||
# E2E Test Generation: Market Search and View Flow
|
||||
# E2Eテスト生成: マーケット検索と表示フロー
|
||||
|
||||
## Test Scenario Identified
|
||||
## 特定されたテストシナリオ
|
||||
|
||||
**User Journey:** Market Search → View Results → Click Market → View Details
|
||||
**ユーザージャーニー:** マーケット検索 → 結果表示 → マーケットクリック → 詳細表示
|
||||
|
||||
**Test Coverage:**
|
||||
1. Navigate to markets page
|
||||
2. Perform semantic search
|
||||
3. Verify search results
|
||||
4. Click on first result
|
||||
5. Verify market details page loads
|
||||
6. Verify chart renders
|
||||
**テストカバレッジ:**
|
||||
1. マーケットページに遷移
|
||||
2. セマンティック検索を実行
|
||||
3. 検索結果を検証
|
||||
4. 最初の結果をクリック
|
||||
5. マーケット詳細ページの読み込みを検証
|
||||
6. チャートの描画を検証
|
||||
|
||||
## Generated Test Code
|
||||
## 生成されたテストコード
|
||||
|
||||
```typescript
|
||||
// tests/e2e/markets/search-and-view.spec.ts
|
||||
@@ -160,7 +160,7 @@ test.describe('Market Search and View Flow', () => {
|
||||
## テスト実行
|
||||
|
||||
```bash
|
||||
# Run the generated test
|
||||
# 生成されたテストを実行
|
||||
npx playwright test tests/e2e/markets/search-and-view.spec.ts
|
||||
|
||||
Running 3 tests using 3 workers
|
||||
@@ -181,54 +181,54 @@ Artifacts generated:
|
||||
|
||||
```
|
||||
╔══════════════════════════════════════════════════════════════╗
|
||||
║ E2E Test Results ║
|
||||
║ E2Eテスト結果 ║
|
||||
╠══════════════════════════════════════════════════════════════╣
|
||||
║ Status: ✅ ALL TESTS PASSED ║
|
||||
║ Total: 3 tests ║
|
||||
║ Passed: 3 (100%) ║
|
||||
║ Failed: 0 ║
|
||||
║ Flaky: 0 ║
|
||||
║ Duration: 9.1s ║
|
||||
║ ステータス: PASS: 全テスト合格 ║
|
||||
║ 合計: 3テスト ║
|
||||
║ 合格: 3 (100%) ║
|
||||
║ 失敗: 0 ║
|
||||
║ 不安定: 0 ║
|
||||
║ 所要時間: 9.1s ║
|
||||
╚══════════════════════════════════════════════════════════════╝
|
||||
|
||||
Artifacts:
|
||||
📸 Screenshots: 2 files
|
||||
📹 Videos: 0 files (only on failure)
|
||||
🔍 Traces: 0 files (only on failure)
|
||||
📊 HTML Report: playwright-report/index.html
|
||||
アーティファクト:
|
||||
スクリーンショット: 2ファイル
|
||||
ビデオ: 0ファイル (失敗時のみ)
|
||||
トレース: 0ファイル (失敗時のみ)
|
||||
HTMLレポート: playwright-report/index.html
|
||||
|
||||
View report: npx playwright show-report
|
||||
レポート表示: npx playwright show-report
|
||||
```
|
||||
|
||||
✅ E2E テストスイートは CI/CD 統合の準備ができました!
|
||||
PASS: E2E テストスイートは CI/CD 統合の準備ができました!
|
||||
|
||||
````
|
||||
|
||||
## Test Artifacts
|
||||
## テストアーティファクト
|
||||
|
||||
When tests run, the following artifacts are captured:
|
||||
テスト実行時、以下のアーティファクトがキャプチャされます:
|
||||
|
||||
**On All Tests:**
|
||||
- HTML Report with timeline and results
|
||||
- JUnit XML for CI integration
|
||||
**全テスト共通:**
|
||||
- タイムラインと結果を含むHTMLレポート
|
||||
- CI統合用のJUnit XML
|
||||
|
||||
**On Failure Only:**
|
||||
- Screenshot of the failing state
|
||||
- Video recording of the test
|
||||
- Trace file for debugging (step-by-step replay)
|
||||
- Network logs
|
||||
- Console logs
|
||||
**失敗時のみ:**
|
||||
- 失敗状態のスクリーンショット
|
||||
- テストのビデオ録画
|
||||
- デバッグ用トレースファイル (ステップバイステップ再生)
|
||||
- ネットワークログ
|
||||
- コンソールログ
|
||||
|
||||
## Viewing Artifacts
|
||||
## アーティファクトの確認
|
||||
|
||||
```bash
|
||||
# View HTML report in browser
|
||||
# ブラウザでHTMLレポートを表示
|
||||
npx playwright show-report
|
||||
|
||||
# View specific trace file
|
||||
# 特定のトレースファイルを表示
|
||||
npx playwright show-trace artifacts/trace-abc123.zip
|
||||
|
||||
# Screenshots are saved in artifacts/ directory
|
||||
# スクリーンショットはartifacts/ディレクトリに保存
|
||||
open artifacts/search-results.png
|
||||
````
|
||||
|
||||
@@ -237,30 +237,30 @@ open artifacts/search-results.png
|
||||
テストが断続的に失敗する場合:
|
||||
|
||||
```
|
||||
⚠️ FLAKY TEST DETECTED: tests/e2e/markets/trade.spec.ts
|
||||
WARNING: FLAKY TEST DETECTED: tests/e2e/markets/trade.spec.ts
|
||||
|
||||
Test passed 7/10 runs (70% pass rate)
|
||||
テストは10回中7回合格 (合格率70%)
|
||||
|
||||
Common failure:
|
||||
よくある失敗:
|
||||
"Timeout waiting for element '[data-testid="confirm-btn"]'"
|
||||
|
||||
Recommended fixes:
|
||||
1. Add explicit wait: await page.waitForSelector('[data-testid="confirm-btn"]')
|
||||
2. Increase timeout: { timeout: 10000 }
|
||||
3. Check for race conditions in component
|
||||
4. Verify element is not hidden by animation
|
||||
推奨修正:
|
||||
1. 明示的な待機を追加: await page.waitForSelector('[data-testid="confirm-btn"]')
|
||||
2. タイムアウトを増加: { timeout: 10000 }
|
||||
3. コンポーネントの競合状態を確認
|
||||
4. 要素がアニメーションで隠れていないか確認
|
||||
|
||||
Quarantine recommendation: Mark as test.fixme() until fixed
|
||||
隔離推奨: 修正されるまでtest.fixme()としてマーク
|
||||
```
|
||||
|
||||
## ブラウザ設定
|
||||
|
||||
デフォルトでは、テストは複数のブラウザで実行されます:
|
||||
|
||||
* ✅ Chromium(デスクトップ Chrome)
|
||||
* ✅ Firefox(デスクトップ)
|
||||
* ✅ WebKit(デスクトップ Safari)
|
||||
* ✅ Mobile Chrome(オプション)
|
||||
* PASS: Chromium(デスクトップ Chrome)
|
||||
* PASS: Firefox(デスクトップ)
|
||||
* PASS: WebKit(デスクトップ Safari)
|
||||
* PASS: Mobile Chrome(オプション)
|
||||
|
||||
`playwright.config.ts` で設定してブラウザを調整します。
|
||||
|
||||
@@ -288,7 +288,7 @@ CI パイプラインに追加:
|
||||
|
||||
PMX の場合、以下の E2E テストを優先:
|
||||
|
||||
**🔴 重大(常に成功する必要):**
|
||||
**重大(常に成功する必要):**
|
||||
|
||||
1. ユーザーがウォレットを接続できる
|
||||
2. ユーザーが市場をブラウズできる
|
||||
@@ -298,7 +298,7 @@ PMX の場合、以下の E2E テストを優先:
|
||||
6. 市場が正しく決済される
|
||||
7. ユーザーが資金を引き出せる
|
||||
|
||||
**🟡 重要:**
|
||||
**重要:**
|
||||
|
||||
1. 市場作成フロー
|
||||
2. ユーザープロフィール更新
|
||||
@@ -311,21 +311,21 @@ PMX の場合、以下の E2E テストを優先:
|
||||
|
||||
**すべき事:**
|
||||
|
||||
* ✅ 保守性を高めるためページオブジェクトモデルを使用します
|
||||
* ✅ セレクタとして data-testid 属性を使用します
|
||||
* ✅ 任意のタイムアウトではなく API レスポンスを待機
|
||||
* ✅ 重要なユーザージャーニーのエンドツーエンドテスト
|
||||
* ✅ main にマージする前にテストを実行
|
||||
* ✅ テスト失敗時にアーティファクトをレビュー
|
||||
* PASS: 保守性を高めるためページオブジェクトモデルを使用します
|
||||
* PASS: セレクタとして data-testid 属性を使用します
|
||||
* PASS: 任意のタイムアウトではなく API レスポンスを待機
|
||||
* PASS: 重要なユーザージャーニーのエンドツーエンドテスト
|
||||
* PASS: main にマージする前にテストを実行
|
||||
* PASS: テスト失敗時にアーティファクトをレビュー
|
||||
|
||||
**すべきでない事:**
|
||||
|
||||
* ❌ 不安定なセレクタを使用します(CSS クラスは変わる可能性)
|
||||
* ❌ 実装の詳細をテスト
|
||||
* ❌ 本番環境に対してテストを実行
|
||||
* ❌ 不安定なテストを無視
|
||||
* ❌ 失敗時にアーティファクトレビューをスキップ
|
||||
* ❌ E2E テストですべてのエッジケースをテスト(単体テストを使用します)
|
||||
* FAIL: 不安定なセレクタを使用します(CSS クラスは変わる可能性)
|
||||
* FAIL: 実装の詳細をテスト
|
||||
* FAIL: 本番環境に対してテストを実行
|
||||
* FAIL: 不安定なテストを無視
|
||||
* FAIL: 失敗時にアーティファクトレビューをスキップ
|
||||
* FAIL: E2E テストですべてのエッジケースをテスト(単体テストを使用します)
|
||||
|
||||
## 重要な注意事項
|
||||
|
||||
@@ -350,21 +350,21 @@ PMX の場合、以下の E2E テストを優先:
|
||||
## 快速命令
|
||||
|
||||
```bash
|
||||
# Run all E2E tests
|
||||
# 全E2Eテストを実行
|
||||
npx playwright test
|
||||
|
||||
# Run specific test file
|
||||
# 特定のテストファイルを実行
|
||||
npx playwright test tests/e2e/markets/search.spec.ts
|
||||
|
||||
# Run in headed mode (see browser)
|
||||
# ヘッドモードで実行 (ブラウザ表示)
|
||||
npx playwright test --headed
|
||||
|
||||
# Debug test
|
||||
# テストをデバッグ
|
||||
npx playwright test --debug
|
||||
|
||||
# Generate test code
|
||||
# テストコードを生成
|
||||
npx playwright codegen http://localhost:3000
|
||||
|
||||
# View report
|
||||
# レポートを表示
|
||||
npx playwright show-report
|
||||
```
|
||||
|
||||
@@ -92,36 +92,36 @@ instinctsが分離の恩恵を受ける複雑な複数ステップのプロセ
|
||||
## 出力フォーマット
|
||||
|
||||
```
|
||||
🧬 Evolve Analysis
|
||||
進化分析
|
||||
==================
|
||||
|
||||
進化の準備ができた3つのクラスターを発見:
|
||||
|
||||
## クラスター1: データベースマイグレーションワークフロー
|
||||
Instincts: new-table-migration, update-schema, regenerate-types
|
||||
Type: Command
|
||||
Confidence: 85%(12件の観測に基づく)
|
||||
タイプ: Command
|
||||
信頼度: 85%(12件の観測に基づく)
|
||||
|
||||
作成: /new-tableコマンド
|
||||
Files:
|
||||
ファイル:
|
||||
- ~/.claude/homunculus/evolved/commands/new-table.md
|
||||
|
||||
## クラスター2: 関数型コードスタイル
|
||||
Instincts: prefer-functional, use-immutable, avoid-classes, pure-functions
|
||||
Type: Skill
|
||||
Confidence: 78%(8件の観測に基づく)
|
||||
タイプ: Skill
|
||||
信頼度: 78%(8件の観測に基づく)
|
||||
|
||||
作成: functional-patternsスキル
|
||||
Files:
|
||||
ファイル:
|
||||
- ~/.claude/homunculus/evolved/skills/functional-patterns.md
|
||||
|
||||
## クラスター3: デバッグプロセス
|
||||
Instincts: debug-check-logs, debug-isolate, debug-reproduce, debug-verify
|
||||
Type: Agent
|
||||
Confidence: 72%(6件の観測に基づく)
|
||||
タイプ: Agent
|
||||
信頼度: 72%(6件の観測に基づく)
|
||||
|
||||
作成: debuggerエージェント
|
||||
Files:
|
||||
ファイル:
|
||||
- ~/.claude/homunculus/evolved/agents/debugger.md
|
||||
|
||||
---
|
||||
|
||||
@@ -62,9 +62,9 @@ internal/handler/api.go:58:2: missing return at end of function
|
||||
|
||||
## 修正1: 未定義の識別子
|
||||
|
||||
File: internal/service/user.go:25
|
||||
Error: undefined: UserRepository
|
||||
Cause: インポート欠落
|
||||
ファイル: internal/service/user.go:25
|
||||
エラー: undefined: UserRepository
|
||||
原因: インポート欠落
|
||||
|
||||
```go
|
||||
// インポートを追加
|
||||
@@ -83,8 +83,8 @@ $ go build ./...
|
||||
|
||||
## 修正2: 型の不一致
|
||||
|
||||
File: internal/handler/api.go:42
|
||||
Error: cannot use x (type string) as type int
|
||||
ファイル: internal/handler/api.go:42
|
||||
エラー: cannot use x (type string) as type int
|
||||
|
||||
```go
|
||||
// 変更前
|
||||
@@ -101,8 +101,8 @@ $ go build ./...
|
||||
|
||||
## 修正3: 戻り値の欠落
|
||||
|
||||
File: internal/handler/api.go:58
|
||||
Error: missing return at end of function
|
||||
ファイル: internal/handler/api.go:58
|
||||
エラー: missing return at end of function
|
||||
|
||||
```go
|
||||
func GetUser(id string) (*User, error) {
|
||||
@@ -140,7 +140,7 @@ ok project/internal/handler 0.023s
|
||||
| 変更されたファイル | 2 |
|
||||
| 残存問題 | 0 |
|
||||
|
||||
ビルドステータス: ✅ 成功
|
||||
ビルドステータス: PASS: 成功
|
||||
```
|
||||
|
||||
## 修正される一般的なエラー
|
||||
|
||||
@@ -85,8 +85,8 @@ Agent:
|
||||
## 発見された問題
|
||||
|
||||
[CRITICAL] 競合状態
|
||||
File: internal/service/auth.go:45
|
||||
Issue: 同期化なしで共有マップにアクセス
|
||||
ファイル: internal/service/auth.go:45
|
||||
問題: 同期化なしで共有マップにアクセス
|
||||
```go
|
||||
var cache = map[string]*Session{} // 並行アクセス!
|
||||
|
||||
@@ -94,7 +94,7 @@ func GetSession(id string) *Session {
|
||||
return cache[id] // 競合状態
|
||||
}
|
||||
```
|
||||
Fix: sync.RWMutexまたはsync.Mapを使用
|
||||
修正: sync.RWMutexまたはsync.Mapを使用
|
||||
```go
|
||||
var (
|
||||
cache = map[string]*Session{}
|
||||
@@ -109,12 +109,12 @@ func GetSession(id string) *Session {
|
||||
```
|
||||
|
||||
[HIGH] エラーコンテキストの欠落
|
||||
File: internal/handler/user.go:28
|
||||
Issue: コンテキストなしでエラーを返す
|
||||
ファイル: internal/handler/user.go:28
|
||||
問題: コンテキストなしでエラーを返す
|
||||
```go
|
||||
return err // コンテキストなし
|
||||
```
|
||||
Fix: コンテキストでラップ
|
||||
修正: コンテキストでラップ
|
||||
```go
|
||||
return fmt.Errorf("get user %s: %w", userID, err)
|
||||
```
|
||||
@@ -124,16 +124,16 @@ return fmt.Errorf("get user %s: %w", userID, err)
|
||||
- HIGH: 1
|
||||
- MEDIUM: 0
|
||||
|
||||
推奨: ❌ CRITICAL問題が修正されるまでマージをブロック
|
||||
推奨: FAIL: CRITICAL問題が修正されるまでマージをブロック
|
||||
```
|
||||
|
||||
## 承認基準
|
||||
|
||||
| ステータス | 条件 |
|
||||
|--------|-----------|
|
||||
| ✅ 承認 | CRITICALまたはHIGH問題なし |
|
||||
| ⚠️ 警告 | MEDIUM問題のみ(注意してマージ) |
|
||||
| ❌ ブロック | CRITICALまたはHIGH問題が発見された |
|
||||
| PASS: 承認 | CRITICALまたはHIGH問題なし |
|
||||
| WARNING: 警告 | MEDIUM問題のみ(注意してマージ) |
|
||||
| FAIL: ブロック | CRITICALまたはHIGH問題が発見された |
|
||||
|
||||
## 他のコマンドとの統合
|
||||
|
||||
|
||||
@@ -70,17 +70,17 @@ instincts:
|
||||
## プライバシーに関する考慮事項
|
||||
|
||||
エクスポートに含まれる内容:
|
||||
- ✅ トリガーパターン
|
||||
- ✅ アクション
|
||||
- ✅ 信頼度スコア
|
||||
- ✅ ドメイン
|
||||
- ✅ 観察回数
|
||||
- PASS: トリガーパターン
|
||||
- PASS: アクション
|
||||
- PASS: 信頼度スコア
|
||||
- PASS: ドメイン
|
||||
- PASS: 観察回数
|
||||
|
||||
エクスポートに含まれない内容:
|
||||
- ❌ 実際のコードスニペット
|
||||
- ❌ ファイルパス
|
||||
- ❌ セッション記録
|
||||
- ❌ 個人識別情報
|
||||
- FAIL: 実際のコードスニペット
|
||||
- FAIL: ファイルパス
|
||||
- FAIL: セッション記録
|
||||
- FAIL: 個人識別情報
|
||||
|
||||
## フラグ
|
||||
|
||||
|
||||
@@ -45,40 +45,40 @@ python3 ~/.claude/skills/continuous-learning-v2/scripts/instinct-cli.py import <
|
||||
## インポートプロセス
|
||||
|
||||
```
|
||||
📥 Importing instincts from: team-instincts.yaml
|
||||
instinctsをインポート中: team-instincts.yaml
|
||||
================================================
|
||||
|
||||
Found 12 instincts to import.
|
||||
12件のinstinctsが見つかりました。
|
||||
|
||||
Analyzing conflicts...
|
||||
競合を分析中...
|
||||
|
||||
## New Instincts (8)
|
||||
These will be added:
|
||||
## 新規instincts (8)
|
||||
以下が追加されます:
|
||||
✓ use-zod-validation (confidence: 0.7)
|
||||
✓ prefer-named-exports (confidence: 0.65)
|
||||
✓ test-async-functions (confidence: 0.8)
|
||||
...
|
||||
|
||||
## Duplicate Instincts (3)
|
||||
Already have similar instincts:
|
||||
⚠️ prefer-functional-style
|
||||
Local: 0.8 confidence, 12 observations
|
||||
Import: 0.7 confidence
|
||||
→ Keep local (higher confidence)
|
||||
## 重複instincts (3)
|
||||
類似のinstinctsが既に存在:
|
||||
WARNING: prefer-functional-style
|
||||
ローカル: 信頼度0.8, 12回の観測
|
||||
インポート: 信頼度0.7
|
||||
→ ローカルを保持 (信頼度が高い)
|
||||
|
||||
⚠️ test-first-workflow
|
||||
Local: 0.75 confidence
|
||||
Import: 0.9 confidence
|
||||
→ Update to import (higher confidence)
|
||||
WARNING: test-first-workflow
|
||||
ローカル: 信頼度0.75
|
||||
インポート: 信頼度0.9
|
||||
→ インポートに更新 (信頼度が高い)
|
||||
|
||||
## Conflicting Instincts (1)
|
||||
These contradict local instincts:
|
||||
❌ use-classes-for-services
|
||||
Conflicts with: avoid-classes
|
||||
→ Skip (requires manual resolution)
|
||||
## 競合instincts (1)
|
||||
ローカルのinstinctsと矛盾:
|
||||
FAIL: use-classes-for-services
|
||||
競合: avoid-classes
|
||||
→ スキップ (手動解決が必要)
|
||||
|
||||
---
|
||||
Import 8 new, update 1, skip 3?
|
||||
8件を新規追加、1件を更新、3件をスキップしますか?
|
||||
```
|
||||
|
||||
## マージ戦略
|
||||
@@ -130,13 +130,13 @@ Skill Creatorからインポートする場合:
|
||||
|
||||
インポート後:
|
||||
```
|
||||
✅ Import complete!
|
||||
PASS: インポート完了!
|
||||
|
||||
Added: 8 instincts
|
||||
Updated: 1 instinct
|
||||
Skipped: 3 instincts (2 duplicates, 1 conflict)
|
||||
追加: 8件のinstincts
|
||||
更新: 1件のinstinct
|
||||
スキップ: 3件のinstincts (2件の重複, 1件の競合)
|
||||
|
||||
New instincts saved to: ~/.claude/homunculus/instincts/inherited/
|
||||
新規instinctsの保存先: ~/.claude/homunculus/instincts/inherited/
|
||||
|
||||
Run /instinct-status to see all instincts.
|
||||
/instinct-statusを実行してすべてのinstinctsを確認できます。
|
||||
```
|
||||
|
||||
@@ -39,42 +39,42 @@ python3 ~/.claude/skills/continuous-learning-v2/scripts/instinct-cli.py status
|
||||
## 出力形式
|
||||
|
||||
```
|
||||
📊 Instinct Status
|
||||
instinctステータス
|
||||
==================
|
||||
|
||||
## Code Style (4 instincts)
|
||||
## コードスタイル (4 instincts)
|
||||
|
||||
### prefer-functional-style
|
||||
Trigger: when writing new functions
|
||||
Action: Use functional patterns over classes
|
||||
Confidence: ████████░░ 80%
|
||||
Source: session-observation | Last updated: 2025-01-22
|
||||
トリガー: 新しい関数を書くとき
|
||||
アクション: クラスより関数型パターンを使用
|
||||
信頼度: ████████░░ 80%
|
||||
ソース: session-observation | 最終更新: 2025-01-22
|
||||
|
||||
### use-path-aliases
|
||||
Trigger: when importing modules
|
||||
Action: Use @/ path aliases instead of relative imports
|
||||
Confidence: ██████░░░░ 60%
|
||||
Source: repo-analysis (github.com/acme/webapp)
|
||||
トリガー: モジュールをインポートするとき
|
||||
アクション: 相対インポートの代わりに@/パスエイリアスを使用
|
||||
信頼度: ██████░░░░ 60%
|
||||
ソース: repo-analysis (github.com/acme/webapp)
|
||||
|
||||
## Testing (2 instincts)
|
||||
## テスト (2 instincts)
|
||||
|
||||
### test-first-workflow
|
||||
Trigger: when adding new functionality
|
||||
Action: Write test first, then implementation
|
||||
Confidence: █████████░ 90%
|
||||
Source: session-observation
|
||||
トリガー: 新しい機能を追加するとき
|
||||
アクション: テストを先に書き、次に実装
|
||||
信頼度: █████████░ 90%
|
||||
ソース: session-observation
|
||||
|
||||
## Workflow (3 instincts)
|
||||
## ワークフロー (3 instincts)
|
||||
|
||||
### grep-before-edit
|
||||
Trigger: when modifying code
|
||||
Action: Search with Grep, confirm with Read, then Edit
|
||||
Confidence: ███████░░░ 70%
|
||||
Source: session-observation
|
||||
トリガー: コードを変更するとき
|
||||
アクション: Grepで検索、Readで確認、次にEdit
|
||||
信頼度: ███████░░░ 70%
|
||||
ソース: session-observation
|
||||
|
||||
---
|
||||
Total: 9 instincts (4 personal, 5 inherited)
|
||||
Observer: Running (last analysis: 5 min ago)
|
||||
合計: 9 instincts (4個人, 5継承)
|
||||
オブザーバー: 実行中 (最終分析: 5分前)
|
||||
```
|
||||
|
||||
## フラグ
|
||||
|
||||
@@ -204,9 +204,9 @@ Claudeの統合計画での欠落リスクを減らすために、両方のモ
|
||||
3. **太字テキスト**でプロンプトを出力(**保存された実際のファイルパスを使用する必要があります**):
|
||||
|
||||
---
|
||||
**計画が生成され、`.claude/plan/actual-feature-name.md`に保存されました**
|
||||
**計画が生成され、`.claude/plan/actual-feature-name.md`に保存されました**
|
||||
|
||||
**上記の計画をレビューしてください。以下のことができます:**
|
||||
**上記の計画をレビューしてください。以下のことができます:**
|
||||
- **計画を変更**: 調整が必要なことを教えてください、計画を更新します
|
||||
- **計画を実行**: 以下のコマンドを新しいセッションにコピー
|
||||
|
||||
@@ -215,7 +215,7 @@ Claudeの統合計画での欠落リスクを減らすために、両方のモ
|
||||
```
|
||||
---
|
||||
|
||||
**注意**: 上記の`actual-feature-name.md`は実際に保存されたファイル名で置き換える必要があります!
|
||||
**注意**: 上記の`actual-feature-name.md`は実際に保存されたファイル名で置き換える必要があります!
|
||||
|
||||
4. **現在のレスポンスを直ちに終了**(ここで停止。これ以上のツール呼び出しはありません。)
|
||||
|
||||
|
||||
@@ -99,36 +99,36 @@ security-reviewer -> code-reviewer -> architect
|
||||
## 最終レポート形式
|
||||
|
||||
```
|
||||
ORCHESTRATION REPORT
|
||||
オーケストレーションレポート
|
||||
====================
|
||||
Workflow: feature
|
||||
Task: Add user authentication
|
||||
Agents: planner -> tdd-guide -> code-reviewer -> security-reviewer
|
||||
ワークフロー: feature
|
||||
タスク: ユーザー認証の追加
|
||||
エージェント: planner -> tdd-guide -> code-reviewer -> security-reviewer
|
||||
|
||||
SUMMARY
|
||||
サマリー
|
||||
-------
|
||||
[1段落の要約]
|
||||
|
||||
AGENT OUTPUTS
|
||||
エージェント出力
|
||||
-------------
|
||||
Planner: [要約]
|
||||
TDD Guide: [要約]
|
||||
Code Reviewer: [要約]
|
||||
Security Reviewer: [要約]
|
||||
|
||||
FILES CHANGED
|
||||
変更ファイル
|
||||
-------------
|
||||
[変更されたすべてのファイルをリスト]
|
||||
|
||||
TEST RESULTS
|
||||
テスト結果
|
||||
------------
|
||||
[テスト合格/不合格の要約]
|
||||
|
||||
SECURITY STATUS
|
||||
セキュリティステータス
|
||||
---------------
|
||||
[セキュリティの発見事項]
|
||||
|
||||
RECOMMENDATION
|
||||
推奨事項
|
||||
--------------
|
||||
[リリース可 / 要修正 / ブロック中]
|
||||
```
|
||||
|
||||
@@ -89,32 +89,32 @@ Agent:
|
||||
## 静的解析結果
|
||||
✓ ruff: 問題なし
|
||||
✓ mypy: エラーなし
|
||||
⚠️ black: 2ファイルが再フォーマット必要
|
||||
WARNING: black: 2ファイルが再フォーマット必要
|
||||
✓ bandit: セキュリティ問題なし
|
||||
|
||||
## 発見された問題
|
||||
|
||||
[CRITICAL] SQLインジェクション脆弱性
|
||||
File: app/routes/user.py:42
|
||||
Issue: ユーザー入力が直接SQLクエリに挿入されている
|
||||
ファイル: app/routes/user.py:42
|
||||
問題: ユーザー入力が直接SQLクエリに挿入されている
|
||||
```python
|
||||
query = f"SELECT * FROM users WHERE id = {user_id}" # 悪い
|
||||
```
|
||||
Fix: パラメータ化クエリを使用
|
||||
修正: パラメータ化クエリを使用
|
||||
```python
|
||||
query = "SELECT * FROM users WHERE id = %s" # 良い
|
||||
cursor.execute(query, (user_id,))
|
||||
```
|
||||
|
||||
[HIGH] 可変デフォルト引数
|
||||
File: app/services/auth.py:18
|
||||
Issue: 可変デフォルト引数が共有状態を引き起こす
|
||||
ファイル: app/services/auth.py:18
|
||||
問題: 可変デフォルト引数が共有状態を引き起こす
|
||||
```python
|
||||
def process_items(items=[]): # 悪い
|
||||
items.append("new")
|
||||
return items
|
||||
```
|
||||
Fix: デフォルトにNoneを使用
|
||||
修正: デフォルトにNoneを使用
|
||||
```python
|
||||
def process_items(items=None): # 良い
|
||||
if items is None:
|
||||
@@ -124,27 +124,27 @@ def process_items(items=None): # 良い
|
||||
```
|
||||
|
||||
[MEDIUM] 型ヒントの欠落
|
||||
File: app/services/auth.py:25
|
||||
Issue: 型アノテーションのない公開関数
|
||||
ファイル: app/services/auth.py:25
|
||||
問題: 型アノテーションのない公開関数
|
||||
```python
|
||||
def get_user(user_id): # 悪い
|
||||
return db.find(user_id)
|
||||
```
|
||||
Fix: 型ヒントを追加
|
||||
修正: 型ヒントを追加
|
||||
```python
|
||||
def get_user(user_id: str) -> Optional[User]: # 良い
|
||||
return db.find(user_id)
|
||||
```
|
||||
|
||||
[MEDIUM] コンテキストマネージャーを使用していない
|
||||
File: app/routes/user.py:55
|
||||
Issue: 例外時にファイルがクローズされない
|
||||
ファイル: app/routes/user.py:55
|
||||
問題: 例外時にファイルがクローズされない
|
||||
```python
|
||||
f = open("config.json") # 悪い
|
||||
data = f.read()
|
||||
f.close()
|
||||
```
|
||||
Fix: コンテキストマネージャーを使用
|
||||
修正: コンテキストマネージャーを使用
|
||||
```python
|
||||
with open("config.json") as f: # 良い
|
||||
data = f.read()
|
||||
@@ -155,7 +155,7 @@ with open("config.json") as f: # 良い
|
||||
- HIGH: 1
|
||||
- MEDIUM: 2
|
||||
|
||||
推奨: ❌ CRITICAL問題が修正されるまでマージをブロック
|
||||
推奨: FAIL: CRITICAL問題が修正されるまでマージをブロック
|
||||
|
||||
## フォーマット必要
|
||||
実行: `black app/routes/user.py app/services/auth.py`
|
||||
@@ -165,9 +165,9 @@ with open("config.json") as f: # 良い
|
||||
|
||||
| ステータス | 条件 |
|
||||
|--------|-----------|
|
||||
| ✅ 承認 | CRITICALまたはHIGH問題なし |
|
||||
| ⚠️ 警告 | MEDIUM問題のみ(注意してマージ) |
|
||||
| ❌ ブロック | CRITICALまたはHIGH問題が発見された |
|
||||
| PASS: 承認 | CRITICALまたはHIGH問題なし |
|
||||
| WARNING: 警告 | MEDIUM問題のみ(注意してマージ) |
|
||||
| FAIL: ブロック | CRITICALまたはHIGH問題が発見された |
|
||||
|
||||
## 他のコマンドとの統合
|
||||
|
||||
|
||||
@@ -133,7 +133,7 @@ FAIL lib/liquidity.test.ts
|
||||
1 test failed, 0 passed
|
||||
```
|
||||
|
||||
✅ テストは期待通りに失敗しました。実装の準備ができました。
|
||||
PASS: テストは期待通りに失敗しました。実装の準備ができました。
|
||||
|
||||
## ステップ4: 最小限のコードを実装(GREEN)
|
||||
|
||||
@@ -179,7 +179,7 @@ PASS lib/liquidity.test.ts
|
||||
3 tests passed
|
||||
```
|
||||
|
||||
✅ すべてのテストが合格しました!
|
||||
PASS: すべてのテストが合格しました!
|
||||
|
||||
## ステップ6: リファクタリング(IMPROVE)
|
||||
|
||||
@@ -236,7 +236,7 @@ PASS lib/liquidity.test.ts
|
||||
3 tests passed
|
||||
```
|
||||
|
||||
✅ リファクタリング完了、テストはまだ合格しています!
|
||||
PASS: リファクタリング完了、テストはまだ合格しています!
|
||||
|
||||
## ステップ8: カバレッジの確認
|
||||
|
||||
@@ -247,29 +247,29 @@ File | % Stmts | % Branch | % Funcs | % Lines
|
||||
---------------|---------|----------|---------|--------
|
||||
liquidity.ts | 100 | 100 | 100 | 100
|
||||
|
||||
Coverage: 100% ✅ (Target: 80%)
|
||||
Coverage: 100% PASS: (Target: 80%)
|
||||
```
|
||||
|
||||
✅ TDDセッション完了!
|
||||
PASS: TDDセッション完了!
|
||||
```
|
||||
|
||||
## TDDベストプラクティス
|
||||
|
||||
**すべきこと:**
|
||||
- ✅ 実装の前にまずテストを書く
|
||||
- ✅ テストを実行し、実装前に失敗することを確認
|
||||
- ✅ テストに合格するための最小限のコードを書く
|
||||
- ✅ テストが緑色になってからのみリファクタリング
|
||||
- ✅ エッジケースとエラーシナリオを追加
|
||||
- ✅ 80%以上のカバレッジを目指す(重要なコードは100%)
|
||||
- PASS: 実装の前にまずテストを書く
|
||||
- PASS: テストを実行し、実装前に失敗することを確認
|
||||
- PASS: テストに合格するための最小限のコードを書く
|
||||
- PASS: テストが緑色になってからのみリファクタリング
|
||||
- PASS: エッジケースとエラーシナリオを追加
|
||||
- PASS: 80%以上のカバレッジを目指す(重要なコードは100%)
|
||||
|
||||
**してはいけないこと:**
|
||||
- ❌ テストの前に実装を書く
|
||||
- ❌ 各変更後のテスト実行をスキップ
|
||||
- ❌ 一度に多くのコードを書く
|
||||
- ❌ 失敗するテストを無視
|
||||
- ❌ 実装の詳細をテスト(動作をテスト)
|
||||
- ❌ すべてをモック化(統合テストを優先)
|
||||
- FAIL: テストの前に実装を書く
|
||||
- FAIL: 各変更後のテスト実行をスキップ
|
||||
- FAIL: 一度に多くのコードを書く
|
||||
- FAIL: 失敗するテストを無視
|
||||
- FAIL: 実装の詳細をテスト(動作をテスト)
|
||||
- FAIL: すべてをモック化(統合テストを優先)
|
||||
|
||||
## 含めるべきテストタイプ
|
||||
|
||||
|
||||
@@ -36,16 +36,16 @@
|
||||
簡潔な検証レポートを生成します:
|
||||
|
||||
```
|
||||
VERIFICATION: [PASS/FAIL]
|
||||
検証結果: [PASS/FAIL]
|
||||
|
||||
Build: [OK/FAIL]
|
||||
Types: [OK/X errors]
|
||||
Lint: [OK/X issues]
|
||||
Tests: [X/Y passed, Z% coverage]
|
||||
Secrets: [OK/X found]
|
||||
Logs: [OK/X console.logs]
|
||||
ビルド: [OK/FAIL]
|
||||
型: [OK/Xエラー]
|
||||
Lint: [OK/X件の問題]
|
||||
テスト: [X/Y合格, Z%カバレッジ]
|
||||
シークレット: [OK/X件発見]
|
||||
ログ: [OK/X件のconsole.log]
|
||||
|
||||
Ready for PR: [YES/NO]
|
||||
PR準備完了: [YES/NO]
|
||||
```
|
||||
|
||||
重大な問題がある場合は、修正案とともにリストアップします。
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user