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
|
@@ -3,7 +3,6 @@ from pathlib import Path
|
|
|
3
3
|
from machineconfig.utils.schemas.repos.repos_types import GitVersionInfo, RepoRecordDict, RepoRemote
|
|
4
4
|
|
|
5
5
|
from machineconfig.utils.schemas.repos.repos_types import RepoRecordFile
|
|
6
|
-
from machineconfig.utils.source_of_truth import CONFIG_ROOT
|
|
7
6
|
from machineconfig.utils.io import save_json
|
|
8
7
|
|
|
9
8
|
from typing import Optional
|
|
@@ -12,7 +11,7 @@ from rich import print as pprint
|
|
|
12
11
|
from rich.progress import Progress, TaskID, SpinnerColumn, TextColumn, BarColumn, TimeElapsedColumn, MofNCompleteColumn
|
|
13
12
|
|
|
14
13
|
|
|
15
|
-
def build_tree_structure(repos: list[RepoRecordDict], repos_root:
|
|
14
|
+
def build_tree_structure(repos: list[RepoRecordDict], repos_root: Path) -> str:
|
|
16
15
|
"""Build a tree structure representation of all repositories."""
|
|
17
16
|
if not repos:
|
|
18
17
|
return "No repositories found."
|
|
@@ -186,10 +185,18 @@ def record_repos_recursively(repos_root: str, r: bool, progress: Progress | None
|
|
|
186
185
|
return res
|
|
187
186
|
|
|
188
187
|
|
|
189
|
-
def
|
|
190
|
-
|
|
191
|
-
|
|
188
|
+
def _resolve_directory(directory: Optional[str]) -> Path:
|
|
189
|
+
import typer
|
|
190
|
+
if directory is None:
|
|
191
|
+
directory = Path.cwd().as_posix()
|
|
192
|
+
typer.echo(f"📁 Using directory: {directory}")
|
|
193
|
+
return Path(directory).expanduser().absolute().resolve()
|
|
194
|
+
|
|
192
195
|
|
|
196
|
+
def main_record(repos_root_str: Optional[str]) -> Path:
|
|
197
|
+
print("\n📝 Recording repositories...")
|
|
198
|
+
repos_root = _resolve_directory(directory=repos_root_str)
|
|
199
|
+
|
|
193
200
|
# Count total directories and repositories for accurate progress tracking
|
|
194
201
|
print("🔍 Analyzing directory structure...")
|
|
195
202
|
total_dirs = count_total_directories(str(repos_root), r=True)
|
|
@@ -222,7 +229,7 @@ def main_record(repos_root: Path):
|
|
|
222
229
|
if repos_with_no_remotes:
|
|
223
230
|
print(f"\n⚠️ WARNING: {len(repos_with_no_remotes)} repositories have no remotes configured:")
|
|
224
231
|
for repo in repos_with_no_remotes:
|
|
225
|
-
repo_path =
|
|
232
|
+
repo_path = Path(repo["parentDir"]).joinpath(repo["name"])
|
|
226
233
|
print(f" • {repo['name']} ({repo_path})")
|
|
227
234
|
print(" These repositories may be local-only or have configuration issues.")
|
|
228
235
|
else:
|
|
@@ -231,7 +238,7 @@ def main_record(repos_root: Path):
|
|
|
231
238
|
if dirty_repos:
|
|
232
239
|
print(f"\n⚠️ WARNING: {len(dirty_repos)} repositories have uncommitted changes:")
|
|
233
240
|
for repo in dirty_repos:
|
|
234
|
-
repo_path =
|
|
241
|
+
repo_path = Path(repo["parentDir"]).joinpath(repo["name"])
|
|
235
242
|
print(f" • {repo['name']} ({repo_path}) [branch: {repo['currentBranch']}]")
|
|
236
243
|
print(" These repositories have uncommitted changes that may need attention.")
|
|
237
244
|
else:
|
|
@@ -239,12 +246,25 @@ def main_record(repos_root: Path):
|
|
|
239
246
|
|
|
240
247
|
# Display repository tree structure
|
|
241
248
|
print("\n🌳 Repository Tree Structure:")
|
|
242
|
-
tree_structure = build_tree_structure(repo_records, repos_root)
|
|
249
|
+
tree_structure = build_tree_structure(repos=repo_records, repos_root=repos_root)
|
|
243
250
|
print(tree_structure)
|
|
244
251
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
252
|
+
spec_path_default = Path(repos_root).expanduser().absolute().joinpath("repos.json")
|
|
253
|
+
from machineconfig.scripts.python.helpers.helpers_devops.cli_config_dotfile import get_backup_path, record_mapping
|
|
254
|
+
spec_path_self_managed = get_backup_path(
|
|
255
|
+
orig_path=spec_path_default,
|
|
256
|
+
sensitivity="private",
|
|
257
|
+
destination=None,
|
|
258
|
+
shared=False,
|
|
259
|
+
)
|
|
260
|
+
save_json(obj=res, path=spec_path_self_managed, indent=4)
|
|
261
|
+
pprint(f"📁 Result saved at {PathExtended(spec_path_self_managed)}")
|
|
262
|
+
|
|
263
|
+
# record_mapping(
|
|
264
|
+
# orig_path=spec_path_default,
|
|
265
|
+
|
|
266
|
+
# )
|
|
267
|
+
_ = record_mapping
|
|
268
|
+
|
|
249
269
|
print(">>>>>>>>> Finished Recording")
|
|
250
|
-
return
|
|
270
|
+
return spec_path_self_managed
|
|
@@ -1,13 +1,23 @@
|
|
|
1
1
|
from git import Repo
|
|
2
|
-
from machineconfig.scripts.python.helpers_repos.repo_analyzer_1 import count_python_lines, get_default_branch
|
|
2
|
+
from machineconfig.scripts.python.helpers.helpers_repos.repo_analyzer_1 import count_python_lines, get_default_branch
|
|
3
3
|
from datetime import datetime
|
|
4
4
|
import polars as pl
|
|
5
5
|
from pathlib import Path
|
|
6
|
-
from typing import
|
|
6
|
+
from typing import cast, TypedDict
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
class FileDataRow(TypedDict):
|
|
10
|
+
filename: str
|
|
11
|
+
lines: int
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class CommitDataRow(TypedDict):
|
|
15
|
+
hash: str
|
|
16
|
+
dtmExit: datetime
|
|
17
|
+
lines: int
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def print_python_files_by_size_impl(repo_path: str) -> pl.DataFrame | Exception:
|
|
11
21
|
import plotly.graph_objects as go
|
|
12
22
|
import plotly.express as px
|
|
13
23
|
|
|
@@ -16,7 +26,7 @@ def print_python_files_by_size_impl(repo_path: str) -> "Union[pl.DataFrame, Exce
|
|
|
16
26
|
if not os.path.exists(repo_path):
|
|
17
27
|
return ValueError(f"Repository path does not exist: {repo_path}")
|
|
18
28
|
# Initialize data storage
|
|
19
|
-
file_data:
|
|
29
|
+
file_data: list[FileDataRow] = []
|
|
20
30
|
|
|
21
31
|
# Walk through the repository
|
|
22
32
|
for root, _, files in os.walk(repo_path):
|
|
@@ -66,7 +76,8 @@ def print_python_files_by_size_impl(repo_path: str) -> "Union[pl.DataFrame, Exce
|
|
|
66
76
|
table.add_column("Lines", justify="right")
|
|
67
77
|
|
|
68
78
|
for idx, row in enumerate(df.iter_rows(named=True), 1):
|
|
69
|
-
|
|
79
|
+
typed_row = cast(FileDataRow, row)
|
|
80
|
+
table.add_row(str(idx), typed_row["filename"], f"{typed_row['lines']:,}")
|
|
70
81
|
|
|
71
82
|
console.print(table)
|
|
72
83
|
print(f"\n📁 Total Python files: {file_count}")
|
|
@@ -118,7 +129,7 @@ def print_python_files_by_size_impl(repo_path: str) -> "Union[pl.DataFrame, Exce
|
|
|
118
129
|
)
|
|
119
130
|
|
|
120
131
|
# Define pie chart figure before conditionally using it
|
|
121
|
-
fig2:
|
|
132
|
+
fig2: go.Figure | None = None
|
|
122
133
|
|
|
123
134
|
# Add pie chart showing distribution
|
|
124
135
|
if len(df) > top_n:
|
|
@@ -175,14 +186,15 @@ def analyze_over_time(repo_path: str):
|
|
|
175
186
|
repo: Repo = Repo(repo_path)
|
|
176
187
|
branch_name: str = get_default_branch(repo)
|
|
177
188
|
print(f"🔍 Using branch: {branch_name}")
|
|
178
|
-
commit_data:
|
|
189
|
+
commit_data: list[CommitDataRow] = []
|
|
179
190
|
print("⏳ Analyzing commits...")
|
|
180
191
|
try:
|
|
181
192
|
commits = list(repo.iter_commits(branch_name))
|
|
182
193
|
from datetime import timezone
|
|
183
194
|
from rich.progress import track
|
|
184
195
|
for commit in track(commits, description="Processing commits..."):
|
|
185
|
-
|
|
196
|
+
lines, _files = count_python_lines(commit)
|
|
197
|
+
commit_data.append({"hash": commit.hexsha, "dtmExit": datetime.fromtimestamp(commit.committed_date, tz=timezone.utc), "lines": lines})
|
|
186
198
|
except Exception as e:
|
|
187
199
|
print(f"❌ Error analyzing commits: {str(e)}")
|
|
188
200
|
return
|
|
@@ -199,20 +211,50 @@ def analyze_over_time(repo_path: str):
|
|
|
199
211
|
# Add markers for significant points (min, max, last)
|
|
200
212
|
min_idx = df["lines"].arg_min()
|
|
201
213
|
max_idx = df["lines"].arg_max()
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
214
|
+
last_point = cast(CommitDataRow, df.slice(-1, 1).to_dicts()[0])
|
|
215
|
+
|
|
216
|
+
marker_x: list[datetime] = []
|
|
217
|
+
marker_y: list[int] = []
|
|
218
|
+
marker_sizes: list[int] = []
|
|
219
|
+
marker_colors: list[str] = []
|
|
220
|
+
marker_symbols: list[str] = []
|
|
221
|
+
marker_texts: list[str] = []
|
|
222
|
+
|
|
223
|
+
if min_idx is not None:
|
|
224
|
+
min_point = cast(CommitDataRow, df.slice(min_idx, 1).to_dicts()[0])
|
|
225
|
+
marker_x.append(min_point["dtmExit"])
|
|
226
|
+
marker_y.append(min_point["lines"])
|
|
227
|
+
marker_sizes.append(10)
|
|
228
|
+
marker_colors.append("#ff4f4f")
|
|
229
|
+
marker_symbols.append("circle")
|
|
230
|
+
marker_texts.append(f"🔽 Min: {min_point['lines']:,} lines")
|
|
231
|
+
|
|
232
|
+
if max_idx is not None:
|
|
233
|
+
max_point = cast(CommitDataRow, df.slice(max_idx, 1).to_dicts()[0])
|
|
234
|
+
marker_x.append(max_point["dtmExit"])
|
|
235
|
+
marker_y.append(max_point["lines"])
|
|
236
|
+
marker_sizes.append(14)
|
|
237
|
+
marker_colors.append("#4fff4f")
|
|
238
|
+
marker_symbols.append("star")
|
|
239
|
+
marker_texts.append(f"🔼 Max: {max_point['lines']:,} lines")
|
|
240
|
+
|
|
241
|
+
marker_x.append(last_point["dtmExit"])
|
|
242
|
+
marker_y.append(last_point["lines"])
|
|
243
|
+
marker_sizes.append(12)
|
|
244
|
+
marker_colors.append("#4f4fff")
|
|
245
|
+
marker_symbols.append("diamond")
|
|
246
|
+
marker_texts.append(f"📊 Current: {last_point['lines']:,} lines")
|
|
205
247
|
|
|
206
248
|
# Add markers for significant points
|
|
207
249
|
fig.add_trace(
|
|
208
250
|
go.Scatter(
|
|
209
|
-
x=
|
|
210
|
-
y=
|
|
251
|
+
x=marker_x,
|
|
252
|
+
y=marker_y,
|
|
211
253
|
mode="markers",
|
|
212
|
-
marker={"size":
|
|
254
|
+
marker={"size": marker_sizes, "color": marker_colors, "line": {"width": 2, "color": "white"}, "symbol": marker_symbols},
|
|
213
255
|
name="Key Points",
|
|
214
256
|
hovertemplate="<b>%{text}</b><br>Date: %{x}<br>Lines: %{y:,}<extra></extra>",
|
|
215
|
-
text=
|
|
257
|
+
text=marker_texts,
|
|
216
258
|
)
|
|
217
259
|
)
|
|
218
260
|
|
|
@@ -264,6 +306,8 @@ def analyze_over_time(repo_path: str):
|
|
|
264
306
|
# Print statistics
|
|
265
307
|
print("\n📊 Repository Statistics:")
|
|
266
308
|
print(f"📚 Total commits analyzed: {len(df)}")
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
print(f"
|
|
309
|
+
initial_lines = int(df['lines'][-1])
|
|
310
|
+
final_lines = int(df['lines'][0])
|
|
311
|
+
print(f"🔙 Initial line count: {initial_lines:,}")
|
|
312
|
+
print(f"🔜 Final line count: {final_lines:,}")
|
|
313
|
+
print(f"📈 Net change: {final_lines - initial_lines:,} lines")
|
|
@@ -246,12 +246,6 @@ def update_repository(repo: git.Repo, auto_uv_sync: bool, allow_password_prompt:
|
|
|
246
246
|
result["permissions_updated"] = True
|
|
247
247
|
print(f"✅ Set permissions for {linux_jobs_path}")
|
|
248
248
|
|
|
249
|
-
lf_exe_path = repo_path / "src" / "machineconfig" / "settings" / "lf" / "linux" / "exe"
|
|
250
|
-
if lf_exe_path.exists():
|
|
251
|
-
set_permissions_recursive(lf_exe_path)
|
|
252
|
-
result["permissions_updated"] = True
|
|
253
|
-
print(f"✅ Set permissions for {lf_exe_path}")
|
|
254
|
-
|
|
255
249
|
# Run uv sync if dependencies changed and auto_sync is enabled
|
|
256
250
|
if result["dependencies_changed"] and auto_uv_sync:
|
|
257
251
|
result["uv_sync_ran"] = True
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
|
|
2
|
+
from typing import Literal
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def list_available_scripts(where: Literal["all", "a", "private", "p", "public", "b", "library", "l", "dynamic", "d", "custom", "c"]) -> None:
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from machineconfig.utils.source_of_truth import CONFIG_ROOT, LIBRARY_ROOT, DEFAULTS_PATH
|
|
8
|
+
|
|
9
|
+
private_root = Path.home().joinpath("dotfiles/scripts")
|
|
10
|
+
public_root = CONFIG_ROOT.joinpath("scripts")
|
|
11
|
+
library_root = LIBRARY_ROOT.joinpath("jobs", "scripts")
|
|
12
|
+
|
|
13
|
+
def get_custom_roots() -> list[Path]:
|
|
14
|
+
custom_roots: list[Path] = []
|
|
15
|
+
if DEFAULTS_PATH.is_file():
|
|
16
|
+
from configparser import ConfigParser
|
|
17
|
+
config = ConfigParser()
|
|
18
|
+
config.read(DEFAULTS_PATH)
|
|
19
|
+
if config.has_section("general") and config.has_option("general", "scripts"):
|
|
20
|
+
custom_dirs = config.get("general", "scripts").split(",")
|
|
21
|
+
for custom_dir in custom_dirs:
|
|
22
|
+
custom_path = Path(custom_dir.strip()).expanduser().resolve()
|
|
23
|
+
if custom_path.is_dir():
|
|
24
|
+
custom_roots.append(custom_path)
|
|
25
|
+
return custom_roots
|
|
26
|
+
|
|
27
|
+
locations: dict[str, Path | str] = {}
|
|
28
|
+
match where:
|
|
29
|
+
case "all" | "a":
|
|
30
|
+
locations = {"private": private_root, "public": public_root, "library": library_root}
|
|
31
|
+
for idx, custom in enumerate(get_custom_roots()): locations[f"custom_{idx}"] = custom
|
|
32
|
+
locations["dynamic"] = "https://github.com/thisismygitrepo/machineconfig/tree/main/src/machineconfig/jobs/scripts_dynamic"
|
|
33
|
+
case "private" | "p":
|
|
34
|
+
locations = {"private": private_root}
|
|
35
|
+
case "public" | "b":
|
|
36
|
+
locations = {"public": public_root}
|
|
37
|
+
case "library" | "l":
|
|
38
|
+
locations = {"library": library_root}
|
|
39
|
+
case "dynamic" | "d":
|
|
40
|
+
locations = {"dynamic": "https://github.com/thisismygitrepo/machineconfig/tree/main/src/machineconfig/jobs/scripts_dynamic"}
|
|
41
|
+
case "custom" | "c":
|
|
42
|
+
for idx, custom in enumerate(get_custom_roots()): locations[f"custom_{idx}"] = custom
|
|
43
|
+
|
|
44
|
+
def _print_files_by_type(files: list[str]) -> None:
|
|
45
|
+
categories: dict[str, list[str]] = {".py": [], ".sh": [], ".ps1": [], ".cmd": [], ".bat": [], "other": []}
|
|
46
|
+
for f in files:
|
|
47
|
+
ext = Path(f).suffix.lower() if "." in str(f) else ""
|
|
48
|
+
if ext in categories: categories[ext].append(str(f))
|
|
49
|
+
else: categories["other"].append(str(f))
|
|
50
|
+
for ext, cat_files in categories.items():
|
|
51
|
+
if cat_files:
|
|
52
|
+
label = ext if ext else "other"
|
|
53
|
+
print(f" [{label}]")
|
|
54
|
+
for cf in sorted(cat_files): print(f" • {cf}")
|
|
55
|
+
|
|
56
|
+
for loc_name, loc_path in locations.items():
|
|
57
|
+
print(f"\n📁 {loc_name.upper()} ({loc_path}):")
|
|
58
|
+
print("-" * 60)
|
|
59
|
+
if isinstance(loc_path, Path):
|
|
60
|
+
if loc_path.is_dir():
|
|
61
|
+
files = [f for f in loc_path.rglob("*") if f.is_file() and f.suffix in (".py", ".sh", ".ps1", ".bat", ".cmd", "")]
|
|
62
|
+
if files:
|
|
63
|
+
relative_files = [str(f.relative_to(loc_path)) for f in files]
|
|
64
|
+
_print_files_by_type(relative_files)
|
|
65
|
+
else:
|
|
66
|
+
print(" (empty)")
|
|
67
|
+
else:
|
|
68
|
+
print(" ⚠️ Directory does not exist")
|
|
69
|
+
else:
|
|
70
|
+
api_url = "https://api.github.com/repos/thisismygitrepo/machineconfig/contents/src/machineconfig/jobs/scripts_dynamic"
|
|
71
|
+
try:
|
|
72
|
+
import requests
|
|
73
|
+
response = requests.get(api_url, timeout=10)
|
|
74
|
+
if response.status_code == 200:
|
|
75
|
+
items = response.json()
|
|
76
|
+
files = [item["name"] for item in items if item["type"] == "file"]
|
|
77
|
+
_print_files_by_type(files)
|
|
78
|
+
else:
|
|
79
|
+
print(f" ⚠️ Could not fetch from GitHub (status: {response.status_code})")
|
|
80
|
+
except Exception as e:
|
|
81
|
+
print(f" ⚠️ Could not fetch from GitHub: {e}")
|
|
File without changes
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
"""Pure Python implementations for sessions commands - no typer dependencies."""
|
|
2
|
+
|
|
3
|
+
from typing import Optional, Literal
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def balance_load(
|
|
8
|
+
layout_path: str,
|
|
9
|
+
max_thresh: int,
|
|
10
|
+
thresh_type: Literal["number", "n", "weight", "w"],
|
|
11
|
+
breaking_method: Literal["moreLayouts", "ml", "combineTabs", "ct"],
|
|
12
|
+
output_path: Optional[str],
|
|
13
|
+
) -> None:
|
|
14
|
+
"""Adjust layout file to limit max tabs per layout, etc."""
|
|
15
|
+
thresh_type_resolved: dict[str, Literal["number", "weight"]] = {"number": "number", "n": "number", "weight": "weight", "w": "weight"}
|
|
16
|
+
breaking_method_resolved: dict[str, Literal["moreLayouts", "combineTabs"]] = {"moreLayouts": "moreLayouts", "ml": "moreLayouts", "combineTabs": "combineTabs", "ct": "combineTabs"}
|
|
17
|
+
|
|
18
|
+
layout_path_obj = Path(layout_path).expanduser().absolute()
|
|
19
|
+
|
|
20
|
+
from machineconfig.utils.schemas.layouts.layout_types import LayoutsFile
|
|
21
|
+
import json
|
|
22
|
+
layoutfile: LayoutsFile = json.loads(layout_path_obj.read_text())
|
|
23
|
+
layout_configs = layoutfile["layouts"]
|
|
24
|
+
from machineconfig.cluster.sessions_managers.utils.load_balancer import limit_tab_num
|
|
25
|
+
new_layouts = limit_tab_num(layout_configs=layout_configs, max_thresh=max_thresh, threshold_type=thresh_type_resolved[thresh_type], breaking_method=breaking_method_resolved[breaking_method])
|
|
26
|
+
layoutfile["layouts"] = new_layouts
|
|
27
|
+
target_file = Path(output_path) if output_path is not None else layout_path_obj.parent / f"{layout_path_obj.stem}_adjusted_{max_thresh}_{thresh_type}_{breaking_method}.json"
|
|
28
|
+
target_file.parent.mkdir(parents=True, exist_ok=True)
|
|
29
|
+
target_file.write_text(data=json.dumps(layoutfile, indent=4), encoding="utf-8")
|
|
30
|
+
print(f"Adjusted layout saved to {target_file}")
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def select_layout(layouts_json_file: str, selected_layouts_names: Optional[list[str]], select_interactively: bool, subsitute_home: bool) -> list["LayoutConfig"]: # type: ignore[name-defined]
|
|
34
|
+
"""Select layout(s) from a layout file."""
|
|
35
|
+
import json
|
|
36
|
+
from machineconfig.utils.schemas.layouts.layout_types import LayoutsFile, LayoutConfig
|
|
37
|
+
json_str = Path(layouts_json_file).read_text(encoding="utf-8")
|
|
38
|
+
if subsitute_home:
|
|
39
|
+
json_str = json_str.replace("~", str(Path.home())).replace("$HOME", str(Path.home()))
|
|
40
|
+
json_str = json_str.replace("""Command": "f """, """Command": "~/.config/machineconfig/scripts/wrap_mcfg fire """)
|
|
41
|
+
json_str = json_str.replace("""Command": "s """, """Command": "~/.config/machineconfig/scripts/wrap_mcfg sessions """)
|
|
42
|
+
|
|
43
|
+
try:
|
|
44
|
+
# src/machineconfig/utils/io.py
|
|
45
|
+
layout_file: LayoutsFile = json.loads(json_str)
|
|
46
|
+
except Exception:
|
|
47
|
+
print(f"Failed to parse the json file {layouts_json_file}, trying to clean the comments and giving it another shot ... ")
|
|
48
|
+
from machineconfig.utils.io import remove_c_style_comments
|
|
49
|
+
json_str = remove_c_style_comments(json_str)
|
|
50
|
+
# print(json_str)
|
|
51
|
+
layout_file: LayoutsFile = json.loads(json_str)
|
|
52
|
+
|
|
53
|
+
if len(layout_file["layouts"]) == 0:
|
|
54
|
+
raise ValueError(f"No layouts found in {layouts_json_file}")
|
|
55
|
+
if selected_layouts_names is None:
|
|
56
|
+
if not select_interactively:
|
|
57
|
+
return layout_file["layouts"]
|
|
58
|
+
options = [layout["layoutName"] for layout in layout_file["layouts"]]
|
|
59
|
+
from machineconfig.utils.options import choose_from_options
|
|
60
|
+
selected_layouts_names = choose_from_options(multi=True, options=options, prompt="Choose a layout configuration:", tv=True, msg="Choose one option")
|
|
61
|
+
print(f"Selected layout(s): {selected_layouts_names}")
|
|
62
|
+
layouts_chosen: list[LayoutConfig] = []
|
|
63
|
+
for name in selected_layouts_names:
|
|
64
|
+
layout_chosen = next((layout for layout in layout_file["layouts"] if layout["layoutName"] == name), None)
|
|
65
|
+
if layout_chosen is None:
|
|
66
|
+
layout_chosen = next((layout for layout in layout_file["layouts"] if layout["layoutName"].lower() == name.lower()), None)
|
|
67
|
+
if layout_chosen is None:
|
|
68
|
+
available_layouts = [layout["layoutName"] for layout in layout_file["layouts"]]
|
|
69
|
+
raise ValueError(f"Layout '{name}' not found. Available layouts: {available_layouts}")
|
|
70
|
+
layouts_chosen.append(layout_chosen)
|
|
71
|
+
return layouts_chosen
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def find_layout_file(layout_path: str) -> str:
|
|
75
|
+
"""Find layout file from a path."""
|
|
76
|
+
from machineconfig.utils.path_helper import search_for_files_of_interest, match_file_name, sanitize_path
|
|
77
|
+
from machineconfig.utils.options import choose_from_options
|
|
78
|
+
path_obj = sanitize_path(layout_path)
|
|
79
|
+
if not path_obj.exists():
|
|
80
|
+
choice_file = match_file_name(sub_string=layout_path, search_root=Path.cwd(), suffixes={".json"})
|
|
81
|
+
elif path_obj.is_dir():
|
|
82
|
+
print(f"🔍 Searching recursively for Python, PowerShell and Shell scripts in directory `{path_obj}`")
|
|
83
|
+
files = search_for_files_of_interest(path_obj, suffixes={".py", ".sh", ".ps1"})
|
|
84
|
+
print(f"🔍 Got #{len(files)} results.")
|
|
85
|
+
choice_file = choose_from_options(multi=False, options=files, tv=True, msg="Choose one option")
|
|
86
|
+
choice_file = Path(choice_file).expanduser().absolute()
|
|
87
|
+
else:
|
|
88
|
+
choice_file = path_obj
|
|
89
|
+
return str(choice_file)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def run_layouts(
|
|
93
|
+
layout_path: Optional[str],
|
|
94
|
+
max_tabs: int,
|
|
95
|
+
max_layouts: int,
|
|
96
|
+
sleep_inbetween: float,
|
|
97
|
+
monitor: bool,
|
|
98
|
+
parallel: bool,
|
|
99
|
+
kill_upon_completion: bool,
|
|
100
|
+
choose: Optional[str],
|
|
101
|
+
choose_interactively: bool,
|
|
102
|
+
subsitute_home: bool,
|
|
103
|
+
) -> None:
|
|
104
|
+
"""Launch terminal sessions based on a layout configuration file."""
|
|
105
|
+
if layout_path is None:
|
|
106
|
+
raise ValueError("layout_path is required")
|
|
107
|
+
|
|
108
|
+
layout_path_resolved = find_layout_file(layout_path=layout_path)
|
|
109
|
+
layouts_selected = select_layout(layouts_json_file=layout_path_resolved, selected_layouts_names=choose.split(",") if choose else None, select_interactively=choose_interactively, subsitute_home=subsitute_home)
|
|
110
|
+
|
|
111
|
+
if parallel and len(layouts_selected) > max_layouts:
|
|
112
|
+
raise ValueError(f"Number of layouts {len(layouts_selected)} exceeds the maximum allowed {max_layouts}. Please adjust your layout file.")
|
|
113
|
+
for a_layout in layouts_selected:
|
|
114
|
+
if len(a_layout["layoutTabs"]) > max_tabs:
|
|
115
|
+
raise ValueError(f"Layout '{a_layout.get('layoutName', 'Unnamed')}' has {len(a_layout['layoutTabs'])} tabs which exceeds the max of {max_tabs}.")
|
|
116
|
+
|
|
117
|
+
import time
|
|
118
|
+
import platform
|
|
119
|
+
if platform.system() == "Linux" or platform.system() == "Darwin":
|
|
120
|
+
from machineconfig.cluster.sessions_managers.zellij_local_manager import ZellijLocalManager
|
|
121
|
+
if not parallel:
|
|
122
|
+
iterable = [[item] for item in layouts_selected]
|
|
123
|
+
else:
|
|
124
|
+
iterable = [layouts_selected]
|
|
125
|
+
for i, a_layouts in enumerate(iterable):
|
|
126
|
+
manager = ZellijLocalManager(session_layouts=a_layouts)
|
|
127
|
+
manager.start_all_sessions(poll_interval=2, poll_seconds=2)
|
|
128
|
+
if monitor:
|
|
129
|
+
manager.run_monitoring_routine(wait_ms=2000)
|
|
130
|
+
if kill_upon_completion:
|
|
131
|
+
manager.kill_all_sessions()
|
|
132
|
+
if i < len(layouts_selected) - 1:
|
|
133
|
+
time.sleep(sleep_inbetween)
|
|
134
|
+
elif platform.system() == "Windows":
|
|
135
|
+
from machineconfig.cluster.sessions_managers.wt_local_manager import WTLocalManager
|
|
136
|
+
if not parallel:
|
|
137
|
+
iterable = [[item] for item in layouts_selected]
|
|
138
|
+
else:
|
|
139
|
+
iterable = [layouts_selected]
|
|
140
|
+
for i, a_layouts in enumerate(iterable):
|
|
141
|
+
manager = WTLocalManager(session_layouts=a_layouts)
|
|
142
|
+
manager.start_all_sessions()
|
|
143
|
+
if monitor:
|
|
144
|
+
manager.run_monitoring_routine(wait_ms=2000)
|
|
145
|
+
if kill_upon_completion:
|
|
146
|
+
manager.kill_all_sessions()
|
|
147
|
+
if i < len(layouts_selected) - 1:
|
|
148
|
+
time.sleep(sleep_inbetween)
|
|
149
|
+
else:
|
|
150
|
+
print(f"❌ Unsupported platform: {platform.system()}")
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
def create_template(name: Optional[str], num_tabs: int) -> None:
|
|
154
|
+
"""Create a layout template file."""
|
|
155
|
+
from machineconfig.utils.schemas.layouts.layout_types import LayoutsFile, TabConfig, LayoutConfig
|
|
156
|
+
tabs: list[TabConfig] = []
|
|
157
|
+
for i in range(1, num_tabs + 1):
|
|
158
|
+
tab: TabConfig = {
|
|
159
|
+
"tabName": f"Tab{i}",
|
|
160
|
+
"startDir": "~/" + str(Path.cwd().relative_to(Path.home())),
|
|
161
|
+
"command": "bash",
|
|
162
|
+
}
|
|
163
|
+
tabs.append(tab)
|
|
164
|
+
layouts: list[LayoutConfig] = [
|
|
165
|
+
{
|
|
166
|
+
"layoutName": f"{Path.cwd().name}Layout",
|
|
167
|
+
"layoutTabs": tabs,
|
|
168
|
+
}
|
|
169
|
+
]
|
|
170
|
+
file: LayoutsFile = {
|
|
171
|
+
"$schema": "https://bit.ly/cfglayout", # type: ignore
|
|
172
|
+
"version": "0.1",
|
|
173
|
+
"layouts": layouts,
|
|
174
|
+
}
|
|
175
|
+
import json
|
|
176
|
+
json_string = json.dumps(file, indent=4)
|
|
177
|
+
if name is None:
|
|
178
|
+
layout_path = Path.cwd() / "layout.json"
|
|
179
|
+
else:
|
|
180
|
+
layout_path = Path.cwd() / (name.replace(".json", "") + ".json")
|
|
181
|
+
layout_path.parent.mkdir(parents=True, exist_ok=True)
|
|
182
|
+
if layout_path.exists():
|
|
183
|
+
print(f"❌ File {layout_path} already exists. Aborting to avoid overwriting.")
|
|
184
|
+
return
|
|
185
|
+
layout_path.write_text(json_string, encoding="utf-8")
|
|
186
|
+
print(f"✅ Created layout template at {layout_path}")
|
machineconfig/scripts/python/{helpers_sessions → helpers/helpers_sessions}/sessions_multiprocess.py
RENAMED
|
@@ -15,7 +15,6 @@ def create_from_function(
|
|
|
15
15
|
from machineconfig.utils.accessories import get_repo_root
|
|
16
16
|
from pathlib import Path
|
|
17
17
|
|
|
18
|
-
|
|
19
18
|
path_obj = sanitize_path(path)
|
|
20
19
|
if not path_obj.exists():
|
|
21
20
|
suffixes = {".py"}
|
|
@@ -46,7 +45,7 @@ def create_from_function(
|
|
|
46
45
|
|
|
47
46
|
# ========================= choosing function to run
|
|
48
47
|
if function is None or function.strip() == "":
|
|
49
|
-
from machineconfig.scripts.python.helpers_fire_command.fire_jobs_route_helper import choose_function_or_lines
|
|
48
|
+
from machineconfig.scripts.python.helpers.helpers_fire_command.fire_jobs_route_helper import choose_function_or_lines
|
|
50
49
|
choice_function, choice_file, _kwargs_dict = choose_function_or_lines(choice_file, kwargs_dict={})
|
|
51
50
|
else:
|
|
52
51
|
choice_function = function
|
|
File without changes
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import re
|
|
2
|
+
import subprocess
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
_ANSI_ESCAPE_RE = re.compile(
|
|
7
|
+
r"(?:\x1B|\u001B|\033)\[[0-?]*[ -/]*[@-~]|\[[0-9;?]+[ -/]*[@-~]|\[m"
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def strip_ansi_codes(text: str) -> str:
|
|
12
|
+
return _ANSI_ESCAPE_RE.sub("", text)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def choose_zellij_session(name: str | None, new_session: bool, kill_all: bool) -> tuple[str, str | None]:
|
|
16
|
+
"""Choose a Zellij session. Returns tuple of (action, script_to_run) where action is 'run_script', 'exit', or 'error'."""
|
|
17
|
+
if name is not None:
|
|
18
|
+
return ("run_script", f"zellij attach {name}")
|
|
19
|
+
if new_session:
|
|
20
|
+
cmd = "zellij --layout st2"
|
|
21
|
+
if kill_all:
|
|
22
|
+
cmd = f"zellij kill-all-sessions --yes\n{cmd}"
|
|
23
|
+
return ("run_script", cmd)
|
|
24
|
+
cmd = "zellij list-sessions"
|
|
25
|
+
try:
|
|
26
|
+
sessions: list[str] = subprocess.check_output(cmd, shell=True).decode().strip().split("\n")
|
|
27
|
+
except subprocess.CalledProcessError:
|
|
28
|
+
sessions = []
|
|
29
|
+
sessions = [s for s in sessions if s.strip()]
|
|
30
|
+
# print(f"Found Zellij sessions: {sessions}")
|
|
31
|
+
sessions.sort(key=lambda s: "EXITED" in s)
|
|
32
|
+
if "current" in sessions:
|
|
33
|
+
return ("error", "Already in a Zellij session, avoiding nesting and exiting.")
|
|
34
|
+
if len(sessions) == 0:
|
|
35
|
+
return ("run_script", "zellij --layout st2")
|
|
36
|
+
if len(sessions) == 1:
|
|
37
|
+
sn = strip_ansi_codes(sessions[0])
|
|
38
|
+
session_name = sn.split(" [Created")[0]
|
|
39
|
+
return ("run_script", f"zellij attach {session_name}")
|
|
40
|
+
from machineconfig.utils.options import choose_from_options
|
|
41
|
+
NEW_SESSION_LABEL = "NEW SESSION"
|
|
42
|
+
KILL_ALL_AND_NEW_LABEL = "KILL ALL SESSIONS & START NEW"
|
|
43
|
+
options = sessions + [NEW_SESSION_LABEL, KILL_ALL_AND_NEW_LABEL]
|
|
44
|
+
try:
|
|
45
|
+
session_name = choose_from_options(msg="Choose a Zellij session to attach to:", multi=False, options=options, tv=True)
|
|
46
|
+
except Exception as e:
|
|
47
|
+
return ("error", f"Error choosing Zellij session: {e}")
|
|
48
|
+
if session_name == NEW_SESSION_LABEL:
|
|
49
|
+
cmd = "zellij --layout st2"
|
|
50
|
+
if kill_all:
|
|
51
|
+
cmd = f"zellij kill-all-sessions --yes\n{cmd}"
|
|
52
|
+
return ("run_script", cmd)
|
|
53
|
+
if session_name == KILL_ALL_AND_NEW_LABEL:
|
|
54
|
+
return ("run_script", "zellij kill-all-sessions --yes\nzellij --layout st2")
|
|
55
|
+
session_name_clean = strip_ansi_codes(session_name)
|
|
56
|
+
session_name_clean = session_name_clean.split(" [Created")[0]
|
|
57
|
+
return ("run_script", f"zellij attach {session_name_clean}")
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def get_session_tabs() -> list[tuple[str, str]]:
|
|
61
|
+
cmd = "zellij list-sessions"
|
|
62
|
+
try:
|
|
63
|
+
sessions: list[str] = subprocess.check_output(cmd, shell=True).decode().strip().split("\n")
|
|
64
|
+
except subprocess.CalledProcessError:
|
|
65
|
+
sessions = []
|
|
66
|
+
sessions = [strip_ansi_codes(s) for s in sessions]
|
|
67
|
+
active_sessions = [s for s in sessions if "EXITED" not in s]
|
|
68
|
+
result: list[tuple[str, str]] = []
|
|
69
|
+
for session_line in active_sessions:
|
|
70
|
+
session_name = session_line.split(" [Created")[0].strip()
|
|
71
|
+
tab_cmd = f"zellij --session {session_name} action query-tab-names"
|
|
72
|
+
try:
|
|
73
|
+
tabs: list[str] = subprocess.check_output(tab_cmd, shell=True).decode().strip().split("\n")
|
|
74
|
+
for tab in tabs:
|
|
75
|
+
if tab.strip():
|
|
76
|
+
result.append((session_name, tab.strip()))
|
|
77
|
+
except subprocess.CalledProcessError:
|
|
78
|
+
continue
|
|
79
|
+
return result
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def start_wt(layout_name: str) -> tuple[str, str | None]:
|
|
83
|
+
"""Start a Windows Terminal layout by name. Returns tuple of (status, message) where status is 'success' or 'error'."""
|
|
84
|
+
import json
|
|
85
|
+
from machineconfig.utils.schemas.layouts.layout_types import LayoutsFile
|
|
86
|
+
from machineconfig.cluster.sessions_managers.wt_local import run_wt_layout
|
|
87
|
+
layouts_file = Path.home().joinpath("dotfiles/machineconfig/layouts.json")
|
|
88
|
+
if not layouts_file.exists():
|
|
89
|
+
return ("error", f"❌ Layouts file not found: {layouts_file}")
|
|
90
|
+
layouts_data: LayoutsFile = json.loads(layouts_file.read_text(encoding="utf-8"))
|
|
91
|
+
chosen_layout = next((a_layout for a_layout in layouts_data["layouts"] if a_layout["layoutName"] == layout_name), None)
|
|
92
|
+
if not chosen_layout:
|
|
93
|
+
available_layouts = [a_layout["layoutName"] for a_layout in layouts_data["layouts"]]
|
|
94
|
+
return ("error", f"❌ Layout '{layout_name}' not found in layouts file.\nAvailable layouts: {', '.join(available_layouts)}")
|
|
95
|
+
run_wt_layout(layout_config=chosen_layout)
|
|
96
|
+
return ("success", None)
|
|
@@ -22,7 +22,7 @@ def download(
|
|
|
22
22
|
if output is not None and output_dir is not None:
|
|
23
23
|
typer.echo("❌ Error: --output and --output-dir cannot be used together.", err=True)
|
|
24
24
|
return None
|
|
25
|
-
typer.echo(f"
|
|
25
|
+
typer.echo(f" {url}")
|
|
26
26
|
|
|
27
27
|
def _sanitize_candidate_filename(name: str) -> Optional[str]:
|
|
28
28
|
candidate = Path(name).name.strip()
|
|
@@ -40,7 +40,7 @@ def merge_pdfs(
|
|
|
40
40
|
in_global=True, import_module=False)
|
|
41
41
|
from machineconfig.utils.code import run_shell_script, get_uv_command_executing_python_script
|
|
42
42
|
uv_command, _py_file = get_uv_command_executing_python_script(python_script=code, uv_with=["pypdf"], uv_project_dir=None)
|
|
43
|
-
run_shell_script(uv_command)
|
|
43
|
+
run_shell_script(uv_command, display_script=True, clean_env=False)
|
|
44
44
|
|
|
45
45
|
|
|
46
46
|
def compress_pdf(
|
|
@@ -92,5 +92,5 @@ def compress_pdf(
|
|
|
92
92
|
)
|
|
93
93
|
from machineconfig.utils.code import run_shell_script, get_uv_command_executing_python_script
|
|
94
94
|
uv_command, _py_file = get_uv_command_executing_python_script(python_script=code, uv_with=["pymupdf"], uv_project_dir=None)
|
|
95
|
-
run_shell_script(uv_command)
|
|
95
|
+
run_shell_script(uv_command, display_script=True, clean_env=False)
|
|
96
96
|
|