|
1 | 1 | # lazycommit
|
2 | 2 |
|
3 |
| -AI-powered Git commit message generator that analyzes your staged changes and generates conventional commit messages. |
| 3 | +AI-powered Git commit message generator that analyzes your staged changes and outputs conventional commit messages. |
4 | 4 |
|
5 | 5 | ## Features
|
6 | 6 |
|
7 |
| -- Generates commit messages using AI (supports OpenAI, OpenRouter, and GitHub Copilot) |
8 |
| -- Interactive prompts for accepting, editing, or canceling commit messages |
9 |
| -- Easy to extend with other AI providers |
10 |
| -- Built with Go for performance and portability |
| 7 | +- Generates 10 commit message suggestions from your staged diff |
| 8 | +- Providers: GitHub Copilot (default), OpenAI, OpenRouter |
| 9 | +- Interactive config to pick provider/model and set keys |
| 10 | +- Simple output suitable for piping into TUI menus (one message per line) |
11 | 11 |
|
12 | 12 | ## Installation
|
13 | 13 |
|
14 | 14 | ```bash
|
15 | 15 | go install github.com/m7medvision/lazycommit@latest
|
16 | 16 | ```
|
17 | 17 |
|
18 |
| -Or clone the repository and build from source: |
| 18 | +Or build from source: |
19 | 19 |
|
20 | 20 | ```bash
|
21 | 21 | git clone https://github.com/m7medvision/lazycommit.git
|
22 | 22 | cd lazycommit
|
23 | 23 | go build -o lazycommit main.go
|
24 | 24 | ```
|
25 | 25 |
|
26 |
| -## Usage |
| 26 | +## CLI |
27 | 27 |
|
28 |
| -Stage your changes first: |
| 28 | +- Root command: `lazycommit` |
| 29 | +- Subcommands: |
| 30 | + - `lazycommit commit` — prints 10 suggested commit messages to stdout, one per line, based on `git diff --cached`. |
| 31 | + - `lazycommit config get` — prints the active provider and model. |
| 32 | + - `lazycommit config set` — interactive setup for provider, API key, and model. |
29 | 33 |
|
30 |
| -```bash |
31 |
| -git add . |
32 |
| -``` |
| 34 | +Exit behaviors: |
| 35 | +- If no staged changes: prints "No staged changes to commit." and exits 0. |
| 36 | +- On config/LLM errors: prints to stderr and exits non‑zero. |
33 | 37 |
|
34 |
| -Then generate a commit message: |
| 38 | +### Examples |
| 39 | + |
| 40 | +Generate suggestions after staging changes: |
35 | 41 |
|
36 | 42 | ```bash
|
| 43 | +git add . |
37 | 44 | lazycommit commit
|
38 | 45 | ```
|
39 | 46 |
|
40 |
| -You can also run the interactive configuration to set your preferred provider and model: |
| 47 | +Pipe the first suggestion to commit (bash example): |
41 | 48 |
|
42 | 49 | ```bash
|
43 |
| -lazycommit config set |
| 50 | +MSG=$(lazycommit commit | sed -n '1p') |
| 51 | +[ -n "$MSG" ] && git commit -m "$MSG" |
44 | 52 | ```
|
45 | 53 |
|
46 |
| -For automatic commit without prompting: |
| 54 | +Pick interactively with `fzf`: |
47 | 55 |
|
48 | 56 | ```bash
|
49 |
| -lazycommit commit -a |
| 57 | +git add . |
| 58 | +lazycommit commit | fzf --prompt='Pick commit> ' | xargs -r -I {} git commit -m "{}" |
50 | 59 | ```
|
51 | 60 |
|
52 | 61 | ## Configuration
|
53 | 62 |
|
54 |
| -- Config directory (`~/.config/.lazycommit.yaml`) |
| 63 | +- Config directory (`~/.config/.lazycommit.yaml` |
55 | 64 |
|
56 | 65 | ```yaml
|
57 |
| -active_provider: openai |
| 66 | +active_provider: copilot # default if a GitHub token is found |
58 | 67 | providers:
|
| 68 | + copilot: |
| 69 | + api_key: "$GITHUB_TOKEN" # Uses GitHub token; token is exchanged internally |
| 70 | + model: "gpt-4o" # or "openai/gpt-4o"; both accepted |
59 | 71 | openai:
|
60 |
| - api_key: "your-openai-api-key" |
| 72 | + api_key: "$OPENAI_API_KEY" |
61 | 73 | model: "gpt-4o"
|
62 | 74 | openrouter:
|
63 |
| - api_key: "$env-your-openrouter-api-key" |
64 |
| - model: "anthropic/claude-3-opus" |
65 |
| - copilot: |
66 |
| - # No API key needed, it uses the GitHub CLI token |
67 |
| - model: "gpt-4o" |
| 75 | + api_key: "$OPENROUTER_API_KEY" # or a literal key |
| 76 | + model: "openai/gpt-4o" # OpenRouter model IDs, e.g. anthropic/claude-3.5-sonnet |
68 | 77 | ```
|
69 | 78 |
|
70 |
| -## Development |
| 79 | +Notes: |
| 80 | +- Copilot: requires a GitHub token with models scope. The tool can also discover IDE Copilot tokens, but models scope is recommended. |
| 81 | +- Environment variable references are supported by prefixing with `$` (e.g., `$OPENAI_API_KEY`). |
71 | 82 |
|
72 |
| -### Project Structure |
| 83 | +### Configure via CLI |
73 | 84 |
|
74 |
| -``` |
75 |
| -lazycommit/ |
76 |
| -├── cmd/ |
77 |
| -│ └── commit.go |
78 |
| -│ └── root.go |
79 |
| -├── internal/ |
80 |
| -│ ├── git/ |
81 |
| -│ │ └── git.go |
82 |
| -│ ├── provider/ |
83 |
| -│ │ ├── provider.go |
84 |
| -│ │ ├── copilot.go |
85 |
| -│ │ └── models/ |
86 |
| -│ │ └── models.go |
87 |
| -│ └── config/ |
88 |
| -│ └── config.go |
89 |
| -├── main.go |
90 |
| -└── go.mod |
| 85 | +```bash |
| 86 | +lazycommit config set # interactive provider/model/key picker |
| 87 | +lazycommit config get # show current provider/model |
91 | 88 | ```
|
92 | 89 |
|
93 |
| -### Building |
| 90 | +## Integration with TUI Git clients |
94 | 91 |
|
95 |
| -```bash |
96 |
| -go build -o lazycommit main.go |
| 92 | +Because `lazycommit commit` prints plain lines, it plugs nicely into menu UIs. |
| 93 | + |
| 94 | +### Lazygit custom command |
| 95 | + |
| 96 | +Add this to `~/.config/lazygit/config.yml`: |
| 97 | + |
| 98 | +```yaml |
| 99 | +customCommands: |
| 100 | + - key: "<c-a>" # ctrl + a |
| 101 | + description: "pick AI commit" |
| 102 | + command: 'git commit -m "{{.Form.Msg}}"' |
| 103 | + context: "files" |
| 104 | + prompts: |
| 105 | + - type: "menuFromCommand" |
| 106 | + title: "ai Commits" |
| 107 | + key: "Msg" |
| 108 | + command: "lazycommit commit" |
| 109 | + filter: '^(?P<raw>.+)$' |
| 110 | + valueFormat: "{{ .raw }}" |
| 111 | + labelFormat: "{{ .raw | green }}" |
97 | 112 | ```
|
98 | 113 |
|
99 |
| -### Dependencies |
| 114 | +Tips: |
| 115 | +- For `lazycommit commit`, you can omit `filter` and just use `valueFormat: "{{ .raw }}"` and `labelFormat: "{{ .raw | green }}"`. |
| 116 | +- If you pipe a numbered list tool (e.g., `bunx bunnai`), keep the regex groups `number` and `message` as shown. |
| 117 | + |
| 118 | +## Providers and models |
| 119 | + |
| 120 | +- Copilot (default when a GitHub token is available): uses `gpt-4o` unless overridden. Accepts `openai/gpt-4o` and normalizes it to `gpt-4o`. |
| 121 | +- OpenAI: choose from models defined in the interactive picker (e.g., gpt‑4o, gpt‑4.1, o3, o1, etc.). |
| 122 | +- OpenRouter: pick from OpenRouter-prefixed IDs (e.g., `openai/gpt-4o`, `anthropic/claude-3.5-sonnet`). Extra headers are set automatically. |
| 123 | + |
| 124 | +## How it works |
| 125 | + |
| 126 | +- Reads `git diff --cached`. |
| 127 | +- Sends a single prompt to the selected provider to generate 10 lines. |
| 128 | +- Prints the lines exactly, suitable for piping/selecting. |
| 129 | + |
| 130 | +## Troubleshooting |
100 | 131 |
|
101 |
| -- [Cobra](https://github.com/spf13/cobra) - CLI framework |
102 |
| -- [Viper](https://github.com/spf13/viper) - Configuration management |
103 |
| -- [go-git](https://github.com/go-git/go-git) - Git implementation in Go |
104 |
| -- [Survey](https://github.com/AlecAivazis/survey) - Interactive prompts |
| 132 | +- "No staged changes to commit." — run `git add` first. |
| 133 | +- "API key not set" — set the appropriate key in `.lazycommit.yaml` or env var and rerun. |
| 134 | +- Copilot errors about token exchange — ensure your GitHub token has models scope or is valid; try setting `GITHUB_TOKEN`. |
105 | 135 |
|
106 | 136 | ## License
|
107 | 137 |
|
|
0 commit comments