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

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

Potentially problematic release.


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

Files changed (389) hide show
  1. machineconfig/__init__.py +0 -28
  2. machineconfig/cluster/remote/distribute.py +0 -1
  3. machineconfig/cluster/remote/file_manager.py +0 -2
  4. machineconfig/cluster/remote/script_execution.py +0 -1
  5. machineconfig/cluster/sessions_managers/{utils → helpers}/enhanced_command_runner.py +4 -6
  6. machineconfig/cluster/sessions_managers/utils/load_balancer.py +1 -1
  7. machineconfig/cluster/sessions_managers/utils/maker.py +69 -0
  8. machineconfig/cluster/sessions_managers/wt_local.py +114 -289
  9. machineconfig/cluster/sessions_managers/wt_local_manager.py +50 -193
  10. machineconfig/cluster/sessions_managers/wt_remote.py +51 -43
  11. machineconfig/cluster/sessions_managers/wt_remote_manager.py +49 -197
  12. machineconfig/cluster/sessions_managers/wt_utils/layout_generator.py +6 -19
  13. machineconfig/cluster/sessions_managers/wt_utils/manager_persistence.py +52 -0
  14. machineconfig/cluster/sessions_managers/wt_utils/monitoring_helpers.py +50 -0
  15. machineconfig/cluster/sessions_managers/wt_utils/status_reporter.py +4 -2
  16. machineconfig/cluster/sessions_managers/wt_utils/status_reporting.py +76 -0
  17. machineconfig/cluster/sessions_managers/wt_utils/wt_helpers.py +199 -0
  18. machineconfig/cluster/sessions_managers/zellij_local.py +81 -375
  19. machineconfig/cluster/sessions_managers/zellij_local_manager.py +22 -169
  20. machineconfig/cluster/sessions_managers/zellij_remote.py +40 -41
  21. machineconfig/cluster/sessions_managers/zellij_remote_manager.py +13 -10
  22. machineconfig/cluster/sessions_managers/zellij_utils/example_usage.py +4 -8
  23. machineconfig/cluster/sessions_managers/zellij_utils/layout_generator.py +5 -20
  24. machineconfig/cluster/sessions_managers/zellij_utils/process_monitor.py +3 -9
  25. machineconfig/cluster/sessions_managers/zellij_utils/status_reporter.py +3 -1
  26. machineconfig/cluster/sessions_managers/zellij_utils/zellij_local_helper.py +298 -0
  27. machineconfig/cluster/sessions_managers/zellij_utils/zellij_local_helper_restart.py +77 -0
  28. machineconfig/cluster/sessions_managers/zellij_utils/zellij_local_helper_with_panes.py +228 -0
  29. machineconfig/cluster/sessions_managers/zellij_utils/zellij_local_manager_helper.py +165 -0
  30. machineconfig/jobs/{python → installer}/check_installations.py +2 -3
  31. machineconfig/jobs/installer/custom/boxes.py +61 -0
  32. machineconfig/jobs/installer/custom/hx.py +76 -19
  33. machineconfig/jobs/installer/custom_dev/alacritty.py +4 -4
  34. machineconfig/jobs/installer/custom_dev/brave.py +1 -7
  35. machineconfig/jobs/installer/custom_dev/cloudflare_warp_cli.py +23 -0
  36. machineconfig/jobs/installer/custom_dev/code.py +4 -1
  37. machineconfig/jobs/installer/custom_dev/dubdb_adbc.py +30 -0
  38. machineconfig/jobs/installer/custom_dev/nerfont_windows_helper.py +9 -18
  39. machineconfig/jobs/installer/custom_dev/sysabc.py +119 -0
  40. machineconfig/jobs/installer/custom_dev/wezterm.py +2 -19
  41. machineconfig/jobs/installer/installer_data.json +1101 -115
  42. machineconfig/jobs/installer/linux_scripts/brave.sh +4 -14
  43. machineconfig/jobs/installer/linux_scripts/{warp-cli.sh → cloudflare_warp_cli.sh} +5 -17
  44. machineconfig/jobs/installer/linux_scripts/docker.sh +5 -17
  45. machineconfig/jobs/installer/linux_scripts/docker_start.sh +6 -14
  46. machineconfig/jobs/installer/linux_scripts/edge.sh +3 -11
  47. machineconfig/jobs/{linux/msc → installer/linux_scripts}/lid.sh +2 -8
  48. machineconfig/jobs/installer/linux_scripts/nerdfont.sh +5 -17
  49. machineconfig/jobs/{linux/msc → installer/linux_scripts}/network.sh +2 -8
  50. machineconfig/jobs/installer/linux_scripts/q.sh +1 -0
  51. machineconfig/jobs/installer/linux_scripts/redis.sh +6 -17
  52. machineconfig/jobs/installer/linux_scripts/vscode.sh +5 -17
  53. machineconfig/jobs/installer/linux_scripts/wezterm.sh +4 -12
  54. machineconfig/jobs/installer/package_groups.py +108 -180
  55. machineconfig/logger.py +0 -1
  56. machineconfig/profile/backup.toml +49 -0
  57. machineconfig/profile/bash_shell_profiles.md +11 -0
  58. machineconfig/profile/create_helper.py +74 -0
  59. machineconfig/profile/create_links.py +288 -0
  60. machineconfig/profile/create_links_export.py +100 -0
  61. machineconfig/profile/create_shell_profile.py +136 -0
  62. machineconfig/profile/mapper.toml +258 -0
  63. machineconfig/scripts/Restore-ThunderbirdProfile.ps1 +92 -0
  64. machineconfig/scripts/__init__.py +0 -4
  65. machineconfig/scripts/linux/{share_cloud.sh → other/share_cloud.sh} +14 -25
  66. machineconfig/scripts/linux/wrap_mcfg +47 -0
  67. machineconfig/scripts/nu/wrap_mcfg.nu +69 -0
  68. machineconfig/scripts/python/agents.py +92 -103
  69. machineconfig/scripts/python/ai/command_runner/command_runner.sh +9 -0
  70. machineconfig/scripts/python/ai/command_runner/prompt.txt +9 -0
  71. machineconfig/scripts/python/ai/generate_files.py +307 -42
  72. machineconfig/scripts/python/ai/initai.py +3 -28
  73. machineconfig/scripts/python/ai/scripts/lint_and_type_check.ps1 +17 -18
  74. machineconfig/scripts/python/ai/scripts/lint_and_type_check.sh +17 -18
  75. machineconfig/scripts/python/ai/solutions/_shared.py +9 -1
  76. machineconfig/scripts/python/ai/solutions/copilot/instructions/python/dev.instructions.md +1 -1
  77. machineconfig/scripts/python/ai/solutions/copilot/prompts/pyright_fix.md +16 -0
  78. machineconfig/scripts/python/ai/solutions/generic.py +27 -4
  79. machineconfig/scripts/python/ai/vscode_tasks.py +37 -0
  80. machineconfig/scripts/python/cloud.py +29 -0
  81. machineconfig/scripts/python/croshell.py +111 -114
  82. machineconfig/scripts/python/define.py +31 -0
  83. machineconfig/scripts/python/devops.py +44 -103
  84. machineconfig/scripts/python/devops_navigator.py +10 -0
  85. machineconfig/scripts/python/env_manager/__init__.py +1 -0
  86. machineconfig/scripts/python/env_manager/path_manager_backend.py +47 -0
  87. machineconfig/scripts/python/env_manager/path_manager_tui.py +228 -0
  88. machineconfig/scripts/python/explore.py +49 -0
  89. machineconfig/scripts/python/fire_jobs.py +115 -152
  90. machineconfig/scripts/python/ftpx.py +29 -24
  91. machineconfig/scripts/python/helpers_agents/agentic_frameworks/fire_crush.json +14 -0
  92. machineconfig/scripts/python/helpers_agents/agentic_frameworks/fire_crush.py +37 -0
  93. machineconfig/scripts/python/helpers_agents/agentic_frameworks/fire_cursor_agents.py +22 -0
  94. machineconfig/scripts/python/helpers_agents/agentic_frameworks/fire_gemini.py +42 -0
  95. machineconfig/scripts/python/helpers_agents/agentic_frameworks/fire_qwen.py +30 -0
  96. machineconfig/scripts/python/{fire_agents_help_launch.py → helpers_agents/fire_agents_help_launch.py} +34 -44
  97. machineconfig/scripts/python/helpers_agents/fire_agents_helper_types.py +34 -0
  98. machineconfig/scripts/python/helpers_agents/templates/prompt.txt +6 -0
  99. machineconfig/scripts/python/helpers_agents/templates/template.ps1 +14 -0
  100. machineconfig/scripts/python/helpers_agents/templates/template.sh +24 -0
  101. machineconfig/scripts/python/{cloud_copy.py → helpers_cloud/cloud_copy.py} +30 -23
  102. machineconfig/scripts/python/{cloud_mount.py → helpers_cloud/cloud_mount.py} +10 -18
  103. machineconfig/scripts/python/{cloud_sync.py → helpers_cloud/cloud_sync.py} +12 -18
  104. machineconfig/scripts/python/{helpers → helpers_cloud}/helpers2.py +1 -1
  105. machineconfig/scripts/python/helpers_croshell/crosh.py +39 -0
  106. machineconfig/scripts/python/{start_slidev.py → helpers_croshell/start_slidev.py} +2 -2
  107. machineconfig/scripts/python/helpers_devops/cli_config.py +95 -0
  108. machineconfig/scripts/python/helpers_devops/cli_config_dotfile.py +89 -0
  109. machineconfig/scripts/python/helpers_devops/cli_data.py +25 -0
  110. machineconfig/scripts/python/helpers_devops/cli_nw.py +134 -0
  111. machineconfig/scripts/python/helpers_devops/cli_repos.py +182 -0
  112. machineconfig/scripts/python/helpers_devops/cli_self.py +134 -0
  113. machineconfig/scripts/python/helpers_devops/cli_share_file.py +137 -0
  114. machineconfig/scripts/python/helpers_devops/cli_share_server.py +141 -0
  115. machineconfig/scripts/python/{share_terminal.py → helpers_devops/cli_terminal.py} +35 -23
  116. machineconfig/scripts/python/helpers_devops/cli_utils.py +96 -0
  117. machineconfig/scripts/python/{devops_backup_retrieve.py → helpers_devops/devops_backup_retrieve.py} +7 -10
  118. machineconfig/scripts/python/helpers_devops/devops_status.py +511 -0
  119. machineconfig/scripts/python/{devops_update_repos.py → helpers_devops/devops_update_repos.py} +68 -49
  120. machineconfig/scripts/python/helpers_devops/themes/choose_pwsh_theme.ps1 +81 -0
  121. machineconfig/scripts/python/helpers_devops/themes/choose_starship_theme.bash +3 -0
  122. machineconfig/scripts/python/{choose_wezterm_theme.py → helpers_devops/themes/choose_wezterm_theme.py} +2 -2
  123. machineconfig/scripts/python/helpers_fire_command/__init__.py +0 -0
  124. machineconfig/scripts/python/{helpers/helpers4.py → helpers_fire_command/file_wrangler.py} +56 -20
  125. machineconfig/scripts/python/{fire_jobs_args_helper.py → helpers_fire_command/fire_jobs_args_helper.py} +5 -1
  126. machineconfig/scripts/python/{fire_jobs_route_helper.py → helpers_fire_command/fire_jobs_route_helper.py} +47 -2
  127. machineconfig/scripts/python/helpers_fire_command/fire_jobs_streamlit_helper.py +0 -0
  128. machineconfig/scripts/python/helpers_msearch/__init__.py +5 -0
  129. machineconfig/scripts/{linux → python/helpers_msearch/scripts_linux}/fzfag +1 -1
  130. machineconfig/scripts/{linux → python/helpers_msearch/scripts_linux}/fzfg +1 -1
  131. machineconfig/scripts/{linux → python/helpers_msearch/scripts_linux}/fzfrga +1 -1
  132. machineconfig/scripts/python/helpers_navigator/__init__.py +20 -0
  133. machineconfig/scripts/python/helpers_navigator/command_builder.py +111 -0
  134. machineconfig/scripts/python/helpers_navigator/command_detail.py +44 -0
  135. machineconfig/scripts/python/helpers_navigator/command_tree.py +588 -0
  136. machineconfig/scripts/python/helpers_navigator/data_models.py +28 -0
  137. machineconfig/scripts/python/helpers_navigator/main_app.py +272 -0
  138. machineconfig/scripts/python/helpers_navigator/search_bar.py +15 -0
  139. machineconfig/scripts/python/helpers_repos/action.py +209 -0
  140. machineconfig/scripts/python/helpers_repos/action_helper.py +150 -0
  141. machineconfig/scripts/python/{repos_helper_clone.py → helpers_repos/clone.py} +2 -3
  142. machineconfig/scripts/python/helpers_repos/cloud_repo_sync.py +218 -0
  143. machineconfig/scripts/python/{count_lines.py → helpers_repos/count_lines.py} +10 -10
  144. machineconfig/scripts/python/helpers_repos/count_lines_frontend.py +17 -0
  145. machineconfig/scripts/python/{repos_helper.py → helpers_repos/entrypoint.py} +9 -17
  146. machineconfig/scripts/python/helpers_repos/grource.py +340 -0
  147. machineconfig/scripts/python/{repos_helper_record.py → helpers_repos/record.py} +4 -3
  148. machineconfig/scripts/python/helpers_repos/sync.py +66 -0
  149. machineconfig/scripts/python/{repos_helper_update.py → helpers_repos/update.py} +3 -3
  150. machineconfig/scripts/python/helpers_sessions/__init__.py +0 -0
  151. machineconfig/scripts/python/helpers_sessions/sessions_multiprocess.py +58 -0
  152. machineconfig/scripts/python/helpers_utils/download.py +152 -0
  153. machineconfig/scripts/python/helpers_utils/path.py +108 -0
  154. machineconfig/scripts/python/interactive.py +64 -84
  155. machineconfig/scripts/python/machineconfig.py +63 -0
  156. machineconfig/scripts/python/msearch.py +21 -0
  157. machineconfig/scripts/python/nw/__init__.py +0 -0
  158. machineconfig/scripts/python/{devops_add_identity.py → nw/devops_add_identity.py} +0 -2
  159. machineconfig/scripts/python/{devops_add_ssh_key.py → nw/devops_add_ssh_key.py} +73 -43
  160. machineconfig/scripts/{linux → python/nw}/mount_nfs +1 -1
  161. machineconfig/scripts/python/{mount_nfs.py → nw/mount_nfs.py} +3 -3
  162. machineconfig/scripts/{linux → python/nw}/mount_nw_drive +1 -2
  163. machineconfig/scripts/python/{mount_ssh.py → nw/mount_ssh.py} +3 -3
  164. machineconfig/scripts/python/{onetimeshare.py → nw/onetimeshare.py} +0 -1
  165. machineconfig/scripts/python/nw/ssh_debug_linux.py +391 -0
  166. machineconfig/scripts/python/nw/ssh_debug_windows.py +338 -0
  167. machineconfig/scripts/python/{wifi_conn.py → nw/wifi_conn.py} +1 -53
  168. machineconfig/scripts/python/{wsl_windows_transfer.py → nw/wsl_windows_transfer.py} +5 -4
  169. machineconfig/scripts/python/sessions.py +64 -44
  170. machineconfig/scripts/python/terminal.py +127 -0
  171. machineconfig/scripts/python/utils.py +66 -0
  172. machineconfig/scripts/windows/{mount_nfs.ps1 → mounts/mount_nfs.ps1} +1 -3
  173. machineconfig/scripts/windows/{mount_ssh.ps1 → mounts/mount_ssh.ps1} +1 -1
  174. machineconfig/scripts/windows/{share_smb.ps1 → mounts/share_smb.ps1} +0 -6
  175. machineconfig/scripts/windows/wrap_mcfg.ps1 +60 -0
  176. machineconfig/settings/broot/br.sh +0 -4
  177. machineconfig/settings/broot/conf.toml +1 -1
  178. machineconfig/settings/helix/config.toml +16 -0
  179. machineconfig/settings/helix/languages.toml +13 -4
  180. machineconfig/settings/helix/yazi-picker.sh +12 -0
  181. machineconfig/settings/lf/linux/exe/lfcd.sh +1 -0
  182. machineconfig/settings/lf/linux/exe/previewer.sh +9 -3
  183. machineconfig/settings/lf/linux/lfrc +10 -12
  184. machineconfig/settings/lf/windows/fzf_edit.ps1 +2 -2
  185. machineconfig/settings/lf/windows/lfrc +18 -38
  186. machineconfig/settings/lf/windows/mkfile.ps1 +1 -1
  187. machineconfig/settings/linters/.ruff.toml +1 -1
  188. machineconfig/settings/lvim/windows/archive/config_additional.lua +0 -6
  189. machineconfig/settings/marimo/marimo.toml +80 -0
  190. machineconfig/settings/marimo/snippets/globalize.py +34 -0
  191. machineconfig/settings/pistol/pistol.conf +1 -1
  192. machineconfig/settings/shells/bash/init.sh +55 -31
  193. machineconfig/settings/shells/nushell/config.nu +1 -34
  194. machineconfig/settings/shells/nushell/init.nu +127 -0
  195. machineconfig/settings/shells/pwsh/init.ps1 +60 -43
  196. machineconfig/settings/shells/starship/starship.toml +16 -0
  197. machineconfig/settings/shells/wezterm/wezterm.lua +2 -0
  198. machineconfig/settings/shells/wt/settings.json +32 -17
  199. machineconfig/settings/shells/zsh/init.sh +89 -0
  200. machineconfig/settings/svim/linux/init.toml +0 -4
  201. machineconfig/settings/svim/windows/init.toml +0 -3
  202. machineconfig/settings/yazi/init.lua +57 -0
  203. machineconfig/settings/yazi/keymap_linux.toml +79 -0
  204. machineconfig/settings/yazi/keymap_windows.toml +78 -0
  205. machineconfig/settings/yazi/shell/yazi_cd.ps1 +33 -0
  206. machineconfig/settings/yazi/shell/yazi_cd.sh +8 -0
  207. machineconfig/settings/yazi/yazi.toml +13 -0
  208. machineconfig/setup_linux/__init__.py +10 -0
  209. machineconfig/setup_linux/apps_desktop.sh +89 -0
  210. machineconfig/setup_linux/apps_gui.sh +64 -0
  211. machineconfig/setup_linux/{nix → others}/cli_installation.sh +9 -29
  212. machineconfig/setup_linux/ssh/openssh_all.sh +25 -0
  213. machineconfig/setup_linux/ssh/openssh_wsl.sh +38 -0
  214. machineconfig/setup_linux/uv.sh +15 -0
  215. machineconfig/setup_linux/web_shortcuts/interactive.sh +26 -6
  216. machineconfig/setup_mac/__init__.py +16 -0
  217. machineconfig/setup_mac/apps_gui.sh +248 -0
  218. machineconfig/setup_mac/ssh/openssh_setup.sh +114 -0
  219. machineconfig/setup_mac/uv.sh +36 -0
  220. machineconfig/setup_windows/__init__.py +8 -0
  221. machineconfig/setup_windows/others/power_options.ps1 +7 -0
  222. machineconfig/setup_windows/ssh/add-sshkey.ps1 +29 -0
  223. machineconfig/setup_windows/ssh/add_identity.ps1 +11 -0
  224. machineconfig/setup_windows/ssh/openssh-server.ps1 +37 -0
  225. machineconfig/setup_windows/uv.ps1 +10 -0
  226. machineconfig/setup_windows/web_shortcuts/interactive.ps1 +27 -10
  227. machineconfig/setup_windows/web_shortcuts/quick_init.ps1 +16 -0
  228. machineconfig/utils/accessories.py +7 -5
  229. machineconfig/utils/cloud/onedrive/README.md +139 -0
  230. machineconfig/utils/code.py +133 -106
  231. machineconfig/utils/files/art/fat_croco.txt +10 -0
  232. machineconfig/utils/files/art/halfwit_croco.txt +9 -0
  233. machineconfig/utils/files/art/happy_croco.txt +22 -0
  234. machineconfig/utils/files/art/water_croco.txt +11 -0
  235. machineconfig/utils/files/ascii_art.py +1 -1
  236. machineconfig/utils/files/dbms.py +257 -0
  237. machineconfig/utils/files/headers.py +11 -14
  238. machineconfig/utils/files/ouch/__init__.py +0 -0
  239. machineconfig/utils/files/ouch/decompress.py +45 -0
  240. machineconfig/utils/files/read.py +10 -18
  241. machineconfig/utils/installer_utils/installer_class.py +68 -126
  242. machineconfig/utils/installer_utils/{installer.py → installer_cli.py} +109 -117
  243. machineconfig/utils/installer_utils/{installer_abc.py → installer_locator_utils.py} +31 -81
  244. machineconfig/utils/{installer.py → installer_utils/installer_runner.py} +44 -74
  245. machineconfig/utils/io.py +77 -23
  246. machineconfig/utils/links.py +254 -162
  247. machineconfig/utils/meta.py +255 -0
  248. machineconfig/utils/notifications.py +1 -1
  249. machineconfig/utils/options.py +13 -3
  250. machineconfig/utils/path_extended.py +46 -100
  251. machineconfig/utils/path_helper.py +75 -22
  252. machineconfig/utils/procs.py +50 -70
  253. machineconfig/utils/scheduler.py +94 -97
  254. machineconfig/utils/scheduling.py +0 -3
  255. machineconfig/utils/schemas/fire_agents/fire_agents_input.py +1 -1
  256. machineconfig/utils/schemas/layouts/layout_types.py +1 -1
  257. machineconfig/utils/source_of_truth.py +3 -6
  258. machineconfig/utils/ssh.py +742 -264
  259. machineconfig/utils/ssh_utils/utils.py +0 -0
  260. machineconfig/utils/terminal.py +2 -113
  261. machineconfig/utils/tst.py +20 -0
  262. machineconfig/utils/upgrade_packages.py +109 -28
  263. machineconfig/utils/ve.py +11 -4
  264. machineconfig-7.66.dist-info/METADATA +124 -0
  265. machineconfig-7.66.dist-info/RECORD +451 -0
  266. machineconfig-7.66.dist-info/entry_points.txt +15 -0
  267. machineconfig/cluster/sessions_managers/ffile.py +0 -4
  268. machineconfig/jobs/installer/linux_scripts/pgsql.sh +0 -49
  269. machineconfig/jobs/installer/linux_scripts/timescaledb.sh +0 -85
  270. machineconfig/jobs/linux/msc/cli_agents.sh +0 -16
  271. machineconfig/jobs/python/python_ve_symlink.py +0 -37
  272. machineconfig/jobs/python/vscode/api.py +0 -57
  273. machineconfig/jobs/python/vscode/sync_code.py +0 -73
  274. machineconfig/jobs/windows/archive/archive_pygraphviz.ps1 +0 -14
  275. machineconfig/jobs/windows/start_terminal.ps1 +0 -6
  276. machineconfig/jobs/windows/startup_file.cmd +0 -2
  277. machineconfig/profile/create.py +0 -303
  278. machineconfig/profile/shell.py +0 -176
  279. machineconfig/scripts/cloud/init.sh +0 -119
  280. machineconfig/scripts/linux/agents +0 -2
  281. machineconfig/scripts/linux/choose_wezterm_theme +0 -3
  282. machineconfig/scripts/linux/cloud_copy +0 -2
  283. machineconfig/scripts/linux/cloud_mount +0 -2
  284. machineconfig/scripts/linux/cloud_repo_sync +0 -2
  285. machineconfig/scripts/linux/cloud_sync +0 -2
  286. machineconfig/scripts/linux/croshell +0 -3
  287. machineconfig/scripts/linux/devops +0 -2
  288. machineconfig/scripts/linux/fire +0 -2
  289. machineconfig/scripts/linux/ftpx +0 -2
  290. machineconfig/scripts/linux/fzf2g +0 -21
  291. machineconfig/scripts/linux/fzffg +0 -25
  292. machineconfig/scripts/linux/gh_models +0 -2
  293. machineconfig/scripts/linux/initai +0 -2
  294. machineconfig/scripts/linux/kill_process +0 -2
  295. machineconfig/scripts/linux/scheduler +0 -2
  296. machineconfig/scripts/linux/sessions +0 -2
  297. machineconfig/scripts/linux/share_smb +0 -1
  298. machineconfig/scripts/linux/start_slidev +0 -2
  299. machineconfig/scripts/linux/start_terminals +0 -3
  300. machineconfig/scripts/linux/warp-cli.sh +0 -122
  301. machineconfig/scripts/linux/wifi_conn +0 -2
  302. machineconfig/scripts/linux/z_ls +0 -104
  303. machineconfig/scripts/python/ai/solutions/copilot/prompts/allLintersAndTypeCheckers.prompt.md +0 -5
  304. machineconfig/scripts/python/cloud_repo_sync.py +0 -190
  305. machineconfig/scripts/python/count_lines_frontend.py +0 -16
  306. machineconfig/scripts/python/dotfile.py +0 -78
  307. machineconfig/scripts/python/fire_agents_helper_types.py +0 -12
  308. machineconfig/scripts/python/get_zellij_cmd.py +0 -15
  309. machineconfig/scripts/python/gh_models.py +0 -104
  310. machineconfig/scripts/python/helpers/repo_sync_helpers.py +0 -116
  311. machineconfig/scripts/python/repos.py +0 -132
  312. machineconfig/scripts/python/repos_helper_action.py +0 -378
  313. machineconfig/scripts/python/snapshot.py +0 -25
  314. machineconfig/scripts/python/start_terminals.py +0 -121
  315. machineconfig/scripts/python/t4.py +0 -17
  316. machineconfig/scripts/windows/agents.ps1 +0 -1
  317. machineconfig/scripts/windows/choose_wezterm_theme.ps1 +0 -1
  318. machineconfig/scripts/windows/cloud_copy.ps1 +0 -1
  319. machineconfig/scripts/windows/cloud_mount.ps1 +0 -1
  320. machineconfig/scripts/windows/cloud_repo_sync.ps1 +0 -1
  321. machineconfig/scripts/windows/cloud_sync.ps1 +0 -1
  322. machineconfig/scripts/windows/croshell.ps1 +0 -1
  323. machineconfig/scripts/windows/devops.ps1 +0 -1
  324. machineconfig/scripts/windows/dotfile.ps1 +0 -1
  325. machineconfig/scripts/windows/fire.ps1 +0 -1
  326. machineconfig/scripts/windows/ftpx.ps1 +0 -1
  327. machineconfig/scripts/windows/gpt.ps1 +0 -1
  328. machineconfig/scripts/windows/grep.ps1 +0 -2
  329. machineconfig/scripts/windows/initai.ps1 +0 -1
  330. machineconfig/scripts/windows/kill_process.ps1 +0 -1
  331. machineconfig/scripts/windows/nano.ps1 +0 -3
  332. machineconfig/scripts/windows/pomodoro.ps1 +0 -1
  333. machineconfig/scripts/windows/reload_path.ps1 +0 -3
  334. machineconfig/scripts/windows/scheduler.ps1 +0 -1
  335. machineconfig/scripts/windows/sessions.ps1 +0 -1
  336. machineconfig/scripts/windows/snapshot.ps1 +0 -1
  337. machineconfig/scripts/windows/start_slidev.ps1 +0 -1
  338. machineconfig/scripts/windows/start_terminals.ps1 +0 -1
  339. machineconfig/scripts/windows/wifi_conn.ps1 +0 -2
  340. machineconfig/scripts/windows/wsl_rdp_windows_port_forwarding.ps1 +0 -46
  341. machineconfig/scripts/windows/wsl_ssh_windows_port_forwarding.ps1 +0 -76
  342. machineconfig/settings/lf/linux/exe/fzf_nano.sh +0 -16
  343. machineconfig/setup_linux/others/openssh-server_add_pub_key.sh +0 -57
  344. machineconfig/setup_linux/web_shortcuts/croshell.sh +0 -11
  345. machineconfig/setup_linux/web_shortcuts/ssh.sh +0 -52
  346. machineconfig/setup_windows/web_shortcuts/all.ps1 +0 -18
  347. machineconfig/setup_windows/web_shortcuts/ascii_art.ps1 +0 -36
  348. machineconfig/setup_windows/web_shortcuts/croshell.ps1 +0 -16
  349. machineconfig/setup_windows/web_shortcuts/ssh.ps1 +0 -11
  350. machineconfig/utils/ai/generate_file_checklist.py +0 -68
  351. machineconfig-5.15.dist-info/METADATA +0 -188
  352. machineconfig-5.15.dist-info/RECORD +0 -415
  353. machineconfig-5.15.dist-info/entry_points.txt +0 -18
  354. machineconfig/cluster/sessions_managers/{utils → helpers}/load_balancer_helper.py +0 -0
  355. machineconfig/scripts/linux/{share_nfs → other/share_nfs} +0 -0
  356. machineconfig/scripts/linux/{start_docker → other/start_docker} +0 -0
  357. machineconfig/scripts/linux/{switch_ip → other/switch_ip} +0 -0
  358. machineconfig/{jobs/python → scripts/python/helpers_agents}/__init__.py +0 -0
  359. machineconfig/scripts/python/{helpers → helpers_agents/agentic_frameworks}/__init__.py +0 -0
  360. machineconfig/scripts/python/{fire_agents_help_search.py → helpers_agents/fire_agents_help_search.py} +0 -0
  361. machineconfig/scripts/python/{fire_agents_load_balancer.py → helpers_agents/fire_agents_load_balancer.py} +0 -0
  362. machineconfig/{jobs/windows/msc/cli_agents.bat → scripts/python/helpers_cloud/__init__.py} +0 -0
  363. machineconfig/scripts/python/{helpers → helpers_cloud}/cloud_helpers.py +1 -1
  364. /machineconfig/scripts/python/{helpers → helpers_cloud}/helpers5.py +0 -0
  365. /machineconfig/{jobs/windows/msc/cli_agents.ps1 → scripts/python/helpers_croshell/__init__.py} +0 -0
  366. /machineconfig/scripts/python/{pomodoro.py → helpers_croshell/pomodoro.py} +0 -0
  367. /machineconfig/scripts/python/{scheduler.py → helpers_croshell/scheduler.py} +0 -0
  368. /machineconfig/scripts/python/{viewer.py → helpers_croshell/viewer.py} +0 -0
  369. /machineconfig/scripts/python/{viewer_template.py → helpers_croshell/viewer_template.py} +0 -0
  370. /machineconfig/scripts/python/{fire_jobs_streamlit_helper.py → helpers_devops/__init__.py} +0 -0
  371. /machineconfig/scripts/{windows/share_nfs.ps1 → python/helpers_devops/themes/__init__.py} +0 -0
  372. /machineconfig/{settings/yazi/keymap.toml → scripts/python/helpers_devops/themes/choose_starship_theme.ps1} +0 -0
  373. /machineconfig/scripts/python/{cloud_manager.py → helpers_fire_command/cloud_manager.py} +0 -0
  374. /machineconfig/scripts/{linux → python/helpers_msearch/scripts_linux}/skrg +0 -0
  375. /machineconfig/scripts/{windows → python/helpers_msearch/scripts_windows}/fzfb.ps1 +0 -0
  376. /machineconfig/scripts/{windows → python/helpers_msearch/scripts_windows}/fzfg.ps1 +0 -0
  377. /machineconfig/scripts/{windows → python/helpers_msearch/scripts_windows}/fzfrga.bat +0 -0
  378. /machineconfig/scripts/{linux → python/nw}/mount_drive +0 -0
  379. /machineconfig/scripts/python/{mount_nw_drive.py → nw/mount_nw_drive.py} +0 -0
  380. /machineconfig/scripts/{linux → python/nw}/mount_smb +0 -0
  381. /machineconfig/scripts/windows/{mount_nw.ps1 → mounts/mount_nw.ps1} +0 -0
  382. /machineconfig/scripts/windows/{mount_smb.ps1 → mounts/mount_smb.ps1} +0 -0
  383. /machineconfig/scripts/windows/{share_cloud.cmd → mounts/share_cloud.cmd} +0 -0
  384. /machineconfig/scripts/windows/{unlock_bitlocker.ps1 → mounts/unlock_bitlocker.ps1} +0 -0
  385. /machineconfig/setup_linux/{web_shortcuts → others}/android.sh +0 -0
  386. /machineconfig/{jobs/windows/archive → setup_windows/ssh}/openssh-server_add_key.ps1 +0 -0
  387. /machineconfig/{jobs/windows/archive → setup_windows/ssh}/openssh-server_copy-ssh-id.ps1 +0 -0
  388. {machineconfig-5.15.dist-info → machineconfig-7.66.dist-info}/WHEEL +0 -0
  389. {machineconfig-5.15.dist-info → machineconfig-7.66.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,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,58 @@
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_activate_line, 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, fzf=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
+
42
+ _activate_ve_line = get_ve_activate_line(ve_root=ve_root_from_file)
43
+
44
+ # ========================= choosing function to run
45
+ if function is None or function.strip() == "":
46
+ from machineconfig.scripts.python.helpers_fire_command.fire_jobs_route_helper import choose_function_or_lines
47
+ choice_function, choice_file, _kwargs_dict = choose_function_or_lines(choice_file, kwargs_dict={})
48
+ else:
49
+ choice_function = function
50
+
51
+ from machineconfig.cluster.sessions_managers.zellij_local import run_zellij_layout
52
+ from machineconfig.utils.schemas.layouts.layout_types import LayoutConfig
53
+ layout: LayoutConfig = {"layoutName": "fireNprocess", "layoutTabs": []}
54
+ for an_arg in range(num_process):
55
+ layout["layoutTabs"].append({"tabName": f"tab{an_arg}", "startDir": str(Path.cwd()), "command": f"uv run -m fire {choice_file} {choice_function} --idx={an_arg} --idx_max={num_process}"})
56
+ print(layout)
57
+ run_zellij_layout(layout_config=layout)
58
+
@@ -0,0 +1,152 @@
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
+
15
+ import subprocess
16
+ from urllib.parse import parse_qs, unquote, urlparse
17
+ from requests import Response
18
+ import requests
19
+ from pathlib import Path
20
+ if url is None:
21
+ typer.echo("❌ Error: URL is required.", err=True)
22
+ return None
23
+ if output is not None and output_dir is not None:
24
+ typer.echo("❌ Error: --output and --output-dir cannot be used together.", err=True)
25
+ return None
26
+ typer.echo(f"📥 Downloading from: {url}")
27
+
28
+ def _sanitize_candidate_filename(name: str) -> Optional[str]:
29
+ candidate = Path(name).name.strip()
30
+ if not candidate or candidate in {".", ".."}:
31
+ return None
32
+ return candidate
33
+
34
+ def _filename_from_content_disposition(header_value: Optional[str]) -> Optional[str]:
35
+ if header_value is None:
36
+ return None
37
+ parts = [segment.strip() for segment in header_value.split(";")]
38
+ for part in parts:
39
+ lower = part.lower()
40
+ if lower.startswith("filename*="):
41
+ value = part.split("=", 1)[1]
42
+ value = value.strip().strip('"')
43
+ if "''" in value:
44
+ value = value.split("''", 1)[1]
45
+ decoded = unquote(value)
46
+ sanitized = _sanitize_candidate_filename(decoded)
47
+ if sanitized is not None:
48
+ return sanitized
49
+ if lower.startswith("filename="):
50
+ value = part.split("=", 1)[1].strip().strip('"')
51
+ decoded = unquote(value)
52
+ sanitized = _sanitize_candidate_filename(decoded)
53
+ if sanitized is not None:
54
+ return sanitized
55
+ return None
56
+
57
+ def _filename_from_url(source_url: str) -> Optional[str]:
58
+ parsed = urlparse(source_url)
59
+ url_candidate = _sanitize_candidate_filename(unquote(Path(parsed.path).name))
60
+ if url_candidate is not None:
61
+ return url_candidate
62
+ query_params = parse_qs(parsed.query, keep_blank_values=True)
63
+ for key, values in query_params.items():
64
+ lower_key = key.lower()
65
+ if "name" in lower_key or "file" in lower_key:
66
+ for value in values:
67
+ sanitized = _sanitize_candidate_filename(unquote(value))
68
+ if sanitized is not None:
69
+ return sanitized
70
+ return None
71
+
72
+ def _resolve_download_path(request_url: str, response: Response, requested_output: Optional[str], requested_output_dir: Optional[str]) -> Path:
73
+ if requested_output is not None:
74
+ return Path(requested_output)
75
+ header_candidate = _filename_from_content_disposition(response.headers.get("content-disposition"))
76
+ if header_candidate is None:
77
+ header_candidate = _filename_from_url(response.url)
78
+ if header_candidate is None:
79
+ header_candidate = _filename_from_url(request_url)
80
+ if header_candidate is None:
81
+ header_candidate = "downloaded_file"
82
+ if requested_output_dir is not None:
83
+ return Path(requested_output_dir) / header_candidate
84
+ return Path(header_candidate)
85
+
86
+ try:
87
+ with requests.get(url, allow_redirects=True, stream=True, timeout=60) as response:
88
+ response.raise_for_status()
89
+ download_path = _resolve_download_path(url, response, output, output_dir)
90
+ download_path.parent.mkdir(parents=True, exist_ok=True)
91
+ total_size_header = response.headers.get("content-length", "0")
92
+ try:
93
+ total_size = int(total_size_header)
94
+ except (TypeError, ValueError):
95
+ total_size = 0
96
+ if total_size <= 0:
97
+ with open(download_path, "wb") as file_handle:
98
+ file_handle.write(response.content)
99
+ else:
100
+ downloaded = 0
101
+ chunk_size = 8192 * 4
102
+ with open(download_path, "wb") as file_handle:
103
+ for chunk in response.iter_content(chunk_size=chunk_size):
104
+ if not chunk:
105
+ continue
106
+ file_handle.write(chunk)
107
+ downloaded += len(chunk)
108
+ progress = (downloaded / total_size) * 100
109
+ typer.echo(f"\r⏬ Progress: {progress:.1f}% ({downloaded}/{total_size} bytes)", nl=False)
110
+ typer.echo()
111
+ except requests.exceptions.RequestException as exception:
112
+ typer.echo(f"❌ Download failed: {exception}", err=True)
113
+ return None
114
+ except OSError as exception:
115
+ typer.echo(f"❌ File write error: {exception}", err=True)
116
+ return None
117
+
118
+ typer.echo(f"✅ Downloaded to: {download_path}")
119
+ result_path: Path = download_path
120
+
121
+ if decompress:
122
+ typer.echo(f"📦 Decompressing: {download_path}")
123
+ base_name = download_path.stem
124
+ if base_name in {"", ".", ".."}:
125
+ base_name = "extracted"
126
+ extract_dir = download_path.parent / base_name
127
+ extract_dir.mkdir(parents=True, exist_ok=True)
128
+ try:
129
+ subprocess.run(
130
+ ["ouch", "decompress", str(download_path), "--dir", str(extract_dir)],
131
+ check=True,
132
+ capture_output=True,
133
+ text=True,
134
+ )
135
+ typer.echo(f"✅ Decompressed to: {extract_dir}")
136
+ if download_path.exists():
137
+ download_path.unlink()
138
+ typer.echo(f"🗑️ Removed archive: {download_path}")
139
+ result_path = extract_dir
140
+ except subprocess.CalledProcessError as exception:
141
+ typer.echo(f"❌ Decompression failed: {exception.stderr}", err=True)
142
+ return None
143
+ except FileNotFoundError:
144
+ typer.echo("❌ Error: ouch command not found. Please install ouch.", err=True)
145
+ typer.echo("💡 Install with: cargo install ouch", err=True)
146
+ return None
147
+
148
+ return result_path.resolve()
149
+
150
+
151
+ if __name__ == "__main__":
152
+ pass