machineconfig 1.97__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 (268) hide show
  1. machineconfig/cluster/cloud_manager.py +22 -29
  2. machineconfig/cluster/data_transfer.py +2 -3
  3. machineconfig/cluster/distribute.py +0 -2
  4. machineconfig/cluster/file_manager.py +4 -5
  5. machineconfig/cluster/job_params.py +1 -4
  6. machineconfig/cluster/loader_runner.py +8 -11
  7. machineconfig/cluster/remote_machine.py +4 -5
  8. machineconfig/cluster/script_execution.py +2 -2
  9. machineconfig/cluster/script_notify_upon_completion.py +0 -1
  10. machineconfig/cluster/sessions_managers/archive/create_zellij_template.py +4 -6
  11. machineconfig/cluster/sessions_managers/archive/session_managers.py +0 -1
  12. machineconfig/cluster/sessions_managers/enhanced_command_runner.py +35 -75
  13. machineconfig/cluster/sessions_managers/wt_local.py +113 -185
  14. machineconfig/cluster/sessions_managers/wt_local_manager.py +127 -197
  15. machineconfig/cluster/sessions_managers/wt_remote.py +60 -67
  16. machineconfig/cluster/sessions_managers/wt_remote_manager.py +110 -149
  17. machineconfig/cluster/sessions_managers/wt_utils/layout_generator.py +61 -64
  18. machineconfig/cluster/sessions_managers/wt_utils/process_monitor.py +72 -172
  19. machineconfig/cluster/sessions_managers/wt_utils/remote_executor.py +27 -60
  20. machineconfig/cluster/sessions_managers/wt_utils/session_manager.py +58 -137
  21. machineconfig/cluster/sessions_managers/wt_utils/status_reporter.py +46 -74
  22. machineconfig/cluster/sessions_managers/zellij_local.py +91 -147
  23. machineconfig/cluster/sessions_managers/zellij_local_manager.py +165 -190
  24. machineconfig/cluster/sessions_managers/zellij_remote.py +51 -58
  25. machineconfig/cluster/sessions_managers/zellij_remote_manager.py +40 -46
  26. machineconfig/cluster/sessions_managers/zellij_utils/example_usage.py +19 -17
  27. machineconfig/cluster/sessions_managers/zellij_utils/layout_generator.py +30 -31
  28. machineconfig/cluster/sessions_managers/zellij_utils/process_monitor.py +64 -134
  29. machineconfig/cluster/sessions_managers/zellij_utils/remote_executor.py +7 -11
  30. machineconfig/cluster/sessions_managers/zellij_utils/session_manager.py +27 -55
  31. machineconfig/cluster/sessions_managers/zellij_utils/status_reporter.py +14 -13
  32. machineconfig/cluster/templates/cli_click.py +0 -1
  33. machineconfig/cluster/templates/cli_gooey.py +0 -2
  34. machineconfig/cluster/templates/cli_trogon.py +0 -1
  35. machineconfig/cluster/templates/run_cloud.py +0 -1
  36. machineconfig/cluster/templates/run_cluster.py +0 -1
  37. machineconfig/cluster/templates/run_remote.py +0 -1
  38. machineconfig/cluster/templates/utils.py +27 -11
  39. machineconfig/jobs/__pycache__/__init__.cpython-313.pyc +0 -0
  40. machineconfig/jobs/linux/msc/cli_agents.sh +16 -0
  41. machineconfig/jobs/python/check_installations.py +9 -9
  42. machineconfig/jobs/python/create_bootable_media.py +0 -2
  43. machineconfig/jobs/python/python_cargo_build_share.py +2 -2
  44. machineconfig/jobs/python/python_ve_symlink.py +9 -11
  45. machineconfig/jobs/python/tasks.py +0 -1
  46. machineconfig/jobs/python/vscode/api.py +5 -5
  47. machineconfig/jobs/python/vscode/link_ve.py +20 -21
  48. machineconfig/jobs/python/vscode/select_interpreter.py +28 -29
  49. machineconfig/jobs/python/vscode/sync_code.py +14 -18
  50. machineconfig/jobs/python_custom_installers/__pycache__/__init__.cpython-313.pyc +0 -0
  51. machineconfig/jobs/python_custom_installers/archive/ngrok.py +15 -15
  52. machineconfig/jobs/python_custom_installers/dev/aider.py +10 -18
  53. machineconfig/jobs/python_custom_installers/dev/alacritty.py +12 -21
  54. machineconfig/jobs/python_custom_installers/dev/brave.py +13 -22
  55. machineconfig/jobs/python_custom_installers/dev/bypass_paywall.py +13 -20
  56. machineconfig/jobs/python_custom_installers/dev/code.py +17 -24
  57. machineconfig/jobs/python_custom_installers/dev/cursor.py +10 -21
  58. machineconfig/jobs/python_custom_installers/dev/docker_desktop.py +12 -11
  59. machineconfig/jobs/python_custom_installers/dev/espanso.py +19 -23
  60. machineconfig/jobs/python_custom_installers/dev/goes.py +9 -16
  61. machineconfig/jobs/python_custom_installers/dev/lvim.py +13 -21
  62. machineconfig/jobs/python_custom_installers/dev/nerdfont.py +15 -22
  63. machineconfig/jobs/python_custom_installers/dev/redis.py +15 -23
  64. machineconfig/jobs/python_custom_installers/dev/wezterm.py +15 -22
  65. machineconfig/jobs/python_custom_installers/dev/winget.py +32 -50
  66. machineconfig/jobs/python_custom_installers/docker.py +15 -24
  67. machineconfig/jobs/python_custom_installers/gh.py +18 -26
  68. machineconfig/jobs/python_custom_installers/hx.py +33 -17
  69. machineconfig/jobs/python_custom_installers/warp-cli.py +15 -23
  70. machineconfig/jobs/python_generic_installers/__pycache__/__init__.cpython-313.pyc +0 -0
  71. machineconfig/jobs/python_generic_installers/config.json +412 -389
  72. machineconfig/jobs/python_linux_installers/__pycache__/__init__.cpython-313.pyc +0 -0
  73. machineconfig/jobs/python_windows_installers/dev/config.json +1 -1
  74. machineconfig/jobs/windows/archive/archive_pygraphviz.ps1 +1 -1
  75. machineconfig/jobs/windows/msc/cli_agents.bat +0 -0
  76. machineconfig/jobs/windows/msc/cli_agents.ps1 +0 -0
  77. machineconfig/jobs/windows/start_terminal.ps1 +1 -1
  78. machineconfig/logger.py +50 -0
  79. machineconfig/profile/create.py +50 -36
  80. machineconfig/profile/create_hardlinks.py +33 -26
  81. machineconfig/profile/shell.py +87 -60
  82. machineconfig/scripts/__pycache__/__init__.cpython-313.pyc +0 -0
  83. machineconfig/scripts/cloud/init.sh +2 -2
  84. machineconfig/scripts/linux/checkout_versions +1 -1
  85. machineconfig/scripts/linux/choose_wezterm_theme +1 -1
  86. machineconfig/scripts/linux/cloud_copy +1 -1
  87. machineconfig/scripts/linux/cloud_manager +1 -1
  88. machineconfig/scripts/linux/cloud_mount +1 -1
  89. machineconfig/scripts/linux/cloud_repo_sync +1 -1
  90. machineconfig/scripts/linux/cloud_sync +1 -1
  91. machineconfig/scripts/linux/croshell +1 -1
  92. machineconfig/scripts/linux/devops +3 -5
  93. machineconfig/scripts/linux/fire +2 -1
  94. machineconfig/scripts/linux/fire_agents +3 -3
  95. machineconfig/scripts/linux/ftpx +1 -1
  96. machineconfig/scripts/linux/gh_models +1 -1
  97. machineconfig/scripts/linux/kill_process +1 -1
  98. machineconfig/scripts/linux/mcinit +2 -2
  99. machineconfig/scripts/linux/repos +1 -1
  100. machineconfig/scripts/linux/scheduler +1 -1
  101. machineconfig/scripts/linux/start_slidev +1 -1
  102. machineconfig/scripts/linux/start_terminals +1 -1
  103. machineconfig/scripts/linux/url2md +1 -1
  104. machineconfig/scripts/linux/warp-cli.sh +122 -0
  105. machineconfig/scripts/linux/wifi_conn +1 -1
  106. machineconfig/scripts/python/__pycache__/__init__.cpython-313.pyc +0 -0
  107. machineconfig/scripts/python/__pycache__/croshell.cpython-313.pyc +0 -0
  108. machineconfig/scripts/python/__pycache__/devops.cpython-313.pyc +0 -0
  109. machineconfig/scripts/python/__pycache__/devops_devapps_install.cpython-313.pyc +0 -0
  110. machineconfig/scripts/python/__pycache__/devops_update_repos.cpython-313.pyc +0 -0
  111. machineconfig/scripts/python/__pycache__/fire_jobs.cpython-313.pyc +0 -0
  112. machineconfig/scripts/python/ai/__init__.py +0 -0
  113. machineconfig/scripts/python/ai/__pycache__/__init__.cpython-313.pyc +0 -0
  114. machineconfig/scripts/python/ai/__pycache__/generate_files.cpython-313.pyc +0 -0
  115. machineconfig/scripts/python/ai/__pycache__/mcinit.cpython-313.pyc +0 -0
  116. machineconfig/scripts/python/ai/chatmodes/Thinking-Beast-Mode.chatmode.md +337 -0
  117. machineconfig/scripts/python/ai/chatmodes/Ultimate-Transparent-Thinking-Beast-Mode.chatmode.md +644 -0
  118. machineconfig/scripts/python/ai/chatmodes/deepResearch.chatmode.md +81 -0
  119. machineconfig/scripts/python/ai/configs/.gemini/settings.json +81 -0
  120. machineconfig/scripts/python/ai/generate_files.py +84 -0
  121. machineconfig/scripts/python/ai/instructions/python/dev.instructions.md +45 -0
  122. machineconfig/scripts/python/ai/mcinit.py +107 -0
  123. machineconfig/scripts/python/ai/prompts/allLintersAndTypeCheckers.prompt.md +5 -0
  124. machineconfig/scripts/python/ai/prompts/research-report-skeleton.prompt.md +38 -0
  125. machineconfig/scripts/python/ai/scripts/lint_and_type_check.sh +52 -0
  126. machineconfig/scripts/python/archive/tmate_conn.py +5 -5
  127. machineconfig/scripts/python/archive/tmate_start.py +3 -3
  128. machineconfig/scripts/python/choose_wezterm_theme.py +2 -2
  129. machineconfig/scripts/python/cloud_copy.py +20 -19
  130. machineconfig/scripts/python/cloud_mount.py +10 -8
  131. machineconfig/scripts/python/cloud_repo_sync.py +15 -15
  132. machineconfig/scripts/python/cloud_sync.py +1 -1
  133. machineconfig/scripts/python/croshell.py +18 -16
  134. machineconfig/scripts/python/devops.py +6 -6
  135. machineconfig/scripts/python/devops_add_identity.py +9 -7
  136. machineconfig/scripts/python/devops_add_ssh_key.py +19 -19
  137. machineconfig/scripts/python/devops_backup_retrieve.py +14 -14
  138. machineconfig/scripts/python/devops_devapps_install.py +3 -3
  139. machineconfig/scripts/python/devops_update_repos.py +141 -53
  140. machineconfig/scripts/python/dotfile.py +3 -3
  141. machineconfig/scripts/python/fire_agents.py +202 -41
  142. machineconfig/scripts/python/fire_jobs.py +20 -21
  143. machineconfig/scripts/python/ftpx.py +4 -3
  144. machineconfig/scripts/python/gh_models.py +94 -94
  145. machineconfig/scripts/python/helpers/__pycache__/__init__.cpython-313.pyc +0 -0
  146. machineconfig/scripts/python/helpers/__pycache__/helpers4.cpython-313.pyc +0 -0
  147. machineconfig/scripts/python/helpers/cloud_helpers.py +3 -3
  148. machineconfig/scripts/python/helpers/helpers2.py +3 -3
  149. machineconfig/scripts/python/helpers/helpers4.py +8 -7
  150. machineconfig/scripts/python/helpers/helpers5.py +7 -7
  151. machineconfig/scripts/python/helpers/repo_sync_helpers.py +2 -2
  152. machineconfig/scripts/python/mount_nfs.py +4 -3
  153. machineconfig/scripts/python/mount_nw_drive.py +4 -4
  154. machineconfig/scripts/python/mount_ssh.py +4 -3
  155. machineconfig/scripts/python/repos.py +9 -9
  156. machineconfig/scripts/python/scheduler.py +1 -1
  157. machineconfig/scripts/python/start_slidev.py +9 -8
  158. machineconfig/scripts/python/start_terminals.py +1 -1
  159. machineconfig/scripts/python/viewer.py +40 -40
  160. machineconfig/scripts/python/wifi_conn.py +65 -66
  161. machineconfig/scripts/python/wsl_windows_transfer.py +2 -2
  162. machineconfig/scripts/windows/checkout_version.ps1 +1 -3
  163. machineconfig/scripts/windows/choose_wezterm_theme.ps1 +1 -3
  164. machineconfig/scripts/windows/cloud_copy.ps1 +2 -6
  165. machineconfig/scripts/windows/cloud_manager.ps1 +1 -1
  166. machineconfig/scripts/windows/cloud_repo_sync.ps1 +1 -2
  167. machineconfig/scripts/windows/cloud_sync.ps1 +2 -2
  168. machineconfig/scripts/windows/croshell.ps1 +2 -2
  169. machineconfig/scripts/windows/devops.ps1 +1 -4
  170. machineconfig/scripts/windows/dotfile.ps1 +1 -3
  171. machineconfig/scripts/windows/fire.ps1 +1 -1
  172. machineconfig/scripts/windows/ftpx.ps1 +2 -2
  173. machineconfig/scripts/windows/gpt.ps1 +1 -1
  174. machineconfig/scripts/windows/kill_process.ps1 +1 -2
  175. machineconfig/scripts/windows/mcinit.ps1 +2 -2
  176. machineconfig/scripts/windows/mount_nfs.ps1 +1 -1
  177. machineconfig/scripts/windows/mount_ssh.ps1 +1 -1
  178. machineconfig/scripts/windows/pomodoro.ps1 +1 -1
  179. machineconfig/scripts/windows/py2exe.ps1 +1 -3
  180. machineconfig/scripts/windows/repos.ps1 +1 -1
  181. machineconfig/scripts/windows/scheduler.ps1 +1 -1
  182. machineconfig/scripts/windows/snapshot.ps1 +2 -2
  183. machineconfig/scripts/windows/start_slidev.ps1 +1 -1
  184. machineconfig/scripts/windows/start_terminals.ps1 +1 -1
  185. machineconfig/scripts/windows/wifi_conn.ps1 +1 -1
  186. machineconfig/scripts/windows/wsl_windows_transfer.ps1 +1 -3
  187. machineconfig/settings/lf/linux/lfrc +1 -1
  188. machineconfig/settings/linters/.ruff.toml +2 -2
  189. machineconfig/settings/linters/.ruff_cache/.gitignore +2 -0
  190. machineconfig/settings/linters/.ruff_cache/CACHEDIR.TAG +1 -0
  191. machineconfig/settings/lvim/windows/archive/config_additional.lua +1 -1
  192. machineconfig/settings/shells/ipy/profiles/default/startup/playext.py +71 -71
  193. machineconfig/settings/shells/wt/settings.json +8 -8
  194. machineconfig/settings/svim/linux/init.toml +1 -1
  195. machineconfig/settings/svim/windows/init.toml +1 -1
  196. machineconfig/setup_linux/web_shortcuts/croshell.sh +0 -54
  197. machineconfig/setup_linux/web_shortcuts/interactive.sh +6 -6
  198. machineconfig/setup_linux/web_shortcuts/tmp.sh +2 -0
  199. machineconfig/setup_windows/web_shortcuts/all.ps1 +2 -2
  200. machineconfig/setup_windows/web_shortcuts/ascii_art.ps1 +1 -1
  201. machineconfig/setup_windows/web_shortcuts/croshell.ps1 +1 -1
  202. machineconfig/setup_windows/web_shortcuts/interactive.ps1 +5 -5
  203. machineconfig/setup_windows/wt_and_pwsh/install_fonts.ps1 +51 -15
  204. machineconfig/setup_windows/wt_and_pwsh/set_pwsh_theme.py +75 -18
  205. machineconfig/setup_windows/wt_and_pwsh/set_wt_settings.py +52 -42
  206. machineconfig/utils/ai/browser_user_wrapper.py +5 -5
  207. machineconfig/utils/ai/generate_file_checklist.py +19 -22
  208. machineconfig/utils/ai/url2md.py +5 -3
  209. machineconfig/utils/cloud/onedrive/setup_oauth.py +5 -4
  210. machineconfig/utils/cloud/onedrive/transaction.py +192 -227
  211. machineconfig/utils/code.py +71 -43
  212. machineconfig/utils/installer.py +77 -85
  213. machineconfig/utils/installer_utils/installer_abc.py +29 -17
  214. machineconfig/utils/installer_utils/installer_class.py +188 -83
  215. machineconfig/utils/io_save.py +3 -15
  216. machineconfig/utils/links.py +22 -11
  217. machineconfig/utils/notifications.py +197 -0
  218. machineconfig/utils/options.py +38 -25
  219. machineconfig/utils/path.py +18 -6
  220. machineconfig/utils/path_reduced.py +637 -316
  221. machineconfig/utils/procs.py +69 -63
  222. machineconfig/utils/scheduling.py +11 -13
  223. machineconfig/utils/ssh.py +351 -0
  224. machineconfig/utils/terminal.py +225 -0
  225. machineconfig/utils/utils.py +13 -12
  226. machineconfig/utils/utils2.py +43 -10
  227. machineconfig/utils/utils5.py +242 -46
  228. machineconfig/utils/ve.py +11 -6
  229. {machineconfig-1.97.dist-info β†’ machineconfig-2.1.dist-info}/METADATA +15 -9
  230. {machineconfig-1.97.dist-info β†’ machineconfig-2.1.dist-info}/RECORD +232 -235
  231. machineconfig/cluster/self_ssh.py +0 -57
  232. machineconfig/jobs/__pycache__/__init__.cpython-311.pyc +0 -0
  233. machineconfig/jobs/python/__pycache__/__init__.cpython-311.pyc +0 -0
  234. machineconfig/jobs/python/archive/python_tools.txt +0 -12
  235. machineconfig/jobs/python/vscode/__pycache__/select_interpreter.cpython-311.pyc +0 -0
  236. machineconfig/jobs/python_custom_installers/__pycache__/__init__.cpython-311.pyc +0 -0
  237. machineconfig/jobs/python_generic_installers/__pycache__/__init__.cpython-311.pyc +0 -0
  238. machineconfig/jobs/python_generic_installers/update.py +0 -3
  239. machineconfig/jobs/python_linux_installers/__pycache__/__init__.cpython-311.pyc +0 -0
  240. machineconfig/profile/__pycache__/__init__.cpython-311.pyc +0 -0
  241. machineconfig/profile/__pycache__/create.cpython-311.pyc +0 -0
  242. machineconfig/profile/__pycache__/shell.cpython-311.pyc +0 -0
  243. machineconfig/scripts/__pycache__/__init__.cpython-311.pyc +0 -0
  244. machineconfig/scripts/linux/activate_ve +0 -87
  245. machineconfig/scripts/python/__pycache__/__init__.cpython-311.pyc +0 -0
  246. machineconfig/scripts/python/__pycache__/cloud_copy.cpython-311.pyc +0 -0
  247. machineconfig/scripts/python/__pycache__/cloud_mount.cpython-311.pyc +0 -0
  248. machineconfig/scripts/python/__pycache__/cloud_sync.cpython-311.pyc +0 -0
  249. machineconfig/scripts/python/__pycache__/croshell.cpython-311.pyc +0 -0
  250. machineconfig/scripts/python/__pycache__/devops.cpython-311.pyc +0 -0
  251. machineconfig/scripts/python/__pycache__/devops_backup_retrieve.cpython-311.pyc +0 -0
  252. machineconfig/scripts/python/__pycache__/devops_devapps_install.cpython-311.pyc +0 -0
  253. machineconfig/scripts/python/__pycache__/devops_update_repos.cpython-311.pyc +0 -0
  254. machineconfig/scripts/python/__pycache__/fire_agents.cpython-311.pyc +0 -0
  255. machineconfig/scripts/python/__pycache__/fire_jobs.cpython-311.pyc +0 -0
  256. machineconfig/scripts/python/__pycache__/get_zellij_cmd.cpython-311.pyc +0 -0
  257. machineconfig/scripts/python/__pycache__/repos.cpython-311.pyc +0 -0
  258. machineconfig/scripts/python/ai/__pycache__/init.cpython-311.pyc +0 -0
  259. machineconfig/scripts/python/ai/init.py +0 -56
  260. machineconfig/scripts/python/ai/rules/python/dev.md +0 -31
  261. machineconfig/scripts/python/helpers/__pycache__/__init__.cpython-311.pyc +0 -0
  262. machineconfig/scripts/python/helpers/__pycache__/cloud_helpers.cpython-311.pyc +0 -0
  263. machineconfig/scripts/python/helpers/__pycache__/helpers2.cpython-311.pyc +0 -0
  264. machineconfig/scripts/python/helpers/__pycache__/helpers4.cpython-311.pyc +0 -0
  265. machineconfig/scripts/python/helpers/__pycache__/repo_sync_helpers.cpython-311.pyc +0 -0
  266. machineconfig/scripts/windows/activate_ve.ps1 +0 -54
  267. {machineconfig-1.97.dist-info β†’ machineconfig-2.1.dist-info}/WHEEL +0 -0
  268. {machineconfig-1.97.dist-info β†’ machineconfig-2.1.dist-info}/top_level.txt +0 -0
@@ -30,35 +30,37 @@ class ZellijLayoutGenerator:
30
30
  children
31
31
  }
32
32
  """
33
-
33
+
34
34
  @staticmethod
35
35
  def _generate_random_suffix(length: int = 8) -> str:
36
36
  """Generate a random string suffix for unique layout file names."""
37
- return ''.join(random.choices(string.ascii_lowercase + string.digits, k=length))
38
-
37
+ return "".join(random.choices(string.ascii_lowercase + string.digits, k=length))
38
+
39
39
  @staticmethod
40
40
  def _parse_command(command: str) -> tuple[str, List[str]]:
41
41
  try:
42
42
  parts = shlex.split(command)
43
- if not parts: raise ValueError("Empty command provided")
43
+ if not parts:
44
+ raise ValueError("Empty command provided")
44
45
  return parts[0], parts[1:] if len(parts) > 1 else []
45
46
  except ValueError as e:
46
47
  logger.error(f"Error parsing command '{command}': {e}")
47
48
  parts = command.split()
48
49
  return parts[0] if parts else "", parts[1:] if len(parts) > 1 else []
49
-
50
+
50
51
  @staticmethod
51
52
  def _format_args_for_kdl(args: List[str]) -> str:
52
- if not args: return ""
53
+ if not args:
54
+ return ""
53
55
  formatted_args = []
54
56
  for arg in args:
55
- if ' ' in arg or '"' in arg or "'" in arg:
57
+ if " " in arg or '"' in arg or "'" in arg:
56
58
  escaped_arg = arg.replace('"', '\\"')
57
59
  formatted_args.append(f'"{escaped_arg}"')
58
60
  else:
59
61
  formatted_args.append(f'"{arg}"')
60
62
  return " ".join(formatted_args)
61
-
63
+
62
64
  @staticmethod
63
65
  def _create_tab_section(tab_name: str, cwd: str, command: str) -> str:
64
66
  cmd, args = ZellijLayoutGenerator._parse_command(command)
@@ -67,33 +69,38 @@ class ZellijLayoutGenerator:
67
69
  escaped_tab_name = tab_name.replace('"', '\\"')
68
70
  tab_section = f' tab name="{escaped_tab_name}" cwd="{tab_cwd}" {{\n'
69
71
  tab_section += f' pane command="{cmd}" {{\n'
70
- if args_str: tab_section += f' args {args_str}\n'
71
- tab_section += ' }\n }\n'
72
+ if args_str:
73
+ tab_section += f" args {args_str}\n"
74
+ tab_section += " }\n }\n"
72
75
  return tab_section
73
-
76
+
74
77
  @staticmethod
75
78
  def _validate_tab_config(tab_config: Dict[str, tuple[str, str]]) -> None:
76
- if not tab_config: raise ValueError("Tab configuration cannot be empty")
79
+ if not tab_config:
80
+ raise ValueError("Tab configuration cannot be empty")
77
81
  for tab_name, (cwd, command) in tab_config.items():
78
- if not tab_name.strip(): raise ValueError(f"Invalid tab name: {tab_name}")
79
- if not command.strip(): raise ValueError(f"Invalid command for tab '{tab_name}': {command}")
80
- if not cwd.strip(): raise ValueError(f"Invalid cwd for tab '{tab_name}': {cwd}")
81
-
82
+ if not tab_name.strip():
83
+ raise ValueError(f"Invalid tab name: {tab_name}")
84
+ if not command.strip():
85
+ raise ValueError(f"Invalid command for tab '{tab_name}': {command}")
86
+ if not cwd.strip():
87
+ raise ValueError(f"Invalid cwd for tab '{tab_name}': {cwd}")
88
+
82
89
  def create_zellij_layout(self, tab_config: Dict[str, tuple[str, str]], output_dir: Optional[str] = None, session_name: Optional[str] = None) -> str:
83
90
  ZellijLayoutGenerator._validate_tab_config(tab_config)
84
-
91
+
85
92
  # Enhanced Rich logging
86
93
  tab_count = len(tab_config)
87
94
  console.print(f"[bold cyan]πŸ“‹ Creating Zellij layout[/bold cyan] [bright_green]with {tab_count} tabs[/bright_green]")
88
-
95
+
89
96
  # Display tab summary with emojis and colors
90
97
  for tab_name, (cwd, command) in tab_config.items():
91
98
  console.print(f" [yellow]β†’[/yellow] [bold]{tab_name}[/bold] [dim]in[/dim] [blue]{cwd}[/blue]")
92
-
99
+
93
100
  # Store session name and entire tab config for status checking
94
101
  self.session_name = session_name or "default"
95
102
  self.tab_config = tab_config.copy()
96
-
103
+
97
104
  layout_content = self.layout_template
98
105
  for tab_name, (cwd, command) in tab_config.items():
99
106
  layout_content += "\n" + ZellijLayoutGenerator._create_tab_section(tab_name, cwd, command)
@@ -104,24 +111,22 @@ class ZellijLayoutGenerator:
104
111
  output_path = Path(output_dir)
105
112
  output_path.mkdir(parents=True, exist_ok=True)
106
113
  layout_file = output_path / f"zellij_layout_{random_suffix}.kdl"
107
- with open(layout_file, 'w', encoding='utf-8') as f:
108
- f.write(layout_content)
114
+ layout_file.write_text(layout_content, encoding="utf-8")
109
115
  self.layout_path = str(layout_file.absolute())
110
116
  else:
111
117
  # Use the predefined TMP_LAYOUT_DIR for temporary files
112
118
  TMP_LAYOUT_DIR.mkdir(parents=True, exist_ok=True)
113
119
  layout_file = TMP_LAYOUT_DIR / f"zellij_layout_{self.session_name or 'default'}_{random_suffix}.kdl"
114
- with open(layout_file, 'w', encoding='utf-8') as f:
115
- f.write(layout_content)
120
+ layout_file.write_text(layout_content, encoding="utf-8")
116
121
  self.layout_path = str(layout_file.absolute())
117
-
122
+
118
123
  # Enhanced Rich logging for file creation
119
124
  console.print(f"[bold green]βœ… Zellij layout file created:[/bold green] [cyan]{self.layout_path}[/cyan]")
120
125
  return self.layout_path
121
126
  except OSError as e:
122
127
  logger.error(f"Failed to create layout file: {e}")
123
128
  raise
124
-
129
+
125
130
  @staticmethod
126
131
  def get_layout_preview(tab_config: Dict[str, tuple[str, str]], layout_template: str | None = None) -> str:
127
132
  if layout_template is None:
@@ -139,157 +144,91 @@ class ZellijLayoutGenerator:
139
144
  for tab_name, (cwd, command) in tab_config.items():
140
145
  layout_content += "\n" + ZellijLayoutGenerator._create_tab_section(tab_name, cwd, command)
141
146
  return layout_content + "\n}\n"
142
-
147
+
143
148
  @staticmethod
144
149
  def check_command_status(tab_name: str, tab_config: Dict[str, tuple[str, str]]) -> Dict[str, Any]:
145
150
  if tab_name not in tab_config:
146
- return {
147
- "status": "unknown",
148
- "error": f"Tab '{tab_name}' not found in tracked tab config",
149
- "running": False,
150
- "pid": None,
151
- "command": None,
152
- "cwd": None
153
- }
154
-
151
+ return {"status": "unknown", "error": f"Tab '{tab_name}' not found in tracked tab config", "running": False, "pid": None, "command": None, "cwd": None}
152
+
155
153
  cwd, command = tab_config[tab_name]
156
154
  cmd, _ = ZellijLayoutGenerator._parse_command(command)
157
-
155
+
158
156
  try:
159
157
  # Look for processes matching the command
160
158
  matching_processes = []
161
- for proc in psutil.process_iter(['pid', 'name', 'cmdline', 'status']):
159
+ for proc in psutil.process_iter(["pid", "name", "cmdline", "status"]):
162
160
  try:
163
- if proc.info['cmdline'] and len(proc.info['cmdline']) > 0:
161
+ if proc.info["cmdline"] and len(proc.info["cmdline"]) > 0:
164
162
  # Check if the command matches
165
- if (proc.info['name'] == cmd or
166
- cmd in proc.info['cmdline'][0] or
167
- any(cmd in arg for arg in proc.info['cmdline'])):
168
- matching_processes.append({
169
- "pid": proc.info['pid'],
170
- "name": proc.info['name'],
171
- "cmdline": proc.info['cmdline'],
172
- "status": proc.info['status']
173
- })
163
+ if proc.info["name"] == cmd or cmd in proc.info["cmdline"][0] or any(cmd in arg for arg in proc.info["cmdline"]):
164
+ matching_processes.append({"pid": proc.info["pid"], "name": proc.info["name"], "cmdline": proc.info["cmdline"], "status": proc.info["status"]})
174
165
  except (psutil.NoSuchProcess, psutil.AccessDenied):
175
166
  continue
176
-
167
+
177
168
  if matching_processes:
178
- return {
179
- "status": "running",
180
- "running": True,
181
- "processes": matching_processes,
182
- "command": command,
183
- "cwd": cwd,
184
- "tab_name": tab_name
185
- }
169
+ return {"status": "running", "running": True, "processes": matching_processes, "command": command, "cwd": cwd, "tab_name": tab_name}
186
170
  else:
187
- return {
188
- "status": "not_running",
189
- "running": False,
190
- "processes": [],
191
- "command": command,
192
- "cwd": cwd,
193
- "tab_name": tab_name
194
- }
195
-
171
+ return {"status": "not_running", "running": False, "processes": [], "command": command, "cwd": cwd, "tab_name": tab_name}
172
+
196
173
  except Exception as e:
197
174
  logger.error(f"Error checking command status for tab '{tab_name}': {e}")
198
- return {
199
- "status": "error",
200
- "error": str(e),
201
- "running": False,
202
- "command": command,
203
- "cwd": cwd,
204
- "tab_name": tab_name
205
- }
175
+ return {"status": "error", "error": str(e), "running": False, "command": command, "cwd": cwd, "tab_name": tab_name}
206
176
 
207
177
  def check_all_commands_status(self) -> Dict[str, Dict[str, Any]]:
208
178
  if not self.tab_config:
209
179
  logger.warning("No tab config tracked. Make sure to create a layout first.")
210
180
  return {}
211
-
181
+
212
182
  status_report = {}
213
183
  for tab_name in self.tab_config:
214
184
  status_report[tab_name] = ZellijLayoutGenerator.check_command_status(tab_name, self.tab_config)
215
-
185
+
216
186
  return status_report
217
187
 
218
188
  @staticmethod
219
189
  def check_zellij_session_status(session_name: str) -> Dict[str, Any]:
220
190
  try:
221
191
  # Run zellij list-sessions command
222
- result = subprocess.run(
223
- ['zellij', 'list-sessions'],
224
- capture_output=True,
225
- text=True,
226
- timeout=10
227
- )
228
-
192
+ result = subprocess.run(["zellij", "list-sessions"], capture_output=True, text=True, timeout=10)
193
+
229
194
  if result.returncode == 0:
230
- sessions = result.stdout.strip().split('\n') if result.stdout.strip() else []
195
+ sessions = result.stdout.strip().split("\n") if result.stdout.strip() else []
231
196
  session_running = any(session_name in session for session in sessions)
232
-
233
- return {
234
- "zellij_running": True,
235
- "session_exists": session_running,
236
- "session_name": session_name,
237
- "all_sessions": sessions
238
- }
197
+
198
+ return {"zellij_running": True, "session_exists": session_running, "session_name": session_name, "all_sessions": sessions}
239
199
  else:
240
- return {
241
- "zellij_running": False,
242
- "error": result.stderr,
243
- "session_name": session_name
244
- }
245
-
200
+ return {"zellij_running": False, "error": result.stderr, "session_name": session_name}
201
+
246
202
  except subprocess.TimeoutExpired:
247
- return {
248
- "zellij_running": False,
249
- "error": "Timeout while checking Zellij sessions",
250
- "session_name": session_name
251
- }
203
+ return {"zellij_running": False, "error": "Timeout while checking Zellij sessions", "session_name": session_name}
252
204
  except FileNotFoundError:
253
- return {
254
- "zellij_running": False,
255
- "error": "Zellij not found in PATH",
256
- "session_name": session_name
257
- }
205
+ return {"zellij_running": False, "error": "Zellij not found in PATH", "session_name": session_name}
258
206
  except Exception as e:
259
- return {
260
- "zellij_running": False,
261
- "error": str(e),
262
- "session_name": session_name
263
- }
207
+ return {"zellij_running": False, "error": str(e), "session_name": session_name}
264
208
 
265
209
  def get_comprehensive_status(self) -> Dict[str, Any]:
266
210
  zellij_status = ZellijLayoutGenerator.check_zellij_session_status(self.session_name or "default")
267
211
  commands_status = self.check_all_commands_status()
268
-
212
+
269
213
  running_count = sum(1 for status in commands_status.values() if status.get("running", False))
270
214
  total_count = len(commands_status)
271
-
215
+
272
216
  return {
273
217
  "zellij_session": zellij_status,
274
218
  "commands": commands_status,
275
- "summary": {
276
- "total_commands": total_count,
277
- "running_commands": running_count,
278
- "stopped_commands": total_count - running_count,
279
- "session_healthy": zellij_status.get("session_exists", False)
280
- }
219
+ "summary": {"total_commands": total_count, "running_commands": running_count, "stopped_commands": total_count - running_count, "session_healthy": zellij_status.get("session_exists", False)},
281
220
  }
282
221
 
283
222
  def print_status_report(self) -> None:
284
223
  from rich.panel import Panel
285
224
  from rich.table import Table
286
-
225
+
287
226
  status = self.get_comprehensive_status()
288
-
227
+
289
228
  # Create main panel
290
229
  console.print()
291
230
  console.print(Panel.fit("πŸ” ZELLIJ LAYOUT STATUS REPORT", style="bold cyan"))
292
-
231
+
293
232
  # Zellij session status
294
233
  zellij = status["zellij_session"]
295
234
  if zellij.get("zellij_running", False):
@@ -298,11 +237,11 @@ class ZellijLayoutGenerator:
298
237
  else:
299
238
  console.print(f"[bold yellow]⚠️ Zellij is running but session[/bold yellow] [yellow]'{self.session_name}'[/yellow] [yellow]not found[/yellow]")
300
239
  else:
301
- error_msg = zellij.get('error', 'Unknown error')
240
+ error_msg = zellij.get("error", "Unknown error")
302
241
  console.print(f"[bold red]❌ Zellij session issue:[/bold red] [red]{error_msg}[/red]")
303
-
242
+
304
243
  console.print()
305
-
244
+
306
245
  # Commands status table
307
246
  table = Table(title="πŸ“‹ COMMAND STATUS", show_header=True, header_style="bold magenta")
308
247
  table.add_column("Tab", style="cyan", no_wrap=True)
@@ -310,7 +249,7 @@ class ZellijLayoutGenerator:
310
249
  table.add_column("PID", justify="center", style="dim")
311
250
  table.add_column("Memory", justify="center", style="blue")
312
251
  table.add_column("Command", style="green", max_width=40)
313
-
252
+
314
253
  for tab_name, cmd_status in status["commands"].items():
315
254
  # Determine status display
316
255
  if cmd_status.get("running", False):
@@ -318,8 +257,8 @@ class ZellijLayoutGenerator:
318
257
  processes = cmd_status.get("processes", [])
319
258
  if processes:
320
259
  proc = processes[0] # Show first process
321
- pid = str(proc.get('pid', 'N/A'))
322
- memory = f"{proc.get('memory_mb', 0):.1f}MB" if proc.get('memory_mb') else "N/A"
260
+ pid = str(proc.get("pid", "N/A"))
261
+ memory = f"{proc.get('memory_mb', 0):.1f}MB" if proc.get("memory_mb") else "N/A"
323
262
  else:
324
263
  pid = "N/A"
325
264
  memory = "N/A"
@@ -327,46 +266,51 @@ class ZellijLayoutGenerator:
327
266
  status_text = "[bold red]❌ Stopped[/bold red]"
328
267
  pid = "N/A"
329
268
  memory = "N/A"
330
-
331
- command = cmd_status.get('command', 'Unknown')
269
+
270
+ command = cmd_status.get("command", "Unknown")
332
271
  # Truncate long commands
333
272
  if len(command) > 35:
334
273
  command = command[:32] + "..."
335
-
274
+
336
275
  table.add_row(tab_name, status_text, pid, memory, command)
337
-
276
+
338
277
  console.print(table)
339
278
  console.print()
340
-
279
+
341
280
  # Enhanced summary
342
281
  summary = status["summary"]
343
282
  from rich.panel import Panel
344
- summary_text = f"""[bold]Total commands:[/bold] {summary['total_commands']}
345
- [green]Running:[/green] {summary['running_commands']}
346
- [red]Stopped:[/red] {summary['stopped_commands']}
347
- [yellow]Session healthy:[/yellow] {'βœ…' if summary['session_healthy'] else '❌'}"""
348
-
283
+
284
+ summary_text = f"""[bold]Total commands:[/bold] {summary["total_commands"]}
285
+ [green]Running:[/green] {summary["running_commands"]}
286
+ [red]Stopped:[/red] {summary["stopped_commands"]}
287
+ [yellow]Session healthy:[/yellow] {"βœ…" if summary["session_healthy"] else "❌"}"""
288
+
349
289
  console.print(Panel(summary_text, title="πŸ“Š Summary", style="blue"))
350
290
 
291
+
351
292
  def created_zellij_layout(tab_config: Dict[str, tuple[str, str]], output_dir: Optional[str] = None) -> str:
352
293
  generator = ZellijLayoutGenerator()
353
294
  return generator.create_zellij_layout(tab_config, output_dir)
295
+
296
+
354
297
  def run_zellij_layout(tab_config: Dict[str, tuple[str, str]], session_name: Optional[str] = None) -> str:
355
298
  if not session_name:
356
- session_name = ''.join(random.choices(string.ascii_lowercase + string.digits, k=8))
299
+ session_name = "".join(random.choices(string.ascii_lowercase + string.digits, k=8))
357
300
  layout_path = created_zellij_layout(tab_config)
358
-
301
+
359
302
  # Use enhanced command execution
360
303
  try:
361
304
  from .enhanced_command_runner import enhanced_zellij_session_start
305
+
362
306
  enhanced_zellij_session_start(session_name, layout_path)
363
307
  except ImportError:
364
308
  # Fallback to original implementation
365
309
  cmd = f"zellij delete-session --force {session_name}; zellij --layout {layout_path} a -b {session_name}"
366
310
  import subprocess
311
+
367
312
  subprocess.run(cmd, shell=True, check=True)
368
313
  console.print(f"[bold green]πŸš€ Zellij layout is running[/bold green] [yellow]@[/yellow] [bold cyan]{session_name}[/bold cyan]")
369
-
370
314
  return session_name
371
315
 
372
316
 
@@ -394,25 +338,25 @@ zellij action close-pane; sleep 2
394
338
  if __name__ == "__main__":
395
339
  sample_tabs = {
396
340
  "πŸ€–Bot1": ("~/code/bytesense/bithence", "~/scripts/fire -mO go1.py bot1 --kw create_new_bot True"),
397
- "πŸ€–Bot2": ("~/code/bytesense/bithence", "~/scripts/fire -mO go2.py bot2 --kw create_new_bot True"),
341
+ "πŸ€–Bot2": ("~/code/bytesense/bithence", "~/scripts/fire -mO go2.py bot2 --kw create_new_bot True"),
398
342
  "πŸ“ŠMonitor": ("~", "htop"),
399
- "πŸ“Logs": ("/var/log", "tail -f /var/log/app.log")
343
+ "πŸ“Logs": ("/var/log", "tail -f /var/log/app.log"),
400
344
  }
401
345
  try:
402
346
  # Create layout using the generator directly to access status methods
403
347
  generator = ZellijLayoutGenerator()
404
348
  layout_path = generator.create_zellij_layout(sample_tabs, session_name="test_session")
405
349
  print(f"βœ… Layout created successfully: {layout_path}")
406
-
350
+
407
351
  # Demonstrate status checking
408
352
  print("\nπŸ” Checking command status (this is just a demo - commands aren't actually running):")
409
353
  generator.print_status_report()
410
-
354
+
411
355
  # Individual command status check
412
356
  print("\nπŸ”Ž Individual command status for Bot1:")
413
357
  bot1_status = ZellijLayoutGenerator.check_command_status("πŸ€–Bot1", generator.tab_config)
414
358
  print(f"Status: {bot1_status['status']}")
415
359
  print(f"Running: {bot1_status['running']}")
416
-
360
+
417
361
  except Exception as e:
418
362
  print(f"❌ Error: {e}")