machineconfig 6.23__py3-none-any.whl → 8.12__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of machineconfig might be problematic. Click here for more details.
- machineconfig/cluster/remote/cloud_manager.py +1 -1
- machineconfig/cluster/remote/distribute.py +0 -1
- machineconfig/cluster/remote/file_manager.py +0 -2
- machineconfig/cluster/sessions_managers/{utils → helpers}/enhanced_command_runner.py +4 -6
- machineconfig/cluster/sessions_managers/utils/load_balancer.py +1 -1
- machineconfig/cluster/sessions_managers/utils/maker.py +69 -0
- machineconfig/cluster/sessions_managers/wt_local.py +16 -221
- machineconfig/cluster/sessions_managers/wt_local_manager.py +55 -193
- machineconfig/cluster/sessions_managers/wt_remote_manager.py +42 -198
- machineconfig/cluster/sessions_managers/wt_utils/manager_persistence.py +52 -0
- machineconfig/cluster/sessions_managers/wt_utils/monitoring_helpers.py +50 -0
- machineconfig/cluster/sessions_managers/wt_utils/status_reporting.py +76 -0
- machineconfig/cluster/sessions_managers/wt_utils/wt_helpers.py +199 -0
- machineconfig/cluster/sessions_managers/zellij_local.py +3 -3
- machineconfig/cluster/sessions_managers/zellij_local_manager.py +5 -3
- machineconfig/cluster/sessions_managers/zellij_remote.py +2 -2
- machineconfig/cluster/sessions_managers/zellij_remote_manager.py +3 -2
- machineconfig/cluster/sessions_managers/zellij_utils/example_usage.py +2 -2
- machineconfig/cluster/sessions_managers/zellij_utils/process_monitor.py +3 -7
- machineconfig/cluster/sessions_managers/{helpers → zellij_utils}/zellij_local_helper_with_panes.py +1 -1
- machineconfig/jobs/installer/check_installations.py +0 -1
- machineconfig/jobs/installer/installer_data.json +1408 -201
- machineconfig/jobs/installer/linux_scripts/q.sh +10 -7
- machineconfig/jobs/installer/linux_scripts/redis.sh +1 -0
- machineconfig/jobs/installer/package_groups.py +63 -92
- machineconfig/jobs/installer/powershell_scripts/install_fonts.ps1 +129 -34
- machineconfig/jobs/installer/python_scripts/boxes.py +61 -0
- machineconfig/jobs/installer/{custom_dev → python_scripts}/brave.py +5 -3
- machineconfig/jobs/installer/python_scripts/cloudflare_warp_cli.py +23 -0
- machineconfig/jobs/installer/{custom_dev → python_scripts}/code.py +4 -1
- machineconfig/jobs/installer/{custom_dev → python_scripts}/dubdb_adbc.py +1 -1
- machineconfig/jobs/installer/{custom → python_scripts}/hx.py +75 -18
- machineconfig/jobs/installer/{custom_dev → python_scripts}/nerdfont.py +2 -2
- machineconfig/jobs/installer/{custom_dev → python_scripts}/nerfont_windows_helper.py +27 -22
- machineconfig/jobs/installer/python_scripts/sysabc.py +139 -0
- machineconfig/jobs/installer/{custom_dev → python_scripts}/wezterm.py +2 -19
- machineconfig/jobs/installer/{custom_dev → python_scripts}/winget.py +10 -14
- machineconfig/jobs/installer/python_scripts/yazi.py +121 -0
- machineconfig/{scripts/python/nw → jobs/scripts/bash_scripts}/mount_nfs +0 -1
- 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 +25 -0
- machineconfig/logger.py +0 -1
- machineconfig/profile/create_helper.py +56 -18
- machineconfig/profile/create_links.py +2 -1
- machineconfig/profile/create_links_export.py +64 -18
- machineconfig/profile/create_shell_profile.py +90 -132
- machineconfig/profile/mapper.toml +18 -8
- machineconfig/scripts/__init__.py +0 -4
- machineconfig/scripts/linux/wrap_mcfg +46 -0
- machineconfig/scripts/nu/wrap_mcfg.nu +69 -0
- machineconfig/scripts/python/agents.py +82 -60
- machineconfig/scripts/python/ai/initai.py +1 -19
- machineconfig/scripts/python/ai/scripts/command_runner.ps1 +33 -0
- machineconfig/scripts/python/ai/{command_runner → scripts}/command_runner.sh +1 -1
- machineconfig/scripts/python/ai/scripts/lint_and_type_check.sh +1 -1
- machineconfig/scripts/python/ai/solutions/copilot/{chatmodes/Thinking-Beast-Mode.chatmode.md → agents/Thinking-Beast-Mode.agent.md} +0 -1
- machineconfig/scripts/python/ai/solutions/copilot/{chatmodes/Ultimate-Transparent-Thinking-Beast-Mode.chatmode.md → agents/Ultimate-Transparent-Thinking-Beast-Mode.agent.md} +0 -1
- machineconfig/scripts/python/ai/solutions/copilot/{chatmodes/deepResearch.chatmode.md → agents/deepResearch.agent.md} +2 -2
- machineconfig/scripts/python/ai/solutions/copilot/github_copilot.py +5 -5
- machineconfig/scripts/python/ai/solutions/copilot/instructions/python/dev.instructions.md +4 -0
- machineconfig/scripts/python/ai/solutions/copilot/instructions/python/watch_exec.prompt.md +20 -0
- machineconfig/scripts/python/ai/solutions/generic.py +1 -1
- machineconfig/scripts/python/ai/{generate_files.py → utils/generate_files.py} +2 -2
- machineconfig/scripts/python/ai/{vscode_tasks.py → utils/vscode_tasks.py} +7 -2
- machineconfig/scripts/python/cloud.py +14 -9
- machineconfig/scripts/python/croshell.py +135 -117
- machineconfig/scripts/python/devops.py +48 -25
- machineconfig/scripts/python/devops_navigator.py +1 -5
- machineconfig/scripts/python/env_manager/env_manager_tui.py +204 -0
- machineconfig/scripts/python/env_manager/path_manager_tui.py +18 -9
- machineconfig/scripts/python/fire_jobs.py +127 -118
- machineconfig/scripts/python/ftpx.py +44 -17
- machineconfig/scripts/python/helpers/ast_search.py +74 -0
- machineconfig/scripts/python/helpers/qr_code.py +166 -0
- machineconfig/scripts/python/helpers/repo_rag.py +325 -0
- machineconfig/scripts/python/helpers/symantic_search.py +25 -0
- machineconfig/scripts/python/{helpers_fire → helpers_agents}/agentic_frameworks/fire_crush.json +1 -1
- machineconfig/scripts/python/helpers_agents/agentic_frameworks/fire_crush.py +39 -0
- machineconfig/scripts/python/{helpers_fire → helpers_agents}/agentic_frameworks/fire_cursor_agents.py +3 -4
- machineconfig/scripts/python/helpers_agents/agentic_frameworks/fire_gemini.py +55 -0
- machineconfig/scripts/python/helpers_agents/agentic_frameworks/fire_qwen.py +30 -0
- machineconfig/scripts/python/{helpers_fire → helpers_agents}/fire_agents_help_launch.py +37 -15
- machineconfig/scripts/python/helpers_agents/fire_agents_helper_types.py +41 -0
- machineconfig/scripts/python/helpers_agents/privacy/configs/aichat/config.yaml +5 -0
- machineconfig/scripts/python/helpers_agents/privacy/configs/aider/.aider.conf.yml +2 -0
- machineconfig/scripts/python/helpers_agents/privacy/configs/copilot/config.yml +1 -0
- machineconfig/scripts/python/helpers_agents/privacy/configs/crush/crush.json +10 -0
- machineconfig/scripts/python/helpers_agents/privacy/configs/gemini/settings.json +12 -0
- machineconfig/scripts/python/helpers_agents/privacy/privacy.py +109 -0
- machineconfig/scripts/python/helpers_agents/templates/prompt.txt +10 -0
- machineconfig/scripts/python/helpers_agents/templates/template.sh +34 -0
- machineconfig/scripts/python/{cloud_helpers → helpers_cloud}/cloud_copy.py +28 -21
- machineconfig/scripts/python/{cloud_helpers → helpers_cloud}/cloud_mount.py +19 -17
- machineconfig/scripts/python/{cloud_helpers → helpers_cloud}/cloud_sync.py +12 -11
- machineconfig/scripts/python/{cloud_helpers → helpers_cloud}/helpers2.py +1 -1
- machineconfig/scripts/python/helpers_croshell/crosh.py +39 -0
- machineconfig/scripts/python/{croshell_helpers → helpers_croshell}/start_slidev.py +6 -7
- machineconfig/scripts/python/helpers_devops/cli_config.py +105 -0
- machineconfig/scripts/python/helpers_devops/cli_config_dotfile.py +89 -0
- machineconfig/scripts/python/helpers_devops/cli_data.py +25 -0
- machineconfig/scripts/python/helpers_devops/cli_nw.py +221 -0
- machineconfig/scripts/python/{devops_helpers → helpers_devops}/cli_repos.py +60 -36
- machineconfig/scripts/python/helpers_devops/cli_self.py +172 -0
- machineconfig/scripts/python/helpers_devops/cli_share_file.py +137 -0
- machineconfig/scripts/python/helpers_devops/cli_share_server.py +142 -0
- machineconfig/scripts/python/{devops_helpers/cli_terminal.py → helpers_devops/cli_share_terminal.py} +15 -17
- machineconfig/scripts/python/{devops_helpers → helpers_devops}/devops_backup_retrieve.py +7 -10
- machineconfig/scripts/python/{devops_helpers → helpers_devops}/devops_status.py +7 -19
- machineconfig/scripts/python/{devops_helpers → helpers_devops}/devops_update_repos.py +1 -1
- machineconfig/scripts/python/helpers_devops/run_script.py +168 -0
- machineconfig/scripts/python/helpers_devops/themes/choose_starship_theme.bash +3 -0
- machineconfig/scripts/python/{devops_helpers → helpers_devops}/themes/choose_wezterm_theme.py +1 -1
- machineconfig/scripts/python/{helpers_fire/helpers4.py → helpers_fire_command/file_wrangler.py} +57 -20
- machineconfig/scripts/python/helpers_fire_command/fire_jobs_args_helper.py +2 -0
- machineconfig/scripts/python/helpers_fire_command/fire_jobs_route_helper.py +26 -16
- machineconfig/scripts/python/helpers_msearch/__init__.py +5 -0
- machineconfig/scripts/{linux → python/helpers_msearch/scripts_linux}/fzfg +3 -3
- machineconfig/scripts/python/helpers_msearch/scripts_windows/fzfg.ps1 +59 -0
- machineconfig/scripts/python/helpers_navigator/__init__.py +20 -0
- machineconfig/scripts/python/{helper_navigator → helpers_navigator}/command_builder.py +1 -1
- machineconfig/scripts/python/{helper_navigator → helpers_navigator}/command_detail.py +1 -1
- machineconfig/scripts/python/{helper_navigator → helpers_navigator}/command_tree.py +160 -23
- machineconfig/scripts/python/{helper_navigator → helpers_navigator}/main_app.py +5 -5
- machineconfig/scripts/python/helpers_network/address.py +176 -0
- machineconfig/scripts/python/helpers_network/address_switch.py +78 -0
- machineconfig/scripts/python/{nw → helpers_network}/mount_nfs.py +2 -2
- machineconfig/scripts/python/{nw → helpers_network}/mount_ssh.py +1 -1
- machineconfig/scripts/python/{nw/devops_add_identity.py → helpers_network/ssh_add_identity.py} +35 -1
- machineconfig/scripts/python/{nw/devops_add_ssh_key.py → helpers_network/ssh_add_ssh_key.py} +26 -7
- machineconfig/scripts/python/{nw → helpers_network}/ssh_debug_linux.py +7 -7
- machineconfig/scripts/python/{nw → helpers_network}/ssh_debug_windows.py +4 -4
- machineconfig/scripts/python/{nw → helpers_network}/wifi_conn.py +1 -53
- machineconfig/scripts/python/helpers_repos/action.py +209 -0
- machineconfig/scripts/python/helpers_repos/action_helper.py +150 -0
- machineconfig/scripts/python/{repos_helpers → helpers_repos}/clone.py +0 -1
- machineconfig/scripts/python/helpers_repos/cloud_repo_sync.py +80 -37
- machineconfig/scripts/python/{repos_helpers → helpers_repos}/entrypoint.py +5 -5
- machineconfig/scripts/python/helpers_repos/grource.py +2 -2
- machineconfig/scripts/python/{repos_helpers → helpers_repos}/record.py +3 -2
- machineconfig/scripts/python/helpers_repos/repo_analyzer_1.py +160 -0
- machineconfig/scripts/python/{repos_helpers/count_lines.py → helpers_repos/repo_analyzer_2.py} +113 -192
- machineconfig/scripts/python/{repos_helpers → helpers_repos}/sync.py +5 -5
- machineconfig/scripts/python/{sessions_helpers → helpers_sessions}/sessions_multiprocess.py +19 -13
- machineconfig/scripts/python/helpers_utils/download.py +150 -0
- machineconfig/scripts/python/helpers_utils/pdf.py +96 -0
- machineconfig/scripts/python/helpers_utils/python.py +187 -0
- machineconfig/scripts/python/interactive.py +26 -35
- machineconfig/scripts/python/{entry.py → mcfg_entry.py} +24 -10
- machineconfig/scripts/python/msearch.py +72 -0
- machineconfig/scripts/python/sessions.py +101 -38
- machineconfig/scripts/python/terminal.py +136 -0
- machineconfig/scripts/python/utils.py +62 -0
- machineconfig/scripts/windows/wrap_mcfg.ps1 +63 -0
- machineconfig/settings/broot/conf.toml +1 -1
- machineconfig/settings/helix/config.toml +16 -0
- machineconfig/settings/helix/languages.toml +13 -4
- machineconfig/settings/helix/yazi-picker.sh +12 -0
- machineconfig/settings/lf/linux/exe/lfcd.sh +1 -0
- machineconfig/settings/lf/linux/exe/previewer.sh +3 -2
- machineconfig/settings/lf/linux/lfrc +10 -11
- machineconfig/settings/lf/windows/lfcd.ps1 +1 -1
- machineconfig/settings/lf/windows/lfrc +15 -17
- machineconfig/settings/lf/windows/mkfile.ps1 +1 -1
- machineconfig/settings/linters/.ruff.toml +1 -1
- machineconfig/settings/marimo/marimo.toml +80 -0
- machineconfig/settings/marimo/snippets/globalize.py +34 -0
- machineconfig/settings/shells/bash/init.sh +57 -10
- machineconfig/settings/shells/ipy/profiles/default/startup/playext.py +1 -1
- machineconfig/settings/shells/nushell/config.nu +2 -35
- machineconfig/settings/shells/nushell/env.nu +45 -6
- machineconfig/settings/shells/nushell/init.nu +314 -0
- machineconfig/settings/shells/pwsh/init.ps1 +59 -23
- machineconfig/settings/shells/starship/starship.toml +16 -0
- machineconfig/settings/shells/wezterm/wezterm.lua +2 -0
- machineconfig/settings/shells/wt/settings.json +32 -17
- machineconfig/settings/shells/zsh/init.sh +89 -0
- machineconfig/settings/television/cable_unix/alias.toml +8 -0
- machineconfig/settings/television/cable_unix/aws-buckets.toml +14 -0
- machineconfig/settings/television/cable_unix/aws-instances.toml +13 -0
- machineconfig/settings/television/cable_unix/bash-history.toml +8 -0
- machineconfig/settings/television/cable_unix/channels.toml +19 -0
- machineconfig/settings/television/cable_unix/dirs.toml +13 -0
- machineconfig/settings/television/cable_unix/distrobox-list.toml +42 -0
- machineconfig/settings/television/cable_unix/docker-images.toml +13 -0
- machineconfig/settings/television/cable_unix/dotfiles.toml +11 -0
- machineconfig/settings/television/cable_unix/env.toml +17 -0
- machineconfig/settings/television/cable_unix/files.toml +11 -0
- machineconfig/settings/television/cable_unix/fish-history.toml +8 -0
- machineconfig/settings/television/cable_unix/git-branch.toml +11 -0
- machineconfig/settings/television/cable_unix/git-diff.toml +10 -0
- machineconfig/settings/television/cable_unix/git-log.toml +12 -0
- machineconfig/settings/television/cable_unix/git-reflog.toml +12 -0
- machineconfig/settings/television/cable_unix/git-repos.toml +16 -0
- machineconfig/settings/television/cable_unix/guix.toml +20 -0
- machineconfig/settings/television/cable_unix/just-recipes.toml +18 -0
- machineconfig/settings/television/cable_unix/k8s-deployments.toml +36 -0
- machineconfig/settings/television/cable_unix/k8s-pods.toml +50 -0
- machineconfig/settings/television/cable_unix/k8s-services.toml +36 -0
- machineconfig/settings/television/cable_unix/man-pages.toml +24 -0
- machineconfig/settings/television/cable_unix/nu-history.toml +7 -0
- machineconfig/settings/television/cable_unix/procs.toml +20 -0
- machineconfig/settings/television/cable_unix/text.toml +17 -0
- machineconfig/settings/television/cable_unix/tldr.toml +18 -0
- machineconfig/settings/television/cable_unix/zsh-history.toml +9 -0
- machineconfig/settings/television/cable_windows/alias.toml +7 -0
- machineconfig/settings/television/cable_windows/dirs.toml +13 -0
- machineconfig/settings/television/cable_windows/docker-images.toml +13 -0
- machineconfig/settings/television/cable_windows/dotfiles.toml +11 -0
- machineconfig/settings/television/cable_windows/env.toml +17 -0
- machineconfig/settings/television/cable_windows/files.toml +14 -0
- machineconfig/settings/television/cable_windows/git-branch.toml +11 -0
- machineconfig/settings/television/cable_windows/git-diff.toml +10 -0
- machineconfig/settings/television/cable_windows/git-log.toml +11 -0
- machineconfig/settings/television/cable_windows/git-reflog.toml +11 -0
- machineconfig/settings/television/cable_windows/git-repos.toml +15 -0
- machineconfig/settings/television/cable_windows/nu-history.toml +7 -0
- machineconfig/settings/television/cable_windows/pwsh-history.toml +6 -0
- machineconfig/settings/television/cable_windows/text.toml +17 -0
- machineconfig/settings/yazi/init.lua +61 -0
- machineconfig/settings/yazi/keymap_linux.toml +94 -0
- machineconfig/settings/yazi/keymap_windows.toml +78 -0
- machineconfig/settings/yazi/shell/yazi_cd.ps1 +33 -0
- machineconfig/settings/yazi/shell/yazi_cd.sh +8 -0
- machineconfig/settings/yazi/theme.toml +4 -0
- machineconfig/settings/yazi/yazi_linux.toml +84 -0
- machineconfig/settings/yazi/yazi_windows.toml +58 -0
- machineconfig/settings/zellij/layouts/st.kdl +39 -8
- machineconfig/setup_linux/__init__.py +2 -2
- machineconfig/setup_linux/apps_desktop.sh +8 -27
- machineconfig/setup_linux/web_shortcuts/interactive.sh +27 -11
- machineconfig/setup_linux/web_shortcuts/live_from_github.sh +31 -0
- machineconfig/setup_mac/__init__.py +16 -0
- machineconfig/setup_mac/apps_gui.sh +248 -0
- machineconfig/setup_mac/ssh/openssh_setup.sh +114 -0
- machineconfig/setup_mac/uv.sh +36 -0
- machineconfig/setup_windows/__init__.py +3 -5
- machineconfig/setup_windows/ssh/openssh-server.ps1 +1 -1
- machineconfig/setup_windows/uv.ps1 +8 -1
- machineconfig/setup_windows/web_shortcuts/interactive.ps1 +26 -10
- machineconfig/setup_windows/web_shortcuts/live_from_github.ps1 +30 -0
- machineconfig/setup_windows/web_shortcuts/quick_init.ps1 +17 -0
- machineconfig/utils/accessories.py +7 -5
- machineconfig/utils/code.py +143 -167
- machineconfig/utils/files/art/fat_croco.txt +10 -0
- machineconfig/utils/files/art/halfwit_croco.txt +9 -0
- machineconfig/utils/files/art/happy_croco.txt +22 -0
- machineconfig/utils/files/art/water_croco.txt +11 -0
- machineconfig/utils/files/ascii_art.py +1 -1
- machineconfig/utils/files/headers.py +6 -11
- machineconfig/utils/files/read.py +3 -9
- machineconfig/utils/installer_utils/github_release_bulk.py +156 -119
- machineconfig/utils/installer_utils/install_from_url.py +183 -0
- machineconfig/utils/installer_utils/installer_class.py +44 -101
- machineconfig/utils/installer_utils/installer_cli.py +175 -0
- machineconfig/utils/installer_utils/installer_helper.py +129 -0
- machineconfig/utils/installer_utils/{installer_abc.py → installer_locator_utils.py} +39 -87
- machineconfig/utils/{installer.py → installer_utils/installer_runner.py} +17 -63
- machineconfig/utils/io.py +77 -4
- machineconfig/utils/links.py +56 -38
- machineconfig/utils/meta.py +235 -145
- machineconfig/utils/options.py +46 -18
- machineconfig/utils/options_tv.py +119 -0
- machineconfig/utils/path_extended.py +46 -97
- machineconfig/utils/path_helper.py +76 -23
- machineconfig/utils/procs.py +10 -23
- machineconfig/utils/scheduler.py +84 -115
- machineconfig/utils/scheduling.py +0 -3
- machineconfig/utils/schemas/fire_agents/fire_agents_input.py +1 -1
- machineconfig/utils/schemas/layouts/layout_types.py +1 -1
- machineconfig/utils/ssh.py +214 -476
- machineconfig/utils/ssh_utils/abc.py +5 -0
- machineconfig/utils/ssh_utils/copy_from_here.py +111 -0
- machineconfig/utils/ssh_utils/copy_to_here.py +303 -0
- machineconfig/utils/ssh_utils/utils.py +142 -0
- machineconfig/utils/ssh_utils/wsl.py +210 -0
- machineconfig/utils/terminal.py +3 -113
- machineconfig/utils/upgrade_packages.py +114 -28
- machineconfig/utils/ve.py +12 -4
- machineconfig-8.12.dist-info/METADATA +132 -0
- machineconfig-8.12.dist-info/RECORD +504 -0
- {machineconfig-6.23.dist-info → machineconfig-8.12.dist-info}/entry_points.txt +5 -1
- machineconfig/jobs/installer/linux_scripts/pgsql.sh +0 -41
- machineconfig/jobs/installer/linux_scripts/timescaledb.sh +0 -71
- machineconfig/jobs/linux/msc/cli_agents.sh +0 -16
- machineconfig/jobs/python/python_ve_symlink.py +0 -37
- machineconfig/jobs/python/vscode/api.py +0 -57
- machineconfig/jobs/windows/archive/archive_pygraphviz.ps1 +0 -12
- machineconfig/jobs/windows/archive/openssh-server_add_key.ps1 +0 -7
- machineconfig/jobs/windows/archive/openssh-server_copy-ssh-id.ps1 +0 -14
- machineconfig/scripts/linux/fzf2g +0 -21
- machineconfig/scripts/linux/fzfag +0 -17
- machineconfig/scripts/linux/fzffg +0 -25
- machineconfig/scripts/linux/fzfrga +0 -21
- machineconfig/scripts/linux/other/share_smb +0 -1
- machineconfig/scripts/linux/other/switch_ip +0 -20
- machineconfig/scripts/linux/skrg +0 -4
- machineconfig/scripts/linux/warp-cli.sh +0 -122
- machineconfig/scripts/linux/z_ls +0 -104
- machineconfig/scripts/python/ai/command_runner/prompt.txt +0 -9
- machineconfig/scripts/python/devops_helpers/cli_config.py +0 -81
- machineconfig/scripts/python/devops_helpers/cli_config_dotfile.py +0 -84
- machineconfig/scripts/python/devops_helpers/cli_data.py +0 -18
- machineconfig/scripts/python/devops_helpers/cli_nw.py +0 -73
- machineconfig/scripts/python/devops_helpers/cli_self.py +0 -117
- machineconfig/scripts/python/devops_helpers/cli_share_server.py +0 -104
- machineconfig/scripts/python/helper_navigator/__init__.py +0 -20
- machineconfig/scripts/python/helpers_fire/agentic_frameworks/fire_crush.py +0 -37
- machineconfig/scripts/python/helpers_fire/agentic_frameworks/fire_gemini.py +0 -44
- machineconfig/scripts/python/helpers_fire/agentic_frameworks/fire_qwen.py +0 -43
- machineconfig/scripts/python/helpers_fire/fire_agents_helper_types.py +0 -30
- machineconfig/scripts/python/helpers_fire/prompt.txt +0 -2
- machineconfig/scripts/python/helpers_fire/template.sh +0 -15
- machineconfig/scripts/python/helpers_repos/secure_repo.py +0 -15
- machineconfig/scripts/python/nw/add_ssh_key.py +0 -148
- machineconfig/scripts/python/nw/wsl_windows_transfer.py +0 -66
- machineconfig/scripts/python/repos_helpers/action.py +0 -378
- machineconfig/scripts/python/repos_helpers/count_lines_frontend.py +0 -17
- machineconfig/scripts/windows/fzfb.ps1 +0 -3
- machineconfig/scripts/windows/fzfg.ps1 +0 -2
- machineconfig/scripts/windows/fzfrga.bat +0 -20
- machineconfig/scripts/windows/mounts/mount_ssh.ps1 +0 -13
- machineconfig/settings/lf/linux/exe/fzf_nano.sh +0 -16
- machineconfig/settings/lf/windows/fzf_edit.ps1 +0 -6
- machineconfig/settings/lf/windows/tst.ps1 +0 -1
- machineconfig/settings/shells/pwsh/profile.ps1 +0 -0
- machineconfig/settings/yazi/keymap.toml +0 -0
- machineconfig/settings/yazi/yazi.toml +0 -4
- machineconfig/setup_linux/apps.sh +0 -66
- machineconfig/setup_linux/nix/cli_installation.sh +0 -137
- machineconfig/setup_linux/ssh/openssh_all.sh +0 -25
- machineconfig/setup_linux/ssh/openssh_wsl.sh +0 -38
- machineconfig/setup_windows/apps.ps1 +0 -62
- machineconfig/setup_windows/others/obs.ps1 +0 -4
- machineconfig/setup_windows/ssh/add_identity.ps1 +0 -11
- machineconfig/setup_windows/wt_and_pwsh/__init__.py +0 -0
- machineconfig/utils/installer_utils/installer.py +0 -225
- machineconfig-6.23.dist-info/METADATA +0 -84
- machineconfig-6.23.dist-info/RECORD +0 -428
- machineconfig/cluster/sessions_managers/{utils → helpers}/load_balancer_helper.py +0 -0
- machineconfig/cluster/sessions_managers/{helpers → zellij_utils}/zellij_local_helper.py +0 -0
- machineconfig/cluster/sessions_managers/{helpers → zellij_utils}/zellij_local_helper_restart.py +0 -0
- machineconfig/cluster/sessions_managers/{helpers → zellij_utils}/zellij_local_manager_helper.py +0 -0
- machineconfig/jobs/installer/linux_scripts/{warp-cli.sh → cloudflare_warp_cli.sh} +0 -0
- machineconfig/jobs/{linux/msc → installer/linux_scripts}/network.sh +0 -0
- machineconfig/jobs/installer/{custom_dev → 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}/cursor.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/{setup_linux/web_shortcuts → jobs/scripts/bash_scripts}/android.sh +0 -0
- machineconfig/jobs/{linux/msc → scripts/bash_scripts}/lid.sh +0 -0
- machineconfig/{setup_linux/others → jobs/scripts/bash_scripts}/mint_keyboard_shortcuts.sh +0 -0
- machineconfig/{scripts/python/nw → jobs/scripts/bash_scripts}/mount_drive +0 -0
- machineconfig/{scripts/python/nw → jobs/scripts/bash_scripts}/mount_nw_drive +0 -0
- machineconfig/{scripts/python/nw → 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 → 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/{jobs/python → scripts/python/ai/utils}/__init__.py +0 -0
- machineconfig/scripts/python/{cloud_helpers → helpers_agents}/__init__.py +0 -0
- machineconfig/scripts/python/{croshell_helpers → helpers_agents/agentic_frameworks}/__init__.py +0 -0
- machineconfig/scripts/python/{helpers_fire → helpers_agents}/fire_agents_help_search.py +0 -0
- machineconfig/scripts/python/{helpers_fire → helpers_agents}/fire_agents_load_balancer.py +0 -0
- machineconfig/scripts/python/{helpers_fire → helpers_agents/templates}/template.ps1 +0 -0
- machineconfig/scripts/python/{devops_helpers → helpers_cloud}/__init__.py +0 -0
- machineconfig/scripts/python/{cloud_helpers → helpers_cloud}/cloud_helpers.py +1 -1
- /machineconfig/scripts/python/{cloud_helpers → helpers_cloud}/helpers5.py +0 -0
- /machineconfig/scripts/python/{devops_helpers/themes → helpers_croshell}/__init__.py +0 -0
- /machineconfig/scripts/python/{croshell_helpers → helpers_croshell}/pomodoro.py +0 -0
- /machineconfig/scripts/python/{croshell_helpers → helpers_croshell}/scheduler.py +0 -0
- /machineconfig/scripts/python/{croshell_helpers → helpers_croshell}/viewer.py +0 -0
- /machineconfig/scripts/python/{croshell_helpers → helpers_croshell}/viewer_template.py +0 -0
- /machineconfig/scripts/python/{helpers_fire → helpers_devops}/__init__.py +0 -0
- /machineconfig/scripts/python/{helpers_fire/agentic_frameworks → helpers_devops/themes}/__init__.py +0 -0
- /machineconfig/scripts/python/{devops_helpers → helpers_devops}/themes/choose_pwsh_theme.ps1 +0 -0
- /machineconfig/{jobs/windows/msc/cli_agents.bat → scripts/python/helpers_devops/themes/choose_starship_theme.ps1} +0 -0
- /machineconfig/{jobs/windows/msc/cli_agents.ps1 → scripts/python/helpers_fire_command/f.py} +0 -0
- /machineconfig/scripts/python/{helper_navigator → helpers_navigator}/data_models.py +0 -0
- /machineconfig/scripts/python/{helper_navigator → helpers_navigator}/search_bar.py +0 -0
- /machineconfig/scripts/python/{helpers_repos → helpers_network}/__init__.py +0 -0
- /machineconfig/scripts/python/{nw → helpers_network}/mount_nw_drive.py +0 -0
- /machineconfig/scripts/python/{nw → helpers_network}/onetimeshare.py +0 -0
- /machineconfig/scripts/python/{repos_helpers → helpers_repos}/update.py +0 -0
- /machineconfig/scripts/python/{nw → helpers_sessions}/__init__.py +0 -0
- /machineconfig/{scripts/python/sessions_helpers → settings/wt}/__init__.py +0 -0
- /machineconfig/{setup_windows/wt_and_pwsh → settings/wt}/set_wt_settings.py +0 -0
- {machineconfig-6.23.dist-info → machineconfig-8.12.dist-info}/WHEEL +0 -0
- {machineconfig-6.23.dist-info → machineconfig-8.12.dist-info}/top_level.txt +0 -0
machineconfig/utils/meta.py
CHANGED
|
@@ -1,166 +1,256 @@
|
|
|
1
1
|
"""Metaprogramming utilities for analyzing and serializing Python functions."""
|
|
2
2
|
|
|
3
|
-
import
|
|
4
|
-
import inspect
|
|
5
|
-
import textwrap
|
|
6
|
-
from types import FunctionType, ModuleType
|
|
3
|
+
from collections.abc import Callable
|
|
7
4
|
from typing import Any
|
|
8
5
|
|
|
9
6
|
|
|
10
|
-
def
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
7
|
+
def get_import_module_string(py_file: str) -> str:
|
|
8
|
+
from machineconfig.scripts.python.helpers_fire_command.file_wrangler import get_import_module_code
|
|
9
|
+
from machineconfig.utils.accessories import get_repo_root
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
repo_root = get_repo_root(Path(py_file))
|
|
12
|
+
import_line = get_import_module_code(py_file)
|
|
13
|
+
if repo_root is not None:
|
|
14
|
+
repo_root_add = f"""sys.path.append(r'{repo_root}')"""
|
|
15
|
+
else:
|
|
16
|
+
repo_root_add = ""
|
|
17
|
+
txt: str = f"""
|
|
18
|
+
try:
|
|
19
|
+
{import_line}
|
|
20
|
+
except (ImportError, ModuleNotFoundError) as ex:
|
|
21
|
+
print(fr"❌ Failed to import `{py_file}` as a module: {{ex}} ")
|
|
22
|
+
print(fr"⚠️ Attempting import with ad-hoc `$PATH` manipulation. DO NOT pickle any objects in this session as correct deserialization cannot be guaranteed.")
|
|
23
|
+
import sys
|
|
24
|
+
sys.path.append(r'{Path(py_file).parent}')
|
|
25
|
+
{repo_root_add}
|
|
26
|
+
from {Path(py_file).stem} import *
|
|
27
|
+
print(fr"✅ Successfully imported `{py_file}`")
|
|
28
|
+
"""
|
|
29
|
+
return txt
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def lambda_to_python_script(lmb: Callable[[], Any],
|
|
33
|
+
in_global: bool, import_module: bool) -> str:
|
|
34
|
+
"""
|
|
35
|
+
caveats: always use keyword arguments in the lambda call for best results.
|
|
36
|
+
return statement not allowed in the wrapped function (otherwise it can be put in the global space)
|
|
37
|
+
type hint in kwargs has nothing that is not built in, e.g. Optional will not work as it requires an import.
|
|
38
|
+
|
|
39
|
+
Given a no-arg lambda like `lambda: func(a=var1, b=var2)`,
|
|
40
|
+
return a string containing the full function definition of `func`
|
|
41
|
+
but with the defaults for the parameters provided in the call replaced
|
|
42
|
+
by the *actual* values (repr) taken from the lambda's globals.
|
|
43
|
+
|
|
44
|
+
All imports are local to this function.
|
|
16
45
|
|
|
17
46
|
Args:
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
Returns:
|
|
23
|
-
A complete Python script as a string that can be executed independently
|
|
24
|
-
|
|
25
|
-
Raises:
|
|
26
|
-
ValueError: If the function cannot be inspected or analyzed
|
|
47
|
+
lmb: A lambda function with no arguments
|
|
48
|
+
in_global: If True, return kwargs as global variable assignments followed by dedented body.
|
|
49
|
+
If False, return the full function definition with updated defaults.
|
|
50
|
+
import_module: When True, prepend module import bootstrap code for the function's source file.
|
|
27
51
|
"""
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
imports = _extract_imports(func)
|
|
35
|
-
globals_needed = _extract_globals(func)
|
|
36
|
-
source_code = _get_function_source(func)
|
|
37
|
-
call_statement = _generate_call_statement(func, call_with_args, call_with_kwargs)
|
|
38
|
-
|
|
39
|
-
script_parts: list[str] = []
|
|
40
|
-
|
|
41
|
-
if imports:
|
|
42
|
-
script_parts.append(imports)
|
|
43
|
-
script_parts.append("")
|
|
44
|
-
|
|
45
|
-
if globals_needed:
|
|
46
|
-
script_parts.append(globals_needed)
|
|
47
|
-
script_parts.append("")
|
|
48
|
-
|
|
49
|
-
script_parts.append(source_code)
|
|
50
|
-
script_parts.append("")
|
|
51
|
-
|
|
52
|
-
if call_statement:
|
|
53
|
-
script_parts.append("")
|
|
54
|
-
script_parts.append("if __name__ == '__main__':")
|
|
55
|
-
script_parts.append(f" {call_statement}")
|
|
56
|
-
|
|
57
|
-
return "\n".join(script_parts)
|
|
52
|
+
# local imports
|
|
53
|
+
import inspect as _inspect
|
|
54
|
+
import ast as _ast
|
|
55
|
+
import textwrap as _textwrap
|
|
56
|
+
import types as _types
|
|
57
|
+
from pathlib import Path as _Path
|
|
58
58
|
|
|
59
|
+
def _stringify_annotation(annotation: Any) -> Any:
|
|
60
|
+
if annotation is _inspect.Signature.empty or annotation is _inspect.Parameter.empty:
|
|
61
|
+
return annotation
|
|
62
|
+
if isinstance(annotation, str):
|
|
63
|
+
return annotation
|
|
64
|
+
try:
|
|
65
|
+
return _inspect.formatannotation(annotation)
|
|
66
|
+
except Exception:
|
|
67
|
+
return str(annotation)
|
|
59
68
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
69
|
+
# sanity checks
|
|
70
|
+
if not (callable(lmb) and isinstance(lmb, _types.LambdaType)):
|
|
71
|
+
raise TypeError("Expected a lambda function object")
|
|
72
|
+
|
|
73
|
+
src = _inspect.getsource(lmb)
|
|
74
|
+
src = _textwrap.dedent(src)
|
|
75
|
+
tree = _ast.parse(src)
|
|
67
76
|
|
|
77
|
+
# find first Lambda node
|
|
78
|
+
lambda_node = None
|
|
79
|
+
for n in _ast.walk(tree):
|
|
80
|
+
if isinstance(n, _ast.Lambda):
|
|
81
|
+
lambda_node = n
|
|
82
|
+
break
|
|
83
|
+
if lambda_node is None:
|
|
84
|
+
raise ValueError("Could not find a lambda expression in source")
|
|
68
85
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
86
|
+
body = lambda_node.body
|
|
87
|
+
if not isinstance(body, _ast.Call):
|
|
88
|
+
raise ValueError("Lambda body is not a call expression")
|
|
89
|
+
|
|
90
|
+
globals_dict = getattr(lmb, "__globals__", {})
|
|
72
91
|
|
|
73
|
-
|
|
74
|
-
|
|
92
|
+
# Also capture closure variables from the lambda
|
|
93
|
+
closure_dict: dict[str, Any] = {}
|
|
94
|
+
if lmb.__closure__:
|
|
95
|
+
code_obj = lmb.__code__
|
|
96
|
+
freevars = code_obj.co_freevars
|
|
97
|
+
for i, var_name in enumerate(freevars):
|
|
98
|
+
closure_dict[var_name] = lmb.__closure__[i].cell_contents
|
|
75
99
|
|
|
100
|
+
# Merge globals and closures (closures take precedence for shadowing)
|
|
101
|
+
eval_namespace = {**globals_dict, **closure_dict}
|
|
102
|
+
|
|
103
|
+
# resolve the function object being called
|
|
76
104
|
try:
|
|
77
|
-
|
|
78
|
-
except
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
used_names.add(node.id)
|
|
85
|
-
elif isinstance(node, ast.Attribute):
|
|
86
|
-
if isinstance(node.value, ast.Name):
|
|
87
|
-
used_names.add(node.value.id)
|
|
88
|
-
|
|
89
|
-
for name in used_names:
|
|
90
|
-
if name in func_globals:
|
|
91
|
-
obj = func_globals[name]
|
|
92
|
-
|
|
93
|
-
if isinstance(obj, ModuleType):
|
|
94
|
-
module_name = obj.__name__
|
|
95
|
-
if name == module_name.split('.')[-1]:
|
|
96
|
-
import_statements.add(f"import {module_name}")
|
|
97
|
-
else:
|
|
98
|
-
import_statements.add(f"import {module_name} as {name}")
|
|
99
|
-
|
|
100
|
-
elif hasattr(obj, '__module__') and obj.__module__ != '__main__':
|
|
101
|
-
try:
|
|
102
|
-
module_name = obj.__module__
|
|
103
|
-
obj_name = obj.__name__ if hasattr(obj, '__name__') else name
|
|
104
|
-
|
|
105
|
-
if module_name and module_name != 'builtins':
|
|
106
|
-
if obj_name == name:
|
|
107
|
-
import_statements.add(f"from {module_name} import {obj_name}")
|
|
108
|
-
else:
|
|
109
|
-
import_statements.add(f"from {module_name} import {obj_name} as {name}")
|
|
110
|
-
except AttributeError:
|
|
111
|
-
pass
|
|
112
|
-
|
|
113
|
-
return "\n".join(sorted(import_statements))
|
|
105
|
+
func_ref_src = _ast.unparse(body.func)
|
|
106
|
+
except AttributeError:
|
|
107
|
+
func_ref_src = _ast.get_source_segment(src, body.func) or ""
|
|
108
|
+
try:
|
|
109
|
+
func_obj = eval(func_ref_src, eval_namespace)
|
|
110
|
+
except Exception as e:
|
|
111
|
+
raise RuntimeError(f"Could not resolve function reference '{func_ref_src}': {e}")
|
|
114
112
|
|
|
113
|
+
if not callable(func_obj):
|
|
114
|
+
raise TypeError("Resolved object is not callable")
|
|
115
115
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
116
|
+
func_name = getattr(func_obj, "__name__", "<unknown>")
|
|
117
|
+
|
|
118
|
+
import_prefix: str = ""
|
|
119
|
+
if import_module:
|
|
120
|
+
module_file = _inspect.getsourcefile(func_obj)
|
|
121
|
+
module_path_candidate: str = module_file if module_file is not None else _inspect.getfile(func_obj)
|
|
122
|
+
import_prefix = get_import_module_string(str(_Path(module_path_candidate)))
|
|
123
|
+
|
|
124
|
+
# Evaluate each keyword argument value in the lambda's globals to get real Python objects
|
|
125
|
+
call_kwargs: dict[str, Any] = {}
|
|
126
|
+
for kw in body.keywords:
|
|
127
|
+
if kw.arg is None:
|
|
128
|
+
# **kwargs in call — evaluate to dict and merge
|
|
129
|
+
try:
|
|
130
|
+
val = eval(compile(_ast.Expression(kw.value), "<lambda_eval>", "eval"), eval_namespace)
|
|
131
|
+
if isinstance(val, dict):
|
|
132
|
+
call_kwargs.update(val)
|
|
133
|
+
else:
|
|
134
|
+
raise ValueError("Keyword expansion did not evaluate to a dict")
|
|
135
|
+
except Exception as e:
|
|
136
|
+
raise RuntimeError(f"Failed to evaluate **kwargs expression: {e}")
|
|
137
|
+
else:
|
|
138
|
+
try:
|
|
139
|
+
val = eval(compile(_ast.Expression(kw.value), "<lambda_eval>", "eval"), eval_namespace)
|
|
140
|
+
call_kwargs[kw.arg] = val
|
|
141
|
+
except Exception as e:
|
|
142
|
+
raise RuntimeError(f"Failed to evaluate value for kw '{kw.arg}': {e}")
|
|
143
|
+
|
|
144
|
+
# Try to get original source and dedent it for body extraction
|
|
123
145
|
try:
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
146
|
+
orig_src = _inspect.getsource(func_obj)
|
|
147
|
+
ded = _textwrap.dedent(orig_src)
|
|
148
|
+
lines = ded.splitlines()
|
|
149
|
+
def_index = None
|
|
150
|
+
for i, ln in enumerate(lines):
|
|
151
|
+
if ln.lstrip().startswith(f"def {func_name}("):
|
|
152
|
+
def_index = i
|
|
153
|
+
break
|
|
154
|
+
if def_index is None:
|
|
155
|
+
body_lines = ded.splitlines()
|
|
156
|
+
else:
|
|
157
|
+
signature_end_index = None
|
|
158
|
+
for i in range(def_index, len(lines)):
|
|
159
|
+
line_no_comment = lines[i].split("#", 1)[0].rstrip()
|
|
160
|
+
if line_no_comment.endswith(":"):
|
|
161
|
+
signature_end_index = i
|
|
162
|
+
break
|
|
163
|
+
if signature_end_index is None:
|
|
164
|
+
body_lines = lines[def_index + 1 :]
|
|
165
|
+
else:
|
|
166
|
+
body_lines = lines[signature_end_index + 1 :]
|
|
167
|
+
# ensure we have a body, otherwise use pass
|
|
168
|
+
if not any(line.strip() for line in body_lines):
|
|
169
|
+
body_text = " pass\n"
|
|
170
|
+
else:
|
|
171
|
+
joined_body = "\n".join(body_lines)
|
|
172
|
+
if not joined_body.endswith("\n"):
|
|
173
|
+
joined_body = f"{joined_body}\n"
|
|
174
|
+
body_text = joined_body
|
|
175
|
+
except (OSError, IOError, TypeError):
|
|
176
|
+
body_text = " pass\n"
|
|
177
|
+
|
|
178
|
+
# Build a replaced signature using inspect.signature
|
|
179
|
+
sig = _inspect.signature(func_obj)
|
|
180
|
+
new_params: list[_inspect.Parameter] = []
|
|
181
|
+
for name, param in sig.parameters.items():
|
|
182
|
+
# If the call provided a value for this parameter, replace default
|
|
183
|
+
if name in call_kwargs:
|
|
184
|
+
new_default = call_kwargs[name]
|
|
185
|
+
else:
|
|
186
|
+
new_default = param.default
|
|
187
|
+
|
|
188
|
+
normalized_annotation = _stringify_annotation(param.annotation)
|
|
189
|
+
|
|
190
|
+
if new_default is _inspect.Parameter.empty:
|
|
191
|
+
new_param = _inspect.Parameter(name, param.kind, annotation=normalized_annotation)
|
|
192
|
+
else:
|
|
193
|
+
new_param = _inspect.Parameter(
|
|
194
|
+
name, param.kind, default=new_default, annotation=normalized_annotation
|
|
195
|
+
)
|
|
196
|
+
new_params.append(new_param)
|
|
197
|
+
|
|
198
|
+
return_annotation = _stringify_annotation(sig.return_annotation)
|
|
199
|
+
new_sig = _inspect.Signature(parameters=new_params, return_annotation=return_annotation)
|
|
200
|
+
|
|
201
|
+
# If in_global mode, return kwargs as global assignments + dedented body
|
|
202
|
+
if in_global:
|
|
203
|
+
global_assignments: list[str] = []
|
|
204
|
+
for name, param in sig.parameters.items():
|
|
205
|
+
# Get the value from call_kwargs if provided, else use original default
|
|
206
|
+
if name in call_kwargs:
|
|
207
|
+
value = call_kwargs[name]
|
|
208
|
+
elif param.default is not _inspect.Parameter.empty:
|
|
209
|
+
value = param.default
|
|
210
|
+
else:
|
|
211
|
+
# No value provided and no default - skip this parameter
|
|
212
|
+
continue
|
|
139
213
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
214
|
+
# Build type annotation string if available
|
|
215
|
+
if param.annotation is not _inspect.Parameter.empty:
|
|
216
|
+
annotation_literal = _stringify_annotation(param.annotation)
|
|
217
|
+
if isinstance(annotation_literal, str):
|
|
218
|
+
global_assignments.append(f"{name}: {repr(annotation_literal)} = {repr(value)}")
|
|
219
|
+
else:
|
|
220
|
+
global_assignments.append(f"{name} = {repr(value)}")
|
|
221
|
+
else:
|
|
222
|
+
global_assignments.append(f"{name} = {repr(value)}")
|
|
223
|
+
|
|
224
|
+
# Dedent the body text to remove function indentation
|
|
225
|
+
dedented_body = _textwrap.dedent(body_text).rstrip()
|
|
226
|
+
|
|
227
|
+
# Combine global assignments and body
|
|
228
|
+
if global_assignments:
|
|
229
|
+
result_parts: list[str] = ["\n".join(global_assignments), "", dedented_body]
|
|
230
|
+
result_text = "\n".join(result_parts)
|
|
231
|
+
else:
|
|
232
|
+
result_text = dedented_body
|
|
233
|
+
else:
|
|
234
|
+
header = f"def {func_name}{new_sig}:\n"
|
|
235
|
+
result_text = header + body_text
|
|
150
236
|
|
|
237
|
+
if in_global:
|
|
238
|
+
lines = result_text.splitlines()
|
|
239
|
+
if lines[-1].startswith("return "):
|
|
240
|
+
lines[-1] = lines[-1].replace("return ", "# return ", 1)
|
|
241
|
+
result_text = "\n".join(lines)
|
|
151
242
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
if
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
return f"{func.__name__}({args_str})"
|
|
243
|
+
if "Optional" in result_text or "Any" in result_text or "Union" in result_text or "Literal" in result_text:
|
|
244
|
+
result_text = "from typing import Optional, Any, Union, Literal\n\n" + result_text
|
|
245
|
+
if import_prefix:
|
|
246
|
+
result_text = f"{import_prefix}{result_text}"
|
|
247
|
+
return result_text
|
|
248
|
+
|
|
249
|
+
if __name__ == "__main__":
|
|
250
|
+
from machineconfig.utils.code import print_code
|
|
251
|
+
import_code_robust = "<import_code_robust>"
|
|
252
|
+
res = lambda_to_python_script(
|
|
253
|
+
lambda: print_code(code=import_code_robust, lexer="python", desc="import as module code"),
|
|
254
|
+
in_global=True, import_module=False
|
|
255
|
+
)
|
|
256
|
+
print(res)
|
machineconfig/utils/options.py
CHANGED
|
@@ -1,38 +1,66 @@
|
|
|
1
|
+
|
|
1
2
|
from pathlib import Path
|
|
2
|
-
from machineconfig.utils.installer_utils.installer_abc import check_tool_exists
|
|
3
3
|
from rich.text import Text
|
|
4
4
|
from rich.panel import Panel
|
|
5
5
|
from rich.console import Console
|
|
6
6
|
import subprocess
|
|
7
|
-
from typing import Optional, Union, Iterable, overload, Literal
|
|
7
|
+
from typing import Optional, Union, Iterable, overload, Literal, cast
|
|
8
8
|
|
|
9
9
|
@overload
|
|
10
|
-
def choose_from_options[T](
|
|
10
|
+
def choose_from_options[T](options: Iterable[T], msg: str, multi: Literal[False], custom_input: bool = False, header: str = "", tail: str = "", prompt: str = "", default: Optional[T] = None, tv: bool = False) -> T: ...
|
|
11
11
|
@overload
|
|
12
|
-
def choose_from_options[T](
|
|
13
|
-
def choose_from_options[T](
|
|
12
|
+
def choose_from_options[T](options: Iterable[T], msg: str, multi: Literal[True], custom_input: bool = True, header: str = "", tail: str = "", prompt: str = "", default: Optional[T] = None, tv: bool = False, ) -> list[T]: ...
|
|
13
|
+
def choose_from_options[T](options: Iterable[T], msg: str, multi: bool, custom_input: bool = True, header: str = "", tail: str = "", prompt: str = "", default: Optional[T] = None, tv: bool = False, ) -> Union[T, list[T]]:
|
|
14
14
|
# TODO: replace with https://github.com/tmbo/questionary
|
|
15
15
|
# # also see https://github.com/charmbracelet/gum
|
|
16
16
|
options_strings: list[str] = [str(x) for x in options]
|
|
17
17
|
default_string = str(default) if default is not None else None
|
|
18
18
|
console = Console()
|
|
19
|
-
|
|
20
|
-
#
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
#
|
|
19
|
+
from machineconfig.utils.installer_utils.installer_locator_utils import check_tool_exists
|
|
20
|
+
# from machineconfig.utils.installer_utils.installer_cli import check_tool_exists
|
|
21
|
+
# print("ch1")
|
|
22
|
+
if tv and check_tool_exists("tv"):
|
|
23
|
+
# from pyfzf.pyfzf import FzfPrompt
|
|
24
|
+
# fzf_prompt = FzfPrompt()
|
|
25
|
+
# nl = "\n"
|
|
26
|
+
# choice_string_multi: list[str] = fzf_prompt.prompt(choices=options_strings, fzf_options=("--multi" if multi else "") + f' --prompt "{prompt.replace(nl, " ")}" --ansi') # --border-label={msg.replace(nl, ' ')}")
|
|
27
|
+
# print("ch2")
|
|
28
|
+
from machineconfig.utils.accessories import randstr
|
|
29
|
+
options_txt_path = Path.home().joinpath("tmp_results/tmp_files/choices_" + randstr(6) + ".txt")
|
|
30
|
+
options_txt_path.parent.mkdir(parents=True, exist_ok=True)
|
|
31
|
+
options_txt_path.write_text("\n".join(options_strings), encoding="utf-8")
|
|
32
|
+
|
|
33
|
+
# Run `tv` interactively so the user can make selections. We redirect tv's
|
|
34
|
+
# stdout to a temporary output file so we can read the chosen lines after
|
|
35
|
+
# the interactive session completes. Do not capture_output or redirect
|
|
36
|
+
# stdin/stderr here so `tv` stays attached to the terminal.
|
|
37
|
+
tv_out_path = options_txt_path.with_name(options_txt_path.stem + "_out.txt")
|
|
38
|
+
tv_cmd = f"""cat {options_txt_path} | tv --ansi true --source-output "{{strip_ansi}}" > {tv_out_path}"""
|
|
39
|
+
res = subprocess.run(tv_cmd, shell=True)
|
|
40
|
+
|
|
41
|
+
# If tv returned a non-zero code and there is no output file, treat it as an error.
|
|
42
|
+
if res.returncode != 0 and not tv_out_path.exists():
|
|
43
|
+
raise RuntimeError(f"Got error running tv command: {tv_cmd}\nreturncode: {res.returncode}")
|
|
44
|
+
|
|
45
|
+
# Read selections (if any) from the output file created by tv.
|
|
46
|
+
out_text = tv_out_path.read_text(encoding="utf-8") if tv_out_path.exists() else ""
|
|
47
|
+
choice_string_multi = [x for x in out_text.splitlines() if x.strip() != ""]
|
|
48
|
+
|
|
49
|
+
# Cleanup temporary files
|
|
50
|
+
options_txt_path.unlink(missing_ok=True)
|
|
51
|
+
tv_out_path.unlink(missing_ok=True)
|
|
27
52
|
if not multi:
|
|
28
53
|
try:
|
|
29
54
|
choice_one_string = choice_string_multi[0]
|
|
55
|
+
if isinstance(list(options)[0], str): return cast(T, choice_one_string)
|
|
30
56
|
choice_idx = options_strings.index(choice_one_string)
|
|
31
57
|
return list(options)[choice_idx]
|
|
32
58
|
except IndexError as ie:
|
|
33
59
|
print(f"❌ Error: {options=}, {choice_string_multi=}")
|
|
34
60
|
print(f"🔍 Available choices: {choice_string_multi}")
|
|
35
61
|
raise ie
|
|
62
|
+
if isinstance(list(options)[0], str):
|
|
63
|
+
return cast(list[T], choice_string_multi)
|
|
36
64
|
choice_idx_s = [options_strings.index(x) for x in choice_string_multi]
|
|
37
65
|
return [list(options)[x] for x in choice_idx_s]
|
|
38
66
|
else:
|
|
@@ -55,7 +83,7 @@ def choose_from_options[T](msg: str, options: Iterable[T], multi: bool, custom_i
|
|
|
55
83
|
if choice_string == "":
|
|
56
84
|
if default_string is None:
|
|
57
85
|
console.print(Panel("🧨 Default option not available!", title="Error", expand=False))
|
|
58
|
-
return choose_from_options(msg=msg, options=options, header=header, tail=tail, prompt=prompt, default=default,
|
|
86
|
+
return choose_from_options(msg=msg, options=options, header=header, tail=tail, prompt=prompt, default=default, tv=tv, multi=multi, custom_input=custom_input)
|
|
59
87
|
choice_idx = options_strings.index(default_string)
|
|
60
88
|
assert default is not None, "🧨 Default option not available!"
|
|
61
89
|
choice_one: T = default
|
|
@@ -73,7 +101,7 @@ def choose_from_options[T](msg: str, options: Iterable[T], multi: bool, custom_i
|
|
|
73
101
|
_ = ie
|
|
74
102
|
# raise ValueError(f"Unknown choice. {choice_string}") from ie
|
|
75
103
|
console.print(Panel(f"❓ Unknown choice: '{choice_string}'", title="Error", expand=False))
|
|
76
|
-
return choose_from_options(msg=msg, options=options, header=header, tail=tail, prompt=prompt, default=default,
|
|
104
|
+
return choose_from_options(msg=msg, options=options, header=header, tail=tail, prompt=prompt, default=default, tv=tv, multi=multi, custom_input=custom_input)
|
|
77
105
|
except (TypeError, ValueError) as te: # int(choice_string) failed due to # either the number is invalid, or the input is custom.
|
|
78
106
|
if choice_string in options_strings: # string input
|
|
79
107
|
choice_idx = options_strings.index(choice_one) # type: ignore
|
|
@@ -84,7 +112,7 @@ def choose_from_options[T](msg: str, options: Iterable[T], multi: bool, custom_i
|
|
|
84
112
|
_ = te
|
|
85
113
|
# raise ValueError(f"Unknown choice. {choice_string}") from te
|
|
86
114
|
console.print(Panel(f"❓ Unknown choice: '{choice_string}'", title="Error", expand=False))
|
|
87
|
-
return choose_from_options(msg=msg, options=options, header=header, tail=tail, prompt=prompt, default=default,
|
|
115
|
+
return choose_from_options(msg=msg, options=options, header=header, tail=tail, prompt=prompt, default=default, tv=tv, multi=multi, custom_input=custom_input)
|
|
88
116
|
console.print(Panel(f"✅ Selected option {choice_idx}: {choice_one}", title="Selected", expand=False))
|
|
89
117
|
if multi:
|
|
90
118
|
return [choice_one]
|
|
@@ -103,7 +131,7 @@ def choose_cloud_interactively() -> str:
|
|
|
103
131
|
raise ValueError(f"Got {tmp} from rclone listremotes")
|
|
104
132
|
if len(remotes) == 0:
|
|
105
133
|
raise RuntimeError("You don't have remotes. Configure your rclone first to get cloud services access.")
|
|
106
|
-
cloud: str = choose_from_options(msg="WHICH CLOUD?", multi=False, options=list(remotes), default=remotes[0],
|
|
134
|
+
cloud: str = choose_from_options(msg="WHICH CLOUD?", multi=False, options=list(remotes), default=remotes[0], tv=True)
|
|
107
135
|
console.print(Panel(f"✅ SELECTED CLOUD | {cloud}", border_style="bold blue", expand=False))
|
|
108
136
|
return cloud
|
|
109
137
|
|
|
@@ -121,4 +149,4 @@ def choose_ssh_host(multi: Literal[False]) -> str: ...
|
|
|
121
149
|
@overload
|
|
122
150
|
def choose_ssh_host(multi: Literal[True]) -> list[str]: ...
|
|
123
151
|
def choose_ssh_host(multi: bool):
|
|
124
|
-
return choose_from_options(msg="", options=get_ssh_hosts(), multi=multi,
|
|
152
|
+
return choose_from_options(msg="", options=get_ssh_hosts(), multi=multi, tv=True)
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
#!/usr/bin/env python3
|
|
4
|
+
import base64
|
|
5
|
+
import pathlib
|
|
6
|
+
import subprocess
|
|
7
|
+
import tempfile
|
|
8
|
+
import os
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def main(options_to_preview_mapping: dict[str, str]) -> str | None:
|
|
12
|
+
keys = list(options_to_preview_mapping.keys())
|
|
13
|
+
if not keys:
|
|
14
|
+
return None
|
|
15
|
+
with tempfile.TemporaryDirectory(prefix="tv_channel_") as tmpdir:
|
|
16
|
+
tempdir = pathlib.Path(tmpdir)
|
|
17
|
+
entries: list[str] = []
|
|
18
|
+
index_map: dict[int, str] = {}
|
|
19
|
+
preview_map_path = tempdir / "previews.tsv"
|
|
20
|
+
preview_rows: list[str] = []
|
|
21
|
+
for idx, key in enumerate(keys):
|
|
22
|
+
display_key = key.replace("\t", " ").replace("\n", " ")
|
|
23
|
+
entries.append(f"{idx}\t{display_key}")
|
|
24
|
+
index_map[idx] = key
|
|
25
|
+
encoded_preview = base64.b64encode(options_to_preview_mapping[key].encode("utf-8")).decode("ascii")
|
|
26
|
+
preview_rows.append(f"{idx}\t{encoded_preview}")
|
|
27
|
+
preview_map_path.write_text("\n".join(preview_rows), encoding="utf-8")
|
|
28
|
+
entries_path = tempdir / "entries.tsv"
|
|
29
|
+
entries_path.write_text("\n".join(entries), encoding="utf-8")
|
|
30
|
+
preview_script = tempdir / "preview.sh"
|
|
31
|
+
preview_script.write_text(
|
|
32
|
+
"""#!/usr/bin/env bash
|
|
33
|
+
set -euo pipefail
|
|
34
|
+
|
|
35
|
+
idx="$1"
|
|
36
|
+
script_dir="$(cd -- "$(dirname -- "$0")" && pwd)"
|
|
37
|
+
previews_file="${script_dir}/previews.tsv"
|
|
38
|
+
|
|
39
|
+
if [[ ! -f "${previews_file}" ]]; then
|
|
40
|
+
exit 0
|
|
41
|
+
fi
|
|
42
|
+
|
|
43
|
+
encoded_preview="$(awk -F '\t' -v idx="${idx}" '($1==idx){print $2; exit}' "${previews_file}" || true)"
|
|
44
|
+
|
|
45
|
+
if [[ -z "${encoded_preview}" ]]; then
|
|
46
|
+
exit 0
|
|
47
|
+
fi
|
|
48
|
+
|
|
49
|
+
preview_content="$(printf '%s' "${encoded_preview}" | base64 --decode)"
|
|
50
|
+
|
|
51
|
+
if command -v bat >/dev/null 2>&1; then
|
|
52
|
+
printf '%s' "${preview_content}" | glow -
|
|
53
|
+
elif command -v bat >/dev/null 2>&1; then
|
|
54
|
+
printf '%s' "${preview_content}" | bat --language=markdown --color=always --style=plain --paging=never
|
|
55
|
+
elif command -v glow >/dev/null 2>&1; then
|
|
56
|
+
printf '%s' "${preview_content}" | glow -
|
|
57
|
+
else
|
|
58
|
+
printf '%s' "${preview_content}"
|
|
59
|
+
fi
|
|
60
|
+
""",
|
|
61
|
+
encoding="utf-8"
|
|
62
|
+
)
|
|
63
|
+
preview_script.chmod(0o755)
|
|
64
|
+
channel_config = f"""[metadata]
|
|
65
|
+
name = "temp_options"
|
|
66
|
+
description = "Temporary channel for selecting options"
|
|
67
|
+
|
|
68
|
+
[source]
|
|
69
|
+
command = "cat '{entries_path}'"
|
|
70
|
+
display = "{{split:\\t:1}}"
|
|
71
|
+
output = "{{split:\\t:0}}"
|
|
72
|
+
|
|
73
|
+
[preview]
|
|
74
|
+
command = "{preview_script} {{split:\\t:0}}"
|
|
75
|
+
|
|
76
|
+
[ui.preview_panel]
|
|
77
|
+
size = 50
|
|
78
|
+
"""
|
|
79
|
+
channel_path = tempdir / "temp_options.toml"
|
|
80
|
+
channel_path.write_text(channel_config, encoding="utf-8")
|
|
81
|
+
env = os.environ.copy()
|
|
82
|
+
tv_config_dir = pathlib.Path.home() / ".config" / "television"
|
|
83
|
+
if not tv_config_dir.exists():
|
|
84
|
+
tv_config_dir = pathlib.Path(os.getenv("XDG_CONFIG_HOME", str(pathlib.Path.home() / ".config"))) / "television"
|
|
85
|
+
cable_dir = tv_config_dir / "cable"
|
|
86
|
+
cable_dir.mkdir(parents=True, exist_ok=True)
|
|
87
|
+
temp_channel_link = cable_dir / "temp_options.toml"
|
|
88
|
+
if temp_channel_link.exists() or temp_channel_link.is_symlink():
|
|
89
|
+
temp_channel_link.unlink()
|
|
90
|
+
temp_channel_link.symlink_to(channel_path)
|
|
91
|
+
output_file = tempdir / "selection.txt"
|
|
92
|
+
try:
|
|
93
|
+
result = subprocess.run(["tv", "temp_options"], check=False, stdout=output_file.open("w"), text=True, env=env)
|
|
94
|
+
finally:
|
|
95
|
+
if temp_channel_link.exists() or temp_channel_link.is_symlink():
|
|
96
|
+
temp_channel_link.unlink()
|
|
97
|
+
if result.returncode not in (0, 130):
|
|
98
|
+
raise SystemExit(result.returncode)
|
|
99
|
+
if result.returncode == 130:
|
|
100
|
+
return None
|
|
101
|
+
if not output_file.exists():
|
|
102
|
+
return None
|
|
103
|
+
selected = output_file.read_text().strip()
|
|
104
|
+
if not selected:
|
|
105
|
+
return None
|
|
106
|
+
try:
|
|
107
|
+
index = int(selected)
|
|
108
|
+
except ValueError:
|
|
109
|
+
return None
|
|
110
|
+
return index_map.get(index)
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
if __name__ == "__main__":
|
|
114
|
+
demo_mapping = {
|
|
115
|
+
"Option 1": "# Option 1\nThis is the preview for option 1.",
|
|
116
|
+
"Option 2": "# Option 2\nThis is the preview for option 2.",
|
|
117
|
+
"Option 3": "# Option 3\nThis is the preview for option 3."
|
|
118
|
+
}
|
|
119
|
+
main(demo_mapping)
|