ace-git-commit 0.23.0
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.
- checksums.yaml +7 -0
- data/.ace-defaults/git/commit.yml +22 -0
- data/.ace-defaults/nav/protocols/guide-sources/ace-git-commit.yml +10 -0
- data/.ace-defaults/nav/protocols/prompt-sources/ace-git-commit.yml +19 -0
- data/.ace-defaults/nav/protocols/wfi-sources/ace-git-commit.yml +19 -0
- data/CHANGELOG.md +404 -0
- data/COMPARISON.md +176 -0
- data/LICENSE +21 -0
- data/README.md +44 -0
- data/Rakefile +14 -0
- data/exe/ace-git-commit +13 -0
- data/handbook/guides/version-control-system-message.g.md +507 -0
- data/handbook/prompts/git-commit.md +22 -0
- data/handbook/prompts/git-commit.system.md +150 -0
- data/handbook/skills/as-git-commit/SKILL.md +57 -0
- data/handbook/workflow-instructions/git/commit.wf.md +75 -0
- data/lib/ace/git_commit/atoms/git_executor.rb +62 -0
- data/lib/ace/git_commit/atoms/gitignore_checker.rb +118 -0
- data/lib/ace/git_commit/cli/commands/commit.rb +147 -0
- data/lib/ace/git_commit/cli.rb +23 -0
- data/lib/ace/git_commit/models/commit_group.rb +53 -0
- data/lib/ace/git_commit/models/commit_options.rb +75 -0
- data/lib/ace/git_commit/models/split_commit_result.rb +60 -0
- data/lib/ace/git_commit/models/stage_result.rb +71 -0
- data/lib/ace/git_commit/molecules/commit_grouper.rb +123 -0
- data/lib/ace/git_commit/molecules/commit_summarizer.rb +43 -0
- data/lib/ace/git_commit/molecules/diff_analyzer.rb +111 -0
- data/lib/ace/git_commit/molecules/file_stager.rb +153 -0
- data/lib/ace/git_commit/molecules/message_generator.rb +438 -0
- data/lib/ace/git_commit/molecules/path_resolver.rb +365 -0
- data/lib/ace/git_commit/molecules/split_commit_executor.rb +272 -0
- data/lib/ace/git_commit/organisms/commit_orchestrator.rb +330 -0
- data/lib/ace/git_commit/version.rb +7 -0
- data/lib/ace/git_commit.rb +41 -0
- metadata +149 -0
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Ace
|
|
4
|
+
module GitCommit
|
|
5
|
+
module Organisms
|
|
6
|
+
# CommitOrchestrator coordinates the entire commit process
|
|
7
|
+
class CommitOrchestrator
|
|
8
|
+
# Reference the default scope name constant
|
|
9
|
+
DEFAULT_SCOPE_NAME = Ace::Support::Config::Models::ConfigGroup::DEFAULT_SCOPE_NAME
|
|
10
|
+
def initialize(config = nil)
|
|
11
|
+
@config = config || load_config
|
|
12
|
+
@git = Atoms::GitExecutor.new
|
|
13
|
+
@diff_analyzer = Molecules::DiffAnalyzer.new(@git)
|
|
14
|
+
@file_stager = Molecules::FileStager.new(@git)
|
|
15
|
+
@path_resolver = Molecules::PathResolver.new(@git)
|
|
16
|
+
@message_generator = Molecules::MessageGenerator.new(@config)
|
|
17
|
+
@commit_grouper = Molecules::CommitGrouper.new
|
|
18
|
+
@split_commit_executor = Molecules::SplitCommitExecutor.new(
|
|
19
|
+
git_executor: @git,
|
|
20
|
+
diff_analyzer: @diff_analyzer,
|
|
21
|
+
file_stager: @file_stager,
|
|
22
|
+
message_generator: @message_generator
|
|
23
|
+
)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Execute the commit process
|
|
27
|
+
# @param options [Models::CommitOptions] Commit options
|
|
28
|
+
# @return [Boolean] True if successful
|
|
29
|
+
def execute(options)
|
|
30
|
+
validate_repository!
|
|
31
|
+
|
|
32
|
+
if options.debug
|
|
33
|
+
puts "Debug: Commit options:"
|
|
34
|
+
options.to_h.each { |k, v| puts " #{k}: #{v.inspect}" }
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Stage files if needed
|
|
38
|
+
staging_result = stage_changes(options)
|
|
39
|
+
|
|
40
|
+
# Stop if staging failed
|
|
41
|
+
unless staging_result
|
|
42
|
+
puts "\nCannot proceed with commit due to staging failure" unless options.quiet
|
|
43
|
+
return false
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Ensure we have changes to commit
|
|
47
|
+
has_staged_changes = @git.has_staged_changes?
|
|
48
|
+
unless has_staged_changes
|
|
49
|
+
puts "No changes to commit" unless options.quiet
|
|
50
|
+
return true
|
|
51
|
+
end
|
|
52
|
+
puts "✓ Changes staged successfully" if options.stage_all? && !options.quiet
|
|
53
|
+
|
|
54
|
+
staged_files = @file_stager.staged_files
|
|
55
|
+
groups = @commit_grouper.group(staged_files, project_root: @git.repository_root)
|
|
56
|
+
|
|
57
|
+
if options.no_split
|
|
58
|
+
message = get_commit_message(options, config_override: @config)
|
|
59
|
+
return handle_single_commit(message, options)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
if groups.length > 1
|
|
63
|
+
display_split_summary(groups) unless options.quiet
|
|
64
|
+
result = @split_commit_executor.execute(groups, options)
|
|
65
|
+
return result.success?
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
group_config = groups.first ? groups.first.config : @config
|
|
69
|
+
message = get_commit_message(options, config_override: group_config)
|
|
70
|
+
handle_single_commit(message, options)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
private
|
|
74
|
+
|
|
75
|
+
# Load configuration with gem defaults and user overrides
|
|
76
|
+
# Follows ADR-022: Configuration Default and Override Pattern
|
|
77
|
+
# Uses Ace::Support::Config.create() for configuration cascade resolution
|
|
78
|
+
# @return [Hash] Configuration
|
|
79
|
+
def load_config
|
|
80
|
+
gem_root = Gem.loaded_specs["ace-git-commit"]&.gem_dir ||
|
|
81
|
+
File.expand_path("../../../..", __dir__)
|
|
82
|
+
|
|
83
|
+
resolver = Ace::Support::Config.create(
|
|
84
|
+
config_dir: ".ace",
|
|
85
|
+
defaults_dir: ".ace-defaults",
|
|
86
|
+
gem_path: gem_root
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
# Resolve config for git/commit namespace
|
|
90
|
+
config = resolver.resolve_namespace("git", filename: "commit")
|
|
91
|
+
|
|
92
|
+
# Extract git section if present, otherwise use root
|
|
93
|
+
config.data["git"] || config.data
|
|
94
|
+
rescue => e
|
|
95
|
+
warn "Error loading git commit config: #{e.message}" if Ace::GitCommit.debug?
|
|
96
|
+
{}
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# Validate we're in a git repository
|
|
100
|
+
# @raise [GitError] If not in a repository
|
|
101
|
+
def validate_repository!
|
|
102
|
+
unless @git.in_repository?
|
|
103
|
+
raise GitError, "Not in a git repository"
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# Stage changes based on options
|
|
108
|
+
# @param options [Models::CommitOptions] Options
|
|
109
|
+
# @return [Boolean] True if staging successful
|
|
110
|
+
def stage_changes(options)
|
|
111
|
+
if options.specific_files?
|
|
112
|
+
stage_specific_files(options)
|
|
113
|
+
elsif options.stage_all?
|
|
114
|
+
stage_all_changes(options)
|
|
115
|
+
else
|
|
116
|
+
true
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
# Stage specific files with progress feedback
|
|
121
|
+
# @param options [Models::CommitOptions] Options
|
|
122
|
+
# @return [Boolean] True if successful
|
|
123
|
+
def stage_specific_files(options)
|
|
124
|
+
# Early validation: check for non-existent paths (exclude glob patterns)
|
|
125
|
+
non_glob_paths = options.files.reject { |f| @path_resolver.glob_pattern?(f) }
|
|
126
|
+
unless non_glob_paths.empty?
|
|
127
|
+
validation = @path_resolver.validate_paths(non_glob_paths)
|
|
128
|
+
if validation[:invalid].any?
|
|
129
|
+
puts "\n✗ Invalid path(s): #{validation[:invalid].join(", ")}"
|
|
130
|
+
if @path_resolver.last_error
|
|
131
|
+
puts "Git error: #{@path_resolver.last_error}"
|
|
132
|
+
else
|
|
133
|
+
puts "These paths do not exist or have no git changes. Please check the paths and try again."
|
|
134
|
+
end
|
|
135
|
+
return false
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
# Separate paths by type for different handling
|
|
140
|
+
glob_patterns = options.files.select { |f| @path_resolver.glob_pattern?(f) }
|
|
141
|
+
non_patterns = options.files - glob_patterns
|
|
142
|
+
directories = non_patterns.select { |f| File.directory?(f) }
|
|
143
|
+
single_files = non_patterns - directories
|
|
144
|
+
|
|
145
|
+
# Build list of paths to stage
|
|
146
|
+
# - Directories: pass through directly (git add handles gitignore)
|
|
147
|
+
# - Globs: expand to tracked files (requires filesystem traversal)
|
|
148
|
+
# - Single files: pass through
|
|
149
|
+
paths_to_stage = directories + single_files
|
|
150
|
+
|
|
151
|
+
# Expand glob patterns to committable files (tracked + untracked)
|
|
152
|
+
unless glob_patterns.empty?
|
|
153
|
+
resolved_globs = @path_resolver.resolve_paths(glob_patterns)
|
|
154
|
+
if resolved_globs.empty?
|
|
155
|
+
puts "\n✗ No files found matching the specified pattern(s)"
|
|
156
|
+
|
|
157
|
+
# Collect suggestions for simple glob patterns
|
|
158
|
+
suggestions = glob_patterns.filter_map do |pattern|
|
|
159
|
+
suggested = @path_resolver.suggest_recursive_pattern(pattern)
|
|
160
|
+
{original: pattern, suggested: suggested} if suggested
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
# Output consolidated hint if any suggestions exist
|
|
164
|
+
unless suggestions.empty?
|
|
165
|
+
puts "\nHint: The following pattern(s) only match files at the current directory level:"
|
|
166
|
+
suggestions.each do |s|
|
|
167
|
+
puts " '#{s[:original]}' → try '#{s[:suggested]}' for recursive matching"
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
return false
|
|
172
|
+
end
|
|
173
|
+
paths_to_stage.concat(resolved_globs)
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
if paths_to_stage.empty?
|
|
177
|
+
puts "\n✗ No files found matching the specified path(s)"
|
|
178
|
+
return false
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
# Stage using path-restricted approach (reset + selective add)
|
|
182
|
+
puts "Staging files from specified path(s)..." unless options.quiet
|
|
183
|
+
result = @file_stager.stage_paths(paths_to_stage)
|
|
184
|
+
|
|
185
|
+
if result
|
|
186
|
+
staged_count = @file_stager.staged_files.length
|
|
187
|
+
puts "✓ Successfully staged #{staged_count} file(s)" unless options.quiet
|
|
188
|
+
true
|
|
189
|
+
else
|
|
190
|
+
# Always show errors, even in quiet mode
|
|
191
|
+
puts "\n✗ Failed to stage files"
|
|
192
|
+
puts "Error: #{@file_stager.last_error}" if @file_stager.last_error
|
|
193
|
+
# Suggestions only in verbose mode
|
|
194
|
+
unless options.quiet
|
|
195
|
+
puts "\nSuggestion: Check file permissions and paths"
|
|
196
|
+
end
|
|
197
|
+
false
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
# Stage all changes with progress feedback
|
|
202
|
+
# @param options [Models::CommitOptions] Options
|
|
203
|
+
# @return [Boolean] True if successful
|
|
204
|
+
def stage_all_changes(options)
|
|
205
|
+
result = @file_stager.stage_all
|
|
206
|
+
|
|
207
|
+
if result
|
|
208
|
+
true
|
|
209
|
+
else
|
|
210
|
+
# Always show errors, even in quiet mode
|
|
211
|
+
puts "\n✗ Failed to stage changes"
|
|
212
|
+
puts "Error: #{@file_stager.last_error}" if @file_stager.last_error
|
|
213
|
+
|
|
214
|
+
# Suggestions only in verbose mode
|
|
215
|
+
unless options.quiet
|
|
216
|
+
puts "\nSuggestions:"
|
|
217
|
+
puts " 1. Check file permissions"
|
|
218
|
+
puts " 2. Run 'git status' to see unstaged files"
|
|
219
|
+
puts " 3. Use --only-staged to commit existing staged files"
|
|
220
|
+
end
|
|
221
|
+
false
|
|
222
|
+
end
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
# Get or generate commit message
|
|
226
|
+
# @param options [Models::CommitOptions] Options
|
|
227
|
+
# @return [String] Commit message
|
|
228
|
+
def get_commit_message(options, config_override: nil)
|
|
229
|
+
if options.use_llm?
|
|
230
|
+
generate_message(options, config_override: config_override)
|
|
231
|
+
else
|
|
232
|
+
options.message
|
|
233
|
+
end
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
# Generate commit message using LLM
|
|
237
|
+
# @param options [Models::CommitOptions] Options
|
|
238
|
+
# @return [String] Generated message
|
|
239
|
+
def generate_message(options, config_override: nil)
|
|
240
|
+
puts "Generating commit message..." unless options.quiet
|
|
241
|
+
|
|
242
|
+
# Get the diff
|
|
243
|
+
diff = @diff_analyzer.get_staged_diff
|
|
244
|
+
files = @diff_analyzer.changed_files(staged_only: true)
|
|
245
|
+
|
|
246
|
+
config = config_override || @config
|
|
247
|
+
config = config.merge("model" => options.model) if options.model
|
|
248
|
+
|
|
249
|
+
message = @message_generator.generate(
|
|
250
|
+
diff,
|
|
251
|
+
intention: options.intention,
|
|
252
|
+
files: files,
|
|
253
|
+
config: config
|
|
254
|
+
)
|
|
255
|
+
|
|
256
|
+
puts "✓ Message generated" unless options.quiet
|
|
257
|
+
puts "\nMessage:\n#{message}" if options.debug
|
|
258
|
+
|
|
259
|
+
message
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
def handle_single_commit(message, options)
|
|
263
|
+
if options.dry_run
|
|
264
|
+
show_dry_run(message, options)
|
|
265
|
+
return true
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
perform_commit(message, options)
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
def display_split_summary(groups)
|
|
272
|
+
puts "Detected #{groups.length} configuration scopes:"
|
|
273
|
+
groups.each do |group|
|
|
274
|
+
label = group.scope_name.to_s.empty? ? DEFAULT_SCOPE_NAME : group.scope_name
|
|
275
|
+
source = group.source ? " (#{group.source})" : ""
|
|
276
|
+
puts " - #{label}#{source}: #{group.file_count} file(s)"
|
|
277
|
+
end
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
# Show dry run information
|
|
281
|
+
# @param message [String] Commit message
|
|
282
|
+
# @param options [Models::CommitOptions] Options
|
|
283
|
+
def show_dry_run(message, options)
|
|
284
|
+
puts "=== DRY RUN ==="
|
|
285
|
+
puts "Would commit with message:"
|
|
286
|
+
puts "-" * 40
|
|
287
|
+
puts message
|
|
288
|
+
puts "-" * 40
|
|
289
|
+
|
|
290
|
+
staged_files = @file_stager.staged_files
|
|
291
|
+
puts "\nFiles to be committed:"
|
|
292
|
+
staged_files.each { |f| puts " #{f}" }
|
|
293
|
+
|
|
294
|
+
if options.debug
|
|
295
|
+
diff_summary = @diff_analyzer.analyze_diff(@diff_analyzer.get_staged_diff)
|
|
296
|
+
puts "\nChanges:"
|
|
297
|
+
puts " Insertions: +#{diff_summary[:insertions]}"
|
|
298
|
+
puts " Deletions: -#{diff_summary[:deletions]}"
|
|
299
|
+
end
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
# Perform the actual commit
|
|
303
|
+
# @param message [String] Commit message
|
|
304
|
+
# @param options [Models::CommitOptions] Options
|
|
305
|
+
# @return [Boolean] True if successful
|
|
306
|
+
def perform_commit(message, options)
|
|
307
|
+
puts "Committing..." unless options.quiet
|
|
308
|
+
|
|
309
|
+
# Execute commit
|
|
310
|
+
@git.execute("commit", "-m", message)
|
|
311
|
+
|
|
312
|
+
# Get the commit SHA
|
|
313
|
+
commit_sha = @git.execute("rev-parse", "HEAD").strip
|
|
314
|
+
|
|
315
|
+
# Display commit summary
|
|
316
|
+
unless options.quiet
|
|
317
|
+
summarizer = Molecules::CommitSummarizer.new(@git)
|
|
318
|
+
summary = summarizer.summarize(commit_sha)
|
|
319
|
+
puts summary
|
|
320
|
+
end
|
|
321
|
+
|
|
322
|
+
true
|
|
323
|
+
rescue GitError => e
|
|
324
|
+
puts "\n✗ Commit failed: #{e.message}"
|
|
325
|
+
false
|
|
326
|
+
end
|
|
327
|
+
end
|
|
328
|
+
end
|
|
329
|
+
end
|
|
330
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "git_commit/version"
|
|
4
|
+
|
|
5
|
+
# Load ace-config and ace-llm
|
|
6
|
+
require "ace/support/config"
|
|
7
|
+
require "ace/llm"
|
|
8
|
+
|
|
9
|
+
# Require all components
|
|
10
|
+
require_relative "git_commit/atoms/git_executor"
|
|
11
|
+
require_relative "git_commit/atoms/gitignore_checker"
|
|
12
|
+
require_relative "git_commit/molecules/diff_analyzer"
|
|
13
|
+
require_relative "git_commit/molecules/message_generator"
|
|
14
|
+
require_relative "git_commit/molecules/file_stager"
|
|
15
|
+
require_relative "git_commit/molecules/path_resolver"
|
|
16
|
+
require_relative "git_commit/molecules/commit_grouper"
|
|
17
|
+
require_relative "git_commit/molecules/commit_summarizer"
|
|
18
|
+
require_relative "git_commit/molecules/split_commit_executor"
|
|
19
|
+
require_relative "git_commit/organisms/commit_orchestrator"
|
|
20
|
+
require_relative "git_commit/models/commit_options"
|
|
21
|
+
require_relative "git_commit/models/commit_group"
|
|
22
|
+
require_relative "git_commit/models/split_commit_result"
|
|
23
|
+
require_relative "git_commit/models/stage_result"
|
|
24
|
+
require_relative "git_commit/cli"
|
|
25
|
+
|
|
26
|
+
module Ace
|
|
27
|
+
module GitCommit
|
|
28
|
+
class Error < StandardError; end
|
|
29
|
+
class GitError < Error; end
|
|
30
|
+
class ConfigurationError < Error; end
|
|
31
|
+
|
|
32
|
+
# Alias the default scope name constant from ace-support-config for convenience
|
|
33
|
+
DEFAULT_SCOPE_NAME = Ace::Support::Config::Models::ConfigGroup::DEFAULT_SCOPE_NAME
|
|
34
|
+
|
|
35
|
+
# Check if debug mode is enabled
|
|
36
|
+
# @return [Boolean] True if debug mode is enabled
|
|
37
|
+
def self.debug?
|
|
38
|
+
ENV["ACE_DEBUG"] == "1" || ENV["DEBUG"] == "1"
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: ace-git-commit
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.23.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Michal Czyz
|
|
8
|
+
bindir: exe
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: ace-support-cli
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - "~>"
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '0.3'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - "~>"
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '0.3'
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: ace-support-core
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - "~>"
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '0.24'
|
|
33
|
+
type: :runtime
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - "~>"
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '0.24'
|
|
40
|
+
- !ruby/object:Gem::Dependency
|
|
41
|
+
name: ace-support-config
|
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - "~>"
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '0.7'
|
|
47
|
+
type: :runtime
|
|
48
|
+
prerelease: false
|
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - "~>"
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '0.7'
|
|
54
|
+
- !ruby/object:Gem::Dependency
|
|
55
|
+
name: ace-git
|
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - "~>"
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: '0.11'
|
|
61
|
+
type: :runtime
|
|
62
|
+
prerelease: false
|
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - "~>"
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: '0.11'
|
|
68
|
+
- !ruby/object:Gem::Dependency
|
|
69
|
+
name: ace-llm
|
|
70
|
+
requirement: !ruby/object:Gem::Requirement
|
|
71
|
+
requirements:
|
|
72
|
+
- - "~>"
|
|
73
|
+
- !ruby/object:Gem::Version
|
|
74
|
+
version: '0.23'
|
|
75
|
+
type: :runtime
|
|
76
|
+
prerelease: false
|
|
77
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
78
|
+
requirements:
|
|
79
|
+
- - "~>"
|
|
80
|
+
- !ruby/object:Gem::Version
|
|
81
|
+
version: '0.23'
|
|
82
|
+
description: Analyzes diffs and developer intent to generate conventional commit messages
|
|
83
|
+
using LLM. Handles monorepo scoping automatically — split commits across packages
|
|
84
|
+
with one command.
|
|
85
|
+
email:
|
|
86
|
+
- mc@cs3b.com
|
|
87
|
+
executables:
|
|
88
|
+
- ace-git-commit
|
|
89
|
+
extensions: []
|
|
90
|
+
extra_rdoc_files: []
|
|
91
|
+
files:
|
|
92
|
+
- ".ace-defaults/git/commit.yml"
|
|
93
|
+
- ".ace-defaults/nav/protocols/guide-sources/ace-git-commit.yml"
|
|
94
|
+
- ".ace-defaults/nav/protocols/prompt-sources/ace-git-commit.yml"
|
|
95
|
+
- ".ace-defaults/nav/protocols/wfi-sources/ace-git-commit.yml"
|
|
96
|
+
- CHANGELOG.md
|
|
97
|
+
- COMPARISON.md
|
|
98
|
+
- LICENSE
|
|
99
|
+
- README.md
|
|
100
|
+
- Rakefile
|
|
101
|
+
- exe/ace-git-commit
|
|
102
|
+
- handbook/guides/version-control-system-message.g.md
|
|
103
|
+
- handbook/prompts/git-commit.md
|
|
104
|
+
- handbook/prompts/git-commit.system.md
|
|
105
|
+
- handbook/skills/as-git-commit/SKILL.md
|
|
106
|
+
- handbook/workflow-instructions/git/commit.wf.md
|
|
107
|
+
- lib/ace/git_commit.rb
|
|
108
|
+
- lib/ace/git_commit/atoms/git_executor.rb
|
|
109
|
+
- lib/ace/git_commit/atoms/gitignore_checker.rb
|
|
110
|
+
- lib/ace/git_commit/cli.rb
|
|
111
|
+
- lib/ace/git_commit/cli/commands/commit.rb
|
|
112
|
+
- lib/ace/git_commit/models/commit_group.rb
|
|
113
|
+
- lib/ace/git_commit/models/commit_options.rb
|
|
114
|
+
- lib/ace/git_commit/models/split_commit_result.rb
|
|
115
|
+
- lib/ace/git_commit/models/stage_result.rb
|
|
116
|
+
- lib/ace/git_commit/molecules/commit_grouper.rb
|
|
117
|
+
- lib/ace/git_commit/molecules/commit_summarizer.rb
|
|
118
|
+
- lib/ace/git_commit/molecules/diff_analyzer.rb
|
|
119
|
+
- lib/ace/git_commit/molecules/file_stager.rb
|
|
120
|
+
- lib/ace/git_commit/molecules/message_generator.rb
|
|
121
|
+
- lib/ace/git_commit/molecules/path_resolver.rb
|
|
122
|
+
- lib/ace/git_commit/molecules/split_commit_executor.rb
|
|
123
|
+
- lib/ace/git_commit/organisms/commit_orchestrator.rb
|
|
124
|
+
- lib/ace/git_commit/version.rb
|
|
125
|
+
homepage: https://github.com/cs3b/ace
|
|
126
|
+
licenses:
|
|
127
|
+
- MIT
|
|
128
|
+
metadata:
|
|
129
|
+
homepage_uri: https://github.com/cs3b/ace
|
|
130
|
+
source_code_uri: https://github.com/cs3b/ace
|
|
131
|
+
changelog_uri: https://github.com/cs3b/ace/blob/main/ace-git-commit/CHANGELOG.md
|
|
132
|
+
rdoc_options: []
|
|
133
|
+
require_paths:
|
|
134
|
+
- lib
|
|
135
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
136
|
+
requirements:
|
|
137
|
+
- - ">="
|
|
138
|
+
- !ruby/object:Gem::Version
|
|
139
|
+
version: 3.2.0
|
|
140
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
141
|
+
requirements:
|
|
142
|
+
- - ">="
|
|
143
|
+
- !ruby/object:Gem::Version
|
|
144
|
+
version: '0'
|
|
145
|
+
requirements: []
|
|
146
|
+
rubygems_version: 3.6.9
|
|
147
|
+
specification_version: 4
|
|
148
|
+
summary: Intention-aware conventional commit generation from diffs
|
|
149
|
+
test_files: []
|