aidp 0.12.1 → 0.13.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e672ad3f8f54f1b3ad0cc4a804a63d1fa048709d47112497d5a4871d046dfb8b
4
- data.tar.gz: 665d0b12e5dff272a0da11fd20d80299eaa4657ab7a87fe4e8b0f80e039e437d
3
+ metadata.gz: 0f6484f93a1d57d07f223f49abab2f1a919490d4cb25e6623e76ca85b430a0be
4
+ data.tar.gz: 6f765c07f09d77cf3ffab88c36aa9a04acf90c39fc44d326a594b7ff4b67759b
5
5
  SHA512:
6
- metadata.gz: 384734aed97d697dce2c06ac6bf6f52b161b6436081ff4feb3b8e99e8038bef2b62a9aa3613b21dc92705569741598b98dcbf72805868f6cbdf82a1a19c3c6dd
7
- data.tar.gz: 3bd5a990c925f10bb1ad863097b1f0a1e84b682e2489b0793242c37cc4034eb6ac8777559cecb6acaef915391dfeb60337074267e52a1cc4c35aee87c793d672
6
+ metadata.gz: e3219a59423ae33fc74bfaf38ac3ecebc3a157ac4f789c22252527652f02f63a1d98078de3db8b277d323073bf5cec8b86c97e9e7749f9a4e3097c6d849a4c2e
7
+ data.tar.gz: 3ec1273d7a35839fef07a02fa3a77e9340c008146c87ae790c8829f851f668af5fe1a1df12e28244b2b78c3313dd4ca667cb5e794232a3c4507f09f540d46cd9
@@ -14,7 +14,7 @@ module Aidp
14
14
 
15
15
  # Store data in a JSON file
16
16
  def store_data(filename, data)
17
- file_path = get_file_path(filename)
17
+ file_path = file_path(filename)
18
18
 
19
19
  # Ensure directory exists
20
20
  FileUtils.mkdir_p(File.dirname(file_path))
@@ -31,8 +31,8 @@ module Aidp
31
31
  end
32
32
 
33
33
  # Retrieve data from a JSON file
34
- def get_data(filename)
35
- file_path = get_file_path(filename)
34
+ def data(filename)
35
+ file_path = file_path(filename)
36
36
 
37
37
  return nil unless File.exist?(file_path)
38
38
 
@@ -45,12 +45,12 @@ module Aidp
45
45
 
46
46
  # Check if a JSON file exists
47
47
  def data_exists?(filename)
48
- File.exist?(get_file_path(filename))
48
+ File.exist?(file_path(filename))
49
49
  end
50
50
 
51
51
  # Delete a JSON file
52
52
  def delete_data(filename)
53
- file_path = get_file_path(filename)
53
+ file_path = file_path(filename)
54
54
 
55
55
  if File.exist?(file_path)
56
56
  File.delete(file_path)
@@ -89,8 +89,8 @@ module Aidp
89
89
  end
90
90
 
91
91
  # Get project configuration
92
- def get_project_config
93
- get_data("project_config.json")
92
+ def project_config
93
+ data("project_config.json")
94
94
  end
95
95
 
96
96
  # Store runtime status
@@ -99,8 +99,8 @@ module Aidp
99
99
  end
100
100
 
101
101
  # Get runtime status
102
- def get_runtime_status
103
- get_data("runtime_status.json")
102
+ def runtime_status
103
+ data("runtime_status.json")
104
104
  end
105
105
 
106
106
  # Store simple metrics
@@ -109,8 +109,8 @@ module Aidp
109
109
  end
110
110
 
111
111
  # Get simple metrics
112
- def get_simple_metrics
113
- get_data("simple_metrics.json")
112
+ def simple_metrics
113
+ data("simple_metrics.json")
114
114
  end
115
115
 
116
116
  # Store analysis session data
@@ -119,8 +119,8 @@ module Aidp
119
119
  end
120
120
 
121
121
  # Get analysis session data
122
- def get_analysis_session(session_id)
123
- get_data("sessions/#{session_id}.json")
122
+ def analysis_session(session_id)
123
+ data("sessions/#{session_id}.json")
124
124
  end
125
125
 
126
126
  # List analysis sessions
@@ -145,8 +145,8 @@ module Aidp
145
145
  end
146
146
 
147
147
  # Get user preferences
148
- def get_user_preferences
149
- get_data("user_preferences.json")
148
+ def user_preferences
149
+ data("user_preferences.json")
150
150
  end
151
151
 
152
152
  # Store cache data
@@ -161,8 +161,8 @@ module Aidp
161
161
  end
162
162
 
163
163
  # Get cache data (respects TTL)
164
- def get_cache(cache_key)
165
- cache_file_data = get_data("cache/#{cache_key}.json")
164
+ def cache(cache_key)
165
+ cache_file_data = data("cache/#{cache_key}.json")
166
166
  return nil unless cache_file_data
167
167
 
168
168
  # Check TTL if specified
@@ -203,7 +203,7 @@ module Aidp
203
203
  end
204
204
 
205
205
  # Get storage statistics
206
- def get_storage_statistics
206
+ def storage_statistics
207
207
  files = list_files
208
208
 
209
209
  {
@@ -226,7 +226,7 @@ module Aidp
226
226
 
227
227
  files = list_files
228
228
  files.each do |file_info|
229
- data = get_data(file_info[:filename])
229
+ data = data(file_info[:filename])
230
230
  export_data["files"][file_info[:filename]] = {
231
231
  "data" => data,
232
232
  "metadata" => {
@@ -249,7 +249,7 @@ module Aidp
249
249
 
250
250
  # Import data from an exported JSON file
251
251
  def import_data(import_filename)
252
- import_path = get_file_path(import_filename)
252
+ import_path = file_path(import_filename)
253
253
 
254
254
  unless File.exist?(import_path)
255
255
  raise "Import file does not exist: #{import_filename}"
@@ -280,7 +280,7 @@ module Aidp
280
280
 
281
281
  private
282
282
 
283
- def get_file_path(filename)
283
+ def file_path(filename)
284
284
  File.join(@storage_dir, filename)
285
285
  end
286
286
 
@@ -0,0 +1,114 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "tty-prompt"
4
+ require "reline"
5
+
6
+ module Aidp
7
+ class CLI
8
+ # Enhanced input handler with full readline-style key bindings using Reline
9
+ class EnhancedInput
10
+ # Standard key bindings supported by Reline:
11
+ # - Ctrl-A: Move to beginning of line
12
+ # - Ctrl-E: Move to end of line
13
+ # - Ctrl-W: Delete word backward
14
+ # - Ctrl-K: Kill to end of line
15
+ # - Ctrl-U: Kill to beginning of line
16
+ # - Ctrl-D: Delete character forward
17
+ # - Ctrl-H/Backspace: Delete character backward
18
+ # - Left/Right arrows: Move cursor
19
+ # - Alt-F/Alt-B: Move forward/backward by word
20
+ # - Home/End: Jump to beginning/end
21
+ # - Ctrl-T: Transpose characters
22
+ # - And many more Emacs-style bindings
23
+
24
+ def initialize(prompt: nil, input: nil, output: nil, use_reline: true)
25
+ @use_reline = use_reline
26
+ @input = input || $stdin
27
+ @output = output || $stdout
28
+ @prompt = prompt || TTY::Prompt.new(
29
+ input: @input,
30
+ output: @output,
31
+ enable_color: true,
32
+ interrupt: :exit
33
+ )
34
+ @show_hints = false
35
+ end
36
+
37
+ # Ask a question with full readline support
38
+ # Uses Reline for readline-style editing when use_reline is true
39
+ def ask(question, **options)
40
+ # If reline is enabled and we're in a TTY, use reline for better editing
41
+ if @use_reline && @input.tty?
42
+ default = options[:default]
43
+ required = options[:required] || false
44
+
45
+ # Display helpful hint on first use
46
+ if @show_hints
47
+ @output.puts "💡 Hint: Use Ctrl-A (start), Ctrl-E (end), Ctrl-W (delete word), Ctrl-K (kill line)"
48
+ @show_hints = false
49
+ end
50
+
51
+ # Use Reline for input with full key binding support
52
+ loop do
53
+ prompt_text = question.to_s
54
+ prompt_text += " (#{default})" if default
55
+ prompt_text += " "
56
+
57
+ # Reline provides full readline editing capabilities
58
+ Reline.output = @output
59
+ Reline.input = @input
60
+ Reline.completion_append_character = " "
61
+
62
+ answer = Reline.readline(prompt_text, false)
63
+
64
+ # Handle Ctrl-D (nil return)
65
+ if answer.nil?
66
+ @output.puts
67
+ raise Interrupt
68
+ end
69
+
70
+ answer = answer.strip
71
+ answer = default if answer.empty? && default
72
+
73
+ if required && (answer.nil? || answer.empty?)
74
+ @output.puts " Value required."
75
+ next
76
+ end
77
+
78
+ return answer
79
+ end
80
+ else
81
+ # Fall back to TTY::Prompt's ask
82
+ @prompt.ask(question, **options)
83
+ end
84
+ rescue Interrupt
85
+ @output.puts
86
+ raise
87
+ end
88
+
89
+ # Enable hints for key bindings
90
+ def enable_hints!
91
+ @show_hints = true
92
+ end
93
+
94
+ # Disable Reline (fall back to TTY::Prompt)
95
+ def disable_reline!
96
+ @use_reline = false
97
+ end
98
+
99
+ # Enable Reline
100
+ def enable_reline!
101
+ @use_reline = true
102
+ end
103
+
104
+ # Delegate other methods to underlying prompt
105
+ def method_missing(method, *args, **kwargs, &block)
106
+ @prompt.send(method, *args, **kwargs, &block)
107
+ end
108
+
109
+ def respond_to_missing?(method, include_private = false)
110
+ @prompt.respond_to?(method, include_private) || super
111
+ end
112
+ end
113
+ end
114
+ end
@@ -137,9 +137,6 @@ module Aidp
137
137
  @prompt.say("Interactive custom configuration: press Enter to accept defaults shown in [brackets].")
138
138
  @prompt.say("")
139
139
 
140
- # Get available providers for validation
141
- available_providers = get_available_providers
142
-
143
140
  # Use TTY::Prompt select for primary provider
144
141
  # Find the formatted string that matches the default
145
142
  default_option = available_providers.find { |option| option.start_with?("cursor -") } || available_providers.first
@@ -191,9 +188,6 @@ module Aidp
191
188
  @prompt.say("Interactive configuration update: press Enter to keep current values shown in [brackets].")
192
189
  @prompt.say("")
193
190
 
194
- # Get available providers for validation
195
- available_providers = get_available_providers
196
-
197
191
  # Use TTY::Prompt select for primary provider
198
192
  # Find the formatted string that matches the current default
199
193
  default_option = available_providers.find { |option| option.start_with?("#{current_default} -") } || available_providers.first
@@ -278,7 +272,7 @@ module Aidp
278
272
  end
279
273
 
280
274
  # Get available providers for validation
281
- def get_available_providers
275
+ def available_providers
282
276
  # Get all supported providers from the factory (single source of truth)
283
277
  all_providers = Aidp::Harness::ProviderFactory::PROVIDER_CLASSES.keys
284
278
 
@@ -57,7 +57,7 @@ module Aidp
57
57
  server_matrix = build_server_matrix
58
58
  eligible_providers = []
59
59
 
60
- @configuration.configured_providers.each do |provider|
60
+ @configuration.provider_names.each do |provider|
61
61
  provider_servers = server_matrix[:provider_servers][provider] || []
62
62
  enabled_servers = provider_servers.select { |s| s[:enabled] }.map { |s| s[:name] }
63
63
 
@@ -70,7 +70,7 @@ module Aidp
70
70
  {
71
71
  required_servers: required_servers,
72
72
  eligible_providers: eligible_providers,
73
- total_providers: @configuration.configured_providers.size
73
+ total_providers: @configuration.provider_names.size
74
74
  }
75
75
  end
76
76
 
@@ -96,7 +96,7 @@ module Aidp
96
96
  private
97
97
 
98
98
  def build_server_matrix
99
- providers = @configuration.configured_providers
99
+ providers = @configuration.provider_names
100
100
  all_servers = {} # server_name => {providers: {provider_name => server_info}}
101
101
  provider_servers = {} # provider_name => [server_info]
102
102
 
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "stringio"
4
+ require "tty-reader"
4
5
 
5
6
  module Aidp
6
7
  class CLI
@@ -32,6 +33,31 @@ module Aidp
32
33
  @input.gets
33
34
  end
34
35
 
36
+ # Enhanced readline-style input with standard key combinations
37
+ # Supports: Ctrl-A (beginning), Ctrl-E (end), Ctrl-W (delete word), etc.
38
+ def readline(prompt = "", default: nil)
39
+ # Use StringIO for testing, otherwise use TTY::Reader for real input
40
+ if @input.is_a?(StringIO)
41
+ @output.print(prompt)
42
+ @output.flush
43
+ line = @input.gets
44
+ return line&.chomp if line
45
+ return default
46
+ end
47
+
48
+ reader = TTY::Reader.new(
49
+ input: @input,
50
+ output: @output,
51
+ interrupt: :exit
52
+ )
53
+
54
+ # Read line with full readline support (Ctrl-A, Ctrl-E, Ctrl-W, etc.)
55
+ result = reader.read_line(prompt, default: default || "")
56
+ result&.chomp
57
+ rescue TTY::Reader::InputInterrupt
58
+ raise Interrupt
59
+ end
60
+
35
61
  def write(str)
36
62
  @output.write(str)
37
63
  end
data/lib/aidp/cli.rb CHANGED
@@ -618,8 +618,8 @@ module Aidp
618
618
  false
619
619
  end
620
620
  end
621
- configuration = Aidp::Harness::Configuration.new(Dir.pwd)
622
- pm = Aidp::Harness::ProviderManager.new(configuration, prompt: TTY::Prompt.new)
621
+ config_manager = Aidp::Harness::ConfigManager.new(Dir.pwd)
622
+ pm = Aidp::Harness::ProviderManager.new(config_manager, prompt: TTY::Prompt.new)
623
623
 
624
624
  # Use TTY::Spinner for progress indication
625
625
  require "tty-spinner"
@@ -772,11 +772,11 @@ module Aidp
772
772
  require "tty-spinner"
773
773
 
774
774
  provider_name = args.shift
775
- configuration = Aidp::Harness::Configuration.new(Dir.pwd)
775
+ config_manager = Aidp::Harness::ConfigManager.new(Dir.pwd)
776
776
  providers_to_refresh = if provider_name
777
777
  [provider_name]
778
778
  else
779
- configuration.configured_providers
779
+ config_manager.provider_names
780
780
  end
781
781
 
782
782
  display_message("Refreshing provider information...", type: :info)
@@ -1425,7 +1425,7 @@ module Aidp
1425
1425
  end
1426
1426
 
1427
1427
  # Get completion confidence level
1428
- def get_completion_confidence(completion_info)
1428
+ def completion_confidence(completion_info)
1429
1429
  return 0.0 unless completion_info && completion_info[:confidence]
1430
1430
 
1431
1431
  completion_info[:confidence]
@@ -1433,23 +1433,23 @@ module Aidp
1433
1433
 
1434
1434
  # Check if completion is high confidence
1435
1435
  def high_confidence_completion?(completion_info)
1436
- get_completion_confidence(completion_info) >= 0.8
1436
+ completion_confidence(completion_info) >= 0.8
1437
1437
  end
1438
1438
 
1439
1439
  # Check if completion is medium confidence
1440
1440
  def medium_confidence_completion?(completion_info)
1441
- confidence = get_completion_confidence(completion_info)
1441
+ confidence = completion_confidence(completion_info)
1442
1442
  confidence >= 0.5 && confidence < 0.8
1443
1443
  end
1444
1444
 
1445
1445
  # Check if completion is low confidence
1446
1446
  def low_confidence_completion?(completion_info)
1447
- confidence = get_completion_confidence(completion_info)
1447
+ confidence = completion_confidence(completion_info)
1448
1448
  confidence > 0.0 && confidence < 0.5
1449
1449
  end
1450
1450
 
1451
1451
  # Get next actions from completion info
1452
- def get_next_actions(completion_info)
1452
+ def next_actions(completion_info)
1453
1453
  return [] unless completion_info && completion_info[:next_actions]
1454
1454
 
1455
1455
  completion_info[:next_actions]
@@ -1495,7 +1495,7 @@ module Aidp
1495
1495
  end
1496
1496
 
1497
1497
  # Get progress status description
1498
- def get_progress_status_description(completion_info)
1498
+ def progress_status_description(completion_info)
1499
1499
  return "unknown" unless completion_info
1500
1500
 
1501
1501
  case completion_info[:progress_status]
@@ -23,7 +23,7 @@ module Aidp
23
23
  validation_result = @validator.load_and_validate
24
24
 
25
25
  if validation_result[:valid]
26
- @config_cache = @validator.get_validated_config
26
+ @config_cache = @validator.validated_config
27
27
  @last_loaded = Time.now
28
28
 
29
29
  # Log warnings if any
@@ -40,7 +40,7 @@ module Aidp
40
40
  end
41
41
 
42
42
  # Get harness configuration with defaults
43
- def get_harness_config(force_reload = false)
43
+ def harness_config(force_reload = false)
44
44
  config = load_config(force_reload)
45
45
  return nil unless config
46
46
 
@@ -48,7 +48,7 @@ module Aidp
48
48
  end
49
49
 
50
50
  # Get provider configuration with defaults
51
- def get_provider_config(provider_name, force_reload = false)
51
+ def provider_config(provider_name, force_reload = false)
52
52
  config = load_config(force_reload)
53
53
  return nil unless config
54
54
 
@@ -57,7 +57,7 @@ module Aidp
57
57
  end
58
58
 
59
59
  # Get all provider configurations
60
- def get_all_provider_configs(force_reload = false)
60
+ def all_provider_configs(force_reload = false)
61
61
  config = load_config(force_reload)
62
62
  return {} unless config
63
63
 
@@ -65,7 +65,7 @@ module Aidp
65
65
  end
66
66
 
67
67
  # Get configured provider names
68
- def get_configured_providers(force_reload = false)
68
+ def configured_providers(force_reload = false)
69
69
  config = load_config(force_reload)
70
70
  return [] unless config
71
71
 
@@ -94,7 +94,7 @@ module Aidp
94
94
  end
95
95
 
96
96
  # Get configuration summary
97
- def get_config_summary
97
+ def config_summary
98
98
  @validator.get_summary
99
99
  end
100
100
 
@@ -109,7 +109,7 @@ module Aidp
109
109
  end
110
110
 
111
111
  # Get configuration with specific overrides
112
- def get_config_with_overrides(overrides = {})
112
+ def config_with_overrides(overrides = {})
113
113
  base_config = load_config
114
114
  return nil unless base_config
115
115
 
@@ -117,17 +117,17 @@ module Aidp
117
117
  end
118
118
 
119
119
  # Get harness configuration with overrides
120
- def get_harness_config_with_overrides(overrides = {})
121
- harness_config = get_harness_config
122
- return nil unless harness_config
120
+ def harness_config_with_overrides(overrides = {})
121
+ base_harness_config = harness_config
122
+ return nil unless base_harness_config
123
123
 
124
124
  harness_overrides = overrides[:harness] || overrides["harness"] || {}
125
- deep_merge(harness_config, harness_overrides)
125
+ deep_merge(base_harness_config, harness_overrides)
126
126
  end
127
127
 
128
128
  # Get provider configuration with overrides
129
- def get_provider_config_with_overrides(provider_name, overrides = {})
130
- provider_config = get_provider_config(provider_name)
129
+ def provider_config_with_overrides(provider_name, overrides = {})
130
+ provider_config = provider_config(provider_name)
131
131
  return nil unless provider_config
132
132
 
133
133
  provider_overrides = overrides[:providers]&.dig(provider_name.to_sym) ||
@@ -158,34 +158,34 @@ module Aidp
158
158
  end
159
159
 
160
160
  # Get validation errors
161
- def get_validation_errors
161
+ def validation_errors
162
162
  validation_result = @validator.validate_existing
163
163
  validation_result[:errors] || []
164
164
  end
165
165
 
166
166
  # Get validation warnings
167
- def get_validation_warnings
167
+ def validation_warnings
168
168
  validation_result = @validator.validate_existing
169
169
  validation_result[:warnings] || []
170
170
  end
171
171
 
172
172
  # Get configuration for specific harness mode
173
- def get_mode_config(mode, force_reload = false)
173
+ def mode_config(mode, force_reload = false)
174
174
  config = load_config(force_reload)
175
175
  return nil unless config
176
176
 
177
177
  case mode.to_s
178
178
  when "analyze"
179
- get_analyze_mode_config(config)
179
+ analyze_mode_config(config)
180
180
  when "execute"
181
- get_execute_mode_config(config)
181
+ execute_mode_config(config)
182
182
  else
183
183
  config
184
184
  end
185
185
  end
186
186
 
187
187
  # Get environment-specific configuration
188
- def get_environment_config(environment = nil, force_reload = false)
188
+ def environment_config(environment = nil, force_reload = false)
189
189
  environment ||= ENV["AIDP_ENV"] || "development"
190
190
  config = load_config(force_reload)
191
191
  return nil unless config
@@ -214,7 +214,7 @@ module Aidp
214
214
  end
215
215
 
216
216
  # Get configuration with feature flags
217
- def get_config_with_features(features = {}, force_reload = false)
217
+ def config_with_features(features = {}, force_reload = false)
218
218
  config = load_config(force_reload)
219
219
  return nil unless config
220
220
 
@@ -250,7 +250,7 @@ module Aidp
250
250
  end
251
251
 
252
252
  # Get configuration with time-based overrides
253
- def get_time_based_config(force_reload = false)
253
+ def time_based_config(force_reload = false)
254
254
  config = load_config(force_reload)
255
255
  return nil unless config
256
256
 
@@ -340,12 +340,12 @@ module Aidp
340
340
  result
341
341
  end
342
342
 
343
- def get_analyze_mode_config(config)
343
+ def analyze_mode_config(config)
344
344
  analyze_overrides = config[:analyze_mode] || config["analyze_mode"] || {}
345
345
  merge_overrides(config, analyze_overrides)
346
346
  end
347
347
 
348
- def get_execute_mode_config(config)
348
+ def execute_mode_config(config)
349
349
  execute_overrides = config[:execute_mode] || config["execute_mode"] || {}
350
350
  merge_overrides(config, execute_overrides)
351
351
  end