machineconfig 2.0__py3-none-any.whl → 2.2__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 (253) 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 +5 -6
  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 +27 -46
  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 +2 -1
  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/archive/ngrok.py +13 -13
  48. machineconfig/jobs/python_custom_installers/dev/aider.py +7 -15
  49. machineconfig/jobs/python_custom_installers/dev/alacritty.py +9 -18
  50. machineconfig/jobs/python_custom_installers/dev/brave.py +10 -19
  51. machineconfig/jobs/python_custom_installers/dev/bypass_paywall.py +8 -15
  52. machineconfig/jobs/python_custom_installers/dev/code.py +12 -32
  53. machineconfig/jobs/python_custom_installers/dev/cursor.py +3 -14
  54. machineconfig/jobs/python_custom_installers/dev/docker_desktop.py +8 -7
  55. machineconfig/jobs/python_custom_installers/dev/espanso.py +15 -19
  56. machineconfig/jobs/python_custom_installers/dev/goes.py +5 -12
  57. machineconfig/jobs/python_custom_installers/dev/lvim.py +9 -17
  58. machineconfig/jobs/python_custom_installers/dev/nerdfont.py +12 -19
  59. machineconfig/jobs/python_custom_installers/dev/redis.py +12 -20
  60. machineconfig/jobs/python_custom_installers/dev/wezterm.py +12 -19
  61. machineconfig/jobs/python_custom_installers/dev/winget.py +5 -23
  62. machineconfig/jobs/python_custom_installers/docker.py +12 -21
  63. machineconfig/jobs/python_custom_installers/gh.py +11 -19
  64. machineconfig/jobs/python_custom_installers/hx.py +32 -16
  65. machineconfig/jobs/python_custom_installers/warp-cli.py +12 -20
  66. machineconfig/jobs/python_generic_installers/__pycache__/__init__.cpython-313.pyc +0 -0
  67. machineconfig/jobs/python_generic_installers/config.json +1 -1
  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 +38 -26
  74. machineconfig/profile/create_hardlinks.py +29 -20
  75. machineconfig/profile/shell.py +56 -32
  76. machineconfig/scripts/__init__.py +0 -2
  77. machineconfig/scripts/__pycache__/__init__.cpython-313.pyc +0 -0
  78. machineconfig/scripts/cloud/init.sh +2 -2
  79. machineconfig/scripts/linux/checkout_versions +1 -1
  80. machineconfig/scripts/linux/choose_wezterm_theme +1 -1
  81. machineconfig/scripts/linux/cloud_copy +1 -1
  82. machineconfig/scripts/linux/cloud_manager +1 -1
  83. machineconfig/scripts/linux/cloud_mount +1 -1
  84. machineconfig/scripts/linux/cloud_repo_sync +1 -1
  85. machineconfig/scripts/linux/cloud_sync +1 -1
  86. machineconfig/scripts/linux/croshell +1 -1
  87. machineconfig/scripts/linux/devops +7 -7
  88. machineconfig/scripts/linux/fire +1 -1
  89. machineconfig/scripts/linux/fire_agents +3 -2
  90. machineconfig/scripts/linux/ftpx +1 -1
  91. machineconfig/scripts/linux/gh_models +1 -1
  92. machineconfig/scripts/linux/kill_process +1 -1
  93. machineconfig/scripts/linux/mcinit +1 -1
  94. machineconfig/scripts/linux/repos +1 -1
  95. machineconfig/scripts/linux/scheduler +1 -1
  96. machineconfig/scripts/linux/start_slidev +1 -1
  97. machineconfig/scripts/linux/start_terminals +1 -1
  98. machineconfig/scripts/linux/url2md +1 -1
  99. machineconfig/scripts/linux/warp-cli.sh +122 -0
  100. machineconfig/scripts/linux/wifi_conn +1 -1
  101. machineconfig/scripts/python/__pycache__/__init__.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_agents.cpython-313.pyc +0 -0
  106. machineconfig/scripts/python/ai/__init__.py +0 -0
  107. machineconfig/scripts/python/ai/generate_files.py +83 -0
  108. machineconfig/scripts/python/ai/instructions/python/dev.instructions.md +2 -2
  109. machineconfig/scripts/python/ai/mcinit.py +14 -7
  110. machineconfig/scripts/python/ai/scripts/lint_and_type_check.sh +10 -5
  111. machineconfig/scripts/python/archive/tmate_conn.py +5 -5
  112. machineconfig/scripts/python/archive/tmate_start.py +7 -7
  113. machineconfig/scripts/python/choose_wezterm_theme.py +35 -32
  114. machineconfig/scripts/python/cloud_copy.py +23 -14
  115. machineconfig/scripts/python/cloud_mount.py +36 -24
  116. machineconfig/scripts/python/cloud_repo_sync.py +40 -27
  117. machineconfig/scripts/python/cloud_sync.py +4 -4
  118. machineconfig/scripts/python/croshell.py +40 -29
  119. machineconfig/scripts/python/devops.py +45 -27
  120. machineconfig/scripts/python/devops_add_identity.py +15 -25
  121. machineconfig/scripts/python/devops_add_ssh_key.py +8 -8
  122. machineconfig/scripts/python/devops_backup_retrieve.py +18 -16
  123. machineconfig/scripts/python/devops_devapps_install.py +25 -20
  124. machineconfig/scripts/python/devops_update_repos.py +232 -59
  125. machineconfig/scripts/python/dotfile.py +17 -15
  126. machineconfig/scripts/python/fire_agents.py +48 -22
  127. machineconfig/scripts/python/fire_jobs.py +93 -58
  128. machineconfig/scripts/python/ftpx.py +26 -15
  129. machineconfig/scripts/python/get_zellij_cmd.py +8 -7
  130. machineconfig/scripts/python/helpers/cloud_helpers.py +33 -28
  131. machineconfig/scripts/python/helpers/helpers2.py +27 -16
  132. machineconfig/scripts/python/helpers/helpers4.py +45 -32
  133. machineconfig/scripts/python/helpers/helpers5.py +1 -1
  134. machineconfig/scripts/python/helpers/repo_sync_helpers.py +32 -10
  135. machineconfig/scripts/python/mount_nfs.py +9 -16
  136. machineconfig/scripts/python/mount_nw_drive.py +10 -5
  137. machineconfig/scripts/python/mount_ssh.py +9 -7
  138. machineconfig/scripts/python/repos.py +216 -58
  139. machineconfig/scripts/python/snapshot.py +0 -1
  140. machineconfig/scripts/python/start_slidev.py +11 -6
  141. machineconfig/scripts/python/start_terminals.py +22 -16
  142. machineconfig/scripts/python/viewer_template.py +0 -1
  143. machineconfig/scripts/python/wifi_conn.py +49 -75
  144. machineconfig/scripts/python/wsl_windows_transfer.py +9 -7
  145. machineconfig/scripts/windows/checkout_version.ps1 +1 -3
  146. machineconfig/scripts/windows/choose_wezterm_theme.ps1 +1 -3
  147. machineconfig/scripts/windows/cloud_copy.ps1 +2 -6
  148. machineconfig/scripts/windows/cloud_manager.ps1 +1 -1
  149. machineconfig/scripts/windows/cloud_repo_sync.ps1 +1 -2
  150. machineconfig/scripts/windows/cloud_sync.ps1 +2 -2
  151. machineconfig/scripts/windows/croshell.ps1 +2 -2
  152. machineconfig/scripts/windows/devops.ps1 +1 -4
  153. machineconfig/scripts/windows/dotfile.ps1 +1 -3
  154. machineconfig/scripts/windows/fire.ps1 +1 -1
  155. machineconfig/scripts/windows/ftpx.ps1 +2 -2
  156. machineconfig/scripts/windows/gpt.ps1 +1 -1
  157. machineconfig/scripts/windows/kill_process.ps1 +1 -2
  158. machineconfig/scripts/windows/mcinit.ps1 +1 -1
  159. machineconfig/scripts/windows/mount_nfs.ps1 +1 -1
  160. machineconfig/scripts/windows/mount_ssh.ps1 +1 -1
  161. machineconfig/scripts/windows/pomodoro.ps1 +1 -1
  162. machineconfig/scripts/windows/py2exe.ps1 +1 -3
  163. machineconfig/scripts/windows/repos.ps1 +1 -1
  164. machineconfig/scripts/windows/scheduler.ps1 +1 -1
  165. machineconfig/scripts/windows/snapshot.ps1 +2 -2
  166. machineconfig/scripts/windows/start_slidev.ps1 +1 -1
  167. machineconfig/scripts/windows/start_terminals.ps1 +1 -1
  168. machineconfig/scripts/windows/wifi_conn.ps1 +1 -1
  169. machineconfig/scripts/windows/wsl_windows_transfer.ps1 +1 -3
  170. machineconfig/settings/lf/linux/lfrc +2 -1
  171. machineconfig/settings/linters/.ruff_cache/.gitignore +2 -0
  172. machineconfig/settings/linters/.ruff_cache/CACHEDIR.TAG +1 -0
  173. machineconfig/settings/lvim/windows/archive/config_additional.lua +1 -1
  174. machineconfig/settings/svim/linux/init.toml +1 -1
  175. machineconfig/settings/svim/windows/init.toml +1 -1
  176. machineconfig/setup_linux/web_shortcuts/croshell.sh +3 -52
  177. machineconfig/setup_linux/web_shortcuts/interactive.sh +6 -6
  178. machineconfig/setup_linux/web_shortcuts/ssh.sh +0 -4
  179. machineconfig/setup_windows/web_shortcuts/all.ps1 +2 -2
  180. machineconfig/setup_windows/web_shortcuts/ascii_art.ps1 +1 -1
  181. machineconfig/setup_windows/web_shortcuts/croshell.ps1 +1 -1
  182. machineconfig/setup_windows/web_shortcuts/interactive.ps1 +5 -5
  183. machineconfig/setup_windows/wt_and_pwsh/install_fonts.ps1 +51 -15
  184. machineconfig/setup_windows/wt_and_pwsh/set_pwsh_theme.py +58 -13
  185. machineconfig/setup_windows/wt_and_pwsh/set_wt_settings.py +45 -37
  186. machineconfig/utils/ai/generate_file_checklist.py +8 -10
  187. machineconfig/utils/ai/url2md.py +4 -2
  188. machineconfig/utils/cloud/onedrive/setup_oauth.py +1 -0
  189. machineconfig/utils/cloud/onedrive/transaction.py +63 -98
  190. machineconfig/utils/code.py +62 -41
  191. machineconfig/utils/installer.py +29 -35
  192. machineconfig/utils/installer_utils/installer_abc.py +11 -11
  193. machineconfig/utils/installer_utils/installer_class.py +155 -74
  194. machineconfig/utils/links.py +112 -31
  195. machineconfig/utils/notifications.py +211 -0
  196. machineconfig/utils/options.py +41 -42
  197. machineconfig/utils/path.py +13 -6
  198. machineconfig/utils/path_reduced.py +614 -311
  199. machineconfig/utils/procs.py +48 -42
  200. machineconfig/utils/scheduling.py +0 -1
  201. machineconfig/utils/source_of_truth.py +27 -0
  202. machineconfig/utils/ssh.py +146 -85
  203. machineconfig/utils/terminal.py +84 -37
  204. machineconfig/utils/upgrade_packages.py +91 -0
  205. machineconfig/utils/utils2.py +39 -50
  206. machineconfig/utils/utils5.py +195 -116
  207. machineconfig/utils/ve.py +13 -5
  208. {machineconfig-2.0.dist-info → machineconfig-2.2.dist-info}/METADATA +14 -13
  209. {machineconfig-2.0.dist-info → machineconfig-2.2.dist-info}/RECORD +212 -237
  210. machineconfig/jobs/__pycache__/__init__.cpython-311.pyc +0 -0
  211. machineconfig/jobs/python/__pycache__/__init__.cpython-311.pyc +0 -0
  212. machineconfig/jobs/python/__pycache__/python_ve_symlink.cpython-311.pyc +0 -0
  213. machineconfig/jobs/python/archive/python_tools.txt +0 -12
  214. machineconfig/jobs/python/vscode/__pycache__/select_interpreter.cpython-311.pyc +0 -0
  215. machineconfig/jobs/python_custom_installers/__pycache__/__init__.cpython-311.pyc +0 -0
  216. machineconfig/jobs/python_generic_installers/__pycache__/__init__.cpython-311.pyc +0 -0
  217. machineconfig/jobs/python_generic_installers/update.py +0 -3
  218. machineconfig/jobs/python_linux_installers/__pycache__/__init__.cpython-311.pyc +0 -0
  219. machineconfig/profile/__pycache__/__init__.cpython-311.pyc +0 -0
  220. machineconfig/profile/__pycache__/create.cpython-311.pyc +0 -0
  221. machineconfig/profile/__pycache__/shell.cpython-311.pyc +0 -0
  222. machineconfig/scripts/__pycache__/__init__.cpython-311.pyc +0 -0
  223. machineconfig/scripts/linux/activate_ve +0 -87
  224. machineconfig/scripts/python/__pycache__/__init__.cpython-311.pyc +0 -0
  225. machineconfig/scripts/python/__pycache__/cloud_copy.cpython-311.pyc +0 -0
  226. machineconfig/scripts/python/__pycache__/cloud_mount.cpython-311.pyc +0 -0
  227. machineconfig/scripts/python/__pycache__/cloud_sync.cpython-311.pyc +0 -0
  228. machineconfig/scripts/python/__pycache__/croshell.cpython-311.pyc +0 -0
  229. machineconfig/scripts/python/__pycache__/devops.cpython-311.pyc +0 -0
  230. machineconfig/scripts/python/__pycache__/devops_backup_retrieve.cpython-311.pyc +0 -0
  231. machineconfig/scripts/python/__pycache__/devops_devapps_install.cpython-311.pyc +0 -0
  232. machineconfig/scripts/python/__pycache__/devops_update_repos.cpython-311.pyc +0 -0
  233. machineconfig/scripts/python/__pycache__/fire_agents.cpython-311.pyc +0 -0
  234. machineconfig/scripts/python/__pycache__/fire_jobs.cpython-311.pyc +0 -0
  235. machineconfig/scripts/python/__pycache__/fire_jobs.cpython-313.pyc +0 -0
  236. machineconfig/scripts/python/__pycache__/get_zellij_cmd.cpython-311.pyc +0 -0
  237. machineconfig/scripts/python/__pycache__/repos.cpython-311.pyc +0 -0
  238. machineconfig/scripts/python/ai/__pycache__/init.cpython-311.pyc +0 -0
  239. machineconfig/scripts/python/ai/__pycache__/mcinit.cpython-311.pyc +0 -0
  240. machineconfig/scripts/python/helpers/__pycache__/__init__.cpython-311.pyc +0 -0
  241. machineconfig/scripts/python/helpers/__pycache__/__init__.cpython-313.pyc +0 -0
  242. machineconfig/scripts/python/helpers/__pycache__/cloud_helpers.cpython-311.pyc +0 -0
  243. machineconfig/scripts/python/helpers/__pycache__/helpers2.cpython-311.pyc +0 -0
  244. machineconfig/scripts/python/helpers/__pycache__/helpers4.cpython-311.pyc +0 -0
  245. machineconfig/scripts/python/helpers/__pycache__/helpers4.cpython-313.pyc +0 -0
  246. machineconfig/scripts/python/helpers/__pycache__/repo_sync_helpers.cpython-311.pyc +0 -0
  247. machineconfig/scripts/windows/activate_ve.ps1 +0 -54
  248. machineconfig/setup_linux/web_shortcuts/all.sh +0 -48
  249. machineconfig/setup_linux/web_shortcuts/update_system.sh +0 -48
  250. machineconfig/utils/utils.py +0 -95
  251. /machineconfig/setup_linux/web_shortcuts/{tmp.sh → android.sh} +0 -0
  252. {machineconfig-2.0.dist-info → machineconfig-2.2.dist-info}/WHEEL +0 -0
  253. {machineconfig-2.0.dist-info → machineconfig-2.2.dist-info}/top_level.txt +0 -0
@@ -3,6 +3,7 @@
3
3
  Windows Terminal layout generation utilities for creating wt command strings.
4
4
  Based on Windows Terminal documentation: https://learn.microsoft.com/en-us/windows/terminal/command-line-arguments
5
5
  """
6
+
6
7
  import shlex
7
8
  import random
8
9
  import string
@@ -19,7 +20,7 @@ class WTLayoutGenerator:
19
20
  @staticmethod
20
21
  def generate_random_suffix(length: int = 8) -> str:
21
22
  """Generate a random string suffix for unique window names."""
22
- return ''.join(random.choices(string.ascii_lowercase + string.digits, k=length))
23
+ return "".join(random.choices(string.ascii_lowercase + string.digits, k=length))
23
24
 
24
25
  @staticmethod
25
26
  def parse_command(command: str) -> Tuple[str, List[str]]:
@@ -40,7 +41,7 @@ class WTLayoutGenerator:
40
41
  # Windows Terminal uses PowerShell-style escaping
41
42
  # Escape special characters that might cause issues
42
43
  text = text.replace('"', '""') # Escape quotes for PowerShell
43
- if ' ' in text or ';' in text or '&' in text or '|' in text:
44
+ if " " in text or ";" in text or "&" in text or "|" in text:
44
45
  return f'"{text}"'
45
46
  return text
46
47
 
@@ -50,9 +51,9 @@ class WTLayoutGenerator:
50
51
  cmd, args = WTLayoutGenerator.parse_command(command)
51
52
 
52
53
  # Convert paths to Windows format if needed
53
- if cwd.startswith('~/'):
54
- cwd = cwd.replace('~/', f"{Path.home()}/")
55
- elif cwd == '~':
54
+ if cwd.startswith("~/"):
55
+ cwd = cwd.replace("~/", f"{Path.home()}/")
56
+ elif cwd == "~":
56
57
  cwd = str(Path.home())
57
58
 
58
59
  # Build the wt command parts
@@ -89,10 +90,7 @@ class WTLayoutGenerator:
89
90
  if not cwd.strip():
90
91
  raise ValueError(f"Invalid cwd for tab '{tab_name}': {cwd}")
91
92
 
92
- def generate_wt_command(self, tab_config: Dict[str, Tuple[str, str]],
93
- window_name: str | None = None,
94
- maximized: bool = False,
95
- focus: bool = True) -> str:
93
+ def generate_wt_command(self, tab_config: Dict[str, Tuple[str, str]], window_name: str | None = None, maximized: bool = False, focus: bool = True) -> str:
96
94
  """Generate complete Windows Terminal command string."""
97
95
  self.validate_tab_config(tab_config)
98
96
 
@@ -129,9 +127,7 @@ class WTLayoutGenerator:
129
127
 
130
128
  return " ".join(wt_parts)
131
129
 
132
- def create_wt_script(self, tab_config: Dict[str, Tuple[str, str]],
133
- output_dir: Path, session_name: str,
134
- window_name: str | None = None) -> str:
130
+ def create_wt_script(self, tab_config: Dict[str, Tuple[str, str]], output_dir: Path, session_name: str, window_name: str | None = None) -> str:
135
131
  """Create a Windows Terminal script file and return its absolute path."""
136
132
  self.validate_tab_config(tab_config)
137
133
 
@@ -168,8 +164,7 @@ REM Windows Terminal layout for {session_name}
168
164
  logger.error(f"Failed to create script file: {e}")
169
165
  raise
170
166
 
171
- def generate_split_pane_command(self, tab_config: Dict[str, Tuple[str, str]],
172
- window_name: str | None = None) -> str:
167
+ def generate_split_pane_command(self, tab_config: Dict[str, Tuple[str, str]], window_name: str | None = None) -> str:
173
168
  """Generate Windows Terminal command with split panes instead of separate tabs."""
174
169
  self.validate_tab_config(tab_config)
175
170
 
@@ -195,4 +190,4 @@ REM Windows Terminal layout for {session_name}
195
190
  wt_parts.extend(["--title", WTLayoutGenerator.escape_for_wt(tab_name)])
196
191
  wt_parts.append(WTLayoutGenerator.escape_for_wt(command))
197
192
 
198
- return " ".join(wt_parts)
193
+ return " ".join(wt_parts)
@@ -3,6 +3,7 @@
3
3
  Process monitoring and status checking utilities for Windows Terminal commands.
4
4
  Adapted from zellij process monitor but focused on Windows processes.
5
5
  """
6
+
6
7
  import json
7
8
  import logging
8
9
  import subprocess
@@ -27,29 +28,16 @@ class WTProcessMonitor:
27
28
  def _run_command(self, command: str, timeout: int = 30) -> subprocess.CompletedProcess[str]:
28
29
  """Run command either locally or remotely."""
29
30
  if self.is_local:
30
- return subprocess.run(
31
- ["powershell", "-Command", command],
32
- capture_output=True,
33
- text=True,
34
- timeout=timeout
35
- )
31
+ return subprocess.run(["powershell", "-Command", command], capture_output=True, text=True, timeout=timeout)
36
32
  else:
37
33
  if self.remote_executor is None:
38
34
  raise ValueError("Remote executor is None but is_local is False")
39
35
  return self.remote_executor.run_command(command, timeout)
40
36
 
41
- def check_command_status(self, tab_name: str, tab_config: Dict[str, Tuple[str, str]],
42
- use_verification: bool = True) -> Dict[str, Any]:
37
+ def check_command_status(self, tab_name: str, tab_config: Dict[str, Tuple[str, str]], use_verification: bool = True) -> Dict[str, Any]:
43
38
  """Check command status with optional process verification."""
44
39
  if tab_name not in tab_config:
45
- return {
46
- "status": "unknown",
47
- "error": f"Tab '{tab_name}' not found in tracked configuration",
48
- "running": False,
49
- "pid": None,
50
- "command": None,
51
- "location": self.location_name
52
- }
40
+ return {"status": "unknown", "error": f"Tab '{tab_name}' not found in tracked configuration", "running": False, "pid": None, "command": None, "location": self.location_name}
53
41
 
54
42
  # Use the verified method by default for more accurate results
55
43
  if use_verification:
@@ -68,11 +56,11 @@ class WTProcessMonitor:
68
56
  if result.returncode == 0:
69
57
  try:
70
58
  # Parse PowerShell output (JSON format)
71
- output_lines = [line.strip() for line in result.stdout.strip().split('\n') if line.strip()]
59
+ output_lines = [line.strip() for line in result.stdout.strip().split("\n") if line.strip()]
72
60
  matching_processes = []
73
61
 
74
62
  for line in output_lines:
75
- if line.startswith('{') and line.endswith('}'):
63
+ if line.startswith("{") and line.endswith("}"):
76
64
  try:
77
65
  proc_info = json.loads(line)
78
66
  matching_processes.append(proc_info)
@@ -80,64 +68,29 @@ class WTProcessMonitor:
80
68
  continue
81
69
 
82
70
  if matching_processes:
83
- return {
84
- "status": "running",
85
- "running": True,
86
- "processes": matching_processes,
87
- "command": command,
88
- "tab_name": tab_name,
89
- "location": self.location_name
90
- }
71
+ return {"status": "running", "running": True, "processes": matching_processes, "command": command, "tab_name": tab_name, "location": self.location_name}
91
72
  else:
92
- return {
93
- "status": "not_running",
94
- "running": False,
95
- "processes": [],
96
- "command": command,
97
- "tab_name": tab_name,
98
- "location": self.location_name
99
- }
73
+ return {"status": "not_running", "running": False, "processes": [], "command": command, "tab_name": tab_name, "location": self.location_name}
100
74
  except Exception as e:
101
75
  logger.error(f"Failed to parse process check output: {e}")
102
- return {
103
- "status": "error",
104
- "error": f"Failed to parse output: {e}",
105
- "running": False,
106
- "command": command,
107
- "tab_name": tab_name,
108
- "location": self.location_name
109
- }
76
+ return {"status": "error", "error": f"Failed to parse output: {e}", "running": False, "command": command, "tab_name": tab_name, "location": self.location_name}
110
77
  else:
111
- return {
112
- "status": "error",
113
- "error": f"Command failed: {result.stderr}",
114
- "running": False,
115
- "command": command,
116
- "tab_name": tab_name,
117
- "location": self.location_name
118
- }
78
+ return {"status": "error", "error": f"Command failed: {result.stderr}", "running": False, "command": command, "tab_name": tab_name, "location": self.location_name}
119
79
 
120
80
  except Exception as e:
121
81
  logger.error(f"Error checking command status for tab '{tab_name}': {e}")
122
- return {
123
- "status": "error",
124
- "error": str(e),
125
- "running": False,
126
- "command": command,
127
- "tab_name": tab_name,
128
- "location": self.location_name
129
- }
82
+ return {"status": "error", "error": str(e), "running": False, "command": command, "tab_name": tab_name, "location": self.location_name}
130
83
 
131
84
  def _create_process_check_script(self, command: str) -> str:
132
85
  """Create PowerShell script for checking processes."""
133
86
  # Escape command for PowerShell
134
87
  escaped_command = command.replace("'", "''").replace('"', '""')
135
88
  cmd_parts = [part for part in command.split() if len(part) > 2]
136
- primary_cmd = cmd_parts[0] if cmd_parts else ''
89
+ primary_cmd = cmd_parts[0] if cmd_parts else ""
137
90
 
138
91
  return f"""
139
92
  $targetCommand = '{escaped_command}'
140
- $cmdParts = @({', '.join([f"'{part}'" for part in cmd_parts])})
93
+ $cmdParts = @({", ".join([f"'{part}'" for part in cmd_parts])})
141
94
  $primaryCmd = '{primary_cmd}'
142
95
  $currentPid = $PID
143
96
 
@@ -182,13 +135,7 @@ Get-Process | ForEach-Object {{
182
135
  def force_fresh_process_check(self, tab_name: str, tab_config: Dict[str, Tuple[str, str]]) -> Dict[str, Any]:
183
136
  """Force a fresh process check with additional validation."""
184
137
  if tab_name not in tab_config:
185
- return {
186
- "status": "unknown",
187
- "error": f"Tab '{tab_name}' not found in tracked configuration",
188
- "running": False,
189
- "command": None,
190
- "location": self.location_name
191
- }
138
+ return {"status": "unknown", "error": f"Tab '{tab_name}' not found in tracked configuration", "running": False, "command": None, "location": self.location_name}
192
139
 
193
140
  _, command = tab_config[tab_name]
194
141
 
@@ -204,9 +151,9 @@ Get-Process | ForEach-Object {{
204
151
  if result.returncode == 0:
205
152
  try:
206
153
  # Parse the output to extract JSON
207
- output_lines = [line.strip() for line in result.stdout.strip().split('\n') if line.strip()]
154
+ output_lines = [line.strip() for line in result.stdout.strip().split("\n") if line.strip()]
208
155
  for line in output_lines:
209
- if line.startswith('{') and '"processes"' in line:
156
+ if line.startswith("{") and '"processes"' in line:
210
157
  check_result = json.loads(line)
211
158
  matching_processes = check_result.get("processes", [])
212
159
 
@@ -218,62 +165,32 @@ Get-Process | ForEach-Object {{
218
165
  "tab_name": tab_name,
219
166
  "location": self.location_name,
220
167
  "check_timestamp": check_timestamp,
221
- "method": "force_fresh_check"
168
+ "method": "force_fresh_check",
222
169
  }
223
170
 
224
171
  # Fallback if no JSON found
225
- return {
226
- "status": "not_running",
227
- "running": False,
228
- "processes": [],
229
- "command": command,
230
- "tab_name": tab_name,
231
- "location": self.location_name,
232
- "raw_output": result.stdout
233
- }
172
+ return {"status": "not_running", "running": False, "processes": [], "command": command, "tab_name": tab_name, "location": self.location_name, "raw_output": result.stdout}
234
173
  except json.JSONDecodeError as e:
235
174
  logger.error(f"Failed to parse fresh check output: {e}")
236
- return {
237
- "status": "error",
238
- "error": f"Failed to parse output: {e}",
239
- "running": False,
240
- "command": command,
241
- "tab_name": tab_name,
242
- "location": self.location_name,
243
- "raw_output": result.stdout
244
- }
175
+ return {"status": "error", "error": f"Failed to parse output: {e}", "running": False, "command": command, "tab_name": tab_name, "location": self.location_name, "raw_output": result.stdout}
245
176
  else:
246
- return {
247
- "status": "error",
248
- "error": f"Command failed: {result.stderr}",
249
- "running": False,
250
- "command": command,
251
- "tab_name": tab_name,
252
- "location": self.location_name
253
- }
177
+ return {"status": "error", "error": f"Command failed: {result.stderr}", "running": False, "command": command, "tab_name": tab_name, "location": self.location_name}
254
178
 
255
179
  except Exception as e:
256
180
  logger.error(f"Error in fresh process check for tab '{tab_name}': {e}")
257
- return {
258
- "status": "error",
259
- "error": str(e),
260
- "running": False,
261
- "command": command,
262
- "tab_name": tab_name,
263
- "location": self.location_name
264
- }
181
+ return {"status": "error", "error": str(e), "running": False, "command": command, "tab_name": tab_name, "location": self.location_name}
265
182
 
266
183
  def _create_fresh_check_script(self, command: str) -> str:
267
184
  """Create enhanced PowerShell process checking script with freshness validation."""
268
185
  escaped_command = command.replace("'", "''").replace('"', '""')
269
186
  cmd_parts = [part for part in command.split() if len(part) > 2]
270
- primary_cmd = cmd_parts[0] if cmd_parts else ''
187
+ primary_cmd = cmd_parts[0] if cmd_parts else ""
271
188
 
272
189
  return f"""
273
190
  Start-Sleep -Milliseconds 100
274
191
 
275
192
  $targetCommand = '{escaped_command}'
276
- $cmdParts = @({', '.join([f"'{part}'" for part in cmd_parts])})
193
+ $cmdParts = @({", ".join([f"'{part}'" for part in cmd_parts])})
277
194
  $primaryCmd = '{primary_cmd}'
278
195
  $currentPid = $PID
279
196
  $checkTime = Get-Date
@@ -391,28 +308,11 @@ ConvertTo-Json -Depth 2
391
308
  if result.returncode == 0 and result.stdout.strip():
392
309
  try:
393
310
  wt_processes = json.loads(result.stdout)
394
- return {
395
- "success": True,
396
- "windows": wt_processes if isinstance(wt_processes, list) else [wt_processes],
397
- "location": self.location_name
398
- }
311
+ return {"success": True, "windows": wt_processes if isinstance(wt_processes, list) else [wt_processes], "location": self.location_name}
399
312
  except json.JSONDecodeError:
400
- return {
401
- "success": False,
402
- "error": "Failed to parse Windows Terminal process info",
403
- "location": self.location_name
404
- }
313
+ return {"success": False, "error": "Failed to parse Windows Terminal process info", "location": self.location_name}
405
314
  else:
406
- return {
407
- "success": True,
408
- "windows": [],
409
- "message": "No Windows Terminal processes found",
410
- "location": self.location_name
411
- }
315
+ return {"success": True, "windows": [], "message": "No Windows Terminal processes found", "location": self.location_name}
412
316
  except Exception as e:
413
317
  logger.error(f"Failed to get Windows Terminal windows: {e}")
414
- return {
415
- "success": False,
416
- "error": str(e),
417
- "location": self.location_name
418
- }
318
+ return {"success": False, "error": str(e), "location": self.location_name}
@@ -3,6 +3,7 @@
3
3
  Remote command execution utilities for SSH operations with Windows Terminal.
4
4
  Adapted from zellij remote executor but focused on Windows Terminal commands.
5
5
  """
6
+
6
7
  import subprocess
7
8
  import logging
8
9
  from typing import Dict, Any, Optional, List
@@ -22,16 +23,11 @@ class WTRemoteExecutor:
22
23
  if shell == "powershell":
23
24
  # Wrap command in PowerShell invocation if needed
24
25
  if not command.startswith("powershell"):
25
- command = f"powershell -Command \"{command}\""
26
+ command = f'powershell -Command "{command}"'
26
27
 
27
28
  ssh_cmd = ["ssh", self.remote_name, command]
28
29
  try:
29
- result = subprocess.run(
30
- ssh_cmd,
31
- capture_output=True,
32
- text=True,
33
- timeout=timeout
34
- )
30
+ result = subprocess.run(ssh_cmd, capture_output=True, text=True, timeout=timeout)
35
31
  return result
36
32
  except subprocess.TimeoutExpired:
37
33
  logger.error(f"SSH command timed out after {timeout}s: {command}")
@@ -93,19 +89,10 @@ class WTRemoteExecutor:
93
89
 
94
90
  wt_available = self.check_wt_available()
95
91
 
96
- return {
97
- "windows_info": result.stdout if result.returncode == 0 else "Unknown",
98
- "wt_available": wt_available,
99
- "remote_name": self.remote_name
100
- }
92
+ return {"windows_info": result.stdout if result.returncode == 0 else "Unknown", "wt_available": wt_available, "remote_name": self.remote_name}
101
93
  except Exception as e:
102
94
  logger.error(f"Failed to get remote Windows info: {e}")
103
- return {
104
- "windows_info": "Error getting info",
105
- "wt_available": False,
106
- "remote_name": self.remote_name,
107
- "error": str(e)
108
- }
95
+ return {"windows_info": "Error getting info", "wt_available": False, "remote_name": self.remote_name, "error": str(e)}
109
96
 
110
97
  def run_wt_command(self, wt_command: str, detached: bool = True) -> subprocess.CompletedProcess[str]:
111
98
  """Run a Windows Terminal command on the remote machine."""
@@ -130,24 +117,12 @@ class WTRemoteExecutor:
130
117
  result = self.run_command(ps_command, timeout=15)
131
118
 
132
119
  if result.returncode == 0:
133
- return {
134
- "success": True,
135
- "processes": result.stdout,
136
- "remote": self.remote_name
137
- }
120
+ return {"success": True, "processes": result.stdout, "remote": self.remote_name}
138
121
  else:
139
- return {
140
- "success": False,
141
- "error": result.stderr,
142
- "remote": self.remote_name
143
- }
122
+ return {"success": False, "error": result.stderr, "remote": self.remote_name}
144
123
  except Exception as e:
145
124
  logger.error(f"Failed to list Windows Terminal processes: {e}")
146
- return {
147
- "success": False,
148
- "error": str(e),
149
- "remote": self.remote_name
150
- }
125
+ return {"success": False, "error": str(e), "remote": self.remote_name}
151
126
 
152
127
  def kill_wt_processes(self, process_ids: Optional[List[Any]] = None) -> Dict[str, Any]:
153
128
  """Kill Windows Terminal processes on the remote machine."""
@@ -161,15 +136,7 @@ class WTRemoteExecutor:
161
136
 
162
137
  result = self.run_command(kill_cmd, timeout=10)
163
138
 
164
- return {
165
- "success": result.returncode == 0,
166
- "message": "Processes killed" if result.returncode == 0 else result.stderr,
167
- "remote": self.remote_name
168
- }
139
+ return {"success": result.returncode == 0, "message": "Processes killed" if result.returncode == 0 else result.stderr, "remote": self.remote_name}
169
140
  except Exception as e:
170
141
  logger.error(f"Failed to kill Windows Terminal processes: {e}")
171
- return {
172
- "success": False,
173
- "error": str(e),
174
- "remote": self.remote_name
175
- }
142
+ return {"success": False, "error": str(e), "remote": self.remote_name}
@@ -2,6 +2,7 @@
2
2
  """
3
3
  Windows Terminal session management utilities for local and remote operations.
4
4
  """
5
+
5
6
  import logging
6
7
  import subprocess
7
8
  from typing import Dict, Any, Optional
@@ -14,8 +15,7 @@ logger = logging.getLogger(__name__)
14
15
  class WTSessionManager:
15
16
  """Handles Windows Terminal session operations on local and remote machines."""
16
17
 
17
- def __init__(self, remote_executor: Optional[WTRemoteExecutor] = None,
18
- session_name: str = "default", tmp_layout_dir: Path | None = None):
18
+ def __init__(self, remote_executor: Optional[WTRemoteExecutor] = None, session_name: str = "default", tmp_layout_dir: Path | None = None):
19
19
  self.remote_executor = remote_executor
20
20
  self.session_name = session_name
21
21
  self.tmp_layout_dir = tmp_layout_dir or Path.home() / "tmp_results" / "wt_layouts" / "layout_manager"
@@ -29,12 +29,7 @@ class WTSessionManager:
29
29
  def _run_command(self, command: str, timeout: int = 30) -> subprocess.CompletedProcess[str]:
30
30
  """Run command either locally or remotely."""
31
31
  if self.is_local:
32
- return subprocess.run(
33
- ["powershell", "-Command", command],
34
- capture_output=True,
35
- text=True,
36
- timeout=timeout
37
- )
32
+ return subprocess.run(["powershell", "-Command", command], capture_output=True, text=True, timeout=timeout)
38
33
  else:
39
34
  if self.remote_executor is None:
40
35
  raise ValueError("Remote executor is None but is_local is False")
@@ -80,6 +75,7 @@ ConvertTo-Json -Depth 2
80
75
  if output and output != "":
81
76
  try:
82
77
  import json
78
+
83
79
  processes = json.loads(output)
84
80
  if not isinstance(processes, list):
85
81
  processes = [processes]
@@ -91,49 +87,19 @@ ConvertTo-Json -Depth 2
91
87
  if self.session_name in window_title or not window_title:
92
88
  session_windows.append(proc)
93
89
 
94
- return {
95
- "wt_running": True,
96
- "session_exists": len(session_windows) > 0,
97
- "session_name": self.session_name,
98
- "all_windows": processes,
99
- "session_windows": session_windows,
100
- "location": self.location_name
101
- }
90
+ return {"wt_running": True, "session_exists": len(session_windows) > 0, "session_name": self.session_name, "all_windows": processes, "session_windows": session_windows, "location": self.location_name}
102
91
  except Exception as e:
103
92
  logger.error(f"Failed to parse Windows Terminal process info: {e}")
104
- return {
105
- "wt_running": True,
106
- "session_exists": False,
107
- "error": f"Failed to parse process info: {e}",
108
- "session_name": self.session_name,
109
- "location": self.location_name
110
- }
93
+ return {"wt_running": True, "session_exists": False, "error": f"Failed to parse process info: {e}", "session_name": self.session_name, "location": self.location_name}
111
94
  else:
112
- return {
113
- "wt_running": False,
114
- "session_exists": False,
115
- "session_name": self.session_name,
116
- "all_windows": [],
117
- "location": self.location_name
118
- }
95
+ return {"wt_running": False, "session_exists": False, "session_name": self.session_name, "all_windows": [], "location": self.location_name}
119
96
  else:
120
- return {
121
- "wt_running": False,
122
- "error": result.stderr,
123
- "session_name": self.session_name,
124
- "location": self.location_name
125
- }
97
+ return {"wt_running": False, "error": result.stderr, "session_name": self.session_name, "location": self.location_name}
126
98
 
127
99
  except Exception as e:
128
- return {
129
- "wt_running": False,
130
- "error": str(e),
131
- "session_name": self.session_name,
132
- "location": self.location_name
133
- }
134
-
135
- def start_wt_session(self, script_file_path: Optional[str] = None,
136
- wt_command: Optional[str] = None) -> Dict[str, Any]:
100
+ return {"wt_running": False, "error": str(e), "session_name": self.session_name, "location": self.location_name}
101
+
102
+ def start_wt_session(self, script_file_path: Optional[str] = None, wt_command: Optional[str] = None) -> Dict[str, Any]:
137
103
  """Start a Windows Terminal session with the generated layout."""
138
104
  try:
139
105
  if script_file_path:
@@ -164,29 +130,14 @@ ConvertTo-Json -Depth 2
164
130
 
165
131
  if result.returncode == 0:
166
132
  logger.info(f"Windows Terminal session '{self.session_name}' started successfully")
167
- return {
168
- "success": True,
169
- "session_name": self.session_name,
170
- "location": self.location_name,
171
- "message": "Session started successfully"
172
- }
133
+ return {"success": True, "session_name": self.session_name, "location": self.location_name, "message": "Session started successfully"}
173
134
  else:
174
- return {
175
- "success": False,
176
- "error": result.stderr or result.stdout,
177
- "session_name": self.session_name,
178
- "location": self.location_name
179
- }
135
+ return {"success": False, "error": result.stderr or result.stdout, "session_name": self.session_name, "location": self.location_name}
180
136
 
181
137
  except Exception as e:
182
138
  error_location = "locally" if self.is_local else f"on {self.remote_executor.remote_name if self.remote_executor else 'unknown'}"
183
139
  logger.error(f"Failed to start Windows Terminal session {error_location}: {e}")
184
- return {
185
- "success": False,
186
- "error": str(e),
187
- "session_name": self.session_name,
188
- "location": self.location_name
189
- }
140
+ return {"success": False, "error": str(e), "session_name": self.session_name, "location": self.location_name}
190
141
 
191
142
  def attach_to_session(self, window_name: Optional[str] = None) -> None:
192
143
  """Attach to a Windows Terminal session/window."""
@@ -228,24 +179,13 @@ ConvertTo-Json -Depth 2
228
179
  logger.info(f"Killing Windows Terminal session '{self.session_name}'")
229
180
  result = self._run_command(kill_cmd, timeout=10)
230
181
 
231
- return {
232
- "success": result.returncode == 0,
233
- "message": "Session killed" if result.returncode == 0 else result.stderr,
234
- "session_name": self.session_name,
235
- "location": self.location_name
236
- }
182
+ return {"success": result.returncode == 0, "message": "Session killed" if result.returncode == 0 else result.stderr, "session_name": self.session_name, "location": self.location_name}
237
183
 
238
184
  except Exception as e:
239
185
  logger.error(f"Failed to kill Windows Terminal session: {e}")
240
- return {
241
- "success": False,
242
- "error": str(e),
243
- "session_name": self.session_name,
244
- "location": self.location_name
245
- }
246
-
247
- def create_new_tab(self, tab_name: str, cwd: str, command: str,
248
- window_name: Optional[str] = None) -> Dict[str, Any]:
186
+ return {"success": False, "error": str(e), "session_name": self.session_name, "location": self.location_name}
187
+
188
+ def create_new_tab(self, tab_name: str, cwd: str, command: str, window_name: Optional[str] = None) -> Dict[str, Any]:
249
189
  """Create a new tab in the Windows Terminal session."""
250
190
  try:
251
191
  # Build the new-tab command
@@ -264,22 +204,11 @@ ConvertTo-Json -Depth 2
264
204
  logger.info(f"Creating new tab '{tab_name}' in Windows Terminal")
265
205
  result = self._run_command(new_tab_cmd, timeout=15)
266
206
 
267
- return {
268
- "success": result.returncode == 0,
269
- "message": f"Tab '{tab_name}' created" if result.returncode == 0 else result.stderr,
270
- "tab_name": tab_name,
271
- "command": command,
272
- "location": self.location_name
273
- }
207
+ return {"success": result.returncode == 0, "message": f"Tab '{tab_name}' created" if result.returncode == 0 else result.stderr, "tab_name": tab_name, "command": command, "location": self.location_name}
274
208
 
275
209
  except Exception as e:
276
210
  logger.error(f"Failed to create new tab '{tab_name}': {e}")
277
- return {
278
- "success": False,
279
- "error": str(e),
280
- "tab_name": tab_name,
281
- "location": self.location_name
282
- }
211
+ return {"success": False, "error": str(e), "tab_name": tab_name, "location": self.location_name}
283
212
 
284
213
  def get_wt_version(self) -> Dict[str, Any]:
285
214
  """Get Windows Terminal version information."""
@@ -287,14 +216,6 @@ ConvertTo-Json -Depth 2
287
216
  version_cmd = "wt --version"
288
217
  result = self._run_command(version_cmd, timeout=10)
289
218
 
290
- return {
291
- "success": result.returncode == 0,
292
- "version": result.stdout.strip() if result.returncode == 0 else "Unknown",
293
- "location": self.location_name
294
- }
219
+ return {"success": result.returncode == 0, "version": result.stdout.strip() if result.returncode == 0 else "Unknown", "location": self.location_name}
295
220
  except Exception as e:
296
- return {
297
- "success": False,
298
- "error": str(e),
299
- "location": self.location_name
300
- }
221
+ return {"success": False, "error": str(e), "location": self.location_name}