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,897 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Aidp
|
4
|
-
class LanguageAnalysisStrategies
|
5
|
-
# Define language-specific analysis strategies
|
6
|
-
LANGUAGE_STRATEGIES = {
|
7
|
-
"ruby" => {
|
8
|
-
"analysis_phases" => [
|
9
|
-
{
|
10
|
-
phase: 1,
|
11
|
-
name: "Code Style and Quality",
|
12
|
-
tools: %w[rubocop reek],
|
13
|
-
focus_areas: ["style violations", "code smells", "complexity metrics"],
|
14
|
-
priority: "high"
|
15
|
-
},
|
16
|
-
{
|
17
|
-
phase: 2,
|
18
|
-
name: "Security Analysis",
|
19
|
-
tools: %w[brakeman bundler-audit],
|
20
|
-
focus_areas: ["security vulnerabilities", "dependency vulnerabilities"],
|
21
|
-
priority: "high"
|
22
|
-
},
|
23
|
-
{
|
24
|
-
phase: 3,
|
25
|
-
name: "Performance Analysis",
|
26
|
-
tools: %w[fasterer ruby-prof],
|
27
|
-
focus_areas: ["performance bottlenecks", "memory usage"],
|
28
|
-
priority: "medium"
|
29
|
-
},
|
30
|
-
{
|
31
|
-
phase: 4,
|
32
|
-
name: "Test Coverage",
|
33
|
-
tools: %w[simplecov rspec],
|
34
|
-
focus_areas: ["test coverage", "test quality"],
|
35
|
-
priority: "medium"
|
36
|
-
}
|
37
|
-
],
|
38
|
-
"code_patterns" => {
|
39
|
-
"complex_methods" => {
|
40
|
-
pattern: "methods with high cyclomatic complexity",
|
41
|
-
detection: "rubocop --only Metrics/CyclomaticComplexity",
|
42
|
-
threshold: 10
|
43
|
-
},
|
44
|
-
"long_methods" => {
|
45
|
-
pattern: "methods with excessive lines",
|
46
|
-
detection: "rubocop --only Metrics/MethodLength",
|
47
|
-
threshold: 20
|
48
|
-
},
|
49
|
-
"duplicate_code" => {
|
50
|
-
pattern: "code duplication",
|
51
|
-
detection: "reek --detect DuplicateMethodCall",
|
52
|
-
threshold: 3
|
53
|
-
},
|
54
|
-
"security_issues" => {
|
55
|
-
pattern: "SQL injection, XSS, CSRF vulnerabilities",
|
56
|
-
detection: "brakeman --quiet --format json",
|
57
|
-
threshold: 0
|
58
|
-
}
|
59
|
-
},
|
60
|
-
"refactoring_priorities" => [
|
61
|
-
"Extract complex methods",
|
62
|
-
"Reduce method length",
|
63
|
-
"Eliminate code duplication",
|
64
|
-
"Improve naming conventions",
|
65
|
-
"Add missing tests"
|
66
|
-
]
|
67
|
-
},
|
68
|
-
"javascript" => {
|
69
|
-
"analysis_phases" => [
|
70
|
-
{
|
71
|
-
phase: 1,
|
72
|
-
name: "Code Quality and Style",
|
73
|
-
tools: %w[eslint prettier],
|
74
|
-
focus_areas: ["linting errors", "code formatting", "best practices"],
|
75
|
-
priority: "high"
|
76
|
-
},
|
77
|
-
{
|
78
|
-
phase: 2,
|
79
|
-
name: "Security Analysis",
|
80
|
-
tools: %w[npm-audit eslint-plugin-security],
|
81
|
-
focus_areas: ["dependency vulnerabilities", "security anti-patterns"],
|
82
|
-
priority: "high"
|
83
|
-
},
|
84
|
-
{
|
85
|
-
phase: 3,
|
86
|
-
name: "Type Safety",
|
87
|
-
tools: %w[typescript flow],
|
88
|
-
focus_areas: ["type errors", "type coverage"],
|
89
|
-
priority: "medium"
|
90
|
-
},
|
91
|
-
{
|
92
|
-
phase: 4,
|
93
|
-
name: "Performance Analysis",
|
94
|
-
tools: %w[webpack-bundle-analyzer lighthouse],
|
95
|
-
focus_areas: ["bundle size", "performance metrics"],
|
96
|
-
priority: "medium"
|
97
|
-
}
|
98
|
-
],
|
99
|
-
"code_patterns" => {
|
100
|
-
"callback_hell" => {
|
101
|
-
pattern: "nested callbacks",
|
102
|
-
detection: 'eslint --rule "callback-return: error"',
|
103
|
-
threshold: 3
|
104
|
-
},
|
105
|
-
"memory_leaks" => {
|
106
|
-
pattern: "event listeners not removed",
|
107
|
-
detection: 'eslint --rule "no-unused-vars: error"',
|
108
|
-
threshold: 0
|
109
|
-
},
|
110
|
-
"async_issues" => {
|
111
|
-
pattern: "unhandled promises",
|
112
|
-
detection: 'eslint --rule "no-floating-promises: error"',
|
113
|
-
threshold: 0
|
114
|
-
},
|
115
|
-
"security_vulnerabilities" => {
|
116
|
-
pattern: "XSS, CSRF, injection vulnerabilities",
|
117
|
-
detection: "eslint-plugin-security",
|
118
|
-
threshold: 0
|
119
|
-
}
|
120
|
-
},
|
121
|
-
"refactoring_priorities" => [
|
122
|
-
"Convert callbacks to async/await",
|
123
|
-
"Add proper error handling",
|
124
|
-
"Implement proper type safety",
|
125
|
-
"Optimize bundle size",
|
126
|
-
"Add comprehensive tests"
|
127
|
-
]
|
128
|
-
},
|
129
|
-
"python" => {
|
130
|
-
"analysis_phases" => [
|
131
|
-
{
|
132
|
-
phase: 1,
|
133
|
-
name: "Code Style and Quality",
|
134
|
-
tools: %w[flake8 black pylint],
|
135
|
-
focus_areas: ["PEP8 compliance", "code formatting", "code quality"],
|
136
|
-
priority: "high"
|
137
|
-
},
|
138
|
-
{
|
139
|
-
phase: 2,
|
140
|
-
name: "Security Analysis",
|
141
|
-
tools: %w[bandit safety],
|
142
|
-
focus_areas: ["security vulnerabilities", "dependency vulnerabilities"],
|
143
|
-
priority: "high"
|
144
|
-
},
|
145
|
-
{
|
146
|
-
phase: 3,
|
147
|
-
name: "Type Safety",
|
148
|
-
tools: %w[mypy pyright],
|
149
|
-
focus_areas: ["type checking", "type coverage"],
|
150
|
-
priority: "medium"
|
151
|
-
},
|
152
|
-
{
|
153
|
-
phase: 4,
|
154
|
-
name: "Performance Analysis",
|
155
|
-
tools: %w[py-spy memory-profiler],
|
156
|
-
focus_areas: ["performance bottlenecks", "memory usage"],
|
157
|
-
priority: "medium"
|
158
|
-
}
|
159
|
-
],
|
160
|
-
"code_patterns" => {
|
161
|
-
"complex_functions" => {
|
162
|
-
pattern: "functions with high complexity",
|
163
|
-
detection: "pylint --disable=all --enable=too-complex",
|
164
|
-
threshold: 10
|
165
|
-
},
|
166
|
-
"long_functions" => {
|
167
|
-
pattern: "functions with excessive lines",
|
168
|
-
detection: "pylint --disable=all --enable=too-many-lines",
|
169
|
-
threshold: 50
|
170
|
-
},
|
171
|
-
"unused_imports" => {
|
172
|
-
pattern: "unused imports",
|
173
|
-
detection: "flake8 --select=F401",
|
174
|
-
threshold: 0
|
175
|
-
},
|
176
|
-
"security_issues" => {
|
177
|
-
pattern: "SQL injection, command injection",
|
178
|
-
detection: "bandit -r .",
|
179
|
-
threshold: 0
|
180
|
-
}
|
181
|
-
},
|
182
|
-
"refactoring_priorities" => [
|
183
|
-
"Simplify complex functions",
|
184
|
-
"Remove unused imports",
|
185
|
-
"Add type hints",
|
186
|
-
"Improve error handling",
|
187
|
-
"Add comprehensive tests"
|
188
|
-
]
|
189
|
-
},
|
190
|
-
"java" => {
|
191
|
-
"analysis_phases" => [
|
192
|
-
{
|
193
|
-
phase: 1,
|
194
|
-
name: "Code Quality",
|
195
|
-
tools: %w[checkstyle pmd],
|
196
|
-
focus_areas: ["code style", "code quality", "best practices"],
|
197
|
-
priority: "high"
|
198
|
-
},
|
199
|
-
{
|
200
|
-
phase: 2,
|
201
|
-
name: "Security Analysis",
|
202
|
-
tools: %w[spotbugs dependency-check],
|
203
|
-
focus_areas: ["security vulnerabilities", "dependency vulnerabilities"],
|
204
|
-
priority: "high"
|
205
|
-
},
|
206
|
-
{
|
207
|
-
phase: 3,
|
208
|
-
name: "Performance Analysis",
|
209
|
-
tools: %w[jmh visualvm],
|
210
|
-
focus_areas: ["performance bottlenecks", "memory leaks"],
|
211
|
-
priority: "medium"
|
212
|
-
},
|
213
|
-
{
|
214
|
-
phase: 4,
|
215
|
-
name: "Test Coverage",
|
216
|
-
tools: %w[jacoco junit],
|
217
|
-
focus_areas: ["test coverage", "test quality"],
|
218
|
-
priority: "medium"
|
219
|
-
}
|
220
|
-
],
|
221
|
-
"code_patterns" => {
|
222
|
-
"complex_methods" => {
|
223
|
-
pattern: "methods with high cyclomatic complexity",
|
224
|
-
detection: "pmd --rulesets complexity",
|
225
|
-
threshold: 10
|
226
|
-
},
|
227
|
-
"code_duplication" => {
|
228
|
-
pattern: "duplicate code blocks",
|
229
|
-
detection: "pmd --rulesets cpd",
|
230
|
-
threshold: 50
|
231
|
-
},
|
232
|
-
"memory_leaks" => {
|
233
|
-
pattern: "potential memory leaks",
|
234
|
-
detection: "spotbugs --effort:max",
|
235
|
-
threshold: 0
|
236
|
-
},
|
237
|
-
"security_vulnerabilities" => {
|
238
|
-
pattern: "SQL injection, XSS, path traversal",
|
239
|
-
detection: "spotbugs --effort:max",
|
240
|
-
threshold: 0
|
241
|
-
}
|
242
|
-
},
|
243
|
-
"refactoring_priorities" => [
|
244
|
-
"Extract complex methods",
|
245
|
-
"Eliminate code duplication",
|
246
|
-
"Improve exception handling",
|
247
|
-
"Add proper logging",
|
248
|
-
"Increase test coverage"
|
249
|
-
]
|
250
|
-
},
|
251
|
-
"go" => {
|
252
|
-
"analysis_phases" => [
|
253
|
-
{
|
254
|
-
phase: 1,
|
255
|
-
name: "Code Quality",
|
256
|
-
tools: %w[golangci-lint gofmt],
|
257
|
-
focus_areas: ["code style", "code quality", "best practices"],
|
258
|
-
priority: "high"
|
259
|
-
},
|
260
|
-
{
|
261
|
-
phase: 2,
|
262
|
-
name: "Security Analysis",
|
263
|
-
tools: %w[gosec govet],
|
264
|
-
focus_areas: ["security vulnerabilities", "common mistakes"],
|
265
|
-
priority: "high"
|
266
|
-
},
|
267
|
-
{
|
268
|
-
phase: 3,
|
269
|
-
name: "Performance Analysis",
|
270
|
-
tools: %w[pprof go-torch],
|
271
|
-
focus_areas: ["performance bottlenecks", "memory usage"],
|
272
|
-
priority: "medium"
|
273
|
-
},
|
274
|
-
{
|
275
|
-
phase: 4,
|
276
|
-
name: "Test Coverage",
|
277
|
-
tools: %w[go test -cover],
|
278
|
-
focus_areas: ["test coverage", "test quality"],
|
279
|
-
priority: "medium"
|
280
|
-
}
|
281
|
-
],
|
282
|
-
"code_patterns" => {
|
283
|
-
"complex_functions" => {
|
284
|
-
pattern: "functions with high cyclomatic complexity",
|
285
|
-
detection: "golangci-lint --enable=gocyclo",
|
286
|
-
threshold: 15
|
287
|
-
},
|
288
|
-
"error_handling" => {
|
289
|
-
pattern: "unhandled errors",
|
290
|
-
detection: "golangci-lint --enable=errcheck",
|
291
|
-
threshold: 0
|
292
|
-
},
|
293
|
-
"race_conditions" => {
|
294
|
-
pattern: "potential race conditions",
|
295
|
-
detection: "go test -race",
|
296
|
-
threshold: 0
|
297
|
-
},
|
298
|
-
"security_issues" => {
|
299
|
-
pattern: "security vulnerabilities",
|
300
|
-
detection: "gosec ./...",
|
301
|
-
threshold: 0
|
302
|
-
}
|
303
|
-
},
|
304
|
-
"refactoring_priorities" => [
|
305
|
-
"Simplify complex functions",
|
306
|
-
"Improve error handling",
|
307
|
-
"Add proper logging",
|
308
|
-
"Eliminate race conditions",
|
309
|
-
"Increase test coverage"
|
310
|
-
]
|
311
|
-
},
|
312
|
-
"rust" => {
|
313
|
-
"analysis_phases" => [
|
314
|
-
{
|
315
|
-
phase: 1,
|
316
|
-
name: "Code Quality",
|
317
|
-
tools: %w[clippy rustfmt],
|
318
|
-
focus_areas: ["code style", "code quality", "best practices"],
|
319
|
-
priority: "high"
|
320
|
-
},
|
321
|
-
{
|
322
|
-
phase: 2,
|
323
|
-
name: "Security Analysis",
|
324
|
-
tools: %w[cargo-audit cargo-geiger],
|
325
|
-
focus_areas: ["dependency vulnerabilities", "unsafe code usage"],
|
326
|
-
priority: "high"
|
327
|
-
},
|
328
|
-
{
|
329
|
-
phase: 3,
|
330
|
-
name: "Performance Analysis",
|
331
|
-
tools: %w[cargo bench flamegraph],
|
332
|
-
focus_areas: ["performance benchmarks", "memory usage"],
|
333
|
-
priority: "medium"
|
334
|
-
},
|
335
|
-
{
|
336
|
-
phase: 4,
|
337
|
-
name: "Test Coverage",
|
338
|
-
tools: %w[tarpaulin cargo test],
|
339
|
-
focus_areas: ["test coverage", "test quality"],
|
340
|
-
priority: "medium"
|
341
|
-
}
|
342
|
-
],
|
343
|
-
"code_patterns" => {
|
344
|
-
"complex_functions" => {
|
345
|
-
pattern: "functions with high cyclomatic complexity",
|
346
|
-
detection: "clippy --all --warn clippy::cognitive_complexity",
|
347
|
-
threshold: 25
|
348
|
-
},
|
349
|
-
"unsafe_code" => {
|
350
|
-
pattern: "unsafe code blocks",
|
351
|
-
detection: "cargo-geiger",
|
352
|
-
threshold: 0
|
353
|
-
},
|
354
|
-
"unused_code" => {
|
355
|
-
pattern: "unused functions and variables",
|
356
|
-
detection: "clippy --all --warn dead_code",
|
357
|
-
threshold: 0
|
358
|
-
},
|
359
|
-
"security_issues" => {
|
360
|
-
pattern: "security vulnerabilities",
|
361
|
-
detection: "cargo-audit",
|
362
|
-
threshold: 0
|
363
|
-
}
|
364
|
-
},
|
365
|
-
"refactoring_priorities" => [
|
366
|
-
"Simplify complex functions",
|
367
|
-
"Reduce unsafe code usage",
|
368
|
-
"Remove unused code",
|
369
|
-
"Improve error handling",
|
370
|
-
"Add comprehensive tests"
|
371
|
-
]
|
372
|
-
}
|
373
|
-
}.freeze
|
374
|
-
|
375
|
-
def initialize(project_dir = Dir.pwd)
|
376
|
-
@project_dir = project_dir
|
377
|
-
end
|
378
|
-
|
379
|
-
# Get analysis strategy for a specific language
|
380
|
-
def get_analysis_strategy(language)
|
381
|
-
strategy = LANGUAGE_STRATEGIES[language]
|
382
|
-
return nil unless strategy
|
383
|
-
|
384
|
-
{
|
385
|
-
language: language,
|
386
|
-
phases: strategy["analysis_phases"],
|
387
|
-
patterns: strategy["code_patterns"],
|
388
|
-
refactoring_priorities: strategy["refactoring_priorities"],
|
389
|
-
customizations: generate_customizations(language)
|
390
|
-
}
|
391
|
-
end
|
392
|
-
|
393
|
-
# Get analysis phases for a language
|
394
|
-
def get_analysis_phases(language)
|
395
|
-
strategy = LANGUAGE_STRATEGIES[language]
|
396
|
-
return [] unless strategy
|
397
|
-
|
398
|
-
strategy["analysis_phases"]
|
399
|
-
end
|
400
|
-
|
401
|
-
# Get code patterns for a language
|
402
|
-
def get_code_patterns(language)
|
403
|
-
strategy = LANGUAGE_STRATEGIES[language]
|
404
|
-
return {} unless strategy
|
405
|
-
|
406
|
-
strategy["code_patterns"]
|
407
|
-
end
|
408
|
-
|
409
|
-
# Get refactoring priorities for a language
|
410
|
-
def get_refactoring_priorities(language)
|
411
|
-
strategy = LANGUAGE_STRATEGIES[language]
|
412
|
-
return [] unless strategy
|
413
|
-
|
414
|
-
strategy["refactoring_priorities"]
|
415
|
-
end
|
416
|
-
|
417
|
-
# Generate custom analysis plan for a language
|
418
|
-
def generate_custom_analysis_plan(language, focus_areas = [])
|
419
|
-
strategy = get_analysis_strategy(language)
|
420
|
-
return nil unless strategy
|
421
|
-
|
422
|
-
plan = {
|
423
|
-
language: language,
|
424
|
-
phases: [],
|
425
|
-
focus_areas: focus_areas,
|
426
|
-
estimated_duration: estimate_analysis_duration(language, focus_areas),
|
427
|
-
tools_required: get_required_tools(language, focus_areas)
|
428
|
-
}
|
429
|
-
|
430
|
-
# Filter phases based on focus areas
|
431
|
-
plan[:phases] = if focus_areas.any?
|
432
|
-
strategy[:phases].select do |phase|
|
433
|
-
focus_areas.any? { |area| phase[:focus_areas].any? { |fa| fa.include?(area) } }
|
434
|
-
end
|
435
|
-
else
|
436
|
-
strategy[:phases]
|
437
|
-
end
|
438
|
-
|
439
|
-
plan
|
440
|
-
end
|
441
|
-
|
442
|
-
# Get language-specific recommendations
|
443
|
-
def get_language_recommendations(language, analysis_results = {})
|
444
|
-
recommendations = []
|
445
|
-
|
446
|
-
case language
|
447
|
-
when "ruby"
|
448
|
-
recommendations.concat(generate_ruby_recommendations(analysis_results))
|
449
|
-
when "javascript"
|
450
|
-
recommendations.concat(generate_javascript_recommendations(analysis_results))
|
451
|
-
when "python"
|
452
|
-
recommendations.concat(generate_python_recommendations(analysis_results))
|
453
|
-
when "java"
|
454
|
-
recommendations.concat(generate_java_recommendations(analysis_results))
|
455
|
-
when "go"
|
456
|
-
recommendations.concat(generate_go_recommendations(analysis_results))
|
457
|
-
when "rust"
|
458
|
-
recommendations.concat(generate_rust_recommendations(analysis_results))
|
459
|
-
end
|
460
|
-
|
461
|
-
recommendations
|
462
|
-
end
|
463
|
-
|
464
|
-
# Get language-specific best practices
|
465
|
-
def get_language_best_practices(language)
|
466
|
-
case language
|
467
|
-
when "ruby"
|
468
|
-
{
|
469
|
-
"style" => [
|
470
|
-
"Follow Ruby style guide",
|
471
|
-
"Use meaningful variable names",
|
472
|
-
"Keep methods small and focused",
|
473
|
-
"Use proper indentation"
|
474
|
-
],
|
475
|
-
"security" => [
|
476
|
-
"Use parameterized queries",
|
477
|
-
"Validate user input",
|
478
|
-
"Use HTTPS in production",
|
479
|
-
"Keep gems updated"
|
480
|
-
],
|
481
|
-
"performance" => [
|
482
|
-
"Use appropriate data structures",
|
483
|
-
"Avoid N+1 queries",
|
484
|
-
"Use caching where appropriate",
|
485
|
-
"Profile before optimizing"
|
486
|
-
]
|
487
|
-
}
|
488
|
-
when "javascript"
|
489
|
-
{
|
490
|
-
"style" => [
|
491
|
-
"Use consistent formatting",
|
492
|
-
"Follow ESLint rules",
|
493
|
-
"Use meaningful variable names",
|
494
|
-
"Avoid global variables"
|
495
|
-
],
|
496
|
-
"security" => [
|
497
|
-
"Validate user input",
|
498
|
-
"Use HTTPS",
|
499
|
-
"Avoid eval()",
|
500
|
-
"Keep dependencies updated"
|
501
|
-
],
|
502
|
-
"performance" => [
|
503
|
-
"Minimize bundle size",
|
504
|
-
"Use lazy loading",
|
505
|
-
"Optimize images",
|
506
|
-
"Use appropriate caching"
|
507
|
-
]
|
508
|
-
}
|
509
|
-
when "python"
|
510
|
-
{
|
511
|
-
"style" => [
|
512
|
-
"Follow PEP 8",
|
513
|
-
"Use meaningful variable names",
|
514
|
-
"Keep functions small",
|
515
|
-
"Use proper docstrings"
|
516
|
-
],
|
517
|
-
"security" => [
|
518
|
-
"Validate user input",
|
519
|
-
"Use parameterized queries",
|
520
|
-
"Keep packages updated",
|
521
|
-
"Use virtual environments"
|
522
|
-
],
|
523
|
-
"performance" => [
|
524
|
-
"Use appropriate data structures",
|
525
|
-
"Profile before optimizing",
|
526
|
-
"Use list comprehensions",
|
527
|
-
"Avoid global variables"
|
528
|
-
]
|
529
|
-
}
|
530
|
-
else
|
531
|
-
{}
|
532
|
-
end
|
533
|
-
end
|
534
|
-
|
535
|
-
# Get language-specific anti-patterns
|
536
|
-
def get_language_anti_patterns(language)
|
537
|
-
case language
|
538
|
-
when "ruby"
|
539
|
-
[
|
540
|
-
"Monkey patching",
|
541
|
-
"Global variables",
|
542
|
-
"Complex conditionals",
|
543
|
-
"Long methods",
|
544
|
-
"Code duplication"
|
545
|
-
]
|
546
|
-
when "javascript"
|
547
|
-
[
|
548
|
-
"Callback hell",
|
549
|
-
"Global variables",
|
550
|
-
"eval() usage",
|
551
|
-
"Unhandled promises",
|
552
|
-
"Memory leaks"
|
553
|
-
]
|
554
|
-
when "python"
|
555
|
-
[
|
556
|
-
"Global variables",
|
557
|
-
"Complex list comprehensions",
|
558
|
-
"Unused imports",
|
559
|
-
"Long functions",
|
560
|
-
"Code duplication"
|
561
|
-
]
|
562
|
-
else
|
563
|
-
[]
|
564
|
-
end
|
565
|
-
end
|
566
|
-
|
567
|
-
private
|
568
|
-
|
569
|
-
def generate_customizations(language)
|
570
|
-
customizations = {}
|
571
|
-
|
572
|
-
case language
|
573
|
-
when "ruby"
|
574
|
-
customizations = {
|
575
|
-
"framework_specific" => detect_ruby_framework,
|
576
|
-
"gem_analysis" => analyze_ruby_gems,
|
577
|
-
"test_framework" => detect_test_framework
|
578
|
-
}
|
579
|
-
when "javascript"
|
580
|
-
customizations = {
|
581
|
-
"framework_specific" => detect_javascript_framework,
|
582
|
-
"package_analysis" => analyze_javascript_packages,
|
583
|
-
"build_tool" => detect_build_tool
|
584
|
-
}
|
585
|
-
when "python"
|
586
|
-
customizations = {
|
587
|
-
"framework_specific" => detect_python_framework,
|
588
|
-
"package_analysis" => analyze_python_packages,
|
589
|
-
"virtual_environment" => detect_virtual_environment
|
590
|
-
}
|
591
|
-
end
|
592
|
-
|
593
|
-
customizations
|
594
|
-
end
|
595
|
-
|
596
|
-
def detect_ruby_framework
|
597
|
-
if File.exist?(File.join(@project_dir, "config", "application.rb"))
|
598
|
-
"rails"
|
599
|
-
elsif File.exist?(File.join(@project_dir, "app.rb"))
|
600
|
-
"sinatra"
|
601
|
-
elsif File.exist?(File.join(@project_dir, "*.gemspec"))
|
602
|
-
"gem"
|
603
|
-
else
|
604
|
-
"unknown"
|
605
|
-
end
|
606
|
-
end
|
607
|
-
|
608
|
-
def analyze_ruby_gems
|
609
|
-
gemfile_path = File.join(@project_dir, "Gemfile")
|
610
|
-
return {} unless File.exist?(gemfile_path)
|
611
|
-
|
612
|
-
gemfile_content = File.read(gemfile_path)
|
613
|
-
{
|
614
|
-
"total_gems" => gemfile_content.scan(/gem\s+['"]([^'"]+)['"]/).flatten.length,
|
615
|
-
"development_gems" => gemfile_content.scan(/group\s+:development.*?end/m).any?,
|
616
|
-
"test_gems" => gemfile_content.scan(/group\s+:test.*?end/m).any?,
|
617
|
-
"production_gems" => gemfile_content.scan(/group\s+:production.*?end/m).any?
|
618
|
-
}
|
619
|
-
end
|
620
|
-
|
621
|
-
def detect_test_framework
|
622
|
-
if File.exist?(File.join(@project_dir, "spec"))
|
623
|
-
"rspec"
|
624
|
-
elsif File.exist?(File.join(@project_dir, "test"))
|
625
|
-
"minitest"
|
626
|
-
else
|
627
|
-
"unknown"
|
628
|
-
end
|
629
|
-
end
|
630
|
-
|
631
|
-
def detect_javascript_framework
|
632
|
-
package_json_path = File.join(@project_dir, "package.json")
|
633
|
-
return "unknown" unless File.exist?(package_json_path)
|
634
|
-
|
635
|
-
package_json = JSON.parse(File.read(package_json_path))
|
636
|
-
dependencies = package_json["dependencies"] || {}
|
637
|
-
dev_dependencies = package_json["devDependencies"] || {}
|
638
|
-
|
639
|
-
if dependencies["react"] || dev_dependencies["react"]
|
640
|
-
"react"
|
641
|
-
elsif dependencies["vue"] || dev_dependencies["vue"]
|
642
|
-
"vue"
|
643
|
-
elsif dependencies["angular"] || dev_dependencies["angular"]
|
644
|
-
"angular"
|
645
|
-
elsif dependencies["express"] || dev_dependencies["express"]
|
646
|
-
"express"
|
647
|
-
else
|
648
|
-
"node"
|
649
|
-
end
|
650
|
-
end
|
651
|
-
|
652
|
-
def analyze_javascript_packages
|
653
|
-
package_json_path = File.join(@project_dir, "package.json")
|
654
|
-
return {} unless File.exist?(package_json_path)
|
655
|
-
|
656
|
-
package_json = JSON.parse(File.read(package_json_path))
|
657
|
-
{
|
658
|
-
"total_dependencies" => (package_json["dependencies"] || {}).length,
|
659
|
-
"total_dev_dependencies" => (package_json["devDependencies"] || {}).length,
|
660
|
-
"has_scripts" => (package_json["scripts"] || {}).any?,
|
661
|
-
"has_type_definitions" => package_json["dependencies"]&.key?("@types") || false
|
662
|
-
}
|
663
|
-
end
|
664
|
-
|
665
|
-
def detect_build_tool
|
666
|
-
if File.exist?(File.join(@project_dir, "webpack.config.js"))
|
667
|
-
"webpack"
|
668
|
-
elsif File.exist?(File.join(@project_dir, "vite.config.js"))
|
669
|
-
"vite"
|
670
|
-
elsif File.exist?(File.join(@project_dir, "rollup.config.js"))
|
671
|
-
"rollup"
|
672
|
-
else
|
673
|
-
"unknown"
|
674
|
-
end
|
675
|
-
end
|
676
|
-
|
677
|
-
def detect_python_framework
|
678
|
-
if File.exist?(File.join(@project_dir, "manage.py"))
|
679
|
-
"django"
|
680
|
-
elsif File.exist?(File.join(@project_dir, "app.py"))
|
681
|
-
"flask"
|
682
|
-
elsif File.exist?(File.join(@project_dir, "main.py"))
|
683
|
-
"fastapi"
|
684
|
-
else
|
685
|
-
"unknown"
|
686
|
-
end
|
687
|
-
end
|
688
|
-
|
689
|
-
def analyze_python_packages
|
690
|
-
requirements_path = File.join(@project_dir, "requirements.txt")
|
691
|
-
return {} unless File.exist?(requirements_path)
|
692
|
-
|
693
|
-
requirements_content = File.read(requirements_path)
|
694
|
-
{
|
695
|
-
"total_packages" => requirements_content.lines.count { |line| line.strip != "" && !line.start_with?("#") },
|
696
|
-
"has_dev_requirements" => File.exist?(File.join(@project_dir, "requirements-dev.txt")),
|
697
|
-
"has_test_requirements" => File.exist?(File.join(@project_dir, "requirements-test.txt"))
|
698
|
-
}
|
699
|
-
end
|
700
|
-
|
701
|
-
def detect_virtual_environment
|
702
|
-
if File.exist?(File.join(@project_dir, "venv"))
|
703
|
-
"venv"
|
704
|
-
elsif File.exist?(File.join(@project_dir, ".venv"))
|
705
|
-
".venv"
|
706
|
-
elsif File.exist?(File.join(@project_dir, "env"))
|
707
|
-
"env"
|
708
|
-
else
|
709
|
-
"unknown"
|
710
|
-
end
|
711
|
-
end
|
712
|
-
|
713
|
-
def estimate_analysis_duration(language, focus_areas)
|
714
|
-
base_duration = case language
|
715
|
-
when "ruby"
|
716
|
-
30 # minutes
|
717
|
-
when "javascript"
|
718
|
-
45 # minutes
|
719
|
-
when "python"
|
720
|
-
25 # minutes
|
721
|
-
when "java"
|
722
|
-
60 # minutes
|
723
|
-
when "go"
|
724
|
-
20 # minutes
|
725
|
-
when "rust"
|
726
|
-
35 # minutes
|
727
|
-
else
|
728
|
-
30 # minutes
|
729
|
-
end
|
730
|
-
|
731
|
-
# Adjust based on focus areas
|
732
|
-
base_duration += 15 if focus_areas.include?("security")
|
733
|
-
base_duration += 20 if focus_areas.include?("performance")
|
734
|
-
base_duration += 10 if focus_areas.include?("test_coverage")
|
735
|
-
|
736
|
-
base_duration
|
737
|
-
end
|
738
|
-
|
739
|
-
def get_required_tools(language, focus_areas)
|
740
|
-
strategy = LANGUAGE_STRATEGIES[language]
|
741
|
-
return [] unless strategy
|
742
|
-
|
743
|
-
required_tools = []
|
744
|
-
strategy["analysis_phases"].each do |phase|
|
745
|
-
if focus_areas.empty? || focus_areas.any? { |area| phase[:focus_areas].any? { |fa| fa.include?(area) } }
|
746
|
-
required_tools.concat(phase[:tools])
|
747
|
-
end
|
748
|
-
end
|
749
|
-
|
750
|
-
required_tools.uniq
|
751
|
-
end
|
752
|
-
|
753
|
-
def generate_ruby_recommendations(analysis_results)
|
754
|
-
recommendations = []
|
755
|
-
|
756
|
-
if analysis_results["style_violations"]&.> 10
|
757
|
-
recommendations << {
|
758
|
-
type: "style",
|
759
|
-
priority: "high",
|
760
|
-
message: "High number of style violations detected",
|
761
|
-
action: "Run RuboCop and fix style issues"
|
762
|
-
}
|
763
|
-
end
|
764
|
-
|
765
|
-
if analysis_results["security_vulnerabilities"]&.> 0
|
766
|
-
recommendations << {
|
767
|
-
type: "security",
|
768
|
-
priority: "critical",
|
769
|
-
message: "Security vulnerabilities found",
|
770
|
-
action: "Run Brakeman and address security issues immediately"
|
771
|
-
}
|
772
|
-
end
|
773
|
-
|
774
|
-
recommendations
|
775
|
-
end
|
776
|
-
|
777
|
-
def generate_javascript_recommendations(analysis_results)
|
778
|
-
recommendations = []
|
779
|
-
|
780
|
-
if analysis_results["linting_errors"]&.> 20
|
781
|
-
recommendations << {
|
782
|
-
type: "quality",
|
783
|
-
priority: "high",
|
784
|
-
message: "High number of linting errors",
|
785
|
-
action: "Run ESLint and fix code quality issues"
|
786
|
-
}
|
787
|
-
end
|
788
|
-
|
789
|
-
if analysis_results["security_vulnerabilities"]&.> 0
|
790
|
-
recommendations << {
|
791
|
-
type: "security",
|
792
|
-
priority: "critical",
|
793
|
-
message: "Security vulnerabilities in dependencies",
|
794
|
-
action: "Run npm audit and update vulnerable packages"
|
795
|
-
}
|
796
|
-
end
|
797
|
-
|
798
|
-
recommendations
|
799
|
-
end
|
800
|
-
|
801
|
-
def generate_python_recommendations(analysis_results)
|
802
|
-
recommendations = []
|
803
|
-
|
804
|
-
if analysis_results["pep8_violations"]&.> 15
|
805
|
-
recommendations << {
|
806
|
-
type: "style",
|
807
|
-
priority: "medium",
|
808
|
-
message: "PEP8 violations detected",
|
809
|
-
action: "Run flake8 and fix style issues"
|
810
|
-
}
|
811
|
-
end
|
812
|
-
|
813
|
-
if analysis_results["security_issues"]&.> 0
|
814
|
-
recommendations << {
|
815
|
-
type: "security",
|
816
|
-
priority: "critical",
|
817
|
-
message: "Security issues found",
|
818
|
-
action: "Run bandit and address security vulnerabilities"
|
819
|
-
}
|
820
|
-
end
|
821
|
-
|
822
|
-
recommendations
|
823
|
-
end
|
824
|
-
|
825
|
-
def generate_java_recommendations(analysis_results)
|
826
|
-
recommendations = []
|
827
|
-
|
828
|
-
if analysis_results["checkstyle_violations"]&.> 25
|
829
|
-
recommendations << {
|
830
|
-
type: "style",
|
831
|
-
priority: "medium",
|
832
|
-
message: "Checkstyle violations detected",
|
833
|
-
action: "Run Checkstyle and fix code style issues"
|
834
|
-
}
|
835
|
-
end
|
836
|
-
|
837
|
-
if analysis_results["security_vulnerabilities"]&.> 0
|
838
|
-
recommendations << {
|
839
|
-
type: "security",
|
840
|
-
priority: "critical",
|
841
|
-
message: "Security vulnerabilities found",
|
842
|
-
action: "Run SpotBugs and address security issues"
|
843
|
-
}
|
844
|
-
end
|
845
|
-
|
846
|
-
recommendations
|
847
|
-
end
|
848
|
-
|
849
|
-
def generate_go_recommendations(analysis_results)
|
850
|
-
recommendations = []
|
851
|
-
|
852
|
-
if analysis_results["linting_errors"]&.> 10
|
853
|
-
recommendations << {
|
854
|
-
type: "quality",
|
855
|
-
priority: "high",
|
856
|
-
message: "Go linting errors detected",
|
857
|
-
action: "Run golangci-lint and fix code quality issues"
|
858
|
-
}
|
859
|
-
end
|
860
|
-
|
861
|
-
if analysis_results["security_issues"]&.> 0
|
862
|
-
recommendations << {
|
863
|
-
type: "security",
|
864
|
-
priority: "critical",
|
865
|
-
message: "Security issues found",
|
866
|
-
action: "Run gosec and address security vulnerabilities"
|
867
|
-
}
|
868
|
-
end
|
869
|
-
|
870
|
-
recommendations
|
871
|
-
end
|
872
|
-
|
873
|
-
def generate_rust_recommendations(analysis_results)
|
874
|
-
recommendations = []
|
875
|
-
|
876
|
-
if analysis_results["clippy_warnings"]&.> 15
|
877
|
-
recommendations << {
|
878
|
-
type: "quality",
|
879
|
-
priority: "medium",
|
880
|
-
message: "Clippy warnings detected",
|
881
|
-
action: "Run cargo clippy and address code quality issues"
|
882
|
-
}
|
883
|
-
end
|
884
|
-
|
885
|
-
if analysis_results["security_vulnerabilities"]&.> 0
|
886
|
-
recommendations << {
|
887
|
-
type: "security",
|
888
|
-
priority: "critical",
|
889
|
-
message: "Security vulnerabilities in dependencies",
|
890
|
-
action: "Run cargo audit and update vulnerable dependencies"
|
891
|
-
}
|
892
|
-
end
|
893
|
-
|
894
|
-
recommendations
|
895
|
-
end
|
896
|
-
end
|
897
|
-
end
|