aidp 0.5.0 → 0.8.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 +128 -151
- data/bin/aidp +1 -1
- data/lib/aidp/analysis/kb_inspector.rb +471 -0
- data/lib/aidp/analysis/seams.rb +159 -0
- data/lib/aidp/analysis/tree_sitter_grammar_loader.rb +480 -0
- data/lib/aidp/analysis/tree_sitter_scan.rb +686 -0
- data/lib/aidp/analyze/error_handler.rb +2 -78
- data/lib/aidp/analyze/json_file_storage.rb +292 -0
- data/lib/aidp/analyze/progress.rb +12 -0
- data/lib/aidp/analyze/progress_visualizer.rb +12 -17
- data/lib/aidp/analyze/ruby_maat_integration.rb +13 -31
- data/lib/aidp/analyze/runner.rb +256 -87
- data/lib/aidp/analyze/steps.rb +6 -0
- data/lib/aidp/cli/jobs_command.rb +103 -435
- data/lib/aidp/cli.rb +317 -191
- data/lib/aidp/config.rb +298 -10
- data/lib/aidp/debug_logger.rb +195 -0
- data/lib/aidp/debug_mixin.rb +187 -0
- data/lib/aidp/execute/progress.rb +9 -0
- data/lib/aidp/execute/runner.rb +221 -40
- data/lib/aidp/execute/steps.rb +17 -7
- data/lib/aidp/execute/workflow_selector.rb +211 -0
- data/lib/aidp/harness/completion_checker.rb +268 -0
- data/lib/aidp/harness/condition_detector.rb +1526 -0
- data/lib/aidp/harness/config_loader.rb +373 -0
- data/lib/aidp/harness/config_manager.rb +382 -0
- data/lib/aidp/harness/config_schema.rb +1006 -0
- data/lib/aidp/harness/config_validator.rb +355 -0
- data/lib/aidp/harness/configuration.rb +477 -0
- data/lib/aidp/harness/enhanced_runner.rb +494 -0
- data/lib/aidp/harness/error_handler.rb +616 -0
- data/lib/aidp/harness/provider_config.rb +423 -0
- data/lib/aidp/harness/provider_factory.rb +306 -0
- data/lib/aidp/harness/provider_manager.rb +1269 -0
- data/lib/aidp/harness/provider_type_checker.rb +88 -0
- data/lib/aidp/harness/runner.rb +411 -0
- data/lib/aidp/harness/state/errors.rb +28 -0
- data/lib/aidp/harness/state/metrics.rb +219 -0
- data/lib/aidp/harness/state/persistence.rb +128 -0
- data/lib/aidp/harness/state/provider_state.rb +132 -0
- data/lib/aidp/harness/state/ui_state.rb +68 -0
- data/lib/aidp/harness/state/workflow_state.rb +123 -0
- data/lib/aidp/harness/state_manager.rb +586 -0
- data/lib/aidp/harness/status_display.rb +888 -0
- data/lib/aidp/harness/ui/base.rb +16 -0
- data/lib/aidp/harness/ui/enhanced_tui.rb +545 -0
- data/lib/aidp/harness/ui/enhanced_workflow_selector.rb +252 -0
- data/lib/aidp/harness/ui/error_handler.rb +132 -0
- data/lib/aidp/harness/ui/frame_manager.rb +361 -0
- data/lib/aidp/harness/ui/job_monitor.rb +500 -0
- data/lib/aidp/harness/ui/navigation/main_menu.rb +311 -0
- data/lib/aidp/harness/ui/navigation/menu_formatter.rb +120 -0
- data/lib/aidp/harness/ui/navigation/menu_item.rb +142 -0
- data/lib/aidp/harness/ui/navigation/menu_state.rb +139 -0
- data/lib/aidp/harness/ui/navigation/submenu.rb +202 -0
- data/lib/aidp/harness/ui/navigation/workflow_selector.rb +176 -0
- data/lib/aidp/harness/ui/progress_display.rb +280 -0
- data/lib/aidp/harness/ui/question_collector.rb +141 -0
- data/lib/aidp/harness/ui/spinner_group.rb +184 -0
- data/lib/aidp/harness/ui/spinner_helper.rb +152 -0
- data/lib/aidp/harness/ui/status_manager.rb +312 -0
- data/lib/aidp/harness/ui/status_widget.rb +280 -0
- data/lib/aidp/harness/ui/workflow_controller.rb +312 -0
- data/lib/aidp/harness/user_interface.rb +2381 -0
- data/lib/aidp/provider_manager.rb +131 -7
- data/lib/aidp/providers/anthropic.rb +28 -109
- data/lib/aidp/providers/base.rb +170 -0
- data/lib/aidp/providers/cursor.rb +52 -183
- data/lib/aidp/providers/gemini.rb +24 -109
- data/lib/aidp/providers/macos_ui.rb +99 -5
- data/lib/aidp/providers/opencode.rb +194 -0
- data/lib/aidp/storage/csv_storage.rb +172 -0
- data/lib/aidp/storage/file_manager.rb +214 -0
- data/lib/aidp/storage/json_storage.rb +140 -0
- data/lib/aidp/version.rb +1 -1
- data/lib/aidp.rb +56 -35
- data/templates/ANALYZE/06a_tree_sitter_scan.md +217 -0
- data/templates/COMMON/AGENT_BASE.md +11 -0
- data/templates/EXECUTE/00_PRD.md +4 -4
- data/templates/EXECUTE/02_ARCHITECTURE.md +5 -4
- data/templates/EXECUTE/07_TEST_PLAN.md +4 -1
- data/templates/EXECUTE/08_TASKS.md +4 -4
- data/templates/EXECUTE/10_IMPLEMENTATION_AGENT.md +4 -4
- data/templates/README.md +279 -0
- data/templates/aidp-development.yml.example +373 -0
- data/templates/aidp-minimal.yml.example +48 -0
- data/templates/aidp-production.yml.example +475 -0
- data/templates/aidp.yml.example +598 -0
- metadata +106 -64
- data/lib/aidp/analyze/agent_personas.rb +0 -71
- data/lib/aidp/analyze/agent_tool_executor.rb +0 -445
- data/lib/aidp/analyze/data_retention_manager.rb +0 -426
- data/lib/aidp/analyze/database.rb +0 -260
- data/lib/aidp/analyze/dependencies.rb +0 -335
- data/lib/aidp/analyze/export_manager.rb +0 -425
- data/lib/aidp/analyze/focus_guidance.rb +0 -517
- data/lib/aidp/analyze/incremental_analyzer.rb +0 -543
- data/lib/aidp/analyze/language_analysis_strategies.rb +0 -897
- data/lib/aidp/analyze/large_analysis_progress.rb +0 -504
- data/lib/aidp/analyze/memory_manager.rb +0 -365
- data/lib/aidp/analyze/metrics_storage.rb +0 -336
- data/lib/aidp/analyze/parallel_processor.rb +0 -460
- data/lib/aidp/analyze/performance_optimizer.rb +0 -694
- data/lib/aidp/analyze/repository_chunker.rb +0 -704
- data/lib/aidp/analyze/static_analysis_detector.rb +0 -577
- data/lib/aidp/analyze/storage.rb +0 -662
- data/lib/aidp/analyze/tool_configuration.rb +0 -456
- data/lib/aidp/analyze/tool_modernization.rb +0 -750
- data/lib/aidp/database/pg_adapter.rb +0 -148
- data/lib/aidp/database_config.rb +0 -69
- data/lib/aidp/database_connection.rb +0 -72
- data/lib/aidp/database_migration.rb +0 -158
- data/lib/aidp/job_manager.rb +0 -41
- data/lib/aidp/jobs/base_job.rb +0 -47
- data/lib/aidp/jobs/provider_execution_job.rb +0 -96
- data/lib/aidp/project_detector.rb +0 -117
- data/lib/aidp/providers/agent_supervisor.rb +0 -348
- data/lib/aidp/providers/supervised_base.rb +0 -317
- data/lib/aidp/providers/supervised_cursor.rb +0 -22
- data/lib/aidp/sync.rb +0 -13
- data/lib/aidp/workspace.rb +0 -19
@@ -1,445 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "open3"
|
4
|
-
require "json"
|
5
|
-
require "timeout"
|
6
|
-
|
7
|
-
module Aidp
|
8
|
-
class AgentToolExecutor
|
9
|
-
# Default timeout for tool execution (5 minutes)
|
10
|
-
DEFAULT_TIMEOUT = 300
|
11
|
-
|
12
|
-
# Default environment variables for tool execution
|
13
|
-
DEFAULT_ENV = {
|
14
|
-
"LANG" => "en_US.UTF-8",
|
15
|
-
"LC_ALL" => "en_US.UTF-8"
|
16
|
-
}.freeze
|
17
|
-
|
18
|
-
def initialize(project_dir = Dir.pwd, config = {})
|
19
|
-
@project_dir = project_dir
|
20
|
-
@config = config
|
21
|
-
@timeout = config[:timeout] || DEFAULT_TIMEOUT
|
22
|
-
@env = DEFAULT_ENV.merge(config[:env] || {})
|
23
|
-
@execution_log = []
|
24
|
-
end
|
25
|
-
|
26
|
-
# Execute a static analysis tool
|
27
|
-
def execute_tool(tool_name, options = {})
|
28
|
-
execution_id = generate_execution_id
|
29
|
-
start_time = Time.now
|
30
|
-
|
31
|
-
log_execution_start(execution_id, tool_name, options)
|
32
|
-
|
33
|
-
begin
|
34
|
-
result = execute_tool_with_timeout(tool_name, options)
|
35
|
-
execution_time = Time.now - start_time
|
36
|
-
|
37
|
-
log_execution_success(execution_id, tool_name, execution_time, result)
|
38
|
-
result
|
39
|
-
rescue => e
|
40
|
-
execution_time = Time.now - start_time
|
41
|
-
log_execution_error(execution_id, tool_name, execution_time, e)
|
42
|
-
raise
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
# Execute multiple tools in parallel
|
47
|
-
def execute_tools_parallel(tools, options = {})
|
48
|
-
results = {}
|
49
|
-
threads = []
|
50
|
-
|
51
|
-
tools.each do |tool_name, tool_options|
|
52
|
-
thread = Thread.new do
|
53
|
-
results[tool_name] = execute_tool(tool_name, tool_options)
|
54
|
-
rescue => e
|
55
|
-
results[tool_name] = {error: e.message, status: "failed"}
|
56
|
-
end
|
57
|
-
threads << thread
|
58
|
-
end
|
59
|
-
|
60
|
-
# Wait for all threads to complete
|
61
|
-
threads.each(&:join)
|
62
|
-
|
63
|
-
results
|
64
|
-
end
|
65
|
-
|
66
|
-
# Execute tools in sequence based on dependencies
|
67
|
-
def execute_tools_sequence(tools, dependencies = {})
|
68
|
-
results = {}
|
69
|
-
executed = Set.new
|
70
|
-
|
71
|
-
tools.each do |tool_name|
|
72
|
-
# Check if dependencies are satisfied
|
73
|
-
tool_deps = dependencies[tool_name] || []
|
74
|
-
unless tool_deps.all? { |dep| executed.include?(dep) }
|
75
|
-
raise "Dependencies not satisfied for #{tool_name}: #{tool_deps}"
|
76
|
-
end
|
77
|
-
|
78
|
-
results[tool_name] = execute_tool(tool_name)
|
79
|
-
executed.add(tool_name)
|
80
|
-
end
|
81
|
-
|
82
|
-
results
|
83
|
-
end
|
84
|
-
|
85
|
-
# Get tool execution status
|
86
|
-
def get_execution_status(execution_id)
|
87
|
-
execution = @execution_log.find { |log| log[:execution_id] == execution_id }
|
88
|
-
return nil unless execution
|
89
|
-
|
90
|
-
{
|
91
|
-
execution_id: execution_id,
|
92
|
-
tool_name: execution[:tool_name],
|
93
|
-
status: execution[:status],
|
94
|
-
start_time: execution[:start_time],
|
95
|
-
end_time: execution[:end_time],
|
96
|
-
duration: execution[:duration],
|
97
|
-
error: execution[:error]
|
98
|
-
}
|
99
|
-
end
|
100
|
-
|
101
|
-
# Get execution history
|
102
|
-
def get_execution_history(limit = 50)
|
103
|
-
@execution_log.last(limit).map do |log|
|
104
|
-
{
|
105
|
-
execution_id: log[:execution_id],
|
106
|
-
tool_name: log[:tool_name],
|
107
|
-
status: log[:status],
|
108
|
-
start_time: log[:start_time],
|
109
|
-
duration: log[:duration],
|
110
|
-
error: log[:error]
|
111
|
-
}
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
# Validate tool configuration
|
116
|
-
def validate_tool_config(tool_name, options = {})
|
117
|
-
errors = []
|
118
|
-
|
119
|
-
# Check if tool is available
|
120
|
-
errors << "Tool '#{tool_name}' is not available" unless tool_available?(tool_name)
|
121
|
-
|
122
|
-
# Validate tool-specific options
|
123
|
-
tool_errors = validate_tool_options(tool_name, options)
|
124
|
-
errors.concat(tool_errors)
|
125
|
-
|
126
|
-
errors
|
127
|
-
end
|
128
|
-
|
129
|
-
# Get available tools
|
130
|
-
def get_available_tools
|
131
|
-
available_tools = []
|
132
|
-
|
133
|
-
# Check for Ruby tools
|
134
|
-
available_tools.concat(check_ruby_tools) if ruby_project?
|
135
|
-
|
136
|
-
# Check for JavaScript tools
|
137
|
-
available_tools.concat(check_javascript_tools) if javascript_project?
|
138
|
-
|
139
|
-
# Check for Python tools
|
140
|
-
available_tools.concat(check_python_tools) if python_project?
|
141
|
-
|
142
|
-
# Check for Java tools
|
143
|
-
available_tools.concat(check_java_tools) if java_project?
|
144
|
-
|
145
|
-
# Check for Go tools
|
146
|
-
available_tools.concat(check_go_tools) if go_project?
|
147
|
-
|
148
|
-
# Check for Rust tools
|
149
|
-
available_tools.concat(check_rust_tools) if rust_project?
|
150
|
-
|
151
|
-
available_tools
|
152
|
-
end
|
153
|
-
|
154
|
-
# Get tool execution statistics
|
155
|
-
def get_execution_statistics
|
156
|
-
return {} if @execution_log.empty?
|
157
|
-
|
158
|
-
total_executions = @execution_log.length
|
159
|
-
successful_executions = @execution_log.count { |log| log[:status] == "success" }
|
160
|
-
failed_executions = @execution_log.count { |log| log[:status] == "error" }
|
161
|
-
|
162
|
-
average_duration = @execution_log.sum { |log| log[:duration] || 0 } / total_executions
|
163
|
-
|
164
|
-
{
|
165
|
-
total_executions: total_executions,
|
166
|
-
successful_executions: successful_executions,
|
167
|
-
failed_executions: failed_executions,
|
168
|
-
success_rate: (successful_executions.to_f / total_executions * 100).round(2),
|
169
|
-
average_duration: average_duration.round(2),
|
170
|
-
tools_used: @execution_log.map { |log| log[:tool_name] }.uniq
|
171
|
-
}
|
172
|
-
end
|
173
|
-
|
174
|
-
private
|
175
|
-
|
176
|
-
def execute_tool_with_timeout(tool_name, options)
|
177
|
-
command = build_tool_command(tool_name, options)
|
178
|
-
working_dir = options[:working_dir] || @project_dir
|
179
|
-
|
180
|
-
Timeout.timeout(@timeout) do
|
181
|
-
execute_command(command, working_dir, options)
|
182
|
-
end
|
183
|
-
end
|
184
|
-
|
185
|
-
def execute_command(command, working_dir, options)
|
186
|
-
stdout, stderr, status = Open3.capture3(@env, command, chdir: working_dir)
|
187
|
-
|
188
|
-
{
|
189
|
-
command: command,
|
190
|
-
stdout: stdout,
|
191
|
-
stderr: stderr,
|
192
|
-
exit_code: status.exitstatus,
|
193
|
-
success: status.success?,
|
194
|
-
working_dir: working_dir,
|
195
|
-
options: options
|
196
|
-
}
|
197
|
-
end
|
198
|
-
|
199
|
-
def build_tool_command(tool_name, options)
|
200
|
-
case tool_name
|
201
|
-
when "rubocop"
|
202
|
-
build_rubocop_command(options)
|
203
|
-
when "reek"
|
204
|
-
build_reek_command(options)
|
205
|
-
when "brakeman"
|
206
|
-
build_brakeman_command(options)
|
207
|
-
when "bundler-audit"
|
208
|
-
build_bundler_audit_command(options)
|
209
|
-
when "eslint"
|
210
|
-
build_eslint_command(options)
|
211
|
-
when "flake8"
|
212
|
-
build_flake8_command(options)
|
213
|
-
when "bandit"
|
214
|
-
build_bandit_command(options)
|
215
|
-
when "golangci-lint"
|
216
|
-
build_golangci_lint_command(options)
|
217
|
-
when "clippy"
|
218
|
-
build_clippy_command(options)
|
219
|
-
else
|
220
|
-
# Generic command building
|
221
|
-
build_generic_command(tool_name, options)
|
222
|
-
end
|
223
|
-
end
|
224
|
-
|
225
|
-
def build_rubocop_command(options)
|
226
|
-
command = "bundle exec rubocop"
|
227
|
-
command += " --format #{options[:format] || "json"}"
|
228
|
-
command += " --out #{options[:output_file]}" if options[:output_file]
|
229
|
-
command += " #{options[:paths] || "."}"
|
230
|
-
command
|
231
|
-
end
|
232
|
-
|
233
|
-
def build_reek_command(options)
|
234
|
-
command = "bundle exec reek"
|
235
|
-
command += " --format #{options[:format] || "json"}"
|
236
|
-
command += " --output #{options[:output_file]}" if options[:output_file]
|
237
|
-
command += " #{options[:paths] || "."}"
|
238
|
-
command
|
239
|
-
end
|
240
|
-
|
241
|
-
def build_brakeman_command(options)
|
242
|
-
command = "bundle exec brakeman"
|
243
|
-
command += " --format #{options[:format] || "json"}"
|
244
|
-
command += " --output #{options[:output_file]}" if options[:output_file]
|
245
|
-
command += " --quiet" if options[:quiet]
|
246
|
-
command
|
247
|
-
end
|
248
|
-
|
249
|
-
def build_bundler_audit_command(options)
|
250
|
-
command = "bundle exec bundle-audit"
|
251
|
-
command += " --output #{options[:output_file]}" if options[:output_file]
|
252
|
-
command += " --update" if options[:update]
|
253
|
-
command
|
254
|
-
end
|
255
|
-
|
256
|
-
def build_eslint_command(options)
|
257
|
-
command = "npx eslint"
|
258
|
-
command += " --format #{options[:format] || "json"}"
|
259
|
-
command += " --output-file #{options[:output_file]}" if options[:output_file]
|
260
|
-
command += " #{options[:paths] || "."}"
|
261
|
-
command
|
262
|
-
end
|
263
|
-
|
264
|
-
def build_flake8_command(options)
|
265
|
-
command = "flake8"
|
266
|
-
command += " --format #{options[:format] || "json"}"
|
267
|
-
command += " --output-file #{options[:output_file]}" if options[:output_file]
|
268
|
-
command += " #{options[:paths] || "."}"
|
269
|
-
command
|
270
|
-
end
|
271
|
-
|
272
|
-
def build_bandit_command(options)
|
273
|
-
command = "bandit"
|
274
|
-
command += " -f #{options[:format] || "json"}"
|
275
|
-
command += " -o #{options[:output_file]}" if options[:output_file]
|
276
|
-
command += " -r #{options[:paths] || "."}"
|
277
|
-
command
|
278
|
-
end
|
279
|
-
|
280
|
-
def build_golangci_lint_command(options)
|
281
|
-
command = "golangci-lint run"
|
282
|
-
command += " --out-format #{options[:format] || "json"}"
|
283
|
-
command += " --out #{options[:output_file]}" if options[:output_file]
|
284
|
-
command += " #{options[:paths] || "."}"
|
285
|
-
command
|
286
|
-
end
|
287
|
-
|
288
|
-
def build_clippy_command(options)
|
289
|
-
command = "cargo clippy"
|
290
|
-
command += " --message-format #{options[:format] || "json"}"
|
291
|
-
command += " --output-file #{options[:output_file]}" if options[:output_file]
|
292
|
-
command
|
293
|
-
end
|
294
|
-
|
295
|
-
def build_generic_command(tool_name, options)
|
296
|
-
command = tool_name
|
297
|
-
command += " #{options[:args]}" if options[:args]
|
298
|
-
command += " #{options[:paths] || "."}" unless options[:args]&.include?(".")
|
299
|
-
command
|
300
|
-
end
|
301
|
-
|
302
|
-
def tool_available?(tool_name)
|
303
|
-
case tool_name
|
304
|
-
when /^bundle exec/
|
305
|
-
# Ruby tool - check if bundle is available
|
306
|
-
system("bundle", "--version", out: File::NULL, err: File::NULL)
|
307
|
-
when /^npx/
|
308
|
-
# Node.js tool - check if npm is available
|
309
|
-
system("npm", "--version", out: File::NULL, err: File::NULL)
|
310
|
-
when /^cargo/
|
311
|
-
# Rust tool - check if cargo is available
|
312
|
-
system("cargo", "--version", out: File::NULL, err: File::NULL)
|
313
|
-
when /^go/
|
314
|
-
# Go tool - check if go is available
|
315
|
-
system("go", "version", out: File::NULL, err: File::NULL)
|
316
|
-
else
|
317
|
-
# Generic tool - check if command is available
|
318
|
-
system("which", tool_name.split(" ").first, out: File::NULL, err: File::NULL)
|
319
|
-
end
|
320
|
-
end
|
321
|
-
|
322
|
-
def validate_tool_options(tool_name, options)
|
323
|
-
errors = []
|
324
|
-
|
325
|
-
case tool_name
|
326
|
-
when "rubocop"
|
327
|
-
errors << "Invalid format" unless %w[json text html].include?(options[:format])
|
328
|
-
when "eslint"
|
329
|
-
errors << "Invalid format" unless %w[json text html].include?(options[:format])
|
330
|
-
when "flake8"
|
331
|
-
errors << "Invalid format" unless %w[json text html].include?(options[:format])
|
332
|
-
end
|
333
|
-
|
334
|
-
errors
|
335
|
-
end
|
336
|
-
|
337
|
-
def ruby_project?
|
338
|
-
File.exist?(File.join(@project_dir, "Gemfile"))
|
339
|
-
end
|
340
|
-
|
341
|
-
def javascript_project?
|
342
|
-
File.exist?(File.join(@project_dir, "package.json"))
|
343
|
-
end
|
344
|
-
|
345
|
-
def python_project?
|
346
|
-
File.exist?(File.join(@project_dir, "requirements.txt")) || File.exist?(File.join(@project_dir, "setup.py"))
|
347
|
-
end
|
348
|
-
|
349
|
-
def java_project?
|
350
|
-
File.exist?(File.join(@project_dir, "pom.xml")) || File.exist?(File.join(@project_dir, "build.gradle"))
|
351
|
-
end
|
352
|
-
|
353
|
-
def go_project?
|
354
|
-
File.exist?(File.join(@project_dir, "go.mod"))
|
355
|
-
end
|
356
|
-
|
357
|
-
def rust_project?
|
358
|
-
File.exist?(File.join(@project_dir, "Cargo.toml"))
|
359
|
-
end
|
360
|
-
|
361
|
-
def check_ruby_tools
|
362
|
-
tools = []
|
363
|
-
tools << "rubocop" if system("bundle", "exec", "rubocop", "--version", out: File::NULL, err: File::NULL)
|
364
|
-
tools << "reek" if system("bundle", "exec", "reek", "--version", out: File::NULL, err: File::NULL)
|
365
|
-
tools << "brakeman" if system("bundle", "exec", "brakeman", "--version", out: File::NULL, err: File::NULL)
|
366
|
-
tools << "bundler-audit" if system("bundle", "exec", "bundle-audit", "--version", out: File::NULL,
|
367
|
-
err: File::NULL)
|
368
|
-
tools
|
369
|
-
end
|
370
|
-
|
371
|
-
def check_javascript_tools
|
372
|
-
tools = []
|
373
|
-
tools << "eslint" if system("npx", "eslint", "--version", out: File::NULL, err: File::NULL)
|
374
|
-
tools << "prettier" if system("npx", "prettier", "--version", out: File::NULL, err: File::NULL)
|
375
|
-
tools
|
376
|
-
end
|
377
|
-
|
378
|
-
def check_python_tools
|
379
|
-
tools = []
|
380
|
-
tools << "flake8" if system("flake8", "--version", out: File::NULL, err: File::NULL)
|
381
|
-
tools << "bandit" if system("bandit", "--version", out: File::NULL, err: File::NULL)
|
382
|
-
tools
|
383
|
-
end
|
384
|
-
|
385
|
-
def check_java_tools
|
386
|
-
tools = []
|
387
|
-
# Java tools typically require specific setup, so we'll check for common ones
|
388
|
-
tools << "checkstyle" if File.exist?(File.join(@project_dir, "checkstyle.xml"))
|
389
|
-
tools << "pmd" if File.exist?(File.join(@project_dir, "pmd.xml"))
|
390
|
-
tools
|
391
|
-
end
|
392
|
-
|
393
|
-
def check_go_tools
|
394
|
-
tools = []
|
395
|
-
tools << "golangci-lint" if system("golangci-lint", "--version", out: File::NULL, err: File::NULL)
|
396
|
-
tools << "gosec" if system("gosec", "--version", out: File::NULL, err: File::NULL)
|
397
|
-
tools
|
398
|
-
end
|
399
|
-
|
400
|
-
def check_rust_tools
|
401
|
-
tools = []
|
402
|
-
tools << "clippy" if system("cargo", "clippy", "--version", out: File::NULL, err: File::NULL)
|
403
|
-
tools << "cargo-audit" if system("cargo", "audit", "--version", out: File::NULL, err: File::NULL)
|
404
|
-
tools
|
405
|
-
end
|
406
|
-
|
407
|
-
def generate_execution_id
|
408
|
-
"exec_#{Time.now.to_i}_#{rand(1000)}"
|
409
|
-
end
|
410
|
-
|
411
|
-
def log_execution_start(execution_id, tool_name, options)
|
412
|
-
@execution_log << {
|
413
|
-
execution_id: execution_id,
|
414
|
-
tool_name: tool_name,
|
415
|
-
status: "running",
|
416
|
-
start_time: Time.now,
|
417
|
-
options: options
|
418
|
-
}
|
419
|
-
end
|
420
|
-
|
421
|
-
def log_execution_success(execution_id, tool_name, duration, result)
|
422
|
-
log_entry = @execution_log.find { |log| log[:execution_id] == execution_id }
|
423
|
-
return unless log_entry
|
424
|
-
|
425
|
-
log_entry.merge!(
|
426
|
-
status: "success",
|
427
|
-
end_time: Time.now,
|
428
|
-
duration: duration,
|
429
|
-
result: result
|
430
|
-
)
|
431
|
-
end
|
432
|
-
|
433
|
-
def log_execution_error(execution_id, tool_name, duration, error)
|
434
|
-
log_entry = @execution_log.find { |log| log[:execution_id] == execution_id }
|
435
|
-
return unless log_entry
|
436
|
-
|
437
|
-
log_entry.merge!(
|
438
|
-
status: "error",
|
439
|
-
end_time: Time.now,
|
440
|
-
duration: duration,
|
441
|
-
error: error.message
|
442
|
-
)
|
443
|
-
end
|
444
|
-
end
|
445
|
-
end
|