machineconfig 1.96__py3-none-any.whl → 2.0__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 (164) hide show
  1. machineconfig/cluster/cloud_manager.py +22 -26
  2. machineconfig/cluster/data_transfer.py +2 -2
  3. machineconfig/cluster/distribute.py +0 -2
  4. machineconfig/cluster/file_manager.py +4 -4
  5. machineconfig/cluster/job_params.py +1 -1
  6. machineconfig/cluster/loader_runner.py +8 -8
  7. machineconfig/cluster/remote_machine.py +4 -4
  8. machineconfig/cluster/script_execution.py +2 -2
  9. machineconfig/cluster/sessions_managers/archive/create_zellij_template.py +1 -1
  10. machineconfig/cluster/sessions_managers/enhanced_command_runner.py +23 -23
  11. machineconfig/cluster/sessions_managers/wt_local.py +78 -76
  12. machineconfig/cluster/sessions_managers/wt_local_manager.py +91 -91
  13. machineconfig/cluster/sessions_managers/wt_remote.py +39 -39
  14. machineconfig/cluster/sessions_managers/wt_remote_manager.py +94 -91
  15. machineconfig/cluster/sessions_managers/wt_utils/layout_generator.py +56 -54
  16. machineconfig/cluster/sessions_managers/wt_utils/process_monitor.py +49 -49
  17. machineconfig/cluster/sessions_managers/wt_utils/remote_executor.py +18 -18
  18. machineconfig/cluster/sessions_managers/wt_utils/session_manager.py +42 -42
  19. machineconfig/cluster/sessions_managers/wt_utils/status_reporter.py +36 -36
  20. machineconfig/cluster/sessions_managers/zellij_local.py +43 -46
  21. machineconfig/cluster/sessions_managers/zellij_local_manager.py +139 -120
  22. machineconfig/cluster/sessions_managers/zellij_remote.py +35 -35
  23. machineconfig/cluster/sessions_managers/zellij_remote_manager.py +33 -33
  24. machineconfig/cluster/sessions_managers/zellij_utils/example_usage.py +15 -15
  25. machineconfig/cluster/sessions_managers/zellij_utils/layout_generator.py +25 -26
  26. machineconfig/cluster/sessions_managers/zellij_utils/process_monitor.py +49 -49
  27. machineconfig/cluster/sessions_managers/zellij_utils/remote_executor.py +5 -5
  28. machineconfig/cluster/sessions_managers/zellij_utils/session_manager.py +15 -15
  29. machineconfig/cluster/sessions_managers/zellij_utils/status_reporter.py +11 -11
  30. machineconfig/cluster/templates/utils.py +3 -3
  31. machineconfig/jobs/__pycache__/__init__.cpython-311.pyc +0 -0
  32. machineconfig/jobs/python/__pycache__/__init__.cpython-311.pyc +0 -0
  33. machineconfig/jobs/python/__pycache__/python_ve_symlink.cpython-311.pyc +0 -0
  34. machineconfig/jobs/python/check_installations.py +8 -9
  35. machineconfig/jobs/python/python_cargo_build_share.py +2 -2
  36. machineconfig/jobs/python/vscode/link_ve.py +7 -7
  37. machineconfig/jobs/python/vscode/select_interpreter.py +7 -7
  38. machineconfig/jobs/python/vscode/sync_code.py +5 -5
  39. machineconfig/jobs/python_custom_installers/archive/ngrok.py +2 -2
  40. machineconfig/jobs/python_custom_installers/dev/aider.py +3 -3
  41. machineconfig/jobs/python_custom_installers/dev/alacritty.py +3 -3
  42. machineconfig/jobs/python_custom_installers/dev/brave.py +3 -3
  43. machineconfig/jobs/python_custom_installers/dev/bypass_paywall.py +5 -5
  44. machineconfig/jobs/python_custom_installers/dev/code.py +3 -3
  45. machineconfig/jobs/python_custom_installers/dev/cursor.py +9 -9
  46. machineconfig/jobs/python_custom_installers/dev/docker_desktop.py +4 -4
  47. machineconfig/jobs/python_custom_installers/dev/espanso.py +4 -4
  48. machineconfig/jobs/python_custom_installers/dev/goes.py +4 -4
  49. machineconfig/jobs/python_custom_installers/dev/lvim.py +4 -4
  50. machineconfig/jobs/python_custom_installers/dev/nerdfont.py +3 -3
  51. machineconfig/jobs/python_custom_installers/dev/redis.py +3 -3
  52. machineconfig/jobs/python_custom_installers/dev/wezterm.py +3 -3
  53. machineconfig/jobs/python_custom_installers/dev/winget.py +27 -27
  54. machineconfig/jobs/python_custom_installers/docker.py +3 -3
  55. machineconfig/jobs/python_custom_installers/gh.py +7 -7
  56. machineconfig/jobs/python_custom_installers/hx.py +1 -1
  57. machineconfig/jobs/python_custom_installers/warp-cli.py +3 -3
  58. machineconfig/jobs/python_generic_installers/config.json +412 -389
  59. machineconfig/jobs/python_windows_installers/dev/config.json +1 -1
  60. machineconfig/logger.py +50 -0
  61. machineconfig/profile/__pycache__/__init__.cpython-311.pyc +0 -0
  62. machineconfig/profile/__pycache__/create.cpython-311.pyc +0 -0
  63. machineconfig/profile/__pycache__/shell.cpython-311.pyc +0 -0
  64. machineconfig/profile/create.py +23 -16
  65. machineconfig/profile/create_hardlinks.py +8 -8
  66. machineconfig/profile/shell.py +41 -37
  67. machineconfig/scripts/__pycache__/__init__.cpython-311.pyc +0 -0
  68. machineconfig/scripts/__pycache__/__init__.cpython-313.pyc +0 -0
  69. machineconfig/scripts/linux/devops +2 -2
  70. machineconfig/scripts/linux/fire +1 -0
  71. machineconfig/scripts/linux/fire_agents +0 -1
  72. machineconfig/scripts/linux/mcinit +27 -0
  73. machineconfig/scripts/python/__pycache__/__init__.cpython-311.pyc +0 -0
  74. machineconfig/scripts/python/__pycache__/__init__.cpython-313.pyc +0 -0
  75. machineconfig/scripts/python/__pycache__/croshell.cpython-311.pyc +0 -0
  76. machineconfig/scripts/python/__pycache__/devops.cpython-311.pyc +0 -0
  77. machineconfig/scripts/python/__pycache__/devops.cpython-313.pyc +0 -0
  78. machineconfig/scripts/python/__pycache__/devops_update_repos.cpython-311.pyc +0 -0
  79. machineconfig/scripts/python/__pycache__/devops_update_repos.cpython-313.pyc +0 -0
  80. machineconfig/scripts/python/__pycache__/fire_agents.cpython-311.pyc +0 -0
  81. machineconfig/scripts/python/__pycache__/fire_jobs.cpython-311.pyc +0 -0
  82. machineconfig/scripts/python/__pycache__/repos.cpython-311.pyc +0 -0
  83. machineconfig/scripts/python/ai/__pycache__/init.cpython-311.pyc +0 -0
  84. machineconfig/scripts/python/ai/__pycache__/mcinit.cpython-311.pyc +0 -0
  85. machineconfig/scripts/python/ai/chatmodes/Thinking-Beast-Mode.chatmode.md +337 -0
  86. machineconfig/scripts/python/ai/chatmodes/Ultimate-Transparent-Thinking-Beast-Mode.chatmode.md +644 -0
  87. machineconfig/scripts/python/ai/chatmodes/deepResearch.chatmode.md +81 -0
  88. machineconfig/scripts/python/ai/configs/.gemini/settings.json +81 -0
  89. machineconfig/scripts/python/ai/instructions/python/dev.instructions.md +45 -0
  90. machineconfig/scripts/python/ai/mcinit.py +103 -0
  91. machineconfig/scripts/python/ai/prompts/allLintersAndTypeCheckers.prompt.md +5 -0
  92. machineconfig/scripts/python/ai/prompts/research-report-skeleton.prompt.md +38 -0
  93. machineconfig/scripts/python/ai/scripts/lint_and_type_check.sh +47 -0
  94. machineconfig/scripts/python/archive/tmate_conn.py +5 -5
  95. machineconfig/scripts/python/archive/tmate_start.py +3 -3
  96. machineconfig/scripts/python/choose_wezterm_theme.py +2 -2
  97. machineconfig/scripts/python/cloud_copy.py +19 -18
  98. machineconfig/scripts/python/cloud_mount.py +9 -7
  99. machineconfig/scripts/python/cloud_repo_sync.py +11 -11
  100. machineconfig/scripts/python/cloud_sync.py +1 -1
  101. machineconfig/scripts/python/croshell.py +14 -14
  102. machineconfig/scripts/python/devops.py +6 -6
  103. machineconfig/scripts/python/devops_add_identity.py +8 -6
  104. machineconfig/scripts/python/devops_add_ssh_key.py +18 -18
  105. machineconfig/scripts/python/devops_backup_retrieve.py +13 -13
  106. machineconfig/scripts/python/devops_devapps_install.py +3 -3
  107. machineconfig/scripts/python/devops_update_repos.py +1 -1
  108. machineconfig/scripts/python/dotfile.py +2 -2
  109. machineconfig/scripts/python/fire_agents.py +183 -41
  110. machineconfig/scripts/python/fire_jobs.py +17 -11
  111. machineconfig/scripts/python/ftpx.py +2 -2
  112. machineconfig/scripts/python/gh_models.py +94 -94
  113. machineconfig/scripts/python/helpers/__pycache__/__init__.cpython-311.pyc +0 -0
  114. machineconfig/scripts/python/helpers/__pycache__/cloud_helpers.cpython-311.pyc +0 -0
  115. machineconfig/scripts/python/helpers/__pycache__/helpers2.cpython-311.pyc +0 -0
  116. machineconfig/scripts/python/helpers/__pycache__/helpers4.cpython-311.pyc +0 -0
  117. machineconfig/scripts/python/helpers/cloud_helpers.py +3 -3
  118. machineconfig/scripts/python/helpers/helpers2.py +1 -1
  119. machineconfig/scripts/python/helpers/helpers4.py +8 -6
  120. machineconfig/scripts/python/helpers/helpers5.py +7 -7
  121. machineconfig/scripts/python/helpers/repo_sync_helpers.py +1 -1
  122. machineconfig/scripts/python/mount_nfs.py +3 -2
  123. machineconfig/scripts/python/mount_nw_drive.py +4 -4
  124. machineconfig/scripts/python/mount_ssh.py +3 -2
  125. machineconfig/scripts/python/repos.py +8 -8
  126. machineconfig/scripts/python/scheduler.py +1 -1
  127. machineconfig/scripts/python/start_slidev.py +8 -7
  128. machineconfig/scripts/python/start_terminals.py +1 -1
  129. machineconfig/scripts/python/viewer.py +40 -40
  130. machineconfig/scripts/python/wifi_conn.py +65 -66
  131. machineconfig/scripts/python/wsl_windows_transfer.py +1 -1
  132. machineconfig/scripts/windows/mcinit.ps1 +4 -0
  133. machineconfig/settings/linters/.ruff.toml +2 -2
  134. machineconfig/settings/shells/ipy/profiles/default/startup/playext.py +71 -71
  135. machineconfig/settings/shells/wt/settings.json +8 -8
  136. machineconfig/setup_linux/web_shortcuts/tmp.sh +2 -0
  137. machineconfig/setup_windows/wt_and_pwsh/set_pwsh_theme.py +10 -7
  138. machineconfig/setup_windows/wt_and_pwsh/set_wt_settings.py +9 -7
  139. machineconfig/utils/ai/browser_user_wrapper.py +5 -5
  140. machineconfig/utils/ai/generate_file_checklist.py +11 -12
  141. machineconfig/utils/ai/url2md.py +1 -1
  142. machineconfig/utils/cloud/onedrive/setup_oauth.py +4 -4
  143. machineconfig/utils/cloud/onedrive/transaction.py +129 -129
  144. machineconfig/utils/code.py +13 -6
  145. machineconfig/utils/installer.py +51 -53
  146. machineconfig/utils/installer_utils/installer_abc.py +21 -10
  147. machineconfig/utils/installer_utils/installer_class.py +42 -16
  148. machineconfig/utils/io_save.py +3 -15
  149. machineconfig/utils/options.py +10 -3
  150. machineconfig/utils/path.py +5 -0
  151. machineconfig/utils/path_reduced.py +201 -149
  152. machineconfig/utils/procs.py +23 -23
  153. machineconfig/utils/scheduling.py +11 -12
  154. machineconfig/utils/ssh.py +270 -0
  155. machineconfig/utils/terminal.py +180 -0
  156. machineconfig/utils/utils.py +1 -2
  157. machineconfig/utils/utils2.py +43 -0
  158. machineconfig/utils/utils5.py +163 -34
  159. machineconfig/utils/ve.py +2 -2
  160. {machineconfig-1.96.dist-info → machineconfig-2.0.dist-info}/METADATA +13 -8
  161. {machineconfig-1.96.dist-info → machineconfig-2.0.dist-info}/RECORD +163 -144
  162. machineconfig/cluster/self_ssh.py +0 -57
  163. {machineconfig-1.96.dist-info → machineconfig-2.0.dist-info}/WHEEL +0 -0
  164. {machineconfig-1.96.dist-info → machineconfig-2.0.dist-info}/top_level.txt +0 -0
@@ -22,12 +22,12 @@ class WTLayoutGenerator:
22
22
  self.session_name: Optional[str] = None
23
23
  self.tab_config: Dict[str, tuple[str, str]] = {} # Store entire tab config (cwd, command) for status checking
24
24
  self.script_path: Optional[str] = None # Store the full path to the script file
25
-
25
+
26
26
  @staticmethod
27
27
  def _generate_random_suffix(length: int = 8) -> str:
28
28
  """Generate a random string suffix for unique script file names."""
29
29
  return ''.join(random.choices(string.ascii_lowercase + string.digits, k=length))
30
-
30
+
31
31
  @staticmethod
32
32
  def _parse_command(command: str) -> tuple[str, List[str]]:
33
33
  try:
@@ -38,7 +38,7 @@ class WTLayoutGenerator:
38
38
  logger.error(f"Error parsing command '{command}': {e}")
39
39
  parts = command.split()
40
40
  return parts[0] if parts else "", parts[1:] if len(parts) > 1 else []
41
-
41
+
42
42
  @staticmethod
43
43
  def _escape_for_wt(text: str) -> str:
44
44
  """Escape text for use in Windows Terminal commands."""
@@ -47,7 +47,7 @@ class WTLayoutGenerator:
47
47
  if ' ' in text or ';' in text or '&' in text or '|' in text:
48
48
  return f'"{text}"'
49
49
  return text
50
-
50
+
51
51
  @staticmethod
52
52
  def _create_tab_command(tab_name: str, cwd: str, command: str, is_first_tab: bool = False) -> str:
53
53
  """Create a Windows Terminal tab command string."""
@@ -56,48 +56,48 @@ class WTLayoutGenerator:
56
56
  cwd = cwd.replace('~/', f"{Path.home()}/")
57
57
  elif cwd == '~':
58
58
  cwd = str(Path.home())
59
-
59
+
60
60
  # Build the wt command parts
61
61
  tab_parts = []
62
-
62
+
63
63
  if not is_first_tab:
64
64
  tab_parts.append("new-tab")
65
-
65
+
66
66
  # Add starting directory
67
67
  tab_parts.extend(["-d", WTLayoutGenerator._escape_for_wt(cwd)])
68
-
68
+
69
69
  # Add tab title
70
70
  tab_parts.extend(["--title", WTLayoutGenerator._escape_for_wt(tab_name)])
71
-
71
+
72
72
  # Add the command to execute
73
73
  tab_parts.append(WTLayoutGenerator._escape_for_wt(command))
74
-
74
+
75
75
  return " ".join(tab_parts)
76
-
76
+
77
77
  @staticmethod
78
78
  def _validate_tab_config(tab_config: Dict[str, tuple[str, str]]) -> None:
79
79
  """Validate tab configuration format and content."""
80
- if not tab_config:
80
+ if not tab_config:
81
81
  raise ValueError("Tab configuration cannot be empty")
82
82
  for tab_name, (cwd, command) in tab_config.items():
83
- if not tab_name.strip():
83
+ if not tab_name.strip():
84
84
  raise ValueError(f"Invalid tab name: {tab_name}")
85
- if not command.strip():
85
+ if not command.strip():
86
86
  raise ValueError(f"Invalid command for tab '{tab_name}': {command}")
87
- if not cwd.strip():
87
+ if not cwd.strip():
88
88
  raise ValueError(f"Invalid cwd for tab '{tab_name}': {cwd}")
89
-
89
+
90
90
  def create_wt_layout(self, tab_config: Dict[str, tuple[str, str]], output_dir: Optional[str] = None, session_name: Optional[str] = None) -> str:
91
91
  WTLayoutGenerator._validate_tab_config(tab_config)
92
92
  logger.info(f"Creating Windows Terminal layout with {len(tab_config)} tabs")
93
-
93
+
94
94
  # Store session name and entire tab config for status checking
95
95
  self.session_name = session_name or "default"
96
96
  self.tab_config = tab_config.copy()
97
-
97
+
98
98
  # Generate Windows Terminal command
99
99
  wt_command = self._generate_wt_command_string(tab_config, self.session_name)
100
-
100
+
101
101
  try:
102
102
  random_suffix = WTLayoutGenerator._generate_random_suffix()
103
103
  if output_dir:
@@ -108,42 +108,44 @@ class WTLayoutGenerator:
108
108
  # Use the predefined TMP_LAYOUT_DIR for temporary files
109
109
  TMP_LAYOUT_DIR.mkdir(parents=True, exist_ok=True)
110
110
  script_file = TMP_LAYOUT_DIR / f"wt_layout_{self.session_name}_{random_suffix}.bat"
111
-
111
+
112
112
  # Create batch script
113
- with open(script_file, 'w', encoding='utf-8') as f:
114
- f.write("@echo off\n")
115
- f.write(f"REM Windows Terminal layout for {self.session_name}\n")
116
- f.write(f"{wt_command}\n")
117
-
113
+ text = f"""@echo off
114
+ REM Windows Terminal layout for {self.session_name}
115
+ {wt_command}
116
+ """
117
+ script_file.write_text(text, encoding="utf-8")
118
+
118
119
  # Also create PowerShell script for better command handling
119
120
  ps1_file = script_file.with_suffix('.ps1')
120
- with open(ps1_file, 'w', encoding='utf-8') as f:
121
- f.write(f"# Windows Terminal layout for {self.session_name}\n")
122
- f.write(f"# Generated with random suffix: {random_suffix}\n")
123
- f.write(f"{wt_command}\n")
124
-
121
+ text = f"""# Windows Terminal layout for {self.session_name}
122
+ # Generated with random suffix: {random_suffix}
123
+ {wt_command}
124
+ """
125
+ ps1_file.write_text(text, encoding="utf-8")
126
+
125
127
  self.script_path = str(script_file.absolute())
126
128
  logger.info(f"Windows Terminal script file created: {self.script_path}")
127
129
  return self.script_path
128
130
  except OSError as e:
129
131
  logger.error(f"Failed to create script file: {e}")
130
132
  raise
131
-
133
+
132
134
  def _generate_wt_command_string(self, tab_config: Dict[str, tuple[str, str]], window_name: str) -> str:
133
135
  """Generate complete Windows Terminal command string."""
134
136
  # Start building the wt command
135
137
  wt_parts = ["wt"]
136
-
138
+
137
139
  # Add window name
138
140
  wt_parts.extend(["-w", WTLayoutGenerator._escape_for_wt(window_name)])
139
-
141
+
140
142
  # Add tabs
141
143
  tab_commands = []
142
144
  for i, (tab_name, (cwd, command)) in enumerate(tab_config.items()):
143
145
  is_first = i == 0
144
146
  tab_cmd = self._create_tab_command(tab_name, cwd, command, is_first)
145
147
  tab_commands.append(tab_cmd)
146
-
148
+
147
149
  # Join all parts with semicolons (Windows Terminal command separator)
148
150
  if tab_commands:
149
151
  if len(tab_commands) == 1:
@@ -154,23 +156,23 @@ class WTLayoutGenerator:
154
156
  wt_parts.append(tab_commands[0]) # First tab
155
157
  for tab_cmd in tab_commands[1:]:
156
158
  wt_parts.extend([";", tab_cmd])
157
-
159
+
158
160
  return " ".join(wt_parts)
159
-
161
+
160
162
  def get_wt_layout_preview(self, tab_config: Dict[str, tuple[str, str]]) -> str:
161
163
  """Generate preview of the Windows Terminal command that would be created."""
162
164
  WTLayoutGenerator._validate_tab_config(tab_config)
163
165
  return self._generate_wt_command_string(tab_config, "preview")
164
-
166
+
165
167
  def check_all_commands_status(self) -> Dict[str, Dict[str, Any]]:
166
168
  if not self.tab_config:
167
169
  logger.warning("No tab config tracked. Make sure to create a layout first.")
168
170
  return {}
169
-
171
+
170
172
  status_report = {}
171
173
  for tab_name in self.tab_config:
172
174
  status_report[tab_name] = WTLayoutGenerator.check_command_status(tab_name, self.tab_config)
173
-
175
+
174
176
  return status_report
175
177
 
176
178
  @staticmethod
@@ -183,9 +185,9 @@ class WTLayoutGenerator:
183
185
  "Select-Object Id, ProcessName, StartTime, MainWindowTitle | "
184
186
  "ConvertTo-Json -Depth 2"
185
187
  ]
186
-
188
+
187
189
  result = subprocess.run(wt_check_cmd, capture_output=True, text=True, timeout=10)
188
-
190
+
189
191
  if result.returncode == 0:
190
192
  output = result.stdout.strip()
191
193
  if output and output != "":
@@ -194,14 +196,14 @@ class WTLayoutGenerator:
194
196
  processes = json.loads(output)
195
197
  if not isinstance(processes, list):
196
198
  processes = [processes]
197
-
199
+
198
200
  # Look for windows that might belong to our session
199
201
  session_windows = []
200
202
  for proc in processes:
201
203
  window_title = proc.get("MainWindowTitle", "")
202
204
  if session_name in window_title or not window_title:
203
205
  session_windows.append(proc)
204
-
206
+
205
207
  return {
206
208
  "wt_running": True,
207
209
  "session_exists": len(session_windows) > 0,
@@ -229,7 +231,7 @@ class WTLayoutGenerator:
229
231
  "error": result.stderr,
230
232
  "session_name": session_name
231
233
  }
232
-
234
+
233
235
  except subprocess.TimeoutExpired:
234
236
  return {
235
237
  "wt_running": False,
@@ -260,16 +262,16 @@ class WTLayoutGenerator:
260
262
  "pid": None,
261
263
  "command": None
262
264
  }
263
-
265
+
264
266
  _, command = tab_config[tab_name]
265
-
267
+
266
268
  try:
267
269
  # Create PowerShell script to check for processes
268
270
  cmd_parts = [part for part in command.split() if len(part) > 2]
269
271
  primary_cmd = cmd_parts[0] if cmd_parts else ''
270
-
272
+
271
273
  ps_script = f"""
272
- $targetCommand = '{command.replace("'", "''")}'
274
+ $targetCommand = '{command.replace("'", "''")}'
273
275
  $cmdParts = @({', '.join([f"'{part}'" for part in cmd_parts])})
274
276
  $primaryCmd = '{primary_cmd}'
275
277
  $currentPid = $PID
@@ -278,23 +280,23 @@ $matchingProcesses = @()
278
280
  Get-Process | ForEach-Object {{
279
281
  try {{
280
282
  if ($_.Id -eq $currentPid) {{ return }}
281
-
283
+
282
284
  $cmdline = ""
283
285
  try {{
284
286
  $cmdline = (Get-WmiObject Win32_Process -Filter "ProcessId = $($_.Id)").CommandLine
285
287
  }} catch {{
286
288
  $cmdline = $_.ProcessName
287
289
  }}
288
-
290
+
289
291
  if ($cmdline -and $cmdline -ne "") {{
290
292
  if ($cmdline -like "*PowerShell*" -and $cmdline -like "*Get-Process*") {{ return }}
291
-
293
+
292
294
  $matchesPrimary = $cmdline -like "*$primaryCmd*" -and $primaryCmd -ne "powershell"
293
295
  $matchCount = 0
294
296
  foreach ($part in $cmdParts[1..($cmdParts.Length-1)]) {{
295
297
  if ($cmdline -like "*$part*") {{ $matchCount++ }}
296
298
  }}
297
-
299
+
298
300
  if ($matchesPrimary -and $matchCount -ge 1) {{
299
301
  $procInfo = @{{
300
302
  "pid" = $_.Id
@@ -311,18 +313,18 @@ Get-Process | ForEach-Object {{
311
313
  }}
312
314
  }}
313
315
  """
314
-
316
+
315
317
  result = subprocess.run(
316
318
  ["powershell", "-Command", ps_script],
317
319
  capture_output=True,
318
320
  text=True,
319
321
  timeout=15
320
322
  )
321
-
323
+
322
324
  if result.returncode == 0:
323
325
  output_lines = [line.strip() for line in result.stdout.strip().split('\n') if line.strip()]
324
326
  matching_processes = []
325
-
327
+
326
328
  for line in output_lines:
327
329
  if line.startswith('{') and line.endswith('}'):
328
330
  try:
@@ -330,7 +332,7 @@ Get-Process | ForEach-Object {{
330
332
  matching_processes.append(proc_info)
331
333
  except json.JSONDecodeError:
332
334
  continue
333
-
335
+
334
336
  if matching_processes:
335
337
  return {
336
338
  "status": "running",
@@ -349,13 +351,13 @@ Get-Process | ForEach-Object {{
349
351
  }
350
352
  else:
351
353
  return {
352
- "status": "error",
354
+ "status": "error",
353
355
  "error": f"Command failed: {result.stderr}",
354
356
  "running": False,
355
357
  "command": command,
356
358
  "tab_name": tab_name
357
359
  }
358
-
360
+
359
361
  except Exception as e:
360
362
  logger.error(f"Error checking command status for tab '{tab_name}': {e}")
361
363
  return {
@@ -370,10 +372,10 @@ Get-Process | ForEach-Object {{
370
372
  """Get status report for this layout including Windows Terminal and commands."""
371
373
  wt_status = WTLayoutGenerator.check_wt_session_status(self.session_name or "default")
372
374
  commands_status = self.check_all_commands_status()
373
-
375
+
374
376
  running_count = sum(1 for status in commands_status.values() if status.get("running", False))
375
377
  total_count = len(commands_status)
376
-
378
+
377
379
  return {
378
380
  "wt_session": wt_status,
379
381
  "commands": commands_status,
@@ -391,11 +393,11 @@ Get-Process | ForEach-Object {{
391
393
  wt_session = status["wt_session"]
392
394
  commands = status["commands"]
393
395
  summary = status["summary"]
394
-
396
+
395
397
  print("=" * 80)
396
398
  print("šŸ–„ļø WINDOWS TERMINAL LAYOUT STATUS REPORT")
397
399
  print("=" * 80)
398
-
400
+
399
401
  # Windows Terminal session status
400
402
  print(f"🪟 Session: {self.session_name}")
401
403
  if wt_session.get("wt_running", False):
@@ -410,9 +412,9 @@ Get-Process | ForEach-Object {{
410
412
  else:
411
413
  error_msg = wt_session.get("error", "Unknown error")
412
414
  print(f"āŒ Windows Terminal session issue: {error_msg}")
413
-
415
+
414
416
  print()
415
-
417
+
416
418
  # Commands in this layout
417
419
  print(f"šŸ“‹ COMMANDS ({summary['running_commands']}/{summary['total_commands']} running):")
418
420
  for tab_name, cmd_status in commands.items():
@@ -420,16 +422,16 @@ Get-Process | ForEach-Object {{
420
422
  cmd_text = cmd_status.get("command", "Unknown")[:50]
421
423
  if len(cmd_status.get("command", "")) > 50:
422
424
  cmd_text += "..."
423
-
425
+
424
426
  print(f" {status_icon} {tab_name}: {cmd_text}")
425
-
427
+
426
428
  if cmd_status.get("processes"):
427
429
  for proc in cmd_status["processes"][:2]: # Show first 2 processes
428
430
  pid = proc.get("pid", "Unknown")
429
431
  name = proc.get("name", "Unknown")
430
432
  print(f" └─ PID {pid}: {name}")
431
433
  print()
432
-
434
+
433
435
  print("=" * 80)
434
436
 
435
437
 
@@ -441,11 +443,11 @@ def run_wt_layout(tab_config: Dict[str, tuple[str, str]], session_name: Optional
441
443
  """Create and run a Windows Terminal layout."""
442
444
  generator = WTLayoutGenerator()
443
445
  script_path = generator.create_wt_layout(tab_config, session_name=session_name)
444
-
446
+
445
447
  # Execute the script
446
448
  cmd = f"powershell -ExecutionPolicy Bypass -File \"{script_path}\""
447
449
  result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
448
-
450
+
449
451
  if result.returncode == 0:
450
452
  print(f"Windows Terminal layout is running @ {session_name}")
451
453
  return script_path
@@ -456,7 +458,7 @@ def run_wt_layout(tab_config: Dict[str, tuple[str, str]], session_name: Optional
456
458
  def run_command_in_wt_tab(command: str, tab_name: str, cwd: Optional[str]) -> str:
457
459
  """Create a command to run in a new Windows Terminal tab."""
458
460
  cwd_part = f"-d \"{cwd}\"" if cwd else ""
459
-
461
+
460
462
  return f"""
461
463
  echo "Creating new Windows Terminal tab: {tab_name}"
462
464
  wt new-tab --title "{tab_name}" {cwd_part} "{command}"
@@ -469,26 +471,26 @@ if __name__ == "__main__":
469
471
  "Frontend": ("~/code", "btm"),
470
472
  "Monitor": ("~", "lf"),
471
473
  }
472
-
474
+
473
475
  try:
474
476
  # Create layout using the generator
475
477
  generator = WTLayoutGenerator()
476
478
  script_path = generator.create_wt_layout(sample_tabs, session_name="test_session")
477
479
  print(f"āœ… Windows Terminal layout created: {script_path}")
478
-
480
+
479
481
  # Show preview
480
482
  preview = generator.get_wt_layout_preview(sample_tabs)
481
483
  print(f"\nšŸ“‹ Command Preview:\n{preview}")
482
-
484
+
483
485
  # Check status (won't find anything since we haven't run it)
484
486
  print("\nšŸ” Current status:")
485
487
  generator.print_status_report()
486
-
488
+
487
489
  # Show how to run the layout
488
490
  print("\nā–¶ļø To run this layout, execute:")
489
491
  print(f" powershell -ExecutionPolicy Bypass -File \"{script_path}\"")
490
-
492
+
491
493
  except Exception as e:
492
494
  print(f"āŒ Error: {e}")
493
495
  import traceback
494
- traceback.print_exc()
496
+ traceback.print_exc()