aidp 0.5.0 → 0.8.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/README.md +128 -151
- data/bin/aidp +1 -1
- data/lib/aidp/analysis/kb_inspector.rb +471 -0
- data/lib/aidp/analysis/seams.rb +159 -0
- data/lib/aidp/analysis/tree_sitter_grammar_loader.rb +480 -0
- data/lib/aidp/analysis/tree_sitter_scan.rb +686 -0
- data/lib/aidp/analyze/error_handler.rb +2 -78
- 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/analyze/steps.rb +6 -0
- data/lib/aidp/cli/jobs_command.rb +103 -435
- data/lib/aidp/cli.rb +317 -191
- 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 -109
- data/lib/aidp/providers/base.rb +170 -0
- data/lib/aidp/providers/cursor.rb +52 -183
- data/lib/aidp/providers/gemini.rb +24 -109
- 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 +56 -35
- data/templates/ANALYZE/06a_tree_sitter_scan.md +217 -0
- 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 +106 -64
- data/lib/aidp/analyze/agent_personas.rb +0 -71
- data/lib/aidp/analyze/agent_tool_executor.rb +0 -445
- data/lib/aidp/analyze/data_retention_manager.rb +0 -426
- data/lib/aidp/analyze/database.rb +0 -260
- data/lib/aidp/analyze/dependencies.rb +0 -335
- data/lib/aidp/analyze/export_manager.rb +0 -425
- data/lib/aidp/analyze/focus_guidance.rb +0 -517
- data/lib/aidp/analyze/incremental_analyzer.rb +0 -543
- data/lib/aidp/analyze/language_analysis_strategies.rb +0 -897
- data/lib/aidp/analyze/large_analysis_progress.rb +0 -504
- data/lib/aidp/analyze/memory_manager.rb +0 -365
- data/lib/aidp/analyze/metrics_storage.rb +0 -336
- data/lib/aidp/analyze/parallel_processor.rb +0 -460
- data/lib/aidp/analyze/performance_optimizer.rb +0 -694
- data/lib/aidp/analyze/repository_chunker.rb +0 -704
- data/lib/aidp/analyze/static_analysis_detector.rb +0 -577
- data/lib/aidp/analyze/storage.rb +0 -662
- data/lib/aidp/analyze/tool_configuration.rb +0 -456
- 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/database_migration.rb +0 -158
- data/lib/aidp/job_manager.rb +0 -41
- data/lib/aidp/jobs/base_job.rb +0 -47
- data/lib/aidp/jobs/provider_execution_job.rb +0 -96
- 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
@@ -0,0 +1,355 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "yaml"
|
4
|
+
require_relative "config_schema"
|
5
|
+
|
6
|
+
module Aidp
|
7
|
+
module Harness
|
8
|
+
# Configuration validator for harness
|
9
|
+
class ConfigValidator
|
10
|
+
def initialize(project_dir = Dir.pwd)
|
11
|
+
@project_dir = project_dir
|
12
|
+
@config_file = find_config_file
|
13
|
+
@config = nil
|
14
|
+
@validation_result = nil
|
15
|
+
end
|
16
|
+
|
17
|
+
# Load and validate configuration
|
18
|
+
def load_and_validate
|
19
|
+
unless @config_file
|
20
|
+
@validation_result = {
|
21
|
+
valid: false,
|
22
|
+
errors: ["No configuration file found"],
|
23
|
+
warnings: []
|
24
|
+
}
|
25
|
+
return @validation_result
|
26
|
+
end
|
27
|
+
|
28
|
+
load_config
|
29
|
+
validate_config
|
30
|
+
@validation_result
|
31
|
+
end
|
32
|
+
|
33
|
+
# Validate existing configuration
|
34
|
+
def validate_existing
|
35
|
+
return {valid: false, errors: ["No configuration file found"], warnings: []} unless @config_file
|
36
|
+
|
37
|
+
load_config
|
38
|
+
validate_config
|
39
|
+
@validation_result
|
40
|
+
end
|
41
|
+
|
42
|
+
# Get configuration with defaults applied
|
43
|
+
def get_validated_config
|
44
|
+
return nil unless @validation_result&.dig(:valid)
|
45
|
+
|
46
|
+
ConfigSchema.apply_defaults(@config)
|
47
|
+
end
|
48
|
+
|
49
|
+
# Check if configuration is valid
|
50
|
+
def valid?
|
51
|
+
@validation_result&.dig(:valid) || false
|
52
|
+
end
|
53
|
+
|
54
|
+
# Get validation errors
|
55
|
+
def errors
|
56
|
+
@validation_result&.dig(:errors) || []
|
57
|
+
end
|
58
|
+
|
59
|
+
# Get validation warnings
|
60
|
+
def warnings
|
61
|
+
@validation_result&.dig(:warnings) || []
|
62
|
+
end
|
63
|
+
|
64
|
+
# Get configuration file path
|
65
|
+
def config_file_path
|
66
|
+
@config_file
|
67
|
+
end
|
68
|
+
|
69
|
+
# Check if configuration file exists
|
70
|
+
def config_exists?
|
71
|
+
!@config_file.nil?
|
72
|
+
end
|
73
|
+
|
74
|
+
# Create example configuration file
|
75
|
+
def create_example_config
|
76
|
+
return false if config_exists?
|
77
|
+
|
78
|
+
example_config = ConfigSchema.generate_example
|
79
|
+
config_path = File.join(@project_dir, "aidp.yml")
|
80
|
+
|
81
|
+
File.write(config_path, YAML.dump(example_config))
|
82
|
+
true
|
83
|
+
end
|
84
|
+
|
85
|
+
# Fix common configuration issues
|
86
|
+
def fix_common_issues
|
87
|
+
return false unless @config_file && @config
|
88
|
+
|
89
|
+
original_config = @config.dup
|
90
|
+
|
91
|
+
# Fix string/symbol key inconsistencies
|
92
|
+
@config = normalize_keys(@config)
|
93
|
+
|
94
|
+
# Apply missing defaults
|
95
|
+
@config = ConfigSchema.apply_defaults(@config)
|
96
|
+
|
97
|
+
# Fix common validation issues
|
98
|
+
fix_validation_issues
|
99
|
+
|
100
|
+
# Check if any changes were made
|
101
|
+
if @config != original_config
|
102
|
+
# Write fixed configuration back to file
|
103
|
+
File.write(@config_file, YAML.dump(@config))
|
104
|
+
true
|
105
|
+
else
|
106
|
+
false
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
# Get configuration summary
|
111
|
+
def get_summary
|
112
|
+
return {error: "No configuration file found"} unless @config_file
|
113
|
+
|
114
|
+
load_config
|
115
|
+
summary = {
|
116
|
+
config_file: @config_file,
|
117
|
+
valid: valid?,
|
118
|
+
errors_count: errors.size,
|
119
|
+
warnings_count: warnings.size,
|
120
|
+
harness_configured: !(@config[:harness] || @config["harness"]).nil?,
|
121
|
+
providers_count: 0,
|
122
|
+
providers: []
|
123
|
+
}
|
124
|
+
|
125
|
+
providers_config = @config[:providers] || @config["providers"] || {}
|
126
|
+
summary[:providers_count] = providers_config.size
|
127
|
+
summary[:providers] = providers_config.keys.map(&:to_s)
|
128
|
+
|
129
|
+
summary
|
130
|
+
end
|
131
|
+
|
132
|
+
# Validate specific provider configuration
|
133
|
+
def validate_provider(provider_name)
|
134
|
+
return {valid: false, errors: ["No configuration file found"], warnings: []} unless @config_file
|
135
|
+
|
136
|
+
load_config
|
137
|
+
providers_config = @config[:providers] || @config["providers"] || {}
|
138
|
+
provider_config = providers_config[provider_name] || providers_config[provider_name.to_sym]
|
139
|
+
|
140
|
+
return {valid: false, errors: ["Provider '#{provider_name}' not found"], warnings: []} unless provider_config
|
141
|
+
|
142
|
+
# Create a minimal config with harness section and just this provider for validation
|
143
|
+
test_config = {
|
144
|
+
harness: {
|
145
|
+
max_retries: 2,
|
146
|
+
default_provider: provider_name,
|
147
|
+
fallback_providers: [provider_name]
|
148
|
+
},
|
149
|
+
providers: {
|
150
|
+
provider_name => provider_config
|
151
|
+
}
|
152
|
+
}
|
153
|
+
|
154
|
+
ConfigSchema.validate(test_config)
|
155
|
+
end
|
156
|
+
|
157
|
+
# Get provider configuration with defaults
|
158
|
+
def get_provider_config(provider_name)
|
159
|
+
return nil unless @config_file
|
160
|
+
|
161
|
+
load_config
|
162
|
+
providers_config = @config[:providers] || @config["providers"] || {}
|
163
|
+
provider_config = providers_config[provider_name] || providers_config[provider_name.to_sym]
|
164
|
+
|
165
|
+
return nil unless provider_config
|
166
|
+
|
167
|
+
# Apply defaults for this provider
|
168
|
+
providers_schema = ConfigSchema::SCHEMA[:providers][:pattern_properties][/^[a-zA-Z0-9_-]+$/]
|
169
|
+
ConfigSchema.apply_section_defaults(provider_config, providers_schema)
|
170
|
+
end
|
171
|
+
|
172
|
+
# Check if provider is properly configured
|
173
|
+
def provider_configured?(provider_name)
|
174
|
+
return false unless @config_file
|
175
|
+
|
176
|
+
load_config
|
177
|
+
providers_config = @config[:providers] || @config["providers"] || {}
|
178
|
+
provider_config = providers_config[provider_name] || providers_config[provider_name.to_sym]
|
179
|
+
|
180
|
+
return false unless provider_config
|
181
|
+
|
182
|
+
# Basic validation
|
183
|
+
provider_type = provider_config[:type] || provider_config["type"]
|
184
|
+
return false unless provider_type
|
185
|
+
|
186
|
+
# For usage-based providers, check for required fields
|
187
|
+
if provider_type == "usage_based"
|
188
|
+
max_tokens = provider_config[:max_tokens] || provider_config["max_tokens"]
|
189
|
+
return false unless max_tokens&.positive?
|
190
|
+
end
|
191
|
+
|
192
|
+
true
|
193
|
+
end
|
194
|
+
|
195
|
+
# Get harness configuration with defaults
|
196
|
+
def get_harness_config
|
197
|
+
return nil unless @config_file
|
198
|
+
|
199
|
+
load_config
|
200
|
+
harness_config = @config[:harness] || @config["harness"] || {}
|
201
|
+
|
202
|
+
# Apply defaults
|
203
|
+
harness_schema = ConfigSchema::SCHEMA[:harness]
|
204
|
+
ConfigSchema.apply_section_defaults(harness_config, harness_schema)
|
205
|
+
end
|
206
|
+
|
207
|
+
# Export configuration to different formats
|
208
|
+
def export_config(format = :yaml)
|
209
|
+
return nil unless @config_file
|
210
|
+
|
211
|
+
load_config
|
212
|
+
validate_config
|
213
|
+
validated_config = get_validated_config
|
214
|
+
return nil unless validated_config
|
215
|
+
|
216
|
+
case format
|
217
|
+
when :yaml
|
218
|
+
YAML.dump(validated_config)
|
219
|
+
when :json
|
220
|
+
require "json"
|
221
|
+
JSON.pretty_generate(validated_config)
|
222
|
+
when :ruby
|
223
|
+
"CONFIG = #{validated_config.inspect}"
|
224
|
+
else
|
225
|
+
raise ArgumentError, "Unsupported format: #{format}"
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
# Validate configuration data (public method for external use)
|
230
|
+
def validate_config(config_data = nil)
|
231
|
+
if config_data
|
232
|
+
# Validate provided configuration data
|
233
|
+
@config = config_data
|
234
|
+
end
|
235
|
+
return unless @config
|
236
|
+
|
237
|
+
# Don't override validation result if it was already set due to loading errors
|
238
|
+
return if @validation_result && !@validation_result[:valid]
|
239
|
+
|
240
|
+
@validation_result = ConfigSchema.validate(@config)
|
241
|
+
end
|
242
|
+
|
243
|
+
private
|
244
|
+
|
245
|
+
def find_config_file
|
246
|
+
# Try new aidp.yml format first, then fall back to .aidp.yml
|
247
|
+
config_file = File.join(@project_dir, "aidp.yml")
|
248
|
+
legacy_config_file = File.join(@project_dir, ".aidp.yml")
|
249
|
+
|
250
|
+
if File.exist?(config_file)
|
251
|
+
config_file
|
252
|
+
elsif File.exist?(legacy_config_file)
|
253
|
+
legacy_config_file
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
def load_config
|
258
|
+
return unless @config_file
|
259
|
+
|
260
|
+
begin
|
261
|
+
@config = YAML.load_file(@config_file) || {}
|
262
|
+
rescue => e
|
263
|
+
@config = {}
|
264
|
+
@validation_result = {
|
265
|
+
valid: false,
|
266
|
+
errors: ["Failed to load configuration file: #{e.message}"],
|
267
|
+
warnings: []
|
268
|
+
}
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
def normalize_keys(hash)
|
273
|
+
return hash unless hash.is_a?(Hash)
|
274
|
+
|
275
|
+
hash.each_with_object({}) do |(key, value), result|
|
276
|
+
new_key = key.is_a?(String) ? key.to_sym : key
|
277
|
+
new_value = value.is_a?(Hash) ? normalize_keys(value) : value
|
278
|
+
result[new_key] = new_value
|
279
|
+
end
|
280
|
+
end
|
281
|
+
|
282
|
+
def fix_validation_issues
|
283
|
+
return unless @config
|
284
|
+
|
285
|
+
# Fix common issues that can be automatically corrected
|
286
|
+
|
287
|
+
# Ensure harness section exists
|
288
|
+
unless @config.key?(:harness)
|
289
|
+
@config[:harness] = {}
|
290
|
+
end
|
291
|
+
|
292
|
+
# Ensure providers section exists
|
293
|
+
unless @config.key?(:providers)
|
294
|
+
@config[:providers] = {}
|
295
|
+
end
|
296
|
+
|
297
|
+
# Fix string/symbol key inconsistencies
|
298
|
+
@config = normalize_keys(@config)
|
299
|
+
|
300
|
+
# Ensure default_provider is set if not specified
|
301
|
+
unless @config[:harness][:default_provider]
|
302
|
+
available_providers = @config[:providers].keys.map(&:to_s)
|
303
|
+
if available_providers.include?("cursor")
|
304
|
+
@config[:harness][:default_provider] = "cursor"
|
305
|
+
elsif available_providers.any?
|
306
|
+
@config[:harness][:default_provider] = available_providers.first
|
307
|
+
end
|
308
|
+
end
|
309
|
+
|
310
|
+
# Ensure fallback_providers is an array
|
311
|
+
unless @config[:harness][:fallback_providers].is_a?(Array)
|
312
|
+
@config[:harness][:fallback_providers] = []
|
313
|
+
end
|
314
|
+
|
315
|
+
# Fix provider configurations
|
316
|
+
@config[:providers].each do |_provider_name, provider_config|
|
317
|
+
# Ensure type is specified
|
318
|
+
unless provider_config[:type]
|
319
|
+
provider_config[:type] = "subscription" # Default to subscription
|
320
|
+
end
|
321
|
+
|
322
|
+
# Ensure default_flags is an array
|
323
|
+
unless provider_config[:default_flags].is_a?(Array)
|
324
|
+
provider_config[:default_flags] = []
|
325
|
+
end
|
326
|
+
|
327
|
+
# Ensure models is an array
|
328
|
+
unless provider_config[:models].is_a?(Array)
|
329
|
+
provider_config[:models] = []
|
330
|
+
end
|
331
|
+
|
332
|
+
# Ensure model_weights is a hash
|
333
|
+
unless provider_config[:model_weights].is_a?(Hash)
|
334
|
+
provider_config[:model_weights] = {}
|
335
|
+
end
|
336
|
+
|
337
|
+
# Ensure models_config is a hash
|
338
|
+
unless provider_config[:models_config].is_a?(Hash)
|
339
|
+
provider_config[:models_config] = {}
|
340
|
+
end
|
341
|
+
|
342
|
+
# Ensure features is a hash
|
343
|
+
unless provider_config[:features].is_a?(Hash)
|
344
|
+
provider_config[:features] = {}
|
345
|
+
end
|
346
|
+
|
347
|
+
# Ensure monitoring is a hash
|
348
|
+
unless provider_config[:monitoring].is_a?(Hash)
|
349
|
+
provider_config[:monitoring] = {}
|
350
|
+
end
|
351
|
+
end
|
352
|
+
end
|
353
|
+
end
|
354
|
+
end
|
355
|
+
end
|