crackerjack 0.30.3__py3-none-any.whl → 0.31.7__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.
- crackerjack/CLAUDE.md +1005 -0
- crackerjack/RULES.md +380 -0
- crackerjack/__init__.py +42 -13
- crackerjack/__main__.py +227 -299
- crackerjack/agents/__init__.py +41 -0
- crackerjack/agents/architect_agent.py +281 -0
- crackerjack/agents/base.py +170 -0
- crackerjack/agents/coordinator.py +512 -0
- crackerjack/agents/documentation_agent.py +498 -0
- crackerjack/agents/dry_agent.py +388 -0
- crackerjack/agents/formatting_agent.py +245 -0
- crackerjack/agents/import_optimization_agent.py +281 -0
- crackerjack/agents/performance_agent.py +669 -0
- crackerjack/agents/proactive_agent.py +104 -0
- crackerjack/agents/refactoring_agent.py +788 -0
- crackerjack/agents/security_agent.py +529 -0
- crackerjack/agents/test_creation_agent.py +657 -0
- crackerjack/agents/test_specialist_agent.py +486 -0
- crackerjack/agents/tracker.py +212 -0
- crackerjack/api.py +560 -0
- crackerjack/cli/__init__.py +24 -0
- crackerjack/cli/facade.py +104 -0
- crackerjack/cli/handlers.py +267 -0
- crackerjack/cli/interactive.py +471 -0
- crackerjack/cli/options.py +409 -0
- crackerjack/cli/utils.py +18 -0
- crackerjack/code_cleaner.py +618 -928
- crackerjack/config/__init__.py +19 -0
- crackerjack/config/hooks.py +218 -0
- crackerjack/core/__init__.py +0 -0
- crackerjack/core/async_workflow_orchestrator.py +406 -0
- crackerjack/core/autofix_coordinator.py +200 -0
- crackerjack/core/container.py +104 -0
- crackerjack/core/enhanced_container.py +542 -0
- crackerjack/core/performance.py +243 -0
- crackerjack/core/phase_coordinator.py +585 -0
- crackerjack/core/proactive_workflow.py +316 -0
- crackerjack/core/session_coordinator.py +289 -0
- crackerjack/core/workflow_orchestrator.py +826 -0
- crackerjack/dynamic_config.py +94 -103
- crackerjack/errors.py +263 -41
- crackerjack/executors/__init__.py +11 -0
- crackerjack/executors/async_hook_executor.py +431 -0
- crackerjack/executors/cached_hook_executor.py +242 -0
- crackerjack/executors/hook_executor.py +345 -0
- crackerjack/executors/individual_hook_executor.py +669 -0
- crackerjack/intelligence/__init__.py +44 -0
- crackerjack/intelligence/adaptive_learning.py +751 -0
- crackerjack/intelligence/agent_orchestrator.py +551 -0
- crackerjack/intelligence/agent_registry.py +414 -0
- crackerjack/intelligence/agent_selector.py +502 -0
- crackerjack/intelligence/integration.py +290 -0
- crackerjack/interactive.py +576 -315
- crackerjack/managers/__init__.py +11 -0
- crackerjack/managers/async_hook_manager.py +135 -0
- crackerjack/managers/hook_manager.py +137 -0
- crackerjack/managers/publish_manager.py +433 -0
- crackerjack/managers/test_command_builder.py +151 -0
- crackerjack/managers/test_executor.py +443 -0
- crackerjack/managers/test_manager.py +258 -0
- crackerjack/managers/test_manager_backup.py +1124 -0
- crackerjack/managers/test_progress.py +114 -0
- crackerjack/mcp/__init__.py +0 -0
- crackerjack/mcp/cache.py +336 -0
- crackerjack/mcp/client_runner.py +104 -0
- crackerjack/mcp/context.py +621 -0
- crackerjack/mcp/dashboard.py +636 -0
- crackerjack/mcp/enhanced_progress_monitor.py +479 -0
- crackerjack/mcp/file_monitor.py +336 -0
- crackerjack/mcp/progress_components.py +569 -0
- crackerjack/mcp/progress_monitor.py +949 -0
- crackerjack/mcp/rate_limiter.py +332 -0
- crackerjack/mcp/server.py +22 -0
- crackerjack/mcp/server_core.py +244 -0
- crackerjack/mcp/service_watchdog.py +501 -0
- crackerjack/mcp/state.py +395 -0
- crackerjack/mcp/task_manager.py +257 -0
- crackerjack/mcp/tools/__init__.py +17 -0
- crackerjack/mcp/tools/core_tools.py +249 -0
- crackerjack/mcp/tools/error_analyzer.py +308 -0
- crackerjack/mcp/tools/execution_tools.py +372 -0
- crackerjack/mcp/tools/execution_tools_backup.py +1097 -0
- crackerjack/mcp/tools/intelligence_tool_registry.py +80 -0
- crackerjack/mcp/tools/intelligence_tools.py +314 -0
- crackerjack/mcp/tools/monitoring_tools.py +502 -0
- crackerjack/mcp/tools/proactive_tools.py +384 -0
- crackerjack/mcp/tools/progress_tools.py +217 -0
- crackerjack/mcp/tools/utility_tools.py +341 -0
- crackerjack/mcp/tools/workflow_executor.py +565 -0
- crackerjack/mcp/websocket/__init__.py +14 -0
- crackerjack/mcp/websocket/app.py +39 -0
- crackerjack/mcp/websocket/endpoints.py +559 -0
- crackerjack/mcp/websocket/jobs.py +253 -0
- crackerjack/mcp/websocket/server.py +116 -0
- crackerjack/mcp/websocket/websocket_handler.py +78 -0
- crackerjack/mcp/websocket_server.py +10 -0
- crackerjack/models/__init__.py +31 -0
- crackerjack/models/config.py +93 -0
- crackerjack/models/config_adapter.py +230 -0
- crackerjack/models/protocols.py +118 -0
- crackerjack/models/task.py +154 -0
- crackerjack/monitoring/ai_agent_watchdog.py +450 -0
- crackerjack/monitoring/regression_prevention.py +638 -0
- crackerjack/orchestration/__init__.py +0 -0
- crackerjack/orchestration/advanced_orchestrator.py +970 -0
- crackerjack/orchestration/coverage_improvement.py +223 -0
- crackerjack/orchestration/execution_strategies.py +341 -0
- crackerjack/orchestration/test_progress_streamer.py +636 -0
- crackerjack/plugins/__init__.py +15 -0
- crackerjack/plugins/base.py +200 -0
- crackerjack/plugins/hooks.py +246 -0
- crackerjack/plugins/loader.py +335 -0
- crackerjack/plugins/managers.py +259 -0
- crackerjack/py313.py +8 -3
- crackerjack/services/__init__.py +22 -0
- crackerjack/services/cache.py +314 -0
- crackerjack/services/config.py +358 -0
- crackerjack/services/config_integrity.py +99 -0
- crackerjack/services/contextual_ai_assistant.py +516 -0
- crackerjack/services/coverage_ratchet.py +356 -0
- crackerjack/services/debug.py +736 -0
- crackerjack/services/dependency_monitor.py +617 -0
- crackerjack/services/enhanced_filesystem.py +439 -0
- crackerjack/services/file_hasher.py +151 -0
- crackerjack/services/filesystem.py +421 -0
- crackerjack/services/git.py +176 -0
- crackerjack/services/health_metrics.py +611 -0
- crackerjack/services/initialization.py +873 -0
- crackerjack/services/log_manager.py +286 -0
- crackerjack/services/logging.py +174 -0
- crackerjack/services/metrics.py +578 -0
- crackerjack/services/pattern_cache.py +362 -0
- crackerjack/services/pattern_detector.py +515 -0
- crackerjack/services/performance_benchmarks.py +653 -0
- crackerjack/services/security.py +163 -0
- crackerjack/services/server_manager.py +234 -0
- crackerjack/services/smart_scheduling.py +144 -0
- crackerjack/services/tool_version_service.py +61 -0
- crackerjack/services/unified_config.py +437 -0
- crackerjack/services/version_checker.py +248 -0
- crackerjack/slash_commands/__init__.py +14 -0
- crackerjack/slash_commands/init.md +122 -0
- crackerjack/slash_commands/run.md +163 -0
- crackerjack/slash_commands/status.md +127 -0
- crackerjack-0.31.7.dist-info/METADATA +742 -0
- crackerjack-0.31.7.dist-info/RECORD +149 -0
- crackerjack-0.31.7.dist-info/entry_points.txt +2 -0
- crackerjack/.gitignore +0 -34
- crackerjack/.libcst.codemod.yaml +0 -18
- crackerjack/.pdm.toml +0 -1
- crackerjack/crackerjack.py +0 -3805
- crackerjack/pyproject.toml +0 -286
- crackerjack-0.30.3.dist-info/METADATA +0 -1290
- crackerjack-0.30.3.dist-info/RECORD +0 -16
- {crackerjack-0.30.3.dist-info → crackerjack-0.31.7.dist-info}/WHEEL +0 -0
- {crackerjack-0.30.3.dist-info → crackerjack-0.31.7.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
from .async_hook_manager import AsyncHookManager
|
|
2
|
+
from .hook_manager import HookManagerImpl
|
|
3
|
+
from .publish_manager import PublishManagerImpl
|
|
4
|
+
from .test_manager import TestManagementImpl
|
|
5
|
+
|
|
6
|
+
__all__ = [
|
|
7
|
+
"AsyncHookManager",
|
|
8
|
+
"HookManagerImpl",
|
|
9
|
+
"PublishManagerImpl",
|
|
10
|
+
"TestManagementImpl",
|
|
11
|
+
]
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import typing as t
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
from rich.console import Console
|
|
6
|
+
|
|
7
|
+
from crackerjack.config.hooks import HookConfigLoader
|
|
8
|
+
from crackerjack.executors.async_hook_executor import AsyncHookExecutor
|
|
9
|
+
from crackerjack.models.task import HookResult
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class AsyncHookManager:
|
|
13
|
+
def __init__(
|
|
14
|
+
self,
|
|
15
|
+
console: Console,
|
|
16
|
+
pkg_path: Path,
|
|
17
|
+
max_concurrent: int = 3,
|
|
18
|
+
) -> None:
|
|
19
|
+
self.console = console
|
|
20
|
+
self.pkg_path = pkg_path
|
|
21
|
+
self.async_executor = AsyncHookExecutor(
|
|
22
|
+
console,
|
|
23
|
+
pkg_path,
|
|
24
|
+
max_concurrent=max_concurrent,
|
|
25
|
+
quiet=True,
|
|
26
|
+
)
|
|
27
|
+
self.config_loader = HookConfigLoader()
|
|
28
|
+
|
|
29
|
+
async def run_fast_hooks_async(self) -> list[HookResult]:
|
|
30
|
+
strategy = self.config_loader.load_strategy("fast")
|
|
31
|
+
|
|
32
|
+
strategy.parallel = False
|
|
33
|
+
|
|
34
|
+
execution_result = await self.async_executor.execute_strategy(strategy)
|
|
35
|
+
return execution_result.results
|
|
36
|
+
|
|
37
|
+
async def run_comprehensive_hooks_async(self) -> list[HookResult]:
|
|
38
|
+
strategy = self.config_loader.load_strategy("comprehensive")
|
|
39
|
+
|
|
40
|
+
strategy.parallel = True
|
|
41
|
+
strategy.max_workers = 3
|
|
42
|
+
|
|
43
|
+
execution_result = await self.async_executor.execute_strategy(strategy)
|
|
44
|
+
return execution_result.results
|
|
45
|
+
|
|
46
|
+
def run_fast_hooks(self) -> list[HookResult]:
|
|
47
|
+
return asyncio.run(self.run_fast_hooks_async())
|
|
48
|
+
|
|
49
|
+
def run_comprehensive_hooks(self) -> list[HookResult]:
|
|
50
|
+
return asyncio.run(self.run_comprehensive_hooks_async())
|
|
51
|
+
|
|
52
|
+
async def install_hooks_async(self) -> bool:
|
|
53
|
+
try:
|
|
54
|
+
process = await asyncio.create_subprocess_exec(
|
|
55
|
+
"pre-commit",
|
|
56
|
+
"install",
|
|
57
|
+
cwd=self.pkg_path,
|
|
58
|
+
stdout=asyncio.subprocess.PIPE,
|
|
59
|
+
stderr=asyncio.subprocess.PIPE,
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
_, stderr = await asyncio.wait_for(process.communicate(), timeout=30)
|
|
63
|
+
|
|
64
|
+
if process.returncode == 0:
|
|
65
|
+
self.console.print("[green]✅[/green] Pre-commit hooks installed")
|
|
66
|
+
return True
|
|
67
|
+
error_msg = stderr.decode() if stderr else "Unknown error"
|
|
68
|
+
self.console.print(
|
|
69
|
+
f"[red]❌[/red] Failed to install hooks: {error_msg}",
|
|
70
|
+
)
|
|
71
|
+
return False
|
|
72
|
+
|
|
73
|
+
except TimeoutError:
|
|
74
|
+
self.console.print("[red]❌[/red] Hook installation timed out")
|
|
75
|
+
return False
|
|
76
|
+
except Exception as e:
|
|
77
|
+
self.console.print(f"[red]❌[/red] Error installing hooks: {e}")
|
|
78
|
+
return False
|
|
79
|
+
|
|
80
|
+
def install_hooks(self) -> bool:
|
|
81
|
+
return asyncio.run(self.install_hooks_async())
|
|
82
|
+
|
|
83
|
+
async def update_hooks_async(self) -> bool:
|
|
84
|
+
try:
|
|
85
|
+
process = await asyncio.create_subprocess_exec(
|
|
86
|
+
"pre-commit",
|
|
87
|
+
"autoupdate",
|
|
88
|
+
cwd=self.pkg_path,
|
|
89
|
+
stdout=asyncio.subprocess.PIPE,
|
|
90
|
+
stderr=asyncio.subprocess.PIPE,
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
_, stderr = await asyncio.wait_for(process.communicate(), timeout=60)
|
|
94
|
+
|
|
95
|
+
if process.returncode == 0:
|
|
96
|
+
self.console.print("[green]✅[/green] Pre-commit hooks updated")
|
|
97
|
+
return True
|
|
98
|
+
error_msg = stderr.decode() if stderr else "Unknown error"
|
|
99
|
+
self.console.print(f"[red]❌[/red] Failed to update hooks: {error_msg}")
|
|
100
|
+
return False
|
|
101
|
+
|
|
102
|
+
except TimeoutError:
|
|
103
|
+
self.console.print("[red]❌[/red] Hook update timed out")
|
|
104
|
+
return False
|
|
105
|
+
except Exception as e:
|
|
106
|
+
self.console.print(f"[red]❌[/red] Error updating hooks: {e}")
|
|
107
|
+
return False
|
|
108
|
+
|
|
109
|
+
def update_hooks(self) -> bool:
|
|
110
|
+
return asyncio.run(self.update_hooks_async())
|
|
111
|
+
|
|
112
|
+
def get_hook_summary(self, results: list[HookResult]) -> dict[str, t.Any]:
|
|
113
|
+
if not results:
|
|
114
|
+
return {
|
|
115
|
+
"total": 0,
|
|
116
|
+
"passed": 0,
|
|
117
|
+
"failed": 0,
|
|
118
|
+
"errors": 0,
|
|
119
|
+
"total_duration": 0,
|
|
120
|
+
"success_rate": 0,
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
passed = sum(1 for r in results if r.status == "passed")
|
|
124
|
+
failed = sum(1 for r in results if r.status == "failed")
|
|
125
|
+
errors = sum(1 for r in results if r.status in ("timeout", "error"))
|
|
126
|
+
total_duration = sum(r.duration for r in results)
|
|
127
|
+
|
|
128
|
+
return {
|
|
129
|
+
"total": len(results),
|
|
130
|
+
"passed": passed,
|
|
131
|
+
"failed": failed,
|
|
132
|
+
"errors": errors,
|
|
133
|
+
"total_duration": total_duration,
|
|
134
|
+
"success_rate": (passed / len(results)) * 100 if results else 0,
|
|
135
|
+
}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import subprocess
|
|
2
|
+
import typing as t
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
from rich.console import Console
|
|
6
|
+
|
|
7
|
+
from crackerjack.config.hooks import HookConfigLoader
|
|
8
|
+
from crackerjack.executors.hook_executor import HookExecutor
|
|
9
|
+
from crackerjack.models.task import HookResult
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class HookManagerImpl:
|
|
13
|
+
def __init__(
|
|
14
|
+
self,
|
|
15
|
+
console: Console,
|
|
16
|
+
pkg_path: Path,
|
|
17
|
+
verbose: bool = False,
|
|
18
|
+
quiet: bool = False,
|
|
19
|
+
) -> None:
|
|
20
|
+
self.console = console
|
|
21
|
+
self.pkg_path = pkg_path
|
|
22
|
+
self.executor = HookExecutor(console, pkg_path, verbose, quiet)
|
|
23
|
+
self.config_loader = HookConfigLoader()
|
|
24
|
+
self._config_path: Path | None = None
|
|
25
|
+
|
|
26
|
+
def set_config_path(self, config_path: Path) -> None:
|
|
27
|
+
self._config_path = config_path
|
|
28
|
+
|
|
29
|
+
def run_fast_hooks(self) -> list[HookResult]:
|
|
30
|
+
strategy = self.config_loader.load_strategy("fast")
|
|
31
|
+
|
|
32
|
+
if self._config_path:
|
|
33
|
+
for hook in strategy.hooks:
|
|
34
|
+
hook.config_path = self._config_path
|
|
35
|
+
execution_result = self.executor.execute_strategy(strategy)
|
|
36
|
+
return execution_result.results
|
|
37
|
+
|
|
38
|
+
def run_comprehensive_hooks(self) -> list[HookResult]:
|
|
39
|
+
strategy = self.config_loader.load_strategy("comprehensive")
|
|
40
|
+
|
|
41
|
+
if self._config_path:
|
|
42
|
+
for hook in strategy.hooks:
|
|
43
|
+
hook.config_path = self._config_path
|
|
44
|
+
execution_result = self.executor.execute_strategy(strategy)
|
|
45
|
+
return execution_result.results
|
|
46
|
+
|
|
47
|
+
def run_hooks(self) -> list[HookResult]:
|
|
48
|
+
fast_results = self.run_fast_hooks()
|
|
49
|
+
comprehensive_results = self.run_comprehensive_hooks()
|
|
50
|
+
return fast_results + comprehensive_results
|
|
51
|
+
|
|
52
|
+
def validate_hooks_config(self) -> bool:
|
|
53
|
+
try:
|
|
54
|
+
result = subprocess.run(
|
|
55
|
+
["pre-commit", "validate-config"],
|
|
56
|
+
cwd=self.pkg_path,
|
|
57
|
+
capture_output=True,
|
|
58
|
+
text=True,
|
|
59
|
+
check=False,
|
|
60
|
+
)
|
|
61
|
+
return result.returncode == 0
|
|
62
|
+
except Exception:
|
|
63
|
+
return False
|
|
64
|
+
|
|
65
|
+
def get_hook_ids(self) -> list[str]:
|
|
66
|
+
fast_strategy = self.config_loader.load_strategy("fast")
|
|
67
|
+
comprehensive_strategy = self.config_loader.load_strategy("comprehensive")
|
|
68
|
+
|
|
69
|
+
all_hooks = fast_strategy.hooks + comprehensive_strategy.hooks
|
|
70
|
+
return [hook.name for hook in all_hooks]
|
|
71
|
+
|
|
72
|
+
def install_hooks(self) -> bool:
|
|
73
|
+
try:
|
|
74
|
+
result = subprocess.run(
|
|
75
|
+
["pre-commit", "install"],
|
|
76
|
+
check=False,
|
|
77
|
+
cwd=self.pkg_path,
|
|
78
|
+
capture_output=True,
|
|
79
|
+
text=True,
|
|
80
|
+
timeout=30,
|
|
81
|
+
)
|
|
82
|
+
if result.returncode == 0:
|
|
83
|
+
self.console.print("[green]✅[/green] Pre-commit hooks installed")
|
|
84
|
+
return True
|
|
85
|
+
self.console.print(
|
|
86
|
+
f"[red]❌[/red] Failed to install hooks: {result.stderr}",
|
|
87
|
+
)
|
|
88
|
+
return False
|
|
89
|
+
except Exception as e:
|
|
90
|
+
self.console.print(f"[red]❌[/red] Error installing hooks: {e}")
|
|
91
|
+
return False
|
|
92
|
+
|
|
93
|
+
def update_hooks(self) -> bool:
|
|
94
|
+
try:
|
|
95
|
+
result = subprocess.run(
|
|
96
|
+
["pre-commit", "autoupdate"],
|
|
97
|
+
check=False,
|
|
98
|
+
cwd=self.pkg_path,
|
|
99
|
+
capture_output=True,
|
|
100
|
+
text=True,
|
|
101
|
+
timeout=60,
|
|
102
|
+
)
|
|
103
|
+
if result.returncode == 0:
|
|
104
|
+
self.console.print("[green]✅[/green] Pre-commit hooks updated")
|
|
105
|
+
return True
|
|
106
|
+
self.console.print(
|
|
107
|
+
f"[red]❌[/red] Failed to update hooks: {result.stderr}",
|
|
108
|
+
)
|
|
109
|
+
return False
|
|
110
|
+
except Exception as e:
|
|
111
|
+
self.console.print(f"[red]❌[/red] Error updating hooks: {e}")
|
|
112
|
+
return False
|
|
113
|
+
|
|
114
|
+
def get_hook_summary(self, results: list[HookResult]) -> dict[str, t.Any]:
|
|
115
|
+
if not results:
|
|
116
|
+
return {
|
|
117
|
+
"total": 0,
|
|
118
|
+
"passed": 0,
|
|
119
|
+
"failed": 0,
|
|
120
|
+
"errors": 0,
|
|
121
|
+
"total_duration": 0,
|
|
122
|
+
"success_rate": 0,
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
passed = sum(1 for r in results if r.status == "passed")
|
|
126
|
+
failed = sum(1 for r in results if r.status == "failed")
|
|
127
|
+
errors = sum(1 for r in results if r.status in ("timeout", "error"))
|
|
128
|
+
total_duration = sum(r.duration for r in results)
|
|
129
|
+
|
|
130
|
+
return {
|
|
131
|
+
"total": len(results),
|
|
132
|
+
"passed": passed,
|
|
133
|
+
"failed": failed,
|
|
134
|
+
"errors": errors,
|
|
135
|
+
"total_duration": total_duration,
|
|
136
|
+
"success_rate": (passed / len(results)) * 100 if results else 0,
|
|
137
|
+
}
|