aidp 0.15.2 → 0.16.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 +47 -0
- data/lib/aidp/analyze/error_handler.rb +14 -15
- data/lib/aidp/analyze/runner.rb +27 -5
- data/lib/aidp/analyze/steps.rb +4 -0
- data/lib/aidp/cli/jobs_command.rb +2 -1
- data/lib/aidp/cli.rb +812 -3
- data/lib/aidp/concurrency/backoff.rb +148 -0
- data/lib/aidp/concurrency/exec.rb +192 -0
- data/lib/aidp/concurrency/wait.rb +148 -0
- data/lib/aidp/concurrency.rb +71 -0
- data/lib/aidp/config.rb +20 -0
- data/lib/aidp/daemon/runner.rb +9 -8
- data/lib/aidp/debug_mixin.rb +1 -0
- data/lib/aidp/errors.rb +12 -0
- data/lib/aidp/execute/interactive_repl.rb +102 -11
- data/lib/aidp/execute/repl_macros.rb +776 -2
- data/lib/aidp/execute/runner.rb +27 -5
- data/lib/aidp/execute/steps.rb +2 -0
- data/lib/aidp/harness/config_loader.rb +24 -2
- data/lib/aidp/harness/enhanced_runner.rb +16 -2
- data/lib/aidp/harness/error_handler.rb +1 -1
- data/lib/aidp/harness/provider_info.rb +19 -15
- data/lib/aidp/harness/provider_manager.rb +47 -41
- data/lib/aidp/harness/runner.rb +3 -11
- data/lib/aidp/harness/state/persistence.rb +1 -6
- data/lib/aidp/harness/state_manager.rb +115 -7
- data/lib/aidp/harness/status_display.rb +11 -18
- data/lib/aidp/harness/ui/navigation/submenu.rb +1 -0
- data/lib/aidp/harness/ui/workflow_controller.rb +1 -1
- data/lib/aidp/harness/user_interface.rb +12 -15
- data/lib/aidp/jobs/background_runner.rb +15 -5
- data/lib/aidp/providers/codex.rb +0 -1
- data/lib/aidp/providers/cursor.rb +0 -1
- data/lib/aidp/providers/github_copilot.rb +0 -1
- data/lib/aidp/providers/opencode.rb +0 -1
- data/lib/aidp/skills/composer.rb +178 -0
- data/lib/aidp/skills/loader.rb +205 -0
- data/lib/aidp/skills/registry.rb +220 -0
- data/lib/aidp/skills/skill.rb +174 -0
- data/lib/aidp/skills.rb +30 -0
- data/lib/aidp/version.rb +1 -1
- data/lib/aidp/watch/build_processor.rb +93 -28
- data/lib/aidp/watch/runner.rb +3 -2
- data/lib/aidp/workstream_executor.rb +244 -0
- data/lib/aidp/workstream_state.rb +212 -0
- data/lib/aidp/worktree.rb +208 -0
- data/lib/aidp.rb +6 -0
- metadata +17 -4
@@ -5,6 +5,7 @@ require "tty-spinner"
|
|
5
5
|
require_relative "async_work_loop_runner"
|
6
6
|
require_relative "repl_macros"
|
7
7
|
require_relative "../rescue_logging"
|
8
|
+
require_relative "../concurrency"
|
8
9
|
|
9
10
|
module Aidp
|
10
11
|
module Execute
|
@@ -32,6 +33,7 @@ module Aidp
|
|
32
33
|
@repl_macros = ReplMacros.new
|
33
34
|
@output_display_thread = nil
|
34
35
|
@running = false
|
36
|
+
@completion_setup_needed = true
|
35
37
|
end
|
36
38
|
|
37
39
|
# Start work loop and enter interactive REPL
|
@@ -96,10 +98,18 @@ module Aidp
|
|
96
98
|
|
97
99
|
# Read command with timeout to allow checking work loop status
|
98
100
|
def read_command_with_timeout
|
99
|
-
# Use
|
100
|
-
|
101
|
-
|
102
|
-
|
101
|
+
# Use Reline for readline-style editing with tab completion
|
102
|
+
require "reline"
|
103
|
+
setup_completion if @completion_setup_needed
|
104
|
+
|
105
|
+
print_prompt_text
|
106
|
+
Reline.output = $stdout
|
107
|
+
Reline.input = $stdin
|
108
|
+
Reline.completion_append_character = " "
|
109
|
+
|
110
|
+
command = Reline.readline("", false)
|
111
|
+
return nil if command.nil? # Ctrl-D
|
112
|
+
|
103
113
|
command&.strip
|
104
114
|
rescue => e
|
105
115
|
log_rescue(e, component: "interactive_repl", action: "read_command", fallback: nil)
|
@@ -107,26 +117,106 @@ module Aidp
|
|
107
117
|
nil
|
108
118
|
end
|
109
119
|
|
110
|
-
#
|
111
|
-
def
|
120
|
+
# Setup tab completion for REPL commands
|
121
|
+
def setup_completion
|
122
|
+
require "reline"
|
123
|
+
|
124
|
+
# Define completion proc
|
125
|
+
Reline.completion_proc = proc do |input|
|
126
|
+
# Get list of commands from repl_macros
|
127
|
+
all_commands = @repl_macros.list_commands
|
128
|
+
|
129
|
+
# Extract the word being completed
|
130
|
+
words = input.split(/\s+/)
|
131
|
+
current_word = words.last || ""
|
132
|
+
|
133
|
+
# If we're completing the first word (command), offer command names
|
134
|
+
if words.size <= 1 || (words.size == 1 && !input.end_with?(" "))
|
135
|
+
all_commands.select { |cmd| cmd.start_with?(current_word) }
|
136
|
+
# If completing after /ws, offer subcommands
|
137
|
+
elsif words.first == "/ws"
|
138
|
+
if words.size == 2 && !input.end_with?(" ")
|
139
|
+
# Completing subcommand
|
140
|
+
subcommands = %w[list new switch rm status pause resume complete dashboard pause-all resume-all stop-all]
|
141
|
+
subcommands.select { |sc| sc.start_with?(current_word) }
|
142
|
+
elsif %w[switch rm status pause resume complete].include?(words[1])
|
143
|
+
# Completing workstream slug
|
144
|
+
require_relative "../worktree"
|
145
|
+
workstreams = Aidp::Worktree.list(project_dir: @project_dir)
|
146
|
+
slugs = workstreams.map { |ws| ws[:slug] }
|
147
|
+
slugs.select { |slug| slug.start_with?(current_word) }
|
148
|
+
else
|
149
|
+
[]
|
150
|
+
end
|
151
|
+
# If completing after /skill, offer subcommands or skill IDs
|
152
|
+
elsif words.first == "/skill"
|
153
|
+
if words.size == 2 && !input.end_with?(" ")
|
154
|
+
# Completing subcommand
|
155
|
+
subcommands = %w[list show search]
|
156
|
+
subcommands.select { |sc| sc.start_with?(current_word) }
|
157
|
+
elsif %w[show].include?(words[1])
|
158
|
+
# Completing skill ID
|
159
|
+
require_relative "../skills"
|
160
|
+
registry = Aidp::Skills::Registry.new(project_dir: @project_dir)
|
161
|
+
registry.load_skills
|
162
|
+
skill_ids = registry.all.map(&:id)
|
163
|
+
skill_ids.select { |id| id.start_with?(current_word) }
|
164
|
+
else
|
165
|
+
[]
|
166
|
+
end
|
167
|
+
else
|
168
|
+
[]
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
@completion_setup_needed = false
|
173
|
+
end
|
174
|
+
|
175
|
+
# Print REPL prompt text (for Reline)
|
176
|
+
def print_prompt_text
|
112
177
|
status = @async_runner.status
|
113
178
|
state = status[:state]
|
114
179
|
iteration = status[:iteration]
|
115
180
|
queued = status.dig(:queued_instructions, :total) || 0
|
181
|
+
# Workstream context (if any)
|
182
|
+
current_ws = if @repl_macros.respond_to?(:current_workstream)
|
183
|
+
@repl_macros.current_workstream
|
184
|
+
elsif @repl_macros.instance_variable_defined?(:@current_workstream)
|
185
|
+
@repl_macros.instance_variable_get(:@current_workstream)
|
186
|
+
end
|
187
|
+
|
188
|
+
ws_fragment = ""
|
189
|
+
if current_ws
|
190
|
+
begin
|
191
|
+
require_relative "../workstream_state"
|
192
|
+
ws_state = Aidp::WorkstreamState.read(slug: current_ws, project_dir: @project_dir) || {}
|
193
|
+
iter = ws_state[:iterations] || 0
|
194
|
+
elapsed = Aidp::WorkstreamState.elapsed_seconds(slug: current_ws, project_dir: @project_dir)
|
195
|
+
ws_fragment = "|ws:#{current_ws}:#{iter}i/#{elapsed}s"
|
196
|
+
rescue
|
197
|
+
ws_fragment = "|ws:#{current_ws}"
|
198
|
+
end
|
199
|
+
end
|
116
200
|
|
117
201
|
prompt_text = case state
|
118
202
|
when "RUNNING"
|
119
|
-
"aidp[#{iteration}]"
|
203
|
+
"aidp[#{iteration}#{ws_fragment}]"
|
120
204
|
when "PAUSED"
|
121
|
-
"aidp[#{iteration}|PAUSED]"
|
205
|
+
"aidp[#{iteration}|PAUSED#{ws_fragment}]"
|
206
|
+
when "CANCELLED"
|
207
|
+
"aidp[#{iteration}|CANCELLED#{ws_fragment}]"
|
208
|
+
when "IDLE"
|
209
|
+
queued_suffix = (queued > 0) ? "+#{queued}" : ""
|
210
|
+
"aidp[#{iteration}#{queued_suffix}#{ws_fragment}]"
|
122
211
|
else
|
123
|
-
"aidp"
|
212
|
+
"aidp[#{iteration}#{ws_fragment}]"
|
124
213
|
end
|
125
214
|
|
126
|
-
prompt_text += "
|
127
|
-
print
|
215
|
+
prompt_text += " > "
|
216
|
+
print prompt_text
|
128
217
|
end
|
129
218
|
|
219
|
+
# Print REPL prompt
|
130
220
|
# Handle REPL command
|
131
221
|
def handle_command(command)
|
132
222
|
return if command.empty?
|
@@ -312,6 +402,7 @@ module Aidp
|
|
312
402
|
@prompt.say(" /merge <plan> - Update plan/contract")
|
313
403
|
@prompt.say(" /update guard <key>=<value> - Update guard rails")
|
314
404
|
@prompt.say(" /rollback <n>, /undo last - Rollback commits")
|
405
|
+
@prompt.say(" /skill list, /skill show <id> - Manage skills/personas")
|
315
406
|
@prompt.say(" /status - Show current state")
|
316
407
|
@prompt.say(" /help - Show all commands")
|
317
408
|
@prompt.say("\nPress Ctrl-C for interrupt menu")
|