brainiac-fizzy 0.0.16 → 0.0.17

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: 6ed1ef3ae4c3db228a9a98a796579e7450e25fad4e19fa5ce075777e677342cc
4
- data.tar.gz: 9e5ceac2510d64194bc498850871ca8105aeea24b742e9930ede13c761928f50
3
+ metadata.gz: 666eda5c356c3b8cc120591eb71c40090b3162adace36563b5c3e1e406aa4154
4
+ data.tar.gz: 51bf4ff7967fd7bcceeedc9ee292a5a5a4a98c4b12d411926780c1722ae125c1
5
5
  SHA512:
6
- metadata.gz: 73f14f9e28f8eaba2558fac32e14116d0255fdb513cd2ba13753f1e5babe9a311807620832b75cd4b46282473e0603a1127a38483f18034177c0d983a84b5146
7
- data.tar.gz: d45acdf7a664c1585b262230a0b1cf70eff969699fc80c270193ccedf0d902ed7876fc6d3eb353acf4768217bd88babced1f10db835b6aa7e13edde62b57b27c
6
+ metadata.gz: 8180e6607b5411e10bad40abb263f22fd18c901df1ba0890a7131e8c8fa801836f88cbacda745b2edcafc50144ab5b96d7b613e06d3758df599cac5a28b1a3cd
7
+ data.tar.gz: 5ffdf9eec9082d78ee43c130fef1ef0c1b1e94a2533991acb2f43f9ab84d700fe397444862fa83d92bb5d7398a9402ebb06e2eb55e2d227546d287b73af5f3b8
@@ -12,6 +12,8 @@ module Brainiac
12
12
  BRAINIAC_DIR = ENV.fetch("BRAINIAC_DIR", File.join(Dir.home, ".brainiac"))
13
13
  FIZZY_CONFIG_FILE = File.join(BRAINIAC_DIR, "fizzy.json")
14
14
 
15
+ PROJECTS_FILE = File.join(BRAINIAC_DIR, "projects.json")
16
+
15
17
  class << self
16
18
  def run(args)
17
19
  command = args.shift
@@ -23,6 +25,8 @@ module Brainiac
23
25
  cmd_status
24
26
  when "setup"
25
27
  cmd_setup
28
+ when "board"
29
+ cmd_board(args)
26
30
  else
27
31
  print_help
28
32
  end
@@ -97,6 +101,463 @@ module Brainiac
97
101
  puts "Webhook URL: https://<your-ngrok>.ngrok-free.app/fizzy/<board-key>"
98
102
  end
99
103
 
104
+ def cmd_board(args)
105
+ sub = args.shift
106
+ case sub
107
+ when "setup", "add"
108
+ board_setup
109
+ when "list", "ls"
110
+ board_list
111
+ when "assign"
112
+ board_assign(args)
113
+ when "columns", "refresh"
114
+ board_columns(args)
115
+ when "webhook"
116
+ board_webhook(args)
117
+ else
118
+ puts "Usage: brainiac fizzy board <setup|list|assign|columns|webhook>"
119
+ puts ""
120
+ puts "Commands:"
121
+ puts " setup Add a new board (interactive, fetches columns from Fizzy)"
122
+ puts " list List configured boards and their columns"
123
+ puts " assign <project> <board_key> Assign a project to a board"
124
+ puts " columns <board_key> Refresh columns for a board from Fizzy"
125
+ puts " webhook <board_key> [url] Create/replace webhook and save the signing secret"
126
+ end
127
+ end
128
+
129
+ # --- board setup (split into phases) ---
130
+
131
+ def board_setup
132
+ puts "Fizzy Board Setup"
133
+ puts "================="
134
+ puts ""
135
+
136
+ board = board_setup_select_board
137
+ return unless board
138
+
139
+ board_key = board_setup_choose_key(board["name"])
140
+ column_map = board_setup_map_columns(board["id"], board["name"])
141
+ secret = board_setup_ask_secret(board_key)
142
+
143
+ config = board_setup_save(board_key, board["id"], column_map, secret)
144
+
145
+ puts ""
146
+ puts "✓ Board \"#{board["name"]}\" added as '#{board_key}' in #{FIZZY_CONFIG_FILE}"
147
+ puts " Columns: #{column_map.keys.join(", ")}" unless column_map.empty?
148
+
149
+ board_setup_offer_webhook(config, board_key, board["id"])
150
+
151
+ puts ""
152
+ puts "Next steps:"
153
+ puts " brainiac fizzy board assign <project-key> #{board_key}"
154
+ end
155
+
156
+ def board_setup_select_board
157
+ boards_json = run_fizzy("board", "list", "--all", "--json")
158
+ unless boards_json
159
+ puts "Error: Could not fetch boards from Fizzy CLI."
160
+ puts " Ensure 'fizzy' is on your PATH and authenticated."
161
+ puts " Run: fizzy doctor"
162
+ return nil
163
+ end
164
+
165
+ boards = JSON.parse(boards_json)["data"] || []
166
+ if boards.empty?
167
+ puts "No boards found in your Fizzy account."
168
+ return nil
169
+ end
170
+
171
+ puts "Available boards:"
172
+ boards.each_with_index do |board, i|
173
+ puts " #{i + 1}) #{board["name"]} (#{board["id"]})"
174
+ end
175
+ puts ""
176
+ print "Select board number: "
177
+ choice = $stdin.gets&.chomp&.to_i
178
+ return puts("Cancelled.") unless choice&.positive? && choice <= boards.size
179
+
180
+ boards[choice - 1]
181
+ end
182
+
183
+ def board_setup_choose_key(board_name)
184
+ suggested_key = board_name.downcase.gsub(/[^a-z0-9]+/, "_").gsub(/^_|_$/, "")
185
+ print "Board key for config [#{suggested_key}]: "
186
+ board_key = $stdin.gets&.chomp
187
+ board_key = suggested_key if board_key.nil? || board_key.empty?
188
+ board_key
189
+ end
190
+
191
+ def board_setup_map_columns(board_id, board_name)
192
+ columns_json = run_fizzy("column", "list", "--board", board_id, "--json")
193
+ columns = columns_json ? (JSON.parse(columns_json)["data"] || []) : []
194
+ custom_columns = columns.reject { |c| c["pseudo"] }
195
+
196
+ puts ""
197
+ puts "Columns for \"#{board_name}\":"
198
+ if columns.empty?
199
+ puts " (no columns found)"
200
+ else
201
+ columns.each do |col|
202
+ pseudo_tag = col["pseudo"] ? " [built-in]" : ""
203
+ puts " • #{col["name"]} (#{col["id"]})#{pseudo_tag}"
204
+ end
205
+ end
206
+
207
+ puts ""
208
+ puts "Which columns should brainiac track? Enter config names for each."
209
+ puts "(These map to column transitions like right_now, needs_review, uat, etc.)"
210
+ puts "Leave blank to skip a column."
211
+ puts ""
212
+
213
+ prompt_column_mapping(custom_columns)
214
+ end
215
+
216
+ def board_setup_ask_secret(board_key)
217
+ puts ""
218
+ puts "Webhook setup:"
219
+ puts " Fizzy generates the signing secret when you create a webhook."
220
+ print "Paste the webhook signing_secret from Fizzy (or 'skip' to set later): "
221
+ secret = $stdin.gets&.chomp
222
+ if secret.nil? || secret.empty? || secret == "skip"
223
+ puts " ⚠ No secret set — you'll need to add it to fizzy.json manually later."
224
+ puts " Create the webhook in Fizzy, then paste the signing_secret into:"
225
+ puts " #{FIZZY_CONFIG_FILE} → boards.#{board_key}.webhook_secret"
226
+ nil
227
+ else
228
+ secret
229
+ end
230
+ end
231
+
232
+ def board_setup_save(board_key, board_id, column_map, secret)
233
+ config = load_fizzy_config
234
+ config["boards"] ||= {}
235
+ board_entry = { "board_id" => board_id, "columns" => column_map }
236
+ board_entry["webhook_secret"] = secret if secret
237
+ config["boards"][board_key] = board_entry
238
+ save_fizzy_config(config)
239
+ config
240
+ end
241
+
242
+ def board_setup_offer_webhook(config, board_key, board_id)
243
+ puts ""
244
+ print "Create webhook in Fizzy now? [Y/n]: "
245
+ answer = $stdin.gets&.chomp&.downcase
246
+ return if answer == "n"
247
+
248
+ webhook_url = prompt_webhook_url(board_key)
249
+ return unless webhook_url && !webhook_url.empty?
250
+
251
+ signing_secret = create_fizzy_webhook(board_id, board_key, webhook_url)
252
+ return unless signing_secret
253
+
254
+ config["boards"][board_key]["webhook_secret"] = signing_secret
255
+ save_fizzy_config(config)
256
+ puts "✓ Webhook created! Signing secret saved to fizzy.json."
257
+ end
258
+
259
+ # --- board list ---
260
+
261
+ def board_list
262
+ config = load_fizzy_config
263
+ boards = config["boards"] || {}
264
+
265
+ if boards.empty?
266
+ puts "No boards configured."
267
+ puts "Run 'brainiac fizzy board setup' to add one."
268
+ return
269
+ end
270
+
271
+ projects = load_projects_config
272
+
273
+ puts "Configured boards:"
274
+ boards.each do |key, board_config|
275
+ puts ""
276
+ puts " #{key}:"
277
+ puts " Board ID: #{board_config["board_id"]}"
278
+ puts " Webhook: #{board_config["webhook_secret"] ? "configured" : "not set"}"
279
+
280
+ columns = board_config["columns"] || {}
281
+ if columns.any?
282
+ puts " Columns:"
283
+ columns.each { |name, id| puts " #{name}: #{id}" }
284
+ else
285
+ puts " Columns: (none configured)"
286
+ end
287
+
288
+ assigned = projects.select { |_, cfg| cfg["fizzy_board"] == key }.keys
289
+ puts " Projects: #{assigned.any? ? assigned.join(", ") : "(none)"}"
290
+ end
291
+ end
292
+
293
+ # --- board assign ---
294
+
295
+ def board_assign(args)
296
+ project_key = args.shift
297
+ board_key = args.shift
298
+
299
+ unless project_key && board_key
300
+ puts "Usage: brainiac fizzy board assign <project-key> <board-key>"
301
+ puts ""
302
+ puts "Available boards:"
303
+ config = load_fizzy_config
304
+ (config["boards"] || {}).each_key { |k| puts " #{k}" }
305
+ puts ""
306
+ puts "Available projects:"
307
+ load_projects_config.each_key { |k| puts " #{k}" }
308
+ return
309
+ end
310
+
311
+ config = load_fizzy_config
312
+ unless config.dig("boards", board_key)
313
+ puts "Error: Board '#{board_key}' not found in fizzy.json."
314
+ puts "Available: #{(config["boards"] || {}).keys.join(", ")}"
315
+ return
316
+ end
317
+
318
+ projects = load_projects_config
319
+ unless projects.key?(project_key)
320
+ puts "Error: Project '#{project_key}' not found in projects.json."
321
+ puts "Available: #{projects.keys.join(", ")}"
322
+ return
323
+ end
324
+
325
+ projects[project_key]["fizzy_board"] = board_key
326
+ save_projects_config(projects)
327
+
328
+ puts "✓ Assigned project '#{project_key}' to board '#{board_key}'"
329
+ end
330
+
331
+ # --- board columns ---
332
+
333
+ def board_columns(args)
334
+ board_key = args.shift
335
+ unless board_key
336
+ puts "Usage: brainiac fizzy board columns <board-key>"
337
+ puts ""
338
+ puts "Fetches current columns from Fizzy and lets you update the config."
339
+ return
340
+ end
341
+
342
+ config = load_fizzy_config
343
+ board_config = config.dig("boards", board_key)
344
+ unless board_config
345
+ puts "Error: Board '#{board_key}' not found in fizzy.json."
346
+ puts "Available: #{(config["boards"] || {}).keys.join(", ")}"
347
+ return
348
+ end
349
+
350
+ board_id = board_config["board_id"]
351
+ columns_json = run_fizzy("column", "list", "--board", board_id, "--json")
352
+ unless columns_json
353
+ puts "Error: Could not fetch columns from Fizzy."
354
+ return
355
+ end
356
+
357
+ columns = JSON.parse(columns_json)["data"] || []
358
+ custom_columns = columns.reject { |c| c["pseudo"] }
359
+ existing_map = board_config["columns"] || {}
360
+
361
+ puts "Columns for board '#{board_key}' (#{board_id}):"
362
+ puts ""
363
+
364
+ columns.each do |col|
365
+ pseudo_tag = col["pseudo"] ? " [built-in]" : ""
366
+ existing_key = existing_map.key(col["id"])
367
+ mapped = existing_key ? " → #{existing_key}" : ""
368
+ puts " • #{col["name"]} (#{col["id"]})#{pseudo_tag}#{mapped}"
369
+ end
370
+
371
+ puts ""
372
+ puts "Update column mappings? (Enter new config keys, blank to keep, '-' to remove)"
373
+ puts ""
374
+
375
+ new_map = prompt_column_mapping(custom_columns, existing_map)
376
+
377
+ config["boards"][board_key]["columns"] = new_map
378
+ save_fizzy_config(config)
379
+
380
+ puts ""
381
+ puts "✓ Updated columns for '#{board_key}': #{new_map.keys.join(", ")}"
382
+ end
383
+
384
+ # --- board webhook (split into phases) ---
385
+
386
+ def board_webhook(args)
387
+ board_key = args.shift
388
+ webhook_url = args.shift
389
+
390
+ unless board_key
391
+ puts "Usage: brainiac fizzy board webhook <board-key> [payload-url]"
392
+ puts ""
393
+ puts "Creates a webhook in Fizzy for the board and saves the signing secret."
394
+ puts "If the board already has a webhook, deletes it first."
395
+ puts ""
396
+ puts "Available boards:"
397
+ config = load_fizzy_config
398
+ (config["boards"] || {}).each_key { |k| puts " #{k}" }
399
+ return
400
+ end
401
+
402
+ config = load_fizzy_config
403
+ board_config = config.dig("boards", board_key)
404
+ unless board_config
405
+ puts "Error: Board '#{board_key}' not found in fizzy.json."
406
+ return
407
+ end
408
+
409
+ board_id = board_config["board_id"]
410
+
411
+ return if remove_existing_webhooks(board_id) == :cancelled
412
+
413
+ webhook_url ||= prompt_webhook_url(board_key)
414
+ if webhook_url.nil? || webhook_url.empty?
415
+ puts "Error: Payload URL is required."
416
+ return
417
+ end
418
+
419
+ board_webhook_create_and_save(config, board_key, board_id, webhook_url)
420
+ end
421
+
422
+ def remove_existing_webhooks(board_id)
423
+ existing_json = run_fizzy("webhook", "list", "--board", board_id, "--all", "--json")
424
+ return :proceed unless existing_json
425
+
426
+ existing = JSON.parse(existing_json)["data"] || []
427
+ brainiac_webhooks = existing.select { |w| w["name"]&.start_with?("brainiac") }
428
+ return :proceed unless brainiac_webhooks.any?
429
+
430
+ puts "Existing brainiac webhook(s) found:"
431
+ brainiac_webhooks.each do |w|
432
+ status = w["active"] ? "active" : "inactive"
433
+ puts " • #{w["name"]} (#{status}) → #{w["payload_url"]}"
434
+ end
435
+ print "Delete existing and create new? [Y/n]: "
436
+ answer = $stdin.gets&.chomp&.downcase
437
+ if answer == "n"
438
+ puts "Cancelled."
439
+ return :cancelled
440
+ end
441
+ brainiac_webhooks.each do |w|
442
+ run_fizzy("webhook", "delete", w["id"], "--board", board_id)
443
+ puts " Deleted: #{w["name"]}"
444
+ end
445
+ :proceed
446
+ end
447
+
448
+ def board_webhook_create_and_save(config, board_key, board_id, webhook_url)
449
+ signing_secret = create_fizzy_webhook(board_id, board_key, webhook_url)
450
+ webhook_id = @last_webhook_id
451
+
452
+ if signing_secret
453
+ config["boards"][board_key]["webhook_secret"] = signing_secret
454
+ save_fizzy_config(config)
455
+ puts "✓ Webhook created (ID: #{webhook_id})"
456
+ puts " URL: #{webhook_url}"
457
+ puts " Signing secret saved to fizzy.json"
458
+ else
459
+ puts "✓ Webhook created but no signing_secret in response."
460
+ puts " Check: fizzy webhook show #{webhook_id} --board #{board_id}"
461
+ end
462
+ end
463
+
464
+ # --- shared helpers ---
465
+
466
+ def prompt_column_mapping(columns, existing_map = {})
467
+ column_map = {}
468
+ columns.each do |col|
469
+ existing_key = existing_map.key(col["id"])
470
+ suggested = existing_key || col["name"].downcase.gsub(/[^a-z0-9]+/, "_").gsub(/^_|_$/, "")
471
+ print " \"#{col["name"]}\" → config key [#{suggested}]: "
472
+ key = $stdin.gets&.chomp
473
+ key = suggested if key.nil? || key.empty?
474
+ next if ["-", "skip"].include?(key)
475
+
476
+ column_map[key] = col["id"]
477
+ end
478
+ column_map
479
+ end
480
+
481
+ def prompt_webhook_url(board_key)
482
+ detected_url = detect_ngrok_url
483
+ if detected_url
484
+ default_url = "#{detected_url}/fizzy/#{board_key}"
485
+ print "Webhook payload URL [#{default_url}]: "
486
+ input = $stdin.gets&.chomp
487
+ input.nil? || input.empty? ? default_url : input
488
+ else
489
+ print "Webhook payload URL (e.g., https://your-ngrok.app/fizzy/#{board_key}): "
490
+ $stdin.gets&.chomp
491
+ end
492
+ end
493
+
494
+ def create_fizzy_webhook(board_id, board_key, webhook_url)
495
+ actions = "card_assigned,card_closed,card_published,card_reopened,card_triaged,comment_created"
496
+ webhook_json = run_fizzy("webhook", "create", "--board", board_id,
497
+ "--name", "brainiac-#{board_key}",
498
+ "--url", webhook_url,
499
+ "--actions", actions, "--json")
500
+ unless webhook_json
501
+ puts "⚠ Failed to create webhook. Create it manually in Fizzy."
502
+ return nil
503
+ end
504
+
505
+ webhook_data = JSON.parse(webhook_json)["data"]
506
+ @last_webhook_id = webhook_data&.dig("id")
507
+ webhook_data&.dig("signing_secret")
508
+ end
509
+
510
+ def load_fizzy_config
511
+ if File.exist?(FIZZY_CONFIG_FILE)
512
+ JSON.parse(File.read(FIZZY_CONFIG_FILE))
513
+ else
514
+ { "boards" => {}, "authorized_users" => [] }
515
+ end
516
+ rescue JSON::ParserError
517
+ { "boards" => {}, "authorized_users" => [] }
518
+ end
519
+
520
+ def save_fizzy_config(config)
521
+ File.write(FIZZY_CONFIG_FILE, JSON.pretty_generate(config))
522
+ end
523
+
524
+ def load_projects_config
525
+ if File.exist?(PROJECTS_FILE)
526
+ JSON.parse(File.read(PROJECTS_FILE))
527
+ else
528
+ {}
529
+ end
530
+ rescue JSON::ParserError
531
+ {}
532
+ end
533
+
534
+ def save_projects_config(projects)
535
+ File.write(PROJECTS_FILE, JSON.pretty_generate(projects))
536
+ end
537
+
538
+ def run_fizzy(*)
539
+ require "open3"
540
+ output, status = Open3.capture2("fizzy", *)
541
+ status.success? ? output : nil
542
+ rescue Errno::ENOENT
543
+ nil
544
+ end
545
+
546
+ def detect_ngrok_url
547
+ require "net/http"
548
+ uri = URI("http://127.0.0.1:4040/api/tunnels")
549
+ http = Net::HTTP.new(uri.host, uri.port)
550
+ http.open_timeout = 2
551
+ http.read_timeout = 2
552
+ response = http.get(uri.path)
553
+ data = JSON.parse(response.body)
554
+ tunnels = data["tunnels"] || []
555
+ https_tunnel = tunnels.find { |t| t["public_url"]&.start_with?("https://") }
556
+ https_tunnel&.dig("public_url")
557
+ rescue StandardError
558
+ nil
559
+ end
560
+
100
561
  def print_help
101
562
  puts <<~HELP
102
563
  Usage: brainiac fizzy <command>
@@ -105,6 +566,10 @@ module Brainiac
105
566
  config Show Fizzy config
106
567
  status Check Fizzy status via server API
107
568
  setup Show setup guide
569
+ board setup Add a new board (interactive, fetches columns from Fizzy)
570
+ board list List configured boards and their columns
571
+ board assign <project> <board_key> Assign a project to a board
572
+ board columns <board_key> Refresh columns for a board from Fizzy
108
573
 
109
574
  Fizzy handles card assignment, comments, @mentions, cross-agent reviews,
110
575
  duplicate detection, and planning mode via webhooks.
@@ -155,7 +620,6 @@ module Brainiac
155
620
  config = JSON.parse(File.read(config_file))
156
621
  config["authorized_users"] ||= []
157
622
 
158
- # Don't add if already present
159
623
  existing = config["authorized_users"].find { |u| u["id"] == user_id || u["name"]&.downcase == display_name.downcase }
160
624
  if existing
161
625
  puts " ✓ #{display_name} already in authorized_users (id: #{existing["id"]})"
@@ -336,9 +336,38 @@ module Brainiac
336
336
  LOG.info "[Fizzy:CardIndex] Starting background backfill..."
337
337
  CARD_INDEX.backfill
338
338
  end
339
+
340
+ # Auto-reactivate deactivated webhooks in background
341
+ Thread.new { check_and_reactivate_webhooks }
339
342
  end
340
343
  end
341
344
 
345
+ def check_and_reactivate_webhooks
346
+ boards = Config.boards
347
+ return if boards.empty?
348
+
349
+ env = Helpers.default_fizzy_env
350
+ boards.each do |board_key, board_config|
351
+ board_id = board_config["board_id"]
352
+ next unless board_id
353
+
354
+ output = run_cmd("fizzy", "webhook", "list", "--board", board_id, "--all", "--json", env: env)
355
+ webhooks = JSON.parse(output)["data"] || []
356
+
357
+ webhooks.each do |webhook|
358
+ next unless webhook["name"]&.start_with?("brainiac")
359
+ next if webhook["active"]
360
+
361
+ LOG.info "[Fizzy] Reactivating webhook '#{webhook["name"]}' on board '#{board_key}' (was inactive)"
362
+ run_cmd("fizzy", "webhook", "reactivate", webhook["id"], "--board", board_id, env: env)
363
+ end
364
+ rescue StandardError => e
365
+ LOG.warn "[Fizzy] Could not check webhooks for board '#{board_key}': #{e.message}"
366
+ end
367
+ rescue StandardError => e
368
+ LOG.warn "[Fizzy] Webhook reactivation check failed: #{e.message}"
369
+ end
370
+
342
371
  # Detect CLI provider from Fizzy card tags (e.g., cli-grok tag)
343
372
  def register_detect_cli_provider
344
373
  Brainiac.on(:detect_cli_provider) do |ctx|
@@ -23,8 +23,12 @@ module Brainiac
23
23
  ### Screenshots (MANDATORY for UI changes)
24
24
  If you touched any `.js`, `.jsx`, `.css`, or `.html` in a web app directory and `./scripts/screenshot-page.sh` exists, screenshot every affected page.
25
25
 
26
- ### Retrieving Full Comment Text
27
- If you need the full text of a truncated comment, run: `fizzy comment show COMMENT_ID --card CARD_NUMBER`
26
+ ### Fizzy CLI Tips
27
+ - Use `--jq` for filtering output (built-in, never pipe to external jq): `fizzy card list --jq '[.data[] | {number, title}]'`
28
+ - Use `fizzy search "query"` for cross-board full-text search
29
+ - Use `fizzy card list --search "term"` for structured filtering within a board
30
+ - Use `--agent` flag for raw JSON data without envelope when parsing output
31
+ - Retrieve full comment text: `fizzy comment show COMMENT_ID --card CARD_NUMBER`
28
32
 
29
33
  ### Card Memory Discipline (CRITICAL for long-running cards)
30
34
  When writing your memory file for a Fizzy card session, include:
@@ -40,8 +44,8 @@ module Brainiac
40
44
  Re-fetch the card to see if anything changed while you were working:
41
45
 
42
46
  ```bash
43
- fizzy card show {{CARD_NUMBER}}
44
- fizzy comment list --card {{CARD_NUMBER}}
47
+ fizzy card show {{CARD_NUMBER}} --jq '.data | {title, description, assignees: [.assignees[].name]}'
48
+ fizzy comment list --card {{CARD_NUMBER}} --jq '[.data[-5:] | .[] | {creator: .creator.name, body: .body.plain_text}]'
45
49
  ```
46
50
 
47
51
  Compare against the card context from the start of your session. Check for:
@@ -3,7 +3,7 @@
3
3
  module Brainiac
4
4
  module Plugins
5
5
  module Fizzy
6
- VERSION = "0.0.16"
6
+ VERSION = "0.0.17"
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-fizzy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.16
4
+ version: 0.0.17
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andy Davis