mcli-framework 7.0.0__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 (186) hide show
  1. mcli/app/chat_cmd.py +42 -0
  2. mcli/app/commands_cmd.py +226 -0
  3. mcli/app/completion_cmd.py +216 -0
  4. mcli/app/completion_helpers.py +288 -0
  5. mcli/app/cron_test_cmd.py +697 -0
  6. mcli/app/logs_cmd.py +419 -0
  7. mcli/app/main.py +492 -0
  8. mcli/app/model/model.py +1060 -0
  9. mcli/app/model_cmd.py +227 -0
  10. mcli/app/redis_cmd.py +269 -0
  11. mcli/app/video/video.py +1114 -0
  12. mcli/app/visual_cmd.py +303 -0
  13. mcli/chat/chat.py +2409 -0
  14. mcli/chat/command_rag.py +514 -0
  15. mcli/chat/enhanced_chat.py +652 -0
  16. mcli/chat/system_controller.py +1010 -0
  17. mcli/chat/system_integration.py +1016 -0
  18. mcli/cli.py +25 -0
  19. mcli/config.toml +20 -0
  20. mcli/lib/api/api.py +586 -0
  21. mcli/lib/api/daemon_client.py +203 -0
  22. mcli/lib/api/daemon_client_local.py +44 -0
  23. mcli/lib/api/daemon_decorator.py +217 -0
  24. mcli/lib/api/mcli_decorators.py +1032 -0
  25. mcli/lib/auth/auth.py +85 -0
  26. mcli/lib/auth/aws_manager.py +85 -0
  27. mcli/lib/auth/azure_manager.py +91 -0
  28. mcli/lib/auth/credential_manager.py +192 -0
  29. mcli/lib/auth/gcp_manager.py +93 -0
  30. mcli/lib/auth/key_manager.py +117 -0
  31. mcli/lib/auth/mcli_manager.py +93 -0
  32. mcli/lib/auth/token_manager.py +75 -0
  33. mcli/lib/auth/token_util.py +1011 -0
  34. mcli/lib/config/config.py +47 -0
  35. mcli/lib/discovery/__init__.py +1 -0
  36. mcli/lib/discovery/command_discovery.py +274 -0
  37. mcli/lib/erd/erd.py +1345 -0
  38. mcli/lib/erd/generate_graph.py +453 -0
  39. mcli/lib/files/files.py +76 -0
  40. mcli/lib/fs/fs.py +109 -0
  41. mcli/lib/lib.py +29 -0
  42. mcli/lib/logger/logger.py +611 -0
  43. mcli/lib/performance/optimizer.py +409 -0
  44. mcli/lib/performance/rust_bridge.py +502 -0
  45. mcli/lib/performance/uvloop_config.py +154 -0
  46. mcli/lib/pickles/pickles.py +50 -0
  47. mcli/lib/search/cached_vectorizer.py +479 -0
  48. mcli/lib/services/data_pipeline.py +460 -0
  49. mcli/lib/services/lsh_client.py +441 -0
  50. mcli/lib/services/redis_service.py +387 -0
  51. mcli/lib/shell/shell.py +137 -0
  52. mcli/lib/toml/toml.py +33 -0
  53. mcli/lib/ui/styling.py +47 -0
  54. mcli/lib/ui/visual_effects.py +634 -0
  55. mcli/lib/watcher/watcher.py +185 -0
  56. mcli/ml/api/app.py +215 -0
  57. mcli/ml/api/middleware.py +224 -0
  58. mcli/ml/api/routers/admin_router.py +12 -0
  59. mcli/ml/api/routers/auth_router.py +244 -0
  60. mcli/ml/api/routers/backtest_router.py +12 -0
  61. mcli/ml/api/routers/data_router.py +12 -0
  62. mcli/ml/api/routers/model_router.py +302 -0
  63. mcli/ml/api/routers/monitoring_router.py +12 -0
  64. mcli/ml/api/routers/portfolio_router.py +12 -0
  65. mcli/ml/api/routers/prediction_router.py +267 -0
  66. mcli/ml/api/routers/trade_router.py +12 -0
  67. mcli/ml/api/routers/websocket_router.py +76 -0
  68. mcli/ml/api/schemas.py +64 -0
  69. mcli/ml/auth/auth_manager.py +425 -0
  70. mcli/ml/auth/models.py +154 -0
  71. mcli/ml/auth/permissions.py +302 -0
  72. mcli/ml/backtesting/backtest_engine.py +502 -0
  73. mcli/ml/backtesting/performance_metrics.py +393 -0
  74. mcli/ml/cache.py +400 -0
  75. mcli/ml/cli/main.py +398 -0
  76. mcli/ml/config/settings.py +394 -0
  77. mcli/ml/configs/dvc_config.py +230 -0
  78. mcli/ml/configs/mlflow_config.py +131 -0
  79. mcli/ml/configs/mlops_manager.py +293 -0
  80. mcli/ml/dashboard/app.py +532 -0
  81. mcli/ml/dashboard/app_integrated.py +738 -0
  82. mcli/ml/dashboard/app_supabase.py +560 -0
  83. mcli/ml/dashboard/app_training.py +615 -0
  84. mcli/ml/dashboard/cli.py +51 -0
  85. mcli/ml/data_ingestion/api_connectors.py +501 -0
  86. mcli/ml/data_ingestion/data_pipeline.py +567 -0
  87. mcli/ml/data_ingestion/stream_processor.py +512 -0
  88. mcli/ml/database/migrations/env.py +94 -0
  89. mcli/ml/database/models.py +667 -0
  90. mcli/ml/database/session.py +200 -0
  91. mcli/ml/experimentation/ab_testing.py +845 -0
  92. mcli/ml/features/ensemble_features.py +607 -0
  93. mcli/ml/features/political_features.py +676 -0
  94. mcli/ml/features/recommendation_engine.py +809 -0
  95. mcli/ml/features/stock_features.py +573 -0
  96. mcli/ml/features/test_feature_engineering.py +346 -0
  97. mcli/ml/logging.py +85 -0
  98. mcli/ml/mlops/data_versioning.py +518 -0
  99. mcli/ml/mlops/experiment_tracker.py +377 -0
  100. mcli/ml/mlops/model_serving.py +481 -0
  101. mcli/ml/mlops/pipeline_orchestrator.py +614 -0
  102. mcli/ml/models/base_models.py +324 -0
  103. mcli/ml/models/ensemble_models.py +675 -0
  104. mcli/ml/models/recommendation_models.py +474 -0
  105. mcli/ml/models/test_models.py +487 -0
  106. mcli/ml/monitoring/drift_detection.py +676 -0
  107. mcli/ml/monitoring/metrics.py +45 -0
  108. mcli/ml/optimization/portfolio_optimizer.py +834 -0
  109. mcli/ml/preprocessing/data_cleaners.py +451 -0
  110. mcli/ml/preprocessing/feature_extractors.py +491 -0
  111. mcli/ml/preprocessing/ml_pipeline.py +382 -0
  112. mcli/ml/preprocessing/politician_trading_preprocessor.py +569 -0
  113. mcli/ml/preprocessing/test_preprocessing.py +294 -0
  114. mcli/ml/scripts/populate_sample_data.py +200 -0
  115. mcli/ml/tasks.py +400 -0
  116. mcli/ml/tests/test_integration.py +429 -0
  117. mcli/ml/tests/test_training_dashboard.py +387 -0
  118. mcli/public/oi/oi.py +15 -0
  119. mcli/public/public.py +4 -0
  120. mcli/self/self_cmd.py +1246 -0
  121. mcli/workflow/daemon/api_daemon.py +800 -0
  122. mcli/workflow/daemon/async_command_database.py +681 -0
  123. mcli/workflow/daemon/async_process_manager.py +591 -0
  124. mcli/workflow/daemon/client.py +530 -0
  125. mcli/workflow/daemon/commands.py +1196 -0
  126. mcli/workflow/daemon/daemon.py +905 -0
  127. mcli/workflow/daemon/daemon_api.py +59 -0
  128. mcli/workflow/daemon/enhanced_daemon.py +571 -0
  129. mcli/workflow/daemon/process_cli.py +244 -0
  130. mcli/workflow/daemon/process_manager.py +439 -0
  131. mcli/workflow/daemon/test_daemon.py +275 -0
  132. mcli/workflow/dashboard/dashboard_cmd.py +113 -0
  133. mcli/workflow/docker/docker.py +0 -0
  134. mcli/workflow/file/file.py +100 -0
  135. mcli/workflow/gcloud/config.toml +21 -0
  136. mcli/workflow/gcloud/gcloud.py +58 -0
  137. mcli/workflow/git_commit/ai_service.py +328 -0
  138. mcli/workflow/git_commit/commands.py +430 -0
  139. mcli/workflow/lsh_integration.py +355 -0
  140. mcli/workflow/model_service/client.py +594 -0
  141. mcli/workflow/model_service/download_and_run_efficient_models.py +288 -0
  142. mcli/workflow/model_service/lightweight_embedder.py +397 -0
  143. mcli/workflow/model_service/lightweight_model_server.py +714 -0
  144. mcli/workflow/model_service/lightweight_test.py +241 -0
  145. mcli/workflow/model_service/model_service.py +1955 -0
  146. mcli/workflow/model_service/ollama_efficient_runner.py +425 -0
  147. mcli/workflow/model_service/pdf_processor.py +386 -0
  148. mcli/workflow/model_service/test_efficient_runner.py +234 -0
  149. mcli/workflow/model_service/test_example.py +315 -0
  150. mcli/workflow/model_service/test_integration.py +131 -0
  151. mcli/workflow/model_service/test_new_features.py +149 -0
  152. mcli/workflow/openai/openai.py +99 -0
  153. mcli/workflow/politician_trading/commands.py +1790 -0
  154. mcli/workflow/politician_trading/config.py +134 -0
  155. mcli/workflow/politician_trading/connectivity.py +490 -0
  156. mcli/workflow/politician_trading/data_sources.py +395 -0
  157. mcli/workflow/politician_trading/database.py +410 -0
  158. mcli/workflow/politician_trading/demo.py +248 -0
  159. mcli/workflow/politician_trading/models.py +165 -0
  160. mcli/workflow/politician_trading/monitoring.py +413 -0
  161. mcli/workflow/politician_trading/scrapers.py +966 -0
  162. mcli/workflow/politician_trading/scrapers_california.py +412 -0
  163. mcli/workflow/politician_trading/scrapers_eu.py +377 -0
  164. mcli/workflow/politician_trading/scrapers_uk.py +350 -0
  165. mcli/workflow/politician_trading/scrapers_us_states.py +438 -0
  166. mcli/workflow/politician_trading/supabase_functions.py +354 -0
  167. mcli/workflow/politician_trading/workflow.py +852 -0
  168. mcli/workflow/registry/registry.py +180 -0
  169. mcli/workflow/repo/repo.py +223 -0
  170. mcli/workflow/scheduler/commands.py +493 -0
  171. mcli/workflow/scheduler/cron_parser.py +238 -0
  172. mcli/workflow/scheduler/job.py +182 -0
  173. mcli/workflow/scheduler/monitor.py +139 -0
  174. mcli/workflow/scheduler/persistence.py +324 -0
  175. mcli/workflow/scheduler/scheduler.py +679 -0
  176. mcli/workflow/sync/sync_cmd.py +437 -0
  177. mcli/workflow/sync/test_cmd.py +314 -0
  178. mcli/workflow/videos/videos.py +242 -0
  179. mcli/workflow/wakatime/wakatime.py +11 -0
  180. mcli/workflow/workflow.py +37 -0
  181. mcli_framework-7.0.0.dist-info/METADATA +479 -0
  182. mcli_framework-7.0.0.dist-info/RECORD +186 -0
  183. mcli_framework-7.0.0.dist-info/WHEEL +5 -0
  184. mcli_framework-7.0.0.dist-info/entry_points.txt +7 -0
  185. mcli_framework-7.0.0.dist-info/licenses/LICENSE +21 -0
  186. mcli_framework-7.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,275 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Test script for the MCLI Daemon Service.
4
+
5
+ This script demonstrates the daemon functionality by creating and executing
6
+ example commands in different programming languages.
7
+ """
8
+
9
+ import os
10
+ import subprocess
11
+ import tempfile
12
+ import time
13
+ from pathlib import Path
14
+
15
+
16
+ def create_test_scripts():
17
+ """Create test scripts for different languages"""
18
+ scripts = {}
19
+
20
+ # Python script
21
+ python_script = '''#!/usr/bin/env python3
22
+ import sys
23
+ import json
24
+
25
+ def process_data(input_data):
26
+ """Process input data and return result"""
27
+ try:
28
+ data = json.loads(input_data)
29
+ result = {
30
+ "processed": True,
31
+ "count": len(data),
32
+ "sum": sum(data) if isinstance(data, list) else 0,
33
+ "timestamp": time.time()
34
+ }
35
+ return json.dumps(result)
36
+ except Exception as e:
37
+ return json.dumps({"error": str(e)})
38
+
39
+ if __name__ == "__main__":
40
+ import time
41
+ input_data = sys.argv[1] if len(sys.argv) > 1 else '[1, 2, 3, 4, 5]'
42
+ result = process_data(input_data)
43
+ print(result)
44
+ '''
45
+ scripts["python"] = python_script
46
+
47
+ # Node.js script
48
+ node_script = """#!/usr/bin/env node
49
+ const fs = require('fs');
50
+
51
+ function processFile(filename) {
52
+ try {
53
+ const content = fs.readFileSync(filename, 'utf8');
54
+ const lines = content.split('\\n').filter(line => line.trim());
55
+ const result = {
56
+ filename: filename,
57
+ lineCount: lines.length,
58
+ wordCount: content.split('\\s+').filter(word => word.trim()).length,
59
+ timestamp: new Date().toISOString()
60
+ };
61
+ console.log(JSON.stringify(result, null, 2));
62
+ } catch (error) {
63
+ console.error(JSON.stringify({error: error.message}));
64
+ }
65
+ }
66
+
67
+ const filename = process.argv[2] || __filename;
68
+ processFile(filename);
69
+ """
70
+ scripts["node"] = node_script
71
+
72
+ # Shell script
73
+ shell_script = """#!/bin/bash
74
+
75
+ # Simple system info script
76
+ echo "=== System Information ==="
77
+ echo "Hostname: $(hostname)"
78
+ echo "OS: $(uname -s)"
79
+ echo "Architecture: $(uname -m)"
80
+ echo "Uptime: $(uptime)"
81
+ echo "Memory: $(free -h | grep Mem | awk '{print $2}')"
82
+ echo "Disk Usage: $(df -h / | tail -1 | awk '{print $5}')"
83
+ echo "=== End ==="
84
+ """
85
+ scripts["shell"] = shell_script
86
+
87
+ return scripts
88
+
89
+
90
+ def test_daemon_functionality():
91
+ """Test the daemon functionality"""
92
+ print("🧪 Testing MCLI Daemon Service")
93
+ print("=" * 50)
94
+
95
+ # Create test scripts
96
+ scripts = create_test_scripts()
97
+
98
+ # Create temporary directory for test scripts
99
+ with tempfile.TemporaryDirectory() as temp_dir:
100
+ temp_path = Path(temp_dir)
101
+
102
+ # Write test scripts
103
+ script_files = {}
104
+ for lang, script in scripts.items():
105
+ if lang == "python":
106
+ filename = temp_path / "test_script.py"
107
+ elif lang == "node":
108
+ filename = temp_path / "test_script.js"
109
+ elif lang == "shell":
110
+ filename = temp_path / "test_script.sh"
111
+
112
+ with open(filename, "w") as f:
113
+ f.write(script)
114
+
115
+ # Make shell script executable
116
+ if lang == "shell":
117
+ os.chmod(filename, 0o755)
118
+
119
+ script_files[lang] = filename
120
+
121
+ print("✅ Test scripts created")
122
+
123
+ # Test daemon commands
124
+ try:
125
+ # Test daemon status
126
+ print("\n📊 Testing daemon status...")
127
+ result = subprocess.run(
128
+ ["mcli", "workflow", "daemon", "status"], capture_output=True, text=True
129
+ )
130
+ print(f"Status: {result.stdout.strip()}")
131
+
132
+ # Test adding commands
133
+ print("\n➕ Testing command addition...")
134
+ for lang, script_file in script_files.items():
135
+ print(f"Adding {lang} command...")
136
+ result = subprocess.run(
137
+ [
138
+ "mcli",
139
+ "workflow",
140
+ "daemon",
141
+ "client",
142
+ "add-file",
143
+ f"test-{lang}",
144
+ str(script_file),
145
+ "--description",
146
+ f"Test {lang} script",
147
+ "--language",
148
+ lang,
149
+ "--group",
150
+ "test",
151
+ "--tags",
152
+ f"test,{lang},demo",
153
+ ],
154
+ capture_output=True,
155
+ text=True,
156
+ )
157
+
158
+ if result.returncode == 0:
159
+ print(f"✅ {lang} command added successfully")
160
+ else:
161
+ print(f"❌ Failed to add {lang} command: {result.stderr}")
162
+
163
+ # Test listing commands
164
+ print("\n📋 Testing command listing...")
165
+ result = subprocess.run(
166
+ ["mcli", "workflow", "daemon", "client", "list"], capture_output=True, text=True
167
+ )
168
+ print(result.stdout)
169
+
170
+ # Test searching commands
171
+ print("\n🔍 Testing command search...")
172
+ result = subprocess.run(
173
+ ["mcli", "workflow", "daemon", "client", "search", "test"],
174
+ capture_output=True,
175
+ text=True,
176
+ )
177
+ print(result.stdout)
178
+
179
+ # Test command execution (if we can get command IDs)
180
+ print("\n⚡ Testing command execution...")
181
+ # Note: In a real scenario, you'd get the command ID from the add command output
182
+ # For this test, we'll just show the command structure
183
+ print("Command execution would be tested with:")
184
+ print("mcli workflow daemon client execute <command-id> [args...]")
185
+
186
+ except Exception as e:
187
+ print(f"❌ Error during testing: {e}")
188
+
189
+ print("\n✅ Daemon functionality test completed!")
190
+
191
+
192
+ def show_usage_examples():
193
+ """Show usage examples"""
194
+ print("\n📚 Usage Examples")
195
+ print("=" * 50)
196
+
197
+ examples = [
198
+ {
199
+ "title": "Start the daemon",
200
+ "command": "mcli workflow daemon start",
201
+ "description": "Start the background daemon service",
202
+ },
203
+ {
204
+ "title": "Add a Python command",
205
+ "command": "mcli workflow daemon client add-file my-script script.py --language python --group utils",
206
+ "description": "Add a Python script as a command",
207
+ },
208
+ {
209
+ "title": "Add command interactively",
210
+ "command": "mcli workflow daemon client add-interactive",
211
+ "description": "Interactive command creation with prompts",
212
+ },
213
+ {
214
+ "title": "Search for commands",
215
+ "command": "mcli workflow daemon client search 'data processing'",
216
+ "description": "Search for commands by name, description, or tags",
217
+ },
218
+ {
219
+ "title": "Execute a command",
220
+ "command": "mcli workflow daemon client execute <command-id> arg1 arg2",
221
+ "description": "Execute a stored command with arguments",
222
+ },
223
+ {
224
+ "title": "List all commands",
225
+ "command": "mcli workflow daemon client list",
226
+ "description": "List all stored commands",
227
+ },
228
+ {
229
+ "title": "Show command details",
230
+ "command": "mcli workflow daemon client show <command-id>",
231
+ "description": "Show detailed information about a command",
232
+ },
233
+ ]
234
+
235
+ for i, example in enumerate(examples, 1):
236
+ print(f"\n{i}. {example['title']}")
237
+ print(f" Command: {example['command']}")
238
+ print(f" Description: {example['description']}")
239
+
240
+
241
+ def main():
242
+ """Main test function"""
243
+ print("🚀 MCLI Daemon Service Test Suite")
244
+ print("=" * 60)
245
+
246
+ # Check if mcli is available
247
+ try:
248
+ result = subprocess.run(["mcli", "--version"], capture_output=True, text=True)
249
+ if result.returncode != 0:
250
+ print("❌ MCLI not found or not working properly")
251
+ return
252
+ except FileNotFoundError:
253
+ print("❌ MCLI command not found in PATH")
254
+ return
255
+
256
+ print("✅ MCLI is available")
257
+
258
+ # Show usage examples
259
+ show_usage_examples()
260
+
261
+ # Ask if user wants to run tests
262
+ print("\n" + "=" * 60)
263
+ response = input("Would you like to run the daemon functionality tests? (y/n): ")
264
+
265
+ if response.lower() in ["y", "yes"]:
266
+ test_daemon_functionality()
267
+ else:
268
+ print("Skipping tests. You can run them manually using the examples above.")
269
+
270
+ print("\n🎉 Test suite completed!")
271
+ print("\nFor more information, see: src/mcli/workflow/daemon/README.md")
272
+
273
+
274
+ if __name__ == "__main__":
275
+ main()
@@ -0,0 +1,113 @@
1
+ """ML Dashboard commands for mcli."""
2
+
3
+ import subprocess
4
+ import sys
5
+ from pathlib import Path
6
+
7
+ import click
8
+
9
+ from mcli.lib.logger.logger import get_logger
10
+
11
+ logger = get_logger(__name__)
12
+
13
+
14
+ @click.group(name="dashboard")
15
+ def dashboard():
16
+ """ML monitoring dashboard commands."""
17
+ pass
18
+
19
+
20
+ @dashboard.command()
21
+ @click.option("--port", "-p", default=8501, help="Port to run dashboard on")
22
+ @click.option("--host", "-h", default="localhost", help="Host to bind to")
23
+ @click.option("--debug", is_flag=True, help="Run in debug mode")
24
+ def launch(port, host, debug):
25
+ """Launch the ML monitoring dashboard."""
26
+
27
+ click.echo(f"🚀 Starting ML Dashboard on http://{host}:{port}")
28
+
29
+ # Get the dashboard app path - use Supabase version to avoid joblib issues
30
+ dashboard_path = Path(__file__).parent.parent.parent / "ml" / "dashboard" / "app_supabase.py"
31
+
32
+ if not dashboard_path.exists():
33
+ click.echo("❌ Dashboard app not found!")
34
+ logger.error(f"Dashboard app not found at {dashboard_path}")
35
+ sys.exit(1)
36
+
37
+ # Build streamlit command
38
+ cmd = [
39
+ sys.executable, "-m", "streamlit", "run",
40
+ str(dashboard_path),
41
+ "--server.port", str(port),
42
+ "--server.address", host,
43
+ "--browser.gatherUsageStats", "false"
44
+ ]
45
+
46
+ if debug:
47
+ cmd.extend(["--logger.level", "debug"])
48
+
49
+ click.echo("📊 Dashboard is starting...")
50
+ click.echo("Press Ctrl+C to stop")
51
+
52
+ try:
53
+ subprocess.run(cmd, check=True)
54
+ except KeyboardInterrupt:
55
+ click.echo("\n⏹️ Dashboard stopped")
56
+ except subprocess.CalledProcessError as e:
57
+ click.echo(f"❌ Failed to start dashboard: {e}")
58
+ logger.error(f"Dashboard failed to start: {e}")
59
+ sys.exit(1)
60
+
61
+
62
+ @dashboard.command()
63
+ def info():
64
+ """Show dashboard information and status."""
65
+
66
+ click.echo("📊 ML Dashboard Information")
67
+ click.echo("━" * 40)
68
+
69
+ # Check if dependencies are installed
70
+ try:
71
+ import streamlit
72
+ import plotly
73
+
74
+ click.echo("✅ Dashboard dependencies installed")
75
+ click.echo(f" Streamlit version: {streamlit.__version__}")
76
+ click.echo(f" Plotly version: {plotly.__version__}")
77
+ except ImportError as e:
78
+ click.echo(f"❌ Missing dependencies: {e}")
79
+ click.echo(" Run: uv sync --extra dashboard")
80
+
81
+ # Check database connection
82
+ try:
83
+ from mcli.ml.config import settings
84
+ click.echo(f"\n📁 Database URL: {settings.database.url}")
85
+ click.echo(f"📍 Redis URL: {settings.redis.url}")
86
+ except Exception as e:
87
+ click.echo(f"⚠️ Configuration not available: {e}")
88
+
89
+ click.echo("\n💡 Quick start:")
90
+ click.echo(" mcli workflow dashboard launch")
91
+ click.echo(" mcli workflow dashboard launch --port 8502 --host 0.0.0.0")
92
+
93
+
94
+ @dashboard.command()
95
+ @click.argument("action", type=click.Choice(["start", "stop", "restart"]))
96
+ def service(action):
97
+ """Manage dashboard as a background service."""
98
+
99
+ if action == "start":
100
+ click.echo("🚀 Starting dashboard service...")
101
+ # Could implement systemd or pm2 integration here
102
+ click.echo("⚠️ Service mode not yet implemented")
103
+ click.echo(" Use 'mcli workflow dashboard launch' instead")
104
+ elif action == "stop":
105
+ click.echo("⏹️ Stopping dashboard service...")
106
+ click.echo("⚠️ Service mode not yet implemented")
107
+ elif action == "restart":
108
+ click.echo("🔄 Restarting dashboard service...")
109
+ click.echo("⚠️ Service mode not yet implemented")
110
+
111
+
112
+ if __name__ == "__main__":
113
+ dashboard()
File without changes
@@ -0,0 +1,100 @@
1
+ import click
2
+ import fitz # PyMuPDF
3
+
4
+
5
+ @click.group(name="file")
6
+ def file():
7
+ """Personal file utility to use with custom and/or default file system paths."""
8
+ pass
9
+
10
+
11
+ @file.command()
12
+ @click.argument("input_oxps", type=click.Path(exists=True))
13
+ @click.argument("output_pdf", type=click.Path())
14
+ def oxps_to_pdf(input_oxps, output_pdf):
15
+ """Converts an OXPS file (INPUT_OXPS) to a PDF file (OUTPUT_PDF)."""
16
+ try:
17
+ # Open the OXPS file
18
+ oxps_document = fitz.open(input_oxps)
19
+
20
+ # Convert to PDF bytes
21
+ pdf_bytes = oxps_document.convert_to_pdf()
22
+
23
+ # Open the PDF bytes as a new PDF document
24
+ pdf_document = fitz.open("pdf", pdf_bytes)
25
+
26
+ # Save the PDF document to a file
27
+ pdf_document.save(output_pdf)
28
+
29
+ click.echo(f"Successfully converted '{input_oxps}' to '{output_pdf}'")
30
+
31
+ except Exception as e:
32
+ click.echo(f"Error converting file: {e}", err=True)
33
+
34
+
35
+ import os
36
+ import subprocess
37
+ from pathlib import Path
38
+ from typing import List, Optional
39
+
40
+ DEFAULT_DIRS = ["~/repos/lefv-vault", "~/Documents/OneDrive", "~/Documents/Documents"]
41
+
42
+
43
+ @file.command(name="search")
44
+ @click.argument("search-string", type=str)
45
+ @click.argument("search-dirs", default=DEFAULT_DIRS)
46
+ @click.argument("context-lines", default=3, type=int)
47
+ def find_string_with_fzf(
48
+ search_string: str = "foo",
49
+ search_dirs: Optional[List[str]] = DEFAULT_DIRS,
50
+ context_lines: int = 3,
51
+ ) -> List[str]:
52
+ """
53
+ Search for a string with ripgrep in given directories and select matches with fzf.
54
+
55
+ Parameters:
56
+ search_string (str): The string to search for.
57
+ search_dirs (Optional[List[str]]): Directories to search in. Defaults to a predefined list.
58
+ context_lines (int): Number of lines of context above and below the match.
59
+
60
+ Returns:
61
+ List[str]: List of selected lines with context from fzf.
62
+ """
63
+ if not search_string.strip():
64
+ raise ValueError("Search string cannot be empty")
65
+
66
+ dirs_to_search = search_dirs or DEFAULT_DIRS
67
+ expanded_dirs = [str(Path(d).expanduser()) for d in dirs_to_search]
68
+
69
+ # Validate directories exist
70
+ valid_dirs = [d for d in expanded_dirs if Path(d).exists()]
71
+ if not valid_dirs:
72
+ raise FileNotFoundError("None of the provided or default directories exist")
73
+
74
+ # Run ripgrep with context lines
75
+ rg_command = ["rg", "--color=always", f"-C{context_lines}", search_string, *valid_dirs]
76
+
77
+ try:
78
+ rg_proc = subprocess.run(rg_command, capture_output=True, text=True, check=True)
79
+ except subprocess.CalledProcessError as e:
80
+ print("No matches found or error running rg.")
81
+ return []
82
+
83
+ # Pipe the output through fzf
84
+ try:
85
+ fzf_proc = subprocess.run(
86
+ ["fzf", "--ansi", "--multi"],
87
+ input=rg_proc.stdout,
88
+ capture_output=True,
89
+ text=True,
90
+ check=True,
91
+ )
92
+ selections = fzf_proc.stdout.strip().split("\n")
93
+ return [s for s in selections if s.strip()]
94
+ except subprocess.CalledProcessError:
95
+ # User exited fzf without selection
96
+ return []
97
+
98
+
99
+ if __name__ == "__main__":
100
+ file()
@@ -0,0 +1,21 @@
1
+ [gcloud]
2
+ default_project = "remote-ws-88" # Default project value
3
+ default_region = "us-west1" # Default region value
4
+
5
+ [workstations]
6
+ cluster = "cluster-cirrus-ws" # Default cluster value
7
+ config = "config-cirrus-ws" # Default config value
8
+
9
+ [instances]
10
+ alpha = "apps-luis-fernandez-de-la-vara"
11
+
12
+ [tcp_tunnel]
13
+ local_host = "127.0.0.1" # Local host for TCP tunnel
14
+ local_port = "2222" # Local port for TCP tunnel
15
+ remote_port = "22" # Remote port for SSH connection
16
+
17
+ [commands.describe]
18
+ command = "describe" # Command for querying workstation details
19
+
20
+ [commands.tunnel]
21
+ command = "start-tcp-tunnel" # Command for establishing TCP tunnel
@@ -0,0 +1,58 @@
1
+ import click
2
+
3
+ # from mcli.public.mcli.lib.shell.shell import shell_exec, get_shell_script_path
4
+ from mcli.lib.shell.shell import get_shell_script_path, shell_exec
5
+
6
+
7
+ # Click CLI group renamed to 'gcloud'
8
+ @click.group()
9
+ def gcloud():
10
+ """gcloud utility - use this to interact with gcloud"""
11
+ pass
12
+
13
+
14
+ @click.command()
15
+ def start():
16
+ """Start a gcloud instance"""
17
+ scripts_path = get_shell_script_path("gcloud", __file__)
18
+ shell_exec(scripts_path, "start")
19
+
20
+
21
+ @gcloud.command()
22
+ def stop():
23
+ """Start a gcloud instance"""
24
+ scripts_path = get_shell_script_path("gcloud", __file__)
25
+ shell_exec(scripts_path, "stop")
26
+
27
+
28
+ @gcloud.command()
29
+ def describe():
30
+ """Start a gcloud instance"""
31
+ scripts_path = get_shell_script_path("gcloud", __file__)
32
+ shell_exec(scripts_path, "describe")
33
+
34
+
35
+ @gcloud.command()
36
+ @click.argument("remote-port", type=str)
37
+ @click.argument("local-port", type=str)
38
+ def tunnel(remote_port: str, local_port: str):
39
+ """Create an alpha tunnel using the instance"""
40
+ logger.info(f"Creating a tunnel at {remote_port} to local port {local_port}")
41
+ scripts_path = get_shell_script_path("gcloud", __file__)
42
+ shell_exec(scripts_path, "tunnel", remote_port, local_port)
43
+
44
+
45
+ @gcloud.command()
46
+ def login(remote_port: str, local_port: str):
47
+ """Login to gcloud"""
48
+ logger.info(f"Authenticating into gcloud")
49
+ scripts_path = get_shell_script_path("gcloud", __file__)
50
+ shell_exec(scripts_path, "login", remote_port, local_port)
51
+
52
+
53
+ gcloud.add_command(start)
54
+ gcloud.add_command(tunnel)
55
+
56
+
57
+ if __name__ == "__main__":
58
+ gcloud()