machineconfig 1.97__py3-none-any.whl → 2.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of machineconfig might be problematic. Click here for more details.

Files changed (268) hide show
  1. machineconfig/cluster/cloud_manager.py +22 -29
  2. machineconfig/cluster/data_transfer.py +2 -3
  3. machineconfig/cluster/distribute.py +0 -2
  4. machineconfig/cluster/file_manager.py +4 -5
  5. machineconfig/cluster/job_params.py +1 -4
  6. machineconfig/cluster/loader_runner.py +8 -11
  7. machineconfig/cluster/remote_machine.py +4 -5
  8. machineconfig/cluster/script_execution.py +2 -2
  9. machineconfig/cluster/script_notify_upon_completion.py +0 -1
  10. machineconfig/cluster/sessions_managers/archive/create_zellij_template.py +4 -6
  11. machineconfig/cluster/sessions_managers/archive/session_managers.py +0 -1
  12. machineconfig/cluster/sessions_managers/enhanced_command_runner.py +35 -75
  13. machineconfig/cluster/sessions_managers/wt_local.py +113 -185
  14. machineconfig/cluster/sessions_managers/wt_local_manager.py +127 -197
  15. machineconfig/cluster/sessions_managers/wt_remote.py +60 -67
  16. machineconfig/cluster/sessions_managers/wt_remote_manager.py +110 -149
  17. machineconfig/cluster/sessions_managers/wt_utils/layout_generator.py +61 -64
  18. machineconfig/cluster/sessions_managers/wt_utils/process_monitor.py +72 -172
  19. machineconfig/cluster/sessions_managers/wt_utils/remote_executor.py +27 -60
  20. machineconfig/cluster/sessions_managers/wt_utils/session_manager.py +58 -137
  21. machineconfig/cluster/sessions_managers/wt_utils/status_reporter.py +46 -74
  22. machineconfig/cluster/sessions_managers/zellij_local.py +91 -147
  23. machineconfig/cluster/sessions_managers/zellij_local_manager.py +165 -190
  24. machineconfig/cluster/sessions_managers/zellij_remote.py +51 -58
  25. machineconfig/cluster/sessions_managers/zellij_remote_manager.py +40 -46
  26. machineconfig/cluster/sessions_managers/zellij_utils/example_usage.py +19 -17
  27. machineconfig/cluster/sessions_managers/zellij_utils/layout_generator.py +30 -31
  28. machineconfig/cluster/sessions_managers/zellij_utils/process_monitor.py +64 -134
  29. machineconfig/cluster/sessions_managers/zellij_utils/remote_executor.py +7 -11
  30. machineconfig/cluster/sessions_managers/zellij_utils/session_manager.py +27 -55
  31. machineconfig/cluster/sessions_managers/zellij_utils/status_reporter.py +14 -13
  32. machineconfig/cluster/templates/cli_click.py +0 -1
  33. machineconfig/cluster/templates/cli_gooey.py +0 -2
  34. machineconfig/cluster/templates/cli_trogon.py +0 -1
  35. machineconfig/cluster/templates/run_cloud.py +0 -1
  36. machineconfig/cluster/templates/run_cluster.py +0 -1
  37. machineconfig/cluster/templates/run_remote.py +0 -1
  38. machineconfig/cluster/templates/utils.py +27 -11
  39. machineconfig/jobs/__pycache__/__init__.cpython-313.pyc +0 -0
  40. machineconfig/jobs/linux/msc/cli_agents.sh +16 -0
  41. machineconfig/jobs/python/check_installations.py +9 -9
  42. machineconfig/jobs/python/create_bootable_media.py +0 -2
  43. machineconfig/jobs/python/python_cargo_build_share.py +2 -2
  44. machineconfig/jobs/python/python_ve_symlink.py +9 -11
  45. machineconfig/jobs/python/tasks.py +0 -1
  46. machineconfig/jobs/python/vscode/api.py +5 -5
  47. machineconfig/jobs/python/vscode/link_ve.py +20 -21
  48. machineconfig/jobs/python/vscode/select_interpreter.py +28 -29
  49. machineconfig/jobs/python/vscode/sync_code.py +14 -18
  50. machineconfig/jobs/python_custom_installers/__pycache__/__init__.cpython-313.pyc +0 -0
  51. machineconfig/jobs/python_custom_installers/archive/ngrok.py +15 -15
  52. machineconfig/jobs/python_custom_installers/dev/aider.py +10 -18
  53. machineconfig/jobs/python_custom_installers/dev/alacritty.py +12 -21
  54. machineconfig/jobs/python_custom_installers/dev/brave.py +13 -22
  55. machineconfig/jobs/python_custom_installers/dev/bypass_paywall.py +13 -20
  56. machineconfig/jobs/python_custom_installers/dev/code.py +17 -24
  57. machineconfig/jobs/python_custom_installers/dev/cursor.py +10 -21
  58. machineconfig/jobs/python_custom_installers/dev/docker_desktop.py +12 -11
  59. machineconfig/jobs/python_custom_installers/dev/espanso.py +19 -23
  60. machineconfig/jobs/python_custom_installers/dev/goes.py +9 -16
  61. machineconfig/jobs/python_custom_installers/dev/lvim.py +13 -21
  62. machineconfig/jobs/python_custom_installers/dev/nerdfont.py +15 -22
  63. machineconfig/jobs/python_custom_installers/dev/redis.py +15 -23
  64. machineconfig/jobs/python_custom_installers/dev/wezterm.py +15 -22
  65. machineconfig/jobs/python_custom_installers/dev/winget.py +32 -50
  66. machineconfig/jobs/python_custom_installers/docker.py +15 -24
  67. machineconfig/jobs/python_custom_installers/gh.py +18 -26
  68. machineconfig/jobs/python_custom_installers/hx.py +33 -17
  69. machineconfig/jobs/python_custom_installers/warp-cli.py +15 -23
  70. machineconfig/jobs/python_generic_installers/__pycache__/__init__.cpython-313.pyc +0 -0
  71. machineconfig/jobs/python_generic_installers/config.json +412 -389
  72. machineconfig/jobs/python_linux_installers/__pycache__/__init__.cpython-313.pyc +0 -0
  73. machineconfig/jobs/python_windows_installers/dev/config.json +1 -1
  74. machineconfig/jobs/windows/archive/archive_pygraphviz.ps1 +1 -1
  75. machineconfig/jobs/windows/msc/cli_agents.bat +0 -0
  76. machineconfig/jobs/windows/msc/cli_agents.ps1 +0 -0
  77. machineconfig/jobs/windows/start_terminal.ps1 +1 -1
  78. machineconfig/logger.py +50 -0
  79. machineconfig/profile/create.py +50 -36
  80. machineconfig/profile/create_hardlinks.py +33 -26
  81. machineconfig/profile/shell.py +87 -60
  82. machineconfig/scripts/__pycache__/__init__.cpython-313.pyc +0 -0
  83. machineconfig/scripts/cloud/init.sh +2 -2
  84. machineconfig/scripts/linux/checkout_versions +1 -1
  85. machineconfig/scripts/linux/choose_wezterm_theme +1 -1
  86. machineconfig/scripts/linux/cloud_copy +1 -1
  87. machineconfig/scripts/linux/cloud_manager +1 -1
  88. machineconfig/scripts/linux/cloud_mount +1 -1
  89. machineconfig/scripts/linux/cloud_repo_sync +1 -1
  90. machineconfig/scripts/linux/cloud_sync +1 -1
  91. machineconfig/scripts/linux/croshell +1 -1
  92. machineconfig/scripts/linux/devops +3 -5
  93. machineconfig/scripts/linux/fire +2 -1
  94. machineconfig/scripts/linux/fire_agents +3 -3
  95. machineconfig/scripts/linux/ftpx +1 -1
  96. machineconfig/scripts/linux/gh_models +1 -1
  97. machineconfig/scripts/linux/kill_process +1 -1
  98. machineconfig/scripts/linux/mcinit +2 -2
  99. machineconfig/scripts/linux/repos +1 -1
  100. machineconfig/scripts/linux/scheduler +1 -1
  101. machineconfig/scripts/linux/start_slidev +1 -1
  102. machineconfig/scripts/linux/start_terminals +1 -1
  103. machineconfig/scripts/linux/url2md +1 -1
  104. machineconfig/scripts/linux/warp-cli.sh +122 -0
  105. machineconfig/scripts/linux/wifi_conn +1 -1
  106. machineconfig/scripts/python/__pycache__/__init__.cpython-313.pyc +0 -0
  107. machineconfig/scripts/python/__pycache__/croshell.cpython-313.pyc +0 -0
  108. machineconfig/scripts/python/__pycache__/devops.cpython-313.pyc +0 -0
  109. machineconfig/scripts/python/__pycache__/devops_devapps_install.cpython-313.pyc +0 -0
  110. machineconfig/scripts/python/__pycache__/devops_update_repos.cpython-313.pyc +0 -0
  111. machineconfig/scripts/python/__pycache__/fire_jobs.cpython-313.pyc +0 -0
  112. machineconfig/scripts/python/ai/__init__.py +0 -0
  113. machineconfig/scripts/python/ai/__pycache__/__init__.cpython-313.pyc +0 -0
  114. machineconfig/scripts/python/ai/__pycache__/generate_files.cpython-313.pyc +0 -0
  115. machineconfig/scripts/python/ai/__pycache__/mcinit.cpython-313.pyc +0 -0
  116. machineconfig/scripts/python/ai/chatmodes/Thinking-Beast-Mode.chatmode.md +337 -0
  117. machineconfig/scripts/python/ai/chatmodes/Ultimate-Transparent-Thinking-Beast-Mode.chatmode.md +644 -0
  118. machineconfig/scripts/python/ai/chatmodes/deepResearch.chatmode.md +81 -0
  119. machineconfig/scripts/python/ai/configs/.gemini/settings.json +81 -0
  120. machineconfig/scripts/python/ai/generate_files.py +84 -0
  121. machineconfig/scripts/python/ai/instructions/python/dev.instructions.md +45 -0
  122. machineconfig/scripts/python/ai/mcinit.py +107 -0
  123. machineconfig/scripts/python/ai/prompts/allLintersAndTypeCheckers.prompt.md +5 -0
  124. machineconfig/scripts/python/ai/prompts/research-report-skeleton.prompt.md +38 -0
  125. machineconfig/scripts/python/ai/scripts/lint_and_type_check.sh +52 -0
  126. machineconfig/scripts/python/archive/tmate_conn.py +5 -5
  127. machineconfig/scripts/python/archive/tmate_start.py +3 -3
  128. machineconfig/scripts/python/choose_wezterm_theme.py +2 -2
  129. machineconfig/scripts/python/cloud_copy.py +20 -19
  130. machineconfig/scripts/python/cloud_mount.py +10 -8
  131. machineconfig/scripts/python/cloud_repo_sync.py +15 -15
  132. machineconfig/scripts/python/cloud_sync.py +1 -1
  133. machineconfig/scripts/python/croshell.py +18 -16
  134. machineconfig/scripts/python/devops.py +6 -6
  135. machineconfig/scripts/python/devops_add_identity.py +9 -7
  136. machineconfig/scripts/python/devops_add_ssh_key.py +19 -19
  137. machineconfig/scripts/python/devops_backup_retrieve.py +14 -14
  138. machineconfig/scripts/python/devops_devapps_install.py +3 -3
  139. machineconfig/scripts/python/devops_update_repos.py +141 -53
  140. machineconfig/scripts/python/dotfile.py +3 -3
  141. machineconfig/scripts/python/fire_agents.py +202 -41
  142. machineconfig/scripts/python/fire_jobs.py +20 -21
  143. machineconfig/scripts/python/ftpx.py +4 -3
  144. machineconfig/scripts/python/gh_models.py +94 -94
  145. machineconfig/scripts/python/helpers/__pycache__/__init__.cpython-313.pyc +0 -0
  146. machineconfig/scripts/python/helpers/__pycache__/helpers4.cpython-313.pyc +0 -0
  147. machineconfig/scripts/python/helpers/cloud_helpers.py +3 -3
  148. machineconfig/scripts/python/helpers/helpers2.py +3 -3
  149. machineconfig/scripts/python/helpers/helpers4.py +8 -7
  150. machineconfig/scripts/python/helpers/helpers5.py +7 -7
  151. machineconfig/scripts/python/helpers/repo_sync_helpers.py +2 -2
  152. machineconfig/scripts/python/mount_nfs.py +4 -3
  153. machineconfig/scripts/python/mount_nw_drive.py +4 -4
  154. machineconfig/scripts/python/mount_ssh.py +4 -3
  155. machineconfig/scripts/python/repos.py +9 -9
  156. machineconfig/scripts/python/scheduler.py +1 -1
  157. machineconfig/scripts/python/start_slidev.py +9 -8
  158. machineconfig/scripts/python/start_terminals.py +1 -1
  159. machineconfig/scripts/python/viewer.py +40 -40
  160. machineconfig/scripts/python/wifi_conn.py +65 -66
  161. machineconfig/scripts/python/wsl_windows_transfer.py +2 -2
  162. machineconfig/scripts/windows/checkout_version.ps1 +1 -3
  163. machineconfig/scripts/windows/choose_wezterm_theme.ps1 +1 -3
  164. machineconfig/scripts/windows/cloud_copy.ps1 +2 -6
  165. machineconfig/scripts/windows/cloud_manager.ps1 +1 -1
  166. machineconfig/scripts/windows/cloud_repo_sync.ps1 +1 -2
  167. machineconfig/scripts/windows/cloud_sync.ps1 +2 -2
  168. machineconfig/scripts/windows/croshell.ps1 +2 -2
  169. machineconfig/scripts/windows/devops.ps1 +1 -4
  170. machineconfig/scripts/windows/dotfile.ps1 +1 -3
  171. machineconfig/scripts/windows/fire.ps1 +1 -1
  172. machineconfig/scripts/windows/ftpx.ps1 +2 -2
  173. machineconfig/scripts/windows/gpt.ps1 +1 -1
  174. machineconfig/scripts/windows/kill_process.ps1 +1 -2
  175. machineconfig/scripts/windows/mcinit.ps1 +2 -2
  176. machineconfig/scripts/windows/mount_nfs.ps1 +1 -1
  177. machineconfig/scripts/windows/mount_ssh.ps1 +1 -1
  178. machineconfig/scripts/windows/pomodoro.ps1 +1 -1
  179. machineconfig/scripts/windows/py2exe.ps1 +1 -3
  180. machineconfig/scripts/windows/repos.ps1 +1 -1
  181. machineconfig/scripts/windows/scheduler.ps1 +1 -1
  182. machineconfig/scripts/windows/snapshot.ps1 +2 -2
  183. machineconfig/scripts/windows/start_slidev.ps1 +1 -1
  184. machineconfig/scripts/windows/start_terminals.ps1 +1 -1
  185. machineconfig/scripts/windows/wifi_conn.ps1 +1 -1
  186. machineconfig/scripts/windows/wsl_windows_transfer.ps1 +1 -3
  187. machineconfig/settings/lf/linux/lfrc +1 -1
  188. machineconfig/settings/linters/.ruff.toml +2 -2
  189. machineconfig/settings/linters/.ruff_cache/.gitignore +2 -0
  190. machineconfig/settings/linters/.ruff_cache/CACHEDIR.TAG +1 -0
  191. machineconfig/settings/lvim/windows/archive/config_additional.lua +1 -1
  192. machineconfig/settings/shells/ipy/profiles/default/startup/playext.py +71 -71
  193. machineconfig/settings/shells/wt/settings.json +8 -8
  194. machineconfig/settings/svim/linux/init.toml +1 -1
  195. machineconfig/settings/svim/windows/init.toml +1 -1
  196. machineconfig/setup_linux/web_shortcuts/croshell.sh +0 -54
  197. machineconfig/setup_linux/web_shortcuts/interactive.sh +6 -6
  198. machineconfig/setup_linux/web_shortcuts/tmp.sh +2 -0
  199. machineconfig/setup_windows/web_shortcuts/all.ps1 +2 -2
  200. machineconfig/setup_windows/web_shortcuts/ascii_art.ps1 +1 -1
  201. machineconfig/setup_windows/web_shortcuts/croshell.ps1 +1 -1
  202. machineconfig/setup_windows/web_shortcuts/interactive.ps1 +5 -5
  203. machineconfig/setup_windows/wt_and_pwsh/install_fonts.ps1 +51 -15
  204. machineconfig/setup_windows/wt_and_pwsh/set_pwsh_theme.py +75 -18
  205. machineconfig/setup_windows/wt_and_pwsh/set_wt_settings.py +52 -42
  206. machineconfig/utils/ai/browser_user_wrapper.py +5 -5
  207. machineconfig/utils/ai/generate_file_checklist.py +19 -22
  208. machineconfig/utils/ai/url2md.py +5 -3
  209. machineconfig/utils/cloud/onedrive/setup_oauth.py +5 -4
  210. machineconfig/utils/cloud/onedrive/transaction.py +192 -227
  211. machineconfig/utils/code.py +71 -43
  212. machineconfig/utils/installer.py +77 -85
  213. machineconfig/utils/installer_utils/installer_abc.py +29 -17
  214. machineconfig/utils/installer_utils/installer_class.py +188 -83
  215. machineconfig/utils/io_save.py +3 -15
  216. machineconfig/utils/links.py +22 -11
  217. machineconfig/utils/notifications.py +197 -0
  218. machineconfig/utils/options.py +38 -25
  219. machineconfig/utils/path.py +18 -6
  220. machineconfig/utils/path_reduced.py +637 -316
  221. machineconfig/utils/procs.py +69 -63
  222. machineconfig/utils/scheduling.py +11 -13
  223. machineconfig/utils/ssh.py +351 -0
  224. machineconfig/utils/terminal.py +225 -0
  225. machineconfig/utils/utils.py +13 -12
  226. machineconfig/utils/utils2.py +43 -10
  227. machineconfig/utils/utils5.py +242 -46
  228. machineconfig/utils/ve.py +11 -6
  229. {machineconfig-1.97.dist-info → machineconfig-2.1.dist-info}/METADATA +15 -9
  230. {machineconfig-1.97.dist-info → machineconfig-2.1.dist-info}/RECORD +232 -235
  231. machineconfig/cluster/self_ssh.py +0 -57
  232. machineconfig/jobs/__pycache__/__init__.cpython-311.pyc +0 -0
  233. machineconfig/jobs/python/__pycache__/__init__.cpython-311.pyc +0 -0
  234. machineconfig/jobs/python/archive/python_tools.txt +0 -12
  235. machineconfig/jobs/python/vscode/__pycache__/select_interpreter.cpython-311.pyc +0 -0
  236. machineconfig/jobs/python_custom_installers/__pycache__/__init__.cpython-311.pyc +0 -0
  237. machineconfig/jobs/python_generic_installers/__pycache__/__init__.cpython-311.pyc +0 -0
  238. machineconfig/jobs/python_generic_installers/update.py +0 -3
  239. machineconfig/jobs/python_linux_installers/__pycache__/__init__.cpython-311.pyc +0 -0
  240. machineconfig/profile/__pycache__/__init__.cpython-311.pyc +0 -0
  241. machineconfig/profile/__pycache__/create.cpython-311.pyc +0 -0
  242. machineconfig/profile/__pycache__/shell.cpython-311.pyc +0 -0
  243. machineconfig/scripts/__pycache__/__init__.cpython-311.pyc +0 -0
  244. machineconfig/scripts/linux/activate_ve +0 -87
  245. machineconfig/scripts/python/__pycache__/__init__.cpython-311.pyc +0 -0
  246. machineconfig/scripts/python/__pycache__/cloud_copy.cpython-311.pyc +0 -0
  247. machineconfig/scripts/python/__pycache__/cloud_mount.cpython-311.pyc +0 -0
  248. machineconfig/scripts/python/__pycache__/cloud_sync.cpython-311.pyc +0 -0
  249. machineconfig/scripts/python/__pycache__/croshell.cpython-311.pyc +0 -0
  250. machineconfig/scripts/python/__pycache__/devops.cpython-311.pyc +0 -0
  251. machineconfig/scripts/python/__pycache__/devops_backup_retrieve.cpython-311.pyc +0 -0
  252. machineconfig/scripts/python/__pycache__/devops_devapps_install.cpython-311.pyc +0 -0
  253. machineconfig/scripts/python/__pycache__/devops_update_repos.cpython-311.pyc +0 -0
  254. machineconfig/scripts/python/__pycache__/fire_agents.cpython-311.pyc +0 -0
  255. machineconfig/scripts/python/__pycache__/fire_jobs.cpython-311.pyc +0 -0
  256. machineconfig/scripts/python/__pycache__/get_zellij_cmd.cpython-311.pyc +0 -0
  257. machineconfig/scripts/python/__pycache__/repos.cpython-311.pyc +0 -0
  258. machineconfig/scripts/python/ai/__pycache__/init.cpython-311.pyc +0 -0
  259. machineconfig/scripts/python/ai/init.py +0 -56
  260. machineconfig/scripts/python/ai/rules/python/dev.md +0 -31
  261. machineconfig/scripts/python/helpers/__pycache__/__init__.cpython-311.pyc +0 -0
  262. machineconfig/scripts/python/helpers/__pycache__/cloud_helpers.cpython-311.pyc +0 -0
  263. machineconfig/scripts/python/helpers/__pycache__/helpers2.cpython-311.pyc +0 -0
  264. machineconfig/scripts/python/helpers/__pycache__/helpers4.cpython-311.pyc +0 -0
  265. machineconfig/scripts/python/helpers/__pycache__/repo_sync_helpers.cpython-311.pyc +0 -0
  266. machineconfig/scripts/windows/activate_ve.ps1 +0 -54
  267. {machineconfig-1.97.dist-info → machineconfig-2.1.dist-info}/WHEEL +0 -0
  268. {machineconfig-1.97.dist-info → machineconfig-2.1.dist-info}/top_level.txt +0 -0
@@ -1,4 +1,3 @@
1
-
2
1
  # """Gooey
3
2
  # """
4
3
 
@@ -12,7 +11,6 @@
12
11
  # # from typing import Any, Optional
13
12
 
14
13
 
15
-
16
14
  # @Gooey(program_name="Cluster Launcher", program_description='Cofigure remote cluster and launch jobs.') # type: ignore
17
15
  # def main() -> RemoteMachineConfig:
18
16
  # # parser = GooeyParser(description='Example of Gooey\'s basic functionality')
@@ -1,4 +1,3 @@
1
-
2
1
  # """Trogon
3
2
  # """
4
3
 
@@ -1,4 +1,3 @@
1
-
2
1
  # """Run with sane defaults for a remote machine.
3
2
  # """
4
3
 
@@ -1,4 +1,3 @@
1
-
2
1
  # """
3
2
  # Cluster Template
4
3
  # """
@@ -1,4 +1,3 @@
1
-
2
1
  # """
3
2
  # This file contains a template for a remote machine. It is not meant to be run, but rather to be used as a template for
4
3
  # """
@@ -1,4 +1,3 @@
1
-
2
1
  # """
3
2
  # This module contains utility functions for the cluster module.
4
3
  # """
@@ -8,7 +7,7 @@
8
7
 
9
8
  # from machineconfig.cluster.remote_machine import WorkloadParams
10
9
  from typing import Optional
11
- from crocodile.file_management import P, PLike
10
+ from machineconfig.utils.path_reduced import PathExtended, PLike
12
11
 
13
12
  # def expensive_function(workload_params: WorkloadParams, sim_dict: Optional[dict[str, Any]] = None) -> P:
14
13
  # import time
@@ -38,12 +37,25 @@ from crocodile.file_management import P, PLike
38
37
  # return True
39
38
 
40
39
 
41
- def to_cloud(localpath: PLike, cloud: str, remotepath: Optional[PLike], zip: bool = False, encrypt: bool = False,
42
- key: Optional[bytes] = None, pwd: Optional[str] = None, rel2home: bool = False, strict: bool = True,
43
- obfuscate: bool = False,
44
- share: bool = False, verbose: bool = True, os_specific: bool = False, transfers: int = 10, root: Optional[str] = "myhome") -> 'P':
40
+ def to_cloud(
41
+ localpath: PLike,
42
+ cloud: str,
43
+ remotepath: Optional[PLike],
44
+ zip: bool = False,
45
+ encrypt: bool = False,
46
+ key: Optional[bytes] = None,
47
+ pwd: Optional[str] = None,
48
+ rel2home: bool = False,
49
+ strict: bool = True,
50
+ # obfuscate: bool = False,
51
+ share: bool = False,
52
+ verbose: bool = True,
53
+ os_specific: bool = False,
54
+ transfers: int = 10,
55
+ root: Optional[str] = "myhome",
56
+ ) -> "PathExtended":
45
57
  to_del = []
46
- localpath = P(localpath).expanduser().absolute() if not P(localpath).exists() else P(localpath)
58
+ localpath = PathExtended(localpath).expanduser().absolute() if not PathExtended(localpath).exists() else PathExtended(localpath)
47
59
  if zip:
48
60
  localpath = localpath.zip(inplace=False)
49
61
  to_del.append(localpath)
@@ -51,20 +63,24 @@ def to_cloud(localpath: PLike, cloud: str, remotepath: Optional[PLike], zip: boo
51
63
  localpath = localpath.encrypt(key=key, pwd=pwd, inplace=False)
52
64
  to_del.append(localpath)
53
65
  if remotepath is None:
54
- rp = localpath.get_remote_path(root=root, os_specific=os_specific, rel2home=rel2home, strict=strict, obfuscate=obfuscate) # if rel2home else (P(root) / localpath if root is not None else localpath)
55
- else: rp = P(remotepath)
66
+ rp = localpath.get_remote_path(root=root, os_specific=os_specific, rel2home=rel2home, strict=strict) # if rel2home else (P(root) / localpath if root is not None else localpath)
67
+ else:
68
+ rp = PathExtended(remotepath)
56
69
 
57
70
  from rclone_python import rclone
71
+
58
72
  rclone.copy(localpath.as_posix(), f"{cloud}:{rp.as_posix()}", show_progress=True)
59
73
 
60
74
  if share:
61
- if verbose: print("🔗 SHARING FILE")
75
+ if verbose:
76
+ print("🔗 SHARING FILE")
62
77
  tmp = rclone.link(f"{cloud}:{rp.as_posix()}")
63
- return P(tmp)
78
+ return PathExtended(tmp)
64
79
  return localpath
65
80
 
66
81
 
67
82
  if __name__ == "__main__":
68
83
  from pathlib import Path
84
+
69
85
  localpath = Path.home().joinpath("Downloads", "exchangeInfo")
70
86
  to_cloud(localpath, "odp", remotepath=None)
@@ -0,0 +1,16 @@
1
+ #!/bin/bash
2
+
3
+
4
+ npm install -g @google/gemini-cli
5
+ npm install -g @charmland/crush
6
+ npm install -g opencode-ai@latest
7
+
8
+ curl https://cursor.com/install -fsS | bash
9
+
10
+ cd $HOME/Downloads
11
+ curl --proto '=https' --tlsv1.2 -sSf "https://desktop-release.q.us-east-1.amazonaws.com/latest/q-x86_64-linux.zip" -o "q.zip"
12
+ unzip q.zip
13
+ ./q/install.sh # goes to ~/.local/bin.
14
+ rm q.zip
15
+ rm -rfd q
16
+
@@ -4,6 +4,7 @@
4
4
 
5
5
  # import time
6
6
  import platform
7
+
7
8
  # from typing import Any
8
9
  # from rich.console import Console
9
10
  # from machineconfig.utils.utils2 import pprint
@@ -24,7 +25,7 @@ APP_SUMMARY_PATH = LIBRARY_ROOT.joinpath(f"profile/records/{platform.system().lo
24
25
 
25
26
  # def scan(path: P, pct: float = 0.0):
26
27
  # import vt # vt-py
27
- # client = vt.Client(PathExtended.home().joinpath("dotfiles/creds/tokens/virustotal").read_text().split("\n")[0])
28
+ # client = vt.Client(PathExtended.home().joinpath("dotfiles/creds/tokens/virustotal").read_text(encoding="utf-8").split("\n")[0])
28
29
  # console = Console()
29
30
  # console.rule(f"Scanning {path}. {pct:.2f}% done")
30
31
  # if path.is_dir():
@@ -44,7 +45,7 @@ APP_SUMMARY_PATH = LIBRARY_ROOT.joinpath(f"profile/records/{platform.system().lo
44
45
  # raise ValueError(f"❌ Error in scanning {path}") from ex
45
46
  # print("⚠️ Error in scanning, trying again...")
46
47
  # time.sleep(30)
47
-
48
+
48
49
  # # Convert results to list of dictionaries
49
50
  # results_data = list(anal.results.values())
50
51
  # malicious = []
@@ -58,13 +59,13 @@ APP_SUMMARY_PATH = LIBRARY_ROOT.joinpath(f"profile/records/{platform.system().lo
58
59
  # 'result': getattr(result_item, 'result', None),
59
60
  # 'category': getattr(result_item, 'category', 'unknown')
60
61
  # }
61
-
62
- # if result_dict.get('result') is None and result_dict.get('category') in ["undetected", "type-unsupported", "failure", "timeout", "confirmed-timeout"]:
62
+
63
+ # if result_dict.get('result') is None and result_dict.get('category') in ["undetected", "type-unsupported", "failure", "timeout", "confirmed-timeout"]:
63
64
  # continue
64
65
  # else:
65
66
  # pprint(result_dict, f"🔍 Found Category {result_dict.get('category')}")
66
67
  # malicious.append(result_item)
67
-
68
+
68
69
  # positive_pct: float = round(number=len(malicious) / len(results_data) * 100, ndigits=1)
69
70
  # print(f"""
70
71
  # {'=' * 50}
@@ -101,10 +102,9 @@ APP_SUMMARY_PATH = LIBRARY_ROOT.joinpath(f"profile/records/{platform.system().lo
101
102
  # for an_app in apps_paths_tmp:
102
103
  # version_path = [x for x in versions_files_paths if x.stem == an_app.stem]
103
104
  # if len(version_path) == 1:
104
- # app_versions.append(version_path[0].read_text())
105
+ # app_versions.append(version_path[0].read_text(encoding="utf-8"))
105
106
  # apps_paths_raw.append(an_app)
106
107
  # # if an_app.stem in versions_files_paths.stem:
107
- # # app_versions.append(versions_files_paths.filter(lambda x: x.stem == an_app.stem.replace(".exe", "")).list[0].read_text())
108
108
  # # else:
109
109
  # # print(f"🤔 Cloud not find a documented version for installation of {an_app.stem}, trying to get it from the app itself.")
110
110
  # # tmp = Terminal().run(f"{an_app.stem} --version", shell="powershell").capture().op_if_successfull_or_default(strict_err=False, strict_returcode=False)
@@ -176,8 +176,8 @@ APP_SUMMARY_PATH = LIBRARY_ROOT.joinpath(f"profile/records/{platform.system().lo
176
176
  # return "\n".join([header, separator] + rows)
177
177
 
178
178
  # markdown_content = format_app_table_markdown(app_data)
179
- # APP_SUMMARY_PATH.with_suffix(".md").write_text(markdown_content)
180
-
179
+ # APP_SUMMARY_PATH.with_suffix(".md").write_text(markdown_content, encoding="utf-8")
180
+
181
181
  # print(f"""
182
182
  # {'=' * 150}
183
183
  # 📊 SAFETY REPORT | Summary of app scanning results
@@ -1,5 +1,3 @@
1
-
2
-
3
1
  # try ventory or netboot.xyz
4
2
 
5
3
  # # one can either install rufus: https://rufus.ie/en/
@@ -2,7 +2,7 @@
2
2
  cargo install
3
3
  """
4
4
 
5
- # from crocodile.meta import Terminal
5
+ # from machineconfig.utils.terminal import Terminal
6
6
  # from machineconfig.utils.path_reduced import P as PathExtended
7
7
  # import platform
8
8
 
@@ -27,7 +27,7 @@ cargo install
27
27
  # {'=' * 150}
28
28
  # """)
29
29
  # if platform.system() == "Windows":
30
- # Terminal(stdout=None).run(f". {PathExtended.tmpfile(suffix='.ps1').write_text(script)}", shell="pwsh").print()
30
+ # Terminal(stdout=None).run(f". {PathExtended.tmpfile(suffix='.ps1').write_text(script, encoding="utf-8")}", shell="pwsh").print()
31
31
  # else:
32
32
  # Terminal(stdout=None).run(script, shell="pwsh")
33
33
 
@@ -1,31 +1,29 @@
1
- """Symlinks
2
- """
1
+ """Symlinks"""
3
2
 
4
- from machineconfig.utils.path_reduced import P as PathExtended
3
+ from machineconfig.utils.path_reduced import PathExtended as PathExtended
5
4
  # from machineconfig.utils.utils import display_options
6
5
 
7
6
 
8
7
  def main():
9
8
  print(f"""
10
- {'=' * 150}
9
+ {"=" * 150}
11
10
  🔗 SYMLINK CREATOR | Create symlinks for virtual environments
12
- {'=' * 150}
11
+ {"=" * 150}
13
12
  """)
14
13
  target = PathExtended(input("🎯 Symlink to which target? ")).expanduser().absolute()
15
14
  source = input(f"📍 Symlink from which source? [default to: CWD/{target.name}] ") or PathExtended.cwd().joinpath(target.name)
16
- if isinstance(source, str): source = PathExtended(source).expanduser().absolute()
17
- # ve_path = display_options(msg="symlin link? ", options=PathExtended.home().joinpath("ve").starget.symlink_to; PathExtended(r'$pwd').joinpath('venv').symlink_to(r'$to'); PathExtended('.gitignore').modify_text('venv', 'venv', replace_line=True)"(target.symlink_to(
18
- # PathExtended('.gitignore').modify_text('venv', 'venv', replace_line=True)"
15
+ if isinstance(source, str):
16
+ source = PathExtended(source).expanduser().absolute()
19
17
  source.symlink_to(target, overwrite=True)
20
18
  print(f"""
21
- {'=' * 150}
19
+ {"=" * 150}
22
20
  ✅ SUCCESS | Symlink created successfully
23
21
  📍 Source: {source}
24
22
  🎯 Target: {target}
25
- {'=' * 150}
23
+ {"=" * 150}
26
24
  """)
27
25
  return "echo '🔗 Finished creating symlink.'"
28
26
 
29
27
 
30
- if __name__ == '__main__':
28
+ if __name__ == "__main__":
31
29
  pass
@@ -1,4 +1,3 @@
1
-
2
1
  from machineconfig.scripts.python.devops_backup_retrieve import main_backup_retrieve
3
2
 
4
3
  program = main_backup_retrieve(direction="BACKUP", which="all")
@@ -4,6 +4,7 @@ from machineconfig.utils.utils2 import randstr
4
4
 
5
5
  def open_file_in_new_instance(file_path: str):
6
6
  import git
7
+
7
8
  repo = git.Repo(search_parent_directories=True)
8
9
  repo_path = repo.working_tree_dir
9
10
  # Ensure repo_path is not None before passing to Path
@@ -19,13 +20,10 @@ code --profile bitProfile --new-window {file_path}
19
20
  from rich.console import Console
20
21
  from rich.syntax import Syntax
21
22
  from rich.panel import Panel
23
+
22
24
  console = Console()
23
25
  console.print(f"\n{'=' * 150}")
24
- console.print(Panel(
25
- Syntax(code, lexer="bash"),
26
- title="🔍 VS CODE API | Opening file in new instance",
27
- subtitle=f"📂 {file_path}"
28
- ), style="bold blue")
26
+ console.print(Panel(Syntax(code, lexer="bash"), title="🔍 VS CODE API | Opening file in new instance", subtitle=f"📂 {file_path}"), style="bold blue")
29
27
  console.print(f"{'=' * 150}\n")
30
28
 
31
29
  code_path = Path.home().joinpath(".config", "machingconfig", "vscode_api", "code_temp")
@@ -33,11 +31,13 @@ code --profile bitProfile --new-window {file_path}
33
31
  code_path.write_text(code, encoding="utf-8")
34
32
  code_path.chmod(0o755)
35
33
  import subprocess
34
+
36
35
  subprocess.run([str(code_path)], shell=True, check=True)
37
36
 
38
37
 
39
38
  def main():
40
39
  import argparse
40
+
41
41
  parser = argparse.ArgumentParser(description="Open file in new vscode instance")
42
42
  parser.add_argument("file_path", type=str, help="Path to the file to open")
43
43
  args = parser.parse_args()
@@ -1,5 +1,4 @@
1
- """VScode task to set interpreter
2
- """
1
+ """VScode task to set interpreter"""
3
2
 
4
3
  # import os
5
4
  # import json
@@ -10,51 +9,51 @@ import argparse
10
9
 
11
10
  def select_interpreter(workspace_root: str):
12
11
  print(f"""
13
- {'=' * 150}
12
+ {"=" * 150}
14
13
  🔗 VSCODE VE LINKER | Linking virtual environment for VS Code
15
14
  📂 Workspace: {workspace_root}
16
- {'=' * 150}
15
+ {"=" * 150}
17
16
  """)
18
-
19
- path = Path(workspace_root).joinpath('.ve_path')
20
-
17
+
18
+ path = Path(workspace_root).joinpath(".ve_path")
19
+
21
20
  if not path.exists():
22
21
  print(f"""
23
- {'⚠️' * 20}
22
+ {"⚠️" * 20}
24
23
  ❌ ERROR | Could not find .ve_path file in workspace
25
24
  📂 Expected at: {path}
26
- {'⚠️' * 20}
25
+ {"⚠️" * 20}
27
26
  """)
28
27
  return
29
-
30
- with open(path, 'r', encoding='utf-8') as f:
28
+
29
+ with open(path, "r", encoding="utf-8") as f:
31
30
  ve_path = Path(f.read().strip()).expanduser()
32
-
31
+
33
32
  venv_link = Path(workspace_root).joinpath(".venv")
34
-
33
+
35
34
  if venv_link.exists() and not venv_link.is_symlink():
36
35
  print(f"""
37
- {'⚠️' * 20}
36
+ {"⚠️" * 20}
38
37
  ❌ ERROR | .venv already exists and is not a symlink
39
38
  📂 Path: {venv_link}
40
- {'⚠️' * 20}
39
+ {"⚠️" * 20}
41
40
  """)
42
41
  return
43
-
42
+
44
43
  venv_link.symlink_to(target=ve_path.expanduser().absolute())
45
-
44
+
46
45
  print(f"""
47
- {'=' * 150}
46
+ {"=" * 150}
48
47
  ✅ SUCCESS | Virtual environment linked successfully
49
48
  🔗 Link: {venv_link}
50
49
  🎯 Target: {ve_path.expanduser().absolute()}
51
- {'=' * 150}
50
+ {"=" * 150}
52
51
  """)
53
52
 
54
53
 
55
54
  def main():
56
- parser = argparse.ArgumentParser(description='Link ve from repo to ve location.')
57
- parser.add_argument('workspace_path', type=str, help='The workspace path')
55
+ parser = argparse.ArgumentParser(description="Link ve from repo to ve location.")
56
+ parser.add_argument("workspace_path", type=str, help="The workspace path")
58
57
 
59
58
  args = parser.parse_args()
60
59
  select_interpreter(args.workspace_path)
@@ -1,5 +1,4 @@
1
- """VScode task to set interpreter
2
- """
1
+ """VScode task to set interpreter"""
3
2
 
4
3
  # import os
5
4
  # import json
@@ -12,73 +11,73 @@ import platform
12
11
 
13
12
  def select_interpreter(workspace_root: str):
14
13
  print(f"""
15
- {'=' * 150}
14
+ {"=" * 150}
16
15
  🐍 PYTHON INTERPRETER | Setting up VS Code Python interpreter
17
16
  📂 Workspace: {workspace_root}
18
- {'=' * 150}
17
+ {"=" * 150}
19
18
  """)
20
-
21
- path = Path(workspace_root).joinpath('.ve_path')
19
+
20
+ path = Path(workspace_root).joinpath(".ve_path")
22
21
  if not path.exists():
23
22
  print(f"""
24
- {'⚠️' * 20}
23
+ {"⚠️" * 20}
25
24
  ❌ ERROR | Could not find .ve_path file in workspace
26
25
  📂 Expected at: {path}
27
- {'⚠️' * 20}
26
+ {"⚠️" * 20}
28
27
  """)
29
28
  return
30
-
31
- with open(path, 'r', encoding='utf-8') as f:
29
+
30
+ with open(path, "r", encoding="utf-8") as f:
32
31
  python_path = Path(f.read().strip()).expanduser()
33
-
32
+
34
33
  print(f"📁 Virtual environment path: {python_path}")
35
34
 
36
- if platform.system() == 'Windows':
37
- python_path = python_path.joinpath('Scripts', 'python.exe')
38
- elif platform.system() == 'Linux':
39
- python_path = python_path.joinpath('bin', 'python')
40
- elif platform.system() == 'Darwin':
41
- python_path = python_path.joinpath('bin', 'python')
35
+ if platform.system() == "Windows":
36
+ python_path = python_path.joinpath("Scripts", "python.exe")
37
+ elif platform.system() == "Linux":
38
+ python_path = python_path.joinpath("bin", "python")
39
+ elif platform.system() == "Darwin":
40
+ python_path = python_path.joinpath("bin", "python")
42
41
  else:
43
42
  error_msg = f"Unsupported platform: {platform.system()}"
44
43
  print(f"""
45
- {'⚠️' * 20}
44
+ {"⚠️" * 20}
46
45
  ❌ ERROR | {error_msg}
47
- {'⚠️' * 20}
46
+ {"⚠️" * 20}
48
47
  """)
49
48
  raise NotImplementedError(error_msg)
50
49
 
51
50
  print(f"🔍 Python interpreter path: {python_path}")
52
-
51
+
53
52
  # tmp = os.getenv('APPDATA')
54
53
  # assert tmp is not None
55
54
  # settings_path = Path(tmp).joinpath('Code', 'User', 'settings.json')
56
- work_space_settings = Path(workspace_root).joinpath('.vscode', 'settings.json')
55
+ work_space_settings = Path(workspace_root).joinpath(".vscode", "settings.json")
57
56
  work_space_settings.parent.mkdir(parents=True, exist_ok=True)
58
57
  if not work_space_settings.exists():
59
58
  print(f"📄 Creating new settings file: {work_space_settings}")
60
59
  work_space_settings.parent.mkdir(parents=True, exist_ok=True)
61
60
  work_space_settings.touch()
62
- work_space_settings.write_text("{}")
61
+ work_space_settings.write_text("{}", encoding="utf-8")
63
62
  else:
64
63
  print(f"📄 Updating existing settings file: {work_space_settings}")
65
-
64
+
66
65
  settings = read_json(work_space_settings)
67
- settings['python.defaultInterpreterPath'] = str(python_path)
66
+ settings["python.defaultInterpreterPath"] = str(python_path)
68
67
  save_json(obj=settings, path=str(work_space_settings), indent=4)
69
-
68
+
70
69
  print(f"""
71
- {'=' * 150}
70
+ {"=" * 150}
72
71
  ✅ SUCCESS | Python interpreter configured successfully
73
72
  🐍 Interpreter: {python_path}
74
73
  📄 Settings: {work_space_settings}
75
- {'=' * 150}
74
+ {"=" * 150}
76
75
  """)
77
76
 
78
77
 
79
78
  def main():
80
- parser = argparse.ArgumentParser(description='Set Python Interpretor in VSCode settings.')
81
- parser.add_argument('workspace_path', type=str, help='The workspace path')
79
+ parser = argparse.ArgumentParser(description="Set Python Interpretor in VSCode settings.")
80
+ parser.add_argument("workspace_path", type=str, help="The workspace path")
82
81
 
83
82
  args = parser.parse_args()
84
83
  select_interpreter(args.workspace_path)
@@ -7,29 +7,29 @@ config = read_ini(Path.home().joinpath(".ssh", "config"))
7
7
 
8
8
  def sync_remote(machine_name: str):
9
9
  print(f"""
10
- {'=' * 150}
10
+ {"=" * 150}
11
11
  🔄 SYNC REMOTE | Initiating remote code synchronization
12
12
  🖥️ Target machine: {machine_name}
13
- {'=' * 150}
13
+ {"=" * 150}
14
14
  """)
15
-
15
+
16
16
  # Handle config as a ConfigParser object
17
17
  machine_config: SectionProxy | None = None
18
18
  if machine_name in config:
19
19
  machine_config = config[machine_name]
20
-
20
+
21
21
  if machine_config is None:
22
22
  error_msg = f"Machine {machine_name} not found in SSH config."
23
23
  print(f"""
24
- {'⚠️' * 20}
24
+ {"⚠️" * 20}
25
25
  ❌ ERROR | {error_msg}
26
- {'⚠️' * 20}
26
+ {"⚠️" * 20}
27
27
  """)
28
28
  raise ValueError(error_msg)
29
29
 
30
30
  # this is template: code = """ssh -o "HostName=zgeby8zhe6ipftpad.alexsaffar.com" -o "User=alex" -o "ProxyCommand=cloudflared access ssh --hostname %h" -o "Port=443" -o "RequestTTY=yes" -o "RemoteCommand=bash ~/scripts/z_ls --attach; bash" tpadCF"""
31
31
  code = f"""
32
- ssh -o "HostName={machine_config['HostName']}" -o "User={machine_config['User']}" -o "ProxyCommand=cloudflared access ssh --hostname %h" -o "Port={machine_config['Port']}" -o "RequestTTY=yes" -o "RemoteCommand=devops --which update; bash" {machine_name}
32
+ ssh -o "HostName={machine_config["HostName"]}" -o "User={machine_config["User"]}" -o "ProxyCommand=cloudflared access ssh --hostname %h" -o "Port={machine_config["Port"]}" -o "RequestTTY=yes" -o "RemoteCommand=devops --which update; bash" {machine_name}
33
33
  """
34
34
  from rich.console import Console
35
35
  from rich.syntax import Syntax
@@ -37,27 +37,23 @@ ssh -o "HostName={machine_config['HostName']}" -o "User={machine_config['User']}
37
37
 
38
38
  console = Console()
39
39
  console.print(f"\n{'=' * 150}")
40
- console.print(Panel(
41
- Syntax(code, lexer="bash"),
42
- title=f"🔄 SYNC COMMAND | Connecting to {machine_name}",
43
- subtitle=f"🌐 Host: {machine_config['HostName']}"
44
- ), style="bold blue")
40
+ console.print(Panel(Syntax(code, lexer="bash"), title=f"🔄 SYNC COMMAND | Connecting to {machine_name}", subtitle=f"🌐 Host: {machine_config['HostName']}"), style="bold blue")
45
41
  console.print(f"{'=' * 150}\n")
46
42
 
47
43
  code_path = Path.home().joinpath(".config", "machingconfig", "vscode_api", "code_temp")
48
44
  code_path.parent.mkdir(parents=True, exist_ok=True)
49
45
  code_path.write_text(code, encoding="utf-8")
50
46
  code_path.chmod(0o755)
51
-
47
+
52
48
  print(f"🚀 Executing sync command for {machine_name}...")
53
-
49
+
54
50
  import subprocess
51
+
55
52
  subprocess.run([str(code_path)], shell=True, check=True)
56
-
53
+
57
54
  print(f"""
58
- {'=' * 150}
55
+ {"=" * 150}
59
56
  ✅ SUCCESS | Remote sync completed successfully
60
57
  🖥️ Machine: {machine_name}
61
- {'=' * 150}
58
+ {"=" * 150}
62
59
  """)
63
-
@@ -8,23 +8,23 @@ from typing import Optional
8
8
 
9
9
 
10
10
  config_dict = {
11
- "repo_url": "CUSTOM",
12
- "doc": "ngrok secure introspectable tunnels to localhost",
13
- "filename_template_windows_amd_64": "ngrok-stable-windows-amd64.zip",
14
- "filename_template_linux_amd_64": "ngrok-stable-linux-amd64.zip",
15
- "strip_v": False,
16
- "exe_name": "ngrok"
17
- }
11
+ "repo_url": "CUSTOM",
12
+ "doc": "ngrok secure introspectable tunnels to localhost",
13
+ "filename_template_windows_amd_64": "ngrok-stable-windows-amd64.zip",
14
+ "filename_template_linux_amd_64": "ngrok-stable-linux-amd64.zip",
15
+ "strip_v": False,
16
+ "exe_name": "ngrok",
17
+ }
18
18
 
19
19
 
20
20
  def main(version: Optional[str]):
21
21
  print(f"""
22
- {'=' * 150}
22
+ {"=" * 150}
23
23
  🔄 NGROK INSTALLER | Setting up secure tunnels to localhost
24
24
  💻 Platform: {platform.system()}
25
- {'=' * 150}
25
+ {"=" * 150}
26
26
  """)
27
-
27
+
28
28
  _ = version
29
29
  if platform.system() == "Windows":
30
30
  print("🪟 Installing ngrok using winget on Windows...")
@@ -43,17 +43,17 @@ sudo nala update && sudo nala install ngrok
43
43
  else:
44
44
  error_msg = f"Unsupported platform: {platform.system()}"
45
45
  print(f"""
46
- {'⚠️' * 20}
46
+ {"⚠️" * 20}
47
47
  ❌ ERROR | {error_msg}
48
- {'⚠️' * 20}
48
+ {"⚠️" * 20}
49
49
  """)
50
50
  raise NotImplementedError(error_msg)
51
-
51
+
52
52
  print(f"""
53
- {'=' * 150}
53
+ {"=" * 150}
54
54
  ⚠️ SECURITY WARNING | ngrok has been flagged by some antivirus engines
55
55
  🛡️ Use at your own risk - flagged by 35% of antivirus engines
56
- {'=' * 150}
56
+ {"=" * 150}
57
57
  """)
58
58
  return program
59
59