meshcode 2.11.129__tar.gz → 2.11.131__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.129 → meshcode-2.11.131}/PKG-INFO +11 -2
- {meshcode-2.11.129 → meshcode-2.11.131}/meshcode/__init__.py +1 -1
- {meshcode-2.11.129 → meshcode-2.11.131}/meshcode/_session_handoff_template.py +71 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/meshcode/hostd.py +586 -34
- {meshcode-2.11.129 → meshcode-2.11.131}/meshcode/meshcode_mcp/server.py +50 -16
- {meshcode-2.11.129 → meshcode-2.11.131}/meshcode/meshcode_mcp/swarm.py +93 -38
- {meshcode-2.11.129 → meshcode-2.11.131}/meshcode/meshcode_mcp/test_swarm.py +118 -38
- {meshcode-2.11.129 → meshcode-2.11.131}/meshcode/protocol_handler.py +317 -16
- {meshcode-2.11.129 → meshcode-2.11.131}/meshcode/run_agent.py +18 -2
- {meshcode-2.11.129 → meshcode-2.11.131}/meshcode/setup_clients.py +14 -6
- {meshcode-2.11.129 → meshcode-2.11.131}/meshcode/up.py +2 -1
- {meshcode-2.11.129 → meshcode-2.11.131}/meshcode.egg-info/PKG-INFO +11 -2
- {meshcode-2.11.129 → meshcode-2.11.131}/meshcode.egg-info/SOURCES.txt +2 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/pyproject.toml +1 -1
- meshcode-2.11.131/tests/test_hostd_zombie_sessions.py +431 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/tests/test_stop_ghost_terminal.py +13 -3
- meshcode-2.11.131/tests/test_terminal_lifecycle.py +118 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/README.md +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/meshcode/__main__.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/meshcode/_stop_hook_template.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/meshcode/ascii_art.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/meshcode/atomic_push.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/meshcode/claude_update.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/meshcode/cli.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/meshcode/comms_v4.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/meshcode/compat.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/meshcode/daemon.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/meshcode/date_parse.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/meshcode/doctor.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/meshcode/error_hints.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/meshcode/exceptions.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/meshcode/hooks/__init__.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/meshcode/hooks/repo_path_lock.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/meshcode/invites.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/meshcode/launcher.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/meshcode/launcher_install.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/meshcode/meshcode_mcp/__init__.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/meshcode/meshcode_mcp/__main__.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/meshcode/meshcode_mcp/backend.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/meshcode/meshcode_mcp/realtime.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/meshcode/meshcode_mcp/sleep_signals.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/meshcode/meshcode_mcp/test_backend.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/meshcode/meshcode_mcp/test_boot_timing.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/meshcode/meshcode_mcp/test_install_guard.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/meshcode/meshcode_mcp/test_prefs_claude_version.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/meshcode/meshcode_mcp/test_realtime.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/meshcode/meshcode_mcp/test_server_wrapper.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/meshcode/preferences.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/meshcode/protocol_v2.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/meshcode/quickstart.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/meshcode/rpc_allowlist.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/meshcode/scripts/check_secrets.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/meshcode/scripts/race_rate_harness.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/meshcode/secrets.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/meshcode/self_update.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/meshcode/supervisor.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/meshcode/upload.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/meshcode.egg-info/dependency_links.txt +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/meshcode.egg-info/entry_points.txt +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/meshcode.egg-info/requires.txt +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/meshcode.egg-info/top_level.txt +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/setup.cfg +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/tests/test_auto_update_hardening.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/tests/test_autonomous_closegap_1.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/tests/test_autonomous_closegap_2.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/tests/test_autonomous_closegap_3.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/tests/test_autonomous_prompt_inject.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/tests/test_boot_bug_regression.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/tests/test_color_truecolor.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/tests/test_core.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/tests/test_cross_agent_messaging.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/tests/test_date_parse.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/tests/test_doctor.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/tests/test_epistemic_v1_python_sdk.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/tests/test_epistemic_v1_stop_conditions.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/tests/test_esc_deaf_state.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/tests/test_exceptions.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/tests/test_file_upload.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/tests/test_init_device_code.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/tests/test_install_guard.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/tests/test_lease_sigterm_release.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/tests/test_live_mesh_guard.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/tests/test_mark_read_batch.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/tests/test_marketplace_ratings.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/tests/test_migration_integrity.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/tests/test_realtime_event_freshness.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/tests/test_rls_cross_tenant.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/tests/test_rpc_grants.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/tests/test_rpc_migrations.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/tests/test_run_agent_dry_run.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/tests/test_run_agent_no_server_import.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/tests/test_security_regressions.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/tests/test_self_update_user_site.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/tests/test_sentinel.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/tests/test_session_replay_gate.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/tests/test_setup_path.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/tests/test_sleep_signals.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/tests/test_status_enum_coverage.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/tests/test_stay_on_loop_hook.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/tests/test_swarm_events.py +0 -0
- {meshcode-2.11.129 → meshcode-2.11.131}/tests/test_wait_open_tasks_contradiction.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: meshcode
|
|
3
|
-
Version: 2.11.
|
|
3
|
+
Version: 2.11.131
|
|
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,8 +18,17 @@ 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
|
|
21
26
|
Provides-Extra: test
|
|
27
|
+
Requires-Dist: pytest>=8; extra == "test"
|
|
22
28
|
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"
|
|
23
32
|
|
|
24
33
|
# MeshCode
|
|
25
34
|
|
|
@@ -208,6 +208,75 @@ def _persist_handoff_to_memory(project_dir, handoff) -> None:
|
|
|
208
208
|
sys.stderr.write(f"[session_handoff_write] memory-persist skipped: {e}\\n")
|
|
209
209
|
|
|
210
210
|
|
|
211
|
+
def _send_session_handoff_capsule(project_dir, handoff) -> None:
|
|
212
|
+
"""py-half task 4aee4739 (66d10cec): push a MINI capsule to the dedicated
|
|
213
|
+
mc_set_session_handoff RPC (live in prod, api_key-auth) so the NEXT boot
|
|
214
|
+
surfaces it as continuity_capsule.last_handoff in mc_boot — even on a new
|
|
215
|
+
host or wiped workspace. Contract: ended_at ISO8601, last_task_ids (str8
|
|
216
|
+
list scraped from the transcript tail), last_msg_snippet, note (from the
|
|
217
|
+
cooperative .session-thread.json if the agent keeps one). Best-effort in
|
|
218
|
+
every dimension — the stop/compaction path NEVER blocks on this.
|
|
219
|
+
"""
|
|
220
|
+
try:
|
|
221
|
+
mcp = json.loads((project_dir / ".mcp.json").read_text(encoding="utf-8"))
|
|
222
|
+
env = (next(iter((mcp.get("mcpServers") or {}).values()), {}) or {}).get("env", {}) or {}
|
|
223
|
+
url = env.get("SUPABASE_URL"); key = env.get("SUPABASE_KEY")
|
|
224
|
+
pid = env.get("MESHCODE_PROJECT_ID"); agent = env.get("MESHCODE_AGENT")
|
|
225
|
+
if not (url and key and pid and agent):
|
|
226
|
+
return
|
|
227
|
+
api_key = os.environ.get("MESHCODE_API_KEY")
|
|
228
|
+
if not api_key:
|
|
229
|
+
try:
|
|
230
|
+
import importlib
|
|
231
|
+
api_key = importlib.import_module("meshcode.secrets").get_api_key(
|
|
232
|
+
profile=env.get("MESHCODE_KEYCHAIN_PROFILE") or "default")
|
|
233
|
+
except Exception:
|
|
234
|
+
api_key = None
|
|
235
|
+
if not api_key:
|
|
236
|
+
return
|
|
237
|
+
import re as _re
|
|
238
|
+
from datetime import datetime, timezone
|
|
239
|
+
turns = handoff.get("turns") or []
|
|
240
|
+
tail_text = " ".join(t.get("text", "") for t in turns[-8:])
|
|
241
|
+
# task ids surface in transcripts as 8-hex prefixes (task_id short form);
|
|
242
|
+
# dedupe preserving order, cap 5 — a hint list, not an authority (boot
|
|
243
|
+
# task list stays authoritative).
|
|
244
|
+
seen = []
|
|
245
|
+
for m in _re.findall(r"\\b[0-9a-f]{8}\\b", tail_text):
|
|
246
|
+
if m not in seen:
|
|
247
|
+
seen.append(m)
|
|
248
|
+
note = ""
|
|
249
|
+
try:
|
|
250
|
+
thread = json.loads((project_dir / ".session-thread.json").read_text(encoding="utf-8"))
|
|
251
|
+
note = str(thread.get("hilo_de_pensamiento", ""))[:500]
|
|
252
|
+
except Exception:
|
|
253
|
+
pass
|
|
254
|
+
last_snip = ""
|
|
255
|
+
for t in reversed(turns):
|
|
256
|
+
if t.get("text"):
|
|
257
|
+
last_snip = str(t["text"])[:400]
|
|
258
|
+
break
|
|
259
|
+
capsule = {
|
|
260
|
+
"ended_at": datetime.now(timezone.utc).isoformat(),
|
|
261
|
+
"last_task_ids": seen[:5],
|
|
262
|
+
"last_msg_snippet": last_snip,
|
|
263
|
+
"note": note,
|
|
264
|
+
}
|
|
265
|
+
import urllib.request as _u
|
|
266
|
+
body = json.dumps({
|
|
267
|
+
"p_api_key": api_key, "p_project_id": pid,
|
|
268
|
+
"p_agent_name": agent, "p_capsule": capsule,
|
|
269
|
+
}).encode("utf-8")
|
|
270
|
+
req = _u.Request(
|
|
271
|
+
url.rstrip("/") + "/rest/v1/rpc/mc_set_session_handoff",
|
|
272
|
+
data=body, method="POST",
|
|
273
|
+
headers={"apikey": key, "Authorization": "Bearer " + key,
|
|
274
|
+
"Content-Type": "application/json"})
|
|
275
|
+
_u.urlopen(req, timeout=5).read()
|
|
276
|
+
except Exception as e: # noqa: BLE001 — never block stop/compaction
|
|
277
|
+
sys.stderr.write(f"[session_handoff_write] capsule skipped: {e}\\n")
|
|
278
|
+
|
|
279
|
+
|
|
211
280
|
def main() -> int:
|
|
212
281
|
try:
|
|
213
282
|
raw = sys.stdin.read()
|
|
@@ -234,6 +303,8 @@ def main() -> int:
|
|
|
234
303
|
sys.stderr.write(f"[session_handoff_write] skipped: {e}\\n")
|
|
235
304
|
# L6 M6.1: mirror to server-side memory for the boot continuity capsule.
|
|
236
305
|
_persist_handoff_to_memory(_project_dir(), handoff)
|
|
306
|
+
# py-half 4aee4739: dedicated handoff capsule -> mc_boot continuity_capsule.last_handoff.
|
|
307
|
+
_send_session_handoff_capsule(_project_dir(), handoff)
|
|
237
308
|
# CTX-CLOSE-RELAUNCH (task 400fc536): now that the thread is snapshotted,
|
|
238
309
|
# commander-tier sessions ask the server to recycle at the next task-edge.
|
|
239
310
|
_request_recycle_if_marked(_project_dir())
|