clink-cli 0.2.1__py3-none-any.whl

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 (141) hide show
  1. clink/__init__.py +19 -0
  2. clink/agents/__init__.py +30 -0
  3. clink/agents/base.py +70 -0
  4. clink/agents/claude.py +7 -0
  5. clink/agents/codex.py +7 -0
  6. clink/agents/gemini.py +7 -0
  7. clink/allowed_roots.py +356 -0
  8. clink/backend.py +765 -0
  9. clink/cli.py +594 -0
  10. clink/constants.py +78 -0
  11. clink/contracts.py +167 -0
  12. clink/files.py +70 -0
  13. clink/generation.py +274 -0
  14. clink/generation_capabilities.py +207 -0
  15. clink/generation_contracts.py +214 -0
  16. clink/generation_policy.py +174 -0
  17. clink/models.py +243 -0
  18. clink/native.py +409 -0
  19. clink/native_adapters.py +244 -0
  20. clink/native_contracts.py +68 -0
  21. clink/native_generation.py +421 -0
  22. clink/native_generation_claude_policy.py +59 -0
  23. clink/native_generation_contracts.py +264 -0
  24. clink/native_generation_families.py +218 -0
  25. clink/native_generation_family_policy.py +14 -0
  26. clink/native_generation_files.py +153 -0
  27. clink/native_generation_policy.py +82 -0
  28. clink/native_policy.py +86 -0
  29. clink/parsers/__init__.py +34 -0
  30. clink/parsers/agy.py +53 -0
  31. clink/parsers/agy_native.py +161 -0
  32. clink/parsers/agy_native_generation.py +189 -0
  33. clink/parsers/base.py +209 -0
  34. clink/parsers/claude.py +104 -0
  35. clink/parsers/claude_native.py +113 -0
  36. clink/parsers/claude_native_generation.py +346 -0
  37. clink/parsers/codex.py +172 -0
  38. clink/parsers/codex_generation.py +212 -0
  39. clink/parsers/codex_native.py +236 -0
  40. clink/parsers/codex_native_generation.py +367 -0
  41. clink/parsers/gemini.py +110 -0
  42. clink/parsers/grok.py +63 -0
  43. clink/parsers/grok_native.py +91 -0
  44. clink/parsers/grok_native_generation.py +157 -0
  45. clink/policy.py +180 -0
  46. clink/registry.py +544 -0
  47. clink/resources/CODEX-LICENSE +201 -0
  48. clink/resources/CODEX-NOTICE +6 -0
  49. clink/resources/PROVENANCE.md +16 -0
  50. clink/resources/codex-0.166.0-models-direct.json +1284 -0
  51. clink/resources/codex-0.166.0-models-generation.json +1269 -0
  52. clink/resources/native-agy-1.4.12-admission.json +746 -0
  53. clink/resources/native-claude-2.1.304-admission.json +99 -0
  54. clink/resources/native-generation-claude-2.1.304-admission.json +277 -0
  55. clink/resources/native-generation-codex-0.166.0-admission.json +309 -0
  56. clink/resources/native-generation-grok-1.0.70-admission.json +329 -0
  57. clink/resources/native-grok-1.0.70-admission.json +644 -0
  58. clink/runner.py +303 -0
  59. clink/setup.py +399 -0
  60. clink/tasks.py +695 -0
  61. clink_cli-0.2.1.dist-info/METADATA +225 -0
  62. clink_cli-0.2.1.dist-info/RECORD +141 -0
  63. clink_cli-0.2.1.dist-info/WHEEL +5 -0
  64. clink_cli-0.2.1.dist-info/entry_points.txt +3 -0
  65. clink_cli-0.2.1.dist-info/licenses/LICENSE +197 -0
  66. clink_cli-0.2.1.dist-info/licenses/clink/resources/CODEX-LICENSE +201 -0
  67. clink_cli-0.2.1.dist-info/licenses/clink/resources/CODEX-NOTICE +6 -0
  68. clink_cli-0.2.1.dist-info/top_level.txt +7 -0
  69. conf/__init__.py +1 -0
  70. conf/cli_clients/agy.json +40 -0
  71. conf/cli_clients/claude.json +39 -0
  72. conf/cli_clients/codex.json +40 -0
  73. conf/cli_clients/gemini.json +23 -0
  74. conf/cli_clients/grok.json +40 -0
  75. config.py +40 -0
  76. server.py +896 -0
  77. systemprompts/__init__.py +35 -0
  78. systemprompts/analyze_prompt.py +87 -0
  79. systemprompts/chat_prompt.py +57 -0
  80. systemprompts/clink/codex_codereviewer.txt +8 -0
  81. systemprompts/clink/default.txt +8 -0
  82. systemprompts/clink/default_codereviewer.txt +8 -0
  83. systemprompts/clink/default_planner.txt +7 -0
  84. systemprompts/clink/native_codereviewer.txt +1 -0
  85. systemprompts/clink/native_default.txt +1 -0
  86. systemprompts/clink/native_planner.txt +1 -0
  87. systemprompts/codereview_prompt.py +91 -0
  88. systemprompts/consensus_prompt.py +120 -0
  89. systemprompts/debug_prompt.py +150 -0
  90. systemprompts/docgen_prompt.py +252 -0
  91. systemprompts/generate_code_prompt.py +181 -0
  92. systemprompts/planner_prompt.py +127 -0
  93. systemprompts/precommit_prompt.py +179 -0
  94. systemprompts/refactor_prompt.py +323 -0
  95. systemprompts/secaudit_prompt.py +420 -0
  96. systemprompts/testgen_prompt.py +133 -0
  97. systemprompts/thinkdeep_prompt.py +55 -0
  98. systemprompts/tracer_prompt.py +145 -0
  99. tools/__init__.py +43 -0
  100. tools/analyze.py +583 -0
  101. tools/apilookup.py +97 -0
  102. tools/challenge.py +198 -0
  103. tools/chat.py +187 -0
  104. tools/clink.py +130 -0
  105. tools/codereview.py +724 -0
  106. tools/consensus.py +790 -0
  107. tools/debug.py +573 -0
  108. tools/docgen.py +577 -0
  109. tools/listmodels.py +48 -0
  110. tools/models.py +373 -0
  111. tools/planner.py +533 -0
  112. tools/precommit.py +776 -0
  113. tools/refactor.py +645 -0
  114. tools/secaudit.py +685 -0
  115. tools/shared/__init__.py +19 -0
  116. tools/shared/base_models.py +167 -0
  117. tools/shared/base_tool.py +659 -0
  118. tools/shared/exceptions.py +20 -0
  119. tools/shared/schema_builders.py +159 -0
  120. tools/simple/__init__.py +18 -0
  121. tools/simple/base.py +539 -0
  122. tools/testgen.py +513 -0
  123. tools/thinkdeep.py +586 -0
  124. tools/tracer.py +763 -0
  125. tools/version.py +53 -0
  126. tools/workflow/__init__.py +22 -0
  127. tools/workflow/base.py +448 -0
  128. tools/workflow/schema_builders.py +166 -0
  129. tools/workflow/workflow_mixin.py +1195 -0
  130. utils/__init__.py +21 -0
  131. utils/call_state.py +349 -0
  132. utils/client_info.py +293 -0
  133. utils/consensus_manifest.py +131 -0
  134. utils/conversation_memory.py +582 -0
  135. utils/env.py +111 -0
  136. utils/file_types.py +271 -0
  137. utils/file_utils.py +803 -0
  138. utils/image_utils.py +94 -0
  139. utils/security_config.py +163 -0
  140. utils/storage_backend.py +177 -0
  141. utils/token_utils.py +54 -0
tools/refactor.py ADDED
@@ -0,0 +1,645 @@
1
+ """
2
+ Refactor tool - Step-by-step refactoring analysis with expert validation
3
+
4
+ This tool provides a structured workflow for comprehensive code refactoring analysis.
5
+ It guides CLI agent through systematic investigation steps with forced pauses between each step
6
+ to ensure thorough code examination, refactoring opportunity identification, and quality
7
+ assessment before proceeding. The tool supports complex refactoring scenarios including
8
+ code smell detection, decomposition planning, modernization opportunities, and organization improvements.
9
+
10
+ Key features:
11
+ - Step-by-step refactoring investigation workflow with progress tracking
12
+ - Context-aware file embedding (references during investigation, full content for analysis)
13
+ - Automatic refactoring opportunity tracking with type and severity classification
14
+ - Expert analysis integration with external models
15
+ - Support for focused refactoring types (codesmells, decompose, modernize, organization)
16
+ - Confidence-based workflow optimization with refactor completion tracking
17
+ """
18
+
19
+ import logging
20
+ from typing import TYPE_CHECKING, Any, Literal, Optional
21
+
22
+ from pydantic import Field, model_validator
23
+
24
+ if TYPE_CHECKING:
25
+ from tools.models import ToolModelCategory
26
+
27
+ from config import TEMPERATURE_ANALYTICAL
28
+ from systemprompts import REFACTOR_PROMPT
29
+ from tools.shared.base_models import WorkflowRequest
30
+
31
+ from .workflow.base import WorkflowTool
32
+
33
+ logger = logging.getLogger(__name__)
34
+
35
+ # Tool-specific field descriptions for refactor tool
36
+ REFACTOR_FIELD_DESCRIPTIONS = {
37
+ "step": (
38
+ "The refactoring plan. Step 1: State strategy. Later steps: Report findings. "
39
+ "CRITICAL: Examine code for smells, and opportunities for decomposition, modernization, and organization. "
40
+ "Use 'relevant_files' for code. FORBIDDEN: Large code snippets."
41
+ ),
42
+ "step_number": (
43
+ "The index of the current step in the refactoring investigation sequence, beginning at 1. Each step should "
44
+ "build upon or revise the previous one."
45
+ ),
46
+ "total_steps": (
47
+ "Your current estimate for how many steps will be needed to complete the refactoring investigation. "
48
+ "Adjust as new opportunities emerge."
49
+ ),
50
+ "next_step_required": (
51
+ "Set to true if you plan to continue the investigation with another step. False means you believe the "
52
+ "refactoring analysis is complete and ready for expert validation."
53
+ ),
54
+ "findings": (
55
+ "Summary of discoveries from this step, including code smells and opportunities for decomposition, modernization, or organization. "
56
+ "Document both strengths and weaknesses. In later steps, confirm or update past findings."
57
+ ),
58
+ "files_checked": (
59
+ "List all files examined (absolute paths). Include even ruled-out files to track exploration path."
60
+ ),
61
+ "relevant_files": (
62
+ "Subset of files_checked with code requiring refactoring (absolute paths). Include files with "
63
+ "code smells, decomposition needs, or improvement opportunities."
64
+ ),
65
+ "relevant_context": (
66
+ "List methods/functions central to refactoring opportunities, in 'ClassName.methodName' or 'functionName' format. "
67
+ "Prioritize those with code smells or needing improvement."
68
+ ),
69
+ "issues_found": (
70
+ "Refactoring opportunities as dictionaries with 'severity' (critical/high/medium/low), "
71
+ "'type' (codesmells/decompose/modernize/organization), and 'description'. "
72
+ "Include all improvement opportunities found."
73
+ ),
74
+ "confidence": (
75
+ "Your confidence in refactoring analysis: exploring (starting), incomplete (significant work remaining), "
76
+ "partial (some opportunities found, more analysis needed), complete (comprehensive analysis finished, "
77
+ "all major opportunities identified). "
78
+ "WARNING: Use 'complete' ONLY when fully analyzed and can provide recommendations without expert help. "
79
+ "'complete' PREVENTS expert validation. Use 'partial' for large files or uncertain analysis."
80
+ ),
81
+ "images": (
82
+ "Optional list of absolute paths to architecture diagrams, UI mockups, design documents, or visual references "
83
+ "that help with refactoring context. Only include if they materially assist understanding or assessment."
84
+ ),
85
+ "refactor_type": "Type of refactoring analysis to perform (codesmells, decompose, modernize, organization)",
86
+ "focus_areas": "Specific areas to focus on (e.g., 'performance', 'readability', 'maintainability', 'security')",
87
+ "style_guide_examples": (
88
+ "Optional existing code files to use as style/pattern reference (must be FULL absolute paths to real files / "
89
+ "folders - DO NOT SHORTEN). These files represent the target coding style and patterns for the project."
90
+ ),
91
+ }
92
+
93
+
94
+ class RefactorRequest(WorkflowRequest):
95
+ """Request model for refactor workflow investigation steps"""
96
+
97
+ # Required fields for each investigation step
98
+ step: str = Field(..., description=REFACTOR_FIELD_DESCRIPTIONS["step"])
99
+ step_number: int = Field(..., description=REFACTOR_FIELD_DESCRIPTIONS["step_number"])
100
+ total_steps: int = Field(..., description=REFACTOR_FIELD_DESCRIPTIONS["total_steps"])
101
+ next_step_required: bool = Field(..., description=REFACTOR_FIELD_DESCRIPTIONS["next_step_required"])
102
+
103
+ # Investigation tracking fields
104
+ findings: str = Field(..., description=REFACTOR_FIELD_DESCRIPTIONS["findings"])
105
+ files_checked: list[str] = Field(default_factory=list, description=REFACTOR_FIELD_DESCRIPTIONS["files_checked"])
106
+ relevant_files: list[str] = Field(default_factory=list, description=REFACTOR_FIELD_DESCRIPTIONS["relevant_files"])
107
+ relevant_context: list[str] = Field(
108
+ default_factory=list, description=REFACTOR_FIELD_DESCRIPTIONS["relevant_context"]
109
+ )
110
+ issues_found: list[dict] = Field(default_factory=list, description=REFACTOR_FIELD_DESCRIPTIONS["issues_found"])
111
+ confidence: Optional[Literal["exploring", "incomplete", "partial", "complete"]] = Field(
112
+ "incomplete", description=REFACTOR_FIELD_DESCRIPTIONS["confidence"]
113
+ )
114
+
115
+ # Optional images for visual context
116
+ images: Optional[list[str]] = Field(default=None, description=REFACTOR_FIELD_DESCRIPTIONS["images"])
117
+
118
+ # Refactor-specific fields (only used in step 1 to initialize)
119
+ refactor_type: Optional[Literal["codesmells", "decompose", "modernize", "organization"]] = Field(
120
+ "codesmells", description=REFACTOR_FIELD_DESCRIPTIONS["refactor_type"]
121
+ )
122
+ focus_areas: Optional[list[str]] = Field(None, description=REFACTOR_FIELD_DESCRIPTIONS["focus_areas"])
123
+ style_guide_examples: Optional[list[str]] = Field(
124
+ None, description=REFACTOR_FIELD_DESCRIPTIONS["style_guide_examples"]
125
+ )
126
+
127
+ # Override inherited fields to exclude them from schema (except model which needs to be available)
128
+ temperature: Optional[float] = Field(default=None, exclude=True)
129
+ thinking_mode: Optional[str] = Field(default=None, exclude=True)
130
+
131
+ @model_validator(mode="after")
132
+ def validate_step_one_requirements(self):
133
+ """Ensure step 1 has required relevant_files field."""
134
+ if self.step_number == 1 and not self.relevant_files:
135
+ raise ValueError(
136
+ "Step 1 requires 'relevant_files' field to specify code files or directories to analyze for refactoring"
137
+ )
138
+ return self
139
+
140
+
141
+ class RefactorTool(WorkflowTool):
142
+ """
143
+ Refactor tool for step-by-step refactoring analysis and expert validation.
144
+
145
+ This tool implements a structured refactoring workflow that guides users through
146
+ methodical investigation steps, ensuring thorough code examination, refactoring opportunity
147
+ identification, and improvement assessment before reaching conclusions. It supports complex
148
+ refactoring scenarios including code smell detection, decomposition planning, modernization
149
+ opportunities, and organization improvements.
150
+ """
151
+
152
+ def __init__(self):
153
+ super().__init__()
154
+ self.initial_request = None
155
+ self.refactor_config = {}
156
+
157
+ def get_name(self) -> str:
158
+ return "refactor"
159
+
160
+ def get_description(self) -> str:
161
+ return (
162
+ "Analyzes code for refactoring opportunities with systematic investigation. "
163
+ "Use for code smell detection, decomposition planning, modernization, and maintainability improvements. "
164
+ "Guides through structured analysis with expert validation."
165
+ )
166
+
167
+ def get_system_prompt(self) -> str:
168
+ return REFACTOR_PROMPT
169
+
170
+ def get_default_temperature(self) -> float:
171
+ return TEMPERATURE_ANALYTICAL
172
+
173
+ def get_model_category(self) -> "ToolModelCategory":
174
+ """Refactor workflow requires thorough analysis and reasoning"""
175
+ from tools.models import ToolModelCategory
176
+
177
+ return ToolModelCategory.EXTENDED_REASONING
178
+
179
+ def get_workflow_request_model(self):
180
+ """Return the refactor workflow-specific request model."""
181
+ return RefactorRequest
182
+
183
+ def get_input_schema(self) -> dict[str, Any]:
184
+ """Generate input schema using WorkflowSchemaBuilder with refactor-specific overrides."""
185
+ from .workflow.schema_builders import WorkflowSchemaBuilder
186
+
187
+ # Refactor workflow-specific field overrides
188
+ refactor_field_overrides = {
189
+ "step": {
190
+ "type": "string",
191
+ "description": REFACTOR_FIELD_DESCRIPTIONS["step"],
192
+ },
193
+ "step_number": {
194
+ "type": "integer",
195
+ "minimum": 1,
196
+ "description": REFACTOR_FIELD_DESCRIPTIONS["step_number"],
197
+ },
198
+ "total_steps": {
199
+ "type": "integer",
200
+ "minimum": 1,
201
+ "description": REFACTOR_FIELD_DESCRIPTIONS["total_steps"],
202
+ },
203
+ "next_step_required": {
204
+ "type": "boolean",
205
+ "description": REFACTOR_FIELD_DESCRIPTIONS["next_step_required"],
206
+ },
207
+ "findings": {
208
+ "type": "string",
209
+ "description": REFACTOR_FIELD_DESCRIPTIONS["findings"],
210
+ },
211
+ "files_checked": {
212
+ "type": "array",
213
+ "items": {"type": "string"},
214
+ "description": REFACTOR_FIELD_DESCRIPTIONS["files_checked"],
215
+ },
216
+ "relevant_files": {
217
+ "type": "array",
218
+ "items": {"type": "string"},
219
+ "description": REFACTOR_FIELD_DESCRIPTIONS["relevant_files"],
220
+ },
221
+ "confidence": {
222
+ "type": "string",
223
+ "enum": ["exploring", "incomplete", "partial", "complete"],
224
+ "default": "incomplete",
225
+ "description": REFACTOR_FIELD_DESCRIPTIONS["confidence"],
226
+ },
227
+ "issues_found": {
228
+ "type": "array",
229
+ "items": {"type": "object"},
230
+ "description": REFACTOR_FIELD_DESCRIPTIONS["issues_found"],
231
+ },
232
+ "images": {
233
+ "type": "array",
234
+ "items": {"type": "string"},
235
+ "description": REFACTOR_FIELD_DESCRIPTIONS["images"],
236
+ },
237
+ # Refactor-specific fields (for step 1)
238
+ # Note: Use relevant_files field instead of files for consistency
239
+ "refactor_type": {
240
+ "type": "string",
241
+ "enum": ["codesmells", "decompose", "modernize", "organization"],
242
+ "default": "codesmells",
243
+ "description": REFACTOR_FIELD_DESCRIPTIONS["refactor_type"],
244
+ },
245
+ "focus_areas": {
246
+ "type": "array",
247
+ "items": {"type": "string"},
248
+ "description": REFACTOR_FIELD_DESCRIPTIONS["focus_areas"],
249
+ },
250
+ "style_guide_examples": {
251
+ "type": "array",
252
+ "items": {"type": "string"},
253
+ "description": REFACTOR_FIELD_DESCRIPTIONS["style_guide_examples"],
254
+ },
255
+ }
256
+
257
+ # Use WorkflowSchemaBuilder with refactor-specific tool fields
258
+ return WorkflowSchemaBuilder.build_schema(
259
+ tool_specific_fields=refactor_field_overrides,
260
+ model_field_schema=self.get_model_field_schema(),
261
+ auto_mode=self.is_effective_auto_mode(),
262
+ tool_name=self.get_name(),
263
+ )
264
+
265
+ def get_required_actions(
266
+ self, step_number: int, confidence: str, findings: str, total_steps: int, request=None
267
+ ) -> list[str]:
268
+ """Define required actions for each investigation phase."""
269
+ if step_number == 1:
270
+ # Initial refactoring investigation tasks
271
+ return [
272
+ "Read and understand the code files specified for refactoring analysis",
273
+ "Examine the overall structure, architecture, and design patterns used",
274
+ "Identify potential code smells: long methods, large classes, duplicate code, complex conditionals",
275
+ "Look for decomposition opportunities: oversized components that could be broken down",
276
+ "Check for modernization opportunities: outdated patterns, deprecated features, newer language constructs",
277
+ "Assess organization: logical grouping, file structure, naming conventions, module boundaries",
278
+ "Document specific refactoring opportunities with file locations and line numbers",
279
+ ]
280
+ elif confidence in ["exploring", "incomplete"]:
281
+ # Need deeper investigation
282
+ return [
283
+ "Examine specific code sections you've identified as needing refactoring",
284
+ "Analyze code smells in detail: complexity, coupling, cohesion issues",
285
+ "Investigate decomposition opportunities: identify natural breaking points for large components",
286
+ "Look for modernization possibilities: language features, patterns, libraries that could improve the code",
287
+ "Check organization issues: related functionality that could be better grouped or structured",
288
+ "Trace dependencies and relationships between components to understand refactoring impact",
289
+ "Prioritize refactoring opportunities by impact and effort required",
290
+ ]
291
+ elif confidence == "partial":
292
+ # Close to completion - need final verification
293
+ return [
294
+ "Verify all identified refactoring opportunities have been properly documented with locations",
295
+ "Check for any missed opportunities in areas not yet thoroughly examined",
296
+ "Confirm that refactoring suggestions align with the specified refactor_type and focus_areas",
297
+ "Ensure refactoring opportunities are prioritized by severity and impact",
298
+ "Validate that proposed changes would genuinely improve code quality without breaking functionality",
299
+ "Double-check that all relevant files and code elements are captured in your analysis",
300
+ ]
301
+ else:
302
+ # General investigation needed
303
+ return [
304
+ "Continue examining the codebase for additional refactoring opportunities",
305
+ "Gather more evidence using appropriate code analysis techniques",
306
+ "Test your assumptions about code quality and improvement possibilities",
307
+ "Look for patterns that confirm or refute your current refactoring assessment",
308
+ "Focus on areas that haven't been thoroughly examined for refactoring potential",
309
+ ]
310
+
311
+ def should_call_expert_analysis(self, consolidated_findings, request=None) -> bool:
312
+ """
313
+ Decide when to call external model based on investigation completeness.
314
+
315
+ Don't call expert analysis if the CLI agent has certain confidence and complete refactoring - trust their judgment.
316
+ """
317
+ # Check if user requested to skip assistant model
318
+ if request and not self.get_request_use_assistant_model(request):
319
+ return False
320
+
321
+ # Check if refactoring work is complete
322
+ if request and request.confidence == "complete":
323
+ return False
324
+
325
+ # Check if we have meaningful investigation data
326
+ return (
327
+ len(consolidated_findings.relevant_files) > 0
328
+ or len(consolidated_findings.findings) >= 2
329
+ or len(consolidated_findings.issues_found) > 0
330
+ )
331
+
332
+ def prepare_expert_analysis_context(self, consolidated_findings) -> str:
333
+ """Prepare context for external model call for final refactoring validation."""
334
+ context_parts = [
335
+ f"=== REFACTORING ANALYSIS REQUEST ===\\n{self.get_expert_initial_request(self.initial_request, 'Refactoring workflow initiated')}\\n=== END REQUEST ==="
336
+ ]
337
+
338
+ # Add investigation summary
339
+ investigation_summary = self._build_refactoring_summary(consolidated_findings)
340
+ context_parts.append(
341
+ f"\\n=== AGENT'S REFACTORING INVESTIGATION ===\\n{investigation_summary}\\n=== END INVESTIGATION ==="
342
+ )
343
+
344
+ # Add refactor configuration context if available
345
+ if self.refactor_config:
346
+ config_text = "\\n".join(f"- {key}: {value}" for key, value in self.refactor_config.items() if value)
347
+ context_parts.append(f"\\n=== REFACTOR CONFIGURATION ===\\n{config_text}\\n=== END CONFIGURATION ===")
348
+
349
+ # Add relevant code elements if available
350
+ if consolidated_findings.relevant_context:
351
+ methods_text = "\\n".join(f"- {method}" for method in consolidated_findings.relevant_context)
352
+ context_parts.append(f"\\n=== RELEVANT CODE ELEMENTS ===\\n{methods_text}\\n=== END CODE ELEMENTS ===")
353
+
354
+ # Add refactoring opportunities found if available
355
+ if consolidated_findings.issues_found:
356
+ opportunities_text = "\\n".join(
357
+ f"[{issue.get('severity', 'unknown').upper()}] {issue.get('type', 'unknown').upper()}: {issue.get('description', 'No description')}"
358
+ for issue in consolidated_findings.issues_found
359
+ )
360
+ context_parts.append(
361
+ f"\\n=== REFACTORING OPPORTUNITIES ===\\n{opportunities_text}\\n=== END OPPORTUNITIES ==="
362
+ )
363
+
364
+ # Add assessment evolution if available
365
+ if consolidated_findings.hypotheses:
366
+ assessments_text = "\\n".join(
367
+ f"Step {h['step']} ({h['confidence']} confidence): {h['hypothesis']}"
368
+ for h in consolidated_findings.hypotheses
369
+ )
370
+ context_parts.append(f"\\n=== ASSESSMENT EVOLUTION ===\\n{assessments_text}\\n=== END ASSESSMENTS ===")
371
+
372
+ # Add images if available
373
+ if consolidated_findings.images:
374
+ images_text = "\\n".join(f"- {img}" for img in consolidated_findings.images)
375
+ context_parts.append(
376
+ f"\\n=== VISUAL REFACTORING INFORMATION ===\\n{images_text}\\n=== END VISUAL INFORMATION ==="
377
+ )
378
+
379
+ return "\\n".join(context_parts)
380
+
381
+ def _build_refactoring_summary(self, consolidated_findings) -> str:
382
+ """Prepare a comprehensive summary of the refactoring investigation."""
383
+ summary_parts = [
384
+ "=== SYSTEMATIC REFACTORING INVESTIGATION SUMMARY ===",
385
+ f"Total steps: {len(consolidated_findings.findings)}",
386
+ f"Files examined: {len(consolidated_findings.files_checked)}",
387
+ f"Relevant files identified: {len(consolidated_findings.relevant_files)}",
388
+ f"Code elements analyzed: {len(consolidated_findings.relevant_context)}",
389
+ f"Refactoring opportunities identified: {len(consolidated_findings.issues_found)}",
390
+ "",
391
+ "=== INVESTIGATION PROGRESSION ===",
392
+ ]
393
+
394
+ for finding in consolidated_findings.findings:
395
+ summary_parts.append(finding)
396
+
397
+ return "\\n".join(summary_parts)
398
+
399
+ def should_include_files_in_expert_prompt(self) -> bool:
400
+ """Include files in expert analysis for comprehensive refactoring validation."""
401
+ return True
402
+
403
+ def should_embed_system_prompt(self) -> bool:
404
+ """Embed system prompt in expert analysis for proper context."""
405
+ return True
406
+
407
+ def get_expert_thinking_mode(self) -> str:
408
+ """Use high thinking mode for thorough refactoring analysis."""
409
+ return "high"
410
+
411
+ def get_expert_analysis_instruction(self) -> str:
412
+ """Get specific instruction for refactoring expert analysis."""
413
+ return (
414
+ "Please provide comprehensive refactoring analysis based on the investigation findings. "
415
+ "Focus on validating the identified opportunities, ensuring completeness of the analysis, "
416
+ "and providing final recommendations for refactoring implementation, following the structured "
417
+ "format specified in the system prompt."
418
+ )
419
+
420
+ # Hook method overrides for refactor-specific behavior
421
+
422
+ def prepare_step_data(self, request) -> dict:
423
+ """
424
+ Map refactor workflow-specific fields for internal processing.
425
+ """
426
+ step_data = {
427
+ "step": request.step,
428
+ "step_number": request.step_number,
429
+ "findings": request.findings,
430
+ "files_checked": request.files_checked,
431
+ "relevant_files": request.relevant_files,
432
+ "relevant_context": request.relevant_context,
433
+ "issues_found": request.issues_found,
434
+ "confidence": request.confidence,
435
+ "hypothesis": request.findings, # Map findings to hypothesis for compatibility
436
+ "images": request.images or [],
437
+ }
438
+ return step_data
439
+
440
+ def should_skip_expert_analysis(self, request, consolidated_findings) -> bool:
441
+ """
442
+ Refactor workflow skips expert analysis when the CLI agent has "complete" confidence.
443
+ """
444
+ return request.confidence == "complete" and not request.next_step_required
445
+
446
+ def store_initial_issue(self, step_description: str):
447
+ """Store initial request for expert analysis."""
448
+ self.initial_request = step_description
449
+
450
+ # Inheritance hook methods for refactor-specific behavior
451
+
452
+ # Override inheritance hooks for refactor-specific behavior
453
+
454
+ def get_completion_status(self) -> str:
455
+ """Refactor tools use refactor-specific status."""
456
+ return "refactoring_analysis_complete_ready_for_implementation"
457
+
458
+ def get_completion_data_key(self) -> str:
459
+ """Refactor uses 'complete_refactoring' key."""
460
+ return "complete_refactoring"
461
+
462
+ def get_final_analysis_from_request(self, request):
463
+ """Refactor tools use 'findings' field."""
464
+ return request.findings
465
+
466
+ def get_confidence_level(self, request) -> str:
467
+ """Refactor tools use 'complete' for high confidence."""
468
+ return "complete"
469
+
470
+ def get_completion_message(self) -> str:
471
+ """Refactor-specific completion message."""
472
+ return (
473
+ "Refactoring analysis complete with COMPLETE confidence. You have identified all significant "
474
+ "refactoring opportunities and provided comprehensive analysis. MANDATORY: Present the user with "
475
+ "the complete refactoring results organized by type and severity, and IMMEDIATELY proceed with "
476
+ "implementing the highest priority refactoring opportunities or provide specific guidance for "
477
+ "improvements. Focus on actionable refactoring steps."
478
+ )
479
+
480
+ def get_skip_reason(self) -> str:
481
+ """Refactor-specific skip reason."""
482
+ return "Completed comprehensive refactoring analysis with full confidence locally"
483
+
484
+ def get_skip_expert_analysis_status(self) -> str:
485
+ """Refactor-specific expert analysis skip status."""
486
+ return "skipped_due_to_complete_refactoring_confidence"
487
+
488
+ def prepare_work_summary(self) -> str:
489
+ """Refactor-specific work summary."""
490
+ return self._build_refactoring_summary(self.consolidated_findings)
491
+
492
+ def get_completion_next_steps_message(self, expert_analysis_used: bool = False) -> str:
493
+ """
494
+ Refactor-specific completion message.
495
+
496
+ Args:
497
+ expert_analysis_used: True if expert analysis was successfully executed
498
+ """
499
+ base_message = (
500
+ "REFACTORING ANALYSIS IS COMPLETE. You MUST now summarize and present ALL refactoring opportunities "
501
+ "organized by type (codesmells → decompose → modernize → organization) and severity (Critical → High → "
502
+ "Medium → Low), specific code locations with line numbers, and exact recommendations for improvement. "
503
+ "Clearly prioritize the top 3 refactoring opportunities that need immediate attention. Provide concrete, "
504
+ "actionable guidance for each opportunity—make it easy for a developer to understand exactly what needs "
505
+ "to be refactored and how to implement the improvements."
506
+ )
507
+
508
+ # Add expert analysis guidance only when expert analysis was actually used
509
+ if expert_analysis_used:
510
+ expert_guidance = self.get_expert_analysis_guidance()
511
+ if expert_guidance:
512
+ return f"{base_message}\n\n{expert_guidance}"
513
+
514
+ return base_message
515
+
516
+ def get_expert_analysis_guidance(self) -> str:
517
+ """
518
+ Get additional guidance for handling expert analysis results in refactor context.
519
+
520
+ Returns:
521
+ Additional guidance text for validating and using expert analysis findings
522
+ """
523
+ return (
524
+ "IMPORTANT: Expert refactoring analysis has been provided above. You MUST review "
525
+ "the expert's architectural insights and refactoring recommendations. Consider whether "
526
+ "the expert's suggestions align with the codebase's evolution trajectory and current "
527
+ "team priorities. Pay special attention to any breaking changes, migration complexity, "
528
+ "or performance implications highlighted by the expert. Present a balanced view that "
529
+ "considers both immediate benefits and long-term maintainability."
530
+ )
531
+
532
+ def get_step_guidance_message(self, request) -> str:
533
+ """
534
+ Refactor-specific step guidance with detailed investigation instructions.
535
+ """
536
+ step_guidance = self.get_refactor_step_guidance(request.step_number, request.confidence, request)
537
+ return step_guidance["next_steps"]
538
+
539
+ def get_refactor_step_guidance(self, step_number: int, confidence: str, request) -> dict[str, Any]:
540
+ """
541
+ Provide step-specific guidance for refactor workflow.
542
+ """
543
+ # Generate the next steps instruction based on required actions
544
+ required_actions = self.get_required_actions(step_number, confidence, request.findings, request.total_steps)
545
+
546
+ if step_number == 1:
547
+ next_steps = (
548
+ f"MANDATORY: DO NOT call the {self.get_name()} tool again immediately. You MUST first examine "
549
+ f"the code files thoroughly for refactoring opportunities using appropriate tools. CRITICAL AWARENESS: "
550
+ f"You need to identify code smells, decomposition opportunities, modernization possibilities, and "
551
+ f"organization improvements across the specified refactor_type. Look for complexity issues, outdated "
552
+ f"patterns, oversized components, and structural problems. Use file reading tools, code analysis, and "
553
+ f"systematic examination to gather comprehensive refactoring information. Only call {self.get_name()} "
554
+ f"again AFTER completing your investigation. When you call {self.get_name()} next time, use "
555
+ f"step_number: {step_number + 1} and report specific files examined, refactoring opportunities found, "
556
+ f"and improvement assessments discovered."
557
+ )
558
+ elif confidence in ["exploring", "incomplete"]:
559
+ next_steps = (
560
+ f"STOP! Do NOT call {self.get_name()} again yet. Based on your findings, you've identified areas that need "
561
+ f"deeper refactoring analysis. MANDATORY ACTIONS before calling {self.get_name()} step {step_number + 1}:\\n"
562
+ + "\\n".join(f"{i+1}. {action}" for i, action in enumerate(required_actions))
563
+ + f"\\n\\nOnly call {self.get_name()} again with step_number: {step_number + 1} AFTER "
564
+ + "completing these refactoring analysis tasks."
565
+ )
566
+ elif confidence == "partial":
567
+ next_steps = (
568
+ f"WAIT! Your refactoring analysis needs final verification. DO NOT call {self.get_name()} immediately. REQUIRED ACTIONS:\\n"
569
+ + "\\n".join(f"{i+1}. {action}" for i, action in enumerate(required_actions))
570
+ + f"\\n\\nREMEMBER: Ensure you have identified all significant refactoring opportunities across all types and "
571
+ f"verified the completeness of your analysis. Document opportunities with specific file references and "
572
+ f"line numbers where applicable, then call {self.get_name()} with step_number: {step_number + 1}."
573
+ )
574
+ else:
575
+ next_steps = (
576
+ f"PAUSE REFACTORING ANALYSIS. Before calling {self.get_name()} step {step_number + 1}, you MUST examine more code thoroughly. "
577
+ + "Required: "
578
+ + ", ".join(required_actions[:2])
579
+ + ". "
580
+ + f"Your next {self.get_name()} call (step_number: {step_number + 1}) must include "
581
+ f"NEW evidence from actual refactoring analysis, not just theories. NO recursive {self.get_name()} calls "
582
+ f"without investigation work!"
583
+ )
584
+
585
+ return {"next_steps": next_steps}
586
+
587
+ def customize_workflow_response(self, response_data: dict, request) -> dict:
588
+ """
589
+ Customize response to match refactor workflow format.
590
+ """
591
+ # Store initial request on first step
592
+ if request.step_number == 1:
593
+ self.initial_request = request.step
594
+ # Store refactor configuration for expert analysis
595
+ if request.relevant_files:
596
+ self.refactor_config = {
597
+ "relevant_files": request.relevant_files,
598
+ "refactor_type": request.refactor_type,
599
+ "focus_areas": request.focus_areas,
600
+ "style_guide_examples": request.style_guide_examples,
601
+ }
602
+
603
+ # Convert generic status names to refactor-specific ones
604
+ tool_name = self.get_name()
605
+ status_mapping = {
606
+ f"{tool_name}_in_progress": "refactoring_analysis_in_progress",
607
+ f"pause_for_{tool_name}": "pause_for_refactoring_analysis",
608
+ f"{tool_name}_required": "refactoring_analysis_required",
609
+ f"{tool_name}_complete": "refactoring_analysis_complete",
610
+ }
611
+
612
+ if response_data["status"] in status_mapping:
613
+ response_data["status"] = status_mapping[response_data["status"]]
614
+
615
+ # Rename status field to match refactor workflow
616
+ if f"{tool_name}_status" in response_data:
617
+ response_data["refactoring_status"] = response_data.pop(f"{tool_name}_status")
618
+ # Add refactor-specific status fields
619
+ refactor_types = {}
620
+ for issue in self.consolidated_findings.issues_found:
621
+ issue_type = issue.get("type", "unknown")
622
+ if issue_type not in refactor_types:
623
+ refactor_types[issue_type] = 0
624
+ refactor_types[issue_type] += 1
625
+ response_data["refactoring_status"]["opportunities_by_type"] = refactor_types
626
+ response_data["refactoring_status"]["refactor_confidence"] = request.confidence
627
+
628
+ # Map complete_refactor to complete_refactoring
629
+ if f"complete_{tool_name}" in response_data:
630
+ response_data["complete_refactoring"] = response_data.pop(f"complete_{tool_name}")
631
+
632
+ # Map the completion flag to match refactor workflow
633
+ if f"{tool_name}_complete" in response_data:
634
+ response_data["refactoring_complete"] = response_data.pop(f"{tool_name}_complete")
635
+
636
+ return response_data
637
+
638
+ # Required abstract methods from BaseTool
639
+ def get_request_model(self):
640
+ """Return the refactor workflow-specific request model."""
641
+ return RefactorRequest
642
+
643
+ async def prepare_prompt(self, request) -> str:
644
+ """Not used - workflow tools use execute_workflow()."""
645
+ return "" # Workflow tools use execute_workflow() directly