aidp 0.24.0 → 0.26.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 +72 -7
- data/lib/aidp/analyze/error_handler.rb +11 -0
- data/lib/aidp/auto_update/bundler_adapter.rb +66 -0
- data/lib/aidp/auto_update/checkpoint.rb +178 -0
- data/lib/aidp/auto_update/checkpoint_store.rb +182 -0
- data/lib/aidp/auto_update/coordinator.rb +204 -0
- data/lib/aidp/auto_update/errors.rb +17 -0
- data/lib/aidp/auto_update/failure_tracker.rb +162 -0
- data/lib/aidp/auto_update/rubygems_api_adapter.rb +95 -0
- data/lib/aidp/auto_update/update_check.rb +106 -0
- data/lib/aidp/auto_update/update_logger.rb +143 -0
- data/lib/aidp/auto_update/update_policy.rb +109 -0
- data/lib/aidp/auto_update/version_detector.rb +144 -0
- data/lib/aidp/auto_update.rb +52 -0
- data/lib/aidp/cli.rb +165 -1
- data/lib/aidp/execute/work_loop_runner.rb +225 -55
- data/lib/aidp/harness/config_loader.rb +20 -11
- data/lib/aidp/harness/config_schema.rb +80 -8
- data/lib/aidp/harness/configuration.rb +73 -2
- data/lib/aidp/harness/filter_strategy.rb +45 -0
- data/lib/aidp/harness/generic_filter_strategy.rb +63 -0
- data/lib/aidp/harness/output_filter.rb +136 -0
- data/lib/aidp/harness/provider_factory.rb +2 -0
- data/lib/aidp/harness/provider_manager.rb +18 -3
- data/lib/aidp/harness/rspec_filter_strategy.rb +82 -0
- data/lib/aidp/harness/test_runner.rb +165 -27
- data/lib/aidp/harness/ui/enhanced_tui.rb +4 -1
- data/lib/aidp/logger.rb +35 -5
- data/lib/aidp/message_display.rb +56 -2
- data/lib/aidp/prompt_optimization/style_guide_indexer.rb +3 -1
- data/lib/aidp/provider_manager.rb +2 -0
- data/lib/aidp/providers/kilocode.rb +202 -0
- data/lib/aidp/safe_directory.rb +10 -3
- data/lib/aidp/setup/provider_registry.rb +15 -0
- data/lib/aidp/setup/wizard.rb +12 -4
- data/lib/aidp/skills/composer.rb +4 -0
- data/lib/aidp/skills/loader.rb +3 -1
- data/lib/aidp/storage/csv_storage.rb +9 -3
- data/lib/aidp/storage/file_manager.rb +8 -2
- data/lib/aidp/storage/json_storage.rb +9 -3
- data/lib/aidp/version.rb +1 -1
- data/lib/aidp/watch/build_processor.rb +106 -17
- data/lib/aidp/watch/change_request_processor.rb +659 -0
- data/lib/aidp/watch/ci_fix_processor.rb +448 -0
- data/lib/aidp/watch/plan_processor.rb +81 -8
- data/lib/aidp/watch/repository_client.rb +465 -20
- data/lib/aidp/watch/review_processor.rb +266 -0
- data/lib/aidp/watch/reviewers/base_reviewer.rb +164 -0
- data/lib/aidp/watch/reviewers/performance_reviewer.rb +65 -0
- data/lib/aidp/watch/reviewers/security_reviewer.rb +65 -0
- data/lib/aidp/watch/reviewers/senior_dev_reviewer.rb +33 -0
- data/lib/aidp/watch/runner.rb +222 -0
- data/lib/aidp/watch/state_store.rb +99 -1
- data/lib/aidp/workstream_executor.rb +5 -2
- data/lib/aidp.rb +5 -0
- data/templates/aidp.yml.example +53 -0
- metadata +25 -1
data/lib/aidp/watch/runner.rb
CHANGED
|
@@ -9,6 +9,10 @@ require_relative "state_store"
|
|
|
9
9
|
require_relative "plan_generator"
|
|
10
10
|
require_relative "plan_processor"
|
|
11
11
|
require_relative "build_processor"
|
|
12
|
+
require_relative "../auto_update"
|
|
13
|
+
require_relative "review_processor"
|
|
14
|
+
require_relative "ci_fix_processor"
|
|
15
|
+
require_relative "change_request_processor"
|
|
12
16
|
|
|
13
17
|
module Aidp
|
|
14
18
|
module Watch
|
|
@@ -26,6 +30,8 @@ module Aidp
|
|
|
26
30
|
@project_dir = project_dir
|
|
27
31
|
@force = force
|
|
28
32
|
@verbose = verbose
|
|
33
|
+
@provider_name = provider_name
|
|
34
|
+
@safety_config = safety_config
|
|
29
35
|
|
|
30
36
|
owner, repo = RepositoryClient.parse_issues_url(issues_url)
|
|
31
37
|
@repository_client = RepositoryClient.new(owner: owner, repo: repo, gh_available: gh_available)
|
|
@@ -52,9 +58,42 @@ module Aidp
|
|
|
52
58
|
verbose: verbose,
|
|
53
59
|
label_config: label_config
|
|
54
60
|
)
|
|
61
|
+
|
|
62
|
+
# Initialize auto-update coordinator
|
|
63
|
+
@auto_update_coordinator = Aidp::AutoUpdate.coordinator(project_dir: project_dir)
|
|
64
|
+
@last_update_check = nil
|
|
65
|
+
@review_processor = ReviewProcessor.new(
|
|
66
|
+
repository_client: @repository_client,
|
|
67
|
+
state_store: @state_store,
|
|
68
|
+
provider_name: provider_name,
|
|
69
|
+
project_dir: project_dir,
|
|
70
|
+
label_config: label_config,
|
|
71
|
+
verbose: verbose
|
|
72
|
+
)
|
|
73
|
+
@ci_fix_processor = CiFixProcessor.new(
|
|
74
|
+
repository_client: @repository_client,
|
|
75
|
+
state_store: @state_store,
|
|
76
|
+
provider_name: provider_name,
|
|
77
|
+
project_dir: project_dir,
|
|
78
|
+
label_config: label_config,
|
|
79
|
+
verbose: verbose
|
|
80
|
+
)
|
|
81
|
+
@change_request_processor = ChangeRequestProcessor.new(
|
|
82
|
+
repository_client: @repository_client,
|
|
83
|
+
state_store: @state_store,
|
|
84
|
+
provider_name: provider_name,
|
|
85
|
+
project_dir: project_dir,
|
|
86
|
+
label_config: label_config,
|
|
87
|
+
change_request_config: safety_config[:pr_change_requests] || safety_config["pr_change_requests"] || {},
|
|
88
|
+
safety_config: safety_config[:safety] || safety_config["safety"] || {},
|
|
89
|
+
verbose: verbose
|
|
90
|
+
)
|
|
55
91
|
end
|
|
56
92
|
|
|
57
93
|
def start
|
|
94
|
+
# Check for and restore from checkpoint (after auto-update)
|
|
95
|
+
restore_from_checkpoint_if_exists
|
|
96
|
+
|
|
58
97
|
# Validate safety requirements before starting
|
|
59
98
|
@safety_checker.validate_watch_mode_safety!(force: @force)
|
|
60
99
|
|
|
@@ -91,6 +130,10 @@ module Aidp
|
|
|
91
130
|
def process_cycle
|
|
92
131
|
process_plan_triggers
|
|
93
132
|
process_build_triggers
|
|
133
|
+
check_for_updates_if_due
|
|
134
|
+
process_review_triggers
|
|
135
|
+
process_ci_fix_triggers
|
|
136
|
+
process_change_request_triggers
|
|
94
137
|
end
|
|
95
138
|
|
|
96
139
|
def process_plan_triggers
|
|
@@ -149,12 +192,191 @@ module Aidp
|
|
|
149
192
|
end
|
|
150
193
|
end
|
|
151
194
|
|
|
195
|
+
def process_review_triggers
|
|
196
|
+
review_label = @review_processor.review_label
|
|
197
|
+
prs = @repository_client.list_pull_requests(labels: [review_label], state: "open")
|
|
198
|
+
Aidp.log_debug("watch_runner", "review_poll", label: review_label, total: prs.size)
|
|
199
|
+
prs.each do |pr|
|
|
200
|
+
unless pr_has_label?(pr, review_label)
|
|
201
|
+
Aidp.log_debug("watch_runner", "review_skip_label_mismatch", pr: pr[:number], labels: pr[:labels])
|
|
202
|
+
next
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
detailed = @repository_client.fetch_pull_request(pr[:number])
|
|
206
|
+
|
|
207
|
+
# Check author authorization before processing
|
|
208
|
+
unless @safety_checker.should_process_issue?(detailed, enforce: false)
|
|
209
|
+
Aidp.log_debug("watch_runner", "review_skip_unauthorized_author", pr: detailed[:number], author: detailed[:author])
|
|
210
|
+
next
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
Aidp.log_debug("watch_runner", "review_process", pr: detailed[:number])
|
|
214
|
+
@review_processor.process(detailed)
|
|
215
|
+
rescue RepositorySafetyChecker::UnauthorizedAuthorError => e
|
|
216
|
+
Aidp.log_warn("watch_runner", "unauthorized PR author", pr: pr[:number], error: e.message)
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
def process_ci_fix_triggers
|
|
221
|
+
ci_fix_label = @ci_fix_processor.ci_fix_label
|
|
222
|
+
prs = @repository_client.list_pull_requests(labels: [ci_fix_label], state: "open")
|
|
223
|
+
Aidp.log_debug("watch_runner", "ci_fix_poll", label: ci_fix_label, total: prs.size)
|
|
224
|
+
prs.each do |pr|
|
|
225
|
+
unless pr_has_label?(pr, ci_fix_label)
|
|
226
|
+
Aidp.log_debug("watch_runner", "ci_fix_skip_label_mismatch", pr: pr[:number], labels: pr[:labels])
|
|
227
|
+
next
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
detailed = @repository_client.fetch_pull_request(pr[:number])
|
|
231
|
+
|
|
232
|
+
# Check author authorization before processing
|
|
233
|
+
unless @safety_checker.should_process_issue?(detailed, enforce: false)
|
|
234
|
+
Aidp.log_debug("watch_runner", "ci_fix_skip_unauthorized_author", pr: detailed[:number], author: detailed[:author])
|
|
235
|
+
next
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
Aidp.log_debug("watch_runner", "ci_fix_process", pr: detailed[:number])
|
|
239
|
+
@ci_fix_processor.process(detailed)
|
|
240
|
+
rescue RepositorySafetyChecker::UnauthorizedAuthorError => e
|
|
241
|
+
Aidp.log_warn("watch_runner", "unauthorized PR author", pr: pr[:number], error: e.message)
|
|
242
|
+
end
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
def process_change_request_triggers
|
|
246
|
+
change_request_label = @change_request_processor.change_request_label
|
|
247
|
+
prs = @repository_client.list_pull_requests(labels: [change_request_label], state: "open")
|
|
248
|
+
Aidp.log_debug("watch_runner", "change_request_poll", label: change_request_label, total: prs.size)
|
|
249
|
+
prs.each do |pr|
|
|
250
|
+
unless pr_has_label?(pr, change_request_label)
|
|
251
|
+
Aidp.log_debug("watch_runner", "change_request_skip_label_mismatch", pr: pr[:number], labels: pr[:labels])
|
|
252
|
+
next
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
detailed = @repository_client.fetch_pull_request(pr[:number])
|
|
256
|
+
|
|
257
|
+
# Check author authorization before processing
|
|
258
|
+
unless @safety_checker.should_process_issue?(detailed, enforce: false)
|
|
259
|
+
Aidp.log_debug("watch_runner", "change_request_skip_unauthorized_author", pr: detailed[:number], author: detailed[:author])
|
|
260
|
+
next
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
Aidp.log_debug("watch_runner", "change_request_process", pr: detailed[:number])
|
|
264
|
+
@change_request_processor.process(detailed)
|
|
265
|
+
rescue RepositorySafetyChecker::UnauthorizedAuthorError => e
|
|
266
|
+
Aidp.log_warn("watch_runner", "unauthorized PR author", pr: pr[:number], error: e.message)
|
|
267
|
+
end
|
|
268
|
+
end
|
|
269
|
+
|
|
152
270
|
def issue_has_label?(issue, label)
|
|
153
271
|
Array(issue[:labels]).any? do |issue_label|
|
|
154
272
|
name = issue_label.is_a?(Hash) ? issue_label["name"] : issue_label.to_s
|
|
155
273
|
name.casecmp(label).zero?
|
|
156
274
|
end
|
|
157
275
|
end
|
|
276
|
+
|
|
277
|
+
# Restore from checkpoint if one exists (after auto-update)
|
|
278
|
+
def restore_from_checkpoint_if_exists
|
|
279
|
+
return unless @auto_update_coordinator.policy.enabled
|
|
280
|
+
|
|
281
|
+
checkpoint = @auto_update_coordinator.restore_from_checkpoint
|
|
282
|
+
return unless checkpoint
|
|
283
|
+
|
|
284
|
+
# Checkpoint exists and was successfully restored
|
|
285
|
+
display_message("✨ Restored from checkpoint after update to v#{Aidp::VERSION}", type: :success)
|
|
286
|
+
|
|
287
|
+
# Override instance variables with checkpoint state
|
|
288
|
+
if checkpoint.watch_mode? && checkpoint.watch_state
|
|
289
|
+
@interval = checkpoint.watch_state[:interval] || @interval
|
|
290
|
+
Aidp.log_info("watch_runner", "checkpoint_restored",
|
|
291
|
+
checkpoint_id: checkpoint.checkpoint_id,
|
|
292
|
+
interval: @interval)
|
|
293
|
+
end
|
|
294
|
+
rescue => e
|
|
295
|
+
# Log but don't fail - continue with fresh start
|
|
296
|
+
Aidp.log_error("watch_runner", "checkpoint_restore_failed",
|
|
297
|
+
error: e.message)
|
|
298
|
+
display_message("⚠️ Checkpoint restore failed, starting fresh: #{e.message}", type: :warning)
|
|
299
|
+
end
|
|
300
|
+
|
|
301
|
+
# Check for updates at appropriate intervals
|
|
302
|
+
def check_for_updates_if_due
|
|
303
|
+
return unless @auto_update_coordinator.policy.enabled
|
|
304
|
+
return unless time_for_update_check?
|
|
305
|
+
|
|
306
|
+
update_check = @auto_update_coordinator.check_for_update
|
|
307
|
+
|
|
308
|
+
if update_check.should_update?
|
|
309
|
+
display_message("🔄 Update available: #{update_check.current_version} → #{update_check.available_version}", type: :highlight)
|
|
310
|
+
display_message(" Saving checkpoint and initiating update...", type: :muted)
|
|
311
|
+
|
|
312
|
+
initiate_update(update_check)
|
|
313
|
+
# Never returns - exits with code 75
|
|
314
|
+
end
|
|
315
|
+
rescue Aidp::AutoUpdate::UpdateLoopError => e
|
|
316
|
+
# Restart loop detected - disable auto-update
|
|
317
|
+
display_message("⚠️ Auto-update disabled: #{e.message}", type: :error)
|
|
318
|
+
Aidp.log_error("watch_runner", "update_loop_detected", error: e.message)
|
|
319
|
+
rescue Aidp::AutoUpdate::UpdateError => e
|
|
320
|
+
# Non-fatal update error - log and continue
|
|
321
|
+
Aidp.log_error("watch_runner", "update_check_failed", error: e.message)
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
# Determine if it's time to check for updates
|
|
325
|
+
# @return [Boolean]
|
|
326
|
+
def time_for_update_check?
|
|
327
|
+
return true if @last_update_check.nil?
|
|
328
|
+
|
|
329
|
+
elapsed = Time.now - @last_update_check
|
|
330
|
+
elapsed >= @auto_update_coordinator.policy.check_interval_seconds
|
|
331
|
+
end
|
|
332
|
+
|
|
333
|
+
# Initiate update process: capture state, create checkpoint, exit
|
|
334
|
+
# @param update_check [Aidp::AutoUpdate::UpdateCheck] Update check result
|
|
335
|
+
def initiate_update(update_check)
|
|
336
|
+
current_state = capture_current_state
|
|
337
|
+
|
|
338
|
+
# This will exit with code 75 if successful
|
|
339
|
+
@auto_update_coordinator.initiate_update(current_state)
|
|
340
|
+
end
|
|
341
|
+
|
|
342
|
+
# Capture current watch mode state for checkpoint
|
|
343
|
+
# @return [Hash] Current state
|
|
344
|
+
def capture_current_state
|
|
345
|
+
{
|
|
346
|
+
mode: "watch",
|
|
347
|
+
watch_state: {
|
|
348
|
+
repository: @repository_client.full_repo,
|
|
349
|
+
interval: @interval,
|
|
350
|
+
provider_name: @provider_name,
|
|
351
|
+
persona: nil,
|
|
352
|
+
safety_config: @safety_config,
|
|
353
|
+
worktree_context: capture_worktree_context,
|
|
354
|
+
state_store_snapshot: @state_store.send(:state).dup
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
end
|
|
358
|
+
|
|
359
|
+
# Capture git worktree context
|
|
360
|
+
# @return [Hash] Worktree information
|
|
361
|
+
def capture_worktree_context
|
|
362
|
+
return {} unless system("git rev-parse --git-dir > /dev/null 2>&1")
|
|
363
|
+
|
|
364
|
+
{
|
|
365
|
+
branch: `git rev-parse --abbrev-ref HEAD`.strip,
|
|
366
|
+
commit_sha: `git rev-parse HEAD`.strip,
|
|
367
|
+
remote_url: `git config --get remote.origin.url`.strip
|
|
368
|
+
}
|
|
369
|
+
rescue => e
|
|
370
|
+
Aidp.log_debug("watch_runner", "worktree_context_unavailable", error: e.message)
|
|
371
|
+
{}
|
|
372
|
+
end
|
|
373
|
+
|
|
374
|
+
def pr_has_label?(pr, label)
|
|
375
|
+
Array(pr[:labels]).any? do |pr_label|
|
|
376
|
+
name = pr_label.is_a?(Hash) ? pr_label["name"] : pr_label.to_s
|
|
377
|
+
name.casecmp(label).zero?
|
|
378
|
+
end
|
|
379
|
+
end
|
|
158
380
|
end
|
|
159
381
|
end
|
|
160
382
|
end
|
|
@@ -27,14 +27,26 @@ module Aidp
|
|
|
27
27
|
plans[issue_number.to_s]
|
|
28
28
|
end
|
|
29
29
|
|
|
30
|
+
def plan_iteration_count(issue_number)
|
|
31
|
+
plan = plans[issue_number.to_s]
|
|
32
|
+
return 0 unless plan
|
|
33
|
+
plan["iteration"] || 1
|
|
34
|
+
end
|
|
35
|
+
|
|
30
36
|
def record_plan(issue_number, data)
|
|
37
|
+
existing_plan = plans[issue_number.to_s]
|
|
38
|
+
iteration = existing_plan ? (existing_plan["iteration"] || 1) + 1 : 1
|
|
39
|
+
|
|
31
40
|
payload = {
|
|
32
41
|
"summary" => data[:summary],
|
|
33
42
|
"tasks" => data[:tasks],
|
|
34
43
|
"questions" => data[:questions],
|
|
35
44
|
"comment_body" => data[:comment_body],
|
|
36
45
|
"comment_hint" => data[:comment_hint],
|
|
37
|
-
"
|
|
46
|
+
"comment_id" => data[:comment_id],
|
|
47
|
+
"posted_at" => data[:posted_at] || Time.now.utc.iso8601,
|
|
48
|
+
"iteration" => iteration,
|
|
49
|
+
"previous_iteration_at" => existing_plan ? existing_plan["posted_at"] : nil
|
|
38
50
|
}.compact
|
|
39
51
|
|
|
40
52
|
plans[issue_number.to_s] = payload
|
|
@@ -53,6 +65,77 @@ module Aidp
|
|
|
53
65
|
save!
|
|
54
66
|
end
|
|
55
67
|
|
|
68
|
+
# Review tracking methods
|
|
69
|
+
def review_processed?(pr_number)
|
|
70
|
+
reviews.key?(pr_number.to_s)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def review_data(pr_number)
|
|
74
|
+
reviews[pr_number.to_s]
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def record_review(pr_number, data)
|
|
78
|
+
payload = {
|
|
79
|
+
"timestamp" => data[:timestamp] || Time.now.utc.iso8601,
|
|
80
|
+
"reviewers" => data[:reviewers],
|
|
81
|
+
"total_findings" => data[:total_findings]
|
|
82
|
+
}.compact
|
|
83
|
+
|
|
84
|
+
reviews[pr_number.to_s] = payload
|
|
85
|
+
save!
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# CI fix tracking methods
|
|
89
|
+
def ci_fix_completed?(pr_number)
|
|
90
|
+
fix_data = ci_fixes[pr_number.to_s]
|
|
91
|
+
fix_data && fix_data["status"] == "completed"
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def ci_fix_data(pr_number)
|
|
95
|
+
ci_fixes[pr_number.to_s]
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def record_ci_fix(pr_number, data)
|
|
99
|
+
payload = {
|
|
100
|
+
"status" => data[:status],
|
|
101
|
+
"timestamp" => data[:timestamp] || Time.now.utc.iso8601,
|
|
102
|
+
"reason" => data[:reason],
|
|
103
|
+
"root_causes" => data[:root_causes],
|
|
104
|
+
"fixes_count" => data[:fixes_count]
|
|
105
|
+
}.compact
|
|
106
|
+
|
|
107
|
+
ci_fixes[pr_number.to_s] = payload
|
|
108
|
+
save!
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
# Change request tracking methods
|
|
112
|
+
def change_request_processed?(pr_number)
|
|
113
|
+
change_requests.key?(pr_number.to_s)
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def change_request_data(pr_number)
|
|
117
|
+
change_requests[pr_number.to_s]
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def record_change_request(pr_number, data)
|
|
121
|
+
payload = {
|
|
122
|
+
"status" => data[:status],
|
|
123
|
+
"timestamp" => data[:timestamp] || Time.now.utc.iso8601,
|
|
124
|
+
"changes_applied" => data[:changes_applied],
|
|
125
|
+
"commits" => data[:commits],
|
|
126
|
+
"reason" => data[:reason],
|
|
127
|
+
"clarification_count" => data[:clarification_count]
|
|
128
|
+
}.compact
|
|
129
|
+
|
|
130
|
+
change_requests[pr_number.to_s] = payload
|
|
131
|
+
save!
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def reset_change_request_state(pr_number)
|
|
135
|
+
change_requests.delete(pr_number.to_s)
|
|
136
|
+
save!
|
|
137
|
+
end
|
|
138
|
+
|
|
56
139
|
private
|
|
57
140
|
|
|
58
141
|
def ensure_directory
|
|
@@ -81,6 +164,9 @@ module Aidp
|
|
|
81
164
|
base = load_state
|
|
82
165
|
base["plans"] ||= {}
|
|
83
166
|
base["builds"] ||= {}
|
|
167
|
+
base["reviews"] ||= {}
|
|
168
|
+
base["ci_fixes"] ||= {}
|
|
169
|
+
base["change_requests"] ||= {}
|
|
84
170
|
base
|
|
85
171
|
end
|
|
86
172
|
end
|
|
@@ -93,6 +179,18 @@ module Aidp
|
|
|
93
179
|
state["builds"]
|
|
94
180
|
end
|
|
95
181
|
|
|
182
|
+
def reviews
|
|
183
|
+
state["reviews"]
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
def ci_fixes
|
|
187
|
+
state["ci_fixes"]
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
def change_requests
|
|
191
|
+
state["change_requests"]
|
|
192
|
+
end
|
|
193
|
+
|
|
96
194
|
def stringify_keys(hash)
|
|
97
195
|
return {} unless hash
|
|
98
196
|
|
|
@@ -156,8 +156,11 @@ module Aidp
|
|
|
156
156
|
)
|
|
157
157
|
|
|
158
158
|
# Log error and exit
|
|
159
|
-
|
|
160
|
-
|
|
159
|
+
# Suppress backtrace noise during tests while keeping it for production debugging
|
|
160
|
+
unless ENV["RSPEC_RUNNING"] == "true"
|
|
161
|
+
warn("Error in workstream #{slug}: #{e.message}")
|
|
162
|
+
warn(e.backtrace.first(5).join("\n"))
|
|
163
|
+
end
|
|
161
164
|
exit(1)
|
|
162
165
|
end
|
|
163
166
|
|
data/lib/aidp.rb
CHANGED
|
@@ -26,6 +26,7 @@ require_relative "aidp/providers/base"
|
|
|
26
26
|
require_relative "aidp/providers/cursor"
|
|
27
27
|
require_relative "aidp/providers/anthropic"
|
|
28
28
|
require_relative "aidp/providers/gemini"
|
|
29
|
+
require_relative "aidp/providers/kilocode"
|
|
29
30
|
# Supervised providers removed - using direct execution model
|
|
30
31
|
require_relative "aidp/provider_manager"
|
|
31
32
|
|
|
@@ -92,6 +93,10 @@ require_relative "aidp/harness/state_manager"
|
|
|
92
93
|
require_relative "aidp/harness/error_handler"
|
|
93
94
|
require_relative "aidp/harness/status_display"
|
|
94
95
|
require_relative "aidp/harness/runner"
|
|
96
|
+
require_relative "aidp/harness/filter_strategy"
|
|
97
|
+
require_relative "aidp/harness/generic_filter_strategy"
|
|
98
|
+
require_relative "aidp/harness/rspec_filter_strategy"
|
|
99
|
+
require_relative "aidp/harness/output_filter"
|
|
95
100
|
|
|
96
101
|
# UI components
|
|
97
102
|
require_relative "aidp/harness/ui/spinner_helper"
|
data/templates/aidp.yml.example
CHANGED
|
@@ -708,6 +708,56 @@ devcontainer:
|
|
|
708
708
|
# - "api.example.com"
|
|
709
709
|
# - "registry.example.com"
|
|
710
710
|
|
|
711
|
+
# Watch mode configuration
|
|
712
|
+
# Configures automated monitoring and processing of GitHub issues/PRs
|
|
713
|
+
watch:
|
|
714
|
+
# Label configuration for different triggers
|
|
715
|
+
labels:
|
|
716
|
+
plan_trigger: "aidp-plan" # Trigger plan generation
|
|
717
|
+
needs_input: "aidp-needs-input" # Request clarification
|
|
718
|
+
ready_to_build: "aidp-ready" # Ready for implementation
|
|
719
|
+
build_trigger: "aidp-build" # Trigger implementation
|
|
720
|
+
review_trigger: "aidp-review" # Trigger code review
|
|
721
|
+
ci_fix_trigger: "aidp-fix-ci" # Trigger CI fix
|
|
722
|
+
change_request_trigger: "aidp-request-changes" # Trigger PR change requests
|
|
723
|
+
|
|
724
|
+
# Safety configuration
|
|
725
|
+
safety:
|
|
726
|
+
# Allow watch mode on public repositories (default: false for safety)
|
|
727
|
+
allow_public_repos: false
|
|
728
|
+
|
|
729
|
+
# List of GitHub usernames allowed to trigger automated actions
|
|
730
|
+
# Empty list means all authenticated users (for private repos)
|
|
731
|
+
author_allowlist: []
|
|
732
|
+
# - "user1"
|
|
733
|
+
# - "user2"
|
|
734
|
+
|
|
735
|
+
# Require running in a container environment (additional safety)
|
|
736
|
+
require_container: false
|
|
737
|
+
|
|
738
|
+
# PR change request configuration
|
|
739
|
+
pr_change_requests:
|
|
740
|
+
# Enable/disable PR change request feature
|
|
741
|
+
enabled: true
|
|
742
|
+
|
|
743
|
+
# Allow changes across multiple files in a single request
|
|
744
|
+
allow_multi_file_edits: true
|
|
745
|
+
|
|
746
|
+
# Run tests and linters before pushing changes
|
|
747
|
+
# If tests fail, changes are committed locally but not pushed
|
|
748
|
+
run_tests_before_push: true
|
|
749
|
+
|
|
750
|
+
# Prefix for commit messages created by change request processor
|
|
751
|
+
commit_message_prefix: "aidp: pr-change"
|
|
752
|
+
|
|
753
|
+
# Require at least one comment before processing change request
|
|
754
|
+
# This ensures there's context for what changes are requested
|
|
755
|
+
require_comment_reference: true
|
|
756
|
+
|
|
757
|
+
# Maximum PR diff size (in lines) to process
|
|
758
|
+
# Large PRs are skipped to avoid overwhelming the AI analysis
|
|
759
|
+
max_diff_size: 2000
|
|
760
|
+
|
|
711
761
|
# Configuration tips:
|
|
712
762
|
# - Set max_tokens based on your API plan limits
|
|
713
763
|
# - Use default_flags to customize provider behavior
|
|
@@ -724,3 +774,6 @@ devcontainer:
|
|
|
724
774
|
# - Use time-based configs for different usage patterns
|
|
725
775
|
# - Use step-specific configs for different workflow steps
|
|
726
776
|
# - Use user-specific configs for personalized experiences
|
|
777
|
+
# - Configure watch mode safety settings before using on public repositories
|
|
778
|
+
# - Set author_allowlist to restrict who can trigger automated actions
|
|
779
|
+
# - Adjust max_diff_size based on your typical PR sizes and AI capabilities
|
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.
|
|
4
|
+
version: 0.26.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Bart Agapinan
|
|
@@ -244,6 +244,18 @@ files:
|
|
|
244
244
|
- lib/aidp/analyze/steps.rb
|
|
245
245
|
- lib/aidp/analyze/tree_sitter_grammar_loader.rb
|
|
246
246
|
- lib/aidp/analyze/tree_sitter_scan.rb
|
|
247
|
+
- lib/aidp/auto_update.rb
|
|
248
|
+
- lib/aidp/auto_update/bundler_adapter.rb
|
|
249
|
+
- lib/aidp/auto_update/checkpoint.rb
|
|
250
|
+
- lib/aidp/auto_update/checkpoint_store.rb
|
|
251
|
+
- lib/aidp/auto_update/coordinator.rb
|
|
252
|
+
- lib/aidp/auto_update/errors.rb
|
|
253
|
+
- lib/aidp/auto_update/failure_tracker.rb
|
|
254
|
+
- lib/aidp/auto_update/rubygems_api_adapter.rb
|
|
255
|
+
- lib/aidp/auto_update/update_check.rb
|
|
256
|
+
- lib/aidp/auto_update/update_logger.rb
|
|
257
|
+
- lib/aidp/auto_update/update_policy.rb
|
|
258
|
+
- lib/aidp/auto_update/version_detector.rb
|
|
247
259
|
- lib/aidp/cli.rb
|
|
248
260
|
- lib/aidp/cli/devcontainer_commands.rb
|
|
249
261
|
- lib/aidp/cli/enhanced_input.rb
|
|
@@ -293,12 +305,16 @@ files:
|
|
|
293
305
|
- lib/aidp/harness/configuration.rb
|
|
294
306
|
- lib/aidp/harness/enhanced_runner.rb
|
|
295
307
|
- lib/aidp/harness/error_handler.rb
|
|
308
|
+
- lib/aidp/harness/filter_strategy.rb
|
|
309
|
+
- lib/aidp/harness/generic_filter_strategy.rb
|
|
310
|
+
- lib/aidp/harness/output_filter.rb
|
|
296
311
|
- lib/aidp/harness/provider_config.rb
|
|
297
312
|
- lib/aidp/harness/provider_factory.rb
|
|
298
313
|
- lib/aidp/harness/provider_info.rb
|
|
299
314
|
- lib/aidp/harness/provider_manager.rb
|
|
300
315
|
- lib/aidp/harness/provider_metrics.rb
|
|
301
316
|
- lib/aidp/harness/provider_type_checker.rb
|
|
317
|
+
- lib/aidp/harness/rspec_filter_strategy.rb
|
|
302
318
|
- lib/aidp/harness/runner.rb
|
|
303
319
|
- lib/aidp/harness/simple_user_interface.rb
|
|
304
320
|
- lib/aidp/harness/state/errors.rb
|
|
@@ -357,6 +373,7 @@ files:
|
|
|
357
373
|
- lib/aidp/providers/error_taxonomy.rb
|
|
358
374
|
- lib/aidp/providers/gemini.rb
|
|
359
375
|
- lib/aidp/providers/github_copilot.rb
|
|
376
|
+
- lib/aidp/providers/kilocode.rb
|
|
360
377
|
- lib/aidp/providers/opencode.rb
|
|
361
378
|
- lib/aidp/rescue_logging.rb
|
|
362
379
|
- lib/aidp/safe_directory.rb
|
|
@@ -387,10 +404,17 @@ files:
|
|
|
387
404
|
- lib/aidp/version.rb
|
|
388
405
|
- lib/aidp/watch.rb
|
|
389
406
|
- lib/aidp/watch/build_processor.rb
|
|
407
|
+
- lib/aidp/watch/change_request_processor.rb
|
|
408
|
+
- lib/aidp/watch/ci_fix_processor.rb
|
|
390
409
|
- lib/aidp/watch/plan_generator.rb
|
|
391
410
|
- lib/aidp/watch/plan_processor.rb
|
|
392
411
|
- lib/aidp/watch/repository_client.rb
|
|
393
412
|
- lib/aidp/watch/repository_safety_checker.rb
|
|
413
|
+
- lib/aidp/watch/review_processor.rb
|
|
414
|
+
- lib/aidp/watch/reviewers/base_reviewer.rb
|
|
415
|
+
- lib/aidp/watch/reviewers/performance_reviewer.rb
|
|
416
|
+
- lib/aidp/watch/reviewers/security_reviewer.rb
|
|
417
|
+
- lib/aidp/watch/reviewers/senior_dev_reviewer.rb
|
|
394
418
|
- lib/aidp/watch/runner.rb
|
|
395
419
|
- lib/aidp/watch/state_store.rb
|
|
396
420
|
- lib/aidp/workflows/definitions.rb
|