claude-mpm 5.4.105__py3-none-any.whl → 5.4.106__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.
@@ -57,33 +57,33 @@ def list_errors(format, hook_type):
57
57
 
58
58
  if not errors:
59
59
  if hook_type:
60
- click.echo(f"No errors recorded for hook type: {hook_type}")
60
+ click.echo(f"No errors recorded for hook type: {hook_type}", err=True)
61
61
  else:
62
- click.echo("No errors recorded. Hook system is healthy! ✅")
62
+ click.echo("No errors recorded. Hook system is healthy! ✅", err=True)
63
63
  return
64
64
 
65
65
  if format == "json":
66
66
  # JSON output
67
- click.echo(json.dumps(errors, indent=2))
67
+ click.echo(json.dumps(errors, indent=2), err=True)
68
68
  else:
69
69
  # Table output
70
- click.echo("\n" + "=" * 80)
71
- click.echo("Hook Error Memory Report")
72
- click.echo("=" * 80)
70
+ click.echo("\n" + "=" * 80, err=True)
71
+ click.echo("Hook Error Memory Report", err=True)
72
+ click.echo("=" * 80, err=True)
73
73
 
74
74
  for key, data in errors.items():
75
- click.echo(f"\n🔴 Error: {data['type']}")
76
- click.echo(f" Hook Type: {data['hook_type']}")
77
- click.echo(f" Details: {data['details']}")
78
- click.echo(f" Match: {data['match']}")
79
- click.echo(f" Count: {data['count']} occurrences")
80
- click.echo(f" First Seen: {data['first_seen']}")
81
- click.echo(f" Last Seen: {data['last_seen']}")
75
+ click.echo(f"\n🔴 Error: {data['type']}", err=True)
76
+ click.echo(f" Hook Type: {data['hook_type']}", err=True)
77
+ click.echo(f" Details: {data['details']}", err=True)
78
+ click.echo(f" Match: {data['match']}", err=True)
79
+ click.echo(f" Count: {data['count']} occurrences", err=True)
80
+ click.echo(f" First Seen: {data['first_seen']}", err=True)
81
+ click.echo(f" Last Seen: {data['last_seen']}", err=True)
82
82
 
83
- click.echo("\n" + "=" * 80)
84
- click.echo(f"Total unique errors: {len(errors)}")
85
- click.echo(f"Memory file: {error_memory.memory_file}")
86
- click.echo("\nTo clear errors: claude-mpm hook-errors clear")
83
+ click.echo("\n" + "=" * 80, err=True)
84
+ click.echo(f"Total unique errors: {len(errors)}", err=True)
85
+ click.echo(f"Memory file: {error_memory.memory_file}", err=True)
86
+ click.echo("\nTo clear errors: claude-mpm hook-errors clear", err=True)
87
87
 
88
88
 
89
89
  @hook_errors_group.command(name="summary")
@@ -99,28 +99,28 @@ def show_summary():
99
99
  summary = error_memory.get_error_summary()
100
100
 
101
101
  if summary["total_errors"] == 0:
102
- click.echo("No errors recorded. Hook system is healthy! ✅")
102
+ click.echo("No errors recorded. Hook system is healthy! ✅", err=True)
103
103
  return
104
104
 
105
- click.echo("\n" + "=" * 80)
106
- click.echo("Hook Error Summary")
107
- click.echo("=" * 80)
108
- click.echo("\n📊 Statistics:")
109
- click.echo(f" Total Errors: {summary['total_errors']}")
110
- click.echo(f" Unique Errors: {summary['unique_errors']}")
105
+ click.echo("\n" + "=" * 80, err=True)
106
+ click.echo("Hook Error Summary", err=True)
107
+ click.echo("=" * 80, err=True)
108
+ click.echo("\n📊 Statistics:", err=True)
109
+ click.echo(f" Total Errors: {summary['total_errors']}", err=True)
110
+ click.echo(f" Unique Errors: {summary['unique_errors']}", err=True)
111
111
 
112
112
  if summary["errors_by_type"]:
113
- click.echo("\n🔍 Errors by Type:")
113
+ click.echo("\n🔍 Errors by Type:", err=True)
114
114
  for error_type, count in summary["errors_by_type"].items():
115
- click.echo(f" {error_type}: {count}")
115
+ click.echo(f" {error_type}: {count}", err=True)
116
116
 
117
117
  if summary["errors_by_hook"]:
118
- click.echo("\n🎣 Errors by Hook Type:")
118
+ click.echo("\n🎣 Errors by Hook Type:", err=True)
119
119
  for hook_type, count in summary["errors_by_hook"].items():
120
- click.echo(f" {hook_type}: {count}")
120
+ click.echo(f" {hook_type}: {count}", err=True)
121
121
 
122
- click.echo(f"\n📁 Memory File: {summary['memory_file']}")
123
- click.echo("\nFor detailed list: claude-mpm hook-errors list")
122
+ click.echo(f"\n📁 Memory File: {summary['memory_file']}", err=True)
123
+ click.echo("\nFor detailed list: claude-mpm hook-errors list", err=True)
124
124
 
125
125
 
126
126
  @hook_errors_group.command(name="clear")
@@ -158,21 +158,21 @@ def clear_errors(hook_type, yes):
158
158
  scope = "all hook types"
159
159
 
160
160
  if count == 0:
161
- click.echo(f"No errors to clear {scope}.")
161
+ click.echo(f"No errors to clear {scope}.", err=True)
162
162
  return
163
163
 
164
164
  # Confirm if not using -y flag
165
165
  if not yes:
166
166
  message = f"Clear {count} error(s) {scope}?"
167
167
  if not click.confirm(message):
168
- click.echo("Cancelled.")
168
+ click.echo("Cancelled.", err=True)
169
169
  return
170
170
 
171
171
  # Clear errors
172
172
  error_memory.clear_errors(hook_type)
173
173
 
174
- click.echo(f"✅ Cleared {count} error(s) {scope}.")
175
- click.echo("\nHooks will be retried on next execution.")
174
+ click.echo(f"✅ Cleared {count} error(s) {scope}.", err=True)
175
+ click.echo("\nHooks will be retried on next execution.", err=True)
176
176
 
177
177
 
178
178
  @hook_errors_group.command(name="diagnose")
@@ -201,19 +201,19 @@ def diagnose_errors(hook_type):
201
201
 
202
202
  if not errors:
203
203
  if hook_type:
204
- click.echo(f"No errors to diagnose for hook type: {hook_type}")
204
+ click.echo(f"No errors to diagnose for hook type: {hook_type}", err=True)
205
205
  else:
206
- click.echo("No errors to diagnose. Hook system is healthy! ✅")
206
+ click.echo("No errors to diagnose. Hook system is healthy! ✅", err=True)
207
207
  return
208
208
 
209
- click.echo("\n" + "=" * 80)
210
- click.echo("Hook Error Diagnostics")
211
- click.echo("=" * 80)
209
+ click.echo("\n" + "=" * 80, err=True)
210
+ click.echo("Hook Error Diagnostics", err=True)
211
+ click.echo("=" * 80, err=True)
212
212
 
213
213
  for key, data in errors.items():
214
- click.echo(f"\n🔴 Error: {data['type']}")
215
- click.echo(f" Hook: {data['hook_type']}")
216
- click.echo(f" Count: {data['count']} failures")
214
+ click.echo(f"\n🔴 Error: {data['type']}", err=True)
215
+ click.echo(f" Hook: {data['hook_type']}", err=True)
216
+ click.echo(f" Count: {data['count']} failures", err=True)
217
217
 
218
218
  # Generate and show fix suggestion
219
219
  error_info = {
@@ -223,13 +223,13 @@ def diagnose_errors(hook_type):
223
223
  }
224
224
  suggestion = error_memory.suggest_fix(error_info)
225
225
 
226
- click.echo("\n" + "-" * 80)
227
- click.echo(suggestion)
228
- click.echo("-" * 80)
226
+ click.echo("\n" + "-" * 80, err=True)
227
+ click.echo(suggestion, err=True)
228
+ click.echo("-" * 80, err=True)
229
229
 
230
- click.echo("\n" + "=" * 80)
231
- click.echo("After fixing issues, clear errors to retry:")
232
- click.echo(" claude-mpm hook-errors clear")
230
+ click.echo("\n" + "=" * 80, err=True)
231
+ click.echo("After fixing issues, clear errors to retry:", err=True)
232
+ click.echo(" claude-mpm hook-errors clear", err=True)
233
233
 
234
234
 
235
235
  @hook_errors_group.command(name="status")
@@ -244,27 +244,27 @@ def show_status():
244
244
  error_memory = get_hook_error_memory()
245
245
  summary = error_memory.get_error_summary()
246
246
 
247
- click.echo("\n📊 Hook Error Memory Status")
248
- click.echo("=" * 80)
247
+ click.echo("\n📊 Hook Error Memory Status", err=True)
248
+ click.echo("=" * 80, err=True)
249
249
 
250
250
  if summary["total_errors"] == 0:
251
- click.echo("✅ Status: Healthy (no errors recorded)")
251
+ click.echo("✅ Status: Healthy (no errors recorded)", err=True)
252
252
  else:
253
- click.echo(f"⚠️ Status: {summary['total_errors']} error(s) recorded")
254
- click.echo(f" Unique errors: {summary['unique_errors']}")
253
+ click.echo(f"⚠️ Status: {summary['total_errors']} error(s) recorded", err=True)
254
+ click.echo(f" Unique errors: {summary['unique_errors']}", err=True)
255
255
 
256
256
  # Show which hooks are affected
257
257
  if summary["errors_by_hook"]:
258
258
  affected_hooks = list(summary["errors_by_hook"].keys())
259
- click.echo(f" Affected hooks: {', '.join(affected_hooks)}")
259
+ click.echo(f" Affected hooks: {', '.join(affected_hooks)}", err=True)
260
260
 
261
- click.echo(f"\n📁 Memory file: {summary['memory_file']}")
262
- click.echo(f" Exists: {Path(summary['memory_file']).exists()}")
261
+ click.echo(f"\n📁 Memory file: {summary['memory_file']}", err=True)
262
+ click.echo(f" Exists: {Path(summary['memory_file']).exists()}", err=True)
263
263
 
264
- click.echo("\nCommands:")
265
- click.echo(" claude-mpm hook-errors list # View detailed errors")
266
- click.echo(" claude-mpm hook-errors diagnose # Get fix suggestions")
267
- click.echo(" claude-mpm hook-errors clear # Clear and retry")
264
+ click.echo("\nCommands:", err=True)
265
+ click.echo(" claude-mpm hook-errors list # View detailed errors", err=True)
266
+ click.echo(" claude-mpm hook-errors diagnose # Get fix suggestions", err=True)
267
+ click.echo(" claude-mpm hook-errors clear # Clear and retry", err=True)
268
268
 
269
269
 
270
270
  # Register the command group
File without changes
File without changes
@@ -496,9 +496,12 @@ class ClaudeHookHandler:
496
496
  """
497
497
  if modified_input is not None:
498
498
  # Claude Code v2.0.30+ supports modifying PreToolUse tool inputs
499
- print(json.dumps({"action": "continue", "tool_input": modified_input}))
499
+ print(
500
+ json.dumps({"action": "continue", "tool_input": modified_input}),
501
+ flush=True,
502
+ )
500
503
  else:
501
- print(json.dumps({"action": "continue"}))
504
+ print(json.dumps({"action": "continue"}), flush=True)
502
505
 
503
506
  # Delegation methods for compatibility with event_handlers
504
507
  def _track_delegation(self, session_id: str, agent_type: str, request_data=None):
@@ -676,7 +679,7 @@ def main():
676
679
  f"Skipping hook processing due to version incompatibility ({version})",
677
680
  file=sys.stderr,
678
681
  )
679
- print(json.dumps({"action": "continue"}))
682
+ print(json.dumps({"action": "continue"}), flush=True)
680
683
  sys.exit(0)
681
684
 
682
685
  def cleanup_handler(signum=None, frame=None):
@@ -689,7 +692,7 @@ def main():
689
692
  )
690
693
  # Only output continue if we haven't already (i.e., if interrupted by signal)
691
694
  if signum is not None and not _continue_printed:
692
- print(json.dumps({"action": "continue"}))
695
+ print(json.dumps({"action": "continue"}), flush=True)
693
696
  _continue_printed = True
694
697
  sys.exit(0)
695
698
 
@@ -727,7 +730,7 @@ def main():
727
730
  except Exception as e:
728
731
  # Only output continue if not already printed
729
732
  if not _continue_printed:
730
- print(json.dumps({"action": "continue"}))
733
+ print(json.dumps({"action": "continue"}), flush=True)
731
734
  _continue_printed = True
732
735
  # Log error for debugging
733
736
  if DEBUG:
@@ -48,15 +48,10 @@ echo "[$(date -u +%Y-%m-%dT%H:%M:%S.%3NZ)] PYTHONPATH: $PYTHONPATH" >> /tmp/hook
48
48
  echo "[$(date -u +%Y-%m-%dT%H:%M:%S.%3NZ)] Running: $PYTHON_CMD -m claude_mpm.hooks.claude_hooks.hook_handler" >> /tmp/hook-wrapper.log
49
49
  echo "[$(date -u +%Y-%m-%dT%H:%M:%S.%3NZ)] SOCKETIO_PORT: $CLAUDE_MPM_SOCKETIO_PORT" >> /tmp/hook-wrapper.log
50
50
 
51
- # Run the Python hook handler as a module with error handling
52
- # Use exec to replace the shell process, but wrap in error handling
53
- if ! "$PYTHON_CMD" -m claude_mpm.hooks.claude_hooks.hook_handler "$@" 2>/tmp/hook-error.log; then
54
- # If the Python handler fails, always return continue to not block Claude
55
- echo '{"action": "continue"}'
56
- # Log the error for debugging
57
- echo "[$(date -u +%Y-%m-%dT%H:%M:%S.%3NZ)] Hook handler failed, see /tmp/hook-error.log" >> /tmp/hook-wrapper.log
58
- exit 0
59
- fi
51
+ # Run the Python hook handler as a module
52
+ # Python handler is responsible for ALL stdout output (including error fallback)
53
+ # Redirect stderr to log file for debugging
54
+ "$PYTHON_CMD" -m claude_mpm.hooks.claude_hooks.hook_handler "$@" 2>/tmp/hook-error.log
60
55
 
61
- # Success - Python handler already printed continue, just exit
62
- exit 0
56
+ # Exit with Python's exit code (should always be 0)
57
+ exit $?
File without changes
File without changes
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: claude-mpm
3
- Version: 5.4.105
3
+ Version: 5.4.106
4
4
  Summary: Claude Multi-Agent Project Manager - Orchestrate Claude with agent delegation and ticket tracking
5
5
  Author-email: Bob Matsuoka <bob@matsuoka.com>
6
6
  Maintainer: Claude MPM Team
@@ -76,7 +76,7 @@ claude_mpm/cli/commands/configure_validators.py,sha256=P0t3MbeQU6ojo2RNiz--5V98C
76
76
  claude_mpm/cli/commands/dashboard.py,sha256=4jPTmTl97DRNNJlYREWeE1iDdkct1uL-vv24MZn9fj4,11403
77
77
  claude_mpm/cli/commands/debug.py,sha256=x22wBjatBAD6yPswlHRFI_RSK7iuv0Mes7EgQzhcOH8,47169
78
78
  claude_mpm/cli/commands/doctor.py,sha256=eN5acliq6rDW9i0dgdBtOySySkn8qbWisYNFqSfiFko,7643
79
- claude_mpm/cli/commands/hook_errors.py,sha256=9NLZaE09KK9RnjhJhvkxie1wFjksnZLx1wKpfmEsxXU,8585
79
+ claude_mpm/cli/commands/hook_errors.py,sha256=K-boqOFDB79bBqDBAXa3ukgryP1R7oiptKU67lx0pK0,9185
80
80
  claude_mpm/cli/commands/info.py,sha256=uiZ2GMkfr-4aeme2l6QhzxyawuhtuyVulfCi66yyvOs,7404
81
81
  claude_mpm/cli/commands/local_deploy.py,sha256=d40Ze35-W---tEioiriRxfkGDSKbIUJjU-naa8vHEO4,21976
82
82
  claude_mpm/cli/commands/mcp.py,sha256=CLxxRzRNA3zYsiN1YVqks_N_FYThp7tMUIuQe2oZKpM,7153
@@ -337,8 +337,8 @@ claude_mpm/hooks/claude_hooks/auto_pause_handler.py,sha256=xDAQZ33I5OhGvtWvA9mxw
337
337
  claude_mpm/hooks/claude_hooks/connection_pool.py,sha256=vpi-XbVf61GWhh85tHBzubbOgbJly_I-5-QmsleND2M,8658
338
338
  claude_mpm/hooks/claude_hooks/correlation_manager.py,sha256=3n-RxzqE8egG4max_NcpJgL9gzrBY6Ti529LrjleI1g,2033
339
339
  claude_mpm/hooks/claude_hooks/event_handlers.py,sha256=_GUOe9urO9RVIaOWSNXv2F_di4D7SaePjxONyd37das,47019
340
- claude_mpm/hooks/claude_hooks/hook_handler.py,sha256=R2RhUoRvI0q_EGu-d5L9bH7cGg5_OLDskQoNrl3JsU0,28504
341
- claude_mpm/hooks/claude_hooks/hook_wrapper.sh,sha256=4lG3TlLVoVfTJipPj1X_ICUlS-KpnkbUp1U3oSq80Bw,2476
340
+ claude_mpm/hooks/claude_hooks/hook_handler.py,sha256=glBHl6TxkSYazu2GPig-Z10xg4FHOmyrSjUHAQ1Llfc,28611
341
+ claude_mpm/hooks/claude_hooks/hook_wrapper.sh,sha256=XYkdYtcM0nfnwYvMdyIFCasr80ry3uI5-fLYsLtDGw4,2214
342
342
  claude_mpm/hooks/claude_hooks/installer.py,sha256=VbvVGMcrmCXQB3Pf9zOdjeGET2AFqbUDMHDy5KXuvz0,30463
343
343
  claude_mpm/hooks/claude_hooks/memory_integration.py,sha256=73w7A5-3s5i1oYdkbEgw7qhgalQvSuJjfx6OFqfaw64,9963
344
344
  claude_mpm/hooks/claude_hooks/response_tracking.py,sha256=bgX4iVQqmX0L3_GHyKs1q4CSIjnavdxYnJZT0GaT4gs,17148
@@ -347,7 +347,7 @@ claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-311.pyc,sha256=EGpgXq
347
347
  claude_mpm/hooks/claude_hooks/__pycache__/auto_pause_handler.cpython-311.pyc,sha256=X7A8O4KPXkuDaLDFbF7Izi1qVDyS0tQjHVo1xy_HzNQ,21172
348
348
  claude_mpm/hooks/claude_hooks/__pycache__/correlation_manager.cpython-311.pyc,sha256=SQX5iiP9bQZkLL-cj_2tlGH7lpAzarO0mYal7btj3tc,3521
349
349
  claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-311.pyc,sha256=76VtByCuOr7L1_snjeHo1iWDyD2QyvoMpAj1hrSq4-Q,45735
350
- claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-311.pyc,sha256=ehLm68zhDmqOwzr1Di6xYjGuE9SRg0mvKePQfepuuQ4,30577
350
+ claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-311.pyc,sha256=klRXoLRRBCjv0nS39cOpNUDqBXfQWZQ8lCJWjl4JhjY,30665
351
351
  claude_mpm/hooks/claude_hooks/__pycache__/installer.cpython-311.pyc,sha256=9mpAKY4gNcbU5VvZ5tGbf2UM0uIEWdreKSUvVr_BKcM,33917
352
352
  claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-311.pyc,sha256=YbwauQDKSGvXkT1972faalJLuxwyvq328DYQhkCnel0,10513
353
353
  claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-311.pyc,sha256=-L-n4xvi1eHY48MdZ-7v249UaNfkuiIwfwxdPgxwd80,16730
@@ -998,10 +998,10 @@ claude_mpm/utils/subprocess_utils.py,sha256=D0izRT8anjiUb_JG72zlJR_JAw1cDkb7kalN
998
998
  claude_mpm/validation/__init__.py,sha256=YZhwE3mhit-lslvRLuwfX82xJ_k4haZeKmh4IWaVwtk,156
999
999
  claude_mpm/validation/agent_validator.py,sha256=GprtAvu80VyMXcKGsK_VhYiXWA6BjKHv7O6HKx0AB9w,20917
1000
1000
  claude_mpm/validation/frontmatter_validator.py,sha256=YpJlYNNYcV8u6hIOi3_jaRsDnzhbcQpjCBE6eyBKaFY,7076
1001
- claude_mpm-5.4.105.dist-info/licenses/LICENSE,sha256=ca3y_Rk4aPrbF6f62z8Ht5MJM9OAvbGlHvEDcj9vUQ4,3867
1002
- claude_mpm-5.4.105.dist-info/licenses/LICENSE-FAQ.md,sha256=TxfEkXVCK98RzDOer09puc7JVCP_q_bN4dHtZKHCMcM,5104
1003
- claude_mpm-5.4.105.dist-info/METADATA,sha256=fq_ncNJUhUEXEoKJSVRH6p4gCBu6XVBJoOFNF4jRc1M,14350
1004
- claude_mpm-5.4.105.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
1005
- claude_mpm-5.4.105.dist-info/entry_points.txt,sha256=n-Uk4vwHPpuvu-g_I7-GHORzTnN_m6iyOsoLveKKD0E,228
1006
- claude_mpm-5.4.105.dist-info/top_level.txt,sha256=1nUg3FEaBySgm8t-s54jK5zoPnu3_eY6EP6IOlekyHA,11
1007
- claude_mpm-5.4.105.dist-info/RECORD,,
1001
+ claude_mpm-5.4.106.dist-info/licenses/LICENSE,sha256=ca3y_Rk4aPrbF6f62z8Ht5MJM9OAvbGlHvEDcj9vUQ4,3867
1002
+ claude_mpm-5.4.106.dist-info/licenses/LICENSE-FAQ.md,sha256=TxfEkXVCK98RzDOer09puc7JVCP_q_bN4dHtZKHCMcM,5104
1003
+ claude_mpm-5.4.106.dist-info/METADATA,sha256=IJCQQYhFAkyzF2Li8SdMnCQnBZWHBP2jWcsgKfJhxr4,14350
1004
+ claude_mpm-5.4.106.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
1005
+ claude_mpm-5.4.106.dist-info/entry_points.txt,sha256=n-Uk4vwHPpuvu-g_I7-GHORzTnN_m6iyOsoLveKKD0E,228
1006
+ claude_mpm-5.4.106.dist-info/top_level.txt,sha256=1nUg3FEaBySgm8t-s54jK5zoPnu3_eY6EP6IOlekyHA,11
1007
+ claude_mpm-5.4.106.dist-info/RECORD,,