meshcode 1.8.6__tar.gz → 1.8.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 (29) hide show
  1. {meshcode-1.8.6 → meshcode-1.8.8}/PKG-INFO +1 -1
  2. {meshcode-1.8.6 → meshcode-1.8.8}/meshcode/__init__.py +1 -1
  3. {meshcode-1.8.6 → meshcode-1.8.8}/meshcode/comms_v4.py +53 -4
  4. {meshcode-1.8.6 → meshcode-1.8.8}/meshcode/invites.py +2 -2
  5. {meshcode-1.8.6 → meshcode-1.8.8}/meshcode/meshcode_mcp/backend.py +2 -2
  6. {meshcode-1.8.6 → meshcode-1.8.8}/meshcode/run_agent.py +10 -0
  7. {meshcode-1.8.6 → meshcode-1.8.8}/meshcode/setup_clients.py +2 -2
  8. {meshcode-1.8.6 → meshcode-1.8.8}/meshcode.egg-info/PKG-INFO +1 -1
  9. {meshcode-1.8.6 → meshcode-1.8.8}/pyproject.toml +1 -1
  10. {meshcode-1.8.6 → meshcode-1.8.8}/README.md +0 -0
  11. {meshcode-1.8.6 → meshcode-1.8.8}/meshcode/cli.py +0 -0
  12. {meshcode-1.8.6 → meshcode-1.8.8}/meshcode/launcher.py +0 -0
  13. {meshcode-1.8.6 → meshcode-1.8.8}/meshcode/launcher_install.py +0 -0
  14. {meshcode-1.8.6 → meshcode-1.8.8}/meshcode/meshcode_mcp/__init__.py +0 -0
  15. {meshcode-1.8.6 → meshcode-1.8.8}/meshcode/meshcode_mcp/__main__.py +0 -0
  16. {meshcode-1.8.6 → meshcode-1.8.8}/meshcode/meshcode_mcp/realtime.py +0 -0
  17. {meshcode-1.8.6 → meshcode-1.8.8}/meshcode/meshcode_mcp/server.py +0 -0
  18. {meshcode-1.8.6 → meshcode-1.8.8}/meshcode/meshcode_mcp/test_backend.py +0 -0
  19. {meshcode-1.8.6 → meshcode-1.8.8}/meshcode/meshcode_mcp/test_realtime.py +0 -0
  20. {meshcode-1.8.6 → meshcode-1.8.8}/meshcode/preferences.py +0 -0
  21. {meshcode-1.8.6 → meshcode-1.8.8}/meshcode/protocol_v2.py +0 -0
  22. {meshcode-1.8.6 → meshcode-1.8.8}/meshcode/secrets.py +0 -0
  23. {meshcode-1.8.6 → meshcode-1.8.8}/meshcode/self_update.py +0 -0
  24. {meshcode-1.8.6 → meshcode-1.8.8}/meshcode.egg-info/SOURCES.txt +0 -0
  25. {meshcode-1.8.6 → meshcode-1.8.8}/meshcode.egg-info/dependency_links.txt +0 -0
  26. {meshcode-1.8.6 → meshcode-1.8.8}/meshcode.egg-info/entry_points.txt +0 -0
  27. {meshcode-1.8.6 → meshcode-1.8.8}/meshcode.egg-info/requires.txt +0 -0
  28. {meshcode-1.8.6 → meshcode-1.8.8}/meshcode.egg-info/top_level.txt +0 -0
  29. {meshcode-1.8.6 → meshcode-1.8.8}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: meshcode
3
- Version: 1.8.6
3
+ Version: 1.8.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__ = "1.8.6"
2
+ __version__ = "1.8.8"
@@ -47,8 +47,8 @@ from urllib.parse import quote
47
47
  # Production defaults baked in. The publishable key is the anon/public key
48
48
  # (RLS-protected, safe to ship — same one the frontend at meshcode.io uses
49
49
  # in the browser). Override via env vars or ~/.meshcode/env if you self-host.
50
- _DEFAULT_SUPABASE_URL = "https://wwgzzmydrwrjgaebspdo.supabase.co"
51
- _DEFAULT_SUPABASE_KEY = "sb_publishable_0qf0U1GURopPIxLR8Vu7eQ_5grflPP4"
50
+ _DEFAULT_SUPABASE_URL = "https://gjinagyyjttyxnaoavnz.supabase.co"
51
+ _DEFAULT_SUPABASE_KEY = "sb_publishable_qwN9PO1L7jUXhhbhhVk2CQ_z1FXG2Qf"
52
52
 
53
53
  def _load_env_file():
54
54
  """Read SUPABASE_URL/KEY from ~/.meshcode/env if present (overrides defaults)."""
@@ -198,12 +198,61 @@ def ensure_sessions():
198
198
  SESSIONS_DIR.mkdir(parents=True, exist_ok=True)
199
199
 
200
200
 
201
+ def _load_api_key_for_cli() -> str:
202
+ """Pull the user's api key from the keychain (or env fallback) so the
203
+ CLI can call SECURITY DEFINER RPCs that use api_key auth instead of
204
+ relying on the publishable anon key + RLS, which is what CLI verbs
205
+ used to do and which always failed because the CLI has no JWT context.
206
+ """
207
+ # 1) explicit env override
208
+ k = os.environ.get("MESHCODE_API_KEY", "").strip()
209
+ if k:
210
+ return k
211
+ # 2) keychain via secrets module
212
+ try:
213
+ import importlib
214
+ secrets_mod = importlib.import_module("meshcode.secrets")
215
+ profile = os.environ.get("MESHCODE_KEYCHAIN_PROFILE") or secrets_mod.DEFAULT_PROFILE
216
+ key = secrets_mod.get_api_key(profile=profile) or ""
217
+ if key:
218
+ return key
219
+ except Exception:
220
+ pass
221
+ return ""
222
+
223
+
201
224
  def get_project_id(project_name):
202
- """Get or create project, return its UUID."""
225
+ """Resolve a project's UUID for the authenticated CLI user.
226
+
227
+ Resolution order:
228
+ 1. api_key + mc_resolve_project RPC (SECURITY DEFINER, the only
229
+ path that actually works for an authenticated CLI session)
230
+ 2. legacy publishable-anon SELECT (only useful for shared/public
231
+ projects; will fail under RLS for owned projects)
232
+ 3. legacy publishable-anon INSERT (will fail under RLS — kept as
233
+ last resort for backwards compat with very old test scripts)
234
+ """
235
+ api_key = _load_api_key_for_cli()
236
+ if api_key:
237
+ try:
238
+ r = sb_rpc("mc_resolve_project", {
239
+ "p_api_key": api_key,
240
+ "p_project_name": project_name,
241
+ })
242
+ if isinstance(r, dict) and r.get("project_id"):
243
+ return r["project_id"]
244
+ # Some deployments return rows
245
+ if isinstance(r, list) and r and r[0].get("project_id"):
246
+ return r[0]["project_id"]
247
+ except Exception:
248
+ pass
249
+
203
250
  rows = sb_select("mc_projects", f"name=eq.{quote(project_name)}")
204
251
  if rows:
205
252
  return rows[0]["id"]
206
- # Create project
253
+
254
+ # Last resort: try to create. Will fail under RLS for unauthenticated
255
+ # contexts, but kept for legacy callers + admin tooling.
207
256
  result = sb_insert("mc_projects", {"name": project_name})
208
257
  if result and len(result) > 0:
209
258
  return result[0]["id"]
@@ -41,8 +41,8 @@ from urllib.request import Request, urlopen
41
41
  # Supabase RPC helpers
42
42
  # ============================================================
43
43
 
44
- _DEFAULT_SUPABASE_URL = "https://wwgzzmydrwrjgaebspdo.supabase.co"
45
- _DEFAULT_SUPABASE_KEY = "sb_publishable_0qf0U1GURopPIxLR8Vu7eQ_5grflPP4"
44
+ _DEFAULT_SUPABASE_URL = "https://gjinagyyjttyxnaoavnz.supabase.co"
45
+ _DEFAULT_SUPABASE_KEY = "sb_publishable_qwN9PO1L7jUXhhbhhVk2CQ_z1FXG2Qf"
46
46
 
47
47
 
48
48
  def _sb() -> Dict[str, str]:
@@ -13,8 +13,8 @@ from urllib.parse import quote
13
13
  from urllib.request import Request, urlopen
14
14
 
15
15
  # Bake in production defaults — RLS-protected publishable key, safe to ship.
16
- _DEFAULT_SUPABASE_URL = "https://wwgzzmydrwrjgaebspdo.supabase.co"
17
- _DEFAULT_SUPABASE_KEY = "sb_publishable_0qf0U1GURopPIxLR8Vu7eQ_5grflPP4"
16
+ _DEFAULT_SUPABASE_URL = "https://gjinagyyjttyxnaoavnz.supabase.co"
17
+ _DEFAULT_SUPABASE_KEY = "sb_publishable_qwN9PO1L7jUXhhbhhVk2CQ_z1FXG2Qf"
18
18
 
19
19
  def _load_env_file() -> Dict[str, str]:
20
20
  env_path = Path.home() / ".meshcode" / "env"
@@ -112,6 +112,16 @@ def run(agent: str, project: Optional[str] = None, editor_override: Optional[str
112
112
  except Exception:
113
113
  pass
114
114
 
115
+ # Detect: are we already inside a Claude Code session? os.execvp(claude)
116
+ # from inside an existing claude won't work — claude needs a fresh
117
+ # interactive terminal it owns. Refuse with a clear message.
118
+ if os.environ.get("CLAUDECODE") == "1" or os.environ.get("CLAUDE_CODE_SESSION"):
119
+ print("[meshcode] ERROR: meshcode run cannot bootstrap a new agent from inside an", file=sys.stderr)
120
+ print("[meshcode] existing Claude Code session.", file=sys.stderr)
121
+ print("[meshcode] Open a fresh Terminal / iTerm window and run the command there.", file=sys.stderr)
122
+ print(f"[meshcode] (or copy this exact line into a new terminal: meshcode run {agent})", file=sys.stderr)
123
+ return 2
124
+
115
125
  found = _find_agent_workspace(agent, project)
116
126
  if not found:
117
127
  return 2
@@ -93,9 +93,9 @@ def _load_supabase_env() -> Dict[str, str]:
93
93
  elif k == "SUPABASE_KEY" and not key:
94
94
  key = v
95
95
  if not url:
96
- url = "https://wwgzzmydrwrjgaebspdo.supabase.co"
96
+ url = "https://gjinagyyjttyxnaoavnz.supabase.co"
97
97
  if not key:
98
- key = "sb_publishable_0qf0U1GURopPIxLR8Vu7eQ_5grflPP4"
98
+ key = "sb_publishable_qwN9PO1L7jUXhhbhhVk2CQ_z1FXG2Qf"
99
99
  return {"SUPABASE_URL": url, "SUPABASE_KEY": key}
100
100
 
101
101
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: meshcode
3
- Version: 1.8.6
3
+ Version: 1.8.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 = "1.8.6"
7
+ version = "1.8.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
File without changes