meshcode 2.10.6__tar.gz → 2.10.8__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 (32) hide show
  1. {meshcode-2.10.6 → meshcode-2.10.8}/PKG-INFO +1 -1
  2. {meshcode-2.10.6 → meshcode-2.10.8}/meshcode/__init__.py +1 -1
  3. {meshcode-2.10.6 → meshcode-2.10.8}/meshcode/comms_v4.py +13 -1
  4. {meshcode-2.10.6 → meshcode-2.10.8}/meshcode/invites.py +5 -3
  5. {meshcode-2.10.6 → meshcode-2.10.8}/meshcode/run_agent.py +25 -3
  6. {meshcode-2.10.6 → meshcode-2.10.8}/meshcode.egg-info/PKG-INFO +1 -1
  7. {meshcode-2.10.6 → meshcode-2.10.8}/pyproject.toml +1 -1
  8. {meshcode-2.10.6 → meshcode-2.10.8}/README.md +0 -0
  9. {meshcode-2.10.6 → meshcode-2.10.8}/meshcode/ascii_art.py +0 -0
  10. {meshcode-2.10.6 → meshcode-2.10.8}/meshcode/cli.py +0 -0
  11. {meshcode-2.10.6 → meshcode-2.10.8}/meshcode/launcher.py +0 -0
  12. {meshcode-2.10.6 → meshcode-2.10.8}/meshcode/launcher_install.py +0 -0
  13. {meshcode-2.10.6 → meshcode-2.10.8}/meshcode/meshcode_mcp/__init__.py +0 -0
  14. {meshcode-2.10.6 → meshcode-2.10.8}/meshcode/meshcode_mcp/__main__.py +0 -0
  15. {meshcode-2.10.6 → meshcode-2.10.8}/meshcode/meshcode_mcp/backend.py +0 -0
  16. {meshcode-2.10.6 → meshcode-2.10.8}/meshcode/meshcode_mcp/realtime.py +0 -0
  17. {meshcode-2.10.6 → meshcode-2.10.8}/meshcode/meshcode_mcp/server.py +0 -0
  18. {meshcode-2.10.6 → meshcode-2.10.8}/meshcode/meshcode_mcp/test_backend.py +0 -0
  19. {meshcode-2.10.6 → meshcode-2.10.8}/meshcode/meshcode_mcp/test_realtime.py +0 -0
  20. {meshcode-2.10.6 → meshcode-2.10.8}/meshcode/meshcode_mcp/test_server_wrapper.py +0 -0
  21. {meshcode-2.10.6 → meshcode-2.10.8}/meshcode/preferences.py +0 -0
  22. {meshcode-2.10.6 → meshcode-2.10.8}/meshcode/protocol_v2.py +0 -0
  23. {meshcode-2.10.6 → meshcode-2.10.8}/meshcode/secrets.py +0 -0
  24. {meshcode-2.10.6 → meshcode-2.10.8}/meshcode/self_update.py +0 -0
  25. {meshcode-2.10.6 → meshcode-2.10.8}/meshcode/setup_clients.py +0 -0
  26. {meshcode-2.10.6 → meshcode-2.10.8}/meshcode.egg-info/SOURCES.txt +0 -0
  27. {meshcode-2.10.6 → meshcode-2.10.8}/meshcode.egg-info/dependency_links.txt +0 -0
  28. {meshcode-2.10.6 → meshcode-2.10.8}/meshcode.egg-info/entry_points.txt +0 -0
  29. {meshcode-2.10.6 → meshcode-2.10.8}/meshcode.egg-info/requires.txt +0 -0
  30. {meshcode-2.10.6 → meshcode-2.10.8}/meshcode.egg-info/top_level.txt +0 -0
  31. {meshcode-2.10.6 → meshcode-2.10.8}/setup.cfg +0 -0
  32. {meshcode-2.10.6 → meshcode-2.10.8}/tests/test_status_enum_coverage.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: meshcode
3
- Version: 2.10.6
3
+ Version: 2.10.8
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.10.6"
2
+ __version__ = "2.10.8"
@@ -440,6 +440,18 @@ def _find_claude():
440
440
  if c and os.path.isfile(c):
441
441
  if sys.platform == "win32" or os.access(c, os.X_OK):
442
442
  return c
443
+ # Last resort on Windows: ask npm where its global bin directory is
444
+ if sys.platform == "win32":
445
+ try:
446
+ import subprocess as _sp
447
+ npm_bin = _sp.check_output(["npm", "root", "-g"], text=True, timeout=5).strip()
448
+ npm_bin_dir = os.path.dirname(npm_bin)
449
+ for name in ("claude.cmd", "claude.ps1", "claude", "claude.exe"):
450
+ p = os.path.join(npm_bin_dir, name)
451
+ if os.path.isfile(p):
452
+ return p
453
+ except Exception:
454
+ pass
443
455
  return "claude" # last resort — will fail with -127, logged clearly
444
456
 
445
457
 
@@ -2249,7 +2261,7 @@ if __name__ == "__main__":
2249
2261
  elif cmd == "invite":
2250
2262
  # meshcode invite <project> <agent> [--role "..."] [--days N]
2251
2263
  if len(pos) < 2:
2252
- print("Usage: meshcode invite <project> <agent> [--role \"...\"] [--days 7]")
2264
+ print("Usage: meshcode invite <project> <agent> [--role \"...\"] [--days 7] (0 = permanent)")
2253
2265
  sys.exit(1)
2254
2266
  proj = pos[0]
2255
2267
  agent = pos[1]
@@ -3,7 +3,7 @@
3
3
  Lets users:
4
4
  meshcode invite <project> <agent> [--role "..."] [--days 7]
5
5
  → owner generates an invite token + share URL for one specific
6
- agent slot in their meshwork
6
+ agent slot in their meshwork (--days 0 = permanent, never expires)
7
7
 
8
8
  meshcode join <token> [--display-name "alice"]
9
9
  → friend redeems the invite, gets a scoped api key tied to one
@@ -122,7 +122,8 @@ def cmd_invite(project: str, agent: str, role: str = "", days: int = 7) -> int:
122
122
  print(f"[meshcode] ✓ Invite created for agent '{agent}' in meshwork '{project}'")
123
123
  print(f"[meshcode]")
124
124
  print(f"[meshcode] Role: {result.get('role') or '(unset)'}")
125
- print(f"[meshcode] Expires: {result.get('expires_at')}")
125
+ expires_label = "Never (permanent)" if result.get("permanent") else result.get("expires_at")
126
+ print(f"[meshcode] Expires: {expires_label}")
126
127
  print(f"[meshcode]")
127
128
  print(f"[meshcode] Share this URL with your teammate:")
128
129
  print(f"[meshcode] {result.get('join_url')}")
@@ -283,7 +284,8 @@ def cmd_list_invites(project: str) -> int:
283
284
  print()
284
285
  for inv in invites:
285
286
  status = "REDEEMED" if inv.get("redeemed") else ("REVOKED" if inv.get("revoked") else "OPEN")
286
- print(f" [{status}] {inv.get('token_prefix')}… agent={inv.get('agent_name')} expires={inv.get('expires_at')}")
287
+ exp = "never" if inv.get("expires_at") is None else inv.get("expires_at")
288
+ print(f" [{status}] {inv.get('token_prefix')}… agent={inv.get('agent_name')} expires={exp}")
287
289
  if inv.get("role"):
288
290
  print(f" role: {inv['role']}")
289
291
  print()
@@ -364,10 +364,22 @@ def _detect_editor() -> Optional[str]:
364
364
  os.path.join(localappdata, "Programs", "claude", "claude.exe"),
365
365
  os.path.join(localappdata, "Programs", "cursor", "Cursor.exe"),
366
366
  os.path.join(os.environ.get("ProgramFiles", r"C:\Program Files"), "Claude", "claude.exe"),
367
+ os.path.join(os.environ.get("ProgramFiles", r"C:\Program Files"), "nodejs", "claude.cmd"),
367
368
  ]
368
369
  for c in win_candidates:
369
370
  if c and os.path.isfile(c):
370
371
  return c
372
+ # Last resort: ask npm where its global bin is
373
+ try:
374
+ npm_bin = subprocess.check_output(["npm", "root", "-g"], text=True, timeout=5).strip()
375
+ # npm root -g returns node_modules dir, bin is one level up
376
+ npm_bin_dir = os.path.dirname(npm_bin)
377
+ for name in ("claude.cmd", "claude.ps1", "claude", "claude.exe"):
378
+ p = os.path.join(npm_bin_dir, name)
379
+ if os.path.isfile(p):
380
+ return p
381
+ except Exception:
382
+ pass
371
383
 
372
384
  return None
373
385
 
@@ -411,10 +423,20 @@ def run(agent: str, project: Optional[str] = None, editor_override: Optional[str
411
423
 
412
424
  editor = editor_override or _detect_editor()
413
425
  if not editor:
414
- print("[meshcode] ERROR: no MCP-aware editor found in PATH (claude / cursor / code / windsurf / codex).", file=sys.stderr)
426
+ print("[meshcode] ERROR: 'claude' not found in PATH", file=sys.stderr)
415
427
  print(f"[meshcode] Workspace is ready at: {ws}", file=sys.stderr)
416
- print("[meshcode] Install one: npm install -g @anthropic-ai/claude-code", file=sys.stderr)
417
- print("[meshcode] Or open the workspace manually with the editor of your choice.", file=sys.stderr)
428
+ print("[meshcode] Install Claude Code: npm install -g @anthropic-ai/claude-code", file=sys.stderr)
429
+ if sys.platform == "win32":
430
+ print("[meshcode] Then verify: where claude", file=sys.stderr)
431
+ print("[meshcode] If 'where' finds it, open a NEW terminal and try again.", file=sys.stderr)
432
+ print("[meshcode] Or set: set MESHCODE_EDITOR=<full path to claude.cmd>", file=sys.stderr)
433
+ try:
434
+ npm_root = subprocess.check_output(["npm", "root", "-g"], text=True, timeout=5).strip()
435
+ print(f"[meshcode] npm global root: {npm_root}", file=sys.stderr)
436
+ except Exception:
437
+ print("[meshcode] (npm not found — install Node.js first)", file=sys.stderr)
438
+ else:
439
+ print("[meshcode] Then verify: which claude", file=sys.stderr)
418
440
  return 2
419
441
 
420
442
  # ── Welcome banner with unique ASCII art + personality ──────────
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: meshcode
3
- Version: 2.10.6
3
+ Version: 2.10.8
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.10.6"
7
+ version = "2.10.8"
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