machineconfig 6.82__py3-none-any.whl → 7.98__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 (294) hide show
  1. machineconfig/cluster/remote/cloud_manager.py +1 -1
  2. machineconfig/cluster/sessions_managers/utils/maker.py +25 -13
  3. machineconfig/cluster/sessions_managers/wt_local.py +16 -221
  4. machineconfig/cluster/sessions_managers/wt_local_manager.py +55 -193
  5. machineconfig/cluster/sessions_managers/wt_remote_manager.py +42 -198
  6. machineconfig/cluster/sessions_managers/wt_utils/manager_persistence.py +52 -0
  7. machineconfig/cluster/sessions_managers/wt_utils/monitoring_helpers.py +50 -0
  8. machineconfig/cluster/sessions_managers/wt_utils/status_reporting.py +76 -0
  9. machineconfig/cluster/sessions_managers/wt_utils/wt_helpers.py +199 -0
  10. machineconfig/cluster/sessions_managers/zellij_local_manager.py +3 -1
  11. machineconfig/cluster/sessions_managers/zellij_remote_manager.py +3 -2
  12. machineconfig/cluster/sessions_managers/zellij_utils/process_monitor.py +2 -2
  13. machineconfig/jobs/installer/custom/boxes.py +2 -2
  14. machineconfig/jobs/installer/custom/hx.py +75 -18
  15. machineconfig/jobs/installer/custom/yazi.py +119 -0
  16. machineconfig/jobs/installer/custom_dev/brave.py +5 -3
  17. machineconfig/jobs/installer/custom_dev/cloudflare_warp_cli.py +23 -0
  18. machineconfig/jobs/installer/custom_dev/code.py +4 -1
  19. machineconfig/jobs/installer/custom_dev/dubdb_adbc.py +1 -1
  20. machineconfig/jobs/installer/custom_dev/nerdfont.py +1 -1
  21. machineconfig/jobs/installer/custom_dev/nerfont_windows_helper.py +27 -22
  22. machineconfig/jobs/installer/custom_dev/sysabc.py +139 -0
  23. machineconfig/jobs/installer/custom_dev/wezterm.py +2 -19
  24. machineconfig/jobs/installer/custom_dev/winget.py +10 -14
  25. machineconfig/jobs/installer/installer_data.json +1287 -216
  26. machineconfig/jobs/installer/linux_scripts/q.sh +10 -7
  27. machineconfig/jobs/installer/linux_scripts/redis.sh +1 -0
  28. machineconfig/jobs/installer/package_groups.py +58 -89
  29. machineconfig/jobs/installer/powershell_scripts/install_fonts.ps1 +129 -34
  30. machineconfig/logger.py +0 -1
  31. machineconfig/profile/create_helper.py +43 -16
  32. machineconfig/profile/create_links.py +2 -1
  33. machineconfig/profile/create_links_export.py +64 -18
  34. machineconfig/profile/create_shell_profile.py +78 -127
  35. machineconfig/profile/mapper.toml +15 -8
  36. machineconfig/scripts/__init__.py +0 -4
  37. machineconfig/scripts/linux/wrap_mcfg +46 -0
  38. machineconfig/scripts/nu/wrap_mcfg.nu +69 -0
  39. machineconfig/scripts/python/agents.py +52 -37
  40. machineconfig/scripts/python/ai/initai.py +1 -1
  41. machineconfig/scripts/python/ai/scripts/command_runner.ps1 +33 -0
  42. machineconfig/scripts/python/ai/{command_runner → scripts}/command_runner.sh +1 -1
  43. machineconfig/scripts/python/ai/solutions/copilot/{chatmodes/Thinking-Beast-Mode.chatmode.md → agents/Thinking-Beast-Mode.agent.md} +0 -1
  44. machineconfig/scripts/python/ai/solutions/copilot/{chatmodes/Ultimate-Transparent-Thinking-Beast-Mode.chatmode.md → agents/Ultimate-Transparent-Thinking-Beast-Mode.agent.md} +0 -1
  45. machineconfig/scripts/python/ai/solutions/copilot/{chatmodes/deepResearch.chatmode.md → agents/deepResearch.agent.md} +2 -2
  46. machineconfig/scripts/python/ai/solutions/copilot/github_copilot.py +5 -5
  47. machineconfig/scripts/python/ai/solutions/copilot/instructions/python/dev.instructions.md +4 -0
  48. machineconfig/scripts/python/ai/solutions/copilot/instructions/python/watch_exec.prompt.md +20 -0
  49. machineconfig/scripts/python/ai/solutions/generic.py +1 -1
  50. machineconfig/scripts/python/ai/{generate_files.py → utils/generate_files.py} +2 -2
  51. machineconfig/scripts/python/ai/{vscode_tasks.py → utils/vscode_tasks.py} +7 -2
  52. machineconfig/scripts/python/croshell.py +77 -78
  53. machineconfig/scripts/python/devops.py +39 -21
  54. machineconfig/scripts/python/devops_navigator.py +0 -4
  55. machineconfig/scripts/python/env_manager/env_manager_tui.py +204 -0
  56. machineconfig/scripts/python/env_manager/path_manager_tui.py +1 -1
  57. machineconfig/scripts/python/fire_jobs.py +84 -115
  58. machineconfig/scripts/python/ftpx.py +42 -16
  59. machineconfig/scripts/python/helpers/ast_search.py +74 -0
  60. machineconfig/scripts/python/helpers/qr_code.py +166 -0
  61. machineconfig/scripts/python/helpers/repo_rag.py +325 -0
  62. machineconfig/scripts/python/helpers/run_py_script.py +79 -0
  63. machineconfig/scripts/python/helpers/symantic_search.py +25 -0
  64. machineconfig/scripts/python/helpers/tmp_py_scripts/a.py +26 -0
  65. machineconfig/scripts/python/{helpers_fire → helpers_agents}/agentic_frameworks/fire_crush.json +1 -1
  66. machineconfig/scripts/python/helpers_agents/agentic_frameworks/fire_crush.py +39 -0
  67. machineconfig/scripts/python/{helpers_fire → helpers_agents}/agentic_frameworks/fire_cursor_agents.py +3 -4
  68. machineconfig/scripts/python/helpers_agents/agentic_frameworks/fire_gemini.py +55 -0
  69. machineconfig/scripts/python/helpers_agents/agentic_frameworks/fire_qwen.py +30 -0
  70. machineconfig/scripts/python/{helpers_fire → helpers_agents}/fire_agents_help_launch.py +32 -13
  71. machineconfig/scripts/python/{helpers_fire → helpers_agents}/fire_agents_helper_types.py +11 -14
  72. machineconfig/scripts/python/helpers_agents/templates/prompt.txt +10 -0
  73. machineconfig/scripts/python/helpers_agents/templates/template.sh +32 -0
  74. machineconfig/scripts/python/helpers_cloud/cloud_copy.py +28 -21
  75. machineconfig/scripts/python/helpers_cloud/cloud_helpers.py +1 -1
  76. machineconfig/scripts/python/helpers_cloud/cloud_mount.py +19 -17
  77. machineconfig/scripts/python/helpers_cloud/cloud_sync.py +8 -7
  78. machineconfig/scripts/python/helpers_croshell/crosh.py +3 -3
  79. machineconfig/scripts/python/helpers_croshell/start_slidev.py +6 -7
  80. machineconfig/scripts/python/helpers_devops/cli_config.py +46 -61
  81. machineconfig/scripts/python/helpers_devops/cli_config_dotfile.py +67 -55
  82. machineconfig/scripts/python/helpers_devops/cli_nw.py +157 -16
  83. machineconfig/scripts/python/helpers_devops/cli_repos.py +55 -21
  84. machineconfig/scripts/python/helpers_devops/cli_self.py +98 -48
  85. machineconfig/scripts/python/helpers_devops/cli_share_file.py +137 -0
  86. machineconfig/scripts/python/helpers_devops/cli_share_server.py +80 -42
  87. machineconfig/scripts/python/helpers_devops/{cli_terminal.py → cli_share_terminal.py} +15 -17
  88. machineconfig/scripts/python/helpers_devops/cli_utils.py +3 -128
  89. machineconfig/scripts/python/helpers_devops/devops_backup_retrieve.py +4 -4
  90. machineconfig/scripts/python/helpers_devops/devops_status.py +7 -19
  91. machineconfig/scripts/python/helpers_devops/themes/choose_wezterm_theme.py +1 -1
  92. machineconfig/scripts/python/{helpers_fire/helpers4.py → helpers_fire_command/file_wrangler.py} +56 -20
  93. machineconfig/scripts/python/helpers_fire_command/fire_jobs_route_helper.py +26 -16
  94. machineconfig/scripts/python/helpers_msearch/__init__.py +5 -0
  95. machineconfig/scripts/{linux → python/helpers_msearch/scripts_linux}/fzfg +3 -3
  96. machineconfig/scripts/python/helpers_msearch/scripts_windows/fzfg.ps1 +59 -0
  97. machineconfig/scripts/python/helpers_navigator/command_tree.py +50 -18
  98. machineconfig/scripts/python/helpers_network/address.py +132 -0
  99. machineconfig/scripts/python/{nw → helpers_network}/devops_add_ssh_key.py +24 -5
  100. machineconfig/scripts/python/{nw → helpers_network}/mount_nfs +0 -1
  101. machineconfig/scripts/python/{nw → helpers_network}/mount_nfs.py +2 -2
  102. machineconfig/scripts/python/{nw → helpers_network}/mount_ssh.py +1 -1
  103. machineconfig/scripts/python/{nw → helpers_network}/ssh_debug_linux.py +7 -7
  104. machineconfig/scripts/python/{nw → helpers_network}/ssh_debug_windows.py +4 -4
  105. machineconfig/scripts/python/{nw → helpers_network}/wifi_conn.py +1 -53
  106. machineconfig/scripts/python/{nw → helpers_network}/wsl_windows_transfer.py +3 -2
  107. machineconfig/scripts/python/helpers_repos/clone.py +0 -1
  108. machineconfig/scripts/python/helpers_repos/cloud_repo_sync.py +46 -19
  109. machineconfig/scripts/python/helpers_repos/entrypoint.py +2 -1
  110. machineconfig/scripts/python/helpers_repos/grource.py +1 -1
  111. machineconfig/scripts/python/helpers_repos/record.py +2 -1
  112. machineconfig/scripts/python/helpers_repos/repo_analyzer_1.py +160 -0
  113. machineconfig/scripts/python/helpers_repos/{count_lines.py → repo_analyzer_2.py} +113 -192
  114. machineconfig/scripts/python/helpers_sessions/sessions_multiprocess.py +20 -13
  115. machineconfig/scripts/python/helpers_utils/download.py +150 -0
  116. machineconfig/scripts/python/helpers_utils/path.py +185 -0
  117. machineconfig/scripts/python/interactive.py +19 -26
  118. machineconfig/scripts/python/{mcfg.py → mcfg_entry.py} +10 -0
  119. machineconfig/scripts/python/msearch.py +71 -0
  120. machineconfig/scripts/python/sessions.py +94 -25
  121. machineconfig/scripts/python/terminal.py +133 -0
  122. machineconfig/scripts/python/utils.py +28 -30
  123. machineconfig/scripts/windows/mounts/mount_ssh.ps1 +1 -1
  124. machineconfig/scripts/windows/wrap_mcfg.ps1 +63 -0
  125. machineconfig/settings/broot/conf.toml +1 -1
  126. machineconfig/settings/helix/config.toml +16 -0
  127. machineconfig/settings/helix/languages.toml +13 -4
  128. machineconfig/settings/helix/yazi-picker.sh +12 -0
  129. machineconfig/settings/lf/linux/exe/lfcd.sh +1 -0
  130. machineconfig/settings/lf/linux/exe/previewer.sh +3 -2
  131. machineconfig/settings/lf/windows/lfcd.ps1 +1 -1
  132. machineconfig/settings/lf/windows/lfrc +14 -16
  133. machineconfig/settings/marimo/marimo.toml +1 -1
  134. machineconfig/settings/marimo/snippets/globalize.py +34 -0
  135. machineconfig/settings/shells/bash/init.sh +43 -11
  136. machineconfig/settings/shells/ipy/profiles/default/startup/playext.py +1 -1
  137. machineconfig/settings/shells/nushell/config.nu +2 -32
  138. machineconfig/settings/shells/nushell/env.nu +45 -6
  139. machineconfig/settings/shells/nushell/init.nu +314 -0
  140. machineconfig/settings/shells/pwsh/init.ps1 +40 -14
  141. machineconfig/settings/shells/starship/starship.toml +16 -0
  142. machineconfig/settings/shells/wezterm/wezterm.lua +2 -0
  143. machineconfig/settings/shells/wt/settings.json +14 -5
  144. machineconfig/settings/shells/zsh/init.sh +17 -19
  145. machineconfig/settings/television/cable_unix/alias.toml +8 -0
  146. machineconfig/settings/television/cable_unix/aws-buckets.toml +14 -0
  147. machineconfig/settings/television/cable_unix/aws-instances.toml +13 -0
  148. machineconfig/settings/television/cable_unix/bash-history.toml +8 -0
  149. machineconfig/settings/television/cable_unix/channels.toml +19 -0
  150. machineconfig/settings/television/cable_unix/dirs.toml +13 -0
  151. machineconfig/settings/television/cable_unix/distrobox-list.toml +42 -0
  152. machineconfig/settings/television/cable_unix/docker-images.toml +13 -0
  153. machineconfig/settings/television/cable_unix/dotfiles.toml +11 -0
  154. machineconfig/settings/television/cable_unix/env.toml +17 -0
  155. machineconfig/settings/television/cable_unix/files.toml +11 -0
  156. machineconfig/settings/television/cable_unix/fish-history.toml +8 -0
  157. machineconfig/settings/television/cable_unix/git-branch.toml +11 -0
  158. machineconfig/settings/television/cable_unix/git-diff.toml +10 -0
  159. machineconfig/settings/television/cable_unix/git-log.toml +12 -0
  160. machineconfig/settings/television/cable_unix/git-reflog.toml +12 -0
  161. machineconfig/settings/television/cable_unix/git-repos.toml +16 -0
  162. machineconfig/settings/television/cable_unix/guix.toml +20 -0
  163. machineconfig/settings/television/cable_unix/just-recipes.toml +18 -0
  164. machineconfig/settings/television/cable_unix/k8s-deployments.toml +36 -0
  165. machineconfig/settings/television/cable_unix/k8s-pods.toml +50 -0
  166. machineconfig/settings/television/cable_unix/k8s-services.toml +36 -0
  167. machineconfig/settings/television/cable_unix/man-pages.toml +24 -0
  168. machineconfig/settings/television/cable_unix/nu-history.toml +7 -0
  169. machineconfig/settings/television/cable_unix/procs.toml +20 -0
  170. machineconfig/settings/television/cable_unix/text.toml +17 -0
  171. machineconfig/settings/television/cable_unix/tldr.toml +18 -0
  172. machineconfig/settings/television/cable_unix/zsh-history.toml +9 -0
  173. machineconfig/settings/television/cable_windows/alias.toml +7 -0
  174. machineconfig/settings/television/cable_windows/dirs.toml +13 -0
  175. machineconfig/settings/television/cable_windows/docker-images.toml +13 -0
  176. machineconfig/settings/television/cable_windows/dotfiles.toml +11 -0
  177. machineconfig/settings/television/cable_windows/env.toml +17 -0
  178. machineconfig/settings/television/cable_windows/files.toml +14 -0
  179. machineconfig/settings/television/cable_windows/git-branch.toml +11 -0
  180. machineconfig/settings/television/cable_windows/git-diff.toml +10 -0
  181. machineconfig/settings/television/cable_windows/git-log.toml +11 -0
  182. machineconfig/settings/television/cable_windows/git-reflog.toml +11 -0
  183. machineconfig/settings/television/cable_windows/git-repos.toml +15 -0
  184. machineconfig/settings/television/cable_windows/nu-history.toml +7 -0
  185. machineconfig/settings/television/cable_windows/pwsh-history.toml +6 -0
  186. machineconfig/settings/television/cable_windows/text.toml +17 -0
  187. machineconfig/settings/yazi/init.lua +61 -0
  188. machineconfig/settings/yazi/keymap_linux.toml +94 -0
  189. machineconfig/settings/yazi/keymap_windows.toml +78 -0
  190. machineconfig/settings/yazi/shell/yazi_cd.ps1 +33 -0
  191. machineconfig/settings/yazi/shell/yazi_cd.sh +8 -0
  192. machineconfig/settings/yazi/theme.toml +4 -0
  193. machineconfig/settings/yazi/yazi_linux.toml +84 -0
  194. machineconfig/settings/yazi/yazi_windows.toml +58 -0
  195. machineconfig/setup_linux/__init__.py +2 -1
  196. machineconfig/setup_linux/web_shortcuts/interactive.sh +27 -12
  197. machineconfig/setup_linux/web_shortcuts/live_from_github.sh +31 -0
  198. machineconfig/setup_mac/__init__.py +2 -3
  199. machineconfig/setup_mac/apps_gui.sh +248 -0
  200. machineconfig/setup_windows/__init__.py +3 -3
  201. machineconfig/setup_windows/uv.ps1 +8 -1
  202. machineconfig/setup_windows/web_shortcuts/interactive.ps1 +26 -11
  203. machineconfig/setup_windows/web_shortcuts/live_from_github.ps1 +30 -0
  204. machineconfig/setup_windows/web_shortcuts/quick_init.ps1 +17 -0
  205. machineconfig/utils/accessories.py +7 -4
  206. machineconfig/utils/code.py +99 -32
  207. machineconfig/utils/files/ascii_art.py +1 -1
  208. machineconfig/utils/files/headers.py +3 -2
  209. machineconfig/utils/installer_utils/github_release_bulk.py +156 -119
  210. machineconfig/utils/installer_utils/install_from_url.py +183 -0
  211. machineconfig/utils/installer_utils/installer_class.py +42 -99
  212. machineconfig/utils/installer_utils/installer_cli.py +175 -0
  213. machineconfig/utils/installer_utils/installer_helper.py +129 -0
  214. machineconfig/utils/installer_utils/{installer_abc.py → installer_locator_utils.py} +36 -85
  215. machineconfig/utils/{installer.py → installer_utils/installer_runner.py} +16 -61
  216. machineconfig/utils/io.py +69 -1
  217. machineconfig/utils/links.py +56 -38
  218. machineconfig/utils/meta.py +33 -18
  219. machineconfig/utils/options.py +46 -18
  220. machineconfig/utils/options_tv.py +119 -0
  221. machineconfig/utils/path_extended.py +44 -95
  222. machineconfig/utils/path_helper.py +76 -23
  223. machineconfig/utils/procs.py +1 -1
  224. machineconfig/utils/scheduler.py +20 -53
  225. machineconfig/utils/scheduling.py +0 -2
  226. machineconfig/utils/schemas/fire_agents/fire_agents_input.py +1 -1
  227. machineconfig/utils/schemas/layouts/layout_types.py +1 -1
  228. machineconfig/utils/ssh.py +159 -412
  229. machineconfig/utils/ssh_utils/abc.py +5 -0
  230. machineconfig/utils/ssh_utils/copy_from_here.py +111 -0
  231. machineconfig/utils/ssh_utils/copy_to_here.py +302 -0
  232. machineconfig/utils/ssh_utils/utils.py +142 -0
  233. machineconfig/utils/ssh_utils/wsl.py +210 -0
  234. machineconfig/utils/terminal.py +1 -0
  235. machineconfig/utils/upgrade_packages.py +104 -28
  236. machineconfig/utils/ve.py +12 -4
  237. machineconfig-7.98.dist-info/METADATA +132 -0
  238. {machineconfig-6.82.dist-info → machineconfig-7.98.dist-info}/RECORD +259 -196
  239. {machineconfig-6.82.dist-info → machineconfig-7.98.dist-info}/entry_points.txt +4 -1
  240. machineconfig/jobs/installer/linux_scripts/pgsql.sh +0 -41
  241. machineconfig/jobs/installer/linux_scripts/timescaledb.sh +0 -71
  242. machineconfig/jobs/installer/powershell_scripts/archive_pygraphviz.ps1 +0 -12
  243. machineconfig/scripts/linux/fzf2g +0 -21
  244. machineconfig/scripts/linux/fzfag +0 -17
  245. machineconfig/scripts/linux/fzffg +0 -25
  246. machineconfig/scripts/linux/fzfrga +0 -21
  247. machineconfig/scripts/linux/mcfgs +0 -38
  248. machineconfig/scripts/linux/other/share_smb +0 -1
  249. machineconfig/scripts/linux/skrg +0 -4
  250. machineconfig/scripts/linux/warp-cli.sh +0 -122
  251. machineconfig/scripts/linux/z_ls +0 -104
  252. machineconfig/scripts/python/ai/command_runner/prompt.txt +0 -9
  253. machineconfig/scripts/python/helpers_fire/agentic_frameworks/fire_crush.py +0 -37
  254. machineconfig/scripts/python/helpers_fire/agentic_frameworks/fire_gemini.py +0 -44
  255. machineconfig/scripts/python/helpers_fire/agentic_frameworks/fire_qwen.py +0 -43
  256. machineconfig/scripts/python/helpers_fire/prompt.txt +0 -2
  257. machineconfig/scripts/python/helpers_fire/template.sh +0 -15
  258. machineconfig/scripts/python/helpers_repos/count_lines_frontend.py +0 -17
  259. machineconfig/scripts/python/helpers_repos/secure_repo.py +0 -15
  260. machineconfig/scripts/python/nw/add_ssh_key.py +0 -148
  261. machineconfig/scripts/windows/fzfb.ps1 +0 -3
  262. machineconfig/scripts/windows/fzfg.ps1 +0 -2
  263. machineconfig/scripts/windows/fzfrga.bat +0 -20
  264. machineconfig/scripts/windows/mcfgs.ps1 +0 -17
  265. machineconfig/settings/lf/linux/exe/fzf_nano.sh +0 -16
  266. machineconfig/settings/lf/windows/fzf_edit.ps1 +0 -6
  267. machineconfig/settings/lf/windows/tst.ps1 +0 -1
  268. machineconfig/settings/yazi/yazi.toml +0 -4
  269. machineconfig/setup_linux/apps.sh +0 -66
  270. machineconfig/setup_linux/others/cli_installation.sh +0 -137
  271. machineconfig/setup_mac/apps.sh +0 -73
  272. machineconfig/setup_windows/apps.ps1 +0 -62
  273. machineconfig/utils/installer_utils/installer.py +0 -225
  274. machineconfig-6.82.dist-info/METADATA +0 -82
  275. /machineconfig/jobs/installer/linux_scripts/{warp-cli.sh → cloudflare_warp_cli.sh} +0 -0
  276. /machineconfig/scripts/python/{helpers_fire → ai/utils}/__init__.py +0 -0
  277. /machineconfig/scripts/python/{helpers_fire/agentic_frameworks → helpers_agents}/__init__.py +0 -0
  278. /machineconfig/scripts/python/{nw → helpers_agents/agentic_frameworks}/__init__.py +0 -0
  279. /machineconfig/scripts/python/{helpers_fire → helpers_agents}/fire_agents_help_search.py +0 -0
  280. /machineconfig/scripts/python/{helpers_fire → helpers_agents}/fire_agents_load_balancer.py +0 -0
  281. /machineconfig/scripts/python/{helpers_fire → helpers_agents/templates}/template.ps1 +0 -0
  282. /machineconfig/{settings/shells/pwsh/profile.ps1 → scripts/python/helpers_fire_command/f.py} +0 -0
  283. /machineconfig/{settings/yazi/keymap.toml → scripts/python/helpers_network/__init__.py} +0 -0
  284. /machineconfig/scripts/python/{nw → helpers_network}/devops_add_identity.py +0 -0
  285. /machineconfig/scripts/python/{nw → helpers_network}/mount_drive +0 -0
  286. /machineconfig/scripts/python/{nw → helpers_network}/mount_nw_drive +0 -0
  287. /machineconfig/scripts/python/{nw → helpers_network}/mount_nw_drive.py +0 -0
  288. /machineconfig/scripts/python/{nw → helpers_network}/mount_smb +0 -0
  289. /machineconfig/scripts/python/{nw → helpers_network}/onetimeshare.py +0 -0
  290. /machineconfig/scripts/{Restore-ThunderbirdProfile.ps1 → windows/mounts/Restore-ThunderbirdProfile.ps1} +0 -0
  291. /machineconfig/{jobs/installer/powershell_scripts → setup_windows/ssh}/openssh-server_add_key.ps1 +0 -0
  292. /machineconfig/{jobs/installer/powershell_scripts → setup_windows/ssh}/openssh-server_copy-ssh-id.ps1 +0 -0
  293. {machineconfig-6.82.dist-info → machineconfig-7.98.dist-info}/WHEEL +0 -0
  294. {machineconfig-6.82.dist-info → machineconfig-7.98.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,204 @@
1
+ #!/usr/bin/env -S uv run --script
2
+ # /// script
3
+ # requires-python = ">=3.13"
4
+ # dependencies = [
5
+ # "machineconfig>=7.98",
6
+ # "textual",
7
+ # "pyperclip",
8
+ # ]
9
+ # ///
10
+
11
+
12
+
13
+ import os
14
+ import platform
15
+ from collections.abc import Mapping
16
+ from typing import Final
17
+
18
+ from rich.text import Text
19
+ from textual import on
20
+ from textual.app import App, ComposeResult
21
+ from textual.binding import Binding
22
+ from textual.containers import Horizontal, Vertical
23
+ from textual.widgets import Footer, Header, Label, ListItem, ListView, Static
24
+
25
+
26
+ VALUE_PREVIEW_LIMIT: Final[int] = 4096
27
+ SUMMARY_LIMIT: Final[int] = 96
28
+
29
+
30
+ def truncate_text(text: str, limit: int) -> tuple[str, int]:
31
+ length = len(text)
32
+ if length <= limit:
33
+ return text, 0
34
+ return text[:limit], length - limit
35
+
36
+
37
+ def format_summary(env_key: str, env_value: str, limit: int) -> str:
38
+ sanitized = env_value.replace("\n", "\\n").replace("\t", "\\t")
39
+ preview, remainder = truncate_text(sanitized, limit)
40
+ if preview == "":
41
+ base = f"{env_key} = <empty>"
42
+ else:
43
+ base = f"{env_key} = {preview}"
44
+ if remainder == 0:
45
+ return base
46
+ return f"{base}... (+{remainder} chars)"
47
+
48
+
49
+ def collect_environment(env: Mapping[str, str]) -> list[tuple[str, str]]:
50
+ return sorted(env.items(), key=lambda pair: pair[0].lower())
51
+
52
+
53
+ class EnvListItem(ListItem):
54
+ def __init__(self, env_key: str, summary: str) -> None:
55
+ super().__init__(Label(summary))
56
+ self._env_key = env_key
57
+
58
+ def env_key(self) -> str:
59
+ return self._env_key
60
+
61
+
62
+ class EnvValuePreview(Static):
63
+ def __init__(self, *args, **kwargs) -> None: # type: ignore[no-untyped-def]
64
+ super().__init__(*args, **kwargs)
65
+ self.border_title = "Environment Value"
66
+
67
+ def show_value(self, env_key: str, env_value: str) -> None:
68
+ preview, remainder = truncate_text(env_value, VALUE_PREVIEW_LIMIT)
69
+ text = Text()
70
+ text.append(f"{env_key}\n\n", style="bold cyan")
71
+ if preview == "":
72
+ text.append("<empty>", style="dim")
73
+ else:
74
+ text.append(preview)
75
+ if remainder > 0:
76
+ text.append(f"\n... truncated {remainder} characters", style="yellow")
77
+ self.update(text)
78
+
79
+
80
+ class StatusBar(Static):
81
+ def __init__(self, *args, **kwargs) -> None: # type: ignore[no-untyped-def]
82
+ super().__init__(*args, **kwargs)
83
+ self.border_title = "Status"
84
+
85
+ def show_message(self, message: str, level: str) -> None:
86
+ palette = {
87
+ "info": "cyan",
88
+ "success": "green",
89
+ "warning": "yellow",
90
+ "error": "red",
91
+ }
92
+ color = palette.get(level, "white")
93
+ self.update(f"[{color}]{message}[/{color}]")
94
+
95
+
96
+ class EnvExplorerApp(App[None]):
97
+ CSS = """
98
+ Screen { background: $surface; }
99
+ Header { background: $primary; color: $text; }
100
+ Footer { background: $panel; }
101
+ #main-container { height: 100%; }
102
+ #left-panel { width: 50%; height: 100%; border: solid $primary; padding: 1; }
103
+ #right-panel { width: 50%; height: 100%; border: solid $accent; padding: 1; }
104
+ ListView { height: 1fr; border: solid $accent; background: $surface; }
105
+ ListView > ListItem { padding: 0 1; }
106
+ EnvValuePreview { height: 1fr; border: solid $primary; background: $surface; padding: 1; overflow-y: auto; }
107
+ StatusBar { height: 3; border: solid $success; background: $surface; padding: 1; }
108
+ Label { padding: 0 1; height: auto; }
109
+ """
110
+
111
+ BINDINGS = [
112
+ Binding("q", "quit", "Quit", show=True),
113
+ Binding("r", "refresh", "Refresh", show=True),
114
+ Binding("c", "copy_entry", "Copy", show=True),
115
+ ]
116
+
117
+ def __init__(self) -> None:
118
+ super().__init__()
119
+ self._env_pairs: list[tuple[str, str]] = []
120
+ self._env_lookup: dict[str, str] = {}
121
+ self._selected_key: str = ""
122
+
123
+ def compose(self) -> ComposeResult:
124
+ platform_name = platform.system()
125
+ yield Header(show_clock=True)
126
+ with Horizontal(id="main-container"):
127
+ with Vertical(id="left-panel"):
128
+ yield Label(f"🌐 Environment Variables ({platform_name})")
129
+ yield ListView(id="env-list")
130
+ with Vertical(id="right-panel"):
131
+ yield EnvValuePreview(id="preview")
132
+ yield StatusBar(id="status")
133
+ yield Footer()
134
+
135
+ def on_mount(self) -> None:
136
+ self.title = "Environment Explorer"
137
+ self.sub_title = f"Platform: {platform.system()}"
138
+ self._reload_environment()
139
+ self._status().show_message("Ready. Select a variable to preview its value.", "info")
140
+
141
+ def _reload_environment(self) -> None:
142
+ self._env_pairs = collect_environment(os.environ)
143
+ self._env_lookup = dict(self._env_pairs)
144
+ self._populate_list()
145
+
146
+ def _populate_list(self) -> None:
147
+ list_view = self.query_one("#env-list", ListView)
148
+ list_view.clear()
149
+ for env_key, env_value in self._env_pairs:
150
+ summary = format_summary(env_key, env_value, SUMMARY_LIMIT)
151
+ list_view.append(EnvListItem(env_key, summary))
152
+ self._status().show_message(f"Loaded {len(self._env_pairs)} environment variables.", "success")
153
+
154
+ def _status(self) -> StatusBar:
155
+ return self.query_one("#status", StatusBar)
156
+
157
+ def _preview(self) -> EnvValuePreview:
158
+ return self.query_one("#preview", EnvValuePreview)
159
+
160
+ @on(ListView.Highlighted)
161
+ def handle_highlight(self, event: ListView.Highlighted) -> None:
162
+ if not isinstance(event.item, EnvListItem):
163
+ return
164
+ env_key = event.item.env_key()
165
+ env_value = self._env_lookup.get(env_key, "")
166
+ self._preview().show_value(env_key, env_value)
167
+ self._status().show_message(f"Previewing {env_key}", "info")
168
+
169
+ @on(ListView.Selected)
170
+ def handle_selection(self, event: ListView.Selected) -> None:
171
+ if not isinstance(event.item, EnvListItem):
172
+ return
173
+ env_key = event.item.env_key()
174
+ self._selected_key = env_key
175
+ env_value = self._env_lookup.get(env_key, "")
176
+ self._preview().show_value(env_key, env_value)
177
+ self._status().show_message(f"Selected {env_key}", "success")
178
+
179
+ def action_refresh(self) -> None:
180
+ self._reload_environment()
181
+ self._status().show_message("Environment reloaded.", "success")
182
+
183
+ def action_copy_entry(self) -> None:
184
+ if self._selected_key == "":
185
+ self._status().show_message("No variable selected.", "warning")
186
+ return
187
+ env_value = self._env_lookup.get(self._selected_key, "")
188
+ payload = f"{self._selected_key}={env_value}"
189
+ try:
190
+ import pyperclip # type: ignore[import]
191
+
192
+ pyperclip.copy(payload)
193
+ self._status().show_message(f"Copied {self._selected_key} to clipboard.", "success")
194
+ except ImportError:
195
+ self._status().show_message("pyperclip unavailable. Install it for clipboard support.", "warning")
196
+
197
+
198
+ def main() -> None:
199
+ app = EnvExplorerApp()
200
+ app.run()
201
+
202
+
203
+ if __name__ == "__main__":
204
+ main()
@@ -2,7 +2,7 @@
2
2
  # /// script
3
3
  # requires-python = ">=3.13"
4
4
  # dependencies = [
5
- # "machineconfig>=6.81",
5
+ # "machineconfig>=7.98",
6
6
  # "textual",
7
7
  # "pyperclip",
8
8
  # ]
@@ -7,43 +7,20 @@ fire
7
7
 
8
8
  """
9
9
 
10
- from machineconfig.utils.ve import get_ve_activate_line, get_ve_path_and_ipython_profile
11
- from machineconfig.utils.options import choose_from_options
12
- from machineconfig.utils.path_helper import match_file_name, sanitize_path
13
- from machineconfig.utils.path_extended import PathExtended
14
- from machineconfig.utils.accessories import get_repo_root, randstr
15
- from machineconfig.scripts.python.helpers_fire_command.fire_jobs_args_helper import FireJobArgs, extract_kwargs, parse_fire_args_from_context
16
-
17
- import platform
18
10
  from typing import Optional, Annotated
19
- from pathlib import Path
20
11
  import typer
21
12
 
22
13
 
23
- def route(args: FireJobArgs, fire_args: str = "") -> None:
24
- path_obj = sanitize_path(args.path)
25
- if not path_obj.exists():
26
- suffixes = {".py", ".sh", ".ps1"}
27
- choice_file = match_file_name(sub_string=args.path, search_root=PathExtended.cwd(), suffixes=suffixes)
28
- elif path_obj.is_dir():
29
- from machineconfig.scripts.python.helpers_fire.helpers4 import search_for_files_of_interest
30
- print(f"🔍 Searching recursively for Python, PowerShell and Shell scripts in directory `{path_obj}`")
31
- files = search_for_files_of_interest(path_obj)
32
- print(f"🔍 Got #{len(files)} results.")
33
- choice_file = choose_from_options(multi=False, options=files, fzf=True, msg="Choose one option")
34
- choice_file = PathExtended(choice_file)
35
- else:
36
- choice_file = path_obj
37
-
38
-
39
- repo_root = get_repo_root(Path(choice_file))
14
+ def route(args: "FireJobArgs", fire_args: str = "") -> None:
15
+ from pathlib import Path
16
+ from machineconfig.utils.path_helper import get_choice_file
17
+ from machineconfig.utils.accessories import get_repo_root, randstr
18
+ choice_file = get_choice_file(args.path, suffixes=None)
19
+ repo_root = get_repo_root(choice_file)
40
20
  print(f"💾 Selected file: {choice_file}.\nRepo root: {repo_root}")
41
- ve_root_from_file, ipy_profile = get_ve_path_and_ipython_profile(choice_file)
42
- if ipy_profile is None:
43
- ipy_profile = "default"
44
-
45
21
  if args.marimo:
46
- tmp_dir = PathExtended.tmp().joinpath(f"tmp_scripts/marimo/{choice_file.stem}_{randstr()}")
22
+ print(f"🧽 Preparing to launch Marimo notebook for `{choice_file}`...")
23
+ tmp_dir = Path.home().joinpath(f"tmp_results/tmp_scripts/marimo/{choice_file.stem}_{randstr()}")
47
24
  tmp_dir.mkdir(parents=True, exist_ok=True)
48
25
  script = f"""
49
26
  cd {tmp_dir}
@@ -57,81 +34,76 @@ uv run --project {repo_root} --with marimo marimo edit --host 0.0.0.0 marimo_nb.
57
34
 
58
35
  # ========================= preparing kwargs_dict
59
36
  if choice_file.suffix == ".py":
37
+ from machineconfig.scripts.python.helpers_fire_command.fire_jobs_args_helper import extract_kwargs
60
38
  kwargs_dict = extract_kwargs(args) # This now returns empty dict, but kept for compatibility
61
- ve_root = args.ve or ve_root_from_file
62
- if ve_root is None:
63
- raise ValueError(f"Could not determine virtual environment for file {choice_file}. Please ensure it is within a recognized project structure or specify the `--ve` option.")
64
- activate_ve_line = get_ve_activate_line(ve_root=ve_root)
65
39
  else:
66
- activate_ve_line = ""
67
40
  kwargs_dict = {}
68
41
 
69
-
70
42
  # ========================= choosing function to run
71
43
  choice_function: Optional[str] = None # Initialize to avoid unbound variable
72
44
  if args.choose_function:
73
45
  from machineconfig.scripts.python.helpers_fire_command.fire_jobs_route_helper import choose_function_or_lines
46
+
74
47
  choice_function, choice_file, kwargs_dict = choose_function_or_lines(choice_file, kwargs_dict)
75
48
  else:
76
49
  choice_function = args.function
77
50
 
78
51
  if choice_file.suffix == ".py":
79
- from machineconfig.scripts.python.helpers_fire_command.fire_jobs_route_helper import get_command_streamlit
80
- if args.streamlit: exe = get_command_streamlit(choice_file, args.environment, repo_root)
81
- elif args.interactive is False: exe = "python"
82
- elif args.jupyter: exe = "jupyter-lab"
83
- else: exe = f"ipython -i --no-banner --profile {ipy_profile} "
84
- elif choice_file.suffix == ".ps1" or choice_file.suffix == ".sh": exe = "."
85
- elif choice_file.suffix == "": exe = ""
86
- else: raise NotImplementedError(f"File type {choice_file.suffix} not supported, in the sense that I don't know how to fire it.")
52
+ with_project = f"--project {repo_root} " if repo_root is not None else ""
53
+ if args.streamlit:
54
+ from machineconfig.scripts.python.helpers_fire_command.fire_jobs_route_helper import get_command_streamlit
55
+ exe = get_command_streamlit(choice_file=choice_file, environment=args.environment, repo_root=repo_root)
56
+ exe = f"uv run {with_project} {exe} "
57
+ elif args.jupyter:
58
+ exe = f"uv run {with_project} jupyter-lab"
59
+ else:
60
+ if args.interactive:
61
+ from machineconfig.utils.ve import get_ve_path_and_ipython_profile
62
+ _ve_root_from_file, ipy_profile = get_ve_path_and_ipython_profile(init_path=choice_file)
63
+ if ipy_profile is None:
64
+ ipy_profile = "default"
65
+ exe = f"uv run {with_project} ipython -i --no-banner --profile {ipy_profile} "
66
+ else:
67
+ exe = f"uv run {with_project} python "
68
+ elif choice_file.suffix == ".ps1" or choice_file.suffix == ".sh":
69
+ exe = "."
70
+ elif choice_file.suffix == "":
71
+ exe = ""
72
+ else:
73
+ raise NotImplementedError(f"File type {choice_file.suffix} not supported, in the sense that I don't know how to fire it.")
87
74
 
88
- if args.module or (args.debug and args.choose_function): # because debugging tools do not support choosing functions and don't interplay with fire module. So the only way to have debugging and choose function options is to import the file as a module into a new script and run the function of interest there and debug the new script.
75
+ if args.module or (args.debug and args.choose_function):
76
+ # because debugging tools do not support choosing functions and don't interplay with fire module. So the only way to have debugging and choose function options is to import the file as a module into a new script and run the function of interest there and debug the new script.
89
77
  assert choice_file.suffix == ".py", f"File must be a python file to be imported as a module. Got {choice_file}"
90
- from machineconfig.scripts.python.helpers_fire.helpers4 import get_import_module_code
91
- import_line = get_import_module_code(str(choice_file))
92
- if repo_root is not None:
93
- repo_root_add = f"""sys.path.append(r'{repo_root}')"""
94
- else:
95
- repo_root_add = ""
96
- txt: str = f"""
97
- try:
98
- {import_line}
99
- except (ImportError, ModuleNotFoundError) as ex:
100
- print(fr"❌ Failed to import `{choice_file}` as a module: {{ex}} ")
101
- print(fr"⚠️ Attempting import with ad-hoc `$PATH` manipulation. DO NOT pickle any objects in this session as correct deserialization cannot be guaranteed.")
102
- import sys
103
- sys.path.append(r'{PathExtended(choice_file).parent}')
104
- {repo_root_add}
105
- from {PathExtended(choice_file).stem} import *
106
- print(fr"✅ Successfully imported `{choice_file}`")
107
- """
108
- if choice_function is not None:
109
- txt = (
110
- txt
111
- + f"""
112
- res = {choice_function}({("**" + str(kwargs_dict)) if kwargs_dict else ""})
113
- """
114
- )
78
+ from machineconfig.scripts.python.helpers_fire_command.file_wrangler import get_import_module_code, wrap_import_in_try_except
79
+ from machineconfig.utils.meta import lambda_to_python_script
80
+ from machineconfig.utils.code import print_code
115
81
 
116
- txt = (
117
- f"""
118
- try:
119
- from rich.panel import Panel
120
- from rich.console import Console
121
- from rich.syntax import Syntax
122
- console = Console()
123
- console.print(Panel(Syntax(code=r'''{txt}''', lexer='python'), title='Import Script'), style="bold red")
124
- except ImportError as _ex:
125
- print(r'''{txt}''')
126
- """
127
- + txt
82
+ import_code = get_import_module_code(str(choice_file))
83
+ import_code_robust = lambda_to_python_script(
84
+ lambda: wrap_import_in_try_except(
85
+ import_line=import_code, pyfile=str(choice_file), repo_root=str(repo_root) if repo_root is not None else None
86
+ ),
87
+ in_global=True,
88
+ import_module=False,
89
+ )
90
+ # print(f"🧩 Preparing import code for module import:\n{import_code}")
91
+ code_printing = lambda_to_python_script(
92
+ lambda: print_code(code=import_code_robust, lexer="python", desc="import as module code"),
93
+ in_global=True, import_module=False
128
94
  )
129
- choice_file = PathExtended.tmp().joinpath(f"tmp_scripts/python/{PathExtended(choice_file).parent.name}_{PathExtended(choice_file).stem}_{randstr()}.py")
95
+ print(f"🧩 Preparing import code for module import:\n{import_code}")
96
+ if choice_function is not None:
97
+ calling = f"""res = {choice_function}({("**" + str(kwargs_dict)) if kwargs_dict else ""})"""
98
+ else:
99
+ calling = """# No function selected to call. You can add your code here."""
100
+ choice_file = Path.home().joinpath(f"tmp_results/tmp_scripts/python/{Path(choice_file).parent.name}_{Path(choice_file).stem}_{randstr()}.py")
130
101
  choice_file.parent.mkdir(parents=True, exist_ok=True)
131
- choice_file.write_text(txt, encoding="utf-8")
102
+ choice_file.write_text(import_code_robust + "\n" + code_printing + "\n" + calling, encoding="utf-8")
132
103
 
133
104
  # ========================= determining basic command structure: putting together exe & choice_file & choice_function & pdb
134
105
  if args.debug:
106
+ import platform
135
107
  if platform.system() == "Windows":
136
108
  command = f"{exe} -m ipdb {choice_file} " # pudb is not available on windows machines, use poor man's debugger instead.
137
109
  elif platform.system() in ["Linux", "Darwin"]:
@@ -148,71 +120,66 @@ except ImportError as _ex:
148
120
  if args.holdDirectory:
149
121
  command = f"{exe} {choice_file}"
150
122
  else:
151
- command = f"cd {choice_file.parent}\n{exe} {choice_file.name}\ncd {PathExtended.cwd()}"
152
-
123
+ command = f"cd {choice_file.parent}\n{exe} {choice_file.name}\ncd {Path.cwd()}"
153
124
  elif args.cmd:
154
125
  command = rf""" cd /d {choice_file.parent} & {exe} {choice_file.name} """
155
126
  else:
156
- if choice_file.suffix == "": command = f"{exe} {choice_file} {fire_args}"
157
- else: command = f"{exe} {choice_file} "
127
+ if choice_file.suffix == "":
128
+ command = f"{exe} {choice_file} {fire_args}"
129
+ else:
130
+ command = f"{exe} {choice_file} "
158
131
 
159
- if not args.cmd: command = f"{activate_ve_line}\n{command}"
132
+ if not args.cmd:
133
+ pass
160
134
  else:
161
135
  new_line = "\n"
162
- command = rf"""start cmd -Argument "/k {activate_ve_line.replace(".ps1", ".bat").replace(". ", "")} & {command.replace(new_line, " & ")} " """ # this works from powershell
136
+ command = rf"""start cmd -Argument "/k {command.replace(new_line, " & ")} " """ # this works from powershell
163
137
  if args.submit_to_cloud:
164
- command = f"""
165
- {activate_ve_line}
166
- python -m machineconfig.cluster.templates.cli_click --file {choice_file} """
138
+ command = f"""uv run python -m machineconfig.cluster.templates.cli_click --file {choice_file} """
167
139
  if choice_function is not None:
168
140
  command += f"--function {choice_function} "
169
141
 
170
142
  if args.optimized:
171
143
  command = command.replace("python ", "python -OO ")
144
+
172
145
  from rich.panel import Panel
173
146
  from rich.console import Console
174
147
  from rich.syntax import Syntax
148
+
175
149
  console = Console()
176
150
  if args.zellij_tab is not None:
177
- comman_path__ = PathExtended.tmpfile(suffix=".sh")
151
+ comman_path__ = Path.home().joinpath(f"tmp_results/tmp_scripts/zellij_commands/{choice_file.stem}_{randstr()}.sh")
178
152
  comman_path__.parent.mkdir(parents=True, exist_ok=True)
179
153
  comman_path__.write_text(command, encoding="utf-8")
180
154
  console.print(Panel(Syntax(command, lexer="shell"), title=f"🔥 fire command @ {comman_path__}: "), style="bold red")
181
155
  import subprocess
156
+
182
157
  existing_tab_names = subprocess.run(["zellij", "action", "query-tab-names"], capture_output=True, text=True, check=True).stdout.splitlines()
183
158
  if args.zellij_tab in existing_tab_names:
184
159
  print(f"⚠️ Tab name `{args.zellij_tab}` already exists. Please choose a different name.")
185
160
  args.zellij_tab += f"_{randstr(3)}"
186
161
  from machineconfig.cluster.sessions_managers.zellij_local import run_command_in_zellij_tab
162
+
187
163
  command = run_command_in_zellij_tab(command=str(comman_path__), tab_name=args.zellij_tab, cwd=None)
188
164
  if args.watch:
189
165
  command = "watchexec --restart --exts py,sh,ps1 " + command
190
166
  if args.git_pull:
191
167
  command = f"\ngit -C {choice_file.parent} pull\n" + command
192
168
  if args.PathExport:
193
- if platform.system() in ["Linux", "Darwin"]:
194
- export_line = f"""export PYTHONPATH="{repo_root}""" + """:${PYTHONPATH}" """
195
- elif platform.system() == "Windows":
196
- export_line = f"""$env:PYTHONPATH="{repo_root}""" + """:$env:PYTHONPATH" """
197
- else:
198
- raise NotImplementedError(f"Platform {platform.system()} not supported.")
169
+ from machineconfig.scripts.python.helpers_fire_command.file_wrangler import add_to_path
170
+
171
+ export_line = add_to_path(path_variable="PYTHONPATH", directory=str(repo_root))
199
172
  command = export_line + "\n" + command
200
173
  if args.loop:
174
+ import platform
201
175
  if platform.system() in ["Linux", "Darwin"]:
202
176
  command = command + "\nsleep 0.5"
203
177
  elif platform.system() == "Windows":
204
178
  command = "$ErrorActionPreference = 'SilentlyContinue';\n" + command + "\nStart-Sleep -Seconds 0.5"
205
179
  else:
206
180
  raise NotImplementedError(f"Platform {platform.system()} not supported.")
207
- import os
208
- op_program_path = os.environ.get("OP_PROGRAM_PATH", None)
209
- if op_program_path is not None:
210
- op_program_path = PathExtended(op_program_path)
211
- op_program_path.parent.mkdir(parents=True, exist_ok=True)
212
- op_program_path.write_text(command, encoding="utf-8")
213
- else:
214
- from machineconfig.utils.code import run_shell_script
215
- run_shell_script(command)
181
+ from machineconfig.utils.code import exit_then_run_shell_script
182
+ exit_then_run_shell_script(script=command, strict=False)
216
183
 
217
184
 
218
185
  def fire(
@@ -230,21 +197,21 @@ def fire(
230
197
  module: Annotated[bool, typer.Option("--module", "-m", help="Launch the main file")] = False,
231
198
  optimized: Annotated[bool, typer.Option("--optimized", "-O", help="Run the optimized version of the function")] = False,
232
199
  zellij_tab: Annotated[Optional[str], typer.Option("--zellij-tab", "-z", help="Open in a new zellij tab")] = None,
233
-
234
200
  submit_to_cloud: Annotated[bool, typer.Option("--submit-to-cloud", "-C", help="Submit to cloud compute")] = False,
235
201
  remote: Annotated[bool, typer.Option("--remote", "-r", help="Launch on a remote machine")] = False,
236
-
237
202
  streamlit: Annotated[bool, typer.Option("--streamlit", "-S", help="Run as streamlit app")] = False,
238
203
  environment: Annotated[str, typer.Option("--environment", "-E", help="Choose ip, localhost, hostname or arbitrary url")] = "",
239
- holdDirectory: Annotated[bool, typer.Option("--holdDirectory", "-D", help="Hold current directory and avoid cd'ing to the script directory")] = False,
204
+ holdDirectory: Annotated[
205
+ bool, typer.Option("--holdDirectory", "-D", help="Hold current directory and avoid cd'ing to the script directory")
206
+ ] = False,
240
207
  PathExport: Annotated[bool, typer.Option("--PathExport", "-P", help="Augment the PYTHONPATH with repo root")] = False,
241
-
242
208
  git_pull: Annotated[bool, typer.Option("--git-pull", "-g", help="Start by pulling the git repo")] = False,
243
209
  watch: Annotated[bool, typer.Option("--watch", "-w", help="Watch the file for changes")] = False,
244
210
  ) -> None:
245
211
  """Main function to process fire jobs arguments."""
246
212
 
247
213
  # Get Fire arguments from context
214
+ from machineconfig.scripts.python.helpers_fire_command.fire_jobs_args_helper import FireJobArgs, parse_fire_args_from_context
248
215
  fire_args = parse_fire_args_from_context(ctx)
249
216
 
250
217
  args = FireJobArgs(
@@ -278,12 +245,14 @@ def fire(
278
245
  except Exception as e:
279
246
  # For other exceptions, print clean error message and exit
280
247
  import sys
248
+
281
249
  print(f"❌ Error: {e}", file=sys.stderr)
282
250
  sys.exit(1)
283
251
 
284
252
 
285
253
  def get_app():
286
254
  from typer import Typer
255
+
287
256
  app = Typer(add_completion=False)
288
257
  app.command(context_settings={"allow_extra_args": True, "allow_interspersed_args": False})(fire)
289
258
  return app
@@ -295,4 +264,4 @@ def main():
295
264
 
296
265
 
297
266
  if __name__ == "__main__":
298
- pass
267
+ from machineconfig.scripts.python.helpers_fire_command.fire_jobs_args_helper import FireJobArgs
@@ -6,17 +6,7 @@ Currently, the only way to work around this is to predifine the host in ~/.ssh/c
6
6
  """
7
7
 
8
8
  import typer
9
- from typing_extensions import Annotated
10
- from rich.console import Console
11
- from rich.panel import Panel
12
-
13
- from machineconfig.utils.ssh import SSH
14
- from machineconfig.utils.path_extended import PathExtended
15
- from machineconfig.scripts.python.helpers_cloud.helpers2 import ES
16
- from machineconfig.utils.accessories import pprint
17
-
18
-
19
- console = Console()
9
+ from typing import Annotated
20
10
 
21
11
 
22
12
  def ftpx(
@@ -25,7 +15,41 @@ def ftpx(
25
15
  recursive: Annotated[bool, typer.Option("--recursive", "-r", help="Send recursively.")] = False,
26
16
  zipFirst: Annotated[bool, typer.Option("--zipFirst", "-z", help="Zip before sending.")] = False,
27
17
  cloud: Annotated[bool, typer.Option("--cloud", "-c", help="Transfer through the cloud.")] = False,
18
+ overwrite_existing: Annotated[bool, typer.Option("--overwrite-existing", "-o", help="Overwrite existing files on remote when sending from local to remote.")] = False,
28
19
  ) -> None:
20
+ from pathlib import Path
21
+ if target == "wsl" or source == "wsl":
22
+ from machineconfig.utils.ssh_utils.wsl import copy_when_inside_windows
23
+ if target == "wsl":
24
+ target_obj = Path(source).expanduser().absolute().relative_to(Path.home())
25
+ source_obj = target_obj
26
+ else:
27
+ source_obj = Path(target).expanduser().absolute().relative_to(Path.home())
28
+ target_obj = source_obj
29
+ copy_when_inside_windows(source_obj, target_obj, overwrite_existing)
30
+ return
31
+ elif source == "win" or target == "win":
32
+ if source == "win":
33
+ source_obj = Path(target).expanduser().absolute().relative_to(Path.home())
34
+ target_obj = source_obj
35
+ else:
36
+ target_obj = Path(source).expanduser().absolute().relative_to(Path.home())
37
+ source_obj = target_obj
38
+ from machineconfig.utils.ssh_utils.wsl import copy_when_inside_wsl
39
+ copy_when_inside_wsl(source_obj, target_obj, overwrite_existing)
40
+ return
41
+
42
+ from rich.console import Console
43
+ from rich.panel import Panel
44
+
45
+ from machineconfig.utils.ssh import SSH
46
+ from machineconfig.utils.path_extended import PathExtended
47
+ from machineconfig.scripts.python.helpers_cloud.helpers2 import ES
48
+ from machineconfig.utils.accessories import pprint
49
+
50
+
51
+ console = Console()
52
+
29
53
  console.print(
30
54
  Panel(
31
55
  "\n".join(
@@ -133,7 +157,7 @@ def ftpx(
133
157
  border_style="cyan",
134
158
  )
135
159
  )
136
- ssh.run_shell(command=f"cloud_copy {resolved_source} :^", verbose_output=True, description="Uploading from remote to the cloud.", strict_stderr=False, strict_return_code=False)
160
+ ssh.run_shell_cmd_on_remote(command=f"cloud_copy {resolved_source} :^", verbose_output=True, description="Uploading from remote to the cloud.", strict_stderr=False, strict_return_code=False)
137
161
  console.print(
138
162
  Panel.fit(
139
163
  "⬇️ Cloud transfer mode — downloading from cloud to local...",
@@ -141,12 +165,14 @@ def ftpx(
141
165
  border_style="cyan",
142
166
  )
143
167
  )
144
- ssh.run_locally(command=f"cloud_copy :^ {resolved_target}")
168
+ ssh.run_shell_cmd_on_local(command=f"cloud_copy :^ {resolved_target}")
145
169
  received_file = PathExtended(resolved_target) # type: ignore
146
170
  else:
147
171
  if source_is_remote:
148
- assert resolved_source is not None, """
149
- ❌ Path Error: Source must be a remote path (machine:path)"""
172
+ if resolved_source is None:
173
+ typer.echo("""❌ Path Error: Source must be a remote path (machine:path)""")
174
+ typer.Exit(code=1)
175
+ return
150
176
  target_display = resolved_target or "<auto>"
151
177
  console.print(
152
178
  Panel(
@@ -183,7 +209,7 @@ def ftpx(
183
209
  padding=(1, 2),
184
210
  )
185
211
  )
186
- received_file = ssh.copy_from_here(source_path=resolved_source, target_rel2home=resolved_target, compress_with_zip=zipFirst, recursive=recursive, overwrite_existing=False)
212
+ received_file = ssh.copy_from_here(source_path=resolved_source, target_rel2home=resolved_target, compress_with_zip=zipFirst, recursive=recursive, overwrite_existing=overwrite_existing)
187
213
 
188
214
  if source_is_remote and isinstance(received_file, PathExtended):
189
215
  console.print(