aidp 0.9.6 → 0.10.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/lib/aidp/analyze/error_handler.rb +4 -2
- data/lib/aidp/{analysis → analyze}/kb_inspector.rb +106 -89
- data/lib/aidp/analyze/prioritizer.rb +3 -2
- data/lib/aidp/analyze/ruby_maat_integration.rb +20 -3
- data/lib/aidp/analyze/runner.rb +27 -9
- data/lib/aidp/{analysis → analyze}/seams.rb +1 -1
- data/lib/aidp/analyze/steps.rb +7 -7
- data/lib/aidp/{analysis → analyze}/tree_sitter_grammar_loader.rb +22 -5
- data/lib/aidp/{analysis → analyze}/tree_sitter_scan.rb +32 -15
- data/lib/aidp/cli/first_run_wizard.rb +37 -28
- data/lib/aidp/cli/jobs_command.rb +37 -18
- data/lib/aidp/cli/terminal_io.rb +3 -3
- data/lib/aidp/cli.rb +131 -63
- data/lib/aidp/execute/runner.rb +27 -9
- data/lib/aidp/execute/steps.rb +18 -18
- data/lib/aidp/execute/workflow_selector.rb +36 -21
- data/lib/aidp/harness/enhanced_runner.rb +3 -3
- data/lib/aidp/harness/provider_factory.rb +3 -1
- data/lib/aidp/harness/provider_manager.rb +34 -15
- data/lib/aidp/harness/runner.rb +24 -5
- data/lib/aidp/harness/simple_user_interface.rb +19 -4
- data/lib/aidp/harness/status_display.rb +121 -104
- data/lib/aidp/harness/ui/enhanced_tui.rb +5 -5
- data/lib/aidp/harness/ui/error_handler.rb +3 -2
- data/lib/aidp/harness/ui/frame_manager.rb +52 -32
- data/lib/aidp/harness/ui/navigation/main_menu.rb +23 -14
- data/lib/aidp/harness/ui/progress_display.rb +28 -5
- data/lib/aidp/harness/ui/status_widget.rb +17 -8
- data/lib/aidp/harness/ui/workflow_controller.rb +25 -9
- data/lib/aidp/harness/user_interface.rb +341 -328
- data/lib/aidp/provider_manager.rb +10 -6
- data/lib/aidp/providers/anthropic.rb +3 -3
- data/lib/aidp/providers/base.rb +20 -1
- data/lib/aidp/providers/cursor.rb +6 -8
- data/lib/aidp/providers/gemini.rb +3 -3
- data/lib/aidp/providers/github_copilot.rb +264 -0
- data/lib/aidp/providers/opencode.rb +6 -8
- data/lib/aidp/version.rb +1 -1
- data/lib/aidp.rb +4 -4
- metadata +6 -6
- data/lib/aidp/analyze/progress_visualizer.rb +0 -314
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2358e7598866519630169447a6ba6fd60704571ca81afc8b6e9ec856916cacc1
|
4
|
+
data.tar.gz: a33aba24daef5e8492d36954b4a36c44fff738dc9b9a54762c81ac28708f2cfa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c37341e9a7a26a5bb23141133f08a67f26f5a88dcf1d5e12b36f638359f6e738cb4ffd86e15b0d8cc1c8282ecea31803faa6b0ff82c55bb1d9b63aaf987cc82b
|
7
|
+
data.tar.gz: 8b78de9305399181898a47542880840487ab667ccb7e151c4ff52d497437a5fd780440844c3b2585d6356c91c25378c7e73b15eebb1fa8f5e321bb46d4a79773
|
@@ -8,7 +8,8 @@ module Aidp
|
|
8
8
|
class ErrorHandler
|
9
9
|
attr_reader :logger, :error_counts, :recovery_strategies
|
10
10
|
|
11
|
-
def initialize(log_file: nil, verbose: false)
|
11
|
+
def initialize(log_file: nil, verbose: false, output: nil)
|
12
|
+
@output = output
|
12
13
|
@logger = setup_logger(log_file, verbose)
|
13
14
|
@error_counts = Hash.new(0)
|
14
15
|
@recovery_strategies = setup_recovery_strategies
|
@@ -87,7 +88,8 @@ module Aidp
|
|
87
88
|
private
|
88
89
|
|
89
90
|
def setup_logger(log_file, verbose)
|
90
|
-
|
91
|
+
output_stream = log_file || @output || $stdout
|
92
|
+
logger = Logger.new(output_stream)
|
91
93
|
logger.level = verbose ? Logger::DEBUG : Logger::INFO
|
92
94
|
logger.formatter = proc do |severity, datetime, progname, msg|
|
93
95
|
"#{datetime.strftime("%Y-%m-%d %H:%M:%S")} [#{severity}] #{msg}\n"
|
@@ -2,15 +2,32 @@
|
|
2
2
|
|
3
3
|
require "json"
|
4
4
|
require "tty-box"
|
5
|
+
require "tty-prompt"
|
5
6
|
|
6
7
|
module Aidp
|
7
|
-
module
|
8
|
+
module Analyze
|
8
9
|
class KBInspector
|
9
|
-
def initialize(kb_dir = ".aidp/kb")
|
10
|
+
def initialize(kb_dir = ".aidp/kb", prompt: TTY::Prompt.new)
|
10
11
|
@kb_dir = File.expand_path(kb_dir)
|
12
|
+
@prompt = prompt
|
11
13
|
@data = load_kb_data
|
12
14
|
end
|
13
15
|
|
16
|
+
# Helper method for consistent message display using TTY::Prompt
|
17
|
+
def display_message(message, type: :info)
|
18
|
+
color = case type
|
19
|
+
when :error then :red
|
20
|
+
when :success then :green
|
21
|
+
when :warning then :yellow
|
22
|
+
when :info then :blue
|
23
|
+
when :highlight then :cyan
|
24
|
+
when :muted then :bright_black
|
25
|
+
else :white
|
26
|
+
end
|
27
|
+
|
28
|
+
@prompt.say(message, color: color)
|
29
|
+
end
|
30
|
+
|
14
31
|
def show(type, format: "summary")
|
15
32
|
case type
|
16
33
|
when "seams"
|
@@ -28,8 +45,8 @@ module Aidp
|
|
28
45
|
when "summary"
|
29
46
|
show_summary(format)
|
30
47
|
else
|
31
|
-
|
32
|
-
|
48
|
+
display_message("Unknown KB type: #{type}", type: :error)
|
49
|
+
display_message("Available types: seams, hotspots, cycles, apis, symbols, imports, summary", type: :info)
|
33
50
|
end
|
34
51
|
end
|
35
52
|
|
@@ -42,8 +59,8 @@ module Aidp
|
|
42
59
|
when "cycles"
|
43
60
|
generate_cycle_graph(format, output)
|
44
61
|
else
|
45
|
-
|
46
|
-
|
62
|
+
display_message("Unknown graph type: #{type}", type: :error)
|
63
|
+
display_message("Available types: imports, calls, cycles", type: :info)
|
47
64
|
end
|
48
65
|
end
|
49
66
|
|
@@ -73,7 +90,7 @@ module Aidp
|
|
73
90
|
border: :thick,
|
74
91
|
padding: [1, 2]
|
75
92
|
)
|
76
|
-
|
93
|
+
display_message(box)
|
77
94
|
end
|
78
95
|
|
79
96
|
def load_kb_data
|
@@ -87,7 +104,7 @@ module Aidp
|
|
87
104
|
rescue JSON::ParserError => e
|
88
105
|
# Suppress warnings in test mode to avoid CI failures
|
89
106
|
unless ENV["RACK_ENV"] == "test" || defined?(RSpec)
|
90
|
-
|
107
|
+
display_message("Warning: Could not parse #{file_path}: #{e.message}", type: :warn)
|
91
108
|
end
|
92
109
|
data[type.to_sym] = []
|
93
110
|
end
|
@@ -100,42 +117,42 @@ module Aidp
|
|
100
117
|
end
|
101
118
|
|
102
119
|
def show_summary(_format)
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
120
|
+
display_message("\n📊 Knowledge Base Summary", type: :highlight)
|
121
|
+
display_message("=" * 50, type: :info)
|
122
|
+
|
123
|
+
display_message("📁 KB Directory: #{@kb_dir}", type: :info)
|
124
|
+
display_message("📄 Files analyzed: #{count_files}", type: :info)
|
125
|
+
display_message("🏗️ Symbols: #{@data[:symbols]&.length || 0}", type: :info)
|
126
|
+
display_message("📦 Imports: #{@data[:imports]&.length || 0}", type: :info)
|
127
|
+
display_message("🔗 Calls: #{@data[:calls]&.length || 0}", type: :info)
|
128
|
+
display_message("📏 Metrics: #{@data[:metrics]&.length || 0}", type: :info)
|
129
|
+
display_message("🔧 Seams: #{@data[:seams]&.length || 0}", type: :info)
|
130
|
+
display_message("🔥 Hotspots: #{@data[:hotspots]&.length || 0}", type: :info)
|
131
|
+
display_message("🧪 Tests: #{@data[:tests]&.length || 0}", type: :info)
|
132
|
+
display_message("🔄 Cycles: #{@data[:cycles]&.length || 0}", type: :info)
|
116
133
|
|
117
134
|
if @data[:seams]&.any?
|
118
|
-
|
135
|
+
display_message("\n🔧 Seam Types:", type: :info)
|
119
136
|
seam_types = @data[:seams].group_by { |s| s[:kind] }
|
120
137
|
seam_types.each do |type, seams|
|
121
|
-
|
138
|
+
display_message(" #{type}: #{seams.length}", type: :info)
|
122
139
|
end
|
123
140
|
end
|
124
141
|
|
125
142
|
if @data[:hotspots]&.any?
|
126
|
-
|
143
|
+
display_message("\n🔥 Top 5 Hotspots:", type: :info)
|
127
144
|
@data[:hotspots].first(5).each_with_index do |hotspot, i|
|
128
|
-
|
145
|
+
display_message(" #{i + 1}. #{hotspot[:file]}:#{hotspot[:method]} (score: #{hotspot[:score]})", type: :info)
|
129
146
|
end
|
130
147
|
end
|
131
148
|
end
|
132
149
|
|
133
150
|
def show_seams(format)
|
134
|
-
return
|
151
|
+
return display_message("No seams data available") unless @data[:seams]&.any?
|
135
152
|
|
136
153
|
case format
|
137
154
|
when "json"
|
138
|
-
|
155
|
+
display_message(JSON.pretty_generate(@data[:seams]))
|
139
156
|
when "table"
|
140
157
|
show_seams_table
|
141
158
|
else
|
@@ -144,8 +161,8 @@ module Aidp
|
|
144
161
|
end
|
145
162
|
|
146
163
|
def show_seams_table
|
147
|
-
|
148
|
-
|
164
|
+
display_message("\n🔧 Seams Analysis")
|
165
|
+
display_message("=" * 80)
|
149
166
|
|
150
167
|
create_table(
|
151
168
|
["Type", "File", "Line", "Symbol", "Suggestion"],
|
@@ -162,34 +179,34 @@ module Aidp
|
|
162
179
|
end
|
163
180
|
|
164
181
|
def show_seams_summary
|
165
|
-
|
166
|
-
|
182
|
+
display_message("\n🔧 Seams Analysis")
|
183
|
+
display_message("=" * 50)
|
167
184
|
|
168
185
|
seam_types = @data[:seams].group_by { |s| s[:kind] }
|
169
186
|
|
170
187
|
seam_types.each do |type, seams|
|
171
|
-
|
172
|
-
|
188
|
+
display_message("\n📌 #{type.upcase} (#{seams.length} found)")
|
189
|
+
display_message("-" * 30)
|
173
190
|
|
174
191
|
seams.first(10).each do |seam|
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
192
|
+
display_message(" #{seam[:file]}:#{seam[:line]}")
|
193
|
+
display_message(" Symbol: #{seam[:symbol_id]&.split(":")&.last}")
|
194
|
+
display_message(" Suggestion: #{seam[:suggestion]}")
|
195
|
+
display_message("")
|
179
196
|
end
|
180
197
|
|
181
198
|
if seams.length > 10
|
182
|
-
|
199
|
+
display_message(" ... and #{seams.length - 10} more")
|
183
200
|
end
|
184
201
|
end
|
185
202
|
end
|
186
203
|
|
187
204
|
def show_hotspots(format)
|
188
|
-
return
|
205
|
+
return display_message("No hotspots data available") unless @data[:hotspots]&.any?
|
189
206
|
|
190
207
|
case format
|
191
208
|
when "json"
|
192
|
-
|
209
|
+
display_message(JSON.pretty_generate(@data[:hotspots]))
|
193
210
|
when "table"
|
194
211
|
show_hotspots_table
|
195
212
|
else
|
@@ -198,8 +215,8 @@ module Aidp
|
|
198
215
|
end
|
199
216
|
|
200
217
|
def show_hotspots_table
|
201
|
-
|
202
|
-
|
218
|
+
display_message("\n🔥 Code Hotspots")
|
219
|
+
display_message("=" * 80)
|
203
220
|
|
204
221
|
create_table(
|
205
222
|
["Rank", "File", "Method", "Score", "Complexity", "Touches"],
|
@@ -217,81 +234,81 @@ module Aidp
|
|
217
234
|
end
|
218
235
|
|
219
236
|
def show_hotspots_summary
|
220
|
-
|
221
|
-
|
237
|
+
display_message("\n🔥 Code Hotspots (Top 20)")
|
238
|
+
display_message("=" * 50)
|
222
239
|
|
223
240
|
@data[:hotspots].each_with_index do |hotspot, i|
|
224
|
-
|
225
|
-
|
226
|
-
|
241
|
+
display_message("#{i + 1}. #{hotspot[:file]}:#{hotspot[:method]}")
|
242
|
+
display_message(" Score: #{hotspot[:score]} (Complexity: #{hotspot[:complexity]}, Touches: #{hotspot[:touches]})")
|
243
|
+
display_message("")
|
227
244
|
end
|
228
245
|
end
|
229
246
|
|
230
247
|
def show_cycles(format)
|
231
|
-
return
|
248
|
+
return display_message("No cycles data available") unless @data[:cycles]&.any?
|
232
249
|
|
233
250
|
case format
|
234
251
|
when "json"
|
235
|
-
|
252
|
+
display_message(JSON.pretty_generate(@data[:cycles]))
|
236
253
|
else
|
237
254
|
show_cycles_summary
|
238
255
|
end
|
239
256
|
end
|
240
257
|
|
241
258
|
def show_cycles_summary
|
242
|
-
|
243
|
-
|
259
|
+
display_message("\n🔄 Import Cycles")
|
260
|
+
display_message("=" * 50)
|
244
261
|
|
245
262
|
@data[:cycles].each_with_index do |cycle, i|
|
246
|
-
|
263
|
+
display_message("Cycle #{i + 1}:")
|
247
264
|
cycle[:members].each do |member|
|
248
|
-
|
265
|
+
display_message(" - #{member}")
|
249
266
|
end
|
250
|
-
|
251
|
-
|
267
|
+
display_message(" Weight: #{cycle[:weight]}") if cycle[:weight]
|
268
|
+
display_message("")
|
252
269
|
end
|
253
270
|
end
|
254
271
|
|
255
272
|
def show_apis(format)
|
256
|
-
return
|
273
|
+
return display_message("No APIs data available") unless @data[:tests]&.any?
|
257
274
|
|
258
275
|
untested_apis = @data[:tests].select { |t| t[:tests].empty? }
|
259
276
|
|
260
277
|
case format
|
261
278
|
when "json"
|
262
|
-
|
279
|
+
display_message(JSON.pretty_generate(untested_apis))
|
263
280
|
else
|
264
281
|
show_apis_summary(untested_apis)
|
265
282
|
end
|
266
283
|
end
|
267
284
|
|
268
285
|
def show_apis_summary(untested_apis)
|
269
|
-
|
270
|
-
|
286
|
+
display_message("\n🧪 Untested Public APIs")
|
287
|
+
display_message("=" * 50)
|
271
288
|
|
272
289
|
if untested_apis.empty?
|
273
|
-
|
290
|
+
display_message("✅ All public APIs have associated tests!")
|
274
291
|
else
|
275
|
-
|
276
|
-
|
292
|
+
display_message("Found #{untested_apis.length} untested public APIs:")
|
293
|
+
display_message("")
|
277
294
|
|
278
295
|
untested_apis.each do |api|
|
279
296
|
symbol = @data[:symbols]&.find { |s| s[:id] == api[:symbol_id] }
|
280
297
|
if symbol
|
281
|
-
|
282
|
-
|
283
|
-
|
298
|
+
display_message(" #{symbol[:file]}:#{symbol[:line]} - #{symbol[:name]}")
|
299
|
+
display_message(" Suggestion: Create characterization tests")
|
300
|
+
display_message("")
|
284
301
|
end
|
285
302
|
end
|
286
303
|
end
|
287
304
|
end
|
288
305
|
|
289
306
|
def show_symbols(format)
|
290
|
-
return
|
307
|
+
return display_message("No symbols data available") unless @data[:symbols]&.any?
|
291
308
|
|
292
309
|
case format
|
293
310
|
when "json"
|
294
|
-
|
311
|
+
display_message(JSON.pretty_generate(@data[:symbols]))
|
295
312
|
when "table"
|
296
313
|
show_symbols_table
|
297
314
|
else
|
@@ -300,8 +317,8 @@ module Aidp
|
|
300
317
|
end
|
301
318
|
|
302
319
|
def show_symbols_table
|
303
|
-
|
304
|
-
|
320
|
+
display_message("\n🏗️ Symbols")
|
321
|
+
display_message("=" * 80)
|
305
322
|
|
306
323
|
create_table(
|
307
324
|
["Type", "Name", "File", "Line", "Visibility"],
|
@@ -318,22 +335,22 @@ module Aidp
|
|
318
335
|
end
|
319
336
|
|
320
337
|
def show_symbols_summary
|
321
|
-
|
322
|
-
|
338
|
+
display_message("\n🏗️ Symbols Summary")
|
339
|
+
display_message("=" * 50)
|
323
340
|
|
324
341
|
symbol_types = @data[:symbols].group_by { |s| s[:kind] }
|
325
342
|
|
326
343
|
symbol_types.each do |type, symbols|
|
327
|
-
|
344
|
+
display_message("#{type.capitalize}: #{symbols.length}")
|
328
345
|
end
|
329
346
|
end
|
330
347
|
|
331
348
|
def show_imports(format)
|
332
|
-
return
|
349
|
+
return display_message("No imports data available") unless @data[:imports]&.any?
|
333
350
|
|
334
351
|
case format
|
335
352
|
when "json"
|
336
|
-
|
353
|
+
display_message(JSON.pretty_generate(@data[:imports]))
|
337
354
|
when "table"
|
338
355
|
show_imports_table
|
339
356
|
else
|
@@ -342,8 +359,8 @@ module Aidp
|
|
342
359
|
end
|
343
360
|
|
344
361
|
def show_imports_table
|
345
|
-
|
346
|
-
|
362
|
+
display_message("\n📦 Imports")
|
363
|
+
display_message("=" * 80)
|
347
364
|
|
348
365
|
create_table(
|
349
366
|
["Type", "Target", "File", "Line"],
|
@@ -359,18 +376,18 @@ module Aidp
|
|
359
376
|
end
|
360
377
|
|
361
378
|
def show_imports_summary
|
362
|
-
|
363
|
-
|
379
|
+
display_message("\n📦 Imports Summary")
|
380
|
+
display_message("=" * 50)
|
364
381
|
|
365
382
|
import_types = @data[:imports].group_by { |i| i[:kind] }
|
366
383
|
|
367
384
|
import_types.each do |type, imports|
|
368
|
-
|
385
|
+
display_message("#{type.capitalize}: #{imports.length}")
|
369
386
|
end
|
370
387
|
end
|
371
388
|
|
372
389
|
def generate_import_graph(format, output)
|
373
|
-
|
390
|
+
display_message("Generating import graph in #{format} format...")
|
374
391
|
|
375
392
|
case format
|
376
393
|
when "dot"
|
@@ -380,7 +397,7 @@ module Aidp
|
|
380
397
|
when "json"
|
381
398
|
generate_json_graph(output)
|
382
399
|
else
|
383
|
-
|
400
|
+
display_message("Unsupported graph format: #{format}")
|
384
401
|
end
|
385
402
|
end
|
386
403
|
|
@@ -399,9 +416,9 @@ module Aidp
|
|
399
416
|
|
400
417
|
if output
|
401
418
|
File.write(output, content.join("\n"))
|
402
|
-
|
419
|
+
display_message("Graph written to #{output}")
|
403
420
|
else
|
404
|
-
|
421
|
+
display_message(content.join("\n"))
|
405
422
|
end
|
406
423
|
end
|
407
424
|
|
@@ -416,9 +433,9 @@ module Aidp
|
|
416
433
|
|
417
434
|
if output
|
418
435
|
File.write(output, content.join("\n"))
|
419
|
-
|
436
|
+
display_message("Graph written to #{output}")
|
420
437
|
else
|
421
|
-
|
438
|
+
display_message(content.join("\n"))
|
422
439
|
end
|
423
440
|
end
|
424
441
|
|
@@ -447,20 +464,20 @@ module Aidp
|
|
447
464
|
|
448
465
|
if output
|
449
466
|
File.write(output, JSON.pretty_generate(graph_data))
|
450
|
-
|
467
|
+
display_message("Graph written to #{output}")
|
451
468
|
else
|
452
|
-
|
469
|
+
display_message(JSON.pretty_generate(graph_data))
|
453
470
|
end
|
454
471
|
end
|
455
472
|
|
456
473
|
def generate_call_graph(_format, _output)
|
457
474
|
# Similar to import graph but for method calls
|
458
|
-
|
475
|
+
display_message("Call graph generation not yet implemented")
|
459
476
|
end
|
460
477
|
|
461
478
|
def generate_cycle_graph(_format, _output)
|
462
479
|
# Generate graph showing only the cycles
|
463
|
-
|
480
|
+
display_message("Cycle graph generation not yet implemented")
|
464
481
|
end
|
465
482
|
|
466
483
|
def count_files
|
@@ -1,14 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "tty-prompt"
|
3
4
|
require_relative "ruby_maat_integration"
|
4
5
|
require_relative "feature_analyzer"
|
5
6
|
|
6
7
|
module Aidp
|
7
8
|
module Analyze
|
8
9
|
class Prioritizer
|
9
|
-
def initialize(project_dir = Dir.pwd)
|
10
|
+
def initialize(project_dir = Dir.pwd, prompt: TTY::Prompt.new)
|
10
11
|
@project_dir = project_dir
|
11
|
-
@code_maat = Aidp::Analyze::RubyMaatIntegration.new(project_dir)
|
12
|
+
@code_maat = Aidp::Analyze::RubyMaatIntegration.new(project_dir, prompt: prompt)
|
12
13
|
@feature_analyzer = Aidp::Analyze::FeatureAnalyzer.new(project_dir)
|
13
14
|
end
|
14
15
|
|
@@ -1,14 +1,16 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "tty-command"
|
4
|
+
require "tty-prompt"
|
4
5
|
require "json"
|
5
6
|
require "fileutils"
|
6
7
|
|
7
8
|
module Aidp
|
8
9
|
module Analyze
|
9
10
|
class RubyMaatIntegration
|
10
|
-
def initialize(project_dir = Dir.pwd)
|
11
|
+
def initialize(project_dir = Dir.pwd, prompt: TTY::Prompt.new)
|
11
12
|
@project_dir = project_dir
|
13
|
+
@prompt = prompt
|
12
14
|
end
|
13
15
|
|
14
16
|
# Check if RubyMaat gem is available and accessible
|
@@ -80,7 +82,7 @@ module Aidp
|
|
80
82
|
|
81
83
|
# Run analysis on large repositories using chunking
|
82
84
|
def run_chunked_analysis(git_log_file)
|
83
|
-
|
85
|
+
display_message("Large repository detected. Running chunked analysis...", type: :info)
|
84
86
|
|
85
87
|
# Split analysis into chunks
|
86
88
|
chunks = create_analysis_chunks(git_log_file)
|
@@ -93,7 +95,7 @@ module Aidp
|
|
93
95
|
}
|
94
96
|
|
95
97
|
chunks.each_with_index do |chunk, index|
|
96
|
-
|
98
|
+
display_message("Processing chunk #{index + 1}/#{chunks.length}...", type: :info)
|
97
99
|
|
98
100
|
chunk_results = analyze_chunk(chunk)
|
99
101
|
|
@@ -453,6 +455,21 @@ module Aidp
|
|
453
455
|
|
454
456
|
result.success? && !result.out.strip.empty?
|
455
457
|
end
|
458
|
+
|
459
|
+
private
|
460
|
+
|
461
|
+
# Helper method for consistent message display using TTY::Prompt
|
462
|
+
def display_message(message, type: :info)
|
463
|
+
color = case type
|
464
|
+
when :error then :red
|
465
|
+
when :warn then :yellow
|
466
|
+
when :success then :green
|
467
|
+
when :highlight then :cyan
|
468
|
+
else :white
|
469
|
+
end
|
470
|
+
|
471
|
+
@prompt.say(message, color: color)
|
472
|
+
end
|
456
473
|
end
|
457
474
|
end
|
458
475
|
end
|
data/lib/aidp/analyze/runner.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "tty-prompt"
|
3
4
|
require_relative "steps"
|
4
5
|
require_relative "progress"
|
5
6
|
require_relative "../storage/file_manager"
|
@@ -10,17 +11,34 @@ module Aidp
|
|
10
11
|
class Runner
|
11
12
|
include Aidp::DebugMixin
|
12
13
|
|
13
|
-
def initialize(project_dir, harness_runner = nil)
|
14
|
+
def initialize(project_dir, harness_runner = nil, prompt: TTY::Prompt.new)
|
14
15
|
@project_dir = project_dir
|
15
16
|
@harness_runner = harness_runner
|
16
17
|
@is_harness_mode = !harness_runner.nil?
|
17
18
|
@file_manager = Aidp::Storage::FileManager.new(File.join(project_dir, ".aidp"))
|
19
|
+
@prompt = prompt
|
18
20
|
end
|
19
21
|
|
20
22
|
def progress
|
21
23
|
@progress ||= Aidp::Analyze::Progress.new(@project_dir)
|
22
24
|
end
|
23
25
|
|
26
|
+
private
|
27
|
+
|
28
|
+
def display_message(message, type: :info)
|
29
|
+
color = case type
|
30
|
+
when :error then :red
|
31
|
+
when :success then :green
|
32
|
+
when :warning then :yellow
|
33
|
+
when :info then :blue
|
34
|
+
when :highlight then :cyan
|
35
|
+
else :white
|
36
|
+
end
|
37
|
+
@prompt.say(message, color: color)
|
38
|
+
end
|
39
|
+
|
40
|
+
public
|
41
|
+
|
24
42
|
def run_step(step_name, options = {})
|
25
43
|
# Always validate step exists first
|
26
44
|
step_spec = Aidp::Analyze::Steps::SPEC[step_name]
|
@@ -42,7 +60,7 @@ module Aidp
|
|
42
60
|
# Harness-aware step execution
|
43
61
|
def run_step_with_harness(step_name, options = {})
|
44
62
|
# Get current provider from harness
|
45
|
-
current_provider = @harness_runner.
|
63
|
+
current_provider = @harness_runner.current_provider
|
46
64
|
provider_type = current_provider || "cursor"
|
47
65
|
|
48
66
|
debug_step(step_name, "Harness execution", {
|
@@ -72,7 +90,7 @@ module Aidp
|
|
72
90
|
|
73
91
|
# Standalone step execution (simplified - synchronous)
|
74
92
|
def run_step_standalone(step_name, options = {})
|
75
|
-
|
93
|
+
display_message("🚀 Running step synchronously: #{step_name}", type: :info)
|
76
94
|
|
77
95
|
start_time = Time.now
|
78
96
|
prompt = composed_prompt(step_name, options)
|
@@ -85,7 +103,7 @@ module Aidp
|
|
85
103
|
# Store execution metrics
|
86
104
|
@file_manager.record_step_execution(step_name, "cursor", duration, result[:status] == "completed")
|
87
105
|
|
88
|
-
|
106
|
+
display_message("✅ Step completed in #{duration.round(2)}s", type: :success)
|
89
107
|
result
|
90
108
|
end
|
91
109
|
|
@@ -223,11 +241,11 @@ module Aidp
|
|
223
241
|
# Add current execution context
|
224
242
|
context_parts << "## Analysis Context"
|
225
243
|
context_parts << "Project Directory: #{@project_dir}"
|
226
|
-
context_parts << "Current Step: #{@harness_runner.
|
227
|
-
context_parts << "Current Provider: #{@harness_runner.
|
244
|
+
context_parts << "Current Step: #{@harness_runner.current_step}"
|
245
|
+
context_parts << "Current Provider: #{@harness_runner.current_provider}"
|
228
246
|
|
229
247
|
# Add user input context
|
230
|
-
user_input = @harness_runner.
|
248
|
+
user_input = @harness_runner.user_input
|
231
249
|
if user_input && !user_input.empty?
|
232
250
|
context_parts << "\n## Previous User Input"
|
233
251
|
user_input.each do |key, value|
|
@@ -236,7 +254,7 @@ module Aidp
|
|
236
254
|
end
|
237
255
|
|
238
256
|
# Add execution history context
|
239
|
-
execution_log = @harness_runner.
|
257
|
+
execution_log = @harness_runner.execution_log
|
240
258
|
if execution_log && !execution_log.empty?
|
241
259
|
context_parts << "\n## Analysis History"
|
242
260
|
recent_logs = execution_log.last(5) # Last 5 entries
|
@@ -251,7 +269,7 @@ module Aidp
|
|
251
269
|
# Execute step with harness provider management
|
252
270
|
def execute_with_harness_provider(provider_type, prompt, step_name, _options)
|
253
271
|
# Get provider manager from harness
|
254
|
-
provider_manager = @harness_runner.
|
272
|
+
provider_manager = @harness_runner.provider_manager
|
255
273
|
|
256
274
|
# Execute with provider
|
257
275
|
provider_manager.execute_with_provider(provider_type, prompt, {
|