meshcode 2.10.14__tar.gz → 2.10.15__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.14 → meshcode-2.10.15}/PKG-INFO +1 -1
- {meshcode-2.10.14 → meshcode-2.10.15}/meshcode/__init__.py +1 -1
- {meshcode-2.10.14 → meshcode-2.10.15}/meshcode/meshcode_mcp/server.py +31 -26
- {meshcode-2.10.14 → meshcode-2.10.15}/meshcode.egg-info/PKG-INFO +1 -1
- {meshcode-2.10.14 → meshcode-2.10.15}/pyproject.toml +1 -1
- {meshcode-2.10.14 → meshcode-2.10.15}/README.md +0 -0
- {meshcode-2.10.14 → meshcode-2.10.15}/meshcode/ascii_art.py +0 -0
- {meshcode-2.10.14 → meshcode-2.10.15}/meshcode/cli.py +0 -0
- {meshcode-2.10.14 → meshcode-2.10.15}/meshcode/comms_v4.py +0 -0
- {meshcode-2.10.14 → meshcode-2.10.15}/meshcode/invites.py +0 -0
- {meshcode-2.10.14 → meshcode-2.10.15}/meshcode/launcher.py +0 -0
- {meshcode-2.10.14 → meshcode-2.10.15}/meshcode/launcher_install.py +0 -0
- {meshcode-2.10.14 → meshcode-2.10.15}/meshcode/meshcode_mcp/__init__.py +0 -0
- {meshcode-2.10.14 → meshcode-2.10.15}/meshcode/meshcode_mcp/__main__.py +0 -0
- {meshcode-2.10.14 → meshcode-2.10.15}/meshcode/meshcode_mcp/backend.py +0 -0
- {meshcode-2.10.14 → meshcode-2.10.15}/meshcode/meshcode_mcp/realtime.py +0 -0
- {meshcode-2.10.14 → meshcode-2.10.15}/meshcode/meshcode_mcp/test_backend.py +0 -0
- {meshcode-2.10.14 → meshcode-2.10.15}/meshcode/meshcode_mcp/test_realtime.py +0 -0
- {meshcode-2.10.14 → meshcode-2.10.15}/meshcode/meshcode_mcp/test_server_wrapper.py +0 -0
- {meshcode-2.10.14 → meshcode-2.10.15}/meshcode/preferences.py +0 -0
- {meshcode-2.10.14 → meshcode-2.10.15}/meshcode/protocol_v2.py +0 -0
- {meshcode-2.10.14 → meshcode-2.10.15}/meshcode/run_agent.py +0 -0
- {meshcode-2.10.14 → meshcode-2.10.15}/meshcode/secrets.py +0 -0
- {meshcode-2.10.14 → meshcode-2.10.15}/meshcode/self_update.py +0 -0
- {meshcode-2.10.14 → meshcode-2.10.15}/meshcode/setup_clients.py +0 -0
- {meshcode-2.10.14 → meshcode-2.10.15}/meshcode.egg-info/SOURCES.txt +0 -0
- {meshcode-2.10.14 → meshcode-2.10.15}/meshcode.egg-info/dependency_links.txt +0 -0
- {meshcode-2.10.14 → meshcode-2.10.15}/meshcode.egg-info/entry_points.txt +0 -0
- {meshcode-2.10.14 → meshcode-2.10.15}/meshcode.egg-info/requires.txt +0 -0
- {meshcode-2.10.14 → meshcode-2.10.15}/meshcode.egg-info/top_level.txt +0 -0
- {meshcode-2.10.14 → meshcode-2.10.15}/setup.cfg +0 -0
- {meshcode-2.10.14 → meshcode-2.10.15}/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.15"
|
|
@@ -67,16 +67,21 @@ def _agent_color(name: str) -> str:
|
|
|
67
67
|
|
|
68
68
|
|
|
69
69
|
def _mc_log(msg: str, level: str = "info") -> None:
|
|
70
|
-
"""Colored [meshcode-mcp] log line. Uses agent color if available.
|
|
70
|
+
"""Colored [meshcode-mcp] log line. Uses agent color if available.
|
|
71
|
+
|
|
72
|
+
CRITICAL: Must write to stderr, NEVER stdout. MCP protocol uses stdout
|
|
73
|
+
for JSON-RPC — any non-JSON output to stdout corrupts the stream and
|
|
74
|
+
causes Claude Code to kill the connection.
|
|
75
|
+
"""
|
|
71
76
|
agent = os.environ.get("MESHCODE_AGENT", "")
|
|
72
77
|
c = _agent_color(agent) if agent else "\033[36m"
|
|
73
78
|
prefix = f"{c}{_ANSI_BOLD}[meshcode-mcp]{_ANSI_RESET}"
|
|
74
79
|
if level == "error":
|
|
75
|
-
print(f"{prefix} \033[91mERROR:{_ANSI_RESET} {msg}",
|
|
80
|
+
print(f"{prefix} \033[91mERROR:{_ANSI_RESET} {msg}", file=sys.stderr)
|
|
76
81
|
elif level == "warn":
|
|
77
|
-
print(f"{prefix} \033[33mWARNING:{_ANSI_RESET} {msg}",
|
|
82
|
+
print(f"{prefix} \033[33mWARNING:{_ANSI_RESET} {msg}", file=sys.stderr)
|
|
78
83
|
else:
|
|
79
|
-
print(f"{prefix} {c}{msg}{_ANSI_RESET}",
|
|
84
|
+
print(f"{prefix} {c}{msg}{_ANSI_RESET}", file=sys.stderr)
|
|
80
85
|
|
|
81
86
|
|
|
82
87
|
# ============================================================
|
|
@@ -373,7 +378,7 @@ def _get_api_key() -> str:
|
|
|
373
378
|
_API_KEY_CACHE = kc_val
|
|
374
379
|
return kc_val
|
|
375
380
|
except Exception as e:
|
|
376
|
-
_mc_log(f" keychain lookup failed for profile '{profile}': {e}",
|
|
381
|
+
_mc_log(f" keychain lookup failed for profile '{profile}': {e}", file=sys.stderr)
|
|
377
382
|
_API_KEY_CACHE = ""
|
|
378
383
|
return ""
|
|
379
384
|
|
|
@@ -398,16 +403,16 @@ if not _PROJECT_ID:
|
|
|
398
403
|
_PROJECT_ID = _r["project_id"]
|
|
399
404
|
break
|
|
400
405
|
elif isinstance(_r, dict) and _r.get("error"):
|
|
401
|
-
_mc_log(f" mc_resolve_project: {_r['error']}",
|
|
406
|
+
_mc_log(f" mc_resolve_project: {_r['error']}", file=sys.stderr)
|
|
402
407
|
except Exception as _e:
|
|
403
|
-
_mc_log(f" mc_resolve_project failed: {_e}",
|
|
408
|
+
_mc_log(f" mc_resolve_project failed: {_e}", file=sys.stderr)
|
|
404
409
|
if not _PROJECT_ID:
|
|
405
410
|
_PROJECT_ID = be.get_project_id(PROJECT_NAME)
|
|
406
411
|
if _PROJECT_ID:
|
|
407
412
|
break
|
|
408
413
|
if _boot_attempt < _BOOT_MAX_RETRIES - 1:
|
|
409
414
|
_wait = _BOOT_BACKOFF[_boot_attempt]
|
|
410
|
-
_mc_log(f" project resolution failed (attempt {_boot_attempt+1}/{_BOOT_MAX_RETRIES}), retrying in {_wait}s...",
|
|
415
|
+
_mc_log(f" project resolution failed (attempt {_boot_attempt+1}/{_BOOT_MAX_RETRIES}), retrying in {_wait}s...", file=sys.stderr)
|
|
411
416
|
_time.sleep(_wait)
|
|
412
417
|
if not _PROJECT_ID:
|
|
413
418
|
_mc_log(f"project '{PROJECT_NAME}' not found after {_BOOT_MAX_RETRIES} attempts (check MESHCODE_KEYCHAIN_PROFILE / MESHCODE_API_KEY)", "error")
|
|
@@ -424,7 +429,7 @@ except Exception:
|
|
|
424
429
|
|
|
425
430
|
_register_result = be.register_agent(PROJECT_NAME, AGENT_NAME, AGENT_ROLE or "MCP-connected agent", api_key=_get_api_key())
|
|
426
431
|
if isinstance(_register_result, dict) and _register_result.get("error"):
|
|
427
|
-
_mc_log(f" register failed: {_register_result['error']}",
|
|
432
|
+
_mc_log(f" register failed: {_register_result['error']}", file=sys.stderr)
|
|
428
433
|
|
|
429
434
|
# ── Fetch profile color from dashboard (single source of truth) ──
|
|
430
435
|
try:
|
|
@@ -458,7 +463,7 @@ def _flip_status(status: str, task: str = "") -> bool:
|
|
|
458
463
|
return False
|
|
459
464
|
|
|
460
465
|
if not _flip_status("idle", ""):
|
|
461
|
-
_mc_log(f" could not flip status to idle",
|
|
466
|
+
_mc_log(f" could not flip status to idle", file=sys.stderr)
|
|
462
467
|
|
|
463
468
|
|
|
464
469
|
# ============================================================
|
|
@@ -623,7 +628,7 @@ def _acquire_lease() -> bool:
|
|
|
623
628
|
})
|
|
624
629
|
except Exception as e:
|
|
625
630
|
# Non-fatal: RPC might not exist on older servers.
|
|
626
|
-
_mc_log(f"stale-lease pre-clean skipped: {e}",
|
|
631
|
+
_mc_log(f"stale-lease pre-clean skipped: {e}", file=sys.stderr)
|
|
627
632
|
for attempt in range(3):
|
|
628
633
|
try:
|
|
629
634
|
r = be.sb_rpc("mc_acquire_agent_lease", {
|
|
@@ -675,14 +680,14 @@ def _acquire_lease() -> bool:
|
|
|
675
680
|
_mc_log(f"Could not start — agent '{AGENT_NAME}' is running in another window.", "error")
|
|
676
681
|
_mc_log("Close the other window first, or use a different agent name.", "error")
|
|
677
682
|
return False
|
|
678
|
-
_mc_log(f"lease attempt {attempt+1}: {r.get('error')}",
|
|
683
|
+
_mc_log(f"lease attempt {attempt+1}: {r.get('error')}", file=sys.stderr)
|
|
679
684
|
else:
|
|
680
685
|
return True
|
|
681
686
|
except Exception as e:
|
|
682
|
-
_mc_log(f"lease attempt {attempt+1} failed: {e}",
|
|
687
|
+
_mc_log(f"lease attempt {attempt+1} failed: {e}", file=sys.stderr)
|
|
683
688
|
if attempt < 2:
|
|
684
689
|
_time.sleep(2)
|
|
685
|
-
_mc_log(f" lease failed after 3 attempts — proceeding anyway",
|
|
690
|
+
_mc_log(f" lease failed after 3 attempts — proceeding anyway", file=sys.stderr)
|
|
686
691
|
return True
|
|
687
692
|
|
|
688
693
|
if not _acquire_lease():
|
|
@@ -700,7 +705,7 @@ def _boot_diagnostic() -> None:
|
|
|
700
705
|
be.sb_select("mc_projects", f"id=eq.{_PROJECT_ID}", limit=1)
|
|
701
706
|
checks_passed += 1
|
|
702
707
|
except Exception as e:
|
|
703
|
-
print(f"[meshcode] BOOT CHECK FAILED: Supabase API unreachable ({e}). Fix: check network/VPN.",
|
|
708
|
+
print(f"[meshcode] BOOT CHECK FAILED: Supabase API unreachable ({e}). Fix: check network/VPN.", file=sys.stderr)
|
|
704
709
|
|
|
705
710
|
# Check 2: Lease valid
|
|
706
711
|
try:
|
|
@@ -710,11 +715,11 @@ def _boot_diagnostic() -> None:
|
|
|
710
715
|
if agent.get("instance_id") == _INSTANCE_ID:
|
|
711
716
|
checks_passed += 1
|
|
712
717
|
else:
|
|
713
|
-
print(f"[meshcode] BOOT CHECK FAILED: Lease mismatch — expected {_INSTANCE_ID}, got {agent.get('instance_id')}. Fix: restart agent.",
|
|
718
|
+
print(f"[meshcode] BOOT CHECK FAILED: Lease mismatch — expected {_INSTANCE_ID}, got {agent.get('instance_id')}. Fix: restart agent.", file=sys.stderr)
|
|
714
719
|
else:
|
|
715
|
-
print(f"[meshcode] BOOT CHECK FAILED: Agent '{AGENT_NAME}' not found in project. Fix: register agent first.",
|
|
720
|
+
print(f"[meshcode] BOOT CHECK FAILED: Agent '{AGENT_NAME}' not found in project. Fix: register agent first.", file=sys.stderr)
|
|
716
721
|
except Exception as e:
|
|
717
|
-
print(f"[meshcode] BOOT CHECK FAILED: Could not verify lease ({e}).",
|
|
722
|
+
print(f"[meshcode] BOOT CHECK FAILED: Could not verify lease ({e}).", file=sys.stderr)
|
|
718
723
|
|
|
719
724
|
# Check 3: Heartbeat recent
|
|
720
725
|
try:
|
|
@@ -723,7 +728,7 @@ def _boot_diagnostic() -> None:
|
|
|
723
728
|
if hb:
|
|
724
729
|
checks_passed += 1
|
|
725
730
|
else:
|
|
726
|
-
print(f"[meshcode] BOOT CHECK WARNING: No heartbeat recorded yet.",
|
|
731
|
+
print(f"[meshcode] BOOT CHECK WARNING: No heartbeat recorded yet.", file=sys.stderr)
|
|
727
732
|
else:
|
|
728
733
|
checks_passed += 1 # skip if no agent data
|
|
729
734
|
except Exception:
|
|
@@ -740,9 +745,9 @@ def _boot_diagnostic() -> None:
|
|
|
740
745
|
checks_passed += 1 # non-critical
|
|
741
746
|
|
|
742
747
|
if checks_passed == checks_total:
|
|
743
|
-
print(f"[meshcode] All boot checks passed ({checks_passed}/{checks_total}).",
|
|
748
|
+
print(f"[meshcode] All boot checks passed ({checks_passed}/{checks_total}).", file=sys.stderr)
|
|
744
749
|
else:
|
|
745
|
-
print(f"[meshcode] Boot checks: {checks_passed}/{checks_total} passed. Agent starting anyway.",
|
|
750
|
+
print(f"[meshcode] Boot checks: {checks_passed}/{checks_total} passed. Agent starting anyway.", file=sys.stderr)
|
|
746
751
|
|
|
747
752
|
|
|
748
753
|
_boot_diagnostic()
|
|
@@ -789,7 +794,7 @@ def _log_crash_to_db(reason: str = "unknown", error_detail: str = "") -> None:
|
|
|
789
794
|
f"crashed: {reason[:100]}", api_key=_get_api_key())
|
|
790
795
|
except Exception:
|
|
791
796
|
pass
|
|
792
|
-
_mc_log(f" crash logged: {reason}",
|
|
797
|
+
_mc_log(f" crash logged: {reason}", file=sys.stderr)
|
|
793
798
|
|
|
794
799
|
|
|
795
800
|
def _on_exit() -> None:
|
|
@@ -1449,9 +1454,9 @@ try:
|
|
|
1449
1454
|
elif isinstance(_ls_val, str):
|
|
1450
1455
|
_LAST_SEEN_TS = _ls_val
|
|
1451
1456
|
if _LAST_SEEN_TS:
|
|
1452
|
-
print(f"[meshcode] Restored last_seen={_LAST_SEEN_TS} from mesh memory.",
|
|
1457
|
+
print(f"[meshcode] Restored last_seen={_LAST_SEEN_TS} from mesh memory.", file=sys.stderr)
|
|
1453
1458
|
except Exception as _e:
|
|
1454
|
-
print(f"[meshcode] Could not restore last_seen: {_e}",
|
|
1459
|
+
print(f"[meshcode] Could not restore last_seen: {_e}", file=sys.stderr)
|
|
1455
1460
|
|
|
1456
1461
|
|
|
1457
1462
|
def _get_pending_tasks_summary() -> Optional[List[Dict[str, str]]]:
|
|
@@ -2611,7 +2616,7 @@ def _auto_update() -> None:
|
|
|
2611
2616
|
return
|
|
2612
2617
|
|
|
2613
2618
|
# 3. Install the new version (blocking, 60s timeout)
|
|
2614
|
-
print(f"[meshcode] Updating {current} → {latest}...",
|
|
2619
|
+
print(f"[meshcode] Updating {current} → {latest}...", file=sys.stderr)
|
|
2615
2620
|
try:
|
|
2616
2621
|
result = subprocess.run(
|
|
2617
2622
|
[sys.executable, "-m", "pip", "install", "--upgrade",
|
|
@@ -2629,7 +2634,7 @@ def _auto_update() -> None:
|
|
|
2629
2634
|
return
|
|
2630
2635
|
|
|
2631
2636
|
# 4. Re-exec to load the new code
|
|
2632
|
-
print(f"[meshcode] Updated to {latest}, restarting...",
|
|
2637
|
+
print(f"[meshcode] Updated to {latest}, restarting...", file=sys.stderr)
|
|
2633
2638
|
os.environ["MESHCODE_UPDATED"] = "1"
|
|
2634
2639
|
try:
|
|
2635
2640
|
os.execv(sys.executable, [sys.executable] + sys.argv)
|
|
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
|