meshagent-cli 0.47.1__tar.gz → 0.49.0__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.
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/PKG-INFO +17 -17
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/cli.py +5 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/cli_test.py +31 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/create_project_templates/python/contact-form/server.py +12 -2
- meshagent_cli-0.49.0/meshagent/cli/mounts.py +64 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/process_live_test.py +6 -7
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/process_test.py +26 -4
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/projects.py +75 -2
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/projects_test.py +96 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/room.py +5 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/routes.py +273 -14
- meshagent_cli-0.49.0/meshagent/cli/routes_test.py +352 -0
- meshagent_cli-0.49.0/meshagent/cli/version.py +1 -0
- meshagent_cli-0.49.0/meshagent/cli/volumes.py +252 -0
- meshagent_cli-0.49.0/meshagent/cli/volumes_test.py +31 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent_cli.egg-info/PKG-INFO +17 -17
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent_cli.egg-info/SOURCES.txt +3 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent_cli.egg-info/requires.txt +16 -16
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/pyproject.toml +16 -16
- meshagent_cli-0.47.1/meshagent/cli/routes_test.py +0 -119
- meshagent_cli-0.47.1/meshagent/cli/version.py +0 -1
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/LICENSE +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/README.md +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/__init__.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/_filedrop.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/agent.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/agent_cli_options_test.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/agent_package_cli.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/agent_package_cli_test.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/agents.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/agents_test.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/ask.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/ask_test.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/async_typer.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/async_typer_test.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/auth.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/auth_async.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/auth_async_test.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/auth_test.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/call.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/chatbot.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/cli_mcp.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/common_options.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/config.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/config_test.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/containers.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/containers_test.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/create.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/create_project_templates/__init__.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/create_project_templates/python/backend-agent/server.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/create_project_templates/python/slack-channel/channel.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/create_project_templates/python/slack-channel/scripts/configure-slack.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/create_project_templates/python/slack-channel/scripts/setup-slack-dev-route.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/create_project_templates/python/slack-channel/server.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/create_project_templates/python/task-queue-dashboard/server.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/create_project_templates/python/telegram-channel/channel.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/create_project_templates/python/telegram-channel/scripts/configure-telegram.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/create_project_templates/python/telegram-channel/scripts/create-bot-token.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/create_project_templates/python/telegram-channel/server.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/create_project_templates/python/twilio-channel/channel.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/create_project_templates/python/twilio-channel/server.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/create_project_templates/python/webserver/server.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/create_project_templates/python/whatsapp-channel/channel.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/create_project_templates/python/whatsapp-channel/server.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/create_test.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/dataset.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/dataset_test.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/developer.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/developer_test.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/doctor.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/doctor_dockerfiles/__init__.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/doctor_templates/__init__.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/doctor_test.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/feeds.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/feeds_test.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/helper.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/helper_test.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/helpers.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/host.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/iam.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/iam_test.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/image.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/image_test.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/launch.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/launch_test.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/llm.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/llm_test.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/local_settings.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/local_settings_test.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/mailbot.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/mailbot_test.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/mailboxes.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/mailboxes_test.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/meeting_transcriber.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/memory.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/memory_test.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/meshagent_images.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/meshagent_images_test.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/messaging.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/messaging_test.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/multi.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/oci_archive.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/oci_archive_test.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/participant_token.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/port.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/port_test.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/preamble_rules.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/preamble_rules_test.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/process.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/queue.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/queue_test.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/registry.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/registry_test.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/room_connect.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/room_connect_test.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/room_services.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/room_services_test.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/rooms.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/rooms_test.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/root_commands.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/root_commands_test.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/sample_channel_http_test.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/sample_channel_live_e2e_test.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/scheduled_tasks.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/scheduled_tasks_test.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/secrets.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/secrets_test.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/service_accounts.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/service_accounts_test.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/services.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/services_test.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/sessions.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/sessions_test.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/sqlite.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/sqlite_test.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/storage.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/storage_test.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/subscriptions.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/sync.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/sync_test.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/task_runner.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/task_runner_test.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/test.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/testing.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/thread_inspect.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/thread_inspect_test.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/thread_sidebar.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/tool_call_summary.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/tool_call_summary_test.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/tool_integrations.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/tool_integrations_test.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/tui/__init__.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/tui/auth_switch.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/tui/auth_switch_test.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/tui/create.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/tui/deploy_room.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/tui/deploy_room_test.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/tui/project_activate.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/tui/project_activate_test.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/tui/setup.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/tui/setup_splash_frames.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/tui/setup_test.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/version_check.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/version_check_test.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/voicebot.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/webserver.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/webserver_test.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/worker.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent/cli/worker_test.py +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent_cli.egg-info/dependency_links.txt +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent_cli.egg-info/entry_points.txt +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/meshagent_cli.egg-info/top_level.txt +0 -0
- {meshagent_cli-0.47.1 → meshagent_cli-0.49.0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: meshagent-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.49.0
|
|
4
4
|
Summary: CLI for Meshagent
|
|
5
5
|
License-Expression: Apache-2.0
|
|
6
6
|
Project-URL: Documentation, https://docs.meshagent.com
|
|
@@ -22,8 +22,8 @@ Requires-Dist: openpyxl~=3.1
|
|
|
22
22
|
Requires-Dist: xlsxwriter~=3.2
|
|
23
23
|
Requires-Dist: pathspec<2,>=1.0.3
|
|
24
24
|
Requires-Dist: zstandard~=0.25.0
|
|
25
|
-
Requires-Dist: meshagent-llm-proxy==0.
|
|
26
|
-
Requires-Dist: meshagent-codex==0.
|
|
25
|
+
Requires-Dist: meshagent-llm-proxy==0.49.0
|
|
26
|
+
Requires-Dist: meshagent-codex==0.49.0
|
|
27
27
|
Requires-Dist: rich~=14.3.0
|
|
28
28
|
Requires-Dist: sounddevice~=0.5
|
|
29
29
|
Requires-Dist: textual<9.0,>=8.2.3
|
|
@@ -32,23 +32,23 @@ Requires-Dist: prompt-toolkit~=3.0.52
|
|
|
32
32
|
Requires-Dist: ascii-magic~=2.3
|
|
33
33
|
Requires-Dist: pillow~=11.3.0
|
|
34
34
|
Provides-Extra: all
|
|
35
|
-
Requires-Dist: meshagent-agents[all]==0.
|
|
36
|
-
Requires-Dist: meshagent-api[all]==0.
|
|
37
|
-
Requires-Dist: meshagent-commoncrawl==0.
|
|
38
|
-
Requires-Dist: meshagent-scrapy==0.
|
|
39
|
-
Requires-Dist: meshagent-computers==0.
|
|
40
|
-
Requires-Dist: meshagent-openai==0.
|
|
41
|
-
Requires-Dist: meshagent-anthropic==0.
|
|
42
|
-
Requires-Dist: meshagent-otel==0.
|
|
43
|
-
Requires-Dist: meshagent-mcp==0.
|
|
44
|
-
Requires-Dist: meshagent-tools==0.
|
|
35
|
+
Requires-Dist: meshagent-agents[all]==0.49.0; extra == "all"
|
|
36
|
+
Requires-Dist: meshagent-api[all]==0.49.0; extra == "all"
|
|
37
|
+
Requires-Dist: meshagent-commoncrawl==0.49.0; extra == "all"
|
|
38
|
+
Requires-Dist: meshagent-scrapy==0.49.0; extra == "all"
|
|
39
|
+
Requires-Dist: meshagent-computers==0.49.0; extra == "all"
|
|
40
|
+
Requires-Dist: meshagent-openai==0.49.0; extra == "all"
|
|
41
|
+
Requires-Dist: meshagent-anthropic==0.49.0; extra == "all"
|
|
42
|
+
Requires-Dist: meshagent-otel==0.49.0; extra == "all"
|
|
43
|
+
Requires-Dist: meshagent-mcp==0.49.0; extra == "all"
|
|
44
|
+
Requires-Dist: meshagent-tools==0.49.0; extra == "all"
|
|
45
45
|
Requires-Dist: supabase-auth~=2.28.0; extra == "all"
|
|
46
46
|
Requires-Dist: prompt-toolkit~=3.0.52; extra == "all"
|
|
47
47
|
Provides-Extra: mcp-service
|
|
48
|
-
Requires-Dist: meshagent-agents[all]==0.
|
|
49
|
-
Requires-Dist: meshagent-api==0.
|
|
50
|
-
Requires-Dist: meshagent-mcp==0.
|
|
51
|
-
Requires-Dist: meshagent-tools==0.
|
|
48
|
+
Requires-Dist: meshagent-agents[all]==0.49.0; extra == "mcp-service"
|
|
49
|
+
Requires-Dist: meshagent-api==0.49.0; extra == "mcp-service"
|
|
50
|
+
Requires-Dist: meshagent-mcp==0.49.0; extra == "mcp-service"
|
|
51
|
+
Requires-Dist: meshagent-tools==0.49.0; extra == "mcp-service"
|
|
52
52
|
Requires-Dist: supabase-auth~=2.28.0; extra == "mcp-service"
|
|
53
53
|
Dynamic: license-file
|
|
54
54
|
|
|
@@ -180,6 +180,11 @@ app.add_lazy_command(
|
|
|
180
180
|
module="meshagent.cli.rooms",
|
|
181
181
|
help="Create, list, and manage rooms in a project",
|
|
182
182
|
)
|
|
183
|
+
app.add_lazy_command(
|
|
184
|
+
name="volumes",
|
|
185
|
+
module="meshagent.cli.volumes",
|
|
186
|
+
help="Manage durable storage volumes for a room",
|
|
187
|
+
)
|
|
183
188
|
app.add_lazy_command(
|
|
184
189
|
name="agent",
|
|
185
190
|
module="meshagent.cli.agents",
|
|
@@ -58,6 +58,7 @@ def test_root_help_lists_create_and_doctor_but_hides_legacy_command_namespaces()
|
|
|
58
58
|
assert "│ api-key" not in result.output
|
|
59
59
|
assert "│ launch" in result.output
|
|
60
60
|
assert "│ room" in result.output
|
|
61
|
+
assert "│ volumes" in result.output
|
|
61
62
|
assert "│ call" not in result.output
|
|
62
63
|
assert "│ package" not in result.output
|
|
63
64
|
assert "│ multi" not in result.output
|
|
@@ -151,6 +152,36 @@ def test_room_help_lists_agents_command() -> None:
|
|
|
151
152
|
assert "│ agents" in result.output
|
|
152
153
|
|
|
153
154
|
|
|
155
|
+
def test_volumes_help_lists_durable_lifecycle_commands() -> None:
|
|
156
|
+
result = CliRunner().invoke(cli.app, ["volumes", "--help"])
|
|
157
|
+
|
|
158
|
+
assert result.exit_code == 0
|
|
159
|
+
assert "│ list" in result.output
|
|
160
|
+
assert "│ create" in result.output
|
|
161
|
+
assert "│ expand" in result.output
|
|
162
|
+
assert "│ delete" in result.output
|
|
163
|
+
assert "lease" not in result.output.lower()
|
|
164
|
+
|
|
165
|
+
create_result = CliRunner().invoke(cli.app, ["volumes", "create", "--help"])
|
|
166
|
+
assert create_result.exit_code == 0
|
|
167
|
+
assert "--type" in create_result.output
|
|
168
|
+
assert "--max-size" in create_result.output
|
|
169
|
+
|
|
170
|
+
expand_result = CliRunner().invoke(cli.app, ["volumes", "expand", "--help"])
|
|
171
|
+
assert expand_result.exit_code == 0
|
|
172
|
+
assert "--max-size" in expand_result.output
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
def test_room_mounts_help_is_list_only() -> None:
|
|
176
|
+
result = CliRunner().invoke(cli.app, ["room", "mounts", "--help"])
|
|
177
|
+
|
|
178
|
+
assert result.exit_code == 0
|
|
179
|
+
assert "│ list" in result.output
|
|
180
|
+
assert "│ mount" not in result.output
|
|
181
|
+
assert "│ unmount" not in result.output
|
|
182
|
+
assert "lease" not in result.output.lower()
|
|
183
|
+
|
|
184
|
+
|
|
154
185
|
def test_room_agents_help_lists_call_command() -> None:
|
|
155
186
|
result = CliRunner().invoke(cli.app, ["room", "agents", "--help"])
|
|
156
187
|
|
|
@@ -25,7 +25,8 @@ logging.basicConfig(
|
|
|
25
25
|
)
|
|
26
26
|
LOGGER = logging.getLogger("contact_form")
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
DEFAULT_MAIL_DOMAIN = "mail.meshagent.com"
|
|
29
|
+
DEFAULT_FROM_ADDRESS = f"contact@{DEFAULT_MAIL_DOMAIN}"
|
|
29
30
|
DEFAULT_TO_ADDRESS = ""
|
|
30
31
|
PRIVATE_MAILBOX_PERMISSION_ERROR = "5.7.1 Permission denied"
|
|
31
32
|
TRUE_ENV_VALUES = {"1", "true", "yes", "on"}
|
|
@@ -181,10 +182,19 @@ def room_slug_from_name(room_name: str) -> str:
|
|
|
181
182
|
return room_slug or "room"
|
|
182
183
|
|
|
183
184
|
|
|
185
|
+
def mail_domain() -> str:
|
|
186
|
+
return (
|
|
187
|
+
os.getenv("MESHAGENT_MAIL_DOMAIN", DEFAULT_MAIL_DOMAIN)
|
|
188
|
+
.strip()
|
|
189
|
+
.removeprefix("@")
|
|
190
|
+
or DEFAULT_MAIL_DOMAIN
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
|
|
184
194
|
def default_from_address() -> str:
|
|
185
195
|
room_name = os.getenv("MESHAGENT_ROOM", "").strip()
|
|
186
196
|
if room_name:
|
|
187
|
-
return f"contact-{room_slug_from_name(room_name)}@
|
|
197
|
+
return f"contact-{room_slug_from_name(room_name)}@{mail_domain()}"
|
|
188
198
|
return DEFAULT_FROM_ADDRESS
|
|
189
199
|
|
|
190
200
|
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import json
|
|
2
|
+
|
|
3
|
+
from rich import print
|
|
4
|
+
|
|
5
|
+
from meshagent.api import RoomClient, RoomException, WebSocketClientProtocol
|
|
6
|
+
from meshagent.api.helpers import websocket_room_url
|
|
7
|
+
from meshagent.cli import async_typer
|
|
8
|
+
from meshagent.cli.common_options import OutputFormatOption, ProjectIdOption, RoomOption
|
|
9
|
+
from meshagent.cli.helper import (
|
|
10
|
+
get_client,
|
|
11
|
+
print_json_table,
|
|
12
|
+
resolve_project_id,
|
|
13
|
+
resolve_room,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
app = async_typer.AsyncTyper(help="List storage mounts currently ready in a room")
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@app.callback()
|
|
21
|
+
def _mounts_callback() -> None:
|
|
22
|
+
pass
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
@app.async_command("list")
|
|
26
|
+
async def list_mounts_command(
|
|
27
|
+
*,
|
|
28
|
+
project_id: ProjectIdOption,
|
|
29
|
+
room: RoomOption,
|
|
30
|
+
output: OutputFormatOption = "table",
|
|
31
|
+
) -> None:
|
|
32
|
+
account_client = await get_client()
|
|
33
|
+
try:
|
|
34
|
+
project_id = await resolve_project_id(project_id=project_id)
|
|
35
|
+
room_name = resolve_room(room)
|
|
36
|
+
if room_name is None:
|
|
37
|
+
raise RoomException("--room is required")
|
|
38
|
+
connection = await account_client.connect_room(
|
|
39
|
+
project_id=project_id,
|
|
40
|
+
room=room_name,
|
|
41
|
+
)
|
|
42
|
+
async with RoomClient(
|
|
43
|
+
protocol_factory=WebSocketClientProtocol(
|
|
44
|
+
url=websocket_room_url(room_name=room_name),
|
|
45
|
+
token=connection.jwt,
|
|
46
|
+
).create_factory()
|
|
47
|
+
) as room_client:
|
|
48
|
+
mounts = await room_client.mounts.list()
|
|
49
|
+
records = [mount.model_dump(mode="json") for mount in mounts]
|
|
50
|
+
if output == "json":
|
|
51
|
+
print(json.dumps(records, indent=2))
|
|
52
|
+
elif records:
|
|
53
|
+
print_json_table(
|
|
54
|
+
records,
|
|
55
|
+
"id",
|
|
56
|
+
"name",
|
|
57
|
+
"required",
|
|
58
|
+
"description",
|
|
59
|
+
"consumers",
|
|
60
|
+
)
|
|
61
|
+
else:
|
|
62
|
+
print("No storage mounts are ready.")
|
|
63
|
+
finally:
|
|
64
|
+
await account_client.close()
|
|
@@ -299,14 +299,13 @@ class _RestoringThreadStorage:
|
|
|
299
299
|
def agent_messages(self) -> list[AgentMessage]:
|
|
300
300
|
return [*self.messages]
|
|
301
301
|
|
|
302
|
-
async def
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
302
|
+
async def restore_session_context(
|
|
303
|
+
self, *, context, llm_adapter, file_reader=None
|
|
304
|
+
) -> None:
|
|
305
|
+
restored_messages = await llm_adapter.project_agent_messages(
|
|
306
|
+
messages=self.messages,
|
|
307
|
+
file_reader=file_reader,
|
|
306
308
|
)
|
|
307
|
-
for message in self.messages:
|
|
308
|
-
reader.consume(message)
|
|
309
|
-
reader.finalize()
|
|
310
309
|
llm_adapter.restore_context_messages(
|
|
311
310
|
context=context,
|
|
312
311
|
messages=restored_messages,
|
|
@@ -5442,12 +5442,12 @@ class _FakeProcessThreadAdapter:
|
|
|
5442
5442
|
def agent_messages(self):
|
|
5443
5443
|
return []
|
|
5444
5444
|
|
|
5445
|
-
def restore_session_context(
|
|
5445
|
+
async def restore_session_context(
|
|
5446
|
+
self, *, context, llm_adapter=None, file_reader=None
|
|
5447
|
+
) -> None:
|
|
5446
5448
|
del context
|
|
5447
5449
|
del llm_adapter
|
|
5448
|
-
|
|
5449
|
-
async def restore_session_context_async(self, *, context, llm_adapter=None) -> None:
|
|
5450
|
-
self.restore_session_context(context=context, llm_adapter=llm_adapter)
|
|
5450
|
+
del file_reader
|
|
5451
5451
|
|
|
5452
5452
|
def make_toolkit(self):
|
|
5453
5453
|
return Toolkit(name="thread", tools=[])
|
|
@@ -5547,6 +5547,28 @@ class _SteeringRecordingAdapter:
|
|
|
5547
5547
|
del custom_event_callback
|
|
5548
5548
|
return lambda message: None
|
|
5549
5549
|
|
|
5550
|
+
async def project_agent_messages(
|
|
5551
|
+
self,
|
|
5552
|
+
*,
|
|
5553
|
+
messages: list[AgentMessage],
|
|
5554
|
+
file_reader=None,
|
|
5555
|
+
callbacks=None,
|
|
5556
|
+
) -> list[dict[str, object]]:
|
|
5557
|
+
del file_reader
|
|
5558
|
+
del callbacks
|
|
5559
|
+
projected: list[dict[str, object]] = []
|
|
5560
|
+
for message in messages:
|
|
5561
|
+
if not isinstance(message, (TurnStart, TurnSteer)):
|
|
5562
|
+
continue
|
|
5563
|
+
text = "\n".join(
|
|
5564
|
+
item.text
|
|
5565
|
+
for item in message.content
|
|
5566
|
+
if isinstance(item, AgentTextContent) and item.text != ""
|
|
5567
|
+
)
|
|
5568
|
+
if text != "":
|
|
5569
|
+
projected.append({"role": "user", "content": text})
|
|
5570
|
+
return projected
|
|
5571
|
+
|
|
5550
5572
|
async def create_response(
|
|
5551
5573
|
self,
|
|
5552
5574
|
*,
|
|
@@ -1,19 +1,24 @@
|
|
|
1
1
|
import sys
|
|
2
2
|
from dataclasses import dataclass
|
|
3
|
-
from
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from typing import Annotated, Literal
|
|
4
5
|
|
|
5
6
|
import typer
|
|
7
|
+
from pydantic import BaseModel, ConfigDict
|
|
8
|
+
from pydantic_yaml import parse_yaml_raw_as
|
|
6
9
|
from rich import print
|
|
7
10
|
|
|
11
|
+
from meshagent.api import ApiScope
|
|
8
12
|
from meshagent.api.client import Meshagent, NotFoundError, ProjectInfo, ProjectsPage
|
|
9
13
|
from meshagent.cli import async_typer
|
|
14
|
+
from meshagent.cli.common_options import OutputFormatOption, ProjectIdOption
|
|
10
15
|
from meshagent.cli.helper import (
|
|
11
16
|
get_client,
|
|
12
17
|
get_active_project,
|
|
13
18
|
print_json_table,
|
|
19
|
+
resolve_project_id,
|
|
14
20
|
set_active_project,
|
|
15
21
|
)
|
|
16
|
-
from meshagent.cli.common_options import OutputFormatOption
|
|
17
22
|
|
|
18
23
|
app = async_typer.AsyncTyper(help="Manage or activate your meshagent projects")
|
|
19
24
|
|
|
@@ -25,6 +30,30 @@ class ListedProject:
|
|
|
25
30
|
is_active: bool
|
|
26
31
|
|
|
27
32
|
|
|
33
|
+
RoomAccessRole = Literal["guest", "viewer", "operator", "developer", "admin"]
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class ParticipantTokenRoleDefinition(BaseModel):
|
|
37
|
+
model_config = ConfigDict(extra="forbid")
|
|
38
|
+
|
|
39
|
+
api: ApiScope
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class RoomRoleDefinition(BaseModel):
|
|
43
|
+
model_config = ConfigDict(extra="forbid")
|
|
44
|
+
|
|
45
|
+
participant: ParticipantTokenRoleDefinition | None = None
|
|
46
|
+
site_user: bool = False
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class RoomRolesSpec(BaseModel):
|
|
50
|
+
model_config = ConfigDict(extra="forbid")
|
|
51
|
+
|
|
52
|
+
version: Literal["v1"]
|
|
53
|
+
kind: Literal["RoomRoles"]
|
|
54
|
+
roles: dict[RoomAccessRole, RoomRoleDefinition]
|
|
55
|
+
|
|
56
|
+
|
|
28
57
|
def _parse_listed_projects(
|
|
29
58
|
response: ProjectsPage,
|
|
30
59
|
*,
|
|
@@ -209,6 +238,50 @@ async def get(
|
|
|
209
238
|
await client.close()
|
|
210
239
|
|
|
211
240
|
|
|
241
|
+
@app.async_command(
|
|
242
|
+
"set-room-roles",
|
|
243
|
+
help="Set authoritative project room-role mappings from a YAML spec.",
|
|
244
|
+
)
|
|
245
|
+
async def set_room_roles(
|
|
246
|
+
file: Annotated[Path, typer.Argument(help="RoomRoles YAML spec")],
|
|
247
|
+
project_id: ProjectIdOption,
|
|
248
|
+
):
|
|
249
|
+
try:
|
|
250
|
+
spec = parse_yaml_raw_as(RoomRolesSpec, file.read_text())
|
|
251
|
+
except (OSError, ValueError) as error:
|
|
252
|
+
print(f"[red]Invalid room role spec: {error}[/red]")
|
|
253
|
+
raise typer.Exit(code=1) from error
|
|
254
|
+
|
|
255
|
+
client = await get_client()
|
|
256
|
+
try:
|
|
257
|
+
resolved_project_id = await resolve_project_id(project_id)
|
|
258
|
+
await client.set_project_settings_document(
|
|
259
|
+
resolved_project_id,
|
|
260
|
+
"room_roles",
|
|
261
|
+
{"roles": spec.model_dump(mode="json", exclude_none=True)["roles"]},
|
|
262
|
+
)
|
|
263
|
+
print(f"[green]Room role override updated:[/] {resolved_project_id}")
|
|
264
|
+
finally:
|
|
265
|
+
await client.close()
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
@app.async_command(
|
|
269
|
+
"reset-room-roles",
|
|
270
|
+
help="Remove the project room-role override and restore built-in defaults.",
|
|
271
|
+
)
|
|
272
|
+
async def reset_room_roles(project_id: ProjectIdOption):
|
|
273
|
+
client = await get_client()
|
|
274
|
+
try:
|
|
275
|
+
resolved_project_id = await resolve_project_id(project_id)
|
|
276
|
+
await client.delete_project_settings_document(
|
|
277
|
+
resolved_project_id,
|
|
278
|
+
"room_roles",
|
|
279
|
+
)
|
|
280
|
+
print(f"[green]Room role defaults restored:[/] {resolved_project_id}")
|
|
281
|
+
finally:
|
|
282
|
+
await client.close()
|
|
283
|
+
|
|
284
|
+
|
|
212
285
|
@app.async_command(
|
|
213
286
|
"activate", help="Set the active project for subsequent CLI commands."
|
|
214
287
|
)
|
|
@@ -17,6 +17,8 @@ class _FakeClient:
|
|
|
17
17
|
self._project_rows = list(project_rows)
|
|
18
18
|
self._created_project_id = created_project_id
|
|
19
19
|
self.created_project_names: list[str] = []
|
|
20
|
+
self.settings_documents: dict[str, dict] = {}
|
|
21
|
+
self.deleted_settings_documents: list[str] = []
|
|
20
22
|
self.closed = False
|
|
21
23
|
|
|
22
24
|
async def list_projects(self) -> ProjectsPage:
|
|
@@ -48,6 +50,16 @@ class _FakeClient:
|
|
|
48
50
|
self._project_rows.append(created_row)
|
|
49
51
|
return ProjectInfo.model_validate(created_row)
|
|
50
52
|
|
|
53
|
+
async def set_project_settings_document(
|
|
54
|
+
self, project_id: str, name: str, document: dict
|
|
55
|
+
):
|
|
56
|
+
self.settings_documents[name] = document
|
|
57
|
+
return {}
|
|
58
|
+
|
|
59
|
+
async def delete_project_settings_document(self, project_id: str, name: str):
|
|
60
|
+
self.deleted_settings_documents.append(name)
|
|
61
|
+
return {}
|
|
62
|
+
|
|
51
63
|
async def close(self) -> None:
|
|
52
64
|
self.closed = True
|
|
53
65
|
|
|
@@ -375,3 +387,87 @@ async def test_activate_prints_cancel_message_when_tui_is_canceled(monkeypatch)
|
|
|
375
387
|
assert active_project_calls == []
|
|
376
388
|
assert output == ["Project activation canceled."]
|
|
377
389
|
assert client.closed is True
|
|
390
|
+
|
|
391
|
+
|
|
392
|
+
@pytest.mark.asyncio
|
|
393
|
+
async def test_set_room_roles_writes_dedicated_document(monkeypatch, tmp_path) -> None:
|
|
394
|
+
client = _FakeClient(
|
|
395
|
+
[
|
|
396
|
+
{
|
|
397
|
+
"id": "project-1",
|
|
398
|
+
"name": "Alpha",
|
|
399
|
+
}
|
|
400
|
+
]
|
|
401
|
+
)
|
|
402
|
+
spec = tmp_path / "room-roles.yaml"
|
|
403
|
+
spec.write_text(
|
|
404
|
+
"""version: v1
|
|
405
|
+
kind: RoomRoles
|
|
406
|
+
roles:
|
|
407
|
+
guest:
|
|
408
|
+
participant:
|
|
409
|
+
api:
|
|
410
|
+
messaging:
|
|
411
|
+
broadcast: false
|
|
412
|
+
list: true
|
|
413
|
+
send: false
|
|
414
|
+
site_user: false
|
|
415
|
+
"""
|
|
416
|
+
)
|
|
417
|
+
|
|
418
|
+
async def _fake_get_client():
|
|
419
|
+
return client
|
|
420
|
+
|
|
421
|
+
async def _fake_resolve_project_id(project_id=None):
|
|
422
|
+
return project_id or "project-1"
|
|
423
|
+
|
|
424
|
+
monkeypatch.setattr(projects, "get_client", _fake_get_client)
|
|
425
|
+
monkeypatch.setattr(projects, "resolve_project_id", _fake_resolve_project_id)
|
|
426
|
+
|
|
427
|
+
await projects.set_room_roles(file=spec, project_id="project-1")
|
|
428
|
+
|
|
429
|
+
assert client.settings_documents == {
|
|
430
|
+
"room_roles": {
|
|
431
|
+
"roles": {
|
|
432
|
+
"guest": {
|
|
433
|
+
"participant": {
|
|
434
|
+
"api": {
|
|
435
|
+
"messaging": {
|
|
436
|
+
"broadcast": False,
|
|
437
|
+
"list": True,
|
|
438
|
+
"send": False,
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
},
|
|
442
|
+
"site_user": False,
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
},
|
|
446
|
+
}
|
|
447
|
+
assert client.closed is True
|
|
448
|
+
|
|
449
|
+
|
|
450
|
+
@pytest.mark.asyncio
|
|
451
|
+
async def test_reset_room_roles_deletes_dedicated_document(monkeypatch) -> None:
|
|
452
|
+
client = _FakeClient(
|
|
453
|
+
[
|
|
454
|
+
{
|
|
455
|
+
"id": "project-1",
|
|
456
|
+
"name": "Alpha",
|
|
457
|
+
}
|
|
458
|
+
]
|
|
459
|
+
)
|
|
460
|
+
|
|
461
|
+
async def _fake_get_client():
|
|
462
|
+
return client
|
|
463
|
+
|
|
464
|
+
async def _fake_resolve_project_id(project_id=None):
|
|
465
|
+
return project_id or "project-1"
|
|
466
|
+
|
|
467
|
+
monkeypatch.setattr(projects, "get_client", _fake_get_client)
|
|
468
|
+
monkeypatch.setattr(projects, "resolve_project_id", _fake_resolve_project_id)
|
|
469
|
+
|
|
470
|
+
await projects.reset_room_roles(project_id="project-1")
|
|
471
|
+
|
|
472
|
+
assert client.deleted_settings_documents == ["room_roles"]
|
|
473
|
+
assert client.closed is True
|
|
@@ -29,6 +29,11 @@ app.add_lazy_command(
|
|
|
29
29
|
module="meshagent.cli.storage",
|
|
30
30
|
help="Manage storage for a room",
|
|
31
31
|
)
|
|
32
|
+
app.add_lazy_command(
|
|
33
|
+
name="mounts",
|
|
34
|
+
module="meshagent.cli.mounts",
|
|
35
|
+
help="List storage mounts currently ready in a room",
|
|
36
|
+
)
|
|
32
37
|
app.add_lazy_command(
|
|
33
38
|
name="service",
|
|
34
39
|
module="meshagent.cli.room_services",
|