machineconfig 1.96__py3-none-any.whl → 2.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 machineconfig might be problematic. Click here for more details.

Files changed (164) hide show
  1. machineconfig/cluster/cloud_manager.py +22 -26
  2. machineconfig/cluster/data_transfer.py +2 -2
  3. machineconfig/cluster/distribute.py +0 -2
  4. machineconfig/cluster/file_manager.py +4 -4
  5. machineconfig/cluster/job_params.py +1 -1
  6. machineconfig/cluster/loader_runner.py +8 -8
  7. machineconfig/cluster/remote_machine.py +4 -4
  8. machineconfig/cluster/script_execution.py +2 -2
  9. machineconfig/cluster/sessions_managers/archive/create_zellij_template.py +1 -1
  10. machineconfig/cluster/sessions_managers/enhanced_command_runner.py +23 -23
  11. machineconfig/cluster/sessions_managers/wt_local.py +78 -76
  12. machineconfig/cluster/sessions_managers/wt_local_manager.py +91 -91
  13. machineconfig/cluster/sessions_managers/wt_remote.py +39 -39
  14. machineconfig/cluster/sessions_managers/wt_remote_manager.py +94 -91
  15. machineconfig/cluster/sessions_managers/wt_utils/layout_generator.py +56 -54
  16. machineconfig/cluster/sessions_managers/wt_utils/process_monitor.py +49 -49
  17. machineconfig/cluster/sessions_managers/wt_utils/remote_executor.py +18 -18
  18. machineconfig/cluster/sessions_managers/wt_utils/session_manager.py +42 -42
  19. machineconfig/cluster/sessions_managers/wt_utils/status_reporter.py +36 -36
  20. machineconfig/cluster/sessions_managers/zellij_local.py +43 -46
  21. machineconfig/cluster/sessions_managers/zellij_local_manager.py +139 -120
  22. machineconfig/cluster/sessions_managers/zellij_remote.py +35 -35
  23. machineconfig/cluster/sessions_managers/zellij_remote_manager.py +33 -33
  24. machineconfig/cluster/sessions_managers/zellij_utils/example_usage.py +15 -15
  25. machineconfig/cluster/sessions_managers/zellij_utils/layout_generator.py +25 -26
  26. machineconfig/cluster/sessions_managers/zellij_utils/process_monitor.py +49 -49
  27. machineconfig/cluster/sessions_managers/zellij_utils/remote_executor.py +5 -5
  28. machineconfig/cluster/sessions_managers/zellij_utils/session_manager.py +15 -15
  29. machineconfig/cluster/sessions_managers/zellij_utils/status_reporter.py +11 -11
  30. machineconfig/cluster/templates/utils.py +3 -3
  31. machineconfig/jobs/__pycache__/__init__.cpython-311.pyc +0 -0
  32. machineconfig/jobs/python/__pycache__/__init__.cpython-311.pyc +0 -0
  33. machineconfig/jobs/python/__pycache__/python_ve_symlink.cpython-311.pyc +0 -0
  34. machineconfig/jobs/python/check_installations.py +8 -9
  35. machineconfig/jobs/python/python_cargo_build_share.py +2 -2
  36. machineconfig/jobs/python/vscode/link_ve.py +7 -7
  37. machineconfig/jobs/python/vscode/select_interpreter.py +7 -7
  38. machineconfig/jobs/python/vscode/sync_code.py +5 -5
  39. machineconfig/jobs/python_custom_installers/archive/ngrok.py +2 -2
  40. machineconfig/jobs/python_custom_installers/dev/aider.py +3 -3
  41. machineconfig/jobs/python_custom_installers/dev/alacritty.py +3 -3
  42. machineconfig/jobs/python_custom_installers/dev/brave.py +3 -3
  43. machineconfig/jobs/python_custom_installers/dev/bypass_paywall.py +5 -5
  44. machineconfig/jobs/python_custom_installers/dev/code.py +3 -3
  45. machineconfig/jobs/python_custom_installers/dev/cursor.py +9 -9
  46. machineconfig/jobs/python_custom_installers/dev/docker_desktop.py +4 -4
  47. machineconfig/jobs/python_custom_installers/dev/espanso.py +4 -4
  48. machineconfig/jobs/python_custom_installers/dev/goes.py +4 -4
  49. machineconfig/jobs/python_custom_installers/dev/lvim.py +4 -4
  50. machineconfig/jobs/python_custom_installers/dev/nerdfont.py +3 -3
  51. machineconfig/jobs/python_custom_installers/dev/redis.py +3 -3
  52. machineconfig/jobs/python_custom_installers/dev/wezterm.py +3 -3
  53. machineconfig/jobs/python_custom_installers/dev/winget.py +27 -27
  54. machineconfig/jobs/python_custom_installers/docker.py +3 -3
  55. machineconfig/jobs/python_custom_installers/gh.py +7 -7
  56. machineconfig/jobs/python_custom_installers/hx.py +1 -1
  57. machineconfig/jobs/python_custom_installers/warp-cli.py +3 -3
  58. machineconfig/jobs/python_generic_installers/config.json +412 -389
  59. machineconfig/jobs/python_windows_installers/dev/config.json +1 -1
  60. machineconfig/logger.py +50 -0
  61. machineconfig/profile/__pycache__/__init__.cpython-311.pyc +0 -0
  62. machineconfig/profile/__pycache__/create.cpython-311.pyc +0 -0
  63. machineconfig/profile/__pycache__/shell.cpython-311.pyc +0 -0
  64. machineconfig/profile/create.py +23 -16
  65. machineconfig/profile/create_hardlinks.py +8 -8
  66. machineconfig/profile/shell.py +41 -37
  67. machineconfig/scripts/__pycache__/__init__.cpython-311.pyc +0 -0
  68. machineconfig/scripts/__pycache__/__init__.cpython-313.pyc +0 -0
  69. machineconfig/scripts/linux/devops +2 -2
  70. machineconfig/scripts/linux/fire +1 -0
  71. machineconfig/scripts/linux/fire_agents +0 -1
  72. machineconfig/scripts/linux/mcinit +27 -0
  73. machineconfig/scripts/python/__pycache__/__init__.cpython-311.pyc +0 -0
  74. machineconfig/scripts/python/__pycache__/__init__.cpython-313.pyc +0 -0
  75. machineconfig/scripts/python/__pycache__/croshell.cpython-311.pyc +0 -0
  76. machineconfig/scripts/python/__pycache__/devops.cpython-311.pyc +0 -0
  77. machineconfig/scripts/python/__pycache__/devops.cpython-313.pyc +0 -0
  78. machineconfig/scripts/python/__pycache__/devops_update_repos.cpython-311.pyc +0 -0
  79. machineconfig/scripts/python/__pycache__/devops_update_repos.cpython-313.pyc +0 -0
  80. machineconfig/scripts/python/__pycache__/fire_agents.cpython-311.pyc +0 -0
  81. machineconfig/scripts/python/__pycache__/fire_jobs.cpython-311.pyc +0 -0
  82. machineconfig/scripts/python/__pycache__/repos.cpython-311.pyc +0 -0
  83. machineconfig/scripts/python/ai/__pycache__/init.cpython-311.pyc +0 -0
  84. machineconfig/scripts/python/ai/__pycache__/mcinit.cpython-311.pyc +0 -0
  85. machineconfig/scripts/python/ai/chatmodes/Thinking-Beast-Mode.chatmode.md +337 -0
  86. machineconfig/scripts/python/ai/chatmodes/Ultimate-Transparent-Thinking-Beast-Mode.chatmode.md +644 -0
  87. machineconfig/scripts/python/ai/chatmodes/deepResearch.chatmode.md +81 -0
  88. machineconfig/scripts/python/ai/configs/.gemini/settings.json +81 -0
  89. machineconfig/scripts/python/ai/instructions/python/dev.instructions.md +45 -0
  90. machineconfig/scripts/python/ai/mcinit.py +103 -0
  91. machineconfig/scripts/python/ai/prompts/allLintersAndTypeCheckers.prompt.md +5 -0
  92. machineconfig/scripts/python/ai/prompts/research-report-skeleton.prompt.md +38 -0
  93. machineconfig/scripts/python/ai/scripts/lint_and_type_check.sh +47 -0
  94. machineconfig/scripts/python/archive/tmate_conn.py +5 -5
  95. machineconfig/scripts/python/archive/tmate_start.py +3 -3
  96. machineconfig/scripts/python/choose_wezterm_theme.py +2 -2
  97. machineconfig/scripts/python/cloud_copy.py +19 -18
  98. machineconfig/scripts/python/cloud_mount.py +9 -7
  99. machineconfig/scripts/python/cloud_repo_sync.py +11 -11
  100. machineconfig/scripts/python/cloud_sync.py +1 -1
  101. machineconfig/scripts/python/croshell.py +14 -14
  102. machineconfig/scripts/python/devops.py +6 -6
  103. machineconfig/scripts/python/devops_add_identity.py +8 -6
  104. machineconfig/scripts/python/devops_add_ssh_key.py +18 -18
  105. machineconfig/scripts/python/devops_backup_retrieve.py +13 -13
  106. machineconfig/scripts/python/devops_devapps_install.py +3 -3
  107. machineconfig/scripts/python/devops_update_repos.py +1 -1
  108. machineconfig/scripts/python/dotfile.py +2 -2
  109. machineconfig/scripts/python/fire_agents.py +183 -41
  110. machineconfig/scripts/python/fire_jobs.py +17 -11
  111. machineconfig/scripts/python/ftpx.py +2 -2
  112. machineconfig/scripts/python/gh_models.py +94 -94
  113. machineconfig/scripts/python/helpers/__pycache__/__init__.cpython-311.pyc +0 -0
  114. machineconfig/scripts/python/helpers/__pycache__/cloud_helpers.cpython-311.pyc +0 -0
  115. machineconfig/scripts/python/helpers/__pycache__/helpers2.cpython-311.pyc +0 -0
  116. machineconfig/scripts/python/helpers/__pycache__/helpers4.cpython-311.pyc +0 -0
  117. machineconfig/scripts/python/helpers/cloud_helpers.py +3 -3
  118. machineconfig/scripts/python/helpers/helpers2.py +1 -1
  119. machineconfig/scripts/python/helpers/helpers4.py +8 -6
  120. machineconfig/scripts/python/helpers/helpers5.py +7 -7
  121. machineconfig/scripts/python/helpers/repo_sync_helpers.py +1 -1
  122. machineconfig/scripts/python/mount_nfs.py +3 -2
  123. machineconfig/scripts/python/mount_nw_drive.py +4 -4
  124. machineconfig/scripts/python/mount_ssh.py +3 -2
  125. machineconfig/scripts/python/repos.py +8 -8
  126. machineconfig/scripts/python/scheduler.py +1 -1
  127. machineconfig/scripts/python/start_slidev.py +8 -7
  128. machineconfig/scripts/python/start_terminals.py +1 -1
  129. machineconfig/scripts/python/viewer.py +40 -40
  130. machineconfig/scripts/python/wifi_conn.py +65 -66
  131. machineconfig/scripts/python/wsl_windows_transfer.py +1 -1
  132. machineconfig/scripts/windows/mcinit.ps1 +4 -0
  133. machineconfig/settings/linters/.ruff.toml +2 -2
  134. machineconfig/settings/shells/ipy/profiles/default/startup/playext.py +71 -71
  135. machineconfig/settings/shells/wt/settings.json +8 -8
  136. machineconfig/setup_linux/web_shortcuts/tmp.sh +2 -0
  137. machineconfig/setup_windows/wt_and_pwsh/set_pwsh_theme.py +10 -7
  138. machineconfig/setup_windows/wt_and_pwsh/set_wt_settings.py +9 -7
  139. machineconfig/utils/ai/browser_user_wrapper.py +5 -5
  140. machineconfig/utils/ai/generate_file_checklist.py +11 -12
  141. machineconfig/utils/ai/url2md.py +1 -1
  142. machineconfig/utils/cloud/onedrive/setup_oauth.py +4 -4
  143. machineconfig/utils/cloud/onedrive/transaction.py +129 -129
  144. machineconfig/utils/code.py +13 -6
  145. machineconfig/utils/installer.py +51 -53
  146. machineconfig/utils/installer_utils/installer_abc.py +21 -10
  147. machineconfig/utils/installer_utils/installer_class.py +42 -16
  148. machineconfig/utils/io_save.py +3 -15
  149. machineconfig/utils/options.py +10 -3
  150. machineconfig/utils/path.py +5 -0
  151. machineconfig/utils/path_reduced.py +201 -149
  152. machineconfig/utils/procs.py +23 -23
  153. machineconfig/utils/scheduling.py +11 -12
  154. machineconfig/utils/ssh.py +270 -0
  155. machineconfig/utils/terminal.py +180 -0
  156. machineconfig/utils/utils.py +1 -2
  157. machineconfig/utils/utils2.py +43 -0
  158. machineconfig/utils/utils5.py +163 -34
  159. machineconfig/utils/ve.py +2 -2
  160. {machineconfig-1.96.dist-info → machineconfig-2.0.dist-info}/METADATA +13 -8
  161. {machineconfig-1.96.dist-info → machineconfig-2.0.dist-info}/RECORD +163 -144
  162. machineconfig/cluster/self_ssh.py +0 -57
  163. {machineconfig-1.96.dist-info → machineconfig-2.0.dist-info}/WHEEL +0 -0
  164. {machineconfig-1.96.dist-info → machineconfig-2.0.dist-info}/top_level.txt +0 -0
@@ -13,11 +13,11 @@ logger = logging.getLogger(__name__)
13
13
 
14
14
  class ProcessMonitor:
15
15
  """Handles process status checking and verification on remote machines."""
16
-
16
+
17
17
  def __init__(self, remote_executor: RemoteExecutor):
18
18
  self.remote_executor = remote_executor
19
-
20
- def check_command_status(self, tab_name: str, tab_config: Dict[str, Tuple[str, str]],
19
+
20
+ def check_command_status(self, tab_name: str, tab_config: Dict[str, Tuple[str, str]],
21
21
  use_verification: bool = True) -> Dict[str, Any]:
22
22
  """Check command status with optional process verification."""
23
23
  if tab_name not in tab_config:
@@ -29,26 +29,26 @@ class ProcessMonitor:
29
29
  "command": None,
30
30
  "remote": self.remote_executor.remote_name
31
31
  }
32
-
32
+
33
33
  # Use the verified method by default for more accurate results
34
34
  if use_verification:
35
35
  return self.get_verified_process_status(tab_name, tab_config)
36
-
36
+
37
37
  return self._basic_process_check(tab_name, tab_config)
38
-
38
+
39
39
  def _basic_process_check(self, tab_name: str, tab_config: Dict[str, Tuple[str, str]]) -> Dict[str, Any]:
40
40
  """Basic process checking without verification."""
41
41
  _, command = tab_config[tab_name]
42
-
42
+
43
43
  try:
44
44
  check_script = self._create_process_check_script(command)
45
45
  remote_cmd = f"$HOME/venvs/ve/bin/python -c {shlex.quote(check_script)}"
46
46
  result = self.remote_executor.run_command(remote_cmd, timeout=15)
47
-
47
+
48
48
  if result.returncode == 0:
49
49
  try:
50
50
  matching_processes = json.loads(result.stdout.strip())
51
-
51
+
52
52
  if matching_processes:
53
53
  return {
54
54
  "status": "running",
@@ -79,14 +79,14 @@ class ProcessMonitor:
79
79
  }
80
80
  else:
81
81
  return {
82
- "status": "error",
82
+ "status": "error",
83
83
  "error": f"Remote command failed: {result.stderr}",
84
84
  "running": False,
85
85
  "command": command,
86
86
  "tab_name": tab_name,
87
87
  "remote": self.remote_executor.remote_name
88
88
  }
89
-
89
+
90
90
  except Exception as e:
91
91
  logger.error(f"Error checking command status for tab '{tab_name}': {e}")
92
92
  return {
@@ -97,7 +97,7 @@ class ProcessMonitor:
97
97
  "tab_name": tab_name,
98
98
  "remote": self.remote_executor.remote_name
99
99
  }
100
-
100
+
101
101
  def _create_process_check_script(self, command: str) -> str:
102
102
  """Create Python script for checking processes on remote machine."""
103
103
  return f"""
@@ -110,25 +110,25 @@ def check_process():
110
110
  full_command = '{command}'
111
111
  cmd_parts = [part for part in full_command.split() if len(part) > 2]
112
112
  current_pid = os.getpid()
113
-
113
+
114
114
  primary_cmd = cmd_parts[0] if cmd_parts else ''
115
-
115
+
116
116
  for proc in psutil.process_iter(['pid', 'name', 'cmdline', 'status', 'create_time']):
117
117
  try:
118
118
  if proc.info['pid'] == current_pid:
119
119
  continue
120
-
120
+
121
121
  if proc.info['cmdline'] and len(proc.info['cmdline']) > 0:
122
122
  cmdline_str = ' '.join(proc.info['cmdline'])
123
-
123
+
124
124
  if 'check_process()' in cmdline_str or 'psutil.process_iter' in cmdline_str:
125
125
  continue
126
-
126
+
127
127
  matches_primary = primary_cmd in cmdline_str
128
128
  matches_parts = sum(1 for part in cmd_parts[1:] if part in cmdline_str)
129
-
129
+
130
130
  if (matches_primary and matches_parts >= 2) or \\
131
- (full_command in cmdline_str and not any(python_indicator in cmdline_str.lower()
131
+ (full_command in cmdline_str and not any(python_indicator in cmdline_str.lower()
132
132
  for python_indicator in ['python -c', 'import psutil', 'def check_process'])):
133
133
  matching_processes.append({{
134
134
  "pid": proc.info['pid'],
@@ -140,14 +140,14 @@ def check_process():
140
140
  }})
141
141
  except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
142
142
  continue
143
-
143
+
144
144
  return matching_processes
145
145
 
146
146
  if __name__ == "__main__":
147
147
  processes = check_process()
148
148
  print(json.dumps(processes))
149
149
  """
150
-
150
+
151
151
  def force_fresh_process_check(self, tab_name: str, tab_config: Dict[str, Tuple[str, str]]) -> Dict[str, Any]:
152
152
  """Force a fresh process check with additional validation."""
153
153
  if tab_name not in tab_config:
@@ -158,23 +158,23 @@ if __name__ == "__main__":
158
158
  "command": None,
159
159
  "remote": self.remote_executor.remote_name
160
160
  }
161
-
161
+
162
162
  _, command = tab_config[tab_name]
163
-
163
+
164
164
  try:
165
165
  # Get timestamp for freshness validation
166
166
  timestamp_result = self.remote_executor.run_command("date +%s", timeout=5)
167
167
  check_timestamp = timestamp_result.stdout.strip() if timestamp_result.returncode == 0 else "unknown"
168
-
168
+
169
169
  check_script = self._create_fresh_check_script(command)
170
170
  remote_cmd = f"$HOME/venvs/ve/bin/python -c {shlex.quote(check_script)}"
171
171
  result = self.remote_executor.run_command(remote_cmd, timeout=15)
172
-
172
+
173
173
  if result.returncode == 0:
174
174
  try:
175
175
  check_result = json.loads(result.stdout.strip())
176
176
  matching_processes = check_result.get("processes", [])
177
-
177
+
178
178
  return {
179
179
  "status": "running" if matching_processes else "not_running",
180
180
  "running": bool(matching_processes),
@@ -198,14 +198,14 @@ if __name__ == "__main__":
198
198
  }
199
199
  else:
200
200
  return {
201
- "status": "error",
201
+ "status": "error",
202
202
  "error": f"Remote command failed: {result.stderr}",
203
203
  "running": False,
204
204
  "command": command,
205
205
  "tab_name": tab_name,
206
206
  "remote": self.remote_executor.remote_name
207
207
  }
208
-
208
+
209
209
  except Exception as e:
210
210
  logger.error(f"Error in fresh process check for tab '{tab_name}': {e}")
211
211
  return {
@@ -216,11 +216,11 @@ if __name__ == "__main__":
216
216
  "tab_name": tab_name,
217
217
  "remote": self.remote_executor.remote_name
218
218
  }
219
-
219
+
220
220
  def _create_fresh_check_script(self, command: str) -> str:
221
221
  """Create enhanced process checking script with freshness validation."""
222
222
  escaped_command = command.replace("'", "\\'").replace('"', '\\"')
223
-
223
+
224
224
  return f'''
225
225
  import psutil
226
226
  import json
@@ -229,40 +229,40 @@ import time
229
229
 
230
230
  def force_fresh_check():
231
231
  time.sleep(0.1)
232
-
232
+
233
233
  matching_processes = []
234
234
  full_command = '{escaped_command}'
235
235
  cmd_parts = [part for part in full_command.split() if len(part) > 2]
236
236
  current_pid = os.getpid()
237
237
  primary_cmd = cmd_parts[0] if cmd_parts else ''
238
-
238
+
239
239
  check_time = time.time()
240
-
240
+
241
241
  for proc in psutil.process_iter(['pid', 'name', 'cmdline', 'status', 'create_time']):
242
242
  try:
243
243
  if proc.info['pid'] == current_pid:
244
244
  continue
245
-
245
+
246
246
  if proc.info['cmdline'] and len(proc.info['cmdline']) > 0:
247
247
  cmdline_str = ' '.join(proc.info['cmdline'])
248
-
248
+
249
249
  if any(indicator in cmdline_str for indicator in [
250
250
  'check_process()', 'psutil.process_iter', 'force_fresh_check',
251
251
  'import psutil', 'def check_process'
252
252
  ]):
253
253
  continue
254
-
254
+
255
255
  if proc.info['create_time'] and proc.info['create_time'] > check_time - 5:
256
256
  continue
257
-
257
+
258
258
  matches_primary = primary_cmd in cmdline_str and primary_cmd != 'python'
259
259
  matches_parts = sum(1 for part in cmd_parts[1:] if part in cmdline_str)
260
-
260
+
261
261
  if matches_primary and matches_parts >= 2:
262
262
  script_indicators = ['-c', 'import ', 'def ', 'psutil']
263
- is_direct_command = not any(script_indicator in cmdline_str.lower()
263
+ is_direct_command = not any(script_indicator in cmdline_str.lower()
264
264
  for script_indicator in script_indicators)
265
-
265
+
266
266
  if is_direct_command or (full_command in cmdline_str and 'python -c' not in cmdline_str):
267
267
  matching_processes.append({{
268
268
  "pid": proc.info['pid'],
@@ -275,7 +275,7 @@ def force_fresh_check():
275
275
  }})
276
276
  except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
277
277
  continue
278
-
278
+
279
279
  return {{
280
280
  "processes": matching_processes,
281
281
  "check_timestamp": check_time,
@@ -287,23 +287,23 @@ if __name__ == "__main__":
287
287
  result = force_fresh_check()
288
288
  print(json.dumps(result))
289
289
  '''
290
-
290
+
291
291
  def verify_process_alive(self, pid: int) -> bool:
292
292
  """Verify if a process with given PID is actually alive."""
293
293
  try:
294
294
  verify_cmd = f"kill -0 {pid} 2>/dev/null && echo 'alive' || echo 'dead'"
295
295
  result = self.remote_executor.run_command(verify_cmd, timeout=5)
296
-
296
+
297
297
  if result.returncode == 0:
298
298
  return result.stdout.strip() == 'alive'
299
299
  return False
300
300
  except Exception:
301
301
  return False
302
-
302
+
303
303
  def get_verified_process_status(self, tab_name: str, tab_config: Dict[str, Tuple[str, str]]) -> Dict[str, Any]:
304
304
  """Get process status with additional verification that processes are actually alive."""
305
305
  status = self.force_fresh_process_check(tab_name, tab_config)
306
-
306
+
307
307
  if status.get("running") and status.get("processes"):
308
308
  verified_processes = []
309
309
  for proc in status["processes"]:
@@ -314,20 +314,20 @@ if __name__ == "__main__":
314
314
  else:
315
315
  proc["verified_alive"] = False
316
316
  logger.warning(f"Process PID {pid} found in process list but not actually alive")
317
-
317
+
318
318
  status["processes"] = verified_processes
319
319
  status["running"] = bool(verified_processes)
320
320
  status["status"] = "running" if verified_processes else "not_running"
321
321
  status["verification_method"] = "kill_signal_check"
322
-
322
+
323
323
  return status
324
-
324
+
325
325
  def check_all_commands_status(self, tab_config: Dict[str, Tuple[str, str]]) -> Dict[str, Dict[str, Any]]:
326
326
  """Check status of all commands in the tab configuration."""
327
327
  if not tab_config:
328
328
  logger.warning("No tab configuration provided.")
329
329
  return {}
330
-
330
+
331
331
  status_report = {}
332
332
  for tab_name in tab_config:
333
333
  status_report[tab_name] = self.check_command_status(tab_name, tab_config)
@@ -11,10 +11,10 @@ logger = logging.getLogger(__name__)
11
11
 
12
12
  class RemoteExecutor:
13
13
  """Handles SSH command execution on remote machines."""
14
-
14
+
15
15
  def __init__(self, remote_name: str):
16
16
  self.remote_name = remote_name
17
-
17
+
18
18
  def run_command(self, command: str, timeout: int = 30) -> subprocess.CompletedProcess[str]:
19
19
  """Execute a command on the remote machine via SSH."""
20
20
  ssh_cmd = ["ssh", self.remote_name, command]
@@ -32,7 +32,7 @@ class RemoteExecutor:
32
32
  except Exception as e:
33
33
  logger.error(f"SSH command failed: {e}")
34
34
  raise
35
-
35
+
36
36
  def copy_file_to_remote(self, local_file: str, remote_path: str) -> Dict[str, Any]:
37
37
  """Copy a file to the remote machine using SCP."""
38
38
  scp_cmd = ["scp", local_file, f"{self.remote_name}:{remote_path}"]
@@ -47,7 +47,7 @@ class RemoteExecutor:
47
47
  except Exception as e:
48
48
  logger.error(f"SCP operation failed: {e}")
49
49
  return {"success": False, "error": str(e)}
50
-
50
+
51
51
  def create_remote_directory(self, remote_dir: str) -> bool:
52
52
  """Create a directory on the remote machine."""
53
53
  try:
@@ -56,7 +56,7 @@ class RemoteExecutor:
56
56
  except Exception as e:
57
57
  logger.error(f"Failed to create remote directory {remote_dir}: {e}")
58
58
  return False
59
-
59
+
60
60
  def attach_to_session_interactive(self, session_name: str) -> None:
61
61
  """Attach to a Zellij session interactively via SSH."""
62
62
  try:
@@ -16,39 +16,39 @@ console = Console()
16
16
 
17
17
  class SessionManager:
18
18
  """Handles Zellij session operations on remote machines."""
19
-
19
+
20
20
  def __init__(self, remote_executor: RemoteExecutor, session_name: str, tmp_layout_dir: Path):
21
21
  self.remote_executor = remote_executor
22
22
  self.session_name = session_name
23
23
  self.tmp_layout_dir = tmp_layout_dir
24
-
24
+
25
25
  def copy_layout_to_remote(self, local_layout_file: Path, random_suffix: str) -> str:
26
26
  """Copy the layout file to the remote machine and return the remote path."""
27
27
  remote_layout_dir = f"~/{self.tmp_layout_dir.relative_to(Path.home())}"
28
28
  remote_layout_file = f"{remote_layout_dir}/zellij_layout_{self.session_name}_{random_suffix}.kdl"
29
-
29
+
30
30
  # Create remote directory
31
31
  if not self.remote_executor.create_remote_directory(remote_layout_dir):
32
32
  raise RuntimeError(f"Failed to create remote directory: {remote_layout_dir}")
33
-
33
+
34
34
  # Copy layout file to remote machine
35
35
  copy_result = self.remote_executor.copy_file_to_remote(str(local_layout_file), remote_layout_file)
36
36
  if not copy_result["success"]:
37
37
  raise RuntimeError(f"Failed to copy layout file to remote: {copy_result['error']}")
38
-
38
+
39
39
  # Enhanced Rich logging
40
40
  console.print(f"[bold green]📁 Zellij layout file copied to remote:[/bold green] [yellow]{self.remote_executor.remote_name}[/yellow][cyan]:{remote_layout_file}[/cyan]")
41
41
  return remote_layout_file
42
-
42
+
43
43
  def check_zellij_session_status(self) -> Dict[str, Any]:
44
44
  """Check if the Zellij session exists and is running."""
45
45
  try:
46
46
  result = self.remote_executor.run_command('zellij list-sessions', timeout=10)
47
-
47
+
48
48
  if result.returncode == 0:
49
49
  sessions = result.stdout.strip().split('\n') if result.stdout.strip() else []
50
50
  session_running = any(self.session_name in session for session in sessions)
51
-
51
+
52
52
  return {
53
53
  "zellij_running": True,
54
54
  "session_exists": session_running,
@@ -63,7 +63,7 @@ class SessionManager:
63
63
  "session_name": self.session_name,
64
64
  "remote": self.remote_executor.remote_name
65
65
  }
66
-
66
+
67
67
  except Exception as e:
68
68
  return {
69
69
  "zellij_running": False,
@@ -71,7 +71,7 @@ class SessionManager:
71
71
  "session_name": self.session_name,
72
72
  "remote": self.remote_executor.remote_name
73
73
  }
74
-
74
+
75
75
  def start_zellij_session(self, layout_file_path: Optional[str] = None) -> Dict[str, Any]:
76
76
  """Start a Zellij session on the remote machine with the generated layout."""
77
77
  try:
@@ -80,15 +80,15 @@ class SessionManager:
80
80
  remote_layout_file = f"~/{self.tmp_layout_dir.relative_to(Path.home())}/{layout_filename}"
81
81
  else:
82
82
  raise ValueError("No layout file path provided.")
83
-
83
+
84
84
  # Enhanced Rich logging for session start
85
85
  console.print(f"[bold cyan]🚀 Starting Zellij session[/bold cyan] [yellow]'{self.session_name}'[/yellow] [dim]on remote[/dim] [bold yellow]'{self.remote_executor.remote_name}'[/bold yellow] [dim]with layout:[/dim] [blue]{remote_layout_file}[/blue]")
86
-
86
+
87
87
  # Start Zellij session with layout
88
88
  start_cmd = f"zellij --layout {remote_layout_file} a -b {self.session_name}"
89
89
  console.print(f"[dim]Executing:[/dim] [green]{start_cmd}[/green]")
90
90
  result = self.remote_executor.run_command(start_cmd, timeout=30)
91
-
91
+
92
92
  if result.returncode == 0:
93
93
  console.print(f"[bold green]✅ Zellij session[/bold green] [yellow]'{self.session_name}'[/yellow] [green]started successfully on[/green] [bold yellow]{self.remote_executor.remote_name}[/bold yellow]")
94
94
  return {
@@ -104,7 +104,7 @@ class SessionManager:
104
104
  "session_name": self.session_name,
105
105
  "remote": self.remote_executor.remote_name
106
106
  }
107
-
107
+
108
108
  except Exception as e:
109
109
  logger.error(f"Failed to start Zellij session on {self.remote_executor.remote_name}: {e}")
110
110
  return {
@@ -113,7 +113,7 @@ class SessionManager:
113
113
  "session_name": self.session_name,
114
114
  "remote": self.remote_executor.remote_name
115
115
  }
116
-
116
+
117
117
  def attach_to_session(self) -> None:
118
118
  """Attach to the Zellij session on the remote machine via SSH."""
119
119
  self.remote_executor.attach_to_session_interactive(self.session_name)
@@ -12,19 +12,19 @@ logger = logging.getLogger(__name__)
12
12
 
13
13
  class StatusReporter:
14
14
  """Handles comprehensive status reporting for Zellij remote sessions."""
15
-
15
+
16
16
  def __init__(self, process_monitor: ProcessMonitor, session_manager: SessionManager):
17
17
  self.process_monitor = process_monitor
18
18
  self.session_manager = session_manager
19
-
19
+
20
20
  def get_comprehensive_status(self, tab_config: Dict[str, Tuple[str, str]]) -> Dict[str, Any]:
21
21
  """Get comprehensive status including Zellij session and all commands."""
22
22
  zellij_status = self.session_manager.check_zellij_session_status()
23
23
  commands_status = self.process_monitor.check_all_commands_status(tab_config)
24
-
24
+
25
25
  running_count = sum(1 for status in commands_status.values() if status.get("running", False))
26
26
  total_count = len(commands_status)
27
-
27
+
28
28
  return {
29
29
  "zellij_session": zellij_status,
30
30
  "commands": commands_status,
@@ -36,17 +36,17 @@ class StatusReporter:
36
36
  "remote": self.session_manager.remote_executor.remote_name
37
37
  }
38
38
  }
39
-
39
+
40
40
  def print_status_report(self, tab_config: Dict[str, Tuple[str, str]]) -> None:
41
41
  """Print a formatted status report to console."""
42
42
  status = self.get_comprehensive_status(tab_config)
43
43
  remote_name = self.session_manager.remote_executor.remote_name
44
44
  session_name = self.session_manager.session_name
45
-
45
+
46
46
  print("=" * 60)
47
47
  print(f"🔍 ZELLIJ REMOTE LAYOUT STATUS REPORT ({remote_name})")
48
48
  print("=" * 60)
49
-
49
+
50
50
  # Zellij session status
51
51
  zellij = status["zellij_session"]
52
52
  if zellij.get("zellij_running", False):
@@ -56,13 +56,13 @@ class StatusReporter:
56
56
  print(f"⚠️ Zellij is running on {remote_name} but session '{session_name}' not found")
57
57
  else:
58
58
  print(f"❌ Zellij session issue on {remote_name}: {zellij.get('error', 'Unknown error')}")
59
-
59
+
60
60
  print()
61
-
61
+
62
62
  # Commands status
63
63
  print("📋 COMMAND STATUS:")
64
64
  print("-" * 40)
65
-
65
+
66
66
  for tab_name, cmd_status in status["commands"].items():
67
67
  if cmd_status.get("running", False):
68
68
  print(f"✅ {tab_name}: Running on {remote_name}")
@@ -73,7 +73,7 @@ class StatusReporter:
73
73
  print(f"❌ {tab_name}: Not running on {remote_name}")
74
74
  print(f" Command: {cmd_status.get('command', 'Unknown')}")
75
75
  print()
76
-
76
+
77
77
  # Summary
78
78
  summary = status["summary"]
79
79
  print("📊 SUMMARY:")
@@ -8,7 +8,7 @@
8
8
 
9
9
  # from machineconfig.cluster.remote_machine import WorkloadParams
10
10
  from typing import Optional
11
- from crocodile.file_management import P, PLike
11
+ from machineconfig.utils.path_reduced import P, PLike
12
12
 
13
13
  # def expensive_function(workload_params: WorkloadParams, sim_dict: Optional[dict[str, Any]] = None) -> P:
14
14
  # import time
@@ -40,7 +40,7 @@ from crocodile.file_management import P, PLike
40
40
 
41
41
  def to_cloud(localpath: PLike, cloud: str, remotepath: Optional[PLike], zip: bool = False, encrypt: bool = False,
42
42
  key: Optional[bytes] = None, pwd: Optional[str] = None, rel2home: bool = False, strict: bool = True,
43
- obfuscate: bool = False,
43
+ # obfuscate: bool = False,
44
44
  share: bool = False, verbose: bool = True, os_specific: bool = False, transfers: int = 10, root: Optional[str] = "myhome") -> 'P':
45
45
  to_del = []
46
46
  localpath = P(localpath).expanduser().absolute() if not P(localpath).exists() else P(localpath)
@@ -51,7 +51,7 @@ def to_cloud(localpath: PLike, cloud: str, remotepath: Optional[PLike], zip: boo
51
51
  localpath = localpath.encrypt(key=key, pwd=pwd, inplace=False)
52
52
  to_del.append(localpath)
53
53
  if remotepath is None:
54
- rp = localpath.get_remote_path(root=root, os_specific=os_specific, rel2home=rel2home, strict=strict, obfuscate=obfuscate) # if rel2home else (P(root) / localpath if root is not None else localpath)
54
+ rp = localpath.get_remote_path(root=root, os_specific=os_specific, rel2home=rel2home, strict=strict) # if rel2home else (P(root) / localpath if root is not None else localpath)
55
55
  else: rp = P(remotepath)
56
56
 
57
57
  from rclone_python import rclone
@@ -24,7 +24,7 @@ APP_SUMMARY_PATH = LIBRARY_ROOT.joinpath(f"profile/records/{platform.system().lo
24
24
 
25
25
  # def scan(path: P, pct: float = 0.0):
26
26
  # import vt # vt-py
27
- # client = vt.Client(PathExtended.home().joinpath("dotfiles/creds/tokens/virustotal").read_text().split("\n")[0])
27
+ # client = vt.Client(PathExtended.home().joinpath("dotfiles/creds/tokens/virustotal").read_text(encoding="utf-8").split("\n")[0])
28
28
  # console = Console()
29
29
  # console.rule(f"Scanning {path}. {pct:.2f}% done")
30
30
  # if path.is_dir():
@@ -44,7 +44,7 @@ APP_SUMMARY_PATH = LIBRARY_ROOT.joinpath(f"profile/records/{platform.system().lo
44
44
  # raise ValueError(f"❌ Error in scanning {path}") from ex
45
45
  # print("⚠️ Error in scanning, trying again...")
46
46
  # time.sleep(30)
47
-
47
+
48
48
  # # Convert results to list of dictionaries
49
49
  # results_data = list(anal.results.values())
50
50
  # malicious = []
@@ -58,13 +58,13 @@ APP_SUMMARY_PATH = LIBRARY_ROOT.joinpath(f"profile/records/{platform.system().lo
58
58
  # 'result': getattr(result_item, 'result', None),
59
59
  # 'category': getattr(result_item, 'category', 'unknown')
60
60
  # }
61
-
62
- # if result_dict.get('result') is None and result_dict.get('category') in ["undetected", "type-unsupported", "failure", "timeout", "confirmed-timeout"]:
61
+
62
+ # if result_dict.get('result') is None and result_dict.get('category') in ["undetected", "type-unsupported", "failure", "timeout", "confirmed-timeout"]:
63
63
  # continue
64
64
  # else:
65
65
  # pprint(result_dict, f"🔍 Found Category {result_dict.get('category')}")
66
66
  # malicious.append(result_item)
67
-
67
+
68
68
  # positive_pct: float = round(number=len(malicious) / len(results_data) * 100, ndigits=1)
69
69
  # print(f"""
70
70
  # {'=' * 50}
@@ -101,10 +101,9 @@ APP_SUMMARY_PATH = LIBRARY_ROOT.joinpath(f"profile/records/{platform.system().lo
101
101
  # for an_app in apps_paths_tmp:
102
102
  # version_path = [x for x in versions_files_paths if x.stem == an_app.stem]
103
103
  # if len(version_path) == 1:
104
- # app_versions.append(version_path[0].read_text())
104
+ # app_versions.append(version_path[0].read_text(encoding="utf-8"))
105
105
  # apps_paths_raw.append(an_app)
106
106
  # # if an_app.stem in versions_files_paths.stem:
107
- # # app_versions.append(versions_files_paths.filter(lambda x: x.stem == an_app.stem.replace(".exe", "")).list[0].read_text())
108
107
  # # else:
109
108
  # # print(f"🤔 Cloud not find a documented version for installation of {an_app.stem}, trying to get it from the app itself.")
110
109
  # # tmp = Terminal().run(f"{an_app.stem} --version", shell="powershell").capture().op_if_successfull_or_default(strict_err=False, strict_returcode=False)
@@ -176,8 +175,8 @@ APP_SUMMARY_PATH = LIBRARY_ROOT.joinpath(f"profile/records/{platform.system().lo
176
175
  # return "\n".join([header, separator] + rows)
177
176
 
178
177
  # markdown_content = format_app_table_markdown(app_data)
179
- # APP_SUMMARY_PATH.with_suffix(".md").write_text(markdown_content)
180
-
178
+ # APP_SUMMARY_PATH.with_suffix(".md").write_text(markdown_content, encoding="utf-8")
179
+
181
180
  # print(f"""
182
181
  # {'=' * 150}
183
182
  # 📊 SAFETY REPORT | Summary of app scanning results
@@ -2,7 +2,7 @@
2
2
  cargo install
3
3
  """
4
4
 
5
- # from crocodile.meta import Terminal
5
+ # from machineconfig.utils.terminal import Terminal
6
6
  # from machineconfig.utils.path_reduced import P as PathExtended
7
7
  # import platform
8
8
 
@@ -27,7 +27,7 @@ cargo install
27
27
  # {'=' * 150}
28
28
  # """)
29
29
  # if platform.system() == "Windows":
30
- # Terminal(stdout=None).run(f". {PathExtended.tmpfile(suffix='.ps1').write_text(script)}", shell="pwsh").print()
30
+ # Terminal(stdout=None).run(f". {PathExtended.tmpfile(suffix='.ps1').write_text(script, encoding="utf-8")}", shell="pwsh").print()
31
31
  # else:
32
32
  # Terminal(stdout=None).run(script, shell="pwsh")
33
33
 
@@ -15,9 +15,9 @@ def select_interpreter(workspace_root: str):
15
15
  📂 Workspace: {workspace_root}
16
16
  {'=' * 150}
17
17
  """)
18
-
18
+
19
19
  path = Path(workspace_root).joinpath('.ve_path')
20
-
20
+
21
21
  if not path.exists():
22
22
  print(f"""
23
23
  {'⚠️' * 20}
@@ -26,12 +26,12 @@ def select_interpreter(workspace_root: str):
26
26
  {'⚠️' * 20}
27
27
  """)
28
28
  return
29
-
29
+
30
30
  with open(path, 'r', encoding='utf-8') as f:
31
31
  ve_path = Path(f.read().strip()).expanduser()
32
-
32
+
33
33
  venv_link = Path(workspace_root).joinpath(".venv")
34
-
34
+
35
35
  if venv_link.exists() and not venv_link.is_symlink():
36
36
  print(f"""
37
37
  {'⚠️' * 20}
@@ -40,9 +40,9 @@ def select_interpreter(workspace_root: str):
40
40
  {'⚠️' * 20}
41
41
  """)
42
42
  return
43
-
43
+
44
44
  venv_link.symlink_to(target=ve_path.expanduser().absolute())
45
-
45
+
46
46
  print(f"""
47
47
  {'=' * 150}
48
48
  ✅ SUCCESS | Virtual environment linked successfully