enhance_swarm 2.0.0 โ†’ 2.1.1

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.
Files changed (106) hide show
  1. checksums.yaml +4 -4
  2. data/.claude/CLAUDE.md +164 -0
  3. data/.claude/MCP.md +117 -0
  4. data/.claude/PERSONAS.md +114 -0
  5. data/.claude/RULES.md +221 -0
  6. data/.enhance_swarm/logs/general_output.log +0 -404
  7. data/.enhance_swarm.yml +33 -0
  8. data/CHANGELOG.md +71 -0
  9. data/PRODUCTION_INSTALL_TEST.md +117 -0
  10. data/README.md +129 -3
  11. data/lib/enhance_swarm/agent_spawner.rb +218 -12
  12. data/lib/enhance_swarm/cli.rb +130 -1
  13. data/lib/enhance_swarm/task_coordinator.rb +363 -86
  14. data/lib/enhance_swarm/version.rb +1 -1
  15. metadata +14 -97
  16. data/PRODUCTION_TEST_LOG.md +0 -502
  17. data/debug_agent_spawner.rb +0 -99
  18. data/debug_cli_spawn.rb +0 -95
  19. data/debug_fixes.rb +0 -209
  20. data/debug_script_execution.rb +0 -124
  21. data/debug_session_issue.rb +0 -87
  22. data/debug_spawn.rb +0 -113
  23. data/debug_spawn_step_by_step.rb +0 -190
  24. data/debug_worktree.rb +0 -77
  25. data/enhance_swarm-0.1.1.gem +0 -0
  26. data/enhance_swarm-1.0.0.gem +0 -0
  27. data/final_validation_test.rb +0 -199
  28. data/setup.sh +0 -86
  29. data/test_blog_app/.enhance_swarm/archives/session_1751187575_e119ea73_20250629_105935.json +0 -16
  30. data/test_blog_app/.enhance_swarm/archives/session_1751187637_7fda97dd_20250629_110037.json +0 -32
  31. data/test_blog_app/.enhance_swarm/archives/session_1751190527_4c99147e_20250629_114847.json +0 -32
  32. data/test_blog_app/.enhance_swarm/archives/session_1751190541_8dc83406_20250629_114901.json +0 -16
  33. data/test_blog_app/.ruby-version +0 -1
  34. data/test_blog_app/Gemfile +0 -18
  35. data/test_blog_app/Gemfile.lock +0 -206
  36. data/test_blog_app/README.md +0 -24
  37. data/test_blog_app/Rakefile +0 -6
  38. data/test_blog_app/app/assets/images/.keep +0 -0
  39. data/test_blog_app/app/assets/stylesheets/application.css +0 -10
  40. data/test_blog_app/app/controllers/application_controller.rb +0 -4
  41. data/test_blog_app/app/controllers/concerns/.keep +0 -0
  42. data/test_blog_app/app/helpers/application_helper.rb +0 -2
  43. data/test_blog_app/app/models/application_record.rb +0 -3
  44. data/test_blog_app/app/models/concerns/.keep +0 -0
  45. data/test_blog_app/app/views/layouts/application.html.erb +0 -27
  46. data/test_blog_app/app/views/pwa/manifest.json.erb +0 -22
  47. data/test_blog_app/app/views/pwa/service-worker.js +0 -26
  48. data/test_blog_app/bin/dev +0 -2
  49. data/test_blog_app/bin/rails +0 -4
  50. data/test_blog_app/bin/rake +0 -4
  51. data/test_blog_app/bin/setup +0 -34
  52. data/test_blog_app/config/application.rb +0 -42
  53. data/test_blog_app/config/boot.rb +0 -3
  54. data/test_blog_app/config/credentials.yml.enc +0 -1
  55. data/test_blog_app/config/database.yml +0 -32
  56. data/test_blog_app/config/environment.rb +0 -5
  57. data/test_blog_app/config/environments/development.rb +0 -51
  58. data/test_blog_app/config/environments/production.rb +0 -67
  59. data/test_blog_app/config/environments/test.rb +0 -42
  60. data/test_blog_app/config/initializers/assets.rb +0 -7
  61. data/test_blog_app/config/initializers/content_security_policy.rb +0 -25
  62. data/test_blog_app/config/initializers/filter_parameter_logging.rb +0 -8
  63. data/test_blog_app/config/initializers/inflections.rb +0 -16
  64. data/test_blog_app/config/locales/en.yml +0 -31
  65. data/test_blog_app/config/master.key +0 -1
  66. data/test_blog_app/config/puma.rb +0 -38
  67. data/test_blog_app/config/routes.rb +0 -14
  68. data/test_blog_app/config.ru +0 -6
  69. data/test_blog_app/db/seeds.rb +0 -9
  70. data/test_blog_app/lib/tasks/.keep +0 -0
  71. data/test_blog_app/log/.keep +0 -0
  72. data/test_blog_app/public/400.html +0 -114
  73. data/test_blog_app/public/404.html +0 -114
  74. data/test_blog_app/public/406-unsupported-browser.html +0 -114
  75. data/test_blog_app/public/422.html +0 -114
  76. data/test_blog_app/public/500.html +0 -114
  77. data/test_blog_app/public/icon.png +0 -0
  78. data/test_blog_app/public/icon.svg +0 -3
  79. data/test_blog_app/public/robots.txt +0 -1
  80. data/test_blog_app/script/.keep +0 -0
  81. data/test_blog_app/storage/.keep +0 -0
  82. data/test_blog_app/test/controllers/.keep +0 -0
  83. data/test_blog_app/test/fixtures/files/.keep +0 -0
  84. data/test_blog_app/test/helpers/.keep +0 -0
  85. data/test_blog_app/test/integration/.keep +0 -0
  86. data/test_blog_app/test/models/.keep +0 -0
  87. data/test_blog_app/test/test_helper.rb +0 -15
  88. data/test_blog_app/test_enhance_swarm_e2e.rb +0 -244
  89. data/test_blog_app/test_realistic_workflow.rb +0 -292
  90. data/test_blog_app/tmp/.keep +0 -0
  91. data/test_blog_app/tmp/pids/.keep +0 -0
  92. data/test_blog_app/tmp/storage/.keep +0 -0
  93. data/test_blog_app/vendor/.keep +0 -0
  94. data/test_builtin_functionality.rb +0 -121
  95. data/test_complete_system.rb +0 -267
  96. data/test_core_components.rb +0 -156
  97. data/test_real_claude_integration.rb +0 -285
  98. data/test_security.rb +0 -150
  99. data/test_smart_defaults.rb +0 -155
  100. data/test_task_integration.rb +0 -173
  101. data/test_web_ui.rb +0 -245
  102. data/web/assets/css/main.css +0 -645
  103. data/web/assets/js/kanban.js +0 -499
  104. data/web/assets/js/main.js +0 -525
  105. data/web/templates/dashboard.html.erb +0 -226
  106. data/web/templates/kanban.html.erb +0 -193
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'timeout'
3
4
  require_relative 'logger'
4
5
  require_relative 'agent_spawner'
5
6
  require_relative 'session_manager'
@@ -314,13 +315,15 @@ module EnhanceSwarm
314
315
  "Establish proper API endpoints and webhook architecture"
315
316
  ],
316
317
  best_practices: [
318
+ "ALWAYS use magic comments (# ๐Ÿš…) for Super Scaffolding insertion points",
319
+ "Models use gem concerns (include ModelNames::Base) - most logic is in gems",
320
+ "Use BULLET_TRAIN_VERSION constant for version synchronization",
317
321
  "Primary model NOT in own namespace (e.g., Subscription, Subscriptions::Plan)",
318
322
  "Team-based ownership over user-based ownership",
319
- "Use Super Scaffolding for ALL CRUD operations",
320
- "Always bin/resolve before customizing framework files",
321
- "Configure full plugin ecosystem by default",
322
- "Implement CanCanCan roles with inheritance",
323
- "Follow shallow nesting for complex routes"
323
+ "Use bin/resolve --interactive for complex file discovery",
324
+ "Follow shallow nesting with namespace :v1 for API routes",
325
+ "Configure real BT roles structure with manageable_roles",
326
+ "Use bin/configure and bin/setup for project initialization"
324
327
  ],
325
328
  shared_knowledge: "You are the expert on Bullet Train architecture and must establish the foundation correctly for other agents to build upon"
326
329
  }
@@ -546,6 +549,9 @@ module EnhanceSwarm
546
549
  # Validate phase completion before proceeding
547
550
  if phase_results.all? { |result| result[:success] }
548
551
  Logger.info("โœ… Phase #{index + 1} completed successfully")
552
+
553
+ # CRITICAL: Merge all agent worktree changes back to main project
554
+ merge_agent_changes_to_main(phase_results)
549
555
  else
550
556
  Logger.error("โŒ Phase #{index + 1} had failures, stopping execution")
551
557
  break
@@ -554,39 +560,79 @@ module EnhanceSwarm
554
560
  # Brief pause between phases for coordination
555
561
  sleep(2) if index < plan[:phases].length - 1
556
562
  end
563
+
564
+ # Final cleanup and commit of merged changes
565
+ finalize_orchestration_results
557
566
  end
558
567
 
559
568
  def execute_phase(tasks)
560
569
  results = []
570
+ threads = []
561
571
 
562
- # Spawn agents for all tasks in this phase
572
+ Logger.info("๐Ÿš€ Starting parallel execution of #{tasks.length} tasks")
573
+
574
+ # Execute tasks in parallel threads
563
575
  tasks.each do |task|
564
- enhanced_prompt = build_enhanced_task_prompt(task)
565
-
566
- result = @agent_spawner.spawn_agent(
567
- role: task[:role],
568
- task: enhanced_prompt,
569
- worktree: true
570
- )
571
-
572
- if result
573
- @agent_assignments[task[:id]] = result
574
- results << { task_id: task[:id], success: true, agent_info: result }
575
- Logger.info("โœ… Spawned #{task[:role]} agent for task: #{task[:id]}")
576
- else
577
- # CRITICAL FIX: Execute task directly when spawning fails
578
- Logger.warn("โš ๏ธ Agent spawn failed, control agent executing task directly")
579
- direct_result = execute_task_directly(task)
580
- results << { task_id: task[:id], success: direct_result, executed_directly: true }
576
+ thread = Thread.new do
577
+ Thread.current[:task_id] = task[:id]
578
+ Thread.current[:role] = task[:role]
581
579
 
582
- if direct_result
583
- Logger.info("โœ… Control agent completed task directly: #{task[:id]}")
584
- else
585
- Logger.error("โŒ Control agent failed to execute task: #{task[:id]}")
580
+ begin
581
+ enhanced_prompt = build_enhanced_task_prompt(task)
582
+
583
+ # Try agent spawning first
584
+ result = @agent_spawner.spawn_agent(
585
+ role: task[:role],
586
+ task: enhanced_prompt,
587
+ worktree: true
588
+ )
589
+
590
+ if result
591
+ @agent_assignments[task[:id]] = result
592
+ Logger.info("โœ… Spawned #{task[:role]} agent for task: #{task[:id]}")
593
+ { task_id: task[:id], success: true, agent_info: result }
594
+ else
595
+ # Fallback to direct execution
596
+ Logger.warn("โš ๏ธ Agent spawn failed for #{task[:role]}, executing directly")
597
+ direct_result = execute_task_directly(task)
598
+
599
+ if direct_result
600
+ Logger.info("โœ… Control agent completed task directly: #{task[:id]}")
601
+ else
602
+ Logger.error("โŒ Control agent failed to execute task: #{task[:id]}")
603
+ end
604
+
605
+ { task_id: task[:id], success: direct_result, executed_directly: true }
606
+ end
607
+ rescue StandardError => e
608
+ Logger.error("๐Ÿ’ฅ Task #{task[:id]} failed: #{e.message}")
609
+ { task_id: task[:id], success: false, error: e.message }
586
610
  end
587
611
  end
612
+
613
+ threads << thread
588
614
  end
589
615
 
616
+ # Wait for all threads with progress updates
617
+ Logger.info("โณ Waiting for parallel task completion...")
618
+ completed = 0
619
+
620
+ while threads.any?(&:alive?)
621
+ sleep(5) # Check every 5 seconds
622
+ previously_completed = completed
623
+ completed = threads.count { |t| !t.alive? }
624
+
625
+ if completed > previously_completed
626
+ Logger.info("๐Ÿ“Š Progress: #{completed}/#{threads.length} tasks completed")
627
+ end
628
+ end
629
+
630
+ # Collect all results
631
+ threads.each do |thread|
632
+ results << thread.value
633
+ end
634
+
635
+ Logger.info("๐ŸŽฏ Phase execution completed: #{results.count { |r| r[:success] }}/#{results.length} successful")
590
636
  results
591
637
  end
592
638
 
@@ -639,21 +685,35 @@ module EnhanceSwarm
639
685
  prompt_file.write(execution_prompt)
640
686
  prompt_file.close
641
687
 
642
- # Execute Claude CLI in the current directory with explicit instructions
688
+ # Execute Claude CLI with timeout controls
643
689
  success = false
644
- Dir.chdir(Dir.pwd) do
645
- # Run Claude and capture both output and success
646
- result = system("claude < #{prompt_file.path}")
647
- success = result && $?.success?
690
+ timeout_seconds = 120 # 2 minutes timeout
691
+
692
+ begin
693
+ Logger.info("๐Ÿ”ง Executing Claude CLI with #{timeout_seconds}s timeout...")
648
694
 
649
- if success
650
- Logger.info("โœ… #{task[:role]} task executed successfully")
651
-
652
- # Commit the changes made by this agent
653
- commit_agent_work(task)
654
- else
655
- Logger.error("โŒ #{task[:role]} task execution failed")
695
+ Timeout::timeout(timeout_seconds) do
696
+ Dir.chdir(Dir.pwd) do
697
+ # Run Claude and capture both output and success
698
+ result = system("claude --dangerously-skip-permissions < #{prompt_file.path}")
699
+ success = result && $?.success?
700
+
701
+ if success
702
+ Logger.info("โœ… #{task[:role]} task executed successfully")
703
+
704
+ # Commit the changes made by this agent
705
+ commit_agent_work(task)
706
+ else
707
+ Logger.error("โŒ #{task[:role]} task execution failed")
708
+ end
709
+ end
656
710
  end
711
+ rescue Timeout::Error
712
+ Logger.error("โฐ #{task[:role]} task timed out after #{timeout_seconds} seconds")
713
+ success = false
714
+ rescue StandardError => e
715
+ Logger.error("๐Ÿ’ฅ #{task[:role]} task failed with error: #{e.message}")
716
+ success = false
657
717
  end
658
718
 
659
719
  # Clean up temp files
@@ -922,38 +982,39 @@ module EnhanceSwarm
922
982
  execution_strategy: <<~STRATEGY,
923
983
  ๐Ÿš€ BULLET TRAIN EXECUTION PROTOCOL (v1.24.0) with FULL PLUGIN ECOSYSTEM:
924
984
 
925
- ## 1. INSTALL ALL BULLET TRAIN PLUGINS (DEFAULT)
926
- Essential Gemfile additions:
985
+ ## 1. BULLET TRAIN GEMFILE WITH VERSION SYNC (REAL STRUCTURE)
986
+ Essential Gemfile setup:
927
987
  ```ruby
928
- # Core Framework
929
- gem "bullet_train"
930
- gem "bullet_train-super_scaffolding"
931
- gem "bullet_train-api"
932
- gem "bullet_train-fields"
933
- gem "bullet_train-themes"
934
- gem "bullet_train-themes-light"
935
- gem "bullet_train-themes-tailwind_css"
988
+ # Version sync constant (CRITICAL for BT apps)
989
+ BULLET_TRAIN_VERSION = "1.24.0"
936
990
 
937
- # Security & Access Control
938
- gem "bullet_train-roles"
939
- gem "bullet_train-scope_validator"
940
- gem "bullet_train-obfuscates_id"
941
- gem "bullet_train-has_uuid"
991
+ # Core packages
992
+ gem "bullet_train", BULLET_TRAIN_VERSION
993
+ gem "bullet_train-super_scaffolding", BULLET_TRAIN_VERSION
994
+ gem "bullet_train-api", BULLET_TRAIN_VERSION
995
+ gem "bullet_train-outgoing_webhooks", BULLET_TRAIN_VERSION
996
+ gem "bullet_train-incoming_webhooks", BULLET_TRAIN_VERSION
997
+ gem "bullet_train-themes", BULLET_TRAIN_VERSION
998
+ gem "bullet_train-themes-light", BULLET_TRAIN_VERSION
999
+ gem "bullet_train-integrations", BULLET_TRAIN_VERSION
1000
+ gem "bullet_train-integrations-stripe", BULLET_TRAIN_VERSION
942
1001
 
943
- # Integrations & Webhooks
944
- gem "bullet_train-integrations"
945
- gem "bullet_train-integrations-stripe"
946
- gem "bullet_train-outgoing_webhooks"
947
- gem "bullet_train-incoming_webhooks"
1002
+ # Optional support packages
1003
+ gem "bullet_train-sortable", BULLET_TRAIN_VERSION
1004
+ gem "bullet_train-obfuscates_id", BULLET_TRAIN_VERSION
948
1005
 
949
- # Utilities
950
- gem "bullet_train-sortable"
951
- gem "bullet_train-routes"
952
- gem "bullet_train-serializers"
1006
+ # Core dependencies (keep version sync)
1007
+ gem "bullet_train-fields", BULLET_TRAIN_VERSION
1008
+ gem "bullet_train-has_uuid", BULLET_TRAIN_VERSION
1009
+ gem "bullet_train-roles", BULLET_TRAIN_VERSION
1010
+ gem "bullet_train-scope_validator", BULLET_TRAIN_VERSION
1011
+ gem "bullet_train-super_load_and_authorize_resource", BULLET_TRAIN_VERSION
1012
+ gem "bullet_train-themes-tailwind_css", BULLET_TRAIN_VERSION
953
1013
 
954
- # Billing & Stripe (formerly paid, now free)
955
- gem "bullet_train-billing"
956
- gem "bullet_train-billing-stripe"
1014
+ # Additional essentials
1015
+ gem "devise"
1016
+ gem "pagy"
1017
+ gem "sidekiq"
957
1018
  ```
958
1019
 
959
1020
  ## 2. GEM UNBUNDLING AWARENESS & FILE RESOLUTION
@@ -971,17 +1032,38 @@ module EnhanceSwarm
971
1032
  - Look for gem paths in error messages
972
1033
  - Scan framework concerns: include ModelNameBase
973
1034
 
974
- ## 3. SUPER SCAFFOLDING WITH ANDREW CULVER'S BEST PRACTICES
975
- **Namespacing Rules (Culver Convention):**
976
- - โœ… Primary model NOT in own namespace: Subscription, Subscriptions::Plan
977
- - โŒ Never: Subscriptions::Subscription
978
- - Use simple associations within namespace: belongs_to :question (not :surveys_question)
1035
+ ## 3. MAGIC COMMENTS & GEM CONCERNS (REAL BT PATTERN)
1036
+ ๐Ÿ” **CRITICAL: Use magic comments for Super Scaffolding insertion points**
979
1037
 
980
- **Scaffolding Commands:**
1038
+ **Model Pattern (EXACT structure):**
1039
+ ```ruby
1040
+ class ModelName < ApplicationRecord
1041
+ include ModelNames::Base # Gem concern with most logic
1042
+ include Webhooks::Outgoing::TeamSupport
1043
+ # ๐Ÿš… add concerns above.
1044
+
1045
+ # ๐Ÿš… add belongs_to associations above.
1046
+ # ๐Ÿš… add has_many associations above.
1047
+ # ๐Ÿš… add oauth providers above.
1048
+ # ๐Ÿš… add has_one associations above.
1049
+ # ๐Ÿš… add scopes above.
1050
+ # ๐Ÿš… add validations above.
1051
+ # ๐Ÿš… add callbacks above.
1052
+ # ๐Ÿš… add delegations above.
1053
+ # ๐Ÿš… add methods above.
1054
+ end
1055
+ ```
1056
+
1057
+ **Super Scaffolding Commands:**
981
1058
  - rails generate super_scaffold ModelName Team field:field_type
982
1059
  - rails generate super_scaffold:field ModelName new_field:field_type
983
1060
  - rails generate super_scaffold:join_model --help for many-to-many
984
1061
 
1062
+ **Namespacing Rules (Culver Convention):**
1063
+ - โœ… Primary model NOT in own namespace: Subscription, Subscriptions::Plan
1064
+ - โŒ Never: Subscriptions::Subscription
1065
+ - Use simple associations within namespace: belongs_to :question (not :surveys_question)
1066
+
985
1067
  ## 4. TEAM-CENTRIC ARCHITECTURE (Culver Philosophy)
986
1068
  "Most domain models should belong to a team, not a user"
987
1069
  - Model resources as team-based by default
@@ -989,17 +1071,41 @@ module EnhanceSwarm
989
1071
  - Assign entities to memberships, not users directly
990
1072
  - Enable collaborative access over individual ownership
991
1073
 
992
- ## 5. ROLE SYSTEM CONFIGURATION
1074
+ ## 5. ROLE SYSTEM CONFIGURATION (REAL BT STRUCTURE)
993
1075
  **config/models/roles.yml setup:**
994
1076
  ```yaml
995
- default: []
1077
+ default:
1078
+ models:
1079
+ Team: read
1080
+ Membership:
1081
+ - read
1082
+ - search
1083
+ Platform::Application: read
1084
+ Webhooks::Outgoing::Endpoint: manage
1085
+ Webhooks::Outgoing::Event: read
1086
+ Invitation:
1087
+ - read
1088
+ - create
1089
+ - destroy
1090
+
996
1091
  editor:
997
- includes: default
998
1092
  models:
999
- - Project
1093
+ YourModel::TangibleThing: manage
1094
+ YourModel::CreativeConcept:
1095
+ - read
1096
+ - update
1097
+
1000
1098
  admin:
1001
- includes: [default, editor]
1002
- global: true
1099
+ includes:
1100
+ - editor
1101
+ manageable_roles:
1102
+ - admin
1103
+ - editor
1104
+ models:
1105
+ Team: manage
1106
+ Membership: manage
1107
+ YourModel::CreativeConcept: manage
1108
+ Platform::Application: manage
1003
1109
  ```
1004
1110
 
1005
1111
  ## 6. BILLING & STRIPE INTEGRATION
@@ -1013,13 +1119,51 @@ module EnhanceSwarm
1013
1119
  - bullet_train-incoming_webhooks for external service integration
1014
1120
  - JSON:API compliant webhook payloads
1015
1121
 
1016
- ๐ŸŽฏ BULLET TRAIN SPECIFIC COMMANDS WITH FULL ECOSYSTEM:
1017
- - bundle install (with all plugins)
1018
- - rails generate super_scaffold Project Team name:text_field
1019
- - bin/resolve ProjectsController --eject --open
1020
- - bin/resolve shared/form_with_fields --eject
1021
- - Write("config/models/roles.yml", role_configuration)
1022
- - Configure Stripe: rails credentials:edit
1122
+ ๐ŸŽฏ BULLET TRAIN SPECIFIC COMMANDS (REAL BT WORKFLOW):
1123
+ **Project Setup:**
1124
+ - bundle install (all plugins with version sync)
1125
+ - bin/configure (initial BT setup)
1126
+ - bin/setup (database and assets)
1127
+
1128
+ **Super Scaffolding Workflow:**
1129
+ - rails generate super_scaffold Project Team name:text_field description:trix_editor
1130
+ - bin/resolve Projects::Base --eject --open (if customization needed)
1131
+ - bin/resolve account/projects/_form --eject (for view customization)
1132
+
1133
+ **File Creation with Magic Comments:**
1134
+ - Write("app/models/project.rb", model_with_magic_comments)
1135
+ - Write("config/models/roles.yml", real_bt_roles_structure)
1136
+ - Write("config/routes/api/v1.rb", shallow_nested_routes)
1137
+
1138
+ ## 8. ๐ŸŽจ TAILWIND CSS STYLING (BULLET TRAIN DEFAULT)
1139
+ **CRITICAL: Use Tailwind CSS - NOT Bootstrap or custom CSS**
1140
+ ```erb
1141
+ <!-- Example BT Tailwind patterns -->
1142
+ <div class="bg-white shadow-sm rounded-lg p-6">
1143
+ <h2 class="text-lg font-semibold text-gray-900 mb-4">Projects</h2>
1144
+ <div class="space-y-4">
1145
+ <% @projects.each do |project| %>
1146
+ <div class="border border-gray-200 rounded-md p-4 hover:bg-gray-50">
1147
+ <h3 class="font-medium text-gray-900"><%= project.title %></h3>
1148
+ <p class="text-sm text-gray-600 mt-1"><%= project.description %></p>
1149
+ </div>
1150
+ <% end %>
1151
+ </div>
1152
+ </div>
1153
+ ```
1154
+
1155
+ **BT Tailwind Best Practices:**
1156
+ - Use BT's design tokens: bg-white, text-gray-900, border-gray-200
1157
+ - Follow BT responsive patterns: sm:, md:, lg:, xl:
1158
+ - Use BT component utilities: space-y-*, divide-y, ring-*
1159
+ - Leverage BT theme classes: .btn, .card, .form-input (Tailwind-based)
1160
+ - NEVER mix Bootstrap classes - BT is pure Tailwind CSS
1161
+
1162
+ **Essential BT Commands:**
1163
+ - bin/resolve --interactive (for file discovery)
1164
+ - bin/super-scaffold (alias for rails generate super_scaffold)
1165
+ - bin/theme (for theme customization)
1166
+ - bin/hack (for local gem development)
1023
1167
  STRATEGY
1024
1168
  file_structure: %w[
1025
1169
  app/models app/controllers/account app/controllers/api/v1
@@ -1034,7 +1178,9 @@ module EnhanceSwarm
1034
1178
  'Prefer concerns over full ejection',
1035
1179
  'Full plugin ecosystem utilization',
1036
1180
  'Role-based permissions with inheritance',
1037
- 'Billing and Stripe integration ready'
1181
+ 'Billing and Stripe integration ready',
1182
+ 'Tailwind CSS styling - NEVER Bootstrap',
1183
+ 'BT theme design tokens and components'
1038
1184
  ],
1039
1185
  commands: [
1040
1186
  'bundle install',
@@ -1046,5 +1192,136 @@ module EnhanceSwarm
1046
1192
  ]
1047
1193
  }
1048
1194
  end
1195
+
1196
+ # CRITICAL: Merge agent worktree changes back to main project
1197
+ def merge_agent_changes_to_main(phase_results)
1198
+ Logger.info("๐Ÿ”„ Merging agent changes from worktrees to main project...")
1199
+
1200
+ merged_count = 0
1201
+
1202
+ phase_results.each do |result|
1203
+ next unless result[:success] && result[:agent_info]
1204
+
1205
+ agent_info = result[:agent_info]
1206
+ worktree_path = agent_info[:worktree_path]
1207
+ role = agent_info[:role]
1208
+
1209
+ if worktree_path && Dir.exist?(worktree_path)
1210
+ begin
1211
+ # Copy all relevant files from worktree to main project
1212
+ merge_worktree_to_main(worktree_path, role)
1213
+ merged_count += 1
1214
+ Logger.info("โœ… Merged #{role} agent changes from #{worktree_path}")
1215
+ rescue StandardError => e
1216
+ Logger.error("โŒ Failed to merge #{role} agent changes: #{e.message}")
1217
+ end
1218
+ end
1219
+ end
1220
+
1221
+ Logger.info("๐ŸŽฏ Merged changes from #{merged_count} agents to main project")
1222
+ end
1223
+
1224
+ def merge_worktree_to_main(worktree_path, role)
1225
+ main_dir = Dir.pwd
1226
+
1227
+ # Define critical directories to sync
1228
+ sync_paths = [
1229
+ 'app/',
1230
+ 'db/',
1231
+ 'config/',
1232
+ 'spec/',
1233
+ 'test/',
1234
+ 'lib/',
1235
+ 'Gemfile'
1236
+ ]
1237
+
1238
+ sync_paths.each do |path|
1239
+ source_path = File.join(worktree_path, path)
1240
+ target_path = File.join(main_dir, path)
1241
+
1242
+ if File.exist?(source_path)
1243
+ if File.directory?(source_path)
1244
+ # Recursively copy directory contents
1245
+ copy_directory_contents(source_path, target_path, role)
1246
+ else
1247
+ # Copy individual file
1248
+ copy_file_if_newer(source_path, target_path, role)
1249
+ end
1250
+ end
1251
+ end
1252
+ end
1253
+
1254
+ def copy_directory_contents(source_dir, target_dir, role)
1255
+ require 'fileutils'
1256
+
1257
+ Dir.glob(File.join(source_dir, '**', '*')).each do |source_file|
1258
+ next if File.directory?(source_file)
1259
+
1260
+ relative_path = source_file.sub(source_dir + '/', '')
1261
+ target_file = File.join(target_dir, relative_path)
1262
+
1263
+ # Ensure target directory exists
1264
+ FileUtils.mkdir_p(File.dirname(target_file))
1265
+
1266
+ # Copy file if newer or different
1267
+ copy_file_if_newer(source_file, target_file, role)
1268
+ end
1269
+ end
1270
+
1271
+ def copy_file_if_newer(source_file, target_file, role)
1272
+ require 'fileutils'
1273
+
1274
+ # Always copy from agents - they have the latest work
1275
+ if File.exist?(source_file)
1276
+ begin
1277
+ FileUtils.cp(source_file, target_file)
1278
+ Logger.debug("๐Ÿ“„ Copied #{role}: #{File.basename(target_file)}")
1279
+ rescue StandardError => e
1280
+ Logger.warn("โš ๏ธ Failed to copy #{source_file}: #{e.message}")
1281
+ end
1282
+ end
1283
+ end
1284
+
1285
+ def finalize_orchestration_results
1286
+ Logger.info("๐ŸŽฏ Finalizing orchestration results...")
1287
+
1288
+ begin
1289
+ # Add all merged changes
1290
+ system("git add -A")
1291
+
1292
+ # Create comprehensive commit
1293
+ commit_message = "EnhanceSwarm orchestration: Multi-agent implementation complete"
1294
+ result = system("git commit -m '#{commit_message}' 2>/dev/null")
1295
+
1296
+ if result
1297
+ Logger.info("๐Ÿ“ All orchestration changes committed successfully")
1298
+ else
1299
+ Logger.info("โ„น๏ธ No new changes to commit (agents may have worked in isolation)")
1300
+ end
1301
+
1302
+ # Clean up completed worktrees
1303
+ cleanup_worktrees
1304
+
1305
+ rescue StandardError => e
1306
+ Logger.warn("โš ๏ธ Failed to finalize results: #{e.message}")
1307
+ end
1308
+ end
1309
+
1310
+ def cleanup_worktrees
1311
+ worktree_dir = '.enhance_swarm/worktrees'
1312
+ return unless Dir.exist?(worktree_dir)
1313
+
1314
+ Dir.glob(File.join(worktree_dir, '*')).each do |worktree_path|
1315
+ if Dir.exist?(worktree_path)
1316
+ begin
1317
+ # Remove the worktree using git
1318
+ system("git worktree remove --force #{worktree_path} 2>/dev/null")
1319
+ Logger.debug("๐Ÿงน Cleaned up worktree: #{File.basename(worktree_path)}")
1320
+ rescue StandardError => e
1321
+ Logger.warn("โš ๏ธ Failed to cleanup worktree #{worktree_path}: #{e.message}")
1322
+ end
1323
+ end
1324
+ end
1325
+ end
1049
1326
  end
1050
1327
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module EnhanceSwarm
4
- VERSION = '2.0.0'
4
+ VERSION = '2.1.1'
5
5
  end