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
@@ -1,189 +1,12 @@
1
-
2
- from typing import TYPE_CHECKING
3
1
  from git import Repo
4
- from collections import defaultdict
2
+ from machineconfig.scripts.python.helpers_repos.repo_analyzer_1 import count_python_lines, get_default_branch
5
3
  from datetime import datetime
6
-
4
+ import polars as pl
7
5
  from pathlib import Path
8
- from rich.progress import track
9
- import typer
10
-
11
-
12
- if TYPE_CHECKING:
13
- from typing import Any, Dict, List, Optional, Union
14
- import polars as pl
15
-
16
-
17
- app = typer.Typer()
18
-
19
-
20
- def count_lines_in_commit(commit: "Any") -> int:
21
- total_lines = 0
22
- for file in commit.stats.files:
23
- if str(file).endswith(".py"):
24
- blob = commit.tree / file
25
- total_lines += len(blob.data_stream.read().decode("utf-8").splitlines())
26
- return total_lines
27
-
28
-
29
- def count_historical_loc(repo_path: str) -> int:
30
- repo = Repo(repo_path)
31
- file_line_counts: "Dict[str, int]" = defaultdict(int)
32
- total_commits: int = sum(1 for _ in repo.iter_commits())
33
- print(f"Total commits to process: {total_commits}")
34
- for i, commit in enumerate(repo.iter_commits(), 1):
35
- if i % 100 == 0 or i == total_commits:
36
- print(f"Processing commit {i}/{total_commits} ({i / total_commits:.1%})")
37
- try:
38
- # Handle initial commits that have no parents
39
- if not commit.parents:
40
- # For initial commit, count all lines in Python files
41
- for file in commit.stats.files:
42
- if str(file).endswith(".py"):
43
- file_line_counts[str(file)] += commit.stats.files[file]["insertions"]
44
- else:
45
- # For commits with parents, use stats
46
- for file in commit.stats.files:
47
- if str(file).endswith(".py"):
48
- file_line_counts[str(file)] += commit.stats.files[file]["insertions"]
49
- except Exception:
50
- # If stats fail (e.g., corrupted parent), skip this commit
51
- print(f"Warning: Could not get stats for commit {commit.hexsha[:8]}, skipping")
52
- continue
53
-
54
- print(f"\nProcessed files: {len(file_line_counts)}")
55
- return sum(file_line_counts.values())
56
-
57
- def count_python_lines(commit: "Any") -> int:
58
- """Count total lines in Python files for a specific commit"""
59
- total_lines = 0
60
- try:
61
- for blob in commit.tree.traverse():
62
- if blob.path.endswith(".py"):
63
- try:
64
- content = blob.data_stream.read().decode("utf-8")
65
- total_lines += len(content.splitlines())
66
- except Exception as _e:
67
- continue
68
- except Exception as _e:
69
- return 0
70
- return total_lines
71
- def get_default_branch(repo: Repo) -> str:
72
- """Get the default branch name of the repository"""
73
- try:
74
- _ = repo.refs["main"]
75
- return "main" # First try 'main'
76
- except IndexError:
77
- try:
78
- _ = repo.refs["master"]
79
- return "master" # Then try 'master'
80
- except IndexError:
81
- return repo.head.reference.name # If neither exists, get the branch the HEAD is pointing to
82
-
83
-
84
- @app.command()
85
- def count_historical(repo_path: str = typer.Argument(..., help="Path to the git repository")):
86
- """Count total historical lines of Python code in the repository."""
87
- print(f"Analyzing repository: {repo_path}")
88
- total_loc: int = count_historical_loc(repo_path)
89
- print(f"\nTotal historical lines of Python code: {total_loc}")
90
-
91
-
92
- @app.command()
93
- def analyze_over_time(repo_path: str = typer.Argument(..., help="Path to the git repository")):
94
- """Analyze a git repository to track Python code size over time with visualization."""
95
- repo: Repo = Repo(repo_path)
96
- branch_name: str = get_default_branch(repo)
97
- print(f"🔍 Using branch: {branch_name}")
98
- commit_data: "List[Dict[str, Any]]" = []
99
- print("⏳ Analyzing commits...")
100
- try:
101
- commits = list(repo.iter_commits(branch_name))
102
- from datetime import timezone
103
-
104
- for commit in track(commits, description="Processing commits..."):
105
- commit_data.append({"hash": commit.hexsha, "dtmExit": datetime.fromtimestamp(commit.committed_date, tz=timezone.utc), "lines": count_python_lines(commit)})
106
- except Exception as e:
107
- print(f"❌ Error analyzing commits: {str(e)}")
108
- return
109
-
110
- import polars as pl
111
- import plotly.graph_objects as go
112
-
113
- df = pl.DataFrame(commit_data)
114
- df = df.sort("dtmExit")
115
- # Create interactive plotly figure with dark theme and all bells and whistles
116
- fig = go.Figure()
117
- # Add line chart with gradient fill and sparkle effect
118
- fig.add_trace(go.Scatter(x=df["dtmExit"], y=df["lines"], mode="lines", line={"width": 3, "color": "#00b4ff"}, fill="tozeroy", fillcolor="rgba(0, 180, 255, 0.2)", name="Lines of Code", hovertemplate="<b>Date:</b> %{x}<br><b>Lines:</b> %{y:,}<extra></extra>"))
119
- # Add markers for significant points (min, max, last)
120
- min_idx = df["lines"].arg_min()
121
- max_idx = df["lines"].arg_max()
122
- min_point = df.slice(min_idx, 1).to_dicts()[0] if min_idx is not None else {}
123
- max_point = df.slice(max_idx, 1).to_dicts()[0] if max_idx is not None else {}
124
- last_point = df.slice(-1, 1).to_dicts()[0]
125
-
126
- # Add markers for significant points
127
- fig.add_trace(
128
- go.Scatter(
129
- x=[min_point["dtmExit"], max_point["dtmExit"], last_point["dtmExit"]],
130
- y=[min_point["lines"], max_point["lines"], last_point["lines"]],
131
- mode="markers",
132
- marker={"size": [10, 14, 12], "color": ["#ff4f4f", "#4fff4f", "#4f4fff"], "line": {"width": 2, "color": "white"}, "symbol": ["circle", "star", "diamond"]},
133
- name="Key Points",
134
- hovertemplate="<b>%{text}</b><br>Date: %{x}<br>Lines: %{y:,}<extra></extra>",
135
- text=[f"🔽 Min: {min_point['lines']:,} lines", f"🔼 Max: {max_point['lines']:,} lines", f"📊 Current: {last_point['lines']:,} lines"],
136
- )
137
- )
138
-
139
- # Add annotation only for current point
140
- # annotations = [
141
- # {"x": last_point['date'], "y": last_point['lines'], "text": f"📊 Current: {last_point['lines']:,} lines", "showarrow": True, "arrowhead": 2, "arrowsize": 1,
142
- # "arrowwidth": 2, "arrowcolor": "#ffffff", "font": {"size": 14, "color": "#ffffff"}, "bgcolor": "#00b4ff", "bordercolor": "#ffffff",
143
- # "borderwidth": 1, "borderpad": 4, "ax": 40, "ay": -40}
144
- # ]
145
-
146
- # Update layout with dark theme and customizations
147
- fig.update_layout(
148
- title={"text": "✨ Python Code Base Size Over Time ✨", "y": 0.95, "x": 0.5, "xanchor": "center", "yanchor": "top", "font": {"size": 24, "color": "white"}},
149
- xaxis_title="Date 📅",
150
- yaxis_title="Lines of Code 📝",
151
- hovermode="closest",
152
- template="plotly_dark",
153
- plot_bgcolor="rgba(25, 25, 35, 1)",
154
- paper_bgcolor="rgba(15, 15, 25, 1)",
155
- font={"family": "Arial, sans-serif", "size": 14, "color": "white"}, # annotations=annotations,
156
- autosize=True,
157
- height=700,
158
- margin={"l": 80, "r": 80, "t": 100, "b": 80},
159
- xaxis={"showgrid": True, "gridcolor": "rgba(80, 80, 100, 0.2)", "showline": True, "linecolor": "rgba(200, 200, 255, 0.2)", "tickfont": {"size": 12}},
160
- yaxis={"showgrid": True, "gridcolor": "rgba(80, 80, 100, 0.2)", "showline": True, "linecolor": "rgba(200, 200, 255, 0.2)", "tickformat": ",", "tickfont": {"size": 12}},
161
- )
162
-
163
- # Add range slider for date selection
164
- fig.update_xaxes(rangeslider_visible=True, rangeslider_thickness=0.05)
165
-
166
- # Save as interactive HTML and static image
167
- plot_dir = Path.home().joinpath("tmp_results", "tmp_images", Path(repo_path).name)
168
- plot_dir.mkdir(parents=True, exist_ok=True)
169
-
170
- html_path = plot_dir.joinpath("code_size_evolution.html")
171
- png_path = plot_dir.joinpath("code_size_evolution.png")
172
-
173
- fig.write_html(html_path, include_plotlyjs="cdn")
174
- fig.write_image(png_path, width=1200, height=700, scale=2)
175
-
176
- print(f"🖼️ Interactive plot saved as {html_path}")
177
- print(f"🖼️ Static image saved as {png_path}")
178
- # Print statistics
179
- print("\n📊 Repository Statistics:")
180
- print(f"📚 Total commits analyzed: {len(df)}")
181
- print(f"🔙 Initial line count: {df['lines'][-1]:,}")
182
- print(f"🔜 Final line count: {df['lines'][0]:,}")
183
- print(f"📈 Net change: {df['lines'][0] - df['lines'][-1]:,} lines")
6
+ from typing import Any, Dict, List, Union, Optional
184
7
 
185
8
 
186
- def _print_python_files_by_size_impl(repo_path: str) -> "Union[pl.DataFrame, Exception]":
9
+ def print_python_files_by_size_impl(repo_path: str) -> "Union[pl.DataFrame, Exception]":
187
10
  import polars as pl
188
11
  import plotly.graph_objects as go
189
12
  import plotly.express as px
@@ -227,13 +50,25 @@ def _print_python_files_by_size_impl(repo_path: str) -> "Union[pl.DataFrame, Exc
227
50
  df = df.sort("lines", descending=True)
228
51
  df = df.filter(pl.col("lines") > 0) # Filter out empty files
229
52
 
53
+ from rich.console import Console
54
+ from rich.table import Table
55
+
230
56
  # Add total count
231
57
  total_lines = int(df["lines"].sum())
232
58
  file_count: int = len(df)
233
-
59
+ console = Console()
234
60
  # Print the DataFrame
235
- print("\n📊 Python Files Line Count (sorted max to min):")
236
- print(df)
61
+ console.print("\n📊 Python Files Line Count (sorted max to min):")
62
+
63
+ table = Table(show_header=True, header_style="bold cyan")
64
+ table.add_column("#", justify="right")
65
+ table.add_column("File", overflow="fold")
66
+ table.add_column("Lines", justify="right")
67
+
68
+ for idx, row in enumerate(df.iter_rows(named=True), 1):
69
+ table.add_row(str(idx), row["filename"], f"{row['lines']:,}")
70
+
71
+ console.print(table)
237
72
  print(f"\n📁 Total Python files: {file_count}")
238
73
  print(f"📝 Total lines of Python code: {total_lines:,}")
239
74
 
@@ -335,14 +170,100 @@ def _print_python_files_by_size_impl(repo_path: str) -> "Union[pl.DataFrame, Exc
335
170
  return Exception(f"❌ Error analyzing repository: {str(e)}")
336
171
 
337
172
 
338
- @app.command()
339
- def print_python_files_by_size(repo_path: str = typer.Argument(..., help="Path to the git repository")):
340
- """Print Python files sorted by size with visualizations."""
341
- result = _print_python_files_by_size_impl(repo_path)
342
- if isinstance(result, Exception):
343
- print(f"Error: {result}")
173
+ def analyze_over_time(repo_path: str):
174
+ """Analyze a git repository to track Python code size over time with visualization."""
175
+ repo: Repo = Repo(repo_path)
176
+ branch_name: str = get_default_branch(repo)
177
+ print(f"🔍 Using branch: {branch_name}")
178
+ commit_data: "List[Dict[str, Any]]" = []
179
+ print("⏳ Analyzing commits...")
180
+ try:
181
+ commits = list(repo.iter_commits(branch_name))
182
+ from datetime import timezone
183
+ from rich.progress import track
184
+ for commit in track(commits, description="Processing commits..."):
185
+ commit_data.append({"hash": commit.hexsha, "dtmExit": datetime.fromtimestamp(commit.committed_date, tz=timezone.utc), "lines": count_python_lines(commit)})
186
+ except Exception as e:
187
+ print(f"❌ Error analyzing commits: {str(e)}")
344
188
  return
345
189
 
190
+ import polars as pl
191
+ import plotly.graph_objects as go
192
+
193
+ df = pl.DataFrame(commit_data)
194
+ df = df.sort("dtmExit")
195
+ # Create interactive plotly figure with dark theme and all bells and whistles
196
+ fig = go.Figure()
197
+ # Add line chart with gradient fill and sparkle effect
198
+ fig.add_trace(go.Scatter(x=df["dtmExit"], y=df["lines"], mode="lines", line={"width": 3, "color": "#00b4ff"}, fill="tozeroy", fillcolor="rgba(0, 180, 255, 0.2)", name="Lines of Code", hovertemplate="<b>Date:</b> %{x}<br><b>Lines:</b> %{y:,}<extra></extra>"))
199
+ # Add markers for significant points (min, max, last)
200
+ min_idx = df["lines"].arg_min()
201
+ max_idx = df["lines"].arg_max()
202
+ min_point = df.slice(min_idx, 1).to_dicts()[0] if min_idx is not None else {}
203
+ max_point = df.slice(max_idx, 1).to_dicts()[0] if max_idx is not None else {}
204
+ last_point = df.slice(-1, 1).to_dicts()[0]
205
+
206
+ # Add markers for significant points
207
+ fig.add_trace(
208
+ go.Scatter(
209
+ x=[min_point["dtmExit"], max_point["dtmExit"], last_point["dtmExit"]],
210
+ y=[min_point["lines"], max_point["lines"], last_point["lines"]],
211
+ mode="markers",
212
+ marker={"size": [10, 14, 12], "color": ["#ff4f4f", "#4fff4f", "#4f4fff"], "line": {"width": 2, "color": "white"}, "symbol": ["circle", "star", "diamond"]},
213
+ name="Key Points",
214
+ hovertemplate="<b>%{text}</b><br>Date: %{x}<br>Lines: %{y:,}<extra></extra>",
215
+ text=[f"🔽 Min: {min_point['lines']:,} lines", f"🔼 Max: {max_point['lines']:,} lines", f"📊 Current: {last_point['lines']:,} lines"],
216
+ )
217
+ )
218
+
219
+ # Add annotation only for current point
220
+ # annotations = [
221
+ # {"x": last_point['date'], "y": last_point['lines'], "text": f"📊 Current: {last_point['lines']:,} lines", "showarrow": True, "arrowhead": 2, "arrowsize": 1,
222
+ # "arrowwidth": 2, "arrowcolor": "#ffffff", "font": {"size": 14, "color": "#ffffff"}, "bgcolor": "#00b4ff", "bordercolor": "#ffffff",
223
+ # "borderwidth": 1, "borderpad": 4, "ax": 40, "ay": -40}
224
+ # ]
346
225
 
347
- if __name__ == "__main__":
348
- app()
226
+ # Update layout with dark theme and customizations
227
+ fig.update_layout(
228
+ title={"text": "✨ Python Code Base Size Over Time ✨", "y": 0.95, "x": 0.5, "xanchor": "center", "yanchor": "top", "font": {"size": 24, "color": "white"}},
229
+ xaxis_title="Date 📅",
230
+ yaxis_title="Lines of Code 📝",
231
+ hovermode="closest",
232
+ template="plotly_dark",
233
+ plot_bgcolor="rgba(25, 25, 35, 1)",
234
+ paper_bgcolor="rgba(15, 15, 25, 1)",
235
+ font={"family": "Arial, sans-serif", "size": 14, "color": "white"}, # annotations=annotations,
236
+ autosize=True,
237
+ height=700,
238
+ margin={"l": 80, "r": 80, "t": 100, "b": 80},
239
+ xaxis={"showgrid": True, "gridcolor": "rgba(80, 80, 100, 0.2)", "showline": True, "linecolor": "rgba(200, 200, 255, 0.2)", "tickfont": {"size": 12}},
240
+ yaxis={"showgrid": True, "gridcolor": "rgba(80, 80, 100, 0.2)", "showline": True, "linecolor": "rgba(200, 200, 255, 0.2)", "tickformat": ",", "tickfont": {"size": 12}},
241
+ )
242
+
243
+ # Add range slider for date selection
244
+ fig.update_xaxes(rangeslider_visible=True, rangeslider_thickness=0.05)
245
+
246
+ # Save as interactive HTML and static image
247
+ plot_dir = Path.home().joinpath("tmp_results", "tmp_images", Path(repo_path).name)
248
+ plot_dir.mkdir(parents=True, exist_ok=True)
249
+
250
+ html_path = plot_dir.joinpath("code_size_evolution.html")
251
+ png_path = plot_dir.joinpath("code_size_evolution.png")
252
+
253
+ try:
254
+ fig.write_html(html_path, include_plotlyjs="cdn")
255
+ except Exception as e:
256
+ print(f"❌ Error saving HTML plot: {str(e)}")
257
+ try:
258
+ fig.write_image(png_path, width=1200, height=700, scale=2)
259
+ except Exception as e:
260
+ print(f"❌ Error saving PNG plot: {str(e)}")
261
+
262
+ print(f"🖼️ Interactive plot saved as {html_path}")
263
+ print(f"🖼️ Static image saved as {png_path}")
264
+ # Print statistics
265
+ print("\n📊 Repository Statistics:")
266
+ print(f"📚 Total commits analyzed: {len(df)}")
267
+ print(f"🔙 Initial line count: {df['lines'][-1]:,}")
268
+ print(f"🔜 Final line count: {df['lines'][0]:,}")
269
+ print(f"📈 Net change: {df['lines'][0] - df['lines'][-1]:,} lines")
@@ -0,0 +1,66 @@
1
+ from machineconfig.utils.path_extended import PathExtended
2
+ import platform
3
+ from pathlib import Path
4
+ from rich.console import Console
5
+ from rich.panel import Panel
6
+
7
+ console = Console()
8
+
9
+
10
+ def get_zellij_cmd(wd1: Path, wd2: Path) -> str:
11
+ _ = wd1, wd2
12
+ lines = [
13
+ """ zellij action new-tab --name gitdiff""",
14
+ """zellij action new-pane --direction down --name local --cwd ./data """,
15
+ """zellij action write-chars "cd '{wd1}'; git status" """,
16
+ """zellij action move-focus up; zellij action close-pane """,
17
+ """zellij action new-pane --direction down --name remote --cwd code """,
18
+ """zellij action write-chars "cd '{wd2}' """,
19
+ """git status" """,
20
+ ]
21
+ return "; ".join(lines)
22
+
23
+ def delete_remote_repo_copy_and_push_local(remote_repo: str, local_repo: str, cloud: str):
24
+ console.print(Panel("🗑️ Deleting remote repo copy and pushing local copy", title="[bold blue]Repo Sync[/bold blue]", border_style="blue"))
25
+ repo_sync_root = PathExtended(remote_repo).expanduser().absolute()
26
+ repo_root_path = PathExtended(local_repo).expanduser().absolute()
27
+ repo_sync_root.delete(sure=True)
28
+ print("🧹 Removed temporary remote copy")
29
+ from git.remote import Remote
30
+ from git.repo import Repo
31
+
32
+ try:
33
+ Remote.remove(Repo(repo_root_path), "originEnc")
34
+ console.print(Panel("🔗 Removed originEnc remote reference", border_style="blue"))
35
+ except Exception:
36
+ pass # type: ignore
37
+ console.print(Panel("📈 Deleting remote repository copy and pushing local changes", width=150, border_style="blue"))
38
+
39
+ repo_root_path.to_cloud(cloud=cloud, zip=True, encrypt=True, rel2home=True, os_specific=False)
40
+
41
+ console.print(Panel("✅ Repository successfully pushed to cloud", title="[bold green]Repo Sync[/bold green]", border_style="green"))
42
+
43
+
44
+
45
+ def get_wt_cmd(wd1: PathExtended, wd2: PathExtended) -> str:
46
+ lines = [
47
+ f"""wt --window 0 new-tab --profile pwsh --title "gitdiff" --tabColor `#3b04d1 --startingDirectory {wd1} ` --colorScheme "Solarized Dark" """,
48
+ f"""split-pane --horizontal --profile pwsh --startingDirectory {wd2} --size 0.5 --colorScheme "Tango Dark" -- pwsh -Interactive """,
49
+ ]
50
+ return " `; ".join(lines)
51
+
52
+
53
+ def inspect_repos(repo_local_root: str, repo_remote_root: str):
54
+ console.print(Panel(f"📂 Local: {repo_local_root}\n📂 Remote: {repo_remote_root}", title="[bold blue]🔍 Inspecting Repositories[/bold blue]", border_style="blue"))
55
+
56
+ if platform.system() == "Windows":
57
+ program = get_wt_cmd(wd1=PathExtended(repo_local_root), wd2=PathExtended(repo_local_root))
58
+ elif platform.system() in ["Linux", "Darwin"]:
59
+ program = get_zellij_cmd(wd1=PathExtended(repo_local_root), wd2=PathExtended(repo_remote_root))
60
+ else:
61
+ raise NotImplementedError(f"Platform {platform.system()} not implemented.")
62
+ import tempfile
63
+ with tempfile.NamedTemporaryFile(mode='w', suffix=".sh" if platform.system() != "Windows" else ".ps1", delete=False, encoding='utf-8') as temp_file:
64
+ temp_file.write(program)
65
+ temp_script_path = PathExtended(temp_file.name)
66
+ console.print(Panel(f"🚀 Launching repo inspection tool...\n\n[blue]{temp_script_path}[/blue]", border_style="blue"))
@@ -45,7 +45,7 @@ def run_uv_sync(repo_path: Path) -> bool:
45
45
  try:
46
46
  print(f"🔄 Running uv sync in {repo_path}")
47
47
  # Run uv sync with output directly to terminal (no capture)
48
- subprocess.run(["uv", "sync"], cwd=repo_path, check=True)
48
+ subprocess.run(["uv", "sync", "--no-dev"], cwd=repo_path, check=True)
49
49
  print("✅ uv sync completed successfully")
50
50
  return True
51
51
  except subprocess.CalledProcessError as e:
@@ -65,7 +65,7 @@ def get_file_hash(file_path: Path) -> str | None:
65
65
  return hashlib.sha256(file_path.read_bytes()).hexdigest()
66
66
 
67
67
 
68
- def update_repository(repo: git.Repo, auto_sync: bool, allow_password_prompt: bool) -> RepositoryUpdateResult:
68
+ def update_repository(repo: git.Repo, auto_uv_sync: bool, allow_password_prompt: bool) -> RepositoryUpdateResult:
69
69
  """Update a single repository and return detailed information about what happened."""
70
70
  repo_path = Path(repo.working_dir)
71
71
  print(f"🔄 {'Updating ' + str(repo_path):.^80}")
@@ -253,7 +253,7 @@ def update_repository(repo: git.Repo, auto_sync: bool, allow_password_prompt: bo
253
253
  print(f"✅ Set permissions for {lf_exe_path}")
254
254
 
255
255
  # Run uv sync if dependencies changed and auto_sync is enabled
256
- if result["dependencies_changed"] and auto_sync:
256
+ if result["dependencies_changed"] and auto_uv_sync:
257
257
  result["uv_sync_ran"] = True
258
258
  result["uv_sync_success"] = run_uv_sync(repo_path)
259
259
 
@@ -0,0 +1,65 @@
1
+
2
+
3
+ from typing import Optional, Annotated
4
+ import typer
5
+
6
+
7
+ def create_from_function(
8
+ num_process: Annotated[int, typer.Option(..., "--num-process", "-n", help="Number of parallel processes to run")],
9
+ path: Annotated[str, typer.Option(..., "--path", "-p", help="Path to a Python or Shell script file or a directory containing such files")] = ".",
10
+ function: Annotated[Optional[str], typer.Option(..., "--function", "-f", help="Function to run from the Python file. If not provided, you will be prompted to choose.")] = None,
11
+ ):
12
+ from machineconfig.utils.ve import get_ve_path_and_ipython_profile
13
+ from machineconfig.utils.options import choose_from_options
14
+ from machineconfig.utils.path_helper import match_file_name, sanitize_path
15
+ from machineconfig.utils.accessories import get_repo_root
16
+ from pathlib import Path
17
+
18
+
19
+ path_obj = sanitize_path(path)
20
+ if not path_obj.exists():
21
+ suffixes = {".py"}
22
+ choice_file = match_file_name(sub_string=path, search_root=Path.cwd(), suffixes=suffixes)
23
+ elif path_obj.is_dir():
24
+ from machineconfig.utils.path_helper import search_for_files_of_interest
25
+ print(f"🔍 Searching recursively for Python, PowerShell and Shell scripts in directory `{path_obj}`")
26
+ files = search_for_files_of_interest(path_obj, suffixes={".py", ".sh", ".ps1"})
27
+ print(f"🔍 Got #{len(files)} results.")
28
+ choice_file = choose_from_options(multi=False, options=files, tv=True, msg="Choose one option")
29
+ choice_file = Path(choice_file)
30
+ else:
31
+ choice_file = path_obj
32
+
33
+
34
+ repo_root = get_repo_root(Path(choice_file))
35
+ print(f"💾 Selected file: {choice_file}.\nRepo root: {repo_root}")
36
+ ve_root_from_file, ipy_profile = get_ve_path_and_ipython_profile(choice_file)
37
+ if ipy_profile is None:
38
+ ipy_profile = "default"
39
+ # if ve_root_from_file is None:
40
+ # raise ValueError(f"Could not determine virtual environment for file {choice_file}. Please ensure it is within a recognized project structure.")
41
+ # _activate_ve_line = get_ve_activate_line(ve_root=ve_root_from_file)
42
+ if ve_root_from_file is not None:
43
+ start_dir = Path(ve_root_from_file).parent
44
+ else:
45
+ start_dir = Path.cwd()
46
+
47
+ # ========================= choosing function to run
48
+ if function is None or function.strip() == "":
49
+ from machineconfig.scripts.python.helpers_fire_command.fire_jobs_route_helper import choose_function_or_lines
50
+ choice_function, choice_file, _kwargs_dict = choose_function_or_lines(choice_file, kwargs_dict={})
51
+ else:
52
+ choice_function = function
53
+
54
+ from machineconfig.cluster.sessions_managers.zellij_local import run_zellij_layout
55
+ from machineconfig.utils.schemas.layouts.layout_types import LayoutConfig
56
+ layout: LayoutConfig = {"layoutName": "fireNprocess", "layoutTabs": []}
57
+ for an_arg in range(num_process):
58
+ layout["layoutTabs"].append({
59
+ "tabName": f"tab{an_arg}",
60
+ "startDir": str(start_dir),
61
+ "command": f"uv run python -m fire {choice_file} {choice_function} --idx={an_arg} --idx_max={num_process}"
62
+ })
63
+ print(layout)
64
+ run_zellij_layout(layout_config=layout)
65
+
@@ -0,0 +1,150 @@
1
+
2
+
3
+ from typing import Annotated, Optional
4
+ import typer
5
+ from pathlib import Path
6
+
7
+
8
+ def download(
9
+ url: Annotated[Optional[str], typer.Argument(..., help="The URL to download the file from.")] = None,
10
+ decompress: Annotated[bool, typer.Option(..., "--decompress", "-d", help="Decompress the file if it's an archive.")] = False,
11
+ output: Annotated[Optional[str], typer.Option("--output", "-o", help="The output file path.")] = None,
12
+ output_dir: Annotated[Optional[str], typer.Option("--output-dir", help="Directory to place the downloaded file in.")] = None,
13
+ ) -> Optional["Path"]:
14
+ import subprocess
15
+ from urllib.parse import parse_qs, unquote, urlparse
16
+ from requests import Response
17
+ import requests
18
+ from pathlib import Path
19
+ if url is None:
20
+ typer.echo("❌ Error: URL is required.", err=True)
21
+ return None
22
+ if output is not None and output_dir is not None:
23
+ typer.echo("❌ Error: --output and --output-dir cannot be used together.", err=True)
24
+ return None
25
+ typer.echo(f"📥 Downloading from: {url}")
26
+
27
+ def _sanitize_candidate_filename(name: str) -> Optional[str]:
28
+ candidate = Path(name).name.strip()
29
+ if not candidate or candidate in {".", ".."}:
30
+ return None
31
+ return candidate
32
+
33
+ def _filename_from_content_disposition(header_value: Optional[str]) -> Optional[str]:
34
+ if header_value is None:
35
+ return None
36
+ parts = [segment.strip() for segment in header_value.split(";")]
37
+ for part in parts:
38
+ lower = part.lower()
39
+ if lower.startswith("filename*="):
40
+ value = part.split("=", 1)[1]
41
+ value = value.strip().strip('"')
42
+ if "''" in value:
43
+ value = value.split("''", 1)[1]
44
+ decoded = unquote(value)
45
+ sanitized = _sanitize_candidate_filename(decoded)
46
+ if sanitized is not None:
47
+ return sanitized
48
+ if lower.startswith("filename="):
49
+ value = part.split("=", 1)[1].strip().strip('"')
50
+ decoded = unquote(value)
51
+ sanitized = _sanitize_candidate_filename(decoded)
52
+ if sanitized is not None:
53
+ return sanitized
54
+ return None
55
+
56
+ def _filename_from_url(source_url: str) -> Optional[str]:
57
+ parsed = urlparse(source_url)
58
+ url_candidate = _sanitize_candidate_filename(unquote(Path(parsed.path).name))
59
+ if url_candidate is not None:
60
+ return url_candidate
61
+ query_params = parse_qs(parsed.query, keep_blank_values=True)
62
+ for key, values in query_params.items():
63
+ lower_key = key.lower()
64
+ if "name" in lower_key or "file" in lower_key:
65
+ for value in values:
66
+ sanitized = _sanitize_candidate_filename(unquote(value))
67
+ if sanitized is not None:
68
+ return sanitized
69
+ return None
70
+
71
+ def _resolve_download_path(request_url: str, response: Response, requested_output: Optional[str], requested_output_dir: Optional[str]) -> Path:
72
+ if requested_output is not None:
73
+ return Path(requested_output)
74
+ header_candidate = _filename_from_content_disposition(response.headers.get("content-disposition"))
75
+ if header_candidate is None:
76
+ header_candidate = _filename_from_url(response.url)
77
+ if header_candidate is None:
78
+ header_candidate = _filename_from_url(request_url)
79
+ if header_candidate is None:
80
+ header_candidate = "downloaded_file"
81
+ if requested_output_dir is not None:
82
+ return Path(requested_output_dir) / header_candidate
83
+ return Path(header_candidate)
84
+
85
+ try:
86
+ with requests.get(url, allow_redirects=True, stream=True, timeout=60) as response:
87
+ response.raise_for_status()
88
+ download_path = _resolve_download_path(url, response, output, output_dir)
89
+ download_path.parent.mkdir(parents=True, exist_ok=True)
90
+ total_size_header = response.headers.get("content-length", "0")
91
+ try:
92
+ total_size = int(total_size_header)
93
+ except (TypeError, ValueError):
94
+ total_size = 0
95
+ if total_size <= 0:
96
+ with open(download_path, "wb") as file_handle:
97
+ file_handle.write(response.content)
98
+ else:
99
+ downloaded = 0
100
+ chunk_size = 8192 * 40
101
+ with open(download_path, "wb") as file_handle:
102
+ for chunk in response.iter_content(chunk_size=chunk_size):
103
+ if not chunk:
104
+ continue
105
+ file_handle.write(chunk)
106
+ downloaded += len(chunk)
107
+ progress = (downloaded / total_size) * 100
108
+ typer.echo(f"\r⏬ Progress: {progress:.1f}% ({downloaded}/{total_size} bytes)", nl=False)
109
+ typer.echo()
110
+ except requests.exceptions.RequestException as exception:
111
+ typer.echo(f"❌ Download failed: {exception}", err=True)
112
+ return None
113
+ except OSError as exception:
114
+ typer.echo(f"❌ File write error: {exception}", err=True)
115
+ return None
116
+
117
+ typer.echo(f"✅ Downloaded to: {download_path}")
118
+ result_path: Path = download_path
119
+ if decompress:
120
+ typer.echo(f"📦 Decompressing: {download_path}")
121
+ base_name = download_path.name.split(".", maxsplit=1)[0] # ouch decompresses all (e.g. .tar.gz) in one go.
122
+ if base_name in {"", ".", ".."}:
123
+ base_name = "extracted"
124
+ extract_dir = download_path.parent / base_name
125
+ extract_dir.mkdir(parents=True, exist_ok=True)
126
+ try:
127
+ subprocess.run(
128
+ ["ouch", "decompress", str(download_path), "--dir", str(extract_dir)],
129
+ check=True,
130
+ capture_output=True,
131
+ text=True,
132
+ )
133
+ typer.echo(f"✅ Decompressed to: {extract_dir}")
134
+ if download_path.exists():
135
+ download_path.unlink()
136
+ typer.echo(f"🗑️ Removed archive: {download_path}")
137
+ result_path = extract_dir
138
+ except subprocess.CalledProcessError as exception:
139
+ typer.echo(f"❌ Decompression failed: {exception.stderr}", err=True)
140
+ return None
141
+ except FileNotFoundError:
142
+ typer.echo("❌ Error: ouch command not found. Please install ouch.", err=True)
143
+ typer.echo("💡 Install with: cargo install ouch", err=True)
144
+ return None
145
+
146
+ return result_path.resolve()
147
+
148
+
149
+ if __name__ == "__main__":
150
+ pass