lgit-cli 3.7.0__py3-none-any.whl

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 (54) hide show
  1. lgit/__init__.py +75 -0
  2. lgit/__main__.py +8 -0
  3. lgit/analysis.py +326 -0
  4. lgit/api.py +1077 -0
  5. lgit/cache.py +338 -0
  6. lgit/changelog.py +523 -0
  7. lgit/cli.py +1104 -0
  8. lgit/compose.py +2110 -0
  9. lgit/config.py +437 -0
  10. lgit/diffing.py +384 -0
  11. lgit/errors.py +137 -0
  12. lgit/git.py +852 -0
  13. lgit/map_reduce.py +508 -0
  14. lgit/markdown_output.py +709 -0
  15. lgit/models.py +924 -0
  16. lgit/normalization.py +411 -0
  17. lgit/patch.py +784 -0
  18. lgit/profile.py +426 -0
  19. lgit/py.typed +0 -0
  20. lgit/repo.py +287 -0
  21. lgit/resources/__init__.py +1 -0
  22. lgit/resources/commit_types.json +242 -0
  23. lgit/resources/prompts/analysis/default.md +237 -0
  24. lgit/resources/prompts/analysis/markdown.md +112 -0
  25. lgit/resources/prompts/changelog/default.md +89 -0
  26. lgit/resources/prompts/changelog/markdown.md +60 -0
  27. lgit/resources/prompts/compose-bind/default.md +40 -0
  28. lgit/resources/prompts/compose-bind/markdown.md +41 -0
  29. lgit/resources/prompts/compose-intent/default.md +63 -0
  30. lgit/resources/prompts/compose-intent/markdown.md +59 -0
  31. lgit/resources/prompts/fast/default.md +46 -0
  32. lgit/resources/prompts/fast/markdown.md +51 -0
  33. lgit/resources/prompts/map/default.md +67 -0
  34. lgit/resources/prompts/map/markdown.md +63 -0
  35. lgit/resources/prompts/reduce/default.md +81 -0
  36. lgit/resources/prompts/reduce/markdown.md +68 -0
  37. lgit/resources/prompts/summary/default.md +74 -0
  38. lgit/resources/prompts/summary/markdown.md +77 -0
  39. lgit/resources/validation_data.json +1 -0
  40. lgit/rewrite.py +392 -0
  41. lgit/style.py +295 -0
  42. lgit/templates.py +385 -0
  43. lgit/testing/__init__.py +62 -0
  44. lgit/testing/compare.py +57 -0
  45. lgit/testing/fixture.py +386 -0
  46. lgit/testing/report.py +201 -0
  47. lgit/testing/runner.py +256 -0
  48. lgit/tokens.py +90 -0
  49. lgit/validation.py +545 -0
  50. lgit_cli-3.7.0.dist-info/METADATA +288 -0
  51. lgit_cli-3.7.0.dist-info/RECORD +54 -0
  52. lgit_cli-3.7.0.dist-info/WHEEL +4 -0
  53. lgit_cli-3.7.0.dist-info/entry_points.txt +2 -0
  54. lgit_cli-3.7.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,59 @@
1
+ You are a commit composer. Plan atomic commits from staged changes by grouping related hunks.
2
+
3
+ <context>
4
+ Return your groups in a markdown-like format where each group defines a standalone, buildable commit. Groups may have dependencies on other groups.
5
+ </context>
6
+
7
+ <instructions>
8
+ 1. Each group is identified by a group ID (G1, G2, G3, etc.)
9
+ 2. Each group has one commit type (from the `<commit_types>` list) and optional scope
10
+ 3. Groups are independent when possible; use dependencies for strict ordering
11
+ 4. Return 1–5 groups (or the requested maximum)
12
+ 5. Every provided file ID must appear in at least one group
13
+
14
+ Format rules:
15
+ - `G1 := type(scope): rationale` — group definition
16
+ - `G2 <- G1` — G2 depends on G1
17
+ - `Files:` section lists file assignments
18
+ - `- GN: file1, file2, file3` — files in group GN
19
+ </instructions>
20
+
21
+ <output_format>
22
+ You MUST return the result in this format WITHOUT the fences:
23
+ ```
24
+ G1 := feat(api): add authentication endpoints
25
+ G2 := test(api): add comprehensive tests
26
+ G3 := docs(api): document new endpoints
27
+
28
+ G2 <- G1
29
+ G3 <- G1
30
+
31
+ Files:
32
+ - G1: src/auth.rs, src/models.rs
33
+ - G2: tests/auth.test.ts
34
+ - G3: docs/API.md
35
+ ```
36
+ </output_format>
37
+
38
+ ======USER=======
39
+ <planning_limits>
40
+ max_commits: {{ max_commits }}
41
+ </planning_limits>
42
+
43
+ <planning_targets>
44
+ {{ planning_targets }}
45
+ </planning_targets>
46
+
47
+ {% if types_description %}
48
+ <commit_types>
49
+ {{ types_description }}
50
+ </commit_types>
51
+ {% endif %}
52
+
53
+ <git_stat>
54
+ {{ stat }}
55
+ </git_stat>
56
+
57
+ <snapshot>
58
+ {{ snapshot_summary }}
59
+ </snapshot>
@@ -0,0 +1,46 @@
1
+ You are a senior engineer writing a conventional commit message.
2
+
3
+ Produce exactly one `create_fast_commit` call with only `type`, optional `scope`, `summary`, and `details`.
4
+
5
+ Rules:
6
+ - Use the supplied `stat`, `scope_candidates`, `user_context`, and `diff`. Treat `diff` as the source of truth; use the other inputs only as hints.
7
+ - `type`: choose the best conventional commit type for the dominant change. When `<commit_types>` guidance is provided, follow its descriptions, notes, and disambiguation rules — they override your priors (e.g. prompt/template files under `prompts/` are functional changes, not `docs`).
8
+ - `scope`: use a narrow lowercase module/component only when the diff clearly supports it. Prefer `scope_candidates` when helpful. Use `null` if unclear, cross-cutting, repo-wide, or if no single scope covers most of the change.
9
+ - `summary`: specific past-tense phrase, no type prefix, no trailing period, and at most 72 characters.
10
+ - `details`: 0-3 past-tense sentences, each ending with a period. Include only material changes that matter to a reader; skip renames, imports, formatting, and incidental churn.
11
+ - If the diff is mixed or noisy, summarize the main cohesive change and keep the scope conservative rather than guessing.
12
+ - Keep the message compact. Do not pad with extra detail just to use the full budget.
13
+ - Do not invent behavior, file contents, or reasons that are not visible in the diff.
14
+
15
+ Before finalizing, self-check:
16
+ - Does the summary fit the length and tense rules?
17
+ - Does the type match the actual change?
18
+ - Is the scope justified, or should it be `null`?
19
+ - Are the details within 0-3 and limited to meaningful changes?
20
+ - Are all claims grounded in the provided diff?
21
+
22
+ Examples:
23
+ - added TLS support for gRPC connections
24
+ - fixed race condition in worker pool shutdown
25
+
26
+ ======USER=======
27
+
28
+ <file_changes>
29
+ {{ stat }}
30
+ </file_changes>
31
+
32
+ {% if scope_candidates %}<scope_candidates>
33
+ {{ scope_candidates }}
34
+ </scope_candidates>
35
+ {% endif %}
36
+ {% if types_description %}<commit_types>
37
+ {{ types_description }}
38
+ </commit_types>
39
+ {% endif %}
40
+ {% if user_context %}<user_context>
41
+ {{ user_context }}
42
+ </user_context>
43
+ {% endif %}
44
+ <diff>
45
+ {{ diff }}
46
+ </diff>
@@ -0,0 +1,51 @@
1
+ You are a senior engineer writing a conventional commit message. Return your response in markdown format for easier parsing.
2
+
3
+ Rules:
4
+ - Use the supplied `stat`, `scope_candidates`, `user_context`, and `diff`. Treat `diff` as the source of truth; use the other inputs only as hints.
5
+ - `type`: choose the best conventional commit type for the dominant change. When `<commit_types>` guidance is provided, follow its descriptions, notes, and disambiguation rules — they override your priors (e.g. prompt/template files under `prompts/` are functional changes, not `docs`).
6
+ - `scope`: use a narrow lowercase module/component only when the diff clearly supports it. Prefer `scope_candidates` when helpful. Omit the `(scope)` if unclear, cross-cutting, repo-wide, or if no single scope covers most of the change.
7
+ - `summary`: specific past-tense phrase, no type prefix, no trailing period, and at most 72 characters.
8
+ - `details`: 0-3 past-tense sentences, each ending with a period. Include only material changes that matter to a reader; skip renames, imports, formatting, and incidental churn.
9
+ - If the diff is mixed or noisy, summarize the main cohesive change and keep the scope conservative rather than guessing.
10
+ - Do not invent behavior, file contents, or reasons that are not visible in the diff.
11
+
12
+ Before finalizing, self-check:
13
+ - Does the summary fit the length and tense rules?
14
+ - Does the type match the actual change?
15
+ - Is the scope justified, or should it be omitted?
16
+ - Are the details within 0-3 and limited to meaningful changes?
17
+ - Are all claims grounded in the provided diff?
18
+
19
+ <output_format>
20
+ You MUST return the result in this format WITHOUT the fences:
21
+ ```
22
+ # type(scope): summary
23
+
24
+ - detail 1
25
+ - detail 2
26
+ ```
27
+
28
+ Omit the `(scope)` if there is no clear scope. Omit the detail bullets entirely if there are no material details.
29
+ </output_format>
30
+
31
+ ======USER=======
32
+
33
+ <file_changes>
34
+ {{ stat }}
35
+ </file_changes>
36
+
37
+ {% if scope_candidates %}<scope_candidates>
38
+ {{ scope_candidates }}
39
+ </scope_candidates>
40
+ {% endif %}
41
+ {% if types_description %}<commit_types>
42
+ {{ types_description }}
43
+ </commit_types>
44
+ {% endif %}
45
+ {% if user_context %}<user_context>
46
+ {{ user_context }}
47
+ </user_context>
48
+ {% endif %}
49
+ <diff>
50
+ {{ diff }}
51
+ </diff>
@@ -0,0 +1,67 @@
1
+ <role>Expert code analyst extracting grounded observations from a batch of file diffs.</role>
2
+
3
+ <instructions>
4
+ Extract only factual observations supported by each current file diff. Be precise.
5
+ Use <related_files> only to resolve names or references; do not add observations about those files.
6
+
7
+ For each `<file>` in `<files>`:
8
+ 1. Return 0-5 observations for that file
9
+ 2. Use past-tense verb + specific target + optional purpose
10
+ 3. Keep each observation under 100 characters
11
+ 4. Cover meaningful changes in that file; omit formatting, comment-only, and import-order changes
12
+ 5. Consolidate related edits when they belong together, but do not guess or overgeneralize
13
+ 6. Do not mention commit type, scope, changelog, or any reduce-phase classification
14
+ </instructions>
15
+
16
+ <scope>
17
+ Include: functions, methods, types, API changes, behavior/logic changes, error handling, performance, security.
18
+
19
+ Exclude: import reordering, whitespace/formatting, comment-only changes, debug statements.
20
+ </scope>
21
+
22
+ <output_format>
23
+ Return exactly one `create_file_observations` payload with a `files` array.
24
+
25
+ Each item must:
26
+ - Use `path` exactly as shown in the input `<file path="...">`
27
+ - Use `observations` as an array of strings
28
+ - Include every input file, using an empty array when a file has no relevant observations
29
+
30
+ Example:
31
+ {
32
+ "files": [
33
+ {
34
+ "path": "src/config.rs",
35
+ "observations": ["added TOML configuration loading"]
36
+ },
37
+ {
38
+ "path": "src/main.rs",
39
+ "observations": ["changed CLI parsing to accept config paths"]
40
+ }
41
+ ]
42
+ }
43
+ </output_format>
44
+
45
+ <verification>
46
+ - Every observation is directly supported by that file's diff
47
+ - No observation depends on `<related_files>` alone
48
+ - No duplicate, trivial, or classification-oriented observations
49
+ </verification>
50
+
51
+ Observations only. Reduce phase handles classification and synthesis.
52
+
53
+ ======USER=======
54
+
55
+ <files>
56
+ {% for f in files %}
57
+ <file path="{{ f.path }}">
58
+ {{ f.diff }}
59
+ </file>
60
+ {% endfor %}
61
+ </files>
62
+ {% if context_header %}
63
+
64
+ <related_files>
65
+ {{ context_header }}
66
+ </related_files>
67
+ {% endif %}
@@ -0,0 +1,63 @@
1
+ <role>Expert code analyst extracting grounded observations from a batch of file diffs.</role>
2
+
3
+ <instructions>
4
+ Extract only factual observations supported by each current file diff. Be precise.
5
+ Use <related_files> only to resolve names or references; do not add observations about those files.
6
+
7
+ For each `<file>` in `<files>`:
8
+ 1. Return 0-5 observations for that file
9
+ 2. Use past-tense verb + specific target + optional purpose
10
+ 3. Keep each observation under 100 characters
11
+ 4. Cover meaningful changes in that file; omit formatting, comment-only, and import-order changes
12
+ 5. Consolidate related edits when they belong together, but do not guess or overgeneralize
13
+ 6. Do not mention commit type, scope, changelog, or any reduce-phase classification
14
+ </instructions>
15
+
16
+ <scope>
17
+ Include: functions, methods, types, API changes, behavior/logic changes, error handling, performance, security.
18
+
19
+ Exclude: import reordering, whitespace/formatting, comment-only changes, debug statements.
20
+ </scope>
21
+
22
+ <output_format>
23
+ You MUST return the result in this format WITHOUT the fences:
24
+ ```
25
+ # src/config.rs
26
+ - added TOML configuration loading
27
+ - changed default timeout to 30s
28
+
29
+ # src/main.rs
30
+ - changed CLI parsing to accept config paths
31
+
32
+ # src/empty.rs
33
+ ```
34
+
35
+ Rules:
36
+ - One `# ` header per input file, using the `path` exactly as shown in `<file path="...">`.
37
+ - List observations as `-` bullets under each header.
38
+ - Include EVERY input file. If a file has no relevant observations, emit just its `# ` header with no bullets.
39
+ </output_format>
40
+
41
+ <verification>
42
+ - Every observation is directly supported by that file's diff
43
+ - No observation depends on `<related_files>` alone
44
+ - No duplicate, trivial, or classification-oriented observations
45
+ </verification>
46
+
47
+ Observations only. Reduce phase handles classification and synthesis.
48
+
49
+ ======USER=======
50
+
51
+ <files>
52
+ {% for f in files %}
53
+ <file path="{{ f.path }}">
54
+ {{ f.diff }}
55
+ </file>
56
+ {% endfor %}
57
+ </files>
58
+ {% if context_header %}
59
+
60
+ <related_files>
61
+ {{ context_header }}
62
+ </related_files>
63
+ {% endif %}
@@ -0,0 +1,81 @@
1
+ You are a senior engineer synthesizing map-phase file observations into one conventional commit analysis.
2
+
3
+ <context>
4
+ Given retrieved observations, git stat, and scope candidates, produce one unified commit classification with changelog metadata.
5
+ </context>
6
+
7
+ <instructions>
8
+ Determine:
9
+ 1. TYPE: one classification for the entire commit.
10
+ 2. SCOPE: one primary component, or null if the change is multi-component or unclear.
11
+ 3. SUMMARY: one concise past-tense commit summary without `type(scope):` prefix.
12
+ 4. DETAILS: 3-4 concise summary points, max 6.
13
+ 5. ISSUE_REFS: only issue references explicitly supported by the observations; otherwise return an empty array.
14
+ 6. CHANGELOG: metadata for user-visible details only.
15
+
16
+ Base the answer only on the provided observations, stat, and scope candidates. Do not invent intent, impact, or file changes that are not supported.
17
+ </instructions>
18
+
19
+ <scope_rules>
20
+ - Use `scope_candidates` as the primary source.
21
+ - Use the dominant component only if the evidence clearly concentrates there; otherwise return null.
22
+ - Use null when changes span multiple components, the best scope is speculative, or no candidate is well supported.
23
+ - Valid scopes are short component names only, ideally one word and at most two words joined by `-`.
24
+ - Shorten long candidates to the most distinctive supported segment, not a fabricated abbreviation.
25
+ </scope_rules>
26
+
27
+ <output_format>
28
+ Return exactly one `create_conventional_analysis` payload with only `type`, optional `scope`, `summary`, `details`, and `issue_refs`.
29
+
30
+ The `summary` must:
31
+ - Start with a past-tense verb.
32
+ - Stay at or under 72 characters.
33
+ - Omit the `type(scope):` prefix and trailing period.
34
+
35
+ Each detail point must:
36
+ - Start with a past-tense verb.
37
+ - Stay under 120 characters and end with a period.
38
+ - Group related cross-file changes when they describe the same outcome.
39
+
40
+ Priority order: user-visible behavior > performance/security > architecture > internal implementation.
41
+
42
+ For changelog metadata:
43
+ - Use `changelog_category` only for user-visible details.
44
+ - Set `user_visible` to true for features, user-facing bugs, breaking changes, and security fixes.
45
+ - Leave internal-only details as not user-visible.
46
+
47
+ For `issue_refs`:
48
+ - Include only references explicitly present in the observations.
49
+ - Return `[]` when no supported issue reference is present.
50
+
51
+ Do not add prose or extra keys.
52
+ </output_format>
53
+
54
+ <synthesis_rules>
55
+ - Produce 3-4 strong grouped details when possible; use the 6-item limit only for genuinely distinct outcomes.
56
+ - Synthesize repeated file observations into the shared behavior, abstraction, or user-visible outcome they support.
57
+ - Prefer broader, evidence-backed details over enumerating files, hunks, or one observation per file.
58
+ - If observations conflict, reconcile them conservatively using the most specific and repeated evidence.
59
+ - If the diff stat shows breadth that observations do not explain, mention the breadth only at the level the evidence supports.
60
+ - Do a final pass before returning to confirm the type, scope, and detail points all agree with the evidence.
61
+ </synthesis_rules>
62
+
63
+ ======USER=======
64
+ {% if types_description %}
65
+
66
+ <type_definitions>
67
+ {{ types_description }}
68
+ </type_definitions>
69
+ {% endif %}
70
+
71
+ <observations>
72
+ {{ observations }}
73
+ </observations>
74
+
75
+ <diff_statistics>
76
+ {{ stat }}
77
+ </diff_statistics>
78
+
79
+ <scope_candidates>
80
+ {{ scope_candidates }}
81
+ </scope_candidates>
@@ -0,0 +1,68 @@
1
+ You are a senior engineer synthesizing map-phase file observations into one conventional commit analysis.
2
+
3
+ <context>
4
+ Given retrieved observations, git stat, and scope candidates, produce one unified commit classification. Return your response in markdown format for easier parsing.
5
+ </context>
6
+
7
+ <instructions>
8
+ Determine:
9
+ 1. TYPE: one classification for the entire commit.
10
+ 2. SCOPE: one primary component, or omit if the change is multi-component or unclear.
11
+ 3. SUMMARY: one concise past-tense commit summary without `type(scope):` prefix.
12
+ 4. DETAILS: 3-4 concise summary points, max 6.
13
+ 5. ISSUE_REFS: only issue references explicitly supported by the observations.
14
+
15
+ Base the answer only on the provided observations, stat, and scope candidates. Do not invent intent, impact, or file changes that are not supported.
16
+ </instructions>
17
+
18
+ <scope_rules>
19
+ - Use `scope_candidates` as the primary source.
20
+ - Use the dominant component only if the evidence clearly concentrates there; otherwise omit scope.
21
+ - Omit scope when changes span multiple components, the best scope is speculative, or no candidate is well supported.
22
+ - Valid scopes are short component names only, ideally one word and at most two words joined by `-`.
23
+ - Shorten long candidates to the most distinctive supported segment, not a fabricated abbreviation.
24
+ </scope_rules>
25
+
26
+ <synthesis_rules>
27
+ - Produce 3-4 strong grouped details when possible; use the 6-item limit only for genuinely distinct outcomes.
28
+ - Synthesize repeated file observations into the shared behavior, abstraction, or user-visible outcome they support.
29
+ - Prefer broader, evidence-backed details over enumerating files, hunks, or one observation per file.
30
+ - If observations conflict, reconcile them conservatively using the most specific and repeated evidence.
31
+ - The summary starts with a past-tense verb, stays at or under 72 characters, and omits the prefix and trailing period.
32
+ - Each detail starts with a past-tense verb and ends with a period.
33
+ </synthesis_rules>
34
+
35
+ <output_format>
36
+ You MUST return the result in this format WITHOUT the fences:
37
+ ```
38
+ # type(scope): summary
39
+
40
+ - detail 1
41
+ - detail 2
42
+ - detail 3
43
+
44
+ Fixes: #123, #456
45
+ ```
46
+
47
+ Omit the `(scope)` if there is no clear scope. Omit the `Fixes:` line if there are no supported issue references.
48
+ </output_format>
49
+
50
+ ======USER=======
51
+ {% if types_description %}
52
+
53
+ <type_definitions>
54
+ {{ types_description }}
55
+ </type_definitions>
56
+ {% endif %}
57
+
58
+ <observations>
59
+ {{ observations }}
60
+ </observations>
61
+
62
+ <diff_statistics>
63
+ {{ stat }}
64
+ </diff_statistics>
65
+
66
+ <scope_candidates>
67
+ {{ scope_candidates }}
68
+ </scope_candidates>
@@ -0,0 +1,74 @@
1
+ You are a commit message specialist generating concise, specific descriptions.
2
+
3
+ <context>
4
+ Output only the description part that follows a conventional commit prefix `type(scope):`.
5
+ Use the max character limit from the user message. No type/scope prefix, no trailing period, no markdown, no quotes.
6
+ </context>
7
+
8
+ <instructions>
9
+ 1. Start with a lowercase past-tense verb that does not repeat the commit type token.
10
+ 2. Write an umbrella description for the whole changeset, not a restatement of one supporting detail.
11
+ 3. Name the shared subsystem, behavior, or user-visible outcome; use a narrow component only when it dominates both the detail points and diff stat.
12
+ 4. Include the reason only when it sharpens the intent.
13
+ 5. Keep the summary to one cohesive headline.
14
+ </instructions>
15
+
16
+ <grounding>
17
+ Use the detail points as supporting evidence and body-bullet context, not as candidate titles to copy.
18
+ Use the diff stat to confirm dominant files, area of change, and scale.
19
+ When multiple detail points exist, do not merely copy or narrowly paraphrase any single detail point; synthesize the shared behavior or intent across them.
20
+ If details span multiple components, prefer their shared purpose over a narrow file or component title unless one component clearly dominates.
21
+ If the details and stat disagree, trust the supplied details and avoid inventing facts.
22
+ </grounding>
23
+
24
+ <verification>
25
+ Before responding, silently check that the summary:
26
+ - fits the character limit from the user message
27
+ - reads as the description after `type(scope):`
28
+ - summarizes the whole changeset rather than one supporting detail
29
+ - stays grounded in the provided detail points and diff stat
30
+ - does not copy or narrowly paraphrase one detail point when multiple details exist
31
+ - uses a past-tense verb and omits the prefix, period, and filler words
32
+ </verification>
33
+
34
+ <verb_reference>
35
+ | Type | Use instead |
36
+ |----------|-------------------------------------------------|
37
+ | feat | added, introduced, implemented, enabled |
38
+ | fix | corrected, resolved, patched, addressed |
39
+ | refactor | restructured, reorganized, migrated, simplified |
40
+ | perf | optimized, reduced, eliminated, accelerated |
41
+ | docs | documented, clarified, expanded |
42
+ | build | upgraded, pinned, configured |
43
+ | chore | cleaned, removed, renamed, organized |
44
+ </verb_reference>
45
+
46
+ <banned_words>
47
+ comprehensive, various, several, improved, enhanced, quickly, simply, basically, this change, this commit, now
48
+ </banned_words>
49
+
50
+ <output_format>
51
+ Output the description text only.
52
+ </output_format>
53
+
54
+ ======USER=======
55
+ <commit_metadata>
56
+ commit_type: {{ commit_type }}
57
+ scope: {% if scope %}{{ scope }}{% else %}(none){% endif %}
58
+ max_summary_chars: {{ chars }}
59
+ expected_prefix_context: {{ commit_type }}{% if scope %}({{ scope }}){% endif %}:
60
+ </commit_metadata>
61
+ {% if user_context %}
62
+
63
+ <user_context>
64
+ {{ user_context }}
65
+ </user_context>
66
+ {% endif %}
67
+
68
+ <detail_points>
69
+ {{ details }}
70
+ </detail_points>
71
+
72
+ <diff_stat>
73
+ {{ stat }}
74
+ </diff_stat>
@@ -0,0 +1,77 @@
1
+ You are a commit message specialist generating concise, specific descriptions.
2
+
3
+ <context>
4
+ Return the description as plain text wrapped in `<summary>...</summary>` tags.
5
+ Use the max character limit from the user message. No type/scope prefix, no trailing period, no markdown, no quotes.
6
+ </context>
7
+
8
+ <instructions>
9
+ 1. Start with a lowercase past-tense verb that does not repeat the commit type token.
10
+ 2. Write an umbrella description for the whole changeset, not a restatement of one supporting detail.
11
+ 3. Name the shared subsystem, behavior, or user-visible outcome; use a narrow component only when it dominates both the detail points and diff stat.
12
+ 4. Include the reason only when it sharpens the intent.
13
+ 5. Keep the summary to one cohesive headline.
14
+ </instructions>
15
+
16
+ <grounding>
17
+ Use the detail points as supporting evidence and body-bullet context, not as candidate titles to copy.
18
+ Use the diff stat to confirm dominant files, area of change, and scale.
19
+ When multiple detail points exist, do not merely copy or narrowly paraphrase any single detail point; synthesize the shared behavior or intent across them.
20
+ If details span multiple components, prefer their shared purpose over a narrow file or component title unless one component clearly dominates.
21
+ If the details and stat disagree, trust the supplied details and avoid inventing facts.
22
+ </grounding>
23
+
24
+ <verification>
25
+ Before responding, silently check that the summary:
26
+ - fits the character limit from the user message
27
+ - reads as the description after `type(scope):`
28
+ - summarizes the whole changeset rather than one supporting detail
29
+ - stays grounded in the provided detail points and diff stat
30
+ - does not copy or narrowly paraphrase one detail point when multiple details exist
31
+ - uses a past-tense verb and omits the prefix, period, and filler words
32
+ </verification>
33
+
34
+ <verb_reference>
35
+ | Type | Use instead |
36
+ |----------|-------------------------------------------------|
37
+ | feat | added, introduced, implemented, enabled |
38
+ | fix | corrected, resolved, patched, addressed |
39
+ | refactor | restructured, reorganized, migrated, simplified |
40
+ | perf | optimized, reduced, eliminated, accelerated |
41
+ | docs | documented, clarified, expanded |
42
+ | build | upgraded, pinned, configured |
43
+ | chore | cleaned, removed, renamed, organized |
44
+ </verb_reference>
45
+
46
+ <banned_words>
47
+ comprehensive, various, several, improved, enhanced, quickly, simply, basically, this change, this commit, now
48
+ </banned_words>
49
+
50
+ <output_format>
51
+ You MUST return the result in this format WITHOUT the fences:
52
+ ```
53
+ <summary>description text only</summary>
54
+ ```
55
+ </output_format>
56
+
57
+ ======USER=======
58
+ <commit_metadata>
59
+ commit_type: {{ commit_type }}
60
+ scope: {% if scope %}{{ scope }}{% else %}(none){% endif %}
61
+ max_summary_chars: {{ chars }}
62
+ expected_prefix_context: {{ commit_type }}{% if scope %}({{ scope }}){% endif %}:
63
+ </commit_metadata>
64
+ {% if user_context %}
65
+
66
+ <user_context>
67
+ {{ user_context }}
68
+ </user_context>
69
+ {% endif %}
70
+
71
+ <detail_points>
72
+ {{ details }}
73
+ </detail_points>
74
+
75
+ <diff_stat>
76
+ {{ stat }}
77
+ </diff_stat>
@@ -0,0 +1 @@
1
+ {"_comment":"Single source of truth for src/validation.rs lookup tables. Codegen'd into static slices by build.rs. Keep verbs lowercase; past_tense values must be genuine single-token past forms.","past_tense":[["add","added"],["fix","fixed"],["update","updated"],["remove","removed"],["replace","replaced"],["improve","improved"],["implement","implemented"],["migrate","migrated"],["rename","renamed"],["move","moved"],["merge","merged"],["extract","extracted"],["restructure","restructured"],["reorganize","reorganized"],["consolidate","consolidated"],["simplify","simplified"],["optimize","optimized"],["document","documented"],["test","tested"],["change","changed"],["introduce","introduced"],["deprecate","deprecated"],["delete","deleted"],["correct","corrected"],["enhance","enhanced"],["revert","reverted"],["refactor","refactored"],["harden","hardened"],["bind","bound"],["guard","guarded"],["defend","defended"],["secure","secured"],["isolate","isolated"],["intercept","intercepted"],["unlock","unlocked"],["block","blocked"],["bypass","bypassed"],["enable","enabled"],["disable","disabled"],["configure","configured"],["adjust","adjusted"],["align","aligned"],["normalize","normalized"],["standardize","standardized"],["format","formatted"],["clean","cleaned"],["reset","reset"],["sync","synced"],["init","initialized"],["install","installed"],["skip","skipped"],["resolve","resolved"],["prevent","prevented"],["route","routed"],["defer","deferred"],["surface","surfaced"],["drop","dropped"],["avoid","avoided"],["switch","switched"],["abort","aborted"],["stop","stopped"],["start","started"],["resume","resumed"],["retry","retried"],["expose","exposed"],["strip","stripped"],["scope","scoped"],["check","checked"],["pass","passed"],["ignore","ignored"],["force","forced"],["load","loaded"],["allow","allowed"],["ensure","ensured"],["track","tracked"],["cap","capped"],["return","returned"],["convert","converted"],["verify","verified"],["validate","validated"],["create","created"],["filter","filtered"],["enforce","enforced"],["integrate","integrated"],["render","rendered"],["inject","injected"],["register","registered"],["parse","parsed"],["clear","cleared"],["wrap","wrapped"],["prune","pruned"],["lower","lowered"],["map","mapped"],["populate","populated"],["scrub","scrubbed"],["style","styled"],["truncate","truncated"],["detect","detected"],["apply","applied"],["prefer","preferred"],["discover","discovered"],["evict","evicted"],["structure","structured"],["shorten","shortened"],["annotate","annotated"],["display","displayed"],["transfer","transferred"],["close","closed"],["reorder","reordered"],["rebuild","rebuilt"],["rewrite","rewrote"],["rerun","reran"],["clarify","clarified"],["restore","restored"],["make","made"],["build","built"],["write","wrote"],["run","ran"],["instrument","instrumented"],["regulate","regulated"],["demote","demoted"],["promote","promoted"],["elevate","elevated"],["expand","expanded"],["extend","extended"],["compress","compressed"],["transpile","transpiled"],["decorate","decorated"],["dampen","dampened"],["coerce","coerced"],["collide","collided"],["position","positioned"],["pad","padded"],["pipe","piped"],["instantiate","instantiated"],["group","grouped"],["gather","gathered"],["fail","failed"],["exceed","exceeded"],["invert","inverted"],["bump","bumped"],["use","used"],["preserve","preserved"],["handle","handled"],["support","supported"],["keep","kept"],["show","showed"],["export","exported"],["import","imported"],["read","read"],["set","set"],["put","put"],["split","split"],["spread","spread"],["cut","cut"],["hit","hit"],["hurt","hurt"],["shut","shut"],["let","let"],["bet","bet"],["cast","cast"],["cost","cost"],["quit","quit"],["undo","undid"],["freeze","froze"],["steal","stole"],["stick","stuck"],["strike","struck"],["swing","swung"],["tear","tore"],["throw","threw"],["wake","woke"],["wear","wore"],["weave","wove"],["weep","wept"],["wind","wound"],["win","won"],["withdraw","withdrew"],["breed","bred"],["bring","brought"],["buy","bought"],["catch","caught"],["choose","chose"],["deal","dealt"],["dig","dug"],["feed","fed"],["flee","fled"],["fling","flung"],["fly","flew"],["grow","grew"],["hang","hung"],["lead","led"],["lend","lent"],["light","lit"],["pay","paid"],["ring","rang"],["rise","rose"],["shake","shook"],["sling","slung"],["speak","spoke"],["spring","sprang"],["sting","stung"],["stink","stank"],["swear","swore"],["take","took"],["give","gave"],["find","found"],["hold","held"],["tell","told"],["sell","sold"],["stand","stood"],["understand","understood"],["become","became"],["begin","began"],["fight","fought"],["seek","sought"],["come","came"],["do","did"],["get","got"],["have","had"],["know","knew"],["meet","met"],["see","saw"],["say","said"],["sit","sat"],["beat","beat"],["bend","bent"],["blow","blew"],["cling","clung"],["creep","crept"],["arise","arose"],["override","overrode"],["shrink","shrank"],["sleep","slept"],["slide","slid"],["sweep","swept"],["teach","taught"],["think","thought"],["patch","patched"],["tweak","tweaked"],["refine","refined"],["polish","polished"],["streamline","streamlined"],["decouple","decoupled"],["encapsulate","encapsulated"],["modularize","modularized"],["generalize","generalized"],["specialize","specialized"],["parameterize","parameterized"],["serialize","serialized"],["deserialize","deserialized"],["cache","cached"],["memoize","memoized"],["batch","batched"],["throttle","throttled"],["debounce","debounced"],["paginate","paginated"],["sort","sorted"],["deduplicate","deduplicated"],["flatten","flattened"],["nest","nested"],["rebase","rebased"],["squash","squashed"],["stash","stashed"],["tag","tagged"],["label","labeled"],["comment","commented"],["uncomment","uncommented"],["lint","linted"],["vendor","vendored"],["pin","pinned"],["unpin","unpinned"],["lock","locked"],["downgrade","downgraded"],["upgrade","upgraded"],["backport","backported"],["scaffold","scaffolded"],["bootstrap","bootstrapped"],["provision","provisioned"],["deploy","deployed"],["redeploy","redeployed"],["ship","shipped"],["publish","published"],["unpublish","unpublished"],["draft","drafted"],["finalize","finalized"],["stabilize","stabilized"],["retire","retired"],["archive","archived"],["recover","recovered"],["repair","repaired"],["mock","mocked"],["stub","stubbed"],["benchmark","benchmarked"],["profile","profiled"],["trace","traced"],["log","logged"],["debug","debugged"],["dump","dumped"],["print","printed"],["emit","emitted"],["subscribe","subscribed"],["unsubscribe","unsubscribed"],["notify","notified"],["alert","alerted"],["warn","warned"],["raise","raised"],["panic","panicked"],["swallow","swallowed"],["propagate","propagated"],["connect","connected"],["disconnect","disconnected"],["reconnect","reconnected"],["listen","listened"],["accept","accepted"],["request","requested"],["respond","responded"],["redirect","redirected"],["proxy","proxied"],["forward","forwarded"],["relay","relayed"],["stream","streamed"],["buffer","buffered"],["flush","flushed"],["drain","drained"],["queue","queued"],["dequeue","dequeued"],["enqueue","enqueued"],["poll","polled"],["push","pushed"],["pop","popped"],["peek","peeked"],["fetch","fetched"],["pull","pulled"],["receive","received"],["transmit","transmitted"],["encode","encoded"],["decode","decoded"],["encrypt","encrypted"],["decrypt","decrypted"],["hash","hashed"],["sign","signed"],["authenticate","authenticated"],["authorize","authorized"],["insert","inserted"],["upsert","upserted"],["query","queried"],["index","indexed"],["reindex","reindexed"],["join","joined"],["aggregate","aggregated"],["reduce","reduced"],["fold","folded"],["accumulate","accumulated"],["count","counted"],["sum","summed"],["average","averaged"],["compute","computed"],["calculate","calculated"],["derive","derived"],["infer","inferred"],["deduce","deduced"],["reconcile","reconciled"],["diff","diffed"],["compare","compared"],["match","matched"],["locate","located"],["scan","scanned"],["traverse","traversed"],["walk","walked"],["iterate","iterated"],["loop","looped"],["recurse","recursed"],["spawn","spawned"],["fork","forked"],["kill","killed"],["terminate","terminated"],["halt","halted"],["suspend","suspended"],["pause","paused"],["schedule","scheduled"],["dispatch","dispatched"],["delegate","delegated"],["await","awaited"],["unblock","unblocked"],["yield","yielded"],["detach","detached"],["attach","attached"],["mount","mounted"],["unmount","unmounted"],["remount","remounted"],["unregister","unregistered"],["deregister","deregistered"],["reveal","revealed"],["toggle","toggled"],["focus","focused"],["blur","blurred"],["scroll","scrolled"],["zoom","zoomed"],["drag","dragged"],["click","clicked"],["hover","hovered"],["swipe","swiped"],["animate","animated"],["transition","transitioned"],["fade","faded"],["highlight","highlighted"],["underline","underlined"],["color","colored"],["paint","painted"],["compile","compiled"],["link","linked"],["assemble","assembled"],["package","packaged"],["bundle","bundled"],["minify","minified"],["gate","gated"],["flag","flagged"],["version","versioned"],["namespace","namespaced"],["alias","aliased"],["relabel","relabeled"],["summarize","summarized"],["describe","described"],["explain","explained"],["illustrate","illustrated"],["demonstrate","demonstrated"],["trim","trimmed"],["fill","filled"],["seed","seeded"],["allocate","allocated"],["deallocate","deallocated"],["reserve","reserved"],["free","freed"],["dispose","disposed"],["recycle","recycled"],["reuse","reused"],["share","shared"],["clone","cloned"],["copy","copied"],["duplicate","duplicated"],["replicate","replicated"],["mirror","mirrored"],["snapshot","snapshotted"],["require","required"],["constrain","constrained"],["restrict","restricted"],["limit","limited"],["sanitize","sanitized"],["escape","escaped"],["unescape","unescaped"],["quote","quoted"],["unquote","unquoted"],["whitelist","whitelisted"],["blacklist","blacklisted"],["allowlist","allowlisted"],["denylist","denylisted"],["embed","embedded"],["shred","shredded"],["need","needed"],["speed","sped"],["proceed","proceeded"],["succeed","succeeded"],["heed","heeded"],["download","downloaded"],["upload","uploaded"],["overload","overloaded"],["reload","reloaded"],["initialize","initialized"],["capture","captured"],["release","released"],["wire","wired"],["rewire","rewired"],["head","headed"],["thread","threaded"],["flood","flooded"],["cloud","clouded"],["bleed","bled"],["trigger","triggered"],["silence","silenced"],["mute","muted"],["unmute","unmuted"],["rotate","rotated"],["expire","expired"],["invalidate","invalidated"],["refresh","refreshed"],["warm","warmed"],["prefetch","prefetched"],["prewarm","prewarmed"],["backfill","backfilled"],["checkpoint","checkpointed"],["replay","replayed"],["record","recorded"],["sample","sampled"],["measure","measured"],["meter","metered"],["audit","audited"],["monitor","monitored"],["observe","observed"],["watch","watched"],["inspect","inspected"],["assert","asserted"],["expect","expected"],["cover","covered"],["exercise","exercised"],["stress","stressed"],["fuzz","fuzzed"],["typecheck","typechecked"],["vet","vetted"],["hide","hid"],["draw","drew"],["bear","bore"],["lay","laid"],["leave","left"],["feel","felt"],["mean","meant"],["send","sent"],["spend","spent"],["lose","lost"],["grind","ground"],["slay","slew"],["shoot","shot"],["spin","spun"],["sink","sank"],["drink","drank"],["swim","swam"],["sing","sang"],["forget","forgot"],["forgive","forgave"],["mistake","mistook"],["overcome","overcame"],["redo","redid"],["remake","remade"],["retake","retook"],["foresee","foresaw"],["withhold","withheld"],["uphold","upheld"],["strive","strove"],["awake","awoke"],["bite","bit"],["ride","rode"],["drive","drove"],["dive","dove"],["fall","fell"],["break","broke"],["string","strung"],["wring","wrung"],["hear","heard"],["shine","shone"]],"irregular_past":["left","felt","meant","sent","spent","lost","slept","slid","swept","ground","slew","stank"],"ed_blocklist":["hundred","thousand","red","bed","wed","shed","feed","need","seed","speed","breed","bleed","exceed","proceed","succeed","heed","weed","indeed","deed","greed","creed","steed","reed","embed","shred","sled","hatred","kindred","naked","wicked","sacred","rugged","ragged","jagged","crooked"],"d_blocklist":["and","bad","bid","god","had","kid","lad","mad","mid","mud","nod","odd","old","pad","raid","said","sad","should","would","could","void","valid","solid","rapid","vivid","timid","lucid","acid","fluid","druid","afraid","abroad","instead","ahead","aboard","payload","android","hybrid","liquid","candid","splendid","good","food","mood","wood","hood","blood","brood","dead","bead","loud","proud","aloud","bread","avoid","lead","head","thread","download","upload","overload","reload","flood","cloud","load"],"code_extensions":["rs","c","cpp","cc","cxx","h","hpp","hxx","zig","nim","v","java","kt","kts","scala","groovy","clj","cljs","cs","fs","vb","js","ts","jsx","tsx","mjs","cjs","vue","svelte","astro","py","pyx","pxd","pyi","rb","rake","gemspec","php","go","swift","m","mm","lua","sh","bash","zsh","fish","ps1","psm1","bat","cmd","pl","pm","hs","lhs","ml","mli","elm","ex","exs","erl","hrl","gleam","lisp","cl","el","scm","rkt","jl","r","dart","cr","d","f","f90","f95","f03","f08","ada","adb","ads","cob","cbl","asm","s","sql","plsql","pro","re","rei","nix","tf","hcl","sol","move","cairo","wasm","wat","odin","jai","hare","roc","zir"],"doc_extensions":["md","mdx","markdown","adoc","asciidoc","rst","txt","org","tex","pod","rmd","wiki","textile","texi","texinfo","man","rdoc"],"filler_words":["comprehensive","better","various","several","numerous","powerful","seamless","robust","flexible","versatile","sophisticated","holistic","myriad","cutting-edge","state-of-the-art","world-class","best-in-class"],"meta_phrases":["this commit","this change","this pr","this patch","updated code","updated the","modified code","changed code","improved code","modified the","changed the","made changes","some changes","minor changes","misc changes","various changes","general changes","code changes","refactored code","added code","removed code"],"body_present_tense":["adds","fixes","updates","removes","changes","creates","refactors","implements","migrates","renames","moves","replaces","improves","merges","splits","extracts","restructures","reorganizes","consolidates","deletes","introduces","deprecates","corrects","enhances","reverts","optimizes","simplifies","documents","configures","enables","disables","resolves","prevents","handles","supports","exposes","validates","verifies","converts","parses","renders","registers","filters","enforces","integrates","wraps","returns","uses"]}