jeeves-git-commit 3.1.1 → 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: 4bf456f354f172b140a241db27b10459ae17c6b96748f3cab435f5dd7024c6ad
4
- data.tar.gz: d8764cc9556d4b8e3d220310c43ec7163fa6195e959445240025d7ab94a9ae4d
3
+ metadata.gz: e4f59a567e89976f44fabc0d1a41ecd582dd66a803a269a5432e057aaa20ad18
4
+ data.tar.gz: e3138daa03b7c885c6b09623e5f74eea3d7d1f6ec4b3d943b8905fd2614a6cf0
5
5
  SHA512:
6
- metadata.gz: 36df36dafc54fd9a2c609d238417f2f8740e7090c255590a84aa87da755726e63a5745f7fc0e8e64653c934f3b3beb3b8417e8f92c388cba2bce43c41c689b6a
7
- data.tar.gz: 50077793c804ab2d87e6681b3c07f18ee4be560487c628b9fa249d6bce4c66a58a50eb3beb4ffbce267e1303deeb5fc8cf1c818fea2cf782d4986f6e994b3dfe
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
@@ -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 or newer. 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 |
@@ -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,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.1'
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.1
4
+ version: 4.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Bishop