meshcode 2.10.28__tar.gz → 2.10.30__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.28 → meshcode-2.10.30}/PKG-INFO +1 -1
- {meshcode-2.10.28 → meshcode-2.10.30}/meshcode/__init__.py +1 -1
- {meshcode-2.10.28 → meshcode-2.10.30}/meshcode/meshcode_mcp/server.py +45 -1
- {meshcode-2.10.28 → meshcode-2.10.30}/meshcode/run_agent.py +10 -6
- {meshcode-2.10.28 → meshcode-2.10.30}/meshcode.egg-info/PKG-INFO +1 -1
- {meshcode-2.10.28 → meshcode-2.10.30}/pyproject.toml +1 -1
- {meshcode-2.10.28 → meshcode-2.10.30}/README.md +0 -0
- {meshcode-2.10.28 → meshcode-2.10.30}/meshcode/ascii_art.py +0 -0
- {meshcode-2.10.28 → meshcode-2.10.30}/meshcode/cli.py +0 -0
- {meshcode-2.10.28 → meshcode-2.10.30}/meshcode/comms_v4.py +0 -0
- {meshcode-2.10.28 → meshcode-2.10.30}/meshcode/invites.py +0 -0
- {meshcode-2.10.28 → meshcode-2.10.30}/meshcode/launcher.py +0 -0
- {meshcode-2.10.28 → meshcode-2.10.30}/meshcode/launcher_install.py +0 -0
- {meshcode-2.10.28 → meshcode-2.10.30}/meshcode/meshcode_mcp/__init__.py +0 -0
- {meshcode-2.10.28 → meshcode-2.10.30}/meshcode/meshcode_mcp/__main__.py +0 -0
- {meshcode-2.10.28 → meshcode-2.10.30}/meshcode/meshcode_mcp/backend.py +0 -0
- {meshcode-2.10.28 → meshcode-2.10.30}/meshcode/meshcode_mcp/realtime.py +0 -0
- {meshcode-2.10.28 → meshcode-2.10.30}/meshcode/meshcode_mcp/test_backend.py +0 -0
- {meshcode-2.10.28 → meshcode-2.10.30}/meshcode/meshcode_mcp/test_realtime.py +0 -0
- {meshcode-2.10.28 → meshcode-2.10.30}/meshcode/meshcode_mcp/test_server_wrapper.py +0 -0
- {meshcode-2.10.28 → meshcode-2.10.30}/meshcode/preferences.py +0 -0
- {meshcode-2.10.28 → meshcode-2.10.30}/meshcode/protocol_v2.py +0 -0
- {meshcode-2.10.28 → meshcode-2.10.30}/meshcode/secrets.py +0 -0
- {meshcode-2.10.28 → meshcode-2.10.30}/meshcode/self_update.py +0 -0
- {meshcode-2.10.28 → meshcode-2.10.30}/meshcode/setup_clients.py +0 -0
- {meshcode-2.10.28 → meshcode-2.10.30}/meshcode.egg-info/SOURCES.txt +0 -0
- {meshcode-2.10.28 → meshcode-2.10.30}/meshcode.egg-info/dependency_links.txt +0 -0
- {meshcode-2.10.28 → meshcode-2.10.30}/meshcode.egg-info/entry_points.txt +0 -0
- {meshcode-2.10.28 → meshcode-2.10.30}/meshcode.egg-info/requires.txt +0 -0
- {meshcode-2.10.28 → meshcode-2.10.30}/meshcode.egg-info/top_level.txt +0 -0
- {meshcode-2.10.28 → meshcode-2.10.30}/setup.cfg +0 -0
- {meshcode-2.10.28 → meshcode-2.10.30}/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.30"
|
|
@@ -2852,4 +2852,48 @@ def run_server():
|
|
|
2852
2852
|
# Non-main thread or Windows doesn't expose the signal — harmless.
|
|
2853
2853
|
pass
|
|
2854
2854
|
|
|
2855
|
-
|
|
2855
|
+
# 2.10.29 field test proved: a bare FastMCP (naive.py / armored.py) loaded
|
|
2856
|
+
# via `claude mcp add` survives ESC, but meshcode does not — even after
|
|
2857
|
+
# moving out of the "Built-in" bucket to "Project". The remaining delta
|
|
2858
|
+
# between meshcode and the naked repro is our lifespan handler: it does
|
|
2859
|
+
# network I/O (release_lease, memory_set), blocking thread joins, and an
|
|
2860
|
+
# await on Realtime.stop() in its `finally`. When ESC cancels the in-flight
|
|
2861
|
+
# tool, CancelledError cascades into those shutdown steps, one of them
|
|
2862
|
+
# raises, and the event loop unwinds — process exits.
|
|
2863
|
+
#
|
|
2864
|
+
# Short of rewriting the lifespan (which we will), the pragmatic safety
|
|
2865
|
+
# net is to treat `mcp.run()` returning unexpectedly as an event loop
|
|
2866
|
+
# casualty and spin up a fresh one. FastMCP registers tools at import
|
|
2867
|
+
# time on the module-level `mcp` object, so the restart re-uses them;
|
|
2868
|
+
# only the lifespan re-runs. `SystemExit` is let through so `sys.exit`
|
|
2869
|
+
# from config-validation paths still works. stdin EOF returns from
|
|
2870
|
+
# `mcp.run()` normally, which breaks the loop.
|
|
2871
|
+
import time as _time_mod
|
|
2872
|
+
_restart_count = 0
|
|
2873
|
+
while True:
|
|
2874
|
+
try:
|
|
2875
|
+
mcp.run()
|
|
2876
|
+
except SystemExit:
|
|
2877
|
+
raise
|
|
2878
|
+
except BaseException as _e:
|
|
2879
|
+
_restart_count += 1
|
|
2880
|
+
try:
|
|
2881
|
+
sys.stderr.write(
|
|
2882
|
+
f"[meshcode-mcp] mcp.run() raised {type(_e).__name__}: {_e} "
|
|
2883
|
+
f"(restart #{_restart_count}); re-entering event loop in 0.3s\n"
|
|
2884
|
+
)
|
|
2885
|
+
sys.stderr.flush()
|
|
2886
|
+
except Exception:
|
|
2887
|
+
pass
|
|
2888
|
+
# If we're restarting more than a few times a second, something
|
|
2889
|
+
# is wrong (config error, unrecoverable import). Bail.
|
|
2890
|
+
if _restart_count > 20:
|
|
2891
|
+
try:
|
|
2892
|
+
sys.stderr.write("[meshcode-mcp] too many restarts; exiting\n")
|
|
2893
|
+
except Exception:
|
|
2894
|
+
pass
|
|
2895
|
+
break
|
|
2896
|
+
_time_mod.sleep(0.3)
|
|
2897
|
+
continue
|
|
2898
|
+
# Clean return = stdin EOF = Claude Code closed the pipe = real shutdown
|
|
2899
|
+
break
|
|
@@ -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:
|
|
469
|
-
#
|
|
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)")
|
|
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
|