| name | my-refactor |
| description | Scan a codebase for refactoring opportunities, write a SARIF-compatible report, and register each finding as a GitHub issue labelled by severity, effort, and Fowler category. After issue creation, report the created issues and suggested feature names without choosing an implementation workflow. Use when the user asks to "リファクタリング候補洗い出し", "技術的負債リスト化", "refactor scan", "refactoring issues", or requests surveying a repo for refactor work. Do NOT use for applying refactors, code review of a specific PR (use `my-pr review`), or for fixing a specific bug. |
| argument-hint | [scan] [path] [--dry-run] [--max=N] |
Refactor — 検出と issue 登録
コードベースをスキャンしてリファクタリング候補を検出し、1候補=1 GitHub issue として登録する。登録済み issue の実装ワークフローは、このスキルでは選ばない。
サブコマンド
先頭トークンで分岐する。現時点では scan のみ。
| 先頭トークン | 動作 |
|---|
省略 or scan | scan フロー(Phase S-1 〜 S-5) |
| その他の文字列 | scan の引数(パス)として扱い、scan を実行 |
issue を消化する apply 相当はこのスキルの対象外。検出〜起票までで止め、計画〜実装の進め方は別途選ぶ。
SCAN: 検出と issue 登録
scan の引数
先頭が scan のときは 1 トークン消費し、残りを以下で解釈する。先頭が scan でない場合は $ARGUMENTS 全体を以下で解釈する:
| 引数 | 動作 |
|---|
| (省略) | リポジトリ全体をスキャン、検出したら即 issue 作成 |
パス(例 src/api/) | 指定パス配下のみスキャン |
--dry-run | issue を作成せずレポートのみ出力(プレビュー) |
--max=N | 1回のスキャンで作成する issue 数の上限(既定 10) |
デフォルトは 即作成。プレビューしたいときは --dry-run を明示する。
Phase S-1: 前提条件の確認
S-1-1: リポジトリと gh 認証を確認
git rev-parse --show-toplevel >/dev/null || { echo "Not a git repo"; exit 1; }
gh auth status >/dev/null 2>&1 || { echo "gh not authenticated"; exit 1; }
REPO_ROOT=$(git rev-parse --show-toplevel)
DEFAULT_BRANCH=$(gh repo view --json defaultBranchRef -q .defaultBranchRef.name)
SCAN_OUT_DIR="$REPO_ROOT/.tmp/refactor"
mkdir -p "$SCAN_OUT_DIR"
S-1-2: スコープを決める
- 引数にパスが渡されている → そのパス配下を対象にする(存在しない場合はエラー)
- 引数にパスがない →
$REPO_ROOT 全体を対象にする
巨大リポの場合は git ls-files | wc -l でファイル数を把握し、10,000 を超えるときはユーザーに「対象を絞ることを推奨」と警告する。
S-1-3: ラベルの準備
以下 3 系統のラベルを使う。未作成なら gh label create で作成する(既存ならスキップ)。
| ラベル | 値の例 |
|---|
| 固定 | refactor |
| severity | severity/critical, severity/high, severity/medium, severity/low |
| category | category/extract-function, category/remove-duplication, category/rename, category/move, category/simplify-conditional, category/dead-code, category/encapsulate, category/replace-primitive, category/other |
category は references/catalog.md の一覧から選ぶ。該当なしのときだけ category/other。
S-1-4: 既存 issue を取得(重複回避)
gh issue list --label refactor --state all --limit 500 \
--json number,title,body,labels,state \
> "$SCAN_OUT_DIR/existing-issues.json"
state all にするのは、closed 済み issue の fingerprint と照合して「一度 close した指摘を再提案しない」ためでもある。
取得件数がちょうど 500 件の場合は --limit による打ち切りの可能性がある。その場合は「既存 issue の取得が上限 500 件で打ち切られ、重複判定が不完全な可能性がある」とユーザーに警告する。
Phase S-2: スキャン
読み取り専用で context を汚さないため、Agent ツールで subagent_type=Explore を起動することを推奨する。プロンプトには以下を含める: 対象ディレクトリ、references/catalog.md を読むよう指示、findings フォーマット(references/sarif.md の results[] に対応する項目)。
Explore subagent は Write できない。subagent は所見を構造化テキスト(ruleId、location、指摘対象行、message、severity、effort、approach、risks)で返すだけにする。返ってきた所見を SARIF に整形し findings.sarif.json に書き込むのは main agent の責務。
検出の判断基準
references/catalog.md を読み、以下に該当するものを列挙する:
- 重複(同一ロジックの複数実装)
- 長い関数(行数やネストが深い)
- 巨大クラス・巨大ファイル(責務が混在)
- 命名の不整合(古い名前、誤解を招く名前)
- 不要コード(未使用の関数・import・変数、到達不能分岐)
- 複雑な条件式(深いネスト、否定の否定、マジックナンバー)
- 配置ずれ(使われる場所から遠いモジュールにある)
- プリミティブの乱用(意味を持たない string/int が API に露出)
- 隠れたカップリング(副作用、グローバル状態)
除外: 投機的リファクタ(「将来必要かも」系)、スタイル・フォーマットだけの指摘、LLM 生成コードの重複を無自覚に提案する類のもの。
SARIF 互換の出力
scan 結果は SARIF 2.1.0 互換のサブセットとして "$SCAN_OUT_DIR/findings.sarif.json" に保存する。JSON 構造、level / properties のマッピング、fingerprint の決定的計算規則、severity / effort_minutes の基準は references/sarif.md を読んで従う。findings.sarif.json は scan ごとに上書きする(run history は Git で追う)。
Phase S-3: 重複排除と絞り込み
findings.sarif.json の各 results[] について、partialFingerprints["refactorFingerprint/v1"] を取り出す
existing-issues.json の各 issue 本文から RefactorFingerprint: 行(Phase S-5 で埋め込む)を抽出
- fingerprint が一致する既存 issue(open/closed 問わず)があれば、新規スキャンから除外
- fingerprint が見つからない既存 issue については location + ruleId の一致でフォールバック判定
level 優先(error → warning → note)、同一 level 内は properties.severity(critical → high → medium → low)を第 2 ソートキーにしてソート → --max=N で上位のみ残す(既定 10 件)。critical と high はどちらも level=error に潰れるため、この第 2 キーが必須
level=error かつ properties.severity=critical は --max を超えても残す
Phase S-4: レポート出力
issue を作る前に、必ず標準出力に人間可読なサマリを出す。--dry-run のときはここで終了。
# Refactor Scan Report
**Scope:** <path or entire repo>
**SARIF output:** `.tmp/refactor/findings.sarif.json` (N results)
**Detected:** N 件 (critical: X, high: Y, medium: Z, low: W)
**Skipped as duplicates:** M 件(fingerprint 一致 a / location 一致 b)
## 作成予定の issue
### 🔴 critical
1. [remove-duplication] タイトル — locations, effort
### 🟠 high
...
--dry-run がない場合は Phase S-5 に進む(ユーザー対話は挟まない)。
Phase S-5: issue 作成
各 SARIF result について gh issue create を 1 回ずつ実行する。
issue 本文テンプレート
## 概要
<message.text>
## 対象
- `src/api/user.ts:42-58`
- `src/api/admin.ts:61-77`
## 提案するアプローチ
<properties.suggested_approach>
## 想定リスク
- <properties.risks>
## メタ
- Category: remove-duplication
- Severity: high
- Effort estimate: ~30 min
<!-- machine-readable footer — DO NOT EDIT -->
RefactorFingerprint: <sha1>
RefactorRuleId: remove-duplication
RefactorSource: my-refactor/scan@YYYY-MM-DD
---
*Generated by `/my-refactor scan`. SARIF: `.tmp/refactor/findings.sarif.json` result index N.*
RefactorFingerprint: を必ず入れる。次回 scan がこの行を読み、重複起票を避ける。
作成コマンド
gh issue create \
--title "<properties.suggested_title>" \
--body-file "$SCAN_OUT_DIR/issue-body-<idx>.md" \
--label "refactor" \
--label "severity/<properties.severity>" \
--label "category/<ruleId>"
--assignee は付けない(誰が取るか未定。ユーザー希望があれば @me)
- rate limit 回避のため、作成ごとに
sleep 1 を挟む
- 作成失敗で以降を中断し、作成済み番号をユーザーに報告する
作成後のサマリ
issue を作ったら必ず次の形式で出力する。実装はこのスキルでは扱わない。
# Created N refactor issues
- #123 🔴 [remove-duplication] タイトル — `refactor/issue-123-extract-auth-header`
- #124 🟠 [extract-function] タイトル — `refactor/issue-124-...`
SARIF: `.tmp/refactor/findings.sarif.json`
## 次のステップ
各 issue の実装は、この scan とは別の作業として扱ってください。
Issue 本文の「提案するアプローチ」「想定リスク」「RefactorFingerprint」を実装時の参照材料にすると効率的です。
各 issue について、ケバブケースの feature-name を 1 つ提案すること(refactor-issue-<num>-<short-slug> 形式)。ユーザーがそのままコピペできる。
注意事項
SARIF 出力
- scan の出力は
SCAN_OUT_DIR/findings.sarif.json。SARIF 2.1.0 サブセットとして他ツールに渡せる。仕様は references/sarif.md
- fingerprint は行番号を含めない。正規化は空白のみ(各行の trim + 連続空白の圧縮)。変数名抽象化は実行間で非決定的になるため行わない
issue と fingerprint
- scan が作る issue には
RefactorFingerprint: / RefactorRuleId: 行が埋め込まれる。この 2 行は手編集しない
- 次回 scan はこの行を読み、同じ所見の重複起票を避ける
- 手動で issue を書いた場合は fingerprint 判定対象外(location + ruleId フォールバックのみ)
その他
- すべての issue タイトル・本文は日本語。ラベル・ファイル名は英語
references/catalog.md を 必ず読んで category 分類の根拠にする。category/other の濫用を避ける
- 480 分を超える effort の issue を提示する前に、ユーザーへ分割を提案する
- このスキルは issue 起票までで止まる。実装フローは別途選ぶ(重複させない)