aidp 0.3.0 → 0.7.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.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +191 -5
  3. data/lib/aidp/analysis/kb_inspector.rb +456 -0
  4. data/lib/aidp/analysis/seams.rb +188 -0
  5. data/lib/aidp/analysis/tree_sitter_grammar_loader.rb +493 -0
  6. data/lib/aidp/analysis/tree_sitter_scan.rb +703 -0
  7. data/lib/aidp/analyze/agent_personas.rb +1 -1
  8. data/lib/aidp/analyze/agent_tool_executor.rb +5 -11
  9. data/lib/aidp/analyze/data_retention_manager.rb +0 -5
  10. data/lib/aidp/analyze/database.rb +99 -82
  11. data/lib/aidp/analyze/error_handler.rb +12 -79
  12. data/lib/aidp/analyze/export_manager.rb +0 -7
  13. data/lib/aidp/analyze/focus_guidance.rb +2 -2
  14. data/lib/aidp/analyze/incremental_analyzer.rb +1 -11
  15. data/lib/aidp/analyze/large_analysis_progress.rb +0 -5
  16. data/lib/aidp/analyze/memory_manager.rb +34 -60
  17. data/lib/aidp/analyze/metrics_storage.rb +336 -0
  18. data/lib/aidp/analyze/parallel_processor.rb +0 -6
  19. data/lib/aidp/analyze/performance_optimizer.rb +0 -3
  20. data/lib/aidp/analyze/prioritizer.rb +2 -2
  21. data/lib/aidp/analyze/repository_chunker.rb +14 -21
  22. data/lib/aidp/analyze/ruby_maat_integration.rb +6 -102
  23. data/lib/aidp/analyze/runner.rb +107 -191
  24. data/lib/aidp/analyze/steps.rb +35 -30
  25. data/lib/aidp/analyze/storage.rb +233 -178
  26. data/lib/aidp/analyze/tool_configuration.rb +21 -36
  27. data/lib/aidp/cli/jobs_command.rb +489 -0
  28. data/lib/aidp/cli/terminal_io.rb +52 -0
  29. data/lib/aidp/cli.rb +160 -45
  30. data/lib/aidp/core_ext/class_attribute.rb +36 -0
  31. data/lib/aidp/database/pg_adapter.rb +148 -0
  32. data/lib/aidp/database_config.rb +69 -0
  33. data/lib/aidp/database_connection.rb +72 -0
  34. data/lib/aidp/execute/runner.rb +65 -92
  35. data/lib/aidp/execute/steps.rb +81 -82
  36. data/lib/aidp/job_manager.rb +41 -0
  37. data/lib/aidp/jobs/base_job.rb +45 -0
  38. data/lib/aidp/jobs/provider_execution_job.rb +83 -0
  39. data/lib/aidp/provider_manager.rb +25 -0
  40. data/lib/aidp/providers/agent_supervisor.rb +348 -0
  41. data/lib/aidp/providers/anthropic.rb +160 -3
  42. data/lib/aidp/providers/base.rb +153 -6
  43. data/lib/aidp/providers/cursor.rb +245 -43
  44. data/lib/aidp/providers/gemini.rb +164 -3
  45. data/lib/aidp/providers/supervised_base.rb +317 -0
  46. data/lib/aidp/providers/supervised_cursor.rb +22 -0
  47. data/lib/aidp/version.rb +1 -1
  48. data/lib/aidp.rb +31 -34
  49. data/templates/ANALYZE/01_REPOSITORY_ANALYSIS.md +4 -4
  50. data/templates/ANALYZE/06a_tree_sitter_scan.md +217 -0
  51. metadata +91 -36
@@ -0,0 +1,317 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "agent_supervisor"
4
+
5
+ module Aidp
6
+ module Providers
7
+ # Base class for providers that use the agent supervisor
8
+ class SupervisedBase
9
+ # Timeout constants are now configurable via environment variables for flexibility
10
+ DEFAULT_TIMEOUT = Integer(ENV.fetch("AIDP_DEFAULT_TIMEOUT", "300")) # 5 minutes for general operations
11
+ QUICK_MODE_TIMEOUT = Integer(ENV.fetch("AIDP_QUICK_MODE_TIMEOUT", "120")) # 2 minutes for testing
12
+ REPOSITORY_ANALYSIS_TIMEOUT = Integer(ENV.fetch("AIDP_REPOSITORY_ANALYSIS_TIMEOUT", "180")) # 3 minutes
13
+ ARCHITECTURE_ANALYSIS_TIMEOUT = Integer(ENV.fetch("AIDP_ARCHITECTURE_ANALYSIS_TIMEOUT", "600")) # 10 minutes
14
+ TEST_ANALYSIS_TIMEOUT = Integer(ENV.fetch("AIDP_TEST_ANALYSIS_TIMEOUT", "300")) # 5 minutes
15
+ FUNCTIONALITY_ANALYSIS_TIMEOUT = Integer(ENV.fetch("AIDP_FUNCTIONALITY_ANALYSIS_TIMEOUT", "600")) # 10 minutes
16
+ DOCUMENTATION_ANALYSIS_TIMEOUT = Integer(ENV.fetch("AIDP_DOCUMENTATION_ANALYSIS_TIMEOUT", "300")) # 5 minutes
17
+ STATIC_ANALYSIS_TIMEOUT = Integer(ENV.fetch("AIDP_STATIC_ANALYSIS_TIMEOUT", "450")) # 7.5 minutes
18
+ REFACTORING_RECOMMENDATIONS_TIMEOUT = Integer(ENV.fetch("AIDP_REFACTORING_RECOMMENDATIONS_TIMEOUT", "600")) # 10 minutes
19
+ ADAPTIVE_TIMEOUT_BUFFER = Float(ENV.fetch("AIDP_ADAPTIVE_TIMEOUT_BUFFER", "1.2")) # 20% buffer for adaptive timeouts
20
+ attr_reader :name, :last_execution_result, :metrics
21
+
22
+ def initialize
23
+ @last_execution_result = nil
24
+ @metrics = {
25
+ total_executions: 0,
26
+ successful_executions: 0,
27
+ timeout_count: 0,
28
+ failure_count: 0,
29
+ average_duration: 0.0,
30
+ total_duration: 0.0
31
+ }
32
+ @job_context = nil
33
+ end
34
+
35
+ # Abstract method - must be implemented by subclasses
36
+ def command
37
+ raise NotImplementedError, "#{self.class} must implement #command"
38
+ end
39
+
40
+ # Abstract method - must be implemented by subclasses
41
+ def provider_name
42
+ raise NotImplementedError, "#{self.class} must implement #provider_name"
43
+ end
44
+
45
+ # Set job context for background execution
46
+ def set_job_context(job_id:, execution_id:, job_manager:)
47
+ @job_context = {
48
+ job_id: job_id,
49
+ execution_id: execution_id,
50
+ job_manager: job_manager
51
+ }
52
+ end
53
+
54
+ # Execute with supervision and recovery
55
+ def send(prompt:, session: nil)
56
+ timeout_seconds = calculate_timeout
57
+ debug = ENV["AIDP_DEBUG"] == "1"
58
+
59
+ log_info("Executing with #{provider_name} provider (timeout: #{timeout_seconds}s)")
60
+
61
+ # Create supervisor
62
+ supervisor = AgentSupervisor.new(
63
+ command,
64
+ timeout_seconds: timeout_seconds,
65
+ debug: debug
66
+ )
67
+
68
+ begin
69
+ # Execute with supervision
70
+ result = supervisor.execute(prompt)
71
+
72
+ # Update metrics
73
+ update_metrics(supervisor, result)
74
+
75
+ # Store result for debugging
76
+ @last_execution_result = result
77
+
78
+ if result[:success]
79
+ log_info("#{provider_name} completed successfully in #{format_duration(result[:duration])}")
80
+ result[:output]
81
+ else
82
+ handle_execution_failure(result, supervisor)
83
+ end
84
+ rescue => e
85
+ log_error("#{provider_name} execution error: #{e.message}")
86
+
87
+ # Try to kill the process if it's still running
88
+ supervisor.kill! if supervisor.active?
89
+
90
+ raise
91
+ end
92
+ end
93
+
94
+ # Get execution statistics
95
+ def stats
96
+ @metrics.dup
97
+ end
98
+
99
+ # Reset statistics
100
+ def reset_stats!
101
+ @metrics = {
102
+ total_executions: 0,
103
+ successful_executions: 0,
104
+ timeout_count: 0,
105
+ failure_count: 0,
106
+ average_duration: 0.0,
107
+ total_duration: 0.0
108
+ }
109
+ end
110
+
111
+ # Check if provider supports activity monitoring
112
+ def supports_activity_monitoring?
113
+ true # Supervised providers always support activity monitoring
114
+ end
115
+
116
+ # Get activity summary for metrics (compatibility with old interface)
117
+ def activity_summary
118
+ return {} unless @last_execution_result
119
+
120
+ {
121
+ provider: provider_name,
122
+ step_name: ENV["AIDP_CURRENT_STEP"],
123
+ start_time: @last_execution_result[:start_time],
124
+ end_time: @last_execution_result[:end_time],
125
+ duration: @last_execution_result[:duration],
126
+ final_state: @last_execution_result[:state],
127
+ stuck_detected: false, # Supervisor handles this differently
128
+ output_count: @last_execution_result[:output_count] || 0
129
+ }
130
+ end
131
+
132
+ # Compatibility methods for old activity monitoring interface
133
+ def setup_activity_monitoring(step_name, callback = nil, timeout = nil)
134
+ # No-op for supervised providers - supervisor handles this
135
+ end
136
+
137
+ def record_activity(message = nil)
138
+ # No-op for supervised providers - supervisor handles this
139
+ end
140
+
141
+ def mark_completed
142
+ # No-op for supervised providers - supervisor handles this
143
+ end
144
+
145
+ def mark_failed(message = nil)
146
+ # No-op for supervised providers - supervisor handles this
147
+ end
148
+
149
+ private
150
+
151
+ def calculate_timeout
152
+ # Priority order for timeout calculation:
153
+ # 1. Quick mode (for testing)
154
+ # 2. Environment variable override
155
+ # 3. Adaptive timeout based on step type
156
+ # 4. Default timeout
157
+
158
+ if ENV["AIDP_QUICK_MODE"]
159
+ log_info("Quick mode enabled - #{QUICK_MODE_TIMEOUT / 60} minute timeout")
160
+ return QUICK_MODE_TIMEOUT
161
+ end
162
+
163
+ provider_timeout_var = "AIDP_#{provider_name.upcase}_TIMEOUT"
164
+ if ENV[provider_timeout_var]
165
+ return ENV[provider_timeout_var].to_i
166
+ end
167
+
168
+ # Adaptive timeout based on step type
169
+ step_timeout = get_adaptive_timeout
170
+ if step_timeout
171
+ log_info("Using adaptive timeout: #{step_timeout} seconds")
172
+ return step_timeout
173
+ end
174
+
175
+ # Default timeout for interactive use
176
+ log_info("Using default timeout: #{DEFAULT_TIMEOUT / 60} minutes")
177
+ DEFAULT_TIMEOUT
178
+ end
179
+
180
+ def get_adaptive_timeout
181
+ # Try to get timeout recommendations from metrics storage
182
+ begin
183
+ require_relative "../analyze/metrics_storage"
184
+ storage = Aidp::Analyze::MetricsStorage.new(Dir.pwd)
185
+ recommendations = storage.calculate_timeout_recommendations
186
+
187
+ # Get current step name from environment or context
188
+ step_name = ENV["AIDP_CURRENT_STEP"] || "unknown"
189
+
190
+ if recommendations[step_name]
191
+ recommended = recommendations[step_name][:recommended_timeout]
192
+ # Add buffer for safety
193
+ return (recommended * ADAPTIVE_TIMEOUT_BUFFER).ceil
194
+ end
195
+ rescue => e
196
+ log_warning("Could not get adaptive timeout: #{e.message}") if ENV["AIDP_DEBUG"]
197
+ end
198
+
199
+ # Fallback timeouts based on step type patterns
200
+ step_name = ENV["AIDP_CURRENT_STEP"] || ""
201
+
202
+ case step_name
203
+ when /REPOSITORY_ANALYSIS/
204
+ REPOSITORY_ANALYSIS_TIMEOUT
205
+ when /ARCHITECTURE_ANALYSIS/
206
+ ARCHITECTURE_ANALYSIS_TIMEOUT
207
+ when /TEST_ANALYSIS/
208
+ TEST_ANALYSIS_TIMEOUT
209
+ when /FUNCTIONALITY_ANALYSIS/
210
+ FUNCTIONALITY_ANALYSIS_TIMEOUT
211
+ when /DOCUMENTATION_ANALYSIS/
212
+ DOCUMENTATION_ANALYSIS_TIMEOUT
213
+ when /STATIC_ANALYSIS/
214
+ STATIC_ANALYSIS_TIMEOUT
215
+ when /REFACTORING_RECOMMENDATIONS/
216
+ REFACTORING_RECOMMENDATIONS_TIMEOUT
217
+ else
218
+ nil # Use default
219
+ end
220
+ end
221
+
222
+ def update_metrics(supervisor, result)
223
+ @metrics[:total_executions] += 1
224
+ @metrics[:total_duration] += supervisor.duration
225
+ @metrics[:average_duration] = @metrics[:total_duration] / @metrics[:total_executions]
226
+
227
+ case result[:state]
228
+ when :completed
229
+ @metrics[:successful_executions] += 1
230
+ when :timeout
231
+ @metrics[:timeout_count] += 1
232
+ when :failed, :killed
233
+ @metrics[:failure_count] += 1
234
+ end
235
+
236
+ # Log metrics update if in job context
237
+ if @job_context
238
+ @job_context[:job_manager].log_message(
239
+ @job_context[:job_id],
240
+ @job_context[:execution_id],
241
+ "Updated execution metrics",
242
+ "debug",
243
+ @metrics
244
+ )
245
+ end
246
+ end
247
+
248
+ def handle_execution_failure(result, supervisor)
249
+ case result[:reason]
250
+ when "user_aborted"
251
+ message = "#{provider_name} was aborted by user after #{format_duration(result[:duration])}"
252
+ log_error(message)
253
+ raise Interrupt, message
254
+ when "non_zero_exit"
255
+ error_msg = result[:error_output].empty? ? "Unknown error" : result[:error_output].strip
256
+ message = "#{provider_name} failed with exit code #{result[:exit_code]}: #{error_msg}"
257
+ log_error(message)
258
+ raise message
259
+ else
260
+ message = "#{provider_name} failed: #{result[:reason] || "Unknown error"}"
261
+ log_error(message)
262
+ raise message
263
+ end
264
+ end
265
+
266
+ def format_duration(seconds)
267
+ minutes = (seconds / 60).to_i
268
+ secs = (seconds % 60).to_i
269
+
270
+ if minutes > 0
271
+ "#{minutes}m #{secs}s"
272
+ else
273
+ "#{secs}s"
274
+ end
275
+ end
276
+
277
+ def log_info(message)
278
+ if @job_context
279
+ @job_context[:job_manager].log_message(
280
+ @job_context[:job_id],
281
+ @job_context[:execution_id],
282
+ message,
283
+ "info"
284
+ )
285
+ else
286
+ puts message
287
+ end
288
+ end
289
+
290
+ def log_warning(message)
291
+ if @job_context
292
+ @job_context[:job_manager].log_message(
293
+ @job_context[:job_id],
294
+ @job_context[:execution_id],
295
+ message,
296
+ "warning"
297
+ )
298
+ else
299
+ puts "⚠️ #{message}"
300
+ end
301
+ end
302
+
303
+ def log_error(message)
304
+ if @job_context
305
+ @job_context[:job_manager].log_message(
306
+ @job_context[:job_id],
307
+ @job_context[:execution_id],
308
+ message,
309
+ "error"
310
+ )
311
+ else
312
+ puts "❌ #{message}"
313
+ end
314
+ end
315
+ end
316
+ end
317
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "supervised_base"
4
+ require_relative "../util"
5
+
6
+ module Aidp
7
+ module Providers
8
+ class SupervisedCursor < SupervisedBase
9
+ def self.available?
10
+ !!Aidp::Util.which("cursor-agent")
11
+ end
12
+
13
+ def provider_name
14
+ "cursor"
15
+ end
16
+
17
+ def command
18
+ ["cursor-agent", "-p"]
19
+ end
20
+ end
21
+ end
22
+ end
data/lib/aidp/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Aidp
4
- VERSION = "0.3.0"
4
+ VERSION = "0.7.0"
5
5
  end
data/lib/aidp.rb CHANGED
@@ -1,53 +1,50 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # Core extensions
4
+ require "aidp/core_ext/class_attribute"
5
+
3
6
  # Shared modules
4
7
  require "aidp/version"
5
8
  require "aidp/config"
6
9
  require "aidp/workspace"
7
10
  require "aidp/util"
8
11
  require "aidp/cli"
12
+ require "aidp/cli/jobs_command"
9
13
  require "aidp/project_detector"
10
14
  require "aidp/sync"
15
+
16
+ # Database
17
+ require "aidp/database_connection"
18
+
19
+ # Job infrastructure
20
+ require "aidp/job_manager"
21
+ require "aidp/jobs/base_job"
22
+ require "aidp/jobs/provider_execution_job"
23
+
24
+ # Providers
11
25
  require "aidp/providers/base"
12
26
  require "aidp/providers/cursor"
13
27
  require "aidp/providers/anthropic"
14
28
  require "aidp/providers/gemini"
15
29
  require "aidp/providers/macos_ui"
30
+ require "aidp/provider_manager"
16
31
 
17
- # Execute mode modules
18
- require "aidp/execute/steps"
19
- require "aidp/execute/runner"
20
- require "aidp/execute/progress"
21
-
22
- # Analyze mode modules
23
- require "aidp/analyze/steps"
32
+ # Analyze mode
33
+ require "aidp/analyze/error_handler"
34
+ require "aidp/analyze/parallel_processor"
35
+ require "aidp/analyze/repository_chunker"
36
+ require "aidp/analyze/ruby_maat_integration"
24
37
  require "aidp/analyze/runner"
38
+ require "aidp/analyze/steps"
25
39
  require "aidp/analyze/progress"
26
- require "aidp/analyze/dependencies"
27
- require "aidp/analyze/storage"
28
- require "aidp/analyze/prioritizer"
29
- require "aidp/analyze/database"
30
- require "aidp/analyze/ruby_maat_integration"
31
- require "aidp/analyze/feature_analyzer"
32
- require "aidp/analyze/focus_guidance"
33
- require "aidp/analyze/agent_personas"
34
- require "aidp/analyze/agent_tool_executor"
35
- require "aidp/analyze/static_analysis_detector"
36
- require "aidp/analyze/tool_configuration"
37
- require "aidp/analyze/tool_modernization"
38
- require "aidp/analyze/language_analysis_strategies"
39
- require "aidp/analyze/report_generator"
40
- require "aidp/analyze/export_manager"
41
- require "aidp/analyze/incremental_analyzer"
42
- require "aidp/analyze/progress_visualizer"
43
- require "aidp/analyze/data_retention_manager"
44
- require "aidp/analyze/repository_chunker"
45
- require "aidp/analyze/parallel_processor"
46
- require "aidp/analyze/memory_manager"
47
- require "aidp/analyze/large_analysis_progress"
48
- require "aidp/analyze/performance_optimizer"
49
- require "aidp/analyze/error_handler"
50
40
 
51
- module Aidp
52
- class Error < StandardError; end
53
- end
41
+ # Tree-sitter analysis
42
+ require "aidp/analysis/tree_sitter_grammar_loader"
43
+ require "aidp/analysis/seams"
44
+ require "aidp/analysis/tree_sitter_scan"
45
+ require "aidp/analysis/kb_inspector"
46
+
47
+ # Execute mode
48
+ require "aidp/execute/steps"
49
+ require "aidp/execute/runner"
50
+ require "aidp/execute/progress"
@@ -13,7 +13,7 @@ You are a **Repository Analyst**, an expert in version control analysis and code
13
13
 
14
14
  ## Analysis Objectives
15
15
 
16
- 1. **Repository Mining**: Use Code Maat to analyze repository activity
16
+ 1. **Repository Mining**: Use ruby-maat gem to analyze repository activity
17
17
  2. **Churn Analysis**: Identify high-activity areas that may indicate technical debt
18
18
  3. **Coupling Analysis**: Understand dependencies between modules/components
19
19
  4. **Authorship Patterns**: Analyze code ownership and knowledge distribution
@@ -21,10 +21,10 @@ You are a **Repository Analyst**, an expert in version control analysis and code
21
21
 
22
22
  ## Required Analysis Steps
23
23
 
24
- ### 1. Code Maat Integration
24
+ ### 1. Ruby Maat Integration
25
25
 
26
- - Check if Docker is available for Code Maat analysis
27
- - Run Code Maat analysis for the repository
26
+ - Use the ruby-maat gem for repository analysis (no Docker required)
27
+ - Run ruby-maat analysis for the repository
28
28
  - Parse and interpret the results
29
29
 
30
30
  ### 2. Repository Activity Analysis
@@ -0,0 +1,217 @@
1
+ # Tree-sitter Static Analysis Template
2
+
3
+ You are a **Tree-sitter Static Analysis Expert**, specializing in advanced static code analysis using Tree-sitter parsers. Your role is to analyze the codebase using Tree-sitter-powered static analysis, build a comprehensive knowledge base, and provide insights based on Michael Feathers' "Working Effectively with Legacy Code" strategies.
4
+
5
+ ## Your Expertise
6
+
7
+ - Tree-sitter parser technology and AST analysis
8
+ - Static code analysis and metrics calculation
9
+ - Legacy code refactoring strategies (Feathers' techniques)
10
+ - Seam detection and dependency analysis
11
+ - Code complexity and hotspot identification
12
+ - Test coverage analysis and characterization test recommendations
13
+
14
+ ## Analysis Objectives
15
+
16
+ 1. **Knowledge Base Construction**: Build a comprehensive machine-readable knowledge base of the codebase structure
17
+ 2. **Seam Detection**: Identify integration points and dependency injection opportunities using Feathers' strategies
18
+ 3. **Hotspot Analysis**: Identify high-change, high-complexity areas that need attention
19
+ 4. **Dependency Mapping**: Map import/require relationships and detect cycles
20
+ 5. **Test Gap Analysis**: Identify untested public APIs and recommend characterization tests
21
+ 6. **Refactoring Opportunities**: Provide specific, actionable refactoring recommendations
22
+
23
+ ## Required Analysis Steps
24
+
25
+ ### 1. Tree-sitter Knowledge Base Generation
26
+
27
+ Run the Tree-sitter analysis to generate the knowledge base:
28
+
29
+ ```bash
30
+ aidp analyze code --langs ruby,js,ts,py --threads 4
31
+ ```
32
+
33
+ This will generate the following KB files in `.aidp/kb/`:
34
+
35
+ - `symbols.json` - Classes, modules, methods with metadata
36
+ - `imports.json` - Require/import statements and dependencies
37
+ - `calls.json` - Method call relationships
38
+ - `metrics.json` - Complexity and size metrics
39
+ - `seams.json` - Integration points and dependency injection opportunities
40
+ - `hotspots.json` - High-change, high-complexity areas
41
+ - `tests.json` - Test coverage mapping
42
+ - `cycles.json` - Import/dependency cycles
43
+
44
+ ### 2. Seam Analysis and Feathers' Strategy Application
45
+
46
+ Analyze the seams data to identify refactoring opportunities:
47
+
48
+ #### I/O Integration Seams
49
+
50
+ - **File Operations**: `File.*`, `IO.*`, `Dir.*` calls
51
+ - **Network Operations**: `Net::HTTP.*`, `Socket.*` calls
52
+ - **System Operations**: `Kernel.system`, `Process.*` calls
53
+ - **Database Operations**: `ActiveRecord.*`, `Sequel.*` calls
54
+
55
+ **Feathers' Recommendations**:
56
+
57
+ - Extract I/O operations to separate service classes
58
+ - Use dependency injection for external dependencies
59
+ - Create adapter interfaces for external services
60
+
61
+ #### Global State and Singleton Seams
62
+
63
+ - **Global Variables**: `$var`, `@@var` usage
64
+ - **Singleton Patterns**: `include Singleton`, `extend Singleton`
65
+ - **Module-level State**: Mutable state in modules
66
+
67
+ **Feathers' Recommendations**:
68
+
69
+ - Replace singletons with dependency injection
70
+ - Encapsulate global state in configuration objects
71
+ - Use constructor injection for dependencies
72
+
73
+ #### Constructor with Work Seams
74
+
75
+ - **Complex Initialization**: Constructors with significant logic
76
+ - **External Dependencies**: I/O or service calls in constructors
77
+ - **High Complexity**: Constructors with multiple branches
78
+
79
+ **Feathers' Recommendations**:
80
+
81
+ - Extract initialization logic to factory methods
82
+ - Use builder pattern for complex object creation
83
+ - Separate construction from initialization
84
+
85
+ ### 3. Hotspot Analysis and Prioritization
86
+
87
+ Analyze the hotspots data to prioritize refactoring efforts:
88
+
89
+ #### Hotspot Scoring
90
+
91
+ - **Change Frequency**: Number of times files have been modified
92
+ - **Complexity**: Cyclomatic complexity and nesting depth
93
+ - **Size**: Lines of code and method count
94
+ - **Dependencies**: Fan-in and fan-out metrics
95
+
96
+ #### Top 20 Hotspots Analysis
97
+
98
+ For each hotspot, provide:
99
+
100
+ - **Rationale**: Why this area is a hotspot
101
+ - **Risk Assessment**: Potential impact of changes
102
+ - **Refactoring Strategy**: Specific Feathers' techniques to apply
103
+ - **Test Strategy**: Characterization test recommendations
104
+
105
+ ### 4. Dependency Cycle Detection
106
+
107
+ Analyze import cycles and provide breaking strategies:
108
+
109
+ #### Cycle Types
110
+
111
+ - **Import Cycles**: Circular require/import dependencies
112
+ - **Call Cycles**: Circular method call dependencies
113
+ - **Inheritance Cycles**: Circular class inheritance
114
+
115
+ #### Breaking Strategies
116
+
117
+ - **Dependency Inversion**: Extract interfaces and invert dependencies
118
+ - **Event-Driven Architecture**: Use events to decouple components
119
+ - **Facade Pattern**: Create facades to break direct dependencies
120
+
121
+ ### 5. Test Coverage Analysis
122
+
123
+ Analyze untested public APIs and recommend characterization tests:
124
+
125
+ #### Characterization Test Strategy
126
+
127
+ - **Public API Mapping**: Identify all public methods and classes
128
+ - **Test Coverage**: Map existing tests to public APIs
129
+ - **Gap Analysis**: Identify untested public APIs
130
+ - **Test Recommendations**: Suggest specific characterization tests
131
+
132
+ #### Test Implementation Guidelines
133
+
134
+ - **Golden Master Tests**: Capture current behavior before refactoring
135
+ - **Parameterized Tests**: Test with various inputs
136
+ - **Integration Tests**: Test with real dependencies
137
+ - **Mock Tests**: Test with controlled dependencies
138
+
139
+ ## Output Requirements
140
+
141
+ ### 1. Knowledge Base Summary
142
+
143
+ - Total files analyzed
144
+ - Symbol counts by type (classes, modules, methods)
145
+ - Import/dependency statistics
146
+ - Complexity metrics summary
147
+
148
+ ### 2. Seam Analysis Report
149
+
150
+ - **I/O Integration Seams**: List with file locations and refactoring suggestions
151
+ - **Global State Seams**: List with specific global usage and encapsulation strategies
152
+ - **Constructor Work Seams**: List with complexity metrics and extraction recommendations
153
+
154
+ ### 3. Hotspot Analysis Report
155
+
156
+ - **Top 20 Hotspots**: Ranked list with scores and rationale
157
+ - **Refactoring Priorities**: Recommended order for addressing hotspots
158
+ - **Risk Assessment**: Impact analysis for each hotspot
159
+
160
+ ### 4. Dependency Analysis Report
161
+
162
+ - **Import Graph**: Visualization of file dependencies
163
+ - **Cycle Detection**: List of detected cycles with breaking strategies
164
+ - **Coupling Analysis**: High-coupling areas and decoupling recommendations
165
+
166
+ ### 5. Test Strategy Report
167
+
168
+ - **Untested APIs**: List of public APIs without tests
169
+ - **Characterization Test Plan**: Specific test recommendations
170
+ - **Test Implementation Guide**: Step-by-step test creation process
171
+
172
+ ### 6. Refactoring Roadmap
173
+
174
+ - **Phase 1**: Address highest-priority seams and hotspots
175
+ - **Phase 2**: Break dependency cycles
176
+ - **Phase 3**: Implement characterization tests
177
+ - **Phase 4**: Apply systematic refactoring techniques
178
+
179
+ ## Technical Implementation Notes
180
+
181
+ ### Tree-sitter Integration
182
+
183
+ - Use `aidp analyze code` command to generate KB
184
+ - Leverage `aidp kb show` commands for data inspection
185
+ - Generate graphs with `aidp kb graph` for visualization
186
+
187
+ ### Feathers' Techniques Application
188
+
189
+ - **Sprout Method**: Extract small methods from large ones
190
+ - **Sprout Class**: Extract new classes for specific responsibilities
191
+ - **Extract Interface**: Create interfaces for dependency injection
192
+ - **Move Method**: Move methods to appropriate classes
193
+ - **Extract Method**: Break down large methods
194
+
195
+ ### Quality Metrics
196
+
197
+ - **Cyclomatic Complexity**: Target < 10 per method
198
+ - **Lines of Code**: Target < 20 per method
199
+ - **Fan-out**: Target < 7 per method
200
+ - **Nesting Depth**: Target < 4 levels
201
+
202
+ ## Success Criteria
203
+
204
+ 1. **Complete KB Generation**: All source files parsed and analyzed
205
+ 2. **Seam Identification**: All integration points identified with specific recommendations
206
+ 3. **Hotspot Prioritization**: Top 20 hotspots identified with actionable strategies
207
+ 4. **Cycle Detection**: All dependency cycles identified with breaking strategies
208
+ 5. **Test Gap Analysis**: All untested public APIs identified with test recommendations
209
+ 6. **Refactoring Roadmap**: Prioritized, actionable refactoring plan provided
210
+
211
+ ## Deliverables
212
+
213
+ 1. **Knowledge Base Files**: Complete `.aidp/kb/` directory with all JSON files
214
+ 2. **Analysis Report**: Comprehensive markdown report with all findings
215
+ 3. **Visualization Files**: Graph files for dependency visualization
216
+ 4. **Refactoring Plan**: Detailed, prioritized refactoring roadmap
217
+ 5. **Test Strategy**: Specific characterization test recommendations