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
@@ -10,6 +10,9 @@ from machineconfig.cluster.sessions_managers.wt_remote import WTRemoteLayoutGene
10
10
 
11
11
  TMP_SERIALIZATION_DIR = Path.home().joinpath("tmp_results", "session_manager", "wt", "remote_manager")
12
12
 
13
+ # Module-level logger to be used throughout this module
14
+ logger = logging.getLogger(__name__)
15
+
13
16
 
14
17
  class WTSessionManager:
15
18
  def __init__(self, machine2wt_tabs: dict[str, dict[str, tuple[str, str]]], session_name_prefix: str = "WTJobMgr"):
@@ -34,13 +37,10 @@ class WTSessionManager:
34
37
  a_cmd = run_command_in_wt_tab(command=ssh_cmd, tab_name=hostname, cwd=None)
35
38
  cmds += a_cmd + "\n"
36
39
  return cmds
37
-
40
+
38
41
  def kill_all_sessions(self) -> None:
39
42
  for an_m in self.managers:
40
- WTRemoteLayoutGenerator.run_remote_command(
41
- remote_name=an_m.remote_name,
42
- command="powershell -Command \"Get-Process -Name 'WindowsTerminal' -ErrorAction SilentlyContinue | Stop-Process -Force\""
43
- )
43
+ WTRemoteLayoutGenerator.run_remote_command(remote_name=an_m.remote_name, command="powershell -Command \"Get-Process -Name 'WindowsTerminal' -ErrorAction SilentlyContinue | Stop-Process -Force\"")
44
44
 
45
45
  def run_monitoring_routine(self, wait_ms: int = 60000) -> None:
46
46
  def routine(scheduler: Scheduler):
@@ -60,12 +60,12 @@ class WTSessionManager:
60
60
  for i, key in enumerate(keys):
61
61
  if i < len(values):
62
62
  status_data.append({"tabName": key, "status": values[i]})
63
-
63
+
64
64
  # Check if all stopped
65
65
  running_count = sum(1 for item in status_data if item.get("status", {}).get("running", False))
66
66
  if running_count == 0: # they all stopped
67
67
  scheduler.max_cycles = scheduler.cycle # stop the scheduler from calling this routine again
68
-
68
+
69
69
  # Print status
70
70
  for item in status_data:
71
71
  print(f"Tab: {item['tabName']}, Status: {item['status']}")
@@ -74,68 +74,63 @@ class WTSessionManager:
74
74
  for _idx, an_m in enumerate(self.managers):
75
75
  a_status = an_m.check_wt_session_status()
76
76
  statuses.append(a_status)
77
-
77
+
78
78
  # Print statuses
79
79
  for i, status in enumerate(statuses):
80
80
  print(f"Manager {i}: {status}")
81
- sched = Scheduler(routine=routine, wait_ms=wait_ms)
81
+
82
+ sched = Scheduler(routine=routine, wait_ms=wait_ms, logger=logger)
82
83
  sched.run()
83
84
 
84
85
  def save(self, session_id: Optional[str] = None) -> str:
85
86
  if session_id is None:
86
87
  session_id = str(uuid.uuid4())[:8]
87
-
88
+
88
89
  # Create session directory
89
90
  session_dir = TMP_SERIALIZATION_DIR / session_id
90
91
  session_dir.mkdir(parents=True, exist_ok=True)
91
-
92
+
92
93
  # Save the machine2wt_tabs configuration
93
94
  config_file = session_dir / "machine2wt_tabs.json"
94
- with open(config_file, 'w', encoding='utf-8') as f:
95
- json.dump(self.machine2wt_tabs, f, indent=2, ensure_ascii=False)
96
-
95
+ text = json.dumps(self.machine2wt_tabs, indent=2, ensure_ascii=False)
96
+ config_file.write_text(text, encoding="utf-8")
97
+
97
98
  # Save session metadata
98
- metadata = {
99
- "session_name_prefix": self.session_name_prefix,
100
- "created_at": str(datetime.now()),
101
- "num_managers": len(self.managers),
102
- "machines": list(self.machine2wt_tabs.keys()),
103
- "manager_type": "WTSessionManager"
104
- }
99
+ metadata = {"session_name_prefix": self.session_name_prefix, "created_at": str(datetime.now()), "num_managers": len(self.managers), "machines": list(self.machine2wt_tabs.keys()), "manager_type": "WTSessionManager"}
105
100
  metadata_file = session_dir / "metadata.json"
106
- with open(metadata_file, 'w', encoding='utf-8') as f:
107
- json.dump(metadata, f, indent=2, ensure_ascii=False)
108
-
101
+ text = json.dumps(metadata, indent=2, ensure_ascii=False)
102
+ metadata_file.write_text(text, encoding="utf-8")
103
+
109
104
  # Save each WTRemoteLayoutGenerator
110
105
  managers_dir = session_dir / "managers"
111
106
  managers_dir.mkdir(exist_ok=True)
112
-
107
+
113
108
  for i, manager in enumerate(self.managers):
114
109
  manager_file = managers_dir / f"manager_{i}_{manager.remote_name}.json"
115
110
  manager.to_json(str(manager_file))
116
-
117
- logging.info(f"โœ… Saved WTSessionManager session to: {session_dir}")
111
+
112
+ logger.info(f"โœ… Saved WTSessionManager session to: {session_dir}")
118
113
  return session_id
119
114
 
120
115
  @classmethod
121
- def load(cls, session_id: str) -> 'WTSessionManager':
116
+ def load(cls, session_id: str) -> "WTSessionManager":
122
117
  session_dir = TMP_SERIALIZATION_DIR / session_id
123
-
118
+
124
119
  if not session_dir.exists():
125
- raise FileNotFoundError(f"Session directory not found: {session_dir}")
120
+ raise FileNotFoundError(f"Session directory not found: {session_dir}")
126
121
  config_file = session_dir / "machine2wt_tabs.json"
127
122
  if not config_file.exists():
128
- raise FileNotFoundError(f"Configuration file not found: {config_file}")
129
- with open(config_file, 'r', encoding='utf-8') as f:
123
+ raise FileNotFoundError(f"Configuration file not found: {config_file}")
124
+ with open(config_file, "r", encoding="utf-8") as f:
130
125
  machine2wt_tabs = json.load(f)
131
-
126
+
132
127
  # Load metadata
133
128
  metadata_file = session_dir / "metadata.json"
134
129
  session_name_prefix = "WTJobMgr" # default fallback
135
130
  if metadata_file.exists():
136
- with open(metadata_file, 'r', encoding='utf-8') as f:
131
+ with open(metadata_file, "r", encoding="utf-8") as f:
137
132
  metadata = json.load(f)
138
- session_name_prefix = metadata.get("session_name_prefix", "WTJobMgr")
133
+ session_name_prefix = metadata.get("session_name_prefix", "WTJobMgr")
139
134
  # Create new instance (this will create new managers)
140
135
  instance = cls(machine2wt_tabs=machine2wt_tabs, session_name_prefix=session_name_prefix)
141
136
  # Load saved managers to restore their states
@@ -144,43 +139,44 @@ class WTSessionManager:
144
139
  # Clear the auto-created managers and load the saved ones
145
140
  instance.managers = []
146
141
  # Get all manager files and sort them
147
- manager_files = sorted(managers_dir.glob("manager_*.json"))
142
+ manager_files = sorted(managers_dir.glob("manager_*.json"))
148
143
  for manager_file in manager_files:
149
144
  try:
150
145
  loaded_manager = WTRemoteLayoutGenerator.from_json(str(manager_file))
151
146
  instance.managers.append(loaded_manager)
152
147
  except Exception as e:
153
- logging.warning(f"Failed to load manager from {manager_file}: {e}")
154
- logging.info(f"โœ… Loaded WTSessionManager session from: {session_dir}")
148
+ logger.warning(f"Failed to load manager from {manager_file}: {e}")
149
+ logger.info(f"โœ… Loaded WTSessionManager session from: {session_dir}")
155
150
  return instance
156
151
 
157
152
  @staticmethod
158
153
  def list_saved_sessions() -> list[str]:
159
154
  if not TMP_SERIALIZATION_DIR.exists():
160
155
  return []
161
-
156
+
162
157
  sessions = []
163
158
  for item in TMP_SERIALIZATION_DIR.iterdir():
164
159
  if item.is_dir() and (item / "metadata.json").exists():
165
160
  sessions.append(item.name)
166
-
161
+
167
162
  return sorted(sessions)
168
163
 
169
164
  @staticmethod
170
165
  def delete_session(session_id: str) -> bool:
171
166
  session_dir = TMP_SERIALIZATION_DIR / session_id
172
-
167
+
173
168
  if not session_dir.exists():
174
- logging.warning(f"Session directory not found: {session_dir}")
169
+ logger.warning(f"Session directory not found: {session_dir}")
175
170
  return False
176
-
171
+
177
172
  try:
178
173
  import shutil
174
+
179
175
  shutil.rmtree(session_dir)
180
- logging.info(f"โœ… Deleted session: {session_id}")
176
+ logger.info(f"โœ… Deleted session: {session_id}")
181
177
  return True
182
178
  except Exception as e:
183
- logging.error(f"Failed to delete session {session_id}: {e}")
179
+ logger.error(f"Failed to delete session {session_id}: {e}")
184
180
  return False
185
181
 
186
182
  def start_all_sessions(self) -> dict[str, Any]:
@@ -190,85 +186,64 @@ class WTSessionManager:
190
186
  try:
191
187
  session_name = manager.session_name
192
188
  remote_name = manager.remote_name
193
-
189
+
194
190
  # Start the Windows Terminal session on the remote machine
195
191
  start_result = manager.start_wt_session()
196
-
192
+
197
193
  results[f"{remote_name}:{session_name}"] = start_result
198
-
194
+
199
195
  if start_result.get("success"):
200
- logging.info(f"โœ… Started session '{session_name}' on {remote_name}")
196
+ logger.info(f"โœ… Started session '{session_name}' on {remote_name}")
201
197
  else:
202
- logging.error(f"โŒ Failed to start session '{session_name}' on {remote_name}: {start_result.get('error')}")
203
-
198
+ logger.error(f"โŒ Failed to start session '{session_name}' on {remote_name}: {start_result.get('error')}")
199
+
204
200
  except Exception as e:
205
- results[f"{manager.remote_name}:{manager.session_name}"] = {
206
- "success": False,
207
- "error": str(e)
208
- }
209
- logging.error(f"โŒ Exception starting session on {manager.remote_name}: {e}")
210
-
201
+ results[f"{manager.remote_name}:{manager.session_name}"] = {"success": False, "error": str(e)}
202
+ logger.error(f"โŒ Exception starting session on {manager.remote_name}: {e}")
203
+
211
204
  return results
212
205
 
213
206
  def check_all_sessions_status(self) -> dict[str, dict[str, Any]]:
214
207
  """Check the status of all remote sessions and their commands."""
215
208
  status_report = {}
216
-
209
+
217
210
  for manager in self.managers:
218
211
  session_key = f"{manager.remote_name}:{manager.session_name}"
219
-
212
+
220
213
  try:
221
214
  # Get Windows Terminal session status
222
215
  wt_status = manager.check_wt_session_status()
223
-
216
+
224
217
  # Get commands status for this session
225
218
  commands_status = manager.check_all_commands_status()
226
-
219
+
227
220
  # Calculate summary for this session
228
221
  running_count = sum(1 for status in commands_status.values() if status.get("running", False))
229
222
  total_count = len(commands_status)
230
-
223
+
231
224
  status_report[session_key] = {
232
225
  "remote_name": manager.remote_name,
233
226
  "session_name": manager.session_name,
234
227
  "wt_status": wt_status,
235
228
  "commands_status": commands_status,
236
- "summary": {
237
- "total_commands": total_count,
238
- "running_commands": running_count,
239
- "stopped_commands": total_count - running_count,
240
- "session_healthy": wt_status.get("wt_running", False)
241
- }
229
+ "summary": {"total_commands": total_count, "running_commands": running_count, "stopped_commands": total_count - running_count, "session_healthy": wt_status.get("wt_running", False)},
242
230
  }
243
-
231
+
244
232
  except Exception as e:
245
- status_report[session_key] = {
246
- "remote_name": manager.remote_name,
247
- "session_name": manager.session_name,
248
- "error": str(e),
249
- "summary": {
250
- "total_commands": 0,
251
- "running_commands": 0,
252
- "stopped_commands": 0,
253
- "session_healthy": False
254
- }
255
- }
256
- logging.error(f"Error checking status for {session_key}: {e}")
257
-
233
+ status_report[session_key] = {"remote_name": manager.remote_name, "session_name": manager.session_name, "error": str(e), "summary": {"total_commands": 0, "running_commands": 0, "stopped_commands": 0, "session_healthy": False}}
234
+ logger.error(f"Error checking status for {session_key}: {e}")
235
+
258
236
  return status_report
259
237
 
260
238
  def get_global_summary(self) -> dict[str, Any]:
261
239
  """Get a global summary across all remote sessions."""
262
240
  all_status = self.check_all_sessions_status()
263
-
241
+
264
242
  total_sessions = len(all_status)
265
- healthy_sessions = sum(1 for status in all_status.values()
266
- if status["summary"]["session_healthy"])
267
- total_commands = sum(status["summary"]["total_commands"]
268
- for status in all_status.values())
269
- total_running = sum(status["summary"]["running_commands"]
270
- for status in all_status.values())
271
-
243
+ healthy_sessions = sum(1 for status in all_status.values() if status["summary"]["session_healthy"])
244
+ total_commands = sum(status["summary"]["total_commands"] for status in all_status.values())
245
+ total_running = sum(status["summary"]["running_commands"] for status in all_status.values())
246
+
272
247
  return {
273
248
  "total_sessions": total_sessions,
274
249
  "healthy_sessions": healthy_sessions,
@@ -278,18 +253,18 @@ class WTSessionManager:
278
253
  "stopped_commands": total_commands - total_running,
279
254
  "all_sessions_healthy": healthy_sessions == total_sessions,
280
255
  "all_commands_running": total_running == total_commands,
281
- "remote_machines": list(set(status["remote_name"] for status in all_status.values()))
256
+ "remote_machines": list(set(status["remote_name"] for status in all_status.values())),
282
257
  }
283
258
 
284
259
  def print_status_report(self) -> None:
285
260
  """Print a comprehensive status report for all remote sessions."""
286
261
  all_status = self.check_all_sessions_status()
287
262
  global_summary = self.get_global_summary()
288
-
263
+
289
264
  print("=" * 80)
290
265
  print("๐Ÿ–ฅ๏ธ WINDOWS TERMINAL REMOTE MANAGER STATUS REPORT")
291
266
  print("=" * 80)
292
-
267
+
293
268
  # Global summary
294
269
  print("๐ŸŒ GLOBAL SUMMARY:")
295
270
  print(f" Total sessions: {global_summary['total_sessions']}")
@@ -299,24 +274,24 @@ class WTSessionManager:
299
274
  print(f" Remote machines: {len(global_summary['remote_machines'])}")
300
275
  print(f" All healthy: {'โœ…' if global_summary['all_sessions_healthy'] else 'โŒ'}")
301
276
  print()
302
-
277
+
303
278
  # Per-session details
304
279
  for _, status in all_status.items():
305
280
  remote_name = status["remote_name"]
306
281
  session_name = status["session_name"]
307
-
282
+
308
283
  print(f"๐Ÿ–ฅ๏ธ REMOTE: {remote_name} | SESSION: {session_name}")
309
284
  print("-" * 60)
310
-
285
+
311
286
  if "error" in status:
312
287
  print(f"โŒ Error: {status['error']}")
313
288
  print()
314
289
  continue
315
-
290
+
316
291
  wt_status = status["wt_status"]
317
292
  commands_status = status["commands_status"]
318
293
  summary = status["summary"]
319
-
294
+
320
295
  # Windows Terminal session health
321
296
  if wt_status.get("wt_running", False):
322
297
  if wt_status.get("session_exists", False):
@@ -329,7 +304,7 @@ class WTSessionManager:
329
304
  print(f"โš ๏ธ Windows Terminal is running but no session windows found on {remote_name}")
330
305
  else:
331
306
  print(f"โŒ Windows Terminal issue on {remote_name}: {wt_status.get('error', 'Unknown error')}")
332
-
307
+
333
308
  # Commands in this session
334
309
  print(f" Commands ({summary['running_commands']}/{summary['total_commands']} running):")
335
310
  for tab_name, cmd_status in commands_status.items():
@@ -338,146 +313,132 @@ class WTSessionManager:
338
313
  if len(cmd_status.get("command", "")) > 50:
339
314
  cmd_text += "..."
340
315
  print(f" {status_icon} {tab_name}: {cmd_text}")
341
-
316
+
342
317
  if cmd_status.get("processes"):
343
318
  for proc in cmd_status["processes"][:2]: # Show first 2 processes
344
319
  print(f" โ””โ”€ PID {proc.get('pid', 'Unknown')}: {proc.get('name', 'Unknown')}")
345
320
  print()
346
-
321
+
347
322
  print("=" * 80)
348
323
 
349
324
  def get_remote_overview(self) -> dict[str, Any]:
350
325
  """Get overview of all remote machines and their Windows Terminal status."""
351
326
  overview = {}
352
-
327
+
353
328
  for manager in self.managers:
354
329
  try:
355
330
  remote_name = manager.remote_name
356
-
331
+
357
332
  # Get remote Windows info
358
333
  windows_info = manager.get_remote_windows_info()
359
-
334
+
360
335
  # Get Windows Terminal processes
361
336
  wt_processes = manager.list_wt_processes()
362
-
337
+
363
338
  # Get Windows Terminal version
364
339
  wt_version = manager.get_wt_version()
365
-
366
- overview[remote_name] = {
367
- "windows_info": windows_info,
368
- "wt_processes": wt_processes,
369
- "wt_version": wt_version,
370
- "session_name": manager.session_name,
371
- "tab_count": len(manager.tab_config)
372
- }
373
-
340
+
341
+ overview[remote_name] = {"windows_info": windows_info, "wt_processes": wt_processes, "wt_version": wt_version, "session_name": manager.session_name, "tab_count": len(manager.tab_config)}
342
+
374
343
  except Exception as e:
375
- overview[manager.remote_name] = {
376
- "error": str(e),
377
- "session_name": manager.session_name
378
- }
379
-
344
+ overview[manager.remote_name] = {"error": str(e), "session_name": manager.session_name}
345
+
380
346
  return overview
381
347
 
382
348
  def print_remote_overview(self) -> None:
383
349
  """Print overview of all remote machines."""
384
350
  overview = self.get_remote_overview()
385
-
351
+
386
352
  print("=" * 80)
387
353
  print("๐ŸŒ REMOTE MACHINES OVERVIEW")
388
354
  print("=" * 80)
389
-
355
+
390
356
  for remote_name, info in overview.items():
391
357
  print(f"๐Ÿ–ฅ๏ธ REMOTE: {remote_name}")
392
358
  print("-" * 40)
393
-
359
+
394
360
  if "error" in info:
395
361
  print(f"โŒ Error: {info['error']}")
396
362
  print()
397
363
  continue
398
-
364
+
399
365
  # Windows Terminal availability
400
366
  windows_info = info.get("windows_info", {})
401
367
  wt_available = windows_info.get("wt_available", False)
402
368
  print(f"Windows Terminal: {'โœ… Available' if wt_available else 'โŒ Not Available'}")
403
-
369
+
404
370
  # Version info
405
371
  wt_version = info.get("wt_version", {})
406
372
  if wt_version.get("success"):
407
373
  print(f"Version: {wt_version.get('version', 'Unknown')}")
408
-
374
+
409
375
  # Current processes
410
376
  wt_processes = info.get("wt_processes", {})
411
377
  if wt_processes.get("success"):
412
378
  processes_output = wt_processes.get("processes", "")
413
379
  if processes_output.strip():
414
- print(f"Active processes: Found")
380
+ print("Active processes: Found")
415
381
  else:
416
- print(f"Active processes: None")
417
-
382
+ print("Active processes: None")
383
+
418
384
  # Session info
419
385
  session_name = info.get("session_name", "Unknown")
420
386
  tab_count = info.get("tab_count", 0)
421
387
  print(f"Managed session: {session_name} ({tab_count} tabs)")
422
-
388
+
423
389
  print()
424
-
390
+
425
391
  print("=" * 80)
426
392
 
427
393
 
428
394
  if __name__ == "__main__":
429
395
  # Example usage
430
396
  sample_machines = {
431
- "server1": {
432
- "๐Ÿค–Bot1": ("~/code/project", "python bot1.py"),
433
- "๐Ÿ“ŠMonitor": ("~", "Get-Process | Sort-Object CPU -Descending | Select-Object -First 10"),
434
- },
435
- "server2": {
436
- "๐Ÿค–Bot2": ("~/code/project", "python bot2.py"),
437
- "๐Ÿ“Logs": ("C:/logs", "Get-Content app.log -Wait"),
438
- }
397
+ "server1": {"๐Ÿค–Bot1": ("~/code/project", "python bot1.py"), "๐Ÿ“ŠMonitor": ("~", "Get-Process | Sort-Object CPU -Descending | Select-Object -First 10")},
398
+ "server2": {"๐Ÿค–Bot2": ("~/code/project", "python bot2.py"), "๐Ÿ“Logs": ("C:/logs", "Get-Content app.log -Wait")},
439
399
  }
440
-
400
+
441
401
  try:
442
402
  # Create the remote manager
443
403
  manager = WTSessionManager(sample_machines, session_name_prefix="RemoteJobs")
444
404
  print(f"โœ… Remote manager created with {len(manager.managers)} remote sessions")
445
-
405
+
446
406
  # Show SSH commands
447
407
  print("\n๐Ÿ“Ž SSH commands to connect to all machines:")
448
408
  ssh_commands = manager.ssh_to_all_machines()
449
409
  print(ssh_commands)
450
-
410
+
451
411
  # Show current status
452
412
  print("\n๐Ÿ” Current status:")
453
413
  manager.print_status_report()
454
-
414
+
455
415
  # Show remote overview
456
416
  print("\n๐ŸŒ Remote machines overview:")
457
417
  manager.print_remote_overview()
458
-
418
+
459
419
  # Demonstrate save/load
460
420
  print("\n๐Ÿ’พ Demonstrating save/load...")
461
421
  session_id = manager.save()
462
422
  print(f"โœ… Saved session: {session_id}")
463
-
423
+
464
424
  # List saved sessions
465
425
  saved_sessions = WTSessionManager.list_saved_sessions()
466
426
  print(f"๐Ÿ“‹ Saved sessions: {saved_sessions}")
467
-
427
+
468
428
  # Load and verify
469
429
  loaded_manager = WTSessionManager.load(session_id)
470
430
  print(f"โœ… Loaded session with {len(loaded_manager.managers)} remote sessions")
471
-
431
+
472
432
  # Show how to start sessions
473
433
  print("\nโ–ถ๏ธ To start all sessions, run:")
474
434
  print("manager.start_all_sessions()")
475
-
435
+
476
436
  # Show how to start monitoring (commented out to prevent infinite loop in demo)
477
437
  print("\nโฐ To start monitoring, run:")
478
438
  print("manager.run_monitoring_routine(wait_ms=60000) # 60 seconds")
479
-
439
+
480
440
  except Exception as e:
481
441
  print(f"โŒ Error: {e}")
482
442
  import traceback
483
- traceback.print_exc()
443
+
444
+ traceback.print_exc()