aidp 0.15.1 ā 0.15.2
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/cli.rb +41 -3
- data/lib/aidp/harness/provider_info.rb +1 -1
- data/lib/aidp/harness/provider_manager.rb +9 -8
- data/lib/aidp/init/doc_generator.rb +75 -10
- data/lib/aidp/init/project_analyzer.rb +154 -26
- data/lib/aidp/init/runner.rb +263 -10
- data/lib/aidp/logger.rb +11 -0
- data/lib/aidp/version.rb +1 -1
- metadata +1 -4
- data/lib/aidp/analyze/prioritizer.rb +0 -403
- data/lib/aidp/analyze/report_generator.rb +0 -582
- data/lib/aidp/cli/checkpoint_command.rb +0 -98
data/lib/aidp/init/runner.rb
CHANGED
@@ -12,20 +12,54 @@ module Aidp
|
|
12
12
|
class Runner
|
13
13
|
include Aidp::MessageDisplay
|
14
14
|
|
15
|
-
def initialize(project_dir = Dir.pwd, prompt: TTY::Prompt.new, analyzer: nil, doc_generator: nil)
|
15
|
+
def initialize(project_dir = Dir.pwd, prompt: TTY::Prompt.new, analyzer: nil, doc_generator: nil, options: {})
|
16
16
|
@project_dir = project_dir
|
17
17
|
@prompt = prompt
|
18
18
|
@analyzer = analyzer || ProjectAnalyzer.new(project_dir)
|
19
19
|
@doc_generator = doc_generator || DocGenerator.new(project_dir)
|
20
|
+
@options = options
|
20
21
|
end
|
21
22
|
|
22
23
|
def run
|
23
24
|
display_message("š Running aidp init project analysis...", type: :info)
|
24
|
-
analysis = @analyzer.analyze
|
25
|
-
|
25
|
+
analysis = @analyzer.analyze(explain_detection: @options[:explain_detection])
|
26
|
+
|
27
|
+
if @options[:explain_detection]
|
28
|
+
display_detailed_analysis(analysis)
|
29
|
+
else
|
30
|
+
display_summary(analysis)
|
31
|
+
end
|
32
|
+
|
33
|
+
# Dry run: skip preferences and generation
|
34
|
+
if @options[:dry_run]
|
35
|
+
display_message("\nš Dry run mode - no files will be written.", type: :info)
|
36
|
+
return {
|
37
|
+
analysis: analysis,
|
38
|
+
preferences: {},
|
39
|
+
generated_files: []
|
40
|
+
}
|
41
|
+
end
|
26
42
|
|
27
43
|
preferences = gather_preferences
|
28
44
|
|
45
|
+
# Offer preview before writing
|
46
|
+
if @options[:preview] || ask_yes_no_with_context(
|
47
|
+
"Preview generated files before saving?",
|
48
|
+
context: "Shows a summary of what will be written to docs/",
|
49
|
+
default: false
|
50
|
+
)
|
51
|
+
preview_generated_docs(analysis, preferences)
|
52
|
+
|
53
|
+
unless ask_yes_no("Proceed with writing these files?", default: true)
|
54
|
+
display_message("\nā Cancelled. No files were written.", type: :info)
|
55
|
+
return {
|
56
|
+
analysis: analysis,
|
57
|
+
preferences: preferences,
|
58
|
+
generated_files: []
|
59
|
+
}
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
29
63
|
@doc_generator.generate(analysis: analysis, preferences: preferences)
|
30
64
|
|
31
65
|
display_message("\nš Generated documentation:", type: :info)
|
@@ -52,24 +86,170 @@ module Aidp
|
|
52
86
|
frameworks = analysis[:frameworks]
|
53
87
|
tests = analysis[:test_frameworks]
|
54
88
|
config_files = analysis[:config_files]
|
89
|
+
tooling = analysis[:tooling]
|
90
|
+
|
91
|
+
# Extract high-confidence frameworks (>= 0.7)
|
92
|
+
confident_frameworks = frameworks.select { |f| f[:confidence] >= 0.7 }.map { |f| f[:name] }
|
93
|
+
uncertain_frameworks = frameworks.select { |f| f[:confidence] < 0.7 }
|
94
|
+
|
95
|
+
# Extract high-confidence test frameworks (>= 0.7)
|
96
|
+
confident_tests = tests.select { |t| t[:confidence] >= 0.7 }.map { |t| t[:name] }
|
97
|
+
|
98
|
+
# Extract high-confidence tooling (>= 0.7)
|
99
|
+
confident_tooling = tooling.select { |t| t[:confidence] >= 0.7 }.map { |t| format_tool(t[:tool]) }
|
55
100
|
|
56
101
|
display_message("\nš Repository Snapshot", type: :highlight)
|
57
102
|
display_message(" Languages: #{languages.empty? ? "Unknown" : languages.join(", ")}", type: :info)
|
58
|
-
|
59
|
-
|
60
|
-
|
103
|
+
|
104
|
+
if confident_frameworks.any?
|
105
|
+
display_message(" Frameworks: #{confident_frameworks.join(", ")}", type: :info)
|
106
|
+
else
|
107
|
+
display_message(" Frameworks: None confidently detected", type: :info)
|
108
|
+
end
|
109
|
+
|
110
|
+
if uncertain_frameworks.any?
|
111
|
+
uncertain_list = uncertain_frameworks.map { |f| "#{f[:name]} (#{(f[:confidence] * 100).round}%)" }.join(", ")
|
112
|
+
display_message(" Possible frameworks: #{uncertain_list}", type: :info)
|
113
|
+
end
|
114
|
+
|
115
|
+
if confident_tests.any?
|
116
|
+
display_message(" Test suites: #{confident_tests.join(", ")}", type: :info)
|
117
|
+
else
|
118
|
+
display_message(" Test suites: Not found", type: :info)
|
119
|
+
end
|
120
|
+
|
121
|
+
if confident_tooling.any?
|
122
|
+
display_message(" Quality tools: #{confident_tooling.join(", ")}", type: :info)
|
123
|
+
end
|
124
|
+
|
125
|
+
display_message(" Config files: #{config_files.empty? ? "None detected" : config_files.size} found", type: :info)
|
126
|
+
end
|
127
|
+
|
128
|
+
def display_detailed_analysis(analysis)
|
129
|
+
display_message("\nš Detailed Detection Analysis", type: :highlight)
|
130
|
+
display_message("=" * 60, type: :info)
|
131
|
+
|
132
|
+
# Languages
|
133
|
+
display_message("\nš Languages (by file size):", type: :highlight)
|
134
|
+
if analysis[:languages].any?
|
135
|
+
total_size = analysis[:languages].values.sum
|
136
|
+
analysis[:languages].each do |lang, size|
|
137
|
+
percentage = ((size.to_f / total_size) * 100).round(1)
|
138
|
+
display_message(" ⢠#{lang}: #{percentage}%", type: :info)
|
139
|
+
end
|
140
|
+
else
|
141
|
+
display_message(" None detected", type: :info)
|
142
|
+
end
|
143
|
+
|
144
|
+
# Frameworks
|
145
|
+
display_message("\nšÆ Frameworks:", type: :highlight)
|
146
|
+
if analysis[:frameworks].any?
|
147
|
+
analysis[:frameworks].each do |fw|
|
148
|
+
confidence_pct = (fw[:confidence] * 100).round
|
149
|
+
display_message(" ⢠#{fw[:name]} (#{confidence_pct}% confidence):", type: :info)
|
150
|
+
fw[:evidence].each do |evidence|
|
151
|
+
display_message(" - #{evidence}", type: :info)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
else
|
155
|
+
display_message(" None detected", type: :info)
|
156
|
+
end
|
157
|
+
|
158
|
+
# Test Frameworks
|
159
|
+
display_message("\nš§Ŗ Test Frameworks:", type: :highlight)
|
160
|
+
if analysis[:test_frameworks].any?
|
161
|
+
analysis[:test_frameworks].each do |test|
|
162
|
+
confidence_pct = (test[:confidence] * 100).round
|
163
|
+
display_message(" ⢠#{test[:name]} (#{confidence_pct}% confidence):", type: :info)
|
164
|
+
test[:evidence].each do |evidence|
|
165
|
+
display_message(" - #{evidence}", type: :info)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
else
|
169
|
+
display_message(" None detected", type: :info)
|
170
|
+
end
|
171
|
+
|
172
|
+
# Tooling
|
173
|
+
display_message("\nš§ Quality Tooling:", type: :highlight)
|
174
|
+
if analysis[:tooling].any?
|
175
|
+
analysis[:tooling].each do |tool_data|
|
176
|
+
tool_name = format_tool(tool_data[:tool])
|
177
|
+
confidence_pct = (tool_data[:confidence] * 100).round
|
178
|
+
display_message(" ⢠#{tool_name} (#{confidence_pct}% confidence):", type: :info)
|
179
|
+
tool_data[:evidence].each do |evidence|
|
180
|
+
display_message(" - #{evidence}", type: :info)
|
181
|
+
end
|
182
|
+
end
|
183
|
+
else
|
184
|
+
display_message(" None detected", type: :info)
|
185
|
+
end
|
186
|
+
|
187
|
+
# Key Directories
|
188
|
+
display_message("\nš Key Directories:", type: :highlight)
|
189
|
+
if analysis[:key_directories].any?
|
190
|
+
analysis[:key_directories].each do |dir|
|
191
|
+
display_message(" ⢠#{dir}", type: :info)
|
192
|
+
end
|
193
|
+
else
|
194
|
+
display_message(" None detected", type: :info)
|
195
|
+
end
|
196
|
+
|
197
|
+
# Config Files
|
198
|
+
display_message("\nāļø Configuration Files:", type: :highlight)
|
199
|
+
if analysis[:config_files].any?
|
200
|
+
analysis[:config_files].each do |file|
|
201
|
+
display_message(" ⢠#{file}", type: :info)
|
202
|
+
end
|
203
|
+
else
|
204
|
+
display_message(" None detected", type: :info)
|
205
|
+
end
|
206
|
+
|
207
|
+
# Repository Stats
|
208
|
+
display_message("\nš Repository Stats:", type: :highlight)
|
209
|
+
stats = analysis[:repo_stats]
|
210
|
+
display_message(" ⢠Total files: #{stats[:total_files]}", type: :info)
|
211
|
+
display_message(" ⢠Total directories: #{stats[:total_directories]}", type: :info)
|
212
|
+
display_message(" ⢠Documentation: #{stats[:docs_present] ? "Present" : "Not found"}", type: :info)
|
213
|
+
display_message(" ⢠CI/CD config: #{stats[:has_ci_config] ? "Present" : "Not found"}", type: :info)
|
214
|
+
display_message(" ⢠Containerization: #{stats[:has_containerization] ? "Present" : "Not found"}", type: :info)
|
215
|
+
|
216
|
+
display_message("\n" + "=" * 60, type: :info)
|
217
|
+
end
|
218
|
+
|
219
|
+
def format_tool(tool)
|
220
|
+
tool.to_s.split("_").map(&:capitalize).join(" ")
|
61
221
|
end
|
62
222
|
|
63
223
|
def gather_preferences
|
64
|
-
display_message("\nāļø
|
224
|
+
display_message("\nāļø Configuration Options", type: :highlight)
|
225
|
+
display_message("The following questions will help customize the generated documentation.", type: :info)
|
226
|
+
display_message("Press Enter to accept defaults shown in brackets.\n", type: :info)
|
65
227
|
|
66
228
|
{
|
67
|
-
adopt_new_conventions:
|
68
|
-
|
69
|
-
|
229
|
+
adopt_new_conventions: ask_yes_no_with_context(
|
230
|
+
"Make these conventions official for this repository?",
|
231
|
+
context: "This saves the detected patterns to LLM_STYLE_GUIDE.md and guides future AI-assisted work.",
|
232
|
+
default: true
|
233
|
+
),
|
234
|
+
stricter_linters: ask_yes_no_with_context(
|
235
|
+
"Enable stricter linting rules in the quality plan?",
|
236
|
+
context: "Recommends failing CI on linting violations for better code quality.",
|
237
|
+
default: false
|
238
|
+
),
|
239
|
+
migrate_styles: ask_yes_no_with_context(
|
240
|
+
"Plan gradual migration of legacy code to new style guide?",
|
241
|
+
context: "Adds migration tasks to CODE_QUALITY_PLAN.md for incremental improvements.",
|
242
|
+
default: false
|
243
|
+
)
|
70
244
|
}
|
71
245
|
end
|
72
246
|
|
247
|
+
def ask_yes_no_with_context(question, context:, default:)
|
248
|
+
display_message("\n#{question}", type: :info)
|
249
|
+
display_message(" ā¹ļø #{context}", type: :info)
|
250
|
+
ask_yes_no(question, default: default)
|
251
|
+
end
|
252
|
+
|
73
253
|
def ask_yes_no(question, default:)
|
74
254
|
@prompt.yes?(question) do |q|
|
75
255
|
q.default default ? "yes" : "no"
|
@@ -78,6 +258,79 @@ module Aidp
|
|
78
258
|
# Compatibility with simplified prompts in tests (e.g. TestPrompt)
|
79
259
|
default
|
80
260
|
end
|
261
|
+
|
262
|
+
def preview_generated_docs(analysis, preferences)
|
263
|
+
display_message("\nš Preview of Generated Documentation", type: :highlight)
|
264
|
+
display_message("=" * 60, type: :info)
|
265
|
+
|
266
|
+
# LLM_STYLE_GUIDE summary
|
267
|
+
display_message("\n1. docs/LLM_STYLE_GUIDE.md", type: :highlight)
|
268
|
+
confident_frameworks = analysis[:frameworks].select { |f| f[:confidence] >= 0.7 }.map { |f| f[:name] }
|
269
|
+
display_message(" - Detected frameworks: #{confident_frameworks.any? ? confident_frameworks.join(", ") : "None"}", type: :info)
|
270
|
+
display_message(" - Adoption status: #{preferences[:adopt_new_conventions] ? "Official conventions" : "Optional reference"}", type: :info)
|
271
|
+
|
272
|
+
# PROJECT_ANALYSIS summary
|
273
|
+
display_message("\n2. docs/PROJECT_ANALYSIS.md", type: :highlight)
|
274
|
+
display_message(" - Languages: #{analysis[:languages].keys.join(", ")}", type: :info)
|
275
|
+
display_message(" - Total frameworks detected: #{analysis[:frameworks].size}", type: :info)
|
276
|
+
display_message(" - Test frameworks: #{analysis[:test_frameworks].map { |t| t[:name] }.join(", ") || "None"}", type: :info)
|
277
|
+
|
278
|
+
# CODE_QUALITY_PLAN summary
|
279
|
+
display_message("\n3. docs/CODE_QUALITY_PLAN.md", type: :highlight)
|
280
|
+
tooling_count = analysis[:tooling].count { |t| t[:confidence] >= 0.7 }
|
281
|
+
display_message(" - Quality tools detected: #{tooling_count}", type: :info)
|
282
|
+
display_message(" - Stricter linting: #{preferences[:stricter_linters] ? "Yes" : "No"}", type: :info)
|
283
|
+
display_message(" - Migration planning: #{preferences[:migrate_styles] ? "Yes" : "No"}", type: :info)
|
284
|
+
|
285
|
+
# Validation warnings
|
286
|
+
validate_tooling(analysis)
|
287
|
+
|
288
|
+
display_message("\n" + "=" * 60, type: :info)
|
289
|
+
end
|
290
|
+
|
291
|
+
def validate_tooling(analysis)
|
292
|
+
display_message("\nš Validation", type: :highlight)
|
293
|
+
|
294
|
+
warnings = []
|
295
|
+
|
296
|
+
# Check if detected tools actually exist
|
297
|
+
analysis[:tooling].select { |t| t[:confidence] >= 0.7 }.each do |tool_data|
|
298
|
+
tool_name = tool_data[:tool].to_s
|
299
|
+
|
300
|
+
# Try to find the tool command
|
301
|
+
tool_command = case tool_name
|
302
|
+
when "rubocop", "standardrb", "eslint", "prettier", "stylelint", "flake8", "black", "pytest", "jest"
|
303
|
+
tool_name
|
304
|
+
when "cargo_fmt"
|
305
|
+
"cargo"
|
306
|
+
when "gofmt"
|
307
|
+
"gofmt"
|
308
|
+
end
|
309
|
+
|
310
|
+
next unless tool_command
|
311
|
+
|
312
|
+
# Check if command exists
|
313
|
+
unless system("which #{tool_command} > /dev/null 2>&1")
|
314
|
+
warnings << " ā ļø #{format_tool(tool_data[:tool])} detected but command '#{tool_command}' not found in PATH"
|
315
|
+
end
|
316
|
+
end
|
317
|
+
|
318
|
+
# Check if test commands can be inferred
|
319
|
+
if analysis[:test_frameworks].empty?
|
320
|
+
warnings << " ā ļø No test framework detected - consider adding one for better quality assurance"
|
321
|
+
end
|
322
|
+
|
323
|
+
# Check for CI configuration
|
324
|
+
unless analysis[:repo_stats][:has_ci_config]
|
325
|
+
warnings << " ā¹ļø No CI configuration detected - consider adding GitHub Actions or similar"
|
326
|
+
end
|
327
|
+
|
328
|
+
if warnings.any?
|
329
|
+
warnings.each { |warning| display_message(warning, type: :info) }
|
330
|
+
else
|
331
|
+
display_message(" ā
All detected tools validated successfully", type: :success)
|
332
|
+
end
|
333
|
+
end
|
81
334
|
end
|
82
335
|
end
|
83
336
|
end
|
data/lib/aidp/logger.rb
CHANGED
@@ -104,10 +104,21 @@ module Aidp
|
|
104
104
|
end
|
105
105
|
|
106
106
|
def create_logger(path)
|
107
|
+
# Ensure parent directory exists before creating logger
|
108
|
+
dir = File.dirname(path)
|
109
|
+
FileUtils.mkdir_p(dir) unless Dir.exist?(dir)
|
110
|
+
|
107
111
|
logger = ::Logger.new(path, @max_files, @max_size)
|
108
112
|
logger.level = ::Logger::DEBUG # Control at write level instead
|
109
113
|
logger.formatter = proc { |severity, datetime, progname, msg| "#{msg}\n" }
|
110
114
|
logger
|
115
|
+
rescue => e
|
116
|
+
# Fall back to STDERR if file logging fails
|
117
|
+
warn "[AIDP Logger] Failed to create log file at #{path}: #{e.message}. Falling back to STDERR."
|
118
|
+
logger = ::Logger.new($stderr)
|
119
|
+
logger.level = ::Logger::DEBUG
|
120
|
+
logger.formatter = proc { |severity, datetime, progname, msg| "#{msg}\n" }
|
121
|
+
logger
|
111
122
|
end
|
112
123
|
|
113
124
|
def write_entry(level, component, message, metadata)
|
data/lib/aidp/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: aidp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.15.
|
4
|
+
version: 0.15.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bart Agapinan
|
@@ -237,9 +237,7 @@ files:
|
|
237
237
|
- lib/aidp/analyze/feature_analyzer.rb
|
238
238
|
- lib/aidp/analyze/json_file_storage.rb
|
239
239
|
- lib/aidp/analyze/kb_inspector.rb
|
240
|
-
- lib/aidp/analyze/prioritizer.rb
|
241
240
|
- lib/aidp/analyze/progress.rb
|
242
|
-
- lib/aidp/analyze/report_generator.rb
|
243
241
|
- lib/aidp/analyze/ruby_maat_integration.rb
|
244
242
|
- lib/aidp/analyze/runner.rb
|
245
243
|
- lib/aidp/analyze/seams.rb
|
@@ -247,7 +245,6 @@ files:
|
|
247
245
|
- lib/aidp/analyze/tree_sitter_grammar_loader.rb
|
248
246
|
- lib/aidp/analyze/tree_sitter_scan.rb
|
249
247
|
- lib/aidp/cli.rb
|
250
|
-
- lib/aidp/cli/checkpoint_command.rb
|
251
248
|
- lib/aidp/cli/enhanced_input.rb
|
252
249
|
- lib/aidp/cli/first_run_wizard.rb
|
253
250
|
- lib/aidp/cli/issue_importer.rb
|