Codexでコードレビューの指摘数をHPゲージで可視化する革新的手法

  • URLをコピーしました!
目次

Codex ユーザーが日常でぶつかる悩み

コードレビューやリポジトリ理解の現場では、Codex を使いながらも「今どれだけ指摘されているか」「このPRの健全度は?」といった可視化が乏しいまま、淡々とやりとりが進みがちです。特に大規模な monorepo では、どのディレクトリのどの指摘が多いかが埋もれやすく、開発者のモチベーションや緊張感も単調になりがちです。Codex の context や path 管理にまつわる「あるある」な困りごととして、以下のような点が挙げられます:

  • Codex が context を見失って違う場所のコードを参照する
  • monorepo で package を跨いだ瞬間、Codex が repo 構造を忘れる
  • session を再開すると、前回までの context や path 指定をまるごと再説明しないといけない
  • 長時間 workflow で long context が膨らみすぎて、important な情報が薄まる (stale context)
  • 「ここはこういう構造のリポジトリ」というあらすじを毎回チャットの冒頭で書く羽目になる

また、レビュー指摘数が多い場合でも「どれだけ危機的状況なのか」が直感的に伝わらず、やりとりが単なる数値やリストで終わってしまうこともしばしばです。可視化・レポートの観点からも、指摘の多寡や状況を楽しく・分かりやすく伝える仕掛けが求められています。

この Skill が一言でいうと何を解決するか

一言サマリ: このスキルは、コードレビューの指摘数をRPGのHPゲージ風に可視化し、開発現場にユーモアと緊張感をもたらします。

もう少し具体化すると、このSkillを入れることで以下のような状態になる:

  • コードレビュー指摘数がHPゲージとして可視化され、今の「体力」が直感的に把握できる
  • レビューごとにHPが減る演出で、まるでラスボス戦のような盛り上がりが生まれる
  • 指摘が多すぎると「力尽きた」メッセージが現れ、チームで状況を共有しやすくなる
  • Codex の context 管理や repository understanding の一助となり、今どのディレクトリ・PRが危機的かを把握しやすい
  • マンネリ化しがちなAI coding workflowに遊び心を加え、onboardingや長時間作業のメリハリにも貢献
QUICK INSTALL
このSkillをすぐ試す

GitHub から degit でコマンド1行、Codex の Skill ディレクトリに展開できます。Node.js があれば即時に動きます。

npx degit aazutaku/ai-note/codex/rpg-review-hp-gauge .agents/skills/rpg-review-hp-gauge

実行したらこうなる (3つの利用シーン)

使う側がイメージしやすいよう、擬似 terminal で出力例を3パターン示します。

シーン1: session 開始時 (プロジェクト初動で)


# /skills menu で rpg-review-hp-gauge を選択

=== RPG Review HP Gauge ===
対象: feature/login-auth PR
初期HP: 100

[████████████████████] 100/100
レビュー指摘: 0件
「このPRはまだまだ元気です!」

シーン2: monorepo / package 跨ぎ作業時


# $rpg-review-hp-gauge mention

=== RPG Review HP Gauge ===
対象: packages/user-profile/src/
指摘合計: 7件

[███████---------] 35/100
HPが大幅に減少!
指摘内容:
- 関数名が一貫していません
- 型定義が不足しています
- テストコードが未整備です
...
「あと1回の攻撃で力尽きそうです…!」

シーン3: お遊び的な使い方


# /skills menu から明示呼び出し

=== RPG Review HP Gauge ===
対象: utils/date-helper.js
指摘合計: 12件

[--------------------] 0/100
HPゼロ!勇者は力尽きた…
「リファクタリングで蘇生してください!」

before / after の違い

場面 Skill 無し Skill 有り
session 再開時 repo 構造から毎回説明、path も指定し直し Codex が自動で context を復元、最小プロンプトで再開
monorepo 移動 違う package のコードを参照しがち directory boundary を意識して必要な範囲だけ見る
長時間 workflow long context で重要箇所が薄まる HPゲージの可視化で重要なレビュー指摘を見失いにくい

発動方式

明示呼び出し (/skills menu or $skill-name mention) と暗黙発動 (description マッチ) の両方に対応。

Skill の中身を全部見せる

.agents/skills/rpg-review-hp-gauge/ に配置するファイル一覧です。GitHub に push 済みなので、上記の degit コマンドで一発取得できます。

.agents/skills/rpg-review-hp-gauge/
├── SKILL.md
├── scripts/
│   └── rpg_review_hp_gauge.py
└── references/
    └── design_notes.md

各ファイルの役割

ファイル 役割
SKILL.md Skill本体。frontmatter (name/description) と指示本文。Codex がこの内容をエージェント指示として読み込み、ユーザーのプロンプトに応じて発動します
scripts/rpg_review_hp_gauge.py RPG風コードレビューHPゲージ
references/design_notes.md 概要 をまとめた参考資料

SKILL.md

---
name: rpg-review-hp-gauge
description: コードレビューの指摘数をRPGのHPゲージ風に可視化したい時、または「HP」「ゲージ」「レビュー指摘」などのキーワードを含むPRや会話で発動してください。
---

# 機能概要
このSkillは、コードレビューの指摘数を“RPGのHPゲージ”として可視化します。PRごとに指摘数をカウントし、最大HPから減算してHPバーを生成。HPが0になると「力尽きた」演出が表示され、レビューの緊張感や遊び心を演出します。レビューの質や指摘傾向が一目で分かり、開発現場にユーモアと可視化の新しい体験をもたらします。

# 使い方
- 明示呼び出し例: `/skills rpg-review-hp-gauge analyze --pr 1234` または `$rpg-review-hp-gauge @PR-1234`
- 暗黙発動キーワード例: 「HPゲージ」「レビュー指摘数」「体力バー」「コードの体力」などを含む会話やPRコメントで自動発動します。

# 出力例
```
[PR #1234] コードレビューHPゲージ
HP: [█████-----] 50/100
指摘数: 5 (HP -50)
コメント:
- 変数名が不明瞭です
- テストケースが不足しています
...
あなたのコードは半分の体力を失いました!
```
HPが0の場合:
```
HP: [----------] 0/100
あなたのコードは力尽きた...
```

# 注意点
- HPの最大値や指摘ごとの減点値は設定可能
- 指摘内容はGitHub/GitLab APIから取得(APIトークン必須)
- ローカルファイル保存は行いません
- 除外パスやBotコメントは自動で無視します

# 参考資料
- references/design_notes.md
- https://docs.github.com/en/rest/pulls/comments
- https://docs.gitlab.com/ee/api/notes.html

scripts/rpg_review_hp_gauge.py

import argparse
import sys
import requests
import os
import math

def get_github_pr_comments(repo, pr_number, token):
    headers = {'Authorization': f'token {token}'}
    comments = []
    page = 1
    while True:
        url = f'https://api.github.com/repos/{repo}/pulls/{pr_number}/comments?page={page}&per_page=100'
        resp = requests.get(url, headers=headers)
        if resp.status_code != 200:
            raise Exception(f'GitHub API error: {resp.status_code} {resp.text}')
        data = resp.json()
        if not data:
            break
        for c in data:
            if c.get('user', {}).get('type') != 'Bot':
                comments.append(c['body'])
        page += 1
    return comments

def get_gitlab_pr_comments(project_id, mr_iid, token):
    headers = {'PRIVATE-TOKEN': token}
    comments = []
    page = 1
    while True:
        url = f'https://gitlab.com/api/v4/projects/{project_id}/merge_requests/{mr_iid}/notes?page={page}&per_page=100'
        resp = requests.get(url, headers=headers)
        if resp.status_code != 200:
            raise Exception(f'GitLab API error: {resp.status_code} {resp.text}')
        data = resp.json()
        if not data:
            break
        for c in data:
            if not c.get('system', False):
                comments.append(c['body'])
        page += 1
    return comments

def calc_hp(num_comments, max_hp=100, damage_per_comment=10):
    hp = max_hp - num_comments * damage_per_comment
    return max(0, hp)

def render_hp_bar(hp, max_hp, bar_length=10):
    filled = int(bar_length * hp / max_hp)
    empty = bar_length - filled
    return '[' + '█' * filled + '-' * empty + f'] {hp}/{max_hp}'

def summarize_comments(comments, max_lines=5):
    lines = []
    for c in comments[:max_lines]:
        first_line = c.strip().split('\n')[0]
        lines.append(f'- {first_line}')
    if len(comments) > max_lines:
        lines.append('...')
    return '\n'.join(lines)

def analyze_github(args):
    token = args.token or os.environ.get('GITHUB_TOKEN')
    if not token:
        print('Error: GitHub token required (--token or GITHUB_TOKEN env)')
        sys.exit(1)
    try:
        comments = get_github_pr_comments(args.repo, args.pr, token)
    except Exception as e:
        print(f'API error: {e}')
        sys.exit(1)
    num_comments = len(comments)
    hp = calc_hp(num_comments, args.max_hp, args.damage)
    bar = render_hp_bar(hp, args.max_hp)
    print(f'[PR #{args.pr}] コードレビューHPゲージ')
    print(f'HP: {bar}')
    print(f'指摘数: {num_comments} (HP -{num_comments*args.damage})')
    print('コメント:')
    print(summarize_comments(comments))
    if hp == 0:
        print('あなたのコードは力尽きた...')
    elif hp < args.max_hp // 2:
        print('あなたのコードは半分の体力を失いました!')

def analyze_gitlab(args):
    token = args.token or os.environ.get('GITLAB_TOKEN')
    if not token:
        print('Error: GitLab token required (--token or GITLAB_TOKEN env)')
        sys.exit(1)
    try:
        comments = get_gitlab_pr_comments(args.project_id, args.mr, token)
    except Exception as e:
        print(f'API error: {e}')
        sys.exit(1)
    num_comments = len(comments)
    hp = calc_hp(num_comments, args.max_hp, args.damage)
    bar = render_hp_bar(hp, args.max_hp)
    print(f'[MR !{args.mr}] コードレビューHPゲージ')
    print(f'HP: {bar}')
    print(f'指摘数: {num_comments} (HP -{num_comments*args.damage})')
    print('コメント:')
    print(summarize_comments(comments))
    if hp == 0:
        print('あなたのコードは力尽きた...')
    elif hp < args.max_hp // 2:
        print('あなたのコードは半分の体力を失いました!')

def main():
    parser = argparse.ArgumentParser(description='RPG風コードレビューHPゲージ')
    subparsers = parser.add_subparsers(dest='cmd')

    gh = subparsers.add_parser('github', help='GitHub PRのHPゲージ表示')
    gh.add_argument('--repo', required=True, help='org/repo 形式')
    gh.add_argument('--pr', type=int, required=True, help='PR番号')
    gh.add_argument('--token', help='GitHub APIトークン')
    gh.add_argument('--max-hp', type=int, default=100, help='最大HP')
    gh.add_argument('--damage', type=int, default=10, help='指摘1件あたりのHP減少')
    gh.set_defaults(func=analyze_github)

    gl = subparsers.add_parser('gitlab', help='GitLab MRのHPゲージ表示')
    gl.add_argument('--project-id', required=True, help='GitLabプロジェクトID')
    gl.add_argument('--mr', type=int, required=True, help='MR番号')
    gl.add_argument('--token', help='GitLab APIトークン')
    gl.add_argument('--max-hp', type=int, default=100, help='最大HP')
    gl.add_argument('--damage', type=int, default=10, help='指摘1件あたりのHP減少')
    gl.set_defaults(func=analyze_gitlab)

    args = parser.parse_args()
    if not args.cmd:
        parser.print_help()
        sys.exit(0)
    args.func(args)

if __name__ == '__main__':
    main()

references/design_notes.md

# 概要
本Skillは、コードレビューの指摘数をRPGのHPゲージとして可視化することで、レビューの進捗や緊張感を演出し、開発現場に遊び心を提供します。

# 公式ドキュメント抜粋
- [GitHub Pull Request Review Comments API](https://docs.github.com/en/rest/pulls/comments)
- [GitLab Merge Request Notes API](https://docs.gitlab.com/ee/api/notes.html)

# 利用例
GitHubのPR番号やGitLabのMR番号を指定することで、指摘数に応じたHPゲージをターミナル上に表示します。HPが0になると「力尽きた」演出が現れ、レビュー体験を盛り上げます。

# 注意点
- Botコメントやシステムコメントは自動で無視します。
- HPや減点値はカスタマイズ可能。
- APIトークンの管理に注意してください。

# 設計方針
シンプルなCLI設計とし、APIレスポンスの信頼性・拡張性を重視。レビュー文化にユーモアを加えつつ、実用的な指摘傾向の可視化を目指しました。

導入手順

このSkillは GitHub で管理されているので、degit を使えば必要なフォルダだけを1コマンドで取得できます。Codex はファイル配置後に再起動するだけで自動認識します。

1. 前提

  • Node.js v16 以上 (degit 実行に必要)
  • Codex がローカルで動いていること

2. degit でフォルダ取得

プロジェクトのルートで以下のコマンドを実行します。

npx degit aazutaku/ai-note/codex/rpg-review-hp-gauge .agents/skills/rpg-review-hp-gauge

.agents/skills/rpg-review-hp-gauge の中に SKILL.md / scripts/ / references/ / README.md が展開されます。

3. ファイル配置確認

ls .agents/skills/rpg-review-hp-gauge
# SKILL.md, scripts/, references/, README.md があればOK

4. Codex を再起動 (or Skill 自動検出を待つ)

新しいSkillが自動で認識されます。リスト確認したい場合は /skills menu or $skill-name mention と Skill 名で出てきます。

5. 動作確認

/skills menu or $skill-name mention で呼び出すか、自然言語で発動条件にマッチする指示を出すと Skill が動きます。期待される出力イメージは「実行したらこうなる」セクションを参照してください。

こんな瞬間に便利

  • session 開始時: 前回までの repo 把握を Codex に一発で復元させたい
  • monorepo 移動時: packages を跨いだ瞬間に context を切り替えたい
  • onboarding 時: 新しい repo を Codex に把握させ、こちらが path を全部指定する手間を省きたい
  • session 再開時: long context が切れた後でも、必要な path と directory 構造だけ素早く戻したい
  • package 跨ぎ作業時: directory boundary を Skill 側で管理して、irrelevant な path 混入を防ぎたい
  • long-running workflow 前: long context で重要箇所が薄まる前に snapshot を取りたい

気になるポイント (壊れそうな箇所)

実運用に乗せる前に頭に入れておきたい懸念。後で検証する観点でもある:

  • stale context 問題: 長時間 workflow で Skill 出力が古くなり、現状と乖離する可能性
  • directory 増えすぎ問題: 大規模 repo で全 directory を網羅すると出力が肥大化して context window を圧迫
  • monorepo 肥大化: packages が多い構成では出力が雑になり、結局 path 指定し直しになる懸念
  • irrelevant path 混入: node_modules / build 成果物 / generated コードを拾ってしまう可能性
  • Codex 固有の引っかかり: description のセマンティックマッチ精度が要件次第
  • 発動しないケース: description が漠然 / 他の Skill が優先 / git管理外 directory

試す前に確かめたいこと

この Skill を実運用に投入する前に確かめたい問いを並べる:

  • 実 repo での token 消費は許容範囲か?
  • monorepo (packages 多数) で安定して動くか?
  • stale context にならず、長時間 workflow でも有効か?
  • AGENTS.md との連携設計はどうあるべきか?
  • 指摘数とHPゲージの連動が正しく動作するか?
  • HPゼロ演出やメッセージが表示されるか?
  • UIがRPGっぽく楽しい雰囲気になっているか?

実際に Codex で試した検証ログは CodexでコードレビューのHPゲージを試してみた!指摘数で体力が減る面白演出 にまとめる予定 (公開準備中の場合あり)。
あわせて Codex 公式ドキュメント と、本シリーズ「Codexを使いこなすSkillアイデア」の他記事も参照のこと。

関連タグで他のSkill記事を探す

本記事に付いているタグから、気になるテーマの記事を探せます。タグページで関連記事をまとめて読めるので、ぜひチェックしてみてください!

この記事が気に入ったら
フォローしてね!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次