meshcode 2.10.27__tar.gz → 2.10.29__tar.gz

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.
Files changed (32) hide show
  1. {meshcode-2.10.27 → meshcode-2.10.29}/PKG-INFO +1 -1
  2. {meshcode-2.10.27 → meshcode-2.10.29}/meshcode/__init__.py +1 -1
  3. {meshcode-2.10.27 → meshcode-2.10.29}/meshcode/meshcode_mcp/server.py +39 -18
  4. {meshcode-2.10.27 → meshcode-2.10.29}/meshcode/run_agent.py +10 -6
  5. {meshcode-2.10.27 → meshcode-2.10.29}/meshcode.egg-info/PKG-INFO +1 -1
  6. {meshcode-2.10.27 → meshcode-2.10.29}/pyproject.toml +1 -1
  7. {meshcode-2.10.27 → meshcode-2.10.29}/README.md +0 -0
  8. {meshcode-2.10.27 → meshcode-2.10.29}/meshcode/ascii_art.py +0 -0
  9. {meshcode-2.10.27 → meshcode-2.10.29}/meshcode/cli.py +0 -0
  10. {meshcode-2.10.27 → meshcode-2.10.29}/meshcode/comms_v4.py +0 -0
  11. {meshcode-2.10.27 → meshcode-2.10.29}/meshcode/invites.py +0 -0
  12. {meshcode-2.10.27 → meshcode-2.10.29}/meshcode/launcher.py +0 -0
  13. {meshcode-2.10.27 → meshcode-2.10.29}/meshcode/launcher_install.py +0 -0
  14. {meshcode-2.10.27 → meshcode-2.10.29}/meshcode/meshcode_mcp/__init__.py +0 -0
  15. {meshcode-2.10.27 → meshcode-2.10.29}/meshcode/meshcode_mcp/__main__.py +0 -0
  16. {meshcode-2.10.27 → meshcode-2.10.29}/meshcode/meshcode_mcp/backend.py +0 -0
  17. {meshcode-2.10.27 → meshcode-2.10.29}/meshcode/meshcode_mcp/realtime.py +0 -0
  18. {meshcode-2.10.27 → meshcode-2.10.29}/meshcode/meshcode_mcp/test_backend.py +0 -0
  19. {meshcode-2.10.27 → meshcode-2.10.29}/meshcode/meshcode_mcp/test_realtime.py +0 -0
  20. {meshcode-2.10.27 → meshcode-2.10.29}/meshcode/meshcode_mcp/test_server_wrapper.py +0 -0
  21. {meshcode-2.10.27 → meshcode-2.10.29}/meshcode/preferences.py +0 -0
  22. {meshcode-2.10.27 → meshcode-2.10.29}/meshcode/protocol_v2.py +0 -0
  23. {meshcode-2.10.27 → meshcode-2.10.29}/meshcode/secrets.py +0 -0
  24. {meshcode-2.10.27 → meshcode-2.10.29}/meshcode/self_update.py +0 -0
  25. {meshcode-2.10.27 → meshcode-2.10.29}/meshcode/setup_clients.py +0 -0
  26. {meshcode-2.10.27 → meshcode-2.10.29}/meshcode.egg-info/SOURCES.txt +0 -0
  27. {meshcode-2.10.27 → meshcode-2.10.29}/meshcode.egg-info/dependency_links.txt +0 -0
  28. {meshcode-2.10.27 → meshcode-2.10.29}/meshcode.egg-info/entry_points.txt +0 -0
  29. {meshcode-2.10.27 → meshcode-2.10.29}/meshcode.egg-info/requires.txt +0 -0
  30. {meshcode-2.10.27 → meshcode-2.10.29}/meshcode.egg-info/top_level.txt +0 -0
  31. {meshcode-2.10.27 → meshcode-2.10.29}/setup.cfg +0 -0
  32. {meshcode-2.10.27 → meshcode-2.10.29}/tests/test_status_enum_coverage.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: meshcode
3
- Version: 2.10.27
3
+ Version: 2.10.29
4
4
  Summary: Real-time communication between AI agents — Supabase-backed CLI
5
5
  Author-email: MeshCode <hello@meshcode.io>
6
6
  License: MIT
@@ -1,2 +1,2 @@
1
1
  """MeshCode — Real-time communication between AI agents."""
2
- __version__ = "2.10.27"
2
+ __version__ = "2.10.29"
@@ -2811,24 +2811,45 @@ def run_server():
2811
2811
  # accidental stdout writes from corrupting the MCP protocol.
2812
2812
  sys.stdout = _REAL_STDOUT
2813
2813
 
2814
- # Claude Code cancels tool calls on ESC via TWO parallel channels:
2815
- # (1) JSON-RPC `notifications/cancelled` over stdin (the correct path)
2816
- # (2) SIGINT to the stdio subprocess (a destructive side-channel)
2817
- # anyio's asyncio backend installs its own SIGINT handler inside
2818
- # Runner.run() only if the current handler is `default_int_handler`
2819
- # (see anyio/_backends/_asyncio.py ~L197-210). That handler cancels the
2820
- # *main task* which for a stdio server IS the whole server run —
2821
- # tearing the event loop down and killing the subprocess. Setting
2822
- # SIG_IGN before mcp.run() trips anyio's guard, so it leaves SIGINT
2823
- # alone; the kernel drops the signal; only the notifications/cancelled
2824
- # path remains, which cancels just the in-flight tool call as intended.
2825
- # SIGTERM is deliberately untouched so Claude Code can still force-shut
2826
- # the server on session end. stdin EOF remains the normal exit path.
2814
+ # Claude Code cancels tool calls on ESC via multiple side channels that
2815
+ # are destructive to the stdio subprocess. 2.10.26's SIG_IGN-on-SIGINT
2816
+ # fix was incomplete in the wild (2.10.27 field test died anyway), so we
2817
+ # widen the net: ignore every signal Claude Code is known to send on
2818
+ # cancellation and log any that arrive so we can see what actually fires.
2819
+ #
2820
+ # SIGINT kernel default: terminate. asyncio Runner also installs a
2821
+ # cancel-main-task handler, but only if the current handler is
2822
+ # default_int_handler; SIG_IGN here trips that guard.
2823
+ # SIGTERM kernel default: terminate. Some Claude Code versions send
2824
+ # this after SIGINT if the subprocess didn't exit fast enough.
2825
+ # SIGHUP — kernel default: terminate. Sent when the controlling tty
2826
+ # detaches or the parent process restructures its session.
2827
+ # SIGPIPE — kernel default: terminate. Fires when Claude Code closes its
2828
+ # side of stdout while we're mid-write. Ignoring makes the
2829
+ # write fail with EPIPE instead of killing us.
2830
+ #
2831
+ # SIGKILL and SIGSTOP cannot be caught — that is how the process is
2832
+ # meant to be forcibly stopped (`kill -9 <pid>` still works). stdin EOF
2833
+ # is untouched and remains the clean-shutdown signal for session end.
2827
2834
  import signal
2828
- try:
2829
- signal.signal(signal.SIGINT, signal.SIG_IGN)
2830
- except (ValueError, OSError):
2831
- # Non-main thread or platform that can't install handlers — harmless.
2832
- pass
2835
+ def _diag_ignore(signum, frame): # pragma: no cover - signal handler
2836
+ try:
2837
+ name = signal.Signals(signum).name
2838
+ except Exception:
2839
+ name = f"signal-{signum}"
2840
+ try:
2841
+ sys.stderr.write(f"[meshcode-mcp] received {name} ({signum}); ignored to keep MCP alive during tool cancellation\n")
2842
+ sys.stderr.flush()
2843
+ except Exception:
2844
+ pass
2845
+ for _sig_name in ("SIGINT", "SIGTERM", "SIGHUP", "SIGPIPE"):
2846
+ _sig = getattr(signal, _sig_name, None)
2847
+ if _sig is None:
2848
+ continue
2849
+ try:
2850
+ signal.signal(_sig, _diag_ignore)
2851
+ except (ValueError, OSError):
2852
+ # Non-main thread or Windows doesn't expose the signal — harmless.
2853
+ pass
2833
2854
 
2834
2855
  mcp.run()
@@ -465,13 +465,17 @@ def run(agent: str, project: Optional[str] = None, editor_override: Optional[str
465
465
  print()
466
466
 
467
467
  if editor == "claude":
468
- # Claude Code: pass --mcp-config to point at the workspace's .mcp.json
469
- # and --strict-mcp-config so it ignores ~/.claude.json's mcpServers.
468
+ # Claude Code: run from inside the workspace and let Claude Code
469
+ # auto-discover .mcp.json as a PROJECT-scoped MCP. We used to pass
470
+ # --mcp-config + --strict-mcp-config here, but that categorises the
471
+ # server as a "Built-in" (session-injected) MCP, and Built-in MCPs
472
+ # are killed by Claude Code when the user presses ESC — a bug/quirk
473
+ # that caused our agents to die on every cancellation. Project-
474
+ # scoped MCPs (loaded from ./.mcp.json at cwd) live in the "Local
475
+ # MCP" bucket and survive ESC. Verified with a minimal FastMCP
476
+ # repro side-by-side: Built-in dies, Local survives, same SDK code.
470
477
  mode = resolve_permission_mode(permission_override)
471
- cmd = [
472
- editor,
473
- "--mcp-config", str(ws / ".mcp.json"),
474
- ]
478
+ cmd = [editor]
475
479
  if mode == "bypass":
476
480
  cmd.append("--dangerously-skip-permissions")
477
481
  print(f"[meshcode] Permission mode: bypass (autonomous loop, no prompts)")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: meshcode
3
- Version: 2.10.27
3
+ Version: 2.10.29
4
4
  Summary: Real-time communication between AI agents — Supabase-backed CLI
5
5
  Author-email: MeshCode <hello@meshcode.io>
6
6
  License: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "meshcode"
7
- version = "2.10.27"
7
+ version = "2.10.29"
8
8
  description = "Real-time communication between AI agents — Supabase-backed CLI"
9
9
  readme = "README.md"
10
10
  license = {text = "MIT"}
File without changes
File without changes
File without changes