machineconfig 2.0__py3-none-any.whl → 2.1__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 (235) hide show
  1. machineconfig/cluster/cloud_manager.py +0 -3
  2. machineconfig/cluster/data_transfer.py +0 -1
  3. machineconfig/cluster/file_manager.py +0 -1
  4. machineconfig/cluster/job_params.py +0 -3
  5. machineconfig/cluster/loader_runner.py +0 -3
  6. machineconfig/cluster/remote_machine.py +0 -1
  7. machineconfig/cluster/script_notify_upon_completion.py +0 -1
  8. machineconfig/cluster/sessions_managers/archive/create_zellij_template.py +3 -5
  9. machineconfig/cluster/sessions_managers/archive/session_managers.py +0 -1
  10. machineconfig/cluster/sessions_managers/enhanced_command_runner.py +17 -57
  11. machineconfig/cluster/sessions_managers/wt_local.py +36 -110
  12. machineconfig/cluster/sessions_managers/wt_local_manager.py +42 -112
  13. machineconfig/cluster/sessions_managers/wt_remote.py +23 -30
  14. machineconfig/cluster/sessions_managers/wt_remote_manager.py +20 -62
  15. machineconfig/cluster/sessions_managers/wt_utils/layout_generator.py +10 -15
  16. machineconfig/cluster/sessions_managers/wt_utils/process_monitor.py +27 -127
  17. machineconfig/cluster/sessions_managers/wt_utils/remote_executor.py +10 -43
  18. machineconfig/cluster/sessions_managers/wt_utils/session_manager.py +22 -101
  19. machineconfig/cluster/sessions_managers/wt_utils/status_reporter.py +11 -39
  20. machineconfig/cluster/sessions_managers/zellij_local.py +49 -102
  21. machineconfig/cluster/sessions_managers/zellij_local_manager.py +34 -78
  22. machineconfig/cluster/sessions_managers/zellij_remote.py +17 -24
  23. machineconfig/cluster/sessions_managers/zellij_remote_manager.py +7 -13
  24. machineconfig/cluster/sessions_managers/zellij_utils/example_usage.py +4 -2
  25. machineconfig/cluster/sessions_managers/zellij_utils/layout_generator.py +6 -6
  26. machineconfig/cluster/sessions_managers/zellij_utils/process_monitor.py +18 -88
  27. machineconfig/cluster/sessions_managers/zellij_utils/remote_executor.py +2 -6
  28. machineconfig/cluster/sessions_managers/zellij_utils/session_manager.py +12 -40
  29. machineconfig/cluster/sessions_managers/zellij_utils/status_reporter.py +3 -2
  30. machineconfig/cluster/templates/cli_click.py +0 -1
  31. machineconfig/cluster/templates/cli_gooey.py +0 -2
  32. machineconfig/cluster/templates/cli_trogon.py +0 -1
  33. machineconfig/cluster/templates/run_cloud.py +0 -1
  34. machineconfig/cluster/templates/run_cluster.py +0 -1
  35. machineconfig/cluster/templates/run_remote.py +0 -1
  36. machineconfig/cluster/templates/utils.py +26 -10
  37. machineconfig/jobs/__pycache__/__init__.cpython-313.pyc +0 -0
  38. machineconfig/jobs/linux/msc/cli_agents.sh +16 -0
  39. machineconfig/jobs/python/check_installations.py +1 -0
  40. machineconfig/jobs/python/create_bootable_media.py +0 -2
  41. machineconfig/jobs/python/python_ve_symlink.py +9 -11
  42. machineconfig/jobs/python/tasks.py +0 -1
  43. machineconfig/jobs/python/vscode/api.py +5 -5
  44. machineconfig/jobs/python/vscode/link_ve.py +13 -14
  45. machineconfig/jobs/python/vscode/select_interpreter.py +21 -22
  46. machineconfig/jobs/python/vscode/sync_code.py +9 -13
  47. machineconfig/jobs/python_custom_installers/__pycache__/__init__.cpython-313.pyc +0 -0
  48. machineconfig/jobs/python_custom_installers/archive/ngrok.py +13 -13
  49. machineconfig/jobs/python_custom_installers/dev/aider.py +7 -15
  50. machineconfig/jobs/python_custom_installers/dev/alacritty.py +9 -18
  51. machineconfig/jobs/python_custom_installers/dev/brave.py +10 -19
  52. machineconfig/jobs/python_custom_installers/dev/bypass_paywall.py +8 -15
  53. machineconfig/jobs/python_custom_installers/dev/code.py +14 -21
  54. machineconfig/jobs/python_custom_installers/dev/cursor.py +3 -14
  55. machineconfig/jobs/python_custom_installers/dev/docker_desktop.py +8 -7
  56. machineconfig/jobs/python_custom_installers/dev/espanso.py +15 -19
  57. machineconfig/jobs/python_custom_installers/dev/goes.py +5 -12
  58. machineconfig/jobs/python_custom_installers/dev/lvim.py +9 -17
  59. machineconfig/jobs/python_custom_installers/dev/nerdfont.py +12 -19
  60. machineconfig/jobs/python_custom_installers/dev/redis.py +12 -20
  61. machineconfig/jobs/python_custom_installers/dev/wezterm.py +12 -19
  62. machineconfig/jobs/python_custom_installers/dev/winget.py +5 -23
  63. machineconfig/jobs/python_custom_installers/docker.py +12 -21
  64. machineconfig/jobs/python_custom_installers/gh.py +11 -19
  65. machineconfig/jobs/python_custom_installers/hx.py +32 -16
  66. machineconfig/jobs/python_custom_installers/warp-cli.py +12 -20
  67. machineconfig/jobs/python_generic_installers/__pycache__/__init__.cpython-313.pyc +0 -0
  68. machineconfig/jobs/python_linux_installers/__pycache__/__init__.cpython-313.pyc +0 -0
  69. machineconfig/jobs/windows/archive/archive_pygraphviz.ps1 +1 -1
  70. machineconfig/jobs/windows/msc/cli_agents.bat +0 -0
  71. machineconfig/jobs/windows/msc/cli_agents.ps1 +0 -0
  72. machineconfig/jobs/windows/start_terminal.ps1 +1 -1
  73. machineconfig/profile/create.py +29 -22
  74. machineconfig/profile/create_hardlinks.py +26 -19
  75. machineconfig/profile/shell.py +51 -28
  76. machineconfig/scripts/__pycache__/__init__.cpython-313.pyc +0 -0
  77. machineconfig/scripts/cloud/init.sh +2 -2
  78. machineconfig/scripts/linux/checkout_versions +1 -1
  79. machineconfig/scripts/linux/choose_wezterm_theme +1 -1
  80. machineconfig/scripts/linux/cloud_copy +1 -1
  81. machineconfig/scripts/linux/cloud_manager +1 -1
  82. machineconfig/scripts/linux/cloud_mount +1 -1
  83. machineconfig/scripts/linux/cloud_repo_sync +1 -1
  84. machineconfig/scripts/linux/cloud_sync +1 -1
  85. machineconfig/scripts/linux/croshell +1 -1
  86. machineconfig/scripts/linux/devops +4 -6
  87. machineconfig/scripts/linux/fire +1 -1
  88. machineconfig/scripts/linux/fire_agents +3 -2
  89. machineconfig/scripts/linux/ftpx +1 -1
  90. machineconfig/scripts/linux/gh_models +1 -1
  91. machineconfig/scripts/linux/kill_process +1 -1
  92. machineconfig/scripts/linux/mcinit +1 -1
  93. machineconfig/scripts/linux/repos +1 -1
  94. machineconfig/scripts/linux/scheduler +1 -1
  95. machineconfig/scripts/linux/start_slidev +1 -1
  96. machineconfig/scripts/linux/start_terminals +1 -1
  97. machineconfig/scripts/linux/url2md +1 -1
  98. machineconfig/scripts/linux/warp-cli.sh +122 -0
  99. machineconfig/scripts/linux/wifi_conn +1 -1
  100. machineconfig/scripts/python/__pycache__/__init__.cpython-313.pyc +0 -0
  101. machineconfig/scripts/python/__pycache__/croshell.cpython-313.pyc +0 -0
  102. machineconfig/scripts/python/__pycache__/devops.cpython-313.pyc +0 -0
  103. machineconfig/scripts/python/__pycache__/devops_devapps_install.cpython-313.pyc +0 -0
  104. machineconfig/scripts/python/__pycache__/devops_update_repos.cpython-313.pyc +0 -0
  105. machineconfig/scripts/python/__pycache__/fire_jobs.cpython-313.pyc +0 -0
  106. machineconfig/scripts/python/ai/__init__.py +0 -0
  107. machineconfig/scripts/python/ai/__pycache__/__init__.cpython-313.pyc +0 -0
  108. machineconfig/scripts/python/ai/__pycache__/generate_files.cpython-313.pyc +0 -0
  109. machineconfig/scripts/python/ai/__pycache__/mcinit.cpython-313.pyc +0 -0
  110. machineconfig/scripts/python/ai/generate_files.py +84 -0
  111. machineconfig/scripts/python/ai/instructions/python/dev.instructions.md +2 -2
  112. machineconfig/scripts/python/ai/mcinit.py +7 -3
  113. machineconfig/scripts/python/ai/scripts/lint_and_type_check.sh +10 -5
  114. machineconfig/scripts/python/cloud_copy.py +1 -1
  115. machineconfig/scripts/python/cloud_mount.py +1 -1
  116. machineconfig/scripts/python/cloud_repo_sync.py +4 -4
  117. machineconfig/scripts/python/croshell.py +5 -3
  118. machineconfig/scripts/python/devops_add_identity.py +1 -1
  119. machineconfig/scripts/python/devops_add_ssh_key.py +1 -1
  120. machineconfig/scripts/python/devops_backup_retrieve.py +1 -1
  121. machineconfig/scripts/python/devops_update_repos.py +140 -52
  122. machineconfig/scripts/python/dotfile.py +1 -1
  123. machineconfig/scripts/python/fire_agents.py +28 -9
  124. machineconfig/scripts/python/fire_jobs.py +3 -4
  125. machineconfig/scripts/python/ftpx.py +2 -1
  126. machineconfig/scripts/python/helpers/__pycache__/__init__.cpython-313.pyc +0 -0
  127. machineconfig/scripts/python/helpers/__pycache__/helpers4.cpython-313.pyc +0 -0
  128. machineconfig/scripts/python/helpers/helpers2.py +2 -2
  129. machineconfig/scripts/python/helpers/helpers4.py +1 -2
  130. machineconfig/scripts/python/helpers/repo_sync_helpers.py +1 -1
  131. machineconfig/scripts/python/mount_nfs.py +1 -1
  132. machineconfig/scripts/python/mount_ssh.py +1 -1
  133. machineconfig/scripts/python/repos.py +1 -1
  134. machineconfig/scripts/python/start_slidev.py +1 -1
  135. machineconfig/scripts/python/wsl_windows_transfer.py +1 -1
  136. machineconfig/scripts/windows/checkout_version.ps1 +1 -3
  137. machineconfig/scripts/windows/choose_wezterm_theme.ps1 +1 -3
  138. machineconfig/scripts/windows/cloud_copy.ps1 +2 -6
  139. machineconfig/scripts/windows/cloud_manager.ps1 +1 -1
  140. machineconfig/scripts/windows/cloud_repo_sync.ps1 +1 -2
  141. machineconfig/scripts/windows/cloud_sync.ps1 +2 -2
  142. machineconfig/scripts/windows/croshell.ps1 +2 -2
  143. machineconfig/scripts/windows/devops.ps1 +1 -4
  144. machineconfig/scripts/windows/dotfile.ps1 +1 -3
  145. machineconfig/scripts/windows/fire.ps1 +1 -1
  146. machineconfig/scripts/windows/ftpx.ps1 +2 -2
  147. machineconfig/scripts/windows/gpt.ps1 +1 -1
  148. machineconfig/scripts/windows/kill_process.ps1 +1 -2
  149. machineconfig/scripts/windows/mcinit.ps1 +1 -1
  150. machineconfig/scripts/windows/mount_nfs.ps1 +1 -1
  151. machineconfig/scripts/windows/mount_ssh.ps1 +1 -1
  152. machineconfig/scripts/windows/pomodoro.ps1 +1 -1
  153. machineconfig/scripts/windows/py2exe.ps1 +1 -3
  154. machineconfig/scripts/windows/repos.ps1 +1 -1
  155. machineconfig/scripts/windows/scheduler.ps1 +1 -1
  156. machineconfig/scripts/windows/snapshot.ps1 +2 -2
  157. machineconfig/scripts/windows/start_slidev.ps1 +1 -1
  158. machineconfig/scripts/windows/start_terminals.ps1 +1 -1
  159. machineconfig/scripts/windows/wifi_conn.ps1 +1 -1
  160. machineconfig/scripts/windows/wsl_windows_transfer.ps1 +1 -3
  161. machineconfig/settings/lf/linux/lfrc +1 -1
  162. machineconfig/settings/linters/.ruff_cache/.gitignore +2 -0
  163. machineconfig/settings/linters/.ruff_cache/CACHEDIR.TAG +1 -0
  164. machineconfig/settings/lvim/windows/archive/config_additional.lua +1 -1
  165. machineconfig/settings/svim/linux/init.toml +1 -1
  166. machineconfig/settings/svim/windows/init.toml +1 -1
  167. machineconfig/setup_linux/web_shortcuts/croshell.sh +0 -54
  168. machineconfig/setup_linux/web_shortcuts/interactive.sh +6 -6
  169. machineconfig/setup_windows/web_shortcuts/all.ps1 +2 -2
  170. machineconfig/setup_windows/web_shortcuts/ascii_art.ps1 +1 -1
  171. machineconfig/setup_windows/web_shortcuts/croshell.ps1 +1 -1
  172. machineconfig/setup_windows/web_shortcuts/interactive.ps1 +5 -5
  173. machineconfig/setup_windows/wt_and_pwsh/install_fonts.ps1 +51 -15
  174. machineconfig/setup_windows/wt_and_pwsh/set_pwsh_theme.py +66 -12
  175. machineconfig/setup_windows/wt_and_pwsh/set_wt_settings.py +44 -36
  176. machineconfig/utils/ai/generate_file_checklist.py +8 -10
  177. machineconfig/utils/ai/url2md.py +4 -2
  178. machineconfig/utils/cloud/onedrive/setup_oauth.py +1 -0
  179. machineconfig/utils/cloud/onedrive/transaction.py +63 -98
  180. machineconfig/utils/code.py +60 -39
  181. machineconfig/utils/installer.py +27 -33
  182. machineconfig/utils/installer_utils/installer_abc.py +8 -7
  183. machineconfig/utils/installer_utils/installer_class.py +149 -70
  184. machineconfig/utils/links.py +22 -11
  185. machineconfig/utils/notifications.py +197 -0
  186. machineconfig/utils/options.py +29 -23
  187. machineconfig/utils/path.py +13 -6
  188. machineconfig/utils/path_reduced.py +485 -216
  189. machineconfig/utils/procs.py +47 -41
  190. machineconfig/utils/scheduling.py +0 -1
  191. machineconfig/utils/ssh.py +157 -76
  192. machineconfig/utils/terminal.py +82 -37
  193. machineconfig/utils/utils.py +12 -10
  194. machineconfig/utils/utils2.py +38 -48
  195. machineconfig/utils/utils5.py +183 -116
  196. machineconfig/utils/ve.py +9 -4
  197. {machineconfig-2.0.dist-info → machineconfig-2.1.dist-info}/METADATA +3 -2
  198. {machineconfig-2.0.dist-info → machineconfig-2.1.dist-info}/RECORD +200 -217
  199. machineconfig/jobs/__pycache__/__init__.cpython-311.pyc +0 -0
  200. machineconfig/jobs/python/__pycache__/__init__.cpython-311.pyc +0 -0
  201. machineconfig/jobs/python/__pycache__/python_ve_symlink.cpython-311.pyc +0 -0
  202. machineconfig/jobs/python/archive/python_tools.txt +0 -12
  203. machineconfig/jobs/python/vscode/__pycache__/select_interpreter.cpython-311.pyc +0 -0
  204. machineconfig/jobs/python_custom_installers/__pycache__/__init__.cpython-311.pyc +0 -0
  205. machineconfig/jobs/python_generic_installers/__pycache__/__init__.cpython-311.pyc +0 -0
  206. machineconfig/jobs/python_generic_installers/update.py +0 -3
  207. machineconfig/jobs/python_linux_installers/__pycache__/__init__.cpython-311.pyc +0 -0
  208. machineconfig/profile/__pycache__/__init__.cpython-311.pyc +0 -0
  209. machineconfig/profile/__pycache__/create.cpython-311.pyc +0 -0
  210. machineconfig/profile/__pycache__/shell.cpython-311.pyc +0 -0
  211. machineconfig/scripts/__pycache__/__init__.cpython-311.pyc +0 -0
  212. machineconfig/scripts/linux/activate_ve +0 -87
  213. machineconfig/scripts/python/__pycache__/__init__.cpython-311.pyc +0 -0
  214. machineconfig/scripts/python/__pycache__/cloud_copy.cpython-311.pyc +0 -0
  215. machineconfig/scripts/python/__pycache__/cloud_mount.cpython-311.pyc +0 -0
  216. machineconfig/scripts/python/__pycache__/cloud_sync.cpython-311.pyc +0 -0
  217. machineconfig/scripts/python/__pycache__/croshell.cpython-311.pyc +0 -0
  218. machineconfig/scripts/python/__pycache__/devops.cpython-311.pyc +0 -0
  219. machineconfig/scripts/python/__pycache__/devops_backup_retrieve.cpython-311.pyc +0 -0
  220. machineconfig/scripts/python/__pycache__/devops_devapps_install.cpython-311.pyc +0 -0
  221. machineconfig/scripts/python/__pycache__/devops_update_repos.cpython-311.pyc +0 -0
  222. machineconfig/scripts/python/__pycache__/fire_agents.cpython-311.pyc +0 -0
  223. machineconfig/scripts/python/__pycache__/fire_jobs.cpython-311.pyc +0 -0
  224. machineconfig/scripts/python/__pycache__/get_zellij_cmd.cpython-311.pyc +0 -0
  225. machineconfig/scripts/python/__pycache__/repos.cpython-311.pyc +0 -0
  226. machineconfig/scripts/python/ai/__pycache__/init.cpython-311.pyc +0 -0
  227. machineconfig/scripts/python/ai/__pycache__/mcinit.cpython-311.pyc +0 -0
  228. machineconfig/scripts/python/helpers/__pycache__/__init__.cpython-311.pyc +0 -0
  229. machineconfig/scripts/python/helpers/__pycache__/cloud_helpers.cpython-311.pyc +0 -0
  230. machineconfig/scripts/python/helpers/__pycache__/helpers2.cpython-311.pyc +0 -0
  231. machineconfig/scripts/python/helpers/__pycache__/helpers4.cpython-311.pyc +0 -0
  232. machineconfig/scripts/python/helpers/__pycache__/repo_sync_helpers.cpython-311.pyc +0 -0
  233. machineconfig/scripts/windows/activate_ve.ps1 +0 -54
  234. {machineconfig-2.0.dist-info → machineconfig-2.1.dist-info}/WHEEL +0 -0
  235. {machineconfig-2.0.dist-info → machineconfig-2.1.dist-info}/top_level.txt +0 -0
@@ -21,7 +21,6 @@ TMP_LAYOUT_DIR = Path.home().joinpath("tmp_results", "zellij_layouts", "layout_m
21
21
 
22
22
 
23
23
  class ZellijRemoteLayoutGenerator:
24
-
25
24
  def __init__(self, remote_name: str, session_name_prefix: str):
26
25
  self.remote_name = remote_name
27
26
  self.session_name = session_name_prefix + "_" + LayoutGenerator.generate_random_suffix()
@@ -96,14 +95,7 @@ class ZellijRemoteLayoutGenerator:
96
95
  return executor.run_command(command, timeout)
97
96
 
98
97
  def to_dict(self) -> Dict[str, Any]:
99
- return {
100
- "remote_name": self.remote_name,
101
- "session_name": self.session_name,
102
- "tab_config": self.tab_config,
103
- "layout_path": self.layout_path,
104
- "created_at": datetime.now().isoformat(),
105
- "class_name": self.__class__.__name__
106
- }
98
+ return {"remote_name": self.remote_name, "session_name": self.session_name, "tab_config": self.tab_config, "layout_path": self.layout_path, "created_at": datetime.now().isoformat(), "class_name": self.__class__.__name__}
107
99
 
108
100
  def to_json(self, file_path: Optional[Union[str, Path]] = None) -> str:
109
101
  # Generate file path if not provided
@@ -116,8 +108,8 @@ class ZellijRemoteLayoutGenerator:
116
108
  file_path_obj = Path(file_path)
117
109
 
118
110
  # Ensure .json extension
119
- if not str(file_path_obj).endswith('.json'):
120
- file_path_obj = file_path_obj.with_suffix('.json')
111
+ if not str(file_path_obj).endswith(".json"):
112
+ file_path_obj = file_path_obj.with_suffix(".json")
121
113
 
122
114
  # Ensure parent directory exists
123
115
  file_path_obj.parent.mkdir(parents=True, exist_ok=True)
@@ -132,38 +124,38 @@ class ZellijRemoteLayoutGenerator:
132
124
  return str(file_path_obj)
133
125
 
134
126
  @classmethod
135
- def from_json(cls, file_path: Union[str, Path]) -> 'ZellijRemoteLayoutGenerator':
127
+ def from_json(cls, file_path: Union[str, Path]) -> "ZellijRemoteLayoutGenerator":
136
128
  file_path = Path(file_path)
137
129
 
138
130
  # Ensure .json extension
139
- if not str(file_path).endswith('.json'):
140
- file_path = file_path.with_suffix('.json')
131
+ if not str(file_path).endswith(".json"):
132
+ file_path = file_path.with_suffix(".json")
141
133
 
142
134
  if not file_path.exists():
143
135
  raise FileNotFoundError(f"JSON file not found: {file_path}")
144
136
 
145
137
  # Load JSON data
146
- with open(file_path, 'r', encoding='utf-8') as f:
138
+ with open(file_path, "r", encoding="utf-8") as f:
147
139
  data = json.load(f)
148
140
 
149
141
  # Validate that it's the correct class
150
- if data.get('class_name') != cls.__name__:
142
+ if data.get("class_name") != cls.__name__:
151
143
  logger.warning(f"Class name mismatch: expected {cls.__name__}, got {data.get('class_name')}")
152
144
 
153
145
  # Create new instance
154
146
  # Extract session name prefix by removing the suffix
155
- session_name = data['session_name']
156
- if '_' in session_name:
157
- session_name_prefix = '_'.join(session_name.split('_')[:-1])
147
+ session_name = data["session_name"]
148
+ if "_" in session_name:
149
+ session_name_prefix = "_".join(session_name.split("_")[:-1])
158
150
  else:
159
151
  session_name_prefix = session_name
160
152
 
161
- instance = cls(remote_name=data['remote_name'], session_name_prefix=session_name_prefix)
153
+ instance = cls(remote_name=data["remote_name"], session_name_prefix=session_name_prefix)
162
154
 
163
155
  # Restore state
164
- instance.session_name = data['session_name']
165
- instance.tab_config = data['tab_config']
166
- instance.layout_path = data['layout_path']
156
+ instance.session_name = data["session_name"]
157
+ instance.tab_config = data["tab_config"]
158
+ instance.layout_path = data["layout_path"]
167
159
 
168
160
  logger.info(f"✅ Loaded ZellijRemoteLayoutGenerator from: {file_path}")
169
161
  return instance
@@ -181,13 +173,14 @@ class ZellijRemoteLayoutGenerator:
181
173
  json_files = [f.name for f in directory_path.glob("*.json")]
182
174
  return sorted(json_files)
183
175
 
176
+
184
177
  if __name__ == "__main__":
185
178
  # Example usage
186
179
  sample_tabs = {
187
180
  "🤖Bot1": ("~/code/bytesense/bithence", "~/scripts/fire -mO go1.py bot1 --kw create_new_bot True"),
188
181
  "🤖Bot2": ("~/code/bytesense/bithence", "~/scripts/fire -mO go2.py bot2 --kw create_new_bot True"),
189
182
  "📊Monitor": ("~", "htop"),
190
- "📝Logs": ("/var/log", "tail -f /var/log/app.log")
183
+ "📝Logs": ("/var/log", "tail -f /var/log/app.log"),
191
184
  }
192
185
 
193
186
  # Replace 'myserver' with an actual SSH config alias
@@ -39,10 +39,7 @@ class ZellijSessionManager:
39
39
 
40
40
  def kill_all_sessions(self) -> None:
41
41
  for an_m in self.managers:
42
- ZellijRemoteLayoutGenerator.run_remote_command(
43
- remote_name=an_m.remote_name,
44
- command="zellij kill-all-sessions --yes"
45
- )
42
+ ZellijRemoteLayoutGenerator.run_remote_command(remote_name=an_m.remote_name, command="zellij kill-all-sessions --yes")
46
43
 
47
44
  def start_zellij_sessions(self) -> None:
48
45
  for an_m in self.managers:
@@ -84,6 +81,7 @@ class ZellijSessionManager:
84
81
  # Print statuses
85
82
  for i, status in enumerate(statuses):
86
83
  print(f"Manager {i}: {status}")
84
+
87
85
  sched = Scheduler(routine=routine, wait_ms=60_000, logger=logger)
88
86
  sched.run()
89
87
 
@@ -101,12 +99,7 @@ class ZellijSessionManager:
101
99
  config_file.write_text(text, encoding="utf-8")
102
100
 
103
101
  # Save session metadata
104
- metadata = {
105
- "session_name_prefix": self.session_name_prefix,
106
- "created_at": str(datetime.now()),
107
- "num_managers": len(self.managers),
108
- "machines": list(self.machine2zellij_tabs.keys())
109
- }
102
+ metadata = {"session_name_prefix": self.session_name_prefix, "created_at": str(datetime.now()), "num_managers": len(self.managers), "machines": list(self.machine2zellij_tabs.keys())}
110
103
  metadata_file = session_dir / "metadata.json"
111
104
  text = json.dumps(metadata, indent=2, ensure_ascii=False)
112
105
  metadata_file.write_text(text, encoding="utf-8")
@@ -122,7 +115,7 @@ class ZellijSessionManager:
122
115
  return session_id
123
116
 
124
117
  @classmethod
125
- def load(cls, session_id: str) -> 'ZellijSessionManager':
118
+ def load(cls, session_id: str) -> "ZellijSessionManager":
126
119
  session_dir = TMP_SERIALIAZATION_DIR / session_id
127
120
 
128
121
  if not session_dir.exists():
@@ -130,14 +123,14 @@ class ZellijSessionManager:
130
123
  config_file = session_dir / "machine2zellij_tabs.json"
131
124
  if not config_file.exists():
132
125
  raise FileNotFoundError(f"Configuration file not found: {config_file}")
133
- with open(config_file, 'r', encoding='utf-8') as f:
126
+ with open(config_file, "r", encoding="utf-8") as f:
134
127
  machine2zellij_tabs = json.load(f)
135
128
 
136
129
  # Load metadata
137
130
  metadata_file = session_dir / "metadata.json"
138
131
  session_name_prefix = "JobMgr" # default fallback
139
132
  if metadata_file.exists():
140
- with open(metadata_file, 'r', encoding='utf-8') as f:
133
+ with open(metadata_file, "r", encoding="utf-8") as f:
141
134
  metadata = json.load(f)
142
135
  session_name_prefix = metadata.get("session_name_prefix", "JobMgr")
143
136
  # Create new instance (this will create new managers)
@@ -180,6 +173,7 @@ class ZellijSessionManager:
180
173
 
181
174
  try:
182
175
  import shutil
176
+
183
177
  shutil.rmtree(session_dir)
184
178
  logger.info(f"✅ Deleted session: {session_id}")
185
179
  return True
@@ -5,6 +5,7 @@ Example usage of the modularized Zellij remote layout generator.
5
5
 
6
6
  from machineconfig.cluster.sessions_managers.zellij_remote import ZellijRemoteLayoutGenerator
7
7
 
8
+
8
9
  def example_usage():
9
10
  """Demonstrate the refactored modular usage."""
10
11
 
@@ -13,7 +14,7 @@ def example_usage():
13
14
  "🤖Bot1": ("~/code/bytesense/bithence", "~/scripts/fire -mO go1.py bot1 --kw create_new_bot True"),
14
15
  "🤖Bot2": ("~/code/bytesense/bithence", "~/scripts/fire -mO go2.py bot2 --kw create_new_bot True"),
15
16
  "📊Monitor": ("~", "htop"),
16
- "📝Logs": ("/var/log", "tail -f /var/log/app.log")
17
+ "📝Logs": ("/var/log", "tail -f /var/log/app.log"),
17
18
  }
18
19
 
19
20
  # Replace 'myserver' with an actual SSH config alias
@@ -37,7 +38,7 @@ def example_usage():
37
38
  generator.print_status_report()
38
39
 
39
40
  # The individual components can also be used directly:
40
- print(f"\n🔧 Direct component usage examples:")
41
+ print("\n🔧 Direct component usage examples:")
41
42
 
42
43
  # Use remote executor directly
43
44
  print(f"Remote executor: {generator.remote_executor.remote_name}")
@@ -60,5 +61,6 @@ def example_usage():
60
61
  except Exception as e:
61
62
  print(f"❌ Error: {e}")
62
63
 
64
+
63
65
  if __name__ == "__main__":
64
66
  example_usage()
@@ -2,6 +2,7 @@
2
2
  """
3
3
  Zellij layout generation utilities for creating KDL layout files.
4
4
  """
5
+
5
6
  import shlex
6
7
  import random
7
8
  import string
@@ -31,7 +32,7 @@ class LayoutGenerator:
31
32
  @staticmethod
32
33
  def generate_random_suffix(length: int = 8) -> str:
33
34
  """Generate a random string suffix for unique layout file names."""
34
- return ''.join(random.choices(string.ascii_lowercase + string.digits, k=length))
35
+ return "".join(random.choices(string.ascii_lowercase + string.digits, k=length))
35
36
 
36
37
  @staticmethod
37
38
  def parse_command(command: str) -> Tuple[str, List[str]]:
@@ -53,7 +54,7 @@ class LayoutGenerator:
53
54
  return ""
54
55
  formatted_args = []
55
56
  for arg in args:
56
- if ' ' in arg or '"' in arg or "'" in arg:
57
+ if " " in arg or '"' in arg or "'" in arg:
57
58
  escaped_arg = arg.replace('"', '\\"')
58
59
  formatted_args.append(f'"{escaped_arg}"')
59
60
  else:
@@ -71,8 +72,8 @@ class LayoutGenerator:
71
72
  tab_section = f' tab name="{escaped_tab_name}" cwd="{tab_cwd}" {{\n'
72
73
  tab_section += f' pane command="{cmd}" {{\n'
73
74
  if args_str:
74
- tab_section += f' args {args_str}\n'
75
- tab_section += ' }\n }\n'
75
+ tab_section += f" args {args_str}\n"
76
+ tab_section += " }\n }\n"
76
77
  return tab_section
77
78
 
78
79
  @staticmethod
@@ -99,8 +100,7 @@ class LayoutGenerator:
99
100
 
100
101
  return layout_content
101
102
 
102
- def create_layout_file(self, tab_config: Dict[str, Tuple[str, str]],
103
- output_dir: Path, session_name: str) -> str:
103
+ def create_layout_file(self, tab_config: Dict[str, Tuple[str, str]], output_dir: Path, session_name: str) -> str:
104
104
  """Create a layout file and return its absolute path."""
105
105
  self.validate_tab_config(tab_config)
106
106
 
@@ -2,6 +2,7 @@
2
2
  """
3
3
  Process monitoring and status checking utilities for remote commands.
4
4
  """
5
+
5
6
  import json
6
7
  import shlex
7
8
  import logging
@@ -17,18 +18,10 @@ class ProcessMonitor:
17
18
  def __init__(self, remote_executor: RemoteExecutor):
18
19
  self.remote_executor = remote_executor
19
20
 
20
- def check_command_status(self, tab_name: str, tab_config: Dict[str, Tuple[str, str]],
21
- use_verification: bool = True) -> Dict[str, Any]:
21
+ def check_command_status(self, tab_name: str, tab_config: Dict[str, Tuple[str, str]], 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:
24
- return {
25
- "status": "unknown",
26
- "error": f"Tab '{tab_name}' not found in tracked configuration",
27
- "running": False,
28
- "pid": None,
29
- "command": None,
30
- "remote": self.remote_executor.remote_name
31
- }
24
+ return {"status": "unknown", "error": f"Tab '{tab_name}' not found in tracked configuration", "running": False, "pid": None, "command": None, "remote": self.remote_executor.remote_name}
32
25
 
33
26
  # Use the verified method by default for more accurate results
34
27
  if use_verification:
@@ -42,7 +35,7 @@ class ProcessMonitor:
42
35
 
43
36
  try:
44
37
  check_script = self._create_process_check_script(command)
45
- remote_cmd = f"$HOME/venvs/ve/bin/python -c {shlex.quote(check_script)}"
38
+ remote_cmd = f"$HOME/code/machineconfig/.venv/bin/python -c {shlex.quote(check_script)}"
46
39
  result = self.remote_executor.run_command(remote_cmd, timeout=15)
47
40
 
48
41
  if result.returncode == 0:
@@ -50,53 +43,18 @@ class ProcessMonitor:
50
43
  matching_processes = json.loads(result.stdout.strip())
51
44
 
52
45
  if matching_processes:
53
- return {
54
- "status": "running",
55
- "running": True,
56
- "processes": matching_processes,
57
- "command": command,
58
- "tab_name": tab_name,
59
- "remote": self.remote_executor.remote_name
60
- }
46
+ return {"status": "running", "running": True, "processes": matching_processes, "command": command, "tab_name": tab_name, "remote": self.remote_executor.remote_name}
61
47
  else:
62
- return {
63
- "status": "not_running",
64
- "running": False,
65
- "processes": [],
66
- "command": command,
67
- "tab_name": tab_name,
68
- "remote": self.remote_executor.remote_name
69
- }
48
+ return {"status": "not_running", "running": False, "processes": [], "command": command, "tab_name": tab_name, "remote": self.remote_executor.remote_name}
70
49
  except json.JSONDecodeError as e:
71
50
  logger.error(f"Failed to parse remote process check output: {e}")
72
- return {
73
- "status": "error",
74
- "error": f"Failed to parse remote output: {e}",
75
- "running": False,
76
- "command": command,
77
- "tab_name": tab_name,
78
- "remote": self.remote_executor.remote_name
79
- }
51
+ return {"status": "error", "error": f"Failed to parse remote output: {e}", "running": False, "command": command, "tab_name": tab_name, "remote": self.remote_executor.remote_name}
80
52
  else:
81
- return {
82
- "status": "error",
83
- "error": f"Remote command failed: {result.stderr}",
84
- "running": False,
85
- "command": command,
86
- "tab_name": tab_name,
87
- "remote": self.remote_executor.remote_name
88
- }
53
+ return {"status": "error", "error": f"Remote command failed: {result.stderr}", "running": False, "command": command, "tab_name": tab_name, "remote": self.remote_executor.remote_name}
89
54
 
90
55
  except Exception as e:
91
56
  logger.error(f"Error checking command status for tab '{tab_name}': {e}")
92
- return {
93
- "status": "error",
94
- "error": str(e),
95
- "running": False,
96
- "command": command,
97
- "tab_name": tab_name,
98
- "remote": self.remote_executor.remote_name
99
- }
57
+ return {"status": "error", "error": str(e), "running": False, "command": command, "tab_name": tab_name, "remote": self.remote_executor.remote_name}
100
58
 
101
59
  def _create_process_check_script(self, command: str) -> str:
102
60
  """Create Python script for checking processes on remote machine."""
@@ -151,13 +109,7 @@ if __name__ == "__main__":
151
109
  def force_fresh_process_check(self, tab_name: str, tab_config: Dict[str, Tuple[str, str]]) -> Dict[str, Any]:
152
110
  """Force a fresh process check with additional validation."""
153
111
  if tab_name not in tab_config:
154
- return {
155
- "status": "unknown",
156
- "error": f"Tab '{tab_name}' not found in tracked configuration",
157
- "running": False,
158
- "command": None,
159
- "remote": self.remote_executor.remote_name
160
- }
112
+ return {"status": "unknown", "error": f"Tab '{tab_name}' not found in tracked configuration", "running": False, "command": None, "remote": self.remote_executor.remote_name}
161
113
 
162
114
  _, command = tab_config[tab_name]
163
115
 
@@ -167,7 +119,7 @@ if __name__ == "__main__":
167
119
  check_timestamp = timestamp_result.stdout.strip() if timestamp_result.returncode == 0 else "unknown"
168
120
 
169
121
  check_script = self._create_fresh_check_script(command)
170
- remote_cmd = f"$HOME/venvs/ve/bin/python -c {shlex.quote(check_script)}"
122
+ remote_cmd = f"$HOME/code/machineconfig/.venv/bin/python -c {shlex.quote(check_script)}"
171
123
  result = self.remote_executor.run_command(remote_cmd, timeout=15)
172
124
 
173
125
  if result.returncode == 0:
@@ -183,45 +135,23 @@ if __name__ == "__main__":
183
135
  "tab_name": tab_name,
184
136
  "remote": self.remote_executor.remote_name,
185
137
  "check_timestamp": check_timestamp,
186
- "method": "force_fresh_check"
138
+ "method": "force_fresh_check",
187
139
  }
188
140
  except json.JSONDecodeError as e:
189
141
  logger.error(f"Failed to parse fresh check output: {e}")
190
- return {
191
- "status": "error",
192
- "error": f"Failed to parse output: {e}",
193
- "running": False,
194
- "command": command,
195
- "tab_name": tab_name,
196
- "remote": self.remote_executor.remote_name,
197
- "raw_output": result.stdout
198
- }
142
+ return {"status": "error", "error": f"Failed to parse output: {e}", "running": False, "command": command, "tab_name": tab_name, "remote": self.remote_executor.remote_name, "raw_output": result.stdout}
199
143
  else:
200
- return {
201
- "status": "error",
202
- "error": f"Remote command failed: {result.stderr}",
203
- "running": False,
204
- "command": command,
205
- "tab_name": tab_name,
206
- "remote": self.remote_executor.remote_name
207
- }
144
+ return {"status": "error", "error": f"Remote command failed: {result.stderr}", "running": False, "command": command, "tab_name": tab_name, "remote": self.remote_executor.remote_name}
208
145
 
209
146
  except Exception as e:
210
147
  logger.error(f"Error in fresh process check for tab '{tab_name}': {e}")
211
- return {
212
- "status": "error",
213
- "error": str(e),
214
- "running": False,
215
- "command": command,
216
- "tab_name": tab_name,
217
- "remote": self.remote_executor.remote_name
218
- }
148
+ return {"status": "error", "error": str(e), "running": False, "command": command, "tab_name": tab_name, "remote": self.remote_executor.remote_name}
219
149
 
220
150
  def _create_fresh_check_script(self, command: str) -> str:
221
151
  """Create enhanced process checking script with freshness validation."""
222
152
  escaped_command = command.replace("'", "\\'").replace('"', '\\"')
223
153
 
224
- return f'''
154
+ return f"""
225
155
  import psutil
226
156
  import json
227
157
  import os
@@ -286,7 +216,7 @@ def force_fresh_check():
286
216
  if __name__ == "__main__":
287
217
  result = force_fresh_check()
288
218
  print(json.dumps(result))
289
- '''
219
+ """
290
220
 
291
221
  def verify_process_alive(self, pid: int) -> bool:
292
222
  """Verify if a process with given PID is actually alive."""
@@ -295,7 +225,7 @@ if __name__ == "__main__":
295
225
  result = self.remote_executor.run_command(verify_cmd, timeout=5)
296
226
 
297
227
  if result.returncode == 0:
298
- return result.stdout.strip() == 'alive'
228
+ return result.stdout.strip() == "alive"
299
229
  return False
300
230
  except Exception:
301
231
  return False
@@ -2,6 +2,7 @@
2
2
  """
3
3
  Remote command execution utilities for SSH operations.
4
4
  """
5
+
5
6
  import subprocess
6
7
  import logging
7
8
  from typing import Dict, Any
@@ -19,12 +20,7 @@ class RemoteExecutor:
19
20
  """Execute a command on the remote machine via SSH."""
20
21
  ssh_cmd = ["ssh", self.remote_name, command]
21
22
  try:
22
- result = subprocess.run(
23
- ssh_cmd,
24
- capture_output=True,
25
- text=True,
26
- timeout=timeout
27
- )
23
+ result = subprocess.run(ssh_cmd, capture_output=True, text=True, timeout=timeout)
28
24
  return result
29
25
  except subprocess.TimeoutExpired:
30
26
  logger.error(f"SSH command timed out after {timeout}s: {command}")
@@ -2,6 +2,7 @@
2
2
  """
3
3
  Zellij session management utilities for remote operations.
4
4
  """
5
+
5
6
  import logging
6
7
  from typing import Dict, Any, Optional
7
8
  from pathlib import Path
@@ -43,34 +44,18 @@ class SessionManager:
43
44
  def check_zellij_session_status(self) -> Dict[str, Any]:
44
45
  """Check if the Zellij session exists and is running."""
45
46
  try:
46
- result = self.remote_executor.run_command('zellij list-sessions', timeout=10)
47
+ result = self.remote_executor.run_command("zellij list-sessions", timeout=10)
47
48
 
48
49
  if result.returncode == 0:
49
- sessions = result.stdout.strip().split('\n') if result.stdout.strip() else []
50
+ sessions = result.stdout.strip().split("\n") if result.stdout.strip() else []
50
51
  session_running = any(self.session_name in session for session in sessions)
51
52
 
52
- return {
53
- "zellij_running": True,
54
- "session_exists": session_running,
55
- "session_name": self.session_name,
56
- "all_sessions": sessions,
57
- "remote": self.remote_executor.remote_name
58
- }
53
+ return {"zellij_running": True, "session_exists": session_running, "session_name": self.session_name, "all_sessions": sessions, "remote": self.remote_executor.remote_name}
59
54
  else:
60
- return {
61
- "zellij_running": False,
62
- "error": result.stderr,
63
- "session_name": self.session_name,
64
- "remote": self.remote_executor.remote_name
65
- }
55
+ return {"zellij_running": False, "error": result.stderr, "session_name": self.session_name, "remote": self.remote_executor.remote_name}
66
56
 
67
57
  except Exception as e:
68
- return {
69
- "zellij_running": False,
70
- "error": str(e),
71
- "session_name": self.session_name,
72
- "remote": self.remote_executor.remote_name
73
- }
58
+ return {"zellij_running": False, "error": str(e), "session_name": self.session_name, "remote": self.remote_executor.remote_name}
74
59
 
75
60
  def start_zellij_session(self, layout_file_path: Optional[str] = None) -> Dict[str, Any]:
76
61
  """Start a Zellij session on the remote machine with the generated layout."""
@@ -82,7 +67,9 @@ class SessionManager:
82
67
  raise ValueError("No layout file path provided.")
83
68
 
84
69
  # Enhanced Rich logging for session start
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]")
70
+ console.print(
71
+ 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]"
72
+ )
86
73
 
87
74
  # Start Zellij session with layout
88
75
  start_cmd = f"zellij --layout {remote_layout_file} a -b {self.session_name}"
@@ -91,28 +78,13 @@ class SessionManager:
91
78
 
92
79
  if result.returncode == 0:
93
80
  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
- return {
95
- "success": True,
96
- "session_name": self.session_name,
97
- "remote": self.remote_executor.remote_name,
98
- "message": "Session started successfully"
99
- }
81
+ return {"success": True, "session_name": self.session_name, "remote": self.remote_executor.remote_name, "message": "Session started successfully"}
100
82
  else:
101
- return {
102
- "success": False,
103
- "error": result.stderr,
104
- "session_name": self.session_name,
105
- "remote": self.remote_executor.remote_name
106
- }
83
+ return {"success": False, "error": result.stderr, "session_name": self.session_name, "remote": self.remote_executor.remote_name}
107
84
 
108
85
  except Exception as e:
109
86
  logger.error(f"Failed to start Zellij session on {self.remote_executor.remote_name}: {e}")
110
- return {
111
- "success": False,
112
- "error": str(e),
113
- "session_name": self.session_name,
114
- "remote": self.remote_executor.remote_name
115
- }
87
+ return {"success": False, "error": str(e), "session_name": self.session_name, "remote": self.remote_executor.remote_name}
116
88
 
117
89
  def attach_to_session(self) -> None:
118
90
  """Attach to the Zellij session on the remote machine via SSH."""
@@ -2,6 +2,7 @@
2
2
  """
3
3
  Status reporting utilities for Zellij remote layouts.
4
4
  """
5
+
5
6
  import logging
6
7
  from typing import Dict, Any, Tuple
7
8
  from .process_monitor import ProcessMonitor
@@ -33,8 +34,8 @@ class StatusReporter:
33
34
  "running_commands": running_count,
34
35
  "stopped_commands": total_count - running_count,
35
36
  "session_healthy": zellij_status.get("session_exists", False),
36
- "remote": self.session_manager.remote_executor.remote_name
37
- }
37
+ "remote": self.session_manager.remote_executor.remote_name,
38
+ },
38
39
  }
39
40
 
40
41
  def print_status_report(self, tab_config: Dict[str, Tuple[str, str]]) -> None:
@@ -1,4 +1,3 @@
1
-
2
1
  # """Trogon
3
2
  # """
4
3
 
@@ -1,4 +1,3 @@
1
-
2
1
  # """Gooey
3
2
  # """
4
3
 
@@ -12,7 +11,6 @@
12
11
  # # from typing import Any, Optional
13
12
 
14
13
 
15
-
16
14
  # @Gooey(program_name="Cluster Launcher", program_description='Cofigure remote cluster and launch jobs.') # type: ignore
17
15
  # def main() -> RemoteMachineConfig:
18
16
  # # parser = GooeyParser(description='Example of Gooey\'s basic functionality')
@@ -1,4 +1,3 @@
1
-
2
1
  # """Trogon
3
2
  # """
4
3
 
@@ -1,4 +1,3 @@
1
-
2
1
  # """Run with sane defaults for a remote machine.
3
2
  # """
4
3
 
@@ -1,4 +1,3 @@
1
-
2
1
  # """
3
2
  # Cluster Template
4
3
  # """
@@ -1,4 +1,3 @@
1
-
2
1
  # """
3
2
  # This file contains a template for a remote machine. It is not meant to be run, but rather to be used as a template for
4
3
  # """