mcli-framework 7.8.4__tar.gz → 7.9.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of mcli-framework might be problematic. Click here for more details.

Files changed (339) hide show
  1. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/PKG-INFO +2 -1
  2. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/pyproject.toml +2 -1
  3. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/app/main.py +10 -17
  4. mcli_framework-7.9.0/src/mcli/app/model_cmd.py +66 -0
  5. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/lib/lib.py +8 -1
  6. mcli_framework-7.9.0/src/mcli/lib/secrets/commands.py +185 -0
  7. mcli_framework-7.9.0/src/mcli/lib/secrets/manager.py +213 -0
  8. mcli_framework-7.9.0/src/mcli/lib/secrets/repl.py +297 -0
  9. mcli_framework-7.9.0/src/mcli/lib/secrets/store.py +246 -0
  10. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/self/self_cmd.py +8 -0
  11. mcli_framework-7.9.0/src/mcli/self/zsh_cmd.py +259 -0
  12. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli_framework.egg-info/PKG-INFO +2 -1
  13. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli_framework.egg-info/SOURCES.txt +5 -3
  14. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli_framework.egg-info/requires.txt +1 -0
  15. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/e2e/test_new_user_workflow.py +15 -12
  16. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/integration/test_module_imports.py +4 -3
  17. mcli_framework-7.8.4/src/mcli/app/chat_cmd.py +0 -42
  18. mcli_framework-7.8.4/src/mcli/app/model_cmd.py +0 -481
  19. mcli_framework-7.8.4/src/mcli/test/test_cmd.py +0 -20
  20. mcli_framework-7.8.4/tests/cli/test_chat_cmd.py +0 -113
  21. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/.github/dependabot.yml +0 -0
  22. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/.github/workflows/build.yml +0 -0
  23. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/.github/workflows/ci.yml +0 -0
  24. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/.github/workflows/ml-pipeline.yml +0 -0
  25. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/.github/workflows/publish-self-hosted.yml +0 -0
  26. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/.github/workflows/publish.yml +0 -0
  27. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/.github/workflows/release.yml +0 -0
  28. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/.github/workflows/security.yml +0 -0
  29. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/.github/workflows/test.yml +0 -0
  30. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/LICENSE +0 -0
  31. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/MANIFEST.in +0 -0
  32. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/README.md +0 -0
  33. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/mcli_rust/Cargo.toml +0 -0
  34. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/mcli_rust/src/command_parser.rs +0 -0
  35. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/mcli_rust/src/file_watcher.rs +0 -0
  36. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/mcli_rust/src/lib.rs +0 -0
  37. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/mcli_rust/src/process_manager.rs +0 -0
  38. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/mcli_rust/src/tfidf.rs +0 -0
  39. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/setup.cfg +0 -0
  40. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/app/commands_cmd.py +0 -0
  41. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/app/completion_helpers.py +0 -0
  42. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/app/model/model.py +0 -0
  43. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/app/video/video.py +0 -0
  44. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/chat/chat.py +0 -0
  45. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/chat/command_rag.py +0 -0
  46. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/chat/enhanced_chat.py +0 -0
  47. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/chat/system_controller.py +0 -0
  48. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/chat/system_integration.py +0 -0
  49. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/cli.py +0 -0
  50. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/config.toml +0 -0
  51. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/lib/api/api.py +0 -0
  52. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/lib/api/daemon_client.py +0 -0
  53. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/lib/api/daemon_client_local.py +0 -0
  54. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/lib/api/daemon_decorator.py +0 -0
  55. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/lib/api/mcli_decorators.py +0 -0
  56. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/lib/auth/auth.py +0 -0
  57. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/lib/auth/aws_manager.py +0 -0
  58. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/lib/auth/azure_manager.py +0 -0
  59. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/lib/auth/credential_manager.py +0 -0
  60. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/lib/auth/gcp_manager.py +0 -0
  61. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/lib/auth/key_manager.py +0 -0
  62. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/lib/auth/mcli_manager.py +0 -0
  63. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/lib/auth/token_manager.py +0 -0
  64. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/lib/auth/token_util.py +0 -0
  65. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/lib/config/config.py +0 -0
  66. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/lib/custom_commands.py +0 -0
  67. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/lib/discovery/__init__.py +0 -0
  68. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/lib/discovery/command_discovery.py +0 -0
  69. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/lib/erd/erd.py +0 -0
  70. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/lib/erd/generate_graph.py +0 -0
  71. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/lib/files/files.py +0 -0
  72. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/lib/fs/fs.py +0 -0
  73. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/lib/logger/logger.py +0 -0
  74. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/lib/paths.py +0 -0
  75. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/lib/performance/optimizer.py +0 -0
  76. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/lib/performance/rust_bridge.py +0 -0
  77. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/lib/performance/uvloop_config.py +0 -0
  78. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/lib/pickles/pickles.py +0 -0
  79. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/lib/search/cached_vectorizer.py +0 -0
  80. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/lib/services/data_pipeline.py +0 -0
  81. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/lib/services/lsh_client.py +0 -0
  82. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/lib/services/redis_service.py +0 -0
  83. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/lib/shell/shell.py +0 -0
  84. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/lib/toml/toml.py +0 -0
  85. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/lib/ui/styling.py +0 -0
  86. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/lib/ui/visual_effects.py +0 -0
  87. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/lib/watcher/watcher.py +0 -0
  88. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/api/app.py +0 -0
  89. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/api/middleware.py +0 -0
  90. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/api/routers/admin_router.py +0 -0
  91. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/api/routers/auth_router.py +0 -0
  92. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/api/routers/backtest_router.py +0 -0
  93. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/api/routers/data_router.py +0 -0
  94. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/api/routers/model_router.py +0 -0
  95. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/api/routers/monitoring_router.py +0 -0
  96. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/api/routers/portfolio_router.py +0 -0
  97. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/api/routers/prediction_router.py +0 -0
  98. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/api/routers/trade_router.py +0 -0
  99. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/api/routers/websocket_router.py +0 -0
  100. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/api/schemas.py +0 -0
  101. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/auth/auth_manager.py +0 -0
  102. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/auth/models.py +0 -0
  103. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/auth/permissions.py +0 -0
  104. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/backtesting/backtest_engine.py +0 -0
  105. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/backtesting/performance_metrics.py +0 -0
  106. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/cache.py +0 -0
  107. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/cli/main.py +0 -0
  108. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/config/settings.py +0 -0
  109. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/configs/dvc_config.py +0 -0
  110. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/configs/mlflow_config.py +0 -0
  111. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/configs/mlops_manager.py +0 -0
  112. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/dashboard/app.py +0 -0
  113. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/dashboard/app_integrated.py +0 -0
  114. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/dashboard/app_supabase.py +0 -0
  115. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/dashboard/app_training.py +0 -0
  116. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/dashboard/cli.py +0 -0
  117. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/dashboard/common.py +0 -0
  118. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/dashboard/components/charts.py +0 -0
  119. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/dashboard/components/metrics.py +0 -0
  120. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/dashboard/components/tables.py +0 -0
  121. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/dashboard/overview.py +0 -0
  122. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/dashboard/pages/cicd.py +0 -0
  123. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/dashboard/pages/debug_dependencies.py +0 -0
  124. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/dashboard/pages/gravity_viz.py +0 -0
  125. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/dashboard/pages/monte_carlo_predictions.py +0 -0
  126. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/dashboard/pages/predictions_enhanced.py +0 -0
  127. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/dashboard/pages/scrapers_and_logs.py +0 -0
  128. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/dashboard/pages/test_portfolio.py +0 -0
  129. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/dashboard/pages/trading.py +0 -0
  130. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/dashboard/pages/workflows.py +0 -0
  131. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/dashboard/streamlit_extras_utils.py +0 -0
  132. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/dashboard/styles.py +0 -0
  133. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/dashboard/utils.py +0 -0
  134. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/dashboard/warning_suppression.py +0 -0
  135. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/data_ingestion/api_connectors.py +0 -0
  136. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/data_ingestion/data_pipeline.py +0 -0
  137. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/data_ingestion/stream_processor.py +0 -0
  138. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/database/migrations/env.py +0 -0
  139. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/database/models.py +0 -0
  140. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/database/session.py +0 -0
  141. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/experimentation/ab_testing.py +0 -0
  142. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/features/ensemble_features.py +0 -0
  143. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/features/political_features.py +0 -0
  144. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/features/recommendation_engine.py +0 -0
  145. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/features/stock_features.py +0 -0
  146. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/features/test_feature_engineering.py +0 -0
  147. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/logging.py +0 -0
  148. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/mlops/data_versioning.py +0 -0
  149. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/mlops/experiment_tracker.py +0 -0
  150. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/mlops/model_serving.py +0 -0
  151. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/mlops/pipeline_orchestrator.py +0 -0
  152. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/models/base_models.py +0 -0
  153. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/models/ensemble_models.py +0 -0
  154. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/models/recommendation_models.py +0 -0
  155. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/models/test_models.py +0 -0
  156. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/monitoring/drift_detection.py +0 -0
  157. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/monitoring/metrics.py +0 -0
  158. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/optimization/portfolio_optimizer.py +0 -0
  159. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/predictions/monte_carlo.py +0 -0
  160. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/predictions/prediction_engine.py +0 -0
  161. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/preprocessing/data_cleaners.py +0 -0
  162. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/preprocessing/feature_extractors.py +0 -0
  163. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/preprocessing/ml_pipeline.py +0 -0
  164. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/preprocessing/politician_trading_preprocessor.py +0 -0
  165. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/preprocessing/test_preprocessing.py +0 -0
  166. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/scripts/populate_sample_data.py +0 -0
  167. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/tasks.py +0 -0
  168. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/tests/test_integration.py +0 -0
  169. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/tests/test_training_dashboard.py +0 -0
  170. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/trading/alpaca_client.py +0 -0
  171. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/trading/migrations.py +0 -0
  172. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/trading/models.py +0 -0
  173. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/trading/paper_trading.py +0 -0
  174. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/trading/risk_management.py +0 -0
  175. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/trading/trading_service.py +0 -0
  176. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/ml/training/train_model.py +0 -0
  177. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/mygroup/test_cmd.py +0 -0
  178. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/public/oi/oi.py +0 -0
  179. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/public/public.py +0 -0
  180. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/self/completion_cmd.py +0 -0
  181. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/self/logs_cmd.py +0 -0
  182. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/self/redis_cmd.py +0 -0
  183. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/self/store_cmd.py +0 -0
  184. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/self/test_cmd.py +0 -0
  185. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/self/visual_cmd.py +0 -0
  186. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/workflow/daemon/async_command_database.py +0 -0
  187. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/workflow/daemon/async_process_manager.py +0 -0
  188. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/workflow/daemon/client.py +0 -0
  189. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/workflow/daemon/daemon.py +0 -0
  190. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/workflow/daemon/daemon_api.py +0 -0
  191. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/workflow/daemon/enhanced_daemon.py +0 -0
  192. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/workflow/daemon/process_cli.py +0 -0
  193. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/workflow/daemon/process_manager.py +0 -0
  194. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/workflow/daemon/test_daemon.py +0 -0
  195. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/workflow/dashboard/dashboard_cmd.py +0 -0
  196. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/workflow/docker/docker.py +0 -0
  197. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/workflow/gcloud/config.toml +0 -0
  198. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/workflow/gcloud/gcloud.py +0 -0
  199. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/workflow/git_commit/ai_service.py +0 -0
  200. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/workflow/lsh_integration.py +0 -0
  201. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/workflow/model_service/client.py +0 -0
  202. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/workflow/model_service/download_and_run_efficient_models.py +0 -0
  203. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/workflow/model_service/lightweight_embedder.py +0 -0
  204. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/workflow/model_service/lightweight_model_server.py +0 -0
  205. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/workflow/model_service/lightweight_test.py +0 -0
  206. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/workflow/model_service/model_service.py +0 -0
  207. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/workflow/model_service/ollama_efficient_runner.py +0 -0
  208. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/workflow/model_service/openai_adapter.py +0 -0
  209. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/workflow/model_service/pdf_processor.py +0 -0
  210. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/workflow/model_service/test_efficient_runner.py +0 -0
  211. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/workflow/model_service/test_example.py +0 -0
  212. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/workflow/model_service/test_integration.py +0 -0
  213. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/workflow/model_service/test_new_features.py +0 -0
  214. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/workflow/openai/openai.py +0 -0
  215. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/workflow/politician_trading/config.py +0 -0
  216. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/workflow/politician_trading/connectivity.py +0 -0
  217. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/workflow/politician_trading/data_sources.py +0 -0
  218. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/workflow/politician_trading/database.py +0 -0
  219. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/workflow/politician_trading/demo.py +0 -0
  220. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/workflow/politician_trading/models.py +0 -0
  221. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/workflow/politician_trading/monitoring.py +0 -0
  222. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/workflow/politician_trading/scrapers.py +0 -0
  223. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/workflow/politician_trading/scrapers_california.py +0 -0
  224. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/workflow/politician_trading/scrapers_corporate_registry.py +0 -0
  225. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/workflow/politician_trading/scrapers_eu.py +0 -0
  226. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/workflow/politician_trading/scrapers_free_sources.py +0 -0
  227. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/workflow/politician_trading/scrapers_third_party.py +0 -0
  228. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/workflow/politician_trading/scrapers_uk.py +0 -0
  229. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/workflow/politician_trading/scrapers_us_states.py +0 -0
  230. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/workflow/politician_trading/seed_database.py +0 -0
  231. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/workflow/politician_trading/supabase_functions.py +0 -0
  232. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/workflow/politician_trading/workflow.py +0 -0
  233. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/workflow/registry/registry.py +0 -0
  234. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/workflow/repo/repo.py +0 -0
  235. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/workflow/scheduler/cron_parser.py +0 -0
  236. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/workflow/scheduler/job.py +0 -0
  237. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/workflow/scheduler/monitor.py +0 -0
  238. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/workflow/scheduler/persistence.py +0 -0
  239. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/workflow/scheduler/scheduler.py +0 -0
  240. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/workflow/sync/test_cmd.py +0 -0
  241. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/workflow/wakatime/wakatime.py +0 -0
  242. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli/workflow/workflow.py +0 -0
  243. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli_framework.egg-info/dependency_links.txt +0 -0
  244. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli_framework.egg-info/entry_points.txt +0 -0
  245. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/src/mcli_framework.egg-info/top_level.txt +0 -0
  246. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/cli/test_all_commands.py +0 -0
  247. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/cli/test_app_logs_cmd.py +0 -0
  248. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/cli/test_app_redis_cmd.py +0 -0
  249. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/cli/test_logs_cmd.py +0 -0
  250. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/cli/test_main_app.py +0 -0
  251. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/cli/test_model_cmd.py +0 -0
  252. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/cli/test_self_cmd.py +0 -0
  253. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/cli/test_self_cmd_commands.py +0 -0
  254. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/cli/test_self_cmd_plugins.py +0 -0
  255. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/cli/test_self_cmd_utilities.py +0 -0
  256. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/cli/test_workflow_file.py +0 -0
  257. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/cli/test_workflow_gcloud.py +0 -0
  258. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/cli/test_workflow_registry.py +0 -0
  259. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/conftest.py +0 -0
  260. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/demo_generate_graph.py +0 -0
  261. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/demo_hierarchical_transform.py +0 -0
  262. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/e2e/test_complete_workflows.py +0 -0
  263. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/e2e/test_model_workflow.py +0 -0
  264. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/e2e/test_update_workflow.py +0 -0
  265. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/fixtures/chat_fixtures.py +0 -0
  266. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/fixtures/cli_fixtures.py +0 -0
  267. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/fixtures/data_fixtures.py +0 -0
  268. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/fixtures/db_fixtures.py +0 -0
  269. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/fixtures/model_fixtures.py +0 -0
  270. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/integration/test_agent.py +0 -0
  271. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/integration/test_california_scraper.py +0 -0
  272. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/integration/test_chat_client.py +0 -0
  273. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/integration/test_chat_system.py +0 -0
  274. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/integration/test_congress_scraper.py +0 -0
  275. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/integration/test_daemon_client.py +0 -0
  276. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/integration/test_daemon_server.py +0 -0
  277. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/integration/test_e2e_dashboard_lsh_supabase.py +0 -0
  278. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/integration/test_flask_webapp.py +0 -0
  279. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/integration/test_gcloud_services.py +0 -0
  280. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/integration/test_lsh_client.py +0 -0
  281. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/integration/test_lsh_service.py +0 -0
  282. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/integration/test_ml_auth.py +0 -0
  283. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/integration/test_ml_data_pipeline.py +0 -0
  284. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/integration/test_ml_models.py +0 -0
  285. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/integration/test_ml_pipeline.py +0 -0
  286. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/integration/test_oi_service.py +0 -0
  287. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/integration/test_politician_trading.py +0 -0
  288. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/integration/test_repo_operations.py +0 -0
  289. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/integration/test_scheduler_integration.py +0 -0
  290. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/integration/test_service_registry.py +0 -0
  291. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/integration/test_supabase_live_connection.py +0 -0
  292. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/integration/test_uk_scraper.py +0 -0
  293. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/integration/test_us_states_scraper.py +0 -0
  294. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/integration/test_video_processing.py +0 -0
  295. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/integration/test_wakatime_api.py +0 -0
  296. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/integration/test_webapp_full.py +0 -0
  297. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/integration/test_workflow.py +0 -0
  298. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/integration/test_workflow_commands.py +0 -0
  299. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/run_tests.py +0 -0
  300. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/test_harness.py +0 -0
  301. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/test_openai_adapter.py +0 -0
  302. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/unit/test_api_utils.py +0 -0
  303. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/unit/test_async_process_manager.py +0 -0
  304. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/unit/test_auth_modules.py +0 -0
  305. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/unit/test_bug_fixes.py +0 -0
  306. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/unit/test_config.py +0 -0
  307. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/unit/test_custom_commands.py +0 -0
  308. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/unit/test_daemon_api.py +0 -0
  309. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/unit/test_dashboard_components.py +0 -0
  310. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/unit/test_dashboard_functions.py +0 -0
  311. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/unit/test_dashboard_pages.py +0 -0
  312. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/unit/test_dependencies.py +0 -0
  313. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/unit/test_emulator_workflow.py +0 -0
  314. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/unit/test_erd_generation.py +0 -0
  315. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/unit/test_erd_generic.py +0 -0
  316. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/unit/test_erd_imports.py +0 -0
  317. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/unit/test_git_commit_workflow.py +0 -0
  318. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/unit/test_lib_auth.py +0 -0
  319. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/unit/test_lib_files.py +0 -0
  320. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/unit/test_lib_utils.py +0 -0
  321. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/unit/test_logger.py +0 -0
  322. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/unit/test_ml_preprocessing.py +0 -0
  323. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/unit/test_paths.py +0 -0
  324. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/unit/test_pdf_compress.py +0 -0
  325. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/unit/test_prediction_engine.py +0 -0
  326. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/unit/test_regression.py +0 -0
  327. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/unit/test_scheduler.py +0 -0
  328. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/unit/test_scheduler_cron_parser.py +0 -0
  329. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/unit/test_scheduler_job.py +0 -0
  330. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/unit/test_scheduler_monitor.py +0 -0
  331. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/unit/test_scheduler_persistence.py +0 -0
  332. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/unit/test_self_update.py +0 -0
  333. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/unit/test_store_cmd.py +0 -0
  334. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/unit/test_supabase_connection.py +0 -0
  335. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/unit/test_supabase_pagination.py +0 -0
  336. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/unit/test_toml_utils.py +0 -0
  337. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/unit/test_trading_imports.py +0 -0
  338. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/unit/test_ui_rich.py +0 -0
  339. {mcli_framework-7.8.4 → mcli_framework-7.9.0}/tests/unit/test_uv_compat.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mcli-framework
3
- Version: 7.8.4
3
+ Version: 7.9.0
4
4
  Summary: Portable workflow framework - transform any script into a versioned, schedulable command. Store in ~/.mcli/commands/, 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>
@@ -48,6 +48,7 @@ Requires-Dist: humanize<5.0.0,>=4.9.0
48
48
  Requires-Dist: psutil<6.0.0,>=5.9.0
49
49
  Requires-Dist: inquirerpy<0.4.0,>=0.3.4
50
50
  Requires-Dist: gitpython<4.0.0,>=3.1.40
51
+ Requires-Dist: prompt-toolkit<4.0.0,>=3.0.0
51
52
  Requires-Dist: aiohttp>=3.9.0
52
53
  Requires-Dist: httpx>=0.28.1
53
54
  Requires-Dist: websockets>=12.0
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "mcli-framework"
3
- version = "7.8.4"
3
+ version = "7.9.0"
4
4
  description = "Portable workflow framework - transform any script into a versioned, schedulable command. Store in ~/.mcli/commands/, version with lockfile, run as daemon or cron job."
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.9"
@@ -49,6 +49,7 @@ dependencies = [
49
49
  "psutil>=5.9.0,<6.0.0",
50
50
  "inquirerpy>=0.3.4,<0.4.0",
51
51
  "gitpython>=3.1.40,<4.0.0",
52
+ "prompt-toolkit>=3.0.0,<4.0.0",
52
53
  # Basic HTTP/async support
53
54
  "aiohttp>=3.9.0",
54
55
  "httpx>=0.28.1",
@@ -12,8 +12,6 @@ from typing import List, Optional
12
12
  import click
13
13
  import tomli
14
14
 
15
- # Import chat command group
16
- from mcli.app.chat_cmd import chat
17
15
  from mcli.lib.logger.logger import disable_runtime_tracing, enable_runtime_tracing, get_logger
18
16
  from mcli.lib.ui.styling import info, success
19
17
 
@@ -346,14 +344,14 @@ def _add_lazy_commands(app: click.Group):
346
344
  except Exception as e:
347
345
  logger.debug(f"Could not load self commands: {e}")
348
346
 
349
- # Test group - load immediately for testing commands
347
+ # Library utilities and secrets management
350
348
  try:
351
- from mcli.test.test_cmd import test_group
349
+ from mcli.lib.lib import lib
352
350
 
353
- app.add_command(test_group, name="test")
354
- logger.debug("Added test group commands")
351
+ app.add_command(lib, name="lib")
352
+ logger.debug("Added lib commands")
355
353
  except Exception as e:
356
- logger.debug(f"Could not load test commands: {e}")
354
+ logger.debug(f"Could not load lib commands: {e}")
357
355
 
358
356
  # Add workflow with completion-aware lazy loading
359
357
  try:
@@ -377,16 +375,11 @@ def _add_lazy_commands(app: click.Group):
377
375
  app.add_command(workflow_group, name="workflow")
378
376
 
379
377
  # Lazy load other heavy commands that are used less frequently
380
- lazy_commands = {
381
- "chat": {
382
- "import_path": "mcli.app.chat_cmd.chat",
383
- "help": "Start an interactive chat session with the MCLI Chat Assistant.",
384
- },
385
- "model": {
386
- "import_path": "mcli.app.model_cmd.model",
387
- "help": "Model management commands for offline and online model usage",
388
- },
389
- }
378
+ # NOTE: chat and model commands have been removed
379
+ # - chat: removed from core commands
380
+ # - model: moved to ~/.mcli/commands workflow
381
+ # - test: removed from core commands
382
+ lazy_commands = {}
390
383
 
391
384
  for cmd_name, cmd_info in lazy_commands.items():
392
385
  # Skip workflow since we already added it with completion support
@@ -0,0 +1,66 @@
1
+ """
2
+ Model command stub - redirects to workflow command in ~/.mcli/commands/model.json
3
+
4
+ This stub exists for backwards compatibility with tests and imports.
5
+ The actual model command implementation is now in ~/.mcli/commands/model.json
6
+ """
7
+
8
+ import sys
9
+ from pathlib import Path
10
+
11
+ # Try to load the model command from the workflow system
12
+ try:
13
+ from mcli.lib.custom_commands import load_command_from_file
14
+
15
+ # Load model command from ~/.mcli/commands/model.json
16
+ model_json_path = Path.home() / ".mcli" / "commands" / "model.json"
17
+
18
+ if model_json_path.exists():
19
+ # Load the command from the JSON file
20
+ import json
21
+
22
+ with open(model_json_path, "r") as f:
23
+ command_data = json.load(f)
24
+
25
+ # Execute the code to get the app (model command group)
26
+ code = command_data.get("code", "")
27
+ namespace = {}
28
+ exec(code, namespace)
29
+
30
+ # Extract the app (model command group) and individual commands
31
+ app = namespace.get("app")
32
+ if app:
33
+ # The model group command
34
+ model = app
35
+
36
+ # Extract individual subcommands from the model group
37
+ if hasattr(model, "commands"):
38
+ commands = model.commands
39
+ list = commands.get("list")
40
+ download = commands.get("download")
41
+ start = commands.get("start")
42
+ recommend = commands.get("recommend")
43
+ status = commands.get("status")
44
+ stop = commands.get("stop")
45
+ pull = commands.get("pull")
46
+ delete = commands.get("delete")
47
+ else:
48
+ # Fallback if commands aren't available
49
+ list = download = start = recommend = status = stop = pull = delete = None
50
+ else:
51
+ # If app is not found, create empty placeholders
52
+ model = list = download = start = recommend = status = stop = pull = delete = None
53
+ else:
54
+ # If the JSON file doesn't exist, create empty placeholders
55
+ print(f"Warning: {model_json_path} not found", file=sys.stderr)
56
+ model = list = download = start = recommend = status = stop = pull = delete = None
57
+
58
+ except Exception as e:
59
+ print(f"Error loading model command from workflow: {e}", file=sys.stderr)
60
+ import traceback
61
+
62
+ traceback.print_exc()
63
+ model = list = download = start = recommend = status = stop = pull = delete = None
64
+
65
+ # Export the commands for backwards compatibility
66
+ __all__ = ["model", "list", "download", "start", "recommend", "status", "stop", "pull", "delete"]
@@ -3,6 +3,8 @@ import sys
3
3
 
4
4
  import click
5
5
 
6
+ from mcli.lib.secrets.commands import secrets_group
7
+
6
8
 
7
9
  def import_public_module(module_name: str):
8
10
  prefix = "mcli.public."
@@ -20,10 +22,15 @@ def import_public_module(module_name: str):
20
22
  return module
21
23
 
22
24
 
23
- @click.group(name="lib")
25
+ @click.group(name="lib", help="Library utilities and secrets management")
24
26
  def lib():
27
+ """Library utilities and management commands."""
25
28
  pass
26
29
 
27
30
 
31
+ # Add secrets as a subcommand
32
+ lib.add_command(secrets_group)
33
+
34
+
28
35
  if __name__ == "__main__":
29
36
  lib()
@@ -0,0 +1,185 @@
1
+ """
2
+ CLI commands for secrets management.
3
+ """
4
+
5
+ from pathlib import Path
6
+ from typing import Optional
7
+
8
+ import click
9
+
10
+ from mcli.lib.ui.styling import error, info, success, warning
11
+
12
+ from .manager import SecretsManager
13
+ from .repl import run_repl
14
+ from .store import SecretsStore
15
+
16
+
17
+ @click.group(name="secrets", help="Secure secrets management with encryption and git sync")
18
+ def secrets_group():
19
+ """Secrets management commands."""
20
+ pass
21
+
22
+
23
+ @secrets_group.command(name="repl", help="Launch interactive secrets shell")
24
+ def secrets_repl():
25
+ """Launch the interactive secrets REPL."""
26
+ run_repl()
27
+
28
+
29
+ @secrets_group.command(name="set", help="Set a secret value")
30
+ @click.argument("key")
31
+ @click.argument("value")
32
+ @click.option("-n", "--namespace", default="default", help="Namespace for the secret")
33
+ def secrets_set(key: str, value: str, namespace: str):
34
+ """Set a secret value."""
35
+ manager = SecretsManager()
36
+ try:
37
+ manager.set(key, value, namespace)
38
+ success(f"Secret '{key}' set in namespace '{namespace}'")
39
+ except Exception as e:
40
+ error(f"Failed to set secret: {e}")
41
+
42
+
43
+ @secrets_group.command(name="get", help="Get a secret value")
44
+ @click.argument("key")
45
+ @click.option("-n", "--namespace", default="default", help="Namespace for the secret")
46
+ @click.option("-s", "--show", is_flag=True, help="Show the full value (not masked)")
47
+ def secrets_get(key: str, namespace: str, show: bool):
48
+ """Get a secret value."""
49
+ manager = SecretsManager()
50
+ value = manager.get(key, namespace)
51
+
52
+ if value is not None:
53
+ if show:
54
+ click.echo(value)
55
+ else:
56
+ # Mask the value
57
+ masked = (
58
+ value[:3] + "*" * (len(value) - 6) + value[-3:]
59
+ if len(value) > 6
60
+ else "*" * len(value)
61
+ )
62
+ info(f"{key} = {masked}")
63
+ info("Use --show to display the full value")
64
+ else:
65
+ warning(f"Secret '{key}' not found in namespace '{namespace}'")
66
+
67
+
68
+ @secrets_group.command(name="list", help="List all secrets")
69
+ @click.option("-n", "--namespace", help="Filter by namespace")
70
+ def secrets_list(namespace: Optional[str]):
71
+ """List all secrets."""
72
+ manager = SecretsManager()
73
+ secrets = manager.list(namespace)
74
+
75
+ if secrets:
76
+ info("Secrets:")
77
+ for secret in secrets:
78
+ click.echo(f" • {secret}")
79
+ else:
80
+ info("No secrets found")
81
+
82
+
83
+ @secrets_group.command(name="delete", help="Delete a secret")
84
+ @click.argument("key")
85
+ @click.option("-n", "--namespace", default="default", help="Namespace for the secret")
86
+ @click.confirmation_option(prompt="Are you sure you want to delete this secret?")
87
+ def secrets_delete(key: str, namespace: str):
88
+ """Delete a secret."""
89
+ manager = SecretsManager()
90
+ if manager.delete(key, namespace):
91
+ success(f"Secret '{key}' deleted from namespace '{namespace}'")
92
+ else:
93
+ warning(f"Secret '{key}' not found in namespace '{namespace}'")
94
+
95
+
96
+ @secrets_group.command(name="export", help="Export secrets as environment variables")
97
+ @click.option("-n", "--namespace", help="Namespace to export")
98
+ @click.option("-o", "--output", type=click.Path(), help="Output file (defaults to stdout)")
99
+ def secrets_export(namespace: Optional[str], output: Optional[str]):
100
+ """Export secrets as environment variables."""
101
+ manager = SecretsManager()
102
+ env_vars = manager.export_env(namespace)
103
+
104
+ if env_vars:
105
+ if output:
106
+ with open(output, "w") as f:
107
+ for key, value in env_vars.items():
108
+ f.write(f"export {key}={value}\n")
109
+ success(f"Exported {len(env_vars)} secrets to {output}")
110
+ else:
111
+ for key, value in env_vars.items():
112
+ click.echo(f"export {key}={value}")
113
+ else:
114
+ info("No secrets to export")
115
+
116
+
117
+ @secrets_group.command(name="import", help="Import secrets from environment file")
118
+ @click.argument("env_file", type=click.Path(exists=True))
119
+ @click.option("-n", "--namespace", default="default", help="Namespace to import into")
120
+ def secrets_import(env_file: str, namespace: str):
121
+ """Import secrets from environment file."""
122
+ manager = SecretsManager()
123
+ count = manager.import_env(Path(env_file), namespace)
124
+ success(f"Imported {count} secrets into namespace '{namespace}'")
125
+
126
+
127
+ @secrets_group.group(name="store", help="Git-based secrets synchronization")
128
+ def store_group():
129
+ """Store management commands."""
130
+ pass
131
+
132
+
133
+ @store_group.command(name="init", help="Initialize secrets store")
134
+ @click.option("-r", "--remote", help="Git remote URL")
135
+ def store_init(remote: Optional[str]):
136
+ """Initialize the secrets store."""
137
+ store = SecretsStore()
138
+ store.init(remote)
139
+
140
+
141
+ @store_group.command(name="push", help="Push secrets to store")
142
+ @click.option("-m", "--message", help="Commit message")
143
+ def store_push(message: Optional[str]):
144
+ """Push secrets to store."""
145
+ manager = SecretsManager()
146
+ store = SecretsStore()
147
+ store.push(manager.secrets_dir, message)
148
+
149
+
150
+ @store_group.command(name="pull", help="Pull secrets from store")
151
+ def store_pull():
152
+ """Pull secrets from store."""
153
+ manager = SecretsManager()
154
+ store = SecretsStore()
155
+ store.pull(manager.secrets_dir)
156
+
157
+
158
+ @store_group.command(name="sync", help="Sync secrets with store")
159
+ @click.option("-m", "--message", help="Commit message")
160
+ def store_sync(message: Optional[str]):
161
+ """Sync secrets with store."""
162
+ manager = SecretsManager()
163
+ store = SecretsStore()
164
+ store.sync(manager.secrets_dir, message)
165
+
166
+
167
+ @store_group.command(name="status", help="Show store status")
168
+ def store_status():
169
+ """Show store status."""
170
+ store = SecretsStore()
171
+ status = store.status()
172
+
173
+ info("Secrets Store Status:")
174
+ click.echo(f" Initialized: {status['initialized']}")
175
+ click.echo(f" Path: {status['store_path']}")
176
+
177
+ if status["initialized"]:
178
+ click.echo(f" Branch: {status['branch']}")
179
+ click.echo(f" Commit: {status['commit']}")
180
+ click.echo(f" Clean: {status['clean']}")
181
+
182
+ if status["has_remote"]:
183
+ click.echo(f" Remote: {status['remote_url']}")
184
+ else:
185
+ click.echo(" Remote: Not configured")
@@ -0,0 +1,213 @@
1
+ """
2
+ Secrets manager for handling secure storage and retrieval of secrets.
3
+ """
4
+
5
+ import base64
6
+ import json
7
+ import os
8
+ from pathlib import Path
9
+ from typing import Dict, List, Optional
10
+
11
+ import click
12
+ from cryptography.fernet import Fernet
13
+ from cryptography.hazmat.primitives import hashes
14
+ from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
15
+
16
+ from mcli.lib.logger.logger import get_logger
17
+
18
+ logger = get_logger(__name__)
19
+
20
+
21
+ class SecretsManager:
22
+ """Manages secrets storage with encryption."""
23
+
24
+ def __init__(self, secrets_dir: Optional[Path] = None):
25
+ """Initialize the secrets manager.
26
+
27
+ Args:
28
+ secrets_dir: Directory to store secrets. Defaults to ~/.mcli/secrets/
29
+ """
30
+ self.secrets_dir = secrets_dir or Path.home() / ".mcli" / "secrets"
31
+ self.secrets_dir.mkdir(parents=True, exist_ok=True)
32
+ self._cipher_suite = self._get_cipher_suite()
33
+
34
+ def _get_cipher_suite(self) -> Fernet:
35
+ """Get or create encryption key."""
36
+ key_file = self.secrets_dir / ".key"
37
+
38
+ if key_file.exists():
39
+ with open(key_file, "rb") as f:
40
+ key = f.read()
41
+ else:
42
+ # Generate a new key from a password
43
+ password = click.prompt("Enter a password for secrets encryption", hide_input=True)
44
+ password_bytes = password.encode()
45
+
46
+ # Use PBKDF2 to derive a key from the password
47
+ kdf = PBKDF2HMAC(
48
+ algorithm=hashes.SHA256(),
49
+ length=32,
50
+ salt=b"mcli-secrets-salt", # In production, use a random salt
51
+ iterations=100000,
52
+ )
53
+ key = base64.urlsafe_b64encode(kdf.derive(password_bytes))
54
+
55
+ # Save the key (in production, this should be stored more securely)
56
+ with open(key_file, "wb") as f:
57
+ f.write(key)
58
+
59
+ # Set restrictive permissions
60
+ os.chmod(key_file, 0o600)
61
+
62
+ return Fernet(key)
63
+
64
+ def set(self, key: str, value: str, namespace: Optional[str] = None) -> None:
65
+ """Set a secret value.
66
+
67
+ Args:
68
+ key: Secret key
69
+ value: Secret value
70
+ namespace: Optional namespace for grouping secrets
71
+ """
72
+ namespace = namespace or "default"
73
+ namespace_dir = self.secrets_dir / namespace
74
+ namespace_dir.mkdir(exist_ok=True)
75
+
76
+ # Encrypt the value
77
+ encrypted_value = self._cipher_suite.encrypt(value.encode())
78
+
79
+ # Store the encrypted value
80
+ secret_file = namespace_dir / f"{key}.secret"
81
+ with open(secret_file, "wb") as f:
82
+ f.write(encrypted_value)
83
+
84
+ # Set restrictive permissions
85
+ os.chmod(secret_file, 0o600)
86
+
87
+ logger.debug(f"Secret '{key}' stored in namespace '{namespace}'")
88
+
89
+ def get(self, key: str, namespace: Optional[str] = None) -> Optional[str]:
90
+ """Get a secret value.
91
+
92
+ Args:
93
+ key: Secret key
94
+ namespace: Optional namespace
95
+
96
+ Returns:
97
+ Decrypted secret value or None if not found
98
+ """
99
+ namespace = namespace or "default"
100
+ secret_file = self.secrets_dir / namespace / f"{key}.secret"
101
+
102
+ if not secret_file.exists():
103
+ return None
104
+
105
+ with open(secret_file, "rb") as f:
106
+ encrypted_value = f.read()
107
+
108
+ try:
109
+ decrypted_value = self._cipher_suite.decrypt(encrypted_value)
110
+ return decrypted_value.decode()
111
+ except Exception as e:
112
+ logger.error(f"Failed to decrypt secret '{key}': {e}")
113
+ return None
114
+
115
+ def list(self, namespace: Optional[str] = None) -> List[str]:
116
+ """List all secret keys.
117
+
118
+ Args:
119
+ namespace: Optional namespace filter
120
+
121
+ Returns:
122
+ List of secret keys
123
+ """
124
+ if namespace:
125
+ namespace_dirs = [self.secrets_dir / namespace]
126
+ else:
127
+ namespace_dirs = [
128
+ d for d in self.secrets_dir.iterdir() if d.is_dir() and not d.name.startswith(".")
129
+ ]
130
+
131
+ secrets = []
132
+ for namespace_dir in namespace_dirs:
133
+ if namespace_dir.exists():
134
+ for secret_file in namespace_dir.glob("*.secret"):
135
+ key = secret_file.stem
136
+ ns = namespace_dir.name
137
+ secrets.append(f"{ns}/{key}" if not namespace else key)
138
+
139
+ return sorted(secrets)
140
+
141
+ def delete(self, key: str, namespace: Optional[str] = None) -> bool:
142
+ """Delete a secret.
143
+
144
+ Args:
145
+ key: Secret key
146
+ namespace: Optional namespace
147
+
148
+ Returns:
149
+ True if deleted, False if not found
150
+ """
151
+ namespace = namespace or "default"
152
+ secret_file = self.secrets_dir / namespace / f"{key}.secret"
153
+
154
+ if secret_file.exists():
155
+ secret_file.unlink()
156
+ logger.debug(f"Secret '{key}' deleted from namespace '{namespace}'")
157
+ return True
158
+
159
+ return False
160
+
161
+ def export_env(self, namespace: Optional[str] = None) -> Dict[str, str]:
162
+ """Export secrets as environment variables.
163
+
164
+ Args:
165
+ namespace: Optional namespace filter
166
+
167
+ Returns:
168
+ Dictionary of key-value pairs
169
+ """
170
+ env_vars = {}
171
+
172
+ for secret_key in self.list(namespace):
173
+ if "/" in secret_key:
174
+ ns, key = secret_key.split("/", 1)
175
+ value = self.get(key, ns)
176
+ else:
177
+ value = self.get(secret_key, namespace)
178
+
179
+ if value:
180
+ # Convert to uppercase for environment variable convention
181
+ if "/" in secret_key:
182
+ env_key = key.upper().replace("-", "_")
183
+ else:
184
+ env_key = secret_key.upper().replace("-", "_")
185
+ env_vars[env_key] = value
186
+
187
+ return env_vars
188
+
189
+ def import_env(self, env_file: Path, namespace: Optional[str] = None) -> int:
190
+ """Import secrets from an environment file.
191
+
192
+ Args:
193
+ env_file: Path to .env file
194
+ namespace: Optional namespace
195
+
196
+ Returns:
197
+ Number of secrets imported
198
+ """
199
+ namespace = namespace or "default"
200
+ count = 0
201
+
202
+ with open(env_file) as f:
203
+ for line in f:
204
+ line = line.strip()
205
+ if line and not line.startswith("#") and "=" in line:
206
+ key, value = line.split("=", 1)
207
+ key = key.strip()
208
+ value = value.strip().strip('"').strip("'")
209
+
210
+ self.set(key.lower().replace("_", "-"), value, namespace)
211
+ count += 1
212
+
213
+ return count