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
|
@@ -30,35 +30,37 @@ class ZellijLayoutGenerator:
|
|
|
30
30
|
children
|
|
31
31
|
}
|
|
32
32
|
"""
|
|
33
|
-
|
|
33
|
+
|
|
34
34
|
@staticmethod
|
|
35
35
|
def _generate_random_suffix(length: int = 8) -> str:
|
|
36
36
|
"""Generate a random string suffix for unique layout file names."""
|
|
37
|
-
return
|
|
38
|
-
|
|
37
|
+
return "".join(random.choices(string.ascii_lowercase + string.digits, k=length))
|
|
38
|
+
|
|
39
39
|
@staticmethod
|
|
40
40
|
def _parse_command(command: str) -> tuple[str, List[str]]:
|
|
41
41
|
try:
|
|
42
42
|
parts = shlex.split(command)
|
|
43
|
-
if not parts:
|
|
43
|
+
if not parts:
|
|
44
|
+
raise ValueError("Empty command provided")
|
|
44
45
|
return parts[0], parts[1:] if len(parts) > 1 else []
|
|
45
46
|
except ValueError as e:
|
|
46
47
|
logger.error(f"Error parsing command '{command}': {e}")
|
|
47
48
|
parts = command.split()
|
|
48
49
|
return parts[0] if parts else "", parts[1:] if len(parts) > 1 else []
|
|
49
|
-
|
|
50
|
+
|
|
50
51
|
@staticmethod
|
|
51
52
|
def _format_args_for_kdl(args: List[str]) -> str:
|
|
52
|
-
if not args:
|
|
53
|
+
if not args:
|
|
54
|
+
return ""
|
|
53
55
|
formatted_args = []
|
|
54
56
|
for arg in args:
|
|
55
|
-
if
|
|
57
|
+
if " " in arg or '"' in arg or "'" in arg:
|
|
56
58
|
escaped_arg = arg.replace('"', '\\"')
|
|
57
59
|
formatted_args.append(f'"{escaped_arg}"')
|
|
58
60
|
else:
|
|
59
61
|
formatted_args.append(f'"{arg}"')
|
|
60
62
|
return " ".join(formatted_args)
|
|
61
|
-
|
|
63
|
+
|
|
62
64
|
@staticmethod
|
|
63
65
|
def _create_tab_section(tab_name: str, cwd: str, command: str) -> str:
|
|
64
66
|
cmd, args = ZellijLayoutGenerator._parse_command(command)
|
|
@@ -67,33 +69,38 @@ class ZellijLayoutGenerator:
|
|
|
67
69
|
escaped_tab_name = tab_name.replace('"', '\\"')
|
|
68
70
|
tab_section = f' tab name="{escaped_tab_name}" cwd="{tab_cwd}" {{\n'
|
|
69
71
|
tab_section += f' pane command="{cmd}" {{\n'
|
|
70
|
-
if args_str:
|
|
71
|
-
|
|
72
|
+
if args_str:
|
|
73
|
+
tab_section += f" args {args_str}\n"
|
|
74
|
+
tab_section += " }\n }\n"
|
|
72
75
|
return tab_section
|
|
73
|
-
|
|
76
|
+
|
|
74
77
|
@staticmethod
|
|
75
78
|
def _validate_tab_config(tab_config: Dict[str, tuple[str, str]]) -> None:
|
|
76
|
-
if not tab_config:
|
|
79
|
+
if not tab_config:
|
|
80
|
+
raise ValueError("Tab configuration cannot be empty")
|
|
77
81
|
for tab_name, (cwd, command) in tab_config.items():
|
|
78
|
-
if not tab_name.strip():
|
|
79
|
-
|
|
80
|
-
if not
|
|
81
|
-
|
|
82
|
+
if not tab_name.strip():
|
|
83
|
+
raise ValueError(f"Invalid tab name: {tab_name}")
|
|
84
|
+
if not command.strip():
|
|
85
|
+
raise ValueError(f"Invalid command for tab '{tab_name}': {command}")
|
|
86
|
+
if not cwd.strip():
|
|
87
|
+
raise ValueError(f"Invalid cwd for tab '{tab_name}': {cwd}")
|
|
88
|
+
|
|
82
89
|
def create_zellij_layout(self, tab_config: Dict[str, tuple[str, str]], output_dir: Optional[str] = None, session_name: Optional[str] = None) -> str:
|
|
83
90
|
ZellijLayoutGenerator._validate_tab_config(tab_config)
|
|
84
|
-
|
|
91
|
+
|
|
85
92
|
# Enhanced Rich logging
|
|
86
93
|
tab_count = len(tab_config)
|
|
87
94
|
console.print(f"[bold cyan]π Creating Zellij layout[/bold cyan] [bright_green]with {tab_count} tabs[/bright_green]")
|
|
88
|
-
|
|
95
|
+
|
|
89
96
|
# Display tab summary with emojis and colors
|
|
90
97
|
for tab_name, (cwd, command) in tab_config.items():
|
|
91
98
|
console.print(f" [yellow]β[/yellow] [bold]{tab_name}[/bold] [dim]in[/dim] [blue]{cwd}[/blue]")
|
|
92
|
-
|
|
99
|
+
|
|
93
100
|
# Store session name and entire tab config for status checking
|
|
94
101
|
self.session_name = session_name or "default"
|
|
95
102
|
self.tab_config = tab_config.copy()
|
|
96
|
-
|
|
103
|
+
|
|
97
104
|
layout_content = self.layout_template
|
|
98
105
|
for tab_name, (cwd, command) in tab_config.items():
|
|
99
106
|
layout_content += "\n" + ZellijLayoutGenerator._create_tab_section(tab_name, cwd, command)
|
|
@@ -104,24 +111,22 @@ class ZellijLayoutGenerator:
|
|
|
104
111
|
output_path = Path(output_dir)
|
|
105
112
|
output_path.mkdir(parents=True, exist_ok=True)
|
|
106
113
|
layout_file = output_path / f"zellij_layout_{random_suffix}.kdl"
|
|
107
|
-
|
|
108
|
-
f.write(layout_content)
|
|
114
|
+
layout_file.write_text(layout_content, encoding="utf-8")
|
|
109
115
|
self.layout_path = str(layout_file.absolute())
|
|
110
116
|
else:
|
|
111
117
|
# Use the predefined TMP_LAYOUT_DIR for temporary files
|
|
112
118
|
TMP_LAYOUT_DIR.mkdir(parents=True, exist_ok=True)
|
|
113
119
|
layout_file = TMP_LAYOUT_DIR / f"zellij_layout_{self.session_name or 'default'}_{random_suffix}.kdl"
|
|
114
|
-
|
|
115
|
-
f.write(layout_content)
|
|
120
|
+
layout_file.write_text(layout_content, encoding="utf-8")
|
|
116
121
|
self.layout_path = str(layout_file.absolute())
|
|
117
|
-
|
|
122
|
+
|
|
118
123
|
# Enhanced Rich logging for file creation
|
|
119
124
|
console.print(f"[bold green]β
Zellij layout file created:[/bold green] [cyan]{self.layout_path}[/cyan]")
|
|
120
125
|
return self.layout_path
|
|
121
126
|
except OSError as e:
|
|
122
127
|
logger.error(f"Failed to create layout file: {e}")
|
|
123
128
|
raise
|
|
124
|
-
|
|
129
|
+
|
|
125
130
|
@staticmethod
|
|
126
131
|
def get_layout_preview(tab_config: Dict[str, tuple[str, str]], layout_template: str | None = None) -> str:
|
|
127
132
|
if layout_template is None:
|
|
@@ -139,157 +144,91 @@ class ZellijLayoutGenerator:
|
|
|
139
144
|
for tab_name, (cwd, command) in tab_config.items():
|
|
140
145
|
layout_content += "\n" + ZellijLayoutGenerator._create_tab_section(tab_name, cwd, command)
|
|
141
146
|
return layout_content + "\n}\n"
|
|
142
|
-
|
|
147
|
+
|
|
143
148
|
@staticmethod
|
|
144
149
|
def check_command_status(tab_name: str, tab_config: Dict[str, tuple[str, str]]) -> Dict[str, Any]:
|
|
145
150
|
if tab_name not in tab_config:
|
|
146
|
-
return {
|
|
147
|
-
|
|
148
|
-
"error": f"Tab '{tab_name}' not found in tracked tab config",
|
|
149
|
-
"running": False,
|
|
150
|
-
"pid": None,
|
|
151
|
-
"command": None,
|
|
152
|
-
"cwd": None
|
|
153
|
-
}
|
|
154
|
-
|
|
151
|
+
return {"status": "unknown", "error": f"Tab '{tab_name}' not found in tracked tab config", "running": False, "pid": None, "command": None, "cwd": None}
|
|
152
|
+
|
|
155
153
|
cwd, command = tab_config[tab_name]
|
|
156
154
|
cmd, _ = ZellijLayoutGenerator._parse_command(command)
|
|
157
|
-
|
|
155
|
+
|
|
158
156
|
try:
|
|
159
157
|
# Look for processes matching the command
|
|
160
158
|
matching_processes = []
|
|
161
|
-
for proc in psutil.process_iter([
|
|
159
|
+
for proc in psutil.process_iter(["pid", "name", "cmdline", "status"]):
|
|
162
160
|
try:
|
|
163
|
-
if proc.info[
|
|
161
|
+
if proc.info["cmdline"] and len(proc.info["cmdline"]) > 0:
|
|
164
162
|
# Check if the command matches
|
|
165
|
-
if
|
|
166
|
-
|
|
167
|
-
any(cmd in arg for arg in proc.info['cmdline'])):
|
|
168
|
-
matching_processes.append({
|
|
169
|
-
"pid": proc.info['pid'],
|
|
170
|
-
"name": proc.info['name'],
|
|
171
|
-
"cmdline": proc.info['cmdline'],
|
|
172
|
-
"status": proc.info['status']
|
|
173
|
-
})
|
|
163
|
+
if proc.info["name"] == cmd or cmd in proc.info["cmdline"][0] or any(cmd in arg for arg in proc.info["cmdline"]):
|
|
164
|
+
matching_processes.append({"pid": proc.info["pid"], "name": proc.info["name"], "cmdline": proc.info["cmdline"], "status": proc.info["status"]})
|
|
174
165
|
except (psutil.NoSuchProcess, psutil.AccessDenied):
|
|
175
166
|
continue
|
|
176
|
-
|
|
167
|
+
|
|
177
168
|
if matching_processes:
|
|
178
|
-
return {
|
|
179
|
-
"status": "running",
|
|
180
|
-
"running": True,
|
|
181
|
-
"processes": matching_processes,
|
|
182
|
-
"command": command,
|
|
183
|
-
"cwd": cwd,
|
|
184
|
-
"tab_name": tab_name
|
|
185
|
-
}
|
|
169
|
+
return {"status": "running", "running": True, "processes": matching_processes, "command": command, "cwd": cwd, "tab_name": tab_name}
|
|
186
170
|
else:
|
|
187
|
-
return {
|
|
188
|
-
|
|
189
|
-
"running": False,
|
|
190
|
-
"processes": [],
|
|
191
|
-
"command": command,
|
|
192
|
-
"cwd": cwd,
|
|
193
|
-
"tab_name": tab_name
|
|
194
|
-
}
|
|
195
|
-
|
|
171
|
+
return {"status": "not_running", "running": False, "processes": [], "command": command, "cwd": cwd, "tab_name": tab_name}
|
|
172
|
+
|
|
196
173
|
except Exception as e:
|
|
197
174
|
logger.error(f"Error checking command status for tab '{tab_name}': {e}")
|
|
198
|
-
return {
|
|
199
|
-
"status": "error",
|
|
200
|
-
"error": str(e),
|
|
201
|
-
"running": False,
|
|
202
|
-
"command": command,
|
|
203
|
-
"cwd": cwd,
|
|
204
|
-
"tab_name": tab_name
|
|
205
|
-
}
|
|
175
|
+
return {"status": "error", "error": str(e), "running": False, "command": command, "cwd": cwd, "tab_name": tab_name}
|
|
206
176
|
|
|
207
177
|
def check_all_commands_status(self) -> Dict[str, Dict[str, Any]]:
|
|
208
178
|
if not self.tab_config:
|
|
209
179
|
logger.warning("No tab config tracked. Make sure to create a layout first.")
|
|
210
180
|
return {}
|
|
211
|
-
|
|
181
|
+
|
|
212
182
|
status_report = {}
|
|
213
183
|
for tab_name in self.tab_config:
|
|
214
184
|
status_report[tab_name] = ZellijLayoutGenerator.check_command_status(tab_name, self.tab_config)
|
|
215
|
-
|
|
185
|
+
|
|
216
186
|
return status_report
|
|
217
187
|
|
|
218
188
|
@staticmethod
|
|
219
189
|
def check_zellij_session_status(session_name: str) -> Dict[str, Any]:
|
|
220
190
|
try:
|
|
221
191
|
# Run zellij list-sessions command
|
|
222
|
-
result = subprocess.run(
|
|
223
|
-
|
|
224
|
-
capture_output=True,
|
|
225
|
-
text=True,
|
|
226
|
-
timeout=10
|
|
227
|
-
)
|
|
228
|
-
|
|
192
|
+
result = subprocess.run(["zellij", "list-sessions"], capture_output=True, text=True, timeout=10)
|
|
193
|
+
|
|
229
194
|
if result.returncode == 0:
|
|
230
|
-
sessions = result.stdout.strip().split(
|
|
195
|
+
sessions = result.stdout.strip().split("\n") if result.stdout.strip() else []
|
|
231
196
|
session_running = any(session_name in session for session in sessions)
|
|
232
|
-
|
|
233
|
-
return {
|
|
234
|
-
"zellij_running": True,
|
|
235
|
-
"session_exists": session_running,
|
|
236
|
-
"session_name": session_name,
|
|
237
|
-
"all_sessions": sessions
|
|
238
|
-
}
|
|
197
|
+
|
|
198
|
+
return {"zellij_running": True, "session_exists": session_running, "session_name": session_name, "all_sessions": sessions}
|
|
239
199
|
else:
|
|
240
|
-
return {
|
|
241
|
-
|
|
242
|
-
"error": result.stderr,
|
|
243
|
-
"session_name": session_name
|
|
244
|
-
}
|
|
245
|
-
|
|
200
|
+
return {"zellij_running": False, "error": result.stderr, "session_name": session_name}
|
|
201
|
+
|
|
246
202
|
except subprocess.TimeoutExpired:
|
|
247
|
-
return {
|
|
248
|
-
"zellij_running": False,
|
|
249
|
-
"error": "Timeout while checking Zellij sessions",
|
|
250
|
-
"session_name": session_name
|
|
251
|
-
}
|
|
203
|
+
return {"zellij_running": False, "error": "Timeout while checking Zellij sessions", "session_name": session_name}
|
|
252
204
|
except FileNotFoundError:
|
|
253
|
-
return {
|
|
254
|
-
"zellij_running": False,
|
|
255
|
-
"error": "Zellij not found in PATH",
|
|
256
|
-
"session_name": session_name
|
|
257
|
-
}
|
|
205
|
+
return {"zellij_running": False, "error": "Zellij not found in PATH", "session_name": session_name}
|
|
258
206
|
except Exception as e:
|
|
259
|
-
return {
|
|
260
|
-
"zellij_running": False,
|
|
261
|
-
"error": str(e),
|
|
262
|
-
"session_name": session_name
|
|
263
|
-
}
|
|
207
|
+
return {"zellij_running": False, "error": str(e), "session_name": session_name}
|
|
264
208
|
|
|
265
209
|
def get_comprehensive_status(self) -> Dict[str, Any]:
|
|
266
210
|
zellij_status = ZellijLayoutGenerator.check_zellij_session_status(self.session_name or "default")
|
|
267
211
|
commands_status = self.check_all_commands_status()
|
|
268
|
-
|
|
212
|
+
|
|
269
213
|
running_count = sum(1 for status in commands_status.values() if status.get("running", False))
|
|
270
214
|
total_count = len(commands_status)
|
|
271
|
-
|
|
215
|
+
|
|
272
216
|
return {
|
|
273
217
|
"zellij_session": zellij_status,
|
|
274
218
|
"commands": commands_status,
|
|
275
|
-
"summary": {
|
|
276
|
-
"total_commands": total_count,
|
|
277
|
-
"running_commands": running_count,
|
|
278
|
-
"stopped_commands": total_count - running_count,
|
|
279
|
-
"session_healthy": zellij_status.get("session_exists", False)
|
|
280
|
-
}
|
|
219
|
+
"summary": {"total_commands": total_count, "running_commands": running_count, "stopped_commands": total_count - running_count, "session_healthy": zellij_status.get("session_exists", False)},
|
|
281
220
|
}
|
|
282
221
|
|
|
283
222
|
def print_status_report(self) -> None:
|
|
284
223
|
from rich.panel import Panel
|
|
285
224
|
from rich.table import Table
|
|
286
|
-
|
|
225
|
+
|
|
287
226
|
status = self.get_comprehensive_status()
|
|
288
|
-
|
|
227
|
+
|
|
289
228
|
# Create main panel
|
|
290
229
|
console.print()
|
|
291
230
|
console.print(Panel.fit("π ZELLIJ LAYOUT STATUS REPORT", style="bold cyan"))
|
|
292
|
-
|
|
231
|
+
|
|
293
232
|
# Zellij session status
|
|
294
233
|
zellij = status["zellij_session"]
|
|
295
234
|
if zellij.get("zellij_running", False):
|
|
@@ -298,11 +237,11 @@ class ZellijLayoutGenerator:
|
|
|
298
237
|
else:
|
|
299
238
|
console.print(f"[bold yellow]β οΈ Zellij is running but session[/bold yellow] [yellow]'{self.session_name}'[/yellow] [yellow]not found[/yellow]")
|
|
300
239
|
else:
|
|
301
|
-
error_msg = zellij.get(
|
|
240
|
+
error_msg = zellij.get("error", "Unknown error")
|
|
302
241
|
console.print(f"[bold red]β Zellij session issue:[/bold red] [red]{error_msg}[/red]")
|
|
303
|
-
|
|
242
|
+
|
|
304
243
|
console.print()
|
|
305
|
-
|
|
244
|
+
|
|
306
245
|
# Commands status table
|
|
307
246
|
table = Table(title="π COMMAND STATUS", show_header=True, header_style="bold magenta")
|
|
308
247
|
table.add_column("Tab", style="cyan", no_wrap=True)
|
|
@@ -310,7 +249,7 @@ class ZellijLayoutGenerator:
|
|
|
310
249
|
table.add_column("PID", justify="center", style="dim")
|
|
311
250
|
table.add_column("Memory", justify="center", style="blue")
|
|
312
251
|
table.add_column("Command", style="green", max_width=40)
|
|
313
|
-
|
|
252
|
+
|
|
314
253
|
for tab_name, cmd_status in status["commands"].items():
|
|
315
254
|
# Determine status display
|
|
316
255
|
if cmd_status.get("running", False):
|
|
@@ -318,8 +257,8 @@ class ZellijLayoutGenerator:
|
|
|
318
257
|
processes = cmd_status.get("processes", [])
|
|
319
258
|
if processes:
|
|
320
259
|
proc = processes[0] # Show first process
|
|
321
|
-
pid = str(proc.get(
|
|
322
|
-
memory = f"{proc.get('memory_mb', 0):.1f}MB" if proc.get(
|
|
260
|
+
pid = str(proc.get("pid", "N/A"))
|
|
261
|
+
memory = f"{proc.get('memory_mb', 0):.1f}MB" if proc.get("memory_mb") else "N/A"
|
|
323
262
|
else:
|
|
324
263
|
pid = "N/A"
|
|
325
264
|
memory = "N/A"
|
|
@@ -327,46 +266,51 @@ class ZellijLayoutGenerator:
|
|
|
327
266
|
status_text = "[bold red]β Stopped[/bold red]"
|
|
328
267
|
pid = "N/A"
|
|
329
268
|
memory = "N/A"
|
|
330
|
-
|
|
331
|
-
command = cmd_status.get(
|
|
269
|
+
|
|
270
|
+
command = cmd_status.get("command", "Unknown")
|
|
332
271
|
# Truncate long commands
|
|
333
272
|
if len(command) > 35:
|
|
334
273
|
command = command[:32] + "..."
|
|
335
|
-
|
|
274
|
+
|
|
336
275
|
table.add_row(tab_name, status_text, pid, memory, command)
|
|
337
|
-
|
|
276
|
+
|
|
338
277
|
console.print(table)
|
|
339
278
|
console.print()
|
|
340
|
-
|
|
279
|
+
|
|
341
280
|
# Enhanced summary
|
|
342
281
|
summary = status["summary"]
|
|
343
282
|
from rich.panel import Panel
|
|
344
|
-
|
|
345
|
-
[
|
|
346
|
-
[
|
|
347
|
-
[
|
|
348
|
-
|
|
283
|
+
|
|
284
|
+
summary_text = f"""[bold]Total commands:[/bold] {summary["total_commands"]}
|
|
285
|
+
[green]Running:[/green] {summary["running_commands"]}
|
|
286
|
+
[red]Stopped:[/red] {summary["stopped_commands"]}
|
|
287
|
+
[yellow]Session healthy:[/yellow] {"β
" if summary["session_healthy"] else "β"}"""
|
|
288
|
+
|
|
349
289
|
console.print(Panel(summary_text, title="π Summary", style="blue"))
|
|
350
290
|
|
|
291
|
+
|
|
351
292
|
def created_zellij_layout(tab_config: Dict[str, tuple[str, str]], output_dir: Optional[str] = None) -> str:
|
|
352
293
|
generator = ZellijLayoutGenerator()
|
|
353
294
|
return generator.create_zellij_layout(tab_config, output_dir)
|
|
295
|
+
|
|
296
|
+
|
|
354
297
|
def run_zellij_layout(tab_config: Dict[str, tuple[str, str]], session_name: Optional[str] = None) -> str:
|
|
355
298
|
if not session_name:
|
|
356
|
-
session_name =
|
|
299
|
+
session_name = "".join(random.choices(string.ascii_lowercase + string.digits, k=8))
|
|
357
300
|
layout_path = created_zellij_layout(tab_config)
|
|
358
|
-
|
|
301
|
+
|
|
359
302
|
# Use enhanced command execution
|
|
360
303
|
try:
|
|
361
304
|
from .enhanced_command_runner import enhanced_zellij_session_start
|
|
305
|
+
|
|
362
306
|
enhanced_zellij_session_start(session_name, layout_path)
|
|
363
307
|
except ImportError:
|
|
364
308
|
# Fallback to original implementation
|
|
365
309
|
cmd = f"zellij delete-session --force {session_name}; zellij --layout {layout_path} a -b {session_name}"
|
|
366
310
|
import subprocess
|
|
311
|
+
|
|
367
312
|
subprocess.run(cmd, shell=True, check=True)
|
|
368
313
|
console.print(f"[bold green]π Zellij layout is running[/bold green] [yellow]@[/yellow] [bold cyan]{session_name}[/bold cyan]")
|
|
369
|
-
|
|
370
314
|
return session_name
|
|
371
315
|
|
|
372
316
|
|
|
@@ -394,25 +338,25 @@ zellij action close-pane; sleep 2
|
|
|
394
338
|
if __name__ == "__main__":
|
|
395
339
|
sample_tabs = {
|
|
396
340
|
"π€Bot1": ("~/code/bytesense/bithence", "~/scripts/fire -mO go1.py bot1 --kw create_new_bot True"),
|
|
397
|
-
"π€Bot2": ("~/code/bytesense/bithence", "~/scripts/fire -mO go2.py bot2 --kw create_new_bot True"),
|
|
341
|
+
"π€Bot2": ("~/code/bytesense/bithence", "~/scripts/fire -mO go2.py bot2 --kw create_new_bot True"),
|
|
398
342
|
"πMonitor": ("~", "htop"),
|
|
399
|
-
"πLogs": ("/var/log", "tail -f /var/log/app.log")
|
|
343
|
+
"πLogs": ("/var/log", "tail -f /var/log/app.log"),
|
|
400
344
|
}
|
|
401
345
|
try:
|
|
402
346
|
# Create layout using the generator directly to access status methods
|
|
403
347
|
generator = ZellijLayoutGenerator()
|
|
404
348
|
layout_path = generator.create_zellij_layout(sample_tabs, session_name="test_session")
|
|
405
349
|
print(f"β
Layout created successfully: {layout_path}")
|
|
406
|
-
|
|
350
|
+
|
|
407
351
|
# Demonstrate status checking
|
|
408
352
|
print("\nπ Checking command status (this is just a demo - commands aren't actually running):")
|
|
409
353
|
generator.print_status_report()
|
|
410
|
-
|
|
354
|
+
|
|
411
355
|
# Individual command status check
|
|
412
356
|
print("\nπ Individual command status for Bot1:")
|
|
413
357
|
bot1_status = ZellijLayoutGenerator.check_command_status("π€Bot1", generator.tab_config)
|
|
414
358
|
print(f"Status: {bot1_status['status']}")
|
|
415
359
|
print(f"Running: {bot1_status['running']}")
|
|
416
|
-
|
|
360
|
+
|
|
417
361
|
except Exception as e:
|
|
418
362
|
print(f"β Error: {e}")
|