machineconfig 6.82__py3-none-any.whl → 8.51__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 (461) hide show
  1. machineconfig/cluster/remote/cloud_manager.py +1 -1
  2. machineconfig/cluster/remote/run_cluster.py +1 -1
  3. machineconfig/cluster/remote/run_remote.py +1 -1
  4. machineconfig/cluster/sessions_managers/utils/maker.py +29 -15
  5. machineconfig/cluster/sessions_managers/wt_local.py +17 -222
  6. machineconfig/cluster/sessions_managers/wt_local_manager.py +56 -194
  7. machineconfig/cluster/sessions_managers/wt_remote_manager.py +42 -198
  8. machineconfig/cluster/sessions_managers/wt_utils/manager_persistence.py +52 -0
  9. machineconfig/cluster/sessions_managers/wt_utils/monitoring_helpers.py +50 -0
  10. machineconfig/cluster/sessions_managers/wt_utils/status_reporting.py +76 -0
  11. machineconfig/cluster/sessions_managers/wt_utils/wt_helpers.py +199 -0
  12. machineconfig/cluster/sessions_managers/zellij_local.py +1 -1
  13. machineconfig/cluster/sessions_managers/zellij_local_manager.py +4 -2
  14. machineconfig/cluster/sessions_managers/zellij_remote_manager.py +3 -2
  15. machineconfig/cluster/sessions_managers/zellij_utils/process_monitor.py +2 -2
  16. machineconfig/jobs/installer/checks/check_installations.py +133 -0
  17. machineconfig/jobs/installer/checks/install_utils.py +132 -0
  18. machineconfig/jobs/installer/checks/report_utils.py +39 -0
  19. machineconfig/jobs/installer/checks/vt_utils.py +89 -0
  20. machineconfig/jobs/installer/installer_data.json +1500 -310
  21. machineconfig/jobs/installer/linux_scripts/docker.sh +6 -9
  22. machineconfig/jobs/installer/linux_scripts/q.sh +10 -7
  23. machineconfig/jobs/installer/linux_scripts/redis.sh +1 -0
  24. machineconfig/jobs/installer/package_groups.py +62 -91
  25. machineconfig/jobs/installer/powershell_scripts/install_fonts.ps1 +129 -34
  26. machineconfig/jobs/installer/{custom → python_scripts}/boxes.py +2 -3
  27. machineconfig/jobs/installer/{custom_dev → python_scripts}/brave.py +5 -3
  28. machineconfig/jobs/installer/python_scripts/cloudflare_warp_cli.py +23 -0
  29. machineconfig/jobs/installer/{custom_dev → python_scripts}/code.py +14 -9
  30. machineconfig/jobs/installer/{custom_dev → python_scripts}/dubdb_adbc.py +1 -1
  31. machineconfig/jobs/installer/python_scripts/hx.py +214 -0
  32. machineconfig/jobs/installer/{custom_dev → python_scripts}/nerdfont.py +2 -2
  33. machineconfig/jobs/installer/{custom_dev → python_scripts}/nerfont_windows_helper.py +32 -26
  34. machineconfig/jobs/installer/python_scripts/sysabc.py +145 -0
  35. machineconfig/jobs/installer/{custom_dev → python_scripts}/wezterm.py +2 -19
  36. machineconfig/jobs/installer/{custom_dev → python_scripts}/winget.py +10 -14
  37. machineconfig/jobs/installer/python_scripts/yazi.py +139 -0
  38. machineconfig/{scripts/python/nw → jobs/scripts/bash_scripts}/mount_nfs +0 -1
  39. machineconfig/jobs/scripts/powershell_scripts/cmatrix.ps1 +52 -0
  40. machineconfig/jobs/scripts/powershell_scripts/mount_ssh.ps1 +13 -0
  41. machineconfig/jobs/scripts/powershell_scripts/obs.ps1 +4 -0
  42. machineconfig/jobs/scripts_dynamic/a.py +428 -0
  43. machineconfig/logger.py +1 -2
  44. machineconfig/profile/create_helper.py +56 -18
  45. machineconfig/profile/create_links.py +79 -21
  46. machineconfig/profile/create_links_export.py +87 -36
  47. machineconfig/profile/create_shell_profile.py +92 -127
  48. machineconfig/profile/mapper_data.toml +45 -0
  49. machineconfig/profile/mapper_dotfiles.toml +249 -0
  50. machineconfig/scripts/__init__.py +0 -4
  51. machineconfig/scripts/linux/wrap_mcfg +46 -0
  52. machineconfig/scripts/nu/wrap_mcfg.nu +69 -0
  53. machineconfig/scripts/python/agents.py +85 -165
  54. machineconfig/scripts/python/ai/initai.py +4 -2
  55. machineconfig/scripts/python/ai/scripts/__init__.py +1 -0
  56. machineconfig/scripts/python/ai/scripts/command_runner.ps1 +33 -0
  57. machineconfig/scripts/python/ai/{command_runner → scripts}/command_runner.sh +1 -1
  58. machineconfig/scripts/python/ai/scripts/lint_and_type_check.ps1 +2 -0
  59. machineconfig/scripts/python/ai/scripts/lint_and_type_check.sh +8 -6
  60. machineconfig/scripts/python/ai/solutions/claude/claude.py +1 -1
  61. machineconfig/scripts/python/ai/solutions/cline/cline.py +1 -1
  62. machineconfig/scripts/python/ai/solutions/copilot/{chatmodes/Thinking-Beast-Mode.chatmode.md → agents/Thinking-Beast-Mode.agent.md} +0 -1
  63. machineconfig/scripts/python/ai/solutions/copilot/{chatmodes/Ultimate-Transparent-Thinking-Beast-Mode.chatmode.md → agents/Ultimate-Transparent-Thinking-Beast-Mode.agent.md} +0 -1
  64. machineconfig/scripts/python/ai/solutions/copilot/{chatmodes/deepResearch.chatmode.md → agents/deepResearch.agent.md} +2 -2
  65. machineconfig/scripts/python/ai/solutions/copilot/github_copilot.py +6 -6
  66. machineconfig/scripts/python/ai/solutions/copilot/instructions/python/dev.instructions.md +33 -0
  67. machineconfig/scripts/python/ai/solutions/copilot/instructions/python/watch_exec.prompt.md +20 -0
  68. machineconfig/scripts/python/ai/solutions/crush/crush.py +1 -1
  69. machineconfig/scripts/python/ai/solutions/cursor/cursors.py +1 -1
  70. machineconfig/scripts/python/ai/solutions/gemini/gemini.py +1 -1
  71. machineconfig/scripts/python/ai/solutions/gemini/settings.json +3 -0
  72. machineconfig/scripts/python/ai/{generate_files.py → utils/generate_files.py} +2 -2
  73. machineconfig/scripts/python/ai/{solutions → utils}/generic.py +2 -15
  74. machineconfig/scripts/python/ai/{vscode_tasks.py → utils/vscode_tasks.py} +13 -5
  75. machineconfig/scripts/python/cloud.py +58 -11
  76. machineconfig/scripts/python/croshell.py +10 -162
  77. machineconfig/scripts/python/devops.py +73 -36
  78. machineconfig/scripts/python/devops_navigator.py +16 -6
  79. machineconfig/scripts/python/fire_jobs.py +8 -222
  80. machineconfig/scripts/python/ftpx.py +7 -200
  81. machineconfig/scripts/python/graph/cli_graph.json +8743 -0
  82. machineconfig/scripts/python/{env_manager → helper_env}/path_manager_tui.py +2 -2
  83. machineconfig/scripts/python/helpers/helper_env/env_manager_tui.py +204 -0
  84. machineconfig/scripts/python/helpers/helper_env/path_manager_tui.py +228 -0
  85. machineconfig/scripts/python/{helpers_fire → helpers/helpers_agents}/agentic_frameworks/fire_crush.json +1 -1
  86. machineconfig/scripts/python/helpers/helpers_agents/agentic_frameworks/fire_crush.py +39 -0
  87. machineconfig/scripts/python/{helpers_fire → helpers/helpers_agents}/agentic_frameworks/fire_cursor_agents.py +3 -4
  88. machineconfig/scripts/python/helpers/helpers_agents/agentic_frameworks/fire_gemini.py +55 -0
  89. machineconfig/scripts/python/helpers/helpers_agents/agentic_frameworks/fire_qwen.py +30 -0
  90. machineconfig/scripts/python/helpers/helpers_agents/agents_impl.py +168 -0
  91. machineconfig/scripts/python/{helpers_fire → helpers/helpers_agents}/fire_agents_help_launch.py +38 -16
  92. machineconfig/scripts/python/{helpers_fire → helpers/helpers_agents}/fire_agents_helper_types.py +11 -14
  93. machineconfig/scripts/python/helpers/helpers_agents/privacy/configs/aichat/config.yaml +5 -0
  94. machineconfig/scripts/python/helpers/helpers_agents/privacy/configs/aider/.aider.conf.yml +2 -0
  95. machineconfig/scripts/python/helpers/helpers_agents/privacy/configs/copilot/config.yml +1 -0
  96. machineconfig/scripts/python/helpers/helpers_agents/privacy/configs/crush/crush.json +10 -0
  97. machineconfig/scripts/python/helpers/helpers_agents/privacy/configs/gemini/settings.json +12 -0
  98. machineconfig/scripts/python/helpers/helpers_agents/privacy/privacy.py +109 -0
  99. machineconfig/scripts/python/helpers/helpers_agents/templates/prompt.txt +10 -0
  100. machineconfig/scripts/python/helpers/helpers_agents/templates/template.sh +34 -0
  101. machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/cloud_copy.py +32 -25
  102. machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/cloud_mount.py +29 -22
  103. machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/cloud_sync.py +9 -8
  104. machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/helpers2.py +1 -1
  105. machineconfig/scripts/python/{helpers_croshell → helpers/helpers_croshell}/crosh.py +3 -3
  106. machineconfig/scripts/python/helpers/helpers_croshell/croshell_impl.py +225 -0
  107. machineconfig/scripts/python/{helpers_croshell → helpers/helpers_croshell}/scheduler.py +4 -4
  108. machineconfig/scripts/python/{helpers_croshell → helpers/helpers_croshell}/start_slidev.py +12 -12
  109. machineconfig/scripts/python/helpers/helpers_devops/backup_config.py +149 -0
  110. machineconfig/scripts/python/helpers/helpers_devops/cli_backup_retrieve.py +262 -0
  111. machineconfig/scripts/python/helpers/helpers_devops/cli_config.py +98 -0
  112. machineconfig/scripts/python/helpers/helpers_devops/cli_config_dotfile.py +274 -0
  113. machineconfig/scripts/python/helpers/helpers_devops/cli_data.py +67 -0
  114. machineconfig/scripts/python/helpers/helpers_devops/cli_nw.py +201 -0
  115. machineconfig/scripts/python/helpers/helpers_devops/cli_repos.py +274 -0
  116. machineconfig/scripts/python/helpers/helpers_devops/cli_self.py +197 -0
  117. machineconfig/scripts/python/helpers/helpers_devops/cli_share_file.py +151 -0
  118. machineconfig/scripts/python/helpers/helpers_devops/cli_share_server.py +125 -0
  119. machineconfig/scripts/python/{helpers_devops/cli_terminal.py → helpers/helpers_devops/cli_share_terminal.py} +26 -22
  120. machineconfig/scripts/python/helpers/helpers_devops/cli_ssh.py +167 -0
  121. machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/devops_status.py +17 -23
  122. machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/devops_update_repos.py +1 -1
  123. machineconfig/scripts/python/{interactive.py → helpers/helpers_devops/interactive.py} +78 -71
  124. machineconfig/scripts/python/helpers/helpers_devops/run_script.py +197 -0
  125. machineconfig/scripts/python/helpers/helpers_devops/themes/choose_starship_theme.ps1 +41 -0
  126. machineconfig/scripts/python/helpers/helpers_devops/themes/choose_starship_theme.sh +48 -0
  127. machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/themes/choose_wezterm_theme.py +4 -4
  128. machineconfig/scripts/python/{helpers_fire/helpers4.py → helpers/helpers_fire_command/file_wrangler.py} +57 -20
  129. machineconfig/scripts/python/{helpers_fire_command → helpers/helpers_fire_command}/fire_jobs_args_helper.py +1 -0
  130. machineconfig/scripts/python/helpers/helpers_fire_command/fire_jobs_impl.py +233 -0
  131. machineconfig/scripts/python/{helpers_fire_command → helpers/helpers_fire_command}/fire_jobs_route_helper.py +26 -16
  132. machineconfig/scripts/python/helpers/helpers_msearch/__init__.py +5 -0
  133. machineconfig/scripts/python/helpers/helpers_msearch/msearch_impl.py +248 -0
  134. machineconfig/scripts/{linux → python/helpers/helpers_msearch/scripts_linux}/fzfg +6 -5
  135. machineconfig/scripts/python/helpers/helpers_msearch/scripts_linux/search_with_context.sh +48 -0
  136. machineconfig/scripts/python/helpers/helpers_msearch/scripts_windows/fzfg.ps1 +59 -0
  137. machineconfig/scripts/python/helpers/helpers_navigator/__init__.py +20 -0
  138. machineconfig/scripts/python/helpers/helpers_navigator/cli_graph_loader.py +234 -0
  139. machineconfig/scripts/python/{helpers_navigator → helpers/helpers_navigator}/command_builder.py +61 -13
  140. machineconfig/scripts/python/helpers/helpers_navigator/command_detail.py +153 -0
  141. machineconfig/scripts/python/helpers/helpers_navigator/command_tree.py +45 -0
  142. machineconfig/scripts/python/{helpers_navigator → helpers/helpers_navigator}/data_models.py +18 -11
  143. machineconfig/scripts/python/{helpers_navigator → helpers/helpers_navigator}/main_app.py +5 -5
  144. machineconfig/scripts/python/helpers/helpers_network/address.py +174 -0
  145. machineconfig/scripts/python/helpers/helpers_network/address_switch.py +78 -0
  146. machineconfig/scripts/python/helpers/helpers_network/ftpx_impl.py +276 -0
  147. machineconfig/scripts/python/{nw → helpers/helpers_network}/mount_nfs.py +2 -2
  148. machineconfig/scripts/python/{nw → helpers/helpers_network}/mount_ssh.py +3 -3
  149. machineconfig/scripts/python/helpers/helpers_network/ssh_add_identity.py +73 -0
  150. machineconfig/scripts/python/helpers/helpers_network/ssh_add_ssh_key.py +175 -0
  151. machineconfig/scripts/python/helpers/helpers_network/ssh_debug_linux.py +319 -0
  152. machineconfig/scripts/python/helpers/helpers_network/ssh_debug_windows.py +275 -0
  153. machineconfig/scripts/python/{nw → helpers/helpers_network}/wifi_conn.py +1 -53
  154. machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/action.py +3 -3
  155. machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/action_helper.py +3 -3
  156. machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/clone.py +0 -1
  157. machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/cloud_repo_sync.py +159 -48
  158. machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/grource.py +4 -3
  159. machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/record.py +33 -12
  160. machineconfig/scripts/python/helpers/helpers_repos/repo_analyzer_1.py +160 -0
  161. machineconfig/scripts/python/{helpers_repos/count_lines.py → helpers/helpers_repos/repo_analyzer_2.py} +156 -191
  162. machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/update.py +0 -6
  163. machineconfig/scripts/python/helpers/helpers_search/ast_search.py +74 -0
  164. machineconfig/scripts/python/helpers/helpers_search/qr_code.py +166 -0
  165. machineconfig/scripts/python/helpers/helpers_search/repo_rag.py +325 -0
  166. machineconfig/scripts/python/helpers/helpers_search/script_help.py +81 -0
  167. machineconfig/scripts/python/helpers/helpers_search/symantic_search.py +25 -0
  168. machineconfig/scripts/python/helpers/helpers_sessions/__init__.py +0 -0
  169. machineconfig/scripts/python/helpers/helpers_sessions/sessions_impl.py +186 -0
  170. machineconfig/scripts/python/{helpers_sessions → helpers/helpers_sessions}/sessions_multiprocess.py +20 -14
  171. machineconfig/scripts/python/helpers/helpers_terminal/__init__.py +0 -0
  172. machineconfig/scripts/python/helpers/helpers_terminal/terminal_impl.py +96 -0
  173. machineconfig/scripts/python/helpers/helpers_utils/download.py +150 -0
  174. machineconfig/scripts/python/helpers/helpers_utils/pdf.py +96 -0
  175. machineconfig/scripts/python/helpers/helpers_utils/python.py +210 -0
  176. machineconfig/scripts/python/helpers/helpers_utils/specs.py +246 -0
  177. machineconfig/scripts/python/mcfg_entry.py +143 -0
  178. machineconfig/scripts/python/msearch.py +26 -0
  179. machineconfig/scripts/python/sessions.py +69 -135
  180. machineconfig/scripts/python/terminal.py +58 -0
  181. machineconfig/scripts/python/utils.py +115 -38
  182. machineconfig/scripts/windows/wrap_mcfg.ps1 +63 -0
  183. machineconfig/settings/atuin/config.toml +294 -0
  184. machineconfig/settings/atuin/themes/catppuccin-mocha-mauve.toml +12 -0
  185. machineconfig/settings/broot/conf.toml +1 -1
  186. machineconfig/settings/helix/config.toml +16 -0
  187. machineconfig/settings/helix/languages.toml +13 -4
  188. machineconfig/settings/helix/yazi-picker.sh +12 -0
  189. machineconfig/settings/lf/linux/exe/lfcd.sh +1 -0
  190. machineconfig/settings/lf/linux/exe/previewer.sh +3 -2
  191. machineconfig/settings/lf/windows/lfcd.ps1 +1 -1
  192. machineconfig/settings/lf/windows/lfrc +14 -16
  193. machineconfig/settings/linters/.ruff.toml +2 -1
  194. machineconfig/settings/marimo/marimo.toml +1 -1
  195. machineconfig/settings/marimo/snippets/globalize.py +34 -0
  196. machineconfig/settings/mprocs/windows/mprocs.yaml +2 -2
  197. machineconfig/settings/shells/bash/init.sh +47 -12
  198. machineconfig/settings/shells/ipy/profiles/default/startup/playext.py +1 -1
  199. machineconfig/settings/shells/nushell/config.nu +25 -33
  200. machineconfig/settings/shells/nushell/env.nu +21 -8
  201. machineconfig/settings/shells/nushell/init.nu +138 -0
  202. machineconfig/settings/shells/pwsh/init.ps1 +111 -17
  203. machineconfig/settings/shells/pwsh/search_pwsh_history.ps1 +99 -0
  204. machineconfig/settings/shells/starship/starship.toml +16 -0
  205. machineconfig/settings/shells/wezterm/wezterm.lua +6 -1
  206. machineconfig/settings/shells/wt/settings.json +27 -18
  207. machineconfig/settings/shells/zsh/init.sh +42 -23
  208. machineconfig/settings/television/cable_unix/alias.toml +8 -0
  209. machineconfig/settings/television/cable_unix/aws-buckets.toml +14 -0
  210. machineconfig/settings/television/cable_unix/aws-instances.toml +13 -0
  211. machineconfig/settings/television/cable_unix/bash-history.toml +8 -0
  212. machineconfig/settings/television/cable_unix/channels.toml +19 -0
  213. machineconfig/settings/television/cable_unix/dirs.toml +13 -0
  214. machineconfig/settings/television/cable_unix/distrobox-list.toml +42 -0
  215. machineconfig/settings/television/cable_unix/docker-images.toml +13 -0
  216. machineconfig/settings/television/cable_unix/dotfiles.toml +11 -0
  217. machineconfig/settings/television/cable_unix/env.toml +17 -0
  218. machineconfig/settings/television/cable_unix/files.toml +11 -0
  219. machineconfig/settings/television/cable_unix/fish-history.toml +8 -0
  220. machineconfig/settings/television/cable_unix/git-branch.toml +11 -0
  221. machineconfig/settings/television/cable_unix/git-diff.toml +10 -0
  222. machineconfig/settings/television/cable_unix/git-log.toml +12 -0
  223. machineconfig/settings/television/cable_unix/git-reflog.toml +12 -0
  224. machineconfig/settings/television/cable_unix/git-repos.toml +16 -0
  225. machineconfig/settings/television/cable_unix/guix.toml +20 -0
  226. machineconfig/settings/television/cable_unix/just-recipes.toml +18 -0
  227. machineconfig/settings/television/cable_unix/k8s-deployments.toml +36 -0
  228. machineconfig/settings/television/cable_unix/k8s-pods.toml +50 -0
  229. machineconfig/settings/television/cable_unix/k8s-services.toml +36 -0
  230. machineconfig/settings/television/cable_unix/man-pages.toml +24 -0
  231. machineconfig/settings/television/cable_unix/nu-history.toml +7 -0
  232. machineconfig/settings/television/cable_unix/procs.toml +20 -0
  233. machineconfig/settings/television/cable_unix/text.toml +17 -0
  234. machineconfig/settings/television/cable_unix/tldr.toml +18 -0
  235. machineconfig/settings/television/cable_unix/zsh-history.toml +9 -0
  236. machineconfig/settings/television/cable_windows/alias.toml +7 -0
  237. machineconfig/settings/television/cable_windows/dirs.toml +13 -0
  238. machineconfig/settings/television/cable_windows/docker-images.toml +13 -0
  239. machineconfig/settings/television/cable_windows/dotfiles.toml +11 -0
  240. machineconfig/settings/television/cable_windows/env.toml +17 -0
  241. machineconfig/settings/television/cable_windows/files.toml +14 -0
  242. machineconfig/settings/television/cable_windows/git-branch.toml +11 -0
  243. machineconfig/settings/television/cable_windows/git-diff.toml +10 -0
  244. machineconfig/settings/television/cable_windows/git-log.toml +11 -0
  245. machineconfig/settings/television/cable_windows/git-reflog.toml +11 -0
  246. machineconfig/settings/television/cable_windows/git-repos.toml +15 -0
  247. machineconfig/settings/television/cable_windows/nu-history.toml +7 -0
  248. machineconfig/settings/television/cable_windows/pwsh-history.toml +6 -0
  249. machineconfig/settings/television/cable_windows/text.toml +17 -0
  250. machineconfig/settings/tv/config.toml +234 -0
  251. machineconfig/settings/tv/themes/catppuccin-mocha-sky.toml +22 -0
  252. machineconfig/settings/wsl/.wslconfig +5 -30
  253. machineconfig/settings/wt/__init__.py +0 -0
  254. machineconfig/settings/yazi/init.lua +61 -0
  255. machineconfig/settings/yazi/keymap_linux.toml +94 -0
  256. machineconfig/settings/yazi/keymap_windows.toml +78 -0
  257. machineconfig/settings/yazi/shell/yazi_cd.ps1 +33 -0
  258. machineconfig/settings/yazi/shell/yazi_cd.sh +8 -0
  259. machineconfig/settings/yazi/theme.toml +4 -0
  260. machineconfig/settings/yazi/yazi_linux.toml +94 -0
  261. machineconfig/settings/yazi/yazi_windows.toml +58 -0
  262. machineconfig/settings/zellij/layouts/st.kdl +40 -9
  263. machineconfig/settings/zellij/layouts/st2.kdl +1 -1
  264. machineconfig/setup_linux/__init__.py +2 -2
  265. machineconfig/setup_linux/apps_desktop.sh +8 -27
  266. machineconfig/setup_linux/web_shortcuts/interactive.sh +27 -12
  267. machineconfig/setup_linux/web_shortcuts/live_from_github.sh +34 -0
  268. machineconfig/setup_mac/__init__.py +1 -4
  269. machineconfig/setup_mac/apps_gui.sh +248 -0
  270. machineconfig/setup_windows/__init__.py +2 -5
  271. machineconfig/setup_windows/uv.ps1 +8 -1
  272. machineconfig/setup_windows/web_shortcuts/interactive.ps1 +28 -12
  273. machineconfig/setup_windows/web_shortcuts/live_from_github.ps1 +31 -0
  274. machineconfig/setup_windows/web_shortcuts/quick_init.ps1 +17 -0
  275. machineconfig/type_hinting/sql/__init__.py +1 -0
  276. machineconfig/type_hinting/sql/base.py +216 -0
  277. machineconfig/type_hinting/sql/core_schema.py +64 -0
  278. machineconfig/type_hinting/sql/core_schema_typeddict.py +41 -0
  279. machineconfig/type_hinting/sql/typeddict_codegen.py +222 -0
  280. machineconfig/type_hinting/typedict/__init__.py +1 -0
  281. machineconfig/type_hinting/typedict/ast_utils.py +130 -0
  282. machineconfig/type_hinting/typedict/generator_helpers.py +319 -0
  283. machineconfig/type_hinting/typedict/generators.py +231 -0
  284. machineconfig/type_hinting/typedict/polars_schema.py +24 -0
  285. machineconfig/type_hinting/typedict/polars_schema_typeddict.py +63 -0
  286. machineconfig/utils/accessories.py +31 -4
  287. machineconfig/utils/code.py +163 -51
  288. machineconfig/utils/files/ascii_art.py +11 -15
  289. machineconfig/utils/files/headers.py +6 -7
  290. machineconfig/utils/files/read.py +8 -1
  291. machineconfig/utils/installer_utils/github_release_bulk.py +95 -138
  292. machineconfig/utils/installer_utils/github_release_scraper.py +99 -0
  293. machineconfig/utils/installer_utils/install_from_url.py +183 -0
  294. machineconfig/utils/installer_utils/installer_class.py +53 -102
  295. machineconfig/utils/installer_utils/installer_cli.py +161 -0
  296. machineconfig/utils/installer_utils/installer_helper.py +129 -0
  297. machineconfig/utils/installer_utils/{installer_abc.py → installer_locator_utils.py} +42 -91
  298. machineconfig/utils/{installer.py → installer_utils/installer_runner.py} +20 -65
  299. machineconfig/utils/io.py +94 -9
  300. machineconfig/utils/links.py +56 -38
  301. machineconfig/utils/meta.py +38 -21
  302. machineconfig/utils/options.py +81 -23
  303. machineconfig/utils/options_utils/__init__.py +0 -0
  304. machineconfig/utils/options_utils/options_tv_linux.py +211 -0
  305. machineconfig/utils/options_utils/options_tv_windows.py +88 -0
  306. machineconfig/utils/options_utils/tv_options.py +37 -0
  307. machineconfig/utils/path_extended.py +52 -102
  308. machineconfig/utils/path_helper.py +76 -23
  309. machineconfig/utils/procs.py +1 -1
  310. machineconfig/utils/scheduler.py +26 -53
  311. machineconfig/utils/scheduling.py +0 -2
  312. machineconfig/utils/schemas/fire_agents/fire_agents_input.py +1 -1
  313. machineconfig/utils/schemas/layouts/layout_types.py +1 -1
  314. machineconfig/utils/source_of_truth.py +6 -1
  315. machineconfig/utils/ssh.py +216 -419
  316. machineconfig/utils/ssh_utils/abc.py +5 -0
  317. machineconfig/utils/ssh_utils/copy_from_here.py +116 -0
  318. machineconfig/utils/ssh_utils/copy_to_here.py +303 -0
  319. machineconfig/utils/ssh_utils/utils.py +158 -0
  320. machineconfig/utils/ssh_utils/wsl.py +147 -0
  321. machineconfig/utils/ssh_utils/wsl_helper.py +217 -0
  322. machineconfig/utils/terminal.py +1 -0
  323. machineconfig/utils/upgrade_packages.py +107 -35
  324. machineconfig/utils/ve.py +12 -4
  325. machineconfig-8.51.dist-info/METADATA +140 -0
  326. machineconfig-8.51.dist-info/RECORD +543 -0
  327. {machineconfig-6.82.dist-info → machineconfig-8.51.dist-info}/entry_points.txt +4 -1
  328. machineconfig/jobs/installer/check_installations.py +0 -248
  329. machineconfig/jobs/installer/custom/hx.py +0 -140
  330. machineconfig/jobs/installer/linux_scripts/pgsql.sh +0 -41
  331. machineconfig/jobs/installer/linux_scripts/timescaledb.sh +0 -71
  332. machineconfig/jobs/installer/powershell_scripts/archive_pygraphviz.ps1 +0 -12
  333. machineconfig/jobs/installer/powershell_scripts/openssh-server_add_key.ps1 +0 -7
  334. machineconfig/jobs/installer/powershell_scripts/openssh-server_copy-ssh-id.ps1 +0 -14
  335. machineconfig/profile/backup.toml +0 -49
  336. machineconfig/profile/mapper.toml +0 -256
  337. machineconfig/scripts/linux/fzf2g +0 -21
  338. machineconfig/scripts/linux/fzfag +0 -17
  339. machineconfig/scripts/linux/fzffg +0 -25
  340. machineconfig/scripts/linux/fzfrga +0 -21
  341. machineconfig/scripts/linux/mcfgs +0 -38
  342. machineconfig/scripts/linux/other/share_smb +0 -1
  343. machineconfig/scripts/linux/other/switch_ip +0 -20
  344. machineconfig/scripts/linux/skrg +0 -4
  345. machineconfig/scripts/linux/warp-cli.sh +0 -122
  346. machineconfig/scripts/linux/z_ls +0 -104
  347. machineconfig/scripts/python/ai/command_runner/prompt.txt +0 -9
  348. machineconfig/scripts/python/helpers_devops/cli_config.py +0 -120
  349. machineconfig/scripts/python/helpers_devops/cli_config_dotfile.py +0 -77
  350. machineconfig/scripts/python/helpers_devops/cli_data.py +0 -25
  351. machineconfig/scripts/python/helpers_devops/cli_nw.py +0 -73
  352. machineconfig/scripts/python/helpers_devops/cli_repos.py +0 -181
  353. machineconfig/scripts/python/helpers_devops/cli_self.py +0 -122
  354. machineconfig/scripts/python/helpers_devops/cli_share_server.py +0 -104
  355. machineconfig/scripts/python/helpers_devops/cli_utils.py +0 -221
  356. machineconfig/scripts/python/helpers_devops/devops_backup_retrieve.py +0 -80
  357. machineconfig/scripts/python/helpers_devops/themes/choose_starship_theme.bash +0 -3
  358. machineconfig/scripts/python/helpers_fire/agentic_frameworks/fire_crush.py +0 -37
  359. machineconfig/scripts/python/helpers_fire/agentic_frameworks/fire_gemini.py +0 -44
  360. machineconfig/scripts/python/helpers_fire/agentic_frameworks/fire_qwen.py +0 -43
  361. machineconfig/scripts/python/helpers_fire/prompt.txt +0 -2
  362. machineconfig/scripts/python/helpers_fire/template.sh +0 -15
  363. machineconfig/scripts/python/helpers_navigator/__init__.py +0 -20
  364. machineconfig/scripts/python/helpers_navigator/command_detail.py +0 -44
  365. machineconfig/scripts/python/helpers_navigator/command_tree.py +0 -588
  366. machineconfig/scripts/python/helpers_repos/count_lines_frontend.py +0 -17
  367. machineconfig/scripts/python/helpers_repos/entrypoint.py +0 -76
  368. machineconfig/scripts/python/helpers_repos/secure_repo.py +0 -15
  369. machineconfig/scripts/python/mcfg.py +0 -48
  370. machineconfig/scripts/python/nw/add_ssh_key.py +0 -148
  371. machineconfig/scripts/python/nw/devops_add_identity.py +0 -82
  372. machineconfig/scripts/python/nw/devops_add_ssh_key.py +0 -134
  373. machineconfig/scripts/python/nw/ssh_debug_linux.py +0 -391
  374. machineconfig/scripts/python/nw/ssh_debug_windows.py +0 -338
  375. machineconfig/scripts/python/nw/wsl_windows_transfer.py +0 -66
  376. machineconfig/scripts/windows/fzfb.ps1 +0 -3
  377. machineconfig/scripts/windows/fzfg.ps1 +0 -2
  378. machineconfig/scripts/windows/fzfrga.bat +0 -20
  379. machineconfig/scripts/windows/mcfgs.ps1 +0 -17
  380. machineconfig/scripts/windows/mounts/mount_ssh.ps1 +0 -13
  381. machineconfig/settings/lf/linux/exe/fzf_nano.sh +0 -16
  382. machineconfig/settings/lf/windows/fzf_edit.ps1 +0 -6
  383. machineconfig/settings/lf/windows/tst.ps1 +0 -1
  384. machineconfig/settings/yazi/yazi.toml +0 -4
  385. machineconfig/setup_linux/apps.sh +0 -66
  386. machineconfig/setup_linux/others/cli_installation.sh +0 -137
  387. machineconfig/setup_linux/others/mint_keyboard_shortcuts.sh +0 -30
  388. machineconfig/setup_linux/ssh/openssh_all.sh +0 -25
  389. machineconfig/setup_linux/ssh/openssh_wsl.sh +0 -38
  390. machineconfig/setup_mac/apps.sh +0 -73
  391. machineconfig/setup_mac/ssh/openssh_setup.sh +0 -114
  392. machineconfig/setup_windows/apps.ps1 +0 -62
  393. machineconfig/setup_windows/others/obs.ps1 +0 -4
  394. machineconfig/setup_windows/ssh/add-sshkey.ps1 +0 -29
  395. machineconfig/setup_windows/ssh/add_identity.ps1 +0 -11
  396. machineconfig/setup_windows/ssh/openssh-server.ps1 +0 -37
  397. machineconfig/utils/installer_utils/installer.py +0 -225
  398. machineconfig/utils/tst.py +0 -20
  399. machineconfig-6.82.dist-info/METADATA +0 -82
  400. machineconfig-6.82.dist-info/RECORD +0 -441
  401. machineconfig/jobs/installer/{custom_dev → checks}/__init__.py +0 -0
  402. machineconfig/jobs/installer/linux_scripts/{warp-cli.sh → cloudflare_warp_cli.sh} +0 -0
  403. machineconfig/{scripts/python/helpers_cloud → jobs/installer/python_scripts}/__init__.py +0 -0
  404. machineconfig/jobs/installer/{custom_dev → python_scripts}/alacritty.py +0 -0
  405. machineconfig/jobs/installer/{custom_dev → python_scripts}/bypass_paywall.py +0 -0
  406. machineconfig/jobs/installer/{custom_dev → python_scripts}/cursor.py +0 -0
  407. machineconfig/jobs/installer/{custom_dev → python_scripts}/espanso.py +0 -0
  408. machineconfig/jobs/installer/{custom → python_scripts}/gh.py +0 -0
  409. machineconfig/jobs/installer/{custom_dev → python_scripts}/goes.py +0 -0
  410. machineconfig/jobs/installer/{custom_dev → python_scripts}/lvim.py +0 -0
  411. machineconfig/jobs/installer/{custom_dev → python_scripts}/redis.py +0 -0
  412. machineconfig/{setup_linux/others → jobs/scripts/bash_scripts}/android.sh +0 -0
  413. machineconfig/jobs/{installer/linux_scripts → scripts/bash_scripts}/lid.sh +0 -0
  414. machineconfig/{scripts/python/nw → jobs/scripts/bash_scripts}/mount_drive +0 -0
  415. machineconfig/{scripts/python/nw → jobs/scripts/bash_scripts}/mount_nw_drive +0 -0
  416. machineconfig/{scripts/python/nw → jobs/scripts/bash_scripts}/mount_smb +0 -0
  417. machineconfig/{scripts/linux/other → jobs/scripts/bash_scripts}/share_cloud.sh +0 -0
  418. machineconfig/{scripts/linux/other → jobs/scripts/bash_scripts}/share_nfs +0 -0
  419. machineconfig/{scripts/linux/other → jobs/scripts/bash_scripts}/start_docker +0 -0
  420. machineconfig/{scripts → jobs/scripts/powershell_scripts}/Restore-ThunderbirdProfile.ps1 +0 -0
  421. machineconfig/{setup_windows/others → jobs/scripts/powershell_scripts}/docker.ps1 +0 -0
  422. machineconfig/{scripts/windows/mounts → jobs/scripts/powershell_scripts}/mount_nfs.ps1 +0 -0
  423. machineconfig/{scripts/windows/mounts → jobs/scripts/powershell_scripts}/mount_nw.ps1 +0 -0
  424. machineconfig/{scripts/windows/mounts → jobs/scripts/powershell_scripts}/mount_smb.ps1 +0 -0
  425. machineconfig/{setup_windows/others → jobs/scripts/powershell_scripts}/power_options.ps1 +0 -0
  426. machineconfig/{scripts/windows/mounts → jobs/scripts/powershell_scripts}/share_cloud.cmd +0 -0
  427. machineconfig/{scripts/windows/mounts → jobs/scripts/powershell_scripts}/share_smb.ps1 +0 -0
  428. machineconfig/{scripts/windows/mounts → jobs/scripts/powershell_scripts}/unlock_bitlocker.ps1 +0 -0
  429. machineconfig/scripts/python/{helpers_croshell → ai/utils}/__init__.py +0 -0
  430. machineconfig/scripts/python/ai/{solutions/_shared.py → utils/shared.py} +0 -0
  431. machineconfig/scripts/python/{helpers_devops → graph}/__init__.py +0 -0
  432. machineconfig/scripts/python/{helpers_devops/themes → helpers}/__init__.py +0 -0
  433. machineconfig/scripts/python/{env_manager → helpers/helper_env}/__init__.py +0 -0
  434. machineconfig/scripts/python/{env_manager → helpers/helper_env}/path_manager_backend.py +0 -0
  435. machineconfig/scripts/python/{helpers_fire → helpers/helpers_agents}/__init__.py +0 -0
  436. machineconfig/scripts/python/{helpers_fire → helpers/helpers_agents}/agentic_frameworks/__init__.py +0 -0
  437. machineconfig/scripts/python/{helpers_fire → helpers/helpers_agents}/fire_agents_help_search.py +0 -0
  438. machineconfig/scripts/python/{helpers_fire → helpers/helpers_agents}/fire_agents_load_balancer.py +0 -0
  439. machineconfig/scripts/python/{helpers_fire → helpers/helpers_agents/templates}/template.ps1 +0 -0
  440. machineconfig/scripts/python/{helpers_fire_command → helpers/helpers_cloud}/__init__.py +0 -0
  441. machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/cloud_helpers.py +1 -1
  442. /machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/helpers5.py +0 -0
  443. /machineconfig/scripts/python/{helpers_sessions → helpers/helpers_croshell}/__init__.py +0 -0
  444. /machineconfig/scripts/python/{helpers_croshell → helpers/helpers_croshell}/pomodoro.py +0 -0
  445. /machineconfig/scripts/python/{helpers_croshell → helpers/helpers_croshell}/viewer.py +0 -0
  446. /machineconfig/scripts/python/{helpers_croshell → helpers/helpers_croshell}/viewer_template.py +0 -0
  447. /machineconfig/scripts/python/{nw → helpers/helpers_devops}/__init__.py +0 -0
  448. /machineconfig/{setup_windows/wt_and_pwsh → scripts/python/helpers/helpers_devops/themes}/__init__.py +0 -0
  449. /machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/themes/choose_pwsh_theme.ps1 +0 -0
  450. /machineconfig/scripts/python/{helpers_devops/themes/choose_starship_theme.ps1 → helpers/helpers_fire_command/__init__.py} +0 -0
  451. /machineconfig/scripts/python/{helpers_fire_command → helpers/helpers_fire_command}/cloud_manager.py +0 -0
  452. /machineconfig/scripts/python/{helpers_fire_command/fire_jobs_streamlit_helper.py → helpers/helpers_fire_command/f.py} +0 -0
  453. /machineconfig/{settings/shells/pwsh/profile.ps1 → scripts/python/helpers/helpers_fire_command/fire_jobs_streamlit_helper.py} +0 -0
  454. /machineconfig/scripts/python/{helpers_navigator → helpers/helpers_navigator}/search_bar.py +0 -0
  455. /machineconfig/{settings/yazi/keymap.toml → scripts/python/helpers/helpers_network/__init__.py} +0 -0
  456. /machineconfig/scripts/python/{nw → helpers/helpers_network}/mount_nw_drive.py +0 -0
  457. /machineconfig/scripts/python/{nw → helpers/helpers_network}/onetimeshare.py +0 -0
  458. /machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/sync.py +0 -0
  459. /machineconfig/{setup_windows/wt_and_pwsh → settings/wt}/set_wt_settings.py +0 -0
  460. {machineconfig-6.82.dist-info → machineconfig-8.51.dist-info}/WHEEL +0 -0
  461. {machineconfig-6.82.dist-info → machineconfig-8.51.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,147 @@
1
+ import platform
2
+ import re
3
+ import shutil
4
+ import subprocess
5
+ from pathlib import Path
6
+
7
+ from machineconfig.utils.ssh_utils.wsl_helper import (
8
+ ensure_relative_path,
9
+ remove_path,
10
+ ensure_wsl_environment,
11
+ ensure_windows_environment,
12
+ ensure_linux_environment,
13
+ resolve_windows_home_from_wsl,
14
+ resolve_wsl_home_on_windows,
15
+ run_windows_copy_command,
16
+ ensure_symlink,
17
+ normalize_port_spec_for_firewall,
18
+ )
19
+
20
+
21
+ def copy_when_inside_wsl(source: Path | str, target: Path | str, overwrite: bool, windows_username: str | None) -> None:
22
+ ensure_wsl_environment()
23
+ source_relative = ensure_relative_path(source)
24
+ target_relative = ensure_relative_path(target)
25
+ source_path = Path.home() / source_relative
26
+ target_path = resolve_windows_home_from_wsl(windows_username) / target_relative
27
+ if not source_path.exists():
28
+ raise FileNotFoundError(source_path)
29
+ if target_path.exists():
30
+ if not overwrite:
31
+ raise FileExistsError(target_path)
32
+ remove_path(target_path)
33
+ target_path.parent.mkdir(parents=True, exist_ok=True)
34
+ if source_path.is_dir():
35
+ shutil.copytree(source_path, target_path, dirs_exist_ok=False)
36
+ return
37
+ print(f"Copying {source_path} to {target_path}")
38
+ shutil.copy2(source_path, target_path)
39
+
40
+
41
+ def copy_when_inside_windows(source: Path | str, target: Path | str, overwrite: bool) -> None:
42
+ ensure_windows_environment()
43
+ source_relative = ensure_relative_path(source)
44
+ target_relative = ensure_relative_path(target)
45
+ source_path = Path.home() / source_relative
46
+ target_path = resolve_wsl_home_on_windows() / target_relative
47
+ if not source_path.exists():
48
+ raise FileNotFoundError(source_path)
49
+ if target_path.exists():
50
+ if not overwrite:
51
+ raise FileExistsError(target_path)
52
+ remove_path(target_path)
53
+ run_windows_copy_command(source_path, target_path)
54
+
55
+
56
+ def link_wsl_and_windows(windows_username: str | None) -> None:
57
+ system = platform.system()
58
+ if system == "Darwin":
59
+ raise RuntimeError("link_wsl_and_windows is not designed for macOS")
60
+ try:
61
+ ensure_wsl_environment()
62
+ except RuntimeError:
63
+ try:
64
+ ensure_windows_environment()
65
+ except RuntimeError as exc:
66
+ raise RuntimeError("link_wsl_and_windows must run inside Windows or WSL") from exc
67
+ print("🔗 Running inside Windows, linking to WSL home...")
68
+ target_path = resolve_wsl_home_on_windows()
69
+ link_path = Path.home() / "wsl"
70
+ created = ensure_symlink(link_path, target_path)
71
+ if created:
72
+ print(f"✅ Created symlink: {link_path} -> {target_path}")
73
+ else:
74
+ print(f"✅ Symlink already exists: {link_path} -> {target_path}")
75
+ return
76
+ print("🔗 Running inside WSL, linking to Windows home...")
77
+ target_path = resolve_windows_home_from_wsl(windows_username)
78
+ link_path = Path.home() / "win"
79
+ created = ensure_symlink(link_path, target_path)
80
+ if created:
81
+ print(f"✅ Created symlink: {link_path} -> {target_path}")
82
+ else:
83
+ print(f"✅ Symlink already exists: {link_path} -> {target_path}")
84
+
85
+
86
+ def open_wsl_port(ports_spec: str) -> None:
87
+ ensure_windows_environment()
88
+ normalized_ports, description = normalize_port_spec_for_firewall(ports_spec)
89
+ rule_name = f"WSL Ports {description}"
90
+ # Build PowerShell array syntax for -LocalPort parameter (e.g., @('3000-4000','8080'))
91
+ port_parts = normalized_ports.split(",")
92
+ ps_array = "@(" + ",".join(f"'{p}'" for p in port_parts) + ")"
93
+ script = f"New-NetFirewallRule -DisplayName '{rule_name}' -Direction Inbound -LocalPort {ps_array} -Protocol TCP -Action Allow"
94
+ print(f"🔥 Opening firewall for ports: {description}...")
95
+ result = subprocess.run(["powershell.exe", "-NoLogo", "-NoProfile", "-Command", script], capture_output=True, text=True)
96
+ if result.returncode == 0:
97
+ print(f"✅ Firewall rule created for ports: {description}")
98
+ else:
99
+ print(f"❌ Failed to create firewall rule: {result.stderr.strip()}")
100
+
101
+
102
+ def change_ssh_port(port: int) -> None:
103
+ ensure_linux_environment()
104
+ if port < 1 or port > 65535:
105
+ raise ValueError(f"Invalid port number: {port}")
106
+
107
+ sshd_config = Path("/etc/ssh/sshd_config")
108
+ if not sshd_config.exists():
109
+ raise FileNotFoundError(f"SSH config file not found: {sshd_config}")
110
+
111
+ print(f"🔧 Changing SSH port to {port}...")
112
+
113
+ content = sshd_config.read_text()
114
+ new_content = re.sub(r"^#?\s*Port\s+\d+", f"Port {port}", content, flags=re.MULTILINE)
115
+ if f"Port {port}" not in new_content:
116
+ new_content = f"Port {port}\n" + new_content
117
+
118
+ print(f"📝 Updating {sshd_config}...")
119
+ result = subprocess.run(["sudo", "tee", str(sshd_config)], input=new_content.encode(), capture_output=True)
120
+ if result.returncode != 0:
121
+ raise RuntimeError(f"Failed to update sshd_config: {result.stderr.decode()}")
122
+ print(f"✅ Updated {sshd_config}")
123
+
124
+ override_dir = Path("/etc/systemd/system/ssh.socket.d")
125
+ override_file = override_dir / "override.conf"
126
+ override_content = f"""[Socket]
127
+ ListenStream=
128
+ ListenStream={port}
129
+ """
130
+ print(f"📝 Creating systemd socket override at {override_file}...")
131
+ subprocess.run(["sudo", "mkdir", "-p", str(override_dir)], check=True)
132
+ result = subprocess.run(["sudo", "tee", str(override_file)], input=override_content.encode(), capture_output=True)
133
+ if result.returncode != 0:
134
+ raise RuntimeError(f"Failed to create override file: {result.stderr.decode()}")
135
+ print("✅ Created systemd socket override")
136
+
137
+ print("🔄 Restarting SSH services...")
138
+ subprocess.run(["sudo", "systemctl", "daemon-reload"], check=True)
139
+ subprocess.run(["sudo", "systemctl", "restart", "ssh.socket"], check=False)
140
+ subprocess.run(["sudo", "service", "ssh", "restart"], check=False)
141
+ print(f"✅ SSH port changed to {port}")
142
+ print(f"⚠️ Remember to open port {port} in Windows Firewall if running in WSL")
143
+
144
+
145
+ if __name__ == "__main__":
146
+ copy_when_inside_wsl(Path("projects/source.txt"), Path("windows_projects/source.txt"), overwrite=True, windows_username=None)
147
+ copy_when_inside_windows(Path("documents/example.txt"), Path("linux_documents/example.txt"), overwrite=True)
@@ -0,0 +1,217 @@
1
+ import os
2
+ import platform
3
+ import stat
4
+ import shutil
5
+ import subprocess
6
+ from pathlib import Path, PureWindowsPath
7
+
8
+
9
+ def ensure_relative_path(requested: Path | str) -> Path:
10
+ path = Path(requested)
11
+ if path.is_absolute():
12
+ raise ValueError("paths must be relative to the home directory")
13
+ if any(part == ".." for part in path.parts):
14
+ raise ValueError("paths must stay within the home directory")
15
+ return path
16
+
17
+
18
+ def remove_path(path: Path) -> None:
19
+ if path.is_symlink() or path.is_file():
20
+ path.unlink()
21
+ return
22
+ shutil.rmtree(path)
23
+
24
+
25
+ def ensure_wsl_environment() -> None:
26
+ if os.environ.get("WSL_DISTRO_NAME"):
27
+ return
28
+ if "microsoft" in platform.release().lower():
29
+ return
30
+ raise RuntimeError("copy_when_inside_wsl must run inside WSL")
31
+
32
+
33
+ def ensure_windows_environment() -> None:
34
+ if os.name != "nt":
35
+ raise RuntimeError("copy_when_inside_windows must run inside Windows")
36
+ if os.environ.get("WSL_DISTRO_NAME"):
37
+ raise RuntimeError("copy_when_inside_windows must run inside Windows")
38
+
39
+
40
+ def ensure_linux_environment() -> None:
41
+ if platform.system() != "Linux":
42
+ raise RuntimeError("change_ssh_port requires Linux environment")
43
+
44
+
45
+ def infer_windows_home_from_permissions(windows_username: str | None) -> Path:
46
+ base_dir = Path("/mnt/c/Users")
47
+ try:
48
+ entries = list(base_dir.iterdir())
49
+ except FileNotFoundError as exc:
50
+ raise RuntimeError("unable to find /mnt/c/Users") from exc
51
+ if windows_username:
52
+ candidate = base_dir / windows_username
53
+ if candidate.is_dir():
54
+ return candidate
55
+ raise RuntimeError(f"specified Windows user directory not found: {candidate}")
56
+ candidates: list[Path] = []
57
+ for entry in entries:
58
+ if not entry.is_dir():
59
+ continue
60
+ if entry.name.lower() == "public" or entry.name.lower() == "all users":
61
+ continue
62
+ try:
63
+ mode = stat.S_IMODE(entry.stat().st_mode)
64
+ except OSError:
65
+ continue
66
+ if mode == 0o777:
67
+ candidates.append(entry)
68
+ if len(candidates) != 1:
69
+ wsl_user = os.environ.get("USER") or os.environ.get("LOGNAME")
70
+ if wsl_user:
71
+ for candidate in candidates:
72
+ if candidate.name == wsl_user:
73
+ return candidate
74
+ non_default = [c for c in candidates if c.name.lower() not in ("default", "default user")]
75
+ if len(non_default) == 1:
76
+ return non_default[0]
77
+ options = ", ".join(sorted(candidate.name for candidate in candidates)) or "none"
78
+ raise RuntimeError(f"unable to infer Windows home directory (candidates: {options})")
79
+ return candidates[0]
80
+
81
+
82
+ def resolve_windows_home_from_wsl(windows_username: str | None) -> Path:
83
+ if windows_username:
84
+ return infer_windows_home_from_permissions(windows_username)
85
+ user_profile = os.environ.get("USERPROFILE")
86
+ if user_profile:
87
+ windows_path = PureWindowsPath(user_profile)
88
+ drive = windows_path.drive
89
+ if drive:
90
+ drive_letter = drive.rstrip(":").lower()
91
+ tail = Path(*windows_path.parts[1:])
92
+ candidate = Path("/mnt") / drive_letter / tail
93
+ if candidate.exists():
94
+ return candidate
95
+ return infer_windows_home_from_permissions(windows_username)
96
+
97
+
98
+ def decode_wsl_output(raw_bytes: bytes) -> str:
99
+ try:
100
+ return raw_bytes.decode("utf-16-le")
101
+ except UnicodeDecodeError:
102
+ return raw_bytes.decode()
103
+
104
+
105
+ def get_single_wsl_distribution() -> str:
106
+ process = subprocess.run(["wsl.exe", "-l"], capture_output=True, text=False, check=True)
107
+ stdout = decode_wsl_output(process.stdout).replace("\ufeff", "")
108
+ distributions: list[str] = []
109
+ for raw_line in stdout.splitlines():
110
+ line = raw_line.strip()
111
+ if not line or line.lower().startswith("windows subsystem for linux"):
112
+ continue
113
+ normalized = line.lstrip("* ").replace("(Default)", "").strip()
114
+ if normalized:
115
+ distributions.append(normalized)
116
+ if len(distributions) != 1:
117
+ raise RuntimeError("unable to pick a single WSL distribution")
118
+ return distributions[0]
119
+
120
+
121
+ def resolve_wsl_home_on_windows() -> Path:
122
+ distribution = get_single_wsl_distribution()
123
+ home_root = Path(rf"\\wsl$\{distribution}\home")
124
+ try:
125
+ entries = list(home_root.iterdir())
126
+ except FileNotFoundError as exc:
127
+ raise RuntimeError(f"unable to locate WSL home directories for {distribution}") from exc
128
+ except OSError as exc:
129
+ raise RuntimeError(f"unable to inspect WSL home directories for {distribution}") from exc
130
+ user_dirs = [entry for entry in entries if entry.is_dir()]
131
+ if len(user_dirs) != 1:
132
+ options = ", ".join(sorted(entry.name for entry in user_dirs)) or "none"
133
+ raise RuntimeError(f"unable to infer WSL user directory (candidates: {options})")
134
+ return user_dirs[0]
135
+
136
+
137
+ def quote_for_powershell(path: Path) -> str:
138
+ return "'" + str(path).replace("'", "''") + "'"
139
+
140
+
141
+ def run_windows_copy_command(source_path: Path, target_path: Path) -> None:
142
+ source_is_dir = source_path.is_dir()
143
+ parent_literal = quote_for_powershell(target_path.parent)
144
+ source_literal = quote_for_powershell(source_path)
145
+ target_literal = quote_for_powershell(target_path)
146
+ script = (
147
+ "$ErrorActionPreference = 'Stop'; "
148
+ f"New-Item -ItemType Directory -Path {parent_literal} -Force | Out-Null; "
149
+ f"Copy-Item -LiteralPath {source_literal} -Destination {target_literal}"
150
+ f"{' -Recurse' if source_is_dir else ''} -Force"
151
+ )
152
+ print(f"Copying {source_path} to {target_path}")
153
+ subprocess.run(["powershell.exe", "-NoLogo", "-NoProfile", "-Command", script], check=True)
154
+
155
+
156
+ def ensure_symlink(link_path: Path, target_path: Path) -> bool:
157
+ if not target_path.exists():
158
+ raise FileNotFoundError(target_path)
159
+ if link_path.is_symlink():
160
+ existing_target = Path(os.path.realpath(link_path))
161
+ desired_target = Path(os.path.realpath(target_path))
162
+ if os.path.normcase(str(existing_target)) == os.path.normcase(str(desired_target)):
163
+ return False
164
+ link_path.unlink()
165
+ elif link_path.exists():
166
+ raise FileExistsError(link_path)
167
+ link_path.symlink_to(target_path, target_is_directory=True)
168
+ return True
169
+
170
+
171
+ def parse_port_spec(port_spec: str) -> list[int]:
172
+ ports: list[int] = []
173
+ for part in port_spec.split(","):
174
+ part = part.strip()
175
+ if not part:
176
+ continue
177
+ if "-" in part:
178
+ range_parts = part.split("-", maxsplit=1)
179
+ start = int(range_parts[0].strip())
180
+ end = int(range_parts[1].strip())
181
+ if start > end:
182
+ raise ValueError(f"Invalid port range: {part} (start > end)")
183
+ ports.extend(range(start, end + 1))
184
+ else:
185
+ ports.append(int(part))
186
+ return ports
187
+
188
+
189
+ def normalize_port_spec_for_firewall(port_spec: str) -> tuple[str, str]:
190
+ """Validates and normalizes port spec for New-NetFirewallRule -LocalPort parameter.
191
+ Returns (normalized_spec, human_readable_description).
192
+ New-NetFirewallRule natively supports ranges (e.g. '5000-5020') and comma-separated values.
193
+ """
194
+ parts: list[str] = []
195
+ for raw_part in port_spec.split(","):
196
+ part = raw_part.strip()
197
+ if not part:
198
+ continue
199
+ if "-" in part:
200
+ range_parts = part.split("-", maxsplit=1)
201
+ start = int(range_parts[0].strip())
202
+ end = int(range_parts[1].strip())
203
+ if start < 1 or start > 65535 or end < 1 or end > 65535:
204
+ raise ValueError(f"Port numbers must be between 1 and 65535: {part}")
205
+ if start > end:
206
+ raise ValueError(f"Invalid port range: {part} (start > end)")
207
+ parts.append(f"{start}-{end}")
208
+ else:
209
+ port = int(part)
210
+ if port < 1 or port > 65535:
211
+ raise ValueError(f"Invalid port number: {port}")
212
+ parts.append(str(port))
213
+ if not parts:
214
+ raise ValueError("No valid ports provided")
215
+ normalized = ",".join(parts)
216
+ description = normalized.replace(",", ", ")
217
+ return normalized, description
@@ -4,6 +4,7 @@ from typing import Any, BinaryIO, Optional, Union
4
4
  from typing import Literal, TypeAlias
5
5
  from dataclasses import dataclass
6
6
 
7
+
7
8
  SHELLS: TypeAlias = Literal["default", "cmd", "powershell", "pwsh", "bash"] # pwsh.exe is PowerShell (community) and powershell.exe is Windows Powershell (msft)
8
9
  CONSOLE: TypeAlias = Literal["wt", "cmd"]
9
10
  MACHINE: TypeAlias = Literal["Windows", "Linux", "Darwin"]
@@ -25,44 +25,48 @@ def generate_uv_add_commands(pyproject_path: Path, output_path: Path) -> None:
25
25
  pyproject_path: Path to the pyproject.toml file
26
26
  output_path: Path where to write the uv add commands
27
27
  """
28
- # Read pyproject.toml
29
28
  with open(pyproject_path, "rb") as f:
30
29
  pyproject_data: dict[str, Any] = tomllib.load(f)
31
30
 
32
31
  commands: list[str] = []
33
32
 
34
- # Handle main dependencies (no group)
35
33
  if "project" in pyproject_data and "dependencies" in pyproject_data["project"]:
36
- main_deps = pyproject_data["project"]["dependencies"]
34
+ main_deps: list[str] = pyproject_data["project"]["dependencies"]
37
35
  if main_deps:
38
- # Extract package names without version constraints
39
- package_names = [extract_package_name(dep) for dep in main_deps]
40
- commands.append(f"uv add {' '.join(package_names)}")
36
+ package_names: list[str] = [f"'{extract_package_name(dep)}'" for dep in main_deps]
37
+ commands.append(f"uv add --no-cache {' '.join(package_names)}")
41
38
 
42
- # Handle optional dependencies as groups
43
39
  if "project" in pyproject_data and "optional-dependencies" in pyproject_data["project"]:
44
- optional_deps = pyproject_data["project"]["optional-dependencies"]
40
+ optional_deps: dict[str, list[str]] = pyproject_data["project"]["optional-dependencies"]
45
41
  for group_name, deps in optional_deps.items():
46
42
  if deps:
47
- package_names = [extract_package_name(dep) for dep in deps]
48
- commands.append(f"uv add {' '.join(package_names)} --group {group_name}")
43
+ package_names = [f"'{extract_package_name(dep)}'" for dep in deps]
44
+ commands.append(f"uv add --no-cache --group {group_name} {' '.join(package_names)}")
49
45
 
50
- # Handle dependency-groups (like dev)
51
46
  if "dependency-groups" in pyproject_data:
52
- dep_groups = pyproject_data["dependency-groups"]
47
+ dep_groups: dict[str, list[str]] = pyproject_data["dependency-groups"]
53
48
  for group_name, deps in dep_groups.items():
54
49
  if deps:
55
- package_names = [extract_package_name(dep) for dep in deps]
50
+ package_names = [f"'{extract_package_name(dep)}'" for dep in deps]
56
51
  if group_name == "dev":
57
- commands.append(f"uv add {' '.join(package_names)} --dev")
52
+ commands.append(f"uv add --no-cache --dev {' '.join(package_names)}")
58
53
  else:
59
- commands.append(f"uv add {' '.join(package_names)} --group {group_name}")
60
-
61
- # Write commands to output file
62
- with open(output_path, "w") as f:
63
- for command in commands:
64
- f.write(command + "\n")
65
-
54
+ commands.append(f"uv add --no-cache --group {group_name} {' '.join(package_names)}")
55
+
56
+ # with open(output_path, "w") as f:
57
+ # f.write("#!/bin/bash\n")
58
+ # f.write("set -e\n\n")
59
+ # f.write("uv cache clean --force\n\n")
60
+ # for command in commands:
61
+ # f.write(command + "\n")
62
+ script = f"""
63
+ #!/bin/bash
64
+ set -e
65
+ uv cache clean --force
66
+ rm -rfd .venv
67
+ {"".join(f"{command}\n" for command in commands)}
68
+ """
69
+ output_path.write_text(script.strip() + "\n", encoding="utf-8")
66
70
  print(f"Generated {len(commands)} uv add commands in {output_path}")
67
71
 
68
72
 
@@ -74,12 +78,8 @@ def extract_package_name(dependency_spec: str) -> str:
74
78
  "rich>=14.0.0" -> "rich"
75
79
  "requests>=2.32.5" -> "requests"
76
80
  "pywin32" -> "pywin32"
77
- "package[extra]>=1.0" -> "package"
81
+ "package[extra]>=1.0" -> "package[extra]"
78
82
  """
79
- # Handle extras like "package[extra]>=1.0" first
80
- if "[" in dependency_spec:
81
- dependency_spec = dependency_spec.split("[")[0].strip()
82
-
83
83
  # Split on common version operators and take the first part
84
84
  for operator in [">=", "<=", "==", "!=", ">", "<", "~=", "===", "@"]:
85
85
  if operator in dependency_spec:
@@ -89,13 +89,85 @@ def extract_package_name(dependency_spec: str) -> str:
89
89
  return dependency_spec.strip()
90
90
 
91
91
 
92
+ def upgrade_machine_config_version() -> None:
93
+ """
94
+ Upgrade machineconfig version in pyproject.toml and all source files.
95
+
96
+ Reads current version from pyproject.toml, bumps it by 0.01, and replaces
97
+ all occurrences of machineconfig>={old_version} and machineconfig[group]>={old_version}
98
+ with the new version in Python (.py), shell (.sh), and PowerShell (.ps1) files.
99
+ """
100
+ current_dir: Path = Path.cwd()
101
+ pyproject_file: Path = current_dir / "pyproject.toml"
102
+
103
+ # Read current version from pyproject.toml
104
+ with open(pyproject_file, "rb") as f:
105
+ pyproject_data: dict[str, Any] = tomllib.load(f)
106
+
107
+ current_version_str: str = pyproject_data["project"]["version"]
108
+ version_parts: list[str] = current_version_str.split(".")
109
+ major: int = int(version_parts[0])
110
+ minor: int = int(version_parts[1])
111
+
112
+ # Bump minor version by 1, preserving zero-padding
113
+ new_minor: int = minor + 1
114
+ # Preserve the same number of digits as the original minor version
115
+ minor_width: int = len(version_parts[1])
116
+ new_version: str = f"{major}.{new_minor:0{minor_width}d}"
117
+
118
+ # Collect all optional dependency groups
119
+ optional_groups: set[str] = set()
120
+ if "project" in pyproject_data and "optional-dependencies" in pyproject_data["project"]:
121
+ optional_groups.update(pyproject_data["project"]["optional-dependencies"].keys())
122
+ if "dependency-groups" in pyproject_data:
123
+ optional_groups.update(pyproject_data["dependency-groups"].keys())
124
+
125
+ print(f"Upgrading from {current_version_str} to {new_version}")
126
+ print(f"Found optional groups: {', '.join(sorted(optional_groups))}")
127
+
128
+ # Update pyproject.toml
129
+ content: str = pyproject_file.read_text(encoding="utf-8")
130
+ updated_content: str = content.replace(f'version = "{current_version_str}"', f'version = "{new_version}"')
131
+ pyproject_file.write_text(updated_content, encoding="utf-8")
132
+ print(f"Updated pyproject.toml: {current_version_str} -> {new_version}")
133
+
134
+ # Find all Python files and replace version constraints
135
+ py_files: list[Path] = list(current_dir.glob("**/*.py")) + list(current_dir.glob("**/*.sh")) + list(current_dir.glob("**/*.ps1"))
136
+
137
+ # Also include Dockerfile files
138
+ dockerfile_files: list[Path] = [f for f in current_dir.glob("**/Dockerfile*") if f.is_file()]
139
+ py_files.extend(dockerfile_files)
140
+
141
+ files_updated: int = 0
142
+ for file_path in py_files:
143
+ try:
144
+ file_content: str = file_path.read_text(encoding="utf-8")
145
+ updated_file_content: str = file_content
146
+
147
+ # Replace base constraint (without group)
148
+ old_constraint: str = f"machineconfig>={current_version_str}"
149
+ new_constraint: str = f"machineconfig>={new_version}"
150
+ if old_constraint in updated_file_content:
151
+ updated_file_content = updated_file_content.replace(old_constraint, new_constraint)
152
+
153
+ # Replace constraints with optional groups
154
+ for group in optional_groups:
155
+ old_group_constraint: str = f"machineconfig[{group}]>={current_version_str}"
156
+ new_group_constraint: str = f"machineconfig[{group}]>={new_version}"
157
+ if old_group_constraint in updated_file_content:
158
+ updated_file_content = updated_file_content.replace(old_group_constraint, new_group_constraint)
159
+
160
+ if updated_file_content != file_content:
161
+ file_path.write_text(updated_file_content, encoding="utf-8")
162
+ files_updated += 1
163
+ print(f"Updated {file_path.relative_to(current_dir)}")
164
+ except (UnicodeDecodeError, PermissionError):
165
+ # Skip files that can't be read as text
166
+ pass
167
+ print(f"Updated {files_updated} files with version constraint")
168
+ from machineconfig.utils.code import exit_then_run_shell_script
169
+ exit_then_run_shell_script(f"cd {current_dir}; uv sync")
170
+
171
+
92
172
  if __name__ == "__main__":
93
- # Example usage
94
- current_dir = Path.cwd()
95
- pyproject_file = current_dir / "pyproject.toml"
96
- output_file = current_dir / "uv_add_commands.txt"
97
-
98
- if pyproject_file.exists():
99
- generate_uv_add_commands(pyproject_file, output_file)
100
- else:
101
- print(f"pyproject.toml not found at {pyproject_file}")
173
+ upgrade_machine_config_version()
machineconfig/utils/ve.py CHANGED
@@ -1,18 +1,20 @@
1
- from machineconfig.utils.io import read_ini
2
- import platform
1
+
3
2
  from typing import Optional
4
- from pathlib import Path
5
3
 
6
4
 
7
- def get_ve_path_and_ipython_profile(init_path: Path) -> tuple[Optional[str], Optional[str]]:
5
+ def get_ve_path_and_ipython_profile(init_path: "Path") -> tuple[Optional[str], Optional[str]]:
8
6
  """Works with .ve.ini .venv and .ve_path"""
9
7
  ve_path: Optional[str] = None
10
8
  ipy_profile: Optional[str] = None
11
9
  tmp = init_path
10
+
11
+ from machineconfig.utils.io import read_ini
12
+
12
13
  for _ in init_path.parents:
13
14
  if tmp.joinpath(".ve.ini").exists():
14
15
  ini = read_ini(tmp.joinpath(".ve.ini"))
15
16
  if ve_path is None:
17
+
16
18
  try:
17
19
  ve_path = ini["specs"]["ve_path"]
18
20
  except KeyError:
@@ -39,6 +41,8 @@ def get_ve_path_and_ipython_profile(init_path: Path) -> tuple[Optional[str], Opt
39
41
 
40
42
 
41
43
  def get_ve_activate_line(ve_root: str):
44
+ import platform
45
+ from pathlib import Path
42
46
  if platform.system() == "Windows":
43
47
  q = Path(ve_root).expanduser().relative_to(Path.home()).as_posix()
44
48
  activate_ve_line = f". $HOME/{q}/Scripts/activate.ps1"
@@ -47,3 +51,7 @@ def get_ve_activate_line(ve_root: str):
47
51
  else:
48
52
  raise NotImplementedError(f"Platform {platform.system()} not supported.")
49
53
  return activate_ve_line
54
+
55
+
56
+ if __name__ == "__main__":
57
+ from pathlib import Path