meshagent-cli 0.52.1__tar.gz → 0.52.4__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 (180) hide show
  1. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/PKG-INFO +18 -18
  2. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/cli.py +7 -0
  3. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/config.py +44 -16
  4. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/config_test.py +47 -0
  5. meshagent_cli-0.52.4/meshagent/cli/oauth_clients.py +120 -0
  6. meshagent_cli-0.52.4/meshagent/cli/oauth_clients_test.py +89 -0
  7. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/process.py +1 -1
  8. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/process_test.py +1 -1
  9. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/projects.py +80 -0
  10. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/projects_test.py +169 -0
  11. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/sqlite.py +116 -5
  12. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/sqlite_recovery.py +1 -1
  13. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/sqlite_recovery_test.py +20 -42
  14. meshagent_cli-0.52.4/meshagent/cli/sqlite_test.py +91 -0
  15. meshagent_cli-0.52.4/meshagent/cli/sqlite_transfer_test.py +105 -0
  16. meshagent_cli-0.52.4/meshagent/cli/version.py +1 -0
  17. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent_cli.egg-info/PKG-INFO +18 -18
  18. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent_cli.egg-info/SOURCES.txt +3 -0
  19. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent_cli.egg-info/requires.txt +17 -17
  20. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/pyproject.toml +17 -17
  21. meshagent_cli-0.52.1/meshagent/cli/sqlite_test.py +0 -68
  22. meshagent_cli-0.52.1/meshagent/cli/version.py +0 -1
  23. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/LICENSE +0 -0
  24. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/README.md +0 -0
  25. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/__init__.py +0 -0
  26. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/_filedrop.py +0 -0
  27. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/agent.py +0 -0
  28. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/agent_cli_options_test.py +0 -0
  29. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/agent_package_cli.py +0 -0
  30. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/agent_package_cli_test.py +0 -0
  31. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/agents.py +0 -0
  32. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/agents_test.py +0 -0
  33. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/ask.py +0 -0
  34. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/ask_test.py +0 -0
  35. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/async_typer.py +0 -0
  36. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/async_typer_test.py +0 -0
  37. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/auth.py +0 -0
  38. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/auth_async.py +0 -0
  39. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/auth_async_test.py +0 -0
  40. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/auth_test.py +0 -0
  41. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/call.py +0 -0
  42. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/chatbot.py +0 -0
  43. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/cli_mcp.py +0 -0
  44. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/cli_test.py +0 -0
  45. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/common_options.py +0 -0
  46. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/containers.py +0 -0
  47. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/containers_test.py +0 -0
  48. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/create.py +0 -0
  49. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/create_project_templates/__init__.py +0 -0
  50. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/create_project_templates/python/backend-agent/server.py +0 -0
  51. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/create_project_templates/python/contact-form/server.py +0 -0
  52. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/create_project_templates/python/slack-channel/channel.py +0 -0
  53. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/create_project_templates/python/slack-channel/scripts/configure-slack.py +0 -0
  54. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/create_project_templates/python/slack-channel/scripts/setup-slack-dev-route.py +0 -0
  55. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/create_project_templates/python/slack-channel/server.py +0 -0
  56. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/create_project_templates/python/task-queue-dashboard/server.py +0 -0
  57. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/create_project_templates/python/telegram-channel/channel.py +0 -0
  58. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/create_project_templates/python/telegram-channel/scripts/configure-telegram.py +0 -0
  59. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/create_project_templates/python/telegram-channel/scripts/create-bot-token.py +0 -0
  60. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/create_project_templates/python/telegram-channel/server.py +0 -0
  61. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/create_project_templates/python/twilio-channel/channel.py +0 -0
  62. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/create_project_templates/python/twilio-channel/server.py +0 -0
  63. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/create_project_templates/python/webserver/server.py +0 -0
  64. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/create_project_templates/python/whatsapp-channel/channel.py +0 -0
  65. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/create_project_templates/python/whatsapp-channel/server.py +0 -0
  66. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/create_test.py +0 -0
  67. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/custom_domains.py +0 -0
  68. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/custom_domains_test.py +0 -0
  69. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/dataset.py +0 -0
  70. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/dataset_test.py +0 -0
  71. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/developer.py +0 -0
  72. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/developer_test.py +0 -0
  73. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/doctor.py +0 -0
  74. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/doctor_dockerfiles/__init__.py +0 -0
  75. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/doctor_templates/__init__.py +0 -0
  76. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/doctor_test.py +0 -0
  77. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/feeds.py +0 -0
  78. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/feeds_test.py +0 -0
  79. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/helper.py +0 -0
  80. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/helper_test.py +0 -0
  81. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/helpers.py +0 -0
  82. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/host.py +0 -0
  83. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/iam.py +0 -0
  84. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/iam_test.py +0 -0
  85. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/image.py +0 -0
  86. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/image_test.py +0 -0
  87. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/launch.py +0 -0
  88. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/launch_test.py +0 -0
  89. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/llm.py +0 -0
  90. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/llm_test.py +0 -0
  91. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/local_settings.py +0 -0
  92. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/local_settings_test.py +0 -0
  93. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/mailbot.py +0 -0
  94. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/mailbot_test.py +0 -0
  95. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/mailboxes.py +0 -0
  96. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/mailboxes_test.py +0 -0
  97. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/meeting_transcriber.py +0 -0
  98. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/memory.py +0 -0
  99. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/memory_test.py +0 -0
  100. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/meshagent_images.py +0 -0
  101. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/meshagent_images_test.py +0 -0
  102. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/messaging.py +0 -0
  103. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/messaging_test.py +0 -0
  104. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/mounts.py +0 -0
  105. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/multi.py +0 -0
  106. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/oci_archive.py +0 -0
  107. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/oci_archive_test.py +0 -0
  108. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/participant_token.py +0 -0
  109. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/port.py +0 -0
  110. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/port_test.py +0 -0
  111. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/preamble_rules.py +0 -0
  112. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/preamble_rules_test.py +0 -0
  113. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/process_live_test.py +0 -0
  114. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/queue.py +0 -0
  115. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/queue_test.py +0 -0
  116. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/registry.py +0 -0
  117. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/registry_test.py +0 -0
  118. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/room.py +0 -0
  119. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/room_connect.py +0 -0
  120. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/room_connect_test.py +0 -0
  121. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/room_services.py +0 -0
  122. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/room_services_test.py +0 -0
  123. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/rooms.py +0 -0
  124. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/rooms_test.py +0 -0
  125. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/root_commands.py +0 -0
  126. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/root_commands_test.py +0 -0
  127. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/routes.py +0 -0
  128. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/routes_test.py +0 -0
  129. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/sample_channel_http_test.py +0 -0
  130. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/sample_channel_live_e2e_test.py +0 -0
  131. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/scheduled_tasks.py +0 -0
  132. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/scheduled_tasks_test.py +0 -0
  133. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/secrets.py +0 -0
  134. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/secrets_test.py +0 -0
  135. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/service_accounts.py +0 -0
  136. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/service_accounts_test.py +0 -0
  137. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/services.py +0 -0
  138. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/services_test.py +0 -0
  139. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/sessions.py +0 -0
  140. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/sessions_test.py +0 -0
  141. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/storage.py +0 -0
  142. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/storage_test.py +0 -0
  143. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/subscriptions.py +0 -0
  144. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/sync.py +0 -0
  145. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/sync_test.py +0 -0
  146. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/task_runner.py +0 -0
  147. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/task_runner_test.py +0 -0
  148. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/test.py +0 -0
  149. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/testing.py +0 -0
  150. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/thread_inspect.py +0 -0
  151. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/thread_inspect_test.py +0 -0
  152. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/thread_sidebar.py +0 -0
  153. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/tool_call_summary.py +0 -0
  154. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/tool_call_summary_test.py +0 -0
  155. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/tool_integrations.py +0 -0
  156. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/tool_integrations_test.py +0 -0
  157. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/tui/__init__.py +0 -0
  158. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/tui/auth_switch.py +0 -0
  159. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/tui/auth_switch_test.py +0 -0
  160. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/tui/create.py +0 -0
  161. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/tui/deploy_room.py +0 -0
  162. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/tui/deploy_room_test.py +0 -0
  163. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/tui/project_activate.py +0 -0
  164. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/tui/project_activate_test.py +0 -0
  165. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/tui/setup.py +0 -0
  166. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/tui/setup_splash_frames.py +0 -0
  167. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/tui/setup_test.py +0 -0
  168. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/version_check.py +0 -0
  169. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/version_check_test.py +0 -0
  170. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/voicebot.py +0 -0
  171. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/volumes.py +0 -0
  172. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/volumes_test.py +0 -0
  173. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/webserver.py +0 -0
  174. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/webserver_test.py +0 -0
  175. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/worker.py +0 -0
  176. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent/cli/worker_test.py +0 -0
  177. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent_cli.egg-info/dependency_links.txt +0 -0
  178. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent_cli.egg-info/entry_points.txt +0 -0
  179. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/meshagent_cli.egg-info/top_level.txt +0 -0
  180. {meshagent_cli-0.52.1 → meshagent_cli-0.52.4}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: meshagent-cli
3
- Version: 0.52.1
3
+ Version: 0.52.4
4
4
  Summary: CLI for Meshagent
5
5
  License-Expression: Apache-2.0
6
6
  Project-URL: Documentation, https://docs.meshagent.com
@@ -17,13 +17,13 @@ Requires-Dist: opentelemetry-exporter-otlp-proto-http~=1.33
17
17
  Requires-Dist: art~=6.5
18
18
  Requires-Dist: pyyaml~=6.0.2
19
19
  Requires-Dist: pydantic-yaml~=1.5
20
- Requires-Dist: pyarrow~=21.0.0
20
+ Requires-Dist: pyarrow~=22.0.0
21
21
  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.52.1
26
- Requires-Dist: meshagent-codex==0.52.1
25
+ Requires-Dist: meshagent-llm-proxy==0.52.4
26
+ Requires-Dist: meshagent-codex==0.52.4
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.52.1; extra == "all"
36
- Requires-Dist: meshagent-api[all]==0.52.1; extra == "all"
37
- Requires-Dist: meshagent-commoncrawl==0.52.1; extra == "all"
38
- Requires-Dist: meshagent-scrapy==0.52.1; extra == "all"
39
- Requires-Dist: meshagent-computers==0.52.1; extra == "all"
40
- Requires-Dist: meshagent-openai==0.52.1; extra == "all"
41
- Requires-Dist: meshagent-anthropic==0.52.1; extra == "all"
42
- Requires-Dist: meshagent-otel==0.52.1; extra == "all"
43
- Requires-Dist: meshagent-mcp==0.52.1; extra == "all"
44
- Requires-Dist: meshagent-tools==0.52.1; extra == "all"
35
+ Requires-Dist: meshagent-agents[all]==0.52.4; extra == "all"
36
+ Requires-Dist: meshagent-api[all]==0.52.4; extra == "all"
37
+ Requires-Dist: meshagent-commoncrawl==0.52.4; extra == "all"
38
+ Requires-Dist: meshagent-scrapy==0.52.4; extra == "all"
39
+ Requires-Dist: meshagent-computers==0.52.4; extra == "all"
40
+ Requires-Dist: meshagent-openai==0.52.4; extra == "all"
41
+ Requires-Dist: meshagent-anthropic==0.52.4; extra == "all"
42
+ Requires-Dist: meshagent-otel==0.52.4; extra == "all"
43
+ Requires-Dist: meshagent-mcp==0.52.4; extra == "all"
44
+ Requires-Dist: meshagent-tools==0.52.4; 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.52.1; extra == "mcp-service"
49
- Requires-Dist: meshagent-api==0.52.1; extra == "mcp-service"
50
- Requires-Dist: meshagent-mcp==0.52.1; extra == "mcp-service"
51
- Requires-Dist: meshagent-tools==0.52.1; extra == "mcp-service"
48
+ Requires-Dist: meshagent-agents[all]==0.52.4; extra == "mcp-service"
49
+ Requires-Dist: meshagent-api==0.52.4; extra == "mcp-service"
50
+ Requires-Dist: meshagent-mcp==0.52.4; extra == "mcp-service"
51
+ Requires-Dist: meshagent-tools==0.52.4; extra == "mcp-service"
52
52
  Requires-Dist: supabase-auth~=2.28.0; extra == "mcp-service"
53
53
  Dynamic: license-file
54
54
 
@@ -386,6 +386,13 @@ SHELL_RENDERERS = {
386
386
  }
387
387
 
388
388
 
389
+ app.add_lazy_command(
390
+ name="oauth-client",
391
+ module="meshagent.cli.oauth_clients",
392
+ help="Manage OAuth clients and login branding",
393
+ )
394
+
395
+
389
396
  def main() -> None:
390
397
  from meshagent.agents.channel_process import dispatch_main
391
398
 
@@ -8,19 +8,49 @@ from meshagent.api import RoomException
8
8
  from meshagent.api.client import MeshagentDeploymentConfig
9
9
  from meshagent.cli import async_typer
10
10
  from meshagent.cli.helper import get_client
11
+ from meshagent.cli.local_settings import resolve_api_url
11
12
 
12
13
  app = async_typer.AsyncTyper(help="Read MeshAgent deployment configuration")
13
14
 
15
+ SUPPORTED_CONFIG_PATHS = (
16
+ "version",
17
+ "openai.url",
18
+ "anthropic.url",
19
+ "grok.url",
20
+ "domains.studio",
21
+ "domains.accounts",
22
+ "domains.powerboards",
23
+ "domains.api",
24
+ "domains.mail",
25
+ "domains.pages",
26
+ "domains.registry",
27
+ )
28
+
14
29
 
15
30
  @app.callback()
16
31
  def _config_callback() -> None:
17
32
  pass
18
33
 
19
34
 
20
- def _config_value(config: MeshagentDeploymentConfig, path: str) -> str | None:
35
+ def _llm_proxy_url(*, api_url: str, provider_path: str) -> str:
36
+ return f"{api_url.rstrip('/')}/{provider_path}"
37
+
38
+
39
+ def _config_value(
40
+ config: MeshagentDeploymentConfig,
41
+ path: str,
42
+ *,
43
+ api_url: str,
44
+ ) -> str | None:
21
45
  match path:
22
46
  case "version":
23
47
  return config.version
48
+ case "openai.url":
49
+ return _llm_proxy_url(api_url=api_url, provider_path="openai/v1")
50
+ case "anthropic.url":
51
+ return _llm_proxy_url(api_url=api_url, provider_path="anthropic")
52
+ case "grok.url":
53
+ return _llm_proxy_url(api_url=api_url, provider_path="grok/v1")
24
54
  case "domains.studio":
25
55
  return config.domains.studio
26
56
  case "domains.accounts":
@@ -36,20 +66,9 @@ def _config_value(config: MeshagentDeploymentConfig, path: str) -> str | None:
36
66
  case "domains.registry":
37
67
  return config.domains.registry
38
68
  case _:
39
- supported_paths = ", ".join(
40
- [
41
- "version",
42
- "domains.studio",
43
- "domains.accounts",
44
- "domains.powerboards",
45
- "domains.api",
46
- "domains.mail",
47
- "domains.pages",
48
- "domains.registry",
49
- ]
50
- )
51
69
  raise typer.BadParameter(
52
- f"unsupported config path; choose one of: {supported_paths}"
70
+ "unsupported config path; choose one of: "
71
+ f"{', '.join(SUPPORTED_CONFIG_PATHS)}"
53
72
  )
54
73
 
55
74
 
@@ -57,7 +76,12 @@ def _config_value(config: MeshagentDeploymentConfig, path: str) -> str | None:
57
76
  async def config_get(
58
77
  path: Annotated[
59
78
  str,
60
- typer.Argument(help="Config path to read, for example domains.pages"),
79
+ typer.Argument(
80
+ help=(
81
+ "Config path to read. Supported paths: "
82
+ f"{', '.join(SUPPORTED_CONFIG_PATHS)}"
83
+ )
84
+ ),
61
85
  ],
62
86
  ) -> None:
63
87
  """Print one deployment config value."""
@@ -70,7 +94,11 @@ async def config_get(
70
94
  finally:
71
95
  await client.close()
72
96
 
73
- value = _config_value(config, path.strip())
97
+ value = _config_value(
98
+ config,
99
+ path.strip(),
100
+ api_url=resolve_api_url(),
101
+ )
74
102
  if value is None:
75
103
  typer.echo(f"Config value is not set: {path.strip()}", err=True)
76
104
  raise typer.Exit(1)
@@ -63,6 +63,53 @@ def test_config_get_version_prints_server_version(
63
63
  assert fake_client.closed is True
64
64
 
65
65
 
66
+ @pytest.mark.parametrize(
67
+ ("path", "expected"),
68
+ [
69
+ ("openai.url", "https://api.meshagent.example/openai/v1"),
70
+ ("anthropic.url", "https://api.meshagent.example/anthropic"),
71
+ ("grok.url", "https://api.meshagent.example/grok/v1"),
72
+ ],
73
+ )
74
+ def test_config_get_prints_llm_proxy_url_for_active_deployment(
75
+ path: str,
76
+ expected: str,
77
+ monkeypatch: pytest.MonkeyPatch,
78
+ capsys: pytest.CaptureFixture[str],
79
+ ) -> None:
80
+ fake_client = _FakeConfigClient(
81
+ MeshagentDeploymentConfig(domains=MeshagentDomains())
82
+ )
83
+
84
+ async def _fake_get_client() -> _FakeConfigClient:
85
+ return fake_client
86
+
87
+ monkeypatch.setattr(config, "get_client", _fake_get_client)
88
+ monkeypatch.setattr(
89
+ config,
90
+ "resolve_api_url",
91
+ lambda: "https://api.meshagent.example/",
92
+ )
93
+
94
+ cli.app(["config", "get", path])
95
+
96
+ captured = capsys.readouterr()
97
+ assert captured.out == f"{expected}\n"
98
+ assert captured.err == ""
99
+ assert fake_client.closed is True
100
+
101
+
102
+ def test_config_get_help_lists_supported_paths(
103
+ capsys: pytest.CaptureFixture[str],
104
+ ) -> None:
105
+ cli.app(["config", "get", "--help"])
106
+
107
+ captured = capsys.readouterr()
108
+ for path in config.SUPPORTED_CONFIG_PATHS:
109
+ assert path in captured.out
110
+ assert captured.err == ""
111
+
112
+
66
113
  def test_config_get_rejects_unknown_path(
67
114
  monkeypatch: pytest.MonkeyPatch,
68
115
  capsys: pytest.CaptureFixture[str],
@@ -0,0 +1,120 @@
1
+ from enum import Enum
2
+ from typing import Annotated
3
+
4
+ import typer
5
+ from meshagent.api.oauth_branding import OAuthClientBranding
6
+ from meshagent.cli import async_typer
7
+ from meshagent.cli.common_options import ProjectIdOption
8
+ from meshagent.cli.helper import get_client, resolve_project_id
9
+ from pydantic import ValidationError
10
+ from rich import print_json
11
+
12
+ app = async_typer.AsyncTyper(help="Manage OAuth clients and login branding")
13
+
14
+
15
+ class Theme(str, Enum):
16
+ light = "light"
17
+ dark = "dark"
18
+ auto = "auto"
19
+
20
+
21
+ def branding_metadata(
22
+ existing: dict[str, str],
23
+ *,
24
+ name: str | None,
25
+ logo_url: str | None,
26
+ theme: Theme | None,
27
+ clear_logo: bool = False,
28
+ ) -> dict[str, str]:
29
+ if clear_logo and logo_url is not None:
30
+ raise typer.BadParameter("Use either --logo-url or --clear-logo")
31
+ metadata = dict(existing)
32
+ if name is not None:
33
+ metadata["name"] = name
34
+ if clear_logo:
35
+ metadata.pop("logo_url", None)
36
+ elif logo_url is not None:
37
+ metadata["logo_url"] = logo_url
38
+ if theme is not None:
39
+ metadata["theme"] = theme.value
40
+ try:
41
+ OAuthClientBranding.model_validate(metadata)
42
+ except ValidationError as exc:
43
+ raise typer.BadParameter("Logo URL must be an absolute HTTP(S) URL") from exc
44
+ return metadata
45
+
46
+
47
+ @app.command("create")
48
+ async def create_client(
49
+ name: Annotated[str, typer.Option(help="Application name shown at login")],
50
+ redirect_uri: Annotated[
51
+ list[str], typer.Option(help="Allowed callback URL; repeat for multiple URLs")
52
+ ],
53
+ scope: Annotated[str, typer.Option(help="OAuth scopes")],
54
+ project_id: ProjectIdOption,
55
+ logo_url: Annotated[
56
+ str | None, typer.Option(help="Optional HTTP(S) login logo URL")
57
+ ] = None,
58
+ theme: Annotated[Theme, typer.Option(help="Login appearance")] = Theme.auto,
59
+ ):
60
+ """Create an authorization-code client. The output includes its new secret."""
61
+ metadata = branding_metadata({}, name=name, logo_url=logo_url, theme=theme)
62
+ project_id = await resolve_project_id(project_id)
63
+ async with await get_client() as client:
64
+ result = await client.create_oauth_client(
65
+ project_id=project_id,
66
+ grant_types=["authorization_code", "refresh_token"],
67
+ response_types=["code"],
68
+ redirect_uris=redirect_uri,
69
+ scope=scope,
70
+ metadata=metadata,
71
+ )
72
+ print_json(result.model_dump_json())
73
+
74
+
75
+ @app.command("update")
76
+ async def update_client(
77
+ client_id: Annotated[str, typer.Argument(help="OAuth client ID")],
78
+ project_id: ProjectIdOption,
79
+ name: Annotated[
80
+ str | None, typer.Option(help="Application name shown at login")
81
+ ] = None,
82
+ logo_url: Annotated[str | None, typer.Option(help="HTTP(S) login logo URL")] = None,
83
+ theme: Annotated[
84
+ Theme | None, typer.Option(help="Login appearance: light, dark, or auto")
85
+ ] = None,
86
+ clear_logo: Annotated[
87
+ bool, typer.Option(help="Restore the default MeshAgent logo")
88
+ ] = False,
89
+ ):
90
+ """Update login branding, preserving other client settings and metadata."""
91
+ project_id = await resolve_project_id(project_id)
92
+ async with await get_client() as client:
93
+ existing = await client.get_oauth_client(
94
+ project_id=project_id, client_id=client_id
95
+ )
96
+ metadata = branding_metadata(
97
+ existing.metadata,
98
+ name=name,
99
+ logo_url=logo_url,
100
+ theme=theme,
101
+ clear_logo=clear_logo,
102
+ )
103
+ result = await client.update_oauth_client(
104
+ project_id=project_id, client_id=client_id, metadata=metadata
105
+ )
106
+ print_json(data=result)
107
+
108
+
109
+ @app.command("get")
110
+ async def get_client_config(
111
+ client_id: Annotated[str, typer.Argument(help="OAuth client ID")],
112
+ project_id: ProjectIdOption,
113
+ ):
114
+ """Show an OAuth client's configuration and branding."""
115
+ project_id = await resolve_project_id(project_id)
116
+ async with await get_client() as client:
117
+ result = await client.get_oauth_client(
118
+ project_id=project_id, client_id=client_id
119
+ )
120
+ print_json(result.model_dump_json())
@@ -0,0 +1,89 @@
1
+ import pytest
2
+ import typer
3
+ from meshagent.cli.oauth_clients import Theme, app, branding_metadata
4
+ from meshagent.cli.testing import CliRunner
5
+
6
+
7
+ def test_branding_update_preserves_other_metadata():
8
+ assert branding_metadata(
9
+ {"name": "App", "custom": "keep", "logo_url": "https://old.example/logo"},
10
+ name=None,
11
+ logo_url=None,
12
+ theme=Theme.dark,
13
+ ) == {
14
+ "name": "App",
15
+ "custom": "keep",
16
+ "logo_url": "https://old.example/logo",
17
+ "theme": "dark",
18
+ }
19
+
20
+
21
+ def test_clear_logo_restores_default_without_removing_name():
22
+ assert branding_metadata(
23
+ {"name": "App", "logo_url": "https://example.com/logo"},
24
+ name=None,
25
+ logo_url=None,
26
+ theme=None,
27
+ clear_logo=True,
28
+ ) == {"name": "App"}
29
+
30
+
31
+ @pytest.mark.parametrize("url", ["javascript:alert(1)", "/logo.svg", "not-a-url"])
32
+ def test_invalid_logo_rejected(url):
33
+ with pytest.raises(typer.BadParameter):
34
+ branding_metadata({}, name="App", logo_url=url, theme=Theme.auto)
35
+
36
+
37
+ def test_oauth_branding_options_are_available():
38
+ result = CliRunner().invoke(app, ["update", "--help"])
39
+ assert result.exit_code == 0, result.output
40
+ from rich.text import Text
41
+
42
+ output = Text.from_ansi(result.output).plain
43
+ assert "--logo-url" in output
44
+ assert "--clear-logo" in output
45
+ assert "--theme" in output
46
+
47
+
48
+ @pytest.mark.asyncio
49
+ async def test_update_command_sends_branding_and_preserves_existing_metadata(
50
+ monkeypatch,
51
+ ):
52
+ from unittest.mock import AsyncMock
53
+
54
+ from meshagent.api.client import OAuthClient
55
+ from meshagent.cli import oauth_clients
56
+
57
+ api = AsyncMock()
58
+ api.__aenter__.return_value = api
59
+ api.get_oauth_client.return_value = OAuthClient(
60
+ client_id="client-1",
61
+ project_id="project-1",
62
+ grant_types=["authorization_code"],
63
+ response_types=["code"],
64
+ redirect_uris=["https://example.com/callback"],
65
+ scope="openid",
66
+ metadata={"name": "Existing", "custom": "preserved"},
67
+ )
68
+ api.update_oauth_client.return_value = {"ok": True}
69
+ monkeypatch.setattr(oauth_clients, "get_client", AsyncMock(return_value=api))
70
+ monkeypatch.setattr(
71
+ oauth_clients, "resolve_project_id", AsyncMock(return_value="project-1")
72
+ )
73
+ monkeypatch.setattr(oauth_clients, "print_json", lambda **kwargs: None)
74
+ await oauth_clients.update_client(
75
+ client_id="client-1",
76
+ project_id="project-1",
77
+ logo_url="https://example.com/logo.svg",
78
+ theme=Theme.dark,
79
+ )
80
+ api.update_oauth_client.assert_awaited_once_with(
81
+ project_id="project-1",
82
+ client_id="client-1",
83
+ metadata={
84
+ "name": "Existing",
85
+ "custom": "preserved",
86
+ "logo_url": "https://example.com/logo.svg",
87
+ "theme": "dark",
88
+ },
89
+ )
@@ -1667,7 +1667,7 @@ def _websocket_iap_cookie_headers(
1667
1667
  raise typer.BadParameter(
1668
1668
  "a room participant token is required for --websocket-auth=iap"
1669
1669
  )
1670
- return {"Cookie": f"__Host-meshagent_iap={token.strip()}"}
1670
+ return {"Cookie": f"__meshagent_iap={token.strip()}"}
1671
1671
 
1672
1672
 
1673
1673
  def _process_use_websocket_headers(
@@ -598,7 +598,7 @@ def test_process_use_websocket_headers_set_iap_cookie() -> None:
598
598
  iap_token="room-jwt",
599
599
  )
600
600
 
601
- assert headers == {"Cookie": "__Host-meshagent_iap=room-jwt"}
601
+ assert headers == {"Cookie": "__meshagent_iap=room-jwt"}
602
602
 
603
603
 
604
604
  def test_process_use_websocket_headers_sign_agent_participant_token(
@@ -4,12 +4,14 @@ from pathlib import Path
4
4
  from typing import Annotated, Literal
5
5
 
6
6
  import typer
7
+ import yaml
7
8
  from pydantic import BaseModel, ConfigDict
8
9
  from pydantic_yaml import parse_yaml_raw_as
9
10
  from rich import print
10
11
 
11
12
  from meshagent.api import ApiScope
12
13
  from meshagent.api.client import Meshagent, NotFoundError, ProjectInfo, ProjectsPage
14
+ from meshagent.api.llm_router_config import LlmRouterConfig
13
15
  from meshagent.cli import async_typer
14
16
  from meshagent.cli.common_options import OutputFormatOption, ProjectIdOption
15
17
  from meshagent.cli.helper import (
@@ -282,6 +284,84 @@ async def reset_room_roles(project_id: ProjectIdOption):
282
284
  await client.close()
283
285
 
284
286
 
287
+ @app.async_command(
288
+ "get-llm-router-config",
289
+ help=(
290
+ "Get the complete LLM router configuration as YAML. The document "
291
+ "contains allowedModels, apps, and rules."
292
+ ),
293
+ )
294
+ async def get_llm_router_config(
295
+ project_id: ProjectIdOption,
296
+ output: Annotated[
297
+ Path | None,
298
+ typer.Option(
299
+ "--output", "-o", help="Write YAML to this file instead of stdout."
300
+ ),
301
+ ] = None,
302
+ ):
303
+ client = await get_client()
304
+ try:
305
+ resolved_project_id = await resolve_project_id(project_id)
306
+ document = await client.get_project_settings_document(
307
+ resolved_project_id, "router"
308
+ )
309
+ try:
310
+ config = LlmRouterConfig.model_validate(document or {})
311
+ except ValueError as error:
312
+ print(f"[red]The stored LLM router configuration is invalid: {error}[/red]")
313
+ raise typer.Exit(code=1) from error
314
+ serialized = yaml.safe_dump(
315
+ config.to_document(),
316
+ sort_keys=False,
317
+ allow_unicode=True,
318
+ )
319
+ if output is None:
320
+ typer.echo(serialized, nl=False)
321
+ else:
322
+ try:
323
+ output.write_text(serialized)
324
+ except OSError as error:
325
+ print(f"[red]Unable to write LLM router configuration: {error}[/red]")
326
+ raise typer.Exit(code=1) from error
327
+ finally:
328
+ await client.close()
329
+
330
+
331
+ @app.async_command(
332
+ "set-llm-router-config",
333
+ help=(
334
+ "Validate and replace allowedModels, apps, and rules from YAML. "
335
+ "Providers: openai, anthropic, grok. APIs: completions, "
336
+ "chat_completions, responses, messages, realtime. Transports: http, "
337
+ "websocket. App modes: allowed, blocked. Ensure tools: web_search, "
338
+ "static, advice; other tool types are filter-only. Search context: "
339
+ "low, medium, high. Advice strategy: parallel."
340
+ ),
341
+ )
342
+ async def set_llm_router_config(
343
+ file: Annotated[Path, typer.Argument(help="LLM router configuration YAML")],
344
+ project_id: ProjectIdOption,
345
+ ):
346
+ try:
347
+ config = parse_yaml_raw_as(LlmRouterConfig, file.read_text())
348
+ except (OSError, ValueError) as error:
349
+ print(f"[red]Invalid LLM router configuration: {error}[/red]")
350
+ raise typer.Exit(code=1) from error
351
+
352
+ client = await get_client()
353
+ try:
354
+ resolved_project_id = await resolve_project_id(project_id)
355
+ await client.set_project_settings_document(
356
+ resolved_project_id,
357
+ "router",
358
+ config.to_document(),
359
+ )
360
+ print(f"[green]LLM router configuration updated:[/] {resolved_project_id}")
361
+ finally:
362
+ await client.close()
363
+
364
+
285
365
  @app.async_command(
286
366
  "activate", help="Set the active project for subsequent CLI commands."
287
367
  )