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.
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/.gitignore +0 -1
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/PKG-INFO +1 -5
- nextmv-1.3.1.dev2/nextmv/__about__.py +1 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/main.py +8 -2
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/mcp/__init__.py +13 -1
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/mcp/serve.py +1 -11
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/mcp/server.py +16 -2
- nextmv-1.3.1.dev2/nextmv/cli/mcp/tools/_helpers.py +316 -0
- nextmv-1.3.1.dev2/nextmv/cli/mcp/tools/guide.py +424 -0
- nextmv-1.3.1.dev2/nextmv/cli/mcp/tools/local.py +431 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/mcp/tools/profile.py +2 -2
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/mcp/tools/run.py +153 -28
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/mcp/tools/scenario.py +11 -173
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/application/_batch_scenario.py +15 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/pyproject.toml +0 -5
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/cli/test_mcp.py +973 -117
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/uv.lock +1 -9
- nextmv-1.3.1.dev0/nextmv/__about__.py +0 -1
- nextmv-1.3.1.dev0/nextmv/cli/mcp/tools/_helpers.py +0 -126
- nextmv-1.3.1.dev0/nextmv/cli/mcp/tools/local.py +0 -361
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/.python-version +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/CONTRIBUTING.md +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/LICENSE +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/README.md +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/__entrypoint__.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/__init__.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/_serialization.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/base_model.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/__init__.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/__init__.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/acceptance/__init__.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/acceptance/create.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/acceptance/delete.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/acceptance/get.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/acceptance/list.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/acceptance/update.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/account/__init__.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/account/create.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/account/delete.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/account/get.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/account/update.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/app/__init__.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/app/create.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/app/delete.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/app/exists.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/app/get.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/app/list.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/app/push.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/app/update.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/batch/__init__.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/batch/create.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/batch/delete.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/batch/get.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/batch/list.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/batch/metadata.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/batch/update.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/data/__init__.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/data/upload.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/ensemble/__init__.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/ensemble/create.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/ensemble/delete.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/ensemble/get.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/ensemble/list.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/ensemble/update.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/input_set/__init__.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/input_set/create.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/input_set/delete.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/input_set/get.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/input_set/list.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/input_set/update.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/instance/__init__.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/instance/create.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/instance/delete.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/instance/exists.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/instance/get.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/instance/list.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/instance/update.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/managed_input/__init__.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/managed_input/create.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/managed_input/delete.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/managed_input/get.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/managed_input/list.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/managed_input/update.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/marketplace/__init__.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/marketplace/app/__init__.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/marketplace/app/create.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/marketplace/app/get.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/marketplace/app/list.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/marketplace/app/update.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/marketplace/subscription/__init__.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/marketplace/subscription/create.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/marketplace/subscription/delete.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/marketplace/subscription/get.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/marketplace/subscription/list.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/marketplace/version/__init__.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/marketplace/version/create.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/marketplace/version/get.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/marketplace/version/list.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/marketplace/version/update.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/run/__init__.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/run/cancel.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/run/create.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/run/get.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/run/input.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/run/list.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/run/logs.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/run/metadata.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/run/track.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/scenario/__init__.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/scenario/create.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/scenario/delete.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/scenario/get.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/scenario/list.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/scenario/metadata.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/scenario/update.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/secrets/__init__.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/secrets/create.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/secrets/delete.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/secrets/get.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/secrets/list.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/secrets/update.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/shadow/__init__.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/shadow/create.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/shadow/delete.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/shadow/get.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/shadow/list.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/shadow/metadata.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/shadow/start.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/shadow/stop.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/shadow/update.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/sso/__init__.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/sso/create.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/sso/delete.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/sso/disable.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/sso/domain/__init__.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/sso/domain/delete.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/sso/enable.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/sso/get.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/sso/update.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/switchback/__init__.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/switchback/create.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/switchback/delete.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/switchback/get.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/switchback/list.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/switchback/metadata.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/switchback/start.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/switchback/stop.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/switchback/update.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/upload/__init__.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/upload/create.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/version/__init__.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/version/create.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/version/delete.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/version/exists.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/version/get.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/version/list.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/cloud/version/update.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/community/__init__.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/community/clone.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/community/list.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/configuration/__init__.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/configuration/config.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/configuration/create.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/configuration/delete.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/configuration/list.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/init.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/local/__init__.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/local/app/__init__.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/local/app/delete.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/local/app/get.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/local/app/list.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/local/app/register.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/local/app/registered.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/local/app/sync.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/local/app/update.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/local/run/__init__.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/local/run/create.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/local/run/get.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/local/run/input.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/local/run/list.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/local/run/logs.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/local/run/metadata.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/local/run/visuals.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/manifest/__init__.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/manifest/init.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/manifest/validate.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/mcp/tools/__init__.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/mcp/tools/acceptance.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/mcp/tools/account.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/mcp/tools/app.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/mcp/tools/batch.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/mcp/tools/community.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/mcp/tools/ensemble.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/mcp/tools/input_set.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/mcp/tools/instance.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/mcp/tools/managed_input.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/mcp/tools/secrets.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/mcp/tools/shadow.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/mcp/tools/sso.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/mcp/tools/switchback.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/mcp/tools/version.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/message.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/options.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cli/version.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/__init__.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/acceptance_test.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/account.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/application/__init__.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/application/_acceptance.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/application/_ensemble.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/application/_input_set.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/application/_instance.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/application/_managed_input.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/application/_run.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/application/_secrets.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/application/_shadow.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/application/_switchback.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/application/_utils.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/application/_version.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/assets.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/batch_experiment.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/client.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/community.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/ensemble.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/input_set.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/instance.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/integration.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/marketplace.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/package.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/scenario.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/secrets.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/shadow.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/sso.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/switchback.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/url.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/cloud/version.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/content_format.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/default_app/.gitignore +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/default_app/README.md +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/default_app/app.yaml +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/default_app/input.json +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/default_app/main.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/default_app/requirements.txt +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/default_app/src/__init__.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/default_app/src/visuals.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/deprecated.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/input.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/local/__init__.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/local/application.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/local/executor.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/local/geojson_handler.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/local/local.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/local/plotly_handler.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/local/registry.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/local/runner.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/logger.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/manifest.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/model.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/options.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/output.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/polling.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/run.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/safe.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/status.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/binary_json_app.yaml +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/binary_multi-file_app.yaml +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/go_json_app.yaml +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/go_json_template/.gitignore +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/go_json_template/README.md +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/go_json_template/app.yaml +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/go_json_template/go.mod +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/go_json_template/input.json +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/go_json_template/main.go +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/go_multi-file_app.yaml +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/go_multi-file_template/.gitignore +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/go_multi-file_template/README.md +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/go_multi-file_template/app.yaml +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/go_multi-file_template/go.mod +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/go_multi-file_template/inputs/input.json +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/go_multi-file_template/main.go +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/java_json_app.yaml +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/java_json_template/.gitignore +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/java_json_template/Main.java +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/java_json_template/README.md +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/java_json_template/app.yaml +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/java_json_template/input.json +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/java_json_template/pom.xml +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/java_multi-file_app.yaml +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/java_multi-file_template/.gitignore +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/java_multi-file_template/Main.java +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/java_multi-file_template/README.md +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/java_multi-file_template/app.yaml +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/java_multi-file_template/inputs/input.json +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/java_multi-file_template/pom.xml +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/python_json_app.yaml +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/python_json_template/.gitignore +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/python_json_template/README.md +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/python_json_template/app.yaml +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/python_json_template/input.json +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/python_json_template/main.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/python_json_template/requirements.txt +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/python_multi-file_app.yaml +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/python_multi-file_template/.gitignore +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/python_multi-file_template/README.md +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/python_multi-file_template/app.yaml +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/python_multi-file_template/inputs/input.json +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/python_multi-file_template/main.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/nextmv/templates/python_multi-file_template/requirements.txt +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/__init__.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/cli/__init__.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/cli/test_configuration.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/cli/test_main.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/cli/test_version.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/cloud/__init__.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/cloud/app.yaml +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/cloud/test_client.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/cloud/test_instance.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/cloud/test_package.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/cloud/test_scenario.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/integration/__init__.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/integration/cloud/__init__.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/integration/cloud/test_integration_cloud.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/integration/cloud/test_integration_marketplace.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/local/__init__.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/local/test_application.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/local/test_executor.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/local/test_registry.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/local/test_runner.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/scripts/__init__.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/scripts/options1.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/scripts/options2.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/scripts/options3.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/scripts/options4.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/scripts/options5.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/scripts/options6.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/scripts/options7.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/test_base_model.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/test_entrypoint/__init__.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/test_entrypoint/test_entrypoint.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/test_input.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/test_inputs/test_data.csv +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/test_inputs/test_data.json +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/test_inputs/test_data.txt +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/test_logger.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/test_manifest.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/test_model.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/test_options.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/test_output.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/test_polling.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/test_run.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/test_safe.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/test_serialization.py +0 -0
- {nextmv-1.3.1.dev0 → nextmv-1.3.1.dev2}/tests/test_version.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: nextmv
|
|
3
|
-
Version: 1.3.1.
|
|
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
|
-
|
|
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
|