machineconfig 7.53__py3-none-any.whl → 7.69__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 (90) hide show
  1. machineconfig/cluster/sessions_managers/utils/maker.py +21 -9
  2. machineconfig/jobs/installer/custom/boxes.py +2 -2
  3. machineconfig/jobs/installer/custom/hx.py +15 -12
  4. machineconfig/jobs/installer/custom_dev/cloudflare_warp_cli.py +23 -0
  5. machineconfig/jobs/installer/custom_dev/dubdb_adbc.py +1 -1
  6. machineconfig/jobs/installer/custom_dev/nerfont_windows_helper.py +1 -1
  7. machineconfig/jobs/installer/custom_dev/sysabc.py +39 -34
  8. machineconfig/jobs/installer/custom_dev/wezterm.py +0 -4
  9. machineconfig/jobs/installer/installer_data.json +103 -35
  10. machineconfig/jobs/installer/package_groups.py +28 -13
  11. machineconfig/scripts/__init__.py +0 -4
  12. machineconfig/scripts/linux/wrap_mcfg +1 -1
  13. machineconfig/scripts/python/ai/solutions/copilot/instructions/python/dev.instructions.md +3 -0
  14. machineconfig/scripts/python/croshell.py +22 -17
  15. machineconfig/scripts/python/devops.py +3 -4
  16. machineconfig/scripts/python/devops_navigator.py +0 -4
  17. machineconfig/scripts/python/env_manager/path_manager_tui.py +1 -1
  18. machineconfig/scripts/python/fire_jobs.py +17 -15
  19. machineconfig/scripts/python/ftpx.py +13 -11
  20. machineconfig/scripts/python/helpers/ast_search.py +74 -0
  21. machineconfig/scripts/python/helpers/repo_rag.py +325 -0
  22. machineconfig/scripts/python/helpers/symantic_search.py +25 -0
  23. machineconfig/scripts/python/helpers_cloud/cloud_copy.py +28 -21
  24. machineconfig/scripts/python/helpers_cloud/cloud_helpers.py +1 -1
  25. machineconfig/scripts/python/helpers_cloud/cloud_sync.py +8 -7
  26. machineconfig/scripts/python/helpers_croshell/crosh.py +2 -2
  27. machineconfig/scripts/python/helpers_devops/cli_config_dotfile.py +22 -13
  28. machineconfig/scripts/python/helpers_devops/cli_self.py +7 -6
  29. machineconfig/scripts/python/helpers_devops/cli_share_file.py +2 -2
  30. machineconfig/scripts/python/helpers_devops/cli_share_server.py +1 -1
  31. machineconfig/scripts/python/helpers_devops/cli_terminal.py +1 -1
  32. machineconfig/scripts/python/helpers_devops/cli_utils.py +2 -73
  33. machineconfig/scripts/python/helpers_devops/devops_backup_retrieve.py +4 -4
  34. machineconfig/scripts/python/helpers_fire_command/file_wrangler.py +2 -3
  35. machineconfig/scripts/python/helpers_fire_command/fire_jobs_route_helper.py +3 -4
  36. machineconfig/scripts/python/helpers_navigator/command_tree.py +50 -18
  37. machineconfig/scripts/python/helpers_repos/cloud_repo_sync.py +13 -5
  38. machineconfig/scripts/python/helpers_repos/count_lines_frontend.py +1 -1
  39. machineconfig/scripts/python/helpers_repos/entrypoint.py +2 -1
  40. machineconfig/scripts/python/helpers_repos/record.py +2 -1
  41. machineconfig/scripts/python/helpers_sessions/sessions_multiprocess.py +5 -5
  42. machineconfig/scripts/python/helpers_utils/download.py +152 -0
  43. machineconfig/scripts/python/helpers_utils/path.py +4 -2
  44. machineconfig/scripts/python/interactive.py +11 -14
  45. machineconfig/scripts/python/{machineconfig.py → mcfg_entry.py} +4 -0
  46. machineconfig/scripts/python/msearch.py +21 -2
  47. machineconfig/scripts/python/nw/devops_add_ssh_key.py +21 -5
  48. machineconfig/scripts/python/nw/ssh_debug_linux.py +7 -7
  49. machineconfig/scripts/python/nw/ssh_debug_windows.py +4 -4
  50. machineconfig/scripts/python/nw/wsl_windows_transfer.py +3 -2
  51. machineconfig/scripts/python/sessions.py +35 -20
  52. machineconfig/scripts/python/terminal.py +2 -2
  53. machineconfig/scripts/python/utils.py +12 -10
  54. machineconfig/scripts/windows/mounts/mount_ssh.ps1 +1 -1
  55. machineconfig/settings/lf/windows/lfcd.ps1 +1 -1
  56. machineconfig/settings/shells/pwsh/init.ps1 +1 -0
  57. machineconfig/settings/shells/wezterm/wezterm.lua +2 -0
  58. machineconfig/settings/shells/zsh/init.sh +0 -7
  59. machineconfig/settings/yazi/shell/yazi_cd.ps1 +29 -5
  60. machineconfig/setup_linux/web_shortcuts/interactive.sh +12 -11
  61. machineconfig/setup_windows/uv.ps1 +8 -1
  62. machineconfig/setup_windows/web_shortcuts/interactive.ps1 +12 -11
  63. machineconfig/setup_windows/web_shortcuts/quick_init.ps1 +4 -2
  64. machineconfig/utils/accessories.py +7 -4
  65. machineconfig/utils/code.py +6 -4
  66. machineconfig/utils/files/headers.py +2 -2
  67. machineconfig/utils/installer_utils/install_from_url.py +180 -0
  68. machineconfig/utils/installer_utils/installer_class.py +56 -46
  69. machineconfig/utils/installer_utils/{installer.py → installer_cli.py} +71 -65
  70. machineconfig/utils/{installer.py → installer_utils/installer_runner.py} +1 -25
  71. machineconfig/utils/meta.py +28 -15
  72. machineconfig/utils/options.py +4 -4
  73. machineconfig/utils/path_extended.py +40 -19
  74. machineconfig/utils/path_helper.py +33 -31
  75. machineconfig/utils/schemas/layouts/layout_types.py +1 -1
  76. machineconfig/utils/ssh.py +330 -99
  77. machineconfig/utils/ve.py +11 -4
  78. machineconfig-7.69.dist-info/METADATA +124 -0
  79. {machineconfig-7.53.dist-info → machineconfig-7.69.dist-info}/RECORD +85 -83
  80. {machineconfig-7.53.dist-info → machineconfig-7.69.dist-info}/entry_points.txt +2 -2
  81. machineconfig/jobs/installer/linux_scripts/pgsql.sh +0 -41
  82. machineconfig/scripts/python/explore.py +0 -49
  83. machineconfig/scripts/python/nw/add_ssh_key.py +0 -148
  84. machineconfig/settings/lf/linux/exe/fzf_nano.sh +0 -16
  85. machineconfig-7.53.dist-info/METADATA +0 -94
  86. /machineconfig/jobs/installer/linux_scripts/{warp-cli.sh → cloudflare_warp_cli.sh} +0 -0
  87. /machineconfig/scripts/{Restore-ThunderbirdProfile.ps1 → windows/mounts/Restore-ThunderbirdProfile.ps1} +0 -0
  88. /machineconfig/utils/installer_utils/{installer_abc.py → installer_locator_utils.py} +0 -0
  89. {machineconfig-7.53.dist-info → machineconfig-7.69.dist-info}/WHEEL +0 -0
  90. {machineconfig-7.53.dist-info → machineconfig-7.69.dist-info}/top_level.txt +0 -0
@@ -19,9 +19,7 @@ for better user experience with checkbox selections.
19
19
 
20
20
  import sys
21
21
  from pathlib import Path
22
- # from typing import cast
23
22
  import platform
24
-
25
23
  import questionary
26
24
  from questionary import Choice
27
25
  from rich.console import Console
@@ -29,12 +27,11 @@ from rich.panel import Panel
29
27
  from rich.text import Text
30
28
  from machineconfig.utils.code import run_shell_script
31
29
 
32
- # _ = cast
33
30
  console = Console()
34
31
 
35
32
 
36
33
  def display_header() -> None:
37
- from machineconfig.utils.installer import get_machineconfig_version
34
+ from machineconfig.utils.installer_utils.installer_runner import get_machineconfig_version
38
35
  from rich.align import Align
39
36
 
40
37
  # Fancy ASCII art header
@@ -96,13 +93,13 @@ def display_dotfiles_instructions() -> None:
96
93
  def get_installation_choices() -> list[str]:
97
94
  """Get user choices for installation options."""
98
95
  choices = [
99
- Choice(value="install_machineconfig", title="🐍 Install machineconfig.", checked=False),
100
- Choice(value="sysabc", title="📥 Install Essential System Packages.", checked=False),
101
- Choice(value="termabc", title="⚡ Install Terminal CLI apps essentials", checked=False),
102
- Choice(value="install_shell_profile", title="🐚 Configure Shell Profile.", checked=False),
103
- Choice(value="install_ssh_server", title="🔒 Install SSH Server", checked=False),
104
- Choice(value="retrieve_repositories", title="📚 Retrieve Repositories", checked=False),
105
- Choice(value="retrieve_data", title="💾 Retrieve Data.", checked=False),
96
+ Choice(value="install_machineconfig", title="🐍 Install machineconfig cli.", checked=False),
97
+ Choice(value="sysabc", title="📥 Install System Package Manager (Needed for other apps to be installed).", checked=False),
98
+ Choice(value="termabc", title="⚡ Install Terminal CLI apps essentials (group `termabc`)", checked=False),
99
+ Choice(value="install_shell_profile", title="🐚 Configure Shell Profile And Map Other Configs.", checked=False),
100
+ Choice(value="install_ssh_server", title="🔒 [ADVANCED] Configure SSH Server", checked=False),
101
+ Choice(value="retrieve_repositories", title="📚 [ADVANCED] Retrieve Repositories", checked=False),
102
+ Choice(value="retrieve_data", title="💾 [ADVANCED] Retrieve Data.", checked=False),
106
103
  ]
107
104
  selected = questionary.checkbox("Select the installation options you want to execute:", choices=choices, show_description=True).ask()
108
105
  return selected or []
@@ -114,12 +111,11 @@ def execute_installations(selected_options: list[str]) -> None:
114
111
  console.print(Panel("⚡ [bold bright_yellow]CLI APPLICATIONS[/bold bright_yellow]\n[italic]Command-line tools installation[/italic]", border_style="bright_yellow"))
115
112
  console.print("🔧 Installing CLI applications", style="bold cyan")
116
113
  try:
117
- from machineconfig.utils.installer_utils.installer import main as devops_devapps_install_main
114
+ from machineconfig.utils.installer_utils.installer_cli import main_installer_cli as devops_devapps_install_main
118
115
  devops_devapps_install_main(group=True, which=maybe_a_group, interactive=False)
119
116
  console.print("✅ CLI applications installed successfully", style="bold green")
120
117
  except Exception as e:
121
118
  console.print(f"❌ Error installing CLI applications: {e}", style="bold red")
122
- import platform
123
119
  if platform.system() != "Windows":
124
120
  run_shell_script(". $HOME/.bashrc")
125
121
 
@@ -130,7 +126,6 @@ def execute_installations(selected_options: list[str]) -> None:
130
126
 
131
127
  if "install_ssh_server" in selected_options:
132
128
  console.print(Panel("🔒 [bold red]SSH SERVER[/bold red]\n[italic]Remote access setup[/italic]", border_style="red"))
133
- import platform
134
129
  if platform.system() == "Windows":
135
130
  powershell_script = """Write-Host "🔧 Installing and configuring SSH server..."
136
131
  Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
@@ -147,6 +142,8 @@ Set-Service -Name sshd -StartupType 'Automatic'"""
147
142
  from machineconfig.profile.create_shell_profile import create_default_shell_profile
148
143
  create_default_shell_profile()
149
144
  console.print("✅ Shell profile configured successfully", style="bold green")
145
+ from machineconfig.profile.create_links_export import main_public_from_parser
146
+ main_public_from_parser(method="copy", on_conflict="overwrite-default-path", which="all", interactive=False)
150
147
  if platform.system() == "Windows":
151
148
  from machineconfig.jobs.installer.custom_dev.nerfont_windows_helper import install_nerd_fonts
152
149
  install_nerd_fonts()
@@ -57,3 +57,7 @@ def get_app():
57
57
  def main():
58
58
  app = get_app()
59
59
  app()
60
+
61
+
62
+ if __name__ == "__main__":
63
+ main()
@@ -1,8 +1,27 @@
1
1
 
2
2
  import typer
3
+ from typing import Annotated
3
4
 
4
5
 
5
- def machineconfig_find():
6
+ def machineconfig_search(
7
+ directory: Annotated[str, typer.Option(..., "--directory", "-d", help="The directory to search")] = ".",
8
+ ast: Annotated[bool, typer.Option(..., "--ast", "-a", help="The abstract syntax tree search/ tree sitter search of symbols")] = False):
9
+
10
+ if ast:
11
+ from machineconfig.scripts.python.helpers.ast_search import get_repo_symbols
12
+ symbols = get_repo_symbols(directory)
13
+ from machineconfig.utils.options import choose_from_options
14
+ try:
15
+ res = choose_from_options(options=symbols, msg="Select a symbol to search for:", fzf=True, multi=False)
16
+ from rich import print_json
17
+ import json
18
+ res_json = json.dumps(res, indent=4)
19
+ print_json(res_json)
20
+ return None
21
+ except Exception as e:
22
+ print(f"❌ Error during selection: {e}")
23
+ return None
24
+
6
25
  from machineconfig.scripts.python.helpers_msearch import FZFG_LINUX_PATH, FZFG_WINDOWS_PATH
7
26
  import platform
8
27
  if platform.system() == "Linux":
@@ -17,5 +36,5 @@ def machineconfig_find():
17
36
 
18
37
  def main():
19
38
  app = typer.Typer(add_completion=False, no_args_is_help=True)
20
- app.command(name="msearch", help="machineconfig search helper", no_args_is_help=False)(machineconfig_find)
39
+ app.command(name="msearch", help="machineconfig search helper", no_args_is_help=False)(machineconfig_search)
21
40
  app()
@@ -13,9 +13,9 @@ import typer
13
13
  console = Console()
14
14
 
15
15
 
16
- def get_add_ssh_key_script(path_to_key: PathExtended):
16
+ def get_add_ssh_key_script(path_to_key: PathExtended) -> str:
17
17
  console.print(Panel("🔑 SSH KEY CONFIGURATION", title="[bold blue]SSH Setup[/bold blue]"))
18
- if system() == "Linux":
18
+ if system() == "Linux" or system() == "Darwin":
19
19
  authorized_keys = PathExtended.home().joinpath(".ssh/authorized_keys")
20
20
  console.print(Panel(f"🐧 Linux SSH configuration\n📄 Authorized keys file: {authorized_keys}", title="[bold blue]System Info[/bold blue]"))
21
21
  elif system() == "Windows":
@@ -35,7 +35,7 @@ def get_add_ssh_key_script(path_to_key: PathExtended):
35
35
  program = ""
36
36
  else:
37
37
  console.print(Panel(f"➕ Adding new SSH key to authorized keys\n🔑 Key file: {path_to_key.name}", title="[bold blue]Action[/bold blue]"))
38
- if system() == "Linux":
38
+ if system() == "Linux" or system() == "Darwin":
39
39
  program = f"cat {path_to_key} >> ~/.ssh/authorized_keys"
40
40
  elif system() == "Windows":
41
41
  program_path = LIBRARY_ROOT.joinpath("setup_windows/add-sshkey.ps1")
@@ -48,14 +48,14 @@ def get_add_ssh_key_script(path_to_key: PathExtended):
48
48
  raise NotImplementedError
49
49
  else:
50
50
  console.print(Panel(f"📝 Creating new authorized_keys file\n🔑 Using key: {path_to_key.name}", title="[bold blue]Action[/bold blue]"))
51
- if system() == "Linux":
51
+ if system() == "Linux" or system() == "Darwin":
52
52
  program = f"cat {path_to_key} > ~/.ssh/authorized_keys"
53
53
  else:
54
54
  program_path = LIBRARY_ROOT.joinpath("setup_windows/openssh-server_add-sshkey.ps1")
55
55
  program = PathExtended(program_path).expanduser().read_text(encoding="utf-8").replace('$sshfile=""', f'$sshfile="{path_to_key}"')
56
56
  console.print(Panel("🔧 Configured PowerShell script for Windows\n📝 Set key path in script", title="[bold blue]Configuration[/bold blue]"))
57
57
 
58
- if system() == "Linux":
58
+ if system() == "Linux" or system() == "Darwin":
59
59
  program += """
60
60
  sudo chmod 700 ~/.ssh
61
61
  sudo chmod 644 ~/.ssh/authorized_keys
@@ -66,6 +66,16 @@ sudo service ssh --full-restart
66
66
  return program
67
67
 
68
68
 
69
+ """
70
+ Common pitfalls:
71
+ 🚫 Wrong line endings (LF/CRLF) in config files
72
+ 🌐 Network port conflicts (try 2222 -> 2223) between WSL and Windows
73
+ sudo service ssh restart
74
+ sudo service ssh status
75
+ sudo nano /etc/ssh/sshd_config
76
+ """
77
+
78
+
69
79
  def main(pub_path: Annotated[Optional[str], typer.Argument(..., help="Path to the public key file")] = None,
70
80
  pub_choose: Annotated[bool, typer.Option(..., "--choose", "-c", help="Choose from available public keys in ~/.ssh")] = False,
71
81
  pub_val: Annotated[bool, typer.Option(..., "--paste", "-p", help="Paste the public key content manually")] = False,
@@ -127,6 +137,12 @@ def main(pub_path: Annotated[Optional[str], typer.Argument(..., help="Path to th
127
137
  console.print(Panel("🚀 SSH KEY AUTHORIZATION READY\nRun the generated script to apply changes", box=box.DOUBLE_EDGE, title_align="left"))
128
138
  from machineconfig.utils.code import run_shell_script
129
139
  run_shell_script(script=program)
140
+ import socket
141
+ s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
142
+ s.connect(('8.8.8.8', 80))
143
+ local_ip_v4 = s.getsockname()[0]
144
+ s.close()
145
+ console.print(Panel(f"🌐 This computer is accessible at: {local_ip_v4}", title="[bold green]Network Info[/bold green]", border_style="green"))
130
146
  console.print(Panel("✅ SSH KEY AUTHORIZATION COMPLETED", box=box.DOUBLE_EDGE, title_align="left"))
131
147
 
132
148
 
@@ -1,7 +1,7 @@
1
1
 
2
2
 
3
3
  from platform import system
4
- from machineconfig.utils.path_extended import PathExtended
4
+ from pathlib import Path
5
5
  from rich.console import Console
6
6
  from rich.panel import Panel
7
7
  from rich import box
@@ -26,7 +26,7 @@ def ssh_debug_linux() -> dict[str, dict[str, str | bool]]:
26
26
  results: dict[str, dict[str, str | bool]] = {}
27
27
  issues_found: list[str] = []
28
28
 
29
- ssh_dir = PathExtended.home().joinpath(".ssh")
29
+ ssh_dir = Path.home().joinpath(".ssh")
30
30
  authorized_keys = ssh_dir.joinpath("authorized_keys")
31
31
 
32
32
  console.print(Panel("🔐 Checking SSH directory and authorized_keys...", title="[bold blue]File Permissions[/bold blue]", border_style="blue"))
@@ -106,7 +106,7 @@ def ssh_debug_linux() -> dict[str, dict[str, str | bool]]:
106
106
 
107
107
  console.print(Panel("🔌 Checking SSH port and listening status...", title="[bold blue]Network Status[/bold blue]", border_style="blue"))
108
108
 
109
- sshd_config_paths = [PathExtended("/etc/ssh/sshd_config"), PathExtended("/etc/sshd_config")]
109
+ sshd_config_paths = [Path("/etc/ssh/sshd_config"), Path("/etc/sshd_config")]
110
110
  sshd_config = None
111
111
  for config_path in sshd_config_paths:
112
112
  if config_path.exists():
@@ -236,7 +236,7 @@ def ssh_debug_linux() -> dict[str, dict[str, str | bool]]:
236
236
 
237
237
  console.print(Panel("🗂️ Checking for problematic files in /etc/...", title="[bold blue]System Files[/bold blue]", border_style="blue"))
238
238
 
239
- hosts_deny = PathExtended("/etc/hosts.deny")
239
+ hosts_deny = Path("/etc/hosts.deny")
240
240
  if hosts_deny.exists():
241
241
  hosts_deny_content = hosts_deny.read_text(encoding="utf-8")
242
242
  active_lines = [line.strip() for line in hosts_deny_content.splitlines() if line.strip() and not line.strip().startswith("#")]
@@ -252,14 +252,14 @@ def ssh_debug_linux() -> dict[str, dict[str, str | bool]]:
252
252
  results["hosts_deny"] = {"status": "ok", "message": "/etc/hosts.deny does not exist", "action": ""}
253
253
  console.print(Panel("✅ /etc/hosts.deny not present", title="[bold green]OK[/bold green]", border_style="green"))
254
254
 
255
- hosts_allow = PathExtended("/etc/hosts.allow")
255
+ hosts_allow = Path("/etc/hosts.allow")
256
256
  if hosts_allow.exists():
257
257
  results["hosts_allow"] = {"status": "ok", "message": "/etc/hosts.allow exists (check if needed)", "action": ""}
258
258
  console.print(Panel("ℹ️ /etc/hosts.allow exists\n💡 Ensure it allows SSH if using TCP wrappers", title="[bold blue]Info[/bold blue]", border_style="blue"))
259
259
 
260
260
  console.print(Panel("👤 Checking home directory permissions...", title="[bold blue]User Permissions[/bold blue]", border_style="blue"))
261
261
 
262
- home_dir = PathExtended.home()
262
+ home_dir = Path.home()
263
263
  home_stat = os.stat(home_dir)
264
264
  home_perms = oct(home_stat.st_mode)[-3:]
265
265
 
@@ -294,7 +294,7 @@ def ssh_debug_linux() -> dict[str, dict[str, str | bool]]:
294
294
 
295
295
  console.print(Panel("📋 Checking SSH logs for errors...", title="[bold blue]Logs[/bold blue]", border_style="blue"))
296
296
 
297
- log_files = [PathExtended("/var/log/auth.log"), PathExtended("/var/log/secure")]
297
+ log_files = [Path("/var/log/auth.log"), Path("/var/log/secure")]
298
298
  log_found = False
299
299
  for log_file in log_files:
300
300
  if log_file.exists():
@@ -1,7 +1,7 @@
1
1
 
2
2
 
3
3
  from platform import system
4
- from machineconfig.utils.path_extended import PathExtended
4
+ from pathlib import Path
5
5
  from rich.console import Console
6
6
  from rich.panel import Panel
7
7
  from rich import box
@@ -26,7 +26,7 @@ def ssh_debug_windows() -> dict[str, dict[str, str | bool]]:
26
26
  results: dict[str, dict[str, str | bool]] = {}
27
27
  issues_found: list[str] = []
28
28
 
29
- ssh_dir = PathExtended.home().joinpath(".ssh")
29
+ ssh_dir = Path.home().joinpath(".ssh")
30
30
  authorized_keys = ssh_dir.joinpath("authorized_keys")
31
31
 
32
32
  console.print(Panel("🔐 Checking SSH directory and authorized_keys...", title="[bold blue]File Permissions[/bold blue]", border_style="blue"))
@@ -124,7 +124,7 @@ def ssh_debug_windows() -> dict[str, dict[str, str | bool]]:
124
124
 
125
125
  console.print(Panel("🔌 Checking SSH port and listening status...", title="[bold blue]Network Status[/bold blue]", border_style="blue"))
126
126
 
127
- sshd_config_paths = [PathExtended("C:\\ProgramData\\ssh\\sshd_config"), PathExtended(os.environ.get("PROGRAMDATA", "C:\\ProgramData")).joinpath("ssh", "sshd_config")]
127
+ sshd_config_paths = [Path("C:\\ProgramData\\ssh\\sshd_config"), Path(os.environ.get("PROGRAMDATA", "C:\\ProgramData")).joinpath("ssh", "sshd_config")]
128
128
  sshd_config = None
129
129
  for config_path in sshd_config_paths:
130
130
  if config_path.exists():
@@ -168,7 +168,7 @@ def ssh_debug_windows() -> dict[str, dict[str, str | bool]]:
168
168
  if admin_authorized_keys_lines:
169
169
  console.print(Panel("⚠️ IMPORTANT: Administrators group uses different authorized_keys location\n💡 For admin users, keys should be in: C:\\ProgramData\\ssh\\administrators_authorized_keys\n💡 Not in user's .ssh/authorized_keys!", title="[bold yellow]Admin Users[/bold yellow]", border_style="yellow"))
170
170
 
171
- programdata_auth_keys = PathExtended(os.environ.get("PROGRAMDATA", "C:\\ProgramData")).joinpath("ssh", "administrators_authorized_keys")
171
+ programdata_auth_keys = Path(os.environ.get("PROGRAMDATA", "C:\\ProgramData")).joinpath("ssh", "administrators_authorized_keys")
172
172
  if programdata_auth_keys.exists():
173
173
  console.print(Panel("✅ administrators_authorized_keys file exists", title="[bold green]OK[/bold green]", border_style="green"))
174
174
  else:
@@ -35,15 +35,16 @@ def main(
35
35
  print("=" * 50 + "\n")
36
36
 
37
37
  path_obj = PathExtended(path).expanduser().absolute()
38
+ relative_home = PathExtended(path_obj.expanduser().absolute().relative_to(Path.home()))
38
39
 
39
40
  if same_file_system:
40
41
  print("⚠️ Using a not recommended transfer method! Copying files across the same file system.")
41
42
  if system == "Windows": # move files over to WSL
42
43
  print("📤 Transferring files from Windows to WSL...")
43
- path_obj.copy(folder=WSL_FROM_WIN.joinpath(UserName).joinpath(path_obj.rel2home().parent), overwrite=True) # the following works for files and folders alike.
44
+ path_obj.copy(folder=WSL_FROM_WIN.joinpath(UserName).joinpath(relative_home.parent), overwrite=True) # the following works for files and folders alike.
44
45
  else: # move files from WSL to win
45
46
  print("📤 Transferring files from WSL to Windows...")
46
- path_obj.copy(folder=WIN_FROM_WSL.joinpath(UserName).joinpath(path_obj.rel2home().parent), overwrite=True)
47
+ path_obj.copy(folder=WIN_FROM_WSL.joinpath(UserName).joinpath(relative_home.parent), overwrite=True)
47
48
  print("✅ Transfer completed successfully!\n")
48
49
  else:
49
50
  from machineconfig.utils.ssh import SSH
@@ -1,32 +1,47 @@
1
1
 
2
- from pathlib import Path
3
2
  from typing import Optional, Literal, Annotated
4
3
  import typer
5
4
 
6
- def balance_load(layout_path: Annotated[Path, typer.Argument(..., help="Path to the layout.json file")],
7
- max_thresh: Annotated[int, typer.Option(..., help="Maximum tabs per layout")],
8
- thresh_type: Annotated[Literal['number', 'weight'], typer.Option(..., help="Threshold type")],
9
- breaking_method: Annotated[Literal['moreLayouts', 'combineTabs'], typer.Option(..., help="Breaking method")],
10
- output_path: Annotated[Optional[Path], typer.Option(..., help="Path to write the adjusted layout.json file")] = None):
5
+ def balance_load(layout_path: Annotated[str, typer.Argument(..., help="Path to the layout.json file")],
6
+ max_thresh: Annotated[int, typer.Option(..., "--max-threshold", "-m", help="Maximum tabs per layout")],
7
+ thresh_type: Annotated[Literal['number', 'n', 'weight', 'w'], typer.Option(..., "--threshold-type", "-t", help="Threshold type")],
8
+ breaking_method: Annotated[Literal['moreLayouts', 'ml', 'combineTabs', 'ct'], typer.Option(..., "--breaking-method", "-b", help="Breaking method")],
9
+ output_path: Annotated[Optional[str], typer.Option(..., "--output-path", "-o", help="Path to write the adjusted layout.json file")] = None):
11
10
  """Adjust layout file to limit max tabs per layout, etc."""
11
+ thresh_type_resolved: dict[str, Literal['number', 'weight']] = {
12
+ 'number': 'number',
13
+ 'n': 'number',
14
+ 'weight': 'weight',
15
+ 'w': 'weight'
16
+ }
17
+ breaking_method_resolved: dict[str, Literal['moreLayouts', 'combineTabs']] = {
18
+ 'moreLayouts': 'moreLayouts',
19
+ 'ml': 'moreLayouts',
20
+ 'combineTabs': 'combineTabs',
21
+ 'ct': 'combineTabs'
22
+ }
23
+ from pathlib import Path
24
+ layout_path_obj = Path(layout_path).expanduser().absolute()
25
+
12
26
  from machineconfig.utils.schemas.layouts.layout_types import LayoutsFile
13
27
  import json
14
- layoutfile: LayoutsFile = json.loads(layout_path.read_text())
28
+ layoutfile: LayoutsFile = json.loads(layout_path_obj.read_text())
15
29
  layout_configs = layoutfile["layouts"]
16
30
  from machineconfig.cluster.sessions_managers.utils.load_balancer import limit_tab_num
17
- new_layouts = limit_tab_num(layout_configs=layout_configs, max_thresh=max_thresh, threshold_type=thresh_type, breaking_method=breaking_method)
31
+ new_layouts = limit_tab_num(layout_configs=layout_configs, max_thresh=max_thresh, threshold_type=thresh_type_resolved[thresh_type], breaking_method=breaking_method_resolved[breaking_method])
18
32
  layoutfile["layouts"] = new_layouts
19
- target_file = output_path if output_path is not None else layout_path.parent / f'{layout_path.stem}_adjusted_{max_thresh}_{thresh_type}_{breaking_method}.json'
33
+ target_file = Path(output_path) if output_path is not None else layout_path_obj.parent / f'{layout_path_obj.stem}_adjusted_{max_thresh}_{thresh_type}_{breaking_method}.json'
20
34
  target_file.parent.mkdir(parents=True, exist_ok=True)
21
35
  target_file.write_text(data=json.dumps(layoutfile, indent=4), encoding="utf-8")
22
36
  typer.echo(f"Adjusted layout saved to {target_file}")
23
37
 
24
38
 
25
- def select_layout(layouts_json_file: Path, selected_layouts_names: Optional[list[str]], select_interactively: bool) -> list["LayoutConfig"]:
39
+ def select_layout(layouts_json_file: str, selected_layouts_names: Optional[list[str]], select_interactively: bool) -> list["LayoutConfig"]:
26
40
  import json
27
41
  from machineconfig.utils.options import choose_from_options
28
42
  from machineconfig.utils.schemas.layouts.layout_types import LayoutsFile
29
- layout_file: LayoutsFile = json.loads(layouts_json_file.read_text(encoding="utf-8"))
43
+ from pathlib import Path
44
+ layout_file: LayoutsFile = json.loads(Path(layouts_json_file).read_text(encoding="utf-8"))
30
45
  if len(layout_file["layouts"]) == 0:
31
46
  raise ValueError(f"No layouts found in {layouts_json_file}")
32
47
  if selected_layouts_names is None: # choose all, or interactively
@@ -49,35 +64,35 @@ def select_layout(layouts_json_file: Path, selected_layouts_names: Optional[list
49
64
  return layouts_chosen
50
65
 
51
66
 
52
- def find_layout_file(layout_path: str, ) -> Path:
53
- from machineconfig.utils.path_extended import PathExtended
67
+ def find_layout_file(layout_path: str, ) -> str:
54
68
  from machineconfig.utils.path_helper import search_for_files_of_interest
55
69
  from machineconfig.utils.options import choose_from_options
56
70
  from machineconfig.utils.path_helper import match_file_name, sanitize_path
71
+ from pathlib import Path
57
72
  path_obj = sanitize_path(layout_path)
58
73
  if not path_obj.exists():
59
- choice_file = match_file_name(sub_string=layout_path, search_root=PathExtended.cwd(), suffixes={".json"})
74
+ choice_file = match_file_name(sub_string=layout_path, search_root=Path.cwd(), suffixes={".json"})
60
75
  elif path_obj.is_dir():
61
76
  print(f"🔍 Searching recursively for Python, PowerShell and Shell scripts in directory `{path_obj}`")
62
77
  files = search_for_files_of_interest(path_obj, suffixes={".py", ".sh", ".ps1"})
63
78
  print(f"🔍 Got #{len(files)} results.")
64
79
  choice_file = choose_from_options(multi=False, options=files, fzf=True, msg="Choose one option")
65
- choice_file = PathExtended(choice_file)
80
+ choice_file = Path(choice_file).expanduser().absolute()
66
81
  else:
67
82
  choice_file = path_obj
68
- return choice_file
83
+ return str(choice_file)
69
84
 
70
85
 
71
86
  def run(ctx: typer.Context,
72
87
  layout_path: Annotated[Optional[str], typer.Argument(..., help="Path to the layout.json file")] = None,
73
- max_tabs: Annotated[int, typer.Option(..., help="A Sanity checker that throws an error if any layout exceeds the maximum number of tabs to launch.")] = 10,
74
- max_layouts: Annotated[int, typer.Option(..., help="A Sanity checker that throws an error if the total number of *parallel layouts exceeds this number.")] = 10,
75
- sleep_inbetween: Annotated[float, typer.Option(..., help="Sleep time in seconds between launching layouts")] = 1.0,
88
+ max_tabs: Annotated[int, typer.Option(..., "--max-tabs", "-mt", help="A Sanity checker that throws an error if any layout exceeds the maximum number of tabs to launch.")] = 10,
89
+ max_layouts: Annotated[int, typer.Option(..., "--max-layouts", "-ml", help="A Sanity checker that throws an error if the total number of *parallel layouts exceeds this number.")] = 10,
90
+ sleep_inbetween: Annotated[float, typer.Option(..., "--sleep-inbetween", "-si", help="Sleep time in seconds between launching layouts")] = 1.0,
76
91
  monitor: Annotated[bool, typer.Option(..., "--monitor", "-m", help="Monitor the layout sessions for completion")] = False,
77
92
  parallel: Annotated[bool, typer.Option(..., "--parallel", "-p", help="Launch multiple layouts in parallel")] = False,
78
93
  kill_upon_completion: Annotated[bool, typer.Option(..., "--kill-upon-completion", "-k", help="Kill session(s) upon completion (only relevant if monitor flag is set)")] = False,
79
94
  choose: Annotated[Optional[str], typer.Option(..., "--choose", "-c", help="Comma separated names of layouts to be selected from the layout file passed")] = None,
80
- choose_interactively: Annotated[bool, typer.Option(..., "--choose-interactively", "-ia", help="Select layouts interactively")] = False
95
+ choose_interactively: Annotated[bool, typer.Option(..., "--choose-interactively", "-i", help="Select layouts interactively")] = False
81
96
  ):
82
97
  """
83
98
  Launch terminal sessions based on a layout configuration file.
@@ -1,5 +1,3 @@
1
- import subprocess
2
- # from machineconfig.utils.schemas.layouts.layout_types import LayoutConfig
3
1
  import typer
4
2
  from typing import Annotated
5
3
 
@@ -26,6 +24,7 @@ def choose_zellij_session(
26
24
  typer.Exit()
27
25
  return
28
26
  cmd = "zellij list-sessions"
27
+ import subprocess
29
28
  sessions: list[str] = subprocess.check_output(cmd, shell=True).decode().strip().split("\n")
30
29
  # filter out empty lines and keep raw lines (they contain creation info)
31
30
  sessions = [s for s in sessions if s.strip()]
@@ -63,6 +62,7 @@ def choose_zellij_session(
63
62
 
64
63
  def get_session_tabs() -> list[tuple[str, str]]:
65
64
  cmd = "zellij list-sessions"
65
+ import subprocess
66
66
  sessions: list[str] = subprocess.check_output(cmd, shell=True).decode().strip().split("\n")
67
67
  sessions = [strip_ansi_codes(s) for s in sessions]
68
68
  active_sessions = [s for s in sessions if "EXITED" not in s]
@@ -1,10 +1,12 @@
1
1
 
2
2
 
3
- from machineconfig.scripts.python.helpers_devops.cli_utils import download, merge_pdfs, compress_pdf
3
+ from machineconfig.scripts.python.helpers_devops.cli_utils import merge_pdfs, compress_pdf
4
4
  from machineconfig.scripts.python.helpers_utils.path import edit_file_with_hx, get_machine_specs, init_project, path
5
+ from machineconfig.scripts.python.helpers_utils.download import download
5
6
  import typer
6
7
  from typing import Annotated
7
8
 
9
+
8
10
  def kill_process(
9
11
  # name: Annotated[Optional[str], typer.Option(..., "--name", "-n", help="Name of the process to kill")],
10
12
  # command: Annotated[str, typer.Option(..., "--command", "-c", help="Match by command line instead of process name")] = "",
@@ -28,27 +30,27 @@ def upgrade_packages():
28
30
 
29
31
  def get_app() -> typer.Typer:
30
32
  app = typer.Typer(help="🛠️ utilities operations", no_args_is_help=True, add_help_option=False, add_completion=False)
31
- app.command(name="kill-process", no_args_is_help=False, help="[k] Choose a process to kill")(kill_process)
33
+ app.command(name="kill-process", no_args_is_help=False, help="⚔️ [k] Choose a process to kill")(kill_process)
32
34
  app.command(name="k", no_args_is_help=False, help="Choose a process to kill", hidden=True)(kill_process)
33
35
 
34
- app.command("path", no_args_is_help=False, help="📚 [p] NAVIGATE PATH variable with TUI")(path)
36
+ app.command("path", no_args_is_help=False, help="📚 [p] NAVIGATE PATH variable with TUI")(path)
35
37
  app.command("p", no_args_is_help=False, help="NAVIGATE PATH variable with TUI", hidden=True)(path)
36
38
 
37
- app.command(name="upgrade-packages", no_args_is_help=False, help="[up] Upgrade project dependencies.")(upgrade_packages)
39
+ app.command(name="upgrade-packages", no_args_is_help=False, help="⬆️ [up] Upgrade project dependencies.")(upgrade_packages)
38
40
  app.command(name="up", no_args_is_help=False, hidden=True)(upgrade_packages)
39
41
 
40
- app.command(name="download", no_args_is_help=True, help="[d] Download a file from a URL and optionally decompress it.")(download)
42
+ app.command(name="download", no_args_is_help=True, help="⬇️ [d] Download a file from a URL and optionally decompress it.")(download)
41
43
  app.command(name="d", no_args_is_help=True, hidden=True)(download)
42
- app.command(name="get-machine-specs", no_args_is_help=False, help="[g] Get machine specifications.")(get_machine_specs)
44
+ app.command(name="get-machine-specs", no_args_is_help=False, help="💻 [g] Get machine specifications.")(get_machine_specs)
43
45
  app.command(name="g", no_args_is_help=False, hidden=True)(get_machine_specs)
44
- app.command(name="init-project", no_args_is_help=False, help="[i] Initialize a project with a uv virtual environment and install dev packages.")(init_project)
46
+ app.command(name="init-project", no_args_is_help=False, help="🚀 [i] Initialize a project with a uv virtual environment and install dev packages.")(init_project)
45
47
  app.command(name="i", no_args_is_help=False, hidden=True)(init_project)
46
- app.command(name="edit", no_args_is_help=False, help="[e] Open a file in the default editor.")(edit_file_with_hx)
48
+ app.command(name="edit", no_args_is_help=False, help="✏️ [e] Open a file in the default editor.")(edit_file_with_hx)
47
49
  app.command(name="e", no_args_is_help=False, hidden=True)(edit_file_with_hx)
48
50
 
49
- app.command(name="pdf-merge", no_args_is_help=True, help="[pm] Merge two PDF files into one.")(merge_pdfs)
51
+ app.command(name="pdf-merge", no_args_is_help=True, help="📄 [pm] Merge two PDF files into one.")(merge_pdfs)
50
52
  app.command(name="pm", no_args_is_help=True, hidden=True)(merge_pdfs)
51
- app.command(name="pdf-compress", no_args_is_help=True, help="[pc] Compress a PDF file.")(compress_pdf)
53
+ app.command(name="pdf-compress", no_args_is_help=True, help="📦 [pc] Compress a PDF file.")(compress_pdf)
52
54
  app.command(name="pc", no_args_is_help=True, hidden=True)(compress_pdf)
53
55
 
54
56
  # app.command(name="copy", no_args_is_help=True, help="[c] Copy files or directories.")(copy)
@@ -7,7 +7,7 @@ $user = ''
7
7
  $sharePath = ''
8
8
  $driveLetter = ''
9
9
 
10
- uv run --python 3.14 --with "machineconfig>=7.53" python -m machineconfig.scripts.python.mount_ssh
10
+ uv run --python 3.14 --with "machineconfig>=7.69" 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
@@ -17,7 +17,7 @@
17
17
 
18
18
  function lfcd {
19
19
  $tmp = [System.IO.Path]::GetTempFileName()
20
- ~\AppData\Local\Microsoft\WindowsApps\lf.exe -last-dir-path="$tmp" $args
20
+ & "$env:USERPROFILE\AppData\Local\Microsoft\WindowsApps\lf.exe" -last-dir-path="$tmp" $args
21
21
  if (Test-Path -PathType Leaf "$tmp")
22
22
  {
23
23
  $dir = Get-Content "$tmp"
@@ -15,6 +15,7 @@ function Add-ToPathIfNotAlready {
15
15
  }
16
16
 
17
17
  Add-ToPathIfNotAlready -Directories @(
18
+ "$HOME\.local\bin",
18
19
  "$CONFIG_ROOT\scripts",
19
20
  "$HOME\dotfiles\scripts\windows",
20
21
  "C:\Program Files (x86)\GnuWin32\bin",
@@ -190,4 +190,6 @@ end
190
190
 
191
191
 
192
192
  -- and finally, return the configuration to wezterm
193
+ -- config.enable_osc133 = false -- to silence: P>|WezTerm 20240203-110809-5046fc22\
194
+
193
195
  return config
@@ -72,15 +72,9 @@ alias x='. $CONFIG_ROOT/scripts/wrap_mcfg explore'
72
72
  # gh copilot explain "Input command is: $x The output is this: $y"
73
73
  # }
74
74
 
75
- # 📦 Node Version Manager
76
- # export NVM_DIR="$HOME/.nvm"
77
- # [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
78
- # [ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion
79
-
80
75
 
81
76
  # https://github.com/atuinsh/atuin
82
77
  # eval "$(atuin init bash)"
83
-
84
78
  # source /home/alex/.config/broot/launcher/bash/br
85
79
  # eval "$(thefuck --alias)"
86
80
  # from https://github.com/ajeetdsouza/zoxide
@@ -90,7 +84,6 @@ eval "$(starship init zsh)"
90
84
  # LEVE THIS IN THE END TO AVOID EXECUTION FAILURE OF THE REST OF THE SCRIPT
91
85
  # from https://github.com/cantino/mcfly
92
86
  eval "$(mcfly init zsh)"
93
-
94
87
  # Show elapsed runtime
95
88
  # _show_elapsed
96
89
 
@@ -1,9 +1,33 @@
1
+ # function y {
2
+ # $tmp = (New-TemporaryFile).FullName
3
+ # yazi $args --cwd-file="$tmp"
4
+ # $cwd = Get-Content -Path $tmp -Encoding UTF8
5
+ # if (-not [String]::IsNullOrEmpty($cwd) -and $cwd -ne $PWD.Path) {
6
+ # Set-Location -LiteralPath (Resolve-Path -LiteralPath $cwd).Path
7
+ # }
8
+ # Remove-Item -Path $tmp
9
+ # }
1
10
  function y {
11
+ # Save + temporarily disable WezTerm/Starship prompt marking
12
+ $oldWez = $env:WEZTERM_SHELL_SKIP_ALL
13
+ $env:WEZTERM_SHELL_SKIP_ALL = "1" # tells WezTerm integration to skip markers (supported knob)
14
+ $oldTransient = $env:STARSHIP_DISABLE_TRANSIENT_PROMPT
15
+ $env:STARSHIP_DISABLE_TRANSIENT_PROMPT = "true"
16
+
2
17
  $tmp = (New-TemporaryFile).FullName
3
- yazi $args --cwd-file="$tmp"
4
- $cwd = Get-Content -Path $tmp -Encoding UTF8
5
- if (-not [String]::IsNullOrEmpty($cwd) -and $cwd -ne $PWD.Path) {
6
- Set-Location -LiteralPath (Resolve-Path -LiteralPath $cwd).Path
18
+ try {
19
+ yazi $args --cwd-file="$tmp"
20
+ $cwd = Get-Content -Path $tmp -Encoding UTF8
21
+ if (-not [string]::IsNullOrEmpty($cwd) -and $cwd -ne $PWD.Path) {
22
+ Set-Location -LiteralPath (Resolve-Path -LiteralPath $cwd).Path
23
+ }
24
+ } finally {
25
+ # Clean up temp file
26
+ Remove-Item -Path $tmp -ErrorAction SilentlyContinue
27
+ # Restore env
28
+ if ($null -ne $oldWez) { $env:WEZTERM_SHELL_SKIP_ALL = $oldWez } else { Remove-Item Env:\WEZTERM_SHELL_SKIP_ALL -ErrorAction SilentlyContinue }
29
+ if ($null -ne $oldTransient) { $env:STARSHIP_DISABLE_TRANSIENT_PROMPT = $oldTransient } else { Remove-Item Env:\STARSHIP_DISABLE_TRANSIENT_PROMPT -ErrorAction SilentlyContinue }
30
+ # Nudge terminal back to sane modes (cursor on, no mouse, no bracketed paste)
31
+ Write-Host -NoNewline "`e[0m`e[?25h`e[?1000l`e[?1002l`e[?1006l`e[?2004l"
7
32
  }
8
- Remove-Item -Path $tmp
9
33
  }
@@ -2,16 +2,16 @@
2
2
  . <( curl -sSL "https://raw.githubusercontent.com/thisismygitrepo/machineconfig/main/src/machineconfig/setup_linux/uv.sh")
3
3
  . <( curl -sSL "https://raw.githubusercontent.com/thisismygitrepo/machineconfig/main/src/machineconfig/scripts/linux/wrap_mcfg")
4
4
 
5
- alias devops='$HOME/.local/bin/uvx --python 3.14 --from "machineconfig>=7.53" devops'
6
- alias cloud='$HOME/.local/bin/uvx --python 3.14 --from "machineconfig>=7.53" cloud'
7
- alias agents='$HOME/.local/bin/uvx --python 3.14 --from "machineconfig>=7.53" agents'
8
- alias sessions='$HOME/.local/bin/uvx --python 3.14 --from "machineconfig>=7.53" sessions'
9
- alias ftpx='$HOME/.local/bin/uvx --python 3.14 --from "machineconfig>=7.53" ftpx'
10
- alias fire='$HOME/.local/bin/uvx --python 3.14 --from "machineconfig>=7.53" fire'
11
- alias croshell='$HOME/.local/bin/uvx --python 3.14 --from "machineconfig>=7.53" croshell'
12
- alias utils='$HOME/.local/bin/uvx --python 3.14 --from "machineconfig>=7.53" utils'
13
- alias terminal='$HOME/.local/bin/uvx --python 3.14 --from "machineconfig>=7.53" terminal'
14
- alias msearch='$HOME/.local/bin/uvx --python 3.14 --from "machineconfig>=7.53" msearch'
5
+ alias devops='$HOME/.local/bin/uvx --python 3.14 --from "machineconfig>=7.69" devops'
6
+ alias cloud='$HOME/.local/bin/uvx --python 3.14 --from "machineconfig>=7.69" cloud'
7
+ alias agents='$HOME/.local/bin/uvx --python 3.14 --from "machineconfig>=7.69" agents'
8
+ alias sessions='$HOME/.local/bin/uvx --python 3.14 --from "machineconfig>=7.69" sessions'
9
+ alias ftpx='$HOME/.local/bin/uvx --python 3.14 --from "machineconfig>=7.69" ftpx'
10
+ alias fire='$HOME/.local/bin/uvx --python 3.14 --from "machineconfig>=7.69" fire'
11
+ alias croshell='$HOME/.local/bin/uvx --python 3.14 --from "machineconfig>=7.69" croshell'
12
+ alias utils='$HOME/.local/bin/uvx --python 3.14 --from "machineconfig>=7.69" utils'
13
+ alias terminal='$HOME/.local/bin/uvx --python 3.14 --from "machineconfig>=7.69" terminal'
14
+ alias msearch='$HOME/.local/bin/uvx --python 3.14 --from "machineconfig>=7.69" msearch'
15
15
 
16
16
  alias d='wrap_in_shell_script devops'
17
17
  alias c='wrap_in_shell_script cloud'
@@ -24,5 +24,6 @@ alias u='wrap_in_shell_script utils'
24
24
  alias t='wrap_in_shell_script terminal'
25
25
  alias ms='wrap_in_shell_script msearch'
26
26
 
27
- devops self
28
27
  echo "mcfg command aliases are now defined in this shell session."
28
+
29
+ devops self interactive