aidp 0.25.0 ā 0.27.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 +45 -6
- data/lib/aidp/analyze/error_handler.rb +11 -0
- data/lib/aidp/cli/checkpoint_command.rb +198 -0
- data/lib/aidp/cli/config_command.rb +71 -0
- data/lib/aidp/cli/enhanced_input.rb +2 -0
- data/lib/aidp/cli/first_run_wizard.rb +8 -7
- data/lib/aidp/cli/harness_command.rb +102 -0
- data/lib/aidp/cli/jobs_command.rb +3 -3
- data/lib/aidp/cli/mcp_dashboard.rb +4 -3
- data/lib/aidp/cli/models_command.rb +662 -0
- data/lib/aidp/cli/providers_command.rb +223 -0
- data/lib/aidp/cli.rb +35 -456
- data/lib/aidp/daemon/runner.rb +2 -2
- data/lib/aidp/debug_mixin.rb +2 -9
- data/lib/aidp/execute/async_work_loop_runner.rb +2 -1
- data/lib/aidp/execute/checkpoint_display.rb +38 -37
- data/lib/aidp/execute/interactive_repl.rb +2 -1
- data/lib/aidp/execute/prompt_manager.rb +4 -4
- data/lib/aidp/execute/work_loop_runner.rb +253 -56
- data/lib/aidp/execute/workflow_selector.rb +2 -2
- data/lib/aidp/harness/config_loader.rb +20 -11
- data/lib/aidp/harness/config_manager.rb +5 -5
- data/lib/aidp/harness/config_schema.rb +30 -8
- data/lib/aidp/harness/configuration.rb +105 -4
- data/lib/aidp/harness/enhanced_runner.rb +24 -15
- data/lib/aidp/harness/error_handler.rb +26 -5
- data/lib/aidp/harness/filter_strategy.rb +45 -0
- data/lib/aidp/harness/generic_filter_strategy.rb +63 -0
- data/lib/aidp/harness/model_cache.rb +269 -0
- data/lib/aidp/harness/model_discovery_service.rb +259 -0
- data/lib/aidp/harness/model_registry.rb +201 -0
- data/lib/aidp/harness/output_filter.rb +136 -0
- data/lib/aidp/harness/provider_manager.rb +18 -3
- data/lib/aidp/harness/rspec_filter_strategy.rb +82 -0
- data/lib/aidp/harness/runner.rb +5 -0
- data/lib/aidp/harness/test_runner.rb +165 -27
- data/lib/aidp/harness/thinking_depth_manager.rb +223 -7
- data/lib/aidp/harness/ui/enhanced_tui.rb +4 -1
- data/lib/aidp/logger.rb +35 -5
- data/lib/aidp/providers/adapter.rb +2 -4
- data/lib/aidp/providers/anthropic.rb +141 -128
- data/lib/aidp/providers/base.rb +98 -2
- data/lib/aidp/providers/capability_registry.rb +0 -1
- data/lib/aidp/providers/codex.rb +49 -67
- data/lib/aidp/providers/cursor.rb +71 -59
- data/lib/aidp/providers/gemini.rb +44 -60
- data/lib/aidp/providers/github_copilot.rb +2 -66
- data/lib/aidp/providers/kilocode.rb +24 -80
- data/lib/aidp/providers/opencode.rb +24 -80
- data/lib/aidp/safe_directory.rb +10 -3
- data/lib/aidp/setup/wizard.rb +345 -8
- 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 +40 -1
- data/lib/aidp/watch/change_request_processor.rb +659 -0
- data/lib/aidp/watch/plan_generator.rb +93 -14
- data/lib/aidp/watch/plan_processor.rb +71 -8
- data/lib/aidp/watch/repository_client.rb +85 -20
- data/lib/aidp/watch/review_processor.rb +3 -3
- data/lib/aidp/watch/runner.rb +37 -0
- data/lib/aidp/watch/state_store.rb +46 -1
- data/lib/aidp/workflows/guided_agent.rb +3 -3
- data/lib/aidp/workstream_executor.rb +5 -2
- data/lib/aidp.rb +4 -0
- data/templates/aidp-development.yml.example +2 -2
- data/templates/aidp-production.yml.example +3 -3
- data/templates/aidp.yml.example +53 -0
- metadata +14 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 174c58fcccbc5d5c927cb30dd3bf8c735de926cf52de5eb2a4bb56f2bc984cc3
|
|
4
|
+
data.tar.gz: 73efb11b31d3ff346a482fde9616047fd64525e44ffe768a81a6e4808e748cd1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 407aecc4942fbda7fbf09e15ebfdfa6ba8595be9f282a0b425ce65dc22e45d3a524fe5dd211ce96ec59029801df01528a835412ba38f90cb273c5b1594df2016
|
|
7
|
+
data.tar.gz: 174a42200bb01198f3c88de3ec35198c9475f018f06a673e7d1d3c0e0dda9c294dd832519327261ac767a42323e965f1fa7ea1fa1d3b394425604ceaaa7bf371
|
data/README.md
CHANGED
|
@@ -218,7 +218,9 @@ aidp watch owner/repo --once
|
|
|
218
218
|
|
|
219
219
|
**Label Workflow:**
|
|
220
220
|
|
|
221
|
-
AIDP uses a smart label-based workflow to manage
|
|
221
|
+
AIDP uses a smart label-based workflow to manage both issues and pull requests:
|
|
222
|
+
|
|
223
|
+
#### Issue Workflow (Plan & Build)
|
|
222
224
|
|
|
223
225
|
1. **Planning Phase** (`aidp-plan` label):
|
|
224
226
|
- Add this label to an issue to trigger plan generation
|
|
@@ -247,6 +249,32 @@ AIDP uses a smart label-based workflow to manage the lifecycle of automated issu
|
|
|
247
249
|
- Posts completion comment with summary
|
|
248
250
|
- Automatically removes the `aidp-build` label
|
|
249
251
|
|
|
252
|
+
#### Pull Request Workflow (Review, CI Fix, Change Requests)
|
|
253
|
+
|
|
254
|
+
<!-- markdownlint-disable-next-line MD029 -->
|
|
255
|
+
1. **Code Review** (`aidp-review` label):
|
|
256
|
+
- Add this label to any PR to trigger automated code review
|
|
257
|
+
- AIDP analyzes code from three expert perspectives (Senior Developer, Security Specialist, Performance Analyst)
|
|
258
|
+
- Posts a comprehensive review comment with severity-categorized findings (High Priority, Major, Minor, Nit)
|
|
259
|
+
- Automatically removes the label after posting review
|
|
260
|
+
- No commits are made - review only
|
|
261
|
+
|
|
262
|
+
2. **CI Fix** (`aidp-fix-ci` label):
|
|
263
|
+
- Add this label to a PR with failing CI checks
|
|
264
|
+
- AIDP analyzes CI failure logs and identifies root causes
|
|
265
|
+
- Automatically fixes issues like linting errors, simple test failures, and dependency problems
|
|
266
|
+
- Commits and pushes fixes to the PR branch
|
|
267
|
+
- Posts a summary of what was fixed
|
|
268
|
+
- Automatically removes the label after completion
|
|
269
|
+
|
|
270
|
+
3. **Change Requests** (`aidp-request-changes` label):
|
|
271
|
+
- Comment on your own PR describing desired changes, then add this label
|
|
272
|
+
- AIDP implements the requested changes on the PR branch
|
|
273
|
+
- Runs tests/linters and commits changes
|
|
274
|
+
- **If clarification needed**: Replaces label with `aidp-needs-input` and posts questions
|
|
275
|
+
- User responds to questions and re-applies the label to continue
|
|
276
|
+
- Automatically removes the label after completion
|
|
277
|
+
|
|
250
278
|
**Customizable Labels:**
|
|
251
279
|
|
|
252
280
|
All label names are configurable to match your repository's existing label scheme. Configure via the interactive wizard or manually in `aidp.yml`:
|
|
@@ -255,10 +283,16 @@ All label names are configurable to match your repository's existing label schem
|
|
|
255
283
|
# .aidp/aidp.yml
|
|
256
284
|
watch:
|
|
257
285
|
labels:
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
286
|
+
# Issue-based automation
|
|
287
|
+
plan_trigger: aidp-plan # Trigger plan generation
|
|
288
|
+
needs_input: aidp-needs-input # Needs user input/clarification
|
|
289
|
+
ready_to_build: aidp-ready # Plan ready for implementation
|
|
290
|
+
build_trigger: aidp-build # Trigger implementation
|
|
291
|
+
|
|
292
|
+
# PR-based automation
|
|
293
|
+
review_trigger: aidp-review # Trigger code review
|
|
294
|
+
ci_fix_trigger: aidp-fix-ci # Trigger CI auto-fix
|
|
295
|
+
change_request_trigger: aidp-request-changes # Trigger PR change implementation
|
|
262
296
|
```
|
|
263
297
|
|
|
264
298
|
Run `aidp config --interactive` and enable watch mode to configure labels interactively.
|
|
@@ -294,7 +328,12 @@ AIDP can automatically request clarification when it needs more information duri
|
|
|
294
328
|
|
|
295
329
|
This ensures AIDP never gets stuck - if it needs more information, it will ask for it rather than making incorrect assumptions or failing silently.
|
|
296
330
|
|
|
297
|
-
|
|
331
|
+
**Additional Documentation:**
|
|
332
|
+
|
|
333
|
+
- [Watch Mode Guide](docs/FULLY_AUTOMATIC_MODE.md) - Complete guide to watch mode setup and operation
|
|
334
|
+
- [Watch Mode Safety](docs/WATCH_MODE_SAFETY.md) - Security features and best practices
|
|
335
|
+
- [PR Automation Guide](docs/PR_AUTOMATION.md) - Detailed guide for code review, CI fixes, and PR changes
|
|
336
|
+
- [PR Change Requests](docs/PR_CHANGE_REQUESTS.md) - Comprehensive documentation for automated PR modifications
|
|
298
337
|
|
|
299
338
|
## Command Reference
|
|
300
339
|
|
|
@@ -99,6 +99,13 @@ module Aidp
|
|
|
99
99
|
private
|
|
100
100
|
|
|
101
101
|
def setup_logger(log_file, verbose)
|
|
102
|
+
# Suppress logger output in test/CI environments
|
|
103
|
+
if suppress_error_logs?
|
|
104
|
+
logger = ::Logger.new(IO::NULL)
|
|
105
|
+
logger.level = ::Logger::FATAL
|
|
106
|
+
return logger
|
|
107
|
+
end
|
|
108
|
+
|
|
102
109
|
output_stream = log_file || @output || $stdout
|
|
103
110
|
logger = ::Logger.new(output_stream)
|
|
104
111
|
logger.level = verbose ? ::Logger::DEBUG : ::Logger::INFO
|
|
@@ -108,6 +115,10 @@ module Aidp
|
|
|
108
115
|
logger
|
|
109
116
|
end
|
|
110
117
|
|
|
118
|
+
def suppress_error_logs?
|
|
119
|
+
ENV["RSPEC_RUNNING"] || ENV["CI"] || ENV["RAILS_ENV"] == "test" || ENV["RACK_ENV"] == "test"
|
|
120
|
+
end
|
|
121
|
+
|
|
111
122
|
def setup_recovery_strategies
|
|
112
123
|
strategies = {
|
|
113
124
|
Errno::ENOENT => :skip_step_with_warning,
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "tty-prompt"
|
|
4
|
+
require_relative "../execute/checkpoint"
|
|
5
|
+
require_relative "../execute/checkpoint_display"
|
|
6
|
+
|
|
7
|
+
module Aidp
|
|
8
|
+
class CLI
|
|
9
|
+
# Command handler for `aidp checkpoint` subcommand
|
|
10
|
+
#
|
|
11
|
+
# Provides commands for managing workflow checkpoints:
|
|
12
|
+
# - show: Display latest checkpoint data
|
|
13
|
+
# - summary: Show progress summary with trends
|
|
14
|
+
# - history: Show last N checkpoints
|
|
15
|
+
# - metrics: Show detailed metrics
|
|
16
|
+
# - clear: Clear all checkpoint data
|
|
17
|
+
#
|
|
18
|
+
# Usage:
|
|
19
|
+
# aidp checkpoint show
|
|
20
|
+
# aidp checkpoint summary --watch
|
|
21
|
+
# aidp checkpoint history 10
|
|
22
|
+
# aidp checkpoint metrics
|
|
23
|
+
# aidp checkpoint clear --force
|
|
24
|
+
class CheckpointCommand
|
|
25
|
+
include Aidp::MessageDisplay
|
|
26
|
+
|
|
27
|
+
def initialize(prompt: TTY::Prompt.new, checkpoint_class: nil, display_class: nil, project_dir: nil)
|
|
28
|
+
@prompt = prompt
|
|
29
|
+
@checkpoint_class = checkpoint_class || Aidp::Execute::Checkpoint
|
|
30
|
+
@display_class = display_class || Aidp::Execute::CheckpointDisplay
|
|
31
|
+
@project_dir = project_dir || Dir.pwd
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Main entry point for checkpoint subcommands
|
|
35
|
+
def run(args)
|
|
36
|
+
sub = args.shift || "summary"
|
|
37
|
+
checkpoint = @checkpoint_class.new(@project_dir)
|
|
38
|
+
display = @display_class.new
|
|
39
|
+
|
|
40
|
+
case sub
|
|
41
|
+
when "show"
|
|
42
|
+
run_show_command(checkpoint, display)
|
|
43
|
+
when "summary"
|
|
44
|
+
run_summary_command(checkpoint, display, args)
|
|
45
|
+
when "history"
|
|
46
|
+
run_history_command(checkpoint, display, args)
|
|
47
|
+
when "metrics"
|
|
48
|
+
run_metrics_command(checkpoint)
|
|
49
|
+
when "clear"
|
|
50
|
+
run_clear_command(checkpoint, args)
|
|
51
|
+
else
|
|
52
|
+
display_usage
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
private
|
|
57
|
+
|
|
58
|
+
def run_show_command(checkpoint, display)
|
|
59
|
+
latest = checkpoint.latest_checkpoint
|
|
60
|
+
if latest
|
|
61
|
+
display.display_checkpoint(latest, show_details: true)
|
|
62
|
+
else
|
|
63
|
+
display_message("No checkpoint data found.", type: :info)
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def run_summary_command(checkpoint, display, args)
|
|
68
|
+
watch = args.include?("--watch")
|
|
69
|
+
interval = extract_interval_option(args) || 5
|
|
70
|
+
|
|
71
|
+
if watch
|
|
72
|
+
watch_checkpoint_summary(checkpoint, display, interval)
|
|
73
|
+
else
|
|
74
|
+
summary = checkpoint.progress_summary
|
|
75
|
+
if summary
|
|
76
|
+
display.display_progress_summary(summary)
|
|
77
|
+
else
|
|
78
|
+
display_message("No checkpoint data found.", type: :info)
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def run_history_command(checkpoint, display, args)
|
|
84
|
+
limit = args.shift || "10"
|
|
85
|
+
history = checkpoint.checkpoint_history(limit: limit.to_i)
|
|
86
|
+
if history.any?
|
|
87
|
+
display.display_checkpoint_history(history, limit: limit.to_i)
|
|
88
|
+
else
|
|
89
|
+
display_message("No checkpoint history found.", type: :info)
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def run_metrics_command(checkpoint)
|
|
94
|
+
latest = checkpoint.latest_checkpoint
|
|
95
|
+
unless latest
|
|
96
|
+
display_message("No checkpoint data found.", type: :info)
|
|
97
|
+
return
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
display_message("", type: :info)
|
|
101
|
+
display_message("š Detailed Metrics", type: :info)
|
|
102
|
+
display_message("=" * 60, type: :muted)
|
|
103
|
+
|
|
104
|
+
metrics = latest[:metrics]
|
|
105
|
+
display_message("Lines of Code: #{metrics[:lines_of_code]}", type: :info)
|
|
106
|
+
display_message("File Count: #{metrics[:file_count]}", type: :info)
|
|
107
|
+
display_message("Test Coverage: #{metrics[:test_coverage]}%", type: :info)
|
|
108
|
+
display_message("Code Quality: #{metrics[:code_quality]}%", type: :info)
|
|
109
|
+
display_message("PRD Task Progress: #{metrics[:prd_task_progress]}%", type: :info)
|
|
110
|
+
|
|
111
|
+
if metrics.key?(:tests_passing)
|
|
112
|
+
status = metrics[:tests_passing] ? "ā Passing" : "ā Failing"
|
|
113
|
+
display_message("Tests: #{status}", type: :info)
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
if metrics.key?(:linters_passing)
|
|
117
|
+
status = metrics[:linters_passing] ? "ā Passing" : "ā Failing"
|
|
118
|
+
display_message("Linters: #{status}", type: :info)
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
display_message("=" * 60, type: :muted)
|
|
122
|
+
display_message("", type: :info)
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def run_clear_command(checkpoint, args)
|
|
126
|
+
force = args.include?("--force")
|
|
127
|
+
unless force
|
|
128
|
+
confirm = @prompt.yes?("Are you sure you want to clear all checkpoint data?")
|
|
129
|
+
return unless confirm
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
checkpoint.clear
|
|
133
|
+
display_message("ā Checkpoint data cleared.", type: :success)
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def watch_checkpoint_summary(checkpoint, display, interval)
|
|
137
|
+
display_message("Watching checkpoint summary (refresh: #{interval}s, Ctrl+C to exit)...", type: :info)
|
|
138
|
+
display_message("", type: :info)
|
|
139
|
+
|
|
140
|
+
begin
|
|
141
|
+
loop do
|
|
142
|
+
# Clear screen
|
|
143
|
+
print "\e[2J\e[H"
|
|
144
|
+
|
|
145
|
+
summary = checkpoint.progress_summary
|
|
146
|
+
if summary
|
|
147
|
+
display.display_progress_summary(summary)
|
|
148
|
+
|
|
149
|
+
# Show last update time
|
|
150
|
+
if summary[:current] && summary[:current][:timestamp]
|
|
151
|
+
last_update = Time.parse(summary[:current][:timestamp])
|
|
152
|
+
age = Time.now - last_update
|
|
153
|
+
display_message("", type: :info)
|
|
154
|
+
display_message("Last update: #{format_time_ago_simple(age)} | Refreshing in #{interval}s...", type: :muted)
|
|
155
|
+
end
|
|
156
|
+
else
|
|
157
|
+
display_message("No checkpoint data found. Waiting for data...", type: :info)
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
sleep interval
|
|
161
|
+
end
|
|
162
|
+
rescue Interrupt
|
|
163
|
+
display_message("\nStopped watching checkpoint summary", type: :info)
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def format_time_ago_simple(seconds)
|
|
168
|
+
if seconds < 60
|
|
169
|
+
"#{seconds.to_i}s ago"
|
|
170
|
+
elsif seconds < 3600
|
|
171
|
+
"#{(seconds / 60).to_i}m ago"
|
|
172
|
+
else
|
|
173
|
+
"#{(seconds / 3600).to_i}h ago"
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
def extract_interval_option(args)
|
|
178
|
+
args.each_with_index do |arg, i|
|
|
179
|
+
if arg == "--interval" && args[i + 1]
|
|
180
|
+
return args[i + 1].to_i
|
|
181
|
+
elsif arg.start_with?("--interval=")
|
|
182
|
+
return arg.split("=")[1].to_i
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
nil
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
def display_usage
|
|
189
|
+
display_message("Usage: aidp checkpoint <show|summary|history|metrics|clear>", type: :info)
|
|
190
|
+
display_message(" show - Show the latest checkpoint data", type: :info)
|
|
191
|
+
display_message(" summary [--watch] - Show progress summary with trends", type: :info)
|
|
192
|
+
display_message(" history [N] - Show last N checkpoints", type: :info)
|
|
193
|
+
display_message(" metrics - Show detailed metrics", type: :info)
|
|
194
|
+
display_message(" clear [--force] - Clear all checkpoint data", type: :info)
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
end
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "tty-prompt"
|
|
4
|
+
require_relative "../setup/wizard"
|
|
5
|
+
|
|
6
|
+
module Aidp
|
|
7
|
+
class CLI
|
|
8
|
+
# Command handler for `aidp config` subcommand
|
|
9
|
+
#
|
|
10
|
+
# Provides commands for managing AIDP configuration:
|
|
11
|
+
# - Interactive configuration wizard
|
|
12
|
+
# - Dry-run mode for testing configuration changes
|
|
13
|
+
#
|
|
14
|
+
# Usage:
|
|
15
|
+
# aidp config --interactive
|
|
16
|
+
# aidp config --interactive --dry-run
|
|
17
|
+
class ConfigCommand
|
|
18
|
+
include Aidp::MessageDisplay
|
|
19
|
+
|
|
20
|
+
def initialize(prompt: TTY::Prompt.new, wizard_class: nil, project_dir: nil)
|
|
21
|
+
@prompt = prompt
|
|
22
|
+
@wizard_class = wizard_class || Aidp::Setup::Wizard
|
|
23
|
+
@project_dir = project_dir || Dir.pwd
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Main entry point for config command
|
|
27
|
+
def run(args)
|
|
28
|
+
interactive = false
|
|
29
|
+
dry_run = false
|
|
30
|
+
|
|
31
|
+
until args.empty?
|
|
32
|
+
token = args.shift
|
|
33
|
+
case token
|
|
34
|
+
when "--interactive"
|
|
35
|
+
interactive = true
|
|
36
|
+
when "--dry-run"
|
|
37
|
+
dry_run = true
|
|
38
|
+
when "-h", "--help"
|
|
39
|
+
display_usage
|
|
40
|
+
return
|
|
41
|
+
else
|
|
42
|
+
display_message("Unknown option: #{token}", type: :error)
|
|
43
|
+
display_usage
|
|
44
|
+
return
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
unless interactive
|
|
49
|
+
display_usage
|
|
50
|
+
return
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
wizard = @wizard_class.new(@project_dir, prompt: @prompt, dry_run: dry_run)
|
|
54
|
+
wizard.run
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
private
|
|
58
|
+
|
|
59
|
+
def display_usage
|
|
60
|
+
display_message("\nUsage: aidp config --interactive [--dry-run]", type: :info)
|
|
61
|
+
display_message("\nOptions:", type: :info)
|
|
62
|
+
display_message(" --interactive Run interactive configuration wizard", type: :info)
|
|
63
|
+
display_message(" --dry-run Perform a dry run without making changes", type: :info)
|
|
64
|
+
display_message(" -h, --help Show this help message", type: :info)
|
|
65
|
+
display_message("\nExamples:", type: :info)
|
|
66
|
+
display_message(" aidp config --interactive", type: :info)
|
|
67
|
+
display_message(" aidp config --interactive --dry-run", type: :info)
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
@@ -21,6 +21,8 @@ module Aidp
|
|
|
21
21
|
# - Ctrl-T: Transpose characters
|
|
22
22
|
# - And many more Emacs-style bindings
|
|
23
23
|
|
|
24
|
+
attr_reader :use_reline, :show_hints
|
|
25
|
+
|
|
24
26
|
def initialize(prompt: nil, input: nil, output: nil, use_reline: true)
|
|
25
27
|
@use_reline = use_reline
|
|
26
28
|
@input = input || $stdin
|
|
@@ -10,10 +10,10 @@ module Aidp
|
|
|
10
10
|
class FirstRunWizard
|
|
11
11
|
include Aidp::MessageDisplay
|
|
12
12
|
|
|
13
|
-
def self.ensure_config(project_dir, non_interactive: false, prompt: TTY::Prompt.new)
|
|
13
|
+
def self.ensure_config(project_dir, non_interactive: false, prompt: TTY::Prompt.new, wizard_class: Aidp::Setup::Wizard)
|
|
14
14
|
return true if Aidp::Config.config_exists?(project_dir)
|
|
15
15
|
|
|
16
|
-
wizard = new(project_dir, prompt: prompt)
|
|
16
|
+
wizard = new(project_dir, prompt: prompt, wizard_class: wizard_class)
|
|
17
17
|
|
|
18
18
|
if non_interactive
|
|
19
19
|
wizard.create_minimal_config
|
|
@@ -24,22 +24,23 @@ module Aidp
|
|
|
24
24
|
end
|
|
25
25
|
end
|
|
26
26
|
|
|
27
|
-
def self.setup_config(project_dir, non_interactive: false, prompt: TTY::Prompt.new)
|
|
27
|
+
def self.setup_config(project_dir, non_interactive: false, prompt: TTY::Prompt.new, wizard_class: Aidp::Setup::Wizard)
|
|
28
28
|
if non_interactive
|
|
29
|
-
new(project_dir, prompt: prompt).send(:display_message, "Configuration setup skipped in non-interactive environment", type: :info)
|
|
29
|
+
new(project_dir, prompt: prompt, wizard_class: wizard_class).send(:display_message, "Configuration setup skipped in non-interactive environment", type: :info)
|
|
30
30
|
return true
|
|
31
31
|
end
|
|
32
32
|
|
|
33
|
-
new(project_dir, prompt: prompt).run
|
|
33
|
+
new(project_dir, prompt: prompt, wizard_class: wizard_class).run
|
|
34
34
|
end
|
|
35
35
|
|
|
36
|
-
def initialize(project_dir, prompt: TTY::Prompt.new)
|
|
36
|
+
def initialize(project_dir, prompt: TTY::Prompt.new, wizard_class: Aidp::Setup::Wizard)
|
|
37
37
|
@project_dir = project_dir
|
|
38
38
|
@prompt = prompt
|
|
39
|
+
@wizard_class = wizard_class
|
|
39
40
|
end
|
|
40
41
|
|
|
41
42
|
def run
|
|
42
|
-
wizard =
|
|
43
|
+
wizard = @wizard_class.new(@project_dir, prompt: @prompt)
|
|
43
44
|
wizard.run
|
|
44
45
|
end
|
|
45
46
|
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "tty-prompt"
|
|
4
|
+
require_relative "../harness/runner"
|
|
5
|
+
|
|
6
|
+
module Aidp
|
|
7
|
+
class CLI
|
|
8
|
+
# Command handler for `aidp harness status` and `aidp harness reset` subcommands
|
|
9
|
+
#
|
|
10
|
+
# Provides commands for viewing and managing harness state:
|
|
11
|
+
# - status: Show detailed harness status for all modes
|
|
12
|
+
# - reset: Reset harness state for a specific mode
|
|
13
|
+
#
|
|
14
|
+
# Usage:
|
|
15
|
+
# aidp harness status
|
|
16
|
+
# aidp harness reset --mode analyze
|
|
17
|
+
class HarnessCommand
|
|
18
|
+
include Aidp::MessageDisplay
|
|
19
|
+
include Aidp::RescueLogging
|
|
20
|
+
|
|
21
|
+
def initialize(prompt: TTY::Prompt.new, runner_class: nil, project_dir: nil)
|
|
22
|
+
@prompt = prompt
|
|
23
|
+
@runner_class = runner_class || Aidp::Harness::Runner
|
|
24
|
+
@project_dir = project_dir || Dir.pwd
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Main entry point for harness status/reset subcommands
|
|
28
|
+
def run(args, subcommand:, options: {})
|
|
29
|
+
case subcommand
|
|
30
|
+
when "status"
|
|
31
|
+
run_status_command
|
|
32
|
+
when "reset"
|
|
33
|
+
run_reset_command(options)
|
|
34
|
+
else
|
|
35
|
+
display_message("Unknown harness subcommand: #{subcommand}", type: :error)
|
|
36
|
+
display_help
|
|
37
|
+
1
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
private
|
|
42
|
+
|
|
43
|
+
def run_status_command
|
|
44
|
+
modes = %i[analyze execute]
|
|
45
|
+
display_message("š§ Harness Status", type: :highlight)
|
|
46
|
+
modes.each do |mode|
|
|
47
|
+
status = fetch_harness_status(mode)
|
|
48
|
+
print_harness_mode_status(mode, status)
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def run_reset_command(options)
|
|
53
|
+
mode = (options[:mode] || "analyze").to_s
|
|
54
|
+
unless %w[analyze execute].include?(mode)
|
|
55
|
+
display_message("ā Invalid mode. Use 'analyze' or 'execute'", type: :error)
|
|
56
|
+
return
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Build a runner to access state manager
|
|
60
|
+
runner = @runner_class.new(@project_dir, mode.to_sym, {})
|
|
61
|
+
state_manager = runner.instance_variable_get(:@state_manager)
|
|
62
|
+
state_manager.reset_all if state_manager.respond_to?(:reset_all)
|
|
63
|
+
display_message("ā
Reset harness state for #{mode} mode", type: :success)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def fetch_harness_status(mode)
|
|
67
|
+
runner = @runner_class.new(@project_dir, mode, {})
|
|
68
|
+
if runner.respond_to?(:detailed_status)
|
|
69
|
+
runner.detailed_status
|
|
70
|
+
else
|
|
71
|
+
{harness: {state: "unknown"}}
|
|
72
|
+
end
|
|
73
|
+
rescue => e
|
|
74
|
+
log_rescue(e, component: "harness_command", action: "fetch_harness_status", fallback: {harness: {state: "error"}}, mode: mode)
|
|
75
|
+
{harness: {state: "error", error: e.message}}
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def print_harness_mode_status(mode, status)
|
|
79
|
+
harness = status[:harness] || {}
|
|
80
|
+
display_message("\nš #{mode.to_s.capitalize} Mode:", type: :info)
|
|
81
|
+
display_message(" State: #{harness[:state]}", type: :info)
|
|
82
|
+
if harness[:progress]
|
|
83
|
+
prog = harness[:progress]
|
|
84
|
+
display_message(" Progress: #{prog[:completed_steps]}/#{prog[:total_steps]}", type: :success)
|
|
85
|
+
display_message(" Current Step: #{harness[:current_step]}", type: :info) if harness[:current_step]
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def display_help
|
|
90
|
+
display_message("\nUsage: aidp harness <subcommand> [options]", type: :info)
|
|
91
|
+
display_message("\nSubcommands:", type: :info)
|
|
92
|
+
display_message(" status Show harness status for all modes", type: :info)
|
|
93
|
+
display_message(" reset Reset harness state for a mode", type: :info)
|
|
94
|
+
display_message("\nOptions:", type: :info)
|
|
95
|
+
display_message(" --mode MODE Specify mode for reset (analyze|execute)", type: :info)
|
|
96
|
+
display_message("\nExamples:", type: :info)
|
|
97
|
+
display_message(" aidp harness status", type: :info)
|
|
98
|
+
display_message(" aidp harness reset --mode analyze", type: :info)
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
@@ -14,7 +14,7 @@ module Aidp
|
|
|
14
14
|
class JobsCommand
|
|
15
15
|
include Aidp::MessageDisplay
|
|
16
16
|
|
|
17
|
-
def initialize(input: nil, output: nil, prompt: TTY::Prompt.new)
|
|
17
|
+
def initialize(input: nil, output: nil, prompt: TTY::Prompt.new, file_manager: nil, background_runner: nil)
|
|
18
18
|
@io = TerminalIO.new(input: input, output: output)
|
|
19
19
|
@prompt = prompt
|
|
20
20
|
@pastel = Pastel.new
|
|
@@ -22,8 +22,8 @@ module Aidp
|
|
|
22
22
|
@view_mode = :list
|
|
23
23
|
@selected_job_id = nil
|
|
24
24
|
@jobs_displayed = false # Track if we've displayed jobs in interactive mode
|
|
25
|
-
@file_manager = Aidp::Storage::FileManager.new(File.join(Dir.pwd, ".aidp"))
|
|
26
|
-
@background_runner = Aidp::Jobs::BackgroundRunner.new(Dir.pwd)
|
|
25
|
+
@file_manager = file_manager || Aidp::Storage::FileManager.new(File.join(Dir.pwd, ".aidp"))
|
|
26
|
+
@background_runner = background_runner || Aidp::Jobs::BackgroundRunner.new(Dir.pwd)
|
|
27
27
|
@screen_width = 80 # Default screen width
|
|
28
28
|
end
|
|
29
29
|
|
|
@@ -10,9 +10,10 @@ module Aidp
|
|
|
10
10
|
class McpDashboard
|
|
11
11
|
include Aidp::MessageDisplay
|
|
12
12
|
|
|
13
|
-
def initialize(root_dir = nil)
|
|
13
|
+
def initialize(root_dir = nil, configuration: nil, provider_info_class: Aidp::Harness::ProviderInfo)
|
|
14
14
|
@root_dir = root_dir || Dir.pwd
|
|
15
|
-
@configuration = Aidp::Harness::Configuration.new(@root_dir)
|
|
15
|
+
@configuration = configuration || Aidp::Harness::Configuration.new(@root_dir)
|
|
16
|
+
@provider_info_class = provider_info_class
|
|
16
17
|
end
|
|
17
18
|
|
|
18
19
|
# Display MCP dashboard showing all servers across all providers
|
|
@@ -101,7 +102,7 @@ module Aidp
|
|
|
101
102
|
provider_servers = {} # provider_name => [server_info]
|
|
102
103
|
|
|
103
104
|
providers.each do |provider|
|
|
104
|
-
provider_info =
|
|
105
|
+
provider_info = @provider_info_class.new(provider, @root_dir)
|
|
105
106
|
info = provider_info.info
|
|
106
107
|
|
|
107
108
|
next unless info[:mcp_support]
|