meshcode 2.11.135__tar.gz → 2.11.137__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.11.135 → meshcode-2.11.137}/PKG-INFO +2 -11
- {meshcode-2.11.135 → meshcode-2.11.137}/meshcode/__init__.py +1 -1
- meshcode-2.11.137/meshcode/helper_visuals.py +142 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/meshcode/hostd.py +305 -53
- {meshcode-2.11.135 → meshcode-2.11.137}/meshcode/meshcode_mcp/server.py +41 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/meshcode/meshcode_mcp/swarm.py +60 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/meshcode/meshcode_mcp/test_swarm.py +43 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/meshcode/protocol_handler.py +55 -1
- {meshcode-2.11.135 → meshcode-2.11.137}/meshcode/run_agent.py +72 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/meshcode.egg-info/PKG-INFO +2 -11
- {meshcode-2.11.135 → meshcode-2.11.137}/meshcode.egg-info/SOURCES.txt +3 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/pyproject.toml +1 -1
- meshcode-2.11.137/tests/test_helper_visuals.py +199 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/tests/test_hostd_zombie_sessions.py +344 -3
- meshcode-2.11.137/tests/test_pretrust_claude.py +86 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/README.md +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/meshcode/__main__.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/meshcode/_session_handoff_template.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/meshcode/_stop_hook_template.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/meshcode/ascii_art.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/meshcode/atomic_push.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/meshcode/claude_update.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/meshcode/cli.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/meshcode/comms_v4.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/meshcode/compat.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/meshcode/daemon.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/meshcode/date_parse.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/meshcode/doctor.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/meshcode/error_hints.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/meshcode/exceptions.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/meshcode/hooks/__init__.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/meshcode/hooks/repo_path_lock.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/meshcode/invites.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/meshcode/launcher.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/meshcode/launcher_install.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/meshcode/meshcode_mcp/__init__.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/meshcode/meshcode_mcp/__main__.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/meshcode/meshcode_mcp/backend.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/meshcode/meshcode_mcp/realtime.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/meshcode/meshcode_mcp/sleep_signals.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/meshcode/meshcode_mcp/test_backend.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/meshcode/meshcode_mcp/test_boot_timing.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/meshcode/meshcode_mcp/test_install_guard.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/meshcode/meshcode_mcp/test_prefs_claude_version.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/meshcode/meshcode_mcp/test_realtime.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/meshcode/meshcode_mcp/test_server_wrapper.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/meshcode/preferences.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/meshcode/protocol_v2.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/meshcode/quickstart.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/meshcode/rpc_allowlist.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/meshcode/scripts/check_secrets.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/meshcode/scripts/race_rate_harness.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/meshcode/secrets.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/meshcode/self_update.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/meshcode/setup_clients.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/meshcode/supervisor.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/meshcode/up.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/meshcode/upload.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/meshcode.egg-info/dependency_links.txt +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/meshcode.egg-info/entry_points.txt +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/meshcode.egg-info/requires.txt +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/meshcode.egg-info/top_level.txt +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/setup.cfg +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/tests/test_auto_update_hardening.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/tests/test_autonomous_closegap_1.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/tests/test_autonomous_closegap_2.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/tests/test_autonomous_closegap_3.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/tests/test_autonomous_prompt_inject.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/tests/test_boot_bug_regression.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/tests/test_color_truecolor.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/tests/test_core.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/tests/test_cross_agent_messaging.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/tests/test_date_parse.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/tests/test_doctor.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/tests/test_epistemic_v1_python_sdk.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/tests/test_epistemic_v1_stop_conditions.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/tests/test_esc_deaf_state.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/tests/test_exceptions.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/tests/test_file_upload.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/tests/test_init_device_code.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/tests/test_install_guard.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/tests/test_lease_sigterm_release.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/tests/test_live_mesh_guard.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/tests/test_mark_read_batch.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/tests/test_marketplace_ratings.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/tests/test_migration_integrity.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/tests/test_realtime_event_freshness.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/tests/test_rls_cross_tenant.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/tests/test_rpc_grants.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/tests/test_rpc_migrations.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/tests/test_run_agent_dry_run.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/tests/test_run_agent_no_server_import.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/tests/test_security_regressions.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/tests/test_self_update_user_site.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/tests/test_sentinel.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/tests/test_session_replay_gate.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/tests/test_setup_path.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/tests/test_sleep_signals.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/tests/test_status_enum_coverage.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/tests/test_stay_on_loop_hook.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/tests/test_stop_ghost_terminal.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/tests/test_swarm_events.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/tests/test_task_progress.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/tests/test_terminal_lifecycle.py +0 -0
- {meshcode-2.11.135 → meshcode-2.11.137}/tests/test_wait_open_tasks_contradiction.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
2
|
Name: meshcode
|
|
3
|
-
Version: 2.11.
|
|
3
|
+
Version: 2.11.137
|
|
4
4
|
Summary: Real-time communication between AI agents — Supabase-backed CLI
|
|
5
5
|
Author-email: MeshCode <hello@meshcode.io>
|
|
6
6
|
License: MIT
|
|
@@ -18,17 +18,8 @@ Classifier: Programming Language :: Python :: 3.12
|
|
|
18
18
|
Classifier: Operating System :: OS Independent
|
|
19
19
|
Requires-Python: >=3.9
|
|
20
20
|
Description-Content-Type: text/markdown
|
|
21
|
-
Requires-Dist: mcp[cli]>=1.0.0
|
|
22
|
-
Requires-Dist: websockets>=12.0
|
|
23
|
-
Requires-Dist: realtime>=2.0.0
|
|
24
|
-
Requires-Dist: keyring>=24.0
|
|
25
|
-
Requires-Dist: cryptography>=41.0
|
|
26
21
|
Provides-Extra: test
|
|
27
|
-
Requires-Dist: pytest>=8; extra == "test"
|
|
28
22
|
Provides-Extra: dev
|
|
29
|
-
Requires-Dist: build>=1.0; extra == "dev"
|
|
30
|
-
Requires-Dist: twine>=4; extra == "dev"
|
|
31
|
-
Requires-Dist: pytest>=8; extra == "dev"
|
|
32
23
|
|
|
33
24
|
# MeshCode
|
|
34
25
|
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
"""Helper terminal visuals (task d8f8e325 — Samuel msgs edf0ed8d + 68c7fee0).
|
|
2
|
+
|
|
3
|
+
ENJAMBRE helpers must open VISUALLY DISTINCT from top-level agents on every
|
|
4
|
+
platform, so a wall of fleet tabs reads instantly: amber = ephemeral helper,
|
|
5
|
+
normal = real agent. Two layers (both silent-degrade — a visuals failure must
|
|
6
|
+
NEVER break a spawn):
|
|
7
|
+
|
|
8
|
+
[1] UNIVERSAL — `meshcode run` emits OSC 0/2 (title "helper:<name>") +
|
|
9
|
+
OSC 11 (dark-amber background) at session start. Works in Windows
|
|
10
|
+
Terminal, iTerm2 and most xterm-compatible Linux terminals regardless
|
|
11
|
+
of which launcher opened the window; terminals that ignore OSC 11
|
|
12
|
+
(e.g. macOS Terminal.app) still get the title.
|
|
13
|
+
[2] PER-PLATFORM at spawn — Windows Terminal gets `--tabColor <amber>` +
|
|
14
|
+
`--title helper:<name>` on the fleet tab; the Linux/macOS launcher
|
|
15
|
+
scripts prepend the same OSC prelude so the tint applies even before
|
|
16
|
+
`meshcode run` boots.
|
|
17
|
+
|
|
18
|
+
HOW A SPAWNER KNOWS IT'S A HELPER (no agent_kind in the spawn payloads —
|
|
19
|
+
probed live 2026-06-12: mc_agents_needing_respawn candidates and
|
|
20
|
+
mc_host_config_get agents carry no kind field):
|
|
21
|
+
|
|
22
|
+
- MARKER FILE: swarm.spawn_helper() runs on the PARENT's host, which is the
|
|
23
|
+
same host the helper spawns on (W5: helper row inherits the parent's
|
|
24
|
+
host/repo). It stamps ~/.meshcode/helpers/<name>.json with the helper's
|
|
25
|
+
TTL; spawners treat a FRESH marker as "helper". TTL expiry is the
|
|
26
|
+
cleanup (helpers are ephemeral by contract, TTL <= 86400).
|
|
27
|
+
- NAME PREFIX fallback: a name starting with 'helper' counts even without
|
|
28
|
+
a marker (covers cross-host edge cases + the observed naming convention).
|
|
29
|
+
|
|
30
|
+
Tradeoff (documented): a top-level agent that shares a helper's bare name on
|
|
31
|
+
the same host within the marker TTL would render amber — cosmetic only, and
|
|
32
|
+
name collisions are already rejected server-side within a meshwork.
|
|
33
|
+
"""
|
|
34
|
+
from __future__ import annotations
|
|
35
|
+
|
|
36
|
+
import json
|
|
37
|
+
import re
|
|
38
|
+
import sys
|
|
39
|
+
import time
|
|
40
|
+
from pathlib import Path
|
|
41
|
+
|
|
42
|
+
# Spec colors (task d8f8e325): amber tab; dark-amber background tint that
|
|
43
|
+
# keeps default light-on-dark text readable.
|
|
44
|
+
HELPER_TAB_COLOR = "#E8A33D"
|
|
45
|
+
HELPER_BG_COLOR = "#3A2310"
|
|
46
|
+
HELPER_TITLE_PREFIX = "helper:"
|
|
47
|
+
|
|
48
|
+
_MARKER_TTL_CAP_S = 86400 # mirror of the server-side helper TTL ceiling
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def _helpers_dir() -> Path:
|
|
52
|
+
"""Marker directory, behind a function so tests can patch it."""
|
|
53
|
+
return Path.home() / ".meshcode" / "helpers"
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def _safe_name(name: str) -> str:
|
|
57
|
+
return re.sub(r"[^A-Za-z0-9_.-]", "_", (name or "").strip()).strip("_")[:80]
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def mark_helper(name: str, ttl_seconds: int = 3600) -> None:
|
|
61
|
+
"""Stamp <name> as a helper on THIS host (called by swarm.spawn_helper).
|
|
62
|
+
Best-effort: never raises. Opportunistically prunes expired markers."""
|
|
63
|
+
try:
|
|
64
|
+
safe = _safe_name(name)
|
|
65
|
+
if not safe:
|
|
66
|
+
return
|
|
67
|
+
d = _helpers_dir()
|
|
68
|
+
d.mkdir(parents=True, exist_ok=True)
|
|
69
|
+
ttl = max(60, min(int(ttl_seconds or 3600), _MARKER_TTL_CAP_S))
|
|
70
|
+
(d / f"{safe}.json").write_text(
|
|
71
|
+
json.dumps({"name": name, "expires_at": time.time() + ttl}),
|
|
72
|
+
encoding="utf-8")
|
|
73
|
+
for p in d.glob("*.json"):
|
|
74
|
+
try:
|
|
75
|
+
if float(json.loads(p.read_text(encoding="utf-8"))
|
|
76
|
+
.get("expires_at", 0)) < time.time():
|
|
77
|
+
p.unlink()
|
|
78
|
+
except Exception:
|
|
79
|
+
continue
|
|
80
|
+
except Exception:
|
|
81
|
+
pass
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def unmark_helper(name: str) -> None:
|
|
85
|
+
"""Drop the marker (helper retired). Best-effort."""
|
|
86
|
+
try:
|
|
87
|
+
safe = _safe_name(name)
|
|
88
|
+
if safe:
|
|
89
|
+
(_helpers_dir() / f"{safe}.json").unlink(missing_ok=True)
|
|
90
|
+
except Exception:
|
|
91
|
+
pass
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def is_helper(target: str) -> bool:
|
|
95
|
+
"""True when `target` (bare 'name' or 'project/name') is a swarm helper:
|
|
96
|
+
fresh marker on this host OR the 'helper' name prefix. Never raises."""
|
|
97
|
+
try:
|
|
98
|
+
agent = (target or "").rsplit("/", 1)[-1].strip()
|
|
99
|
+
if not agent:
|
|
100
|
+
return False
|
|
101
|
+
if agent.lower().startswith("helper"):
|
|
102
|
+
return True
|
|
103
|
+
p = _helpers_dir() / f"{_safe_name(agent)}.json"
|
|
104
|
+
if not p.exists():
|
|
105
|
+
return False
|
|
106
|
+
data = json.loads(p.read_text(encoding="utf-8"))
|
|
107
|
+
return float(data.get("expires_at", 0)) >= time.time()
|
|
108
|
+
except Exception:
|
|
109
|
+
return False
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def helper_title(target: str) -> str:
|
|
113
|
+
"""Tab/window title for a helper: 'helper:<bare name>' (sanitized)."""
|
|
114
|
+
agent = _safe_name((target or "").rsplit("/", 1)[-1])
|
|
115
|
+
return f"{HELPER_TITLE_PREFIX}{agent or 'agent'}"[:48]
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def osc_prelude(target: str) -> str:
|
|
119
|
+
"""Escape string: OSC 0 title + OSC 11 background. Terminals that don't
|
|
120
|
+
support either sequence ignore it (that IS the degradation path)."""
|
|
121
|
+
return (f"\x1b]0;{helper_title(target)}\x07"
|
|
122
|
+
f"\x1b]11;{HELPER_BG_COLOR}\x07")
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def osc_prelude_shell(target: str) -> str:
|
|
126
|
+
"""The same prelude as a POSIX-shell `printf` command (for launcher
|
|
127
|
+
scripts / bash -lc command strings). Title is sanitized [A-Za-z0-9_.-:]
|
|
128
|
+
so it can never break out of the single quotes."""
|
|
129
|
+
return ("printf '\\033]0;%s\\007\\033]11;%s\\007' 2>/dev/null || true"
|
|
130
|
+
% (helper_title(target), HELPER_BG_COLOR))
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def emit_osc(target: str) -> None:
|
|
134
|
+
"""Universal layer: write the prelude to the live terminal from
|
|
135
|
+
`meshcode run`. Best-effort, TTY-gated (a piped/CI stdout never sees
|
|
136
|
+
escape garbage)."""
|
|
137
|
+
try:
|
|
138
|
+
if sys.stdout.isatty():
|
|
139
|
+
sys.stdout.write(osc_prelude(target))
|
|
140
|
+
sys.stdout.flush()
|
|
141
|
+
except Exception:
|
|
142
|
+
pass
|