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
@@ -1,335 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative "steps"
|
4
|
-
|
5
|
-
module Aidp
|
6
|
-
module Analyze
|
7
|
-
class Dependencies
|
8
|
-
# Define step dependencies - which steps must be completed before others
|
9
|
-
DEPENDENCIES = {
|
10
|
-
"repository" => [], # No dependencies - can run first
|
11
|
-
"architecture" => ["repository"], # Needs repository analysis first
|
12
|
-
"test-coverage" => ["repository"], # Needs repository analysis first
|
13
|
-
"functionality" => %w[repository architecture], # Needs both repository and architecture
|
14
|
-
"documentation" => %w[repository functionality], # Needs repository and functionality analysis
|
15
|
-
"static-analysis" => ["repository"], # Needs repository analysis first
|
16
|
-
"refactoring" => %w[repository architecture functionality static-analysis] # Needs most other analyses
|
17
|
-
}.freeze
|
18
|
-
|
19
|
-
# Define step prerequisites - what data/artifacts are needed
|
20
|
-
PREREQUISITES = {
|
21
|
-
"repository" => {
|
22
|
-
required_files: [],
|
23
|
-
required_data: [],
|
24
|
-
description: "No prerequisites - analyzes Git repository directly"
|
25
|
-
},
|
26
|
-
"architecture" => {
|
27
|
-
required_files: ["docs/RepositoryAnalysis.md"],
|
28
|
-
required_data: ["repository_metrics"],
|
29
|
-
description: "Requires repository analysis results to understand project structure"
|
30
|
-
},
|
31
|
-
"test-coverage" => {
|
32
|
-
required_files: ["docs/RepositoryAnalysis.md"],
|
33
|
-
required_data: ["repository_metrics"],
|
34
|
-
description: "Requires repository analysis to identify test files and coverage gaps"
|
35
|
-
},
|
36
|
-
"functionality" => {
|
37
|
-
required_files: ["docs/RepositoryAnalysis.md", "docs/ArchitectureAnalysis.md"],
|
38
|
-
required_data: %w[repository_metrics architecture_patterns],
|
39
|
-
description: "Requires repository and architecture analysis to understand feature boundaries"
|
40
|
-
},
|
41
|
-
"documentation" => {
|
42
|
-
required_files: ["docs/RepositoryAnalysis.md", "docs/FunctionalityAnalysis.md"],
|
43
|
-
required_data: %w[repository_metrics feature_map],
|
44
|
-
description: "Requires repository and functionality analysis to identify documentation gaps"
|
45
|
-
},
|
46
|
-
"static-analysis" => {
|
47
|
-
required_files: ["docs/RepositoryAnalysis.md"],
|
48
|
-
required_data: ["repository_metrics"],
|
49
|
-
description: "Requires repository analysis to identify files for static analysis"
|
50
|
-
},
|
51
|
-
"refactoring" => {
|
52
|
-
required_files: ["docs/RepositoryAnalysis.md", "docs/ArchitectureAnalysis.md", "docs/FunctionalityAnalysis.md",
|
53
|
-
"docs/StaticAnalysisReport.md"],
|
54
|
-
required_data: %w[repository_metrics architecture_patterns feature_map static_analysis_results],
|
55
|
-
description: "Requires comprehensive analysis results to provide refactoring recommendations"
|
56
|
-
}
|
57
|
-
}.freeze
|
58
|
-
|
59
|
-
def initialize(project_dir = Dir.pwd)
|
60
|
-
@project_dir = project_dir
|
61
|
-
end
|
62
|
-
|
63
|
-
# Get all dependencies for a specific step
|
64
|
-
def get_dependencies(step_name)
|
65
|
-
DEPENDENCIES[step_name] || []
|
66
|
-
end
|
67
|
-
|
68
|
-
# Get all prerequisites for a specific step
|
69
|
-
def get_prerequisites(step_name)
|
70
|
-
PREREQUISITES[step_name] || {}
|
71
|
-
end
|
72
|
-
|
73
|
-
# Check if a step can be executed (all dependencies satisfied)
|
74
|
-
def can_execute_step?(step_name, completed_steps)
|
75
|
-
dependencies = get_dependencies(step_name)
|
76
|
-
dependencies.all? { |dep| completed_steps.include?(dep) }
|
77
|
-
end
|
78
|
-
|
79
|
-
# Get all steps that can be executed next (dependencies satisfied)
|
80
|
-
def get_executable_steps(completed_steps)
|
81
|
-
all_steps = Aidp::Analyze::Steps::SPEC.keys
|
82
|
-
all_steps.select { |step| can_execute_step?(step, completed_steps) }
|
83
|
-
end
|
84
|
-
|
85
|
-
# Get the next recommended step to execute
|
86
|
-
def get_next_recommended_step(completed_steps)
|
87
|
-
executable_steps = get_executable_steps(completed_steps)
|
88
|
-
return nil if executable_steps.empty?
|
89
|
-
|
90
|
-
# Prioritize steps based on dependency depth and importance
|
91
|
-
prioritized_steps = prioritize_steps(executable_steps, completed_steps)
|
92
|
-
prioritized_steps.first
|
93
|
-
end
|
94
|
-
|
95
|
-
# Check if prerequisites are satisfied for a step
|
96
|
-
def prerequisites_satisfied?(step_name)
|
97
|
-
prereqs = get_prerequisites(step_name)
|
98
|
-
|
99
|
-
# Check required files
|
100
|
-
required_files = prereqs[:required_files] || []
|
101
|
-
required_files.each do |file|
|
102
|
-
file_path = File.join(@project_dir, file)
|
103
|
-
return false unless File.exist?(file_path)
|
104
|
-
end
|
105
|
-
|
106
|
-
# Check required data (this would be more sophisticated in a real implementation)
|
107
|
-
required_data = prereqs[:required_data] || []
|
108
|
-
required_data.each do |data_type|
|
109
|
-
# For now, we'll assume data is available if the corresponding step is completed
|
110
|
-
# In a real implementation, this would check the database or other data stores
|
111
|
-
return false unless data_available?(data_type)
|
112
|
-
end
|
113
|
-
|
114
|
-
true
|
115
|
-
end
|
116
|
-
|
117
|
-
# Get execution order for all steps
|
118
|
-
def get_execution_order
|
119
|
-
execution_order = []
|
120
|
-
completed_steps = []
|
121
|
-
|
122
|
-
# Start with steps that have no dependencies
|
123
|
-
current_steps = DEPENDENCIES.select { |_, deps| deps.empty? }.keys
|
124
|
-
|
125
|
-
while current_steps.any?
|
126
|
-
# Add current steps to execution order
|
127
|
-
execution_order.concat(current_steps)
|
128
|
-
completed_steps.concat(current_steps)
|
129
|
-
|
130
|
-
# Find next steps that can be executed
|
131
|
-
current_steps = get_executable_steps(completed_steps) - completed_steps
|
132
|
-
end
|
133
|
-
|
134
|
-
# Add any remaining steps (should be none if dependencies are well-formed)
|
135
|
-
remaining_steps = AnalyzeSteps.list - execution_order
|
136
|
-
execution_order.concat(remaining_steps) if remaining_steps.any?
|
137
|
-
|
138
|
-
execution_order
|
139
|
-
end
|
140
|
-
|
141
|
-
# Validate that all dependencies can be satisfied
|
142
|
-
def validate_dependencies
|
143
|
-
errors = []
|
144
|
-
|
145
|
-
AnalyzeSteps.list.each do |step|
|
146
|
-
dependencies = get_dependencies(step)
|
147
|
-
dependencies.each do |dep|
|
148
|
-
errors << "Step '#{step}' depends on unknown step '#{dep}'" unless AnalyzeSteps.list.include?(dep)
|
149
|
-
end
|
150
|
-
end
|
151
|
-
|
152
|
-
# Check for circular dependencies
|
153
|
-
execution_order = get_execution_order
|
154
|
-
if execution_order.length != AnalyzeSteps.list.length
|
155
|
-
errors << "Circular dependencies detected - cannot determine execution order"
|
156
|
-
end
|
157
|
-
|
158
|
-
errors
|
159
|
-
end
|
160
|
-
|
161
|
-
# Get dependency graph for visualization
|
162
|
-
def get_dependency_graph
|
163
|
-
graph = {}
|
164
|
-
|
165
|
-
AnalyzeSteps.list.each do |step|
|
166
|
-
graph[step] = {
|
167
|
-
dependencies: get_dependencies(step),
|
168
|
-
prerequisites: get_prerequisites(step),
|
169
|
-
can_execute: false, # Will be set by caller
|
170
|
-
completed: false # Will be set by caller
|
171
|
-
}
|
172
|
-
end
|
173
|
-
|
174
|
-
graph
|
175
|
-
end
|
176
|
-
|
177
|
-
# Get detailed execution plan
|
178
|
-
def get_execution_plan(completed_steps = [])
|
179
|
-
plan = {
|
180
|
-
completed: completed_steps,
|
181
|
-
next_steps: [],
|
182
|
-
blocked_steps: [],
|
183
|
-
execution_order: get_execution_order,
|
184
|
-
recommendations: []
|
185
|
-
}
|
186
|
-
|
187
|
-
# Find next executable steps
|
188
|
-
next_steps = get_executable_steps(completed_steps) - completed_steps
|
189
|
-
plan[:next_steps] = next_steps
|
190
|
-
|
191
|
-
# Find blocked steps
|
192
|
-
blocked_steps = AnalyzeSteps.list - completed_steps - next_steps
|
193
|
-
plan[:blocked_steps] = blocked_steps
|
194
|
-
|
195
|
-
# Generate recommendations
|
196
|
-
plan[:recommendations] = generate_recommendations(plan)
|
197
|
-
|
198
|
-
plan
|
199
|
-
end
|
200
|
-
|
201
|
-
# Check if a step is blocked by missing dependencies
|
202
|
-
def step_blocked?(step_name, completed_steps)
|
203
|
-
!can_execute_step?(step_name, completed_steps)
|
204
|
-
end
|
205
|
-
|
206
|
-
# Get blocking steps for a specific step
|
207
|
-
def get_blocking_steps(step_name, completed_steps)
|
208
|
-
dependencies = get_dependencies(step_name)
|
209
|
-
dependencies - completed_steps
|
210
|
-
end
|
211
|
-
|
212
|
-
# Get steps that depend on a specific step
|
213
|
-
def get_dependent_steps(step_name)
|
214
|
-
dependent_steps = []
|
215
|
-
|
216
|
-
AnalyzeSteps.list.each do |step|
|
217
|
-
dependencies = get_dependencies(step)
|
218
|
-
dependent_steps << step if dependencies.include?(step_name)
|
219
|
-
end
|
220
|
-
|
221
|
-
dependent_steps
|
222
|
-
end
|
223
|
-
|
224
|
-
# Check if forcing a step would break dependencies
|
225
|
-
def can_force_step?(step_name, completed_steps)
|
226
|
-
# A step can be forced if it's not currently executable
|
227
|
-
!can_execute_step?(step_name, completed_steps)
|
228
|
-
end
|
229
|
-
|
230
|
-
# Get impact of forcing a step (what other steps might be affected)
|
231
|
-
def get_force_impact(step_name, completed_steps)
|
232
|
-
impact = {
|
233
|
-
step: step_name,
|
234
|
-
missing_dependencies: get_blocking_steps(step_name, completed_steps),
|
235
|
-
dependent_steps: get_dependent_steps(step_name),
|
236
|
-
risks: [],
|
237
|
-
recommendations: []
|
238
|
-
}
|
239
|
-
|
240
|
-
# Assess risks
|
241
|
-
missing_deps = impact[:missing_dependencies]
|
242
|
-
if missing_deps.any?
|
243
|
-
impact[:risks] << "Step may produce incomplete results due to missing dependencies: #{missing_deps.join(", ")}"
|
244
|
-
impact[:recommendations] << "Consider completing dependencies first for better results"
|
245
|
-
end
|
246
|
-
|
247
|
-
# Check if this step is a dependency for others
|
248
|
-
dependent_steps = impact[:dependent_steps]
|
249
|
-
if dependent_steps.any?
|
250
|
-
impact[:risks] << "Forcing this step may affect dependent steps: #{dependent_steps.join(", ")}"
|
251
|
-
impact[:recommendations] << "Review dependent steps after completion"
|
252
|
-
end
|
253
|
-
|
254
|
-
impact
|
255
|
-
end
|
256
|
-
|
257
|
-
private
|
258
|
-
|
259
|
-
def prioritize_steps(steps, completed_steps)
|
260
|
-
# Sort steps by priority (lower dependency depth first, then by step order)
|
261
|
-
steps.sort_by do |step|
|
262
|
-
[
|
263
|
-
get_dependency_depth(step),
|
264
|
-
get_step_priority(step),
|
265
|
-
Aidp::Analyze::Steps::SPEC.keys.index(step)
|
266
|
-
]
|
267
|
-
end
|
268
|
-
end
|
269
|
-
|
270
|
-
def get_dependency_depth(step)
|
271
|
-
dependencies = get_dependencies(step)
|
272
|
-
return 0 if dependencies.empty?
|
273
|
-
|
274
|
-
max_depth = 0
|
275
|
-
dependencies.each do |dep|
|
276
|
-
depth = get_dependency_depth(dep) + 1
|
277
|
-
max_depth = [max_depth, depth].max
|
278
|
-
end
|
279
|
-
|
280
|
-
max_depth
|
281
|
-
end
|
282
|
-
|
283
|
-
def get_step_priority(step)
|
284
|
-
# Define step priorities (lower number = higher priority)
|
285
|
-
priorities = {
|
286
|
-
"repository" => 1,
|
287
|
-
"architecture" => 2,
|
288
|
-
"test-coverage" => 3,
|
289
|
-
"functionality" => 4,
|
290
|
-
"documentation" => 5,
|
291
|
-
"static-analysis" => 6,
|
292
|
-
"refactoring" => 7
|
293
|
-
}
|
294
|
-
|
295
|
-
priorities[step] || 999
|
296
|
-
end
|
297
|
-
|
298
|
-
def data_available?(data_type)
|
299
|
-
# In a real implementation, this would check the database or other data stores
|
300
|
-
# For now, we'll assume data is available if the corresponding step is completed
|
301
|
-
case data_type
|
302
|
-
when "repository_metrics"
|
303
|
-
File.exist?(File.join(@project_dir, "docs/RepositoryAnalysis.md"))
|
304
|
-
when "architecture_patterns"
|
305
|
-
File.exist?(File.join(@project_dir, "docs/ArchitectureAnalysis.md"))
|
306
|
-
when "feature_map"
|
307
|
-
File.exist?(File.join(@project_dir, "docs/FunctionalityAnalysis.md"))
|
308
|
-
when "static_analysis_results"
|
309
|
-
File.exist?(File.join(@project_dir, "docs/StaticAnalysisReport.md"))
|
310
|
-
else
|
311
|
-
true # Assume available for unknown data types
|
312
|
-
end
|
313
|
-
end
|
314
|
-
|
315
|
-
def generate_recommendations(plan)
|
316
|
-
recommendations = []
|
317
|
-
|
318
|
-
if plan[:next_steps].any?
|
319
|
-
next_step = plan[:next_steps].first
|
320
|
-
recommendations << "Recommended next step: #{next_step}"
|
321
|
-
end
|
322
|
-
|
323
|
-
if plan[:blocked_steps].any?
|
324
|
-
blocked_step = plan[:blocked_steps].first
|
325
|
-
blocking_steps = get_blocking_steps(blocked_step, plan[:completed])
|
326
|
-
recommendations << "Step '#{blocked_step}' is blocked by: #{blocking_steps.join(", ")}"
|
327
|
-
end
|
328
|
-
|
329
|
-
recommendations << "Start with repository analysis to establish baseline" if plan[:completed].empty?
|
330
|
-
|
331
|
-
recommendations
|
332
|
-
end
|
333
|
-
end
|
334
|
-
end
|
335
|
-
end
|