aidp 0.1.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 (79) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/README.md +210 -0
  4. data/bin/aidp +5 -0
  5. data/lib/aidp/analyze/agent_personas.rb +71 -0
  6. data/lib/aidp/analyze/agent_tool_executor.rb +445 -0
  7. data/lib/aidp/analyze/data_retention_manager.rb +426 -0
  8. data/lib/aidp/analyze/database.rb +243 -0
  9. data/lib/aidp/analyze/dependencies.rb +335 -0
  10. data/lib/aidp/analyze/error_handler.rb +486 -0
  11. data/lib/aidp/analyze/export_manager.rb +425 -0
  12. data/lib/aidp/analyze/feature_analyzer.rb +397 -0
  13. data/lib/aidp/analyze/focus_guidance.rb +517 -0
  14. data/lib/aidp/analyze/incremental_analyzer.rb +543 -0
  15. data/lib/aidp/analyze/language_analysis_strategies.rb +897 -0
  16. data/lib/aidp/analyze/large_analysis_progress.rb +504 -0
  17. data/lib/aidp/analyze/memory_manager.rb +365 -0
  18. data/lib/aidp/analyze/parallel_processor.rb +460 -0
  19. data/lib/aidp/analyze/performance_optimizer.rb +694 -0
  20. data/lib/aidp/analyze/prioritizer.rb +402 -0
  21. data/lib/aidp/analyze/progress.rb +75 -0
  22. data/lib/aidp/analyze/progress_visualizer.rb +320 -0
  23. data/lib/aidp/analyze/report_generator.rb +582 -0
  24. data/lib/aidp/analyze/repository_chunker.rb +702 -0
  25. data/lib/aidp/analyze/ruby_maat_integration.rb +572 -0
  26. data/lib/aidp/analyze/runner.rb +245 -0
  27. data/lib/aidp/analyze/static_analysis_detector.rb +577 -0
  28. data/lib/aidp/analyze/steps.rb +53 -0
  29. data/lib/aidp/analyze/storage.rb +600 -0
  30. data/lib/aidp/analyze/tool_configuration.rb +456 -0
  31. data/lib/aidp/analyze/tool_modernization.rb +750 -0
  32. data/lib/aidp/execute/progress.rb +76 -0
  33. data/lib/aidp/execute/runner.rb +135 -0
  34. data/lib/aidp/execute/steps.rb +113 -0
  35. data/lib/aidp/shared/cli.rb +117 -0
  36. data/lib/aidp/shared/config.rb +35 -0
  37. data/lib/aidp/shared/project_detector.rb +119 -0
  38. data/lib/aidp/shared/providers/anthropic.rb +26 -0
  39. data/lib/aidp/shared/providers/base.rb +17 -0
  40. data/lib/aidp/shared/providers/cursor.rb +102 -0
  41. data/lib/aidp/shared/providers/gemini.rb +26 -0
  42. data/lib/aidp/shared/providers/macos_ui.rb +26 -0
  43. data/lib/aidp/shared/sync.rb +15 -0
  44. data/lib/aidp/shared/util.rb +41 -0
  45. data/lib/aidp/shared/version.rb +7 -0
  46. data/lib/aidp/shared/workspace.rb +21 -0
  47. data/lib/aidp.rb +53 -0
  48. data/templates/ANALYZE/01_REPOSITORY_ANALYSIS.md +100 -0
  49. data/templates/ANALYZE/02_ARCHITECTURE_ANALYSIS.md +151 -0
  50. data/templates/ANALYZE/03_TEST_ANALYSIS.md +182 -0
  51. data/templates/ANALYZE/04_FUNCTIONALITY_ANALYSIS.md +200 -0
  52. data/templates/ANALYZE/05_DOCUMENTATION_ANALYSIS.md +202 -0
  53. data/templates/ANALYZE/06_STATIC_ANALYSIS.md +233 -0
  54. data/templates/ANALYZE/07_REFACTORING_RECOMMENDATIONS.md +316 -0
  55. data/templates/COMMON/AGENT_BASE.md +129 -0
  56. data/templates/COMMON/CONVENTIONS.md +19 -0
  57. data/templates/COMMON/TEMPLATES/ADR_TEMPLATE.md +21 -0
  58. data/templates/COMMON/TEMPLATES/DOMAIN_CHARTER.md +27 -0
  59. data/templates/COMMON/TEMPLATES/EVENT_EXAMPLE.yaml +16 -0
  60. data/templates/COMMON/TEMPLATES/MERMAID_C4.md +46 -0
  61. data/templates/COMMON/TEMPLATES/OPENAPI_STUB.yaml +11 -0
  62. data/templates/EXECUTE/00_PRD.md +36 -0
  63. data/templates/EXECUTE/01_NFRS.md +27 -0
  64. data/templates/EXECUTE/02A_ARCH_GATE_QUESTIONS.md +13 -0
  65. data/templates/EXECUTE/02_ARCHITECTURE.md +42 -0
  66. data/templates/EXECUTE/03_ADR_FACTORY.md +22 -0
  67. data/templates/EXECUTE/04_DOMAIN_DECOMPOSITION.md +24 -0
  68. data/templates/EXECUTE/05_CONTRACTS.md +27 -0
  69. data/templates/EXECUTE/06_THREAT_MODEL.md +23 -0
  70. data/templates/EXECUTE/07_TEST_PLAN.md +24 -0
  71. data/templates/EXECUTE/08_TASKS.md +29 -0
  72. data/templates/EXECUTE/09_SCAFFOLDING_DEVEX.md +25 -0
  73. data/templates/EXECUTE/10_IMPLEMENTATION_AGENT.md +30 -0
  74. data/templates/EXECUTE/11_STATIC_ANALYSIS.md +22 -0
  75. data/templates/EXECUTE/12_OBSERVABILITY_SLOS.md +21 -0
  76. data/templates/EXECUTE/13_DELIVERY_ROLLOUT.md +21 -0
  77. data/templates/EXECUTE/14_DOCS_PORTAL.md +23 -0
  78. data/templates/EXECUTE/15_POST_RELEASE.md +25 -0
  79. metadata +301 -0
@@ -0,0 +1,402 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "ruby_maat_integration"
4
+ require_relative "feature_analyzer"
5
+
6
+ module Aidp
7
+ module Analyze
8
+ class Prioritizer
9
+ def initialize(project_dir = Dir.pwd)
10
+ @project_dir = project_dir
11
+ @code_maat = Aidp::Analyze::RubyMaatIntegration.new(project_dir)
12
+ @feature_analyzer = Aidp::Analyze::FeatureAnalyzer.new(project_dir)
13
+ end
14
+
15
+ # Generate prioritized analysis recommendations based on Code Maat data
16
+ def generate_prioritized_recommendations
17
+ # Get Code Maat analysis data
18
+ code_maat_data = @code_maat.run_comprehensive_analysis
19
+
20
+ # Get feature analysis data
21
+ features = @feature_analyzer.detect_features
22
+
23
+ # Generate prioritized recommendations
24
+ {
25
+ high_priority: generate_high_priority_recommendations(code_maat_data, features),
26
+ medium_priority: generate_medium_priority_recommendations(code_maat_data, features),
27
+ low_priority: generate_low_priority_recommendations(code_maat_data, features),
28
+ focus_areas: identify_focus_areas(code_maat_data, features),
29
+ analysis_strategy: generate_analysis_strategy(code_maat_data, features)
30
+ }
31
+ end
32
+
33
+ # Get high-priority analysis targets
34
+ def get_high_priority_targets
35
+ @code_maat.run_comprehensive_analysis
36
+
37
+ high_priority = []
38
+
39
+ # High churn + single author (knowledge silos)
40
+ high_churn_files = @code_maat.get_high_churn_files(10)
41
+ knowledge_silos = @code_maat.get_knowledge_silos
42
+
43
+ high_churn_files.each do |churn_file|
44
+ silo_file = knowledge_silos.find { |s| s[:file] == churn_file[:file] }
45
+ next unless silo_file
46
+
47
+ high_priority << {
48
+ type: "knowledge_silo",
49
+ file: churn_file[:file],
50
+ changes: churn_file[:changes],
51
+ author: silo_file[:authors].first,
52
+ priority_score: calculate_priority_score(churn_file, silo_file),
53
+ recommendation: "High churn file with single author - potential knowledge silo"
54
+ }
55
+ end
56
+
57
+ # Tightly coupled files
58
+ tightly_coupled = @code_maat.get_tightly_coupled_files(5)
59
+ tightly_coupled.each do |coupling|
60
+ high_priority << {
61
+ type: "tight_coupling",
62
+ file1: coupling[:file1],
63
+ file2: coupling[:file2],
64
+ shared_changes: coupling[:shared_changes],
65
+ priority_score: coupling[:shared_changes] * 2,
66
+ recommendation: "Tightly coupled files - consider refactoring to reduce coupling"
67
+ }
68
+ end
69
+
70
+ high_priority.sort_by { |item| -item[:priority_score] }
71
+ end
72
+
73
+ # Get medium-priority analysis targets
74
+ def get_medium_priority_targets
75
+ code_maat_data = @code_maat.run_comprehensive_analysis
76
+
77
+ medium_priority = []
78
+
79
+ # High churn + multiple authors (coordination issues)
80
+ high_churn_files = @code_maat.get_high_churn_files(5)
81
+ multi_author_files = code_maat_data[:authorship][:files].select { |f| f[:author_count] > 1 }
82
+
83
+ high_churn_files.each do |churn_file|
84
+ multi_auth_file = multi_author_files.find { |m| m[:file] == churn_file[:file] }
85
+ next unless multi_auth_file
86
+
87
+ medium_priority << {
88
+ type: "coordination_issue",
89
+ file: churn_file[:file],
90
+ changes: churn_file[:changes],
91
+ authors: multi_auth_file[:authors],
92
+ priority_score: calculate_priority_score(churn_file, multi_auth_file),
93
+ recommendation: "High churn file with multiple authors - potential coordination issues"
94
+ }
95
+ end
96
+
97
+ # Medium churn files
98
+ medium_churn_files = code_maat_data[:churn][:files].select { |f| f[:changes] > 3 && f[:changes] <= 10 }
99
+ medium_churn_files.each do |file|
100
+ medium_priority << {
101
+ type: "medium_churn",
102
+ file: file[:file],
103
+ changes: file[:changes],
104
+ priority_score: file[:changes],
105
+ recommendation: "Medium churn file - monitor for increasing complexity"
106
+ }
107
+ end
108
+
109
+ medium_priority.sort_by { |item| -item[:priority_score] }
110
+ end
111
+
112
+ # Get low-priority analysis targets
113
+ def get_low_priority_targets
114
+ code_maat_data = @code_maat.run_comprehensive_analysis
115
+
116
+ low_priority = []
117
+
118
+ # Low churn files
119
+ low_churn_files = code_maat_data[:churn][:files].select { |f| f[:changes] <= 3 }
120
+ low_churn_files.each do |file|
121
+ low_priority << {
122
+ type: "low_churn",
123
+ file: file[:file],
124
+ changes: file[:changes],
125
+ priority_score: file[:changes],
126
+ recommendation: "Low churn file - stable, may not need immediate attention"
127
+ }
128
+ end
129
+
130
+ low_priority.sort_by { |item| -item[:priority_score] }
131
+ end
132
+
133
+ # Identify focus areas for analysis
134
+ def identify_focus_areas
135
+ @code_maat.run_comprehensive_analysis
136
+ @feature_analyzer.detect_features
137
+
138
+ focus_areas = []
139
+
140
+ # High churn areas
141
+ high_churn_files = @code_maat.get_high_churn_files(8)
142
+ high_churn_areas = group_files_by_directory(high_churn_files.map { |f| f[:file] })
143
+
144
+ high_churn_areas.each do |area, files|
145
+ focus_areas << {
146
+ type: "high_churn_area",
147
+ area: area,
148
+ files: files,
149
+ priority: "high",
150
+ recommendation: "High churn area - focus analysis on #{area} directory"
151
+ }
152
+ end
153
+
154
+ # Knowledge silo areas
155
+ knowledge_silos = @code_maat.get_knowledge_silos
156
+ silo_areas = group_files_by_directory(knowledge_silos.map { |f| f[:file] })
157
+
158
+ silo_areas.each do |area, files|
159
+ focus_areas << {
160
+ type: "knowledge_silo_area",
161
+ area: area,
162
+ files: files,
163
+ priority: "high",
164
+ recommendation: "Knowledge silo area - #{area} has single-author files"
165
+ }
166
+ end
167
+
168
+ # Coupling hotspots
169
+ tightly_coupled = @code_maat.get_tightly_coupled_files(3)
170
+ coupling_areas = identify_coupling_hotspots(tightly_coupled)
171
+
172
+ coupling_areas.each do |area, couplings|
173
+ focus_areas << {
174
+ type: "coupling_hotspot",
175
+ area: area,
176
+ couplings: couplings,
177
+ priority: "medium",
178
+ recommendation: "Coupling hotspot - #{area} has tightly coupled files"
179
+ }
180
+ end
181
+
182
+ focus_areas
183
+ end
184
+
185
+ # Generate analysis strategy recommendations
186
+ def generate_analysis_strategy
187
+ code_maat_data = @code_maat.run_comprehensive_analysis
188
+ @feature_analyzer.detect_features
189
+
190
+ {
191
+ overall_approach: determine_overall_approach(code_maat_data),
192
+ analysis_order: determine_analysis_order(code_maat_data),
193
+ resource_allocation: determine_resource_allocation(code_maat_data),
194
+ risk_assessment: assess_analysis_risks(code_maat_data),
195
+ success_metrics: define_success_metrics(code_maat_data)
196
+ }
197
+ end
198
+
199
+ private
200
+
201
+ def generate_high_priority_recommendations(code_maat_data, features)
202
+ recommendations = []
203
+
204
+ # Knowledge silos
205
+ knowledge_silos = @code_maat.get_knowledge_silos
206
+ knowledge_silos.each do |silo|
207
+ recommendations << {
208
+ type: "knowledge_silo",
209
+ target: silo[:file],
210
+ priority: "high",
211
+ rationale: "Single author with #{silo[:changes]} changes",
212
+ action: "Document knowledge and consider pair programming",
213
+ effort: "medium",
214
+ impact: "high"
215
+ }
216
+ end
217
+
218
+ # Tight coupling
219
+ tightly_coupled = @code_maat.get_tightly_coupled_files(5)
220
+ tightly_coupled.each do |coupling|
221
+ recommendations << {
222
+ type: "tight_coupling",
223
+ target: "#{coupling[:file1]} ↔ #{coupling[:file2]}",
224
+ priority: "high",
225
+ rationale: "#{coupling[:shared_changes]} shared changes",
226
+ action: "Refactor to reduce coupling",
227
+ effort: "high",
228
+ impact: "high"
229
+ }
230
+ end
231
+
232
+ recommendations
233
+ end
234
+
235
+ def generate_medium_priority_recommendations(code_maat_data, features)
236
+ recommendations = []
237
+
238
+ # High churn with multiple authors
239
+ high_churn_multi_author = code_maat_data[:churn][:files].select do |file|
240
+ file[:changes] > 5 &&
241
+ (code_maat_data[:authorship][:files].find { |a| a[:file] == file[:file] }&.dig(:author_count)&.> 1)
242
+ end
243
+
244
+ high_churn_multi_author.each do |file|
245
+ recommendations << {
246
+ type: "coordination_issue",
247
+ target: file[:file],
248
+ priority: "medium",
249
+ rationale: "High churn (#{file[:changes]} changes) with multiple authors",
250
+ action: "Improve coordination and communication",
251
+ effort: "medium",
252
+ impact: "medium"
253
+ }
254
+ end
255
+
256
+ recommendations
257
+ end
258
+
259
+ def generate_low_priority_recommendations(code_maat_data, features)
260
+ recommendations = []
261
+
262
+ # Stable files
263
+ stable_files = code_maat_data[:churn][:files].select { |f| f[:changes] <= 2 }
264
+ stable_files.each do |file|
265
+ recommendations << {
266
+ type: "stable_file",
267
+ target: file[:file],
268
+ priority: "low",
269
+ rationale: "Low churn (#{file[:changes]} changes) - stable",
270
+ action: "Monitor for changes",
271
+ effort: "low",
272
+ impact: "low"
273
+ }
274
+ end
275
+
276
+ recommendations
277
+ end
278
+
279
+ def calculate_priority_score(churn_file, authorship_file)
280
+ base_score = churn_file[:changes]
281
+
282
+ # Adjust for authorship patterns
283
+ if authorship_file[:author_count] == 1
284
+ base_score *= 1.5 # Knowledge silo penalty
285
+ elsif authorship_file[:author_count] > 3
286
+ base_score *= 1.2 # Coordination complexity penalty
287
+ end
288
+
289
+ base_score
290
+ end
291
+
292
+ def group_files_by_directory(files)
293
+ grouped = {}
294
+
295
+ files.each do |file|
296
+ dir = File.dirname(file)
297
+ grouped[dir] ||= []
298
+ grouped[dir] << file
299
+ end
300
+
301
+ grouped
302
+ end
303
+
304
+ def identify_coupling_hotspots(couplings)
305
+ hotspots = {}
306
+
307
+ couplings.each do |coupling|
308
+ dir1 = File.dirname(coupling[:file1])
309
+ dir2 = File.dirname(coupling[:file2])
310
+
311
+ # Group by common directory or create cross-directory coupling
312
+ if dir1 == dir2
313
+ hotspots[dir1] ||= []
314
+ hotspots[dir1] << coupling
315
+ else
316
+ cross_dir = "#{dir1} ↔ #{dir2}"
317
+ hotspots[cross_dir] ||= []
318
+ hotspots[cross_dir] << coupling
319
+ end
320
+ end
321
+
322
+ hotspots
323
+ end
324
+
325
+ def determine_overall_approach(code_maat_data)
326
+ total_files = code_maat_data[:churn][:total_files]
327
+ high_churn_count = code_maat_data[:churn][:files].count { |f| f[:changes] > 10 }
328
+ knowledge_silos = code_maat_data[:authorship][:files_with_single_author]
329
+
330
+ if high_churn_count > total_files * 0.3
331
+ "aggressive_refactoring"
332
+ elsif knowledge_silos > total_files * 0.2
333
+ "knowledge_transfer_focused"
334
+ elsif code_maat_data[:coupling][:average_coupling] > 5
335
+ "coupling_reduction_focused"
336
+ else
337
+ "incremental_improvement"
338
+ end
339
+ end
340
+
341
+ def determine_analysis_order(code_maat_data)
342
+ order = []
343
+
344
+ # Start with highest impact areas
345
+ order << "knowledge_silos" if code_maat_data[:authorship][:files_with_single_author] > 0
346
+
347
+ order << "coupling_analysis" if code_maat_data[:coupling][:average_coupling] > 3
348
+
349
+ order << "high_churn_analysis" if code_maat_data[:churn][:files].any? { |f| f[:changes] > 15 }
350
+
351
+ order << "general_quality_analysis"
352
+ order
353
+ end
354
+
355
+ def determine_resource_allocation(code_maat_data)
356
+ total_files = code_maat_data[:churn][:total_files]
357
+
358
+ {
359
+ high_priority_percentage: 20,
360
+ medium_priority_percentage: 50,
361
+ low_priority_percentage: 30,
362
+ estimated_effort_hours: total_files * 0.5,
363
+ recommended_team_size: [total_files / 50, 1].max
364
+ }
365
+ end
366
+
367
+ def assess_analysis_risks(code_maat_data)
368
+ risks = []
369
+
370
+ if code_maat_data[:authorship][:files_with_single_author] > code_maat_data[:churn][:total_files] * 0.3
371
+ risks << {
372
+ type: "knowledge_silo_risk",
373
+ severity: "high",
374
+ description: "High percentage of single-author files indicates knowledge silos",
375
+ mitigation: "Implement knowledge sharing and documentation practices"
376
+ }
377
+ end
378
+
379
+ if code_maat_data[:coupling][:average_coupling] > 8
380
+ risks << {
381
+ type: "coupling_risk",
382
+ severity: "medium",
383
+ description: "High average coupling indicates tight dependencies",
384
+ mitigation: "Focus on reducing coupling through refactoring"
385
+ }
386
+ end
387
+
388
+ risks
389
+ end
390
+
391
+ def define_success_metrics(code_maat_data)
392
+ {
393
+ knowledge_silo_reduction: "Reduce single-author files by 50%",
394
+ coupling_reduction: "Reduce average coupling by 30%",
395
+ churn_stabilization: "Reduce high-churn files by 25%",
396
+ documentation_coverage: "Achieve 80% documentation coverage",
397
+ test_coverage: "Achieve 90% test coverage"
398
+ }
399
+ end
400
+ end
401
+ end
402
+ end
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "yaml"
4
+ require "time"
5
+
6
+ module Aidp
7
+ module Analyze
8
+ # Manages progress tracking for analyze mode, isolated from execute mode
9
+ class Progress
10
+ attr_reader :project_dir, :progress_file
11
+
12
+ def initialize(project_dir)
13
+ @project_dir = project_dir
14
+ @progress_file = File.join(project_dir, ".aidp-analyze-progress.yml")
15
+ load_progress
16
+ end
17
+
18
+ def completed_steps
19
+ @progress["completed_steps"] || []
20
+ end
21
+
22
+ def current_step
23
+ @progress["current_step"]
24
+ end
25
+
26
+ def started_at
27
+ @progress["started_at"] ? Time.parse(@progress["started_at"]) : nil
28
+ end
29
+
30
+ def step_completed?(step_name)
31
+ completed_steps.include?(step_name)
32
+ end
33
+
34
+ def mark_step_completed(step_name)
35
+ @progress["completed_steps"] ||= []
36
+ @progress["completed_steps"] << step_name unless step_completed?(step_name)
37
+ @progress["current_step"] = nil
38
+ save_progress
39
+ end
40
+
41
+ def mark_step_in_progress(step_name)
42
+ @progress["current_step"] = step_name
43
+ @progress["started_at"] ||= Time.now.iso8601
44
+ save_progress
45
+ end
46
+
47
+ def reset
48
+ @progress = {
49
+ "completed_steps" => [],
50
+ "current_step" => nil,
51
+ "started_at" => nil
52
+ }
53
+ save_progress
54
+ end
55
+
56
+ def next_step
57
+ Aidp::Analyze::Steps::SPEC.keys.find { |step| !step_completed?(step) }
58
+ end
59
+
60
+ private
61
+
62
+ def load_progress
63
+ @progress = if File.exist?(@progress_file)
64
+ YAML.load_file(@progress_file) || {}
65
+ else
66
+ {}
67
+ end
68
+ end
69
+
70
+ def save_progress
71
+ File.write(@progress_file, @progress.to_yaml)
72
+ end
73
+ end
74
+ end
75
+ end