machineconfig 7.98__py3-none-any.whl → 8.61__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 (353) 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 +271 -152
  13. machineconfig/jobs/installer/linux_scripts/docker.sh +6 -9
  14. machineconfig/jobs/installer/package_groups.py +11 -9
  15. machineconfig/jobs/installer/{custom → python_scripts}/boxes.py +1 -2
  16. machineconfig/jobs/installer/{custom_dev → python_scripts}/brave.py +1 -1
  17. machineconfig/jobs/installer/{custom_dev → python_scripts}/code.py +10 -8
  18. machineconfig/jobs/installer/{custom → python_scripts}/hx.py +30 -13
  19. machineconfig/jobs/installer/{custom_dev → python_scripts}/nerdfont.py +1 -1
  20. machineconfig/jobs/installer/{custom_dev → python_scripts}/nerfont_windows_helper.py +6 -5
  21. machineconfig/jobs/installer/{custom_dev → python_scripts}/sysabc.py +28 -43
  22. machineconfig/jobs/installer/{custom_dev → python_scripts}/wezterm.py +1 -1
  23. machineconfig/jobs/installer/{custom → python_scripts}/yazi.py +39 -19
  24. machineconfig/jobs/scripts/powershell_scripts/cmatrix.ps1 +52 -0
  25. machineconfig/jobs/scripts_dynamic/a.py +428 -0
  26. machineconfig/logger.py +1 -1
  27. machineconfig/profile/create_helper.py +21 -10
  28. machineconfig/profile/create_links.py +77 -20
  29. machineconfig/profile/create_links_export.py +63 -58
  30. machineconfig/profile/create_shell_profile.py +14 -0
  31. machineconfig/profile/mapper_data.toml +45 -0
  32. machineconfig/profile/mapper_dotfiles.toml +249 -0
  33. machineconfig/scripts/python/agents.py +76 -171
  34. machineconfig/scripts/python/ai/initai.py +3 -1
  35. machineconfig/scripts/python/ai/scripts/__init__.py +1 -0
  36. machineconfig/scripts/python/ai/scripts/lint_and_type_check.ps1 +2 -0
  37. machineconfig/scripts/python/ai/scripts/lint_and_type_check.sh +8 -6
  38. machineconfig/scripts/python/ai/solutions/claude/claude.py +1 -1
  39. machineconfig/scripts/python/ai/solutions/cline/cline.py +1 -1
  40. machineconfig/scripts/python/ai/solutions/copilot/github_copilot.py +1 -1
  41. machineconfig/scripts/python/ai/solutions/copilot/instructions/python/dev.instructions.md +29 -0
  42. machineconfig/scripts/python/ai/solutions/crush/crush.py +1 -1
  43. machineconfig/scripts/python/ai/solutions/cursor/cursors.py +1 -1
  44. machineconfig/scripts/python/ai/solutions/gemini/gemini.py +1 -1
  45. machineconfig/scripts/python/ai/solutions/gemini/settings.json +3 -0
  46. machineconfig/scripts/python/ai/{solutions → utils}/generic.py +2 -15
  47. machineconfig/scripts/python/ai/utils/vscode_tasks.py +6 -3
  48. machineconfig/scripts/python/cloud.py +58 -11
  49. machineconfig/scripts/python/croshell.py +4 -155
  50. machineconfig/scripts/python/devops.py +57 -38
  51. machineconfig/scripts/python/devops_navigator.py +17 -3
  52. machineconfig/scripts/python/fire_jobs.py +10 -193
  53. machineconfig/scripts/python/ftpx.py +5 -224
  54. machineconfig/scripts/python/graph/cli_graph.json +8743 -0
  55. machineconfig/scripts/python/{env_manager → helper_env}/path_manager_tui.py +2 -2
  56. machineconfig/scripts/python/{env_manager → helpers/helper_env}/env_manager_tui.py +1 -1
  57. machineconfig/scripts/python/helpers/helper_env/path_manager_tui.py +228 -0
  58. machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/agentic_frameworks/fire_crush.py +1 -1
  59. machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/agentic_frameworks/fire_cursor_agents.py +1 -1
  60. machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/agentic_frameworks/fire_gemini.py +1 -1
  61. machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/agentic_frameworks/fire_qwen.py +1 -1
  62. machineconfig/scripts/python/helpers/helpers_agents/agents_impl.py +168 -0
  63. machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/fire_agents_help_launch.py +10 -7
  64. machineconfig/scripts/python/helpers/helpers_agents/privacy/configs/aichat/config.yaml +5 -0
  65. machineconfig/scripts/python/helpers/helpers_agents/privacy/configs/aider/.aider.conf.yml +2 -0
  66. machineconfig/scripts/python/helpers/helpers_agents/privacy/configs/copilot/config.yml +1 -0
  67. machineconfig/scripts/python/helpers/helpers_agents/privacy/configs/crush/crush.json +10 -0
  68. machineconfig/scripts/python/helpers/helpers_agents/privacy/configs/gemini/settings.json +12 -0
  69. machineconfig/scripts/python/helpers/helpers_agents/privacy/privacy.py +109 -0
  70. machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/templates/template.sh +3 -1
  71. machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/cloud_copy.py +6 -6
  72. machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/cloud_mount.py +10 -5
  73. machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/cloud_sync.py +4 -4
  74. machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/helpers2.py +1 -1
  75. machineconfig/scripts/python/helpers/helpers_croshell/croshell_impl.py +229 -0
  76. machineconfig/scripts/python/{helpers_croshell → helpers/helpers_croshell}/scheduler.py +4 -4
  77. machineconfig/scripts/python/{helpers_croshell → helpers/helpers_croshell}/start_slidev.py +7 -6
  78. machineconfig/scripts/python/helpers/helpers_devops/backup_config.py +149 -0
  79. machineconfig/scripts/python/helpers/helpers_devops/cli_backup_retrieve.py +262 -0
  80. machineconfig/scripts/python/helpers/helpers_devops/cli_config.py +130 -0
  81. machineconfig/scripts/python/helpers/helpers_devops/cli_config_dotfile.py +274 -0
  82. machineconfig/scripts/python/helpers/helpers_devops/cli_config_mount.py +77 -0
  83. machineconfig/scripts/python/helpers/helpers_devops/cli_data.py +71 -0
  84. machineconfig/scripts/python/helpers/helpers_devops/cli_nw.py +285 -0
  85. machineconfig/scripts/python/helpers/helpers_devops/cli_repos.py +274 -0
  86. machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/cli_self.py +84 -33
  87. machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/cli_share_file.py +44 -30
  88. machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/cli_share_server.py +26 -43
  89. machineconfig/scripts/python/helpers/helpers_devops/cli_share_temp.py +69 -0
  90. machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/cli_share_terminal.py +12 -6
  91. machineconfig/scripts/python/helpers/helpers_devops/cli_ssh.py +167 -0
  92. machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/devops_status.py +12 -6
  93. machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/devops_update_repos.py +1 -1
  94. machineconfig/scripts/python/{interactive.py → helpers/helpers_devops/interactive.py} +64 -50
  95. machineconfig/scripts/python/helpers/helpers_devops/mount_helpers/commands.py +25 -0
  96. machineconfig/scripts/python/helpers/helpers_devops/mount_helpers/device_entry.py +17 -0
  97. machineconfig/scripts/python/helpers/helpers_devops/mount_helpers/devices.py +17 -0
  98. machineconfig/scripts/python/helpers/helpers_devops/mount_helpers/linux.py +103 -0
  99. machineconfig/scripts/python/helpers/helpers_devops/mount_helpers/macos.py +100 -0
  100. machineconfig/scripts/python/helpers/helpers_devops/mount_helpers/selection.py +47 -0
  101. machineconfig/scripts/python/helpers/helpers_devops/mount_helpers/utils.py +28 -0
  102. machineconfig/scripts/python/helpers/helpers_devops/mount_helpers/windows.py +91 -0
  103. machineconfig/scripts/python/helpers/helpers_devops/run_script.py +197 -0
  104. machineconfig/scripts/python/helpers/helpers_devops/themes/choose_starship_theme.ps1 +41 -0
  105. machineconfig/scripts/python/helpers/helpers_devops/themes/choose_starship_theme.sh +48 -0
  106. machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/themes/choose_wezterm_theme.py +3 -3
  107. machineconfig/scripts/python/{helpers_fire_command → helpers/helpers_fire_command}/file_wrangler.py +1 -0
  108. machineconfig/scripts/python/{helpers_fire_command → helpers/helpers_fire_command}/fire_jobs_args_helper.py +1 -0
  109. machineconfig/scripts/python/helpers/helpers_fire_command/fire_jobs_impl.py +233 -0
  110. machineconfig/scripts/python/{helpers_fire_command → helpers/helpers_fire_command}/fire_jobs_route_helper.py +3 -3
  111. machineconfig/scripts/python/helpers/helpers_fire_command/fire_jobs_streamlit_helper.py +0 -0
  112. machineconfig/scripts/python/helpers/helpers_msearch/msearch_impl.py +248 -0
  113. machineconfig/scripts/python/{helpers_msearch → helpers/helpers_msearch}/scripts_linux/fzfg +4 -3
  114. machineconfig/scripts/python/helpers/helpers_msearch/scripts_linux/search_with_context.sh +48 -0
  115. machineconfig/scripts/python/{helpers_msearch → helpers/helpers_msearch}/scripts_windows/fzfg.ps1 +2 -7
  116. machineconfig/scripts/python/helpers/helpers_navigator/__init__.py +20 -0
  117. machineconfig/scripts/python/helpers/helpers_navigator/cli_graph_loader.py +234 -0
  118. machineconfig/scripts/python/{helpers_navigator → helpers/helpers_navigator}/command_builder.py +61 -13
  119. machineconfig/scripts/python/helpers/helpers_navigator/command_detail.py +153 -0
  120. machineconfig/scripts/python/helpers/helpers_navigator/command_tree.py +45 -0
  121. machineconfig/scripts/python/{helpers_navigator → helpers/helpers_navigator}/data_models.py +18 -11
  122. machineconfig/scripts/python/{helpers_navigator → helpers/helpers_navigator}/main_app.py +5 -5
  123. machineconfig/scripts/python/helpers/helpers_network/__init__.py +0 -0
  124. machineconfig/scripts/python/{helpers_network → helpers/helpers_network}/address.py +52 -10
  125. machineconfig/scripts/python/helpers/helpers_network/address_switch.py +78 -0
  126. machineconfig/scripts/python/helpers/helpers_network/ftpx_impl.py +276 -0
  127. machineconfig/scripts/python/helpers/helpers_network/ssh/__init__.py +0 -0
  128. machineconfig/scripts/python/helpers/helpers_network/ssh/ssh_add_identity.py +73 -0
  129. machineconfig/scripts/python/helpers/helpers_network/ssh/ssh_add_key_windows.py +23 -0
  130. machineconfig/scripts/python/helpers/helpers_network/ssh/ssh_add_ssh_key.py +169 -0
  131. machineconfig/scripts/python/helpers/helpers_network/ssh/ssh_cloud_init.py +33 -0
  132. machineconfig/scripts/python/helpers/helpers_network/ssh/ssh_debug_linux.py +338 -0
  133. machineconfig/scripts/python/helpers/helpers_network/ssh/ssh_debug_linux_utils.py +35 -0
  134. machineconfig/scripts/python/helpers/helpers_network/ssh/ssh_debug_windows.py +245 -0
  135. machineconfig/scripts/python/helpers/helpers_network/ssh/ssh_debug_windows_utils.py +34 -0
  136. machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/action.py +3 -3
  137. machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/action_helper.py +3 -3
  138. machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/cloud_repo_sync.py +120 -37
  139. machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/grource.py +3 -2
  140. machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/record.py +33 -13
  141. machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/repo_analyzer_2.py +63 -19
  142. machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/update.py +0 -6
  143. machineconfig/scripts/python/helpers/helpers_search/script_help.py +81 -0
  144. machineconfig/scripts/python/helpers/helpers_sessions/__init__.py +0 -0
  145. machineconfig/scripts/python/helpers/helpers_sessions/attach_impl.py +87 -0
  146. machineconfig/scripts/python/helpers/helpers_sessions/sessions_impl.py +114 -0
  147. machineconfig/scripts/python/{helpers_sessions → helpers/helpers_sessions}/sessions_multiprocess.py +1 -2
  148. machineconfig/scripts/python/helpers/helpers_sessions/utils.py +69 -0
  149. machineconfig/scripts/python/{helpers_utils → helpers/helpers_utils}/download.py +1 -1
  150. machineconfig/scripts/python/{helpers_devops/cli_utils.py → helpers/helpers_utils/pdf.py} +2 -2
  151. machineconfig/scripts/python/{helpers_utils/path.py → helpers/helpers_utils/python.py} +65 -40
  152. machineconfig/scripts/python/helpers/helpers_utils/specs.py +246 -0
  153. machineconfig/scripts/python/mcfg_entry.py +126 -48
  154. machineconfig/scripts/python/msearch.py +16 -61
  155. machineconfig/scripts/python/sessions.py +137 -191
  156. machineconfig/scripts/python/utils.py +104 -24
  157. machineconfig/settings/atuin/config.toml +294 -0
  158. machineconfig/settings/atuin/themes/catppuccin-mocha-mauve.toml +12 -0
  159. machineconfig/settings/linters/.ruff.toml +2 -1
  160. machineconfig/settings/mprocs/windows/mprocs.yaml +2 -2
  161. machineconfig/settings/shells/bash/init.sh +6 -10
  162. machineconfig/settings/shells/nushell/config.nu +23 -1
  163. machineconfig/settings/shells/nushell/env.nu +22 -48
  164. machineconfig/settings/shells/nushell/init.nu +64 -240
  165. machineconfig/settings/shells/pwsh/init.ps1 +71 -5
  166. machineconfig/settings/shells/pwsh/search_pwsh_history.ps1 +99 -0
  167. machineconfig/settings/shells/wezterm/wezterm.lua +4 -0
  168. machineconfig/settings/shells/wt/settings.json +31 -37
  169. machineconfig/settings/shells/zsh/init.sh +25 -5
  170. machineconfig/settings/television/cable_unix/bash-history.toml +1 -1
  171. machineconfig/settings/television/cable_windows/pwsh-history.toml +1 -1
  172. machineconfig/settings/tv/config.toml +234 -0
  173. machineconfig/settings/tv/themes/catppuccin-mocha-sky.toml +22 -0
  174. machineconfig/settings/wsl/.wslconfig +5 -30
  175. machineconfig/settings/wt/__init__.py +0 -0
  176. machineconfig/settings/yazi/yazi_linux.toml +18 -8
  177. machineconfig/settings/zellij/__init__.py +0 -0
  178. machineconfig/settings/zellij/config.kdl +0 -295
  179. machineconfig/settings/zellij/layouts/__init__.py +0 -0
  180. machineconfig/settings/zellij/layouts/st.kdl +39 -9
  181. machineconfig/settings/zellij/layouts/st2.kdl +6 -2
  182. machineconfig/setup_linux/__init__.py +0 -1
  183. machineconfig/setup_linux/apps_desktop.sh +8 -27
  184. machineconfig/setup_linux/web_shortcuts/interactive.sh +10 -10
  185. machineconfig/setup_linux/web_shortcuts/live_from_github.sh +3 -0
  186. machineconfig/setup_mac/__init__.py +0 -2
  187. machineconfig/setup_windows/__init__.py +2 -5
  188. machineconfig/setup_windows/web_shortcuts/interactive.ps1 +14 -13
  189. machineconfig/setup_windows/web_shortcuts/live_from_github.ps1 +4 -3
  190. machineconfig/setup_windows/web_shortcuts/quick_init.ps1 +3 -3
  191. machineconfig/type_hinting/sql/__init__.py +1 -0
  192. machineconfig/type_hinting/sql/base.py +216 -0
  193. machineconfig/type_hinting/sql/core_schema.py +64 -0
  194. machineconfig/type_hinting/sql/core_schema_typeddict.py +41 -0
  195. machineconfig/type_hinting/sql/typeddict_codegen.py +222 -0
  196. machineconfig/type_hinting/typedict/__init__.py +1 -0
  197. machineconfig/type_hinting/typedict/ast_utils.py +130 -0
  198. machineconfig/type_hinting/typedict/generator_helpers.py +319 -0
  199. machineconfig/type_hinting/typedict/generators.py +231 -0
  200. machineconfig/type_hinting/typedict/polars_schema.py +24 -0
  201. machineconfig/type_hinting/typedict/polars_schema_typeddict.py +63 -0
  202. machineconfig/utils/accessories.py +24 -0
  203. machineconfig/utils/code.py +78 -33
  204. machineconfig/utils/files/ascii_art.py +10 -14
  205. machineconfig/utils/files/headers.py +3 -5
  206. machineconfig/utils/files/read.py +8 -1
  207. machineconfig/utils/installer_utils/github_release_bulk.py +11 -91
  208. machineconfig/utils/installer_utils/github_release_scraper.py +99 -0
  209. machineconfig/utils/installer_utils/install_from_url.py +1 -1
  210. machineconfig/utils/installer_utils/installer_class.py +12 -4
  211. machineconfig/utils/installer_utils/installer_cli.py +7 -17
  212. machineconfig/utils/installer_utils/installer_helper.py +52 -36
  213. machineconfig/utils/installer_utils/installer_locator_utils.py +15 -25
  214. machineconfig/utils/installer_utils/installer_runner.py +4 -4
  215. machineconfig/utils/io.py +25 -8
  216. machineconfig/utils/meta.py +6 -4
  217. machineconfig/utils/options.py +49 -19
  218. machineconfig/utils/options_utils/__init__.py +0 -0
  219. machineconfig/utils/options_utils/options_tv_linux.py +211 -0
  220. machineconfig/utils/options_utils/options_tv_windows.py +88 -0
  221. machineconfig/utils/options_utils/tv_options.py +37 -0
  222. machineconfig/utils/path_extended.py +8 -7
  223. machineconfig/utils/procs.py +35 -27
  224. machineconfig/utils/scheduler.py +8 -2
  225. machineconfig/utils/schemas/fire_agents/fire_agents_input.py +1 -1
  226. machineconfig/utils/schemas/layouts/layout_types.py +10 -0
  227. machineconfig/utils/source_of_truth.py +7 -1
  228. machineconfig/utils/ssh.py +73 -23
  229. machineconfig/utils/ssh_utils/abc.py +1 -1
  230. machineconfig/utils/ssh_utils/copy_from_here.py +19 -14
  231. machineconfig/utils/ssh_utils/copy_to_here.py +2 -1
  232. machineconfig/utils/ssh_utils/utils.py +23 -7
  233. machineconfig/utils/ssh_utils/wsl.py +107 -170
  234. machineconfig/utils/ssh_utils/wsl_helper.py +217 -0
  235. machineconfig/utils/upgrade_packages.py +4 -8
  236. {machineconfig-7.98.dist-info → machineconfig-8.61.dist-info}/METADATA +30 -23
  237. machineconfig-8.61.dist-info/RECORD +539 -0
  238. {machineconfig-7.98.dist-info → machineconfig-8.61.dist-info}/entry_points.txt +0 -1
  239. machineconfig/jobs/installer/check_installations.py +0 -248
  240. machineconfig/profile/backup.toml +0 -49
  241. machineconfig/profile/mapper.toml +0 -263
  242. machineconfig/scripts/linux/other/share_cloud.sh +0 -64
  243. machineconfig/scripts/linux/other/share_nfs +0 -49
  244. machineconfig/scripts/linux/other/start_docker +0 -23
  245. machineconfig/scripts/linux/other/switch_ip +0 -20
  246. machineconfig/scripts/python/helpers/run_py_script.py +0 -79
  247. machineconfig/scripts/python/helpers/tmp_py_scripts/a.py +0 -26
  248. machineconfig/scripts/python/helpers_devops/cli_config.py +0 -105
  249. machineconfig/scripts/python/helpers_devops/cli_config_dotfile.py +0 -89
  250. machineconfig/scripts/python/helpers_devops/cli_data.py +0 -25
  251. machineconfig/scripts/python/helpers_devops/cli_nw.py +0 -214
  252. machineconfig/scripts/python/helpers_devops/cli_repos.py +0 -215
  253. machineconfig/scripts/python/helpers_devops/devops_backup_retrieve.py +0 -80
  254. machineconfig/scripts/python/helpers_devops/themes/choose_starship_theme.bash +0 -3
  255. machineconfig/scripts/python/helpers_navigator/__init__.py +0 -20
  256. machineconfig/scripts/python/helpers_navigator/command_detail.py +0 -44
  257. machineconfig/scripts/python/helpers_navigator/command_tree.py +0 -620
  258. machineconfig/scripts/python/helpers_network/devops_add_identity.py +0 -82
  259. machineconfig/scripts/python/helpers_network/devops_add_ssh_key.py +0 -153
  260. machineconfig/scripts/python/helpers_network/mount_drive +0 -128
  261. machineconfig/scripts/python/helpers_network/mount_nfs +0 -49
  262. machineconfig/scripts/python/helpers_network/mount_nfs.py +0 -85
  263. machineconfig/scripts/python/helpers_network/mount_nw_drive +0 -61
  264. machineconfig/scripts/python/helpers_network/mount_nw_drive.py +0 -48
  265. machineconfig/scripts/python/helpers_network/mount_smb +0 -3
  266. machineconfig/scripts/python/helpers_network/mount_ssh.py +0 -64
  267. machineconfig/scripts/python/helpers_network/ssh_debug_linux.py +0 -391
  268. machineconfig/scripts/python/helpers_network/ssh_debug_windows.py +0 -338
  269. machineconfig/scripts/python/helpers_network/wsl_windows_transfer.py +0 -67
  270. machineconfig/scripts/python/helpers_repos/entrypoint.py +0 -77
  271. machineconfig/scripts/python/terminal.py +0 -133
  272. machineconfig/scripts/windows/mounts/Restore-ThunderbirdProfile.ps1 +0 -92
  273. machineconfig/scripts/windows/mounts/mount_nfs.ps1 +0 -42
  274. machineconfig/scripts/windows/mounts/mount_nw.ps1 +0 -9
  275. machineconfig/scripts/windows/mounts/mount_smb.ps1 +0 -2
  276. machineconfig/scripts/windows/mounts/mount_ssh.ps1 +0 -13
  277. machineconfig/scripts/windows/mounts/share_cloud.cmd +0 -34
  278. machineconfig/scripts/windows/mounts/share_smb.ps1 +0 -16
  279. machineconfig/settings/zellij/config.orig.kdl +0 -295
  280. machineconfig/setup_linux/others/android.sh +0 -2
  281. machineconfig/setup_linux/others/mint_keyboard_shortcuts.sh +0 -30
  282. machineconfig/setup_linux/ssh/openssh_all.sh +0 -25
  283. machineconfig/setup_linux/ssh/openssh_wsl.sh +0 -38
  284. machineconfig/setup_mac/ssh/openssh_setup.sh +0 -114
  285. machineconfig/setup_windows/others/docker.ps1 +0 -7
  286. machineconfig/setup_windows/others/obs.ps1 +0 -4
  287. machineconfig/setup_windows/others/power_options.ps1 +0 -7
  288. machineconfig/setup_windows/ssh/add-sshkey.ps1 +0 -29
  289. machineconfig/setup_windows/ssh/add_identity.ps1 +0 -11
  290. machineconfig/setup_windows/ssh/openssh-server.ps1 +0 -37
  291. machineconfig/setup_windows/ssh/openssh-server_add_key.ps1 +0 -7
  292. machineconfig/setup_windows/ssh/openssh-server_copy-ssh-id.ps1 +0 -14
  293. machineconfig/utils/options_tv.py +0 -119
  294. machineconfig/utils/tst.py +0 -20
  295. machineconfig-7.98.dist-info/RECORD +0 -504
  296. /machineconfig/{jobs/installer/custom_dev → cluster/sessions_managers/wt_utils/examples}/__init__.py +0 -0
  297. /machineconfig/{scripts/python/helpers_agents → jobs/installer/checks}/__init__.py +0 -0
  298. /machineconfig/{scripts/python/helpers_agents/agentic_frameworks → jobs/installer/python_scripts}/__init__.py +0 -0
  299. /machineconfig/jobs/installer/{custom_dev → python_scripts}/alacritty.py +0 -0
  300. /machineconfig/jobs/installer/{custom_dev → python_scripts}/bypass_paywall.py +0 -0
  301. /machineconfig/jobs/installer/{custom_dev → python_scripts}/cloudflare_warp_cli.py +0 -0
  302. /machineconfig/jobs/installer/{custom_dev → python_scripts}/cursor.py +0 -0
  303. /machineconfig/jobs/installer/{custom_dev → python_scripts}/dubdb_adbc.py +0 -0
  304. /machineconfig/jobs/installer/{custom_dev → python_scripts}/espanso.py +0 -0
  305. /machineconfig/jobs/installer/{custom → python_scripts}/gh.py +0 -0
  306. /machineconfig/jobs/installer/{custom_dev → python_scripts}/goes.py +0 -0
  307. /machineconfig/jobs/installer/{custom_dev → python_scripts}/lvim.py +0 -0
  308. /machineconfig/jobs/installer/{custom_dev → python_scripts}/redis.py +0 -0
  309. /machineconfig/jobs/installer/{custom_dev → python_scripts}/winget.py +0 -0
  310. /machineconfig/jobs/{installer/linux_scripts → scripts/bash_scripts}/lid.sh +0 -0
  311. /machineconfig/{scripts/windows/mounts → jobs/scripts/powershell_scripts}/unlock_bitlocker.ps1 +0 -0
  312. /machineconfig/scripts/python/ai/{solutions/_shared.py → utils/shared.py} +0 -0
  313. /machineconfig/scripts/python/{helpers_cloud → graph}/__init__.py +0 -0
  314. /machineconfig/scripts/python/{helpers_croshell → helpers}/__init__.py +0 -0
  315. /machineconfig/scripts/python/{env_manager → helpers/helper_env}/__init__.py +0 -0
  316. /machineconfig/scripts/python/{env_manager → helpers/helper_env}/path_manager_backend.py +0 -0
  317. /machineconfig/scripts/python/{helpers_devops → helpers/helpers_agents}/__init__.py +0 -0
  318. /machineconfig/scripts/python/{helpers_devops/themes → helpers/helpers_agents/agentic_frameworks}/__init__.py +0 -0
  319. /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/agentic_frameworks/fire_crush.json +0 -0
  320. /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/fire_agents_help_search.py +0 -0
  321. /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/fire_agents_helper_types.py +0 -0
  322. /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/fire_agents_load_balancer.py +0 -0
  323. /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/templates/prompt.txt +0 -0
  324. /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/templates/template.ps1 +0 -0
  325. /machineconfig/scripts/python/{helpers_fire_command → helpers/helpers_cloud}/__init__.py +0 -0
  326. /machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/cloud_helpers.py +0 -0
  327. /machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/helpers5.py +0 -0
  328. /machineconfig/scripts/python/{helpers_network → helpers/helpers_croshell}/__init__.py +0 -0
  329. /machineconfig/scripts/python/{helpers_croshell → helpers/helpers_croshell}/crosh.py +0 -0
  330. /machineconfig/scripts/python/{helpers_croshell → helpers/helpers_croshell}/pomodoro.py +0 -0
  331. /machineconfig/scripts/python/{helpers_croshell → helpers/helpers_croshell}/viewer.py +0 -0
  332. /machineconfig/scripts/python/{helpers_croshell → helpers/helpers_croshell}/viewer_template.py +0 -0
  333. /machineconfig/scripts/python/{helpers_sessions → helpers/helpers_devops}/__init__.py +0 -0
  334. /machineconfig/{setup_windows/wt_and_pwsh → scripts/python/helpers/helpers_devops/mount_helpers}/__init__.py +0 -0
  335. /machineconfig/scripts/python/{helpers_devops/themes/choose_starship_theme.ps1 → helpers/helpers_devops/themes/__init__.py} +0 -0
  336. /machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/themes/choose_pwsh_theme.ps1 +0 -0
  337. /machineconfig/scripts/python/{helpers_fire_command/f.py → helpers/helpers_fire_command/__init__.py} +0 -0
  338. /machineconfig/scripts/python/{helpers_fire_command → helpers/helpers_fire_command}/cloud_manager.py +0 -0
  339. /machineconfig/scripts/python/{helpers_fire_command/fire_jobs_streamlit_helper.py → helpers/helpers_fire_command/f.py} +0 -0
  340. /machineconfig/scripts/python/{helpers_msearch → helpers/helpers_msearch}/__init__.py +0 -0
  341. /machineconfig/scripts/python/{helpers_navigator → helpers/helpers_navigator}/search_bar.py +0 -0
  342. /machineconfig/scripts/python/{helpers_network → helpers/helpers_network}/onetimeshare.py +0 -0
  343. /machineconfig/scripts/python/{helpers_network → helpers/helpers_network}/wifi_conn.py +0 -0
  344. /machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/clone.py +0 -0
  345. /machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/repo_analyzer_1.py +0 -0
  346. /machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/sync.py +0 -0
  347. /machineconfig/scripts/python/helpers/{ast_search.py → helpers_search/ast_search.py} +0 -0
  348. /machineconfig/scripts/python/helpers/{qr_code.py → helpers_search/qr_code.py} +0 -0
  349. /machineconfig/scripts/python/helpers/{repo_rag.py → helpers_search/repo_rag.py} +0 -0
  350. /machineconfig/scripts/python/helpers/{symantic_search.py → helpers_search/symantic_search.py} +0 -0
  351. /machineconfig/{setup_windows/wt_and_pwsh → settings/wt}/set_wt_settings.py +0 -0
  352. {machineconfig-7.98.dist-info → machineconfig-8.61.dist-info}/WHEEL +0 -0
  353. {machineconfig-7.98.dist-info → machineconfig-8.61.dist-info}/top_level.txt +0 -0
@@ -4,15 +4,15 @@ from machineconfig.utils.accessories import randstr
4
4
  from pathlib import Path
5
5
 
6
6
 
7
- def get_uv_run_command(platform: str) -> str:
7
+ def get_uv_command(platform: str) -> str:
8
8
  res = cast(Literal["Windows", "windows", "nt", "Linux", "linux", "Darwin", "darwin", "macos"], platform)
9
9
  match res:
10
10
  case "Windows" | "windows" | "nt":
11
- return """& "$env:USERPROFILE/.local/bin/uv" run"""
11
+ return """& "$env:USERPROFILE/.local/bin/uv" """
12
12
  case "Linux" | "linux" | "Darwin" | "darwin" | "macos":
13
- return """$HOME/.local/bin/uv run"""
13
+ return """$HOME/.local/bin/uv """
14
14
  case _:
15
- return """$HOME/.local/bin/uv run"""
15
+ return """$HOME/.local/bin/uv """
16
16
 
17
17
  def print_code(code: str, lexer: str, desc: str, subtitle: str = ""):
18
18
  import platform
@@ -35,10 +35,10 @@ def print_code(code: str, lexer: str, desc: str, subtitle: str = ""):
35
35
  print(f"--- End of {desc} ---")
36
36
 
37
37
 
38
- def get_uv_command_executing_python_script(python_script: str, uv_with: Optional[list[str]], uv_project_dir: Optional[str],
39
- prepend_print: bool = True) -> tuple[str, Path]:
40
- python_file = Path.home().joinpath("tmp_results", "tmp_scripts", "python", randstr() + ".py")
41
- python_file.parent.mkdir(parents=True, exist_ok=True)
38
+ def get_uv_command_executing_python_file(python_file: str, uv_with: Optional[list[str]],
39
+ uv_project_dir: Optional[str],
40
+ prepend_print: bool = True, ) -> str:
41
+ # shell script
42
42
  if uv_with is not None and len(uv_with) > 0:
43
43
  if prepend_print: uv_with.append("rich")
44
44
  uv_with_arg = "--with " + '"' + ",".join(uv_with) + '"'
@@ -50,8 +50,18 @@ def get_uv_command_executing_python_script(python_script: str, uv_with: Optional
50
50
  if uv_project_dir is not None:
51
51
  uv_project_dir_arg = "--project" + f' "{uv_project_dir}"'
52
52
  else:
53
- uv_project_dir_arg = ""
54
-
53
+ uv_project_dir_arg = "--no-project"
54
+ import platform
55
+
56
+ uv_command = get_uv_command(platform=platform.system())
57
+ shell_script = f"""{uv_command} run {uv_with_arg} {uv_project_dir_arg} {str(python_file)} """
58
+ return shell_script
59
+
60
+
61
+ def get_uv_command_executing_python_script(python_script: str, uv_with: Optional[list[str]], uv_project_dir: Optional[str],
62
+ prepend_print: bool = True, ) -> tuple[str, Path]:
63
+ python_file = Path.home().joinpath("tmp_results", "tmp_scripts", "python", randstr() + ".py")
64
+ python_file.parent.mkdir(parents=True, exist_ok=True)
55
65
  if prepend_print:
56
66
  from machineconfig.utils.meta import lambda_to_python_script
57
67
  print_code_string = lambda_to_python_script(lambda: print_code(code=python_script, lexer="python", desc="Temporary Python Script", subtitle="Executing via shell script"),
@@ -59,18 +69,19 @@ def get_uv_command_executing_python_script(python_script: str, uv_with: Optional
59
69
  python_file.write_text(print_code_string + "\n" + python_script, encoding="utf-8")
60
70
  else:
61
71
  python_file.write_text(python_script, encoding="utf-8")
62
- import platform
63
- uv_run = get_uv_run_command(platform=platform.system())
64
- shell_script = f"""{uv_run} {uv_with_arg} {uv_project_dir_arg} {str(python_file)} """
72
+ shell_script = get_uv_command_executing_python_file(python_file=str(python_file), uv_with=uv_with, uv_project_dir=uv_project_dir, prepend_print=prepend_print)
65
73
  return shell_script, python_file
66
74
 
67
75
 
68
- def run_lambda_function(lmb: Callable[[], Any], uv_with: Optional[list[str]], uv_project_dir: Optional[str]) -> None:
76
+ def get_shell_script_running_lambda_function(lmb: Callable[[], Any], uv_with: Optional[list[str]], uv_project_dir: Optional[str]) -> tuple[str, Path]:
69
77
  from machineconfig.utils.meta import lambda_to_python_script
70
78
  code = lambda_to_python_script(lmb,
71
79
  in_global=True, import_module=False)
72
- uv_command, _py_file = get_uv_command_executing_python_script(python_script=code, uv_with=uv_with, uv_project_dir=uv_project_dir)
73
- run_shell_script(uv_command)
80
+ uv_command, py_file = get_uv_command_executing_python_script(python_script=code, uv_with=uv_with, uv_project_dir=uv_project_dir)
81
+ return uv_command, py_file
82
+ def run_lambda_function(lmb: Callable[[], Any], uv_with: Optional[list[str]], uv_project_dir: Optional[str]) -> None:
83
+ uv_command, _py_file = get_shell_script_running_lambda_function(lmb=lmb, uv_with=uv_with, uv_project_dir=uv_project_dir)
84
+ run_shell_script(uv_command, display_script=True, clean_env=False)
74
85
 
75
86
 
76
87
  def run_python_script_in_marimo(py_script: str, uv_project_with: Optional[str]):
@@ -92,35 +103,38 @@ uv run {requirements} marimo edit --host 0.0.0.0 marimo_nb.py
92
103
  exit_then_run_shell_script(fire_line)
93
104
 
94
105
 
95
- def run_shell_script(script: str, display_script: bool = True, clean_env: bool = False):
96
- import tempfile
106
+ def run_shell_file(script_path: str, clean_env: bool):
107
+ import platform
108
+ env = {} if clean_env else None
109
+ if platform.system() == "Windows":
110
+ import subprocess
111
+ proc = subprocess.run(f'powershell -ExecutionPolicy Bypass -File "{script_path}"', check=True, shell=True, env=env)
112
+ elif platform.system() == "Linux" or platform.system() == "Darwin":
113
+ import subprocess
114
+ proc = subprocess.run(f"bash {str(script_path)}", check=True, shell=True, env=env)
115
+ else:
116
+ raise NotImplementedError(f"Platform {platform.system()} not supported.")
117
+ return proc
118
+ def run_shell_script(script: str, display_script: bool, clean_env: bool):
97
119
  import platform
98
- from rich.console import Console
99
- from rich.panel import Panel
100
- from rich.syntax import Syntax
101
-
102
120
  if platform.system() == "Windows":
103
121
  suffix = ".ps1"
104
122
  lexer = "powershell"
105
123
  else:
106
124
  suffix = ".sh"
107
125
  lexer = "bash"
126
+ import tempfile
108
127
  with tempfile.NamedTemporaryFile(mode='w', suffix=suffix, delete=False, encoding='utf-8') as temp_file:
109
128
  temp_file.write(script)
110
129
  temp_shell_script_path = Path(temp_file.name)
130
+ from rich.panel import Panel
131
+ from rich.syntax import Syntax
132
+ from rich.console import Console
111
133
  console = Console()
112
134
  if display_script:
113
135
  from rich.syntax import Syntax
114
136
  console.print(Panel(Syntax(code=script, lexer=lexer), title=f"📄 shell script @ {temp_shell_script_path}", subtitle="shell script being executed"), style="bold red")
115
- env = {} if clean_env else None
116
- if platform.system() == "Windows":
117
- import subprocess
118
- proc = subprocess.run(f'powershell -ExecutionPolicy Bypass -File "{temp_shell_script_path}"', check=True, shell=True, env=env)
119
- elif platform.system() == "Linux" or platform.system() == "Darwin":
120
- import subprocess
121
- proc = subprocess.run(f"bash {str(temp_shell_script_path)}", check=True, shell=True, env=env)
122
- else:
123
- raise NotImplementedError(f"Platform {platform.system()} not supported.")
137
+ proc = run_shell_file(script_path=str(temp_shell_script_path), clean_env=clean_env)
124
138
  # console.print(f"✅ [green]Script executed successfully:[/green] [blue]{temp_script_path}[/blue]")
125
139
  if proc.returncode != 0:
126
140
  console.print(f"❌ [red]Script execution failed with return code {proc.returncode}:[/red] [blue]{temp_shell_script_path}[/blue]")
@@ -136,7 +150,6 @@ def run_shell_script(script: str, display_script: bool = True, clean_env: bool =
136
150
  def exit_then_run_shell_script(script: str, strict: bool = False):
137
151
  import os
138
152
  from rich.console import Console
139
-
140
153
  console = Console()
141
154
  op_program_path = os.environ.get("OP_PROGRAM_PATH", None)
142
155
  if op_program_path is not None:
@@ -176,6 +189,38 @@ def exit_then_run_shell_script(script: str, strict: bool = False):
176
189
  console.print(f"[yellow]⚠️ OP_PROGRAM_PATH @ {str(op_program_path)} already exists.[/yellow] [cyan]Falling back to direct execution.[/cyan]")
177
190
  elif op_program_path is None:
178
191
  console.print("[cyan]ℹ️ OP_PROGRAM_PATH is not set.[/cyan] [yellow]Falling back to direct execution.[/yellow]")
179
- run_shell_script(script)
192
+ run_shell_script(script, display_script=True, clean_env=False)
193
+ import sys
194
+ sys.exit(0)
195
+ def exit_then_run_shell_file(script_path: str, strict: bool):
196
+ import os
197
+ from rich.console import Console
198
+ console = Console()
199
+ op_program_path = os.environ.get("OP_PROGRAM_PATH", None)
200
+ if op_program_path is None or Path(op_program_path).exists():
201
+ if strict:
202
+ console.print("[red]❌ OP_PROGRAM_PATH environment variable is not set or the file already exists in strict mode.[/red]")
203
+ import sys
204
+ sys.exit(1)
205
+ if op_program_path is None or Path(op_program_path).exists():
206
+ console.print("[cyan]ℹ️ OP_PROGRAM_PATH is not set.[/cyan] [yellow]Falling back to direct execution.[/yellow]")
207
+ run_shell_file(script_path=script_path, clean_env=False)
208
+ return
209
+ import platform
210
+ if platform.system() == "Windows":
211
+ suffix = ".ps1"
212
+ lexer = "powershell"
213
+ script = str(script_path)
214
+ elif platform.system() == "Linux" or platform.system() == "Darwin":
215
+ suffix = ".sh"
216
+ lexer = "bash"
217
+ script = f"source {str(script_path)}"
218
+ else:
219
+ raise NotImplementedError(f"Platform {platform.system()} not supported.")
220
+ op_program_path = Path(op_program_path)
221
+ op_program_path.parent.mkdir(parents=True, exist_ok=True)
222
+ op_program_path.write_text(script, encoding="utf-8")
223
+ _ = suffix, lexer
224
+ console.print(f"[cyan]🚀 Handing over to shell script runner via OP_PROGRAM_PATH @ {str(op_program_path)}[/cyan]")
180
225
  import sys
181
226
  sys.exit(0)
@@ -32,15 +32,11 @@ class BoxStyles:
32
32
 
33
33
  class CowStyles:
34
34
  eyes = ['-b', '-d', '-g', '-h', '-l', '-L', '-n', '-N', '-p', '-s', '-t', '-w', '-y']
35
- # this one for the package installed with sudo apt install cowsay and is located at /usr/games/cowsay. See cowsay -l
36
- figures = ['apt', 'bunny', 'cheese', 'cock', 'cower', 'daemon', 'default', 'dragon',
37
- 'dragon-and-cow', 'duck', 'elephant', 'elephant-in-snake', 'eyes', 'fox', 'ghostbusters',
38
- 'gnu', 'kangaroo', 'kiss', 'milk',
39
- 'moose', 'pony', 'pony-smaller', 'sheep', 'skeleton', 'snowman', 'stegosaurus', # 'suse',
40
- 'three-eyes', 'turkey', 'turtle', 'tux', 'unipony', 'unipony-smaller', 'vader', 'vader'] # 'hellokitty' 'mech-and-cow' # 'moofasa', 'stimpy', 'calvin', , 'ren', 'koala', 'flaming-sheep' , 'bud-frogs' , 'kosh' , 'luke-koala'
35
+ # Available characters from Python cowsay package (uv tool install cowsay)
36
+ figures = ['beavis', 'cheese', 'cow', 'daemon', 'dragon', 'fox', 'ghostbusters', 'kitty', 'meow', 'miki', 'milk', 'octopus', 'pig', 'stegosaurus', 'stimpy', 'trex', 'turkey', 'turtle', 'tux']
41
37
 
42
38
 
43
- FIGLET_FONTS = ['banner', 'big', 'standard']
39
+ FIGLET_FONTS = ['Banner', 'Big', 'Standard']
44
40
 
45
41
  FIGJS_FONTS = ['3D Diagonal', '3D-ASCII', '4Max', '5 Line Oblique', 'Acrobatic', 'ANSI Regular', 'ANSI Shadow',
46
42
  'Avatar', 'Banner', 'Banner3-D', 'Banner4',
@@ -55,8 +51,8 @@ FIGJS_FONTS = ['3D Diagonal', '3D-ASCII', '4Max', '5 Line Oblique', 'Acrobatic',
55
51
 
56
52
  def get_art(comment: Optional[str] = None, artlib: Optional[BOX_OR_CHAR] = None, style: Optional[str] = None, super_style: str = 'scene', prefix: str = ' ', file: Optional[str] = None, verbose: bool = True):
57
53
  """ takes in a comment and does the following wrangling:
58
- * text => figlet font => boxes => lolcat
59
- * text => cowsay => lolcat
54
+ * text => figlet font => boxes => lolcatjs
55
+ * text => cowsay => lolcatjs
60
56
  """
61
57
  if comment is None:
62
58
  try:
@@ -68,10 +64,10 @@ def get_art(comment: Optional[str] = None, artlib: Optional[BOX_OR_CHAR] = None,
68
64
  if artlib == 'boxes':
69
65
  if style is None: style = random.choice(BoxStyles.__dict__[super_style or random.choice(['language', 'scene', 'character'])])
70
66
  fonting = f'figlet -f {random.choice(FIGLET_FONTS)}'
71
- cmd = f"""echo "{comment}" | {fonting} | boxes -d {style} {to_file}"""
67
+ cmd = f"""{fonting} "{comment}" | boxes -d {style} {to_file}"""
72
68
  else:
73
69
  if style is None: style = random.choice(CowStyles.figures)
74
- cmd = f"""echo "{comment}" | /usr/games/cowsay -f {style} {to_file}"""
70
+ cmd = f"""cowsay -c {style} -t "{comment}" {to_file}"""
75
71
  try:
76
72
  res = subprocess.run(cmd, text=True, capture_output=True, shell=True, check=True).stdout
77
73
  except subprocess.CalledProcessError as ex:
@@ -91,7 +87,7 @@ def font_box_color(logo: str):
91
87
  box_style = random.choice(['whirly', 'xes', 'columns', 'parchment', 'scroll', 'scroll-akn', 'diamonds', 'headline', 'nuke', 'spring', 'stark1'])
92
88
  _cmd = f'figlet -f "{font}" "{logo}" | boxes -d "{box_style}" | lolcatjs'
93
89
  # print(_cmd)
94
- os.system(_cmd) # | lolcat
90
+ os.system(_cmd) # | lolcatjs
95
91
  # print("after")
96
92
 
97
93
 
@@ -100,7 +96,7 @@ def character_color(logo: str):
100
96
  with tempfile.NamedTemporaryFile(mode='w', suffix='.txt', delete=False) as f:
101
97
  f.write(ArtLib.cowsay(logo))
102
98
  _new_art = f.name
103
- os.system(f'type {_new_art} | lolcatjs') # | lolcat
99
+ os.system(f'type {_new_art} | lolcatjs') # | lolcatjs
104
100
 
105
101
 
106
102
  def character_or_box_color(logo: str):
@@ -110,7 +106,7 @@ def character_or_box_color(logo: str):
110
106
  get_art(logo, artlib=None, file=_new_art, verbose=False)
111
107
  # Prefer bat on mac if available, fallback to cat
112
108
  pager = "bat" if (platform.system() == "Darwin" and any((Path(p).joinpath("bat").exists() for p in os.environ.get("PATH", "").split(os.pathsep)))) else "cat"
113
- command = f"{pager} {_new_art} | lolcat"
109
+ command = f"{pager} {_new_art} | lolcatjs"
114
110
  os.system(command)
115
111
 
116
112
 
@@ -46,7 +46,7 @@ def print_logo(logo: str):
46
46
  elif platform.system() in ["Linux", "Darwin"]: # Explicitly handle both Linux and macOS
47
47
  from machineconfig.utils.installer_utils.installer_locator_utils import is_executable_in_path
48
48
  avail_cowsay = is_executable_in_path("cowsay")
49
- avail_lolcat = is_executable_in_path("lolcat")
49
+ avail_lolcat = is_executable_in_path("lolcatjs")
50
50
  avail_boxes = is_executable_in_path("boxes")
51
51
  avail_figlet = is_executable_in_path("figlet")
52
52
  if avail_cowsay and avail_lolcat and avail_boxes and avail_figlet:
@@ -56,10 +56,8 @@ def print_logo(logo: str):
56
56
  # print(Path(random.choice(glob.glob(str(Path(__file__).parent.joinpath("art", "*"))))).read_text())
57
57
  character_or_box_color(logo=logo)
58
58
  else:
59
- print("\n" + "🚫 " + "-" * 70 + " 🚫")
60
- install_cmd = "devops install --group TerminalEyeCandy" if platform.system() == "Linux" else "brew install cowsay lolcat boxes figlet"
61
- print(f"🔍 Missing ASCII art dependencies. Install with: {install_cmd}")
62
- print("🚫 " + "-" * 70 + " 🚫\n")
59
+ install_cmd = "devops install --group term-eye-candy "
60
+ print(f"🔍 Missing ASCII art dependencies. Install with: {install_cmd} | {avail_boxes=} {avail_cowsay} {avail_figlet} {avail_lolcat=}")
63
61
  _default_art = Path(random.choice(glob.glob(str(Path(__file__).parent.joinpath("art", "*")))))
64
62
  print(_default_art.read_text())
65
63
  else:
@@ -14,7 +14,11 @@ class Read:
14
14
  if suffix in ("sqlite", "sqlite3", "db", "duckdb"):
15
15
  from machineconfig.utils.files.dbms import DBMS
16
16
  res = DBMS.from_local_db(path=path)
17
- print(res.describe_db())
17
+ try:
18
+ print(res.describe_db())
19
+ except Exception:
20
+ print("💥 Could not describe the database.")
21
+ pass
18
22
  return res
19
23
  try: return getattr(Read, suffix)(str(path), **kwargs)
20
24
  except AttributeError as err:
@@ -28,6 +32,9 @@ class Read:
28
32
  elif suffix == "csv":
29
33
  import polars as pl
30
34
  return pl.read_csv(path, **kwargs)
35
+ elif suffix == "npz" or suffix == "npy":
36
+ import numpy as np
37
+ return np.load(str(path), **kwargs)
31
38
  try:
32
39
  # guess = install_n_import('magic', 'python-magic').from_file(path)
33
40
  guess = "IDKm"
@@ -10,6 +10,8 @@ from pathlib import Path
10
10
  from typing import Any, Dict, Optional, Set, TypedDict
11
11
  from urllib.parse import urlparse
12
12
 
13
+ from machineconfig.utils.installer_utils.github_release_scraper import scrape_github_release_page
14
+
13
15
 
14
16
  class AssetInfo(TypedDict):
15
17
  """Type definition for GitHub release asset information."""
@@ -74,7 +76,7 @@ def fetch_github_release_data(
74
76
  repo_name: str,
75
77
  version: Optional[str] = None,
76
78
  ) -> Optional[Dict[str, Any]]:
77
- """Fetch GitHub release data for the latest or a specific tag."""
79
+ """Fetch GitHub release data for the latest or a specific tag. Falls back to HTML scraping if API fails."""
78
80
 
79
81
  try:
80
82
  requested_version = (version or "").strip()
@@ -85,24 +87,24 @@ def fetch_github_release_data(
85
87
 
86
88
  response = requests.get(url, timeout=30)
87
89
  if response.status_code != 200:
88
- print(f" Failed to fetch data for {username}/{repo_name}: HTTP {response.status_code}")
89
- return None
90
+ print(f"⚠️ API failed for {username}/{repo_name}: HTTP {response.status_code}, trying HTML scraper...")
91
+ return scrape_github_release_page(username, repo_name, version)
90
92
 
91
93
  response_data = response.json()
92
94
  message = response_data.get("message")
93
95
  if isinstance(message, str):
94
96
  if "API rate limit exceeded" in message:
95
- print(f"🚫 Rate limit exceeded for {username}/{repo_name}")
96
- return None
97
+ print(f"🚫 Rate limit exceeded for {username}/{repo_name}, trying HTML scraper...")
98
+ return scrape_github_release_page(username, repo_name, version)
97
99
  if "Not Found" in message:
98
- print(f"🔍 No releases found for {username}/{repo_name}")
99
- return None
100
+ print(f"🔍 No releases found via API for {username}/{repo_name}, trying HTML scraper...")
101
+ return scrape_github_release_page(username, repo_name, version)
100
102
 
101
103
  return response_data
102
104
 
103
105
  except (requests.RequestException, requests.Timeout, json.JSONDecodeError) as error:
104
- print(f" Error fetching {username}/{repo_name}: {error}")
105
- return None
106
+ print(f"⚠️ API error for {username}/{repo_name}: {error}, trying HTML scraper...")
107
+ return scrape_github_release_page(username, repo_name, version)
106
108
 
107
109
 
108
110
  def get_release_info(
@@ -141,85 +143,3 @@ def extract_release_info(release_data: Dict[str, Any]) -> Optional[ReleaseInfo]:
141
143
  "assets_count": len(assets)
142
144
  }
143
145
 
144
-
145
- # def main() -> None:
146
- # """Main function to process installer JSON files and fetch GitHub release data."""
147
- # # Define paths
148
- # current_dir = Path(__file__).parent
149
- # installer_dir = current_dir.parent.parent / "jobs" / "installer"
150
-
151
- # standard_json = installer_dir / "installer_data.json"
152
- # output_json = current_dir / "github_releases.json"
153
-
154
- # print("🔍 Starting GitHub release data extraction...")
155
- # print(f"📁 Processing files from: {installer_dir}")
156
-
157
- # # Extract GitHub repositories from both files
158
- # all_github_repos: Set[str] = set()
159
-
160
- # if standard_json.exists():
161
- # print(f"📄 Reading {standard_json.name}...")
162
- # repos = extract_github_repos_from_json(standard_json)
163
- # all_github_repos.update(repos)
164
- # print(f" Found {len(repos)} GitHub repos")
165
- # else:
166
- # print(f"⚠️ File not found: {standard_json}")
167
- # print(f"🎯 Total unique GitHub repositories found: {len(all_github_repos)}")
168
-
169
- # if not all_github_repos:
170
- # print("❌ No GitHub repositories found. Exiting.")
171
- # return
172
-
173
- # # Fetch release data with rate limiting
174
- # release_mapping: Dict[str, Optional[ReleaseInfo]] = {}
175
- # total_repos = len(all_github_repos)
176
-
177
- # print(f"\n🚀 Fetching release data for {total_repos} repositories...")
178
- # print("⏰ Rate limiting: 5 seconds between requests")
179
- # print("-" * 60)
180
-
181
- # for i, repo_url in enumerate(sorted(all_github_repos), 1):
182
- # repo_info = get_repo_name_from_url(repo_url)
183
-
184
- # if not repo_info:
185
- # print(f"⚠️ [{i:3d}/{total_repos}] Invalid repo URL: {repo_url}")
186
- # continue
187
-
188
- # username, repo_name = repo_info
189
- # repo_full_name = f"{username}/{repo_name}"
190
-
191
- # print(f"📡 [{i:3d}/{total_repos}] Fetching: {repo_full_name}", end=" ... ")
192
-
193
- # release_info = get_release_info(username, repo_name)
194
-
195
- # if release_info:
196
- # release_mapping[repo_url] = release_info
197
- # assets_count = release_info["assets_count"]
198
- # tag = release_info["tag_name"]
199
- # print(f"✅ {tag} ({assets_count} assets)")
200
- # else:
201
- # release_mapping[repo_url] = None
202
- # print("❌ No data")
203
-
204
- # # Rate limiting - wait 5 seconds between requests (except for the last one)
205
- # if i < total_repos:
206
- # time.sleep(5)
207
-
208
- # # Save results
209
- # output_data: OutputData = {
210
- # "generated_at": time.strftime("%Y-%m-%d %H:%M:%S UTC", time.gmtime()),
211
- # "total_repositories": len(all_github_repos),
212
- # "successful_fetches": len([v for v in release_mapping.values() if v]),
213
- # "releases": release_mapping
214
- # }
215
-
216
- # with open(output_json, 'w', encoding='utf-8') as f:
217
- # json.dump(output_data, f, indent=2, ensure_ascii=False)
218
-
219
- # successful = len([v for v in release_mapping.values() if v])
220
- # print("\n📊 Summary:")
221
- # print(f" Total repositories processed: {len(all_github_repos)}")
222
- # print(f" Successful fetches: {successful}")
223
- # print(f" Failed fetches: {len(all_github_repos) - successful}")
224
- # print(f" Output saved to: {output_json}")
225
- # print("✅ Done!")
@@ -0,0 +1,99 @@
1
+ #!/usr/bin/env python3
2
+ """HTML scraper for GitHub release pages as fallback when API rate limit is exceeded."""
3
+
4
+ import re
5
+ from typing import Any, Optional
6
+ import requests
7
+
8
+
9
+ def extract_tag_from_html(html: str, owner: str, repo: str) -> str:
10
+ patterns = [
11
+ rf'/{re.escape(owner)}/{re.escape(repo)}/releases/tag/([^"\'<>\s]+)',
12
+ rf'/{re.escape(owner)}/{re.escape(repo)}/tree/([^"\'<>\s]+)',
13
+ r'<span[^>]*class="[^"]*ml-1[^"]*"[^>]*>([^<]+)</span>',
14
+ ]
15
+ for pattern in patterns:
16
+ match = re.search(pattern, html, re.IGNORECASE)
17
+ if match:
18
+ tag = match.group(1).strip()
19
+ if tag and not tag.startswith("http"):
20
+ return tag
21
+ return ""
22
+
23
+
24
+ def extract_release_name(html: str) -> str:
25
+ patterns = [
26
+ r'<h1[^>]*class="[^"]*d-inline[^"]*"[^>]*>([^<]+)</h1>',
27
+ r'<bdi[^>]*class="[^"]*mr-2[^"]*"[^>]*>([^<]+)</bdi>',
28
+ r'<h1[^>]*>([^<]+)</h1>',
29
+ ]
30
+ for pattern in patterns:
31
+ match = re.search(pattern, html)
32
+ if match:
33
+ name = match.group(1).strip()
34
+ if name:
35
+ return name
36
+ return ""
37
+
38
+
39
+ def extract_published_at(html: str) -> str:
40
+ pattern = r'<relative-time[^>]*datetime="([^"]+)"'
41
+ match = re.search(pattern, html)
42
+ if match:
43
+ return match.group(1)
44
+ return ""
45
+
46
+
47
+ def fetch_expanded_assets(username: str, repo_name: str, tag_name: str, headers: dict[str, str]) -> list[dict[str, Any]]:
48
+ """Fetch assets from the expanded_assets endpoint which contains all downloadable files."""
49
+ assets: list[dict[str, Any]] = []
50
+ expanded_url = f"https://github.com/{username}/{repo_name}/releases/expanded_assets/{tag_name}"
51
+ try:
52
+ response = requests.get(expanded_url, timeout=30, headers=headers)
53
+ if response.status_code != 200:
54
+ print(f"⚠️ [Scraper] Could not fetch expanded assets for {username}/{repo_name}: HTTP {response.status_code}")
55
+ return assets
56
+ html = response.text
57
+ pattern = r'href="([^"]*?/releases/download/[^"]+)"[^>]*>.*?<span[^>]*class="[^"]*Truncate-text[^"]*text-bold[^"]*"[^>]*>([^<]+)</span>'
58
+ seen_urls: set[str] = set()
59
+ matches = re.findall(pattern, html, re.DOTALL)
60
+ for href, name in matches:
61
+ asset_name = name.strip()
62
+ if not asset_name or asset_name.isspace():
63
+ continue
64
+ download_url = f"https://github.com{href}" if href.startswith("/") else href
65
+ if download_url in seen_urls:
66
+ continue
67
+ seen_urls.add(download_url)
68
+ assets.append({"name": asset_name, "size": 0, "download_count": 0, "content_type": "", "created_at": "", "updated_at": "", "browser_download_url": download_url})
69
+ except requests.RequestException as error:
70
+ print(f"⚠️ [Scraper] Error fetching expanded assets for {username}/{repo_name}: {error}")
71
+ return assets
72
+
73
+
74
+ def scrape_github_release_page(username: str, repo_name: str, version: Optional[str] = None) -> Optional[dict[str, Any]]:
75
+ """Scrape GitHub release page HTML to extract release information. Falls back to this when API rate limit is hit."""
76
+ try:
77
+ requested_version = (version or "").strip()
78
+ if requested_version and requested_version.lower() != "latest":
79
+ url = f"https://github.com/{username}/{repo_name}/releases/tag/{requested_version}"
80
+ else:
81
+ url = f"https://github.com/{username}/{repo_name}/releases/latest"
82
+ headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"}
83
+ response = requests.get(url, timeout=30, headers=headers, allow_redirects=True)
84
+ if response.status_code != 200:
85
+ print(f"❌ [Scraper] Failed to fetch page for {username}/{repo_name}: HTTP {response.status_code}")
86
+ return None
87
+ html = response.text
88
+ tag_name = extract_tag_from_html(html, username, repo_name)
89
+ if not tag_name:
90
+ print(f"🔍 [Scraper] No tag found for {username}/{repo_name}")
91
+ return None
92
+ release_name = extract_release_name(html) or tag_name
93
+ published_at = extract_published_at(html)
94
+ assets = fetch_expanded_assets(username, repo_name, tag_name, headers)
95
+ print(f"✅ [Scraper] Found {len(assets)} assets for {username}/{repo_name} @ {tag_name}")
96
+ return {"tag_name": tag_name, "name": release_name, "published_at": published_at, "assets": assets}
97
+ except requests.RequestException as error:
98
+ print(f"❌ [Scraper] Error fetching {username}/{repo_name}: {error}")
99
+ return None
@@ -150,7 +150,7 @@ def install_from_github_url(github_url: str) -> None:
150
150
  size_padded = item["size_str"].ljust(max_size_len)
151
151
  downloads_padded = item["downloads_str"].rjust(max_downloads_len)
152
152
 
153
- label = f"{name_padded} {size_padded} | {downloads_padded} | 📅 {item['date_str']}"
153
+ label = f"{name_padded} {size_padded} | #🔽 {downloads_padded} | 📅 {item['date_str']}"
154
154
  options_map[label] = item["asset"]
155
155
 
156
156
  if not options_map:
@@ -13,6 +13,9 @@ import subprocess
13
13
  from typing import Optional
14
14
 
15
15
 
16
+ PACAKGE_MANAGERS = ["bun", "npm", "pip", "uv", "winget", "powershell", "irm", "brew", "curl", "sudo"]
17
+
18
+
16
19
  class Installer:
17
20
  def __init__(self, installer_data: InstallerData):
18
21
  self.installer_data: InstallerData = installer_data
@@ -62,8 +65,13 @@ class Installer:
62
65
  if installer_arch_os is None:
63
66
  raise ValueError(f"No installation pattern for {exe_name} on {os_name} {arch}")
64
67
  version_to_be_installed: str = "unknown" # Initialize to ensure it's always bound
65
- if repo_url == "CMD":
66
- if any(pm in installer_arch_os for pm in ["npm ", "pip ", "winget ", "brew ", "curl "]):
68
+
69
+ package_manager_installer = any(pm in installer_arch_os.split(" ") for pm in PACAKGE_MANAGERS)
70
+ script_installer = installer_arch_os.endswith((".sh", ".py", ".ps1"))
71
+ binary_download_link = installer_arch_os.startswith("https://") or installer_arch_os.startswith("http://")
72
+
73
+ if (repo_url == "CMD") or package_manager_installer or script_installer or binary_download_link:
74
+ if package_manager_installer:
67
75
  from rich import print as rprint
68
76
  from rich.panel import Panel
69
77
  from rich.console import Group
@@ -81,7 +89,7 @@ class Installer:
81
89
  sub_panels.append(Panel(result.stderr, title="STDERR", style="red"))
82
90
  group_content = Group(f"❌ {desc} failed\nReturn code: {result.returncode}", *sub_panels)
83
91
  rprint(Panel(group_content, title=desc, style="red"))
84
- elif installer_arch_os.endswith((".sh", ".py", ".ps1")):
92
+ elif script_installer:
85
93
  import machineconfig.jobs.installer as module
86
94
  from pathlib import Path
87
95
  search_root = Path(module.__file__).parent
@@ -106,7 +114,7 @@ class Installer:
106
114
  import runpy
107
115
  runpy.run_path(str(installer_path), run_name=None)["main"](self.installer_data, version=version)
108
116
  version_to_be_installed = str(version)
109
- elif installer_arch_os.startswith("https://") or installer_arch_os.startswith("http://"):
117
+ elif binary_download_link:
110
118
  downloaded_object = download_and_prepare(installer_arch_os)
111
119
  if downloaded_object.suffix in [".exe", ""]: # likely an executable
112
120
  if platform.system() == "Windows":
@@ -1,18 +1,5 @@
1
- """Devops Devapps Install
2
-
3
-
4
- sudo apt update && sudo apt install -y \
5
- git gcc g++ clang \
6
- yasm nasm pkg-config \
7
- meson ninja-build \
8
- autoconf automake libtool \
9
- libx11-dev libxext-dev libxrandr-dev libxrender-dev libxss-dev \
10
- libvdpau-dev libgl1-mesa-dev libegl1-mesa-dev libxv-dev \
11
- libasound2-dev libpulse-dev \
12
- libfribidi-dev libfreetype-dev libfontconfig1-dev libharfbuzz-dev \
13
- libjpeg-dev libssl-dev zlib1g-dev python3-pip
14
-
15
1
 
2
+ """Devops Devapps Install
16
3
  """
17
4
 
18
5
  from machineconfig.utils.installer_utils.installer_helper import get_group_name_to_repr
@@ -20,7 +7,6 @@ import typer
20
7
  from typing import Annotated, Optional
21
8
 
22
9
 
23
-
24
10
  def main_installer_cli(
25
11
  which: Annotated[Optional[str], typer.Argument(..., help="Comma-separated list of program/groups names to install (if --group flag is set).")] = None,
26
12
  group: Annotated[bool, typer.Option(..., "--group", "-g", help="Treat 'which' as a group name. A group is bundle of apps.")] = False,
@@ -135,6 +121,7 @@ def install_clis(clis_names: list[str]):
135
121
  from machineconfig.utils.installer_utils.install_from_url import install_from_binary_url
136
122
  install_from_binary_url(binary_url=a_cli_name)
137
123
  continue
124
+
138
125
  selected_installer = None
139
126
  for installer in all_installers_data:
140
127
  app_name = installer["appName"]
@@ -143,8 +130,11 @@ def install_clis(clis_names: list[str]):
143
130
  break
144
131
  if selected_installer is None:
145
132
  from machineconfig.utils.installer_utils.installer_helper import handle_installer_not_found
146
- handle_installer_not_found(a_cli_name, all_installers_data)
147
- return None
133
+ clis_names_chosen_interactively = handle_installer_not_found(a_cli_name, all_installers_data)
134
+ if len(clis_names_chosen_interactively) == 0:
135
+ continue
136
+ _ = install_clis(clis_names=clis_names_chosen_interactively)
137
+ continue
148
138
  message = Installer(selected_installer).install_robust(version=None) # finish the task
149
139
  total_messages.append(message)
150
140
  if total_messages: