mcli-framework 7.7.1__tar.gz → 7.8.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 (331) hide show
  1. {mcli_framework-7.7.1/src/mcli_framework.egg-info → mcli_framework-7.8.0}/PKG-INFO +1 -1
  2. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/pyproject.toml +1 -1
  3. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/app/main.py +14 -2
  4. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/self/self_cmd.py +0 -28
  5. {mcli_framework-7.7.1 → mcli_framework-7.8.0/src/mcli_framework.egg-info}/PKG-INFO +1 -1
  6. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli_framework.egg-info/SOURCES.txt +1 -0
  7. mcli_framework-7.8.0/tests/unit/test_pdf_compress.py +265 -0
  8. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/.github/dependabot.yml +0 -0
  9. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/.github/workflows/build.yml +0 -0
  10. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/.github/workflows/ci.yml +0 -0
  11. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/.github/workflows/ml-pipeline.yml +0 -0
  12. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/.github/workflows/publish-self-hosted.yml +0 -0
  13. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/.github/workflows/publish.yml +0 -0
  14. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/.github/workflows/release.yml +0 -0
  15. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/.github/workflows/security.yml +0 -0
  16. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/.github/workflows/test.yml +0 -0
  17. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/LICENSE +0 -0
  18. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/MANIFEST.in +0 -0
  19. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/README.md +0 -0
  20. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/mcli_rust/Cargo.toml +0 -0
  21. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/mcli_rust/src/command_parser.rs +0 -0
  22. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/mcli_rust/src/file_watcher.rs +0 -0
  23. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/mcli_rust/src/lib.rs +0 -0
  24. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/mcli_rust/src/process_manager.rs +0 -0
  25. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/mcli_rust/src/tfidf.rs +0 -0
  26. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/setup.cfg +0 -0
  27. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/app/chat_cmd.py +0 -0
  28. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/app/commands_cmd.py +0 -0
  29. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/app/completion_helpers.py +0 -0
  30. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/app/model/model.py +0 -0
  31. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/app/model_cmd.py +0 -0
  32. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/app/video/video.py +0 -0
  33. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/chat/chat.py +0 -0
  34. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/chat/command_rag.py +0 -0
  35. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/chat/enhanced_chat.py +0 -0
  36. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/chat/system_controller.py +0 -0
  37. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/chat/system_integration.py +0 -0
  38. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/cli.py +0 -0
  39. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/config.toml +0 -0
  40. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/lib/api/api.py +0 -0
  41. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/lib/api/daemon_client.py +0 -0
  42. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/lib/api/daemon_client_local.py +0 -0
  43. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/lib/api/daemon_decorator.py +0 -0
  44. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/lib/api/mcli_decorators.py +0 -0
  45. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/lib/auth/auth.py +0 -0
  46. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/lib/auth/aws_manager.py +0 -0
  47. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/lib/auth/azure_manager.py +0 -0
  48. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/lib/auth/credential_manager.py +0 -0
  49. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/lib/auth/gcp_manager.py +0 -0
  50. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/lib/auth/key_manager.py +0 -0
  51. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/lib/auth/mcli_manager.py +0 -0
  52. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/lib/auth/token_manager.py +0 -0
  53. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/lib/auth/token_util.py +0 -0
  54. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/lib/config/config.py +0 -0
  55. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/lib/custom_commands.py +0 -0
  56. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/lib/discovery/__init__.py +0 -0
  57. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/lib/discovery/command_discovery.py +0 -0
  58. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/lib/erd/erd.py +0 -0
  59. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/lib/erd/generate_graph.py +0 -0
  60. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/lib/files/files.py +0 -0
  61. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/lib/fs/fs.py +0 -0
  62. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/lib/lib.py +0 -0
  63. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/lib/logger/logger.py +0 -0
  64. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/lib/paths.py +0 -0
  65. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/lib/performance/optimizer.py +0 -0
  66. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/lib/performance/rust_bridge.py +0 -0
  67. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/lib/performance/uvloop_config.py +0 -0
  68. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/lib/pickles/pickles.py +0 -0
  69. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/lib/search/cached_vectorizer.py +0 -0
  70. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/lib/services/data_pipeline.py +0 -0
  71. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/lib/services/lsh_client.py +0 -0
  72. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/lib/services/redis_service.py +0 -0
  73. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/lib/shell/shell.py +0 -0
  74. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/lib/toml/toml.py +0 -0
  75. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/lib/ui/styling.py +0 -0
  76. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/lib/ui/visual_effects.py +0 -0
  77. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/lib/watcher/watcher.py +0 -0
  78. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/api/app.py +0 -0
  79. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/api/middleware.py +0 -0
  80. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/api/routers/admin_router.py +0 -0
  81. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/api/routers/auth_router.py +0 -0
  82. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/api/routers/backtest_router.py +0 -0
  83. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/api/routers/data_router.py +0 -0
  84. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/api/routers/model_router.py +0 -0
  85. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/api/routers/monitoring_router.py +0 -0
  86. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/api/routers/portfolio_router.py +0 -0
  87. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/api/routers/prediction_router.py +0 -0
  88. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/api/routers/trade_router.py +0 -0
  89. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/api/routers/websocket_router.py +0 -0
  90. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/api/schemas.py +0 -0
  91. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/auth/auth_manager.py +0 -0
  92. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/auth/models.py +0 -0
  93. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/auth/permissions.py +0 -0
  94. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/backtesting/backtest_engine.py +0 -0
  95. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/backtesting/performance_metrics.py +0 -0
  96. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/cache.py +0 -0
  97. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/cli/main.py +0 -0
  98. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/config/settings.py +0 -0
  99. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/configs/dvc_config.py +0 -0
  100. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/configs/mlflow_config.py +0 -0
  101. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/configs/mlops_manager.py +0 -0
  102. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/dashboard/app.py +0 -0
  103. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/dashboard/app_integrated.py +0 -0
  104. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/dashboard/app_supabase.py +0 -0
  105. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/dashboard/app_training.py +0 -0
  106. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/dashboard/cli.py +0 -0
  107. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/dashboard/common.py +0 -0
  108. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/dashboard/components/charts.py +0 -0
  109. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/dashboard/components/metrics.py +0 -0
  110. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/dashboard/components/tables.py +0 -0
  111. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/dashboard/overview.py +0 -0
  112. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/dashboard/pages/cicd.py +0 -0
  113. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/dashboard/pages/debug_dependencies.py +0 -0
  114. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/dashboard/pages/gravity_viz.py +0 -0
  115. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/dashboard/pages/monte_carlo_predictions.py +0 -0
  116. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/dashboard/pages/predictions_enhanced.py +0 -0
  117. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/dashboard/pages/scrapers_and_logs.py +0 -0
  118. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/dashboard/pages/test_portfolio.py +0 -0
  119. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/dashboard/pages/trading.py +0 -0
  120. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/dashboard/pages/workflows.py +0 -0
  121. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/dashboard/streamlit_extras_utils.py +0 -0
  122. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/dashboard/styles.py +0 -0
  123. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/dashboard/utils.py +0 -0
  124. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/dashboard/warning_suppression.py +0 -0
  125. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/data_ingestion/api_connectors.py +0 -0
  126. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/data_ingestion/data_pipeline.py +0 -0
  127. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/data_ingestion/stream_processor.py +0 -0
  128. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/database/migrations/env.py +0 -0
  129. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/database/models.py +0 -0
  130. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/database/session.py +0 -0
  131. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/experimentation/ab_testing.py +0 -0
  132. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/features/ensemble_features.py +0 -0
  133. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/features/political_features.py +0 -0
  134. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/features/recommendation_engine.py +0 -0
  135. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/features/stock_features.py +0 -0
  136. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/features/test_feature_engineering.py +0 -0
  137. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/logging.py +0 -0
  138. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/mlops/data_versioning.py +0 -0
  139. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/mlops/experiment_tracker.py +0 -0
  140. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/mlops/model_serving.py +0 -0
  141. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/mlops/pipeline_orchestrator.py +0 -0
  142. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/models/base_models.py +0 -0
  143. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/models/ensemble_models.py +0 -0
  144. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/models/recommendation_models.py +0 -0
  145. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/models/test_models.py +0 -0
  146. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/monitoring/drift_detection.py +0 -0
  147. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/monitoring/metrics.py +0 -0
  148. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/optimization/portfolio_optimizer.py +0 -0
  149. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/predictions/monte_carlo.py +0 -0
  150. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/predictions/prediction_engine.py +0 -0
  151. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/preprocessing/data_cleaners.py +0 -0
  152. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/preprocessing/feature_extractors.py +0 -0
  153. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/preprocessing/ml_pipeline.py +0 -0
  154. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/preprocessing/politician_trading_preprocessor.py +0 -0
  155. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/preprocessing/test_preprocessing.py +0 -0
  156. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/scripts/populate_sample_data.py +0 -0
  157. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/tasks.py +0 -0
  158. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/tests/test_integration.py +0 -0
  159. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/tests/test_training_dashboard.py +0 -0
  160. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/trading/alpaca_client.py +0 -0
  161. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/trading/migrations.py +0 -0
  162. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/trading/models.py +0 -0
  163. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/trading/paper_trading.py +0 -0
  164. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/trading/risk_management.py +0 -0
  165. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/trading/trading_service.py +0 -0
  166. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/ml/training/train_model.py +0 -0
  167. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/mygroup/test_cmd.py +0 -0
  168. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/public/oi/oi.py +0 -0
  169. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/public/public.py +0 -0
  170. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/self/completion_cmd.py +0 -0
  171. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/self/logs_cmd.py +0 -0
  172. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/self/redis_cmd.py +0 -0
  173. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/self/test_cmd.py +0 -0
  174. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/self/visual_cmd.py +0 -0
  175. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/test/cron_test_cmd.py +0 -0
  176. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/test/test_cmd.py +0 -0
  177. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/workflow/daemon/async_command_database.py +0 -0
  178. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/workflow/daemon/async_process_manager.py +0 -0
  179. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/workflow/daemon/client.py +0 -0
  180. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/workflow/daemon/daemon.py +0 -0
  181. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/workflow/daemon/daemon_api.py +0 -0
  182. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/workflow/daemon/enhanced_daemon.py +0 -0
  183. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/workflow/daemon/process_cli.py +0 -0
  184. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/workflow/daemon/process_manager.py +0 -0
  185. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/workflow/daemon/test_daemon.py +0 -0
  186. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/workflow/docker/docker.py +0 -0
  187. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/workflow/gcloud/config.toml +0 -0
  188. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/workflow/gcloud/gcloud.py +0 -0
  189. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/workflow/git_commit/ai_service.py +0 -0
  190. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/workflow/lsh_integration.py +0 -0
  191. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/workflow/model_service/client.py +0 -0
  192. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/workflow/model_service/download_and_run_efficient_models.py +0 -0
  193. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/workflow/model_service/lightweight_embedder.py +0 -0
  194. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/workflow/model_service/lightweight_model_server.py +0 -0
  195. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/workflow/model_service/lightweight_test.py +0 -0
  196. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/workflow/model_service/model_service.py +0 -0
  197. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/workflow/model_service/ollama_efficient_runner.py +0 -0
  198. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/workflow/model_service/openai_adapter.py +0 -0
  199. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/workflow/model_service/pdf_processor.py +0 -0
  200. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/workflow/model_service/test_efficient_runner.py +0 -0
  201. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/workflow/model_service/test_example.py +0 -0
  202. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/workflow/model_service/test_integration.py +0 -0
  203. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/workflow/model_service/test_new_features.py +0 -0
  204. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/workflow/openai/openai.py +0 -0
  205. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/workflow/politician_trading/config.py +0 -0
  206. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/workflow/politician_trading/connectivity.py +0 -0
  207. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/workflow/politician_trading/data_sources.py +0 -0
  208. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/workflow/politician_trading/database.py +0 -0
  209. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/workflow/politician_trading/demo.py +0 -0
  210. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/workflow/politician_trading/models.py +0 -0
  211. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/workflow/politician_trading/monitoring.py +0 -0
  212. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/workflow/politician_trading/scrapers.py +0 -0
  213. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/workflow/politician_trading/scrapers_california.py +0 -0
  214. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/workflow/politician_trading/scrapers_corporate_registry.py +0 -0
  215. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/workflow/politician_trading/scrapers_eu.py +0 -0
  216. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/workflow/politician_trading/scrapers_free_sources.py +0 -0
  217. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/workflow/politician_trading/scrapers_third_party.py +0 -0
  218. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/workflow/politician_trading/scrapers_uk.py +0 -0
  219. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/workflow/politician_trading/scrapers_us_states.py +0 -0
  220. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/workflow/politician_trading/seed_database.py +0 -0
  221. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/workflow/politician_trading/supabase_functions.py +0 -0
  222. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/workflow/politician_trading/workflow.py +0 -0
  223. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/workflow/registry/registry.py +0 -0
  224. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/workflow/repo/repo.py +0 -0
  225. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/workflow/scheduler/cron_parser.py +0 -0
  226. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/workflow/scheduler/job.py +0 -0
  227. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/workflow/scheduler/monitor.py +0 -0
  228. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/workflow/scheduler/persistence.py +0 -0
  229. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/workflow/scheduler/scheduler.py +0 -0
  230. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/workflow/sync/test_cmd.py +0 -0
  231. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/workflow/wakatime/wakatime.py +0 -0
  232. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli/workflow/workflow.py +0 -0
  233. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli_framework.egg-info/dependency_links.txt +0 -0
  234. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli_framework.egg-info/entry_points.txt +0 -0
  235. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli_framework.egg-info/requires.txt +0 -0
  236. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/src/mcli_framework.egg-info/top_level.txt +0 -0
  237. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/cli/test_all_commands.py +0 -0
  238. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/cli/test_app_logs_cmd.py +0 -0
  239. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/cli/test_app_redis_cmd.py +0 -0
  240. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/cli/test_chat_cmd.py +0 -0
  241. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/cli/test_logs_cmd.py +0 -0
  242. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/cli/test_main_app.py +0 -0
  243. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/cli/test_model_cmd.py +0 -0
  244. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/cli/test_self_cmd.py +0 -0
  245. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/cli/test_self_cmd_commands.py +0 -0
  246. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/cli/test_self_cmd_plugins.py +0 -0
  247. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/cli/test_self_cmd_utilities.py +0 -0
  248. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/cli/test_workflow_file.py +0 -0
  249. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/cli/test_workflow_gcloud.py +0 -0
  250. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/cli/test_workflow_registry.py +0 -0
  251. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/conftest.py +0 -0
  252. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/demo_generate_graph.py +0 -0
  253. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/demo_hierarchical_transform.py +0 -0
  254. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/e2e/test_complete_workflows.py +0 -0
  255. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/e2e/test_model_workflow.py +0 -0
  256. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/e2e/test_new_user_workflow.py +0 -0
  257. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/e2e/test_update_workflow.py +0 -0
  258. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/fixtures/chat_fixtures.py +0 -0
  259. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/fixtures/cli_fixtures.py +0 -0
  260. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/fixtures/data_fixtures.py +0 -0
  261. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/fixtures/db_fixtures.py +0 -0
  262. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/fixtures/model_fixtures.py +0 -0
  263. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/integration/test_agent.py +0 -0
  264. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/integration/test_california_scraper.py +0 -0
  265. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/integration/test_chat_client.py +0 -0
  266. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/integration/test_chat_system.py +0 -0
  267. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/integration/test_congress_scraper.py +0 -0
  268. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/integration/test_daemon_client.py +0 -0
  269. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/integration/test_daemon_server.py +0 -0
  270. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/integration/test_e2e_dashboard_lsh_supabase.py +0 -0
  271. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/integration/test_flask_webapp.py +0 -0
  272. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/integration/test_gcloud_services.py +0 -0
  273. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/integration/test_lsh_client.py +0 -0
  274. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/integration/test_lsh_service.py +0 -0
  275. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/integration/test_ml_auth.py +0 -0
  276. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/integration/test_ml_data_pipeline.py +0 -0
  277. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/integration/test_ml_models.py +0 -0
  278. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/integration/test_ml_pipeline.py +0 -0
  279. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/integration/test_module_imports.py +0 -0
  280. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/integration/test_oi_service.py +0 -0
  281. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/integration/test_politician_trading.py +0 -0
  282. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/integration/test_repo_operations.py +0 -0
  283. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/integration/test_scheduler_integration.py +0 -0
  284. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/integration/test_service_registry.py +0 -0
  285. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/integration/test_supabase_live_connection.py +0 -0
  286. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/integration/test_uk_scraper.py +0 -0
  287. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/integration/test_us_states_scraper.py +0 -0
  288. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/integration/test_video_processing.py +0 -0
  289. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/integration/test_wakatime_api.py +0 -0
  290. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/integration/test_webapp_full.py +0 -0
  291. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/integration/test_workflow.py +0 -0
  292. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/integration/test_workflow_commands.py +0 -0
  293. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/run_tests.py +0 -0
  294. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/test_harness.py +0 -0
  295. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/test_openai_adapter.py +0 -0
  296. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/unit/test_api_utils.py +0 -0
  297. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/unit/test_async_process_manager.py +0 -0
  298. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/unit/test_auth_modules.py +0 -0
  299. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/unit/test_bug_fixes.py +0 -0
  300. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/unit/test_config.py +0 -0
  301. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/unit/test_custom_commands.py +0 -0
  302. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/unit/test_daemon_api.py +0 -0
  303. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/unit/test_dashboard_components.py +0 -0
  304. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/unit/test_dashboard_functions.py +0 -0
  305. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/unit/test_dashboard_pages.py +0 -0
  306. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/unit/test_dependencies.py +0 -0
  307. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/unit/test_emulator_workflow.py +0 -0
  308. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/unit/test_erd_generation.py +0 -0
  309. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/unit/test_erd_generic.py +0 -0
  310. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/unit/test_erd_imports.py +0 -0
  311. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/unit/test_git_commit_workflow.py +0 -0
  312. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/unit/test_lib_auth.py +0 -0
  313. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/unit/test_lib_files.py +0 -0
  314. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/unit/test_lib_utils.py +0 -0
  315. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/unit/test_logger.py +0 -0
  316. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/unit/test_ml_preprocessing.py +0 -0
  317. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/unit/test_paths.py +0 -0
  318. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/unit/test_prediction_engine.py +0 -0
  319. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/unit/test_regression.py +0 -0
  320. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/unit/test_scheduler.py +0 -0
  321. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/unit/test_scheduler_cron_parser.py +0 -0
  322. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/unit/test_scheduler_job.py +0 -0
  323. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/unit/test_scheduler_monitor.py +0 -0
  324. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/unit/test_scheduler_persistence.py +0 -0
  325. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/unit/test_self_update.py +0 -0
  326. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/unit/test_supabase_connection.py +0 -0
  327. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/unit/test_supabase_pagination.py +0 -0
  328. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/unit/test_toml_utils.py +0 -0
  329. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/unit/test_trading_imports.py +0 -0
  330. {mcli_framework-7.7.1 → mcli_framework-7.8.0}/tests/unit/test_ui_rich.py +0 -0
  331. {mcli_framework-7.7.1 → mcli_framework-7.8.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.7.1
3
+ Version: 7.8.0
4
4
  Summary: 🚀 High-performance CLI framework with Rust extensions, AI chat, and stunning visuals
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 = "7.7.1"
3
+ version = "7.8.0"
4
4
  description = "🚀 High-performance CLI framework with Rust extensions, AI chat, and stunning visuals"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.9"
@@ -456,8 +456,20 @@ def create_app() -> click.Group:
456
456
  def get_version_info(verbose: bool = False) -> str:
457
457
  """Get version info, cached to prevent multiple calls."""
458
458
  try:
459
- mcli_version = version("mcli")
460
- meta = metadata("mcli")
459
+ # Try mcli-framework first (PyPI package name), then mcli (local dev)
460
+ mcli_version = None
461
+ meta = None
462
+
463
+ for pkg_name in ["mcli-framework", "mcli"]:
464
+ try:
465
+ mcli_version = version(pkg_name)
466
+ meta = metadata(pkg_name)
467
+ break
468
+ except Exception:
469
+ continue
470
+
471
+ if mcli_version is None:
472
+ return "Could not determine version: Package metadata not found"
461
473
 
462
474
  info = [f"mcli version {mcli_version}"]
463
475
 
@@ -1243,34 +1243,6 @@ def update(check: bool, pre: bool, yes: bool, skip_ci_check: bool):
1243
1243
 
1244
1244
  console.print(f"[dim]{traceback.format_exc()}[/dim]")
1245
1245
 
1246
- # Validate syntax
1247
- try:
1248
- compile(new_code, "<string>", "exec")
1249
- except SyntaxError as e:
1250
- click.echo(f"❌ Syntax error in edited code: {e}", err=True)
1251
- should_save = Prompt.ask("Save anyway?", choices=["y", "n"], default="n")
1252
- if should_save.lower() != "y":
1253
- return 1
1254
-
1255
- # Update the command
1256
- command_data["code"] = new_code
1257
- command_data["updated_at"] = datetime.now().isoformat()
1258
-
1259
- with open(command_file, "w") as f:
1260
- json.dump(command_data, f, indent=2)
1261
-
1262
- # Update lockfile
1263
- manager.generate_lockfile()
1264
-
1265
- click.echo(f"✅ Updated command: {command_name}")
1266
- click.echo(f"📁 Saved to: {command_file}")
1267
- click.echo(f"🔄 Reload with: mcli self reload" or "restart mcli")
1268
-
1269
- finally:
1270
- Path(tmp_path).unlink(missing_ok=True)
1271
-
1272
- return 0
1273
-
1274
1246
 
1275
1247
  # Register the plugin group with self_app
1276
1248
  self_app.add_command(plugin)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mcli-framework
3
- Version: 7.7.1
3
+ Version: 7.8.0
4
4
  Summary: 🚀 High-performance CLI framework with Rust extensions, AI chat, and stunning visuals
5
5
  Author-email: Luis Fernandez de la Vara <luis@lefv.io>
6
6
  Maintainer-email: Luis Fernandez de la Vara <luis@lefv.io>
@@ -313,6 +313,7 @@ tests/unit/test_lib_utils.py
313
313
  tests/unit/test_logger.py
314
314
  tests/unit/test_ml_preprocessing.py
315
315
  tests/unit/test_paths.py
316
+ tests/unit/test_pdf_compress.py
316
317
  tests/unit/test_prediction_engine.py
317
318
  tests/unit/test_regression.py
318
319
  tests/unit/test_scheduler.py
@@ -0,0 +1,265 @@
1
+ """
2
+ Unit tests for PDF compression functionality
3
+ """
4
+
5
+ import os
6
+ import pytest
7
+ from pathlib import Path
8
+ from unittest.mock import Mock, patch, MagicMock
9
+
10
+
11
+ @pytest.fixture
12
+ def mock_fitz():
13
+ """Mock PyMuPDF (fitz) library"""
14
+ with patch("fitz") as mock:
15
+ # Mock document
16
+ mock_doc = MagicMock()
17
+ mock_doc.__len__.return_value = 3
18
+ mock.open.return_value = mock_doc
19
+
20
+ # Mock page
21
+ mock_page = MagicMock()
22
+ mock_page.rect = MagickMock()
23
+ mock_page.rect.width = 612
24
+ mock_page.rect.height = 792
25
+ mock_doc.load_page.return_value = mock_page
26
+
27
+ # Mock pixmap
28
+ mock_pix = MagicMock()
29
+ mock_pix.tobytes.return_value = b"fake_image_data"
30
+ mock_page.get_pixmap.return_value = mock_pix
31
+
32
+ # Mock output document
33
+ mock_out_doc = MagicMock()
34
+ mock_new_page = MagicMock()
35
+ mock_new_page.rect = mock_page.rect
36
+ mock_out_doc.new_page.return_value = mock_new_page
37
+ mock.open.side_effect = [mock_doc, mock_out_doc]
38
+
39
+ yield mock
40
+
41
+
42
+ class TestPageRangeParsing:
43
+ """Test parse_page_range function"""
44
+
45
+ def test_parse_single_page(self):
46
+ """Test parsing single page number"""
47
+ # This would need to import the actual function from the PDF workflow
48
+ # For now, we're testing the logic
49
+ result = self._parse_page_range("3")
50
+ assert result == [3]
51
+
52
+ def test_parse_multiple_pages(self):
53
+ """Test parsing multiple page numbers"""
54
+ result = self._parse_page_range("3,4,7")
55
+ assert result == [3, 4, 7]
56
+
57
+ def test_parse_page_range(self):
58
+ """Test parsing page range"""
59
+ result = self._parse_page_range("3-5")
60
+ assert result == [3, 4, 5]
61
+
62
+ def test_parse_mixed_format(self):
63
+ """Test parsing mixed format"""
64
+ result = self._parse_page_range("1,3-5,8")
65
+ assert result == [1, 3, 4, 5, 8]
66
+
67
+ def test_parse_empty_string(self):
68
+ """Test parsing empty string"""
69
+ result = self._parse_page_range("")
70
+ assert result == []
71
+
72
+ def test_parse_none(self):
73
+ """Test parsing None"""
74
+ result = self._parse_page_range(None)
75
+ assert result == []
76
+
77
+ @staticmethod
78
+ def _parse_page_range(page_range_str):
79
+ """Helper method to parse page range (implementation from compress command)"""
80
+ pages = set()
81
+ if not page_range_str:
82
+ return []
83
+
84
+ for part in page_range_str.split(","):
85
+ part = part.strip()
86
+ if "-" in part:
87
+ start, end = map(int, part.split("-"))
88
+ pages.update(range(start, end + 1))
89
+ else:
90
+ pages.add(int(part))
91
+
92
+ return sorted(list(pages))
93
+
94
+
95
+ class TestCompressionSettings:
96
+ """Test compression settings for different levels"""
97
+
98
+ def test_light_compression_settings(self):
99
+ """Test light compression level settings"""
100
+ settings = self._get_compression_settings("light")
101
+ assert settings["color_quality"] == 90
102
+ assert settings["gray_quality"] == 85
103
+
104
+ def test_medium_compression_settings(self):
105
+ """Test medium compression level settings"""
106
+ settings = self._get_compression_settings("medium")
107
+ assert settings["color_quality"] == 80
108
+ assert settings["gray_quality"] == 70
109
+
110
+ def test_aggressive_compression_settings(self):
111
+ """Test aggressive compression level settings"""
112
+ settings = self._get_compression_settings("aggressive")
113
+ assert settings["color_quality"] == 65
114
+ assert settings["gray_quality"] == 45
115
+
116
+ def test_ultra_compression_settings(self):
117
+ """Test ultra compression level settings"""
118
+ settings = self._get_compression_settings("ultra")
119
+ assert settings["color_quality"] == 55
120
+ assert settings["gray_quality"] == 35
121
+
122
+ def test_smart_compression_settings(self):
123
+ """Test smart compression level settings (default)"""
124
+ settings = self._get_compression_settings("smart")
125
+ assert settings["color_quality"] == 85
126
+ assert settings["gray_quality"] == 65
127
+
128
+ def test_invalid_level_defaults_to_smart(self):
129
+ """Test invalid compression level defaults to smart"""
130
+ settings = self._get_compression_settings("invalid")
131
+ assert settings == self._get_compression_settings("smart")
132
+
133
+ @staticmethod
134
+ def _get_compression_settings(level):
135
+ """Helper method to get compression settings (implementation from compress command)"""
136
+ settings = {
137
+ "light": {
138
+ "color_quality": 90,
139
+ "gray_quality": 85,
140
+ "description": "Light compression, high quality",
141
+ },
142
+ "medium": {
143
+ "color_quality": 80,
144
+ "gray_quality": 70,
145
+ "description": "Balanced compression and quality",
146
+ },
147
+ "aggressive": {
148
+ "color_quality": 65,
149
+ "gray_quality": 45,
150
+ "description": "Maximum compression, lower quality",
151
+ },
152
+ "ultra": {
153
+ "color_quality": 55,
154
+ "gray_quality": 35,
155
+ "description": "Ultra compression for minimum file size (may reduce legibility)",
156
+ },
157
+ "smart": {
158
+ "color_quality": 85,
159
+ "gray_quality": 65,
160
+ "description": "Smart per-page optimization",
161
+ },
162
+ }
163
+ return settings.get(level, settings["smart"])
164
+
165
+
166
+ class TestPDFCompression:
167
+ """Test PDF compression functionality"""
168
+
169
+ def test_compress_without_pymupdf(self):
170
+ """Test compression fails gracefully without PyMuPDF"""
171
+ # Test that appropriate error message is returned
172
+ # when PyMuPDF is not available
173
+ # This is tested through the actual workflow command
174
+ pass
175
+
176
+ def test_compress_with_color_pages(self):
177
+ """Test compression preserves specified color pages"""
178
+ # Test that color pages are identified correctly
179
+ color_pages = [3, 4]
180
+ assert 3 in color_pages
181
+ assert 4 in color_pages
182
+ assert 5 not in color_pages
183
+
184
+ def test_compress_dpi_scaling(self):
185
+ """Test DPI scaling calculation"""
186
+ dpi = 150
187
+ scaling_factor = dpi / 72 # 72 is default DPI
188
+ assert scaling_factor == pytest.approx(2.083, rel=0.01)
189
+
190
+ def test_compression_quality_for_color_page(self):
191
+ """Test JPEG quality for color pages"""
192
+ settings = self._get_compression_settings("smart")
193
+ color_quality = settings["color_quality"]
194
+ assert color_quality == 85
195
+
196
+ def test_compression_quality_for_gray_page(self):
197
+ """Test JPEG quality for grayscale pages"""
198
+ settings = self._get_compression_settings("smart")
199
+ gray_quality = settings["gray_quality"]
200
+ assert gray_quality == 65
201
+
202
+ @staticmethod
203
+ def _get_compression_settings(level):
204
+ """Helper method (same as TestCompressionSettings)"""
205
+ settings = {
206
+ "smart": {
207
+ "color_quality": 85,
208
+ "gray_quality": 65,
209
+ "description": "Smart per-page optimization",
210
+ }
211
+ }
212
+ return settings.get(level, settings["smart"])
213
+
214
+
215
+ class TestCompressionResults:
216
+ """Test compression result metrics"""
217
+
218
+ def test_size_reduction_calculation(self):
219
+ """Test size reduction percentage calculation"""
220
+ original_size = 10_000_000 # 10 MB
221
+ compressed_size = 1_000_000 # 1 MB
222
+ reduction = ((original_size - compressed_size) / original_size) * 100
223
+ assert reduction == 90.0
224
+
225
+ def test_mb_conversion(self):
226
+ """Test bytes to MB conversion"""
227
+ size_bytes = 1_048_576 # 1 MB in bytes
228
+ size_mb = size_bytes / (1024 * 1024)
229
+ assert size_mb == 1.0
230
+
231
+ def test_savings_calculation(self):
232
+ """Test space savings calculation"""
233
+ original_mb = 10.73
234
+ compressed_mb = 0.81
235
+ savings = original_mb - compressed_mb
236
+ assert savings == pytest.approx(9.92, rel=0.01)
237
+
238
+
239
+ @pytest.mark.integration
240
+ class TestPDFCompressionIntegration:
241
+ """Integration tests for PDF compression (requires PyMuPDF)"""
242
+
243
+ def test_compress_command_available(self):
244
+ """Test that compress command is available in PDF workflow"""
245
+ # This would test the actual CLI command
246
+ pass
247
+
248
+ def test_compress_with_real_pdf(self, tmp_path):
249
+ """Test compression with a real PDF file"""
250
+ # This would require a test PDF file
251
+ pass
252
+
253
+ def test_selective_color_preservation(self, tmp_path):
254
+ """Test that specified pages remain in color"""
255
+ # This would verify color preservation in output
256
+ pass
257
+
258
+ def test_target_size_iteration(self, tmp_path):
259
+ """Test that target size triggers aggressive compression"""
260
+ # This would test the retry logic
261
+ pass
262
+
263
+
264
+ if __name__ == "__main__":
265
+ pytest.main([__file__, "-v"])
File without changes
File without changes
File without changes