machineconfig 1.96__py3-none-any.whl → 2.0__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 (164) hide show
  1. machineconfig/cluster/cloud_manager.py +22 -26
  2. machineconfig/cluster/data_transfer.py +2 -2
  3. machineconfig/cluster/distribute.py +0 -2
  4. machineconfig/cluster/file_manager.py +4 -4
  5. machineconfig/cluster/job_params.py +1 -1
  6. machineconfig/cluster/loader_runner.py +8 -8
  7. machineconfig/cluster/remote_machine.py +4 -4
  8. machineconfig/cluster/script_execution.py +2 -2
  9. machineconfig/cluster/sessions_managers/archive/create_zellij_template.py +1 -1
  10. machineconfig/cluster/sessions_managers/enhanced_command_runner.py +23 -23
  11. machineconfig/cluster/sessions_managers/wt_local.py +78 -76
  12. machineconfig/cluster/sessions_managers/wt_local_manager.py +91 -91
  13. machineconfig/cluster/sessions_managers/wt_remote.py +39 -39
  14. machineconfig/cluster/sessions_managers/wt_remote_manager.py +94 -91
  15. machineconfig/cluster/sessions_managers/wt_utils/layout_generator.py +56 -54
  16. machineconfig/cluster/sessions_managers/wt_utils/process_monitor.py +49 -49
  17. machineconfig/cluster/sessions_managers/wt_utils/remote_executor.py +18 -18
  18. machineconfig/cluster/sessions_managers/wt_utils/session_manager.py +42 -42
  19. machineconfig/cluster/sessions_managers/wt_utils/status_reporter.py +36 -36
  20. machineconfig/cluster/sessions_managers/zellij_local.py +43 -46
  21. machineconfig/cluster/sessions_managers/zellij_local_manager.py +139 -120
  22. machineconfig/cluster/sessions_managers/zellij_remote.py +35 -35
  23. machineconfig/cluster/sessions_managers/zellij_remote_manager.py +33 -33
  24. machineconfig/cluster/sessions_managers/zellij_utils/example_usage.py +15 -15
  25. machineconfig/cluster/sessions_managers/zellij_utils/layout_generator.py +25 -26
  26. machineconfig/cluster/sessions_managers/zellij_utils/process_monitor.py +49 -49
  27. machineconfig/cluster/sessions_managers/zellij_utils/remote_executor.py +5 -5
  28. machineconfig/cluster/sessions_managers/zellij_utils/session_manager.py +15 -15
  29. machineconfig/cluster/sessions_managers/zellij_utils/status_reporter.py +11 -11
  30. machineconfig/cluster/templates/utils.py +3 -3
  31. machineconfig/jobs/__pycache__/__init__.cpython-311.pyc +0 -0
  32. machineconfig/jobs/python/__pycache__/__init__.cpython-311.pyc +0 -0
  33. machineconfig/jobs/python/__pycache__/python_ve_symlink.cpython-311.pyc +0 -0
  34. machineconfig/jobs/python/check_installations.py +8 -9
  35. machineconfig/jobs/python/python_cargo_build_share.py +2 -2
  36. machineconfig/jobs/python/vscode/link_ve.py +7 -7
  37. machineconfig/jobs/python/vscode/select_interpreter.py +7 -7
  38. machineconfig/jobs/python/vscode/sync_code.py +5 -5
  39. machineconfig/jobs/python_custom_installers/archive/ngrok.py +2 -2
  40. machineconfig/jobs/python_custom_installers/dev/aider.py +3 -3
  41. machineconfig/jobs/python_custom_installers/dev/alacritty.py +3 -3
  42. machineconfig/jobs/python_custom_installers/dev/brave.py +3 -3
  43. machineconfig/jobs/python_custom_installers/dev/bypass_paywall.py +5 -5
  44. machineconfig/jobs/python_custom_installers/dev/code.py +3 -3
  45. machineconfig/jobs/python_custom_installers/dev/cursor.py +9 -9
  46. machineconfig/jobs/python_custom_installers/dev/docker_desktop.py +4 -4
  47. machineconfig/jobs/python_custom_installers/dev/espanso.py +4 -4
  48. machineconfig/jobs/python_custom_installers/dev/goes.py +4 -4
  49. machineconfig/jobs/python_custom_installers/dev/lvim.py +4 -4
  50. machineconfig/jobs/python_custom_installers/dev/nerdfont.py +3 -3
  51. machineconfig/jobs/python_custom_installers/dev/redis.py +3 -3
  52. machineconfig/jobs/python_custom_installers/dev/wezterm.py +3 -3
  53. machineconfig/jobs/python_custom_installers/dev/winget.py +27 -27
  54. machineconfig/jobs/python_custom_installers/docker.py +3 -3
  55. machineconfig/jobs/python_custom_installers/gh.py +7 -7
  56. machineconfig/jobs/python_custom_installers/hx.py +1 -1
  57. machineconfig/jobs/python_custom_installers/warp-cli.py +3 -3
  58. machineconfig/jobs/python_generic_installers/config.json +412 -389
  59. machineconfig/jobs/python_windows_installers/dev/config.json +1 -1
  60. machineconfig/logger.py +50 -0
  61. machineconfig/profile/__pycache__/__init__.cpython-311.pyc +0 -0
  62. machineconfig/profile/__pycache__/create.cpython-311.pyc +0 -0
  63. machineconfig/profile/__pycache__/shell.cpython-311.pyc +0 -0
  64. machineconfig/profile/create.py +23 -16
  65. machineconfig/profile/create_hardlinks.py +8 -8
  66. machineconfig/profile/shell.py +41 -37
  67. machineconfig/scripts/__pycache__/__init__.cpython-311.pyc +0 -0
  68. machineconfig/scripts/__pycache__/__init__.cpython-313.pyc +0 -0
  69. machineconfig/scripts/linux/devops +2 -2
  70. machineconfig/scripts/linux/fire +1 -0
  71. machineconfig/scripts/linux/fire_agents +0 -1
  72. machineconfig/scripts/linux/mcinit +27 -0
  73. machineconfig/scripts/python/__pycache__/__init__.cpython-311.pyc +0 -0
  74. machineconfig/scripts/python/__pycache__/__init__.cpython-313.pyc +0 -0
  75. machineconfig/scripts/python/__pycache__/croshell.cpython-311.pyc +0 -0
  76. machineconfig/scripts/python/__pycache__/devops.cpython-311.pyc +0 -0
  77. machineconfig/scripts/python/__pycache__/devops.cpython-313.pyc +0 -0
  78. machineconfig/scripts/python/__pycache__/devops_update_repos.cpython-311.pyc +0 -0
  79. machineconfig/scripts/python/__pycache__/devops_update_repos.cpython-313.pyc +0 -0
  80. machineconfig/scripts/python/__pycache__/fire_agents.cpython-311.pyc +0 -0
  81. machineconfig/scripts/python/__pycache__/fire_jobs.cpython-311.pyc +0 -0
  82. machineconfig/scripts/python/__pycache__/repos.cpython-311.pyc +0 -0
  83. machineconfig/scripts/python/ai/__pycache__/init.cpython-311.pyc +0 -0
  84. machineconfig/scripts/python/ai/__pycache__/mcinit.cpython-311.pyc +0 -0
  85. machineconfig/scripts/python/ai/chatmodes/Thinking-Beast-Mode.chatmode.md +337 -0
  86. machineconfig/scripts/python/ai/chatmodes/Ultimate-Transparent-Thinking-Beast-Mode.chatmode.md +644 -0
  87. machineconfig/scripts/python/ai/chatmodes/deepResearch.chatmode.md +81 -0
  88. machineconfig/scripts/python/ai/configs/.gemini/settings.json +81 -0
  89. machineconfig/scripts/python/ai/instructions/python/dev.instructions.md +45 -0
  90. machineconfig/scripts/python/ai/mcinit.py +103 -0
  91. machineconfig/scripts/python/ai/prompts/allLintersAndTypeCheckers.prompt.md +5 -0
  92. machineconfig/scripts/python/ai/prompts/research-report-skeleton.prompt.md +38 -0
  93. machineconfig/scripts/python/ai/scripts/lint_and_type_check.sh +47 -0
  94. machineconfig/scripts/python/archive/tmate_conn.py +5 -5
  95. machineconfig/scripts/python/archive/tmate_start.py +3 -3
  96. machineconfig/scripts/python/choose_wezterm_theme.py +2 -2
  97. machineconfig/scripts/python/cloud_copy.py +19 -18
  98. machineconfig/scripts/python/cloud_mount.py +9 -7
  99. machineconfig/scripts/python/cloud_repo_sync.py +11 -11
  100. machineconfig/scripts/python/cloud_sync.py +1 -1
  101. machineconfig/scripts/python/croshell.py +14 -14
  102. machineconfig/scripts/python/devops.py +6 -6
  103. machineconfig/scripts/python/devops_add_identity.py +8 -6
  104. machineconfig/scripts/python/devops_add_ssh_key.py +18 -18
  105. machineconfig/scripts/python/devops_backup_retrieve.py +13 -13
  106. machineconfig/scripts/python/devops_devapps_install.py +3 -3
  107. machineconfig/scripts/python/devops_update_repos.py +1 -1
  108. machineconfig/scripts/python/dotfile.py +2 -2
  109. machineconfig/scripts/python/fire_agents.py +183 -41
  110. machineconfig/scripts/python/fire_jobs.py +17 -11
  111. machineconfig/scripts/python/ftpx.py +2 -2
  112. machineconfig/scripts/python/gh_models.py +94 -94
  113. machineconfig/scripts/python/helpers/__pycache__/__init__.cpython-311.pyc +0 -0
  114. machineconfig/scripts/python/helpers/__pycache__/cloud_helpers.cpython-311.pyc +0 -0
  115. machineconfig/scripts/python/helpers/__pycache__/helpers2.cpython-311.pyc +0 -0
  116. machineconfig/scripts/python/helpers/__pycache__/helpers4.cpython-311.pyc +0 -0
  117. machineconfig/scripts/python/helpers/cloud_helpers.py +3 -3
  118. machineconfig/scripts/python/helpers/helpers2.py +1 -1
  119. machineconfig/scripts/python/helpers/helpers4.py +8 -6
  120. machineconfig/scripts/python/helpers/helpers5.py +7 -7
  121. machineconfig/scripts/python/helpers/repo_sync_helpers.py +1 -1
  122. machineconfig/scripts/python/mount_nfs.py +3 -2
  123. machineconfig/scripts/python/mount_nw_drive.py +4 -4
  124. machineconfig/scripts/python/mount_ssh.py +3 -2
  125. machineconfig/scripts/python/repos.py +8 -8
  126. machineconfig/scripts/python/scheduler.py +1 -1
  127. machineconfig/scripts/python/start_slidev.py +8 -7
  128. machineconfig/scripts/python/start_terminals.py +1 -1
  129. machineconfig/scripts/python/viewer.py +40 -40
  130. machineconfig/scripts/python/wifi_conn.py +65 -66
  131. machineconfig/scripts/python/wsl_windows_transfer.py +1 -1
  132. machineconfig/scripts/windows/mcinit.ps1 +4 -0
  133. machineconfig/settings/linters/.ruff.toml +2 -2
  134. machineconfig/settings/shells/ipy/profiles/default/startup/playext.py +71 -71
  135. machineconfig/settings/shells/wt/settings.json +8 -8
  136. machineconfig/setup_linux/web_shortcuts/tmp.sh +2 -0
  137. machineconfig/setup_windows/wt_and_pwsh/set_pwsh_theme.py +10 -7
  138. machineconfig/setup_windows/wt_and_pwsh/set_wt_settings.py +9 -7
  139. machineconfig/utils/ai/browser_user_wrapper.py +5 -5
  140. machineconfig/utils/ai/generate_file_checklist.py +11 -12
  141. machineconfig/utils/ai/url2md.py +1 -1
  142. machineconfig/utils/cloud/onedrive/setup_oauth.py +4 -4
  143. machineconfig/utils/cloud/onedrive/transaction.py +129 -129
  144. machineconfig/utils/code.py +13 -6
  145. machineconfig/utils/installer.py +51 -53
  146. machineconfig/utils/installer_utils/installer_abc.py +21 -10
  147. machineconfig/utils/installer_utils/installer_class.py +42 -16
  148. machineconfig/utils/io_save.py +3 -15
  149. machineconfig/utils/options.py +10 -3
  150. machineconfig/utils/path.py +5 -0
  151. machineconfig/utils/path_reduced.py +201 -149
  152. machineconfig/utils/procs.py +23 -23
  153. machineconfig/utils/scheduling.py +11 -12
  154. machineconfig/utils/ssh.py +270 -0
  155. machineconfig/utils/terminal.py +180 -0
  156. machineconfig/utils/utils.py +1 -2
  157. machineconfig/utils/utils2.py +43 -0
  158. machineconfig/utils/utils5.py +163 -34
  159. machineconfig/utils/ve.py +2 -2
  160. {machineconfig-1.96.dist-info → machineconfig-2.0.dist-info}/METADATA +13 -8
  161. {machineconfig-1.96.dist-info → machineconfig-2.0.dist-info}/RECORD +163 -144
  162. machineconfig/cluster/self_ssh.py +0 -57
  163. {machineconfig-1.96.dist-info → machineconfig-2.0.dist-info}/WHEEL +0 -0
  164. {machineconfig-1.96.dist-info → machineconfig-2.0.dist-info}/top_level.txt +0 -0
@@ -17,7 +17,7 @@ def select_interpreter(workspace_root: str):
17
17
  📂 Workspace: {workspace_root}
18
18
  {'=' * 150}
19
19
  """)
20
-
20
+
21
21
  path = Path(workspace_root).joinpath('.ve_path')
22
22
  if not path.exists():
23
23
  print(f"""
@@ -27,10 +27,10 @@ def select_interpreter(workspace_root: str):
27
27
  {'⚠️' * 20}
28
28
  """)
29
29
  return
30
-
30
+
31
31
  with open(path, 'r', encoding='utf-8') as f:
32
32
  python_path = Path(f.read().strip()).expanduser()
33
-
33
+
34
34
  print(f"📁 Virtual environment path: {python_path}")
35
35
 
36
36
  if platform.system() == 'Windows':
@@ -49,7 +49,7 @@ def select_interpreter(workspace_root: str):
49
49
  raise NotImplementedError(error_msg)
50
50
 
51
51
  print(f"🔍 Python interpreter path: {python_path}")
52
-
52
+
53
53
  # tmp = os.getenv('APPDATA')
54
54
  # assert tmp is not None
55
55
  # settings_path = Path(tmp).joinpath('Code', 'User', 'settings.json')
@@ -59,14 +59,14 @@ def select_interpreter(workspace_root: str):
59
59
  print(f"📄 Creating new settings file: {work_space_settings}")
60
60
  work_space_settings.parent.mkdir(parents=True, exist_ok=True)
61
61
  work_space_settings.touch()
62
- work_space_settings.write_text("{}")
62
+ work_space_settings.write_text("{}", encoding="utf-8")
63
63
  else:
64
64
  print(f"📄 Updating existing settings file: {work_space_settings}")
65
-
65
+
66
66
  settings = read_json(work_space_settings)
67
67
  settings['python.defaultInterpreterPath'] = str(python_path)
68
68
  save_json(obj=settings, path=str(work_space_settings), indent=4)
69
-
69
+
70
70
  print(f"""
71
71
  {'=' * 150}
72
72
  ✅ SUCCESS | Python interpreter configured successfully
@@ -12,12 +12,12 @@ def sync_remote(machine_name: str):
12
12
  🖥️ Target machine: {machine_name}
13
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"""
@@ -48,12 +48,12 @@ ssh -o "HostName={machine_config['HostName']}" -o "User={machine_config['User']}
48
48
  code_path.parent.mkdir(parents=True, exist_ok=True)
49
49
  code_path.write_text(code, encoding="utf-8")
50
50
  code_path.chmod(0o755)
51
-
51
+
52
52
  print(f"🚀 Executing sync command for {machine_name}...")
53
-
53
+
54
54
  import subprocess
55
55
  subprocess.run([str(code_path)], shell=True, check=True)
56
-
56
+
57
57
  print(f"""
58
58
  {'=' * 150}
59
59
  ✅ SUCCESS | Remote sync completed successfully
@@ -24,7 +24,7 @@ def main(version: Optional[str]):
24
24
  💻 Platform: {platform.system()}
25
25
  {'=' * 150}
26
26
  """)
27
-
27
+
28
28
  _ = version
29
29
  if platform.system() == "Windows":
30
30
  print("🪟 Installing ngrok using winget on Windows...")
@@ -48,7 +48,7 @@ sudo nala update && sudo nala install ngrok
48
48
  {'⚠️' * 20}
49
49
  """)
50
50
  raise NotImplementedError(error_msg)
51
-
51
+
52
52
  print(f"""
53
53
  {'=' * 150}
54
54
  ⚠️ SECURITY WARNING | ngrok has been flagged by some antivirus engines
@@ -19,16 +19,16 @@ def main(version: Optional[str] = None):
19
19
  🔄 Version: {'latest' if version is None else version}
20
20
  {'=' * 150}
21
21
  """)
22
-
22
+
23
23
  install_script = "uv tool install --force --python python3.12 aider-chat@latest"
24
-
24
+
25
25
  print(f"""
26
26
  {'=' * 150}
27
27
  ✅ SUCCESS | Installation command prepared:
28
28
  📄 Command: {install_script}
29
29
  {'=' * 150}
30
30
  """)
31
-
31
+
32
32
  return install_script
33
33
 
34
34
 
@@ -23,7 +23,7 @@ def main(version: Optional[str]):
23
23
  🔄 Version: {'latest' if version is None else version}
24
24
  {'=' * 150}
25
25
  """)
26
-
26
+
27
27
  _ = version
28
28
  if platform.system() == "Windows":
29
29
  print("🪟 Installing Alacritty on Windows using Cargo...")
@@ -53,7 +53,7 @@ git clone https://github.com/alacritty/alacritty-theme ~/.config/alacritty/theme
53
53
  {'⚠️' * 20}
54
54
  """)
55
55
  raise NotImplementedError(error_msg)
56
-
56
+
57
57
  print(f"""
58
58
  {'=' * 150}
59
59
  ℹ️ INFO | Installation will proceed with the following steps:
@@ -62,7 +62,7 @@ git clone https://github.com/alacritty/alacritty-theme ~/.config/alacritty/theme
62
62
  3️⃣ Clone theme repository
63
63
  {'=' * 150}
64
64
  """)
65
-
65
+
66
66
  # _res = Terminal(stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE).run_script(script=program, shell="default").print(desc="Running custom installer", capture=True)
67
67
  # run script here as it requires user input
68
68
  return program
@@ -24,7 +24,7 @@ def main(version: Optional[str]):
24
24
  🔄 Version: {'latest' if version is None else version}
25
25
  {'=' * 150}
26
26
  """)
27
-
27
+
28
28
  _ = version
29
29
  if platform.system() == "Windows":
30
30
  print("🪟 Installing Brave Browser on Windows using winget...")
@@ -50,7 +50,7 @@ winget install --Name "Brave Browser" --Id Brave.Brave --source winget --accept-
50
50
  {'⚠️' * 20}
51
51
  """)
52
52
  raise NotImplementedError(error_msg)
53
-
53
+
54
54
  print(f"""
55
55
  {'=' * 150}
56
56
  ℹ️ INFO | Brave Browser features:
@@ -60,7 +60,7 @@ winget install --Name "Brave Browser" --Id Brave.Brave --source winget --accept-
60
60
  🪙 Optional crypto rewards
61
61
  {'=' * 150}
62
62
  """)
63
-
63
+
64
64
  # _res = Terminal(stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE).run_script(script=program, shell="default").print(desc="Running custom installer", capture=True)
65
65
  # run script here as it requires user input
66
66
  return program
@@ -22,26 +22,26 @@ def main(version: Optional[str] = None):
22
22
  🔄 Version: {'latest' if version is None else version}
23
23
  {'=' * 150}
24
24
  """)
25
-
25
+
26
26
  _ = version
27
27
  # see remove paywalls and enhance YT experience by Chris Titus
28
28
  folder = r"C:\\"
29
-
29
+
30
30
  print("📥 Downloading extension from GitHub repository...")
31
31
  PathExtended("https://github.com/iamadamdev/bypass-paywalls-chrome/archive/master.zip").download().unzip(folder=folder, content=True)
32
32
  extension_folder = PathExtended(folder).joinpath("bypass-paywalls-chrome-master")
33
-
33
+
34
34
  print(f"""
35
35
  {'=' * 150}
36
36
  ✅ SUCCESS | Extension downloaded successfully
37
37
  📂 Location: {extension_folder}
38
- ℹ️ Next steps:
38
+ ℹ️ Next steps:
39
39
  1️⃣ Open Chrome and navigate to chrome://extensions
40
40
  2️⃣ Enable Developer Mode (toggle in top right)
41
41
  3️⃣ Click "Load unpacked" and select the extension folder
42
42
  {'=' * 150}
43
43
  """)
44
-
44
+
45
45
  return ""
46
46
 
47
47
 
@@ -43,9 +43,9 @@ def main(version: Optional[str] = None):
43
43
  {'⚠️' * 20}
44
44
  """)
45
45
  raise NotImplementedError(error_msg)
46
-
46
+
47
47
  _ = version
48
-
48
+
49
49
  print(f"""
50
50
  {'=' * 150}
51
51
  ℹ️ INFO | VS Code features:
@@ -56,7 +56,7 @@ def main(version: Optional[str] = None):
56
56
  ⚙️ Highly customizable
57
57
  {'=' * 150}
58
58
  """)
59
-
59
+
60
60
  return install_script
61
61
 
62
62
 
@@ -66,7 +66,7 @@ def install_windows(version: Optional[str] = None):
66
66
  _ = version
67
67
  home = Path.home()
68
68
  downloads_dir = home / "Downloads"
69
-
69
+
70
70
  # Search for Cursor installer in Downloads
71
71
  cursor_installer = None
72
72
  for pattern in ["**/Cursor*.exe", "**/cursor*.exe"]:
@@ -74,16 +74,16 @@ def install_windows(version: Optional[str] = None):
74
74
  if found:
75
75
  cursor_installer = found[0]
76
76
  break
77
-
77
+
78
78
  if cursor_installer is None:
79
79
  raise FileNotFoundError("Cursor installer (.exe) not found in Downloads folder.")
80
-
80
+
81
81
  print(f"Cursor installer found: {cursor_installer}")
82
-
82
+
83
83
  # Run the installer silently
84
84
  try:
85
85
  print("Running Cursor installer...")
86
- subprocess.run([str(cursor_installer), "/SILENT"],
86
+ subprocess.run([str(cursor_installer), "/SILENT"],
87
87
  capture_output=True, text=True, check=True)
88
88
  print("Cursor installer completed successfully.")
89
89
  except subprocess.CalledProcessError as e:
@@ -92,7 +92,7 @@ def install_windows(version: Optional[str] = None):
92
92
  # Try alternative silent install flags
93
93
  try:
94
94
  print("Trying alternative silent install...")
95
- subprocess.run([str(cursor_installer), "/S"],
95
+ subprocess.run([str(cursor_installer), "/S"],
96
96
  capture_output=True, text=True, check=True)
97
97
  print("Cursor installer completed successfully with /S flag.")
98
98
  except subprocess.CalledProcessError as e2:
@@ -101,21 +101,21 @@ def install_windows(version: Optional[str] = None):
101
101
  # If silent install fails, run normally and let user handle it
102
102
  print("Running installer in normal mode (user interaction required)...")
103
103
  subprocess.run([str(cursor_installer)])
104
-
104
+
105
105
  # Clean up installer file
106
106
  try:
107
107
  cursor_installer.unlink()
108
108
  print(f"Installer file removed: {cursor_installer}")
109
109
  except OSError as e:
110
110
  print(f"Warning: Could not remove installer file: {e}")
111
-
111
+
112
112
  print("Cursor installation completed. Check your Start Menu or Desktop for Cursor.")
113
113
 
114
114
 
115
115
  def main(version: Optional[str] = None):
116
116
  """Main installation function that handles both Linux and Windows."""
117
117
  system = platform.system()
118
-
118
+
119
119
  if system == "Linux":
120
120
  install_linux(version)
121
121
  elif system == "Windows":
@@ -31,9 +31,9 @@ def main(version: Optional[str]):
31
31
  📚 Source: https://docs.docker.com/desktop/install/ubuntu/
32
32
  {'=' * 150}
33
33
  """)
34
-
34
+
35
35
  _ = version
36
-
36
+
37
37
  print("""
38
38
  📋 Installation steps:
39
39
  1️⃣ Adding Docker's official GPG key
@@ -41,7 +41,7 @@ def main(version: Optional[str]):
41
41
  3️⃣ Updating package lists
42
42
  4️⃣ Installing Docker components
43
43
  """)
44
-
44
+
45
45
  code = """
46
46
  # Add Docker's official GPG key:
47
47
  sudo apt-get update
@@ -68,7 +68,7 @@ sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin
68
68
  🔹 Log out and back in to apply group changes
69
69
  {'=' * 150}
70
70
  """)
71
-
71
+
72
72
  return code
73
73
 
74
74
 
@@ -24,7 +24,7 @@ def main(version: Optional[str]):
24
24
  🔗 Source: https://github.com/espanso/espanso
25
25
  {'=' * 150}
26
26
  """)
27
-
27
+
28
28
  _ = version
29
29
  import platform
30
30
  config_dict["repo_url"] = "https://github.com/espanso/espanso"
@@ -66,13 +66,13 @@ def main(version: Optional[str]):
66
66
  from machineconfig.utils.installer_utils.installer_class import Installer
67
67
  installer = Installer.from_dict(config_dict, name="espanso")
68
68
  installer.install(version=None)
69
-
69
+
70
70
  config = """
71
71
  espanso service register
72
72
  espanso start
73
73
  espanso install actually-all-emojis
74
74
  """
75
-
75
+
76
76
  print(f"""
77
77
  {'=' * 150}
78
78
  ✅ SUCCESS | Espanso installation completed
@@ -82,5 +82,5 @@ espanso install actually-all-emojis
82
82
  3️⃣ Install the emoji package
83
83
  {'=' * 150}
84
84
  """)
85
-
85
+
86
86
  return config
@@ -25,7 +25,7 @@ def main():
25
25
  📦 Virtual Environment: {ve_name}
26
26
  {'=' * 150}
27
27
  """)
28
-
28
+
29
29
  print("🔄 Preparing installation script...")
30
30
  install_script = """
31
31
 
@@ -34,18 +34,18 @@ git clone https://github.com/ShishirPatil/gorilla --depth 1
34
34
  cd gorilla/goex
35
35
  uv sync
36
36
  """
37
-
37
+
38
38
  print(f"""
39
39
  {'=' * 150}
40
40
  📋 INSTALLATION STEPS:
41
- 1️⃣ Creating Python 3.11 virtual environment: {ve_name}
41
+ 1️⃣ Creating Python 3.13 virtual environment: {ve_name}
42
42
  2️⃣ Cloning Gorilla repository to ~/code/foreign
43
43
  3️⃣ Installing Gorilla in development mode
44
44
  {'=' * 150}
45
45
 
46
46
  ✅ Installation script prepared successfully!
47
47
  """)
48
-
48
+
49
49
  return install_script
50
50
 
51
51
 
@@ -1,7 +1,7 @@
1
1
  """lvim
2
2
  """
3
3
 
4
- from crocodile.meta import Terminal
4
+ from machineconfig.utils.terminal import Terminal
5
5
  import subprocess
6
6
  import platform
7
7
  from typing import Optional
@@ -29,7 +29,7 @@ def main(version: Optional[str]):
29
29
  📚 Branch: release-1.4/neovim-0.9
30
30
  {'=' * 150}
31
31
  """)
32
-
32
+
33
33
  _ = version
34
34
  if platform.system() == "Windows":
35
35
  print("🪟 Installing LunarVim on Windows...")
@@ -54,7 +54,7 @@ LV_BRANCH='release-1.4/neovim-0.9' bash <(curl -s https://raw.githubusercontent.
54
54
  {'⚠️' * 20}
55
55
  """)
56
56
  raise NotImplementedError(error_msg)
57
-
57
+
58
58
  print(f"""
59
59
  {'=' * 150}
60
60
  ℹ️ INFO | LunarVim features:
@@ -67,7 +67,7 @@ LV_BRANCH='release-1.4/neovim-0.9' bash <(curl -s https://raw.githubusercontent.
67
67
 
68
68
  ⚠️ NOTE: The installer will prompt for user input during installation.
69
69
  """)
70
-
70
+
71
71
  # _res = Terminal(stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE).run_script(script=program, shell="default").print(desc="Running custom installer", capture=True)
72
72
  # run script here as it requires user input
73
73
  return program
@@ -23,7 +23,7 @@ def main(version: Optional[str]):
23
23
  🔄 Version: {'latest' if version is None else version}
24
24
  {'=' * 150}
25
25
  """)
26
-
26
+
27
27
  _ = version
28
28
  if platform.system() == "Windows":
29
29
  error_msg = "Nerd Fonts installation not supported on Windows through this installer"
@@ -47,7 +47,7 @@ def main(version: Optional[str]):
47
47
  {'⚠️' * 20}
48
48
  """)
49
49
  raise NotImplementedError(error_msg)
50
-
50
+
51
51
  print(f"""
52
52
  {'=' * 150}
53
53
  ℹ️ INFO | Nerd Fonts features:
@@ -57,7 +57,7 @@ def main(version: Optional[str]):
57
57
  🧰 Works with many terminal applications and editors
58
58
  {'=' * 150}
59
59
  """)
60
-
60
+
61
61
  # _res = Terminal(stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE).run_script(script=program, shell="default").print(desc="Running custom installer", capture=True)
62
62
  # run script here as it requires user input
63
63
  return program
@@ -23,7 +23,7 @@ def main(version: Optional[str]):
23
23
  🔄 Version: {'latest' if version is None else version}
24
24
  {'=' * 150}
25
25
  """)
26
-
26
+
27
27
  _ = version
28
28
  if platform.system() == "Windows":
29
29
  error_msg = "Redis installation not supported on Windows through this installer"
@@ -51,7 +51,7 @@ def main(version: Optional[str]):
51
51
  {'⚠️' * 20}
52
52
  """)
53
53
  raise NotImplementedError(error_msg)
54
-
54
+
55
55
  print(f"""
56
56
  {'=' * 150}
57
57
  ℹ️ INFO | Redis features:
@@ -62,7 +62,7 @@ def main(version: Optional[str]):
62
62
  🔄 Built-in replication and Lua scripting
63
63
  {'=' * 150}
64
64
  """)
65
-
65
+
66
66
  # _res = Terminal(stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE).run_script(script=program, shell="default").print(desc="Running custom installer", capture=True)
67
67
  # run script here as it requires user input
68
68
  return program
@@ -23,7 +23,7 @@ def main(version: Optional[str]):
23
23
  🔄 Version: {'latest' if version is None else version}
24
24
  {'═' * 150}
25
25
  """)
26
-
26
+
27
27
  _ = version
28
28
  if platform.system() == "Windows":
29
29
  error_msg = "WezTerm installation not supported on Windows through this installer"
@@ -53,7 +53,7 @@ def main(version: Optional[str]):
53
53
  {'⚠️' * 20}
54
54
  """)
55
55
  raise NotImplementedError(error_msg)
56
-
56
+
57
57
  print(f"""
58
58
  {'═' * 150}
59
59
  ℹ️ INFO | WezTerm Features:
@@ -65,7 +65,7 @@ def main(version: Optional[str]):
65
65
  🔌 Plugin system
66
66
  {'═' * 150}
67
67
  """)
68
-
68
+
69
69
  # _res = Terminal(stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE).run_script(script=program, shell="default").print(desc="Running custom installer", capture=True)
70
70
  # run script here as it requires user input
71
71
  return program
@@ -18,7 +18,7 @@ config_dict = {
18
18
  def is_winget_available() -> bool:
19
19
  """
20
20
  Check if winget is available in the system PATH.
21
-
21
+
22
22
  Returns:
23
23
  bool: True if winget is available, False otherwise
24
24
  """
@@ -37,7 +37,7 @@ def is_winget_available() -> bool:
37
37
  def get_latest_winget_release_url() -> Optional[str]:
38
38
  """
39
39
  Get the download URL for the latest winget .msixbundle file from GitHub releases.
40
-
40
+
41
41
  Returns:
42
42
  Optional[str]: URL to the latest .msixbundle file, or None if not found
43
43
  """
@@ -45,17 +45,17 @@ def get_latest_winget_release_url() -> Optional[str]:
45
45
  # Get the latest release information from GitHub API
46
46
  api_url = "https://api.github.com/repos/microsoft/winget-cli/releases/latest"
47
47
  headers = {"Accept": "application/vnd.github.v3+json"}
48
-
48
+
49
49
  response = requests.get(api_url, headers=headers, timeout=30)
50
50
  response.raise_for_status()
51
-
51
+
52
52
  release_data = response.json()
53
-
53
+
54
54
  # Look for .msixbundle file in assets
55
55
  for asset in release_data.get("assets", []):
56
56
  if asset["name"].endswith(".msixbundle"):
57
57
  return asset["browser_download_url"]
58
-
58
+
59
59
  return None
60
60
  except (requests.RequestException, KeyError, ValueError) as e:
61
61
  print(f"Error fetching latest winget release: {e}")
@@ -65,23 +65,23 @@ def get_latest_winget_release_url() -> Optional[str]:
65
65
  def download_file(url: str, destination: Path) -> bool:
66
66
  """
67
67
  Download a file from URL to destination.
68
-
68
+
69
69
  Args:
70
70
  url: URL to download from
71
71
  destination: Path where to save the file
72
-
72
+
73
73
  Returns:
74
74
  bool: True if download successful, False otherwise
75
75
  """
76
76
  try:
77
77
  response = requests.get(url, stream=True, timeout=60)
78
78
  response.raise_for_status()
79
-
79
+
80
80
  with open(destination, 'wb') as f:
81
81
  for chunk in response.iter_content(chunk_size=8192):
82
82
  if chunk:
83
83
  f.write(chunk)
84
-
84
+
85
85
  return True
86
86
  except (requests.RequestException, IOError) as e:
87
87
  print(f"Error downloading file: {e}")
@@ -91,10 +91,10 @@ def download_file(url: str, destination: Path) -> bool:
91
91
  def install_msix_package(package_path: Path) -> bool:
92
92
  """
93
93
  Install an MSIX package using PowerShell.
94
-
94
+
95
95
  Args:
96
96
  package_path: Path to the .msixbundle file
97
-
97
+
98
98
  Returns:
99
99
  bool: True if installation successful, False otherwise
100
100
  """
@@ -106,14 +106,14 @@ def install_msix_package(package_path: Path) -> bool:
106
106
  "-Command",
107
107
  f"Add-AppxPackage -Path '{package_path}'"
108
108
  ]
109
-
109
+
110
110
  result = subprocess.run(
111
111
  powershell_cmd,
112
112
  capture_output=True,
113
113
  text=True,
114
114
  timeout=300 # 5 minutes timeout
115
115
  )
116
-
116
+
117
117
  if result.returncode == 0:
118
118
  print("Winget installed successfully!")
119
119
  return True
@@ -121,7 +121,7 @@ def install_msix_package(package_path: Path) -> bool:
121
121
  print(f"Installation failed with return code {result.returncode}")
122
122
  print(f"Error output: {result.stderr}")
123
123
  return False
124
-
124
+
125
125
  except (subprocess.SubprocessError, subprocess.TimeoutExpired) as e:
126
126
  print(f"Error installing MSIX package: {e}")
127
127
  return False
@@ -130,7 +130,7 @@ def install_msix_package(package_path: Path) -> bool:
130
130
  def ensure_winget_available() -> bool:
131
131
  """
132
132
  Ensure winget is available on the system. If not available, download and install it.
133
-
133
+
134
134
  Returns:
135
135
  bool: True if winget is available (either was already installed or successfully installed),
136
136
  False if installation failed
@@ -139,41 +139,41 @@ def ensure_winget_available() -> bool:
139
139
  if is_winget_available():
140
140
  print("Winget is already available on the system.")
141
141
  return True
142
-
142
+
143
143
  print("Winget not found. Attempting to download and install...")
144
-
144
+
145
145
  # Get the latest release URL
146
146
  download_url = get_latest_winget_release_url()
147
147
  if not download_url:
148
148
  print("Could not find the latest winget release URL.")
149
149
  return False
150
-
150
+
151
151
  print(f"Found latest winget release: {download_url}")
152
-
152
+
153
153
  # Create temporary directory for download
154
154
  with tempfile.TemporaryDirectory() as temp_dir:
155
155
  temp_path = Path(temp_dir)
156
-
156
+
157
157
  # Extract filename from URL
158
158
  filename = download_url.split("/")[-1]
159
159
  if not filename.endswith(".msixbundle"):
160
160
  filename = "winget-latest.msixbundle"
161
-
161
+
162
162
  package_path = temp_path / filename
163
-
163
+
164
164
  # Download the package
165
165
  print(f"Downloading winget package to {package_path}...")
166
166
  if not download_file(download_url, package_path):
167
167
  print("Failed to download winget package.")
168
168
  return False
169
-
169
+
170
170
  print("Download completed. Installing winget...")
171
-
171
+
172
172
  # Install the package
173
173
  if not install_msix_package(package_path):
174
174
  print("Failed to install winget package.")
175
175
  return False
176
-
176
+
177
177
  # Verify installation
178
178
  if is_winget_available():
179
179
  print("Winget has been successfully installed and is now available!")
@@ -186,7 +186,7 @@ def ensure_winget_available() -> bool:
186
186
  if __name__ == "__main__":
187
187
  # Example usage
188
188
  print("=== Winget Installation ===\n")
189
-
189
+
190
190
  if ensure_winget_available():
191
191
  print("Winget is ready to use!")
192
192
  else: