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,340 @@
1
+ """Gource visualization tool for git repositories."""
2
+
3
+ from pathlib import Path
4
+ from typing import Annotated, Optional
5
+ import subprocess
6
+ import platform
7
+ import zipfile
8
+ import typer
9
+
10
+
11
+ def get_gource_install_dir() -> Path:
12
+ """Get the installation directory for portable Gource."""
13
+ if platform.system() == "Windows":
14
+ appdata = Path.home() / "AppData" / "Local"
15
+ return appdata / "gource"
16
+ else:
17
+ return Path.home() / ".local" / "bin" / "gource"
18
+
19
+
20
+ def get_gource_executable() -> Path:
21
+ """Get the path to the gource executable (inside the extracted directory with DLLs)."""
22
+ install_dir = get_gource_install_dir()
23
+ if platform.system() == "Windows":
24
+ possible_paths = [
25
+ install_dir / "gource.exe",
26
+ install_dir / f"gource-{get_default_version()}.win64" / "gource.exe",
27
+ ]
28
+ for path in possible_paths:
29
+ if path.exists():
30
+ return path
31
+ return install_dir / f"gource-{get_default_version()}.win64" / "gource.exe"
32
+ else:
33
+ return install_dir / "gource"
34
+
35
+
36
+ def get_default_version() -> str:
37
+ """Get the default gource version."""
38
+ return "0.53"
39
+
40
+
41
+ def install_gource_windows(version: Optional[str] = None) -> None:
42
+ """Install portable Gource on Windows by downloading and extracting the zip archive."""
43
+ if platform.system() != "Windows":
44
+ raise OSError(f"This installer is for Windows only. Current OS: {platform.system()}")
45
+
46
+ from machineconfig.utils.path_extended import PathExtended
47
+ from machineconfig.utils.source_of_truth import INSTALL_TMP_DIR
48
+
49
+ print("\n" + "=" * 80)
50
+ print("🚀 GOURCE PORTABLE INSTALLATION 🚀")
51
+ print("=" * 80 + "\n")
52
+
53
+ version_str = version or get_default_version()
54
+ portable_url = f"https://github.com/acaudwell/Gource/releases/download/gource-{version_str}/gource-{version_str}.win64.zip"
55
+ install_dir = get_gource_install_dir()
56
+
57
+ print(f"📥 Downloading portable Gource from: {portable_url}")
58
+ downloaded_zip = PathExtended(portable_url).download(folder=INSTALL_TMP_DIR)
59
+ print(f"✅ Downloaded to: {downloaded_zip}")
60
+
61
+ print(f"\n� Extracting to: {install_dir}")
62
+ install_dir.mkdir(parents=True, exist_ok=True)
63
+
64
+ try:
65
+ with zipfile.ZipFile(downloaded_zip, 'r') as zip_ref:
66
+ zip_ref.extractall(install_dir)
67
+ print(f"✅ Extracted successfully to: {install_dir}")
68
+ print(f" (The zip contains gource-{version_str}.win64/ directory with exe and DLL dependencies)")
69
+ except Exception as e:
70
+ print(f"❌ Extraction failed with error: {e}")
71
+ raise
72
+
73
+ print("\n🗑️ Cleaning up zip file...")
74
+ try:
75
+ downloaded_zip.unlink()
76
+ print(f"✅ Removed zip file: {downloaded_zip}")
77
+ except Exception as e:
78
+ print(f"⚠️ Warning: Could not remove zip file: {e}")
79
+
80
+ gource_exe = get_gource_executable()
81
+ if gource_exe.exists():
82
+ print(f"\n✅ Gource executable found at: {gource_exe}")
83
+ dll_dir = gource_exe.parent
84
+ dll_count = len(list(dll_dir.glob("*.dll")))
85
+ print(f" Found {dll_count} DLL dependencies in: {dll_dir}")
86
+ else:
87
+ print(f"\n⚠️ Warning: Expected executable not found at: {gource_exe}")
88
+ print(f" Contents of {install_dir}:")
89
+ for item in install_dir.rglob("*"):
90
+ if item.is_file():
91
+ print(f" - {item.relative_to(install_dir)}")
92
+
93
+ print("\n" + "=" * 80)
94
+ print("✅ GOURCE PORTABLE INSTALLATION COMPLETED")
95
+ print("=" * 80)
96
+ print(f"\n📌 Gource installed to: {install_dir}")
97
+ print(f" Executable: {gource_exe}")
98
+ print(" All DLL dependencies are kept together in the same directory.")
99
+ print(" This script will automatically use the portable version.")
100
+
101
+
102
+ def visualize(
103
+ repo: Annotated[str, typer.Option("--repo", "-r", help="Path to git repository to visualize")] = ".",
104
+ output_file: Annotated[Optional[Path], typer.Option("--output", "-o", help="Output video file (e.g., output.mp4). If specified, gource will render to video.")] = None,
105
+ resolution: Annotated[str, typer.Option("--resolution", "-res", help="Video resolution (e.g., 1920x1080, 1280x720)")] = "1920x1080",
106
+ seconds_per_day: Annotated[float, typer.Option("--seconds-per-day", "-spd", help="Speed of simulation (lower = faster)")] = 0.1,
107
+ auto_skip_seconds: Annotated[float, typer.Option("--auto-skip-seconds", "-as", help="Skip to next entry if nothing happens for X seconds")] = 1.0,
108
+ title: Annotated[Optional[str], typer.Option("--title", "-t", help="Title for the visualization")] = None,
109
+ hide_items: Annotated[list[str], typer.Option("--hide", "-h", help="Items to hide: bloom, date, dirnames, files, filenames, mouse, progress, root, tree, users, usernames")] = [],
110
+ key_items: Annotated[bool, typer.Option("--key", "-k", help="Show file extension key")] = False,
111
+ fullscreen: Annotated[bool, typer.Option("--fullscreen", "-f", help="Run in fullscreen mode")] = False,
112
+ viewport: Annotated[Optional[str], typer.Option("--viewport", "-v", help="Camera viewport (e.g., '1000x1000')")] = None,
113
+ start_date: Annotated[Optional[str], typer.Option("--start-date", help="Start date (YYYY-MM-DD)")] = None,
114
+ stop_date: Annotated[Optional[str], typer.Option("--stop-date", help="Stop date (YYYY-MM-DD)")] = None,
115
+ user_image_dir: Annotated[Optional[Path], typer.Option("--user-image-dir", help="Directory with user avatar images")] = None,
116
+ max_files: Annotated[int, typer.Option("--max-files", help="Maximum number of files to show (0 = no limit)")] = 0,
117
+ max_file_lag: Annotated[float, typer.Option("--max-file-lag", help="Max time files remain on screen after last change")] = 5.0,
118
+ file_idle_time: Annotated[int, typer.Option("--file-idle-time", help="Time in seconds files remain idle before being removed")] = 0,
119
+ framerate: Annotated[int, typer.Option("--framerate", help="Frames per second for video output")] = 60,
120
+ background_color: Annotated[str, typer.Option("--background-color", help="Background color in hex (e.g., 000000 for black)")] = "000000",
121
+ font_size: Annotated[int, typer.Option("--font-size", help="Font size")] = 22,
122
+ camera_mode: Annotated[str, typer.Option("--camera-mode", help="Camera mode: overview or track")] = "overview",
123
+ ) -> None:
124
+ """
125
+ Visualize git repository history using Gource with reasonable defaults.
126
+
127
+ Examples:
128
+ # Basic visualization of current directory
129
+ python grource.py visualize
130
+
131
+ # Visualize specific repository
132
+ python grource.py visualize --repo-path /path/to/repo
133
+
134
+ # Create video output
135
+ python grource.py visualize --output output.mp4
136
+
137
+ # Fast visualization with custom title
138
+ python grource.py visualize --seconds-per-day 0.01 --title "My Project"
139
+
140
+ # Hide specific elements
141
+ python grource.py visualize --hide filenames --hide date
142
+
143
+ # Custom resolution and viewport
144
+ python grource.py visualize --resolution 2560x1440 --viewport 1200x1200
145
+ """
146
+ print("\n" + "=" * 80)
147
+ print("🎬 GOURCE VISUALIZATION 🎬")
148
+ print("=" * 80 + "\n")
149
+ repo_path: Path = Path(repo).expanduser().resolve()
150
+ if not repo_path.exists():
151
+ print(f"❌ Error: Repository path does not exist: {repo_path}")
152
+ raise typer.Exit(1)
153
+
154
+ if not repo_path.joinpath(".git").exists():
155
+ print(f"❌ Error: Not a git repository: {repo_path}")
156
+ raise typer.Exit(1)
157
+
158
+ print(f"📁 Repository: {repo_path}")
159
+ print("⚙️ Configuration:")
160
+ print(f" - Resolution: {resolution}")
161
+ print(f" - Speed: {seconds_per_day} seconds per day")
162
+ print(f" - Auto-skip: {auto_skip_seconds} seconds")
163
+ if output_file:
164
+ print(f" - Output: {output_file}")
165
+ print()
166
+
167
+ gource_exe: Path = get_gource_executable()
168
+ if not gource_exe.exists():
169
+ if platform.system() == "Windows":
170
+ print(f"⚠️ Portable gource not found at {gource_exe}, installing...")
171
+ install_gource_windows()
172
+ # Check again after installation
173
+ if gource_exe.exists():
174
+ print(f"✅ Gource installed successfully at: {gource_exe}")
175
+ gource_cmd: str = str(gource_exe)
176
+ else:
177
+ print("❌ Installation failed, falling back to system gource")
178
+ raise typer.Exit(1)
179
+ else:
180
+ raise FileNotFoundError(f"Gource executable not found at {gource_exe}. Please install gource using your package manager.")
181
+ else:
182
+ gource_cmd = str(gource_exe)
183
+
184
+ cmd: list[str] = [gource_cmd, str(repo_path)]
185
+
186
+ cmd.extend(["--seconds-per-day", str(seconds_per_day)])
187
+ cmd.extend(["--auto-skip-seconds", str(auto_skip_seconds)])
188
+
189
+ if resolution:
190
+ width, height = resolution.split("x")
191
+ cmd.extend(["-{}x{}".format(width, height)])
192
+
193
+ if title:
194
+ cmd.extend(["--title", title])
195
+ elif not title and not output_file:
196
+ cmd.extend(["--title", repo_path.name])
197
+
198
+ for hide_item in hide_items:
199
+ cmd.extend(["--hide", hide_item])
200
+
201
+ if key_items:
202
+ cmd.append("--key")
203
+
204
+ if fullscreen and not output_file:
205
+ cmd.append("--fullscreen")
206
+
207
+ if viewport:
208
+ cmd.extend(["--viewport", viewport])
209
+
210
+ if start_date:
211
+ cmd.extend(["--start-date", start_date])
212
+
213
+ if stop_date:
214
+ cmd.extend(["--stop-date", stop_date])
215
+
216
+ if user_image_dir and user_image_dir.exists():
217
+ cmd.extend(["--user-image-dir", str(user_image_dir)])
218
+
219
+ if max_files > 0:
220
+ cmd.extend(["--max-files", str(max_files)])
221
+
222
+ cmd.extend(["--max-file-lag", str(max_file_lag)])
223
+
224
+ if file_idle_time > 0:
225
+ cmd.extend(["--file-idle-time", str(file_idle_time)])
226
+
227
+ cmd.extend(["--background-colour", background_color])
228
+ cmd.extend(["--font-size", str(font_size)])
229
+ cmd.extend(["--camera-mode", camera_mode])
230
+
231
+ if output_file:
232
+ cmd.extend(["-r", str(framerate)])
233
+ if platform.system() == "Windows":
234
+ cmd.extend(["-o", "-"])
235
+ ffmpeg_cmd: list[str] = [
236
+ "ffmpeg",
237
+ "-y",
238
+ "-r", str(framerate),
239
+ "-f", "image2pipe",
240
+ "-vcodec", "ppm",
241
+ "-i", "-",
242
+ "-vcodec", "libx264",
243
+ "-preset", "medium",
244
+ "-pix_fmt", "yuv420p",
245
+ "-crf", "23",
246
+ str(output_file),
247
+ ]
248
+ print("🎥 Rendering video...")
249
+ print(f" Command: {' '.join(cmd)} | {' '.join(ffmpeg_cmd)}")
250
+ print()
251
+ try:
252
+ gource_proc: subprocess.Popen[bytes] = subprocess.Popen(cmd, stdout=subprocess.PIPE)
253
+ ffmpeg_proc: subprocess.Popen[bytes] = subprocess.Popen(ffmpeg_cmd, stdin=gource_proc.stdout)
254
+ if gource_proc.stdout:
255
+ gource_proc.stdout.close()
256
+ ffmpeg_proc.communicate()
257
+ print(f"\n✅ Video saved to: {output_file}")
258
+ except subprocess.CalledProcessError as e:
259
+ print(f"❌ Error during video rendering: {e}")
260
+ raise typer.Exit(1)
261
+ except FileNotFoundError:
262
+ print("❌ Error: ffmpeg not found. Please install ffmpeg to create video output.")
263
+ print(" Download from: https://ffmpeg.org/download.html")
264
+ raise typer.Exit(1)
265
+ else:
266
+ cmd.extend(["-o", "-"])
267
+ ffmpeg_cmd = [
268
+ "ffmpeg",
269
+ "-y",
270
+ "-r", str(framerate),
271
+ "-f", "image2pipe",
272
+ "-vcodec", "ppm",
273
+ "-i", "-",
274
+ "-vcodec", "libx264",
275
+ "-preset", "medium",
276
+ "-pix_fmt", "yuv420p",
277
+ "-crf", "23",
278
+ str(output_file),
279
+ ]
280
+ print("🎥 Rendering video...")
281
+ print(f" Command: {' '.join(cmd)} | {' '.join(ffmpeg_cmd)}")
282
+ print()
283
+ try:
284
+ gource_proc = subprocess.Popen(cmd, stdout=subprocess.PIPE)
285
+ ffmpeg_proc = subprocess.Popen(ffmpeg_cmd, stdin=gource_proc.stdout)
286
+ if gource_proc.stdout:
287
+ gource_proc.stdout.close()
288
+ ffmpeg_proc.communicate()
289
+ print(f"\n✅ Video saved to: {output_file}")
290
+ except subprocess.CalledProcessError as e:
291
+ print(f"❌ Error during video rendering: {e}")
292
+ raise typer.Exit(1)
293
+ except FileNotFoundError:
294
+ print("❌ Error: ffmpeg not found. Please install ffmpeg to create video output.")
295
+ raise typer.Exit(1)
296
+ else:
297
+ print("🎬 Launching interactive visualization...")
298
+ print(f" Command: {' '.join(cmd)}")
299
+ print()
300
+ try:
301
+ subprocess.run(cmd, check=True)
302
+ except subprocess.CalledProcessError as e:
303
+ print(f"❌ Error running gource: {e}")
304
+ raise typer.Exit(1)
305
+ except FileNotFoundError:
306
+ print("❌ Error: gource not found. Please install gource first.")
307
+ if platform.system() == "Windows":
308
+ print(" Run: uv run python src/machineconfig/scripts/python/grource.py install")
309
+ else:
310
+ print(" For Linux/Mac, use your package manager:")
311
+ print(" - Ubuntu/Debian: sudo apt install gource")
312
+ print(" - macOS: brew install gource")
313
+ print(" - Fedora: sudo dnf install gource")
314
+ raise typer.Exit(1)
315
+
316
+ print("\n" + "=" * 80)
317
+ print("✅ VISUALIZATION COMPLETED")
318
+ print("=" * 80)
319
+
320
+
321
+ def install(
322
+ version: Annotated[Optional[str], typer.Option(..., "--version", "-v", help="Gource version to install")] = "0.53",
323
+ ) -> None:
324
+ """Install portable Gource on Windows (no admin privileges required)."""
325
+ if platform.system() == "Windows":
326
+ install_gource_windows(version=version)
327
+ else:
328
+ print(f"❌ Portable installer currently supports Windows only. Current OS: {platform.system()}")
329
+ print("For Linux/Mac, please use your package manager:")
330
+ print(" - Ubuntu/Debian: sudo apt install gource")
331
+ print(" - macOS: brew install gource")
332
+ print(" - Fedora: sudo dnf install gource")
333
+ raise typer.Exit(1)
334
+
335
+
336
+ if __name__ == "__main__":
337
+ app = typer.Typer(help="Gource visualization tool for git repositories", add_help_option=False, add_completion=False)
338
+ app.command()(install)
339
+ app.command()(visualize)
340
+ app()
@@ -3,7 +3,7 @@ from pathlib import Path
3
3
  from machineconfig.utils.schemas.repos.repos_types import GitVersionInfo, RepoRecordDict, RepoRemote
4
4
 
5
5
  from machineconfig.utils.schemas.repos.repos_types import RepoRecordFile
6
- from machineconfig.utils.source_of_truth import CONFIG_PATH
6
+ from machineconfig.utils.source_of_truth import CONFIG_ROOT
7
7
  from machineconfig.utils.io import save_json
8
8
 
9
9
  from typing import Optional
@@ -186,7 +186,7 @@ def record_repos_recursively(repos_root: str, r: bool, progress: Progress | None
186
186
  return res
187
187
 
188
188
 
189
- def main(repos_root: Path):
189
+ def main_record(repos_root: Path):
190
190
  print("\n📝 Recording repositories...")
191
191
  repos_root = PathExtended(repos_root).expanduser().absolute()
192
192
 
@@ -242,7 +242,8 @@ def main(repos_root: Path):
242
242
  tree_structure = build_tree_structure(repo_records, repos_root)
243
243
  print(tree_structure)
244
244
 
245
- save_path = CONFIG_PATH.joinpath("repos").joinpath(repos_root.rel2home()).joinpath("repos.json")
245
+ relative_repos_root = PathExtended(repos_root).expanduser().absolute().relative_to(Path.home())
246
+ save_path = CONFIG_ROOT.joinpath("repos").joinpath(relative_repos_root).joinpath("repos.json")
246
247
  save_json(obj=res, path=save_path, indent=4)
247
248
  pprint(f"📁 Result saved at {PathExtended(save_path)}")
248
249
  print(">>>>>>>>> Finished Recording")
@@ -0,0 +1,160 @@
1
+
2
+
3
+ import subprocess
4
+
5
+ from git import Repo
6
+ from collections import defaultdict
7
+ from datetime import datetime, date
8
+ from typing import Any, Dict, List, Optional, Union
9
+ from pathlib import Path
10
+
11
+
12
+
13
+ def count_historical_line_edits(repo_path: str) -> int:
14
+
15
+ repo = Repo(repo_path)
16
+ last_commit = next(repo.iter_commits())
17
+ total_lines, total_files = count_python_lines(last_commit)
18
+ print(f"Total lines of Python code in latest commit ({last_commit.hexsha[:8]}): {total_lines} across {total_files} files")
19
+
20
+ gitcs_viz(repo_path=repo_path, pull_full_history=True)
21
+
22
+ file_line_counts: "Dict[str, int]" = defaultdict(int)
23
+ total_commits: int = sum(1 for _ in repo.iter_commits())
24
+ print(f"Total commits to process: {total_commits}")
25
+ for i, commit in enumerate(repo.iter_commits(), 1):
26
+ if i % 100 == 0 or i == total_commits:
27
+ print(f"Processing commit {i}/{total_commits} ({i / total_commits:.1%})")
28
+ try:
29
+ # Handle initial commits that have no parents
30
+ if not commit.parents:
31
+ # For initial commit, count all lines in Python files
32
+ for file in commit.stats.files:
33
+ if str(file).endswith(".py"):
34
+ file_line_counts[str(file)] += commit.stats.files[file]["insertions"]
35
+ else:
36
+ # For commits with parents, use stats
37
+ for file in commit.stats.files:
38
+ if str(file).endswith(".py"):
39
+ file_line_counts[str(file)] += commit.stats.files[file]["insertions"]
40
+ except Exception:
41
+ # If stats fail (e.g., corrupted parent), skip this commit
42
+ print(f"Warning: Could not get stats for commit {commit.hexsha[:8]}, skipping")
43
+ continue
44
+
45
+ print(f"\nProcessed files: {len(file_line_counts)}")
46
+ res = sum(file_line_counts.values())
47
+ print(f"Total historical lines of Python code: {res}")
48
+ return res
49
+
50
+
51
+
52
+
53
+ def count_lines_changed_in_commit(commit: "Any") -> int:
54
+ _total_lines = 0
55
+ for _file in commit.stats.files:
56
+ if str(_file).endswith(".py"):
57
+ _blob = commit.tree / _file
58
+ _total_lines += len(_blob.data_stream.read().decode("utf-8").splitlines())
59
+ return _total_lines
60
+ def count_python_lines(commit: "Any") -> tuple[int, int]:
61
+ """Count total lines in Python files for a specific commit"""
62
+ total_lines = 0
63
+ total_files = 0
64
+ try:
65
+ for blob in commit.tree.traverse():
66
+ if blob.path.endswith(".py"):
67
+ try:
68
+ content = blob.data_stream.read().decode("utf-8")
69
+ total_lines += len(content.splitlines())
70
+ total_files += 1
71
+ except Exception as _e:
72
+ continue
73
+ except Exception as e:
74
+ print(f"Error traversing commit {commit.hexsha[:8]}: {e}")
75
+ pass
76
+ return total_lines, total_files
77
+
78
+
79
+ def get_default_branch(repo: Repo) -> str:
80
+ """Get the default branch name of the repository"""
81
+ try:
82
+ _ = repo.refs["main"]
83
+ return "main" # First try 'main'
84
+ except IndexError:
85
+ try:
86
+ _ = repo.refs["master"]
87
+ return "master" # Then try 'master'
88
+ except IndexError:
89
+ return repo.head.reference.name # If neither exists, get the branch the HEAD is pointing to
90
+
91
+
92
+
93
+ def gitcs_viz(repo_path: Union[str, Path], email: Optional[str] = None, pull_full_history: bool = False) -> None:
94
+ """Invoke the gitcs CLI across 6-month windows covering the repo history.
95
+
96
+ Args:
97
+ repo_path: Path to the git repository
98
+ email: Optional email filter for gitcs
99
+ pull_full_history: If True, unshallow the repo to fetch full history (useful for shallow clones)
100
+ """
101
+ from machineconfig.utils.installer_utils.installer_cli import install_if_missing
102
+ install_if_missing("gitcs")
103
+
104
+ repo_path = Path(repo_path).expanduser().resolve()
105
+ repo = Repo(repo_path)
106
+
107
+ # Check if repo is shallow and optionally unshallow it
108
+ if pull_full_history:
109
+ shallow_file = Path(repo.git_dir) / "shallow"
110
+ if shallow_file.exists():
111
+ print("🔄 Detected shallow clone. Fetching full history...")
112
+ try:
113
+ repo.git.fetch("--unshallow")
114
+ print("✅ Successfully fetched full history")
115
+ except Exception as e:
116
+ print(f"⚠️ Failed to unshallow repository: {e}")
117
+ print("Continuing with available history...")
118
+ else:
119
+ print("ℹ️ Repository already has full history")
120
+
121
+ branch_name = get_default_branch(repo)
122
+ commits: "List[Any]" = list(repo.iter_commits(branch_name))
123
+ if not commits:
124
+ print("⚠️ No commits found; skipping gitcs visualization.")
125
+ return
126
+
127
+ from datetime import timezone
128
+
129
+ commit_dates = [datetime.fromtimestamp(commit.committed_date, tz=timezone.utc).date() for commit in commits]
130
+ min_year = min(commit_dates).year
131
+ max_year = max(commit_dates).year
132
+
133
+ print(f"📆 gitcs windows: {min_year}-01-01 → {max_year}-12-31 (fixed half-year slices)")
134
+
135
+ chunk_idx = 1
136
+ for year in range(min_year, max_year + 1):
137
+ windows = [(date(year, 1, 1), date(year, 6, 30)), (date(year, 7, 1), date(year, 12, 31))]
138
+ for chunk_start, chunk_end in windows:
139
+ cmd = ["gitcs", "--since", chunk_start.isoformat(), "--until", chunk_end.isoformat()]
140
+ if email:
141
+ cmd.extend(["--email", email])
142
+
143
+ print(f"\n===== gitcs chunk {chunk_idx}: {chunk_start.isoformat()} → {chunk_end.isoformat()} =====")
144
+ try:
145
+ completed = subprocess.run(cmd, cwd=str(repo_path), capture_output=True, text=True, input=f"{repo_path}\n")
146
+ except FileNotFoundError:
147
+ print("❌ gitcs CLI is not available on PATH; aborting visualization.")
148
+ return
149
+
150
+ if completed.stdout.strip():
151
+ print(completed.stdout.strip())
152
+ if completed.stderr.strip():
153
+ print(completed.stderr.strip())
154
+ if completed.returncode != 0:
155
+ print(f"⚠️ gitcs exited with code {completed.returncode} for this range.")
156
+
157
+ chunk_idx += 1
158
+
159
+
160
+