brainiac-fizzy 0.0.29 → 0.0.30
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:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8e54fe3a10cd6e39be3f52862b1625e2532be592e5480c11f685423910a75b91
|
|
4
|
+
data.tar.gz: 77cc0b0ce8a518bde93484bf8513f538f9a26f4412479556d80f83de3ae5c545
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 71c5abb12093956521a3ebdf78566d416d1c3ed33293d6c402a5236462b524042af9a259a3cda7fbf1930c80b93e7be68462952aed0f61393a1eb84b055a851a
|
|
7
|
+
data.tar.gz: 1ecc72a231ccef4c9fadbc279fe561628fda23151aad9b8b64afd65cd151d7ec612d95c25daa008958176b0e922b582602689f6c0754a0474643a4216131055c
|
|
@@ -27,6 +27,8 @@ module Brainiac
|
|
|
27
27
|
cmd_setup
|
|
28
28
|
when "board"
|
|
29
29
|
cmd_board(args)
|
|
30
|
+
when "env"
|
|
31
|
+
cmd_env(args)
|
|
30
32
|
else
|
|
31
33
|
print_help
|
|
32
34
|
end
|
|
@@ -126,6 +128,66 @@ module Brainiac
|
|
|
126
128
|
end
|
|
127
129
|
end
|
|
128
130
|
|
|
131
|
+
# --- ephemeral env management ---
|
|
132
|
+
|
|
133
|
+
# `brainiac fizzy env setup <card_number>`
|
|
134
|
+
#
|
|
135
|
+
# Manually set up (or refresh tracking for) an ephemeral Belt env for a
|
|
136
|
+
# card that was already worked — no agent, no tokens. Once tracked, PR
|
|
137
|
+
# updates auto-redeploy it via brainiac-github.
|
|
138
|
+
def cmd_env(args)
|
|
139
|
+
sub = args.shift
|
|
140
|
+
case sub
|
|
141
|
+
when "setup", "add"
|
|
142
|
+
env_setup(args)
|
|
143
|
+
else
|
|
144
|
+
puts "Usage: brainiac fizzy env setup <card_number>"
|
|
145
|
+
puts ""
|
|
146
|
+
puts "Commands:"
|
|
147
|
+
puts " setup <card_number> Configure + deploy an ephemeral Belt env for a"
|
|
148
|
+
puts " card that was already worked (no agent dispatch)."
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
def env_setup(args)
|
|
153
|
+
card_number = args.shift
|
|
154
|
+
if card_number.nil? || card_number.strip.empty?
|
|
155
|
+
puts "Usage: brainiac fizzy env setup <card_number>"
|
|
156
|
+
return
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
require "net/http"
|
|
160
|
+
require "uri"
|
|
161
|
+
|
|
162
|
+
server_url = detect_server_url
|
|
163
|
+
uri = URI("#{server_url}/api/fizzy/ephemeral-env/#{card_number}")
|
|
164
|
+
|
|
165
|
+
puts "Setting up ephemeral env for card ##{card_number} (no agent)..."
|
|
166
|
+
begin
|
|
167
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
|
168
|
+
http.read_timeout = 600 # belt deploy can be slow
|
|
169
|
+
response = http.post(uri.path, "")
|
|
170
|
+
data = begin
|
|
171
|
+
JSON.parse(response.body)
|
|
172
|
+
rescue StandardError
|
|
173
|
+
{}
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
if response.is_a?(Net::HTTPSuccess) && data["status"] == "ok"
|
|
177
|
+
puts "✓ Ephemeral env '#{data["env"]}' ready#{" (was already configured)" if data["already_configured"]}"
|
|
178
|
+
puts " Worktree: #{data["worktree"]}" if data["worktree"]
|
|
179
|
+
puts " URL: #{data["url"]}" if data["url"]
|
|
180
|
+
puts ""
|
|
181
|
+
puts "Tracked in ephemeral_envs.json — PR updates will auto-redeploy it."
|
|
182
|
+
else
|
|
183
|
+
puts "✗ Failed: #{data["reason"] || response.message}"
|
|
184
|
+
end
|
|
185
|
+
rescue StandardError => e
|
|
186
|
+
puts "Could not reach server at #{server_url}: #{e.message}"
|
|
187
|
+
puts "Is the server running? Check with: brainiac status"
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
|
|
129
191
|
# --- board setup (split into phases) ---
|
|
130
192
|
|
|
131
193
|
def board_setup
|
|
@@ -629,6 +691,7 @@ module Brainiac
|
|
|
629
691
|
board list List configured boards and their columns
|
|
630
692
|
board assign <project> <board_key> Assign a project to a board
|
|
631
693
|
board columns <board_key> Refresh columns for a board from Fizzy
|
|
694
|
+
env setup <card_number> Set up an ephemeral Belt env for an already-worked card (no agent)
|
|
632
695
|
|
|
633
696
|
Fizzy handles card assignment, comments, @mentions, cross-agent reviews,
|
|
634
697
|
duplicate detection, and planning mode via webhooks.
|
|
@@ -662,11 +725,13 @@ module Brainiac
|
|
|
662
725
|
# When called with args (the words typed so far after the plugin name),
|
|
663
726
|
# returns context-sensitive completions for nested subcommands.
|
|
664
727
|
def self.completions(args = [])
|
|
665
|
-
return %w[board config setup status] if args.empty?
|
|
728
|
+
return %w[board config env setup status] if args.empty?
|
|
666
729
|
|
|
667
730
|
case args[0]
|
|
668
731
|
when "board"
|
|
669
732
|
board_completions(args[1..])
|
|
733
|
+
when "env"
|
|
734
|
+
args.length <= 1 ? %w[setup add] : []
|
|
670
735
|
else
|
|
671
736
|
[]
|
|
672
737
|
end
|
|
@@ -194,8 +194,13 @@ end
|
|
|
194
194
|
#
|
|
195
195
|
# `belt g environment` is synchronous so the worktree is configured before the
|
|
196
196
|
# agent starts. The actual `belt deploy` runs in the background.
|
|
197
|
+
#
|
|
198
|
+
# When `force: true`, the `deploy` tag requirement is bypassed — the caller is
|
|
199
|
+
# explicitly requesting env setup (e.g. the `brainiac fizzy env setup` CLI or
|
|
200
|
+
# the `/api/fizzy/ephemeral-env/:card` endpoint), so no tag is needed.
|
|
197
201
|
def maybe_create_ephemeral_belt_env(worktree_path:, card_number:, project_key:, tags: nil,
|
|
198
|
-
repo_path: nil, agent_name: nil, fetch_live_tags: false
|
|
202
|
+
repo_path: nil, agent_name: nil, fetch_live_tags: false,
|
|
203
|
+
force: false)
|
|
199
204
|
unless defined?(BeltConfig) && defined?(BeltEnvironment)
|
|
200
205
|
LOG.debug "[EphemeralEnv] Belt utilities not available — skipping"
|
|
201
206
|
return
|
|
@@ -216,14 +221,16 @@ def maybe_create_ephemeral_belt_env(worktree_path:, card_number:, project_key:,
|
|
|
216
221
|
return
|
|
217
222
|
end
|
|
218
223
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
224
|
+
unless force
|
|
225
|
+
resolved_tags = resolve_ephemeral_env_tags(
|
|
226
|
+
tags, card_number: card_number, repo_path: repo_path || worktree_path,
|
|
227
|
+
agent_name: agent_name, fetch_live_tags: fetch_live_tags
|
|
228
|
+
)
|
|
229
|
+
tag_list = tag_names(resolved_tags)
|
|
230
|
+
unless tag_list.include?("deploy")
|
|
231
|
+
LOG.debug "[EphemeralEnv] Card ##{card_number} tags=#{tag_list.inspect} — no deploy tag, skipping"
|
|
232
|
+
return
|
|
233
|
+
end
|
|
227
234
|
end
|
|
228
235
|
|
|
229
236
|
parent_env = BeltConfig.parent_env_for(project_key)
|
|
@@ -266,6 +273,75 @@ def ensure_ephemeral_env_for_comment(ctx, card_number, worktree)
|
|
|
266
273
|
)
|
|
267
274
|
end
|
|
268
275
|
|
|
276
|
+
# Manually set up an ephemeral Belt env for a card that was already worked,
|
|
277
|
+
# without dispatching an agent. Resolves the card's existing worktree from the
|
|
278
|
+
# work item map, configures + deploys the env synchronously, and tracks it in
|
|
279
|
+
# ephemeral_envs.json so PR-update auto-redeploys (brainiac-github) work.
|
|
280
|
+
#
|
|
281
|
+
# Bypasses the `deploy` tag requirement (force: true) — the caller is asking
|
|
282
|
+
# for this explicitly. Returns a result hash suitable for a JSON API response.
|
|
283
|
+
#
|
|
284
|
+
# @param card_number [Integer, String] Fizzy card number
|
|
285
|
+
# @return [Hash] { status:, env:, url:, worktree:, reason: }
|
|
286
|
+
def setup_ephemeral_env_for_card(card_number)
|
|
287
|
+
return { status: "error", reason: "card_number required" } unless card_number
|
|
288
|
+
|
|
289
|
+
unless defined?(BeltConfig) && defined?(BeltEnvironment)
|
|
290
|
+
return { status: "error", reason: "Belt utilities not available" }
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
card_number = card_number.to_s
|
|
294
|
+
entry = work_item_entry_for_card(card_number)
|
|
295
|
+
return { status: "error", reason: "no work item found for card ##{card_number}" } unless entry
|
|
296
|
+
|
|
297
|
+
worktree = entry["worktree"]
|
|
298
|
+
project_key = entry["project"]
|
|
299
|
+
unless worktree && File.directory?(worktree)
|
|
300
|
+
return { status: "error", reason: "worktree missing for card ##{card_number} (#{worktree.inspect})" }
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
env_name = BeltConfig.ephemeral_env_for_card(card_number)
|
|
304
|
+
already = BeltEnvironment.environment_configured?(worktree: worktree, env_name: env_name)
|
|
305
|
+
|
|
306
|
+
maybe_create_ephemeral_belt_env(
|
|
307
|
+
worktree_path: worktree, card_number: card_number,
|
|
308
|
+
project_key: project_key, force: true
|
|
309
|
+
)
|
|
310
|
+
|
|
311
|
+
# After setup, resolve the public URL the same way deployment lookups do.
|
|
312
|
+
url = defined?(deployment_url_for_card) ? (deployment_url_for_card(card_number) || {})[:url] : nil
|
|
313
|
+
|
|
314
|
+
{
|
|
315
|
+
status: "ok",
|
|
316
|
+
env: env_name,
|
|
317
|
+
url: url,
|
|
318
|
+
worktree: worktree,
|
|
319
|
+
already_configured: already
|
|
320
|
+
}
|
|
321
|
+
rescue StandardError => e
|
|
322
|
+
LOG.error "[EphemeralEnv] Manual setup failed for card ##{card_number}: #{e.message}"
|
|
323
|
+
{ status: "error", reason: e.message }
|
|
324
|
+
end
|
|
325
|
+
|
|
326
|
+
# Resolve the work item entry for a Fizzy card number from work_items.json.
|
|
327
|
+
# Returns a flattened hash with worktree/branch/project or nil.
|
|
328
|
+
def work_item_entry_for_card(card_number)
|
|
329
|
+
map = load_work_item_map
|
|
330
|
+
match = map.values.find do |entry|
|
|
331
|
+
entry.dig("sources", "fizzy", "card_number").to_s == card_number.to_s
|
|
332
|
+
end
|
|
333
|
+
return nil unless match
|
|
334
|
+
|
|
335
|
+
{
|
|
336
|
+
"worktree" => match["worktree"],
|
|
337
|
+
"branch" => match["branch"],
|
|
338
|
+
"project" => match["project"]
|
|
339
|
+
}
|
|
340
|
+
rescue StandardError => e
|
|
341
|
+
LOG.error "[EphemeralEnv] Could not load work item for card ##{card_number}: #{e.message}" if defined?(LOG)
|
|
342
|
+
nil
|
|
343
|
+
end
|
|
344
|
+
|
|
269
345
|
def belt_app_for_ephemeral?(worktree_path)
|
|
270
346
|
return BeltEnvironment.belt_app?(worktree_path) if defined?(BeltEnvironment) && BeltEnvironment.respond_to?(:belt_app?)
|
|
271
347
|
|
|
@@ -103,8 +103,7 @@ module Brainiac
|
|
|
103
103
|
end
|
|
104
104
|
|
|
105
105
|
# Card index API (duplicate detection)
|
|
106
|
-
app.get "/api/card-index" do
|
|
107
|
-
content_type :json
|
|
106
|
+
app.get "/api/card-index" do content_type :json
|
|
108
107
|
halt 404, { error: "Card index not available" }.to_json unless defined?(CARD_INDEX)
|
|
109
108
|
|
|
110
109
|
query = params["q"]
|
|
@@ -116,6 +115,21 @@ module Brainiac
|
|
|
116
115
|
end
|
|
117
116
|
end
|
|
118
117
|
|
|
118
|
+
# Manually set up an ephemeral Belt env for a card that was already
|
|
119
|
+
# worked — no agent dispatch, no tokens. Configures + deploys the env
|
|
120
|
+
# in the card's existing worktree and tracks it so PR-update
|
|
121
|
+
# auto-redeploys keep it fresh.
|
|
122
|
+
app.post "/api/fizzy/ephemeral-env/:card" do
|
|
123
|
+
content_type :json
|
|
124
|
+
card_number = params["card"]
|
|
125
|
+
result = setup_ephemeral_env_for_card(card_number)
|
|
126
|
+
if result[:status] == "ok"
|
|
127
|
+
result.to_json
|
|
128
|
+
else
|
|
129
|
+
halt 422, result.to_json
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
|
|
119
133
|
# Deployment API routes (if deployments are configured)
|
|
120
134
|
return unless defined?(DEPLOYMENTS_CONFIG)
|
|
121
135
|
|