aidp 0.9.6 → 0.11.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 (100) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +194 -25
  3. data/lib/aidp/analyze/error_handler.rb +4 -2
  4. data/lib/aidp/{analysis → analyze}/kb_inspector.rb +93 -89
  5. data/lib/aidp/analyze/prioritizer.rb +3 -2
  6. data/lib/aidp/analyze/progress.rb +2 -1
  7. data/lib/aidp/analyze/ruby_maat_integration.rb +7 -3
  8. data/lib/aidp/analyze/runner.rb +73 -11
  9. data/lib/aidp/{analysis → analyze}/seams.rb +1 -1
  10. data/lib/aidp/analyze/steps.rb +10 -8
  11. data/lib/aidp/{analysis → analyze}/tree_sitter_grammar_loader.rb +11 -5
  12. data/lib/aidp/{analysis → analyze}/tree_sitter_scan.rb +21 -15
  13. data/lib/aidp/cli/checkpoint_command.rb +98 -0
  14. data/lib/aidp/cli/first_run_wizard.rb +83 -103
  15. data/lib/aidp/cli/jobs_command.rb +270 -36
  16. data/lib/aidp/cli/terminal_io.rb +3 -3
  17. data/lib/aidp/cli.rb +411 -69
  18. data/lib/aidp/config.rb +5 -8
  19. data/lib/aidp/debug_logger.rb +4 -4
  20. data/lib/aidp/debug_mixin.rb +11 -4
  21. data/lib/aidp/execute/checkpoint.rb +282 -0
  22. data/lib/aidp/execute/checkpoint_display.rb +221 -0
  23. data/lib/aidp/execute/progress.rb +2 -1
  24. data/lib/aidp/execute/prompt_manager.rb +62 -0
  25. data/lib/aidp/execute/runner.rb +67 -20
  26. data/lib/aidp/execute/steps.rb +36 -27
  27. data/lib/aidp/execute/work_loop_runner.rb +308 -0
  28. data/lib/aidp/execute/workflow_selector.rb +50 -26
  29. data/lib/aidp/harness/condition_detector.rb +4 -4
  30. data/lib/aidp/harness/config_schema.rb +40 -0
  31. data/lib/aidp/harness/config_validator.rb +3 -6
  32. data/lib/aidp/harness/configuration.rb +35 -1
  33. data/lib/aidp/harness/enhanced_runner.rb +25 -4
  34. data/lib/aidp/harness/error_handler.rb +103 -28
  35. data/lib/aidp/harness/provider_factory.rb +6 -1
  36. data/lib/aidp/harness/provider_manager.rb +273 -19
  37. data/lib/aidp/harness/runner.rb +14 -6
  38. data/lib/aidp/harness/simple_user_interface.rb +6 -4
  39. data/lib/aidp/harness/status_display.rb +118 -106
  40. data/lib/aidp/harness/test_runner.rb +83 -0
  41. data/lib/aidp/harness/ui/enhanced_tui.rb +7 -5
  42. data/lib/aidp/harness/ui/enhanced_workflow_selector.rb +22 -4
  43. data/lib/aidp/harness/ui/error_handler.rb +7 -2
  44. data/lib/aidp/harness/ui/frame_manager.rb +61 -39
  45. data/lib/aidp/harness/ui/job_monitor.rb +2 -0
  46. data/lib/aidp/harness/ui/navigation/main_menu.rb +27 -16
  47. data/lib/aidp/harness/ui/navigation/menu_item.rb +1 -0
  48. data/lib/aidp/harness/ui/navigation/menu_state.rb +1 -0
  49. data/lib/aidp/harness/ui/navigation/submenu.rb +1 -0
  50. data/lib/aidp/harness/ui/navigation/workflow_selector.rb +2 -0
  51. data/lib/aidp/harness/ui/progress_display.rb +26 -7
  52. data/lib/aidp/harness/ui/question_collector.rb +2 -0
  53. data/lib/aidp/harness/ui/spinner_group.rb +2 -0
  54. data/lib/aidp/harness/ui/spinner_helper.rb +1 -1
  55. data/lib/aidp/harness/ui/status_manager.rb +4 -2
  56. data/lib/aidp/harness/ui/status_widget.rb +20 -9
  57. data/lib/aidp/harness/ui/workflow_controller.rb +27 -9
  58. data/lib/aidp/harness/user_interface.rb +338 -330
  59. data/lib/aidp/jobs/background_runner.rb +278 -0
  60. data/lib/aidp/message_display.rb +48 -0
  61. data/lib/aidp/provider_manager.rb +13 -7
  62. data/lib/aidp/providers/anthropic.rb +101 -18
  63. data/lib/aidp/providers/base.rb +51 -1
  64. data/lib/aidp/providers/codex.rb +248 -0
  65. data/lib/aidp/providers/cursor.rb +39 -48
  66. data/lib/aidp/providers/gemini.rb +26 -16
  67. data/lib/aidp/providers/github_copilot.rb +263 -0
  68. data/lib/aidp/providers/opencode.rb +38 -47
  69. data/lib/aidp/version.rb +1 -1
  70. data/lib/aidp/workflows/definitions.rb +357 -0
  71. data/lib/aidp/workflows/selector.rb +171 -0
  72. data/lib/aidp.rb +16 -4
  73. data/templates/planning/generate_llm_style_guide.md +119 -0
  74. metadata +43 -31
  75. data/lib/aidp/analyze/progress_visualizer.rb +0 -314
  76. /data/templates/{ANALYZE/02_ARCHITECTURE_ANALYSIS.md → analysis/analyze_architecture.md} +0 -0
  77. /data/templates/{ANALYZE/05_DOCUMENTATION_ANALYSIS.md → analysis/analyze_documentation.md} +0 -0
  78. /data/templates/{ANALYZE/04_FUNCTIONALITY_ANALYSIS.md → analysis/analyze_functionality.md} +0 -0
  79. /data/templates/{ANALYZE/01_REPOSITORY_ANALYSIS.md → analysis/analyze_repository.md} +0 -0
  80. /data/templates/{ANALYZE/06_STATIC_ANALYSIS.md → analysis/analyze_static_code.md} +0 -0
  81. /data/templates/{ANALYZE/03_TEST_ANALYSIS.md → analysis/analyze_tests.md} +0 -0
  82. /data/templates/{ANALYZE/07_REFACTORING_RECOMMENDATIONS.md → analysis/recommend_refactoring.md} +0 -0
  83. /data/templates/{ANALYZE/06a_tree_sitter_scan.md → analysis/scan_with_tree_sitter.md} +0 -0
  84. /data/templates/{EXECUTE/11_STATIC_ANALYSIS.md → implementation/configure_static_analysis.md} +0 -0
  85. /data/templates/{EXECUTE/14_DOCS_PORTAL.md → implementation/create_documentation_portal.md} +0 -0
  86. /data/templates/{EXECUTE/10_IMPLEMENTATION_AGENT.md → implementation/implement_features.md} +0 -0
  87. /data/templates/{EXECUTE/13_DELIVERY_ROLLOUT.md → implementation/plan_delivery.md} +0 -0
  88. /data/templates/{EXECUTE/15_POST_RELEASE.md → implementation/review_post_release.md} +0 -0
  89. /data/templates/{EXECUTE/09_SCAFFOLDING_DEVEX.md → implementation/setup_scaffolding.md} +0 -0
  90. /data/templates/{EXECUTE/02A_ARCH_GATE_QUESTIONS.md → planning/ask_architecture_questions.md} +0 -0
  91. /data/templates/{EXECUTE/00_PRD.md → planning/create_prd.md} +0 -0
  92. /data/templates/{EXECUTE/08_TASKS.md → planning/create_tasks.md} +0 -0
  93. /data/templates/{EXECUTE/04_DOMAIN_DECOMPOSITION.md → planning/decompose_domain.md} +0 -0
  94. /data/templates/{EXECUTE/01_NFRS.md → planning/define_nfrs.md} +0 -0
  95. /data/templates/{EXECUTE/05_CONTRACTS.md → planning/design_apis.md} +0 -0
  96. /data/templates/{EXECUTE/02_ARCHITECTURE.md → planning/design_architecture.md} +0 -0
  97. /data/templates/{EXECUTE/06_THREAT_MODEL.md → planning/design_data_model.md} +0 -0
  98. /data/templates/{EXECUTE/03_ADR_FACTORY.md → planning/generate_adrs.md} +0 -0
  99. /data/templates/{EXECUTE/12_OBSERVABILITY_SLOS.md → planning/plan_observability.md} +0 -0
  100. /data/templates/{EXECUTE/07_TEST_PLAN.md → planning/plan_testing.md} +0 -0
@@ -0,0 +1,248 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "timeout"
4
+ require_relative "base"
5
+ require_relative "../util"
6
+ require_relative "../debug_mixin"
7
+
8
+ module Aidp
9
+ module Providers
10
+ class Codex < Base
11
+ include Aidp::DebugMixin
12
+
13
+ def self.available?
14
+ !!Aidp::Util.which("codex")
15
+ end
16
+
17
+ def name
18
+ "codex"
19
+ end
20
+
21
+ def display_name
22
+ "Codex CLI"
23
+ end
24
+
25
+ def available?
26
+ return false unless self.class.available?
27
+
28
+ # Additional check to ensure the CLI is properly configured
29
+ begin
30
+ result = Aidp::Util.execute_command("codex", ["--version"], timeout: 10)
31
+ result.exit_status == 0
32
+ rescue
33
+ false
34
+ end
35
+ end
36
+
37
+ def send(prompt:, session: nil)
38
+ raise "codex CLI not available" unless self.class.available?
39
+
40
+ # Smart timeout calculation
41
+ timeout_seconds = calculate_timeout
42
+
43
+ debug_provider("codex", "Starting execution", {timeout: timeout_seconds})
44
+ debug_log("📝 Sending prompt to codex (length: #{prompt.length})", level: :info)
45
+
46
+ # Check if streaming mode is enabled
47
+ streaming_enabled = ENV["AIDP_STREAMING"] == "1" || ENV["DEBUG"] == "1"
48
+ if streaming_enabled
49
+ display_message("📺 Streaming mode enabled - output will appear in real-time", type: :info)
50
+ end
51
+
52
+ # Set up activity monitoring
53
+ setup_activity_monitoring("codex", method(:activity_callback))
54
+ record_activity("Starting codex execution")
55
+
56
+ # Create a spinner for activity display
57
+ spinner = TTY::Spinner.new("[:spinner] :title", format: :dots, hide_cursor: true)
58
+ spinner.auto_spin
59
+
60
+ # Start activity display thread with timeout
61
+ activity_display_thread = Thread.new do
62
+ start_time = Time.now
63
+ loop do
64
+ sleep 0.5 # Update every 500ms to reduce spam
65
+ elapsed = Time.now - start_time
66
+
67
+ # Break if we've been running too long or state changed
68
+ break if elapsed > timeout_seconds || @activity_state == :completed || @activity_state == :failed
69
+
70
+ update_spinner_status(spinner, elapsed, "🤖 Codex CLI")
71
+ end
72
+ end
73
+
74
+ begin
75
+ # Use non-interactive mode (exec) for automation
76
+ args = ["exec", prompt]
77
+
78
+ # Add session support if provided (codex may support session/thread continuation)
79
+ if session && !session.empty?
80
+ args += ["--session", session]
81
+ end
82
+
83
+ # Use debug_execute_command for better debugging
84
+ result = debug_execute_command("codex", args: args, timeout: timeout_seconds, streaming: streaming_enabled)
85
+
86
+ # Log the results
87
+ debug_command("codex", args: args, input: prompt, output: result.out, error: result.err, exit_code: result.exit_status)
88
+
89
+ if result.exit_status == 0
90
+ spinner.success("✓")
91
+ mark_completed
92
+ result.out
93
+ else
94
+ spinner.error("✗")
95
+ mark_failed("codex failed with exit code #{result.exit_status}")
96
+ debug_error(StandardError.new("codex failed"), {exit_code: result.exit_status, stderr: result.err})
97
+ raise "codex failed with exit code #{result.exit_status}: #{result.err}"
98
+ end
99
+ rescue => e
100
+ spinner&.error("✗")
101
+ mark_failed("codex execution failed: #{e.message}")
102
+ debug_error(e, {provider: "codex", prompt_length: prompt.length})
103
+ raise
104
+ ensure
105
+ cleanup_activity_display(activity_display_thread, spinner)
106
+ end
107
+ end
108
+
109
+ # Enhanced send method with additional options
110
+ def send_with_options(prompt:, session: nil, model: nil, ask_for_approval: false)
111
+ args = ["exec", prompt]
112
+
113
+ # Add session support
114
+ if session && !session.empty?
115
+ args += ["--session", session]
116
+ end
117
+
118
+ # Add model selection
119
+ if model
120
+ args += ["--model", model]
121
+ end
122
+
123
+ # Add approval flag
124
+ if ask_for_approval
125
+ args += ["--ask-for-approval"]
126
+ end
127
+
128
+ # Use the enhanced version of send
129
+ send_with_custom_args(prompt: prompt, args: args)
130
+ end
131
+
132
+ # Override health check for Codex specific considerations
133
+ def harness_healthy?
134
+ return false unless super
135
+
136
+ # Additional health checks specific to Codex CLI
137
+ # Check if we can access the CLI (basic connectivity test)
138
+ begin
139
+ result = Aidp::Util.execute_command("codex", ["--help"], timeout: 5)
140
+ result.exit_status == 0
141
+ rescue
142
+ false
143
+ end
144
+ end
145
+
146
+ private
147
+
148
+ # Internal helper for send_with_options - executes with custom arguments
149
+ def send_with_custom_args(prompt:, args:)
150
+ timeout_seconds = calculate_timeout
151
+
152
+ debug_provider("codex", "Starting execution", {timeout: timeout_seconds, args: args})
153
+ debug_log("📝 Sending prompt to codex with custom args", level: :info)
154
+
155
+ # Check if streaming mode is enabled
156
+ streaming_enabled = ENV["AIDP_STREAMING"] == "1" || ENV["DEBUG"] == "1"
157
+ if streaming_enabled
158
+ display_message("📺 Display streaming enabled - output buffering reduced (codex CLI does not support true streaming)", type: :info)
159
+ end
160
+
161
+ setup_activity_monitoring("codex", method(:activity_callback))
162
+ record_activity("Starting codex execution with custom args")
163
+
164
+ begin
165
+ result = debug_execute_command("codex", args: args, timeout: timeout_seconds, streaming: streaming_enabled)
166
+ debug_command("codex", args: args, output: result.out, error: result.err, exit_code: result.exit_status)
167
+
168
+ if result.exit_status == 0
169
+ mark_completed
170
+ result.out
171
+ else
172
+ mark_failed("codex failed with exit code #{result.exit_status}")
173
+ debug_error(StandardError.new("codex failed"), {exit_code: result.exit_status, stderr: result.err})
174
+ raise "codex failed with exit code #{result.exit_status}: #{result.err}"
175
+ end
176
+ rescue => e
177
+ mark_failed("codex execution failed: #{e.message}")
178
+ debug_error(e, {provider: "codex", prompt_length: prompt.length})
179
+ raise
180
+ end
181
+ end
182
+
183
+ def calculate_timeout
184
+ # Priority order for timeout calculation:
185
+ # 1. Quick mode (for testing)
186
+ # 2. Environment variable override
187
+ # 3. Adaptive timeout based on step type
188
+ # 4. Default timeout
189
+
190
+ if ENV["AIDP_QUICK_MODE"]
191
+ display_message("⚡ Quick mode enabled - #{TIMEOUT_QUICK_MODE / 60} minute timeout", type: :highlight)
192
+ return TIMEOUT_QUICK_MODE
193
+ end
194
+
195
+ if ENV["AIDP_CODEX_TIMEOUT"]
196
+ return ENV["AIDP_CODEX_TIMEOUT"].to_i
197
+ end
198
+
199
+ # Adaptive timeout based on step type
200
+ step_timeout = get_adaptive_timeout
201
+ if step_timeout
202
+ display_message("🧠 Using adaptive timeout: #{step_timeout} seconds", type: :info)
203
+ return step_timeout
204
+ end
205
+
206
+ # Default timeout
207
+ display_message("📋 Using default timeout: #{TIMEOUT_DEFAULT / 60} minutes", type: :info)
208
+ TIMEOUT_DEFAULT
209
+ end
210
+
211
+ def get_adaptive_timeout
212
+ # Timeout recommendations based on step type patterns
213
+ step_name = ENV["AIDP_CURRENT_STEP"] || ""
214
+
215
+ case step_name
216
+ when /REPOSITORY_ANALYSIS/
217
+ TIMEOUT_REPOSITORY_ANALYSIS
218
+ when /ARCHITECTURE_ANALYSIS/
219
+ TIMEOUT_ARCHITECTURE_ANALYSIS
220
+ when /TEST_ANALYSIS/
221
+ TIMEOUT_TEST_ANALYSIS
222
+ when /FUNCTIONALITY_ANALYSIS/
223
+ TIMEOUT_FUNCTIONALITY_ANALYSIS
224
+ when /DOCUMENTATION_ANALYSIS/
225
+ TIMEOUT_DOCUMENTATION_ANALYSIS
226
+ when /STATIC_ANALYSIS/
227
+ TIMEOUT_STATIC_ANALYSIS
228
+ when /REFACTORING_RECOMMENDATIONS/
229
+ TIMEOUT_REFACTORING_RECOMMENDATIONS
230
+ else
231
+ nil # Use default
232
+ end
233
+ end
234
+
235
+ def activity_callback(state, message, provider)
236
+ # Handle activity state changes
237
+ case state
238
+ when :stuck
239
+ display_message("\n⚠️ Codex CLI appears stuck: #{message}", type: :warning)
240
+ when :completed
241
+ display_message("\n✅ Codex CLI completed: #{message}", type: :success)
242
+ when :failed
243
+ display_message("\n❌ Codex CLI failed: #{message}", type: :error)
244
+ end
245
+ end
246
+ end
247
+ end
248
+ end
@@ -18,6 +18,10 @@ module Aidp
18
18
  "cursor"
19
19
  end
20
20
 
21
+ def display_name
22
+ "Cursor AI"
23
+ end
24
+
21
25
  def send(prompt:, session: nil)
22
26
  raise "cursor-agent not available" unless self.class.available?
23
27
 
@@ -27,10 +31,20 @@ module Aidp
27
31
  debug_provider("cursor", "Starting execution", {timeout: timeout_seconds})
28
32
  debug_log("📝 Sending prompt to cursor-agent (length: #{prompt.length})", level: :info)
29
33
 
34
+ # Check if streaming mode is enabled
35
+ streaming_enabled = ENV["AIDP_STREAMING"] == "1" || ENV["DEBUG"] == "1"
36
+ if streaming_enabled
37
+ display_message("📺 Display streaming enabled - output buffering reduced (cursor-agent does not support true streaming)", type: :info)
38
+ end
39
+
30
40
  # Set up activity monitoring
31
41
  setup_activity_monitoring("cursor-agent", method(:activity_callback))
32
42
  record_activity("Starting cursor-agent execution")
33
43
 
44
+ # Create a spinner for activity display
45
+ spinner = TTY::Spinner.new("[:spinner] :title", format: :dots, hide_cursor: true)
46
+ spinner.auto_spin
47
+
34
48
  # Start activity display thread with timeout
35
49
  activity_display_thread = Thread.new do
36
50
  start_time = Time.now
@@ -41,7 +55,7 @@ module Aidp
41
55
  # Break if we've been running too long or state changed
42
56
  break if elapsed > timeout_seconds || @activity_state == :completed || @activity_state == :failed
43
57
 
44
- print_activity_status(elapsed)
58
+ update_spinner_status(spinner, elapsed, "🔄 cursor-agent")
45
59
  end
46
60
  end
47
61
 
@@ -49,61 +63,38 @@ module Aidp
49
63
  # Use debug_execute_command for better debugging
50
64
  # Try agent command first (better for large prompts), fallback to -p mode
51
65
  begin
52
- result = debug_execute_command("cursor-agent", args: ["agent"], input: prompt, timeout: timeout_seconds)
66
+ result = debug_execute_command("cursor-agent", args: ["agent"], input: prompt, timeout: timeout_seconds, streaming: streaming_enabled)
53
67
  rescue => e
54
68
  # Fallback to -p mode if agent command fails
55
69
  debug_log("🔄 Falling back to -p mode: #{e.message}", level: :warn)
56
- result = debug_execute_command("cursor-agent", args: ["-p"], input: prompt, timeout: timeout_seconds)
70
+ result = debug_execute_command("cursor-agent", args: ["-p"], input: prompt, timeout: timeout_seconds, streaming: streaming_enabled)
57
71
  end
58
72
 
59
73
  # Log the results
60
74
  debug_command("cursor-agent", args: ["-p"], input: prompt, output: result.out, error: result.err, exit_code: result.exit_status)
61
75
 
62
- # Stop activity display
63
- activity_display_thread.kill if activity_display_thread.alive?
64
- activity_display_thread.join(0.1) # Give it 100ms to finish
65
- clear_activity_status
66
-
67
76
  if result.exit_status == 0
77
+ spinner.success("✓")
68
78
  mark_completed
69
79
  result.out
70
80
  else
81
+ spinner.error("✗")
71
82
  mark_failed("cursor-agent failed with exit code #{result.exit_status}")
72
83
  debug_error(StandardError.new("cursor-agent failed"), {exit_code: result.exit_status, stderr: result.err})
73
84
  raise "cursor-agent failed with exit code #{result.exit_status}: #{result.err}"
74
85
  end
75
86
  rescue => e
76
- # Stop activity display
77
- activity_display_thread.kill if activity_display_thread.alive?
78
- activity_display_thread.join(0.1) # Give it 100ms to finish
79
- clear_activity_status
87
+ spinner&.error("✗")
80
88
  mark_failed("cursor-agent execution failed: #{e.message}")
81
89
  debug_error(e, {provider: "cursor", prompt_length: prompt.length})
82
90
  raise
91
+ ensure
92
+ cleanup_activity_display(activity_display_thread, spinner)
83
93
  end
84
94
  end
85
95
 
86
96
  private
87
97
 
88
- def print_activity_status(elapsed)
89
- # Print activity status during cursor execution with elapsed time
90
- minutes = (elapsed / 60).to_i
91
- seconds = (elapsed % 60).to_i
92
-
93
- if minutes > 0
94
- print "\r🔄 cursor-agent is running... (#{minutes}m #{seconds}s)"
95
- else
96
- print "\r🔄 cursor-agent is running... (#{seconds}s)"
97
- end
98
- $stdout.flush
99
- end
100
-
101
- def clear_activity_status
102
- # Clear the activity status line
103
- print "\r" + " " * 50 + "\r"
104
- $stdout.flush
105
- end
106
-
107
98
  def calculate_timeout
108
99
  # Priority order for timeout calculation:
109
100
  # 1. Quick mode (for testing)
@@ -112,8 +103,8 @@ module Aidp
112
103
  # 4. Default timeout
113
104
 
114
105
  if ENV["AIDP_QUICK_MODE"]
115
- puts "⚡ Quick mode enabled - 2 minute timeout"
116
- return 120
106
+ display_message("⚡ Quick mode enabled - #{TIMEOUT_QUICK_MODE / 60} minute timeout", type: :highlight)
107
+ return TIMEOUT_QUICK_MODE
117
108
  end
118
109
 
119
110
  if ENV["AIDP_CURSOR_TIMEOUT"]
@@ -123,13 +114,13 @@ module Aidp
123
114
  # Adaptive timeout based on step type
124
115
  step_timeout = get_adaptive_timeout
125
116
  if step_timeout
126
- puts "🧠 Using adaptive timeout: #{step_timeout} seconds"
117
+ display_message("🧠 Using adaptive timeout: #{step_timeout} seconds", type: :info)
127
118
  return step_timeout
128
119
  end
129
120
 
130
- # Default timeout (5 minutes for interactive use)
131
- puts "📋 Using default timeout: 5 minutes"
132
- 300
121
+ # Default timeout
122
+ display_message("📋 Using default timeout: #{TIMEOUT_DEFAULT / 60} minutes", type: :info)
123
+ TIMEOUT_DEFAULT
133
124
  end
134
125
 
135
126
  def get_adaptive_timeout
@@ -138,21 +129,21 @@ module Aidp
138
129
 
139
130
  case step_name
140
131
  when /REPOSITORY_ANALYSIS/
141
- 180 # 3 minutes - repository analysis can be quick
132
+ TIMEOUT_REPOSITORY_ANALYSIS
142
133
  when /ARCHITECTURE_ANALYSIS/
143
- 600 # 10 minutes - architecture analysis needs more time
134
+ TIMEOUT_ARCHITECTURE_ANALYSIS
144
135
  when /TEST_ANALYSIS/
145
- 300 # 5 minutes - test analysis is moderate
136
+ TIMEOUT_TEST_ANALYSIS
146
137
  when /FUNCTIONALITY_ANALYSIS/
147
- 600 # 10 minutes - functionality analysis is complex
138
+ TIMEOUT_FUNCTIONALITY_ANALYSIS
148
139
  when /DOCUMENTATION_ANALYSIS/
149
- 300 # 5 minutes - documentation analysis is moderate
140
+ TIMEOUT_DOCUMENTATION_ANALYSIS
150
141
  when /STATIC_ANALYSIS/
151
- 450 # 7.5 minutes - static analysis can be intensive
142
+ TIMEOUT_STATIC_ANALYSIS
152
143
  when /REFACTORING_RECOMMENDATIONS/
153
- 600 # 10 minutes - refactoring recommendations are complex
144
+ TIMEOUT_REFACTORING_RECOMMENDATIONS
154
145
  else
155
- nil # Use default
146
+ nil # Use default
156
147
  end
157
148
  end
158
149
 
@@ -161,11 +152,11 @@ module Aidp
161
152
  # Only print static messages for state changes
162
153
  case state
163
154
  when :stuck
164
- puts "\n⚠️ cursor appears stuck: #{message}"
155
+ display_message("\n⚠️ cursor appears stuck: #{message}", type: :warning)
165
156
  when :completed
166
- puts "\n✅ cursor completed: #{message}"
157
+ display_message("\n✅ cursor completed: #{message}", type: :success)
167
158
  when :failed
168
- puts "\n❌ cursor failed: #{message}"
159
+ display_message("\n❌ cursor failed: #{message}", type: :error)
169
160
  end
170
161
  end
171
162
  end
@@ -16,6 +16,10 @@ module Aidp
16
16
  "gemini"
17
17
  end
18
18
 
19
+ def display_name
20
+ "Google Gemini"
21
+ end
22
+
19
23
  def send(prompt:, session: nil)
20
24
  raise "gemini CLI not available" unless self.class.available?
21
25
 
@@ -25,9 +29,15 @@ module Aidp
25
29
  debug_provider("gemini", "Starting execution", {timeout: timeout_seconds})
26
30
  debug_log("📝 Sending prompt to gemini...", level: :info)
27
31
 
32
+ # Check if streaming mode is enabled
33
+ streaming_enabled = ENV["AIDP_STREAMING"] == "1" || ENV["DEBUG"] == "1"
34
+ if streaming_enabled
35
+ display_message("📺 Display streaming enabled - output buffering reduced (gemini CLI does not support true streaming)", type: :info)
36
+ end
37
+
28
38
  begin
29
- # Use debug_execute_command for better debugging
30
- result = debug_execute_command("gemini", args: ["--print"], input: prompt, timeout: timeout_seconds)
39
+ # Use debug_execute_command with streaming support
40
+ result = debug_execute_command("gemini", args: ["--print"], input: prompt, timeout: timeout_seconds, streaming: streaming_enabled)
31
41
 
32
42
  # Log the results
33
43
  debug_command("gemini", args: ["--print"], input: prompt, output: result.out, error: result.err, exit_code: result.exit_status)
@@ -54,8 +64,8 @@ module Aidp
54
64
  # 4. Default timeout
55
65
 
56
66
  if ENV["AIDP_QUICK_MODE"]
57
- puts "⚡ Quick mode enabled - 2 minute timeout"
58
- return 120
67
+ display_message("⚡ Quick mode enabled - #{TIMEOUT_QUICK_MODE / 60} minute timeout", type: :highlight)
68
+ return TIMEOUT_QUICK_MODE
59
69
  end
60
70
 
61
71
  if ENV["AIDP_GEMINI_TIMEOUT"]
@@ -65,13 +75,13 @@ module Aidp
65
75
  # Adaptive timeout based on step type
66
76
  step_timeout = get_adaptive_timeout
67
77
  if step_timeout
68
- puts "🧠 Using adaptive timeout: #{step_timeout} seconds"
78
+ display_message("🧠 Using adaptive timeout: #{step_timeout} seconds", type: :info)
69
79
  return step_timeout
70
80
  end
71
81
 
72
- # Default timeout (5 minutes for interactive use)
73
- puts "📋 Using default timeout: 5 minutes"
74
- 300
82
+ # Default timeout
83
+ display_message("📋 Using default timeout: #{TIMEOUT_DEFAULT / 60} minutes", type: :info)
84
+ TIMEOUT_DEFAULT
75
85
  end
76
86
 
77
87
  def get_adaptive_timeout
@@ -80,21 +90,21 @@ module Aidp
80
90
 
81
91
  case step_name
82
92
  when /REPOSITORY_ANALYSIS/
83
- 180 # 3 minutes - repository analysis can be quick
93
+ TIMEOUT_REPOSITORY_ANALYSIS
84
94
  when /ARCHITECTURE_ANALYSIS/
85
- 600 # 10 minutes - architecture analysis needs more time
95
+ TIMEOUT_ARCHITECTURE_ANALYSIS
86
96
  when /TEST_ANALYSIS/
87
- 300 # 5 minutes - test analysis is moderate
97
+ TIMEOUT_TEST_ANALYSIS
88
98
  when /FUNCTIONALITY_ANALYSIS/
89
- 600 # 10 minutes - functionality analysis is complex
99
+ TIMEOUT_FUNCTIONALITY_ANALYSIS
90
100
  when /DOCUMENTATION_ANALYSIS/
91
- 300 # 5 minutes - documentation analysis is moderate
101
+ TIMEOUT_DOCUMENTATION_ANALYSIS
92
102
  when /STATIC_ANALYSIS/
93
- 450 # 7.5 minutes - static analysis can be intensive
103
+ TIMEOUT_STATIC_ANALYSIS
94
104
  when /REFACTORING_RECOMMENDATIONS/
95
- 600 # 10 minutes - refactoring recommendations are complex
105
+ TIMEOUT_REFACTORING_RECOMMENDATIONS
96
106
  else
97
- nil # Use default
107
+ nil # Use default
98
108
  end
99
109
  end
100
110
  end