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.
- checksums.yaml +4 -4
- data/lib/aidp/analyze/error_handler.rb +4 -2
- data/lib/aidp/{analysis → analyze}/kb_inspector.rb +106 -89
- data/lib/aidp/analyze/prioritizer.rb +3 -2
- data/lib/aidp/analyze/ruby_maat_integration.rb +20 -3
- data/lib/aidp/analyze/runner.rb +27 -9
- data/lib/aidp/{analysis → analyze}/seams.rb +1 -1
- data/lib/aidp/analyze/steps.rb +7 -7
- data/lib/aidp/{analysis → analyze}/tree_sitter_grammar_loader.rb +22 -5
- data/lib/aidp/{analysis → analyze}/tree_sitter_scan.rb +32 -15
- data/lib/aidp/cli/first_run_wizard.rb +37 -28
- data/lib/aidp/cli/jobs_command.rb +37 -18
- data/lib/aidp/cli/terminal_io.rb +3 -3
- data/lib/aidp/cli.rb +131 -63
- data/lib/aidp/execute/runner.rb +27 -9
- data/lib/aidp/execute/steps.rb +18 -18
- data/lib/aidp/execute/workflow_selector.rb +36 -21
- data/lib/aidp/harness/enhanced_runner.rb +3 -3
- data/lib/aidp/harness/provider_factory.rb +3 -1
- data/lib/aidp/harness/provider_manager.rb +34 -15
- data/lib/aidp/harness/runner.rb +24 -5
- data/lib/aidp/harness/simple_user_interface.rb +19 -4
- data/lib/aidp/harness/status_display.rb +121 -104
- data/lib/aidp/harness/ui/enhanced_tui.rb +33 -5
- data/lib/aidp/harness/ui/error_handler.rb +3 -2
- data/lib/aidp/harness/ui/frame_manager.rb +52 -32
- data/lib/aidp/harness/ui/navigation/main_menu.rb +23 -14
- data/lib/aidp/harness/ui/progress_display.rb +28 -5
- data/lib/aidp/harness/ui/status_widget.rb +17 -8
- data/lib/aidp/harness/ui/workflow_controller.rb +25 -9
- data/lib/aidp/harness/user_interface.rb +341 -328
- data/lib/aidp/provider_manager.rb +10 -6
- data/lib/aidp/providers/anthropic.rb +3 -3
- data/lib/aidp/providers/base.rb +20 -1
- data/lib/aidp/providers/cursor.rb +6 -8
- data/lib/aidp/providers/gemini.rb +3 -3
- data/lib/aidp/providers/github_copilot.rb +264 -0
- data/lib/aidp/providers/opencode.rb +6 -8
- data/lib/aidp/version.rb +1 -1
- data/lib/aidp.rb +4 -4
- metadata +6 -6
- data/lib/aidp/analyze/progress_visualizer.rb +0 -314
@@ -24,9 +24,24 @@ module Aidp
|
|
24
24
|
|
25
25
|
private
|
26
26
|
|
27
|
+
# Helper method for consistent message display using TTY::Prompt
|
28
|
+
def display_message(message, type: :info)
|
29
|
+
color = case type
|
30
|
+
when :error then :red
|
31
|
+
when :success then :green
|
32
|
+
when :warning then :yellow
|
33
|
+
when :info then :blue
|
34
|
+
when :highlight then :cyan
|
35
|
+
when :muted then :bright_black
|
36
|
+
else :white
|
37
|
+
end
|
38
|
+
|
39
|
+
@prompt.say(message, color: color)
|
40
|
+
end
|
41
|
+
|
27
42
|
def select_workflow_interactive
|
28
|
-
|
29
|
-
|
43
|
+
display_message("\n🚀 Welcome to AI Dev Pipeline!", type: :highlight)
|
44
|
+
display_message("Let's set up your development workflow.\n\n")
|
30
45
|
|
31
46
|
# Step 1: Collect project information
|
32
47
|
collect_project_info
|
@@ -45,7 +60,7 @@ module Aidp
|
|
45
60
|
end
|
46
61
|
|
47
62
|
def select_workflow_with_defaults
|
48
|
-
|
63
|
+
display_message("\n🚀 Starting harness with default workflow configuration...", type: :highlight)
|
49
64
|
|
50
65
|
# Use default project information
|
51
66
|
@user_input = {
|
@@ -71,7 +86,7 @@ module Aidp
|
|
71
86
|
private
|
72
87
|
|
73
88
|
def collect_project_info
|
74
|
-
|
89
|
+
display_message("📋 First, tell us about your project:\n", type: :highlight)
|
75
90
|
|
76
91
|
@user_input[:project_description] = prompt_required(
|
77
92
|
"What do you want to build? (Be specific about features and goals)"
|
@@ -91,17 +106,17 @@ module Aidp
|
|
91
106
|
end
|
92
107
|
|
93
108
|
def choose_workflow_type
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
109
|
+
display_message("\n🎯 Choose your development approach:\n", type: :highlight)
|
110
|
+
display_message("1. 🔬 Exploration/Experiment - Quick prototype or proof of concept")
|
111
|
+
display_message(" • Fast iteration, minimal documentation", type: :muted)
|
112
|
+
display_message(" • Focus on core functionality and validation", type: :muted)
|
113
|
+
display_message(" • Steps: PRD → Tasks → Implementation", type: :muted)
|
114
|
+
display_message("")
|
115
|
+
display_message("2. 🏗️ Full Development - Production-ready feature or system")
|
116
|
+
display_message(" • Comprehensive planning and documentation", type: :muted)
|
117
|
+
display_message(" • You can customize which steps to include", type: :muted)
|
118
|
+
display_message(" • Full enterprise workflow available", type: :muted)
|
119
|
+
display_message("")
|
105
120
|
|
106
121
|
choice = prompt_choice("Which approach fits your project?", ["1", "2", "exploration", "full"])
|
107
122
|
|
@@ -111,7 +126,7 @@ module Aidp
|
|
111
126
|
when "2", "full"
|
112
127
|
:full
|
113
128
|
else
|
114
|
-
|
129
|
+
display_message("Invalid choice. Defaulting to exploration workflow.", type: :warning)
|
115
130
|
:exploration
|
116
131
|
end
|
117
132
|
end
|
@@ -137,8 +152,8 @@ module Aidp
|
|
137
152
|
end
|
138
153
|
|
139
154
|
def full_workflow_steps
|
140
|
-
|
141
|
-
|
155
|
+
display_message("\n🛠️ Customize your full development workflow:\n", type: :highlight)
|
156
|
+
display_message("Select the steps you want to include (enter numbers separated by commas):\n")
|
142
157
|
|
143
158
|
available_steps = {
|
144
159
|
"1" => "00_PRD - Product Requirements Document",
|
@@ -155,8 +170,8 @@ module Aidp
|
|
155
170
|
"12" => "13_DELIVERY_ROLLOUT - Deployment Planning"
|
156
171
|
}
|
157
172
|
|
158
|
-
available_steps.each { |num, desc|
|
159
|
-
|
173
|
+
available_steps.each { |num, desc| display_message(" #{num}. #{desc}") }
|
174
|
+
display_message("")
|
160
175
|
|
161
176
|
selected = prompt_required("Enter step numbers (e.g., 1,3,5,9,10): ")
|
162
177
|
selected_numbers = selected.split(",").map(&:strip).map(&:to_i)
|
@@ -193,7 +208,7 @@ module Aidp
|
|
193
208
|
input = @prompt.ask("#{question}:")
|
194
209
|
|
195
210
|
if input.nil? || input.strip.empty?
|
196
|
-
|
211
|
+
display_message("❌ This field is required. Please provide an answer.", type: :error)
|
197
212
|
next
|
198
213
|
end
|
199
214
|
|
@@ -50,7 +50,7 @@ module Aidp
|
|
50
50
|
@configuration = Configuration.new(project_dir)
|
51
51
|
@state_manager = StateManager.new(project_dir, @mode)
|
52
52
|
@condition_detector = ConditionDetector.new
|
53
|
-
@provider_manager = ProviderManager.new(@configuration)
|
53
|
+
@provider_manager = ProviderManager.new(@configuration, prompt: TTY::Prompt.new)
|
54
54
|
@error_handler = ErrorHandler.new(@provider_manager, @configuration)
|
55
55
|
@completion_checker = CompletionChecker.new(@project_dir, @workflow_type)
|
56
56
|
end
|
@@ -312,9 +312,9 @@ module Aidp
|
|
312
312
|
def get_mode_runner
|
313
313
|
case @mode
|
314
314
|
when :analyze
|
315
|
-
Aidp::Analyze::Runner.new(@project_dir, self)
|
315
|
+
Aidp::Analyze::Runner.new(@project_dir, self, prompt: TTY::Prompt.new)
|
316
316
|
when :execute
|
317
|
-
Aidp::Execute::Runner.new(@project_dir, self)
|
317
|
+
Aidp::Execute::Runner.new(@project_dir, self, prompt: TTY::Prompt.new)
|
318
318
|
else
|
319
319
|
raise ArgumentError, "Unsupported mode: #{@mode}"
|
320
320
|
end
|
@@ -7,6 +7,7 @@ require_relative "../providers/anthropic"
|
|
7
7
|
require_relative "../providers/gemini"
|
8
8
|
require_relative "../providers/macos_ui"
|
9
9
|
require_relative "../providers/opencode"
|
10
|
+
require_relative "../providers/github_copilot"
|
10
11
|
|
11
12
|
module Aidp
|
12
13
|
module Harness
|
@@ -17,7 +18,8 @@ module Aidp
|
|
17
18
|
"anthropic" => Aidp::Providers::Anthropic,
|
18
19
|
"gemini" => Aidp::Providers::Gemini,
|
19
20
|
"macos" => Aidp::Providers::MacOSUI,
|
20
|
-
"opencode" => Aidp::Providers::Opencode
|
21
|
+
"opencode" => Aidp::Providers::Opencode,
|
22
|
+
"github_copilot" => Aidp::Providers::GithubCopilot
|
21
23
|
}.freeze
|
22
24
|
|
23
25
|
def initialize(config_manager = nil)
|
@@ -1,13 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "tty-prompt"
|
3
4
|
require_relative "provider_factory"
|
4
5
|
|
5
6
|
module Aidp
|
6
7
|
module Harness
|
7
8
|
# Manages provider switching and fallback logic
|
8
9
|
class ProviderManager
|
9
|
-
def initialize(configuration)
|
10
|
+
def initialize(configuration, prompt: TTY::Prompt.new)
|
10
11
|
@configuration = configuration
|
12
|
+
@prompt = prompt
|
11
13
|
@current_provider = nil
|
12
14
|
@current_model = nil
|
13
15
|
@provider_history = []
|
@@ -1199,20 +1201,37 @@ module Aidp
|
|
1199
1201
|
[delay, 60].min # Cap at 60 seconds
|
1200
1202
|
end
|
1201
1203
|
|
1204
|
+
private
|
1205
|
+
|
1206
|
+
def display_message(message, type: :info)
|
1207
|
+
color = case type
|
1208
|
+
when :error then :red
|
1209
|
+
when :success then :green
|
1210
|
+
when :warning then :yellow
|
1211
|
+
when :info then :blue
|
1212
|
+
when :highlight then :cyan
|
1213
|
+
when :muted then :bright_black
|
1214
|
+
else :white
|
1215
|
+
end
|
1216
|
+
@prompt.say(message, color: color)
|
1217
|
+
end
|
1218
|
+
|
1219
|
+
public
|
1220
|
+
|
1202
1221
|
# Log provider switch
|
1203
1222
|
def log_provider_switch(from_provider, to_provider, reason, context)
|
1204
|
-
|
1223
|
+
display_message("🔄 Provider switch: #{from_provider} → #{to_provider} (#{reason})", type: :info)
|
1205
1224
|
if context.any?
|
1206
|
-
|
1225
|
+
display_message(" Context: #{context.inspect}", type: :muted)
|
1207
1226
|
end
|
1208
1227
|
end
|
1209
1228
|
|
1210
1229
|
# Log no providers available
|
1211
1230
|
def log_no_providers_available(reason, context)
|
1212
|
-
|
1213
|
-
|
1231
|
+
display_message("❌ No providers available for switching (#{reason})", type: :error)
|
1232
|
+
display_message(" All providers are rate limited, unhealthy, or circuit breaker open", type: :warning)
|
1214
1233
|
if context.any?
|
1215
|
-
|
1234
|
+
display_message(" Context: #{context.inspect}", type: :muted)
|
1216
1235
|
end
|
1217
1236
|
end
|
1218
1237
|
|
@@ -1220,26 +1239,26 @@ module Aidp
|
|
1220
1239
|
def log_circuit_breaker_event(provider_name, event)
|
1221
1240
|
case event
|
1222
1241
|
when "opened"
|
1223
|
-
|
1242
|
+
display_message("🔴 Circuit breaker opened for provider: #{provider_name}", type: :error)
|
1224
1243
|
when "reset"
|
1225
|
-
|
1244
|
+
display_message("🟢 Circuit breaker reset for provider: #{provider_name}", type: :success)
|
1226
1245
|
end
|
1227
1246
|
end
|
1228
1247
|
|
1229
1248
|
# Log model switch
|
1230
1249
|
def log_model_switch(from_model, to_model, reason, context)
|
1231
|
-
|
1250
|
+
display_message("🔄 Model switch: #{from_model} → #{to_model} (#{reason})", type: :info)
|
1232
1251
|
if context.any?
|
1233
|
-
|
1252
|
+
display_message(" Context: #{context.inspect}", type: :muted)
|
1234
1253
|
end
|
1235
1254
|
end
|
1236
1255
|
|
1237
1256
|
# Log no models available
|
1238
1257
|
def log_no_models_available(provider_name, reason, context)
|
1239
|
-
|
1240
|
-
|
1258
|
+
display_message("❌ No models available for provider #{provider_name} (#{reason})", type: :error)
|
1259
|
+
display_message(" All models are rate limited, unhealthy, or circuit breaker open", type: :warning)
|
1241
1260
|
if context.any?
|
1242
|
-
|
1261
|
+
display_message(" Context: #{context.inspect}", type: :muted)
|
1243
1262
|
end
|
1244
1263
|
end
|
1245
1264
|
|
@@ -1247,9 +1266,9 @@ module Aidp
|
|
1247
1266
|
def log_model_circuit_breaker_event(provider_name, model_name, event)
|
1248
1267
|
case event
|
1249
1268
|
when "opened"
|
1250
|
-
|
1269
|
+
display_message("🔴 Circuit breaker opened for model: #{provider_name}:#{model_name}", type: :error)
|
1251
1270
|
when "reset"
|
1252
|
-
|
1271
|
+
display_message("🟢 Circuit breaker reset for model: #{provider_name}:#{model_name}", type: :success)
|
1253
1272
|
end
|
1254
1273
|
end
|
1255
1274
|
|
data/lib/aidp/harness/runner.rb
CHANGED
@@ -27,6 +27,9 @@ module Aidp
|
|
27
27
|
error: "error"
|
28
28
|
}.freeze
|
29
29
|
|
30
|
+
# Public accessors for testing and integration
|
31
|
+
attr_reader :current_provider, :current_step, :user_input, :execution_log, :provider_manager
|
32
|
+
|
30
33
|
def initialize(project_dir, mode = :analyze, options = {})
|
31
34
|
@project_dir = project_dir
|
32
35
|
@mode = mode.to_sym
|
@@ -37,6 +40,7 @@ module Aidp
|
|
37
40
|
@current_provider = nil
|
38
41
|
@user_input = options[:user_input] || {} # Include user input from workflow selection
|
39
42
|
@execution_log = []
|
43
|
+
@prompt = options[:prompt] || TTY::Prompt.new
|
40
44
|
|
41
45
|
# Store workflow configuration
|
42
46
|
@selected_steps = options[:selected_steps]
|
@@ -46,7 +50,7 @@ module Aidp
|
|
46
50
|
@configuration = Configuration.new(project_dir)
|
47
51
|
@state_manager = StateManager.new(project_dir, @mode)
|
48
52
|
@condition_detector = ConditionDetector.new
|
49
|
-
@provider_manager = ProviderManager.new(@configuration)
|
53
|
+
@provider_manager = ProviderManager.new(@configuration, prompt: @prompt)
|
50
54
|
@user_interface = SimpleUserInterface.new
|
51
55
|
@error_handler = ErrorHandler.new(@provider_manager, @configuration)
|
52
56
|
@status_display = StatusDisplay.new
|
@@ -96,8 +100,8 @@ module Aidp
|
|
96
100
|
log_execution("Harness completed successfully - all criteria met", completion_status)
|
97
101
|
else
|
98
102
|
log_execution("Steps completed but completion criteria not met", completion_status)
|
99
|
-
|
100
|
-
|
103
|
+
display_message("\n⚠️ All steps completed but some completion criteria not met:", type: :warning)
|
104
|
+
display_message(completion_status[:summary], type: :info)
|
101
105
|
|
102
106
|
# Ask user if they want to continue anyway
|
103
107
|
if @user_interface.get_confirmation("Continue anyway? This may indicate issues that should be addressed.", default: false)
|
@@ -181,9 +185,9 @@ module Aidp
|
|
181
185
|
def get_mode_runner
|
182
186
|
case @mode
|
183
187
|
when :analyze
|
184
|
-
Aidp::Analyze::Runner.new(@project_dir, self)
|
188
|
+
Aidp::Analyze::Runner.new(@project_dir, self, prompt: TTY::Prompt.new)
|
185
189
|
when :execute
|
186
|
-
Aidp::Execute::Runner.new(@project_dir, self)
|
190
|
+
Aidp::Execute::Runner.new(@project_dir, self, prompt: TTY::Prompt.new)
|
187
191
|
else
|
188
192
|
raise ArgumentError, "Unsupported mode: #{@mode}"
|
189
193
|
end
|
@@ -406,6 +410,21 @@ module Aidp
|
|
406
410
|
"Harness finished in state: #{@state}"
|
407
411
|
end
|
408
412
|
end
|
413
|
+
|
414
|
+
private
|
415
|
+
|
416
|
+
def display_message(message, type: :info)
|
417
|
+
color = case type
|
418
|
+
when :error then :red
|
419
|
+
when :success then :green
|
420
|
+
when :warning then :yellow
|
421
|
+
when :info then :blue
|
422
|
+
when :highlight then :cyan
|
423
|
+
when :muted then :bright_black
|
424
|
+
else :white
|
425
|
+
end
|
426
|
+
@prompt.say(message, color: color)
|
427
|
+
end
|
409
428
|
end
|
410
429
|
end
|
411
430
|
end
|
@@ -26,10 +26,25 @@ module Aidp
|
|
26
26
|
|
27
27
|
private
|
28
28
|
|
29
|
+
# Helper method for consistent message display using TTY::Prompt
|
30
|
+
def display_message(message, type: :info)
|
31
|
+
color = case type
|
32
|
+
when :error then :red
|
33
|
+
when :success then :green
|
34
|
+
when :warning then :yellow
|
35
|
+
when :info then :blue
|
36
|
+
when :highlight then :cyan
|
37
|
+
when :muted then :bright_black
|
38
|
+
else :white
|
39
|
+
end
|
40
|
+
|
41
|
+
@prompt.say(message, color: color)
|
42
|
+
end
|
43
|
+
|
29
44
|
def show_context(context)
|
30
|
-
|
31
|
-
|
32
|
-
|
45
|
+
display_message("\n🤖 Agent needs feedback", type: :info)
|
46
|
+
display_message("Context: #{context[:description]}", type: :info) if context[:description]
|
47
|
+
display_message("", type: :info)
|
33
48
|
end
|
34
49
|
|
35
50
|
def ask_question(question_data)
|
@@ -39,7 +54,7 @@ module Aidp
|
|
39
54
|
required = question_data[:required] != false
|
40
55
|
options = question_data[:options]
|
41
56
|
|
42
|
-
|
57
|
+
display_message("\n#{question}", type: :info)
|
43
58
|
|
44
59
|
case type
|
45
60
|
when "text"
|