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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (472) hide show
  1. machineconfig/__init__.py +0 -28
  2. machineconfig/cluster/remote/cloud_manager.py +1 -1
  3. machineconfig/cluster/remote/distribute.py +0 -1
  4. machineconfig/cluster/remote/file_manager.py +0 -2
  5. machineconfig/cluster/remote/script_execution.py +0 -1
  6. machineconfig/cluster/sessions_managers/{utils → helpers}/enhanced_command_runner.py +4 -6
  7. machineconfig/cluster/sessions_managers/utils/load_balancer.py +1 -1
  8. machineconfig/cluster/sessions_managers/utils/maker.py +69 -0
  9. machineconfig/cluster/sessions_managers/wt_local.py +114 -289
  10. machineconfig/cluster/sessions_managers/wt_local_manager.py +70 -210
  11. machineconfig/cluster/sessions_managers/wt_remote.py +51 -43
  12. machineconfig/cluster/sessions_managers/wt_remote_manager.py +52 -198
  13. machineconfig/cluster/sessions_managers/wt_utils/layout_generator.py +6 -19
  14. machineconfig/cluster/sessions_managers/wt_utils/manager_persistence.py +52 -0
  15. machineconfig/cluster/sessions_managers/wt_utils/monitoring_helpers.py +50 -0
  16. machineconfig/cluster/sessions_managers/wt_utils/status_reporter.py +4 -2
  17. machineconfig/cluster/sessions_managers/wt_utils/status_reporting.py +76 -0
  18. machineconfig/cluster/sessions_managers/wt_utils/wt_helpers.py +199 -0
  19. machineconfig/cluster/sessions_managers/zellij_local.py +81 -375
  20. machineconfig/cluster/sessions_managers/zellij_local_manager.py +25 -170
  21. machineconfig/cluster/sessions_managers/zellij_remote.py +40 -41
  22. machineconfig/cluster/sessions_managers/zellij_remote_manager.py +16 -12
  23. machineconfig/cluster/sessions_managers/zellij_utils/example_usage.py +4 -8
  24. machineconfig/cluster/sessions_managers/zellij_utils/layout_generator.py +5 -20
  25. machineconfig/cluster/sessions_managers/zellij_utils/process_monitor.py +3 -9
  26. machineconfig/cluster/sessions_managers/zellij_utils/status_reporter.py +3 -1
  27. machineconfig/cluster/sessions_managers/zellij_utils/zellij_local_helper.py +298 -0
  28. machineconfig/cluster/sessions_managers/zellij_utils/zellij_local_helper_restart.py +77 -0
  29. machineconfig/cluster/sessions_managers/zellij_utils/zellij_local_helper_with_panes.py +228 -0
  30. machineconfig/cluster/sessions_managers/zellij_utils/zellij_local_manager_helper.py +165 -0
  31. machineconfig/jobs/{python → installer}/check_installations.py +2 -3
  32. machineconfig/jobs/installer/custom/boxes.py +61 -0
  33. machineconfig/jobs/installer/custom/hx.py +76 -19
  34. machineconfig/jobs/installer/custom/yazi.py +119 -0
  35. machineconfig/jobs/installer/custom_dev/alacritty.py +4 -4
  36. machineconfig/jobs/installer/custom_dev/brave.py +5 -9
  37. machineconfig/jobs/installer/custom_dev/cloudflare_warp_cli.py +23 -0
  38. machineconfig/jobs/installer/custom_dev/code.py +4 -1
  39. machineconfig/jobs/installer/custom_dev/dubdb_adbc.py +30 -0
  40. machineconfig/jobs/installer/custom_dev/nerdfont.py +1 -1
  41. machineconfig/jobs/installer/custom_dev/nerfont_windows_helper.py +33 -28
  42. machineconfig/jobs/installer/custom_dev/sysabc.py +139 -0
  43. machineconfig/jobs/installer/custom_dev/wezterm.py +2 -19
  44. machineconfig/jobs/installer/custom_dev/winget.py +10 -14
  45. machineconfig/jobs/installer/installer_data.json +1487 -229
  46. machineconfig/jobs/installer/linux_scripts/brave.sh +4 -14
  47. machineconfig/jobs/installer/linux_scripts/{warp-cli.sh → cloudflare_warp_cli.sh} +5 -17
  48. machineconfig/jobs/installer/linux_scripts/docker.sh +5 -17
  49. machineconfig/jobs/installer/linux_scripts/docker_start.sh +6 -14
  50. machineconfig/jobs/installer/linux_scripts/edge.sh +3 -11
  51. machineconfig/jobs/{linux/msc → installer/linux_scripts}/lid.sh +2 -8
  52. machineconfig/jobs/installer/linux_scripts/nerdfont.sh +5 -17
  53. machineconfig/jobs/{linux/msc → installer/linux_scripts}/network.sh +2 -8
  54. machineconfig/jobs/installer/linux_scripts/q.sh +10 -6
  55. machineconfig/jobs/installer/linux_scripts/redis.sh +6 -17
  56. machineconfig/jobs/installer/linux_scripts/vscode.sh +5 -17
  57. machineconfig/jobs/installer/linux_scripts/wezterm.sh +4 -12
  58. machineconfig/jobs/installer/package_groups.py +106 -177
  59. machineconfig/jobs/installer/powershell_scripts/install_fonts.ps1 +129 -34
  60. machineconfig/logger.py +0 -1
  61. machineconfig/profile/backup.toml +49 -0
  62. machineconfig/profile/bash_shell_profiles.md +11 -0
  63. machineconfig/profile/create_helper.py +62 -0
  64. machineconfig/profile/create_links.py +288 -0
  65. machineconfig/profile/create_links_export.py +100 -0
  66. machineconfig/profile/create_shell_profile.py +147 -0
  67. machineconfig/profile/mapper.toml +263 -0
  68. machineconfig/scripts/__init__.py +0 -4
  69. machineconfig/scripts/linux/{share_cloud.sh → other/share_cloud.sh} +14 -25
  70. machineconfig/scripts/linux/wrap_mcfg +46 -0
  71. machineconfig/scripts/nu/wrap_mcfg.nu +69 -0
  72. machineconfig/scripts/python/agents.py +123 -117
  73. machineconfig/scripts/python/ai/initai.py +3 -28
  74. machineconfig/scripts/python/ai/scripts/command_runner.ps1 +33 -0
  75. machineconfig/scripts/python/ai/scripts/command_runner.sh +9 -0
  76. machineconfig/scripts/python/ai/scripts/lint_and_type_check.ps1 +17 -18
  77. machineconfig/scripts/python/ai/scripts/lint_and_type_check.sh +17 -18
  78. machineconfig/scripts/python/ai/solutions/_shared.py +9 -1
  79. machineconfig/scripts/python/ai/solutions/copilot/{chatmodes/Thinking-Beast-Mode.chatmode.md → agents/Thinking-Beast-Mode.agent.md} +0 -1
  80. machineconfig/scripts/python/ai/solutions/copilot/{chatmodes/Ultimate-Transparent-Thinking-Beast-Mode.chatmode.md → agents/Ultimate-Transparent-Thinking-Beast-Mode.agent.md} +0 -1
  81. machineconfig/scripts/python/ai/solutions/copilot/{chatmodes/deepResearch.chatmode.md → agents/deepResearch.agent.md} +2 -2
  82. machineconfig/scripts/python/ai/solutions/copilot/github_copilot.py +5 -5
  83. machineconfig/scripts/python/ai/solutions/copilot/instructions/python/dev.instructions.md +5 -1
  84. machineconfig/scripts/python/ai/solutions/copilot/instructions/python/watch_exec.prompt.md +20 -0
  85. machineconfig/scripts/python/ai/solutions/copilot/prompts/pyright_fix.md +16 -0
  86. machineconfig/scripts/python/ai/solutions/generic.py +28 -5
  87. machineconfig/scripts/python/ai/utils/generate_files.py +348 -0
  88. machineconfig/scripts/python/ai/utils/vscode_tasks.py +37 -0
  89. machineconfig/scripts/python/cloud.py +29 -0
  90. machineconfig/scripts/python/croshell.py +137 -113
  91. machineconfig/scripts/python/devops.py +61 -101
  92. machineconfig/scripts/python/devops_navigator.py +6 -0
  93. machineconfig/scripts/python/env_manager/__init__.py +1 -0
  94. machineconfig/scripts/python/env_manager/env_manager_tui.py +204 -0
  95. machineconfig/scripts/python/env_manager/path_manager_backend.py +47 -0
  96. machineconfig/scripts/python/env_manager/path_manager_tui.py +228 -0
  97. machineconfig/scripts/python/fire_jobs.py +110 -150
  98. machineconfig/scripts/python/ftpx.py +51 -24
  99. machineconfig/scripts/python/helpers/ast_search.py +74 -0
  100. machineconfig/scripts/python/helpers/qr_code.py +166 -0
  101. machineconfig/scripts/python/helpers/repo_rag.py +325 -0
  102. machineconfig/scripts/python/helpers/run_py_script.py +79 -0
  103. machineconfig/scripts/python/helpers/symantic_search.py +25 -0
  104. machineconfig/scripts/python/helpers/tmp_py_scripts/a.py +26 -0
  105. machineconfig/scripts/python/helpers_agents/agentic_frameworks/fire_crush.json +14 -0
  106. machineconfig/scripts/python/helpers_agents/agentic_frameworks/fire_crush.py +39 -0
  107. machineconfig/scripts/python/helpers_agents/agentic_frameworks/fire_cursor_agents.py +22 -0
  108. machineconfig/scripts/python/helpers_agents/agentic_frameworks/fire_gemini.py +55 -0
  109. machineconfig/scripts/python/helpers_agents/agentic_frameworks/fire_qwen.py +30 -0
  110. machineconfig/scripts/python/helpers_agents/fire_agents_help_launch.py +126 -0
  111. machineconfig/scripts/python/helpers_agents/fire_agents_helper_types.py +41 -0
  112. machineconfig/scripts/python/helpers_agents/templates/prompt.txt +10 -0
  113. machineconfig/scripts/python/helpers_agents/templates/template.ps1 +14 -0
  114. machineconfig/scripts/python/helpers_agents/templates/template.sh +32 -0
  115. machineconfig/scripts/python/{cloud_copy.py → helpers_cloud/cloud_copy.py} +30 -23
  116. machineconfig/scripts/python/{cloud_mount.py → helpers_cloud/cloud_mount.py} +29 -35
  117. machineconfig/scripts/python/{cloud_sync.py → helpers_cloud/cloud_sync.py} +12 -18
  118. machineconfig/scripts/python/{helpers → helpers_cloud}/helpers2.py +1 -1
  119. machineconfig/scripts/python/helpers_croshell/crosh.py +39 -0
  120. machineconfig/scripts/python/{start_slidev.py → helpers_croshell/start_slidev.py} +8 -9
  121. machineconfig/scripts/python/helpers_devops/cli_config.py +105 -0
  122. machineconfig/scripts/python/helpers_devops/cli_config_dotfile.py +89 -0
  123. machineconfig/scripts/python/helpers_devops/cli_data.py +25 -0
  124. machineconfig/scripts/python/helpers_devops/cli_nw.py +214 -0
  125. machineconfig/scripts/python/helpers_devops/cli_repos.py +215 -0
  126. machineconfig/scripts/python/helpers_devops/cli_self.py +172 -0
  127. machineconfig/scripts/python/helpers_devops/cli_share_file.py +137 -0
  128. machineconfig/scripts/python/helpers_devops/cli_share_server.py +142 -0
  129. machineconfig/scripts/python/{share_terminal.py → helpers_devops/cli_share_terminal.py} +45 -35
  130. machineconfig/scripts/python/helpers_devops/cli_utils.py +96 -0
  131. machineconfig/scripts/python/{devops_backup_retrieve.py → helpers_devops/devops_backup_retrieve.py} +7 -10
  132. machineconfig/scripts/python/helpers_devops/devops_status.py +499 -0
  133. machineconfig/scripts/python/{devops_update_repos.py → helpers_devops/devops_update_repos.py} +68 -49
  134. machineconfig/scripts/python/helpers_devops/themes/choose_pwsh_theme.ps1 +81 -0
  135. machineconfig/scripts/python/helpers_devops/themes/choose_starship_theme.bash +3 -0
  136. machineconfig/scripts/python/{choose_wezterm_theme.py → helpers_devops/themes/choose_wezterm_theme.py} +3 -3
  137. machineconfig/scripts/python/helpers_fire_command/__init__.py +0 -0
  138. machineconfig/scripts/python/helpers_fire_command/f.py +0 -0
  139. machineconfig/scripts/python/{helpers/helpers4.py → helpers_fire_command/file_wrangler.py} +56 -20
  140. machineconfig/scripts/python/{fire_jobs_args_helper.py → helpers_fire_command/fire_jobs_args_helper.py} +5 -1
  141. machineconfig/scripts/python/helpers_fire_command/fire_jobs_route_helper.py +121 -0
  142. machineconfig/scripts/python/helpers_fire_command/fire_jobs_streamlit_helper.py +0 -0
  143. machineconfig/scripts/python/helpers_msearch/__init__.py +5 -0
  144. machineconfig/scripts/{linux → python/helpers_msearch/scripts_linux}/fzfg +3 -3
  145. machineconfig/scripts/python/helpers_msearch/scripts_windows/fzfg.ps1 +59 -0
  146. machineconfig/scripts/python/helpers_navigator/__init__.py +20 -0
  147. machineconfig/scripts/python/helpers_navigator/command_builder.py +111 -0
  148. machineconfig/scripts/python/helpers_navigator/command_detail.py +44 -0
  149. machineconfig/scripts/python/helpers_navigator/command_tree.py +620 -0
  150. machineconfig/scripts/python/helpers_navigator/data_models.py +28 -0
  151. machineconfig/scripts/python/helpers_navigator/main_app.py +272 -0
  152. machineconfig/scripts/python/helpers_navigator/search_bar.py +15 -0
  153. machineconfig/scripts/python/helpers_network/__init__.py +0 -0
  154. machineconfig/scripts/python/helpers_network/address.py +132 -0
  155. machineconfig/scripts/python/{devops_add_identity.py → helpers_network/devops_add_identity.py} +0 -2
  156. machineconfig/scripts/python/helpers_network/devops_add_ssh_key.py +153 -0
  157. machineconfig/scripts/{linux → python/helpers_network}/mount_nfs +0 -1
  158. machineconfig/scripts/python/{mount_nfs.py → helpers_network/mount_nfs.py} +3 -3
  159. machineconfig/scripts/{linux → python/helpers_network}/mount_nw_drive +1 -2
  160. machineconfig/scripts/python/{mount_ssh.py → helpers_network/mount_ssh.py} +3 -3
  161. machineconfig/scripts/python/{onetimeshare.py → helpers_network/onetimeshare.py} +0 -1
  162. machineconfig/scripts/python/helpers_network/ssh_debug_linux.py +391 -0
  163. machineconfig/scripts/python/helpers_network/ssh_debug_windows.py +338 -0
  164. machineconfig/scripts/python/{wifi_conn.py → helpers_network/wifi_conn.py} +1 -53
  165. machineconfig/scripts/python/{wsl_windows_transfer.py → helpers_network/wsl_windows_transfer.py} +5 -4
  166. machineconfig/scripts/python/helpers_repos/action.py +209 -0
  167. machineconfig/scripts/python/helpers_repos/action_helper.py +150 -0
  168. machineconfig/scripts/python/{repos_helper_clone.py → helpers_repos/clone.py} +2 -3
  169. machineconfig/scripts/python/helpers_repos/cloud_repo_sync.py +218 -0
  170. machineconfig/scripts/python/{repos_helper.py → helpers_repos/entrypoint.py} +9 -17
  171. machineconfig/scripts/python/helpers_repos/grource.py +340 -0
  172. machineconfig/scripts/python/{repos_helper_record.py → helpers_repos/record.py} +4 -3
  173. machineconfig/scripts/python/helpers_repos/repo_analyzer_1.py +160 -0
  174. machineconfig/scripts/python/{count_lines.py → helpers_repos/repo_analyzer_2.py} +113 -192
  175. machineconfig/scripts/python/helpers_repos/sync.py +66 -0
  176. machineconfig/scripts/python/{repos_helper_update.py → helpers_repos/update.py} +3 -3
  177. machineconfig/scripts/python/helpers_sessions/__init__.py +0 -0
  178. machineconfig/scripts/python/helpers_sessions/sessions_multiprocess.py +65 -0
  179. machineconfig/scripts/python/helpers_utils/download.py +150 -0
  180. machineconfig/scripts/python/helpers_utils/path.py +185 -0
  181. machineconfig/scripts/python/interactive.py +64 -84
  182. machineconfig/scripts/python/mcfg_entry.py +58 -0
  183. machineconfig/scripts/python/msearch.py +71 -0
  184. machineconfig/scripts/python/sessions.py +119 -45
  185. machineconfig/scripts/python/terminal.py +133 -0
  186. machineconfig/scripts/python/utils.py +64 -0
  187. machineconfig/scripts/windows/mounts/Restore-ThunderbirdProfile.ps1 +92 -0
  188. machineconfig/scripts/windows/{mount_nfs.ps1 → mounts/mount_nfs.ps1} +1 -3
  189. machineconfig/scripts/windows/{mount_ssh.ps1 → mounts/mount_ssh.ps1} +1 -1
  190. machineconfig/scripts/windows/{share_smb.ps1 → mounts/share_smb.ps1} +0 -6
  191. machineconfig/scripts/windows/wrap_mcfg.ps1 +63 -0
  192. machineconfig/settings/broot/br.sh +0 -4
  193. machineconfig/settings/broot/conf.toml +1 -1
  194. machineconfig/settings/helix/config.toml +16 -0
  195. machineconfig/settings/helix/languages.toml +13 -4
  196. machineconfig/settings/helix/yazi-picker.sh +12 -0
  197. machineconfig/settings/lf/linux/exe/lfcd.sh +1 -0
  198. machineconfig/settings/lf/linux/exe/previewer.sh +9 -3
  199. machineconfig/settings/lf/linux/lfrc +10 -12
  200. machineconfig/settings/lf/windows/lfcd.ps1 +1 -1
  201. machineconfig/settings/lf/windows/lfrc +18 -38
  202. machineconfig/settings/lf/windows/mkfile.ps1 +1 -1
  203. machineconfig/settings/linters/.ruff.toml +1 -1
  204. machineconfig/settings/lvim/windows/archive/config_additional.lua +0 -6
  205. machineconfig/settings/marimo/marimo.toml +80 -0
  206. machineconfig/settings/marimo/snippets/globalize.py +34 -0
  207. machineconfig/settings/pistol/pistol.conf +1 -1
  208. machineconfig/settings/shells/bash/init.sh +82 -31
  209. machineconfig/settings/shells/ipy/profiles/default/startup/playext.py +1 -1
  210. machineconfig/settings/shells/nushell/config.nu +2 -35
  211. machineconfig/settings/shells/nushell/env.nu +45 -6
  212. machineconfig/settings/shells/nushell/init.nu +314 -0
  213. machineconfig/settings/shells/pwsh/init.ps1 +61 -43
  214. machineconfig/settings/shells/starship/starship.toml +16 -0
  215. machineconfig/settings/shells/wezterm/wezterm.lua +2 -0
  216. machineconfig/settings/shells/wt/settings.json +32 -17
  217. machineconfig/settings/shells/zsh/init.sh +89 -0
  218. machineconfig/settings/svim/linux/init.toml +0 -4
  219. machineconfig/settings/svim/windows/init.toml +0 -3
  220. machineconfig/settings/television/cable_unix/alias.toml +8 -0
  221. machineconfig/settings/television/cable_unix/aws-buckets.toml +14 -0
  222. machineconfig/settings/television/cable_unix/aws-instances.toml +13 -0
  223. machineconfig/settings/television/cable_unix/bash-history.toml +8 -0
  224. machineconfig/settings/television/cable_unix/channels.toml +19 -0
  225. machineconfig/settings/television/cable_unix/dirs.toml +13 -0
  226. machineconfig/settings/television/cable_unix/distrobox-list.toml +42 -0
  227. machineconfig/settings/television/cable_unix/docker-images.toml +13 -0
  228. machineconfig/settings/television/cable_unix/dotfiles.toml +11 -0
  229. machineconfig/settings/television/cable_unix/env.toml +17 -0
  230. machineconfig/settings/television/cable_unix/files.toml +11 -0
  231. machineconfig/settings/television/cable_unix/fish-history.toml +8 -0
  232. machineconfig/settings/television/cable_unix/git-branch.toml +11 -0
  233. machineconfig/settings/television/cable_unix/git-diff.toml +10 -0
  234. machineconfig/settings/television/cable_unix/git-log.toml +12 -0
  235. machineconfig/settings/television/cable_unix/git-reflog.toml +12 -0
  236. machineconfig/settings/television/cable_unix/git-repos.toml +16 -0
  237. machineconfig/settings/television/cable_unix/guix.toml +20 -0
  238. machineconfig/settings/television/cable_unix/just-recipes.toml +18 -0
  239. machineconfig/settings/television/cable_unix/k8s-deployments.toml +36 -0
  240. machineconfig/settings/television/cable_unix/k8s-pods.toml +50 -0
  241. machineconfig/settings/television/cable_unix/k8s-services.toml +36 -0
  242. machineconfig/settings/television/cable_unix/man-pages.toml +24 -0
  243. machineconfig/settings/television/cable_unix/nu-history.toml +7 -0
  244. machineconfig/settings/television/cable_unix/procs.toml +20 -0
  245. machineconfig/settings/television/cable_unix/text.toml +17 -0
  246. machineconfig/settings/television/cable_unix/tldr.toml +18 -0
  247. machineconfig/settings/television/cable_unix/zsh-history.toml +9 -0
  248. machineconfig/settings/television/cable_windows/alias.toml +7 -0
  249. machineconfig/settings/television/cable_windows/dirs.toml +13 -0
  250. machineconfig/settings/television/cable_windows/docker-images.toml +13 -0
  251. machineconfig/settings/television/cable_windows/dotfiles.toml +11 -0
  252. machineconfig/settings/television/cable_windows/env.toml +17 -0
  253. machineconfig/settings/television/cable_windows/files.toml +14 -0
  254. machineconfig/settings/television/cable_windows/git-branch.toml +11 -0
  255. machineconfig/settings/television/cable_windows/git-diff.toml +10 -0
  256. machineconfig/settings/television/cable_windows/git-log.toml +11 -0
  257. machineconfig/settings/television/cable_windows/git-reflog.toml +11 -0
  258. machineconfig/settings/television/cable_windows/git-repos.toml +15 -0
  259. machineconfig/settings/television/cable_windows/nu-history.toml +7 -0
  260. machineconfig/settings/television/cable_windows/pwsh-history.toml +6 -0
  261. machineconfig/settings/television/cable_windows/text.toml +17 -0
  262. machineconfig/settings/yazi/init.lua +61 -0
  263. machineconfig/settings/yazi/keymap_linux.toml +94 -0
  264. machineconfig/settings/yazi/keymap_windows.toml +78 -0
  265. machineconfig/settings/yazi/shell/yazi_cd.ps1 +33 -0
  266. machineconfig/settings/yazi/shell/yazi_cd.sh +8 -0
  267. machineconfig/settings/yazi/theme.toml +4 -0
  268. machineconfig/settings/yazi/yazi_linux.toml +84 -0
  269. machineconfig/settings/yazi/yazi_windows.toml +58 -0
  270. machineconfig/setup_linux/__init__.py +11 -0
  271. machineconfig/setup_linux/apps_desktop.sh +89 -0
  272. machineconfig/setup_linux/apps_gui.sh +64 -0
  273. machineconfig/setup_linux/ssh/openssh_all.sh +25 -0
  274. machineconfig/setup_linux/ssh/openssh_wsl.sh +38 -0
  275. machineconfig/setup_linux/uv.sh +15 -0
  276. machineconfig/setup_linux/web_shortcuts/interactive.sh +26 -6
  277. machineconfig/setup_linux/web_shortcuts/live_from_github.sh +31 -0
  278. machineconfig/setup_mac/__init__.py +16 -0
  279. machineconfig/setup_mac/apps_gui.sh +248 -0
  280. machineconfig/setup_mac/ssh/openssh_setup.sh +114 -0
  281. machineconfig/setup_mac/uv.sh +36 -0
  282. machineconfig/setup_windows/__init__.py +11 -0
  283. machineconfig/setup_windows/others/power_options.ps1 +7 -0
  284. machineconfig/setup_windows/ssh/add-sshkey.ps1 +29 -0
  285. machineconfig/setup_windows/ssh/add_identity.ps1 +11 -0
  286. machineconfig/setup_windows/ssh/openssh-server.ps1 +37 -0
  287. machineconfig/setup_windows/uv.ps1 +17 -0
  288. machineconfig/setup_windows/web_shortcuts/interactive.ps1 +27 -10
  289. machineconfig/setup_windows/web_shortcuts/live_from_github.ps1 +30 -0
  290. machineconfig/setup_windows/web_shortcuts/quick_init.ps1 +17 -0
  291. machineconfig/utils/accessories.py +7 -5
  292. machineconfig/utils/cloud/onedrive/README.md +139 -0
  293. machineconfig/utils/code.py +155 -105
  294. machineconfig/utils/files/art/fat_croco.txt +10 -0
  295. machineconfig/utils/files/art/halfwit_croco.txt +9 -0
  296. machineconfig/utils/files/art/happy_croco.txt +22 -0
  297. machineconfig/utils/files/art/water_croco.txt +11 -0
  298. machineconfig/utils/files/ascii_art.py +1 -1
  299. machineconfig/utils/files/dbms.py +257 -0
  300. machineconfig/utils/files/headers.py +11 -14
  301. machineconfig/utils/files/ouch/__init__.py +0 -0
  302. machineconfig/utils/files/ouch/decompress.py +45 -0
  303. machineconfig/utils/files/read.py +10 -18
  304. machineconfig/utils/installer_utils/github_release_bulk.py +156 -119
  305. machineconfig/utils/installer_utils/install_from_url.py +183 -0
  306. machineconfig/utils/installer_utils/installer_class.py +64 -181
  307. machineconfig/utils/installer_utils/installer_cli.py +175 -0
  308. machineconfig/utils/installer_utils/installer_helper.py +129 -0
  309. machineconfig/utils/installer_utils/{installer_abc.py → installer_locator_utils.py} +66 -97
  310. machineconfig/utils/{installer.py → installer_utils/installer_runner.py} +49 -82
  311. machineconfig/utils/io.py +77 -23
  312. machineconfig/utils/links.py +254 -162
  313. machineconfig/utils/meta.py +256 -0
  314. machineconfig/utils/notifications.py +1 -1
  315. machineconfig/utils/options.py +46 -18
  316. machineconfig/utils/options_tv.py +119 -0
  317. machineconfig/utils/path_extended.py +48 -101
  318. machineconfig/utils/path_helper.py +76 -23
  319. machineconfig/utils/procs.py +50 -70
  320. machineconfig/utils/scheduler.py +88 -124
  321. machineconfig/utils/scheduling.py +0 -3
  322. machineconfig/utils/schemas/fire_agents/fire_agents_input.py +1 -1
  323. machineconfig/utils/schemas/layouts/layout_types.py +1 -1
  324. machineconfig/utils/source_of_truth.py +3 -6
  325. machineconfig/utils/ssh.py +263 -274
  326. machineconfig/utils/ssh_utils/abc.py +5 -0
  327. machineconfig/utils/ssh_utils/copy_from_here.py +111 -0
  328. machineconfig/utils/ssh_utils/copy_to_here.py +302 -0
  329. machineconfig/utils/ssh_utils/utils.py +142 -0
  330. machineconfig/utils/ssh_utils/wsl.py +210 -0
  331. machineconfig/utils/terminal.py +3 -113
  332. machineconfig/utils/tst.py +20 -0
  333. machineconfig/utils/upgrade_packages.py +114 -28
  334. machineconfig/utils/ve.py +12 -4
  335. machineconfig-7.98.dist-info/METADATA +132 -0
  336. machineconfig-7.98.dist-info/RECORD +504 -0
  337. machineconfig-7.98.dist-info/entry_points.txt +13 -0
  338. machineconfig/cluster/sessions_managers/ffile.py +0 -4
  339. machineconfig/jobs/installer/linux_scripts/pgsql.sh +0 -49
  340. machineconfig/jobs/installer/linux_scripts/timescaledb.sh +0 -85
  341. machineconfig/jobs/linux/msc/cli_agents.sh +0 -16
  342. machineconfig/jobs/python/python_ve_symlink.py +0 -37
  343. machineconfig/jobs/python/vscode/api.py +0 -57
  344. machineconfig/jobs/python/vscode/sync_code.py +0 -73
  345. machineconfig/jobs/windows/archive/archive_pygraphviz.ps1 +0 -14
  346. machineconfig/jobs/windows/start_terminal.ps1 +0 -6
  347. machineconfig/jobs/windows/startup_file.cmd +0 -2
  348. machineconfig/profile/create.py +0 -303
  349. machineconfig/profile/shell.py +0 -176
  350. machineconfig/scripts/cloud/init.sh +0 -119
  351. machineconfig/scripts/linux/agents +0 -2
  352. machineconfig/scripts/linux/choose_wezterm_theme +0 -3
  353. machineconfig/scripts/linux/cloud_copy +0 -2
  354. machineconfig/scripts/linux/cloud_mount +0 -2
  355. machineconfig/scripts/linux/cloud_repo_sync +0 -2
  356. machineconfig/scripts/linux/cloud_sync +0 -2
  357. machineconfig/scripts/linux/croshell +0 -3
  358. machineconfig/scripts/linux/devops +0 -2
  359. machineconfig/scripts/linux/fire +0 -2
  360. machineconfig/scripts/linux/ftpx +0 -2
  361. machineconfig/scripts/linux/fzf2g +0 -21
  362. machineconfig/scripts/linux/fzfag +0 -17
  363. machineconfig/scripts/linux/fzffg +0 -25
  364. machineconfig/scripts/linux/fzfrga +0 -21
  365. machineconfig/scripts/linux/gh_models +0 -2
  366. machineconfig/scripts/linux/initai +0 -2
  367. machineconfig/scripts/linux/kill_process +0 -2
  368. machineconfig/scripts/linux/scheduler +0 -2
  369. machineconfig/scripts/linux/sessions +0 -2
  370. machineconfig/scripts/linux/share_smb +0 -1
  371. machineconfig/scripts/linux/skrg +0 -4
  372. machineconfig/scripts/linux/start_slidev +0 -2
  373. machineconfig/scripts/linux/start_terminals +0 -3
  374. machineconfig/scripts/linux/warp-cli.sh +0 -122
  375. machineconfig/scripts/linux/wifi_conn +0 -2
  376. machineconfig/scripts/linux/z_ls +0 -104
  377. machineconfig/scripts/python/ai/generate_files.py +0 -83
  378. machineconfig/scripts/python/ai/solutions/copilot/prompts/allLintersAndTypeCheckers.prompt.md +0 -5
  379. machineconfig/scripts/python/cloud_repo_sync.py +0 -190
  380. machineconfig/scripts/python/count_lines_frontend.py +0 -16
  381. machineconfig/scripts/python/devops_add_ssh_key.py +0 -120
  382. machineconfig/scripts/python/dotfile.py +0 -78
  383. machineconfig/scripts/python/fire_agents_help_launch.py +0 -120
  384. machineconfig/scripts/python/fire_agents_helper_types.py +0 -12
  385. machineconfig/scripts/python/fire_jobs_route_helper.py +0 -65
  386. machineconfig/scripts/python/get_zellij_cmd.py +0 -15
  387. machineconfig/scripts/python/gh_models.py +0 -104
  388. machineconfig/scripts/python/helpers/repo_sync_helpers.py +0 -116
  389. machineconfig/scripts/python/repos.py +0 -132
  390. machineconfig/scripts/python/repos_helper_action.py +0 -378
  391. machineconfig/scripts/python/snapshot.py +0 -25
  392. machineconfig/scripts/python/start_terminals.py +0 -121
  393. machineconfig/scripts/python/t4.py +0 -17
  394. machineconfig/scripts/windows/agents.ps1 +0 -1
  395. machineconfig/scripts/windows/choose_wezterm_theme.ps1 +0 -1
  396. machineconfig/scripts/windows/cloud_copy.ps1 +0 -1
  397. machineconfig/scripts/windows/cloud_mount.ps1 +0 -1
  398. machineconfig/scripts/windows/cloud_repo_sync.ps1 +0 -1
  399. machineconfig/scripts/windows/cloud_sync.ps1 +0 -1
  400. machineconfig/scripts/windows/croshell.ps1 +0 -1
  401. machineconfig/scripts/windows/devops.ps1 +0 -1
  402. machineconfig/scripts/windows/dotfile.ps1 +0 -1
  403. machineconfig/scripts/windows/fire.ps1 +0 -1
  404. machineconfig/scripts/windows/ftpx.ps1 +0 -1
  405. machineconfig/scripts/windows/fzfb.ps1 +0 -3
  406. machineconfig/scripts/windows/fzfg.ps1 +0 -2
  407. machineconfig/scripts/windows/fzfrga.bat +0 -20
  408. machineconfig/scripts/windows/gpt.ps1 +0 -1
  409. machineconfig/scripts/windows/grep.ps1 +0 -2
  410. machineconfig/scripts/windows/initai.ps1 +0 -1
  411. machineconfig/scripts/windows/kill_process.ps1 +0 -1
  412. machineconfig/scripts/windows/nano.ps1 +0 -3
  413. machineconfig/scripts/windows/pomodoro.ps1 +0 -1
  414. machineconfig/scripts/windows/reload_path.ps1 +0 -3
  415. machineconfig/scripts/windows/scheduler.ps1 +0 -1
  416. machineconfig/scripts/windows/sessions.ps1 +0 -1
  417. machineconfig/scripts/windows/snapshot.ps1 +0 -1
  418. machineconfig/scripts/windows/start_slidev.ps1 +0 -1
  419. machineconfig/scripts/windows/start_terminals.ps1 +0 -1
  420. machineconfig/scripts/windows/wifi_conn.ps1 +0 -2
  421. machineconfig/scripts/windows/wsl_rdp_windows_port_forwarding.ps1 +0 -46
  422. machineconfig/scripts/windows/wsl_ssh_windows_port_forwarding.ps1 +0 -76
  423. machineconfig/settings/lf/linux/exe/fzf_nano.sh +0 -16
  424. machineconfig/settings/lf/windows/fzf_edit.ps1 +0 -6
  425. machineconfig/settings/lf/windows/tst.ps1 +0 -1
  426. machineconfig/settings/yazi/yazi.toml +0 -4
  427. machineconfig/setup_linux/nix/cli_installation.sh +0 -157
  428. machineconfig/setup_linux/others/openssh-server_add_pub_key.sh +0 -57
  429. machineconfig/setup_linux/web_shortcuts/croshell.sh +0 -11
  430. machineconfig/setup_linux/web_shortcuts/ssh.sh +0 -52
  431. machineconfig/setup_windows/web_shortcuts/all.ps1 +0 -18
  432. machineconfig/setup_windows/web_shortcuts/ascii_art.ps1 +0 -36
  433. machineconfig/setup_windows/web_shortcuts/croshell.ps1 +0 -16
  434. machineconfig/setup_windows/web_shortcuts/ssh.ps1 +0 -11
  435. machineconfig/utils/ai/generate_file_checklist.py +0 -68
  436. machineconfig/utils/installer_utils/installer.py +0 -189
  437. machineconfig-5.15.dist-info/METADATA +0 -188
  438. machineconfig-5.15.dist-info/RECORD +0 -415
  439. machineconfig-5.15.dist-info/entry_points.txt +0 -18
  440. machineconfig/cluster/sessions_managers/{utils → helpers}/load_balancer_helper.py +0 -0
  441. machineconfig/scripts/linux/{share_nfs → other/share_nfs} +0 -0
  442. machineconfig/scripts/linux/{start_docker → other/start_docker} +0 -0
  443. machineconfig/scripts/linux/{switch_ip → other/switch_ip} +0 -0
  444. machineconfig/{jobs/python → scripts/python/ai/utils}/__init__.py +0 -0
  445. machineconfig/scripts/python/{helpers → helpers_agents}/__init__.py +0 -0
  446. machineconfig/{jobs/windows/msc/cli_agents.bat → scripts/python/helpers_agents/agentic_frameworks/__init__.py} +0 -0
  447. machineconfig/scripts/python/{fire_agents_help_search.py → helpers_agents/fire_agents_help_search.py} +0 -0
  448. machineconfig/scripts/python/{fire_agents_load_balancer.py → helpers_agents/fire_agents_load_balancer.py} +0 -0
  449. machineconfig/{jobs/windows/msc/cli_agents.ps1 → scripts/python/helpers_cloud/__init__.py} +0 -0
  450. machineconfig/scripts/python/{helpers → helpers_cloud}/cloud_helpers.py +1 -1
  451. /machineconfig/scripts/python/{helpers → helpers_cloud}/helpers5.py +0 -0
  452. /machineconfig/scripts/python/{fire_jobs_streamlit_helper.py → helpers_croshell/__init__.py} +0 -0
  453. /machineconfig/scripts/python/{pomodoro.py → helpers_croshell/pomodoro.py} +0 -0
  454. /machineconfig/scripts/python/{scheduler.py → helpers_croshell/scheduler.py} +0 -0
  455. /machineconfig/scripts/python/{viewer.py → helpers_croshell/viewer.py} +0 -0
  456. /machineconfig/scripts/python/{viewer_template.py → helpers_croshell/viewer_template.py} +0 -0
  457. /machineconfig/scripts/{windows/share_nfs.ps1 → python/helpers_devops/__init__.py} +0 -0
  458. /machineconfig/{settings/shells/pwsh/profile.ps1 → scripts/python/helpers_devops/themes/__init__.py} +0 -0
  459. /machineconfig/{settings/yazi/keymap.toml → scripts/python/helpers_devops/themes/choose_starship_theme.ps1} +0 -0
  460. /machineconfig/scripts/python/{cloud_manager.py → helpers_fire_command/cloud_manager.py} +0 -0
  461. /machineconfig/scripts/{linux → python/helpers_network}/mount_drive +0 -0
  462. /machineconfig/scripts/python/{mount_nw_drive.py → helpers_network/mount_nw_drive.py} +0 -0
  463. /machineconfig/scripts/{linux → python/helpers_network}/mount_smb +0 -0
  464. /machineconfig/scripts/windows/{mount_nw.ps1 → mounts/mount_nw.ps1} +0 -0
  465. /machineconfig/scripts/windows/{mount_smb.ps1 → mounts/mount_smb.ps1} +0 -0
  466. /machineconfig/scripts/windows/{share_cloud.cmd → mounts/share_cloud.cmd} +0 -0
  467. /machineconfig/scripts/windows/{unlock_bitlocker.ps1 → mounts/unlock_bitlocker.ps1} +0 -0
  468. /machineconfig/setup_linux/{web_shortcuts → others}/android.sh +0 -0
  469. /machineconfig/{jobs/windows/archive → setup_windows/ssh}/openssh-server_add_key.ps1 +0 -0
  470. /machineconfig/{jobs/windows/archive → setup_windows/ssh}/openssh-server_copy-ssh-id.ps1 +0 -0
  471. {machineconfig-5.15.dist-info → machineconfig-7.98.dist-info}/WHEEL +0 -0
  472. {machineconfig-5.15.dist-info → machineconfig-7.98.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,96 @@
1
+
2
+
3
+ import typer
4
+ from typing import Annotated, Optional
5
+
6
+
7
+ def merge_pdfs(
8
+ pdfs: Annotated[list[str], typer.Argument(..., help="Paths to the PDF files to merge.")],
9
+ output: Annotated[Optional[str], typer.Option("--output", "-o", help="Output merged PDF file path.")] = None,
10
+ compress: Annotated[bool, typer.Option("--compress", "-c", help="Compress the output PDF.")] = False,
11
+ ) -> None:
12
+ def merge_pdfs_internal(pdfs: list[str], output: str | None, compress: bool) -> None:
13
+ from pypdf import PdfReader, PdfWriter
14
+ writer = PdfWriter()
15
+ for pdf_path in pdfs:
16
+ reader = PdfReader(pdf_path)
17
+ for page in reader.pages:
18
+ writer.add_page(page)
19
+ output_path = output if output else "merged.pdf"
20
+ if compress:
21
+ try:
22
+ for p in writer.pages:
23
+ try:
24
+ # PageObject.compress_content_streams exists in pypdf
25
+ p.compress_content_streams()
26
+ except Exception:
27
+ # best-effort: ignore per-page compression failures
28
+ continue
29
+ except Exception:
30
+ pass
31
+ try:
32
+ writer.compress_identical_objects()
33
+ except Exception:
34
+ # non-fatal if this fails
35
+ pass
36
+ writer.write(output_path)
37
+ print(f"✅ Merged PDF saved to: {output_path}")
38
+ from machineconfig.utils.meta import lambda_to_python_script
39
+ code = lambda_to_python_script(lambda : merge_pdfs_internal(pdfs=pdfs, output=output, compress=compress),
40
+ in_global=True, import_module=False)
41
+ from machineconfig.utils.code import run_shell_script, get_uv_command_executing_python_script
42
+ uv_command, _py_file = get_uv_command_executing_python_script(python_script=code, uv_with=["pypdf"], uv_project_dir=None)
43
+ run_shell_script(uv_command)
44
+
45
+
46
+ def compress_pdf(
47
+ pdf_input: Annotated[str, typer.Argument(..., help="Path to the input PDF file to compress.")],
48
+ output: Annotated[Optional[str], typer.Option("--output", "-o", help="Output compressed PDF file path.")] = None,
49
+ quality: Annotated[int, typer.Option("--quality", "-q", help="JPEG quality for image compression (0-100, 0=no change, 100=best).")] = 85,
50
+ image_dpi: Annotated[int, typer.Option("--image-dpi", "-d", help="Target DPI for image resampling. If set, images above this DPI will be downsampled.")] = 0,
51
+ # remove_images: Annotated[bool, typer.Option("--remove-images", "-r", help="Remove all images from the PDF.")] = False,
52
+ compress_streams: Annotated[bool, typer.Option("--compress-streams", "-c", help="Compress uncompressed streams.")] = True,
53
+ use_objstms: Annotated[bool, typer.Option("--object-streams", "-s", help="Use object streams for additional compression.")] = True,
54
+ ) -> None:
55
+ def compress_pdf_internal(pdf_input: str, output: str | None, quality: int, image_dpi: int, compress_streams: bool, use_objstms: bool) -> None:
56
+ import pymupdf
57
+ from pathlib import Path
58
+ output_path = output if output else pdf_input.replace(".pdf", "_compressed.pdf")
59
+ doc = pymupdf.open(pdf_input)
60
+ try:
61
+ # if remove_images:
62
+ # for page in doc:
63
+ # page.remove_images()
64
+ if quality > 0 or image_dpi > 0:
65
+ doc.rewrite_images(
66
+ dpi_threshold=image_dpi if image_dpi > 0 else None,
67
+ dpi_target=max(72, image_dpi - 10) if image_dpi > 72 else 72,
68
+ quality=quality,
69
+ lossy=True,
70
+ lossless=True,
71
+ )
72
+ doc.save(
73
+ output_path,
74
+ deflate=compress_streams,
75
+ garbage=3,
76
+ use_objstms=1 if use_objstms else 0,
77
+ )
78
+ input_size = Path(pdf_input).stat().st_size
79
+ output_size = Path(output_path).stat().st_size
80
+ ratio = (1 - output_size / input_size) * 100
81
+ print(f"✅ Compressed PDF saved to: {output_path}")
82
+ print(f" Original: {input_size / 1024 / 1024:.2f} MB")
83
+ print(f" Compressed: {output_size / 1024 / 1024:.2f} MB")
84
+ print(f" Reduction: {ratio:.1f}%")
85
+ finally:
86
+ doc.close()
87
+ from machineconfig.utils.meta import lambda_to_python_script
88
+ code = lambda_to_python_script(
89
+ lambda: compress_pdf_internal(pdf_input=pdf_input, output=output, quality=quality, image_dpi=image_dpi, compress_streams=compress_streams, use_objstms=use_objstms),
90
+ in_global=True,
91
+ import_module=False,
92
+ )
93
+ from machineconfig.utils.code import run_shell_script, get_uv_command_executing_python_script
94
+ uv_command, _py_file = get_uv_command_executing_python_script(python_script=code, uv_with=["pymupdf"], uv_project_dir=None)
95
+ run_shell_script(uv_command)
96
+
@@ -2,33 +2,30 @@
2
2
 
3
3
  # import subprocess
4
4
  from machineconfig.utils.io import read_ini
5
- from machineconfig.utils.path_extended import PathExtended
6
5
  from machineconfig.utils.source_of_truth import LIBRARY_ROOT, DEFAULTS_PATH
7
6
  from machineconfig.utils.code import print_code
8
7
  from machineconfig.utils.options import choose_cloud_interactively, choose_from_options
9
- from machineconfig.scripts.python.helpers.helpers2 import ES
8
+ from machineconfig.scripts.python.helpers_cloud.helpers2 import ES
10
9
  from platform import system
11
10
  from typing import Any, Literal, Optional
12
11
  from rich.console import Console
13
12
  from rich.panel import Panel
13
+ from pathlib import Path
14
14
  import tomllib
15
15
 
16
16
 
17
17
  OPTIONS = Literal["BACKUP", "RETRIEVE"]
18
18
 
19
19
 
20
- def main_backup_retrieve(direction: OPTIONS, which: Optional[str] = None) -> None:
20
+ def main_backup_retrieve(direction: OPTIONS, which: Optional[str], cloud: Optional[str]) -> None:
21
21
  console = Console()
22
-
23
22
  try:
24
- cloud: str = read_ini(DEFAULTS_PATH)["general"]["rclone_config_name"]
23
+ cloud = read_ini(DEFAULTS_PATH)["general"]["rclone_config_name"]
25
24
  console.print(Panel(f"⚠️ DEFAULT CLOUD CONFIGURATION\n🌥️ Using default cloud: {cloud}", title="[bold blue]Cloud Configuration[/bold blue]", border_style="blue"))
26
25
  except (FileNotFoundError, KeyError, IndexError):
27
26
  console.print(Panel("🔍 DEFAULT CLOUD NOT FOUND\n🔄 Please select a cloud configuration from the options below", title="[bold red]Error: Cloud Not Found[/bold red]", border_style="red"))
28
27
  cloud = choose_cloud_interactively()
29
-
30
28
  bu_file: dict[str, Any] = tomllib.loads(LIBRARY_ROOT.joinpath("profile/backup.toml").read_text(encoding="utf-8"))
31
-
32
29
  console.print(Panel(f"🧰 LOADING BACKUP CONFIGURATION\n📄 File: {LIBRARY_ROOT.joinpath('profile/backup.toml')}", title="[bold blue]Backup Configuration[/bold blue]", border_style="blue"))
33
30
 
34
31
  if system() == "Linux":
@@ -59,13 +56,13 @@ def main_backup_retrieve(direction: OPTIONS, which: Optional[str] = None) -> Non
59
56
  flags += "e" if item["encrypt"] == "True" else ""
60
57
  flags += "r" if item["rel2home"] == "True" else ""
61
58
  flags += "o" if system().lower() in item_name else ""
62
- console.print(Panel(f"📦 PROCESSING: {item_name}\n📂 Path: {PathExtended(item['path']).as_posix()}\n🏳️ Flags: {flags or 'None'}", title=f"[bold blue]Processing Item: {item_name}[/bold blue]", border_style="blue"))
59
+ console.print(Panel(f"📦 PROCESSING: {item_name}\n📂 Path: {Path(item['path']).as_posix()}\n🏳️ Flags: {flags or 'None'}", title=f"[bold blue]Processing Item: {item_name}[/bold blue]", border_style="blue"))
63
60
  if flags:
64
61
  flags = "-" + flags
65
62
  if direction == "BACKUP":
66
- program += f"""\ncloud_copy "{PathExtended(item["path"]).as_posix()}" $cloud {flags}\n"""
63
+ program += f"""\ncloud_copy "{Path(item["path"]).as_posix()}" $cloud {flags}\n"""
67
64
  elif direction == "RETRIEVE":
68
- program += f"""\ncloud_copy $cloud "{PathExtended(item["path"]).as_posix()}" {flags}\n"""
65
+ program += f"""\ncloud_copy $cloud "{Path(item["path"]).as_posix()}" {flags}\n"""
69
66
  else:
70
67
  console.print(Panel('❌ ERROR: INVALID DIRECTION\n⚠️ Direction must be either "BACKUP" or "RETRIEVE"', title="[bold red]Error: Invalid Direction[/bold red]", border_style="red"))
71
68
  raise RuntimeError(f"Unknown direction: {direction}")
@@ -0,0 +1,499 @@
1
+ """Machine Status Display - Comprehensive system and configuration overview"""
2
+
3
+ import platform
4
+ import shutil
5
+ from pathlib import Path
6
+ from typing import Any
7
+
8
+ from rich.console import Console
9
+ from rich.panel import Panel
10
+ from rich.table import Table
11
+ from rich.text import Text
12
+
13
+ from machineconfig.utils.path_extended import PathExtended
14
+ from machineconfig.utils.source_of_truth import CONFIG_ROOT, DEFAULTS_PATH, LIBRARY_ROOT
15
+
16
+
17
+ console = Console()
18
+
19
+
20
+
21
+ def _check_shell_profile_status() -> dict[str, Any]:
22
+ """Check shell profile configuration status."""
23
+ from machineconfig.profile.create_shell_profile import get_shell_profile_path
24
+
25
+ try:
26
+ profile_path = get_shell_profile_path()
27
+ if not profile_path.exists():
28
+ profile_path.parent.mkdir(parents=True, exist_ok=True)
29
+ profile_path.touch()
30
+ profile_content = profile_path.read_text(encoding="utf-8")
31
+ system_name = platform.system()
32
+ if system_name == "Windows":
33
+ init_script = PathExtended(CONFIG_ROOT).joinpath("settings/shells/pwsh/init.ps1")
34
+ init_script_copy = PathExtended(CONFIG_ROOT).joinpath("profile/init.ps1").collapseuser()
35
+ source_reference = f". {str(init_script.collapseuser()).replace('~', '$HOME')}"
36
+ source_copy = f". {str(init_script_copy).replace('~', '$HOME')}"
37
+ else:
38
+ init_script = PathExtended(CONFIG_ROOT).joinpath("settings/shells/bash/init.sh")
39
+ init_script_copy = PathExtended(CONFIG_ROOT).joinpath("profile/init.sh").collapseuser()
40
+ source_reference = f"source {str(init_script.collapseuser()).replace('~', '$HOME')}"
41
+ source_copy = f"source {str(init_script_copy).replace('~', '$HOME')}"
42
+
43
+ configured = source_reference in profile_content or source_copy in profile_content
44
+ method = "reference" if source_reference in profile_content else ("copy" if source_copy in profile_content else "none")
45
+
46
+ return {
47
+ "profile_path": str(profile_path),
48
+ "exists": True,
49
+ "configured": configured,
50
+ "method": method,
51
+ "init_script_exists": init_script.exists(),
52
+ "init_script_copy_exists": init_script_copy.exists(),
53
+ }
54
+ except Exception as ex:
55
+ return {
56
+ "profile_path": "Error",
57
+ "exists": False,
58
+ "configured": False,
59
+ "method": "error",
60
+ "error": str(ex),
61
+ "init_script_exists": False,
62
+ "init_script_copy_exists": False,
63
+ }
64
+
65
+
66
+ def _check_repos_status() -> dict[str, Any]:
67
+ """Check configured repositories status."""
68
+ from machineconfig.utils.io import read_ini
69
+
70
+ try:
71
+ repos_str = read_ini(DEFAULTS_PATH)["general"]["repos"]
72
+ repo_paths = [Path(p.strip()).expanduser() for p in repos_str.split(",") if p.strip()]
73
+
74
+ repos_info = []
75
+ for repo_path in repo_paths:
76
+ if not repo_path.exists():
77
+ repos_info.append({"path": str(repo_path), "name": repo_path.name, "exists": False, "is_repo": False})
78
+ continue
79
+
80
+ try:
81
+ import git
82
+
83
+ repo = git.Repo(str(repo_path))
84
+ repos_info.append(
85
+ {
86
+ "path": str(repo_path),
87
+ "name": repo_path.name,
88
+ "exists": True,
89
+ "is_repo": True,
90
+ "clean": not repo.is_dirty(untracked_files=True),
91
+ "branch": repo.active_branch.name if not repo.head.is_detached else "DETACHED",
92
+ }
93
+ )
94
+ except Exception:
95
+ repos_info.append({"path": str(repo_path), "name": repo_path.name, "exists": True, "is_repo": False})
96
+
97
+ return {"configured": True, "count": len(repos_info), "repos": repos_info}
98
+ except (FileNotFoundError, KeyError, IndexError):
99
+ return {"configured": False, "count": 0, "repos": []}
100
+
101
+
102
+ def _check_ssh_status() -> dict[str, Any]:
103
+ """Check SSH configuration status."""
104
+ ssh_dir = PathExtended.home().joinpath(".ssh")
105
+ if not ssh_dir.exists():
106
+ return {"ssh_dir_exists": False, "keys": [], "config_exists": False, "authorized_keys_exists": False, "known_hosts_exists": False}
107
+
108
+ keys = []
109
+ for pub_key in ssh_dir.glob("*.pub"):
110
+ private_key = pub_key.with_suffix("")
111
+ keys.append(
112
+ {
113
+ "name": pub_key.stem,
114
+ "public_exists": True,
115
+ "private_exists": private_key.exists(),
116
+ "public_path": str(pub_key),
117
+ "private_path": str(private_key),
118
+ }
119
+ )
120
+
121
+ config_file = ssh_dir.joinpath("config")
122
+ authorized_keys = ssh_dir.joinpath("authorized_keys")
123
+ known_hosts = ssh_dir.joinpath("known_hosts")
124
+
125
+ return {
126
+ "ssh_dir_exists": True,
127
+ "keys": keys,
128
+ "config_exists": config_file.exists(),
129
+ "authorized_keys_exists": authorized_keys.exists(),
130
+ "known_hosts_exists": known_hosts.exists(),
131
+ "ssh_dir_path": str(ssh_dir),
132
+ }
133
+
134
+
135
+ def _check_config_files_status() -> dict[str, Any]:
136
+ """Check public and private configuration files status."""
137
+ from machineconfig.profile.create_links import read_mapper
138
+
139
+ try:
140
+ mapper = read_mapper()
141
+ public_configs = list(mapper.get("public", {}).keys())
142
+ private_configs = list(mapper.get("private", {}).keys())
143
+
144
+ public_count = len(public_configs)
145
+ private_count = len(private_configs)
146
+
147
+ public_linked = 0
148
+ for config_name in public_configs:
149
+ for config_item in mapper["public"][config_name]:
150
+ target_path = PathExtended(config_item["config_file_default_path"]).expanduser()
151
+ if target_path.exists():
152
+ public_linked += 1
153
+ break
154
+
155
+ private_linked = 0
156
+ for config_name in private_configs:
157
+ for config_item in mapper["private"][config_name]:
158
+ target_path = PathExtended(config_item["config_file_default_path"]).expanduser()
159
+ if target_path.exists():
160
+ private_linked += 1
161
+ break
162
+
163
+ return {
164
+ "public_count": public_count,
165
+ "public_linked": public_linked,
166
+ "private_count": private_count,
167
+ "private_linked": private_linked,
168
+ "public_configs": public_configs,
169
+ "private_configs": private_configs,
170
+ }
171
+ except Exception as ex:
172
+ return {
173
+ "public_count": 0,
174
+ "public_linked": 0,
175
+ "private_count": 0,
176
+ "private_linked": 0,
177
+ "error": str(ex),
178
+ "public_configs": [],
179
+ "private_configs": [],
180
+ }
181
+
182
+
183
+ def _check_important_tools() -> dict[str, dict[str, bool]]:
184
+ """Check if important CLI tools are installed, organized by groups."""
185
+ from machineconfig.jobs.installer.package_groups import PACKAGE_GROUP2NAMES
186
+
187
+ group_status = {}
188
+ for group_name, tools in PACKAGE_GROUP2NAMES.items():
189
+ tool_status = {}
190
+ for tool in tools:
191
+ tool_status[tool] = shutil.which(tool) is not None
192
+ group_status[group_name] = tool_status
193
+
194
+ return group_status
195
+
196
+
197
+ def _check_backup_config() -> dict[str, Any]:
198
+ """Check backup configuration status."""
199
+ from machineconfig.utils.io import read_ini
200
+ import tomllib
201
+
202
+ try:
203
+ cloud_config = read_ini(DEFAULTS_PATH)["general"]["rclone_config_name"]
204
+ except (FileNotFoundError, KeyError, IndexError):
205
+ cloud_config = "Not configured"
206
+
207
+ try:
208
+ backup_file = LIBRARY_ROOT.joinpath("profile/backup.toml")
209
+ if backup_file.exists():
210
+ backup_data = tomllib.loads(backup_file.read_text(encoding="utf-8"))
211
+ backup_items = list(backup_data.keys())
212
+ backup_items_count = len(backup_items)
213
+ else:
214
+ backup_items = []
215
+ backup_items_count = 0
216
+ except Exception:
217
+ backup_items = []
218
+ backup_items_count = 0
219
+
220
+ return {"cloud_config": cloud_config, "backup_items_count": backup_items_count, "backup_items": backup_items}
221
+
222
+
223
+ def _display_system_info(info: dict[str, str]) -> None:
224
+ """Display system information panel."""
225
+ console.rule("[bold blue]💻 System Information[/bold blue]")
226
+
227
+ table = Table(show_header=False, box=None, padding=(0, 1), expand=False)
228
+ table.add_column("Property", style="cyan", no_wrap=True)
229
+ table.add_column("Value", style="white")
230
+
231
+ table.add_row("🏠 Hostname", info["hostname"])
232
+ table.add_row("💿 System", f"{info['system']} {info['release']}")
233
+ table.add_row("🖥️ Machine", info["machine"])
234
+ table.add_row("⚙️ Processor", info["processor"])
235
+ table.add_row("🐍 Python", info["python_version"])
236
+ table.add_row("👤 User", info["user"])
237
+
238
+ console.print(Panel(table, title="System", border_style="blue", padding=(1, 2), expand=False))
239
+
240
+
241
+ def _display_shell_status(status: dict[str, Any]) -> None:
242
+ """Display shell profile status panel."""
243
+ console.rule("[bold green]🐚 Shell Profile[/bold green]")
244
+
245
+ if "error" in status:
246
+ console.print(Panel(f"❌ Error: {status['error']}", title="Shell Profile", border_style="red", padding=(1, 2), expand=False))
247
+ return
248
+
249
+ from rich.columns import Columns
250
+
251
+ left_table = Table(show_header=False, box=None, padding=(0, 1))
252
+ left_table.add_column("Item", style="cyan", no_wrap=True)
253
+ left_table.add_column("Status")
254
+
255
+ left_table.add_row("📄 Profile", status["profile_path"])
256
+ left_table.add_row(f"{'✅' if status['exists'] else '❌'} Exists", str(status["exists"]))
257
+ left_table.add_row(f"{'✅' if status['configured'] else '❌'} Configured", str(status["configured"]))
258
+
259
+ right_table = Table(show_header=False, box=None, padding=(0, 1))
260
+ right_table.add_column("Item", style="cyan", no_wrap=True)
261
+ right_table.add_column("Status")
262
+
263
+ right_table.add_row("🔧 Method", status["method"])
264
+ right_table.add_row(f"{'✅' if status['init_script_exists'] else '❌'} Init (source)", str(status["init_script_exists"]))
265
+ right_table.add_row(f"{'✅' if status['init_script_copy_exists'] else '❌'} Init (copy)", str(status["init_script_copy_exists"]))
266
+
267
+ border_style = "green" if status["configured"] else "yellow"
268
+ console.print(
269
+ Panel(
270
+ Columns([left_table, right_table], equal=True, expand=True),
271
+ title="Shell Profile",
272
+ border_style=border_style,
273
+ padding=(1, 2),
274
+ expand=False,
275
+ )
276
+ )
277
+
278
+
279
+ def _display_repos_status(status: dict[str, Any]) -> None:
280
+ """Display configured repositories status."""
281
+ console.rule("[bold cyan]📚 Configured Repositories[/bold cyan]")
282
+
283
+ if not status["configured"]:
284
+ console.print(Panel(f"⚠️ No repositories configured in {DEFAULTS_PATH}", title="Repositories", border_style="yellow", padding=(1, 2)))
285
+ return
286
+
287
+ if status["count"] == 0:
288
+ console.print(Panel("ℹ️ No repositories configured", title="Repositories", border_style="blue", padding=(1, 2)))
289
+ return
290
+
291
+ table = Table(show_lines=True, header_style="bold cyan")
292
+ table.add_column("Repository", style="bold")
293
+ table.add_column("Status")
294
+ table.add_column("Details")
295
+
296
+ for repo in status["repos"]:
297
+ name = repo["name"]
298
+ if not repo["exists"]:
299
+ table.add_row(f"❌ {name}", "Missing", f"Path: {repo['path']}")
300
+ elif not repo["is_repo"]:
301
+ table.add_row(f"⚠️ {name}", "Not a repo", f"Path: {repo['path']}")
302
+ else:
303
+ status_icon = "✅" if repo["clean"] else "⚠️"
304
+ status_text = "Clean" if repo["clean"] else "Uncommitted changes"
305
+ table.add_row(f"{status_icon} {name}", status_text, f"Branch: {repo['branch']}")
306
+
307
+ console.print(Panel(table, title=f"Repositories ({status['count']})", border_style="cyan", padding=(1, 2)))
308
+
309
+
310
+ def _display_ssh_status(status: dict[str, Any]) -> None:
311
+ """Display SSH configuration status."""
312
+ console.rule("[bold yellow]🔐 SSH Configuration[/bold yellow]")
313
+
314
+ if not status["ssh_dir_exists"]:
315
+ console.print(Panel("❌ SSH directory (~/.ssh) does not exist", title="SSH Status", border_style="red", padding=(1, 2), expand=False))
316
+ return
317
+
318
+ from rich.columns import Columns
319
+
320
+ config_table = Table(show_header=False, box=None, padding=(0, 1))
321
+ config_table.add_column("Item", style="cyan", no_wrap=True)
322
+ config_table.add_column("Status")
323
+
324
+ config_table.add_row("📁 Directory", status["ssh_dir_path"])
325
+ config_table.add_row(f"{'✅' if status['config_exists'] else '❌'} Config", str(status["config_exists"]))
326
+ config_table.add_row(f"{'✅' if status['authorized_keys_exists'] else '❌'} Auth Keys", str(status["authorized_keys_exists"]))
327
+ config_table.add_row(f"{'✅' if status['known_hosts_exists'] else '❌'} Known Hosts", str(status["known_hosts_exists"]))
328
+
329
+ config_panel = Panel(config_table, title="SSH Config", border_style="yellow", padding=(1, 2), expand=False)
330
+
331
+ if status["keys"]:
332
+ keys_table = Table(show_header=True, box=None, padding=(0, 1), show_lines=False, expand=False)
333
+ keys_table.add_column("Key Name", style="bold cyan")
334
+ keys_table.add_column("Pub", justify="center")
335
+ keys_table.add_column("Priv", justify="center")
336
+
337
+ for key in status["keys"]:
338
+ pub_status = "✅" if key["public_exists"] else "❌"
339
+ priv_status = "✅" if key["private_exists"] else "❌"
340
+ keys_table.add_row(key["name"], pub_status, priv_status)
341
+
342
+ keys_panel = Panel(keys_table, title=f"SSH Keys ({len(status['keys'])})", border_style="yellow", padding=(1, 2), expand=False)
343
+
344
+ console.print(Columns([config_panel, keys_panel], equal=False, expand=True))
345
+ else:
346
+ console.print(config_panel)
347
+
348
+
349
+ def _display_config_files_status(status: dict[str, Any]) -> None:
350
+ """Display configuration files status."""
351
+ console.rule("[bold bright_blue]⚙️ Configuration Files[/bold bright_blue]")
352
+
353
+ if "error" in status:
354
+ console.print(
355
+ Panel(f"❌ Error reading configuration: {status['error']}", title="Configuration Files", border_style="red", padding=(1, 2), expand=False)
356
+ )
357
+ return
358
+
359
+ public_percentage = (status["public_linked"] / status["public_count"] * 100) if status["public_count"] > 0 else 0
360
+ private_percentage = (status["private_linked"] / status["private_count"] * 100) if status["private_count"] > 0 else 0
361
+
362
+ table = Table(show_header=True, box=None, padding=(0, 2), expand=False)
363
+ table.add_column("Type", style="cyan", no_wrap=True)
364
+ table.add_column("Linked", justify="right")
365
+ table.add_column("Total", justify="right")
366
+ table.add_column("Progress", justify="right")
367
+
368
+ table.add_row("📂 Public", str(status["public_linked"]), str(status["public_count"]), f"{public_percentage:.0f}%")
369
+ table.add_row("🔒 Private", str(status["private_linked"]), str(status["private_count"]), f"{private_percentage:.0f}%")
370
+
371
+ overall_linked = status["public_linked"] + status["private_linked"]
372
+ overall_total = status["public_count"] + status["private_count"]
373
+ overall_percentage = (overall_linked / overall_total * 100) if overall_total > 0 else 0
374
+
375
+ border_style = "green" if overall_percentage > 80 else ("yellow" if overall_percentage > 50 else "red")
376
+
377
+ console.print(
378
+ Panel(table, title=f"Configuration Files ({overall_percentage:.0f}% configured)", border_style=border_style, padding=(1, 2), expand=False)
379
+ )
380
+
381
+
382
+ def _display_tools_status(grouped_tools: dict[str, dict[str, bool]]) -> None:
383
+ """Display important tools installation status organized by groups."""
384
+ console.rule("[bold bright_magenta]🛠️ Important Tools[/bold bright_magenta]")
385
+
386
+ from rich.columns import Columns
387
+
388
+ all_group_panels = []
389
+ total_installed = 0
390
+ total_tools = 0
391
+
392
+ for group_name, tools in grouped_tools.items():
393
+ sorted_tools = sorted(tools.keys())
394
+ installed = [tool for tool, status in tools.items() if status]
395
+ total_installed += len(installed)
396
+ total_tools += len(tools)
397
+
398
+ num_columns = 8
399
+ tools_per_column = (len(sorted_tools) + num_columns - 1) // num_columns
400
+
401
+ tables = []
402
+ for col_idx in range(num_columns):
403
+ table = Table(show_header=False, box=None, padding=(0, 0), collapse_padding=True)
404
+ table.add_column("Tool", style="cyan", no_wrap=True, width=None)
405
+ table.add_column("", justify="center", width=2, no_wrap=True)
406
+
407
+ start_idx = col_idx * tools_per_column
408
+ end_idx = min(start_idx + tools_per_column, len(sorted_tools))
409
+
410
+ for i in range(start_idx, end_idx):
411
+ tool = sorted_tools[i]
412
+ status_icon = "✅" if tools[tool] else "❌"
413
+ table.add_row(tool, status_icon)
414
+
415
+ if start_idx < len(sorted_tools):
416
+ tables.append(table)
417
+
418
+ installed_percentage = (len(installed) / len(tools) * 100) if tools else 0
419
+ border_style = "green" if installed_percentage > 80 else ("yellow" if installed_percentage > 50 else "red")
420
+
421
+ group_display_name = group_name.replace("_", " ").title()
422
+ group_panel = Panel(
423
+ Columns(tables, equal=False, expand=False, padding=(0, 1)),
424
+ title=f"{group_display_name} ({len(installed)}/{len(tools)})",
425
+ border_style=border_style,
426
+ padding=(0, 1),
427
+ expand=False,
428
+ )
429
+ all_group_panels.append(group_panel)
430
+
431
+ overall_percentage = (total_installed / total_tools * 100) if total_tools else 0
432
+ master_border_style = "green" if overall_percentage > 80 else ("yellow" if overall_percentage > 50 else "red")
433
+
434
+ from rich.console import Group
435
+
436
+ master_panel = Panel(
437
+ Group(*all_group_panels),
438
+ title=f"🛠️ Tools Overview ({total_installed}/{total_tools} installed - {overall_percentage:.0f}%)",
439
+ border_style=master_border_style,
440
+ padding=(1, 2),
441
+ expand=False,
442
+ )
443
+ console.print(master_panel)
444
+
445
+
446
+ def _display_backup_status(status: dict[str, Any]) -> None:
447
+ """Display backup configuration status."""
448
+ console.rule("[bold bright_cyan]💾 Backup Configuration[/bold bright_cyan]")
449
+
450
+ table = Table(show_header=False, box=None, padding=(0, 1), expand=False)
451
+ table.add_column("Property", style="cyan", no_wrap=True)
452
+ table.add_column("Value", style="white")
453
+
454
+ table.add_row("🌥️ Cloud Config", status["cloud_config"])
455
+ table.add_row("📦 Backup Items", str(status["backup_items_count"]))
456
+
457
+ border_style = "green" if status["cloud_config"] != "Not configured" else "yellow"
458
+
459
+ console.print(Panel(table, title="Backup Configuration", border_style=border_style, padding=(1, 2), expand=False))
460
+
461
+
462
+ def main() -> None:
463
+ """Main function to display comprehensive machine status."""
464
+ console.print("\n")
465
+ console.print(Panel(Text("📊 Machine Status Report", justify="center", style="bold white"), style="bold blue", padding=(1, 2)))
466
+ console.print("\n")
467
+
468
+ # system_info = _check_system_info()
469
+ # from machineconfig.scripts.python.helpers_devops.devops_system_info import _check_system_info
470
+ from machineconfig.scripts.python.helpers_utils.path import get_machine_specs
471
+ system_info = get_machine_specs()
472
+ from typing import cast
473
+ system_info = cast(dict[str, str], system_info)
474
+ _display_system_info(system_info)
475
+ shell_status = _check_shell_profile_status()
476
+ _display_shell_status(shell_status)
477
+
478
+ repos_status = _check_repos_status()
479
+ _display_repos_status(repos_status)
480
+
481
+ ssh_status = _check_ssh_status()
482
+ _display_ssh_status(ssh_status)
483
+
484
+ config_status = _check_config_files_status()
485
+ _display_config_files_status(config_status)
486
+
487
+ tools_status = _check_important_tools()
488
+ _display_tools_status(tools_status)
489
+
490
+ backup_status = _check_backup_config()
491
+ _display_backup_status(backup_status)
492
+
493
+ console.print("\n")
494
+ console.print(Panel(Text("✨ Status report complete!", justify="center", style="bold green"), style="green", padding=(1, 2)))
495
+ console.print("\n")
496
+
497
+
498
+ if __name__ == "__main__":
499
+ main()