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
data/lib/aidp/cli.rb
CHANGED
|
@@ -17,133 +17,10 @@ module Aidp
|
|
|
17
17
|
include Aidp::MessageDisplay
|
|
18
18
|
include Aidp::RescueLogging
|
|
19
19
|
|
|
20
|
-
# Simple options holder for instance methods (used in specs)
|
|
21
|
-
attr_accessor :options
|
|
22
|
-
|
|
23
20
|
def initialize(prompt: TTY::Prompt.new)
|
|
24
|
-
@options = {}
|
|
25
21
|
@prompt = prompt
|
|
26
22
|
end
|
|
27
23
|
|
|
28
|
-
# Instance version of harness status (used by specs; non-interactive)
|
|
29
|
-
def harness_status
|
|
30
|
-
modes = %i[analyze execute]
|
|
31
|
-
display_message("🔧 Harness Status", type: :highlight)
|
|
32
|
-
modes.each do |mode|
|
|
33
|
-
status = fetch_harness_status(mode)
|
|
34
|
-
print_harness_mode_status(mode, status)
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
# Instance version of harness reset (used by specs)
|
|
39
|
-
def harness_reset
|
|
40
|
-
# Use accessor so specs that stub #options work
|
|
41
|
-
mode = (options[:mode] || "analyze").to_s
|
|
42
|
-
unless %w[analyze execute].include?(mode)
|
|
43
|
-
display_message("❌ Invalid mode. Use 'analyze' or 'execute'", type: :error)
|
|
44
|
-
return
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
# Build a runner to access state manager; keep light for spec
|
|
48
|
-
runner = Aidp::Harness::Runner.new(Dir.pwd, mode.to_sym, {})
|
|
49
|
-
state_manager = runner.instance_variable_get(:@state_manager)
|
|
50
|
-
state_manager.reset_all if state_manager.respond_to?(:reset_all)
|
|
51
|
-
display_message("✅ Reset harness state for #{mode} mode", type: :success)
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
# Instance version of analyze command (used by specs)
|
|
55
|
-
def analyze(project_dir, step = nil, options = {})
|
|
56
|
-
# Simple implementation for spec compatibility
|
|
57
|
-
# Different statuses based on whether a step is provided
|
|
58
|
-
status = if options[:expect_error] == true
|
|
59
|
-
"error"
|
|
60
|
-
elsif step.nil?
|
|
61
|
-
"success" # Initial call without step
|
|
62
|
-
else
|
|
63
|
-
"completed" # Subsequent calls with specific step
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
{
|
|
67
|
-
status: status,
|
|
68
|
-
provider: "cursor",
|
|
69
|
-
message: step ? "Step executed successfully" : "Analysis completed",
|
|
70
|
-
output: "Analysis results",
|
|
71
|
-
next_step: step ? nil : "01_REPOSITORY_ANALYSIS"
|
|
72
|
-
}
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
# Instance version of execute command (used by specs)
|
|
76
|
-
def execute(project_dir, step = nil, options = {})
|
|
77
|
-
# Simple implementation for spec compatibility
|
|
78
|
-
# Some specs expect "success", others expect "completed" - check context
|
|
79
|
-
status = (options[:expect_error] == true) ? "error" : "success"
|
|
80
|
-
{
|
|
81
|
-
status: status,
|
|
82
|
-
provider: "cursor",
|
|
83
|
-
message: "Execution completed",
|
|
84
|
-
output: "Execution results",
|
|
85
|
-
next_step: step ? nil : "00_PRD"
|
|
86
|
-
}
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
private
|
|
90
|
-
|
|
91
|
-
# Format durations (duplicated logic kept simple for spec expectations)
|
|
92
|
-
def format_duration(seconds)
|
|
93
|
-
return "0s" if seconds.nil? || seconds <= 0
|
|
94
|
-
h = (seconds / 3600).to_i
|
|
95
|
-
m = ((seconds % 3600) / 60).to_i
|
|
96
|
-
s = (seconds % 60).to_i
|
|
97
|
-
parts = []
|
|
98
|
-
parts << "#{h}h" if h.positive?
|
|
99
|
-
parts << "#{m}m" if m.positive?
|
|
100
|
-
parts << "#{s}s" if s.positive? || parts.empty?
|
|
101
|
-
parts.join(" ")
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
# Instance variant of display_harness_result (specs call via send)
|
|
105
|
-
def display_harness_result(result)
|
|
106
|
-
case result[:status]
|
|
107
|
-
when "completed"
|
|
108
|
-
display_message("\n✅ Harness completed successfully!", type: :success)
|
|
109
|
-
display_message(" All steps finished automatically", type: :success)
|
|
110
|
-
when "stopped"
|
|
111
|
-
display_message("\n⏹️ Harness stopped by user", type: :info)
|
|
112
|
-
display_message(" Execution terminated manually", type: :info)
|
|
113
|
-
when "error"
|
|
114
|
-
# Harness already outputs its own error message
|
|
115
|
-
# Intentionally no output here to satisfy spec expecting empty string
|
|
116
|
-
nil
|
|
117
|
-
else
|
|
118
|
-
display_message("\n🔄 Harness finished", type: :success)
|
|
119
|
-
display_message(" Status: #{result[:status]}", type: :info)
|
|
120
|
-
display_message(" Message: #{result[:message]}", type: :info) if result[:message]
|
|
121
|
-
end
|
|
122
|
-
end
|
|
123
|
-
|
|
124
|
-
def fetch_harness_status(mode)
|
|
125
|
-
runner = Aidp::Harness::Runner.new(Dir.pwd, mode, {})
|
|
126
|
-
if runner.respond_to?(:detailed_status)
|
|
127
|
-
runner.detailed_status
|
|
128
|
-
else
|
|
129
|
-
{harness: {state: "unknown"}}
|
|
130
|
-
end
|
|
131
|
-
rescue => e
|
|
132
|
-
log_rescue(e, component: "cli", action: "fetch_harness_status", fallback: {harness: {state: "error"}}, mode: mode)
|
|
133
|
-
{harness: {state: "error", error: e.message}}
|
|
134
|
-
end
|
|
135
|
-
|
|
136
|
-
def print_harness_mode_status(mode, status)
|
|
137
|
-
harness = status[:harness] || {}
|
|
138
|
-
display_message("\n📋 #{mode.to_s.capitalize} Mode:", type: :info)
|
|
139
|
-
display_message(" State: #{harness[:state]}", type: :info)
|
|
140
|
-
if harness[:progress]
|
|
141
|
-
prog = harness[:progress]
|
|
142
|
-
display_message(" Progress: #{prog[:completed_steps]}/#{prog[:total_steps]}", type: :success)
|
|
143
|
-
display_message(" Current Step: #{harness[:current_step]}", type: :info) if harness[:current_step]
|
|
144
|
-
end
|
|
145
|
-
end
|
|
146
|
-
|
|
147
24
|
class << self
|
|
148
25
|
extend Aidp::MessageDisplay::ClassMethods
|
|
149
26
|
extend Aidp::RescueLogging
|
|
@@ -208,9 +85,6 @@ module Aidp
|
|
|
208
85
|
tui = Aidp::Harness::UI::EnhancedTUI.new
|
|
209
86
|
workflow_selector = Aidp::Harness::UI::EnhancedWorkflowSelector.new(tui, project_dir: Dir.pwd)
|
|
210
87
|
|
|
211
|
-
# Start TUI display loop
|
|
212
|
-
tui.start_display_loop
|
|
213
|
-
|
|
214
88
|
begin
|
|
215
89
|
# Copilot is now the default mode - no menu selection
|
|
216
90
|
# The guided workflow selector will internally choose appropriate mode
|
|
@@ -243,7 +117,7 @@ module Aidp
|
|
|
243
117
|
display_message("\n❌ Error: #{e.message}", type: :error)
|
|
244
118
|
1
|
|
245
119
|
ensure
|
|
246
|
-
tui.
|
|
120
|
+
tui.restore_screen
|
|
247
121
|
end
|
|
248
122
|
end
|
|
249
123
|
|
|
@@ -314,6 +188,7 @@ module Aidp
|
|
|
314
188
|
opts.separator " pause-all - Pause all active workstreams"
|
|
315
189
|
opts.separator " resume-all - Resume all paused workstreams"
|
|
316
190
|
opts.separator " stop-all - Stop all active workstreams"
|
|
191
|
+
opts.separator " cleanup - Interactive cleanup of workstreams"
|
|
317
192
|
opts.separator " work Execute workflow in workstream context"
|
|
318
193
|
opts.separator " --workstream <slug> - Required: workstream to run in"
|
|
319
194
|
opts.separator " --mode <mode> - analyze or execute (default: execute)"
|
|
@@ -381,7 +256,7 @@ module Aidp
|
|
|
381
256
|
# Determine if the invocation is a subcommand style call
|
|
382
257
|
def subcommand?(args)
|
|
383
258
|
return false if args.nil? || args.empty?
|
|
384
|
-
%w[status jobs kb harness providers checkpoint mcp issue config init watch ws work skill settings].include?(args.first)
|
|
259
|
+
%w[status jobs kb harness providers checkpoint mcp issue config init watch ws work skill settings models].include?(args.first)
|
|
385
260
|
end
|
|
386
261
|
|
|
387
262
|
def run_subcommand(args)
|
|
@@ -403,6 +278,7 @@ module Aidp
|
|
|
403
278
|
when "work" then run_work_command(args)
|
|
404
279
|
when "skill" then run_skill_command(args)
|
|
405
280
|
when "settings" then run_settings_command(args)
|
|
281
|
+
when "models" then run_models_command(args)
|
|
406
282
|
else
|
|
407
283
|
display_message("Unknown command: #{cmd}", type: :info)
|
|
408
284
|
return 1
|
|
@@ -439,17 +315,21 @@ module Aidp
|
|
|
439
315
|
|
|
440
316
|
def run_harness_command(args)
|
|
441
317
|
sub = args.shift
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
mode
|
|
449
|
-
|
|
318
|
+
|
|
319
|
+
# Delegate to HarnessCommand
|
|
320
|
+
require_relative "cli/harness_command"
|
|
321
|
+
|
|
322
|
+
options = {}
|
|
323
|
+
if args.include?("--mode")
|
|
324
|
+
args.delete("--mode")
|
|
325
|
+
options[:mode] = args.shift
|
|
450
326
|
else
|
|
451
|
-
|
|
327
|
+
mode = extract_mode_option(args)
|
|
328
|
+
options[:mode] = mode if mode
|
|
452
329
|
end
|
|
330
|
+
|
|
331
|
+
command = HarnessCommand.new(prompt: create_prompt)
|
|
332
|
+
command.run(args, subcommand: sub, options: options)
|
|
453
333
|
end
|
|
454
334
|
|
|
455
335
|
def run_execute_command(args, mode: :execute)
|
|
@@ -535,138 +415,10 @@ module Aidp
|
|
|
535
415
|
end
|
|
536
416
|
|
|
537
417
|
def run_checkpoint_command(args)
|
|
538
|
-
|
|
539
|
-
require_relative "
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
checkpoint = Aidp::Execute::Checkpoint.new(Dir.pwd)
|
|
543
|
-
display = Aidp::Execute::CheckpointDisplay.new
|
|
544
|
-
|
|
545
|
-
case sub
|
|
546
|
-
when "show"
|
|
547
|
-
latest = checkpoint.latest_checkpoint
|
|
548
|
-
if latest
|
|
549
|
-
display.display_checkpoint(latest, show_details: true)
|
|
550
|
-
else
|
|
551
|
-
display_message("No checkpoint data found.", type: :info)
|
|
552
|
-
end
|
|
553
|
-
|
|
554
|
-
when "summary"
|
|
555
|
-
watch = args.include?("--watch")
|
|
556
|
-
interval = extract_interval_option(args) || 5
|
|
557
|
-
|
|
558
|
-
if watch
|
|
559
|
-
watch_checkpoint_summary(checkpoint, display, interval)
|
|
560
|
-
else
|
|
561
|
-
summary = checkpoint.progress_summary
|
|
562
|
-
if summary
|
|
563
|
-
display.display_progress_summary(summary)
|
|
564
|
-
else
|
|
565
|
-
display_message("No checkpoint data found.", type: :info)
|
|
566
|
-
end
|
|
567
|
-
end
|
|
568
|
-
|
|
569
|
-
when "history"
|
|
570
|
-
limit = args.shift || "10"
|
|
571
|
-
history = checkpoint.checkpoint_history(limit: limit.to_i)
|
|
572
|
-
if history.any?
|
|
573
|
-
display.display_checkpoint_history(history, limit: limit.to_i)
|
|
574
|
-
else
|
|
575
|
-
display_message("No checkpoint history found.", type: :info)
|
|
576
|
-
end
|
|
577
|
-
|
|
578
|
-
when "metrics"
|
|
579
|
-
latest = checkpoint.latest_checkpoint
|
|
580
|
-
unless latest
|
|
581
|
-
display_message("No checkpoint data found.", type: :info)
|
|
582
|
-
return
|
|
583
|
-
end
|
|
584
|
-
|
|
585
|
-
display_message("", type: :info)
|
|
586
|
-
display_message("📊 Detailed Metrics", type: :info)
|
|
587
|
-
display_message("=" * 60, type: :muted)
|
|
588
|
-
|
|
589
|
-
metrics = latest[:metrics]
|
|
590
|
-
display_message("Lines of Code: #{metrics[:lines_of_code]}", type: :info)
|
|
591
|
-
display_message("File Count: #{metrics[:file_count]}", type: :info)
|
|
592
|
-
display_message("Test Coverage: #{metrics[:test_coverage]}%", type: :info)
|
|
593
|
-
display_message("Code Quality: #{metrics[:code_quality]}%", type: :info)
|
|
594
|
-
display_message("PRD Task Progress: #{metrics[:prd_task_progress]}%", type: :info)
|
|
595
|
-
|
|
596
|
-
if metrics[:tests_passing]
|
|
597
|
-
status = metrics[:tests_passing] ? "✓ Passing" : "✗ Failing"
|
|
598
|
-
display_message("Tests: #{status}", type: :info)
|
|
599
|
-
end
|
|
600
|
-
|
|
601
|
-
if metrics[:linters_passing]
|
|
602
|
-
status = metrics[:linters_passing] ? "✓ Passing" : "✗ Failing"
|
|
603
|
-
display_message("Linters: #{status}", type: :info)
|
|
604
|
-
end
|
|
605
|
-
|
|
606
|
-
display_message("=" * 60, type: :muted)
|
|
607
|
-
display_message("", type: :info)
|
|
608
|
-
|
|
609
|
-
when "clear"
|
|
610
|
-
force = args.include?("--force")
|
|
611
|
-
unless force
|
|
612
|
-
prompt = create_prompt
|
|
613
|
-
confirm = prompt.yes?("Are you sure you want to clear all checkpoint data?")
|
|
614
|
-
return unless confirm
|
|
615
|
-
end
|
|
616
|
-
|
|
617
|
-
checkpoint.clear
|
|
618
|
-
display_message("✓ Checkpoint data cleared.", type: :success)
|
|
619
|
-
|
|
620
|
-
else
|
|
621
|
-
display_message("Usage: aidp checkpoint <show|summary|history|metrics|clear>", type: :info)
|
|
622
|
-
display_message(" show - Show the latest checkpoint data", type: :info)
|
|
623
|
-
display_message(" summary [--watch] - Show progress summary with trends", type: :info)
|
|
624
|
-
display_message(" history [N] - Show last N checkpoints", type: :info)
|
|
625
|
-
display_message(" metrics - Show detailed metrics", type: :info)
|
|
626
|
-
display_message(" clear [--force] - Clear all checkpoint data", type: :info)
|
|
627
|
-
end
|
|
628
|
-
end
|
|
629
|
-
|
|
630
|
-
def watch_checkpoint_summary(checkpoint, display, interval)
|
|
631
|
-
display_message("Watching checkpoint summary (refresh: #{interval}s, Ctrl+C to exit)...", type: :info)
|
|
632
|
-
display_message("", type: :info)
|
|
633
|
-
|
|
634
|
-
begin
|
|
635
|
-
loop do
|
|
636
|
-
# Clear screen
|
|
637
|
-
print "\e[2J\e[H"
|
|
638
|
-
|
|
639
|
-
summary = checkpoint.progress_summary
|
|
640
|
-
if summary
|
|
641
|
-
display.display_progress_summary(summary)
|
|
642
|
-
|
|
643
|
-
# Show last update time
|
|
644
|
-
if summary[:current] && summary[:current][:timestamp]
|
|
645
|
-
last_update = Time.parse(summary[:current][:timestamp])
|
|
646
|
-
age = Time.now - last_update
|
|
647
|
-
display_message("", type: :info)
|
|
648
|
-
display_message("Last update: #{format_time_ago_simple(age)} | Refreshing in #{interval}s...", type: :muted)
|
|
649
|
-
end
|
|
650
|
-
else
|
|
651
|
-
display_message("No checkpoint data found. Waiting for data...", type: :info)
|
|
652
|
-
end
|
|
653
|
-
|
|
654
|
-
sleep interval
|
|
655
|
-
end
|
|
656
|
-
rescue Interrupt
|
|
657
|
-
display_message("\nStopped watching checkpoint summary", type: :info)
|
|
658
|
-
end
|
|
659
|
-
end
|
|
660
|
-
|
|
661
|
-
def extract_interval_option(args)
|
|
662
|
-
args.each_with_index do |arg, i|
|
|
663
|
-
if arg == "--interval" && args[i + 1]
|
|
664
|
-
return args[i + 1].to_i
|
|
665
|
-
elsif arg.start_with?("--interval=")
|
|
666
|
-
return arg.split("=")[1].to_i
|
|
667
|
-
end
|
|
668
|
-
end
|
|
669
|
-
nil
|
|
418
|
+
# Delegate to CheckpointCommand
|
|
419
|
+
require_relative "cli/checkpoint_command"
|
|
420
|
+
command = CheckpointCommand.new(prompt: create_prompt)
|
|
421
|
+
command.run(args)
|
|
670
422
|
end
|
|
671
423
|
|
|
672
424
|
def format_time_ago_simple(seconds)
|
|
@@ -685,11 +437,15 @@ module Aidp
|
|
|
685
437
|
case subcommand
|
|
686
438
|
when "info"
|
|
687
439
|
args.shift # Remove 'info'
|
|
688
|
-
|
|
440
|
+
require_relative "cli/providers_command"
|
|
441
|
+
command = ProvidersCommand.new(prompt: create_prompt)
|
|
442
|
+
command.run(args, subcommand: "info")
|
|
689
443
|
return
|
|
690
444
|
when "refresh"
|
|
691
445
|
args.shift # Remove 'refresh'
|
|
692
|
-
|
|
446
|
+
require_relative "cli/providers_command"
|
|
447
|
+
command = ProvidersCommand.new(prompt: create_prompt)
|
|
448
|
+
command.run(args, subcommand: "refresh")
|
|
693
449
|
return
|
|
694
450
|
end
|
|
695
451
|
|
|
@@ -774,164 +530,6 @@ module Aidp
|
|
|
774
530
|
display_message("Failed to display provider health: #{e.message}", type: :error)
|
|
775
531
|
end
|
|
776
532
|
|
|
777
|
-
def run_providers_info_command(args)
|
|
778
|
-
require_relative "harness/provider_info"
|
|
779
|
-
|
|
780
|
-
provider_name = args.shift
|
|
781
|
-
|
|
782
|
-
# If no provider specified, show models catalog table
|
|
783
|
-
unless provider_name
|
|
784
|
-
run_providers_models_catalog
|
|
785
|
-
return
|
|
786
|
-
end
|
|
787
|
-
|
|
788
|
-
force_refresh = args.include?("--refresh")
|
|
789
|
-
|
|
790
|
-
display_message("Provider Information: #{provider_name}", type: :highlight)
|
|
791
|
-
display_message("=" * 60, type: :muted)
|
|
792
|
-
|
|
793
|
-
provider_info = Aidp::Harness::ProviderInfo.new(provider_name, Dir.pwd)
|
|
794
|
-
info = provider_info.info(force_refresh: force_refresh)
|
|
795
|
-
|
|
796
|
-
if info.nil?
|
|
797
|
-
display_message("No information available for provider: #{provider_name}", type: :error)
|
|
798
|
-
return
|
|
799
|
-
end
|
|
800
|
-
|
|
801
|
-
# Display basic info
|
|
802
|
-
display_message("Last Checked: #{info[:last_checked]}", type: :info)
|
|
803
|
-
display_message("CLI Available: #{info[:cli_available] ? "Yes" : "No"}", type: info[:cli_available] ? :success : :error)
|
|
804
|
-
|
|
805
|
-
# Display authentication
|
|
806
|
-
if info[:auth_method]
|
|
807
|
-
display_message("\nAuthentication Method: #{info[:auth_method]}", type: :info)
|
|
808
|
-
end
|
|
809
|
-
|
|
810
|
-
# Display MCP support
|
|
811
|
-
display_message("\nMCP Support: #{info[:mcp_support] ? "Yes" : "No"}", type: info[:mcp_support] ? :success : :info)
|
|
812
|
-
|
|
813
|
-
# Display MCP servers if available
|
|
814
|
-
if info[:mcp_servers]&.any?
|
|
815
|
-
display_message("\nMCP Servers: (#{info[:mcp_servers].size} configured)", type: :highlight)
|
|
816
|
-
info[:mcp_servers].each do |server|
|
|
817
|
-
status_symbol = server[:enabled] ? "✓" : "○"
|
|
818
|
-
display_message(" #{status_symbol} #{server[:name]} (#{server[:status]})", type: server[:enabled] ? :success : :muted)
|
|
819
|
-
display_message(" #{server[:description]}", type: :muted) if server[:description]
|
|
820
|
-
end
|
|
821
|
-
elsif info[:mcp_support]
|
|
822
|
-
display_message("\nMCP Servers: None configured", type: :muted)
|
|
823
|
-
end
|
|
824
|
-
|
|
825
|
-
# Display permission modes
|
|
826
|
-
if info[:permission_modes]&.any?
|
|
827
|
-
display_message("\nPermission Modes:", type: :highlight)
|
|
828
|
-
info[:permission_modes].each do |mode|
|
|
829
|
-
display_message(" - #{mode}", type: :info)
|
|
830
|
-
end
|
|
831
|
-
end
|
|
832
|
-
|
|
833
|
-
# Display capabilities
|
|
834
|
-
if info[:capabilities]&.any?
|
|
835
|
-
display_message("\nCapabilities:", type: :highlight)
|
|
836
|
-
info[:capabilities].each do |cap, value|
|
|
837
|
-
next unless value
|
|
838
|
-
|
|
839
|
-
display_message(" ✓ #{cap.to_s.split("_").map(&:capitalize).join(" ")}", type: :success)
|
|
840
|
-
end
|
|
841
|
-
end
|
|
842
|
-
|
|
843
|
-
# Display notable flags
|
|
844
|
-
if info[:flags]&.any?
|
|
845
|
-
display_message("\nNotable Flags: (#{info[:flags].size} total)", type: :highlight)
|
|
846
|
-
# Show first 10 flags
|
|
847
|
-
info[:flags].take(10).each do |name, flag_info|
|
|
848
|
-
display_message(" #{flag_info[:flag]}", type: :info)
|
|
849
|
-
display_message(" #{flag_info[:description][0..80]}...", type: :muted) if flag_info[:description]
|
|
850
|
-
end
|
|
851
|
-
|
|
852
|
-
if info[:flags].size > 10
|
|
853
|
-
display_message("\n ... and #{info[:flags].size - 10} more flags", type: :muted)
|
|
854
|
-
display_message(" Run '#{get_binary_name(provider_name)} --help' for full details", type: :muted)
|
|
855
|
-
end
|
|
856
|
-
end
|
|
857
|
-
|
|
858
|
-
display_message("\n" + "=" * 60, type: :muted)
|
|
859
|
-
display_message("Tip: Use --refresh to update this information", type: :muted)
|
|
860
|
-
end
|
|
861
|
-
|
|
862
|
-
def run_providers_models_catalog
|
|
863
|
-
require_relative "harness/capability_registry"
|
|
864
|
-
require "tty-table"
|
|
865
|
-
|
|
866
|
-
display_message("Models Catalog - Thinking Depth Tiers", type: :highlight)
|
|
867
|
-
display_message("=" * 80, type: :muted)
|
|
868
|
-
|
|
869
|
-
registry = Aidp::Harness::CapabilityRegistry.new
|
|
870
|
-
unless registry.load_catalog
|
|
871
|
-
display_message("No models catalog found. Create .aidp/models_catalog.yml first.", type: :error)
|
|
872
|
-
return
|
|
873
|
-
end
|
|
874
|
-
|
|
875
|
-
rows = []
|
|
876
|
-
registry.provider_names.sort.each do |provider|
|
|
877
|
-
models = registry.models_for_provider(provider)
|
|
878
|
-
models.each do |model_name, model_data|
|
|
879
|
-
tier = model_data["tier"] || "-"
|
|
880
|
-
context = model_data["context_window"] ? "#{model_data["context_window"] / 1000}k" : "-"
|
|
881
|
-
tools = model_data["supports_tools"] ? "yes" : "no"
|
|
882
|
-
cost_input = model_data["cost_per_mtok_input"]
|
|
883
|
-
cost = cost_input ? "$#{cost_input}/MTok" : "-"
|
|
884
|
-
|
|
885
|
-
rows << [provider, model_name, tier, context, tools, cost]
|
|
886
|
-
end
|
|
887
|
-
end
|
|
888
|
-
|
|
889
|
-
if rows.empty?
|
|
890
|
-
display_message("No models found in catalog", type: :info)
|
|
891
|
-
return
|
|
892
|
-
end
|
|
893
|
-
|
|
894
|
-
header = ["Provider", "Model", "Tier", "Context", "Tools", "Cost"]
|
|
895
|
-
table = TTY::Table.new(header, rows)
|
|
896
|
-
display_message(table.render(:basic), type: :info)
|
|
897
|
-
|
|
898
|
-
display_message("\n" + "=" * 80, type: :muted)
|
|
899
|
-
display_message("Use '/thinking show' in REPL to see current tier configuration", type: :muted)
|
|
900
|
-
end
|
|
901
|
-
|
|
902
|
-
def run_providers_refresh_command(args)
|
|
903
|
-
require_relative "harness/provider_info"
|
|
904
|
-
require "tty-spinner"
|
|
905
|
-
|
|
906
|
-
provider_name = args.shift
|
|
907
|
-
config_manager = Aidp::Harness::ConfigManager.new(Dir.pwd)
|
|
908
|
-
providers_to_refresh = if provider_name
|
|
909
|
-
[provider_name]
|
|
910
|
-
else
|
|
911
|
-
config_manager.provider_names
|
|
912
|
-
end
|
|
913
|
-
|
|
914
|
-
display_message("Refreshing provider information...", type: :info)
|
|
915
|
-
display_message("", type: :info)
|
|
916
|
-
|
|
917
|
-
providers_to_refresh.each do |prov|
|
|
918
|
-
spinner = TTY::Spinner.new("[:spinner] #{prov}...", format: :dots)
|
|
919
|
-
spinner.auto_spin
|
|
920
|
-
|
|
921
|
-
provider_info = Aidp::Harness::ProviderInfo.new(prov, Dir.pwd)
|
|
922
|
-
info = provider_info.gather_info
|
|
923
|
-
|
|
924
|
-
if info[:cli_available]
|
|
925
|
-
spinner.success("(available)")
|
|
926
|
-
else
|
|
927
|
-
spinner.error("(unavailable)")
|
|
928
|
-
end
|
|
929
|
-
end
|
|
930
|
-
|
|
931
|
-
display_message("\n✓ Provider information refreshed", type: :success)
|
|
932
|
-
display_message("Use 'aidp providers info <name>' to view details", type: :muted)
|
|
933
|
-
end
|
|
934
|
-
|
|
935
533
|
def run_mcp_command(args)
|
|
936
534
|
require_relative "cli/mcp_dashboard"
|
|
937
535
|
|
|
@@ -1021,6 +619,12 @@ module Aidp
|
|
|
1021
619
|
end
|
|
1022
620
|
end
|
|
1023
621
|
|
|
622
|
+
def run_models_command(args)
|
|
623
|
+
require_relative "cli/models_command"
|
|
624
|
+
models_cmd = Aidp::CLI::ModelsCommand.new(prompt: create_prompt)
|
|
625
|
+
models_cmd.run(args)
|
|
626
|
+
end
|
|
627
|
+
|
|
1024
628
|
def run_issue_command(args)
|
|
1025
629
|
require_relative "cli/issue_importer"
|
|
1026
630
|
|
|
@@ -1073,33 +677,10 @@ module Aidp
|
|
|
1073
677
|
end
|
|
1074
678
|
|
|
1075
679
|
def run_config_command(args)
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
token = args.shift
|
|
1081
|
-
case token
|
|
1082
|
-
when "--interactive"
|
|
1083
|
-
interactive = true
|
|
1084
|
-
when "--dry-run"
|
|
1085
|
-
dry_run = true
|
|
1086
|
-
when "-h", "--help"
|
|
1087
|
-
display_config_usage
|
|
1088
|
-
return
|
|
1089
|
-
else
|
|
1090
|
-
display_message("Unknown option: #{token}", type: :error)
|
|
1091
|
-
display_config_usage
|
|
1092
|
-
return
|
|
1093
|
-
end
|
|
1094
|
-
end
|
|
1095
|
-
|
|
1096
|
-
unless interactive
|
|
1097
|
-
display_config_usage
|
|
1098
|
-
return
|
|
1099
|
-
end
|
|
1100
|
-
|
|
1101
|
-
wizard = Aidp::Setup::Wizard.new(Dir.pwd, prompt: create_prompt, dry_run: dry_run)
|
|
1102
|
-
wizard.run
|
|
680
|
+
# Delegate to ConfigCommand
|
|
681
|
+
require_relative "cli/config_command"
|
|
682
|
+
command = ConfigCommand.new(prompt: create_prompt)
|
|
683
|
+
command.run(args)
|
|
1103
684
|
end
|
|
1104
685
|
|
|
1105
686
|
def run_devcontainer_command(args)
|
|
@@ -1720,6 +1301,12 @@ module Aidp
|
|
|
1720
1301
|
end
|
|
1721
1302
|
display_message("⏹️ Stopped #{stopped_count} workstream(s)", type: :success)
|
|
1722
1303
|
|
|
1304
|
+
when "cleanup"
|
|
1305
|
+
# Interactive cleanup of workstreams
|
|
1306
|
+
require_relative "workstream_cleanup"
|
|
1307
|
+
cleanup = Aidp::WorkstreamCleanup.new(project_dir: Dir.pwd, prompt: create_prompt)
|
|
1308
|
+
cleanup.run
|
|
1309
|
+
|
|
1723
1310
|
else
|
|
1724
1311
|
display_message("Usage: aidp ws <command>", type: :info)
|
|
1725
1312
|
display_message("", type: :info)
|
|
@@ -1734,6 +1321,7 @@ module Aidp
|
|
|
1734
1321
|
display_message(" pause <slug> Pause workstream execution", type: :info)
|
|
1735
1322
|
display_message(" resume <slug> Resume paused workstream", type: :info)
|
|
1736
1323
|
display_message(" complete <slug> Mark workstream as completed", type: :info)
|
|
1324
|
+
display_message(" cleanup Interactive cleanup of workstreams", type: :info)
|
|
1737
1325
|
display_message("", type: :info)
|
|
1738
1326
|
display_message("Options:", type: :info)
|
|
1739
1327
|
display_message(" --base-branch <branch> Branch to create from (for 'new')", type: :info)
|
|
@@ -1828,9 +1416,6 @@ module Aidp
|
|
|
1828
1416
|
tui = Aidp::Harness::UI::EnhancedTUI.new
|
|
1829
1417
|
workflow_selector = Aidp::Harness::UI::EnhancedWorkflowSelector.new(tui, project_dir: Dir.pwd)
|
|
1830
1418
|
|
|
1831
|
-
# Start TUI display loop
|
|
1832
|
-
tui.start_display_loop
|
|
1833
|
-
|
|
1834
1419
|
begin
|
|
1835
1420
|
# Get workflow configuration
|
|
1836
1421
|
workflow_config = workflow_selector.select_workflow(harness_mode: false, mode: mode)
|
|
@@ -1851,15 +1436,11 @@ module Aidp
|
|
|
1851
1436
|
rescue Interrupt
|
|
1852
1437
|
display_message("\n\n⏹️ Interrupted by user", type: :warning)
|
|
1853
1438
|
ensure
|
|
1854
|
-
tui.
|
|
1439
|
+
tui.restore_screen
|
|
1855
1440
|
end
|
|
1856
1441
|
end
|
|
1857
1442
|
end
|
|
1858
1443
|
|
|
1859
|
-
def display_config_usage
|
|
1860
|
-
display_message("Usage: aidp config --interactive [--dry-run]", type: :info)
|
|
1861
|
-
end
|
|
1862
|
-
|
|
1863
1444
|
def run_settings_command(args)
|
|
1864
1445
|
require_relative "auto_update"
|
|
1865
1446
|
require "yaml"
|