mcpField
D
dg

dg

github.com/v1r3nテスト・品質19744 回インストール30 週間前に更新
リポジトリ

dg について

dgは、GilfoyleとDineshの2つのエージェントが対立形式で問題を探り、評価するコードレビュー用スキルです。git diffまたは指定ファイルを確認し、実行可能な要約と軽妙なやり取りをまとめます。

主な機能

  1. 01ステージ済み・未ステージの差分をレビュー
  2. 02指定ファイルやディレクトリをレビュー
  3. 032エージェントによる複数ラウンドの対立レビュー
  4. 04依存関係の脆弱性情報を考慮
  5. 05構造化レビューと任意のコミック生成

活用シーン

  1. 01コミット前の変更にある問題の発見
  2. 02指定したソースファイルやディレクトリのレビュー
  3. 03コードレビューでの依存リスク評価
  4. 04レビュー中のやり取りをコミック化

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/v1r3n/dinesh-gilfoyle --skill dg

インストール後、Claude Code で/dgを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

comic-template.html
dinesh-agent.md
gilfoyle-agent.md

詳細

Dinesh 対 Gilfoyle のコードレビュー

HBO の『Silicon Valley』に着想を得た、2 人のエージェントによる対抗形式のコードレビューです。Gilfoyle は容赦ない技術的な正確さでコードを批判します。Dinesh は動揺しながらも有能に反論します。掛け合いは楽しめるだけでなく、やり取りを重ねることで、実際により良いレビューが生まれます。

実行方法

  • /dg — git diff(ステージ済み + 未ステージ)をレビュー
  • /dg 3 — git diff を最大 3 ラウンドレビュー
  • /dg src/auth.ts — 指定したファイルをレビュー
  • /dg src/auth.ts 3 — 指定したファイルを最大 3 ラウンドレビュー

引数の解析

  1. 引数なし → 対象 = git diff、上限 = 5
  2. 数字のみ → 対象 = git diff、上限 = その数字
  3. パスのみ → 対象 = そのパス、上限 = 5
  4. パス + 数字 → 対象 = そのパス、上限 = その数字

オーケストレーション

ステップ 1:コードを収集する

git diff の場合:

git diff HEAD
git diff --staged

両方の差分を結合します。両方とも空の場合は、レビュー対象がないことをユーザーに伝えます。

ファイル/パスの場合: 対象のファイルを読み込みます。パスがディレクトリの場合は、その中にあるすべてのソースファイルを読み込みます。

常に実行:依存関係のコンテキストを収集します。 プロジェクトのルートディレクトリにある依存関係ファイルを探し、エージェントに渡すコンテキストに含めます。

  • package.json、package-lock.json、yarn.lock、pnpm-lock.yaml(Node.js)
  • requirements.txt、pyproject.toml、Pipfile.lock(Python)
  • go.mod、go.sum(Go)
  • pom.xml、build.gradle(Java)
  • Gemfile、Gemfile.lock(Ruby)
  • Cargo.toml、Cargo.lock(Rust)
  • composer.json、composer.lock(PHP)

これらは、Gilfoyle が依存関係の脆弱性をスキャンするために必要です。

ステップ 2:討論を実行する

初期化:round = 0、debate_history = []

digraph debate {
    "Gather code" [shape=box];
    "Dispatch Gilfoyle" [shape=box];
    "New issues found?" [shape=diamond];
    "Dispatch Dinesh" [shape=box];
    "All conceded, no pushback?" [shape=diamond];
    "Round >= cap?" [shape=diamond];
    "Ask user: continue?" [shape=diamond];
    "Synthesize final review" [shape=doublecircle];

    "Gather code" -> "Dispatch Gilfoyle";
    "Dispatch Gilfoyle" -> "New issues found?";
    "New issues found?" -> "Synthesize final review" [label="no — converged"];
    "New issues found?" -> "Dispatch Dinesh" [label="yes"];
    "Dispatch Dinesh" -> "All conceded, no pushback?";
    "All conceded, no pushback?" -> "Synthesize final review" [label="yes — converged"];
    "All conceded, no pushback?" -> "Round >= cap?";
    "Round >= cap?" -> "Dispatch Gilfoyle" [label="no — next round"];
    "Round >= cap?" -> "Ask user: continue?" [label="yes"];
    "Ask user: continue?" -> "Dispatch Gilfoyle" [label="yes — extend cap"];
    "Ask user: continue?" -> "Synthesize final review" [label="no"];
}

各ラウンドで:

  1. Gilfoyle エージェントを呼び出す(Agent ツール、汎用)際に、以下を渡します。

    • このスキルのディレクトリにある gilfoyle-agent.md の全内容
    • レビュー対象のコード
    • 討論履歴全体
    • ラウンド番号
    • 指示:「調査のみを行ってください。コードを読んでレビューを作成してください。ファイルは編集しないでください。」
  2. Gilfoyle の掛け合いをユーザーに表示します。

  3. 収束を確認します: Gilfoyle の FINDINGS セクションを解析します。すべての指摘が前のラウンドの繰り返しであれば、収束したと判断します。

  4. Dinesh エージェントを呼び出す(Agent ツール、汎用)際に、以下を渡します。

    • このスキルのディレクトリにある dinesh-agent.md の全内容
    • レビュー対象のコード
    • Gilfoyle の直近の完全な応答
    • 討論履歴全体
    • ラウンド番号
    • 指示:「調査のみを行ってください。コードを読んで反論を作成してください。ファイルは編集しないでください。」
  5. Dinesh の掛け合いをユーザーに表示します。

  6. 収束を確認します: Dinesh の FINDINGS セクションを解析します。すべての指摘が [concede] で、[defend] または [dismiss] が 1 つもなければ、収束したと判断します。

  7. 両者の応答を debate_history に追加し、ラウンドを 1 増やします。

  8. ラウンド数が上限以上の場合: ユーザーに質問します。「この 2 人はいつまでも続けそうです。さらにラウンドを重ねますか?(y/N)」

    • はい → 元の上限分だけ上限を延長し、ループを続けます
    • いいえ → 総括に進みます

収束時のメッセージ(状況に合うものを選択):

  • 「Gilfoyle の批判材料が尽きたようです。前例のないことです。」
  • 「Dinesh が敗北を認めました。予想どおりです。」
  • 「この 2 人は同じ話を繰り返しています。手が出る前に引き離しましょう。」
ステップ 3:最終レビューを総括する

討論の終了後、討論記録全体から構造化された要約を作成します。

表示形式:

## Dinesh vs Gilfoyle Review — [target]
### [N] rounds of mass destruction

---
### Best of the Banter
[2-4 of the funniest or most insightful exchanges from the debate]

---

### Verdict

#### Critical (Gilfoyle won, Dinesh conceded)
[Issues where Dinesh couldn't mount a defense — these are real and need fixing]
- `file:line` — issue — fix

#### Important (Gilfoyle won after debate)
[Issues Dinesh tried to defend but Gilfoyle's argument was stronger]
- `file:line` — issue — fix

#### Contested (Dinesh held his ground)
[Issues where Dinesh's defense was valid — code is likely fine]
- `file:line` — what was raised — why the defense holds

#### Dismissed (Gilfoyle was nitpicking)
[Issues both sides agree don't matter]
- `file:line` — what was raised — why it's a non-issue

### Strengths
[Things even Gilfoyle grudgingly acknowledged were good]

### Score
Gilfoyle: X | Dinesh: Y
[Tongue-in-cheek tally of who won more arguments]

### Recommended Changes
[Clean checklist — no banter, no context, just what to do]
- [ ] `file:line` — what to change
- [ ] `file:line` — what to change
- [ ] ...

If no changes needed: "Nothing to fix. Gilfoyle is furious."
ステップ 4:コミックストリップを提案する

最終レビューを表示した後、ユーザーに尋ねます。

「ベストなやり取りをコミックストリップにしますか?(y/N/pr)」

  • y — 生成してブラウザーで開く
  • pr — 生成して PNG に変換し、現在の PR にコメントとして添付する
  • N — スキップする

y または pr の場合は、HTML コミックストリップを生成します。

  1. このスキルのディレクトリにある comic-template.html からコミックのテンプレートを読み込みます。
  2. テンプレートのプレースホルダーを埋めます。
    • {{REVIEW_TARGET}} — レビュー対象(例:「UI Codebase」、「git diff」、ファイルパス)
    • {{ROUND_COUNT}} — 議論のラウンド数
    • {{GILFOYLE_SCORE}} / {{DINESH_SCORE}} — 最終スコア
    • {{DATE}} — 現在の日付
    • {{PANELS}} — ベストな掛け合いからコミックのパネルを 4~8 個生成します。各パネルには次の HTML 構造を使用します。

<div class="panel gilfoyle">
  <span class="panel-number">1</span>
  <div class="panel-header">
    <div class="avatar"><svg><use href="#gilfoyle-avatar"/></svg></div>
    GILFOYLE
  </div>
  <div class="panel-body">
    <div class="speech">The quote goes here. Use <code>inline code</code> for technical references.</div>
  </div>
</div>


<div class="panel dinesh">
  <span class="panel-number">2</span>
  <div class="panel-header">
    <div class="avatar"><svg><use href="#dinesh-avatar"/></svg></div>
    DINESH
  </div>
  <div class="panel-body">
    <div class="speech">The response goes here.</div>
  </div>
</div>


<div class="panel gilfoyle full-width">
  <span class="panel-number">3</span>
  <div class="panel-header">
    <div class="avatar"><svg><use href="#gilfoyle-avatar"/></svg></div>
    GILFOYLE
  </div>
  <div class="panel-body">
    <div class="speech">A particularly devastating line that deserves the full width.</div>
  </div>
</div>
  • {{VERDICT_ITEMS}} — 最終レビューから判定項目を生成します。
<div class="verdict-item">
  <span class="tag tag-fixed">FIXED</span> CSP nonce replaced with deploy-time placeholder
</div>
<div class="verdict-item">
  <span class="tag tag-contested">CONTESTED</span> MutationObserver lifetime — Dinesh held ground
</div>
<div class="verdict-item">
  <span class="tag tag-dismissed">DISMISSED</span> prop-types — tree-shakes out
</div>
  1. パネルに使うベストな場面を選びます。 次の点を優先します。

    • 最もおもしろいやり取り(応酬のある掛け合いが最適です)
    • ギルフォイルが譲歩した場面(めったにない、劇的な場面)
    • ディネシュの最高の切り返し
    • 技術的に最も痛烈な指摘
    • 引用は簡潔にします。吹き出しごとに 1~3 文にまとめます。
  2. 埋めた HTML をタイムスタンプ付きのファイルに書き込みます。/tmp/dg-comic-{timestamp}.html

y の場合: 5. ブラウザーで開きます。open /tmp/dg-comic-{timestamp}.html 6. ファイルの保存先をユーザーに伝えます。

pr の場合: 5. ヘッドレスブラウザーを使って PNG に変換します。

# Try puppeteer/chromium first, fall back to wkhtmltoimage, then to Safari
npx --yes puppeteer-screenshot /tmp/dg-comic-{timestamp}.html /tmp/dg-comic-{timestamp}.png 2>/dev/null \
  || wkhtmltoimage --quality 90 /tmp/dg-comic-{timestamp}.html /tmp/dg-comic-{timestamp}.png 2>/dev/null \
  || /usr/bin/osascript -e 'tell application "Safari" to open POSIX file "/tmp/dg-comic-{timestamp}.html"'

スクリーンショットツールが利用できない場合は、ブラウザーから手動でスクリーンショットを撮るようユーザーに伝えます。 6. 現在の PR を検出します。

gh pr view --json number,url --jq '.number'
  1. 画像をアップロードし、PR にコメントします。
    gh pr comment {PR_NUMBER} --body "$(cat <<'EOF'
    ## /dg Review Comic Strip
    
    ![Dinesh vs Gilfoyle](/tmp/dg-comic-{timestamp}.png)
    
    _Generated by [/dg](https://github.com/v1r3n/dinesh-gilfoyle)_
    EOF
    )"
    
    注:gh pr comment がローカル画像のアップロードに対応していない場合は、PR の本文に画像をドラッグ&ドロップする方法を提案するか、base64 に変換して埋め込みます。
  2. PR へのリンクを添えて、コメントを投稿したことをユーザーに伝えます。

重要な原則

  • 掛け合いは飾りではなく、機能です — レビューを楽しく、かつ徹底したものにします
  • ディネシュの譲歩は最も強いシグナルです — 反論できない場合は、実際に問題があります
  • 反論が成功すればコードの妥当性が裏付けられます — ギルフォイルの追及に対してディネシュが正当化できるなら、そのコードは堅実です
  • 最後は必ず実行可能な要約で締めくくります — 外側は楽しく、内側は役に立つ内容にします
  • 技術的な正確さを保ちます — 技術的な中身が本物であってこそ、ユーモアが機能します

コメント