crackerjack 0.34.2__py3-none-any.whl → 0.35.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.

crackerjack/__main__.py CHANGED
@@ -11,7 +11,6 @@ from crackerjack.services.git import GitService
11
11
 
12
12
  from .cli import (
13
13
  CLI_OPTIONS,
14
- BumpOption,
15
14
  create_options,
16
15
  handle_interactive_mode,
17
16
  handle_standard_mode,
@@ -1220,9 +1219,9 @@ def main(
1220
1219
  update_precommit: bool = CLI_OPTIONS["update_precommit"],
1221
1220
  verbose: bool = CLI_OPTIONS["verbose"],
1222
1221
  debug: bool = CLI_OPTIONS["debug"],
1223
- publish: BumpOption | None = CLI_OPTIONS["publish"],
1224
- all: BumpOption | None = CLI_OPTIONS["all"],
1225
- bump: BumpOption | None = CLI_OPTIONS["bump"],
1222
+ publish: str | None = CLI_OPTIONS["publish"],
1223
+ all: str | None = CLI_OPTIONS["all"],
1224
+ bump: str | None = CLI_OPTIONS["bump"],
1226
1225
  strip_code: bool = CLI_OPTIONS["strip_code"],
1227
1226
  run_tests: bool = CLI_OPTIONS["run_tests"],
1228
1227
  benchmark: bool = CLI_OPTIONS["benchmark"],
@@ -325,8 +325,8 @@ class DocumentationAgent(SubAgent):
325
325
 
326
326
  All notable changes to this project will be documented in this file.
327
327
 
328
- The format is based on [Keep a Changelog](https: //keepachangelog.com/en/1.0.0/),
329
- and this project adheres to [Semantic Versioning](https: //semver.org/spec/v2.0.0.html).
328
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
329
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
330
330
 
331
331
  {entry}
332
332
  """
crackerjack/api.py CHANGED
@@ -601,10 +601,10 @@ class CrackerjackAPI:
601
601
  return None
602
602
 
603
603
  def _find_fallback_package_directory(self) -> Path | None:
604
- for possible_name in ("src", self.project_path.name):
605
- package_dir = self.project_path / possible_name
606
- if self._is_valid_python_package_directory(package_dir):
607
- return package_dir
604
+ # Only check project directory name, not src
605
+ package_dir = self.project_path / self.project_path.name
606
+ if self._is_valid_python_package_directory(package_dir):
607
+ return package_dir
608
608
  return None
609
609
 
610
610
  def _is_valid_python_package_directory(self, directory: Path) -> bool:
@@ -2,15 +2,36 @@ import typing as t
2
2
  import warnings
3
3
  from enum import Enum
4
4
 
5
+ import click
5
6
  import typer
6
7
  from pydantic import BaseModel, field_validator, model_validator
7
8
 
8
9
 
10
+ def parse_bump_option_with_flag_support(
11
+ ctx: click.Context, param: click.Parameter, value: str | None
12
+ ) -> str | None:
13
+ """Parse bump option that supports both flag usage (-p) and value usage (-p patch)."""
14
+ if value is None:
15
+ return None
16
+
17
+ # If the value starts with a dash, it's likely another flag that typer mistakenly captured
18
+ if value.startswith("-"):
19
+ # Put the value back into the arguments for typer to process
20
+ if hasattr(ctx, "protected_args"):
21
+ ctx.protected_args.insert(0, value)
22
+ elif hasattr(ctx, "args"):
23
+ ctx.args.insert(0, value)
24
+ return "interactive"
25
+
26
+ return value
27
+
28
+
9
29
  class BumpOption(str, Enum):
10
30
  patch = "patch"
11
31
  minor = "minor"
12
32
  major = "major"
13
33
  interactive = "interactive"
34
+ auto = "auto"
14
35
 
15
36
  def __str__(self) -> str:
16
37
  return str(self.value)
@@ -91,7 +112,7 @@ class Options(BaseModel):
91
112
  strip_code: bool | None = None # Replaces clean
92
113
  run_tests: bool = False # Replaces test
93
114
  ai_fix: bool | None = None # Replaces ai_agent
94
- full_release: BumpOption | None = None # Replaces all
115
+ full_release: str | None = None # Replaces all
95
116
  show_progress: bool | None = None # Replaces track_progress
96
117
  advanced_monitor: bool | None = None # Replaces enhanced_monitor
97
118
  coverage_report: bool | None = None # Replaces coverage_status
@@ -223,6 +244,11 @@ class Options(BaseModel):
223
244
  return None
224
245
  if value == "":
225
246
  return BumpOption.interactive
247
+
248
+ # Handle case where typer parsed a flag as the value (e.g., -p -c becomes value="-c")
249
+ if isinstance(value, str) and value.startswith("-"):
250
+ return BumpOption.interactive
251
+
226
252
  try:
227
253
  return BumpOption(value.lower())
228
254
  except ValueError:
@@ -275,9 +301,12 @@ CLI_OPTIONS = {
275
301
  None,
276
302
  "-p",
277
303
  "--publish",
304
+ callback=parse_bump_option_with_flag_support,
278
305
  help=(
279
- "Bump version and publish to PyPI (patch, minor, major). "
280
- "Use 'interactive' to be prompted for version selection."
306
+ "Bump version and publish to PyPI (patch, minor, major, auto). "
307
+ "Use 'interactive' to be prompted for version selection. "
308
+ "Use 'auto' to automatically use AI recommendations. "
309
+ "When used as a flag (-p), defaults to 'interactive'."
281
310
  ),
282
311
  case_sensitive=False,
283
312
  ),
@@ -285,14 +314,16 @@ CLI_OPTIONS = {
285
314
  None,
286
315
  "-a",
287
316
  "--all",
288
- help="Full release workflow: bump version, run quality checks, and publish (patch, minor, major).",
317
+ callback=parse_bump_option_with_flag_support,
318
+ help="Full release workflow: bump version, run quality checks, and publish (patch, minor, major, auto). When used as a flag (-a), defaults to 'interactive'.",
289
319
  case_sensitive=False,
290
320
  ),
291
321
  "bump": typer.Option(
292
322
  None,
293
323
  "-b",
294
324
  "--bump",
295
- help="Bump version (patch, minor, major).",
325
+ callback=parse_bump_option_with_flag_support,
326
+ help="Bump version (patch, minor, major, auto). When used as a flag (-b), defaults to 'interactive'.",
296
327
  case_sensitive=False,
297
328
  ),
298
329
  "benchmark": typer.Option(
@@ -644,7 +675,8 @@ CLI_OPTIONS = {
644
675
  None,
645
676
  "-a",
646
677
  "--full-release",
647
- help="Complete release workflow: strip code, run tests, bump version, and publish. Equivalent to `-x -t -p <version> -c`.",
678
+ callback=parse_bump_option_with_flag_support,
679
+ help="Complete release workflow: strip code, run tests, bump version, and publish (patch, minor, major, auto). Equivalent to `-x -t -p <version> -c`. When used as a flag (-a), defaults to 'interactive'.",
648
680
  case_sensitive=False,
649
681
  ),
650
682
  "show_progress": typer.Option(
@@ -869,8 +901,8 @@ def create_options(
869
901
  update_precommit: bool,
870
902
  verbose: bool,
871
903
  debug: bool,
872
- publish: BumpOption | None,
873
- bump: BumpOption | None,
904
+ publish: str | None,
905
+ bump: str | None,
874
906
  benchmark: bool,
875
907
  test_workers: int,
876
908
  test_timeout: int,
@@ -953,7 +985,7 @@ def create_options(
953
985
  strip_code: bool | None = None,
954
986
  run_tests: bool = False,
955
987
  ai_fix: bool | None = None,
956
- full_release: BumpOption | None = None,
988
+ full_release: str | None = None,
957
989
  show_progress: bool | None = None,
958
990
  advanced_monitor: bool | None = None,
959
991
  coverage_report: bool | None = None,
@@ -499,13 +499,12 @@ class DynamicConfigGenerator:
499
499
  except Exception:
500
500
  pass
501
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
502
+ # Fallback to project directory name
503
+ if (current_dir / current_dir.name).exists():
504
+ return current_dir.name
506
505
 
507
- # Default fallback
508
- return "src"
506
+ # Default fallback to current directory name
507
+ return current_dir.name
509
508
 
510
509
  def _should_include_hook(
511
510
  self,
@@ -565,6 +564,13 @@ class DynamicConfigGenerator:
565
564
  "crackerjack", self.package_directory
566
565
  )
567
566
 
567
+ # Ensure hooks exclude src directories to avoid JavaScript conflicts
568
+ if hook["exclude"]:
569
+ if "src/" not in hook["exclude"]:
570
+ hook["exclude"] = f"{hook['exclude']}|^src/"
571
+ else:
572
+ hook["exclude"] = "^src/"
573
+
568
574
  return hook
569
575
 
570
576
  def group_hooks_by_repo(
@@ -284,7 +284,7 @@ class PublishManagerImpl:
284
284
  [
285
285
  "keyring",
286
286
  "get",
287
- "https: //upload.pypi.org/legacy/",
287
+ "https://upload.pypi.org/legacy/",
288
288
  "__token__",
289
289
  ],
290
290
  )
@@ -315,7 +315,7 @@ class PublishManagerImpl:
315
315
  " 1. Set environment variable: export UV_PUBLISH_TOKEN=<your-pypi-token>",
316
316
  )
317
317
  self.console.print(
318
- " 2. Use keyring: keyring set[t.Any] https: //upload.pypi.org/legacy/ __token__",
318
+ " 2. Use keyring: keyring set[t.Any] https://upload.pypi.org/legacy/ __token__",
319
319
  )
320
320
  self.console.print(
321
321
  " 3. Ensure token starts with 'pypi-' and is properly formatted",
@@ -434,7 +434,7 @@ class PublishManagerImpl:
434
434
  package_name = self._get_package_name()
435
435
 
436
436
  if package_name and current_version:
437
- url = f"https: //pypi.org/project/{package_name}/{current_version}/"
437
+ url = f"https://pypi.org/project/{package_name}/{current_version}/"
438
438
  self.console.print(f"[cyan]🔗[/ cyan] Package URL: {url}")
439
439
 
440
440
  def _get_package_name(self) -> str | None:
@@ -157,11 +157,9 @@ class JobDataCollector:
157
157
  "network_operations",
158
158
  timeout=5.0,
159
159
  ):
160
- websocket_base = self.websocket_url.replace(
161
- "ws: //", "http: //"
162
- ).replace(
163
- "wss: //",
164
- "https: //",
160
+ websocket_base = self.websocket_url.replace("ws://", "http://").replace(
161
+ "wss://",
162
+ "https://",
165
163
  )
166
164
 
167
165
  async with (
@@ -6,6 +6,8 @@ from typing import Final
6
6
 
7
7
  from rich.console import Console
8
8
 
9
+ from ..ui.server_panels import create_server_panels
10
+
9
11
  try:
10
12
  import tomli
11
13
  except ImportError:
@@ -259,18 +261,23 @@ def _print_server_info(
259
261
  websocket_port: int | None,
260
262
  http_mode: bool,
261
263
  ) -> None:
262
- console.print("[green]Starting Crackerjack MCP Server...[/ green]")
263
- console.print(f"Project path: {project_path}")
264
+ panels = create_server_panels(console)
264
265
 
265
266
  if mcp_config.get("http_enabled", False) or http_mode:
266
- console.print(
267
- f"[cyan]HTTP Mode: http: //{mcp_config['http_host']}: {mcp_config['http_port']}/mcp[/ cyan]"
267
+ mode = "HTTP"
268
+ http_endpoint = (
269
+ f"http://{mcp_config['http_host']}:{mcp_config['http_port']}/mcp"
268
270
  )
269
271
  else:
270
- console.print("[cyan]STDIO Mode[/ cyan]")
272
+ mode = "STDIO"
273
+ http_endpoint = None
271
274
 
272
- if websocket_port:
273
- console.print(f"WebSocket port: {websocket_port}")
275
+ panels.start_panel(
276
+ project_path=project_path,
277
+ mode=mode,
278
+ http_endpoint=http_endpoint,
279
+ websocket_port=websocket_port,
280
+ )
274
281
 
275
282
 
276
283
  def _run_mcp_server(
@@ -331,6 +338,26 @@ def main(
331
338
  f"[yellow]⚠️ WebSocket server auto-start failed: {e}[/yellow]"
332
339
  )
333
340
 
341
+ # Show final success panel before starting the server
342
+ panels = create_server_panels(console)
343
+
344
+ if mcp_config.get("http_enabled", False) or http_mode:
345
+ http_endpoint = (
346
+ f"http://{mcp_config['http_host']}:{mcp_config['http_port']}/mcp"
347
+ )
348
+ else:
349
+ http_endpoint = None
350
+
351
+ websocket_monitor = (
352
+ f"ws://127.0.0.1:{websocket_port}" if websocket_port else None
353
+ )
354
+
355
+ panels.success_panel(
356
+ http_endpoint=http_endpoint,
357
+ websocket_monitor=websocket_monitor,
358
+ process_id=None, # Will be set by the process manager
359
+ )
360
+
334
361
  _run_mcp_server(mcp_app, mcp_config, http_mode)
335
362
 
336
363
  except KeyboardInterrupt:
@@ -452,13 +452,13 @@ class DependencyMonitorService:
452
452
 
453
453
  import requests
454
454
 
455
- url = f"https: //pypi.org/pypi/{package}/json"
455
+ url = f"https://pypi.org/pypi/{package}/json"
456
456
  self._validate_pypi_url(url)
457
457
 
458
458
  parsed = urlparse(url)
459
459
 
460
460
  if parsed.scheme != "https" or parsed.netloc != "pypi.org":
461
- msg = f"Invalid URL: only https: //pypi.org URLs are allowed, got {url}"
461
+ msg = f"Invalid URL: only https://pypi.org URLs are allowed, got {url}"
462
462
  raise ValueError(msg)
463
463
 
464
464
  response = requests.get(url, timeout=10, verify=True)
@@ -347,11 +347,11 @@ class HealthMetricsService:
347
347
  try:
348
348
  from urllib.parse import urlparse
349
349
 
350
- url = f"https: //pypi.org/pypi/{package_name}/json"
350
+ url = f"https://pypi.org/pypi/{package_name}/json"
351
351
 
352
352
  parsed = urlparse(url)
353
353
  if parsed.scheme != "https" or parsed.netloc != "pypi.org":
354
- msg = f"Invalid URL: only https: //pypi.org URLs are allowed, got {url}"
354
+ msg = f"Invalid URL: only https://pypi.org URLs are allowed, got {url}"
355
355
  raise ValueError(msg)
356
356
 
357
357
  if not parsed.path.startswith("/pypi/") or not parsed.path.endswith(
@@ -7,6 +7,7 @@ from pathlib import Path
7
7
 
8
8
  from rich.console import Console
9
9
 
10
+ from ..ui.server_panels import create_server_panels
10
11
  from .secure_subprocess import execute_secure_subprocess
11
12
  from .security_logger import get_security_logger
12
13
 
@@ -201,21 +202,27 @@ def stop_mcp_server(console: Console | None = None) -> bool:
201
202
  if console is None:
202
203
  console = Console()
203
204
 
205
+ panels = create_server_panels(console)
204
206
  processes = find_mcp_server_processes()
205
207
 
206
208
  if not processes:
207
209
  console.print("[yellow]⚠️ No MCP server processes found[/ yellow]")
208
210
  return True
209
211
 
212
+ panels.stop_servers(len(processes))
213
+
210
214
  success = True
211
215
  for proc in processes:
212
- console.print(f"🛑 Stopping MCP server process {proc['pid']}")
216
+ console.print(f"Stopping process {proc['pid']}...")
213
217
  if stop_process(proc["pid"]):
214
- console.print(f"✅ Stopped process {proc['pid']}")
218
+ console.print(f"✅ Process {proc['pid']} terminated gracefully")
215
219
  else:
216
220
  console.print(f"❌ Failed to stop process {proc['pid']}")
217
221
  success = False
218
222
 
223
+ if success:
224
+ panels.stop_complete(len(processes))
225
+
219
226
  return success
220
227
 
221
228
 
@@ -282,14 +289,15 @@ def restart_mcp_server(
282
289
  if console is None:
283
290
  console = Console()
284
291
 
285
- console.print("[bold cyan]🔄 Restarting MCP server...[/ bold cyan]")
292
+ panels = create_server_panels(console)
293
+ panels.restart_header()
286
294
 
287
295
  stop_mcp_server(console)
288
296
 
289
- console.print("⏳ Waiting for cleanup...")
297
+ panels.cleanup_wait()
290
298
  time.sleep(2)
291
299
 
292
- console.print("🚀 Starting new MCP server...")
300
+ panels.starting_server()
293
301
  try:
294
302
  cmd = [sys.executable, "-m", "crackerjack", "--start-mcp-server"]
295
303
  if websocket_port:
@@ -297,7 +305,7 @@ def restart_mcp_server(
297
305
 
298
306
  import subprocess
299
307
 
300
- subprocess.Popen(
308
+ process = subprocess.Popen(
301
309
  cmd,
302
310
  stdout=subprocess.DEVNULL,
303
311
  stderr=subprocess.DEVNULL,
@@ -310,11 +318,24 @@ def restart_mcp_server(
310
318
  purpose="mcp_server_restart",
311
319
  )
312
320
 
313
- console.print("✅ MCP server restart initiated")
321
+ # Give the server a moment to start
322
+ time.sleep(1)
323
+
324
+ # Display success panel with server details
325
+ http_endpoint = "http://127.0.0.1:8676/mcp"
326
+ websocket_monitor = (
327
+ f"ws://127.0.0.1:{websocket_port or 8675}" if websocket_port else None
328
+ )
329
+
330
+ panels.success_panel(
331
+ http_endpoint=http_endpoint,
332
+ websocket_monitor=websocket_monitor,
333
+ process_id=process.pid,
334
+ )
314
335
  return True
315
336
 
316
337
  except Exception as e:
317
- console.print(f"❌ Failed to restart MCP server: {e}")
338
+ panels.failure_panel(str(e))
318
339
  return False
319
340
 
320
341
 
@@ -0,0 +1 @@
1
+ """UI components for Crackerjack."""
@@ -0,0 +1,126 @@
1
+ """Rich panel utilities for MCP server operations with consistent styling."""
2
+
3
+ import typing as t
4
+ from pathlib import Path
5
+
6
+ from rich.console import Console
7
+ from rich.panel import Panel
8
+ from rich.text import Text
9
+
10
+
11
+ class ServerPanels:
12
+ """Rich panel utilities for server operations with 74-char width limit."""
13
+
14
+ WIDTH = 74 # Match session-mgmt-mcp width constraint
15
+
16
+ def __init__(self, console: Console | None = None) -> None:
17
+ self.console = console or Console()
18
+
19
+ def restart_header(self) -> None:
20
+ """Display server restart header panel."""
21
+ panel = Panel(
22
+ "🔄 Restarting Crackerjack MCP Server...",
23
+ width=self.WIDTH,
24
+ title="Server Restart",
25
+ style="cyan",
26
+ )
27
+ self.console.print(panel)
28
+
29
+ def stop_servers(self, count: int) -> None:
30
+ """Display stopping servers status."""
31
+ self.console.print("📴 Stopping existing servers...")
32
+ self.console.print(f"🛑 Stopping {count} server process(es)...")
33
+
34
+ def process_stopped(self, pid: int) -> None:
35
+ """Display process stopped message."""
36
+ self.console.print(f"Stopping process {pid}...")
37
+ self.console.print(f"✅ Process {pid} terminated gracefully")
38
+
39
+ def stop_complete(self, count: int) -> None:
40
+ """Display stop completion panel."""
41
+ panel = Panel(
42
+ f"✅ Successfully stopped {count} process(es)",
43
+ width=self.WIDTH,
44
+ title="Server Stopped",
45
+ style="green",
46
+ )
47
+ self.console.print(panel)
48
+
49
+ def cleanup_wait(self) -> None:
50
+ """Display cleanup waiting message."""
51
+ self.console.print("⏳ Waiting for cleanup...")
52
+
53
+ def starting_server(self) -> None:
54
+ """Display starting server message."""
55
+ self.console.print("🚀 Starting fresh server instance...")
56
+ self.console.print("🚀 Starting Crackerjack MCP Server...")
57
+ self.console.print("⏳ Waiting for server to start...")
58
+
59
+ def success_panel(
60
+ self,
61
+ http_endpoint: str | None = None,
62
+ websocket_monitor: str | None = None,
63
+ process_id: int | None = None
64
+ ) -> None:
65
+ """Display success panel with server details."""
66
+ content = Text()
67
+ content.append("✅ Server started successfully!\n", style="green bold")
68
+
69
+ if http_endpoint:
70
+ content.append(f"🌐 HTTP Endpoint: {http_endpoint}\n", style="cyan")
71
+
72
+ if websocket_monitor:
73
+ content.append(f"🔌 WebSocket Monitor: {websocket_monitor}\n", style="cyan")
74
+
75
+ if process_id:
76
+ content.append(f"📊 Process ID: {process_id}", style="cyan")
77
+
78
+ panel = Panel(
79
+ content,
80
+ width=self.WIDTH,
81
+ title="Crackerjack MCP Server",
82
+ style="green",
83
+ )
84
+ self.console.print(panel)
85
+
86
+ def failure_panel(self, error: str) -> None:
87
+ """Display failure panel with error details."""
88
+ panel = Panel(
89
+ f"❌ Server failed to start: {error}",
90
+ width=self.WIDTH,
91
+ title="Server Error",
92
+ style="red",
93
+ )
94
+ self.console.print(panel)
95
+
96
+ def start_panel(
97
+ self,
98
+ project_path: Path,
99
+ mode: str = "STDIO",
100
+ http_endpoint: str | None = None,
101
+ websocket_port: int | None = None,
102
+ ) -> None:
103
+ """Display server start panel with configuration details."""
104
+ content = Text()
105
+ content.append("🚀 Starting Crackerjack MCP Server...\n", style="green bold")
106
+ content.append(f"📁 Project: {project_path.name}\n", style="cyan")
107
+ content.append(f"🔗 Mode: {mode}\n", style="cyan")
108
+
109
+ if http_endpoint:
110
+ content.append(f"🌐 HTTP: {http_endpoint}\n", style="cyan")
111
+
112
+ if websocket_port:
113
+ content.append(f"🔌 WebSocket: {websocket_port}", style="cyan")
114
+
115
+ panel = Panel(
116
+ content,
117
+ width=self.WIDTH,
118
+ title="Server Configuration",
119
+ style="green",
120
+ )
121
+ self.console.print(panel)
122
+
123
+
124
+ def create_server_panels(console: Console | None = None) -> ServerPanels:
125
+ """Factory function to create ServerPanels instance."""
126
+ return ServerPanels(console)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: crackerjack
3
- Version: 0.34.2
3
+ Version: 0.35.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
@@ -1,8 +1,8 @@
1
1
  crackerjack/__init__.py,sha256=k8_Ev_3fWdjFtGNSJdSOvyaSLW54y3j484d3a8k_Ob4,1396
2
- crackerjack/__main__.py,sha256=zSZyImAZrHvOvGQT7-QHXqJPW8IQLH2c6QU5Awvy1eU,52552
3
- crackerjack/api.py,sha256=hXWqk9qLxYley6NiIIz9RemYhxC67cwwbktQdV1IPPY,21550
2
+ crackerjack/__main__.py,sha256=lE5ZDbAzI9TLCzMTxFGw23Dk1hP-MEhd1i_nNbi_Mag,52515
3
+ crackerjack/api.py,sha256=sfKzCphsTMFCvdNizviPdYemwg0H8Oei_5C08LAuDvA,21538
4
4
  crackerjack/code_cleaner.py,sha256=M1zVaq31uW0nOkPneKR8kfR3892gyyVx0VhFgRaxsj4,44338
5
- crackerjack/dynamic_config.py,sha256=DOfq5Qjkfcww7qW9Q-MDOCn-TSUu6sZWMpZ4rbaFn40,21564
5
+ crackerjack/dynamic_config.py,sha256=YGlUyTEp_K9rGWtLsboXMtVeKyI7bUoNoftO3ZnCiwc,21815
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
@@ -15,7 +15,7 @@ crackerjack/agents/__init__.py,sha256=OkL6WdzTk1_EnhJpIPsHV2qCrw6tqKegu_zTpZXnJi
15
15
  crackerjack/agents/architect_agent.py,sha256=Gq9eAy1_pl-1iEYC28xn4rdIPi9AVynZ7Sd5FnBrNn8,8130
16
16
  crackerjack/agents/base.py,sha256=XRF0VKrkIB-QJ_izuM33EPKL26gBABrDKKgMNJy9lJQ,4888
17
17
  crackerjack/agents/coordinator.py,sha256=uLh-9aTJedqmTSDmwV2dx42_aeIIOCEFbcdj9wcIR4w,22470
18
- crackerjack/agents/documentation_agent.py,sha256=tPtNO-2K1f4LELDtC4xnM6m8tet5HPr-PEb9j020908,17180
18
+ crackerjack/agents/documentation_agent.py,sha256=bI9qPJ5rTZrjimythO_N27zpJFrFcP6i1N2hYZMr_u4,17178
19
19
  crackerjack/agents/dry_agent.py,sha256=OP386uTOEQEQZCetCIHV6j7_cl7BKrhK3BmAmRqdgYI,13302
20
20
  crackerjack/agents/formatting_agent.py,sha256=eDkLABvpkc3vkYLBjsjib9_AtqsdjxyPIddIvD293L8,6821
21
21
  crackerjack/agents/import_optimization_agent.py,sha256=DoDaN7Pb0Z6Nt6YkkKeWMu3Paffy5eOb6ao4khtL3ko,40578
@@ -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=g1OcUXA6a59dLQfNw-84HQt66zQR9QRBGnVvlbrbVwI,34010
37
+ crackerjack/cli/options.py,sha256=tpvOMQHrL7-j9wuo2_NwvzJTAWF3XcyeOEonQPbepa4,35433
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
@@ -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=Jn0XqGjZNfLNiq3-XaQWGU950TRbDWW-5WMEn7jJ6ag,21373
87
+ crackerjack/managers/publish_manager.py,sha256=-sHzSVMF6fSUXuPdWA47gBFkFCT8sIb4cPj3GJB-uX4,21370
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
@@ -97,11 +97,11 @@ crackerjack/mcp/context.py,sha256=T1rhScFxbqi0Kaf6o8NusVUIwc8o7YGxcsLdmlWVsPI,28
97
97
  crackerjack/mcp/dashboard.py,sha256=eApQekZe1DfKBrlDW5yobyqaN_gdh17ZQlqGmut5TCs,19602
98
98
  crackerjack/mcp/enhanced_progress_monitor.py,sha256=xhACaEjreDw1cLObJmhr5ttowl5mRqeohmMzQfRQj3w,16448
99
99
  crackerjack/mcp/file_monitor.py,sha256=4OR-nxqH0ettiGInIY6MckFoflwX5VP9bgxXcAZZzfE,12824
100
- crackerjack/mcp/progress_components.py,sha256=OzD6jccwQOk2-pAcq2-D7f9E_VKsnhZ7AYBGBcT59-g,20577
100
+ crackerjack/mcp/progress_components.py,sha256=URtnrNv1QQzUKY3msO_cBrYHjPlzVDqFbZa_trfZHXY,20535
101
101
  crackerjack/mcp/progress_monitor.py,sha256=3TxQ_Og1md8zuNrH9cltOa8RQf_5lHNiVh9DiBkvbBM,37546
102
102
  crackerjack/mcp/rate_limiter.py,sha256=oM29wHyvoR9Q9cMBAEqWquHoiBBS1ylrZkUhhFnDkVo,12309
103
103
  crackerjack/mcp/server.py,sha256=-AdHHoFNAtoPM1A3_M2giZbIbggUhhvv16uIXk2xqNo,403
104
- crackerjack/mcp/server_core.py,sha256=c1R_X8U2t1B0_4ZfJEHy_e2AXMF6vr9e6KtNGvorytc,10589
104
+ crackerjack/mcp/server_core.py,sha256=o93_j8nmGRIl-FL-Y5cKCDDJh3J7vTi1SmxIOdoqj0w,11301
105
105
  crackerjack/mcp/service_watchdog.py,sha256=_z99JrYrmVaXI2tVERts0_xHsl4pjltD5iF47mQVADk,16826
106
106
  crackerjack/mcp/state.py,sha256=pNclwUxGTH5YiRMq8hB15B9_rpX9aJ-IVnhMw7q9dtI,14427
107
107
  crackerjack/mcp/task_manager.py,sha256=hxuZGbRHwEBO-W3UTbg7Lx7gMhTcPRaAiQ8I8VIFs6g,8713
@@ -166,7 +166,7 @@ crackerjack/services/coverage_badge_service.py,sha256=gzC3LEyVLt4rpf378APsFVRGgN
166
166
  crackerjack/services/coverage_ratchet.py,sha256=eKxmFyg-7Rnctnk--6P-yNNOFhoKwzTxd4iCJ52dtZE,13439
167
167
  crackerjack/services/debug.py,sha256=kTy2vy6JjjNReNn4z7xmhXDVIj8xImaE67kYi-Pfb3o,23227
168
168
  crackerjack/services/dependency_analyzer.py,sha256=4MxexuyQ3wyPHVsHr77N22EsAqZTDGOVcSBSm1mOXFQ,16322
169
- crackerjack/services/dependency_monitor.py,sha256=g2XocjAs5UJmgUfAFFbKc0__cYDMAZqvNVgFufswi6E,20562
169
+ crackerjack/services/dependency_monitor.py,sha256=x_PpRUt-LbzHlTyoSt2kiXTQn2fqAiqouiwFSAU9SGg,20560
170
170
  crackerjack/services/documentation_generator.py,sha256=xDJ2dv3Q_HTGCPJADKPVtYzcIpSOhuH5qUxPU2ttICE,16482
171
171
  crackerjack/services/documentation_service.py,sha256=V2fY01u_tP_ep87KMGxIocgP6hfpwbf-YyVqssLQSns,24792
172
172
  crackerjack/services/enhanced_filesystem.py,sha256=IT-obfj2U2Sfy0iJOq0ZAiczEN6LdHf6VAhnugQe1mQ,15487
@@ -175,7 +175,7 @@ crackerjack/services/error_pattern_analyzer.py,sha256=bTMwhAMAjVPSUXrNkrtm1KDqfx
175
175
  crackerjack/services/file_hasher.py,sha256=eReytwwK-_-B8JBnpwytDC52cKKgg4qpaxaZKcQjD-0,5211
176
176
  crackerjack/services/filesystem.py,sha256=nmL3mYqylS_BSQpwFbC7EMHoA44K5qUxa9CPg1QFZvc,17480
177
177
  crackerjack/services/git.py,sha256=g0D9K7PFGWiv_-CbPXEhGtxJVJccEsshYNEmGstjXss,12716
178
- crackerjack/services/health_metrics.py,sha256=KmwFlvcB-Pb8DnDI0IRV9ETDdp_vJTaGlhJ_HmBL2YY,21538
178
+ crackerjack/services/health_metrics.py,sha256=nDuKEC2a5csOhMpy6zXJkls1Y4Vfrr62-4cFcWCr8ow,21536
179
179
  crackerjack/services/heatmap_generator.py,sha256=zz5V-zXPfoCGNXoj7iuyOeFuDRRUhFpxuENUnd0X75g,26200
180
180
  crackerjack/services/initialization.py,sha256=_ZjGpIG5eGHzrVXCxlhlouhY-E-4OITEln1GDTswZ6s,26049
181
181
  crackerjack/services/input_validator.py,sha256=Botr3ottp9InSw163QaFrNfy0kM_STsJdWBbjsCX96M,22262
@@ -202,7 +202,7 @@ crackerjack/services/secure_status_formatter.py,sha256=yhwNtzvvQVcuHsNOTNZMzlqIM
202
202
  crackerjack/services/secure_subprocess.py,sha256=upuiBL0sYIElC8DWQ622-A6572zBaSBoMPVnNM8AeaQ,19838
203
203
  crackerjack/services/security.py,sha256=plgIz-B8oYN_mpF4NYrqHnT7TRcsp4jr0-YlV9WgD5o,7298
204
204
  crackerjack/services/security_logger.py,sha256=AAjd9VKVmCo158UifyEKd79VgtWKeuaIVyXYL8qvqT8,17001
205
- crackerjack/services/server_manager.py,sha256=IQ0oUFEEMZTxI8csecIJzkCSMESE5KIkYqPxa56tvUw,11399
205
+ crackerjack/services/server_manager.py,sha256=MwvMMxhaCiZD4pcKM2ODXB-gu2s22n_v_uIqrwoJsHs,11934
206
206
  crackerjack/services/smart_scheduling.py,sha256=VSaL7DpKR6aa0sC_TUrYP9ZgC9CB7tE3TTNzEqB-GpE,4352
207
207
  crackerjack/services/status_authentication.py,sha256=2OJ1MoWlBuvUUXOX02N_zdWKzQfXz4jhEZpsmIJfQ00,16453
208
208
  crackerjack/services/status_security_manager.py,sha256=et0h6w7Wt1cPFjzg7frsykAQ-IMfiAXr44WU9Fs6-1U,10967
@@ -222,8 +222,10 @@ crackerjack/slash_commands/status.md,sha256=U3qqppVLtIIm2lEiMYaKagaHYLI9UplL7OH1
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
224
  crackerjack/tools/validate_regex_patterns.py,sha256=9ejFb7Tw1js_oydzuEeeeXvrU5ipHUEX9ATBfkLCCE8,5811
225
- crackerjack-0.34.2.dist-info/METADATA,sha256=lHdu1Cejg0Jvt5xvQfc1oyFpQ7zX2fpNZnFjmGOoLro,37942
226
- crackerjack-0.34.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
227
- crackerjack-0.34.2.dist-info/entry_points.txt,sha256=AJKNft0WXm9xoGUJ3Trl-iXHOWxRAYbagQiza3AILr4,57
228
- crackerjack-0.34.2.dist-info/licenses/LICENSE,sha256=fDt371P6_6sCu7RyqiZH_AhT1LdN3sN1zjBtqEhDYCk,1531
229
- crackerjack-0.34.2.dist-info/RECORD,,
225
+ crackerjack/ui/__init__.py,sha256=seLTuIcCzZDvUNfCvm1xNkiw0814JqUxoaQKmocJPpU,36
226
+ crackerjack/ui/server_panels.py,sha256=1MsCbKVPUD6EOONw7miovL_r5CDvllTxjnVU14dKtIE,4249
227
+ crackerjack-0.35.1.dist-info/METADATA,sha256=s6RH3Wqup4CHvmsEcd3fTtqBnshDsrGM9-0cZJkDMgE,37942
228
+ crackerjack-0.35.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
229
+ crackerjack-0.35.1.dist-info/entry_points.txt,sha256=AJKNft0WXm9xoGUJ3Trl-iXHOWxRAYbagQiza3AILr4,57
230
+ crackerjack-0.35.1.dist-info/licenses/LICENSE,sha256=fDt371P6_6sCu7RyqiZH_AhT1LdN3sN1zjBtqEhDYCk,1531
231
+ crackerjack-0.35.1.dist-info/RECORD,,