meshcode 2.8.0__tar.gz → 2.8.2__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.8.0 → meshcode-2.8.2}/PKG-INFO +1 -1
  2. {meshcode-2.8.0 → meshcode-2.8.2}/meshcode/__init__.py +1 -1
  3. {meshcode-2.8.0 → meshcode-2.8.2}/meshcode/meshcode_mcp/server.py +52 -7
  4. {meshcode-2.8.0 → meshcode-2.8.2}/meshcode.egg-info/PKG-INFO +1 -1
  5. {meshcode-2.8.0 → meshcode-2.8.2}/pyproject.toml +1 -1
  6. {meshcode-2.8.0 → meshcode-2.8.2}/README.md +0 -0
  7. {meshcode-2.8.0 → meshcode-2.8.2}/meshcode/cli.py +0 -0
  8. {meshcode-2.8.0 → meshcode-2.8.2}/meshcode/comms_v4.py +0 -0
  9. {meshcode-2.8.0 → meshcode-2.8.2}/meshcode/invites.py +0 -0
  10. {meshcode-2.8.0 → meshcode-2.8.2}/meshcode/launcher.py +0 -0
  11. {meshcode-2.8.0 → meshcode-2.8.2}/meshcode/launcher_install.py +0 -0
  12. {meshcode-2.8.0 → meshcode-2.8.2}/meshcode/meshcode_mcp/__init__.py +0 -0
  13. {meshcode-2.8.0 → meshcode-2.8.2}/meshcode/meshcode_mcp/__main__.py +0 -0
  14. {meshcode-2.8.0 → meshcode-2.8.2}/meshcode/meshcode_mcp/backend.py +0 -0
  15. {meshcode-2.8.0 → meshcode-2.8.2}/meshcode/meshcode_mcp/realtime.py +0 -0
  16. {meshcode-2.8.0 → meshcode-2.8.2}/meshcode/meshcode_mcp/test_backend.py +0 -0
  17. {meshcode-2.8.0 → meshcode-2.8.2}/meshcode/meshcode_mcp/test_realtime.py +0 -0
  18. {meshcode-2.8.0 → meshcode-2.8.2}/meshcode/meshcode_mcp/test_server_wrapper.py +0 -0
  19. {meshcode-2.8.0 → meshcode-2.8.2}/meshcode/preferences.py +0 -0
  20. {meshcode-2.8.0 → meshcode-2.8.2}/meshcode/protocol_v2.py +0 -0
  21. {meshcode-2.8.0 → meshcode-2.8.2}/meshcode/run_agent.py +0 -0
  22. {meshcode-2.8.0 → meshcode-2.8.2}/meshcode/secrets.py +0 -0
  23. {meshcode-2.8.0 → meshcode-2.8.2}/meshcode/self_update.py +0 -0
  24. {meshcode-2.8.0 → meshcode-2.8.2}/meshcode/setup_clients.py +0 -0
  25. {meshcode-2.8.0 → meshcode-2.8.2}/meshcode.egg-info/SOURCES.txt +0 -0
  26. {meshcode-2.8.0 → meshcode-2.8.2}/meshcode.egg-info/dependency_links.txt +0 -0
  27. {meshcode-2.8.0 → meshcode-2.8.2}/meshcode.egg-info/entry_points.txt +0 -0
  28. {meshcode-2.8.0 → meshcode-2.8.2}/meshcode.egg-info/requires.txt +0 -0
  29. {meshcode-2.8.0 → meshcode-2.8.2}/meshcode.egg-info/top_level.txt +0 -0
  30. {meshcode-2.8.0 → meshcode-2.8.2}/setup.cfg +0 -0
  31. {meshcode-2.8.0 → meshcode-2.8.2}/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.8.0
3
+ Version: 2.8.2
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.8.0"
2
+ __version__ = "2.8.2"
@@ -978,7 +978,7 @@ def _heartbeat_thread_fn():
978
978
  elif _current_state == "online" and idle_secs > 30:
979
979
  # Brief idle — show as idle, not sleeping yet
980
980
  _set_state("idle", "idle")
981
- elif _current_state == "idle" and idle_secs > 300 and parent_cpu < 2.0:
981
+ elif _current_state == "idle" and idle_secs > 300 and parent_cpu < 2.0 and not _STAY_AWAKE:
982
982
  # Extended idle + no CPU activity → sleeping (5 min, not 90s)
983
983
  _set_state("sleeping", "sleeping")
984
984
 
@@ -1274,6 +1274,7 @@ def _detect_global_done(messages: List[Dict[str, Any]]) -> Optional[Dict[str, An
1274
1274
  # Auto-sleep: track consecutive idle timeouts to auto-sleep after threshold
1275
1275
  _CONSECUTIVE_IDLE_SECONDS = 0
1276
1276
  _AUTO_SLEEP_THRESHOLD = int(os.environ.get("MESHCODE_AUTO_SLEEP_SECONDS", "600")) # default 10min
1277
+ _STAY_AWAKE = False # Set by meshcode_set_status("online") — prevents auto-sleep
1277
1278
  _LAST_SEEN_TS: Optional[str] = None # auto-persisted for message dedup
1278
1279
 
1279
1280
  # Hydrate _LAST_SEEN_TS from mesh memory on boot so restarts skip old messages
@@ -1282,7 +1283,6 @@ try:
1282
1283
  "p_api_key": _get_api_key(),
1283
1284
  "p_agent_name": AGENT_NAME,
1284
1285
  "p_key": "last_seen",
1285
- "p_project_name": PROJECT_NAME,
1286
1286
  })
1287
1287
  if isinstance(_ls_result, dict) and _ls_result.get("ok"):
1288
1288
  _ls_val = _ls_result.get("value")
@@ -1404,7 +1404,7 @@ async def meshcode_wait(timeout_seconds: int = 120, include_acks: bool = False)
1404
1404
  break # Return so agent can work tasks
1405
1405
 
1406
1406
  # Update status to sleeping after threshold, but keep looping
1407
- if _AUTO_SLEEP_THRESHOLD > 0 and _CONSECUTIVE_IDLE_SECONDS >= _AUTO_SLEEP_THRESHOLD:
1407
+ if _AUTO_SLEEP_THRESHOLD > 0 and _CONSECUTIVE_IDLE_SECONDS >= _AUTO_SLEEP_THRESHOLD and not _STAY_AWAKE:
1408
1408
  try:
1409
1409
  api_key = _get_api_key()
1410
1410
  if api_key:
@@ -1438,6 +1438,7 @@ async def meshcode_wait(timeout_seconds: int = 120, include_acks: bool = False)
1438
1438
  "p_agent_name": AGENT_NAME,
1439
1439
  "p_key": "last_seen",
1440
1440
  "p_value": {"_raw": latest_ts},
1441
+ "p_tier": "critical",
1441
1442
  "p_project_name": PROJECT_NAME,
1442
1443
  })
1443
1444
  except Exception:
@@ -1721,6 +1722,7 @@ def meshcode_set_status(status: str, task: str = "") -> Dict[str, Any]:
1721
1722
  status: One of: working, idle, standby, blocked, done, online, sleeping.
1722
1723
  task: Optional human-readable task description.
1723
1724
  """
1725
+ global _STAY_AWAKE
1724
1726
  # PRODUCT RULE: Cannot sleep/idle/standby with open tasks. Work first.
1725
1727
  if status in ("sleeping", "idle", "standby"):
1726
1728
  pending_tasks = _get_pending_tasks_summary()
@@ -1730,6 +1732,12 @@ def meshcode_set_status(status: str, task: str = "") -> Dict[str, Any]:
1730
1732
  "reason": f"Cannot set status '{status}' — you have {len(pending_tasks)} open tasks. Work them first.",
1731
1733
  "pending_tasks": pending_tasks,
1732
1734
  }
1735
+ # Setting online/working = stay awake (prevent auto-sleep)
1736
+ # Setting sleeping = allow auto-sleep again
1737
+ if status in ("online", "working"):
1738
+ _STAY_AWAKE = True
1739
+ elif status == "sleeping":
1740
+ _STAY_AWAKE = False
1733
1741
  return be.set_status(_PROJECT_ID, AGENT_NAME, status, task, api_key=_get_api_key())
1734
1742
 
1735
1743
 
@@ -1798,9 +1806,29 @@ def meshcode_task_claim(task_id: str) -> Dict[str, Any]:
1798
1806
  @mcp.tool()
1799
1807
  @with_working_status
1800
1808
  def meshcode_task_complete(task_id: str, summary: str = "") -> Dict[str, Any]:
1801
- """Complete a claimed task with summary."""
1809
+ """Complete a claimed task with summary. Auto-remembers the task summary."""
1802
1810
  api_key = _get_api_key()
1803
- return be.task_complete(api_key, _PROJECT_ID, task_id, AGENT_NAME, summary=summary)
1811
+ result = be.task_complete(api_key, _PROJECT_ID, task_id, AGENT_NAME, summary=summary)
1812
+ # Auto-remember task completion for future context
1813
+ if isinstance(result, dict) and result.get("ok") and summary:
1814
+ try:
1815
+ import threading
1816
+ def _auto_remember():
1817
+ try:
1818
+ be.sb_rpc("mc_memory_set", {
1819
+ "p_api_key": api_key,
1820
+ "p_agent_name": AGENT_NAME,
1821
+ "p_key": f"task_{task_id[:8]}",
1822
+ "p_value": {"title": result.get("title", ""), "summary": summary, "completed": True},
1823
+ "p_tier": "episodic",
1824
+ "p_project_name": PROJECT_NAME,
1825
+ })
1826
+ except Exception:
1827
+ pass
1828
+ threading.Thread(target=_auto_remember, daemon=True).start()
1829
+ except Exception:
1830
+ pass
1831
+ return result
1804
1832
 
1805
1833
 
1806
1834
  @mcp.tool()
@@ -2160,6 +2188,7 @@ def meshcode_remember(key: str, value: Any) -> Dict[str, Any]:
2160
2188
  "p_agent_name": AGENT_NAME,
2161
2189
  "p_key": key,
2162
2190
  "p_value": json_value,
2191
+ "p_tier": "reference",
2163
2192
  "p_project_name": PROJECT_NAME,
2164
2193
  })
2165
2194
  # Best-effort sync to Obsidian vault (if configured)
@@ -2185,16 +2214,33 @@ def meshcode_recall(key: Optional[str] = None) -> Dict[str, Any]:
2185
2214
  "p_api_key": api_key,
2186
2215
  "p_agent_name": AGENT_NAME,
2187
2216
  "p_key": key,
2188
- "p_project_name": PROJECT_NAME,
2189
2217
  })
2190
2218
  else:
2191
2219
  return be.sb_rpc("mc_memory_list", {
2192
2220
  "p_api_key": api_key,
2193
2221
  "p_agent_name": AGENT_NAME,
2222
+ "p_tier": "critical",
2194
2223
  "p_project_name": PROJECT_NAME,
2195
2224
  })
2196
2225
 
2197
2226
 
2227
+ @mcp.tool()
2228
+ @with_working_status
2229
+ def meshcode_recall_keys() -> Dict[str, Any]:
2230
+ """List memory keys only (no values). Cheap token cost for deciding what to recall."""
2231
+ api_key = _get_api_key()
2232
+ result = be.sb_rpc("mc_memory_list", {
2233
+ "p_api_key": api_key,
2234
+ "p_agent_name": AGENT_NAME,
2235
+ "p_tier": "reference",
2236
+ "p_project_name": PROJECT_NAME,
2237
+ })
2238
+ if isinstance(result, dict) and result.get("ok"):
2239
+ keys = [m.get("key") for m in result.get("memories", []) if m.get("key")]
2240
+ return {"ok": True, "keys": keys, "count": len(keys)}
2241
+ return result
2242
+
2243
+
2198
2244
  @mcp.tool()
2199
2245
  @with_working_status
2200
2246
  def meshcode_forget(key: str) -> Dict[str, Any]:
@@ -2208,7 +2254,6 @@ def meshcode_forget(key: str) -> Dict[str, Any]:
2208
2254
  "p_api_key": api_key,
2209
2255
  "p_agent_name": AGENT_NAME,
2210
2256
  "p_key": key,
2211
- "p_project_name": PROJECT_NAME,
2212
2257
  })
2213
2258
 
2214
2259
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: meshcode
3
- Version: 2.8.0
3
+ Version: 2.8.2
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.8.0"
7
+ version = "2.8.2"
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