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

@@ -157,7 +157,7 @@ class PhaseCoordinator:
157
157
  "CLAUDE.md",
158
158
  "RULES.md",
159
159
  ".gitignore",
160
- "mcp.json",
160
+ "example.mcp.json",
161
161
  "uv.lock",
162
162
  ]
163
163
 
@@ -172,10 +172,12 @@ class WorkflowPipeline:
172
172
  async def _execute_workflow_phases(self, options: OptionsProtocol) -> bool:
173
173
  success = True
174
174
  self.phases.run_configuration_phase(options)
175
+
175
176
  if not self.phases.run_cleaning_phase(options):
176
177
  success = False
177
178
  self.session.fail_task("workflow", "Cleaning phase failed")
178
179
  return False
180
+
179
181
  if not await self._execute_quality_phase(options):
180
182
  success = False
181
183
  return False
@@ -263,6 +265,21 @@ class WorkflowPipeline:
263
265
  ) -> bool:
264
266
  """Handle standard workflow where all phases must pass."""
265
267
  success = testing_passed and comprehensive_passed
268
+
269
+ # Debug information for workflow continuation issues
270
+ if not success and getattr(options, "verbose", False):
271
+ self.console.print(
272
+ f"[yellow]⚠️ Workflow stopped - testing_passed: {testing_passed}, comprehensive_passed: {comprehensive_passed}[/yellow]"
273
+ )
274
+ if not testing_passed:
275
+ self.console.print(
276
+ "[yellow] → Tests reported failure despite appearing successful[/yellow]"
277
+ )
278
+ if not comprehensive_passed:
279
+ self.console.print(
280
+ "[yellow] → Comprehensive hooks reported failure despite appearing successful[/yellow]"
281
+ )
282
+
266
283
  if options.ai_agent and self._should_debug():
267
284
  self.debugger.log_iteration_end(iteration, success)
268
285
  return success
@@ -136,6 +136,36 @@ class TestManager:
136
136
  except Exception:
137
137
  return None
138
138
 
139
+ def get_coverage(self) -> dict[str, t.Any]:
140
+ """Get coverage information as required by TestManagerProtocol."""
141
+ try:
142
+ # Get the ratchet status which includes coverage information
143
+ status = self.coverage_ratchet.get_status_report()
144
+
145
+ if status.get("status") == "not_initialized":
146
+ return {
147
+ "status": "not_initialized",
148
+ "coverage_percent": 0.0,
149
+ "message": "Coverage ratchet not initialized",
150
+ }
151
+
152
+ return {
153
+ "status": "active",
154
+ "coverage_percent": status.get("current_coverage", 0.0),
155
+ "target_coverage": status.get("target_coverage", 100.0),
156
+ "next_milestone": status.get("next_milestone"),
157
+ "progress_percent": status.get("progress_percent", 0.0),
158
+ "last_updated": status.get("last_updated"),
159
+ "milestones_achieved": status.get("milestones_achieved", []),
160
+ }
161
+ except Exception as e:
162
+ return {
163
+ "status": "error",
164
+ "coverage_percent": 0.0,
165
+ "error": str(e),
166
+ "message": "Failed to get coverage information",
167
+ }
168
+
139
169
  def has_tests(self) -> bool:
140
170
  """Check if project has tests."""
141
171
  test_directories = ["tests", "test"]
@@ -219,11 +249,17 @@ class TestManager:
219
249
  self._handle_coverage_improvement(ratchet_result)
220
250
  return True
221
251
  else:
222
- self.console.print(
223
- f"[red]📉[/red] Coverage regression: "
224
- f"{ratchet_result.get('current_coverage', 0):.2f}% < "
225
- f"{ratchet_result.get('previous_coverage', 0):.2f}%"
226
- )
252
+ # Use the message from the ratchet result if available, or construct from available data
253
+ if "message" in ratchet_result:
254
+ self.console.print(f"[red]📉[/red] {ratchet_result['message']}")
255
+ else:
256
+ # Fallback to constructing message from available keys
257
+ current = ratchet_result.get("current_coverage", 0)
258
+ previous = ratchet_result.get("previous_coverage", 0)
259
+ self.console.print(
260
+ f"[red]📉[/red] Coverage regression: "
261
+ f"{current:.2f}% < {previous:.2f}%"
262
+ )
227
263
  return False
228
264
 
229
265
  def _handle_coverage_improvement(self, ratchet_result: dict[str, t.Any]) -> None:
@@ -332,11 +332,13 @@ class CoverageRatchetService:
332
332
  # Look for .coverage file or coverage.json
333
333
  coverage_file = self.pkg_path / "coverage.json"
334
334
  if not coverage_file.exists():
335
- # Look for coverage data in htmlcov/index.html or other standard locations
335
+ # No coverage data - this is acceptable, return success
336
336
  return {
337
- "success": False,
338
- "error": "No coverage data found",
339
- "message": "Run tests with coverage enabled first",
337
+ "success": True,
338
+ "status": "no_coverage_data",
339
+ "message": "No coverage data found - tests passed without coverage",
340
+ "allowed": True,
341
+ "baseline_updated": False,
340
342
  }
341
343
 
342
344
  # Parse coverage data (simplified for now)
@@ -346,7 +348,9 @@ class CoverageRatchetService:
346
348
  )
347
349
 
348
350
  # Update the ratchet
349
- return self.update_coverage(current_coverage)
351
+ result = self.update_coverage(current_coverage)
352
+ result["success"] = result.get("allowed", True)
353
+ return result
350
354
 
351
355
  except Exception as e:
352
356
  return {
@@ -29,18 +29,27 @@ class GitService:
29
29
 
30
30
  def get_changed_files(self) -> list[str]:
31
31
  try:
32
- staged_result = self._run_git_command(["diff", "--cached", "--name-only"])
32
+ # Get staged files excluding deletions
33
+ staged_result = self._run_git_command(
34
+ ["diff", "--cached", "--name-only", "--diff-filter=ACMRT"]
35
+ )
33
36
  staged_files = (
34
37
  staged_result.stdout.strip().split("\n")
35
38
  if staged_result.stdout.strip()
36
39
  else []
37
40
  )
38
- unstaged_result = self._run_git_command(["diff", "--name-only"])
41
+
42
+ # Get unstaged files excluding deletions
43
+ unstaged_result = self._run_git_command(
44
+ ["diff", "--name-only", "--diff-filter=ACMRT"]
45
+ )
39
46
  unstaged_files = (
40
47
  unstaged_result.stdout.strip().split("\n")
41
48
  if unstaged_result.stdout.strip()
42
49
  else []
43
50
  )
51
+
52
+ # Get untracked files
44
53
  untracked_result = self._run_git_command(
45
54
  ["ls-files", "--others", "--exclude-standard"],
46
55
  )
@@ -49,6 +58,7 @@ class GitService:
49
58
  if untracked_result.stdout.strip()
50
59
  else []
51
60
  )
61
+
52
62
  all_files = set(staged_files + unstaged_files + untracked_files)
53
63
  return [f for f in all_files if f]
54
64
  except Exception as e:
@@ -72,7 +72,7 @@ class InitializationService:
72
72
  "pyproject.toml": "smart_merge",
73
73
  "CLAUDE.md": "smart_append",
74
74
  "RULES.md": "replace_if_missing",
75
- "mcp.json": "special", # Special handling: mcp.json -> .mcp.json with merging
75
+ "example.mcp.json": "special", # Special handling: example.mcp.json -> .mcp.json with merging
76
76
  }
77
77
 
78
78
  def _process_config_file(
@@ -84,8 +84,8 @@ class InitializationService:
84
84
  force: bool,
85
85
  results: dict[str, t.Any],
86
86
  ) -> None:
87
- # Special handling for mcp.json -> .mcp.json
88
- if file_name == "mcp.json":
87
+ # Special handling for example.mcp.json -> .mcp.json
88
+ if file_name == "example.mcp.json":
89
89
  self._process_mcp_config(target_path, force, results)
90
90
  return
91
91
 
@@ -248,14 +248,14 @@ class InitializationService:
248
248
  force: bool,
249
249
  results: dict[str, t.Any],
250
250
  ) -> None:
251
- """Handle special processing for mcp.json -> .mcp.json with merging."""
252
- # Source: mcp.json in crackerjack package (contains servers to add to projects)
253
- source_file = self.pkg_path / "mcp.json"
251
+ """Handle special processing for example.mcp.json -> .mcp.json with merging."""
252
+ # Source: example.mcp.json in crackerjack package (contains servers to add to projects)
253
+ source_file = self.pkg_path / "example.mcp.json"
254
254
  # Target: .mcp.json in target project
255
255
  target_file = target_path / ".mcp.json"
256
256
 
257
257
  if not source_file.exists():
258
- self._handle_missing_source_file("mcp.json", results)
258
+ self._handle_missing_source_file("example.mcp.json", results)
259
259
  return
260
260
 
261
261
  try:
@@ -265,8 +265,8 @@ class InitializationService:
265
265
 
266
266
  if not isinstance(source_config.get("mcpServers"), dict):
267
267
  self._handle_file_processing_error(
268
- "mcp.json",
269
- ValueError("Invalid mcp.json format: missing mcpServers"),
268
+ "example.mcp.json",
269
+ ValueError("Invalid example.mcp.json format: missing mcpServers"),
270
270
  results,
271
271
  )
272
272
  return
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: crackerjack
3
- Version: 0.31.9
3
+ Version: 0.31.10
4
4
  Summary: Opinionated Python project management tool
5
5
  Project-URL: documentation, https://github.com/lesleslie/crackerjack
6
6
  Project-URL: homepage, https://github.com/lesleslie/crackerjack
@@ -37,10 +37,10 @@ crackerjack/core/autofix_coordinator.py,sha256=txbXTeGm-gJwuyRekVDbvvKgG0gQ1GqB3
37
37
  crackerjack/core/container.py,sha256=e9_1YnWHijUJ0yl23lpgf9mennVQy8NkgJBKtZstG-M,2889
38
38
  crackerjack/core/enhanced_container.py,sha256=fl5XvhNY0fzDnD5hSr16yQXGtL_AW01Wf4F4PL1L0P4,18169
39
39
  crackerjack/core/performance.py,sha256=sL9g2-_JflofnsXW6LUCwp9MaUDQprfV8lSG18s9mns,7601
40
- crackerjack/core/phase_coordinator.py,sha256=iWPVB3A5CFfHwqc3wFXGEQwBhzaa-VlGsvhvRid5FKE,21236
40
+ crackerjack/core/phase_coordinator.py,sha256=L0-OXrxNDfcqSQnhyaeXot1fDk_zdHEWBl-thcbz65Y,21244
41
41
  crackerjack/core/proactive_workflow.py,sha256=ML1amNJI4Gx0dFJK5AKdvB0zNc1chbq-ZyqnhUi4tms,12677
42
42
  crackerjack/core/session_coordinator.py,sha256=hJKLthZBzX7fXm8AmNMFLEjITNmKxDGqM58Om6p7fr0,9893
43
- crackerjack/core/workflow_orchestrator.py,sha256=YfqnVartb7qIHEF5qRpy_Fw1ViyICfBf2r0Le9UCiIM,37749
43
+ crackerjack/core/workflow_orchestrator.py,sha256=YHG-qp8J76fqj_poGRvTvuimljbJBvVwPT1r1OjF95M,38459
44
44
  crackerjack/executors/__init__.py,sha256=HF-DmXvKN45uKKDdiMxOT9bYxuy1B-Z91BihOhkK5lg,322
45
45
  crackerjack/executors/async_hook_executor.py,sha256=3U-AHToGNBojnlDsXK6HLv4CfJvv64UqTmCWYAoLcb8,15958
46
46
  crackerjack/executors/cached_hook_executor.py,sha256=LyrFINWbixB-0xEnaU0F2ZUBFUWrAdaTKvj_JW1Wss0,8186
@@ -58,7 +58,7 @@ crackerjack/managers/hook_manager.py,sha256=3qAKLYqoJGPJ8NAUB1KEoWHZafjs6564P9ud
58
58
  crackerjack/managers/publish_manager.py,sha256=7bBXkaHm1Ou-tMLvUqNQZScp_onZ2SJgB0o3kwThUDE,16084
59
59
  crackerjack/managers/test_command_builder.py,sha256=MdDz9AYSLOoLmI-8zoq3zd2SXF3DeuIkANa76h9cINI,5295
60
60
  crackerjack/managers/test_executor.py,sha256=XCMuJPssTV2Glb0hDPHvoDbVrJHVJpZrsAIltegMMfE,16337
61
- crackerjack/managers/test_manager.py,sha256=BqCaMCUhXx_MJV8CmqXQ-54gZErfdCU5ejgvps4vXPo,9735
61
+ crackerjack/managers/test_manager.py,sha256=4HfnkWy2Sqbu-YW9zkIK0UNc1bnk0SUspK0ldg5RFGI,11387
62
62
  crackerjack/managers/test_manager_backup.py,sha256=tptpX99nw-caLJMVga4Hss7grJRqcFHz1JkRBqro4sE,41307
63
63
  crackerjack/managers/test_progress.py,sha256=gCNKdE7Bh7RS3K7Ekj2MGKCqiY4px54AzPNi0gMhAL0,3908
64
64
  crackerjack/mcp/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -117,15 +117,15 @@ crackerjack/services/cache.py,sha256=LKZIa8xZ6SzwdTBttO1W6VEBxaTgMNI5Paz_IgrqoaI
117
117
  crackerjack/services/config.py,sha256=BrIJoKKi0qyQg2lcZZhTTUpAVB6ej6gkbPv95o2rVvc,14050
118
118
  crackerjack/services/config_integrity.py,sha256=wn6b0x90wXNRSj64J_kOQ5JMQvG_9FwtOno0ITVJGwM,3416
119
119
  crackerjack/services/contextual_ai_assistant.py,sha256=QnJvJNdGimk-u6XxPm9D7F516AmbueNnAmky42D2caQ,19206
120
- crackerjack/services/coverage_ratchet.py,sha256=i12mOg5kB2iU3i4hn0LVLcVXJSPkBorO6Xu_nIiGrfs,13567
120
+ crackerjack/services/coverage_ratchet.py,sha256=XM4iCe_Bckh1j378FgAG2zlbiJNCF0VeH1qVWG-fu1s,13731
121
121
  crackerjack/services/debug.py,sha256=crjsUZwVjP92aCEOEmtpEJwNf5gtlwNeZF_eB9JSfiI,24018
122
122
  crackerjack/services/dependency_monitor.py,sha256=axBXFGBdezoPK9ph5_ZGxIwhSJhurgdvCSiuaCWSrKY,21085
123
123
  crackerjack/services/enhanced_filesystem.py,sha256=MQj5zqvkNc5U6ZUmSVzgFQWKfnizD1lv4SJ2pt-w8W4,15424
124
124
  crackerjack/services/file_hasher.py,sha256=vHSJ6QbWU5Q5JPLYuQkyRMRXCpDC_hsxToaM83vI58U,5201
125
125
  crackerjack/services/filesystem.py,sha256=Re5VyP7H8W6T2tpDakoaghEivdR2VmshJgnZ9Y3QkH8,17932
126
- crackerjack/services/git.py,sha256=Jth_GiufRkEkUACUyOXELVx92CUXoPAdW5_6G-Mr8Sc,8366
126
+ crackerjack/services/git.py,sha256=ZsIrsYhTuDyRSz4Lhtvh2cEFose7EPSpuDg74Vh8npI,8613
127
127
  crackerjack/services/health_metrics.py,sha256=M2OBqwwnGvnJB3eXIXXh5SgMuckYCjHIrD0RkYFAbQU,21458
128
- crackerjack/services/initialization.py,sha256=xcMqZmIi6pKufwYksJI17Tl7bZ7X7tOLqzNW7cvVZhg,33375
128
+ crackerjack/services/initialization.py,sha256=l3CagjRvBD9AQWkzD_JWQciSCQpYOPduRkPdUprE6MA,33455
129
129
  crackerjack/services/log_manager.py,sha256=deM_i97biZVyuZJoHaGlnBitc5QV4WaaZHEb70N5LV0,8388
130
130
  crackerjack/services/logging.py,sha256=c15gVCLR_yRhqaza7f1pLLYL-xQ3Oi_OMWL_mR5G46k,5354
131
131
  crackerjack/services/metrics.py,sha256=kInkb2G0ML8hAtmEG1jK04b-F1hT_fZjHvYJKisyr1Y,22894
@@ -142,8 +142,8 @@ crackerjack/slash_commands/__init__.py,sha256=ZHfKjluj9dX88zDYN6Saj7tGUMdMnh37Q8
142
142
  crackerjack/slash_commands/init.md,sha256=mANRdCiFAzaTw29lKNrI1JFthK4pxVdtiFC5lN2SDSQ,4581
143
143
  crackerjack/slash_commands/run.md,sha256=bf_mEtnXagUuw3w8os5h3t1Yi3vjpfiNbkMJvuFEu-Y,6500
144
144
  crackerjack/slash_commands/status.md,sha256=U3qqppVLtIIm2lEiMYaKagaHYLI9UplL7OH1j6SRJGw,3921
145
- crackerjack-0.31.9.dist-info/METADATA,sha256=Y15hY2DSOtPmmEzByI4qpJBfAjPAg2GdnGxCj8SoEvw,22437
146
- crackerjack-0.31.9.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
147
- crackerjack-0.31.9.dist-info/entry_points.txt,sha256=AJKNft0WXm9xoGUJ3Trl-iXHOWxRAYbagQiza3AILr4,57
148
- crackerjack-0.31.9.dist-info/licenses/LICENSE,sha256=fDt371P6_6sCu7RyqiZH_AhT1LdN3sN1zjBtqEhDYCk,1531
149
- crackerjack-0.31.9.dist-info/RECORD,,
145
+ crackerjack-0.31.10.dist-info/METADATA,sha256=4VBwoRFPEEXi1M6Lh6wY7wCEFTAmVKnyRowdCjDT4V8,22438
146
+ crackerjack-0.31.10.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
147
+ crackerjack-0.31.10.dist-info/entry_points.txt,sha256=AJKNft0WXm9xoGUJ3Trl-iXHOWxRAYbagQiza3AILr4,57
148
+ crackerjack-0.31.10.dist-info/licenses/LICENSE,sha256=fDt371P6_6sCu7RyqiZH_AhT1LdN3sN1zjBtqEhDYCk,1531
149
+ crackerjack-0.31.10.dist-info/RECORD,,