meshagent-cli 0.41.7__tar.gz → 0.42.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.
Files changed (143) hide show
  1. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/PKG-INFO +16 -16
  2. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/agents.py +1 -1
  3. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/api_keys.py +2 -2
  4. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/api_keys_test.py +4 -4
  5. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/ask.py +1 -1
  6. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/ask_test.py +20 -10
  7. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/cli_test.py +1 -1
  8. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/containers.py +2 -1
  9. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/containers_test.py +7 -2
  10. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/create.py +1 -1
  11. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/create_test.py +96 -6
  12. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/dataset.py +45 -0
  13. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/feeds.py +4 -4
  14. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/image.py +467 -83
  15. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/image_test.py +567 -37
  16. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/llm.py +4 -4
  17. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/mailboxes.py +4 -4
  18. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/memory.py +1 -0
  19. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/meshagent_images.py +3 -1
  20. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/meshagent_images_test.py +28 -0
  21. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/projects.py +48 -15
  22. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/projects_test.py +46 -1
  23. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/registry.py +4 -4
  24. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/rooms.py +39 -8
  25. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/rooms_test.py +87 -0
  26. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/routes.py +4 -4
  27. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/services.py +4 -4
  28. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/services_test.py +8 -8
  29. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/sessions.py +2 -2
  30. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/sessions_test.py +8 -2
  31. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/storage.py +3 -3
  32. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/subscriptions.py +4 -4
  33. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/sync.py +2 -2
  34. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/tui/deploy_room.py +139 -13
  35. meshagent_cli-0.42.0/meshagent/cli/tui/deploy_room_test.py +272 -0
  36. meshagent_cli-0.42.0/meshagent/cli/version.py +1 -0
  37. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/webhook.py +21 -0
  38. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent_cli.egg-info/PKG-INFO +16 -16
  39. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent_cli.egg-info/requires.txt +15 -15
  40. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/pyproject.toml +15 -15
  41. meshagent_cli-0.41.7/meshagent/cli/tui/deploy_room_test.py +0 -61
  42. meshagent_cli-0.41.7/meshagent/cli/version.py +0 -1
  43. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/LICENSE +0 -0
  44. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/README.md +0 -0
  45. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/__init__.py +0 -0
  46. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/agent.py +0 -0
  47. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/agent_cli_options_test.py +0 -0
  48. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/agent_package_cli.py +0 -0
  49. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/agent_package_cli_test.py +0 -0
  50. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/agents_test.py +0 -0
  51. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/async_typer.py +0 -0
  52. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/async_typer_test.py +0 -0
  53. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/auth.py +0 -0
  54. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/auth_async.py +0 -0
  55. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/auth_async_test.py +0 -0
  56. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/auth_test.py +0 -0
  57. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/call.py +0 -0
  58. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/chatbot.py +0 -0
  59. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/cli.py +0 -0
  60. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/cli_mcp.py +0 -0
  61. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/cli_secrets.py +0 -0
  62. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/common_options.py +0 -0
  63. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/config.py +0 -0
  64. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/config_test.py +0 -0
  65. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/create_project_templates/__init__.py +0 -0
  66. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/create_project_templates/python/backend-agent/server.py +0 -0
  67. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/create_project_templates/python/contact-form/server.py +0 -0
  68. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/create_project_templates/python/webserver/server.py +0 -0
  69. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/dataset_test.py +0 -0
  70. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/developer.py +0 -0
  71. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/developer_test.py +0 -0
  72. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/doctor.py +0 -0
  73. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/doctor_dockerfiles/__init__.py +0 -0
  74. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/doctor_templates/__init__.py +0 -0
  75. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/doctor_test.py +0 -0
  76. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/helper.py +0 -0
  77. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/helper_test.py +0 -0
  78. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/helpers.py +0 -0
  79. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/host.py +0 -0
  80. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/launch.py +0 -0
  81. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/launch_test.py +0 -0
  82. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/llm_test.py +0 -0
  83. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/local_settings.py +0 -0
  84. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/local_settings_test.py +0 -0
  85. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/mailbot.py +0 -0
  86. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/mailbot_test.py +0 -0
  87. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/meeting_transcriber.py +0 -0
  88. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/memory_test.py +0 -0
  89. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/messaging.py +0 -0
  90. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/multi.py +0 -0
  91. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/oauth2.py +0 -0
  92. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/oauth2_test.py +0 -0
  93. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/oci_archive.py +0 -0
  94. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/oci_archive_test.py +0 -0
  95. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/participant_token.py +0 -0
  96. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/port.py +0 -0
  97. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/port_test.py +0 -0
  98. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/preamble_rules.py +0 -0
  99. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/preamble_rules_test.py +0 -0
  100. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/process.py +0 -0
  101. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/process_live_test.py +0 -0
  102. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/process_test.py +0 -0
  103. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/queue.py +0 -0
  104. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/queue_test.py +0 -0
  105. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/registry_test.py +0 -0
  106. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/room.py +0 -0
  107. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/room_connect.py +0 -0
  108. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/room_connect_test.py +0 -0
  109. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/room_services.py +0 -0
  110. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/root_commands.py +0 -0
  111. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/root_commands_test.py +0 -0
  112. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/scheduled_tasks.py +0 -0
  113. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/scheduled_tasks_test.py +0 -0
  114. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/storage_test.py +0 -0
  115. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/sync_test.py +0 -0
  116. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/task_runner.py +0 -0
  117. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/task_runner_test.py +0 -0
  118. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/test.py +0 -0
  119. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/tool_call_summary.py +0 -0
  120. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/tool_call_summary_test.py +0 -0
  121. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/tool_integrations.py +0 -0
  122. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/tool_integrations_test.py +0 -0
  123. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/tui/__init__.py +0 -0
  124. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/tui/auth_switch.py +0 -0
  125. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/tui/auth_switch_test.py +0 -0
  126. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/tui/create.py +0 -0
  127. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/tui/project_activate.py +0 -0
  128. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/tui/project_activate_test.py +0 -0
  129. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/tui/setup.py +0 -0
  130. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/tui/setup_splash_frames.py +0 -0
  131. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/tui/setup_test.py +0 -0
  132. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/version_check.py +0 -0
  133. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/version_check_test.py +0 -0
  134. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/voicebot.py +0 -0
  135. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/webserver.py +0 -0
  136. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/webserver_test.py +0 -0
  137. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/worker.py +0 -0
  138. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent/cli/worker_test.py +0 -0
  139. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent_cli.egg-info/SOURCES.txt +0 -0
  140. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent_cli.egg-info/dependency_links.txt +0 -0
  141. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent_cli.egg-info/entry_points.txt +0 -0
  142. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/meshagent_cli.egg-info/top_level.txt +0 -0
  143. {meshagent_cli-0.41.7 → meshagent_cli-0.42.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: meshagent-cli
3
- Version: 0.41.7
3
+ Version: 0.42.0
4
4
  Summary: CLI for Meshagent
5
5
  License-Expression: Apache-2.0
6
6
  Project-URL: Documentation, https://docs.meshagent.com
@@ -22,7 +22,7 @@ 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.41.7
25
+ Requires-Dist: meshagent-llm-proxy==0.42.0
26
26
  Requires-Dist: rich~=14.3.0
27
27
  Requires-Dist: sounddevice~=0.5
28
28
  Requires-Dist: textual<9.0,>=8.2.3
@@ -30,23 +30,23 @@ Requires-Dist: prompt-toolkit~=3.0.52
30
30
  Requires-Dist: ascii-magic~=2.3
31
31
  Requires-Dist: pillow~=11.3.0
32
32
  Provides-Extra: all
33
- Requires-Dist: meshagent-agents[all]==0.41.7; extra == "all"
34
- Requires-Dist: meshagent-api[all]==0.41.7; extra == "all"
35
- Requires-Dist: meshagent-commoncrawl==0.41.7; extra == "all"
36
- Requires-Dist: meshagent-scrapy==0.41.7; extra == "all"
37
- Requires-Dist: meshagent-computers==0.41.7; extra == "all"
38
- Requires-Dist: meshagent-openai==0.41.7; extra == "all"
39
- Requires-Dist: meshagent-anthropic==0.41.7; extra == "all"
40
- Requires-Dist: meshagent-otel==0.41.7; extra == "all"
41
- Requires-Dist: meshagent-mcp==0.41.7; extra == "all"
42
- Requires-Dist: meshagent-tools==0.41.7; extra == "all"
33
+ Requires-Dist: meshagent-agents[all]==0.42.0; extra == "all"
34
+ Requires-Dist: meshagent-api[all]==0.42.0; extra == "all"
35
+ Requires-Dist: meshagent-commoncrawl==0.42.0; extra == "all"
36
+ Requires-Dist: meshagent-scrapy==0.42.0; extra == "all"
37
+ Requires-Dist: meshagent-computers==0.42.0; extra == "all"
38
+ Requires-Dist: meshagent-openai==0.42.0; extra == "all"
39
+ Requires-Dist: meshagent-anthropic==0.42.0; extra == "all"
40
+ Requires-Dist: meshagent-otel==0.42.0; extra == "all"
41
+ Requires-Dist: meshagent-mcp==0.42.0; extra == "all"
42
+ Requires-Dist: meshagent-tools==0.42.0; extra == "all"
43
43
  Requires-Dist: supabase-auth~=2.28.0; extra == "all"
44
44
  Requires-Dist: prompt-toolkit~=3.0.52; extra == "all"
45
45
  Provides-Extra: mcp-service
46
- Requires-Dist: meshagent-agents[all]==0.41.7; extra == "mcp-service"
47
- Requires-Dist: meshagent-api==0.41.7; extra == "mcp-service"
48
- Requires-Dist: meshagent-mcp==0.41.7; extra == "mcp-service"
49
- Requires-Dist: meshagent-tools==0.41.7; extra == "mcp-service"
46
+ Requires-Dist: meshagent-agents[all]==0.42.0; extra == "mcp-service"
47
+ Requires-Dist: meshagent-api==0.42.0; extra == "mcp-service"
48
+ Requires-Dist: meshagent-mcp==0.42.0; extra == "mcp-service"
49
+ Requires-Dist: meshagent-tools==0.42.0; extra == "mcp-service"
50
50
  Requires-Dist: supabase-auth~=2.28.0; extra == "mcp-service"
51
51
  Dynamic: license-file
52
52
 
@@ -644,7 +644,7 @@ async def agent_list_command(
644
644
  await account_client.close()
645
645
 
646
646
 
647
- @app.async_command("get", help="Show a managed agent configuration.")
647
+ @app.async_command("get", help="Get a managed agent configuration.")
648
648
  async def agent_get_command(
649
649
  *,
650
650
  project_id: ProjectIdOption,
@@ -123,8 +123,8 @@ async def create(
123
123
  )
124
124
 
125
125
 
126
- @app.async_command("show", help="Show the activated API key for a project.")
127
- async def show(*, project_id: ProjectIdOption):
126
+ @app.async_command("get", help="Get the activated API key for a project.")
127
+ async def get(*, project_id: ProjectIdOption):
128
128
  key = await _require_active_api_key(project_id=project_id)
129
129
  typer.echo(key)
130
130
 
@@ -91,7 +91,7 @@ async def test_list_marks_activated_api_key_in_table_output(
91
91
 
92
92
 
93
93
  @pytest.mark.asyncio
94
- async def test_show_prints_activated_api_key(
94
+ async def test_get_prints_activated_api_key(
95
95
  monkeypatch: pytest.MonkeyPatch,
96
96
  ) -> None:
97
97
  printed: list[str] = []
@@ -108,7 +108,7 @@ async def test_show_prints_activated_api_key(
108
108
  monkeypatch.setattr(api_keys, "get_active_api_key", fake_get_active_api_key)
109
109
  monkeypatch.setattr(api_keys.typer, "echo", printed.append)
110
110
 
111
- await api_keys.show(project_id="project-1")
111
+ await api_keys.get(project_id="project-1")
112
112
 
113
113
  assert printed == ["ma-key-1"]
114
114
 
@@ -137,7 +137,7 @@ async def test_env_prints_shell_export_for_activated_api_key(
137
137
 
138
138
 
139
139
  @pytest.mark.asyncio
140
- async def test_show_exits_when_no_activated_api_key(
140
+ async def test_get_exits_when_no_activated_api_key(
141
141
  monkeypatch: pytest.MonkeyPatch,
142
142
  ) -> None:
143
143
  printed: list[str] = []
@@ -155,7 +155,7 @@ async def test_show_exits_when_no_activated_api_key(
155
155
  monkeypatch.setattr(api_keys, "print", printed.append)
156
156
 
157
157
  with pytest.raises(typer.Exit) as exc_info:
158
- await api_keys.show(project_id="project-1")
158
+ await api_keys.get(project_id="project-1")
159
159
 
160
160
  assert exc_info.value.exit_code == 1
161
161
  assert printed == [
@@ -3891,7 +3891,7 @@ async def ask(
3891
3891
  help="Output format for non-interactive responses.",
3892
3892
  case_sensitive=False,
3893
3893
  ),
3894
- ] = "text",
3894
+ ] = "markdown",
3895
3895
  model: Annotated[
3896
3896
  str,
3897
3897
  typer.Option("--model", help="Name of the LLM model to use"),
@@ -1227,9 +1227,11 @@ async def test_resolve_ask_access_token_prefers_meshagent_token(monkeypatch) ->
1227
1227
 
1228
1228
 
1229
1229
  @pytest.mark.asyncio
1230
- async def test_ask_command_uses_oauth_token_and_prints_result(monkeypatch) -> None:
1230
+ async def test_ask_command_uses_oauth_token_and_renders_markdown_by_default(
1231
+ monkeypatch,
1232
+ ) -> None:
1231
1233
  captured: dict[str, object] = {}
1232
- printed: list[tuple[tuple[object, ...], dict[str, object]]] = []
1234
+ rendered: list[object] = []
1233
1235
 
1234
1236
  async def _fake_get_access_token() -> str:
1235
1237
  return "oauth-token"
@@ -1255,10 +1257,19 @@ async def test_ask_command_uses_oauth_token_and_prints_result(monkeypatch) -> No
1255
1257
  monkeypatch.setattr(ask_module, "resolve_project_id", _fake_resolve_project_id)
1256
1258
  monkeypatch.setattr(ask_module, "_build_ask_adapter", _fake_build_ask_adapter)
1257
1259
 
1258
- def _fake_echo(*args: object, **kwargs: object) -> None:
1259
- printed.append((args, dict(kwargs)))
1260
+ class _FakeConsole:
1261
+ def print(self, value: object) -> None:
1262
+ rendered.append(value)
1260
1263
 
1261
- monkeypatch.setattr(ask_module.click, "echo", _fake_echo)
1264
+ monkeypatch.setattr(ask_module, "Console", _FakeConsole)
1265
+ monkeypatch.setattr(ask_module, "Markdown", lambda text: ("markdown", text))
1266
+ monkeypatch.setattr(
1267
+ ask_module.click,
1268
+ "echo",
1269
+ lambda *args, **kwargs: (_ for _ in ()).throw(
1270
+ AssertionError("streaming output should not be used")
1271
+ ),
1272
+ )
1262
1273
 
1263
1274
  await ask_module.ask(
1264
1275
  project_id="project-123",
@@ -1271,11 +1282,7 @@ async def test_ask_command_uses_oauth_token_and_prints_result(monkeypatch) -> No
1271
1282
  "project_id": "project-123",
1272
1283
  "access_token": "oauth-token",
1273
1284
  }
1274
- assert printed == [
1275
- (("hello",), {"nl": False}),
1276
- ((" world",), {"nl": False}),
1277
- ((), {}),
1278
- ]
1285
+ assert rendered == [("markdown", "hello world")]
1279
1286
 
1280
1287
 
1281
1288
  def test_meshagent_ask_cli_invocation_prints_streamed_response(
@@ -1311,6 +1318,8 @@ def test_meshagent_ask_cli_invocation_prints_streamed_response(
1311
1318
  "project-123",
1312
1319
  "--message",
1313
1320
  "hello",
1321
+ "--format",
1322
+ "text",
1314
1323
  "--model",
1315
1324
  "gpt-5.5",
1316
1325
  ],
@@ -1603,6 +1612,7 @@ async def test_ask_command_prefers_meshagent_token_over_oauth(monkeypatch) -> No
1603
1612
  await ask_module.ask(
1604
1613
  project_id="project-123",
1605
1614
  message="hello",
1615
+ format="text",
1606
1616
  model="gpt-5.5",
1607
1617
  )
1608
1618
 
@@ -121,7 +121,7 @@ def test_agent_help_lists_command_descriptions() -> None:
121
121
  assert "│ delete Delete a managed agent from the project." in result.output
122
122
  assert "│ update Update a managed agent configuration." in result.output
123
123
  assert "│ list List managed agents in the project." in result.output
124
- assert "│ get Show a managed agent configuration." in result.output
124
+ assert "│ get Get a managed agent configuration." in result.output
125
125
 
126
126
 
127
127
  def test_room_agents_call_help_lists_call_targets() -> None:
@@ -30,6 +30,7 @@ from meshagent.cli.helper import (
30
30
  split_container_mount,
31
31
  split_image_mount,
32
32
  )
33
+ from meshagent.api.helpers import websocket_room_url
33
34
  from meshagent.api import (
34
35
  RoomClient,
35
36
  WebSocketClientProtocol,
@@ -555,7 +556,7 @@ async def _with_client(
555
556
  connection = await account_client.connect_room(project_id=project_id, room=room)
556
557
 
557
558
  proto = WebSocketClientProtocol(
558
- url=connection.room_url,
559
+ url=websocket_room_url(room_name=room),
559
560
  token=connection.jwt,
560
561
  )
561
562
  client_cm = RoomClient(protocol_factory=proto.create_factory())
@@ -522,7 +522,7 @@ async def test_images_inspect_renders_detail_tables(
522
522
 
523
523
 
524
524
  @pytest.mark.asyncio
525
- async def test_with_client_uses_room_url_from_connection_info(
525
+ async def test_with_client_uses_configured_websocket_room_url(
526
526
  monkeypatch: pytest.MonkeyPatch,
527
527
  ) -> None:
528
528
  connection = SimpleNamespace(
@@ -560,6 +560,11 @@ async def test_with_client_uses_room_url_from_connection_info(
560
560
  monkeypatch.setattr(containers, "get_client", _fake_get_client)
561
561
  monkeypatch.setattr(containers, "resolve_project_id", _fake_resolve_project_id)
562
562
  monkeypatch.setattr(containers, "resolve_room", lambda room: f"{room}-resolved")
563
+ monkeypatch.setattr(
564
+ containers,
565
+ "websocket_room_url",
566
+ lambda room_name: f"wss://configured-router/{room_name}",
567
+ )
563
568
  monkeypatch.setattr(containers, "WebSocketClientProtocol", _FakeProtocol)
564
569
  monkeypatch.setattr(containers, "RoomClient", _FakeRoomClient)
565
570
 
@@ -574,7 +579,7 @@ async def test_with_client_uses_room_url_from_connection_info(
574
579
  ]
575
580
  assert protocol_calls == [
576
581
  {
577
- "url": "wss://room-router.meshagent.dev/custom/room-endpoint",
582
+ "url": "wss://configured-router/room-1-resolved",
578
583
  "token": "jwt-token",
579
584
  }
580
585
  ]
@@ -129,7 +129,7 @@ NPM_CHATBOT_UI_NEXT_STEPS = (
129
129
  )
130
130
  CONTACT_FORM_NEXT_STEPS = (
131
131
  "./scripts/install.sh",
132
- "meshagent rooms create --name <room> --if-not-exists",
132
+ "meshagent rooms create <room> --if-not-exists",
133
133
  "./scripts/dev.sh --room <room>",
134
134
  "CONTACT_FORM_TO=you@example.com ./scripts/deploy.sh --room <room>",
135
135
  )
@@ -2,11 +2,46 @@ from __future__ import annotations
2
2
 
3
3
  from click.testing import CliRunner
4
4
 
5
+ from meshagent.api.specs.service import ServiceTemplateSpec
5
6
  from meshagent.cli import create as create_module
6
7
  from meshagent.cli.doctor import diagnose_project
7
8
  from meshagent.cli.create import create_command
8
9
 
9
10
 
11
+ def _assert_runtime_image_mount_deploy_yaml(
12
+ project_path,
13
+ *,
14
+ runtime: str,
15
+ command: str,
16
+ ) -> ServiceTemplateSpec:
17
+ deploy_yaml = (project_path / ".meshagent" / "deploy.yaml").read_text(
18
+ encoding="utf-8"
19
+ )
20
+ spec = ServiceTemplateSpec.from_yaml(
21
+ deploy_yaml,
22
+ values={
23
+ "image": "registry.example.com/test-app:dev",
24
+ "from_email": "from@example.com",
25
+ "to_email": "to@example.com",
26
+ },
27
+ )
28
+
29
+ assert spec.container is not None
30
+ container = spec.container
31
+ assert container.image == f"meshagent/{runtime}:default"
32
+ assert container.command == command
33
+ assert container.working_dir == "/app"
34
+ assert container.storage is not None
35
+ assert container.storage.images is not None
36
+ assert len(container.storage.images) == 1
37
+ image_mount = container.storage.images[0]
38
+ assert image_mount.image == "registry.example.com/test-app:dev"
39
+ assert image_mount.path == "/app"
40
+ assert image_mount.subpath == "app"
41
+ assert image_mount.read_only is True
42
+ return spec
43
+
44
+
10
45
  def _assert_node_content_toolkit(
11
46
  source: str,
12
47
  *,
@@ -133,6 +168,11 @@ def test_init_creates_python_backend_agent_by_default_in_non_tty(tmp_path) -> No
133
168
  assert "LABEL meshagent.runtime=python" in dockerfile
134
169
  assert 'CMD ["-m", "server"]' in dockerfile
135
170
  assert "EXPOSE" not in dockerfile
171
+ _assert_runtime_image_mount_deploy_yaml(
172
+ tmp_path,
173
+ runtime="python",
174
+ command="python -m server",
175
+ )
136
176
  assert 'PYTHON="${PYTHON:-python3.13}"' in install_sh
137
177
  assert 'VENV="${VENV:-.venv}"' in install_sh
138
178
  assert 'PIP_ONLY_BINARY="${PIP_ONLY_BINARY:-:all:}"' in install_sh
@@ -284,6 +324,11 @@ def test_init_creates_python_webserver_non_interactively(tmp_path) -> None:
284
324
  assert "FROM scratch" in dockerfile
285
325
  assert "LABEL meshagent.runtime=python" in dockerfile
286
326
  assert "EXPOSE 8000" in dockerfile
327
+ _assert_runtime_image_mount_deploy_yaml(
328
+ tmp_path,
329
+ runtime="python",
330
+ command="python -m server",
331
+ )
287
332
  assert 'PYTHON="${PYTHON:-python3.13}"' in install_sh
288
333
  assert 'VENV="${VENV:-.venv}"' in install_sh
289
334
  assert 'PIP_ONLY_BINARY="${PIP_ONLY_BINARY:-:all:}"' in install_sh
@@ -317,7 +362,7 @@ def test_init_creates_python_contact_form_non_interactively(tmp_path) -> None:
317
362
  assert "2. Create room" in result.output
318
363
  assert "3. Run locally" in result.output
319
364
  assert "4. Deploy" in result.output
320
- assert "meshagent rooms create --name <room> --if-not-exists" in result.output
365
+ assert "meshagent rooms create <room> --if-not-exists" in result.output
321
366
  assert (
322
367
  "Before testing a submission, set up the sender mailbox for that room"
323
368
  in result.output
@@ -354,7 +399,7 @@ def test_init_creates_python_contact_form_non_interactively(tmp_path) -> None:
354
399
  deploy_yaml = (tmp_path / ".meshagent" / "deploy.yaml").read_text(encoding="utf-8")
355
400
 
356
401
  assert "Python Contact Form" in readme
357
- assert "meshagent rooms create --name <room> --if-not-exists" in readme
402
+ assert "meshagent rooms create <room> --if-not-exists" in readme
358
403
  assert "./scripts/dev.sh --room <room>" in readme
359
404
  assert "CONTACT_FORM_TO=you@example.com ./scripts/deploy.sh --room <room>" in readme
360
405
  assert (
@@ -389,6 +434,11 @@ def test_init_creates_python_contact_form_non_interactively(tmp_path) -> None:
389
434
  assert "FROM scratch" in dockerfile
390
435
  assert "LABEL meshagent.runtime=python" in dockerfile
391
436
  assert "EXPOSE 8000" in dockerfile
437
+ _assert_runtime_image_mount_deploy_yaml(
438
+ tmp_path,
439
+ runtime="python",
440
+ command="python -m server",
441
+ )
392
442
  assert 'PYTHON="${PYTHON:-python3.13}"' in install_sh
393
443
  assert 'VENV="${VENV:-.venv}"' in install_sh
394
444
  assert 'PIP_ONLY_BINARY="${PIP_ONLY_BINARY:-:all:}"' in install_sh
@@ -403,13 +453,13 @@ def test_init_creates_python_contact_form_non_interactively(tmp_path) -> None:
403
453
  assert "CONTACT_FORM_OPEN_BROWSER" in dev_sh
404
454
  assert "CONTACT_FORM_OPEN_BROWSER_PROMPT" not in dev_sh
405
455
  assert "read -r OPEN_BROWSER_ANSWER" not in dev_sh
406
- assert 'meshagent rooms create --name "$ROOM_NAME" --if-not-exists' in dev_sh
456
+ assert 'meshagent rooms create "$ROOM_NAME" --if-not-exists' in dev_sh
407
457
  assert 'meshagent room connect "$@" -- "$VENV_PYTHON" -u server.py' in dev_sh
408
458
  assert 'if [ "$status" -eq 130 ] || [ "$status" -eq 143 ]; then' in dev_sh
409
459
  assert "Stopped contact form." in dev_sh
410
460
  assert "If the room does not exist yet, create it first:" in dev_sh
411
- assert "meshagent rooms create --name <room> --if-not-exists" in dev_sh
412
- assert 'meshagent rooms create --name "$ROOM_NAME" --if-not-exists' not in deploy_sh
461
+ assert "meshagent rooms create <room> --if-not-exists" in dev_sh
462
+ assert 'meshagent rooms create "$ROOM_NAME" --if-not-exists' not in deploy_sh
413
463
  assert "--meshagent-token agentDefault" in deploy_sh
414
464
  assert '--set "from_email=$CONTACT_FORM_FROM"' in deploy_sh
415
465
  assert '--set "to_email=$CONTACT_FORM_TO"' in deploy_sh
@@ -497,6 +547,11 @@ def test_init_creates_javascript_webserver_non_interactively(tmp_path) -> None:
497
547
  assert "FROM scratch" in dockerfile_text
498
548
  assert "LABEL meshagent.runtime=node" in dockerfile_text
499
549
  assert "EXPOSE 3000" in dockerfile_text
550
+ _assert_runtime_image_mount_deploy_yaml(
551
+ tmp_path,
552
+ runtime="node",
553
+ command="node index.js",
554
+ )
500
555
 
501
556
 
502
557
  def test_init_creates_javascript_backend_agent_non_interactively(tmp_path) -> None:
@@ -547,6 +602,11 @@ def test_init_creates_javascript_backend_agent_non_interactively(tmp_path) -> No
547
602
  assert "FROM scratch" in dockerfile
548
603
  assert "LABEL meshagent.runtime=node" in dockerfile
549
604
  assert "EXPOSE" not in dockerfile
605
+ _assert_runtime_image_mount_deploy_yaml(
606
+ tmp_path,
607
+ runtime="node",
608
+ command="node index.js",
609
+ )
550
610
 
551
611
 
552
612
  def test_init_creates_typescript_webserver_non_interactively(tmp_path) -> None:
@@ -609,6 +669,11 @@ def test_init_creates_typescript_webserver_non_interactively(tmp_path) -> None:
609
669
  assert "FROM scratch" in dockerfile_text
610
670
  assert "LABEL meshagent.runtime=node" in dockerfile_text
611
671
  assert "EXPOSE 3000" in dockerfile_text
672
+ _assert_runtime_image_mount_deploy_yaml(
673
+ tmp_path,
674
+ runtime="node",
675
+ command="node index.js",
676
+ )
612
677
  assert diagnosis.language == "TypeScript"
613
678
  assert diagnosis.javascript_flavor == "Node.js/TypeScript"
614
679
  assert diagnosis.sdk == "@meshagent/meshagent"
@@ -661,6 +726,11 @@ def test_init_creates_typescript_backend_agent_non_interactively(tmp_path) -> No
661
726
  assert "FROM scratch" in dockerfile
662
727
  assert "LABEL meshagent.runtime=node" in dockerfile
663
728
  assert "EXPOSE" not in dockerfile
729
+ _assert_runtime_image_mount_deploy_yaml(
730
+ tmp_path,
731
+ runtime="node",
732
+ command="node index.js",
733
+ )
664
734
  assert diagnosis.language == "TypeScript"
665
735
  assert diagnosis.javascript_flavor == "Node.js/TypeScript"
666
736
  assert diagnosis.sdk == "@meshagent/meshagent"
@@ -727,6 +797,11 @@ def test_init_creates_typescript_chatbot_non_interactively(tmp_path) -> None:
727
797
  assert "FROM scratch" in dockerfile
728
798
  assert "LABEL meshagent.runtime=node" in dockerfile
729
799
  assert "EXPOSE 3000" in dockerfile
800
+ _assert_runtime_image_mount_deploy_yaml(
801
+ tmp_path,
802
+ runtime="node",
803
+ command="node index.js",
804
+ )
730
805
  assert diagnosis.language == "TypeScript"
731
806
  assert diagnosis.javascript_flavor == "Node.js/TypeScript"
732
807
  assert diagnosis.sdk is None
@@ -804,6 +879,11 @@ def test_init_creates_typescript_anthropic_chatbot_non_interactively(
804
879
  assert "FROM scratch" in dockerfile
805
880
  assert "LABEL meshagent.runtime=node" in dockerfile
806
881
  assert "EXPOSE 3000" in dockerfile
882
+ _assert_runtime_image_mount_deploy_yaml(
883
+ tmp_path,
884
+ runtime="node",
885
+ command="node index.js",
886
+ )
807
887
  assert diagnosis.language == "TypeScript"
808
888
  assert diagnosis.javascript_flavor == "Node.js/TypeScript"
809
889
  assert diagnosis.sdk is None
@@ -966,7 +1046,7 @@ def test_init_creates_typescript_chatbot_ui_non_interactively(tmp_path) -> None:
966
1046
  assert '"build": "next build"' in package_json
967
1047
  assert '"start": "node .next/standalone/server.js"' in package_json
968
1048
  assert (
969
- '"deploy": "meshagent deploy . --tag meshagent-create-typescript-chatbot-ui:dev --private --validation-mode=cookie --extra-port=3001:/messages --liveness /health --wait"'
1049
+ '"deploy": "meshagent deploy . --tag meshagent-create-typescript-chatbot-ui:dev --private --validation-mode=cookie --extra-port=assistant:/messages --liveness /health --wait"'
970
1050
  in package_json
971
1051
  )
972
1052
  assert 'from "@msgpack/msgpack"' in page_tsx
@@ -983,6 +1063,16 @@ def test_init_creates_typescript_chatbot_ui_non_interactively(tmp_path) -> None:
983
1063
  assert 'CMD ["server.js"]' in dockerfile
984
1064
  assert "ENV HOSTNAME=0.0.0.0" in dockerfile
985
1065
  assert "EXPOSE 3000" in dockerfile
1066
+ spec = _assert_runtime_image_mount_deploy_yaml(
1067
+ tmp_path,
1068
+ runtime="node",
1069
+ command="node server.js",
1070
+ )
1071
+ assert spec.container is not None
1072
+ assert spec.container.environment is not None
1073
+ env = {entry.name: entry.value for entry in spec.container.environment}
1074
+ assert env["HOSTNAME"] == "0.0.0.0"
1075
+ assert env["PORT"] == "3000"
986
1076
 
987
1077
 
988
1078
  def test_init_rejects_react_backend_agent(tmp_path) -> None:
@@ -2129,6 +2129,51 @@ async def list_branches(
2129
2129
  await account_client.close()
2130
2130
 
2131
2131
 
2132
+ @branch_app.async_command("get", help="Get a dataset branch.")
2133
+ async def get_branch(
2134
+ *,
2135
+ project_id: ProjectIdOption,
2136
+ room: RoomOption,
2137
+ branch: Annotated[str, typer.Option(..., "--branch", help="Branch name")],
2138
+ namespace: NamespaceOption = None,
2139
+ pretty: Annotated[
2140
+ bool, typer.Option("--pretty/--no-pretty", help="Pretty-print JSON")
2141
+ ] = True,
2142
+ ):
2143
+ account_client = await get_client()
2144
+ try:
2145
+ project_id = await resolve_project_id(project_id=project_id)
2146
+ room_name = resolve_room(room)
2147
+ connection = await account_client.connect_room(
2148
+ project_id=project_id, room=room_name
2149
+ )
2150
+
2151
+ async with RoomClient(
2152
+ protocol_factory=WebSocketClientProtocol(
2153
+ url=websocket_room_url(room_name=room_name),
2154
+ token=connection.jwt,
2155
+ ).create_factory()
2156
+ ) as client:
2157
+ branches = await client.datasets.list_branches(namespace=_ns(namespace))
2158
+ for candidate in branches:
2159
+ if candidate.name == branch:
2160
+ print(
2161
+ _json.dumps(
2162
+ candidate.model_dump(mode="json"),
2163
+ indent=2 if pretty else None,
2164
+ )
2165
+ )
2166
+ return
2167
+ print(f"[red]Branch not found:[/] {branch}")
2168
+ raise typer.Exit(1)
2169
+
2170
+ except RoomException as e:
2171
+ print(e)
2172
+ raise typer.Exit(1)
2173
+ finally:
2174
+ await account_client.close()
2175
+
2176
+
2132
2177
  @branch_app.async_command("create", help="Create a dataset branch.")
2133
2178
  async def create_branch(
2134
2179
  *,
@@ -239,13 +239,13 @@ async def feed_update(
239
239
  await client.close()
240
240
 
241
241
 
242
- @app.async_command("show")
243
- async def feed_show(
242
+ @app.async_command("get")
243
+ async def feed_get(
244
244
  *,
245
245
  project_id: ProjectIdOption,
246
- feed_id: Annotated[str, typer.Argument(help="Feed id to show")],
246
+ feed_id: Annotated[str, typer.Argument(help="Feed id to get")],
247
247
  ):
248
- """Show feed details."""
248
+ """Get feed details."""
249
249
  client = await get_client()
250
250
  try:
251
251
  project_id = await resolve_project_id(project_id)