Class: Aidp::Harness::ConfigLoader

Inherits:
Object
  • Object
show all
Defined in:
lib/aidp/harness/config_loader.rb

Overview

Enhanced configuration loader for harness

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(project_dir = Dir.pwd, validator: nil) ⇒ ConfigLoader



15
16
17
18
19
20
21
# File 'lib/aidp/harness/config_loader.rb', line 15

def initialize(project_dir = Dir.pwd, validator: nil)
  @project_dir = project_dir
  @validator = validator || ConfigValidator.new(project_dir)
  @config_cache = nil
  @last_loaded = nil
  @last_signature = nil # stores {mtime:, size:, hash:}
end

Instance Attribute Details

#validatorObject (readonly)

Expose for testability



13
14
15
# File 'lib/aidp/harness/config_loader.rb', line 13

def validator
  @validator
end

Instance Method Details

#all_provider_configs(force_reload = false) ⇒ Object

Get all provider configurations



66
67
68
69
70
71
# File 'lib/aidp/harness/config_loader.rb', line 66

def all_provider_configs(force_reload = false)
  config = load_config(force_reload)
  return {} unless config

  config[:providers] || {}
end

#config_exists?Boolean

Check if configuration exists



83
84
85
# File 'lib/aidp/harness/config_loader.rb', line 83

def config_exists?
  @validator.config_exists?
end

#config_file_pathObject

Get configuration file path



88
89
90
# File 'lib/aidp/harness/config_loader.rb', line 88

def config_file_path
  @validator.config_file_path
end

#config_summaryObject

Get configuration summary



103
104
105
# File 'lib/aidp/harness/config_loader.rb', line 103

def config_summary
  @validator.get_summary
end

#config_valid?Boolean

Check if configuration is valid



161
162
163
164
# File 'lib/aidp/harness/config_loader.rb', line 161

def config_valid?
  validation_result = @validator.validate_existing
  validation_result[:valid]
end

#config_with_features(features = {}, force_reload = false) ⇒ Object

Get configuration with feature flags



223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
# File 'lib/aidp/harness/config_loader.rb', line 223

def config_with_features(features = {}, force_reload = false)
  config = load_config(force_reload)
  return nil unless config

  feature_overrides = {}

  features.each do |feature, enabled|
    if enabled
      feature_config = config[:features]&.dig(feature.to_sym) ||
        config[:features]&.dig(feature.to_s) ||
        config["features"]&.dig(feature.to_s) ||
        config["features"]&.dig(feature.to_sym) ||
        {}
      feature_overrides = deep_merge(feature_overrides, feature_config)
    end
  end

  merge_overrides(config, feature_overrides)
end

#config_with_overrides(overrides = {}) ⇒ Object

Get configuration with specific overrides



118
119
120
121
122
123
# File 'lib/aidp/harness/config_loader.rb', line 118

def config_with_overrides(overrides = {})
  base_config = load_config
  return nil unless base_config

  merge_overrides(base_config, overrides)
end

#configured_providers(force_reload = false) ⇒ Object

Get configured provider names



74
75
76
77
78
79
80
# File 'lib/aidp/harness/config_loader.rb', line 74

def configured_providers(force_reload = false)
  config = load_config(force_reload)
  return [] unless config

  providers = config[:providers] || {}
  providers.keys.map(&:to_s)
end

#create_example_configObject

Create example configuration



93
94
95
# File 'lib/aidp/harness/config_loader.rb', line 93

def create_example_config
  @validator.create_example_config
end

#environment_config(environment = nil, force_reload = false) ⇒ Object

Get environment-specific configuration



194
195
196
197
198
199
200
201
202
203
204
205
206
# File 'lib/aidp/harness/config_loader.rb', line 194

def environment_config(environment = nil, force_reload = false)
  environment ||= ENV["AIDP_ENV"] || "development"
  config = load_config(force_reload)
  return nil unless config

  env_config = config[:environments]&.dig(environment.to_sym) ||
    config[:environments]&.dig(environment.to_s) ||
    config["environments"]&.dig(environment.to_s) ||
    config["environments"]&.dig(environment.to_sym) ||
    {}

  merge_overrides(config, env_config)
end

#export_config(format = :yaml) ⇒ Object

Export configuration



149
150
151
# File 'lib/aidp/harness/config_loader.rb', line 149

def export_config(format = :yaml)
  @validator.export_config(format)
end

#fix_config_issuesObject

Fix configuration issues



98
99
100
# File 'lib/aidp/harness/config_loader.rb', line 98

def fix_config_issues
  @validator.fix_common_issues
end

#get_step_config(step_name, force_reload = false) ⇒ Object

Get configuration for specific step



209
210
211
212
213
214
215
216
217
218
219
220
# File 'lib/aidp/harness/config_loader.rb', line 209

def get_step_config(step_name, force_reload = false)
  config = load_config(force_reload)
  return nil unless config

  step_config = config[:steps]&.dig(step_name.to_sym) ||
    config[:steps]&.dig(step_name.to_s) ||
    config["steps"]&.dig(step_name.to_s) ||
    config["steps"]&.dig(step_name.to_sym) ||
    {}

  merge_overrides(config, step_config)
end

#get_user_config(user_id = nil, force_reload = false) ⇒ Object

Get configuration for specific user



244
245
246
247
248
249
250
251
252
253
254
255
256
# File 'lib/aidp/harness/config_loader.rb', line 244

def get_user_config(user_id = nil, force_reload = false)
  user_id ||= ENV["USER"] || "default"
  config = load_config(force_reload)
  return nil unless config

  user_config = config[:users]&.dig(user_id.to_sym) ||
    config[:users]&.dig(user_id.to_s) ||
    config["users"]&.dig(user_id.to_s) ||
    config["users"]&.dig(user_id.to_sym) ||
    {}

  merge_overrides(config, user_config)
end

#harness_config(force_reload = false) ⇒ Object

Get harness configuration with defaults



49
50
51
52
53
54
# File 'lib/aidp/harness/config_loader.rb', line 49

def harness_config(force_reload = false)
  config = load_config(force_reload)
  return nil unless config

  config[:harness] || {}
end

#harness_config_with_overrides(overrides = {}) ⇒ Object

Get harness configuration with overrides



126
127
128
129
130
131
132
# File 'lib/aidp/harness/config_loader.rb', line 126

def harness_config_with_overrides(overrides = {})
  base_harness_config = harness_config
  return nil unless base_harness_config

  harness_overrides = overrides[:harness] || overrides["harness"] || {}
  deep_merge(base_harness_config, harness_overrides)
end

#load_config(force_reload = false) ⇒ Object

Load and validate configuration with caching



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/aidp/harness/config_loader.rb', line 24

def load_config(force_reload = false)
  return @config_cache if @config_cache && !force_reload && !config_file_changed?

  # Load and validate configuration
  validation_result = @validator.load_and_validate

  if validation_result[:valid]
    @config_cache = @validator.validated_config
    @last_loaded = Time.now
    @last_signature = current_file_signature

    # Log warnings if any
    unless validation_result[:warnings].empty?
      log_warnings(validation_result[:warnings])
    end

    @config_cache
  else
    # Handle validation errors
    handle_validation_errors(validation_result[:errors])
    nil
  end
end

#mode_config(mode, force_reload = false) ⇒ Object

Get configuration for specific harness mode



179
180
181
182
183
184
185
186
187
188
189
190
191
# File 'lib/aidp/harness/config_loader.rb', line 179

def mode_config(mode, force_reload = false)
  config = load_config(force_reload)
  return nil unless config

  case mode.to_s
  when "analyze"
    analyze_mode_config(config)
  when "execute"
    execute_mode_config(config)
  else
    config
  end
end

#provider_config(provider_name, force_reload = false) ⇒ Object

Get provider configuration with defaults



57
58
59
60
61
62
63
# File 'lib/aidp/harness/config_loader.rb', line 57

def provider_config(provider_name, force_reload = false)
  config = load_config(force_reload)
  return nil unless config

  providers = config[:providers] || {}
  providers[provider_name.to_sym] || providers[provider_name.to_s]
end

#provider_config_with_overrides(provider_name, overrides = {}) ⇒ Object

Get provider configuration with overrides



135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/aidp/harness/config_loader.rb', line 135

def provider_config_with_overrides(provider_name, overrides = {})
  provider_config = provider_config(provider_name)
  return nil unless provider_config

  provider_overrides = overrides[:providers]&.dig(provider_name.to_sym) ||
    overrides[:providers]&.dig(provider_name.to_s) ||
    overrides["providers"]&.dig(provider_name.to_s) ||
    overrides["providers"]&.dig(provider_name.to_sym) ||
    {}

  deep_merge(provider_config, provider_overrides)
end

#provider_configured?(provider_name) ⇒ Boolean

Check if provider is configured



113
114
115
# File 'lib/aidp/harness/config_loader.rb', line 113

def provider_configured?(provider_name)
  @validator.provider_configured?(provider_name)
end

#reload_configObject

Reload configuration from file



154
155
156
157
158
# File 'lib/aidp/harness/config_loader.rb', line 154

def reload_config
  @config_cache = nil
  @last_loaded = nil
  load_config(true)
end

#time_based_config(force_reload = false) ⇒ Object

Get configuration with time-based overrides



259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
# File 'lib/aidp/harness/config_loader.rb', line 259

def time_based_config(force_reload = false)
  config = load_config(force_reload)
  return nil unless config

  time_overrides = {}
  current_hour = Time.now.hour

  # Check for time-based configurations
  if config[:time_based]
    time_config = config[:time_based]

    # Check for hour-based overrides
    time_config[:hours]&.each do |hour_range, hour_config|
      if hour_in_range?(current_hour, hour_range)
        time_overrides = deep_merge(time_overrides, hour_config)
      end
    end

    # Check for day-based overrides
    if time_config[:days]
      current_day = Time.now.strftime("%A").downcase
      day_config = time_config[:days][current_day.to_sym] || time_config[:days][current_day]
      if day_config
        time_overrides = deep_merge(time_overrides, day_config)
      end
    end
  end

  merge_overrides(config, time_overrides)
end

#validate_provider(provider_name) ⇒ Object

Validate specific provider



108
109
110
# File 'lib/aidp/harness/config_loader.rb', line 108

def validate_provider(provider_name)
  @validator.validate_provider(provider_name)
end

#validation_errorsObject

Get validation errors



167
168
169
170
# File 'lib/aidp/harness/config_loader.rb', line 167

def validation_errors
  validation_result = @validator.validate_existing
  validation_result[:errors] || []
end

#validation_warningsObject

Get validation warnings



173
174
175
176
# File 'lib/aidp/harness/config_loader.rb', line 173

def validation_warnings
  validation_result = @validator.validate_existing
  validation_result[:warnings] || []
end