machineconfig 3.99__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 (418) 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 +1 -2
  5. machineconfig/cluster/sessions_managers/{enhanced_command_runner.py → helpers/enhanced_command_runner.py} +4 -6
  6. machineconfig/cluster/sessions_managers/helpers/load_balancer_helper.py +145 -0
  7. machineconfig/cluster/sessions_managers/utils/load_balancer.py +53 -0
  8. machineconfig/cluster/sessions_managers/utils/maker.py +69 -0
  9. machineconfig/cluster/sessions_managers/wt_local.py +128 -330
  10. machineconfig/cluster/sessions_managers/wt_local_manager.py +53 -187
  11. machineconfig/cluster/sessions_managers/wt_remote.py +51 -43
  12. machineconfig/cluster/sessions_managers/wt_remote_manager.py +49 -197
  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 +22 -172
  21. machineconfig/cluster/sessions_managers/zellij_remote.py +40 -41
  22. machineconfig/cluster/sessions_managers/zellij_remote_manager.py +13 -10
  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 -16
  32. machineconfig/jobs/installer/custom/boxes.py +61 -0
  33. machineconfig/jobs/installer/custom/gh.py +69 -53
  34. machineconfig/jobs/installer/custom/hx.py +77 -20
  35. machineconfig/jobs/installer/custom_dev/alacritty.py +45 -30
  36. machineconfig/jobs/installer/custom_dev/brave.py +43 -35
  37. machineconfig/jobs/installer/custom_dev/bypass_paywall.py +31 -20
  38. machineconfig/jobs/installer/custom_dev/cloudflare_warp_cli.py +23 -0
  39. machineconfig/jobs/installer/custom_dev/code.py +33 -21
  40. machineconfig/jobs/installer/custom_dev/dubdb_adbc.py +30 -0
  41. machineconfig/jobs/installer/custom_dev/espanso.py +64 -41
  42. machineconfig/jobs/installer/custom_dev/goes.py +41 -36
  43. machineconfig/jobs/installer/custom_dev/lvim.py +49 -33
  44. machineconfig/jobs/installer/custom_dev/nerdfont.py +71 -47
  45. machineconfig/jobs/installer/custom_dev/nerfont_windows_helper.py +32 -26
  46. machineconfig/jobs/installer/custom_dev/redis.py +51 -33
  47. machineconfig/jobs/installer/custom_dev/sysabc.py +119 -0
  48. machineconfig/jobs/installer/custom_dev/wezterm.py +55 -39
  49. machineconfig/jobs/installer/custom_dev/winget.py +1 -0
  50. machineconfig/jobs/installer/installer_data.json +3406 -0
  51. machineconfig/jobs/installer/linux_scripts/brave.sh +4 -14
  52. machineconfig/jobs/installer/linux_scripts/{warp-cli.sh → cloudflare_warp_cli.sh} +5 -17
  53. machineconfig/jobs/installer/linux_scripts/docker.sh +5 -17
  54. machineconfig/jobs/installer/linux_scripts/docker_start.sh +6 -14
  55. machineconfig/jobs/installer/linux_scripts/edge.sh +3 -11
  56. machineconfig/jobs/{linux/msc → installer/linux_scripts}/lid.sh +2 -8
  57. machineconfig/jobs/installer/linux_scripts/nerdfont.sh +5 -17
  58. machineconfig/jobs/{linux/msc → installer/linux_scripts}/network.sh +2 -8
  59. machineconfig/jobs/installer/linux_scripts/ngrok.sh +6 -0
  60. machineconfig/jobs/installer/linux_scripts/q.sh +9 -0
  61. machineconfig/jobs/installer/linux_scripts/redis.sh +6 -17
  62. machineconfig/jobs/installer/linux_scripts/vscode.sh +5 -17
  63. machineconfig/jobs/installer/linux_scripts/wezterm.sh +4 -12
  64. machineconfig/jobs/installer/package_groups.py +255 -0
  65. machineconfig/logger.py +0 -1
  66. machineconfig/profile/backup.toml +49 -0
  67. machineconfig/profile/bash_shell_profiles.md +11 -0
  68. machineconfig/profile/create_helper.py +74 -0
  69. machineconfig/profile/create_links.py +288 -0
  70. machineconfig/profile/create_links_export.py +100 -0
  71. machineconfig/profile/create_shell_profile.py +136 -0
  72. machineconfig/profile/mapper.toml +258 -0
  73. machineconfig/scripts/Restore-ThunderbirdProfile.ps1 +92 -0
  74. machineconfig/scripts/__init__.py +0 -4
  75. machineconfig/scripts/linux/{share_cloud.sh → other/share_cloud.sh} +14 -25
  76. machineconfig/scripts/linux/wrap_mcfg +47 -0
  77. machineconfig/scripts/nu/wrap_mcfg.nu +69 -0
  78. machineconfig/scripts/python/agents.py +198 -0
  79. machineconfig/scripts/python/ai/command_runner/command_runner.sh +9 -0
  80. machineconfig/scripts/python/ai/command_runner/prompt.txt +9 -0
  81. machineconfig/scripts/python/ai/generate_files.py +307 -42
  82. machineconfig/scripts/python/ai/initai.py +3 -28
  83. machineconfig/scripts/python/ai/scripts/lint_and_type_check.ps1 +17 -18
  84. machineconfig/scripts/python/ai/scripts/lint_and_type_check.sh +17 -18
  85. machineconfig/scripts/python/ai/solutions/_shared.py +9 -1
  86. machineconfig/scripts/python/ai/solutions/copilot/instructions/python/dev.instructions.md +1 -1
  87. machineconfig/scripts/python/ai/solutions/copilot/prompts/pyright_fix.md +16 -0
  88. machineconfig/scripts/python/ai/solutions/generic.py +27 -4
  89. machineconfig/scripts/python/ai/vscode_tasks.py +37 -0
  90. machineconfig/scripts/python/cloud.py +29 -0
  91. machineconfig/scripts/python/croshell.py +117 -181
  92. machineconfig/scripts/python/define.py +31 -0
  93. machineconfig/scripts/python/devops.py +44 -124
  94. machineconfig/scripts/python/devops_navigator.py +10 -0
  95. machineconfig/scripts/python/env_manager/__init__.py +1 -0
  96. machineconfig/scripts/python/env_manager/path_manager_backend.py +47 -0
  97. machineconfig/scripts/python/env_manager/path_manager_tui.py +228 -0
  98. machineconfig/scripts/python/explore.py +49 -0
  99. machineconfig/scripts/python/fire_jobs.py +106 -244
  100. machineconfig/scripts/python/ftpx.py +125 -68
  101. machineconfig/scripts/python/helpers_agents/agentic_frameworks/fire_crush.json +14 -0
  102. machineconfig/scripts/python/helpers_agents/agentic_frameworks/fire_crush.py +37 -0
  103. machineconfig/scripts/python/helpers_agents/agentic_frameworks/fire_cursor_agents.py +22 -0
  104. machineconfig/scripts/python/helpers_agents/agentic_frameworks/fire_gemini.py +42 -0
  105. machineconfig/scripts/python/helpers_agents/agentic_frameworks/fire_qwen.py +30 -0
  106. machineconfig/scripts/python/helpers_agents/fire_agents_help_launch.py +110 -0
  107. machineconfig/scripts/python/helpers_agents/fire_agents_helper_types.py +34 -0
  108. machineconfig/scripts/python/helpers_agents/fire_agents_load_balancer.py +22 -0
  109. machineconfig/scripts/python/helpers_agents/templates/prompt.txt +6 -0
  110. machineconfig/scripts/python/helpers_agents/templates/template.ps1 +14 -0
  111. machineconfig/scripts/python/helpers_agents/templates/template.sh +24 -0
  112. machineconfig/scripts/python/{cloud_copy.py → helpers_cloud/cloud_copy.py} +30 -23
  113. machineconfig/scripts/python/{cloud_mount.py → helpers_cloud/cloud_mount.py} +11 -19
  114. machineconfig/scripts/python/{cloud_sync.py → helpers_cloud/cloud_sync.py} +12 -18
  115. machineconfig/scripts/python/{helpers → helpers_cloud}/helpers2.py +3 -3
  116. machineconfig/scripts/python/helpers_croshell/crosh.py +39 -0
  117. machineconfig/scripts/python/{start_slidev.py → helpers_croshell/start_slidev.py} +17 -7
  118. machineconfig/scripts/python/helpers_devops/cli_config.py +95 -0
  119. machineconfig/scripts/python/helpers_devops/cli_config_dotfile.py +89 -0
  120. machineconfig/scripts/python/helpers_devops/cli_data.py +25 -0
  121. machineconfig/scripts/python/helpers_devops/cli_nw.py +134 -0
  122. machineconfig/scripts/python/helpers_devops/cli_repos.py +182 -0
  123. machineconfig/scripts/python/helpers_devops/cli_self.py +134 -0
  124. machineconfig/scripts/python/helpers_devops/cli_share_file.py +137 -0
  125. machineconfig/scripts/python/helpers_devops/cli_share_server.py +141 -0
  126. machineconfig/scripts/python/helpers_devops/cli_terminal.py +156 -0
  127. machineconfig/scripts/python/helpers_devops/cli_utils.py +96 -0
  128. machineconfig/scripts/python/{devops_backup_retrieve.py → helpers_devops/devops_backup_retrieve.py} +7 -10
  129. machineconfig/scripts/python/helpers_devops/devops_status.py +511 -0
  130. machineconfig/scripts/python/helpers_devops/devops_update_repos.py +269 -0
  131. machineconfig/scripts/python/helpers_devops/themes/choose_pwsh_theme.ps1 +81 -0
  132. machineconfig/scripts/python/helpers_devops/themes/choose_starship_theme.bash +3 -0
  133. machineconfig/scripts/python/{choose_wezterm_theme.py → helpers_devops/themes/choose_wezterm_theme.py} +2 -2
  134. machineconfig/scripts/python/helpers_fire_command/__init__.py +0 -0
  135. machineconfig/scripts/python/{helpers/helpers4.py → helpers_fire_command/file_wrangler.py} +57 -87
  136. machineconfig/scripts/python/helpers_fire_command/fire_jobs_args_helper.py +145 -0
  137. machineconfig/scripts/python/helpers_fire_command/fire_jobs_route_helper.py +110 -0
  138. machineconfig/scripts/python/helpers_fire_command/fire_jobs_streamlit_helper.py +0 -0
  139. machineconfig/scripts/python/helpers_msearch/__init__.py +5 -0
  140. machineconfig/scripts/{linux → python/helpers_msearch/scripts_linux}/fzfag +1 -1
  141. machineconfig/scripts/{linux → python/helpers_msearch/scripts_linux}/fzfg +1 -1
  142. machineconfig/scripts/{linux → python/helpers_msearch/scripts_linux}/fzfrga +1 -1
  143. machineconfig/scripts/python/helpers_navigator/__init__.py +20 -0
  144. machineconfig/scripts/python/helpers_navigator/command_builder.py +111 -0
  145. machineconfig/scripts/python/helpers_navigator/command_detail.py +44 -0
  146. machineconfig/scripts/python/helpers_navigator/command_tree.py +588 -0
  147. machineconfig/scripts/python/helpers_navigator/data_models.py +28 -0
  148. machineconfig/scripts/python/helpers_navigator/main_app.py +272 -0
  149. machineconfig/scripts/python/helpers_navigator/search_bar.py +15 -0
  150. machineconfig/scripts/python/helpers_repos/action.py +209 -0
  151. machineconfig/scripts/python/helpers_repos/action_helper.py +150 -0
  152. machineconfig/scripts/python/{repos_helper_clone.py → helpers_repos/clone.py} +6 -7
  153. machineconfig/scripts/python/helpers_repos/cloud_repo_sync.py +218 -0
  154. machineconfig/scripts/python/helpers_repos/count_lines.py +348 -0
  155. machineconfig/scripts/python/helpers_repos/count_lines_frontend.py +17 -0
  156. machineconfig/scripts/python/helpers_repos/entrypoint.py +77 -0
  157. machineconfig/scripts/python/helpers_repos/grource.py +340 -0
  158. machineconfig/scripts/python/{repos_helper_record.py → helpers_repos/record.py} +7 -4
  159. machineconfig/scripts/python/helpers_repos/sync.py +66 -0
  160. machineconfig/scripts/python/{repos_helper_update.py → helpers_repos/update.py} +3 -3
  161. machineconfig/scripts/python/helpers_sessions/__init__.py +0 -0
  162. machineconfig/scripts/python/helpers_sessions/sessions_multiprocess.py +58 -0
  163. machineconfig/scripts/python/helpers_utils/download.py +152 -0
  164. machineconfig/scripts/python/helpers_utils/path.py +108 -0
  165. machineconfig/scripts/python/interactive.py +79 -160
  166. machineconfig/scripts/python/machineconfig.py +63 -0
  167. machineconfig/scripts/python/msearch.py +21 -0
  168. machineconfig/scripts/python/nw/__init__.py +0 -0
  169. machineconfig/scripts/python/{devops_add_identity.py → nw/devops_add_identity.py} +1 -3
  170. machineconfig/scripts/python/{devops_add_ssh_key.py → nw/devops_add_ssh_key.py} +74 -44
  171. machineconfig/scripts/{linux → python/nw}/mount_nfs +1 -1
  172. machineconfig/scripts/python/{mount_nfs.py → nw/mount_nfs.py} +19 -16
  173. machineconfig/scripts/{linux → python/nw}/mount_nw_drive +1 -2
  174. machineconfig/scripts/python/{mount_ssh.py → nw/mount_ssh.py} +7 -8
  175. machineconfig/scripts/python/{onetimeshare.py → nw/onetimeshare.py} +0 -1
  176. machineconfig/scripts/python/nw/ssh_debug_linux.py +391 -0
  177. machineconfig/scripts/python/nw/ssh_debug_windows.py +338 -0
  178. machineconfig/scripts/python/{wifi_conn.py → nw/wifi_conn.py} +1 -53
  179. machineconfig/scripts/python/{wsl_windows_transfer.py → nw/wsl_windows_transfer.py} +6 -5
  180. machineconfig/scripts/python/sessions.py +167 -0
  181. machineconfig/scripts/python/terminal.py +127 -0
  182. machineconfig/scripts/python/utils.py +66 -0
  183. machineconfig/scripts/windows/{mount_nfs.ps1 → mounts/mount_nfs.ps1} +1 -3
  184. machineconfig/scripts/windows/{mount_ssh.ps1 → mounts/mount_ssh.ps1} +1 -1
  185. machineconfig/scripts/windows/{share_smb.ps1 → mounts/share_smb.ps1} +0 -6
  186. machineconfig/scripts/windows/wrap_mcfg.ps1 +60 -0
  187. machineconfig/settings/broot/br.sh +0 -4
  188. machineconfig/settings/broot/conf.toml +1 -1
  189. machineconfig/settings/helix/config.toml +16 -0
  190. machineconfig/settings/helix/languages.toml +13 -4
  191. machineconfig/settings/helix/yazi-picker.sh +12 -0
  192. machineconfig/settings/lf/linux/exe/lfcd.sh +1 -0
  193. machineconfig/settings/lf/linux/exe/previewer.sh +9 -3
  194. machineconfig/settings/lf/linux/lfrc +10 -12
  195. machineconfig/settings/lf/windows/fzf_edit.ps1 +2 -2
  196. machineconfig/settings/lf/windows/lfrc +18 -38
  197. machineconfig/settings/lf/windows/mkfile.ps1 +1 -1
  198. machineconfig/settings/linters/.ruff.toml +1 -1
  199. machineconfig/settings/lvim/windows/archive/config_additional.lua +0 -6
  200. machineconfig/settings/marimo/marimo.toml +80 -0
  201. machineconfig/settings/marimo/snippets/globalize.py +34 -0
  202. machineconfig/settings/pistol/pistol.conf +1 -1
  203. machineconfig/settings/shells/bash/init.sh +55 -31
  204. machineconfig/settings/shells/nushell/config.nu +1 -34
  205. machineconfig/settings/shells/nushell/init.nu +127 -0
  206. machineconfig/settings/shells/pwsh/init.ps1 +60 -43
  207. machineconfig/settings/shells/starship/starship.toml +16 -0
  208. machineconfig/settings/shells/wezterm/wezterm.lua +2 -0
  209. machineconfig/settings/shells/wt/settings.json +32 -17
  210. machineconfig/settings/shells/zsh/init.sh +89 -0
  211. machineconfig/settings/svim/linux/init.toml +0 -4
  212. machineconfig/settings/svim/windows/init.toml +0 -3
  213. machineconfig/settings/yazi/init.lua +57 -0
  214. machineconfig/settings/yazi/keymap_linux.toml +79 -0
  215. machineconfig/settings/yazi/keymap_windows.toml +78 -0
  216. machineconfig/settings/yazi/shell/yazi_cd.ps1 +33 -0
  217. machineconfig/settings/yazi/shell/yazi_cd.sh +8 -0
  218. machineconfig/settings/yazi/yazi.toml +13 -0
  219. machineconfig/setup_linux/__init__.py +10 -0
  220. machineconfig/setup_linux/apps_desktop.sh +89 -0
  221. machineconfig/setup_linux/apps_gui.sh +64 -0
  222. machineconfig/setup_linux/{nix → others}/cli_installation.sh +9 -29
  223. machineconfig/setup_linux/ssh/openssh_all.sh +25 -0
  224. machineconfig/setup_linux/ssh/openssh_wsl.sh +38 -0
  225. machineconfig/setup_linux/uv.sh +15 -0
  226. machineconfig/setup_linux/web_shortcuts/interactive.sh +26 -6
  227. machineconfig/setup_mac/__init__.py +16 -0
  228. machineconfig/setup_mac/apps_gui.sh +248 -0
  229. machineconfig/setup_mac/ssh/openssh_setup.sh +114 -0
  230. machineconfig/setup_mac/uv.sh +36 -0
  231. machineconfig/setup_windows/__init__.py +8 -0
  232. machineconfig/setup_windows/others/power_options.ps1 +7 -0
  233. machineconfig/setup_windows/ssh/add-sshkey.ps1 +29 -0
  234. machineconfig/setup_windows/ssh/add_identity.ps1 +11 -0
  235. machineconfig/setup_windows/ssh/openssh-server.ps1 +37 -0
  236. machineconfig/setup_windows/uv.ps1 +10 -0
  237. machineconfig/setup_windows/web_shortcuts/interactive.ps1 +27 -9
  238. machineconfig/setup_windows/web_shortcuts/quick_init.ps1 +16 -0
  239. machineconfig/setup_windows/wt_and_pwsh/set_wt_settings.py +37 -23
  240. machineconfig/utils/accessories.py +7 -5
  241. machineconfig/utils/cloud/onedrive/README.md +139 -0
  242. machineconfig/utils/code.py +140 -93
  243. machineconfig/utils/files/art/fat_croco.txt +10 -0
  244. machineconfig/utils/files/art/halfwit_croco.txt +9 -0
  245. machineconfig/utils/files/art/happy_croco.txt +22 -0
  246. machineconfig/utils/files/art/water_croco.txt +11 -0
  247. machineconfig/utils/files/ascii_art.py +118 -0
  248. machineconfig/utils/files/dbms.py +257 -0
  249. machineconfig/utils/files/headers.py +68 -0
  250. machineconfig/utils/files/ouch/__init__.py +0 -0
  251. machineconfig/utils/files/ouch/decompress.py +45 -0
  252. machineconfig/utils/files/read.py +95 -0
  253. machineconfig/utils/installer_utils/github_release_bulk.py +2 -12
  254. machineconfig/utils/installer_utils/installer_class.py +68 -126
  255. machineconfig/utils/installer_utils/installer_cli.py +181 -0
  256. machineconfig/utils/installer_utils/{installer_abc.py → installer_locator_utils.py} +38 -85
  257. machineconfig/utils/{installer.py → installer_utils/installer_runner.py} +69 -69
  258. machineconfig/utils/io.py +77 -23
  259. machineconfig/utils/links.py +309 -100
  260. machineconfig/utils/meta.py +255 -0
  261. machineconfig/utils/notifications.py +1 -1
  262. machineconfig/utils/options.py +10 -25
  263. machineconfig/utils/path_extended.py +94 -104
  264. machineconfig/utils/path_helper.py +75 -22
  265. machineconfig/utils/procs.py +50 -74
  266. machineconfig/utils/scheduler.py +94 -97
  267. machineconfig/utils/scheduling.py +0 -3
  268. machineconfig/utils/schemas/fire_agents/fire_agents_input.py +5 -17
  269. machineconfig/utils/schemas/installer/installer_types.py +0 -1
  270. machineconfig/utils/schemas/layouts/layout_types.py +2 -1
  271. machineconfig/utils/source_of_truth.py +3 -6
  272. machineconfig/utils/ssh.py +742 -254
  273. machineconfig/utils/ssh_utils/utils.py +0 -0
  274. machineconfig/utils/terminal.py +3 -140
  275. machineconfig/utils/tst.py +20 -0
  276. machineconfig/utils/upgrade_packages.py +109 -28
  277. machineconfig/utils/ve.py +13 -5
  278. machineconfig-7.66.dist-info/METADATA +124 -0
  279. machineconfig-7.66.dist-info/RECORD +451 -0
  280. machineconfig-7.66.dist-info/entry_points.txt +15 -0
  281. machineconfig/cluster/templates/utils.py +0 -51
  282. machineconfig/jobs/installer/linux_scripts/pgsql.sh +0 -49
  283. machineconfig/jobs/installer/linux_scripts/timescaledb.sh +0 -85
  284. machineconfig/jobs/installer/packages_custom_dev.json +0 -226
  285. machineconfig/jobs/installer/packages_custom_essential.json +0 -39
  286. machineconfig/jobs/installer/packages_github_dev.json +0 -1110
  287. machineconfig/jobs/installer/packages_github_essential.json +0 -804
  288. machineconfig/jobs/linux/msc/cli_agents.sh +0 -37
  289. machineconfig/jobs/python/create_bootable_media.py +0 -16
  290. machineconfig/jobs/python/python_cargo_build_share.py +0 -59
  291. machineconfig/jobs/python/python_ve_symlink.py +0 -29
  292. machineconfig/jobs/python/tasks.py +0 -3
  293. machineconfig/jobs/python/vscode/api.py +0 -49
  294. machineconfig/jobs/python/vscode/sync_code.py +0 -58
  295. machineconfig/jobs/windows/archive/archive_pygraphviz.ps1 +0 -14
  296. machineconfig/jobs/windows/start_terminal.ps1 +0 -6
  297. machineconfig/jobs/windows/startup_file.cmd +0 -2
  298. machineconfig/profile/create.py +0 -170
  299. machineconfig/profile/shell.py +0 -176
  300. machineconfig/scripts/cloud/init.sh +0 -119
  301. machineconfig/scripts/linux/choose_wezterm_theme +0 -3
  302. machineconfig/scripts/linux/cloud_copy +0 -2
  303. machineconfig/scripts/linux/cloud_mount +0 -2
  304. machineconfig/scripts/linux/cloud_repo_sync +0 -2
  305. machineconfig/scripts/linux/cloud_sync +0 -2
  306. machineconfig/scripts/linux/croshell +0 -3
  307. machineconfig/scripts/linux/devops +0 -2
  308. machineconfig/scripts/linux/fire +0 -2
  309. machineconfig/scripts/linux/fire_agents +0 -2
  310. machineconfig/scripts/linux/ftpx +0 -2
  311. machineconfig/scripts/linux/fzf2g +0 -21
  312. machineconfig/scripts/linux/fzffg +0 -25
  313. machineconfig/scripts/linux/gh_models +0 -2
  314. machineconfig/scripts/linux/initai +0 -2
  315. machineconfig/scripts/linux/kill_process +0 -2
  316. machineconfig/scripts/linux/programs +0 -21
  317. machineconfig/scripts/linux/repos +0 -2
  318. machineconfig/scripts/linux/scheduler +0 -2
  319. machineconfig/scripts/linux/share_smb +0 -1
  320. machineconfig/scripts/linux/start_slidev +0 -2
  321. machineconfig/scripts/linux/start_terminals +0 -3
  322. machineconfig/scripts/linux/warp-cli.sh +0 -122
  323. machineconfig/scripts/linux/wifi_conn +0 -2
  324. machineconfig/scripts/linux/z_ls +0 -104
  325. machineconfig/scripts/python/ai/solutions/copilot/prompts/allLintersAndTypeCheckers.prompt.md +0 -5
  326. machineconfig/scripts/python/cloud_repo_sync.py +0 -186
  327. machineconfig/scripts/python/devops_devapps_install.py +0 -159
  328. machineconfig/scripts/python/devops_update_repos.py +0 -180
  329. machineconfig/scripts/python/dotfile.py +0 -52
  330. machineconfig/scripts/python/fire_agents.py +0 -175
  331. machineconfig/scripts/python/fire_agents_help_launch.py +0 -143
  332. machineconfig/scripts/python/fire_agents_load_balancer.py +0 -50
  333. machineconfig/scripts/python/fire_jobs_args_helper.py +0 -75
  334. machineconfig/scripts/python/fire_jobs_layout_helper.py +0 -74
  335. machineconfig/scripts/python/get_zellij_cmd.py +0 -15
  336. machineconfig/scripts/python/gh_models.py +0 -104
  337. machineconfig/scripts/python/helpers/repo_sync_helpers.py +0 -114
  338. machineconfig/scripts/python/repos.py +0 -80
  339. machineconfig/scripts/python/repos_helper_action.py +0 -335
  340. machineconfig/scripts/python/share_terminal.py +0 -104
  341. machineconfig/scripts/python/snapshot.py +0 -25
  342. machineconfig/scripts/python/start_terminals.py +0 -121
  343. machineconfig/scripts/python/t4.py +0 -17
  344. machineconfig/scripts/windows/choose_wezterm_theme.ps1 +0 -1
  345. machineconfig/scripts/windows/cloud_copy.ps1 +0 -1
  346. machineconfig/scripts/windows/cloud_mount.ps1 +0 -1
  347. machineconfig/scripts/windows/cloud_repo_sync.ps1 +0 -1
  348. machineconfig/scripts/windows/cloud_sync.ps1 +0 -1
  349. machineconfig/scripts/windows/croshell.ps1 +0 -1
  350. machineconfig/scripts/windows/devops.ps1 +0 -1
  351. machineconfig/scripts/windows/dotfile.ps1 +0 -1
  352. machineconfig/scripts/windows/fire.ps1 +0 -1
  353. machineconfig/scripts/windows/ftpx.ps1 +0 -1
  354. machineconfig/scripts/windows/gpt.ps1 +0 -1
  355. machineconfig/scripts/windows/grep.ps1 +0 -2
  356. machineconfig/scripts/windows/initai.ps1 +0 -1
  357. machineconfig/scripts/windows/kill_process.ps1 +0 -1
  358. machineconfig/scripts/windows/nano.ps1 +0 -3
  359. machineconfig/scripts/windows/pomodoro.ps1 +0 -1
  360. machineconfig/scripts/windows/reload_path.ps1 +0 -3
  361. machineconfig/scripts/windows/repos.ps1 +0 -1
  362. machineconfig/scripts/windows/scheduler.ps1 +0 -1
  363. machineconfig/scripts/windows/snapshot.ps1 +0 -1
  364. machineconfig/scripts/windows/start_slidev.ps1 +0 -1
  365. machineconfig/scripts/windows/start_terminals.ps1 +0 -1
  366. machineconfig/scripts/windows/wifi_conn.ps1 +0 -2
  367. machineconfig/scripts/windows/wsl_rdp_windows_port_forwarding.ps1 +0 -46
  368. machineconfig/scripts/windows/wsl_ssh_windows_port_forwarding.ps1 +0 -76
  369. machineconfig/settings/lf/linux/exe/fzf_nano.sh +0 -16
  370. machineconfig/setup_linux/others/openssh-server_add_pub_key.sh +0 -57
  371. machineconfig/setup_linux/web_shortcuts/ascii_art.sh +0 -93
  372. machineconfig/setup_linux/web_shortcuts/croshell.sh +0 -11
  373. machineconfig/setup_linux/web_shortcuts/ssh.sh +0 -52
  374. machineconfig/setup_windows/web_shortcuts/all.ps1 +0 -18
  375. machineconfig/setup_windows/web_shortcuts/ascii_art.ps1 +0 -36
  376. machineconfig/setup_windows/web_shortcuts/croshell.ps1 +0 -16
  377. machineconfig/setup_windows/web_shortcuts/ssh.ps1 +0 -11
  378. machineconfig/utils/ai/generate_file_checklist.py +0 -68
  379. machineconfig-3.99.dist-info/METADATA +0 -167
  380. machineconfig-3.99.dist-info/RECORD +0 -409
  381. machineconfig-3.99.dist-info/entry_points.txt +0 -18
  382. machineconfig/cluster/{templates → remote}/run_cloud.py +0 -0
  383. machineconfig/cluster/{templates → remote}/run_cluster.py +0 -0
  384. machineconfig/cluster/{templates → remote}/run_remote.py +0 -0
  385. machineconfig/scripts/linux/{share_nfs → other/share_nfs} +0 -0
  386. machineconfig/scripts/linux/{start_docker → other/start_docker} +0 -0
  387. machineconfig/scripts/linux/{switch_ip → other/switch_ip} +0 -0
  388. machineconfig/{jobs/python → scripts/python/helpers_agents}/__init__.py +0 -0
  389. machineconfig/scripts/python/{helpers → helpers_agents/agentic_frameworks}/__init__.py +0 -0
  390. machineconfig/scripts/python/{fire_agents_help_search.py → helpers_agents/fire_agents_help_search.py} +0 -0
  391. machineconfig/{jobs/windows/msc/cli_agents.bat → scripts/python/helpers_cloud/__init__.py} +0 -0
  392. machineconfig/scripts/python/{helpers → helpers_cloud}/cloud_helpers.py +1 -1
  393. /machineconfig/scripts/python/{helpers → helpers_cloud}/helpers5.py +0 -0
  394. /machineconfig/{jobs/windows/msc/cli_agents.ps1 → scripts/python/helpers_croshell/__init__.py} +0 -0
  395. /machineconfig/scripts/python/{pomodoro.py → helpers_croshell/pomodoro.py} +0 -0
  396. /machineconfig/scripts/python/{scheduler.py → helpers_croshell/scheduler.py} +0 -0
  397. /machineconfig/scripts/python/{viewer.py → helpers_croshell/viewer.py} +0 -0
  398. /machineconfig/scripts/python/{viewer_template.py → helpers_croshell/viewer_template.py} +0 -0
  399. /machineconfig/scripts/python/{fire_jobs_streamlit_helper.py → helpers_devops/__init__.py} +0 -0
  400. /machineconfig/scripts/{windows/share_nfs.ps1 → python/helpers_devops/themes/__init__.py} +0 -0
  401. /machineconfig/{settings/yazi/keymap.toml → scripts/python/helpers_devops/themes/choose_starship_theme.ps1} +0 -0
  402. /machineconfig/scripts/python/{cloud_manager.py → helpers_fire_command/cloud_manager.py} +0 -0
  403. /machineconfig/scripts/{linux → python/helpers_msearch/scripts_linux}/skrg +0 -0
  404. /machineconfig/scripts/{windows → python/helpers_msearch/scripts_windows}/fzfb.ps1 +0 -0
  405. /machineconfig/scripts/{windows → python/helpers_msearch/scripts_windows}/fzfg.ps1 +0 -0
  406. /machineconfig/scripts/{windows → python/helpers_msearch/scripts_windows}/fzfrga.bat +0 -0
  407. /machineconfig/scripts/{linux → python/nw}/mount_drive +0 -0
  408. /machineconfig/scripts/python/{mount_nw_drive.py → nw/mount_nw_drive.py} +0 -0
  409. /machineconfig/scripts/{linux → python/nw}/mount_smb +0 -0
  410. /machineconfig/scripts/windows/{mount_nw.ps1 → mounts/mount_nw.ps1} +0 -0
  411. /machineconfig/scripts/windows/{mount_smb.ps1 → mounts/mount_smb.ps1} +0 -0
  412. /machineconfig/scripts/windows/{share_cloud.cmd → mounts/share_cloud.cmd} +0 -0
  413. /machineconfig/scripts/windows/{unlock_bitlocker.ps1 → mounts/unlock_bitlocker.ps1} +0 -0
  414. /machineconfig/setup_linux/{web_shortcuts → others}/android.sh +0 -0
  415. /machineconfig/{jobs/windows/archive → setup_windows/ssh}/openssh-server_add_key.ps1 +0 -0
  416. /machineconfig/{jobs/windows/archive → setup_windows/ssh}/openssh-server_copy-ssh-id.ps1 +0 -0
  417. {machineconfig-3.99.dist-info → machineconfig-7.66.dist-info}/WHEEL +0 -0
  418. {machineconfig-3.99.dist-info → machineconfig-7.66.dist-info}/top_level.txt +0 -0
@@ -1,15 +1,14 @@
1
-
2
- from machineconfig.utils.path_extended import PathExtended as PathExtended
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
 
5
4
  from pathlib import Path
6
- from typing import Any, Optional
5
+ from typing import Optional
7
6
  import subprocess
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,26 +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
144
 
145
+ def is_executable_in_path(name: str) -> bool:
146
+ import os
147
+ path_dirs = os.environ['PATH'].split(os.pathsep)
148
+ for path_dir in path_dirs:
149
+ path_to_executable = os.path.join(path_dir, name)
150
+ if os.path.isfile(path_to_executable) and os.access(path_to_executable, os.X_OK): return True
151
+ return False
152
+
128
153
 
129
154
  def check_if_installed_already(exe_name: str, version: Optional[str], use_cache: bool) -> tuple[str, str, str]:
130
- print(f"\n{'=' * 80}\n🔍 CHECKING INSTALLATION STATUS: {exe_name} 🔍\n{'=' * 80}")
155
+ print(f"🔍 CHECKING INSTALLATION STATUS: {exe_name} 🔍")
131
156
  INSTALL_VERSION_ROOT.joinpath(exe_name).parent.mkdir(parents=True, exist_ok=True)
132
157
  tmp_path = INSTALL_VERSION_ROOT.joinpath(exe_name)
133
158
 
@@ -166,75 +191,3 @@ def check_if_installed_already(exe_name: str, version: Optional[str], use_cache:
166
191
  return ("⚠️ NotInstalled", "None", version or "unknown")
167
192
 
168
193
 
169
- def parse_apps_installer_linux(txt: str) -> dict[str, Any]:
170
- """Parse Linux shell installation scripts into logical chunks.
171
-
172
- Supports two formats:
173
- 1. Legacy format with 'yes '' | sed 3q; echo "----------------------------- installing' delimiter
174
- 2. New format with # --BLOCK:<name>-- comment signatures
175
-
176
- Returns:
177
- dict[str, str]: Dictionary mapping block/section names to their installation scripts
178
- """
179
- # Try new block format first
180
- if "# --BLOCK:" in txt:
181
- import re
182
- # Split by block signatures: # --BLOCK:<name>--
183
- blocks = re.split(r'# --BLOCK:([^-]+)--', txt)
184
- res: dict[str, str] = {}
185
-
186
- # Process blocks in pairs (block_name, block_content)
187
- for i in range(1, len(blocks), 2):
188
- if i + 1 < len(blocks):
189
- block_name = blocks[i].strip()
190
- block_content = blocks[i + 1].strip()
191
- if block_content:
192
- res[block_name] = block_content
193
-
194
- return res
195
-
196
- # Legacy format fallback
197
- txts = txt.split("""yes '' | sed 3q; echo "----------------------------- installing """)
198
- res = {}
199
- for chunk in txts[1:]:
200
- try:
201
- k = chunk.split("----")[0].rstrip().lstrip()
202
- v = "\n".join(chunk.split("\n")[1:])
203
- res[k] = v
204
- except IndexError as e:
205
- print(f"""
206
- ❌ Error parsing chunk:
207
- {"-" * 50}
208
- {chunk}
209
- {"-" * 50}""")
210
- raise e
211
- return res
212
-
213
-
214
- def parse_apps_installer_windows(txt: str) -> dict[str, Any]:
215
- chunks: list[str] = []
216
- for idx, item in enumerate(txt.split(sep="winget install")):
217
- if idx == 0:
218
- continue
219
- if idx == 1:
220
- chunks.append(item)
221
- else:
222
- chunks.append("winget install" + item)
223
- # progs = L(txt.splitlines()).filter(lambda x: x.startswith("winget ") or x.startswith("#winget"))
224
- res: dict[str, str] = {}
225
- for a_chunk in chunks:
226
- try:
227
- name = a_chunk.split("--name ")[1]
228
- if "--Id" not in name:
229
- print(f"⚠️ Warning: {name} does not have an Id, skipping")
230
- continue
231
- name = name.split(" --Id ", maxsplit=1)[0].strip('"').strip('"')
232
- res[name] = a_chunk
233
- except IndexError as e:
234
- print(f"""
235
- ❌ Error parsing chunk:
236
- {"-" * 50}
237
- {a_chunk}
238
- {"-" * 50}""")
239
- raise e
240
- return res
@@ -1,16 +1,16 @@
1
1
  """package manager"""
2
2
 
3
- from machineconfig.utils.installer_utils.installer_abc import check_if_installed_already
3
+ from machineconfig.utils.installer_utils.installer_locator_utils import check_if_installed_already
4
4
  from machineconfig.utils.installer_utils.installer_class import Installer
5
- from machineconfig.utils.schemas.installer.installer_types import APP_INSTALLER_CATEGORY, InstallerData, InstallerDataFiles, get_normalized_arch, get_os_name, OPERATING_SYSTEMS, CPU_ARCHITECTURES
6
- from rich.console import Console
7
- from rich.panel import Panel
8
-
9
- from machineconfig.utils.path_extended import PathExtended as PathExtended
5
+ from machineconfig.utils.schemas.installer.installer_types import InstallerData, InstallerDataFiles, get_normalized_arch, get_os_name, OPERATING_SYSTEMS, CPU_ARCHITECTURES
6
+ from machineconfig.jobs.installer.package_groups import PACKAGE_GROUP2NAMES
7
+ from machineconfig.utils.path_extended import PathExtended
10
8
  from machineconfig.utils.source_of_truth import INSTALL_VERSION_ROOT, LINUX_INSTALL_PATH
11
9
  from machineconfig.utils.io import read_json
12
10
 
13
- from typing import Any
11
+ from rich.console import Console
12
+ from rich.panel import Panel
13
+ from typing import Any, Optional
14
14
  import platform
15
15
  from joblib import Parallel, delayed
16
16
 
@@ -18,11 +18,11 @@ from joblib import Parallel, delayed
18
18
  def check_latest():
19
19
  console = Console() # Added console initialization
20
20
  console.print(Panel("🔍 CHECKING FOR LATEST VERSIONS", title="Status", expand=False)) # Replaced print with Panel
21
- installers = get_installers(os=get_os_name(), arch=get_normalized_arch(), which_cats=["GITHUB_ESSENTIAL", "CUSTOM_ESSENTIAL"])
21
+ installers = get_installers(os=get_os_name(), arch=get_normalized_arch(), which_cats=["termabc"])
22
22
  installers_github = []
23
23
  for inst__ in installers:
24
- app_name = inst__.installer_data.get("appName", "unknown")
25
- repo_url = inst__.installer_data.get("repoURL", "")
24
+ app_name = inst__["appName"]
25
+ repo_url = inst__["repoURL"]
26
26
  if "ntop" in app_name:
27
27
  print(f"⏭️ Skipping {app_name} (ntop)")
28
28
  continue
@@ -63,16 +63,16 @@ def check_latest():
63
63
 
64
64
  # Print each group
65
65
  for status, items in grouped_data.items():
66
- print(f"\n{status.upper()}:")
67
- print("-" * 60)
66
+ console.print(f"\n[bold]{status.upper()}:[/bold]")
67
+ console.rule(style="dim")
68
68
  for item in items:
69
- print(f" {item['Tool']:<20} | Current: {item['Current Version']:<15} | New: {item['New Version']}")
70
- print("-" * 60)
71
- 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")
72
72
 
73
73
 
74
74
  def get_installed_cli_apps():
75
- print(f"\n{'=' * 80}\n🔍 LISTING INSTALLED CLI APPS 🔍\n{'=' * 80}")
75
+ print("🔍 LISTING INSTALLED CLI APPS 🔍")
76
76
  if platform.system() == "Windows":
77
77
  print("🪟 Searching for Windows executables...")
78
78
  apps = PathExtended.home().joinpath("AppData/Local/Microsoft/WindowsApps").search("*.exe", not_in=["notepad"])
@@ -87,78 +87,59 @@ def get_installed_cli_apps():
87
87
  print(error_msg)
88
88
  raise NotImplementedError(error_msg)
89
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
90
- print(f"✅ Found {len(apps)} installed applications\n{'=' * 80}")
90
+ print(f"✅ Found {len(apps)} installed applications")
91
91
  return apps
92
92
 
93
93
 
94
- def get_installers(os: OPERATING_SYSTEMS, arch: CPU_ARCHITECTURES, which_cats: list[APP_INSTALLER_CATEGORY]) -> list[Installer]:
95
- print(f"\n{'=' * 80}\n🔍 LOADING INSTALLER CONFIGURATIONS 🔍\n{'=' * 80}")
96
- res_all = get_all_installer_data_files(which_cats=which_cats)
94
+ def get_installers(os: OPERATING_SYSTEMS, arch: CPU_ARCHITECTURES, which_cats: Optional[list[str]]) -> list[InstallerData]:
95
+ res_all = get_all_installer_data_files()
96
+ acceptable_apps_names: list[str] | None = None
97
+ if which_cats is not None:
98
+ acceptable_apps_names = []
99
+ for cat in which_cats:
100
+ acceptable_apps_names += PACKAGE_GROUP2NAMES[cat]
101
+ else:
102
+ acceptable_apps_names = None
97
103
  all_installers: list[InstallerData] = []
98
- for _category, installer_data_files in res_all.items():
99
- suitable_installers = []
100
- for an_installer in installer_data_files["installers"]:
101
- if an_installer["fileNamePattern"][arch][os] is None:
104
+ for installer_data in res_all:
105
+ if acceptable_apps_names is not None:
106
+ if installer_data["appName"] not in acceptable_apps_names:
102
107
  continue
103
- suitable_installers.append(an_installer)
104
- all_installers.extend(suitable_installers)
105
- print(f"✅ Loaded {len(all_installers)} installer configurations\n{'=' * 80}")
106
- return [Installer(installer_data=installer_data) for installer_data in all_installers]
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}")
115
+ all_installers.append(installer_data)
116
+ return all_installers
107
117
 
108
118
 
109
- def get_all_installer_data_files(which_cats: list[APP_INSTALLER_CATEGORY]) -> dict[APP_INSTALLER_CATEGORY, InstallerDataFiles]:
110
- print(f"\n{'=' * 80}\n📂 LOADING CONFIGURATION FILES 📂\n{'=' * 80}")
119
+ def get_all_installer_data_files() -> list[InstallerData]:
111
120
  import machineconfig.jobs.installer as module
112
121
  from pathlib import Path
113
- print("📂 Loading configuration files...")
114
- res_final: dict[APP_INSTALLER_CATEGORY, InstallerDataFiles] = {key: read_json(Path(module.__file__).parent.joinpath(f"packages_{key.lower()}.json")) for key in which_cats}
115
- print(f"Loaded: {len(res_final)} installer categories")
116
- for k, v in res_final.items():
117
- print(f" - {k}: {len(v['installers'])} items")
122
+ res_raw: InstallerDataFiles = read_json(Path(module.__file__).parent.joinpath("installer_data.json"))
123
+ res_final: list[InstallerData] = res_raw["installers"]
118
124
  return res_final
119
125
 
120
126
 
121
- def install_all(installers: list[Installer], safe: bool = False, jobs: int = 10, fresh: bool = False):
122
- print(f"\n{'=' * 80}\n🚀 BULK INSTALLATION PROCESS 🚀\n{'=' * 80}")
127
+ def install_bulk(installers_data: list[InstallerData], safe: bool = False, jobs: int = 10, fresh: bool = False):
128
+ print("🚀 BULK INSTALLATION PROCESS 🚀")
123
129
  if fresh:
124
130
  print("🧹 Fresh install requested - clearing version cache...")
125
131
  PathExtended(INSTALL_VERSION_ROOT).delete(sure=True)
126
132
  print("✅ Version cache cleared")
127
-
128
133
  if safe:
129
134
  pass
130
- # print("⚠️ Safe installation mode activated...")
131
- # from machineconfig.jobs.python.check_installations import APP_SUMMARY_PATH
132
- # if platform.system().lower() == "windows":
133
- # print("🪟 Moving applications to Windows Apps folder...")
134
- # # PathExtended.get_env().WindowsPaths().WindowsApps)
135
- # folder = PathExtended.home().joinpath("AppData/Local/Microsoft/WindowsApps")
136
- # apps_dir.search("*").apply(lambda app: app.move(folder=folder))
137
- # elif platform.system().lower() in ["linux", "darwin"]:
138
- # system_name = "Linux" if platform.system().lower() == "linux" else "macOS"
139
- # print(f"🐧 Moving applications to {system_name} bin folder...")
140
- # if platform.system().lower() == "linux":
141
- # install_path = LINUX_INSTALL_PATH
142
- # else: # Darwin/macOS
143
- # install_path = "/usr/local/bin"
144
- # 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)
145
- # else:
146
- # error_msg = f"❌ ERROR: System {platform.system()} not supported"
147
- # print(error_msg)
148
- # raise NotImplementedError(error_msg)
149
-
150
- # apps_dir.delete(sure=True)
151
- # print(f"✅ Safe installation completed\n{'='*80}")
152
- # return None
153
-
154
- print(f"🚀 Starting installation of {len(installers)} packages...")
155
- print(f"\n{'=' * 80}\n📦 INSTALLING FIRST PACKAGE 📦\n{'=' * 80}")
156
- installers[0].install(version=None)
157
- installers_remaining = installers[1:]
158
- print(f"\n{'=' * 80}\n📦 INSTALLING REMAINING PACKAGES 📦\n{'=' * 80}")
135
+ print(f"🚀 Starting installation of {len(installers_data)} packages...")
136
+ print("📦 INSTALLING FIRST PACKAGE 📦")
137
+ Installer(installers_data[0]).install(version=None)
138
+ installers_remaining = installers_data[1:]
139
+ print("📦 INSTALLING REMAINING PACKAGES 📦")
159
140
 
160
141
  # Use joblib for parallel processing of remaining installers
161
- res = Parallel(n_jobs=jobs)(delayed(lambda x: x.install_robust(version=None))(installer) for installer in installers_remaining)
142
+ res = Parallel(n_jobs=jobs)(delayed(lambda x: Installer(x).install_robust(version=None))(installer) for installer in installers_remaining)
162
143
 
163
144
  console = Console()
164
145
 
@@ -188,4 +169,23 @@ def install_all(installers: list[Installer], safe: bool = False, jobs: int = 10,
188
169
  print("\n" * 2)
189
170
 
190
171
 
191
-
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"
machineconfig/utils/io.py CHANGED
@@ -1,4 +1,3 @@
1
- from __future__ import annotations
2
1
 
3
2
  from typing import Any, Union, Optional, Mapping
4
3
  from pathlib import Path
@@ -35,24 +34,6 @@ def save_json(obj: Any, path: PathLike, indent: Optional[int] = None, verbose: b
35
34
  return Path(path_obj)
36
35
 
37
36
 
38
- # def save_toml(obj: Mapping[str, Any], path: PathLike, verbose: bool = False) -> Path:
39
- # path_obj = _ensure_parent(path)
40
- # with open(path_obj, "w", encoding="utf-8") as fh:
41
- # toml.dump(obj, fh)
42
- # if verbose:
43
- # print(f"Saved toml -> {path_obj}")
44
- # return Path(path_obj)
45
-
46
-
47
- # def save_yaml(obj: Any, path: PathLike, verbose: bool = False) -> Path:
48
- # path_obj = _ensure_parent(path)
49
- # with open(path_obj, "w", encoding="utf-8") as fh:
50
- # yaml.safe_dump(obj, fh, sort_keys=False)
51
- # if verbose:
52
- # print(f"Saved yaml -> {path_obj}")
53
- # return Path(path_obj)
54
-
55
-
56
37
  def save_ini(path: PathLike, obj: Mapping[str, Mapping[str, Any]], verbose: bool = False) -> Path:
57
38
  cp = configparser.ConfigParser()
58
39
  for section, values in obj.items():
@@ -69,7 +50,6 @@ def read_ini(path: "Path", encoding: Optional[str] = None):
69
50
  if not Path(path).exists() or Path(path).is_dir():
70
51
  raise FileNotFoundError(f"File not found or is a directory: {path}")
71
52
  import configparser
72
-
73
53
  res = configparser.ConfigParser()
74
54
  res.read(filenames=[str(path)], encoding=encoding)
75
55
  return res
@@ -80,9 +60,14 @@ def read_json(path: "Path", r: bool = False, **kwargs: Any) -> Any: # return co
80
60
  try:
81
61
  mydict = json.loads(Path(path).read_text(encoding="utf-8"), **kwargs)
82
62
  except Exception:
83
- import pyjson5
84
-
85
- mydict = pyjson5.loads(Path(path).read_text(encoding="utf-8"), **kwargs) # file has C-style comments.
63
+ import re
64
+ def remove_comments(text: str) -> str:
65
+ # remove all // single-line comments
66
+ text = re.sub(r'//.*', '', text)
67
+ # remove all /* … */ block comments (non-greedy)
68
+ text = re.sub(r'/\*.*?\*/', '', text, flags=re.DOTALL)
69
+ return text
70
+ mydict = json.loads(remove_comments(Path(path).read_text(encoding="utf-8")), **kwargs)
86
71
  _ = r
87
72
  return mydict
88
73
 
@@ -91,3 +76,72 @@ def from_pickle(path: Path) -> Any:
91
76
  import pickle
92
77
 
93
78
  return pickle.loads(path.read_bytes())
79
+
80
+
81
+ def pwd2key(password: str, salt: Optional[bytes] = None, iterations: int = 10) -> bytes: # Derive a secret key from a given password and salt"""
82
+ import base64
83
+ if salt is None:
84
+ import hashlib
85
+ m = hashlib.sha256()
86
+ m.update(password.encode(encoding="utf-8"))
87
+ return base64.urlsafe_b64encode(s=m.digest()) # make url-safe bytes required by Ferent.
88
+ from cryptography.hazmat.primitives import hashes
89
+ from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
90
+ return base64.urlsafe_b64encode(PBKDF2HMAC(algorithm=hashes.SHA256(), length=32, salt=salt, iterations=iterations, backend=None).derive(password.encode()))
91
+
92
+
93
+ def encrypt(msg: bytes, key: Optional[bytes] = None, pwd: Optional[str] = None, salted: bool = True, iteration: Optional[int] = None, gen_key: bool = False) -> bytes:
94
+ import base64
95
+ from cryptography.fernet import Fernet
96
+
97
+ salt, iteration = None, None
98
+ if pwd is not None: # generate it from password
99
+ assert (key is None) and (type(pwd) is str), "❌ You can either pass key or pwd, or none of them, but not both."
100
+ import secrets
101
+ iteration = iteration or secrets.randbelow(exclusive_upper_bound=1_000_000)
102
+ salt = secrets.token_bytes(nbytes=16) if salted else None
103
+ key_resolved = pwd2key(password=pwd, salt=salt, iterations=iteration)
104
+ elif key is None:
105
+ if gen_key:
106
+ key_resolved = Fernet.generate_key()
107
+ Path.home().joinpath("dotfiles/creds/data/encrypted_files_key.bytes").write_bytes(key_resolved)
108
+ else:
109
+ try:
110
+ key_resolved = Path.home().joinpath("dotfiles/creds/data/encrypted_files_key.bytes").read_bytes()
111
+ print(f"⚠️ Using key from: {Path.home().joinpath('dotfiles/creds/data/encrypted_files_key.bytes')}")
112
+ except FileNotFoundError as err:
113
+ print("\n" * 3, "~" * 50, """Consider Loading up your dotfiles or pass `gen_key=True` to make and save one.""", "~" * 50, "\n" * 3)
114
+ raise FileNotFoundError(err) from err
115
+ elif isinstance(key, (str, Path)):
116
+ key_resolved = Path(key).read_bytes() # a path to a key file was passed, read it:
117
+ elif type(key) is bytes:
118
+ key_resolved = key # key passed explicitly
119
+ else:
120
+ raise TypeError("❌ Key must be either a path, bytes object or None.")
121
+ code = Fernet(key=key_resolved).encrypt(msg)
122
+ if pwd is not None and salt is not None and iteration is not None:
123
+ return base64.urlsafe_b64encode(b"%b%b%b" % (salt, iteration.to_bytes(4, "big"), base64.urlsafe_b64decode(code)))
124
+ return code
125
+
126
+
127
+ def decrypt(token: bytes, key: Optional[bytes] = None, pwd: Optional[str] = None, salted: bool = True) -> bytes:
128
+ import base64
129
+ if pwd is not None:
130
+ assert key is None, "❌ You can either pass key or pwd, or none of them, but not both."
131
+ if salted:
132
+ decoded = base64.urlsafe_b64decode(token)
133
+ salt, iterations, token = decoded[:16], decoded[16:20], base64.urlsafe_b64encode(decoded[20:])
134
+ key_resolved = pwd2key(password=pwd, salt=salt, iterations=int.from_bytes(bytes=iterations, byteorder="big"))
135
+ else:
136
+ key_resolved = pwd2key(password=pwd) # trailing `;` prevents IPython from caching the result.
137
+ elif type(key) is bytes:
138
+ assert pwd is None, "❌ You can either pass key or pwd, or none of them, but not both."
139
+ key_resolved = key # passsed explicitly
140
+ elif key is None:
141
+ key_resolved = Path.home().joinpath("dotfiles/creds/data/encrypted_files_key.bytes").read_bytes() # read from file
142
+ elif isinstance(key, (str, Path)):
143
+ key_resolved = Path(key).read_bytes() # passed a path to a file containing kwy
144
+ else:
145
+ raise TypeError(f"❌ Key must be either str, P, Path, bytes or None. Recieved: {type(key)}")
146
+ from cryptography.fernet import Fernet
147
+ return Fernet(key=key_resolved).decrypt(token)