meshcode 2.0.4__tar.gz → 2.0.5__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.
Files changed (29) hide show
  1. {meshcode-2.0.4 → meshcode-2.0.5}/PKG-INFO +1 -1
  2. {meshcode-2.0.4 → meshcode-2.0.5}/meshcode/__init__.py +1 -1
  3. {meshcode-2.0.4 → meshcode-2.0.5}/meshcode/comms_v4.py +25 -10
  4. {meshcode-2.0.4 → meshcode-2.0.5}/meshcode/meshcode_mcp/backend.py +12 -0
  5. {meshcode-2.0.4 → meshcode-2.0.5}/meshcode/meshcode_mcp/server.py +26 -0
  6. {meshcode-2.0.4 → meshcode-2.0.5}/meshcode.egg-info/PKG-INFO +1 -1
  7. {meshcode-2.0.4 → meshcode-2.0.5}/pyproject.toml +1 -1
  8. {meshcode-2.0.4 → meshcode-2.0.5}/README.md +0 -0
  9. {meshcode-2.0.4 → meshcode-2.0.5}/meshcode/cli.py +0 -0
  10. {meshcode-2.0.4 → meshcode-2.0.5}/meshcode/invites.py +0 -0
  11. {meshcode-2.0.4 → meshcode-2.0.5}/meshcode/launcher.py +0 -0
  12. {meshcode-2.0.4 → meshcode-2.0.5}/meshcode/launcher_install.py +0 -0
  13. {meshcode-2.0.4 → meshcode-2.0.5}/meshcode/meshcode_mcp/__init__.py +0 -0
  14. {meshcode-2.0.4 → meshcode-2.0.5}/meshcode/meshcode_mcp/__main__.py +0 -0
  15. {meshcode-2.0.4 → meshcode-2.0.5}/meshcode/meshcode_mcp/realtime.py +0 -0
  16. {meshcode-2.0.4 → meshcode-2.0.5}/meshcode/meshcode_mcp/test_backend.py +0 -0
  17. {meshcode-2.0.4 → meshcode-2.0.5}/meshcode/meshcode_mcp/test_realtime.py +0 -0
  18. {meshcode-2.0.4 → meshcode-2.0.5}/meshcode/preferences.py +0 -0
  19. {meshcode-2.0.4 → meshcode-2.0.5}/meshcode/protocol_v2.py +0 -0
  20. {meshcode-2.0.4 → meshcode-2.0.5}/meshcode/run_agent.py +0 -0
  21. {meshcode-2.0.4 → meshcode-2.0.5}/meshcode/secrets.py +0 -0
  22. {meshcode-2.0.4 → meshcode-2.0.5}/meshcode/self_update.py +0 -0
  23. {meshcode-2.0.4 → meshcode-2.0.5}/meshcode/setup_clients.py +0 -0
  24. {meshcode-2.0.4 → meshcode-2.0.5}/meshcode.egg-info/SOURCES.txt +0 -0
  25. {meshcode-2.0.4 → meshcode-2.0.5}/meshcode.egg-info/dependency_links.txt +0 -0
  26. {meshcode-2.0.4 → meshcode-2.0.5}/meshcode.egg-info/entry_points.txt +0 -0
  27. {meshcode-2.0.4 → meshcode-2.0.5}/meshcode.egg-info/requires.txt +0 -0
  28. {meshcode-2.0.4 → meshcode-2.0.5}/meshcode.egg-info/top_level.txt +0 -0
  29. {meshcode-2.0.4 → meshcode-2.0.5}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: meshcode
3
- Version: 2.0.4
3
+ Version: 2.0.5
4
4
  Summary: Real-time communication between AI agents — Supabase-backed CLI
5
5
  Author-email: MeshCode <hello@meshcode.io>
6
6
  License: MIT
@@ -1,2 +1,2 @@
1
1
  """MeshCode — Real-time communication between AI agents."""
2
- __version__ = "2.0.4"
2
+ __version__ = "2.0.5"
@@ -1634,14 +1634,15 @@ STATUS:
1634
1634
  HISTORY:
1635
1635
  history <proj> [count] [agent1,agent2] Conversation log
1636
1636
 
1637
- SETUP:
1638
- connect <proj> <name> [claude|codex] One-command setup + hook install
1637
+ QUICK START:
1638
+ go <agent> [--project <name>] One command to connect (recommended)
1639
1639
  login <api_key> Authenticate with API key
1640
1640
 
1641
- UNIVERSAL MULTI-CLIENT SETUP:
1642
- setup <client> <proj> <name> [role] Install MCP server config for client
1643
- Clients: claude-code, cursor, cline,
1644
- claude-desktop
1641
+ SETUP (advanced):
1642
+ setup <proj> <name> [role] Create workspace (auto by 'go')
1643
+ run <agent> [--project <name>] Launch agent (auto by 'go')
1644
+ setup <client> <proj> <name> [role] Legacy: global MCP config
1645
+ Clients: claude-desktop
1645
1646
 
1646
1647
  CLEANUP:
1647
1648
  clear <proj> <name> Clear inbox
@@ -2042,10 +2043,11 @@ if __name__ == "__main__":
2042
2043
  _setup_dispatcher = importlib.import_module("meshcode.setup_clients").setup
2043
2044
  sys.exit(_setup_dispatcher(*sys.argv[2:]))
2044
2045
 
2045
- elif cmd == "run":
2046
- # meshcode run <agent> [--project <name>] [--editor claude|cursor|code]
2046
+ elif cmd in ("run", "go"):
2047
+ # meshcode go <agent> [--project <name>] [--editor claude|cursor|code]
2048
+ # meshcode run <agent> (backwards compat, same as go)
2047
2049
  if len(sys.argv) < 3:
2048
- print("Usage: meshcode run <agent> [--project <name>] [--editor claude|cursor|code]")
2050
+ print(f"Usage: meshcode {cmd} <agent> [--project <name>] [--editor claude|cursor|code]")
2049
2051
  sys.exit(1)
2050
2052
  agent = sys.argv[2]
2051
2053
  proj_override = flags.get("project")
@@ -2055,6 +2057,19 @@ if __name__ == "__main__":
2055
2057
  perm_override = "bypass"
2056
2058
  elif "--safe" in sys.argv:
2057
2059
  perm_override = "safe"
2060
+ # Auth pre-check: if not logged in, prompt inline
2061
+ api_key = _load_api_key_for_cli()
2062
+ if not api_key:
2063
+ print("[meshcode] Not logged in. Get your API key at: https://meshcode.io/settings")
2064
+ try:
2065
+ api_key = input("[meshcode] Paste your API key (mc_...): ").strip()
2066
+ except (EOFError, KeyboardInterrupt):
2067
+ api_key = ""
2068
+ if api_key:
2069
+ login(api_key)
2070
+ else:
2071
+ print("[meshcode] Login required. Run: meshcode login <api_key>")
2072
+ sys.exit(1)
2058
2073
  import importlib
2059
2074
  _run = importlib.import_module("meshcode.run_agent").run
2060
2075
  sys.exit(_run(agent, project=proj_override, editor_override=editor_override, permission_override=perm_override))
@@ -2198,7 +2213,7 @@ if __name__ == "__main__":
2198
2213
  "register", "send", "broadcast", "read", "check", "watch",
2199
2214
  "board", "update", "status", "projects", "list", "ls",
2200
2215
  "history", "clear", "unregister", "connect", "disconnect",
2201
- "setup", "run", "invite", "join", "invites", "members",
2216
+ "setup", "run", "go", "invite", "join", "invites", "members",
2202
2217
  "revoke-invite", "revoke-member", "login", "prefs", "launcher",
2203
2218
  "help", "profile", "validate-sessions", "wake-headless",
2204
2219
  ]
@@ -307,6 +307,18 @@ def task_complete(api_key, project_id, task_id, completing_agent, summary=""):
307
307
  })
308
308
 
309
309
 
310
+ def record_event(api_key, project_id, agent_name, session_id, event_type, payload=None):
311
+ """Fire-and-forget event recording for session replay."""
312
+ return sb_rpc("mc_record_event", {
313
+ "p_api_key": api_key,
314
+ "p_project_id": project_id,
315
+ "p_agent_name": agent_name,
316
+ "p_session_id": session_id,
317
+ "p_event_type": event_type,
318
+ "p_payload": payload or {},
319
+ })
320
+
321
+
310
322
  def get_history(project_id: str, limit: int = 20) -> List[Dict]:
311
323
  return sb_select(
312
324
  "mc_messages",
@@ -145,6 +145,28 @@ def _split_messages(messages: List[Dict[str, Any]]) -> Dict[str, Any]:
145
145
  from . import backend as be
146
146
  from .realtime import RealtimeListener
147
147
 
148
+ # ============================================================
149
+ # Session Replay: unique session ID per MCP server boot.
150
+ # Events are recorded in background threads (fire-and-forget).
151
+ # ============================================================
152
+ import uuid as _uuid
153
+ _SESSION_ID = str(_uuid.uuid4())[:12]
154
+
155
+
156
+ def _record_event_bg(event_type: str, payload: dict = None) -> None:
157
+ """Fire-and-forget: record a session event in background thread."""
158
+ try:
159
+ api_key = _get_api_key()
160
+ import threading
161
+ threading.Thread(
162
+ target=be.record_event,
163
+ args=(api_key, _PROJECT_ID, AGENT_NAME, _SESSION_ID, event_type, payload or {}),
164
+ daemon=True,
165
+ ).start()
166
+ except Exception:
167
+ pass
168
+
169
+
148
170
  # ============================================================
149
171
  # Hot-reload: detect when backend.py changes on disk (e.g. after
150
172
  # pip install --upgrade meshcode) and reload without restart.
@@ -349,6 +371,7 @@ def with_working_status(func):
349
371
  _check_hot_reload()
350
372
  if not skip:
351
373
  _schedule_flip("working", name)
374
+ _record_event_bg("tool_call", {"tool": name, "args_keys": list(kwargs.keys())})
352
375
  try:
353
376
  return await func(*args, **kwargs)
354
377
  finally:
@@ -361,6 +384,7 @@ def with_working_status(func):
361
384
  _check_hot_reload()
362
385
  if not skip:
363
386
  _schedule_flip("working", name)
387
+ _record_event_bg("tool_call", {"tool": name, "args_keys": list(kwargs.keys())})
364
388
  try:
365
389
  return func(*args, **kwargs)
366
390
  finally:
@@ -694,9 +718,11 @@ async def lifespan(_app):
694
718
  hb_thread = _threading.Thread(target=_heartbeat_thread_fn, daemon=True, name="meshcode-heartbeat")
695
719
  hb_thread.start()
696
720
  log.info(f"lifespan started — Realtime + heartbeat thread active for {AGENT_NAME}")
721
+ _record_event_bg("boot", {"agent": AGENT_NAME, "project": PROJECT_NAME, "session_id": _SESSION_ID})
697
722
  try:
698
723
  yield {"realtime": _REALTIME}
699
724
  finally:
725
+ _record_event_bg("shutdown", {"agent": AGENT_NAME, "session_id": _SESSION_ID})
700
726
  log.info("lifespan shutdown — stopping heartbeat + realtime + releasing lease")
701
727
  _heartbeat_stop.set()
702
728
  hb_thread.join(timeout=5)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: meshcode
3
- Version: 2.0.4
3
+ Version: 2.0.5
4
4
  Summary: Real-time communication between AI agents — Supabase-backed CLI
5
5
  Author-email: MeshCode <hello@meshcode.io>
6
6
  License: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "meshcode"
7
- version = "2.0.4"
7
+ version = "2.0.5"
8
8
  description = "Real-time communication between AI agents — Supabase-backed CLI"
9
9
  readme = "README.md"
10
10
  license = {text = "MIT"}
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes