aidp 0.26.0 ā 0.28.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 +89 -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 +661 -0
- data/lib/aidp/cli/providers_command.rb +223 -0
- data/lib/aidp/cli.rb +45 -464
- data/lib/aidp/config.rb +54 -0
- data/lib/aidp/daemon/runner.rb +2 -2
- data/lib/aidp/debug_mixin.rb +25 -10
- data/lib/aidp/execute/agent_signal_parser.rb +22 -0
- 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/repl_macros.rb +2 -2
- data/lib/aidp/execute/steps.rb +94 -1
- data/lib/aidp/execute/work_loop_runner.rb +238 -19
- data/lib/aidp/execute/workflow_selector.rb +4 -27
- data/lib/aidp/firewall/provider_requirements_collector.rb +262 -0
- data/lib/aidp/harness/ai_decision_engine.rb +35 -2
- data/lib/aidp/harness/config_manager.rb +5 -10
- data/lib/aidp/harness/config_schema.rb +8 -0
- data/lib/aidp/harness/configuration.rb +40 -2
- data/lib/aidp/harness/enhanced_runner.rb +25 -19
- data/lib/aidp/harness/error_handler.rb +23 -73
- 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/provider_factory.rb +11 -2
- data/lib/aidp/harness/runner.rb +5 -0
- data/lib/aidp/harness/state_manager.rb +0 -7
- data/lib/aidp/harness/thinking_depth_manager.rb +202 -7
- data/lib/aidp/harness/ui/enhanced_tui.rb +8 -18
- data/lib/aidp/harness/ui/enhanced_workflow_selector.rb +0 -18
- data/lib/aidp/harness/ui/progress_display.rb +6 -2
- data/lib/aidp/harness/user_interface.rb +0 -58
- data/lib/aidp/init/runner.rb +7 -2
- data/lib/aidp/message_display.rb +0 -46
- data/lib/aidp/planning/analyzers/feedback_analyzer.rb +365 -0
- data/lib/aidp/planning/builders/agile_plan_builder.rb +387 -0
- data/lib/aidp/planning/builders/project_plan_builder.rb +193 -0
- data/lib/aidp/planning/generators/gantt_generator.rb +190 -0
- data/lib/aidp/planning/generators/iteration_plan_generator.rb +392 -0
- data/lib/aidp/planning/generators/legacy_research_planner.rb +473 -0
- data/lib/aidp/planning/generators/marketing_report_generator.rb +348 -0
- data/lib/aidp/planning/generators/mvp_scope_generator.rb +310 -0
- data/lib/aidp/planning/generators/user_test_plan_generator.rb +373 -0
- data/lib/aidp/planning/generators/wbs_generator.rb +259 -0
- data/lib/aidp/planning/mappers/persona_mapper.rb +163 -0
- data/lib/aidp/planning/parsers/document_parser.rb +141 -0
- data/lib/aidp/planning/parsers/feedback_data_parser.rb +252 -0
- data/lib/aidp/provider_manager.rb +8 -32
- data/lib/aidp/providers/adapter.rb +2 -4
- data/lib/aidp/providers/aider.rb +264 -0
- data/lib/aidp/providers/anthropic.rb +206 -121
- data/lib/aidp/providers/base.rb +123 -3
- data/lib/aidp/providers/capability_registry.rb +0 -1
- data/lib/aidp/providers/codex.rb +75 -70
- data/lib/aidp/providers/cursor.rb +87 -59
- data/lib/aidp/providers/gemini.rb +57 -60
- data/lib/aidp/providers/github_copilot.rb +19 -66
- data/lib/aidp/providers/kilocode.rb +35 -80
- data/lib/aidp/providers/opencode.rb +35 -80
- data/lib/aidp/setup/wizard.rb +555 -8
- data/lib/aidp/version.rb +1 -1
- data/lib/aidp/watch/build_processor.rb +211 -30
- data/lib/aidp/watch/change_request_processor.rb +128 -14
- data/lib/aidp/watch/ci_fix_processor.rb +103 -37
- data/lib/aidp/watch/ci_log_extractor.rb +258 -0
- data/lib/aidp/watch/github_state_extractor.rb +177 -0
- data/lib/aidp/watch/implementation_verifier.rb +284 -0
- data/lib/aidp/watch/plan_generator.rb +95 -52
- data/lib/aidp/watch/plan_processor.rb +7 -6
- data/lib/aidp/watch/repository_client.rb +245 -17
- data/lib/aidp/watch/review_processor.rb +100 -19
- data/lib/aidp/watch/reviewers/base_reviewer.rb +1 -1
- data/lib/aidp/watch/runner.rb +181 -29
- data/lib/aidp/watch/state_store.rb +22 -1
- data/lib/aidp/workflows/definitions.rb +147 -0
- data/lib/aidp/workflows/guided_agent.rb +3 -3
- data/lib/aidp/workstream_cleanup.rb +245 -0
- data/lib/aidp/worktree.rb +19 -0
- data/templates/aidp-development.yml.example +2 -2
- data/templates/aidp-production.yml.example +3 -3
- data/templates/aidp.yml.example +57 -0
- data/templates/implementation/generate_tdd_specs.md +213 -0
- data/templates/implementation/iterative_implementation.md +122 -0
- data/templates/planning/agile/analyze_feedback.md +183 -0
- data/templates/planning/agile/generate_iteration_plan.md +179 -0
- data/templates/planning/agile/generate_legacy_research_plan.md +171 -0
- data/templates/planning/agile/generate_marketing_report.md +162 -0
- data/templates/planning/agile/generate_mvp_scope.md +127 -0
- data/templates/planning/agile/generate_user_test_plan.md +143 -0
- data/templates/planning/agile/ingest_feedback.md +174 -0
- data/templates/planning/assemble_project_plan.md +113 -0
- data/templates/planning/assign_personas.md +108 -0
- data/templates/planning/create_tasks.md +52 -6
- data/templates/planning/generate_gantt.md +86 -0
- data/templates/planning/generate_wbs.md +85 -0
- data/templates/planning/initialize_planning_mode.md +70 -0
- data/templates/skills/README.md +2 -2
- data/templates/skills/marketing_strategist/SKILL.md +279 -0
- data/templates/skills/product_manager/SKILL.md +177 -0
- data/templates/skills/ruby_aidp_planning/SKILL.md +497 -0
- data/templates/skills/ruby_rspec_tdd/SKILL.md +514 -0
- data/templates/skills/ux_researcher/SKILL.md +222 -0
- metadata +47 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 931d08a58cf52b7acc999d7e3320181c29710c50922463f4fb5c4e0a76c02e04
|
|
4
|
+
data.tar.gz: 1971534889d0fde6daa6d8da6f345ffac4a698f827a205e445f75e7fa26d38da
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b87667e112faeb9818187eb97e281539e936ad213dcd49867781b37ff57ae9c827308cb9d4f7bdf707e48133fc3efcc79d1815d5a9b12cb3b395aad5d0e432cf
|
|
7
|
+
data.tar.gz: 5b9fa041a4e680115248fad3fad2ccd7c8ab9cc956a471051b2e2945b1d2277cfea2af7f1d3f105dd36e8e9be1f149f42fb91080496f055deb0c26e8daef1427
|
data/README.md
CHANGED
|
@@ -135,6 +135,95 @@ AIDP implements **work loops** - an iterative execution pattern where AI agents
|
|
|
135
135
|
|
|
136
136
|
See [Work Loops Guide](docs/WORK_LOOPS_GUIDE.md) for details.
|
|
137
137
|
|
|
138
|
+
### Waterfall Planning Mode
|
|
139
|
+
|
|
140
|
+
Create comprehensive project plans with work breakdown structures, Gantt charts, and automated task assignments:
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
# Start planning workflow
|
|
144
|
+
aidp execute
|
|
145
|
+
# Select "Waterfall Planning"
|
|
146
|
+
|
|
147
|
+
# Choose your path:
|
|
148
|
+
# - Ingest existing documentation (PRDs, design docs)
|
|
149
|
+
# - Generate from scratch through AI dialogue
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
**Generated Artifacts** (in `.aidp/docs/`):
|
|
153
|
+
|
|
154
|
+
- **PRD.md** - Product requirements document
|
|
155
|
+
- **TECH_DESIGN.md** - Technical architecture and design
|
|
156
|
+
- **WBS.md** - Work breakdown structure with phases and tasks
|
|
157
|
+
- **GANTT.md** - Mermaid Gantt chart with critical path analysis
|
|
158
|
+
- **persona_map.yml** - AI-powered task-to-persona assignments
|
|
159
|
+
- **PROJECT_PLAN.md** - Complete integrated project plan
|
|
160
|
+
|
|
161
|
+
**Key Features:**
|
|
162
|
+
|
|
163
|
+
- **Documentation Ingestion** - Import and enhance existing project docs
|
|
164
|
+
- **AI-Guided Planning** - Generate complete plans through dialogue
|
|
165
|
+
- **Critical Path Analysis** - Identify project bottlenecks
|
|
166
|
+
- **Zero Framework Cognition** - AI-powered persona assignment (no heuristics)
|
|
167
|
+
- **Mermaid Visualizations** - Gantt charts renderable on GitHub/GitLab
|
|
168
|
+
- **TDD Integration** - Optional test-driven development workflow
|
|
169
|
+
|
|
170
|
+
See [Waterfall Planning Mode Guide](docs/WATERFALL_PLANNING_MODE.md) for complete documentation.
|
|
171
|
+
|
|
172
|
+
### Agile Development Mode
|
|
173
|
+
|
|
174
|
+
Build products iteratively with user feedback loops, MVP scoping, and data-driven iteration planning:
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
# Start planning workflow
|
|
178
|
+
aidp execute
|
|
179
|
+
# Select "Agile MVP Planning", "Agile Iteration Planning", or "Legacy Product Research"
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
**Three Agile Workflows:**
|
|
183
|
+
|
|
184
|
+
#### 1. MVP Planning
|
|
185
|
+
|
|
186
|
+
Define minimum viable product scope, create user testing plans, and generate marketing materials:
|
|
187
|
+
|
|
188
|
+
- **Input**: Product Requirements Document (PRD)
|
|
189
|
+
- **Outputs**: MVP scope, user testing plan, marketing report
|
|
190
|
+
- **Use case**: Launching a new product with user validation
|
|
191
|
+
|
|
192
|
+
#### 2. Iteration Planning
|
|
193
|
+
|
|
194
|
+
Analyze user feedback and plan next development iteration:
|
|
195
|
+
|
|
196
|
+
- **Input**: User feedback data (CSV/JSON/markdown)
|
|
197
|
+
- **Outputs**: Feedback analysis, iteration plan with prioritized tasks
|
|
198
|
+
- **Use case**: Improving product based on real user data
|
|
199
|
+
|
|
200
|
+
#### 3. Legacy Research
|
|
201
|
+
|
|
202
|
+
Analyze existing codebase and create user research plan:
|
|
203
|
+
|
|
204
|
+
- **Input**: Codebase path and language
|
|
205
|
+
- **Outputs**: Research plan, feature audit, testing strategy
|
|
206
|
+
- **Use case**: Understanding user needs for existing product
|
|
207
|
+
|
|
208
|
+
**Generated Artifacts** (in `.aidp/docs/`):
|
|
209
|
+
|
|
210
|
+
- **MVP_SCOPE.md** - Must-have vs nice-to-have feature breakdown
|
|
211
|
+
- **USER_TEST_PLAN.md** - Comprehensive user testing strategy
|
|
212
|
+
- **MARKETING_REPORT.md** - Value propositions and messaging
|
|
213
|
+
- **USER_FEEDBACK_ANALYSIS.md** - AI-powered semantic feedback analysis
|
|
214
|
+
- **NEXT_ITERATION_PLAN.md** - Prioritized tasks for next iteration
|
|
215
|
+
- **LEGACY_USER_RESEARCH_PLAN.md** - Research strategy for existing product
|
|
216
|
+
|
|
217
|
+
**Key Features:**
|
|
218
|
+
|
|
219
|
+
- **Zero Framework Cognition** - AI-powered semantic analysis (no heuristics)
|
|
220
|
+
- **Multi-Format Support** - Ingest feedback from CSV, JSON, or markdown
|
|
221
|
+
- **Iterative Loops** - Continuous improvement based on user data
|
|
222
|
+
- **Marketing Focus** - Translate features into customer value
|
|
223
|
+
- **Three New Personas** - Product Manager, UX Researcher, Marketing Strategist
|
|
224
|
+
|
|
225
|
+
See [Agile Development Mode Guide](docs/AGILE_MODE_GUIDE.md) for complete documentation.
|
|
226
|
+
|
|
138
227
|
### Job Management
|
|
139
228
|
|
|
140
229
|
Monitor and control background jobs:
|
|
@@ -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]
|