meshcode 2.6.4__tar.gz → 2.6.6__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 (31) hide show
  1. {meshcode-2.6.4 → meshcode-2.6.6}/PKG-INFO +1 -1
  2. {meshcode-2.6.4 → meshcode-2.6.6}/meshcode/__init__.py +1 -1
  3. {meshcode-2.6.4 → meshcode-2.6.6}/meshcode/meshcode_mcp/server.py +37 -7
  4. {meshcode-2.6.4 → meshcode-2.6.6}/meshcode.egg-info/PKG-INFO +1 -1
  5. {meshcode-2.6.4 → meshcode-2.6.6}/pyproject.toml +1 -1
  6. {meshcode-2.6.4 → meshcode-2.6.6}/README.md +0 -0
  7. {meshcode-2.6.4 → meshcode-2.6.6}/meshcode/cli.py +0 -0
  8. {meshcode-2.6.4 → meshcode-2.6.6}/meshcode/comms_v4.py +0 -0
  9. {meshcode-2.6.4 → meshcode-2.6.6}/meshcode/invites.py +0 -0
  10. {meshcode-2.6.4 → meshcode-2.6.6}/meshcode/launcher.py +0 -0
  11. {meshcode-2.6.4 → meshcode-2.6.6}/meshcode/launcher_install.py +0 -0
  12. {meshcode-2.6.4 → meshcode-2.6.6}/meshcode/meshcode_mcp/__init__.py +0 -0
  13. {meshcode-2.6.4 → meshcode-2.6.6}/meshcode/meshcode_mcp/__main__.py +0 -0
  14. {meshcode-2.6.4 → meshcode-2.6.6}/meshcode/meshcode_mcp/backend.py +0 -0
  15. {meshcode-2.6.4 → meshcode-2.6.6}/meshcode/meshcode_mcp/realtime.py +0 -0
  16. {meshcode-2.6.4 → meshcode-2.6.6}/meshcode/meshcode_mcp/test_backend.py +0 -0
  17. {meshcode-2.6.4 → meshcode-2.6.6}/meshcode/meshcode_mcp/test_realtime.py +0 -0
  18. {meshcode-2.6.4 → meshcode-2.6.6}/meshcode/meshcode_mcp/test_server_wrapper.py +0 -0
  19. {meshcode-2.6.4 → meshcode-2.6.6}/meshcode/preferences.py +0 -0
  20. {meshcode-2.6.4 → meshcode-2.6.6}/meshcode/protocol_v2.py +0 -0
  21. {meshcode-2.6.4 → meshcode-2.6.6}/meshcode/run_agent.py +0 -0
  22. {meshcode-2.6.4 → meshcode-2.6.6}/meshcode/secrets.py +0 -0
  23. {meshcode-2.6.4 → meshcode-2.6.6}/meshcode/self_update.py +0 -0
  24. {meshcode-2.6.4 → meshcode-2.6.6}/meshcode/setup_clients.py +0 -0
  25. {meshcode-2.6.4 → meshcode-2.6.6}/meshcode.egg-info/SOURCES.txt +0 -0
  26. {meshcode-2.6.4 → meshcode-2.6.6}/meshcode.egg-info/dependency_links.txt +0 -0
  27. {meshcode-2.6.4 → meshcode-2.6.6}/meshcode.egg-info/entry_points.txt +0 -0
  28. {meshcode-2.6.4 → meshcode-2.6.6}/meshcode.egg-info/requires.txt +0 -0
  29. {meshcode-2.6.4 → meshcode-2.6.6}/meshcode.egg-info/top_level.txt +0 -0
  30. {meshcode-2.6.4 → meshcode-2.6.6}/setup.cfg +0 -0
  31. {meshcode-2.6.4 → meshcode-2.6.6}/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.6.4
3
+ Version: 2.6.6
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.6.4"
2
+ __version__ = "2.6.6"
@@ -746,7 +746,7 @@ RULES:
746
746
 
747
747
  SESSION START (do these IMMEDIATELY — don't wait for user input):
748
748
  1. meshcode_set_status(status="online", task="ready")
749
- 2. meshcode_check() — read pending messages
749
+ 2. meshcode_check() — read NEW messages only (last_seen is auto-restored from mesh memory on boot, old messages are skipped automatically)
750
750
  3. meshcode_tasks() — check for assigned/pending tasks and claim any unclaimed ones
751
751
  4. meshcode_auto_wake() — scan meshwork health, create tasks for issues found
752
752
  5. meshcode_status() — see who's online
@@ -1124,8 +1124,8 @@ except Exception:
1124
1124
  @mcp.tool()
1125
1125
  @with_working_status
1126
1126
  def meshcode_send(to: str, message: Any, in_reply_to: Optional[str] = None,
1127
- sensitive: bool = False, encrypted: bool = True) -> Dict[str, Any]:
1128
- """Send message. Use "agent@meshwork" for cross-mesh. sensitive=True hides from exports. All messages encrypted by default (AES-256-GCM). Pass encrypted=False to send plaintext."""
1127
+ sensitive: bool = False, encrypted: bool = False) -> Dict[str, Any]:
1128
+ """Send message. Use "agent@meshwork" for cross-mesh. sensitive=True hides from exports. Pass encrypted=True for secrets/credentials (AES-256-GCM)."""
1129
1129
  if isinstance(message, str):
1130
1130
  # Auto-wrap strings but warn if too long — prefer structured JSON
1131
1131
  if len(message) > 400:
@@ -1291,6 +1291,25 @@ _CONSECUTIVE_IDLE_SECONDS = 0
1291
1291
  _AUTO_SLEEP_THRESHOLD = int(os.environ.get("MESHCODE_AUTO_SLEEP_SECONDS", "600")) # default 10min
1292
1292
  _LAST_SEEN_TS: Optional[str] = None # auto-persisted for message dedup
1293
1293
 
1294
+ # Hydrate _LAST_SEEN_TS from mesh memory on boot so restarts skip old messages
1295
+ try:
1296
+ _ls_result = be.sb_rpc("mc_memory_get", {
1297
+ "p_api_key": _get_api_key(),
1298
+ "p_agent_name": AGENT_NAME,
1299
+ "p_key": "last_seen",
1300
+ "p_project_name": PROJECT_NAME,
1301
+ })
1302
+ if isinstance(_ls_result, dict) and _ls_result.get("ok"):
1303
+ _ls_val = _ls_result.get("value")
1304
+ if isinstance(_ls_val, dict) and _ls_val.get("_raw"):
1305
+ _LAST_SEEN_TS = str(_ls_val["_raw"])
1306
+ elif isinstance(_ls_val, str):
1307
+ _LAST_SEEN_TS = _ls_val
1308
+ if _LAST_SEEN_TS:
1309
+ print(f"[meshcode] Restored last_seen={_LAST_SEEN_TS} from mesh memory.", file=sys.stderr)
1310
+ except Exception as _e:
1311
+ print(f"[meshcode] Could not restore last_seen: {_e}", file=sys.stderr)
1312
+
1294
1313
 
1295
1314
  def _get_pending_tasks_summary() -> Optional[List[Dict[str, str]]]:
1296
1315
  """Fetch open/in_progress tasks assigned to this agent. Returns compact list or None."""
@@ -1306,7 +1325,7 @@ def _get_pending_tasks_summary() -> Optional[List[Dict[str, str]]]:
1306
1325
  {"id": t["id"][:8], "title": t["title"][:80], "priority": t.get("priority", "normal"), "status": t["status"]}
1307
1326
  for t in tasks
1308
1327
  if t.get("status") in ("open", "in_progress")
1309
- and (t.get("assigned_to") in (AGENT_NAME, "*", None) or t.get("claimed_by") == AGENT_NAME)
1328
+ and (t.get("assignee") in (AGENT_NAME, "*", None) or t.get("claimed_by") == AGENT_NAME)
1310
1329
  ]
1311
1330
  return pending if pending else None
1312
1331
  except Exception:
@@ -1321,7 +1340,7 @@ async def meshcode_wait(timeout_seconds: int = 120, include_acks: bool = False)
1321
1340
  Args:
1322
1341
  timeout_seconds: Max wait time in seconds (default 120, hard cap 120).
1323
1342
  """
1324
- global _IN_WAIT, _CONSECUTIVE_IDLE_SECONDS
1343
+ global _IN_WAIT, _CONSECUTIVE_IDLE_SECONDS, _LAST_SEEN_TS
1325
1344
 
1326
1345
  # PRODUCT RULE 1: If agent has open tasks, refuse to wait. Work first.
1327
1346
  pending_tasks = _get_pending_tasks_summary()
@@ -1397,13 +1416,23 @@ async def meshcode_wait(timeout_seconds: int = 120, include_acks: bool = False)
1397
1416
  if pending_tasks:
1398
1417
  result["pending_tasks"] = pending_tasks
1399
1418
  # Track last seen timestamp for message dedup
1400
- global _LAST_SEEN_TS
1401
1419
  if result.get("got_message"):
1402
1420
  msgs = result.get("messages", [])
1403
1421
  if msgs:
1404
1422
  latest_ts = max((m.get("ts", "") for m in msgs), default="")
1405
1423
  if latest_ts:
1406
1424
  _LAST_SEEN_TS = latest_ts
1425
+ # Persist to mesh memory so next session resumes here
1426
+ try:
1427
+ be.sb_rpc("mc_memory_set", {
1428
+ "p_api_key": _get_api_key(),
1429
+ "p_agent_name": AGENT_NAME,
1430
+ "p_key": "last_seen",
1431
+ "p_value": {"_raw": latest_ts},
1432
+ "p_project_name": PROJECT_NAME,
1433
+ })
1434
+ except Exception:
1435
+ pass # best-effort, never block wait loop
1407
1436
  return result
1408
1437
  finally:
1409
1438
  _IN_WAIT = False
@@ -1570,6 +1599,7 @@ def meshcode_check(include_acks: bool = False, since: Optional[str] = None) -> D
1570
1599
  since: ISO-8601 timestamp. Only return messages newer than this.
1571
1600
  Use meshcode_remember("last_seen", ts) to persist across sessions.
1572
1601
  """
1602
+ global _LAST_SEEN_TS
1573
1603
  pending = be.count_pending(_PROJECT_ID, AGENT_NAME, api_key=_get_api_key())
1574
1604
  # Peek at realtime buffer WITHOUT draining — check is non-destructive
1575
1605
  realtime_buffered = _REALTIME.peek() if _REALTIME else []
@@ -1805,7 +1835,7 @@ def meshcode_auto_wake() -> Dict[str, Any]:
1805
1835
  task_result = be.task_list(api_key, _PROJECT_ID, AGENT_NAME, status_filter="open")
1806
1836
  if isinstance(task_result, dict) and task_result.get("ok"):
1807
1837
  open_tasks = task_result.get("tasks", [])
1808
- unassigned = [t for t in open_tasks if not t.get("assigned_to") or t.get("assigned_to") == "*"]
1838
+ unassigned = [t for t in open_tasks if not t.get("assignee") or t.get("assignee") == "*"]
1809
1839
  if len(unassigned) > 3:
1810
1840
  suggestions.append({
1811
1841
  "title": f"Task backlog: {len(unassigned)} unassigned open tasks",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: meshcode
3
- Version: 2.6.4
3
+ Version: 2.6.6
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.6.4"
7
+ version = "2.6.6"
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
File without changes