machineconfig 6.82__py3-none-any.whl → 8.51__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (461) hide show
  1. machineconfig/cluster/remote/cloud_manager.py +1 -1
  2. machineconfig/cluster/remote/run_cluster.py +1 -1
  3. machineconfig/cluster/remote/run_remote.py +1 -1
  4. machineconfig/cluster/sessions_managers/utils/maker.py +29 -15
  5. machineconfig/cluster/sessions_managers/wt_local.py +17 -222
  6. machineconfig/cluster/sessions_managers/wt_local_manager.py +56 -194
  7. machineconfig/cluster/sessions_managers/wt_remote_manager.py +42 -198
  8. machineconfig/cluster/sessions_managers/wt_utils/manager_persistence.py +52 -0
  9. machineconfig/cluster/sessions_managers/wt_utils/monitoring_helpers.py +50 -0
  10. machineconfig/cluster/sessions_managers/wt_utils/status_reporting.py +76 -0
  11. machineconfig/cluster/sessions_managers/wt_utils/wt_helpers.py +199 -0
  12. machineconfig/cluster/sessions_managers/zellij_local.py +1 -1
  13. machineconfig/cluster/sessions_managers/zellij_local_manager.py +4 -2
  14. machineconfig/cluster/sessions_managers/zellij_remote_manager.py +3 -2
  15. machineconfig/cluster/sessions_managers/zellij_utils/process_monitor.py +2 -2
  16. machineconfig/jobs/installer/checks/check_installations.py +133 -0
  17. machineconfig/jobs/installer/checks/install_utils.py +132 -0
  18. machineconfig/jobs/installer/checks/report_utils.py +39 -0
  19. machineconfig/jobs/installer/checks/vt_utils.py +89 -0
  20. machineconfig/jobs/installer/installer_data.json +1500 -310
  21. machineconfig/jobs/installer/linux_scripts/docker.sh +6 -9
  22. machineconfig/jobs/installer/linux_scripts/q.sh +10 -7
  23. machineconfig/jobs/installer/linux_scripts/redis.sh +1 -0
  24. machineconfig/jobs/installer/package_groups.py +62 -91
  25. machineconfig/jobs/installer/powershell_scripts/install_fonts.ps1 +129 -34
  26. machineconfig/jobs/installer/{custom → python_scripts}/boxes.py +2 -3
  27. machineconfig/jobs/installer/{custom_dev → python_scripts}/brave.py +5 -3
  28. machineconfig/jobs/installer/python_scripts/cloudflare_warp_cli.py +23 -0
  29. machineconfig/jobs/installer/{custom_dev → python_scripts}/code.py +14 -9
  30. machineconfig/jobs/installer/{custom_dev → python_scripts}/dubdb_adbc.py +1 -1
  31. machineconfig/jobs/installer/python_scripts/hx.py +214 -0
  32. machineconfig/jobs/installer/{custom_dev → python_scripts}/nerdfont.py +2 -2
  33. machineconfig/jobs/installer/{custom_dev → python_scripts}/nerfont_windows_helper.py +32 -26
  34. machineconfig/jobs/installer/python_scripts/sysabc.py +145 -0
  35. machineconfig/jobs/installer/{custom_dev → python_scripts}/wezterm.py +2 -19
  36. machineconfig/jobs/installer/{custom_dev → python_scripts}/winget.py +10 -14
  37. machineconfig/jobs/installer/python_scripts/yazi.py +139 -0
  38. machineconfig/{scripts/python/nw → jobs/scripts/bash_scripts}/mount_nfs +0 -1
  39. machineconfig/jobs/scripts/powershell_scripts/cmatrix.ps1 +52 -0
  40. machineconfig/jobs/scripts/powershell_scripts/mount_ssh.ps1 +13 -0
  41. machineconfig/jobs/scripts/powershell_scripts/obs.ps1 +4 -0
  42. machineconfig/jobs/scripts_dynamic/a.py +428 -0
  43. machineconfig/logger.py +1 -2
  44. machineconfig/profile/create_helper.py +56 -18
  45. machineconfig/profile/create_links.py +79 -21
  46. machineconfig/profile/create_links_export.py +87 -36
  47. machineconfig/profile/create_shell_profile.py +92 -127
  48. machineconfig/profile/mapper_data.toml +45 -0
  49. machineconfig/profile/mapper_dotfiles.toml +249 -0
  50. machineconfig/scripts/__init__.py +0 -4
  51. machineconfig/scripts/linux/wrap_mcfg +46 -0
  52. machineconfig/scripts/nu/wrap_mcfg.nu +69 -0
  53. machineconfig/scripts/python/agents.py +85 -165
  54. machineconfig/scripts/python/ai/initai.py +4 -2
  55. machineconfig/scripts/python/ai/scripts/__init__.py +1 -0
  56. machineconfig/scripts/python/ai/scripts/command_runner.ps1 +33 -0
  57. machineconfig/scripts/python/ai/{command_runner → scripts}/command_runner.sh +1 -1
  58. machineconfig/scripts/python/ai/scripts/lint_and_type_check.ps1 +2 -0
  59. machineconfig/scripts/python/ai/scripts/lint_and_type_check.sh +8 -6
  60. machineconfig/scripts/python/ai/solutions/claude/claude.py +1 -1
  61. machineconfig/scripts/python/ai/solutions/cline/cline.py +1 -1
  62. machineconfig/scripts/python/ai/solutions/copilot/{chatmodes/Thinking-Beast-Mode.chatmode.md → agents/Thinking-Beast-Mode.agent.md} +0 -1
  63. machineconfig/scripts/python/ai/solutions/copilot/{chatmodes/Ultimate-Transparent-Thinking-Beast-Mode.chatmode.md → agents/Ultimate-Transparent-Thinking-Beast-Mode.agent.md} +0 -1
  64. machineconfig/scripts/python/ai/solutions/copilot/{chatmodes/deepResearch.chatmode.md → agents/deepResearch.agent.md} +2 -2
  65. machineconfig/scripts/python/ai/solutions/copilot/github_copilot.py +6 -6
  66. machineconfig/scripts/python/ai/solutions/copilot/instructions/python/dev.instructions.md +33 -0
  67. machineconfig/scripts/python/ai/solutions/copilot/instructions/python/watch_exec.prompt.md +20 -0
  68. machineconfig/scripts/python/ai/solutions/crush/crush.py +1 -1
  69. machineconfig/scripts/python/ai/solutions/cursor/cursors.py +1 -1
  70. machineconfig/scripts/python/ai/solutions/gemini/gemini.py +1 -1
  71. machineconfig/scripts/python/ai/solutions/gemini/settings.json +3 -0
  72. machineconfig/scripts/python/ai/{generate_files.py → utils/generate_files.py} +2 -2
  73. machineconfig/scripts/python/ai/{solutions → utils}/generic.py +2 -15
  74. machineconfig/scripts/python/ai/{vscode_tasks.py → utils/vscode_tasks.py} +13 -5
  75. machineconfig/scripts/python/cloud.py +58 -11
  76. machineconfig/scripts/python/croshell.py +10 -162
  77. machineconfig/scripts/python/devops.py +73 -36
  78. machineconfig/scripts/python/devops_navigator.py +16 -6
  79. machineconfig/scripts/python/fire_jobs.py +8 -222
  80. machineconfig/scripts/python/ftpx.py +7 -200
  81. machineconfig/scripts/python/graph/cli_graph.json +8743 -0
  82. machineconfig/scripts/python/{env_manager → helper_env}/path_manager_tui.py +2 -2
  83. machineconfig/scripts/python/helpers/helper_env/env_manager_tui.py +204 -0
  84. machineconfig/scripts/python/helpers/helper_env/path_manager_tui.py +228 -0
  85. machineconfig/scripts/python/{helpers_fire → helpers/helpers_agents}/agentic_frameworks/fire_crush.json +1 -1
  86. machineconfig/scripts/python/helpers/helpers_agents/agentic_frameworks/fire_crush.py +39 -0
  87. machineconfig/scripts/python/{helpers_fire → helpers/helpers_agents}/agentic_frameworks/fire_cursor_agents.py +3 -4
  88. machineconfig/scripts/python/helpers/helpers_agents/agentic_frameworks/fire_gemini.py +55 -0
  89. machineconfig/scripts/python/helpers/helpers_agents/agentic_frameworks/fire_qwen.py +30 -0
  90. machineconfig/scripts/python/helpers/helpers_agents/agents_impl.py +168 -0
  91. machineconfig/scripts/python/{helpers_fire → helpers/helpers_agents}/fire_agents_help_launch.py +38 -16
  92. machineconfig/scripts/python/{helpers_fire → helpers/helpers_agents}/fire_agents_helper_types.py +11 -14
  93. machineconfig/scripts/python/helpers/helpers_agents/privacy/configs/aichat/config.yaml +5 -0
  94. machineconfig/scripts/python/helpers/helpers_agents/privacy/configs/aider/.aider.conf.yml +2 -0
  95. machineconfig/scripts/python/helpers/helpers_agents/privacy/configs/copilot/config.yml +1 -0
  96. machineconfig/scripts/python/helpers/helpers_agents/privacy/configs/crush/crush.json +10 -0
  97. machineconfig/scripts/python/helpers/helpers_agents/privacy/configs/gemini/settings.json +12 -0
  98. machineconfig/scripts/python/helpers/helpers_agents/privacy/privacy.py +109 -0
  99. machineconfig/scripts/python/helpers/helpers_agents/templates/prompt.txt +10 -0
  100. machineconfig/scripts/python/helpers/helpers_agents/templates/template.sh +34 -0
  101. machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/cloud_copy.py +32 -25
  102. machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/cloud_mount.py +29 -22
  103. machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/cloud_sync.py +9 -8
  104. machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/helpers2.py +1 -1
  105. machineconfig/scripts/python/{helpers_croshell → helpers/helpers_croshell}/crosh.py +3 -3
  106. machineconfig/scripts/python/helpers/helpers_croshell/croshell_impl.py +225 -0
  107. machineconfig/scripts/python/{helpers_croshell → helpers/helpers_croshell}/scheduler.py +4 -4
  108. machineconfig/scripts/python/{helpers_croshell → helpers/helpers_croshell}/start_slidev.py +12 -12
  109. machineconfig/scripts/python/helpers/helpers_devops/backup_config.py +149 -0
  110. machineconfig/scripts/python/helpers/helpers_devops/cli_backup_retrieve.py +262 -0
  111. machineconfig/scripts/python/helpers/helpers_devops/cli_config.py +98 -0
  112. machineconfig/scripts/python/helpers/helpers_devops/cli_config_dotfile.py +274 -0
  113. machineconfig/scripts/python/helpers/helpers_devops/cli_data.py +67 -0
  114. machineconfig/scripts/python/helpers/helpers_devops/cli_nw.py +201 -0
  115. machineconfig/scripts/python/helpers/helpers_devops/cli_repos.py +274 -0
  116. machineconfig/scripts/python/helpers/helpers_devops/cli_self.py +197 -0
  117. machineconfig/scripts/python/helpers/helpers_devops/cli_share_file.py +151 -0
  118. machineconfig/scripts/python/helpers/helpers_devops/cli_share_server.py +125 -0
  119. machineconfig/scripts/python/{helpers_devops/cli_terminal.py → helpers/helpers_devops/cli_share_terminal.py} +26 -22
  120. machineconfig/scripts/python/helpers/helpers_devops/cli_ssh.py +167 -0
  121. machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/devops_status.py +17 -23
  122. machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/devops_update_repos.py +1 -1
  123. machineconfig/scripts/python/{interactive.py → helpers/helpers_devops/interactive.py} +78 -71
  124. machineconfig/scripts/python/helpers/helpers_devops/run_script.py +197 -0
  125. machineconfig/scripts/python/helpers/helpers_devops/themes/choose_starship_theme.ps1 +41 -0
  126. machineconfig/scripts/python/helpers/helpers_devops/themes/choose_starship_theme.sh +48 -0
  127. machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/themes/choose_wezterm_theme.py +4 -4
  128. machineconfig/scripts/python/{helpers_fire/helpers4.py → helpers/helpers_fire_command/file_wrangler.py} +57 -20
  129. machineconfig/scripts/python/{helpers_fire_command → helpers/helpers_fire_command}/fire_jobs_args_helper.py +1 -0
  130. machineconfig/scripts/python/helpers/helpers_fire_command/fire_jobs_impl.py +233 -0
  131. machineconfig/scripts/python/{helpers_fire_command → helpers/helpers_fire_command}/fire_jobs_route_helper.py +26 -16
  132. machineconfig/scripts/python/helpers/helpers_msearch/__init__.py +5 -0
  133. machineconfig/scripts/python/helpers/helpers_msearch/msearch_impl.py +248 -0
  134. machineconfig/scripts/{linux → python/helpers/helpers_msearch/scripts_linux}/fzfg +6 -5
  135. machineconfig/scripts/python/helpers/helpers_msearch/scripts_linux/search_with_context.sh +48 -0
  136. machineconfig/scripts/python/helpers/helpers_msearch/scripts_windows/fzfg.ps1 +59 -0
  137. machineconfig/scripts/python/helpers/helpers_navigator/__init__.py +20 -0
  138. machineconfig/scripts/python/helpers/helpers_navigator/cli_graph_loader.py +234 -0
  139. machineconfig/scripts/python/{helpers_navigator → helpers/helpers_navigator}/command_builder.py +61 -13
  140. machineconfig/scripts/python/helpers/helpers_navigator/command_detail.py +153 -0
  141. machineconfig/scripts/python/helpers/helpers_navigator/command_tree.py +45 -0
  142. machineconfig/scripts/python/{helpers_navigator → helpers/helpers_navigator}/data_models.py +18 -11
  143. machineconfig/scripts/python/{helpers_navigator → helpers/helpers_navigator}/main_app.py +5 -5
  144. machineconfig/scripts/python/helpers/helpers_network/address.py +174 -0
  145. machineconfig/scripts/python/helpers/helpers_network/address_switch.py +78 -0
  146. machineconfig/scripts/python/helpers/helpers_network/ftpx_impl.py +276 -0
  147. machineconfig/scripts/python/{nw → helpers/helpers_network}/mount_nfs.py +2 -2
  148. machineconfig/scripts/python/{nw → helpers/helpers_network}/mount_ssh.py +3 -3
  149. machineconfig/scripts/python/helpers/helpers_network/ssh_add_identity.py +73 -0
  150. machineconfig/scripts/python/helpers/helpers_network/ssh_add_ssh_key.py +175 -0
  151. machineconfig/scripts/python/helpers/helpers_network/ssh_debug_linux.py +319 -0
  152. machineconfig/scripts/python/helpers/helpers_network/ssh_debug_windows.py +275 -0
  153. machineconfig/scripts/python/{nw → helpers/helpers_network}/wifi_conn.py +1 -53
  154. machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/action.py +3 -3
  155. machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/action_helper.py +3 -3
  156. machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/clone.py +0 -1
  157. machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/cloud_repo_sync.py +159 -48
  158. machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/grource.py +4 -3
  159. machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/record.py +33 -12
  160. machineconfig/scripts/python/helpers/helpers_repos/repo_analyzer_1.py +160 -0
  161. machineconfig/scripts/python/{helpers_repos/count_lines.py → helpers/helpers_repos/repo_analyzer_2.py} +156 -191
  162. machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/update.py +0 -6
  163. machineconfig/scripts/python/helpers/helpers_search/ast_search.py +74 -0
  164. machineconfig/scripts/python/helpers/helpers_search/qr_code.py +166 -0
  165. machineconfig/scripts/python/helpers/helpers_search/repo_rag.py +325 -0
  166. machineconfig/scripts/python/helpers/helpers_search/script_help.py +81 -0
  167. machineconfig/scripts/python/helpers/helpers_search/symantic_search.py +25 -0
  168. machineconfig/scripts/python/helpers/helpers_sessions/__init__.py +0 -0
  169. machineconfig/scripts/python/helpers/helpers_sessions/sessions_impl.py +186 -0
  170. machineconfig/scripts/python/{helpers_sessions → helpers/helpers_sessions}/sessions_multiprocess.py +20 -14
  171. machineconfig/scripts/python/helpers/helpers_terminal/__init__.py +0 -0
  172. machineconfig/scripts/python/helpers/helpers_terminal/terminal_impl.py +96 -0
  173. machineconfig/scripts/python/helpers/helpers_utils/download.py +150 -0
  174. machineconfig/scripts/python/helpers/helpers_utils/pdf.py +96 -0
  175. machineconfig/scripts/python/helpers/helpers_utils/python.py +210 -0
  176. machineconfig/scripts/python/helpers/helpers_utils/specs.py +246 -0
  177. machineconfig/scripts/python/mcfg_entry.py +143 -0
  178. machineconfig/scripts/python/msearch.py +26 -0
  179. machineconfig/scripts/python/sessions.py +69 -135
  180. machineconfig/scripts/python/terminal.py +58 -0
  181. machineconfig/scripts/python/utils.py +115 -38
  182. machineconfig/scripts/windows/wrap_mcfg.ps1 +63 -0
  183. machineconfig/settings/atuin/config.toml +294 -0
  184. machineconfig/settings/atuin/themes/catppuccin-mocha-mauve.toml +12 -0
  185. machineconfig/settings/broot/conf.toml +1 -1
  186. machineconfig/settings/helix/config.toml +16 -0
  187. machineconfig/settings/helix/languages.toml +13 -4
  188. machineconfig/settings/helix/yazi-picker.sh +12 -0
  189. machineconfig/settings/lf/linux/exe/lfcd.sh +1 -0
  190. machineconfig/settings/lf/linux/exe/previewer.sh +3 -2
  191. machineconfig/settings/lf/windows/lfcd.ps1 +1 -1
  192. machineconfig/settings/lf/windows/lfrc +14 -16
  193. machineconfig/settings/linters/.ruff.toml +2 -1
  194. machineconfig/settings/marimo/marimo.toml +1 -1
  195. machineconfig/settings/marimo/snippets/globalize.py +34 -0
  196. machineconfig/settings/mprocs/windows/mprocs.yaml +2 -2
  197. machineconfig/settings/shells/bash/init.sh +47 -12
  198. machineconfig/settings/shells/ipy/profiles/default/startup/playext.py +1 -1
  199. machineconfig/settings/shells/nushell/config.nu +25 -33
  200. machineconfig/settings/shells/nushell/env.nu +21 -8
  201. machineconfig/settings/shells/nushell/init.nu +138 -0
  202. machineconfig/settings/shells/pwsh/init.ps1 +111 -17
  203. machineconfig/settings/shells/pwsh/search_pwsh_history.ps1 +99 -0
  204. machineconfig/settings/shells/starship/starship.toml +16 -0
  205. machineconfig/settings/shells/wezterm/wezterm.lua +6 -1
  206. machineconfig/settings/shells/wt/settings.json +27 -18
  207. machineconfig/settings/shells/zsh/init.sh +42 -23
  208. machineconfig/settings/television/cable_unix/alias.toml +8 -0
  209. machineconfig/settings/television/cable_unix/aws-buckets.toml +14 -0
  210. machineconfig/settings/television/cable_unix/aws-instances.toml +13 -0
  211. machineconfig/settings/television/cable_unix/bash-history.toml +8 -0
  212. machineconfig/settings/television/cable_unix/channels.toml +19 -0
  213. machineconfig/settings/television/cable_unix/dirs.toml +13 -0
  214. machineconfig/settings/television/cable_unix/distrobox-list.toml +42 -0
  215. machineconfig/settings/television/cable_unix/docker-images.toml +13 -0
  216. machineconfig/settings/television/cable_unix/dotfiles.toml +11 -0
  217. machineconfig/settings/television/cable_unix/env.toml +17 -0
  218. machineconfig/settings/television/cable_unix/files.toml +11 -0
  219. machineconfig/settings/television/cable_unix/fish-history.toml +8 -0
  220. machineconfig/settings/television/cable_unix/git-branch.toml +11 -0
  221. machineconfig/settings/television/cable_unix/git-diff.toml +10 -0
  222. machineconfig/settings/television/cable_unix/git-log.toml +12 -0
  223. machineconfig/settings/television/cable_unix/git-reflog.toml +12 -0
  224. machineconfig/settings/television/cable_unix/git-repos.toml +16 -0
  225. machineconfig/settings/television/cable_unix/guix.toml +20 -0
  226. machineconfig/settings/television/cable_unix/just-recipes.toml +18 -0
  227. machineconfig/settings/television/cable_unix/k8s-deployments.toml +36 -0
  228. machineconfig/settings/television/cable_unix/k8s-pods.toml +50 -0
  229. machineconfig/settings/television/cable_unix/k8s-services.toml +36 -0
  230. machineconfig/settings/television/cable_unix/man-pages.toml +24 -0
  231. machineconfig/settings/television/cable_unix/nu-history.toml +7 -0
  232. machineconfig/settings/television/cable_unix/procs.toml +20 -0
  233. machineconfig/settings/television/cable_unix/text.toml +17 -0
  234. machineconfig/settings/television/cable_unix/tldr.toml +18 -0
  235. machineconfig/settings/television/cable_unix/zsh-history.toml +9 -0
  236. machineconfig/settings/television/cable_windows/alias.toml +7 -0
  237. machineconfig/settings/television/cable_windows/dirs.toml +13 -0
  238. machineconfig/settings/television/cable_windows/docker-images.toml +13 -0
  239. machineconfig/settings/television/cable_windows/dotfiles.toml +11 -0
  240. machineconfig/settings/television/cable_windows/env.toml +17 -0
  241. machineconfig/settings/television/cable_windows/files.toml +14 -0
  242. machineconfig/settings/television/cable_windows/git-branch.toml +11 -0
  243. machineconfig/settings/television/cable_windows/git-diff.toml +10 -0
  244. machineconfig/settings/television/cable_windows/git-log.toml +11 -0
  245. machineconfig/settings/television/cable_windows/git-reflog.toml +11 -0
  246. machineconfig/settings/television/cable_windows/git-repos.toml +15 -0
  247. machineconfig/settings/television/cable_windows/nu-history.toml +7 -0
  248. machineconfig/settings/television/cable_windows/pwsh-history.toml +6 -0
  249. machineconfig/settings/television/cable_windows/text.toml +17 -0
  250. machineconfig/settings/tv/config.toml +234 -0
  251. machineconfig/settings/tv/themes/catppuccin-mocha-sky.toml +22 -0
  252. machineconfig/settings/wsl/.wslconfig +5 -30
  253. machineconfig/settings/wt/__init__.py +0 -0
  254. machineconfig/settings/yazi/init.lua +61 -0
  255. machineconfig/settings/yazi/keymap_linux.toml +94 -0
  256. machineconfig/settings/yazi/keymap_windows.toml +78 -0
  257. machineconfig/settings/yazi/shell/yazi_cd.ps1 +33 -0
  258. machineconfig/settings/yazi/shell/yazi_cd.sh +8 -0
  259. machineconfig/settings/yazi/theme.toml +4 -0
  260. machineconfig/settings/yazi/yazi_linux.toml +94 -0
  261. machineconfig/settings/yazi/yazi_windows.toml +58 -0
  262. machineconfig/settings/zellij/layouts/st.kdl +40 -9
  263. machineconfig/settings/zellij/layouts/st2.kdl +1 -1
  264. machineconfig/setup_linux/__init__.py +2 -2
  265. machineconfig/setup_linux/apps_desktop.sh +8 -27
  266. machineconfig/setup_linux/web_shortcuts/interactive.sh +27 -12
  267. machineconfig/setup_linux/web_shortcuts/live_from_github.sh +34 -0
  268. machineconfig/setup_mac/__init__.py +1 -4
  269. machineconfig/setup_mac/apps_gui.sh +248 -0
  270. machineconfig/setup_windows/__init__.py +2 -5
  271. machineconfig/setup_windows/uv.ps1 +8 -1
  272. machineconfig/setup_windows/web_shortcuts/interactive.ps1 +28 -12
  273. machineconfig/setup_windows/web_shortcuts/live_from_github.ps1 +31 -0
  274. machineconfig/setup_windows/web_shortcuts/quick_init.ps1 +17 -0
  275. machineconfig/type_hinting/sql/__init__.py +1 -0
  276. machineconfig/type_hinting/sql/base.py +216 -0
  277. machineconfig/type_hinting/sql/core_schema.py +64 -0
  278. machineconfig/type_hinting/sql/core_schema_typeddict.py +41 -0
  279. machineconfig/type_hinting/sql/typeddict_codegen.py +222 -0
  280. machineconfig/type_hinting/typedict/__init__.py +1 -0
  281. machineconfig/type_hinting/typedict/ast_utils.py +130 -0
  282. machineconfig/type_hinting/typedict/generator_helpers.py +319 -0
  283. machineconfig/type_hinting/typedict/generators.py +231 -0
  284. machineconfig/type_hinting/typedict/polars_schema.py +24 -0
  285. machineconfig/type_hinting/typedict/polars_schema_typeddict.py +63 -0
  286. machineconfig/utils/accessories.py +31 -4
  287. machineconfig/utils/code.py +163 -51
  288. machineconfig/utils/files/ascii_art.py +11 -15
  289. machineconfig/utils/files/headers.py +6 -7
  290. machineconfig/utils/files/read.py +8 -1
  291. machineconfig/utils/installer_utils/github_release_bulk.py +95 -138
  292. machineconfig/utils/installer_utils/github_release_scraper.py +99 -0
  293. machineconfig/utils/installer_utils/install_from_url.py +183 -0
  294. machineconfig/utils/installer_utils/installer_class.py +53 -102
  295. machineconfig/utils/installer_utils/installer_cli.py +161 -0
  296. machineconfig/utils/installer_utils/installer_helper.py +129 -0
  297. machineconfig/utils/installer_utils/{installer_abc.py → installer_locator_utils.py} +42 -91
  298. machineconfig/utils/{installer.py → installer_utils/installer_runner.py} +20 -65
  299. machineconfig/utils/io.py +94 -9
  300. machineconfig/utils/links.py +56 -38
  301. machineconfig/utils/meta.py +38 -21
  302. machineconfig/utils/options.py +81 -23
  303. machineconfig/utils/options_utils/__init__.py +0 -0
  304. machineconfig/utils/options_utils/options_tv_linux.py +211 -0
  305. machineconfig/utils/options_utils/options_tv_windows.py +88 -0
  306. machineconfig/utils/options_utils/tv_options.py +37 -0
  307. machineconfig/utils/path_extended.py +52 -102
  308. machineconfig/utils/path_helper.py +76 -23
  309. machineconfig/utils/procs.py +1 -1
  310. machineconfig/utils/scheduler.py +26 -53
  311. machineconfig/utils/scheduling.py +0 -2
  312. machineconfig/utils/schemas/fire_agents/fire_agents_input.py +1 -1
  313. machineconfig/utils/schemas/layouts/layout_types.py +1 -1
  314. machineconfig/utils/source_of_truth.py +6 -1
  315. machineconfig/utils/ssh.py +216 -419
  316. machineconfig/utils/ssh_utils/abc.py +5 -0
  317. machineconfig/utils/ssh_utils/copy_from_here.py +116 -0
  318. machineconfig/utils/ssh_utils/copy_to_here.py +303 -0
  319. machineconfig/utils/ssh_utils/utils.py +158 -0
  320. machineconfig/utils/ssh_utils/wsl.py +147 -0
  321. machineconfig/utils/ssh_utils/wsl_helper.py +217 -0
  322. machineconfig/utils/terminal.py +1 -0
  323. machineconfig/utils/upgrade_packages.py +107 -35
  324. machineconfig/utils/ve.py +12 -4
  325. machineconfig-8.51.dist-info/METADATA +140 -0
  326. machineconfig-8.51.dist-info/RECORD +543 -0
  327. {machineconfig-6.82.dist-info → machineconfig-8.51.dist-info}/entry_points.txt +4 -1
  328. machineconfig/jobs/installer/check_installations.py +0 -248
  329. machineconfig/jobs/installer/custom/hx.py +0 -140
  330. machineconfig/jobs/installer/linux_scripts/pgsql.sh +0 -41
  331. machineconfig/jobs/installer/linux_scripts/timescaledb.sh +0 -71
  332. machineconfig/jobs/installer/powershell_scripts/archive_pygraphviz.ps1 +0 -12
  333. machineconfig/jobs/installer/powershell_scripts/openssh-server_add_key.ps1 +0 -7
  334. machineconfig/jobs/installer/powershell_scripts/openssh-server_copy-ssh-id.ps1 +0 -14
  335. machineconfig/profile/backup.toml +0 -49
  336. machineconfig/profile/mapper.toml +0 -256
  337. machineconfig/scripts/linux/fzf2g +0 -21
  338. machineconfig/scripts/linux/fzfag +0 -17
  339. machineconfig/scripts/linux/fzffg +0 -25
  340. machineconfig/scripts/linux/fzfrga +0 -21
  341. machineconfig/scripts/linux/mcfgs +0 -38
  342. machineconfig/scripts/linux/other/share_smb +0 -1
  343. machineconfig/scripts/linux/other/switch_ip +0 -20
  344. machineconfig/scripts/linux/skrg +0 -4
  345. machineconfig/scripts/linux/warp-cli.sh +0 -122
  346. machineconfig/scripts/linux/z_ls +0 -104
  347. machineconfig/scripts/python/ai/command_runner/prompt.txt +0 -9
  348. machineconfig/scripts/python/helpers_devops/cli_config.py +0 -120
  349. machineconfig/scripts/python/helpers_devops/cli_config_dotfile.py +0 -77
  350. machineconfig/scripts/python/helpers_devops/cli_data.py +0 -25
  351. machineconfig/scripts/python/helpers_devops/cli_nw.py +0 -73
  352. machineconfig/scripts/python/helpers_devops/cli_repos.py +0 -181
  353. machineconfig/scripts/python/helpers_devops/cli_self.py +0 -122
  354. machineconfig/scripts/python/helpers_devops/cli_share_server.py +0 -104
  355. machineconfig/scripts/python/helpers_devops/cli_utils.py +0 -221
  356. machineconfig/scripts/python/helpers_devops/devops_backup_retrieve.py +0 -80
  357. machineconfig/scripts/python/helpers_devops/themes/choose_starship_theme.bash +0 -3
  358. machineconfig/scripts/python/helpers_fire/agentic_frameworks/fire_crush.py +0 -37
  359. machineconfig/scripts/python/helpers_fire/agentic_frameworks/fire_gemini.py +0 -44
  360. machineconfig/scripts/python/helpers_fire/agentic_frameworks/fire_qwen.py +0 -43
  361. machineconfig/scripts/python/helpers_fire/prompt.txt +0 -2
  362. machineconfig/scripts/python/helpers_fire/template.sh +0 -15
  363. machineconfig/scripts/python/helpers_navigator/__init__.py +0 -20
  364. machineconfig/scripts/python/helpers_navigator/command_detail.py +0 -44
  365. machineconfig/scripts/python/helpers_navigator/command_tree.py +0 -588
  366. machineconfig/scripts/python/helpers_repos/count_lines_frontend.py +0 -17
  367. machineconfig/scripts/python/helpers_repos/entrypoint.py +0 -76
  368. machineconfig/scripts/python/helpers_repos/secure_repo.py +0 -15
  369. machineconfig/scripts/python/mcfg.py +0 -48
  370. machineconfig/scripts/python/nw/add_ssh_key.py +0 -148
  371. machineconfig/scripts/python/nw/devops_add_identity.py +0 -82
  372. machineconfig/scripts/python/nw/devops_add_ssh_key.py +0 -134
  373. machineconfig/scripts/python/nw/ssh_debug_linux.py +0 -391
  374. machineconfig/scripts/python/nw/ssh_debug_windows.py +0 -338
  375. machineconfig/scripts/python/nw/wsl_windows_transfer.py +0 -66
  376. machineconfig/scripts/windows/fzfb.ps1 +0 -3
  377. machineconfig/scripts/windows/fzfg.ps1 +0 -2
  378. machineconfig/scripts/windows/fzfrga.bat +0 -20
  379. machineconfig/scripts/windows/mcfgs.ps1 +0 -17
  380. machineconfig/scripts/windows/mounts/mount_ssh.ps1 +0 -13
  381. machineconfig/settings/lf/linux/exe/fzf_nano.sh +0 -16
  382. machineconfig/settings/lf/windows/fzf_edit.ps1 +0 -6
  383. machineconfig/settings/lf/windows/tst.ps1 +0 -1
  384. machineconfig/settings/yazi/yazi.toml +0 -4
  385. machineconfig/setup_linux/apps.sh +0 -66
  386. machineconfig/setup_linux/others/cli_installation.sh +0 -137
  387. machineconfig/setup_linux/others/mint_keyboard_shortcuts.sh +0 -30
  388. machineconfig/setup_linux/ssh/openssh_all.sh +0 -25
  389. machineconfig/setup_linux/ssh/openssh_wsl.sh +0 -38
  390. machineconfig/setup_mac/apps.sh +0 -73
  391. machineconfig/setup_mac/ssh/openssh_setup.sh +0 -114
  392. machineconfig/setup_windows/apps.ps1 +0 -62
  393. machineconfig/setup_windows/others/obs.ps1 +0 -4
  394. machineconfig/setup_windows/ssh/add-sshkey.ps1 +0 -29
  395. machineconfig/setup_windows/ssh/add_identity.ps1 +0 -11
  396. machineconfig/setup_windows/ssh/openssh-server.ps1 +0 -37
  397. machineconfig/utils/installer_utils/installer.py +0 -225
  398. machineconfig/utils/tst.py +0 -20
  399. machineconfig-6.82.dist-info/METADATA +0 -82
  400. machineconfig-6.82.dist-info/RECORD +0 -441
  401. machineconfig/jobs/installer/{custom_dev → checks}/__init__.py +0 -0
  402. machineconfig/jobs/installer/linux_scripts/{warp-cli.sh → cloudflare_warp_cli.sh} +0 -0
  403. machineconfig/{scripts/python/helpers_cloud → jobs/installer/python_scripts}/__init__.py +0 -0
  404. machineconfig/jobs/installer/{custom_dev → python_scripts}/alacritty.py +0 -0
  405. machineconfig/jobs/installer/{custom_dev → python_scripts}/bypass_paywall.py +0 -0
  406. machineconfig/jobs/installer/{custom_dev → python_scripts}/cursor.py +0 -0
  407. machineconfig/jobs/installer/{custom_dev → python_scripts}/espanso.py +0 -0
  408. machineconfig/jobs/installer/{custom → python_scripts}/gh.py +0 -0
  409. machineconfig/jobs/installer/{custom_dev → python_scripts}/goes.py +0 -0
  410. machineconfig/jobs/installer/{custom_dev → python_scripts}/lvim.py +0 -0
  411. machineconfig/jobs/installer/{custom_dev → python_scripts}/redis.py +0 -0
  412. machineconfig/{setup_linux/others → jobs/scripts/bash_scripts}/android.sh +0 -0
  413. machineconfig/jobs/{installer/linux_scripts → scripts/bash_scripts}/lid.sh +0 -0
  414. machineconfig/{scripts/python/nw → jobs/scripts/bash_scripts}/mount_drive +0 -0
  415. machineconfig/{scripts/python/nw → jobs/scripts/bash_scripts}/mount_nw_drive +0 -0
  416. machineconfig/{scripts/python/nw → jobs/scripts/bash_scripts}/mount_smb +0 -0
  417. machineconfig/{scripts/linux/other → jobs/scripts/bash_scripts}/share_cloud.sh +0 -0
  418. machineconfig/{scripts/linux/other → jobs/scripts/bash_scripts}/share_nfs +0 -0
  419. machineconfig/{scripts/linux/other → jobs/scripts/bash_scripts}/start_docker +0 -0
  420. machineconfig/{scripts → jobs/scripts/powershell_scripts}/Restore-ThunderbirdProfile.ps1 +0 -0
  421. machineconfig/{setup_windows/others → jobs/scripts/powershell_scripts}/docker.ps1 +0 -0
  422. machineconfig/{scripts/windows/mounts → jobs/scripts/powershell_scripts}/mount_nfs.ps1 +0 -0
  423. machineconfig/{scripts/windows/mounts → jobs/scripts/powershell_scripts}/mount_nw.ps1 +0 -0
  424. machineconfig/{scripts/windows/mounts → jobs/scripts/powershell_scripts}/mount_smb.ps1 +0 -0
  425. machineconfig/{setup_windows/others → jobs/scripts/powershell_scripts}/power_options.ps1 +0 -0
  426. machineconfig/{scripts/windows/mounts → jobs/scripts/powershell_scripts}/share_cloud.cmd +0 -0
  427. machineconfig/{scripts/windows/mounts → jobs/scripts/powershell_scripts}/share_smb.ps1 +0 -0
  428. machineconfig/{scripts/windows/mounts → jobs/scripts/powershell_scripts}/unlock_bitlocker.ps1 +0 -0
  429. machineconfig/scripts/python/{helpers_croshell → ai/utils}/__init__.py +0 -0
  430. machineconfig/scripts/python/ai/{solutions/_shared.py → utils/shared.py} +0 -0
  431. machineconfig/scripts/python/{helpers_devops → graph}/__init__.py +0 -0
  432. machineconfig/scripts/python/{helpers_devops/themes → helpers}/__init__.py +0 -0
  433. machineconfig/scripts/python/{env_manager → helpers/helper_env}/__init__.py +0 -0
  434. machineconfig/scripts/python/{env_manager → helpers/helper_env}/path_manager_backend.py +0 -0
  435. machineconfig/scripts/python/{helpers_fire → helpers/helpers_agents}/__init__.py +0 -0
  436. machineconfig/scripts/python/{helpers_fire → helpers/helpers_agents}/agentic_frameworks/__init__.py +0 -0
  437. machineconfig/scripts/python/{helpers_fire → helpers/helpers_agents}/fire_agents_help_search.py +0 -0
  438. machineconfig/scripts/python/{helpers_fire → helpers/helpers_agents}/fire_agents_load_balancer.py +0 -0
  439. machineconfig/scripts/python/{helpers_fire → helpers/helpers_agents/templates}/template.ps1 +0 -0
  440. machineconfig/scripts/python/{helpers_fire_command → helpers/helpers_cloud}/__init__.py +0 -0
  441. machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/cloud_helpers.py +1 -1
  442. /machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/helpers5.py +0 -0
  443. /machineconfig/scripts/python/{helpers_sessions → helpers/helpers_croshell}/__init__.py +0 -0
  444. /machineconfig/scripts/python/{helpers_croshell → helpers/helpers_croshell}/pomodoro.py +0 -0
  445. /machineconfig/scripts/python/{helpers_croshell → helpers/helpers_croshell}/viewer.py +0 -0
  446. /machineconfig/scripts/python/{helpers_croshell → helpers/helpers_croshell}/viewer_template.py +0 -0
  447. /machineconfig/scripts/python/{nw → helpers/helpers_devops}/__init__.py +0 -0
  448. /machineconfig/{setup_windows/wt_and_pwsh → scripts/python/helpers/helpers_devops/themes}/__init__.py +0 -0
  449. /machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/themes/choose_pwsh_theme.ps1 +0 -0
  450. /machineconfig/scripts/python/{helpers_devops/themes/choose_starship_theme.ps1 → helpers/helpers_fire_command/__init__.py} +0 -0
  451. /machineconfig/scripts/python/{helpers_fire_command → helpers/helpers_fire_command}/cloud_manager.py +0 -0
  452. /machineconfig/scripts/python/{helpers_fire_command/fire_jobs_streamlit_helper.py → helpers/helpers_fire_command/f.py} +0 -0
  453. /machineconfig/{settings/shells/pwsh/profile.ps1 → scripts/python/helpers/helpers_fire_command/fire_jobs_streamlit_helper.py} +0 -0
  454. /machineconfig/scripts/python/{helpers_navigator → helpers/helpers_navigator}/search_bar.py +0 -0
  455. /machineconfig/{settings/yazi/keymap.toml → scripts/python/helpers/helpers_network/__init__.py} +0 -0
  456. /machineconfig/scripts/python/{nw → helpers/helpers_network}/mount_nw_drive.py +0 -0
  457. /machineconfig/scripts/python/{nw → helpers/helpers_network}/onetimeshare.py +0 -0
  458. /machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/sync.py +0 -0
  459. /machineconfig/{setup_windows/wt_and_pwsh → settings/wt}/set_wt_settings.py +0 -0
  460. {machineconfig-6.82.dist-info → machineconfig-8.51.dist-info}/WHEEL +0 -0
  461. {machineconfig-6.82.dist-info → machineconfig-8.51.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,199 @@
1
+ import subprocess
2
+ import random
3
+ import string
4
+ import json
5
+ import shlex
6
+ import logging
7
+ from typing import Any
8
+ from pathlib import Path
9
+
10
+ from machineconfig.utils.schemas.layouts.layout_types import LayoutConfig
11
+
12
+ logger = logging.getLogger(__name__)
13
+
14
+ POWERSHELL_CMD = "powershell" if __import__("platform").system().lower() == "windows" else "pwsh"
15
+
16
+
17
+ def generate_random_suffix(length: int) -> str:
18
+ """Generate a random string suffix for unique PowerShell script names."""
19
+ return "".join(random.choices(string.ascii_lowercase + string.digits, k=length))
20
+
21
+
22
+ def parse_command(command: str) -> tuple[str, list[str]]:
23
+ try:
24
+ parts = shlex.split(command)
25
+ if not parts:
26
+ raise ValueError("Empty command provided")
27
+ return parts[0], parts[1:] if len(parts) > 1 else []
28
+ except ValueError as e:
29
+ logger.error(f"Error parsing command '{command}': {e}")
30
+ parts = command.split()
31
+ return parts[0] if parts else "", parts[1:] if len(parts) > 1 else []
32
+
33
+
34
+ def escape_for_wt(text: str) -> str:
35
+ """Escape text for use in Windows Terminal commands."""
36
+ text = text.replace('"', '""')
37
+ if " " in text or ";" in text or "&" in text or "|" in text:
38
+ return f'"{text}"'
39
+ return text
40
+
41
+
42
+ def validate_layout_config(layout_config: LayoutConfig) -> None:
43
+ """Validate layout configuration format and content."""
44
+ if not layout_config["layoutTabs"]:
45
+ raise ValueError("Layout must contain at least one tab")
46
+ for tab in layout_config["layoutTabs"]:
47
+ if not tab["tabName"].strip():
48
+ raise ValueError(f"Invalid tab name: {tab['tabName']}")
49
+ if not tab["command"].strip():
50
+ raise ValueError(f"Invalid command for tab '{tab['tabName']}': {tab['command']}")
51
+ if not tab["startDir"].strip():
52
+ raise ValueError(f"Invalid startDir for tab '{tab['tabName']}': {tab['startDir']}")
53
+
54
+
55
+ def generate_wt_command_string(layout_config: LayoutConfig, window_name: str) -> str:
56
+ """Generate complete Windows Terminal command string."""
57
+ command_parts = []
58
+
59
+ for i, tab in enumerate(layout_config["layoutTabs"]):
60
+ is_first = i == 0
61
+
62
+ if is_first:
63
+ tab_parts = ["wt", "-w", escape_for_wt(window_name)]
64
+ else:
65
+ tab_parts = ["new-tab"]
66
+
67
+ tab_name = tab["tabName"]
68
+ cwd = tab["startDir"]
69
+ command = tab["command"]
70
+
71
+ if cwd.startswith("~/"):
72
+ cwd = cwd.replace("~/", f"{Path.home()}/")
73
+ elif cwd == "~":
74
+ cwd = str(Path.home())
75
+
76
+ tab_parts.extend(["-d", escape_for_wt(cwd)])
77
+ tab_parts.extend(["--title", escape_for_wt(tab_name)])
78
+ tab_parts.append("--")
79
+
80
+ # Split the command into arguments
81
+ command_args = shlex.split(command)
82
+ tab_parts.extend(command_args)
83
+
84
+ command_parts.append(" ".join(tab_parts))
85
+
86
+ return " `; ".join(command_parts)
87
+
88
+
89
+ def check_wt_session_status(session_name: str) -> dict[str, Any]:
90
+ try:
91
+ ps_script = """
92
+ try {
93
+ $wtProcesses = Get-Process -Name 'WindowsTerminal' -ErrorAction SilentlyContinue
94
+ if ($wtProcesses) {
95
+ $processInfo = @()
96
+ $wtProcesses | ForEach-Object {
97
+ $info = @{
98
+ "Id" = $_.Id
99
+ "ProcessName" = $_.ProcessName
100
+ "StartTime" = $_.StartTime.ToString()
101
+ }
102
+ $processInfo += $info
103
+ }
104
+ $processInfo | ConvertTo-Json -Depth 2
105
+ }
106
+ } catch {
107
+ # No Windows Terminal processes found
108
+ }
109
+ """
110
+
111
+ result = subprocess.run([POWERSHELL_CMD, "-Command", ps_script], capture_output=True, text=True, timeout=5)
112
+
113
+ if result.returncode == 0:
114
+ output = result.stdout.strip()
115
+ if output and output != "":
116
+ try:
117
+ processes = json.loads(output)
118
+ if not isinstance(processes, list):
119
+ processes = [processes]
120
+
121
+ return {"wt_running": True, "session_exists": len(processes) > 0, "session_name": session_name, "all_windows": processes, "session_windows": processes}
122
+ except Exception as e:
123
+ return {"wt_running": True, "session_exists": False, "error": f"Failed to parse process info: {e}", "session_name": session_name}
124
+ else:
125
+ return {"wt_running": False, "session_exists": False, "session_name": session_name, "all_windows": []}
126
+ else:
127
+ return {"wt_running": False, "error": result.stderr, "session_name": session_name}
128
+
129
+ except subprocess.TimeoutExpired:
130
+ return {"wt_running": False, "error": "Timeout while checking Windows Terminal processes", "session_name": session_name}
131
+ except FileNotFoundError:
132
+ return {"wt_running": False, "error": f"PowerShell ({POWERSHELL_CMD}) not found in PATH", "session_name": session_name}
133
+ except Exception as e:
134
+ return {"wt_running": False, "error": str(e), "session_name": session_name}
135
+
136
+
137
+ def check_command_status(tab_name: str, layout_config: LayoutConfig) -> dict[str, Any]:
138
+ """Check if a command is running by looking for processes."""
139
+ tab_config = None
140
+ for tab in layout_config["layoutTabs"]:
141
+ if tab["tabName"] == tab_name:
142
+ tab_config = tab
143
+ break
144
+
145
+ if tab_config is None:
146
+ return {"status": "unknown", "error": f"Tab '{tab_name}' not found in layout config", "running": False, "pid": None, "command": None}
147
+
148
+ command = tab_config["command"]
149
+
150
+ try:
151
+ primary_cmd = command.split()[0] if command.strip() else ""
152
+ if not primary_cmd:
153
+ return {"status": "error", "error": "Empty command", "running": False, "command": command, "tab_name": tab_name}
154
+
155
+ ps_script = f"""
156
+ try {{
157
+ $processes = Get-Process -Name '{primary_cmd}' -ErrorAction SilentlyContinue
158
+ if ($processes) {{
159
+ $processes | ForEach-Object {{
160
+ $procInfo = @{{
161
+ "pid" = $_.Id
162
+ "name" = $_.ProcessName
163
+ "start_time" = $_.StartTime.ToString()
164
+ }}
165
+ Write-Output ($procInfo | ConvertTo-Json -Compress)
166
+ }}
167
+ }}
168
+ }} catch {{
169
+ # No processes found or other error
170
+ }}
171
+ """
172
+
173
+ result = subprocess.run([POWERSHELL_CMD, "-Command", ps_script], capture_output=True, text=True, timeout=5)
174
+
175
+ if result.returncode == 0:
176
+ output_lines = [line.strip() for line in result.stdout.strip().split("\n") if line.strip()]
177
+ matching_processes = []
178
+
179
+ for line in output_lines:
180
+ if line.startswith("{") and line.endswith("}"):
181
+ try:
182
+ proc_info = json.loads(line)
183
+ matching_processes.append(proc_info)
184
+ except json.JSONDecodeError:
185
+ continue
186
+
187
+ if matching_processes:
188
+ return {"status": "running", "running": True, "processes": matching_processes, "command": command, "tab_name": tab_name}
189
+ else:
190
+ return {"status": "not_running", "running": False, "processes": [], "command": command, "tab_name": tab_name}
191
+ else:
192
+ return {"status": "error", "error": f"Command failed: {result.stderr}", "running": False, "command": command, "tab_name": tab_name}
193
+
194
+ except subprocess.TimeoutExpired:
195
+ logger.error(f"Timeout checking command status for tab '{tab_name}'")
196
+ return {"status": "timeout", "error": "Timeout checking process status", "running": False, "command": command, "tab_name": tab_name}
197
+ except Exception as e:
198
+ logger.error(f"Error checking command status for tab '{tab_name}': {e}")
199
+ return {"status": "error", "error": str(e), "running": False, "command": command, "tab_name": tab_name}
@@ -206,7 +206,7 @@ if __name__ == "__main__":
206
206
  # Example usage with new schema
207
207
  sample_layout: LayoutConfig = {
208
208
  "layoutName": "SampleBots",
209
- "layoutTabs": [{"tabName": "Explorer", "startDir": "~/code", "command": "lf"}, {"tabName": "🤖Bot2", "startDir": "~", "command": "cmatrix"}, {"tabName": "📊Monitor", "startDir": "~", "command": "htop"}, {"tabName": "📝Logs", "startDir": "/var/log", "command": "tail -f /var/log/app.log"}],
209
+ "layoutTabs": [{"tabName": "Explorer", "startDir": "~/code", "command": "yazi"}, {"tabName": "🤖Bot2", "startDir": "~", "command": "cmatrix"}, {"tabName": "📊Monitor", "startDir": "~", "command": "htop"}, {"tabName": "📝Logs", "startDir": "/var/log", "command": "tail -f /var/log/app.log"}],
210
210
  }
211
211
  try:
212
212
  # Create layout using the generator with new design
@@ -276,7 +276,9 @@ class ZellijLocalManager:
276
276
  print(f"📊 Quick Summary: {global_summary['running_commands']}/{global_summary['total_commands']} commands running across {global_summary['healthy_sessions']}/{global_summary['total_sessions']} sessions")
277
277
 
278
278
  logger.info(f"Starting monitoring routine with {wait_ms}ms intervals")
279
- sched = Scheduler(routine=routine, wait_ms=wait_ms, logger=logger)
279
+ from machineconfig.utils.scheduler import LoggerTemplate
280
+ from typing import cast
281
+ sched = Scheduler(routine=routine, wait_ms=wait_ms, logger=cast(LoggerTemplate, logger))
280
282
  sched.run()
281
283
 
282
284
  def save(self, session_id: Optional[str]) -> str:
@@ -312,7 +314,7 @@ if __name__ == "__main__":
312
314
  {
313
315
  "layoutName": "Development",
314
316
  "layoutTabs": [
315
- {"tabName": "🚀Frontend", "startDir": "~/code/myapp/frontend", "command": "npm run dev"},
317
+ {"tabName": "🚀Frontend", "startDir": "~/code/myapp/frontend", "command": "bun run dev"},
316
318
  {"tabName": "⚙️Backend", "startDir": "~/code/myapp/backend", "command": "python manage.py runserver"},
317
319
  {"tabName": "📊Monitor", "startDir": "~", "command": "htop"},
318
320
  ],
@@ -88,8 +88,9 @@ class ZellijSessionManager:
88
88
  # Print statuses
89
89
  for i, status in enumerate(statuses):
90
90
  print(f"Manager {i}: {status}")
91
-
92
- sched = Scheduler(routine=routine, wait_ms=60_000, logger=logger)
91
+ from machineconfig.utils.scheduler import LoggerTemplate
92
+ from typing import cast
93
+ sched = Scheduler(routine=routine, wait_ms=60_000, logger=cast(LoggerTemplate, logger))
93
94
  sched.run()
94
95
 
95
96
  def save(self, session_id: Optional[str]) -> str:
@@ -53,7 +53,7 @@ class ProcessMonitor:
53
53
  command = tab_config["command"]
54
54
  try:
55
55
  check_script = self._create_process_check_script(command)
56
- remote_cmd = f"$HOME/.local/bin devops self run-python -c {shlex.quote(check_script)}"
56
+ remote_cmd = f"$HOME/.local/bin devops self python -c {shlex.quote(check_script)}"
57
57
  result = self.remote_executor.run_command(remote_cmd, timeout=15)
58
58
  if result.returncode == 0:
59
59
  try:
@@ -139,7 +139,7 @@ if __name__ == "__main__":
139
139
  check_timestamp = timestamp_result.stdout.strip() if timestamp_result.returncode == 0 else "unknown"
140
140
 
141
141
  check_script = self._create_fresh_check_script(command)
142
- remote_cmd = f"$HOME/.local/bin/devops self run-python -c {shlex.quote(check_script)}"
142
+ remote_cmd = f"$HOME/.local/bin/devops self python -c {shlex.quote(check_script)}"
143
143
  result = self.remote_executor.run_command(remote_cmd, timeout=15)
144
144
 
145
145
  if result.returncode == 0:
@@ -0,0 +1,133 @@
1
+ """
2
+ Check Installations
3
+ ===================
4
+
5
+ This module scans installed applications using VirusTotal and generates a safety report.
6
+ It also provides functionality to download and install pre-checked applications.
7
+ """
8
+
9
+ import csv
10
+ import platform
11
+ from datetime import datetime
12
+ from typing import Optional
13
+
14
+ from rich.console import Console
15
+ from rich.progress import BarColumn, Progress, SpinnerColumn, TextColumn
16
+
17
+ from machineconfig.jobs.installer.checks.install_utils import upload_app
18
+ from machineconfig.jobs.installer.checks.report_utils import AppData, generate_markdown_report
19
+ from machineconfig.jobs.installer.checks.vt_utils import get_vt_client, scan_file
20
+ from machineconfig.utils.installer_utils.installer_runner import get_installed_cli_apps
21
+ from machineconfig.utils.path_extended import PathExtended
22
+ from machineconfig.utils.source_of_truth import CONFIG_ROOT, INSTALL_VERSION_ROOT
23
+
24
+ # Constants
25
+ APP_SUMMARY_PATH = CONFIG_ROOT.joinpath(f"profile/records/{platform.system().lower()}/apps_summary_report.csv")
26
+
27
+ console = Console()
28
+
29
+ def main() -> None:
30
+ """Main execution function."""
31
+ console.rule("[bold blue]MachineConfig Installation Checker[/bold blue]")
32
+
33
+ # 1. Gather Installed Apps
34
+ with console.status("[bold green]Gathering installed applications...[/bold green]"):
35
+ apps_paths = get_installed_cli_apps()
36
+ # Filter and find versions
37
+ # This part mimics the original logic but simplifies it
38
+ # We assume apps_paths contains PathExtended objects
39
+
40
+ # Find version files
41
+ install_version_root_ext = PathExtended(INSTALL_VERSION_ROOT)
42
+ version_files = list(install_version_root_ext.search()) if install_version_root_ext.exists() else []
43
+
44
+ apps_to_scan: list[tuple[PathExtended, Optional[str]]] = []
45
+
46
+ for app_path in apps_paths:
47
+ # Try to find version
48
+ version = None
49
+ # Simple matching logic: check if any version file matches the app name
50
+ # This is a heuristic from the original code
51
+ matching_versions = [v for v in version_files if v.stem == app_path.stem]
52
+ if matching_versions:
53
+ version = matching_versions[0].read_text(encoding="utf-8").strip()
54
+
55
+ apps_to_scan.append((app_path, version))
56
+
57
+ console.print(f"[green]Found {len(apps_to_scan)} applications to check.[/green]")
58
+
59
+ # 2. Scan Apps with VirusTotal
60
+ app_data_list: list[AppData] = []
61
+
62
+ try:
63
+ client = get_vt_client()
64
+
65
+ with Progress(
66
+ SpinnerColumn(),
67
+ TextColumn("[progress.description]{task.description}"),
68
+ BarColumn(),
69
+ TextColumn("[progress.percentage]{task.percentage:>3.0f}%"),
70
+ console=console
71
+ ) as progress:
72
+ scan_task = progress.add_task("[cyan]Scanning apps...", total=len(apps_to_scan))
73
+
74
+ for app_path, version in apps_to_scan:
75
+ progress.update(scan_task, description=f"Scanning {app_path.name}...")
76
+
77
+ positive_pct, _ = scan_file(app_path, client, progress, scan_task)
78
+
79
+ # Upload if safe (optional, based on original code logic which uploaded everything?)
80
+ # Original code uploaded everything.
81
+ progress.update(scan_task, description=f"Uploading {app_path.name}...")
82
+ app_url = upload_app(app_path) or ""
83
+
84
+ app_data_list.append({
85
+ "app_name": app_path.stem,
86
+ "version": version,
87
+ "positive_pct": positive_pct,
88
+ "scan_time": datetime.now().strftime("%Y-%m-%d %H:%M"),
89
+ "app_path": app_path.collapseuser(strict=False).as_posix(),
90
+ "app_url": app_url
91
+ })
92
+
93
+ progress.advance(scan_task)
94
+
95
+ except FileNotFoundError as e:
96
+ console.print(f"[bold red]{e}[/bold red]")
97
+ console.print("[yellow]Skipping scanning due to missing credentials.[/yellow]")
98
+ # Fallback: just list apps without scan results
99
+ for app_path, version in apps_to_scan:
100
+ app_data_list.append({
101
+ "app_name": app_path.stem,
102
+ "version": version,
103
+ "positive_pct": None,
104
+ "scan_time": datetime.now().strftime("%Y-%m-%d %H:%M"),
105
+ "app_path": app_path.collapseuser(strict=False).as_posix(),
106
+ "app_url": ""
107
+ })
108
+ except Exception as e:
109
+ console.print(f"[bold red]An unexpected error occurred during scanning: {e}[/bold red]")
110
+
111
+ # 3. Generate Reports
112
+ if app_data_list:
113
+ # CSV Report
114
+ APP_SUMMARY_PATH.parent.mkdir(parents=True, exist_ok=True)
115
+ csv_path = APP_SUMMARY_PATH.with_suffix(".csv")
116
+
117
+ with open(csv_path, 'w', newline='', encoding='utf-8') as csvfile:
118
+ fieldnames = list(app_data_list[0].keys())
119
+ writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
120
+ writer.writeheader()
121
+ writer.writerows(app_data_list)
122
+
123
+ console.print(f"[green]CSV report saved to: {csv_path}[/green]")
124
+
125
+ # Markdown Report
126
+ md_path = APP_SUMMARY_PATH.with_suffix(".md")
127
+ generate_markdown_report(app_data_list, md_path)
128
+ console.print(f"[green]Markdown report saved to: {md_path}[/green]")
129
+
130
+
131
+
132
+ if __name__ == '__main__':
133
+ main()
@@ -0,0 +1,132 @@
1
+ """
2
+ Installation Utilities
3
+ ======================
4
+
5
+ This module provides functionality to download and install pre-checked applications.
6
+ """
7
+
8
+ import csv
9
+ import platform
10
+ from concurrent.futures import ThreadPoolExecutor
11
+ from pathlib import Path
12
+ from typing import Any, Optional
13
+
14
+ import gdown
15
+ from rich.console import Console
16
+
17
+ from machineconfig.utils.path_extended import PathExtended
18
+ from machineconfig.utils.source_of_truth import CONFIG_ROOT
19
+
20
+ # Constants
21
+ APP_SUMMARY_PATH = CONFIG_ROOT.joinpath(f"profile/records/{platform.system().lower()}/apps_summary_report.csv")
22
+ CLOUD_STORAGE_NAME = "gdw" # Default cloud storage name for rclone
23
+
24
+ console = Console()
25
+
26
+ def upload_app(path: PathExtended) -> Optional[str]:
27
+ """Uploads the app to cloud storage and returns the shareable link."""
28
+ try:
29
+ # Using PathExtended.to_cloud
30
+ # Assuming 'gdw' is the configured remote in rclone
31
+ link_path = path.to_cloud(CLOUD_STORAGE_NAME, rel2home=True, share=True, os_specific=True, verbose=False)
32
+ if link_path:
33
+ return str(link_path)
34
+ return None
35
+ except Exception as e:
36
+ console.print(f"[red]Failed to upload {path}: {e}[/red]")
37
+ return None
38
+
39
+ def download_google_drive_file(url: str) -> PathExtended:
40
+ """Downloads a file from Google Drive using gdown."""
41
+ try:
42
+ # Extract ID from URL
43
+ # Assuming URL format like https://drive.google.com/file/d/FILE_ID/view or similar
44
+ # or https://drive.google.com/uc?id=FILE_ID
45
+ if "id=" in url:
46
+ file_id = url.split("id=")[1].split("&")[0]
47
+ elif "/d/" in url:
48
+ file_id = url.split("/d/")[1].split("/")[0]
49
+ else:
50
+ # Fallback to gdown's auto detection or just pass URL
51
+ file_id = url
52
+
53
+ # Create a temporary directory for download
54
+ output_dir = PathExtended.tmpdir(prefix="gdown_")
55
+ # gdown.download returns the output filename
56
+ output_file = gdown.download(id=file_id, output=str(output_dir) + "/", quiet=False, fuzzy=True)
57
+
58
+ if not output_file:
59
+ raise ValueError(f"Download failed for {url}")
60
+
61
+ return PathExtended(output_file)
62
+ except Exception as e:
63
+ raise RuntimeError(f"Failed to download from Google Drive: {e}") from e
64
+
65
+ def install_cli_app(app_url: str) -> bool:
66
+ """Downloads and installs a CLI app."""
67
+ try:
68
+ if not app_url:
69
+ return False
70
+
71
+ exe_path = download_google_drive_file(app_url)
72
+ console.print(f"[green]Downloaded {exe_path.name}[/green]")
73
+
74
+ system = platform.system().lower()
75
+ if system in ["linux", "darwin"]:
76
+ exe_path.chmod(0o755) # Make executable
77
+ # Move to local bin (requires user to have write access or sudo, which we can't easily do here without interaction)
78
+ # Using ~/.local/bin is safer
79
+ install_path = Path.home() / ".local/bin"
80
+ install_path.mkdir(parents=True, exist_ok=True)
81
+ target = install_path / exe_path.name
82
+ exe_path.rename(target)
83
+ console.print(f"[green]Installed to {target}[/green]")
84
+ elif system == "windows":
85
+ install_path = Path.home() / "AppData/Local/Microsoft/WindowsApps"
86
+ install_path.mkdir(parents=True, exist_ok=True)
87
+ target = install_path / exe_path.name
88
+ # Use shutil.move or PathExtended.move
89
+ exe_path.move(path=target, overwrite=True)
90
+ console.print(f"[green]Installed to {target}[/green]")
91
+
92
+ return True
93
+ except Exception as e:
94
+ console.print(f"[red]Failed to install app from {app_url}: {e}[/red]")
95
+ return False
96
+
97
+ def load_summary_report() -> list[dict[str, Any]]:
98
+ """Loads the summary report from CSV."""
99
+ if APP_SUMMARY_PATH.exists():
100
+ with open(APP_SUMMARY_PATH, 'r', encoding='utf-8') as csvfile:
101
+ reader = csv.DictReader(csvfile)
102
+ return list(reader)
103
+ else:
104
+ console.print(f"[yellow]Warning: Summary report not found at {APP_SUMMARY_PATH}[/yellow]")
105
+ return []
106
+
107
+ def download_safe_apps(name: str = "essentials") -> None:
108
+ """Downloads and installs safe apps."""
109
+ data = load_summary_report()
110
+ if not data:
111
+ console.print("[red]No app data available to install.[/red]")
112
+ return
113
+
114
+ apps_to_install = []
115
+ if name == "essentials":
116
+ # Install all available apps in the report? Or filter?
117
+ # Original code installed all if name="essentials" (implied by logic)
118
+ apps_to_install = [item['app_url'] for item in data if item.get('app_url')]
119
+ else:
120
+ apps_to_install = [item['app_url'] for item in data if item.get('app_name') == name and item.get('app_url')]
121
+
122
+ if not apps_to_install:
123
+ console.print(f"[yellow]No apps found to install for '{name}'.[/yellow]")
124
+ return
125
+
126
+ console.print(f"[bold]Installing {len(apps_to_install)} apps...[/bold]")
127
+
128
+ with ThreadPoolExecutor(max_workers=5) as executor:
129
+ results = list(executor.map(install_cli_app, apps_to_install))
130
+
131
+ success_count = sum(results)
132
+ console.print(f"[bold green]Successfully installed {success_count}/{len(apps_to_install)} apps.[/bold green]")
@@ -0,0 +1,39 @@
1
+ """
2
+ Report Utilities
3
+ ================
4
+
5
+ This module provides functionality to generate reports for installed applications.
6
+ """
7
+
8
+ from pathlib import Path
9
+ from typing import Optional, TypedDict
10
+ from rich.console import Console
11
+ from rich.panel import Panel
12
+
13
+ console = Console()
14
+
15
+ class AppData(TypedDict):
16
+ app_name: str
17
+ version: Optional[str]
18
+ positive_pct: Optional[float]
19
+ scan_time: str
20
+ app_path: str
21
+ app_url: str
22
+
23
+ def generate_markdown_report(data: list[AppData], output_path: Path) -> None:
24
+ """Generates a Markdown table from the app data."""
25
+ if not data:
26
+ return
27
+
28
+ keys = list(data[0].keys())
29
+ header = "| " + " | ".join(key.replace("_", " ").title() for key in keys) + " |"
30
+ separator = "| " + " | ".join("---" for _ in keys) + " |"
31
+ rows = []
32
+ for row in data:
33
+ # Fix: row is a dict, keys are strings.
34
+ row_values = [str(row.get(key, '')) for key in keys]
35
+ rows.append("| " + " | ".join(row_values) + " |")
36
+
37
+ content = "\n".join([header, separator] + rows)
38
+ output_path.write_text(content, encoding="utf-8")
39
+ console.print(Panel(content, title="Safety Report Summary", expand=False))
@@ -0,0 +1,89 @@
1
+ """
2
+ VirusTotal Utilities
3
+ ====================
4
+
5
+ This module provides functionality to interact with VirusTotal API.
6
+ """
7
+
8
+ import time
9
+ from pathlib import Path
10
+ from typing import Any, Optional, TypedDict
11
+
12
+ import vt
13
+ from rich.progress import Progress, TaskID
14
+
15
+ # Constants
16
+ VT_TOKEN_PATH = Path.home().joinpath("dotfiles/creds/tokens/virustotal")
17
+
18
+ class ScanResult(TypedDict):
19
+ result: Optional[str]
20
+ category: str
21
+
22
+ def get_vt_client() -> vt.Client:
23
+ """Retrieves the VirusTotal client using the token from the credentials file."""
24
+ if not VT_TOKEN_PATH.exists():
25
+ raise FileNotFoundError(f"VirusTotal token not found at {VT_TOKEN_PATH}")
26
+
27
+ token = VT_TOKEN_PATH.read_text(encoding="utf-8").split("\n")[0].strip()
28
+ return vt.Client(token)
29
+
30
+ def scan_file(path: Path, client: vt.Client, progress: Optional[Progress] = None, task_id: Optional[TaskID] = None) -> tuple[Optional[float], list[Any]]:
31
+ """
32
+ Scans a file using VirusTotal.
33
+
34
+ Args:
35
+ path: Path to the file to scan.
36
+ client: VirusTotal client instance.
37
+ progress: Optional Rich progress bar.
38
+ task_id: Optional Task ID for the progress bar.
39
+
40
+ Returns:
41
+ A tuple containing the positive percentage (0-100) and the list of result details.
42
+ Returns (None, []) if scanning fails or file is skipped.
43
+ """
44
+ if path.is_dir():
45
+ if progress and task_id:
46
+ progress.console.print(f"[yellow]📁 Skipping directory: {path}[/yellow]")
47
+ return None, []
48
+
49
+ try:
50
+ with open(path, "rb") as f:
51
+ analysis = client.scan_file(f)
52
+
53
+ repeat_counter = 0
54
+ while True:
55
+ try:
56
+ anal = client.get_object("/analyses/{}", analysis.id)
57
+ if anal.status == "completed":
58
+ break
59
+ except Exception as e:
60
+ repeat_counter += 1
61
+ if repeat_counter > 3:
62
+ raise ValueError(f"❌ Error scanning {path}: {e}") from e
63
+ if progress and task_id:
64
+ progress.console.print(f"[red]⚠️ Error scanning {path}, retrying... ({repeat_counter}/3)[/red]")
65
+ time.sleep(5)
66
+
67
+ time.sleep(10) # Wait before checking status again
68
+
69
+ # Process results
70
+ results_data = list(anal.results.values())
71
+ malicious = []
72
+ for result_item in results_data:
73
+ result_dict = result_item.__dict__ if hasattr(result_item, '__dict__') else {
74
+ 'result': getattr(result_item, 'result', None),
75
+ 'category': getattr(result_item, 'category', 'unknown')
76
+ }
77
+
78
+ if result_dict.get('result') is None and result_dict.get('category') in ["undetected", "type-unsupported", "failure", "timeout", "confirmed-timeout"]:
79
+ continue
80
+
81
+ malicious.append(result_item)
82
+
83
+ positive_pct = round(len(malicious) / len(results_data) * 100, 1) if results_data else 0.0
84
+ return positive_pct, results_data
85
+
86
+ except Exception as e:
87
+ if progress and task_id:
88
+ progress.console.print(f"[bold red]❌ Failed to scan {path}: {e}[/bold red]")
89
+ return None, []