aidp 0.9.5 → 0.10.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.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/lib/aidp/analyze/error_handler.rb +4 -2
  3. data/lib/aidp/{analysis → analyze}/kb_inspector.rb +106 -89
  4. data/lib/aidp/analyze/prioritizer.rb +3 -2
  5. data/lib/aidp/analyze/ruby_maat_integration.rb +20 -3
  6. data/lib/aidp/analyze/runner.rb +27 -9
  7. data/lib/aidp/{analysis → analyze}/seams.rb +1 -1
  8. data/lib/aidp/analyze/steps.rb +7 -7
  9. data/lib/aidp/{analysis → analyze}/tree_sitter_grammar_loader.rb +22 -5
  10. data/lib/aidp/{analysis → analyze}/tree_sitter_scan.rb +32 -15
  11. data/lib/aidp/cli/first_run_wizard.rb +37 -28
  12. data/lib/aidp/cli/jobs_command.rb +37 -18
  13. data/lib/aidp/cli/terminal_io.rb +3 -3
  14. data/lib/aidp/cli.rb +131 -63
  15. data/lib/aidp/execute/runner.rb +27 -9
  16. data/lib/aidp/execute/steps.rb +18 -18
  17. data/lib/aidp/execute/workflow_selector.rb +36 -21
  18. data/lib/aidp/harness/enhanced_runner.rb +3 -3
  19. data/lib/aidp/harness/provider_factory.rb +3 -1
  20. data/lib/aidp/harness/provider_manager.rb +34 -15
  21. data/lib/aidp/harness/runner.rb +24 -5
  22. data/lib/aidp/harness/simple_user_interface.rb +19 -4
  23. data/lib/aidp/harness/status_display.rb +121 -104
  24. data/lib/aidp/harness/ui/enhanced_tui.rb +33 -5
  25. data/lib/aidp/harness/ui/error_handler.rb +3 -2
  26. data/lib/aidp/harness/ui/frame_manager.rb +52 -32
  27. data/lib/aidp/harness/ui/navigation/main_menu.rb +23 -14
  28. data/lib/aidp/harness/ui/progress_display.rb +28 -5
  29. data/lib/aidp/harness/ui/status_widget.rb +17 -8
  30. data/lib/aidp/harness/ui/workflow_controller.rb +25 -9
  31. data/lib/aidp/harness/user_interface.rb +341 -328
  32. data/lib/aidp/provider_manager.rb +10 -6
  33. data/lib/aidp/providers/anthropic.rb +3 -3
  34. data/lib/aidp/providers/base.rb +20 -1
  35. data/lib/aidp/providers/cursor.rb +6 -8
  36. data/lib/aidp/providers/gemini.rb +3 -3
  37. data/lib/aidp/providers/github_copilot.rb +264 -0
  38. data/lib/aidp/providers/opencode.rb +6 -8
  39. data/lib/aidp/version.rb +1 -1
  40. data/lib/aidp.rb +4 -4
  41. metadata +6 -6
  42. data/lib/aidp/analyze/progress_visualizer.rb +0 -314
@@ -1,14 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "tty-prompt"
4
+
3
5
  module Aidp
4
6
  module Harness
5
7
  # Real-time status updates and monitoring interface
6
8
  class StatusDisplay
7
- def initialize(provider_manager = nil, metrics_manager = nil, circuit_breaker_manager = nil, error_logger = nil)
9
+ def initialize(provider_manager = nil, metrics_manager = nil, circuit_breaker_manager = nil, error_logger = nil, prompt: TTY::Prompt.new)
8
10
  @provider_manager = provider_manager
9
11
  @metrics_manager = metrics_manager
10
12
  @circuit_breaker_manager = circuit_breaker_manager
11
13
  @error_logger = error_logger
14
+ @prompt = prompt
12
15
 
13
16
  @start_time = nil
14
17
  @current_step = nil
@@ -38,6 +41,21 @@ module Aidp
38
41
  @display_animator = DisplayAnimator.new
39
42
  end
40
43
 
44
+ # Helper method for consistent message display using TTY::Prompt
45
+ def display_message(message, type: :info)
46
+ color = case type
47
+ when :error then :red
48
+ when :success then :green
49
+ when :warning then :yellow
50
+ when :info then :blue
51
+ when :highlight then :cyan
52
+ when :muted then :bright_black
53
+ else :white
54
+ end
55
+
56
+ @prompt.say(message, color: color)
57
+ end
58
+
41
59
  # Start real-time status updates
42
60
  def start_status_updates(display_mode = :compact)
43
61
  return if @running
@@ -177,61 +195,61 @@ module Aidp
177
195
  # Show paused status
178
196
  def show_paused_status
179
197
  clear_display
180
- puts "\n⏸️ Harness PAUSED"
181
- puts " Press 'r' to resume, 's' to stop"
182
- puts " Current step: #{@current_step}" if @current_step
183
- puts " Current provider: #{@current_provider}" if @current_provider
184
- puts " Current model: #{@current_model}" if @current_model
185
- puts " Duration: #{format_duration(Time.now - @start_time)}" if @start_time
198
+ display_message("\n⏸️ Harness PAUSED", type: :warning)
199
+ display_message(" Press 'r' to resume, 's' to stop", type: :info)
200
+ display_message(" Current step: #{@current_step}", type: :info) if @current_step
201
+ display_message(" Current provider: #{@current_provider}", type: :info) if @current_provider
202
+ display_message(" Current model: #{@current_model}", type: :info) if @current_model
203
+ display_message(" Duration: #{format_duration(Time.now - @start_time)}", type: :info) if @start_time
186
204
  end
187
205
 
188
206
  # Show resumed status
189
207
  def show_resumed_status
190
208
  clear_display
191
- puts "\n▶️ Harness RESUMED"
192
- puts " Continuing execution..."
209
+ display_message("\n▶️ Harness RESUMED", type: :success)
210
+ display_message(" Continuing execution...", type: :info)
193
211
  end
194
212
 
195
213
  # Show stopped status
196
214
  def show_stopped_status
197
215
  clear_display
198
- puts "\n⏹️ Harness STOPPED"
199
- puts " Execution terminated by user"
216
+ display_message("\n⏹️ Harness STOPPED", type: :error)
217
+ display_message(" Execution terminated by user", type: :info)
200
218
  end
201
219
 
202
220
  # Show rate limit wait
203
221
  def show_rate_limit_wait(reset_time)
204
222
  clear_display
205
223
  remaining = reset_time - Time.now
206
- puts "\n🚫 Rate limit reached"
207
- puts " Waiting for reset at #{reset_time.strftime("%H:%M:%S")}"
208
- puts " Remaining: #{format_duration(remaining)}"
209
- puts " Press Ctrl+C to cancel"
224
+ display_message("\n🚫 Rate limit reached", type: :error)
225
+ display_message(" Waiting for reset at #{reset_time.strftime("%H:%M:%S")}", type: :info)
226
+ display_message(" Remaining: #{format_duration(remaining)}", type: :info)
227
+ display_message(" Press Ctrl+C to cancel", type: :info)
210
228
  end
211
229
 
212
230
  # Update rate limit countdown
213
231
  def update_rate_limit_countdown(remaining_seconds)
214
232
  clear_display
215
- puts "\n🚫 Rate limit - waiting..."
216
- puts " Resets in: #{format_duration(remaining_seconds)}"
217
- puts " Press Ctrl+C to cancel"
233
+ display_message("\n🚫 Rate limit - waiting...", type: :warning)
234
+ display_message(" Resets in: #{format_duration(remaining_seconds)}", type: :info)
235
+ display_message(" Press Ctrl+C to cancel", type: :info)
218
236
  end
219
237
 
220
238
  # Show completion status
221
239
  def show_completion_status(duration, steps_completed, total_steps)
222
240
  clear_display
223
- puts "\n✅ Harness COMPLETED"
224
- puts " Duration: #{format_duration(duration)}"
225
- puts " Steps completed: #{steps_completed}/#{total_steps}"
226
- puts " All workflows finished successfully!"
241
+ display_message("\n✅ Harness COMPLETED", type: :success)
242
+ display_message(" Duration: #{format_duration(duration)}", type: :info)
243
+ display_message(" Steps completed: #{steps_completed}/#{total_steps}", type: :info)
244
+ display_message(" All workflows finished successfully!", type: :success)
227
245
  end
228
246
 
229
247
  # Show error status
230
248
  def show_error_status(error_message)
231
249
  clear_display
232
- puts "\n❌ Harness ERROR"
233
- puts " Error: #{error_message}"
234
- puts " Check logs for details"
250
+ display_message("\n❌ Harness ERROR", type: :error)
251
+ display_message(" Error: #{error_message}", type: :error)
252
+ display_message(" Check logs for details", type: :info)
235
253
  end
236
254
 
237
255
  # Cleanup display
@@ -368,47 +386,47 @@ module Aidp
368
386
  def display_compact_status
369
387
  duration = @start_time ? Time.now - @start_time : 0
370
388
 
371
- puts "\n🔄 Harness Status"
372
- puts " Duration: #{format_duration(duration)}"
373
- puts " Step: #{@current_step || "Starting..."}"
374
- puts " Provider: #{@current_provider || "Initializing..."}"
375
- puts " Model: #{@current_model || "N/A"}"
376
- puts " Status: Running"
389
+ display_message("\n🔄 Harness Status", type: :info)
390
+ display_message(" Duration: #{format_duration(duration)}", type: :info)
391
+ display_message(" Step: #{@current_step || "Starting..."}", type: :info)
392
+ display_message(" Provider: #{@current_provider || "Initializing..."}", type: :info)
393
+ display_message(" Model: #{@current_model || "N/A"}", type: :info)
394
+ display_message(" Status: Running", type: :info)
377
395
 
378
396
  # Show key metrics
379
397
  if @performance_metrics[:error_rate] && @performance_metrics[:error_rate] > 0
380
- puts " Error Rate: #{format_percentage(@performance_metrics[:error_rate])}"
398
+ display_message(" Error Rate: #{format_percentage(@performance_metrics[:error_rate])}", type: :warning)
381
399
  end
382
400
 
383
401
  if @token_usage[@current_provider] && @token_usage[@current_provider][@current_model]
384
402
  tokens = @token_usage[@current_provider][@current_model]
385
- puts " Tokens: #{tokens[:used]} used"
386
- puts " Remaining: #{tokens[:remaining]}" if tokens[:remaining]
403
+ display_message(" Tokens: #{tokens[:used]} used", type: :info)
404
+ display_message(" Remaining: #{tokens[:remaining]}", type: :info) if tokens[:remaining]
387
405
  end
388
406
 
389
- puts " Press Ctrl+C to stop"
407
+ display_message(" Press Ctrl+C to stop", type: :info)
390
408
  end
391
409
 
392
410
  def display_detailed_status
393
411
  duration = @start_time ? Time.now - @start_time : 0
394
412
 
395
- puts "\n🔄 Harness Status - Detailed"
396
- puts " Duration: #{format_duration(duration)}"
397
- puts " Current Step: #{@current_step || "Starting..."}"
398
- puts " Provider: #{@current_provider || "Initializing..."}"
399
- puts " Model: #{@current_model || "N/A"}"
400
- puts " Status: Running"
413
+ display_message("\n🔄 Harness Status - Detailed", type: :info)
414
+ display_message(" Duration: #{format_duration(duration)}", type: :info)
415
+ display_message(" Current Step: #{@current_step || "Starting..."}", type: :info)
416
+ display_message(" Provider: #{@current_provider || "Initializing..."}", type: :info)
417
+ display_message(" Model: #{@current_model || "N/A"}", type: :info)
418
+ display_message(" Status: Running", type: :info)
401
419
 
402
420
  # Provider information
403
421
  if @provider_status[:available_providers]
404
- puts " Available Providers: #{@provider_status[:available_providers].join(", ")}"
422
+ display_message(" Available Providers: #{@provider_status[:available_providers].join(", ")}", type: :info)
405
423
  end
406
424
 
407
425
  # Circuit breaker status
408
426
  if @circuit_breaker_status.any?
409
427
  open_circuits = @circuit_breaker_status.select { |_, status| status[:state] == :open }
410
428
  if open_circuits.any?
411
- puts " Open Circuit Breakers: #{open_circuits.keys.join(", ")}"
429
+ display_message(" Open Circuit Breakers: #{open_circuits.keys.join(", ")}", type: :warning)
412
430
  end
413
431
  end
414
432
 
@@ -417,22 +435,22 @@ module Aidp
417
435
 
418
436
  # Error summary
419
437
  if @error_summary[:error_summary] && @error_summary[:error_summary][:total_errors] > 0
420
- puts " Errors: #{@error_summary[:error_summary][:total_errors]} total"
438
+ display_message(" Errors: #{@error_summary[:error_summary][:total_errors]} total", type: :warning)
421
439
  end
422
440
 
423
- puts " Press Ctrl+C to stop"
441
+ display_message(" Press Ctrl+C to stop", type: :info)
424
442
  end
425
443
 
426
444
  def display_minimal_status
427
445
  duration = @start_time ? Time.now - @start_time : 0
428
- puts "\r🔄 #{@current_step || "Starting"} | #{@current_provider || "Init"} | #{format_duration(duration)}"
446
+ display_message("\r🔄 #{@current_step || "Starting"} | #{@current_provider || "Init"} | #{format_duration(duration)}", type: :info)
429
447
  end
430
448
 
431
449
  def display_full_status
432
450
  clear_display
433
- puts "\n" + "=" * 80
434
- puts "🔄 AIDP HARNESS - FULL STATUS REPORT"
435
- puts "=" * 80
451
+ display_message("\n" + "=" * 80, type: :info)
452
+ display_message("🔄 AIDP HARNESS - FULL STATUS REPORT", type: :highlight)
453
+ display_message("=" * 80, type: :info)
436
454
 
437
455
  display_basic_info
438
456
  display_provider_info
@@ -446,33 +464,33 @@ module Aidp
446
464
  display_work_completion_info
447
465
  display_alerts
448
466
 
449
- puts "=" * 80
450
- puts "Press Ctrl+C to stop | Last updated: #{Time.now.strftime("%H:%M:%S")}"
467
+ display_message("=" * 80, type: :info)
468
+ display_message("Press Ctrl+C to stop | Last updated: #{Time.now.strftime("%H:%M:%S")}", type: :muted)
451
469
  end
452
470
 
453
471
  def display_basic_info
454
472
  duration = @start_time ? Time.now - @start_time : 0
455
473
 
456
- puts "\n📊 BASIC INFORMATION"
457
- puts " Duration: #{format_duration(duration)}"
458
- puts " Current Step: #{@current_step || "Starting..."}"
459
- puts " Provider: #{@current_provider || "Initializing..."}"
460
- puts " Model: #{@current_model || "N/A"}"
461
- puts " Status: Running"
462
- puts " Update Interval: #{@update_interval}s"
474
+ display_message("\n📊 BASIC INFORMATION", type: :info)
475
+ display_message(" Duration: #{format_duration(duration)}", type: :info)
476
+ display_message(" Current Step: #{@current_step || "Starting..."}", type: :info)
477
+ display_message(" Provider: #{@current_provider || "Initializing..."}", type: :info)
478
+ display_message(" Model: #{@current_model || "N/A"}", type: :info)
479
+ display_message(" Status: Running", type: :info)
480
+ display_message(" Update Interval: #{@update_interval}s", type: :info)
463
481
  end
464
482
 
465
483
  def display_provider_info
466
484
  return unless @provider_status.any?
467
485
 
468
- puts "\n🔌 PROVIDER INFORMATION"
486
+ display_message("\n🔌 PROVIDER INFORMATION", type: :info)
469
487
  if @provider_status[:available_providers]
470
- puts " Available Providers: #{@provider_status[:available_providers].join(", ")}"
488
+ display_message(" Available Providers: #{@provider_status[:available_providers].join(", ")}", type: :info)
471
489
  end
472
490
  if @provider_status[:provider_health]
473
- puts " Provider Health:"
491
+ display_message(" Provider Health:", type: :info)
474
492
  @provider_status[:provider_health].each do |provider, health|
475
- puts " #{provider}: #{health[:status]} (#{format_percentage(health[:health_score])})"
493
+ display_message(" #{provider}: #{health[:status]} (#{format_percentage(health[:health_score])})", type: :info)
476
494
  end
477
495
  end
478
496
  end
@@ -480,11 +498,11 @@ module Aidp
480
498
  def display_token_info
481
499
  return unless @token_usage.any?
482
500
 
483
- puts "\n🎫 TOKEN USAGE"
501
+ display_message("\n🎫 TOKEN USAGE", type: :info)
484
502
  @token_usage.each do |provider, models|
485
- puts " #{provider}:"
503
+ display_message(" #{provider}:", type: :info)
486
504
  models.each do |model, usage|
487
- puts " #{model}: #{usage[:used]} used, #{usage[:remaining]} remaining"
505
+ display_message(" #{model}: #{usage[:used]} used, #{usage[:remaining]} remaining", type: :info)
488
506
  end
489
507
  end
490
508
  end
@@ -492,14 +510,14 @@ module Aidp
492
510
  def display_performance_info
493
511
  return unless @performance_metrics.any?
494
512
 
495
- puts "\n⚡ PERFORMANCE METRICS"
496
- puts " Uptime: #{format_duration(@performance_metrics[:uptime] || 0)}"
497
- puts " Step Duration: #{format_duration(@performance_metrics[:step_duration] || 0)}"
498
- puts " Provider Switches: #{@performance_metrics[:provider_switch_count] || 0}"
499
- puts " Error Rate: #{format_percentage(@performance_metrics[:error_rate] || 0)}"
513
+ display_message("\n⚡ PERFORMANCE METRICS", type: :info)
514
+ display_message(" Uptime: #{format_duration(@performance_metrics[:uptime] || 0)}", type: :info)
515
+ display_message(" Step Duration: #{format_duration(@performance_metrics[:step_duration] || 0)}", type: :info)
516
+ display_message(" Provider Switches: #{@performance_metrics[:provider_switch_count] || 0}", type: :info)
517
+ display_message(" Error Rate: #{format_percentage(@performance_metrics[:error_rate] || 0)}", type: :info)
500
518
 
501
519
  if @performance_metrics[:throughput]
502
- puts " Throughput: #{@performance_metrics[:throughput]} requests/min"
520
+ display_message(" Throughput: #{@performance_metrics[:throughput]} requests/min", type: :info)
503
521
  end
504
522
  end
505
523
 
@@ -509,21 +527,21 @@ module Aidp
509
527
  error_summary = @error_summary[:error_summary]
510
528
  return if error_summary[:total_errors] == 0
511
529
 
512
- puts "\n❌ ERROR INFORMATION"
513
- puts " Total Errors: #{error_summary[:total_errors]}"
514
- puts " Error Rate: #{format_percentage(error_summary[:error_rate] || 0)}"
530
+ display_message("\n❌ ERROR INFORMATION", type: :error)
531
+ display_message(" Total Errors: #{error_summary[:total_errors]}", type: :error)
532
+ display_message(" Error Rate: #{format_percentage(error_summary[:error_rate] || 0)}", type: :error)
515
533
 
516
534
  if error_summary[:errors_by_severity].respond_to?(:any?) && error_summary[:errors_by_severity].any?
517
- puts " By Severity:"
535
+ display_message(" By Severity:", type: :info)
518
536
  error_summary[:errors_by_severity].each do |severity, count|
519
- puts " #{severity}: #{count}"
537
+ display_message(" #{severity}: #{count}", type: :info)
520
538
  end
521
539
  end
522
540
 
523
541
  if error_summary[:errors_by_provider].respond_to?(:any?) && error_summary[:errors_by_provider].any?
524
- puts " By Provider:"
542
+ display_message(" By Provider:", type: :info)
525
543
  error_summary[:errors_by_provider].each do |provider, count|
526
- puts " #{provider}: #{count}"
544
+ display_message(" #{provider}: #{count}", type: :info)
527
545
  end
528
546
  end
529
547
  end
@@ -531,23 +549,23 @@ module Aidp
531
549
  def display_circuit_breaker_info
532
550
  return unless @circuit_breaker_status.any?
533
551
 
534
- puts "\n🔒 CIRCUIT BREAKER STATUS"
552
+ display_message("\n🔒 CIRCUIT BREAKER STATUS", type: :info)
535
553
  @circuit_breaker_status.each do |key, status|
536
554
  state_icons = {closed: "🟢", open: "🔴", half_open: "🟡"}
537
555
  state_icon = state_icons[status[:state]] || "⚪"
538
- puts " #{state_icon} #{key}: #{status[:state]} (failures: #{status[:failure_count]})"
556
+ display_message(" #{state_icon} #{key}: #{status[:state]} (failures: #{status[:failure_count]})", type: :info)
539
557
  end
540
558
  end
541
559
 
542
560
  def display_token_usage
543
561
  return unless @token_usage.any?
544
562
 
545
- puts "\n🎫 TOKEN USAGE"
563
+ display_message("\n🎫 TOKEN USAGE", type: :info)
546
564
  @token_usage.each do |provider, models|
547
- puts " #{provider}:"
565
+ display_message(" #{provider}:", type: :info)
548
566
  models.each do |model, usage|
549
- puts " #{model}: #{usage[:used]} used"
550
- puts " Remaining: #{usage[:remaining]}" if usage[:remaining]
567
+ display_message(" #{model}: #{usage[:used]} used", type: :info)
568
+ display_message(" Remaining: #{usage[:remaining]}", type: :info) if usage[:remaining]
551
569
  end
552
570
  end
553
571
  end
@@ -555,14 +573,14 @@ module Aidp
555
573
  def display_rate_limit_info
556
574
  return unless @rate_limit_status.any?
557
575
 
558
- puts "\n🚫 RATE LIMIT STATUS"
576
+ display_message("\n🚫 RATE LIMIT STATUS", type: :warning)
559
577
  @rate_limit_status.each do |provider, models|
560
578
  models.each do |model, status|
561
579
  if status[:rate_limited]
562
- puts " #{provider}:#{model}: Rate Limited"
563
- puts " Reset Time: #{status[:reset_time]&.strftime("%H:%M:%S")}"
564
- puts " Retry After: #{status[:retry_after]}s"
565
- puts " Quota: #{status[:quota_remaining]}/#{status[:quota_limit]}" if status[:quota_remaining]
580
+ display_message(" #{provider}:#{model}: Rate Limited", type: :warning)
581
+ display_message(" Reset Time: #{status[:reset_time]&.strftime("%H:%M:%S")}", type: :info)
582
+ display_message(" Retry After: #{status[:retry_after]}s", type: :info)
583
+ display_message(" Quota: #{status[:quota_remaining]}/#{status[:quota_limit]}", type: :info) if status[:quota_remaining]
566
584
  end
567
585
  end
568
586
  end
@@ -571,12 +589,12 @@ module Aidp
571
589
  def display_recovery_info
572
590
  return unless @recovery_status.any?
573
591
 
574
- puts "\n🔄 RECOVERY STATUS"
592
+ display_message("\n🔄 RECOVERY STATUS", type: :info)
575
593
  @recovery_status.each do |type, status|
576
- puts " #{type}: #{status[:status]}"
594
+ display_message(" #{type}: #{status[:status]}", type: :info)
577
595
  if status[:details].any?
578
596
  status[:details].each do |key, value|
579
- puts " #{key}: #{value}"
597
+ display_message(" #{key}: #{value}", type: :info)
580
598
  end
581
599
  end
582
600
  end
@@ -585,12 +603,12 @@ module Aidp
585
603
  def display_user_feedback_info
586
604
  return unless @user_feedback_status.any?
587
605
 
588
- puts "\n💬 USER FEEDBACK STATUS"
606
+ display_message("\n💬 USER FEEDBACK STATUS", type: :info)
589
607
  @user_feedback_status.each do |type, status|
590
- puts " #{type}: #{status[:status]}"
608
+ display_message(" #{type}: #{status[:status]}", type: :info)
591
609
  if status[:details].any?
592
610
  status[:details].each do |key, value|
593
- puts " #{key}: #{value}"
611
+ display_message(" #{key}: #{value}", type: :info)
594
612
  end
595
613
  end
596
614
  end
@@ -599,24 +617,24 @@ module Aidp
599
617
  def display_work_completion_info
600
618
  return unless @work_completion_status.any?
601
619
 
602
- puts "\n✅ WORK COMPLETION STATUS"
620
+ display_message("\n✅ WORK COMPLETION STATUS", type: :info)
603
621
  if @work_completion_status[:is_complete]
604
- puts " Status: Complete"
622
+ display_message(" Status: Complete", type: :success)
605
623
  else
606
- puts " Status: In Progress"
624
+ display_message(" Status: In Progress", type: :info)
607
625
  end
608
- puts " Steps Completed: #{@work_completion_status[:completed_steps]}/#{@work_completion_status[:total_steps]}"
626
+ display_message(" Steps Completed: #{@work_completion_status[:completed_steps]}/#{@work_completion_status[:total_steps]}", type: :info)
609
627
  end
610
628
 
611
629
  def display_alerts
612
630
  alerts = get_alerts
613
631
  return unless alerts.any?
614
632
 
615
- puts "\n🚨 ALERTS"
633
+ display_message("\n🚨 ALERTS", type: :warning)
616
634
  alerts.each do |alert|
617
635
  severity_icons = {critical: "🔴", warning: "🟡", info: "🔵"}
618
636
  severity_icon = severity_icons[alert[:severity]] || "⚪"
619
- puts " #{severity_icon} #{alert[:message]}"
637
+ display_message(" #{severity_icon} #{alert[:message]}", type: :warning)
620
638
  end
621
639
  end
622
640
 
@@ -661,8 +679,8 @@ module Aidp
661
679
  end
662
680
 
663
681
  def handle_display_error(error)
664
- puts "\n❌ Display Error: #{error.message}"
665
- puts " Continuing with status updates..."
682
+ display_message("\n❌ Display Error: #{error.message}", type: :error)
683
+ display_message(" Continuing with status updates...", type: :info)
666
684
  end
667
685
 
668
686
  def get_basic_status
@@ -739,7 +757,6 @@ module Aidp
739
757
  def clear_display
740
758
  # Clear the current line and move cursor to beginning
741
759
  print "\r" + " " * 80 + "\r"
742
- $stdout.flush
743
760
  end
744
761
 
745
762
  def format_duration(seconds)
@@ -129,7 +129,7 @@ module Aidp
129
129
  border: :thick,
130
130
  padding: [1, 2]
131
131
  )
132
- puts box
132
+ @prompt.say(box)
133
133
  end
134
134
 
135
135
  # Enhanced step execution display
@@ -149,7 +149,7 @@ module Aidp
149
149
  padding: [1, 2],
150
150
  style: {border: {fg: :blue}}
151
151
  )
152
- puts box
152
+ @prompt.say(box)
153
153
 
154
154
  when :running
155
155
  content = []
@@ -165,7 +165,7 @@ module Aidp
165
165
  padding: [1, 2],
166
166
  style: {border: {fg: :yellow}}
167
167
  )
168
- puts box
168
+ @prompt.say(box)
169
169
 
170
170
  when :completed
171
171
  content = []
@@ -181,7 +181,7 @@ module Aidp
181
181
  padding: [1, 2],
182
182
  style: {border: {fg: :green}}
183
183
  )
184
- puts box
184
+ @prompt.say(box)
185
185
 
186
186
  when :failed
187
187
  content = []
@@ -222,10 +222,38 @@ module Aidp
222
222
  style: {border: {fg: :red}},
223
223
  width: 80
224
224
  )
225
- puts box
225
+ @prompt.say(box)
226
226
  end
227
227
  end
228
228
 
229
+ # Job management methods - interface for EnhancedRunner
230
+ def add_job(job_id, job_data)
231
+ @jobs[job_id] = {
232
+ id: job_id,
233
+ name: job_data[:name] || job_id,
234
+ status: job_data[:status] || :pending,
235
+ progress: job_data[:progress] || 0,
236
+ provider: job_data[:provider],
237
+ message: job_data[:message],
238
+ created_at: Time.now
239
+ }
240
+ end
241
+
242
+ def update_job(job_id, updates)
243
+ return unless @jobs[job_id]
244
+
245
+ @jobs[job_id].merge!(updates)
246
+ @jobs[job_id][:updated_at] = Time.now
247
+ end
248
+
249
+ def remove_job(job_id)
250
+ @jobs.delete(job_id)
251
+ end
252
+
253
+ def show_input_area(message)
254
+ @prompt.say("📝 #{message}", color: :cyan)
255
+ end
256
+
229
257
  private
230
258
 
231
259
  def extract_questions_for_step(step_name)
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "tty-prompt"
3
4
  require "pastel"
4
5
 
5
6
  module Aidp
@@ -16,6 +17,7 @@ module Aidp
16
17
  def initialize(ui_components = {})
17
18
  @logger = ui_components[:logger] || default_logger
18
19
  @formatter = ui_components[:formatter] || ErrorFormatter.new
20
+ @prompt = ui_components[:prompt] || TTY::Prompt.new
19
21
  end
20
22
 
21
23
  def handle_error(error, context = {})
@@ -67,8 +69,7 @@ module Aidp
67
69
  end
68
70
 
69
71
  def display_user_friendly_error(message)
70
- pastel = Pastel.new
71
- puts("#{pastel.red("Error:")} #{message}")
72
+ @prompt.say("Error: #{message}", color: :red)
72
73
  end
73
74
 
74
75
  def display_generic_error(error)