machineconfig 5.15__py3-none-any.whl → 7.98__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (472) hide show
  1. machineconfig/__init__.py +0 -28
  2. machineconfig/cluster/remote/cloud_manager.py +1 -1
  3. machineconfig/cluster/remote/distribute.py +0 -1
  4. machineconfig/cluster/remote/file_manager.py +0 -2
  5. machineconfig/cluster/remote/script_execution.py +0 -1
  6. machineconfig/cluster/sessions_managers/{utils → helpers}/enhanced_command_runner.py +4 -6
  7. machineconfig/cluster/sessions_managers/utils/load_balancer.py +1 -1
  8. machineconfig/cluster/sessions_managers/utils/maker.py +69 -0
  9. machineconfig/cluster/sessions_managers/wt_local.py +114 -289
  10. machineconfig/cluster/sessions_managers/wt_local_manager.py +70 -210
  11. machineconfig/cluster/sessions_managers/wt_remote.py +51 -43
  12. machineconfig/cluster/sessions_managers/wt_remote_manager.py +52 -198
  13. machineconfig/cluster/sessions_managers/wt_utils/layout_generator.py +6 -19
  14. machineconfig/cluster/sessions_managers/wt_utils/manager_persistence.py +52 -0
  15. machineconfig/cluster/sessions_managers/wt_utils/monitoring_helpers.py +50 -0
  16. machineconfig/cluster/sessions_managers/wt_utils/status_reporter.py +4 -2
  17. machineconfig/cluster/sessions_managers/wt_utils/status_reporting.py +76 -0
  18. machineconfig/cluster/sessions_managers/wt_utils/wt_helpers.py +199 -0
  19. machineconfig/cluster/sessions_managers/zellij_local.py +81 -375
  20. machineconfig/cluster/sessions_managers/zellij_local_manager.py +25 -170
  21. machineconfig/cluster/sessions_managers/zellij_remote.py +40 -41
  22. machineconfig/cluster/sessions_managers/zellij_remote_manager.py +16 -12
  23. machineconfig/cluster/sessions_managers/zellij_utils/example_usage.py +4 -8
  24. machineconfig/cluster/sessions_managers/zellij_utils/layout_generator.py +5 -20
  25. machineconfig/cluster/sessions_managers/zellij_utils/process_monitor.py +3 -9
  26. machineconfig/cluster/sessions_managers/zellij_utils/status_reporter.py +3 -1
  27. machineconfig/cluster/sessions_managers/zellij_utils/zellij_local_helper.py +298 -0
  28. machineconfig/cluster/sessions_managers/zellij_utils/zellij_local_helper_restart.py +77 -0
  29. machineconfig/cluster/sessions_managers/zellij_utils/zellij_local_helper_with_panes.py +228 -0
  30. machineconfig/cluster/sessions_managers/zellij_utils/zellij_local_manager_helper.py +165 -0
  31. machineconfig/jobs/{python → installer}/check_installations.py +2 -3
  32. machineconfig/jobs/installer/custom/boxes.py +61 -0
  33. machineconfig/jobs/installer/custom/hx.py +76 -19
  34. machineconfig/jobs/installer/custom/yazi.py +119 -0
  35. machineconfig/jobs/installer/custom_dev/alacritty.py +4 -4
  36. machineconfig/jobs/installer/custom_dev/brave.py +5 -9
  37. machineconfig/jobs/installer/custom_dev/cloudflare_warp_cli.py +23 -0
  38. machineconfig/jobs/installer/custom_dev/code.py +4 -1
  39. machineconfig/jobs/installer/custom_dev/dubdb_adbc.py +30 -0
  40. machineconfig/jobs/installer/custom_dev/nerdfont.py +1 -1
  41. machineconfig/jobs/installer/custom_dev/nerfont_windows_helper.py +33 -28
  42. machineconfig/jobs/installer/custom_dev/sysabc.py +139 -0
  43. machineconfig/jobs/installer/custom_dev/wezterm.py +2 -19
  44. machineconfig/jobs/installer/custom_dev/winget.py +10 -14
  45. machineconfig/jobs/installer/installer_data.json +1487 -229
  46. machineconfig/jobs/installer/linux_scripts/brave.sh +4 -14
  47. machineconfig/jobs/installer/linux_scripts/{warp-cli.sh → cloudflare_warp_cli.sh} +5 -17
  48. machineconfig/jobs/installer/linux_scripts/docker.sh +5 -17
  49. machineconfig/jobs/installer/linux_scripts/docker_start.sh +6 -14
  50. machineconfig/jobs/installer/linux_scripts/edge.sh +3 -11
  51. machineconfig/jobs/{linux/msc → installer/linux_scripts}/lid.sh +2 -8
  52. machineconfig/jobs/installer/linux_scripts/nerdfont.sh +5 -17
  53. machineconfig/jobs/{linux/msc → installer/linux_scripts}/network.sh +2 -8
  54. machineconfig/jobs/installer/linux_scripts/q.sh +10 -6
  55. machineconfig/jobs/installer/linux_scripts/redis.sh +6 -17
  56. machineconfig/jobs/installer/linux_scripts/vscode.sh +5 -17
  57. machineconfig/jobs/installer/linux_scripts/wezterm.sh +4 -12
  58. machineconfig/jobs/installer/package_groups.py +106 -177
  59. machineconfig/jobs/installer/powershell_scripts/install_fonts.ps1 +129 -34
  60. machineconfig/logger.py +0 -1
  61. machineconfig/profile/backup.toml +49 -0
  62. machineconfig/profile/bash_shell_profiles.md +11 -0
  63. machineconfig/profile/create_helper.py +62 -0
  64. machineconfig/profile/create_links.py +288 -0
  65. machineconfig/profile/create_links_export.py +100 -0
  66. machineconfig/profile/create_shell_profile.py +147 -0
  67. machineconfig/profile/mapper.toml +263 -0
  68. machineconfig/scripts/__init__.py +0 -4
  69. machineconfig/scripts/linux/{share_cloud.sh → other/share_cloud.sh} +14 -25
  70. machineconfig/scripts/linux/wrap_mcfg +46 -0
  71. machineconfig/scripts/nu/wrap_mcfg.nu +69 -0
  72. machineconfig/scripts/python/agents.py +123 -117
  73. machineconfig/scripts/python/ai/initai.py +3 -28
  74. machineconfig/scripts/python/ai/scripts/command_runner.ps1 +33 -0
  75. machineconfig/scripts/python/ai/scripts/command_runner.sh +9 -0
  76. machineconfig/scripts/python/ai/scripts/lint_and_type_check.ps1 +17 -18
  77. machineconfig/scripts/python/ai/scripts/lint_and_type_check.sh +17 -18
  78. machineconfig/scripts/python/ai/solutions/_shared.py +9 -1
  79. machineconfig/scripts/python/ai/solutions/copilot/{chatmodes/Thinking-Beast-Mode.chatmode.md → agents/Thinking-Beast-Mode.agent.md} +0 -1
  80. machineconfig/scripts/python/ai/solutions/copilot/{chatmodes/Ultimate-Transparent-Thinking-Beast-Mode.chatmode.md → agents/Ultimate-Transparent-Thinking-Beast-Mode.agent.md} +0 -1
  81. machineconfig/scripts/python/ai/solutions/copilot/{chatmodes/deepResearch.chatmode.md → agents/deepResearch.agent.md} +2 -2
  82. machineconfig/scripts/python/ai/solutions/copilot/github_copilot.py +5 -5
  83. machineconfig/scripts/python/ai/solutions/copilot/instructions/python/dev.instructions.md +5 -1
  84. machineconfig/scripts/python/ai/solutions/copilot/instructions/python/watch_exec.prompt.md +20 -0
  85. machineconfig/scripts/python/ai/solutions/copilot/prompts/pyright_fix.md +16 -0
  86. machineconfig/scripts/python/ai/solutions/generic.py +28 -5
  87. machineconfig/scripts/python/ai/utils/generate_files.py +348 -0
  88. machineconfig/scripts/python/ai/utils/vscode_tasks.py +37 -0
  89. machineconfig/scripts/python/cloud.py +29 -0
  90. machineconfig/scripts/python/croshell.py +137 -113
  91. machineconfig/scripts/python/devops.py +61 -101
  92. machineconfig/scripts/python/devops_navigator.py +6 -0
  93. machineconfig/scripts/python/env_manager/__init__.py +1 -0
  94. machineconfig/scripts/python/env_manager/env_manager_tui.py +204 -0
  95. machineconfig/scripts/python/env_manager/path_manager_backend.py +47 -0
  96. machineconfig/scripts/python/env_manager/path_manager_tui.py +228 -0
  97. machineconfig/scripts/python/fire_jobs.py +110 -150
  98. machineconfig/scripts/python/ftpx.py +51 -24
  99. machineconfig/scripts/python/helpers/ast_search.py +74 -0
  100. machineconfig/scripts/python/helpers/qr_code.py +166 -0
  101. machineconfig/scripts/python/helpers/repo_rag.py +325 -0
  102. machineconfig/scripts/python/helpers/run_py_script.py +79 -0
  103. machineconfig/scripts/python/helpers/symantic_search.py +25 -0
  104. machineconfig/scripts/python/helpers/tmp_py_scripts/a.py +26 -0
  105. machineconfig/scripts/python/helpers_agents/agentic_frameworks/fire_crush.json +14 -0
  106. machineconfig/scripts/python/helpers_agents/agentic_frameworks/fire_crush.py +39 -0
  107. machineconfig/scripts/python/helpers_agents/agentic_frameworks/fire_cursor_agents.py +22 -0
  108. machineconfig/scripts/python/helpers_agents/agentic_frameworks/fire_gemini.py +55 -0
  109. machineconfig/scripts/python/helpers_agents/agentic_frameworks/fire_qwen.py +30 -0
  110. machineconfig/scripts/python/helpers_agents/fire_agents_help_launch.py +126 -0
  111. machineconfig/scripts/python/helpers_agents/fire_agents_helper_types.py +41 -0
  112. machineconfig/scripts/python/helpers_agents/templates/prompt.txt +10 -0
  113. machineconfig/scripts/python/helpers_agents/templates/template.ps1 +14 -0
  114. machineconfig/scripts/python/helpers_agents/templates/template.sh +32 -0
  115. machineconfig/scripts/python/{cloud_copy.py → helpers_cloud/cloud_copy.py} +30 -23
  116. machineconfig/scripts/python/{cloud_mount.py → helpers_cloud/cloud_mount.py} +29 -35
  117. machineconfig/scripts/python/{cloud_sync.py → helpers_cloud/cloud_sync.py} +12 -18
  118. machineconfig/scripts/python/{helpers → helpers_cloud}/helpers2.py +1 -1
  119. machineconfig/scripts/python/helpers_croshell/crosh.py +39 -0
  120. machineconfig/scripts/python/{start_slidev.py → helpers_croshell/start_slidev.py} +8 -9
  121. machineconfig/scripts/python/helpers_devops/cli_config.py +105 -0
  122. machineconfig/scripts/python/helpers_devops/cli_config_dotfile.py +89 -0
  123. machineconfig/scripts/python/helpers_devops/cli_data.py +25 -0
  124. machineconfig/scripts/python/helpers_devops/cli_nw.py +214 -0
  125. machineconfig/scripts/python/helpers_devops/cli_repos.py +215 -0
  126. machineconfig/scripts/python/helpers_devops/cli_self.py +172 -0
  127. machineconfig/scripts/python/helpers_devops/cli_share_file.py +137 -0
  128. machineconfig/scripts/python/helpers_devops/cli_share_server.py +142 -0
  129. machineconfig/scripts/python/{share_terminal.py → helpers_devops/cli_share_terminal.py} +45 -35
  130. machineconfig/scripts/python/helpers_devops/cli_utils.py +96 -0
  131. machineconfig/scripts/python/{devops_backup_retrieve.py → helpers_devops/devops_backup_retrieve.py} +7 -10
  132. machineconfig/scripts/python/helpers_devops/devops_status.py +499 -0
  133. machineconfig/scripts/python/{devops_update_repos.py → helpers_devops/devops_update_repos.py} +68 -49
  134. machineconfig/scripts/python/helpers_devops/themes/choose_pwsh_theme.ps1 +81 -0
  135. machineconfig/scripts/python/helpers_devops/themes/choose_starship_theme.bash +3 -0
  136. machineconfig/scripts/python/{choose_wezterm_theme.py → helpers_devops/themes/choose_wezterm_theme.py} +3 -3
  137. machineconfig/scripts/python/helpers_fire_command/__init__.py +0 -0
  138. machineconfig/scripts/python/helpers_fire_command/f.py +0 -0
  139. machineconfig/scripts/python/{helpers/helpers4.py → helpers_fire_command/file_wrangler.py} +56 -20
  140. machineconfig/scripts/python/{fire_jobs_args_helper.py → helpers_fire_command/fire_jobs_args_helper.py} +5 -1
  141. machineconfig/scripts/python/helpers_fire_command/fire_jobs_route_helper.py +121 -0
  142. machineconfig/scripts/python/helpers_fire_command/fire_jobs_streamlit_helper.py +0 -0
  143. machineconfig/scripts/python/helpers_msearch/__init__.py +5 -0
  144. machineconfig/scripts/{linux → python/helpers_msearch/scripts_linux}/fzfg +3 -3
  145. machineconfig/scripts/python/helpers_msearch/scripts_windows/fzfg.ps1 +59 -0
  146. machineconfig/scripts/python/helpers_navigator/__init__.py +20 -0
  147. machineconfig/scripts/python/helpers_navigator/command_builder.py +111 -0
  148. machineconfig/scripts/python/helpers_navigator/command_detail.py +44 -0
  149. machineconfig/scripts/python/helpers_navigator/command_tree.py +620 -0
  150. machineconfig/scripts/python/helpers_navigator/data_models.py +28 -0
  151. machineconfig/scripts/python/helpers_navigator/main_app.py +272 -0
  152. machineconfig/scripts/python/helpers_navigator/search_bar.py +15 -0
  153. machineconfig/scripts/python/helpers_network/__init__.py +0 -0
  154. machineconfig/scripts/python/helpers_network/address.py +132 -0
  155. machineconfig/scripts/python/{devops_add_identity.py → helpers_network/devops_add_identity.py} +0 -2
  156. machineconfig/scripts/python/helpers_network/devops_add_ssh_key.py +153 -0
  157. machineconfig/scripts/{linux → python/helpers_network}/mount_nfs +0 -1
  158. machineconfig/scripts/python/{mount_nfs.py → helpers_network/mount_nfs.py} +3 -3
  159. machineconfig/scripts/{linux → python/helpers_network}/mount_nw_drive +1 -2
  160. machineconfig/scripts/python/{mount_ssh.py → helpers_network/mount_ssh.py} +3 -3
  161. machineconfig/scripts/python/{onetimeshare.py → helpers_network/onetimeshare.py} +0 -1
  162. machineconfig/scripts/python/helpers_network/ssh_debug_linux.py +391 -0
  163. machineconfig/scripts/python/helpers_network/ssh_debug_windows.py +338 -0
  164. machineconfig/scripts/python/{wifi_conn.py → helpers_network/wifi_conn.py} +1 -53
  165. machineconfig/scripts/python/{wsl_windows_transfer.py → helpers_network/wsl_windows_transfer.py} +5 -4
  166. machineconfig/scripts/python/helpers_repos/action.py +209 -0
  167. machineconfig/scripts/python/helpers_repos/action_helper.py +150 -0
  168. machineconfig/scripts/python/{repos_helper_clone.py → helpers_repos/clone.py} +2 -3
  169. machineconfig/scripts/python/helpers_repos/cloud_repo_sync.py +218 -0
  170. machineconfig/scripts/python/{repos_helper.py → helpers_repos/entrypoint.py} +9 -17
  171. machineconfig/scripts/python/helpers_repos/grource.py +340 -0
  172. machineconfig/scripts/python/{repos_helper_record.py → helpers_repos/record.py} +4 -3
  173. machineconfig/scripts/python/helpers_repos/repo_analyzer_1.py +160 -0
  174. machineconfig/scripts/python/{count_lines.py → helpers_repos/repo_analyzer_2.py} +113 -192
  175. machineconfig/scripts/python/helpers_repos/sync.py +66 -0
  176. machineconfig/scripts/python/{repos_helper_update.py → helpers_repos/update.py} +3 -3
  177. machineconfig/scripts/python/helpers_sessions/__init__.py +0 -0
  178. machineconfig/scripts/python/helpers_sessions/sessions_multiprocess.py +65 -0
  179. machineconfig/scripts/python/helpers_utils/download.py +150 -0
  180. machineconfig/scripts/python/helpers_utils/path.py +185 -0
  181. machineconfig/scripts/python/interactive.py +64 -84
  182. machineconfig/scripts/python/mcfg_entry.py +58 -0
  183. machineconfig/scripts/python/msearch.py +71 -0
  184. machineconfig/scripts/python/sessions.py +119 -45
  185. machineconfig/scripts/python/terminal.py +133 -0
  186. machineconfig/scripts/python/utils.py +64 -0
  187. machineconfig/scripts/windows/mounts/Restore-ThunderbirdProfile.ps1 +92 -0
  188. machineconfig/scripts/windows/{mount_nfs.ps1 → mounts/mount_nfs.ps1} +1 -3
  189. machineconfig/scripts/windows/{mount_ssh.ps1 → mounts/mount_ssh.ps1} +1 -1
  190. machineconfig/scripts/windows/{share_smb.ps1 → mounts/share_smb.ps1} +0 -6
  191. machineconfig/scripts/windows/wrap_mcfg.ps1 +63 -0
  192. machineconfig/settings/broot/br.sh +0 -4
  193. machineconfig/settings/broot/conf.toml +1 -1
  194. machineconfig/settings/helix/config.toml +16 -0
  195. machineconfig/settings/helix/languages.toml +13 -4
  196. machineconfig/settings/helix/yazi-picker.sh +12 -0
  197. machineconfig/settings/lf/linux/exe/lfcd.sh +1 -0
  198. machineconfig/settings/lf/linux/exe/previewer.sh +9 -3
  199. machineconfig/settings/lf/linux/lfrc +10 -12
  200. machineconfig/settings/lf/windows/lfcd.ps1 +1 -1
  201. machineconfig/settings/lf/windows/lfrc +18 -38
  202. machineconfig/settings/lf/windows/mkfile.ps1 +1 -1
  203. machineconfig/settings/linters/.ruff.toml +1 -1
  204. machineconfig/settings/lvim/windows/archive/config_additional.lua +0 -6
  205. machineconfig/settings/marimo/marimo.toml +80 -0
  206. machineconfig/settings/marimo/snippets/globalize.py +34 -0
  207. machineconfig/settings/pistol/pistol.conf +1 -1
  208. machineconfig/settings/shells/bash/init.sh +82 -31
  209. machineconfig/settings/shells/ipy/profiles/default/startup/playext.py +1 -1
  210. machineconfig/settings/shells/nushell/config.nu +2 -35
  211. machineconfig/settings/shells/nushell/env.nu +45 -6
  212. machineconfig/settings/shells/nushell/init.nu +314 -0
  213. machineconfig/settings/shells/pwsh/init.ps1 +61 -43
  214. machineconfig/settings/shells/starship/starship.toml +16 -0
  215. machineconfig/settings/shells/wezterm/wezterm.lua +2 -0
  216. machineconfig/settings/shells/wt/settings.json +32 -17
  217. machineconfig/settings/shells/zsh/init.sh +89 -0
  218. machineconfig/settings/svim/linux/init.toml +0 -4
  219. machineconfig/settings/svim/windows/init.toml +0 -3
  220. machineconfig/settings/television/cable_unix/alias.toml +8 -0
  221. machineconfig/settings/television/cable_unix/aws-buckets.toml +14 -0
  222. machineconfig/settings/television/cable_unix/aws-instances.toml +13 -0
  223. machineconfig/settings/television/cable_unix/bash-history.toml +8 -0
  224. machineconfig/settings/television/cable_unix/channels.toml +19 -0
  225. machineconfig/settings/television/cable_unix/dirs.toml +13 -0
  226. machineconfig/settings/television/cable_unix/distrobox-list.toml +42 -0
  227. machineconfig/settings/television/cable_unix/docker-images.toml +13 -0
  228. machineconfig/settings/television/cable_unix/dotfiles.toml +11 -0
  229. machineconfig/settings/television/cable_unix/env.toml +17 -0
  230. machineconfig/settings/television/cable_unix/files.toml +11 -0
  231. machineconfig/settings/television/cable_unix/fish-history.toml +8 -0
  232. machineconfig/settings/television/cable_unix/git-branch.toml +11 -0
  233. machineconfig/settings/television/cable_unix/git-diff.toml +10 -0
  234. machineconfig/settings/television/cable_unix/git-log.toml +12 -0
  235. machineconfig/settings/television/cable_unix/git-reflog.toml +12 -0
  236. machineconfig/settings/television/cable_unix/git-repos.toml +16 -0
  237. machineconfig/settings/television/cable_unix/guix.toml +20 -0
  238. machineconfig/settings/television/cable_unix/just-recipes.toml +18 -0
  239. machineconfig/settings/television/cable_unix/k8s-deployments.toml +36 -0
  240. machineconfig/settings/television/cable_unix/k8s-pods.toml +50 -0
  241. machineconfig/settings/television/cable_unix/k8s-services.toml +36 -0
  242. machineconfig/settings/television/cable_unix/man-pages.toml +24 -0
  243. machineconfig/settings/television/cable_unix/nu-history.toml +7 -0
  244. machineconfig/settings/television/cable_unix/procs.toml +20 -0
  245. machineconfig/settings/television/cable_unix/text.toml +17 -0
  246. machineconfig/settings/television/cable_unix/tldr.toml +18 -0
  247. machineconfig/settings/television/cable_unix/zsh-history.toml +9 -0
  248. machineconfig/settings/television/cable_windows/alias.toml +7 -0
  249. machineconfig/settings/television/cable_windows/dirs.toml +13 -0
  250. machineconfig/settings/television/cable_windows/docker-images.toml +13 -0
  251. machineconfig/settings/television/cable_windows/dotfiles.toml +11 -0
  252. machineconfig/settings/television/cable_windows/env.toml +17 -0
  253. machineconfig/settings/television/cable_windows/files.toml +14 -0
  254. machineconfig/settings/television/cable_windows/git-branch.toml +11 -0
  255. machineconfig/settings/television/cable_windows/git-diff.toml +10 -0
  256. machineconfig/settings/television/cable_windows/git-log.toml +11 -0
  257. machineconfig/settings/television/cable_windows/git-reflog.toml +11 -0
  258. machineconfig/settings/television/cable_windows/git-repos.toml +15 -0
  259. machineconfig/settings/television/cable_windows/nu-history.toml +7 -0
  260. machineconfig/settings/television/cable_windows/pwsh-history.toml +6 -0
  261. machineconfig/settings/television/cable_windows/text.toml +17 -0
  262. machineconfig/settings/yazi/init.lua +61 -0
  263. machineconfig/settings/yazi/keymap_linux.toml +94 -0
  264. machineconfig/settings/yazi/keymap_windows.toml +78 -0
  265. machineconfig/settings/yazi/shell/yazi_cd.ps1 +33 -0
  266. machineconfig/settings/yazi/shell/yazi_cd.sh +8 -0
  267. machineconfig/settings/yazi/theme.toml +4 -0
  268. machineconfig/settings/yazi/yazi_linux.toml +84 -0
  269. machineconfig/settings/yazi/yazi_windows.toml +58 -0
  270. machineconfig/setup_linux/__init__.py +11 -0
  271. machineconfig/setup_linux/apps_desktop.sh +89 -0
  272. machineconfig/setup_linux/apps_gui.sh +64 -0
  273. machineconfig/setup_linux/ssh/openssh_all.sh +25 -0
  274. machineconfig/setup_linux/ssh/openssh_wsl.sh +38 -0
  275. machineconfig/setup_linux/uv.sh +15 -0
  276. machineconfig/setup_linux/web_shortcuts/interactive.sh +26 -6
  277. machineconfig/setup_linux/web_shortcuts/live_from_github.sh +31 -0
  278. machineconfig/setup_mac/__init__.py +16 -0
  279. machineconfig/setup_mac/apps_gui.sh +248 -0
  280. machineconfig/setup_mac/ssh/openssh_setup.sh +114 -0
  281. machineconfig/setup_mac/uv.sh +36 -0
  282. machineconfig/setup_windows/__init__.py +11 -0
  283. machineconfig/setup_windows/others/power_options.ps1 +7 -0
  284. machineconfig/setup_windows/ssh/add-sshkey.ps1 +29 -0
  285. machineconfig/setup_windows/ssh/add_identity.ps1 +11 -0
  286. machineconfig/setup_windows/ssh/openssh-server.ps1 +37 -0
  287. machineconfig/setup_windows/uv.ps1 +17 -0
  288. machineconfig/setup_windows/web_shortcuts/interactive.ps1 +27 -10
  289. machineconfig/setup_windows/web_shortcuts/live_from_github.ps1 +30 -0
  290. machineconfig/setup_windows/web_shortcuts/quick_init.ps1 +17 -0
  291. machineconfig/utils/accessories.py +7 -5
  292. machineconfig/utils/cloud/onedrive/README.md +139 -0
  293. machineconfig/utils/code.py +155 -105
  294. machineconfig/utils/files/art/fat_croco.txt +10 -0
  295. machineconfig/utils/files/art/halfwit_croco.txt +9 -0
  296. machineconfig/utils/files/art/happy_croco.txt +22 -0
  297. machineconfig/utils/files/art/water_croco.txt +11 -0
  298. machineconfig/utils/files/ascii_art.py +1 -1
  299. machineconfig/utils/files/dbms.py +257 -0
  300. machineconfig/utils/files/headers.py +11 -14
  301. machineconfig/utils/files/ouch/__init__.py +0 -0
  302. machineconfig/utils/files/ouch/decompress.py +45 -0
  303. machineconfig/utils/files/read.py +10 -18
  304. machineconfig/utils/installer_utils/github_release_bulk.py +156 -119
  305. machineconfig/utils/installer_utils/install_from_url.py +183 -0
  306. machineconfig/utils/installer_utils/installer_class.py +64 -181
  307. machineconfig/utils/installer_utils/installer_cli.py +175 -0
  308. machineconfig/utils/installer_utils/installer_helper.py +129 -0
  309. machineconfig/utils/installer_utils/{installer_abc.py → installer_locator_utils.py} +66 -97
  310. machineconfig/utils/{installer.py → installer_utils/installer_runner.py} +49 -82
  311. machineconfig/utils/io.py +77 -23
  312. machineconfig/utils/links.py +254 -162
  313. machineconfig/utils/meta.py +256 -0
  314. machineconfig/utils/notifications.py +1 -1
  315. machineconfig/utils/options.py +46 -18
  316. machineconfig/utils/options_tv.py +119 -0
  317. machineconfig/utils/path_extended.py +48 -101
  318. machineconfig/utils/path_helper.py +76 -23
  319. machineconfig/utils/procs.py +50 -70
  320. machineconfig/utils/scheduler.py +88 -124
  321. machineconfig/utils/scheduling.py +0 -3
  322. machineconfig/utils/schemas/fire_agents/fire_agents_input.py +1 -1
  323. machineconfig/utils/schemas/layouts/layout_types.py +1 -1
  324. machineconfig/utils/source_of_truth.py +3 -6
  325. machineconfig/utils/ssh.py +263 -274
  326. machineconfig/utils/ssh_utils/abc.py +5 -0
  327. machineconfig/utils/ssh_utils/copy_from_here.py +111 -0
  328. machineconfig/utils/ssh_utils/copy_to_here.py +302 -0
  329. machineconfig/utils/ssh_utils/utils.py +142 -0
  330. machineconfig/utils/ssh_utils/wsl.py +210 -0
  331. machineconfig/utils/terminal.py +3 -113
  332. machineconfig/utils/tst.py +20 -0
  333. machineconfig/utils/upgrade_packages.py +114 -28
  334. machineconfig/utils/ve.py +12 -4
  335. machineconfig-7.98.dist-info/METADATA +132 -0
  336. machineconfig-7.98.dist-info/RECORD +504 -0
  337. machineconfig-7.98.dist-info/entry_points.txt +13 -0
  338. machineconfig/cluster/sessions_managers/ffile.py +0 -4
  339. machineconfig/jobs/installer/linux_scripts/pgsql.sh +0 -49
  340. machineconfig/jobs/installer/linux_scripts/timescaledb.sh +0 -85
  341. machineconfig/jobs/linux/msc/cli_agents.sh +0 -16
  342. machineconfig/jobs/python/python_ve_symlink.py +0 -37
  343. machineconfig/jobs/python/vscode/api.py +0 -57
  344. machineconfig/jobs/python/vscode/sync_code.py +0 -73
  345. machineconfig/jobs/windows/archive/archive_pygraphviz.ps1 +0 -14
  346. machineconfig/jobs/windows/start_terminal.ps1 +0 -6
  347. machineconfig/jobs/windows/startup_file.cmd +0 -2
  348. machineconfig/profile/create.py +0 -303
  349. machineconfig/profile/shell.py +0 -176
  350. machineconfig/scripts/cloud/init.sh +0 -119
  351. machineconfig/scripts/linux/agents +0 -2
  352. machineconfig/scripts/linux/choose_wezterm_theme +0 -3
  353. machineconfig/scripts/linux/cloud_copy +0 -2
  354. machineconfig/scripts/linux/cloud_mount +0 -2
  355. machineconfig/scripts/linux/cloud_repo_sync +0 -2
  356. machineconfig/scripts/linux/cloud_sync +0 -2
  357. machineconfig/scripts/linux/croshell +0 -3
  358. machineconfig/scripts/linux/devops +0 -2
  359. machineconfig/scripts/linux/fire +0 -2
  360. machineconfig/scripts/linux/ftpx +0 -2
  361. machineconfig/scripts/linux/fzf2g +0 -21
  362. machineconfig/scripts/linux/fzfag +0 -17
  363. machineconfig/scripts/linux/fzffg +0 -25
  364. machineconfig/scripts/linux/fzfrga +0 -21
  365. machineconfig/scripts/linux/gh_models +0 -2
  366. machineconfig/scripts/linux/initai +0 -2
  367. machineconfig/scripts/linux/kill_process +0 -2
  368. machineconfig/scripts/linux/scheduler +0 -2
  369. machineconfig/scripts/linux/sessions +0 -2
  370. machineconfig/scripts/linux/share_smb +0 -1
  371. machineconfig/scripts/linux/skrg +0 -4
  372. machineconfig/scripts/linux/start_slidev +0 -2
  373. machineconfig/scripts/linux/start_terminals +0 -3
  374. machineconfig/scripts/linux/warp-cli.sh +0 -122
  375. machineconfig/scripts/linux/wifi_conn +0 -2
  376. machineconfig/scripts/linux/z_ls +0 -104
  377. machineconfig/scripts/python/ai/generate_files.py +0 -83
  378. machineconfig/scripts/python/ai/solutions/copilot/prompts/allLintersAndTypeCheckers.prompt.md +0 -5
  379. machineconfig/scripts/python/cloud_repo_sync.py +0 -190
  380. machineconfig/scripts/python/count_lines_frontend.py +0 -16
  381. machineconfig/scripts/python/devops_add_ssh_key.py +0 -120
  382. machineconfig/scripts/python/dotfile.py +0 -78
  383. machineconfig/scripts/python/fire_agents_help_launch.py +0 -120
  384. machineconfig/scripts/python/fire_agents_helper_types.py +0 -12
  385. machineconfig/scripts/python/fire_jobs_route_helper.py +0 -65
  386. machineconfig/scripts/python/get_zellij_cmd.py +0 -15
  387. machineconfig/scripts/python/gh_models.py +0 -104
  388. machineconfig/scripts/python/helpers/repo_sync_helpers.py +0 -116
  389. machineconfig/scripts/python/repos.py +0 -132
  390. machineconfig/scripts/python/repos_helper_action.py +0 -378
  391. machineconfig/scripts/python/snapshot.py +0 -25
  392. machineconfig/scripts/python/start_terminals.py +0 -121
  393. machineconfig/scripts/python/t4.py +0 -17
  394. machineconfig/scripts/windows/agents.ps1 +0 -1
  395. machineconfig/scripts/windows/choose_wezterm_theme.ps1 +0 -1
  396. machineconfig/scripts/windows/cloud_copy.ps1 +0 -1
  397. machineconfig/scripts/windows/cloud_mount.ps1 +0 -1
  398. machineconfig/scripts/windows/cloud_repo_sync.ps1 +0 -1
  399. machineconfig/scripts/windows/cloud_sync.ps1 +0 -1
  400. machineconfig/scripts/windows/croshell.ps1 +0 -1
  401. machineconfig/scripts/windows/devops.ps1 +0 -1
  402. machineconfig/scripts/windows/dotfile.ps1 +0 -1
  403. machineconfig/scripts/windows/fire.ps1 +0 -1
  404. machineconfig/scripts/windows/ftpx.ps1 +0 -1
  405. machineconfig/scripts/windows/fzfb.ps1 +0 -3
  406. machineconfig/scripts/windows/fzfg.ps1 +0 -2
  407. machineconfig/scripts/windows/fzfrga.bat +0 -20
  408. machineconfig/scripts/windows/gpt.ps1 +0 -1
  409. machineconfig/scripts/windows/grep.ps1 +0 -2
  410. machineconfig/scripts/windows/initai.ps1 +0 -1
  411. machineconfig/scripts/windows/kill_process.ps1 +0 -1
  412. machineconfig/scripts/windows/nano.ps1 +0 -3
  413. machineconfig/scripts/windows/pomodoro.ps1 +0 -1
  414. machineconfig/scripts/windows/reload_path.ps1 +0 -3
  415. machineconfig/scripts/windows/scheduler.ps1 +0 -1
  416. machineconfig/scripts/windows/sessions.ps1 +0 -1
  417. machineconfig/scripts/windows/snapshot.ps1 +0 -1
  418. machineconfig/scripts/windows/start_slidev.ps1 +0 -1
  419. machineconfig/scripts/windows/start_terminals.ps1 +0 -1
  420. machineconfig/scripts/windows/wifi_conn.ps1 +0 -2
  421. machineconfig/scripts/windows/wsl_rdp_windows_port_forwarding.ps1 +0 -46
  422. machineconfig/scripts/windows/wsl_ssh_windows_port_forwarding.ps1 +0 -76
  423. machineconfig/settings/lf/linux/exe/fzf_nano.sh +0 -16
  424. machineconfig/settings/lf/windows/fzf_edit.ps1 +0 -6
  425. machineconfig/settings/lf/windows/tst.ps1 +0 -1
  426. machineconfig/settings/yazi/yazi.toml +0 -4
  427. machineconfig/setup_linux/nix/cli_installation.sh +0 -157
  428. machineconfig/setup_linux/others/openssh-server_add_pub_key.sh +0 -57
  429. machineconfig/setup_linux/web_shortcuts/croshell.sh +0 -11
  430. machineconfig/setup_linux/web_shortcuts/ssh.sh +0 -52
  431. machineconfig/setup_windows/web_shortcuts/all.ps1 +0 -18
  432. machineconfig/setup_windows/web_shortcuts/ascii_art.ps1 +0 -36
  433. machineconfig/setup_windows/web_shortcuts/croshell.ps1 +0 -16
  434. machineconfig/setup_windows/web_shortcuts/ssh.ps1 +0 -11
  435. machineconfig/utils/ai/generate_file_checklist.py +0 -68
  436. machineconfig/utils/installer_utils/installer.py +0 -189
  437. machineconfig-5.15.dist-info/METADATA +0 -188
  438. machineconfig-5.15.dist-info/RECORD +0 -415
  439. machineconfig-5.15.dist-info/entry_points.txt +0 -18
  440. machineconfig/cluster/sessions_managers/{utils → helpers}/load_balancer_helper.py +0 -0
  441. machineconfig/scripts/linux/{share_nfs → other/share_nfs} +0 -0
  442. machineconfig/scripts/linux/{start_docker → other/start_docker} +0 -0
  443. machineconfig/scripts/linux/{switch_ip → other/switch_ip} +0 -0
  444. machineconfig/{jobs/python → scripts/python/ai/utils}/__init__.py +0 -0
  445. machineconfig/scripts/python/{helpers → helpers_agents}/__init__.py +0 -0
  446. machineconfig/{jobs/windows/msc/cli_agents.bat → scripts/python/helpers_agents/agentic_frameworks/__init__.py} +0 -0
  447. machineconfig/scripts/python/{fire_agents_help_search.py → helpers_agents/fire_agents_help_search.py} +0 -0
  448. machineconfig/scripts/python/{fire_agents_load_balancer.py → helpers_agents/fire_agents_load_balancer.py} +0 -0
  449. machineconfig/{jobs/windows/msc/cli_agents.ps1 → scripts/python/helpers_cloud/__init__.py} +0 -0
  450. machineconfig/scripts/python/{helpers → helpers_cloud}/cloud_helpers.py +1 -1
  451. /machineconfig/scripts/python/{helpers → helpers_cloud}/helpers5.py +0 -0
  452. /machineconfig/scripts/python/{fire_jobs_streamlit_helper.py → helpers_croshell/__init__.py} +0 -0
  453. /machineconfig/scripts/python/{pomodoro.py → helpers_croshell/pomodoro.py} +0 -0
  454. /machineconfig/scripts/python/{scheduler.py → helpers_croshell/scheduler.py} +0 -0
  455. /machineconfig/scripts/python/{viewer.py → helpers_croshell/viewer.py} +0 -0
  456. /machineconfig/scripts/python/{viewer_template.py → helpers_croshell/viewer_template.py} +0 -0
  457. /machineconfig/scripts/{windows/share_nfs.ps1 → python/helpers_devops/__init__.py} +0 -0
  458. /machineconfig/{settings/shells/pwsh/profile.ps1 → scripts/python/helpers_devops/themes/__init__.py} +0 -0
  459. /machineconfig/{settings/yazi/keymap.toml → scripts/python/helpers_devops/themes/choose_starship_theme.ps1} +0 -0
  460. /machineconfig/scripts/python/{cloud_manager.py → helpers_fire_command/cloud_manager.py} +0 -0
  461. /machineconfig/scripts/{linux → python/helpers_network}/mount_drive +0 -0
  462. /machineconfig/scripts/python/{mount_nw_drive.py → helpers_network/mount_nw_drive.py} +0 -0
  463. /machineconfig/scripts/{linux → python/helpers_network}/mount_smb +0 -0
  464. /machineconfig/scripts/windows/{mount_nw.ps1 → mounts/mount_nw.ps1} +0 -0
  465. /machineconfig/scripts/windows/{mount_smb.ps1 → mounts/mount_smb.ps1} +0 -0
  466. /machineconfig/scripts/windows/{share_cloud.cmd → mounts/share_cloud.cmd} +0 -0
  467. /machineconfig/scripts/windows/{unlock_bitlocker.ps1 → mounts/unlock_bitlocker.ps1} +0 -0
  468. /machineconfig/setup_linux/{web_shortcuts → others}/android.sh +0 -0
  469. /machineconfig/{jobs/windows/archive → setup_windows/ssh}/openssh-server_add_key.ps1 +0 -0
  470. /machineconfig/{jobs/windows/archive → setup_windows/ssh}/openssh-server_copy-ssh-id.ps1 +0 -0
  471. {machineconfig-5.15.dist-info → machineconfig-7.98.dist-info}/WHEEL +0 -0
  472. {machineconfig-5.15.dist-info → machineconfig-7.98.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,175 @@
1
+ """Devops Devapps Install
2
+
3
+
4
+ sudo apt update && sudo apt install -y \
5
+ git gcc g++ clang \
6
+ yasm nasm pkg-config \
7
+ meson ninja-build \
8
+ autoconf automake libtool \
9
+ libx11-dev libxext-dev libxrandr-dev libxrender-dev libxss-dev \
10
+ libvdpau-dev libgl1-mesa-dev libegl1-mesa-dev libxv-dev \
11
+ libasound2-dev libpulse-dev \
12
+ libfribidi-dev libfreetype-dev libfontconfig1-dev libharfbuzz-dev \
13
+ libjpeg-dev libssl-dev zlib1g-dev python3-pip
14
+
15
+
16
+ """
17
+
18
+ from machineconfig.utils.installer_utils.installer_helper import get_group_name_to_repr
19
+ import typer
20
+ from typing import Annotated, Optional
21
+
22
+
23
+
24
+ def main_installer_cli(
25
+ which: Annotated[Optional[str], typer.Argument(..., help="Comma-separated list of program/groups names to install (if --group flag is set).")] = None,
26
+ group: Annotated[bool, typer.Option(..., "--group", "-g", help="Treat 'which' as a group name. A group is bundle of apps.")] = False,
27
+ interactive: Annotated[bool, typer.Option(..., "--interactive", "-i", help="Interactive selection of programs to install.")] = False,
28
+ ) -> None:
29
+ if interactive:
30
+ return install_interactively()
31
+ if which is not None:
32
+ if group:
33
+ for a_group in [x.strip() for x in which.split(",") if x.strip() != ""]:
34
+ return install_group(package_group=a_group)
35
+ else:
36
+ return install_clis(clis_names=[x.strip() for x in which.split(",") if x.strip() != ""])
37
+ else:
38
+ if group:
39
+ from rich.console import Console
40
+ from rich.table import Table
41
+ console = Console()
42
+
43
+ typer.echo("❌ You must provide a group name when using the --group/-g option.")
44
+ from machineconfig.utils.installer_utils.installer_helper import get_group_name_to_repr
45
+ res = get_group_name_to_repr()
46
+ console.print("[bold blue]Here are the available groups:[/bold blue]")
47
+ table = Table(show_header=True, header_style="bold magenta")
48
+ table.add_column("Group", style="cyan", no_wrap=True)
49
+ table.add_column("AppsBundled", style="green", overflow="fold")
50
+ for display, group_name in res.items():
51
+ # Parse display
52
+ if " -- " in display:
53
+ group_part, items_part = display.split(" -- ", 1)
54
+ group_name_parsed = group_part.replace("📦 ", "").strip()
55
+ items_str = items_part.strip()
56
+ else:
57
+ group_name_parsed = display
58
+ items_str = group_name
59
+ table.add_row(group_name_parsed, items_str)
60
+ console.print(table)
61
+ raise typer.Exit(1)
62
+ typer.echo("❌ You must provide either a program name/group name, or use --interactive/-ia option.")
63
+ import click
64
+ ctx = click.get_current_context()
65
+ typer.echo(ctx.get_help())
66
+ raise typer.Exit(1)
67
+
68
+
69
+
70
+
71
+
72
+ def install_interactively():
73
+ from machineconfig.utils.options import choose_from_options
74
+ from machineconfig.utils.schemas.installer.installer_types import get_normalized_arch, get_os_name
75
+ from machineconfig.utils.installer_utils.installer_runner import get_installers
76
+ from machineconfig.utils.installer_utils.installer_class import Installer
77
+ from rich.console import Console
78
+ from rich.panel import Panel
79
+ # from rich.table import Table
80
+ installers = get_installers(os=get_os_name(), arch=get_normalized_arch(), which_cats=None)
81
+ installer_options = [Installer(installer_data=x).get_description() for x in installers]
82
+ category_display_to_name = get_group_name_to_repr()
83
+ options = list(category_display_to_name.keys()) + installer_options
84
+ program_names = choose_from_options(multi=True, msg="Categories are prefixed with 📦", options=options, header="🚀 CHOOSE DEV APP OR CATEGORY", tv=True)
85
+ installation_messages: list[str] = []
86
+ for _an_idx, a_program_name in enumerate(program_names):
87
+ if a_program_name.startswith("📦 "):
88
+ category_name = category_display_to_name.get(a_program_name)
89
+ if category_name:
90
+ install_group(package_group=category_name)
91
+ else:
92
+ installer_idx = installer_options.index(a_program_name)
93
+ an_installer_data = installers[installer_idx]
94
+ status_message = Installer(an_installer_data).install_robust(version=None) # finish the task - this returns a status message, not a command
95
+ installation_messages.append(status_message)
96
+ if installation_messages:
97
+ console = Console()
98
+
99
+ panel = Panel("\n".join([f"[blue]• {message}[/blue]" for message in installation_messages]), title="[bold green]📊 Installation Summary[/bold green]", border_style="green", padding=(1, 2))
100
+ console.print(panel)
101
+
102
+
103
+ def install_group(package_group: str):
104
+ from machineconfig.utils.installer_utils.installer_runner import get_installers, install_bulk
105
+ from machineconfig.utils.schemas.installer.installer_types import get_normalized_arch, get_os_name
106
+ from rich.console import Console
107
+ from rich.panel import Panel
108
+ # from rich.table import Table
109
+ from machineconfig.jobs.installer.package_groups import PACKAGE_GROUP2NAMES
110
+ if package_group in PACKAGE_GROUP2NAMES:
111
+ panel = Panel(f"[bold yellow]Installing programs from category: [green]{package_group}[/green][/bold yellow]", title="[bold blue]📦 Category Installation[/bold blue]", border_style="blue", padding=(1, 2))
112
+ console = Console()
113
+ console.print(panel)
114
+ installers_ = get_installers(os=get_os_name(), arch=get_normalized_arch(), which_cats=[package_group])
115
+ install_bulk(installers_data=installers_)
116
+ return
117
+ console = Console()
118
+ console.print(f"❌ ERROR: Unknown package group: {package_group}. Available groups are: {list(PACKAGE_GROUP2NAMES.keys())}")
119
+
120
+
121
+ def install_clis(clis_names: list[str]):
122
+ from machineconfig.utils.schemas.installer.installer_types import get_normalized_arch, get_os_name
123
+ from machineconfig.utils.installer_utils.installer_runner import get_installers
124
+ from machineconfig.utils.installer_utils.installer_class import Installer
125
+ from rich.console import Console
126
+ all_installers_data = get_installers(os=get_os_name(), arch=get_normalized_arch(), which_cats=None)
127
+ total_messages: list[str] = []
128
+ for a_cli_name in clis_names:
129
+ if "github.com" in a_cli_name.lower():
130
+ from machineconfig.utils.installer_utils.install_from_url import install_from_github_url
131
+ install_from_github_url(github_url=a_cli_name)
132
+ continue
133
+ elif a_cli_name.startswith("https://") or a_cli_name.startswith("http://"):
134
+ print(f"⏳ Installing from binary URL: {a_cli_name} ...")
135
+ from machineconfig.utils.installer_utils.install_from_url import install_from_binary_url
136
+ install_from_binary_url(binary_url=a_cli_name)
137
+ continue
138
+ selected_installer = None
139
+ for installer in all_installers_data:
140
+ app_name = installer["appName"]
141
+ if app_name.lower() == a_cli_name.lower():
142
+ selected_installer = installer
143
+ break
144
+ if selected_installer is None:
145
+ from machineconfig.utils.installer_utils.installer_helper import handle_installer_not_found
146
+ handle_installer_not_found(a_cli_name, all_installers_data)
147
+ return None
148
+ message = Installer(selected_installer).install_robust(version=None) # finish the task
149
+ total_messages.append(message)
150
+ if total_messages:
151
+ console = Console()
152
+ console.print("\n[bold green]📊 Installation Results:[/bold green]")
153
+ for a_message in total_messages:
154
+ console.print(f"[blue]• {a_message}[/blue]")
155
+ return None
156
+ def install_if_missing(which: str) -> bool:
157
+ from machineconfig.utils.installer_utils.installer_locator_utils import check_tool_exists
158
+ exists = check_tool_exists(which)
159
+ if exists:
160
+ print(f"✅ {which} is already installed.")
161
+ return True
162
+ print(f"⏳ {which} not found. Installing...")
163
+ from machineconfig.utils.installer_utils.installer_cli import main_installer_cli
164
+ try:
165
+ main_installer_cli(which=which, interactive=False)
166
+ return True
167
+ except Exception as e:
168
+ print(f"❌ Error installing {which}: {e}")
169
+ return False
170
+
171
+ if __name__ == "__main__":
172
+ from machineconfig.utils.schemas.installer.installer_types import InstallerData
173
+ from machineconfig.utils.installer_utils.installer_class import Installer
174
+ _ = InstallerData, Installer
175
+ pass
@@ -0,0 +1,129 @@
1
+ from machineconfig.jobs.installer.package_groups import PACKAGE_GROUP2NAMES
2
+ from machineconfig.utils.schemas.installer.installer_types import InstallerData
3
+ from pathlib import Path
4
+ from machineconfig.utils.path_extended import DECOMPRESS_SUPPORTED_FORMATS, PathExtended
5
+ from machineconfig.utils.source_of_truth import INSTALL_TMP_DIR
6
+
7
+
8
+ def get_group_name_to_repr() -> dict[str, str]:
9
+ # Build category options and maintain a mapping from display text to actual category name
10
+ category_display_to_name: dict[str, str] = {}
11
+ for group_name, group_values in PACKAGE_GROUP2NAMES.items():
12
+ display = f"📦 {group_name:<20}" + " -- " + f"{'|'.join(group_values):<60}"
13
+ category_display_to_name[display] = group_name
14
+ return category_display_to_name
15
+
16
+
17
+ def handle_installer_not_found(search_term: str, app_apps: list[InstallerData]) -> None: # type: ignore
18
+ """Handle installer not found with friendly suggestions using fuzzy matching."""
19
+ from difflib import get_close_matches
20
+ from rich.console import Console
21
+ from rich.panel import Panel
22
+ from rich.table import Table
23
+ all_names = sorted([inst["appName"] for inst in app_apps])
24
+ name_to_doc = {inst["appName"]: inst["doc"] for inst in app_apps}
25
+ all_descriptions = {f"{inst['appName']}: {inst['doc']}": inst["appName"] for inst in app_apps}
26
+
27
+ close_name_matches = get_close_matches(search_term, all_names, n=5, cutoff=0.4)
28
+ close_description_matches = get_close_matches(search_term, list(all_descriptions.keys()), n=5, cutoff=0.4)
29
+
30
+ search_lower = search_term.lower()
31
+ substring_matches = [
32
+ inst["appName"]
33
+ for inst in app_apps
34
+ if search_lower in inst["appName"].lower() or search_lower in inst["doc"].lower()
35
+ ]
36
+
37
+ ordered_matches: list[str] = list(
38
+ dict.fromkeys(
39
+ close_name_matches
40
+ + [all_descriptions[desc] for desc in close_description_matches]
41
+ + substring_matches
42
+ )
43
+ )
44
+ top_matches = ordered_matches[:10]
45
+ console = Console()
46
+
47
+ console.print(f"\n❌ '[red]{search_term}[/red]' was not found.", style="bold")
48
+ if top_matches:
49
+ console.print("🤔 Did you mean one of these?", style="yellow")
50
+ table = Table(show_header=True, header_style="bold", box=None, pad_edge=False)
51
+ table.add_column("#", justify="right", width=3)
52
+ table.add_column("Installer", style="green")
53
+ table.add_column("Description", style="dim", overflow="fold")
54
+ for i, match in enumerate(top_matches, 1):
55
+ table.add_row(f"[cyan]{i}[/cyan]", match, name_to_doc.get(match, ""))
56
+ console.print(table)
57
+ else:
58
+ console.print("📋 Here are some available options:", style="blue")
59
+ # Show first 10 installers as examples
60
+ if len(all_names) > 10:
61
+ sample_names = all_names[:10]
62
+ else:
63
+ sample_names = all_names
64
+ table = Table(show_header=True, header_style="bold", box=None, pad_edge=False)
65
+ table.add_column("#", justify="right", width=3)
66
+ table.add_column("Installer", style="green")
67
+ table.add_column("Description", style="dim", overflow="fold")
68
+ for i, name in enumerate(sample_names, 1):
69
+ table.add_row(f"[cyan]{i}[/cyan]", name, name_to_doc.get(name, ""))
70
+ console.print(table)
71
+ if len(all_names) > 10:
72
+ console.print(f" [dim]... and {len(all_names) - 10} more[/dim]")
73
+
74
+ panel = Panel(f"[bold blue]💡 Use 'ia' to interactively browse all available installers.[/bold blue]\n[bold blue]💡 Use one of the categories: {list(PACKAGE_GROUP2NAMES.keys())}[/bold blue]", title="[yellow]Helpful Tips[/yellow]", border_style="yellow")
75
+ console.print(panel)
76
+
77
+
78
+ def install_deb_package(downloaded: Path) -> None:
79
+ from rich import print as rprint
80
+ from rich.panel import Panel
81
+ print(f"📦 Installing .deb package: {downloaded}")
82
+ import platform
83
+ import subprocess
84
+ assert platform.system() == "Linux"
85
+ result = subprocess.run(f"sudo nala install -y {downloaded}", shell=True, capture_output=True, text=True)
86
+ success = result.returncode == 0 and result.stderr == ""
87
+ if not success:
88
+ from rich.console import Group
89
+ desc = "Installing .deb"
90
+ sub_panels = []
91
+ if result.stdout:
92
+ sub_panels.append(Panel(result.stdout, title="STDOUT", style="blue"))
93
+ if result.stderr:
94
+ sub_panels.append(Panel(result.stderr, title="STDERR", style="red"))
95
+ group_content = Group(f"❌ {desc} failed\nReturn code: {result.returncode}", *sub_panels)
96
+ rprint(Panel(group_content, title=desc, style="red"))
97
+ print("🗑️ Cleaning up .deb package...")
98
+ if downloaded.is_file():
99
+ downloaded.unlink(missing_ok=True)
100
+ elif downloaded.is_dir():
101
+ import shutil
102
+ shutil.rmtree(downloaded, ignore_errors=True)
103
+
104
+
105
+ def download_and_prepare(download_url: str) -> PathExtended:
106
+ # archive_path = PathExtended(download_url).download(folder=INSTALL_TMP_DIR)
107
+ from machineconfig.scripts.python.helpers_utils.download import download
108
+ downloaded_object = download(download_url, output_dir=str(INSTALL_TMP_DIR))
109
+ if downloaded_object is None:
110
+ raise ValueError(f"Failed to download from URL: {download_url}")
111
+ archive_path = PathExtended(downloaded_object)
112
+ extracted_path = archive_path
113
+ if extracted_path.is_file() and any(ext in archive_path.suffixes for ext in DECOMPRESS_SUPPORTED_FORMATS):
114
+ extracted_path = archive_path.decompress()
115
+ # print(f"Decompressed {archive_path} to {extracted_path}")
116
+ archive_path.delete(sure=True)
117
+ if extracted_path.is_dir():
118
+ nested_items = list(extracted_path.glob("*"))
119
+ if len(nested_items) == 1:
120
+ nested_path = PathExtended(nested_items[0])
121
+ if nested_path.is_file() and any(ex in nested_path.suffixes for ex in DECOMPRESS_SUPPORTED_FORMATS):
122
+ extracted_path = nested_path.decompress()
123
+ nested_path.delete(sure=True)
124
+ elif extracted_path.is_dir() and len(extracted_path.search("*", r=True)) == 1:
125
+ only_file_in = next(extracted_path.glob("*"))
126
+ if only_file_in.is_file() and any(ext in str(only_file_in) for ext in DECOMPRESS_SUPPORTED_FORMATS): # further decompress
127
+ extracted_path = only_file_in.decompress()
128
+ only_file_in.delete(sure=True)
129
+ return extracted_path
@@ -1,4 +1,3 @@
1
-
2
1
  from machineconfig.utils.path_extended import PathExtended
3
2
  from machineconfig.utils.source_of_truth import WINDOWS_INSTALL_PATH, LINUX_INSTALL_PATH, INSTALL_VERSION_ROOT
4
3
 
@@ -8,23 +7,28 @@ import subprocess
8
7
  import platform
9
8
 
10
9
 
11
- def find_move_delete_windows(downloaded_file_path: PathExtended, exe_name: Optional[str] = None, delete: bool = True, rename_to: Optional[str] = None):
12
- print(f"\n{'=' * 80}\n🔍 PROCESSING WINDOWS EXECUTABLE 🔍\n{'=' * 80}")
13
- if exe_name is not None and ".exe" in exe_name:
14
- exe_name = exe_name.replace(".exe", "")
10
+ def find_move_delete_windows(downloaded_file_path: PathExtended, tool_name: Optional[str], delete: bool, rename_to: Optional[str]):
11
+ # print("🔍 PROCESSING WINDOWS EXECUTABLE 🔍")
12
+ # if exe_name is not None and len(exe_name.split("+")) > 1:
13
+ # last_result = None
14
+ # for a_binary in [x.strip() for x in exe_name.split("+") if x.strip() != ""]:
15
+ # last_result = find_move_delete_windows(downloaded_file_path=downloaded_file_path, exe_name=a_binary, delete=delete, rename_to=rename_to)
16
+ # return last_result
17
+ if tool_name is not None and ".exe" in tool_name:
18
+ tool_name = tool_name.replace(".exe", "")
15
19
  if downloaded_file_path.is_file():
16
20
  exe = downloaded_file_path
17
21
  print(f"📄 Found direct executable file: {exe}")
18
22
  else:
19
23
  print(f"🔎 Searching for executable in: {downloaded_file_path}")
20
- if exe_name is None:
24
+ if tool_name is None:
21
25
  exe = downloaded_file_path.search("*.exe", r=True)[0]
22
26
  print(f"✅ Found executable: {exe}")
23
27
  else:
24
- tmp = downloaded_file_path.search(f"{exe_name}.exe", r=True)
28
+ tmp = downloaded_file_path.search(f"{tool_name}.exe", r=True)
25
29
  if len(tmp) == 1:
26
30
  exe = tmp[0]
27
- print(f"✅ Found exact match for {exe_name}.exe: {exe}")
31
+ print(f"✅ Found exact match for {tool_name}.exe: {exe}")
28
32
  else:
29
33
  search_res = downloaded_file_path.search("*.exe", r=True)
30
34
  if len(search_res) == 0:
@@ -53,8 +57,14 @@ def find_move_delete_windows(downloaded_file_path: PathExtended, exe_name: Optio
53
57
  return exe_new_location
54
58
 
55
59
 
56
- def find_move_delete_linux(downloaded: PathExtended, tool_name: str, delete: Optional[bool] = True, rename_to: Optional[str] = None):
57
- print(f"\n{'=' * 80}\n🔍 PROCESSING LINUX EXECUTABLE 🔍\n{'=' * 80}")
60
+ def find_move_delete_linux(downloaded: PathExtended, tool_name: Optional[str], delete: bool, rename_to: Optional[str]):
61
+ # if len(tool_name.split("+")) > 1:
62
+ # last_result = None
63
+ # for a_binary in [x.strip() for x in tool_name.split("+") if x.strip() != ""]:
64
+ # last_result = find_move_delete_linux(downloaded=downloaded, tool_name=a_binary, delete=False, rename_to=rename_to)
65
+ # return last_result
66
+
67
+ print("🔍 PROCESSING LINUX EXECUTABLE 🔍")
58
68
  if downloaded.is_file():
59
69
  exe = downloaded
60
70
  print(f"📄 Found direct executable file: {exe}")
@@ -65,16 +75,24 @@ def find_move_delete_linux(downloaded: PathExtended, tool_name: str, delete: Opt
65
75
  exe = res[0]
66
76
  print(f"✅ Found match for pattern '*{tool_name}*': {exe}")
67
77
  else:
68
- exe_search_res = downloaded.search(tool_name, folders=False, r=True)
69
- if len(exe_search_res) == 0:
70
- print(f"❌ ERROR: No search results for `{tool_name}` in `{downloaded}`")
71
- raise IndexError(f"No executable found in {downloaded}")
72
- elif len(exe_search_res) == 1:
73
- exe = exe_search_res[0]
74
- print(f"✅ Found exact match for '{tool_name}': {exe}")
75
- else:
76
- exe = max(exe_search_res, key=lambda x: x.size("kb"))
78
+ if tool_name is None: # no tool name provided, get the largest executable
79
+ search_res = downloaded.search("*", folders=False, files=True, r=True)
80
+ if len(search_res) == 0:
81
+ print(f"❌ ERROR: No search results in `{downloaded}`")
82
+ raise IndexError(f"No executable found in {downloaded}")
83
+ exe = max(search_res, key=lambda x: x.size("kb"))
77
84
  print(f"✅ Selected largest executable ({exe.size('kb')} KB): {exe}")
85
+ else:
86
+ exe_search_res = downloaded.search(tool_name, folders=False, r=True)
87
+ if len(exe_search_res) == 0:
88
+ print(f"❌ ERROR: No search results for `{tool_name}` in `{downloaded}`")
89
+ raise IndexError(f"No executable found in {downloaded}")
90
+ elif len(exe_search_res) == 1:
91
+ exe = exe_search_res[0]
92
+ print(f"✅ Found exact match for '{tool_name}': {exe}")
93
+ else:
94
+ exe = max(exe_search_res, key=lambda x: x.size("kb"))
95
+ print(f"✅ Selected largest executable ({exe.size('kb')} KB): {exe}")
78
96
 
79
97
  if rename_to and exe.name != rename_to:
80
98
  print(f"🏷️ Renaming '{exe.name}' to '{rename_to}'")
@@ -108,33 +126,52 @@ def find_move_delete_linux(downloaded: PathExtended, tool_name: str, delete: Opt
108
126
  print("✅ Temporary files removed")
109
127
 
110
128
  exe_new_location = PathExtended(LINUX_INSTALL_PATH).joinpath(exe.name)
111
- print(f"✅ Executable installed at: {exe_new_location}\n{'=' * 80}")
129
+ print(f"✅ Executable installed at: {exe_new_location}")
112
130
  return exe_new_location
113
131
 
114
132
 
115
133
  def check_tool_exists(tool_name: str) -> bool:
116
134
  if platform.system() == "Windows":
117
- tool_name = tool_name.replace(".exe", "") + ".exe"
118
- res1 = any([Path(WINDOWS_INSTALL_PATH).joinpath(tool_name).is_file(), Path.home().joinpath("AppData/Roaming/npm").joinpath(tool_name).is_file()])
119
- tool_name = tool_name.replace(".exe", "") + ".exe"
120
- res2 = any([Path(WINDOWS_INSTALL_PATH).joinpath(tool_name).is_file(), Path.home().joinpath("AppData/Roaming/npm").joinpath(tool_name).is_file()])
121
- return res1 or res2
135
+ tool_name_exe = tool_name.replace(".exe", "") + ".exe"
136
+ res1 = any([Path(WINDOWS_INSTALL_PATH).joinpath(tool_name_exe).is_file(), Path.home().joinpath("AppData/Roaming/npm").joinpath(tool_name_exe).is_file()])
137
+ if res1:
138
+ return True
139
+ tool_name_no_exe = tool_name.replace(".exe", "")
140
+ res2 = any([Path(WINDOWS_INSTALL_PATH).joinpath(tool_name_no_exe).is_file(), Path.home().joinpath("AppData/Roaming/npm").joinpath(tool_name_no_exe).is_file()])
141
+ return res2
122
142
  elif platform.system() in ["Linux", "Darwin"]:
123
143
  root_path = Path(LINUX_INSTALL_PATH)
124
- return any([Path("/usr/local/bin").joinpath(tool_name).is_file(), Path("/usr/bin").joinpath(tool_name).is_file(), root_path.joinpath(tool_name).is_file()])
144
+ standard_checks = [
145
+ Path("/usr/local/bin").joinpath(tool_name).is_file(),
146
+ Path("/usr/bin").joinpath(tool_name).is_file(),
147
+ root_path.joinpath(tool_name).is_file()
148
+ ]
149
+ if any(standard_checks):
150
+ return True
151
+ # Check for npm packages via nvm
152
+ npm_check = False
153
+ try:
154
+ result = subprocess.run(["node", "--version"], capture_output=True, text=True, check=True)
155
+ version = result.stdout.strip().lstrip('v')
156
+ nvm_bin_path = Path.home() / ".nvm" / "versions" / "node" / f"v{version}" / "bin" / tool_name
157
+ npm_check = nvm_bin_path.is_file()
158
+ except subprocess.CalledProcessError:
159
+ pass
160
+ return npm_check
125
161
  else:
126
162
  raise NotImplementedError(f"platform {platform.system()} not implemented")
127
- def is_executable_in_path(executable_name: str) -> bool:
163
+
164
+ def is_executable_in_path(name: str) -> bool:
128
165
  import os
129
166
  path_dirs = os.environ['PATH'].split(os.pathsep)
130
167
  for path_dir in path_dirs:
131
- path_to_executable = os.path.join(path_dir, executable_name)
168
+ path_to_executable = os.path.join(path_dir, name)
132
169
  if os.path.isfile(path_to_executable) and os.access(path_to_executable, os.X_OK): return True
133
170
  return False
134
171
 
135
172
 
136
173
  def check_if_installed_already(exe_name: str, version: Optional[str], use_cache: bool) -> tuple[str, str, str]:
137
- print(f"\n{'=' * 80}\n🔍 CHECKING INSTALLATION STATUS: {exe_name} 🔍\n{'=' * 80}")
174
+ print(f"🔍 CHECKING INSTALLATION STATUS: {exe_name} 🔍")
138
175
  INSTALL_VERSION_ROOT.joinpath(exe_name).parent.mkdir(parents=True, exist_ok=True)
139
176
  tmp_path = INSTALL_VERSION_ROOT.joinpath(exe_name)
140
177
 
@@ -173,71 +210,3 @@ def check_if_installed_already(exe_name: str, version: Optional[str], use_cache:
173
210
  return ("⚠️ NotInstalled", "None", version or "unknown")
174
211
 
175
212
 
176
- def parse_apps_installer_linux(txt: str) -> dict[str, tuple[str, str]]:
177
- """Parse Linux shell installation scripts into logical chunks.
178
-
179
- Splits scripts by # --GROUP:<name>:<description> comment signatures into a dictionary
180
- mapping block names to (description, shell script content) tuples.
181
-
182
- Returns:
183
- dict[str, tuple[str, str]]: Dictionary mapping block/section names to (description, installation_script) tuples
184
- """
185
- chunks = txt.split('# --GROUP:')
186
- res: dict[str, tuple[str, str]] = {}
187
-
188
- for chunk in chunks[1:]: # Skip first empty chunk before first group
189
- lines = chunk.split('\n')
190
- # First line contains the group name and description in format "NAME:DESCRIPTION"
191
- group_line = lines[0].strip()
192
-
193
- # Extract group name and description
194
- if ':' in group_line:
195
- parts = group_line.split(':', 1) # Split only on first colon
196
- group_name = parts[0].strip()
197
- group_description = parts[1].strip() if len(parts) > 1 else ""
198
- else:
199
- group_name = group_line
200
- group_description = ""
201
-
202
- # Rest is the content
203
- content = '\n'.join(lines[1:]).strip()
204
-
205
- if group_name and content:
206
- res[group_name] = (group_description, content)
207
-
208
- return res
209
-
210
-
211
- def parse_apps_installer_windows(txt: str) -> dict[str, tuple[str, str]]:
212
- """Parse Windows PowerShell installation scripts into logical chunks.
213
-
214
- Splits scripts by # --GROUP:<name>:<description> comment signatures into a dictionary
215
- mapping block names to (description, PowerShell script content) tuples.
216
-
217
- Returns:
218
- dict[str, tuple[str, str]]: Dictionary mapping block/section names to (description, installation_script) tuples
219
- """
220
- chunks = txt.split('# --GROUP:')
221
- res: dict[str, tuple[str, str]] = {}
222
-
223
- for chunk in chunks[1:]: # Skip first chunk before first group
224
- lines = chunk.split('\n')
225
- # First line contains the group name and description in format "NAME:DESCRIPTION"
226
- group_line = lines[0].strip()
227
-
228
- # Extract group name and description
229
- if ':' in group_line:
230
- parts = group_line.split(':', 1) # Split only on first colon
231
- group_name = parts[0].strip()
232
- group_description = parts[1].strip() if len(parts) > 1 else ""
233
- else:
234
- group_name = group_line
235
- group_description = ""
236
-
237
- # Rest is the content
238
- content = '\n'.join(lines[1:]).strip()
239
-
240
- if group_name and content:
241
- res[group_name] = (group_description, content)
242
-
243
- return res