code-antipatterns-analysis について
code-antipatterns-analysisは、ast-grepでコードのアンチパターンや品質上の問題を分析するスキルです。コードレビューや検出ルールの設計向けに複数の言語・問題領域を扱い、並列エージェントで調査して優先度別にまとめる方法を示します。
主な機能
- 01ast-grepのアンチパターン検索例
- 02複数言語とフレームワークの問題を網羅
- 03並列エージェントによる分析手法
- 04指摘の優先順位付けと修正提案
- 05YAML検出ルールの例
活用シーン
- 01コードスキャンルールの設計・拡張
- 02非同期処理やエラー処理の問題確認
- 03セキュリティ・性能・保守性リスクの監査
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ laurigates/ claude-plugins --skill code-antipatterns-analysisインストール後、Claude Code で/code-antipatterns-analysisを入力して読み込まれたか確認します。
同梱ファイルREFERENCE.md
詳細
コードのアンチパターン分析
このスキルを使用する場面
| 次のような場合にこのスキルを使用します... | 次のような場合は別のものを使用します... |
|---|---|
| スキャンを作成するために ast-grep のアンチパターンクエリのカタログが必要な場合 | ユーザーが直接実行できるスキャナーを実行する場合 → code-antipatterns |
| 並列委任によるアンチパターン検出を設計または拡張する場合 | ast-grep のパターン構文自体を調べる場合 → ast-grep-search |
| エラーの握りつぶしに特化して監査する場合 | 専用スキャナーを使用します → code-error-swallowing |
| より広範なレビューのために品質上の問題をカタログ化する場合 | コードレビュー全体を実行する場合 → code-review |
ast-grep とエージェントへの並列委任を使用して、コードベース全体のアンチパターン、コードの臭い、品質上の問題を体系的に検出・分析するための専門知識です。
分析の方針
このスキルでは、包括的な分析のために並列委任を重視します。問題を順番にスキャンするのではなく、複数の専門エージェントを同時に起動して異なるカテゴリを調査し、その後、検出結果を統合します。
分析カテゴリ
1. JavaScript/TypeScript のアンチパターン
コールバック地獄と非同期処理の問題
# Nested callbacks (3+ levels)
ast-grep -p '$FUNC($$$, function($$$) { $FUNC2($$$, function($$$) { $$$ }) })' --lang js
# Missing error handling in async
ast-grep -p 'async function $NAME($$$) { $$$ }' --lang js
# Then check if try-catch is present
# Unhandled promise rejection
ast-grep -p '$PROMISE.then($$$)' --lang js
# Without .catch() - use composite rule
マジック値
# Magic numbers in comparisons
ast-grep -p 'if ($VAR > 100)' --lang js
ast-grep -p 'if ($VAR < 50)' --lang js
ast-grep -p 'if ($VAR === 42)' --lang js
# Magic strings
ast-grep -p "if ($VAR === 'admin')" --lang js
空の catch ブロック
ast-grep -p 'try { $$$ } catch ($E) { }' --lang js
console 文(デバッグ用コードの残存)
ast-grep -p 'console.log($$$)' --lang js
ast-grep -p 'console.debug($$$)' --lang js
ast-grep -p 'console.warn($$$)' --lang js
変数宣言には let/const を使用する
ast-grep -p 'var $VAR = $$$' --lang js
2. Vue 3 のアンチパターン
props の変更
# YAML rule for props mutation detection
id: vue-props-mutation
language: JavaScript
message: Use computed properties or emit events to update props
rule:
pattern: props.$PROP = $VALUE
# Direct prop assignment
ast-grep -p 'props.$PROP = $VALUE' --lang js
v-for のキー不足
# Search in Vue templates
ast-grep -p 'v-for="$ITEM in $LIST"' --lang html
# Check if :key is present nearby
Composition API のコードベースで Options API を使用
# Find Options API usage
ast-grep -p 'export default { data() { $$$ } }' --lang js
ast-grep -p 'export default { methods: { $$$ } }' --lang js
ast-grep -p 'export default { computed: { $$$ } }' --lang js
# vs Composition API
ast-grep -p 'defineComponent({ setup($$$) { $$$ } })' --lang js
リアクティブな状態の問題
# Destructuring reactive state (loses reactivity)
ast-grep -p 'const { $$$PROPS } = $REACTIVE' --lang js
# Should use toRefs
ast-grep -p 'const { $$$PROPS } = toRefs($REACTIVE)' --lang js
3. TypeScript の品質上の問題
any の過剰な使用
ast-grep -p ': any' --lang ts
ast-grep -p 'as any' --lang ts
ast-grep -p '<any>' --lang ts
非 null アサーション
ast-grep -p '$VAR!' --lang ts
ast-grep -p '$VAR!.$PROP' --lang ts
型ガードの代わりに型アサーションを使用
ast-grep -p '$VAR as $TYPE' --lang ts
戻り値の型の不足
# Functions without return type annotations
ast-grep -p 'function $NAME($$$) { $$$ }' --lang ts
# Check if return type is present
4. 非同期処理/Promise のパターン
未処理の Promise
# Promise without await or .then/.catch
ast-grep -p '$ASYNC_FUNC($$$)' --lang js
# Context: check if result is used
# Floating promises (no await)
ast-grep -p '$PROMISE_RETURNING()' --lang ts
ネストしたコールバック(破滅のピラミッド)
ast-grep -p '$F1($$$, function($$$) { $F2($$$, function($$$) { $F3($$$, function($$$) { $$$ }) }) })' --lang js
Promise コンストラクターのアンチパターン
# Wrapping already-async code in new Promise
ast-grep -p 'new Promise(($RESOLVE, $REJECT) => { $ASYNC_FUNC($$$).then($$$) })' --lang js
5. コードの複雑さ
長い関数(手動レビュー)
# Find function definitions, then count lines
ast-grep -p 'function $NAME($$$) { $$$ }' --lang js --json | jq '.[] | select(.range.end.line - .range.start.line > 50)'
深いネスト
# Nested if statements (4+ levels)
ast-grep -p 'if ($A) { if ($B) { if ($C) { if ($D) { $$$ } } } }' --lang js
パラメーター数が多い
ast-grep -p 'function $NAME($A, $B, $C, $D, $E, $$$)' --lang js
循環的複雑度の指標
# Multiple conditionals in single function
ast-grep -p 'if ($$$) { $$$ } else if ($$$) { $$$ } else if ($$$) { $$$ }' --lang js
6. React/Pinia ストアのパターン
状態の直接変更(Pinia)
# Direct store state mutation outside actions
ast-grep -p '$STORE.$STATE = $VALUE' --lang js
useEffect の依存関係不足
ast-grep -p 'useEffect(() => { $$$ }, [])' --lang jsx
# Check if variables used inside are in dependency array
JSX 内のインライン関数
ast-grep -p '<$COMPONENT onClick={() => $$$} />' --lang jsx
ast-grep -p '<$COMPONENT onChange={() => $$$} />' --lang jsx
7. メモリとパフォーマンス
クリーンアップされないイベントリスナー
ast-grep -p 'addEventListener($EVENT, $HANDLER)' --lang js
# Check for corresponding removeEventListener
クリーンアップされない setInterval
ast-grep -p 'setInterval($$$)' --lang js
# Check for clearInterval
computed/メモ化処理内の大きな配列
ast-grep -p 'computed(() => $ARRAY.filter($$$))' --lang js
ast-grep -p 'useMemo(() => $ARRAY.filter($$$), [$$$])' --lang jsx
8. セキュリティ上の懸念
eval の使用
ast-grep -p 'eval($$$)' --lang js
ast-grep -p 'new Function($$$)' --lang js
innerHTML への代入(XSS のリスク)
ast-grep -p '$ELEM.innerHTML = $$$' --lang js
ast-grep -p 'dangerouslySetInnerHTML={{ __html: $$$ }}' --lang jsx
ハードコードされたシークレット
ast-grep -p "apiKey: '$$$'" --lang js
ast-grep -p "password = '$$$'" --lang js
ast-grep -p "secret: '$$$'" --lang js
SQL 文字列の連結
ast-grep -p '"SELECT * FROM " + $VAR' --lang js
ast-grep -p '`SELECT * FROM ${$VAR}`' --lang js
9. Python のアンチパターン
例外の型を指定しない except
ast-grep -p 'except: $$$' --lang py
変更可能なデフォルト引数
ast-grep -p 'def $FUNC($ARG=[])' --lang py
ast-grep -p 'def $FUNC($ARG={})' --lang py
グローバル変数の使用
ast-grep -p 'global $VAR' --lang py
理由のない Type: ignore
# Search in comments via grep
grep -r "# type: ignore$" --include="*.py"
並列分析の戦略
コードベースを分析する際は、効率を最大化するために複数のエージェントを並列で起動します。
エージェント委任パターン
1. **Language Detection Agent** (Explore)
- Detect project languages and frameworks
- Identify relevant file patterns
2. **JavaScript/TypeScript Agent** (code-analysis or Explore)
- JS anti-patterns
- TypeScript quality issues
- Async/Promise patterns
3. **Framework-Specific Agent** (code-analysis or Explore)
- Vue 3 anti-patterns (if Vue detected)
- React anti-patterns (if React detected)
- Pinia/Redux patterns (if detected)
4. **Security Agent** (security-audit)
- Security concerns
- Hardcoded values
- Injection risks
5. **Complexity Agent** (code-analysis or Explore)
- Code complexity metrics
- Long functions
- Deep nesting
6. **Python Agent** (if Python detected)
- Python anti-patterns
- Type annotation issues
統合
並列分析が完了したら:
- 重大度(critical、high、medium、low)ごとに検出結果を集約します
- カテゴリ(セキュリティ、パフォーマンス、保守性)ごとに分類します
- 実行可能な修正案を提示します
- 影響度に基づいて修正の優先順位を決めます
YAML ルールの例
アンチパターンの完全なルール
id: no-empty-catch
language: JavaScript
severity: warning
message: Empty catch block suppresses errors silently
note: |
Empty catch blocks hide errors and make debugging difficult.
Either log the error, handle it specifically, or re-throw.
rule:
pattern: try { $$$ } catch ($E) { }
fix: |
try { $$$ } catch ($E) {
console.error('Error:', $E);
throw $E;
}
files:
- 'src/**/*.js'
- 'src/**/*.ts'
ignores:
- '**/*.test.js'
- '**/node_modules/**'
Vue の props 変更ルール
id: no-props-mutation
language: JavaScript
severity: error
message: Never mutate props directly - use emit or local copy
rule:
all:
- pattern: props.$PROP = $VALUE
- inside:
kind: function_declaration
note: |
Props should be treated as immutable. To modify data:
1. Emit an event to parent: emit('update:propName', newValue)
2. Create a local ref: const local = ref(props.propName)
コマンドとの連携
このスキルは、次の処理を行う /code:antipatterns コマンドと連携するように設計されています:
- プロジェクトの言語スタックを検出します
- 専門エージェントを並列で起動します
- 検出結果を統合し、優先順位を付けたレポートにまとめます
- 可能な場合は自動修正を提案します
分析のベストプラクティス
- まず言語を検出する - 検出された言語に適したパターンを実行します
- エージェントを並列で使用する - 順番に分析せず、専門のエージェントに委任します
- 深刻度に応じて優先順位を付ける - まずセキュリティ上の問題、次に正確性、最後にスタイルを確認します
- 修正案を提示する - 問題を特定するだけでなく、解決策も提案します
- コンテキストを考慮する - 「アンチパターン」の中には、特定の状況では許容されるものもあります
- テストファイルを個別に確認する - テストコードには異なる基準が適用される場合があります
深刻度レベル
| 深刻度 | 説明 | 例 |
|---|---|---|
| Critical | セキュリティの脆弱性、データ損失のリスク | eval()、SQL インジェクション、ハードコードされたシークレット |
| High | バグ、誤った動作 | Props の変更、未処理の promise、空の catch |
| Medium | 保守性の問題 | マジックナンバー、深いネスト、大きな関数 |
| Low | スタイルや好みに関するもの | var の使用、console.log、インライン関数 |
リソース
- ast-grep ドキュメント: https://ast-grep.github.io/
- ast-grep プレイグラウンド: https://ast-grep.github.io/playground.html
- OWASP Top 10: https://owasp.org/www-project-top-ten/
- クリーンコードの原則: https://clean-code-developer.com/