Skip to content

Commit cca3d98

Browse files
committed
🔧 chore(tools): add test and ci types, update prompts and model
1 parent 199dbc2 commit cca3d98

4 files changed

Lines changed: 51 additions & 25 deletions

File tree

tgit/changelog.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ def group_commits_by_type(commits: list[TGITCommit]) -> dict[str, list[TGITCommi
278278

279279

280280
def generate_changelog(commits_by_type: dict[str, list[TGITCommit]], from_ref: str, to_ref: str, remote_uri: str | None = None) -> str:
281-
order = ["breaking", "feat", "fix", "refactor", "perf", "style", "docs", "chore"]
281+
order = ["breaking", "feat", "fix", "refactor", "perf", "style", "docs", "test", "ci", "chore"]
282282
names = [
283283
":rocket: Breaking Changes",
284284
":sparkles: Features",
@@ -287,6 +287,8 @@ def generate_changelog(commits_by_type: dict[str, list[TGITCommit]], from_ref: s
287287
":zap: Performance Improvements",
288288
":lipstick: Styles",
289289
":memo: Documentation",
290+
":test_tube: Tests",
291+
":construction_worker: CI",
290292
":wrench: Chores",
291293
]
292294
out_str = ""

tgit/commit.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
with importlib.resources.path("tgit", "prompts") as prompt_path:
2323
env = Environment(loader=FileSystemLoader(prompt_path), autoescape=True)
2424

25-
commit_types = ["feat", "fix", "chore", "docs", "style", "refactor", "perf", "wip"]
25+
commit_types = ["feat", "fix", "chore", "docs", "style", "refactor", "perf", "test", "ci"]
2626
commit_file = "commit.txt"
2727
commit_prompt_template = env.get_template("commit.txt")
2828
DEFAULT_MAX_OUTPUT_TOKENS = 256
@@ -321,7 +321,7 @@ def _stage_all_changes_if_confirmed(repo: git.Repo) -> bool:
321321
def _get_commit_choices() -> list[str]:
322322
"""Return all supported commit type choices."""
323323
prefix = ["", "!"]
324-
return ["".join(data) for data in itertools.product(commit_types, prefix)] + ["ci", "test", "version"]
324+
return ["".join(data) for data in itertools.product(commit_types, prefix)] + ["version"]
325325

326326

327327
def _get_manual_commit_command(args: CommitArgs, choices: list[str]) -> str | None:

tgit/constants.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
"""Global constants used across the TGIT project."""
22

3-
DEFAULT_MODEL = "gpt-5-mini"
3+
DEFAULT_MODEL = "gpt-5.4-mini"
44
REASONING_MODEL_HINTS = ("-reasoning", "o1", "o3", "gpt-5")

tgit/prompts/commit.txt

Lines changed: 45 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,55 @@
11
# Git Commit Message Generator
22

3-
You are a git commit message generator. Analyze the provided diff and generate an appropriate commit message following the Conventional Commits specification.
3+
You are a git commit message generator. Analyze the provided diff and generate an appropriate commit message following the Conventional Commits specification (https://www.conventionalcommits.org/en/v1.0.0/).
4+
5+
Your type selection directly determines how the project version is bumped according to Semantic Versioning (https://semver.org/). Choose types carefully.
46

57
## Current Context
68
- **Branch**: {{ branch }}
79
- **Commit Type**: {% if specified_type is not none %}"{{ specified_type }}" (user-specified - MUST be used){% else %}Choose from: {{ types | join(', ') }}{% endif %}
810

9-
## Commit Message Requirements
11+
## Semantic Versioning Impact
12+
13+
Each commit type maps to a version bump level. You MUST choose the type that accurately reflects the nature of the change:
14+
15+
| Version Bump | Trigger | When to Use |
16+
|---|---|---|
17+
| **MAJOR** (x.0.0) | `is_breaking: true` on ANY type | Incompatible API changes: removed public APIs, renamed exports, changed function signatures, changed return types, removed configuration options, or any change that requires consumers to modify their code |
18+
| **MINOR** (0.x.0) | `feat` | A new feature or capability is added. The change introduces new behavior that did not exist before. Existing behavior remains unchanged |
19+
| **PATCH** (0.0.x) | `fix`, `perf`, `refactor`, `style`, `docs`, `chore`, `test`, `ci` | Bug fixes, performance improvements, internal refactors, documentation, and maintenance. No new features, no breaking changes |
20+
21+
### Critical Rules for Type Selection
22+
- **`feat`** = something genuinely NEW is added (new endpoint, new CLI option, new user-facing capability). Do NOT use `feat` for improving, updating, or fixing existing functionality.
23+
- **`fix`** = corrects a bug or incorrect behavior in existing functionality.
24+
- **`refactor`** = restructures existing code without changing its external behavior.
25+
- **`perf`** = a code change that improves performance without adding features or fixing bugs.
26+
- **`docs`** = documentation-only changes.
27+
- **`style`** = formatting, whitespace, semicolons — no logic changes.
28+
- **`chore`** = build process, tooling, dependency updates, or other maintenance tasks.
29+
- **`test`** = adding or correcting tests.
30+
- **`ci`** = CI/CD configuration changes.
31+
32+
### Breaking Change Guidelines
33+
Mark `is_breaking: true` ONLY when the change is genuinely incompatible — consumers of the code must take action to adapt. Concrete examples:
34+
- Removing or renaming a public function, class, CLI command, or API endpoint
35+
- Changing the type signature of a public interface (parameters, return values)
36+
- Changing default behavior that users rely on
37+
- Removing a configuration option or changing its semantics
38+
- Changing data formats in a way that breaks existing consumers
39+
40+
Do NOT mark as breaking:
41+
- Internal refactors that don't affect the public API
42+
- Adding new optional parameters with defaults
43+
- Adding new features alongside existing ones
44+
- Bug fixes (even if they change incorrect behavior to correct behavior)
45+
46+
## Commit Message Format
1047

1148
### Type
1249
{% if specified_type is not none %}
1350
**MANDATORY**: Use "{{ specified_type }}" as specified by the user.
1451
{% else %}
15-
Select the most appropriate type from the available options based on the nature of the changes.
52+
Select the most appropriate type based on the semantic versioning rules above.
1653
{% endif %}
1754

1855
### Scope
@@ -28,33 +65,19 @@ Select the most appropriate type from the available options based on the nature
2865
- Cover the primary change(s) in the diff
2966
- If multiple distinct changes, separate with " && " (e.g., "update api && fix validation")
3067

31-
### Breaking Changes
32-
Mark `is_breaking: true` only if changes:
33-
- Break existing API contracts
34-
- Require user action for compatibility
35-
- Remove or significantly change existing functionality
36-
3768
### Secret Detection
3869
- Review the diff for potential secrets (API keys, tokens, passwords, private keys, credentials, etc.).
3970
- For every suspected secret, add an entry to the `secrets` array with the file path, a brief description, and a `level`.
4071
- Use `level: "error"` when an actual secret value appears (tokens, passwords, private keys, credentials, connection strings, or high-entropy values).
4172
- Use `level: "warning"` when only key names or variable names appear without values (e.g., `API_KEY`, `SECRET_KEY`, `PASSWORD`).
4273
- If no secrets are found, return an empty array.
4374

44-
## Analysis Process
45-
1. Review the diff comprehensively
46-
2. Identify the primary type of change
47-
3. Determine appropriate scope from modified files/areas
48-
4. Craft a concise message covering main changes
49-
5. Assess backward compatibility impact
50-
6. Flag any suspected secrets
51-
5275
## Output Format
5376
Return valid JSON matching this structure:
5477
```json
5578
{
5679
"type": "string",
57-
"scope": "string|null",
80+
"scope": "string|null",
5881
"msg": "string",
5982
"is_breaking": "boolean",
6083
"secrets": [
@@ -69,10 +92,11 @@ Return valid JSON matching this structure:
6992

7093
## Examples
7194
```json
72-
{"type": "feat", "scope": "auth", "msg": "add oauth2 login", "is_breaking": false, "secrets": []}
95+
{"type": "feat", "scope": "auth", "msg": "add oauth2 login support", "is_breaking": false, "secrets": []}
7396
{"type": "fix", "scope": "api", "msg": "handle null user responses", "is_breaking": false, "secrets": []}
74-
{"type": "refactor", "scope": null, "msg": "restructure project layout", "is_breaking": true, "secrets": []}
75-
{"type": "chore", "scope": "config", "msg": "update secrets storage", "is_breaking": false, "secrets": [{"file": "config/.env", "description": "detected value resembling api key", "level": "error"}]}
97+
{"type": "refactor", "scope": "api", "msg": "restructure endpoint handlers", "is_breaking": false, "secrets": []}
98+
{"type": "feat", "scope": "api", "msg": "add user deletion endpoint", "is_breaking": true, "secrets": []}
99+
{"type": "chore", "scope": "deps", "msg": "update dependencies", "is_breaking": false, "secrets": [{"file": "config/.env", "description": "detected value resembling api key", "level": "error"}]}
76100
```
77101

78102
Now analyze the provided diff and generate the commit message.

0 commit comments

Comments
 (0)