226 lines
6.1 KiB
Markdown
226 lines
6.1 KiB
Markdown
<div align="center">
|
||
|
||
# gai
|
||
|
||
**AI-powered Git commit and pull request helper**
|
||
|
||
[](https://git.catpl.top/Mplan/gai/releases)
|
||
[](./LICENSE)
|
||
[](https://bun.sh)
|
||
[](https://www.typescriptlang.org/)
|
||
|
||
Generate **Conventional Commits** messages and pull request descriptions using AI, based on your project context, code diff, branch changes, and commit history.
|
||
|
||
</div>
|
||
|
||
---
|
||
|
||
## Features
|
||
|
||
- **Interactive menu** — `gai` opens a menu, select actions with ↑/↓ + space/enter
|
||
- **Context-aware commits** — reads project overview, staged diff, and recent commit history
|
||
- **Conventional Commits** — `feat(scope): description` format by default
|
||
- **Interactive file selection** — ↑/↓ to navigate, space to select, top-level "Select all"
|
||
- **Inline editing** — edit AI-generated messages right in the terminal with cursor movement
|
||
- **AI-generated PRs** — create GitHub, Gitea, or GitLab pull requests with generated title and body
|
||
- **OpenAI-compatible API** — works with DeepSeek, OpenAI, Ollama, OpenRouter, and more
|
||
- **Review before commit** — confirm, edit, or abort the generated message
|
||
- **Bun-native runtime** — built on Bun APIs with no runtime npm dependencies
|
||
|
||
## Quick Start
|
||
|
||
```bash
|
||
# Install dependencies
|
||
bun install
|
||
|
||
# Configure your API key
|
||
gai config
|
||
|
||
# Open interactive menu
|
||
gai
|
||
|
||
# Or directly generate a commit message
|
||
gai commit
|
||
|
||
# Or create an AI-generated pull request
|
||
gai pr
|
||
```
|
||
|
||
## Usage
|
||
|
||
```
|
||
gai Open interactive menu
|
||
gai commit Generate commit message (interactive file selection)
|
||
gai commit --auto Auto-stage all changed files
|
||
gai commit -d Generate message without committing
|
||
gai pr Create a PR with AI-generated title and body
|
||
gai pr --draft Create a draft PR
|
||
gai config Configure API settings
|
||
gai --help Show help
|
||
gai --version Show version
|
||
```
|
||
|
||
### Interactive Menu
|
||
|
||
```
|
||
$ gai
|
||
|
||
gai
|
||
Choose a workflow
|
||
↑/↓ navigate · enter/space select · ctrl+c cancel
|
||
|
||
❯ ● commit Generate AI commit message
|
||
○ pr Create a PR with AI-generated title
|
||
○ config Configure API settings
|
||
```
|
||
|
||
### Commit Flow
|
||
|
||
```
|
||
$ gai commit
|
||
|
||
Staged files (will be included):
|
||
✓ src/git.ts (modified)
|
||
|
||
Select files to stage:
|
||
2 unstaged files available
|
||
↑/↓ navigate · space toggle · enter confirm · ←/backspace back · ctrl+c cancel
|
||
|
||
❯ □ Select all
|
||
□ src/ai.ts modified
|
||
■ src/newfile.ts new
|
||
|
||
Generating commit message...
|
||
|
||
Generated commit message:
|
||
feat(git): add interactive file staging and commit wrapper
|
||
|
||
Use this message? [Y/n/e] Y
|
||
|
||
✔ Committed successfully!
|
||
[main a3f7c2b] feat(git): add interactive file staging and commit wrapper
|
||
1 file changed, 45 insertions(+), 12 deletions(-)
|
||
```
|
||
|
||
### Pull Request Flow
|
||
|
||
`gai pr` detects the remote platform from `origin`:
|
||
|
||
- GitHub remotes use the `gh` CLI
|
||
- Gitea remotes use the `tea` CLI
|
||
- GitLab remotes use the `glab` CLI
|
||
- Unknown remotes prompt you to choose a platform
|
||
|
||
The command compares your current branch against the default branch, pushes the branch if needed, generates a PR title/body from the branch commits and diff, then asks for confirmation before creating the PR.
|
||
|
||
```bash
|
||
gai pr
|
||
gai pr --draft
|
||
```
|
||
|
||
## Configuration
|
||
|
||
### Via `gai config` (interactive)
|
||
|
||
```bash
|
||
gai config
|
||
```
|
||
|
||
### Via environment variables
|
||
|
||
| Variable | Default | Description |
|
||
|---|---|---|
|
||
| `GAI_API_KEY` | — | **Required.** Your API key |
|
||
| `GAI_API_BASE` | `https://api.deepseek.com/v1` | API base URL |
|
||
| `GAI_MODEL` | `deepseek-v4-flash` | Model name |
|
||
| `GAI_MAX_TOKENS` | `500` | Max response tokens |
|
||
| `GAI_TEMPERATURE` | `0.7` | Sampling temperature |
|
||
|
||
### Via `.env` file
|
||
|
||
Bun auto-loads `.env` — no dotenv needed:
|
||
|
||
```bash
|
||
GAI_API_KEY=sk-your-key
|
||
GAI_API_BASE=https://api.deepseek.com/v1
|
||
GAI_MODEL=deepseek-v4-flash
|
||
```
|
||
|
||
### Using other providers
|
||
|
||
<details>
|
||
<summary><strong>OpenAI</strong></summary>
|
||
|
||
```bash
|
||
GAI_API_KEY=sk-xxx
|
||
GAI_API_BASE=https://api.openai.com/v1
|
||
GAI_MODEL=gpt-4o
|
||
```
|
||
|
||
</details>
|
||
|
||
<details>
|
||
<summary><strong>Ollama (local)</strong></summary>
|
||
|
||
```bash
|
||
GAI_API_KEY=ollama
|
||
GAI_API_BASE=http://localhost:11434/v1
|
||
GAI_MODEL=llama3
|
||
```
|
||
|
||
</details>
|
||
|
||
<details>
|
||
<summary><strong>OpenRouter</strong></summary>
|
||
|
||
```bash
|
||
GAI_API_KEY=sk-or-xxx
|
||
GAI_API_BASE=https://openrouter.ai/api/v1
|
||
GAI_MODEL=anthropic/claude-sonnet-4
|
||
```
|
||
|
||
</details>
|
||
|
||
## How It Works
|
||
|
||
```
|
||
┌─────────────────────────────────────────────┐
|
||
│ gai │
|
||
├─────────────────────────────────────────────┤
|
||
│ 1. Collect project context │
|
||
│ ├─ README.md / package.json │
|
||
│ └─ Directory structure │
|
||
│ │
|
||
│ 2. Collect code changes │
|
||
│ ├─ git diff --staged for commits │
|
||
│ └─ branch diff for pull requests │
|
||
│ │
|
||
│ 3. Collect commit history │
|
||
│ ├─ git log --oneline -10 for commits │
|
||
│ └─ branch commits for pull requests │
|
||
│ │
|
||
│ 4. Build prompt → Call AI API │
|
||
│ │
|
||
│ 5. Review → Confirm → Commit or Create PR │
|
||
└─────────────────────────────────────────────┘
|
||
```
|
||
|
||
## Build
|
||
|
||
Compile to a standalone binary:
|
||
|
||
```bash
|
||
bun run build
|
||
# Output: ./gai
|
||
```
|
||
|
||
## Test
|
||
|
||
```bash
|
||
bun test
|
||
```
|
||
|
||
## License
|
||
|
||
[MIT](./LICENSE)
|