git-cai-cli 0.13.1__tar.gz → 0.13.2__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.13.1 → git_cai_cli-0.13.2}/.linters/.pylintrc +4 -4
  2. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/PKG-INFO +30 -3
  3. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/README.md +28 -2
  4. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/cai_config.yml +1 -0
  5. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/docs/git-cai.txt +97 -3
  6. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/docs/man/git-cai.1 +139 -5
  7. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/pyproject.toml +1 -0
  8. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/src/git_cai_cli/_version.py +3 -3
  9. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/src/git_cai_cli/cli/cli.py +55 -12
  10. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/src/git_cai_cli/cli/helptext.py +5 -0
  11. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/src/git_cai_cli/cli/modes.py +6 -2
  12. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/src/git_cai_cli/core/config.py +64 -11
  13. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/src/git_cai_cli/core/gitutils.py +22 -9
  14. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/src/git_cai_cli/core/llm.py +236 -20
  15. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/src/git_cai_cli/core/options.py +2 -0
  16. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/src/git_cai_cli/core/pr.py +15 -1
  17. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/src/git_cai_cli/core/squash.py +58 -12
  18. git_cai_cli-0.13.2/src/git_cai_cli/core/stats.py +419 -0
  19. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/src/git_cai_cli/core/validate.py +109 -25
  20. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/src/git_cai_cli/main.py +41 -6
  21. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/src/git_cai_cli.egg-info/PKG-INFO +30 -3
  22. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/src/git_cai_cli.egg-info/SOURCES.txt +2 -0
  23. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/src/git_cai_cli.egg-info/requires.txt +1 -0
  24. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/tests/unit/test_branch_context.py +13 -1
  25. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/tests/unit/test_cli.py +110 -4
  26. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/tests/unit/test_config.py +231 -3
  27. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/tests/unit/test_gitutils.py +42 -0
  28. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/tests/unit/test_llm.py +176 -23
  29. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/tests/unit/test_prompt_loading.py +56 -0
  30. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/tests/unit/test_squash.py +195 -0
  31. git_cai_cli-0.13.2/tests/unit/test_stats.py +705 -0
  32. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/tests/unit/test_validate.py +227 -0
  33. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/uv.lock +11 -0
  34. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/.caiignore +0 -0
  35. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/.gitattributes +0 -0
  36. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/.github/cd/.SRCINFO +0 -0
  37. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/.github/cd/PKGBUILD +0 -0
  38. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/.github/ci/_version.py +0 -0
  39. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/.github/ci/cai_config.ci.yml +0 -0
  40. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/.github/ci/tokens.ci.yml +0 -0
  41. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/.github/workflows/python-tests.yml +0 -0
  42. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/.github/workflows/release.yml +0 -0
  43. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/.github/workflows/release_aur.yml +0 -0
  44. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/.gitignore +0 -0
  45. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/.linters/.bandit.yml +0 -0
  46. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/.linters/.checkov.yml +0 -0
  47. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/.linters/.flake8 +0 -0
  48. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/.linters/.ls-lint.yml +0 -0
  49. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/.linters/.markdown-link-check.json +0 -0
  50. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/.linters/.markdownlint.json +0 -0
  51. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/.linters/.proselintrc +0 -0
  52. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/.linters/.yamllint.yml +0 -0
  53. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/.linters/check_git_branch_name.sh +0 -0
  54. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/.linters/lychee.toml +0 -0
  55. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/.linters/pyrightconfig.json +0 -0
  56. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/.markdownlintignore +0 -0
  57. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/.mega-linter.yml +0 -0
  58. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/.semgrepignore +0 -0
  59. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/.trivyignore +0 -0
  60. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/CLAUDE.md +0 -0
  61. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/LICENSE +0 -0
  62. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/Makefile +0 -0
  63. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/setup.cfg +0 -0
  64. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/src/git_cai_cli/__init__.py +0 -0
  65. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/src/git_cai_cli/cli/__init__.py +0 -0
  66. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/src/git_cai_cli/core/__init__.py +0 -0
  67. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/src/git_cai_cli/core/completion.py +0 -0
  68. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/src/git_cai_cli/core/editors.py +0 -0
  69. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/src/git_cai_cli/core/languages.py +0 -0
  70. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/src/git_cai_cli/core/prompts_fallback.py +0 -0
  71. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/src/git_cai_cli/core/spinner.py +0 -0
  72. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/src/git_cai_cli.egg-info/dependency_links.txt +0 -0
  73. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/src/git_cai_cli.egg-info/entry_points.txt +0 -0
  74. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/src/git_cai_cli.egg-info/top_level.txt +0 -0
  75. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/tests/conftest.py +0 -0
  76. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/tests/integration/test_cli_integration.py +0 -0
  77. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/tests/integration/test_config_integration.py +0 -0
  78. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/tests/integration/test_gitutils_integration.py +0 -0
  79. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/tests/integration/test_modes_integration.py +0 -0
  80. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/tests/integration/test_options_integration.py +0 -0
  81. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/tests/integration/test_pr_integration.py +0 -0
  82. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/tests/integration/test_squash_integration.py +0 -0
  83. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/tests/unit/test_amend.py +0 -0
  84. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/tests/unit/test_completion.py +0 -0
  85. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/tests/unit/test_conventional.py +0 -0
  86. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/tests/unit/test_helptext.py +0 -0
  87. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/tests/unit/test_main.py +0 -0
  88. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/tests/unit/test_modes.py +0 -0
  89. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/tests/unit/test_options.py +0 -0
  90. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/tests/unit/test_pr.py +0 -0
  91. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/tests/unit/test_set_config.py +0 -0
  92. {git_cai_cli-0.13.1 → git_cai_cli-0.13.2}/tests/unit/test_spinner.py +0 -0
@@ -66,10 +66,10 @@ check-protected-access-in-special-methods=no
66
66
  # Don’t warn about protected attr access in dunder methods
67
67
 
68
68
  [DESIGN]
69
- max-args=15 # Max arguments per function
70
- max-attributes=7 # Max attributes per class
69
+ max-args=20 # Max arguments per function
70
+ max-attributes=12 # Max attributes per class
71
71
  max-branches=30 # Max branches per function
72
- max-locals=50 # Max locals per function
72
+ max-locals=60 # Max locals per function
73
73
  max-returns=10 # Max return statements per function
74
74
  max-statements=100 # Max total statements per function
75
75
  max-public-methods=20 # Max public methods per class
@@ -77,7 +77,7 @@ min-public-methods=1 # Min public methods per class
77
77
  max-nested-blocks=15 # Max nesting depth
78
78
  max-bool-expr=15 # Max boolean subexpressions in a condition
79
79
  max-parents=7 # Max base classes per class
80
- max-positional-arguments=15 # Max positional arguments per function
80
+ max-positional-arguments=20 # Max positional arguments per function
81
81
 
82
82
  [EXCEPTIONS]
83
83
  overgeneral-exceptions=builtins.BaseException,builtins.Exception
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: git-cai-cli
3
- Version: 0.13.1
3
+ Version: 0.13.2
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
@@ -25,6 +25,7 @@ Requires-Dist: pyyaml>=6.0.3
25
25
  Requires-Dist: openai>=2.30.0
26
26
  Requires-Dist: typer>=0.23.1
27
27
  Requires-Dist: requests>=2.33.0
28
+ Requires-Dist: pathspec>=0.12.1
28
29
  Dynamic: license-file
29
30
 
30
31
  # cai
@@ -87,6 +88,7 @@ Currently supported providers:
87
88
  - Branch name as LLM context
88
89
  - Extra context for the LLM
89
90
  - Generation time measurement
91
+ - Local-only usage analytics (per-provider commits, tokens, latency) with opt-in SQLite storage
90
92
  - Shell completion for bash, zsh, and fish
91
93
 
92
94
  ---
@@ -237,6 +239,8 @@ git cai -g
237
239
  - `pr_to_file` – when `--PR` is used, write the generated description to a Markdown file in the repo root instead of stdout (default `false`)
238
240
  - `pr_file_name` – filename used when `pr_to_file` is `true` (default `PR_DESCRIPTION.md`)
239
241
  - `pr_prompt_file` – optional path to a custom Markdown prompt for `--PR` (falls back to `~/.config/cai/pr_prompt.md`, then a built-in default)
242
+ - `stats` – opt in to local-only usage analytics (per-run row in a SQLite DB at `~/.local/share/git-cai/stats.db`); default `false`.
243
+ No diff content, commit messages, or file paths are stored — only metadata (provider, model, kind, repo name, token counts, latency, settings)
240
244
 
241
245
  ---
242
246
 
@@ -258,17 +262,22 @@ In addition to `git cai`, the following options are available:
258
262
  - `-i`, `--install-completion` – install shell completion for bash, zsh, or fish
259
263
  - `-l`, `--list` – list available information (`config`, `editor`, `language`, `model`, `path`, `provider`, `style`)
260
264
  - `-m`, `--model` – override the model for this invocation (requires `-P`)
261
- - `-p`, `--generate-prompts` – generate default `commit_prompt.md` and `squash_prompt.md` in the current directory (for customization)
262
265
  - `-P`, `--provider` – override the LLM provider for this invocation
266
+ - `-p`, `--generate-prompts` – generate default `commit_prompt.md` and `squash_prompt.md` in the current directory (for customization)
267
+ - `-Q`, `--stats` – show local-only usage analytics (commits/squashes/PRs per provider, tokens, average latency)
268
+ - `--since YYYY-MM-DD` – filter `--stats` to events on or after this date
269
+ - `--json` – render `--stats` output as JSON
270
+ - `--reset-stats` – delete all rows from the local stats DB
271
+ - `-q`, `--sql true|false` – override stats writing for this run (wins over the persisted `stats` config)
263
272
  - `-r`, `--PR` – generate a Pull Request description from the commits between the current branch and its base (prints to stdout by default; set `pr_to_file=true` to write a Markdown file)
264
273
  - `--base` `BRANCH` – explicit base branch for `--PR` (overrides auto-detection: `origin/HEAD` → `main` → `master`)
265
274
  - `-S`, `--set` – set a config value (`key=value`) in repo config (requires existing repo config)
266
275
  - `-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
267
276
  - `-T`, `--timeout` `SECONDS` – HTTP timeout for this invocation (overrides config)
268
277
  - `-t`, `--time` – measure and log commit message generation time
269
- - `-x`, `--context` – provide extra context for the LLM (e.g. ticket number, reason for change)
270
278
  - `-u`, `--update` – check for updates
271
279
  - `-v`, `--version` – show the installed version
280
+ - `-x`, `--context` – provide extra context for the LLM (e.g. ticket number, reason for change)
272
281
 
273
282
  ## Examples
274
283
 
@@ -356,6 +365,24 @@ git cai -r # writes ./PR.md (or PR_DESCRIPTION.md by defau
356
365
  Configuration follows the usual precedence: repo `cai_config.yml` wins,
357
366
  otherwise `~/.config/cai/cai_config.yml`, otherwise the built-in defaults.
358
367
 
368
+ ### Local usage analytics
369
+
370
+ Opt in by setting `stats: true` in `cai_config.yml` (or pass `-q true` for a single run). Each generation appends one row to a local SQLite DB at `~/.local/share/git-cai/stats.db` with metadata only — no diff, message, or file content.
371
+
372
+ ```sh
373
+ git cai -S stats=true # enable persistently in the repo config
374
+ git cai -H stats=true # or in the home config
375
+ git cai -q true # one-off opt-in regardless of config
376
+ git cai -q false # one-off opt-out
377
+
378
+ git cai --stats # text summary
379
+ git cai -Q --json # machine-readable
380
+ git cai -Q --since 2026-01-01 # date filter
381
+ git cai --reset-stats # wipe all rows
382
+ ```
383
+
384
+ Rows are split by `kind` (`commit`, `amend`, `squash`, `pr`) and capture provider, model, repo name, token counts, real LLM latency, and a snapshot of the active settings (language, style, emoji, temperature, prompt file).
385
+
359
386
  ### Changing configuration from the CLI
360
387
 
361
388
  Instead of editing YAML files manually, use `--set` or `--set-home` to update config values.
@@ -58,6 +58,7 @@ Currently supported providers:
58
58
  - Branch name as LLM context
59
59
  - Extra context for the LLM
60
60
  - Generation time measurement
61
+ - Local-only usage analytics (per-provider commits, tokens, latency) with opt-in SQLite storage
61
62
  - Shell completion for bash, zsh, and fish
62
63
 
63
64
  ---
@@ -208,6 +209,8 @@ git cai -g
208
209
  - `pr_to_file` – when `--PR` is used, write the generated description to a Markdown file in the repo root instead of stdout (default `false`)
209
210
  - `pr_file_name` – filename used when `pr_to_file` is `true` (default `PR_DESCRIPTION.md`)
210
211
  - `pr_prompt_file` – optional path to a custom Markdown prompt for `--PR` (falls back to `~/.config/cai/pr_prompt.md`, then a built-in default)
212
+ - `stats` – opt in to local-only usage analytics (per-run row in a SQLite DB at `~/.local/share/git-cai/stats.db`); default `false`.
213
+ No diff content, commit messages, or file paths are stored — only metadata (provider, model, kind, repo name, token counts, latency, settings)
211
214
 
212
215
  ---
213
216
 
@@ -229,17 +232,22 @@ In addition to `git cai`, the following options are available:
229
232
  - `-i`, `--install-completion` – install shell completion for bash, zsh, or fish
230
233
  - `-l`, `--list` – list available information (`config`, `editor`, `language`, `model`, `path`, `provider`, `style`)
231
234
  - `-m`, `--model` – override the model for this invocation (requires `-P`)
232
- - `-p`, `--generate-prompts` – generate default `commit_prompt.md` and `squash_prompt.md` in the current directory (for customization)
233
235
  - `-P`, `--provider` – override the LLM provider for this invocation
236
+ - `-p`, `--generate-prompts` – generate default `commit_prompt.md` and `squash_prompt.md` in the current directory (for customization)
237
+ - `-Q`, `--stats` – show local-only usage analytics (commits/squashes/PRs per provider, tokens, average latency)
238
+ - `--since YYYY-MM-DD` – filter `--stats` to events on or after this date
239
+ - `--json` – render `--stats` output as JSON
240
+ - `--reset-stats` – delete all rows from the local stats DB
241
+ - `-q`, `--sql true|false` – override stats writing for this run (wins over the persisted `stats` config)
234
242
  - `-r`, `--PR` – generate a Pull Request description from the commits between the current branch and its base (prints to stdout by default; set `pr_to_file=true` to write a Markdown file)
235
243
  - `--base` `BRANCH` – explicit base branch for `--PR` (overrides auto-detection: `origin/HEAD` → `main` → `master`)
236
244
  - `-S`, `--set` – set a config value (`key=value`) in repo config (requires existing repo config)
237
245
  - `-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
238
246
  - `-T`, `--timeout` `SECONDS` – HTTP timeout for this invocation (overrides config)
239
247
  - `-t`, `--time` – measure and log commit message generation time
240
- - `-x`, `--context` – provide extra context for the LLM (e.g. ticket number, reason for change)
241
248
  - `-u`, `--update` – check for updates
242
249
  - `-v`, `--version` – show the installed version
250
+ - `-x`, `--context` – provide extra context for the LLM (e.g. ticket number, reason for change)
243
251
 
244
252
  ## Examples
245
253
 
@@ -327,6 +335,24 @@ git cai -r # writes ./PR.md (or PR_DESCRIPTION.md by defau
327
335
  Configuration follows the usual precedence: repo `cai_config.yml` wins,
328
336
  otherwise `~/.config/cai/cai_config.yml`, otherwise the built-in defaults.
329
337
 
338
+ ### Local usage analytics
339
+
340
+ Opt in by setting `stats: true` in `cai_config.yml` (or pass `-q true` for a single run). Each generation appends one row to a local SQLite DB at `~/.local/share/git-cai/stats.db` with metadata only — no diff, message, or file content.
341
+
342
+ ```sh
343
+ git cai -S stats=true # enable persistently in the repo config
344
+ git cai -H stats=true # or in the home config
345
+ git cai -q true # one-off opt-in regardless of config
346
+ git cai -q false # one-off opt-out
347
+
348
+ git cai --stats # text summary
349
+ git cai -Q --json # machine-readable
350
+ git cai -Q --since 2026-01-01 # date filter
351
+ git cai --reset-stats # wipe all rows
352
+ ```
353
+
354
+ Rows are split by `kind` (`commit`, `amend`, `squash`, `pr`) and capture provider, model, repo name, token counts, real LLM latency, and a snapshot of the active settings (language, style, emoji, temperature, prompt file).
355
+
330
356
  ### Changing configuration from the CLI
331
357
 
332
358
  Instead of editing YAML files manually, use `--set` or `--set-home` to update config values.
@@ -15,6 +15,7 @@ full_files: false
15
15
  pr_to_file: false
16
16
  pr_file_name: PR_DESCRIPTION.md
17
17
  pr_prompt_file: "/home/thorsten/.config/cai/pr_prompt.md"
18
+ stats: true
18
19
  anthropic:
19
20
  model: claude-haiku-4-5
20
21
  temperature: 0
@@ -12,7 +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
- [-F | --full-files] [-f PATH | --files PATH]
15
+ [-F | --full-files | --no-full-files] [-f PATH | --files PATH]
16
16
  [-g | --generate-config]
17
17
  [-H KEY=VALUE | --set-home KEY=VALUE] [-h | --help]
18
18
  [-i | --install-completion]
@@ -23,6 +23,8 @@ SYNOPSIS
23
23
  [-r | --PR] [--base BRANCH]
24
24
  [-S KEY=VALUE | --set KEY=VALUE]
25
25
  [-s [N|HASH] | --squash [N|HASH]]
26
+ [-Q | --stats] [--since YYYY-MM-DD] [--json] [--reset-stats]
27
+ [-q true|false | --sql true|false]
26
28
  [-T SECONDS | --timeout SECONDS]
27
29
  [-t | --time] [-u | --update] [-v | --version]
28
30
  [-x CONTEXT | --context CONTEXT]
@@ -97,12 +99,15 @@ Cannot be combined with `--list`, `--update`, or `--squash`.
97
99
  git cai -a
98
100
  ----
99
101
 
100
- -b, --branch::
102
+ -b, --branch / --no-branch::
101
103
  Include the current Git branch name as context when generating the commit
102
104
  message. The LLM uses the branch name to better understand the intent and
103
105
  scope of the changes (e.g., a branch named `fix/login-timeout` hints at a
104
106
  bug fix related to login timeouts).
105
107
  +
108
+ Use `--no-branch` to explicitly disable branch context for this run when
109
+ the persisted config has it enabled.
110
+ +
106
111
  This flag applies for the current invocation only. To enable it permanently,
107
112
  set `branch_context: true` in `cai_config.yml` or run:
108
113
  +
@@ -113,15 +118,19 @@ git cai -S branch_context=true
113
118
  ----
114
119
  git cai -b
115
120
  git cai -b -c
121
+ git cai --no-branch
116
122
  ----
117
123
 
118
- -C, --conventional::
124
+ -C, --conventional / --no-conventional::
119
125
  Generate the commit message in Conventional Commits format
120
126
  (`type(scope): description`). The LLM is instructed to use one of the
121
127
  following types: `feat`, `fix`, `docs`, `style`, `refactor`, `perf`, `test`,
122
128
  `build`, `ci`, `chore`, `revert`. Append `!` after the type or scope to
123
129
  signal a breaking change.
124
130
  +
131
+ Use `--no-conventional` to explicitly disable Conventional Commits for
132
+ this run when the persisted config has it enabled.
133
+ +
125
134
  This flag applies for the current invocation only. To enable it permanently,
126
135
  set `conventional: true` in `cai_config.yml` or run:
127
136
  +
@@ -132,6 +141,7 @@ git cai -S conventional=true
132
141
  ----
133
142
  git cai -C
134
143
  git cai -C -c
144
+ git cai --no-conventional
135
145
  ----
136
146
 
137
147
  -c, --crazy::
@@ -300,6 +310,83 @@ overwrites.
300
310
  git cai -p
301
311
  ----
302
312
 
313
+ -Q, --stats::
314
+ Show local-only usage analytics: commits and squashes generated, top
315
+ provider, total token counts, average latency, and per-provider rollups.
316
+ Recording is opt-in via the top-level `stats` config key (a plain
317
+ boolean, default `false`), so this view is empty until you turn writing
318
+ on. No diff content, commit messages, or file paths are stored — only
319
+ metadata.
320
+ +
321
+ Combine with `--since YYYY-MM-DD` to scope the view to recent activity, or
322
+ with `--json` to emit machine-readable output. Use `--reset-stats` to
323
+ clear the local SQLite database.
324
+ +
325
+ The DB lives at `$XDG_DATA_HOME/git-cai/stats.db` (default
326
+ `~/.local/share/git-cai/stats.db`). Override with the top-level
327
+ `stats_db_path` config key.
328
+ +
329
+ At the start of every run, git-cai logs whether stats writing is
330
+ enabled and (when enabled) the path of the SQLite database, so users
331
+ always know where their analytics live.
332
+ +
333
+ If the running Python build was compiled without sqlite3, this command
334
+ prints a clear message explaining how to fix it; commit generation
335
+ continues to work normally in that case.
336
+ +
337
+ The `stats` (and `stats_db_path`) keys are the one configuration
338
+ exception that does not follow the strict repo-replaces-home rule:
339
+ when the repo `cai_config.yml` does not mention them, the values are
340
+ taken from the home `~/.config/cai/cai_config.yml`. If neither file
341
+ defines `stats`, the hardcoded default is `false`. Use `git cai -g` to
342
+ write a fresh config that includes the setting so it is visible.
343
+ +
344
+ ----
345
+ git cai --stats
346
+ git cai -Q --since 2026-01-01
347
+ git cai -Q --json
348
+ git cai --reset-stats
349
+ ----
350
+
351
+ --since YYYY-MM-DD::
352
+ Restrict `--stats` (`-Q`) output to events recorded on or after this UTC
353
+ date. Has no effect outside of `--stats`. The date format is strict
354
+ ISO-8601 (e.g. `2026-01-15`).
355
+ +
356
+ ----
357
+ git cai -Q --since 2026-01-01
358
+ ----
359
+
360
+ --json::
361
+ Emit `--stats` (`-Q`) output as a JSON document instead of the text
362
+ summary. Suitable for piping into `jq` or other tooling. Has no effect
363
+ outside of `--stats`.
364
+ +
365
+ ----
366
+ git cai -Q --json
367
+ git cai -Q --json --since 2026-01-01 | jq '.per_provider'
368
+ ----
369
+
370
+ --reset-stats::
371
+ Delete every row from the local stats SQLite DB and exit. Prints the
372
+ number of rows removed. The schema and DB file are preserved (so the
373
+ next opt-in run records into the same file). No-op when the DB does
374
+ not yet exist.
375
+ +
376
+ ----
377
+ git cai --reset-stats
378
+ ----
379
+
380
+ -q, --sql VALUE::
381
+ Per-invocation override for `stats.enabled`. VALUE is `true` or `false`
382
+ (also accepts `yes/no`, `on/off`, `1/0`). Wins over the persisted config
383
+ value. Useful for one-off opt-in or opt-out without editing the config.
384
+ +
385
+ ----
386
+ git cai --sql true # record this commit even when config has stats off
387
+ git cai -q false # don't record this commit even when config has stats on
388
+ ----
389
+
303
390
  -r, --PR::
304
391
  Generate a Pull Request description summarizing the commits between the
305
392
  current branch and its base branch. git-cai collects the commit messages
@@ -683,6 +770,13 @@ Available configuration keys:
683
770
  (default `32768`)
684
771
  - `ollama.timeout` -- HTTP timeout in seconds for Ollama generation calls
685
772
  (default `300`; overrides the global `timeout` for this provider only)
773
+ - `stats` -- opt in to local-only usage analytics (`true`/`false`,
774
+ default `false`). When enabled, every generation appends one row to
775
+ `~/.local/share/git-cai/stats.db` capturing kind, repo name, provider,
776
+ model, token counts, real LLM latency, and a snapshot of the active
777
+ settings (language, style, emoji, temperature, prompt file). No diff
778
+ content, commit messages, or file paths are stored. View the rollup
779
+ with `git cai --stats` (`-Q`).
686
780
 
687
781
  FILES
688
782
  -----
@@ -2,12 +2,12 @@
2
2
  .\" Title: git-cai
3
3
  .\" Author: Thorsten Foltz
4
4
  .\" Generator: Asciidoctor 2.0.26
5
- .\" Date: 2026-04-27
5
+ .\" Date: 2026-05-09
6
6
  .\" Manual: \ \&
7
7
  .\" Source: \ \&
8
8
  .\" Language: English
9
9
  .\"
10
- .TH "GIT\-CAI" "1" "2026-04-27" "\ \&" "\ \&"
10
+ .TH "GIT\-CAI" "1" "2026-05-09" "\ \&" "\ \&"
11
11
  .ie \n(.g .ds Aq \(aq
12
12
  .el .ds Aq '
13
13
  .ss \n[.ss] 0
@@ -34,7 +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
- [\-F | \-\-full\-files] [\-f PATH | \-\-files PATH]
37
+ [\-F | \-\-full\-files | \-\-no\-full\-files] [\-f PATH | \-\-files PATH]
38
38
  [\-g | \-\-generate\-config]
39
39
  [\-H KEY=VALUE | \-\-set\-home KEY=VALUE] [\-h | \-\-help]
40
40
  [\-i | \-\-install\-completion]
@@ -45,6 +45,8 @@ git-cai \- AI\-powered commit message generator
45
45
  [\-r | \-\-PR] [\-\-base BRANCH]
46
46
  [\-S KEY=VALUE | \-\-set KEY=VALUE]
47
47
  [\-s [N|HASH] | \-\-squash [N|HASH]]
48
+ [\-Q | \-\-stats] [\-\-since YYYY\-MM\-DD] [\-\-json] [\-\-reset\-stats]
49
+ [\-q true|false | \-\-sql true|false]
48
50
  [\-T SECONDS | \-\-timeout SECONDS]
49
51
  [\-t | \-\-time] [\-u | \-\-update] [\-v | \-\-version]
50
52
  [\-x CONTEXT | \-\-context CONTEXT]
@@ -225,13 +227,16 @@ git cai \-a
225
227
  .if n .RE
226
228
  .RE
227
229
  .sp
228
- \-b, \-\-branch
230
+ \-b, \-\-branch / \-\-no\-branch
229
231
  .RS 4
230
232
  Include the current Git branch name as context when generating the commit
231
233
  message. The LLM uses the branch name to better understand the intent and
232
234
  scope of the changes (e.g., a branch named \f(CRfix/login\-timeout\fP hints at a
233
235
  bug fix related to login timeouts).
234
236
  .sp
237
+ Use \f(CR\-\-no\-branch\fP to explicitly disable branch context for this run when
238
+ the persisted config has it enabled.
239
+ .sp
235
240
  This flag applies for the current invocation only. To enable it permanently,
236
241
  set \f(CRbranch_context: true\fP in \f(CRcai_config.yml\fP or run:
237
242
  .sp
@@ -248,12 +253,13 @@ git cai \-S branch_context=true
248
253
  .fam C
249
254
  git cai \-b
250
255
  git cai \-b \-c
256
+ git cai \-\-no\-branch
251
257
  .fam
252
258
  .fi
253
259
  .if n .RE
254
260
  .RE
255
261
  .sp
256
- \-C, \-\-conventional
262
+ \-C, \-\-conventional / \-\-no\-conventional
257
263
  .RS 4
258
264
  Generate the commit message in Conventional Commits format
259
265
  (\f(CRtype(scope): description\fP). The LLM is instructed to use one of the
@@ -261,6 +267,9 @@ following types: \f(CRfeat\fP, \f(CRfix\fP, \f(CRdocs\fP, \f(CRstyle\fP, \f(CRre
261
267
  \f(CRbuild\fP, \f(CRci\fP, \f(CRchore\fP, \f(CRrevert\fP. Append \f(CR!\fP after the type or scope to
262
268
  signal a breaking change.
263
269
  .sp
270
+ Use \f(CR\-\-no\-conventional\fP to explicitly disable Conventional Commits for
271
+ this run when the persisted config has it enabled.
272
+ .sp
264
273
  This flag applies for the current invocation only. To enable it permanently,
265
274
  set \f(CRconventional: true\fP in \f(CRcai_config.yml\fP or run:
266
275
  .sp
@@ -277,6 +286,7 @@ git cai \-S conventional=true
277
286
  .fam C
278
287
  git cai \-C
279
288
  git cai \-C \-c
289
+ git cai \-\-no\-conventional
280
290
  .fam
281
291
  .fi
282
292
  .if n .RE
@@ -524,6 +534,113 @@ git cai \-p
524
534
  .if n .RE
525
535
  .RE
526
536
  .sp
537
+ \-Q, \-\-stats
538
+ .RS 4
539
+ Show local\-only usage analytics: commits and squashes generated, top
540
+ provider, total token counts, average latency, and per\-provider rollups.
541
+ Recording is opt\-in via the top\-level \f(CRstats\fP config key (a plain
542
+ boolean, default \f(CRfalse\fP), so this view is empty until you turn writing
543
+ on. No diff content, commit messages, or file paths are stored — only
544
+ metadata.
545
+ .sp
546
+ Combine with \f(CR\-\-since YYYY\-MM\-DD\fP to scope the view to recent activity, or
547
+ with \f(CR\-\-json\fP to emit machine\-readable output. Use \f(CR\-\-reset\-stats\fP to
548
+ clear the local SQLite database.
549
+ .sp
550
+ The DB lives at \f(CR$XDG_DATA_HOME/git\-cai/stats.db\fP (default
551
+ \f(CR~/.local/share/git\-cai/stats.db\fP). Override with the top\-level
552
+ \f(CRstats_db_path\fP config key.
553
+ .sp
554
+ At the start of every run, git\-cai logs whether stats writing is
555
+ enabled and (when enabled) the path of the SQLite database, so users
556
+ always know where their analytics live.
557
+ .sp
558
+ If the running Python build was compiled without sqlite3, this command
559
+ prints a clear message explaining how to fix it; commit generation
560
+ continues to work normally in that case.
561
+ .sp
562
+ The \f(CRstats\fP (and \f(CRstats_db_path\fP) keys are the one configuration
563
+ exception that does not follow the strict repo\-replaces\-home rule:
564
+ when the repo \f(CRcai_config.yml\fP does not mention them, the values are
565
+ taken from the home \f(CR~/.config/cai/cai_config.yml\fP. If neither file
566
+ defines \f(CRstats\fP, the hardcoded default is \f(CRfalse\fP. Use \f(CRgit cai \-g\fP to
567
+ write a fresh config that includes the setting so it is visible.
568
+ .sp
569
+ .if n .RS 4
570
+ .nf
571
+ .fam C
572
+ git cai \-\-stats
573
+ git cai \-Q \-\-since 2026\-01\-01
574
+ git cai \-Q \-\-json
575
+ git cai \-\-reset\-stats
576
+ .fam
577
+ .fi
578
+ .if n .RE
579
+ .RE
580
+ .sp
581
+ \-\-since YYYY\-MM\-DD
582
+ .RS 4
583
+ Restrict \f(CR\-\-stats\fP (\f(CR\-Q\fP) output to events recorded on or after this UTC
584
+ date. Has no effect outside of \f(CR\-\-stats\fP. The date format is strict
585
+ ISO\-8601 (e.g. \f(CR2026\-01\-15\fP).
586
+ .sp
587
+ .if n .RS 4
588
+ .nf
589
+ .fam C
590
+ git cai \-Q \-\-since 2026\-01\-01
591
+ .fam
592
+ .fi
593
+ .if n .RE
594
+ .RE
595
+ .sp
596
+ \-\-json
597
+ .RS 4
598
+ Emit \f(CR\-\-stats\fP (\f(CR\-Q\fP) output as a JSON document instead of the text
599
+ summary. Suitable for piping into \f(CRjq\fP or other tooling. Has no effect
600
+ outside of \f(CR\-\-stats\fP.
601
+ .sp
602
+ .if n .RS 4
603
+ .nf
604
+ .fam C
605
+ git cai \-Q \-\-json
606
+ git cai \-Q \-\-json \-\-since 2026\-01\-01 | jq \*(Aq.per_provider\*(Aq
607
+ .fam
608
+ .fi
609
+ .if n .RE
610
+ .RE
611
+ .sp
612
+ \-\-reset\-stats
613
+ .RS 4
614
+ Delete every row from the local stats SQLite DB and exit. Prints the
615
+ number of rows removed. The schema and DB file are preserved (so the
616
+ next opt\-in run records into the same file). No\-op when the DB does
617
+ not yet exist.
618
+ .sp
619
+ .if n .RS 4
620
+ .nf
621
+ .fam C
622
+ git cai \-\-reset\-stats
623
+ .fam
624
+ .fi
625
+ .if n .RE
626
+ .RE
627
+ .sp
628
+ \-q, \-\-sql VALUE
629
+ .RS 4
630
+ Per\-invocation override for \f(CRstats.enabled\fP. VALUE is \f(CRtrue\fP or \f(CRfalse\fP
631
+ (also accepts \f(CRyes/no\fP, \f(CRon/off\fP, \f(CR1/0\fP). Wins over the persisted config
632
+ value. Useful for one\-off opt\-in or opt\-out without editing the config.
633
+ .sp
634
+ .if n .RS 4
635
+ .nf
636
+ .fam C
637
+ git cai \-\-sql true\& # record this commit even when config has stats off
638
+ git cai \-q false\& # don\*(Aqt record this commit even when config has stats on
639
+ .fam
640
+ .fi
641
+ .if n .RE
642
+ .RE
643
+ .sp
527
644
  \-r, \-\-PR
528
645
  .RS 4
529
646
  Generate a Pull Request description summarizing the commits between the
@@ -1265,6 +1382,23 @@ built\-in fallback.
1265
1382
  \f(CRollama.timeout\fP \(em HTTP timeout in seconds for Ollama generation calls
1266
1383
  (default \f(CR300\fP; overrides the global \f(CRtimeout\fP for this provider only)
1267
1384
  .RE
1385
+ .sp
1386
+ .RS 4
1387
+ .ie n \{\
1388
+ \h'-04'\(bu\h'+03'\c
1389
+ .\}
1390
+ .el \{\
1391
+ . sp -1
1392
+ . IP \(bu 2.3
1393
+ .\}
1394
+ \f(CRstats\fP \(em opt in to local\-only usage analytics (\f(CRtrue\fP/\f(CRfalse\fP,
1395
+ default \f(CRfalse\fP). When enabled, every generation appends one row to
1396
+ \f(CR~/.local/share/git\-cai/stats.db\fP capturing kind, repo name, provider,
1397
+ model, token counts, real LLM latency, and a snapshot of the active
1398
+ settings (language, style, emoji, temperature, prompt file). No diff
1399
+ content, commit messages, or file paths are stored. View the rollup
1400
+ with \f(CRgit cai \-\-stats\fP (\f(CR\-Q\fP).
1401
+ .RE
1268
1402
  .SH "FILES"
1269
1403
  .sp
1270
1404
  \f(CR~/.config/cai/cai_config.yml\fP
@@ -11,6 +11,7 @@ dependencies = [
11
11
  "openai>=2.30.0",
12
12
  "typer>=0.23.1",
13
13
  "requests>=2.33.0",
14
+ "pathspec>=0.12.1",
14
15
  ]
15
16
  license = "MIT"
16
17
  classifiers = [
@@ -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.13.1'
22
- __version_tuple__ = version_tuple = (0, 13, 1)
21
+ __version__ = version = '0.13.2'
22
+ __version_tuple__ = version_tuple = (0, 13, 2)
23
23
 
24
- __commit_id__ = commit_id = 'gab0a91cf3'
24
+ __commit_id__ = commit_id = 'g89441925e'