crackerjack 0.37.8__py3-none-any.whl → 0.38.0__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.

@@ -23,9 +23,7 @@ def main() -> int:
23
23
 
24
24
  # If no files specified, check project files
25
25
  if not files_to_check:
26
- project_path = Path.cwd()
27
- lsp_client = LSPClient(console)
28
- files_to_check = lsp_client.get_project_files(project_path)
26
+ files_to_check = _get_project_files(console)
29
27
 
30
28
  if not files_to_check:
31
29
  console.print("🔍 No Python files to check")
@@ -36,29 +34,46 @@ def main() -> int:
36
34
 
37
35
  # Check if LSP server is running
38
36
  if not lsp_client.is_server_running():
39
- console.print(
40
- "⚠️ Zuban LSP server not running, falling back to direct zuban check"
41
- )
42
- # Fall back to regular zuban execution
43
- import subprocess
44
-
45
- try:
46
- result = subprocess.run(
47
- ["zuban", "check"] + files_to_check,
48
- capture_output=True,
49
- text=True,
50
- timeout=120,
51
- )
52
- if result.stdout:
53
- console.print(result.stdout)
54
- if result.stderr:
55
- console.print(result.stderr, style="red")
56
- return result.returncode
57
- except (subprocess.TimeoutExpired, FileNotFoundError) as e:
58
- console.print(f"❌ Error running zuban: {e}", style="red")
59
- return 1
37
+ return _fallback_to_zuban_check(console, files_to_check)
60
38
 
61
39
  # Use LSP server for type checking
40
+ return _check_files_with_lsp(console, lsp_client, files_to_check)
41
+
42
+
43
+ def _get_project_files(console: Console) -> list[str]:
44
+ """Get project files to check."""
45
+ project_path = Path.cwd()
46
+ lsp_client = LSPClient(console)
47
+ return lsp_client.get_project_files(project_path)
48
+
49
+
50
+ def _fallback_to_zuban_check(console: Console, files_to_check: list[str]) -> int:
51
+ """Fall back to regular zuban execution when LSP server is not running."""
52
+ console.print("⚠️ Zuban LSP server not running, falling back to direct zuban check")
53
+ # Fall back to regular zuban execution
54
+ import subprocess
55
+
56
+ try:
57
+ result = subprocess.run(
58
+ ["zuban", "check"] + files_to_check,
59
+ capture_output=True,
60
+ text=True,
61
+ timeout=120,
62
+ )
63
+ if result.stdout:
64
+ console.print(result.stdout)
65
+ if result.stderr:
66
+ console.print(result.stderr, style="red")
67
+ return result.returncode
68
+ except (subprocess.TimeoutExpired, FileNotFoundError) as e:
69
+ console.print(f"❌ Error running zuban: {e}", style="red")
70
+ return 1
71
+
72
+
73
+ def _check_files_with_lsp(
74
+ console: Console, lsp_client: LSPClient, files_to_check: list[str]
75
+ ) -> int:
76
+ """Check files using LSP server."""
62
77
  server_info = lsp_client.get_server_info()
63
78
  if server_info:
64
79
  console.print(f"🔍 Using Zuban LSP server (PID: {server_info['pid']})")
@@ -24,7 +24,7 @@ class TaskStatus(Enum):
24
24
 
25
25
 
26
26
  @dataclass
27
- class WorkflowOptions:
27
+ class InteractiveWorkflowOptions:
28
28
  clean: bool = False
29
29
  test: bool = False
30
30
  publish: str | None = None
@@ -35,25 +35,14 @@ class WorkflowOptions:
35
35
  dry_run: bool = False
36
36
 
37
37
  @classmethod
38
- def from_args(cls, args: t.Any) -> "WorkflowOptions":
38
+ def from_args(cls, args: t.Any) -> "InteractiveWorkflowOptions":
39
39
  return cls(
40
- cleaning=CleaningConfig(
41
- clean=getattr(args, "clean", False),
42
- ),
43
- testing=TestConfig(
44
- test=getattr(args, "test", False),
45
- ),
46
- publishing=PublishConfig(
47
- publish=getattr(args, "publish", None),
48
- bump=getattr(args, "bump", None),
49
- ),
50
- git=GitConfig(
51
- commit=getattr(args, "commit", False),
52
- create_pr=getattr(args, "create_pr", False),
53
- ),
54
- ai=AIConfig(
55
- ai_agent=getattr(args, "ai_agent", False),
56
- ),
40
+ clean=getattr(args, "clean", False),
41
+ test=getattr(args, "test", False),
42
+ publish=getattr(args, "publish", None),
43
+ bump=getattr(args, "bump", None),
44
+ commit=getattr(args, "commit", False),
45
+ create_pr=getattr(args, "create_pr", False),
57
46
  interactive=getattr(args, "interactive", True),
58
47
  dry_run=getattr(args, "dry_run", False),
59
48
  )
@@ -410,7 +399,7 @@ class InteractiveCLI:
410
399
 
411
400
  self.logger = logging.getLogger("crackerjack.interactive.cli")
412
401
 
413
- def create_dynamic_workflow(self, options: WorkflowOptions) -> None:
402
+ def create_dynamic_workflow(self, options: InteractiveWorkflowOptions) -> None:
414
403
  builder = WorkflowBuilder(self.console)
415
404
 
416
405
  workflow_steps = [
@@ -592,7 +581,7 @@ class InteractiveCLI:
592
581
  or last_task
593
582
  )
594
583
 
595
- def run_interactive_workflow(self, options: WorkflowOptions) -> bool:
584
+ def run_interactive_workflow(self, options: InteractiveWorkflowOptions) -> bool:
596
585
  self.logger.info(
597
586
  f"Starting interactive workflow with options: {options.__dict__}",
598
587
  )
@@ -693,7 +682,9 @@ def launch_interactive_cli(version: str, options: t.Any = None) -> None:
693
682
  console.print()
694
683
 
695
684
  workflow_options = (
696
- WorkflowOptions.from_args(options) if options else WorkflowOptions()
685
+ InteractiveWorkflowOptions.from_args(options)
686
+ if options
687
+ else InteractiveWorkflowOptions()
697
688
  )
698
689
  cli.create_dynamic_workflow(workflow_options)
699
690
  cli.run_interactive_workflow(workflow_options)
@@ -124,7 +124,7 @@ class PublishManagerImpl:
124
124
 
125
125
  # Get intelligent version analysis and recommendation
126
126
  recommendation = self._get_version_recommendation()
127
- if recommendation and version_type not in ["interactive"]:
127
+ if recommendation and version_type != "interactive":
128
128
  self._display_version_analysis(recommendation)
129
129
  if version_type == "auto":
130
130
  version_type = recommendation.bump_type.value
@@ -812,24 +812,23 @@ def _register_agent_suggestions_tool(mcp_app: t.Any) -> None:
812
812
  t.cast(list[str], suggestions["usage_patterns"])
813
813
 
814
814
  if project_type.lower() == "python" or "python" in task_description.lower():
815
- primary_agents.append(
816
- {
817
- "name": "crackerjack-architect",
818
- "emoji": "🏗️",
819
- "description": "Expert in crackerjack's modular architecture and Python project management patterns",
820
- "usage": "Use PROACTIVELY for all feature development, architectural decisions, and ensuring code follows crackerjack standards",
821
- "priority": "HIGH",
822
- }
823
- )
824
-
825
- primary_agents.append(
826
- {
827
- "name": "python-pro",
828
- "emoji": "🐍",
829
- "description": "Modern Python development with type hints, async/await patterns, and clean architecture",
830
- "usage": "Use for implementing Python code with best practices",
831
- "priority": "HIGH",
832
- }
815
+ primary_agents.extend(
816
+ (
817
+ {
818
+ "name": "crackerjack-architect",
819
+ "emoji": "🏗️",
820
+ "description": "Expert in crackerjack's modular architecture and Python project management patterns",
821
+ "usage": "Use PROACTIVELY for all feature development, architectural decisions, and ensuring code follows crackerjack standards",
822
+ "priority": "HIGH",
823
+ },
824
+ {
825
+ "name": "python-pro",
826
+ "emoji": "🐍",
827
+ "description": "Modern Python development with type hints, async/await patterns, and clean architecture",
828
+ "usage": "Use for implementing Python code with best practices",
829
+ "priority": "HIGH",
830
+ },
831
+ )
833
832
  )
834
833
 
835
834
  task_lower = task_description.lower()
@@ -839,24 +838,23 @@ def _register_agent_suggestions_tool(mcp_app: t.Any) -> None:
839
838
  word in task_lower + context_lower
840
839
  for word in ("test", "testing", "coverage", "pytest")
841
840
  ):
842
- task_specific_agents.append(
843
- {
844
- "name": "crackerjack-test-specialist",
845
- "emoji": "🧪",
846
- "description": "Advanced testing specialist for complex scenarios and coverage optimization",
847
- "usage": "Use for test creation, debugging test failures, and coverage improvements",
848
- "priority": "HIGH",
849
- }
850
- )
851
-
852
- task_specific_agents.append(
853
- {
854
- "name": "pytest-hypothesis-specialist",
855
- "emoji": "🧪",
856
- "description": "Advanced testing patterns and property-based testing",
857
- "usage": "Use for comprehensive test development and optimization",
858
- "priority": "MEDIUM",
859
- }
841
+ task_specific_agents.extend(
842
+ (
843
+ {
844
+ "name": "crackerjack-test-specialist",
845
+ "emoji": "🧪",
846
+ "description": "Advanced testing specialist for complex scenarios and coverage optimization",
847
+ "usage": "Use for test creation, debugging test failures, and coverage improvements",
848
+ "priority": "HIGH",
849
+ },
850
+ {
851
+ "name": "pytest-hypothesis-specialist",
852
+ "emoji": "🧪",
853
+ "description": "Advanced testing patterns and property-based testing",
854
+ "usage": "Use for comprehensive test development and optimization",
855
+ "priority": "MEDIUM",
856
+ },
857
+ )
860
858
  )
861
859
 
862
860
  if any(
@@ -133,7 +133,7 @@ class CustomHookPlugin(HookPluginBase):
133
133
  return HookResult(
134
134
  name=hook_def.name,
135
135
  status="failed",
136
- message="Hook command is None",
136
+ issues_found=["Hook command is None"],
137
137
  duration=0.0,
138
138
  )
139
139
  cmd = hook_def.command.copy()
@@ -310,7 +310,7 @@ class ConfigMergeService(ConfigMergeServiceProtocol):
310
310
  sort_keys=False,
311
311
  width=float("inf"),
312
312
  )
313
- content = yaml_content or ""
313
+ content = yaml_content
314
314
 
315
315
  from crackerjack.services.filesystem import FileSystemService
316
316
 
@@ -506,35 +506,38 @@ class ConfigMergeService(ConfigMergeServiceProtocol):
506
506
  processed_repos = []
507
507
  for repo in repos:
508
508
  processed_repo = copy.deepcopy(repo)
509
-
510
- # Process hooks within each repo
511
- hooks = processed_repo.get("hooks", [])
512
- for hook in hooks:
513
- if isinstance(hook, dict):
514
- # Replace crackerjack directory references in args
515
- if "args" in hook:
516
- hook["args"] = [
517
- arg.replace("crackerjack", project_name)
518
- if isinstance(arg, str)
519
- else arg
520
- for arg in hook["args"]
521
- ]
522
-
523
- # Replace crackerjack directory references in files pattern
524
- if "files" in hook:
525
- files_pattern = hook["files"]
526
- if isinstance(files_pattern, str):
527
- hook["files"] = files_pattern.replace(
528
- "^crackerjack/", f"^{project_name}/"
529
- )
530
-
531
- # Special handling for validate-regex-patterns hook - keep it pointing to crackerjack package
532
- if hook.get("id") == "validate-regex-patterns":
533
- # This should reference the installed crackerjack package, not the current project
534
- # The entry already uses "uv run python -m crackerjack.tools.validate_regex_patterns"
535
- # which is correct - it runs from the installed crackerjack package
536
- pass
537
-
509
+ self._process_repo_hooks(processed_repo, project_name)
538
510
  processed_repos.append(processed_repo)
539
511
 
540
512
  return processed_repos
513
+
514
+ def _process_repo_hooks(self, repo: dict[str, t.Any], project_name: str) -> None:
515
+ """Process hooks within a repo to replace project-specific references."""
516
+ hooks = repo.get("hooks", [])
517
+ for hook in hooks:
518
+ if isinstance(hook, dict):
519
+ self._process_hook_args(hook, project_name)
520
+ self._process_hook_files(hook, project_name)
521
+ # Special handling for validate-regex-patterns hook - keep it pointing to crackerjack package
522
+ # This should reference the installed crackerjack package, not the current project
523
+ # The entry already uses "uv run python -m crackerjack.tools.validate_regex_patterns"
524
+ # which is correct - it runs from the installed crackerjack package
525
+
526
+ def _process_hook_args(self, hook: dict[str, t.Any], project_name: str) -> None:
527
+ """Process hook args to replace project-specific references."""
528
+ if "args" in hook:
529
+ hook["args"] = [
530
+ arg.replace("crackerjack", project_name)
531
+ if isinstance(arg, str)
532
+ else arg
533
+ for arg in hook["args"]
534
+ ]
535
+
536
+ def _process_hook_files(self, hook: dict[str, t.Any], project_name: str) -> None:
537
+ """Process hook files pattern to replace project-specific references."""
538
+ if "files" in hook:
539
+ files_pattern = hook["files"]
540
+ if isinstance(files_pattern, str):
541
+ hook["files"] = files_pattern.replace(
542
+ "^crackerjack/", f"^{project_name}/"
543
+ )
@@ -329,36 +329,54 @@ class SecureSubprocessExecutor:
329
329
  self, arg: str, index: int, issues: list[str], command: list[str]
330
330
  ) -> bool:
331
331
  # First check if this is an allowed git pattern
332
- for git_pattern in self.allowed_git_patterns:
333
- if re.match(git_pattern, arg):
334
- return False # It's an allowed git pattern, don't flag as dangerous
332
+ if self._is_allowed_git_pattern(arg):
333
+ return False
335
334
 
336
335
  # Special handling for git commit messages
337
336
  if self._is_git_commit_message(index, command):
338
- # For git commit messages, only check for truly dangerous patterns
339
- # Parentheses are common in commit messages and should be allowed
340
- safe_commit_patterns = [
341
- r"[;&|`$]", # Still dangerous in commit messages
342
- r"\.\./", # Path traversal
343
- r"\$\{.*\}", # Variable expansion
344
- r"`.*`", # Command substitution
345
- r"\$\(.*\)", # Command substitution (but allow simple parentheses)
346
- r">\s*/", # Redirection to paths
347
- r"<\s*/", # Redirection from paths
348
- ]
349
-
350
- for pattern in safe_commit_patterns:
351
- if re.search(pattern, arg):
352
- # Allow simple parentheses that don't look like command substitution
353
- if pattern == r"\$\(.*\)" and not re.search(r"\$\(", arg):
354
- continue
355
- issues.append(
356
- f"Dangerous pattern '{pattern}' in argument {index}: {arg[:50]}"
357
- )
358
- return True
359
- return False
337
+ return self._check_dangerous_patterns_in_commit_message(arg, index, issues)
360
338
 
361
339
  # Check for dangerous patterns in other contexts
340
+ return self._check_dangerous_patterns_in_other_contexts(arg, index, issues)
341
+
342
+ def _is_allowed_git_pattern(self, arg: str) -> bool:
343
+ """Check if the argument matches an allowed git pattern."""
344
+ for git_pattern in self.allowed_git_patterns:
345
+ if re.match(git_pattern, arg):
346
+ return True
347
+ return False
348
+
349
+ def _check_dangerous_patterns_in_commit_message(
350
+ self, arg: str, index: int, issues: list[str]
351
+ ) -> bool:
352
+ """Check for dangerous patterns specifically in git commit messages."""
353
+ # For git commit messages, only check for truly dangerous patterns
354
+ # Parentheses are common in commit messages and should be allowed
355
+ safe_commit_patterns = [
356
+ r"[;&|`$]", # Still dangerous in commit messages
357
+ r"\.\./", # Path traversal
358
+ r"\$\{.*\}", # Variable expansion
359
+ r"`.*`", # Command substitution
360
+ r"\$\(.*\)", # Command substitution (but allow simple parentheses)
361
+ r">\s*/", # Redirection to paths
362
+ r"<\s*/", # Redirection from paths
363
+ ]
364
+
365
+ for pattern in safe_commit_patterns:
366
+ if re.search(pattern, arg):
367
+ # Allow simple parentheses that don't look like command substitution
368
+ if pattern == r"\$\(.*\)" and not re.search(r"\$\(", arg):
369
+ continue
370
+ issues.append(
371
+ f"Dangerous pattern '{pattern}' in argument {index}: {arg[:50]}"
372
+ )
373
+ return True
374
+ return False
375
+
376
+ def _check_dangerous_patterns_in_other_contexts(
377
+ self, arg: str, index: int, issues: list[str]
378
+ ) -> bool:
379
+ """Check for dangerous patterns in non-commit message contexts."""
362
380
  for pattern in self.dangerous_patterns:
363
381
  if re.search(pattern, arg):
364
382
  issues.append(
@@ -37,6 +37,7 @@ ALLOWED_PATTERNS = {
37
37
  r"crackerjack/intelligence/agent_selector\.py$",
38
38
  r"crackerjack/managers/test_.*\.py$",
39
39
  r"crackerjack/core/async_workflow_orchestrator\.py$",
40
+ r"crackerjack/core/workflow_orchestrator\.py$",
40
41
  r"crackerjack/agents/.*\.py$",
41
42
  }
42
43
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: crackerjack
3
- Version: 0.37.8
3
+ Version: 0.38.0
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
@@ -73,7 +73,7 @@ Description-Content-Type: text/markdown
73
73
  [![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)
74
74
  [![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit)](https://github.com/pre-commit/pre-commit)
75
75
  [![License](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause)
76
- ![Coverage](https://img.shields.io/badge/coverage-17.6%25-red)
76
+ ![Coverage](https://img.shields.io/badge/coverage-37.1%25-red)
77
77
 
78
78
  ## 🎯 Purpose
79
79
 
@@ -1,10 +1,10 @@
1
- crackerjack/__init__.py,sha256=k8_Ev_3fWdjFtGNSJdSOvyaSLW54y3j484d3a8k_Ob4,1396
1
+ crackerjack/__init__.py,sha256=DajG9zHB8qBdgdiKMumrrssUbKeMXmtIQ3oOaSTb46Y,1426
2
2
  crackerjack/__main__.py,sha256=lE5ZDbAzI9TLCzMTxFGw23Dk1hP-MEhd1i_nNbi_Mag,52515
3
- crackerjack/api.py,sha256=sfKzCphsTMFCvdNizviPdYemwg0H8Oei_5C08LAuDvA,21538
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=-lpwDhkVwxAXUDbX47sEClZZieNbkqhDxk_2jpxpLBw,22070
5
+ crackerjack/dynamic_config.py,sha256=4c8Fts9vyH8Tdon_47OFVT1iTBINSzSgB0WoeSvpzII,22418
6
6
  crackerjack/errors.py,sha256=yYbZ92kn_y6acEWgQvEPvozAYs2HT65uLwAXrtXxGsE,10049
7
- crackerjack/interactive.py,sha256=QXFZrnbY0nc8rFJcivFAVFNgUTHXqLCu3FFv5bmq_eI,21634
7
+ crackerjack/interactive.py,sha256=CYu53ySL2I1YCWRRRHmVEYQq3RQ0xDCXFTuPUAw6DTc,21399
8
8
  crackerjack/adapters/__init__.py,sha256=k-8ajMDL9DS9hV2FYOu694nmNQg3HkudJRuNcXmx8N4,451
9
9
  crackerjack/adapters/lsp_client.py,sha256=4kQ3T5JiWC7uc6kOjZuPdtUboseKSDjZpuKQpV74onc,10963
10
10
  crackerjack/adapters/rust_tool_adapter.py,sha256=ui_qMt_WIwInRvRCeT7MnIdp8eln7Fvp4hakXQiVnjg,5999
@@ -54,7 +54,7 @@ crackerjack/core/service_watchdog.py,sha256=Ttj1imOxvUea4Tkf5JO1e2dQtGIK7D-bX1xO
54
54
  crackerjack/core/session_coordinator.py,sha256=TgoGE9DfXe2x-OkH93Ld9dX9ROjx2_mZFkGXen-z5YI,15680
55
55
  crackerjack/core/timeout_manager.py,sha256=_sbEsfYDwWx7y0Pn89QCoAZ5DpWIbCdtR9qkG_Kqj5E,15013
56
56
  crackerjack/core/websocket_lifecycle.py,sha256=74kn6ugu6FLlDQhCNSPgqguCFwRoT1WFOvtl8G2OyFc,12860
57
- crackerjack/core/workflow_orchestrator.py,sha256=jh8G1xKqxXwD0yGaFHgdESRjm23-kUZt4qriMJltowM,70789
57
+ crackerjack/core/workflow_orchestrator.py,sha256=S7XiVdJEEKcHQF1_PL1IymDpx940le_z6ozG6EIpk-s,75876
58
58
  crackerjack/docs/INDEX.md,sha256=a6CGFEeL5DX_FRft_JFWd0nOxoBmCSSp-QHIC3B7ato,342
59
59
  crackerjack/docs/generated/api/API_REFERENCE.md,sha256=mWoqImZA7AhDvRqqF1MhUo70g_pnZr3NoBeZQRotqN8,155816
60
60
  crackerjack/docs/generated/api/CLI_REFERENCE.md,sha256=ikuG0hO5EjIiQlJtAUnvEuAhXDa-JHPULPXNNmUwvk4,2805
@@ -65,7 +65,7 @@ crackerjack/documentation/__init__.py,sha256=gGR--er5oTHhbwLKOHVlU2QgGmQtA0qUXf3
65
65
  crackerjack/documentation/ai_templates.py,sha256=GRBKB5bqWudh9MDLjo1b3vNiFAgpL62ezzRp_WxTews,21629
66
66
  crackerjack/documentation/dual_output_generator.py,sha256=w7rDthOnyFeRPQDWvYiR4aiScPxsHzkwjJ3blMwT9-w,28552
67
67
  crackerjack/documentation/mkdocs_integration.py,sha256=KqU2_9mA-rjP_VDrrfr6KTuPWtTlcvkInPxoH03LTC0,15657
68
- crackerjack/documentation/reference_generator.py,sha256=qthAvJU32xUjpl6GZ5s0sWILdCS3OGQLzIuw6UBsUU4,30618
68
+ crackerjack/documentation/reference_generator.py,sha256=NGAIsC5bnjLBQkvEXPDU0pw8bQ5kYzbUUokhlXXFqrU,34520
69
69
  crackerjack/executors/__init__.py,sha256=HF-DmXvKN45uKKDdiMxOT9bYxuy1B-Z91BihOhkK5lg,322
70
70
  crackerjack/executors/async_hook_executor.py,sha256=FmKpiAxpZXKwvOWXnRQ73N-reDfX8NusESQ9a4HeacM,17620
71
71
  crackerjack/executors/cached_hook_executor.py,sha256=izwdW0B22EZcl_2_llmTIyq5oTcZDZTRL2G97ZwYiXg,11173
@@ -74,7 +74,7 @@ crackerjack/executors/hook_lock_manager.py,sha256=ft24q6VFEkW_QrifNnSlrQeHGx9GuJ
74
74
  crackerjack/executors/individual_hook_executor.py,sha256=t0W9vuqLGPx0HmbTo01N9MRFyqLfY0ZLG06ZIA5qfBY,24362
75
75
  crackerjack/executors/lsp_aware_hook_executor.py,sha256=aZxtTwpaDxfmN71II2MEAtfzEst-jPJp-GXmMLwnibA,10388
76
76
  crackerjack/executors/tool_proxy.py,sha256=dJnrt72aFXEMuZLsgrLZrf51vfELDaXs5nBxzGHu7SQ,14881
77
- crackerjack/hooks/lsp_hook.py,sha256=hJCkJ-jUJasE35XPWdnGRDXgynEh2-gUiEd1wxLFp48,2397
77
+ crackerjack/hooks/lsp_hook.py,sha256=MPP9EYmKdZMNBvAQSAwzI5L8TkwKTd0uVx3heaTHmM0,2877
78
78
  crackerjack/intelligence/__init__.py,sha256=3Sty6xFyxBEXTyy8W34dpAQk7S7m8SnxUz4wrb3xrZc,878
79
79
  crackerjack/intelligence/adaptive_learning.py,sha256=Q0pUyxzBBCtySTfp96zHObQVAUaN0c5kEFOFJKIG0j8,25610
80
80
  crackerjack/intelligence/agent_orchestrator.py,sha256=YOG2sQc0l5ddz7TzRZ_1YAugTNwuyY1brWrlj5tnMhk,16728
@@ -84,7 +84,7 @@ crackerjack/intelligence/integration.py,sha256=vVaC2Fp5RbbABpaohCePzGw1XANuRztGl
84
84
  crackerjack/managers/__init__.py,sha256=PFWccXx4hDQA76T02idAViOLVD-aPeVpgjdfSkh_Dmk,298
85
85
  crackerjack/managers/async_hook_manager.py,sha256=c0HFR98sFwfk0uZ3NmAe_6OVZpBrq9I570V8A2DoIxw,5129
86
86
  crackerjack/managers/hook_manager.py,sha256=_FT0ngwPwujqg0KZGpLz-pP07mwDmptJ5pVkiy5yS8k,7820
87
- crackerjack/managers/publish_manager.py,sha256=5jpYM2IeTxavP2KYypZqz83ASQrBQDOhcKpws8DLFbM,22040
87
+ crackerjack/managers/publish_manager.py,sha256=Pe0zWtLaho5BCTO8-EC9sY0Gl4L1B2guDM2D8B8TryA,22034
88
88
  crackerjack/managers/test_command_builder.py,sha256=1TlPzddNcDDxRORH6UvAudcbRc6hKwFyknSEVLkiWAo,3459
89
89
  crackerjack/managers/test_executor.py,sha256=2837Ti4OaNsmLxnmELjbQ18hmfL0-Z2EW-W2UeFSDcE,13871
90
90
  crackerjack/managers/test_manager.py,sha256=BRPBWXx4flPDK0w96xyHhg-9dmUca1vpKQRM2VofSlI,13158
@@ -110,7 +110,7 @@ crackerjack/mcp/tools/__init__.py,sha256=T_RMPXHQQWJLvSJjrPkJYtWi5tmyoRrzm0WS2G-
110
110
  crackerjack/mcp/tools/core_tools.py,sha256=8gytjhqxKglR-ZvLIy0DwJzzaqStex_s9WHiAjkXlD0,14612
111
111
  crackerjack/mcp/tools/error_analyzer.py,sha256=8ap3_TIqEfrN0n49w_wJFRE3zu7eHB9E8UyXqqz7unM,8515
112
112
  crackerjack/mcp/tools/execution_tools.py,sha256=iMtcTm45v04wNgfiIdzOjMXyB-lZ9x-yUtN9SuLGxNI,10410
113
- crackerjack/mcp/tools/execution_tools_backup.py,sha256=aq3njWeBlHT8EbBlmWsdtKwYujssV1hyI5waGku68Ec,33269
113
+ crackerjack/mcp/tools/execution_tools_backup.py,sha256=sWOtid00SkuonFLT2XCtljOGZiibbaIXzEdLWsPrXyI,33351
114
114
  crackerjack/mcp/tools/intelligence_tool_registry.py,sha256=eAOBzW3EZTKSz_MeYVzgjD6a1xVZFSXUdgOsgcQLSBk,1262
115
115
  crackerjack/mcp/tools/intelligence_tools.py,sha256=R0TK-sLuCezJQu0FfTg1xXs-xI_oI2aJeueZgOrM58g,9106
116
116
  crackerjack/mcp/tools/monitoring_tools.py,sha256=5RYbytBmLjJdz1sE33xYchdrO9LgzGwSvsqRsZIV7oA,21804
@@ -145,7 +145,7 @@ crackerjack/orchestration/execution_strategies.py,sha256=G34eYqd5fqKPgPcRScASS86
145
145
  crackerjack/orchestration/test_progress_streamer.py,sha256=Yu6uHuhoCvX6SZP0QNG3Yt8Q4s2tufEHr40o16QU98c,22541
146
146
  crackerjack/plugins/__init__.py,sha256=B7hy9b9amJVbYLHgIz8kgTI29j-vYxsUY_sZ5ISbXU0,386
147
147
  crackerjack/plugins/base.py,sha256=VFk-xNsgjSlmzJ_iPQALhkr7cguiOtEd3XSR9CcCPkc,5732
148
- crackerjack/plugins/hooks.py,sha256=IOnYYEB366HR0t09bV7G_F7wOf2D9vtMcEiR0PRfwiw,7574
148
+ crackerjack/plugins/hooks.py,sha256=XagUpeehUwP_k4NnODnn0M1ycTe1F4uP1EMiFULUlKY,7581
149
149
  crackerjack/plugins/loader.py,sha256=9RmA5Lkizz5BADn-aJDGekISyL7C_O2Grr1tB6undHY,10814
150
150
  crackerjack/plugins/managers.py,sha256=3kQlxjvcHyHDgZIdr-JZBO1kqz2asqA4kf2XVAA1K6A,8824
151
151
  crackerjack/security/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -159,7 +159,7 @@ crackerjack/services/cache.py,sha256=FutQKxItKSdQFzOlWQaQzVBEfn6lbPXCDdvNnz3NCDQ
159
159
  crackerjack/services/changelog_automation.py,sha256=KUeXCYLihRfLR0mUIRiI2aRQdCfe-45GnbB2gYNJJQE,14095
160
160
  crackerjack/services/config.py,sha256=1gUQkcHPCGHVYSlx6mcrJlJLVIWhdaL7RjEmuy8_ev4,13704
161
161
  crackerjack/services/config_integrity.py,sha256=Ac6-c7WuupsyrP2dxx_ijgjzpNnx9G0NWsXB-SZjelg,2904
162
- crackerjack/services/config_merge.py,sha256=FPh4u4J68JkNVf0AT1paNeEy2MjusSbYu9kN72LzR9w,18825
162
+ crackerjack/services/config_merge.py,sha256=ubApDKbYMREaHARP3oaW9vY8iVeYuknsr6tJIiIz-_E,18999
163
163
  crackerjack/services/config_template.py,sha256=RgSYFVNBxdBfMitlRqz7bzkEHaQhEWMm3pUMS7maRFU,18035
164
164
  crackerjack/services/contextual_ai_assistant.py,sha256=6Pnb2r824c4JYkP5mtCH8sJ2OPPvI-KtzbXcosspCfE,19962
165
165
  crackerjack/services/coverage_badge_service.py,sha256=gzC3LEyVLt4rpf378APsFVRGgNwkLc50w9S_9xEPPoM,6645
@@ -199,7 +199,7 @@ crackerjack/services/regex_patterns.py,sha256=iis9gSzXZtnX14lODGfSUsf7bcCRTw7rdS
199
199
  crackerjack/services/regex_utils.py,sha256=e7AD59_L-T5-oOxzqsGgrLd94uxRE9aKnwasZkohwI8,14966
200
200
  crackerjack/services/secure_path_utils.py,sha256=aHsLwxDch42DidPYtTL_ko40g2rhbXDLnRhcx2LlGk8,16688
201
201
  crackerjack/services/secure_status_formatter.py,sha256=yhwNtzvvQVcuHsNOTNZMzlqIMQT9zx-lzAtq9LuSDuk,14121
202
- crackerjack/services/secure_subprocess.py,sha256=upuiBL0sYIElC8DWQ622-A6572zBaSBoMPVnNM8AeaQ,19838
202
+ crackerjack/services/secure_subprocess.py,sha256=tDHyuxavTES1uXzJOdxZlza8d92hvza2xzx5JMamsoA,20488
203
203
  crackerjack/services/security.py,sha256=plgIz-B8oYN_mpF4NYrqHnT7TRcsp4jr0-YlV9WgD5o,7298
204
204
  crackerjack/services/security_logger.py,sha256=AAjd9VKVmCo158UifyEKd79VgtWKeuaIVyXYL8qvqT8,17001
205
205
  crackerjack/services/server_manager.py,sha256=MwvMMxhaCiZD4pcKM2ODXB-gu2s22n_v_uIqrwoJsHs,11934
@@ -221,11 +221,11 @@ crackerjack/slash_commands/run.md,sha256=VEWWset52jPV0m00LnQpjRkHL8g8XRPYAzgOq6B
221
221
  crackerjack/slash_commands/status.md,sha256=U3qqppVLtIIm2lEiMYaKagaHYLI9UplL7OH1j6SRJGw,3921
222
222
  crackerjack/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
223
223
  crackerjack/tools/validate_input_validator_patterns.py,sha256=NN7smYlXWrHLQXTb-81gRam2vjW-cJav92f1klPA0qA,8234
224
- crackerjack/tools/validate_regex_patterns.py,sha256=9ejFb7Tw1js_oydzuEeeeXvrU5ipHUEX9ATBfkLCCE8,5811
224
+ crackerjack/tools/validate_regex_patterns.py,sha256=J7GG9EP1fASpRIsG8qRPeiCSkdCwmk0sdo29GgoJ6w8,5863
225
225
  crackerjack/ui/__init__.py,sha256=eMb1OeTU-dSLICAACn0YdYB4Amdr8wHckjKfn0wOIZE,37
226
226
  crackerjack/ui/server_panels.py,sha256=F5IH6SNN06BaZQMsFx_D-OA286aojmaFPJ5kvvSRv_c,4232
227
- crackerjack-0.37.8.dist-info/METADATA,sha256=qF__5Ea3FSxtJK3fOtYXXnX3Y6WPwA-drRfCYVteHsw,37949
228
- crackerjack-0.37.8.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
229
- crackerjack-0.37.8.dist-info/entry_points.txt,sha256=AJKNft0WXm9xoGUJ3Trl-iXHOWxRAYbagQiza3AILr4,57
230
- crackerjack-0.37.8.dist-info/licenses/LICENSE,sha256=fDt371P6_6sCu7RyqiZH_AhT1LdN3sN1zjBtqEhDYCk,1531
231
- crackerjack-0.37.8.dist-info/RECORD,,
227
+ crackerjack-0.38.0.dist-info/METADATA,sha256=eOtnsgHgSIJAR_hBiHx8bgF6maVsKm7LdATHCdtTu6A,37949
228
+ crackerjack-0.38.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
229
+ crackerjack-0.38.0.dist-info/entry_points.txt,sha256=AJKNft0WXm9xoGUJ3Trl-iXHOWxRAYbagQiza3AILr4,57
230
+ crackerjack-0.38.0.dist-info/licenses/LICENSE,sha256=fDt371P6_6sCu7RyqiZH_AhT1LdN3sN1zjBtqEhDYCk,1531
231
+ crackerjack-0.38.0.dist-info/RECORD,,