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
@@ -17,11 +17,11 @@ TMP_SERIALIZATION_DIR = Path.home().joinpath("tmp_results", "session_manager", "
17
17
 
18
18
  class WTLocalManager:
19
19
  """Manages multiple local Windows Terminal sessions and monitors their tabs and processes."""
20
-
20
+
21
21
  def __init__(self, session2wt_tabs: Dict[str, Dict[str, tuple[str, str]]], session_name_prefix: str = "LocalWTMgr"):
22
22
  """
23
23
  Initialize the local Windows Terminal manager.
24
-
24
+
25
25
  Args:
26
26
  session2wt_tabs: Dict mapping session names to their tab configs
27
27
  Format: {session_name: {tab_name: (cwd, command), ...}, ...}
@@ -30,14 +30,14 @@ class WTLocalManager:
30
30
  self.session_name_prefix = session_name_prefix
31
31
  self.session2wt_tabs = session2wt_tabs # Store the original config
32
32
  self.managers: List[WTLayoutGenerator] = []
33
-
33
+
34
34
  # Create a WTLayoutGenerator for each session
35
35
  for session_name, tab_config in session2wt_tabs.items():
36
36
  manager = WTLayoutGenerator()
37
37
  full_session_name = f"{self.session_name_prefix}_{session_name}"
38
38
  manager.create_wt_layout(tab_config=tab_config, session_name=full_session_name)
39
39
  self.managers.append(manager)
40
-
40
+
41
41
  logger.info(f"Initialized WTLocalManager with {len(self.managers)} sessions")
42
42
 
43
43
  def get_all_session_names(self) -> List[str]:
@@ -51,40 +51,28 @@ class WTLocalManager:
51
51
  session_name = manager.session_name or "unknown"
52
52
  try:
53
53
  script_path = manager.script_path
54
-
54
+
55
55
  if not script_path:
56
- results[session_name] = {
57
- "success": False,
58
- "error": "No script file path available"
59
- }
56
+ results[session_name] = {"success": False, "error": "No script file path available"}
60
57
  continue
61
-
58
+
62
59
  # Execute the PowerShell script to start Windows Terminal
63
- cmd = f"powershell -ExecutionPolicy Bypass -File \"{script_path}\""
64
-
60
+ cmd = f'powershell -ExecutionPolicy Bypass -File "{script_path}"'
61
+
65
62
  logger.info(f"Starting session '{session_name}' with script: {script_path}")
66
63
  result = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=30)
67
-
64
+
68
65
  if result.returncode == 0:
69
- results[session_name] = {
70
- "success": True,
71
- "message": f"Session '{session_name}' started successfully"
72
- }
66
+ results[session_name] = {"success": True, "message": f"Session '{session_name}' started successfully"}
73
67
  logger.info(f"✅ Session '{session_name}' started successfully")
74
68
  else:
75
- results[session_name] = {
76
- "success": False,
77
- "error": result.stderr or result.stdout
78
- }
69
+ results[session_name] = {"success": False, "error": result.stderr or result.stdout}
79
70
  logger.error(f"❌ Failed to start session '{session_name}': {result.stderr}")
80
-
71
+
81
72
  except Exception as e:
82
- results[session_name] = {
83
- "success": False,
84
- "error": str(e)
85
- }
73
+ results[session_name] = {"success": False, "error": str(e)}
86
74
  logger.error(f"❌ Exception starting session '{session_name}': {e}")
87
-
75
+
88
76
  return results
89
77
 
90
78
  def kill_all_sessions(self) -> Dict[str, Any]:
@@ -95,30 +83,24 @@ class WTLocalManager:
95
83
  try:
96
84
  # Kill all Windows Terminal processes (Windows Terminal doesn't have session-specific killing)
97
85
  cmd = "powershell -Command \"Get-Process -Name 'WindowsTerminal' -ErrorAction SilentlyContinue | Stop-Process -Force\""
98
-
86
+
99
87
  logger.info(f"Killing Windows Terminal processes for session '{session_name}'")
100
88
  result = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=10)
101
-
102
- results[session_name] = {
103
- "success": result.returncode == 0,
104
- "message": "Windows Terminal processes killed" if result.returncode == 0 else result.stderr
105
- }
106
-
89
+
90
+ results[session_name] = {"success": result.returncode == 0, "message": "Windows Terminal processes killed" if result.returncode == 0 else result.stderr}
91
+
107
92
  except Exception as e:
108
- results[session_name] = {
109
- "success": False,
110
- "error": str(e)
111
- }
112
-
93
+ results[session_name] = {"success": False, "error": str(e)}
94
+
113
95
  return results
114
96
 
115
97
  def attach_to_session(self, session_name: Optional[str] = None) -> str:
116
98
  """
117
99
  Generate command to attach to a specific session or list attachment commands for all.
118
-
100
+
119
101
  Args:
120
102
  session_name: Specific session to attach to, or None for all sessions
121
-
103
+
122
104
  Returns:
123
105
  Command string to attach to session(s)
124
106
  """
@@ -140,45 +122,37 @@ class WTLocalManager:
140
122
  def check_all_sessions_status(self) -> Dict[str, Dict[str, Any]]:
141
123
  """Check the status of all sessions and their commands."""
142
124
  status_report = {}
143
-
125
+
144
126
  for manager in self.managers:
145
127
  session_name = manager.session_name or "default"
146
-
128
+
147
129
  # Get session status
148
130
  session_status = WTLayoutGenerator.check_wt_session_status(session_name)
149
-
131
+
150
132
  # Get commands status for this session
151
133
  commands_status = manager.check_all_commands_status()
152
-
134
+
153
135
  # Calculate summary for this session
154
136
  running_count = sum(1 for status in commands_status.values() if status.get("running", False))
155
137
  total_count = len(commands_status)
156
-
138
+
157
139
  status_report[session_name] = {
158
140
  "session_status": session_status,
159
141
  "commands_status": commands_status,
160
- "summary": {
161
- "total_commands": total_count,
162
- "running_commands": running_count,
163
- "stopped_commands": total_count - running_count,
164
- "session_healthy": session_status.get("session_exists", False)
165
- }
142
+ "summary": {"total_commands": total_count, "running_commands": running_count, "stopped_commands": total_count - running_count, "session_healthy": session_status.get("session_exists", False)},
166
143
  }
167
-
144
+
168
145
  return status_report
169
146
 
170
147
  def get_global_summary(self) -> Dict[str, Any]:
171
148
  """Get a global summary across all sessions."""
172
149
  all_status = self.check_all_sessions_status()
173
-
150
+
174
151
  total_sessions = len(all_status)
175
- healthy_sessions = sum(1 for status in all_status.values()
176
- if status["summary"]["session_healthy"])
177
- total_commands = sum(status["summary"]["total_commands"]
178
- for status in all_status.values())
179
- total_running = sum(status["summary"]["running_commands"]
180
- for status in all_status.values())
181
-
152
+ healthy_sessions = sum(1 for status in all_status.values() if status["summary"]["session_healthy"])
153
+ total_commands = sum(status["summary"]["total_commands"] for status in all_status.values())
154
+ total_running = sum(status["summary"]["running_commands"] for status in all_status.values())
155
+
182
156
  return {
183
157
  "total_sessions": total_sessions,
184
158
  "healthy_sessions": healthy_sessions,
@@ -187,18 +161,18 @@ class WTLocalManager:
187
161
  "running_commands": total_running,
188
162
  "stopped_commands": total_commands - total_running,
189
163
  "all_sessions_healthy": healthy_sessions == total_sessions,
190
- "all_commands_running": total_running == total_commands
164
+ "all_commands_running": total_running == total_commands,
191
165
  }
192
166
 
193
167
  def print_status_report(self) -> None:
194
168
  """Print a comprehensive status report for all sessions."""
195
169
  all_status = self.check_all_sessions_status()
196
170
  global_summary = self.get_global_summary()
197
-
171
+
198
172
  print("=" * 80)
199
173
  print("🖥️ WINDOWS TERMINAL LOCAL MANAGER STATUS REPORT")
200
174
  print("=" * 80)
201
-
175
+
202
176
  # Global summary
203
177
  print("🌐 GLOBAL SUMMARY:")
204
178
  print(f" Total sessions: {global_summary['total_sessions']}")
@@ -207,16 +181,16 @@ class WTLocalManager:
207
181
  print(f" Running commands: {global_summary['running_commands']}")
208
182
  print(f" All healthy: {'✅' if global_summary['all_sessions_healthy'] else '❌'}")
209
183
  print()
210
-
184
+
211
185
  # Per-session details
212
186
  for session_name, status in all_status.items():
213
187
  session_status = status["session_status"]
214
188
  commands_status = status["commands_status"]
215
189
  summary = status["summary"]
216
-
190
+
217
191
  print(f"🪟 SESSION: {session_name}")
218
192
  print("-" * 60)
219
-
193
+
220
194
  # Session health
221
195
  if session_status.get("wt_running", False):
222
196
  if session_status.get("session_exists", False):
@@ -229,7 +203,7 @@ class WTLocalManager:
229
203
  print("⚠️ Windows Terminal is running but no session windows found")
230
204
  else:
231
205
  print(f"❌ Windows Terminal session issue: {session_status.get('error', 'Unknown error')}")
232
-
206
+
233
207
  # Commands in this session
234
208
  print(f" Commands ({summary['running_commands']}/{summary['total_commands']} running):")
235
209
  for tab_name, cmd_status in commands_status.items():
@@ -238,41 +212,44 @@ class WTLocalManager:
238
212
  if len(cmd_status.get("command", "")) > 50:
239
213
  cmd_text += "..."
240
214
  print(f" {status_icon} {tab_name}: {cmd_text}")
241
-
215
+
242
216
  if cmd_status.get("processes"):
243
217
  for proc in cmd_status["processes"][:2]: # Show first 2 processes
244
218
  print(f" └─ PID {proc['pid']}: {proc['name']}")
245
219
  print()
246
-
220
+
247
221
  print("=" * 80)
248
222
 
249
223
  def run_monitoring_routine(self, wait_ms: int = 30000) -> None:
250
224
  """
251
225
  Run a continuous monitoring routine that checks status periodically.
252
-
226
+
253
227
  Args:
254
228
  wait_ms: How long to wait between checks in milliseconds (default: 30000ms = 30s)
255
229
  """
230
+
256
231
  def routine(scheduler: Scheduler):
257
232
  print(f"\n⏰ Monitoring cycle {scheduler.cycle} at {datetime.now()}")
258
233
  print("-" * 50)
259
-
234
+
260
235
  if scheduler.cycle % 2 == 0:
261
236
  # Detailed status check every other cycle
262
237
  all_status = self.check_all_sessions_status()
263
-
238
+
264
239
  # Create DataFrame-like data for easier viewing
265
240
  status_data = []
266
241
  for session_name, status in all_status.items():
267
242
  for tab_name, cmd_status in status["commands_status"].items():
268
- status_data.append({
269
- "session": session_name,
270
- "tab": tab_name,
271
- "running": cmd_status.get("running", False),
272
- "command": cmd_status.get("command", "Unknown")[:50] + "..." if len(cmd_status.get("command", "")) > 50 else cmd_status.get("command", ""),
273
- "processes": len(cmd_status.get("processes", []))
274
- })
275
-
243
+ status_data.append(
244
+ {
245
+ "session": session_name,
246
+ "tab": tab_name,
247
+ "running": cmd_status.get("running", False),
248
+ "command": cmd_status.get("command", "Unknown")[:50] + "..." if len(cmd_status.get("command", "")) > 50 else cmd_status.get("command", ""),
249
+ "processes": len(cmd_status.get("processes", [])),
250
+ }
251
+ )
252
+
276
253
  if status_data:
277
254
  # Format data as table
278
255
  headers = ["session", "tab", "running", "command", "processes"]
@@ -283,7 +260,7 @@ class WTLocalManager:
283
260
  for row in status_data:
284
261
  values = [str(row.get(h, ""))[:15] for h in headers]
285
262
  print(" | ".join(f"{v:<15}" for v in values))
286
-
263
+
287
264
  # Check if all sessions have stopped
288
265
  running_count = sum(1 for row in status_data if row.get("running", False))
289
266
  if running_count == 0:
@@ -296,103 +273,93 @@ class WTLocalManager:
296
273
  # Quick summary check
297
274
  global_summary = self.get_global_summary()
298
275
  print(f"📊 Quick Summary: {global_summary['running_commands']}/{global_summary['total_commands']} commands running across {global_summary['healthy_sessions']}/{global_summary['total_sessions']} sessions")
299
-
276
+
300
277
  logger.info(f"Starting monitoring routine with {wait_ms}ms intervals")
301
- sched = Scheduler(routine=routine, wait_ms=wait_ms)
278
+ sched = Scheduler(routine=routine, wait_ms=wait_ms, logger=logger)
302
279
  sched.run(max_cycles=None)
303
280
 
304
281
  def save(self, session_id: Optional[str] = None) -> str:
305
282
  """Save the manager state to disk."""
306
283
  if session_id is None:
307
284
  session_id = str(uuid.uuid4())[:8]
308
-
285
+
309
286
  # Create session directory
310
287
  session_dir = TMP_SERIALIZATION_DIR / session_id
311
288
  session_dir.mkdir(parents=True, exist_ok=True)
312
-
289
+
313
290
  # Save the session2wt_tabs configuration
314
291
  config_file = session_dir / "session2wt_tabs.json"
315
- with open(config_file, 'w', encoding='utf-8') as f:
316
- json.dump(self.session2wt_tabs, f, indent=2, ensure_ascii=False)
317
-
292
+ text = json.dumps(self.session2wt_tabs, indent=2, ensure_ascii=False)
293
+ config_file.write_text(text, encoding="utf-8")
294
+
318
295
  # Save metadata
319
- metadata = {
320
- "session_name_prefix": self.session_name_prefix,
321
- "created_at": str(datetime.now()),
322
- "num_managers": len(self.managers),
323
- "sessions": list(self.session2wt_tabs.keys()),
324
- "manager_type": "WTLocalManager"
325
- }
296
+ metadata = {"session_name_prefix": self.session_name_prefix, "created_at": str(datetime.now()), "num_managers": len(self.managers), "sessions": list(self.session2wt_tabs.keys()), "manager_type": "WTLocalManager"}
326
297
  metadata_file = session_dir / "metadata.json"
327
- with open(metadata_file, 'w', encoding='utf-8') as f:
328
- json.dump(metadata, f, indent=2, ensure_ascii=False)
329
-
298
+ text = json.dumps(metadata, indent=2, ensure_ascii=False)
299
+ metadata_file.write_text(text, encoding="utf-8")
300
+
330
301
  # Save each manager's state
331
302
  managers_dir = session_dir / "managers"
332
303
  managers_dir.mkdir(exist_ok=True)
333
-
304
+
334
305
  for i, manager in enumerate(self.managers):
335
- manager_data = {
336
- "session_name": manager.session_name,
337
- "tab_config": manager.tab_config,
338
- "script_path": manager.script_path
339
- }
306
+ manager_data = {"session_name": manager.session_name, "tab_config": manager.tab_config, "script_path": manager.script_path}
340
307
  manager_file = managers_dir / f"manager_{i}_{manager.session_name}.json"
341
- with open(manager_file, 'w', encoding='utf-8') as f:
342
- json.dump(manager_data, f, indent=2, ensure_ascii=False)
343
-
308
+ text = json.dumps(manager_data, indent=2, ensure_ascii=False)
309
+ manager_file.write_text(text, encoding="utf-8")
310
+
344
311
  logger.info(f"✅ Saved WTLocalManager session to: {session_dir}")
345
312
  return session_id
346
313
 
347
314
  @classmethod
348
- def load(cls, session_id: str) -> 'WTLocalManager':
315
+ def load(cls, session_id: str) -> "WTLocalManager":
349
316
  """Load a saved manager state from disk."""
350
317
  session_dir = TMP_SERIALIZATION_DIR / session_id
351
-
318
+
352
319
  if not session_dir.exists():
353
320
  raise FileNotFoundError(f"Session directory not found: {session_dir}")
354
-
321
+
355
322
  # Load configuration
356
323
  config_file = session_dir / "session2wt_tabs.json"
357
324
  if not config_file.exists():
358
325
  raise FileNotFoundError(f"Configuration file not found: {config_file}")
359
-
360
- with open(config_file, 'r', encoding='utf-8') as f:
326
+
327
+ with open(config_file, "r", encoding="utf-8") as f:
361
328
  session2wt_tabs = json.load(f)
362
-
329
+
363
330
  # Load metadata
364
331
  metadata_file = session_dir / "metadata.json"
365
332
  session_name_prefix = "LocalWTMgr" # default fallback
366
333
  if metadata_file.exists():
367
- with open(metadata_file, 'r', encoding='utf-8') as f:
334
+ with open(metadata_file, "r", encoding="utf-8") as f:
368
335
  metadata = json.load(f)
369
336
  session_name_prefix = metadata.get("session_name_prefix", "LocalWTMgr")
370
-
337
+
371
338
  # Create new instance
372
339
  instance = cls(session2wt_tabs=session2wt_tabs, session_name_prefix=session_name_prefix)
373
-
340
+
374
341
  # Load saved manager states
375
342
  managers_dir = session_dir / "managers"
376
343
  if managers_dir.exists():
377
344
  instance.managers = []
378
345
  manager_files = sorted(managers_dir.glob("manager_*.json"))
379
-
346
+
380
347
  for manager_file in manager_files:
381
348
  try:
382
- with open(manager_file, 'r', encoding='utf-8') as f:
349
+ with open(manager_file, "r", encoding="utf-8") as f:
383
350
  manager_data = json.load(f)
384
-
351
+
385
352
  # Recreate the manager
386
353
  manager = WTLayoutGenerator()
387
354
  manager.session_name = manager_data["session_name"]
388
355
  manager.tab_config = manager_data["tab_config"]
389
356
  manager.script_path = manager_data["script_path"]
390
-
357
+
391
358
  instance.managers.append(manager)
392
-
359
+
393
360
  except Exception as e:
394
361
  logger.warning(f"Failed to load manager from {manager_file}: {e}")
395
-
362
+
396
363
  logger.info(f"✅ Loaded WTLocalManager session from: {session_dir}")
397
364
  return instance
398
365
 
@@ -401,25 +368,26 @@ class WTLocalManager:
401
368
  """List all saved session IDs."""
402
369
  if not TMP_SERIALIZATION_DIR.exists():
403
370
  return []
404
-
371
+
405
372
  sessions = []
406
373
  for item in TMP_SERIALIZATION_DIR.iterdir():
407
374
  if item.is_dir() and (item / "metadata.json").exists():
408
375
  sessions.append(item.name)
409
-
376
+
410
377
  return sorted(sessions)
411
378
 
412
379
  @staticmethod
413
380
  def delete_session(session_id: str) -> bool:
414
381
  """Delete a saved session."""
415
382
  session_dir = TMP_SERIALIZATION_DIR / session_id
416
-
383
+
417
384
  if not session_dir.exists():
418
385
  logger.warning(f"Session directory not found: {session_dir}")
419
386
  return False
420
-
387
+
421
388
  try:
422
389
  import shutil
390
+
423
391
  shutil.rmtree(session_dir)
424
392
  logger.info(f"✅ Deleted session: {session_id}")
425
393
  return True
@@ -430,121 +398,82 @@ class WTLocalManager:
430
398
  def list_active_sessions(self) -> List[Dict[str, Any]]:
431
399
  """List currently active Windows Terminal sessions managed by this instance."""
432
400
  active_sessions = []
433
-
401
+
434
402
  try:
435
403
  # Get all running Windows Terminal processes
436
404
  result = subprocess.run(
437
- ['powershell', '-Command',
438
- 'Get-Process -Name "WindowsTerminal" -ErrorAction SilentlyContinue | Select-Object Id, ProcessName, StartTime, MainWindowTitle | ConvertTo-Json -Depth 2'],
439
- capture_output=True,
440
- text=True,
441
- timeout=10
405
+ ["powershell", "-Command", 'Get-Process -Name "WindowsTerminal" -ErrorAction SilentlyContinue | Select-Object Id, ProcessName, StartTime, MainWindowTitle | ConvertTo-Json -Depth 2'], capture_output=True, text=True, timeout=10
442
406
  )
443
-
407
+
444
408
  if result.returncode == 0 and result.stdout.strip():
445
409
  import json
410
+
446
411
  all_processes = json.loads(result.stdout.strip())
447
412
  if not isinstance(all_processes, list):
448
413
  all_processes = [all_processes]
449
-
414
+
450
415
  # Filter to only our managed sessions
451
416
  for manager in self.managers:
452
417
  session_name = manager.session_name
453
418
  session_windows = []
454
-
419
+
455
420
  for proc in all_processes:
456
421
  window_title = proc.get("MainWindowTitle", "")
457
422
  if session_name in window_title or not window_title:
458
423
  session_windows.append(proc)
459
-
460
- active_sessions.append({
461
- "session_name": session_name,
462
- "is_active": len(session_windows) > 0,
463
- "tab_count": len(manager.tab_config),
464
- "tabs": list(manager.tab_config.keys()),
465
- "windows": session_windows
466
- })
467
-
424
+
425
+ active_sessions.append({"session_name": session_name, "is_active": len(session_windows) > 0, "tab_count": len(manager.tab_config), "tabs": list(manager.tab_config.keys()), "windows": session_windows})
426
+
468
427
  except Exception as e:
469
428
  logger.error(f"Error listing active sessions: {e}")
470
-
429
+
471
430
  return active_sessions
472
431
 
473
432
  def get_wt_overview(self) -> Dict[str, Any]:
474
433
  """Get overview of all Windows Terminal windows and processes."""
475
434
  try:
476
435
  result = subprocess.run(
477
- ['powershell', '-Command',
478
- 'Get-Process -Name "WindowsTerminal" -ErrorAction SilentlyContinue | Select-Object Id, ProcessName, StartTime, MainWindowTitle, CPU | ConvertTo-Json -Depth 2'],
479
- capture_output=True,
480
- text=True,
481
- timeout=10
436
+ ["powershell", "-Command", 'Get-Process -Name "WindowsTerminal" -ErrorAction SilentlyContinue | Select-Object Id, ProcessName, StartTime, MainWindowTitle, CPU | ConvertTo-Json -Depth 2'], capture_output=True, text=True, timeout=10
482
437
  )
483
-
438
+
484
439
  if result.returncode == 0 and result.stdout.strip():
485
440
  import json
441
+
486
442
  processes = json.loads(result.stdout.strip())
487
443
  if not isinstance(processes, list):
488
444
  processes = [processes]
489
-
490
- return {
491
- "success": True,
492
- "total_windows": len(processes),
493
- "windows": processes,
494
- "managed_sessions": len(self.managers)
495
- }
445
+
446
+ return {"success": True, "total_windows": len(processes), "windows": processes, "managed_sessions": len(self.managers)}
496
447
  else:
497
- return {
498
- "success": True,
499
- "total_windows": 0,
500
- "windows": [],
501
- "managed_sessions": len(self.managers),
502
- "message": "No Windows Terminal processes found"
503
- }
448
+ return {"success": True, "total_windows": 0, "windows": [], "managed_sessions": len(self.managers), "message": "No Windows Terminal processes found"}
504
449
  except Exception as e:
505
- return {
506
- "success": False,
507
- "error": str(e),
508
- "managed_sessions": len(self.managers)
509
- }
450
+ return {"success": False, "error": str(e), "managed_sessions": len(self.managers)}
510
451
 
511
452
 
512
453
  if __name__ == "__main__":
513
454
  # Example usage
514
455
  sample_sessions = {
515
- "development": {
516
- "🚀Frontend": ("~/code/myapp/frontend", "npm run dev"),
517
- "⚙️Backend": ("~/code/myapp/backend", "python manage.py runserver"),
518
- "📊Monitor": ("~", "Get-Process | Sort-Object CPU -Descending | Select-Object -First 10")
519
- },
520
- "testing": {
521
- "🧪Tests": ("~/code/myapp", "pytest --watch"),
522
- "🔍Coverage": ("~/code/myapp", "python -m coverage run --source=. -m pytest"),
523
- "📝Logs": ("~/logs", "Get-Content app.log -Wait")
524
- },
525
- "deployment": {
526
- "🐳Docker": ("~/code/myapp", "docker-compose up"),
527
- "☸️K8s": ("~/k8s", "kubectl get pods --watch"),
528
- "📈Metrics": ("~", "Get-Counter \"\\Processor(_Total)\\% Processor Time\" -SampleInterval 2 -MaxSamples 30")
529
- }
456
+ "development": {"🚀Frontend": ("~/code/myapp/frontend", "npm run dev"), "⚙️Backend": ("~/code/myapp/backend", "python manage.py runserver"), "📊Monitor": ("~", "Get-Process | Sort-Object CPU -Descending | Select-Object -First 10")},
457
+ "testing": {"🧪Tests": ("~/code/myapp", "pytest --watch"), "🔍Coverage": ("~/code/myapp", "python -m coverage run --source=. -m pytest"), "📝Logs": ("~/logs", "Get-Content app.log -Wait")},
458
+ "deployment": {"🐳Docker": ("~/code/myapp", "docker-compose up"), "☸️K8s": ("~/k8s", "kubectl get pods --watch"), "📈Metrics": ("~", 'Get-Counter "\\Processor(_Total)\\% Processor Time" -SampleInterval 2 -MaxSamples 30')},
530
459
  }
531
-
460
+
532
461
  try:
533
462
  # Create the local manager
534
463
  manager = WTLocalManager(sample_sessions, session_name_prefix="DevEnv")
535
464
  print(f"✅ Local manager created with {len(manager.managers)} sessions")
536
-
465
+
537
466
  # Show session names
538
467
  print(f"📋 Sessions: {manager.get_all_session_names()}")
539
-
468
+
540
469
  # Print attachment commands (without actually starting)
541
470
  print("\n📎 Attachment commands:")
542
471
  print(manager.attach_to_session())
543
-
472
+
544
473
  # Show current status
545
474
  print("\n🔍 Current status:")
546
475
  manager.print_status_report()
547
-
476
+
548
477
  # Show Windows Terminal overview
549
478
  print("\n🖥️ Windows Terminal Overview:")
550
479
  overview = manager.get_wt_overview()
@@ -553,25 +482,26 @@ if __name__ == "__main__":
553
482
  print(f" Managed sessions: {overview['managed_sessions']}")
554
483
  else:
555
484
  print(f" Error: {overview.get('error', 'Unknown')}")
556
-
485
+
557
486
  # Demonstrate save/load
558
487
  print("\n💾 Demonstrating save/load...")
559
488
  session_id = manager.save()
560
489
  print(f"✅ Saved session: {session_id}")
561
-
490
+
562
491
  # List saved sessions
563
492
  saved_sessions = WTLocalManager.list_saved_sessions()
564
493
  print(f"📋 Saved sessions: {saved_sessions}")
565
-
494
+
566
495
  # Load and verify
567
496
  loaded_manager = WTLocalManager.load(session_id)
568
497
  print(f"✅ Loaded session with {len(loaded_manager.managers)} sessions")
569
-
498
+
570
499
  # Show how to start monitoring (commented out to prevent infinite loop in demo)
571
500
  print("\n⏰ To start monitoring, run:")
572
501
  print("manager.run_monitoring_routine(wait_ms=30000) # 30 seconds")
573
-
502
+
574
503
  except Exception as e:
575
504
  print(f"❌ Error: {e}")
576
505
  import traceback
577
- traceback.print_exc()
506
+
507
+ traceback.print_exc()