mcli-framework 7.12.2__py3-none-any.whl → 7.12.4__py3-none-any.whl

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 (216) hide show
  1. mcli/app/__init__.py +0 -2
  2. mcli/app/commands_cmd.py +30 -26
  3. mcli/app/completion_helpers.py +5 -5
  4. mcli/app/init_cmd.py +10 -10
  5. mcli/app/lock_cmd.py +29 -24
  6. mcli/app/main.py +2 -8
  7. mcli/app/model/model.py +5 -10
  8. mcli/app/store_cmd.py +8 -8
  9. mcli/app/video/__init__.py +0 -2
  10. mcli/app/video/video.py +1 -14
  11. mcli/chat/chat.py +90 -108
  12. mcli/chat/command_rag.py +0 -4
  13. mcli/chat/enhanced_chat.py +32 -41
  14. mcli/chat/system_controller.py +37 -37
  15. mcli/chat/system_integration.py +4 -5
  16. mcli/cli.py +2 -3
  17. mcli/lib/api/api.py +4 -9
  18. mcli/lib/api/daemon_client.py +19 -20
  19. mcli/lib/api/daemon_client_local.py +1 -3
  20. mcli/lib/api/daemon_decorator.py +6 -6
  21. mcli/lib/api/mcli_decorators.py +4 -8
  22. mcli/lib/auth/__init__.py +0 -1
  23. mcli/lib/auth/auth.py +4 -5
  24. mcli/lib/auth/mcli_manager.py +7 -12
  25. mcli/lib/auth/token_util.py +5 -5
  26. mcli/lib/config/__init__.py +29 -1
  27. mcli/lib/config/config.py +0 -1
  28. mcli/lib/custom_commands.py +1 -1
  29. mcli/lib/discovery/command_discovery.py +15 -15
  30. mcli/lib/erd/erd.py +7 -7
  31. mcli/lib/files/files.py +1 -1
  32. mcli/lib/fs/__init__.py +31 -1
  33. mcli/lib/fs/fs.py +12 -13
  34. mcli/lib/lib.py +0 -1
  35. mcli/lib/logger/logger.py +7 -10
  36. mcli/lib/performance/optimizer.py +25 -27
  37. mcli/lib/performance/rust_bridge.py +22 -27
  38. mcli/lib/performance/uvloop_config.py +0 -1
  39. mcli/lib/pickles/__init__.py +0 -1
  40. mcli/lib/pickles/pickles.py +0 -2
  41. mcli/lib/secrets/commands.py +0 -2
  42. mcli/lib/secrets/manager.py +0 -1
  43. mcli/lib/secrets/repl.py +2 -3
  44. mcli/lib/secrets/store.py +1 -2
  45. mcli/lib/services/data_pipeline.py +34 -34
  46. mcli/lib/services/lsh_client.py +38 -40
  47. mcli/lib/shell/shell.py +2 -2
  48. mcli/lib/toml/__init__.py +0 -1
  49. mcli/lib/ui/styling.py +0 -1
  50. mcli/lib/ui/visual_effects.py +33 -41
  51. mcli/lib/watcher/watcher.py +0 -1
  52. mcli/ml/__init__.py +1 -1
  53. mcli/ml/api/__init__.py +1 -1
  54. mcli/ml/api/app.py +8 -9
  55. mcli/ml/api/middleware.py +10 -10
  56. mcli/ml/api/routers/__init__.py +1 -1
  57. mcli/ml/api/routers/admin_router.py +3 -3
  58. mcli/ml/api/routers/auth_router.py +17 -18
  59. mcli/ml/api/routers/backtest_router.py +2 -2
  60. mcli/ml/api/routers/data_router.py +2 -2
  61. mcli/ml/api/routers/model_router.py +14 -15
  62. mcli/ml/api/routers/monitoring_router.py +2 -2
  63. mcli/ml/api/routers/portfolio_router.py +2 -2
  64. mcli/ml/api/routers/prediction_router.py +10 -9
  65. mcli/ml/api/routers/trade_router.py +2 -2
  66. mcli/ml/api/routers/websocket_router.py +6 -7
  67. mcli/ml/api/schemas.py +2 -2
  68. mcli/ml/auth/__init__.py +1 -1
  69. mcli/ml/auth/auth_manager.py +22 -23
  70. mcli/ml/auth/models.py +17 -17
  71. mcli/ml/auth/permissions.py +17 -17
  72. mcli/ml/backtesting/__init__.py +1 -1
  73. mcli/ml/backtesting/backtest_engine.py +31 -35
  74. mcli/ml/backtesting/performance_metrics.py +12 -14
  75. mcli/ml/backtesting/run.py +1 -2
  76. mcli/ml/cache.py +35 -36
  77. mcli/ml/cli/__init__.py +1 -1
  78. mcli/ml/cli/main.py +21 -24
  79. mcli/ml/config/__init__.py +1 -1
  80. mcli/ml/config/settings.py +28 -29
  81. mcli/ml/configs/__init__.py +1 -1
  82. mcli/ml/configs/dvc_config.py +14 -15
  83. mcli/ml/configs/mlflow_config.py +12 -13
  84. mcli/ml/configs/mlops_manager.py +19 -21
  85. mcli/ml/dashboard/__init__.py +4 -4
  86. mcli/ml/dashboard/app.py +20 -30
  87. mcli/ml/dashboard/app_supabase.py +16 -19
  88. mcli/ml/dashboard/app_training.py +11 -14
  89. mcli/ml/dashboard/cli.py +2 -2
  90. mcli/ml/dashboard/common.py +2 -3
  91. mcli/ml/dashboard/components/__init__.py +1 -1
  92. mcli/ml/dashboard/components/charts.py +13 -11
  93. mcli/ml/dashboard/components/metrics.py +7 -7
  94. mcli/ml/dashboard/components/tables.py +12 -9
  95. mcli/ml/dashboard/overview.py +2 -2
  96. mcli/ml/dashboard/pages/__init__.py +1 -1
  97. mcli/ml/dashboard/pages/cicd.py +15 -18
  98. mcli/ml/dashboard/pages/debug_dependencies.py +7 -7
  99. mcli/ml/dashboard/pages/monte_carlo_predictions.py +11 -18
  100. mcli/ml/dashboard/pages/predictions_enhanced.py +24 -32
  101. mcli/ml/dashboard/pages/scrapers_and_logs.py +22 -24
  102. mcli/ml/dashboard/pages/test_portfolio.py +3 -6
  103. mcli/ml/dashboard/pages/trading.py +16 -18
  104. mcli/ml/dashboard/pages/workflows.py +20 -30
  105. mcli/ml/dashboard/utils.py +9 -9
  106. mcli/ml/dashboard/warning_suppression.py +3 -3
  107. mcli/ml/data_ingestion/__init__.py +1 -1
  108. mcli/ml/data_ingestion/api_connectors.py +41 -46
  109. mcli/ml/data_ingestion/data_pipeline.py +36 -46
  110. mcli/ml/data_ingestion/stream_processor.py +43 -46
  111. mcli/ml/database/__init__.py +1 -1
  112. mcli/ml/database/migrations/env.py +2 -2
  113. mcli/ml/database/models.py +22 -24
  114. mcli/ml/database/session.py +14 -14
  115. mcli/ml/experimentation/__init__.py +1 -1
  116. mcli/ml/experimentation/ab_testing.py +45 -46
  117. mcli/ml/features/__init__.py +1 -1
  118. mcli/ml/features/ensemble_features.py +22 -27
  119. mcli/ml/features/recommendation_engine.py +30 -30
  120. mcli/ml/features/stock_features.py +29 -32
  121. mcli/ml/features/test_feature_engineering.py +10 -11
  122. mcli/ml/logging.py +4 -4
  123. mcli/ml/mlops/__init__.py +1 -1
  124. mcli/ml/mlops/data_versioning.py +29 -30
  125. mcli/ml/mlops/experiment_tracker.py +24 -24
  126. mcli/ml/mlops/model_serving.py +31 -34
  127. mcli/ml/mlops/pipeline_orchestrator.py +27 -35
  128. mcli/ml/models/__init__.py +5 -6
  129. mcli/ml/models/base_models.py +23 -23
  130. mcli/ml/models/ensemble_models.py +31 -31
  131. mcli/ml/models/recommendation_models.py +18 -19
  132. mcli/ml/models/test_models.py +14 -16
  133. mcli/ml/monitoring/__init__.py +1 -1
  134. mcli/ml/monitoring/drift_detection.py +32 -36
  135. mcli/ml/monitoring/metrics.py +2 -2
  136. mcli/ml/optimization/__init__.py +1 -1
  137. mcli/ml/optimization/optimize.py +1 -2
  138. mcli/ml/optimization/portfolio_optimizer.py +30 -32
  139. mcli/ml/predictions/__init__.py +1 -1
  140. mcli/ml/preprocessing/__init__.py +1 -1
  141. mcli/ml/preprocessing/data_cleaners.py +22 -23
  142. mcli/ml/preprocessing/feature_extractors.py +23 -26
  143. mcli/ml/preprocessing/ml_pipeline.py +23 -23
  144. mcli/ml/preprocessing/test_preprocessing.py +7 -8
  145. mcli/ml/scripts/populate_sample_data.py +0 -4
  146. mcli/ml/serving/serve.py +1 -2
  147. mcli/ml/tasks.py +17 -17
  148. mcli/ml/tests/test_integration.py +29 -30
  149. mcli/ml/tests/test_training_dashboard.py +21 -21
  150. mcli/ml/trading/__init__.py +1 -1
  151. mcli/ml/trading/migrations.py +5 -5
  152. mcli/ml/trading/models.py +21 -23
  153. mcli/ml/trading/paper_trading.py +16 -13
  154. mcli/ml/trading/risk_management.py +17 -18
  155. mcli/ml/trading/trading_service.py +25 -28
  156. mcli/ml/training/__init__.py +1 -1
  157. mcli/ml/training/train.py +0 -1
  158. mcli/public/oi/oi.py +1 -2
  159. mcli/self/completion_cmd.py +6 -10
  160. mcli/self/logs_cmd.py +19 -24
  161. mcli/self/migrate_cmd.py +22 -20
  162. mcli/self/redis_cmd.py +10 -11
  163. mcli/self/self_cmd.py +10 -18
  164. mcli/self/store_cmd.py +10 -12
  165. mcli/self/visual_cmd.py +9 -14
  166. mcli/self/zsh_cmd.py +2 -4
  167. mcli/workflow/daemon/async_command_database.py +23 -24
  168. mcli/workflow/daemon/async_process_manager.py +27 -29
  169. mcli/workflow/daemon/client.py +27 -33
  170. mcli/workflow/daemon/daemon.py +32 -36
  171. mcli/workflow/daemon/enhanced_daemon.py +24 -33
  172. mcli/workflow/daemon/process_cli.py +11 -12
  173. mcli/workflow/daemon/process_manager.py +23 -26
  174. mcli/workflow/daemon/test_daemon.py +4 -5
  175. mcli/workflow/dashboard/dashboard_cmd.py +0 -1
  176. mcli/workflow/doc_convert.py +15 -17
  177. mcli/workflow/gcloud/__init__.py +0 -1
  178. mcli/workflow/gcloud/gcloud.py +11 -8
  179. mcli/workflow/git_commit/ai_service.py +14 -15
  180. mcli/workflow/lsh_integration.py +9 -11
  181. mcli/workflow/model_service/client.py +26 -31
  182. mcli/workflow/model_service/download_and_run_efficient_models.py +10 -14
  183. mcli/workflow/model_service/lightweight_embedder.py +25 -35
  184. mcli/workflow/model_service/lightweight_model_server.py +26 -32
  185. mcli/workflow/model_service/lightweight_test.py +7 -10
  186. mcli/workflow/model_service/model_service.py +80 -91
  187. mcli/workflow/model_service/ollama_efficient_runner.py +14 -18
  188. mcli/workflow/model_service/openai_adapter.py +23 -23
  189. mcli/workflow/model_service/pdf_processor.py +21 -26
  190. mcli/workflow/model_service/test_efficient_runner.py +12 -16
  191. mcli/workflow/model_service/test_example.py +11 -13
  192. mcli/workflow/model_service/test_integration.py +3 -5
  193. mcli/workflow/model_service/test_new_features.py +7 -8
  194. mcli/workflow/notebook/converter.py +1 -1
  195. mcli/workflow/notebook/notebook_cmd.py +5 -6
  196. mcli/workflow/notebook/schema.py +0 -1
  197. mcli/workflow/notebook/validator.py +7 -3
  198. mcli/workflow/openai/openai.py +1 -2
  199. mcli/workflow/registry/registry.py +4 -1
  200. mcli/workflow/repo/repo.py +6 -7
  201. mcli/workflow/scheduler/cron_parser.py +16 -19
  202. mcli/workflow/scheduler/job.py +10 -10
  203. mcli/workflow/scheduler/monitor.py +15 -15
  204. mcli/workflow/scheduler/persistence.py +17 -18
  205. mcli/workflow/scheduler/scheduler.py +37 -38
  206. mcli/workflow/secrets/__init__.py +1 -1
  207. mcli/workflow/sync/test_cmd.py +0 -1
  208. mcli/workflow/wakatime/__init__.py +5 -9
  209. mcli/workflow/wakatime/wakatime.py +1 -2
  210. {mcli_framework-7.12.2.dist-info → mcli_framework-7.12.4.dist-info}/METADATA +1 -1
  211. mcli_framework-7.12.4.dist-info/RECORD +279 -0
  212. mcli_framework-7.12.2.dist-info/RECORD +0 -279
  213. {mcli_framework-7.12.2.dist-info → mcli_framework-7.12.4.dist-info}/WHEEL +0 -0
  214. {mcli_framework-7.12.2.dist-info → mcli_framework-7.12.4.dist-info}/entry_points.txt +0 -0
  215. {mcli_framework-7.12.2.dist-info → mcli_framework-7.12.4.dist-info}/licenses/LICENSE +0 -0
  216. {mcli_framework-7.12.2.dist-info → mcli_framework-7.12.4.dist-info}/top_level.txt +0 -0
@@ -7,10 +7,10 @@ import sys
7
7
  import tempfile
8
8
  import time
9
9
  import uuid
10
- from dataclasses import asdict, dataclass
10
+ from dataclasses import dataclass
11
11
  from datetime import datetime
12
12
  from pathlib import Path
13
- from typing import Any, Dict, List, Optional, Union
13
+ from typing import Any, Dict, List, Optional
14
14
 
15
15
  import click
16
16
  import psutil
@@ -44,12 +44,11 @@ class CommandDatabase:
44
44
 
45
45
  def __init__(self, db_path: Optional[str] = None):
46
46
  logger.debug("CommandDatabase stub initialized - commands now managed via JSON files")
47
- pass
48
47
 
49
48
 
50
49
  @dataclass
51
50
  class Command:
52
- """Represents a stored command"""
51
+ """Represents a stored command."""
53
52
 
54
53
  id: str
55
54
  name: str
@@ -155,7 +154,7 @@ def start_command_file_watcher(db, watch_dir: str = None):
155
154
  self._update_embeddings()
156
155
 
157
156
  def init_database(self):
158
- """Initialize SQLite database"""
157
+ """Initialize SQLite database."""
159
158
  conn = sqlite3.connect(self.db_path)
160
159
  cursor = conn.cursor()
161
160
 
@@ -213,7 +212,7 @@ def start_command_file_watcher(db, watch_dir: str = None):
213
212
  conn.close()
214
213
 
215
214
  def _update_embeddings(self):
216
- """Update TF-IDF embeddings for similarity search"""
215
+ """Update TF-IDF embeddings for similarity search."""
217
216
  commands = self.get_all_commands()
218
217
  if not commands:
219
218
  return
@@ -229,7 +228,7 @@ def start_command_file_watcher(db, watch_dir: str = None):
229
228
  self.vectorizer.fit(texts)
230
229
 
231
230
  def add_command(self, command: Command) -> str:
232
- """Add a new command to the database"""
231
+ """Add a new command to the database."""
233
232
  conn = sqlite3.connect(self.db_path)
234
233
  cursor = conn.cursor()
235
234
 
@@ -269,7 +268,7 @@ def start_command_file_watcher(db, watch_dir: str = None):
269
268
  conn.close()
270
269
 
271
270
  def get_command(self, command_id: str) -> Optional[Command]:
272
- """Get a command by ID"""
271
+ """Get a command by ID."""
273
272
  conn = sqlite3.connect(self.db_path)
274
273
  cursor = conn.cursor()
275
274
 
@@ -292,7 +291,7 @@ def start_command_file_watcher(db, watch_dir: str = None):
292
291
  conn.close()
293
292
 
294
293
  def get_all_commands(self, include_inactive: bool = False) -> List[Command]:
295
- """Get all commands, optionally including inactive ones"""
294
+ """Get all commands, optionally including inactive ones."""
296
295
  conn = sqlite3.connect(self.db_path)
297
296
  cursor = conn.cursor()
298
297
  try:
@@ -319,7 +318,7 @@ def start_command_file_watcher(db, watch_dir: str = None):
319
318
  conn.close()
320
319
 
321
320
  def search_commands(self, query: str, limit: int = 10) -> List[Command]:
322
- """Search commands by name, description, or tags"""
321
+ """Search commands by name, description, or tags."""
323
322
  conn = sqlite3.connect(self.db_path)
324
323
  cursor = conn.cursor()
325
324
 
@@ -345,7 +344,7 @@ def start_command_file_watcher(db, watch_dir: str = None):
345
344
  conn.close()
346
345
 
347
346
  def find_similar_commands(self, query: str, limit: int = 5) -> List[tuple]:
348
- """Find similar commands using cosine similarity"""
347
+ """Find similar commands using cosine similarity."""
349
348
  commands = self.get_all_commands()
350
349
  if not commands:
351
350
  return []
@@ -383,7 +382,7 @@ def start_command_file_watcher(db, watch_dir: str = None):
383
382
  return []
384
383
 
385
384
  def update_command(self, command: Command) -> bool:
386
- """Update an existing command"""
385
+ """Update an existing command."""
387
386
  conn = sqlite3.connect(self.db_path)
388
387
  cursor = conn.cursor()
389
388
 
@@ -420,7 +419,7 @@ def start_command_file_watcher(db, watch_dir: str = None):
420
419
  conn.close()
421
420
 
422
421
  def delete_command(self, command_id: str) -> bool:
423
- """Delete a command (soft delete)"""
422
+ """Delete a command (soft delete)."""
424
423
  conn = sqlite3.connect(self.db_path)
425
424
  cursor = conn.cursor()
426
425
 
@@ -451,7 +450,7 @@ def start_command_file_watcher(db, watch_dir: str = None):
451
450
  error: str = None,
452
451
  execution_time_ms: int = None,
453
452
  ):
454
- """Record command execution"""
453
+ """Record command execution."""
455
454
  conn = sqlite3.connect(self.db_path)
456
455
  cursor = conn.cursor()
457
456
 
@@ -495,7 +494,7 @@ def start_command_file_watcher(db, watch_dir: str = None):
495
494
  conn.close()
496
495
 
497
496
  def _row_to_command(self, row) -> Command:
498
- """Convert database row to Command object"""
497
+ """Convert database row to Command object."""
499
498
  return Command(
500
499
  id=row[0],
501
500
  name=row[1],
@@ -513,7 +512,7 @@ def start_command_file_watcher(db, watch_dir: str = None):
513
512
 
514
513
 
515
514
  class CommandExecutor:
516
- """Handles safe execution of commands in different languages"""
515
+ """Handles safe execution of commands in different languages."""
517
516
 
518
517
  def __init__(self, temp_dir: Optional[str] = None):
519
518
  self.temp_dir = Path(temp_dir) if temp_dir else Path(tempfile.gettempdir()) / "mcli_daemon"
@@ -528,7 +527,7 @@ class CommandExecutor:
528
527
  }
529
528
 
530
529
  def execute_command(self, command: Command, args: List[str] = None) -> Dict[str, Any]:
531
- """Execute a command safely"""
530
+ """Execute a command safely."""
532
531
  start_time = time.time()
533
532
 
534
533
  try:
@@ -561,7 +560,7 @@ class CommandExecutor:
561
560
  }
562
561
 
563
562
  def _execute_python(self, command: Command, args: List[str]) -> Dict[str, str]:
564
- """Execute Python code safely"""
563
+ """Execute Python code safely."""
565
564
  # Create temporary file
566
565
  script_file = self.temp_dir / f"{command.id}_{int(time.time())}.py"
567
566
 
@@ -587,7 +586,7 @@ class CommandExecutor:
587
586
  script_file.unlink()
588
587
 
589
588
  def _execute_node(self, command: Command, args: List[str]) -> Dict[str, str]:
590
- """Execute Node.js code safely"""
589
+ """Execute Node.js code safely."""
591
590
  script_file = self.temp_dir / f"{command.id}_{int(time.time())}.js"
592
591
 
593
592
  try:
@@ -609,7 +608,7 @@ class CommandExecutor:
609
608
  script_file.unlink()
610
609
 
611
610
  def _execute_lua(self, command: Command, args: List[str]) -> Dict[str, str]:
612
- """Execute Lua code safely"""
611
+ """Execute Lua code safely."""
613
612
  script_file = self.temp_dir / f"{command.id}_{int(time.time())}.lua"
614
613
 
615
614
  try:
@@ -631,7 +630,7 @@ class CommandExecutor:
631
630
  script_file.unlink()
632
631
 
633
632
  def _execute_shell(self, command: Command, args: List[str]) -> Dict[str, str]:
634
- """Execute shell commands safely"""
633
+ """Execute shell commands safely."""
635
634
  script_file = self.temp_dir / f"{command.id}_{int(time.time())}.sh"
636
635
 
637
636
  try:
@@ -658,7 +657,7 @@ class CommandExecutor:
658
657
 
659
658
 
660
659
  class DaemonService:
661
- """Background daemon service for command management"""
660
+ """Background daemon service for command management."""
662
661
 
663
662
  def __init__(self, config_path: Optional[str] = None):
664
663
  # Load configuration from TOML
@@ -696,7 +695,7 @@ class DaemonService:
696
695
  self.pid_file.parent.mkdir(parents=True, exist_ok=True)
697
696
 
698
697
  def start(self):
699
- """Start the daemon service"""
698
+ """Start the daemon service."""
700
699
  if self.running:
701
700
  logger.info("Daemon is already running")
702
701
  return
@@ -734,7 +733,7 @@ class DaemonService:
734
733
  self.stop()
735
734
 
736
735
  def stop(self):
737
- """Stop the daemon service"""
736
+ """Stop the daemon service."""
738
737
  if not self.running:
739
738
  return
740
739
 
@@ -747,13 +746,13 @@ class DaemonService:
747
746
  logger.info("Daemon stopped")
748
747
 
749
748
  def _signal_handler(self, signum, frame):
750
- """Handle shutdown signals"""
749
+ """Handle shutdown signals."""
751
750
  logger.info(f"Received signal {signum}, shutting down...")
752
751
  self.stop()
753
752
  sys.exit(0)
754
753
 
755
754
  def _main_loop(self):
756
- """Main daemon loop"""
755
+ """Main daemon loop."""
757
756
  logger.info("Daemon main loop started")
758
757
 
759
758
  while self.running:
@@ -768,7 +767,7 @@ class DaemonService:
768
767
  time.sleep(5)
769
768
 
770
769
  def status(self) -> Dict[str, Any]:
771
- """Get daemon status"""
770
+ """Get daemon status."""
772
771
  is_running = False
773
772
  pid = None
774
773
 
@@ -791,21 +790,20 @@ class DaemonService:
791
790
  # CLI Commands
792
791
  @click.group(name="daemon")
793
792
  def daemon():
794
- """Daemon service for command management"""
795
- pass
793
+ """Daemon service for command management."""
796
794
 
797
795
 
798
796
  @daemon.command()
799
797
  @click.option("--config", help="Path to configuration file")
800
798
  def start(config: Optional[str]):
801
- """Start the daemon service"""
799
+ """Start the daemon service."""
802
800
  service = DaemonService(config)
803
801
  service.start()
804
802
 
805
803
 
806
804
  @daemon.command()
807
805
  def stop():
808
- """Stop the daemon service"""
806
+ """Stop the daemon service."""
809
807
  pid_file = Path.home() / ".local" / "mcli" / "daemon" / "daemon.pid"
810
808
 
811
809
  if not pid_file.exists():
@@ -833,7 +831,7 @@ def stop():
833
831
 
834
832
  @daemon.command()
835
833
  def status():
836
- """Show daemon status"""
834
+ """Show daemon status."""
837
835
  service = DaemonService()
838
836
  status_info = service.status()
839
837
  if status_info["running"]:
@@ -849,8 +847,7 @@ def status():
849
847
  @click.option("--json", "as_json", is_flag=True, help="Output as JSON")
850
848
  @click.option("--all", "show_all", is_flag=True, help="Show all commands, including inactive")
851
849
  def list_commands(as_json, show_all):
852
- """List all available commands (optionally including inactive)"""
853
- import sys
850
+ """List all available commands (optionally including inactive)."""
854
851
 
855
852
  service = DaemonService()
856
853
  commands = service.db.get_all_commands(include_inactive=show_all)
@@ -887,8 +884,7 @@ def list_commands(as_json, show_all):
887
884
  @click.argument("args", nargs=-1)
888
885
  @click.option("--json", "as_json", is_flag=True, help="Output as JSON")
889
886
  def execute_command(command_name, args, as_json):
890
- """Execute a command by name with optional arguments"""
891
- import sys
887
+ """Execute a command by name with optional arguments."""
892
888
 
893
889
  service = DaemonService()
894
890
  # Find command by name
@@ -4,24 +4,15 @@ Enhanced async daemon with Rust extensions and performance optimizations
4
4
 
5
5
  import asyncio
6
6
  import json
7
- import os
8
7
  import signal
9
8
  import uuid
10
9
  from datetime import datetime
11
10
  from pathlib import Path
12
11
  from typing import Any, Dict, List, Optional
13
12
 
14
- import aiosqlite
15
- import redis.asyncio as redis
16
-
17
13
  from mcli.lib.logger.logger import get_logger
18
- from mcli.lib.performance.rust_bridge import (
19
- get_command_matcher,
20
- get_file_watcher,
21
- get_process_manager,
22
- get_tfidf_vectorizer,
23
- )
24
- from mcli.lib.search.cached_vectorizer import CachedTfIdfVectorizer, SmartVectorizerManager
14
+ from mcli.lib.performance.rust_bridge import get_command_matcher, get_file_watcher
15
+ from mcli.lib.search.cached_vectorizer import SmartVectorizerManager
25
16
  from mcli.workflow.daemon.async_command_database import (
26
17
  AsyncCommandDatabase,
27
18
  Command,
@@ -33,7 +24,7 @@ logger = get_logger(__name__)
33
24
 
34
25
 
35
26
  class EnhancedDaemon:
36
- """High-performance async daemon with Rust extensions"""
27
+ """High-performance async daemon with Rust extensions."""
37
28
 
38
29
  def __init__(
39
30
  self, db_path: Optional[str] = None, redis_url: Optional[str] = None, use_rust: bool = True
@@ -64,7 +55,7 @@ class EnhancedDaemon:
64
55
  }
65
56
 
66
57
  async def initialize(self):
67
- """Initialize all daemon components"""
58
+ """Initialize all daemon components."""
68
59
  logger.info("Initializing Enhanced Daemon...")
69
60
 
70
61
  try:
@@ -96,7 +87,7 @@ class EnhancedDaemon:
96
87
  raise
97
88
 
98
89
  async def _initialize_rust_components(self):
99
- """Initialize Rust-based components"""
90
+ """Initialize Rust-based components."""
100
91
  try:
101
92
  # File watcher
102
93
  self.file_watcher = get_file_watcher(use_rust=self.use_rust)
@@ -138,7 +129,7 @@ class EnhancedDaemon:
138
129
  logger.warning(f"Failed to initialize some Rust components: {e}")
139
130
 
140
131
  def _setup_signal_handlers(self):
141
- """Setup signal handlers for graceful shutdown"""
132
+ """Setup signal handlers for graceful shutdown."""
142
133
 
143
134
  def signal_handler():
144
135
  logger.info("Received shutdown signal")
@@ -152,7 +143,7 @@ class EnhancedDaemon:
152
143
  signal.signal(sig, lambda s, f: asyncio.create_task(self.shutdown()))
153
144
 
154
145
  async def start(self):
155
- """Start the daemon"""
146
+ """Start the daemon."""
156
147
  if self.running:
157
148
  logger.warning("Daemon is already running")
158
149
  return
@@ -182,7 +173,7 @@ class EnhancedDaemon:
182
173
  logger.info("Enhanced Daemon stopped")
183
174
 
184
175
  async def shutdown(self):
185
- """Graceful shutdown"""
176
+ """Graceful shutdown."""
186
177
  if not self.running:
187
178
  return
188
179
 
@@ -208,7 +199,7 @@ class EnhancedDaemon:
208
199
  await self.vectorizer_manager.close_all()
209
200
 
210
201
  async def _file_watcher_loop(self):
211
- """Background loop for processing file system events"""
202
+ """Background loop for processing file system events."""
212
203
  if not self.file_watcher:
213
204
  return
214
205
 
@@ -227,7 +218,7 @@ class EnhancedDaemon:
227
218
  await asyncio.sleep(5) # Back off on error
228
219
 
229
220
  async def _handle_file_event(self, event):
230
- """Handle a file system event"""
221
+ """Handle a file system event."""
231
222
  try:
232
223
  event_type = event.get("event_type") or event.get("type", "unknown")
233
224
  path = event.get("path", "")
@@ -244,7 +235,7 @@ class EnhancedDaemon:
244
235
  logger.error(f"Error handling file event {event}: {e}")
245
236
 
246
237
  async def _reload_command_file(self, file_path: str):
247
- """Reload a command from a JSON file"""
238
+ """Reload a command from a JSON file."""
248
239
  try:
249
240
  with open(file_path, "r") as f:
250
241
  data = json.load(f)
@@ -286,7 +277,7 @@ class EnhancedDaemon:
286
277
  logger.error(f"Failed to reload command file {file_path}: {e}")
287
278
 
288
279
  async def _remove_command_file(self, file_path: str):
289
- """Remove a command when its file is deleted"""
280
+ """Remove a command when its file is deleted."""
290
281
  try:
291
282
  # Extract command ID from filename
292
283
  command_id = Path(file_path).stem
@@ -300,7 +291,7 @@ class EnhancedDaemon:
300
291
  logger.error(f"Failed to remove command file {file_path}: {e}")
301
292
 
302
293
  async def _maintenance_loop(self):
303
- """Background maintenance tasks"""
294
+ """Background maintenance tasks."""
304
295
  while self.running:
305
296
  try:
306
297
  # Clean up finished processes
@@ -320,7 +311,7 @@ class EnhancedDaemon:
320
311
  await asyncio.sleep(60)
321
312
 
322
313
  async def _metrics_loop(self):
323
- """Background metrics collection"""
314
+ """Background metrics collection."""
324
315
  while self.running:
325
316
  try:
326
317
  # Log performance metrics every 10 minutes
@@ -339,7 +330,7 @@ class EnhancedDaemon:
339
330
  await asyncio.sleep(60)
340
331
 
341
332
  async def _update_search_indexes(self):
342
- """Update search indexes for better performance"""
333
+ """Update search indexes for better performance."""
343
334
  try:
344
335
  # Get all commands
345
336
  commands = await self.command_db.get_all_commands()
@@ -366,7 +357,7 @@ class EnhancedDaemon:
366
357
  # Public API methods
367
358
 
368
359
  async def add_command(self, command_data: Dict[str, Any]) -> str:
369
- """Add a new command"""
360
+ """Add a new command."""
370
361
  command = Command(
371
362
  id=command_data.get("id") or str(uuid.uuid4()),
372
363
  name=command_data["name"],
@@ -396,7 +387,7 @@ class EnhancedDaemon:
396
387
  return command_id
397
388
 
398
389
  async def search_commands(self, query: str, limit: int = 10) -> List[Dict[str, Any]]:
399
- """Search for commands"""
390
+ """Search for commands."""
400
391
  self.metrics["search_queries"] += 1
401
392
 
402
393
  # Try Rust command matcher first
@@ -465,7 +456,7 @@ class EnhancedDaemon:
465
456
  async def execute_command(
466
457
  self, command_id: str, context: Optional[Dict[str, Any]] = None
467
458
  ) -> str:
468
- """Execute a command"""
459
+ """Execute a command."""
469
460
  self.metrics["commands_executed"] += 1
470
461
 
471
462
  # Get command
@@ -498,7 +489,7 @@ class EnhancedDaemon:
498
489
  return process_id
499
490
 
500
491
  def _get_command_executor(self, language: str) -> str:
501
- """Get the appropriate executor for a language"""
492
+ """Get the appropriate executor for a language."""
502
493
  executors = {
503
494
  "python": "python",
504
495
  "node": "node",
@@ -509,7 +500,7 @@ class EnhancedDaemon:
509
500
  return executors.get(language, "bash")
510
501
 
511
502
  def _prepare_command_args(self, command: Command) -> List[str]:
512
- """Prepare command arguments based on language"""
503
+ """Prepare command arguments based on language."""
513
504
  if command.language == "python":
514
505
  return ["-c", command.code]
515
506
  elif command.language == "node":
@@ -522,7 +513,7 @@ class EnhancedDaemon:
522
513
  return [command.code]
523
514
 
524
515
  async def get_status(self) -> Dict[str, Any]:
525
- """Get daemon status"""
516
+ """Get daemon status."""
526
517
  return {
527
518
  "running": self.running,
528
519
  "uptime": (
@@ -546,7 +537,7 @@ _daemon_instance: Optional[EnhancedDaemon] = None
546
537
 
547
538
 
548
539
  async def get_daemon() -> EnhancedDaemon:
549
- """Get the global daemon instance"""
540
+ """Get the global daemon instance."""
550
541
  global _daemon_instance
551
542
 
552
543
  if _daemon_instance is None:
@@ -557,13 +548,13 @@ async def get_daemon() -> EnhancedDaemon:
557
548
 
558
549
 
559
550
  async def start_daemon():
560
- """Start the global daemon"""
551
+ """Start the global daemon."""
561
552
  daemon = await get_daemon()
562
553
  await daemon.start()
563
554
 
564
555
 
565
556
  async def stop_daemon():
566
- """Stop the global daemon"""
557
+ """Stop the global daemon."""
567
558
  global _daemon_instance
568
559
 
569
560
  if _daemon_instance:
@@ -14,15 +14,14 @@ API_BASE_URL = "http://localhost:8000"
14
14
 
15
15
  @click.group(name="process")
16
16
  def process_cli():
17
- """Docker-like process management commands"""
18
- pass
17
+ """Docker-like process management commands."""
19
18
 
20
19
 
21
20
  @process_cli.command("ps")
22
21
  @click.option("--all", "-a", is_flag=True, help="Show all processes including exited ones")
23
22
  @click.option("--json", "as_json", is_flag=True, help="Output as JSON")
24
23
  def list_processes(all: bool, as_json: bool):
25
- """List processes (like 'docker ps')"""
24
+ """List processes (like 'docker ps')."""
26
25
  try:
27
26
  params = {"all": "true"} if all else {}
28
27
  response = requests.get(f"{API_BASE_URL}/processes", params=params)
@@ -66,7 +65,7 @@ def list_processes(all: bool, as_json: bool):
66
65
  def run_process(
67
66
  command: str, args: tuple, name: Optional[str], detach: bool, working_dir: Optional[str]
68
67
  ):
69
- """Create and start a process (like 'docker run')"""
68
+ """Create and start a process (like 'docker run')."""
70
69
  try:
71
70
  data = {
72
71
  "name": name or f"proc-{command}",
@@ -98,7 +97,7 @@ def run_process(
98
97
  @click.argument("process_id")
99
98
  @click.option("--lines", "-n", type=int, help="Number of lines to show from end of logs")
100
99
  def show_logs(process_id: str, lines: Optional[int]):
101
- """Show logs for a process (like 'docker logs')"""
100
+ """Show logs for a process (like 'docker logs')."""
102
101
  try:
103
102
  params = {}
104
103
  if lines:
@@ -128,7 +127,7 @@ def show_logs(process_id: str, lines: Optional[int]):
128
127
  @click.argument("process_id")
129
128
  @click.option("--json", "as_json", is_flag=True, help="Output as JSON")
130
129
  def inspect_process(process_id: str, as_json: bool):
131
- """Show detailed information about a process (like 'docker inspect')"""
130
+ """Show detailed information about a process (like 'docker inspect')."""
132
131
  try:
133
132
  response = requests.get(f"{API_BASE_URL}/processes/{process_id}")
134
133
 
@@ -150,7 +149,7 @@ def inspect_process(process_id: str, as_json: bool):
150
149
 
151
150
  if info.get("stats"):
152
151
  stats = info["stats"]
153
- click.echo(f"\nResource Usage:")
152
+ click.echo("\nResource Usage:")
154
153
  click.echo(f" CPU: {stats.get('cpu_percent', 0):.1f}%")
155
154
  click.echo(f" Memory: {stats.get('memory_mb', 0):.1f} MB")
156
155
  click.echo(f" Uptime: {stats.get('uptime_seconds', 0)} seconds")
@@ -168,7 +167,7 @@ def inspect_process(process_id: str, as_json: bool):
168
167
  @click.argument("process_id")
169
168
  @click.option("--timeout", "-t", type=int, default=10, help="Timeout in seconds")
170
169
  def stop_process(process_id: str, timeout: int):
171
- """Stop a process (like 'docker stop')"""
170
+ """Stop a process (like 'docker stop')."""
172
171
  try:
173
172
  data = {"timeout": timeout}
174
173
  response = requests.post(f"{API_BASE_URL}/processes/{process_id}/stop", json=data)
@@ -187,7 +186,7 @@ def stop_process(process_id: str, timeout: int):
187
186
  @process_cli.command("start")
188
187
  @click.argument("process_id")
189
188
  def start_process(process_id: str):
190
- """Start a stopped process (like 'docker start')"""
189
+ """Start a stopped process (like 'docker start')."""
191
190
  try:
192
191
  response = requests.post(f"{API_BASE_URL}/processes/{process_id}/start")
193
192
 
@@ -205,7 +204,7 @@ def start_process(process_id: str):
205
204
  @process_cli.command("kill")
206
205
  @click.argument("process_id")
207
206
  def kill_process(process_id: str):
208
- """Kill a process (like 'docker kill')"""
207
+ """Kill a process (like 'docker kill')."""
209
208
  try:
210
209
  response = requests.post(f"{API_BASE_URL}/processes/{process_id}/kill")
211
210
 
@@ -222,9 +221,9 @@ def kill_process(process_id: str):
222
221
 
223
222
  @process_cli.command("rm")
224
223
  @click.argument("process_id")
225
- @click.option("--force", "-f", is_flag=True, help="Force remove running process")
224
+ @click.option("--force", "-", is_flag=True, help="Force remove running process")
226
225
  def remove_process(process_id: str, force: bool):
227
- """Remove a process (like 'docker rm')"""
226
+ """Remove a process (like 'docker rm')."""
228
227
  try:
229
228
  params = {"force": "true"} if force else {}
230
229
  response = requests.delete(f"{API_BASE_URL}/processes/{process_id}", params=params)