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
@@ -14,12 +14,9 @@ def get_group_name_to_repr() -> dict[str, str]:
14
14
  return category_display_to_name
15
15
 
16
16
 
17
- def handle_installer_not_found(search_term: str, app_apps: list[InstallerData]) -> None: # type: ignore
17
+ def handle_installer_not_found(search_term: str, app_apps: list[InstallerData]) -> list[str]:
18
18
  """Handle installer not found with friendly suggestions using fuzzy matching."""
19
19
  from difflib import get_close_matches
20
- from rich.console import Console
21
- from rich.panel import Panel
22
- from rich.table import Table
23
20
  all_names = sorted([inst["appName"] for inst in app_apps])
24
21
  name_to_doc = {inst["appName"]: inst["doc"] for inst in app_apps}
25
22
  all_descriptions = {f"{inst['appName']}: {inst['doc']}": inst["appName"] for inst in app_apps}
@@ -41,38 +38,57 @@ def handle_installer_not_found(search_term: str, app_apps: list[InstallerData])
41
38
  + substring_matches
42
39
  )
43
40
  )
44
- top_matches = ordered_matches[:10]
45
- console = Console()
46
41
 
47
- console.print(f"\n❌ '[red]{search_term}[/red]' was not found.", style="bold")
48
- if top_matches:
49
- console.print("🤔 Did you mean one of these?", style="yellow")
50
- table = Table(show_header=True, header_style="bold", box=None, pad_edge=False)
51
- table.add_column("#", justify="right", width=3)
52
- table.add_column("Installer", style="green")
53
- table.add_column("Description", style="dim", overflow="fold")
54
- for i, match in enumerate(top_matches, 1):
55
- table.add_row(f"[cyan]{i}[/cyan]", match, name_to_doc.get(match, ""))
56
- console.print(table)
57
- else:
58
- console.print("📋 Here are some available options:", style="blue")
59
- # Show first 10 installers as examples
60
- if len(all_names) > 10:
61
- sample_names = all_names[:10]
62
- else:
63
- sample_names = all_names
64
- table = Table(show_header=True, header_style="bold", box=None, pad_edge=False)
65
- table.add_column("#", justify="right", width=3)
66
- table.add_column("Installer", style="green")
67
- table.add_column("Description", style="dim", overflow="fold")
68
- for i, name in enumerate(sample_names, 1):
69
- table.add_row(f"[cyan]{i}[/cyan]", name, name_to_doc.get(name, ""))
70
- console.print(table)
71
- if len(all_names) > 10:
72
- console.print(f" [dim]... and {len(all_names) - 10} more[/dim]")
42
+ order_matches_with_docs = [f"{app_name:<20} : " + name_to_doc.get(app_name, "") for app_name in ordered_matches]
43
+ from machineconfig.utils.options import choose_from_options
44
+
45
+ try:
46
+ chosen = choose_from_options(
47
+ options=order_matches_with_docs,
48
+ msg=f"🔍 No installer found for '[red]{search_term}[/red]'. Did you mean one of these?",
49
+ multi=True,
50
+ tv=True
51
+ )
52
+ except KeyboardInterrupt:
53
+ print("\n❌ Selection cancelled by user.")
54
+ return []
55
+ apps_chosen = [app.split(" : ")[0].strip() for app in chosen]
56
+ print(f"➡️ You selected: {apps_chosen}")
57
+ return apps_chosen
58
+ # top_matches = ordered_matches[:10] if len(ordered_matches) > 10 else ordered_matches
59
+ # from rich.console import Console
60
+ # from rich.panel import Panel
61
+ # from rich.table import Table
62
+ # console = Console()
63
+ # console.print(f"\n❌ '[red]{search_term}[/red]' was not found.", style="bold")
64
+ # if top_matches:
65
+ # console.print("🤔 Did you mean one of these?", style="yellow")
66
+ # table = Table(show_header=True, header_style="bold", box=None, pad_edge=False)
67
+ # table.add_column("#", justify="right", width=3)
68
+ # table.add_column("Installer", style="green")
69
+ # table.add_column("Description", style="dim", overflow="fold")
70
+ # for i, match in enumerate(top_matches, 1):
71
+ # table.add_row(f"[cyan]{i}[/cyan]", match, name_to_doc.get(match, ""))
72
+ # console.print(table)
73
+ # else:
74
+ # console.print("📋 Here are some available options:", style="blue")
75
+ # # Show first 10 installers as examples
76
+ # if len(all_names) > 10:
77
+ # sample_names = all_names[:10]
78
+ # else:
79
+ # sample_names = all_names
80
+ # table = Table(show_header=True, header_style="bold", box=None, pad_edge=False)
81
+ # table.add_column("#", justify="right", width=3)
82
+ # table.add_column("Installer", style="green")
83
+ # table.add_column("Description", style="dim", overflow="fold")
84
+ # for i, name in enumerate(sample_names, 1):
85
+ # table.add_row(f"[cyan]{i}[/cyan]", name, name_to_doc.get(name, ""))
86
+ # console.print(table)
87
+ # if len(all_names) > 10:
88
+ # console.print(f" [dim]... and {len(all_names) - 10} more[/dim]")
73
89
 
74
- panel = Panel(f"[bold blue]💡 Use 'ia' to interactively browse all available installers.[/bold blue]\n[bold blue]💡 Use one of the categories: {list(PACKAGE_GROUP2NAMES.keys())}[/bold blue]", title="[yellow]Helpful Tips[/yellow]", border_style="yellow")
75
- console.print(panel)
90
+ # panel = Panel(f"[bold blue]💡 Use 'ia' to interactively browse all available installers.[/bold blue]\n[bold blue]💡 Use one of the categories: {list(PACKAGE_GROUP2NAMES.keys())}[/bold blue]", title="[yellow]Helpful Tips[/yellow]", border_style="yellow")
91
+ # console.print(panel)
76
92
 
77
93
 
78
94
  def install_deb_package(downloaded: Path) -> None:
@@ -104,7 +120,7 @@ def install_deb_package(downloaded: Path) -> None:
104
120
 
105
121
  def download_and_prepare(download_url: str) -> PathExtended:
106
122
  # archive_path = PathExtended(download_url).download(folder=INSTALL_TMP_DIR)
107
- from machineconfig.scripts.python.helpers_utils.download import download
123
+ from machineconfig.scripts.python.helpers.helpers_utils.download import download
108
124
  downloaded_object = download(download_url, output_dir=str(INSTALL_TMP_DIR))
109
125
  if downloaded_object is None:
110
126
  raise ValueError(f"Failed to download from URL: {download_url}")
@@ -121,7 +137,7 @@ def download_and_prepare(download_url: str) -> PathExtended:
121
137
  if nested_path.is_file() and any(ex in nested_path.suffixes for ex in DECOMPRESS_SUPPORTED_FORMATS):
122
138
  extracted_path = nested_path.decompress()
123
139
  nested_path.delete(sure=True)
124
- elif extracted_path.is_dir() and len(extracted_path.search("*", r=True)) == 1:
140
+ elif extracted_path.is_dir() and len([p for p in extracted_path.rglob("*") if not p.name.startswith(".")]) == 1:
125
141
  only_file_in = next(extracted_path.glob("*"))
126
142
  if only_file_in.is_file() and any(ext in str(only_file_in) for ext in DECOMPRESS_SUPPORTED_FORMATS): # further decompress
127
143
  extracted_path = only_file_in.decompress()
@@ -22,15 +22,15 @@ def find_move_delete_windows(downloaded_file_path: PathExtended, tool_name: Opti
22
22
  else:
23
23
  print(f"🔎 Searching for executable in: {downloaded_file_path}")
24
24
  if tool_name is None:
25
- exe = downloaded_file_path.search("*.exe", r=True)[0]
25
+ exe = list(downloaded_file_path.rglob("*.exe"))[0]
26
26
  print(f"✅ Found executable: {exe}")
27
27
  else:
28
- tmp = downloaded_file_path.search(f"{tool_name}.exe", r=True)
28
+ tmp = list(downloaded_file_path.rglob(f"{tool_name}.exe"))
29
29
  if len(tmp) == 1:
30
30
  exe = tmp[0]
31
31
  print(f"✅ Found exact match for {tool_name}.exe: {exe}")
32
32
  else:
33
- search_res = downloaded_file_path.search("*.exe", r=True)
33
+ search_res = list(downloaded_file_path.rglob("*.exe"))
34
34
  if len(search_res) == 0:
35
35
  print(f"❌ ERROR: No executable found in {downloaded_file_path}")
36
36
  raise IndexError(f"No executable found in {downloaded_file_path}")
@@ -38,8 +38,8 @@ def find_move_delete_windows(downloaded_file_path: PathExtended, tool_name: Opti
38
38
  exe = search_res[0]
39
39
  print(f"✅ Found single executable: {exe}")
40
40
  else:
41
- exe = max(search_res, key=lambda x: x.size("kb"))
42
- print(f"✅ Selected largest executable ({exe.size('kb')} KB): {exe}")
41
+ exe = max(search_res, key=lambda x: x.stat().st_size)
42
+ print(f"✅ Selected largest executable ({round(exe.stat().st_size / 1024, 1)} KB): {exe}")
43
43
  if rename_to and exe.name != rename_to:
44
44
  print(f"🏷️ Renaming '{exe.name}' to '{rename_to}'")
45
45
  exe = exe.with_name(name=rename_to, inplace=True)
@@ -70,20 +70,20 @@ def find_move_delete_linux(downloaded: PathExtended, tool_name: Optional[str], d
70
70
  print(f"📄 Found direct executable file: {exe}")
71
71
  else:
72
72
  print(f"🔎 Searching for executable in: {downloaded}")
73
- res = downloaded.search(f"*{tool_name}*", folders=False, r=True)
73
+ res = [p for p in downloaded.rglob(f"*{tool_name}*") if p.is_file()]
74
74
  if len(res) == 1:
75
75
  exe = res[0]
76
76
  print(f"✅ Found match for pattern '*{tool_name}*': {exe}")
77
77
  else:
78
78
  if tool_name is None: # no tool name provided, get the largest executable
79
- search_res = downloaded.search("*", folders=False, files=True, r=True)
79
+ search_res = [p for p in downloaded.rglob("*") if p.is_file()]
80
80
  if len(search_res) == 0:
81
81
  print(f"❌ ERROR: No search results in `{downloaded}`")
82
82
  raise IndexError(f"No executable found in {downloaded}")
83
- exe = max(search_res, key=lambda x: x.size("kb"))
84
- print(f"✅ Selected largest executable ({exe.size('kb')} KB): {exe}")
83
+ exe = max(search_res, key=lambda x: x.stat().st_size)
84
+ print(f"✅ Selected largest executable ({round(exe.stat().st_size / 1024, 1)} KB): {exe}")
85
85
  else:
86
- exe_search_res = downloaded.search(tool_name, folders=False, r=True)
86
+ exe_search_res = [p for p in downloaded.rglob(tool_name) if p.is_file()]
87
87
  if len(exe_search_res) == 0:
88
88
  print(f"❌ ERROR: No search results for `{tool_name}` in `{downloaded}`")
89
89
  raise IndexError(f"No executable found in {downloaded}")
@@ -91,8 +91,8 @@ def find_move_delete_linux(downloaded: PathExtended, tool_name: Optional[str], d
91
91
  exe = exe_search_res[0]
92
92
  print(f"✅ Found exact match for '{tool_name}': {exe}")
93
93
  else:
94
- exe = max(exe_search_res, key=lambda x: x.size("kb"))
95
- print(f"✅ Selected largest executable ({exe.size('kb')} KB): {exe}")
94
+ exe = max(exe_search_res, key=lambda x: x.stat().st_size)
95
+ print(f"✅ Selected largest executable ({round(exe.stat().st_size / 1024, 1)} KB): {exe}")
96
96
 
97
97
  if rename_to and exe.name != rename_to:
98
98
  print(f"🏷️ Renaming '{exe.name}' to '{rename_to}'")
@@ -144,20 +144,10 @@ def check_tool_exists(tool_name: str) -> bool:
144
144
  standard_checks = [
145
145
  Path("/usr/local/bin").joinpath(tool_name).is_file(),
146
146
  Path("/usr/bin").joinpath(tool_name).is_file(),
147
- root_path.joinpath(tool_name).is_file()
147
+ root_path.joinpath(tool_name).is_file(),
148
+ (Path.home() / ".bun" / "bin" / tool_name ).is_file(),
148
149
  ]
149
- if any(standard_checks):
150
- return True
151
- # Check for npm packages via nvm
152
- npm_check = False
153
- try:
154
- result = subprocess.run(["node", "--version"], capture_output=True, text=True, check=True)
155
- version = result.stdout.strip().lstrip('v')
156
- nvm_bin_path = Path.home() / ".nvm" / "versions" / "node" / f"v{version}" / "bin" / tool_name
157
- npm_check = nvm_bin_path.is_file()
158
- except subprocess.CalledProcessError:
159
- pass
160
- return npm_check
150
+ return any(standard_checks)
161
151
  else:
162
152
  raise NotImplementedError(f"platform {platform.system()} not implemented")
163
153
 
@@ -75,18 +75,18 @@ def get_installed_cli_apps():
75
75
  print("🔍 LISTING INSTALLED CLI APPS 🔍")
76
76
  if platform.system() == "Windows":
77
77
  print("🪟 Searching for Windows executables...")
78
- apps = PathExtended.home().joinpath("AppData/Local/Microsoft/WindowsApps").search("*.exe", not_in=["notepad"])
78
+ apps = [p for p in PathExtended.home().joinpath("AppData/Local/Microsoft/WindowsApps").glob("*.exe") if "notepad" not in str(p)]
79
79
  elif platform.system() in ["Linux", "Darwin"]:
80
80
  print(f"🐧 Searching for {platform.system()} executables...")
81
81
  if platform.system() == "Linux":
82
- apps = PathExtended(LINUX_INSTALL_PATH).search("*") + PathExtended("/usr/local/bin").search("*")
82
+ apps = list(PathExtended(LINUX_INSTALL_PATH).glob("*")) + list(PathExtended("/usr/local/bin").glob("*"))
83
83
  else: # Darwin/macOS
84
- apps = PathExtended("/usr/local/bin").search("*") + PathExtended("/opt/homebrew/bin").search("*")
84
+ apps = list(PathExtended("/usr/local/bin").glob("*")) + list(PathExtended("/opt/homebrew/bin").glob("*"))
85
85
  else:
86
86
  error_msg = f"❌ ERROR: System {platform.system()} not supported"
87
87
  print(error_msg)
88
88
  raise NotImplementedError(error_msg)
89
- apps = [app for app in apps if app.size("kb") > 0.1 and not app.is_symlink()] # no symlinks like paint and wsl and bash
89
+ apps = [app for app in apps if (app.stat().st_size / 1024) > 0.1 and not app.is_symlink()] # no symlinks like paint and wsl and bash
90
90
  print(f"✅ Found {len(apps)} installed applications")
91
91
  return apps
92
92
 
machineconfig/utils/io.py CHANGED
@@ -55,19 +55,36 @@ def read_ini(path: "Path", encoding: Optional[str] = None):
55
55
  return res
56
56
 
57
57
 
58
+ def remove_c_style_comments(text: str) -> str:
59
+ import re
60
+ # Step 1: Escape URLs (https:// or any URLs you want to protect)
61
+ url_pattern = r'https?://[^\s]*'
62
+ urls = re.findall(url_pattern, text)
63
+ url_map = {url: f"__URL{index}__" for index, url in enumerate(urls)}
64
+
65
+ # Temporarily replace URLs with placeholders
66
+ for url, placeholder in url_map.items():
67
+ text = text.replace(url, placeholder)
68
+
69
+ # Step 2: Remove C-style comments
70
+ # Remove all // single-line comments
71
+ text = re.sub(r'//.*', '', text)
72
+ # Remove all /* … */ block comments (non-greedy)
73
+ text = re.sub(r'/\*.*?\*/', '', text, flags=re.DOTALL)
74
+
75
+ # Step 3: Restore URLs
76
+ for url, placeholder in url_map.items():
77
+ text = text.replace(placeholder, url)
78
+
79
+ return text
80
+
81
+
58
82
  def read_json(path: "Path", r: bool = False, **kwargs: Any) -> Any: # return could be list or dict etc
59
83
  import json
60
84
  try:
61
85
  mydict = json.loads(Path(path).read_text(encoding="utf-8"), **kwargs)
62
86
  except Exception:
63
- import re
64
- def remove_comments(text: str) -> str:
65
- # remove all // single-line comments
66
- text = re.sub(r'//.*', '', text)
67
- # remove all /* … */ block comments (non-greedy)
68
- text = re.sub(r'/\*.*?\*/', '', text, flags=re.DOTALL)
69
- return text
70
- mydict = json.loads(remove_comments(Path(path).read_text(encoding="utf-8")), **kwargs)
87
+ mydict = json.loads(remove_c_style_comments(Path(path).read_text(encoding="utf-8")), **kwargs)
71
88
  _ = r
72
89
  return mydict
73
90
 
@@ -5,7 +5,7 @@ from typing import Any
5
5
 
6
6
 
7
7
  def get_import_module_string(py_file: str) -> str:
8
- from machineconfig.scripts.python.helpers_fire_command.file_wrangler import get_import_module_code
8
+ from machineconfig.scripts.python.helpers.helpers_fire_command.file_wrangler import get_import_module_code
9
9
  from machineconfig.utils.accessories import get_repo_root
10
10
  from pathlib import Path
11
11
  repo_root = get_repo_root(Path(py_file))
@@ -68,7 +68,7 @@ def lambda_to_python_script(lmb: Callable[[], Any],
68
68
 
69
69
  # sanity checks
70
70
  if not (callable(lmb) and isinstance(lmb, _types.LambdaType)):
71
- raise TypeError("Expected a lambda function object")
71
+ raise TypeError(f"Expected a lambda function object, got {type(lmb)}")
72
72
 
73
73
  src = _inspect.getsource(lmb)
74
74
  src = _textwrap.dedent(src)
@@ -81,7 +81,7 @@ def lambda_to_python_script(lmb: Callable[[], Any],
81
81
  lambda_node = n
82
82
  break
83
83
  if lambda_node is None:
84
- raise ValueError("Could not find a lambda expression in source")
84
+ raise ValueError(f"""Could not find a lambda expression in source, got:\n{lmb}\nwhich is not a lambda, its a {src}""")
85
85
 
86
86
  body = lambda_node.body
87
87
  if not isinstance(body, _ast.Call):
@@ -113,7 +113,7 @@ def lambda_to_python_script(lmb: Callable[[], Any],
113
113
  if not callable(func_obj):
114
114
  raise TypeError("Resolved object is not callable")
115
115
 
116
- func_name = getattr(func_obj, "__name__", "<unknown>")
116
+ func_name = getattr(getattr(func_obj, "__code__", None), "co_name", None) or getattr(func_obj, "__name__", "<unknown>")
117
117
 
118
118
  import_prefix: str = ""
119
119
  if import_module:
@@ -249,8 +249,10 @@ def lambda_to_python_script(lmb: Callable[[], Any],
249
249
  if __name__ == "__main__":
250
250
  from machineconfig.utils.code import print_code
251
251
  import_code_robust = "<import_code_robust>"
252
+ print_code.__name__ = "blah"
252
253
  res = lambda_to_python_script(
253
254
  lambda: print_code(code=import_code_robust, lexer="python", desc="import as module code"),
254
255
  in_global=True, import_module=False
255
256
  )
257
+
256
258
  print(res)
@@ -7,10 +7,10 @@ import subprocess
7
7
  from typing import Optional, Union, Iterable, overload, Literal, cast
8
8
 
9
9
  @overload
10
- def choose_from_options[T](options: Iterable[T], msg: str, multi: Literal[False], custom_input: bool = False, header: str = "", tail: str = "", prompt: str = "", default: Optional[T] = None, tv: bool = False) -> T: ...
10
+ def choose_from_options[T](options: Iterable[T], msg: str, multi: Literal[False], custom_input: bool = False, header: str = "", tail: str = "", prompt: str = "", default: Optional[T] = None, tv: bool = False, preview: Optional[Literal["bat"]]=None) -> T: ...
11
11
  @overload
12
- def choose_from_options[T](options: Iterable[T], msg: str, multi: Literal[True], custom_input: bool = True, header: str = "", tail: str = "", prompt: str = "", default: Optional[T] = None, tv: bool = False, ) -> list[T]: ...
13
- def choose_from_options[T](options: Iterable[T], msg: str, multi: bool, custom_input: bool = True, header: str = "", tail: str = "", prompt: str = "", default: Optional[T] = None, tv: bool = False, ) -> Union[T, list[T]]:
12
+ def choose_from_options[T](options: Iterable[T], msg: str, multi: Literal[True], custom_input: bool = True, header: str = "", tail: str = "", prompt: str = "", default: Optional[T] = None, tv: bool = False, preview: Optional[Literal["bat"]]=None) -> list[T]: ...
13
+ def choose_from_options[T](options: Iterable[T], msg: str, multi: bool, custom_input: bool = True, header: str = "", tail: str = "", prompt: str = "", default: Optional[T] = None, tv: bool = False, preview: Optional[Literal["bat"]]=None, ) -> Union[T, list[T]]:
14
14
  # TODO: replace with https://github.com/tmbo/questionary
15
15
  # # also see https://github.com/charmbracelet/gum
16
16
  options_strings: list[str] = [str(x) for x in options]
@@ -20,11 +20,6 @@ def choose_from_options[T](options: Iterable[T], msg: str, multi: bool, custom_i
20
20
  # from machineconfig.utils.installer_utils.installer_cli import check_tool_exists
21
21
  # print("ch1")
22
22
  if tv and check_tool_exists("tv"):
23
- # from pyfzf.pyfzf import FzfPrompt
24
- # fzf_prompt = FzfPrompt()
25
- # nl = "\n"
26
- # choice_string_multi: list[str] = fzf_prompt.prompt(choices=options_strings, fzf_options=("--multi" if multi else "") + f' --prompt "{prompt.replace(nl, " ")}" --ansi') # --border-label={msg.replace(nl, ' ')}")
27
- # print("ch2")
28
23
  from machineconfig.utils.accessories import randstr
29
24
  options_txt_path = Path.home().joinpath("tmp_results/tmp_files/choices_" + randstr(6) + ".txt")
30
25
  options_txt_path.parent.mkdir(parents=True, exist_ok=True)
@@ -35,34 +30,70 @@ def choose_from_options[T](options: Iterable[T], msg: str, multi: bool, custom_i
35
30
  # the interactive session completes. Do not capture_output or redirect
36
31
  # stdin/stderr here so `tv` stays attached to the terminal.
37
32
  tv_out_path = options_txt_path.with_name(options_txt_path.stem + "_out.txt")
38
- tv_cmd = f"""cat {options_txt_path} | tv --ansi true --source-output "{{strip_ansi}}" > {tv_out_path}"""
39
- res = subprocess.run(tv_cmd, shell=True)
40
-
33
+ if preview is None:
34
+ preview_line = ""
35
+ elif preview == "bat":
36
+ preview_line = r"""--preview-command "bat -n --color=always {}" --preview-size 70 """
37
+
38
+ import platform
39
+ if platform.system() == "Windows":
40
+ # PowerShell + TUI apps can be finicky when stdin is a pipe. Avoid piping into `tv` and
41
+ # instead provide a `--source-command` so `tv` can keep stdin attached to the console.
42
+ # Also: `tv --ansi` is a flag (no value). Passing `true` makes it a positional argument
43
+ # (channel/path/command), which can lead to confusing behavior.
44
+ source_cmd = f"cmd /C type \"{options_txt_path}\""
45
+ tv_cmd = f"""
46
+ $OutputEncoding = [Console]::InputEncoding = [Console]::OutputEncoding = [System.Text.UTF8Encoding]::new()
47
+ tv {preview_line} --ansi --source-command '{source_cmd}' --source-output "{{}}" | Out-File -Encoding utf8 -FilePath "{tv_out_path}" """
48
+ else:
49
+ source_cmd = f'cat "{options_txt_path}"'
50
+ tv_cmd = f"""tv {preview_line} --ansi --source-command "{source_cmd}" --source-output "{{}}" > "{tv_out_path}" """
51
+
52
+ # print(f"Running tv command: {tv_cmd}")
53
+ # print(f"Options file: {options_txt_path}")
54
+ # print(f"Content:\n{options_txt_path.read_text(encoding='utf-8')}")
55
+ # print(f"tv output file: {tv_out_path}")
56
+ from machineconfig.utils.code import run_shell_script
57
+ res = run_shell_script(tv_cmd, display_script=False, clean_env=False)
58
+
41
59
  # If tv returned a non-zero code and there is no output file, treat it as an error.
42
60
  if res.returncode != 0 and not tv_out_path.exists():
43
61
  raise RuntimeError(f"Got error running tv command: {tv_cmd}\nreturncode: {res.returncode}")
44
62
 
45
63
  # Read selections (if any) from the output file created by tv.
46
- out_text = tv_out_path.read_text(encoding="utf-8") if tv_out_path.exists() else ""
64
+ print(f"Reading tv output from: {tv_out_path}")
65
+ out_text = tv_out_path.read_text(encoding="utf-8-sig")
47
66
  choice_string_multi = [x for x in out_text.splitlines() if x.strip() != ""]
48
67
 
68
+ # if len(choice_string_multi) == 0: # e.g. user pressed escape
69
+ # console.print(Panel("❓ No option selected!", title="Error", expand=False))
70
+ # return choose_from_options(msg=msg, options=options, header=header, tail=tail, prompt=prompt, default=default, tv=tv, multi=multi, custom_input=custom_input)
71
+
49
72
  # Cleanup temporary files
50
73
  options_txt_path.unlink(missing_ok=True)
51
74
  tv_out_path.unlink(missing_ok=True)
52
75
  if not multi:
53
76
  try:
54
77
  choice_one_string = choice_string_multi[0]
55
- if isinstance(list(options)[0], str): return cast(T, choice_one_string)
78
+ if isinstance(list(options)[0], str):
79
+ print(f"✅ Selected option: {choice_one_string}")
80
+ return cast(T, choice_one_string)
56
81
  choice_idx = options_strings.index(choice_one_string)
57
- return list(options)[choice_idx]
82
+ choice_made = list(options)[choice_idx]
83
+ print(f"✅ Selected option: {choice_made}")
84
+ return choice_made
58
85
  except IndexError as ie:
59
- print(f"❌ Error: {options=}, {choice_string_multi=}")
60
- print(f"🔍 Available choices: {choice_string_multi}")
86
+ # print(f"❌ Error: {options=}, {choice_string_multi=}")
87
+ print(f"🔍 Available choices: {len(choice_string_multi)}")
61
88
  raise ie
62
89
  if isinstance(list(options)[0], str):
63
- return cast(list[T], choice_string_multi)
90
+ result2 = cast(list[T], choice_string_multi)
91
+ print(f"✅ Selected options: {result2}")
92
+ return result2
64
93
  choice_idx_s = [options_strings.index(x) for x in choice_string_multi]
65
- return [list(options)[x] for x in choice_idx_s]
94
+ result = [list(options)[x] for x in choice_idx_s]
95
+ print(f"✅ Selected options: {result}")
96
+ return result
66
97
  else:
67
98
  if default is not None:
68
99
  assert default in options, f"Default `{default}` option not in options `{list(options)}`"
@@ -138,7 +169,6 @@ def choose_cloud_interactively() -> str:
138
169
 
139
170
  def get_ssh_hosts() -> list[str]:
140
171
  from paramiko import SSHConfig
141
-
142
172
  c = SSHConfig()
143
173
  c.parse(open(Path.home().joinpath(".ssh/config"), encoding="utf-8"))
144
174
  return list(c.get_hostnames())
File without changes