git-cai-cli 0.14.0__tar.gz → 0.14.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.
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/.linters/.proselintrc +1 -1
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/.linters/.pylintrc +1 -1
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/PKG-INFO +8 -1
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/README.md +7 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/docs/git-cai.txt +53 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/docs/man/git-cai.1 +89 -2
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/src/git_cai_cli/_version.py +3 -3
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/src/git_cai_cli/cli/cli.py +25 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/src/git_cai_cli/core/completion.py +66 -11
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/src/git_cai_cli/core/config.py +48 -1
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/src/git_cai_cli/core/gitutils.py +22 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/src/git_cai_cli/core/llm.py +8 -1
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/src/git_cai_cli/core/options.py +2 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/src/git_cai_cli/core/pr.py +22 -3
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/src/git_cai_cli/core/squash.py +36 -5
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/src/git_cai_cli/core/validate.py +1 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/src/git_cai_cli/main.py +23 -1
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/src/git_cai_cli.egg-info/PKG-INFO +8 -1
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/tests/unit/test_completion.py +60 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/tests/unit/test_config.py +151 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/tests/unit/test_gitutils.py +48 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/tests/unit/test_llm.py +16 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/tests/unit/test_pr.py +35 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/tests/unit/test_squash.py +27 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/.caiignore +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/.gitattributes +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/.github/cd/.SRCINFO +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/.github/cd/PKGBUILD +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/.github/ci/_version.py +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/.github/ci/cai_config.ci.yml +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/.github/ci/tokens.ci.yml +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/.github/workflows/python-tests.yml +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/.github/workflows/release.yml +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/.github/workflows/release_aur.yml +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/.gitignore +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/.linters/.bandit.yml +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/.linters/.checkov.yml +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/.linters/.flake8 +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/.linters/.ls-lint.yml +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/.linters/.markdown-link-check.json +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/.linters/.markdownlint.json +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/.linters/.yamllint.yml +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/.linters/check_git_branch_name.sh +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/.linters/lychee.toml +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/.linters/pyrightconfig.json +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/.markdownlintignore +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/.mega-linter.yml +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/.semgrepignore +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/.trivyignore +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/CLAUDE.md +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/LICENSE +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/Makefile +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/cai_config.yml +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/pyproject.toml +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/setup.cfg +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/src/git_cai_cli/__init__.py +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/src/git_cai_cli/cli/__init__.py +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/src/git_cai_cli/cli/helptext.py +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/src/git_cai_cli/cli/modes.py +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/src/git_cai_cli/core/__init__.py +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/src/git_cai_cli/core/editors.py +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/src/git_cai_cli/core/init.py +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/src/git_cai_cli/core/languages.py +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/src/git_cai_cli/core/prompts_fallback.py +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/src/git_cai_cli/core/spinner.py +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/src/git_cai_cli/core/stats.py +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/src/git_cai_cli.egg-info/SOURCES.txt +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/src/git_cai_cli.egg-info/dependency_links.txt +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/src/git_cai_cli.egg-info/entry_points.txt +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/src/git_cai_cli.egg-info/requires.txt +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/src/git_cai_cli.egg-info/top_level.txt +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/tests/conftest.py +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/tests/integration/test_cli_integration.py +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/tests/integration/test_config_integration.py +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/tests/integration/test_gitutils_integration.py +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/tests/integration/test_modes_integration.py +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/tests/integration/test_options_integration.py +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/tests/integration/test_pr_integration.py +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/tests/integration/test_squash_integration.py +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/tests/unit/test_amend.py +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/tests/unit/test_branch_context.py +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/tests/unit/test_cli.py +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/tests/unit/test_conventional.py +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/tests/unit/test_helptext.py +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/tests/unit/test_init.py +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/tests/unit/test_main.py +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/tests/unit/test_modes.py +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/tests/unit/test_options.py +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/tests/unit/test_print.py +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/tests/unit/test_prompt_loading.py +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/tests/unit/test_set_config.py +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/tests/unit/test_signoff.py +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/tests/unit/test_spinner.py +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/tests/unit/test_stats.py +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/tests/unit/test_validate.py +0 -0
- {git_cai_cli-0.14.0 → git_cai_cli-0.14.1}/uv.lock +0 -0
|
@@ -69,7 +69,7 @@ check-protected-access-in-special-methods=no
|
|
|
69
69
|
max-args=25 # Max arguments per function
|
|
70
70
|
max-attributes=12 # Max attributes per class
|
|
71
71
|
max-branches=30 # Max branches per function
|
|
72
|
-
max-locals=
|
|
72
|
+
max-locals=70 # Max locals per function
|
|
73
73
|
max-returns=10 # Max return statements per function
|
|
74
74
|
max-statements=120 # Max total statements per function
|
|
75
75
|
max-public-methods=20 # Max public methods per class
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: git-cai-cli
|
|
3
|
-
Version: 0.14.
|
|
3
|
+
Version: 0.14.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
|
|
@@ -90,6 +90,8 @@ Currently supported providers:
|
|
|
90
90
|
- Token usage logging for API calls
|
|
91
91
|
- Branch name as LLM context
|
|
92
92
|
- Extra context for the LLM
|
|
93
|
+
- Per-invocation overrides for temperature, style, language, and emoji
|
|
94
|
+
- Optional large-diff guard (`max_diff_bytes`) that truncates oversized diffs before sending
|
|
93
95
|
- Generation time measurement
|
|
94
96
|
- Local-only usage analytics (per-provider commits, tokens, latency) with opt-in SQLite storage
|
|
95
97
|
- Shell completion for bash, zsh, and fish
|
|
@@ -247,6 +249,7 @@ git cai -g
|
|
|
247
249
|
- `squash_prompt_file` - path to the file where the prompt for the squash is stored
|
|
248
250
|
- `full_files_prompt_file` - path to the prompt used when `-F` / `--full-files` attaches full file contents
|
|
249
251
|
- `full_files` – attach always the full working-tree contents of affected files alongside the diff
|
|
252
|
+
- `max_diff_bytes` – maximum size (in UTF-8 bytes) of the diff/commit-log sent to the LLM; oversized input is truncated with a marker. `0` (default) means no limit
|
|
250
253
|
- `timeout` – HTTP timeout for LLM calls in seconds
|
|
251
254
|
- `branch_context` – include current branch name as LLM context
|
|
252
255
|
- `conventional` – use Conventional Commits format
|
|
@@ -271,6 +274,7 @@ In addition to `git cai`, the following options are available:
|
|
|
271
274
|
- `-C`, `--conventional` – use Conventional Commits format (`type(scope): description`)
|
|
272
275
|
- `-c`, `--crazy` – Trust the LLM and commit without checking
|
|
273
276
|
- `-d`, `--debug` – enable debug logging
|
|
277
|
+
- `-e`, `--temperature` `TEMPERATURE` – override the active provider's sampling temperature for this invocation (provider-scoped, like `-m`)
|
|
274
278
|
- `-F`, `--full-files` – attach the full contents of affected files alongside the diff (uses `full_files_prompt.md`)
|
|
275
279
|
- `-f`, `--files` `PATH` – limit the diff (and full-file content, if enabled) to PATH; repeat for multiple files
|
|
276
280
|
- `-g`, `--generate-config` – generate the default `cai_config.yml` in the current directory
|
|
@@ -293,6 +297,9 @@ In addition to `git cai`, the following options are available:
|
|
|
293
297
|
- `--base` `BRANCH` – explicit base branch for `--PR` (overrides auto-detection: `origin/HEAD` → `main` → `master`)
|
|
294
298
|
- `-S`, `--set` – set a config value (`key=value`) in repo config (requires existing repo config)
|
|
295
299
|
- `-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
|
|
300
|
+
- `--style` `STYLE` – override the commit message style for this invocation (e.g. `funny`, `neutral`, `none`); validated against the supported styles
|
|
301
|
+
- `--language` `CODE` – override the commit message language for this invocation (e.g. `de`, `fr`, `none`); validated against supported codes
|
|
302
|
+
- `--emoji` / `--no-emoji` – override emoji usage for this invocation (use `--no-emoji` to disable when config enables it)
|
|
296
303
|
- `-T`, `--timeout` `SECONDS` – HTTP timeout for this invocation (overrides config)
|
|
297
304
|
- `-t`, `--time` – measure and log commit message generation time
|
|
298
305
|
- `-u`, `--update` – check for updates
|
|
@@ -60,6 +60,8 @@ Currently supported providers:
|
|
|
60
60
|
- Token usage logging for API calls
|
|
61
61
|
- Branch name as LLM context
|
|
62
62
|
- Extra context for the LLM
|
|
63
|
+
- Per-invocation overrides for temperature, style, language, and emoji
|
|
64
|
+
- Optional large-diff guard (`max_diff_bytes`) that truncates oversized diffs before sending
|
|
63
65
|
- Generation time measurement
|
|
64
66
|
- Local-only usage analytics (per-provider commits, tokens, latency) with opt-in SQLite storage
|
|
65
67
|
- Shell completion for bash, zsh, and fish
|
|
@@ -217,6 +219,7 @@ git cai -g
|
|
|
217
219
|
- `squash_prompt_file` - path to the file where the prompt for the squash is stored
|
|
218
220
|
- `full_files_prompt_file` - path to the prompt used when `-F` / `--full-files` attaches full file contents
|
|
219
221
|
- `full_files` – attach always the full working-tree contents of affected files alongside the diff
|
|
222
|
+
- `max_diff_bytes` – maximum size (in UTF-8 bytes) of the diff/commit-log sent to the LLM; oversized input is truncated with a marker. `0` (default) means no limit
|
|
220
223
|
- `timeout` – HTTP timeout for LLM calls in seconds
|
|
221
224
|
- `branch_context` – include current branch name as LLM context
|
|
222
225
|
- `conventional` – use Conventional Commits format
|
|
@@ -241,6 +244,7 @@ In addition to `git cai`, the following options are available:
|
|
|
241
244
|
- `-C`, `--conventional` – use Conventional Commits format (`type(scope): description`)
|
|
242
245
|
- `-c`, `--crazy` – Trust the LLM and commit without checking
|
|
243
246
|
- `-d`, `--debug` – enable debug logging
|
|
247
|
+
- `-e`, `--temperature` `TEMPERATURE` – override the active provider's sampling temperature for this invocation (provider-scoped, like `-m`)
|
|
244
248
|
- `-F`, `--full-files` – attach the full contents of affected files alongside the diff (uses `full_files_prompt.md`)
|
|
245
249
|
- `-f`, `--files` `PATH` – limit the diff (and full-file content, if enabled) to PATH; repeat for multiple files
|
|
246
250
|
- `-g`, `--generate-config` – generate the default `cai_config.yml` in the current directory
|
|
@@ -263,6 +267,9 @@ In addition to `git cai`, the following options are available:
|
|
|
263
267
|
- `--base` `BRANCH` – explicit base branch for `--PR` (overrides auto-detection: `origin/HEAD` → `main` → `master`)
|
|
264
268
|
- `-S`, `--set` – set a config value (`key=value`) in repo config (requires existing repo config)
|
|
265
269
|
- `-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
|
|
270
|
+
- `--style` `STYLE` – override the commit message style for this invocation (e.g. `funny`, `neutral`, `none`); validated against the supported styles
|
|
271
|
+
- `--language` `CODE` – override the commit message language for this invocation (e.g. `de`, `fr`, `none`); validated against supported codes
|
|
272
|
+
- `--emoji` / `--no-emoji` – override emoji usage for this invocation (use `--no-emoji` to disable when config enables it)
|
|
266
273
|
- `-T`, `--timeout` `SECONDS` – HTTP timeout for this invocation (overrides config)
|
|
267
274
|
- `-t`, `--time` – measure and log commit message generation time
|
|
268
275
|
- `-u`, `--update` – check for updates
|
|
@@ -12,6 +12,7 @@ SYNOPSIS
|
|
|
12
12
|
[verse]
|
|
13
13
|
`git cai` [-A | --amend] [-a | --all] [-C | --conventional]
|
|
14
14
|
[-b | --branch] [-c | --crazy] [-d | --debug]
|
|
15
|
+
[-e TEMPERATURE | --temperature TEMPERATURE]
|
|
15
16
|
[-F | --full-files | --no-full-files] [-f PATH | --files PATH]
|
|
16
17
|
[-g | --generate-config]
|
|
17
18
|
[-H KEY=VALUE | --set-home KEY=VALUE] [-h | --help]
|
|
@@ -27,6 +28,7 @@ SYNOPSIS
|
|
|
27
28
|
[-S KEY=VALUE | --set KEY=VALUE]
|
|
28
29
|
[-s [N|HASH] | --squash [N|HASH]]
|
|
29
30
|
[-q true|false | --sql true|false]
|
|
31
|
+
[--style STYLE] [--language CODE] [--emoji | --no-emoji]
|
|
30
32
|
[-T SECONDS | --timeout SECONDS]
|
|
31
33
|
[-t | --time] [-u | --update] [-v | --version]
|
|
32
34
|
[-x CONTEXT | --context CONTEXT]
|
|
@@ -181,6 +183,17 @@ Cannot be combined with `--help` or `--version`.
|
|
|
181
183
|
git cai -d
|
|
182
184
|
----
|
|
183
185
|
|
|
186
|
+
-e, --temperature TEMPERATURE::
|
|
187
|
+
Override the sampling temperature of the active provider for this invocation
|
|
188
|
+
only. Higher values produce more varied wording; lower values are more
|
|
189
|
+
deterministic. The override is provider-scoped, mirroring `--model`, and does
|
|
190
|
+
not change the persisted `cai_config.yml`.
|
|
191
|
+
+
|
|
192
|
+
----
|
|
193
|
+
git cai -e 0.7
|
|
194
|
+
git cai -P anthropic -e 0.2
|
|
195
|
+
----
|
|
196
|
+
|
|
184
197
|
-F, --full-files::
|
|
185
198
|
Send the full working-tree contents of every staged file alongside the diff.
|
|
186
199
|
By default, git-cai sends only the staged diff to the LLM. With `-F`, the
|
|
@@ -488,6 +501,42 @@ git cai -s 3
|
|
|
488
501
|
git cai -s a1b2c3d
|
|
489
502
|
----
|
|
490
503
|
|
|
504
|
+
--style STYLE::
|
|
505
|
+
Override the commit message tone style for this invocation only (e.g.
|
|
506
|
+
`professional`, `neutral`, `friendly`, `funny`, `excited`, `sarcastic`,
|
|
507
|
+
`apologetic`, `academic`, or `none` to let the model choose). Run
|
|
508
|
+
`git cai -l style` to see all styles with examples. An invalid value is
|
|
509
|
+
rejected with an error. To change the style permanently, set `style:` in
|
|
510
|
+
`cai_config.yml`.
|
|
511
|
+
+
|
|
512
|
+
----
|
|
513
|
+
git cai --style funny
|
|
514
|
+
git cai --style none
|
|
515
|
+
----
|
|
516
|
+
|
|
517
|
+
--language CODE::
|
|
518
|
+
Override the commit message language for this invocation only, using a
|
|
519
|
+
supported language code (e.g. `de`, `fr`, `es`), or `none` to omit the
|
|
520
|
+
language instruction. Run `git cai -l language` to list supported codes. An
|
|
521
|
+
unsupported code is rejected with an error. To change it permanently, set
|
|
522
|
+
`language:` in `cai_config.yml`.
|
|
523
|
+
+
|
|
524
|
+
----
|
|
525
|
+
git cai --language de
|
|
526
|
+
git cai --language none
|
|
527
|
+
----
|
|
528
|
+
|
|
529
|
+
--emoji / --no-emoji::
|
|
530
|
+
Override emoji usage for this invocation only. `--emoji` instructs the model
|
|
531
|
+
to use relevant emojis; `--no-emoji` disables them even when the persisted
|
|
532
|
+
config enables emoji. To change the default permanently, set `emoji:` in
|
|
533
|
+
`cai_config.yml`.
|
|
534
|
+
+
|
|
535
|
+
----
|
|
536
|
+
git cai --no-emoji
|
|
537
|
+
git cai --emoji
|
|
538
|
+
----
|
|
539
|
+
|
|
491
540
|
-T, --timeout SECONDS::
|
|
492
541
|
Override the HTTP timeout for the LLM call in this invocation. The default
|
|
493
542
|
is 30 seconds for remote providers and 300 seconds for Ollama (since local
|
|
@@ -824,6 +873,10 @@ Available configuration keys:
|
|
|
824
873
|
- `timeout` -- HTTP timeout in seconds for remote LLM calls (default `30`)
|
|
825
874
|
- `full_files` -- send full working-tree contents of staged files alongside
|
|
826
875
|
the diff (`true`/`false`, default `false`)
|
|
876
|
+
- `max_diff_bytes` -- maximum size (in UTF-8 bytes) of the diff/commit-log
|
|
877
|
+
sent to the LLM. When the input exceeds this, it is truncated and a marker
|
|
878
|
+
line is appended so the model knows it was cut. `0` (the default) means no
|
|
879
|
+
limit. Useful to avoid context-window errors on very large staged changes.
|
|
827
880
|
- `pr_to_file` -- when running `--PR`, write the generated PR description
|
|
828
881
|
to a Markdown file in the repository root instead of printing it to
|
|
829
882
|
stdout (`true`/`false`, default `false`)
|
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
.\" Title: git-cai
|
|
3
3
|
.\" Author: Thorsten Foltz
|
|
4
4
|
.\" Generator: Asciidoctor 2.0.26
|
|
5
|
-
.\" Date: 2026-
|
|
5
|
+
.\" Date: 2026-06-04
|
|
6
6
|
.\" Manual: \ \&
|
|
7
7
|
.\" Source: \ \&
|
|
8
8
|
.\" Language: English
|
|
9
9
|
.\"
|
|
10
|
-
.TH "GIT\-CAI" "1" "2026-
|
|
10
|
+
.TH "GIT\-CAI" "1" "2026-06-04" "\ \&" "\ \&"
|
|
11
11
|
.ie \n(.g .ds Aq \(aq
|
|
12
12
|
.el .ds Aq '
|
|
13
13
|
.ss \n[.ss] 0
|
|
@@ -34,6 +34,7 @@ git-cai \- AI\-powered commit message generator
|
|
|
34
34
|
.nf
|
|
35
35
|
\f(CRgit cai\fP [\-A | \-\-amend] [\-a | \-\-all] [\-C | \-\-conventional]
|
|
36
36
|
[\-b | \-\-branch] [\-c | \-\-crazy] [\-d | \-\-debug]
|
|
37
|
+
[\-e TEMPERATURE | \-\-temperature TEMPERATURE]
|
|
37
38
|
[\-F | \-\-full\-files | \-\-no\-full\-files] [\-f PATH | \-\-files PATH]
|
|
38
39
|
[\-g | \-\-generate\-config]
|
|
39
40
|
[\-H KEY=VALUE | \-\-set\-home KEY=VALUE] [\-h | \-\-help]
|
|
@@ -49,6 +50,7 @@ git-cai \- AI\-powered commit message generator
|
|
|
49
50
|
[\-S KEY=VALUE | \-\-set KEY=VALUE]
|
|
50
51
|
[\-s [N|HASH] | \-\-squash [N|HASH]]
|
|
51
52
|
[\-q true|false | \-\-sql true|false]
|
|
53
|
+
[\-\-style STYLE] [\-\-language CODE] [\-\-emoji | \-\-no\-emoji]
|
|
52
54
|
[\-T SECONDS | \-\-timeout SECONDS]
|
|
53
55
|
[\-t | \-\-time] [\-u | \-\-update] [\-v | \-\-version]
|
|
54
56
|
[\-x CONTEXT | \-\-context CONTEXT]
|
|
@@ -350,6 +352,23 @@ git cai \-d
|
|
|
350
352
|
.if n .RE
|
|
351
353
|
.RE
|
|
352
354
|
.sp
|
|
355
|
+
\-e, \-\-temperature TEMPERATURE
|
|
356
|
+
.RS 4
|
|
357
|
+
Override the sampling temperature of the active provider for this invocation
|
|
358
|
+
only. Higher values produce more varied wording; lower values are more
|
|
359
|
+
deterministic. The override is provider\-scoped, mirroring \f(CR\-\-model\fP, and does
|
|
360
|
+
not change the persisted \f(CRcai_config.yml\fP.
|
|
361
|
+
.sp
|
|
362
|
+
.if n .RS 4
|
|
363
|
+
.nf
|
|
364
|
+
.fam C
|
|
365
|
+
git cai \-e 0.7
|
|
366
|
+
git cai \-P anthropic \-e 0.2
|
|
367
|
+
.fam
|
|
368
|
+
.fi
|
|
369
|
+
.if n .RE
|
|
370
|
+
.RE
|
|
371
|
+
.sp
|
|
353
372
|
\-F, \-\-full\-files
|
|
354
373
|
.RS 4
|
|
355
374
|
Send the full working\-tree contents of every staged file alongside the diff.
|
|
@@ -773,6 +792,60 @@ git cai \-s a1b2c3d
|
|
|
773
792
|
.if n .RE
|
|
774
793
|
.RE
|
|
775
794
|
.sp
|
|
795
|
+
\-\-style STYLE
|
|
796
|
+
.RS 4
|
|
797
|
+
Override the commit message tone style for this invocation only (e.g.
|
|
798
|
+
\f(CRprofessional\fP, \f(CRneutral\fP, \f(CRfriendly\fP, \f(CRfunny\fP, \f(CRexcited\fP, \f(CRsarcastic\fP,
|
|
799
|
+
\f(CRapologetic\fP, \f(CRacademic\fP, or \f(CRnone\fP to let the model choose). Run
|
|
800
|
+
\f(CRgit cai \-l style\fP to see all styles with examples. An invalid value is
|
|
801
|
+
rejected with an error. To change the style permanently, set \f(CRstyle:\fP in
|
|
802
|
+
\f(CRcai_config.yml\fP.
|
|
803
|
+
.sp
|
|
804
|
+
.if n .RS 4
|
|
805
|
+
.nf
|
|
806
|
+
.fam C
|
|
807
|
+
git cai \-\-style funny
|
|
808
|
+
git cai \-\-style none
|
|
809
|
+
.fam
|
|
810
|
+
.fi
|
|
811
|
+
.if n .RE
|
|
812
|
+
.RE
|
|
813
|
+
.sp
|
|
814
|
+
\-\-language CODE
|
|
815
|
+
.RS 4
|
|
816
|
+
Override the commit message language for this invocation only, using a
|
|
817
|
+
supported language code (e.g. \f(CRde\fP, \f(CRfr\fP, \f(CRes\fP), or \f(CRnone\fP to omit the
|
|
818
|
+
language instruction. Run \f(CRgit cai \-l language\fP to list supported codes. An
|
|
819
|
+
unsupported code is rejected with an error. To change it permanently, set
|
|
820
|
+
\f(CRlanguage:\fP in \f(CRcai_config.yml\fP.
|
|
821
|
+
.sp
|
|
822
|
+
.if n .RS 4
|
|
823
|
+
.nf
|
|
824
|
+
.fam C
|
|
825
|
+
git cai \-\-language de
|
|
826
|
+
git cai \-\-language none
|
|
827
|
+
.fam
|
|
828
|
+
.fi
|
|
829
|
+
.if n .RE
|
|
830
|
+
.RE
|
|
831
|
+
.sp
|
|
832
|
+
\-\-emoji / \-\-no\-emoji
|
|
833
|
+
.RS 4
|
|
834
|
+
Override emoji usage for this invocation only. \f(CR\-\-emoji\fP instructs the model
|
|
835
|
+
to use relevant emojis; \f(CR\-\-no\-emoji\fP disables them even when the persisted
|
|
836
|
+
config enables emoji. To change the default permanently, set \f(CRemoji:\fP in
|
|
837
|
+
\f(CRcai_config.yml\fP.
|
|
838
|
+
.sp
|
|
839
|
+
.if n .RS 4
|
|
840
|
+
.nf
|
|
841
|
+
.fam C
|
|
842
|
+
git cai \-\-no\-emoji
|
|
843
|
+
git cai \-\-emoji
|
|
844
|
+
.fam
|
|
845
|
+
.fi
|
|
846
|
+
.if n .RE
|
|
847
|
+
.RE
|
|
848
|
+
.sp
|
|
776
849
|
\-T, \-\-timeout SECONDS
|
|
777
850
|
.RS 4
|
|
778
851
|
Override the HTTP timeout for the LLM call in this invocation. The default
|
|
@@ -1394,6 +1467,20 @@ the diff (\f(CRtrue\fP/\f(CRfalse\fP, default \f(CRfalse\fP)
|
|
|
1394
1467
|
. sp -1
|
|
1395
1468
|
. IP \(bu 2.3
|
|
1396
1469
|
.\}
|
|
1470
|
+
\f(CRmax_diff_bytes\fP \(em maximum size (in UTF\-8 bytes) of the diff/commit\-log
|
|
1471
|
+
sent to the LLM. When the input exceeds this, it is truncated and a marker
|
|
1472
|
+
line is appended so the model knows it was cut. \f(CR0\fP (the default) means no
|
|
1473
|
+
limit. Useful to avoid context\-window errors on very large staged changes.
|
|
1474
|
+
.RE
|
|
1475
|
+
.sp
|
|
1476
|
+
.RS 4
|
|
1477
|
+
.ie n \{\
|
|
1478
|
+
\h'-04'\(bu\h'+03'\c
|
|
1479
|
+
.\}
|
|
1480
|
+
.el \{\
|
|
1481
|
+
. sp -1
|
|
1482
|
+
. IP \(bu 2.3
|
|
1483
|
+
.\}
|
|
1397
1484
|
\f(CRpr_to_file\fP \(em when running \f(CR\-\-PR\fP, write the generated PR description
|
|
1398
1485
|
to a Markdown file in the repository root instead of printing it to
|
|
1399
1486
|
stdout (\f(CRtrue\fP/\f(CRfalse\fP, default \f(CRfalse\fP)
|
|
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
|
|
|
18
18
|
commit_id: str | None
|
|
19
19
|
__commit_id__: str | None
|
|
20
20
|
|
|
21
|
-
__version__ = version = '0.14.
|
|
22
|
-
__version_tuple__ = version_tuple = (0, 14,
|
|
21
|
+
__version__ = version = '0.14.1'
|
|
22
|
+
__version_tuple__ = version_tuple = (0, 14, 1)
|
|
23
23
|
|
|
24
|
-
__commit_id__ = commit_id = '
|
|
24
|
+
__commit_id__ = commit_id = 'gbd1b6f7b7'
|
|
@@ -179,6 +179,27 @@ def callback( # pylint: disable=too-many-arguments,too-many-positional-argument
|
|
|
179
179
|
"--print",
|
|
180
180
|
help="Generate the commit message, print it to stdout, and exit without committing.",
|
|
181
181
|
),
|
|
182
|
+
temperature: float = typer.Option(
|
|
183
|
+
None,
|
|
184
|
+
"-e",
|
|
185
|
+
"--temperature",
|
|
186
|
+
help="Override the active provider's sampling temperature for this invocation.",
|
|
187
|
+
),
|
|
188
|
+
style: str = typer.Option(
|
|
189
|
+
None,
|
|
190
|
+
"--style",
|
|
191
|
+
help="Override the commit message style for this invocation (e.g. funny, neutral, none).",
|
|
192
|
+
),
|
|
193
|
+
language: str = typer.Option(
|
|
194
|
+
None,
|
|
195
|
+
"--language",
|
|
196
|
+
help="Override the commit message language code for this invocation (e.g. de, fr, none).",
|
|
197
|
+
),
|
|
198
|
+
emoji: bool | None = typer.Option(
|
|
199
|
+
None,
|
|
200
|
+
"--emoji/--no-emoji",
|
|
201
|
+
help="Override emoji usage for this invocation. Use --no-emoji to disable when config enables it.",
|
|
202
|
+
),
|
|
182
203
|
):
|
|
183
204
|
"""
|
|
184
205
|
CLI entry point for git-cai-cli.
|
|
@@ -311,6 +332,10 @@ def callback( # pylint: disable=too-many-arguments,too-many-positional-argument
|
|
|
311
332
|
stats_reset=stats_reset,
|
|
312
333
|
signoff=signoff,
|
|
313
334
|
print_only=print_only,
|
|
335
|
+
temperature_override=temperature,
|
|
336
|
+
style_override=style,
|
|
337
|
+
language_override=language,
|
|
338
|
+
emoji_override=emoji,
|
|
314
339
|
)
|
|
315
340
|
|
|
316
341
|
|
|
@@ -24,22 +24,42 @@ _git-cai() {
|
|
|
24
24
|
options=(
|
|
25
25
|
'(-A --amend)'{-A,--amend}'[Regenerate and amend last commit message]'
|
|
26
26
|
'(-a --all)'{-a,--all}'[Stage all tracked files]'
|
|
27
|
+
'(-b --branch)'{-b,--branch}'[Include current branch name as context]'
|
|
27
28
|
'(-C --conventional)'{-C,--conventional}'[Use Conventional Commits format]'
|
|
28
29
|
'(-c --crazy)'{-c,--crazy}'[Commit immediately without editor]'
|
|
29
30
|
'(-d --debug)'{-d,--debug}'[Enable debug logging]'
|
|
31
|
+
'(-e --temperature)'{-e,--temperature}'[Override sampling temperature]:temperature:'
|
|
32
|
+
'(-F --full-files)'{-F,--full-files}'[Send full file contents alongside the diff]'
|
|
33
|
+
'(-f --files)'{-f,--files}'[Limit the diff to these paths]:file:_files'
|
|
30
34
|
'(-g --generate-config)'{-g,--generate-config}'[Generate default config]'
|
|
31
35
|
'(-H --set-home)'{-H,--set-home}'[Set config value in home config]:key=value:'
|
|
32
36
|
'(-h --help)'{-h,--help}'[Show help]'
|
|
37
|
+
'(-I --init)'{-I,--init}'[Interactive setup wizard]'
|
|
33
38
|
'(-i --install-completion)'{-i,--install-completion}'[Install shell completion]'
|
|
34
|
-
'(-l --list)'{-l,--list}'[List information]'
|
|
39
|
+
'(-l --list)'{-l,--list}'[List information]:type:(config editor language model path provider style)'
|
|
35
40
|
'(-m --model)'{-m,--model}'[Override model (requires --provider)]:model:'
|
|
41
|
+
'(-o --signoff)'{-o,--signoff}'[Append a Signed-off-by trailer]'
|
|
36
42
|
'(-P --provider)'{-P,--provider}'[Override LLM provider]:provider:(anthropic deepseek gemini groq mistral ollama openai xai)'
|
|
37
43
|
'(-p --generate-prompts)'{-p,--generate-prompts}'[Generate default prompts]'
|
|
44
|
+
'--print[Print the generated message to stdout and exit]'
|
|
45
|
+
'(-q --sql)'{-q,--sql}'[Override stats writing for this run]:value:(true false)'
|
|
46
|
+
'(-r --PR)'{-r,--PR}'[Generate a Pull Request description]'
|
|
47
|
+
'--base[Base branch for --PR]:branch:'
|
|
38
48
|
'(-S --set)'{-S,--set}'[Set config value in repo config]:key=value:'
|
|
39
49
|
'(-s --squash)'{-s,--squash}'[Squash commits on this branch]'
|
|
50
|
+
'(-T --timeout)'{-T,--timeout}'[HTTP timeout in seconds]:seconds:'
|
|
40
51
|
'(-t --time)'{-t,--time}'[Measure generation time]'
|
|
41
52
|
'(-u --update)'{-u,--update}'[Check for updates]'
|
|
42
53
|
'(-v --version)'{-v,--version}'[Show version]'
|
|
54
|
+
'(-x --context)'{-x,--context}'[Provide extra context for the LLM]:context:'
|
|
55
|
+
'(-z --stats)'{-z,--stats}'[Show local usage analytics]'
|
|
56
|
+
'--since[Filter --stats to events on or after a date]:date:'
|
|
57
|
+
'--json[Render --stats output as JSON]'
|
|
58
|
+
'--reset-stats[Delete all rows from the local stats DB]'
|
|
59
|
+
'--style[Override commit message style]:style:(academic apologetic excited friendly funny neutral none professional sarcastic)'
|
|
60
|
+
'--language[Override commit message language code]:language:'
|
|
61
|
+
'--emoji[Enable emoji for this invocation]'
|
|
62
|
+
'--no-emoji[Disable emoji for this invocation]'
|
|
43
63
|
)
|
|
44
64
|
_arguments -s -S $options
|
|
45
65
|
}
|
|
@@ -50,22 +70,37 @@ _git-cai "$@"
|
|
|
50
70
|
# Bash completion script.
|
|
51
71
|
_BASH_SCRIPT = """\
|
|
52
72
|
_git_cai_completion() {
|
|
53
|
-
local cur opts
|
|
73
|
+
local cur prev opts
|
|
54
74
|
COMPREPLY=()
|
|
55
75
|
cur="${COMP_WORDS[COMP_CWORD]}"
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
-
|
|
59
|
-
-
|
|
60
|
-
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
76
|
+
prev="${COMP_WORDS[COMP_CWORD-1]}"
|
|
77
|
+
opts="-A --amend -a --all -b --branch -C --conventional -c --crazy \\
|
|
78
|
+
-d --debug -e --temperature -F --full-files -f --files \\
|
|
79
|
+
-g --generate-config -H --set-home -h --help -I --init \\
|
|
80
|
+
-i --install-completion -l --list -m --model -o --signoff \\
|
|
81
|
+
-P --provider -p --generate-prompts --print -q --sql \\
|
|
82
|
+
-r --PR --base -S --set -s --squash -T --timeout -t --time \\
|
|
83
|
+
-u --update -v --version -x --context -z --stats --since \\
|
|
84
|
+
--json --reset-stats --style --language --emoji --no-emoji"
|
|
85
|
+
|
|
86
|
+
if [[ "$prev" == "--provider" || "$prev" == "-P" ]]; then
|
|
64
87
|
local providers="anthropic deepseek gemini groq mistral ollama openai xai"
|
|
65
88
|
COMPREPLY=( $(compgen -W "$providers" -- "$cur") )
|
|
66
89
|
return 0
|
|
67
90
|
fi
|
|
68
91
|
|
|
92
|
+
if [[ "$prev" == "--list" || "$prev" == "-l" ]]; then
|
|
93
|
+
local types="config editor language model path provider style"
|
|
94
|
+
COMPREPLY=( $(compgen -W "$types" -- "$cur") )
|
|
95
|
+
return 0
|
|
96
|
+
fi
|
|
97
|
+
|
|
98
|
+
if [[ "$prev" == "--style" ]]; then
|
|
99
|
+
local styles="academic apologetic excited friendly funny neutral none professional sarcastic"
|
|
100
|
+
COMPREPLY=( $(compgen -W "$styles" -- "$cur") )
|
|
101
|
+
return 0
|
|
102
|
+
fi
|
|
103
|
+
|
|
69
104
|
COMPREPLY=( $(compgen -W "$opts" -- "$cur") )
|
|
70
105
|
return 0
|
|
71
106
|
}
|
|
@@ -83,22 +118,42 @@ _FISH_SCRIPT = """\
|
|
|
83
118
|
# Completions for git-cai / git cai
|
|
84
119
|
complete -c git-cai -s A -l amend -d 'Regenerate and amend last commit message'
|
|
85
120
|
complete -c git-cai -s a -l all -d 'Stage all tracked files'
|
|
121
|
+
complete -c git-cai -s b -l branch -d 'Include current branch name as context'
|
|
86
122
|
complete -c git-cai -s C -l conventional -d 'Use Conventional Commits format'
|
|
87
123
|
complete -c git-cai -s c -l crazy -d 'Commit immediately without editor'
|
|
88
124
|
complete -c git-cai -s d -l debug -d 'Enable debug logging'
|
|
125
|
+
complete -c git-cai -s e -l temperature -d 'Override sampling temperature' -r
|
|
126
|
+
complete -c git-cai -s F -l full-files -d 'Send full file contents alongside the diff'
|
|
127
|
+
complete -c git-cai -s f -l files -d 'Limit the diff to these paths' -r
|
|
89
128
|
complete -c git-cai -s g -l generate-config -d 'Generate default config'
|
|
90
129
|
complete -c git-cai -s H -l set-home -d 'Set config value in home config' -r
|
|
91
130
|
complete -c git-cai -s h -l help -d 'Show help'
|
|
131
|
+
complete -c git-cai -s I -l init -d 'Interactive setup wizard'
|
|
92
132
|
complete -c git-cai -s i -l install-completion -d 'Install shell completion'
|
|
93
|
-
complete -c git-cai -s l -l list -d 'List information'
|
|
133
|
+
complete -c git-cai -s l -l list -d 'List information' -x -a 'config editor language model path provider style'
|
|
94
134
|
complete -c git-cai -s m -l model -d 'Override model' -r
|
|
135
|
+
complete -c git-cai -s o -l signoff -d 'Append a Signed-off-by trailer'
|
|
95
136
|
complete -c git-cai -s P -l provider -d 'Override LLM provider' -r -a 'anthropic deepseek gemini groq mistral ollama openai xai'
|
|
96
137
|
complete -c git-cai -s p -l generate-prompts -d 'Generate default prompts'
|
|
138
|
+
complete -c git-cai -l print -d 'Print the generated message and exit'
|
|
139
|
+
complete -c git-cai -s q -l sql -d 'Override stats writing for this run' -r -a 'true false'
|
|
140
|
+
complete -c git-cai -s r -l PR -d 'Generate a Pull Request description'
|
|
141
|
+
complete -c git-cai -l base -d 'Base branch for --PR' -r
|
|
97
142
|
complete -c git-cai -s S -l set -d 'Set config value in repo config' -r
|
|
98
143
|
complete -c git-cai -s s -l squash -d 'Squash commits on this branch'
|
|
144
|
+
complete -c git-cai -s T -l timeout -d 'HTTP timeout in seconds' -r
|
|
99
145
|
complete -c git-cai -s t -l time -d 'Measure generation time'
|
|
100
146
|
complete -c git-cai -s u -l update -d 'Check for updates'
|
|
101
147
|
complete -c git-cai -s v -l version -d 'Show version'
|
|
148
|
+
complete -c git-cai -s x -l context -d 'Provide extra context for the LLM' -r
|
|
149
|
+
complete -c git-cai -s z -l stats -d 'Show local usage analytics'
|
|
150
|
+
complete -c git-cai -l since -d 'Filter --stats to events on or after a date' -r
|
|
151
|
+
complete -c git-cai -l json -d 'Render --stats output as JSON'
|
|
152
|
+
complete -c git-cai -l reset-stats -d 'Delete all rows from the local stats DB'
|
|
153
|
+
complete -c git-cai -l style -d 'Override commit message style' -x -a 'academic apologetic excited friendly funny neutral none professional sarcastic'
|
|
154
|
+
complete -c git-cai -l language -d 'Override commit message language code' -r
|
|
155
|
+
complete -c git-cai -l emoji -d 'Enable emoji for this invocation'
|
|
156
|
+
complete -c git-cai -l no-emoji -d 'Disable emoji for this invocation'
|
|
102
157
|
"""
|
|
103
158
|
|
|
104
159
|
|
|
@@ -60,6 +60,7 @@ DEFAULT_CONFIG: dict[str, Any] = {
|
|
|
60
60
|
"measure_time": False,
|
|
61
61
|
"timeout": 30,
|
|
62
62
|
"full_files": False,
|
|
63
|
+
"max_diff_bytes": 0,
|
|
63
64
|
"pr_to_file": False,
|
|
64
65
|
"pr_file_name": "PR_DESCRIPTION.md",
|
|
65
66
|
"pr_prompt_file": "",
|
|
@@ -74,6 +75,7 @@ TOKENLESS_PROVIDERS: set[str] = {
|
|
|
74
75
|
|
|
75
76
|
TOKEN_TEMPLATE = {
|
|
76
77
|
"anthropic": "PUT-YOUR-ANTHROPIC-TOKEN-HERE",
|
|
78
|
+
"deepseek": "PUT-YOUR-DEEPSEEK-TOKEN-HERE",
|
|
77
79
|
"gemini": "PUT-YOUR-GEMINI-TOKEN-HERE",
|
|
78
80
|
"groq": "PUT-YOUR-GROQ-TOKEN-HERE",
|
|
79
81
|
"openai": "PUT-YOUR-OPENAI-TOKEN-HERE",
|
|
@@ -460,6 +462,7 @@ def ordered_default_config(
|
|
|
460
462
|
"measure_time",
|
|
461
463
|
"timeout",
|
|
462
464
|
"full_files",
|
|
465
|
+
"max_diff_bytes",
|
|
463
466
|
"pr_to_file",
|
|
464
467
|
"pr_file_name",
|
|
465
468
|
"pr_prompt_file",
|
|
@@ -592,6 +595,9 @@ def apply_cli_overrides(
|
|
|
592
595
|
timeout_override: int | None = None,
|
|
593
596
|
full_files_override: bool | None = None,
|
|
594
597
|
sql_override: bool | None = None,
|
|
598
|
+
style_override: str | None = None,
|
|
599
|
+
language_override: str | None = None,
|
|
600
|
+
emoji_override: bool | None = None,
|
|
595
601
|
) -> None:
|
|
596
602
|
"""Apply per-invocation CLI flag overrides to the config dict in-place.
|
|
597
603
|
|
|
@@ -602,6 +608,12 @@ def apply_cli_overrides(
|
|
|
602
608
|
|
|
603
609
|
``sql_override`` mirrors ``--sql true|false`` and overrides the
|
|
604
610
|
top-level ``stats`` boolean.
|
|
611
|
+
|
|
612
|
+
``style_override`` / ``language_override`` / ``emoji_override`` mirror
|
|
613
|
+
``--style`` / ``--language`` / ``--emoji`` and override the top-level
|
|
614
|
+
generation knobs. Style and language are validated here (the normal
|
|
615
|
+
config validation already ran during ``load_config``, before these
|
|
616
|
+
overrides are applied); invalid values raise ``typer.Exit``.
|
|
605
617
|
"""
|
|
606
618
|
if conventional is not None:
|
|
607
619
|
config["conventional"] = conventional
|
|
@@ -613,15 +625,38 @@ def apply_cli_overrides(
|
|
|
613
625
|
config["full_files"] = full_files_override
|
|
614
626
|
if sql_override is not None:
|
|
615
627
|
config["stats"] = sql_override
|
|
628
|
+
if style_override is not None:
|
|
629
|
+
try:
|
|
630
|
+
config["style"] = _validate_style(style_override)
|
|
631
|
+
except ValueError as exc:
|
|
632
|
+
typer.echo(f"Error: {exc}", err=True)
|
|
633
|
+
raise typer.Exit(code=1) from exc
|
|
634
|
+
if language_override is not None:
|
|
635
|
+
normalized = language_override.strip().lower()
|
|
636
|
+
if normalized != "none" and normalized not in ALLOWED_LANGUAGES:
|
|
637
|
+
typer.echo(
|
|
638
|
+
f"Error: unknown language '{language_override}'. "
|
|
639
|
+
"Run 'git cai -l language' to see supported codes.",
|
|
640
|
+
err=True,
|
|
641
|
+
)
|
|
642
|
+
raise typer.Exit(code=1)
|
|
643
|
+
config["language"] = normalized
|
|
644
|
+
if emoji_override is not None:
|
|
645
|
+
config["emoji"] = emoji_override
|
|
616
646
|
|
|
617
647
|
|
|
618
648
|
def apply_provider_overrides(
|
|
619
649
|
config: dict,
|
|
620
650
|
provider_override: str | None,
|
|
621
651
|
model_override: str | None,
|
|
652
|
+
temperature_override: float | None = None,
|
|
622
653
|
) -> None:
|
|
623
654
|
"""
|
|
624
|
-
Apply --provider and --
|
|
655
|
+
Apply --provider, --model and --temperature overrides to the config
|
|
656
|
+
dict in-place.
|
|
657
|
+
|
|
658
|
+
``temperature_override`` is provider-scoped (like ``--model``): it
|
|
659
|
+
sets ``config[<active provider>]["temperature"]`` for this run only.
|
|
625
660
|
|
|
626
661
|
Raises typer.Exit on validation errors.
|
|
627
662
|
"""
|
|
@@ -664,3 +699,15 @@ def apply_provider_overrides(
|
|
|
664
699
|
model_override,
|
|
665
700
|
provider,
|
|
666
701
|
)
|
|
702
|
+
|
|
703
|
+
if temperature_override is not None:
|
|
704
|
+
provider = config["default"]
|
|
705
|
+
if provider not in config or not isinstance(config[provider], dict):
|
|
706
|
+
config[provider] = {"temperature": temperature_override}
|
|
707
|
+
else:
|
|
708
|
+
config[provider]["temperature"] = temperature_override
|
|
709
|
+
log.info(
|
|
710
|
+
"Temperature overridden to %s for provider '%s'.",
|
|
711
|
+
temperature_override,
|
|
712
|
+
provider,
|
|
713
|
+
)
|
|
@@ -192,6 +192,28 @@ def git_diff_excluding(
|
|
|
192
192
|
return result.stdout
|
|
193
193
|
|
|
194
194
|
|
|
195
|
+
def truncate_diff(diff: str, max_bytes: int) -> tuple[str, bool]:
|
|
196
|
+
"""Truncate ``diff`` to at most ``max_bytes`` UTF-8 bytes.
|
|
197
|
+
|
|
198
|
+
A ``max_bytes`` of 0 (or negative) means "no limit" and the diff is
|
|
199
|
+
returned unchanged — preserving the default behavior. When truncation
|
|
200
|
+
occurs, a marker line is appended so both the LLM and the user know the
|
|
201
|
+
input was cut. Returns ``(possibly_truncated_diff, was_truncated)``.
|
|
202
|
+
"""
|
|
203
|
+
if max_bytes <= 0:
|
|
204
|
+
return diff, False
|
|
205
|
+
|
|
206
|
+
encoded = diff.encode("utf-8")
|
|
207
|
+
if len(encoded) <= max_bytes:
|
|
208
|
+
return diff, False
|
|
209
|
+
|
|
210
|
+
# Cut on a UTF-8 safe boundary: decoding with errors="ignore" drops any
|
|
211
|
+
# partial trailing multibyte sequence left by the byte-level slice.
|
|
212
|
+
truncated = encoded[:max_bytes].decode("utf-8", errors="ignore")
|
|
213
|
+
marker = f"\n\n[... diff truncated: exceeded max_diff_bytes={max_bytes} ...]"
|
|
214
|
+
return truncated + marker, True
|
|
215
|
+
|
|
216
|
+
|
|
195
217
|
def _matches_caiignore(path: str, patterns: Sequence[str]) -> bool:
|
|
196
218
|
"""Return True if `path` matches any of the `.caiignore` patterns.
|
|
197
219
|
|
|
@@ -1148,7 +1148,14 @@ class CommitMessageGenerator:
|
|
|
1148
1148
|
getattr(usage, "completion_tokens", None),
|
|
1149
1149
|
)
|
|
1150
1150
|
|
|
1151
|
-
|
|
1151
|
+
# Some models (e.g. reasoning models that hit a stop/refusal) return
|
|
1152
|
+
# ``None`` content; ``.strip()`` on that would raise AttributeError.
|
|
1153
|
+
# Surface a clean ValueError that ``_validate_llm_call`` can classify.
|
|
1154
|
+
content_out = completion.choices[0].message.content
|
|
1155
|
+
if not content_out:
|
|
1156
|
+
raise ValueError(f"{provider_name} returned an empty response.")
|
|
1157
|
+
|
|
1158
|
+
return content_out.strip()
|
|
1152
1159
|
|
|
1153
1160
|
def generate_xai(
|
|
1154
1161
|
self,
|