{"id":35788390,"url":"https://github.com/tumf/jj-desc","last_synced_at":"2026-04-04T11:33:29.421Z","repository":{"id":332413196,"uuid":"1129023706","full_name":"tumf/jj-desc","owner":"tumf","description":"Generate jj (Jujutsu) commit descriptions automatically using LLMs","archived":false,"fork":false,"pushed_at":"2026-01-08T08:16:31.000Z","size":1754,"stargazers_count":6,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-01T22:51:45.185Z","etag":null,"topics":["anthropic","cli","commit-message","jj","jujutsu","llm","openai","openrouter","rust"],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tumf.png","metadata":{"files":{"readme":"README.ja.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-01-06T13:53:53.000Z","updated_at":"2026-02-08T10:27:29.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/tumf/jj-desc","commit_stats":null,"previous_names":["tumf/jj-desc"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/tumf/jj-desc","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tumf%2Fjj-desc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tumf%2Fjj-desc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tumf%2Fjj-desc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tumf%2Fjj-desc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tumf","download_url":"https://codeload.github.com/tumf/jj-desc/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tumf%2Fjj-desc/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31398230,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-04T10:20:44.708Z","status":"ssl_error","status_checked_at":"2026-04-04T10:20:06.846Z","response_time":60,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["anthropic","cli","commit-message","jj","jujutsu","llm","openai","openrouter","rust"],"created_at":"2026-01-07T07:25:42.658Z","updated_at":"2026-04-04T11:33:29.413Z","avatar_url":"https://github.com/tumf.png","language":"Rust","funding_links":[],"categories":["cli"],"sub_categories":[],"readme":"# jj-desc\n\n[jj (Jujutsu)](https://github.com/martinvonz/jj) のコミット説明文を LLM を使って自動生成するCLIツールです。\n\n[English](README.md) | 日本語\n\n## 特徴\n\n- 🤖 diff から LLM を使って意味のあるコミット説明文を自動生成\n- 📦 **バッチ処理**: revset を使って複数のコミットを一括処理\n- 🔄 jj の undo ワークフローとシームレスに連携（確認プロンプト不要）\n- 🎯 複数の LLM プロバイダーに対応: OpenRouter, OpenAI, Anthropic, Gemini\n- 🔌 カスタムエンドポイント対応（Azure OpenAI, Ollama, LM Studio など）\n- 🔍 `--dry-run` でプレビューモード\n- 💬 インタラクティブモードで適用前に確認\n- 🎚️ jj の revset 構文で柔軟にターゲット指定\n- 📝 [Conventional Commits](https://www.conventionalcommits.org/) 形式に準拠\n- 🔀 マージコミットを自動処理（空のマージコミットは LLM 呼び出し不要）\n- ⚡ 大きな diff に最適化: ロックファイルを自動除外、バイナリファイルを簡略化\n- 🎛️ `--exclude` オプションでファイル除外をカスタマイズ可能\n\n## デモ\n\n![jj-desc demo](docs/demo.gif)\n\n## インストール\n\n### Homebrew (macOS/Linux)\n\nmacOS または Linux での推奨インストール方法:\n\n```bash\nbrew install tumf/tap/jj-desc\n```\n\n### ビルド済みバイナリ\n\n[最新リリース](https://github.com/tumf/jj-desc/releases/latest)からプラットフォーム用のビルド済みバイナリをダウンロードできます。\n\n#### macOS\n\n**インストーラースクリプトを使用（推奨）:**\n\n```bash\ncurl --proto '=https' --tlsv1.2 -LsSf https://github.com/tumf/jj-desc/releases/latest/download/jj-desc-installer.sh | sh\n```\n\n**手動ダウンロード:**\n\n- Apple Silicon (M1/M2/M3): [jj-desc-aarch64-apple-darwin.tar.xz](https://github.com/tumf/jj-desc/releases/latest/download/jj-desc-aarch64-apple-darwin.tar.xz)\n- Intel: [jj-desc-x86_64-apple-darwin.tar.xz](https://github.com/tumf/jj-desc/releases/latest/download/jj-desc-x86_64-apple-darwin.tar.xz)\n\n```bash\n# Apple Silicon の例\ncurl -LO https://github.com/tumf/jj-desc/releases/latest/download/jj-desc-aarch64-apple-darwin.tar.xz\ntar xf jj-desc-aarch64-apple-darwin.tar.xz\nsudo mv jj-desc /usr/local/bin/\n```\n\n#### Linux\n\n**インストーラースクリプトを使用（推奨）:**\n\n```bash\ncurl --proto '=https' --tlsv1.2 -LsSf https://github.com/tumf/jj-desc/releases/latest/download/jj-desc-installer.sh | sh\n```\n\n**手動ダウンロード:**\n\n- x86_64: [jj-desc-x86_64-unknown-linux-gnu.tar.xz](https://github.com/tumf/jj-desc/releases/latest/download/jj-desc-x86_64-unknown-linux-gnu.tar.xz)\n- ARM64: [jj-desc-aarch64-unknown-linux-gnu.tar.xz](https://github.com/tumf/jj-desc/releases/latest/download/jj-desc-aarch64-unknown-linux-gnu.tar.xz)\n\n```bash\n# x86_64 の例\ncurl -LO https://github.com/tumf/jj-desc/releases/latest/download/jj-desc-x86_64-unknown-linux-gnu.tar.xz\ntar xf jj-desc-x86_64-unknown-linux-gnu.tar.xz\nsudo mv jj-desc /usr/local/bin/\n```\n\n#### Windows\n\n**PowerShell インストーラーを使用（推奨）:**\n\n```powershell\npowershell -ExecutionPolicy Bypass -c \"irm https://github.com/tumf/jj-desc/releases/latest/download/jj-desc-installer.ps1 | iex\"\n```\n\n**手動ダウンロード:**\n\n[jj-desc-x86_64-pc-windows-msvc.zip](https://github.com/tumf/jj-desc/releases/latest/download/jj-desc-x86_64-pc-windows-msvc.zip) をダウンロードし、`jj-desc.exe` を PATH の通ったディレクトリに展開してください。\n\n### ソースからビルド (Cargo)\n\nRust がインストールされている場合:\n\n```bash\ncargo install --git https://github.com/tumf/jj-desc\n```\n\nまたは、ローカルクローンからビルド:\n\n```bash\ngit clone https://github.com/tumf/jj-desc\ncd jj-desc\ncargo install --path .\n```\n\n### 必要条件\n\n- [jj](https://github.com/martinvonz/jj) がインストールされ、PATH で利用可能であること\n- 使用する LLM プロバイダーの API キー\n- ソースからビルドする場合: Rust 1.85+ (Edition 2024)\n\n## 設定\n\n### LLM プロバイダーの選択\n\n`LLM_PROVIDER` 環境変数または `--provider` CLI オプションで LLM プロバイダーを選択:\n\n```bash\nexport LLM_PROVIDER=openai        # オプション: openrouter, openai, anthropic, gemini\n```\n\n### 環境変数\n\n#### 共通設定\n\n| 変数 | 必須 | デフォルト | 説明 |\n|------|------|------------|------|\n| `LLM_PROVIDER` | ❌ | `openrouter` | 使用する LLM プロバイダー |\n| `LLM_MODEL` | ❌ | (プロバイダーのデフォルト) | モデルを上書き |\n\n#### プロバイダー別 API キー\n\n| プロバイダー | 環境変数 | API キー取得先 |\n|-------------|---------|---------------|\n| OpenRouter | `OPENROUTER_API_KEY` | [OpenRouter](https://openrouter.ai/) |\n| OpenAI | `OPENAI_API_KEY` | [OpenAI Platform](https://platform.openai.com/) |\n| Anthropic | `ANTHROPIC_API_KEY` | [Anthropic Console](https://console.anthropic.com/) |\n| Gemini | `GEMINI_API_KEY` | [Google AI Studio](https://aistudio.google.com/) |\n\n#### プロバイダー別ベース URL（オプション）\n\nカスタムセットアップ用にデフォルトの API エンドポイントを上書き:\n\n| プロバイダー | 環境変数 | デフォルト値 |\n|-------------|---------|-------------|\n| OpenRouter | `OPENROUTER_BASE_URL` | `https://openrouter.ai/api/v1` |\n| OpenAI | `OPENAI_BASE_URL` | `https://api.openai.com/v1` |\n| Anthropic | `ANTHROPIC_BASE_URL` | `https://api.anthropic.com` |\n| Gemini | `GEMINI_BASE_URL` | `https://generativelanguage.googleapis.com/v1beta/openai` |\n\n#### プロバイダー別デフォルトモデル\n\n| プロバイダー | デフォルトモデル |\n|-------------|-----------------|\n| OpenRouter | `anthropic/claude-sonnet-4` |\n| OpenAI | `gpt-4o` |\n| Anthropic | `claude-sonnet-4-20250514` |\n| Gemini | `gemini-2.0-flash` |\n\n### 設定例\n\n#### OpenRouter（デフォルト）\n\n```bash\nexport OPENROUTER_API_KEY=\"your-api-key-here\"\n```\n\n#### OpenAI\n\n```bash\nexport LLM_PROVIDER=openai\nexport OPENAI_API_KEY=\"sk-...\"\n```\n\n#### Anthropic\n\n```bash\nexport LLM_PROVIDER=anthropic\nexport ANTHROPIC_API_KEY=\"sk-ant-...\"\n```\n\n#### Gemini\n\n```bash\nexport LLM_PROVIDER=gemini\nexport GEMINI_API_KEY=\"...\"\n```\n\n#### Azure OpenAI\n\n```bash\nexport LLM_PROVIDER=openai\nexport OPENAI_API_KEY=\"your-azure-key\"\nexport OPENAI_BASE_URL=\"https://your-resource.openai.azure.com/openai/deployments/your-deployment\"\nexport LLM_MODEL=\"gpt-4\"\n```\n\n#### Ollama（ローカル LLM）\n\n```bash\nexport LLM_PROVIDER=openai\nexport OPENAI_API_KEY=\"dummy\"  # Ollama はキー不要\nexport OPENAI_BASE_URL=\"http://localhost:11434/v1\"\nexport LLM_MODEL=\"llama2\"\n```\n\n#### LM Studio（ローカル LLM）\n\n```bash\nexport LLM_PROVIDER=openai\nexport OPENAI_API_KEY=\"dummy\"  # LM Studio はキー不要\nexport OPENAI_BASE_URL=\"http://localhost:1234/v1\"\nexport LLM_MODEL=\"your-model-name\"\n```\n\n恒久的な設定には、これらをシェル設定ファイル（`~/.bashrc`, `~/.zshrc` など）に追加してください。\n\n## 使い方\n\n### 基本的な使い方\n\nデフォルトでは、`jj-desc` は `::@ \u0026 mutable()` 内の説明文がないすべての変更可能なコミットに対して説明文を生成します:\n\n```bash\njj-desc\n```\n\n### 単一のコミットに説明文を生成\n\n現在のワーキングコピーに説明文を生成して適用:\n\n```bash\njj-desc -r @\n```\n\n### 特定のリビジョンをターゲット\n\njj の revset 構文を使って特定のリビジョンをターゲット:\n\n```bash\n# 自分のコミットを処理\njj-desc -r \"mine()\"\n\n# 特定の範囲のコミットを処理\njj-desc -r \"@..main\"\n\n# 特定のリビジョンを処理\njj-desc -r @-\n\n# 処理するコミット数を制限\njj-desc -n 5\n\n# 適用前にプレビュー\njj-desc --dry-run\n\n# インタラクティブモード - 各説明文を確認\njj-desc -i\n```\n\n### プレビューモード\n\n適用せずに生成される説明文を確認:\n\n```bash\njj-desc --dry-run\n```\n\n### 別のプロバイダーを使用\n\nプロバイダーを上書き:\n\n```bash\njj-desc --provider openai\njj-desc --provider anthropic\n```\n\n### 別のモデルを使用\n\nデフォルトモデルを上書き:\n\n```bash\njj-desc --model gpt-4o\n# または\njj-desc --model anthropic/claude-3.5-sonnet\n```\n\n### 詳細ログ\n\nデバッグ用に詳細ログを有効化:\n\n```bash\njj-desc --verbose\n```\n\nまたは `RUST_LOG` 環境変数を使用:\n\n```bash\nRUST_LOG=debug jj-desc\n```\n\n### diff からファイルを除外\n\nLLM に送信する diff から特定のファイルやパターンを除外:\n\n```bash\n# 特定のファイルを除外\njj-desc --exclude \"*.json\" --exclude \"*.yaml\"\n\n# 短縮形\njj-desc -x \"docs/*\" -x \"*.lock\"\n```\n\n**自動的に除外されるファイル:**\n- ロックファイル: `Cargo.lock`, `package-lock.json`, `pnpm-lock.yaml`, `yarn.lock`, `*.lock`, `*.lockb`\n- バイナリファイルは自動的に `\"Binary file {path} changed\"` に簡略化\n\n**ファイルを除外する理由:**\n- トークン使用量とコストを削減\n- コンテキスト制限超過による API エラーを防止\n- 意味のある変更に焦点を当てて説明文の品質を向上\n\n**大きな diff の警告:**\nフィルタリング後の diff が 50KB を超えると警告が表示されます:\n```\n⚠ Warning: Diff is large (75000 bytes, 3500 lines)\n  Consider splitting into smaller commits.\n```\n\n### コマンドラインオプション\n\n```\nUsage: jj-desc [OPTIONS]\n\nOptions:\n      --dry-run                    適用せずに生成される説明文をプレビュー\n      --provider \u003cPROVIDER\u003e        使用する LLM プロバイダー (openrouter, openai, anthropic, gemini)\n      --model \u003cMODEL\u003e              使用する LLM モデルを上書き\n      --max-tokens \u003cMAX_TOKENS\u003e    LLM レスポンスの最大トークン数\n      --temperature \u003cTEMPERATURE\u003e  LLM レスポンスの temperature (0.0-2.0)\n  -r, --revisions \u003cREVISIONS\u003e      ターゲットコミットを選択する revset [default: \"::@ \u0026 mutable()\"]\n  -n, --limit \u003cLIMIT\u003e              処理するコミットの最大数\n  -i, --interactive                各説明文を適用する前に確認\n  -x, --exclude \u003cEXCLUDE\u003e          diff から除外するファイル（複数指定可）\n  -v, --verbose                    詳細ログを有効化\n  -h, --help                       ヘルプを表示\n  -V, --version                    バージョンを表示\n```\n\n## 使用例\n\n### 例1: 基本的なワークフロー\n\n```bash\n# 変更を加える\necho \"fn hello() {}\" \u003e\u003e lib.rs\n\n# 現在のワーキングコピーに説明文を生成\njj-desc\n\n# 出力:\n# Applied description:\n# ─────────────────────\n# feat: add hello function\n```\n\n### 例2: 適用前にプレビュー\n\n```bash\njj-desc --dry-run\n\n# 出力:\n# Generated description (not applied):\n# ─────────────────────\n# feat(auth): add JWT authentication\n```\n\n### 例3: 複数のコミットを処理\n\n```bash\n# 説明文がないすべての変更可能なコミットに説明文を生成\njj-desc\n\n# 出力:\n# Found 3 commit(s) without descriptions\n# Processing 3 commit(s)\n#\n# Processing: 1/3 (33%)\n# Commit: abc123def456\n# Generated description:\n#   feat(auth): add authentication endpoint\n# ✓ Description applied\n#\n# Processing: 2/3 (66%)\n# Commit: def456ghi789\n# Generated description:\n#   fix(auth): fix validation bug in login form\n# ✓ Description applied\n#\n# Processing: 3/3 (100%)\n# Commit: ghi789jkl012\n# Generated description:\n#   chore(deps): update dependencies\n# ✓ Description applied\n#\n# ═══════════════════════\n# Summary:\n#   Success:  3\n#   Skipped:  0\n#   Failed:   0\n# ═══════════════════════\n```\n\n### 例4: インタラクティブモード\n\n```bash\njj-desc -i -r \"mine()\"\n\n# 各コミットで以下が表示されます:\n# Processing: 1/5 (20%)\n# Commit: abc123\n# Generated description:\n#   feat(auth): add user authentication\n#\n# Full description:\n# ─────────────────────\n# feat(auth): add JWT authentication\n#\n# Implements login and logout endpoints with secure\n# token generation and validation.\n# ─────────────────────\n# Accept (a) / Skip (s) / Quit (q): a\n# ✓ Description applied\n```\n\n## 動作の仕組み\n\n1. `jj diff` を実行して現在の変更を取得\n2. LLM 処理のために **diff をフィルタリング**:\n   - ロックファイル（`Cargo.lock`, `package-lock.json` など）を自動除外\n   - バイナリファイルを `\"Binary file {path} changed\"` に簡略化\n   - `--exclude` で指定されたユーザー除外を適用\n   - diff が 50KB を超えると警告\n3. フィルタリング後の diff が空の場合:\n   - マージコミットかどうかを確認（`jj log -T 'parents.len()'` を使用）\n   - マージコミットの場合、LLM を呼び出さずに \"Merge commit\" を設定\n   - そうでない場合はエラーを返す\n4. diff が空でない場合、専用のプロンプトとともに選択した LLM プロバイダー API に送信\n5. `jj desc -m` を使用して生成された説明文を適用\n\n### マージコミットの処理\n\njj はマージコミット自体が新しい変更を導入しないため、「空」としてマークすることがよくあります（[jj FAQ](https://docs.jj-vcs.dev/latest/FAQ/#why-are-most-merge-commits-marked-as-empty) を参照）。`jj-desc` はマージコミットを自動検出し、LLM API 呼び出しなしで適切な説明文を設定します。\n\n## Tips: jj push エイリアスで自動化\n\njj エイリアスを追加することで、`jj-desc` を push ワークフローに統合できます。これにより、push のたびに `jj-desc` が自動実行されます:\n\n```bash\n# jj 設定を編集\njj config edit --user\n```\n\n以下のエイリアスを追加:\n\n```toml\n[aliases]\npush = [\"util\", \"exec\", \"--\", \"bash\", \"-c\", \"\"\"\nset -e\n# 説明文がないコミットに説明文を生成（jj-desc がインストールされている場合）\ncommand -v jj-desc \u0026\u003e /dev/null \u0026\u0026 jj-desc\n# pre-commit 設定がある場合はチェックを実行\n[ ! -f .pre-commit-config.yaml ] || pre-commit run --all-files\n# Push\njj git push \\\"$@\\\"\n\"\"\", \"\"]\n```\n\nこれで `jj push` が以下を実行します:\n1. 説明文がないコミットに自動で説明文を生成\n2. pre-commit チェックを実行（設定されている場合）\n3. リモートに push\n\nバイパスするには `jj git push` を直接使用してください。\n\n## なぜ確認プロンプトがないのか？\n\ngit とは異なり、jj では任意の操作を非常に簡単に取り消すことができます:\n\n- `jj undo` - 最後の操作を取り消し\n- `jj op log` - 操作履歴を表示\n- すべての変更は復元可能\n\nこの設計哲学により、説明文を即座に適用しても安全で、ワークフローがより高速でスムーズになります。\n\n## ライセンス\n\nMIT\n\n## コントリビュート\n\nコントリビュートを歓迎します！開発セットアップ、コーディングガイドライン、変更の提出方法については [CONTRIBUTING.md](CONTRIBUTING.md) を参照してください。\n\n## マイグレーションガイド\n\n### 既存ユーザー向け (v0.1.x)\n\n以前のバージョンは OpenRouter のみをサポートしていました。新バージョンは完全な後方互換性を維持しています:\n\n- 既存の `OPENROUTER_API_KEY` 環境変数は引き続き動作\n- 既存の `OPENROUTER_MODEL` 環境変数は引き続き動作\n- 設定の変更は不要\n\n新しいプロバイダーを利用するには、`LLM_PROVIDER` と適切な API キーを設定するだけです。\n\n## 関連リンク\n\n- [jj ドキュメント](https://martinvonz.github.io/jj/)\n- [OpenRouter](https://openrouter.ai/)\n- [OpenAI Platform](https://platform.openai.com/)\n- [Anthropic Console](https://console.anthropic.com/)\n- [Google AI Studio](https://aistudio.google.com/)\n- [jj-desc についてのブログ記事](https://blog.tumf.dev/posts/diary/2026/1/8/jj-desc-release/?utm_source=github\u0026utm_medium=readme\u0026utm_campaign=jj-desc)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftumf%2Fjj-desc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftumf%2Fjj-desc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftumf%2Fjj-desc/lists"}