aidp 0.15.2 → 0.17.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 +46 -28
- data/lib/aidp/analyze/progress.rb +1 -1
- 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 +1086 -4
- 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 +21 -1
- 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/async_work_loop_runner.rb +2 -1
- data/lib/aidp/execute/checkpoint.rb +1 -1
- data/lib/aidp/execute/future_work_backlog.rb +1 -1
- data/lib/aidp/execute/interactive_repl.rb +102 -11
- data/lib/aidp/execute/progress.rb +1 -1
- data/lib/aidp/execute/repl_macros.rb +845 -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/config_validator.rb +1 -1
- 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 +16 -6
- 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 +222 -0
- data/lib/aidp/skills/router.rb +178 -0
- data/lib/aidp/skills/skill.rb +174 -0
- data/lib/aidp/skills/wizard/builder.rb +141 -0
- data/lib/aidp/skills/wizard/controller.rb +145 -0
- data/lib/aidp/skills/wizard/differ.rb +232 -0
- data/lib/aidp/skills/wizard/prompter.rb +317 -0
- data/lib/aidp/skills/wizard/template_library.rb +164 -0
- data/lib/aidp/skills/wizard/writer.rb +105 -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
- data/templates/skills/README.md +334 -0
- data/templates/skills/architecture_analyst/SKILL.md +173 -0
- data/templates/skills/product_strategist/SKILL.md +141 -0
- data/templates/skills/repository_analyst/SKILL.md +117 -0
- data/templates/skills/test_analyzer/SKILL.md +213 -0
- metadata +29 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 84451cdcc0886f1a70e799ab53d9b8898633f324cdd80c5f07a5f204848a3de2
|
|
4
|
+
data.tar.gz: e93982382c700564db24fac6ff1de2276e5b0301b91f6cade19aa8dfacd3f7d3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3de783cb25c3eedc9056f77c2b294918a2f5ab46c009280897b6094dd157c45c681fc5c8fe22c6eea401ba74e0c4151c132a85e3c8ceedfef7722e9580f96f43
|
|
7
|
+
data.tar.gz: de86c77e08a8f9b837d501d8e69786b6f969c0e2a1538f1a9d2062267f01d6e8c855f0885c31d0bdc3f2c9362fa78439fccdcfe5e09a12cd1ab61282365cdc4a
|
data/README.md
CHANGED
|
@@ -93,6 +93,34 @@ aidp checkpoint history 20
|
|
|
93
93
|
- PRD task completion percentage
|
|
94
94
|
- File count and growth trends
|
|
95
95
|
|
|
96
|
+
### Parallel Workstreams
|
|
97
|
+
|
|
98
|
+
Work on multiple tasks simultaneously using isolated git worktrees:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
# Create a workstream for each task
|
|
102
|
+
aidp ws new issue-123-fix-auth
|
|
103
|
+
aidp ws new feature-dashboard
|
|
104
|
+
|
|
105
|
+
# List all workstreams
|
|
106
|
+
aidp ws list
|
|
107
|
+
|
|
108
|
+
# Check status
|
|
109
|
+
aidp ws status issue-123-fix-auth
|
|
110
|
+
|
|
111
|
+
# Remove when complete
|
|
112
|
+
aidp ws rm issue-123-fix-auth --delete-branch
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
**Benefits:**
|
|
116
|
+
|
|
117
|
+
- Complete isolation between tasks
|
|
118
|
+
- Separate git branches for each workstream
|
|
119
|
+
- Independent state and history
|
|
120
|
+
- Work on multiple features in parallel
|
|
121
|
+
|
|
122
|
+
See [Workstreams Guide](docs/WORKSTREAMS.md) for detailed usage.
|
|
123
|
+
|
|
96
124
|
## Command Reference
|
|
97
125
|
|
|
98
126
|
### Copilot Mode
|
|
@@ -147,6 +175,25 @@ aidp checkpoint clear
|
|
|
147
175
|
aidp checkpoint clear --force # Skip confirmation
|
|
148
176
|
```
|
|
149
177
|
|
|
178
|
+
### Workstream Commands
|
|
179
|
+
|
|
180
|
+
```bash
|
|
181
|
+
# Create a new workstream
|
|
182
|
+
aidp ws new <slug>
|
|
183
|
+
aidp ws new <slug> --base-branch <branch>
|
|
184
|
+
|
|
185
|
+
# List all workstreams
|
|
186
|
+
aidp ws list
|
|
187
|
+
|
|
188
|
+
# Check workstream status
|
|
189
|
+
aidp ws status <slug>
|
|
190
|
+
|
|
191
|
+
# Remove a workstream
|
|
192
|
+
aidp ws rm <slug>
|
|
193
|
+
aidp ws rm <slug> --delete-branch # Also delete git branch
|
|
194
|
+
aidp ws rm <slug> --force # Skip confirmation
|
|
195
|
+
```
|
|
196
|
+
|
|
150
197
|
### System Commands
|
|
151
198
|
|
|
152
199
|
```bash
|
|
@@ -1,6 +1,19 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "logger"
|
|
4
|
+
require_relative "../concurrency"
|
|
5
|
+
|
|
6
|
+
begin
|
|
7
|
+
require "net/http"
|
|
8
|
+
rescue LoadError
|
|
9
|
+
# Net::HTTP might not be available in all environments
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
begin
|
|
13
|
+
require "sqlite3"
|
|
14
|
+
rescue LoadError
|
|
15
|
+
# SQLite3 might not be available in all environments
|
|
16
|
+
end
|
|
4
17
|
|
|
5
18
|
module Aidp
|
|
6
19
|
module Analyze
|
|
@@ -23,7 +36,7 @@ module Aidp
|
|
|
23
36
|
context: context,
|
|
24
37
|
step: step,
|
|
25
38
|
retry_count: retry_count,
|
|
26
|
-
timestamp: Time.
|
|
39
|
+
timestamp: Time.now
|
|
27
40
|
}
|
|
28
41
|
|
|
29
42
|
log_error(error_info)
|
|
@@ -38,21 +51,19 @@ module Aidp
|
|
|
38
51
|
|
|
39
52
|
# Recovery strategies
|
|
40
53
|
def retry_with_backoff(operation, max_retries: 3, base_delay: 1)
|
|
41
|
-
|
|
42
|
-
|
|
54
|
+
Aidp::Concurrency::Backoff.retry(
|
|
55
|
+
max_attempts: max_retries,
|
|
56
|
+
base: base_delay,
|
|
57
|
+
strategy: :exponential,
|
|
58
|
+
jitter: 0.2,
|
|
59
|
+
on: [StandardError]
|
|
60
|
+
) do
|
|
43
61
|
operation.call
|
|
44
|
-
rescue => e
|
|
45
|
-
retry_count += 1
|
|
46
|
-
if retry_count <= max_retries
|
|
47
|
-
delay = base_delay * (2**(retry_count - 1))
|
|
48
|
-
logger.warn("Retrying operation in #{delay} seconds (attempt #{retry_count}/#{max_retries})")
|
|
49
|
-
Async::Task.current.sleep(delay)
|
|
50
|
-
retry
|
|
51
|
-
else
|
|
52
|
-
logger.error("Operation failed after #{max_retries} retries: #{e.message}")
|
|
53
|
-
raise e
|
|
54
|
-
end
|
|
55
62
|
end
|
|
63
|
+
rescue Aidp::Concurrency::MaxAttemptsError => e
|
|
64
|
+
logger.error("Operation failed after #{max_retries} retries")
|
|
65
|
+
# Re-raise the MaxAttemptsError to preserve error chain and context
|
|
66
|
+
raise e
|
|
56
67
|
end
|
|
57
68
|
|
|
58
69
|
def skip_step_with_warning(step_name, error)
|
|
@@ -60,7 +71,7 @@ module Aidp
|
|
|
60
71
|
{
|
|
61
72
|
status: "skipped",
|
|
62
73
|
reason: error.message,
|
|
63
|
-
timestamp: Time.
|
|
74
|
+
timestamp: Time.now
|
|
64
75
|
}
|
|
65
76
|
end
|
|
66
77
|
|
|
@@ -89,8 +100,8 @@ module Aidp
|
|
|
89
100
|
|
|
90
101
|
def setup_logger(log_file, verbose)
|
|
91
102
|
output_stream = log_file || @output || $stdout
|
|
92
|
-
logger = Logger.new(output_stream)
|
|
93
|
-
logger.level = verbose ? Logger::DEBUG : Logger::INFO
|
|
103
|
+
logger = ::Logger.new(output_stream)
|
|
104
|
+
logger.level = verbose ? ::Logger::DEBUG : ::Logger::INFO
|
|
94
105
|
logger.formatter = proc do |severity, datetime, progname, msg|
|
|
95
106
|
"#{datetime.strftime("%Y-%m-%d %H:%M:%S")} [#{severity}] #{msg}\n"
|
|
96
107
|
end
|
|
@@ -98,19 +109,28 @@ module Aidp
|
|
|
98
109
|
end
|
|
99
110
|
|
|
100
111
|
def setup_recovery_strategies
|
|
101
|
-
{
|
|
102
|
-
Net::TimeoutError => :retry_with_backoff,
|
|
103
|
-
Net::HTTPError => :retry_with_backoff,
|
|
104
|
-
SocketError => :retry_with_backoff,
|
|
112
|
+
strategies = {
|
|
105
113
|
Errno::ENOENT => :skip_step_with_warning,
|
|
106
114
|
Errno::EACCES => :skip_step_with_warning,
|
|
107
115
|
Errno::ENOSPC => :critical_error,
|
|
108
|
-
SQLite3::BusyException => :retry_with_backoff,
|
|
109
|
-
SQLite3::CorruptException => :critical_error,
|
|
110
116
|
AnalysisTimeoutError => :chunk_and_retry,
|
|
111
117
|
AnalysisDataError => :continue_with_partial_data,
|
|
112
118
|
AnalysisToolError => :log_and_continue
|
|
113
119
|
}
|
|
120
|
+
|
|
121
|
+
# Add network error classes if available
|
|
122
|
+
strategies[Net::TimeoutError] = :retry_with_backoff if defined?(Net::TimeoutError)
|
|
123
|
+
|
|
124
|
+
strategies[Net::HTTPError] = :retry_with_backoff if defined?(Net::HTTPError)
|
|
125
|
+
|
|
126
|
+
strategies[SocketError] = :retry_with_backoff if defined?(SocketError)
|
|
127
|
+
|
|
128
|
+
# Add SQLite error classes if available
|
|
129
|
+
strategies[SQLite3::BusyException] = :retry_with_backoff if defined?(SQLite3::BusyException)
|
|
130
|
+
|
|
131
|
+
strategies[SQLite3::CorruptException] = :critical_error if defined?(SQLite3::CorruptException)
|
|
132
|
+
|
|
133
|
+
strategies
|
|
114
134
|
end
|
|
115
135
|
|
|
116
136
|
def log_error(error_info)
|
|
@@ -176,8 +196,8 @@ module Aidp
|
|
|
176
196
|
logger.warn("HTTP error: #{error.message}")
|
|
177
197
|
case error.response&.code
|
|
178
198
|
when "429" # Rate limited
|
|
179
|
-
|
|
180
|
-
retry_with_backoff(-> { context[:operation].call }, max_retries: 2)
|
|
199
|
+
# For rate limiting, use longer base delay
|
|
200
|
+
retry_with_backoff(-> { context[:operation].call }, max_retries: 2, base_delay: 60)
|
|
181
201
|
when "500".."599" # Server errors
|
|
182
202
|
retry_with_backoff(-> { context[:operation].call }, max_retries: 3)
|
|
183
203
|
else
|
|
@@ -251,9 +271,7 @@ module Aidp
|
|
|
251
271
|
tool_name = context[:tool_name] || "analysis tool"
|
|
252
272
|
error_msg = "#{tool_name} failed: #{error.message}"
|
|
253
273
|
|
|
254
|
-
if context[:installation_guide]
|
|
255
|
-
error_msg += "\n\nTo install #{tool_name}:\n#{context[:installation_guide]}"
|
|
256
|
-
end
|
|
274
|
+
error_msg += "\n\nTo install #{tool_name}:\n#{context[:installation_guide]}" if context[:installation_guide]
|
|
257
275
|
|
|
258
276
|
raise AnalysisToolError.new(error_msg)
|
|
259
277
|
end
|
data/lib/aidp/analyze/runner.rb
CHANGED
|
@@ -5,6 +5,7 @@ require_relative "steps"
|
|
|
5
5
|
require_relative "progress"
|
|
6
6
|
require_relative "../storage/file_manager"
|
|
7
7
|
require_relative "../debug_mixin"
|
|
8
|
+
require_relative "../skills"
|
|
8
9
|
|
|
9
10
|
module Aidp
|
|
10
11
|
module Analyze
|
|
@@ -18,6 +19,8 @@ module Aidp
|
|
|
18
19
|
@is_harness_mode = !harness_runner.nil?
|
|
19
20
|
@file_manager = Aidp::Storage::FileManager.new(File.join(project_dir, ".aidp"))
|
|
20
21
|
@prompt = prompt
|
|
22
|
+
@skills_registry = nil # Lazy-loaded
|
|
23
|
+
@skills_composer = Aidp::Skills::Composer.new
|
|
21
24
|
end
|
|
22
25
|
|
|
23
26
|
def progress
|
|
@@ -199,18 +202,37 @@ module Aidp
|
|
|
199
202
|
step_spec = Aidp::Analyze::Steps::SPEC[step_name]
|
|
200
203
|
raise "Step '#{step_name}' not found" unless step_spec
|
|
201
204
|
|
|
205
|
+
# Load template
|
|
202
206
|
template_name = step_spec["templates"].first
|
|
203
207
|
template_path = find_template(template_name)
|
|
204
208
|
raise "Template not found for step #{step_name}" unless template_path
|
|
205
|
-
|
|
206
209
|
template = File.read(template_path)
|
|
207
210
|
|
|
208
|
-
#
|
|
209
|
-
|
|
210
|
-
|
|
211
|
+
# Load skill if specified
|
|
212
|
+
skill = nil
|
|
213
|
+
if step_spec["skill"]
|
|
214
|
+
skill = skills_registry.find(step_spec["skill"])
|
|
215
|
+
if skill.nil?
|
|
216
|
+
Aidp.log_warn(
|
|
217
|
+
"skills",
|
|
218
|
+
"Skill not found for step",
|
|
219
|
+
step: step_name,
|
|
220
|
+
skill_id: step_spec["skill"]
|
|
221
|
+
)
|
|
222
|
+
end
|
|
211
223
|
end
|
|
212
224
|
|
|
213
|
-
template
|
|
225
|
+
# Compose skill + template
|
|
226
|
+
@skills_composer.compose(skill: skill, template: template, options: options)
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
def skills_registry
|
|
230
|
+
@skills_registry ||= begin
|
|
231
|
+
provider = get_harness_provider_safely if @is_harness_mode
|
|
232
|
+
registry = Aidp::Skills::Registry.new(project_dir: @project_dir, provider: provider)
|
|
233
|
+
registry.load_skills
|
|
234
|
+
registry
|
|
235
|
+
end
|
|
214
236
|
end
|
|
215
237
|
|
|
216
238
|
# Compose prompt with harness context and user input
|
data/lib/aidp/analyze/steps.rb
CHANGED
|
@@ -5,20 +5,24 @@ module Aidp
|
|
|
5
5
|
module Steps
|
|
6
6
|
# Analysis step specifications
|
|
7
7
|
# Templates are organized by purpose and named with action verbs
|
|
8
|
+
# Skills define WHO the agent is, templates define WHAT task to do
|
|
8
9
|
SPEC = {
|
|
9
10
|
"01_REPOSITORY_ANALYSIS" => {
|
|
11
|
+
"skill" => "repository_analyst",
|
|
10
12
|
"templates" => ["analysis/analyze_repository.md"],
|
|
11
13
|
"description" => "Initial code-maat based repository mining",
|
|
12
14
|
"outs" => ["docs/analysis/repository_analysis.md"],
|
|
13
15
|
"gate" => false
|
|
14
16
|
},
|
|
15
17
|
"02_ARCHITECTURE_ANALYSIS" => {
|
|
18
|
+
"skill" => "architecture_analyst",
|
|
16
19
|
"templates" => ["analysis/analyze_architecture.md"],
|
|
17
20
|
"description" => "Identify architectural patterns, dependencies, and violations",
|
|
18
21
|
"outs" => ["docs/analysis/architecture_analysis.md"],
|
|
19
22
|
"gate" => true
|
|
20
23
|
},
|
|
21
24
|
"03_TEST_ANALYSIS" => {
|
|
25
|
+
"skill" => "test_analyzer",
|
|
22
26
|
"templates" => ["analysis/analyze_tests.md"],
|
|
23
27
|
"description" => "Analyze existing test coverage and identify gaps",
|
|
24
28
|
"outs" => ["docs/analysis/test_analysis.md"],
|
|
@@ -206,7 +206,8 @@ module Aidp
|
|
|
206
206
|
# Exit if job is done
|
|
207
207
|
break unless status[:running]
|
|
208
208
|
|
|
209
|
-
#
|
|
209
|
+
# Periodic status polling - acceptable for UI updates
|
|
210
|
+
# Alternative: event-driven updates via IPC/file watching
|
|
210
211
|
sleep 2
|
|
211
212
|
end
|
|
212
213
|
rescue Interrupt
|