machineconfig 8.14__py3-none-any.whl → 8.50__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 (273) hide show
  1. machineconfig/cluster/remote/run_cluster.py +1 -1
  2. machineconfig/cluster/remote/run_remote.py +1 -1
  3. machineconfig/cluster/sessions_managers/utils/maker.py +10 -8
  4. machineconfig/cluster/sessions_managers/wt_local.py +1 -1
  5. machineconfig/cluster/sessions_managers/wt_local_manager.py +1 -1
  6. machineconfig/cluster/sessions_managers/zellij_local.py +1 -1
  7. machineconfig/cluster/sessions_managers/zellij_local_manager.py +1 -1
  8. machineconfig/jobs/installer/checks/check_installations.py +133 -0
  9. machineconfig/jobs/installer/checks/install_utils.py +132 -0
  10. machineconfig/jobs/installer/checks/report_utils.py +39 -0
  11. machineconfig/jobs/installer/checks/vt_utils.py +89 -0
  12. machineconfig/jobs/installer/installer_data.json +225 -140
  13. machineconfig/jobs/installer/linux_scripts/docker.sh +6 -9
  14. machineconfig/jobs/installer/package_groups.py +10 -9
  15. machineconfig/jobs/installer/python_scripts/boxes.py +1 -2
  16. machineconfig/jobs/installer/python_scripts/code.py +10 -8
  17. machineconfig/jobs/installer/python_scripts/hx.py +30 -13
  18. machineconfig/jobs/installer/python_scripts/nerfont_windows_helper.py +6 -5
  19. machineconfig/jobs/installer/python_scripts/sysabc.py +25 -19
  20. machineconfig/jobs/installer/python_scripts/yazi.py +33 -17
  21. machineconfig/jobs/scripts/powershell_scripts/cmatrix.ps1 +52 -0
  22. machineconfig/jobs/scripts/powershell_scripts/mount_ssh.ps1 +1 -1
  23. machineconfig/jobs/scripts_dynamic/a.py +413 -10
  24. machineconfig/profile/create_links.py +77 -20
  25. machineconfig/profile/create_links_export.py +63 -58
  26. machineconfig/profile/mapper_data.toml +30 -0
  27. machineconfig/profile/mapper_dotfiles.toml +253 -0
  28. machineconfig/scripts/python/agents.py +70 -172
  29. machineconfig/scripts/python/ai/initai.py +3 -1
  30. machineconfig/scripts/python/ai/scripts/__init__.py +1 -0
  31. machineconfig/scripts/python/ai/scripts/lint_and_type_check.ps1 +2 -0
  32. machineconfig/scripts/python/ai/scripts/lint_and_type_check.sh +7 -5
  33. machineconfig/scripts/python/ai/solutions/claude/claude.py +1 -1
  34. machineconfig/scripts/python/ai/solutions/cline/cline.py +1 -1
  35. machineconfig/scripts/python/ai/solutions/copilot/github_copilot.py +1 -1
  36. machineconfig/scripts/python/ai/solutions/copilot/instructions/python/dev.instructions.md +29 -0
  37. machineconfig/scripts/python/ai/solutions/crush/crush.py +1 -1
  38. machineconfig/scripts/python/ai/solutions/cursor/cursors.py +1 -1
  39. machineconfig/scripts/python/ai/solutions/gemini/gemini.py +1 -1
  40. machineconfig/scripts/python/ai/solutions/gemini/settings.json +3 -0
  41. machineconfig/scripts/python/ai/{solutions → utils}/generic.py +2 -15
  42. machineconfig/scripts/python/ai/utils/vscode_tasks.py +6 -3
  43. machineconfig/scripts/python/cloud.py +58 -11
  44. machineconfig/scripts/python/croshell.py +4 -156
  45. machineconfig/scripts/python/devops.py +57 -40
  46. machineconfig/scripts/python/devops_navigator.py +17 -3
  47. machineconfig/scripts/python/fire_jobs.py +8 -207
  48. machineconfig/scripts/python/ftpx.py +5 -225
  49. machineconfig/scripts/python/graph/cli_graph.json +8743 -0
  50. machineconfig/scripts/python/{env_manager → helper_env}/path_manager_tui.py +2 -2
  51. machineconfig/scripts/python/{env_manager → helpers/helper_env}/env_manager_tui.py +1 -1
  52. machineconfig/scripts/python/helpers/helper_env/path_manager_tui.py +228 -0
  53. machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/agentic_frameworks/fire_crush.py +1 -1
  54. machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/agentic_frameworks/fire_cursor_agents.py +1 -1
  55. machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/agentic_frameworks/fire_gemini.py +1 -1
  56. machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/agentic_frameworks/fire_qwen.py +1 -1
  57. machineconfig/scripts/python/helpers/helpers_agents/agents_impl.py +168 -0
  58. machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/fire_agents_help_launch.py +5 -5
  59. machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/cloud_copy.py +6 -6
  60. machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/cloud_mount.py +10 -5
  61. machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/cloud_sync.py +3 -3
  62. machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/helpers2.py +1 -1
  63. machineconfig/scripts/python/helpers/helpers_croshell/croshell_impl.py +225 -0
  64. machineconfig/scripts/python/{helpers_croshell → helpers/helpers_croshell}/scheduler.py +4 -4
  65. machineconfig/scripts/python/{helpers_croshell → helpers/helpers_croshell}/start_slidev.py +7 -6
  66. machineconfig/scripts/python/helpers/helpers_devops/backup_config.py +149 -0
  67. machineconfig/scripts/python/helpers/helpers_devops/cli_backup_retrieve.py +267 -0
  68. machineconfig/scripts/python/helpers/helpers_devops/cli_config.py +98 -0
  69. machineconfig/scripts/python/helpers/helpers_devops/cli_config_dotfile.py +274 -0
  70. machineconfig/scripts/python/helpers/helpers_devops/cli_data.py +76 -0
  71. machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/cli_nw.py +52 -72
  72. machineconfig/scripts/python/helpers/helpers_devops/cli_repos.py +274 -0
  73. machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/cli_self.py +40 -23
  74. machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/cli_share_file.py +44 -30
  75. machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/cli_share_server.py +26 -43
  76. machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/cli_share_terminal.py +12 -6
  77. machineconfig/scripts/python/helpers/helpers_devops/cli_ssh.py +167 -0
  78. machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/devops_status.py +12 -6
  79. machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/devops_update_repos.py +1 -1
  80. machineconfig/scripts/python/{interactive.py → helpers/helpers_devops/interactive.py} +68 -52
  81. machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/run_script.py +75 -58
  82. machineconfig/scripts/python/helpers/helpers_devops/themes/choose_starship_theme.ps1 +41 -0
  83. machineconfig/scripts/python/helpers/helpers_devops/themes/choose_starship_theme.sh +48 -0
  84. machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/themes/choose_wezterm_theme.py +3 -3
  85. machineconfig/scripts/python/helpers/helpers_fire_command/fire_jobs_impl.py +233 -0
  86. machineconfig/scripts/python/{helpers_fire_command → helpers/helpers_fire_command}/fire_jobs_route_helper.py +3 -3
  87. machineconfig/scripts/python/helpers/helpers_msearch/msearch_impl.py +248 -0
  88. machineconfig/scripts/python/{helpers_msearch → helpers/helpers_msearch}/scripts_linux/fzfg +4 -3
  89. machineconfig/scripts/python/helpers/helpers_msearch/scripts_linux/search_with_context.sh +48 -0
  90. machineconfig/scripts/python/{helpers_msearch → helpers/helpers_msearch}/scripts_windows/fzfg.ps1 +1 -1
  91. machineconfig/scripts/python/helpers/helpers_navigator/__init__.py +20 -0
  92. machineconfig/scripts/python/helpers/helpers_navigator/cli_graph_loader.py +234 -0
  93. machineconfig/scripts/python/{helpers_navigator → helpers/helpers_navigator}/command_builder.py +61 -13
  94. machineconfig/scripts/python/helpers/helpers_navigator/command_detail.py +153 -0
  95. machineconfig/scripts/python/helpers/helpers_navigator/command_tree.py +45 -0
  96. machineconfig/scripts/python/{helpers_navigator → helpers/helpers_navigator}/data_models.py +18 -11
  97. machineconfig/scripts/python/{helpers_navigator → helpers/helpers_navigator}/main_app.py +5 -5
  98. machineconfig/scripts/python/helpers/helpers_network/__init__.py +0 -0
  99. machineconfig/scripts/python/{helpers_network → helpers/helpers_network}/address.py +15 -17
  100. machineconfig/scripts/python/{helpers_network → helpers/helpers_network}/address_switch.py +1 -1
  101. machineconfig/scripts/python/helpers/helpers_network/ftpx_impl.py +276 -0
  102. machineconfig/scripts/python/{helpers_network → helpers/helpers_network}/mount_ssh.py +2 -2
  103. machineconfig/scripts/python/helpers/helpers_network/ssh_add_identity.py +73 -0
  104. machineconfig/scripts/python/helpers/helpers_network/ssh_add_ssh_key.py +175 -0
  105. machineconfig/scripts/python/helpers/helpers_network/ssh_debug_linux.py +319 -0
  106. machineconfig/scripts/python/helpers/helpers_network/ssh_debug_windows.py +275 -0
  107. machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/action.py +3 -3
  108. machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/action_helper.py +3 -3
  109. machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/cloud_repo_sync.py +117 -33
  110. machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/grource.py +3 -2
  111. machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/record.py +33 -13
  112. machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/repo_analyzer_2.py +63 -19
  113. machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/update.py +0 -6
  114. machineconfig/scripts/python/helpers/helpers_search/script_help.py +81 -0
  115. machineconfig/scripts/python/helpers/helpers_sessions/__init__.py +0 -0
  116. machineconfig/scripts/python/helpers/helpers_sessions/sessions_impl.py +186 -0
  117. machineconfig/scripts/python/{helpers_sessions → helpers/helpers_sessions}/sessions_multiprocess.py +1 -1
  118. machineconfig/scripts/python/helpers/helpers_terminal/__init__.py +0 -0
  119. machineconfig/scripts/python/helpers/helpers_terminal/terminal_impl.py +96 -0
  120. machineconfig/scripts/python/{helpers_utils → helpers/helpers_utils}/download.py +1 -1
  121. machineconfig/scripts/python/{helpers_utils → helpers/helpers_utils}/python.py +47 -26
  122. machineconfig/scripts/python/helpers/helpers_utils/specs.py +246 -0
  123. machineconfig/scripts/python/mcfg_entry.py +133 -48
  124. machineconfig/scripts/python/msearch.py +15 -61
  125. machineconfig/scripts/python/sessions.py +59 -194
  126. machineconfig/scripts/python/terminal.py +18 -96
  127. machineconfig/scripts/python/utils.py +101 -20
  128. machineconfig/settings/atuin/config.toml +294 -0
  129. machineconfig/settings/atuin/themes/catppuccin-mocha-mauve.toml +12 -0
  130. machineconfig/settings/linters/.ruff.toml +1 -0
  131. machineconfig/settings/mprocs/windows/mprocs.yaml +2 -2
  132. machineconfig/settings/shells/bash/init.sh +6 -3
  133. machineconfig/settings/shells/pwsh/init.ps1 +69 -1
  134. machineconfig/settings/shells/pwsh/search_pwsh_history.ps1 +99 -0
  135. machineconfig/settings/shells/wezterm/wezterm.lua +4 -1
  136. machineconfig/settings/shells/wt/settings.json +20 -7
  137. machineconfig/settings/shells/zsh/init.sh +25 -4
  138. machineconfig/settings/television/cable_unix/bash-history.toml +1 -1
  139. machineconfig/settings/television/cable_windows/pwsh-history.toml +1 -1
  140. machineconfig/settings/tv/config.toml +234 -0
  141. machineconfig/settings/tv/themes/catppuccin-mocha-sky.toml +22 -0
  142. machineconfig/settings/wsl/.wslconfig +5 -30
  143. machineconfig/settings/yazi/yazi_linux.toml +18 -8
  144. machineconfig/settings/zellij/layouts/st.kdl +2 -2
  145. machineconfig/settings/zellij/layouts/st2.kdl +1 -1
  146. machineconfig/setup_linux/web_shortcuts/interactive.sh +10 -10
  147. machineconfig/setup_linux/web_shortcuts/live_from_github.sh +3 -0
  148. machineconfig/setup_mac/__init__.py +0 -2
  149. machineconfig/setup_windows/__init__.py +0 -1
  150. machineconfig/setup_windows/web_shortcuts/interactive.ps1 +14 -13
  151. machineconfig/setup_windows/web_shortcuts/live_from_github.ps1 +4 -3
  152. machineconfig/setup_windows/web_shortcuts/quick_init.ps1 +3 -3
  153. machineconfig/type_hinting/sql/__init__.py +1 -0
  154. machineconfig/type_hinting/sql/base.py +216 -0
  155. machineconfig/type_hinting/sql/core_schema.py +64 -0
  156. machineconfig/type_hinting/sql/core_schema_typeddict.py +41 -0
  157. machineconfig/type_hinting/sql/typeddict_codegen.py +222 -0
  158. machineconfig/type_hinting/typedict/__init__.py +1 -0
  159. machineconfig/type_hinting/typedict/ast_utils.py +130 -0
  160. machineconfig/type_hinting/typedict/generator_helpers.py +319 -0
  161. machineconfig/type_hinting/typedict/generators.py +231 -0
  162. machineconfig/type_hinting/typedict/polars_schema.py +24 -0
  163. machineconfig/type_hinting/typedict/polars_schema_typeddict.py +63 -0
  164. machineconfig/utils/accessories.py +24 -0
  165. machineconfig/utils/code.py +41 -13
  166. machineconfig/utils/files/ascii_art.py +10 -14
  167. machineconfig/utils/files/headers.py +3 -5
  168. machineconfig/utils/files/read.py +8 -1
  169. machineconfig/utils/installer_utils/github_release_bulk.py +11 -91
  170. machineconfig/utils/installer_utils/github_release_scraper.py +99 -0
  171. machineconfig/utils/installer_utils/install_from_url.py +1 -1
  172. machineconfig/utils/installer_utils/installer_class.py +12 -4
  173. machineconfig/utils/installer_utils/installer_cli.py +1 -15
  174. machineconfig/utils/installer_utils/installer_helper.py +2 -2
  175. machineconfig/utils/installer_utils/installer_locator_utils.py +13 -13
  176. machineconfig/utils/installer_utils/installer_runner.py +4 -4
  177. machineconfig/utils/io.py +25 -8
  178. machineconfig/utils/meta.py +6 -4
  179. machineconfig/utils/options.py +49 -19
  180. machineconfig/utils/options_utils/__init__.py +0 -0
  181. machineconfig/utils/options_utils/options_tv_linux.py +211 -0
  182. machineconfig/utils/options_utils/options_tv_windows.py +88 -0
  183. machineconfig/utils/options_utils/tv_options.py +37 -0
  184. machineconfig/utils/path_extended.py +6 -6
  185. machineconfig/utils/scheduler.py +8 -2
  186. machineconfig/utils/schemas/fire_agents/fire_agents_input.py +1 -1
  187. machineconfig/utils/source_of_truth.py +6 -1
  188. machineconfig/utils/ssh.py +69 -18
  189. machineconfig/utils/ssh_utils/abc.py +1 -1
  190. machineconfig/utils/ssh_utils/copy_from_here.py +17 -12
  191. machineconfig/utils/ssh_utils/utils.py +21 -5
  192. machineconfig/utils/ssh_utils/wsl.py +107 -170
  193. machineconfig/utils/ssh_utils/wsl_helper.py +217 -0
  194. machineconfig/utils/upgrade_packages.py +4 -8
  195. {machineconfig-8.14.dist-info → machineconfig-8.50.dist-info}/METADATA +29 -22
  196. {machineconfig-8.14.dist-info → machineconfig-8.50.dist-info}/RECORD +251 -211
  197. machineconfig/jobs/installer/check_installations.py +0 -248
  198. machineconfig/profile/backup.toml +0 -49
  199. machineconfig/profile/mapper.toml +0 -263
  200. machineconfig/scripts/python/helpers_devops/cli_config.py +0 -105
  201. machineconfig/scripts/python/helpers_devops/cli_config_dotfile.py +0 -89
  202. machineconfig/scripts/python/helpers_devops/cli_data.py +0 -25
  203. machineconfig/scripts/python/helpers_devops/cli_repos.py +0 -208
  204. machineconfig/scripts/python/helpers_devops/devops_backup_retrieve.py +0 -80
  205. machineconfig/scripts/python/helpers_devops/themes/choose_starship_theme.bash +0 -3
  206. machineconfig/scripts/python/helpers_navigator/__init__.py +0 -20
  207. machineconfig/scripts/python/helpers_navigator/command_detail.py +0 -44
  208. machineconfig/scripts/python/helpers_navigator/command_tree.py +0 -620
  209. machineconfig/scripts/python/helpers_network/ssh_add_identity.py +0 -116
  210. machineconfig/scripts/python/helpers_network/ssh_add_ssh_key.py +0 -153
  211. machineconfig/scripts/python/helpers_network/ssh_debug_linux.py +0 -391
  212. machineconfig/scripts/python/helpers_network/ssh_debug_windows.py +0 -338
  213. machineconfig/scripts/python/helpers_repos/entrypoint.py +0 -77
  214. machineconfig/setup_mac/ssh/openssh_setup.sh +0 -114
  215. machineconfig/setup_windows/ssh/add-sshkey.ps1 +0 -29
  216. machineconfig/setup_windows/ssh/openssh-server.ps1 +0 -37
  217. machineconfig/utils/options_tv.py +0 -119
  218. machineconfig/utils/tst.py +0 -20
  219. /machineconfig/{scripts/python/helpers_agents → jobs/installer/checks}/__init__.py +0 -0
  220. /machineconfig/scripts/python/ai/{solutions/_shared.py → utils/shared.py} +0 -0
  221. /machineconfig/scripts/python/{helpers_agents/agentic_frameworks → graph}/__init__.py +0 -0
  222. /machineconfig/scripts/python/{helpers_cloud → helpers}/__init__.py +0 -0
  223. /machineconfig/scripts/python/{env_manager → helpers/helper_env}/__init__.py +0 -0
  224. /machineconfig/scripts/python/{env_manager → helpers/helper_env}/path_manager_backend.py +0 -0
  225. /machineconfig/scripts/python/{helpers_croshell → helpers/helpers_agents}/__init__.py +0 -0
  226. /machineconfig/scripts/python/{helpers_devops → helpers/helpers_agents/agentic_frameworks}/__init__.py +0 -0
  227. /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/agentic_frameworks/fire_crush.json +0 -0
  228. /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/fire_agents_help_search.py +0 -0
  229. /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/fire_agents_helper_types.py +0 -0
  230. /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/fire_agents_load_balancer.py +0 -0
  231. /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/privacy/configs/aichat/config.yaml +0 -0
  232. /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/privacy/configs/aider/.aider.conf.yml +0 -0
  233. /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/privacy/configs/copilot/config.yml +0 -0
  234. /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/privacy/configs/crush/crush.json +0 -0
  235. /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/privacy/configs/gemini/settings.json +0 -0
  236. /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/privacy/privacy.py +0 -0
  237. /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/templates/prompt.txt +0 -0
  238. /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/templates/template.ps1 +0 -0
  239. /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/templates/template.sh +0 -0
  240. /machineconfig/scripts/python/{helpers_devops/themes → helpers/helpers_cloud}/__init__.py +0 -0
  241. /machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/cloud_helpers.py +0 -0
  242. /machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/helpers5.py +0 -0
  243. /machineconfig/scripts/python/{helpers_fire_command → helpers/helpers_croshell}/__init__.py +0 -0
  244. /machineconfig/scripts/python/{helpers_croshell → helpers/helpers_croshell}/crosh.py +0 -0
  245. /machineconfig/scripts/python/{helpers_croshell → helpers/helpers_croshell}/pomodoro.py +0 -0
  246. /machineconfig/scripts/python/{helpers_croshell → helpers/helpers_croshell}/viewer.py +0 -0
  247. /machineconfig/scripts/python/{helpers_croshell → helpers/helpers_croshell}/viewer_template.py +0 -0
  248. /machineconfig/scripts/python/{helpers_network → helpers/helpers_devops}/__init__.py +0 -0
  249. /machineconfig/scripts/python/{helpers_sessions → helpers/helpers_devops/themes}/__init__.py +0 -0
  250. /machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/themes/choose_pwsh_theme.ps1 +0 -0
  251. /machineconfig/scripts/python/{helpers_devops/themes/choose_starship_theme.ps1 → helpers/helpers_fire_command/__init__.py} +0 -0
  252. /machineconfig/scripts/python/{helpers_fire_command → helpers/helpers_fire_command}/cloud_manager.py +0 -0
  253. /machineconfig/scripts/python/{helpers_fire_command → helpers/helpers_fire_command}/f.py +0 -0
  254. /machineconfig/scripts/python/{helpers_fire_command → helpers/helpers_fire_command}/file_wrangler.py +0 -0
  255. /machineconfig/scripts/python/{helpers_fire_command → helpers/helpers_fire_command}/fire_jobs_args_helper.py +0 -0
  256. /machineconfig/scripts/python/{helpers_fire_command → helpers/helpers_fire_command}/fire_jobs_streamlit_helper.py +0 -0
  257. /machineconfig/scripts/python/{helpers_msearch → helpers/helpers_msearch}/__init__.py +0 -0
  258. /machineconfig/scripts/python/{helpers_navigator → helpers/helpers_navigator}/search_bar.py +0 -0
  259. /machineconfig/scripts/python/{helpers_network → helpers/helpers_network}/mount_nfs.py +0 -0
  260. /machineconfig/scripts/python/{helpers_network → helpers/helpers_network}/mount_nw_drive.py +0 -0
  261. /machineconfig/scripts/python/{helpers_network → helpers/helpers_network}/onetimeshare.py +0 -0
  262. /machineconfig/scripts/python/{helpers_network → helpers/helpers_network}/wifi_conn.py +0 -0
  263. /machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/clone.py +0 -0
  264. /machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/repo_analyzer_1.py +0 -0
  265. /machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/sync.py +0 -0
  266. /machineconfig/scripts/python/helpers/{ast_search.py → helpers_search/ast_search.py} +0 -0
  267. /machineconfig/scripts/python/helpers/{qr_code.py → helpers_search/qr_code.py} +0 -0
  268. /machineconfig/scripts/python/helpers/{repo_rag.py → helpers_search/repo_rag.py} +0 -0
  269. /machineconfig/scripts/python/helpers/{symantic_search.py → helpers_search/symantic_search.py} +0 -0
  270. /machineconfig/scripts/python/{helpers_utils → helpers/helpers_utils}/pdf.py +0 -0
  271. {machineconfig-8.14.dist-info → machineconfig-8.50.dist-info}/WHEEL +0 -0
  272. {machineconfig-8.14.dist-info → machineconfig-8.50.dist-info}/entry_points.txt +0 -0
  273. {machineconfig-8.14.dist-info → machineconfig-8.50.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,76 @@
1
+ import typer
2
+ from typing import Annotated, Optional, Literal
3
+
4
+
5
+ def sync(
6
+ direction: Annotated[Literal["up", "u", "down", "d"], typer.Argument(..., help="Direction of sync: backup or retrieve")],
7
+ cloud: Annotated[Optional[str], typer.Option("--cloud", "-c", help="☁️ Cloud configuration name (rclone config name)")] = None,
8
+ which: Annotated[
9
+ Optional[str], typer.Option("--which", "-w", help="📝 Comma-separated list of items to BACKUP (from backup.toml), or 'all' for all items")
10
+ ] = None,
11
+ repo: Annotated[
12
+ Literal["library", "l", "user", "u", "all", "a"],
13
+ typer.Option("--repo", "-r", help="📁 Which backup configuration to use: 'library' or 'user'"),
14
+ ] = "all",
15
+ # interactive: Annotated[bool, typer.Option("--interactive", "-i", help="🤔 Prompt the selection of which items to process")] = False,
16
+ ):
17
+ from machineconfig.scripts.python.helpers.helpers_devops.cli_backup_retrieve import main_backup_retrieve
18
+ match direction:
19
+ case "up" | "u":
20
+ direction_resolved = "BACKUP"
21
+ case "down" | "d":
22
+ direction_resolved = "RETRIEVE"
23
+ main_backup_retrieve(direction=direction_resolved, which=which, cloud=cloud, repo=repo)
24
+
25
+
26
+ def register_data(
27
+ path_local: Annotated[str, typer.Argument(..., help="Local file/folder path to back up.")],
28
+ group: Annotated[str, typer.Option("--group", "-g", help="Group section name in backup.toml.")] = "default",
29
+ name: Annotated[Optional[str], typer.Option("--name", "-n", help="Entry name inside the group in backup.toml.")] = None,
30
+ path_cloud: Annotated[Optional[str], typer.Option("--path-cloud", "-C", help="Cloud path override (optional).")] = None,
31
+ zip_: Annotated[bool, typer.Option("--zip/--no-zip", "-z/-nz", help="Zip before uploading.")] = False,
32
+ encrypt: Annotated[bool, typer.Option("--encrypt/--no-encrypt", "-e/-ne", help="Encrypt before uploading.")] = False,
33
+ rel2home: Annotated[Optional[bool], typer.Option("--rel2home/--no-rel2home", "-r/-nr", help="Treat the local path as relative to home.")] = None,
34
+ os: Annotated[str, typer.Option("--os", "-o", help="OS filter for this backup entry (comma-separated, or 'any').")] = "any",
35
+ ) -> None:
36
+ from machineconfig.scripts.python.helpers.helpers_devops.cli_backup_retrieve import register_backup_entry
37
+
38
+ try:
39
+ backup_path, entry_name, replaced = register_backup_entry(
40
+ path_local=path_local,
41
+ group=group,
42
+ entry_name=name,
43
+ path_cloud=path_cloud,
44
+ zip=zip_,
45
+ encrypt=encrypt,
46
+ rel2home=rel2home,
47
+ os=os,
48
+ )
49
+ except ValueError as exc:
50
+ msg = typer.style("Error: ", fg=typer.colors.RED) + str(exc)
51
+ typer.echo(msg)
52
+ raise typer.Exit(code=1)
53
+ action = "Updated" if replaced else "Added"
54
+ typer.echo(f"{action} backup entry '{entry_name}' in {backup_path}")
55
+
56
+
57
+ def get_app() -> typer.Typer:
58
+ app = typer.Typer(
59
+ name="data",
60
+ help="🗄️ [d] Backup and retrieve configuration files and directories to/from cloud storage using rclone.",
61
+ no_args_is_help=True,
62
+ add_help_option=True,
63
+ add_completion=False,
64
+ )
65
+
66
+ app.command(name="sync", no_args_is_help=True, hidden=False, help="🔄 [s] Sync (backup) files and directories to cloud storage using rclone.")(
67
+ sync
68
+ )
69
+
70
+ app.command(name="s", no_args_is_help=True, hidden=True)(sync)
71
+
72
+ app.command(name="register", no_args_is_help=True, hidden=False, help="📝 [r] Register a new backup entry in user backup.toml.")(register_data)
73
+
74
+ app.command(name="r", no_args_is_help=True, hidden=True)(register_data)
75
+
76
+ return app
@@ -1,9 +1,10 @@
1
1
 
2
- import machineconfig.scripts.python.helpers_devops.cli_share_file
3
- import machineconfig.scripts.python.helpers_devops.cli_share_terminal as cli_share_terminal
4
- import machineconfig.scripts.python.helpers_devops.cli_share_server as cli_share_server
2
+ import machineconfig.scripts.python.helpers.helpers_devops.cli_share_file
3
+ import machineconfig.scripts.python.helpers.helpers_devops.cli_share_terminal as cli_share_terminal
4
+ import machineconfig.scripts.python.helpers.helpers_devops.cli_share_server as cli_share_server
5
+ import machineconfig.scripts.python.helpers.helpers_devops.cli_ssh as cli_ssh
5
6
  import typer
6
- from typing import Optional, Annotated
7
+ from typing import Annotated
7
8
 
8
9
 
9
10
  def switch_public_ip_address(
@@ -11,48 +12,21 @@ def switch_public_ip_address(
11
12
  max_trials: Annotated[int, typer.Option(..., "--max-trials", "-m", help="Max number of switch attempts")] = 10,
12
13
  ) -> None:
13
14
  """🔁 Switch public IP address (Cloudflare WARP)"""
14
- import machineconfig.scripts.python.helpers_network.address_switch as helper
15
+ import machineconfig.scripts.python.helpers.helpers_network.address_switch as helper
15
16
  helper.switch_public_ip_address(max_trials=max_trials, wait_seconds=wait_seconds)
16
17
 
17
18
 
18
- def install_ssh_server():
19
- """📡 SSH install server""" # VRPR66JD$X3FQ3
20
- import platform
21
- if platform.system() == "Windows":
22
- from machineconfig.setup_windows import SSH_SERVER
23
- script = SSH_SERVER.read_text(encoding="utf-8")
24
- elif platform.system() == "Linux" or platform.system() == "Darwin":
25
- script = """
26
- sudo nala install openssh-server -y || true # try to install first
27
- # sudo nala purge openssh-server -y
28
- # sudo nala install openssh-server -y
29
- echo "✅ FINISHED installing openssh-server."""
30
- else:
31
- raise NotImplementedError(f"Platform {platform.system()} is not supported.")
32
- from machineconfig.utils.code import run_shell_script
33
- run_shell_script(script=script)
34
-
35
-
36
- def add_ssh_key(path: Annotated[Optional[str], typer.Option(..., help="Path to the public key file")] = None,
37
- choose: Annotated[bool, typer.Option(..., "--choose", "-c", help="Choose from available public keys in ~/.ssh/*.pub")] = False,
38
- value: Annotated[bool, typer.Option(..., "--value", "-v", help="Paste the public key content manually")] = False,
39
- github: Annotated[Optional[str], typer.Option(..., "--github", "-g", help="Fetch public keys from a GitHub username")] = None
40
- ):
41
- """🔑 SSH add pub key to this machine so its accessible by owner of corresponding private key."""
42
- import machineconfig.scripts.python.helpers_network.ssh_add_ssh_key as helper
43
- helper.main(pub_path=path, pub_choose=choose, pub_val=value, from_github=github)
44
- def add_ssh_identity():
45
- """🗝️ SSH add identity (private key) to this machine"""
46
- import machineconfig.scripts.python.helpers_network.ssh_add_identity as helper
47
- helper.main()
48
-
49
-
50
19
  def show_address() -> None:
51
20
  """📌 Show this computer addresses on network"""
52
- import machineconfig.scripts.python.helpers_network.address as helper
53
- loaded_json = helper.get_public_ip_address()
54
- from rich import print_json
55
- print_json(data=loaded_json)
21
+ import machineconfig.scripts.python.helpers.helpers_network.address as helper
22
+
23
+ try:
24
+ loaded_json = helper.get_public_ip_address()
25
+ from rich import print_json
26
+ print_json(data=loaded_json)
27
+ except Exception as e:
28
+ print(f"⚠️ Could not fetch public IP address: {e}")
29
+ loaded_json = {}
56
30
 
57
31
  from rich.table import Table
58
32
  from rich.console import Console
@@ -93,20 +67,16 @@ netsh interface portproxy add v4tov4 listenport={port} listenaddress=0.0.0.0 con
93
67
  """
94
68
  from machineconfig.utils.code import exit_then_run_shell_script
95
69
  exit_then_run_shell_script(code)
70
+ def open_wsl_port(ports: Annotated[str, typer.Argument(..., help="Comma-separated ports or port ranges (e.g., '8080,3000-3005,443')")]):
71
+ """🔥 Open Windows firewall ports for WSL (Windows only)."""
72
+ import machineconfig.utils.ssh_utils.wsl as wsl_utils
73
+ wsl_utils.open_wsl_port(ports)
74
+ def link_wsl_and_windows_home(windows_username: Annotated[str | None, typer.Option("--windows-username", "-u", help="Windows username to use (optional, auto-detected if not provided)")] = None):
75
+ """🔗 Link WSL home and Windows home directories."""
76
+ import machineconfig.utils.ssh_utils.wsl as wsl_utils
77
+ wsl_utils.link_wsl_and_windows(windows_username)
96
78
 
97
79
 
98
- def debug_ssh():
99
- """🐛 SSH debug"""
100
- from platform import system
101
- if system() == "Linux" or system() == "Darwin":
102
- import machineconfig.scripts.python.helpers_network.ssh_debug_linux as helper
103
- helper.ssh_debug_linux()
104
- elif system() == "Windows":
105
- import machineconfig.scripts.python.helpers_network.ssh_debug_windows as helper
106
- helper.ssh_debug_windows()
107
- else:
108
- raise NotImplementedError(f"Platform {system()} is not supported.")
109
-
110
80
  def wifi_select(
111
81
  ssid: Annotated[str, typer.Option("-n", "--ssid", help="🔗 SSID of WiFi (from config)")] = "MyPhoneHotSpot",
112
82
  manual: Annotated[bool, typer.Option("-m", "--manual", help="🔍 Manual network selection mode")] = False,
@@ -116,7 +86,7 @@ def wifi_select(
116
86
  from rich.panel import Panel
117
87
  from rich.prompt import Confirm
118
88
  from rich.console import Console
119
- from machineconfig.scripts.python.helpers_network.wifi_conn import try_config_connection, manual_network_selection, display_available_networks
89
+ from machineconfig.scripts.python.helpers.helpers_network.wifi_conn import try_config_connection, manual_network_selection, display_available_networks
120
90
  console = Console()
121
91
  console.print(Panel("📶 Welcome to the WiFi Connector Tool", title="[bold blue]WiFi Connection[/bold blue]", border_style="blue"))
122
92
 
@@ -166,17 +136,29 @@ sudo rm /etc/cloudflared/config.yml || true
166
136
  sudo $cloudflared_path --config $home_dir/.cloudflared/config.yml service install
167
137
  """
168
138
  print(code)
169
- def add_ip_exclusion_to_warp(ip: Annotated[str, typer.Option(..., "--ip", help="IP address to exclude from WARP")]):
139
+ print("NOTE: Please run the above commands in your terminal to apply the changes.")
140
+
141
+ def add_ip_exclusion_to_warp(ip: Annotated[str, typer.Option(..., "--ip", help="IP address(es) to exclude from WARP (Comma separated)")]):
142
+ ips = ip.split(",")
143
+ res = ""
144
+ for an_ip in ips:
145
+ res += f'sudo warp-cli tunnel ip add {an_ip}\n'
146
+ print(f"Adding IP exclusion to WARP for: {an_ip}")
170
147
  code = f"""
171
- sudo warp-cli tunnel ip add {ip}
148
+ {res}
149
+ echo "Restarting WARP connection..."
172
150
  sudo warp-cli disconnect
151
+ echo "Waiting for 2 seconds..."
152
+ sleep 2
153
+ echo "Reconnecting WARP..."
173
154
  sudo warp-cli connect
174
155
  """
175
156
  print(code)
157
+ print("NOTE: Please run the above commands in your terminal to apply the changes.")
176
158
 
177
159
 
178
160
  def get_app():
179
- nw_apps = typer.Typer(help="🔐 [n] Network subcommands", no_args_is_help=True, add_help_option=False, add_completion=False)
161
+ nw_apps = typer.Typer(help="🔐 [n] Network subcommands", no_args_is_help=True, add_help_option=True, add_completion=False)
180
162
  nw_apps.command(name="share-terminal", help="📡 [t] Share terminal via web browser")(cli_share_terminal.share_terminal)
181
163
  nw_apps.command(name="t", help="Share terminal via web browser", hidden=True)(cli_share_terminal.share_terminal)
182
164
 
@@ -186,17 +168,13 @@ def get_app():
186
168
  # app = cli_share_server.get_share_file_app()
187
169
  # nw_apps.add_typer(app, name="share-file", help="📁 [f] Share a file via relay server", no_args_is_help=True)
188
170
  # nw_apps.add_typer(app, name="f", help="Share a file via relay server", hidden=True, no_args_is_help=True)
189
- nw_apps.command(name="send", no_args_is_help=True, hidden=False, help="📁 [sx] send files from here.")(machineconfig.scripts.python.helpers_devops.cli_share_file.share_file_send)
190
- nw_apps.command(name="sx", no_args_is_help=True, hidden=True, help="📁 [sx] send files from here.")(machineconfig.scripts.python.helpers_devops.cli_share_file.share_file_send)
191
- nw_apps.command(name="receive", no_args_is_help=True, hidden=False, help="📁 [rx] receive files to here.")(machineconfig.scripts.python.helpers_devops.cli_share_file.share_file_receive)
192
- nw_apps.command(name="rx", no_args_is_help=True, hidden=True, help="📁 [rx] receive files to here.")(machineconfig.scripts.python.helpers_devops.cli_share_file.share_file_receive)
193
-
194
- nw_apps.command(name="install-ssh-server", help="📡 [i] Install SSH server")(install_ssh_server)
195
- nw_apps.command(name="i", help="Install SSH server", hidden=True)(install_ssh_server)
196
- nw_apps.command(name="add-ssh-key", help="🔑 [k] Add SSH public key to this machine", no_args_is_help=True)(add_ssh_key)
197
- nw_apps.command(name="k", help="Add SSH public key to this machine", hidden=True, no_args_is_help=True)(add_ssh_key)
198
- nw_apps.command(name="add-ssh-identity", help="🗝️ [A] Add SSH identity (private key) to this machine")(add_ssh_identity)
199
- nw_apps.command(name="A", help="Add SSH identity (private key) to this machine", hidden=True)(add_ssh_identity)
171
+ nw_apps.command(name="send", no_args_is_help=True, hidden=False, help="📁 [sx] send files from here.")(machineconfig.scripts.python.helpers.helpers_devops.cli_share_file.share_file_send)
172
+ nw_apps.command(name="sx", no_args_is_help=True, hidden=True, help="📁 [sx] send files from here.")(machineconfig.scripts.python.helpers.helpers_devops.cli_share_file.share_file_send)
173
+ nw_apps.command(name="receive", no_args_is_help=True, hidden=False, help="📁 [rx] receive files to here.")(machineconfig.scripts.python.helpers.helpers_devops.cli_share_file.share_file_receive)
174
+ nw_apps.command(name="rx", no_args_is_help=True, hidden=True, help="📁 [rx] receive files to here.")(machineconfig.scripts.python.helpers.helpers_devops.cli_share_file.share_file_receive)
175
+
176
+ nw_apps.add_typer(cli_ssh.get_app(), name="ssh", help="🔐 [S] SSH subcommands")
177
+ nw_apps.add_typer(cli_ssh.get_app(), name="S", help="SSH subcommands", hidden=True)
200
178
 
201
179
  nw_apps.command(name="show-address", help="📌 [a] Show this computer addresses on network")(show_address)
202
180
  nw_apps.command(name="a", help="Show this computer addresses on network", hidden=True)(show_address)
@@ -204,16 +182,18 @@ def get_app():
204
182
  nw_apps.command(name="switch-public-ip", help="🔁 [c] Switch public IP address (Cloudflare WARP)")(switch_public_ip_address)
205
183
  nw_apps.command(name="c", help="Switch public IP address (Cloudflare WARP)", hidden=True)(switch_public_ip_address)
206
184
 
207
- nw_apps.command(name="debug-ssh", help="🐛 [d] Debug SSH connection")(debug_ssh)
208
- nw_apps.command(name="d", help="Debug SSH connection", hidden=True)(debug_ssh)
209
-
210
185
  nw_apps.command(name="wifi-select", no_args_is_help=True, help="📶 [w] WiFi connection utility.")(wifi_select)
211
186
  nw_apps.command(name="w", no_args_is_help=True, hidden=True)(wifi_select)
212
187
 
213
188
  nw_apps.command(name="bind-wsl-port", help="🔌 [b] Bind WSL port to Windows host", no_args_is_help=True)(bind_wsl_port)
214
189
  nw_apps.command(name="b", help="Bind WSL port to Windows host", hidden=True, no_args_is_help=True)(bind_wsl_port)
190
+ nw_apps.command(name="open-wsl-port", no_args_is_help=True, help="🔥 [o] Open Windows firewall ports for WSL.", hidden=False)(open_wsl_port)
191
+ nw_apps.command(name="o", no_args_is_help=True, help="Open Windows firewall ports for WSL.", hidden=True)(open_wsl_port)
192
+ nw_apps.command(name="link-wsl-windows", no_args_is_help=False, help="🔗 [l] Link WSL home and Windows home directories.", hidden=False)(link_wsl_and_windows_home)
193
+ nw_apps.command(name="l", no_args_is_help=False, help="Link WSL home and Windows home directories.", hidden=True)(link_wsl_and_windows_home)
194
+
215
195
 
216
- nw_apps.command(name="reset-cloudflare-tunnel", help="☁️ [r] Reset Cloudflare tunnel service")(reset_cloudflare_tunnel)
196
+ nw_apps.command(name="reset-cloudflare-tunnel", help="☁️ [r] Reset Cloudflare tunnel service")(reset_cloudflare_tunnel)
217
197
  nw_apps.command(name="r", help="Reset Cloudflare tunnel service", hidden=True)(reset_cloudflare_tunnel)
218
198
  nw_apps.command(name="add-ip-exclusion-to-warp", help="🚫 [p] Add IP exclusion to WARP")(add_ip_exclusion_to_warp)
219
199
  nw_apps.command(name="p", help="Add IP exclusion to WARP", hidden=True)(add_ip_exclusion_to_warp)
@@ -0,0 +1,274 @@
1
+ """Repos CLI powered by Typer.
2
+
3
+ # TODO use gh api user --jq '.login' to get the username and use it to clone the repos.
4
+ in the event that username@github.com is not mentioned in the remote url.
5
+
6
+ """
7
+
8
+ from pathlib import Path
9
+ from typing import Annotated, Optional
10
+ import typer
11
+ from machineconfig.scripts.python.helpers.helpers_repos.cloud_repo_sync import main as secure_repo_main
12
+
13
+
14
+ def _resolve_directory(directory: Optional[str]) -> Path:
15
+ if directory is None:
16
+ directory = Path.cwd().as_posix()
17
+ typer.echo(f"📁 Using directory: {directory}")
18
+ return Path(directory).expanduser().absolute().resolve()
19
+
20
+
21
+ def push(directory: Annotated[Optional[str], typer.Argument(help="📁 Directory containing repo(s).")] = None, recursive: Annotated[bool, typer.Option("--recursive", "-r", help="🔍 Recurse into nested repositories.")] = False, auto_uv_sync: Annotated[bool, typer.Option("--uv-sync/--no-uv-sync", "-u/-ns", help="Automatic uv sync after pulls.")] = False) -> None:
22
+ """🚀 Push changes across repositories."""
23
+ repos_root = _resolve_directory(directory)
24
+ from machineconfig.scripts.python.helpers.helpers_repos.action import perform_git_operations
25
+ from machineconfig.utils.path_extended import PathExtended
26
+ perform_git_operations(repos_root=PathExtended(repos_root), pull=False, commit=False, push=True, recursive=recursive, auto_uv_sync=auto_uv_sync)
27
+
28
+
29
+ def pull(directory: Annotated[Optional[str], typer.Argument(help="📁 Directory containing repo(s).")] = None, recursive: Annotated[bool, typer.Option("--recursive", "-r", help="🔍 Recurse into nested repositories.")] = False, auto_uv_sync: Annotated[bool, typer.Option("--uv-sync/--no-uv-sync", "-u/-ns", help="Automatic uv sync after pulls.")] = False) -> None:
30
+ """⬇️ Pull changes across repositories."""
31
+ repos_root = _resolve_directory(directory)
32
+ from machineconfig.scripts.python.helpers.helpers_repos.action import perform_git_operations
33
+ from machineconfig.utils.path_extended import PathExtended
34
+ perform_git_operations(repos_root=PathExtended(repos_root), pull=True, commit=False, push=False, recursive=recursive, auto_uv_sync=auto_uv_sync)
35
+
36
+
37
+ def commit(directory: Annotated[Optional[str], typer.Argument(help="📁 Directory containing repo(s).")] = None, recursive: Annotated[bool, typer.Option("--recursive", "-r", help="🔍 Recurse into nested repositories.")] = False, auto_uv_sync: Annotated[bool, typer.Option("--uv-sync/--no-uv-sync", "-u/-ns", help="Automatic uv sync after pulls.")] = False) -> None:
38
+ """💾 Commit changes across repositories."""
39
+ repos_root = _resolve_directory(directory)
40
+ from machineconfig.scripts.python.helpers.helpers_repos.action import perform_git_operations
41
+ from machineconfig.utils.path_extended import PathExtended
42
+ perform_git_operations(repos_root=PathExtended(repos_root), pull=False, commit=True, push=False, recursive=recursive, auto_uv_sync=auto_uv_sync)
43
+
44
+
45
+ def sync(directory: Annotated[Optional[str], typer.Argument(help="📁 Directory containing repo(s).")] = None, recursive: Annotated[bool, typer.Option("--recursive", "-r", help="🔍 Recurse into nested repositories.")] = False, auto_uv_sync: Annotated[bool, typer.Option("--uv-sync/--no-uv-sync", "-u/-ns", help="Automatic uv sync after pulls.")] = False) -> None:
46
+ """🔄 Pull, commit, and push changes across repositories."""
47
+ repos_root = _resolve_directory(directory)
48
+ from machineconfig.scripts.python.helpers.helpers_repos.action import perform_git_operations
49
+ from machineconfig.utils.path_extended import PathExtended
50
+ perform_git_operations(repos_root=PathExtended(repos_root), pull=True, commit=True, push=True, recursive=recursive, auto_uv_sync=auto_uv_sync)
51
+
52
+
53
+ def capture(directory: Annotated[Optional[str], typer.Argument(help="📁 Directory containing repo(s).")] = None) -> None:
54
+ """📝 Record repositories into a repos.json specification."""
55
+ from machineconfig.scripts.python.helpers.helpers_repos.record import main_record as record_repos
56
+ save_path = record_repos(repos_root_str=directory)
57
+ print(f"\n✅ Saved repository specification to {save_path}")
58
+
59
+
60
+ def clone(directory: Annotated[str, typer.Argument(help="📁 Directory containing repo(s).")] = ".",
61
+ specs_path: Annotated[Optional[str], typer.Option("--specs-path", "-s", help="Path to repos.json specification file.")] = None,
62
+ interactive: Annotated[bool, typer.Option("--interactive/--no-interactive", "-i/-ni", help="Select interactively.")]=False
63
+ ) -> None:
64
+ """📥 Clone repositories described by a repos.json specification."""
65
+ if interactive:
66
+ from machineconfig.scripts.python.helpers.helpers_devops.cli_config_dotfile import BACKUP_ROOT_PRIVATE, BACKUP_ROOT_PUBLIC, get_original_path_from_backup_path
67
+ results_public = list(BACKUP_ROOT_PUBLIC.rglob("repos.json"))
68
+ results_private = list(BACKUP_ROOT_PRIVATE.rglob("repos.json"))
69
+ if len(results_public) + len(results_private) == 0:
70
+ print("❌ No repos.json specifications found in backup directories.")
71
+ return
72
+ from machineconfig.utils.options import choose_from_options
73
+ chosen_files = choose_from_options(options=[str(p) for p in results_public + results_private], msg="Select a repos.json specification to clone from:", multi=True, tv=True)
74
+ for file in chosen_files:
75
+ if str(file).startswith(str(BACKUP_ROOT_PRIVATE)):
76
+ original_path = get_original_path_from_backup_path(Path(file), sensitivity="private", destination=None, shared=False)
77
+ else:
78
+ original_path = get_original_path_from_backup_path(Path(file), sensitivity="public", destination=None, shared=False)
79
+ typer.echo("\n📥 Cloning or checking out repositories...")
80
+ dir_obj = _resolve_directory(str(original_path))
81
+ spec_path_default = dir_obj.joinpath("repos.json")
82
+ from machineconfig.scripts.python.helpers.helpers_devops.cli_config_dotfile import get_backup_path
83
+ spec_path_self_managed = get_backup_path(orig_path=spec_path_default, sensitivity="private", destination=None, shared=False)
84
+ from machineconfig.scripts.python.helpers.helpers_repos.clone import clone_repos
85
+ clone_repos(spec_path=spec_path_self_managed, preferred_remote=None, checkout_branch_flag=False, checkout_commit_flag=False)
86
+ return
87
+ if specs_path is not None:
88
+ spec_path_self_managed = Path(specs_path).expanduser().absolute()
89
+ else:
90
+ dir_obj = _resolve_directory(directory)
91
+ spec_path_default = dir_obj.joinpath("repos.json")
92
+ from machineconfig.scripts.python.helpers.helpers_devops.cli_config_dotfile import get_backup_path
93
+ spec_path_self_managed = get_backup_path(orig_path=spec_path_default, sensitivity="private", destination=None, shared=False)
94
+ if not spec_path_self_managed.exists():
95
+ print(f"❌ Specification file not found: {spec_path_self_managed}. Ensure this file exists or provide it explicitly using --specs-path.")
96
+ return
97
+ from machineconfig.scripts.python.helpers.helpers_repos.clone import clone_repos
98
+ clone_repos(spec_path=spec_path_self_managed, preferred_remote=None, checkout_branch_flag=False, checkout_commit_flag=False)
99
+
100
+
101
+ def checkout_command(directory: Annotated[Optional[str], typer.Argument(help="📁 Directory containing repo(s).")] = None) -> None:
102
+ """🔀 Check out specific commits listed in the specification."""
103
+ typer.echo("\n📥 Cloning or checking out repositories...")
104
+ dir_obj = _resolve_directory(directory)
105
+ spec_path_default = dir_obj.joinpath("repos.json")
106
+ from machineconfig.scripts.python.helpers.helpers_devops.cli_config_dotfile import get_backup_path
107
+ spec_path_self_managed = get_backup_path(orig_path=spec_path_default, sensitivity="private", destination=None, shared=False)
108
+ from machineconfig.scripts.python.helpers.helpers_repos.clone import clone_repos
109
+ clone_repos(spec_path=spec_path_self_managed, preferred_remote=None, checkout_branch_flag=False, checkout_commit_flag=True)
110
+
111
+
112
+ def checkout_to_branch_command(directory: Annotated[Optional[str], typer.Argument(help="📁 Directory containing repo(s).")] = None) -> None:
113
+ """🔀 Check out to the main branch defined in the specification."""
114
+ typer.echo("\n📥 Cloning or checking out repositories...")
115
+ dir_obj = _resolve_directory(directory)
116
+ spec_path_default = dir_obj.joinpath("repos.json")
117
+ from machineconfig.scripts.python.helpers.helpers_devops.cli_config_dotfile import get_backup_path
118
+ spec_path_self_managed = get_backup_path(orig_path=spec_path_default, sensitivity="private", destination=None, shared=False)
119
+ from machineconfig.scripts.python.helpers.helpers_repos.clone import clone_repos
120
+ clone_repos(spec_path=spec_path_self_managed, preferred_remote=None, checkout_branch_flag=True, checkout_commit_flag=False)
121
+
122
+
123
+ def count_lines_in_repo(repo_path: Annotated[str, typer.Argument(..., help="Path to the git repository")]):
124
+ # def func(repo_path: str):
125
+ # from machineconfig.scripts.python.helpers.helpers_repos import repo_analyzer_1
126
+ # repo_analyzer_1.count_historical_line_edits(repo_path=repo_path)
127
+ # from machineconfig.utils.code import run_lambda_function
128
+ # run_lambda_function(lambda: func(repo_path=repo_path), uv_project_dir=None, uv_with=["machineconfig>=8.50"])
129
+ from machineconfig.scripts.python.helpers.helpers_repos import repo_analyzer_1
130
+ try:
131
+ repo_analyzer_1.count_historical_line_edits(repo_path=repo_path)
132
+ except Exception as e:
133
+ typer.echo(f"❌ Error counting lines in repo {repo_path}: {e}")
134
+
135
+
136
+ def print_python_files_by_size(repo_path: Annotated[str, typer.Argument(..., help="Path to the git repository")]):
137
+ # def func(repo_path: str):
138
+ # from machineconfig.scripts.python.helpers.helpers_repos.repo_analyzer_2 import print_python_files_by_size_impl
139
+ # print_python_files_by_size_impl(repo_path=repo_path)
140
+ # from machineconfig.utils.code import run_lambda_function
141
+ # run_lambda_function(lambda: func(repo_path=repo_path), uv_project_dir=None, uv_with=["machineconfig[plot]>=8.50"])
142
+ from machineconfig.scripts.python.helpers.helpers_repos.repo_analyzer_2 import print_python_files_by_size_impl
143
+ print_python_files_by_size_impl(repo_path=repo_path)
144
+
145
+
146
+ def analyze_repo_development(repo_path: Annotated[str, typer.Argument(..., help="Path to the git repository")]):
147
+ # def func(repo_path: str):
148
+ # from machineconfig.scripts.python.helpers.helpers_repos.repo_analyzer_2 import analyze_over_time
149
+ # analyze_over_time(repo_path=repo_path)
150
+ # from machineconfig.utils.code import run_lambda_function
151
+ # run_lambda_function(lambda: func(repo_path=repo_path), uv_project_dir=None, uv_with=["machineconfig[plot]>=8.50"])
152
+ from machineconfig.scripts.python.helpers.helpers_repos.repo_analyzer_2 import analyze_over_time
153
+ analyze_over_time(repo_path=repo_path)
154
+
155
+
156
+ def gource_viz(
157
+ repo: Annotated[str, typer.Option(..., "--repo", "-r", help="Path to git repository to visualize")] = ".",
158
+ 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,
159
+ resolution: Annotated[str, typer.Option(..., "--resolution", "-res", help="Video resolution (e.g., 1920x1080, 1280x720)")] = "1920x1080",
160
+ seconds_per_day: Annotated[float, typer.Option(..., "--seconds-per-day", "-spd", help="Speed of simulation (lower = faster)")] = 0.1,
161
+ auto_skip_seconds: Annotated[float, typer.Option(..., "--auto-skip-seconds", "-as", help="Skip to next entry if nothing happens for X seconds")] = 1.0,
162
+ title: Annotated[Optional[str], typer.Option(..., "--title", "-t", help="Title for the visualization")] = None,
163
+ hide_items: Annotated[list[str], typer.Option(..., "--hide", "-h", help="Items to hide: bloom, date, dirnames, files, filenames, mouse, progress, root, tree, users, usernames")] = [],
164
+ key_items: Annotated[bool, typer.Option(..., "--key", "-k", help="Show file extension key")] = False,
165
+ fullscreen: Annotated[bool, typer.Option(..., "--fullscreen", "-f", help="Run in fullscreen mode")] = False,
166
+ viewport: Annotated[Optional[str], typer.Option(..., "--viewport", "-v", help="Camera viewport (e.g., '1000x1000')")] = None,
167
+ start_date: Annotated[Optional[str], typer.Option(..., "--start-date", help="Start date (YYYY-MM-DD)")] = None,
168
+ stop_date: Annotated[Optional[str], typer.Option(..., "--stop-date", help="Stop date (YYYY-MM-DD)")] = None,
169
+ user_image_dir: Annotated[Optional[Path], typer.Option(..., "--user-image-dir", help="Directory with user avatar images")] = None,
170
+ max_files: Annotated[int, typer.Option(..., "--max-files", help="Maximum number of files to show (0 = no limit)")] = 0,
171
+ max_file_lag: Annotated[float, typer.Option(..., "--max-file-lag", help="Max time files remain on screen after last change")] = 5.0,
172
+ file_idle_time: Annotated[int, typer.Option(..., "--file-idle-time", help="Time in seconds files remain idle before being removed")] = 0,
173
+ framerate: Annotated[int, typer.Option(..., "--framerate", help="Frames per second for video output")] = 60,
174
+ background_color: Annotated[str, typer.Option(..., "--background-color", help="Background color in hex (e.g., 000000 for black)")] = "000000",
175
+ font_size: Annotated[int, typer.Option(..., "--font-size", help="Font size")] = 22,
176
+ camera_mode: Annotated[str, typer.Option(..., "--camera-mode", help="Camera mode: overview or track")] = "overview",
177
+ self: Annotated[bool, typer.Option(..., "--self", help="Clone machineconfig repository and act on it")] = False,
178
+ ) -> None:
179
+ """🎬 Visualize repository activity using Gource."""
180
+ from machineconfig.scripts.python.helpers.helpers_repos.grource import visualize
181
+ if self:
182
+ repo_path = Path.home().joinpath("machineconfig")
183
+ if not repo_path.exists():
184
+ import git
185
+ repo_url = "https://github.com/thisismygitrepo/machineconfig.git"
186
+ git.Repo.clone_from(repo_url, to_path=repo_path.as_posix())
187
+ repo = repo_path.as_posix()
188
+ visualize(repo=repo, output_file=output_file, resolution=resolution, seconds_per_day=seconds_per_day,
189
+ auto_skip_seconds=auto_skip_seconds, title=title, hide_items=hide_items, key_items=key_items,
190
+ fullscreen=fullscreen, viewport=viewport, start_date=start_date, stop_date=stop_date,
191
+ user_image_dir=user_image_dir, max_files=max_files, max_file_lag=max_file_lag,
192
+ file_idle_time=file_idle_time, framerate=framerate, background_color=background_color,
193
+ font_size=font_size, camera_mode=camera_mode)
194
+
195
+
196
+ def cleanup(repo: Annotated[Optional[str], typer.Argument(help="📁 Directory containing repo(s).")] = None, recursive: Annotated[bool, typer.Option("--recursive", "-r", help="🔍 Recurse into nested repositories.")] = False) -> None:
197
+ """🧹 Clean repository directories from cache files."""
198
+ if repo is None:
199
+ repo = Path.cwd().as_posix()
200
+
201
+ arg_path = Path(repo).expanduser().absolute()
202
+ from git import Repo, InvalidGitRepositoryError
203
+ if not recursive:
204
+ # Check if the directory is a git repo
205
+ try:
206
+ Repo(str(arg_path), search_parent_directories=False)
207
+ except InvalidGitRepositoryError:
208
+ typer.echo(f"❌ {arg_path} is not a git repository. Use -r flag for recursive cleanup.")
209
+ return
210
+ # Run cleanup on this repo
211
+ repos_to_clean = [arg_path]
212
+ else:
213
+ # Find all git repos recursively under the directory
214
+ git_dirs = list(arg_path.rglob('.git'))
215
+ repos_to_clean = [git_dir.parent for git_dir in git_dirs if git_dir.is_dir()]
216
+ if not repos_to_clean:
217
+ typer.echo(f"❌ No git repositories found under {arg_path}")
218
+ return
219
+
220
+ for repo_path in repos_to_clean:
221
+ typer.echo(f"🧹 Cleaning {repo_path}")
222
+ script = fr"""
223
+ cd "{repo_path}"
224
+ uv run --with cleanpy cleanpy .
225
+ # mcinit .
226
+ # find "." -type f \( -name "*.py" -o -name "*.md" -o -name "*.json" \) -not -path "*/\.*" -not -path "*/__pycache__/*" -print0 | xargs -0 sed -i 's/[[:space:]]*$//'
227
+ """
228
+ from machineconfig.utils.code import run_shell_script
229
+ run_shell_script(script)
230
+
231
+
232
+ def get_app():
233
+ repos_apps = typer.Typer(help="📁 [r] Manage development repositories", no_args_is_help=True, add_help_option=True, add_completion=False)
234
+ mirror_app = typer.Typer(help="🔄 [m] Manage repository specifications and syncing", no_args_is_help=True, add_help_option=True, add_completion=False)
235
+ repos_apps.add_typer(mirror_app, name="mirror", help="🔄 [m] mirror repositories using saved specs")
236
+ repos_apps.add_typer(mirror_app, name="m", help="mirror repositories using saved specs", hidden=True)
237
+
238
+ repos_apps.command(name="push", help="🚀 [p] Push changes across repositories")(push)
239
+ repos_apps.command(name="p", help="Push changes across repositories", hidden=True)(push)
240
+ repos_apps.command(name="pull", help="⬇️ [P] Pull changes across repositories")(pull)
241
+ repos_apps.command(name="P", help="Pull changes across repositories", hidden=True)(pull)
242
+ repos_apps.command(name="commit", help="💾 [c] Commit changes across repositories")(commit)
243
+ repos_apps.command(name="c", help="Commit changes across repositories", hidden=True)(commit)
244
+ repos_apps.command(name="sync", help="🔄 [y] Pull, commit, and push changes across repositories")(sync)
245
+ repos_apps.command(name="y", help="Pull, commit, and push changes across repositories", hidden=True)(sync)
246
+ repos_apps.command(name="analyze", help="📊 [a] Analyze repository development over time")(analyze_repo_development)
247
+ repos_apps.command(name="a", help="Analyze repository development over time", hidden=True)(analyze_repo_development)
248
+
249
+ repos_apps.command(name="secure", help="🔐 [s] Securely sync git repository to/from cloud with encryption")(secure_repo_main)
250
+ repos_apps.command(name="s", help="Securely sync git repository to/from cloud with encryption", hidden=True)(secure_repo_main)
251
+
252
+ repos_apps.command(name="viz", help="🎬 [v] Visualize repository activity using Gource")(gource_viz)
253
+ repos_apps.command(name="v", help="Visualize repository activity using Gource", hidden=True)(gource_viz)
254
+
255
+ repos_apps.command(name="count-lines", help="📄 [l] Count python lines of code in current repo + historical edits.")(count_lines_in_repo)
256
+ repos_apps.command(name="l", help="Count python lines of code in current repo + historical edits.", hidden=True)(count_lines_in_repo)
257
+
258
+ repos_apps.command(name="cleanup", help="🧹 [n] Clean repository directories from cache files")(cleanup)
259
+ repos_apps.command(name="n", help="Clean repository directories from cache files", hidden=True)(cleanup)
260
+
261
+ mirror_app.command(name="capture", help="📝 [cap] Record repositories into a repos.json specification")(capture)
262
+ mirror_app.command(name="cap", help="Record repositories into a repos.json specification", hidden=True)(capture)
263
+
264
+ mirror_app.command(name="clone", help="📥 [clo] Clone repositories described by a repos.json specification")(clone)
265
+ mirror_app.command(name="clo", help="Clone repositories described by a repos.json specification", hidden=True)(clone)
266
+
267
+ mirror_app.command(name="checkout-to-commit", help="🔀 [ctc] Check out specific commits listed in the specification")(checkout_command)
268
+ mirror_app.command(name="ctc", help="Check out specific commits listed in the specification", hidden=True)(checkout_command)
269
+
270
+ mirror_app.command(name="checkout-to-branch", help="🔀 [ctb] Check out to the main branch defined in the specification")(checkout_to_branch_command)
271
+ mirror_app.command(name="ctb", help="Check out to the main branch defined in the specification", hidden=True)(checkout_to_branch_command)
272
+
273
+ return repos_apps
274
+