deep-trace について
deep-traceは、変更されたコードからアプリケーションの入口や下流への影響まで、実行経路を1行ずつ追跡するスキルです。画面やURL、データフロー、トリガーを表にまとめ、拡張機能対応の表も生成できます。
主な機能
- 01変更コードからアプリの入口を追跡
- 02呼び出し元と下流の呼び出しを追跡
- 03画面・URL・データフロー・トリガーを記録
- 04拡張機能対応のトレース表を生成
- 05任意で表をクリップボードにコピー
活用シーン
- 01コード変更の実行経路を把握
- 02プルリクエストが影響するフローを確認
- 03VS Code拡張機能向けの追跡行を準備
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ laststance/ skills --skill deep-traceインストール後、Claude Code で/deep-traceを入力して読み込まれたか確認します。
同梱ファイルscripts/copy-to-clipboard.sh
詳細
Deep Trace — 行単位の実行パストレーサー
Codex 互換性
Codex でこのスキルを実行する場合は、作業を開始する前に Claude Code 専用のプリミティブを変換してください。AskUserQuestion → chat/request_user_input、TodoWrite → update_plan、Task/TaskCreate/TeamCreate/SendMessage → 利用可能かつ許可されている場合は spawn_agent/send_input/wait_agent、EnterPlanMode/ExitPlanMode → 簡潔なチャットでの計画提示と明示的な承認。
Read/Write/Edit/Bash/WebSearch/WebFetch は Codex のファイル/シェル/ウェブツールに対応付け、~/.claude/... のパスは、タスクで Claude Code が明示的に対象とされていない限り、~/.agents/... または ~/.codex/... に対応付けてください。
Cursor 互換性
Cursor Agent でこのスキルを実行する場合は、作業を開始する前に Claude Code 専用のプリミティブを変換してください。AskUserQuestion → AskQuestion、TodoWrite → Cursor の TodoWrite または同等のチェックリスト、Task/TaskCreate/TeamCreate/SendMessage/マルチエージェントのフロー → Cursor の Task(サブエージェント)、並列の Task、または許可されている場合は run_in_background(TeamCreate/SendMessage に完全に一致する機能がない場合があります)、EnterPlanMode/ExitPlanMode → Plan mode(SwitchMode / CreatePlan)と明示的なユーザー承認。
Read/Write/Edit/StrReplace/Bash/ウェブ/検索/MCP は、Cursor Composer または Agent の同等機能に対応付けてください。mcp__server__tool の形式で記述された MCP 名は、通常、設定済みのサーバー識別子を使う call_mcp_tool に対応します。タスクで Claude Code が明示的に対象とされていない限り、~/.claude/... は ~/.cursor/skills/、.cursor/skills/、.cursor/rules/ に対応付けてください。
<essential_principles>
基本概念
デバッガーで1行ずつ実行するようにコードを追跡し、次の情報を加えます。
- 画面:このコードが実行されたときにユーザーに表示されるもの
- URL:このコードが実行されるページ/API ルート
- データフロー:どのデータが入力され、変換され、出力されるか
- トリガー:この行を実行させるイベント/アクション
トレース表の形式
すべてのトレースは、次の構造化された表を出力します。
## Trace: [description]
| # | File:Line | Code | Screen/URL | Data Flow | Trigger |
|---|-----------|------|------------|-----------|---------|
| 1 | page.tsx:15 | `const router = useRouter()` | /drawings | — | Page mount |
| 2 | page.tsx:16 | `const { id } = router.query` | /drawings?id=123 | id: string | URL params |
| 3 | hook.ts:8 | `const { data } = useQuery(...)` | /drawings?id=123 | id → API call | React render |
| ... | ... | ... | ... | ... | ... |
原則
- 差分優先:変更された行から始め、エントリーポイントと後続の影響まで追跡します
- 行単位:意味のある行ごとに独立した行を設けます(空行、import、型のみの行は省略)
- 画面との対応付け:このコードの実行時にユーザーが表示している画面/URLを必ず特定します
- 双方向:上流(何がこれを呼び出すか)と下流(これが何を呼び出すか)の両方を追跡します
- アプリケーション境界:ライブラリ呼び出しは1行で要約し、node_modules の内部までは追跡しません
- File:Line の省略禁止:ファイル名を切り詰めたり、省略記号を使ったりしてはいけません。常にファイル名全体を示します(例:
useSetFormValuesFromQueryStrings.tsx:77。useSetFormValues...:77は不可)。80文字を超える場合、コード列は省略してもかまいませんが、ファイル名は正確に記載してください。
</essential_principles>
ワークフロー
ステップ 1:対象を特定する
ユーザーの引数から入力元を判断します。
| 入力 | 判定方法 | アクション |
|---|---|---|
| PR 番号 | #1234 または番号 | gh pr diff <number> |
| ブランチの差分 | --diff または引数なし | git diff HEAD~1 または git diff dev...HEAD |
| ファイルパス | .ts、.tsx など | ファイルを読み込み、export から追跡 |
| 関数名 | パスを含まないテキスト | Serena find_symbol |
ステップ 2:変更されたコードを抽出する
PR/差分の入力の場合:
- 差分を解析し、変更されたファイルと行範囲を取得します
- ファイルごとに変更をまとめます
- 優先順位:コンポーネント > フック > ユーティリティ > 型
ファイル/関数の入力の場合:
- 対象のコードを読み込みます
- エクスポートされた関数/コンポーネントを特定します
ステップ 3:エントリーポイントを見つける
変更されたコードセクションごとに、エントリーポイントを見つけるために上流をたどります。
Changed line → containing function → caller → ... → page component / API route / event handler
Serena ツールを使用します。
find_symbol— 関数を見つけますfind_referencing_symbols— 呼び出し元を見つけます- ページ/ルート/イベントの境界に達するまで繰り返します
エントリーポイントの種類:
| 種類 | 例 | 画面/URL |
|---|---|---|
| ページコンポーネント | pages/drawings/index.tsx | /drawings |
| API ルート | pages/api/drawings.ts | POST /api/drawings |
| イベントハンドラー | onClick, onSubmit | 現在のページ上のボタンクリック |
| エフェクト | useEffectOnMount | ページ読み込み |
| プロバイダー | _app.tsx ラッパー | すべてのページ |
ステップ 4:トレーステーブルを作成する
エントリーポイントから開始し、1 行ずつ順を追います。
-
エントリーポイントのファイルを読みます(Serena の
find_symbolでinclude_body=Trueを指定) -
意味のある各行について、テーブルの行を作成します。
#:連番のステップ番号File:Line:完全なファイル名+行番号。ファイル名を省略したり、三点リーダーで表したりしないでくださいCode:実際のコード(バッククォートで囲み、80 文字を超える場合は省略可)Screen/URL:アクティブな画面/ページ/URLData Flow:読み取り/書き込み/変換されるデータTrigger:この行の実行を引き起こすもの(マウント、クリック、API レスポンスなど)
-
関数呼び出しに到達した場合:
- アプリケーションコードの場合 → 関数内をたどります(3.1、3.2 などのサブステップ)
- ライブラリ呼び出しの場合 →
[lib]プレフィックスを付けて 1 行にまとめます
-
**条件分岐に到達した場合:**両方の経路を記録し、主要な経路をたどります
ステップ 5:コンテキストを注釈として追加する
トレーステーブルの後に、次のセクションを追加します。
## Summary
- **When**: [user action / event that triggers this code]
- **Where**: [screen URL and component location]
- **What**: [1-2 sentence description of what the code accomplishes]
- **Data**: [key data entities involved, their sources and destinations]
## Key Observations
- [Notable patterns, potential issues, or design decisions]
ステップ 6:拡張機能と互換性のある出力を生成する
Summary の後に、deep-trace-extension VS Code 拡張機能用のコピー可能な別テーブルを生成します。
拡張機能の形式(4 列。指定されたヘッダー名が必要です):
## 📋 Deep Trace Extension
| file | line | col | reason |
| --- | --- | --- | --- |
| src/components/FreewordSearchFilter.tsx | 40 | 1 | useFreewordSearchFormContext — Component render |
| src/components/FreewordSearchFilter.tsx | 54 | 1 | useWatch target values — Form state change |
トレーステーブルから拡張機能テーブルへの変換ルール:
| トレース列 | → 拡張機能の列 | ルール |
|---|---|---|
File:Line | file + line | 最後の : で分割します。前半がファイルパス、後半が行番号です |
| — | col | 常に 1(トレースでは列情報を追跡しません) |
Code + Trigger | reason | 組み合わせ:コードの簡潔な説明 + — + トリガー |
要件:
- トレーステーブルのすべての行に対応する行を設けます
fileには完全な相対パスを指定します(ファイル名だけではありません)。トレーステーブルにファイル名だけがある場合は、Serena を使用してプロジェクトルートから解決してください- ユーザーが生の Markdown をコピーできるよう、フェンス付きコードブロック(
```markdown ... ```)内に出力します
Step 6.5: 拡張テーブルをクリップボードにコピーする(任意、OS に応じて実行)
Step 6 でコードフェンス付きの拡張テーブルブロックを出力した直後に、同じブロックをバンドルされているヘルパーにもパイプで渡します。ユーザーが手動で選択しなくても、deep-trace-extension にそのまま貼り付けられるようにします。
cat <<'EOF' | bash skills/deep-trace/scripts/copy-to-clipboard.sh
| file | line | col | reason |
| --- | --- | --- | --- |
| src/components/FreewordSearchFilter.tsx | 40 | 1 | useFreewordSearchFormContext — Component render |
| src/components/FreewordSearchFilter.tsx | 54 | 1 | useWatch target values — Form state change |
EOF
ヘルパーは、ホストのクリップボードツールを自動検出します。
| OS/環境 | 試行するツール |
|---|---|
| macOS | pbcopy |
| Linux(Wayland セッション) | wl-copy |
| Linux(X11 セッション) | xclip -selection clipboard → xsel |
| WSL | clip.exe |
| Cygwin/MinGW/MSYS | clip |
| ツールなし/不明な OS | スキップし、stderr に 1 行の通知を出力します |
動作要件(遵守してください):
- Step 6 のコードフェンス付き Markdown ブロックを必ず最初に出力します。クリップボードへのコピーは追加処理であり、置き換えではありません。
- スクリプトは、クリップボードツールがない場合でも必ず終了コード 0 で終了します。クリップボードを利用できないことが原因で、スキルのワークフローが失敗してはいけません。
- スクリプトは、選択したツール(またはスキップした理由)をstderr に報告します(例:
copy-to-clipboard: copied via pbcopy (macOS))。手動でコピーする必要があるかどうかがユーザーにわかるよう、この行をユーザーに伝えてください。
このステップ全体を省略する場合:
- ヘッドレス CI/非対話型の実行(貼り付けを行う人がいない場合)
- クリップボードへのアクセスが拒否される、または意味をなさない、サンドボックス環境やリモート環境
- ユーザーが明示的にオプトアウトした場合(例:セキュリティ上機密性の高い状況)
Step 7: メモリに保存する(任意)
ユーザーがこのトレースを記憶しておきたい場合:
Serena write_memory("trace_<descriptive_name>", traceContent)
例
例:PR の差分をトレースする
/deep-trace #3548
出力:
## Trace: PR #3548 — フリーワード検索の種別フィルター追加
### Entry: FreewordSearchFilter.tsx (絞り込みPopover内)
| # | File:Line | Code | Screen/URL | Data Flow | Trigger |
|---|-----------|------|------------|-----------|---------|
| 1 | FreewordSearchFilter.tsx:40 | `const { control } = useFreewordSearchFormContext()` | /freeword_search?query=テスト | form context | Component render |
| 2 | FreewordSearchFilter.tsx:54 | `const targetValues = useWatch({ control, name: 'target' })` | same | target: SelectOption[] | Form state change |
| 3 | FreewordSearchFilter.tsx:65 | `useDocumentTypeSettingsQuery(...)` | same | API → document_type_settings | React Query cache/fetch |
| 4 | FreewordSearchFilter.tsx:70 | `const targetOptions = useMemo(...)` | same | settings → SelectOption[] | Deps change |
| 5 | FreewordSearchFilter.tsx:119 | `<MultiSelectRHF ... options={targetOptions}>` | same (Popover open) | targetOptions → UI | User opens filter |
### Summary
- **When**: User opens 絞り込み popover on freeword search page
- **Where**: /freeword_search (ファイルフリーワード検索モード)
- **What**: Shows multi-select filter for 種別 (drawing + document types)
- **Data**: document_type_settings API → SelectOption[] → form state → API search params
## 📋 Deep Trace Extension
```markdown
| file | line | col | reason |
| --- | --- | --- | --- |
| src/components/FreewordSearchFilter.tsx | 40 | 1 | useFreewordSearchFormContext — Component render |
| src/components/FreewordSearchFilter.tsx | 54 | 1 | useWatch target values — Form state change |
| src/components/FreewordSearchFilter.tsx | 65 | 1 | useDocumentTypeSettingsQuery — React Query cache/fetch |
| src/components/FreewordSearchFilter.tsx | 70 | 1 | useMemo targetOptions — Deps change |
| src/components/FreewordSearchFilter.tsx | 119 | 1 | MultiSelectRHF render — User opens filter |
## Tools Used
| Tool | Purpose |
|------|---------|
| `gh pr diff` | Get PR diff |
| `git diff` | Get branch diff |
| Serena `find_symbol` | Locate functions |
| Serena `find_referencing_symbols` | Find callers (trace UP) |
| Serena `get_symbols_overview` | Map file structure |
| Serena `write_memory` | Save trace for future reference |
| `scripts/copy-to-clipboard.sh` | OS-aware clipboard copy of the extension table (pbcopy / wl-copy / xclip / xsel / clip.exe / clip; graceful skip otherwise) |
## Success Criteria
- [ ] Entry point correctly identified (page/route/event)
- [ ] Every meaningful changed line has a trace row
- [ ] Screen/URL column populated for all rows
- [ ] Data flow shows inputs → transformations → outputs
- [ ] Trace is readable top-to-bottom as an execution story
- [ ] Summary captures when/where/what/data
- [ ] Extension-compatible table included with `file`, `line`, `col`, `reason` columns
- [ ] Extension table uses full relative paths (not just filenames)
- [ ] Extension table wrapped in fenced code block for easy copy
- [ ] Extension table also piped through `scripts/copy-to-clipboard.sh` (or step explicitly skipped with reason); helper's stderr status surfaced to the user