machineconfig 6.23__py3-none-any.whl → 8.12__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of machineconfig might be problematic. Click here for more details.

Files changed (402) hide show
  1. machineconfig/cluster/remote/cloud_manager.py +1 -1
  2. machineconfig/cluster/remote/distribute.py +0 -1
  3. machineconfig/cluster/remote/file_manager.py +0 -2
  4. machineconfig/cluster/sessions_managers/{utils → helpers}/enhanced_command_runner.py +4 -6
  5. machineconfig/cluster/sessions_managers/utils/load_balancer.py +1 -1
  6. machineconfig/cluster/sessions_managers/utils/maker.py +69 -0
  7. machineconfig/cluster/sessions_managers/wt_local.py +16 -221
  8. machineconfig/cluster/sessions_managers/wt_local_manager.py +55 -193
  9. machineconfig/cluster/sessions_managers/wt_remote_manager.py +42 -198
  10. machineconfig/cluster/sessions_managers/wt_utils/manager_persistence.py +52 -0
  11. machineconfig/cluster/sessions_managers/wt_utils/monitoring_helpers.py +50 -0
  12. machineconfig/cluster/sessions_managers/wt_utils/status_reporting.py +76 -0
  13. machineconfig/cluster/sessions_managers/wt_utils/wt_helpers.py +199 -0
  14. machineconfig/cluster/sessions_managers/zellij_local.py +3 -3
  15. machineconfig/cluster/sessions_managers/zellij_local_manager.py +5 -3
  16. machineconfig/cluster/sessions_managers/zellij_remote.py +2 -2
  17. machineconfig/cluster/sessions_managers/zellij_remote_manager.py +3 -2
  18. machineconfig/cluster/sessions_managers/zellij_utils/example_usage.py +2 -2
  19. machineconfig/cluster/sessions_managers/zellij_utils/process_monitor.py +3 -7
  20. machineconfig/cluster/sessions_managers/{helpers → zellij_utils}/zellij_local_helper_with_panes.py +1 -1
  21. machineconfig/jobs/installer/check_installations.py +0 -1
  22. machineconfig/jobs/installer/installer_data.json +1408 -201
  23. machineconfig/jobs/installer/linux_scripts/q.sh +10 -7
  24. machineconfig/jobs/installer/linux_scripts/redis.sh +1 -0
  25. machineconfig/jobs/installer/package_groups.py +63 -92
  26. machineconfig/jobs/installer/powershell_scripts/install_fonts.ps1 +129 -34
  27. machineconfig/jobs/installer/python_scripts/boxes.py +61 -0
  28. machineconfig/jobs/installer/{custom_dev → python_scripts}/brave.py +5 -3
  29. machineconfig/jobs/installer/python_scripts/cloudflare_warp_cli.py +23 -0
  30. machineconfig/jobs/installer/{custom_dev → python_scripts}/code.py +4 -1
  31. machineconfig/jobs/installer/{custom_dev → python_scripts}/dubdb_adbc.py +1 -1
  32. machineconfig/jobs/installer/{custom → python_scripts}/hx.py +75 -18
  33. machineconfig/jobs/installer/{custom_dev → python_scripts}/nerdfont.py +2 -2
  34. machineconfig/jobs/installer/{custom_dev → python_scripts}/nerfont_windows_helper.py +27 -22
  35. machineconfig/jobs/installer/python_scripts/sysabc.py +139 -0
  36. machineconfig/jobs/installer/{custom_dev → python_scripts}/wezterm.py +2 -19
  37. machineconfig/jobs/installer/{custom_dev → python_scripts}/winget.py +10 -14
  38. machineconfig/jobs/installer/python_scripts/yazi.py +121 -0
  39. machineconfig/{scripts/python/nw → jobs/scripts/bash_scripts}/mount_nfs +0 -1
  40. machineconfig/jobs/scripts/powershell_scripts/mount_ssh.ps1 +13 -0
  41. machineconfig/jobs/scripts/powershell_scripts/obs.ps1 +4 -0
  42. machineconfig/jobs/scripts_dynamic/a.py +25 -0
  43. machineconfig/logger.py +0 -1
  44. machineconfig/profile/create_helper.py +56 -18
  45. machineconfig/profile/create_links.py +2 -1
  46. machineconfig/profile/create_links_export.py +64 -18
  47. machineconfig/profile/create_shell_profile.py +90 -132
  48. machineconfig/profile/mapper.toml +18 -8
  49. machineconfig/scripts/__init__.py +0 -4
  50. machineconfig/scripts/linux/wrap_mcfg +46 -0
  51. machineconfig/scripts/nu/wrap_mcfg.nu +69 -0
  52. machineconfig/scripts/python/agents.py +82 -60
  53. machineconfig/scripts/python/ai/initai.py +1 -19
  54. machineconfig/scripts/python/ai/scripts/command_runner.ps1 +33 -0
  55. machineconfig/scripts/python/ai/{command_runner → scripts}/command_runner.sh +1 -1
  56. machineconfig/scripts/python/ai/scripts/lint_and_type_check.sh +1 -1
  57. machineconfig/scripts/python/ai/solutions/copilot/{chatmodes/Thinking-Beast-Mode.chatmode.md → agents/Thinking-Beast-Mode.agent.md} +0 -1
  58. machineconfig/scripts/python/ai/solutions/copilot/{chatmodes/Ultimate-Transparent-Thinking-Beast-Mode.chatmode.md → agents/Ultimate-Transparent-Thinking-Beast-Mode.agent.md} +0 -1
  59. machineconfig/scripts/python/ai/solutions/copilot/{chatmodes/deepResearch.chatmode.md → agents/deepResearch.agent.md} +2 -2
  60. machineconfig/scripts/python/ai/solutions/copilot/github_copilot.py +5 -5
  61. machineconfig/scripts/python/ai/solutions/copilot/instructions/python/dev.instructions.md +4 -0
  62. machineconfig/scripts/python/ai/solutions/copilot/instructions/python/watch_exec.prompt.md +20 -0
  63. machineconfig/scripts/python/ai/solutions/generic.py +1 -1
  64. machineconfig/scripts/python/ai/{generate_files.py → utils/generate_files.py} +2 -2
  65. machineconfig/scripts/python/ai/{vscode_tasks.py → utils/vscode_tasks.py} +7 -2
  66. machineconfig/scripts/python/cloud.py +14 -9
  67. machineconfig/scripts/python/croshell.py +135 -117
  68. machineconfig/scripts/python/devops.py +48 -25
  69. machineconfig/scripts/python/devops_navigator.py +1 -5
  70. machineconfig/scripts/python/env_manager/env_manager_tui.py +204 -0
  71. machineconfig/scripts/python/env_manager/path_manager_tui.py +18 -9
  72. machineconfig/scripts/python/fire_jobs.py +127 -118
  73. machineconfig/scripts/python/ftpx.py +44 -17
  74. machineconfig/scripts/python/helpers/ast_search.py +74 -0
  75. machineconfig/scripts/python/helpers/qr_code.py +166 -0
  76. machineconfig/scripts/python/helpers/repo_rag.py +325 -0
  77. machineconfig/scripts/python/helpers/symantic_search.py +25 -0
  78. machineconfig/scripts/python/{helpers_fire → helpers_agents}/agentic_frameworks/fire_crush.json +1 -1
  79. machineconfig/scripts/python/helpers_agents/agentic_frameworks/fire_crush.py +39 -0
  80. machineconfig/scripts/python/{helpers_fire → helpers_agents}/agentic_frameworks/fire_cursor_agents.py +3 -4
  81. machineconfig/scripts/python/helpers_agents/agentic_frameworks/fire_gemini.py +55 -0
  82. machineconfig/scripts/python/helpers_agents/agentic_frameworks/fire_qwen.py +30 -0
  83. machineconfig/scripts/python/{helpers_fire → helpers_agents}/fire_agents_help_launch.py +37 -15
  84. machineconfig/scripts/python/helpers_agents/fire_agents_helper_types.py +41 -0
  85. machineconfig/scripts/python/helpers_agents/privacy/configs/aichat/config.yaml +5 -0
  86. machineconfig/scripts/python/helpers_agents/privacy/configs/aider/.aider.conf.yml +2 -0
  87. machineconfig/scripts/python/helpers_agents/privacy/configs/copilot/config.yml +1 -0
  88. machineconfig/scripts/python/helpers_agents/privacy/configs/crush/crush.json +10 -0
  89. machineconfig/scripts/python/helpers_agents/privacy/configs/gemini/settings.json +12 -0
  90. machineconfig/scripts/python/helpers_agents/privacy/privacy.py +109 -0
  91. machineconfig/scripts/python/helpers_agents/templates/prompt.txt +10 -0
  92. machineconfig/scripts/python/helpers_agents/templates/template.sh +34 -0
  93. machineconfig/scripts/python/{cloud_helpers → helpers_cloud}/cloud_copy.py +28 -21
  94. machineconfig/scripts/python/{cloud_helpers → helpers_cloud}/cloud_mount.py +19 -17
  95. machineconfig/scripts/python/{cloud_helpers → helpers_cloud}/cloud_sync.py +12 -11
  96. machineconfig/scripts/python/{cloud_helpers → helpers_cloud}/helpers2.py +1 -1
  97. machineconfig/scripts/python/helpers_croshell/crosh.py +39 -0
  98. machineconfig/scripts/python/{croshell_helpers → helpers_croshell}/start_slidev.py +6 -7
  99. machineconfig/scripts/python/helpers_devops/cli_config.py +105 -0
  100. machineconfig/scripts/python/helpers_devops/cli_config_dotfile.py +89 -0
  101. machineconfig/scripts/python/helpers_devops/cli_data.py +25 -0
  102. machineconfig/scripts/python/helpers_devops/cli_nw.py +221 -0
  103. machineconfig/scripts/python/{devops_helpers → helpers_devops}/cli_repos.py +60 -36
  104. machineconfig/scripts/python/helpers_devops/cli_self.py +172 -0
  105. machineconfig/scripts/python/helpers_devops/cli_share_file.py +137 -0
  106. machineconfig/scripts/python/helpers_devops/cli_share_server.py +142 -0
  107. machineconfig/scripts/python/{devops_helpers/cli_terminal.py → helpers_devops/cli_share_terminal.py} +15 -17
  108. machineconfig/scripts/python/{devops_helpers → helpers_devops}/devops_backup_retrieve.py +7 -10
  109. machineconfig/scripts/python/{devops_helpers → helpers_devops}/devops_status.py +7 -19
  110. machineconfig/scripts/python/{devops_helpers → helpers_devops}/devops_update_repos.py +1 -1
  111. machineconfig/scripts/python/helpers_devops/run_script.py +168 -0
  112. machineconfig/scripts/python/helpers_devops/themes/choose_starship_theme.bash +3 -0
  113. machineconfig/scripts/python/{devops_helpers → helpers_devops}/themes/choose_wezterm_theme.py +1 -1
  114. machineconfig/scripts/python/{helpers_fire/helpers4.py → helpers_fire_command/file_wrangler.py} +57 -20
  115. machineconfig/scripts/python/helpers_fire_command/fire_jobs_args_helper.py +2 -0
  116. machineconfig/scripts/python/helpers_fire_command/fire_jobs_route_helper.py +26 -16
  117. machineconfig/scripts/python/helpers_msearch/__init__.py +5 -0
  118. machineconfig/scripts/{linux → python/helpers_msearch/scripts_linux}/fzfg +3 -3
  119. machineconfig/scripts/python/helpers_msearch/scripts_windows/fzfg.ps1 +59 -0
  120. machineconfig/scripts/python/helpers_navigator/__init__.py +20 -0
  121. machineconfig/scripts/python/{helper_navigator → helpers_navigator}/command_builder.py +1 -1
  122. machineconfig/scripts/python/{helper_navigator → helpers_navigator}/command_detail.py +1 -1
  123. machineconfig/scripts/python/{helper_navigator → helpers_navigator}/command_tree.py +160 -23
  124. machineconfig/scripts/python/{helper_navigator → helpers_navigator}/main_app.py +5 -5
  125. machineconfig/scripts/python/helpers_network/address.py +176 -0
  126. machineconfig/scripts/python/helpers_network/address_switch.py +78 -0
  127. machineconfig/scripts/python/{nw → helpers_network}/mount_nfs.py +2 -2
  128. machineconfig/scripts/python/{nw → helpers_network}/mount_ssh.py +1 -1
  129. machineconfig/scripts/python/{nw/devops_add_identity.py → helpers_network/ssh_add_identity.py} +35 -1
  130. machineconfig/scripts/python/{nw/devops_add_ssh_key.py → helpers_network/ssh_add_ssh_key.py} +26 -7
  131. machineconfig/scripts/python/{nw → helpers_network}/ssh_debug_linux.py +7 -7
  132. machineconfig/scripts/python/{nw → helpers_network}/ssh_debug_windows.py +4 -4
  133. machineconfig/scripts/python/{nw → helpers_network}/wifi_conn.py +1 -53
  134. machineconfig/scripts/python/helpers_repos/action.py +209 -0
  135. machineconfig/scripts/python/helpers_repos/action_helper.py +150 -0
  136. machineconfig/scripts/python/{repos_helpers → helpers_repos}/clone.py +0 -1
  137. machineconfig/scripts/python/helpers_repos/cloud_repo_sync.py +80 -37
  138. machineconfig/scripts/python/{repos_helpers → helpers_repos}/entrypoint.py +5 -5
  139. machineconfig/scripts/python/helpers_repos/grource.py +2 -2
  140. machineconfig/scripts/python/{repos_helpers → helpers_repos}/record.py +3 -2
  141. machineconfig/scripts/python/helpers_repos/repo_analyzer_1.py +160 -0
  142. machineconfig/scripts/python/{repos_helpers/count_lines.py → helpers_repos/repo_analyzer_2.py} +113 -192
  143. machineconfig/scripts/python/{repos_helpers → helpers_repos}/sync.py +5 -5
  144. machineconfig/scripts/python/{sessions_helpers → helpers_sessions}/sessions_multiprocess.py +19 -13
  145. machineconfig/scripts/python/helpers_utils/download.py +150 -0
  146. machineconfig/scripts/python/helpers_utils/pdf.py +96 -0
  147. machineconfig/scripts/python/helpers_utils/python.py +187 -0
  148. machineconfig/scripts/python/interactive.py +26 -35
  149. machineconfig/scripts/python/{entry.py → mcfg_entry.py} +24 -10
  150. machineconfig/scripts/python/msearch.py +72 -0
  151. machineconfig/scripts/python/sessions.py +101 -38
  152. machineconfig/scripts/python/terminal.py +136 -0
  153. machineconfig/scripts/python/utils.py +62 -0
  154. machineconfig/scripts/windows/wrap_mcfg.ps1 +63 -0
  155. machineconfig/settings/broot/conf.toml +1 -1
  156. machineconfig/settings/helix/config.toml +16 -0
  157. machineconfig/settings/helix/languages.toml +13 -4
  158. machineconfig/settings/helix/yazi-picker.sh +12 -0
  159. machineconfig/settings/lf/linux/exe/lfcd.sh +1 -0
  160. machineconfig/settings/lf/linux/exe/previewer.sh +3 -2
  161. machineconfig/settings/lf/linux/lfrc +10 -11
  162. machineconfig/settings/lf/windows/lfcd.ps1 +1 -1
  163. machineconfig/settings/lf/windows/lfrc +15 -17
  164. machineconfig/settings/lf/windows/mkfile.ps1 +1 -1
  165. machineconfig/settings/linters/.ruff.toml +1 -1
  166. machineconfig/settings/marimo/marimo.toml +80 -0
  167. machineconfig/settings/marimo/snippets/globalize.py +34 -0
  168. machineconfig/settings/shells/bash/init.sh +57 -10
  169. machineconfig/settings/shells/ipy/profiles/default/startup/playext.py +1 -1
  170. machineconfig/settings/shells/nushell/config.nu +2 -35
  171. machineconfig/settings/shells/nushell/env.nu +45 -6
  172. machineconfig/settings/shells/nushell/init.nu +314 -0
  173. machineconfig/settings/shells/pwsh/init.ps1 +59 -23
  174. machineconfig/settings/shells/starship/starship.toml +16 -0
  175. machineconfig/settings/shells/wezterm/wezterm.lua +2 -0
  176. machineconfig/settings/shells/wt/settings.json +32 -17
  177. machineconfig/settings/shells/zsh/init.sh +89 -0
  178. machineconfig/settings/television/cable_unix/alias.toml +8 -0
  179. machineconfig/settings/television/cable_unix/aws-buckets.toml +14 -0
  180. machineconfig/settings/television/cable_unix/aws-instances.toml +13 -0
  181. machineconfig/settings/television/cable_unix/bash-history.toml +8 -0
  182. machineconfig/settings/television/cable_unix/channels.toml +19 -0
  183. machineconfig/settings/television/cable_unix/dirs.toml +13 -0
  184. machineconfig/settings/television/cable_unix/distrobox-list.toml +42 -0
  185. machineconfig/settings/television/cable_unix/docker-images.toml +13 -0
  186. machineconfig/settings/television/cable_unix/dotfiles.toml +11 -0
  187. machineconfig/settings/television/cable_unix/env.toml +17 -0
  188. machineconfig/settings/television/cable_unix/files.toml +11 -0
  189. machineconfig/settings/television/cable_unix/fish-history.toml +8 -0
  190. machineconfig/settings/television/cable_unix/git-branch.toml +11 -0
  191. machineconfig/settings/television/cable_unix/git-diff.toml +10 -0
  192. machineconfig/settings/television/cable_unix/git-log.toml +12 -0
  193. machineconfig/settings/television/cable_unix/git-reflog.toml +12 -0
  194. machineconfig/settings/television/cable_unix/git-repos.toml +16 -0
  195. machineconfig/settings/television/cable_unix/guix.toml +20 -0
  196. machineconfig/settings/television/cable_unix/just-recipes.toml +18 -0
  197. machineconfig/settings/television/cable_unix/k8s-deployments.toml +36 -0
  198. machineconfig/settings/television/cable_unix/k8s-pods.toml +50 -0
  199. machineconfig/settings/television/cable_unix/k8s-services.toml +36 -0
  200. machineconfig/settings/television/cable_unix/man-pages.toml +24 -0
  201. machineconfig/settings/television/cable_unix/nu-history.toml +7 -0
  202. machineconfig/settings/television/cable_unix/procs.toml +20 -0
  203. machineconfig/settings/television/cable_unix/text.toml +17 -0
  204. machineconfig/settings/television/cable_unix/tldr.toml +18 -0
  205. machineconfig/settings/television/cable_unix/zsh-history.toml +9 -0
  206. machineconfig/settings/television/cable_windows/alias.toml +7 -0
  207. machineconfig/settings/television/cable_windows/dirs.toml +13 -0
  208. machineconfig/settings/television/cable_windows/docker-images.toml +13 -0
  209. machineconfig/settings/television/cable_windows/dotfiles.toml +11 -0
  210. machineconfig/settings/television/cable_windows/env.toml +17 -0
  211. machineconfig/settings/television/cable_windows/files.toml +14 -0
  212. machineconfig/settings/television/cable_windows/git-branch.toml +11 -0
  213. machineconfig/settings/television/cable_windows/git-diff.toml +10 -0
  214. machineconfig/settings/television/cable_windows/git-log.toml +11 -0
  215. machineconfig/settings/television/cable_windows/git-reflog.toml +11 -0
  216. machineconfig/settings/television/cable_windows/git-repos.toml +15 -0
  217. machineconfig/settings/television/cable_windows/nu-history.toml +7 -0
  218. machineconfig/settings/television/cable_windows/pwsh-history.toml +6 -0
  219. machineconfig/settings/television/cable_windows/text.toml +17 -0
  220. machineconfig/settings/yazi/init.lua +61 -0
  221. machineconfig/settings/yazi/keymap_linux.toml +94 -0
  222. machineconfig/settings/yazi/keymap_windows.toml +78 -0
  223. machineconfig/settings/yazi/shell/yazi_cd.ps1 +33 -0
  224. machineconfig/settings/yazi/shell/yazi_cd.sh +8 -0
  225. machineconfig/settings/yazi/theme.toml +4 -0
  226. machineconfig/settings/yazi/yazi_linux.toml +84 -0
  227. machineconfig/settings/yazi/yazi_windows.toml +58 -0
  228. machineconfig/settings/zellij/layouts/st.kdl +39 -8
  229. machineconfig/setup_linux/__init__.py +2 -2
  230. machineconfig/setup_linux/apps_desktop.sh +8 -27
  231. machineconfig/setup_linux/web_shortcuts/interactive.sh +27 -11
  232. machineconfig/setup_linux/web_shortcuts/live_from_github.sh +31 -0
  233. machineconfig/setup_mac/__init__.py +16 -0
  234. machineconfig/setup_mac/apps_gui.sh +248 -0
  235. machineconfig/setup_mac/ssh/openssh_setup.sh +114 -0
  236. machineconfig/setup_mac/uv.sh +36 -0
  237. machineconfig/setup_windows/__init__.py +3 -5
  238. machineconfig/setup_windows/ssh/openssh-server.ps1 +1 -1
  239. machineconfig/setup_windows/uv.ps1 +8 -1
  240. machineconfig/setup_windows/web_shortcuts/interactive.ps1 +26 -10
  241. machineconfig/setup_windows/web_shortcuts/live_from_github.ps1 +30 -0
  242. machineconfig/setup_windows/web_shortcuts/quick_init.ps1 +17 -0
  243. machineconfig/utils/accessories.py +7 -5
  244. machineconfig/utils/code.py +143 -167
  245. machineconfig/utils/files/art/fat_croco.txt +10 -0
  246. machineconfig/utils/files/art/halfwit_croco.txt +9 -0
  247. machineconfig/utils/files/art/happy_croco.txt +22 -0
  248. machineconfig/utils/files/art/water_croco.txt +11 -0
  249. machineconfig/utils/files/ascii_art.py +1 -1
  250. machineconfig/utils/files/headers.py +6 -11
  251. machineconfig/utils/files/read.py +3 -9
  252. machineconfig/utils/installer_utils/github_release_bulk.py +156 -119
  253. machineconfig/utils/installer_utils/install_from_url.py +183 -0
  254. machineconfig/utils/installer_utils/installer_class.py +44 -101
  255. machineconfig/utils/installer_utils/installer_cli.py +175 -0
  256. machineconfig/utils/installer_utils/installer_helper.py +129 -0
  257. machineconfig/utils/installer_utils/{installer_abc.py → installer_locator_utils.py} +39 -87
  258. machineconfig/utils/{installer.py → installer_utils/installer_runner.py} +17 -63
  259. machineconfig/utils/io.py +77 -4
  260. machineconfig/utils/links.py +56 -38
  261. machineconfig/utils/meta.py +235 -145
  262. machineconfig/utils/options.py +46 -18
  263. machineconfig/utils/options_tv.py +119 -0
  264. machineconfig/utils/path_extended.py +46 -97
  265. machineconfig/utils/path_helper.py +76 -23
  266. machineconfig/utils/procs.py +10 -23
  267. machineconfig/utils/scheduler.py +84 -115
  268. machineconfig/utils/scheduling.py +0 -3
  269. machineconfig/utils/schemas/fire_agents/fire_agents_input.py +1 -1
  270. machineconfig/utils/schemas/layouts/layout_types.py +1 -1
  271. machineconfig/utils/ssh.py +214 -476
  272. machineconfig/utils/ssh_utils/abc.py +5 -0
  273. machineconfig/utils/ssh_utils/copy_from_here.py +111 -0
  274. machineconfig/utils/ssh_utils/copy_to_here.py +303 -0
  275. machineconfig/utils/ssh_utils/utils.py +142 -0
  276. machineconfig/utils/ssh_utils/wsl.py +210 -0
  277. machineconfig/utils/terminal.py +3 -113
  278. machineconfig/utils/upgrade_packages.py +114 -28
  279. machineconfig/utils/ve.py +12 -4
  280. machineconfig-8.12.dist-info/METADATA +132 -0
  281. machineconfig-8.12.dist-info/RECORD +504 -0
  282. {machineconfig-6.23.dist-info → machineconfig-8.12.dist-info}/entry_points.txt +5 -1
  283. machineconfig/jobs/installer/linux_scripts/pgsql.sh +0 -41
  284. machineconfig/jobs/installer/linux_scripts/timescaledb.sh +0 -71
  285. machineconfig/jobs/linux/msc/cli_agents.sh +0 -16
  286. machineconfig/jobs/python/python_ve_symlink.py +0 -37
  287. machineconfig/jobs/python/vscode/api.py +0 -57
  288. machineconfig/jobs/windows/archive/archive_pygraphviz.ps1 +0 -12
  289. machineconfig/jobs/windows/archive/openssh-server_add_key.ps1 +0 -7
  290. machineconfig/jobs/windows/archive/openssh-server_copy-ssh-id.ps1 +0 -14
  291. machineconfig/scripts/linux/fzf2g +0 -21
  292. machineconfig/scripts/linux/fzfag +0 -17
  293. machineconfig/scripts/linux/fzffg +0 -25
  294. machineconfig/scripts/linux/fzfrga +0 -21
  295. machineconfig/scripts/linux/other/share_smb +0 -1
  296. machineconfig/scripts/linux/other/switch_ip +0 -20
  297. machineconfig/scripts/linux/skrg +0 -4
  298. machineconfig/scripts/linux/warp-cli.sh +0 -122
  299. machineconfig/scripts/linux/z_ls +0 -104
  300. machineconfig/scripts/python/ai/command_runner/prompt.txt +0 -9
  301. machineconfig/scripts/python/devops_helpers/cli_config.py +0 -81
  302. machineconfig/scripts/python/devops_helpers/cli_config_dotfile.py +0 -84
  303. machineconfig/scripts/python/devops_helpers/cli_data.py +0 -18
  304. machineconfig/scripts/python/devops_helpers/cli_nw.py +0 -73
  305. machineconfig/scripts/python/devops_helpers/cli_self.py +0 -117
  306. machineconfig/scripts/python/devops_helpers/cli_share_server.py +0 -104
  307. machineconfig/scripts/python/helper_navigator/__init__.py +0 -20
  308. machineconfig/scripts/python/helpers_fire/agentic_frameworks/fire_crush.py +0 -37
  309. machineconfig/scripts/python/helpers_fire/agentic_frameworks/fire_gemini.py +0 -44
  310. machineconfig/scripts/python/helpers_fire/agentic_frameworks/fire_qwen.py +0 -43
  311. machineconfig/scripts/python/helpers_fire/fire_agents_helper_types.py +0 -30
  312. machineconfig/scripts/python/helpers_fire/prompt.txt +0 -2
  313. machineconfig/scripts/python/helpers_fire/template.sh +0 -15
  314. machineconfig/scripts/python/helpers_repos/secure_repo.py +0 -15
  315. machineconfig/scripts/python/nw/add_ssh_key.py +0 -148
  316. machineconfig/scripts/python/nw/wsl_windows_transfer.py +0 -66
  317. machineconfig/scripts/python/repos_helpers/action.py +0 -378
  318. machineconfig/scripts/python/repos_helpers/count_lines_frontend.py +0 -17
  319. machineconfig/scripts/windows/fzfb.ps1 +0 -3
  320. machineconfig/scripts/windows/fzfg.ps1 +0 -2
  321. machineconfig/scripts/windows/fzfrga.bat +0 -20
  322. machineconfig/scripts/windows/mounts/mount_ssh.ps1 +0 -13
  323. machineconfig/settings/lf/linux/exe/fzf_nano.sh +0 -16
  324. machineconfig/settings/lf/windows/fzf_edit.ps1 +0 -6
  325. machineconfig/settings/lf/windows/tst.ps1 +0 -1
  326. machineconfig/settings/shells/pwsh/profile.ps1 +0 -0
  327. machineconfig/settings/yazi/keymap.toml +0 -0
  328. machineconfig/settings/yazi/yazi.toml +0 -4
  329. machineconfig/setup_linux/apps.sh +0 -66
  330. machineconfig/setup_linux/nix/cli_installation.sh +0 -137
  331. machineconfig/setup_linux/ssh/openssh_all.sh +0 -25
  332. machineconfig/setup_linux/ssh/openssh_wsl.sh +0 -38
  333. machineconfig/setup_windows/apps.ps1 +0 -62
  334. machineconfig/setup_windows/others/obs.ps1 +0 -4
  335. machineconfig/setup_windows/ssh/add_identity.ps1 +0 -11
  336. machineconfig/setup_windows/wt_and_pwsh/__init__.py +0 -0
  337. machineconfig/utils/installer_utils/installer.py +0 -225
  338. machineconfig-6.23.dist-info/METADATA +0 -84
  339. machineconfig-6.23.dist-info/RECORD +0 -428
  340. machineconfig/cluster/sessions_managers/{utils → helpers}/load_balancer_helper.py +0 -0
  341. machineconfig/cluster/sessions_managers/{helpers → zellij_utils}/zellij_local_helper.py +0 -0
  342. machineconfig/cluster/sessions_managers/{helpers → zellij_utils}/zellij_local_helper_restart.py +0 -0
  343. machineconfig/cluster/sessions_managers/{helpers → zellij_utils}/zellij_local_manager_helper.py +0 -0
  344. machineconfig/jobs/installer/linux_scripts/{warp-cli.sh → cloudflare_warp_cli.sh} +0 -0
  345. machineconfig/jobs/{linux/msc → installer/linux_scripts}/network.sh +0 -0
  346. machineconfig/jobs/installer/{custom_dev → python_scripts}/__init__.py +0 -0
  347. machineconfig/jobs/installer/{custom_dev → python_scripts}/alacritty.py +0 -0
  348. machineconfig/jobs/installer/{custom_dev → python_scripts}/bypass_paywall.py +0 -0
  349. machineconfig/jobs/installer/{custom_dev → python_scripts}/cursor.py +0 -0
  350. machineconfig/jobs/installer/{custom_dev → python_scripts}/espanso.py +0 -0
  351. machineconfig/jobs/installer/{custom → python_scripts}/gh.py +0 -0
  352. machineconfig/jobs/installer/{custom_dev → python_scripts}/goes.py +0 -0
  353. machineconfig/jobs/installer/{custom_dev → python_scripts}/lvim.py +0 -0
  354. machineconfig/jobs/installer/{custom_dev → python_scripts}/redis.py +0 -0
  355. machineconfig/{setup_linux/web_shortcuts → jobs/scripts/bash_scripts}/android.sh +0 -0
  356. machineconfig/jobs/{linux/msc → scripts/bash_scripts}/lid.sh +0 -0
  357. machineconfig/{setup_linux/others → jobs/scripts/bash_scripts}/mint_keyboard_shortcuts.sh +0 -0
  358. machineconfig/{scripts/python/nw → jobs/scripts/bash_scripts}/mount_drive +0 -0
  359. machineconfig/{scripts/python/nw → jobs/scripts/bash_scripts}/mount_nw_drive +0 -0
  360. machineconfig/{scripts/python/nw → jobs/scripts/bash_scripts}/mount_smb +0 -0
  361. machineconfig/{scripts/linux/other → jobs/scripts/bash_scripts}/share_cloud.sh +0 -0
  362. machineconfig/{scripts/linux/other → jobs/scripts/bash_scripts}/share_nfs +0 -0
  363. machineconfig/{scripts/linux/other → jobs/scripts/bash_scripts}/start_docker +0 -0
  364. machineconfig/{scripts → jobs/scripts/powershell_scripts}/Restore-ThunderbirdProfile.ps1 +0 -0
  365. machineconfig/{setup_windows/others → jobs/scripts/powershell_scripts}/docker.ps1 +0 -0
  366. machineconfig/{scripts/windows/mounts → jobs/scripts/powershell_scripts}/mount_nfs.ps1 +0 -0
  367. machineconfig/{scripts/windows/mounts → jobs/scripts/powershell_scripts}/mount_nw.ps1 +0 -0
  368. machineconfig/{scripts/windows/mounts → jobs/scripts/powershell_scripts}/mount_smb.ps1 +0 -0
  369. machineconfig/{setup_windows/others → jobs/scripts/powershell_scripts}/power_options.ps1 +0 -0
  370. machineconfig/{scripts/windows/mounts → jobs/scripts/powershell_scripts}/share_cloud.cmd +0 -0
  371. machineconfig/{scripts/windows/mounts → jobs/scripts/powershell_scripts}/share_smb.ps1 +0 -0
  372. machineconfig/{scripts/windows/mounts → jobs/scripts/powershell_scripts}/unlock_bitlocker.ps1 +0 -0
  373. machineconfig/{jobs/python → scripts/python/ai/utils}/__init__.py +0 -0
  374. machineconfig/scripts/python/{cloud_helpers → helpers_agents}/__init__.py +0 -0
  375. machineconfig/scripts/python/{croshell_helpers → helpers_agents/agentic_frameworks}/__init__.py +0 -0
  376. machineconfig/scripts/python/{helpers_fire → helpers_agents}/fire_agents_help_search.py +0 -0
  377. machineconfig/scripts/python/{helpers_fire → helpers_agents}/fire_agents_load_balancer.py +0 -0
  378. machineconfig/scripts/python/{helpers_fire → helpers_agents/templates}/template.ps1 +0 -0
  379. machineconfig/scripts/python/{devops_helpers → helpers_cloud}/__init__.py +0 -0
  380. machineconfig/scripts/python/{cloud_helpers → helpers_cloud}/cloud_helpers.py +1 -1
  381. /machineconfig/scripts/python/{cloud_helpers → helpers_cloud}/helpers5.py +0 -0
  382. /machineconfig/scripts/python/{devops_helpers/themes → helpers_croshell}/__init__.py +0 -0
  383. /machineconfig/scripts/python/{croshell_helpers → helpers_croshell}/pomodoro.py +0 -0
  384. /machineconfig/scripts/python/{croshell_helpers → helpers_croshell}/scheduler.py +0 -0
  385. /machineconfig/scripts/python/{croshell_helpers → helpers_croshell}/viewer.py +0 -0
  386. /machineconfig/scripts/python/{croshell_helpers → helpers_croshell}/viewer_template.py +0 -0
  387. /machineconfig/scripts/python/{helpers_fire → helpers_devops}/__init__.py +0 -0
  388. /machineconfig/scripts/python/{helpers_fire/agentic_frameworks → helpers_devops/themes}/__init__.py +0 -0
  389. /machineconfig/scripts/python/{devops_helpers → helpers_devops}/themes/choose_pwsh_theme.ps1 +0 -0
  390. /machineconfig/{jobs/windows/msc/cli_agents.bat → scripts/python/helpers_devops/themes/choose_starship_theme.ps1} +0 -0
  391. /machineconfig/{jobs/windows/msc/cli_agents.ps1 → scripts/python/helpers_fire_command/f.py} +0 -0
  392. /machineconfig/scripts/python/{helper_navigator → helpers_navigator}/data_models.py +0 -0
  393. /machineconfig/scripts/python/{helper_navigator → helpers_navigator}/search_bar.py +0 -0
  394. /machineconfig/scripts/python/{helpers_repos → helpers_network}/__init__.py +0 -0
  395. /machineconfig/scripts/python/{nw → helpers_network}/mount_nw_drive.py +0 -0
  396. /machineconfig/scripts/python/{nw → helpers_network}/onetimeshare.py +0 -0
  397. /machineconfig/scripts/python/{repos_helpers → helpers_repos}/update.py +0 -0
  398. /machineconfig/scripts/python/{nw → helpers_sessions}/__init__.py +0 -0
  399. /machineconfig/{scripts/python/sessions_helpers → settings/wt}/__init__.py +0 -0
  400. /machineconfig/{setup_windows/wt_and_pwsh → settings/wt}/set_wt_settings.py +0 -0
  401. {machineconfig-6.23.dist-info → machineconfig-8.12.dist-info}/WHEEL +0 -0
  402. {machineconfig-6.23.dist-info → machineconfig-8.12.dist-info}/top_level.txt +0 -0
@@ -1,7 +1,7 @@
1
1
 
2
2
 
3
3
  from platform import system
4
- from machineconfig.utils.path_extended import PathExtended
4
+ from pathlib import Path
5
5
  from rich.console import Console
6
6
  from rich.panel import Panel
7
7
  from rich import box
@@ -26,7 +26,7 @@ def ssh_debug_linux() -> dict[str, dict[str, str | bool]]:
26
26
  results: dict[str, dict[str, str | bool]] = {}
27
27
  issues_found: list[str] = []
28
28
 
29
- ssh_dir = PathExtended.home().joinpath(".ssh")
29
+ ssh_dir = Path.home().joinpath(".ssh")
30
30
  authorized_keys = ssh_dir.joinpath("authorized_keys")
31
31
 
32
32
  console.print(Panel("🔐 Checking SSH directory and authorized_keys...", title="[bold blue]File Permissions[/bold blue]", border_style="blue"))
@@ -106,7 +106,7 @@ def ssh_debug_linux() -> dict[str, dict[str, str | bool]]:
106
106
 
107
107
  console.print(Panel("🔌 Checking SSH port and listening status...", title="[bold blue]Network Status[/bold blue]", border_style="blue"))
108
108
 
109
- sshd_config_paths = [PathExtended("/etc/ssh/sshd_config"), PathExtended("/etc/sshd_config")]
109
+ sshd_config_paths = [Path("/etc/ssh/sshd_config"), Path("/etc/sshd_config")]
110
110
  sshd_config = None
111
111
  for config_path in sshd_config_paths:
112
112
  if config_path.exists():
@@ -236,7 +236,7 @@ def ssh_debug_linux() -> dict[str, dict[str, str | bool]]:
236
236
 
237
237
  console.print(Panel("🗂️ Checking for problematic files in /etc/...", title="[bold blue]System Files[/bold blue]", border_style="blue"))
238
238
 
239
- hosts_deny = PathExtended("/etc/hosts.deny")
239
+ hosts_deny = Path("/etc/hosts.deny")
240
240
  if hosts_deny.exists():
241
241
  hosts_deny_content = hosts_deny.read_text(encoding="utf-8")
242
242
  active_lines = [line.strip() for line in hosts_deny_content.splitlines() if line.strip() and not line.strip().startswith("#")]
@@ -252,14 +252,14 @@ def ssh_debug_linux() -> dict[str, dict[str, str | bool]]:
252
252
  results["hosts_deny"] = {"status": "ok", "message": "/etc/hosts.deny does not exist", "action": ""}
253
253
  console.print(Panel("✅ /etc/hosts.deny not present", title="[bold green]OK[/bold green]", border_style="green"))
254
254
 
255
- hosts_allow = PathExtended("/etc/hosts.allow")
255
+ hosts_allow = Path("/etc/hosts.allow")
256
256
  if hosts_allow.exists():
257
257
  results["hosts_allow"] = {"status": "ok", "message": "/etc/hosts.allow exists (check if needed)", "action": ""}
258
258
  console.print(Panel("ℹ️ /etc/hosts.allow exists\n💡 Ensure it allows SSH if using TCP wrappers", title="[bold blue]Info[/bold blue]", border_style="blue"))
259
259
 
260
260
  console.print(Panel("👤 Checking home directory permissions...", title="[bold blue]User Permissions[/bold blue]", border_style="blue"))
261
261
 
262
- home_dir = PathExtended.home()
262
+ home_dir = Path.home()
263
263
  home_stat = os.stat(home_dir)
264
264
  home_perms = oct(home_stat.st_mode)[-3:]
265
265
 
@@ -294,7 +294,7 @@ def ssh_debug_linux() -> dict[str, dict[str, str | bool]]:
294
294
 
295
295
  console.print(Panel("📋 Checking SSH logs for errors...", title="[bold blue]Logs[/bold blue]", border_style="blue"))
296
296
 
297
- log_files = [PathExtended("/var/log/auth.log"), PathExtended("/var/log/secure")]
297
+ log_files = [Path("/var/log/auth.log"), Path("/var/log/secure")]
298
298
  log_found = False
299
299
  for log_file in log_files:
300
300
  if log_file.exists():
@@ -1,7 +1,7 @@
1
1
 
2
2
 
3
3
  from platform import system
4
- from machineconfig.utils.path_extended import PathExtended
4
+ from pathlib import Path
5
5
  from rich.console import Console
6
6
  from rich.panel import Panel
7
7
  from rich import box
@@ -26,7 +26,7 @@ def ssh_debug_windows() -> dict[str, dict[str, str | bool]]:
26
26
  results: dict[str, dict[str, str | bool]] = {}
27
27
  issues_found: list[str] = []
28
28
 
29
- ssh_dir = PathExtended.home().joinpath(".ssh")
29
+ ssh_dir = Path.home().joinpath(".ssh")
30
30
  authorized_keys = ssh_dir.joinpath("authorized_keys")
31
31
 
32
32
  console.print(Panel("🔐 Checking SSH directory and authorized_keys...", title="[bold blue]File Permissions[/bold blue]", border_style="blue"))
@@ -124,7 +124,7 @@ def ssh_debug_windows() -> dict[str, dict[str, str | bool]]:
124
124
 
125
125
  console.print(Panel("🔌 Checking SSH port and listening status...", title="[bold blue]Network Status[/bold blue]", border_style="blue"))
126
126
 
127
- sshd_config_paths = [PathExtended("C:\\ProgramData\\ssh\\sshd_config"), PathExtended(os.environ.get("PROGRAMDATA", "C:\\ProgramData")).joinpath("ssh", "sshd_config")]
127
+ sshd_config_paths = [Path("C:\\ProgramData\\ssh\\sshd_config"), Path(os.environ.get("PROGRAMDATA", "C:\\ProgramData")).joinpath("ssh", "sshd_config")]
128
128
  sshd_config = None
129
129
  for config_path in sshd_config_paths:
130
130
  if config_path.exists():
@@ -168,7 +168,7 @@ def ssh_debug_windows() -> dict[str, dict[str, str | bool]]:
168
168
  if admin_authorized_keys_lines:
169
169
  console.print(Panel("⚠️ IMPORTANT: Administrators group uses different authorized_keys location\n💡 For admin users, keys should be in: C:\\ProgramData\\ssh\\administrators_authorized_keys\n💡 Not in user's .ssh/authorized_keys!", title="[bold yellow]Admin Users[/bold yellow]", border_style="yellow"))
170
170
 
171
- programdata_auth_keys = PathExtended(os.environ.get("PROGRAMDATA", "C:\\ProgramData")).joinpath("ssh", "administrators_authorized_keys")
171
+ programdata_auth_keys = Path(os.environ.get("PROGRAMDATA", "C:\\ProgramData")).joinpath("ssh", "administrators_authorized_keys")
172
172
  if programdata_auth_keys.exists():
173
173
  console.print(Panel("✅ administrators_authorized_keys file exists", title="[bold green]OK[/bold green]", border_style="green"))
174
174
  else:
@@ -28,8 +28,6 @@ Usage examples:
28
28
 
29
29
  """
30
30
 
31
- from typing import Annotated
32
- import typer
33
31
  import configparser
34
32
  from pathlib import Path
35
33
  import os
@@ -38,8 +36,7 @@ import subprocess
38
36
  import getpass
39
37
  from typing import List, Dict, Optional
40
38
  from rich.console import Console
41
- from rich.panel import Panel
42
- from rich.prompt import Prompt, Confirm
39
+ from rich.prompt import Prompt
43
40
  from rich.table import Table
44
41
 
45
42
  console = Console()
@@ -263,51 +260,6 @@ def manual_network_selection() -> bool:
263
260
  return False
264
261
 
265
262
 
266
- def main(
267
- ssid: Annotated[str, typer.Option("-n", "--ssid", help="🔗 SSID of WiFi (from config)")] = "MyPhoneHotSpot",
268
- manual: Annotated[bool, typer.Option("-m", "--manual", help="🔍 Manual network selection mode")] = False,
269
- list_: Annotated[bool, typer.Option("-l", "--list", help="📡 List available networks only")] = False,
270
- ) -> None:
271
- """Main function with fallback network selection"""
272
- console.print(Panel("📶 Welcome to the WiFi Connector Tool", title="[bold blue]WiFi Connection[/bold blue]", border_style="blue"))
273
-
274
- # If user just wants to list networks
275
- if list_:
276
- display_available_networks()
277
- return
278
-
279
- # If user wants manual mode, skip config and go straight to selection
280
- if manual:
281
- console.print("[blue]🔍 Manual network selection mode[/blue]")
282
- if manual_network_selection():
283
- console.print("[green]🎉 Successfully connected![/green]")
284
- else:
285
- console.print("[red]❌ Failed to connect[/red]")
286
- return
287
-
288
- # Try to connect using configuration first
289
- console.print(f"[blue]🔍 Attempting to connect to configured network: {ssid}[/blue]")
290
-
291
- if try_config_connection(ssid):
292
- console.print("[green]🎉 Successfully connected using configuration![/green]")
293
- return
294
-
295
- # Configuration failed, offer fallback options
296
- console.print("\n[yellow]⚠️ Configuration connection failed or not available[/yellow]")
297
-
298
- if Confirm.ask("[blue]Would you like to manually select a network?[/blue]", default=True):
299
- if manual_network_selection():
300
- console.print("[green]🎉 Successfully connected![/green]")
301
- else:
302
- console.print("[red]❌ Failed to connect[/red]")
303
- else:
304
- console.print("[blue]👋 Goodbye![/blue]")
305
-
306
-
307
- def arg_parser() -> None:
308
- typer.run(main)
309
-
310
-
311
263
  def get_current_wifi_name() -> str:
312
264
  """Get the name of the currently connected WiFi network"""
313
265
  console.print("\n[blue]🔍 Checking current WiFi connection...[/blue]")
@@ -412,7 +364,3 @@ def create_new_connection(name: str, ssid: str, password: str):
412
364
  except Exception as e:
413
365
  console.print(f"[red]❌ Unexpected error: {e}[/red]")
414
366
  raise
415
-
416
-
417
- if __name__ == "__main__":
418
- arg_parser()
@@ -0,0 +1,209 @@
1
+ from machineconfig.scripts.python.helpers_repos.action_helper import GitAction, GitOperationResult, GitOperationSummary, print_git_operations_summary
2
+ from machineconfig.utils.path_extended import PathExtended
3
+ from machineconfig.utils.accessories import randstr
4
+ from machineconfig.scripts.python.helpers_repos.update import update_repository
5
+
6
+ from typing import Optional, Dict, Any, List, cast
7
+ import concurrent.futures
8
+ import os
9
+
10
+ from rich import print as pprint
11
+
12
+
13
+ def git_action(path: PathExtended, action: GitAction, mess: Optional[str], r: bool, auto_uv_sync: bool) -> GitOperationResult:
14
+ """Perform git actions using Python instead of shell scripts. Returns detailed operation result."""
15
+ from git.exc import InvalidGitRepositoryError
16
+ from git.repo import Repo
17
+
18
+ try:
19
+ repo = Repo(str(path), search_parent_directories=False)
20
+ except InvalidGitRepositoryError:
21
+ pprint(f"⚠️ Skipping {path} because it is not a git repository.")
22
+ if r:
23
+ results = [git_action(path=sub_path, action=action, mess=mess, r=r, auto_uv_sync=auto_uv_sync) for sub_path in path.search()]
24
+ # For recursive calls, we need to aggregate results somehow
25
+ # For now, return success if all recursive operations succeeded
26
+ all_successful = all(result.success for result in results)
27
+ return GitOperationResult(
28
+ repo_path=path,
29
+ action=action.value,
30
+ success=all_successful,
31
+ message=f"Recursive operation: {len([r for r in results if r.success])}/{len(results)} succeeded",
32
+ is_git_repo=False,
33
+ )
34
+ else:
35
+ return GitOperationResult(repo_path=path, action=action.value, success=False, message="Not a git repository", is_git_repo=False)
36
+
37
+ print(f">>>>>>>>> 🔧{action} - {path}")
38
+ remote_count = len(repo.remotes)
39
+
40
+ try:
41
+ if action == GitAction.commit:
42
+ if mess is None:
43
+ mess = "auto_commit_" + randstr()
44
+
45
+ # Check if there are changes to commit
46
+ if repo.is_dirty() or repo.untracked_files:
47
+ repo.git.add(A=True) # Stage all changes
48
+ repo.index.commit(mess)
49
+ print(f"✅ Committed changes with message: {mess}")
50
+ return GitOperationResult(
51
+ repo_path=path,
52
+ action=action.value,
53
+ success=True,
54
+ message=f"Committed changes with message: {mess}",
55
+ had_changes=True,
56
+ remote_count=remote_count,
57
+ )
58
+ else:
59
+ print("ℹ️ No changes to commit")
60
+ return GitOperationResult(
61
+ repo_path=path, action=action.value, success=True, message="No changes to commit", had_changes=False, remote_count=remote_count
62
+ )
63
+
64
+ elif action == GitAction.push:
65
+ if not repo.remotes:
66
+ print("⚠️ No remotes configured for push")
67
+ return GitOperationResult(repo_path=path, action=action.value, success=False, message="No remotes configured", remote_count=0)
68
+
69
+ success = True
70
+ failed_remotes = []
71
+ for remote in repo.remotes:
72
+ try:
73
+ print(f"🚀 Pushing to {remote.url}")
74
+ remote.push(repo.active_branch.name)
75
+ print(f"✅ Pushed to {remote.name}")
76
+ except Exception as e:
77
+ print(f"❌ Failed to push to {remote.name}: {e}")
78
+ failed_remotes.append(f"{remote.name}: {str(e)}")
79
+ success = False
80
+
81
+ message = "Push successful" if success else f"Push failed for: {', '.join(failed_remotes)}"
82
+ return GitOperationResult(repo_path=path, action=action.value, success=success, message=message, remote_count=remote_count)
83
+
84
+ elif action == GitAction.pull:
85
+ # Use the enhanced update function with uv sync support
86
+ try:
87
+ update_repository(repo, auto_uv_sync=auto_uv_sync, allow_password_prompt=False)
88
+ print("✅ Pull completed")
89
+ return GitOperationResult(
90
+ repo_path=path, action=action.value, success=True, message="Pull completed successfully", remote_count=remote_count
91
+ )
92
+ except Exception as e:
93
+ print(f"❌ Pull failed: {e}")
94
+ return GitOperationResult(
95
+ repo_path=path, action=action.value, success=False, message=f"Pull failed: {str(e)}", remote_count=remote_count
96
+ )
97
+
98
+ except Exception as e:
99
+ print(f"❌ Error performing {action} on {path}: {e}")
100
+ return GitOperationResult(repo_path=path, action=action.value, success=False, message=f"Error: {str(e)}", remote_count=remote_count)
101
+
102
+ # This should never be reached, but just in case
103
+ return GitOperationResult(repo_path=path, action=action.value, success=False, message="Unknown error", remote_count=remote_count)
104
+
105
+
106
+ def perform_git_operations(repos_root: PathExtended, pull: bool, commit: bool, push: bool, recursive: bool, auto_uv_sync: bool) -> None:
107
+ """Perform git operations on all repositories and provide detailed summary."""
108
+ print(f"\n🔄 Performing Git actions on repositories @ `{repos_root}`...")
109
+ summary = GitOperationSummary()
110
+ # Keep track of which operations we are performing
111
+ operations_performed: List[str] = []
112
+ if pull:
113
+ operations_performed.append("pull")
114
+ if commit:
115
+ operations_performed.append("commit")
116
+ if push:
117
+ operations_performed.append("push")
118
+
119
+ # Collect all candidate paths first
120
+ paths = list(repos_root.search("*"))
121
+
122
+ def _process_path(a_path: PathExtended) -> Dict[str, Any]:
123
+ """Worker that processes a single path and returns metadata and results."""
124
+ from git.exc import InvalidGitRepositoryError
125
+ from git.repo import Repo
126
+
127
+ result_payload: Dict[str, Any] = {"path": a_path, "is_git": False, "results": [], "repo_remotes_count": 0}
128
+ print(f"{('Handling ' + str(a_path)).center(80, '-')}")
129
+
130
+ try:
131
+ repo = Repo(str(a_path), search_parent_directories=False)
132
+ except InvalidGitRepositoryError:
133
+ result_payload["non_git"] = True
134
+ pprint(f"⚠️ Skipping {a_path} because it is not a git repository.")
135
+ return result_payload
136
+
137
+ # It's a git repo
138
+ result_payload["is_git"] = True
139
+ result_payload["repo_remotes_count"] = len(repo.remotes)
140
+
141
+ # Perform configured operations sequentially for this repo (the repo-level work is done concurrently between repos)
142
+ try:
143
+ if pull:
144
+ r = git_action(path=a_path, action=GitAction.pull, mess=None, r=recursive, auto_uv_sync=auto_uv_sync)
145
+ result_payload["results"].append(r)
146
+ if commit:
147
+ r = git_action(path=a_path, action=GitAction.commit, mess=None, r=recursive, auto_uv_sync=auto_uv_sync)
148
+ result_payload["results"].append(r)
149
+ if push:
150
+ r = git_action(path=a_path, action=GitAction.push, mess=None, r=recursive, auto_uv_sync=auto_uv_sync)
151
+ result_payload["results"].append(r)
152
+ except Exception as e:
153
+ # Capture any unexpected exception for this path
154
+ pprint(f"❌ Error processing {a_path}: {e}")
155
+
156
+ return result_payload
157
+
158
+ # Choose a reasonable number of workers
159
+ max_workers = min(32, (os.cpu_count() or 1) * 5, len(paths) or 1)
160
+
161
+ # Run the workers in parallel and aggregate results
162
+ with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as exc:
163
+ future_to_path = {exc.submit(_process_path, p): p for p in paths}
164
+ for fut in concurrent.futures.as_completed(future_to_path):
165
+ payload = fut.result()
166
+ a_path = cast(PathExtended, payload.get("path"))
167
+ summary.total_paths_processed += 1
168
+
169
+ if not payload.get("is_git"):
170
+ summary.non_git_paths += 1
171
+ continue
172
+
173
+ # git repo found
174
+ summary.git_repos_found += 1
175
+ if payload.get("repo_remotes_count", 0) == 0:
176
+ summary.repos_without_remotes.append(a_path)
177
+
178
+ for r in payload.get("results", []):
179
+ action_name = r.action if hasattr(r, "action") else ""
180
+ # Pull
181
+ if action_name == "pull":
182
+ summary.pulls_attempted += 1
183
+ if r.success:
184
+ summary.pulls_successful += 1
185
+ else:
186
+ summary.pulls_failed += 1
187
+ summary.failed_operations.append(r)
188
+ # Commit
189
+ elif action_name == "commit":
190
+ summary.commits_attempted += 1
191
+ if r.success:
192
+ if getattr(r, "had_changes", False):
193
+ summary.commits_successful += 1
194
+ else:
195
+ summary.commits_no_changes += 1
196
+ else:
197
+ summary.commits_failed += 1
198
+ summary.failed_operations.append(r)
199
+ # Push
200
+ elif action_name == "push":
201
+ summary.pushes_attempted += 1
202
+ if r.success:
203
+ summary.pushes_successful += 1
204
+ else:
205
+ summary.pushes_failed += 1
206
+ summary.failed_operations.append(r)
207
+
208
+ # Print the detailed summary
209
+ print_git_operations_summary(summary, operations_performed)
@@ -0,0 +1,150 @@
1
+ from enum import Enum
2
+ from machineconfig.utils.path_extended import PathExtended
3
+
4
+
5
+ from dataclasses import dataclass
6
+
7
+ from rich.columns import Columns
8
+ from rich.panel import Panel
9
+ from rich.table import Table
10
+
11
+
12
+ @dataclass
13
+ class GitOperationResult:
14
+ """Result of a git operation on a single repository."""
15
+ repo_path: PathExtended
16
+ action: str
17
+ success: bool
18
+ message: str
19
+ is_git_repo: bool = True
20
+ had_changes: bool = False
21
+ remote_count: int = 0
22
+
23
+
24
+ class GitAction(Enum):
25
+ commit = "commit"
26
+ push = "push"
27
+ pull = "pull"
28
+
29
+
30
+ @dataclass
31
+ class GitOperationSummary:
32
+ """Summary of all git operations performed."""
33
+
34
+ # Basic statistics
35
+ total_paths_processed: int = 0
36
+ git_repos_found: int = 0
37
+ non_git_paths: int = 0
38
+
39
+ # Per-operation statistics
40
+ commits_attempted: int = 0
41
+ commits_successful: int = 0
42
+ commits_no_changes: int = 0
43
+ commits_failed: int = 0
44
+
45
+ pulls_attempted: int = 0
46
+ pulls_successful: int = 0
47
+ pulls_failed: int = 0
48
+
49
+ pushes_attempted: int = 0
50
+ pushes_successful: int = 0
51
+ pushes_failed: int = 0
52
+
53
+ def __post_init__(self):
54
+ self.failed_operations: list[GitOperationResult] = []
55
+ self.repos_without_remotes: list[PathExtended] = []
56
+
57
+
58
+ def print_git_operations_summary(summary: GitOperationSummary, operations_performed: list[str]) -> None:
59
+ """Print a detailed summary of git operations with rich formatting and tables."""
60
+ from rich.console import Console
61
+
62
+ console = Console()
63
+
64
+ # Main summary panel
65
+ summary_stats = [
66
+ f"Total paths processed: {summary.total_paths_processed}",
67
+ f"Git repositories found: {summary.git_repos_found}",
68
+ f"Non-git paths skipped: {summary.non_git_paths}",
69
+ ]
70
+
71
+ console.print(Panel.fit("\n".join(summary_stats), title="[bold blue]📊 Git Operations Summary[/bold blue]", border_style="blue"))
72
+
73
+ # Statistics panels in columns
74
+ stat_panels = []
75
+
76
+ if "commit" in operations_performed:
77
+ commit_stats = [
78
+ f"Attempted: {summary.commits_attempted}",
79
+ f"Successful: {summary.commits_successful}",
80
+ f"No changes: {summary.commits_no_changes}",
81
+ f"Failed: {summary.commits_failed}",
82
+ ]
83
+ stat_panels.append(Panel.fit("\n".join(commit_stats), title="[bold green]💾 Commit Operations[/bold green]", border_style="green"))
84
+
85
+ if "pull" in operations_performed:
86
+ pull_stats = [f"Attempted: {summary.pulls_attempted}", f"Successful: {summary.pulls_successful}", f"Failed: {summary.pulls_failed}"]
87
+ stat_panels.append(Panel.fit("\n".join(pull_stats), title="[bold cyan]⬇️ Pull Operations[/bold cyan]", border_style="cyan"))
88
+
89
+ if "push" in operations_performed:
90
+ push_stats = [f"Attempted: {summary.pushes_attempted}", f"Successful: {summary.pushes_successful}", f"Failed: {summary.pushes_failed}"]
91
+ stat_panels.append(Panel.fit("\n".join(push_stats), title="[bold magenta]🚀 Push Operations[/bold magenta]", border_style="magenta"))
92
+
93
+ if stat_panels:
94
+ console.print(Columns(stat_panels, equal=True, expand=True))
95
+
96
+ # Repositories without remotes warning
97
+ if summary.repos_without_remotes:
98
+ repos_table = Table(title="[bold yellow]⚠️ Repositories Without Remotes[/bold yellow]")
99
+ repos_table.add_column("Repository Name", style="cyan", no_wrap=True)
100
+ repos_table.add_column("Full Path", style="dim")
101
+
102
+ for repo_path in summary.repos_without_remotes:
103
+ repos_table.add_row(repo_path.name, str(repo_path))
104
+
105
+ console.print(repos_table)
106
+ console.print("[yellow]These repositories cannot be pushed to remote servers.[/yellow]")
107
+ elif "push" in operations_performed:
108
+ console.print("[green]✅ All repositories have remote configurations.[/green]")
109
+
110
+ # Failed operations table
111
+ if summary.failed_operations:
112
+ failed_table = Table(title=f"[bold red]❌ Failed Operations ({len(summary.failed_operations)} total)[/bold red]")
113
+ failed_table.add_column("Action", style="bold red", no_wrap=True)
114
+ failed_table.add_column("Repository", style="cyan", no_wrap=True)
115
+ failed_table.add_column("Problem", style="red")
116
+
117
+ # Group failed operations by type for better organization
118
+ failed_by_action = {}
119
+ for failed_op in summary.failed_operations:
120
+ if failed_op.action not in failed_by_action:
121
+ failed_by_action[failed_op.action] = []
122
+ failed_by_action[failed_op.action].append(failed_op)
123
+
124
+ for action, failures in failed_by_action.items():
125
+ for failure in failures:
126
+ repo_name = failure.repo_path.name if failure.is_git_repo else f"{failure.repo_path.name} (not git repo)"
127
+ problem = failure.message if failure.is_git_repo else "Not a git repository"
128
+ failed_table.add_row(action.upper(), repo_name, problem)
129
+
130
+ console.print(failed_table)
131
+ else:
132
+ console.print("[green]✅ All git operations completed successfully![/green]")
133
+
134
+ # Overall success assessment
135
+ total_failed = len(summary.failed_operations)
136
+ total_operations = summary.commits_attempted + summary.pulls_attempted + summary.pushes_attempted
137
+
138
+ if total_failed == 0 and total_operations > 0:
139
+ console.print(f"\n[bold green]🎉 SUCCESS: All {total_operations} operations completed successfully![/bold green]")
140
+ elif total_operations == 0:
141
+ console.print("\n[blue]📝 No git operations were performed.[/blue]")
142
+ else:
143
+ success_rate = ((total_operations - total_failed) / total_operations * 100) if total_operations > 0 else 0
144
+ if total_failed > 0:
145
+ console.print(
146
+ f"\n[bold yellow]⚖️ SUMMARY: {total_operations - total_failed}/{total_operations} operations succeeded ({success_rate:.1f}% success rate)[/bold yellow]"
147
+ )
148
+ console.print("[yellow]Review the failed operations table above for details on what needs attention.[/yellow]")
149
+ else:
150
+ console.print(f"\n[bold green]⚖️ SUMMARY: {total_operations}/{total_operations} operations succeeded (100% success rate)[/bold green]")
@@ -1,4 +1,3 @@
1
- from __future__ import annotations
2
1
 
3
2
  from pathlib import Path
4
3
  from typing import Literal, Optional, cast