mcli-framework 8.0.39__tar.gz → 8.0.40__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.
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/PKG-INFO +1 -1
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/pyproject.toml +1 -1
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/app/init_cmd.py +6 -4
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/constants/env.py +3 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/constants/messages.py +4 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/constants/paths.py +3 -1
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/paths.py +48 -20
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/workspace_registry.py +29 -23
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/self/env_cmd.py +11 -2
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/self/migrate_cmd.py +57 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli_framework.egg-info/PKG-INFO +1 -1
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli_framework.egg-info/SOURCES.txt +1 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/integration/test_all_commands_comprehensive.py +2 -2
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_init_mv_cmd.py +16 -16
- mcli_framework-8.0.40/tests/unit/test_migrate_rename_dir.py +104 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_paths.py +105 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_workflow_file_completion.py +5 -5
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/.github/dependabot.yml +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/.github/dependency-review-config.yml +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/.github/workflows/build.yml +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/.github/workflows/ci.yml +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/.github/workflows/codeql.yml +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/.github/workflows/docs-links.yml +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/.github/workflows/publish-self-hosted.yml +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/.github/workflows/publish.yml +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/.github/workflows/release.yml +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/.github/workflows/security.yml +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/.github/workflows/test.yml +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/LICENSE +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/MANIFEST.in +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/README.md +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/llms-full.txt +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/llms.txt +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/mcli_rust/Cargo.toml +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/mcli_rust/src/command_parser.rs +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/mcli_rust/src/file_watcher.rs +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/mcli_rust/src/lib.rs +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/mcli_rust/src/process_manager.rs +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/mcli_rust/src/tfidf.rs +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/setup.cfg +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/app/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/app/commands_cmd.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/app/completion_helpers.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/app/context_cmd.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/app/create_cmd.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/app/delete_cmd.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/app/edit_cmd.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/app/import_cmd.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/app/list_cmd.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/app/main.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/app/migrate_cmd.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/app/model/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/app/model/model.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/app/model_cmd.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/app/mv_cmd.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/app/new_cmd.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/app/remove_cmd.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/app/rm_cmd.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/app/search_cmd.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/app/services_cmd.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/app/sync_cmd.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/app/video/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/app/video/video.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/config.toml +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/api/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/api/api.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/api/daemon_client.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/api/daemon_client_local.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/api/daemon_decorator.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/api/mcli_decorators.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/auth/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/auth/auth.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/auth/aws_manager.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/auth/azure_manager.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/auth/credential_manager.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/auth/gcp_manager.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/auth/key_manager.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/auth/mcli_manager.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/auth/token_manager.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/auth/token_util.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/config/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/config/config.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/constants/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/constants/commands.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/constants/defaults.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/constants/scripts.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/constants/storage.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/custom_commands.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/discovery/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/discovery/command_discovery.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/erd/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/erd/erd.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/erd/generate_graph.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/errors.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/feature_detection.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/files/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/files/files.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/folder_workflows.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/fs/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/fs/fs.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/ipfs_sync.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/ipfs_utils.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/lib.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/logger/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/logger/correlation.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/logger/logger.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/logger/structured.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/optional_deps.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/performance/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/performance/optimizer.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/performance/rust_bridge.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/performance/uvloop_config.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/pickles/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/pickles/pickles.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/pyenv/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/pyenv/deps.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/pyenv/manager.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/pyenv/venv.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/script_loader.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/script_sync.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/script_watcher.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/search/cached_vectorizer.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/secrets/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/secrets/commands.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/secrets/manager.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/secrets/repl.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/secrets/store.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/services/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/services/config.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/services/data_pipeline.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/services/health.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/services/lsh_client.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/services/manager.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/services/redis_service.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/services/registry.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/services/state.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/services/supervisor.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/shell/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/shell/exceptions.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/shell/shell.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/templates/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/templates/command_templates.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/toml/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/toml/toml.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/types.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/ui/styling.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/ui/visual_effects.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/watcher/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/watcher/watcher.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/lib/workflow_models.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/api/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/api/app.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/api/middleware.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/api/routers/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/api/routers/admin_router.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/api/routers/auth_router.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/api/routers/backtest_router.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/api/routers/data_router.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/api/routers/model_router.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/api/routers/monitoring_router.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/api/routers/portfolio_router.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/api/routers/prediction_router.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/api/routers/trade_router.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/api/routers/websocket_router.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/api/schemas.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/auth/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/auth/auth_manager.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/auth/models.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/auth/permissions.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/backtesting/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/backtesting/backtest_engine.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/backtesting/performance_metrics.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/backtesting/run.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/cache.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/cli/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/cli/main.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/config/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/config/settings.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/configs/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/configs/dvc_config.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/configs/mlflow_config.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/configs/mlops_manager.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/dashboard/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/dashboard/app.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/dashboard/app_integrated.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/dashboard/app_supabase.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/dashboard/app_training.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/dashboard/cli.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/dashboard/common.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/dashboard/components/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/dashboard/components/charts.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/dashboard/components/metrics.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/dashboard/components/tables.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/dashboard/overview.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/dashboard/pages/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/dashboard/pages/cicd.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/dashboard/pages/debug_dependencies.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/dashboard/pages/gravity_viz.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/dashboard/pages/monte_carlo_predictions.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/dashboard/pages/predictions_enhanced.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/dashboard/pages/scrapers_and_logs.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/dashboard/pages/test_portfolio.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/dashboard/pages/trading.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/dashboard/pages/workflows.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/dashboard/streamlit_extras_utils.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/dashboard/styles.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/dashboard/utils.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/dashboard/warning_suppression.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/data_ingestion/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/data_ingestion/api_connectors.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/data_ingestion/data_pipeline.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/data_ingestion/stream_processor.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/database/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/database/migrations/env.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/database/models.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/database/session.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/experimentation/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/experimentation/ab_testing.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/features/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/features/ensemble_features.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/features/recommendation_engine.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/features/stock_features.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/features/test_feature_engineering.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/logging.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/mlops/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/mlops/data_versioning.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/mlops/experiment_tracker.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/mlops/model_serving.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/mlops/pipeline_orchestrator.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/models/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/models/base_models.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/models/ensemble_models.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/models/recommendation_models.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/models/test_models.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/monitoring/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/monitoring/drift_detection.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/monitoring/metrics.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/optimization/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/optimization/optimize.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/optimization/portfolio_optimizer.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/predictions/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/predictions/monte_carlo.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/predictions/prediction_engine.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/preprocessing/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/preprocessing/data_cleaners.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/preprocessing/feature_extractors.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/preprocessing/ml_pipeline.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/preprocessing/test_preprocessing.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/scripts/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/scripts/populate_sample_data.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/serving/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/serving/serve.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/tasks.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/tests/test_integration.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/tests/test_training_dashboard.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/trading/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/trading/alpaca_client.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/trading/migrations.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/trading/models.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/trading/paper_trading.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/trading/risk_management.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/trading/trading_service.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/training/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/training/train.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/ml/training/train_model.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/mygroup/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/mygroup/test_cmd.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/public/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/public/commands/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/public/oi/oi.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/public/public.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/self/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/self/completion_cmd.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/self/health_cmd.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/self/ipfs_cmd.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/self/logs_cmd.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/self/self_cmd.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/self/store_cmd.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/self/test_cmd.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/self/workflows_cmd.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/storage/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/storage/backends/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/storage/backends/ipfs_backend.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/storage/base.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/storage/cache.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/storage/encryption.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/storage/factory.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/storage/registry.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/storage/storacha_cli.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/daemon/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/daemon/async_command_database.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/daemon/async_process_manager.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/daemon/client.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/daemon/daemon.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/daemon/daemon_api.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/daemon/enhanced_daemon.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/daemon/process_cli.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/daemon/process_manager.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/daemon/test_daemon.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/dashboard/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/dashboard/dashboard_cmd.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/doc_convert.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/docker/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/docker/docker.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/file/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/gcloud/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/gcloud/config.toml +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/gcloud/gcloud.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/git_commit/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/git_commit/ai_service.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/interview/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/lsh_integration.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/model_service/client.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/model_service/download_and_run_efficient_models.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/model_service/lightweight_embedder.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/model_service/lightweight_model_server.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/model_service/lightweight_test.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/model_service/model_service.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/model_service/ollama_efficient_runner.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/model_service/openai_adapter.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/model_service/pdf_processor.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/model_service/test_efficient_runner.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/model_service/test_example.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/model_service/test_integration.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/model_service/test_new_features.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/notebook/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/notebook/command_loader.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/notebook/converter.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/notebook/executor.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/notebook/notebook_cmd.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/notebook/schema.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/notebook/validator.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/openai/openai.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/registry/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/registry/registry.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/repo/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/repo/repo.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/scheduler/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/scheduler/cron_parser.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/scheduler/job.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/scheduler/models.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/scheduler/monitor.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/scheduler/persistence.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/scheduler/scheduler.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/scheduler/validation.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/search/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/secrets/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/secrets/secrets_cmd.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/storage/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/storage/storage_cmd.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/sync/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/sync/test_cmd.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/videos/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/wakatime/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/wakatime/wakatime.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli/workflow/workflow.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli_framework.egg-info/dependency_links.txt +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli_framework.egg-info/entry_points.txt +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli_framework.egg-info/requires.txt +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/src/mcli_framework.egg-info/top_level.txt +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/cli/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/cli/test_all_commands.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/cli/test_app_logs_cmd.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/cli/test_app_redis_cmd.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/cli/test_logs_cmd.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/cli/test_main_app.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/cli/test_model_cmd.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/cli/test_self_cmd.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/cli/test_self_cmd_plugins.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/cli/test_self_cmd_utilities.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/cli/test_workflow_creation_commands.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/cli/test_workflow_file.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/cli/test_workflow_gcloud.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/cli/test_workflow_registry.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/conftest.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/e2e/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/e2e/test_complete_workflows.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/e2e/test_model_workflow.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/e2e/test_new_user_workflow.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/e2e/test_update_workflow.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/fixtures/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/fixtures/chat_fixtures.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/fixtures/cli_fixtures.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/fixtures/command_fixtures.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/fixtures/data_fixtures.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/fixtures/db_fixtures.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/fixtures/model_fixtures.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/integration/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/integration/test_daemon_server.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/integration/test_direct_file_execution.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/integration/test_e2e_dashboard_lsh_supabase.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/integration/test_flask_webapp.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/integration/test_folder_workflows_integration.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/integration/test_gcloud_services.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/integration/test_ml_auth.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/integration/test_ml_data_pipeline.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/integration/test_ml_models.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/integration/test_ml_pipeline.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/integration/test_module_imports.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/integration/test_notebook_workflows.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/integration/test_oi_service.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/integration/test_repo_operations.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/integration/test_scheduler_integration.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/integration/test_service_registry.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/integration/test_supabase_live_connection.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/integration/test_video_processing.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/integration/test_wakatime_api.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/integration/test_webapp_full.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/integration/test_workflow.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/integration/test_workflow_commands.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/performance/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/property/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/storage/__init__.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/storage/test_cache.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/storage/test_encryption.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/storage/test_storacha_cli.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_api_utils.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_async_process_manager.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_auth_modules.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_bug_fixes.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_command_fixtures.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_config.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_correlation_logging.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_custom_commands.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_custom_commands_filtering.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_daemon_api.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_dashboard_components.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_dashboard_functions.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_dashboard_pages.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_dependencies.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_doc_convert_workflow.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_emulator_workflow.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_erd_generation.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_erd_generic.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_erd_imports.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_folder_workflows.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_git_commit_workflow.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_health_cmd.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_import_cmd.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_ipfs_cmd.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_ipfs_retry.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_language_suffix.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_lib_auth.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_lib_files.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_lib_utils.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_logger.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_ml_preprocessing.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_new_cmd.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_notebook_command_loader.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_notebook_executor.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_optional_deps.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_pdf_compress.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_prediction_engine.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_pyenv.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_regression.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_scheduler.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_scheduler_cron_parser.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_scheduler_job.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_scheduler_models.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_scheduler_monitor.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_scheduler_persistence.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_scheduler_validation.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_script_loader_options.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_security_command_injection.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_self_update.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_service_config.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_service_health.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_service_manager.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_service_state.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_services_cmd.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_shell_exceptions.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_shell_functions.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_shell_security.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_store_cmd.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_supabase_connection.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_supabase_pagination.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_sync_cmd.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_toml_utils.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_trading_imports.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_ui_rich.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_uv_compat.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/test_workflow_models.py +0 -0
- {mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/unit/workflow/test_notebook.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mcli-framework
|
|
3
|
-
Version: 8.0.
|
|
3
|
+
Version: 8.0.40
|
|
4
4
|
Summary: Portable workflow framework - transform any script into a versioned, schedulable command. Store in ~/.mcli/workflows/, version with lockfile, run as daemon or cron job.
|
|
5
5
|
Author-email: Luis Fernandez de la Vara <luis@lefv.io>
|
|
6
6
|
Maintainer-email: Luis Fernandez de la Vara <luis@lefv.io>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "mcli-framework"
|
|
3
|
-
version = "8.0.
|
|
3
|
+
version = "8.0.40"
|
|
4
4
|
description = "Portable workflow framework - transform any script into a versioned, schedulable command. Store in ~/.mcli/workflows/, version with lockfile, run as daemon or cron job."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.10"
|
|
@@ -30,11 +30,11 @@ def init(is_global, git, force):
|
|
|
30
30
|
"""🚀 Initialize workflows directory structure.
|
|
31
31
|
|
|
32
32
|
Creates the necessary directories and configuration files for managing
|
|
33
|
-
custom workflows. By default, creates a local
|
|
33
|
+
custom workflows. By default, creates a local mcli/workflows/ directory
|
|
34
34
|
in the current directory.
|
|
35
35
|
|
|
36
36
|
Examples:
|
|
37
|
-
mcli init # Initialize local
|
|
37
|
+
mcli init # Initialize local mcli/workflows/ in current directory
|
|
38
38
|
mcli init --global # Initialize global ~/.mcli/workflows/
|
|
39
39
|
mcli init --git # Also initialize git repository
|
|
40
40
|
"""
|
|
@@ -50,11 +50,13 @@ def init(is_global, git, force):
|
|
|
50
50
|
workflows_dir = get_mcli_home() / "workflows"
|
|
51
51
|
is_local = False
|
|
52
52
|
else:
|
|
53
|
-
# Local:
|
|
53
|
+
# Local: mcli/workflows in current directory (default behavior)
|
|
54
54
|
from pathlib import Path
|
|
55
55
|
|
|
56
|
+
from mcli.lib.constants.paths import DirNames
|
|
57
|
+
|
|
56
58
|
cwd = Path.cwd()
|
|
57
|
-
workflows_dir = cwd /
|
|
59
|
+
workflows_dir = cwd / DirNames.LOCAL_MCLI / "workflows"
|
|
58
60
|
is_local = True
|
|
59
61
|
|
|
60
62
|
lockfile_path = workflows_dir / "commands.lock.json"
|
|
@@ -68,5 +68,8 @@ class EnvVars:
|
|
|
68
68
|
MCLI_USE_SYSTEM_PYTHON = "MCLI_USE_SYSTEM_PYTHON" # Skip venv detection
|
|
69
69
|
MCLI_VENV_PATH = "MCLI_VENV_PATH" # Override venv path
|
|
70
70
|
|
|
71
|
+
# Local workspace directory override
|
|
72
|
+
MCLI_LOCAL_DIR = "MCLI_LOCAL_DIR" # Override local workspace dir name
|
|
73
|
+
|
|
71
74
|
|
|
72
75
|
__all__ = ["EnvVars"]
|
|
@@ -59,6 +59,10 @@ class WarningMessages:
|
|
|
59
59
|
RATE_LIMIT_WARNING = "Approaching rate limit for {service}"
|
|
60
60
|
LARGE_FILE_WARNING = "Large file detected: {path} ({size})"
|
|
61
61
|
AMBIGUOUS_COMMAND = "Multiple versions of '{name}' found. Specify language: {options}"
|
|
62
|
+
DEPRECATED_LOCAL_DIR = (
|
|
63
|
+
"[yellow]Using legacy '.mcli/' directory. "
|
|
64
|
+
"Run 'mcli self migrate --rename-dir' to upgrade to 'mcli/'.[/yellow]"
|
|
65
|
+
)
|
|
62
66
|
|
|
63
67
|
|
|
64
68
|
class InfoMessages:
|
|
@@ -8,7 +8,9 @@ Using these constants ensures consistency across the codebase.
|
|
|
8
8
|
class DirNames:
|
|
9
9
|
"""Directory name constants."""
|
|
10
10
|
|
|
11
|
-
MCLI = ".mcli"
|
|
11
|
+
MCLI = ".mcli" # Global home (~/.mcli) — UNCHANGED
|
|
12
|
+
LOCAL_MCLI = "mcli" # New local workspace dir (visible in IDE/ls)
|
|
13
|
+
LEGACY_LOCAL_MCLI = ".mcli" # Legacy local dir (for fallback)
|
|
12
14
|
GIT = ".git"
|
|
13
15
|
LOGS = "logs"
|
|
14
16
|
CONFIG = "config"
|
|
@@ -158,16 +158,45 @@ def get_git_root(path: Optional[Path] = None) -> Optional[Path]:
|
|
|
158
158
|
|
|
159
159
|
def get_local_mcli_dir() -> Optional[Path]:
|
|
160
160
|
"""
|
|
161
|
-
Get the local
|
|
161
|
+
Get the local mcli workspace directory for the current git repository.
|
|
162
|
+
|
|
163
|
+
Resolution order:
|
|
164
|
+
1. MCLI_LOCAL_DIR env var override
|
|
165
|
+
2. New 'mcli/' directory (visible in IDE/ls)
|
|
166
|
+
3. Legacy '.mcli/' directory (with deprecation warning)
|
|
167
|
+
4. Default to new 'mcli/' path (for fresh init)
|
|
162
168
|
|
|
163
169
|
Returns:
|
|
164
|
-
Path to
|
|
170
|
+
Path to local mcli directory in git root, or None if not in a git repository
|
|
165
171
|
"""
|
|
166
172
|
git_root = get_git_root()
|
|
167
|
-
if git_root:
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
173
|
+
if not git_root:
|
|
174
|
+
return None
|
|
175
|
+
|
|
176
|
+
# 1. Check MCLI_LOCAL_DIR env var override
|
|
177
|
+
custom_dir = os.environ.get("MCLI_LOCAL_DIR")
|
|
178
|
+
if custom_dir:
|
|
179
|
+
return git_root / custom_dir
|
|
180
|
+
|
|
181
|
+
# 2. Check new "mcli/" directory
|
|
182
|
+
new_dir = git_root / DirNames.LOCAL_MCLI
|
|
183
|
+
if new_dir.exists():
|
|
184
|
+
return new_dir
|
|
185
|
+
|
|
186
|
+
# 3. Fall back to legacy ".mcli/"
|
|
187
|
+
legacy_dir = git_root / DirNames.LEGACY_LOCAL_MCLI
|
|
188
|
+
if legacy_dir.exists():
|
|
189
|
+
import warnings
|
|
190
|
+
|
|
191
|
+
warnings.warn(
|
|
192
|
+
"Using legacy '.mcli/' directory. " "Run 'mcli self migrate --rename-dir' to upgrade.",
|
|
193
|
+
DeprecationWarning,
|
|
194
|
+
stacklevel=2,
|
|
195
|
+
)
|
|
196
|
+
return legacy_dir
|
|
197
|
+
|
|
198
|
+
# 4. Neither exists — return new path (for fresh init)
|
|
199
|
+
return git_root / DirNames.LOCAL_MCLI
|
|
171
200
|
|
|
172
201
|
|
|
173
202
|
def get_local_commands_dir() -> Optional[Path]:
|
|
@@ -257,7 +286,7 @@ def resolve_workspace(workspace_path: str) -> Optional[Path]:
|
|
|
257
286
|
Resolve a workspace path to a workflows directory.
|
|
258
287
|
|
|
259
288
|
Accepts either:
|
|
260
|
-
- A directory path (uses <dir>/.mcli/workflows/)
|
|
289
|
+
- A directory path (uses <dir>/mcli/workflows/ or <dir>/.mcli/workflows/)
|
|
261
290
|
- A config file path (parses for workflows location)
|
|
262
291
|
|
|
263
292
|
Args:
|
|
@@ -271,20 +300,19 @@ def resolve_workspace(workspace_path: str) -> Optional[Path]:
|
|
|
271
300
|
if not path.exists():
|
|
272
301
|
return None
|
|
273
302
|
|
|
274
|
-
# If it's a directory, look for .mcli/workflows/ inside it
|
|
303
|
+
# If it's a directory, look for mcli/workflows/ or .mcli/workflows/ inside it
|
|
275
304
|
if path.is_dir():
|
|
276
|
-
# Check
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
return workflows_dir
|
|
305
|
+
# Check new mcli/ first, then legacy .mcli/
|
|
306
|
+
for dir_name in [DirNames.LOCAL_MCLI, DirNames.LEGACY_LOCAL_MCLI]:
|
|
307
|
+
workflows_dir = path / dir_name / "workflows"
|
|
308
|
+
if workflows_dir.exists():
|
|
309
|
+
return workflows_dir
|
|
310
|
+
commands_dir = path / dir_name / "commands"
|
|
311
|
+
if commands_dir.exists():
|
|
312
|
+
return commands_dir
|
|
313
|
+
|
|
314
|
+
# If neither exists, return the expected new path
|
|
315
|
+
return path / DirNames.LOCAL_MCLI / "workflows"
|
|
288
316
|
|
|
289
317
|
# If it's a file, try to parse it as a config file
|
|
290
318
|
if path.is_file():
|
|
@@ -12,6 +12,7 @@ from datetime import datetime
|
|
|
12
12
|
from pathlib import Path
|
|
13
13
|
from typing import Any, Dict, List, Optional
|
|
14
14
|
|
|
15
|
+
from mcli.lib.constants.paths import DirNames
|
|
15
16
|
from mcli.lib.logger.logger import get_logger
|
|
16
17
|
from mcli.lib.paths import get_git_root, get_mcli_home, is_git_repository
|
|
17
18
|
from mcli.lib.script_loader import ScriptLoader
|
|
@@ -19,6 +20,23 @@ from mcli.lib.script_loader import ScriptLoader
|
|
|
19
20
|
logger = get_logger(__name__)
|
|
20
21
|
|
|
21
22
|
|
|
23
|
+
def _resolve_local_workflows(workspace_path: Path) -> Optional[Path]:
|
|
24
|
+
"""Find the workflows dir in a workspace, checking new and legacy paths."""
|
|
25
|
+
for dir_name in [DirNames.LOCAL_MCLI, DirNames.LEGACY_LOCAL_MCLI]:
|
|
26
|
+
workflows_dir = workspace_path / dir_name / "workflows"
|
|
27
|
+
if workflows_dir.exists():
|
|
28
|
+
return workflows_dir
|
|
29
|
+
commands_dir = workspace_path / dir_name / "commands"
|
|
30
|
+
if commands_dir.exists():
|
|
31
|
+
return commands_dir
|
|
32
|
+
return None
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def _local_workflows_exist(workspace_path: Path) -> bool:
|
|
36
|
+
"""Check if any local workflows directory exists in a workspace."""
|
|
37
|
+
return _resolve_local_workflows(workspace_path) is not None
|
|
38
|
+
|
|
39
|
+
|
|
22
40
|
def get_registry_path() -> Path:
|
|
23
41
|
"""Get the path to the workspaces registry file."""
|
|
24
42
|
return get_mcli_home() / "workspaces.json"
|
|
@@ -105,15 +123,11 @@ def register_workspace(
|
|
|
105
123
|
|
|
106
124
|
workspace_path = workspace_path.resolve()
|
|
107
125
|
|
|
108
|
-
# Check if workflows directory exists
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
if not legacy_dir.exists():
|
|
114
|
-
logger.warning(f"No workflows found at {workspace_path}")
|
|
115
|
-
logger.info("Initialize with: mcli init")
|
|
116
|
-
return None
|
|
126
|
+
# Check if workflows directory exists (new mcli/ or legacy .mcli/)
|
|
127
|
+
if not _local_workflows_exist(workspace_path):
|
|
128
|
+
logger.warning(f"No workflows found at {workspace_path}")
|
|
129
|
+
logger.info("Initialize with: mcli init")
|
|
130
|
+
return None
|
|
117
131
|
|
|
118
132
|
# Load registry
|
|
119
133
|
registry = load_registry()
|
|
@@ -191,9 +205,7 @@ def list_registered_workspaces() -> List[Dict[str, Any]]:
|
|
|
191
205
|
workspace_path = Path(workspace_data["path"])
|
|
192
206
|
|
|
193
207
|
# Check if workspace still exists
|
|
194
|
-
|
|
195
|
-
legacy_dir = workspace_path / ".mcli" / "commands"
|
|
196
|
-
exists = workflows_dir.exists() or legacy_dir.exists()
|
|
208
|
+
exists = _local_workflows_exist(workspace_path)
|
|
197
209
|
|
|
198
210
|
workspaces.append(
|
|
199
211
|
{
|
|
@@ -242,12 +254,9 @@ def get_all_workflows() -> Dict[str, List[Dict[str, Any]]]:
|
|
|
242
254
|
workspace_path = Path(workspace_data["path"])
|
|
243
255
|
workspace_name = workspace_data.get("name", workspace_path.name)
|
|
244
256
|
|
|
245
|
-
# Determine workflows directory
|
|
246
|
-
workflows_dir = workspace_path
|
|
247
|
-
if
|
|
248
|
-
workflows_dir = workspace_path / ".mcli" / "commands"
|
|
249
|
-
|
|
250
|
-
if not workflows_dir.exists():
|
|
257
|
+
# Determine workflows directory (check new mcli/ then legacy .mcli/)
|
|
258
|
+
workflows_dir = _resolve_local_workflows(workspace_path)
|
|
259
|
+
if workflows_dir is None:
|
|
251
260
|
continue
|
|
252
261
|
|
|
253
262
|
loader = ScriptLoader(workflows_dir)
|
|
@@ -290,11 +299,8 @@ def auto_register_current() -> Optional[str]:
|
|
|
290
299
|
if workspace_id in registry.get("workspaces", {}):
|
|
291
300
|
return workspace_id
|
|
292
301
|
|
|
293
|
-
# Check if has workflows
|
|
294
|
-
|
|
295
|
-
legacy_dir = git_root / ".mcli" / "commands"
|
|
296
|
-
|
|
297
|
-
if workflows_dir.exists() or legacy_dir.exists():
|
|
302
|
+
# Check if has workflows (new mcli/ or legacy .mcli/)
|
|
303
|
+
if _local_workflows_exist(git_root):
|
|
298
304
|
return register_workspace(git_root)
|
|
299
305
|
|
|
300
306
|
return None
|
|
@@ -175,8 +175,17 @@ def env_command(
|
|
|
175
175
|
# Get workflows directory for this workspace
|
|
176
176
|
_workflows_dir = get_custom_commands_dir(global_mode=False) # noqa: F841
|
|
177
177
|
if workspace_dir and is_git_repository():
|
|
178
|
-
|
|
179
|
-
|
|
178
|
+
from mcli.lib.constants.paths import DirNames
|
|
179
|
+
|
|
180
|
+
# Check both new mcli/ and legacy .mcli/ local dir
|
|
181
|
+
local_workflows = None
|
|
182
|
+
for dir_name in [DirNames.LOCAL_MCLI, DirNames.LEGACY_LOCAL_MCLI]:
|
|
183
|
+
candidate = workspace_dir / dir_name / "workflows"
|
|
184
|
+
if candidate.exists():
|
|
185
|
+
local_workflows = candidate
|
|
186
|
+
break
|
|
187
|
+
|
|
188
|
+
if local_workflows is not None:
|
|
180
189
|
env_info["workflows_dir"] = str(local_workflows)
|
|
181
190
|
# Count workflow scripts
|
|
182
191
|
script_count = sum(
|
|
@@ -194,6 +194,11 @@ def get_migration_status() -> dict:
|
|
|
194
194
|
local_old = git_root / DirNames.MCLI / "commands"
|
|
195
195
|
local_new = git_root / DirNames.MCLI / "workflows"
|
|
196
196
|
|
|
197
|
+
# Check if local dir needs rename (.mcli/ → mcli/)
|
|
198
|
+
legacy_local = git_root / DirNames.LEGACY_LOCAL_MCLI
|
|
199
|
+
new_local = git_root / DirNames.LOCAL_MCLI
|
|
200
|
+
needs_dir_rename = legacy_local.exists() and not new_local.exists()
|
|
201
|
+
|
|
197
202
|
local_status: dict = {
|
|
198
203
|
"git_root": str(git_root),
|
|
199
204
|
"old_dir_exists": local_old.exists(),
|
|
@@ -203,6 +208,7 @@ def get_migration_status() -> dict:
|
|
|
203
208
|
"needs_migration": False,
|
|
204
209
|
"files_to_migrate": [],
|
|
205
210
|
"migration_done": False,
|
|
211
|
+
"needs_dir_rename": needs_dir_rename,
|
|
206
212
|
}
|
|
207
213
|
status["local"] = local_status
|
|
208
214
|
|
|
@@ -411,6 +417,11 @@ def migrate_commands_to_workflows(
|
|
|
411
417
|
is_flag=True,
|
|
412
418
|
help="Remove JSON files after successful conversion (use with --json-to-scripts)",
|
|
413
419
|
)
|
|
420
|
+
@click.option(
|
|
421
|
+
"--rename-dir",
|
|
422
|
+
is_flag=True,
|
|
423
|
+
help="Rename local '.mcli/' directories to 'mcli/' in current git repo",
|
|
424
|
+
)
|
|
414
425
|
def migrate_command(
|
|
415
426
|
dry_run: bool,
|
|
416
427
|
force: bool,
|
|
@@ -420,6 +431,7 @@ def migrate_command(
|
|
|
420
431
|
description: str,
|
|
421
432
|
json_to_scripts: bool,
|
|
422
433
|
remove_json: bool,
|
|
434
|
+
rename_dir: bool,
|
|
423
435
|
):
|
|
424
436
|
"""
|
|
425
437
|
Migrate mcli configuration and data to new structure.
|
|
@@ -427,6 +439,7 @@ def migrate_command(
|
|
|
427
439
|
Currently handles:
|
|
428
440
|
- Moving ~/.mcli/commands to ~/.mcli/workflows (global)
|
|
429
441
|
- Moving .mcli/commands to .mcli/workflows (local, in git repos)
|
|
442
|
+
- Renaming local .mcli/ to mcli/ for visibility (--rename-dir)
|
|
430
443
|
- Converting JSON workflow files to native scripts (--json-to-scripts)
|
|
431
444
|
- Optionally pushing to IPFS for decentralized backup
|
|
432
445
|
|
|
@@ -437,6 +450,7 @@ def migrate_command(
|
|
|
437
450
|
mcli self migrate --scope global # Migrate only global
|
|
438
451
|
mcli self migrate --scope local # Migrate only local (current repo)
|
|
439
452
|
mcli self migrate --force # Force migration (overwrite existing)
|
|
453
|
+
mcli self migrate --rename-dir # Rename .mcli/ to mcli/ in current repo
|
|
440
454
|
mcli self migrate --json-to-scripts # Convert JSON workflows to scripts
|
|
441
455
|
mcli self migrate --to-ipfs -d "Migrated workflows v1.0" # Push to IPFS after
|
|
442
456
|
"""
|
|
@@ -481,6 +495,12 @@ def migrate_command(
|
|
|
481
495
|
else:
|
|
482
496
|
console.print(" [green]✓ No migration needed[/green]")
|
|
483
497
|
|
|
498
|
+
if local_status.get("needs_dir_rename"):
|
|
499
|
+
console.print(
|
|
500
|
+
" [yellow]⚠ Directory rename needed: "
|
|
501
|
+
".mcli/ → mcli/ (run --rename-dir)[/yellow]"
|
|
502
|
+
)
|
|
503
|
+
|
|
484
504
|
# Show files to migrate if any
|
|
485
505
|
all_files = global_status.get("files_to_migrate", [])
|
|
486
506
|
if migration_status["local"]:
|
|
@@ -504,6 +524,43 @@ def migrate_command(
|
|
|
504
524
|
|
|
505
525
|
return
|
|
506
526
|
|
|
527
|
+
# Handle --rename-dir: rename local .mcli/ → mcli/
|
|
528
|
+
if rename_dir:
|
|
529
|
+
from mcli.lib.paths import get_git_root, is_git_repository
|
|
530
|
+
|
|
531
|
+
if not is_git_repository():
|
|
532
|
+
error("Not in a git repository")
|
|
533
|
+
return
|
|
534
|
+
|
|
535
|
+
git_root = get_git_root()
|
|
536
|
+
if not git_root:
|
|
537
|
+
error("Could not determine git root")
|
|
538
|
+
return
|
|
539
|
+
|
|
540
|
+
old_dir = git_root / DirNames.LEGACY_LOCAL_MCLI # .mcli
|
|
541
|
+
new_dir = git_root / DirNames.LOCAL_MCLI # mcli
|
|
542
|
+
|
|
543
|
+
if new_dir.exists() and not old_dir.exists():
|
|
544
|
+
info("Already using 'mcli/' directory — no migration needed")
|
|
545
|
+
return
|
|
546
|
+
|
|
547
|
+
if not old_dir.exists():
|
|
548
|
+
info("No '.mcli/' directory found — nothing to migrate")
|
|
549
|
+
return
|
|
550
|
+
|
|
551
|
+
if new_dir.exists() and old_dir.exists():
|
|
552
|
+
error("Both 'mcli/' and '.mcli/' exist. Resolve manually.")
|
|
553
|
+
return
|
|
554
|
+
|
|
555
|
+
if dry_run:
|
|
556
|
+
console.print(f"[yellow]Would rename:[/yellow] {old_dir} → {new_dir}")
|
|
557
|
+
return
|
|
558
|
+
|
|
559
|
+
shutil.move(str(old_dir), str(new_dir))
|
|
560
|
+
success(f"Renamed '{old_dir.name}/' → '{new_dir.name}/'")
|
|
561
|
+
console.print("[dim]Tip: Update your .gitignore if it references .mcli/[/dim]")
|
|
562
|
+
return
|
|
563
|
+
|
|
507
564
|
# Handle --json-to-scripts conversion
|
|
508
565
|
if json_to_scripts:
|
|
509
566
|
from mcli.lib.paths import get_custom_commands_dir, get_git_root, is_git_repository
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mcli-framework
|
|
3
|
-
Version: 8.0.
|
|
3
|
+
Version: 8.0.40
|
|
4
4
|
Summary: Portable workflow framework - transform any script into a versioned, schedulable command. Store in ~/.mcli/workflows/, version with lockfile, run as daemon or cron job.
|
|
5
5
|
Author-email: Luis Fernandez de la Vara <luis@lefv.io>
|
|
6
6
|
Maintainer-email: Luis Fernandez de la Vara <luis@lefv.io>
|
|
@@ -441,6 +441,7 @@ tests/unit/test_lib_auth.py
|
|
|
441
441
|
tests/unit/test_lib_files.py
|
|
442
442
|
tests/unit/test_lib_utils.py
|
|
443
443
|
tests/unit/test_logger.py
|
|
444
|
+
tests/unit/test_migrate_rename_dir.py
|
|
444
445
|
tests/unit/test_ml_preprocessing.py
|
|
445
446
|
tests/unit/test_new_cmd.py
|
|
446
447
|
tests/unit/test_notebook_command_loader.py
|
{mcli_framework-8.0.39 → mcli_framework-8.0.40}/tests/integration/test_all_commands_comprehensive.py
RENAMED
|
@@ -42,8 +42,8 @@ def mock_repo(tmp_path):
|
|
|
42
42
|
repo_dir = tmp_path / "mock_repo"
|
|
43
43
|
repo_dir.mkdir()
|
|
44
44
|
|
|
45
|
-
# Create
|
|
46
|
-
mcli_dir = repo_dir / "
|
|
45
|
+
# Create mcli directory structure (local workspace)
|
|
46
|
+
mcli_dir = repo_dir / "mcli"
|
|
47
47
|
mcli_dir.mkdir()
|
|
48
48
|
|
|
49
49
|
commands_dir = mcli_dir / "commands"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""Unit tests for mcli init and mv commands.
|
|
2
2
|
|
|
3
3
|
Tests the new behaviors added in v8.0.26:
|
|
4
|
-
- mcli init defaults to local
|
|
4
|
+
- mcli init defaults to local mcli/workflows in current directory
|
|
5
5
|
- mcli mv auto-detects directory paths as workspace destinations
|
|
6
6
|
"""
|
|
7
7
|
|
|
@@ -31,13 +31,13 @@ class TestInitCommand:
|
|
|
31
31
|
return tmp_path
|
|
32
32
|
|
|
33
33
|
def test_init_defaults_to_local(self, cli_runner, temp_dir):
|
|
34
|
-
"""Test that mcli init creates local
|
|
34
|
+
"""Test that mcli init creates local mcli/workflows by default."""
|
|
35
35
|
with cli_runner.isolated_filesystem(temp_dir=temp_dir):
|
|
36
36
|
result = cli_runner.invoke(init, [])
|
|
37
37
|
|
|
38
38
|
assert result.exit_code == 0
|
|
39
|
-
assert Path("
|
|
40
|
-
assert Path("
|
|
39
|
+
assert Path("mcli/workflows").exists()
|
|
40
|
+
assert Path("mcli/workflows/commands.lock.json").exists()
|
|
41
41
|
assert "Local (directory-specific)" in result.output
|
|
42
42
|
|
|
43
43
|
def test_init_global_flag_uses_home(self, cli_runner, temp_dir):
|
|
@@ -59,7 +59,7 @@ class TestInitCommand:
|
|
|
59
59
|
|
|
60
60
|
assert result.exit_code == 0
|
|
61
61
|
|
|
62
|
-
lockfile_path = Path("
|
|
62
|
+
lockfile_path = Path("mcli/workflows/commands.lock.json")
|
|
63
63
|
with open(lockfile_path) as f:
|
|
64
64
|
lockfile = json.load(f)
|
|
65
65
|
|
|
@@ -87,7 +87,7 @@ class TestInitCommand:
|
|
|
87
87
|
result = cli_runner.invoke(init, [])
|
|
88
88
|
|
|
89
89
|
assert result.exit_code == 0
|
|
90
|
-
assert Path("
|
|
90
|
+
assert Path("mcli/workflows/README.md").exists()
|
|
91
91
|
|
|
92
92
|
def test_init_creates_gitignore(self, cli_runner, temp_dir):
|
|
93
93
|
"""Test that init creates a .gitignore file."""
|
|
@@ -95,7 +95,7 @@ class TestInitCommand:
|
|
|
95
95
|
result = cli_runner.invoke(init, [])
|
|
96
96
|
|
|
97
97
|
assert result.exit_code == 0
|
|
98
|
-
assert Path("
|
|
98
|
+
assert Path("mcli/workflows/.gitignore").exists()
|
|
99
99
|
|
|
100
100
|
def test_init_force_reinitializes(self, cli_runner, temp_dir):
|
|
101
101
|
"""Test that --force flag allows reinitialization."""
|
|
@@ -134,7 +134,7 @@ class TestMvCommand:
|
|
|
134
134
|
def setup_workflows(self, tmp_path):
|
|
135
135
|
"""Create a mock workflow setup for testing."""
|
|
136
136
|
# Create source workflows directory with a test command
|
|
137
|
-
workflows_dir = tmp_path / "
|
|
137
|
+
workflows_dir = tmp_path / "mcli" / "workflows"
|
|
138
138
|
workflows_dir.mkdir(parents=True)
|
|
139
139
|
|
|
140
140
|
# Create a test command file
|
|
@@ -152,7 +152,7 @@ class TestMvCommand:
|
|
|
152
152
|
# Setup source
|
|
153
153
|
source_dir = tmp_path / "source"
|
|
154
154
|
source_dir.mkdir()
|
|
155
|
-
source_workflows = source_dir / "
|
|
155
|
+
source_workflows = source_dir / "mcli" / "workflows"
|
|
156
156
|
source_workflows.mkdir(parents=True)
|
|
157
157
|
|
|
158
158
|
test_cmd = source_workflows / "my-cmd.py"
|
|
@@ -172,7 +172,7 @@ class TestMvCommand:
|
|
|
172
172
|
result = cli_runner.invoke(mv, ["my-cmd", str(dest_dir) + "/"], input="y\n")
|
|
173
173
|
|
|
174
174
|
# Should recognize it's a directory and try to move there
|
|
175
|
-
# The command may fail because dest doesn't have
|
|
175
|
+
# The command may fail because dest doesn't have mcli/workflows but
|
|
176
176
|
# the important thing is it recognized the directory path
|
|
177
177
|
assert "destination" in result.output.lower() or "workspace" in result.output.lower()
|
|
178
178
|
|
|
@@ -181,7 +181,7 @@ class TestMvCommand:
|
|
|
181
181
|
# This tests the path detection logic
|
|
182
182
|
source_dir = tmp_path / "source"
|
|
183
183
|
source_dir.mkdir()
|
|
184
|
-
source_workflows = source_dir / "
|
|
184
|
+
source_workflows = source_dir / "mcli" / "workflows"
|
|
185
185
|
source_workflows.mkdir(parents=True)
|
|
186
186
|
|
|
187
187
|
test_cmd = source_workflows / "my-cmd.py"
|
|
@@ -204,7 +204,7 @@ class TestMvCommand:
|
|
|
204
204
|
"""Test that providing both directory path and -w option fails."""
|
|
205
205
|
source_dir = tmp_path / "source"
|
|
206
206
|
source_dir.mkdir()
|
|
207
|
-
source_workflows = source_dir / "
|
|
207
|
+
source_workflows = source_dir / "mcli" / "workflows"
|
|
208
208
|
source_workflows.mkdir(parents=True)
|
|
209
209
|
|
|
210
210
|
test_cmd = source_workflows / "my-cmd.py"
|
|
@@ -236,7 +236,7 @@ class TestMvCommand:
|
|
|
236
236
|
# Setup source
|
|
237
237
|
source_dir = tmp_path / "source"
|
|
238
238
|
source_dir.mkdir()
|
|
239
|
-
source_workflows = source_dir / "
|
|
239
|
+
source_workflows = source_dir / "mcli" / "workflows"
|
|
240
240
|
source_workflows.mkdir(parents=True)
|
|
241
241
|
|
|
242
242
|
test_cmd = source_workflows / "original-name.py"
|
|
@@ -245,10 +245,10 @@ class TestMvCommand:
|
|
|
245
245
|
lockfile = source_workflows / "commands.lock.json"
|
|
246
246
|
lockfile.write_text(json.dumps({"version": "1.0", "scope": "local", "commands": {}}))
|
|
247
247
|
|
|
248
|
-
# Setup destination with
|
|
248
|
+
# Setup destination with mcli/workflows
|
|
249
249
|
dest_dir = tmp_path / "destination"
|
|
250
250
|
dest_dir.mkdir()
|
|
251
|
-
dest_workflows = dest_dir / "
|
|
251
|
+
dest_workflows = dest_dir / "mcli" / "workflows"
|
|
252
252
|
dest_workflows.mkdir(parents=True)
|
|
253
253
|
|
|
254
254
|
dest_lockfile = dest_workflows / "commands.lock.json"
|
|
@@ -275,7 +275,7 @@ class TestMvCommandRename:
|
|
|
275
275
|
|
|
276
276
|
def test_mv_same_source_dest_no_change(self, cli_runner, tmp_path):
|
|
277
277
|
"""Test that mv with same source and dest does nothing."""
|
|
278
|
-
workflows_dir = tmp_path / "
|
|
278
|
+
workflows_dir = tmp_path / "mcli" / "workflows"
|
|
279
279
|
workflows_dir.mkdir(parents=True)
|
|
280
280
|
|
|
281
281
|
test_cmd = workflows_dir / "my-cmd.py"
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"""Unit tests for mcli self migrate --rename-dir functionality."""
|
|
2
|
+
|
|
3
|
+
from unittest.mock import patch
|
|
4
|
+
|
|
5
|
+
import pytest
|
|
6
|
+
from click.testing import CliRunner
|
|
7
|
+
|
|
8
|
+
from mcli.self.migrate_cmd import migrate_command
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class TestMigrateRenameDir:
|
|
12
|
+
"""Tests for the --rename-dir flag on mcli self migrate."""
|
|
13
|
+
|
|
14
|
+
@pytest.fixture
|
|
15
|
+
def cli_runner(self):
|
|
16
|
+
return CliRunner()
|
|
17
|
+
|
|
18
|
+
def test_rename_dir_success(self, cli_runner, tmp_path):
|
|
19
|
+
"""Test successful rename of .mcli/ to mcli/."""
|
|
20
|
+
(tmp_path / ".git").mkdir()
|
|
21
|
+
old_dir = tmp_path / ".mcli"
|
|
22
|
+
old_dir.mkdir()
|
|
23
|
+
(old_dir / "workflows").mkdir()
|
|
24
|
+
(old_dir / "workflows" / "test.py").write_text("print('hi')")
|
|
25
|
+
|
|
26
|
+
with patch("mcli.lib.paths.is_git_repository", return_value=True):
|
|
27
|
+
with patch("mcli.lib.paths.get_git_root", return_value=tmp_path):
|
|
28
|
+
result = cli_runner.invoke(migrate_command, ["--rename-dir"])
|
|
29
|
+
|
|
30
|
+
assert result.exit_code == 0
|
|
31
|
+
assert "Renamed" in result.output
|
|
32
|
+
assert not old_dir.exists()
|
|
33
|
+
assert (tmp_path / "mcli").exists()
|
|
34
|
+
assert (tmp_path / "mcli" / "workflows" / "test.py").exists()
|
|
35
|
+
|
|
36
|
+
def test_rename_dir_dry_run(self, cli_runner, tmp_path):
|
|
37
|
+
"""Test --rename-dir with --dry-run shows what would happen."""
|
|
38
|
+
(tmp_path / ".git").mkdir()
|
|
39
|
+
old_dir = tmp_path / ".mcli"
|
|
40
|
+
old_dir.mkdir()
|
|
41
|
+
|
|
42
|
+
with patch("mcli.lib.paths.is_git_repository", return_value=True):
|
|
43
|
+
with patch("mcli.lib.paths.get_git_root", return_value=tmp_path):
|
|
44
|
+
result = cli_runner.invoke(migrate_command, ["--rename-dir", "--dry-run"])
|
|
45
|
+
|
|
46
|
+
assert result.exit_code == 0
|
|
47
|
+
assert "Would rename" in result.output
|
|
48
|
+
assert old_dir.exists() # Not actually renamed
|
|
49
|
+
|
|
50
|
+
def test_rename_dir_already_migrated(self, cli_runner, tmp_path):
|
|
51
|
+
"""Test --rename-dir when mcli/ already exists and .mcli/ doesn't."""
|
|
52
|
+
(tmp_path / ".git").mkdir()
|
|
53
|
+
(tmp_path / "mcli").mkdir()
|
|
54
|
+
|
|
55
|
+
with patch("mcli.lib.paths.is_git_repository", return_value=True):
|
|
56
|
+
with patch("mcli.lib.paths.get_git_root", return_value=tmp_path):
|
|
57
|
+
result = cli_runner.invoke(migrate_command, ["--rename-dir"])
|
|
58
|
+
|
|
59
|
+
assert result.exit_code == 0
|
|
60
|
+
assert "Already using" in result.output
|
|
61
|
+
|
|
62
|
+
def test_rename_dir_no_mcli_dir(self, cli_runner, tmp_path):
|
|
63
|
+
"""Test --rename-dir when no .mcli/ directory exists."""
|
|
64
|
+
(tmp_path / ".git").mkdir()
|
|
65
|
+
|
|
66
|
+
with patch("mcli.lib.paths.is_git_repository", return_value=True):
|
|
67
|
+
with patch("mcli.lib.paths.get_git_root", return_value=tmp_path):
|
|
68
|
+
result = cli_runner.invoke(migrate_command, ["--rename-dir"])
|
|
69
|
+
|
|
70
|
+
assert result.exit_code == 0
|
|
71
|
+
assert "nothing to migrate" in result.output.lower()
|
|
72
|
+
|
|
73
|
+
def test_rename_dir_both_exist(self, cli_runner, tmp_path):
|
|
74
|
+
"""Test --rename-dir when both mcli/ and .mcli/ exist."""
|
|
75
|
+
(tmp_path / ".git").mkdir()
|
|
76
|
+
(tmp_path / ".mcli").mkdir()
|
|
77
|
+
(tmp_path / "mcli").mkdir()
|
|
78
|
+
|
|
79
|
+
with patch("mcli.lib.paths.is_git_repository", return_value=True):
|
|
80
|
+
with patch("mcli.lib.paths.get_git_root", return_value=tmp_path):
|
|
81
|
+
result = cli_runner.invoke(migrate_command, ["--rename-dir"])
|
|
82
|
+
|
|
83
|
+
assert result.exit_code == 0
|
|
84
|
+
assert "Both" in result.output
|
|
85
|
+
|
|
86
|
+
def test_rename_dir_not_in_git_repo(self, cli_runner, tmp_path):
|
|
87
|
+
"""Test --rename-dir when not in a git repository."""
|
|
88
|
+
with patch("mcli.lib.paths.is_git_repository", return_value=False):
|
|
89
|
+
result = cli_runner.invoke(migrate_command, ["--rename-dir"])
|
|
90
|
+
|
|
91
|
+
assert result.exit_code == 0
|
|
92
|
+
assert "Not in a git repository" in result.output
|
|
93
|
+
|
|
94
|
+
def test_migration_status_shows_dir_rename_needed(self, cli_runner, tmp_path):
|
|
95
|
+
"""Test --status shows directory rename needed."""
|
|
96
|
+
(tmp_path / ".git").mkdir()
|
|
97
|
+
(tmp_path / ".mcli" / "workflows").mkdir(parents=True)
|
|
98
|
+
|
|
99
|
+
with patch("mcli.lib.paths.is_git_repository", return_value=True):
|
|
100
|
+
with patch("mcli.lib.paths.get_git_root", return_value=tmp_path):
|
|
101
|
+
result = cli_runner.invoke(migrate_command, ["--status"])
|
|
102
|
+
|
|
103
|
+
assert result.exit_code == 0
|
|
104
|
+
assert "rename" in result.output.lower()
|