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