git-cai-cli 0.1.1.dev0__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.1.1.dev0/.caiignore +5 -0
- git_cai_cli-0.1.1.dev0/.gitignore +13 -0
- git_cai_cli-0.1.1.dev0/.linters/.bandit.yml +4 -0
- git_cai_cli-0.1.1.dev0/.linters/.checkov.yml +2 -0
- git_cai_cli-0.1.1.dev0/.linters/.flake8 +7 -0
- git_cai_cli-0.1.1.dev0/.linters/.ls-lint.yml +14 -0
- git_cai_cli-0.1.1.dev0/.linters/.markdown-link-check.json +10 -0
- git_cai_cli-0.1.1.dev0/.linters/.markdownlint.json +18 -0
- git_cai_cli-0.1.1.dev0/.linters/.proselintrc +78 -0
- git_cai_cli-0.1.1.dev0/.linters/.pylintrc +112 -0
- git_cai_cli-0.1.1.dev0/.linters/.yamllint.yml +18 -0
- git_cai_cli-0.1.1.dev0/.linters/check_git_branch_name.sh +28 -0
- git_cai_cli-0.1.1.dev0/.linters/lychee.toml +18 -0
- git_cai_cli-0.1.1.dev0/.linters/pyrightconfig.json +5 -0
- git_cai_cli-0.1.1.dev0/.mega-linter.yml +72 -0
- git_cai_cli-0.1.1.dev0/.semgrepignore +1 -0
- git_cai_cli-0.1.1.dev0/.trivyignore +2 -0
- git_cai_cli-0.1.1.dev0/LICENSE +21 -0
- git_cai_cli-0.1.1.dev0/Makefile +47 -0
- git_cai_cli-0.1.1.dev0/PKG-INFO +104 -0
- git_cai_cli-0.1.1.dev0/PKGBUILD +36 -0
- git_cai_cli-0.1.1.dev0/README.md +77 -0
- git_cai_cli-0.1.1.dev0/pyproject.toml +50 -0
- git_cai_cli-0.1.1.dev0/setup.cfg +4 -0
- git_cai_cli-0.1.1.dev0/src/git_cai_cli/__init__.py +0 -0
- git_cai_cli-0.1.1.dev0/src/git_cai_cli/cli.py +61 -0
- git_cai_cli-0.1.1.dev0/src/git_cai_cli/core/__init__.py +0 -0
- git_cai_cli-0.1.1.dev0/src/git_cai_cli/core/config.py +146 -0
- git_cai_cli-0.1.1.dev0/src/git_cai_cli/core/gitutils.py +57 -0
- git_cai_cli-0.1.1.dev0/src/git_cai_cli/core/llm.py +97 -0
- git_cai_cli-0.1.1.dev0/src/git_cai_cli.egg-info/PKG-INFO +104 -0
- git_cai_cli-0.1.1.dev0/src/git_cai_cli.egg-info/SOURCES.txt +36 -0
- git_cai_cli-0.1.1.dev0/src/git_cai_cli.egg-info/dependency_links.txt +1 -0
- git_cai_cli-0.1.1.dev0/src/git_cai_cli.egg-info/entry_points.txt +2 -0
- git_cai_cli-0.1.1.dev0/src/git_cai_cli.egg-info/requires.txt +3 -0
- git_cai_cli-0.1.1.dev0/src/git_cai_cli.egg-info/top_level.txt +2 -0
- git_cai_cli-0.1.1.dev0/src/tests/test_core/test_config.py +128 -0
- git_cai_cli-0.1.1.dev0/uv.lock +789 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
ls:
|
|
2
|
+
.py: lowercase | snake_case
|
|
3
|
+
.sh: lowercase | snake_case
|
|
4
|
+
.yml: lowercase | snake_case
|
|
5
|
+
.json: lowercase | snake_case
|
|
6
|
+
.txt: lowercase | snake_case
|
|
7
|
+
.toml: lowercase | snake_case
|
|
8
|
+
.config: lowercase | snake_case
|
|
9
|
+
.env: lowercase | snake_case
|
|
10
|
+
|
|
11
|
+
ignore:
|
|
12
|
+
- .git
|
|
13
|
+
- .venv
|
|
14
|
+
- src/git_cai_cli.egg-info
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"MD004": true,
|
|
3
|
+
"MD007": {
|
|
4
|
+
"indent": 2
|
|
5
|
+
},
|
|
6
|
+
"MD013": {
|
|
7
|
+
"line_length": 256,
|
|
8
|
+
"code_blocks": false
|
|
9
|
+
},
|
|
10
|
+
"MD026": {
|
|
11
|
+
"punctuation": ".,;:!。,;:"
|
|
12
|
+
},
|
|
13
|
+
"MD029": true,
|
|
14
|
+
"MD033": false,
|
|
15
|
+
"MD036": true,
|
|
16
|
+
"MD041": true,
|
|
17
|
+
"MD051": true
|
|
18
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
{
|
|
2
|
+
"checks": {
|
|
3
|
+
"airlinese.misc": false
|
|
4
|
+
, "annotations.misc": false
|
|
5
|
+
, "archaism.misc": false
|
|
6
|
+
, "cliches.hell": true
|
|
7
|
+
, "cliches.misc": true
|
|
8
|
+
, "consistency.spacing": true
|
|
9
|
+
, "consistency.spelling": true
|
|
10
|
+
, "corporate_speak.misc": true
|
|
11
|
+
, "cursing.filth": false
|
|
12
|
+
, "cursing.nfl": false
|
|
13
|
+
, "dates_times.am_pm": true
|
|
14
|
+
, "dates_times.dates": true
|
|
15
|
+
, "hedging.misc": true
|
|
16
|
+
, "hyperbole.misc": true
|
|
17
|
+
, "jargon.misc": false
|
|
18
|
+
, "lgbtq.offensive_terms": true
|
|
19
|
+
, "lgbtq.terms": true
|
|
20
|
+
, "lexical_illusions.misc": false
|
|
21
|
+
, "links.broken": true
|
|
22
|
+
, "malapropisms.misc": true
|
|
23
|
+
, "misc.apologizing": true
|
|
24
|
+
, "misc.back_formations": true
|
|
25
|
+
, "misc.bureaucratese": true
|
|
26
|
+
, "misc.but": true
|
|
27
|
+
, "misc.capitalization": true
|
|
28
|
+
, "misc.chatspeak": true
|
|
29
|
+
, "misc.commercialese": true
|
|
30
|
+
, "misc.currency": true
|
|
31
|
+
, "misc.debased": true
|
|
32
|
+
, "misc.false_plurals": true
|
|
33
|
+
, "misc.illogic": true
|
|
34
|
+
, "misc.inferior_superior": true
|
|
35
|
+
, "misc.latin": true
|
|
36
|
+
, "misc.many_a": true
|
|
37
|
+
, "misc.metaconcepts": true
|
|
38
|
+
, "misc.narcissism": true
|
|
39
|
+
, "misc.phrasal_adjectives": false
|
|
40
|
+
, "misc.preferred_forms": true
|
|
41
|
+
, "misc.pretension": true
|
|
42
|
+
, "misc.professions": true
|
|
43
|
+
, "misc.punctuation": true
|
|
44
|
+
, "misc.scare_quotes": true
|
|
45
|
+
, "misc.suddenly": true
|
|
46
|
+
, "misc.tense_present": true
|
|
47
|
+
, "misc.waxed": true
|
|
48
|
+
, "misc.whence": true
|
|
49
|
+
, "mixed_metaphors.misc": true
|
|
50
|
+
, "mondegreens.misc": true
|
|
51
|
+
, "needless_variants.misc": true
|
|
52
|
+
, "nonwords.misc": true
|
|
53
|
+
, "oxymorons.misc": true
|
|
54
|
+
, "psychology.misc": true
|
|
55
|
+
, "redundancy.misc": true
|
|
56
|
+
, "redundancy.ras_syndrome": true
|
|
57
|
+
, "skunked_terms.misc": true
|
|
58
|
+
, "spelling.able_atable": true
|
|
59
|
+
, "spelling.able_ible": true
|
|
60
|
+
, "spelling.athletes": false
|
|
61
|
+
, "spelling.em_im_en_in": true
|
|
62
|
+
, "spelling.er_or": true
|
|
63
|
+
, "spelling.in_un": true
|
|
64
|
+
, "spelling.misc": true
|
|
65
|
+
, "security.credit_card": true
|
|
66
|
+
, "security.password": true
|
|
67
|
+
, "sexism.misc": true
|
|
68
|
+
, "terms.animal_adjectives": true
|
|
69
|
+
, "terms.eponymous_adjectives": true
|
|
70
|
+
, "terms.venery": true
|
|
71
|
+
, "typography.diacritical_marks": true
|
|
72
|
+
, "typography.exclamation": true
|
|
73
|
+
, "typography.symbols": false
|
|
74
|
+
, "uncomparables.misc": true
|
|
75
|
+
, "weasel_words.misc": true
|
|
76
|
+
, "weasel_words.very": true
|
|
77
|
+
}
|
|
78
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
[MAIN]
|
|
2
|
+
fail-under=10 # Require a perfect 10/10 score or exit with error
|
|
3
|
+
analyse-fallback-blocks=no # Don’t analyze import fallback blocks (legacy Python 2/3 support)
|
|
4
|
+
clear-cache-post-run=no # Keep caches after linting (faster subsequent runs)
|
|
5
|
+
jobs=0 # Use all CPU cores (parallel analysis)
|
|
6
|
+
persistent=yes # Save data between runs (improves inference caching)
|
|
7
|
+
suggestion-mode=yes # Provide friendly hints instead of false positives
|
|
8
|
+
unsafe-load-any-extension=no # Prevent loading arbitrary C extensions for safety
|
|
9
|
+
|
|
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)
|
|
13
|
+
|
|
14
|
+
extension-pkg-allow-list= # List allowed C-extension modules (empty = none)
|
|
15
|
+
fail-on= # Fail immediately if these specific warnings/errors are found
|
|
16
|
+
|
|
17
|
+
[REPORTS]
|
|
18
|
+
reports=no # Don’t show full summary report (CI-friendly)
|
|
19
|
+
evaluation=max(0, 0 if fatal else 10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10))
|
|
20
|
+
# Formula for calculating score (out of 10)
|
|
21
|
+
msg-template={path}:{line}:{column}: {msg_id} ({symbol}) {msg}
|
|
22
|
+
# Output format for each message (good for CI/editors)
|
|
23
|
+
output-format=colorized # Colorized console output
|
|
24
|
+
|
|
25
|
+
[BASIC]
|
|
26
|
+
argument-naming-style=snake_case # Function/method args must be snake_case
|
|
27
|
+
attr-naming-style=snake_case # Instance attributes must be snake_case
|
|
28
|
+
class-naming-style=PascalCase # Classes must be PascalCase
|
|
29
|
+
const-naming-style=UPPER_CASE # Constants must be UPPER_CASE
|
|
30
|
+
function-naming-style=snake_case # Functions must be snake_case
|
|
31
|
+
method-naming-style=snake_case # Methods must be snake_case
|
|
32
|
+
module-naming-style=snake_case # Modules (files) must be snake_case
|
|
33
|
+
variable-naming-style=snake_case # Local variables must be snake_case
|
|
34
|
+
|
|
35
|
+
bad-names=foo,bar,baz,toto,tutu,tata,tmp,data1
|
|
36
|
+
# Forbidden names that always fail
|
|
37
|
+
good-names=i,j,k,ex,_,pk,id # Short names that are acceptable
|
|
38
|
+
include-naming-hint=yes # Suggest the expected format when naming is wrong
|
|
39
|
+
|
|
40
|
+
[FORMAT]
|
|
41
|
+
max-line-length=256 # Maximum line length
|
|
42
|
+
indent-string=' ' # Use 4 spaces per indentation level
|
|
43
|
+
indent-after-paren=4 # Hanging indent size
|
|
44
|
+
max-module-lines=1000 # Max lines per module before warning
|
|
45
|
+
ignore-long-lines=^\s*(# )?<?https?://\S+>?$
|
|
46
|
+
# Ignore long lines if they’re URLs or comments
|
|
47
|
+
expected-line-ending-format=LF # Require LF line endings
|
|
48
|
+
single-line-if-stmt=no # Disallow single-line ifs
|
|
49
|
+
single-line-class-stmt=no # Disallow single-line class definitions
|
|
50
|
+
function-rgx=^([a-z_][a-z0-9_]*|[a-z]+(?:[A-Z][a-z0-9]+)*|[A-Z][a-z0-9]+(?:[A-Z][a-z0-9]+)*)$
|
|
51
|
+
|
|
52
|
+
[IMPORTS]
|
|
53
|
+
allow-wildcard-with-all=no # Don’t allow wildcard imports even with __all__
|
|
54
|
+
allow-reexport-from-package=no # Don’t allow alias re-exports in __init__.py
|
|
55
|
+
known-third-party=requests,polars
|
|
56
|
+
# Declare 3rd party modules for correct grouping
|
|
57
|
+
|
|
58
|
+
[CLASSES]
|
|
59
|
+
defining-attr-methods=__init__,__new__,setUp,asyncSetUp,__post_init__
|
|
60
|
+
# Methods where attributes can be defined
|
|
61
|
+
exclude-protected=_asdict,_fields,_replace,_source,_make,os._exit
|
|
62
|
+
# Protected names allowed to be accessed
|
|
63
|
+
valid-classmethod-first-arg=cls # Class methods must use `cls`
|
|
64
|
+
valid-metaclass-classmethod-first-arg=mcs # Metaclass methods must use `mcs`
|
|
65
|
+
check-protected-access-in-special-methods=no
|
|
66
|
+
# Don’t warn about protected attr access in dunder methods
|
|
67
|
+
|
|
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
|
|
75
|
+
max-public-methods=20 # Max public methods per class
|
|
76
|
+
min-public-methods=1 # Min public methods per class
|
|
77
|
+
max-nested-blocks=15 # Max nesting depth
|
|
78
|
+
max-bool-expr=15 # Max boolean subexpressions in a condition
|
|
79
|
+
max-parents=7 # Max base classes per class
|
|
80
|
+
max-positional-arguments=10 # Max positional arguments per function
|
|
81
|
+
|
|
82
|
+
[EXCEPTIONS]
|
|
83
|
+
overgeneral-exceptions=builtins.BaseException,builtins.Exception
|
|
84
|
+
# Warn when catching too broad exceptions
|
|
85
|
+
|
|
86
|
+
[LOGGING]
|
|
87
|
+
logging-format-style=new # Enforce `{}`-style logging (not `%s` or f-strings)
|
|
88
|
+
logging-modules=logging # Logging library to check against
|
|
89
|
+
|
|
90
|
+
[MESSAGES CONTROL]
|
|
91
|
+
confidence=HIGH,CONTROL_FLOW,INFERENCE,INFERENCE_FAILURE,UNDEFINED
|
|
92
|
+
# Only show warnings with these confidence levels
|
|
93
|
+
disable=logging-too-many-args,
|
|
94
|
+
import-error
|
|
95
|
+
# Disable noisy/meta warnings
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
[METHOD_ARGS]
|
|
100
|
+
timeout-methods=requests.api.delete,requests.api.get,requests.api.head,requests.api.options,requests.api.patch,requests.api.post,requests.api.put,requests.api.request
|
|
101
|
+
# Enforce timeout param in requests.* calls
|
|
102
|
+
|
|
103
|
+
[MISCELLANEOUS]
|
|
104
|
+
notes=FIXME,TODO,XXX,BUG,HACK # Markers that are flagged in comments
|
|
105
|
+
|
|
106
|
+
[REFACTORING]
|
|
107
|
+
never-returning-functions=sys.exit,argparse.parse_error
|
|
108
|
+
# Functions that always exit the program
|
|
109
|
+
suggest-join-with-non-empty-separator=yes # Warn if `" - " + " - ".join(items)` could be simplified
|
|
110
|
+
|
|
111
|
+
[SIMILARITIES]
|
|
112
|
+
min-similarity-lines=8 # Minimum lines of similarity to report
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
###########################################
|
|
2
|
+
# These are the rules used for #
|
|
3
|
+
# linting all the yaml files in the stack #
|
|
4
|
+
# NOTE: #
|
|
5
|
+
# You can disable line with: #
|
|
6
|
+
# # yamllint disable-line #
|
|
7
|
+
###########################################
|
|
8
|
+
extends: default
|
|
9
|
+
rules:
|
|
10
|
+
new-lines:
|
|
11
|
+
level: warning
|
|
12
|
+
type: unix
|
|
13
|
+
line-length:
|
|
14
|
+
max: 500
|
|
15
|
+
document-start:
|
|
16
|
+
present: false
|
|
17
|
+
comments:
|
|
18
|
+
min-spaces-from-content: 1 # Used to follow prettier standard: https://github.com/prettier/prettier/pull/10926
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# Define color codes
|
|
4
|
+
RED='\033[0;31m'
|
|
5
|
+
GREEN='\033[0;32m'
|
|
6
|
+
NC='\033[0m' # No Color
|
|
7
|
+
|
|
8
|
+
# Unicode symbols
|
|
9
|
+
CHECK_MARK="${GREEN}✔${NC}"
|
|
10
|
+
CROSS_MARK="${RED}✖${NC}"
|
|
11
|
+
|
|
12
|
+
# Get the current branch name
|
|
13
|
+
BRANCH_NAME=${1:-$(git rev-parse --abbrev-ref HEAD)}
|
|
14
|
+
|
|
15
|
+
# Define the branch name pattern
|
|
16
|
+
BRANCH_NAME_REGEX="^(master|(feature|fix|hotfix|chore|refactor|test|docs)/[a-z0-9._-]+)$"
|
|
17
|
+
|
|
18
|
+
# Check the branch name against the pattern
|
|
19
|
+
if [[ ! $BRANCH_NAME =~ $BRANCH_NAME_REGEX && $BRANCH_NAME != "main" ]]; then
|
|
20
|
+
echo -e "\n\n${CROSS_MARK} ${RED}Error:${NC} Branch name '${BRANCH_NAME}' does not follow the naming convention.\n"
|
|
21
|
+
echo -e "${RED}Branch names must match the pattern:${NC} $BRANCH_NAME_REGEX"
|
|
22
|
+
echo -e "${RED}Do you use feature/fix/hotfix/chore/refactor/test/docs as a prefix?${NC}"
|
|
23
|
+
echo -e "${RED}Do you use only lowercase letters, numbers, dots, and hyphens in the branch name?${NC}"
|
|
24
|
+
echo -e "${RED}You can rename your branch by running:${NC} git branch -m <new-branch-name>\n\n"
|
|
25
|
+
exit 1
|
|
26
|
+
fi
|
|
27
|
+
|
|
28
|
+
echo -e "\n\n${CHECK_MARK} ${GREEN}Branch name '${BRANCH_NAME}' is valid.${NC}\n\n"
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Accepts log level: "error", "warn", "info", "debug", "trace"
|
|
2
|
+
verbose = "info"
|
|
3
|
+
|
|
4
|
+
# Don't show interactive progress bar while checking links.
|
|
5
|
+
no_progress = true
|
|
6
|
+
|
|
7
|
+
accept = ["200", "429"]
|
|
8
|
+
|
|
9
|
+
exclude = [
|
|
10
|
+
"https://megalinter.io/configuration/",
|
|
11
|
+
"file:///tmp/lint/dwh/models/logo.png"
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
exclude_path = [
|
|
15
|
+
"logs",
|
|
16
|
+
"megalinter-reports",
|
|
17
|
+
".venv",
|
|
18
|
+
]
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# Configuration file for MegaLinter
|
|
2
|
+
# See all available variables at https://megalinter.io/configuration/
|
|
3
|
+
# and in linters documentation
|
|
4
|
+
|
|
5
|
+
APPLY_FIXES: none # all, none, or list of linter keys
|
|
6
|
+
BASH_SHELLCHECK_ARGUMENTS: -e "SC2162"
|
|
7
|
+
CLEAR_REPORT_FOLDER: true
|
|
8
|
+
DISABLE_ERRORS: false
|
|
9
|
+
ENABLE_LINTERS:
|
|
10
|
+
- BASH_EXEC
|
|
11
|
+
- BASH_SHELLCHECK
|
|
12
|
+
- BASH_SHFMT
|
|
13
|
+
- JSON_JSONLINT
|
|
14
|
+
- JSON_PRETTIER
|
|
15
|
+
- JSON_V8R
|
|
16
|
+
- MAKEFILE_CHECKMAKE
|
|
17
|
+
- MARKDOWN_MARKDOWNLINT
|
|
18
|
+
- MARKDOWN_MARKDOWN_LINK_CHECK
|
|
19
|
+
- MARKDOWN_MARKDOWN_TABLE_FORMATTER
|
|
20
|
+
- PYTHON_BLACK
|
|
21
|
+
- PYTHON_BANDIT
|
|
22
|
+
- PYTHON_FLAKE8
|
|
23
|
+
- PYTHON_ISORT
|
|
24
|
+
- PYTHON_MYPY
|
|
25
|
+
- PYTHON_PYLINT
|
|
26
|
+
- PYTHON_PYRIGHT
|
|
27
|
+
- PYTHON_RUFF
|
|
28
|
+
- PYTHON_RUFF_FORMAT
|
|
29
|
+
- REPOSITORY_CHECKOV
|
|
30
|
+
- REPOSITORY_GITLEAKS
|
|
31
|
+
- REPOSITORY_KICS
|
|
32
|
+
- REPOSITORY_LS_LINT
|
|
33
|
+
- REPOSITORY_SECRETLINT
|
|
34
|
+
- REPOSITORY_SEMGREP
|
|
35
|
+
- REPOSITORY_TRIVY
|
|
36
|
+
- REPOSITORY_TRUFFLEHOG
|
|
37
|
+
- SPELL_LYCHEE
|
|
38
|
+
- SPELL_PROSELINT
|
|
39
|
+
- YAML_PRETTIER
|
|
40
|
+
- YAML_V8R
|
|
41
|
+
- YAML_YAMLLINT
|
|
42
|
+
FAIL_IF_UPDATED_SOURCES: false
|
|
43
|
+
FILEIO_REPORTER: false
|
|
44
|
+
FILTER_REGEX_EXCLUDE: none
|
|
45
|
+
FLAVOR_SUGGESTIONS: false
|
|
46
|
+
FORMATTERS_DISABLE_ERRORS: false
|
|
47
|
+
IGNORE_GITIGNORED_FILES: true
|
|
48
|
+
LINTER_RULES_PATH: .linters
|
|
49
|
+
LOG_LEVEL: INFO
|
|
50
|
+
MARKDOWN_DEFAULT_STYLE: markdownlint
|
|
51
|
+
MARKDOWN_MARKDOWN_LINK_CHECK_RULES_PATH: .linters
|
|
52
|
+
PARALLEL: true
|
|
53
|
+
PRINT_ALPACA: false
|
|
54
|
+
PYTHON_BANDIT_RULES_PATH: .linters
|
|
55
|
+
PYTHON_BANDIT_CONFIG_FILE: .bandit.yml
|
|
56
|
+
PYTHON_FLAKE8_RULES_PATH: .linters
|
|
57
|
+
REPOSITORY_LS_LINT_RULES_PATH: .linters
|
|
58
|
+
REPOSITORY_SEMGREP_RULESETS:
|
|
59
|
+
[
|
|
60
|
+
"p/comment",
|
|
61
|
+
"p/cwe-top-25",
|
|
62
|
+
"p/docker-compose",
|
|
63
|
+
"p/dockerfile",
|
|
64
|
+
"p/owasp-top-ten",
|
|
65
|
+
"p/python",
|
|
66
|
+
"p/r2c-security-audit",
|
|
67
|
+
"p/secure-defaults",
|
|
68
|
+
]
|
|
69
|
+
SHOW_ELAPSED_TIME: true
|
|
70
|
+
SHOW_SKIPPED_LINTERS: false
|
|
71
|
+
SPELL_PROSELINT_RULES_PATH: .linters
|
|
72
|
+
SPELL_VALE_RULES_PATH: .linters
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.devcontainer/Dockerfile
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Thorsten Foltz
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
#!/usr/bin/make -f
|
|
2
|
+
|
|
3
|
+
PIP := pipx
|
|
4
|
+
UV := uv
|
|
5
|
+
SHELL := /bin/bash
|
|
6
|
+
|
|
7
|
+
.PHONY: help lint check-docker check-npx lint-fix add-lint-hook clean
|
|
8
|
+
|
|
9
|
+
help: ## Shows this help message
|
|
10
|
+
@echo "Available commands:"
|
|
11
|
+
@awk '/^[a-zA-Z_-]+:.*## / { printf " %-20s %s\n", $$1, substr($$0, index($$0, "##") + 3) }' $(MAKEFILE_LIST)
|
|
12
|
+
|
|
13
|
+
add-lint-hook: ## Adds a git pre-push hook to automatically run 'lint' before pushing
|
|
14
|
+
@echo "#!/bin/bash" > .git/hooks/pre-push
|
|
15
|
+
@echo "make lint" >> .git/hooks/pre-push
|
|
16
|
+
@chmod +x .git/hooks/pre-push
|
|
17
|
+
@echo "Pre-push hook added. The 'lint' command will now run before each push."
|
|
18
|
+
|
|
19
|
+
check-docker: ## Checks if docker is installed
|
|
20
|
+
@if ! command -v docker &> /dev/null; then \
|
|
21
|
+
echo "Docker is not installed. Please install it."; \
|
|
22
|
+
exit 1; \
|
|
23
|
+
else \
|
|
24
|
+
echo "Docker version:"; \
|
|
25
|
+
docker --version; \
|
|
26
|
+
fi
|
|
27
|
+
|
|
28
|
+
check-npx: ## Checks if npx is installed
|
|
29
|
+
@if ! command -v npx &> /dev/null; then \
|
|
30
|
+
echo "npx is not installed. Please install it."; \
|
|
31
|
+
exit 1; \
|
|
32
|
+
else \
|
|
33
|
+
echo "npx version:"; \
|
|
34
|
+
npx --version; \
|
|
35
|
+
fi
|
|
36
|
+
|
|
37
|
+
clean: ## Clean cache of uv and delete virtual environment
|
|
38
|
+
@$(UV) cache clean
|
|
39
|
+
@rm -rf .venv
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
lint:
|
|
43
|
+
@sh ./.linters/check_git_branch_name.sh
|
|
44
|
+
@npx mega-linter-runner --flavor python
|
|
45
|
+
|
|
46
|
+
lint-fix: ## Lints the code using sqlfluff and fixes the issues
|
|
47
|
+
@npx mega-linter-runner --fix
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: git-cai-cli
|
|
3
|
+
Version: 0.1.1.dev0
|
|
4
|
+
Summary: Use LLM to create git commits
|
|
5
|
+
Author-email: Thorsten Foltz <thorsten.foltz@live.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/thorstenfoltz/cai
|
|
8
|
+
Project-URL: Issues, https://github.com/thorstenfoltz/cai/issues
|
|
9
|
+
Keywords: Git,LLM,Commit,AI,GenAI
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Environment :: Console
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: Operating System :: OS Independent
|
|
19
|
+
Classifier: Topic :: Software Development :: Version Control
|
|
20
|
+
Requires-Python: >=3.10
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
License-File: LICENSE
|
|
23
|
+
Requires-Dist: pyyaml>=6.0
|
|
24
|
+
Requires-Dist: openai>=1.0
|
|
25
|
+
Requires-Dist: google-genai>=1.41.0
|
|
26
|
+
Dynamic: license-file
|
|
27
|
+
|
|
28
|
+
# cai
|
|
29
|
+
|
|
30
|
+
`cai` is a Git extension written in Python that automates commit message creation. It allows you to run `git cai` to automatically generate a commit message based on changes and new additions in your repository.
|
|
31
|
+
|
|
32
|
+
`cai` leverages a **large language model (LLM)** to generate meaningful and context-aware commit messages. Currently, it supports the **OpenAI** and **Gemini API** for generating commit messages.
|
|
33
|
+
|
|
34
|
+
## Table of Contents
|
|
35
|
+
|
|
36
|
+
- [About](#about-section)
|
|
37
|
+
- [Prerequisites](#prerequisites)
|
|
38
|
+
- [Features](#features-section)
|
|
39
|
+
- [Installation](#installation-section)
|
|
40
|
+
- [Usage](#usage-section)
|
|
41
|
+
- [License](#license-section)
|
|
42
|
+
|
|
43
|
+
<h2 id="about-section">About</h2>
|
|
44
|
+
|
|
45
|
+
`cai` is designed to simplify your Git workflow by automatically generating commit messages using an LLM. No more struggling to summarize changes — `git cai` does it for you.
|
|
46
|
+
|
|
47
|
+
Currently, the only supported backend are the OpenAI and Gemini API, but additional LLM integrations may be added in the future.
|
|
48
|
+
|
|
49
|
+
<h2 id="prerequisites">Prerequisites</h2>
|
|
50
|
+
|
|
51
|
+
- Python 3.10 or higher
|
|
52
|
+
- [Pipx](https://pypi.org/project/pipx/) or [Pip](https://pypi.org/project/pip/) if installed in a virtual environment
|
|
53
|
+
- API key, currently supported
|
|
54
|
+
- OpenAI
|
|
55
|
+
- Gemini
|
|
56
|
+
|
|
57
|
+
<h2 id="features-section">Features</h2>
|
|
58
|
+
|
|
59
|
+
- Automatically detects added, modified, and deleted files
|
|
60
|
+
- Generates meaningful commit messages using an LLM
|
|
61
|
+
- Seamless integration with Git as a plugin/extension
|
|
62
|
+
- Written in Python for easy customization
|
|
63
|
+
|
|
64
|
+
<h2 id="installation-section">Installation</h2>
|
|
65
|
+
|
|
66
|
+
Install by
|
|
67
|
+
|
|
68
|
+
```sh
|
|
69
|
+
pipx install git-cai-cli
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Afterwards set cai to PATH by
|
|
73
|
+
|
|
74
|
+
```sh
|
|
75
|
+
pipx ensurepath
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Restart your shell by executing `bash` or `zsh` or whatever else is your used shell.
|
|
79
|
+
|
|
80
|
+
<h2 id="usage-section">Usage</h2>
|
|
81
|
+
|
|
82
|
+
Once installed, you can use `cai` like a normal Git command:
|
|
83
|
+
|
|
84
|
+
```sh
|
|
85
|
+
git cai
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
`cai` automatically creates a configuration file at: `~/.config/cai/token.yml`
|
|
89
|
+
This file stores your OpenAI API key, which is used every time you run `git cai`.
|
|
90
|
+
Open `~/.config/cai/token.yml` and store your token from OpenAI.
|
|
91
|
+
If a `cai_config.yml` file exists in the root of your repository, `cai` will use the settings defined there. Otherwise, it falls back to default settings, which are automatically created in the same directory as `token.yml` if they don’t already exist.
|
|
92
|
+
Currently, the only configurable options are:
|
|
93
|
+
|
|
94
|
+
- LLM model
|
|
95
|
+
- Temperature
|
|
96
|
+
|
|
97
|
+
`cai` uses Git’s `diff` output as input for generating commit messages.
|
|
98
|
+
To exclude specific files or directories from being included in the generated commit message, create a `.caiignore` file in the root of your repository. This file works like a `.gitignore`.
|
|
99
|
+
|
|
100
|
+
- Files listed in `.gitignore` are **always excluded**.
|
|
101
|
+
- `.caiignore` is only needed for files that are tracked by Git but should **not** be included in the commit message.
|
|
102
|
+
|
|
103
|
+
<h2 id="license-section">License</h2>
|
|
104
|
+
This project is licensed under the MIT License.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Maintainer: Thorsten Foltz <thorsten.foltz@live.com>
|
|
2
|
+
pkgname=cai
|
|
3
|
+
pkgver=0.1.0
|
|
4
|
+
pkgrel=1
|
|
5
|
+
pkgdesc="Use LLM to create git commit messages."
|
|
6
|
+
arch=('any')
|
|
7
|
+
license=('MIT')
|
|
8
|
+
depends=('python' 'python-pip' 'python-yaml' 'python-openai')
|
|
9
|
+
source=()
|
|
10
|
+
sha256sums=()
|
|
11
|
+
|
|
12
|
+
build() {
|
|
13
|
+
# Create a clean staging directory
|
|
14
|
+
mkdir -p "$srcdir/$pkgname-$pkgver"
|
|
15
|
+
|
|
16
|
+
# Copy only project files, skip makepkg internals
|
|
17
|
+
for f in "$startdir"/*; do
|
|
18
|
+
case "$(basename "$f")" in
|
|
19
|
+
src|pkg) ;; # skip makepkg working dirs
|
|
20
|
+
*) cp -r "$f" "$srcdir/$pkgname-$pkgver"/ ;;
|
|
21
|
+
esac
|
|
22
|
+
done
|
|
23
|
+
|
|
24
|
+
cd "$srcdir/$pkgname-$pkgver"
|
|
25
|
+
|
|
26
|
+
# Optional: build a wheel (can skip, pip install . works too)
|
|
27
|
+
python -m pip wheel . --wheel-dir "$srcdir/dist"
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
package() {
|
|
31
|
+
cd "$srcdir/$pkgname-$pkgver"
|
|
32
|
+
|
|
33
|
+
# Install the package system-wide in staged dir
|
|
34
|
+
# This ensures console scripts go to /usr/bin
|
|
35
|
+
python -m pip install --root="$pkgdir" --prefix=/usr .
|
|
36
|
+
}
|