git-cai-cli 0.1.0__tar.gz → 0.1.dev1__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 (118) hide show
  1. git_cai_cli-0.1.dev1/.caiignore +1 -0
  2. git_cai_cli-0.1.dev1/.gitattributes +51 -0
  3. git_cai_cli-0.1.dev1/.github/cd/.SRCINFO +22 -0
  4. git_cai_cli-0.1.dev1/.github/cd/PKGBUILD +39 -0
  5. git_cai_cli-0.1.dev1/.github/ci/_version.py +6 -0
  6. git_cai_cli-0.1.dev1/.github/ci/cai_config.ci.yml +33 -0
  7. git_cai_cli-0.1.dev1/.github/ci/tokens.ci.yml +7 -0
  8. git_cai_cli-0.1.dev1/.github/workflows/python-tests.yml +117 -0
  9. git_cai_cli-0.1.dev1/.github/workflows/release.yml +57 -0
  10. git_cai_cli-0.1.dev1/.github/workflows/release_aur.yml +130 -0
  11. {git_cai_cli-0.1.0 → git_cai_cli-0.1.dev1}/.gitignore +12 -1
  12. {git_cai_cli-0.1.0 → git_cai_cli-0.1.dev1}/.linters/.bandit.yml +1 -1
  13. git_cai_cli-0.1.dev1/.linters/.checkov.yml +2 -0
  14. {git_cai_cli-0.1.0 → git_cai_cli-0.1.dev1}/.linters/.flake8 +1 -1
  15. {git_cai_cli-0.1.0 → git_cai_cli-0.1.dev1}/.linters/.proselintrc +3 -3
  16. {git_cai_cli-0.1.0 → git_cai_cli-0.1.dev1}/.linters/.pylintrc +16 -13
  17. {git_cai_cli-0.1.0 → git_cai_cli-0.1.dev1}/.linters/lychee.toml +1 -0
  18. git_cai_cli-0.1.dev1/.markdownlintignore +2 -0
  19. {git_cai_cli-0.1.0 → git_cai_cli-0.1.dev1}/.mega-linter.yml +3 -1
  20. git_cai_cli-0.1.dev1/.semgrepignore +6 -0
  21. git_cai_cli-0.1.dev1/.trivyignore +8 -0
  22. git_cai_cli-0.1.dev1/CLAUDE.md +75 -0
  23. {git_cai_cli-0.1.0 → git_cai_cli-0.1.dev1}/Makefile +7 -3
  24. git_cai_cli-0.1.dev1/PKG-INFO +523 -0
  25. git_cai_cli-0.1.dev1/README.md +493 -0
  26. git_cai_cli-0.1.dev1/cai_config.yml +44 -0
  27. git_cai_cli-0.1.dev1/docs/git-cai.txt +1178 -0
  28. git_cai_cli-0.1.dev1/docs/man/git-cai.1 +2021 -0
  29. {git_cai_cli-0.1.0 → git_cai_cli-0.1.dev1}/pyproject.toml +20 -7
  30. git_cai_cli-0.1.dev1/src/git_cai_cli/__init__.py +5 -0
  31. git_cai_cli-0.1.dev1/src/git_cai_cli/_version.py +24 -0
  32. git_cai_cli-0.1.dev1/src/git_cai_cli/cli/cli.py +371 -0
  33. git_cai_cli-0.1.dev1/src/git_cai_cli/cli/helptext.py +75 -0
  34. git_cai_cli-0.1.dev1/src/git_cai_cli/cli/modes.py +145 -0
  35. git_cai_cli-0.1.dev1/src/git_cai_cli/core/completion.py +250 -0
  36. git_cai_cli-0.1.dev1/src/git_cai_cli/core/config.py +714 -0
  37. git_cai_cli-0.1.dev1/src/git_cai_cli/core/doctor.py +195 -0
  38. git_cai_cli-0.1.dev1/src/git_cai_cli/core/editors.py +23 -0
  39. git_cai_cli-0.1.dev1/src/git_cai_cli/core/gitutils.py +547 -0
  40. git_cai_cli-0.1.dev1/src/git_cai_cli/core/init.py +206 -0
  41. git_cai_cli-0.1.dev1/src/git_cai_cli/core/languages.py +120 -0
  42. git_cai_cli-0.1.dev1/src/git_cai_cli/core/llm.py +1315 -0
  43. git_cai_cli-0.1.dev1/src/git_cai_cli/core/options.py +459 -0
  44. git_cai_cli-0.1.dev1/src/git_cai_cli/core/pr.py +187 -0
  45. git_cai_cli-0.1.dev1/src/git_cai_cli/core/prompts_fallback.py +172 -0
  46. git_cai_cli-0.1.dev1/src/git_cai_cli/core/secrets.py +160 -0
  47. git_cai_cli-0.1.dev1/src/git_cai_cli/core/spinner.py +130 -0
  48. git_cai_cli-0.1.dev1/src/git_cai_cli/core/squash.py +490 -0
  49. git_cai_cli-0.1.dev1/src/git_cai_cli/core/stats.py +419 -0
  50. git_cai_cli-0.1.dev1/src/git_cai_cli/core/validate.py +350 -0
  51. git_cai_cli-0.1.dev1/src/git_cai_cli/main.py +332 -0
  52. git_cai_cli-0.1.dev1/src/git_cai_cli.egg-info/PKG-INFO +523 -0
  53. git_cai_cli-0.1.dev1/src/git_cai_cli.egg-info/SOURCES.txt +99 -0
  54. git_cai_cli-0.1.dev1/src/git_cai_cli.egg-info/entry_points.txt +2 -0
  55. git_cai_cli-0.1.dev1/src/git_cai_cli.egg-info/requires.txt +5 -0
  56. {git_cai_cli-0.1.0 → git_cai_cli-0.1.dev1}/src/git_cai_cli.egg-info/top_level.txt +0 -1
  57. git_cai_cli-0.1.dev1/tests/conftest.py +9 -0
  58. git_cai_cli-0.1.dev1/tests/integration/test_cli_integration.py +102 -0
  59. git_cai_cli-0.1.dev1/tests/integration/test_config_integration.py +73 -0
  60. git_cai_cli-0.1.dev1/tests/integration/test_gitutils_integration.py +70 -0
  61. git_cai_cli-0.1.dev1/tests/integration/test_modes_integration.py +219 -0
  62. git_cai_cli-0.1.dev1/tests/integration/test_options_integration.py +65 -0
  63. git_cai_cli-0.1.dev1/tests/integration/test_pr_integration.py +139 -0
  64. git_cai_cli-0.1.dev1/tests/integration/test_squash_integration.py +53 -0
  65. git_cai_cli-0.1.dev1/tests/unit/test_amend.py +178 -0
  66. git_cai_cli-0.1.dev1/tests/unit/test_branch_context.py +90 -0
  67. git_cai_cli-0.1.dev1/tests/unit/test_classification.py +81 -0
  68. git_cai_cli-0.1.dev1/tests/unit/test_cli.py +567 -0
  69. git_cai_cli-0.1.dev1/tests/unit/test_completion.py +289 -0
  70. git_cai_cli-0.1.dev1/tests/unit/test_config.py +875 -0
  71. git_cai_cli-0.1.dev1/tests/unit/test_conventional.py +74 -0
  72. git_cai_cli-0.1.dev1/tests/unit/test_doctor.py +117 -0
  73. git_cai_cli-0.1.dev1/tests/unit/test_gitutils.py +600 -0
  74. git_cai_cli-0.1.dev1/tests/unit/test_helptext.py +13 -0
  75. git_cai_cli-0.1.dev1/tests/unit/test_init.py +199 -0
  76. git_cai_cli-0.1.dev1/tests/unit/test_llm.py +1343 -0
  77. git_cai_cli-0.1.dev1/tests/unit/test_main.py +135 -0
  78. git_cai_cli-0.1.dev1/tests/unit/test_modes.py +369 -0
  79. git_cai_cli-0.1.dev1/tests/unit/test_options.py +494 -0
  80. git_cai_cli-0.1.dev1/tests/unit/test_pr.py +345 -0
  81. git_cai_cli-0.1.dev1/tests/unit/test_print.py +80 -0
  82. git_cai_cli-0.1.dev1/tests/unit/test_prompt_loading.py +1000 -0
  83. git_cai_cli-0.1.dev1/tests/unit/test_secrets.py +120 -0
  84. git_cai_cli-0.1.dev1/tests/unit/test_set_config.py +176 -0
  85. git_cai_cli-0.1.dev1/tests/unit/test_signoff.py +134 -0
  86. git_cai_cli-0.1.dev1/tests/unit/test_spinner.py +251 -0
  87. git_cai_cli-0.1.dev1/tests/unit/test_squash.py +635 -0
  88. git_cai_cli-0.1.dev1/tests/unit/test_stats.py +705 -0
  89. git_cai_cli-0.1.dev1/tests/unit/test_validate.py +675 -0
  90. git_cai_cli-0.1.dev1/uv.lock +1195 -0
  91. git_cai_cli-0.1.0/.caiignore +0 -5
  92. git_cai_cli-0.1.0/.linters/.checkov.yml +0 -2
  93. git_cai_cli-0.1.0/.semgrepignore +0 -1
  94. git_cai_cli-0.1.0/.trivyignore +0 -2
  95. git_cai_cli-0.1.0/PKG-INFO +0 -104
  96. git_cai_cli-0.1.0/PKGBUILD +0 -36
  97. git_cai_cli-0.1.0/README.md +0 -77
  98. git_cai_cli-0.1.0/src/git_cai_cli/cli.py +0 -61
  99. git_cai_cli-0.1.0/src/git_cai_cli/core/config.py +0 -146
  100. git_cai_cli-0.1.0/src/git_cai_cli/core/gitutils.py +0 -57
  101. git_cai_cli-0.1.0/src/git_cai_cli/core/llm.py +0 -97
  102. git_cai_cli-0.1.0/src/git_cai_cli.egg-info/PKG-INFO +0 -104
  103. git_cai_cli-0.1.0/src/git_cai_cli.egg-info/SOURCES.txt +0 -36
  104. git_cai_cli-0.1.0/src/git_cai_cli.egg-info/entry_points.txt +0 -2
  105. git_cai_cli-0.1.0/src/git_cai_cli.egg-info/requires.txt +0 -3
  106. git_cai_cli-0.1.0/src/tests/test_core/test_config.py +0 -128
  107. git_cai_cli-0.1.0/uv.lock +0 -740
  108. {git_cai_cli-0.1.0 → git_cai_cli-0.1.dev1}/.linters/.ls-lint.yml +0 -0
  109. {git_cai_cli-0.1.0 → git_cai_cli-0.1.dev1}/.linters/.markdown-link-check.json +0 -0
  110. {git_cai_cli-0.1.0 → git_cai_cli-0.1.dev1}/.linters/.markdownlint.json +0 -0
  111. {git_cai_cli-0.1.0 → git_cai_cli-0.1.dev1}/.linters/.yamllint.yml +0 -0
  112. {git_cai_cli-0.1.0 → git_cai_cli-0.1.dev1}/.linters/check_git_branch_name.sh +0 -0
  113. {git_cai_cli-0.1.0 → git_cai_cli-0.1.dev1}/.linters/pyrightconfig.json +0 -0
  114. {git_cai_cli-0.1.0 → git_cai_cli-0.1.dev1}/LICENSE +0 -0
  115. {git_cai_cli-0.1.0 → git_cai_cli-0.1.dev1}/setup.cfg +0 -0
  116. {git_cai_cli-0.1.0/src/git_cai_cli → git_cai_cli-0.1.dev1/src/git_cai_cli/cli}/__init__.py +0 -0
  117. {git_cai_cli-0.1.0 → git_cai_cli-0.1.dev1}/src/git_cai_cli/core/__init__.py +0 -0
  118. {git_cai_cli-0.1.0 → git_cai_cli-0.1.dev1}/src/git_cai_cli.egg-info/dependency_links.txt +0 -0
@@ -0,0 +1 @@
1
+ tests/unit/test_secrets.py
@@ -0,0 +1,51 @@
1
+ ###############################################################################
2
+ # Global defaults
3
+ ###############################################################################
4
+
5
+ # Automatically detect text files and normalize line endings
6
+ * text=auto
7
+
8
+ ###############################################################################
9
+ # Enforce Linux (LF) line endings for known text formats
10
+ ###############################################################################
11
+
12
+ # YAML
13
+ *.yml text eol=lf
14
+ *.yaml text eol=lf
15
+
16
+ # Shell scripts
17
+ *.sh text eol=lf
18
+
19
+ # Python
20
+ *.py text eol=lf
21
+
22
+ # Makefiles
23
+ Makefile text eol=lf
24
+ makefile text eol=lf
25
+ *.mk text eol=lf
26
+
27
+ # Plain text
28
+ *.txt text eol=lf
29
+ *.md text eol=lf
30
+ *.rst text eol=lf
31
+
32
+ ###############################################################################
33
+ # Git configuration and metadata files
34
+ ###############################################################################
35
+
36
+ .gitattributes text eol=lf
37
+ .gitignore text eol=lf
38
+ .gitmodules text eol=lf
39
+
40
+ ###############################################################################
41
+ # Binary files (never attempt to diff or normalize)
42
+ ###############################################################################
43
+
44
+ *.png binary
45
+ *.jpg binary
46
+ *.jpeg binary
47
+ *.gif binary
48
+ *.pdf binary
49
+ *.zip binary
50
+ *.tar binary
51
+ *.gz binary
@@ -0,0 +1,22 @@
1
+ pkgbase = cai
2
+ pkgdesc = CLI tool that generates concise git commit messages from diffs or commit history using large language models
3
+ pkgver = Y.Y.Y
4
+ pkgrel = 1
5
+ url = https://github.com/thorstenfoltz/cai
6
+ arch = any
7
+ license = MIT
8
+ makedepends = python-build
9
+ makedepends = python-installer
10
+ makedepends = python-setuptools
11
+ makedepends = python-wheel
12
+ makedepends = python-setuptools-scm
13
+ depends = python
14
+ depends = python-yaml
15
+ depends = python-openai
16
+ depends = python-requests
17
+ depends = python-typer
18
+ depends = git
19
+ source = cai-Y.Y.Y.tar.gz::https://github.com/thorstenfoltz/cai/archive/refs/tags/Y.Y.Y.tar.gz
20
+ sha256sums = YYYYYY
21
+
22
+ pkgname = cai
@@ -0,0 +1,39 @@
1
+ # Maintainer: Thorsten Foltz <thorsten.foltz@live.com>
2
+ # Contributor: Thorsten Foltz <thorsten.foltz@live.com>
3
+ pkgname=cai
4
+ pkgver=X.X.X
5
+ pkgrel=1
6
+ pkgdesc="CLI tool that generates concise git commit messages from diffs or commit history using large language models"
7
+ arch=('any')
8
+ url="https://github.com/thorstenfoltz/cai"
9
+ license=('MIT')
10
+ depends=(
11
+ python
12
+ python-yaml
13
+ python-openai
14
+ python-requests
15
+ python-typer
16
+ git
17
+ )
18
+ makedepends=(
19
+ python-build
20
+ python-installer
21
+ python-setuptools
22
+ python-wheel
23
+ python-setuptools-scm
24
+ )
25
+ source=(
26
+ "$pkgname-$pkgver.tar.gz::https://github.com/thorstenfoltz/cai/archive/refs/tags/$pkgver.tar.gz"
27
+ )
28
+ sha256sums=(
29
+ 'XXX'
30
+ )
31
+ build() {
32
+ cd "$srcdir/cai-$pkgver"
33
+ export SETUPTOOLS_SCM_PRETEND_VERSION_FOR_GIT_CAI_CLI="$pkgver"
34
+ python -m build --wheel --no-isolation
35
+ }
36
+ package() {
37
+ cd "$srcdir/cai-$pkgver"
38
+ python -m installer --destdir="$pkgdir" dist/*.whl
39
+ }
@@ -0,0 +1,6 @@
1
+ """
2
+ Dummy for CI to copy the version file here.
3
+ Pylint will otherwise complain about missing module.
4
+ """
5
+
6
+ __version__ = "0.0.0"
@@ -0,0 +1,33 @@
1
+ default: groq
2
+ language: en
3
+ style: professional
4
+ emoji: false
5
+ load_tokens_from: /home/runner/work/.config/cai/tokens.yml
6
+ timeout: 30
7
+ full_files: false
8
+ anthropic:
9
+ model: claude-haiku-4-5
10
+ temperature: 0
11
+ max_tokens: 32768
12
+ deepseek:
13
+ model: deepseek-chat
14
+ temperature: 0
15
+ gemini:
16
+ model: gemini-2.5-flash
17
+ temperature: 0
18
+ groq:
19
+ model: moonshotai/kimi-k2-instruct
20
+ temperature: 0
21
+ mistral:
22
+ model: codestral-2508
23
+ temperature: 0
24
+ ollama:
25
+ model: llama3.1
26
+ temperature: 0
27
+ timeout: 300
28
+ openai:
29
+ model: gpt-5.1
30
+ temperature: 0
31
+ xai:
32
+ model: grok-4-1-fast-reasoning
33
+ temperature: 0
@@ -0,0 +1,7 @@
1
+ gemini: DUMMY_API_KEY_FOR_TESTING_PURPOSES
2
+ openai: sk-proj-DUMMY_API_KEY_FOR_TESTING_PURPOSES
3
+ anthropic: sk-ant-api03-DUMMY_API_KEY_FOR_TESTING_PURPOSES
4
+ groq: DUMMY_API_KEY_FOR_TESTING_PURPOSES
5
+ xai: DUMMY_API_KEY_FOR_TESTING_PURPOSES
6
+ mistral: DUMMY_API_KEY_FOR_TESTING_PURPOSES
7
+ deepseek: DUMMY_API_KEY_FOR_TESTING_PURPOSES
@@ -0,0 +1,117 @@
1
+ name: Tests-and-Linters
2
+
3
+ permissions:
4
+ contents: read
5
+
6
+ on:
7
+ pull_request:
8
+ branches:
9
+ - master
10
+
11
+ jobs:
12
+ check-branch-name:
13
+ name: Check git branch name
14
+ runs-on: ubuntu-slim
15
+
16
+ steps:
17
+ - name: Checkout code
18
+ uses: actions/checkout@v4
19
+ with:
20
+ ref: ${{ github.head_ref }}
21
+
22
+ - name: Make script executable
23
+ run: chmod +x .linters/check_git_branch_name.sh
24
+
25
+ - name: Run branch name check
26
+ run: .linters/check_git_branch_name.sh
27
+
28
+ test:
29
+ needs: check-branch-name
30
+ runs-on: ubuntu-slim
31
+
32
+ strategy:
33
+ fail-fast: false
34
+ matrix:
35
+ python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
36
+
37
+ steps:
38
+ - uses: actions/checkout@v4
39
+
40
+ - name: Set up Python ${{ matrix.python-version }}
41
+ uses: actions/setup-python@v4
42
+ with:
43
+ python-version: ${{ matrix.python-version }}
44
+
45
+ - name: Install uv
46
+ uses: astral-sh/setup-uv@681c641aba71e4a1c380be3ab5e12ad51f415867
47
+
48
+ - name: Create virtual environment
49
+ run: uv venv
50
+
51
+ - name: Restore cache uv
52
+ uses: actions/cache@v4
53
+ with:
54
+ path: |
55
+ ~/.cache/uv
56
+ .venv
57
+ key: uv-${{ runner.os }}-${{ matrix.python-version }}-${{ hashFiles('**/pyproject.toml') }}
58
+ restore-keys: |
59
+ uv-${{ runner.os }}-${{ matrix.python-version }}-
60
+
61
+ - name: Install dependencies
62
+ run: |
63
+ uv sync --dev
64
+
65
+ - name: Create CAI config and tokens
66
+ run: |
67
+ mkdir -p /home/runner/.config/cai /home/runner/work/.config/cai
68
+
69
+ cp .github/ci/cai_config.ci.yml /home/runner/.config/cai/cai_config.yml
70
+ cp .github/ci/cai_config.ci.yml /home/runner/work/.config/cai/cai_config.yml
71
+
72
+ cp .github/ci/tokens.ci.yml /home/runner/.config/cai/tokens.yml
73
+ cp .github/ci/tokens.ci.yml /home/runner/work/.config/cai/tokens.yml
74
+
75
+ - name: Run tests
76
+ run: |
77
+ uv run pytest
78
+
79
+ megalinter:
80
+ name: MegaLinter
81
+ needs: test
82
+ runs-on: ubuntu-latest
83
+
84
+ permissions:
85
+ contents: write
86
+ issues: write
87
+ pull-requests: write
88
+
89
+ steps:
90
+ # Git Checkout
91
+ - name: Checkout Code
92
+ uses: actions/checkout@v6
93
+ with:
94
+ token: ${{ secrets.PAT || secrets.GITHUB_TOKEN }}
95
+ fetch-depth: 0
96
+
97
+ - name: Generate version file
98
+ run: cp .github/ci/_version.py "$GITHUB_WORKSPACE/src/git_cai_cli/_version.py"
99
+
100
+ # MegaLinter
101
+ - name: MegaLinter
102
+ uses: oxsecurity/megalinter@42bb470545e359597e7f12156947c436e4e3fb9a
103
+ id: ml
104
+ env:
105
+ VALIDATE_ALL_CODEBASE: false
106
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
107
+
108
+ # Upload MegaLinter artifacts
109
+ - name: Archive production artifacts
110
+ if: success() || failure()
111
+ uses: actions/upload-artifact@v4
112
+ with:
113
+ name: MegaLinter reports
114
+ include-hidden-files: "true"
115
+ path: |
116
+ megalinter-reports
117
+ mega-linter.log
@@ -0,0 +1,57 @@
1
+ name: Release to PyPI
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ permissions:
8
+ contents: read
9
+ id-token: write
10
+
11
+ jobs:
12
+ pypi-release:
13
+ runs-on: ubuntu-latest
14
+
15
+ environment:
16
+ name: pypi
17
+ url: https://pypi.org/project/git-cai-cli/
18
+
19
+ steps:
20
+ - name: Checkout tagged commit
21
+ uses: actions/checkout@v4
22
+ with:
23
+ ref: ${{ github.ref }}
24
+
25
+ - name: Set up Python
26
+ uses: actions/setup-python@v5
27
+ with:
28
+ python-version: "3.13"
29
+
30
+ - name: Install uv
31
+ uses: astral-sh/setup-uv@681c641aba71e4a1c380be3ab5e12ad51f415867
32
+
33
+ - name: Create virtual environment
34
+ run: uv venv
35
+
36
+ - name: Restore uv cache
37
+ uses: actions/cache@v4
38
+ with:
39
+ path: |
40
+ ~/.cache/uv
41
+ .venv
42
+ key: uv-${{ runner.os }}-release-${{ hashFiles('**/pyproject.toml') }}
43
+ restore-keys: |
44
+ uv-${{ runner.os }}-release-
45
+
46
+ - name: Install dependencies (including dev)
47
+ run: uv sync --dev
48
+
49
+ - name: Build distributions
50
+ run: |
51
+ source .venv/bin/activate
52
+ python -m build
53
+
54
+ - name: Publish to PyPI (Trusted Publishing)
55
+ uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e
56
+ with:
57
+ packages-dir: dist/
@@ -0,0 +1,130 @@
1
+ name: Publish to AUR
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+ workflow_dispatch:
7
+ inputs:
8
+ version:
9
+ description: "Release version (e.g. 0.6.5)"
10
+ required: true
11
+
12
+ jobs:
13
+ aur:
14
+ runs-on: ubuntu-slim
15
+ environment:
16
+ name: aur
17
+
18
+ steps:
19
+ - name: Checkout repository
20
+ uses: actions/checkout@v4
21
+
22
+ - name: Install tools
23
+ run: |
24
+ sudo apt-get update
25
+ sudo apt-get install -y git curl openssh-client
26
+
27
+ - name: Determine release version
28
+ id: version
29
+ run: |
30
+ if [ -n "${{ github.event.inputs.version }}" ]; then
31
+ VERSION="${{ github.event.inputs.version }}"
32
+ else
33
+ TAG="${GITHUB_REF_NAME}"
34
+ VERSION="${TAG#v}"
35
+ fi
36
+ echo "version=$VERSION" >> "$GITHUB_OUTPUT"
37
+
38
+ - name: Download release tarball
39
+ run: |
40
+ VERSION="${{ steps.version.outputs.version }}"
41
+
42
+ if [ "${{ github.event_name }}" = "release" ]; then
43
+ TAG="${GITHUB_REF_NAME}"
44
+ else
45
+ TAG="${VERSION}"
46
+ fi
47
+
48
+ echo "Downloading tag: ${TAG}"
49
+
50
+ curl -fL \
51
+ -o cai-${VERSION}.tar.gz \
52
+ https://github.com/thorstenfoltz/cai/archive/refs/tags/${TAG}.tar.gz
53
+
54
+ - name: Compute sha256sum
55
+ id: sha
56
+ run: |
57
+ SHA256=$(sha256sum cai-${{ steps.version.outputs.version }}.tar.gz | awk '{print $1}')
58
+ echo "sha256=$SHA256" >> "$GITHUB_OUTPUT"
59
+
60
+ - name: Configure SSH for AUR (RSA)
61
+ run: |
62
+ mkdir -p ~/.ssh
63
+ echo "${{ secrets.AUR_SSH_PRIVATE_KEY }}" > ~/.ssh/aur
64
+ chmod 600 ~/.ssh/aur
65
+
66
+ cat >> ~/.ssh/config <<'EOF'
67
+ Host aur.archlinux.org
68
+ IdentityFile ~/.ssh/aur
69
+ User aur
70
+ EOF
71
+
72
+ ssh-keyscan aur.archlinux.org >> ~/.ssh/known_hosts
73
+
74
+ - name: Clone AUR repository (master branch)
75
+ run: |
76
+ git -c init.defaultBranch=master clone \
77
+ ssh://aur@aur.archlinux.org/cai.git aur
78
+
79
+ - name: Copy PKGBUILD and .SRCINFO
80
+ run: |
81
+ cp .github/cd/PKGBUILD aur/PKGBUILD
82
+ cp .github/cd/.SRCINFO aur/.SRCINFO
83
+
84
+ - name: Update PKGBUILD and .SRCINFO
85
+ run: |
86
+ cd aur
87
+
88
+ VERSION="${{ steps.version.outputs.version }}"
89
+ SHA="${{ steps.sha.outputs.sha256 }}"
90
+
91
+ # PKGBUILD
92
+ sed -i \
93
+ -e "s/^pkgver=.*/pkgver=${VERSION}/" \
94
+ -e "/^sha256sums=/,/^)/c\sha256sums=(\n '${SHA}'\n)" \
95
+ PKGBUILD
96
+
97
+ # .SRCINFO
98
+ sed -i \
99
+ -e "s/^\tpkgver = .*/\tpkgver = ${VERSION}/" \
100
+ -e "s|^\tsource = .*|\tsource = cai-${VERSION}.tar.gz::https://github.com/thorstenfoltz/cai/archive/refs/tags/${VERSION}.tar.gz|" \
101
+ -e "s/^\tsha256sums = .*/\tsha256sums = ${SHA}/" \
102
+ .SRCINFO
103
+
104
+ - name: Show updated files
105
+ run: |
106
+ cd aur
107
+ cat PKGBUILD
108
+ echo "-----"
109
+ cat .SRCINFO
110
+
111
+ - name: Verify PKGBUILD and .SRCINFO have changed
112
+ run: |
113
+ set -euo pipefail
114
+
115
+ cd aur
116
+
117
+ STATUS="$(git status --porcelain)"
118
+
119
+ echo "$STATUS" | grep -q '^.*PKGBUILD$'
120
+ echo "$STATUS" | grep -q '^.*\.SRCINFO$'
121
+
122
+ - name: Commit and push
123
+ run: |
124
+ cd aur
125
+ git config user.name "GitHub Actions"
126
+ git config user.email "actions@github.com"
127
+
128
+ git add PKGBUILD .SRCINFO
129
+ git commit -m "release ${{ steps.version.outputs.version }}"
130
+ git push
@@ -1,13 +1,24 @@
1
1
  # directories
2
2
  build/
3
+ .claude/
3
4
  dist/
4
5
  src/git_cai_cli.egg-info/
5
6
  .ipynb_checkpoints/
6
7
  megalinter-reports/
7
8
  __pycache__/
8
9
  .ruff_cache/
10
+ .pytest_cache/
11
+ .mypy_cache/
9
12
  .venv/
10
13
 
11
14
  # files
12
15
 
13
- *.ipynb
16
+ *.ipynb
17
+ _version.py
18
+ *.log
19
+ *.tar.gz
20
+ *.zip
21
+ *.tar.zst
22
+
23
+ # exceptions
24
+ !.github/ci/_version.py
@@ -1,4 +1,4 @@
1
1
  # FILE: bandit.yml
2
2
  exclude_dirs: ["venv", "megalinter-reports", "tests"]
3
3
  #tests: ['B201', 'B301']
4
- skips: ["B404", "B603", "B607"]
4
+ skips: ["B404", "B603", "B607", "B608"]
@@ -0,0 +1,2 @@
1
+ skip-path:
2
+ - /.github/workflows/
@@ -1,5 +1,5 @@
1
1
  [flake8]
2
- #extend-ignore = E501, F821
2
+ extend-ignore = E203
3
3
  exclude =
4
4
  test_copy_files_fsb.py,
5
5
  __pycache__
@@ -18,7 +18,7 @@
18
18
  , "lgbtq.offensive_terms": true
19
19
  , "lgbtq.terms": true
20
20
  , "lexical_illusions.misc": false
21
- , "links.broken": true
21
+ , "links.broken": false
22
22
  , "malapropisms.misc": true
23
23
  , "misc.apologizing": true
24
24
  , "misc.back_formations": true
@@ -48,7 +48,7 @@
48
48
  , "misc.whence": true
49
49
  , "mixed_metaphors.misc": true
50
50
  , "mondegreens.misc": true
51
- , "needless_variants.misc": true
51
+ , "needless_variants.misc": false
52
52
  , "nonwords.misc": true
53
53
  , "oxymorons.misc": true
54
54
  , "psychology.misc": true
@@ -73,6 +73,6 @@
73
73
  , "typography.symbols": false
74
74
  , "uncomparables.misc": true
75
75
  , "weasel_words.misc": true
76
- , "weasel_words.very": true
76
+ , "weasel_words.very": false
77
77
  }
78
78
  }
@@ -4,12 +4,12 @@ analyse-fallback-blocks=no # Don’t analyze import fallback blocks (legacy
4
4
  clear-cache-post-run=no # Keep caches after linting (faster subsequent runs)
5
5
  jobs=0 # Use all CPU cores (parallel analysis)
6
6
  persistent=yes # Save data between runs (improves inference caching)
7
- suggestion-mode=yes # Provide friendly hints instead of false positives
8
7
  unsafe-load-any-extension=no # Prevent loading arbitrary C extensions for safety
9
8
 
10
- ignore=venv,build,dist,__pycache__ # Ignore common generated/virtual dirs
11
- ignore-paths=.*[/\\](\.venv|\.mypy_cache|\.pytest_cache|build|dist|docs)[/\\].*
12
- ignore-patterns=^\.# # Ignore editor lockfiles (e.g., Emacs)
9
+ ignore=venv,build,dist,__pycache__,tests # Ignore common generated/virtual dirs
10
+ ignore-paths=.*[\\/](\.venv|\.mypy_cache|\.pytest_cache|build|dist|docs)([\\/].*)?$,.*[\\/]_version\.py$
11
+
12
+ ignore-patterns=^\.#,^__init__\.py$ # Ignore editor lockfiles (e.g., Emacs)
13
13
 
14
14
  extension-pkg-allow-list= # List allowed C-extension modules (empty = none)
15
15
  fail-on= # Fail immediately if these specific warnings/errors are found
@@ -41,7 +41,7 @@ include-naming-hint=yes # Suggest the expected format when na
41
41
  max-line-length=256 # Maximum line length
42
42
  indent-string=' ' # Use 4 spaces per indentation level
43
43
  indent-after-paren=4 # Hanging indent size
44
- max-module-lines=1000 # Max lines per module before warning
44
+ max-module-lines=2000 # Max lines per module before warning
45
45
  ignore-long-lines=^\s*(# )?<?https?://\S+>?$
46
46
  # Ignore long lines if they’re URLs or comments
47
47
  expected-line-ending-format=LF # Require LF line endings
@@ -66,18 +66,18 @@ 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=10 # Max arguments per function
70
- max-attributes=7 # Max attributes per class
71
- max-branches=12 # Max branches per function
72
- max-locals=30 # Max locals per function
73
- max-returns=6 # Max return statements per function
74
- max-statements=50 # Max total statements per function
69
+ max-args=30 # Max arguments per function
70
+ max-attributes=12 # Max attributes per class
71
+ max-branches=30 # Max branches per function
72
+ max-locals=80 # Max locals per function
73
+ max-returns=10 # Max return statements per function
74
+ max-statements=130 # Max total statements per function
75
75
  max-public-methods=20 # Max public methods per class
76
76
  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=10 # Max positional arguments per function
80
+ max-positional-arguments=25 # Max positional arguments per function
81
81
 
82
82
  [EXCEPTIONS]
83
83
  overgeneral-exceptions=builtins.BaseException,builtins.Exception
@@ -91,7 +91,10 @@ logging-modules=logging # Logging library to check against
91
91
  confidence=HIGH,CONTROL_FLOW,INFERENCE,INFERENCE_FAILURE,UNDEFINED
92
92
  # Only show warnings with these confidence levels
93
93
  disable=logging-too-many-args,
94
- import-error
94
+ import-error,
95
+ wrong-import-order,
96
+ import-outside-toplevel,
97
+ duplicate-code,
95
98
  # Disable noisy/meta warnings
96
99
 
97
100
 
@@ -15,4 +15,5 @@ exclude_path = [
15
15
  "logs",
16
16
  "megalinter-reports",
17
17
  ".venv",
18
+ ".github/workflows",
18
19
  ]
@@ -0,0 +1,2 @@
1
+ commit_prompt.md
2
+ squash_prompt.md
@@ -54,6 +54,7 @@ PRINT_ALPACA: false
54
54
  PYTHON_BANDIT_RULES_PATH: .linters
55
55
  PYTHON_BANDIT_CONFIG_FILE: .bandit.yml
56
56
  PYTHON_FLAKE8_RULES_PATH: .linters
57
+ PYTHON_PYLINT_FILTER_REGEX_EXCLUDE: tests/.*
57
58
  REPOSITORY_LS_LINT_RULES_PATH: .linters
58
59
  REPOSITORY_SEMGREP_RULESETS:
59
60
  [
@@ -67,6 +68,7 @@ REPOSITORY_SEMGREP_RULESETS:
67
68
  "p/secure-defaults",
68
69
  ]
69
70
  SHOW_ELAPSED_TIME: true
70
- SHOW_SKIPPED_LINTERS: false
71
+ SHOW_SKIPPED_LINTERS: true
71
72
  SPELL_PROSELINT_RULES_PATH: .linters
72
73
  SPELL_VALE_RULES_PATH: .linters
74
+ VALIDATE_ALL_CODEBASE: false
@@ -0,0 +1,6 @@
1
+ .devcontainer/Dockerfile
2
+ cli.py
3
+ config.py
4
+ squash.py
5
+ pr.py
6
+ release_aur.yml
@@ -0,0 +1,8 @@
1
+ # urllib3 vulnerability is introduced via twine, which is a dev-only dependency
2
+ # used exclusively for package publishing. It is not included in runtime
3
+ # environments or production artifacts. No production attack surface exists.
4
+ #
5
+ # Upstream fix pending in twine.
6
+ #
7
+ # Reviewed: 2026-01-10
8
+ CVE-2026-21441