brainiac-basecamp 0.0.20 → 0.0.22

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: df6f7d762ab28802603ffb217a64d0fce08df13bf2a25390d2ee92d7249a7daa
4
- data.tar.gz: 1c8b2cecb38112764ed4859c06fee2bd4228e80993198fc8e340672e56e1a41e
3
+ metadata.gz: cbdaed237c170e246708af6b6f249cc90897b58aa3551eeb563e2a154145b49f
4
+ data.tar.gz: ab6c55d1ef2f88e26194059cb453fda42c3660777ab34813d15b6e88fd5afaf5
5
5
  SHA512:
6
- metadata.gz: 3c0f4a96699a386478bdcb38e47f267c78009e42fef1ae6f3341b49e985fe19c13eb089a9e3027b17b1f11d58fade52d4062065012e466bab8c66a274e8a96e2
7
- data.tar.gz: 0b42872311687c6c3db3d5d2aeaef4a8043a98cbc5f9862288b4fb21aa2097278e90c4419394e41151e2115231c60e2bfbea82112976e5ad55a6116224837040
6
+ metadata.gz: 46f0a19b34106661205fc2cc0dc6b921511a04a7a3a2b6df2665c8d1034afc937029ac5b00b11fe3e7f42b52d8fe24bd48ef29705b15211ed76deb8e05bfde8d
7
+ data.tar.gz: a278fc0d456893561a8e320ee223510ef338296605a66e1871099514f711cf3989e2d000f3864371097105c3af6a0afd332ddf87a70910870f45a488cbb1f509
data/README.md CHANGED
@@ -201,6 +201,16 @@ brainiac restart
201
201
  { "agent": "GLaDOS", "role": "test-engineer" },
202
202
  { "agent": "Threepio", "role": "code-reviewer" }
203
203
  ],
204
+ "deploy": {
205
+ "enabled": true,
206
+ "trigger": "on_final_pr",
207
+ "default_env": "dev",
208
+ "project_envs": {
209
+ "stowzilla": "dev",
210
+ "posh-nosh": "dev02"
211
+ },
212
+ "command": "belt deploy {env} --auto"
213
+ },
204
214
  "notifications": {
205
215
  "channel": "discord",
206
216
  "target": "1423854179880927274",
@@ -212,6 +222,66 @@ brainiac restart
212
222
  }
213
223
  ```
214
224
 
225
+ ## Epic Deployment
226
+
227
+ Deploy epics to test environments before merging the final PR to main.
228
+
229
+ ### Per-Epic Deploy Environment
230
+
231
+ Specify the deploy environment in the epic title or description:
232
+
233
+ ```
234
+ Todolist: "Epic: Build Authentication System [deploy:dev02]"
235
+ ```
236
+
237
+ Or in the todolist description:
238
+
239
+ ```
240
+ deploy:dev02
241
+ ```
242
+
243
+ The title syntax takes precedence over description.
244
+
245
+ ### Manual Deploy
246
+
247
+ ```bash
248
+ brainiac basecamp deploy <epic-id> [env]
249
+ ```
250
+
251
+ Environment resolution (in order):
252
+ 1. Explicit env argument
253
+ 2. `[deploy:env]` in epic title
254
+ 3. `deploy:env` in epic description
255
+ 4. `deploy.project_envs.<project>` in config (per-project default)
256
+ 5. `deploy.default_env` in config (global default)
257
+
258
+ ### Automated Deploy
259
+
260
+ Configure automated deployment in `~/.brainiac/basecamp.json`:
261
+
262
+ ```json
263
+ {
264
+ "deploy": {
265
+ "enabled": true,
266
+ "trigger": "on_final_pr",
267
+ "default_env": "dev",
268
+ "project_envs": {
269
+ "stowzilla": "dev",
270
+ "posh-nosh": "dev02"
271
+ },
272
+ "command": "belt deploy {env} --auto"
273
+ }
274
+ }
275
+ ```
276
+
277
+ | Option | Description |
278
+ |--------|-------------|
279
+ | `enabled` | Enable/disable automated deploys |
280
+ | `trigger` | When to deploy: `manual`, `on_final_pr` |
281
+ | `default_env` | Global fallback environment |
282
+ | `project_envs` | Per-project default environments (e.g., `{"stowzilla": "dev"}`) |
283
+ | `command` | Deploy command template (`{env}` is replaced) |
284
+
215
285
  ## CLI Commands
216
286
 
217
287
  ```bash
@@ -220,6 +290,7 @@ brainiac basecamp config # Show config
220
290
  brainiac basecamp status # Plugin health check
221
291
  brainiac basecamp epics # List active epics
222
292
  brainiac basecamp epics --all # Include completed
293
+ brainiac basecamp deploy <epic-id> [env] # Deploy epic to environment
223
294
  brainiac basecamp bot add <name> <id> <agent> # Add bot account
224
295
  brainiac basecamp bot list # List bot accounts
225
296
  brainiac basecamp projects map <key> <bc-id> # Map project
@@ -2,6 +2,8 @@
2
2
 
3
3
  require "json"
4
4
  require "open3"
5
+ require_relative "config"
6
+ require_relative "epic"
5
7
 
6
8
  module Brainiac
7
9
  module Plugins
@@ -23,6 +25,8 @@ module Brainiac
23
25
  cmd_status
24
26
  when "epics"
25
27
  cmd_epics(args)
28
+ when "deploy"
29
+ cmd_deploy(args)
26
30
  when "link"
27
31
  cmd_link(args)
28
32
  when "bot"
@@ -163,14 +167,14 @@ module Brainiac
163
167
  data = JSON.parse(File.read(epics_file))
164
168
  epics = data["epics"] || []
165
169
 
166
- if args.first == "--all"
170
+ if args.include?("--all")
167
171
  display_epics = epics
168
172
  else
169
173
  display_epics = epics.select { |e| e["status"] == "active" }
170
174
  end
171
175
 
172
176
  if display_epics.empty?
173
- puts "No #{args.first == '--all' ? '' : 'active '}epics."
177
+ puts "No #{args.include?('--all') ? '' : 'active '}epics."
174
178
  return
175
179
  end
176
180
 
@@ -181,11 +185,23 @@ module Brainiac
181
185
  total = tasks.size
182
186
 
183
187
  status_icon = epic["status"] == "active" ? "🚀" : "✅"
184
- puts "#{status_icon} #{epic['title']}"
188
+
189
+ # Show deploy env if configured
190
+ deploy_env = Basecamp::Epic.extract_deploy_env(epic["title"], epic["description"])
191
+ deploy_display = deploy_env ? " [deploy:#{deploy_env}]" : ""
192
+
193
+ puts "#{status_icon} #{epic['title']}#{deploy_display}"
185
194
  puts " Todolist: #{epic['basecamp_todolist_id']} | Agent: #{epic['agent']}"
186
195
  puts " Tasks: #{complete}/#{total} complete, #{in_flight} in-flight"
187
196
  puts " Started: #{epic['started_at']}"
188
197
 
198
+ # Show last deploy if present
199
+ if epic["last_deploy"]
200
+ ld = epic["last_deploy"]
201
+ deploy_status = ld["status"] == "success" ? "✅" : "❌"
202
+ puts " Last deploy: #{deploy_status} #{ld['env']} @ #{ld['at']}"
203
+ end
204
+
189
205
  # Show per-task detail if verbose or few tasks
190
206
  if args.include?("--verbose") || args.include?("-v")
191
207
  tasks.each do |t|
@@ -203,6 +219,119 @@ module Brainiac
203
219
  end
204
220
  end
205
221
 
222
+ def cmd_deploy(args)
223
+ epic_id = args.shift
224
+ env_override = args.shift
225
+
226
+ unless epic_id
227
+ puts "Usage: brainiac basecamp deploy <epic-id> [env]"
228
+ puts ""
229
+ puts "Deploy an epic's worktree to the specified environment."
230
+ puts ""
231
+ puts "Arguments:"
232
+ puts " <epic-id> Basecamp todolist ID for the epic"
233
+ puts " [env] Environment to deploy to (overrides epic's [deploy:env])"
234
+ puts ""
235
+ puts "Environment resolution (in order):"
236
+ puts " 1. Explicit env argument"
237
+ puts " 2. [deploy:env] in epic title"
238
+ puts " 3. deploy:env in epic description"
239
+ puts " 4. deploy.default_env in config"
240
+ puts ""
241
+ puts "Active epics:"
242
+ list_epics_for_deploy
243
+ return
244
+ end
245
+
246
+ # Load epic
247
+ epics = load_epics
248
+ epic = epics.find { |e| e["basecamp_todolist_id"] == epic_id.to_s }
249
+
250
+ unless epic
251
+ puts "❌ No epic found with todolist ID #{epic_id}"
252
+ puts ""
253
+ puts "Active epics:"
254
+ list_epics_for_deploy
255
+ return
256
+ end
257
+
258
+ # Resolve deploy environment
259
+ deploy_env = resolve_deploy_env(epic, env_override)
260
+
261
+ unless deploy_env
262
+ puts "❌ No deploy environment specified."
263
+ puts ""
264
+ puts "Either:"
265
+ puts " 1. Pass env as argument: brainiac basecamp deploy #{epic_id} dev02"
266
+ puts " 2. Add [deploy:env] to epic title: \"Epic: My Feature [deploy:dev02]\""
267
+ puts " 3. Add deploy:env to epic description"
268
+ puts " 4. Set deploy.project_envs.<project> in ~/.brainiac/basecamp.json"
269
+ puts " 5. Set deploy.default_env in ~/.brainiac/basecamp.json"
270
+ return
271
+ end
272
+
273
+ # Find worktree
274
+ worktree_path = find_epic_worktree(epic)
275
+
276
+ unless worktree_path
277
+ puts "❌ No worktree found for epic '#{epic['title']}'"
278
+ puts " Epic branch mode may not be enabled, or no tasks have been dispatched."
279
+ return
280
+ end
281
+
282
+ puts "🚀 Deploying epic '#{epic['title']}'"
283
+ puts " Environment: #{deploy_env}"
284
+ puts " Worktree: #{worktree_path}"
285
+ puts ""
286
+
287
+ # Pull latest changes before deploying
288
+ puts "Pulling latest changes..."
289
+ pull_output, pull_status = Open3.capture2e("git", "pull", "--ff-only", chdir: worktree_path)
290
+ if pull_status.success?
291
+ if pull_output.include?("Already up to date")
292
+ puts "Already up to date."
293
+ else
294
+ puts pull_output.lines.first(5).join
295
+ end
296
+ else
297
+ puts "⚠️ Git pull failed (continuing anyway):"
298
+ puts pull_output.lines.first(3).join
299
+ end
300
+ puts ""
301
+
302
+ # Run deploy
303
+ success = run_deploy(worktree_path, deploy_env)
304
+
305
+ puts ""
306
+
307
+ if success
308
+ puts "✅ Deploy completed successfully"
309
+
310
+ # Update epic state
311
+ epic["last_deploy"] = {
312
+ "env" => deploy_env,
313
+ "at" => Time.now.iso8601,
314
+ "status" => "success"
315
+ }
316
+ else
317
+ puts "❌ Deploy failed"
318
+
319
+ epic["last_deploy"] = {
320
+ "env" => deploy_env,
321
+ "at" => Time.now.iso8601,
322
+ "status" => "failed"
323
+ }
324
+ end
325
+
326
+ save_epics(epics)
327
+
328
+ # Change into the worktree directory
329
+ puts ""
330
+ puts "Entering worktree..."
331
+ Dir.chdir(worktree_path)
332
+ exec ENV.fetch("SHELL", "/bin/bash")
333
+ end
334
+
206
335
  def cmd_link(args)
207
336
  fizzy_card = args.shift
208
337
  basecamp_url = args.shift
@@ -517,7 +646,8 @@ module Brainiac
517
646
  setup Interactive setup guide
518
647
  config Show current config
519
648
  status Check plugin status
520
- epics [--all] List active epics (--all for completed too)
649
+ epics [--all] [-v] List active epics (--all for completed too)
650
+ deploy <epic-id> [env] Deploy epic worktree to environment
521
651
  link <card> <url> Link a Fizzy card to a Basecamp todo
522
652
  bot add <agent-name> Add bot (auto-resolves person_id from Basecamp)
523
653
  bot add <name> <person-id> <agent> Add bot with explicit person_id
@@ -542,6 +672,13 @@ module Brainiac
542
672
  on_complete — Advance to next task as soon as agent finishes (default)
543
673
  on_pr_merge — Wait for PR to be merged before advancing (review gate)
544
674
 
675
+ Deploy environment resolution (in order):
676
+ 1. Explicit env argument: brainiac basecamp deploy 12345 dev02
677
+ 2. [deploy:env] in epic title: "Epic: My Feature [deploy:dev02]"
678
+ 3. deploy:env in epic description
679
+ 4. deploy.project_envs.<project> in config (per-project default)
680
+ 5. deploy.default_env in config (global default)
681
+
545
682
  Task statuses (for reset --to):
546
683
  pending — Not yet started, waiting for dependencies
547
684
  in_flight — Agent is actively working on it
@@ -873,6 +1010,91 @@ module Brainiac
873
1010
  }))
874
1011
  end
875
1012
 
1013
+ # --- Deploy helpers ---
1014
+
1015
+ def list_epics_for_deploy
1016
+ epics = load_epics.select { |e| e["status"] == "active" }
1017
+ if epics.empty?
1018
+ puts " (no active epics)"
1019
+ return
1020
+ end
1021
+
1022
+ epics.each do |epic|
1023
+ deploy_env = resolve_deploy_env(epic, nil)
1024
+ env_display = deploy_env ? "[deploy:#{deploy_env}]" : "(no env)"
1025
+ puts " #{epic['basecamp_todolist_id']} — #{epic['title']} #{env_display}"
1026
+ end
1027
+ end
1028
+
1029
+ def resolve_deploy_env(epic, override)
1030
+ # 1. Explicit override
1031
+ return override if override && !override.empty?
1032
+
1033
+ # 2. [deploy:env] in title or deploy:env in description
1034
+ env = Basecamp::Epic.extract_deploy_env(epic["title"], epic["description"])
1035
+ return env if env
1036
+
1037
+ # 3. Per-project default from config
1038
+ # Prefer the project from tasks (set from Fizzy card tags) over basecamp mapping
1039
+ # since multiple brainiac projects can share the same basecamp project.
1040
+ project_key = (epic["tasks"] || []).filter_map { |t| t["project"] }.first
1041
+ project_key ||= Config.brainiac_project_for(epic["basecamp_project_id"])
1042
+ project_env = Config.deploy.dig("project_envs", project_key) if project_key
1043
+ return project_env if project_env
1044
+
1045
+ # 4. Global default
1046
+ Config.deploy["default_env"]
1047
+ end
1048
+
1049
+ def find_epic_worktree(epic)
1050
+ # Epic branches are stored per-project in epic["epic_branches"]
1051
+ # Find any worktree that has the epic branch checked out
1052
+ epic_branches = epic["epic_branches"] || {}
1053
+ return nil if epic_branches.empty?
1054
+
1055
+ # Load projects to find repo paths
1056
+ projects_file = File.join(BRAINIAC_DIR, "projects.json")
1057
+ return nil unless File.exist?(projects_file)
1058
+
1059
+ projects = JSON.parse(File.read(projects_file))
1060
+
1061
+ epic_branches.each do |project_key, branch_name|
1062
+ repo_path = projects.dig(project_key, "repo_path")
1063
+ next unless repo_path && File.directory?(repo_path)
1064
+
1065
+ # List worktrees and find one with this branch
1066
+ output, status = Open3.capture2("git", "worktree", "list", "--porcelain", chdir: repo_path)
1067
+ next unless status.success?
1068
+
1069
+ # Parse porcelain output
1070
+ current_worktree = nil
1071
+ output.each_line do |line|
1072
+ if line.start_with?("worktree ")
1073
+ current_worktree = line.sub("worktree ", "").strip
1074
+ elsif line.start_with?("branch refs/heads/")
1075
+ wt_branch = line.sub("branch refs/heads/", "").strip
1076
+ return current_worktree if wt_branch == branch_name && current_worktree && current_worktree != repo_path
1077
+ end
1078
+ end
1079
+ end
1080
+
1081
+ nil
1082
+ rescue JSON::ParserError
1083
+ nil
1084
+ end
1085
+
1086
+ def run_deploy(worktree_path, env)
1087
+ deploy_config = Config.deploy
1088
+ command_template = deploy_config["command"] || "belt deploy {env} --auto"
1089
+ command = command_template.gsub("{env}", env)
1090
+
1091
+ puts "Running: #{command}"
1092
+ puts "-" * 40
1093
+
1094
+ # Run the deploy command in the worktree directory
1095
+ system(command, chdir: worktree_path)
1096
+ end
1097
+
876
1098
  def auto_resolve_person_id(agent_name)
877
1099
  output, status = Open3.capture2(
878
1100
  "basecamp", "people", "list", "--jq",
@@ -928,7 +1150,7 @@ module Brainiac
928
1150
  end
929
1151
 
930
1152
  def self.completions
931
- %w[setup config status epics link bot projects set reset webhook]
1153
+ %w[setup config status epics deploy link bot projects set reset webhook]
932
1154
  end
933
1155
  end
934
1156
  end
@@ -20,6 +20,13 @@ module Brainiac
20
20
  "fizzy_account_id" => nil,
21
21
  "review_gate" => "on_complete",
22
22
  "review_gates" => [],
23
+ "deploy" => {
24
+ "enabled" => false,
25
+ "trigger" => "manual",
26
+ "default_env" => nil,
27
+ "project_envs" => {},
28
+ "command" => "belt deploy {env} --auto"
29
+ },
23
30
  "notifications" => {
24
31
  "epic_started" => true,
25
32
  "task_dispatched" => true,
@@ -103,6 +110,13 @@ module Brainiac
103
110
  current["review_gate"] || "on_complete"
104
111
  end
105
112
 
113
+ # Deploy configuration.
114
+ #
115
+ # @return [Hash]
116
+ def deploy
117
+ current["deploy"] || DEFAULT_CONFIG["deploy"]
118
+ end
119
+
106
120
  private
107
121
 
108
122
  def config_mtime
@@ -123,6 +123,37 @@ module Brainiac
123
123
  lines.join("\n")
124
124
  end
125
125
 
126
+ # Extract deploy environment from epic title or description.
127
+ # Supports:
128
+ # [deploy:dev02] — in title (preferred)
129
+ # deploy:dev02 — in description (fallback)
130
+ #
131
+ # @param title [String] Epic/todolist title
132
+ # @param description [String, nil] Optional description to check as fallback
133
+ # @return [String, nil] Environment name or nil
134
+ def extract_deploy_env(title, description = nil)
135
+ # Try [deploy:env] format in title (preferred)
136
+ if title
137
+ marker = "[deploy:"
138
+ value_start = title.index(marker)
139
+ if value_start
140
+ value_start += marker.length
141
+ value_end = title.index("]", value_start)
142
+ if value_end
143
+ environment = title[value_start...value_end].strip
144
+ return environment unless environment.empty?
145
+ end
146
+ end
147
+ end
148
+
149
+ # Fallback: try deploy:env in description
150
+ if description && (match = description.match(/deploy:(\S+)/i))
151
+ return match[1].strip
152
+ end
153
+
154
+ nil
155
+ end
156
+
126
157
  private
127
158
 
128
159
  # Extract Fizzy card number from title.
@@ -737,6 +737,9 @@ module Brainiac
737
737
  # If epic_branch mode, open final PRs to main
738
738
  if epic["review_gate"] == "epic_branch" && epic["epic_branches"]&.any?
739
739
  open_final_prs(epic)
740
+
741
+ # Trigger automated deploy if configured
742
+ trigger_deploy_if_configured(epic, "on_final_pr")
740
743
  end
741
744
 
742
745
  # Post a summary message in Basecamp
@@ -925,6 +928,130 @@ module Brainiac
925
928
  message: message,
926
929
  agent: agent)
927
930
  end
931
+
932
+ # Trigger automated deploy if configured for the given trigger point.
933
+ #
934
+ # @param epic [Hash] Epic state
935
+ # @param trigger [String] Trigger point ("on_final_pr", "on_task_merge", etc.)
936
+ def trigger_deploy_if_configured(epic, trigger)
937
+ deploy_config = Config.deploy
938
+ return unless deploy_config["enabled"]
939
+ return unless deploy_config["trigger"] == trigger
940
+
941
+ # Resolve deploy environment
942
+ deploy_env = resolve_epic_deploy_env(epic)
943
+ unless deploy_env
944
+ LOG.warn "[Basecamp:Orchestrator] Deploy triggered but no environment configured for epic '#{epic['title']}'" if defined?(LOG)
945
+ return
946
+ end
947
+
948
+ # Find worktree
949
+ worktree_path = find_epic_worktree(epic)
950
+ unless worktree_path
951
+ LOG.warn "[Basecamp:Orchestrator] Deploy triggered but no worktree found for epic '#{epic['title']}'" if defined?(LOG)
952
+ return
953
+ end
954
+
955
+ LOG.info "[Basecamp:Orchestrator] Auto-deploying epic '#{epic['title']}' to #{deploy_env}" if defined?(LOG)
956
+
957
+ # Run deploy
958
+ command_template = deploy_config["command"] || "belt deploy {env} --auto"
959
+ command = command_template.gsub("{env}", deploy_env)
960
+
961
+ success = system(command, chdir: worktree_path)
962
+
963
+ # Record deploy result
964
+ epic["last_deploy"] = {
965
+ "env" => deploy_env,
966
+ "at" => Time.now.iso8601,
967
+ "status" => success ? "success" : "failed",
968
+ "trigger" => trigger
969
+ }
970
+
971
+ # Send notification
972
+ if success
973
+ send_notification(
974
+ event: :epic_deployed,
975
+ message: "🚀 Epic **#{epic['title']}** deployed to **#{deploy_env}**",
976
+ agent: epic["agent"]
977
+ )
978
+ else
979
+ send_notification(
980
+ event: :epic_deploy_failed,
981
+ message: "❌ Epic **#{epic['title']}** deploy to **#{deploy_env}** failed",
982
+ agent: epic["agent"]
983
+ )
984
+ end
985
+ rescue StandardError => e
986
+ LOG.error "[Basecamp:Orchestrator] Deploy failed: #{e.message}" if defined?(LOG)
987
+ epic["last_deploy"] = {
988
+ "env" => deploy_env,
989
+ "at" => Time.now.iso8601,
990
+ "status" => "error",
991
+ "error" => e.message,
992
+ "trigger" => trigger
993
+ }
994
+ end
995
+
996
+ # Resolve deploy environment for an epic.
997
+ #
998
+ # @param epic [Hash] Epic state
999
+ # @return [String, nil] Environment name or nil
1000
+ def resolve_epic_deploy_env(epic)
1001
+ # 1. [deploy:env] in title or deploy:env in description
1002
+ env = Epic.extract_deploy_env(epic["title"], epic["description"])
1003
+ return env if env
1004
+
1005
+ # 2. Per-project default from config
1006
+ # Prefer the project from tasks (set from Fizzy card tags) over basecamp mapping
1007
+ # since multiple brainiac projects can share the same basecamp project.
1008
+ project_key = (epic["tasks"] || []).map { |t| t["project"] }.compact.first
1009
+ project_key ||= Config.brainiac_project_for(epic["basecamp_project_id"])
1010
+ project_env = Config.deploy.dig("project_envs", project_key) if project_key
1011
+ return project_env if project_env
1012
+
1013
+ # 3. Global default
1014
+ Config.deploy["default_env"]
1015
+ end
1016
+
1017
+ # Find the worktree path for an epic's branch.
1018
+ #
1019
+ # @param epic [Hash] Epic state
1020
+ # @return [String, nil] Worktree path or nil
1021
+ def find_epic_worktree(epic)
1022
+ epic_branches = epic["epic_branches"] || {}
1023
+ return nil if epic_branches.empty?
1024
+
1025
+ projects_file = File.join(BRAINIAC_DIR, "projects.json")
1026
+ return nil unless File.exist?(projects_file)
1027
+
1028
+ projects = JSON.parse(File.read(projects_file))
1029
+
1030
+ epic_branches.each do |project_key, branch_name|
1031
+ repo_path = projects.dig(project_key, "repo_path")
1032
+ next unless repo_path && File.directory?(repo_path)
1033
+
1034
+ # List worktrees and find one with this branch
1035
+ output, status = Open3.capture2("git", "worktree", "list", "--porcelain", chdir: repo_path)
1036
+ next unless status.success?
1037
+
1038
+ current_worktree = nil
1039
+ output.each_line do |line|
1040
+ if line.start_with?("worktree ")
1041
+ current_worktree = line.sub("worktree ", "").strip
1042
+ elsif line.start_with?("branch refs/heads/")
1043
+ wt_branch = line.sub("branch refs/heads/", "").strip
1044
+ if wt_branch == branch_name && current_worktree && current_worktree != repo_path
1045
+ return current_worktree
1046
+ end
1047
+ end
1048
+ end
1049
+ end
1050
+
1051
+ nil
1052
+ rescue JSON::ParserError
1053
+ nil
1054
+ end
928
1055
  end
929
1056
  end
930
1057
  end
@@ -3,7 +3,7 @@
3
3
  module Brainiac
4
4
  module Plugins
5
5
  module Basecamp
6
- VERSION = "0.0.20"
6
+ VERSION = "0.0.22"
7
7
  end
8
8
  end
9
9
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: brainiac-basecamp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.20
4
+ version: 0.0.22
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andy Davis