jeeves-git-commit 3.1.0 → 4.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c677877fa585dc14ffd287c273bd0a79c82b4592c0f84c5e532c2171b576d061
4
- data.tar.gz: fcfcd962506dc36115358ae8e5b20afe7273e1a8f531101d4b9c92442bc24b4c
3
+ metadata.gz: e4f59a567e89976f44fabc0d1a41ecd582dd66a803a269a5432e057aaa20ad18
4
+ data.tar.gz: e3138daa03b7c885c6b09623e5f74eea3d7d1f6ec4b3d943b8905fd2614a6cf0
5
5
  SHA512:
6
- metadata.gz: 0773d6fa8d0504583fbca079ffcb0a418c0de29b09a8ae799b5ac42b0e917fbba3d7f06b2b1a78ab69ae1255a5f36aa118dccdcc06fab41edb10ad452a35aacf
7
- data.tar.gz: 05a7466354d8ff50a486d4c3bf4487a68a746fdce0c64209133ccb2f52e30a85a4ddf5637f016393293d2fc40e3137c685ab915559f383f1bb6f017f03b964cb
6
+ metadata.gz: '05096cd1f2f6c01388ea230937c0e6e79635a1ce5108ff738c3140de47e13ef0a1fb8cf22fee08312c360902ed9cfe74e30c47b1756ac89c4acba092bba90c08'
7
+ data.tar.gz: ad8ae30b3e57dd9b35b39195dde57d44e141d79881927e13bbadd78372c1128c8d892083e165be54edb2f961a502c7e20c9d9f404f09ce40ae46bf620b3a086a
data/README.md CHANGED
@@ -4,8 +4,8 @@
4
4
  <img src="assets/jeeves.png" alt="Jeeves Logo" width="200">
5
5
  </p>
6
6
 
7
- Jeeves creates Git commit messages from your changes using OpenRouter or a
8
- local Ollama model. The bundled prompt adds gitmoji and a sarcastic roast of
7
+ Jeeves creates Git commit messages from your changes using OpenRouter, the
8
+ Anthropic API, or a local Ollama model. The bundled prompt adds gitmoji and a sarcastic roast of
9
9
  your engineering choices. Your own prompt can be neutral.
10
10
 
11
11
  ```text
@@ -17,7 +17,7 @@ never going to make the missing endpoint appear.
17
17
 
18
18
  ## Install
19
19
 
20
- Use Ruby 3.3 through 4.0 and Git. Development uses the version in `.ruby-version`.
20
+ Use Ruby 3.3 or newer and Git. Development uses Homebrew's current Ruby.
21
21
 
22
22
  ```sh
23
23
  gem install jeeves-git-commit
@@ -35,8 +35,18 @@ The checkout must remain available when using this installation method.
35
35
 
36
36
  ## Configure
37
37
 
38
- For OpenRouter, export `OPENROUTER_API_KEY`. Optionally set `GIT_COMMIT_MODEL`
39
- to your preferred model. The provider defaults to OpenRouter.
38
+ For OpenRouter, export `OPENROUTER_API_KEY`. Optionally set
39
+ `GIT_COMMIT_OPENROUTER_MODEL` to your preferred model. The provider defaults to
40
+ OpenRouter.
41
+
42
+ To call Anthropic directly, save these settings. `GIT_COMMIT_ANTHROPIC_MODEL`
43
+ is optional and defaults to `claude-haiku-5-5`:
44
+
45
+ ```dotenv
46
+ GIT_COMMIT_PROVIDER=anthropic
47
+ ANTHROPIC_API_KEY=your-anthropic-key
48
+ GIT_COMMIT_ANTHROPIC_MODEL=claude-haiku-5-5
49
+ ```
40
50
 
41
51
  To use an installed local Ollama model, save these in your shell's configuration
42
52
  or the environment file your shell already loads:
@@ -50,9 +60,10 @@ Plain `jeeves` then uses local generation; no per-command flag or cloud key is
50
60
  needed. See [configuration](docs/configuration.md) for installation, fish
51
61
  syntax, all settings, prompt customization, and input limits.
52
62
 
53
- Version 3 requires Ruby 3.3 through 4.0. It validates conventional commit
54
- subjects by default; use `GIT_COMMIT_MESSAGE_FORMAT=plain` for a custom format.
55
- Existing personal prompts are preserved. See the [release notes](docs/releases.md).
63
+ Version 4 renames `GIT_COMMIT_MODEL` to `GIT_COMMIT_OPENROUTER_MODEL`. Jeeves
64
+ requires Ruby 3.3 or newer and validates conventional commit subjects by
65
+ default; use `GIT_COMMIT_MESSAGE_FORMAT=plain` for a custom format. Existing
66
+ personal prompts are preserved. See the [release notes](docs/releases.md).
56
67
 
57
68
  ## Use
58
69
 
@@ -73,8 +84,9 @@ git diff | jeeves
73
84
  # Push only after a successful commit
74
85
  jeeves --push
75
86
 
76
- # Use the saved cloud model for one command
87
+ # Use a saved provider and its model for one command
77
88
  jeeves --provider openrouter
89
+ jeeves --provider anthropic
78
90
 
79
91
  # Override the local model for one command
80
92
  jeeves --local --model another-installed-model
@@ -85,7 +97,7 @@ jeeves --local --model another-installed-model
85
97
  | `-a`, `--all` | Include all working-tree changes |
86
98
  | `-d`, `--dry-run` | Print the message without changing the real index or HEAD |
87
99
  | `-p`, `--push` | Push after a successful commit |
88
- | `--provider openrouter\|ollama` | Override the provider |
100
+ | `--provider openrouter\|anthropic\|ollama` | Override the provider |
89
101
  | `--local` | Use Ollama for this invocation |
90
102
  | `--model MODEL` | Override the selected provider's model |
91
103
  | `--version` | Print the version |
@@ -113,13 +125,15 @@ bin/doctor
113
125
  ```
114
126
 
115
127
  `bin/check` runs fast foundation checks. `bin/check --documents-only` checks
116
- Markdown. `bin/check --full` adds the foundation tests and Ruby tests, lint,
128
+ Markdown. `bin/check --full` adds `bin/check-application`: Ruby tests, lint,
117
129
  and gem build. Application checks are not part of the two routine modes.
118
130
  Built gems go in `gems/`. Publishing with `rake push` is an explicit release
119
131
  action; it is never part of normal validation.
120
132
 
121
- - [Development workflow](docs/development-workflow.md): setup, knowledge search,
122
- worktrees, hooks, runtime policy, and validation.
133
+ - [Development workflow](docs/development-workflow.md): setup, validation,
134
+ runtime policy, and releases.
135
+ - [Project Starter foundation](docs/foundation/README.md): knowledge search,
136
+ worktrees, hooks, task tracking, and shared engineering policy.
123
137
  - [Documents](docs/README.md) and [memory](memory/README.md).
124
138
  - [GitHub Issues](https://github.com/jubishop/Jeeves/issues): bugs and planned work.
125
139
  - [Agent instructions](AGENTS.md).
@@ -129,3 +143,11 @@ action; it is never part of normal validation.
129
143
 
130
144
  Jeeves uses the [MIT license](LICENSE). The adopted project foundation retains
131
145
  its separate [license notice](LICENSE.project-starter).
146
+
147
+ ## Local task tracking
148
+
149
+ Use `td` for local tasks, progress, blockers, and session handoffs. After cloning,
150
+ install td and run `td init` in the primary checkout. Use `td status` or
151
+ `td monitor` to inspect progress. Follow the [task workflow](docs/foundation/task-tracking.md)
152
+ for setup, review, worktrees, and local data. Keep GitHub Issues for shared scope
153
+ and acceptance criteria, linked from related td tasks.
@@ -65,6 +65,30 @@ module Jeeves
65
65
  end
66
66
  end
67
67
 
68
+ class Anthropic
69
+ def initialize(settings)
70
+ @settings = settings
71
+ @key = settings.env['ANTHROPIC_API_KEY']
72
+ raise Error, 'ANTHROPIC_API_KEY environment variable not set' if @key.nil? || @key.empty?
73
+ end
74
+
75
+ def generate(prompt)
76
+ # Leave thinking at the model's default: newer models reject disabling it.
77
+ # The limit covers thinking as well as the message.
78
+ body = { model: @settings.model, max_tokens: 16_000, messages: [{ role: 'user', content: prompt }] }
79
+ headers = { 'x-api-key' => @key, 'anthropic-version' => '2023-06-01' }
80
+ result = HTTP.post(URI('https://api.anthropic.com/v1/messages'), body, headers)
81
+ raise Error, 'Anthropic reached its output limit; no commit message was accepted' if result['stop_reason'] == 'max_tokens'
82
+ raise Error, 'Anthropic declined to write this commit message' if result['stop_reason'] == 'refusal'
83
+
84
+ result.fetch('content').select { |block| block.fetch('type') == 'text' }.map { |block| block.fetch('text') }.join
85
+ rescue KeyError, NoMethodError, TypeError
86
+ raise Error, 'Unexpected Anthropic response structure'
87
+ rescue Net::OpenTimeout, Net::ReadTimeout, SocketError, SystemCallError => e
88
+ raise Error, "Anthropic request failed: #{e.message}"
89
+ end
90
+ end
91
+
68
92
  class Ollama
69
93
  def initialize(settings)
70
94
  @settings = settings
@@ -100,5 +124,7 @@ module Jeeves
100
124
  raise Error, 'Ollama timed out. Check the server or try a smaller model or diff.'
101
125
  end
102
126
  end
127
+
128
+ CLIENTS = { 'openrouter' => OpenRouter, 'anthropic' => Anthropic, 'ollama' => Ollama }.freeze
103
129
  end
104
130
  end
@@ -4,12 +4,12 @@ require 'rubygems/requirement'
4
4
 
5
5
  module Jeeves
6
6
  module Runtime
7
- REQUIREMENT = Gem::Requirement.new('>= 3.3', '< 4.1').freeze
7
+ REQUIREMENT = Gem::Requirement.new('>= 3.3').freeze
8
8
 
9
- def self.check!
10
- return if REQUIREMENT.satisfied_by?(Gem::Version.new(RUBY_VERSION))
9
+ def self.check!(version = RUBY_VERSION)
10
+ return if REQUIREMENT.satisfied_by?(Gem::Version.new(version))
11
11
 
12
- abort "Jeeves requires Ruby #{REQUIREMENT}; found #{RUBY_VERSION}. Select a supported Ruby with your version manager."
12
+ abort "Jeeves requires Ruby #{REQUIREMENT}; found #{version}. Select the latest stable Ruby with your version manager."
13
13
  end
14
14
  end
15
15
  end
@@ -4,15 +4,17 @@ module Jeeves
4
4
  class Settings
5
5
  attr_reader :provider, :model, :context, :max_diff_bytes, :message_format, :env
6
6
 
7
+ PROVIDERS = %w[openrouter anthropic ollama].freeze
8
+
7
9
  def initialize(env, options = {})
8
10
  @env = env
9
11
  @provider = options[:provider] || env.fetch('GIT_COMMIT_PROVIDER', 'openrouter')
10
- raise Error, 'GIT_COMMIT_PROVIDER must be openrouter or ollama' unless %w[openrouter ollama].include?(@provider)
12
+ raise Error, 'GIT_COMMIT_PROVIDER must be openrouter, anthropic, or ollama' unless PROVIDERS.include?(@provider)
11
13
 
12
- @model = options[:model] || if @provider == 'ollama'
13
- env.fetch('GIT_COMMIT_LOCAL_MODEL', 'gemma4:26b')
14
- else
15
- env.fetch('GIT_COMMIT_MODEL', 'x-ai/grok-code-fast-1')
14
+ @model = options[:model] || case @provider
15
+ when 'ollama' then env.fetch('GIT_COMMIT_LOCAL_MODEL', 'gemma4:26b')
16
+ when 'anthropic' then env.fetch('GIT_COMMIT_ANTHROPIC_MODEL', 'claude-haiku-5-5')
17
+ else env.fetch('GIT_COMMIT_OPENROUTER_MODEL', 'anthropic/claude-haiku-5.5')
16
18
  end
17
19
  raise Error, 'The configured model must not be empty' if @model.strip.empty?
18
20
 
@@ -1,3 +1,3 @@
1
1
  module Jeeves
2
- VERSION = '3.1.0'
2
+ VERSION = '4.0.0'
3
3
  end
data/lib/jeeves.rb CHANGED
@@ -36,7 +36,7 @@ module Jeeves
36
36
  return show(VERSION) if options[:version]
37
37
 
38
38
  settings = Settings.new(@env, options)
39
- provider = settings.provider == 'ollama' ? Providers::Ollama.new(settings) : Providers::OpenRouter.new(settings)
39
+ provider = Providers::CLIENTS.fetch(settings.provider).new(settings)
40
40
  piped = !@input.tty? && !@input.closed?
41
41
  if piped
42
42
  diff = (@input.read || +'').force_encoding(Encoding::UTF_8)
@@ -78,7 +78,7 @@ module Jeeves
78
78
  parser.on('-a', '--all', 'Include all working-tree changes') { options[:all] = true }
79
79
  parser.on('-p', '--push', 'Push after a successful commit') { options[:push] = true }
80
80
  parser.on('-d', '--dry-run', 'Print the message without staging or committing') { options[:dry_run] = true }
81
- parser.on('--provider PROVIDER', %w[openrouter ollama], 'Use openrouter or ollama') { |value| options[:provider] = value }
81
+ parser.on('--provider PROVIDER', Settings::PROVIDERS, 'Use openrouter, anthropic, or ollama') { |value| options[:provider] = value }
82
82
  parser.on('--local', 'Use Ollama for this invocation') { options[:provider] = 'ollama' }
83
83
  parser.on('--model MODEL', 'Override the configured model') { |value| options[:model] = value }
84
84
  parser.on('--version', 'Show version') { options[:version] = true }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jeeves-git-commit
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.0
4
+ version: 4.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Bishop
@@ -99,9 +99,6 @@ required_ruby_version: !ruby/object:Gem::Requirement
99
99
  - - ">="
100
100
  - !ruby/object:Gem::Version
101
101
  version: '3.3'
102
- - - "<"
103
- - !ruby/object:Gem::Version
104
- version: '4.1'
105
102
  required_rubygems_version: !ruby/object:Gem::Requirement
106
103
  requirements:
107
104
  - - ">="