crackerjack 0.39.11__py3-none-any.whl → 0.40.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.

Potentially problematic release.


This version of crackerjack might be problematic. Click here for more details.

@@ -0,0 +1,443 @@
1
+ """
2
+ Iterative auto-fix workflow for crackerjack.
3
+
4
+ This module implements the AutoFixWorkflow class that runs an iterative
5
+ loop to detect issues via pre-commit hooks, apply AI-powered fixes, and
6
+ verify the fixes until convergence or max iterations is reached.
7
+ """
8
+
9
+ import asyncio
10
+ import logging
11
+ import typing as t
12
+ from dataclasses import dataclass, field
13
+ from pathlib import Path
14
+
15
+ from rich.console import Console
16
+
17
+ from crackerjack.agents.base import AgentContext, Issue, IssueType, Priority
18
+ from crackerjack.agents.enhanced_coordinator import EnhancedAgentCoordinator
19
+ from crackerjack.managers.async_hook_manager import AsyncHookManager
20
+ from crackerjack.models.task import HookResult
21
+
22
+
23
+ @dataclass
24
+ class FixIteration:
25
+ """Records data from a single iteration of the fix cycle."""
26
+
27
+ iteration_num: int
28
+ hooks_run: list[str]
29
+ issues_found: int
30
+ fixes_applied: int
31
+ fixes_successful: int
32
+ hooks_passing: list[str]
33
+ hooks_failing: list[str]
34
+ duration: float = 0.0
35
+ convergence_status: str = "incomplete"
36
+
37
+ def to_dict(self) -> dict[str, t.Any]:
38
+ """Convert iteration to dictionary for serialization."""
39
+ return {
40
+ "iteration_num": self.iteration_num,
41
+ "hooks_run": self.hooks_run,
42
+ "issues_found": self.issues_found,
43
+ "fixes_applied": self.fixes_applied,
44
+ "fixes_successful": self.fixes_successful,
45
+ "hooks_passing": self.hooks_passing,
46
+ "hooks_failing": self.hooks_failing,
47
+ "duration": self.duration,
48
+ "convergence_status": self.convergence_status,
49
+ }
50
+
51
+
52
+ @dataclass
53
+ class WorkflowResult:
54
+ """Results from the complete auto-fix workflow."""
55
+
56
+ success: bool
57
+ iterations: list[FixIteration] = field(default_factory=list)
58
+ total_fixes: int = 0
59
+ total_issues_found: int = 0
60
+ final_status: str = "incomplete"
61
+ total_duration: float = 0.0
62
+ convergence_achieved: bool = False
63
+ exit_reason: str = "unknown"
64
+
65
+ def to_dict(self) -> dict[str, t.Any]:
66
+ """Convert result to dictionary for serialization."""
67
+ return {
68
+ "success": self.success,
69
+ "iterations": [it.to_dict() for it in self.iterations],
70
+ "total_fixes": self.total_fixes,
71
+ "total_issues_found": self.total_issues_found,
72
+ "final_status": self.final_status,
73
+ "total_duration": self.total_duration,
74
+ "convergence_achieved": self.convergence_achieved,
75
+ "exit_reason": self.exit_reason,
76
+ }
77
+
78
+
79
+ class AutoFixWorkflow:
80
+ """Iterative auto-fix workflow with convergence detection."""
81
+
82
+ MAX_ITERATIONS = 10
83
+ CONVERGENCE_THRESHOLD = 0 # No new fixes needed
84
+
85
+ def __init__(
86
+ self,
87
+ project_path: Path | None = None,
88
+ console: Console | None = None,
89
+ enable_external_agents: bool = True,
90
+ ) -> None:
91
+ """Initialize the auto-fix workflow.
92
+
93
+ Args:
94
+ project_path: Path to project root (defaults to cwd)
95
+ console: Rich console for output (creates default if None)
96
+ enable_external_agents: Enable Claude Code external agent integration
97
+ """
98
+ self.project_path = project_path or Path.cwd()
99
+ self.console = console or Console()
100
+ self.logger = logging.getLogger(__name__)
101
+
102
+ # Initialize agent context
103
+ self.context = AgentContext(
104
+ project_path=self.project_path,
105
+ temp_dir=self.project_path / ".crackerjack" / "temp",
106
+ )
107
+
108
+ # Initialize agent coordinator with external agent support
109
+ self.coordinator = EnhancedAgentCoordinator(
110
+ context=self.context,
111
+ enable_external_agents=enable_external_agents,
112
+ )
113
+
114
+ # Initialize hook manager
115
+ self.hook_manager = AsyncHookManager(
116
+ console=self.console,
117
+ pkg_path=self.project_path,
118
+ max_concurrent=3,
119
+ )
120
+
121
+ async def run(
122
+ self, command: str = "check", max_iterations: int | None = None
123
+ ) -> WorkflowResult:
124
+ """Run iterative auto-fix workflow.
125
+
126
+ Args:
127
+ command: Semantic command (test, lint, check, etc.)
128
+ max_iterations: Max fix iterations (default: 10)
129
+
130
+ Returns:
131
+ WorkflowResult with iteration history and final status
132
+ """
133
+ max_iter = max_iterations or self.MAX_ITERATIONS
134
+ iterations: list[FixIteration] = []
135
+ workflow_start_time = asyncio.get_event_loop().time()
136
+
137
+ self.logger.info(
138
+ f"Starting auto-fix workflow: {command} (max {max_iter} iterations)"
139
+ )
140
+ self.console.print("[bold cyan]🔄 Auto-Fix Workflow Started[/bold cyan]")
141
+ self.console.print(
142
+ f"[dim]Command: {command} | Max iterations: {max_iter}[/dim]\n"
143
+ )
144
+
145
+ exit_reason = "unknown"
146
+ all_passing = False
147
+
148
+ for i in range(1, max_iter + 1):
149
+ iteration_start_time = asyncio.get_event_loop().time()
150
+
151
+ self.logger.info(f"Iteration {i}/{max_iter}")
152
+ self.console.print(f"[bold]━━━ Iteration {i}/{max_iter} ━━━[/bold]")
153
+
154
+ # Step 1: Run hooks and collect failures
155
+ hook_results = await self._run_hooks(command)
156
+
157
+ # Step 2: Check for convergence (all passing)
158
+ if hook_results["all_passing"]:
159
+ all_passing = True
160
+ exit_reason = "convergence"
161
+
162
+ iteration_duration = (
163
+ asyncio.get_event_loop().time() - iteration_start_time
164
+ )
165
+
166
+ iteration = FixIteration(
167
+ iteration_num=i,
168
+ hooks_run=hook_results["hooks_run"],
169
+ issues_found=0,
170
+ fixes_applied=0,
171
+ fixes_successful=0,
172
+ hooks_passing=hook_results["passing"],
173
+ hooks_failing=[],
174
+ duration=iteration_duration,
175
+ convergence_status="converged",
176
+ )
177
+ iterations.append(iteration)
178
+
179
+ self.logger.info("✅ All hooks passing - convergence achieved!")
180
+ self.console.print(
181
+ "[bold green]✅ All hooks passing - convergence achieved![/bold green]\n"
182
+ )
183
+ break
184
+
185
+ # Step 3: Apply AI fixes for failures
186
+ fix_results = await self._apply_fixes(hook_results["failures"])
187
+
188
+ iteration_duration = asyncio.get_event_loop().time() - iteration_start_time
189
+
190
+ # Step 4: Record iteration
191
+ iteration = FixIteration(
192
+ iteration_num=i,
193
+ hooks_run=hook_results["hooks_run"],
194
+ issues_found=len(hook_results["failures"]),
195
+ fixes_applied=fix_results["fixes_applied"],
196
+ fixes_successful=fix_results["fixes_successful"],
197
+ hooks_passing=hook_results["passing"],
198
+ hooks_failing=hook_results["failing"],
199
+ duration=iteration_duration,
200
+ convergence_status="in_progress",
201
+ )
202
+ iterations.append(iteration)
203
+
204
+ self.console.print(
205
+ f"[dim]Issues found: {iteration.issues_found} | "
206
+ f"Fixes applied: {iteration.fixes_applied} | "
207
+ f"Successful: {iteration.fixes_successful}[/dim]\n"
208
+ )
209
+
210
+ # Step 5: Check for convergence (no fixes possible)
211
+ if fix_results["fixes_applied"] == 0:
212
+ exit_reason = "no_progress"
213
+ self.logger.warning("⚠️ No fixes applied - cannot make progress")
214
+ self.console.print(
215
+ "[bold yellow]⚠️ No fixes applied - cannot make progress[/bold yellow]\n"
216
+ )
217
+ break
218
+
219
+ # Handle max iterations reached
220
+ if not all_passing and exit_reason == "unknown":
221
+ exit_reason = "max_iterations"
222
+ self.logger.warning(
223
+ f"⚠️ Max iterations ({max_iter}) reached without full convergence"
224
+ )
225
+ self.console.print(
226
+ f"[bold yellow]⚠️ Max iterations ({max_iter}) reached[/bold yellow]\n"
227
+ )
228
+
229
+ # Calculate final statistics
230
+ total_duration = asyncio.get_event_loop().time() - workflow_start_time
231
+ total_fixes = sum(it.fixes_successful for it in iterations)
232
+ total_issues = sum(it.issues_found for it in iterations)
233
+
234
+ result = WorkflowResult(
235
+ success=all_passing,
236
+ iterations=iterations,
237
+ total_fixes=total_fixes,
238
+ total_issues_found=total_issues,
239
+ final_status="converged" if all_passing else "incomplete",
240
+ total_duration=total_duration,
241
+ convergence_achieved=all_passing,
242
+ exit_reason=exit_reason,
243
+ )
244
+
245
+ # Print summary
246
+ self._print_summary(result)
247
+
248
+ return result
249
+
250
+ async def _run_hooks(self, command: str) -> dict[str, t.Any]:
251
+ """Run pre-commit hooks and collect results.
252
+
253
+ Args:
254
+ command: Semantic command (determines which hooks to run)
255
+
256
+ Returns:
257
+ Dictionary with hook results and status
258
+ """
259
+ self.logger.debug(f"Running hooks for command: {command}")
260
+
261
+ # Choose hook strategy based on command
262
+ if command in ("test", "check", "all"):
263
+ results = await self.hook_manager.run_comprehensive_hooks_async()
264
+ else:
265
+ results = await self.hook_manager.run_fast_hooks_async()
266
+
267
+ # Parse results
268
+ hooks_run = [r.name for r in results]
269
+ passing = [r.name for r in results if r.status == "passed"]
270
+ failing = [r.name for r in results if r.status != "passed"]
271
+ all_passing = len(failing) == 0
272
+
273
+ self.logger.debug(
274
+ f"Hook results: {len(passing)} passing, {len(failing)} failing"
275
+ )
276
+
277
+ return {
278
+ "hooks_run": hooks_run,
279
+ "passing": passing,
280
+ "failing": failing,
281
+ "failures": [r for r in results if r.status != "passed"],
282
+ "all_passing": all_passing,
283
+ }
284
+
285
+ async def _apply_fixes(self, failures: list[HookResult]) -> dict[str, int]:
286
+ """Apply AI fixes for all failures.
287
+
288
+ Args:
289
+ failures: List of failed HookResults
290
+
291
+ Returns:
292
+ Dictionary with fix statistics
293
+ """
294
+ fixes_applied = 0
295
+ fixes_successful = 0
296
+
297
+ self.logger.info(f"Applying fixes for {len(failures)} failures")
298
+
299
+ for failure in failures:
300
+ try:
301
+ # Convert HookResult to Issue for agent system
302
+ issue = self._hook_result_to_issue(failure)
303
+
304
+ self.logger.debug(f"Fixing {failure.name}: {issue.message}")
305
+
306
+ # Coordinate fix via enhanced agent coordinator
307
+ result = await self.coordinator.handle_issues_proactively([issue])
308
+
309
+ if result.fixes_applied:
310
+ fixes_applied += len(result.fixes_applied)
311
+
312
+ if result.success:
313
+ fixes_successful += len(result.fixes_applied)
314
+ self.logger.info(
315
+ f"✅ Successfully fixed {failure.name} ({result.confidence:.2f} confidence)"
316
+ )
317
+ else:
318
+ self.logger.warning(
319
+ f"⚠️ Partial fix for {failure.name} ({result.confidence:.2f} confidence)"
320
+ )
321
+ else:
322
+ self.logger.debug(f"No fixes applied for {failure.name}")
323
+
324
+ except Exception as e:
325
+ self.logger.exception(f"Fix failed for {failure.name}: {e}")
326
+ self.console.print(f"[red]❌ Error fixing {failure.name}: {e}[/red]")
327
+
328
+ return {
329
+ "fixes_applied": fixes_applied,
330
+ "fixes_successful": fixes_successful,
331
+ }
332
+
333
+ def _hook_result_to_issue(self, hook_result: HookResult) -> Issue:
334
+ """Convert a HookResult to an Issue for the agent system.
335
+
336
+ Args:
337
+ hook_result: Hook execution result
338
+
339
+ Returns:
340
+ Issue object for agent processing
341
+ """
342
+ # Map hook names to issue types
343
+ issue_type_mapping: dict[str, IssueType] = {
344
+ "refurb": IssueType.DRY_VIOLATION,
345
+ "pyright": IssueType.TYPE_ERROR,
346
+ "bandit": IssueType.SECURITY,
347
+ "ruff": IssueType.FORMATTING,
348
+ "pytest": IssueType.TEST_FAILURE,
349
+ "complexipy": IssueType.COMPLEXITY,
350
+ "vulture": IssueType.DEAD_CODE,
351
+ "creosote": IssueType.DEPENDENCY,
352
+ }
353
+
354
+ # Determine issue type from hook name
355
+ issue_type = IssueType.FORMATTING # Default
356
+ for hook_prefix, mapped_type in issue_type_mapping.items():
357
+ if hook_result.name.lower().startswith(hook_prefix):
358
+ issue_type = mapped_type
359
+ break
360
+
361
+ # Determine severity based on hook status
362
+ severity = Priority.HIGH if hook_result.status == "failed" else Priority.MEDIUM
363
+
364
+ # Create issue
365
+ issue = Issue(
366
+ id=f"{hook_result.id}_{hook_result.name}",
367
+ type=issue_type,
368
+ severity=severity,
369
+ message=f"Hook {hook_result.name} failed",
370
+ details=hook_result.issues_found or [],
371
+ stage=hook_result.stage,
372
+ )
373
+
374
+ return issue
375
+
376
+ def _check_convergence(self, hook_results: dict[str, t.Any]) -> bool:
377
+ """Determine if workflow has converged.
378
+
379
+ Args:
380
+ hook_results: Results from _run_hooks
381
+
382
+ Returns:
383
+ True if converged (all hooks passing)
384
+ """
385
+ return bool(hook_results["all_passing"])
386
+
387
+ def _print_summary(self, result: WorkflowResult) -> None:
388
+ """Print workflow summary to console.
389
+
390
+ Args:
391
+ result: Final workflow result
392
+ """
393
+ self.console.print("\n[bold cyan]━━━ Auto-Fix Summary ━━━[/bold cyan]")
394
+
395
+ # Status
396
+ status_color = "green" if result.success else "yellow"
397
+ status_icon = "✅" if result.success else "⚠️"
398
+ self.console.print(
399
+ f"{status_icon} [bold {status_color}]Status:[/bold {status_color}] {result.final_status}"
400
+ )
401
+
402
+ # Statistics
403
+ self.console.print("📊 [bold]Statistics:[/bold]")
404
+ self.console.print(f" • Iterations: {len(result.iterations)}")
405
+ self.console.print(f" • Total issues found: {result.total_issues_found}")
406
+ self.console.print(f" • Total fixes applied: {result.total_fixes}")
407
+ self.console.print(f" • Total duration: {result.total_duration:.2f}s")
408
+ self.console.print(f" • Exit reason: {result.exit_reason}")
409
+
410
+ # Iteration breakdown
411
+ if result.iterations:
412
+ self.console.print("\n📋 [bold]Iteration Breakdown:[/bold]")
413
+ for iteration in result.iterations:
414
+ status_symbol = "✅" if not iteration.hooks_failing else "❌"
415
+ self.console.print(
416
+ f" {status_symbol} Iteration {iteration.iteration_num}: "
417
+ f"{iteration.fixes_successful}/{iteration.fixes_applied} fixes successful "
418
+ f"({iteration.duration:.2f}s)"
419
+ )
420
+
421
+ self.console.print()
422
+
423
+
424
+ def create_auto_fix_workflow(
425
+ project_path: Path | None = None,
426
+ console: Console | None = None,
427
+ enable_external_agents: bool = True,
428
+ ) -> AutoFixWorkflow:
429
+ """Factory function to create an AutoFixWorkflow.
430
+
431
+ Args:
432
+ project_path: Path to project root (defaults to cwd)
433
+ console: Rich console for output (creates default if None)
434
+ enable_external_agents: Enable Claude Code external agent integration
435
+
436
+ Returns:
437
+ Configured AutoFixWorkflow instance
438
+ """
439
+ return AutoFixWorkflow(
440
+ project_path=project_path,
441
+ console=console,
442
+ enable_external_agents=enable_external_agents,
443
+ )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: crackerjack
3
- Version: 0.39.11
3
+ Version: 0.40.1
4
4
  Summary: Crackerjack Python project management tool
5
5
  Project-URL: documentation, https://github.com/lesleslie/crackerjack
6
6
  Project-URL: homepage, https://github.com/lesleslie/crackerjack
@@ -79,7 +79,7 @@ Description-Content-Type: text/markdown
79
79
  [![uv](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json)](https://github.com/astral-sh/uv)
80
80
  [![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit)](https://github.com/pre-commit/pre-commit)
81
81
  [![License](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause)
82
- ![Coverage](https://img.shields.io/badge/coverage-17.9%25-red)
82
+ ![Coverage](https://img.shields.io/badge/coverage-17.7%25-red)
83
83
 
84
84
  ## 🎯 Purpose
85
85
 
@@ -142,17 +142,17 @@ Crackerjack is built on the following core principles:
142
142
 
143
143
  ## Table of Contents
144
144
 
145
- - \[[#installation|Installation]\]
146
- - \[[#quick-start|Quick Start]\]
147
- - \[[#ai-auto-fix-features|AI Auto-Fix Features]\]
148
- - \[[#core-workflow|Core Workflow]\]
149
- - \[[#core-features|Core Features]\]
150
- - \[[#mcp-server-configuration|MCP Server Configuration]\]
151
- - \[[#pre-commit-hook-modes|Pre-commit Hook Modes]\]
152
- - \[[#command-reference|Command Reference]\]
153
- - \[[#style-guide|Style Guide]\]
154
- - \[[#publishing--version-management|Publishing & Version Management]\]
155
- - \[[#-troubleshooting|Troubleshooting]\]
145
+ - [Installation](<#installation>)
146
+ - [Quick Start](<#quick-start>)
147
+ - [AI Auto-Fix Features](<#ai-auto-fix-features>)
148
+ - [Core Workflow](<#core-workflow>)
149
+ - [Core Features](<#core-features>)
150
+ - [MCP Server Configuration](<#mcp-server-configuration>)
151
+ - [Pre-commit Hook Modes](<#pre-commit-hook-modes>)
152
+ - [Command Reference](<#command-reference>)
153
+ - [Style Guide](<#style-guide>)
154
+ - [Publishing & Version Management](<#publishing--version-management>)
155
+ - [Troubleshooting](<#-troubleshooting>)
156
156
 
157
157
  ## Installation
158
158
 
@@ -241,6 +241,12 @@ The AI agent intelligently fixes:
241
241
  # Standard AI agent mode (recommended)
242
242
  python -m crackerjack --ai-fix --run-tests --verbose
243
243
 
244
+ # Preview fixes without applying (dry-run mode)
245
+ python -m crackerjack --dry-run --run-tests --verbose
246
+
247
+ # Custom iteration limit
248
+ python -m crackerjack --ai-fix --max-iterations 15
249
+
244
250
  # MCP server with WebSocket support (localhost:8675)
245
251
  python -m crackerjack --start-mcp-server
246
252
 
@@ -248,6 +254,43 @@ python -m crackerjack --start-mcp-server
248
254
  python -m crackerjack.mcp.progress_monitor <job_id> ws://localhost:8675
249
255
  ```
250
256
 
257
+ #### MCP Integration
258
+
259
+ When using crackerjack via MCP tools (session-mgmt-mcp):
260
+
261
+ ```python
262
+ # ✅ CORRECT - Use semantic command + ai_agent_mode parameter
263
+ crackerjack_run(command="test", ai_agent_mode=True)
264
+
265
+ # ✅ CORRECT - With additional arguments
266
+ crackerjack_run(command="check", args="--verbose", ai_agent_mode=True, timeout=600)
267
+
268
+ # ✅ CORRECT - Dry-run mode
269
+ crackerjack_run(command="test", args="--dry-run", ai_agent_mode=True)
270
+
271
+ # ❌ WRONG - Don't put flags in command parameter
272
+ crackerjack_run(command="--ai-fix -t") # This will error!
273
+
274
+ # ❌ WRONG - Don't use --ai-fix in args
275
+ crackerjack_run(command="test", args="--ai-fix") # Use ai_agent_mode=True instead
276
+ ```
277
+
278
+ #### Configuration
279
+
280
+ Auto-fix requires:
281
+
282
+ 1. **Anthropic API key**: Set environment variable
283
+
284
+ ```bash
285
+ export ANTHROPIC_API_KEY=sk-ant-...
286
+ ```
287
+
288
+ 1. **Configuration file**: `settings/adapters.yml`
289
+
290
+ ```yaml
291
+ ai: claude
292
+ ```
293
+
251
294
  #### Key Benefits
252
295
 
253
296
  - **Zero Configuration**: No complex flag combinations needed
@@ -736,7 +779,7 @@ python -m crackerjack --ai-fix
736
779
  | **Clear Caches** | `python -m crackerjack --clear-cache` | Reset all cache data |
737
780
  | **Fast Iteration** | `python -m crackerjack --skip-hooks` | Skip quality checks during dev |
738
781
  | **Documentation** | `python -m crackerjack --generate-docs` | Generate API documentation |
739
- | **Advanced Features** | See \[[ADVANCED-FEATURES|ADVANCED-FEATURES.md]\] | 82 enterprise/power user flags |
782
+ | **Advanced Features** | See [ADVANCED-FEATURES.md](<./docs/guides/ADVANCED-FEATURES.md>) | 82 enterprise/power user flags |
740
783
 
741
784
  **📑 Alphabetical Flag Reference**
742
785
 
@@ -777,9 +820,9 @@ python -m crackerjack --ai-fix
777
820
 
778
821
  **🔗 Related Documentation**
779
822
 
780
- - **Advanced Features**: \[[ADVANCED-FEATURES|ADVANCED-FEATURES.md]\] - 82 enterprise/power user flags
781
- - **Developer Guide**: \[[CLAUDE|CLAUDE.md]\] - AI assistant guidelines and developer commands
782
- - **Phase 2 Analysis**: \[[PHASE2-CROSS-REFERENCE-ANALYSIS|docs/PHASE2-CROSS-REFERENCE-ANALYSIS.md]\] - CLI flag audit
823
+ - **Advanced Features**: [ADVANCED-FEATURES.md](<./docs/guides/ADVANCED-FEATURES.md>) - 82 enterprise/power user flags
824
+ - **Developer Guide**: [CLAUDE.md](<./CLAUDE.md>) - AI assistant guidelines and developer commands
825
+ - **Phase 2 Analysis**: [PHASE2-CROSS-REFERENCE-ANALYSIS.md](<./docs/history/phases/PHASE2-CROSS-REFERENCE-ANALYSIS.md>) - CLI flag audit (archived)
783
826
 
784
827
  ______________________________________________________________________
785
828
 
@@ -2,20 +2,22 @@ crackerjack/__init__.py,sha256=DajG9zHB8qBdgdiKMumrrssUbKeMXmtIQ3oOaSTb46Y,1426
2
2
  crackerjack/__main__.py,sha256=jf-77hiq9_OVWFUN3qaX1eiuFEg-GMDRnszwyujx22I,59085
3
3
  crackerjack/api.py,sha256=PyCRaZHvKWdu62_2O4t_HcEfKNBdqyrfPdonS_PNn4c,21495
4
4
  crackerjack/code_cleaner.py,sha256=M1zVaq31uW0nOkPneKR8kfR3892gyyVx0VhFgRaxsj4,44338
5
- crackerjack/dynamic_config.py,sha256=MQpZpTcGeWruPb98XMJrsQWinSgVnZlAh1vPGwcETh8,21757
5
+ crackerjack/dynamic_config.py,sha256=X0KfFfu9vdMl8aCRnJ4qExaMvssPKNBv3NznUOVO0wo,21769
6
6
  crackerjack/errors.py,sha256=yYbZ92kn_y6acEWgQvEPvozAYs2HT65uLwAXrtXxGsE,10049
7
7
  crackerjack/interactive.py,sha256=7hSyCfUxuzyvVUdkO1XsOfeQ5vAlTjIH_TB8o3af-9g,21990
8
8
  crackerjack/py313.py,sha256=TbzL6vJ8kf5GbuAFVjZ6wgfXnhcoLlzwATaFhV8HEVo,6256
9
- crackerjack/adapters/__init__.py,sha256=k-8ajMDL9DS9hV2FYOu694nmNQg3HkudJRuNcXmx8N4,451
9
+ crackerjack/adapters/__init__.py,sha256=SPiokldDNDbwLFxEH2qYpSRuEsM4aEBbhLCleGXFiyc,593
10
10
  crackerjack/adapters/lsp_client.py,sha256=4kQ3T5JiWC7uc6kOjZuPdtUboseKSDjZpuKQpV74onc,10963
11
11
  crackerjack/adapters/rust_tool_adapter.py,sha256=ui_qMt_WIwInRvRCeT7MnIdp8eln7Fvp4hakXQiVnjg,5999
12
12
  crackerjack/adapters/rust_tool_manager.py,sha256=RotOX7WUMAm4GT9bD8xOhSeHFXaME37R9dW-YLTpVcc,6590
13
13
  crackerjack/adapters/skylos_adapter.py,sha256=aUO8P7daTXstM3UxaAKOwZDLdMPIUbjmhmXROTF5RlU,7890
14
14
  crackerjack/adapters/zuban_adapter.py,sha256=NHg2vAsaONEMMlV3a5lmjPm61poIojL-gqZWqoX-R9o,19663
15
+ crackerjack/adapters/ai/__init__.py,sha256=airGrN2riDDdhqM75j4dIOWeFnuINYYzGPns2ZT1CGg,168
16
+ crackerjack/adapters/ai/claude.py,sha256=kQTCC_9tJA3ZXPdZRFjtB_SJYbesA3EdAPm8vm5Tl2k,28895
15
17
  crackerjack/agents/__init__.py,sha256=Mja1iIHEW4wsvci5g6CXHtR1OEltd3N00XOZLUfaHPU,950
16
18
  crackerjack/agents/architect_agent.py,sha256=Gq9eAy1_pl-1iEYC28xn4rdIPi9AVynZ7Sd5FnBrNn8,8130
17
19
  crackerjack/agents/base.py,sha256=qu3wmtFZwXsaf75WXiRdyvJJaNp_EE7MptJQI_7Wd3o,4930
18
- crackerjack/agents/claude_code_bridge.py,sha256=H453vlAcIpa7EH_eytcb7uWv-ezIrFqU6fMGtXQKKPI,12950
20
+ crackerjack/agents/claude_code_bridge.py,sha256=B8tDvU0I5xlioSTkJ9PdpD9utxS9JEfOAz7TuKPQFOI,20606
19
21
  crackerjack/agents/coordinator.py,sha256=jK22whXR6WKe7NWyhQAwTnlPNlNqJigJTn3-COf2Wpc,22637
20
22
  crackerjack/agents/documentation_agent.py,sha256=bI9qPJ5rTZrjimythO_N27zpJFrFcP6i1N2hYZMr_u4,17178
21
23
  crackerjack/agents/dry_agent.py,sha256=mAcwIRCnuf5X6MKMxOaTLx4895VvPVV-CZcnL-DSJOo,20501
@@ -37,10 +39,10 @@ crackerjack/agents/tracker.py,sha256=5Hje7Ox-hSPq2yTqkbucwChEvzwlCQxjgVri0KSUUPY
37
39
  crackerjack/cli/__init__.py,sha256=6pnXZIglNzax4XA2lWfiqAZQs24Dr7GbXUwIwCF_9_w,583
38
40
  crackerjack/cli/cache_handlers.py,sha256=Wa-1ZJdWO7RufLd6Fo62pUTij-a3epFi92h5CfJLlDM,6757
39
41
  crackerjack/cli/cache_handlers_enhanced.py,sha256=6X5rYSo1l-rj9eb7eB8mpA-6BlUagyDu-IvCaHwYy5k,24841
40
- crackerjack/cli/facade.py,sha256=e4_oB04awqEijI3yqiYAZGc6x09uMBa4ih0SsXpgMuY,3751
42
+ crackerjack/cli/facade.py,sha256=VlLaubyWoD19HNjKzdH0hAtH3e2ABoT658JfLRTbVCc,5856
41
43
  crackerjack/cli/handlers.py,sha256=mYhwMLUKid6mQLff0ScpcnhP0yUS9IzOIMdM7VLkUCc,17178
42
44
  crackerjack/cli/interactive.py,sha256=E7WgzgNRlgOuKLbi5Io3RQ3BBXS8sIDiUQcJh6b2x9I,17583
43
- crackerjack/cli/options.py,sha256=DAR2zu40U0pDHJ-fLVyppIHh9Klzsg-c5hqxOJkw-dA,37440
45
+ crackerjack/cli/options.py,sha256=XAyN_Gj_tQH4r9RDZ7CH8FxY4lrCHkha0KEsy0bAcfg,37790
44
46
  crackerjack/cli/semantic_handlers.py,sha256=QrlyKfy3K7wI0mLYv7W4nL9WZ14SA4zqWDUc21jM9is,10103
45
47
  crackerjack/cli/utils.py,sha256=XC7dT8GNidhORjUe2p2hQOpZgCi2KvVCNu6g3azzgqY,584
46
48
  crackerjack/config/__init__.py,sha256=b0481N2f_JvGufMPcbo5IXu2VjYd111r1BHw0oD3x7o,330
@@ -159,7 +161,7 @@ crackerjack/plugins/loader.py,sha256=2U4_vWLXsc7qOji-4dzJDF993EU7p8SH23ijhqMHahY
159
161
  crackerjack/plugins/managers.py,sha256=3kQlxjvcHyHDgZIdr-JZBO1kqz2asqA4kf2XVAA1K6A,8824
160
162
  crackerjack/security/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
161
163
  crackerjack/security/audit.py,sha256=NZJRREvjeKJMhusNZkL8GnBf4XiQFnTwKGcu6NqmvgI,6728
162
- crackerjack/services/__init__.py,sha256=thXyf5Yh6WRsnGjG3onf5Obe1xbd_p72Fm2tIl1IA3s,617
164
+ crackerjack/services/__init__.py,sha256=EJoHoZfGbD8TiuIJgQSE8oFHWjJYufZpMVXwzPneKQk,254
163
165
  crackerjack/services/anomaly_detector.py,sha256=vUwhhGxNGarHQAly4GaN7kc5PBaBvlTfzuvbNYJNf3g,13405
164
166
  crackerjack/services/api_extractor.py,sha256=iN4JDkvSyfHRNlhgV0Sf5B9cg4NVaCZn6p-zQlp9YGU,23836
165
167
  crackerjack/services/backup_service.py,sha256=0e8AAo9svSBtbsbI9vwnAVSilB2fjph61lskgsUvDLk,15528
@@ -183,6 +185,7 @@ crackerjack/services/enhanced_filesystem.py,sha256=IT-obfj2U2Sfy0iJOq0ZAiczEN6Ld
183
185
  crackerjack/services/enterprise_optimizer.py,sha256=q6srIGxe18N9zH-MNhZ9R34sWnr_-ybGqOWnKyI17Zk,33798
184
186
  crackerjack/services/error_pattern_analyzer.py,sha256=YKFQi_nXx5dq-Wvi6AngKEaA-Bv5ggTQ2B2ML0AtF0c,24415
185
187
  crackerjack/services/file_hasher.py,sha256=eReytwwK-_-B8JBnpwytDC52cKKgg4qpaxaZKcQjD-0,5211
188
+ crackerjack/services/file_modifier.py,sha256=mgnr9rROfBGzUowi0vDBhEf3rABfqG-I74su5pqkl90,17013
186
189
  crackerjack/services/filesystem.py,sha256=nmL3mYqylS_BSQpwFbC7EMHoA44K5qUxa9CPg1QFZvc,17480
187
190
  crackerjack/services/git.py,sha256=E4z-hdA0UR-y5FY2A8d3fugt5Q41lonLAIt_op2Zde0,12727
188
191
  crackerjack/services/health_metrics.py,sha256=nDuKEC2a5csOhMpy6zXJkls1Y4Vfrr62-4cFcWCr8ow,21536
@@ -235,8 +238,10 @@ crackerjack/tools/validate_input_validator_patterns.py,sha256=NN7smYlXWrHLQXTb-8
235
238
  crackerjack/tools/validate_regex_patterns.py,sha256=J7GG9EP1fASpRIsG8qRPeiCSkdCwmk0sdo29GgoJ6w8,5863
236
239
  crackerjack/ui/__init__.py,sha256=eMb1OeTU-dSLICAACn0YdYB4Amdr8wHckjKfn0wOIZE,37
237
240
  crackerjack/ui/server_panels.py,sha256=F5IH6SNN06BaZQMsFx_D-OA286aojmaFPJ5kvvSRv_c,4232
238
- crackerjack-0.39.11.dist-info/METADATA,sha256=9c24Ghkza-ehvBuzxolKU6qg63_E3aqFF8sIOznD4qg,42314
239
- crackerjack-0.39.11.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
240
- crackerjack-0.39.11.dist-info/entry_points.txt,sha256=AJKNft0WXm9xoGUJ3Trl-iXHOWxRAYbagQiza3AILr4,57
241
- crackerjack-0.39.11.dist-info/licenses/LICENSE,sha256=fDt371P6_6sCu7RyqiZH_AhT1LdN3sN1zjBtqEhDYCk,1531
242
- crackerjack-0.39.11.dist-info/RECORD,,
241
+ crackerjack/workflows/__init__.py,sha256=jaJdTSPM_zKREXp7F6nUlk9tTrKHaWC8UqlXZbHBRkE,292
242
+ crackerjack/workflows/auto_fix.py,sha256=q-3yQB_cHc-kgiG0BmPrwK-R3x3TJFqs63Uy5H9yKC0,16037
243
+ crackerjack-0.40.1.dist-info/METADATA,sha256=AEJAbxiemr1z-Wb3RhqAwMEInCLryj8cPu18N3UwprE,43456
244
+ crackerjack-0.40.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
245
+ crackerjack-0.40.1.dist-info/entry_points.txt,sha256=AJKNft0WXm9xoGUJ3Trl-iXHOWxRAYbagQiza3AILr4,57
246
+ crackerjack-0.40.1.dist-info/licenses/LICENSE,sha256=fDt371P6_6sCu7RyqiZH_AhT1LdN3sN1zjBtqEhDYCk,1531
247
+ crackerjack-0.40.1.dist-info/RECORD,,