git-cai-cli 0.11.2__tar.gz → 0.12.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/.github/ci/cai_config.ci.yml +7 -0
  2. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/CLAUDE.md +19 -6
  3. {git_cai_cli-0.11.2/src/git_cai_cli.egg-info → git_cai_cli-0.12.1}/PKG-INFO +57 -20
  4. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/README.md +56 -19
  5. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/cai_config.yml +8 -3
  6. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/docs/git-cai.txt +105 -2
  7. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/docs/man/git-cai.1 +193 -4
  8. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/pyproject.toml +0 -3
  9. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/src/git_cai_cli/_version.py +3 -3
  10. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/src/git_cai_cli/cli/cli.py +24 -1
  11. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/src/git_cai_cli/cli/helptext.py +3 -0
  12. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/src/git_cai_cli/cli/modes.py +8 -0
  13. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/src/git_cai_cli/core/config.py +66 -38
  14. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/src/git_cai_cli/core/gitutils.py +118 -16
  15. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/src/git_cai_cli/core/llm.py +59 -36
  16. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/src/git_cai_cli/core/options.py +67 -32
  17. git_cai_cli-0.12.1/src/git_cai_cli/core/prompts_fallback.py +111 -0
  18. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/src/git_cai_cli/core/validate.py +6 -0
  19. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/src/git_cai_cli/main.py +47 -43
  20. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1/src/git_cai_cli.egg-info}/PKG-INFO +57 -20
  21. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/src/git_cai_cli.egg-info/SOURCES.txt +0 -3
  22. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/tests/integration/test_cli_integration.py +34 -0
  23. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/tests/integration/test_modes_integration.py +44 -0
  24. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/tests/unit/test_cli.py +166 -0
  25. git_cai_cli-0.12.1/tests/unit/test_config.py +496 -0
  26. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/tests/unit/test_gitutils.py +205 -0
  27. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/tests/unit/test_llm.py +160 -1
  28. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/tests/unit/test_main.py +22 -0
  29. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/tests/unit/test_options.py +87 -0
  30. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/tests/unit/test_prompt_loading.py +168 -56
  31. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/tests/unit/test_validate.py +131 -0
  32. git_cai_cli-0.11.2/src/git_cai_cli/core/prompts_fallback.py +0 -36
  33. git_cai_cli-0.11.2/src/git_cai_cli/defaults/__init__.py +0 -0
  34. git_cai_cli-0.11.2/src/git_cai_cli/defaults/commit_prompt.md +0 -12
  35. git_cai_cli-0.11.2/src/git_cai_cli/defaults/squash_prompt.md +0 -10
  36. git_cai_cli-0.11.2/tests/unit/test_config.py +0 -258
  37. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/.caiignore +0 -0
  38. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/.gitattributes +0 -0
  39. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/.github/cd/.SRCINFO +0 -0
  40. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/.github/cd/PKGBUILD +0 -0
  41. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/.github/ci/_version.py +0 -0
  42. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/.github/ci/tokens.ci.yml +0 -0
  43. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/.github/workflows/python-tests.yml +0 -0
  44. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/.github/workflows/release.yml +0 -0
  45. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/.github/workflows/release_aur.yml +0 -0
  46. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/.gitignore +0 -0
  47. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/.linters/.bandit.yml +0 -0
  48. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/.linters/.checkov.yml +0 -0
  49. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/.linters/.flake8 +0 -0
  50. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/.linters/.ls-lint.yml +0 -0
  51. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/.linters/.markdown-link-check.json +0 -0
  52. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/.linters/.markdownlint.json +0 -0
  53. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/.linters/.proselintrc +0 -0
  54. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/.linters/.pylintrc +0 -0
  55. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/.linters/.yamllint.yml +0 -0
  56. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/.linters/check_git_branch_name.sh +0 -0
  57. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/.linters/lychee.toml +0 -0
  58. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/.linters/pyrightconfig.json +0 -0
  59. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/.markdownlintignore +0 -0
  60. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/.mega-linter.yml +0 -0
  61. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/.semgrepignore +0 -0
  62. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/.trivyignore +0 -0
  63. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/LICENSE +0 -0
  64. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/Makefile +0 -0
  65. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/setup.cfg +0 -0
  66. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/src/git_cai_cli/__init__.py +0 -0
  67. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/src/git_cai_cli/cli/__init__.py +0 -0
  68. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/src/git_cai_cli/core/__init__.py +0 -0
  69. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/src/git_cai_cli/core/completion.py +0 -0
  70. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/src/git_cai_cli/core/editors.py +0 -0
  71. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/src/git_cai_cli/core/languages.py +0 -0
  72. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/src/git_cai_cli/core/spinner.py +0 -0
  73. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/src/git_cai_cli/core/squash.py +0 -0
  74. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/src/git_cai_cli.egg-info/dependency_links.txt +0 -0
  75. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/src/git_cai_cli.egg-info/entry_points.txt +0 -0
  76. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/src/git_cai_cli.egg-info/requires.txt +0 -0
  77. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/src/git_cai_cli.egg-info/top_level.txt +0 -0
  78. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/tests/conftest.py +0 -0
  79. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/tests/integration/test_config_integration.py +0 -0
  80. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/tests/integration/test_gitutils_integration.py +0 -0
  81. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/tests/integration/test_options_integration.py +0 -0
  82. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/tests/integration/test_squash_integration.py +0 -0
  83. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/tests/unit/test_amend.py +0 -0
  84. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/tests/unit/test_branch_context.py +0 -0
  85. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/tests/unit/test_completion.py +0 -0
  86. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/tests/unit/test_conventional.py +0 -0
  87. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/tests/unit/test_helptext.py +0 -0
  88. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/tests/unit/test_modes.py +0 -0
  89. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/tests/unit/test_set_config.py +0 -0
  90. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/tests/unit/test_spinner.py +0 -0
  91. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/tests/unit/test_squash.py +0 -0
  92. {git_cai_cli-0.11.2 → git_cai_cli-0.12.1}/uv.lock +0 -0
@@ -3,9 +3,12 @@ language: en
3
3
  style: professional
4
4
  emoji: false
5
5
  load_tokens_from: /home/runner/work/.config/cai/tokens.yml
6
+ timeout: 30
7
+ full_files: false
6
8
  anthropic:
7
9
  model: claude-haiku-4-5
8
10
  temperature: 0
11
+ max_tokens: 32768
9
12
  deepseek:
10
13
  model: deepseek-chat
11
14
  temperature: 0
@@ -18,6 +21,10 @@ groq:
18
21
  mistral:
19
22
  model: codestral-2508
20
23
  temperature: 0
24
+ ollama:
25
+ model: llama3.1
26
+ temperature: 0
27
+ timeout: 300
21
28
  openai:
22
29
  model: gpt-5.1
23
30
  temperature: 0
@@ -9,8 +9,9 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
9
9
  ## Common Commands
10
10
 
11
11
  ```bash
12
+ uv sync --dev # Install dependencies (including dev deps)
12
13
  make test # Run all tests (uv run pytest)
13
- make lint # Branch name check + MegaLinter
14
+ make lint # Branch name check + MegaLinter (requires npx + Docker)
14
15
  make lint-fix # Auto-fix lint issues
15
16
  make clean # Clean uv cache and .venv
16
17
 
@@ -34,16 +35,19 @@ Entry point: `src/git_cai_cli/cli/cli.py` (Typer app) → `main.py` (dispatcher)
34
35
 
35
36
  ### Core Modules (core/)
36
37
 
37
- - **config.py** — Config loading with precedence: repo `cai_config.yml` > home `~/.config/cai/cai_config.yml` > bundled defaults
38
- - **llm.py** — `CommitMessageGenerator` class with `_dispatch_generate()` routing to provider-specific methods (`generate_openai()`, `generate_anthropic()`, etc.)
38
+ - **config.py** — Config loading. Repo config is **authoritative** (not merged with home config): repo `cai_config.yml` > home `~/.config/cai/cai_config.yml` > bundled `DEFAULT_CONFIG`
39
+ - **llm.py** — `CommitMessageGenerator` class with `_dispatch_generate()` routing to
40
+ provider-specific methods. OpenAI/DeepSeek use the OpenAI SDK;
41
+ Anthropic/Gemini/Groq/xAI/Mistral use direct HTTP via `requests`; Ollama uses its
42
+ local HTTP API and auto-starts the server if needed
39
43
  - **gitutils.py** — Git operations (find root, diff with `.caiignore` support, commit)
40
- - **validate.py** — Config and LLM call validation
44
+ - **validate.py** — Config key/structure validation, language/style validation, and LLM call wrapper that converts auth errors to user-facing messages
41
45
  - **squash.py** — Squash commit workflow (stage → generate summary → editor → reset + commit)
42
46
  - **options.py** — `CliManager` orchestrating CLI operations
43
47
 
44
48
  ### Prompt Fallback Chain
45
49
 
46
- File (repo-level) → File (user home) → Bundled package (`defaults/*.md`) → Hardcoded string (`prompts_fallback.py`)
50
+ File (repo-level) → File (user home `~/.config/cai/`) → Hardcoded string (`prompts_fallback.py`)
47
51
 
48
52
  ### Tokens
49
53
 
@@ -53,10 +57,19 @@ API tokens loaded from `~/.config/cai/tokens.yml`. Ollama is in `TOKENLESS_PROVI
53
57
 
54
58
  - Unit tests in `tests/unit/`, integration tests in `tests/integration/`
55
59
  - Uses `requests-mock` for HTTP mocking
56
- - CI tests against Python 3.10–3.14
60
+ - `tests/conftest.py` inserts `src/` into `sys.path` so local source wins over any installed package
61
+ - CI tests against Python 3.10–3.14; CI copies `.github/ci/cai_config.ci.yml` and `tokens.ci.yml` to `~/.config/cai/`
57
62
 
58
63
  ## Build & Versioning
59
64
 
60
65
  - Package manager: **uv**
61
66
  - Version: auto-generated from git tags via `setuptools-scm` → `src/git_cai_cli/_version.py`
62
67
  - Do not edit `_version.py` manually
68
+
69
+ ## Branch Naming
70
+
71
+ Enforced by CI and `make lint` via `.linters/check_git_branch_name.sh`:
72
+
73
+ ```text
74
+ master | (feature|fix|hotfix|chore|refactor|test|docs)/<lowercase-slug>
75
+ ```
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: git-cai-cli
3
- Version: 0.11.2
3
+ Version: 0.12.1
4
4
  Summary: Use LLM to create git commit messages
5
5
  Author-email: Thorsten Foltz <thorsten.foltz@live.com>
6
6
  License-Expression: MIT
@@ -75,19 +75,18 @@ Currently supported providers:
75
75
  - Generates meaningful, context-aware commit messages using an LLM
76
76
  - Seamless integration with Git
77
77
  - Supports multiple LLM providers and models
78
- - Override provider and model per invocation (`-P`, `-m`)
79
78
  - Global configuration with per-repository overrides
80
79
  - Repository-specific language, style, and model selection
81
- - Amend the last commit message with a regenerated one (`-A`)
82
- - Conventional Commits format support (`-C`)
83
- - Change configuration from the command line (`-S`, `-H`)
80
+ - Amend the last commit message with a regenerated one
81
+ - Conventional Commits format support
82
+ - Change configuration from the command line
84
83
  - Optional commit squashing with automatic summary generation (all, last N, or up to a specific commit)
85
- - List providers, models, active config, and file paths (`-l`)
84
+ - List providers, models, active config, and file paths
86
85
  - Token usage logging for API calls
87
- - Branch name as LLM context via `--branch` / `-b`
88
- - Extra context for the LLM via `--context` / `-x` (e.g. ticket numbers, reasons)
89
- - Generation time measurement (`-t`)
90
- - Shell completion for bash, zsh, and fish (`-i`)
86
+ - Branch name as LLM context
87
+ - Extra context for the LLM
88
+ - Generation time measurement
89
+ - Shell completion for bash, zsh, and fish
91
90
 
92
91
  ---
93
92
 
@@ -124,7 +123,7 @@ Once installed, cai works like a standard Git command:
124
123
  git cai
125
124
  ```
126
125
 
127
- cai uses the output of `git diff` to generate a commit message.
126
+ cai uses the output of `git diff` to generate a commit message or, if optional, with the complete file content.
128
127
  The generated message is opened in your configured Git editor, allowing you to review or edit it before committing.
129
128
 
130
129
  In short: it behaves like `git commit`, but the commit message is pre-filled.
@@ -150,18 +149,21 @@ On first execution, cai automatically creates the base configuration in your hom
150
149
  - API tokens:
151
150
  ~/.config/cai/tokens.yml
152
151
 
153
- It also creates two Markdown prompt files:
152
+ It also creates three Markdown prompt files:
154
153
 
155
154
  - Default commit prompt:
156
155
  ~/.config/cai/commit_prompt.md
157
156
  - Default squash prompt:
158
157
  ~/.config/cai/squash_prompt.md
158
+ - Default full-files prompt (used with `-F` / `--full-files`):
159
+ ~/.config/cai/full_files_prompt.md
159
160
 
160
161
  Don't be scared the first run will show an error. It only misses a token.
161
162
  Add your provider API keys to `tokens.yml`. Once configured, cai will reuse them automatically.
163
+ Optional for each repository a file containing tokens can be set.
162
164
  Set your preferred LLM in `cai_config.yml` (Groq by default).
163
165
 
164
- If you want to use Ollama, set `default: ollama` and configure the `ollama:` block (model/temperature). Ollama is automatically started when used.
166
+ If you want to use Ollama, install it, set `default: ollama` and configure the `ollama:` block (model/temperature). Ollama is automatically started when used.
165
167
 
166
168
  ### Custom prompts (Markdown)
167
169
 
@@ -178,8 +180,12 @@ This creates:
178
180
 
179
181
  - `commit_prompt.md`
180
182
  - `squash_prompt.md`
183
+ - `full_files_prompt.md`
184
+ so the LLM knows the full working-tree contents of each changed file are
185
+ attached and can reason about *why* each edit was made, not just what
186
+ the diff shows.
181
187
 
182
- Then set `prompt_file` and/or `squash_prompt_file` in your `cai_config.yml` (also repo) to point to those files.
188
+ Then set `prompt_file`, `squash_prompt_file`, and/or `full_files_prompt_file` in your `cai_config.yml` (also repo) to point to those files.
183
189
 
184
190
  ### Repository-specific configuration
185
191
 
@@ -220,10 +226,13 @@ git cai -g
220
226
  - `load_tokens_from` – path to the file where API tokens are stored
221
227
  - `prompt_file` - path to the file where the prompt for the commit is stored
222
228
  - `squash_prompt_file` - path to the file where the prompt for the squash is stored
223
- - `branch_context` include current branch name as LLM context (default: `false`)
224
- - `conventional` – use Conventional Commits format (default: `false`)
225
- - `token_logging` – log token usage after each LLM call (default: `true` for new installs)
226
- - `measure_time` – log generation time (default: `false`)
229
+ - `full_files_prompt_file` - path to the prompt used when `-F` / `--full-files` attaches full file contents
230
+ - `full_files` – attach always the full working-tree contents of affected files alongside the diff
231
+ - `timeout` – HTTP timeout for LLM calls in seconds
232
+ - `branch_context` – include current branch name as LLM context
233
+ - `conventional` – use Conventional Commits format
234
+ - `token_logging` – log token usage after each LLM call
235
+ - `measure_time` – log generation time
227
236
 
228
237
  ---
229
238
 
@@ -237,6 +246,8 @@ In addition to `git cai`, the following options are available:
237
246
  - `-C`, `--conventional` – use Conventional Commits format (`type(scope): description`)
238
247
  - `-c`, `--crazy` – Trust the LLM and commit without checking
239
248
  - `-d`, `--debug` – enable debug logging
249
+ - `-F`, `--full-files` – attach the full contents of affected files alongside the diff (uses `full_files_prompt.md`)
250
+ - `-f`, `--files` `PATH` – limit the diff (and full-file content, if enabled) to PATH; repeat for multiple files
240
251
  - `-g`, `--generate-config` – generate the default `cai_config.yml` in the current directory
241
252
  - `-H`, `--set-home` – set a config value in home config (`key=value`), always targets `~/.config/cai/`
242
253
  - `-h`, `--help` – show help and available commands
@@ -246,13 +257,15 @@ In addition to `git cai`, the following options are available:
246
257
  - `-p`, `--generate-prompts` – generate default `commit_prompt.md` and `squash_prompt.md` in the current directory (for customization)
247
258
  - `-P`, `--provider` – override the LLM provider for this invocation
248
259
  - `-S`, `--set` – set a config value (`key=value`) in repo config (requires existing repo config)
249
- - `-H`, `--set-home` – set a config value in home config (`key=value`), always targets `~/.config/cai/`
250
260
  - `-s`, `--squash` `[N|HASH]` – squash commits on the current branch and summarize them. Without argument: squash all since branch checkout. With a number: squash the last N commits. With a commit hash: squash up to and including that commit
261
+ - `-T`, `--timeout` `SECONDS` – HTTP timeout for this invocation (overrides config)
251
262
  - `-t`, `--time` – measure and log commit message generation time
252
263
  - `-x`, `--context` – provide extra context for the LLM (e.g. ticket number, reason for change)
253
264
  - `-u`, `--update` – check for updates
254
265
  - `-v`, `--version` – show the installed version
255
266
 
267
+ ## Examples
268
+
256
269
  ### Amend
257
270
 
258
271
  To regenerate the last commit message and amend it:
@@ -280,6 +293,30 @@ To enable it permanently:
280
293
  git cai -S conventional=true
281
294
  ```
282
295
 
296
+ ### Attaching full file contents and restricting to specific files
297
+
298
+ Sometimes the diff alone is too little context for the LLM to explain *why* a
299
+ change was made. `-F` / `--full-files` attaches the complete working-tree
300
+ contents of every staged file alongside the diff and switches to a dedicated
301
+ prompt (`full_files_prompt.md`) that instructs the LLM to use that full
302
+ context to infer intent rather than just describe the mechanical edit.
303
+
304
+ ```sh
305
+ git cai -F # attach full contents of all staged files
306
+ git cai -F -f src/foo.py -f src/bar.py # only these files
307
+ git cai -f docs/README.md # restrict diff to one file (no full files)
308
+ ```
309
+
310
+ Both flags log the affected files at INFO level as paths relative to the
311
+ repository root, so you can see exactly what ends up in the prompt — binaries,
312
+ deleted files, and paths matched by `.caiignore` are filtered out and skipped.
313
+
314
+ Persist the default:
315
+
316
+ ```sh
317
+ git cai -S full_files=true
318
+ ```
319
+
283
320
  ### Changing configuration from the CLI
284
321
 
285
322
  Instead of editing YAML files manually, use `--set` or `--set-home` to update config values.
@@ -288,7 +325,7 @@ Instead of editing YAML files manually, use `--set` or `--set-home` to update co
288
325
 
289
326
  ```sh
290
327
  git cai -S default=anthropic # change the default provider
291
- git cai -S emoji=false # disable emojis
328
+ git cai -S emoji=false # disable emojis
292
329
  git cai -S groq.model=llama-3.3-70b # nested key (dot notation)
293
330
  git cai -S openai.temperature=0.7 # set temperature as float
294
331
  ```
@@ -46,19 +46,18 @@ Currently supported providers:
46
46
  - Generates meaningful, context-aware commit messages using an LLM
47
47
  - Seamless integration with Git
48
48
  - Supports multiple LLM providers and models
49
- - Override provider and model per invocation (`-P`, `-m`)
50
49
  - Global configuration with per-repository overrides
51
50
  - Repository-specific language, style, and model selection
52
- - Amend the last commit message with a regenerated one (`-A`)
53
- - Conventional Commits format support (`-C`)
54
- - Change configuration from the command line (`-S`, `-H`)
51
+ - Amend the last commit message with a regenerated one
52
+ - Conventional Commits format support
53
+ - Change configuration from the command line
55
54
  - Optional commit squashing with automatic summary generation (all, last N, or up to a specific commit)
56
- - List providers, models, active config, and file paths (`-l`)
55
+ - List providers, models, active config, and file paths
57
56
  - Token usage logging for API calls
58
- - Branch name as LLM context via `--branch` / `-b`
59
- - Extra context for the LLM via `--context` / `-x` (e.g. ticket numbers, reasons)
60
- - Generation time measurement (`-t`)
61
- - Shell completion for bash, zsh, and fish (`-i`)
57
+ - Branch name as LLM context
58
+ - Extra context for the LLM
59
+ - Generation time measurement
60
+ - Shell completion for bash, zsh, and fish
62
61
 
63
62
  ---
64
63
 
@@ -95,7 +94,7 @@ Once installed, cai works like a standard Git command:
95
94
  git cai
96
95
  ```
97
96
 
98
- cai uses the output of `git diff` to generate a commit message.
97
+ cai uses the output of `git diff` to generate a commit message or, if optional, with the complete file content.
99
98
  The generated message is opened in your configured Git editor, allowing you to review or edit it before committing.
100
99
 
101
100
  In short: it behaves like `git commit`, but the commit message is pre-filled.
@@ -121,18 +120,21 @@ On first execution, cai automatically creates the base configuration in your hom
121
120
  - API tokens:
122
121
  ~/.config/cai/tokens.yml
123
122
 
124
- It also creates two Markdown prompt files:
123
+ It also creates three Markdown prompt files:
125
124
 
126
125
  - Default commit prompt:
127
126
  ~/.config/cai/commit_prompt.md
128
127
  - Default squash prompt:
129
128
  ~/.config/cai/squash_prompt.md
129
+ - Default full-files prompt (used with `-F` / `--full-files`):
130
+ ~/.config/cai/full_files_prompt.md
130
131
 
131
132
  Don't be scared the first run will show an error. It only misses a token.
132
133
  Add your provider API keys to `tokens.yml`. Once configured, cai will reuse them automatically.
134
+ Optional for each repository a file containing tokens can be set.
133
135
  Set your preferred LLM in `cai_config.yml` (Groq by default).
134
136
 
135
- If you want to use Ollama, set `default: ollama` and configure the `ollama:` block (model/temperature). Ollama is automatically started when used.
137
+ If you want to use Ollama, install it, set `default: ollama` and configure the `ollama:` block (model/temperature). Ollama is automatically started when used.
136
138
 
137
139
  ### Custom prompts (Markdown)
138
140
 
@@ -149,8 +151,12 @@ This creates:
149
151
 
150
152
  - `commit_prompt.md`
151
153
  - `squash_prompt.md`
154
+ - `full_files_prompt.md`
155
+ so the LLM knows the full working-tree contents of each changed file are
156
+ attached and can reason about *why* each edit was made, not just what
157
+ the diff shows.
152
158
 
153
- Then set `prompt_file` and/or `squash_prompt_file` in your `cai_config.yml` (also repo) to point to those files.
159
+ Then set `prompt_file`, `squash_prompt_file`, and/or `full_files_prompt_file` in your `cai_config.yml` (also repo) to point to those files.
154
160
 
155
161
  ### Repository-specific configuration
156
162
 
@@ -191,10 +197,13 @@ git cai -g
191
197
  - `load_tokens_from` – path to the file where API tokens are stored
192
198
  - `prompt_file` - path to the file where the prompt for the commit is stored
193
199
  - `squash_prompt_file` - path to the file where the prompt for the squash is stored
194
- - `branch_context` include current branch name as LLM context (default: `false`)
195
- - `conventional` – use Conventional Commits format (default: `false`)
196
- - `token_logging` – log token usage after each LLM call (default: `true` for new installs)
197
- - `measure_time` – log generation time (default: `false`)
200
+ - `full_files_prompt_file` - path to the prompt used when `-F` / `--full-files` attaches full file contents
201
+ - `full_files` – attach always the full working-tree contents of affected files alongside the diff
202
+ - `timeout` – HTTP timeout for LLM calls in seconds
203
+ - `branch_context` – include current branch name as LLM context
204
+ - `conventional` – use Conventional Commits format
205
+ - `token_logging` – log token usage after each LLM call
206
+ - `measure_time` – log generation time
198
207
 
199
208
  ---
200
209
 
@@ -208,6 +217,8 @@ In addition to `git cai`, the following options are available:
208
217
  - `-C`, `--conventional` – use Conventional Commits format (`type(scope): description`)
209
218
  - `-c`, `--crazy` – Trust the LLM and commit without checking
210
219
  - `-d`, `--debug` – enable debug logging
220
+ - `-F`, `--full-files` – attach the full contents of affected files alongside the diff (uses `full_files_prompt.md`)
221
+ - `-f`, `--files` `PATH` – limit the diff (and full-file content, if enabled) to PATH; repeat for multiple files
211
222
  - `-g`, `--generate-config` – generate the default `cai_config.yml` in the current directory
212
223
  - `-H`, `--set-home` – set a config value in home config (`key=value`), always targets `~/.config/cai/`
213
224
  - `-h`, `--help` – show help and available commands
@@ -217,13 +228,15 @@ In addition to `git cai`, the following options are available:
217
228
  - `-p`, `--generate-prompts` – generate default `commit_prompt.md` and `squash_prompt.md` in the current directory (for customization)
218
229
  - `-P`, `--provider` – override the LLM provider for this invocation
219
230
  - `-S`, `--set` – set a config value (`key=value`) in repo config (requires existing repo config)
220
- - `-H`, `--set-home` – set a config value in home config (`key=value`), always targets `~/.config/cai/`
221
231
  - `-s`, `--squash` `[N|HASH]` – squash commits on the current branch and summarize them. Without argument: squash all since branch checkout. With a number: squash the last N commits. With a commit hash: squash up to and including that commit
232
+ - `-T`, `--timeout` `SECONDS` – HTTP timeout for this invocation (overrides config)
222
233
  - `-t`, `--time` – measure and log commit message generation time
223
234
  - `-x`, `--context` – provide extra context for the LLM (e.g. ticket number, reason for change)
224
235
  - `-u`, `--update` – check for updates
225
236
  - `-v`, `--version` – show the installed version
226
237
 
238
+ ## Examples
239
+
227
240
  ### Amend
228
241
 
229
242
  To regenerate the last commit message and amend it:
@@ -251,6 +264,30 @@ To enable it permanently:
251
264
  git cai -S conventional=true
252
265
  ```
253
266
 
267
+ ### Attaching full file contents and restricting to specific files
268
+
269
+ Sometimes the diff alone is too little context for the LLM to explain *why* a
270
+ change was made. `-F` / `--full-files` attaches the complete working-tree
271
+ contents of every staged file alongside the diff and switches to a dedicated
272
+ prompt (`full_files_prompt.md`) that instructs the LLM to use that full
273
+ context to infer intent rather than just describe the mechanical edit.
274
+
275
+ ```sh
276
+ git cai -F # attach full contents of all staged files
277
+ git cai -F -f src/foo.py -f src/bar.py # only these files
278
+ git cai -f docs/README.md # restrict diff to one file (no full files)
279
+ ```
280
+
281
+ Both flags log the affected files at INFO level as paths relative to the
282
+ repository root, so you can see exactly what ends up in the prompt — binaries,
283
+ deleted files, and paths matched by `.caiignore` are filtered out and skipped.
284
+
285
+ Persist the default:
286
+
287
+ ```sh
288
+ git cai -S full_files=true
289
+ ```
290
+
254
291
  ### Changing configuration from the CLI
255
292
 
256
293
  Instead of editing YAML files manually, use `--set` or `--set-home` to update config values.
@@ -259,7 +296,7 @@ Instead of editing YAML files manually, use `--set` or `--set-home` to update co
259
296
 
260
297
  ```sh
261
298
  git cai -S default=anthropic # change the default provider
262
- git cai -S emoji=false # disable emojis
299
+ git cai -S emoji=false # disable emojis
263
300
  git cai -S groq.model=llama-3.3-70b # nested key (dot notation)
264
301
  git cai -S openai.temperature=0.7 # set temperature as float
265
302
  ```
@@ -1,4 +1,4 @@
1
- default: anthropic
1
+ default: openai
2
2
  language: en
3
3
  style: professional
4
4
  emoji: true
@@ -7,11 +7,15 @@ branch_context: false
7
7
  load_tokens_from: /home/thorsten/.config/cai/tokens.yml
8
8
  prompt_file: ""
9
9
  squash_prompt_file: ""
10
+ full_files_prompt_file: ""
10
11
  token_logging: true
11
12
  measure_time: true
13
+ timeout: 30
14
+ full_files: false
12
15
  anthropic:
13
- model: claude-opus-4-6
16
+ model: claude-haiku-4-5
14
17
  temperature: 0
18
+ max_tokens: 32768
15
19
  deepseek:
16
20
  model: deepseek-chat
17
21
  temperature: 0
@@ -27,8 +31,9 @@ mistral:
27
31
  ollama:
28
32
  model: llama3.1
29
33
  temperature: 0
34
+ timeout: 300
30
35
  openai:
31
- model: gpt-5.2
36
+ model: gpt-5.4
32
37
  temperature: 0
33
38
  xai:
34
39
  model: grok-4-1-fast-reasoning
@@ -11,7 +11,9 @@ SYNOPSIS
11
11
  --------
12
12
  [verse]
13
13
  `git cai` [-A | --amend] [-a | --all] [-C | --conventional]
14
- [-b | --branch] [-c | --crazy] [-d | --debug] [-g | --generate-config]
14
+ [-b | --branch] [-c | --crazy] [-d | --debug]
15
+ [-F | --full-files] [-f PATH | --files PATH]
16
+ [-g | --generate-config]
15
17
  [-H KEY=VALUE | --set-home KEY=VALUE] [-h | --help]
16
18
  [-i | --install-completion]
17
19
  [-l [config|editor|language|model|path|provider|style] |
@@ -19,7 +21,9 @@ SYNOPSIS
19
21
  [-m MODEL | --model MODEL]
20
22
  [-P PROVIDER | --provider PROVIDER] [-p | --generate-prompts]
21
23
  [-S KEY=VALUE | --set KEY=VALUE]
22
- [-s [N|HASH] | --squash [N|HASH]] [-t | --time] [-u | --update] [-v | --version]
24
+ [-s [N|HASH] | --squash [N|HASH]]
25
+ [-T SECONDS | --timeout SECONDS]
26
+ [-t | --time] [-u | --update] [-v | --version]
23
27
  [-x CONTEXT | --context CONTEXT]
24
28
 
25
29
 
@@ -154,6 +158,51 @@ Cannot be combined with `--help` or `--version`.
154
158
  git cai -d
155
159
  ----
156
160
 
161
+ -F, --full-files::
162
+ Send the full working-tree contents of every staged file alongside the diff.
163
+ By default, git-cai sends only the staged diff to the LLM. With `-F`, the
164
+ diff is followed by a block of the form:
165
+ +
166
+ ----
167
+ --- File: path/to/file.py ---
168
+ <full contents>
169
+ ----
170
+ +
171
+ for each staged text file. This produces higher-quality commit messages for
172
+ large or context-dependent changes, at the cost of more input tokens. Binary
173
+ files and files matching `.caiignore` are skipped.
174
+ +
175
+ The flag applies for the current invocation only. To enable it permanently,
176
+ set `full_files: true` in `cai_config.yml` or run:
177
+ +
178
+ ----
179
+ git cai -S full_files=true
180
+ ----
181
+ +
182
+ Can be combined with `-f` to scope the content dump to specific files.
183
+ +
184
+ ----
185
+ git cai -F
186
+ git cai -F -f src/foo.py
187
+ ----
188
+
189
+ -f, --files PATH::
190
+ Restrict the diff (and full-file content, if `-F` is on) to the given path.
191
+ Repeat the flag to pass multiple paths. `.caiignore` patterns still apply on
192
+ top of the whitelist.
193
+ +
194
+ Useful when a working tree contains unrelated staged changes and the commit
195
+ should focus on a subset of them, or when you want the LLM to concentrate
196
+ on a specific file.
197
+ +
198
+ Cannot be used with `--list`, `--update`, or `--squash`.
199
+ +
200
+ ----
201
+ git cai -f src/foo.py
202
+ git cai -f src/foo.py -f tests/test_foo.py
203
+ git cai -F -f src/foo.py
204
+ ----
205
+
157
206
  -g, --generate-config::
158
207
  Write the default `cai_config.yml` into the current directory. This is a
159
208
  convenient way to create a repository-specific configuration that overrides
@@ -294,6 +343,32 @@ git cai -s 3
294
343
  git cai -s a1b2c3d
295
344
  ----
296
345
 
346
+ -T, --timeout SECONDS::
347
+ Override the HTTP timeout for the LLM call in this invocation. The default
348
+ is 30 seconds for remote providers and 300 seconds for Ollama (since local
349
+ generation can be significantly slower). The override applies uniformly to
350
+ whichever provider is selected for this run.
351
+ +
352
+ To change the default permanently, set `timeout: <seconds>` in
353
+ `cai_config.yml` or the home config:
354
+ +
355
+ ----
356
+ git cai -H timeout=60
357
+ git cai -S timeout=45
358
+ ----
359
+ +
360
+ Ollama keeps its own timeout under `ollama.timeout` (default 300). Override
361
+ it separately:
362
+ +
363
+ ----
364
+ git cai -H ollama.timeout=600
365
+ ----
366
+ +
367
+ ----
368
+ git cai -T 60
369
+ git cai -T 120 -P anthropic
370
+ ----
371
+
297
372
  -t, --time::
298
373
  Measure and log the wall-clock time taken to generate the commit message.
299
374
  The duration is printed to stderr after the LLM responds. Useful for
@@ -543,8 +618,15 @@ Available configuration keys:
543
618
  - `squash_prompt_file` -- path to the squash prompt Markdown file
544
619
  - `token_logging` -- log token usage after each LLM call (`true`/`false`)
545
620
  - `measure_time` -- log generation time (`true`/`false`)
621
+ - `timeout` -- HTTP timeout in seconds for remote LLM calls (default `30`)
622
+ - `full_files` -- send full working-tree contents of staged files alongside
623
+ the diff (`true`/`false`, default `false`)
546
624
  - `<provider>.model` -- model name for a specific provider
547
625
  - `<provider>.temperature` -- temperature for a specific provider
626
+ - `anthropic.max_tokens` -- upper bound on Anthropic response tokens
627
+ (default `32768`)
628
+ - `ollama.timeout` -- HTTP timeout in seconds for Ollama generation calls
629
+ (default `300`; overrides the global `timeout` for this provider only)
548
630
 
549
631
  FILES
550
632
  -----
@@ -706,6 +788,27 @@ Measure generation time:
706
788
  git cai -t
707
789
  ----
708
790
 
791
+ Send full file contents in addition to the diff:
792
+
793
+ ----
794
+ git cai -F
795
+ git cai -F -f src/foo.py
796
+ ----
797
+
798
+ Limit generation to specific files:
799
+
800
+ ----
801
+ git cai -f src/foo.py
802
+ git cai -f src/foo.py -f tests/test_foo.py
803
+ ----
804
+
805
+ Override the HTTP timeout for a single run:
806
+
807
+ ----
808
+ git cai -T 60
809
+ git cai -T 120 -P anthropic
810
+ ----
811
+
709
812
  Install shell completion:
710
813
 
711
814
  ----