meshagent-cli 0.36.1__tar.gz → 0.36.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 (86) hide show
  1. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/PKG-INFO +13 -13
  2. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/auth_async.py +3 -2
  3. meshagent_cli-0.36.2/meshagent/cli/auth_async_test.py +16 -0
  4. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/cli.py +1 -0
  5. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/room.py +6 -0
  6. meshagent_cli-0.36.2/meshagent/cli/room_connect.py +119 -0
  7. meshagent_cli-0.36.2/meshagent/cli/room_connect_test.py +151 -0
  8. meshagent_cli-0.36.2/meshagent/cli/version.py +1 -0
  9. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent_cli.egg-info/PKG-INFO +13 -13
  10. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent_cli.egg-info/SOURCES.txt +3 -0
  11. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent_cli.egg-info/requires.txt +12 -12
  12. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/pyproject.toml +12 -12
  13. meshagent_cli-0.36.1/meshagent/cli/version.py +0 -1
  14. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/README.md +0 -0
  15. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/__init__.py +0 -0
  16. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/agent.py +0 -0
  17. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/api_keys.py +0 -0
  18. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/api_keys_test.py +0 -0
  19. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/async_typer.py +0 -0
  20. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/async_typer_test.py +0 -0
  21. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/auth.py +0 -0
  22. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/call.py +0 -0
  23. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/chatbot.py +0 -0
  24. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/cli_mcp.py +0 -0
  25. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/cli_secrets.py +0 -0
  26. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/cli_test.py +0 -0
  27. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/codex.py +0 -0
  28. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/common_options.py +0 -0
  29. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/containers.py +0 -0
  30. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/containers_test.py +0 -0
  31. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/database.py +0 -0
  32. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/developer.py +0 -0
  33. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/developer_test.py +0 -0
  34. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/helper.py +0 -0
  35. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/helper_test.py +0 -0
  36. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/helpers.py +0 -0
  37. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/host.py +0 -0
  38. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/image.py +0 -0
  39. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/image_test.py +0 -0
  40. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/mailbot.py +0 -0
  41. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/mailboxes.py +0 -0
  42. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/meeting_transcriber.py +0 -0
  43. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/memory.py +0 -0
  44. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/memory_test.py +0 -0
  45. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/messaging.py +0 -0
  46. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/multi.py +0 -0
  47. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/oauth2.py +0 -0
  48. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/oci_archive.py +0 -0
  49. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/oci_archive_test.py +0 -0
  50. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/participant_token.py +0 -0
  51. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/port.py +0 -0
  52. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/port_test.py +0 -0
  53. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/process.py +0 -0
  54. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/process_test.py +0 -0
  55. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/projects.py +0 -0
  56. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/queue.py +0 -0
  57. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/queue_test.py +0 -0
  58. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/room_services.py +0 -0
  59. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/rooms.py +0 -0
  60. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/root_commands.py +0 -0
  61. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/routes.py +0 -0
  62. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/scheduled_tasks.py +0 -0
  63. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/scheduled_tasks_test.py +0 -0
  64. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/services.py +0 -0
  65. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/services_test.py +0 -0
  66. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/sessions.py +0 -0
  67. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/sessions_test.py +0 -0
  68. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/storage.py +0 -0
  69. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/storage_test.py +0 -0
  70. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/sync.py +0 -0
  71. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/sync_test.py +0 -0
  72. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/task_runner.py +0 -0
  73. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/test.py +0 -0
  74. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/tui/__init__.py +0 -0
  75. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/tui/setup.py +0 -0
  76. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/tui/setup_splash_frames.py +0 -0
  77. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/tui/setup_test.py +0 -0
  78. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/voicebot.py +0 -0
  79. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/webhook.py +0 -0
  80. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/webserver.py +0 -0
  81. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/webserver_test.py +0 -0
  82. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/worker.py +0 -0
  83. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent_cli.egg-info/dependency_links.txt +0 -0
  84. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent_cli.egg-info/entry_points.txt +0 -0
  85. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent_cli.egg-info/top_level.txt +0 -0
  86. {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: meshagent-cli
3
- Version: 0.36.1
3
+ Version: 0.36.2
4
4
  Summary: CLI for Meshagent
5
5
  License-Expression: Apache-2.0
6
6
  Project-URL: Documentation, https://docs.meshagent.com
@@ -20,21 +20,21 @@ Requires-Dist: rich~=14.3.0
20
20
  Requires-Dist: textual<2.0,>=0.50
21
21
  Requires-Dist: prompt-toolkit~=3.0.52
22
22
  Provides-Extra: all
23
- Requires-Dist: meshagent-agents[all]~=0.36.1; extra == "all"
24
- Requires-Dist: meshagent-api[all]~=0.36.1; extra == "all"
25
- Requires-Dist: meshagent-computers~=0.36.1; extra == "all"
26
- Requires-Dist: meshagent-openai~=0.36.1; extra == "all"
27
- Requires-Dist: meshagent-anthropic~=0.36.1; extra == "all"
28
- Requires-Dist: meshagent-codex~=0.36.1; extra == "all"
29
- Requires-Dist: meshagent-mcp~=0.36.1; extra == "all"
30
- Requires-Dist: meshagent-tools~=0.36.1; extra == "all"
23
+ Requires-Dist: meshagent-agents[all]~=0.36.2; extra == "all"
24
+ Requires-Dist: meshagent-api[all]~=0.36.2; extra == "all"
25
+ Requires-Dist: meshagent-computers~=0.36.2; extra == "all"
26
+ Requires-Dist: meshagent-openai~=0.36.2; extra == "all"
27
+ Requires-Dist: meshagent-anthropic~=0.36.2; extra == "all"
28
+ Requires-Dist: meshagent-codex~=0.36.2; extra == "all"
29
+ Requires-Dist: meshagent-mcp~=0.36.2; extra == "all"
30
+ Requires-Dist: meshagent-tools~=0.36.2; extra == "all"
31
31
  Requires-Dist: supabase-auth~=2.28.0; extra == "all"
32
32
  Requires-Dist: prompt-toolkit~=3.0.52; extra == "all"
33
33
  Provides-Extra: mcp-service
34
- Requires-Dist: meshagent-agents[all]~=0.36.1; extra == "mcp-service"
35
- Requires-Dist: meshagent-api~=0.36.1; extra == "mcp-service"
36
- Requires-Dist: meshagent-mcp~=0.36.1; extra == "mcp-service"
37
- Requires-Dist: meshagent-tools~=0.36.1; extra == "mcp-service"
34
+ Requires-Dist: meshagent-agents[all]~=0.36.2; extra == "mcp-service"
35
+ Requires-Dist: meshagent-api~=0.36.2; extra == "mcp-service"
36
+ Requires-Dist: meshagent-mcp~=0.36.2; extra == "mcp-service"
37
+ Requires-Dist: meshagent-tools~=0.36.2; extra == "mcp-service"
38
38
  Requires-Dist: supabase-auth~=2.28.0; extra == "mcp-service"
39
39
 
40
40
  # [Meshagent](https://www.meshagent.com)
@@ -11,6 +11,7 @@ from pathlib import Path
11
11
  from typing import Awaitable, Callable, Optional
12
12
  from urllib.parse import urlencode
13
13
  from aiohttp import web, ClientSession
14
+ from meshagent.api.oauth_scopes import FULL_OAUTH_SCOPE
14
15
 
15
16
  # -----------------------------------------------------------------------------
16
17
  # Config
@@ -24,7 +25,7 @@ REDIRECT_URL = f"http://localhost:{REDIRECT_PORT}/callback"
24
25
  # - MESHAGENT_API_URL (required): e.g., https://api.meshagent.com
25
26
  # - MESHAGENT_OAUTH_CLIENT_ID (required)
26
27
  # - MESHAGENT_OAUTH_CLIENT_SECRET (optional; only if your server requires it)
27
- # - MESHAGENT_OAUTH_SCOPES (optional; defaults to "openid email profile")
28
+ # - MESHAGENT_OAUTH_SCOPES (optional; defaults to the full official scope set)
28
29
 
29
30
  # -----------------------------------------------------------------------------
30
31
  # Helpers
@@ -80,7 +81,7 @@ def _client_secret() -> str | None:
80
81
 
81
82
 
82
83
  def _scopes() -> str:
83
- return os.getenv("MESHAGENT_OAUTH_SCOPES", "admin")
84
+ return os.getenv("MESHAGENT_OAUTH_SCOPES", FULL_OAUTH_SCOPE)
84
85
 
85
86
 
86
87
  def _save(tokens: dict):
@@ -0,0 +1,16 @@
1
+ from meshagent.api.oauth_scopes import FULL_OAUTH_SCOPE
2
+ from meshagent.cli import auth_async
3
+
4
+
5
+ def test_scopes_defaults_to_full_official_scope_set(
6
+ monkeypatch,
7
+ ) -> None:
8
+ monkeypatch.delenv("MESHAGENT_OAUTH_SCOPES", raising=False)
9
+
10
+ assert auth_async._scopes() == FULL_OAUTH_SCOPE
11
+
12
+
13
+ def test_scopes_prefers_environment_override(monkeypatch) -> None:
14
+ monkeypatch.setenv("MESHAGENT_OAUTH_SCOPES", "admin")
15
+
16
+ assert auth_async._scopes() == "admin"
@@ -116,6 +116,7 @@ app.add_lazy_command(
116
116
  name="helper",
117
117
  module="meshagent.cli.helpers",
118
118
  help="Developer helper services",
119
+ hidden=True,
119
120
  )
120
121
  app.add_lazy_command(
121
122
  name="helpers",
@@ -76,3 +76,9 @@ app.add_lazy_command(
76
76
  module="meshagent.cli.sync",
77
77
  help="Inspect and update mesh documents in a room",
78
78
  )
79
+ app.add_lazy_command(
80
+ name="connect",
81
+ module="meshagent.cli.room_connect",
82
+ attribute="connect_command",
83
+ help="Connect to a room and run a local command with room auth env",
84
+ )
@@ -0,0 +1,119 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass
4
+ import os
5
+ import subprocess
6
+ from typing import Sequence
7
+
8
+ import click
9
+ from rich import print
10
+
11
+ from meshagent.api.helpers import meshagent_base_url
12
+ from meshagent.cli import async_typer
13
+ from meshagent.cli.helper import get_client, resolve_project_id, resolve_room
14
+
15
+
16
+ @dataclass(frozen=True)
17
+ class _ConnectedRoomEnv:
18
+ api_url: str
19
+ room_name: str
20
+ room_url: str
21
+ token: str
22
+
23
+
24
+ def _normalize_room_url(*, room_url: str) -> str:
25
+ normalized = room_url.strip().rstrip("/")
26
+ if normalized.startswith("wss:"):
27
+ return "https:" + normalized.removeprefix("wss:")
28
+ if normalized.startswith("ws:"):
29
+ return "http:" + normalized.removeprefix("ws:")
30
+ return normalized
31
+
32
+
33
+ async def _connect_room_env(
34
+ *,
35
+ project_id: str | None,
36
+ room: str | None,
37
+ ) -> _ConnectedRoomEnv:
38
+ account_client = await get_client()
39
+ try:
40
+ resolved_project_id = await resolve_project_id(project_id=project_id)
41
+ resolved_room = resolve_room(room)
42
+ if resolved_room is None:
43
+ print("[red]--room is required (or set MESHAGENT_ROOM).[/red]")
44
+ raise click.exceptions.Exit(1)
45
+
46
+ connection = await account_client.connect_room(
47
+ project_id=resolved_project_id,
48
+ room=resolved_room,
49
+ )
50
+ return _ConnectedRoomEnv(
51
+ api_url=os.getenv("MESHAGENT_API_URL") or meshagent_base_url(),
52
+ room_name=connection.room_name,
53
+ room_url=_normalize_room_url(room_url=connection.room_url),
54
+ token=connection.jwt,
55
+ )
56
+ finally:
57
+ await account_client.close()
58
+
59
+
60
+ def _run_connected_command(
61
+ *,
62
+ command: Sequence[str],
63
+ room_env: _ConnectedRoomEnv,
64
+ ) -> int:
65
+ child_env = os.environ.copy()
66
+ child_env["MESHAGENT_API_URL"] = room_env.api_url
67
+ child_env["MESHAGENT_TOKEN"] = room_env.token
68
+ child_env["MESHAGENT_ROOM"] = room_env.room_name
69
+ child_env["OPENAI_BASE_URL"] = f"{room_env.room_url}/openai/v1"
70
+ child_env["ANTHROPIC_BASE_URL"] = f"{room_env.room_url}/anthropic"
71
+ child_env["OPENAI_API_KEY"] = room_env.token
72
+ child_env["ANTHROPIC_API_KEY"] = room_env.token
73
+
74
+ try:
75
+ result = subprocess.run(
76
+ list(command),
77
+ check=False,
78
+ env=child_env,
79
+ )
80
+ except OSError as exc:
81
+ error_message = exc.strerror or str(exc)
82
+ raise click.ClickException(
83
+ f"Failed to start {command[0]}: {error_message}"
84
+ ) from exc
85
+
86
+ return result.returncode
87
+
88
+
89
+ @click.command(
90
+ "connect",
91
+ help=(
92
+ "Connect to a room and run a local command with "
93
+ "MESHAGENT_API_URL, MESHAGENT_TOKEN, and MESHAGENT_ROOM set. "
94
+ "Use -- before the local command."
95
+ ),
96
+ )
97
+ @click.option(
98
+ "--project-id",
99
+ help="A MeshAgent project id. If empty, the activated project will be used.",
100
+ )
101
+ @click.option("--room", help="Room name")
102
+ @click.argument("command", nargs=-1, type=click.UNPROCESSED)
103
+ def connect_command(
104
+ project_id: str | None,
105
+ room: str | None,
106
+ command: tuple[str, ...],
107
+ ) -> None:
108
+ if len(command) == 0:
109
+ raise click.UsageError(
110
+ "Pass the local command after --, for example: "
111
+ "meshagent room connect -- python script.py"
112
+ )
113
+
114
+ room_env = async_typer._run_coroutine_sync(
115
+ _connect_room_env(project_id=project_id, room=room)
116
+ )
117
+ raise click.exceptions.Exit(
118
+ _run_connected_command(command=command, room_env=room_env)
119
+ )
@@ -0,0 +1,151 @@
1
+ from types import SimpleNamespace
2
+
3
+ import pytest
4
+ from click.testing import CliRunner
5
+
6
+ from meshagent.cli import room_connect
7
+ from meshagent.cli import cli as root_cli
8
+ from meshagent.cli.async_typer import get_command
9
+
10
+
11
+ class _FakeAccountClient:
12
+ def __init__(self) -> None:
13
+ self.base_url = "https://api.example.meshagent.test"
14
+ self.closed = False
15
+ self.connect_calls: list[dict[str, str]] = []
16
+
17
+ async def connect_room(self, *, project_id: str, room: str) -> SimpleNamespace:
18
+ self.connect_calls.append({"project_id": project_id, "room": room})
19
+ return SimpleNamespace(
20
+ jwt="room-jwt",
21
+ room_name="connected-room",
22
+ room_url="wss://room-proxy.meshagent.test/rooms/connected-room",
23
+ )
24
+
25
+ async def close(self) -> None:
26
+ self.closed = True
27
+
28
+
29
+ def test_room_connect_runs_command_with_connected_room_env(
30
+ monkeypatch: pytest.MonkeyPatch,
31
+ ) -> None:
32
+ account_client = _FakeAccountClient()
33
+ captured_run: dict[str, object] = {}
34
+
35
+ async def _fake_get_client() -> _FakeAccountClient:
36
+ return account_client
37
+
38
+ async def _fake_resolve_project_id(*, project_id: str | None) -> str:
39
+ assert project_id == "project-input"
40
+ return "project-1"
41
+
42
+ def _fake_resolve_room(room: str | None) -> str | None:
43
+ assert room == "room-input"
44
+ return room
45
+
46
+ def _fake_run(command, *, check: bool, env: dict[str, str]):
47
+ captured_run["command"] = command
48
+ captured_run["check"] = check
49
+ captured_run["env"] = env
50
+ return SimpleNamespace(returncode=23)
51
+
52
+ monkeypatch.setattr(room_connect, "get_client", _fake_get_client)
53
+ monkeypatch.setattr(room_connect, "resolve_project_id", _fake_resolve_project_id)
54
+ monkeypatch.setattr(room_connect, "resolve_room", _fake_resolve_room)
55
+ monkeypatch.setattr(room_connect.subprocess, "run", _fake_run)
56
+ monkeypatch.setattr(
57
+ room_connect,
58
+ "meshagent_base_url",
59
+ lambda: "https://default.meshagent.test",
60
+ )
61
+ monkeypatch.setenv("UNCHANGED_ENV", "keep-me")
62
+ monkeypatch.setenv("MESHAGENT_API_URL", "https://env.meshagent.test")
63
+
64
+ result = CliRunner().invoke(
65
+ get_command(root_cli.app),
66
+ [
67
+ "room",
68
+ "connect",
69
+ "--project-id",
70
+ "project-input",
71
+ "--room",
72
+ "room-input",
73
+ "--",
74
+ "python",
75
+ "-c",
76
+ "print('hello')",
77
+ ],
78
+ )
79
+
80
+ assert result.exit_code == 23
81
+ assert account_client.connect_calls == [
82
+ {"project_id": "project-1", "room": "room-input"}
83
+ ]
84
+ assert account_client.closed is True
85
+ assert captured_run["command"] == ["python", "-c", "print('hello')"]
86
+ assert captured_run["check"] is False
87
+ captured_env = captured_run["env"]
88
+ assert isinstance(captured_env, dict)
89
+ assert captured_env["UNCHANGED_ENV"] == "keep-me"
90
+ assert captured_env["MESHAGENT_API_URL"] == "https://env.meshagent.test"
91
+ assert captured_env["MESHAGENT_TOKEN"] == "room-jwt"
92
+ assert captured_env["MESHAGENT_ROOM"] == "connected-room"
93
+ assert (
94
+ captured_env["OPENAI_BASE_URL"]
95
+ == "https://room-proxy.meshagent.test/rooms/connected-room/openai/v1"
96
+ )
97
+ assert (
98
+ captured_env["ANTHROPIC_BASE_URL"]
99
+ == "https://room-proxy.meshagent.test/rooms/connected-room/anthropic"
100
+ )
101
+ assert captured_env["OPENAI_API_KEY"] == "room-jwt"
102
+ assert captured_env["ANTHROPIC_API_KEY"] == "room-jwt"
103
+
104
+
105
+ @pytest.mark.asyncio
106
+ async def test_room_connect_uses_default_api_url_when_env_is_unset(
107
+ monkeypatch: pytest.MonkeyPatch,
108
+ ) -> None:
109
+ account_client = _FakeAccountClient()
110
+
111
+ async def _fake_get_client() -> _FakeAccountClient:
112
+ return account_client
113
+
114
+ async def _fake_resolve_project_id(*, project_id: str | None) -> str:
115
+ assert project_id == "project-input"
116
+ return "project-1"
117
+
118
+ def _fake_resolve_room(room: str | None) -> str | None:
119
+ assert room == "room-input"
120
+ return room
121
+
122
+ monkeypatch.setattr(room_connect, "get_client", _fake_get_client)
123
+ monkeypatch.setattr(room_connect, "resolve_project_id", _fake_resolve_project_id)
124
+ monkeypatch.setattr(room_connect, "resolve_room", _fake_resolve_room)
125
+ monkeypatch.setattr(
126
+ room_connect,
127
+ "meshagent_base_url",
128
+ lambda: "https://default.meshagent.test",
129
+ )
130
+ monkeypatch.delenv("MESHAGENT_API_URL", raising=False)
131
+
132
+ room_env = await room_connect._connect_room_env(
133
+ project_id="project-input",
134
+ room="room-input",
135
+ )
136
+
137
+ assert room_env.api_url == "https://default.meshagent.test"
138
+ assert room_env.room_name == "connected-room"
139
+ assert room_env.room_url == "https://room-proxy.meshagent.test/rooms/connected-room"
140
+ assert room_env.token == "room-jwt"
141
+ assert account_client.closed is True
142
+
143
+
144
+ def test_room_connect_requires_command_after_separator() -> None:
145
+ result = CliRunner().invoke(
146
+ get_command(root_cli.app),
147
+ ["room", "connect", "--"],
148
+ )
149
+
150
+ assert result.exit_code == 2
151
+ assert "Pass the local command after --" in result.output
@@ -0,0 +1 @@
1
+ __version__ = "0.36.2"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: meshagent-cli
3
- Version: 0.36.1
3
+ Version: 0.36.2
4
4
  Summary: CLI for Meshagent
5
5
  License-Expression: Apache-2.0
6
6
  Project-URL: Documentation, https://docs.meshagent.com
@@ -20,21 +20,21 @@ Requires-Dist: rich~=14.3.0
20
20
  Requires-Dist: textual<2.0,>=0.50
21
21
  Requires-Dist: prompt-toolkit~=3.0.52
22
22
  Provides-Extra: all
23
- Requires-Dist: meshagent-agents[all]~=0.36.1; extra == "all"
24
- Requires-Dist: meshagent-api[all]~=0.36.1; extra == "all"
25
- Requires-Dist: meshagent-computers~=0.36.1; extra == "all"
26
- Requires-Dist: meshagent-openai~=0.36.1; extra == "all"
27
- Requires-Dist: meshagent-anthropic~=0.36.1; extra == "all"
28
- Requires-Dist: meshagent-codex~=0.36.1; extra == "all"
29
- Requires-Dist: meshagent-mcp~=0.36.1; extra == "all"
30
- Requires-Dist: meshagent-tools~=0.36.1; extra == "all"
23
+ Requires-Dist: meshagent-agents[all]~=0.36.2; extra == "all"
24
+ Requires-Dist: meshagent-api[all]~=0.36.2; extra == "all"
25
+ Requires-Dist: meshagent-computers~=0.36.2; extra == "all"
26
+ Requires-Dist: meshagent-openai~=0.36.2; extra == "all"
27
+ Requires-Dist: meshagent-anthropic~=0.36.2; extra == "all"
28
+ Requires-Dist: meshagent-codex~=0.36.2; extra == "all"
29
+ Requires-Dist: meshagent-mcp~=0.36.2; extra == "all"
30
+ Requires-Dist: meshagent-tools~=0.36.2; extra == "all"
31
31
  Requires-Dist: supabase-auth~=2.28.0; extra == "all"
32
32
  Requires-Dist: prompt-toolkit~=3.0.52; extra == "all"
33
33
  Provides-Extra: mcp-service
34
- Requires-Dist: meshagent-agents[all]~=0.36.1; extra == "mcp-service"
35
- Requires-Dist: meshagent-api~=0.36.1; extra == "mcp-service"
36
- Requires-Dist: meshagent-mcp~=0.36.1; extra == "mcp-service"
37
- Requires-Dist: meshagent-tools~=0.36.1; extra == "mcp-service"
34
+ Requires-Dist: meshagent-agents[all]~=0.36.2; extra == "mcp-service"
35
+ Requires-Dist: meshagent-api~=0.36.2; extra == "mcp-service"
36
+ Requires-Dist: meshagent-mcp~=0.36.2; extra == "mcp-service"
37
+ Requires-Dist: meshagent-tools~=0.36.2; extra == "mcp-service"
38
38
  Requires-Dist: supabase-auth~=2.28.0; extra == "mcp-service"
39
39
 
40
40
  # [Meshagent](https://www.meshagent.com)
@@ -8,6 +8,7 @@ meshagent/cli/async_typer.py
8
8
  meshagent/cli/async_typer_test.py
9
9
  meshagent/cli/auth.py
10
10
  meshagent/cli/auth_async.py
11
+ meshagent/cli/auth_async_test.py
11
12
  meshagent/cli/call.py
12
13
  meshagent/cli/chatbot.py
13
14
  meshagent/cli/cli.py
@@ -46,6 +47,8 @@ meshagent/cli/projects.py
46
47
  meshagent/cli/queue.py
47
48
  meshagent/cli/queue_test.py
48
49
  meshagent/cli/room.py
50
+ meshagent/cli/room_connect.py
51
+ meshagent/cli/room_connect_test.py
49
52
  meshagent/cli/room_services.py
50
53
  meshagent/cli/rooms.py
51
54
  meshagent/cli/root_commands.py
@@ -11,20 +11,20 @@ textual<2.0,>=0.50
11
11
  prompt-toolkit~=3.0.52
12
12
 
13
13
  [all]
14
- meshagent-agents[all]~=0.36.1
15
- meshagent-api[all]~=0.36.1
16
- meshagent-computers~=0.36.1
17
- meshagent-openai~=0.36.1
18
- meshagent-anthropic~=0.36.1
19
- meshagent-codex~=0.36.1
20
- meshagent-mcp~=0.36.1
21
- meshagent-tools~=0.36.1
14
+ meshagent-agents[all]~=0.36.2
15
+ meshagent-api[all]~=0.36.2
16
+ meshagent-computers~=0.36.2
17
+ meshagent-openai~=0.36.2
18
+ meshagent-anthropic~=0.36.2
19
+ meshagent-codex~=0.36.2
20
+ meshagent-mcp~=0.36.2
21
+ meshagent-tools~=0.36.2
22
22
  supabase-auth~=2.28.0
23
23
  prompt-toolkit~=3.0.52
24
24
 
25
25
  [mcp-service]
26
- meshagent-agents[all]~=0.36.1
27
- meshagent-api~=0.36.1
28
- meshagent-mcp~=0.36.1
29
- meshagent-tools~=0.36.1
26
+ meshagent-agents[all]~=0.36.2
27
+ meshagent-api~=0.36.2
28
+ meshagent-mcp~=0.36.2
29
+ meshagent-tools~=0.36.2
30
30
  supabase-auth~=2.28.0
@@ -27,23 +27,23 @@ dynamic = ["version", "readme"]
27
27
  [project.optional-dependencies]
28
28
 
29
29
  all = [
30
- "meshagent-agents[all]~=0.36.1",
31
- "meshagent-api[all]~=0.36.1",
32
- "meshagent-computers~=0.36.1",
33
- "meshagent-openai~=0.36.1",
34
- "meshagent-anthropic~=0.36.1",
35
- "meshagent-codex~=0.36.1",
36
- "meshagent-mcp~=0.36.1",
37
- "meshagent-tools~=0.36.1",
30
+ "meshagent-agents[all]~=0.36.2",
31
+ "meshagent-api[all]~=0.36.2",
32
+ "meshagent-computers~=0.36.2",
33
+ "meshagent-openai~=0.36.2",
34
+ "meshagent-anthropic~=0.36.2",
35
+ "meshagent-codex~=0.36.2",
36
+ "meshagent-mcp~=0.36.2",
37
+ "meshagent-tools~=0.36.2",
38
38
  "supabase-auth~=2.28.0",
39
39
  "prompt-toolkit~=3.0.52"
40
40
  ]
41
41
 
42
42
  mcp-service = [
43
- "meshagent-agents[all]~=0.36.1",
44
- "meshagent-api~=0.36.1",
45
- "meshagent-mcp~=0.36.1",
46
- "meshagent-tools~=0.36.1",
43
+ "meshagent-agents[all]~=0.36.2",
44
+ "meshagent-api~=0.36.2",
45
+ "meshagent-mcp~=0.36.2",
46
+ "meshagent-tools~=0.36.2",
47
47
  "supabase-auth~=2.28.0"
48
48
  ]
49
49
 
@@ -1 +0,0 @@
1
- __version__ = "0.36.1"
File without changes
File without changes