meshagent-cli 0.47.0__tar.gz → 0.48.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 (172) hide show
  1. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/PKG-INFO +17 -17
  2. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/ask.py +4 -0
  3. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/cli.py +11 -2
  4. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/cli_test.py +43 -0
  5. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/create.py +6 -59
  6. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/create_project_templates/python/contact-form/server.py +12 -2
  7. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/create_test.py +3 -5
  8. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/image.py +134 -37
  9. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/image_test.py +153 -4
  10. meshagent_cli-0.48.0/meshagent/cli/mounts.py +64 -0
  11. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/process.py +40 -21
  12. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/process_live_test.py +6 -7
  13. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/process_test.py +112 -4
  14. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/room.py +5 -0
  15. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/room_connect.py +7 -5
  16. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/room_connect_test.py +6 -24
  17. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/tool_call_summary.py +70 -0
  18. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/tool_call_summary_test.py +34 -0
  19. meshagent_cli-0.48.0/meshagent/cli/version.py +1 -0
  20. meshagent_cli-0.48.0/meshagent/cli/volumes.py +252 -0
  21. meshagent_cli-0.48.0/meshagent/cli/volumes_test.py +31 -0
  22. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent_cli.egg-info/PKG-INFO +17 -17
  23. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent_cli.egg-info/SOURCES.txt +3 -0
  24. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent_cli.egg-info/requires.txt +16 -16
  25. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/pyproject.toml +16 -16
  26. meshagent_cli-0.47.0/meshagent/cli/version.py +0 -1
  27. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/LICENSE +0 -0
  28. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/README.md +0 -0
  29. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/__init__.py +0 -0
  30. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/_filedrop.py +0 -0
  31. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/agent.py +0 -0
  32. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/agent_cli_options_test.py +0 -0
  33. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/agent_package_cli.py +0 -0
  34. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/agent_package_cli_test.py +0 -0
  35. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/agents.py +0 -0
  36. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/agents_test.py +0 -0
  37. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/ask_test.py +0 -0
  38. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/async_typer.py +0 -0
  39. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/async_typer_test.py +0 -0
  40. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/auth.py +0 -0
  41. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/auth_async.py +0 -0
  42. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/auth_async_test.py +0 -0
  43. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/auth_test.py +0 -0
  44. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/call.py +0 -0
  45. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/chatbot.py +0 -0
  46. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/cli_mcp.py +0 -0
  47. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/common_options.py +0 -0
  48. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/config.py +0 -0
  49. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/config_test.py +0 -0
  50. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/containers.py +0 -0
  51. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/containers_test.py +0 -0
  52. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/create_project_templates/__init__.py +0 -0
  53. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/create_project_templates/python/backend-agent/server.py +0 -0
  54. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/create_project_templates/python/slack-channel/channel.py +0 -0
  55. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/create_project_templates/python/slack-channel/scripts/configure-slack.py +0 -0
  56. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/create_project_templates/python/slack-channel/scripts/setup-slack-dev-route.py +0 -0
  57. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/create_project_templates/python/slack-channel/server.py +0 -0
  58. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/create_project_templates/python/task-queue-dashboard/server.py +0 -0
  59. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/create_project_templates/python/telegram-channel/channel.py +0 -0
  60. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/create_project_templates/python/telegram-channel/scripts/configure-telegram.py +0 -0
  61. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/create_project_templates/python/telegram-channel/scripts/create-bot-token.py +0 -0
  62. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/create_project_templates/python/telegram-channel/server.py +0 -0
  63. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/create_project_templates/python/twilio-channel/channel.py +0 -0
  64. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/create_project_templates/python/twilio-channel/server.py +0 -0
  65. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/create_project_templates/python/webserver/server.py +0 -0
  66. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/create_project_templates/python/whatsapp-channel/channel.py +0 -0
  67. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/create_project_templates/python/whatsapp-channel/server.py +0 -0
  68. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/dataset.py +0 -0
  69. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/dataset_test.py +0 -0
  70. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/developer.py +0 -0
  71. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/developer_test.py +0 -0
  72. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/doctor.py +0 -0
  73. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/doctor_dockerfiles/__init__.py +0 -0
  74. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/doctor_templates/__init__.py +0 -0
  75. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/doctor_test.py +0 -0
  76. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/feeds.py +0 -0
  77. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/feeds_test.py +0 -0
  78. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/helper.py +0 -0
  79. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/helper_test.py +0 -0
  80. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/helpers.py +0 -0
  81. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/host.py +0 -0
  82. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/iam.py +0 -0
  83. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/iam_test.py +0 -0
  84. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/launch.py +0 -0
  85. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/launch_test.py +0 -0
  86. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/llm.py +0 -0
  87. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/llm_test.py +0 -0
  88. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/local_settings.py +0 -0
  89. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/local_settings_test.py +0 -0
  90. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/mailbot.py +0 -0
  91. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/mailbot_test.py +0 -0
  92. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/mailboxes.py +0 -0
  93. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/mailboxes_test.py +0 -0
  94. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/meeting_transcriber.py +0 -0
  95. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/memory.py +0 -0
  96. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/memory_test.py +0 -0
  97. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/meshagent_images.py +0 -0
  98. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/meshagent_images_test.py +0 -0
  99. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/messaging.py +0 -0
  100. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/messaging_test.py +0 -0
  101. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/multi.py +0 -0
  102. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/oci_archive.py +0 -0
  103. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/oci_archive_test.py +0 -0
  104. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/participant_token.py +0 -0
  105. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/port.py +0 -0
  106. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/port_test.py +0 -0
  107. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/preamble_rules.py +0 -0
  108. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/preamble_rules_test.py +0 -0
  109. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/projects.py +0 -0
  110. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/projects_test.py +0 -0
  111. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/queue.py +0 -0
  112. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/queue_test.py +0 -0
  113. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/registry.py +0 -0
  114. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/registry_test.py +0 -0
  115. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/room_services.py +0 -0
  116. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/room_services_test.py +0 -0
  117. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/rooms.py +0 -0
  118. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/rooms_test.py +0 -0
  119. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/root_commands.py +0 -0
  120. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/root_commands_test.py +0 -0
  121. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/routes.py +0 -0
  122. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/routes_test.py +0 -0
  123. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/sample_channel_http_test.py +0 -0
  124. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/sample_channel_live_e2e_test.py +0 -0
  125. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/scheduled_tasks.py +0 -0
  126. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/scheduled_tasks_test.py +0 -0
  127. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/secrets.py +0 -0
  128. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/secrets_test.py +0 -0
  129. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/service_accounts.py +0 -0
  130. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/service_accounts_test.py +0 -0
  131. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/services.py +0 -0
  132. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/services_test.py +0 -0
  133. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/sessions.py +0 -0
  134. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/sessions_test.py +0 -0
  135. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/sqlite.py +0 -0
  136. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/sqlite_test.py +0 -0
  137. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/storage.py +0 -0
  138. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/storage_test.py +0 -0
  139. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/subscriptions.py +0 -0
  140. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/sync.py +0 -0
  141. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/sync_test.py +0 -0
  142. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/task_runner.py +0 -0
  143. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/task_runner_test.py +0 -0
  144. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/test.py +0 -0
  145. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/testing.py +0 -0
  146. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/thread_inspect.py +0 -0
  147. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/thread_inspect_test.py +0 -0
  148. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/thread_sidebar.py +0 -0
  149. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/tool_integrations.py +0 -0
  150. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/tool_integrations_test.py +0 -0
  151. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/tui/__init__.py +0 -0
  152. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/tui/auth_switch.py +0 -0
  153. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/tui/auth_switch_test.py +0 -0
  154. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/tui/create.py +0 -0
  155. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/tui/deploy_room.py +0 -0
  156. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/tui/deploy_room_test.py +0 -0
  157. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/tui/project_activate.py +0 -0
  158. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/tui/project_activate_test.py +0 -0
  159. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/tui/setup.py +0 -0
  160. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/tui/setup_splash_frames.py +0 -0
  161. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/tui/setup_test.py +0 -0
  162. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/version_check.py +0 -0
  163. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/version_check_test.py +0 -0
  164. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/voicebot.py +0 -0
  165. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/webserver.py +0 -0
  166. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/webserver_test.py +0 -0
  167. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/worker.py +0 -0
  168. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent/cli/worker_test.py +0 -0
  169. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent_cli.egg-info/dependency_links.txt +0 -0
  170. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent_cli.egg-info/entry_points.txt +0 -0
  171. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/meshagent_cli.egg-info/top_level.txt +0 -0
  172. {meshagent_cli-0.47.0 → meshagent_cli-0.48.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: meshagent-cli
3
- Version: 0.47.0
3
+ Version: 0.48.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.47.0
26
- Requires-Dist: meshagent-codex==0.47.0
25
+ Requires-Dist: meshagent-llm-proxy==0.48.0
26
+ Requires-Dist: meshagent-codex==0.48.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.47.0; extra == "all"
36
- Requires-Dist: meshagent-api[all]==0.47.0; extra == "all"
37
- Requires-Dist: meshagent-commoncrawl==0.47.0; extra == "all"
38
- Requires-Dist: meshagent-scrapy==0.47.0; extra == "all"
39
- Requires-Dist: meshagent-computers==0.47.0; extra == "all"
40
- Requires-Dist: meshagent-openai==0.47.0; extra == "all"
41
- Requires-Dist: meshagent-anthropic==0.47.0; extra == "all"
42
- Requires-Dist: meshagent-otel==0.47.0; extra == "all"
43
- Requires-Dist: meshagent-mcp==0.47.0; extra == "all"
44
- Requires-Dist: meshagent-tools==0.47.0; extra == "all"
35
+ Requires-Dist: meshagent-agents[all]==0.48.0; extra == "all"
36
+ Requires-Dist: meshagent-api[all]==0.48.0; extra == "all"
37
+ Requires-Dist: meshagent-commoncrawl==0.48.0; extra == "all"
38
+ Requires-Dist: meshagent-scrapy==0.48.0; extra == "all"
39
+ Requires-Dist: meshagent-computers==0.48.0; extra == "all"
40
+ Requires-Dist: meshagent-openai==0.48.0; extra == "all"
41
+ Requires-Dist: meshagent-anthropic==0.48.0; extra == "all"
42
+ Requires-Dist: meshagent-otel==0.48.0; extra == "all"
43
+ Requires-Dist: meshagent-mcp==0.48.0; extra == "all"
44
+ Requires-Dist: meshagent-tools==0.48.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.47.0; extra == "mcp-service"
49
- Requires-Dist: meshagent-api==0.47.0; extra == "mcp-service"
50
- Requires-Dist: meshagent-mcp==0.47.0; extra == "mcp-service"
51
- Requires-Dist: meshagent-tools==0.47.0; extra == "mcp-service"
48
+ Requires-Dist: meshagent-agents[all]==0.48.0; extra == "mcp-service"
49
+ Requires-Dist: meshagent-api==0.48.0; extra == "mcp-service"
50
+ Requires-Dist: meshagent-mcp==0.48.0; extra == "mcp-service"
51
+ Requires-Dist: meshagent-tools==0.48.0; extra == "mcp-service"
52
52
  Requires-Dist: supabase-auth~=2.28.0; extra == "mcp-service"
53
53
  Dynamic: license-file
54
54
 
@@ -137,6 +137,7 @@ from meshagent.agents.process import (
137
137
  TurnInstructionsProvider,
138
138
  )
139
139
  from meshagent.api import Participant, RoomException
140
+ from meshagent.api.messaging import Content
140
141
  from meshagent.cli import async_typer, auth_async
141
142
  from meshagent.cli._filedrop import (
142
143
  dropped_file_paths_from_text,
@@ -348,6 +349,7 @@ def _format_ask_tool_call_entry_text(
348
349
  toolkit: str,
349
350
  tool: str,
350
351
  arguments: dict[str, Any] | None,
352
+ result: Content | dict[str, object] | None = None,
351
353
  logs: list[str],
352
354
  error_message: str | None,
353
355
  completed: bool = True,
@@ -357,6 +359,7 @@ def _format_ask_tool_call_entry_text(
357
359
  toolkit=toolkit,
358
360
  tool=tool,
359
361
  arguments=arguments,
362
+ result=result,
360
363
  failed=failed,
361
364
  completed=completed,
362
365
  )
@@ -4701,6 +4704,7 @@ async def _run_ask_tui(
4701
4704
  toolkit=toolkit,
4702
4705
  tool=tool,
4703
4706
  arguments=arguments,
4707
+ result=message.result,
4704
4708
  logs=logs,
4705
4709
  error_message=error_message,
4706
4710
  )
@@ -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",
@@ -376,8 +381,12 @@ SHELL_RENDERERS = {
376
381
  }
377
382
 
378
383
 
379
- if __name__ == "__main__":
384
+ def main() -> None:
380
385
  from meshagent.agents.channel_process import dispatch_main
381
386
 
382
387
  if not dispatch_main(executable_name=Path(sys.argv[0]).name, argv=sys.argv[1:]):
383
- app()
388
+ raise SystemExit(app())
389
+
390
+
391
+ if __name__ == "__main__":
392
+ main()
@@ -5,6 +5,7 @@ import types
5
5
  import pytest
6
6
 
7
7
  from meshagent.api import RoomException
8
+ from meshagent.agents import channel_process
8
9
  from meshagent.cli import async_typer
9
10
  from meshagent.cli import cli
10
11
  from meshagent.cli.testing import CliRunner
@@ -57,6 +58,7 @@ def test_root_help_lists_create_and_doctor_but_hides_legacy_command_namespaces()
57
58
  assert "│ api-key" not in result.output
58
59
  assert "│ launch" in result.output
59
60
  assert "│ room" in result.output
61
+ assert "│ volumes" in result.output
60
62
  assert "│ call" not in result.output
61
63
  assert "│ package" not in result.output
62
64
  assert "│ multi" not in result.output
@@ -132,6 +134,17 @@ def test_app_prints_room_exception_without_traceback(capsys) -> None:
132
134
  assert captured.out == ""
133
135
 
134
136
 
137
+ def test_main_exits_with_status_returned_by_async_typer(monkeypatch) -> None:
138
+ monkeypatch.setattr(channel_process, "dispatch_main", lambda **kwargs: False)
139
+ monkeypatch.setattr(cli, "app", lambda: 23)
140
+ monkeypatch.setattr(sys, "argv", ["meshagent", "build"])
141
+
142
+ with pytest.raises(SystemExit) as exc_info:
143
+ cli.main()
144
+
145
+ assert exc_info.value.code == 23
146
+
147
+
135
148
  def test_room_help_lists_agents_command() -> None:
136
149
  result = CliRunner().invoke(cli.app, ["room", "--help"])
137
150
 
@@ -139,6 +152,36 @@ def test_room_help_lists_agents_command() -> None:
139
152
  assert "│ agents" in result.output
140
153
 
141
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
+
142
185
  def test_room_agents_help_lists_call_command() -> None:
143
186
  result = CliRunner().invoke(cli.app, ["room", "agents", "--help"])
144
187
 
@@ -17,46 +17,6 @@ from meshagent.cli.meshagent_images import render_meshagent_image_prefix_templat
17
17
  from meshagent.cli.version import __version__ as MESHAGENT_CLIENT_VERSION
18
18
 
19
19
 
20
- SOURCE_SUFFIXES = {
21
- ".cs",
22
- ".dart",
23
- ".go",
24
- ".js",
25
- ".jsx",
26
- ".py",
27
- ".rb",
28
- ".ts",
29
- ".tsx",
30
- }
31
- PROJECT_MARKER_NAMES = {
32
- "Containerfile",
33
- "Dockerfile",
34
- "Gemfile",
35
- "go.mod",
36
- "meshagent.yaml",
37
- "meshagent.yml",
38
- "package.json",
39
- "pubspec.yaml",
40
- "pyproject.toml",
41
- "requirements.txt",
42
- "tsconfig.json",
43
- }
44
- IGNORED_DIR_NAMES = {
45
- ".git",
46
- ".venv",
47
- "__pycache__",
48
- "build",
49
- "dist",
50
- "node_modules",
51
- "obj",
52
- "target",
53
- "venv",
54
- }
55
- IGNORED_FILE_NAMES = {
56
- ".DS_Store",
57
- ".gitkeep",
58
- }
59
-
60
20
  WEB_FOCUS = "webserver"
61
21
  AGENT_FOCUS = "backend-agent"
62
22
  CHATBOT_FOCUS = "chatbot"
@@ -637,23 +597,8 @@ FOCUS_ALIASES = {
637
597
  }
638
598
 
639
599
 
640
- def _has_existing_project_content(root: Path) -> bool:
641
- for path in sorted(root.rglob("*")):
642
- try:
643
- relative_parts = path.relative_to(root).parts
644
- except ValueError:
645
- continue
646
- if any(part in IGNORED_DIR_NAMES for part in relative_parts[:-1]):
647
- continue
648
- if path.is_dir():
649
- continue
650
- if path.name in IGNORED_FILE_NAMES:
651
- continue
652
- if path.name in PROJECT_MARKER_NAMES:
653
- return True
654
- if path.suffix.lower() in SOURCE_SUFFIXES:
655
- return True
656
- return False
600
+ def _target_directory_is_nonempty(root: Path) -> bool:
601
+ return next(root.iterdir(), None) is not None
657
602
 
658
603
 
659
604
  def _read_create_template(template_name: str) -> str:
@@ -1153,7 +1098,7 @@ def _create_command(
1153
1098
  "--no-interactive when running from a script."
1154
1099
  )
1155
1100
 
1156
- if _has_existing_project_content(root):
1101
+ if _target_directory_is_nonempty(root):
1157
1102
  if interactive is not False and is_interactive_stdio:
1158
1103
  existing_project_selection = _run_existing_project_tui(root=root)
1159
1104
  if existing_project_selection is None:
@@ -1169,7 +1114,9 @@ def _create_command(
1169
1114
  typer.echo(f"New project: {root}")
1170
1115
  else:
1171
1116
  typer.echo("")
1172
- typer.echo("Existing application code or deployment metadata was detected.")
1117
+ typer.echo(
1118
+ "The target directory is not empty; treating it as an existing project."
1119
+ )
1173
1120
  typer.echo("No files were written.")
1174
1121
  typer.echo("")
1175
1122
  typer.echo("Recommended next step for existing projects:")
@@ -25,7 +25,8 @@ logging.basicConfig(
25
25
  )
26
26
  LOGGER = logging.getLogger("contact_form")
27
27
 
28
- DEFAULT_FROM_ADDRESS = "contact@mail.meshagent.com"
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)}@mail.meshagent.com"
197
+ return f"contact-{room_slug_from_name(room_name)}@{mail_domain()}"
188
198
  return DEFAULT_FROM_ADDRESS
189
199
 
190
200
 
@@ -295,8 +295,6 @@ def test_static_nginx_create_templates_mount_writable_data_dir() -> None:
295
295
 
296
296
 
297
297
  def test_init_creates_python_backend_agent_by_default_in_non_tty(tmp_path) -> None:
298
- (tmp_path / ".gitkeep").write_text("", encoding="utf-8")
299
-
300
298
  result = CliRunner().invoke(create_command, [str(tmp_path)])
301
299
  diagnosis = diagnose_project(tmp_path)
302
300
 
@@ -4363,8 +4361,8 @@ def test_init_interactive_requires_tty_when_language_missing(tmp_path) -> None:
4363
4361
  assert not (tmp_path / "Dockerfile").exists()
4364
4362
 
4365
4363
 
4366
- def test_init_recommends_doctor_for_existing_code(tmp_path) -> None:
4367
- (tmp_path / "server.py").write_text("print('already here')\n", encoding="utf-8")
4364
+ def test_init_treats_any_nonempty_target_as_an_existing_project(tmp_path) -> None:
4365
+ (tmp_path / ".gitkeep").write_text("", encoding="utf-8")
4368
4366
 
4369
4367
  result = CliRunner().invoke(
4370
4368
  create_command,
@@ -4380,7 +4378,7 @@ def test_init_recommends_doctor_for_existing_code(tmp_path) -> None:
4380
4378
 
4381
4379
  assert result.exit_code == 0
4382
4380
  assert "meshagent create" in result.output
4383
- assert "Existing application code" in result.output
4381
+ assert "target directory is not empty" in result.output
4384
4382
  assert "No files were written" in result.output
4385
4383
  assert "meshagent doctor" in result.output
4386
4384
  assert not (tmp_path / "Dockerfile").exists()
@@ -175,7 +175,7 @@ _DEPLOY_DOCKERFILE_HAPPY_PATH = (
175
175
  _DEPLOY_MISSING_DOCKERFILE_GUIDANCE = (
176
176
  "If PATH does not include a Dockerfile yet, create a minimal Dockerfile in "
177
177
  "the app directory first or create one elsewhere in PATH and pass it with "
178
- "--dockerfile-path."
178
+ "--file."
179
179
  )
180
180
 
181
181
 
@@ -521,6 +521,41 @@ def _resolve_build_context_path(
521
521
  return mount_path
522
522
 
523
523
 
524
+ def _dockerfile_path_from_file_option(
525
+ *,
526
+ pack_spec: _BuildPackSpec,
527
+ file_path: str,
528
+ ) -> str:
529
+ relative_path = PurePosixPath(file_path)
530
+ if relative_path.is_absolute():
531
+ raise typer.BadParameter("--file must be relative to PATH")
532
+ if len(relative_path.parts) == 0 or relative_path == PurePosixPath("."):
533
+ raise typer.BadParameter("--file cannot be empty")
534
+ if ".." in relative_path.parts:
535
+ raise typer.BadParameter("--file must stay inside PATH")
536
+ return posixpath.join(pack_spec.mount_path, relative_path.as_posix())
537
+
538
+
539
+ def _warn_legacy_build_path_options(
540
+ *,
541
+ context_path: str | None,
542
+ dockerfile_path: str | None,
543
+ ) -> None:
544
+ if context_path is not None:
545
+ typer.echo(
546
+ "Warning: --context-path is deprecated; pass the selected build "
547
+ "context directory as PATH instead.",
548
+ err=True,
549
+ )
550
+ if dockerfile_path is not None:
551
+ typer.echo(
552
+ "Warning: --dockerfile-path/--docker-file-path is deprecated; use "
553
+ "--file with a path relative to PATH instead (for example, "
554
+ "--file refresher/Dockerfile).",
555
+ err=True,
556
+ )
557
+
558
+
524
559
  def _parse_build_tag(tag: str) -> _ParsedImageTag:
525
560
  cleaned = tag.strip()
526
561
  if cleaned == "":
@@ -1046,17 +1081,28 @@ def _resolve_build_stage_inputs(
1046
1081
  context_path: str | None,
1047
1082
  dockerfile_path: str | None,
1048
1083
  pack: str,
1084
+ file_path: str | None = None,
1049
1085
  ) -> _ResolvedBuildStageInputs:
1050
1086
  pack_spec = _parse_build_pack(pack)
1087
+ if file_path is not None and dockerfile_path is not None:
1088
+ raise typer.BadParameter(
1089
+ "--file cannot be combined with --dockerfile-path/--docker-file-path"
1090
+ )
1051
1091
  resolved_context_path = _resolve_build_context_path(
1052
1092
  context_path=context_path,
1053
1093
  mount_path=pack_spec.mount_path,
1054
1094
  )
1055
- dockerfile_path = _infer_packed_dockerfile_path(
1056
- pack_spec=pack_spec,
1057
- context_path=resolved_context_path,
1058
- dockerfile_path=dockerfile_path,
1059
- )
1095
+ if file_path is not None:
1096
+ dockerfile_path = _dockerfile_path_from_file_option(
1097
+ pack_spec=pack_spec,
1098
+ file_path=file_path,
1099
+ )
1100
+ else:
1101
+ dockerfile_path = _infer_packed_dockerfile_path(
1102
+ pack_spec=pack_spec,
1103
+ context_path=resolved_context_path,
1104
+ dockerfile_path=dockerfile_path,
1105
+ )
1060
1106
 
1061
1107
  local_packed_dockerfile = _resolve_local_packed_dockerfile(
1062
1108
  pack_spec=pack_spec,
@@ -3688,6 +3734,19 @@ def _print_service_exited_before_live(
3688
3734
  )
3689
3735
 
3690
3736
 
3737
+ def _is_transient_room_disconnect(error: RoomException) -> bool:
3738
+ message = str(error).lower()
3739
+ return any(
3740
+ marker in message
3741
+ for marker in (
3742
+ "room connection is disconnected",
3743
+ "room connection unexpectedly closed",
3744
+ "websocket closed with code 1006",
3745
+ "cannot write to closing transport",
3746
+ )
3747
+ )
3748
+
3749
+
3691
3750
  async def _wait_for_deployed_service_live(
3692
3751
  *,
3693
3752
  client: RoomClient,
@@ -3701,6 +3760,7 @@ async def _wait_for_deployed_service_live(
3701
3760
  log_handler: Callable[[str], Awaitable[None]] | None = None,
3702
3761
  ) -> None:
3703
3762
  active_logs: _ActiveDeployLogStream | None = None
3763
+ connection_retry_reported = False
3704
3764
 
3705
3765
  await _emit_deploy_status(
3706
3766
  status_handler,
@@ -3728,9 +3788,29 @@ async def _wait_for_deployed_service_live(
3728
3788
 
3729
3789
  try:
3730
3790
  while True:
3731
- state = await _get_service_runtime_state(
3732
- client=client, service_id=service_id
3733
- )
3791
+ try:
3792
+ state = await _get_service_runtime_state(
3793
+ client=client, service_id=service_id
3794
+ )
3795
+ except RoomException as error:
3796
+ if not _is_transient_room_disconnect(error):
3797
+ raise
3798
+ if not connection_retry_reported:
3799
+ await _emit_deploy_status(
3800
+ status_handler,
3801
+ rich_message=(
3802
+ "[yellow]Room connection interrupted while confirming "
3803
+ "service readiness; retrying...[/]"
3804
+ ),
3805
+ plain_message=(
3806
+ "Room connection interrupted while confirming service "
3807
+ "readiness; retrying..."
3808
+ ),
3809
+ )
3810
+ connection_retry_reported = True
3811
+ await asyncio.sleep(_DEPLOY_WAIT_POLL_INTERVAL_SECONDS)
3812
+ continue
3813
+ connection_retry_reported = False
3734
3814
  if state is None:
3735
3815
  await asyncio.sleep(_DEPLOY_WAIT_POLL_INTERVAL_SECONDS)
3736
3816
  continue
@@ -3989,6 +4069,7 @@ async def _run_image_build_stage(
3989
4069
  private: bool,
3990
4070
  optimize: bool,
3991
4071
  cred: list[str],
4072
+ file_path: str | None = None,
3992
4073
  add_latest_tag: bool = False,
3993
4074
  status_handler: Callable[[str], Awaitable[None]] | None = None,
3994
4075
  log_handler: Callable[[str], Awaitable[None]] | None = None,
@@ -3998,6 +4079,7 @@ async def _run_image_build_stage(
3998
4079
  context_path=context_path,
3999
4080
  dockerfile_path=dockerfile_path,
4000
4081
  pack=pack,
4082
+ file_path=file_path,
4001
4083
  )
4002
4084
 
4003
4085
  account_client, client = await _with_client(
@@ -4129,6 +4211,7 @@ def _validate_deploy_build_stage_options(
4129
4211
  optimize: bool,
4130
4212
  cred: list[str],
4131
4213
  add_latest_tag: bool,
4214
+ file_path: str | None = None,
4132
4215
  ) -> None:
4133
4216
  if pack is not None:
4134
4217
  return
@@ -4138,6 +4221,8 @@ def _validate_deploy_build_stage_options(
4138
4221
  invalid_options.append("--context-path")
4139
4222
  if dockerfile_path is not None:
4140
4223
  invalid_options.append("--dockerfile-path")
4224
+ if file_path is not None:
4225
+ invalid_options.append("--file")
4141
4226
  if builder_name is not None:
4142
4227
  invalid_options.append("--builder-name")
4143
4228
  if not optimize:
@@ -4170,16 +4255,15 @@ async def build_image(
4170
4255
  typer.Argument(
4171
4256
  ...,
4172
4257
  metavar="PATH",
4173
- help=(
4174
- "Local directory to stream as the build context. Format "
4175
- "'<path>[:<mount>]'. Defaults mount to /context."
4176
- ),
4258
+ help=("Local directory to use as the Docker build context."),
4177
4259
  ),
4178
4260
  ],
4179
4261
  tag: Annotated[
4180
4262
  str,
4181
4263
  typer.Option(
4182
4264
  ...,
4265
+ "-t",
4266
+ "--tag",
4183
4267
  help=(
4184
4268
  "Image tag to build. Supports <repository>:<tag>, "
4185
4269
  "<project-key>/<repository>:<tag>, or "
@@ -4188,24 +4272,27 @@ async def build_image(
4188
4272
  ),
4189
4273
  ),
4190
4274
  ],
4275
+ file_path: Annotated[
4276
+ Optional[str],
4277
+ typer.Option(
4278
+ "-f",
4279
+ "--file",
4280
+ help="Dockerfile path relative to PATH.",
4281
+ ),
4282
+ ] = None,
4191
4283
  context_path: Annotated[
4192
4284
  Optional[str],
4193
4285
  typer.Option(
4194
4286
  "--context-path",
4195
- help=(
4196
- "Build context path inside the streamed build context (absolute "
4197
- "path). Defaults to the PATH mount path."
4198
- ),
4287
+ hidden=True,
4199
4288
  ),
4200
4289
  ] = None,
4201
4290
  dockerfile_path: Annotated[
4202
4291
  Optional[str],
4203
4292
  typer.Option(
4204
4293
  "--dockerfile-path",
4205
- help=(
4206
- "Optional Dockerfile path inside the streamed build context "
4207
- "(absolute path)."
4208
- ),
4294
+ "--docker-file-path",
4295
+ hidden=True,
4209
4296
  ),
4210
4297
  ] = None,
4211
4298
  builder_name: Annotated[
@@ -4247,6 +4334,10 @@ async def build_image(
4247
4334
  ),
4248
4335
  ] = False,
4249
4336
  ) -> None:
4337
+ _warn_legacy_build_path_options(
4338
+ context_path=context_path,
4339
+ dockerfile_path=dockerfile_path,
4340
+ )
4250
4341
  parsed_tag = _parse_build_tag(tag)
4251
4342
  resolved_room = resolve_room(room)
4252
4343
  if resolved_room is None:
@@ -4273,6 +4364,7 @@ async def build_image(
4273
4364
  private=private,
4274
4365
  optimize=optimize,
4275
4366
  cred=cred,
4367
+ file_path=file_path,
4276
4368
  add_latest_tag=latest,
4277
4369
  )
4278
4370
 
@@ -4350,17 +4442,15 @@ async def deploy_image(
4350
4442
  Optional[str],
4351
4443
  typer.Argument(
4352
4444
  metavar="PATH",
4353
- help=(
4354
- "Local directory to stream as the build context before deploy. "
4355
- "Format '<path>[:<mount>]'. Defaults mount to /context. PATH is "
4356
- "typically the app directory you want to deploy."
4357
- ),
4445
+ help=("Local directory to use as the Docker build context before deploy."),
4358
4446
  ),
4359
4447
  ] = None,
4360
4448
  tag: Annotated[
4361
4449
  str,
4362
4450
  typer.Option(
4363
4451
  ...,
4452
+ "-t",
4453
+ "--tag",
4364
4454
  help=(
4365
4455
  "Image tag to deploy, e.g. repo/name:tag. When used with PATH, "
4366
4456
  "shorthand <repository>:<tag> and "
@@ -4369,26 +4459,27 @@ async def deploy_image(
4369
4459
  ),
4370
4460
  ),
4371
4461
  ],
4462
+ file_path: Annotated[
4463
+ Optional[str],
4464
+ typer.Option(
4465
+ "-f",
4466
+ "--file",
4467
+ help="Dockerfile path relative to PATH. Only used with PATH.",
4468
+ ),
4469
+ ] = None,
4372
4470
  context_path: Annotated[
4373
4471
  Optional[str],
4374
4472
  typer.Option(
4375
4473
  "--context-path",
4376
- help=(
4377
- "Build context path inside the packed build context (absolute path). "
4378
- "Only used with PATH."
4379
- ),
4474
+ hidden=True,
4380
4475
  ),
4381
4476
  ] = None,
4382
4477
  dockerfile_path: Annotated[
4383
4478
  Optional[str],
4384
4479
  typer.Option(
4385
4480
  "--dockerfile-path",
4386
- help=(
4387
- "Optional Dockerfile path inside the packed build context (absolute "
4388
- "path). Only used with PATH. Use this when the app directory has "
4389
- "no top-level Dockerfile or when you create the Dockerfile under "
4390
- "a different path."
4391
- ),
4481
+ "--docker-file-path",
4482
+ hidden=True,
4392
4483
  ),
4393
4484
  ] = None,
4394
4485
  optimize: Annotated[
@@ -4453,7 +4544,6 @@ async def deploy_image(
4453
4544
  list[str],
4454
4545
  typer.Option(
4455
4546
  "--values",
4456
- "-f",
4457
4547
  help=(
4458
4548
  "YAML file containing deploy template values. Can be passed "
4459
4549
  "multiple times; later files override earlier files."
@@ -4605,6 +4695,10 @@ async def deploy_image(
4605
4695
  ] = True,
4606
4696
  ) -> None:
4607
4697
  """Create or update a room service from an image."""
4698
+ _warn_legacy_build_path_options(
4699
+ context_path=context_path,
4700
+ dockerfile_path=dockerfile_path,
4701
+ )
4608
4702
  parsed_tag = _parse_build_tag(tag)
4609
4703
  project_registry: str | None = None
4610
4704
  _validate_deploy_build_stage_options(
@@ -4615,6 +4709,7 @@ async def deploy_image(
4615
4709
  optimize=optimize,
4616
4710
  cred=cred,
4617
4711
  add_latest_tag=latest,
4712
+ file_path=file_path,
4618
4713
  )
4619
4714
  parsed_environment = _parse_environment_variables(values=env)
4620
4715
  parsed_secret_environment = _parse_environment_secret_variables(values=env_secret)
@@ -4672,6 +4767,7 @@ async def deploy_image(
4672
4767
  context_path=context_path,
4673
4768
  dockerfile_path=dockerfile_path,
4674
4769
  pack=pack,
4770
+ file_path=file_path,
4675
4771
  )
4676
4772
  packed_dockerfile_metadata = _parse_packed_dockerfile_metadata(
4677
4773
  local_packed_dockerfile=build_inputs.local_packed_dockerfile
@@ -4964,6 +5060,7 @@ async def deploy_image(
4964
5060
  private=False,
4965
5061
  optimize=optimize,
4966
5062
  cred=cred,
5063
+ file_path=file_path,
4967
5064
  add_latest_tag=latest,
4968
5065
  status_handler=status_handler,
4969
5066
  log_handler=log_handler,