nextmv 1.3.1.dev0__tar.gz → 1.3.1.dev2__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 (353) hide show
  1. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/.gitignore +0 -1
  2. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/PKG-INFO +1 -5
  3. nextmv-1.3.1.dev2/nextmv/__about__.py +1 -0
  4. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/main.py +8 -2
  5. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/mcp/__init__.py +13 -1
  6. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/mcp/serve.py +1 -11
  7. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/mcp/server.py +16 -2
  8. nextmv-1.3.1.dev2/nextmv/cli/mcp/tools/_helpers.py +316 -0
  9. nextmv-1.3.1.dev2/nextmv/cli/mcp/tools/guide.py +424 -0
  10. nextmv-1.3.1.dev2/nextmv/cli/mcp/tools/local.py +431 -0
  11. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/mcp/tools/profile.py +2 -2
  12. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/mcp/tools/run.py +153 -28
  13. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/mcp/tools/scenario.py +11 -173
  14. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/application/_batch_scenario.py +15 -0
  15. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/pyproject.toml +0 -5
  16. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/cli/test_mcp.py +973 -117
  17. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/uv.lock +1 -9
  18. nextmv-1.3.1.dev0/nextmv/__about__.py +0 -1
  19. nextmv-1.3.1.dev0/nextmv/cli/mcp/tools/_helpers.py +0 -126
  20. nextmv-1.3.1.dev0/nextmv/cli/mcp/tools/local.py +0 -361
  21. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/.python-version +0 -0
  22. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/CONTRIBUTING.md +0 -0
  23. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/LICENSE +0 -0
  24. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/README.md +0 -0
  25. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/__entrypoint__.py +0 -0
  26. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/__init__.py +0 -0
  27. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/_serialization.py +0 -0
  28. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/base_model.py +0 -0
  29. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/__init__.py +0 -0
  30. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/__init__.py +0 -0
  31. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/acceptance/__init__.py +0 -0
  32. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/acceptance/create.py +0 -0
  33. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/acceptance/delete.py +0 -0
  34. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/acceptance/get.py +0 -0
  35. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/acceptance/list.py +0 -0
  36. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/acceptance/update.py +0 -0
  37. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/account/__init__.py +0 -0
  38. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/account/create.py +0 -0
  39. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/account/delete.py +0 -0
  40. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/account/get.py +0 -0
  41. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/account/update.py +0 -0
  42. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/app/__init__.py +0 -0
  43. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/app/create.py +0 -0
  44. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/app/delete.py +0 -0
  45. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/app/exists.py +0 -0
  46. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/app/get.py +0 -0
  47. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/app/list.py +0 -0
  48. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/app/push.py +0 -0
  49. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/app/update.py +0 -0
  50. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/batch/__init__.py +0 -0
  51. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/batch/create.py +0 -0
  52. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/batch/delete.py +0 -0
  53. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/batch/get.py +0 -0
  54. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/batch/list.py +0 -0
  55. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/batch/metadata.py +0 -0
  56. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/batch/update.py +0 -0
  57. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/data/__init__.py +0 -0
  58. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/data/upload.py +0 -0
  59. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/ensemble/__init__.py +0 -0
  60. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/ensemble/create.py +0 -0
  61. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/ensemble/delete.py +0 -0
  62. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/ensemble/get.py +0 -0
  63. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/ensemble/list.py +0 -0
  64. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/ensemble/update.py +0 -0
  65. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/input_set/__init__.py +0 -0
  66. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/input_set/create.py +0 -0
  67. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/input_set/delete.py +0 -0
  68. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/input_set/get.py +0 -0
  69. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/input_set/list.py +0 -0
  70. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/input_set/update.py +0 -0
  71. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/instance/__init__.py +0 -0
  72. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/instance/create.py +0 -0
  73. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/instance/delete.py +0 -0
  74. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/instance/exists.py +0 -0
  75. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/instance/get.py +0 -0
  76. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/instance/list.py +0 -0
  77. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/instance/update.py +0 -0
  78. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/managed_input/__init__.py +0 -0
  79. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/managed_input/create.py +0 -0
  80. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/managed_input/delete.py +0 -0
  81. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/managed_input/get.py +0 -0
  82. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/managed_input/list.py +0 -0
  83. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/managed_input/update.py +0 -0
  84. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/marketplace/__init__.py +0 -0
  85. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/marketplace/app/__init__.py +0 -0
  86. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/marketplace/app/create.py +0 -0
  87. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/marketplace/app/get.py +0 -0
  88. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/marketplace/app/list.py +0 -0
  89. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/marketplace/app/update.py +0 -0
  90. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/marketplace/subscription/__init__.py +0 -0
  91. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/marketplace/subscription/create.py +0 -0
  92. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/marketplace/subscription/delete.py +0 -0
  93. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/marketplace/subscription/get.py +0 -0
  94. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/marketplace/subscription/list.py +0 -0
  95. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/marketplace/version/__init__.py +0 -0
  96. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/marketplace/version/create.py +0 -0
  97. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/marketplace/version/get.py +0 -0
  98. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/marketplace/version/list.py +0 -0
  99. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/marketplace/version/update.py +0 -0
  100. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/run/__init__.py +0 -0
  101. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/run/cancel.py +0 -0
  102. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/run/create.py +0 -0
  103. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/run/get.py +0 -0
  104. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/run/input.py +0 -0
  105. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/run/list.py +0 -0
  106. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/run/logs.py +0 -0
  107. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/run/metadata.py +0 -0
  108. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/run/track.py +0 -0
  109. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/scenario/__init__.py +0 -0
  110. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/scenario/create.py +0 -0
  111. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/scenario/delete.py +0 -0
  112. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/scenario/get.py +0 -0
  113. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/scenario/list.py +0 -0
  114. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/scenario/metadata.py +0 -0
  115. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/scenario/update.py +0 -0
  116. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/secrets/__init__.py +0 -0
  117. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/secrets/create.py +0 -0
  118. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/secrets/delete.py +0 -0
  119. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/secrets/get.py +0 -0
  120. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/secrets/list.py +0 -0
  121. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/secrets/update.py +0 -0
  122. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/shadow/__init__.py +0 -0
  123. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/shadow/create.py +0 -0
  124. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/shadow/delete.py +0 -0
  125. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/shadow/get.py +0 -0
  126. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/shadow/list.py +0 -0
  127. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/shadow/metadata.py +0 -0
  128. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/shadow/start.py +0 -0
  129. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/shadow/stop.py +0 -0
  130. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/shadow/update.py +0 -0
  131. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/sso/__init__.py +0 -0
  132. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/sso/create.py +0 -0
  133. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/sso/delete.py +0 -0
  134. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/sso/disable.py +0 -0
  135. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/sso/domain/__init__.py +0 -0
  136. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/sso/domain/delete.py +0 -0
  137. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/sso/enable.py +0 -0
  138. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/sso/get.py +0 -0
  139. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/sso/update.py +0 -0
  140. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/switchback/__init__.py +0 -0
  141. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/switchback/create.py +0 -0
  142. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/switchback/delete.py +0 -0
  143. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/switchback/get.py +0 -0
  144. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/switchback/list.py +0 -0
  145. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/switchback/metadata.py +0 -0
  146. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/switchback/start.py +0 -0
  147. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/switchback/stop.py +0 -0
  148. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/switchback/update.py +0 -0
  149. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/upload/__init__.py +0 -0
  150. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/upload/create.py +0 -0
  151. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/version/__init__.py +0 -0
  152. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/version/create.py +0 -0
  153. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/version/delete.py +0 -0
  154. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/version/exists.py +0 -0
  155. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/version/get.py +0 -0
  156. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/version/list.py +0 -0
  157. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/version/update.py +0 -0
  158. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/community/__init__.py +0 -0
  159. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/community/clone.py +0 -0
  160. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/community/list.py +0 -0
  161. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/configuration/__init__.py +0 -0
  162. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/configuration/config.py +0 -0
  163. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/configuration/create.py +0 -0
  164. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/configuration/delete.py +0 -0
  165. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/configuration/list.py +0 -0
  166. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/init.py +0 -0
  167. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/local/__init__.py +0 -0
  168. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/local/app/__init__.py +0 -0
  169. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/local/app/delete.py +0 -0
  170. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/local/app/get.py +0 -0
  171. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/local/app/list.py +0 -0
  172. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/local/app/register.py +0 -0
  173. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/local/app/registered.py +0 -0
  174. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/local/app/sync.py +0 -0
  175. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/local/app/update.py +0 -0
  176. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/local/run/__init__.py +0 -0
  177. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/local/run/create.py +0 -0
  178. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/local/run/get.py +0 -0
  179. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/local/run/input.py +0 -0
  180. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/local/run/list.py +0 -0
  181. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/local/run/logs.py +0 -0
  182. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/local/run/metadata.py +0 -0
  183. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/local/run/visuals.py +0 -0
  184. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/manifest/__init__.py +0 -0
  185. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/manifest/init.py +0 -0
  186. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/manifest/validate.py +0 -0
  187. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/mcp/tools/__init__.py +0 -0
  188. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/mcp/tools/acceptance.py +0 -0
  189. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/mcp/tools/account.py +0 -0
  190. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/mcp/tools/app.py +0 -0
  191. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/mcp/tools/batch.py +0 -0
  192. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/mcp/tools/community.py +0 -0
  193. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/mcp/tools/ensemble.py +0 -0
  194. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/mcp/tools/input_set.py +0 -0
  195. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/mcp/tools/instance.py +0 -0
  196. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/mcp/tools/managed_input.py +0 -0
  197. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/mcp/tools/secrets.py +0 -0
  198. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/mcp/tools/shadow.py +0 -0
  199. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/mcp/tools/sso.py +0 -0
  200. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/mcp/tools/switchback.py +0 -0
  201. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/mcp/tools/version.py +0 -0
  202. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/message.py +0 -0
  203. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/options.py +0 -0
  204. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/version.py +0 -0
  205. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/__init__.py +0 -0
  206. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/acceptance_test.py +0 -0
  207. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/account.py +0 -0
  208. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/application/__init__.py +0 -0
  209. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/application/_acceptance.py +0 -0
  210. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/application/_ensemble.py +0 -0
  211. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/application/_input_set.py +0 -0
  212. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/application/_instance.py +0 -0
  213. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/application/_managed_input.py +0 -0
  214. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/application/_run.py +0 -0
  215. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/application/_secrets.py +0 -0
  216. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/application/_shadow.py +0 -0
  217. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/application/_switchback.py +0 -0
  218. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/application/_utils.py +0 -0
  219. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/application/_version.py +0 -0
  220. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/assets.py +0 -0
  221. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/batch_experiment.py +0 -0
  222. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/client.py +0 -0
  223. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/community.py +0 -0
  224. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/ensemble.py +0 -0
  225. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/input_set.py +0 -0
  226. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/instance.py +0 -0
  227. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/integration.py +0 -0
  228. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/marketplace.py +0 -0
  229. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/package.py +0 -0
  230. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/scenario.py +0 -0
  231. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/secrets.py +0 -0
  232. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/shadow.py +0 -0
  233. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/sso.py +0 -0
  234. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/switchback.py +0 -0
  235. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/url.py +0 -0
  236. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/version.py +0 -0
  237. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/content_format.py +0 -0
  238. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/default_app/.gitignore +0 -0
  239. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/default_app/README.md +0 -0
  240. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/default_app/app.yaml +0 -0
  241. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/default_app/input.json +0 -0
  242. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/default_app/main.py +0 -0
  243. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/default_app/requirements.txt +0 -0
  244. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/default_app/src/__init__.py +0 -0
  245. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/default_app/src/visuals.py +0 -0
  246. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/deprecated.py +0 -0
  247. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/input.py +0 -0
  248. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/local/__init__.py +0 -0
  249. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/local/application.py +0 -0
  250. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/local/executor.py +0 -0
  251. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/local/geojson_handler.py +0 -0
  252. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/local/local.py +0 -0
  253. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/local/plotly_handler.py +0 -0
  254. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/local/registry.py +0 -0
  255. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/local/runner.py +0 -0
  256. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/logger.py +0 -0
  257. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/manifest.py +0 -0
  258. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/model.py +0 -0
  259. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/options.py +0 -0
  260. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/output.py +0 -0
  261. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/polling.py +0 -0
  262. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/run.py +0 -0
  263. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/safe.py +0 -0
  264. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/status.py +0 -0
  265. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/binary_json_app.yaml +0 -0
  266. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/binary_multi-file_app.yaml +0 -0
  267. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/go_json_app.yaml +0 -0
  268. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/go_json_template/.gitignore +0 -0
  269. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/go_json_template/README.md +0 -0
  270. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/go_json_template/app.yaml +0 -0
  271. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/go_json_template/go.mod +0 -0
  272. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/go_json_template/input.json +0 -0
  273. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/go_json_template/main.go +0 -0
  274. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/go_multi-file_app.yaml +0 -0
  275. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/go_multi-file_template/.gitignore +0 -0
  276. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/go_multi-file_template/README.md +0 -0
  277. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/go_multi-file_template/app.yaml +0 -0
  278. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/go_multi-file_template/go.mod +0 -0
  279. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/go_multi-file_template/inputs/input.json +0 -0
  280. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/go_multi-file_template/main.go +0 -0
  281. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/java_json_app.yaml +0 -0
  282. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/java_json_template/.gitignore +0 -0
  283. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/java_json_template/Main.java +0 -0
  284. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/java_json_template/README.md +0 -0
  285. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/java_json_template/app.yaml +0 -0
  286. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/java_json_template/input.json +0 -0
  287. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/java_json_template/pom.xml +0 -0
  288. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/java_multi-file_app.yaml +0 -0
  289. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/java_multi-file_template/.gitignore +0 -0
  290. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/java_multi-file_template/Main.java +0 -0
  291. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/java_multi-file_template/README.md +0 -0
  292. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/java_multi-file_template/app.yaml +0 -0
  293. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/java_multi-file_template/inputs/input.json +0 -0
  294. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/java_multi-file_template/pom.xml +0 -0
  295. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/python_json_app.yaml +0 -0
  296. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/python_json_template/.gitignore +0 -0
  297. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/python_json_template/README.md +0 -0
  298. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/python_json_template/app.yaml +0 -0
  299. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/python_json_template/input.json +0 -0
  300. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/python_json_template/main.py +0 -0
  301. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/python_json_template/requirements.txt +0 -0
  302. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/python_multi-file_app.yaml +0 -0
  303. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/python_multi-file_template/.gitignore +0 -0
  304. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/python_multi-file_template/README.md +0 -0
  305. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/python_multi-file_template/app.yaml +0 -0
  306. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/python_multi-file_template/inputs/input.json +0 -0
  307. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/python_multi-file_template/main.py +0 -0
  308. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/python_multi-file_template/requirements.txt +0 -0
  309. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/__init__.py +0 -0
  310. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/cli/__init__.py +0 -0
  311. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/cli/test_configuration.py +0 -0
  312. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/cli/test_main.py +0 -0
  313. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/cli/test_version.py +0 -0
  314. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/cloud/__init__.py +0 -0
  315. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/cloud/app.yaml +0 -0
  316. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/cloud/test_client.py +0 -0
  317. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/cloud/test_instance.py +0 -0
  318. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/cloud/test_package.py +0 -0
  319. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/cloud/test_scenario.py +0 -0
  320. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/integration/__init__.py +0 -0
  321. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/integration/cloud/__init__.py +0 -0
  322. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/integration/cloud/test_integration_cloud.py +0 -0
  323. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/integration/cloud/test_integration_marketplace.py +0 -0
  324. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/local/__init__.py +0 -0
  325. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/local/test_application.py +0 -0
  326. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/local/test_executor.py +0 -0
  327. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/local/test_registry.py +0 -0
  328. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/local/test_runner.py +0 -0
  329. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/scripts/__init__.py +0 -0
  330. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/scripts/options1.py +0 -0
  331. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/scripts/options2.py +0 -0
  332. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/scripts/options3.py +0 -0
  333. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/scripts/options4.py +0 -0
  334. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/scripts/options5.py +0 -0
  335. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/scripts/options6.py +0 -0
  336. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/scripts/options7.py +0 -0
  337. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/test_base_model.py +0 -0
  338. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/test_entrypoint/__init__.py +0 -0
  339. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/test_entrypoint/test_entrypoint.py +0 -0
  340. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/test_input.py +0 -0
  341. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/test_inputs/test_data.csv +0 -0
  342. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/test_inputs/test_data.json +0 -0
  343. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/test_inputs/test_data.txt +0 -0
  344. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/test_logger.py +0 -0
  345. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/test_manifest.py +0 -0
  346. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/test_model.py +0 -0
  347. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/test_options.py +0 -0
  348. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/test_output.py +0 -0
  349. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/test_polling.py +0 -0
  350. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/test_run.py +0 -0
  351. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/test_safe.py +0 -0
  352. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/test_serialization.py +0 -0
  353. {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/test_version.py +0 -0
@@ -168,4 +168,3 @@ cython_debug/
168
168
  site/
169
169
 
170
170
  scratch
171
- .claude
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nextmv
3
- Version: 1.3.1.dev0
3
+ Version: 1.3.1.dev2
4
4
  Summary: The all-purpose Python SDK for Nextmv
5
5
  Project-URL: Homepage, https://www.nextmv.io
6
6
  Project-URL: Documentation, https://nextmv-py.docs.nextmv.io/en/latest/nextmv/
@@ -227,10 +227,6 @@ Requires-Dist: questionary>=2.1.1
227
227
  Requires-Dist: requests>=2.31.0
228
228
  Requires-Dist: typer>=0.20.1
229
229
  Requires-Dist: urllib3>=2.1.0
230
- Provides-Extra: all
231
- Requires-Dist: folium>=0.20.0; extra == 'all'
232
- Requires-Dist: mcp[cli]>=1.0; extra == 'all'
233
- Requires-Dist: plotly>=6.0.1; extra == 'all'
234
230
  Provides-Extra: mcp
235
231
  Requires-Dist: mcp[cli]>=1.0; extra == 'mcp'
236
232
  Provides-Extra: notebook
@@ -0,0 +1 @@
1
+ __version__ = "v1.3.1.dev2"
@@ -27,7 +27,6 @@ from nextmv.cli.configuration.config import CONFIG_DIR, GO_CLI_PATH, load_config
27
27
  from nextmv.cli.init import app as init_app
28
28
  from nextmv.cli.local import app as local_app
29
29
  from nextmv.cli.manifest import app as manifest_app
30
- from nextmv.cli.mcp import app as mcp_app
31
30
  from nextmv.cli.message import confirmation, error, info, success, warning
32
31
  from nextmv.cli.version import app as version_app
33
32
  from nextmv.cli.version import version_callback
@@ -54,9 +53,16 @@ app.add_typer(configuration_app, name="configuration")
54
53
  app.add_typer(init_app)
55
54
  app.add_typer(local_app, name="local")
56
55
  app.add_typer(manifest_app, name="manifest")
57
- app.add_typer(mcp_app, name="mcp")
58
56
  app.add_typer(version_app)
59
57
 
58
+ # Register the MCP subcommand only if the mcp extra is installed.
59
+ try:
60
+ from nextmv.cli.mcp import app as mcp_app
61
+
62
+ app.add_typer(mcp_app, name="mcp", rich_help_panel="Preview")
63
+ except ImportError:
64
+ pass
65
+
60
66
 
61
67
  @app.callback()
62
68
  def callback(
@@ -1,4 +1,16 @@
1
- """MCP (Model Context Protocol) server for the Nextmv CLI."""
1
+ """MCP (Model Context Protocol) server for the Nextmv CLI.
2
+
3
+ Requires the ``mcp`` optional extra: ``pip install nextmv[mcp]``.
4
+ """
5
+
6
+ # Fail fast at import time so that main.py's try/except can gate the
7
+ # subcommand registration.
8
+ import importlib.util
9
+
10
+ if importlib.util.find_spec("mcp") is None:
11
+ raise ImportError(
12
+ "The mcp extra is not installed. Install it with: pip install nextmv[mcp]"
13
+ )
2
14
 
3
15
  import typer
4
16
 
@@ -39,9 +39,6 @@ def serve(
39
39
  [magenta]stdio[/magenta], which is what Claude Code, Cursor, and most
40
40
  local clients expect.
41
41
 
42
- Requires the [magenta]mcp[/magenta] optional dependency. Install with:
43
- [code]pip install 'nextmv[mcp]'[/code]
44
-
45
42
  [bold][underline]Examples[/underline][/bold]
46
43
 
47
44
  - Start the MCP server with stdio transport (default).
@@ -54,14 +51,7 @@ def serve(
54
51
  $ [dim]claude mcp add nextmv -- nextmv mcp serve[/dim]
55
52
  """
56
53
 
57
- try:
58
- from nextmv.cli.mcp.server import create_server
59
- except ImportError:
60
- error(
61
- "MCP support requires the [magenta]mcp[/magenta] package. "
62
- "Install with: [code]pip install 'nextmv[mcp]'[/code]"
63
- )
64
- return # unreachable, error() raises
54
+ from nextmv.cli.mcp.server import create_server
65
55
 
66
56
  server = create_server()
67
57
 
@@ -15,6 +15,7 @@ from nextmv.cli.mcp.tools import (
15
15
  batch,
16
16
  community,
17
17
  ensemble,
18
+ guide,
18
19
  input_set,
19
20
  instance,
20
21
  local,
@@ -32,12 +33,12 @@ from nextmv.cli.mcp.tools import (
32
33
  # Re-export helpers for backward compatibility — tests and external code
33
34
  # may import these directly from ``nextmv.cli.mcp.server``.
34
35
  from nextmv.cli.mcp.tools._helpers import ( # noqa: F401
35
- _current_profile,
36
36
  _get_app,
37
37
  _get_client,
38
38
  _get_local_app,
39
39
  _mask_key,
40
40
  _save_to_file,
41
+ session,
41
42
  )
42
43
 
43
44
  # Re-export SDK names that tests patch on this module.
@@ -69,7 +70,17 @@ def create_server() -> FastMCP:
69
70
  "to use a specific profile (e.g. \"list apps in my dev "
70
71
  "profile\"), call cloud_set_profile first. Always state which "
71
72
  "profile you are using when calling cloud tools, e.g. "
72
- "(profile: \"default\")."
73
+ "(profile: \"default\").\n\n"
74
+ "CLOUD RUN CACHE: Cloud run data (results, inputs, logs) is "
75
+ "cached locally at ~/.nextmv/runs/{endpoint}/{run_id}/ using "
76
+ "the same directory layout as local runs. The {endpoint} is the "
77
+ "API endpoint (e.g. api.cloud.nextmv.io). If a file already "
78
+ "exists there, it will not be re-downloaded. You can read "
79
+ "cached cloud run data directly from these paths without "
80
+ "calling the cloud tools again.\n\n"
81
+ "WORKFLOW GUIDE: When creating a new app, deploying to Cloud, "
82
+ "or running experiments, call the nextmv_workflow_guide tool "
83
+ "first to get the step-by-step workflow and coding patterns."
73
84
  ),
74
85
  )
75
86
 
@@ -97,4 +108,7 @@ def create_server() -> FastMCP:
97
108
  # Local tools
98
109
  local.register(mcp)
99
110
 
111
+ # Workflow guide
112
+ guide.register(mcp)
113
+
100
114
  return mcp
@@ -0,0 +1,316 @@
1
+ """Shared helpers for MCP tool modules."""
2
+
3
+ import contextvars
4
+ import json
5
+ import logging
6
+ import os
7
+ import tempfile
8
+ from typing import Any
9
+
10
+ from nextmv import local
11
+ from nextmv.cloud import Application, Client
12
+ from nextmv.local.local import LOGS_FILE, LOGS_KEY
13
+ from nextmv.output import ASSETS_KEY, METRICS_KEY, OUTPUTS_KEY, SOLUTIONS_KEY, STATISTICS_KEY
14
+
15
+ logger = logging.getLogger(__name__)
16
+
17
+
18
+ class ProfileSession:
19
+ """Manages the active Nextmv Cloud profile for the current async context.
20
+
21
+ Uses ``contextvars.ContextVar`` internally so that each async task
22
+ (and therefore each concurrent HTTP request in streamable-http
23
+ transport) gets its own isolated profile state.
24
+ """
25
+
26
+ def __init__(self) -> None:
27
+ self._profile: contextvars.ContextVar[str | None] = contextvars.ContextVar(
28
+ "nextmv_profile", default=None,
29
+ )
30
+
31
+ @property
32
+ def profile(self) -> str | None:
33
+ """Return the current profile name, or ``None`` for the default."""
34
+
35
+ return self._profile.get()
36
+
37
+ @profile.setter
38
+ def profile(self, value: str | None) -> None:
39
+ self._profile.set(value)
40
+
41
+ def get_client(self, profile: str | None = None) -> Client:
42
+ """Build a Nextmv Cloud client from env var or CLI config.
43
+
44
+ Checks for credentials in the following order:
45
+
46
+ 1. ``NEXTMV_API_KEY`` environment variable (unless a profile is active).
47
+ 2. CLI configuration file at ``~/.nextmv/config.yaml``.
48
+
49
+ Args:
50
+ profile: Optional profile name override. If not provided, uses
51
+ the session-level profile.
52
+ """
53
+
54
+ resolved = profile or self.profile
55
+
56
+ api_key = os.getenv("NEXTMV_API_KEY")
57
+ if api_key and not resolved:
58
+ endpoint = os.getenv("NEXTMV_ENDPOINT", "https://api.cloud.nextmv.io")
59
+ if not endpoint.startswith("http"):
60
+ endpoint = f"https://{endpoint}"
61
+ return Client(api_key=api_key, url=endpoint)
62
+
63
+ # Fall back to the CLI configuration file (~/.nextmv/config.yaml).
64
+ try:
65
+ from nextmv.cli.configuration.config import build_client
66
+
67
+ # "default" means use top-level keys (profile=None in build_client).
68
+ p = None if resolved is None or resolved == "default" else resolved
69
+ return build_client(profile=p)
70
+ except Exception as e:
71
+ raise ValueError(
72
+ f"Could not build a Nextmv client: {e}. Either set the "
73
+ "NEXTMV_API_KEY environment variable or configure the "
74
+ "CLI with: nextmv configuration create"
75
+ ) from e
76
+
77
+ def get_app(self, app_id: str, profile: str | None = None) -> Application:
78
+ """Build a cloud Application handle for the given ID."""
79
+
80
+ client = self.get_client(profile=profile)
81
+ return Application(client=client, id=app_id)
82
+
83
+
84
+ # Singleton session used by all MCP tool modules.
85
+ session = ProfileSession()
86
+
87
+
88
+ def _mask_key(key: str | None) -> str | None:
89
+ """Mask an API key, keeping only the last 4 characters visible."""
90
+
91
+ if not key:
92
+ return None
93
+ if len(key) <= 4:
94
+ return key
95
+ return "X" * (len(key) - 4) + key[-4:]
96
+
97
+
98
+ # ---------------------------------------------------------------------------
99
+ # Convenience aliases so tool modules can call ``_helpers._get_client()``
100
+ # without reaching into ``session`` directly.
101
+ # ---------------------------------------------------------------------------
102
+
103
+
104
+ def _get_client(profile: str | None = None) -> Client:
105
+ return session.get_client(profile=profile)
106
+
107
+
108
+ def _get_app(app_id: str, profile: str | None = None) -> Application:
109
+ return session.get_app(app_id=app_id, profile=profile)
110
+
111
+
112
+ def _get_local_app(app_dir: str, app_id: str | None = None) -> local.Application:
113
+ """Build a local Application, registering it if needed."""
114
+
115
+ app, _ = local.Application.get_or_register(app_src=app_dir, app_id=app_id)
116
+ return app
117
+
118
+
119
+ def _build_run_configuration(content_format: str | None):
120
+ """Build a RunConfiguration for the given content format string, or None."""
121
+
122
+ if content_format is None:
123
+ return None
124
+
125
+ from nextmv.input import InputFormat
126
+ from nextmv.run import Format, FormatInput, RunConfiguration
127
+
128
+ config = RunConfiguration()
129
+ config.format = Format(
130
+ format_input=FormatInput(
131
+ input_type=InputFormat(content_format),
132
+ ),
133
+ )
134
+ return config
135
+
136
+
137
+ def _none_if_empty(value: str | None) -> str | None:
138
+ """Convert empty or whitespace-only strings to None.
139
+
140
+ LLMs sometimes pass ``""`` instead of omitting optional parameters.
141
+ This normalises empty strings so downstream code sees ``None``.
142
+ Whitespace-only strings (e.g. ``" "``) are also treated as empty.
143
+ """
144
+
145
+ if value is None or not value.strip():
146
+ return None
147
+ return value.strip()
148
+
149
+
150
+ def _require_non_empty(value: str, name: str) -> str:
151
+ """Raise a clear error when a required string parameter is empty."""
152
+
153
+ if not value or not value.strip():
154
+ raise ValueError(f"'{name}' is required and must not be empty.")
155
+ return value.strip()
156
+
157
+
158
+ def _save_to_file(data: Any, prefix: str) -> str:
159
+ """Serialize data to a temp JSON file and return a message with the path.
160
+
161
+ This keeps large payloads out of the MCP response (and thus out of
162
+ the LLM context window). The caller can selectively read the file
163
+ using standard file-reading tools.
164
+ """
165
+
166
+ fd, path = tempfile.mkstemp(suffix=".json", prefix=f"{prefix}_")
167
+ with os.fdopen(fd, "w") as fh:
168
+ json.dump(data, fh, indent=2)
169
+ return f"Data saved to {path} — use file-reading tools to inspect the contents."
170
+
171
+
172
+ def _cloud_run_dir(endpoint: str, run_id: str) -> str:
173
+ """Build the local cache directory for a cloud run.
174
+
175
+ Returns ``~/.nextmv/runs/{endpoint}/{run_id}``. The *endpoint*
176
+ parameter should already have the URL scheme (``https://`` /
177
+ ``http://``) stripped.
178
+ """
179
+
180
+ return os.path.join(os.path.expanduser("~"), ".nextmv", "runs", endpoint, run_id)
181
+
182
+
183
+ def _cloud_run_file_exists(endpoint: str, run_id: str, *path_parts: str) -> str | None:
184
+ """Return the file path if a cached cloud run file exists, else None.
185
+
186
+ Args:
187
+ endpoint: API endpoint with scheme stripped.
188
+ run_id: The run ID.
189
+ *path_parts: Path components relative to the run directory
190
+ (e.g. ``"inputs", "input.json"``).
191
+ """
192
+
193
+ path = os.path.join(_cloud_run_dir(endpoint, run_id), *path_parts)
194
+ return path if os.path.exists(path) else None
195
+
196
+
197
+ def _endpoint_from_app(app: Application) -> str:
198
+ """Return the API endpoint from an Application with scheme stripped."""
199
+
200
+ url: str = app.client.url
201
+ for scheme in ("https://", "http://"):
202
+ if url.startswith(scheme):
203
+ url = url[len(scheme):]
204
+ break
205
+ return url
206
+
207
+
208
+ def _save_cloud_run_file(data: Any, endpoint: str, run_id: str, *path_parts: str) -> str:
209
+ """Serialize *data* as JSON into the cloud run cache and return the path.
210
+
211
+ Creates intermediate directories as needed. The *endpoint* parameter
212
+ should already have the URL scheme stripped.
213
+ """
214
+
215
+ path = os.path.join(_cloud_run_dir(endpoint, run_id), *path_parts)
216
+ os.makedirs(os.path.dirname(path), exist_ok=True)
217
+ with open(path, "w") as fh:
218
+ json.dump(data, fh, indent=2)
219
+ return path
220
+
221
+
222
+ def _extract_cloud_run_outputs(result_dict: dict[str, Any], endpoint: str, run_id: str) -> None:
223
+ """Extract output components from a cloud result into separate files.
224
+
225
+ Mirrors the local run ``outputs/`` directory structure:
226
+
227
+ * ``outputs/solutions/solution.json`` — the full output dict (matches local)
228
+ * ``outputs/metrics/metrics.json`` — raw metrics value
229
+ * ``outputs/statistics/statistics.json`` — wrapped as ``{"statistics": ...}``
230
+ * ``outputs/assets/assets.json`` — wrapped as ``{"assets": ...}``
231
+
232
+ Skipped when *output* is not a dict with inline data (e.g. csv-archive
233
+ results where the SDK already extracted files via ``output_dir_path``).
234
+ """
235
+
236
+ output = result_dict.get("output")
237
+ if not isinstance(output, dict) or "solution" not in output:
238
+ return
239
+
240
+ run_dir = _cloud_run_dir(endpoint, run_id)
241
+ outputs_dir = os.path.join(run_dir, OUTPUTS_KEY)
242
+
243
+ # solution → outputs/solutions/solution.json
244
+ # Local writes the entire stdout output dict here, so we do the same.
245
+ path = os.path.join(outputs_dir, SOLUTIONS_KEY, "solution.json")
246
+ os.makedirs(os.path.dirname(path), exist_ok=True)
247
+ with open(path, "w") as fh:
248
+ json.dump(output, fh, indent=2)
249
+
250
+ # metrics → outputs/metrics/metrics.json (raw, matching local)
251
+ metrics = output.get(METRICS_KEY)
252
+ if metrics:
253
+ path = os.path.join(outputs_dir, METRICS_KEY, f"{METRICS_KEY}.json")
254
+ os.makedirs(os.path.dirname(path), exist_ok=True)
255
+ with open(path, "w") as fh:
256
+ json.dump(metrics, fh, indent=2)
257
+
258
+ # statistics → outputs/statistics/statistics.json (wrapped, matching local)
259
+ statistics = output.get(STATISTICS_KEY)
260
+ if statistics:
261
+ path = os.path.join(outputs_dir, STATISTICS_KEY, f"{STATISTICS_KEY}.json")
262
+ os.makedirs(os.path.dirname(path), exist_ok=True)
263
+ with open(path, "w") as fh:
264
+ json.dump({STATISTICS_KEY: statistics}, fh, indent=2)
265
+
266
+ # assets → outputs/assets/assets.json (wrapped, matching local)
267
+ assets = output.get(ASSETS_KEY)
268
+ if assets:
269
+ path = os.path.join(outputs_dir, ASSETS_KEY, f"{ASSETS_KEY}.json")
270
+ os.makedirs(os.path.dirname(path), exist_ok=True)
271
+ with open(path, "w") as fh:
272
+ json.dump({ASSETS_KEY: assets}, fh, indent=2)
273
+
274
+ # Generate visuals from assets (Plotly/GeoJSON → HTML), matching local.
275
+ try:
276
+ from nextmv.local.executor import process_run_visuals
277
+
278
+ process_run_visuals(run_dir=run_dir, outputs_dir=outputs_dir)
279
+ except Exception as exc:
280
+ logger.warning("Visual generation failed for run %s: %s", run_id, exc)
281
+
282
+
283
+ def _save_cloud_run_logs(data: Any, endpoint: str, run_id: str) -> str:
284
+ """Write cloud run logs as plain text to match local run format.
285
+
286
+ Accepts either a ``RunLog.to_dict()`` (``{"log": "..."}`` with an
287
+ optional ``"stderr"`` key) or a list of poll entries
288
+ (``[{"timestamp": ..., "log": ...}, ...]``).
289
+ """
290
+
291
+ path = os.path.join(_cloud_run_dir(endpoint, run_id), LOGS_KEY, LOGS_FILE)
292
+ os.makedirs(os.path.dirname(path), exist_ok=True)
293
+
294
+ with open(path, "w") as fh:
295
+ if isinstance(data, list):
296
+ # Poll entries: write each as "timestamp log\n".
297
+ for entry in data:
298
+ ts = entry.get("timestamp") or ""
299
+ log = entry.get("log") or ""
300
+ fh.write(f"{ts} {log}\n")
301
+ elif isinstance(data, dict):
302
+ # RunLog.to_dict(): write the log string directly.
303
+ log = data.get("log", "")
304
+ if log:
305
+ fh.write(log)
306
+ if not log.endswith("\n"):
307
+ fh.write("\n")
308
+ stderr = data.get("stderr", "")
309
+ if stderr:
310
+ fh.write(stderr)
311
+ if not stderr.endswith("\n"):
312
+ fh.write("\n")
313
+ else:
314
+ fh.write(str(data))
315
+
316
+ return path