machineconfig 5.15__py3-none-any.whl → 7.66__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.

Files changed (389) hide show
  1. machineconfig/__init__.py +0 -28
  2. machineconfig/cluster/remote/distribute.py +0 -1
  3. machineconfig/cluster/remote/file_manager.py +0 -2
  4. machineconfig/cluster/remote/script_execution.py +0 -1
  5. machineconfig/cluster/sessions_managers/{utils → helpers}/enhanced_command_runner.py +4 -6
  6. machineconfig/cluster/sessions_managers/utils/load_balancer.py +1 -1
  7. machineconfig/cluster/sessions_managers/utils/maker.py +69 -0
  8. machineconfig/cluster/sessions_managers/wt_local.py +114 -289
  9. machineconfig/cluster/sessions_managers/wt_local_manager.py +50 -193
  10. machineconfig/cluster/sessions_managers/wt_remote.py +51 -43
  11. machineconfig/cluster/sessions_managers/wt_remote_manager.py +49 -197
  12. machineconfig/cluster/sessions_managers/wt_utils/layout_generator.py +6 -19
  13. machineconfig/cluster/sessions_managers/wt_utils/manager_persistence.py +52 -0
  14. machineconfig/cluster/sessions_managers/wt_utils/monitoring_helpers.py +50 -0
  15. machineconfig/cluster/sessions_managers/wt_utils/status_reporter.py +4 -2
  16. machineconfig/cluster/sessions_managers/wt_utils/status_reporting.py +76 -0
  17. machineconfig/cluster/sessions_managers/wt_utils/wt_helpers.py +199 -0
  18. machineconfig/cluster/sessions_managers/zellij_local.py +81 -375
  19. machineconfig/cluster/sessions_managers/zellij_local_manager.py +22 -169
  20. machineconfig/cluster/sessions_managers/zellij_remote.py +40 -41
  21. machineconfig/cluster/sessions_managers/zellij_remote_manager.py +13 -10
  22. machineconfig/cluster/sessions_managers/zellij_utils/example_usage.py +4 -8
  23. machineconfig/cluster/sessions_managers/zellij_utils/layout_generator.py +5 -20
  24. machineconfig/cluster/sessions_managers/zellij_utils/process_monitor.py +3 -9
  25. machineconfig/cluster/sessions_managers/zellij_utils/status_reporter.py +3 -1
  26. machineconfig/cluster/sessions_managers/zellij_utils/zellij_local_helper.py +298 -0
  27. machineconfig/cluster/sessions_managers/zellij_utils/zellij_local_helper_restart.py +77 -0
  28. machineconfig/cluster/sessions_managers/zellij_utils/zellij_local_helper_with_panes.py +228 -0
  29. machineconfig/cluster/sessions_managers/zellij_utils/zellij_local_manager_helper.py +165 -0
  30. machineconfig/jobs/{python → installer}/check_installations.py +2 -3
  31. machineconfig/jobs/installer/custom/boxes.py +61 -0
  32. machineconfig/jobs/installer/custom/hx.py +76 -19
  33. machineconfig/jobs/installer/custom_dev/alacritty.py +4 -4
  34. machineconfig/jobs/installer/custom_dev/brave.py +1 -7
  35. machineconfig/jobs/installer/custom_dev/cloudflare_warp_cli.py +23 -0
  36. machineconfig/jobs/installer/custom_dev/code.py +4 -1
  37. machineconfig/jobs/installer/custom_dev/dubdb_adbc.py +30 -0
  38. machineconfig/jobs/installer/custom_dev/nerfont_windows_helper.py +9 -18
  39. machineconfig/jobs/installer/custom_dev/sysabc.py +119 -0
  40. machineconfig/jobs/installer/custom_dev/wezterm.py +2 -19
  41. machineconfig/jobs/installer/installer_data.json +1101 -115
  42. machineconfig/jobs/installer/linux_scripts/brave.sh +4 -14
  43. machineconfig/jobs/installer/linux_scripts/{warp-cli.sh → cloudflare_warp_cli.sh} +5 -17
  44. machineconfig/jobs/installer/linux_scripts/docker.sh +5 -17
  45. machineconfig/jobs/installer/linux_scripts/docker_start.sh +6 -14
  46. machineconfig/jobs/installer/linux_scripts/edge.sh +3 -11
  47. machineconfig/jobs/{linux/msc → installer/linux_scripts}/lid.sh +2 -8
  48. machineconfig/jobs/installer/linux_scripts/nerdfont.sh +5 -17
  49. machineconfig/jobs/{linux/msc → installer/linux_scripts}/network.sh +2 -8
  50. machineconfig/jobs/installer/linux_scripts/q.sh +1 -0
  51. machineconfig/jobs/installer/linux_scripts/redis.sh +6 -17
  52. machineconfig/jobs/installer/linux_scripts/vscode.sh +5 -17
  53. machineconfig/jobs/installer/linux_scripts/wezterm.sh +4 -12
  54. machineconfig/jobs/installer/package_groups.py +108 -180
  55. machineconfig/logger.py +0 -1
  56. machineconfig/profile/backup.toml +49 -0
  57. machineconfig/profile/bash_shell_profiles.md +11 -0
  58. machineconfig/profile/create_helper.py +74 -0
  59. machineconfig/profile/create_links.py +288 -0
  60. machineconfig/profile/create_links_export.py +100 -0
  61. machineconfig/profile/create_shell_profile.py +136 -0
  62. machineconfig/profile/mapper.toml +258 -0
  63. machineconfig/scripts/Restore-ThunderbirdProfile.ps1 +92 -0
  64. machineconfig/scripts/__init__.py +0 -4
  65. machineconfig/scripts/linux/{share_cloud.sh → other/share_cloud.sh} +14 -25
  66. machineconfig/scripts/linux/wrap_mcfg +47 -0
  67. machineconfig/scripts/nu/wrap_mcfg.nu +69 -0
  68. machineconfig/scripts/python/agents.py +92 -103
  69. machineconfig/scripts/python/ai/command_runner/command_runner.sh +9 -0
  70. machineconfig/scripts/python/ai/command_runner/prompt.txt +9 -0
  71. machineconfig/scripts/python/ai/generate_files.py +307 -42
  72. machineconfig/scripts/python/ai/initai.py +3 -28
  73. machineconfig/scripts/python/ai/scripts/lint_and_type_check.ps1 +17 -18
  74. machineconfig/scripts/python/ai/scripts/lint_and_type_check.sh +17 -18
  75. machineconfig/scripts/python/ai/solutions/_shared.py +9 -1
  76. machineconfig/scripts/python/ai/solutions/copilot/instructions/python/dev.instructions.md +1 -1
  77. machineconfig/scripts/python/ai/solutions/copilot/prompts/pyright_fix.md +16 -0
  78. machineconfig/scripts/python/ai/solutions/generic.py +27 -4
  79. machineconfig/scripts/python/ai/vscode_tasks.py +37 -0
  80. machineconfig/scripts/python/cloud.py +29 -0
  81. machineconfig/scripts/python/croshell.py +111 -114
  82. machineconfig/scripts/python/define.py +31 -0
  83. machineconfig/scripts/python/devops.py +44 -103
  84. machineconfig/scripts/python/devops_navigator.py +10 -0
  85. machineconfig/scripts/python/env_manager/__init__.py +1 -0
  86. machineconfig/scripts/python/env_manager/path_manager_backend.py +47 -0
  87. machineconfig/scripts/python/env_manager/path_manager_tui.py +228 -0
  88. machineconfig/scripts/python/explore.py +49 -0
  89. machineconfig/scripts/python/fire_jobs.py +115 -152
  90. machineconfig/scripts/python/ftpx.py +29 -24
  91. machineconfig/scripts/python/helpers_agents/agentic_frameworks/fire_crush.json +14 -0
  92. machineconfig/scripts/python/helpers_agents/agentic_frameworks/fire_crush.py +37 -0
  93. machineconfig/scripts/python/helpers_agents/agentic_frameworks/fire_cursor_agents.py +22 -0
  94. machineconfig/scripts/python/helpers_agents/agentic_frameworks/fire_gemini.py +42 -0
  95. machineconfig/scripts/python/helpers_agents/agentic_frameworks/fire_qwen.py +30 -0
  96. machineconfig/scripts/python/{fire_agents_help_launch.py → helpers_agents/fire_agents_help_launch.py} +34 -44
  97. machineconfig/scripts/python/helpers_agents/fire_agents_helper_types.py +34 -0
  98. machineconfig/scripts/python/helpers_agents/templates/prompt.txt +6 -0
  99. machineconfig/scripts/python/helpers_agents/templates/template.ps1 +14 -0
  100. machineconfig/scripts/python/helpers_agents/templates/template.sh +24 -0
  101. machineconfig/scripts/python/{cloud_copy.py → helpers_cloud/cloud_copy.py} +30 -23
  102. machineconfig/scripts/python/{cloud_mount.py → helpers_cloud/cloud_mount.py} +10 -18
  103. machineconfig/scripts/python/{cloud_sync.py → helpers_cloud/cloud_sync.py} +12 -18
  104. machineconfig/scripts/python/{helpers → helpers_cloud}/helpers2.py +1 -1
  105. machineconfig/scripts/python/helpers_croshell/crosh.py +39 -0
  106. machineconfig/scripts/python/{start_slidev.py → helpers_croshell/start_slidev.py} +2 -2
  107. machineconfig/scripts/python/helpers_devops/cli_config.py +95 -0
  108. machineconfig/scripts/python/helpers_devops/cli_config_dotfile.py +89 -0
  109. machineconfig/scripts/python/helpers_devops/cli_data.py +25 -0
  110. machineconfig/scripts/python/helpers_devops/cli_nw.py +134 -0
  111. machineconfig/scripts/python/helpers_devops/cli_repos.py +182 -0
  112. machineconfig/scripts/python/helpers_devops/cli_self.py +134 -0
  113. machineconfig/scripts/python/helpers_devops/cli_share_file.py +137 -0
  114. machineconfig/scripts/python/helpers_devops/cli_share_server.py +141 -0
  115. machineconfig/scripts/python/{share_terminal.py → helpers_devops/cli_terminal.py} +35 -23
  116. machineconfig/scripts/python/helpers_devops/cli_utils.py +96 -0
  117. machineconfig/scripts/python/{devops_backup_retrieve.py → helpers_devops/devops_backup_retrieve.py} +7 -10
  118. machineconfig/scripts/python/helpers_devops/devops_status.py +511 -0
  119. machineconfig/scripts/python/{devops_update_repos.py → helpers_devops/devops_update_repos.py} +68 -49
  120. machineconfig/scripts/python/helpers_devops/themes/choose_pwsh_theme.ps1 +81 -0
  121. machineconfig/scripts/python/helpers_devops/themes/choose_starship_theme.bash +3 -0
  122. machineconfig/scripts/python/{choose_wezterm_theme.py → helpers_devops/themes/choose_wezterm_theme.py} +2 -2
  123. machineconfig/scripts/python/helpers_fire_command/__init__.py +0 -0
  124. machineconfig/scripts/python/{helpers/helpers4.py → helpers_fire_command/file_wrangler.py} +56 -20
  125. machineconfig/scripts/python/{fire_jobs_args_helper.py → helpers_fire_command/fire_jobs_args_helper.py} +5 -1
  126. machineconfig/scripts/python/{fire_jobs_route_helper.py → helpers_fire_command/fire_jobs_route_helper.py} +47 -2
  127. machineconfig/scripts/python/helpers_fire_command/fire_jobs_streamlit_helper.py +0 -0
  128. machineconfig/scripts/python/helpers_msearch/__init__.py +5 -0
  129. machineconfig/scripts/{linux → python/helpers_msearch/scripts_linux}/fzfag +1 -1
  130. machineconfig/scripts/{linux → python/helpers_msearch/scripts_linux}/fzfg +1 -1
  131. machineconfig/scripts/{linux → python/helpers_msearch/scripts_linux}/fzfrga +1 -1
  132. machineconfig/scripts/python/helpers_navigator/__init__.py +20 -0
  133. machineconfig/scripts/python/helpers_navigator/command_builder.py +111 -0
  134. machineconfig/scripts/python/helpers_navigator/command_detail.py +44 -0
  135. machineconfig/scripts/python/helpers_navigator/command_tree.py +588 -0
  136. machineconfig/scripts/python/helpers_navigator/data_models.py +28 -0
  137. machineconfig/scripts/python/helpers_navigator/main_app.py +272 -0
  138. machineconfig/scripts/python/helpers_navigator/search_bar.py +15 -0
  139. machineconfig/scripts/python/helpers_repos/action.py +209 -0
  140. machineconfig/scripts/python/helpers_repos/action_helper.py +150 -0
  141. machineconfig/scripts/python/{repos_helper_clone.py → helpers_repos/clone.py} +2 -3
  142. machineconfig/scripts/python/helpers_repos/cloud_repo_sync.py +218 -0
  143. machineconfig/scripts/python/{count_lines.py → helpers_repos/count_lines.py} +10 -10
  144. machineconfig/scripts/python/helpers_repos/count_lines_frontend.py +17 -0
  145. machineconfig/scripts/python/{repos_helper.py → helpers_repos/entrypoint.py} +9 -17
  146. machineconfig/scripts/python/helpers_repos/grource.py +340 -0
  147. machineconfig/scripts/python/{repos_helper_record.py → helpers_repos/record.py} +4 -3
  148. machineconfig/scripts/python/helpers_repos/sync.py +66 -0
  149. machineconfig/scripts/python/{repos_helper_update.py → helpers_repos/update.py} +3 -3
  150. machineconfig/scripts/python/helpers_sessions/__init__.py +0 -0
  151. machineconfig/scripts/python/helpers_sessions/sessions_multiprocess.py +58 -0
  152. machineconfig/scripts/python/helpers_utils/download.py +152 -0
  153. machineconfig/scripts/python/helpers_utils/path.py +108 -0
  154. machineconfig/scripts/python/interactive.py +64 -84
  155. machineconfig/scripts/python/machineconfig.py +63 -0
  156. machineconfig/scripts/python/msearch.py +21 -0
  157. machineconfig/scripts/python/nw/__init__.py +0 -0
  158. machineconfig/scripts/python/{devops_add_identity.py → nw/devops_add_identity.py} +0 -2
  159. machineconfig/scripts/python/{devops_add_ssh_key.py → nw/devops_add_ssh_key.py} +73 -43
  160. machineconfig/scripts/{linux → python/nw}/mount_nfs +1 -1
  161. machineconfig/scripts/python/{mount_nfs.py → nw/mount_nfs.py} +3 -3
  162. machineconfig/scripts/{linux → python/nw}/mount_nw_drive +1 -2
  163. machineconfig/scripts/python/{mount_ssh.py → nw/mount_ssh.py} +3 -3
  164. machineconfig/scripts/python/{onetimeshare.py → nw/onetimeshare.py} +0 -1
  165. machineconfig/scripts/python/nw/ssh_debug_linux.py +391 -0
  166. machineconfig/scripts/python/nw/ssh_debug_windows.py +338 -0
  167. machineconfig/scripts/python/{wifi_conn.py → nw/wifi_conn.py} +1 -53
  168. machineconfig/scripts/python/{wsl_windows_transfer.py → nw/wsl_windows_transfer.py} +5 -4
  169. machineconfig/scripts/python/sessions.py +64 -44
  170. machineconfig/scripts/python/terminal.py +127 -0
  171. machineconfig/scripts/python/utils.py +66 -0
  172. machineconfig/scripts/windows/{mount_nfs.ps1 → mounts/mount_nfs.ps1} +1 -3
  173. machineconfig/scripts/windows/{mount_ssh.ps1 → mounts/mount_ssh.ps1} +1 -1
  174. machineconfig/scripts/windows/{share_smb.ps1 → mounts/share_smb.ps1} +0 -6
  175. machineconfig/scripts/windows/wrap_mcfg.ps1 +60 -0
  176. machineconfig/settings/broot/br.sh +0 -4
  177. machineconfig/settings/broot/conf.toml +1 -1
  178. machineconfig/settings/helix/config.toml +16 -0
  179. machineconfig/settings/helix/languages.toml +13 -4
  180. machineconfig/settings/helix/yazi-picker.sh +12 -0
  181. machineconfig/settings/lf/linux/exe/lfcd.sh +1 -0
  182. machineconfig/settings/lf/linux/exe/previewer.sh +9 -3
  183. machineconfig/settings/lf/linux/lfrc +10 -12
  184. machineconfig/settings/lf/windows/fzf_edit.ps1 +2 -2
  185. machineconfig/settings/lf/windows/lfrc +18 -38
  186. machineconfig/settings/lf/windows/mkfile.ps1 +1 -1
  187. machineconfig/settings/linters/.ruff.toml +1 -1
  188. machineconfig/settings/lvim/windows/archive/config_additional.lua +0 -6
  189. machineconfig/settings/marimo/marimo.toml +80 -0
  190. machineconfig/settings/marimo/snippets/globalize.py +34 -0
  191. machineconfig/settings/pistol/pistol.conf +1 -1
  192. machineconfig/settings/shells/bash/init.sh +55 -31
  193. machineconfig/settings/shells/nushell/config.nu +1 -34
  194. machineconfig/settings/shells/nushell/init.nu +127 -0
  195. machineconfig/settings/shells/pwsh/init.ps1 +60 -43
  196. machineconfig/settings/shells/starship/starship.toml +16 -0
  197. machineconfig/settings/shells/wezterm/wezterm.lua +2 -0
  198. machineconfig/settings/shells/wt/settings.json +32 -17
  199. machineconfig/settings/shells/zsh/init.sh +89 -0
  200. machineconfig/settings/svim/linux/init.toml +0 -4
  201. machineconfig/settings/svim/windows/init.toml +0 -3
  202. machineconfig/settings/yazi/init.lua +57 -0
  203. machineconfig/settings/yazi/keymap_linux.toml +79 -0
  204. machineconfig/settings/yazi/keymap_windows.toml +78 -0
  205. machineconfig/settings/yazi/shell/yazi_cd.ps1 +33 -0
  206. machineconfig/settings/yazi/shell/yazi_cd.sh +8 -0
  207. machineconfig/settings/yazi/yazi.toml +13 -0
  208. machineconfig/setup_linux/__init__.py +10 -0
  209. machineconfig/setup_linux/apps_desktop.sh +89 -0
  210. machineconfig/setup_linux/apps_gui.sh +64 -0
  211. machineconfig/setup_linux/{nix → others}/cli_installation.sh +9 -29
  212. machineconfig/setup_linux/ssh/openssh_all.sh +25 -0
  213. machineconfig/setup_linux/ssh/openssh_wsl.sh +38 -0
  214. machineconfig/setup_linux/uv.sh +15 -0
  215. machineconfig/setup_linux/web_shortcuts/interactive.sh +26 -6
  216. machineconfig/setup_mac/__init__.py +16 -0
  217. machineconfig/setup_mac/apps_gui.sh +248 -0
  218. machineconfig/setup_mac/ssh/openssh_setup.sh +114 -0
  219. machineconfig/setup_mac/uv.sh +36 -0
  220. machineconfig/setup_windows/__init__.py +8 -0
  221. machineconfig/setup_windows/others/power_options.ps1 +7 -0
  222. machineconfig/setup_windows/ssh/add-sshkey.ps1 +29 -0
  223. machineconfig/setup_windows/ssh/add_identity.ps1 +11 -0
  224. machineconfig/setup_windows/ssh/openssh-server.ps1 +37 -0
  225. machineconfig/setup_windows/uv.ps1 +10 -0
  226. machineconfig/setup_windows/web_shortcuts/interactive.ps1 +27 -10
  227. machineconfig/setup_windows/web_shortcuts/quick_init.ps1 +16 -0
  228. machineconfig/utils/accessories.py +7 -5
  229. machineconfig/utils/cloud/onedrive/README.md +139 -0
  230. machineconfig/utils/code.py +133 -106
  231. machineconfig/utils/files/art/fat_croco.txt +10 -0
  232. machineconfig/utils/files/art/halfwit_croco.txt +9 -0
  233. machineconfig/utils/files/art/happy_croco.txt +22 -0
  234. machineconfig/utils/files/art/water_croco.txt +11 -0
  235. machineconfig/utils/files/ascii_art.py +1 -1
  236. machineconfig/utils/files/dbms.py +257 -0
  237. machineconfig/utils/files/headers.py +11 -14
  238. machineconfig/utils/files/ouch/__init__.py +0 -0
  239. machineconfig/utils/files/ouch/decompress.py +45 -0
  240. machineconfig/utils/files/read.py +10 -18
  241. machineconfig/utils/installer_utils/installer_class.py +68 -126
  242. machineconfig/utils/installer_utils/{installer.py → installer_cli.py} +109 -117
  243. machineconfig/utils/installer_utils/{installer_abc.py → installer_locator_utils.py} +31 -81
  244. machineconfig/utils/{installer.py → installer_utils/installer_runner.py} +44 -74
  245. machineconfig/utils/io.py +77 -23
  246. machineconfig/utils/links.py +254 -162
  247. machineconfig/utils/meta.py +255 -0
  248. machineconfig/utils/notifications.py +1 -1
  249. machineconfig/utils/options.py +13 -3
  250. machineconfig/utils/path_extended.py +46 -100
  251. machineconfig/utils/path_helper.py +75 -22
  252. machineconfig/utils/procs.py +50 -70
  253. machineconfig/utils/scheduler.py +94 -97
  254. machineconfig/utils/scheduling.py +0 -3
  255. machineconfig/utils/schemas/fire_agents/fire_agents_input.py +1 -1
  256. machineconfig/utils/schemas/layouts/layout_types.py +1 -1
  257. machineconfig/utils/source_of_truth.py +3 -6
  258. machineconfig/utils/ssh.py +742 -264
  259. machineconfig/utils/ssh_utils/utils.py +0 -0
  260. machineconfig/utils/terminal.py +2 -113
  261. machineconfig/utils/tst.py +20 -0
  262. machineconfig/utils/upgrade_packages.py +109 -28
  263. machineconfig/utils/ve.py +11 -4
  264. machineconfig-7.66.dist-info/METADATA +124 -0
  265. machineconfig-7.66.dist-info/RECORD +451 -0
  266. machineconfig-7.66.dist-info/entry_points.txt +15 -0
  267. machineconfig/cluster/sessions_managers/ffile.py +0 -4
  268. machineconfig/jobs/installer/linux_scripts/pgsql.sh +0 -49
  269. machineconfig/jobs/installer/linux_scripts/timescaledb.sh +0 -85
  270. machineconfig/jobs/linux/msc/cli_agents.sh +0 -16
  271. machineconfig/jobs/python/python_ve_symlink.py +0 -37
  272. machineconfig/jobs/python/vscode/api.py +0 -57
  273. machineconfig/jobs/python/vscode/sync_code.py +0 -73
  274. machineconfig/jobs/windows/archive/archive_pygraphviz.ps1 +0 -14
  275. machineconfig/jobs/windows/start_terminal.ps1 +0 -6
  276. machineconfig/jobs/windows/startup_file.cmd +0 -2
  277. machineconfig/profile/create.py +0 -303
  278. machineconfig/profile/shell.py +0 -176
  279. machineconfig/scripts/cloud/init.sh +0 -119
  280. machineconfig/scripts/linux/agents +0 -2
  281. machineconfig/scripts/linux/choose_wezterm_theme +0 -3
  282. machineconfig/scripts/linux/cloud_copy +0 -2
  283. machineconfig/scripts/linux/cloud_mount +0 -2
  284. machineconfig/scripts/linux/cloud_repo_sync +0 -2
  285. machineconfig/scripts/linux/cloud_sync +0 -2
  286. machineconfig/scripts/linux/croshell +0 -3
  287. machineconfig/scripts/linux/devops +0 -2
  288. machineconfig/scripts/linux/fire +0 -2
  289. machineconfig/scripts/linux/ftpx +0 -2
  290. machineconfig/scripts/linux/fzf2g +0 -21
  291. machineconfig/scripts/linux/fzffg +0 -25
  292. machineconfig/scripts/linux/gh_models +0 -2
  293. machineconfig/scripts/linux/initai +0 -2
  294. machineconfig/scripts/linux/kill_process +0 -2
  295. machineconfig/scripts/linux/scheduler +0 -2
  296. machineconfig/scripts/linux/sessions +0 -2
  297. machineconfig/scripts/linux/share_smb +0 -1
  298. machineconfig/scripts/linux/start_slidev +0 -2
  299. machineconfig/scripts/linux/start_terminals +0 -3
  300. machineconfig/scripts/linux/warp-cli.sh +0 -122
  301. machineconfig/scripts/linux/wifi_conn +0 -2
  302. machineconfig/scripts/linux/z_ls +0 -104
  303. machineconfig/scripts/python/ai/solutions/copilot/prompts/allLintersAndTypeCheckers.prompt.md +0 -5
  304. machineconfig/scripts/python/cloud_repo_sync.py +0 -190
  305. machineconfig/scripts/python/count_lines_frontend.py +0 -16
  306. machineconfig/scripts/python/dotfile.py +0 -78
  307. machineconfig/scripts/python/fire_agents_helper_types.py +0 -12
  308. machineconfig/scripts/python/get_zellij_cmd.py +0 -15
  309. machineconfig/scripts/python/gh_models.py +0 -104
  310. machineconfig/scripts/python/helpers/repo_sync_helpers.py +0 -116
  311. machineconfig/scripts/python/repos.py +0 -132
  312. machineconfig/scripts/python/repos_helper_action.py +0 -378
  313. machineconfig/scripts/python/snapshot.py +0 -25
  314. machineconfig/scripts/python/start_terminals.py +0 -121
  315. machineconfig/scripts/python/t4.py +0 -17
  316. machineconfig/scripts/windows/agents.ps1 +0 -1
  317. machineconfig/scripts/windows/choose_wezterm_theme.ps1 +0 -1
  318. machineconfig/scripts/windows/cloud_copy.ps1 +0 -1
  319. machineconfig/scripts/windows/cloud_mount.ps1 +0 -1
  320. machineconfig/scripts/windows/cloud_repo_sync.ps1 +0 -1
  321. machineconfig/scripts/windows/cloud_sync.ps1 +0 -1
  322. machineconfig/scripts/windows/croshell.ps1 +0 -1
  323. machineconfig/scripts/windows/devops.ps1 +0 -1
  324. machineconfig/scripts/windows/dotfile.ps1 +0 -1
  325. machineconfig/scripts/windows/fire.ps1 +0 -1
  326. machineconfig/scripts/windows/ftpx.ps1 +0 -1
  327. machineconfig/scripts/windows/gpt.ps1 +0 -1
  328. machineconfig/scripts/windows/grep.ps1 +0 -2
  329. machineconfig/scripts/windows/initai.ps1 +0 -1
  330. machineconfig/scripts/windows/kill_process.ps1 +0 -1
  331. machineconfig/scripts/windows/nano.ps1 +0 -3
  332. machineconfig/scripts/windows/pomodoro.ps1 +0 -1
  333. machineconfig/scripts/windows/reload_path.ps1 +0 -3
  334. machineconfig/scripts/windows/scheduler.ps1 +0 -1
  335. machineconfig/scripts/windows/sessions.ps1 +0 -1
  336. machineconfig/scripts/windows/snapshot.ps1 +0 -1
  337. machineconfig/scripts/windows/start_slidev.ps1 +0 -1
  338. machineconfig/scripts/windows/start_terminals.ps1 +0 -1
  339. machineconfig/scripts/windows/wifi_conn.ps1 +0 -2
  340. machineconfig/scripts/windows/wsl_rdp_windows_port_forwarding.ps1 +0 -46
  341. machineconfig/scripts/windows/wsl_ssh_windows_port_forwarding.ps1 +0 -76
  342. machineconfig/settings/lf/linux/exe/fzf_nano.sh +0 -16
  343. machineconfig/setup_linux/others/openssh-server_add_pub_key.sh +0 -57
  344. machineconfig/setup_linux/web_shortcuts/croshell.sh +0 -11
  345. machineconfig/setup_linux/web_shortcuts/ssh.sh +0 -52
  346. machineconfig/setup_windows/web_shortcuts/all.ps1 +0 -18
  347. machineconfig/setup_windows/web_shortcuts/ascii_art.ps1 +0 -36
  348. machineconfig/setup_windows/web_shortcuts/croshell.ps1 +0 -16
  349. machineconfig/setup_windows/web_shortcuts/ssh.ps1 +0 -11
  350. machineconfig/utils/ai/generate_file_checklist.py +0 -68
  351. machineconfig-5.15.dist-info/METADATA +0 -188
  352. machineconfig-5.15.dist-info/RECORD +0 -415
  353. machineconfig-5.15.dist-info/entry_points.txt +0 -18
  354. machineconfig/cluster/sessions_managers/{utils → helpers}/load_balancer_helper.py +0 -0
  355. machineconfig/scripts/linux/{share_nfs → other/share_nfs} +0 -0
  356. machineconfig/scripts/linux/{start_docker → other/start_docker} +0 -0
  357. machineconfig/scripts/linux/{switch_ip → other/switch_ip} +0 -0
  358. machineconfig/{jobs/python → scripts/python/helpers_agents}/__init__.py +0 -0
  359. machineconfig/scripts/python/{helpers → helpers_agents/agentic_frameworks}/__init__.py +0 -0
  360. machineconfig/scripts/python/{fire_agents_help_search.py → helpers_agents/fire_agents_help_search.py} +0 -0
  361. machineconfig/scripts/python/{fire_agents_load_balancer.py → helpers_agents/fire_agents_load_balancer.py} +0 -0
  362. machineconfig/{jobs/windows/msc/cli_agents.bat → scripts/python/helpers_cloud/__init__.py} +0 -0
  363. machineconfig/scripts/python/{helpers → helpers_cloud}/cloud_helpers.py +1 -1
  364. /machineconfig/scripts/python/{helpers → helpers_cloud}/helpers5.py +0 -0
  365. /machineconfig/{jobs/windows/msc/cli_agents.ps1 → scripts/python/helpers_croshell/__init__.py} +0 -0
  366. /machineconfig/scripts/python/{pomodoro.py → helpers_croshell/pomodoro.py} +0 -0
  367. /machineconfig/scripts/python/{scheduler.py → helpers_croshell/scheduler.py} +0 -0
  368. /machineconfig/scripts/python/{viewer.py → helpers_croshell/viewer.py} +0 -0
  369. /machineconfig/scripts/python/{viewer_template.py → helpers_croshell/viewer_template.py} +0 -0
  370. /machineconfig/scripts/python/{fire_jobs_streamlit_helper.py → helpers_devops/__init__.py} +0 -0
  371. /machineconfig/scripts/{windows/share_nfs.ps1 → python/helpers_devops/themes/__init__.py} +0 -0
  372. /machineconfig/{settings/yazi/keymap.toml → scripts/python/helpers_devops/themes/choose_starship_theme.ps1} +0 -0
  373. /machineconfig/scripts/python/{cloud_manager.py → helpers_fire_command/cloud_manager.py} +0 -0
  374. /machineconfig/scripts/{linux → python/helpers_msearch/scripts_linux}/skrg +0 -0
  375. /machineconfig/scripts/{windows → python/helpers_msearch/scripts_windows}/fzfb.ps1 +0 -0
  376. /machineconfig/scripts/{windows → python/helpers_msearch/scripts_windows}/fzfg.ps1 +0 -0
  377. /machineconfig/scripts/{windows → python/helpers_msearch/scripts_windows}/fzfrga.bat +0 -0
  378. /machineconfig/scripts/{linux → python/nw}/mount_drive +0 -0
  379. /machineconfig/scripts/python/{mount_nw_drive.py → nw/mount_nw_drive.py} +0 -0
  380. /machineconfig/scripts/{linux → python/nw}/mount_smb +0 -0
  381. /machineconfig/scripts/windows/{mount_nw.ps1 → mounts/mount_nw.ps1} +0 -0
  382. /machineconfig/scripts/windows/{mount_smb.ps1 → mounts/mount_smb.ps1} +0 -0
  383. /machineconfig/scripts/windows/{share_cloud.cmd → mounts/share_cloud.cmd} +0 -0
  384. /machineconfig/scripts/windows/{unlock_bitlocker.ps1 → mounts/unlock_bitlocker.ps1} +0 -0
  385. /machineconfig/setup_linux/{web_shortcuts → others}/android.sh +0 -0
  386. /machineconfig/{jobs/windows/archive → setup_windows/ssh}/openssh-server_add_key.ps1 +0 -0
  387. /machineconfig/{jobs/windows/archive → setup_windows/ssh}/openssh-server_copy-ssh-id.ps1 +0 -0
  388. {machineconfig-5.15.dist-info → machineconfig-7.66.dist-info}/WHEEL +0 -0
  389. {machineconfig-5.15.dist-info → machineconfig-7.66.dist-info}/top_level.txt +0 -0
@@ -1,165 +1,147 @@
1
1
  """Devops Devapps Install"""
2
2
 
3
- from machineconfig.utils.installer import get_installers_system_groups
4
3
  import typer
5
- from rich.console import Console
6
- from rich.panel import Panel
7
- from rich.table import Table
8
- from typing import Optional, cast, get_args
9
- from machineconfig.jobs.installer.package_groups import PACKAGE_GROUPS, PACKAGE_GROUP2NAMES
10
-
11
- console = Console()
12
-
13
-
14
- def _handle_installer_not_found(search_term: str, all_installers: list["InstallerData"]) -> None: # type: ignore
15
- """Handle installer not found with friendly suggestions using fuzzy matching."""
16
- from difflib import get_close_matches
17
-
18
- all_names = []
19
- for inst in all_installers:
20
- exe_name = inst["appName"]
21
- all_names.append(exe_name)
22
- close_matches = get_close_matches(search_term, all_names, n=5, cutoff=0.4)
23
- console.print(f"\n❌ '[red]{search_term}[/red]' was not found.", style="bold")
24
-
25
- if close_matches:
26
- console.print("🤔 Did you mean one of these?", style="yellow")
27
- table = Table(show_header=False, box=None, pad_edge=False)
28
- for i, match in enumerate(close_matches, 1):
29
- table.add_row(f"[cyan]{i}.[/cyan]", f"[green]{match}[/green]")
30
- console.print(table)
31
- else:
32
- console.print("📋 Here are some available options:", style="blue")
33
- # Show first 10 installers as examples
34
- sample_names = []
35
- for inst in all_installers[:10]:
36
- exe_name = inst["appName"]
37
- sample_names.append(exe_name)
38
-
39
- table = Table(show_header=False, box=None, pad_edge=False)
40
- for i, name in enumerate(sample_names, 1):
41
- table.add_row(f"[cyan]{i}.[/cyan]", f"[green]{name}[/green]")
42
- console.print(table)
43
-
44
- if len(all_installers) > 10:
45
- console.print(f" [dim]... and {len(all_installers) - 10} more[/dim]")
46
-
47
- panel = Panel(f"[bold blue]💡 Use 'ia' to interactively browse all available installers.[/bold blue]\n[bold blue]💡 Use one of the categories: {list(get_args(PACKAGE_GROUPS))}[/bold blue]", title="[yellow]Helpful Tips[/yellow]", border_style="yellow")
48
- console.print(panel)
49
-
50
-
51
- def main_with_parser():
52
- import typer
53
- app = typer.Typer()
54
- app.command()(main)
55
- app()
4
+ from typing import Optional, Annotated
5
+ from machineconfig.jobs.installer.package_groups import PACKAGE_GROUP2NAMES
56
6
 
57
7
 
58
8
  def main(
59
- which: Optional[str] = typer.Option(None, "--which", "-w", help="Comma-separated list of program names to install."),
60
- group: Optional[PACKAGE_GROUPS] = typer.Option(None, "--group", "-g", help=f"Group name (one of {list(get_args(PACKAGE_GROUPS))})"),
61
- interactive: bool = typer.Option(False, "--interactive", "-ia", help="Interactive selection of programs to install."),
9
+ which: Annotated[Optional[str], typer.Argument(..., help="Comma-separated list of program/groups names to install (if --group flag is set).")] = None,
10
+ group: Annotated[bool, typer.Option(..., "--group", "-g", help="Treat 'which' as a group name. A group is bundle of apps.")] = False,
11
+ interactive: Annotated[bool, typer.Option(..., "--interactive", "-i", help="Interactive selection of programs to install.")] = False,
62
12
  ) -> None:
63
- if which is not None:
64
- return install_clis(clis_names=[x.strip() for x in which.split(",") if x.strip() != ""])
65
- if group is not None:
66
- return install_group(package_group=group)
67
13
  if interactive:
68
14
  return install_interactively()
69
- typer.echo("❌ You must provide either --which, --group, or --interactive/-ia option.")
15
+ if which is not None:
16
+ if group:
17
+ for a_group in [x.strip() for x in which.split(",") if x.strip() != ""]:
18
+ return install_group(package_group=a_group)
19
+ else:
20
+ return install_clis(clis_names=[x.strip() for x in which.split(",") if x.strip() != ""])
21
+ else:
22
+ if group:
23
+ from rich.console import Console
24
+ from rich.table import Table
25
+ console = Console()
26
+
27
+ typer.echo("❌ You must provide a group name when using the --group/-g option.")
28
+ res = get_group_name_to_repr()
29
+ console.print("[bold blue]Here are the available groups:[/bold blue]")
30
+ table = Table(show_header=True, header_style="bold magenta")
31
+ table.add_column("Group", style="cyan", no_wrap=True)
32
+ table.add_column("AppsBundled", style="green", overflow="fold")
33
+ for display, group_name in res.items():
34
+ # Parse display
35
+ if " -- " in display:
36
+ group_part, items_part = display.split(" -- ", 1)
37
+ group_name_parsed = group_part.replace("📦 ", "").strip()
38
+ items_str = items_part.strip()
39
+ else:
40
+ group_name_parsed = display
41
+ items_str = group_name
42
+ table.add_row(group_name_parsed, items_str)
43
+ console.print(table)
44
+ raise typer.Exit(1)
45
+ typer.echo("❌ You must provide either a program name/group name, or use --interactive/-ia option.")
70
46
  import click
71
47
  ctx = click.get_current_context()
72
48
  typer.echo(ctx.get_help())
73
49
  raise typer.Exit(1)
74
50
 
75
51
 
76
- def install_interactively():
77
- from machineconfig.utils.options import choose_from_options
78
- from machineconfig.utils.schemas.installer.installer_types import get_normalized_arch, get_os_name
79
- from machineconfig.utils.installer import get_installers
80
- from machineconfig.utils.installer_utils.installer_class import Installer
81
- installers = get_installers(os=get_os_name(), arch=get_normalized_arch(), which_cats=None)
82
- installer_options = []
83
- for x in installers:
84
- installer_options.append(Installer(installer_data=x).get_description())
85
-
52
+ def get_group_name_to_repr() -> dict[str, str]:
86
53
  # Build category options and maintain a mapping from display text to actual category name
87
54
  category_display_to_name: dict[str, str] = {}
88
55
  for group_name, group_values in PACKAGE_GROUP2NAMES.items():
89
56
  display = f"📦 {group_name:<20}" + " -- " + f"{'|'.join(group_values):<60}"
90
57
  category_display_to_name[display] = group_name
91
-
92
- options_system = get_installers_system_groups()
93
- for item in options_system:
94
- display = f"📦 {item['appName']:<20} -- {item['doc']:<60}"
95
- category_display_to_name[display] = item['appName']
96
-
97
- options = list(category_display_to_name.keys()) + ["─" * 50] + installer_options
98
- program_names = choose_from_options(multi=True, msg="Categories are prefixed with 📦", options=options, header="🚀 CHOOSE DEV APP OR CATEGORY", default="📦 essentials", fzf=True)
58
+ return category_display_to_name
59
+
60
+
61
+ def install_interactively():
62
+ from machineconfig.utils.options import choose_from_options
63
+ from machineconfig.utils.schemas.installer.installer_types import get_normalized_arch, get_os_name
64
+ from machineconfig.utils.installer_utils.installer_runner import get_installers
65
+ from machineconfig.utils.installer_utils.installer_class import Installer
66
+ from rich.console import Console
67
+ from rich.panel import Panel
68
+ # from rich.table import Table
69
+ installers = get_installers(os=get_os_name(), arch=get_normalized_arch(), which_cats=None)
70
+ installer_options = [Installer(installer_data=x).get_description() for x in installers]
71
+ category_display_to_name = get_group_name_to_repr()
72
+ options = list(category_display_to_name.keys()) + installer_options
73
+ program_names = choose_from_options(multi=True, msg="Categories are prefixed with 📦", options=options, header="🚀 CHOOSE DEV APP OR CATEGORY", fzf=True)
99
74
  installation_messages: list[str] = []
100
75
  for _an_idx, a_program_name in enumerate(program_names):
101
- if a_program_name.startswith("─"): # 50 dashes separator
102
- continue
103
76
  if a_program_name.startswith("📦 "):
104
77
  category_name = category_display_to_name.get(a_program_name)
105
78
  if category_name:
106
- install_group(package_group=cast(PACKAGE_GROUPS, category_name))
79
+ install_group(package_group=category_name)
107
80
  else:
108
81
  installer_idx = installer_options.index(a_program_name)
109
82
  an_installer_data = installers[installer_idx]
110
83
  status_message = Installer(an_installer_data).install_robust(version=None) # finish the task - this returns a status message, not a command
111
84
  installation_messages.append(status_message)
112
85
  if installation_messages:
86
+ console = Console()
87
+
113
88
  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))
114
89
  console.print(panel)
115
90
 
116
91
 
117
- def install_group(package_group: PACKAGE_GROUPS):
118
- 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))
119
- console.print(panel)
120
- from machineconfig.utils.installer import get_installers, install_bulk
92
+ def install_group(package_group: str):
93
+ from machineconfig.utils.installer_utils.installer_runner import get_installers, install_bulk
121
94
  from machineconfig.utils.schemas.installer.installer_types import get_normalized_arch, get_os_name
95
+ from rich.console import Console
96
+ from rich.panel import Panel
97
+ # from rich.table import Table
122
98
  if package_group in PACKAGE_GROUP2NAMES:
99
+ 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))
100
+ console = Console()
101
+ console.print(panel)
123
102
  installers_ = get_installers(os=get_os_name(), arch=get_normalized_arch(), which_cats=[package_group])
124
103
  install_bulk(installers_data=installers_)
104
+ return
105
+ console = Console()
106
+ console.print(f"❌ ERROR: Unknown package group: {package_group}. Available groups are: {list(PACKAGE_GROUP2NAMES.keys())}")
107
+ def _handle_installer_not_found(search_term: str, all_names: list[str]) -> None: # type: ignore
108
+ """Handle installer not found with friendly suggestions using fuzzy matching."""
109
+ from difflib import get_close_matches
110
+ from rich.console import Console
111
+ from rich.panel import Panel
112
+ from rich.table import Table
113
+ close_matches = get_close_matches(search_term, all_names, n=5, cutoff=0.4)
114
+ console = Console()
115
+
116
+ console.print(f"\n❌ '[red]{search_term}[/red]' was not found.", style="bold")
117
+ if close_matches:
118
+ console.print("🤔 Did you mean one of these?", style="yellow")
119
+ table = Table(show_header=False, box=None, pad_edge=False)
120
+ for i, match in enumerate(close_matches, 1):
121
+ table.add_row(f"[cyan]{i}.[/cyan]", f"[green]{match}[/green]")
122
+ console.print(table)
125
123
  else:
126
- options_system = get_installers_system_groups()
127
- from machineconfig.utils.schemas.installer.installer_types import get_normalized_arch, get_os_name
128
- from machineconfig.utils.code import run_shell_script
129
- for an_item in options_system:
130
- if an_item["appName"] == package_group:
131
- program = an_item["fileNamePattern"][get_normalized_arch()][get_os_name()]
132
- if program is not None:
133
- run_shell_script(program)
134
- break
135
-
136
-
137
- def choose_from_system_package_groups(options_system: dict[str, tuple[str, str]]) -> str:
138
- from machineconfig.utils.options import choose_from_options
139
- display_options = []
140
- for group_name, (description, _) in options_system.items():
141
- if description:
142
- display_options.append(f"{group_name:<20} - {description}")
124
+ console.print("📋 Here are some available options:", style="blue")
125
+ # Show first 10 installers as examples
126
+ if len(all_names) > 10:
127
+ sample_names = all_names[:10]
143
128
  else:
144
- display_options.append(group_name)
145
- program_names = choose_from_options(multi=True, msg="", options=sorted(display_options), header="🚀 CHOOSE DEV APP", fzf=True)
146
- program = ""
147
- for display_name in program_names:
148
- # Extract the actual group name (everything before " - " if present)
149
- group_name = display_name.split(" - ")[0].strip() if " - " in display_name else display_name.strip()
150
- console.print(f"\n[bold cyan]⚙️ Installing: [yellow]{group_name}[/yellow][/bold cyan]", style="bold")
151
- _, sub_program = options_system[group_name] # Extract content from tuple
152
- if sub_program.startswith("#winget"):
153
- sub_program = sub_program[1:]
154
- program += "\n" + sub_program
155
- return program
129
+ sample_names = all_names
130
+ table = Table(show_header=False, box=None, pad_edge=False)
131
+ for i, name in enumerate(sample_names, 1):
132
+ table.add_row(f"[cyan]{i}.[/cyan]", f"[green]{name}[/green]")
133
+ console.print(table)
134
+ if len(all_names) > 10:
135
+ console.print(f" [dim]... and {len(all_names) - 10} more[/dim]")
156
136
 
137
+ 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")
138
+ console.print(panel)
157
139
 
158
140
  def install_clis(clis_names: list[str]):
159
141
  from machineconfig.utils.schemas.installer.installer_types import get_normalized_arch, get_os_name
160
- from machineconfig.utils.installer import get_installers
142
+ from machineconfig.utils.installer_utils.installer_runner import get_installers
161
143
  from machineconfig.utils.installer_utils.installer_class import Installer
162
-
144
+ from rich.console import Console
163
145
  total_messages: list[str] = []
164
146
  for a_which in clis_names:
165
147
  all_installers = get_installers(os=get_os_name(), arch=get_normalized_arch(), which_cats=None)
@@ -170,15 +152,25 @@ def install_clis(clis_names: list[str]):
170
152
  selected_installer = installer
171
153
  break
172
154
  if selected_installer is None:
173
- _handle_installer_not_found(a_which, all_installers)
155
+ _handle_installer_not_found(a_which, all_names=[inst["appName"] for inst in all_installers])
174
156
  return None
175
157
  message = Installer(selected_installer).install_robust(version=None) # finish the task
176
158
  total_messages.append(message)
177
159
  if total_messages:
160
+ console = Console()
178
161
  console.print("\n[bold green]📊 Installation Results:[/bold green]")
179
162
  for a_message in total_messages:
180
163
  console.print(f"[blue]• {a_message}[/blue]")
181
164
  return None
165
+ def install_if_missing(which: str):
166
+ from machineconfig.utils.installer_utils.installer_locator_utils import check_tool_exists
167
+ exists = check_tool_exists(which)
168
+ if exists:
169
+ print(f"✅ {which} is already installed.")
170
+ return
171
+ print(f"⏳ {which} not found. Installing...")
172
+ from machineconfig.utils.installer_utils.installer_cli import main
173
+ main(which=which, interactive=False)
182
174
 
183
175
 
184
176
  if __name__ == "__main__":
@@ -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
 
@@ -9,7 +8,7 @@ import platform
9
8
 
10
9
 
11
10
  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}")
11
+ print("🔍 PROCESSING WINDOWS EXECUTABLE 🔍")
13
12
  if exe_name is not None and ".exe" in exe_name:
14
13
  exe_name = exe_name.replace(".exe", "")
15
14
  if downloaded_file_path.is_file():
@@ -54,7 +53,7 @@ def find_move_delete_windows(downloaded_file_path: PathExtended, exe_name: Optio
54
53
 
55
54
 
56
55
  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}")
56
+ print("🔍 PROCESSING LINUX EXECUTABLE 🔍")
58
57
  if downloaded.is_file():
59
58
  exe = downloaded
60
59
  print(f"📄 Found direct executable file: {exe}")
@@ -108,33 +107,52 @@ def find_move_delete_linux(downloaded: PathExtended, tool_name: str, delete: Opt
108
107
  print("✅ Temporary files removed")
109
108
 
110
109
  exe_new_location = PathExtended(LINUX_INSTALL_PATH).joinpath(exe.name)
111
- print(f"✅ Executable installed at: {exe_new_location}\n{'=' * 80}")
110
+ print(f"✅ Executable installed at: {exe_new_location}")
112
111
  return exe_new_location
113
112
 
114
113
 
115
114
  def check_tool_exists(tool_name: str) -> bool:
116
115
  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
116
+ tool_name_exe = tool_name.replace(".exe", "") + ".exe"
117
+ res1 = any([Path(WINDOWS_INSTALL_PATH).joinpath(tool_name_exe).is_file(), Path.home().joinpath("AppData/Roaming/npm").joinpath(tool_name_exe).is_file()])
118
+ if res1:
119
+ return True
120
+ tool_name_no_exe = tool_name.replace(".exe", "")
121
+ 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()])
122
+ return res2
122
123
  elif platform.system() in ["Linux", "Darwin"]:
123
124
  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()])
125
+ standard_checks = [
126
+ Path("/usr/local/bin").joinpath(tool_name).is_file(),
127
+ Path("/usr/bin").joinpath(tool_name).is_file(),
128
+ root_path.joinpath(tool_name).is_file()
129
+ ]
130
+ if any(standard_checks):
131
+ return True
132
+ # Check for npm packages via nvm
133
+ npm_check = False
134
+ try:
135
+ result = subprocess.run(["node", "--version"], capture_output=True, text=True, check=True)
136
+ version = result.stdout.strip().lstrip('v')
137
+ nvm_bin_path = Path.home() / ".nvm" / "versions" / "node" / f"v{version}" / "bin" / tool_name
138
+ npm_check = nvm_bin_path.is_file()
139
+ except subprocess.CalledProcessError:
140
+ pass
141
+ return npm_check
125
142
  else:
126
143
  raise NotImplementedError(f"platform {platform.system()} not implemented")
127
- def is_executable_in_path(executable_name: str) -> bool:
144
+
145
+ def is_executable_in_path(name: str) -> bool:
128
146
  import os
129
147
  path_dirs = os.environ['PATH'].split(os.pathsep)
130
148
  for path_dir in path_dirs:
131
- path_to_executable = os.path.join(path_dir, executable_name)
149
+ path_to_executable = os.path.join(path_dir, name)
132
150
  if os.path.isfile(path_to_executable) and os.access(path_to_executable, os.X_OK): return True
133
151
  return False
134
152
 
135
153
 
136
154
  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}")
155
+ print(f"🔍 CHECKING INSTALLATION STATUS: {exe_name} 🔍")
138
156
  INSTALL_VERSION_ROOT.joinpath(exe_name).parent.mkdir(parents=True, exist_ok=True)
139
157
  tmp_path = INSTALL_VERSION_ROOT.joinpath(exe_name)
140
158
 
@@ -173,71 +191,3 @@ def check_if_installed_already(exe_name: str, version: Optional[str], use_cache:
173
191
  return ("⚠️ NotInstalled", "None", version or "unknown")
174
192
 
175
193
 
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
@@ -1,17 +1,15 @@
1
1
  """package manager"""
2
2
 
3
- from machineconfig.utils.installer_utils.installer_abc import check_if_installed_already, parse_apps_installer_linux, parse_apps_installer_windows
4
-
3
+ from machineconfig.utils.installer_utils.installer_locator_utils import check_if_installed_already
5
4
  from machineconfig.utils.installer_utils.installer_class import Installer
6
5
  from machineconfig.utils.schemas.installer.installer_types import InstallerData, InstallerDataFiles, get_normalized_arch, get_os_name, OPERATING_SYSTEMS, CPU_ARCHITECTURES
7
- from machineconfig.jobs.installer.package_groups import PACKAGE_GROUPS, PACKAGE_GROUP2NAMES
8
- from rich.console import Console
9
- from rich.panel import Panel
10
-
6
+ from machineconfig.jobs.installer.package_groups import PACKAGE_GROUP2NAMES
11
7
  from machineconfig.utils.path_extended import PathExtended
12
- from machineconfig.utils.source_of_truth import INSTALL_VERSION_ROOT, LINUX_INSTALL_PATH, LIBRARY_ROOT
8
+ from machineconfig.utils.source_of_truth import INSTALL_VERSION_ROOT, LINUX_INSTALL_PATH
13
9
  from machineconfig.utils.io import read_json
14
10
 
11
+ from rich.console import Console
12
+ from rich.panel import Panel
15
13
  from typing import Any, Optional
16
14
  import platform
17
15
  from joblib import Parallel, delayed
@@ -20,7 +18,7 @@ from joblib import Parallel, delayed
20
18
  def check_latest():
21
19
  console = Console() # Added console initialization
22
20
  console.print(Panel("🔍 CHECKING FOR LATEST VERSIONS", title="Status", expand=False)) # Replaced print with Panel
23
- installers = get_installers(os=get_os_name(), arch=get_normalized_arch(), which_cats=["ESSENTIAL"])
21
+ installers = get_installers(os=get_os_name(), arch=get_normalized_arch(), which_cats=["termabc"])
24
22
  installers_github = []
25
23
  for inst__ in installers:
26
24
  app_name = inst__["appName"]
@@ -65,16 +63,16 @@ def check_latest():
65
63
 
66
64
  # Print each group
67
65
  for status, items in grouped_data.items():
68
- print(f"\n{status.upper()}:")
69
- print("-" * 60)
66
+ console.print(f"\n[bold]{status.upper()}:[/bold]")
67
+ console.rule(style="dim")
70
68
  for item in items:
71
- print(f" {item['Tool']:<20} | Current: {item['Current Version']:<15} | New: {item['New Version']}")
72
- print("-" * 60)
73
- print(f"{'═' * 80}")
69
+ console.print(f" {item['Tool']:<20} | Current: {item['Current Version']:<15} | New: {item['New Version']}")
70
+ console.rule(style="dim")
71
+ console.rule(style="bold blue")
74
72
 
75
73
 
76
74
  def get_installed_cli_apps():
77
- print(f"\n{'=' * 80}\n🔍 LISTING INSTALLED CLI APPS 🔍\n{'=' * 80}")
75
+ print("🔍 LISTING INSTALLED CLI APPS 🔍")
78
76
  if platform.system() == "Windows":
79
77
  print("🪟 Searching for Windows executables...")
80
78
  apps = PathExtended.home().joinpath("AppData/Local/Microsoft/WindowsApps").search("*.exe", not_in=["notepad"])
@@ -89,12 +87,11 @@ def get_installed_cli_apps():
89
87
  print(error_msg)
90
88
  raise NotImplementedError(error_msg)
91
89
  apps = [app for app in apps if app.size("kb") > 0.1 and not app.is_symlink()] # no symlinks like paint and wsl and bash
92
- print(f"✅ Found {len(apps)} installed applications\n{'=' * 80}")
90
+ print(f"✅ Found {len(apps)} installed applications")
93
91
  return apps
94
92
 
95
93
 
96
- def get_installers(os: OPERATING_SYSTEMS, arch: CPU_ARCHITECTURES, which_cats: Optional[list[PACKAGE_GROUPS]]) -> list[InstallerData]:
97
- print(f"\n{'=' * 80}\n🔍 LOADING INSTALLER CONFIGURATIONS 🔍\n{'=' * 80}")
94
+ def get_installers(os: OPERATING_SYSTEMS, arch: CPU_ARCHITECTURES, which_cats: Optional[list[str]]) -> list[InstallerData]:
98
95
  res_all = get_all_installer_data_files()
99
96
  acceptable_apps_names: list[str] | None = None
100
97
  if which_cats is not None:
@@ -108,84 +105,38 @@ def get_installers(os: OPERATING_SYSTEMS, arch: CPU_ARCHITECTURES, which_cats: O
108
105
  if acceptable_apps_names is not None:
109
106
  if installer_data["appName"] not in acceptable_apps_names:
110
107
  continue
111
- if installer_data["fileNamePattern"][arch][os] is None:
112
- continue
108
+ try:
109
+ if installer_data["fileNamePattern"][arch][os] is None:
110
+ continue
111
+ except KeyError as ke:
112
+ print(f"❌ ERROR: Missing key in installer data: {ke}")
113
+ print(f"Installer data: {installer_data}")
114
+ raise KeyError(f"Missing key in installer data: {ke}")
113
115
  all_installers.append(installer_data)
114
- print(f"✅ Loaded {len(all_installers)} installer configurations\n{'=' * 80}")
115
116
  return all_installers
116
117
 
117
118
 
118
119
  def get_all_installer_data_files() -> list[InstallerData]:
119
- print(f"\n{'=' * 80}\n📂 LOADING CONFIGURATION FILES 📂\n{'=' * 80}")
120
120
  import machineconfig.jobs.installer as module
121
121
  from pathlib import Path
122
- print("📂 Loading configuration files...")
123
122
  res_raw: InstallerDataFiles = read_json(Path(module.__file__).parent.joinpath("installer_data.json"))
124
123
  res_final: list[InstallerData] = res_raw["installers"]
125
- print(f"Loaded: {len(res_final)} installer categories")
126
- return res_final
127
-
128
-
129
- def get_installers_system_groups():
130
- res_final: list[InstallerData] = []
131
- from platform import system
132
- if system() == "Windows":
133
- options_system = parse_apps_installer_windows(LIBRARY_ROOT.joinpath("setup_windows/apps.ps1").read_text(encoding="utf-8"))
134
- elif system() == "Linux" or system() == "Darwin":
135
- options_system = parse_apps_installer_linux(LIBRARY_ROOT.joinpath("setup_linux/apps.sh").read_text(encoding="utf-8"))
136
- else:
137
- raise NotImplementedError(f"❌ System {system()} not supported")
138
- os_name = get_os_name()
139
- for group_name, (docs, script) in options_system.items():
140
- item: InstallerData = {
141
- "appName": group_name,
142
- "doc": docs,
143
- "repoURL": "CMD",
144
- "fileNamePattern": {
145
- "amd64": {os_name: script,},
146
- "arm64": {os_name: script,},}}
147
- res_final.append(item)
148
124
  return res_final
149
125
 
150
126
 
151
127
  def install_bulk(installers_data: list[InstallerData], safe: bool = False, jobs: int = 10, fresh: bool = False):
152
- print(f"\n{'=' * 80}\n🚀 BULK INSTALLATION PROCESS 🚀\n{'=' * 80}")
128
+ print("🚀 BULK INSTALLATION PROCESS 🚀")
153
129
  if fresh:
154
130
  print("🧹 Fresh install requested - clearing version cache...")
155
131
  PathExtended(INSTALL_VERSION_ROOT).delete(sure=True)
156
132
  print("✅ Version cache cleared")
157
-
158
133
  if safe:
159
134
  pass
160
- # print("⚠️ Safe installation mode activated...")
161
- # from machineconfig.jobs.python.check_installations import APP_SUMMARY_PATH
162
- # if platform.system().lower() == "windows":
163
- # print("🪟 Moving applications to Windows Apps folder...")
164
- # # PathExtended.get_env().WindowsPaths().WindowsApps)
165
- # folder = PathExtended.home().joinpath("AppData/Local/Microsoft/WindowsApps")
166
- # apps_dir.search("*").apply(lambda app: app.move(folder=folder))
167
- # elif platform.system().lower() in ["linux", "darwin"]:
168
- # system_name = "Linux" if platform.system().lower() == "linux" else "macOS"
169
- # print(f"🐧 Moving applications to {system_name} bin folder...")
170
- # if platform.system().lower() == "linux":
171
- # install_path = LINUX_INSTALL_PATH
172
- # else: # Darwin/macOS
173
- # install_path = "/usr/local/bin"
174
- # Terminal().run(f"sudo mv {apps_dir.as_posix()}/* {install_path}/").capture().print_if_unsuccessful(desc=f"MOVING executable to {install_path}", strict_err=True, strict_returncode=True)
175
- # else:
176
- # error_msg = f"❌ ERROR: System {platform.system()} not supported"
177
- # print(error_msg)
178
- # raise NotImplementedError(error_msg)
179
-
180
- # apps_dir.delete(sure=True)
181
- # print(f"✅ Safe installation completed\n{'='*80}")
182
- # return None
183
-
184
135
  print(f"🚀 Starting installation of {len(installers_data)} packages...")
185
- print(f"\n{'=' * 80}\n📦 INSTALLING FIRST PACKAGE 📦\n{'=' * 80}")
136
+ print("📦 INSTALLING FIRST PACKAGE 📦")
186
137
  Installer(installers_data[0]).install(version=None)
187
138
  installers_remaining = installers_data[1:]
188
- print(f"\n{'=' * 80}\n📦 INSTALLING REMAINING PACKAGES 📦\n{'=' * 80}")
139
+ print("📦 INSTALLING REMAINING PACKAGES 📦")
189
140
 
190
141
  # Use joblib for parallel processing of remaining installers
191
142
  res = Parallel(n_jobs=jobs)(delayed(lambda x: Installer(x).install_robust(version=None))(installer) for installer in installers_remaining)
@@ -218,4 +169,23 @@ def install_bulk(installers_data: list[InstallerData], safe: bool = False, jobs:
218
169
  print("\n" * 2)
219
170
 
220
171
 
221
-
172
+ def get_machineconfig_version() -> str:
173
+ from importlib.metadata import PackageNotFoundError, version as _pkg_version
174
+ from pathlib import Path
175
+ import tomllib
176
+ name: str = "machineconfig"
177
+ try:
178
+ return _pkg_version(name)
179
+ except PackageNotFoundError:
180
+ pass
181
+ root: Path = Path(__file__).resolve().parents[2]
182
+ pyproject: Path = root / "pyproject.toml"
183
+ if pyproject.is_file():
184
+ with pyproject.open("rb") as f:
185
+ data: dict[str, object] = tomllib.load(f)
186
+ project = data.get("project")
187
+ if isinstance(project, dict):
188
+ version = project.get("version")
189
+ if isinstance(version, str) and version:
190
+ return version
191
+ return "0.0.0"