aidp 0.7.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 +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 +0 -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,441 +0,0 @@
|
|
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
|
-
config_data = case File.extname(file_path)
|
255
|
-
when ".yml", ".yaml"
|
256
|
-
YAML.load_file(file_path)
|
257
|
-
when ".json"
|
258
|
-
JSON.parse(File.read(file_path))
|
259
|
-
else
|
260
|
-
raise ArgumentError, "Unsupported file format: #{File.extname(file_path)}"
|
261
|
-
end
|
262
|
-
|
263
|
-
case scope
|
264
|
-
when :project
|
265
|
-
@project_config = config_data
|
266
|
-
save_project_config
|
267
|
-
when :user
|
268
|
-
@user_config = config_data
|
269
|
-
save_user_config
|
270
|
-
else
|
271
|
-
raise ArgumentError, "Invalid scope: #{scope}"
|
272
|
-
end
|
273
|
-
|
274
|
-
true
|
275
|
-
end
|
276
|
-
|
277
|
-
# Validate configuration
|
278
|
-
def validate_config
|
279
|
-
errors = []
|
280
|
-
|
281
|
-
# Validate user config
|
282
|
-
errors.concat(validate_config_structure(@user_config, "user"))
|
283
|
-
|
284
|
-
# Validate project config
|
285
|
-
errors.concat(validate_config_structure(@project_config, "project"))
|
286
|
-
|
287
|
-
errors
|
288
|
-
end
|
289
|
-
|
290
|
-
private
|
291
|
-
|
292
|
-
def load_user_config
|
293
|
-
return {} unless File.exist?(USER_CONFIG_FILE)
|
294
|
-
|
295
|
-
YAML.load_file(USER_CONFIG_FILE) || {}
|
296
|
-
end
|
297
|
-
|
298
|
-
def load_project_config
|
299
|
-
config_path = project_config_path
|
300
|
-
return {} unless File.exist?(config_path)
|
301
|
-
|
302
|
-
YAML.load_file(config_path) || {}
|
303
|
-
end
|
304
|
-
|
305
|
-
def project_config_path
|
306
|
-
File.join(@project_dir, PROJECT_CONFIG_FILE)
|
307
|
-
end
|
308
|
-
|
309
|
-
def set_project_preferred_tool(language, category, tool_name)
|
310
|
-
@project_config["preferred_tools"] ||= {}
|
311
|
-
@project_config["preferred_tools"][language] ||= {}
|
312
|
-
@project_config["preferred_tools"][language][category] = tool_name
|
313
|
-
save_project_config
|
314
|
-
end
|
315
|
-
|
316
|
-
def set_user_preferred_tool(language, category, tool_name)
|
317
|
-
@user_config["preferred_tools"] ||= {}
|
318
|
-
@user_config["preferred_tools"][language] ||= {}
|
319
|
-
@user_config["preferred_tools"][language][category] = tool_name
|
320
|
-
save_user_config
|
321
|
-
end
|
322
|
-
|
323
|
-
def set_project_tool_config(tool_name, config)
|
324
|
-
@project_config["tool_configs"] ||= {}
|
325
|
-
@project_config["tool_configs"][tool_name] = config
|
326
|
-
save_project_config
|
327
|
-
end
|
328
|
-
|
329
|
-
def set_user_tool_config(tool_name, config)
|
330
|
-
@user_config["tool_configs"] ||= {}
|
331
|
-
@user_config["tool_configs"][tool_name] = config
|
332
|
-
save_user_config
|
333
|
-
end
|
334
|
-
|
335
|
-
def set_project_execution_settings(settings)
|
336
|
-
@project_config["execution_settings"] = settings
|
337
|
-
save_project_config
|
338
|
-
end
|
339
|
-
|
340
|
-
def set_user_execution_settings(settings)
|
341
|
-
@user_config["execution_settings"] = settings
|
342
|
-
save_user_config
|
343
|
-
end
|
344
|
-
|
345
|
-
def set_project_execution_order(language, order)
|
346
|
-
@project_config["execution_order"] ||= {}
|
347
|
-
@project_config["execution_order"][language] = order
|
348
|
-
save_project_config
|
349
|
-
end
|
350
|
-
|
351
|
-
def set_user_execution_order(language, order)
|
352
|
-
@user_config["execution_order"] ||= {}
|
353
|
-
@user_config["execution_order"][language] = order
|
354
|
-
save_user_config
|
355
|
-
end
|
356
|
-
|
357
|
-
def set_project_integration_settings(integrations)
|
358
|
-
@project_config["integrations"] = integrations
|
359
|
-
save_project_config
|
360
|
-
end
|
361
|
-
|
362
|
-
def set_user_integration_settings(integrations)
|
363
|
-
@user_config["integrations"] = integrations
|
364
|
-
save_user_config
|
365
|
-
end
|
366
|
-
|
367
|
-
def save_user_config
|
368
|
-
FileUtils.mkdir_p(File.dirname(USER_CONFIG_FILE))
|
369
|
-
File.write(USER_CONFIG_FILE, @user_config.to_yaml)
|
370
|
-
end
|
371
|
-
|
372
|
-
def save_project_config
|
373
|
-
File.write(project_config_path, @project_config.to_yaml)
|
374
|
-
end
|
375
|
-
|
376
|
-
def initialize_user_config
|
377
|
-
default_user_config = {
|
378
|
-
"preferred_tools" => DEFAULT_PREFERRED_TOOLS,
|
379
|
-
"execution_settings" => {
|
380
|
-
"timeout" => 300,
|
381
|
-
"parallel_execution" => true,
|
382
|
-
"max_parallel_jobs" => 4
|
383
|
-
},
|
384
|
-
"integrations" => {
|
385
|
-
"ci_cd" => {"enabled" => true},
|
386
|
-
"ide" => {"enabled" => true}
|
387
|
-
}
|
388
|
-
}
|
389
|
-
|
390
|
-
@user_config = default_user_config
|
391
|
-
save_user_config
|
392
|
-
end
|
393
|
-
|
394
|
-
def initialize_project_config
|
395
|
-
default_project_config = {
|
396
|
-
"preferred_tools" => {},
|
397
|
-
"execution_settings" => {},
|
398
|
-
"integrations" => {}
|
399
|
-
}
|
400
|
-
|
401
|
-
@project_config = default_project_config
|
402
|
-
save_project_config
|
403
|
-
end
|
404
|
-
|
405
|
-
def merge_configurations
|
406
|
-
merged = @user_config.dup
|
407
|
-
|
408
|
-
# Merge project config with user config
|
409
|
-
@project_config.each do |key, value|
|
410
|
-
merged[key] = if merged[key].is_a?(Hash) && value.is_a?(Hash)
|
411
|
-
merged[key].merge(value)
|
412
|
-
else
|
413
|
-
value
|
414
|
-
end
|
415
|
-
end
|
416
|
-
|
417
|
-
merged
|
418
|
-
end
|
419
|
-
|
420
|
-
def validate_config_structure(config, config_name)
|
421
|
-
errors = []
|
422
|
-
|
423
|
-
# Validate preferred_tools structure
|
424
|
-
if config["preferred_tools"] && !config["preferred_tools"].is_a?(Hash)
|
425
|
-
errors << "#{config_name} config: preferred_tools must be a hash"
|
426
|
-
end
|
427
|
-
|
428
|
-
# Validate execution_settings structure
|
429
|
-
if config["execution_settings"] && !config["execution_settings"].is_a?(Hash)
|
430
|
-
errors << "#{config_name} config: execution_settings must be a hash"
|
431
|
-
end
|
432
|
-
|
433
|
-
# Validate integrations structure
|
434
|
-
if config["integrations"] && !config["integrations"].is_a?(Hash)
|
435
|
-
errors << "#{config_name} config: integrations must be a hash"
|
436
|
-
end
|
437
|
-
|
438
|
-
errors
|
439
|
-
end
|
440
|
-
end
|
441
|
-
end
|