machineconfig 7.98__py3-none-any.whl → 8.51__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/cluster/remote/run_cluster.py +1 -1
- machineconfig/cluster/remote/run_remote.py +1 -1
- machineconfig/cluster/sessions_managers/utils/maker.py +10 -8
- machineconfig/cluster/sessions_managers/wt_local.py +1 -1
- machineconfig/cluster/sessions_managers/wt_local_manager.py +1 -1
- machineconfig/cluster/sessions_managers/zellij_local.py +1 -1
- machineconfig/cluster/sessions_managers/zellij_local_manager.py +1 -1
- machineconfig/jobs/installer/checks/check_installations.py +133 -0
- machineconfig/jobs/installer/checks/install_utils.py +132 -0
- machineconfig/jobs/installer/checks/report_utils.py +39 -0
- machineconfig/jobs/installer/checks/vt_utils.py +89 -0
- machineconfig/jobs/installer/installer_data.json +271 -152
- machineconfig/jobs/installer/linux_scripts/docker.sh +6 -9
- machineconfig/jobs/installer/package_groups.py +11 -9
- machineconfig/jobs/installer/{custom → python_scripts}/boxes.py +1 -2
- machineconfig/jobs/installer/{custom_dev → python_scripts}/brave.py +1 -1
- machineconfig/jobs/installer/{custom_dev → python_scripts}/code.py +10 -8
- machineconfig/jobs/installer/{custom → python_scripts}/hx.py +30 -13
- machineconfig/jobs/installer/{custom_dev → python_scripts}/nerdfont.py +1 -1
- machineconfig/jobs/installer/{custom_dev → python_scripts}/nerfont_windows_helper.py +6 -5
- machineconfig/jobs/installer/{custom_dev → python_scripts}/sysabc.py +26 -20
- machineconfig/jobs/installer/{custom_dev → python_scripts}/wezterm.py +1 -1
- machineconfig/jobs/installer/{custom → python_scripts}/yazi.py +39 -19
- machineconfig/jobs/scripts/powershell_scripts/cmatrix.ps1 +52 -0
- machineconfig/jobs/scripts/powershell_scripts/mount_ssh.ps1 +13 -0
- machineconfig/jobs/scripts/powershell_scripts/obs.ps1 +4 -0
- machineconfig/jobs/scripts_dynamic/a.py +428 -0
- machineconfig/logger.py +1 -1
- machineconfig/profile/create_helper.py +21 -10
- machineconfig/profile/create_links.py +77 -20
- machineconfig/profile/create_links_export.py +63 -58
- machineconfig/profile/create_shell_profile.py +14 -0
- machineconfig/profile/mapper_data.toml +45 -0
- machineconfig/profile/mapper_dotfiles.toml +249 -0
- machineconfig/scripts/python/agents.py +76 -171
- machineconfig/scripts/python/ai/initai.py +3 -1
- machineconfig/scripts/python/ai/scripts/__init__.py +1 -0
- machineconfig/scripts/python/ai/scripts/lint_and_type_check.ps1 +2 -0
- machineconfig/scripts/python/ai/scripts/lint_and_type_check.sh +8 -6
- machineconfig/scripts/python/ai/solutions/claude/claude.py +1 -1
- machineconfig/scripts/python/ai/solutions/cline/cline.py +1 -1
- machineconfig/scripts/python/ai/solutions/copilot/github_copilot.py +1 -1
- machineconfig/scripts/python/ai/solutions/copilot/instructions/python/dev.instructions.md +29 -0
- machineconfig/scripts/python/ai/solutions/crush/crush.py +1 -1
- machineconfig/scripts/python/ai/solutions/cursor/cursors.py +1 -1
- machineconfig/scripts/python/ai/solutions/gemini/gemini.py +1 -1
- machineconfig/scripts/python/ai/solutions/gemini/settings.json +3 -0
- machineconfig/scripts/python/ai/{solutions → utils}/generic.py +2 -15
- machineconfig/scripts/python/ai/utils/vscode_tasks.py +6 -3
- machineconfig/scripts/python/cloud.py +58 -11
- machineconfig/scripts/python/croshell.py +4 -155
- machineconfig/scripts/python/devops.py +57 -38
- machineconfig/scripts/python/devops_navigator.py +17 -3
- machineconfig/scripts/python/fire_jobs.py +10 -193
- machineconfig/scripts/python/ftpx.py +5 -224
- machineconfig/scripts/python/graph/cli_graph.json +8743 -0
- machineconfig/scripts/python/{env_manager → helper_env}/path_manager_tui.py +2 -2
- machineconfig/scripts/python/{env_manager → helpers/helper_env}/env_manager_tui.py +1 -1
- machineconfig/scripts/python/helpers/helper_env/path_manager_tui.py +228 -0
- machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/agentic_frameworks/fire_crush.py +1 -1
- machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/agentic_frameworks/fire_cursor_agents.py +1 -1
- machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/agentic_frameworks/fire_gemini.py +1 -1
- machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/agentic_frameworks/fire_qwen.py +1 -1
- machineconfig/scripts/python/helpers/helpers_agents/agents_impl.py +168 -0
- machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/fire_agents_help_launch.py +10 -7
- machineconfig/scripts/python/helpers/helpers_agents/privacy/configs/aichat/config.yaml +5 -0
- machineconfig/scripts/python/helpers/helpers_agents/privacy/configs/aider/.aider.conf.yml +2 -0
- machineconfig/scripts/python/helpers/helpers_agents/privacy/configs/copilot/config.yml +1 -0
- machineconfig/scripts/python/helpers/helpers_agents/privacy/configs/crush/crush.json +10 -0
- machineconfig/scripts/python/helpers/helpers_agents/privacy/configs/gemini/settings.json +12 -0
- machineconfig/scripts/python/helpers/helpers_agents/privacy/privacy.py +109 -0
- machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/templates/template.sh +3 -1
- machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/cloud_copy.py +6 -6
- machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/cloud_mount.py +10 -5
- machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/cloud_sync.py +4 -4
- machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/helpers2.py +1 -1
- machineconfig/scripts/python/helpers/helpers_croshell/croshell_impl.py +225 -0
- machineconfig/scripts/python/{helpers_croshell → helpers/helpers_croshell}/scheduler.py +4 -4
- machineconfig/scripts/python/{helpers_croshell → helpers/helpers_croshell}/start_slidev.py +7 -6
- machineconfig/scripts/python/helpers/helpers_devops/backup_config.py +149 -0
- machineconfig/scripts/python/helpers/helpers_devops/cli_backup_retrieve.py +262 -0
- machineconfig/scripts/python/helpers/helpers_devops/cli_config.py +98 -0
- machineconfig/scripts/python/helpers/helpers_devops/cli_config_dotfile.py +274 -0
- machineconfig/scripts/python/helpers/helpers_devops/cli_data.py +67 -0
- machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/cli_nw.py +69 -82
- machineconfig/scripts/python/helpers/helpers_devops/cli_repos.py +274 -0
- machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/cli_self.py +47 -22
- machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/cli_share_file.py +44 -30
- machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/cli_share_server.py +26 -43
- machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/cli_share_terminal.py +12 -6
- machineconfig/scripts/python/helpers/helpers_devops/cli_ssh.py +167 -0
- machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/devops_status.py +12 -6
- machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/devops_update_repos.py +1 -1
- machineconfig/scripts/python/{interactive.py → helpers/helpers_devops/interactive.py} +64 -50
- machineconfig/scripts/python/helpers/helpers_devops/run_script.py +197 -0
- machineconfig/scripts/python/helpers/helpers_devops/themes/choose_starship_theme.ps1 +41 -0
- machineconfig/scripts/python/helpers/helpers_devops/themes/choose_starship_theme.sh +48 -0
- machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/themes/choose_wezterm_theme.py +3 -3
- machineconfig/scripts/python/{helpers_fire_command → helpers/helpers_fire_command}/file_wrangler.py +1 -0
- machineconfig/scripts/python/{helpers_fire_command → helpers/helpers_fire_command}/fire_jobs_args_helper.py +1 -0
- machineconfig/scripts/python/helpers/helpers_fire_command/fire_jobs_impl.py +233 -0
- machineconfig/scripts/python/{helpers_fire_command → helpers/helpers_fire_command}/fire_jobs_route_helper.py +3 -3
- machineconfig/scripts/python/helpers/helpers_msearch/msearch_impl.py +248 -0
- machineconfig/scripts/python/{helpers_msearch → helpers/helpers_msearch}/scripts_linux/fzfg +4 -3
- machineconfig/scripts/python/helpers/helpers_msearch/scripts_linux/search_with_context.sh +48 -0
- machineconfig/scripts/python/{helpers_msearch → helpers/helpers_msearch}/scripts_windows/fzfg.ps1 +1 -1
- machineconfig/scripts/python/helpers/helpers_navigator/__init__.py +20 -0
- machineconfig/scripts/python/helpers/helpers_navigator/cli_graph_loader.py +234 -0
- machineconfig/scripts/python/{helpers_navigator → helpers/helpers_navigator}/command_builder.py +61 -13
- machineconfig/scripts/python/helpers/helpers_navigator/command_detail.py +153 -0
- machineconfig/scripts/python/helpers/helpers_navigator/command_tree.py +45 -0
- machineconfig/scripts/python/{helpers_navigator → helpers/helpers_navigator}/data_models.py +18 -11
- machineconfig/scripts/python/{helpers_navigator → helpers/helpers_navigator}/main_app.py +5 -5
- machineconfig/scripts/python/{helpers_network → helpers/helpers_network}/address.py +52 -10
- machineconfig/scripts/python/helpers/helpers_network/address_switch.py +78 -0
- machineconfig/scripts/python/helpers/helpers_network/ftpx_impl.py +276 -0
- machineconfig/scripts/python/{helpers_network → helpers/helpers_network}/mount_ssh.py +2 -2
- machineconfig/scripts/python/helpers/helpers_network/ssh_add_identity.py +73 -0
- machineconfig/scripts/python/helpers/helpers_network/ssh_add_ssh_key.py +175 -0
- machineconfig/scripts/python/helpers/helpers_network/ssh_debug_linux.py +319 -0
- machineconfig/scripts/python/helpers/helpers_network/ssh_debug_windows.py +275 -0
- machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/action.py +3 -3
- machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/action_helper.py +3 -3
- machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/cloud_repo_sync.py +118 -34
- machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/grource.py +3 -2
- machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/record.py +33 -13
- machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/repo_analyzer_2.py +63 -19
- machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/update.py +0 -6
- machineconfig/scripts/python/helpers/helpers_search/script_help.py +81 -0
- machineconfig/scripts/python/helpers/helpers_sessions/__init__.py +0 -0
- machineconfig/scripts/python/helpers/helpers_sessions/sessions_impl.py +186 -0
- machineconfig/scripts/python/{helpers_sessions → helpers/helpers_sessions}/sessions_multiprocess.py +1 -2
- machineconfig/scripts/python/helpers/helpers_terminal/__init__.py +0 -0
- machineconfig/scripts/python/helpers/helpers_terminal/terminal_impl.py +96 -0
- machineconfig/scripts/python/{helpers_utils → helpers/helpers_utils}/download.py +1 -1
- machineconfig/scripts/python/{helpers_devops/cli_utils.py → helpers/helpers_utils/pdf.py} +2 -2
- machineconfig/scripts/python/{helpers_utils/path.py → helpers/helpers_utils/python.py} +65 -40
- machineconfig/scripts/python/helpers/helpers_utils/specs.py +246 -0
- machineconfig/scripts/python/mcfg_entry.py +133 -48
- machineconfig/scripts/python/msearch.py +16 -61
- machineconfig/scripts/python/sessions.py +68 -203
- machineconfig/scripts/python/terminal.py +27 -102
- machineconfig/scripts/python/utils.py +101 -22
- machineconfig/settings/atuin/config.toml +294 -0
- machineconfig/settings/atuin/themes/catppuccin-mocha-mauve.toml +12 -0
- machineconfig/settings/linters/.ruff.toml +2 -1
- machineconfig/settings/mprocs/windows/mprocs.yaml +2 -2
- machineconfig/settings/shells/bash/init.sh +6 -3
- machineconfig/settings/shells/nushell/config.nu +23 -1
- machineconfig/settings/shells/nushell/env.nu +22 -48
- machineconfig/settings/shells/nushell/init.nu +64 -240
- machineconfig/settings/shells/pwsh/init.ps1 +69 -1
- machineconfig/settings/shells/pwsh/search_pwsh_history.ps1 +99 -0
- machineconfig/settings/shells/wezterm/wezterm.lua +4 -1
- machineconfig/settings/shells/wt/settings.json +21 -21
- machineconfig/settings/shells/zsh/init.sh +25 -4
- machineconfig/settings/television/cable_unix/bash-history.toml +1 -1
- machineconfig/settings/television/cable_windows/pwsh-history.toml +1 -1
- machineconfig/settings/tv/config.toml +234 -0
- machineconfig/settings/tv/themes/catppuccin-mocha-sky.toml +22 -0
- machineconfig/settings/wsl/.wslconfig +5 -30
- machineconfig/settings/wt/__init__.py +0 -0
- machineconfig/settings/yazi/yazi_linux.toml +18 -8
- machineconfig/settings/zellij/layouts/st.kdl +40 -9
- machineconfig/settings/zellij/layouts/st2.kdl +1 -1
- machineconfig/setup_linux/__init__.py +0 -1
- machineconfig/setup_linux/apps_desktop.sh +8 -27
- machineconfig/setup_linux/web_shortcuts/interactive.sh +10 -10
- machineconfig/setup_linux/web_shortcuts/live_from_github.sh +3 -0
- machineconfig/setup_mac/__init__.py +0 -2
- machineconfig/setup_windows/__init__.py +2 -5
- machineconfig/setup_windows/web_shortcuts/interactive.ps1 +14 -13
- machineconfig/setup_windows/web_shortcuts/live_from_github.ps1 +4 -3
- machineconfig/setup_windows/web_shortcuts/quick_init.ps1 +3 -3
- machineconfig/type_hinting/sql/__init__.py +1 -0
- machineconfig/type_hinting/sql/base.py +216 -0
- machineconfig/type_hinting/sql/core_schema.py +64 -0
- machineconfig/type_hinting/sql/core_schema_typeddict.py +41 -0
- machineconfig/type_hinting/sql/typeddict_codegen.py +222 -0
- machineconfig/type_hinting/typedict/__init__.py +1 -0
- machineconfig/type_hinting/typedict/ast_utils.py +130 -0
- machineconfig/type_hinting/typedict/generator_helpers.py +319 -0
- machineconfig/type_hinting/typedict/generators.py +231 -0
- machineconfig/type_hinting/typedict/polars_schema.py +24 -0
- machineconfig/type_hinting/typedict/polars_schema_typeddict.py +63 -0
- machineconfig/utils/accessories.py +24 -0
- machineconfig/utils/code.py +78 -33
- machineconfig/utils/files/ascii_art.py +10 -14
- machineconfig/utils/files/headers.py +3 -5
- machineconfig/utils/files/read.py +8 -1
- machineconfig/utils/installer_utils/github_release_bulk.py +11 -91
- machineconfig/utils/installer_utils/github_release_scraper.py +99 -0
- machineconfig/utils/installer_utils/install_from_url.py +1 -1
- machineconfig/utils/installer_utils/installer_class.py +12 -4
- machineconfig/utils/installer_utils/installer_cli.py +1 -15
- machineconfig/utils/installer_utils/installer_helper.py +2 -2
- machineconfig/utils/installer_utils/installer_locator_utils.py +13 -13
- machineconfig/utils/installer_utils/installer_runner.py +4 -4
- machineconfig/utils/io.py +25 -8
- machineconfig/utils/meta.py +6 -4
- machineconfig/utils/options.py +49 -19
- machineconfig/utils/options_utils/__init__.py +0 -0
- machineconfig/utils/options_utils/options_tv_linux.py +211 -0
- machineconfig/utils/options_utils/options_tv_windows.py +88 -0
- machineconfig/utils/options_utils/tv_options.py +37 -0
- machineconfig/utils/path_extended.py +8 -7
- machineconfig/utils/scheduler.py +8 -2
- machineconfig/utils/schemas/fire_agents/fire_agents_input.py +1 -1
- machineconfig/utils/source_of_truth.py +6 -1
- machineconfig/utils/ssh.py +73 -23
- machineconfig/utils/ssh_utils/abc.py +1 -1
- machineconfig/utils/ssh_utils/copy_from_here.py +19 -14
- machineconfig/utils/ssh_utils/copy_to_here.py +2 -1
- machineconfig/utils/ssh_utils/utils.py +23 -7
- machineconfig/utils/ssh_utils/wsl.py +107 -170
- machineconfig/utils/ssh_utils/wsl_helper.py +217 -0
- machineconfig/utils/upgrade_packages.py +4 -8
- {machineconfig-7.98.dist-info → machineconfig-8.51.dist-info}/METADATA +30 -22
- machineconfig-8.51.dist-info/RECORD +543 -0
- machineconfig/jobs/installer/check_installations.py +0 -248
- machineconfig/profile/backup.toml +0 -49
- machineconfig/profile/mapper.toml +0 -263
- machineconfig/scripts/linux/other/switch_ip +0 -20
- machineconfig/scripts/python/helpers/run_py_script.py +0 -79
- machineconfig/scripts/python/helpers/tmp_py_scripts/a.py +0 -26
- machineconfig/scripts/python/helpers_devops/cli_config.py +0 -105
- machineconfig/scripts/python/helpers_devops/cli_config_dotfile.py +0 -89
- machineconfig/scripts/python/helpers_devops/cli_data.py +0 -25
- machineconfig/scripts/python/helpers_devops/cli_repos.py +0 -215
- machineconfig/scripts/python/helpers_devops/devops_backup_retrieve.py +0 -80
- machineconfig/scripts/python/helpers_devops/themes/choose_starship_theme.bash +0 -3
- machineconfig/scripts/python/helpers_navigator/__init__.py +0 -20
- machineconfig/scripts/python/helpers_navigator/command_detail.py +0 -44
- machineconfig/scripts/python/helpers_navigator/command_tree.py +0 -620
- machineconfig/scripts/python/helpers_network/devops_add_identity.py +0 -82
- machineconfig/scripts/python/helpers_network/devops_add_ssh_key.py +0 -153
- machineconfig/scripts/python/helpers_network/ssh_debug_linux.py +0 -391
- machineconfig/scripts/python/helpers_network/ssh_debug_windows.py +0 -338
- machineconfig/scripts/python/helpers_network/wsl_windows_transfer.py +0 -67
- machineconfig/scripts/python/helpers_repos/entrypoint.py +0 -77
- machineconfig/scripts/windows/mounts/mount_ssh.ps1 +0 -13
- machineconfig/setup_linux/others/mint_keyboard_shortcuts.sh +0 -30
- machineconfig/setup_linux/ssh/openssh_all.sh +0 -25
- machineconfig/setup_linux/ssh/openssh_wsl.sh +0 -38
- machineconfig/setup_mac/ssh/openssh_setup.sh +0 -114
- machineconfig/setup_windows/others/obs.ps1 +0 -4
- machineconfig/setup_windows/ssh/add-sshkey.ps1 +0 -29
- machineconfig/setup_windows/ssh/add_identity.ps1 +0 -11
- machineconfig/setup_windows/ssh/openssh-server.ps1 +0 -37
- machineconfig/setup_windows/ssh/openssh-server_add_key.ps1 +0 -7
- machineconfig/setup_windows/ssh/openssh-server_copy-ssh-id.ps1 +0 -14
- machineconfig/utils/options_tv.py +0 -119
- machineconfig/utils/tst.py +0 -20
- machineconfig-7.98.dist-info/RECORD +0 -504
- /machineconfig/jobs/installer/{custom_dev → checks}/__init__.py +0 -0
- /machineconfig/{scripts/python/helpers_agents → jobs/installer/python_scripts}/__init__.py +0 -0
- /machineconfig/jobs/installer/{custom_dev → python_scripts}/alacritty.py +0 -0
- /machineconfig/jobs/installer/{custom_dev → python_scripts}/bypass_paywall.py +0 -0
- /machineconfig/jobs/installer/{custom_dev → python_scripts}/cloudflare_warp_cli.py +0 -0
- /machineconfig/jobs/installer/{custom_dev → python_scripts}/cursor.py +0 -0
- /machineconfig/jobs/installer/{custom_dev → python_scripts}/dubdb_adbc.py +0 -0
- /machineconfig/jobs/installer/{custom_dev → python_scripts}/espanso.py +0 -0
- /machineconfig/jobs/installer/{custom → python_scripts}/gh.py +0 -0
- /machineconfig/jobs/installer/{custom_dev → python_scripts}/goes.py +0 -0
- /machineconfig/jobs/installer/{custom_dev → python_scripts}/lvim.py +0 -0
- /machineconfig/jobs/installer/{custom_dev → python_scripts}/redis.py +0 -0
- /machineconfig/jobs/installer/{custom_dev → python_scripts}/winget.py +0 -0
- /machineconfig/{setup_linux/others → jobs/scripts/bash_scripts}/android.sh +0 -0
- /machineconfig/jobs/{installer/linux_scripts → scripts/bash_scripts}/lid.sh +0 -0
- /machineconfig/{scripts/python/helpers_network → jobs/scripts/bash_scripts}/mount_drive +0 -0
- /machineconfig/{scripts/python/helpers_network → jobs/scripts/bash_scripts}/mount_nfs +0 -0
- /machineconfig/{scripts/python/helpers_network → jobs/scripts/bash_scripts}/mount_nw_drive +0 -0
- /machineconfig/{scripts/python/helpers_network → jobs/scripts/bash_scripts}/mount_smb +0 -0
- /machineconfig/{scripts/linux/other → jobs/scripts/bash_scripts}/share_cloud.sh +0 -0
- /machineconfig/{scripts/linux/other → jobs/scripts/bash_scripts}/share_nfs +0 -0
- /machineconfig/{scripts/linux/other → jobs/scripts/bash_scripts}/start_docker +0 -0
- /machineconfig/{scripts/windows/mounts → jobs/scripts/powershell_scripts}/Restore-ThunderbirdProfile.ps1 +0 -0
- /machineconfig/{setup_windows/others → jobs/scripts/powershell_scripts}/docker.ps1 +0 -0
- /machineconfig/{scripts/windows/mounts → jobs/scripts/powershell_scripts}/mount_nfs.ps1 +0 -0
- /machineconfig/{scripts/windows/mounts → jobs/scripts/powershell_scripts}/mount_nw.ps1 +0 -0
- /machineconfig/{scripts/windows/mounts → jobs/scripts/powershell_scripts}/mount_smb.ps1 +0 -0
- /machineconfig/{setup_windows/others → jobs/scripts/powershell_scripts}/power_options.ps1 +0 -0
- /machineconfig/{scripts/windows/mounts → jobs/scripts/powershell_scripts}/share_cloud.cmd +0 -0
- /machineconfig/{scripts/windows/mounts → jobs/scripts/powershell_scripts}/share_smb.ps1 +0 -0
- /machineconfig/{scripts/windows/mounts → jobs/scripts/powershell_scripts}/unlock_bitlocker.ps1 +0 -0
- /machineconfig/scripts/python/ai/{solutions/_shared.py → utils/shared.py} +0 -0
- /machineconfig/scripts/python/{helpers_agents/agentic_frameworks → graph}/__init__.py +0 -0
- /machineconfig/scripts/python/{helpers_cloud → helpers}/__init__.py +0 -0
- /machineconfig/scripts/python/{env_manager → helpers/helper_env}/__init__.py +0 -0
- /machineconfig/scripts/python/{env_manager → helpers/helper_env}/path_manager_backend.py +0 -0
- /machineconfig/scripts/python/{helpers_croshell → helpers/helpers_agents}/__init__.py +0 -0
- /machineconfig/scripts/python/{helpers_devops → helpers/helpers_agents/agentic_frameworks}/__init__.py +0 -0
- /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/agentic_frameworks/fire_crush.json +0 -0
- /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/fire_agents_help_search.py +0 -0
- /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/fire_agents_helper_types.py +0 -0
- /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/fire_agents_load_balancer.py +0 -0
- /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/templates/prompt.txt +0 -0
- /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/templates/template.ps1 +0 -0
- /machineconfig/scripts/python/{helpers_devops/themes → helpers/helpers_cloud}/__init__.py +0 -0
- /machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/cloud_helpers.py +0 -0
- /machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/helpers5.py +0 -0
- /machineconfig/scripts/python/{helpers_fire_command → helpers/helpers_croshell}/__init__.py +0 -0
- /machineconfig/scripts/python/{helpers_croshell → helpers/helpers_croshell}/crosh.py +0 -0
- /machineconfig/scripts/python/{helpers_croshell → helpers/helpers_croshell}/pomodoro.py +0 -0
- /machineconfig/scripts/python/{helpers_croshell → helpers/helpers_croshell}/viewer.py +0 -0
- /machineconfig/scripts/python/{helpers_croshell → helpers/helpers_croshell}/viewer_template.py +0 -0
- /machineconfig/scripts/python/{helpers_network → helpers/helpers_devops}/__init__.py +0 -0
- /machineconfig/scripts/python/{helpers_sessions → helpers/helpers_devops/themes}/__init__.py +0 -0
- /machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/themes/choose_pwsh_theme.ps1 +0 -0
- /machineconfig/{setup_windows/wt_and_pwsh → scripts/python/helpers/helpers_fire_command}/__init__.py +0 -0
- /machineconfig/scripts/python/{helpers_fire_command → helpers/helpers_fire_command}/cloud_manager.py +0 -0
- /machineconfig/scripts/python/{helpers_fire_command → helpers/helpers_fire_command}/f.py +0 -0
- /machineconfig/scripts/python/{helpers_fire_command → helpers/helpers_fire_command}/fire_jobs_streamlit_helper.py +0 -0
- /machineconfig/scripts/python/{helpers_msearch → helpers/helpers_msearch}/__init__.py +0 -0
- /machineconfig/scripts/python/{helpers_navigator → helpers/helpers_navigator}/search_bar.py +0 -0
- /machineconfig/scripts/python/{helpers_devops/themes/choose_starship_theme.ps1 → helpers/helpers_network/__init__.py} +0 -0
- /machineconfig/scripts/python/{helpers_network → helpers/helpers_network}/mount_nfs.py +0 -0
- /machineconfig/scripts/python/{helpers_network → helpers/helpers_network}/mount_nw_drive.py +0 -0
- /machineconfig/scripts/python/{helpers_network → helpers/helpers_network}/onetimeshare.py +0 -0
- /machineconfig/scripts/python/{helpers_network → helpers/helpers_network}/wifi_conn.py +0 -0
- /machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/clone.py +0 -0
- /machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/repo_analyzer_1.py +0 -0
- /machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/sync.py +0 -0
- /machineconfig/scripts/python/helpers/{ast_search.py → helpers_search/ast_search.py} +0 -0
- /machineconfig/scripts/python/helpers/{qr_code.py → helpers_search/qr_code.py} +0 -0
- /machineconfig/scripts/python/helpers/{repo_rag.py → helpers_search/repo_rag.py} +0 -0
- /machineconfig/scripts/python/helpers/{symantic_search.py → helpers_search/symantic_search.py} +0 -0
- /machineconfig/{setup_windows/wt_and_pwsh → settings/wt}/set_wt_settings.py +0 -0
- {machineconfig-7.98.dist-info → machineconfig-8.51.dist-info}/WHEEL +0 -0
- {machineconfig-7.98.dist-info → machineconfig-8.51.dist-info}/entry_points.txt +0 -0
- {machineconfig-7.98.dist-info → machineconfig-8.51.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
from platform import system
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from rich.console import Console
|
|
6
|
+
from rich.panel import Panel
|
|
7
|
+
from rich.table import Table
|
|
8
|
+
from rich import box
|
|
9
|
+
import subprocess
|
|
10
|
+
import os
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
console = Console()
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def _run_ps(cmd: str) -> tuple[bool, str]:
|
|
17
|
+
result = subprocess.run(["powershell", "-Command", cmd], capture_output=True, text=True, check=False)
|
|
18
|
+
return result.returncode == 0, result.stdout.strip()
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def _check_sshd_binary_exists() -> tuple[bool, str]:
|
|
22
|
+
sshd_locations = [
|
|
23
|
+
Path("C:/Windows/System32/OpenSSH/sshd.exe"),
|
|
24
|
+
Path("C:/Program Files/OpenSSH/sshd.exe"),
|
|
25
|
+
Path("C:/Program Files (x86)/OpenSSH/sshd.exe"),
|
|
26
|
+
]
|
|
27
|
+
for loc in sshd_locations:
|
|
28
|
+
if loc.exists():
|
|
29
|
+
return True, str(loc)
|
|
30
|
+
ok, which_out = _run_ps("Get-Command sshd -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Source")
|
|
31
|
+
if ok and which_out:
|
|
32
|
+
return True, which_out
|
|
33
|
+
return False, ""
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def _detect_openssh() -> tuple[str, Path | None, Path | None]:
|
|
37
|
+
capability_sshd = Path("C:/Windows/System32/OpenSSH/sshd.exe")
|
|
38
|
+
winget_sshd = Path("C:/Program Files/OpenSSH/sshd.exe")
|
|
39
|
+
programdata_config = Path("C:/ProgramData/ssh")
|
|
40
|
+
capability_config = Path("C:/ProgramData/ssh")
|
|
41
|
+
if capability_sshd.exists():
|
|
42
|
+
return ("capability", capability_sshd, capability_config)
|
|
43
|
+
if winget_sshd.exists():
|
|
44
|
+
return ("winget", winget_sshd, programdata_config)
|
|
45
|
+
return ("not_found", None, None)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def ssh_debug_windows() -> dict[str, dict[str, str | bool]]:
|
|
49
|
+
if system() != "Windows":
|
|
50
|
+
raise NotImplementedError("ssh_debug_windows is only supported on Windows")
|
|
51
|
+
|
|
52
|
+
results: dict[str, dict[str, str | bool]] = {}
|
|
53
|
+
issues: list[tuple[str, str, str]] = []
|
|
54
|
+
current_user = os.environ.get("USERNAME", "unknown")
|
|
55
|
+
ssh_port = "22"
|
|
56
|
+
ip_addresses: list[str] = []
|
|
57
|
+
|
|
58
|
+
sshd_exists, sshd_path = _check_sshd_binary_exists()
|
|
59
|
+
install_type, _sshd_exe, config_dir = _detect_openssh()
|
|
60
|
+
ok, hostname = _run_ps("hostname")
|
|
61
|
+
hostname = hostname if ok else "unknown"
|
|
62
|
+
|
|
63
|
+
install_info: list[str] = []
|
|
64
|
+
if not sshd_exists:
|
|
65
|
+
results["installation"] = {"status": "error", "message": "sshd.exe not found on system"}
|
|
66
|
+
issues.append(("sshd.exe not found", "OpenSSH Server binary missing entirely", "Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0"))
|
|
67
|
+
install_info.append("❌ sshd.exe: [red]NOT FOUND[/red]")
|
|
68
|
+
install_info.append(" [dim]OpenSSH Server is not installed on this system[/dim]")
|
|
69
|
+
elif install_type == "not_found":
|
|
70
|
+
results["installation"] = {"status": "warning", "message": f"sshd found at {sshd_path} but not in standard location"}
|
|
71
|
+
install_info.append(f"⚠️ sshd.exe: found at [yellow]{sshd_path}[/yellow]")
|
|
72
|
+
install_info.append(" [dim]Non-standard location - may need manual configuration[/dim]")
|
|
73
|
+
else:
|
|
74
|
+
results["installation"] = {"status": "ok", "message": f"OpenSSH installed ({install_type})"}
|
|
75
|
+
install_info.append(f"✅ OpenSSH Server: installed via {'Windows Capability' if install_type == 'capability' else 'winget'}")
|
|
76
|
+
install_info.append(f" Binary: {sshd_path}")
|
|
77
|
+
install_info.append(f" Config: {config_dir}")
|
|
78
|
+
|
|
79
|
+
ok, status = _run_ps("Get-Service -Name sshd -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Status")
|
|
80
|
+
if not ok or not status:
|
|
81
|
+
results["ssh_service"] = {"status": "error", "message": "sshd service not found"}
|
|
82
|
+
issues.append(("sshd service missing", "SSH daemon not installed", "Install OpenSSH Server first"))
|
|
83
|
+
install_info.append("❌ sshd service: [red]NOT FOUND[/red]")
|
|
84
|
+
elif status != "Running":
|
|
85
|
+
results["ssh_service"] = {"status": "error", "message": f"sshd is {status}"}
|
|
86
|
+
issues.append((f"sshd is {status}", "SSH connections will be refused", "Start-Service sshd ; Set-Service sshd -StartupType Automatic"))
|
|
87
|
+
install_info.append(f"❌ sshd service: [yellow]{status}[/yellow]")
|
|
88
|
+
else:
|
|
89
|
+
results["ssh_service"] = {"status": "ok", "message": "sshd running"}
|
|
90
|
+
ok, startup = _run_ps("Get-Service -Name sshd | Select-Object -ExpandProperty StartType")
|
|
91
|
+
startup_note = f" (startup: {startup})" if ok else ""
|
|
92
|
+
install_info.append(f"✅ sshd service: [green]Running[/green]{startup_note}")
|
|
93
|
+
|
|
94
|
+
console.print(Panel("\n".join(install_info), title="[bold]Installation & Service[/bold]", border_style="blue"))
|
|
95
|
+
|
|
96
|
+
ssh_dir = Path.home().joinpath(".ssh")
|
|
97
|
+
authorized_keys = ssh_dir.joinpath("authorized_keys")
|
|
98
|
+
admin_auth_keys = Path("C:/ProgramData/ssh/administrators_authorized_keys")
|
|
99
|
+
perm_info: list[str] = []
|
|
100
|
+
|
|
101
|
+
ok, is_admin_str = _run_ps("([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)")
|
|
102
|
+
is_admin = "True" in is_admin_str
|
|
103
|
+
|
|
104
|
+
if is_admin:
|
|
105
|
+
perm_info.append(f"👤 User [cyan]{current_user}[/cyan] is an [yellow]Administrator[/yellow]")
|
|
106
|
+
perm_info.append(" ➜ Keys must be in: [cyan]C:\\ProgramData\\ssh\\administrators_authorized_keys[/cyan]")
|
|
107
|
+
target_auth_keys = admin_auth_keys
|
|
108
|
+
else:
|
|
109
|
+
perm_info.append(f"👤 User [cyan]{current_user}[/cyan] is a standard user")
|
|
110
|
+
perm_info.append(f" ➜ Keys should be in: [cyan]{authorized_keys}[/cyan]")
|
|
111
|
+
target_auth_keys = authorized_keys
|
|
112
|
+
|
|
113
|
+
if not target_auth_keys.exists():
|
|
114
|
+
results["authorized_keys"] = {"status": "error", "message": f"{target_auth_keys.name} missing"}
|
|
115
|
+
issues.append((f"{target_auth_keys.name} missing", "No public keys authorized - SSH login will fail", f"Create file and add your public key to {target_auth_keys}"))
|
|
116
|
+
perm_info.append(f"\n❌ [red]{target_auth_keys.name} does not exist[/red]")
|
|
117
|
+
perm_info.append(" [dim]No keys = no login. Add your public key to this file.[/dim]")
|
|
118
|
+
else:
|
|
119
|
+
try:
|
|
120
|
+
keys = [line for line in target_auth_keys.read_text(encoding="utf-8").split("\n") if line.strip()]
|
|
121
|
+
results["authorized_keys"] = {"status": "ok", "message": f"{len(keys)} key(s)"}
|
|
122
|
+
perm_info.append(f"\n✅ {target_auth_keys.name}: [green]{len(keys)} key(s)[/green]")
|
|
123
|
+
except Exception as e:
|
|
124
|
+
perm_info.append(f"\n⚠️ Could not read {target_auth_keys.name}: {e}")
|
|
125
|
+
|
|
126
|
+
if is_admin and admin_auth_keys.exists():
|
|
127
|
+
ok, icacls_out = _run_ps(f'icacls "{admin_auth_keys}"')
|
|
128
|
+
if ok:
|
|
129
|
+
needs_fix = "BUILTIN\\Users" in icacls_out or "Everyone" in icacls_out
|
|
130
|
+
if needs_fix:
|
|
131
|
+
results["admin_keys_perms"] = {"status": "error", "message": "Permissions too open"}
|
|
132
|
+
issues.append(("administrators_authorized_keys permissions wrong", "sshd ignores file if permissions allow other users", f'icacls "{admin_auth_keys}" /inheritance:r /grant "Administrators:F" /grant "SYSTEM:F"'))
|
|
133
|
+
perm_info.append("❌ [red]Permissions too open[/red] - sshd will ignore this file!")
|
|
134
|
+
else:
|
|
135
|
+
perm_info.append("✅ Permissions: restricted to Administrators/SYSTEM")
|
|
136
|
+
|
|
137
|
+
console.print(Panel("\n".join(perm_info), title="[bold]Keys & Permissions[/bold]", border_style="blue"))
|
|
138
|
+
|
|
139
|
+
net_info: list[str] = []
|
|
140
|
+
ok, ip_out = _run_ps("Get-NetIPAddress -AddressFamily IPv4 -PrefixOrigin Dhcp,Manual | Where-Object {$_.IPAddress -notlike '127.*' -and $_.IPAddress -notlike '169.254.*'} | Select-Object -ExpandProperty IPAddress")
|
|
141
|
+
if ok and ip_out:
|
|
142
|
+
ip_addresses = [ip.strip() for ip in ip_out.split("\n") if ip.strip()]
|
|
143
|
+
net_info.append(f"🌐 IP addresses: [cyan]{', '.join(ip_addresses)}[/cyan]")
|
|
144
|
+
|
|
145
|
+
sshd_config: Path | None = config_dir.joinpath("sshd_config") if config_dir else None
|
|
146
|
+
config_text: str | None = None
|
|
147
|
+
if sshd_config and sshd_config.exists():
|
|
148
|
+
try:
|
|
149
|
+
config_text = sshd_config.read_text(encoding="utf-8")
|
|
150
|
+
except PermissionError:
|
|
151
|
+
ok, config_text_ps = _run_ps(f'Get-Content "{sshd_config}" -Raw')
|
|
152
|
+
config_text = config_text_ps if ok and config_text_ps else None
|
|
153
|
+
except Exception:
|
|
154
|
+
config_text = None
|
|
155
|
+
if config_text:
|
|
156
|
+
port_lines = [line for line in config_text.split("\n") if line.strip().startswith("Port") and not line.strip().startswith("#")]
|
|
157
|
+
if port_lines:
|
|
158
|
+
ssh_port = port_lines[0].split()[1]
|
|
159
|
+
|
|
160
|
+
auth_info: list[str] = []
|
|
161
|
+
auth_info.append(f"📄 Config file: [cyan]{sshd_config}[/cyan]" if sshd_config else "📄 Config file: [red]not found[/red]")
|
|
162
|
+
if config_text:
|
|
163
|
+
pubkey_lines = [line for line in config_text.split("\n") if "PubkeyAuthentication" in line and not line.strip().startswith("#")]
|
|
164
|
+
if pubkey_lines and "no" in pubkey_lines[-1].lower():
|
|
165
|
+
results["pubkey_auth"] = {"status": "error", "message": "PubkeyAuthentication disabled"}
|
|
166
|
+
issues.append(("PubkeyAuthentication disabled", "Key-based login won't work", f'Edit {sshd_config} and set PubkeyAuthentication yes, then Restart-Service sshd'))
|
|
167
|
+
auth_info.append("❌ PubkeyAuthentication: [red]disabled[/red]")
|
|
168
|
+
else:
|
|
169
|
+
results["pubkey_auth"] = {"status": "ok", "message": "PubkeyAuthentication enabled (default)"}
|
|
170
|
+
auth_info.append("✅ PubkeyAuthentication: [green]enabled[/green] (default: yes)")
|
|
171
|
+
|
|
172
|
+
password_lines = [line for line in config_text.split("\n") if "PasswordAuthentication" in line and not line.strip().startswith("#")]
|
|
173
|
+
if password_lines:
|
|
174
|
+
password_enabled = "yes" in password_lines[-1].lower()
|
|
175
|
+
if password_enabled:
|
|
176
|
+
results["password_auth"] = {"status": "ok", "message": "PasswordAuthentication enabled"}
|
|
177
|
+
auth_info.append("✅ PasswordAuthentication: [green]enabled[/green]")
|
|
178
|
+
else:
|
|
179
|
+
results["password_auth"] = {"status": "info", "message": "PasswordAuthentication disabled"}
|
|
180
|
+
auth_info.append("🔐 PasswordAuthentication: [yellow]disabled[/yellow] (key-only)")
|
|
181
|
+
else:
|
|
182
|
+
results["password_auth"] = {"status": "ok", "message": "PasswordAuthentication enabled (default)"}
|
|
183
|
+
auth_info.append("✅ PasswordAuthentication: [green]enabled[/green] (default: yes)")
|
|
184
|
+
else:
|
|
185
|
+
auth_info.append("⚠️ Could not read sshd_config - auth settings unknown")
|
|
186
|
+
results["pubkey_auth"] = {"status": "unknown", "message": "Could not read config"}
|
|
187
|
+
results["password_auth"] = {"status": "unknown", "message": "Could not read config"}
|
|
188
|
+
|
|
189
|
+
console.print(Panel("\n".join(auth_info), title="[bold]Authentication Settings[/bold]", border_style="blue"))
|
|
190
|
+
|
|
191
|
+
net_info.append(f"🔌 SSH port: [cyan]{ssh_port}[/cyan]")
|
|
192
|
+
netstat = subprocess.run(["netstat", "-an"], capture_output=True, text=True, check=False)
|
|
193
|
+
if netstat.returncode == 0:
|
|
194
|
+
listening_lines = [line for line in netstat.stdout.split("\n") if f":{ssh_port}" in line and "LISTENING" in line]
|
|
195
|
+
if not listening_lines:
|
|
196
|
+
results["ssh_listening"] = {"status": "error", "message": f"Not listening on port {ssh_port}"}
|
|
197
|
+
issues.append((f"SSH not listening on port {ssh_port}", "No connections possible", "Restart-Service sshd"))
|
|
198
|
+
net_info.append(f"❌ Listening: [red]NOT listening on port {ssh_port}[/red]")
|
|
199
|
+
elif all("127.0.0.1" in line or "[::1]" in line for line in listening_lines):
|
|
200
|
+
results["ssh_listening"] = {"status": "error", "message": "Listening on localhost only"}
|
|
201
|
+
issues.append(("SSH bound to localhost only", "Only local connections work", f"Check ListenAddress in {sshd_config}"))
|
|
202
|
+
net_info.append("❌ Listening: [red]localhost only[/red] (remote connections blocked)")
|
|
203
|
+
else:
|
|
204
|
+
results["ssh_listening"] = {"status": "ok", "message": f"Listening on port {ssh_port}"}
|
|
205
|
+
net_info.append(f"✅ Listening: 0.0.0.0:{ssh_port}")
|
|
206
|
+
|
|
207
|
+
fw_cmd = f"""
|
|
208
|
+
$rules = Get-NetFirewallRule -ErrorAction SilentlyContinue | Where-Object {{
|
|
209
|
+
($_.DisplayName -like '*SSH*' -or $_.DisplayName -like '*OpenSSH*' -or $_.Name -like '*SSH*' -or $_.Name -like '*sshd*') -and
|
|
210
|
+
$_.Direction -eq 'Inbound'
|
|
211
|
+
}}
|
|
212
|
+
if (-not $rules) {{
|
|
213
|
+
$portFilter = Get-NetFirewallPortFilter -ErrorAction SilentlyContinue | Where-Object {{ $_.LocalPort -eq '{ssh_port}' -and $_.Protocol -eq 'TCP' }}
|
|
214
|
+
if ($portFilter) {{
|
|
215
|
+
$rules = $portFilter | ForEach-Object {{ Get-NetFirewallRule -AssociatedNetFirewallPortFilter $_ -ErrorAction SilentlyContinue }} | Where-Object {{ $_.Direction -eq 'Inbound' }}
|
|
216
|
+
}}
|
|
217
|
+
}}
|
|
218
|
+
if ($rules) {{
|
|
219
|
+
$rules | Select-Object Name, DisplayName, Enabled, Action | Format-List
|
|
220
|
+
}}
|
|
221
|
+
"""
|
|
222
|
+
ok, fw_out = _run_ps(fw_cmd)
|
|
223
|
+
if ok and fw_out.strip():
|
|
224
|
+
has_allow = "Enabled : True" in fw_out and "Action : Allow" in fw_out
|
|
225
|
+
if has_allow:
|
|
226
|
+
results["firewall"] = {"status": "ok", "message": "Firewall allows SSH"}
|
|
227
|
+
net_info.append("✅ Firewall: SSH rule exists and enabled")
|
|
228
|
+
else:
|
|
229
|
+
results["firewall"] = {"status": "warning", "message": "Firewall rule exists but may not be active"}
|
|
230
|
+
issues.append(("Firewall rule not active", "Incoming SSH may be blocked", f'New-NetFirewallRule -Name "SSH" -DisplayName "SSH" -Protocol TCP -LocalPort {ssh_port} -Action Allow -Enabled True'))
|
|
231
|
+
net_info.append("⚠️ Firewall: SSH rule exists but [yellow]not enabled[/yellow]")
|
|
232
|
+
else:
|
|
233
|
+
if not is_admin:
|
|
234
|
+
results["firewall"] = {"status": "warning", "message": "Cannot verify firewall (run as Admin)"}
|
|
235
|
+
net_info.append("⚠️ Firewall: [yellow]Cannot verify - run script as Administrator[/yellow]")
|
|
236
|
+
net_info.append(" [dim]Firewall rules may exist but require elevation to query.[/dim]")
|
|
237
|
+
else:
|
|
238
|
+
results["firewall"] = {"status": "error", "message": "No SSH firewall rule"}
|
|
239
|
+
issues.append(("No SSH firewall rule", "Windows Firewall blocks incoming SSH by default", f'New-NetFirewallRule -Name "SSH" -DisplayName "SSH" -Protocol TCP -LocalPort {ssh_port} -Action Allow -Enabled True'))
|
|
240
|
+
net_info.append("❌ Firewall: [red]No SSH rule found[/red]")
|
|
241
|
+
net_info.append(" [dim]Windows blocks all incoming by default. Must create allow rule.[/dim]")
|
|
242
|
+
|
|
243
|
+
console.print(Panel("\n".join(net_info), title="[bold]Network & Firewall[/bold]", border_style="blue"))
|
|
244
|
+
|
|
245
|
+
if issues:
|
|
246
|
+
fix_table = Table(title="Issues & Fixes", box=box.ROUNDED, show_lines=True, title_style="bold red")
|
|
247
|
+
fix_table.add_column("Issue", style="yellow", width=30)
|
|
248
|
+
fix_table.add_column("Impact", style="white", width=35)
|
|
249
|
+
fix_table.add_column("Fix Command", style="green", width=60)
|
|
250
|
+
for issue, impact, fix in issues:
|
|
251
|
+
fix_table.add_row(issue, impact, fix)
|
|
252
|
+
console.print(fix_table)
|
|
253
|
+
|
|
254
|
+
fix_script_path = Path(os.environ.get("TEMP", "C:/Temp")).joinpath("ssh_fix.ps1")
|
|
255
|
+
script_lines = ["# SSH Fix Script - Generated by ssh_debug_windows", f"# {len(issues)} issue(s) to fix", "# Run this script as Administrator", "", "$ErrorActionPreference = 'Stop'", ""]
|
|
256
|
+
for issue, _impact, fix in issues:
|
|
257
|
+
script_lines.append(f"# Fix: {issue}")
|
|
258
|
+
script_lines.append(f"Write-Host 'Fixing: {issue}' -ForegroundColor Yellow")
|
|
259
|
+
script_lines.append(fix)
|
|
260
|
+
script_lines.append("")
|
|
261
|
+
script_lines.append("Write-Host 'All fixes applied. Re-run ssh_debug_windows to verify.' -ForegroundColor Green")
|
|
262
|
+
fix_script_path.write_text("\n".join(script_lines), encoding="utf-8")
|
|
263
|
+
|
|
264
|
+
console.print(Panel(f"[bold yellow]⚠️ {len(issues)} issue(s) found[/bold yellow]\n\nFix script generated: [cyan]{fix_script_path}[/cyan]\nRun as Administrator: [green]powershell -ExecutionPolicy Bypass -File \"{fix_script_path}\"[/green]", title="[bold]Summary[/bold]", border_style="yellow"))
|
|
265
|
+
else:
|
|
266
|
+
conn_info = f"👤 {current_user} 🖥️ {hostname} 🔌 :{ssh_port}"
|
|
267
|
+
if ip_addresses:
|
|
268
|
+
conn_info += f"\n\n[bold]Connect:[/bold] ssh {current_user}@{ip_addresses[0]}"
|
|
269
|
+
console.print(Panel(f"[bold green]✅ All checks passed[/bold green]\n\n{conn_info}", title="[bold]Ready[/bold]", border_style="green"))
|
|
270
|
+
|
|
271
|
+
return results
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
if __name__ == "__main__":
|
|
275
|
+
ssh_debug_windows()
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
from machineconfig.scripts.python.helpers_repos.action_helper import GitAction, GitOperationResult, GitOperationSummary, print_git_operations_summary
|
|
1
|
+
from machineconfig.scripts.python.helpers.helpers_repos.action_helper import GitAction, GitOperationResult, GitOperationSummary, print_git_operations_summary
|
|
2
2
|
from machineconfig.utils.path_extended import PathExtended
|
|
3
3
|
from machineconfig.utils.accessories import randstr
|
|
4
|
-
from machineconfig.scripts.python.helpers_repos.update import update_repository
|
|
4
|
+
from machineconfig.scripts.python.helpers.helpers_repos.update import update_repository
|
|
5
5
|
|
|
6
6
|
from typing import Optional, Dict, Any, List, cast
|
|
7
7
|
import concurrent.futures
|
|
@@ -117,7 +117,7 @@ def perform_git_operations(repos_root: PathExtended, pull: bool, commit: bool, p
|
|
|
117
117
|
operations_performed.append("push")
|
|
118
118
|
|
|
119
119
|
# Collect all candidate paths first
|
|
120
|
-
paths = list(repos_root.
|
|
120
|
+
paths = list(repos_root.glob("*"))
|
|
121
121
|
|
|
122
122
|
def _process_path(a_path: PathExtended) -> Dict[str, Any]:
|
|
123
123
|
"""Worker that processes a single path and returns metadata and results."""
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from enum import Enum
|
|
2
|
-
from
|
|
2
|
+
from pathlib import Path
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
from dataclasses import dataclass
|
|
@@ -12,7 +12,7 @@ from rich.table import Table
|
|
|
12
12
|
@dataclass
|
|
13
13
|
class GitOperationResult:
|
|
14
14
|
"""Result of a git operation on a single repository."""
|
|
15
|
-
repo_path:
|
|
15
|
+
repo_path: Path
|
|
16
16
|
action: str
|
|
17
17
|
success: bool
|
|
18
18
|
message: str
|
|
@@ -52,7 +52,7 @@ class GitOperationSummary:
|
|
|
52
52
|
|
|
53
53
|
def __post_init__(self):
|
|
54
54
|
self.failed_operations: list[GitOperationResult] = []
|
|
55
|
-
self.repos_without_remotes: list[
|
|
55
|
+
self.repos_without_remotes: list[Path] = []
|
|
56
56
|
|
|
57
57
|
|
|
58
58
|
def print_git_operations_summary(summary: GitOperationSummary, operations_performed: list[str]) -> None:
|
|
@@ -1,7 +1,22 @@
|
|
|
1
1
|
|
|
2
|
-
from typing import Optional, Literal, Annotated
|
|
3
2
|
|
|
3
|
+
from typing import Optional, Literal, Annotated
|
|
4
4
|
import typer
|
|
5
|
+
from machineconfig.utils.ssh_utils.abc import MACHINECONFIG_VERSION
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def get_tmp_file():
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
import platform
|
|
11
|
+
from machineconfig.utils.accessories import randstr
|
|
12
|
+
name = randstr(8)
|
|
13
|
+
if platform.system() == "Windows":
|
|
14
|
+
suffix = "ps1"
|
|
15
|
+
else:
|
|
16
|
+
suffix = "sh"
|
|
17
|
+
tmp_file = Path.home().joinpath(f"tmp_results/tmp_files/{name}.{suffix}")
|
|
18
|
+
tmp_file.parent.mkdir(parents=True, exist_ok=True)
|
|
19
|
+
return tmp_file
|
|
5
20
|
|
|
6
21
|
|
|
7
22
|
def main(
|
|
@@ -29,6 +44,7 @@ def main(
|
|
|
29
44
|
"remove-rclone-conflict": "remove-rclone-conflict",
|
|
30
45
|
}
|
|
31
46
|
on_conflict = on_conflict_mapper[on_conflict]
|
|
47
|
+
import platform
|
|
32
48
|
import git
|
|
33
49
|
from rich.console import Console
|
|
34
50
|
from rich.panel import Panel
|
|
@@ -38,10 +54,15 @@ def main(
|
|
|
38
54
|
from machineconfig.utils.source_of_truth import CONFIG_ROOT, DEFAULTS_PATH
|
|
39
55
|
from machineconfig.utils.code import get_uv_command_executing_python_script
|
|
40
56
|
from pathlib import Path
|
|
41
|
-
import platform
|
|
42
57
|
import subprocess
|
|
43
58
|
console = Console()
|
|
44
59
|
|
|
60
|
+
def _bash_single_quote(val: str) -> str:
|
|
61
|
+
return "'" + val.replace("'", "'\"'\"'") + "'"
|
|
62
|
+
|
|
63
|
+
def _ps_single_quote(val: str) -> str:
|
|
64
|
+
return "'" + val.replace("'", "''") + "'"
|
|
65
|
+
|
|
45
66
|
if cloud is None:
|
|
46
67
|
try:
|
|
47
68
|
from machineconfig.utils.io import read_ini
|
|
@@ -57,7 +78,8 @@ def main(
|
|
|
57
78
|
try:
|
|
58
79
|
repo_local_obj = git.Repo(repo_local_root, search_parent_directories=True)
|
|
59
80
|
except git.InvalidGitRepositoryError:
|
|
60
|
-
typer.
|
|
81
|
+
msg = typer.style("Error: ", fg=typer.colors.RED) + f"The specified path '{repo_local_root}' is not a valid git repository."
|
|
82
|
+
typer.echo(msg)
|
|
61
83
|
typer.Exit(code=1)
|
|
62
84
|
return ""
|
|
63
85
|
repo_local_root = PathExtended(repo_local_obj.working_dir) # cwd might have been in a sub directory of repo_root, so its better to redefine it.
|
|
@@ -80,43 +102,89 @@ def main(
|
|
|
80
102
|
if repo_remote_obj.is_dirty():
|
|
81
103
|
console.print(Panel(f"⚠️ WARNING: REMOTE REPOSITORY IS DIRTY\nLocation: {repo_remote_root}\nPlease commit or stash changes before proceeding.", title="Warning", border_style="yellow"))
|
|
82
104
|
|
|
83
|
-
|
|
105
|
+
message_resolved = "sync" if message is None or message.strip() == "" else message
|
|
106
|
+
|
|
107
|
+
repo_local_root_str = str(repo_local_root)
|
|
108
|
+
repo_remote_root_str = str(repo_remote_root)
|
|
109
|
+
|
|
110
|
+
script_bash = f"""
|
|
84
111
|
echo ""
|
|
85
|
-
echo
|
|
86
|
-
cd {
|
|
112
|
+
echo -e "\\033[1;34m═════ COMMITTING LOCAL CHANGES ═════\\033[0m"
|
|
113
|
+
cd {_bash_single_quote(repo_local_root_str)}
|
|
87
114
|
git status
|
|
88
|
-
git add
|
|
89
|
-
git
|
|
115
|
+
git add -A
|
|
116
|
+
if git diff --cached --quiet; then
|
|
117
|
+
echo "-> No staged changes to commit."
|
|
118
|
+
else
|
|
119
|
+
git commit -m {_bash_single_quote(message_resolved)} || true
|
|
120
|
+
fi
|
|
90
121
|
echo ""
|
|
91
122
|
echo ""
|
|
92
|
-
echo
|
|
93
|
-
cd {
|
|
94
|
-
echo
|
|
95
|
-
# git remote remove originEnc
|
|
123
|
+
echo -e "\\033[1;34m═════ PULLING LATEST FROM REMOTE ═════\\033[0m"
|
|
124
|
+
cd {_bash_single_quote(repo_local_root_str)}
|
|
125
|
+
echo "-> Trying to removing originEnc remote from local repo if it exists."
|
|
96
126
|
git remote remove originEnc 2>/dev/null || true
|
|
97
|
-
echo
|
|
98
|
-
git remote add originEnc {
|
|
99
|
-
echo
|
|
127
|
+
echo "-> Adding originEnc remote to local repo"
|
|
128
|
+
git remote add originEnc {_bash_single_quote(repo_remote_root_str)}
|
|
129
|
+
echo "-> Fetching originEnc remote."
|
|
100
130
|
git pull originEnc master
|
|
101
131
|
|
|
102
132
|
"""
|
|
103
133
|
|
|
134
|
+
script_powershell = f"""
|
|
135
|
+
Write-Host ""
|
|
136
|
+
Write-Host "═════ COMMITTING LOCAL CHANGES ═════" -ForegroundColor Blue
|
|
137
|
+
Set-Location -LiteralPath {_ps_single_quote(repo_local_root_str)}
|
|
138
|
+
git status
|
|
139
|
+
git add -A
|
|
140
|
+
git diff --cached --quiet
|
|
141
|
+
if ($LASTEXITCODE -eq 0) {{
|
|
142
|
+
Write-Host "-> No staged changes to commit."
|
|
143
|
+
}} else {{
|
|
144
|
+
git commit -m {_ps_single_quote(message_resolved)}
|
|
145
|
+
if ($LASTEXITCODE -ne 0) {{
|
|
146
|
+
Write-Host "-> Commit skipped/failed (continuing)."
|
|
147
|
+
}}
|
|
148
|
+
}}
|
|
149
|
+
|
|
150
|
+
Write-Host ""
|
|
151
|
+
Write-Host ""
|
|
152
|
+
Write-Host "═════ PULLING LATEST FROM REMOTE ═════" -ForegroundColor Blue
|
|
153
|
+
Set-Location -LiteralPath {_ps_single_quote(repo_local_root_str)}
|
|
154
|
+
Write-Host "-> Trying to remove originEnc remote from local repo if it exists."
|
|
155
|
+
git remote remove originEnc 2>$null
|
|
156
|
+
Write-Host "-> Adding originEnc remote to local repo"
|
|
157
|
+
git remote add originEnc {_ps_single_quote(repo_remote_root_str)}
|
|
158
|
+
Write-Host "-> Fetching originEnc remote."
|
|
159
|
+
git pull originEnc master
|
|
160
|
+
exit $LASTEXITCODE
|
|
161
|
+
"""
|
|
162
|
+
|
|
163
|
+
script = script_powershell if platform.system() == "Windows" else script_bash
|
|
164
|
+
|
|
104
165
|
if Path.home().joinpath("code/machineconfig").exists():
|
|
105
166
|
uv_project_dir = f"""{str(Path.home().joinpath("code/machineconfig"))}"""
|
|
106
167
|
uv_with = None
|
|
107
168
|
else:
|
|
108
|
-
uv_with = [
|
|
169
|
+
uv_with = [MACHINECONFIG_VERSION]
|
|
109
170
|
uv_project_dir = None
|
|
110
171
|
|
|
111
|
-
|
|
112
|
-
shell_path = Path(tempfile.mkstemp(suffix=".ps1" if platform.system() == "Windows" else ".sh")[1])
|
|
172
|
+
shell_path = get_tmp_file()
|
|
113
173
|
shell_path.write_text(script, encoding="utf-8")
|
|
114
|
-
|
|
115
|
-
command = f". {shell_path}"
|
|
116
174
|
if platform.system() == "Windows":
|
|
117
|
-
completed = subprocess.run(
|
|
175
|
+
completed = subprocess.run(
|
|
176
|
+
["powershell", "-ExecutionPolicy", "Bypass", "-File", str(shell_path)],
|
|
177
|
+
capture_output=True,
|
|
178
|
+
check=False,
|
|
179
|
+
text=True,
|
|
180
|
+
)
|
|
118
181
|
else:
|
|
119
|
-
completed = subprocess.run(
|
|
182
|
+
completed = subprocess.run(
|
|
183
|
+
["bash", str(shell_path)],
|
|
184
|
+
capture_output=True,
|
|
185
|
+
check=False,
|
|
186
|
+
text=True,
|
|
187
|
+
)
|
|
120
188
|
res = Response.from_completed_process(completed).capture().print()
|
|
121
189
|
|
|
122
190
|
if res.is_successful(strict_err=True, strict_returcode=True):
|
|
@@ -134,31 +202,37 @@ git pull originEnc master
|
|
|
134
202
|
option1 = "Delete remote copy and push local:"
|
|
135
203
|
from machineconfig.utils.meta import lambda_to_python_script
|
|
136
204
|
def func2(remote_repo: str, local_repo: str, cloud: str):
|
|
137
|
-
from machineconfig.scripts.python.helpers_repos.sync import delete_remote_repo_copy_and_push_local
|
|
205
|
+
from machineconfig.scripts.python.helpers.helpers_repos.sync import delete_remote_repo_copy_and_push_local
|
|
138
206
|
delete_remote_repo_copy_and_push_local(remote_repo=remote_repo, local_repo=local_repo, cloud=cloud)
|
|
139
207
|
program_1_py = lambda_to_python_script(lambda: func2(remote_repo=str(repo_remote_root), local_repo=str(repo_local_root), cloud=str(cloud_resolved)),
|
|
140
208
|
in_global=True, import_module=False)
|
|
141
209
|
program1, _pyfile1 = get_uv_command_executing_python_script(python_script=program_1_py, uv_with=uv_with, uv_project_dir=uv_project_dir)
|
|
142
210
|
# ================================================================================
|
|
211
|
+
|
|
143
212
|
option2 = "Delete local repo and replace it with remote copy:"
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
213
|
+
if platform.system() == "Windows":
|
|
214
|
+
program_2 = f"""
|
|
215
|
+
Remove-Item -LiteralPath {_ps_single_quote(repo_local_root_str)} -Recurse -Force -ErrorAction SilentlyContinue
|
|
216
|
+
Move-Item -LiteralPath {_ps_single_quote(repo_remote_root_str)} -Destination {_ps_single_quote(repo_local_root_str)} -Force
|
|
217
|
+
"""
|
|
218
|
+
else:
|
|
219
|
+
program_2 = f"""
|
|
220
|
+
rm -rfd {_bash_single_quote(repo_local_root_str)}
|
|
221
|
+
mv {_bash_single_quote(repo_remote_root_str)} {_bash_single_quote(repo_local_root_str)}
|
|
222
|
+
"""
|
|
148
223
|
if platform.system() in ["Linux", "Darwin"]:
|
|
149
224
|
program_2 += """
|
|
150
225
|
sudo chmod 600 $HOME/.ssh/*
|
|
151
226
|
sudo chmod 700 $HOME/.ssh
|
|
152
227
|
sudo chmod +x $HOME/dotfiles/scripts/linux -R
|
|
153
228
|
"""
|
|
154
|
-
|
|
155
|
-
shell_file_2 = Path(tempfile.mkstemp(suffix=".ps1" if platform.system() == "Windows" else ".sh")[1])
|
|
229
|
+
shell_file_2 = get_tmp_file()
|
|
156
230
|
shell_file_2.write_text(program_2, encoding="utf-8")
|
|
157
231
|
|
|
158
232
|
# ================================================================================
|
|
159
233
|
option3 = "Inspect repos:"
|
|
160
234
|
def func(repo_local_root: str, repo_remote_root: str):
|
|
161
|
-
from machineconfig.scripts.python.helpers_repos.sync import inspect_repos
|
|
235
|
+
from machineconfig.scripts.python.helpers.helpers_repos.sync import inspect_repos
|
|
162
236
|
inspect_repos(repo_local_root=repo_local_root, repo_remote_root=repo_remote_root)
|
|
163
237
|
# program_3_py = function_to_script(func=func, call_with_kwargs={"repo_local_root": str(repo_local_root), "repo_remote_root": str(repo_remote_root)})
|
|
164
238
|
# shell_file_3 = get_shell_file_executing_python_script(python_script=program_3_py, ve_path=None, executable=executable)
|
|
@@ -168,14 +242,24 @@ sudo chmod +x $HOME/dotfiles/scripts/linux -R
|
|
|
168
242
|
# ================================================================================
|
|
169
243
|
|
|
170
244
|
option4 = "Remove problematic rclone file from repo and replace with remote:"
|
|
171
|
-
|
|
245
|
+
if platform.system() == "Windows":
|
|
246
|
+
program_4 = f"""
|
|
247
|
+
Remove-Item -LiteralPath "$HOME/dotfiles/creds/rclone/rclone.conf" -Force -ErrorAction SilentlyContinue
|
|
248
|
+
New-Item -ItemType Directory -Path "$HOME/dotfiles/creds/rclone" -Force | Out-Null
|
|
249
|
+
Copy-Item -LiteralPath "$HOME/.config/machineconfig/remote/dotfiles/creds/rclone/rclone.conf" -Destination "$HOME/dotfiles/creds/rclone/rclone.conf" -Force
|
|
250
|
+
Set-Location -LiteralPath "$HOME/dotfiles"
|
|
251
|
+
git commit -am "finished merging"
|
|
252
|
+
{program1}
|
|
253
|
+
"""
|
|
254
|
+
else:
|
|
255
|
+
program_4 = f"""
|
|
172
256
|
rm $HOME/dotfiles/creds/rclone/rclone.conf
|
|
173
257
|
cp $HOME/.config/machineconfig/remote/dotfiles/creds/rclone/rclone.conf $HOME/dotfiles/creds/rclone
|
|
174
258
|
cd $HOME/dotfiles
|
|
175
259
|
git commit -am "finished merging"
|
|
176
260
|
{program1}
|
|
177
|
-
"""
|
|
178
|
-
shell_file_4 =
|
|
261
|
+
"""
|
|
262
|
+
shell_file_4 = get_tmp_file()
|
|
179
263
|
shell_file_4.write_text(program_4, encoding="utf-8")
|
|
180
264
|
# ================================================================================
|
|
181
265
|
|
|
@@ -213,6 +297,6 @@ git commit -am "finished merging"
|
|
|
213
297
|
case _:
|
|
214
298
|
raise ValueError(f"Unknown action: {on_conflict}")
|
|
215
299
|
from machineconfig.utils.code import run_shell_script
|
|
216
|
-
run_shell_script(script=program_content)
|
|
300
|
+
run_shell_script(script=program_content, display_script=True, clean_env=False)
|
|
217
301
|
return program_content
|
|
218
302
|
|
|
@@ -169,7 +169,7 @@ def visualize(
|
|
|
169
169
|
if platform.system() == "Windows":
|
|
170
170
|
print(f"⚠️ Portable gource not found at {gource_exe}, installing...")
|
|
171
171
|
install_gource_windows()
|
|
172
|
-
#
|
|
172
|
+
gource_exe = get_gource_executable() # Re-fetch path after installation
|
|
173
173
|
if gource_exe.exists():
|
|
174
174
|
print(f"✅ Gource installed successfully at: {gource_exe}")
|
|
175
175
|
gource_cmd: str = str(gource_exe)
|
|
@@ -177,7 +177,8 @@ def visualize(
|
|
|
177
177
|
print("❌ Installation failed, falling back to system gource")
|
|
178
178
|
raise typer.Exit(1)
|
|
179
179
|
else:
|
|
180
|
-
|
|
180
|
+
print(f"❌ Error: Gource executable not found at {gource_exe}. Please install gource using your package manager.")
|
|
181
|
+
raise typer.Exit(1)
|
|
181
182
|
else:
|
|
182
183
|
gource_cmd = str(gource_exe)
|
|
183
184
|
|