🔧

gitのちょっとした手間を解決するCLI、gut-cliを作りました

に公開

はじめに

git commit -m "ここに何書こう..." ってなることありませんか?
これをgit commitだけにして、変更内容はAIに書いて欲しいなと思ってCLIツールを作りに着手しました。

Claude Codeでやれば?という話かもしれませんが、Claude Codeは汎用的なコーディングエージェントなのでファイル全体を読み込んでユーザーの許可を得てみたいな感じで
コミットメッセージを考えて欲しいだけなのに若干待たされるのが不便でした。

このCLI(gut-cli)だとこんな感じでサクサクです!

ブランチ名も同じです。GitHubのissueの内容を見て、feature/user-authentication-with-oauth2-integrationみたいな名前を考えて、タイプミスしないように気をつけながらgit checkout -bする。地味にめんどくさい。

PRの説明文も書かないといけないし、stashに名前をつけ忘れて後で「これ何だっけ...」となることもしばしば。

これらって一つひとつは大したことないんですが、積み重なると開発のフローが止まるんですよね。

こういった「gitまわりの小さなめんどくさい」をAIで自動化するCLIツール「gut」を作りました。

https://github.com/gitton-dev/gut-cli

たとえば、従来のgit commitだとこんな感じですよね。

# 変更をステージング
$ git add src/auth.ts

$ git commit -m "feat(auth): add OAuth2 login flow with Google provider"

gutを使うとこうなります。

# これだけ
$ gut commit

✨ Generated commit message:
feat(auth): add OAuth2 login flow with Google provider

Proceed? (Y/n) y
✅ Committed!

diffを解析してコミットメッセージを自動生成してくれるので、メッセージを考える必要がありません。

ブランチ名も同様です。従来だとissueを見ながら自分で考える必要がありました。

# issueを確認して...ブランチ名を考えて...
$ git checkout -b feature/user-authentication-with-oauth2

gutならissue番号を渡すだけ。

$ gut branch 123 --checkout

✨ Created and checked out: feature/123-oauth2-authentication

PRの説明文も、今まではテンプレートを埋めるのが手間でした。

# テンプレートを開いて、変更内容を思い出しながら書いて...
$ gh pr create --title "Add OAuth2" --body "..."

gutならコマンド一発です。

$ gut pr

📝 Generated PR:

Title: Add OAuth2 authentication with Google provider

Description:
──────────────────────────────────────────────────
## Summary
- OAuth2認証フローを実装
- Googleプロバイダーに対応

## Changes
- src/auth.ts: OAuth2クライアントの実装
- src/config.ts: 認証設定の追加
──────────────────────────────────────────────────

Create PR with gh CLI? (y/N) y
✓ PR created successfully!

日本語でコミットメッセージやPR説明文を生成したい場合は、以下のコマンドで設定できます:

# グローバル設定(すべてのリポジトリに適用)
$ gut config set lang ja

# 特定のリポジトリだけ日本語にしたい場合
$ gut config set lang ja --local

.gutフォルダにテンプレートを置いて置ける

またどんなルールでコミットメッセージを書くのかどんなブランチ名にするのかあらかじめその命名規則をマークダウンに定義しておけると最高なのでその機能もつけました!

なぜgutを作ったのか

コードを書く以外のところでAIを使いたかった

Claude CodeのようなAIアシスタントも強力ですが、単にコミットメッセージを生成したいだけなのに、ちょっと時間がかかります

gutはgit操作だけに特化しています。コードベース全体を解析するのではなく、diffだけを見るので数秒で結果が返ります。

サブスクリプション不要

多くのAIツールは月額課金が必要ですよね。gutは自分のAPIキーを使う方式なので、使った分だけの従量課金で済みます。

Gemini、OpenAI、Anthropicから好きなプロバイダーを選べます。APIキーはOSのネイティブキーチェーン(macOSならKeychain、WindowsならCredential Vault)に保存されるので、平文で保存されることはありません。

gutでできること

コミットメッセージの自動生成

$ gut commit

✨ Generated commit message:
feat(auth): add OAuth2 login flow with Google provider

Proceed? (Y/n)

変更内容を解析して、Conventional Commits形式のメッセージを自動生成します。プロジェクトに.gut/commit.mdを置けば、独自のルールにも対応します。

PR説明文の生成

$ gut pr

📝 Generated PR:

Title: Add user authentication feature

Description:
──────────────────────────────────────────────────
## Summary
- ユーザー認証機能を追加
- セッション管理を実装

## Changes
- 新規ファイル: src/auth.ts
- 設定追加: src/config.ts
──────────────────────────────────────────────────

Create PR with gh CLI? (y/N) y
✓ PR created successfully!

ブランチのコミット履歴とdiffから、PRのタイトルと説明文を生成。.github/pull_request_template.mdがあれば、そのテンプレートに沿って埋めてくれます。--copyオプションでクリップボードにコピーも可能です。

コードレビュー

$ gut review

📝 Code Review

Summary: Overall good implementation with minor suggestions

Issues:
🔴 critical | src/auth.ts:42
   Password is logged to console
   → Remove console.log or use secure logging

⚠️ warning | src/api.ts:15
   Missing error handling for API call
   → Wrap in try-catch block

変更内容をレビューして、バグやセキュリティ上の問題、改善点を指摘します。

変更内容からブランチを作成

$ gut checkout

✨ Generated branch name:

  feature/add-user-authentication

Create and checkout this branch? (y/N) y
✓ Created and checked out branch: feature/add-user-authentication

「まずコードを書き始めてしまった!」というとき、現在の変更内容を解析してブランチ名を自動生成します。gut branchがissue番号から生成するのに対し、gut checkoutはdiffから生成するので、先にコードを書き始めた場合に便利です。

stashにわかりやすい名前を自動生成

$ gut stash

✨ Generating stash name...
✓ Stashed: WIP: add OAuth2 login validation

通常のgit stashだと「WIP on branch-name: abc1234」みたいな機械的な名前になりますよね。後から見返して「これ何の作業だっけ...」となることありませんか?

gut stashは変更内容を解析して、わかりやすい名前を自動生成します。もちろん、自分で名前を指定することもできます:

# 手動で名前をつける
$ gut stash "デバッグ用の一時変更"

stashの操作も一通りサポートしています:

# stash一覧
$ gut stash --list
Stashes:
  0 WIP: add OAuth2 login validation
  1 WIP: refactor config loading

# 適用
$ gut stash --apply 0

# pop(適用して削除)
$ gut stash --pop

.gut/stash.mdにルールを書いておけば、プロジェクトに合わせた命名規則にもできます。

コンフリクトの自動解決

$ gut merge feature/login

🔀 Merging feature/login into main...
⚠️ Found 2 conflicted files

Resolving conflicts with AI...
✅ src/auth.ts - resolved (combined)
✅ src/config.ts - resolved (theirs)

All conflicts resolved!

マージコンフリクトが発生した際、AIが両方の変更の意図を理解して解決案を提示します。

変更の説明

$ gut explain abc123

📝 Explanation

Summary: Add rate limiting to API endpoints

Purpose: Prevent abuse and ensure fair usage of API resources

Key Changes:
  src/middleware/rateLimit.ts
    New rate limiting middleware using sliding window algorithm
  src/routes/api.ts
    Apply rate limiting to all endpoints

Impact: Prevents API abuse while maintaining good UX for normal users

「このコミット何してるんだっけ?」「このPR何が変わるの?」という疑問をAIが解説してくれます。

引数なしで実行すると、今の未コミットの変更を説明してくれるので、コミット前の確認にも便利です:

# 今の変更内容を説明
$ gut explain

# ステージ済みの変更だけ説明
$ gut explain --staged

PRの説明もできます。レビュー前にざっと内容を把握したいときに便利ですね:

# PR番号で指定
$ gut explain #42

# URLでもOK
$ gut explain https://github.com/owner/repo/pull/42

さらに、ファイルを指定するとそのファイルの内容や変更履歴を説明してくれます:

# ファイルの内容を説明
$ gut explain src/auth.ts

# ファイルの最近の変更履歴を説明
$ gut explain src/auth.ts --history

# 直近5コミット分の変更を説明
$ gut explain src/auth.ts --history -n 5

新しくプロジェクトに参加したときや、久しぶりに触るコードを理解するのに重宝します!

コミットの検索

$ gut find "ログイン機能"

🔍 Found 3 matching commits:

1. abc1234 - feat(auth): add login form component
   Reason: Implements the login UI functionality

2. def5678 - fix(auth): handle login timeout error
   Reason: Fixes an issue with the login feature

「あの機能いつ実装したっけ?」という曖昧な検索をAIが解釈して、関連するコミットを見つけます。

技術的な実装

アーキテクチャ

gutは以下の技術スタックで構築されています:

  • TypeScript: 型安全な実装
  • Commander.js: CLIフレームワーク
  • Vercel AI SDK: マルチプロバイダー対応
  • Zod: スキーマ定義と構造化出力
  • simple-git: Git操作
  • keytar: セキュアな認証情報管理

Vercel AI SDKによるマルチプロバイダー対応

複数のAIプロバイダーに対応するため、Vercel AI SDKを採用しました。これにより、プロバイダーごとの差異を吸収しています:

import { generateText, generateObject } from 'ai'
import { createGoogleGenerativeAI } from '@ai-sdk/google'
import { createOpenAI } from '@ai-sdk/openai'
import { createAnthropic } from '@ai-sdk/anthropic'

const DEFAULT_MODELS: Record<Provider, string> = {
  gemini: 'gemini-2.0-flash',
  openai: 'gpt-4o-mini',
  anthropic: 'claude-sonnet-4-20250514'
}

async function getModel(options: AIOptions) {
  const apiKey = await getApiKey(options.provider)

  switch (options.provider) {
    case 'gemini': {
      const google = createGoogleGenerativeAI({ apiKey })
      return google(modelName)
    }
    case 'openai': {
      const openai = createOpenAI({ apiKey })
      return openai(modelName)
    }
    case 'anthropic': {
      const anthropic = createAnthropic({ apiKey })
      return anthropic(modelName)
    }
  }
}

ユーザーは--providerオプションで好きなプロバイダーを選べます:

$ gut commit --provider openai

Zodによる構造化出力

AIからの出力を型安全に扱うため、Zodスキーマを定義しています:

const CodeReviewSchema = z.object({
  summary: z.string().describe('Brief overall assessment'),
  issues: z.array(
    z.object({
      severity: z.enum(['critical', 'warning', 'suggestion']),
      file: z.string(),
      line: z.number().optional(),
      message: z.string(),
      suggestion: z.string().optional()
    })
  ),
  positives: z.array(z.string()).describe('Good practices observed')
})

Vercel AI SDKのgenerateObjectを使うことで、AIの出力を直接このスキーマに沿った型付きオブジェクトとして取得できます:

const result = await generateObject({
  model,
  schema: CodeReviewSchema,
  prompt: `You are an expert code reviewer...`
})

// result.object は CodeReview 型として型安全に使える

セキュアな認証情報管理

APIキーの管理にはkeytarを使用しています。keytarはOSのネイティブ認証情報ストレージ(macOSのKeychain、WindowsのCredential Vault、LinuxのSecret Service API)を利用するため、平文でキーを保存することなくセキュアに管理できます:

import keytar from 'keytar'

const SERVICE_NAME = 'gut-cli'

export async function saveApiKey(provider: Provider, key: string): Promise<void> {
  await keytar.setPassword(SERVICE_NAME, provider, key)
}

export async function getApiKey(provider: Provider): Promise<string | null> {
  return await keytar.getPassword(SERVICE_NAME, provider)
}

プロジェクト固有の設定

gutはプロジェクトごとにカスタマイズ可能です。.gut/ディレクトリにテンプレートファイルを置くことで、AIの出力をプロジェクトのルールに合わせられます:

ファイル 用途
.gut/commit.md コミットメッセージのルール
.gut/pr.md PRの説明文テンプレート
.gut/branch.md ブランチ命名規則
.gut/merge.md コンフリクト解決戦略
.gut/checkout.md diffからのブランチ名生成ルール
.gut/stash.md stash名の生成ルール

テンプレートを設定しない場合

.gut/フォルダにテンプレートを置かなくても、gutはデフォルトのルールで動作します。たとえばコミットメッセージならConventional Commits形式で生成されますし、ブランチ名も一般的な命名規則に従います。

デフォルトでは英語で出力されますが、lang jaを設定しておけば日本語で生成してくれます:

$ gut config set lang ja

これだけで、テンプレートを用意しなくても日本語のコミットメッセージやPR説明文が生成されるようになります!

もちろん、より細かくルールを指定したい場合は.gut/フォルダにテンプレートを追加できます。

例えば、コミットメッセージに日本語を使いたい場合:

<!-- .gut/commit.md -->
# コミットメッセージ規約

- 日本語で記述する
- 形式: [種別] 説明
- 種別: 機能追加、バグ修正、リファクタリング、ドキュメント
- 例: [機能追加] ログイン機能を実装

また、グローバルに日本語出力を設定することも可能です:

$ gut config set lang ja

インストールと使い方

# 1. インストール
npm install -g gut-cli

# 2. APIキーの設定(システムのキーチェーンに安全に保存されます)
gut auth login --provider gemini

# 3. 使ってみる
gut commit          # コミットメッセージを生成
gut pr              # PR説明文を生成
gut review          # AIコードレビュー

# 4.(オプション)テンプレートをカスタマイズ
gut init            # .gut/ に編集可能なテンプレートを作成

対応プロバイダー:gemini(デフォルト)、openai、anthropic

gut initで生成されるテンプレートは、言語設定が日本語(gut config set lang ja)の場合、自動的に日本語に翻訳されます。生成されたテンプレートはプロジェクトに合わせて自由にカスタマイズできます。

まとめ

gutは「gitワークフローの小さな面倒をAIで解消する」というコンセプトで作りました。既存のAIコーディングツールとは異なり、git操作に特化することで高速かつ実用的なツールになっています。

サブスクリプション不要で、自分のAPIキーさえあれば使えます。ぜひ試してみてください!

https://github.com/gitton-dev/gut

Discussion