brainiac 0.0.29 → 0.0.31

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: 37f135fffb0c94919fa376fee96e12053af77062f93dadc520cce7285ee86e78
4
- data.tar.gz: 553b10319590bde4fee8f89cf227059fec83d750d6ad7188d56aa5243a6cf169
3
+ metadata.gz: ab80207a78e9cf2150459e67eae0d37fd9768a3f6aae774209099bd2b0f7fe93
4
+ data.tar.gz: c0af2f5a0348fa8540d575f7124218d803dee7531a6dc68205d516108314ae63
5
5
  SHA512:
6
- metadata.gz: e04d26de1e9010e175b69032358e400223af29ffabde834e48b206d6cff58340fe1082262b36843fe6995aff752df2ed053793a78f416cc47d1dd4b47b881a99
7
- data.tar.gz: fe32e3768064d1728a2b28d40aef900c1afb454d04e192b67a9e4f631bf117a147ebef547898709ead380b286336dee64da8a40b62cf6f10b7a327ca1bb3d505
6
+ metadata.gz: 83451dba00ca901f85495784fcd143a5ad4fe808ea2921702805804be1bef0f26202435e6057ddfb935cbc3d3f66518eed17878ecad9123034dbd8a33bdbac28
7
+ data.tar.gz: 194a1c6bc7e5819cd48f3f74aeb28988e6ebcaf0681cef7ac6168497a0a487ee116ee7c78b2b7bb9a6f750743ce23c9e2d5fdc6f8cb4c6e50e4b05f2397cac55
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- brainiac (0.0.29)
4
+ brainiac (0.0.31)
5
5
  puma (~> 7.2)
6
6
  rackup (~> 2.3)
7
7
  sinatra (~> 4.1)
@@ -84,7 +84,7 @@ DEPENDENCIES
84
84
  CHECKSUMS
85
85
  ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383
86
86
  base64 (0.3.0) sha256=27337aeabad6ffae05c265c450490628ef3ebd4b67be58257393227588f5a97b
87
- brainiac (0.0.29)
87
+ brainiac (0.0.31)
88
88
  json (2.19.9) sha256=9b9025b7cdddafa38d316eca0b2358488e42d417045c1b90d216a9fefe46b79a
89
89
  language_server-protocol (3.17.0.5) sha256=fd1e39a51a28bf3eec959379985a72e296e9f9acfce46f6a79d31ca8760803cc
90
90
  lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87
data/bin/brainiac CHANGED
@@ -50,6 +50,64 @@ def save_config(config)
50
50
  File.write(CONFIG_FILE, JSON.pretty_generate(config))
51
51
  end
52
52
 
53
+ # Describe the git branch state of a local plugin checkout for the `plugins` list.
54
+ # Returns a short human-readable string like "main", "my-branch ↑2 ↓1 *"
55
+ # where ↑ = ahead of upstream, ↓ = behind upstream, * = uncommitted changes.
56
+ # Returns nil if the path isn't a git repo (so callers can skip the annotation).
57
+ def plugin_branch_status(path)
58
+ return nil unless Dir.exist?(path)
59
+
60
+ branch, _, br_status = Open3.capture3("git", "rev-parse", "--abbrev-ref", "HEAD", chdir: path)
61
+ return nil unless br_status.success?
62
+
63
+ branch = branch.strip
64
+ branch = "(detached)" if branch.empty? || branch == "HEAD"
65
+
66
+ parts = [branch]
67
+
68
+ # Ahead/behind counts vs the upstream tracking branch (if one is set).
69
+ counts, _, ab_status = Open3.capture3(
70
+ "git", "rev-list", "--left-right", "--count", "@{upstream}...HEAD", chdir: path
71
+ )
72
+ if ab_status.success?
73
+ behind, ahead = counts.strip.split(/\s+/).map(&:to_i)
74
+ parts << "↑#{ahead}" if ahead&.positive?
75
+ parts << "↓#{behind}" if behind&.positive?
76
+ end
77
+
78
+ # Uncommitted changes (staged, unstaged, or untracked).
79
+ dirty, _, st_status = Open3.capture3("git", "status", "--porcelain", chdir: path)
80
+ parts << "*" if st_status.success? && !dirty.strip.empty?
81
+
82
+ parts.join(" ")
83
+ end
84
+
85
+ # Format a single line for the `brainiac plugins` list. Handles both local
86
+ # (path-based) plugins and gem-based plugins, including branch/sync status
87
+ # for local checkouts.
88
+ def plugin_list_line(entry)
89
+ name = entry["name"]
90
+ gem_name = entry["gem"] || "brainiac-#{name}"
91
+ local_path = entry["path"]
92
+ installed_at = entry["installed_at"] ? " (#{entry["installed_at"][0..9]})" : ""
93
+
94
+ return " #{gem_plugin_status(name, gem_name)}#{installed_at}" unless local_path
95
+
96
+ return " ✗ #{name} → #{local_path} (path missing)#{installed_at}" unless Dir.exist?(local_path)
97
+
98
+ branch = plugin_branch_status(local_path)
99
+ branch_note = branch ? " [#{branch}]" : ""
100
+ " ✓ #{name} → #{local_path}#{branch_note}#{installed_at}"
101
+ end
102
+
103
+ # Check whether a gem-based plugin is installed/loadable and return a status string.
104
+ def gem_plugin_status(name, gem_name)
105
+ spec = Gem::Specification.find_by_name(gem_name)
106
+ "✓ #{name} (#{gem_name} #{spec.version})"
107
+ rescue Gem::MissingSpecError
108
+ "✗ #{name} (#{gem_name} — gem not found)"
109
+ end
110
+
53
111
  # Resolve the default agent name: env var → brainiac.json → nil.
54
112
  def default_agent_name
55
113
  return ENV["AI_AGENT_NAME"] if ENV["AI_AGENT_NAME"] && !ENV["AI_AGENT_NAME"].empty?
@@ -3035,29 +3093,7 @@ when "plugins"
3035
3093
  puts "Installed plugins:"
3036
3094
  plugins.each do |p|
3037
3095
  entry = p.is_a?(Hash) ? p : { "name" => p.to_s }
3038
- name = entry["name"]
3039
- gem_name = entry["gem"] || "brainiac-#{name}"
3040
- local_path = entry["path"]
3041
- installed_at = entry["installed_at"] ? " (#{entry["installed_at"][0..9]})" : ""
3042
-
3043
- if local_path
3044
- # Local plugin — check path exists
3045
- if Dir.exist?(local_path)
3046
- puts " ✓ #{name} → #{local_path}#{installed_at}"
3047
- else
3048
- puts " ✗ #{name} → #{local_path} (path missing)#{installed_at}"
3049
- end
3050
- else
3051
- # Gem plugin — check gem is loadable
3052
- version = entry["version"] || "latest"
3053
- loadable = begin
3054
- spec = Gem::Specification.find_by_name(gem_name)
3055
- "✓ #{name} (#{gem_name} #{spec.version})"
3056
- rescue Gem::MissingSpecError
3057
- "✗ #{name} (#{gem_name} — gem not found)"
3058
- end
3059
- puts " #{loadable}#{installed_at}"
3060
- end
3096
+ puts plugin_list_line(entry)
3061
3097
  end
3062
3098
  end
3063
3099
  else
@@ -72,15 +72,22 @@ def reload_agent_registry!(force: false)
72
72
  end
73
73
  end
74
74
 
75
- # Get the env hash for an agent. Returns {} if none configured.
75
+ # Default environment for all agent processes. Prevents git from hanging
76
+ # on COMMIT_EDITMSG when rebasing in non-interactive sessions.
77
+ DEFAULT_AGENT_ENV = {
78
+ "GIT_EDITOR" => "true"
79
+ }.freeze
80
+
81
+ # Get the env hash for an agent. Merges default agent env with agent-specific env.
82
+ # Returns at minimum the DEFAULT_AGENT_ENV even if no agent-specific env is configured.
76
83
  def agent_env_for(agent_name)
77
- return {} unless agent_name
84
+ return DEFAULT_AGENT_ENV.dup unless agent_name
78
85
 
79
86
  key = agent_name.downcase.gsub(/[^a-z0-9-]/, "-")
80
87
  entry = AGENT_REGISTRY[key]
81
- return {} unless entry.is_a?(Hash)
88
+ return DEFAULT_AGENT_ENV.dup unless entry.is_a?(Hash)
82
89
 
83
- entry["env"] || {}
90
+ DEFAULT_AGENT_ENV.merge(entry["env"] || {})
84
91
  end
85
92
 
86
93
  # Get a specific env var for an agent. Returns nil if not set.
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Brainiac
4
4
  # @return [String] the current gem version
5
- VERSION = "0.0.29"
5
+ VERSION = "0.0.31"
6
6
  end
@@ -0,0 +1,17 @@
1
+ {
2
+ "binary": "stdbuf",
3
+ "default_args": "-oL agy --mode=accept-edits --dangerously-skip-permissions",
4
+ "agent_flag": null,
5
+ "model_flag": "--model",
6
+ "prompt_mode": "stdin",
7
+ "resume_flag": null,
8
+ "list_models_command": null,
9
+ "models": {
10
+ "gemini": "gemini-3.1-pro",
11
+ "pro": "gemini-3.1-pro",
12
+ "flash": "gemini-3.5-flash",
13
+ "flash-lite": "gemini-3.5-flash",
14
+ "sonnet": "claude-sonnet-4.6",
15
+ "opus": "claude-opus-4.6"
16
+ }
17
+ }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: brainiac
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.29
4
+ version: 0.0.31
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andy Davis
@@ -163,6 +163,7 @@ files:
163
163
  - templates/agents.json.example
164
164
  - templates/brainiac.json.example
165
165
  - templates/cli-providers/codex.json.example
166
+ - templates/cli-providers/gemini.json.example
166
167
  - templates/cli-providers/grok.json.example
167
168
  - templates/cli-providers/kiro.json.example
168
169
  - templates/hooks/pre-commit