machineconfig 6.49__py3-none-any.whl → 6.52__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 (26) hide show
  1. machineconfig/jobs/installer/check_installations.py +0 -1
  2. machineconfig/jobs/installer/installer_data.json +17 -0
  3. machineconfig/scripts/python/croshell.py +28 -29
  4. machineconfig/scripts/python/env_manager/path_manager_tui.py +1 -1
  5. machineconfig/scripts/python/fire_jobs.py +9 -7
  6. machineconfig/scripts/python/helpers_croshell/crosh.py +34 -38
  7. machineconfig/scripts/python/helpers_devops/cli_config.py +3 -2
  8. machineconfig/scripts/python/helpers_devops/cli_self.py +3 -3
  9. machineconfig/scripts/python/helpers_repos/cloud_repo_sync.py +1 -1
  10. machineconfig/scripts/python/helpers_repos/count_lines_frontend.py +1 -1
  11. machineconfig/scripts/python/nw/mount_nfs +1 -1
  12. machineconfig/scripts/windows/mounts/mount_ssh.ps1 +1 -1
  13. machineconfig/setup_linux/web_shortcuts/interactive.sh +1 -1
  14. machineconfig/setup_mac/__init__.py +17 -0
  15. machineconfig/setup_mac/apps.sh +73 -0
  16. machineconfig/setup_mac/ssh/openssh_setup.sh +114 -0
  17. machineconfig/setup_mac/uv.sh +36 -0
  18. machineconfig/setup_windows/web_shortcuts/interactive.ps1 +1 -1
  19. machineconfig/utils/installer.py +7 -2
  20. machineconfig/utils/meta.py +178 -1
  21. machineconfig/utils/ssh.py +1 -1
  22. {machineconfig-6.49.dist-info → machineconfig-6.52.dist-info}/METADATA +1 -1
  23. {machineconfig-6.49.dist-info → machineconfig-6.52.dist-info}/RECORD +26 -22
  24. {machineconfig-6.49.dist-info → machineconfig-6.52.dist-info}/WHEEL +0 -0
  25. {machineconfig-6.49.dist-info → machineconfig-6.52.dist-info}/entry_points.txt +0 -0
  26. {machineconfig-6.49.dist-info → machineconfig-6.52.dist-info}/top_level.txt +0 -0
@@ -221,7 +221,6 @@ APP_SUMMARY_PATH = CONFIG_ROOT.joinpath(f"profile/records/{platform.system().low
221
221
  # # cli_installers = get_cli_py_installers()
222
222
  # # else: raise NotImplementedError(f"Platform {platform.system().lower()} is not supported yet.")
223
223
 
224
- # if name == "essentials":
225
224
  # print(f"""
226
225
  # {'=' * 150}
227
226
  # 📥 DOWNLOAD | Downloading {len(self.data)} apps...
@@ -2144,6 +2144,23 @@
2144
2144
  }
2145
2145
  }
2146
2146
  },
2147
+ {
2148
+ "appName": "cline",
2149
+ "repoURL": "CMD",
2150
+ "doc": "Cline agent extension in the terminal",
2151
+ "fileNamePattern": {
2152
+ "amd64": {
2153
+ "linux": "npm install -g cline",
2154
+ "windows": "npm install -g cline",
2155
+ "macos": "npm install -g cline"
2156
+ },
2157
+ "arm64": {
2158
+ "linux": "npm install -g cline",
2159
+ "windows": "npm install -g cline",
2160
+ "macos": "npm install -g cline"
2161
+ }
2162
+ }
2163
+ },
2147
2164
  {
2148
2165
  "appName": "copilot",
2149
2166
  "repoURL": "CMD",
@@ -5,8 +5,8 @@ croshell
5
5
  """
6
6
 
7
7
  from typing import Annotated, Optional
8
- from machineconfig.scripts.python.helpers_croshell.crosh import add_print_header_pycode
9
- from machineconfig.scripts.python.helpers_croshell.crosh import get_read_data_pycode
8
+ from machineconfig.scripts.python.helpers_croshell.crosh import code, get_read_data_pycode
9
+ from machineconfig.utils.meta import lambda_to_defstring
10
10
  import typer
11
11
  from machineconfig.utils.path_extended import PathExtended
12
12
  from pathlib import Path
@@ -26,10 +26,9 @@ def croshell(
26
26
  profile: Annotated[Optional[str], typer.Option("--profile", "-P", help="ipython profile to use, defaults to default profile.")] = None,
27
27
  jupyter: Annotated[bool, typer.Option("--jupyter", "-j", help="run in jupyter interactive console")] = False,
28
28
  vscode: Annotated[bool, typer.Option("--vscode", "-c", help="open the script in vscode")] = False,
29
- streamlit_viewer: Annotated[bool, typer.Option("--stViewer", "-s", help="view in streamlit app")] = False,
30
- visidata: Annotated[bool, typer.Option("--visidata", "-V", help="open data file in visidata")] = False,
29
+ streamlit_viewer: Annotated[bool, typer.Option("--streamlit", "-s", help="view in streamlit app")] = False,
30
+ visidata: Annotated[bool, typer.Option("--visidata", "-v", help="open data file in visidata")] = False,
31
31
  marimo: Annotated[bool, typer.Option("--marimo", "-m", help="open the notebook using marimo if available")] = False,
32
- local: Annotated[bool, typer.Option("--local", "-l", help="run in local mode, not in virtual env.")]= False,
33
32
  ) -> None:
34
33
  # ==================================================================================
35
34
  # flags processing
@@ -59,9 +58,10 @@ def croshell(
59
58
  # streamlit run {py_file_path}
60
59
  # """
61
60
  # PROGRAM_PATH.write_text(data=final_program, encoding="utf-8")
61
+ print("Streamlit viewer is not yet implemented in this version.")
62
62
  return None
63
63
  file_obj = PathExtended(str(path).lstrip()).expanduser().absolute()
64
- program = get_read_data_pycode(str(file_obj))
64
+ program = lambda_to_defstring(lambda: get_read_data_pycode(path=str(file_obj)), in_global=True)
65
65
  text = f"📄 Reading data from: {file_obj.name}"
66
66
  console.print(Panel(text, title="[bold blue]Info[/bold blue]"))
67
67
  else: # if nothing is specified, then run in interactive mode.
@@ -71,23 +71,29 @@ def croshell(
71
71
  # InteractiveShell().run()
72
72
  # return None
73
73
  program = ""
74
-
75
74
  preprogram = """
76
-
77
75
  #%%
78
-
79
- from machineconfig.utils.files.headers import print_header, print_logo
80
- print_header()
81
- print_logo("CROCODILE")
82
- from pathlib import Path
83
-
84
76
  """
77
+ def preprogram_func():
78
+ from machineconfig.utils.files.headers import print_header, print_logo
79
+ print_header()
80
+ print_logo("CROCODILE")
81
+ from pathlib import Path
82
+ from machineconfig.utils.path_extended import PathExtended
83
+ _ = Path, PathExtended # avoid unused import warnings
84
+ import inspect, textwrap
85
+ from types import FunctionType
86
+ def get_body_simple_function_no_args(f: FunctionType):
87
+ return textwrap.dedent("\n".join(inspect.getsource(f).splitlines()[1:]))
88
+ preprogram += get_body_simple_function_no_args(preprogram_func)
85
89
 
86
90
  pyfile = PathExtended.tmp().joinpath(f"tmp_scripts/python/croshell/{randstr()}/script.py")
87
91
  pyfile.parent.mkdir(parents=True, exist_ok=True)
88
92
 
89
93
  title = "Reading Data"
90
- python_program = preprogram + add_print_header_pycode(str(pyfile), title=title) + program
94
+ def_code = lambda_to_defstring(lambda: code(path=str(pyfile), title=title))
95
+ # print(def_code)
96
+ python_program = preprogram + "\n\n" + def_code + program
91
97
  pyfile.write_text(python_program, encoding="utf-8")
92
98
  # ve_root_from_file, ipython_profile = get_ve_path_and_ipython_profile(PathExtended(file))
93
99
  ipython_profile = ipython_profile if ipython_profile is not None else "default"
@@ -120,38 +126,31 @@ from pathlib import Path
120
126
  if visidata:
121
127
  fire_line = f"uv run --with visidata,pyarrow vd {str(file_obj)}"
122
128
  elif marimo:
123
- if Path.home().joinpath("code/machineconfig").exists(): requirements = f"""--project "{str(Path.home().joinpath("code/machineconfig"))}" """
124
- else: requirements = """--with "marimo,machineconfig[plot]>=6.49" """
129
+ if Path.home().joinpath("code/machineconfig").exists(): requirements = f"""--with marimo --project "{str(Path.home().joinpath("code/machineconfig"))}" """
130
+ else: requirements = """--with "marimo,machineconfig[plot]>=6.52" """
125
131
  fire_line = f"""
126
132
  cd {str(pyfile.parent)}
127
133
  uv run --with "marimo" marimo convert {pyfile.name} -o marimo_nb.py
128
134
  uv run {requirements} marimo edit --host 0.0.0.0 marimo_nb.py
129
135
  """
130
136
  elif jupyter:
131
- if Path.home().joinpath("code/machineconfig").exists(): requirements = f"""--project "{str(Path.home().joinpath("code/machineconfig"))}" """
132
- else: requirements = """--with "machineconfig[plot]>=6.49" """
137
+ if Path.home().joinpath("code/machineconfig").exists(): requirements = f"""--project "{str(Path.home().joinpath("code/machineconfig"))}" --with jupyterlab """
138
+ else: requirements = """--with "machineconfig[plot]>=6.52" """
133
139
  fire_line = f"uv run {requirements} jupyter-lab {str(nb_target)}"
134
140
  elif vscode:
135
141
  fire_line = f"""
136
142
  cd {str(pyfile.parent)}
137
143
  uv init --python 3.14
138
144
  uv venv
139
- uv add "machineconfig[plot]>=6.49"
145
+ uv add "machineconfig[plot]>=6.52"
140
146
  # code serve-web
141
147
  code --new-window {str(pyfile)}
142
148
  """
143
149
  else:
144
150
  if interpreter == "ipython": profile = f" --profile {ipython_profile} --no-banner"
145
151
  else: profile = ""
146
- if local:
147
- from machineconfig.utils.source_of_truth import LIBRARY_ROOT
148
- repo_root = LIBRARY_ROOT.parent.parent
149
- if repo_root.parent.name == "code" and repo_root.name == "machineconfig" and repo_root.exists() and repo_root.is_dir():
150
- ve_line = f"--project {str(repo_root)}"
151
- else:
152
- console.print(Panel("❌ Could not determine the local machineconfig repo root. Please ensure the `REPO_ROOT` in `source_of_truth.py` is correctly set to the local path of the machineconfig repo, or do not use the `--local` flag.", title="Error", border_style="red"))
153
- return
154
- else: ve_line = """--with "machineconfig[plot]>=6.49" """
152
+ if Path.home().joinpath("code/machineconfig").exists(): ve_line = f"""--project "{str(Path.home().joinpath("code/machineconfig"))}" """
153
+ else: ve_line = """--with "machineconfig[plot]>=6.52" """
155
154
  # ve_path_maybe, ipython_profile_maybe = get_ve_path_and_ipython_profile(Path.cwd())
156
155
  # --python 3.14
157
156
  fire_line = f"uv run {ve_line} {interpreter} {interactivity} {profile} {str(pyfile)}"
@@ -2,7 +2,7 @@
2
2
  # /// script
3
3
  # requires-python = ">=3.13"
4
4
  # dependencies = [
5
- # "machineconfig>=6.49",
5
+ # "machineconfig>=6.52",
6
6
  # "textual",
7
7
  # "pyperclip",
8
8
  # ]
@@ -204,19 +204,22 @@ def fire(
204
204
  cmd: Annotated[bool, typer.Option("--cmd", "-B", help="Create a cmd fire command to launch the job asynchronously")] = False,
205
205
  interactive: Annotated[bool, typer.Option("--interactive", "-i", help="Whether to run the job interactively using IPython")] = False,
206
206
  debug: Annotated[bool, typer.Option("--debug", "-d", help="Enable debug mode")] = False,
207
- choose_function: Annotated[bool, typer.Option("--choose_function", "-c", help="Choose function interactively")] = False,
207
+ choose_function: Annotated[bool, typer.Option("--choose-function", "-c", help="Choose function interactively")] = False,
208
208
  loop: Annotated[bool, typer.Option("--loop", "-l", help="Infinite recursion (runs again after completion/interruption)")] = False,
209
209
  jupyter: Annotated[bool, typer.Option("--jupyter", "-j", help="Open in a jupyter notebook")] = False,
210
- submit_to_cloud: Annotated[bool, typer.Option("--submit_to_cloud", "-C", help="Submit to cloud compute")] = False,
211
- remote: Annotated[bool, typer.Option("--remote", "-r", help="Launch on a remote machine")] = False,
212
210
  module: Annotated[bool, typer.Option("--module", "-m", help="Launch the main file")] = False,
211
+ optimized: Annotated[bool, typer.Option("--optimized", "-O", help="Run the optimized version of the function")] = False,
212
+ zellij_tab: Annotated[Optional[str], typer.Option("--zellij-tab", "-z", help="Open in a new zellij tab")] = None,
213
+
214
+ submit_to_cloud: Annotated[bool, typer.Option("--submit-to-cloud", "-C", help="Submit to cloud compute")] = False,
215
+ remote: Annotated[bool, typer.Option("--remote", "-r", help="Launch on a remote machine")] = False,
216
+
213
217
  streamlit: Annotated[bool, typer.Option("--streamlit", "-S", help="Run as streamlit app")] = False,
214
218
  environment: Annotated[str, typer.Option("--environment", "-E", help="Choose ip, localhost, hostname or arbitrary url")] = "",
215
219
  holdDirectory: Annotated[bool, typer.Option("--holdDirectory", "-D", help="Hold current directory and avoid cd'ing to the script directory")] = False,
216
220
  PathExport: Annotated[bool, typer.Option("--PathExport", "-P", help="Augment the PYTHONPATH with repo root")] = False,
217
- git_pull: Annotated[bool, typer.Option("--git_pull", "-g", help="Start by pulling the git repo")] = False,
218
- optimized: Annotated[bool, typer.Option("--optimized", "-O", help="Run the optimized version of the function")] = False,
219
- zellij_tab: Annotated[Optional[str], typer.Option("--zellij_tab", "-z", help="Open in a new zellij tab")] = None,
221
+
222
+ git_pull: Annotated[bool, typer.Option("--git-pull", "-g", help="Start by pulling the git repo")] = False,
220
223
  watch: Annotated[bool, typer.Option("--watch", "-w", help="Watch the file for changes")] = False,
221
224
  ) -> None:
222
225
  """Main function to process fire jobs arguments."""
@@ -254,7 +257,6 @@ def fire(
254
257
  except Exception as e:
255
258
  # For other exceptions, print clean error message and exit
256
259
  import sys
257
-
258
260
  print(f"❌ Error: {e}", file=sys.stderr)
259
261
  sys.exit(1)
260
262
 
@@ -1,43 +1,39 @@
1
- def add_print_header_pycode(path: str, title: str):
2
- return f"""
3
1
 
4
- from machineconfig.utils.path_extended import PathExtended
5
- pycode = PathExtended(r'{path}').read_text(encoding="utf-8")
6
- pycode = pycode.split("except Exception: print(pycode)")[2]
7
2
 
8
- try:
9
- from rich.text import Text
10
- from rich.panel import Panel
11
- from rich.console import Console
12
- from rich.syntax import Syntax
13
- console = Console()
14
- if pycode.strip() != "":
15
- console.print(Panel(Syntax(pycode, lexer="python"), title='{title}'), style="bold red")
16
- except Exception: print(pycode)
17
- """
3
+ def code(path: str, title: str):
4
+ from pathlib import Path
5
+ print("Reading code from path:", path)
6
+ pycode = Path(path).read_text(encoding="utf-8")
7
+ pycode = pycode.split("except Exception: print(pycode)")[2]
8
+ try:
9
+ # from rich.text import Text
10
+ from rich.panel import Panel
11
+ from rich.console import Console
12
+ from rich.syntax import Syntax
13
+ console = Console()
14
+ if pycode.strip() != "":
15
+ console.print(Panel(Syntax(pycode, lexer="python"), title=title), style="bold red")
16
+ except Exception: print(pycode)
18
17
 
19
18
 
20
19
  def get_read_data_pycode(path: str):
21
- return f"""
22
- from rich.panel import Panel
23
- from rich.text import Text
24
- from rich.console import Console
25
- console = Console()
26
- p = PathExtended(r'{path}').absolute()
27
- try:
28
- from machineconfig.utils.files.read import Read
29
- from machineconfig.utils.accessories import pprint
30
- dat = Read.read(p)
31
- if isinstance(dat, dict):
32
- panel_title = f"📄 File Data: {{p.name}}"
33
- console.print(Panel(Text(str(dat), justify="left"), title=panel_title, expand=False))
34
- pprint(dat, PathExtended.name)
35
- else:
36
- panel_title = f"📄 Successfully read the file: {{p.name}}"
37
- console.print(Panel(Text(str(dat), justify="left"), title=panel_title, expand=False))
38
- except Exception as e:
39
- error_message = f'''❌ ERROR READING FILE\nFile: {{p.name}}\nError: {{e}}'''
40
- console.print(Panel(Text(error_message, justify="left"), title="Error", expand=False, border_style="red"))
41
- """
42
-
43
-
20
+ from rich.panel import Panel
21
+ from rich.text import Text
22
+ from rich.console import Console
23
+ from machineconfig.utils.path_extended import PathExtended
24
+ console = Console()
25
+ p = PathExtended(path).absolute()
26
+ try:
27
+ from machineconfig.utils.files.read import Read
28
+ from machineconfig.utils.accessories import pprint
29
+ dat = Read.read(p)
30
+ if isinstance(dat, dict):
31
+ panel_title = f"📄 File Data: {p.name}"
32
+ console.print(Panel(Text(str(dat), justify="left"), title=panel_title, expand=False))
33
+ pprint(dat, p.name)
34
+ else:
35
+ panel_title = f"📄 Successfully read the file: {p.name}"
36
+ console.print(Panel(Text(str(dat), justify="left"), title=panel_title, expand=False))
37
+ except Exception as e:
38
+ error_message = f'''❌ ERROR READING FILE\nFile: {p.name}\nError: {e}'''
39
+ console.print(Panel(Text(error_message, justify="left"), title="Error", expand=False, border_style="red"))
@@ -36,13 +36,14 @@ def shell():
36
36
  from machineconfig.profile.create_shell_profile import create_default_shell_profile
37
37
  create_default_shell_profile()
38
38
 
39
+
39
40
  def path():
40
41
  """📚 NAVIGATE PATH variable with TUI"""
41
42
  from machineconfig.scripts.python import env_manager as navigator
42
43
  from pathlib import Path
43
44
  path = Path(navigator.__file__).resolve().parent.joinpath("path_manager_tui.py")
44
45
  from machineconfig.utils.code import run_shell_script
45
- if not Path.home().joinpath("code/machineconfig").exists(): executable = """--with "machineconfig>=6.49,textual" """
46
+ if not Path.home().joinpath("code/machineconfig").exists(): executable = """--with "machineconfig>=6.52,textual" """
46
47
  else: executable = f"""--project "{str(Path.home().joinpath("code/machineconfig"))}" --with textual"""
47
48
  run_shell_script(f"""uv run {executable} {path}""")
48
49
 
@@ -78,7 +79,7 @@ def get_app():
78
79
  config_apps.command("path", no_args_is_help=False, help="📚 [p] NAVIGATE PATH variable with TUI")(path)
79
80
  config_apps.command("p", no_args_is_help=False, help="NAVIGATE PATH variable with TUI", hidden=True)(path)
80
81
  config_apps.command("pwsh-theme", no_args_is_help=False, help="🔗 [t] Select powershell prompt theme.")(pwsh_theme)
81
- config_apps.command("t", no_args_is_help=True, help="Select powershell prompt theme.", hidden=True)(pwsh_theme)
82
+ config_apps.command("t", no_args_is_help=False, help="Select powershell prompt theme.", hidden=True)(pwsh_theme)
82
83
  config_apps.command("copy-assets", no_args_is_help=True, help="🔗 [c] Copy asset files from library to machine.", hidden=False)(copy_assets)
83
84
  config_apps.command("c", no_args_is_help=True, help="Copy asset files from library to machine.", hidden=True)(copy_assets)
84
85
  return config_apps
@@ -40,9 +40,9 @@ def install(no_copy_assets: Annotated[bool, typer.Option("--no-assets-copy", "-n
40
40
  else:
41
41
  import platform
42
42
  if platform.system() == "Windows":
43
- run_shell_script(r"""$HOME\.local\bin\uv.exe tool install --upgrade "machineconfig>=6.49" """)
43
+ run_shell_script(r"""& "$HOME\.local\bin\uv.exe" tool install --upgrade "machineconfig>=6.52" """)
44
44
  else:
45
- run_shell_script("""$HOME/.local/bin/uv tool install --upgrade "machineconfig>=6.49" """)
45
+ run_shell_script("""$HOME/.local/bin/uv tool install --upgrade "machineconfig>=6.52" """)
46
46
  from machineconfig.profile.create_shell_profile import create_default_shell_profile
47
47
  if not no_copy_assets:
48
48
  create_default_shell_profile() # involves copying assets too
@@ -67,7 +67,7 @@ def navigate():
67
67
  path = Path(navigator.__file__).resolve().parent.joinpath("devops_navigator.py")
68
68
  from machineconfig.utils.code import run_shell_script
69
69
  if Path.home().joinpath("code/machineconfig").exists(): executable = f"""--project "{str(Path.home().joinpath("code/machineconfig"))}" --with textual"""
70
- else: executable = """--with "machineconfig>=6.49,textual" """
70
+ else: executable = """--with "machineconfig>=6.52,textual" """
71
71
  run_shell_script(f"""uv run {executable} {path}""")
72
72
 
73
73
 
@@ -77,7 +77,7 @@ git pull originEnc master
77
77
  """
78
78
 
79
79
  if Path.home().joinpath("code/machineconfig").exists(): executable = f"""uv run --project "{str(Path.home().joinpath("code/machineconfig"))}" """
80
- else: executable = """uv run --with "machineconfig>=6.49" """
80
+ else: executable = """uv run --with "machineconfig>=6.52" """
81
81
 
82
82
  shell_path = write_shell_script_to_file(shell_script=script)
83
83
  command = f". {shell_path}"
@@ -8,7 +8,7 @@ def analyze_repo_development(repo_path: Annotated[str, typer.Argument(..., help=
8
8
  from pathlib import Path
9
9
  count_lines_path = Path(count_lines.__file__)
10
10
  # --project $HOME/code/ machineconfig --group plot
11
- cmd = f"""uv run --python 3.14 --with "machineconfig[plot]>=6.49" {count_lines_path} analyze-over-time {repo_path}"""
11
+ cmd = f"""uv run --python 3.14 --with "machineconfig[plot]>=6.52" {count_lines_path} analyze-over-time {repo_path}"""
12
12
  from machineconfig.utils.code import run_shell_script
13
13
  run_shell_script(cmd)
14
14
 
@@ -5,7 +5,7 @@
5
5
  # mkdir ~/data/local
6
6
  # sudo mount -o nolock,noatime,nodiratime,proto=tcp,timeo=600,retrans=2,noac alex-p51s-5:/home/alex/data/local ./data/local
7
7
 
8
- uv run --python 3.14 --with "machineconfig>=6.49" python -m machineconfig.scripts.python.mount_nfs
8
+ uv run --python 3.14 --with "machineconfig>=6.52" python -m machineconfig.scripts.python.mount_nfs
9
9
  # Check if remote server is reachable and share folder exists
10
10
  if ! ping -c 1 "$remote_server" &> /dev/null; then
11
11
  echo "💥 Error: Remote server $remote_server is not reachable."
@@ -7,7 +7,7 @@ $user = ''
7
7
  $sharePath = ''
8
8
  $driveLetter = ''
9
9
 
10
- uv run --python 3.14 --with "machineconfig>=6.49" python -m machineconfig.scripts.python.mount_ssh
10
+ uv run --python 3.14 --with "machineconfig>=6.52" python -m machineconfig.scripts.python.mount_ssh
11
11
 
12
12
  net use T: \\sshfs.kr\$user@$host.local
13
13
  # this worked: net use T: \\sshfs\alex@alex-p51s-5.local
@@ -1,7 +1,7 @@
1
1
  #!/bin/bash
2
2
  . <( curl -sSL "https://raw.githubusercontent.com/thisismygitrepo/machineconfig/main/src/machineconfig/setup_linux/uv.sh")
3
3
  mcfg() {
4
- "$HOME/.local/bin/uv" run --python 3.14 --with "machineconfig>=6.49" mcfg "$@"
4
+ "$HOME/.local/bin/uv" run --python 3.14 --with "machineconfig>=6.52" mcfg "$@"
5
5
  }
6
6
  alias d="mcfg devops"
7
7
  alias c="mcfg cloud"
@@ -0,0 +1,17 @@
1
+ """Mac setup module for machineconfig.
2
+
3
+ This module provides setup script locations and configurations for macOS systems.
4
+ It mirrors the layout used by the Linux setup module and exposes Path objects
5
+ pointing at common scripts (so other code can import these paths).
6
+ """
7
+
8
+ from pathlib import Path
9
+
10
+ # Path to main installer script for macOS
11
+ APPS = Path(__file__).parent.joinpath("apps.sh")
12
+ # Optional helper scripts (may or may not exist)
13
+ UV = Path(__file__).parent.joinpath("uv.sh")
14
+ # Path to macOS SSH helper
15
+ SSH_SETUP = Path(__file__).parent.joinpath("ssh/openssh_setup.sh")
16
+
17
+ __all__ = ["APPS", "UV", "SSH_SETUP"]
@@ -0,0 +1,73 @@
1
+ #!/usr/bin/env bash
2
+
3
+ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
4
+ echo "🔄 Updating Homebrew..."
5
+ brew update || true
6
+
7
+ # --GROUP:ESSENTIAL_SYSTEM:git,nano,curl,nvm,nodejs,brave-browser,visual-studio-code
8
+ echo "📥 Installing essential tools..."
9
+ echo "📥 Installing Git version control..."
10
+ echo "📥 Installing Nano text editor..."
11
+ echo "📥 Installing Node Version Manager (NVM)..."
12
+ # Note: git and nano are pre-installed on macOS, but we install via Homebrew to ensure latest versions
13
+ brew install git || true
14
+ brew install nano || true
15
+ brew install curl || true
16
+ # Install NVM
17
+ if [ ! -s "$HOME/.nvm/nvm.sh" ]; then
18
+ echo "📥 Installing NVM (Node Version Manager)..."
19
+ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash
20
+ fi
21
+ echo "🔧 Configuring NVM environment..."
22
+ export NVM_DIR="$HOME/.nvm"
23
+ [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
24
+ echo "📥 Installing latest Node.js..."
25
+ nvm install node || true
26
+ brew install --cask brave-browser || true
27
+ brew install --cask visual-studio-code || true
28
+
29
+ # Database tools
30
+ # echo "📥 Installing SQLite - lightweight SQL database..."
31
+ # echo "📥 Installing PostgreSQL client..."
32
+ # echo "📥 Installing Redis command-line tools..."
33
+ # brew install sqlite3 || true
34
+ # brew install postgresql || true
35
+ # brew install redis || true
36
+
37
+ # --GROUP:TerminalEyeCandy:fortune,toilet,sl,cmatrix,chafa
38
+ echo "📥 Installing fortune - random wisdom generator..."
39
+ echo "📥 Installing figlet - ASCII art text generator..."
40
+ echo "📥 Installing cowsay - ASCII cow speech generator..."
41
+ echo "📥 Installing lolcat - colorized text output..."
42
+ echo "📥 Installing chafa - terminal image viewer..."
43
+ brew install fortune || true
44
+ brew install figlet || true
45
+ brew install cowsay || true
46
+ brew install lolcat || true
47
+ brew install chafa || true
48
+
49
+ # --GROUP:NetworkTools: sshfs,nfs-utils
50
+ echo "📥 Installing SSHFS - mount remote filesystems over SSH..."
51
+ echo "📥 Installing NFS utilities..."
52
+ brew install sshfs || true
53
+ brew install nfs-utils || true
54
+
55
+ # --GROUP:DEV_SYSTEM: graphviz,make,rust,sqlite3,postgresql-client,redis-tools,ffmpeg
56
+ echo "📥 Installing Graphviz - graph visualization software..."
57
+ echo "📥 Installing make - build automation tool..."
58
+ echo "📥 Installing FFmpeg - multimedia framework..."
59
+ echo "📥 Installing SSL/TLS development libraries..."
60
+ echo "📥 Installing Rust programming language and toolchain..."
61
+ brew install graphviz || true
62
+ brew install make || true
63
+ brew install ffmpeg || true
64
+ brew install openssl || true
65
+
66
+ # Install Rust if not already installed
67
+ if ! command -v rustc &> /dev/null; then
68
+ echo "📥 Installing Rust..."
69
+ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y || true
70
+ fi
71
+
72
+
73
+
@@ -0,0 +1,114 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # 🔐 OpenSSH Setup for macOS
4
+ # This script sets up SSH configuration and permissions on macOS
5
+
6
+ echo "🔐 Starting OpenSSH setup for macOS..."
7
+
8
+ # ✅ SSH is built-in on macOS (OpenSSH comes pre-installed)
9
+ echo "✅ OpenSSH is pre-installed on macOS"
10
+
11
+ # 📁 Create SSH directory with correct permissions
12
+ echo "📁 Setting up SSH directory..."
13
+ mkdir -p ~/.ssh
14
+ chmod 700 ~/.ssh
15
+ echo "✅ SSH directory created with correct permissions (700)"
16
+
17
+ # 📝 Create authorized_keys file if it doesn't exist
18
+ if [ ! -f ~/.ssh/authorized_keys ]; then
19
+ touch ~/.ssh/authorized_keys
20
+ chmod 600 ~/.ssh/authorized_keys
21
+ echo "✅ Created authorized_keys file"
22
+ else
23
+ echo "✅ authorized_keys file already exists"
24
+ chmod 600 ~/.ssh/authorized_keys
25
+ fi
26
+
27
+ # 🔑 Create SSH keys if they don't exist
28
+ if [ ! -f ~/.ssh/id_rsa ]; then
29
+ echo "🔑 Generating SSH keys (RSA)..."
30
+ ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa -N "" -C "$(whoami)@$(hostname)"
31
+ echo "✅ SSH RSA keys generated: ~/.ssh/id_rsa"
32
+ else
33
+ echo "✅ SSH keys already exist"
34
+ fi
35
+
36
+ # 🔐 Create Ed25519 keys (modern alternative)
37
+ if [ ! -f ~/.ssh/id_ed25519 ]; then
38
+ echo "🔑 Generating SSH keys (Ed25519)..."
39
+ ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519 -N "" -C "$(whoami)@$(hostname)"
40
+ echo "✅ SSH Ed25519 keys generated: ~/.ssh/id_ed25519"
41
+ else
42
+ echo "✅ SSH Ed25519 keys already exist"
43
+ fi
44
+
45
+ # 🔧 Configure SSH config file for convenience
46
+ SSH_CONFIG="$HOME/.ssh/config"
47
+ if [ ! -f "$SSH_CONFIG" ]; then
48
+ echo "📝 Creating SSH config file..."
49
+ cat > "$SSH_CONFIG" << 'EOF'
50
+ # SSH Config File for macOS
51
+ # Add your remote hosts below
52
+
53
+ # Example host configuration:
54
+ # Host myserver
55
+ # HostName example.com
56
+ # User username
57
+ # Port 22
58
+ # IdentityFile ~/.ssh/id_ed25519
59
+ # IdentityFile ~/.ssh/id_rsa
60
+
61
+ # Global settings
62
+ Host *
63
+ AddKeysToAgent yes
64
+ UseKeychain yes
65
+ IdentityFile ~/.ssh/id_ed25519
66
+ IdentityFile ~/.ssh/id_rsa
67
+ ServerAliveInterval 60
68
+ EOF
69
+ chmod 600 "$SSH_CONFIG"
70
+ echo "✅ SSH config file created: $SSH_CONFIG"
71
+ else
72
+ echo "✅ SSH config file already exists"
73
+ fi
74
+
75
+ # 🔒 Ensure correct file permissions
76
+ echo "🔒 Setting correct SSH file permissions..."
77
+ chmod 700 ~/.ssh
78
+ chmod 600 ~/.ssh/authorized_keys 2>/dev/null || true
79
+ chmod 600 ~/.ssh/id_rsa 2>/dev/null || true
80
+ chmod 644 ~/.ssh/id_rsa.pub 2>/dev/null || true
81
+ chmod 600 ~/.ssh/id_ed25519 2>/dev/null || true
82
+ chmod 644 ~/.ssh/id_ed25519.pub 2>/dev/null || true
83
+ chmod 600 ~/.ssh/config 2>/dev/null || true
84
+ echo "✅ SSH file permissions configured correctly"
85
+
86
+ # ℹ️ Display SSH key information
87
+ echo ""
88
+ echo "📋 SSH Setup Summary:"
89
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
90
+ echo "SSH Directory: ~/.ssh"
91
+ echo "SSH Config: ~/.ssh/config"
92
+ echo ""
93
+ echo "Available SSH Keys:"
94
+ if [ -f ~/.ssh/id_rsa.pub ]; then
95
+ echo " • RSA Key: ~/.ssh/id_rsa"
96
+ fi
97
+ if [ -f ~/.ssh/id_ed25519.pub ]; then
98
+ echo " • Ed25519 Key: ~/.ssh/id_ed25519"
99
+ fi
100
+ echo ""
101
+ echo "💡 Next Steps:"
102
+ echo " 1. View your public key:"
103
+ echo " cat ~/.ssh/id_ed25519.pub (or id_rsa.pub)"
104
+ echo " 2. Add it to your GitHub/GitLab/server authorized_keys"
105
+ echo " 3. Test connection:"
106
+ echo " ssh -v your_server"
107
+ echo " 4. Configure hosts in ~/.ssh/config for easy access"
108
+ echo ""
109
+ echo "📚 Learn more about SSH:"
110
+ echo " • man ssh"
111
+ echo " • man ssh-keygen"
112
+ echo " • man ssh_config"
113
+ echo ""
114
+ echo "✅ OpenSSH setup complete!"
@@ -0,0 +1,36 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # Install or update uv (universal version manager) on macOS
4
+ # Mirrors Linux uv installer but adapts PATH and locations for mac
5
+
6
+ set -euo pipefail
7
+
8
+ UV_BIN="$HOME/.local/bin/uv"
9
+
10
+ if [ ! -f "$UV_BIN" ]; then
11
+ echo "📦 uv binary not found — installing uv to $HOME/.local/bin..."
12
+ mkdir -p "$HOME/.local/bin"
13
+ curl -LsSf https://astral.sh/uv/install.sh | sh
14
+ echo "✅ uv installed to $UV_BIN"
15
+ else
16
+ echo "🔄 uv binary found — attempting self-update..."
17
+ "$UV_BIN" self update || true
18
+ fi
19
+
20
+ # Ensure local bin is in PATH for this run
21
+ export PATH="$HOME/.local/bin:$PATH"
22
+
23
+ if ! command -v uv &> /dev/null; then
24
+ echo "⚠️ uv not found in PATH even after install; add \"$HOME/.local/bin\" to your shell profile"
25
+ else
26
+ echo "🔧 uv available: $(command -v uv)"
27
+ fi
28
+
29
+ # Example uv usage: ensure Python 3.14 is available (adjust as needed)
30
+ if command -v uv &> /dev/null; then
31
+ echo "📥 Ensuring Python 3.14 via uv (if supported)"
32
+ # uv may manage various runtimes; this is an example command and will be skipped gracefully if unsupported
33
+ uv python install 3.14 || true
34
+ fi
35
+
36
+ echo "✅ uv setup complete"
@@ -2,7 +2,7 @@
2
2
 
3
3
  iex (iwr "https://raw.githubusercontent.com/thisismygitrepo/machineconfig/main/src/machineconfig/setup_windows/uv.ps1").Content
4
4
  function mcfg {
5
- & "$HOME\.local\bin\uv.exe" run --python 3.14 --with "machineconfig>=6.49" mcfg $args
5
+ & "$HOME\.local\bin\uv.exe" run --python 3.14 --with "machineconfig>=6.52" mcfg $args
6
6
  }
7
7
  function d { mcfg devops @args }
8
8
  function c { mcfg cloud @args }
@@ -123,9 +123,14 @@ def dynamically_extract_installers_system_groups_from_scripts():
123
123
  res_final: list[InstallerData] = []
124
124
  from platform import system
125
125
  if system() == "Windows":
126
- options_system = parse_apps_installer_windows(LIBRARY_ROOT.joinpath("setup_windows/apps.ps1").read_text(encoding="utf-8"))
126
+ from machineconfig.setup_windows import APPS
127
+ options_system = parse_apps_installer_windows(APPS.read_text(encoding="utf-8"))
127
128
  elif system() == "Linux" or system() == "Darwin":
128
- options_system = parse_apps_installer_linux(LIBRARY_ROOT.joinpath("setup_linux/apps.sh").read_text(encoding="utf-8"))
129
+ from machineconfig.setup_linux import APPS
130
+ options_system = parse_apps_installer_linux(APPS.read_text(encoding="utf-8"))
131
+ elif system() == "Darwin":
132
+ from machineconfig.setup_mac import APPS
133
+ options_system = parse_apps_installer_linux(APPS.read_text(encoding="utf-8"))
129
134
  else:
130
135
  raise NotImplementedError(f"❌ System {system()} not supported")
131
136
  os_name = get_os_name()
@@ -5,7 +5,7 @@ import inspect
5
5
  import textwrap
6
6
  from collections.abc import Callable, Mapping
7
7
  from types import FunctionType, ModuleType
8
- from typing import ParamSpec
8
+ from typing import Any, ParamSpec
9
9
 
10
10
  P = ParamSpec("P")
11
11
 
@@ -245,6 +245,183 @@ def _generate_call_statement(func: FunctionType, kwargs: dict[str, object]) -> s
245
245
  return f"{func.__name__}({args_str})"
246
246
 
247
247
 
248
+ def lambda_to_defstring(lmb: Callable[[], Any], in_global: bool = False) -> str:
249
+ """
250
+ Given a no-arg lambda like `lambda: func(a=var1, b=var2)`,
251
+ return a string containing the full function definition of `func`
252
+ but with the defaults for the parameters provided in the call replaced
253
+ by the *actual* values (repr) taken from the lambda's globals.
254
+
255
+ All imports are local to this function.
256
+
257
+ Args:
258
+ lmb: A lambda function with no arguments
259
+ in_global: If True, return kwargs as global variable assignments followed by dedented body.
260
+ If False (default), return the full function definition with updated defaults.
261
+ """
262
+ # local imports
263
+ import inspect as _inspect
264
+ import ast as _ast
265
+ import textwrap as _textwrap
266
+ import types as _types
267
+
268
+ # sanity checks
269
+ if not (callable(lmb) and isinstance(lmb, _types.LambdaType)):
270
+ raise TypeError("Expected a lambda function object")
271
+
272
+ src = _inspect.getsource(lmb)
273
+ src = _textwrap.dedent(src)
274
+ tree = _ast.parse(src)
275
+
276
+ # find first Lambda node
277
+ lambda_node = None
278
+ for n in _ast.walk(tree):
279
+ if isinstance(n, _ast.Lambda):
280
+ lambda_node = n
281
+ break
282
+ if lambda_node is None:
283
+ raise ValueError("Could not find a lambda expression in source")
284
+
285
+ body = lambda_node.body
286
+ if not isinstance(body, _ast.Call):
287
+ raise ValueError("Lambda body is not a call expression")
288
+
289
+ globals_dict = getattr(lmb, "__globals__", {})
290
+
291
+ # Also capture closure variables from the lambda
292
+ closure_dict: dict[str, Any] = {}
293
+ if lmb.__closure__:
294
+ code_obj = lmb.__code__
295
+ freevars = code_obj.co_freevars
296
+ for i, var_name in enumerate(freevars):
297
+ closure_dict[var_name] = lmb.__closure__[i].cell_contents
298
+
299
+ # Merge globals and closures (closures take precedence for shadowing)
300
+ eval_namespace = {**globals_dict, **closure_dict}
301
+
302
+ # resolve the function object being called
303
+ try:
304
+ func_ref_src = _ast.unparse(body.func)
305
+ except AttributeError:
306
+ func_ref_src = _ast.get_source_segment(src, body.func) or ""
307
+ try:
308
+ func_obj = eval(func_ref_src, eval_namespace)
309
+ except Exception as e:
310
+ raise RuntimeError(f"Could not resolve function reference '{func_ref_src}': {e}")
311
+
312
+ if not callable(func_obj):
313
+ raise TypeError("Resolved object is not callable")
314
+
315
+ func_name = getattr(func_obj, "__name__", "<unknown>")
316
+
317
+ # Evaluate each keyword argument value in the lambda's globals to get real Python objects
318
+ call_kwargs = {}
319
+ for kw in body.keywords:
320
+ if kw.arg is None:
321
+ # **kwargs in call — evaluate to dict and merge
322
+ try:
323
+ val = eval(compile(_ast.Expression(kw.value), "<lambda_eval>", "eval"), eval_namespace)
324
+ if isinstance(val, dict):
325
+ call_kwargs.update(val)
326
+ else:
327
+ raise ValueError("Keyword expansion did not evaluate to a dict")
328
+ except Exception as e:
329
+ raise RuntimeError(f"Failed to evaluate **kwargs expression: {e}")
330
+ else:
331
+ try:
332
+ val = eval(compile(_ast.Expression(kw.value), "<lambda_eval>", "eval"), eval_namespace)
333
+ call_kwargs[kw.arg] = val
334
+ except Exception as e:
335
+ raise RuntimeError(f"Failed to evaluate value for kw '{kw.arg}': {e}")
336
+
337
+ # Try to get original source and dedent it for body extraction
338
+ try:
339
+ orig_src = _inspect.getsource(func_obj)
340
+ ded = _textwrap.dedent(orig_src)
341
+ lines = ded.splitlines()
342
+ # find the line that starts with def <name>(
343
+ def_index = None
344
+ for i, ln in enumerate(lines):
345
+ if ln.lstrip().startswith(f"def {func_name}("):
346
+ def_index = i
347
+ break
348
+ if def_index is None:
349
+ body_lines = ded.splitlines()
350
+ else:
351
+ body_lines = lines[def_index + 1 :]
352
+ # ensure we have a body, otherwise use pass
353
+ if not any(line.strip() for line in body_lines):
354
+ body_text = " pass\n"
355
+ else:
356
+ # keep the dedented body lines exactly as-is (they should be indented)
357
+ body_text = "\n".join(body_lines) + ("\n" if not body_lines[-1].endswith("\n") else "")
358
+ except (OSError, IOError, TypeError):
359
+ body_text = " pass\n"
360
+
361
+ # Build a replaced signature using inspect.signature
362
+ sig = _inspect.signature(func_obj)
363
+ new_params = []
364
+ for name, param in sig.parameters.items():
365
+ # If the call provided a value for this parameter, replace default
366
+ if name in call_kwargs:
367
+ new_default = call_kwargs[name]
368
+ else:
369
+ new_default = param.default
370
+
371
+ # Recreate the Parameter (keeping annotation and kind)
372
+ if new_default is _inspect.Parameter.empty:
373
+ new_param = _inspect.Parameter(name, param.kind, annotation=param.annotation)
374
+ else:
375
+ new_param = _inspect.Parameter(
376
+ name, param.kind, default=new_default, annotation=param.annotation
377
+ )
378
+ new_params.append(new_param)
379
+
380
+ new_sig = _inspect.Signature(parameters=new_params, return_annotation=sig.return_annotation)
381
+
382
+ # If in_global mode, return kwargs as global assignments + dedented body
383
+ if in_global:
384
+ global_assignments: list[str] = []
385
+ for name, param in sig.parameters.items():
386
+ # Get the value from call_kwargs if provided, else use original default
387
+ if name in call_kwargs:
388
+ value = call_kwargs[name]
389
+ elif param.default is not _inspect.Parameter.empty:
390
+ value = param.default
391
+ else:
392
+ # No value provided and no default - skip this parameter
393
+ continue
394
+
395
+ # Build type annotation string if available
396
+ if param.annotation is not _inspect.Parameter.empty:
397
+ # Try to get a nice string representation of the annotation
398
+ try:
399
+ if hasattr(param.annotation, "__name__"):
400
+ type_str = param.annotation.__name__
401
+ else:
402
+ type_str = str(param.annotation)
403
+ except Exception:
404
+ type_str = str(param.annotation)
405
+ global_assignments.append(f"{name}: {type_str} = {repr(value)}")
406
+ else:
407
+ global_assignments.append(f"{name} = {repr(value)}")
408
+
409
+ # Dedent the body text to remove function indentation
410
+ dedented_body = _textwrap.dedent(body_text).rstrip()
411
+
412
+ # Combine global assignments and body
413
+ if global_assignments:
414
+ result_parts = ["\n".join(global_assignments), "", dedented_body]
415
+ return "\n".join(result_parts)
416
+ else:
417
+ return dedented_body
418
+
419
+ # Compose final function definition text
420
+ header = f"def {func_name}{new_sig}:\n"
421
+ final_src = header + body_text
422
+ return final_src
423
+
424
+
248
425
  if __name__ == "__main__":
249
426
  # Example usage
250
427
  a = True
@@ -6,7 +6,7 @@ from machineconfig.utils.terminal import Response, MACHINE
6
6
  from machineconfig.utils.accessories import pprint
7
7
 
8
8
  UV_RUN_CMD = "$HOME/.local/bin/uv run"
9
- MACHINECONFIG_VERSION = "machineconfig>=6.49"
9
+ MACHINECONFIG_VERSION = "machineconfig>=6.52"
10
10
  DEFAULT_PICKLE_SUBDIR = "tmp_results/tmp_scripts/ssh"
11
11
 
12
12
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: machineconfig
3
- Version: 6.49
3
+ Version: 6.52
4
4
  Summary: Dotfiles management package
5
5
  Author-email: Alex Al-Saffar <programmer@usa.com>
6
6
  License: Apache 2.0
@@ -46,8 +46,8 @@ machineconfig/cluster/templates/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm
46
46
  machineconfig/cluster/templates/cli_trogon.py,sha256=PFWGy8SFYIhT9r3ZV4oIEYfImsQwzAHH_04stPuV5bY,647
47
47
  machineconfig/jobs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
48
48
  machineconfig/jobs/installer/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
49
- machineconfig/jobs/installer/check_installations.py,sha256=uFuxhgI8rIMtClcGmuc9gpG6iJ7X0__peGUQfGkreT8,10778
50
- machineconfig/jobs/installer/installer_data.json,sha256=NDm-igW86P2LmyaNn5lAOePE4ikjyx_Tj3mfNnQ4vgE,75405
49
+ machineconfig/jobs/installer/check_installations.py,sha256=hkHmmT7Bx3_QWRn2v8dCKOzAapFzqHRzbe-Q08GLnKE,10743
50
+ machineconfig/jobs/installer/installer_data.json,sha256=04KvR0X55GRYh8gyzOCtJItfVrNYpzF0GM9n08Kv89g,75876
51
51
  machineconfig/jobs/installer/package_groups.py,sha256=i4z83F_rk7BVsrwFhz5Vn4SLF0IHxyQBFSxpAaZBl8M,5270
52
52
  machineconfig/jobs/installer/custom/gh.py,sha256=gn7TUSrsLx7uqFqj1Z-iYglS0EYBSgtJ9jWHxaJIfXM,4119
53
53
  machineconfig/jobs/installer/custom/hx.py,sha256=YQClQXqWtGvon8BLFGf1Fp20JPkHgZeEZ6ebmCJQQfI,5838
@@ -122,11 +122,11 @@ machineconfig/scripts/linux/other/switch_ip,sha256=NQfeKMBSbFY3eP6M-BadD-TQo5qMP
122
122
  machineconfig/scripts/python/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
123
123
  machineconfig/scripts/python/agents.py,sha256=gGeeWCI0AN_DyDJ3G5KR9qSsXv8zkUd5dBRRWqz-dQE,10722
124
124
  machineconfig/scripts/python/cloud.py,sha256=yAD6ciKiEtv2CH3g2NScDK5cpCZQi7Vu8yyeehw_cU8,1263
125
- machineconfig/scripts/python/croshell.py,sha256=JFL0YpO1990pFlpim04RkrWU5jQzsmfUkzFVPLjcgKw,8007
125
+ machineconfig/scripts/python/croshell.py,sha256=BCwiH_Wi_2_Y8fr-D2Cn9TpSTnzMPufXF7SF7Ri2fn8,8046
126
126
  machineconfig/scripts/python/devops.py,sha256=LGra1YiLEQYjaRevNjJB51Bia81IgjrvUQkA6z8wq8I,2440
127
127
  machineconfig/scripts/python/devops_navigator.py,sha256=5Cm384D4S8_GsvMzTwr0C16D0ktf8_5Mk5bEJncwDO8,237
128
128
  machineconfig/scripts/python/entry.py,sha256=a0Zk_3RnIFTQ55zSQrvOOiKom_SaoxElPMmWQgGy4V0,2221
129
- machineconfig/scripts/python/fire_jobs.py,sha256=O5DrckUGLxGblOcLf_iXU31pmCSpTg-c0hQZxQKD1os,13591
129
+ machineconfig/scripts/python/fire_jobs.py,sha256=My7sFn1R2vh21uIHGfNppgX99WTEitCFgJ1MSasBUOQ,13597
130
130
  machineconfig/scripts/python/ftpx.py,sha256=vm4QNJA0z1Vu-85wFliGNoDHMZZ-Yy8zQACL6x7Wo6U,9760
131
131
  machineconfig/scripts/python/interactive.py,sha256=zt3g6nGKR_Y5A57UnR4Y5-JpLzrpnCOSaqU1bnaikK0,11666
132
132
  machineconfig/scripts/python/sessions.py,sha256=UERxO472EDtN7nKHEULbn6G3S5PJIpsDG9Gq3TlByqI,9823
@@ -162,7 +162,7 @@ machineconfig/scripts/python/ai/solutions/opencode/opencode.json,sha256=nahHKRw1
162
162
  machineconfig/scripts/python/ai/solutions/opencode/opencode.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
163
163
  machineconfig/scripts/python/env_manager/__init__.py,sha256=E4LAHbU1wo2dLjE36ntv8U7QNTe8TasujUAYK9SLvWk,6
164
164
  machineconfig/scripts/python/env_manager/path_manager_backend.py,sha256=ZVGlGJALhg7zNABDdwXxL7MFbL2BXPebObipXSLGbic,1552
165
- machineconfig/scripts/python/env_manager/path_manager_tui.py,sha256=u5TeU6k_7fk2PGSAAKqd_rWqC6cD3nn0lxIL68ZvZKU,6932
165
+ machineconfig/scripts/python/env_manager/path_manager_tui.py,sha256=SuaYgj8UFgFYLf1fAKCSLIJC7dDqsscCw3Epp3uyqlY,6932
166
166
  machineconfig/scripts/python/helpers_cloud/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
167
167
  machineconfig/scripts/python/helpers_cloud/cloud_copy.py,sha256=OV1w3ajFVFs6FJytjIPOntYB_aW2ywGohKi73V4Dm2Y,8691
168
168
  machineconfig/scripts/python/helpers_cloud/cloud_helpers.py,sha256=GA-bxXouUmknk9fyQAsPT-Xl3RG9-yBed71a2tu9Pig,4914
@@ -171,19 +171,19 @@ machineconfig/scripts/python/helpers_cloud/cloud_sync.py,sha256=ThfI4rvKG6IPzAo3
171
171
  machineconfig/scripts/python/helpers_cloud/helpers2.py,sha256=3fXDiDlz5EDk_04YtPd-bjZcjUjmGTpgiQ1YMaGbD8g,7310
172
172
  machineconfig/scripts/python/helpers_cloud/helpers5.py,sha256=dPBvA9Tcyx9TMgM6On49A1CueGMhBdRzikDnlJGf3J0,1123
173
173
  machineconfig/scripts/python/helpers_croshell/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
174
- machineconfig/scripts/python/helpers_croshell/crosh.py,sha256=W6sG3qu8fNvuEXtogT6yFgJhqgXSEwIQ9zLHvijbszM,1524
174
+ machineconfig/scripts/python/helpers_croshell/crosh.py,sha256=FlK3qyMsbacM27Hq83JpXNOSlC4QSsF8B2665BEFs34,1620
175
175
  machineconfig/scripts/python/helpers_croshell/pomodoro.py,sha256=SPkfeoZGv8rylGiOyzQ7UK3aXZ3G2FIOuGkSuBUggOI,2019
176
176
  machineconfig/scripts/python/helpers_croshell/scheduler.py,sha256=rKhssuxkD697EY6qaV6CSdNhxpAQLDWO4fE8GMCQ9FA,3061
177
177
  machineconfig/scripts/python/helpers_croshell/start_slidev.py,sha256=HfJReOusTPhwcbAvCyJyTBd2iumJB5wmPdcTXz_Yvh8,4897
178
178
  machineconfig/scripts/python/helpers_croshell/viewer.py,sha256=heQNjB9fwn3xxbPgMofhv1Lp6Vtkl76YjjexWWBM0pM,2041
179
179
  machineconfig/scripts/python/helpers_croshell/viewer_template.py,sha256=ve3Q1-iKhCLc0VJijKvAeOYp2xaFOeIOC_XW956GWCc,3944
180
180
  machineconfig/scripts/python/helpers_devops/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
181
- machineconfig/scripts/python/helpers_devops/cli_config.py,sha256=mZlaV1eSrwg3nAev2b17PEAZ2-qg-xYC3EtqJ5k8iQk,5652
181
+ machineconfig/scripts/python/helpers_devops/cli_config.py,sha256=kbIULtkfHecOzfUA3gbRyRKxdIOXjitnoO3BH1HleEg,5654
182
182
  machineconfig/scripts/python/helpers_devops/cli_config_dotfile.py,sha256=rjTys4FNf9_feP9flWM7Zvq17dxWmetSiGaHPxp25nk,2737
183
183
  machineconfig/scripts/python/helpers_devops/cli_data.py,sha256=79Xvx7YnbueruEnl69hrDg2AhVxf_zCUdlVcKfeMGyQ,1774
184
184
  machineconfig/scripts/python/helpers_devops/cli_nw.py,sha256=B5Xa9pV5MdC4vPo3EmKaHvNMlThsY3c5F92YPE5j3rI,4176
185
185
  machineconfig/scripts/python/helpers_devops/cli_repos.py,sha256=Xwkv1adqHZvTfRSPWiqSK3PZ1XADyx3llw_YkbxaKyE,12505
186
- machineconfig/scripts/python/helpers_devops/cli_self.py,sha256=OWM83WqD_reebUxPkNhhU2EB8JoNZ-gFxyev6IGgURM,6167
186
+ machineconfig/scripts/python/helpers_devops/cli_self.py,sha256=-IyJpuw8Wnttls8y2vcNNkxtI9jUveROMPT-eudOoC4,6171
187
187
  machineconfig/scripts/python/helpers_devops/cli_share_server.py,sha256=q9pFJ6AxPuygMr3onMNOKEuuQHbVE_6Qoyo7xRT5FX0,4196
188
188
  machineconfig/scripts/python/helpers_devops/cli_terminal.py,sha256=k_PzXaiGyE0vXr0Ii1XcJz2A7UvyPJrR31TRWt4RKRI,6019
189
189
  machineconfig/scripts/python/helpers_devops/cli_utils.py,sha256=G2RHnOvNfEWjxETZjXVu688xyLL-c0Zq22p24kXLLQ8,3487
@@ -222,9 +222,9 @@ machineconfig/scripts/python/helpers_navigator/main_app.py,sha256=R1vOBMUKaiFHOg
222
222
  machineconfig/scripts/python/helpers_navigator/search_bar.py,sha256=kDi8Jhxap8wdm7YpDBtfhwcPnSqDPFrV2LqbcSBWMT4,414
223
223
  machineconfig/scripts/python/helpers_repos/action.py,sha256=9AxWy8mB9HFeV5t11-qD_l-KA5jkUmm0pXVKT1L6-Qk,14894
224
224
  machineconfig/scripts/python/helpers_repos/clone.py,sha256=UULEG5xJuXlPGU0nqXH6U45jA9DOFqLw8B4iPytCwOQ,5471
225
- machineconfig/scripts/python/helpers_repos/cloud_repo_sync.py,sha256=NlYJrRV7_2vnRm2EaMYGkoRwfdZi-BoGcO7ryziQs-0,10412
225
+ machineconfig/scripts/python/helpers_repos/cloud_repo_sync.py,sha256=fLWZN1ZRlfFvKQHBLyFNHayYZAYQTZqBerRcpb7XBII,10412
226
226
  machineconfig/scripts/python/helpers_repos/count_lines.py,sha256=Q5c7b-DxvTlQmljoic7niTuiAVyFlwYvkVQ7uRJHiTo,16009
227
- machineconfig/scripts/python/helpers_repos/count_lines_frontend.py,sha256=EWhoJV8rUAgnOKWTHLcO4TxXYXGmasCgVS0xUWtw8ZM,607
227
+ machineconfig/scripts/python/helpers_repos/count_lines_frontend.py,sha256=epbXDwuXe_9jXaX3KA2JlG1sPXybdGq1NX4dRljHpF8,607
228
228
  machineconfig/scripts/python/helpers_repos/entrypoint.py,sha256=WYEFGUJp9HWImlFjbs_hiFZrUqM_KEYm5VvSUjWd04I,2810
229
229
  machineconfig/scripts/python/helpers_repos/grource.py,sha256=oJj1-gqlkV3Z_BrIOXRmtzoXcuBl0xTYfulJ5D0srOc,14656
230
230
  machineconfig/scripts/python/helpers_repos/record.py,sha256=FQo0swuJZOp0I2XGK-t1OQU4zJHmQ2z9zTpDD30Tmg4,11001
@@ -238,7 +238,7 @@ machineconfig/scripts/python/nw/add_ssh_key.py,sha256=9JLmWu8pE7PAL5VuCFd19iVEdC
238
238
  machineconfig/scripts/python/nw/devops_add_identity.py,sha256=aPjcHbTLhxYwWYcandyAHdwuO15ZBu3fB82u6bI0tMQ,3773
239
239
  machineconfig/scripts/python/nw/devops_add_ssh_key.py,sha256=CkIl85hZLtG9k7yXLSzqi88YrilHV4hIUWHAPBwxWjw,8922
240
240
  machineconfig/scripts/python/nw/mount_drive,sha256=zemKofv7hOmRN_V3qK0q580GkfWw3VdikyVVQyiu8j8,3514
241
- machineconfig/scripts/python/nw/mount_nfs,sha256=3fbjsC6q8rFVGIM9Ax9ZTgqJ8Buqy1XX7cC6w9LoY14,1855
241
+ machineconfig/scripts/python/nw/mount_nfs,sha256=OCPbADc0AlkYOb0hcEWyHXOhjnnkA3uoP2uP5yqqwcQ,1855
242
242
  machineconfig/scripts/python/nw/mount_nfs.py,sha256=lOMDY4RS7tx8gsCazVR5tNNwFbaRyO2PJlnwBCDQgCM,3573
243
243
  machineconfig/scripts/python/nw/mount_nw_drive,sha256=BqjGBCbwe5ZAsZDO3L0zHhh_gJfZy1CYOcqXA4Y-WkQ,2262
244
244
  machineconfig/scripts/python/nw/mount_nw_drive.py,sha256=iru6AtnTyvyuk6WxlK5R4lDkuliVpPV5_uBTVVhXtjQ,1550
@@ -255,7 +255,7 @@ machineconfig/scripts/windows/fzfrga.bat,sha256=rU_KBMO6ii2EZ0akMnmDk9vpuhKSUZqk
255
255
  machineconfig/scripts/windows/mounts/mount_nfs.ps1,sha256=XrAdzpxE6a4OccSmWJ7YWHJTnsZK8uXnFE5j9GOPA20,2026
256
256
  machineconfig/scripts/windows/mounts/mount_nw.ps1,sha256=puxcfZc3ZCJerm8pj8OZGVoTYkhzp-h7oV-MrksSqIE,454
257
257
  machineconfig/scripts/windows/mounts/mount_smb.ps1,sha256=PzYWpIO9BpwXjdWlUQL9pnMRnOGNSkxfh4bHukJFme8,69
258
- machineconfig/scripts/windows/mounts/mount_ssh.ps1,sha256=HyfwTG1YyHLyg228fw3nHWCqBmcd_DNShm20KBrwg5E,322
258
+ machineconfig/scripts/windows/mounts/mount_ssh.ps1,sha256=eKKep-_E-eQLUEN8d3yPEjLaJF5yxE_L5l8_pBatGZU,322
259
259
  machineconfig/scripts/windows/mounts/share_cloud.cmd,sha256=exD7JCdxw2LqVjw2MKCYHbVZlEqmelXtwnATng-dhJ4,1028
260
260
  machineconfig/scripts/windows/mounts/share_smb.ps1,sha256=U7x8ULYSjbgzTtiHNSKQuTaZ_apilDvkGV5Xm5hXk5M,384
261
261
  machineconfig/scripts/windows/mounts/unlock_bitlocker.ps1,sha256=Wv-SLscdckV-1mG3p82VXKPY9zW3hgkRmcLUXIZ1daE,253
@@ -371,7 +371,11 @@ machineconfig/setup_linux/others/mint_keyboard_shortcuts.sh,sha256=F5dbg0n9RHsKG
371
371
  machineconfig/setup_linux/ssh/openssh_all.sh,sha256=3dg6HEUFbHQOzLfSAtzK_D_GB8rGCCp_aBnxNdnidVc,824
372
372
  machineconfig/setup_linux/ssh/openssh_wsl.sh,sha256=1eeRGrloVB34K5z8yWVUMG5b9pV-WBfHgV9jqXiYgCQ,1398
373
373
  machineconfig/setup_linux/web_shortcuts/android.sh,sha256=gzep6bBhK7FCBvGcXK0fdJCtkSfBOftt0aFyDZq_eMs,68
374
- machineconfig/setup_linux/web_shortcuts/interactive.sh,sha256=kk44iHWeYfn95NltBrye0eWkPyFyK1iFN6mFQb3hl2k,441
374
+ machineconfig/setup_linux/web_shortcuts/interactive.sh,sha256=4DjErSCQ4A2TUPYCkqFITqsJRfnViqZd0jWbVzx8JyQ,441
375
+ machineconfig/setup_mac/__init__.py,sha256=Q1waupi5vCBroLqc8Rtnw69_7jLnm2Cs7_zH_GSZgMs,616
376
+ machineconfig/setup_mac/apps.sh,sha256=R0N6fBwLCzwy4qAormyMerXXXrHazibSkY6NrNOpTQU,2772
377
+ machineconfig/setup_mac/uv.sh,sha256=CSN8oCBKS-LK1vJJqYOhAMcrouTf4Q_F3cpplc_ddMA,1157
378
+ machineconfig/setup_mac/ssh/openssh_setup.sh,sha256=TxfySnwFYg1UQLXmJbEQ2gfEWIT084F5JvNZI9ncpc0,3537
375
379
  machineconfig/setup_windows/__init__.py,sha256=NnSVZkIBoxoMgkj-_KAqGonH3YziBIWXOKDEcmNAGTY,386
376
380
  machineconfig/setup_windows/apps.ps1,sha256=dmZQZD4ZlNZo9jYkjIS3ag4qDAYZvaLysjmo9ELwBA4,11218
377
381
  machineconfig/setup_windows/uv.ps1,sha256=ukk1Abh-q-RfpoEqI2XTE2dcQJmHk0VFF6WqkK3TW8Q,350
@@ -381,16 +385,16 @@ machineconfig/setup_windows/others/power_options.ps1,sha256=c7Hn94jBD5GWF29CxMhm
381
385
  machineconfig/setup_windows/ssh/add-sshkey.ps1,sha256=qfPdqCpd9KP3VhH4ifsUm1Xvec7c0QVl4Wt8JIAm9HQ,1653
382
386
  machineconfig/setup_windows/ssh/add_identity.ps1,sha256=b8ZXpmNUSw3IMYvqSY7ClpdWPG39FS7MefoWnRhWN2U,506
383
387
  machineconfig/setup_windows/ssh/openssh-server.ps1,sha256=OMlYQdvuJQNxF5EILLPizB6BZAT3jAmDsv1WcVVxpFQ,2529
384
- machineconfig/setup_windows/web_shortcuts/interactive.ps1,sha256=FEGMTTGmhavoarHyxcNNdZis0FcD8JIIV5V8vJlZLss,547
388
+ machineconfig/setup_windows/web_shortcuts/interactive.ps1,sha256=AXszMmuVfiukqy_9E56G-0JzcDDitF0epTpqPqNG75A,547
385
389
  machineconfig/setup_windows/wt_and_pwsh/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
386
390
  machineconfig/setup_windows/wt_and_pwsh/set_wt_settings.py,sha256=ogxJnwpdcpH7N6dFJu95UCNoGYirZKQho_3X0F_hmXs,6791
387
391
  machineconfig/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
388
392
  machineconfig/utils/accessories.py,sha256=W_9dLzjwNTW5JQk_pe3B2ijQ1nA2-8Kdg2r7VBtzgQs,4340
389
393
  machineconfig/utils/code.py,sha256=W0JFDF1ynJJIYtrAP6IqCcmrhvS-_zyDz43etnWW7_4,7543
390
- machineconfig/utils/installer.py,sha256=wNkX2r6dlZD9zmuIkBKj5AliNPfI9zVWgtu8XqgUVIg,10204
394
+ machineconfig/utils/installer.py,sha256=afQgxDGsiS6HM0UQzQ85cPT4EcoXX2H0QOH5mQ18wtM,10391
391
395
  machineconfig/utils/io.py,sha256=4dSieoqZO8Vvi4vW8lLoITDHBvmFp4dtl3kyeZHQ6Co,2528
392
396
  machineconfig/utils/links.py,sha256=KM6vIn3hag9FYEzLSHP5MAM9tU_RStw2mCq2_OvmmZA,23672
393
- machineconfig/utils/meta.py,sha256=cXAXv0dFeS-G_ypjxhAN5Zo2Hc5C-GqAbf96ls6vrj0,10213
397
+ machineconfig/utils/meta.py,sha256=r557UPqgNLXzQpk8Umeujj9RnRBeIz3RwOwjZ7hWsw0,17309
394
398
  machineconfig/utils/notifications.py,sha256=tuXIudcip0tEioG-bm8BbLr3FMDve4f6BktlznBhKxM,9013
395
399
  machineconfig/utils/options.py,sha256=vUO4Kej-vDOv64wHr2HNDyu6PATURpjd7xp6N8OOoJg,7083
396
400
  machineconfig/utils/path_extended.py,sha256=WyJwoHnXdvSQQJ-yrxTX78FpqYmgVeKDYpNEB9UsRck,53223
@@ -399,7 +403,7 @@ machineconfig/utils/procs.py,sha256=YPA_vEYQGwPd_o_Lc6nOTBo5BrB1tSs8PJ42XiGpenM,
399
403
  machineconfig/utils/scheduler.py,sha256=44CASABJg3epccxhAwv2CX7TVgZh6zVy3K4vqHKTuf4,14228
400
404
  machineconfig/utils/scheduling.py,sha256=RF1iXJpqf4Dg18jdZWtBixz97KAHC6VKYqTFSpdLWuc,11188
401
405
  machineconfig/utils/source_of_truth.py,sha256=ZAnCRltiM07ig--P6g9_6nEAvNFC4X4ERFTVcvpIYsE,764
402
- machineconfig/utils/ssh.py,sha256=dpy7g3FWBopiC-WCniYxyjgai_sSgEMfSSLMcm8WwCY,39079
406
+ machineconfig/utils/ssh.py,sha256=pBGZPmai5x_9zhIsmd66xiZvHZLDVUbeOn8pBZibKp4,39079
403
407
  machineconfig/utils/terminal.py,sha256=IlmOByfQG-vjhaFFxxzU5rWzP5_qUzmalRfuey3PAmc,11801
404
408
  machineconfig/utils/tst.py,sha256=6u1GI49NdcpxH2BYGAusNfY5q9G_ytCGVzFM5b6HYpM,674
405
409
  machineconfig/utils/upgrade_packages.py,sha256=mSFyKvB3JhHte_x1dtmEgrJZCAXgTUQoaJUSx1OXQ3Y,4145
@@ -428,8 +432,8 @@ machineconfig/utils/schemas/installer/installer_types.py,sha256=QClRY61QaduBPJoS
428
432
  machineconfig/utils/schemas/layouts/layout_types.py,sha256=TcqlZdGVoH8htG5fHn1KWXhRdPueAcoyApppZsPAPto,2020
429
433
  machineconfig/utils/schemas/repos/repos_types.py,sha256=ECVr-3IVIo8yjmYmVXX2mnDDN1SLSwvQIhx4KDDQHBQ,405
430
434
  machineconfig/utils/ssh_utils/utils.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
431
- machineconfig-6.49.dist-info/METADATA,sha256=PsUcO81dHh_62I1kLsFutAMmEYSlR7AgfJm9KBzwaiQ,2928
432
- machineconfig-6.49.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
433
- machineconfig-6.49.dist-info/entry_points.txt,sha256=M0jwN_brZdXWhmNVeXLvdKxfkv8WhhXFZYcuKBA9qnk,418
434
- machineconfig-6.49.dist-info/top_level.txt,sha256=porRtB8qms8fOIUJgK-tO83_FeH6Bpe12oUVC670teA,14
435
- machineconfig-6.49.dist-info/RECORD,,
435
+ machineconfig-6.52.dist-info/METADATA,sha256=Utdnwcdeihed2hrfWbWheAB2vgB30EKxqNlPxUk6OSI,2928
436
+ machineconfig-6.52.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
437
+ machineconfig-6.52.dist-info/entry_points.txt,sha256=M0jwN_brZdXWhmNVeXLvdKxfkv8WhhXFZYcuKBA9qnk,418
438
+ machineconfig-6.52.dist-info/top_level.txt,sha256=porRtB8qms8fOIUJgK-tO83_FeH6Bpe12oUVC670teA,14
439
+ machineconfig-6.52.dist-info/RECORD,,