enhance_swarm 2.0.0 โ 2.1.0
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 +4 -4
- data/.claude/CLAUDE.md +164 -0
- data/.claude/MCP.md +117 -0
- data/.claude/PERSONAS.md +114 -0
- data/.claude/RULES.md +221 -0
- data/.enhance_swarm/logs/general_output.log +0 -404
- data/.enhance_swarm.yml +33 -0
- data/CHANGELOG.md +71 -0
- data/README.md +128 -3
- data/lib/enhance_swarm/agent_spawner.rb +205 -12
- data/lib/enhance_swarm/cli.rb +129 -1
- data/lib/enhance_swarm/task_coordinator.rb +363 -86
- data/lib/enhance_swarm/version.rb +1 -1
- metadata +13 -97
- data/PRODUCTION_TEST_LOG.md +0 -502
- data/debug_agent_spawner.rb +0 -99
- data/debug_cli_spawn.rb +0 -95
- data/debug_fixes.rb +0 -209
- data/debug_script_execution.rb +0 -124
- data/debug_session_issue.rb +0 -87
- data/debug_spawn.rb +0 -113
- data/debug_spawn_step_by_step.rb +0 -190
- data/debug_worktree.rb +0 -77
- data/enhance_swarm-0.1.1.gem +0 -0
- data/enhance_swarm-1.0.0.gem +0 -0
- data/final_validation_test.rb +0 -199
- data/setup.sh +0 -86
- data/test_blog_app/.enhance_swarm/archives/session_1751187575_e119ea73_20250629_105935.json +0 -16
- data/test_blog_app/.enhance_swarm/archives/session_1751187637_7fda97dd_20250629_110037.json +0 -32
- data/test_blog_app/.enhance_swarm/archives/session_1751190527_4c99147e_20250629_114847.json +0 -32
- data/test_blog_app/.enhance_swarm/archives/session_1751190541_8dc83406_20250629_114901.json +0 -16
- data/test_blog_app/.ruby-version +0 -1
- data/test_blog_app/Gemfile +0 -18
- data/test_blog_app/Gemfile.lock +0 -206
- data/test_blog_app/README.md +0 -24
- data/test_blog_app/Rakefile +0 -6
- data/test_blog_app/app/assets/images/.keep +0 -0
- data/test_blog_app/app/assets/stylesheets/application.css +0 -10
- data/test_blog_app/app/controllers/application_controller.rb +0 -4
- data/test_blog_app/app/controllers/concerns/.keep +0 -0
- data/test_blog_app/app/helpers/application_helper.rb +0 -2
- data/test_blog_app/app/models/application_record.rb +0 -3
- data/test_blog_app/app/models/concerns/.keep +0 -0
- data/test_blog_app/app/views/layouts/application.html.erb +0 -27
- data/test_blog_app/app/views/pwa/manifest.json.erb +0 -22
- data/test_blog_app/app/views/pwa/service-worker.js +0 -26
- data/test_blog_app/bin/dev +0 -2
- data/test_blog_app/bin/rails +0 -4
- data/test_blog_app/bin/rake +0 -4
- data/test_blog_app/bin/setup +0 -34
- data/test_blog_app/config/application.rb +0 -42
- data/test_blog_app/config/boot.rb +0 -3
- data/test_blog_app/config/credentials.yml.enc +0 -1
- data/test_blog_app/config/database.yml +0 -32
- data/test_blog_app/config/environment.rb +0 -5
- data/test_blog_app/config/environments/development.rb +0 -51
- data/test_blog_app/config/environments/production.rb +0 -67
- data/test_blog_app/config/environments/test.rb +0 -42
- data/test_blog_app/config/initializers/assets.rb +0 -7
- data/test_blog_app/config/initializers/content_security_policy.rb +0 -25
- data/test_blog_app/config/initializers/filter_parameter_logging.rb +0 -8
- data/test_blog_app/config/initializers/inflections.rb +0 -16
- data/test_blog_app/config/locales/en.yml +0 -31
- data/test_blog_app/config/master.key +0 -1
- data/test_blog_app/config/puma.rb +0 -38
- data/test_blog_app/config/routes.rb +0 -14
- data/test_blog_app/config.ru +0 -6
- data/test_blog_app/db/seeds.rb +0 -9
- data/test_blog_app/lib/tasks/.keep +0 -0
- data/test_blog_app/log/.keep +0 -0
- data/test_blog_app/public/400.html +0 -114
- data/test_blog_app/public/404.html +0 -114
- data/test_blog_app/public/406-unsupported-browser.html +0 -114
- data/test_blog_app/public/422.html +0 -114
- data/test_blog_app/public/500.html +0 -114
- data/test_blog_app/public/icon.png +0 -0
- data/test_blog_app/public/icon.svg +0 -3
- data/test_blog_app/public/robots.txt +0 -1
- data/test_blog_app/script/.keep +0 -0
- data/test_blog_app/storage/.keep +0 -0
- data/test_blog_app/test/controllers/.keep +0 -0
- data/test_blog_app/test/fixtures/files/.keep +0 -0
- data/test_blog_app/test/helpers/.keep +0 -0
- data/test_blog_app/test/integration/.keep +0 -0
- data/test_blog_app/test/models/.keep +0 -0
- data/test_blog_app/test/test_helper.rb +0 -15
- data/test_blog_app/test_enhance_swarm_e2e.rb +0 -244
- data/test_blog_app/test_realistic_workflow.rb +0 -292
- data/test_blog_app/tmp/.keep +0 -0
- data/test_blog_app/tmp/pids/.keep +0 -0
- data/test_blog_app/tmp/storage/.keep +0 -0
- data/test_blog_app/vendor/.keep +0 -0
- data/test_builtin_functionality.rb +0 -121
- data/test_complete_system.rb +0 -267
- data/test_core_components.rb +0 -156
- data/test_real_claude_integration.rb +0 -285
- data/test_security.rb +0 -150
- data/test_smart_defaults.rb +0 -155
- data/test_task_integration.rb +0 -173
- data/test_web_ui.rb +0 -245
- data/web/assets/css/main.css +0 -645
- data/web/assets/js/kanban.js +0 -499
- data/web/assets/js/main.js +0 -525
- data/web/templates/dashboard.html.erb +0 -226
- 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
|
320
|
-
"
|
321
|
-
"Configure
|
322
|
-
"
|
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
|
-
|
572
|
+
Logger.info("๐ Starting parallel execution of #{tasks.length} tasks")
|
573
|
+
|
574
|
+
# Execute tasks in parallel threads
|
563
575
|
tasks.each do |task|
|
564
|
-
|
565
|
-
|
566
|
-
|
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
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
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
|
688
|
+
# Execute Claude CLI with timeout controls
|
643
689
|
success = false
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
690
|
+
timeout_seconds = 120 # 2 minutes timeout
|
691
|
+
|
692
|
+
begin
|
693
|
+
Logger.info("๐ง Executing Claude CLI with #{timeout_seconds}s timeout...")
|
648
694
|
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
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.
|
926
|
-
Essential Gemfile
|
985
|
+
## 1. BULLET TRAIN GEMFILE WITH VERSION SYNC (REAL STRUCTURE)
|
986
|
+
Essential Gemfile setup:
|
927
987
|
```ruby
|
928
|
-
#
|
929
|
-
|
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
|
-
#
|
938
|
-
gem "bullet_train
|
939
|
-
gem "bullet_train-
|
940
|
-
gem "bullet_train-
|
941
|
-
gem "bullet_train-
|
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
|
-
#
|
944
|
-
gem "bullet_train-
|
945
|
-
gem "bullet_train-
|
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
|
-
#
|
950
|
-
gem "bullet_train-
|
951
|
-
gem "bullet_train-
|
952
|
-
gem "bullet_train-
|
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
|
-
#
|
955
|
-
gem "
|
956
|
-
gem "
|
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.
|
975
|
-
**
|
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
|
-
**
|
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
|
-
|
1093
|
+
YourModel::TangibleThing: manage
|
1094
|
+
YourModel::CreativeConcept:
|
1095
|
+
- read
|
1096
|
+
- update
|
1097
|
+
|
1000
1098
|
admin:
|
1001
|
-
includes:
|
1002
|
-
|
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
|
1017
|
-
|
1018
|
-
-
|
1019
|
-
- bin/
|
1020
|
-
- bin/
|
1021
|
-
|
1022
|
-
|
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
|