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,456 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "yaml"
4
+ require "json"
5
+ require "fileutils"
6
+
7
+ module Aidp
8
+ class ToolConfiguration
9
+ # Default configuration file names
10
+ USER_CONFIG_FILE = File.expand_path("~/.aidp-tools.yml")
11
+ PROJECT_CONFIG_FILE = ".aidp-tools.yml"
12
+
13
+ # Default preferred tools by language
14
+ DEFAULT_PREFERRED_TOOLS = {
15
+ "ruby" => {
16
+ "style" => "rubocop",
17
+ "security" => "brakeman",
18
+ "dependencies" => "bundler-audit",
19
+ "quality" => "reek",
20
+ "performance" => "fasterer"
21
+ },
22
+ "javascript" => {
23
+ "style" => "eslint",
24
+ "formatting" => "prettier",
25
+ "security" => "npm-audit",
26
+ "quality" => "eslint"
27
+ },
28
+ "python" => {
29
+ "style" => "flake8",
30
+ "security" => "bandit",
31
+ "quality" => "pylint"
32
+ },
33
+ "java" => {
34
+ "style" => "checkstyle",
35
+ "quality" => "pmd",
36
+ "security" => "spotbugs"
37
+ },
38
+ "go" => {
39
+ "style" => "golangci-lint",
40
+ "security" => "gosec",
41
+ "quality" => "golangci-lint"
42
+ },
43
+ "rust" => {
44
+ "style" => "clippy",
45
+ "security" => "cargo-audit",
46
+ "quality" => "clippy"
47
+ }
48
+ }.freeze
49
+
50
+ def initialize(project_dir = Dir.pwd)
51
+ @project_dir = project_dir
52
+ @user_config = load_user_config
53
+ @project_config = load_project_config
54
+ end
55
+
56
+ # Get preferred tools for a specific language and category
57
+ def get_preferred_tools(language, category = nil)
58
+ # Priority: project config > user config > defaults
59
+ project_tools = @project_config.dig("preferred_tools", language) || {}
60
+ user_tools = @user_config.dig("preferred_tools", language) || {}
61
+ default_tools = DEFAULT_PREFERRED_TOOLS[language] || {}
62
+
63
+ if category
64
+ project_tools[category] || user_tools[category] || default_tools[category]
65
+ else
66
+ # Merge all configurations with project taking precedence
67
+ default_tools.merge(user_tools).merge(project_tools)
68
+
69
+ end
70
+ end
71
+
72
+ # Get all preferred tools for a language
73
+ def get_all_preferred_tools(language)
74
+ get_preferred_tools(language)
75
+ end
76
+
77
+ # Set preferred tool for a language and category
78
+ def set_preferred_tool(language, category, tool_name, scope = :project)
79
+ case scope
80
+ when :project
81
+ set_project_preferred_tool(language, category, tool_name)
82
+ when :user
83
+ set_user_preferred_tool(language, category, tool_name)
84
+ else
85
+ raise ArgumentError, "Invalid scope: #{scope}. Use :project or :user"
86
+ end
87
+ end
88
+
89
+ # Get tool configuration (settings, options, etc.)
90
+ def get_tool_config(tool_name, language = nil)
91
+ # Priority: project config > user config > defaults
92
+ project_tool_config = @project_config.dig("tool_configs", tool_name) || {}
93
+ user_tool_config = @user_config.dig("tool_configs", tool_name) || {}
94
+
95
+ merged_config = user_tool_config.merge(project_tool_config)
96
+
97
+ # Add language-specific defaults if available
98
+ if language && DEFAULT_PREFERRED_TOOLS[language]
99
+ end
100
+ merged_config
101
+ end
102
+
103
+ # Set tool configuration
104
+ def set_tool_config(tool_name, config, scope = :project)
105
+ case scope
106
+ when :project
107
+ set_project_tool_config(tool_name, config)
108
+ when :user
109
+ set_user_tool_config(tool_name, config)
110
+ else
111
+ raise ArgumentError, "Invalid scope: #{scope}. Use :project or :user"
112
+ end
113
+ end
114
+
115
+ # Get execution settings (timeout, parallel execution, etc.)
116
+ def get_execution_settings
117
+ # Priority: project config > user config > defaults
118
+ project_settings = @project_config["execution_settings"] || {}
119
+ user_settings = @user_config["execution_settings"] || {}
120
+
121
+ default_settings = {
122
+ "timeout" => 300, # 5 minutes
123
+ "parallel_execution" => true,
124
+ "max_parallel_jobs" => 4,
125
+ "retry_failed" => true,
126
+ "max_retries" => 2
127
+ }
128
+
129
+ default_settings.merge(user_settings).merge(project_settings)
130
+ end
131
+
132
+ # Set execution settings
133
+ def set_execution_settings(settings, scope = :project)
134
+ case scope
135
+ when :project
136
+ set_project_execution_settings(settings)
137
+ when :user
138
+ set_user_execution_settings(settings)
139
+ else
140
+ raise ArgumentError, "Invalid scope: #{scope}. Use :project or :user"
141
+ end
142
+ end
143
+
144
+ # Get tool execution order for a language
145
+ def get_tool_execution_order(language)
146
+ # Priority: project config > user config > defaults
147
+ project_order = @project_config.dig("execution_order", language) || []
148
+ user_order = @user_config.dig("execution_order", language) || []
149
+
150
+ if project_order.any?
151
+ project_order
152
+ elsif user_order.any?
153
+ user_order
154
+ else
155
+ # Default order based on tool categories
156
+ default_order = []
157
+ tools = get_preferred_tools(language)
158
+
159
+ # Order by category priority
160
+ category_priority = %w[security dependencies quality style formatting performance]
161
+ category_priority.each do |category|
162
+ default_order << tools[category] if tools[category]
163
+ end
164
+
165
+ default_order
166
+ end
167
+ end
168
+
169
+ # Set tool execution order for a language
170
+ def set_tool_execution_order(language, order, scope = :project)
171
+ case scope
172
+ when :project
173
+ set_project_execution_order(language, order)
174
+ when :user
175
+ set_user_execution_order(language, order)
176
+ else
177
+ raise ArgumentError, "Invalid scope: #{scope}. Use :project or :user"
178
+ end
179
+ end
180
+
181
+ # Get tool integration settings (CI/CD, IDE integration, etc.)
182
+ def get_integration_settings
183
+ project_integrations = @project_config["integrations"] || {}
184
+ user_integrations = @user_config["integrations"] || {}
185
+
186
+ default_integrations = {
187
+ "ci_cd" => {
188
+ "enabled" => true,
189
+ "fail_on_errors" => true,
190
+ "fail_on_warnings" => false
191
+ },
192
+ "ide" => {
193
+ "enabled" => true,
194
+ "auto_fix" => false,
195
+ "show_warnings" => true
196
+ },
197
+ "git_hooks" => {
198
+ "enabled" => false,
199
+ "pre_commit" => false,
200
+ "pre_push" => false
201
+ }
202
+ }
203
+
204
+ default_integrations.merge(user_integrations).merge(project_integrations)
205
+ end
206
+
207
+ # Set integration settings
208
+ def set_integration_settings(integrations, scope = :project)
209
+ case scope
210
+ when :project
211
+ set_project_integration_settings(integrations)
212
+ when :user
213
+ set_user_integration_settings(integrations)
214
+ else
215
+ raise ArgumentError, "Invalid scope: #{scope}. Use :project or :user"
216
+ end
217
+ end
218
+
219
+ # Initialize default configuration files
220
+ def initialize_config_files
221
+ initialize_user_config unless File.exist?(USER_CONFIG_FILE)
222
+ initialize_project_config unless File.exist?(project_config_path)
223
+ end
224
+
225
+ # Export configuration to different formats
226
+ def export_config(format = :yaml, scope = :project)
227
+ config_data = case scope
228
+ when :project
229
+ @project_config
230
+ when :user
231
+ @user_config
232
+ when :merged
233
+ merge_configurations
234
+ else
235
+ raise ArgumentError, "Invalid scope: #{scope}"
236
+ end
237
+
238
+ case format
239
+ when :yaml
240
+ config_data.to_yaml
241
+ when :json
242
+ config_data.to_json
243
+ when :ruby
244
+ config_data.inspect
245
+ else
246
+ raise ArgumentError, "Invalid format: #{format}"
247
+ end
248
+ end
249
+
250
+ # Import configuration from file
251
+ def import_config(file_path, scope = :project)
252
+ return false unless File.exist?(file_path)
253
+
254
+ begin
255
+ config_data = case File.extname(file_path)
256
+ when ".yml", ".yaml"
257
+ YAML.load_file(file_path)
258
+ when ".json"
259
+ JSON.parse(File.read(file_path))
260
+ else
261
+ raise ArgumentError, "Unsupported file format: #{File.extname(file_path)}"
262
+ end
263
+
264
+ case scope
265
+ when :project
266
+ @project_config = config_data
267
+ save_project_config
268
+ when :user
269
+ @user_config = config_data
270
+ save_user_config
271
+ else
272
+ raise ArgumentError, "Invalid scope: #{scope}"
273
+ end
274
+
275
+ true
276
+ rescue => e
277
+ warn "Failed to import configuration: #{e.message}"
278
+ false
279
+ end
280
+ end
281
+
282
+ # Validate configuration
283
+ def validate_config
284
+ errors = []
285
+
286
+ # Validate user config
287
+ errors.concat(validate_config_structure(@user_config, "user"))
288
+
289
+ # Validate project config
290
+ errors.concat(validate_config_structure(@project_config, "project"))
291
+
292
+ errors
293
+ end
294
+
295
+ private
296
+
297
+ def load_user_config
298
+ return {} unless File.exist?(USER_CONFIG_FILE)
299
+
300
+ begin
301
+ YAML.load_file(USER_CONFIG_FILE) || {}
302
+ rescue => e
303
+ warn "Failed to load user config: #{e.message}"
304
+ {}
305
+ end
306
+ end
307
+
308
+ def load_project_config
309
+ config_path = project_config_path
310
+ return {} unless File.exist?(config_path)
311
+
312
+ begin
313
+ YAML.load_file(config_path) || {}
314
+ rescue => e
315
+ warn "Failed to load project config: #{e.message}"
316
+ {}
317
+ end
318
+ end
319
+
320
+ def project_config_path
321
+ File.join(@project_dir, PROJECT_CONFIG_FILE)
322
+ end
323
+
324
+ def set_project_preferred_tool(language, category, tool_name)
325
+ @project_config["preferred_tools"] ||= {}
326
+ @project_config["preferred_tools"][language] ||= {}
327
+ @project_config["preferred_tools"][language][category] = tool_name
328
+ save_project_config
329
+ end
330
+
331
+ def set_user_preferred_tool(language, category, tool_name)
332
+ @user_config["preferred_tools"] ||= {}
333
+ @user_config["preferred_tools"][language] ||= {}
334
+ @user_config["preferred_tools"][language][category] = tool_name
335
+ save_user_config
336
+ end
337
+
338
+ def set_project_tool_config(tool_name, config)
339
+ @project_config["tool_configs"] ||= {}
340
+ @project_config["tool_configs"][tool_name] = config
341
+ save_project_config
342
+ end
343
+
344
+ def set_user_tool_config(tool_name, config)
345
+ @user_config["tool_configs"] ||= {}
346
+ @user_config["tool_configs"][tool_name] = config
347
+ save_user_config
348
+ end
349
+
350
+ def set_project_execution_settings(settings)
351
+ @project_config["execution_settings"] = settings
352
+ save_project_config
353
+ end
354
+
355
+ def set_user_execution_settings(settings)
356
+ @user_config["execution_settings"] = settings
357
+ save_user_config
358
+ end
359
+
360
+ def set_project_execution_order(language, order)
361
+ @project_config["execution_order"] ||= {}
362
+ @project_config["execution_order"][language] = order
363
+ save_project_config
364
+ end
365
+
366
+ def set_user_execution_order(language, order)
367
+ @user_config["execution_order"] ||= {}
368
+ @user_config["execution_order"][language] = order
369
+ save_user_config
370
+ end
371
+
372
+ def set_project_integration_settings(integrations)
373
+ @project_config["integrations"] = integrations
374
+ save_project_config
375
+ end
376
+
377
+ def set_user_integration_settings(integrations)
378
+ @user_config["integrations"] = integrations
379
+ save_user_config
380
+ end
381
+
382
+ def save_user_config
383
+ FileUtils.mkdir_p(File.dirname(USER_CONFIG_FILE))
384
+ File.write(USER_CONFIG_FILE, @user_config.to_yaml)
385
+ end
386
+
387
+ def save_project_config
388
+ File.write(project_config_path, @project_config.to_yaml)
389
+ end
390
+
391
+ def initialize_user_config
392
+ default_user_config = {
393
+ "preferred_tools" => DEFAULT_PREFERRED_TOOLS,
394
+ "execution_settings" => {
395
+ "timeout" => 300,
396
+ "parallel_execution" => true,
397
+ "max_parallel_jobs" => 4
398
+ },
399
+ "integrations" => {
400
+ "ci_cd" => {"enabled" => true},
401
+ "ide" => {"enabled" => true}
402
+ }
403
+ }
404
+
405
+ @user_config = default_user_config
406
+ save_user_config
407
+ end
408
+
409
+ def initialize_project_config
410
+ default_project_config = {
411
+ "preferred_tools" => {},
412
+ "execution_settings" => {},
413
+ "integrations" => {}
414
+ }
415
+
416
+ @project_config = default_project_config
417
+ save_project_config
418
+ end
419
+
420
+ def merge_configurations
421
+ merged = @user_config.dup
422
+
423
+ # Merge project config with user config
424
+ @project_config.each do |key, value|
425
+ merged[key] = if merged[key].is_a?(Hash) && value.is_a?(Hash)
426
+ merged[key].merge(value)
427
+ else
428
+ value
429
+ end
430
+ end
431
+
432
+ merged
433
+ end
434
+
435
+ def validate_config_structure(config, config_name)
436
+ errors = []
437
+
438
+ # Validate preferred_tools structure
439
+ if config["preferred_tools"] && !config["preferred_tools"].is_a?(Hash)
440
+ errors << "#{config_name} config: preferred_tools must be a hash"
441
+ end
442
+
443
+ # Validate execution_settings structure
444
+ if config["execution_settings"] && !config["execution_settings"].is_a?(Hash)
445
+ errors << "#{config_name} config: execution_settings must be a hash"
446
+ end
447
+
448
+ # Validate integrations structure
449
+ if config["integrations"] && !config["integrations"].is_a?(Hash)
450
+ errors << "#{config_name} config: integrations must be a hash"
451
+ end
452
+
453
+ errors
454
+ end
455
+ end
456
+ end