meshcode 2.10.25__tar.gz → 2.10.27__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.
- {meshcode-2.10.25 → meshcode-2.10.27}/PKG-INFO +1 -1
- {meshcode-2.10.25 → meshcode-2.10.27}/meshcode/__init__.py +1 -1
- {meshcode-2.10.25 → meshcode-2.10.27}/meshcode/meshcode_mcp/server.py +37 -18
- {meshcode-2.10.25 → meshcode-2.10.27}/meshcode.egg-info/PKG-INFO +1 -1
- {meshcode-2.10.25 → meshcode-2.10.27}/pyproject.toml +1 -1
- {meshcode-2.10.25 → meshcode-2.10.27}/README.md +0 -0
- {meshcode-2.10.25 → meshcode-2.10.27}/meshcode/ascii_art.py +0 -0
- {meshcode-2.10.25 → meshcode-2.10.27}/meshcode/cli.py +0 -0
- {meshcode-2.10.25 → meshcode-2.10.27}/meshcode/comms_v4.py +0 -0
- {meshcode-2.10.25 → meshcode-2.10.27}/meshcode/invites.py +0 -0
- {meshcode-2.10.25 → meshcode-2.10.27}/meshcode/launcher.py +0 -0
- {meshcode-2.10.25 → meshcode-2.10.27}/meshcode/launcher_install.py +0 -0
- {meshcode-2.10.25 → meshcode-2.10.27}/meshcode/meshcode_mcp/__init__.py +0 -0
- {meshcode-2.10.25 → meshcode-2.10.27}/meshcode/meshcode_mcp/__main__.py +0 -0
- {meshcode-2.10.25 → meshcode-2.10.27}/meshcode/meshcode_mcp/backend.py +0 -0
- {meshcode-2.10.25 → meshcode-2.10.27}/meshcode/meshcode_mcp/realtime.py +0 -0
- {meshcode-2.10.25 → meshcode-2.10.27}/meshcode/meshcode_mcp/test_backend.py +0 -0
- {meshcode-2.10.25 → meshcode-2.10.27}/meshcode/meshcode_mcp/test_realtime.py +0 -0
- {meshcode-2.10.25 → meshcode-2.10.27}/meshcode/meshcode_mcp/test_server_wrapper.py +0 -0
- {meshcode-2.10.25 → meshcode-2.10.27}/meshcode/preferences.py +0 -0
- {meshcode-2.10.25 → meshcode-2.10.27}/meshcode/protocol_v2.py +0 -0
- {meshcode-2.10.25 → meshcode-2.10.27}/meshcode/run_agent.py +0 -0
- {meshcode-2.10.25 → meshcode-2.10.27}/meshcode/secrets.py +0 -0
- {meshcode-2.10.25 → meshcode-2.10.27}/meshcode/self_update.py +0 -0
- {meshcode-2.10.25 → meshcode-2.10.27}/meshcode/setup_clients.py +0 -0
- {meshcode-2.10.25 → meshcode-2.10.27}/meshcode.egg-info/SOURCES.txt +0 -0
- {meshcode-2.10.25 → meshcode-2.10.27}/meshcode.egg-info/dependency_links.txt +0 -0
- {meshcode-2.10.25 → meshcode-2.10.27}/meshcode.egg-info/entry_points.txt +0 -0
- {meshcode-2.10.25 → meshcode-2.10.27}/meshcode.egg-info/requires.txt +0 -0
- {meshcode-2.10.25 → meshcode-2.10.27}/meshcode.egg-info/top_level.txt +0 -0
- {meshcode-2.10.25 → meshcode-2.10.27}/setup.cfg +0 -0
- {meshcode-2.10.25 → meshcode-2.10.27}/tests/test_status_enum_coverage.py +0 -0
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"""MeshCode — Real-time communication between AI agents."""
|
|
2
|
-
__version__ = "2.10.
|
|
2
|
+
__version__ = "2.10.27"
|
|
@@ -105,8 +105,12 @@ _SEEN_MSG_CAP = 1000
|
|
|
105
105
|
# DEFAULT: ON. Disable with MESHCODE_AUTO_WAKE=0 if you don't want it.
|
|
106
106
|
# ============================================================
|
|
107
107
|
_IN_WAIT = False # True while meshcode_wait is blocking
|
|
108
|
-
# Default
|
|
109
|
-
|
|
108
|
+
# Default OFF as of 2.10.27 — the AppleScript/PowerShell keystroke injection
|
|
109
|
+
# wrote nudge text directly into the user's terminal, which corrupts stdin on
|
|
110
|
+
# terminals that don't interpret ANSI, interrupts the user mid-typing, and
|
|
111
|
+
# duplicates what the dashboard already surfaces. Opt-in with
|
|
112
|
+
# MESHCODE_AUTO_WAKE=1 for users who want the legacy behavior.
|
|
113
|
+
_AUTO_WAKE = os.environ.get("MESHCODE_AUTO_WAKE", "0").lower() in ("1", "true", "yes")
|
|
110
114
|
|
|
111
115
|
|
|
112
116
|
def _try_auto_wake(from_agent: str, preview: str) -> None:
|
|
@@ -156,9 +160,11 @@ def _try_auto_wake(from_agent: str, preview: str) -> None:
|
|
|
156
160
|
# Sanitize inputs: strip everything except alphanumeric, spaces, basic punctuation
|
|
157
161
|
safe_agent = re.sub(r'[^a-zA-Z0-9_\- ]', '', from_agent)[:50]
|
|
158
162
|
safe_preview = re.sub(r'[^a-zA-Z0-9_\-.,!? ]', '', preview)[:60]
|
|
159
|
-
#
|
|
160
|
-
|
|
161
|
-
|
|
163
|
+
# Plain-text nudge. ANSI colors were stripped 2026-04-16 because terminals
|
|
164
|
+
# that don't interpret escape sequences (TypeScript runners, some VSCode
|
|
165
|
+
# configurations, pipelines, tmux without termguicolors) render the raw
|
|
166
|
+
# bytes — "[91m[1m[mesh][0m …" — which is worse UX than no color at all.
|
|
167
|
+
nudge = f"[mesh] {safe_agent} > {safe_preview} — meshcode_check()"
|
|
162
168
|
system = platform.system()
|
|
163
169
|
try:
|
|
164
170
|
if system == "Darwin":
|
|
@@ -799,12 +805,11 @@ def _log_crash_to_db(reason: str = "unknown", error_detail: str = "") -> None:
|
|
|
799
805
|
|
|
800
806
|
|
|
801
807
|
|
|
802
|
-
# NOTE: Do NOT install
|
|
803
|
-
#
|
|
804
|
-
# handlers override Python's default KeyboardInterrupt, preventing anyio from
|
|
805
|
-
# cancelling tasks cleanly. Network calls inside signal/atexit handlers can
|
|
806
|
-
# deadlock or corrupt the event loop. The lease will be released by the
|
|
808
|
+
# NOTE: Do NOT install custom SIGTERM handlers or atexit hooks here — network
|
|
809
|
+
# calls inside them can deadlock the event loop. The lease is released by the
|
|
807
810
|
# lifespan shutdown handler instead.
|
|
811
|
+
#
|
|
812
|
+
# SIGINT handling is special — see run_server() for why we set SIG_IGN there.
|
|
808
813
|
|
|
809
814
|
|
|
810
815
|
# ============================================================
|
|
@@ -2795,14 +2800,7 @@ def _auto_update() -> None:
|
|
|
2795
2800
|
|
|
2796
2801
|
|
|
2797
2802
|
def run_server():
|
|
2798
|
-
"""Start the MCP server on stdio (default for Claude Code).
|
|
2799
|
-
|
|
2800
|
-
IMPORTANT: Do NOT wrap mcp.run() with try/except, signal handlers, or
|
|
2801
|
-
atexit hooks. FastMCP/anyio manages its own event loop lifecycle and
|
|
2802
|
-
signal handling. Any interference (custom SIGINT handler, atexit network
|
|
2803
|
-
calls, catching KeyboardInterrupt) corrupts the event loop and causes
|
|
2804
|
-
the MCP server to crash when Claude Code cancels a tool call (ESC).
|
|
2805
|
-
"""
|
|
2803
|
+
"""Start the MCP server on stdio (default for Claude Code)."""
|
|
2806
2804
|
_auto_update()
|
|
2807
2805
|
print(
|
|
2808
2806
|
f"[meshcode-mcp] Starting server for {AGENT_NAME}@{PROJECT_NAME}",
|
|
@@ -2812,4 +2810,25 @@ def run_server():
|
|
|
2812
2810
|
# sys.stdout was redirected to stderr at module load to prevent
|
|
2813
2811
|
# accidental stdout writes from corrupting the MCP protocol.
|
|
2814
2812
|
sys.stdout = _REAL_STDOUT
|
|
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.
|
|
2827
|
+
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
|
|
2833
|
+
|
|
2815
2834
|
mcp.run()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|