diff --git a/app/models/app_generation/log_entry.rb b/app/models/app_generation/log_entry.rb
index 4b47500..92ddac6 100644
--- a/app/models/app_generation/log_entry.rb
+++ b/app/models/app_generation/log_entry.rb
@@ -29,9 +29,13 @@ class LogEntry < ApplicationRecord
self.table_name = "app_generation_log_entries"
+ def rails_output?
+ entry_type == "rails_output"
+ end
+
after_commit -> {
+ Rails.logger.debug "%%%%% LogEntry Create callback: #{id}"
stream_name = "#{generated_app.to_gid}:app_generation_log_entries"
-
Turbo::StreamsChannel.broadcast_prepend_to(
stream_name,
target: "app_generation_log_entries",
@@ -41,8 +45,8 @@ class LogEntry < ApplicationRecord
}, on: :create
after_commit -> {
+ Rails.logger.debug "%%%%% LogEntry Update callback: #{id}, message length: #{message.length}"
stream_name = "#{generated_app.to_gid}:app_generation_log_entries"
-
Turbo::StreamsChannel.broadcast_replace_to(
stream_name,
target: "log_entry_#{id}",
diff --git a/app/notifiers/app_status_change_notifier.rb b/app/notifiers/app_status_change_notifier.rb
index 0c169e3..7c11e41 100644
--- a/app/notifiers/app_status_change_notifier.rb
+++ b/app/notifiers/app_status_change_notifier.rb
@@ -1,4 +1,6 @@
class AppStatusChangeNotifier < Noticed::Event
+ include Rails.application.routes.url_helpers
+
deliver_by :action_cable do |config|
config.channel = "Noticed::NotificationChannel"
config.stream = -> { recipient }
diff --git a/app/services/command_execution_service.rb b/app/services/command_execution_service.rb
index e594c49..e36e007 100644
--- a/app/services/command_execution_service.rb
+++ b/app/services/command_execution_service.rb
@@ -113,10 +113,13 @@ def run_isolated_process
env = {
"BUNDLE_GEMFILE" => nil,
+ "BUNDLE_PATH" => File.join(@temp_dir, "vendor/bundle"),
+ "BUNDLE_APP_CONFIG" => File.join(@temp_dir, ".bundle"),
"RAILS_ENV" => "development",
"NODE_ENV" => "development",
"PATH" => ENV["PATH"]
}
+
log_environment_variables_for_command_execution(env)
buffer = Buffer.new(@generated_app)
@@ -125,35 +128,17 @@ def run_isolated_process
@pid = wait_thr&.pid
@logger.info("Rails app generation process started", { pid: @pid })
- # Auto-accept all prompts
- stdin_thread = Thread.new do
- loop do
- stdin.puts "Y"
- sleep 0.1
- end
- rescue IOError
- # Stream closed
- end
-
stdout_thread = Thread.new do
stdout.each_line do |line|
buffer.append(line.strip)
end
end
- stderr_thread = Thread.new do
- stderr.each_line do |line|
- buffer.append(line.strip)
- end
- end
-
- [stdout_thread, stderr_thread].each(&:join)
- stdin_thread.kill # Clean up stdin thread
+ stdout_thread.join
buffer.complete!
-
exit_status = wait_thr&.value
- output = buffer.join("\n").presence || "No output"
+ output = buffer.message || "No output"
if exit_status&.success?
@logger.info("Rails app generation process finished successfully", {
diff --git a/app/services/command_execution_service/buffer.rb b/app/services/command_execution_service/buffer.rb
index 6a17582..de7a02f 100644
--- a/app/services/command_execution_service/buffer.rb
+++ b/app/services/command_execution_service/buffer.rb
@@ -9,13 +9,15 @@ def initialize(generated_app)
@log_entry = create_initial_log_entry
@last_flush = Time.current
@completed = false
+ Rails.logger.debug "%%%%% Buffer initialized with log entry #{@log_entry.id}"
end
def append(message)
should_flush = false
synchronize do
- @output << message.gsub("\n", "
")
+ Rails.logger.debug "%%%%% Buffer append: Adding message of length #{message.length}"
+ @output << message
should_flush = should_flush?
end
@@ -23,33 +25,38 @@ def append(message)
end
def complete!
+ Rails.logger.debug "%%%%% Buffer complete! called"
@completed = true
flush
end
def flush
- message = nil
-
synchronize do
- message = @output.join("\n")
- message = "No output" if message.blank?
- end
+ return if @output.empty?
- if @completed
- @log_entry.update!(message: message, entry_type: nil)
- else
- @log_entry.update!(message: message)
- end
+ Rails.logger.debug "%%%%% Buffer flush: Current entry: #{@log_entry&.id}, buffer size: #{@output.length}"
- synchronize do
+ if @log_entry.nil?
+ @log_entry = create_initial_log_entry
+ Rails.logger.debug "%%%%% Created new log entry: #{@log_entry.id}"
+ end
+
+ new_content = @output.join("\n")
+ message = @log_entry.message.present? ? "#{@log_entry.message}\n#{new_content}" : new_content
+ Rails.logger.debug "%%%%% Updating log entry #{@log_entry.id} with message length: #{message.length}"
+
+ @log_entry.update!(
+ message: message,
+ phase: @generated_app.status
+ )
+
+ @output.clear
@last_flush = Time.current
end
end
- def join(separator = "\n")
- synchronize do
- @output.join(separator)
- end
+ def message
+ @log_entry&.message
end
private
@@ -70,7 +77,8 @@ def synchronize(&block)
end
def should_flush?
- Time.current - @last_flush >= FLUSH_INTERVAL
+ # Flush if enough time has passed OR if buffer is getting large
+ Time.current - @last_flush >= FLUSH_INTERVAL || @output.length >= 20
end
end
end
diff --git a/app/views/app_generation/log_entries/_log_entry.html.erb b/app/views/app_generation/log_entries/_log_entry.html.erb
index 64cf226..3795621 100644
--- a/app/views/app_generation/log_entries/_log_entry.html.erb
+++ b/app/views/app_generation/log_entries/_log_entry.html.erb
@@ -1,9 +1,9 @@
<%= turbo_frame_tag "log_entry_#{log_entry.id}" do %>
-