aidp 0.9.4 → 0.9.5

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: '09966bf3624e503612b279e176b987e8c1b504d279069a613069708448af3413'
4
- data.tar.gz: fa60a7047610f5799be416bb3ce1ff81c1caa5f5e003d0b919940ce5bdac6d7f
3
+ metadata.gz: 12e70b298f80b189c33c7db0a67027086a8441a4fdd5c0ae45045b491c5ca825
4
+ data.tar.gz: 1f6445fd7ed137c78e4c6000aac0418d15d00856beea9db9afd4d843aad11b4a
5
5
  SHA512:
6
- metadata.gz: b1003ebfa6759d428c4573ba74f850be3f282b29ece02fe48d1a0c80009165b06fba58ecf70d1c9f5743b070309f770e91d000fd65f8135e005642f1aa0f963b
7
- data.tar.gz: 5a17af6cf7f58304968c351e1e90d75f6c53cdfa2eed4c020fbf8786770625012749d7bb4b0d14770f1d5356cb5faa023d6e736762a31fe4a3c281ea03f00d29
6
+ metadata.gz: 5fab5f97f7874314f0991cd75260175b7aab803d199bb25ab1223fae0d280a7b6a97a11ff160d90b5bc263fc312bc64bb3c95c32e34e31d960c8ab7a403a8778
7
+ data.tar.gz: 9bf30d28286d09e7d25bb23bd3109e422e91518f7e46113949ed27a87cc722046dc8cfd881f00279c6f849173a6a9f4c503d07b519d7cd7ca53d7cd53a71cf67
@@ -10,10 +10,10 @@ module Aidp
10
10
  class FirstRunWizard
11
11
  TEMPLATES_DIR = File.expand_path(File.join(__dir__, "..", "..", "..", "templates"))
12
12
 
13
- def self.ensure_config(project_dir, input: $stdin, output: $stdout, non_interactive: false)
13
+ def self.ensure_config(project_dir, input: $stdin, output: $stdout, non_interactive: false, prompt: TTY::Prompt.new)
14
14
  return true if Aidp::Config.config_exists?(project_dir)
15
15
 
16
- wizard = new(project_dir, input: input, output: output)
16
+ wizard = new(project_dir, input: input, output: output, prompt: prompt)
17
17
 
18
18
  if non_interactive || !input.tty? || !output.tty?
19
19
  # Non-interactive environment - create minimal config silently
@@ -25,8 +25,8 @@ module Aidp
25
25
  wizard.run
26
26
  end
27
27
 
28
- def self.setup_config(project_dir, input: $stdin, output: $stdout, non_interactive: false)
29
- wizard = new(project_dir, input: input, output: output)
28
+ def self.setup_config(project_dir, input: $stdin, output: $stdout, non_interactive: false, prompt: TTY::Prompt.new)
29
+ wizard = new(project_dir, input: input, output: output, prompt: prompt)
30
30
 
31
31
  if non_interactive || !input.tty? || !output.tty?
32
32
  # Non-interactive environment - skip setup
@@ -37,11 +37,11 @@ module Aidp
37
37
  wizard.run_setup_config
38
38
  end
39
39
 
40
- def initialize(project_dir, input: $stdin, output: $stdout)
40
+ def initialize(project_dir, input: $stdin, output: $stdout, prompt: TTY::Prompt.new)
41
41
  @project_dir = project_dir
42
42
  @input = input
43
43
  @output = output
44
- @prompt = TTY::Prompt.new
44
+ @prompt = prompt
45
45
  end
46
46
 
47
47
  def run
@@ -49,11 +49,8 @@ module Aidp
49
49
  loop do
50
50
  choice = ask_choice
51
51
  case choice
52
- when "1" then return finish(write_minimal_config(@project_dir))
53
- when "2" then return finish(copy_template("aidp-development.yml.example"))
54
- when "3" then return finish(copy_template("aidp-production.yml.example"))
55
- when "4" then return finish(write_example_config(@project_dir))
56
- when "5" then return finish(run_custom)
52
+ when "1" then return finish(write_quick_config(@project_dir))
53
+ when "2" then return finish(run_custom)
57
54
  when "q", "Q" then @output.puts("Exiting without creating configuration.")
58
55
  return false
59
56
  else
@@ -92,19 +89,14 @@ module Aidp
92
89
 
93
90
  def ask_choice
94
91
  @output.puts "Choose a configuration style:" unless @asking
95
- @output.puts <<~MENU
96
- 1) Minimal (single provider: cursor)
97
- 2) Development template (multiple providers, safe defaults)
98
- 3) Production template (full features, review required)
99
- 4) Full example (verbose example config)
100
- 5) Custom (interactive prompts)
101
- q) Quit
102
- MENU
103
- @output.print "Enter choice [1]: "
104
- @output.flush
105
- ans = @input.gets&.strip
106
- ans = "1" if ans.nil? || ans.empty?
107
- ans
92
+
93
+ options = {
94
+ "Quick setup (cursor + macos, no API keys needed)" => "1",
95
+ "Custom setup (choose your own providers and settings)" => "2",
96
+ "Quit" => "q"
97
+ }
98
+
99
+ @prompt.select("Select an option:", options, default: "Quick setup (cursor + macos, no API keys needed)")
108
100
  end
109
101
 
110
102
  def finish(path)
@@ -150,6 +142,31 @@ module Aidp
150
142
  dest
151
143
  end
152
144
 
145
+ def write_quick_config(project_dir)
146
+ dest = File.join(project_dir, "aidp.yml")
147
+ return dest if File.exist?(dest)
148
+ data = {
149
+ "harness" => {
150
+ "max_retries" => 2,
151
+ "default_provider" => "cursor",
152
+ "fallback_providers" => ["macos"],
153
+ "no_api_keys_required" => true
154
+ },
155
+ "providers" => {
156
+ "cursor" => {
157
+ "type" => "subscription",
158
+ "default_flags" => []
159
+ },
160
+ "macos" => {
161
+ "type" => "usage_based",
162
+ "default_flags" => []
163
+ }
164
+ }
165
+ }
166
+ File.write(dest, YAML.dump(data))
167
+ dest
168
+ end
169
+
153
170
  def write_example_config(project_dir)
154
171
  Aidp::Config.create_example_config(project_dir)
155
172
  File.join(project_dir, "aidp.yml")
@@ -252,6 +269,12 @@ module Aidp
252
269
  # Convert existing provider config to string keys
253
270
  converted_provider = {}
254
271
  existing_provider.each { |k, v| converted_provider[k.to_s] = v }
272
+ # Ensure the type is correct (fix old "package" and "api" types)
273
+ if converted_provider["type"] == "package"
274
+ converted_provider["type"] = "subscription"
275
+ elsif converted_provider["type"] == "api"
276
+ converted_provider["type"] = "usage_based"
277
+ end
255
278
  provider_section[prov] = converted_provider
256
279
  else
257
280
  provider_section[prov] = {"type" => (prov == "cursor") ? "subscription" : "usage_based", "default_flags" => []}
@@ -6,9 +6,9 @@ module Aidp
6
6
  module Execute
7
7
  # Handles interactive workflow selection and project setup
8
8
  class WorkflowSelector
9
- def initialize
9
+ def initialize(prompt: TTY::Prompt.new)
10
10
  @user_input = {}
11
- @prompt = TTY::Prompt.new
11
+ @prompt = prompt
12
12
  end
13
13
 
14
14
  # Main entry point for interactive workflow selection
@@ -7,8 +7,8 @@ module Aidp
7
7
  # Simple, focused user interface for collecting feedback
8
8
  # Replaces the bloated UserInterface with minimal, clean code
9
9
  class SimpleUserInterface
10
- def initialize
11
- @prompt = TTY::Prompt.new
10
+ def initialize(prompt: TTY::Prompt.new)
11
+ @prompt = prompt
12
12
  end
13
13
 
14
14
  # Main method - collect responses for questions
@@ -18,15 +18,17 @@ module Aidp
18
18
  class InputError < TUIError; end
19
19
  class DisplayError < TUIError; end
20
20
 
21
- def initialize
21
+ def initialize(prompt: TTY::Prompt.new)
22
22
  @cursor = TTY::Cursor
23
23
  @screen = TTY::Screen
24
24
  @pastel = Pastel.new
25
- @prompt = TTY::Prompt.new
25
+ @prompt = prompt
26
+
26
27
  # Headless (non-interactive) detection for test/CI environments:
27
28
  # - RSpec defined or RSPEC_RUNNING env set
28
29
  # - STDIN not a TTY (captured by PTY/tmux harness)
29
30
  @headless = !!(defined?(RSpec) || ENV["RSPEC_RUNNING"] || $stdin.nil? || !$stdin.tty?)
31
+
30
32
  @current_mode = nil
31
33
  @workflow_active = false
32
34
  @current_step = nil
@@ -47,32 +49,6 @@ module Aidp
47
49
  restore_screen
48
50
  end
49
51
 
50
- # Job monitoring methods
51
- def add_job(job_id, job_data)
52
- @jobs[job_id] = {
53
- id: job_id,
54
- name: job_data[:name] || job_id,
55
- status: job_data[:status] || :pending,
56
- progress: job_data[:progress] || 0,
57
- started_at: Time.now,
58
- message: job_data[:message] || "",
59
- provider: job_data[:provider] || "unknown"
60
- }
61
- @jobs_visible = true
62
- end
63
-
64
- def update_job(job_id, updates)
65
- return unless @jobs[job_id]
66
-
67
- @jobs[job_id].merge!(updates)
68
- @jobs[job_id][:updated_at] = Time.now
69
- end
70
-
71
- def remove_job(job_id)
72
- @jobs.delete(job_id)
73
- @jobs_visible = @jobs.any?
74
- end
75
-
76
52
  # Input methods using TTY::Prompt only - no background threads
77
53
  def get_user_input(prompt = "💬 You: ")
78
54
  @prompt.ask(prompt)
@@ -31,9 +31,9 @@ module Aidp
31
31
  urgent: "Urgent"
32
32
  }.freeze
33
33
 
34
- def initialize(ui_components = {})
34
+ def initialize(ui_components = {}, prompt: TTY::Prompt.new)
35
35
  super()
36
- @prompt = TTY::Prompt.new
36
+ @prompt = prompt
37
37
  @pastel = Pastel.new
38
38
  @status_manager = ui_components[:status_manager] || StatusManager.new
39
39
  @frame_manager = ui_components[:frame_manager] || FrameManager.new
@@ -17,9 +17,9 @@ module Aidp
17
17
  class InvalidMenuError < MenuError; end
18
18
  class NavigationError < MenuError; end
19
19
 
20
- def initialize(ui_components = {})
20
+ def initialize(ui_components = {}, prompt: nil)
21
21
  super()
22
- @prompt = ui_components[:prompt] || TTY::Prompt.new
22
+ @prompt = prompt || ui_components[:prompt] || TTY::Prompt.new
23
23
  @pastel = Pastel.new
24
24
  @formatter = ui_components[:formatter] || MenuFormatter.new
25
25
  @state_manager = ui_components[:state_manager] || MenuState.new
@@ -28,9 +28,9 @@ module Aidp
28
28
  }
29
29
  }.freeze
30
30
 
31
- def initialize(ui_components = {})
31
+ def initialize(ui_components = {}, prompt: nil)
32
32
  super()
33
- @prompt = ui_components[:prompt] || TTY::Prompt.new
33
+ @prompt = prompt || ui_components[:prompt] || TTY::Prompt.new
34
34
  @pastel = Pastel.new
35
35
  @formatter = ui_components[:formatter] || WorkflowFormatter.new
36
36
  @state_manager = ui_components[:state_manager]
@@ -12,9 +12,9 @@ module Aidp
12
12
  class ValidationError < QuestionError; end
13
13
  class CollectionError < QuestionError; end
14
14
 
15
- def initialize(ui_components = {})
15
+ def initialize(ui_components = {}, prompt: nil)
16
16
  super()
17
- @prompt = ui_components[:prompt] || TTY::Prompt.new
17
+ @prompt = prompt || ui_components[:prompt] || TTY::Prompt.new
18
18
  @validator = ui_components[:validator] || QuestionValidator.new
19
19
  end
20
20
 
@@ -6,10 +6,10 @@ module Aidp
6
6
  module Harness
7
7
  # Handles user interaction and feedback collection
8
8
  class UserInterface
9
- def initialize
9
+ def initialize(prompt: TTY::Prompt.new)
10
10
  @input_history = []
11
11
  @file_selection_enabled = false
12
- @prompt = TTY::Prompt.new
12
+ @prompt = prompt
13
13
  @control_mutex = Mutex.new
14
14
  @pause_requested = false
15
15
  @stop_requested = false
data/lib/aidp/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Aidp
4
- VERSION = "0.9.4"
4
+ VERSION = "0.9.5"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aidp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.4
4
+ version: 0.9.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bart Agapinan