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