diff --git a/README.md b/README.md index fbc869b..8ad7269 100644 --- a/README.md +++ b/README.md @@ -1,193 +1,106 @@ +
+ # ai-commit -[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) -[![Python](https://img.shields.io/badge/python-3.9+-blue.svg)](https://www.python.org/downloads/) -[![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit)](https://pre-commit.com/) -[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-%23FE5196?logo=conventionalcommits)](https://conventionalcommits.org/) +Zero-dependency Git prepare-commit-msg hook for Conventional Commits via any OpenAI-compatible API. + [![CI](https://github.com/mcocdaa/ai-commit/actions/workflows/ci.yml/badge.svg)](https://github.com/mcocdaa/ai-commit/actions/workflows/ci.yml) [![Latest Release](https://img.shields.io/github/v/release/mcocdaa/ai-commit?color=blue&label=latest%20release)](https://github.com/mcocdaa/ai-commit/releases/latest) +[![Python 3.9+](https://img.shields.io/badge/python-3.9+-blue.svg)](https://www.python.org/downloads/) +[![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit)](https://pre-commit.com/) +[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-%23FE5196?logo=conventionalcommits)](https://conventionalcommits.org/) +[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) -### 🎬 Live Demo - -

- ai-commit Live Demo -

+[English](README.md) · [简体中文](README_CN.md) -AI-powered Git commit message generator hook. Generates [Conventional Commits](https://www.conventionalcommits.org/) messages using any OpenAI-compatible API. +ai-commit demo -**Zero external dependencies** — uses only Python standard library (`json`, `urllib`, `subprocess`, `fnmatch`). +
-## Features +## ✨ Highlights -- Generates Conventional Commits format messages from your staged diff -- Works with any OpenAI-compatible API (DeepSeek, OpenAI, etc.) -- **Zero external dependencies** — pure Python standard library -- Respects `.opencommitignore` for excluding files from diff analysis -- Abbreviates large diffs (configurable threshold, default 1000 lines) -- Multi-language support (en, zh, zh-TW, ja, ko) -- Graceful degradation: if AI fails, your commit still proceeds -- `git commit` → AI generates the full message -- `git commit -m "aaa"` → AI appends details after your message "aaa" -- Native Windows support (no WSL required) -- Debug mode with full pipeline visibility (`verbose: true` in pre-commit config) +- **Zero Third-Party Dependencies** — Powered strictly by the Python 3.9+ standard library (`json`, `urllib`, `subprocess`, `fnmatch`) with no external `pip` packages required. +- **Seamless `prepare-commit-msg` Workflow** — Generates full [Conventional Commits](https://www.conventionalcommits.org/) messages on `git commit`, or appends structured details when you run `git commit -m "summary"`. +- **Smart Diff Compression & `.opencommitignore` Filtering** — Automatically excludes lockfiles, minified bundles, and custom `.opencommitignore` patterns while truncating oversized diffs to stay within token budgets. +- **Universal OpenAI-Compatible Support** — Works out of the box with DeepSeek, OpenAI, Ollama, vLLM, and any `/v1/chat/completions` endpoint. +- **Multi-Language Output** — Supports commit generation in English (`en`), Simplified/Traditional Chinese (`zh`, `zh-TW`), Japanese (`ja`), and Korean (`ko`). +- **Graceful Fallback** — Never blocks your Git workflow; if the network or API fails, your commit proceeds normally. -## Quick Start +## 🚀 Quick Start -### Via pre-commit Framework (Recommended) +### 1. Configure `pre-commit` -1. Install [pre-commit](https://pre-commit.com/): `pip install pre-commit` -2. Add to your `.pre-commit-config.yaml`: +Add `ai-commit` to your `.pre-commit-config.yaml` and install the `prepare-commit-msg` hook: ```yaml repos: - repo: https://github.com/mcocdaa/ai-commit.git - rev: main # or specify the latest release tag (see badge above) + rev: v1.0.0 # Run `pre-commit autoupdate` for the latest release hooks: - id: ai-commit ``` -> 💡 **Tip — Always stay on the latest version**: -> - Run `pre-commit autoupdate` anytime to automatically update `ai-commit` to the latest release tag. -> - Or use `rev: main` if you prefer to automatically track the newest changes on `main`. - -3. Install the hook: - ```bash +pip install pre-commit pre-commit install --hook-type prepare-commit-msg ``` -> **Tip**: If you also ran `pre-commit install` (without `--hook-type`), other hooks may run twice. Add `default_stages: [pre-commit]` at the top of your `.pre-commit-config.yaml` to prevent this. ai-commit's own `stages: [prepare-commit-msg]` is defined in the hook and is not affected. +### 2. Set Your API Key & Commit -### Local / Testing +```bash +export AI_COMMIT_API_KEY="sk-..." +git add -A && git commit +``` -For local development or testing without a published repo: +## ⚙️ Configuration -```yaml -repos: - - repo: /path/to/ai-commit - hooks: - - id: ai-commit -``` +Configure via environment variables, project `.ai-commit.json`, or global `~/.ai-commit.json` (precedence: `ENV` > `./.ai-commit.json` > `~/.ai-commit.json`): -Or use `repo: .` if the hook files are in your project root. +| Environment Variable | `.ai-commit.json` Key | Default | Description | +| :--- | :--- | :--- | :--- | +| `AI_COMMIT_API_KEY` | `api_key` | `""` | API key for the OpenAI-compatible provider | +| `AI_COMMIT_API_BASE_URL` | `api_base_url` | `https://api.deepseek.com` | Base URL for chat completions API | +| `AI_COMMIT_MODEL` | `model` | `deepseek-v4-flash` | Model identifier used for generation | +| `AI_COMMIT_LANGUAGE` | `language` | `en` | Output language (`en`, `zh`, `zh-TW`, `ja`, `ko`) | +| `AI_COMMIT_MAX_DIFF_LINES` | `max_diff_lines` | `1000` | Max diff lines per file before abbreviation | +| `AI_COMMIT_MAX_OUTPUT_TOKENS` | `max_output_tokens` | `2048` | Max tokens for generated response | +| `AI_COMMIT_IGNORE_FILE` | `ignore_file` | `.opencommitignore` | Ignore file for excluding paths from diff analysis | +| `AI_COMMIT_THINKING` | `thinking` | `false` | Enable/disable reasoning mode on DeepSeek models | +| `AI_COMMIT_DEBUG` | `debug` | `false` | Print diagnostic pipeline logs to `stderr` | -## Configuration +
+Advanced Configuration & Troubleshooting -Create `.ai-commit.json` in your project root (or `~/.ai-commit.json` for global): +### Example `.ai-commit.json` ```json { - "api_key": "", "api_base_url": "https://api.deepseek.com", "model": "deepseek-v4-flash", "max_diff_lines": 1000, - "max_output_tokens": 2048, - "debug": false, "language": "en", "ignore_file": ".opencommitignore", "thinking": false } ``` -### Config Priority +### Custom Ignore Rules (`.opencommitignore`) -Environment variables > project `.ai-commit.json` > global `~/.ai-commit.json` +Lockfiles (`uv.lock`, `package-lock.json`, `pnpm-lock.yaml`, `Cargo.lock`, `poetry.lock`) and `*.min.js` / `*.min.css` are ignored by default. Add custom `.gitignore`-style patterns in `.opencommitignore`: -| Config Key | Env Variable | Default | -|---|---|---| -| `api_key` | `AI_COMMIT_API_KEY` | `""` | -| `api_base_url` | `AI_COMMIT_API_BASE_URL` | `https://api.deepseek.com` | -| `model` | `AI_COMMIT_MODEL` | `deepseek-v4-flash` | -| `max_diff_lines` | `AI_COMMIT_MAX_DIFF_LINES` | `1000` | -| `max_output_tokens` | `AI_COMMIT_MAX_OUTPUT_TOKENS` | `2048` | -| `debug` | `AI_COMMIT_DEBUG` | `false` | -| `language` | `AI_COMMIT_LANGUAGE` | `en` | -| `ignore_file` | `AI_COMMIT_IGNORE_FILE` | `.opencommitignore` | -| `thinking` | `AI_COMMIT_THINKING` | `false` | - -### API Key Security - -- **Recommended**: Set `AI_COMMIT_API_KEY` environment variable -- **Per-project**: Use `.ai-commit.json` (auto-added to `.gitignore`) -- **Global**: Use `~/.ai-commit.json` with restricted permissions -- **Never** commit API keys to version control - -### .opencommitignore - -Exclude files from diff analysis: - -``` +```gitignore *.md -package-lock.json dist/ +fixtures/*.json ``` -### Debug Mode - -Set `debug: true` in `.ai-commit.json` or `AI_COMMIT_DEBUG=true` env var. To see debug output during `git commit`, add `verbose: true` to the hook config: - -```yaml -repos: - - repo: https://github.com/mcocdaa/ai-commit.git - rev: main - hooks: - - id: ai-commit - verbose: true -``` - -### Thinking Mode (DeepSeek) - -DeepSeek V4 models support a reasoning/thinking mode (`deepseek-v4-flash`, `deepseek-v4-pro`, etc.). Set `thinking: true` to enable it, or `thinking: false` for standard chat mode: - -```json -{ - "thinking": false -} -``` - -When thinking is disabled, the model outputs the commit message directly without intermediate reasoning. This reduces token usage and response time. Use `thinking: false` if you encounter empty responses from the AI (reasoning consumed all output tokens before the model could write the commit message). - -## Dependencies - -- **Python 3.9+** — No pip packages required -- **Git** — Obviously - -## File Structure - -``` -ai-commit/ -├── prepare_commit_msg_hooks/ -│ ├── __init__.py -│ ├── ai_commit_gen.py # Entry point & orchestration -│ └── util/ -│ ├── __init__.py -│ ├── api.py # OpenAI-compatible API client -│ ├── config.py # Configuration & constants -│ ├── diff_processor.py # Diff filtering & abbreviation -│ ├── git_util.py # Git subprocess wrappers -│ └── gitignore.py # .gitignore-style pattern matching -├── .pre-commit-hooks.yaml # pre-commit framework hook definition -├── setup.py # Editable install stub -├── pyproject.toml # Package metadata, build & tool config -├── tests/ -│ └── test_ai_commit_gen.py # Pytest test suite (24 tests) -├── README.md # This file -├── AGENTS.md # AI agent integration guide -├── LICENSE # MIT License -└── .ai-commit.json # Configuration (gitignored) -``` +### Debugging & Pre-Commit Hook Stages -## How It Works +- **Verbose Hook Output**: Set `AI_COMMIT_DEBUG=true` and add `verbose: true` under `- id: ai-commit` in `.pre-commit-config.yaml` to inspect diff filtering and API payloads. +- **Avoid Duplicate Hook Runs**: If you use both `pre-commit` and `prepare-commit-msg` hooks, add `default_stages: [pre-commit]` at the top of `.pre-commit-config.yaml`. -1. The `prepare-commit-msg` hook is triggered by Git before the editor opens -2. The script reads staged diff via `git diff --cached` -3. Files matching `.opencommitignore` patterns are excluded -4. Large diffs (per `max_diff_lines`) are abbreviated -5. The diff + file summary is sent to the OpenAI-compatible chat completions API -6. The generated commit message is written to the commit message file -7. If `git commit -m "..."` was used, AI appends after your message -8. If AI fails for any reason, the commit proceeds normally +
-## License +## 📄 License -MIT +Released under the [MIT License](LICENSE). diff --git a/README_CN.md b/README_CN.md new file mode 100644 index 0000000..1662a42 --- /dev/null +++ b/README_CN.md @@ -0,0 +1,106 @@ +
+ +# ai-commit + +零外部依赖、支持任意 OpenAI 兼容接口的 Git Conventional Commits 自动生成钩子。 + +[![CI](https://github.com/mcocdaa/ai-commit/actions/workflows/ci.yml/badge.svg)](https://github.com/mcocdaa/ai-commit/actions/workflows/ci.yml) +[![Latest Release](https://img.shields.io/github/v/release/mcocdaa/ai-commit?color=blue&label=latest%20release)](https://github.com/mcocdaa/ai-commit/releases/latest) +[![Python 3.9+](https://img.shields.io/badge/python-3.9+-blue.svg)](https://www.python.org/downloads/) +[![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit)](https://pre-commit.com/) +[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-%23FE5196?logo=conventionalcommits)](https://conventionalcommits.org/) +[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) + +[English](README.md) · [简体中文](README_CN.md) + +ai-commit demo + +
+ +## ✨ 核心特性 + +- **零第三方依赖** — 仅使用 Python 3.9+ 标准库(`json`、`urllib`、`subprocess`、`fnmatch`),无需安装任何额外 `pip` 依赖包。 +- **无缝融入 Git 工作流** — 基于 `prepare-commit-msg` 钩子:直接运行 `git commit` 自动生成完整 [Conventional Commits](https://www.conventionalcommits.org/) 提交信息;使用 `git commit -m "摘要"` 时自动在摘要后追加结构化变更详情。 +- **智能 Diff 压缩与 `.opencommitignore` 过滤** — 自动剔除各类 Lockfile、压缩产物及 `.opencommitignore` 匹配文件,并对超大 Diff 智能截断以控制 Token 消耗。 +- **通用 OpenAI 兼容接口支持** — 开箱即用支持 DeepSeek、OpenAI、Ollama、vLLM 等任意兼容 `/v1/chat/completions` 的服务。 +- **多语言生成** — 支持英文(`en`)、简体/繁体中文(`zh`、`zh-TW`)、日文(`ja`)与韩文(`ko`)提交信息。 +- **优雅降级** — 绝不阻塞提交流程;若网络超时或 API 调用失败,Git 提交将静默回退并正常继续。 + +## 🚀 快速开始 + +### 1. 配置 `pre-commit` + +在项目的 `.pre-commit-config.yaml` 中添加 `ai-commit` 并安装 `prepare-commit-msg` 钩子: + +```yaml +repos: + - repo: https://github.com/mcocdaa/ai-commit.git + rev: v1.0.0 # 可运行 `pre-commit autoupdate` 自动更新至最新版本 + hooks: + - id: ai-commit +``` + +```bash +pip install pre-commit +pre-commit install --hook-type prepare-commit-msg +``` + +### 2. 配置 API Key 并提交 + +```bash +export AI_COMMIT_API_KEY="sk-..." +git add -A && git commit +``` + +## ⚙️ 配置说明 + +支持通过环境变量、项目根目录 `.ai-commit.json` 或全局 `~/.ai-commit.json` 配置(优先级:`环境变量` > `./.ai-commit.json` > `~/.ai-commit.json`): + +| 环境变量 | `.ai-commit.json` 键名 | 默认值 | 说明 | +| :--- | :--- | :--- | :--- | +| `AI_COMMIT_API_KEY` | `api_key` | `""` | OpenAI 兼容接口的 API Key | +| `AI_COMMIT_API_BASE_URL` | `api_base_url` | `https://api.deepseek.com` | Chat Completions 接口基础地址 | +| `AI_COMMIT_MODEL` | `model` | `deepseek-v4-flash` | 用于生成提交信息的模型名称 | +| `AI_COMMIT_LANGUAGE` | `language` | `en` | 输出语言(`en`、`zh`、`zh-TW`、`ja`、`ko`) | +| `AI_COMMIT_MAX_DIFF_LINES` | `max_diff_lines` | `1000` | 单文件 Diff 触发缩写的最大行数阈值 | +| `AI_COMMIT_MAX_OUTPUT_TOKENS` | `max_output_tokens` | `2048` | 模型输出的最大 Token 数 | +| `AI_COMMIT_IGNORE_FILE` | `ignore_file` | `.opencommitignore` | 排除 Diff 分析的忽略规则文件名 | +| `AI_COMMIT_THINKING` | `thinking` | `false` | 是否开启 DeepSeek 模型的思考/推理模式 | +| `AI_COMMIT_DEBUG` | `debug` | `false` | 是否向 `stderr` 输出调试日志 | + +
+高级配置与常见问题排查 + +### `.ai-commit.json` 配置示例 + +```json +{ + "api_base_url": "https://api.deepseek.com", + "model": "deepseek-v4-flash", + "max_diff_lines": 1000, + "language": "zh", + "ignore_file": ".opencommitignore", + "thinking": false +} +``` + +### 自定义忽略规则(`.opencommitignore`) + +默认已忽略常见锁文件(`uv.lock`、`package-lock.json`、`pnpm-lock.yaml`、`Cargo.lock`、`poetry.lock`)与 `*.min.js` / `*.min.css`。可在项目根目录创建 `.opencommitignore` 添加自定义规则: + +```gitignore +*.md +dist/ +fixtures/*.json +``` + +### 调试模式与钩子阶段配置 + +- **查看详细调试输出**:设置 `AI_COMMIT_DEBUG=true`,并在 `.pre-commit-config.yaml` 的 `- id: ai-commit` 下添加 `verbose: true` 即可在提交时查看完整流水线日志。 +- **避免其他钩子重复执行**:若同时安装了 `pre-commit` 与 `prepare-commit-msg` 钩子,建议在 `.pre-commit-config.yaml` 顶部添加 `default_stages: [pre-commit]`。 + +
+ +## 📄 License + +本项目基于 [MIT License](LICENSE) 开源。