fix: refresh stale technical content in agents, rules, and skills (#2168)

Several published examples contained APIs that no longer exist, code that
does not run, or model versions that drifted from reality:

- agents/performance-optimizer.md used the web-vitals v3 API
  (getCLS/getFID/getLCP/getFCP/getTTFB) and reported FID. web-vitals v4
  renamed the imports to onCLS/onINP/onLCP/onFCP/onTTFB and FID was
  replaced by INP (target < 200ms)
- rules/common/performance.md pinned stale model versions in the
  model-selection guidance; refresh to the versions the repo itself uses
  (agent.yaml pins claude-opus-4-6) and add the PowerShell variant for
  MAX_THINKING_TOKENS next to the bash export
- skills/python-patterns/SKILL.md: both get_value examples referenced
  default_value without declaring the parameter (NameError); add
  default_value: Any = None to the EAFP and LBYL signatures
- skills/frontend-patterns/SKILL.md: the custom useQuery example rebuilt
  refetch whenever callers passed inline fetchers/options, re-triggering
  the effect after every state update (infinite fetch loop). Keep the
  latest fetcher/options in refs so refetch stays referentially stable.
  The PASS-labelled useMemo example mutated its input with in-place sort;
  copy before sorting
- skills/coding-standards/SKILL.md repeated the same PASS-labelled
  in-place-sort-in-useMemo example; same fix
- rules/typescript/security.md used a vendor-specific OPENAI_API_KEY in
  generic guidance; switch to a neutral API_KEY

Every hand-maintained copy of the affected content is synced in the same
change: locale mirrors (ja-JP, ko-KR, pt-BR, tr, zh-CN, zh-TW - each only
where it carries the affected file) and the .agents/.kiro/.cursor harness
mirrors. Two structural divergences are left alone and noted here:
.kiro/steering/performance.md has no extended-thinking control list to
carry the PowerShell variant, and docs/zh-TW/rules/performance.md keeps an
older condensed thinking section without the budget-cap line.
rules/zh/performance.md is intentionally untouched - the rules/zh tree is
being retired in a separate change
This commit is contained in:
konstapukarifastnetfi
2026-06-07 08:26:01 +03:00
committed by GitHub
parent 36bec90d45
commit 8b24f63ede
31 changed files with 215 additions and 112 deletions
+2 -1
View File
@@ -414,8 +414,9 @@ export async function searchMarkets(
import { useMemo, useCallback } from 'react' import { useMemo, useCallback } from 'react'
// PASS: GOOD: Memoize expensive computations // PASS: GOOD: Memoize expensive computations
// Copy before sorting - Array.prototype.sort mutates in place
const sortedMarkets = useMemo(() => { const sortedMarkets = useMemo(() => {
return markets.sort((a, b) => b.volume - a.volume) return [...markets].sort((a, b) => b.volume - a.volume)
}, [markets]) }, [markets])
// PASS: GOOD: Memoize callbacks // PASS: GOOD: Memoize callbacks
+21 -7
View File
@@ -174,28 +174,41 @@ export function useQuery<T>(
const [error, setError] = useState<Error | null>(null) const [error, setError] = useState<Error | null>(null)
const [loading, setLoading] = useState(false) const [loading, setLoading] = useState(false)
// Keep the latest fetcher/options in refs so refetch stays referentially
// stable even when callers pass inline functions and object literals.
// Without this, every render creates a new refetch, and the effect below
// re-runs after each state update - an infinite fetch loop.
const fetcherRef = useRef(fetcher)
const optionsRef = useRef(options)
useEffect(() => {
fetcherRef.current = fetcher
optionsRef.current = options
})
const refetch = useCallback(async () => { const refetch = useCallback(async () => {
setLoading(true) setLoading(true)
setError(null) setError(null)
try { try {
const result = await fetcher() const result = await fetcherRef.current()
setData(result) setData(result)
options?.onSuccess?.(result) optionsRef.current?.onSuccess?.(result)
} catch (err) { } catch (err) {
const error = err as Error const error = err as Error
setError(error) setError(error)
options?.onError?.(error) optionsRef.current?.onError?.(error)
} finally { } finally {
setLoading(false) setLoading(false)
} }
}, [fetcher, options]) }, [])
const enabled = options?.enabled !== false
useEffect(() => { useEffect(() => {
if (options?.enabled !== false) { if (enabled) {
refetch() refetch()
} }
}, [key, refetch, options?.enabled]) }, [key, enabled, refetch])
return { data, error, loading, refetch } return { data, error, loading, refetch }
} }
@@ -300,8 +313,9 @@ export function useMarkets() {
```typescript ```typescript
// PASS: useMemo for expensive computations // PASS: useMemo for expensive computations
// Copy before sorting - Array.prototype.sort mutates in place
const sortedMarkets = useMemo(() => { const sortedMarkets = useMemo(() => {
return markets.sort((a, b) => b.volume - a.volume) return [...markets].sort((a, b) => b.volume - a.volume)
}, [markets]) }, [markets])
// PASS: useCallback for functions passed to children // PASS: useCallback for functions passed to children
+2 -2
View File
@@ -16,7 +16,7 @@ alwaysApply: true
- Orchestrating multi-agent workflows - Orchestrating multi-agent workflows
- Complex coding tasks - Complex coding tasks
**Opus 4.5** (Deepest reasoning): **Opus 4.6** (Deepest reasoning):
- Complex architectural decisions - Complex architectural decisions
- Maximum reasoning requirements - Maximum reasoning requirements
- Research and analysis tasks - Research and analysis tasks
@@ -41,7 +41,7 @@ Extended thinking is enabled by default, reserving up to 31,999 tokens for inter
Control extended thinking via: Control extended thinking via:
- **Toggle**: Option+T (macOS) / Alt+T (Windows/Linux) - **Toggle**: Option+T (macOS) / Alt+T (Windows/Linux)
- **Config**: Set `alwaysThinkingEnabled` in `~/.claude/settings.json` - **Config**: Set `alwaysThinkingEnabled` in `~/.claude/settings.json`
- **Budget cap**: `export MAX_THINKING_TOKENS=10000` - **Budget cap**: `export MAX_THINKING_TOKENS=10000` (bash) or `$env:MAX_THINKING_TOKENS = "10000"` (PowerShell)
- **Verbose mode**: Ctrl+O to see thinking output - **Verbose mode**: Ctrl+O to see thinking output
For complex tasks requiring deep reasoning: For complex tasks requiring deep reasoning:
+2 -1
View File
@@ -398,8 +398,9 @@ export async function searchMarkets(
import { useMemo, useCallback } from 'react' import { useMemo, useCallback } from 'react'
// PASS: GOOD: Memoize expensive computations // PASS: GOOD: Memoize expensive computations
// Copy before sorting - Array.prototype.sort mutates in place
const sortedMarkets = useMemo(() => { const sortedMarkets = useMemo(() => {
return markets.sort((a, b) => b.volume - a.volume) return [...markets].sort((a, b) => b.volume - a.volume)
}, [markets]) }, [markets])
// PASS: GOOD: Memoize callbacks // PASS: GOOD: Memoize callbacks
+21 -7
View File
@@ -171,28 +171,41 @@ export function useQuery<T>(
const [error, setError] = useState<Error | null>(null) const [error, setError] = useState<Error | null>(null)
const [loading, setLoading] = useState(false) const [loading, setLoading] = useState(false)
// Keep the latest fetcher/options in refs so refetch stays referentially
// stable even when callers pass inline functions and object literals.
// Without this, every render creates a new refetch, and the effect below
// re-runs after each state update - an infinite fetch loop.
const fetcherRef = useRef(fetcher)
const optionsRef = useRef(options)
useEffect(() => {
fetcherRef.current = fetcher
optionsRef.current = options
})
const refetch = useCallback(async () => { const refetch = useCallback(async () => {
setLoading(true) setLoading(true)
setError(null) setError(null)
try { try {
const result = await fetcher() const result = await fetcherRef.current()
setData(result) setData(result)
options?.onSuccess?.(result) optionsRef.current?.onSuccess?.(result)
} catch (err) { } catch (err) {
const error = err as Error const error = err as Error
setError(error) setError(error)
options?.onError?.(error) optionsRef.current?.onError?.(error)
} finally { } finally {
setLoading(false) setLoading(false)
} }
}, [fetcher, options]) }, [])
const enabled = options?.enabled !== false
useEffect(() => { useEffect(() => {
if (options?.enabled !== false) { if (enabled) {
refetch() refetch()
} }
}, [key, refetch, options?.enabled]) }, [key, enabled, refetch])
return { data, error, loading, refetch } return { data, error, loading, refetch }
} }
@@ -297,8 +310,9 @@ export function useMarkets() {
```typescript ```typescript
// PASS: useMemo for expensive computations // PASS: useMemo for expensive computations
// Copy before sorting - Array.prototype.sort mutates in place
const sortedMarkets = useMemo(() => { const sortedMarkets = useMemo(() => {
return markets.sort((a, b) => b.volume - a.volume) return [...markets].sort((a, b) => b.volume - a.volume)
}, [markets]) }, [markets])
// PASS: useCallback for functions passed to children // PASS: useCallback for functions passed to children
+2 -2
View File
@@ -12,12 +12,12 @@ description: Performance optimization guidelines including model selection strat
- Pair programming and code generation - Pair programming and code generation
- Worker agents in multi-agent systems - Worker agents in multi-agent systems
**Claude Sonnet 4.5** (Best coding model): **Claude Sonnet 4.6** (Best coding model):
- Main development work - Main development work
- Orchestrating multi-agent workflows - Orchestrating multi-agent workflows
- Complex coding tasks - Complex coding tasks
**Claude Opus 4.5** (Deepest reasoning): **Claude Opus 4.6** (Deepest reasoning):
- Complex architectural decisions - Complex architectural decisions
- Maximum reasoning requirements - Maximum reasoning requirements
- Research and analysis tasks - Research and analysis tasks
+8 -8
View File
@@ -362,14 +362,14 @@ npx lighthouse https://your-app.com --only-categories=performance
### Web Vitals Monitoring ### Web Vitals Monitoring
```typescript ```typescript
// Track Core Web Vitals // Track Core Web Vitals (web-vitals v4 API)
import { getCLS, getFID, getLCP, getFCP, getTTFB } from 'web-vitals'; import { onCLS, onINP, onLCP, onFCP, onTTFB } from 'web-vitals';
getCLS(console.log); // Cumulative Layout Shift onCLS(console.log); // Cumulative Layout Shift
getFID(console.log); // First Input Delay onINP(console.log); // Interaction to Next Paint
getLCP(console.log); // Largest Contentful Paint onLCP(console.log); // Largest Contentful Paint
getFCP(console.log); // First Contentful Paint onFCP(console.log); // First Contentful Paint
getTTFB(console.log); // Time to First Byte onTTFB(console.log); // Time to First Byte
``` ```
## Performance Report Template ## Performance Report Template
@@ -393,7 +393,7 @@ getTTFB(console.log); // Time to First Byte
| Metric | Current | Target | Status | | Metric | Current | Target | Status |
|--------|---------|--------|--------| |--------|---------|--------|--------|
| LCP | X.Xs | < 2.5s | PASS: | | LCP | X.Xs | < 2.5s | PASS: |
| FID | XXms | < 100ms | PASS: | | INP | XXms | < 200ms | PASS: |
| CLS | X.XX | < 0.1 | WARNING: | | CLS | X.XX | < 0.1 | WARNING: |
## Critical Issues ## Critical Issues
+8 -8
View File
@@ -362,14 +362,14 @@ npx lighthouse https://your-app.com --only-categories=performance
### Web Vitalsモニタリング ### Web Vitalsモニタリング
```typescript ```typescript
// Core Web Vitalsの追跡 // Track Core Web Vitals (web-vitals v4 API)
import { getCLS, getFID, getLCP, getFCP, getTTFB } from 'web-vitals'; import { onCLS, onINP, onLCP, onFCP, onTTFB } from 'web-vitals';
getCLS(console.log); // Cumulative Layout Shift onCLS(console.log); // Cumulative Layout Shift
getFID(console.log); // First Input Delay onINP(console.log); // Interaction to Next Paint
getLCP(console.log); // Largest Contentful Paint onLCP(console.log); // Largest Contentful Paint
getFCP(console.log); // First Contentful Paint onFCP(console.log); // First Contentful Paint
getTTFB(console.log); // Time to First Byte onTTFB(console.log); // Time to First Byte
``` ```
## パフォーマンスレポートテンプレート ## パフォーマンスレポートテンプレート
@@ -393,7 +393,7 @@ getTTFB(console.log); // Time to First Byte
| メトリクス | 現在 | 目標 | ステータス | | メトリクス | 現在 | 目標 | ステータス |
|-----------|------|------|----------| |-----------|------|------|----------|
| LCP | X.X秒 | < 2.5秒 | PASS: | | LCP | X.X秒 | < 2.5秒 | PASS: |
| FID | XXms | < 100ms | PASS: | | INP | XXms | < 200ms | PASS: |
| CLS | X.XX | < 0.1 | WARNING: | | CLS | X.XX | < 0.1 | WARNING: |
## 重大な問題 ## 重大な問題
+3 -3
View File
@@ -7,12 +7,12 @@
- ペアプログラミングとコード生成 - ペアプログラミングとコード生成
- マルチ agent システムのワーカー agent - マルチ agent システムのワーカー agent
**Sonnet 4.5**(最高のコーディングモデル): **Sonnet 4.6**(最高のコーディングモデル):
- メイン開発作業 - メイン開発作業
- マルチ agent ワークフローのオーケストレーション - マルチ agent ワークフローのオーケストレーション
- 複雑なコーディングタスク - 複雑なコーディングタスク
**Opus 4.5**(最も深い推論): **Opus 4.6**(最も深い推論):
- 複雑なアーキテクチャの意思決定 - 複雑なアーキテクチャの意思決定
- 最大限の推論要件 - 最大限の推論要件
- 調査と分析タスク - 調査と分析タスク
@@ -37,7 +37,7 @@
拡張思考の制御: 拡張思考の制御:
- **トグル**: Option+TmacOS/ Alt+TWindows/Linux - **トグル**: Option+TmacOS/ Alt+TWindows/Linux
- **設定**: `~/.claude/settings.json``alwaysThinkingEnabled` を設定 - **設定**: `~/.claude/settings.json``alwaysThinkingEnabled` を設定
- **予算上限**: `export MAX_THINKING_TOKENS=10000` - **予算上限**: `export MAX_THINKING_TOKENS=10000`bash)または `$env:MAX_THINKING_TOKENS = "10000"`PowerShell
- **詳細モード**: Ctrl+O で思考出力を表示 - **詳細モード**: Ctrl+O で思考出力を表示
深い推論を必要とする複雑なタスクの場合: 深い推論を必要とする複雑なタスクの場合:
+2 -2
View File
@@ -16,10 +16,10 @@ paths:
const apiKey = "sk-proj-xxxxx" const apiKey = "sk-proj-xxxxx"
// 常に: 環境変数 // 常に: 環境変数
const apiKey = process.env.OPENAI_API_KEY const apiKey = process.env.API_KEY
if (!apiKey) { if (!apiKey) {
throw new Error('OPENAI_API_KEY not configured') throw new Error('API_KEY not configured')
} }
``` ```
+21 -7
View File
@@ -158,28 +158,41 @@ export function useQuery<T>(
const [error, setError] = useState<Error | null>(null) const [error, setError] = useState<Error | null>(null)
const [loading, setLoading] = useState(false) const [loading, setLoading] = useState(false)
// Keep the latest fetcher/options in refs so refetch stays referentially
// stable even when callers pass inline functions and object literals.
// Without this, every render creates a new refetch, and the effect below
// re-runs after each state update - an infinite fetch loop.
const fetcherRef = useRef(fetcher)
const optionsRef = useRef(options)
useEffect(() => {
fetcherRef.current = fetcher
optionsRef.current = options
})
const refetch = useCallback(async () => { const refetch = useCallback(async () => {
setLoading(true) setLoading(true)
setError(null) setError(null)
try { try {
const result = await fetcher() const result = await fetcherRef.current()
setData(result) setData(result)
options?.onSuccess?.(result) optionsRef.current?.onSuccess?.(result)
} catch (err) { } catch (err) {
const error = err as Error const error = err as Error
setError(error) setError(error)
options?.onError?.(error) optionsRef.current?.onError?.(error)
} finally { } finally {
setLoading(false) setLoading(false)
} }
}, [fetcher, options]) }, [])
const enabled = options?.enabled !== false
useEffect(() => { useEffect(() => {
if (options?.enabled !== false) { if (enabled) {
refetch() refetch()
} }
}, [key, refetch, options?.enabled]) }, [key, enabled, refetch])
return { data, error, loading, refetch } return { data, error, loading, refetch }
} }
@@ -284,8 +297,9 @@ export function useMarkets() {
```typescript ```typescript
// PASS: useMemo for expensive computations // PASS: useMemo for expensive computations
// Copy before sorting - Array.prototype.sort mutates in place
const sortedMarkets = useMemo(() => { const sortedMarkets = useMemo(() => {
return markets.sort((a, b) => b.volume - a.volume) return [...markets].sort((a, b) => b.volume - a.volume)
}, [markets]) }, [markets])
// PASS: useCallback for functions passed to children // PASS: useCallback for functions passed to children
+2 -2
View File
@@ -56,14 +56,14 @@ Pythonは条件チェックよりも例外処理を好みます。
```python ```python
# Good: EAFP style # Good: EAFP style
def get_value(dictionary: dict, key: str) -> Any: def get_value(dictionary: dict, key: str, default_value: Any = None) -> Any:
try: try:
return dictionary[key] return dictionary[key]
except KeyError: except KeyError:
return default_value return default_value
# Bad: LBYL (Look Before You Leap) style # Bad: LBYL (Look Before You Leap) style
def get_value(dictionary: dict, key: str) -> Any: def get_value(dictionary: dict, key: str, default_value: Any = None) -> Any:
if key in dictionary: if key in dictionary:
return dictionary[key] return dictionary[key]
else: else:
+2 -2
View File
@@ -12,7 +12,7 @@
- 멀티 에이전트 워크플로우 오케스트레이션 - 멀티 에이전트 워크플로우 오케스트레이션
- 복잡한 코딩 작업 - 복잡한 코딩 작업
**Opus 4.5** (가장 깊은 추론): **Opus 4.6** (가장 깊은 추론):
- 복잡한 아키텍처 의사결정 - 복잡한 아키텍처 의사결정
- 최대 추론 요구사항 - 최대 추론 요구사항
- 리서치 및 분석 작업 - 리서치 및 분석 작업
@@ -37,7 +37,7 @@
확장 사고 제어 방법: 확장 사고 제어 방법:
- **전환**: Option+T (macOS) / Alt+T (Windows/Linux) - **전환**: Option+T (macOS) / Alt+T (Windows/Linux)
- **설정**: `~/.claude/settings.json`에서 `alwaysThinkingEnabled` 설정 - **설정**: `~/.claude/settings.json`에서 `alwaysThinkingEnabled` 설정
- **예산 제한**: `export MAX_THINKING_TOKENS=10000` - **예산 제한**: `export MAX_THINKING_TOKENS=10000` (bash) 또는 `$env:MAX_THINKING_TOKENS = "10000"` (PowerShell)
- **상세 모드**: Ctrl+O로 사고 출력 확인 - **상세 모드**: Ctrl+O로 사고 출력 확인
깊은 추론이 필요한 복잡한 작업: 깊은 추론이 필요한 복잡한 작업:
+2 -2
View File
@@ -12,7 +12,7 @@
- Orquestrando fluxos de trabalho multi-agente - Orquestrando fluxos de trabalho multi-agente
- Tarefas de codificação complexas - Tarefas de codificação complexas
**Opus 4.5** (Raciocínio mais profundo): **Opus 4.6** (Raciocínio mais profundo):
- Decisões arquiteturais complexas - Decisões arquiteturais complexas
- Requisitos máximos de raciocínio - Requisitos máximos de raciocínio
- Pesquisa e análise - Pesquisa e análise
@@ -37,7 +37,7 @@ O pensamento estendido está habilitado por padrão, reservando até 31.999 toke
Controle o pensamento estendido via: Controle o pensamento estendido via:
- **Toggle**: Option+T (macOS) / Alt+T (Windows/Linux) - **Toggle**: Option+T (macOS) / Alt+T (Windows/Linux)
- **Config**: Defina `alwaysThinkingEnabled` em `~/.claude/settings.json` - **Config**: Defina `alwaysThinkingEnabled` em `~/.claude/settings.json`
- **Limite de orçamento**: `export MAX_THINKING_TOKENS=10000` - **Limite de orçamento**: `export MAX_THINKING_TOKENS=10000` (bash) ou `$env:MAX_THINKING_TOKENS = "10000"` (PowerShell)
- **Modo verbose**: Ctrl+O para ver a saída de pensamento - **Modo verbose**: Ctrl+O para ver a saída de pensamento
Para tarefas complexas que requerem raciocínio profundo: Para tarefas complexas que requerem raciocínio profundo:
+2 -2
View File
@@ -12,7 +12,7 @@
- Multi-agent iş akışlarını orkestrasyon - Multi-agent iş akışlarını orkestrasyon
- Karmaşık kodlama görevleri - Karmaşık kodlama görevleri
**Opus 4.5** (En derin akıl yürütme): **Opus 4.6** (En derin akıl yürütme):
- Karmaşık mimari kararlar - Karmaşık mimari kararlar
- Maksimum akıl yürütme gereksinimleri - Maksimum akıl yürütme gereksinimleri
- Araştırma ve analiz görevleri - Araştırma ve analiz görevleri
@@ -37,7 +37,7 @@ Extended thinking varsayılan olarak etkindir ve dahili akıl yürütme için 31
Extended thinking kontrolü: Extended thinking kontrolü:
- **Toggle**: Option+T (macOS) / Alt+T (Windows/Linux) - **Toggle**: Option+T (macOS) / Alt+T (Windows/Linux)
- **Config**: `~/.claude/settings.json` içinde `alwaysThinkingEnabled` ayarla - **Config**: `~/.claude/settings.json` içinde `alwaysThinkingEnabled` ayarla
- **Budget cap**: `export MAX_THINKING_TOKENS=10000` - **Budget cap**: `export MAX_THINKING_TOKENS=10000` (bash) veya `$env:MAX_THINKING_TOKENS = "10000"` (PowerShell)
- **Verbose mode**: Thinking çıktısını görmek için Ctrl+O - **Verbose mode**: Thinking çıktısını görmek için Ctrl+O
Derin akıl yürütme gerektiren karmaşık görevler için: Derin akıl yürütme gerektiren karmaşık görevler için:
+2 -2
View File
@@ -16,10 +16,10 @@ paths:
const apiKey = "sk-proj-xxxxx" const apiKey = "sk-proj-xxxxx"
// DAIMA: Environment variable'lar // DAIMA: Environment variable'lar
const apiKey = process.env.OPENAI_API_KEY const apiKey = process.env.API_KEY
if (!apiKey) { if (!apiKey) {
throw new Error('OPENAI_API_KEY not configured') throw new Error('API_KEY not configured')
} }
``` ```
+22 -7
View File
@@ -169,28 +169,42 @@ export function useQuery<T>(
const [error, setError] = useState<Error | null>(null) const [error, setError] = useState<Error | null>(null)
const [loading, setLoading] = useState(false) const [loading, setLoading] = useState(false)
// Çağıranlar satır içi fonksiyonlar ve nesne literalleri geçirse bile
// refetch'in referans olarak kararlı kalması için en güncel fetcher/options
// değerlerini ref'lerde tutun. Bu olmadan her render yeni bir refetch
// oluşturur ve aşağıdaki effect her state güncellemesinden sonra yeniden
// çalışır - sonsuz bir fetch döngüsü.
const fetcherRef = useRef(fetcher)
const optionsRef = useRef(options)
useEffect(() => {
fetcherRef.current = fetcher
optionsRef.current = options
})
const refetch = useCallback(async () => { const refetch = useCallback(async () => {
setLoading(true) setLoading(true)
setError(null) setError(null)
try { try {
const result = await fetcher() const result = await fetcherRef.current()
setData(result) setData(result)
options?.onSuccess?.(result) optionsRef.current?.onSuccess?.(result)
} catch (err) { } catch (err) {
const error = err as Error const error = err as Error
setError(error) setError(error)
options?.onError?.(error) optionsRef.current?.onError?.(error)
} finally { } finally {
setLoading(false) setLoading(false)
} }
}, [fetcher, options]) }, [])
const enabled = options?.enabled !== false
useEffect(() => { useEffect(() => {
if (options?.enabled !== false) { if (enabled) {
refetch() refetch()
} }
}, [key, refetch, options?.enabled]) }, [key, enabled, refetch])
return { data, error, loading, refetch } return { data, error, loading, refetch }
} }
@@ -295,8 +309,9 @@ export function useMarkets() {
```typescript ```typescript
// PASS: Pahalı hesaplamalar için useMemo // PASS: Pahalı hesaplamalar için useMemo
// Sıralamadan önce kopyalayın - Array.prototype.sort yerinde değiştirir
const sortedMarkets = useMemo(() => { const sortedMarkets = useMemo(() => {
return markets.sort((a, b) => b.volume - a.volume) return [...markets].sort((a, b) => b.volume - a.volume)
}, [markets]) }, [markets])
// PASS: Alt bileşenlere geçirilen fonksiyonlar için useCallback // PASS: Alt bileşenlere geçirilen fonksiyonlar için useCallback
+2 -2
View File
@@ -57,14 +57,14 @@ Python, koşulları kontrol etmek yerine exception handling'i tercih eder.
```python ```python
# İyi: EAFP stili # İyi: EAFP stili
def get_value(dictionary: dict, key: str) -> Any: def get_value(dictionary: dict, key: str, default_value: Any = None) -> Any:
try: try:
return dictionary[key] return dictionary[key]
except KeyError: except KeyError:
return default_value return default_value
# Kötü: LBYL (Atlamadan Önce Bak) stili # Kötü: LBYL (Atlamadan Önce Bak) stili
def get_value(dictionary: dict, key: str) -> Any: def get_value(dictionary: dict, key: str, default_value: Any = None) -> Any:
if key in dictionary: if key in dictionary:
return dictionary[key] return dictionary[key]
else: else:
+8 -8
View File
@@ -353,14 +353,14 @@ npx lighthouse https://your-app.com --only-categories=performance
### Web Vitals 监控 ### Web Vitals 监控
```typescript ```typescript
// Track Core Web Vitals // Track Core Web Vitals (web-vitals v4 API)
import { getCLS, getFID, getLCP, getFCP, getTTFB } from 'web-vitals'; import { onCLS, onINP, onLCP, onFCP, onTTFB } from 'web-vitals';
getCLS(console.log); // Cumulative Layout Shift onCLS(console.log); // Cumulative Layout Shift
getFID(console.log); // First Input Delay onINP(console.log); // Interaction to Next Paint
getLCP(console.log); // Largest Contentful Paint onLCP(console.log); // Largest Contentful Paint
getFCP(console.log); // First Contentful Paint onFCP(console.log); // First Contentful Paint
getTTFB(console.log); // Time to First Byte onTTFB(console.log); // Time to First Byte
``` ```
## 性能报告模板 ## 性能报告模板
@@ -384,7 +384,7 @@ getTTFB(console.log); // Time to First Byte
| 指标 | 当前值 | 目标值 | 状态 | | 指标 | 当前值 | 目标值 | 状态 |
|--------|---------|--------|--------| |--------|---------|--------|--------|
| LCP | X.X秒 | < 2.5秒 | 通过: | | LCP | X.X秒 | < 2.5秒 | 通过: |
| FID | XX毫秒 | < 100毫秒 | 通过: | | INP | XX毫秒 | < 200毫秒 | 通过: |
| CLS | X.XX | < 0.1 | 警告: | | CLS | X.XX | < 0.1 | 警告: |
## 关键问题 ## 关键问题
+2 -2
View File
@@ -14,7 +14,7 @@
* 编排多智能体工作流 * 编排多智能体工作流
* 复杂的编码任务 * 复杂的编码任务
**Opus 4.5** (最深的推理能力): **Opus 4.6** (最深的推理能力):
* 复杂的架构决策 * 复杂的架构决策
* 最高级别的推理需求 * 最高级别的推理需求
@@ -43,7 +43,7 @@
* **切换**Option+T (macOS) / Alt+T (Windows/Linux) * **切换**Option+T (macOS) / Alt+T (Windows/Linux)
* **配置**:在 `~/.claude/settings.json` 中设置 `alwaysThinkingEnabled` * **配置**:在 `~/.claude/settings.json` 中设置 `alwaysThinkingEnabled`
* **预算上限**`export MAX_THINKING_TOKENS=10000` * **预算上限**`export MAX_THINKING_TOKENS=10000`bash)或 `$env:MAX_THINKING_TOKENS = "10000"`PowerShell
* **详细模式**:Ctrl+O 查看思考输出 * **详细模式**:Ctrl+O 查看思考输出
对于需要深度推理的复杂任务: 对于需要深度推理的复杂任务:
+2 -2
View File
@@ -17,10 +17,10 @@ paths:
const apiKey = "sk-proj-xxxxx" const apiKey = "sk-proj-xxxxx"
// ALWAYS: Environment variables // ALWAYS: Environment variables
const apiKey = process.env.OPENAI_API_KEY const apiKey = process.env.API_KEY
if (!apiKey) { if (!apiKey) {
throw new Error('OPENAI_API_KEY not configured') throw new Error('API_KEY not configured')
} }
``` ```
+2 -1
View File
@@ -400,8 +400,9 @@ export async function searchMarkets(
import { useMemo, useCallback } from 'react' import { useMemo, useCallback } from 'react'
// PASS: GOOD: Memoize expensive computations // PASS: GOOD: Memoize expensive computations
// Copy before sorting - Array.prototype.sort mutates in place
const sortedMarkets = useMemo(() => { const sortedMarkets = useMemo(() => {
return markets.sort((a, b) => b.volume - a.volume) return [...markets].sort((a, b) => b.volume - a.volume)
}, [markets]) }, [markets])
// PASS: GOOD: Memoize callbacks // PASS: GOOD: Memoize callbacks
+21 -7
View File
@@ -169,28 +169,41 @@ export function useQuery<T>(
const [error, setError] = useState<Error | null>(null) const [error, setError] = useState<Error | null>(null)
const [loading, setLoading] = useState(false) const [loading, setLoading] = useState(false)
// Keep the latest fetcher/options in refs so refetch stays referentially
// stable even when callers pass inline functions and object literals.
// Without this, every render creates a new refetch, and the effect below
// re-runs after each state update - an infinite fetch loop.
const fetcherRef = useRef(fetcher)
const optionsRef = useRef(options)
useEffect(() => {
fetcherRef.current = fetcher
optionsRef.current = options
})
const refetch = useCallback(async () => { const refetch = useCallback(async () => {
setLoading(true) setLoading(true)
setError(null) setError(null)
try { try {
const result = await fetcher() const result = await fetcherRef.current()
setData(result) setData(result)
options?.onSuccess?.(result) optionsRef.current?.onSuccess?.(result)
} catch (err) { } catch (err) {
const error = err as Error const error = err as Error
setError(error) setError(error)
options?.onError?.(error) optionsRef.current?.onError?.(error)
} finally { } finally {
setLoading(false) setLoading(false)
} }
}, [fetcher, options]) }, [])
const enabled = options?.enabled !== false
useEffect(() => { useEffect(() => {
if (options?.enabled !== false) { if (enabled) {
refetch() refetch()
} }
}, [key, refetch, options?.enabled]) }, [key, enabled, refetch])
return { data, error, loading, refetch } return { data, error, loading, refetch }
} }
@@ -295,8 +308,9 @@ export function useMarkets() {
```typescript ```typescript
// PASS: useMemo for expensive computations // PASS: useMemo for expensive computations
// Copy before sorting - Array.prototype.sort mutates in place
const sortedMarkets = useMemo(() => { const sortedMarkets = useMemo(() => {
return markets.sort((a, b) => b.volume - a.volume) return [...markets].sort((a, b) => b.volume - a.volume)
}, [markets]) }, [markets])
// PASS: useCallback for functions passed to children // PASS: useCallback for functions passed to children
+2 -2
View File
@@ -57,14 +57,14 @@ Python 倾向于使用异常处理而非检查条件。
```python ```python
# Good: EAFP style # Good: EAFP style
def get_value(dictionary: dict, key: str) -> Any: def get_value(dictionary: dict, key: str, default_value: Any = None) -> Any:
try: try:
return dictionary[key] return dictionary[key]
except KeyError: except KeyError:
return default_value return default_value
# Bad: LBYL (Look Before You Leap) style # Bad: LBYL (Look Before You Leap) style
def get_value(dictionary: dict, key: str) -> Any: def get_value(dictionary: dict, key: str, default_value: Any = None) -> Any:
if key in dictionary: if key in dictionary:
return dictionary[key] return dictionary[key]
else: else:
+2 -2
View File
@@ -7,12 +7,12 @@
- 配對程式設計和程式碼產生 - 配對程式設計和程式碼產生
- 多 agent 系統中的 worker agents - 多 agent 系統中的 worker agents
**Sonnet 4.5**(最佳程式碼模型): **Sonnet 4.6**(最佳程式碼模型):
- 主要開發工作 - 主要開發工作
- 協調多 agent 工作流程 - 協調多 agent 工作流程
- 複雜程式碼任務 - 複雜程式碼任務
**Opus 4.5**(最深度推理): **Opus 4.6**(最深度推理):
- 複雜架構決策 - 複雜架構決策
- 最大推理需求 - 最大推理需求
- 研究和分析任務 - 研究和分析任務
+21 -7
View File
@@ -158,28 +158,41 @@ export function useQuery<T>(
const [error, setError] = useState<Error | null>(null) const [error, setError] = useState<Error | null>(null)
const [loading, setLoading] = useState(false) const [loading, setLoading] = useState(false)
// 將最新的 fetcher/options 保存在 ref 中,讓 refetch 即使在呼叫端
// 傳入行內函式與物件字面值時也能保持參照穩定。
// 若沒有這麼做,每次渲染都會建立新的 refetch,下方的 effect 會在
// 每次狀態更新後重新執行,造成無限取得迴圈。
const fetcherRef = useRef(fetcher)
const optionsRef = useRef(options)
useEffect(() => {
fetcherRef.current = fetcher
optionsRef.current = options
})
const refetch = useCallback(async () => { const refetch = useCallback(async () => {
setLoading(true) setLoading(true)
setError(null) setError(null)
try { try {
const result = await fetcher() const result = await fetcherRef.current()
setData(result) setData(result)
options?.onSuccess?.(result) optionsRef.current?.onSuccess?.(result)
} catch (err) { } catch (err) {
const error = err as Error const error = err as Error
setError(error) setError(error)
options?.onError?.(error) optionsRef.current?.onError?.(error)
} finally { } finally {
setLoading(false) setLoading(false)
} }
}, [fetcher, options]) }, [])
const enabled = options?.enabled !== false
useEffect(() => { useEffect(() => {
if (options?.enabled !== false) { if (enabled) {
refetch() refetch()
} }
}, [key, refetch, options?.enabled]) }, [key, enabled, refetch])
return { data, error, loading, refetch } return { data, error, loading, refetch }
} }
@@ -284,8 +297,9 @@ export function useMarkets() {
```typescript ```typescript
// PASS: useMemo 用於昂貴計算 // PASS: useMemo 用於昂貴計算
// 排序前先複製 - Array.prototype.sort 會就地修改陣列
const sortedMarkets = useMemo(() => { const sortedMarkets = useMemo(() => {
return markets.sort((a, b) => b.volume - a.volume) return [...markets].sort((a, b) => b.volume - a.volume)
}, [markets]) }, [markets])
// PASS: useCallback 用於傳遞給子元件的函式 // PASS: useCallback 用於傳遞給子元件的函式
+2 -2
View File
@@ -12,7 +12,7 @@
- Orchestrating multi-agent workflows - Orchestrating multi-agent workflows
- Complex coding tasks - Complex coding tasks
**Opus 4.5** (Deepest reasoning): **Opus 4.6** (Deepest reasoning):
- Complex architectural decisions - Complex architectural decisions
- Maximum reasoning requirements - Maximum reasoning requirements
- Research and analysis tasks - Research and analysis tasks
@@ -37,7 +37,7 @@ Extended thinking is enabled by default, reserving up to 31,999 tokens for inter
Control extended thinking via: Control extended thinking via:
- **Toggle**: Option+T (macOS) / Alt+T (Windows/Linux) - **Toggle**: Option+T (macOS) / Alt+T (Windows/Linux)
- **Config**: Set `alwaysThinkingEnabled` in `~/.claude/settings.json` - **Config**: Set `alwaysThinkingEnabled` in `~/.claude/settings.json`
- **Budget cap**: `export MAX_THINKING_TOKENS=10000` - **Budget cap**: `export MAX_THINKING_TOKENS=10000` (bash) or `$env:MAX_THINKING_TOKENS = "10000"` (PowerShell)
- **Verbose mode**: Ctrl+O to see thinking output - **Verbose mode**: Ctrl+O to see thinking output
For complex tasks requiring deep reasoning: For complex tasks requiring deep reasoning:
+2 -2
View File
@@ -16,10 +16,10 @@ paths:
const apiKey = "sk-proj-xxxxx" const apiKey = "sk-proj-xxxxx"
// ALWAYS: Environment variables // ALWAYS: Environment variables
const apiKey = process.env.OPENAI_API_KEY const apiKey = process.env.API_KEY
if (!apiKey) { if (!apiKey) {
throw new Error('OPENAI_API_KEY not configured') throw new Error('API_KEY not configured')
} }
``` ```
+2 -1
View File
@@ -415,8 +415,9 @@ export async function searchMarkets(
import { useMemo, useCallback } from 'react' import { useMemo, useCallback } from 'react'
// PASS: GOOD: Memoize expensive computations // PASS: GOOD: Memoize expensive computations
// Copy before sorting - Array.prototype.sort mutates in place
const sortedMarkets = useMemo(() => { const sortedMarkets = useMemo(() => {
return markets.sort((a, b) => b.volume - a.volume) return [...markets].sort((a, b) => b.volume - a.volume)
}, [markets]) }, [markets])
// PASS: GOOD: Memoize callbacks // PASS: GOOD: Memoize callbacks
+21 -7
View File
@@ -169,28 +169,41 @@ export function useQuery<T>(
const [error, setError] = useState<Error | null>(null) const [error, setError] = useState<Error | null>(null)
const [loading, setLoading] = useState(false) const [loading, setLoading] = useState(false)
// Keep the latest fetcher/options in refs so refetch stays referentially
// stable even when callers pass inline functions and object literals.
// Without this, every render creates a new refetch, and the effect below
// re-runs after each state update - an infinite fetch loop.
const fetcherRef = useRef(fetcher)
const optionsRef = useRef(options)
useEffect(() => {
fetcherRef.current = fetcher
optionsRef.current = options
})
const refetch = useCallback(async () => { const refetch = useCallback(async () => {
setLoading(true) setLoading(true)
setError(null) setError(null)
try { try {
const result = await fetcher() const result = await fetcherRef.current()
setData(result) setData(result)
options?.onSuccess?.(result) optionsRef.current?.onSuccess?.(result)
} catch (err) { } catch (err) {
const error = err as Error const error = err as Error
setError(error) setError(error)
options?.onError?.(error) optionsRef.current?.onError?.(error)
} finally { } finally {
setLoading(false) setLoading(false)
} }
}, [fetcher, options]) }, [])
const enabled = options?.enabled !== false
useEffect(() => { useEffect(() => {
if (options?.enabled !== false) { if (enabled) {
refetch() refetch()
} }
}, [key, refetch, options?.enabled]) }, [key, enabled, refetch])
return { data, error, loading, refetch } return { data, error, loading, refetch }
} }
@@ -295,8 +308,9 @@ export function useMarkets() {
```typescript ```typescript
// PASS: useMemo for expensive computations // PASS: useMemo for expensive computations
// Copy before sorting - Array.prototype.sort mutates in place
const sortedMarkets = useMemo(() => { const sortedMarkets = useMemo(() => {
return markets.sort((a, b) => b.volume - a.volume) return [...markets].sort((a, b) => b.volume - a.volume)
}, [markets]) }, [markets])
// PASS: useCallback for functions passed to children // PASS: useCallback for functions passed to children
+2 -2
View File
@@ -57,14 +57,14 @@ Python prefers exception handling over checking conditions.
```python ```python
# Good: EAFP style # Good: EAFP style
def get_value(dictionary: dict, key: str) -> Any: def get_value(dictionary: dict, key: str, default_value: Any = None) -> Any:
try: try:
return dictionary[key] return dictionary[key]
except KeyError: except KeyError:
return default_value return default_value
# Bad: LBYL (Look Before You Leap) style # Bad: LBYL (Look Before You Leap) style
def get_value(dictionary: dict, key: str) -> Any: def get_value(dictionary: dict, key: str, default_value: Any = None) -> Any:
if key in dictionary: if key in dictionary:
return dictionary[key] return dictionary[key]
else: else: