code_healer 0.1.18 → 0.1.20

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a88b89f7bf244566728987fa8a20b3db2d6ee1e6b0a249956c06907441eb5a13
4
- data.tar.gz: 349d7d045fa176d54454d7d42ae354369001eddeee2764cedf9f82c62bf4a49f
3
+ metadata.gz: c54944cc1cad8a6a188bbf5b5a50a216b0719046339b59eccc12447aff916582
4
+ data.tar.gz: f190123758f3d4b73a7c7f53ccf8b275347819e5a7b60008085a62a79c239751
5
5
  SHA512:
6
- metadata.gz: 50dd2dc5f4af17274e9854ea43581a794b55d88d50e2fbc2ffbde5c450dfadc9801929454d4f0f4f34d523c16bb7921f5c060c273d43448f300f8ab3d25e2ad5
7
- data.tar.gz: b7f287a9b342cd8ad8e110c4eb480ac7c7f1dbc2b8fc753b272e32ff767eabe8d947b1c790c65cbe9eb13fdac2701aad91ff23ed2c228b53f7729cefbbe36a84
6
+ metadata.gz: 050def7293a77fb6204fb51f9fc5640caf036903b765c34be1b9c9163300e1034ae880ad3855d92480df40fe813c4590df6c1a86b812d80c9e541b8d7df8d9ef
7
+ data.tar.gz: 1d2874cf1817fdf4825d189f666c5fd9e9a300966892118dd79e254a4b528251d8cb85e587525735a3749f07ad75711e1ac1cdd444f30ba0c76852d4d4f62504
data/CHANGELOG.md CHANGED
@@ -5,7 +5,35 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
- ## [Unreleased]
8
+ ## [0.1.20] - 2025-08-27
9
+
10
+ ### Added
11
+ - **Confluence MCP Integration**: Added direct Confluence MCP tools for business context fetching (optional usage)
12
+ - **Flexible MCP Usage**: Enhanced prompts to optionally use Confluence MCP tools when available
13
+ - **Non-interactive MCP**: Fixed Claude Terminal flags to avoid manual approval prompts
14
+ - **Business Context Strategy**: Added `confluence_only` strategy for focused Confluence documentation usage
15
+
16
+ ### Fixed
17
+ - **MCP Tool Access**: Removed restrictive tool flags that blocked MCP tool usage
18
+ - **Debug Logging**: Cleaned up unnecessary MCP debugging logs from initialization and job startup
19
+ - **Command Optimization**: Fixed Claude Terminal command flags for proper MCP integration
20
+
21
+ ### Changed
22
+ - **Prompt Strategy**: Updated business context prompts to optionally use MCP tools when available
23
+ - **Initialization**: Streamlined gem startup without MCP availability checks
24
+ - **Dependencies**: Maintained `httparty` for MCP API integration while removing debug overhead
25
+
26
+ ## [0.1.19] - 2025-08-21
27
+
28
+ ### Fixed
29
+ - **Critical Git Operations Duplication**: Fixed duplicate Git operations between evolution handler and workspace manager.
30
+ - **Branch Detection**: Fixed automatic detection of repository's default branch (master vs main).
31
+ - **Configuration Loading**: Fixed pr_target_branch configuration loading from both git section and root level.
32
+ - **Workspace Isolation**: Improved Git operations to occur only in isolated workspace, preventing conflicts.
33
+
34
+ ### Changed
35
+ - **Evolution Handler**: Removed duplicate Git operations to prevent conflicts with workspace manager.
36
+ - **Setup Script**: Enhanced with automatic branch detection and better configuration structure.
9
37
 
10
38
  ## [0.1.18] - 2025-08-21
11
39
 
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Start Claude Terminal with code_healer_session for MCP tools access
4
+ # This session will be used by CodeHealer for healing jobs
5
+
6
+ puts "🚀 Starting Claude Terminal with code_healer_session for MCP tools..."
7
+ puts "This session will be used by CodeHealer for healing jobs with Jira/Confluence access"
8
+ puts ""
9
+ puts "Session name: code_healer_session"
10
+ puts "MCP tools: Jira, Confluence, and other Atlassian integrations"
11
+ puts ""
12
+ puts "Keep this terminal open while running healing jobs!"
13
+ puts "=" * 60
14
+
15
+ # Start Claude Terminal with the session
16
+ exec "claude --session code_healer_session"
data/code_healer.gemspec CHANGED
@@ -60,6 +60,8 @@ Gem::Specification.new do |spec|
60
60
  spec.add_runtime_dependency 'activesupport', '>= 6.0.0'
61
61
  spec.add_runtime_dependency 'actionpack', '>= 6.0.0'
62
62
  spec.add_runtime_dependency 'activemodel', '>= 6.0.0'
63
+ spec.add_runtime_dependency 'httparty', '~> 0.21.0', '>= 0.21.0'
64
+
63
65
 
64
66
  # Development dependencies
65
67
  spec.add_development_dependency "bundler", ">= 2.0.0"
@@ -49,7 +49,39 @@ claude_code:
49
49
  business_context:
50
50
  enabled: true
51
51
 
52
- # Define business rules for specific classes
52
+ # Business Context Strategy
53
+ strategy: "jira_mcp" # Options: "jira_mcp", "markdown", "hybrid"
54
+
55
+ # Jira MCP Configuration (when strategy is "jira_mcp" or "hybrid")
56
+ jira_mcp:
57
+ enabled: true
58
+ project_key: "DGTL" # Your Jira project key
59
+ search_tickets_on_error: true
60
+ include_business_rules: true
61
+ system_prompt: |
62
+ When fixing code, ALWAYS check Jira MCP for business context:
63
+ 1. Search for tickets about the class/method you're fixing
64
+ 2. Use Jira requirements to ensure your fix follows business rules
65
+ 3. Reference specific Jira tickets in your explanation
66
+ 4. Make sure fixes align with business requirements
67
+
68
+ # Markdown Configuration (when strategy is "markdown" or "hybrid")
69
+ markdown:
70
+ enabled: true
71
+ search_paths:
72
+ - "docs/business_rules.md"
73
+ - "docs/requirements.md"
74
+ - "business_requirements/"
75
+ include_patterns:
76
+ - "*.md"
77
+ - "*.txt"
78
+
79
+ # Hybrid Configuration (when strategy is "hybrid")
80
+ hybrid:
81
+ priority: ["jira_mcp", "markdown"] # Which source to check first
82
+ combine_results: true # Merge results from both sources
83
+
84
+ # Define business rules for specific classes (fallback when MCP unavailable)
53
85
  User:
54
86
  domain: "User Management"
55
87
  key_rules:
@@ -177,8 +177,44 @@ module CodeHealer
177
177
  end
178
178
 
179
179
  def build_claude_code_prompt(error, class_name, method_name, file_path)
180
- # Load business context from markdown files
181
- business_context = load_business_context_from_markdown_simple
180
+ # Get business context based on configured strategy
181
+ business_context = case CodeHealer::ConfigManager.business_context_strategy
182
+ when 'confluence_only'
183
+ "## Business Context Instructions:\n" \
184
+ "OPTIONAL: You can use Confluence MCP tools to enhance business context if available.\n\n" \
185
+ "1. If Confluence MCP is available:\n" \
186
+ " - Search for PRDs/specs related to '#{class_name}' / '#{method_name}'.\n" \
187
+ " - Query terms: '#{class_name}', '#{method_name}', 'business rules', 'validation patterns'.\n" \
188
+ " - Apply any found documentation to your fix.\n\n" \
189
+ "2. If Confluence MCP is not available:\n" \
190
+ " - Proceed with standard business logic and error handling practices.\n" \
191
+ " - Use common validation patterns and best practices.\n\n" \
192
+ "Note: MCP usage is optional - proceed with or without it."
193
+ when 'claude_atlassian_mcp'
194
+ "## Business Context Instructions:\n" \
195
+ "OPTIONAL: You can use Atlassian MCP tools to enhance business context if available.\n\n" \
196
+ "1. **If Jira MCP is available:**\n" \
197
+ " - Search for tickets related to '#{class_name}' or '#{method_name}'\n" \
198
+ " - Look for bug reports, requirements, or business rules\n" \
199
+ " - Apply any found ticket context to your fix\n\n" \
200
+ "2. **If Confluence MCP is available:**\n" \
201
+ " - Search for PRDs, technical specs, or business process docs\n" \
202
+ " - Look for domain-specific business rules related to '#{class_name}'\n" \
203
+ " - Apply any found documentation to your fix\n\n" \
204
+ "3. **If MCP tools are not available:**\n" \
205
+ " - Proceed with standard business logic and error handling practices\n" \
206
+ " - Use common validation patterns and best practices\n\n" \
207
+ "Note: MCP usage is optional - proceed with or without it."
208
+ when 'jira_mcp'
209
+ # Use Jira MCP context
210
+ get_jira_business_context(class_name)
211
+ when 'markdown'
212
+ # Use markdown files
213
+ load_business_context_from_markdown_simple
214
+ else
215
+ # Default fallback
216
+ load_business_context_from_markdown_simple
217
+ end
182
218
 
183
219
  prompt = <<~PROMPT
184
220
  I have a Ruby on Rails application with an error that needs fixing.
@@ -195,7 +231,7 @@ module CodeHealer
195
231
  #{error.backtrace&.join("\n") || "No backtrace available"}
196
232
  ```
197
233
 
198
- ## Business Context (from requirements):
234
+ ## Business Context:
199
235
  #{business_context}
200
236
 
201
237
  ## Instructions:
@@ -262,6 +298,24 @@ module CodeHealer
262
298
  prompt.strip
263
299
  end
264
300
 
301
+ def get_jira_business_context(class_name)
302
+ # Get Jira business context using MCP tools
303
+ begin
304
+ # This would integrate with Jira MCP tools
305
+ # For now, return instructions to use Jira MCP
306
+ "## Jira Business Context Instructions:\n" \
307
+ "Use Jira MCP tools to fetch business context:\n" \
308
+ "1. Search for tickets related to '#{class_name}'\n" \
309
+ "2. Look for business requirements and rules\n" \
310
+ "3. Apply the context to your fix\n" \
311
+ "4. Reference specific Jira tickets in your explanation"
312
+ rescue => e
313
+ "## Jira Business Context:\n" \
314
+ "Unable to fetch Jira context: #{e.message}\n" \
315
+ "Please use Jira MCP tools manually to get business context."
316
+ end
317
+ end
318
+
265
319
  private
266
320
 
267
321
  def load_business_context_from_markdown_simple
@@ -31,8 +31,9 @@ module CodeHealer
31
31
  reload_modified_files
32
32
 
33
33
  # 🚀 Trigger Git operations (commit, push, PR creation)
34
- puts "🔄 Starting Git operations..."
35
- trigger_git_operations(error, class_name, method_name, file_path)
34
+ # Note: Git operations are now handled by the isolated workspace manager
35
+ # to prevent duplication and ensure proper isolation
36
+ puts "🔄 Git operations will be handled by isolated workspace manager..."
36
37
 
37
38
  return true
38
39
  else
@@ -109,31 +110,30 @@ module CodeHealer
109
110
  def build_claude_command(prompt, config)
110
111
  # Escape prompt for shell
111
112
  escaped_prompt = prompt.gsub("'", "'\"'\"'")
112
-
113
- # Build command template
113
+
114
+ # Build command template for MCP tools access
114
115
  command_template = config['command_template'] || "claude --code '{prompt}'"
115
-
116
+
116
117
  # Replace placeholder
117
118
  command = command_template.gsub('{prompt}', escaped_prompt)
118
-
119
- # Add additional options if configured
119
+
120
+ # [rest of your existing code remains the same]
120
121
  if config['include_tests'] && !CodeHealer::ConfigManager.demo_mode?
121
122
  command += " --append-system-prompt 'Include tests when fixing the code'"
122
123
  else
123
124
  command += " --append-system-prompt 'Do NOT create or modify tests'"
124
125
  end
125
-
126
+
126
127
  if config['max_file_changes']
127
128
  command += " --append-system-prompt 'Limit changes to #{config['max_file_changes']} files maximum'"
128
129
  end
129
-
130
- # Add file editing permissions
130
+
131
131
  command += " --permission-mode acceptEdits --allowedTools Edit"
132
-
133
- # Add current directory access but advise not to scan everything
132
+ command += " --append-system-prompt 'Optionally use Confluence MCP tools if available to enhance business context, but proceed regardless.'"
134
133
  command += " --add-dir . --append-system-prompt 'Do not scan the whole repo; open only files explicitly referenced.'"
135
-
136
- command
134
+
135
+ # Return combined command
136
+ mcp_setup + command
137
137
  end
138
138
 
139
139
  def reload_modified_files
@@ -193,6 +193,8 @@ module CodeHealer
193
193
  puts "📝 Evolution attempt logged to #{log_file}"
194
194
  end
195
195
 
196
+
197
+
196
198
  def trigger_git_operations(error, class_name, method_name, file_path)
197
199
  puts "🚀 Triggering Git operations for Claude Code evolution..."
198
200
 
@@ -107,6 +107,57 @@ module CodeHealer
107
107
  config['business_context'] || {}
108
108
  end
109
109
 
110
+ # Business Context Strategy Configuration
111
+ def business_context_strategy
112
+ business_context_settings['strategy'] || 'markdown'
113
+ end
114
+
115
+ def use_jira_mcp?
116
+ business_context_strategy == 'jira_mcp' || business_context_strategy == 'hybrid'
117
+ end
118
+
119
+ def use_markdown_context?
120
+ business_context_strategy == 'markdown' || business_context_strategy == 'hybrid'
121
+ end
122
+
123
+ def use_hybrid_context?
124
+ business_context_strategy == 'hybrid'
125
+ end
126
+
127
+ def jira_mcp_settings
128
+ business_context_settings['jira_mcp'] || {}
129
+ end
130
+
131
+ def markdown_settings
132
+ business_context_settings['markdown'] || {}
133
+ end
134
+
135
+ def hybrid_settings
136
+ business_context_settings['hybrid'] || {}
137
+ end
138
+
139
+ def jira_mcp_enabled?
140
+ use_jira_mcp? && jira_mcp_settings['enabled'] != false
141
+ end
142
+
143
+ def markdown_enabled?
144
+ use_markdown_context? && markdown_settings['enabled'] != false
145
+ end
146
+
147
+ def jira_mcp_system_prompt
148
+ jira_mcp_settings['system_prompt'] || default_jira_mcp_prompt
149
+ end
150
+
151
+ def default_jira_mcp_prompt
152
+ <<~PROMPT
153
+ When fixing code, ALWAYS check Jira MCP for business context:
154
+ 1. Search for tickets about the class/method you're fixing
155
+ 2. Use Jira requirements to ensure your fix follows business rules
156
+ 3. Reference specific Jira tickets in your explanation
157
+ 4. Make sure fixes align with business requirements
158
+ PROMPT
159
+ end
160
+
110
161
  # API Configuration
111
162
  def api_settings
112
163
  config['api'] || {}
@@ -189,7 +240,8 @@ module CodeHealer
189
240
  end
190
241
 
191
242
  def pr_target_branch
192
- git_settings['pr_target_branch'] || 'main'
243
+ # Check both git section and root level for backward compatibility
244
+ git_settings['pr_target_branch'] || config['pr_target_branch'] || 'main'
193
245
  end
194
246
 
195
247
  def commit_message_template
@@ -25,7 +25,7 @@ class EvolutionJob
25
25
  healing_branch = CodeHealer::HealingWorkspaceManager.create_healing_branch(
26
26
  Rails.root.to_s,
27
27
  workspace_path,
28
- CodeHealer::ConfigManager.git_settings['pr_target_branch'] || 'main'
28
+ CodeHealer::ConfigManager.pr_target_branch
29
29
  )
30
30
 
31
31
  if healing_branch
@@ -1,4 +1,5 @@
1
1
  require 'sidekiq'
2
+ require 'open3'
2
3
 
3
4
  module CodeHealer
4
5
  class HealingJob
@@ -9,6 +10,8 @@ module CodeHealer
9
10
  def perform(*args)
10
11
  puts "🚀 [HEALING_JOB] Starting job with args: #{args.inspect}"
11
12
 
13
+
14
+
12
15
  # Support both legacy and new invocation styles
13
16
  error, class_name, method_name, evolution_method, backtrace = parse_args(args)
14
17
 
@@ -68,7 +71,7 @@ module CodeHealer
68
71
  healing_branch = CodeHealer::HealingWorkspaceManager.create_healing_branch(
69
72
  Rails.root.to_s,
70
73
  workspace_path,
71
- CodeHealer::ConfigManager.git_settings['pr_target_branch'] || 'main'
74
+ CodeHealer::ConfigManager.pr_target_branch
72
75
  )
73
76
  git_time_ms = ((Process.clock_gettime(Process::CLOCK_MONOTONIC) - git_started_at) * 1000).round
74
77
 
@@ -127,6 +130,47 @@ module CodeHealer
127
130
  end
128
131
 
129
132
  private
133
+
134
+ def log_mcp_tools_availability
135
+ puts "🔍 [HEALING_JOB] Checking MCP tools availability..."
136
+
137
+ begin
138
+ # Check if Claude has MCP tools available
139
+ mcp_check_command = "claude --print 'List all available MCP tools' --output-format text"
140
+ stdout, stderr, status = Open3.capture3(mcp_check_command)
141
+
142
+ if status.success?
143
+ puts "✅ [HEALING_JOB] Claude Terminal is available"
144
+
145
+ # Extract MCP tools from output
146
+ if stdout.include?("MCP tools available") || stdout.include?("mcp__")
147
+ puts "🔧 [HEALING_JOB] MCP tools detected in Claude Terminal"
148
+
149
+ # Log specific MCP tools if found
150
+ if stdout.include?("mcp__atlassian")
151
+ puts " - Atlassian MCP tools: Available"
152
+ puts " - Jira integration: Available"
153
+ puts " - Confluence integration: Available"
154
+ end
155
+
156
+ if stdout.include?("mcp__")
157
+ puts " - Other MCP tools: Available"
158
+ end
159
+ else
160
+ puts "⚠️ [HEALING_JOB] No MCP tools detected in Claude Terminal"
161
+ puts "💡 Make sure Claude Terminal has MCP tools configured"
162
+ end
163
+ else
164
+ puts "❌ [HEALING_JOB] Claude Terminal is not available"
165
+ puts "💡 Make sure Claude Terminal is installed and accessible"
166
+ end
167
+ rescue => e
168
+ puts "⚠️ [HEALING_JOB] Could not check MCP tools: #{e.message}"
169
+ puts "💡 Make sure Claude Terminal is properly installed"
170
+ end
171
+
172
+ puts "🔍 [HEALING_JOB] MCP tools check complete"
173
+ end
130
174
 
131
175
  def parse_args(args)
132
176
  # Formats supported:
@@ -18,7 +18,9 @@ module CodeHealer
18
18
  tools: [
19
19
  ErrorAnalysisTool,
20
20
  CodeFixTool,
21
- ContextAnalysisTool
21
+ ContextAnalysisTool,
22
+ JIRAIntegrationTool, # Add Jira integration tool
23
+ ConfluenceIntegrationTool # Add Confluence integration tool
22
24
  ],
23
25
  server_context: {
24
26
  codebase_context: @codebase_context,
@@ -237,13 +239,231 @@ module CodeHealer
237
239
  end
238
240
 
239
241
  def get_business_context(class_name)
240
- {
242
+ base_context = {
241
243
  domain: determine_business_domain(class_name),
242
244
  criticality: assess_business_criticality(class_name),
243
245
  regulatory_requirements: identify_regulatory_requirements(class_name),
244
246
  sla_requirements: get_sla_requirements(class_name),
245
247
  user_impact: assess_user_impact(class_name)
246
248
  }
249
+
250
+ # Get business context based on configured sources
251
+ business_context = get_configured_business_context(class_name)
252
+ base_context.merge!(business_context)
253
+
254
+ base_context
255
+ end
256
+
257
+ def get_configured_business_context(class_name)
258
+ context = {}
259
+
260
+ # Get business context based on configured strategy
261
+ case CodeHealer::ConfigManager.business_context_strategy
262
+ when 'jira_mcp'
263
+ if CodeHealer::ConfigManager.jira_mcp_enabled?
264
+ context[:strategy] = 'jira_mcp'
265
+ context[:instructions] = CodeHealer::ConfigManager.jira_mcp_system_prompt
266
+ context[:project_key] = CodeHealer::ConfigManager.jira_mcp_settings['project_key']
267
+ end
268
+ when 'markdown'
269
+ if CodeHealer::ConfigManager.markdown_enabled?
270
+ markdown_context = get_markdown_business_context(class_name)
271
+ context[:strategy] = 'markdown'
272
+ context[:markdown_context] = markdown_context
273
+ end
274
+ when 'hybrid'
275
+ # Combine both approaches
276
+ context[:strategy] = 'hybrid'
277
+ if CodeHealer::ConfigManager.jira_mcp_enabled?
278
+ context[:jira_mcp_instructions] = CodeHealer::ConfigManager.jira_mcp_system_prompt
279
+ context[:project_key] = CodeHealer::ConfigManager.jira_mcp_settings['project_key']
280
+ end
281
+ if CodeHealer::ConfigManager.markdown_enabled?
282
+ markdown_context = get_markdown_business_context(class_name)
283
+ context[:markdown_context] = markdown_context
284
+ end
285
+ end
286
+
287
+ context
288
+ end
289
+
290
+ def get_jira_business_context(class_name)
291
+ return {} unless defined?(JIRAIntegrationTool)
292
+
293
+ begin
294
+ # Use MCP tool to get Jira context
295
+ result = JIRAIntegrationTool.call(
296
+ action: "search_tickets",
297
+ search_query: "#{class_name} business rules requirements",
298
+ project_key: get_default_jira_project_key,
299
+ server_context: {}
300
+ )
301
+
302
+ if result && result.content.any?
303
+ data = JSON.parse(result.content.first[:text])
304
+ return {} if data['error']
305
+
306
+ # Extract business context from Jira tickets
307
+ {
308
+ related_tickets: data['tickets']&.first(3) || [],
309
+ business_rules: extract_business_rules_from_tickets(data['tickets']),
310
+ requirements: extract_requirements_from_tickets(data['tickets'])
311
+ }
312
+ end
313
+ rescue => e
314
+ puts "⚠️ Failed to get Jira business context: #{e.message}"
315
+ end
316
+
317
+ {}
318
+ end
319
+
320
+ def get_default_jira_project_key
321
+ # Extract from environment or use default
322
+ ENV['JIRA_PROJECT_KEY'] || 'DGTL'
323
+ end
324
+
325
+ def extract_business_rules_from_tickets(tickets)
326
+ return [] unless tickets
327
+
328
+ tickets.flat_map do |ticket|
329
+ # Extract business rules from ticket summary, description, labels
330
+ rules = []
331
+ rules << ticket['summary'] if ticket['summary']&.include?('rule')
332
+ rules << ticket['summary'] if ticket['summary']&.include?('policy')
333
+ rules << ticket['summary'] if ticket['summary']&.include?('requirement')
334
+ rules
335
+ end.compact.uniq
336
+ end
337
+
338
+ def extract_requirements_from_tickets(tickets)
339
+ return [] unless tickets
340
+
341
+ tickets.flat_map do |ticket|
342
+ # Extract business context from ticket content
343
+ requirements = []
344
+ requirements << ticket['summary'] if ticket['summary']&.include?('requirement')
345
+ requirements << ticket['summary'] if ticket['summary']&.include?('should')
346
+ requirements << ticket['summary'] if ticket['summary']&.include?('need')
347
+ requirements
348
+ end.compact.uniq
349
+ end
350
+
351
+ # Public method for Claude Terminal to access Confluence business context
352
+ def get_confluence_business_context(class_name)
353
+ return {} unless defined?(ConfluenceIntegrationTool)
354
+
355
+ begin
356
+ # Use MCP tool to get Confluence context
357
+ result = ConfluenceIntegrationTool.call(
358
+ action: "search_documents",
359
+ search_query: "#{class_name} PRD requirements business rules",
360
+ space_key: get_default_confluence_space_key,
361
+ server_context: {}
362
+ )
363
+
364
+ if result && result.content.any?
365
+ data = JSON.parse(result.content.first[:text])
366
+ return {} if data['error']
367
+
368
+ # Extract business context from Confluence documents
369
+ {
370
+ related_documents: data['documents']&.first(3) || [],
371
+ prd_content: extract_prd_content(data['documents']),
372
+ business_processes: extract_business_processes(data['documents'])
373
+ }
374
+ end
375
+ rescue => e
376
+ puts "⚠️ Failed to get Confluence business context: #{e.message}"
377
+ end
378
+
379
+ {}
380
+ end
381
+
382
+ # Public method for Claude Terminal to get Confluence space key
383
+ def get_default_confluence_space_key
384
+ # Extract from environment or use default
385
+ ENV['CONFLUENCE_SPACE_KEY'] || 'DGTL'
386
+ end
387
+
388
+ # Public method for Claude Terminal to extract PRD content
389
+ def extract_prd_content(documents)
390
+ return [] unless documents
391
+
392
+ documents.flat_map do |doc|
393
+ # Extract PRD content from document title, content, labels
394
+ content = []
395
+ content << doc['title'] if doc['title']&.include?('PRD')
396
+ content << doc['title'] if doc['title']&.include?('Product Requirements')
397
+ content << doc['title'] if doc['title']&.include?('Requirements')
398
+ content << doc['content']&.truncate(200) if doc['content']
399
+ content
400
+ end.compact.uniq
401
+ end
402
+
403
+ # Public method for Claude Terminal to extract business processes
404
+ def extract_business_processes(documents)
405
+ return [] unless documents
406
+
407
+ documents.flat_map do |doc|
408
+ # Extract business process information from document content
409
+ processes = []
410
+ processes << doc['title'] if doc['title']&.include?('Process')
411
+ processes << doc['title'] if doc['title']&.include?('Workflow')
412
+ processes << doc['title'] if doc['title']&.include?('Procedure')
413
+ processes << doc['content']&.truncate(200) if doc['content']
414
+ processes
415
+ end.compact.uniq
416
+ end
417
+
418
+ # Public method for Claude Terminal to access Markdown business context
419
+ def get_markdown_business_context(class_name)
420
+ return {} unless CodeHealer::ConfigManager.use_markdown_context?
421
+
422
+ begin
423
+ # Load from existing markdown business context
424
+ markdown_context = load_business_requirements_from_markdown
425
+
426
+ if markdown_context.any?
427
+ {
428
+ markdown_files: markdown_context['markdown_requirements'] || [],
429
+ business_rules: extract_business_rules_from_markdown(markdown_context),
430
+ requirements: extract_requirements_from_markdown(markdown_context)
431
+ }
432
+ end
433
+ rescue => e
434
+ puts "⚠️ Failed to get Markdown business context: #{e.message}"
435
+ end
436
+
437
+ {}
438
+ end
439
+
440
+ # Public method for Claude Terminal to extract business rules from markdown
441
+ def extract_business_rules_from_markdown(markdown_context)
442
+ return [] unless markdown_context['markdown_requirements']
443
+
444
+ markdown_context['markdown_requirements'].flat_map do |file_info|
445
+ content = file_info[:content]
446
+ rules = []
447
+ rules << content if content.include?('rule')
448
+ rules << content if content.include?('policy')
449
+ rules << content if content.include?('requirement')
450
+ rules
451
+ end.compact.uniq
452
+ end
453
+
454
+ # Public method for Claude Terminal to extract requirements from markdown
455
+ def extract_requirements_from_markdown(markdown_context)
456
+ return [] unless markdown_context['markdown_requirements']
457
+
458
+ markdown_context['markdown_requirements'].flat_map do |file_info|
459
+ content = file_info[:content]
460
+ requirements = []
461
+ requirements << content if content.include?('requirement')
462
+ requirements << content if content.include?('must')
463
+ requirements << content if content.include?('should')
464
+ requirements << content if content.include?('need')
465
+ requirements
466
+ end.compact.uniq
247
467
  end
248
468
 
249
469
  def get_evolution_history(class_name, method_name)