meshcode 2.10.5__tar.gz → 2.10.7__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.5 → meshcode-2.10.7}/PKG-INFO +1 -1
  2. {meshcode-2.10.5 → meshcode-2.10.7}/meshcode/__init__.py +1 -1
  3. {meshcode-2.10.5 → meshcode-2.10.7}/meshcode/comms_v4.py +29 -13
  4. {meshcode-2.10.5 → meshcode-2.10.7}/meshcode/invites.py +5 -3
  5. {meshcode-2.10.5 → meshcode-2.10.7}/meshcode/run_agent.py +16 -0
  6. {meshcode-2.10.5 → meshcode-2.10.7}/meshcode.egg-info/PKG-INFO +1 -1
  7. {meshcode-2.10.5 → meshcode-2.10.7}/pyproject.toml +1 -1
  8. {meshcode-2.10.5 → meshcode-2.10.7}/README.md +0 -0
  9. {meshcode-2.10.5 → meshcode-2.10.7}/meshcode/ascii_art.py +0 -0
  10. {meshcode-2.10.5 → meshcode-2.10.7}/meshcode/cli.py +0 -0
  11. {meshcode-2.10.5 → meshcode-2.10.7}/meshcode/launcher.py +0 -0
  12. {meshcode-2.10.5 → meshcode-2.10.7}/meshcode/launcher_install.py +0 -0
  13. {meshcode-2.10.5 → meshcode-2.10.7}/meshcode/meshcode_mcp/__init__.py +0 -0
  14. {meshcode-2.10.5 → meshcode-2.10.7}/meshcode/meshcode_mcp/__main__.py +0 -0
  15. {meshcode-2.10.5 → meshcode-2.10.7}/meshcode/meshcode_mcp/backend.py +0 -0
  16. {meshcode-2.10.5 → meshcode-2.10.7}/meshcode/meshcode_mcp/realtime.py +0 -0
  17. {meshcode-2.10.5 → meshcode-2.10.7}/meshcode/meshcode_mcp/server.py +0 -0
  18. {meshcode-2.10.5 → meshcode-2.10.7}/meshcode/meshcode_mcp/test_backend.py +0 -0
  19. {meshcode-2.10.5 → meshcode-2.10.7}/meshcode/meshcode_mcp/test_realtime.py +0 -0
  20. {meshcode-2.10.5 → meshcode-2.10.7}/meshcode/meshcode_mcp/test_server_wrapper.py +0 -0
  21. {meshcode-2.10.5 → meshcode-2.10.7}/meshcode/preferences.py +0 -0
  22. {meshcode-2.10.5 → meshcode-2.10.7}/meshcode/protocol_v2.py +0 -0
  23. {meshcode-2.10.5 → meshcode-2.10.7}/meshcode/secrets.py +0 -0
  24. {meshcode-2.10.5 → meshcode-2.10.7}/meshcode/self_update.py +0 -0
  25. {meshcode-2.10.5 → meshcode-2.10.7}/meshcode/setup_clients.py +0 -0
  26. {meshcode-2.10.5 → meshcode-2.10.7}/meshcode.egg-info/SOURCES.txt +0 -0
  27. {meshcode-2.10.5 → meshcode-2.10.7}/meshcode.egg-info/dependency_links.txt +0 -0
  28. {meshcode-2.10.5 → meshcode-2.10.7}/meshcode.egg-info/entry_points.txt +0 -0
  29. {meshcode-2.10.5 → meshcode-2.10.7}/meshcode.egg-info/requires.txt +0 -0
  30. {meshcode-2.10.5 → meshcode-2.10.7}/meshcode.egg-info/top_level.txt +0 -0
  31. {meshcode-2.10.5 → meshcode-2.10.7}/setup.cfg +0 -0
  32. {meshcode-2.10.5 → meshcode-2.10.7}/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.5
3
+ Version: 2.10.7
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.5"
2
+ __version__ = "2.10.7"
@@ -407,23 +407,39 @@ _ACTIONABLE_FIELDS = {"task", "ask", "q", "question", "need", "request", "please
407
407
 
408
408
  def _find_claude():
409
409
  """Locate the claude CLI binary. PATH lookup first, then common install
410
- locations. Critical for daemons (launchd/systemd) which run with stripped
411
- PATH and won't find claude via plain `claude` invocation."""
410
+ locations. Critical for daemons (launchd/systemd/Windows services) which
411
+ run with stripped PATH and won't find claude via plain `claude` invocation."""
412
412
  import shutil as _sh
413
413
  p = _sh.which("claude")
414
414
  if p:
415
415
  return p
416
- candidates = [
417
- "/opt/homebrew/bin/claude",
418
- "/usr/local/bin/claude",
419
- os.path.expanduser("~/.local/bin/claude"),
420
- os.path.expanduser("~/anaconda3/bin/claude"),
421
- "/opt/anaconda3/bin/claude",
422
- "/Applications/Claude Code.app/Contents/MacOS/claude",
423
- ]
416
+ if sys.platform == "win32":
417
+ # Windows: npm global installs, AppData locations, Program Files
418
+ appdata = os.environ.get("APPDATA", "")
419
+ localappdata = os.environ.get("LOCALAPPDATA", "")
420
+ userprofile = os.environ.get("USERPROFILE", "")
421
+ candidates = [
422
+ os.path.join(appdata, "npm", "claude.cmd"),
423
+ os.path.join(appdata, "npm", "claude"),
424
+ os.path.join(localappdata, "Programs", "claude", "claude.exe"),
425
+ os.path.join(localappdata, "Microsoft", "WinGet", "Packages", "Anthropic.Claude", "claude.exe"),
426
+ os.path.join(userprofile, "AppData", "Local", "npm-cache", "_npx", "claude.cmd"),
427
+ os.path.join(os.environ.get("ProgramFiles", r"C:\Program Files"), "nodejs", "claude.cmd"),
428
+ os.path.join(os.environ.get("ProgramFiles", r"C:\Program Files"), "Claude", "claude.exe"),
429
+ ]
430
+ else:
431
+ candidates = [
432
+ "/opt/homebrew/bin/claude",
433
+ "/usr/local/bin/claude",
434
+ os.path.expanduser("~/.local/bin/claude"),
435
+ os.path.expanduser("~/anaconda3/bin/claude"),
436
+ "/opt/anaconda3/bin/claude",
437
+ "/Applications/Claude Code.app/Contents/MacOS/claude",
438
+ ]
424
439
  for c in candidates:
425
- if os.path.isfile(c) and os.access(c, os.X_OK):
426
- return c
440
+ if c and os.path.isfile(c):
441
+ if sys.platform == "win32" or os.access(c, os.X_OK):
442
+ return c
427
443
  return "claude" # last resort — will fail with -127, logged clearly
428
444
 
429
445
 
@@ -2233,7 +2249,7 @@ if __name__ == "__main__":
2233
2249
  elif cmd == "invite":
2234
2250
  # meshcode invite <project> <agent> [--role "..."] [--days N]
2235
2251
  if len(pos) < 2:
2236
- print("Usage: meshcode invite <project> <agent> [--role \"...\"] [--days 7]")
2252
+ print("Usage: meshcode invite <project> <agent> [--role \"...\"] [--days 7] (0 = permanent)")
2237
2253
  sys.exit(1)
2238
2254
  proj = pos[0]
2239
2255
  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()
@@ -353,6 +353,22 @@ def _detect_editor() -> Optional[str]:
353
353
  for cmd in ("claude", "cursor", "code", "windsurf", "codex"):
354
354
  if shutil.which(cmd):
355
355
  return cmd
356
+
357
+ # Windows fallback: check common install locations not in PATH
358
+ if sys.platform == "win32":
359
+ appdata = os.environ.get("APPDATA", "")
360
+ localappdata = os.environ.get("LOCALAPPDATA", "")
361
+ win_candidates = [
362
+ os.path.join(appdata, "npm", "claude.cmd"),
363
+ os.path.join(appdata, "npm", "claude"),
364
+ os.path.join(localappdata, "Programs", "claude", "claude.exe"),
365
+ os.path.join(localappdata, "Programs", "cursor", "Cursor.exe"),
366
+ os.path.join(os.environ.get("ProgramFiles", r"C:\Program Files"), "Claude", "claude.exe"),
367
+ ]
368
+ for c in win_candidates:
369
+ if c and os.path.isfile(c):
370
+ return c
371
+
356
372
  return None
357
373
 
358
374
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: meshcode
3
- Version: 2.10.5
3
+ Version: 2.10.7
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.5"
7
+ version = "2.10.7"
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