machineconfig 5.15__py3-none-any.whl → 7.98__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.
- machineconfig/__init__.py +0 -28
- machineconfig/cluster/remote/cloud_manager.py +1 -1
- machineconfig/cluster/remote/distribute.py +0 -1
- machineconfig/cluster/remote/file_manager.py +0 -2
- machineconfig/cluster/remote/script_execution.py +0 -1
- machineconfig/cluster/sessions_managers/{utils → helpers}/enhanced_command_runner.py +4 -6
- machineconfig/cluster/sessions_managers/utils/load_balancer.py +1 -1
- machineconfig/cluster/sessions_managers/utils/maker.py +69 -0
- machineconfig/cluster/sessions_managers/wt_local.py +114 -289
- machineconfig/cluster/sessions_managers/wt_local_manager.py +70 -210
- machineconfig/cluster/sessions_managers/wt_remote.py +51 -43
- machineconfig/cluster/sessions_managers/wt_remote_manager.py +52 -198
- machineconfig/cluster/sessions_managers/wt_utils/layout_generator.py +6 -19
- machineconfig/cluster/sessions_managers/wt_utils/manager_persistence.py +52 -0
- machineconfig/cluster/sessions_managers/wt_utils/monitoring_helpers.py +50 -0
- machineconfig/cluster/sessions_managers/wt_utils/status_reporter.py +4 -2
- machineconfig/cluster/sessions_managers/wt_utils/status_reporting.py +76 -0
- machineconfig/cluster/sessions_managers/wt_utils/wt_helpers.py +199 -0
- machineconfig/cluster/sessions_managers/zellij_local.py +81 -375
- machineconfig/cluster/sessions_managers/zellij_local_manager.py +25 -170
- machineconfig/cluster/sessions_managers/zellij_remote.py +40 -41
- machineconfig/cluster/sessions_managers/zellij_remote_manager.py +16 -12
- machineconfig/cluster/sessions_managers/zellij_utils/example_usage.py +4 -8
- machineconfig/cluster/sessions_managers/zellij_utils/layout_generator.py +5 -20
- machineconfig/cluster/sessions_managers/zellij_utils/process_monitor.py +3 -9
- machineconfig/cluster/sessions_managers/zellij_utils/status_reporter.py +3 -1
- machineconfig/cluster/sessions_managers/zellij_utils/zellij_local_helper.py +298 -0
- machineconfig/cluster/sessions_managers/zellij_utils/zellij_local_helper_restart.py +77 -0
- machineconfig/cluster/sessions_managers/zellij_utils/zellij_local_helper_with_panes.py +228 -0
- machineconfig/cluster/sessions_managers/zellij_utils/zellij_local_manager_helper.py +165 -0
- machineconfig/jobs/{python → installer}/check_installations.py +2 -3
- machineconfig/jobs/installer/custom/boxes.py +61 -0
- machineconfig/jobs/installer/custom/hx.py +76 -19
- machineconfig/jobs/installer/custom/yazi.py +119 -0
- machineconfig/jobs/installer/custom_dev/alacritty.py +4 -4
- machineconfig/jobs/installer/custom_dev/brave.py +5 -9
- machineconfig/jobs/installer/custom_dev/cloudflare_warp_cli.py +23 -0
- machineconfig/jobs/installer/custom_dev/code.py +4 -1
- machineconfig/jobs/installer/custom_dev/dubdb_adbc.py +30 -0
- machineconfig/jobs/installer/custom_dev/nerdfont.py +1 -1
- machineconfig/jobs/installer/custom_dev/nerfont_windows_helper.py +33 -28
- machineconfig/jobs/installer/custom_dev/sysabc.py +139 -0
- machineconfig/jobs/installer/custom_dev/wezterm.py +2 -19
- machineconfig/jobs/installer/custom_dev/winget.py +10 -14
- machineconfig/jobs/installer/installer_data.json +1487 -229
- machineconfig/jobs/installer/linux_scripts/brave.sh +4 -14
- machineconfig/jobs/installer/linux_scripts/{warp-cli.sh → cloudflare_warp_cli.sh} +5 -17
- machineconfig/jobs/installer/linux_scripts/docker.sh +5 -17
- machineconfig/jobs/installer/linux_scripts/docker_start.sh +6 -14
- machineconfig/jobs/installer/linux_scripts/edge.sh +3 -11
- machineconfig/jobs/{linux/msc → installer/linux_scripts}/lid.sh +2 -8
- machineconfig/jobs/installer/linux_scripts/nerdfont.sh +5 -17
- machineconfig/jobs/{linux/msc → installer/linux_scripts}/network.sh +2 -8
- machineconfig/jobs/installer/linux_scripts/q.sh +10 -6
- machineconfig/jobs/installer/linux_scripts/redis.sh +6 -17
- machineconfig/jobs/installer/linux_scripts/vscode.sh +5 -17
- machineconfig/jobs/installer/linux_scripts/wezterm.sh +4 -12
- machineconfig/jobs/installer/package_groups.py +106 -177
- machineconfig/jobs/installer/powershell_scripts/install_fonts.ps1 +129 -34
- machineconfig/logger.py +0 -1
- machineconfig/profile/backup.toml +49 -0
- machineconfig/profile/bash_shell_profiles.md +11 -0
- machineconfig/profile/create_helper.py +62 -0
- machineconfig/profile/create_links.py +288 -0
- machineconfig/profile/create_links_export.py +100 -0
- machineconfig/profile/create_shell_profile.py +147 -0
- machineconfig/profile/mapper.toml +263 -0
- machineconfig/scripts/__init__.py +0 -4
- machineconfig/scripts/linux/{share_cloud.sh → other/share_cloud.sh} +14 -25
- machineconfig/scripts/linux/wrap_mcfg +46 -0
- machineconfig/scripts/nu/wrap_mcfg.nu +69 -0
- machineconfig/scripts/python/agents.py +123 -117
- machineconfig/scripts/python/ai/initai.py +3 -28
- machineconfig/scripts/python/ai/scripts/command_runner.ps1 +33 -0
- machineconfig/scripts/python/ai/scripts/command_runner.sh +9 -0
- machineconfig/scripts/python/ai/scripts/lint_and_type_check.ps1 +17 -18
- machineconfig/scripts/python/ai/scripts/lint_and_type_check.sh +17 -18
- machineconfig/scripts/python/ai/solutions/_shared.py +9 -1
- machineconfig/scripts/python/ai/solutions/copilot/{chatmodes/Thinking-Beast-Mode.chatmode.md → agents/Thinking-Beast-Mode.agent.md} +0 -1
- machineconfig/scripts/python/ai/solutions/copilot/{chatmodes/Ultimate-Transparent-Thinking-Beast-Mode.chatmode.md → agents/Ultimate-Transparent-Thinking-Beast-Mode.agent.md} +0 -1
- machineconfig/scripts/python/ai/solutions/copilot/{chatmodes/deepResearch.chatmode.md → agents/deepResearch.agent.md} +2 -2
- machineconfig/scripts/python/ai/solutions/copilot/github_copilot.py +5 -5
- machineconfig/scripts/python/ai/solutions/copilot/instructions/python/dev.instructions.md +5 -1
- machineconfig/scripts/python/ai/solutions/copilot/instructions/python/watch_exec.prompt.md +20 -0
- machineconfig/scripts/python/ai/solutions/copilot/prompts/pyright_fix.md +16 -0
- machineconfig/scripts/python/ai/solutions/generic.py +28 -5
- machineconfig/scripts/python/ai/utils/generate_files.py +348 -0
- machineconfig/scripts/python/ai/utils/vscode_tasks.py +37 -0
- machineconfig/scripts/python/cloud.py +29 -0
- machineconfig/scripts/python/croshell.py +137 -113
- machineconfig/scripts/python/devops.py +61 -101
- machineconfig/scripts/python/devops_navigator.py +6 -0
- machineconfig/scripts/python/env_manager/__init__.py +1 -0
- machineconfig/scripts/python/env_manager/env_manager_tui.py +204 -0
- machineconfig/scripts/python/env_manager/path_manager_backend.py +47 -0
- machineconfig/scripts/python/env_manager/path_manager_tui.py +228 -0
- machineconfig/scripts/python/fire_jobs.py +110 -150
- machineconfig/scripts/python/ftpx.py +51 -24
- machineconfig/scripts/python/helpers/ast_search.py +74 -0
- machineconfig/scripts/python/helpers/qr_code.py +166 -0
- machineconfig/scripts/python/helpers/repo_rag.py +325 -0
- machineconfig/scripts/python/helpers/run_py_script.py +79 -0
- machineconfig/scripts/python/helpers/symantic_search.py +25 -0
- machineconfig/scripts/python/helpers/tmp_py_scripts/a.py +26 -0
- machineconfig/scripts/python/helpers_agents/agentic_frameworks/fire_crush.json +14 -0
- machineconfig/scripts/python/helpers_agents/agentic_frameworks/fire_crush.py +39 -0
- machineconfig/scripts/python/helpers_agents/agentic_frameworks/fire_cursor_agents.py +22 -0
- machineconfig/scripts/python/helpers_agents/agentic_frameworks/fire_gemini.py +55 -0
- machineconfig/scripts/python/helpers_agents/agentic_frameworks/fire_qwen.py +30 -0
- machineconfig/scripts/python/helpers_agents/fire_agents_help_launch.py +126 -0
- machineconfig/scripts/python/helpers_agents/fire_agents_helper_types.py +41 -0
- machineconfig/scripts/python/helpers_agents/templates/prompt.txt +10 -0
- machineconfig/scripts/python/helpers_agents/templates/template.ps1 +14 -0
- machineconfig/scripts/python/helpers_agents/templates/template.sh +32 -0
- machineconfig/scripts/python/{cloud_copy.py → helpers_cloud/cloud_copy.py} +30 -23
- machineconfig/scripts/python/{cloud_mount.py → helpers_cloud/cloud_mount.py} +29 -35
- machineconfig/scripts/python/{cloud_sync.py → helpers_cloud/cloud_sync.py} +12 -18
- machineconfig/scripts/python/{helpers → helpers_cloud}/helpers2.py +1 -1
- machineconfig/scripts/python/helpers_croshell/crosh.py +39 -0
- machineconfig/scripts/python/{start_slidev.py → helpers_croshell/start_slidev.py} +8 -9
- machineconfig/scripts/python/helpers_devops/cli_config.py +105 -0
- machineconfig/scripts/python/helpers_devops/cli_config_dotfile.py +89 -0
- machineconfig/scripts/python/helpers_devops/cli_data.py +25 -0
- machineconfig/scripts/python/helpers_devops/cli_nw.py +214 -0
- machineconfig/scripts/python/helpers_devops/cli_repos.py +215 -0
- machineconfig/scripts/python/helpers_devops/cli_self.py +172 -0
- machineconfig/scripts/python/helpers_devops/cli_share_file.py +137 -0
- machineconfig/scripts/python/helpers_devops/cli_share_server.py +142 -0
- machineconfig/scripts/python/{share_terminal.py → helpers_devops/cli_share_terminal.py} +45 -35
- machineconfig/scripts/python/helpers_devops/cli_utils.py +96 -0
- machineconfig/scripts/python/{devops_backup_retrieve.py → helpers_devops/devops_backup_retrieve.py} +7 -10
- machineconfig/scripts/python/helpers_devops/devops_status.py +499 -0
- machineconfig/scripts/python/{devops_update_repos.py → helpers_devops/devops_update_repos.py} +68 -49
- machineconfig/scripts/python/helpers_devops/themes/choose_pwsh_theme.ps1 +81 -0
- machineconfig/scripts/python/helpers_devops/themes/choose_starship_theme.bash +3 -0
- machineconfig/scripts/python/{choose_wezterm_theme.py → helpers_devops/themes/choose_wezterm_theme.py} +3 -3
- machineconfig/scripts/python/helpers_fire_command/__init__.py +0 -0
- machineconfig/scripts/python/helpers_fire_command/f.py +0 -0
- machineconfig/scripts/python/{helpers/helpers4.py → helpers_fire_command/file_wrangler.py} +56 -20
- machineconfig/scripts/python/{fire_jobs_args_helper.py → helpers_fire_command/fire_jobs_args_helper.py} +5 -1
- machineconfig/scripts/python/helpers_fire_command/fire_jobs_route_helper.py +121 -0
- machineconfig/scripts/python/helpers_fire_command/fire_jobs_streamlit_helper.py +0 -0
- machineconfig/scripts/python/helpers_msearch/__init__.py +5 -0
- machineconfig/scripts/{linux → python/helpers_msearch/scripts_linux}/fzfg +3 -3
- machineconfig/scripts/python/helpers_msearch/scripts_windows/fzfg.ps1 +59 -0
- machineconfig/scripts/python/helpers_navigator/__init__.py +20 -0
- machineconfig/scripts/python/helpers_navigator/command_builder.py +111 -0
- machineconfig/scripts/python/helpers_navigator/command_detail.py +44 -0
- machineconfig/scripts/python/helpers_navigator/command_tree.py +620 -0
- machineconfig/scripts/python/helpers_navigator/data_models.py +28 -0
- machineconfig/scripts/python/helpers_navigator/main_app.py +272 -0
- machineconfig/scripts/python/helpers_navigator/search_bar.py +15 -0
- machineconfig/scripts/python/helpers_network/__init__.py +0 -0
- machineconfig/scripts/python/helpers_network/address.py +132 -0
- machineconfig/scripts/python/{devops_add_identity.py → helpers_network/devops_add_identity.py} +0 -2
- machineconfig/scripts/python/helpers_network/devops_add_ssh_key.py +153 -0
- machineconfig/scripts/{linux → python/helpers_network}/mount_nfs +0 -1
- machineconfig/scripts/python/{mount_nfs.py → helpers_network/mount_nfs.py} +3 -3
- machineconfig/scripts/{linux → python/helpers_network}/mount_nw_drive +1 -2
- machineconfig/scripts/python/{mount_ssh.py → helpers_network/mount_ssh.py} +3 -3
- machineconfig/scripts/python/{onetimeshare.py → helpers_network/onetimeshare.py} +0 -1
- machineconfig/scripts/python/helpers_network/ssh_debug_linux.py +391 -0
- machineconfig/scripts/python/helpers_network/ssh_debug_windows.py +338 -0
- machineconfig/scripts/python/{wifi_conn.py → helpers_network/wifi_conn.py} +1 -53
- machineconfig/scripts/python/{wsl_windows_transfer.py → helpers_network/wsl_windows_transfer.py} +5 -4
- machineconfig/scripts/python/helpers_repos/action.py +209 -0
- machineconfig/scripts/python/helpers_repos/action_helper.py +150 -0
- machineconfig/scripts/python/{repos_helper_clone.py → helpers_repos/clone.py} +2 -3
- machineconfig/scripts/python/helpers_repos/cloud_repo_sync.py +218 -0
- machineconfig/scripts/python/{repos_helper.py → helpers_repos/entrypoint.py} +9 -17
- machineconfig/scripts/python/helpers_repos/grource.py +340 -0
- machineconfig/scripts/python/{repos_helper_record.py → helpers_repos/record.py} +4 -3
- machineconfig/scripts/python/helpers_repos/repo_analyzer_1.py +160 -0
- machineconfig/scripts/python/{count_lines.py → helpers_repos/repo_analyzer_2.py} +113 -192
- machineconfig/scripts/python/helpers_repos/sync.py +66 -0
- machineconfig/scripts/python/{repos_helper_update.py → helpers_repos/update.py} +3 -3
- machineconfig/scripts/python/helpers_sessions/__init__.py +0 -0
- machineconfig/scripts/python/helpers_sessions/sessions_multiprocess.py +65 -0
- machineconfig/scripts/python/helpers_utils/download.py +150 -0
- machineconfig/scripts/python/helpers_utils/path.py +185 -0
- machineconfig/scripts/python/interactive.py +64 -84
- machineconfig/scripts/python/mcfg_entry.py +58 -0
- machineconfig/scripts/python/msearch.py +71 -0
- machineconfig/scripts/python/sessions.py +119 -45
- machineconfig/scripts/python/terminal.py +133 -0
- machineconfig/scripts/python/utils.py +64 -0
- machineconfig/scripts/windows/mounts/Restore-ThunderbirdProfile.ps1 +92 -0
- machineconfig/scripts/windows/{mount_nfs.ps1 → mounts/mount_nfs.ps1} +1 -3
- machineconfig/scripts/windows/{mount_ssh.ps1 → mounts/mount_ssh.ps1} +1 -1
- machineconfig/scripts/windows/{share_smb.ps1 → mounts/share_smb.ps1} +0 -6
- machineconfig/scripts/windows/wrap_mcfg.ps1 +63 -0
- machineconfig/settings/broot/br.sh +0 -4
- machineconfig/settings/broot/conf.toml +1 -1
- machineconfig/settings/helix/config.toml +16 -0
- machineconfig/settings/helix/languages.toml +13 -4
- machineconfig/settings/helix/yazi-picker.sh +12 -0
- machineconfig/settings/lf/linux/exe/lfcd.sh +1 -0
- machineconfig/settings/lf/linux/exe/previewer.sh +9 -3
- machineconfig/settings/lf/linux/lfrc +10 -12
- machineconfig/settings/lf/windows/lfcd.ps1 +1 -1
- machineconfig/settings/lf/windows/lfrc +18 -38
- machineconfig/settings/lf/windows/mkfile.ps1 +1 -1
- machineconfig/settings/linters/.ruff.toml +1 -1
- machineconfig/settings/lvim/windows/archive/config_additional.lua +0 -6
- machineconfig/settings/marimo/marimo.toml +80 -0
- machineconfig/settings/marimo/snippets/globalize.py +34 -0
- machineconfig/settings/pistol/pistol.conf +1 -1
- machineconfig/settings/shells/bash/init.sh +82 -31
- machineconfig/settings/shells/ipy/profiles/default/startup/playext.py +1 -1
- machineconfig/settings/shells/nushell/config.nu +2 -35
- machineconfig/settings/shells/nushell/env.nu +45 -6
- machineconfig/settings/shells/nushell/init.nu +314 -0
- machineconfig/settings/shells/pwsh/init.ps1 +61 -43
- machineconfig/settings/shells/starship/starship.toml +16 -0
- machineconfig/settings/shells/wezterm/wezterm.lua +2 -0
- machineconfig/settings/shells/wt/settings.json +32 -17
- machineconfig/settings/shells/zsh/init.sh +89 -0
- machineconfig/settings/svim/linux/init.toml +0 -4
- machineconfig/settings/svim/windows/init.toml +0 -3
- machineconfig/settings/television/cable_unix/alias.toml +8 -0
- machineconfig/settings/television/cable_unix/aws-buckets.toml +14 -0
- machineconfig/settings/television/cable_unix/aws-instances.toml +13 -0
- machineconfig/settings/television/cable_unix/bash-history.toml +8 -0
- machineconfig/settings/television/cable_unix/channels.toml +19 -0
- machineconfig/settings/television/cable_unix/dirs.toml +13 -0
- machineconfig/settings/television/cable_unix/distrobox-list.toml +42 -0
- machineconfig/settings/television/cable_unix/docker-images.toml +13 -0
- machineconfig/settings/television/cable_unix/dotfiles.toml +11 -0
- machineconfig/settings/television/cable_unix/env.toml +17 -0
- machineconfig/settings/television/cable_unix/files.toml +11 -0
- machineconfig/settings/television/cable_unix/fish-history.toml +8 -0
- machineconfig/settings/television/cable_unix/git-branch.toml +11 -0
- machineconfig/settings/television/cable_unix/git-diff.toml +10 -0
- machineconfig/settings/television/cable_unix/git-log.toml +12 -0
- machineconfig/settings/television/cable_unix/git-reflog.toml +12 -0
- machineconfig/settings/television/cable_unix/git-repos.toml +16 -0
- machineconfig/settings/television/cable_unix/guix.toml +20 -0
- machineconfig/settings/television/cable_unix/just-recipes.toml +18 -0
- machineconfig/settings/television/cable_unix/k8s-deployments.toml +36 -0
- machineconfig/settings/television/cable_unix/k8s-pods.toml +50 -0
- machineconfig/settings/television/cable_unix/k8s-services.toml +36 -0
- machineconfig/settings/television/cable_unix/man-pages.toml +24 -0
- machineconfig/settings/television/cable_unix/nu-history.toml +7 -0
- machineconfig/settings/television/cable_unix/procs.toml +20 -0
- machineconfig/settings/television/cable_unix/text.toml +17 -0
- machineconfig/settings/television/cable_unix/tldr.toml +18 -0
- machineconfig/settings/television/cable_unix/zsh-history.toml +9 -0
- machineconfig/settings/television/cable_windows/alias.toml +7 -0
- machineconfig/settings/television/cable_windows/dirs.toml +13 -0
- machineconfig/settings/television/cable_windows/docker-images.toml +13 -0
- machineconfig/settings/television/cable_windows/dotfiles.toml +11 -0
- machineconfig/settings/television/cable_windows/env.toml +17 -0
- machineconfig/settings/television/cable_windows/files.toml +14 -0
- machineconfig/settings/television/cable_windows/git-branch.toml +11 -0
- machineconfig/settings/television/cable_windows/git-diff.toml +10 -0
- machineconfig/settings/television/cable_windows/git-log.toml +11 -0
- machineconfig/settings/television/cable_windows/git-reflog.toml +11 -0
- machineconfig/settings/television/cable_windows/git-repos.toml +15 -0
- machineconfig/settings/television/cable_windows/nu-history.toml +7 -0
- machineconfig/settings/television/cable_windows/pwsh-history.toml +6 -0
- machineconfig/settings/television/cable_windows/text.toml +17 -0
- machineconfig/settings/yazi/init.lua +61 -0
- machineconfig/settings/yazi/keymap_linux.toml +94 -0
- machineconfig/settings/yazi/keymap_windows.toml +78 -0
- machineconfig/settings/yazi/shell/yazi_cd.ps1 +33 -0
- machineconfig/settings/yazi/shell/yazi_cd.sh +8 -0
- machineconfig/settings/yazi/theme.toml +4 -0
- machineconfig/settings/yazi/yazi_linux.toml +84 -0
- machineconfig/settings/yazi/yazi_windows.toml +58 -0
- machineconfig/setup_linux/__init__.py +11 -0
- machineconfig/setup_linux/apps_desktop.sh +89 -0
- machineconfig/setup_linux/apps_gui.sh +64 -0
- machineconfig/setup_linux/ssh/openssh_all.sh +25 -0
- machineconfig/setup_linux/ssh/openssh_wsl.sh +38 -0
- machineconfig/setup_linux/uv.sh +15 -0
- machineconfig/setup_linux/web_shortcuts/interactive.sh +26 -6
- machineconfig/setup_linux/web_shortcuts/live_from_github.sh +31 -0
- machineconfig/setup_mac/__init__.py +16 -0
- machineconfig/setup_mac/apps_gui.sh +248 -0
- machineconfig/setup_mac/ssh/openssh_setup.sh +114 -0
- machineconfig/setup_mac/uv.sh +36 -0
- machineconfig/setup_windows/__init__.py +11 -0
- machineconfig/setup_windows/others/power_options.ps1 +7 -0
- machineconfig/setup_windows/ssh/add-sshkey.ps1 +29 -0
- machineconfig/setup_windows/ssh/add_identity.ps1 +11 -0
- machineconfig/setup_windows/ssh/openssh-server.ps1 +37 -0
- machineconfig/setup_windows/uv.ps1 +17 -0
- machineconfig/setup_windows/web_shortcuts/interactive.ps1 +27 -10
- machineconfig/setup_windows/web_shortcuts/live_from_github.ps1 +30 -0
- machineconfig/setup_windows/web_shortcuts/quick_init.ps1 +17 -0
- machineconfig/utils/accessories.py +7 -5
- machineconfig/utils/cloud/onedrive/README.md +139 -0
- machineconfig/utils/code.py +155 -105
- machineconfig/utils/files/art/fat_croco.txt +10 -0
- machineconfig/utils/files/art/halfwit_croco.txt +9 -0
- machineconfig/utils/files/art/happy_croco.txt +22 -0
- machineconfig/utils/files/art/water_croco.txt +11 -0
- machineconfig/utils/files/ascii_art.py +1 -1
- machineconfig/utils/files/dbms.py +257 -0
- machineconfig/utils/files/headers.py +11 -14
- machineconfig/utils/files/ouch/__init__.py +0 -0
- machineconfig/utils/files/ouch/decompress.py +45 -0
- machineconfig/utils/files/read.py +10 -18
- machineconfig/utils/installer_utils/github_release_bulk.py +156 -119
- machineconfig/utils/installer_utils/install_from_url.py +183 -0
- machineconfig/utils/installer_utils/installer_class.py +64 -181
- machineconfig/utils/installer_utils/installer_cli.py +175 -0
- machineconfig/utils/installer_utils/installer_helper.py +129 -0
- machineconfig/utils/installer_utils/{installer_abc.py → installer_locator_utils.py} +66 -97
- machineconfig/utils/{installer.py → installer_utils/installer_runner.py} +49 -82
- machineconfig/utils/io.py +77 -23
- machineconfig/utils/links.py +254 -162
- machineconfig/utils/meta.py +256 -0
- machineconfig/utils/notifications.py +1 -1
- machineconfig/utils/options.py +46 -18
- machineconfig/utils/options_tv.py +119 -0
- machineconfig/utils/path_extended.py +48 -101
- machineconfig/utils/path_helper.py +76 -23
- machineconfig/utils/procs.py +50 -70
- machineconfig/utils/scheduler.py +88 -124
- machineconfig/utils/scheduling.py +0 -3
- machineconfig/utils/schemas/fire_agents/fire_agents_input.py +1 -1
- machineconfig/utils/schemas/layouts/layout_types.py +1 -1
- machineconfig/utils/source_of_truth.py +3 -6
- machineconfig/utils/ssh.py +263 -274
- machineconfig/utils/ssh_utils/abc.py +5 -0
- machineconfig/utils/ssh_utils/copy_from_here.py +111 -0
- machineconfig/utils/ssh_utils/copy_to_here.py +302 -0
- machineconfig/utils/ssh_utils/utils.py +142 -0
- machineconfig/utils/ssh_utils/wsl.py +210 -0
- machineconfig/utils/terminal.py +3 -113
- machineconfig/utils/tst.py +20 -0
- machineconfig/utils/upgrade_packages.py +114 -28
- machineconfig/utils/ve.py +12 -4
- machineconfig-7.98.dist-info/METADATA +132 -0
- machineconfig-7.98.dist-info/RECORD +504 -0
- machineconfig-7.98.dist-info/entry_points.txt +13 -0
- machineconfig/cluster/sessions_managers/ffile.py +0 -4
- machineconfig/jobs/installer/linux_scripts/pgsql.sh +0 -49
- machineconfig/jobs/installer/linux_scripts/timescaledb.sh +0 -85
- machineconfig/jobs/linux/msc/cli_agents.sh +0 -16
- machineconfig/jobs/python/python_ve_symlink.py +0 -37
- machineconfig/jobs/python/vscode/api.py +0 -57
- machineconfig/jobs/python/vscode/sync_code.py +0 -73
- machineconfig/jobs/windows/archive/archive_pygraphviz.ps1 +0 -14
- machineconfig/jobs/windows/start_terminal.ps1 +0 -6
- machineconfig/jobs/windows/startup_file.cmd +0 -2
- machineconfig/profile/create.py +0 -303
- machineconfig/profile/shell.py +0 -176
- machineconfig/scripts/cloud/init.sh +0 -119
- machineconfig/scripts/linux/agents +0 -2
- machineconfig/scripts/linux/choose_wezterm_theme +0 -3
- machineconfig/scripts/linux/cloud_copy +0 -2
- machineconfig/scripts/linux/cloud_mount +0 -2
- machineconfig/scripts/linux/cloud_repo_sync +0 -2
- machineconfig/scripts/linux/cloud_sync +0 -2
- machineconfig/scripts/linux/croshell +0 -3
- machineconfig/scripts/linux/devops +0 -2
- machineconfig/scripts/linux/fire +0 -2
- machineconfig/scripts/linux/ftpx +0 -2
- machineconfig/scripts/linux/fzf2g +0 -21
- machineconfig/scripts/linux/fzfag +0 -17
- machineconfig/scripts/linux/fzffg +0 -25
- machineconfig/scripts/linux/fzfrga +0 -21
- machineconfig/scripts/linux/gh_models +0 -2
- machineconfig/scripts/linux/initai +0 -2
- machineconfig/scripts/linux/kill_process +0 -2
- machineconfig/scripts/linux/scheduler +0 -2
- machineconfig/scripts/linux/sessions +0 -2
- machineconfig/scripts/linux/share_smb +0 -1
- machineconfig/scripts/linux/skrg +0 -4
- machineconfig/scripts/linux/start_slidev +0 -2
- machineconfig/scripts/linux/start_terminals +0 -3
- machineconfig/scripts/linux/warp-cli.sh +0 -122
- machineconfig/scripts/linux/wifi_conn +0 -2
- machineconfig/scripts/linux/z_ls +0 -104
- machineconfig/scripts/python/ai/generate_files.py +0 -83
- machineconfig/scripts/python/ai/solutions/copilot/prompts/allLintersAndTypeCheckers.prompt.md +0 -5
- machineconfig/scripts/python/cloud_repo_sync.py +0 -190
- machineconfig/scripts/python/count_lines_frontend.py +0 -16
- machineconfig/scripts/python/devops_add_ssh_key.py +0 -120
- machineconfig/scripts/python/dotfile.py +0 -78
- machineconfig/scripts/python/fire_agents_help_launch.py +0 -120
- machineconfig/scripts/python/fire_agents_helper_types.py +0 -12
- machineconfig/scripts/python/fire_jobs_route_helper.py +0 -65
- machineconfig/scripts/python/get_zellij_cmd.py +0 -15
- machineconfig/scripts/python/gh_models.py +0 -104
- machineconfig/scripts/python/helpers/repo_sync_helpers.py +0 -116
- machineconfig/scripts/python/repos.py +0 -132
- machineconfig/scripts/python/repos_helper_action.py +0 -378
- machineconfig/scripts/python/snapshot.py +0 -25
- machineconfig/scripts/python/start_terminals.py +0 -121
- machineconfig/scripts/python/t4.py +0 -17
- machineconfig/scripts/windows/agents.ps1 +0 -1
- machineconfig/scripts/windows/choose_wezterm_theme.ps1 +0 -1
- machineconfig/scripts/windows/cloud_copy.ps1 +0 -1
- machineconfig/scripts/windows/cloud_mount.ps1 +0 -1
- machineconfig/scripts/windows/cloud_repo_sync.ps1 +0 -1
- machineconfig/scripts/windows/cloud_sync.ps1 +0 -1
- machineconfig/scripts/windows/croshell.ps1 +0 -1
- machineconfig/scripts/windows/devops.ps1 +0 -1
- machineconfig/scripts/windows/dotfile.ps1 +0 -1
- machineconfig/scripts/windows/fire.ps1 +0 -1
- machineconfig/scripts/windows/ftpx.ps1 +0 -1
- machineconfig/scripts/windows/fzfb.ps1 +0 -3
- machineconfig/scripts/windows/fzfg.ps1 +0 -2
- machineconfig/scripts/windows/fzfrga.bat +0 -20
- machineconfig/scripts/windows/gpt.ps1 +0 -1
- machineconfig/scripts/windows/grep.ps1 +0 -2
- machineconfig/scripts/windows/initai.ps1 +0 -1
- machineconfig/scripts/windows/kill_process.ps1 +0 -1
- machineconfig/scripts/windows/nano.ps1 +0 -3
- machineconfig/scripts/windows/pomodoro.ps1 +0 -1
- machineconfig/scripts/windows/reload_path.ps1 +0 -3
- machineconfig/scripts/windows/scheduler.ps1 +0 -1
- machineconfig/scripts/windows/sessions.ps1 +0 -1
- machineconfig/scripts/windows/snapshot.ps1 +0 -1
- machineconfig/scripts/windows/start_slidev.ps1 +0 -1
- machineconfig/scripts/windows/start_terminals.ps1 +0 -1
- machineconfig/scripts/windows/wifi_conn.ps1 +0 -2
- machineconfig/scripts/windows/wsl_rdp_windows_port_forwarding.ps1 +0 -46
- machineconfig/scripts/windows/wsl_ssh_windows_port_forwarding.ps1 +0 -76
- machineconfig/settings/lf/linux/exe/fzf_nano.sh +0 -16
- machineconfig/settings/lf/windows/fzf_edit.ps1 +0 -6
- machineconfig/settings/lf/windows/tst.ps1 +0 -1
- machineconfig/settings/yazi/yazi.toml +0 -4
- machineconfig/setup_linux/nix/cli_installation.sh +0 -157
- machineconfig/setup_linux/others/openssh-server_add_pub_key.sh +0 -57
- machineconfig/setup_linux/web_shortcuts/croshell.sh +0 -11
- machineconfig/setup_linux/web_shortcuts/ssh.sh +0 -52
- machineconfig/setup_windows/web_shortcuts/all.ps1 +0 -18
- machineconfig/setup_windows/web_shortcuts/ascii_art.ps1 +0 -36
- machineconfig/setup_windows/web_shortcuts/croshell.ps1 +0 -16
- machineconfig/setup_windows/web_shortcuts/ssh.ps1 +0 -11
- machineconfig/utils/ai/generate_file_checklist.py +0 -68
- machineconfig/utils/installer_utils/installer.py +0 -189
- machineconfig-5.15.dist-info/METADATA +0 -188
- machineconfig-5.15.dist-info/RECORD +0 -415
- machineconfig-5.15.dist-info/entry_points.txt +0 -18
- machineconfig/cluster/sessions_managers/{utils → helpers}/load_balancer_helper.py +0 -0
- machineconfig/scripts/linux/{share_nfs → other/share_nfs} +0 -0
- machineconfig/scripts/linux/{start_docker → other/start_docker} +0 -0
- machineconfig/scripts/linux/{switch_ip → other/switch_ip} +0 -0
- machineconfig/{jobs/python → scripts/python/ai/utils}/__init__.py +0 -0
- machineconfig/scripts/python/{helpers → helpers_agents}/__init__.py +0 -0
- machineconfig/{jobs/windows/msc/cli_agents.bat → scripts/python/helpers_agents/agentic_frameworks/__init__.py} +0 -0
- machineconfig/scripts/python/{fire_agents_help_search.py → helpers_agents/fire_agents_help_search.py} +0 -0
- machineconfig/scripts/python/{fire_agents_load_balancer.py → helpers_agents/fire_agents_load_balancer.py} +0 -0
- machineconfig/{jobs/windows/msc/cli_agents.ps1 → scripts/python/helpers_cloud/__init__.py} +0 -0
- machineconfig/scripts/python/{helpers → helpers_cloud}/cloud_helpers.py +1 -1
- /machineconfig/scripts/python/{helpers → helpers_cloud}/helpers5.py +0 -0
- /machineconfig/scripts/python/{fire_jobs_streamlit_helper.py → helpers_croshell/__init__.py} +0 -0
- /machineconfig/scripts/python/{pomodoro.py → helpers_croshell/pomodoro.py} +0 -0
- /machineconfig/scripts/python/{scheduler.py → helpers_croshell/scheduler.py} +0 -0
- /machineconfig/scripts/python/{viewer.py → helpers_croshell/viewer.py} +0 -0
- /machineconfig/scripts/python/{viewer_template.py → helpers_croshell/viewer_template.py} +0 -0
- /machineconfig/scripts/{windows/share_nfs.ps1 → python/helpers_devops/__init__.py} +0 -0
- /machineconfig/{settings/shells/pwsh/profile.ps1 → scripts/python/helpers_devops/themes/__init__.py} +0 -0
- /machineconfig/{settings/yazi/keymap.toml → scripts/python/helpers_devops/themes/choose_starship_theme.ps1} +0 -0
- /machineconfig/scripts/python/{cloud_manager.py → helpers_fire_command/cloud_manager.py} +0 -0
- /machineconfig/scripts/{linux → python/helpers_network}/mount_drive +0 -0
- /machineconfig/scripts/python/{mount_nw_drive.py → helpers_network/mount_nw_drive.py} +0 -0
- /machineconfig/scripts/{linux → python/helpers_network}/mount_smb +0 -0
- /machineconfig/scripts/windows/{mount_nw.ps1 → mounts/mount_nw.ps1} +0 -0
- /machineconfig/scripts/windows/{mount_smb.ps1 → mounts/mount_smb.ps1} +0 -0
- /machineconfig/scripts/windows/{share_cloud.cmd → mounts/share_cloud.cmd} +0 -0
- /machineconfig/scripts/windows/{unlock_bitlocker.ps1 → mounts/unlock_bitlocker.ps1} +0 -0
- /machineconfig/setup_linux/{web_shortcuts → others}/android.sh +0 -0
- /machineconfig/{jobs/windows/archive → setup_windows/ssh}/openssh-server_add_key.ps1 +0 -0
- /machineconfig/{jobs/windows/archive → setup_windows/ssh}/openssh-server_copy-ssh-id.ps1 +0 -0
- {machineconfig-5.15.dist-info → machineconfig-7.98.dist-info}/WHEEL +0 -0
- {machineconfig-5.15.dist-info → machineconfig-7.98.dist-info}/top_level.txt +0 -0
machineconfig/utils/procs.py
CHANGED
|
@@ -2,12 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
import psutil
|
|
4
4
|
from rich.progress import Progress, SpinnerColumn, TextColumn
|
|
5
|
-
from zoneinfo import ZoneInfo
|
|
6
5
|
from machineconfig.utils.options import choose_from_options
|
|
7
|
-
from typing import Optional,
|
|
6
|
+
from typing import Optional, TypedDict, List, Dict
|
|
8
7
|
from rich.console import Console
|
|
9
8
|
from rich.panel import Panel
|
|
10
|
-
from datetime import datetime
|
|
9
|
+
from datetime import datetime
|
|
11
10
|
from machineconfig.utils.accessories import pprint
|
|
12
11
|
|
|
13
12
|
console = Console()
|
|
@@ -15,11 +14,29 @@ console = Console()
|
|
|
15
14
|
BOX_WIDTH = 78 # width for box drawing
|
|
16
15
|
|
|
17
16
|
|
|
18
|
-
|
|
17
|
+
class ProcessInfo(TypedDict):
|
|
18
|
+
"""TypedDict for process information."""
|
|
19
|
+
command: str
|
|
20
|
+
pid: int
|
|
21
|
+
name: str
|
|
22
|
+
username: str
|
|
23
|
+
cpu_percent: float
|
|
24
|
+
memory_usage_mb: float
|
|
25
|
+
status: str
|
|
26
|
+
create_time: datetime
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class FileAccessInfo(TypedDict):
|
|
30
|
+
"""TypedDict for file access information."""
|
|
31
|
+
pid: int
|
|
32
|
+
files: List[str]
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def get_processes_accessing_file(path: str) -> List[FileAccessInfo]:
|
|
19
36
|
# header for searching processes
|
|
20
37
|
title = "🔍 SEARCHING FOR PROCESSES ACCESSING FILE"
|
|
21
38
|
console.print(Panel(title, title="[bold blue]Process Info[/bold blue]", border_style="blue"))
|
|
22
|
-
res:
|
|
39
|
+
res: Dict[int, List[str]] = {}
|
|
23
40
|
|
|
24
41
|
with Progress(SpinnerColumn(), TextColumn("[progress.description]{task.description}")) as progress:
|
|
25
42
|
progress.add_task("🔎 Scanning processes...", total=None)
|
|
@@ -34,22 +51,22 @@ def get_processes_accessing_file(path: str):
|
|
|
34
51
|
res[proc.pid] = tmp
|
|
35
52
|
|
|
36
53
|
# Convert to list of dictionaries for consistent data structure
|
|
37
|
-
result_data = [{"pid": pid, "files": files} for pid, files in res.items()]
|
|
54
|
+
result_data: List[FileAccessInfo] = [{"pid": pid, "files": files} for pid, files in res.items()]
|
|
38
55
|
console.print(Panel(f"✅ Found {len(res)} processes accessing the specified file", title="[bold blue]Process Info[/bold blue]", border_style="blue"))
|
|
39
56
|
return result_data
|
|
40
57
|
|
|
41
58
|
|
|
42
59
|
def kill_process(name: str):
|
|
43
|
-
print(f"⚠️ Attempting to kill process: {name}...")
|
|
60
|
+
console.print(f"⚠️ Attempting to kill process: {name}...", style="yellow")
|
|
44
61
|
killed = False
|
|
45
62
|
for proc in psutil.process_iter():
|
|
46
63
|
if proc.name() == name:
|
|
47
64
|
proc.kill()
|
|
48
|
-
print(f"💀 Process {name} (PID: {proc.pid}) terminated successfully")
|
|
65
|
+
console.print(f"💀 Process {name} (PID: {proc.pid}) terminated successfully", style="green")
|
|
49
66
|
killed = True
|
|
50
67
|
if not killed:
|
|
51
|
-
print(f"❓ No process with name '{name}' was found")
|
|
52
|
-
|
|
68
|
+
console.print(f"❓ No process with name '{name}' was found", style="red")
|
|
69
|
+
console.rule(style="dim")
|
|
53
70
|
|
|
54
71
|
|
|
55
72
|
class ProcessManager:
|
|
@@ -57,15 +74,13 @@ class ProcessManager:
|
|
|
57
74
|
# header for initializing process manager
|
|
58
75
|
title = "📊 INITIALIZING PROCESS MANAGER"
|
|
59
76
|
console.print(Panel(title, title="[bold blue]Process Info[/bold blue]", border_style="blue"))
|
|
60
|
-
process_info = []
|
|
77
|
+
process_info: List[ProcessInfo] = []
|
|
61
78
|
with Progress(SpinnerColumn(), TextColumn("[progress.description]{task.description}")) as progress:
|
|
62
79
|
progress.add_task("🔍 Reading system processes...", total=None)
|
|
63
80
|
for proc in psutil.process_iter():
|
|
64
81
|
try:
|
|
65
82
|
mem_usage_mb = proc.memory_info().rss / (1024 * 1024)
|
|
66
|
-
|
|
67
|
-
create_time_utc = datetime.fromtimestamp(proc.create_time(), tz=timezone.utc)
|
|
68
|
-
create_time_local = create_time_utc.astimezone(ZoneInfo("Australia/Adelaide"))
|
|
83
|
+
create_time = datetime.fromtimestamp(proc.create_time(), tz=None)
|
|
69
84
|
|
|
70
85
|
process_info.append(
|
|
71
86
|
{
|
|
@@ -75,7 +90,7 @@ class ProcessManager:
|
|
|
75
90
|
"cpu_percent": proc.cpu_percent(),
|
|
76
91
|
"memory_usage_mb": mem_usage_mb,
|
|
77
92
|
"status": proc.status(),
|
|
78
|
-
"create_time":
|
|
93
|
+
"create_time": create_time,
|
|
79
94
|
"command": " ".join(proc.cmdline()),
|
|
80
95
|
}
|
|
81
96
|
)
|
|
@@ -91,57 +106,51 @@ class ProcessManager:
|
|
|
91
106
|
"""Format process data as table string for display."""
|
|
92
107
|
if not self.data:
|
|
93
108
|
return ""
|
|
94
|
-
|
|
95
109
|
# Create header
|
|
96
|
-
_headers = ["PID", "Name", "Username", "CPU%", "Memory(MB)", "Status", "Create Time"
|
|
97
|
-
header_line = f"{'PID':<8} {'Name':<20} {'Username':<12} {'CPU%':<8} {'Memory(MB)':<12} {'Status':<12} {'Create Time':<20}
|
|
110
|
+
_headers = ["Command", "PID", "Name", "Username", "CPU%", "Memory(MB)", "Status", "Create Time"]
|
|
111
|
+
header_line = f"{'Command':<50} {'PID':<8} {'Name':<20} {'Username':<12} {'CPU%':<8} {'Memory(MB)':<12} {'Status':<12} {'Create Time':<20}"
|
|
98
112
|
separator = "-" * len(header_line)
|
|
99
|
-
|
|
100
113
|
lines = [header_line, separator]
|
|
101
|
-
|
|
102
114
|
for process in self.data:
|
|
103
115
|
# Format create_time as string
|
|
104
116
|
create_time_str = process["create_time"].strftime("%Y-%m-%d %H:%M:%S")
|
|
105
117
|
# Truncate command if too long
|
|
106
118
|
command = process["command"][:47] + "..." if len(process["command"]) > 50 else process["command"]
|
|
107
|
-
|
|
108
|
-
line = f"{process['pid']:<8} {process['name'][:19]:<20} {process['username'][:11]:<12} {process['cpu_percent']:<8.1f} {process['memory_usage_mb']:<12.2f} {process['status'][:11]:<12} {create_time_str:<20} {command:<50}"
|
|
119
|
+
line = f"{command:<50} {process['pid']:<8} {process['name'][:19]:<20} {process['username'][:11]:<12} {process['cpu_percent']:<8.1f} {process['memory_usage_mb']:<12.2f} {process['status'][:11]:<12} {create_time_str:<20}"
|
|
109
120
|
lines.append(line)
|
|
110
|
-
|
|
111
121
|
return "\n".join(lines)
|
|
112
122
|
|
|
113
123
|
def choose_and_kill(self):
|
|
114
124
|
# header for interactive process selection
|
|
115
125
|
title = "🎯 INTERACTIVE PROCESS SELECTION AND TERMINATION"
|
|
116
126
|
console.print(Panel(title, title="[bold blue]Process Info[/bold blue]", border_style="blue"))
|
|
117
|
-
|
|
118
127
|
# Format data as table for display
|
|
119
128
|
formatted_data = self._format_process_table()
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
129
|
+
all_lines = formatted_data.split("\n")
|
|
130
|
+
header_and_separator = all_lines[:2] # First two lines: header and separator
|
|
131
|
+
options = all_lines[2:] # Skip header and separator, only process lines
|
|
132
|
+
res = choose_from_options(options=all_lines, msg="📋 Select processes to manage:", tv=True, multi=True)
|
|
133
|
+
# Filter out header and separator if they were selected
|
|
134
|
+
selected_lines = [line for line in res if line not in header_and_separator]
|
|
135
|
+
indices = [options.index(val) for val in selected_lines]
|
|
123
136
|
selected_processes = [self.data[i] for i in indices]
|
|
124
|
-
|
|
125
137
|
print("\n📊 All Processes:")
|
|
126
138
|
print(formatted_data)
|
|
127
139
|
print("\n🎯 Selected Processes:")
|
|
128
140
|
for process in selected_processes:
|
|
129
141
|
print(f"PID: {process['pid']}, Name: {process['name']}, Memory: {process['memory_usage_mb']:.2f}MB")
|
|
130
|
-
|
|
131
142
|
for idx, process in enumerate(selected_processes):
|
|
132
|
-
pprint(process, f"📌 Process {idx}")
|
|
133
|
-
|
|
143
|
+
pprint(dict(process), f"📌 Process {idx}")
|
|
134
144
|
kill_all = input("\n⚠️ Confirm killing ALL selected processes? y/[n] ").lower() == "y"
|
|
135
145
|
if kill_all:
|
|
136
146
|
self.kill(pids=[p["pid"] for p in selected_processes])
|
|
137
147
|
return
|
|
138
|
-
|
|
139
148
|
kill_by_index = input("\n🔫 Kill by index? (enter numbers separated by spaces, e.g. '1 4') or [n] to cancel: ")
|
|
140
149
|
if kill_by_index != "" and kill_by_index != "n":
|
|
141
150
|
indices = [int(val) for val in kill_by_index.split(" ")]
|
|
142
151
|
target_processes = [selected_processes[i] for i in indices]
|
|
143
152
|
for idx2, process in enumerate(target_processes):
|
|
144
|
-
pprint(process, f"🎯 Target Process {idx2}")
|
|
153
|
+
pprint(dict(process), f"🎯 Target Process {idx2}")
|
|
145
154
|
_ = self.kill(pids=[p["pid"] for p in target_processes]) if input("\n⚠️ Confirm termination? y/[n] ").lower() == "y" else None
|
|
146
155
|
console.print(Panel("🔔 No processes were terminated.", title="[bold blue]Process Info[/bold blue]", border_style="blue"))
|
|
147
156
|
|
|
@@ -149,12 +158,10 @@ class ProcessManager:
|
|
|
149
158
|
# header for filtering processes by name
|
|
150
159
|
title = "🔍 FILTERING AND TERMINATING PROCESSES BY NAME"
|
|
151
160
|
console.print(Panel(title, title="[bold blue]Process Info[/bold blue]", border_style="blue"))
|
|
152
|
-
|
|
153
161
|
# Filter processes by name
|
|
154
162
|
filtered_processes = [p for p in self.data if p["name"] == name]
|
|
155
163
|
# Sort by create_time (ascending)
|
|
156
164
|
filtered_processes.sort(key=lambda x: x["create_time"])
|
|
157
|
-
|
|
158
165
|
print(f"🎯 Found {len(filtered_processes)} processes matching name: '{name}'")
|
|
159
166
|
self.kill(pids=[p["pid"] for p in filtered_processes])
|
|
160
167
|
console.print(Panel("", title="[bold blue]Process Info[/bold blue]", border_style="blue"))
|
|
@@ -171,69 +178,42 @@ class ProcessManager:
|
|
|
171
178
|
pids = []
|
|
172
179
|
if commands is None:
|
|
173
180
|
commands = []
|
|
174
|
-
|
|
175
181
|
killed_count = 0
|
|
176
|
-
|
|
177
182
|
for name in names:
|
|
178
183
|
matching_processes = [p for p in self.data if p["name"] == name]
|
|
179
184
|
if len(matching_processes) > 0:
|
|
180
185
|
for process in matching_processes:
|
|
181
186
|
psutil.Process(process["pid"]).kill()
|
|
182
|
-
print(f"💀 Killed process {name} with PID {process['pid']}. It lived {get_age(process['create_time'])}. RIP
|
|
187
|
+
print(f"💀 Killed process {name} with PID {process['pid']}. It lived {get_age(process['create_time'])}. RIP 💐")
|
|
183
188
|
killed_count += 1
|
|
184
189
|
else:
|
|
185
190
|
print(f'❓ No process named "{name}" found')
|
|
186
|
-
|
|
187
191
|
for pid in pids:
|
|
188
192
|
try:
|
|
189
193
|
proc = psutil.Process(pid)
|
|
190
194
|
proc_name = proc.name()
|
|
191
|
-
proc_lifetime = get_age(proc.create_time())
|
|
195
|
+
proc_lifetime = get_age(datetime.fromtimestamp(proc.create_time(), tz=None))
|
|
192
196
|
proc.kill()
|
|
193
|
-
print(f'💀 Killed process with PID {pid} and name "{proc_name}". It lived {proc_lifetime}. RIP
|
|
197
|
+
print(f'💀 Killed process with PID {pid} and name "{proc_name}". It lived {proc_lifetime}. RIP 💐')
|
|
194
198
|
killed_count += 1
|
|
195
199
|
except psutil.NoSuchProcess:
|
|
196
200
|
print(f"❓ No process with PID {pid} found")
|
|
197
|
-
|
|
198
201
|
for command in commands:
|
|
199
202
|
matching_processes = [p for p in self.data if command in p["command"]]
|
|
200
203
|
if len(matching_processes) > 0:
|
|
201
204
|
for process in matching_processes:
|
|
202
205
|
psutil.Process(process["pid"]).kill()
|
|
203
|
-
print(f'💀 Killed process with "{command}" in its command & PID {process["pid"]}. It lived {get_age(process["create_time"])}. RIP
|
|
206
|
+
print(f'💀 Killed process with "{command}" in its command & PID {process["pid"]}. It lived {get_age(process["create_time"])}. RIP 💐')
|
|
204
207
|
killed_count += 1
|
|
205
208
|
else:
|
|
206
209
|
print(f'❓ No process has "{command}" in its command.')
|
|
207
|
-
|
|
208
210
|
console.print(Panel(f"✅ Termination complete: {killed_count} processes terminated", title="[bold blue]Process Info[/bold blue]", border_style="blue"))
|
|
209
211
|
|
|
210
212
|
|
|
211
|
-
def get_age(create_time:
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
# Handle timestampz
|
|
216
|
-
create_time_utc = datetime.fromtimestamp(create_time, tz=timezone.utc)
|
|
217
|
-
create_time_local = create_time_utc.astimezone(ZoneInfo("Australia/Adelaide"))
|
|
218
|
-
else:
|
|
219
|
-
# Already a datetime object
|
|
220
|
-
create_time_local = create_time
|
|
221
|
-
|
|
222
|
-
now_local = datetime.now(tz=ZoneInfo("Australia/Adelaide"))
|
|
223
|
-
age = now_local - create_time_local
|
|
224
|
-
return str(age)
|
|
225
|
-
except Exception as e:
|
|
226
|
-
try:
|
|
227
|
-
# Fallback without timezone
|
|
228
|
-
if isinstance(create_time, (int, float)):
|
|
229
|
-
create_time_dt = datetime.fromtimestamp(create_time)
|
|
230
|
-
else:
|
|
231
|
-
create_time_dt = create_time.replace(tzinfo=None) if create_time.tzinfo else create_time
|
|
232
|
-
now_dt = datetime.now()
|
|
233
|
-
age = now_dt - create_time_dt
|
|
234
|
-
return str(age)
|
|
235
|
-
except Exception as ee:
|
|
236
|
-
return f"unknown due to {ee} and {e}"
|
|
213
|
+
def get_age(create_time: datetime) -> str:
|
|
214
|
+
dtm_now = datetime.now()
|
|
215
|
+
delta = dtm_now - create_time
|
|
216
|
+
return str(delta).split(".")[0] # remove microseconds
|
|
237
217
|
|
|
238
218
|
|
|
239
219
|
def main():
|
machineconfig/utils/scheduler.py
CHANGED
|
@@ -1,31 +1,26 @@
|
|
|
1
|
+
|
|
1
2
|
from pathlib import Path
|
|
2
|
-
from typing import Callable, Optional, Union, Any,
|
|
3
|
-
import logging
|
|
3
|
+
from typing import Callable, Optional, Union, Any, Protocol, List, TypeVar
|
|
4
|
+
# import logging
|
|
4
5
|
import time
|
|
5
6
|
from datetime import datetime, timezone, timedelta
|
|
6
7
|
from machineconfig.utils.io import from_pickle
|
|
7
|
-
from machineconfig.utils.path_extended import PathExtended
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
class LoggerTemplate(Protocol):
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
def
|
|
11
|
+
def trace(self, __message: str, *args: Any, **kwargs: Any) -> None:
|
|
12
|
+
pass # 5
|
|
13
|
+
def success(self, __message: str, *args: Any, **kwargs: Any) -> None:
|
|
14
|
+
pass # 25
|
|
15
|
+
def debug(self, __message: str, *args: Any, **kwargs: Any) -> None:
|
|
14
16
|
pass # 10
|
|
15
|
-
|
|
16
|
-
def info(self, msg: str) -> None:
|
|
17
|
+
def info(self, __message: str, *args: Any, **kwargs: Any) -> None:
|
|
17
18
|
pass # 20
|
|
18
|
-
|
|
19
|
-
def warning(self, msg: str) -> None:
|
|
19
|
+
def warning(self, __message: str, *args: Any, **kwargs: Any) -> None:
|
|
20
20
|
pass # 30
|
|
21
|
-
|
|
22
|
-
def error(self, msg: str) -> None:
|
|
21
|
+
def error(self, __message: str, *args: Any, **kwargs: Any) -> None:
|
|
23
22
|
pass # 40
|
|
24
|
-
|
|
25
|
-
def critical(self, msg: str) -> None:
|
|
26
|
-
pass # 50
|
|
27
|
-
|
|
28
|
-
def fatal(self, msg: str) -> None:
|
|
23
|
+
def critical(self, __message: str, *args: Any, **kwargs: Any) -> None:
|
|
29
24
|
pass # 50
|
|
30
25
|
|
|
31
26
|
|
|
@@ -139,149 +134,118 @@ class Scheduler:
|
|
|
139
134
|
def default_exception_handler(self, ex: Union[Exception, KeyboardInterrupt], during: str, sched: "Scheduler") -> None: # user decides on handling and continue, terminate, save checkpoint, etc. # Use signal library.
|
|
140
135
|
print(sched)
|
|
141
136
|
self.record_session_end(reason=f"during {during}, " + str(ex))
|
|
142
|
-
self.logger.
|
|
137
|
+
self.logger.critical(str(ex))
|
|
143
138
|
raise ex
|
|
144
139
|
|
|
145
140
|
|
|
146
|
-
T = TypeVar("T")
|
|
141
|
+
# T = TypeVar("T")
|
|
147
142
|
T2 = TypeVar("T2")
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
class PrintFunc(Protocol):
|
|
151
|
-
def __call__(self, msg: str) -> Union[NoReturn, None]: ...
|
|
152
|
-
|
|
153
|
-
|
|
154
143
|
def to_pickle(obj: Any, path: Path) -> None:
|
|
155
144
|
import pickle
|
|
156
|
-
|
|
157
|
-
path.parent.mkdir(parents=True, exist_ok=True)
|
|
158
145
|
path.write_bytes(pickle.dumps(obj))
|
|
159
146
|
|
|
160
147
|
|
|
161
|
-
class
|
|
162
|
-
|
|
148
|
+
class CacheMemory[T]():
|
|
149
|
+
def __init__(
|
|
150
|
+
self, source_func: Callable[[], T], expire: timedelta, logger: LoggerTemplate, name: Optional[str] = None
|
|
151
|
+
) -> None:
|
|
152
|
+
self.cache: T
|
|
153
|
+
self.source_func = source_func
|
|
154
|
+
self.time_produced = datetime.now()
|
|
155
|
+
self.logger = logger
|
|
156
|
+
self.expire = expire
|
|
157
|
+
self.name = name if isinstance(name, str) else self.source_func.__name__
|
|
158
|
+
def __call__(self, fresh: bool, tolerance_seconds: float | int) -> T:
|
|
159
|
+
if fresh or not hasattr(self, "cache"):
|
|
160
|
+
why = "There was an explicit fresh order." if fresh else "Previous cache never existed."
|
|
161
|
+
t0 = time.time()
|
|
162
|
+
self.logger.warning(f"""🆕 NEW CACHE 🔄 {self.name} CACHE ℹ️ Reason: {why}""")
|
|
163
|
+
self.cache = self.source_func()
|
|
164
|
+
self.logger.warning(f"⏱️ Cache population took {time.time() - t0:.2f} seconds.")
|
|
165
|
+
self.time_produced = datetime.now()
|
|
166
|
+
else:
|
|
167
|
+
age = datetime.now() - self.time_produced
|
|
168
|
+
if (age > self.expire) or (fresh and (age.total_seconds() > tolerance_seconds)):
|
|
169
|
+
self.logger.warning(f"""🔄 CACHE UPDATE ⚠️ {self.name} cache: Updating cache from source func. """ + f""" ⏱️ Age = {age} > {self.expire}""" if not fresh else f""" ⏱️ Age = {age}. Fresh flag raised.""")
|
|
170
|
+
t0 = time.time()
|
|
171
|
+
self.cache = self.source_func()
|
|
172
|
+
self.logger.warning(f"⏱️ Cache population took {time.time() - t0:.2f} seconds.")
|
|
173
|
+
self.time_produced = datetime.now()
|
|
174
|
+
else:
|
|
175
|
+
self.logger.warning(f"""✅ USING CACHE 📦 {self.name} cache: Using cached values ⏱️ Lag = {age} < {self.expire} < {tolerance_seconds} seconds.""")
|
|
176
|
+
return self.cache
|
|
177
|
+
|
|
178
|
+
@staticmethod
|
|
179
|
+
def as_decorator(expire: timedelta, logger: LoggerTemplate, name: Optional[str] = None):
|
|
180
|
+
def decorator(source_func: Callable[[], T2]) -> CacheMemory["T2"]:
|
|
181
|
+
res = CacheMemory(source_func=source_func, expire=expire, logger=logger, name=name)
|
|
182
|
+
return res
|
|
183
|
+
return decorator
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
class Cache[T](): # This class helps to accelrate access to latest data coming from expensive function. The class has two flavours, memory-based and disk-based variants."""
|
|
163
187
|
def __init__(
|
|
164
|
-
self, source_func: Callable[[], T], expire: timedelta, logger:
|
|
188
|
+
self, source_func: Callable[[], T], expire: timedelta, logger: LoggerTemplate, path: Path, saver: Callable[[T, Path], Any] = to_pickle, reader: Callable[[Path], T] = from_pickle, name: Optional[str] = None
|
|
165
189
|
) -> None:
|
|
166
190
|
self.cache: T
|
|
167
191
|
self.source_func = source_func # function which when called returns a fresh object to be frozen.
|
|
168
|
-
self.path:
|
|
192
|
+
self.path: Path = path
|
|
193
|
+
_ = self.path.parent.mkdir(parents=True, exist_ok=True)
|
|
169
194
|
self.time_produced = datetime.now() # if path is None else
|
|
170
195
|
self.save = saver
|
|
171
196
|
self.reader = reader
|
|
172
197
|
self.logger = logger
|
|
173
198
|
self.expire = expire
|
|
174
|
-
self.name = name if isinstance(name, str) else
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
def age(self):
|
|
179
|
-
"""Throws AttributeError if called before cache is populated and path doesn't exists"""
|
|
180
|
-
if self.path is None: # memory-based cache.
|
|
181
|
-
return datetime.now() - self.time_produced
|
|
182
|
-
return datetime.now() - datetime.fromtimestamp(self.path.stat().st_mtime)
|
|
183
|
-
|
|
184
|
-
# def __setstate__(self, state: dict[str, Any]) -> None:
|
|
185
|
-
# self.__dict__.update(state)
|
|
186
|
-
# self.path = P.home() / self.path if self.path is not None else self.path
|
|
187
|
-
# def __getstate__(self) -> dict[str, Any]:
|
|
188
|
-
# state = self.__dict__.copy()
|
|
189
|
-
# state["path"] = self.path.rel2home() if self.path is not None else state["path"]
|
|
190
|
-
# return state # With this implementation, instances can be pickled and loaded up in different machine and still works.
|
|
191
|
-
def __call__(self, fresh: bool = False) -> T:
|
|
192
|
-
self.last_call_is_fresh = False
|
|
193
|
-
if fresh or not hasattr(self, "cache"): # populate cache for the first time
|
|
194
|
-
if not fresh and self.path is not None and self.path.exists():
|
|
199
|
+
self.name = name if isinstance(name, str) else self.source_func.__name__
|
|
200
|
+
def __call__(self, fresh: bool, tolerance_seconds: float | int) -> T:
|
|
201
|
+
if not hasattr(self, "cache"): # populate cache for the first time: we have two options, populate from disk or from source func.
|
|
202
|
+
if self.path.exists(): # prefer to read from disk over source func as a default source of cache.
|
|
195
203
|
age = datetime.now() - datetime.fromtimestamp(self.path.stat().st_mtime)
|
|
196
|
-
|
|
197
|
-
📦
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
204
|
+
if (age > self.expire) or (fresh and (age.total_seconds() > tolerance_seconds)): # cache is old or if fresh flag is raised
|
|
205
|
+
self.logger.warning(f"""🔄 CACHE STALE 📦 {self.name} cache: Populating fresh cache from source func. """ + f"""⏱️ Age = {age} > Expiry {self.expire} """ if not fresh else """⚠️ Fresh flag raised.""")
|
|
206
|
+
t0 = time.time()
|
|
207
|
+
self.cache = self.source_func() # fresh data.
|
|
208
|
+
self.logger.warning(f"⏱️ Cache population took {time.time() - t0:.2f} seconds.")
|
|
209
|
+
self.time_produced = datetime.now()
|
|
210
|
+
self.save(self.cache, self.path)
|
|
211
|
+
return self.cache
|
|
212
|
+
msg1 = f"""📦 CACHE OPERATION 🔄 {self.name} cache: Reading cached values from `{self.path}` ⏱️ Lag = {age}"""
|
|
202
213
|
try:
|
|
203
214
|
self.cache = self.reader(self.path)
|
|
204
215
|
except Exception as ex:
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
⚠️ {self.name} cache: Cache file is corrupted
|
|
209
|
-
🔍 Error: {ex}
|
|
210
|
-
════════════════════════════════════════════════════════
|
|
211
|
-
"""
|
|
212
|
-
self.logger(msg1 + msg2)
|
|
216
|
+
msg2 = f"""❌ CACHE ERROR ⚠️ {self.name} cache: Cache file is corrupted 🔍 Error: {ex}"""
|
|
217
|
+
self.logger.warning(msg1 + msg2)
|
|
218
|
+
t0 = time.time()
|
|
213
219
|
self.cache = self.source_func()
|
|
214
|
-
self.
|
|
220
|
+
self.logger.warning(f"⏱️ Cache population took {time.time() - t0:.2f} seconds.")
|
|
215
221
|
self.time_produced = datetime.now()
|
|
216
|
-
|
|
217
|
-
# self.save(self.cache, self.path)
|
|
222
|
+
self.save(self.cache, self.path)
|
|
218
223
|
return self.cache
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
# Previous cache never existed or there was an explicit fresh order.
|
|
223
|
-
why = "There was an explicit fresh order." if fresh else "Previous cache never existed or is corrupted."
|
|
224
|
-
self.logger(f"""
|
|
225
|
-
🆕 ════════════════════ NEW CACHE ════════════════════
|
|
226
|
-
🔄 {self.name} cache: Populating fresh cache from source func
|
|
227
|
-
ℹ️ Reason: {why}
|
|
228
|
-
════════════════════════════════════════════════════════
|
|
229
|
-
""")
|
|
224
|
+
else: # disk cache does not exist, populate from source func.
|
|
225
|
+
self.logger.warning(f"""🆕 NEW CACHE 🔄 {self.name} cache: Populating fresh cache from source func ℹ️ Reason: Previous cache never existed.""")
|
|
226
|
+
t0 = time.time()
|
|
230
227
|
self.cache = self.source_func() # fresh data.
|
|
231
|
-
self.
|
|
228
|
+
self.logger.warning(f"⏱️ Cache population took {time.time() - t0:.2f} seconds.")
|
|
232
229
|
self.time_produced = datetime.now()
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
return self(fresh=True)
|
|
240
|
-
if age > self.expire:
|
|
241
|
-
if self.logger:
|
|
242
|
-
self.logger(f"""
|
|
243
|
-
🔄 ════════════════════ CACHE UPDATE ════════════════════
|
|
244
|
-
⚠️ {self.name} cache: Updating cache from source func
|
|
245
|
-
⏱️ Age = {age} > {self.expire}
|
|
246
|
-
════════════════════════════════════════════════════════""")
|
|
230
|
+
self.save(self.cache, self.path)
|
|
231
|
+
else: # memory cache exists
|
|
232
|
+
age = datetime.now() - self.time_produced
|
|
233
|
+
if (age > self.expire) or (fresh and (age.total_seconds() > tolerance_seconds)): # cache is old or if fresh flag is raised
|
|
234
|
+
self.logger.warning(f"""🔄 CACHE UPDATE ⚠️ {self.name} cache: Updating cache from source func. ⏱️ Age = {age} > {self.expire}""")
|
|
235
|
+
t0 = time.time()
|
|
247
236
|
self.cache = self.source_func()
|
|
248
|
-
self.
|
|
237
|
+
self.logger.warning(f"⏱️ Cache population took {time.time() - t0:.2f} seconds.")
|
|
249
238
|
self.time_produced = datetime.now()
|
|
250
|
-
|
|
251
|
-
self.save(self.cache, self.path)
|
|
239
|
+
self.save(self.cache, self.path)
|
|
252
240
|
else:
|
|
253
|
-
|
|
254
|
-
self.logger(f"""
|
|
255
|
-
✅ ════════════════════ USING CACHE ════════════════════
|
|
256
|
-
📦 {self.name} cache: Using cached values
|
|
257
|
-
⏱️ Lag = {age}
|
|
258
|
-
════════════════════════════════════════════════════════""")
|
|
241
|
+
self.logger.warning(f"""✅ USING CACHE 📦 {self.name} cache: Using cached values ⏱️ Lag = {age} < {self.expire} < {tolerance_seconds} seconds.""")
|
|
259
242
|
return self.cache
|
|
260
243
|
|
|
261
244
|
@staticmethod
|
|
262
245
|
def as_decorator(
|
|
263
|
-
expire: timedelta, logger:
|
|
246
|
+
expire: timedelta, logger: LoggerTemplate, path: Path, saver: Callable[[T2, Path], Any] = to_pickle, reader: Callable[[Path], T2] = from_pickle, name: Optional[str] = None
|
|
264
247
|
): # -> Callable[..., 'Cache[T2]']:
|
|
265
248
|
def decorator(source_func: Callable[[], T2]) -> Cache["T2"]:
|
|
266
249
|
res = Cache(source_func=source_func, expire=expire, logger=logger, path=path, name=name, reader=reader, saver=saver)
|
|
267
250
|
return res
|
|
268
|
-
|
|
269
251
|
return decorator
|
|
270
|
-
|
|
271
|
-
def from_cloud(self, cloud: str, rel2home: bool = True, root: Optional[str] = None):
|
|
272
|
-
assert self.path is not None
|
|
273
|
-
exists = self.path.exists()
|
|
274
|
-
exists_but_old = exists and ((datetime.now() - datetime.fromtimestamp(self.path.stat().st_mtime)) > self.expire)
|
|
275
|
-
if not exists or exists_but_old:
|
|
276
|
-
returned_path = self.path.from_cloud(cloud=cloud, rel2home=rel2home, root=root)
|
|
277
|
-
if returned_path is None and not exists:
|
|
278
|
-
raise FileNotFoundError(f"❌ Failed to get @ {self.path}. Build the cache first with signed API.")
|
|
279
|
-
elif returned_path is None and exists and self.logger is not None:
|
|
280
|
-
self.logger(f"""
|
|
281
|
-
⚠️ ════════════════════ CLOUD FETCH WARNING ════════════════════
|
|
282
|
-
🔄 Failed to get fresh data from cloud
|
|
283
|
-
📦 Using old cache @ {self.path}
|
|
284
|
-
════════════════════════════════════════════════════════════════""")
|
|
285
|
-
else:
|
|
286
|
-
pass # maybe we don't need to fetch it from cloud, if its too hot
|
|
287
|
-
return self.reader(self.path)
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
# """Task scheduler
|
|
2
2
|
# """
|
|
3
3
|
|
|
4
|
-
# from machineconfig.utils.utils import get_shell_script_executing_python_file
|
|
5
4
|
# from machineconfig.utils.utils2 import read_ini
|
|
6
5
|
# from dataclasses import dataclass
|
|
7
6
|
# from datetime import datetime, timedelta
|
|
@@ -140,8 +139,6 @@
|
|
|
140
139
|
# start: datetime
|
|
141
140
|
# end: datetime
|
|
142
141
|
# status: str
|
|
143
|
-
|
|
144
|
-
# @classmethod
|
|
145
142
|
# def from_path(cls, path: PathExtended, return_default_if_not_found: bool=False):
|
|
146
143
|
# if not path.exists():
|
|
147
144
|
# if return_default_if_not_found:
|
|
@@ -6,7 +6,7 @@ capturing all user inputs collected during interactive execution.
|
|
|
6
6
|
|
|
7
7
|
from pathlib import Path
|
|
8
8
|
from typing import TypedDict, Literal, NotRequired
|
|
9
|
-
from machineconfig.scripts.python.fire_agents_help_launch import AGENTS
|
|
9
|
+
from machineconfig.scripts.python.helpers_agents.fire_agents_help_launch import AGENTS
|
|
10
10
|
|
|
11
11
|
SEARCH_STRATEGIES = Literal["file_path", "keyword_search", "filename_pattern"]
|
|
12
12
|
|
|
@@ -5,19 +5,16 @@ Utils
|
|
|
5
5
|
import machineconfig
|
|
6
6
|
from pathlib import Path
|
|
7
7
|
|
|
8
|
-
EXCLUDE_DIRS = [".links", ".ai", ".
|
|
9
|
-
|
|
8
|
+
EXCLUDE_DIRS = [".links", ".ai", ".venv", ".git", ".idea", ".vscode", "node_modules", "__pycache__", ".mypy_cache"]
|
|
10
9
|
LIBRARY_ROOT = Path(machineconfig.__file__).resolve().parent
|
|
11
|
-
REPO_ROOT = LIBRARY_ROOT.parent.parent
|
|
12
10
|
|
|
13
|
-
|
|
11
|
+
CONFIG_ROOT = Path.home().joinpath(".config/machineconfig")
|
|
14
12
|
DEFAULTS_PATH = Path.home().joinpath("dotfiles/machineconfig/defaults.ini")
|
|
15
13
|
|
|
16
|
-
INSTALL_VERSION_ROOT =
|
|
14
|
+
INSTALL_VERSION_ROOT = CONFIG_ROOT.joinpath("cli_tools_installers/versions")
|
|
17
15
|
INSTALL_TMP_DIR = Path.home().joinpath("tmp_results", "tmp_installers")
|
|
18
16
|
|
|
19
17
|
# LINUX_INSTALL_PATH = '/usr/local/bin'
|
|
20
|
-
# LINUX_INSTALL_PATH = '~/.local/bin'
|
|
21
18
|
LINUX_INSTALL_PATH = Path.home().joinpath(".local/bin").__str__()
|
|
22
19
|
WINDOWS_INSTALL_PATH = Path.home().joinpath("AppData/Local/Microsoft/WindowsApps").__str__()
|
|
23
20
|
|