brainiac-basecamp 0.0.25 → 0.0.26

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: 9baa0382677cf44d0ef67156c66420348c00b74e7532f6b410dab9d8e61f7e90
4
- data.tar.gz: 353777dfdc0f84ba57e89b8e36249867e9fec29f46ebfe4af0ac090704e14dff
3
+ metadata.gz: 527e9e3b326e216a5080ae89148317e15530ac84d07ec01e30a90a3676528f9c
4
+ data.tar.gz: 436a083dda6818c8328df04179f3789d9febc0f4f6bd3016f744d7cd09921bc8
5
5
  SHA512:
6
- metadata.gz: 8f2eee7436544bcfc8278bbb22add64237c6dc4bf4256930566741ce60f683364ec24e9d2784d6765ca418bada76e6f5be8cbbc625b2384f64d1b4d5b1f6d65b
7
- data.tar.gz: a72b44713badc00c8f3bbfc4c433afbf832550e11675d9bb8e384131209c4f1a1d1d810be885fe620bf68762cf1632cf855c209c617ad3b5a57df044895f6150
6
+ metadata.gz: 5cfd4aba7b96d8fdc49c368dab4dc76c8f21f2a29052ff6f8271dcee4cc824e95f9036aeb0325a540c9c082194b9d3854705092629ea9020fb16797ffe3d413f
7
+ data.tar.gz: 97ee914315cd7f978a3b736553db059e572a3bd629950cc7ed7220d644bdf6b6d89bda0d013e317a87b9b70c21069e7b4e3776563b82f20e062f59c67f260bfa
@@ -986,9 +986,15 @@ module Brainiac
986
986
  # Reset the task
987
987
  reset_task_to(task, target_status)
988
988
 
989
+ # If completing this task leaves every task in the epic complete,
990
+ # seal the epic in the same atomic write so the reconcile loop never
991
+ # re-fires the completion notification.
992
+ finalized = finalize_epic_if_all_complete!(epic)
993
+
989
994
  save_epics(epics)
990
995
  puts "✓ Reset card ##{card_number} from '#{old_status}' → '#{target_status}'"
991
996
  puts " Epic: #{epic['title']}"
997
+ puts "✓ All tasks complete — epic finalized (status=complete, notification suppressed)" if finalized
992
998
 
993
999
  return unless target_status == "pending"
994
1000
 
@@ -1096,8 +1102,11 @@ module Brainiac
1096
1102
  tasks_to_reset.each { |t| reset_task_to(t, target_status) }
1097
1103
  epic["updated_at"] = Time.now.iso8601
1098
1104
 
1105
+ finalized = finalize_epic_if_all_complete!(epic)
1106
+
1099
1107
  save_epics(epics)
1100
1108
  puts "✓ Reset #{tasks_to_reset.size} task(s) → '#{target_status}' in epic '#{epic['title']}'"
1109
+ puts "✓ All tasks complete — epic finalized (status=complete, notification suppressed)" if finalized
1101
1110
  puts ""
1102
1111
  epic["tasks"].each do |t|
1103
1112
  icon = case t["status"]
@@ -1169,9 +1178,31 @@ module Brainiac
1169
1178
  task["awaiting_final_decision"] = true
1170
1179
  when "complete"
1171
1180
  task["completed_at"] ||= Time.now.iso8601
1181
+ # A completed task is no longer awaiting a final decision. Leaving
1182
+ # this true lets reconcile_final_decision_task treat the task as
1183
+ # unsettled and re-dispatch/re-complete it on the next sweep.
1184
+ task["awaiting_final_decision"] = false
1172
1185
  end
1173
1186
  end
1174
1187
 
1188
+ # Seal an epic when a reset leaves every task complete. Without this, an
1189
+ # epic can sit status="active" with all tasks done — exactly the
1190
+ # thrash-prone state where the 90s reconcile loop re-detects "all
1191
+ # complete", re-runs complete_epic, and re-posts the "🎉 Epic completed"
1192
+ # notification on every sweep. Setting completion_notified suppresses a
1193
+ # notification for this manual, operator-driven completion. Returns true
1194
+ # if the epic was finalized.
1195
+ def finalize_epic_if_all_complete!(epic)
1196
+ return false unless epic["tasks"]&.any?
1197
+ return false unless epic["tasks"].all? { |t| t["status"] == "complete" }
1198
+ return false if epic["status"] == "complete"
1199
+
1200
+ epic["status"] = "complete"
1201
+ epic["completed_at"] ||= Time.now.iso8601
1202
+ epic["completion_notified"] = true
1203
+ true
1204
+ end
1205
+
1175
1206
  def load_epics
1176
1207
  epics_file = File.join(BRAINIAC_DIR, "basecamp_epics.json")
1177
1208
  return [] unless File.exist?(epics_file)
@@ -3,7 +3,7 @@
3
3
  module Brainiac
4
4
  module Plugins
5
5
  module Basecamp
6
- VERSION = "0.0.25"
6
+ VERSION = "0.0.26"
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.25
4
+ version: 0.0.26
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andy Davis