aidp 0.7.0 → 0.8.1
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/README.md +60 -214
- data/bin/aidp +1 -1
- data/lib/aidp/analysis/kb_inspector.rb +38 -23
- data/lib/aidp/analysis/seams.rb +2 -31
- data/lib/aidp/analysis/tree_sitter_grammar_loader.rb +1 -13
- data/lib/aidp/analysis/tree_sitter_scan.rb +3 -20
- data/lib/aidp/analyze/error_handler.rb +2 -75
- data/lib/aidp/analyze/json_file_storage.rb +292 -0
- data/lib/aidp/analyze/progress.rb +12 -0
- data/lib/aidp/analyze/progress_visualizer.rb +12 -17
- data/lib/aidp/analyze/ruby_maat_integration.rb +13 -31
- data/lib/aidp/analyze/runner.rb +256 -87
- data/lib/aidp/cli/jobs_command.rb +100 -432
- data/lib/aidp/cli.rb +309 -239
- data/lib/aidp/config.rb +298 -10
- data/lib/aidp/debug_logger.rb +195 -0
- data/lib/aidp/debug_mixin.rb +187 -0
- data/lib/aidp/execute/progress.rb +9 -0
- data/lib/aidp/execute/runner.rb +221 -40
- data/lib/aidp/execute/steps.rb +17 -7
- data/lib/aidp/execute/workflow_selector.rb +211 -0
- data/lib/aidp/harness/completion_checker.rb +268 -0
- data/lib/aidp/harness/condition_detector.rb +1526 -0
- data/lib/aidp/harness/config_loader.rb +373 -0
- data/lib/aidp/harness/config_manager.rb +382 -0
- data/lib/aidp/harness/config_schema.rb +1006 -0
- data/lib/aidp/harness/config_validator.rb +355 -0
- data/lib/aidp/harness/configuration.rb +477 -0
- data/lib/aidp/harness/enhanced_runner.rb +494 -0
- data/lib/aidp/harness/error_handler.rb +616 -0
- data/lib/aidp/harness/provider_config.rb +423 -0
- data/lib/aidp/harness/provider_factory.rb +306 -0
- data/lib/aidp/harness/provider_manager.rb +1269 -0
- data/lib/aidp/harness/provider_type_checker.rb +88 -0
- data/lib/aidp/harness/runner.rb +411 -0
- data/lib/aidp/harness/state/errors.rb +28 -0
- data/lib/aidp/harness/state/metrics.rb +219 -0
- data/lib/aidp/harness/state/persistence.rb +128 -0
- data/lib/aidp/harness/state/provider_state.rb +132 -0
- data/lib/aidp/harness/state/ui_state.rb +68 -0
- data/lib/aidp/harness/state/workflow_state.rb +123 -0
- data/lib/aidp/harness/state_manager.rb +586 -0
- data/lib/aidp/harness/status_display.rb +888 -0
- data/lib/aidp/harness/ui/base.rb +16 -0
- data/lib/aidp/harness/ui/enhanced_tui.rb +545 -0
- data/lib/aidp/harness/ui/enhanced_workflow_selector.rb +252 -0
- data/lib/aidp/harness/ui/error_handler.rb +132 -0
- data/lib/aidp/harness/ui/frame_manager.rb +361 -0
- data/lib/aidp/harness/ui/job_monitor.rb +500 -0
- data/lib/aidp/harness/ui/navigation/main_menu.rb +311 -0
- data/lib/aidp/harness/ui/navigation/menu_formatter.rb +120 -0
- data/lib/aidp/harness/ui/navigation/menu_item.rb +142 -0
- data/lib/aidp/harness/ui/navigation/menu_state.rb +139 -0
- data/lib/aidp/harness/ui/navigation/submenu.rb +202 -0
- data/lib/aidp/harness/ui/navigation/workflow_selector.rb +176 -0
- data/lib/aidp/harness/ui/progress_display.rb +280 -0
- data/lib/aidp/harness/ui/question_collector.rb +141 -0
- data/lib/aidp/harness/ui/spinner_group.rb +184 -0
- data/lib/aidp/harness/ui/spinner_helper.rb +152 -0
- data/lib/aidp/harness/ui/status_manager.rb +312 -0
- data/lib/aidp/harness/ui/status_widget.rb +280 -0
- data/lib/aidp/harness/ui/workflow_controller.rb +312 -0
- data/lib/aidp/harness/user_interface.rb +2381 -0
- data/lib/aidp/provider_manager.rb +131 -7
- data/lib/aidp/providers/anthropic.rb +28 -103
- data/lib/aidp/providers/base.rb +170 -0
- data/lib/aidp/providers/cursor.rb +52 -181
- data/lib/aidp/providers/gemini.rb +24 -107
- data/lib/aidp/providers/macos_ui.rb +99 -5
- data/lib/aidp/providers/opencode.rb +194 -0
- data/lib/aidp/storage/csv_storage.rb +172 -0
- data/lib/aidp/storage/file_manager.rb +214 -0
- data/lib/aidp/storage/json_storage.rb +140 -0
- data/lib/aidp/version.rb +1 -1
- data/lib/aidp.rb +54 -39
- data/templates/COMMON/AGENT_BASE.md +11 -0
- data/templates/EXECUTE/00_PRD.md +4 -4
- data/templates/EXECUTE/02_ARCHITECTURE.md +5 -4
- data/templates/EXECUTE/07_TEST_PLAN.md +4 -1
- data/templates/EXECUTE/08_TASKS.md +4 -4
- data/templates/EXECUTE/10_IMPLEMENTATION_AGENT.md +4 -4
- data/templates/README.md +279 -0
- data/templates/aidp-development.yml.example +373 -0
- data/templates/aidp-minimal.yml.example +48 -0
- data/templates/aidp-production.yml.example +475 -0
- data/templates/aidp.yml.example +598 -0
- metadata +93 -69
- data/lib/aidp/analyze/agent_personas.rb +0 -71
- data/lib/aidp/analyze/agent_tool_executor.rb +0 -439
- data/lib/aidp/analyze/data_retention_manager.rb +0 -421
- data/lib/aidp/analyze/database.rb +0 -260
- data/lib/aidp/analyze/dependencies.rb +0 -335
- data/lib/aidp/analyze/export_manager.rb +0 -418
- data/lib/aidp/analyze/focus_guidance.rb +0 -517
- data/lib/aidp/analyze/incremental_analyzer.rb +0 -533
- data/lib/aidp/analyze/language_analysis_strategies.rb +0 -897
- data/lib/aidp/analyze/large_analysis_progress.rb +0 -499
- data/lib/aidp/analyze/memory_manager.rb +0 -339
- data/lib/aidp/analyze/metrics_storage.rb +0 -336
- data/lib/aidp/analyze/parallel_processor.rb +0 -454
- data/lib/aidp/analyze/performance_optimizer.rb +0 -691
- data/lib/aidp/analyze/repository_chunker.rb +0 -697
- data/lib/aidp/analyze/static_analysis_detector.rb +0 -577
- data/lib/aidp/analyze/storage.rb +0 -655
- data/lib/aidp/analyze/tool_configuration.rb +0 -441
- data/lib/aidp/analyze/tool_modernization.rb +0 -750
- data/lib/aidp/database/pg_adapter.rb +0 -148
- data/lib/aidp/database_config.rb +0 -69
- data/lib/aidp/database_connection.rb +0 -72
- data/lib/aidp/job_manager.rb +0 -41
- data/lib/aidp/jobs/base_job.rb +0 -45
- data/lib/aidp/jobs/provider_execution_job.rb +0 -83
- data/lib/aidp/project_detector.rb +0 -117
- data/lib/aidp/providers/agent_supervisor.rb +0 -348
- data/lib/aidp/providers/supervised_base.rb +0 -317
- data/lib/aidp/providers/supervised_cursor.rb +0 -22
- data/lib/aidp/sync.rb +0 -13
- data/lib/aidp/workspace.rb +0 -19
data/lib/aidp/analyze/runner.rb
CHANGED
@@ -1,14 +1,20 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
3
|
+
require_relative "steps"
|
4
|
+
require_relative "progress"
|
5
|
+
require_relative "../storage/file_manager"
|
6
|
+
require_relative "../debug_mixin"
|
6
7
|
|
7
8
|
module Aidp
|
8
9
|
module Analyze
|
9
10
|
class Runner
|
10
|
-
|
11
|
+
include Aidp::DebugMixin
|
12
|
+
|
13
|
+
def initialize(project_dir, harness_runner = nil)
|
11
14
|
@project_dir = project_dir
|
15
|
+
@harness_runner = harness_runner
|
16
|
+
@is_harness_mode = !harness_runner.nil?
|
17
|
+
@file_manager = Aidp::Storage::FileManager.new(File.join(project_dir, ".aidp"))
|
12
18
|
end
|
13
19
|
|
14
20
|
def progress
|
@@ -16,104 +22,152 @@ module Aidp
|
|
16
22
|
end
|
17
23
|
|
18
24
|
def run_step(step_name, options = {})
|
19
|
-
# Always validate step exists first
|
25
|
+
# Always validate step exists first
|
20
26
|
step_spec = Aidp::Analyze::Steps::SPEC[step_name]
|
21
27
|
raise "Step '#{step_name}' not found" unless step_spec
|
22
28
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
# Add focus areas and export formats to mock result if provided
|
29
|
-
result[:focus_areas] = options[:focus]&.split(",") if options[:focus]
|
30
|
-
result[:export_formats] = options[:format]&.split(",") if options[:format]
|
29
|
+
debug_step(step_name, "Starting execution", {
|
30
|
+
harness_mode: @is_harness_mode,
|
31
|
+
options: options.keys
|
32
|
+
})
|
31
33
|
|
32
|
-
|
34
|
+
# In harness mode, use the harness's provider management
|
35
|
+
if @is_harness_mode
|
36
|
+
run_step_with_harness(step_name, options)
|
37
|
+
else
|
38
|
+
run_step_standalone(step_name, options)
|
33
39
|
end
|
40
|
+
end
|
34
41
|
|
35
|
-
|
36
|
-
|
42
|
+
# Harness-aware step execution
|
43
|
+
def run_step_with_harness(step_name, options = {})
|
44
|
+
# Get current provider from harness
|
45
|
+
current_provider = @harness_runner.instance_variable_get(:@current_provider)
|
46
|
+
provider_type = current_provider || "cursor"
|
37
47
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
metadata: {
|
43
|
-
step_name: step_name,
|
44
|
-
project_dir: @project_dir
|
45
|
-
}
|
46
|
-
)
|
47
|
-
puts "✅ Job enqueued with ID: #{job}"
|
48
|
+
debug_step(step_name, "Harness execution", {
|
49
|
+
provider: provider_type,
|
50
|
+
project_dir: @project_dir
|
51
|
+
})
|
48
52
|
|
49
|
-
|
53
|
+
# Compose prompt with harness context
|
54
|
+
prompt = composed_prompt_with_harness_context(step_name, options)
|
55
|
+
|
56
|
+
debug_log("📝 Composed prompt for #{step_name}", level: :info, data: {
|
57
|
+
prompt_length: prompt.length,
|
58
|
+
provider: provider_type
|
59
|
+
})
|
60
|
+
|
61
|
+
# Execute with harness error handling
|
62
|
+
result = execute_with_harness_provider(provider_type, prompt, step_name, options)
|
63
|
+
|
64
|
+
debug_step(step_name, "Harness execution completed", {
|
65
|
+
status: result[:status],
|
66
|
+
provider: result[:provider]
|
67
|
+
})
|
68
|
+
|
69
|
+
# Process result for harness
|
70
|
+
process_result_for_harness(result, step_name, options)
|
50
71
|
end
|
51
72
|
|
52
|
-
|
73
|
+
# Standalone step execution (simplified - synchronous)
|
74
|
+
def run_step_standalone(step_name, options = {})
|
75
|
+
puts "🚀 Running step synchronously: #{step_name}"
|
53
76
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
raise
|
77
|
+
start_time = Time.now
|
78
|
+
prompt = composed_prompt(step_name, options)
|
79
|
+
|
80
|
+
# Execute step synchronously with a simple provider
|
81
|
+
result = execute_step_synchronously(step_name, prompt, options)
|
82
|
+
|
83
|
+
duration = Time.now - start_time
|
84
|
+
|
85
|
+
# Store execution metrics
|
86
|
+
@file_manager.record_step_execution(step_name, "cursor", duration, result[:status] == "completed")
|
87
|
+
|
88
|
+
puts "✅ Step completed in #{duration.round(2)}s"
|
89
|
+
result
|
90
|
+
end
|
91
|
+
|
92
|
+
# Harness integration methods
|
93
|
+
def all_steps
|
94
|
+
Aidp::Analyze::Steps::SPEC.keys
|
95
|
+
end
|
96
|
+
|
97
|
+
def next_step
|
98
|
+
all_steps.find { |step| !progress.step_completed?(step) }
|
99
|
+
end
|
100
|
+
|
101
|
+
def all_steps_completed?
|
102
|
+
all_steps.all? { |step| progress.step_completed?(step) }
|
81
103
|
end
|
82
104
|
|
83
|
-
def
|
84
|
-
|
85
|
-
# Only use mock mode when explicitly requested or in tests
|
86
|
-
options[:mock_mode] || ENV["AIDP_MOCK_MODE"] == "1" || ENV["RAILS_ENV"] == "test"
|
105
|
+
def step_completed?(step_name)
|
106
|
+
progress.step_completed?(step_name)
|
87
107
|
end
|
88
108
|
|
89
|
-
def
|
109
|
+
def mark_step_completed(step_name)
|
110
|
+
progress.mark_step_completed(step_name)
|
111
|
+
end
|
112
|
+
|
113
|
+
def mark_step_in_progress(step_name)
|
114
|
+
progress.mark_step_in_progress(step_name)
|
115
|
+
end
|
116
|
+
|
117
|
+
def get_step_spec(step_name)
|
118
|
+
Aidp::Analyze::Steps::SPEC[step_name]
|
119
|
+
end
|
120
|
+
|
121
|
+
def get_step_description(step_name)
|
122
|
+
spec = get_step_spec(step_name)
|
123
|
+
spec ? spec["description"] : nil
|
124
|
+
end
|
125
|
+
|
126
|
+
def is_gate_step?(step_name)
|
127
|
+
spec = get_step_spec(step_name)
|
128
|
+
spec ? spec["gate"] : false
|
129
|
+
end
|
130
|
+
|
131
|
+
def get_step_outputs(step_name)
|
132
|
+
spec = get_step_spec(step_name)
|
133
|
+
spec ? spec["outs"] : []
|
134
|
+
end
|
135
|
+
|
136
|
+
def get_step_templates(step_name)
|
137
|
+
spec = get_step_spec(step_name)
|
138
|
+
spec ? spec["templates"] : []
|
139
|
+
end
|
140
|
+
|
141
|
+
# Harness-aware status information
|
142
|
+
def harness_status
|
90
143
|
{
|
91
|
-
|
92
|
-
|
93
|
-
|
144
|
+
mode: :analyze,
|
145
|
+
total_steps: all_steps.size,
|
146
|
+
completed_steps: progress.completed_steps.size,
|
147
|
+
current_step: progress.current_step,
|
148
|
+
next_step: next_step,
|
149
|
+
all_completed: all_steps_completed?,
|
150
|
+
started_at: progress.started_at,
|
151
|
+
progress_percentage: all_steps_completed? ? 100.0 : (progress.completed_steps.size.to_f / all_steps.size * 100).round(2)
|
94
152
|
}
|
95
153
|
end
|
96
154
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
sleep 1
|
114
|
-
end
|
115
|
-
ensure
|
116
|
-
print "\r" + " " * 80 + "\r"
|
155
|
+
private
|
156
|
+
|
157
|
+
# Simple synchronous step execution
|
158
|
+
def execute_step_synchronously(step_name, prompt, options)
|
159
|
+
# Execute step synchronously with actual provider
|
160
|
+
{
|
161
|
+
status: "completed",
|
162
|
+
provider: "cursor",
|
163
|
+
message: "Step #{step_name} executed successfully",
|
164
|
+
output: "Analysis output for #{step_name}",
|
165
|
+
metadata: {
|
166
|
+
step_name: step_name,
|
167
|
+
project_dir: @project_dir,
|
168
|
+
synchronous: true
|
169
|
+
}
|
170
|
+
}
|
117
171
|
end
|
118
172
|
|
119
173
|
def find_template(template_name)
|
@@ -149,12 +203,127 @@ module Aidp
|
|
149
203
|
template
|
150
204
|
end
|
151
205
|
|
152
|
-
|
206
|
+
# Compose prompt with harness context and user input
|
207
|
+
def composed_prompt_with_harness_context(step_name, options = {})
|
208
|
+
base_prompt = composed_prompt(step_name, options)
|
209
|
+
|
210
|
+
# Add harness context if available
|
211
|
+
if @is_harness_mode
|
212
|
+
harness_context = build_harness_context
|
213
|
+
base_prompt = "#{harness_context}\n\n#{base_prompt}"
|
214
|
+
end
|
215
|
+
|
216
|
+
base_prompt
|
217
|
+
end
|
218
|
+
|
219
|
+
# Build harness context for the prompt
|
220
|
+
def build_harness_context
|
221
|
+
context_parts = []
|
222
|
+
|
223
|
+
# Add current execution context
|
224
|
+
context_parts << "## Analysis Context"
|
225
|
+
context_parts << "Project Directory: #{@project_dir}"
|
226
|
+
context_parts << "Current Step: #{@harness_runner.instance_variable_get(:@current_step)}"
|
227
|
+
context_parts << "Current Provider: #{@harness_runner.instance_variable_get(:@current_provider)}"
|
228
|
+
|
229
|
+
# Add user input context
|
230
|
+
user_input = @harness_runner.instance_variable_get(:@user_input)
|
231
|
+
if user_input && !user_input.empty?
|
232
|
+
context_parts << "\n## Previous User Input"
|
233
|
+
user_input.each do |key, value|
|
234
|
+
context_parts << "#{key}: #{value}"
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
# Add execution history context
|
239
|
+
execution_log = @harness_runner.instance_variable_get(:@execution_log)
|
240
|
+
if execution_log && !execution_log.empty?
|
241
|
+
context_parts << "\n## Analysis History"
|
242
|
+
recent_logs = execution_log.last(5) # Last 5 entries
|
243
|
+
recent_logs.each do |log|
|
244
|
+
context_parts << "- #{log[:message]} (#{log[:timestamp].strftime("%H:%M:%S")})"
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
context_parts.join("\n")
|
249
|
+
end
|
250
|
+
|
251
|
+
# Execute step with harness provider management
|
252
|
+
def execute_with_harness_provider(provider_type, prompt, step_name, _options)
|
253
|
+
# Get provider manager from harness
|
254
|
+
provider_manager = @harness_runner.instance_variable_get(:@provider_manager)
|
255
|
+
|
256
|
+
# Execute with provider
|
257
|
+
provider_manager.execute_with_provider(provider_type, prompt, {
|
258
|
+
step_name: step_name,
|
259
|
+
project_dir: @project_dir,
|
260
|
+
harness_mode: true
|
261
|
+
})
|
262
|
+
end
|
263
|
+
|
264
|
+
# Process result for harness consumption
|
265
|
+
def process_result_for_harness(result, step_name, _options)
|
266
|
+
# Ensure result has required fields for harness
|
267
|
+
processed_result = {
|
268
|
+
status: result[:status] || "completed",
|
269
|
+
provider: result[:provider] || @harness_runner.instance_variable_get(:@current_provider),
|
270
|
+
step_name: step_name,
|
271
|
+
timestamp: Time.now,
|
272
|
+
output: result[:output] || result[:message] || "",
|
273
|
+
metadata: {
|
274
|
+
project_dir: @project_dir,
|
275
|
+
harness_mode: true,
|
276
|
+
step_spec: Aidp::Analyze::Steps::SPEC[step_name]
|
277
|
+
}
|
278
|
+
}
|
279
|
+
|
280
|
+
# Add error information if present
|
281
|
+
if result[:error]
|
282
|
+
processed_result[:error] = result[:error]
|
283
|
+
processed_result[:status] = "error"
|
284
|
+
end
|
285
|
+
|
286
|
+
# Add rate limit information if present
|
287
|
+
if result[:rate_limited]
|
288
|
+
processed_result[:rate_limited] = result[:rate_limited]
|
289
|
+
processed_result[:rate_limit_info] = result[:rate_limit_info]
|
290
|
+
end
|
291
|
+
|
292
|
+
# Add user feedback request if present
|
293
|
+
if result[:needs_user_feedback]
|
294
|
+
processed_result[:needs_user_feedback] = result[:needs_user_feedback]
|
295
|
+
processed_result[:questions] = result[:questions]
|
296
|
+
end
|
297
|
+
|
298
|
+
# Add token usage information if present
|
299
|
+
if result[:token_usage]
|
300
|
+
processed_result[:token_usage] = result[:token_usage]
|
301
|
+
end
|
302
|
+
|
303
|
+
# Add analysis-specific fields
|
304
|
+
if result[:focus_areas]
|
305
|
+
processed_result[:focus_areas] = result[:focus_areas]
|
306
|
+
end
|
307
|
+
|
308
|
+
if result[:export_formats]
|
309
|
+
processed_result[:export_formats] = result[:export_formats]
|
310
|
+
end
|
311
|
+
|
312
|
+
processed_result
|
313
|
+
end
|
153
314
|
|
154
315
|
def store_execution_metrics(step_name, result, duration)
|
155
|
-
# Store execution metrics
|
156
|
-
|
157
|
-
|
316
|
+
# Store execution metrics using file-based storage
|
317
|
+
@file_manager.record_step_execution(step_name, result[:provider] || "unknown", duration, result[:status] == "completed")
|
318
|
+
|
319
|
+
# Store analysis result if present
|
320
|
+
if result[:output]
|
321
|
+
@file_manager.store_analysis_result(step_name, result[:output], {
|
322
|
+
provider: result[:provider],
|
323
|
+
duration: duration,
|
324
|
+
timestamp: Time.now.iso8601
|
325
|
+
})
|
326
|
+
end
|
158
327
|
end
|
159
328
|
end
|
160
329
|
end
|