crackerjack 0.33.12__py3-none-any.whl → 0.34.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.

@@ -110,7 +110,7 @@ class Options(BaseModel):
110
110
  accept_version: bool = False
111
111
 
112
112
  # Intelligent features
113
- smart_commit: bool = False
113
+ smart_commit: bool = True # Default enabled for advanced services integration
114
114
 
115
115
  # Analytics and visualization features
116
116
  heatmap: bool = False
@@ -733,9 +733,9 @@ CLI_OPTIONS = {
733
733
  help="Automatically accept version bump recommendation without confirmation.",
734
734
  ),
735
735
  "smart_commit": typer.Option(
736
- False,
737
- "--smart-commit",
738
- help="Generate intelligent commit messages based on code changes using AI analysis.",
736
+ True, # Now enabled by default for advanced services integration
737
+ "--smart-commit/--basic-commit",
738
+ help="Generate intelligent commit messages using AI analysis (default: enabled). Use --basic-commit for simple messages.",
739
739
  ),
740
740
  "heatmap": typer.Option(
741
741
  False,
@@ -474,8 +474,12 @@ class PhaseCoordinator(ErrorHandlingMixin):
474
474
  changed_files: list[str],
475
475
  options: OptionsProtocol,
476
476
  ) -> str:
477
- # Check if smart commit is enabled
478
- if getattr(options, "smart_commit", False):
477
+ # Smart commit is now enabled by default for all commit operations
478
+ # Use basic commit messages only if explicitly disabled
479
+ use_smart_commit = getattr(options, "smart_commit", True)
480
+ disable_smart_commit = getattr(options, "basic_commit", False)
481
+
482
+ if use_smart_commit and not disable_smart_commit:
479
483
  try:
480
484
  from crackerjack.services.intelligent_commit import (
481
485
  CommitMessageGenerator,
@@ -19,11 +19,16 @@ from crackerjack.services.logging import (
19
19
  setup_structured_logging,
20
20
  )
21
21
  from crackerjack.services.memory_optimizer import get_memory_optimizer, memory_optimized
22
+ from crackerjack.services.performance_benchmarks import PerformanceBenchmarkService
22
23
  from crackerjack.services.performance_cache import get_performance_cache
23
24
  from crackerjack.services.performance_monitor import (
24
25
  get_performance_monitor,
25
26
  phase_monitor,
26
27
  )
28
+ from crackerjack.services.quality_baseline_enhanced import (
29
+ EnhancedQualityBaselineService,
30
+ )
31
+ from crackerjack.services.quality_intelligence import QualityIntelligenceService
27
32
 
28
33
  from .phase_coordinator import PhaseCoordinator
29
34
  from .session_coordinator import SessionCoordinator
@@ -60,6 +65,25 @@ class WorkflowPipeline:
60
65
  self._memory_optimizer = get_memory_optimizer()
61
66
  self._cache = get_performance_cache()
62
67
 
68
+ # Initialize quality intelligence for advanced decision making
69
+ try:
70
+ quality_baseline = EnhancedQualityBaselineService(console, pkg_path)
71
+ self._quality_intelligence = QualityIntelligenceService(
72
+ quality_baseline, console
73
+ )
74
+ except Exception:
75
+ # Fallback gracefully if quality intelligence is not available
76
+ self._quality_intelligence = None
77
+
78
+ # Initialize performance benchmarking for workflow analysis
79
+ try:
80
+ self._performance_benchmarks = PerformanceBenchmarkService(
81
+ console, pkg_path
82
+ )
83
+ except Exception:
84
+ # Fallback gracefully if benchmarking is not available
85
+ self._performance_benchmarks = None
86
+
63
87
  @property
64
88
  def debugger(self) -> AIAgentDebugger | NoOpDebugger:
65
89
  if self._debugger is None:
@@ -297,6 +321,9 @@ class WorkflowPipeline:
297
321
  duration = time.time() - start_time
298
322
  self._log_workflow_completion(success, duration)
299
323
  self._log_workflow_completion_debug(success, duration)
324
+ await self._generate_performance_benchmark_report(
325
+ workflow_id, duration, success
326
+ )
300
327
 
301
328
  return success
302
329
 
@@ -318,6 +345,50 @@ class WorkflowPipeline:
318
345
  duration=duration,
319
346
  )
320
347
 
348
+ async def _generate_performance_benchmark_report(
349
+ self, workflow_id: str, duration: float, success: bool
350
+ ) -> None:
351
+ """Generate and display performance benchmark report for workflow execution."""
352
+ if not self._performance_benchmarks:
353
+ return
354
+
355
+ try:
356
+ # Gather performance metrics from the workflow execution
357
+ {
358
+ "workflow_id": workflow_id,
359
+ "total_duration": duration,
360
+ "success": success,
361
+ "cache_metrics": self._cache.get_stats() if self._cache else {},
362
+ "memory_metrics": self._memory_optimizer.get_stats()
363
+ if hasattr(self._memory_optimizer, "get_stats")
364
+ else {},
365
+ }
366
+
367
+ # Generate benchmark comparison
368
+ benchmark_results = await self._performance_benchmarks.run_benchmark_suite()
369
+
370
+ # Display compact performance summary
371
+ if benchmark_results:
372
+ self.console.print("\n[cyan]📊 Performance Benchmark Summary[/cyan]")
373
+ self.console.print(f"Workflow Duration: [bold]{duration:.2f}s[/bold]")
374
+
375
+ # Show key performance improvements if available
376
+ for result in benchmark_results.results[:3]: # Top 3 results
377
+ if result.time_improvement_percentage > 0:
378
+ self.console.print(
379
+ f"[green]⚡[/green] {result.test_name}: {result.time_improvement_percentage:.1f}% faster"
380
+ )
381
+
382
+ if result.cache_hit_ratio > 0:
383
+ self.console.print(
384
+ f"[blue]🎯[/blue] Cache efficiency: {result.cache_hit_ratio:.0%}"
385
+ )
386
+
387
+ except Exception as e:
388
+ self.console.print(
389
+ f"[dim]⚠️ Performance benchmark failed: {str(e)[:50]}...[/dim]"
390
+ )
391
+
321
392
  if self.debugger.enabled:
322
393
  self.debugger.print_debug_summary()
323
394
 
@@ -391,6 +462,13 @@ class WorkflowPipeline:
391
462
  async def _execute_quality_phase(
392
463
  self, options: OptionsProtocol, workflow_id: str
393
464
  ) -> bool:
465
+ # Use quality intelligence to make informed decisions about quality phase
466
+ if self._quality_intelligence:
467
+ quality_decision = await self._make_quality_intelligence_decision(options)
468
+ self.console.print(
469
+ f"[dim]🧠 Quality Intelligence: {quality_decision}[/dim]"
470
+ )
471
+
394
472
  if hasattr(options, "fast") and options.fast:
395
473
  return await self._run_fast_hooks_phase_monitored(options, workflow_id)
396
474
  if hasattr(options, "comp") and options.comp:
@@ -403,6 +481,48 @@ class WorkflowPipeline:
403
481
  options, workflow_id
404
482
  )
405
483
 
484
+ async def _make_quality_intelligence_decision(
485
+ self, options: OptionsProtocol
486
+ ) -> str:
487
+ """Use quality intelligence to make informed decisions about workflow execution."""
488
+ try:
489
+ if not self._quality_intelligence:
490
+ return "Quality intelligence not available"
491
+
492
+ # Analyze recent quality trends and anomalies
493
+ anomalies = await self._quality_intelligence.detect_anomalies()
494
+ patterns = await self._quality_intelligence.identify_patterns()
495
+
496
+ # Make intelligent recommendations based on current state
497
+ recommendations = []
498
+ if anomalies:
499
+ high_severity_anomalies = [
500
+ a for a in anomalies if a.severity.name in ["CRITICAL", "HIGH"]
501
+ ]
502
+ if high_severity_anomalies:
503
+ recommendations.append(
504
+ "comprehensive analysis recommended due to quality anomalies"
505
+ )
506
+ else:
507
+ recommendations.append("standard quality checks sufficient")
508
+
509
+ if patterns:
510
+ improving_patterns = [
511
+ p for p in patterns if p.trend_direction.name == "IMPROVING"
512
+ ]
513
+ if improving_patterns:
514
+ recommendations.append("quality trending upward")
515
+ else:
516
+ recommendations.append("quality monitoring active")
517
+
518
+ if not recommendations:
519
+ recommendations.append("baseline quality analysis active")
520
+
521
+ return "; ".join(recommendations)
522
+
523
+ except Exception as e:
524
+ return f"Quality intelligence analysis failed: {str(e)[:50]}..."
525
+
406
526
  async def _execute_test_workflow(
407
527
  self, options: OptionsProtocol, workflow_id: str
408
528
  ) -> bool:
@@ -457,8 +457,55 @@ PRE_COMMIT_TEMPLATE = """repos:
457
457
 
458
458
 
459
459
  class DynamicConfigGenerator:
460
- def __init__(self) -> None:
460
+ def __init__(self, package_directory: str | None = None) -> None:
461
461
  self.template = jinja2.Template(PRE_COMMIT_TEMPLATE)
462
+ self.package_directory = package_directory or self._detect_package_directory()
463
+
464
+ def _detect_package_directory(self) -> str:
465
+ """Detect the package directory name for the current project."""
466
+ import os
467
+ from pathlib import Path
468
+
469
+ # Check if we're in the crackerjack project itself
470
+ current_dir = Path(os.getcwd())
471
+ if (current_dir / "crackerjack").exists() and (
472
+ current_dir / "pyproject.toml"
473
+ ).exists():
474
+ # Check if this is actually the crackerjack project
475
+ try:
476
+ import tomllib
477
+
478
+ with (current_dir / "pyproject.toml").open("rb") as f:
479
+ data = tomllib.load(f)
480
+ if data.get("project", {}).get("name") == "crackerjack":
481
+ return "crackerjack"
482
+ except Exception:
483
+ pass
484
+
485
+ # Try to read package name from pyproject.toml
486
+ pyproject_path = current_dir / "pyproject.toml"
487
+ if pyproject_path.exists():
488
+ try:
489
+ import tomllib
490
+
491
+ with pyproject_path.open("rb") as f:
492
+ data = tomllib.load(f)
493
+
494
+ if "project" in data and "name" in data["project"]:
495
+ package_name = str(data["project"]["name"])
496
+ # Check if package directory exists
497
+ if (current_dir / package_name).exists():
498
+ return package_name
499
+ except Exception:
500
+ pass
501
+
502
+ # Fallback to common patterns
503
+ for possible_name in ("src", current_dir.name):
504
+ if (current_dir / possible_name).exists():
505
+ return possible_name
506
+
507
+ # Default fallback
508
+ return "src"
462
509
 
463
510
  def _should_include_hook(
464
511
  self,
@@ -486,10 +533,40 @@ class DynamicConfigGenerator:
486
533
  for category_hooks in HOOKS_REGISTRY.values():
487
534
  for hook in category_hooks:
488
535
  if self._should_include_hook(hook, config, enabled_experimental):
489
- filtered_hooks.append(hook)
536
+ # Create a copy and update package-specific configurations
537
+ updated_hook = self._update_hook_for_package(hook.copy())
538
+ filtered_hooks.append(updated_hook)
490
539
 
491
540
  return filtered_hooks
492
541
 
542
+ def _update_hook_for_package(self, hook: HookMetadata) -> HookMetadata:
543
+ """Update hook configuration to use the detected package directory."""
544
+ # Update skylos hook
545
+ if hook["id"] == "skylos" and hook["args"]:
546
+ hook["args"] = [self.package_directory]
547
+
548
+ # Update zuban hook
549
+ elif hook["id"] == "zuban" and hook["args"]:
550
+ # Replace the hardcoded "./crackerjack" with the dynamic package directory
551
+ updated_args = []
552
+ for arg in hook["args"]:
553
+ if arg == "./crackerjack":
554
+ updated_args.append(f"./{self.package_directory}")
555
+ else:
556
+ updated_args.append(arg)
557
+ hook["args"] = updated_args
558
+
559
+ # Update other hooks that use hardcoded "crackerjack" patterns
560
+ elif hook["files"] and "crackerjack" in hook["files"]:
561
+ hook["files"] = hook["files"].replace("crackerjack", self.package_directory)
562
+
563
+ elif hook["exclude"] and "crackerjack" in hook["exclude"]:
564
+ hook["exclude"] = hook["exclude"].replace(
565
+ "crackerjack", self.package_directory
566
+ )
567
+
568
+ return hook
569
+
493
570
  def group_hooks_by_repo(
494
571
  self,
495
572
  hooks: list[HookMetadata],
@@ -580,8 +657,11 @@ class DynamicConfigGenerator:
580
657
  def generate_config_for_mode(
581
658
  mode: str,
582
659
  enabled_experimental: list[str] | None = None,
660
+ package_directory: str | None = None,
583
661
  ) -> Path:
584
- return DynamicConfigGenerator().create_temp_config(mode, enabled_experimental)
662
+ return DynamicConfigGenerator(package_directory).create_temp_config(
663
+ mode, enabled_experimental
664
+ )
585
665
 
586
666
 
587
667
  def get_available_modes() -> list[str]:
@@ -122,8 +122,18 @@ class PublishManagerImpl:
122
122
  raise ValueError(msg)
123
123
  self.console.print(f"[cyan]📦[/ cyan] Current version: {current_version}")
124
124
 
125
+ # Get intelligent version analysis and recommendation
126
+ recommendation = self._get_version_recommendation()
127
+ if recommendation and version_type not in ["interactive"]:
128
+ self._display_version_analysis(recommendation)
129
+ if version_type == "auto":
130
+ version_type = recommendation.bump_type.value
131
+ self.console.print(
132
+ f"[green]🎯[/green] Using AI-recommended bump type: {version_type}"
133
+ )
134
+
125
135
  if version_type == "interactive":
126
- version_type = self._prompt_for_version_type()
136
+ version_type = self._prompt_for_version_type(recommendation)
127
137
 
128
138
  try:
129
139
  new_version = self._calculate_next_version(current_version, version_type)
@@ -146,14 +156,21 @@ class PublishManagerImpl:
146
156
  self.console.print(f"[red]❌[/ red] Version bump failed: {e}")
147
157
  raise
148
158
 
149
- def _prompt_for_version_type(self) -> str:
159
+ def _prompt_for_version_type(self, recommendation=None) -> str:
150
160
  try:
151
161
  from rich.prompt import Prompt
152
162
 
163
+ default_type = "patch"
164
+ if recommendation:
165
+ default_type = recommendation.bump_type.value
166
+ self.console.print(
167
+ f"[dim]AI recommendation: {default_type} (confidence: {recommendation.confidence:.0%})[/dim]"
168
+ )
169
+
153
170
  return Prompt.ask(
154
171
  "[cyan]📦[/ cyan] Select version bump type",
155
172
  choices=["patch", "minor", "major"],
156
- default="patch",
173
+ default=default_type,
157
174
  )
158
175
  except ImportError:
159
176
  self.console.print(
@@ -161,6 +178,73 @@ class PublishManagerImpl:
161
178
  )
162
179
  return "patch"
163
180
 
181
+ def _get_version_recommendation(self):
182
+ """Get AI-powered version bump recommendation based on git history."""
183
+ try:
184
+ import asyncio
185
+
186
+ from crackerjack.services.git import GitService
187
+ from crackerjack.services.version_analyzer import VersionAnalyzer
188
+
189
+ # Initialize services
190
+ git_service = GitService(self.console, self.pkg_path)
191
+ version_analyzer = VersionAnalyzer(self.console, git_service)
192
+
193
+ # Get recommendation asynchronously
194
+ try:
195
+ # Try to get existing event loop
196
+ loop = asyncio.get_event_loop()
197
+ if loop.is_running():
198
+ # Create a new event loop in a thread if one is already running
199
+ import concurrent.futures
200
+
201
+ with concurrent.futures.ThreadPoolExecutor() as executor:
202
+ future = executor.submit(
203
+ asyncio.run, version_analyzer.recommend_version_bump()
204
+ )
205
+ recommendation = future.result(timeout=10)
206
+ else:
207
+ recommendation = loop.run_until_complete(
208
+ version_analyzer.recommend_version_bump()
209
+ )
210
+ except RuntimeError:
211
+ # No event loop, create one
212
+ recommendation = asyncio.run(version_analyzer.recommend_version_bump())
213
+
214
+ return recommendation
215
+
216
+ except Exception as e:
217
+ self.console.print(f"[yellow]⚠️[/yellow] Version analysis failed: {e}")
218
+ return None
219
+
220
+ def _display_version_analysis(self, recommendation):
221
+ """Display version analysis in a compact format."""
222
+ if not recommendation:
223
+ return
224
+
225
+ self.console.print("\n[cyan]🎯 AI Version Analysis[/cyan]")
226
+ self.console.print(
227
+ f"Recommended: [bold green]{recommendation.recommended_version}[/bold green] "
228
+ f"({recommendation.bump_type.value.upper()}) - {recommendation.confidence:.0%} confidence"
229
+ )
230
+
231
+ if recommendation.reasoning:
232
+ self.console.print(f"[dim]→ {recommendation.reasoning[0]}[/dim]")
233
+
234
+ # Show key changes briefly
235
+ if recommendation.breaking_changes:
236
+ self.console.print(
237
+ f"[red]⚠️[/red] {len(recommendation.breaking_changes)} breaking changes detected"
238
+ )
239
+ elif recommendation.new_features:
240
+ self.console.print(
241
+ f"[green]✨[/green] {len(recommendation.new_features)} new features detected"
242
+ )
243
+ elif recommendation.bug_fixes:
244
+ self.console.print(
245
+ f"[blue]🔧[/blue] {len(recommendation.bug_fixes)} bug fixes detected"
246
+ )
247
+
164
248
  def validate_auth(self) -> bool:
165
249
  auth_methods = self._collect_auth_methods()
166
250
  return self._report_auth_status(auth_methods)
@@ -71,7 +71,7 @@ class TestProgress:
71
71
  border_style="yellow",
72
72
  title_style="bold yellow",
73
73
  expand=True,
74
- min_width=80,
74
+ min_width=74,
75
75
  )
76
76
 
77
77
  table.add_column("Type", style="cyan", ratio=1)
@@ -106,7 +106,7 @@ class TestProgress:
106
106
  border_style="cyan",
107
107
  title_style="bold cyan",
108
108
  expand=True,
109
- min_width=80,
109
+ min_width=74,
110
110
  )
111
111
 
112
112
  table.add_column("Metric", style="cyan", ratio=1)
@@ -12,12 +12,20 @@ class ConfigurationService:
12
12
  def __init__(self, console: Console, pkg_path: Path) -> None:
13
13
  self.console = console
14
14
  self.pkg_path = pkg_path
15
- self.config_generator = DynamicConfigGenerator()
15
+ # Extract package directory name from the pkg_path
16
+ package_directory = pkg_path.name if pkg_path != Path.cwd() else None
17
+ self.config_generator = DynamicConfigGenerator(package_directory)
16
18
 
17
19
  def update_precommit_config(self, options: OptionsProtocol) -> bool:
18
20
  try:
19
21
  mode = self._determine_config_mode(options)
20
- config_temp_path = generate_config_for_mode(mode)
22
+ # Extract package directory name from the pkg_path
23
+ package_directory = (
24
+ self.pkg_path.name if self.pkg_path != Path.cwd() else None
25
+ )
26
+ config_temp_path = generate_config_for_mode(
27
+ mode, package_directory=package_directory
28
+ )
21
29
  if not config_temp_path:
22
30
  self.console.print("[yellow]⚠️ No configuration generated[/ yellow]")
23
31
  return False
@@ -130,7 +130,7 @@ class PerformanceBenchmarker:
130
130
  obj = {
131
131
  "data": f"heavy_data_{i}" * 100,
132
132
  "metadata": {"created": time.time(), "index": i},
133
- "payload": list[t.Any](range(100)),
133
+ "payload": list(range(100)),
134
134
  }
135
135
  heavy_objects.append(obj)
136
136
 
@@ -153,7 +153,7 @@ class PerformanceBenchmarker:
153
153
  return {
154
154
  "data": f"heavy_data_{index}" * 100,
155
155
  "metadata": {"created": time.time(), "index": index},
156
- "payload": list[t.Any](range(100)),
156
+ "payload": list(range(100)),
157
157
  }
158
158
 
159
159
  lazy_obj = LazyLoader(create_heavy_object, f"heavy_object_{i}")
@@ -298,5 +298,27 @@ class PerformanceBenchmarker:
298
298
  self._logger.info(f"Exported benchmark results to {output_path}")
299
299
 
300
300
 
301
+ class PerformanceBenchmarkService:
302
+ """Service wrapper for performance benchmarking in workflow orchestration."""
303
+
304
+ def __init__(self, console, pkg_path):
305
+ self._console = console
306
+ self._pkg_path = pkg_path
307
+ self._benchmarker = PerformanceBenchmarker()
308
+ self._logger = get_logger("crackerjack.benchmark_service")
309
+
310
+ async def run_benchmark_suite(self) -> BenchmarkSuite | None:
311
+ """Run comprehensive benchmark suite and return results."""
312
+ try:
313
+ return await self._benchmarker.run_comprehensive_benchmark()
314
+ except Exception as e:
315
+ self._logger.warning(f"Benchmark suite failed: {e}")
316
+ return None
317
+
318
+ def export_results(self, suite: BenchmarkSuite, output_path: Path) -> None:
319
+ """Export benchmark results to file."""
320
+ self._benchmarker.export_benchmark_results(suite, output_path)
321
+
322
+
301
323
  def get_benchmarker() -> PerformanceBenchmarker:
302
324
  return PerformanceBenchmarker()
@@ -140,7 +140,7 @@ class PerformanceCache:
140
140
  ttl_seconds: int | None = None,
141
141
  invalidation_keys: builtins.set[str] | None = None,
142
142
  ) -> None:
143
- self.set[t.Any](key, value, ttl_seconds, invalidation_keys)
143
+ self.set(key, value, ttl_seconds, invalidation_keys)
144
144
 
145
145
  def invalidate(self, invalidation_key: str) -> int:
146
146
  with self._lock:
@@ -166,15 +166,15 @@ def main(file_paths: list[str]) -> int:
166
166
  if exit_code == 0:
167
167
  print("✅ All regex patterns validated successfully!")
168
168
  else:
169
- print("\n" + "=" * 80)
169
+ print("\n" + "=" * 74)
170
170
  print("REGEX VALIDATION FAILED")
171
- print("=" * 80)
171
+ print("=" * 74)
172
172
  print("To fix these issues: ")
173
173
  print("1. Use patterns from crackerjack.services.regex_patterns")
174
174
  print("2. Add new patterns to SAFE_PATTERNS with comprehensive tests")
175
175
  print("3. Use '# REGEX OK: reason' comment for legitimate exceptions")
176
176
  print("4. Fix \\g<1> replacement syntax (no spaces)")
177
- print("=" * 80)
177
+ print("=" * 74)
178
178
 
179
179
  return exit_code
180
180
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: crackerjack
3
- Version: 0.33.12
3
+ Version: 0.34.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
@@ -2,7 +2,7 @@ crackerjack/__init__.py,sha256=k8_Ev_3fWdjFtGNSJdSOvyaSLW54y3j484d3a8k_Ob4,1396
2
2
  crackerjack/__main__.py,sha256=zSZyImAZrHvOvGQT7-QHXqJPW8IQLH2c6QU5Awvy1eU,52552
3
3
  crackerjack/api.py,sha256=hXWqk9qLxYley6NiIIz9RemYhxC67cwwbktQdV1IPPY,21550
4
4
  crackerjack/code_cleaner.py,sha256=M1zVaq31uW0nOkPneKR8kfR3892gyyVx0VhFgRaxsj4,44338
5
- crackerjack/dynamic_config.py,sha256=1eIXUemABDmY7nN3i45L91GXDEKC14wXfkXsE7YVAWY,18360
5
+ crackerjack/dynamic_config.py,sha256=DOfq5Qjkfcww7qW9Q-MDOCn-TSUu6sZWMpZ4rbaFn40,21564
6
6
  crackerjack/errors.py,sha256=yYbZ92kn_y6acEWgQvEPvozAYs2HT65uLwAXrtXxGsE,10049
7
7
  crackerjack/interactive.py,sha256=QXFZrnbY0nc8rFJcivFAVFNgUTHXqLCu3FFv5bmq_eI,21634
8
8
  crackerjack/adapters/__init__.py,sha256=k-8ajMDL9DS9hV2FYOu694nmNQg3HkudJRuNcXmx8N4,451
@@ -34,7 +34,7 @@ crackerjack/cli/cache_handlers_enhanced.py,sha256=6X5rYSo1l-rj9eb7eB8mpA-6BlUagy
34
34
  crackerjack/cli/facade.py,sha256=e4_oB04awqEijI3yqiYAZGc6x09uMBa4ih0SsXpgMuY,3751
35
35
  crackerjack/cli/handlers.py,sha256=mYhwMLUKid6mQLff0ScpcnhP0yUS9IzOIMdM7VLkUCc,17178
36
36
  crackerjack/cli/interactive.py,sha256=bGOMXHYyuselHh2b4khbDGJ4tX9yI2rVN3SZ1oSDOaM,16988
37
- crackerjack/cli/options.py,sha256=rbjGnl4Y_xbJwWWZEfCVVqzO6RLackGvk4GYthbB2uo,33847
37
+ crackerjack/cli/options.py,sha256=g1OcUXA6a59dLQfNw-84HQt66zQR9QRBGnVvlbrbVwI,34010
38
38
  crackerjack/cli/utils.py,sha256=XC7dT8GNidhORjUe2p2hQOpZgCi2KvVCNu6g3azzgqY,584
39
39
  crackerjack/config/__init__.py,sha256=b0481N2f_JvGufMPcbo5IXu2VjYd111r1BHw0oD3x7o,330
40
40
  crackerjack/config/global_lock_config.py,sha256=PyonoA2__HKEEvn6SD-gEYh9iD7xIAdts2C3lNoTWhw,1996
@@ -47,14 +47,14 @@ crackerjack/core/enhanced_container.py,sha256=0rN9aDm5WfcH-g3D_dj7byc1aZK6dLKthK
47
47
  crackerjack/core/file_lifecycle.py,sha256=W0A0Bk3XTds1Za-h4gASAUdUrMozbq2XvGi-BjrnkGc,15149
48
48
  crackerjack/core/performance.py,sha256=ZVpDydd5BDycxwwZLOUG1tzwejwVvjJvFFSiKbDHpVQ,7606
49
49
  crackerjack/core/performance_monitor.py,sha256=5fMDcn8mSDAEJNm6DfNNLDt_NTcRwDHcbKx_eyqHeTs,13303
50
- crackerjack/core/phase_coordinator.py,sha256=qEkbaD4iXcpFi2voLMy4n0AQveQ8S5dxtAToZJIlN-Y,31126
50
+ crackerjack/core/phase_coordinator.py,sha256=Ubx1CchB3dQ-2GxlMgm_86O7GKyvmnodE5e4wBaw-8M,31366
51
51
  crackerjack/core/proactive_workflow.py,sha256=DcmQnOvP4uge5O13t0bfXfBI4K4EjD8fnJPQmlYMO5U,9774
52
52
  crackerjack/core/resource_manager.py,sha256=gFQ629Ves5vwd0KNSVCqDp4H57e7-342yRCWL4xRHD8,12797
53
53
  crackerjack/core/service_watchdog.py,sha256=Ttj1imOxvUea4Tkf5JO1e2dQtGIK7D-bX1xOsHTa-Kc,15688
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=Hqow7VkI7WeZVXHDn_Mt6Cc_aKhUaOh5PQ4wurtZfG0,65007
57
+ crackerjack/core/workflow_orchestrator.py,sha256=NgvOn6pTVV8aULxe-bbwT6GeIELRc-KNXU7bYKroGV8,70162
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
@@ -84,11 +84,11 @@ 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=10LzEiTH3Ck7uP6ky6JaMNSigwdZeWgwc6Ru53CR8sc,17740
87
+ crackerjack/managers/publish_manager.py,sha256=Jn0XqGjZNfLNiq3-XaQWGU950TRbDWW-5WMEn7jJ6ag,21373
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
91
- crackerjack/managers/test_manager_backup.py,sha256=Yj_HcJBgSM0DJTWOgRCn-pDslEjrmQ_094kBU6Mn1Ec,37932
91
+ crackerjack/managers/test_manager_backup.py,sha256=CR8D7WZ68ZrTADFqYJtVDUWnlznJXJNriPIdsp6ZB1E,37932
92
92
  crackerjack/managers/test_progress.py,sha256=B1013ygUk2nAo37whDXNA7n-FYdsEO4qj17fuDm_fdg,3058
93
93
  crackerjack/mcp/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
94
94
  crackerjack/mcp/cache.py,sha256=uq5XVeRjNyARfaAyN9DsaPURU_OHdBId5UfDvXbfSos,11974
@@ -157,7 +157,7 @@ crackerjack/services/backup_service.py,sha256=0e8AAo9svSBtbsbI9vwnAVSilB2fjph61l
157
157
  crackerjack/services/bounded_status_operations.py,sha256=mrBkUQwgtYjkbp-Y-5MdrU2A3rp3ZLVgOJv9vLdnJ8k,18763
158
158
  crackerjack/services/cache.py,sha256=FutQKxItKSdQFzOlWQaQzVBEfn6lbPXCDdvNnz3NCDQ,14536
159
159
  crackerjack/services/changelog_automation.py,sha256=KUeXCYLihRfLR0mUIRiI2aRQdCfe-45GnbB2gYNJJQE,14095
160
- crackerjack/services/config.py,sha256=Jseaw8bVRxLlMKo2zrEiTO2PPSK1CrlZJYlGFNKZRJ4,13182
160
+ crackerjack/services/config.py,sha256=fF3EpPfIxFBmZ9oTr7V64zCMBmxHWCmD_649qr0dgsI,13590
161
161
  crackerjack/services/config_integrity.py,sha256=Ac6-c7WuupsyrP2dxx_ijgjzpNnx9G0NWsXB-SZjelg,2904
162
162
  crackerjack/services/config_merge.py,sha256=FPh4u4J68JkNVf0AT1paNeEy2MjusSbYu9kN72LzR9w,18825
163
163
  crackerjack/services/config_template.py,sha256=RgSYFVNBxdBfMitlRqz7bzkEHaQhEWMm3pUMS7maRFU,18035
@@ -188,8 +188,8 @@ crackerjack/services/metrics.py,sha256=0_tiaK2-lBY0Y5MrS3Rrzyxft_JziGEEPgUXW486r
188
188
  crackerjack/services/parallel_executor.py,sha256=cwKj8KKzaANn6zLmvPRr1v_nije_VqF6O6jSprBFDdM,13604
189
189
  crackerjack/services/pattern_cache.py,sha256=fdD-HPoImUnd07rlGuDfyFWG86teWpNVr2LacJkCZ5Q,11097
190
190
  crackerjack/services/pattern_detector.py,sha256=soB9zXsjsNFo5pzMpFhFehNOemPTCQh-ARdKlHi46U0,18032
191
- crackerjack/services/performance_benchmarks.py,sha256=WWZq2J6uxDAPF_tkOumFaBIb8FP3x8bFkIrlKpozynM,10450
192
- crackerjack/services/performance_cache.py,sha256=Q8_nVePfUFbOhAOyvjoip-VodkGpBsqZcD7Zc4zo6wc,11865
191
+ crackerjack/services/performance_benchmarks.py,sha256=HPH86UM9IArkWQgXm71abAhuGuriUza4i6_zyJNOGPc,11326
192
+ crackerjack/services/performance_cache.py,sha256=d_sREaPQAdxFPKgLCgLMC4Iz-DdDc1QDYCbhvNYmUGQ,11858
193
193
  crackerjack/services/performance_monitor.py,sha256=cDu6FoiUX2VpslA3vG4JL6YQyIk1JzDcD4g5zR8NdjI,20214
194
194
  crackerjack/services/predictive_analytics.py,sha256=OcZYP0p2_zZuyWqbqzLHDoHTxVfrPm3VtiY-Yq9y7xc,17843
195
195
  crackerjack/services/quality_baseline.py,sha256=ImC1XTFTfrwFIDDDX1F0V7sGquAXI21oVxgjOSYIYFQ,8229
@@ -221,9 +221,9 @@ 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=y2pAp2BzfSC_3XYMIKGMpQFwwwDidPy3k2Y2almOy74,5811
225
- crackerjack-0.33.12.dist-info/METADATA,sha256=xSBoAQBABRSpw1pq9725j8awamEe39-zypROYaMA2vI,37943
226
- crackerjack-0.33.12.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
227
- crackerjack-0.33.12.dist-info/entry_points.txt,sha256=AJKNft0WXm9xoGUJ3Trl-iXHOWxRAYbagQiza3AILr4,57
228
- crackerjack-0.33.12.dist-info/licenses/LICENSE,sha256=fDt371P6_6sCu7RyqiZH_AhT1LdN3sN1zjBtqEhDYCk,1531
229
- crackerjack-0.33.12.dist-info/RECORD,,
224
+ crackerjack/tools/validate_regex_patterns.py,sha256=9ejFb7Tw1js_oydzuEeeeXvrU5ipHUEX9ATBfkLCCE8,5811
225
+ crackerjack-0.34.1.dist-info/METADATA,sha256=-sQdyBb8jKMkmJpTrCLuhSEdyNf14jNcAMENmumnCa0,37942
226
+ crackerjack-0.34.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
227
+ crackerjack-0.34.1.dist-info/entry_points.txt,sha256=AJKNft0WXm9xoGUJ3Trl-iXHOWxRAYbagQiza3AILr4,57
228
+ crackerjack-0.34.1.dist-info/licenses/LICENSE,sha256=fDt371P6_6sCu7RyqiZH_AhT1LdN3sN1zjBtqEhDYCk,1531
229
+ crackerjack-0.34.1.dist-info/RECORD,,