machineconfig 3.97__py3-none-any.whl → 3.98__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.

@@ -1,22 +1,18 @@
1
1
  """devops with emojis"""
2
2
 
3
- from machineconfig.utils.options import choose_from_options
3
+ from machineconfig.scripts.python.share_terminal import main as share_terminal_main
4
+ import machineconfig.scripts.python.devops_devapps_install as installer_entry_point
4
5
 
5
6
  from platform import system
6
- from typing import Optional, Literal, TypeAlias
7
7
  from rich.console import Console
8
8
  from rich.panel import Panel
9
9
  import typer
10
10
 
11
11
  console = Console()
12
- app = typer.Typer(help="🛠️ DevOps operations with emojis", invoke_without_command=True, no_args_is_help=True)
12
+ app = typer.Typer(help="🛠️ DevOps operations with emojis", no_args_is_help=True)
13
13
 
14
- BOX_WIDTH = 150 # width for box drawing
15
-
16
-
17
- COMMANDS: TypeAlias = Literal["🔄 UPDATE essential repos", "⚙️ DEVAPPS install", "🔗 SYMLINKS, SHELL PROFILE, FONT, TERMINAL SETTINGS.", "🆕 SYMLINKS new", "🔑 SSH add pub key to this machine", "🗝️ SSH add identity (private key) to this machine", "🔐 SSH use key pair to connect two machines", "📡 SSH setup", "🐧 SSH setup wsl", "💾 BACKUP", "📥 RETRIEVE", "⏰ SCHEDULER"]
18
14
 
19
- options_list = list(COMMANDS.__args__)
15
+ BOX_WIDTH = 150 # width for box drawing
20
16
 
21
17
 
22
18
  @app.command()
@@ -27,12 +23,9 @@ def update():
27
23
  helper.main()
28
24
 
29
25
 
30
- @app.command()
31
- def install():
32
- """⚙️ DEVAPPS install"""
33
- console.print(Panel("⚙️ Installing development applications...", width=BOX_WIDTH, border_style="blue"))
34
- import machineconfig.scripts.python.devops_devapps_install as helper
35
- helper.main(which=None)
26
+ app.command(name="install")(installer_entry_point.main)
27
+ app.command(name="share-terminal", help="📡 Share terminal via web browser")(share_terminal_main)
28
+
36
29
 
37
30
 
38
31
  @app.command()
@@ -123,55 +116,11 @@ def scheduler():
123
116
  # from machineconfig.scripts.python.scheduler import main as helper
124
117
  # helper()
125
118
 
126
-
127
- def args_parser():
128
- app()
129
-
130
-
131
- @app.command()
132
- def interactive(which: Optional[COMMANDS] = None):
133
- """🛠️ Interactive menu mode (legacy)"""
134
- console.print(Panel("🚀 Initializing DevOps operation...", width=BOX_WIDTH, border_style="blue"))
135
- options = options_list
136
- if which is None:
137
- try:
138
- choice_key = choose_from_options(msg="", options=options, header="🛠️ DEVOPS", default=options[0], multi=False, fzf=False)
139
- except KeyboardInterrupt:
140
- console.print(Panel("❌ Operation cancelled by user", title_align="left", border_style="red", width=BOX_WIDTH))
141
- return
142
- else:
143
- choice_key = which
144
-
145
- console.print(Panel(f"🔧 SELECTED OPERATION\n{choice_key}", title_align="left", border_style="green", width=BOX_WIDTH))
146
-
147
- if choice_key == "🔄 UPDATE essential repos":
148
- update()
149
- elif choice_key == "⚙️ DEVAPPS install":
150
- install()
151
- elif choice_key == "🆕 SYMLINKS new":
152
- symlinks_new()
153
- elif choice_key == "🔗 SYMLINKS, SHELL PROFILE, FONT, TERMINAL SETTINGS.":
154
- symlinks()
155
- elif choice_key == "🔑 SSH add pub key to this machine":
156
- ssh_add_key()
157
- elif choice_key == "🔐 SSH use key pair to connect two machines":
158
- ssh_connect()
159
- elif choice_key == "🗝️ SSH add identity (private key) to this machine":
160
- ssh_add_identity()
161
- elif choice_key == "📡 SSH setup":
162
- ssh_setup()
163
- elif choice_key == "🐧 SSH setup wsl":
164
- ssh_setup_wsl()
165
- elif choice_key == "💾 BACKUP":
166
- backup()
167
- elif choice_key == "📥 RETRIEVE":
168
- retrieve()
169
- elif choice_key == "⏰ SCHEDULER":
170
- scheduler()
171
- else:
172
- console.print(Panel("❌ ERROR: Invalid choice", title_align="left", border_style="red", width=BOX_WIDTH))
173
- raise ValueError(f"Unimplemented choice: {choice_key}")
119
+ @app.command("ia")
120
+ def interactive():
121
+ from machineconfig.scripts.python.interactive import main
122
+ main()
174
123
 
175
124
 
176
125
  if __name__ == "__main__":
177
- args_parser()
126
+ pass
@@ -1,16 +1,11 @@
1
1
  """Devops Devapps Install"""
2
2
 
3
- # import subprocess
4
3
  import typer
5
4
  from rich.progress import Progress, SpinnerColumn, TextColumn
6
- from machineconfig.utils.source_of_truth import LIBRARY_ROOT
7
- from machineconfig.utils.options import choose_from_options
8
- from machineconfig.utils.installer import get_installers, install_all
9
- from machineconfig.utils.schemas.installer.installer_types import get_normalized_arch, get_os_name
10
5
  from platform import system
11
- from typing import Any, Optional, Literal, TypeAlias, get_args, Annotated
6
+ from typing import Optional, Literal, TypeAlias, cast, get_args, Annotated
12
7
 
13
- WHICH_CAT: TypeAlias = Literal["essentials", "essentialsDev", "systymPackages", "precheckedPackages"]
8
+ WHICH_CAT: TypeAlias = Literal["essentials", "essentialsDev", "systymPackages", "precheckedPackages", "ia"]
14
9
 
15
10
 
16
11
  def main_with_parser():
@@ -20,11 +15,12 @@ def main_with_parser():
20
15
  app()
21
16
 
22
17
 
23
- def main(which: Annotated[Optional[str], typer.Argument(help=f"Choose a category or program to install, {list(get_args(WHICH_CAT))} or <program_name>")]) -> None:
24
- if which is not None and which in get_args(WHICH_CAT): # install by category
18
+ def main(which: Annotated[Optional[str], typer.Argument(help=f"Choose a category or program to install, {list(get_args(WHICH_CAT))} or <program_name> or list of programs names separated by comma.")]) -> None:
19
+ if which in get_args(WHICH_CAT): # install by category
25
20
  return get_programs_by_category(program_name=which) # type: ignore
26
-
27
- if which is not None: # install by name
21
+ from machineconfig.utils.schemas.installer.installer_types import get_normalized_arch, get_os_name
22
+ from machineconfig.utils.installer import get_installers
23
+ if which != "ia" and which is not None: # install by name
28
24
  total_messages: list[str] = []
29
25
  for a_which in which.split(",") if type(which) == str else which:
30
26
  all_installers = get_installers(os=get_os_name(), arch=get_normalized_arch(), which_cats=["GITHUB_ESSENTIAL", "CUSTOM_ESSENTIAL", "GITHUB_DEV", "CUSTOM_DEV"])
@@ -53,6 +49,12 @@ def main(which: Annotated[Optional[str], typer.Argument(help=f"Choose a category
53
49
  print(a_message)
54
50
  return None
55
51
 
52
+
53
+
54
+ def install_interactively():
55
+ from machineconfig.utils.options import choose_from_options
56
+ from machineconfig.utils.schemas.installer.installer_types import get_normalized_arch, get_os_name
57
+ from machineconfig.utils.installer import get_installers
56
58
  installers = get_installers(os=get_os_name(), arch=get_normalized_arch(), which_cats=["GITHUB_ESSENTIAL", "CUSTOM_ESSENTIAL", "GITHUB_DEV", "CUSTOM_DEV"])
57
59
  # Check installed programs with progress indicator
58
60
  with Progress(SpinnerColumn(), TextColumn("[progress.description]{task.description}")) as progress:
@@ -84,8 +86,7 @@ def main(which: Annotated[Optional[str], typer.Argument(help=f"Choose a category
84
86
  if a_program_name.startswith("📦 "):
85
87
  category_name = a_program_name[2:] # Remove "📦 " prefix
86
88
  if category_name in get_args(WHICH_CAT):
87
- shell_commands = get_programs_by_category(program_name=category_name) # type: ignore
88
- total_commands += "\n" + shell_commands
89
+ get_programs_by_category(program_name=cast(WHICH_CAT, category_name))
89
90
  else:
90
91
  # Handle individual installer options
91
92
  installer_idx = installer_options.index(a_program_name)
@@ -112,15 +113,18 @@ def get_programs_by_category(program_name: WHICH_CAT):
112
113
  ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
113
114
  ┃ 📦 Installing Category: {program_name}
114
115
  ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━""")
116
+ from machineconfig.utils.source_of_truth import LIBRARY_ROOT
117
+ from machineconfig.utils.installer import get_installers, install_all
118
+ from machineconfig.utils.installer_utils.installer_abc import parse_apps_installer_linux, parse_apps_installer_windows
119
+ from machineconfig.utils.schemas.installer.installer_types import get_normalized_arch, get_os_name
120
+ from machineconfig.utils.options import choose_from_options
115
121
  match program_name:
116
122
  case "essentials":
117
123
  installers_ = get_installers(os=get_os_name(), arch=get_normalized_arch(), which_cats=["GITHUB_ESSENTIAL", "CUSTOM_ESSENTIAL"])
118
124
  install_all(installers=installers_)
119
- program = ""
120
125
  case "essentialsDev":
121
126
  installers_ = get_installers(os=get_os_name(), arch=get_normalized_arch(), which_cats=["GITHUB_DEV", "CUSTOM_DEV", "GITHUB_ESSENTIAL", "CUSTOM_ESSENTIAL"])
122
127
  install_all(installers=installers_)
123
- program = ""
124
128
  case "systymPackages":
125
129
  if system() == "Windows":
126
130
  options_system = parse_apps_installer_windows(LIBRARY_ROOT.joinpath("setup_windows/apps.ps1").read_text(encoding="utf-8"))
@@ -141,79 +145,14 @@ def get_programs_by_category(program_name: WHICH_CAT):
141
145
  if sub_program.startswith("#winget"):
142
146
  sub_program = sub_program[1:]
143
147
  program += "\n" + sub_program
144
- # case "CHOOSE": raise NotImplementedError("CHOOSE is not implemented yet.")
145
- # case "OtherDevApps":
146
- # installers = get_installers(dev=True, system=system())
147
- # options__: list[str] = [x.get_description() for x in tqdm(installers, desc="Checking installed programs")]
148
- # program_names = choose_from_options(multi=True, msg="", options=sorted(options__) + ["all"], header="CHOOSE DEV APP")
149
- # if "all" in program_names: program_names = options__
150
- # program = ""
151
- # print("Installing:")
152
- # L(program_names).print()
153
- # for name in program_names:
154
- # try:
155
- # idx = options__.index(name)
156
- # except ValueError as ve:
157
- # print(f"{name=}")
158
- # print(f"{options__=}")
159
- # raise ve
160
- # print(f"Installing {name}")
161
- # sub_program = installers[idx].install_robust(version=None) # finish the task
162
-
148
+ case "ia":
149
+ install_interactively()
163
150
  case "precheckedPackages":
164
151
  # from machineconfig.jobs.python.check_installations import precheckedPackages
165
152
  # ci = precheckedPackages()
166
153
  # ci.download_safe_apps(name="essentials")
167
154
  # program = ""
168
155
  raise NotImplementedError("precheckedPackages is not implemented yet.")
169
- return program
170
-
171
-
172
- def parse_apps_installer_linux(txt: str) -> dict[str, Any]:
173
- txts = txt.split("""yes '' | sed 3q; echo "----------------------------- installing """)
174
- res = {}
175
- for chunk in txts[1:]:
176
- try:
177
- k = chunk.split("----")[0].rstrip().lstrip()
178
- v = "\n".join(chunk.split("\n")[1:])
179
- res[k] = v
180
- except IndexError as e:
181
- print(f"""
182
- ❌ Error parsing chunk:
183
- {"-" * 50}
184
- {chunk}
185
- {"-" * 50}""")
186
- raise e
187
- return res
188
-
189
-
190
- def parse_apps_installer_windows(txt: str) -> dict[str, Any]:
191
- chunks: list[str] = []
192
- for idx, item in enumerate(txt.split(sep="winget install")):
193
- if idx == 0:
194
- continue
195
- if idx == 1:
196
- chunks.append(item)
197
- else:
198
- chunks.append("winget install" + item)
199
- # progs = L(txt.splitlines()).filter(lambda x: x.startswith("winget ") or x.startswith("#winget"))
200
- res: dict[str, str] = {}
201
- for a_chunk in chunks:
202
- try:
203
- name = a_chunk.split("--name ")[1]
204
- if "--Id" not in name:
205
- print(f"⚠️ Warning: {name} does not have an Id, skipping")
206
- continue
207
- name = name.split(" --Id ", maxsplit=1)[0].strip('"').strip('"')
208
- res[name] = a_chunk
209
- except IndexError as e:
210
- print(f"""
211
- ❌ Error parsing chunk:
212
- {"-" * 50}
213
- {a_chunk}
214
- {"-" * 50}""")
215
- raise e
216
- return res
217
156
 
218
157
 
219
158
  if __name__ == "__main__":
@@ -39,36 +39,23 @@ def run_command(command: str, description: str) -> bool:
39
39
  except subprocess.CalledProcessError as e:
40
40
  console.print(f"❌ Error executing command: {e}", style="bold red")
41
41
  return False
42
-
43
-
44
42
  def display_header() -> None:
45
43
  """Display the script header."""
46
44
  header_text = Text("MACHINE CONFIGURATION", style="bold magenta")
47
45
  subtitle_text = Text("Interactive Installation Script", style="italic cyan")
48
- console.print(Panel(
49
- f"📦 {header_text}\n{subtitle_text}",
50
- border_style="blue",
51
- padding=(1, 2)
52
- ))
53
-
54
-
46
+ console.print(Panel(f"📦 {header_text}\n{subtitle_text}", border_style="blue", padding=(1, 2)))
55
47
  def display_completion_message() -> None:
56
48
  """Display completion message."""
57
49
  completion_text = Text("INSTALLATION COMPLETE", style="bold green")
58
50
  subtitle_text = Text("System setup finished successfully", style="italic green")
59
- console.print(Panel(
60
- f"✨ {completion_text}\n{subtitle_text}\n\n🎉 Your system has been configured successfully!\n🔄 You may need to reboot to apply all changes.",
61
- border_style="green",
62
- padding=(1, 2)
63
- ))
64
-
65
-
51
+ console.print(Panel(f"✨ {completion_text}\n{subtitle_text}\n\n🎉 Your system has been configured successfully!\n🔄 You may need to reboot to apply all changes.", border_style="green", padding=(1, 2)))
66
52
  def display_dotfiles_instructions() -> None:
67
53
  """Display instructions for dotfiles migration."""
68
54
  header_text = Text("DOTFILES MIGRATION", style="bold yellow")
69
55
  subtitle_text = Text("Configuration transfer options", style="italic yellow")
70
-
71
- instructions = """🖱️ [bold blue]Method 1: USING MOUSE WITHOUT KB OR BROWSER SHARE[/bold blue]
56
+
57
+ instructions = """
58
+ 🖱️ [bold blue]Method 1: USING MOUSE WITHOUT KB OR BROWSER SHARE[/bold blue]
72
59
  On original machine, run:
73
60
  [dim]cd ~/dotfiles/creds/msc
74
61
  easy-sharing . --password rew --username al[/dim]
@@ -84,172 +71,105 @@ def display_dotfiles_instructions() -> None:
84
71
  [dim]cd ~
85
72
  cloud_copy SHARE_URL . --config ss[/dim]
86
73
  (requires symlinks to be created first)"""
87
-
88
- console.print(Panel(
89
- f"📂 {header_text}\n{subtitle_text}\n\n{instructions}",
90
- border_style="yellow",
91
- padding=(1, 2)
92
- ))
74
+
75
+ console.print(Panel(f"📂 {header_text}\n{subtitle_text}\n\n{instructions}", border_style="yellow", padding=(1, 2)))
93
76
 
94
77
 
95
78
  def get_installation_choices() -> list[str]:
96
79
  """Get user choices for installation options."""
97
80
  choices = [
98
- Choice(value="install_apps", title="📥 Install Apps - Install base system applications", checked=False),
99
- Choice(value="upgrade_system", title="🔄 Upgrade System Packages - Update all system packages", checked=False),
100
- Choice(value="install_uv_repos", title="🐍 Install UV and Repos - Set up Python environment and repositories", checked=False),
101
- Choice(value="install_ssh_server", title="🔒 Install SSH Server - Set up remote access", checked=False),
102
- Choice(value="create_symlinks", title="🔗 Create Symlinks - Set up configuration symlinks (finish dotfiles transfer first)", checked=False),
103
- Choice(value="install_cli_apps", title="⚡ Install CLI Apps - Command-line tools installation", checked=False),
104
- Choice(value="install_dev_tools", title="🛠️ Install Development Tools - rust, libssl-dev, ffmpeg, wezterm, brave, code", checked=False),
81
+ Choice(value="install_apps", title="📥 Install Apps - Install base system applications", checked=False),
82
+ Choice(value="upgrade_system", title="🔄 Upgrade System Packages - Update all system packages", checked=False),
83
+ Choice(value="install_uv_repos", title="🐍 Install Repos - Set up Python environment and repositories permanently.", checked=False),
84
+ Choice(value="install_ssh_server", title="🔒 Install SSH Server - Set up remote access", checked=False),
85
+ Choice(value="create_symlinks", title="🔗 Create Symlinks - Set up configuration symlinks (finish dotfiles transfer first)", checked=False),
86
+ Choice(value="install_cli_apps", title="⚡ Install CLI Apps - Command-line tools installation", checked=False),
87
+ Choice(value="install_dev_tools", title="🛠️ Install Development Tools - rust, libssl-dev, ffmpeg, wezterm, brave, code", checked=False),
105
88
  Choice(value="retrieve_repositories", title="📚 Retrieve Repositories - Clone repositories to ~/code", checked=False),
106
- Choice(value="retrieve_data", title="💾 Retrieve Data - Backup restoration", checked=False),
107
- Choice(value="install_ascii_art", title="🎨 Install ASCII Art Libraries - Terminal visualization tools", checked=False),
89
+ Choice(value="retrieve_data", title="💾 Retrieve Data - Backup restoration", checked=False),
90
+ Choice(value="install_ascii_art", title="🎨 Install ASCII Art Libraries - Terminal visualization tools", checked=False),
108
91
  ]
109
-
110
- selected = questionary.checkbox(
111
- "Select the installation options you want to execute:",
112
- choices=choices,
113
- show_description=True,
114
- ).ask()
115
-
92
+ selected = questionary.checkbox("Select the installation options you want to execute:", choices=choices, show_description=True).ask()
116
93
  return selected or []
117
94
 
118
95
 
119
96
  def execute_installations(selected_options: list[str]) -> None:
120
97
  """Execute the selected installation options."""
121
98
  # Always start with VE setup
122
- console.print(Panel(
123
- "🐍 [bold green]PYTHON ENVIRONMENT[/bold green]\n[italic]Setting up base virtual environment[/italic]",
124
- border_style="green"
125
- ))
126
- run_command(
127
- "curl https://raw.githubusercontent.com/thisismygitrepo/machineconfig/main/src/machineconfig/setup_linux/ve.sh | bash",
128
- "Setting up base virtual environment"
129
- )
130
-
99
+ console.print(Panel("🐍 [bold green]PYTHON ENVIRONMENT[/bold green]\n[italic]Setting up base virtual environment[/italic]", border_style="green"))
100
+ run_command("curl https://raw.githubusercontent.com/thisismygitrepo/machineconfig/main/src/machineconfig/setup_linux/ve.sh | bash", "Setting up base virtual environment")
101
+
131
102
  if "install_apps" in selected_options:
132
- console.print(Panel(
133
- "📦 [bold blue]APPLICATIONS[/bold blue]\n[italic]Installing base system applications[/italic]",
134
- border_style="blue"
135
- ))
136
- run_command(
137
- "curl https://raw.githubusercontent.com/thisismygitrepo/machineconfig/main/src/machineconfig/setup_linux/apps.sh | bash",
138
- "Installing base system applications"
139
- )
140
-
103
+ console.print(Panel("📦 [bold blue]APPLICATIONS[/bold blue]\n[italic]Installing base system applications[/italic]", border_style="blue"))
104
+ from machineconfig import setup_linux as module
105
+ from pathlib import Path
106
+ script = Path(module.__file__).parent / "apps.sh"
107
+ run_command(f"bash {script}", "Installing base system applications")
108
+
141
109
  if "upgrade_system" in selected_options:
142
- console.print(Panel(
143
- "🔄 [bold magenta]SYSTEM UPDATE[/bold magenta]\n[italic]Package management[/italic]",
144
- border_style="magenta"
145
- ))
110
+ console.print(Panel("🔄 [bold magenta]SYSTEM UPDATE[/bold magenta]\n[italic]Package management[/italic]", border_style="magenta"))
146
111
  run_command("sudo nala upgrade -y", "Upgrading system packages")
147
-
112
+
148
113
  if "install_uv_repos" in selected_options:
149
- console.print(Panel(
150
- "🐍 [bold green]PYTHON ENVIRONMENT[/bold green]\n[italic]Virtual environment setup[/italic]",
151
- border_style="green"
152
- ))
153
- run_command(
154
- "curl https://raw.githubusercontent.com/thisismygitrepo/machineconfig/main/src/machineconfig/setup_linux/repos.sh | bash",
155
- "Setting up Python environment and repositories"
156
- )
157
-
114
+ console.print(Panel("🐍 [bold green]PYTHON ENVIRONMENT[/bold green]\n[italic]Virtual environment setup[/italic]", border_style="green"))
115
+ from machineconfig import setup_linux as module
116
+ from pathlib import Path
117
+ script = Path(module.__file__).parent / "repos.sh"
118
+ run_command(f"bash {script}", "Setting up Python environment and repositories")
119
+
158
120
  if "install_ssh_server" in selected_options:
159
- console.print(Panel(
160
- "🔒 [bold red]SSH SERVER[/bold red]\n[italic]Remote access setup[/italic]",
161
- border_style="red"
162
- ))
121
+ console.print(Panel("🔒 [bold red]SSH SERVER[/bold red]\n[italic]Remote access setup[/italic]", border_style="red"))
163
122
  run_command("sudo nala install openssh-server -y", "Installing SSH server")
164
-
165
- # Always display dotfiles instructions if symlinks are selected
123
+
166
124
  if "create_symlinks" in selected_options:
167
125
  display_dotfiles_instructions()
168
-
169
- dotfiles_ready = questionary.confirm(
170
- "📂 Have you finished copying dotfiles?",
171
- default=True
172
- ).ask()
173
-
126
+ dotfiles_ready = questionary.confirm("📂 Have you finished copying dotfiles?", default=True).ask()
174
127
  if dotfiles_ready:
175
- console.print(Panel(
176
- "🔗 [bold cyan]SYMLINK CREATION[/bold cyan]\n[italic]Configuration setup[/italic]",
177
- border_style="cyan"
178
- ))
179
- run_command(
180
- "uv run --python 3.13 --with machineconfig python -m fire machineconfig.profile.create main_symlinks --choice=all",
181
- "Creating symlinks"
182
- )
128
+ console.print(Panel("🔗 [bold cyan]SYMLINK CREATION[/bold cyan]\n[italic]Configuration setup[/italic]", border_style="cyan"))
129
+ run_command("uv run --python 3.13 --with machineconfig python -m fire machineconfig.profile.create main_symlinks --choice=all", "Creating symlinks")
183
130
  run_command("sudo chmod 600 $HOME/.ssh/*", "Setting SSH key permissions")
184
131
  run_command("sudo chmod 700 $HOME/.ssh", "Setting SSH directory permissions")
185
132
  else:
186
133
  console.print("⏭️ Skipping symlink creation - finish dotfiles transfer first", style="yellow")
187
-
134
+
188
135
  if "install_cli_apps" in selected_options:
189
- console.print(Panel(
190
- " [bold bright_yellow]CLI APPLICATIONS[/bold bright_yellow]\n[italic]Command-line tools installation[/italic]",
191
- border_style="bright_yellow"
192
- ))
193
- run_command(
194
- "uv run --python 3.13 --with machineconfig python -m fire machineconfig.scripts.python.devops_devapps_install main --which=essentials",
195
- "Installing CLI applications"
196
- )
136
+ console.print(Panel("⚡ [bold bright_yellow]CLI APPLICATIONS[/bold bright_yellow]\n[italic]Command-line tools installation[/italic]", border_style="bright_yellow"))
137
+ run_command("uv run --python 3.13 --with machineconfig python -m fire machineconfig.scripts.python.devops_devapps_install main --which=essentials", "Installing CLI applications")
197
138
  run_command(". $HOME/.bashrc", "Reloading bash configuration")
198
-
139
+
199
140
  if "install_dev_tools" in selected_options:
200
- console.print(Panel(
201
- "🛠️ [bold bright_blue]DEVELOPMENT TOOLS[/bold bright_blue]\n[italic]Software development packages[/italic]",
202
- border_style="bright_blue"
203
- ))
204
- run_command(
205
- "(curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh) || true",
206
- "Installing Rust toolchain"
207
- )
141
+ console.print(Panel("🛠️ [bold bright_blue]DEVELOPMENT TOOLS[/bold bright_blue]\n[italic]Software development packages[/italic]", border_style="bright_blue"))
142
+ run_command("(curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh) || true", "Installing Rust toolchain")
208
143
  run_command("sudo nala install libssl-dev -y", "Installing libssl-dev")
209
144
  run_command("sudo nala install ffmpeg -y", "Installing ffmpeg")
210
- run_command(
211
- "uv run --python 3.13 --with machineconfig python -m fire machineconfig.scripts.python.devops_devapps_install main --which=wezterm,brave,code",
212
- "Installing development applications"
213
- )
214
-
145
+ run_command("uv run --python 3.13 --with machineconfig python -m fire machineconfig.scripts.python.devops_devapps_install main --which=wezterm,brave,code", "Installing development applications")
146
+
215
147
  if "retrieve_repositories" in selected_options:
216
- console.print(Panel(
217
- "📚 [bold bright_magenta]REPOSITORIES[/bold bright_magenta]\n[italic]Project code retrieval[/italic]",
218
- border_style="bright_magenta"
219
- ))
148
+ console.print(Panel("📚 [bold bright_magenta]REPOSITORIES[/bold bright_magenta]\n[italic]Project code retrieval[/italic]", border_style="bright_magenta"))
220
149
  run_command("repos ~/code --clone --cloud odg1", "Cloning repositories")
221
-
150
+
222
151
  if "retrieve_data" in selected_options:
223
- console.print(Panel(
224
- "💾 [bold bright_cyan]DATA RETRIEVAL[/bold bright_cyan]\n[italic]Backup restoration[/italic]",
225
- border_style="bright_cyan"
226
- ))
227
- run_command(
228
- "uv run --python 3.13 --with machineconfig python -m fire machineconfig.scripts.python.devops_backup_retrieve main --direction=RETRIEVE",
229
- "Retrieving backup data"
230
- )
231
-
152
+ console.print(Panel("💾 [bold bright_cyan]DATA RETRIEVAL[/bold bright_cyan]\n[italic]Backup restoration[/italic]", border_style="bright_cyan"))
153
+ run_command("uv run --python 3.13 --with machineconfig python -m fire machineconfig.scripts.python.devops_backup_retrieve main --direction=RETRIEVE", "Retrieving backup data")
154
+
232
155
  if "install_ascii_art" in selected_options:
233
- console.print(Panel(
234
- "🎨 [bold bright_green]ASCII ART[/bold bright_green]\n[italic]Terminal visualization tools[/italic]",
235
- border_style="bright_green"
236
- ))
156
+ console.print(Panel("🎨 [bold bright_green]ASCII ART[/bold bright_green]\n[italic]Terminal visualization tools[/italic]", border_style="bright_green"))
237
157
  run_command("curl bit.ly/cfgasciiartlinux -L | sudo bash", "Installing ASCII art libraries")
238
158
 
239
159
 
240
160
  def main() -> None:
241
161
  """Main function to run the interactive installation."""
242
162
  display_header()
243
- selected_options = get_installation_choices()
163
+ selected_options = get_installation_choices()
244
164
  if not selected_options:
245
165
  console.print("❌ No options selected. Exiting...", style="bold red")
246
166
  sys.exit(0)
247
167
  console.print(f"\n✅ Selected options: {', '.join(selected_options)}", style="bold green")
248
- proceed = questionary.confirm("🚀 Proceed with installation?", default=True).ask()
168
+ proceed = questionary.confirm("🚀 Proceed with installation?", default=True).ask()
249
169
  if not proceed:
250
170
  console.print("❌ Installation cancelled.", style="bold red")
251
171
  sys.exit(0)
252
- execute_installations(selected_options)
172
+ execute_installations(selected_options)
253
173
  display_completion_message()
254
174
 
255
175
 
@@ -1,7 +1,7 @@
1
1
 
2
2
 
3
3
  from pathlib import Path
4
- from typing import Optional
4
+ from typing import Optional, Annotated
5
5
  import typer
6
6
  from rich.console import Console
7
7
  from rich.panel import Panel
@@ -43,12 +43,33 @@ def display_terminal_url(local_ip_v4: str, port: int) -> None:
43
43
  )
44
44
 
45
45
  # Print with extra spacing and attention-grabbing elements
46
- console.print("\n" + "🔥" * 60 + "\n", style="bright_red bold")
46
+ # console.print("\n" + "🔥" * 60 + "\n", style="bright_red bold")
47
47
  console.print(panel)
48
- console.print("🔥" * 60 + "\n", style="bright_red bold")
49
-
50
-
51
- def main(port: Optional[int]=None, password: Optional[str]=None) -> None:
48
+ # console.print("🔥" * 60 + "\n", style="bright_red bold")
49
+
50
+
51
+ def install_ttyd():
52
+ # uv run --python 3.13 --with machineconfig devops install ttyd
53
+ from machineconfig.utils.installer_utils.installer_abc import check_tool_exists
54
+ exists = check_tool_exists("ttyd")
55
+ if exists:
56
+ print("✅ ttyd is already installed.")
57
+ return
58
+ print("⏳ ttyd not found. Installing...")
59
+ from machineconfig.scripts.python.devops_devapps_install import main
60
+ main(which="ttyd")
61
+
62
+
63
+
64
+ def main(
65
+ port: Annotated[Optional[int], typer.Option("--port", "-p", help="Port to run the terminal server on (default: 7681)")] = None,
66
+ username: Annotated[Optional[str], typer.Option("--username", "-u", help="Username for terminal access (default: current user)")] = None,
67
+ password: Annotated[Optional[str], typer.Option("--password", "-w", help="Password for terminal access (default: from ~/dotfiles/creds/passwords/quick_password)")] = None
68
+ ) -> None:
69
+ install_ttyd()
70
+ if username is None:
71
+ import getpass
72
+ username = getpass.getuser()
52
73
  if password is None:
53
74
  pwd_path = Path.home().joinpath("dotfiles/creds/passwords/quick_password")
54
75
  if pwd_path.exists():
@@ -67,11 +88,9 @@ def main(port: Optional[int]=None, password: Optional[str]=None) -> None:
67
88
 
68
89
  # Display the flashy terminal announcement
69
90
  display_terminal_url(local_ip_v4, port)
70
-
71
- code = f"""
72
- #!/bin/bash
73
- uv run --python 3.13 --with machineconfig install -ttyd
74
- ttyd --writable -t enableSixel=true --port {port} --credential "$USER:{password}" -t 'theme={"background": "black"}' bash
91
+
92
+ code = f"""#!/bin/bash
93
+ ttyd --writable -t enableSixel=true --port {port} --credential "{username}:{password}" -t 'theme={{"background": "black"}}' bash
75
94
  """
76
95
  import subprocess
77
96
  subprocess.run(code, shell=True, check=True)
File without changes
@@ -2,57 +2,8 @@
2
2
 
3
3
  echo """
4
4
  =======================================================================
5
- 📦 MACHINE CONFIGURATION | Interactive Installation Script
5
+ 📦 MACHINE CONFIGURATION | Interactive Installation Script. Installing uv then getting started.
6
6
  ======================================================================="""
7
7
 
8
8
  curl https://raw.githubusercontent.com/thisismygitrepo/machineconfig/main/src/machineconfig/setup_linux/ve.sh | bash
9
- $HOME/.local/bin/uv run --python 3.13 --with machineconfig ia
10
-
11
-
12
-
13
-
14
- echo """#=======================================================================
15
- 📂 DOTFILES MIGRATION | Configuration transfer options
16
- #=======================================================================
17
-
18
- 🖱️ Method 1: USING MOUSE WITHOUT KB OR BROWSER SHARE
19
- On original machine, run:
20
- cd ~/dotfiles/creds/msc
21
- easy-sharing . --password rew --username al
22
- Then open brave on new machine to get MouseWithoutBorders password
23
-
24
- 🔐 Method 2: USING SSH
25
- FROM REMOTE, RUN:
26
- fptx ~/dotfiles $USER@$(hostname):^ -z
27
- # OR, using IP address if router has not yet found the hostname:
28
- fptx ~/dotfiles $USER@$(hostname -I | awk '{print $1}'):^ -z
29
-
30
- ☁️ Method 3: USING INTERNET SECURE SHARE
31
- cd ~
32
- cloud_copy SHARE_URL . --config ss
33
- (requires symlinks to be created first)
34
- """
35
-
36
- echo """#=======================================================================
37
- 📂 DOTFILES STATUS | Configuration files check
38
- #=======================================================================
39
- """
40
- read -p "📂 Have you finished copying dotfiles? [y]/n? " choice
41
-
42
- echo """#=======================================================================
43
- 🔗 SYMLINK CREATION | Configuration setup
44
- #=======================================================================
45
- """
46
- read -p "🔗 Create Symlinks (finish dotfiles transfer first) [y]/n? " choice
47
- choice=${choice:-y}
48
- if [[ "$choice" == "y" || "$choice" == "Y" ]]; then
49
- echo """ 🔧 Creating symlinks and setting permissions...
50
- """
51
- uv run --python 3.13 --with machineconfig python -m fire machineconfig.profile.create main_symlinks --choice=all
52
- sudo chmod 600 $HOME/.ssh/*
53
- sudo chmod 700 $HOME/.ssh
54
- else
55
- echo """ ⏭️ Skipping symlink creation
56
- """
57
- fi
58
-
9
+ $HOME/.local/bin/uv run --python 3.13 --with machineconfig devops ia
@@ -1,13 +1,13 @@
1
1
  """package manager"""
2
2
 
3
- from machineconfig.utils.installer_utils.installer_abc import LINUX_INSTALL_PATH
3
+ from machineconfig.utils.installer_utils.installer_abc import check_if_installed_already
4
4
  from machineconfig.utils.installer_utils.installer_class import Installer
5
5
  from machineconfig.utils.schemas.installer.installer_types import APP_INSTALLER_CATEGORY, InstallerData, InstallerDataFiles, get_normalized_arch, get_os_name, OPERATING_SYSTEMS, CPU_ARCHITECTURES
6
6
  from rich.console import Console
7
- from rich.panel import Panel # Added import
7
+ from rich.panel import Panel
8
8
 
9
9
  from machineconfig.utils.path_extended import PathExtended as PathExtended
10
- from machineconfig.utils.source_of_truth import INSTALL_VERSION_ROOT
10
+ from machineconfig.utils.source_of_truth import INSTALL_VERSION_ROOT, LINUX_INSTALL_PATH
11
11
  from machineconfig.utils.io import read_json
12
12
 
13
13
  from typing import Any
@@ -38,7 +38,7 @@ def check_latest():
38
38
  repo_url = inst.installer_data.get("repoURL", "")
39
39
  print(f"🔎 Checking {exe_name}...")
40
40
  _release_url, version_to_be_installed = inst.get_github_release(repo_url=repo_url, version=None)
41
- verdict, current_ver, new_ver = inst.check_if_installed_already(exe_name=exe_name, version=version_to_be_installed, use_cache=False)
41
+ verdict, current_ver, new_ver = check_if_installed_already(exe_name=exe_name, version=version_to_be_installed, use_cache=False)
42
42
  return exe_name, verdict, current_ver, new_ver
43
43
 
44
44
  print("\n⏳ Processing installers...\n")
@@ -188,5 +188,4 @@ def install_all(installers: list[Installer], safe: bool = False, jobs: int = 10,
188
188
  print("\n" * 2)
189
189
 
190
190
 
191
- if __name__ == "__main__":
192
- pass
191
+
@@ -1,7 +1,11 @@
1
+
1
2
  from machineconfig.utils.path_extended import PathExtended as PathExtended
2
- from machineconfig.utils.source_of_truth import WINDOWS_INSTALL_PATH, LINUX_INSTALL_PATH
3
- from typing import Optional
3
+ from machineconfig.utils.source_of_truth import WINDOWS_INSTALL_PATH, LINUX_INSTALL_PATH, INSTALL_VERSION_ROOT
4
+
5
+ from pathlib import Path
6
+ from typing import Any, Optional
4
7
  import subprocess
8
+ import platform
5
9
 
6
10
 
7
11
  def find_move_delete_windows(downloaded_file_path: PathExtended, exe_name: Optional[str] = None, delete: bool = True, rename_to: Optional[str] = None):
@@ -106,3 +110,104 @@ def find_move_delete_linux(downloaded: PathExtended, tool_name: str, delete: Opt
106
110
  exe_new_location = PathExtended(LINUX_INSTALL_PATH).joinpath(exe.name)
107
111
  print(f"✅ Executable installed at: {exe_new_location}\n{'=' * 80}")
108
112
  return exe_new_location
113
+
114
+
115
+ def check_tool_exists(tool_name: str) -> bool:
116
+ if platform.system() == "Windows":
117
+ tool_name = tool_name.replace(".exe", "") + ".exe"
118
+ res1 = any([Path(WINDOWS_INSTALL_PATH).joinpath(tool_name).is_file(), Path.home().joinpath("AppData/Roaming/npm").joinpath(tool_name).is_file()])
119
+ tool_name = tool_name.replace(".exe", "") + ".exe"
120
+ res2 = any([Path(WINDOWS_INSTALL_PATH).joinpath(tool_name).is_file(), Path.home().joinpath("AppData/Roaming/npm").joinpath(tool_name).is_file()])
121
+ return res1 or res2
122
+ elif platform.system() in ["Linux", "Darwin"]:
123
+ root_path = Path(LINUX_INSTALL_PATH)
124
+ return any([Path("/usr/local/bin").joinpath(tool_name).is_file(), Path("/usr/bin").joinpath(tool_name).is_file(), root_path.joinpath(tool_name).is_file()])
125
+ else:
126
+ raise NotImplementedError(f"platform {platform.system()} not implemented")
127
+
128
+
129
+ def check_if_installed_already(exe_name: str, version: Optional[str], use_cache: bool) -> tuple[str, str, str]:
130
+ print(f"\n{'=' * 80}\n🔍 CHECKING INSTALLATION STATUS: {exe_name} 🔍\n{'=' * 80}")
131
+ INSTALL_VERSION_ROOT.joinpath(exe_name).parent.mkdir(parents=True, exist_ok=True)
132
+ tmp_path = INSTALL_VERSION_ROOT.joinpath(exe_name)
133
+
134
+ if use_cache:
135
+ print("🗂️ Using cached version information...")
136
+ if tmp_path.exists():
137
+ existing_version = tmp_path.read_text(encoding="utf-8").rstrip()
138
+ print(f"📄 Found cached version: {existing_version}")
139
+ else:
140
+ existing_version = None
141
+ print("ℹ️ No cached version information found")
142
+ else:
143
+ print("🔍 Checking installed version directly...")
144
+ result = subprocess.run([exe_name, "--version"], check=False, capture_output=True, text=True)
145
+ if result.stdout.strip() == "":
146
+ existing_version = None
147
+ print("ℹ️ Could not detect installed version")
148
+ else:
149
+ existing_version = result.stdout.strip()
150
+ print(f"📄 Detected installed version: {existing_version}")
151
+
152
+ if existing_version is not None and version is not None:
153
+ if existing_version == version:
154
+ print(f"✅ {exe_name} is up to date (version {version})")
155
+ print(f"📂 Version information stored at: {INSTALL_VERSION_ROOT}")
156
+ return ("✅ Up to date", version.strip(), version.strip())
157
+ else:
158
+ print(f"🔄 {exe_name} needs update: {existing_version.rstrip()} → {version}")
159
+ tmp_path.write_text(version, encoding="utf-8")
160
+ return ("❌ Outdated", existing_version.strip(), version.strip())
161
+ else:
162
+ print(f"📦 {exe_name} is not installed. Will install version: {version}")
163
+ # tmp_path.write_text(version, encoding="utf-8")
164
+
165
+ print(f"{'=' * 80}")
166
+ return ("⚠️ NotInstalled", "None", version or "unknown")
167
+
168
+
169
+ def parse_apps_installer_linux(txt: str) -> dict[str, Any]:
170
+ txts = txt.split("""yes '' | sed 3q; echo "----------------------------- installing """)
171
+ res = {}
172
+ for chunk in txts[1:]:
173
+ try:
174
+ k = chunk.split("----")[0].rstrip().lstrip()
175
+ v = "\n".join(chunk.split("\n")[1:])
176
+ res[k] = v
177
+ except IndexError as e:
178
+ print(f"""
179
+ ❌ Error parsing chunk:
180
+ {"-" * 50}
181
+ {chunk}
182
+ {"-" * 50}""")
183
+ raise e
184
+ return res
185
+
186
+
187
+ def parse_apps_installer_windows(txt: str) -> dict[str, Any]:
188
+ chunks: list[str] = []
189
+ for idx, item in enumerate(txt.split(sep="winget install")):
190
+ if idx == 0:
191
+ continue
192
+ if idx == 1:
193
+ chunks.append(item)
194
+ else:
195
+ chunks.append("winget install" + item)
196
+ # progs = L(txt.splitlines()).filter(lambda x: x.startswith("winget ") or x.startswith("#winget"))
197
+ res: dict[str, str] = {}
198
+ for a_chunk in chunks:
199
+ try:
200
+ name = a_chunk.split("--name ")[1]
201
+ if "--Id" not in name:
202
+ print(f"⚠️ Warning: {name} does not have an Id, skipping")
203
+ continue
204
+ name = name.split(" --Id ", maxsplit=1)[0].strip('"').strip('"')
205
+ res[name] = a_chunk
206
+ except IndexError as e:
207
+ print(f"""
208
+ ❌ Error parsing chunk:
209
+ {"-" * 50}
210
+ {a_chunk}
211
+ {"-" * 50}""")
212
+ raise e
213
+ return res
@@ -1,7 +1,7 @@
1
1
  from machineconfig.utils.path_extended import PathExtended as PathExtended
2
2
  from machineconfig.utils.installer_utils.installer_abc import find_move_delete_linux, find_move_delete_windows
3
3
  from machineconfig.utils.source_of_truth import INSTALL_TMP_DIR, INSTALL_VERSION_ROOT, LIBRARY_ROOT
4
- from machineconfig.utils.options import check_tool_exists
4
+ from machineconfig.utils.installer_utils.installer_abc import check_tool_exists
5
5
  from machineconfig.utils.io import read_json
6
6
  from machineconfig.utils.schemas.installer.installer_types import InstallerData, InstallerDataFiles, get_os_name, get_normalized_arch
7
7
 
@@ -356,43 +356,3 @@ class Installer:
356
356
  return None, None
357
357
  browser_download_url = f"{repo_url}/releases/download/{actual_version}/{filename}"
358
358
  return browser_download_url, actual_version
359
-
360
- @staticmethod
361
- def check_if_installed_already(exe_name: str, version: Optional[str], use_cache: bool) -> tuple[str, str, str]:
362
- print(f"\n{'=' * 80}\n🔍 CHECKING INSTALLATION STATUS: {exe_name} 🔍\n{'=' * 80}")
363
- INSTALL_VERSION_ROOT.joinpath(exe_name).parent.mkdir(parents=True, exist_ok=True)
364
- tmp_path = INSTALL_VERSION_ROOT.joinpath(exe_name)
365
-
366
- if use_cache:
367
- print("🗂️ Using cached version information...")
368
- if tmp_path.exists():
369
- existing_version = tmp_path.read_text(encoding="utf-8").rstrip()
370
- print(f"📄 Found cached version: {existing_version}")
371
- else:
372
- existing_version = None
373
- print("ℹ️ No cached version information found")
374
- else:
375
- print("🔍 Checking installed version directly...")
376
- result = subprocess.run([exe_name, "--version"], check=False, capture_output=True, text=True)
377
- if result.stdout.strip() == "":
378
- existing_version = None
379
- print("ℹ️ Could not detect installed version")
380
- else:
381
- existing_version = result.stdout.strip()
382
- print(f"📄 Detected installed version: {existing_version}")
383
-
384
- if existing_version is not None and version is not None:
385
- if existing_version == version:
386
- print(f"✅ {exe_name} is up to date (version {version})")
387
- print(f"📂 Version information stored at: {INSTALL_VERSION_ROOT}")
388
- return ("✅ Up to date", version.strip(), version.strip())
389
- else:
390
- print(f"🔄 {exe_name} needs update: {existing_version.rstrip()} → {version}")
391
- tmp_path.write_text(version, encoding="utf-8")
392
- return ("❌ Outdated", existing_version.strip(), version.strip())
393
- else:
394
- print(f"📦 {exe_name} is not installed. Will install version: {version}")
395
- # tmp_path.write_text(version, encoding="utf-8")
396
-
397
- print(f"{'=' * 80}")
398
- return ("⚠️ NotInstalled", "None", version or "unknown")
@@ -1,25 +1,12 @@
1
1
  from pathlib import Path
2
+ from machineconfig.utils.installer_utils.installer_abc import check_tool_exists
2
3
  from rich.text import Text
3
4
  from rich.panel import Panel
4
5
  from rich.console import Console
5
- import platform
6
6
  import subprocess
7
7
  from typing import Optional, Union, Iterable, overload, Literal
8
- from machineconfig.utils.source_of_truth import WINDOWS_INSTALL_PATH, LINUX_INSTALL_PATH
9
-
10
-
11
- def check_tool_exists(tool_name: str) -> bool:
12
- if platform.system() == "Windows":
13
- tool_name = tool_name.replace(".exe", "") + ".exe"
14
- res1 = any([Path(WINDOWS_INSTALL_PATH).joinpath(tool_name).is_file(), Path.home().joinpath("AppData/Roaming/npm").joinpath(tool_name).is_file()])
15
- tool_name = tool_name.replace(".exe", "") + ".exe"
16
- res2 = any([Path(WINDOWS_INSTALL_PATH).joinpath(tool_name).is_file(), Path.home().joinpath("AppData/Roaming/npm").joinpath(tool_name).is_file()])
17
- return res1 or res2
18
- elif platform.system() in ["Linux", "Darwin"]:
19
- root_path = Path(LINUX_INSTALL_PATH)
20
- return any([Path("/usr/local/bin").joinpath(tool_name).is_file(), Path("/usr/bin").joinpath(tool_name).is_file(), root_path.joinpath(tool_name).is_file()])
21
- else:
22
- raise NotImplementedError(f"platform {platform.system()} not implemented")
8
+
9
+
23
10
  # _ = cmd
24
11
  # cmd = "where.exe"
25
12
  # cmd = "which"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: machineconfig
3
- Version: 3.97
3
+ Version: 3.98
4
4
  Summary: Dotfiles management package
5
5
  Author-email: Alex Al-Saffar <programmer@usa.com>
6
6
  License: Apache 2.0
@@ -144,11 +144,11 @@ machineconfig/scripts/python/cloud_mount.py,sha256=RFMzRUep2D5HtVXANIi-pab3EkI-W
144
144
  machineconfig/scripts/python/cloud_repo_sync.py,sha256=GBhdUu9BJwhLYmhxxtvqJGLy7xKdQcnH9kkL4jcbzEE,9502
145
145
  machineconfig/scripts/python/cloud_sync.py,sha256=RWGpAfJ9fnN18yNBSgN44dzA38Hmd4879JL5r2pcyrM,3514
146
146
  machineconfig/scripts/python/croshell.py,sha256=shv0FmFfD2Br0EVE-zvpt4i5Tl8kliLlIvxkx0umGiA,8954
147
- machineconfig/scripts/python/devops.py,sha256=NuCnXAyJ3VDx-wUO7CLvSDbqFiyMqxCb3_XINAcLe0I,6862
147
+ machineconfig/scripts/python/devops.py,sha256=qjBXv6x-7mfJRPyLfGNzcadGBpoHoxWaZFTJCqx0DS4,4554
148
148
  machineconfig/scripts/python/devops_add_identity.py,sha256=JfN3ZrYMCgmt4ks_VCfnV9BIIHAsOYO3E0W0wZ15FR8,3791
149
149
  machineconfig/scripts/python/devops_add_ssh_key.py,sha256=KaoX83KltBsmutfKhSfZjd7nP_R1hJ2OLAWRhbswO7o,6889
150
150
  machineconfig/scripts/python/devops_backup_retrieve.py,sha256=jZe5Vki7E2GCMG8hvqUZeOONFC4cNzISoGzq_dMG4GA,5601
151
- machineconfig/scripts/python/devops_devapps_install.py,sha256=utqZdXD_2i9ZpOhgwgQAPTAhbXiop8xZCOk5eifWnuw,10850
151
+ machineconfig/scripts/python/devops_devapps_install.py,sha256=Oe8u6_EurEltEtJagcuapz-G3DyZdRyWqQ8kSEp-zHQ,8911
152
152
  machineconfig/scripts/python/devops_update_repos.py,sha256=c5qBc9cuTGDEqDHufkjDT4d_vvJsswv3tlqk9MAulYk,8063
153
153
  machineconfig/scripts/python/dotfile.py,sha256=SRcX-9Ak1jRvF-killBTTm2IWcsNxfiLucH6ZsytAFA,2202
154
154
  machineconfig/scripts/python/fire_agents.py,sha256=IpglbN30zJ1jIBzHNCR2LmPULoIdFaj2M0JBsEfZEZg,9216
@@ -162,7 +162,7 @@ machineconfig/scripts/python/fire_jobs_streamlit_helper.py,sha256=47DEQpj8HBSa-_
162
162
  machineconfig/scripts/python/ftpx.py,sha256=l_gdJS0QB2wVZErubtZvm4HJD9HZAJxSP68sbY73xwo,10278
163
163
  machineconfig/scripts/python/get_zellij_cmd.py,sha256=e35-18hoXM9N3PFbvbizfkNY_-63iMicieWE3TbGcCQ,576
164
164
  machineconfig/scripts/python/gh_models.py,sha256=3BLfW25mBRiPO5VKtVm-nMlKLv-PaZDw7mObajq6F6M,5538
165
- machineconfig/scripts/python/interactive.py,sha256=wSGhhsVFFLd8ElaPqaLJzKgUoYolkvAVFk9I8oTptlk,11079
165
+ machineconfig/scripts/python/interactive.py,sha256=qGcvn8XXCkck1xidcEFqPGBawgiEJXctwQqd_-dhRIQ,10162
166
166
  machineconfig/scripts/python/mount_nfs.py,sha256=c8pWXimDWdgCkSskcnPgT-8ESPosil6Cvy2hGSaIBJE,3359
167
167
  machineconfig/scripts/python/mount_nw_drive.py,sha256=iru6AtnTyvyuk6WxlK5R4lDkuliVpPV5_uBTVVhXtjQ,1550
168
168
  machineconfig/scripts/python/mount_ssh.py,sha256=rGY2pgtlnWMi0Rrge1aCdjtfbULrj2cyaStDoX-y2w4,2236
@@ -174,7 +174,7 @@ machineconfig/scripts/python/repos_helper_clone.py,sha256=xW5YZEoNt3k7h9NIULhUhO
174
174
  machineconfig/scripts/python/repos_helper_record.py,sha256=YEEQORfEiLddOIIgePo5eEkyQUFruFg3kc8npMvRL-o,10927
175
175
  machineconfig/scripts/python/repos_helper_update.py,sha256=AYyKIB7eQ48yoYmFjydIhRI1lV39TBv_S4_LCa-oKuQ,11042
176
176
  machineconfig/scripts/python/scheduler.py,sha256=rKhssuxkD697EY6qaV6CSdNhxpAQLDWO4fE8GMCQ9FA,3061
177
- machineconfig/scripts/python/share_terminal.py,sha256=QkzxEqvGZG29heiFByB4JrT21UvG8qyYhwG2JIgR_hw,2551
177
+ machineconfig/scripts/python/share_terminal.py,sha256=3d0tOjAiXbonuJprHitoUmyU4zVLnexQGdTNs1-5qq0,3455
178
178
  machineconfig/scripts/python/snapshot.py,sha256=aDvKeoniZaeTSNv9zWBUajaj2yagAxVdfuvO1_tgq5Y,1026
179
179
  machineconfig/scripts/python/start_slidev.py,sha256=U5ujAL7R5Gd5CzFReTsnF2SThjY91aFBg0Qz_MMl6U4,4573
180
180
  machineconfig/scripts/python/start_terminals.py,sha256=DRWbMZumhPmL0DvvsCsbRNFL5AVQn1SgaziafTio3YQ,6149
@@ -353,13 +353,14 @@ machineconfig/settings/zellij/layouts/panes.kdl,sha256=KlhKtelBy4Z2ENV_pix4xE7NH
353
353
  machineconfig/settings/zellij/layouts/st.kdl,sha256=QXLRK7Wx05aKbKRHVmm4RspLYzPmEa44JMK1TwXQk58,523
354
354
  machineconfig/settings/zellij/layouts/st2.kdl,sha256=1FKTH3qQWYMWp_wPMreP7fKOTlVd4cfBy3J8fv4zCBc,1489
355
355
  machineconfig/settings/zellij/layouts/stacked_panes.kdl,sha256=usY8kKKwX1KUMXnWDivPg0i0drpM1Biw-tOnNZVjiZU,163
356
+ machineconfig/setup_linux/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
356
357
  machineconfig/setup_linux/nix/cli_installation.sh,sha256=AQ_wRmldeD1tPqCmU7qgz9ZrZFly4OYwBJDGRpb9IJ0,5470
357
358
  machineconfig/setup_linux/others/mint_keyboard_shortcuts.sh,sha256=F5dbg0n9RHsKGPn8fIdZMn3p0RrHEkb8rWBGsdVGbus,1207
358
359
  machineconfig/setup_linux/others/openssh-server_add_pub_key.sh,sha256=UiJcD1o4UekKKtp5YJKRq135PpqdTLXy7M6HvQ-Qum4,1993
359
360
  machineconfig/setup_linux/web_shortcuts/android.sh,sha256=gzep6bBhK7FCBvGcXK0fdJCtkSfBOftt0aFyDZq_eMs,68
360
361
  machineconfig/setup_linux/web_shortcuts/ascii_art.sh,sha256=RWcxH_Db7WHH37PclYmc92o6zAS557wGZxcYTuyTUZ0,3550
361
362
  machineconfig/setup_linux/web_shortcuts/croshell.sh,sha256=X9-B1cVptbaFWaWTA-2ELNQx_2ktxu7ZVe48RvpCmkU,316
362
- machineconfig/setup_linux/web_shortcuts/interactive.sh,sha256=DOv0iYsDgavKrBkzTZm6hcuwfYok_isg6KDNr5h3fjk,2178
363
+ machineconfig/setup_linux/web_shortcuts/interactive.sh,sha256=o_rw_1lVKU7dazJ4ST58ZbaDwZ6FGLRyTD-yI2dBShk,454
363
364
  machineconfig/setup_linux/web_shortcuts/ssh.sh,sha256=k6BAY-zAWsi1beOMiZODxw4VOjZCTABZu__gxSET1eU,1924
364
365
  machineconfig/setup_windows/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
365
366
  machineconfig/setup_windows/others/docker.ps1,sha256=M8NfsSxH8YlmY92J4rSe1xWOwTW8IFrdgb8cI8Riu2E,311
@@ -374,11 +375,11 @@ machineconfig/setup_windows/wt_and_pwsh/set_wt_settings.py,sha256=rZZJamy3YxAeJh
374
375
  machineconfig/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
375
376
  machineconfig/utils/accessories.py,sha256=W_9dLzjwNTW5JQk_pe3B2ijQ1nA2-8Kdg2r7VBtzgQs,4340
376
377
  machineconfig/utils/code.py,sha256=pKPHInKgXJWeACVbxuE7sMdYeZCbNttaYCsfonGhFfc,4464
377
- machineconfig/utils/installer.py,sha256=N8Vg5P7SEwIZdjSNbwrocIOv1l2_D3pdNIG3zdzJ2iQ,8982
378
+ machineconfig/utils/installer.py,sha256=Cfu0arQ-QE2TfDThP5Bb5HHpDA7kHlsWpAqGFrTA8c0,8954
378
379
  machineconfig/utils/io.py,sha256=ZXB3aataS1IZ_0WMcCRSmoN1nbkvEO-bWYcs-TpngqU,2872
379
380
  machineconfig/utils/links.py,sha256=riNUrG8aGElRszdOPOic4M2AyOcpdcth_-y8JEiZpJ4,10253
380
381
  machineconfig/utils/notifications.py,sha256=vvdsY5IX6XEiILTnt5lNyHxhCi0ljdGX2T_67VRfrG4,9009
381
- machineconfig/utils/options.py,sha256=aEFeVbHfbX0d3VjjZcUAQA0jSOsKhKhr7P0kGHYhPd0,9284
382
+ machineconfig/utils/options.py,sha256=8pG-apcc28xxJ5BQiACsGNTKwWtkQyH3hCtzBEhokK8,8366
382
383
  machineconfig/utils/path_extended.py,sha256=nTETtTxzNaxdrapIH3WzkR__b-1k6Lx7SpRAXqmIJN4,51793
383
384
  machineconfig/utils/path_helper.py,sha256=jqOf3TAlw5cqSp4HBAlOqjAR_bzC8_fvjA-_-CooI6Y,8030
384
385
  machineconfig/utils/procs.py,sha256=KjEbrwfbdoi5IBM518scxMDVi7NxTZLHuYiKmwdGlzg,11393
@@ -395,14 +396,14 @@ machineconfig/utils/cloud/onedrive/setup_oauth.py,sha256=ZTVkqgrwbV_EoPvyT8dyOTU
395
396
  machineconfig/utils/cloud/onedrive/transaction.py,sha256=m-aNcnWj_gfZVvJOSpkdIqjZxU_3nXx2CA-qKbQgP3I,26232
396
397
  machineconfig/utils/installer_utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
397
398
  machineconfig/utils/installer_utils/github_release_bulk.py,sha256=vK5WJ-a566egAIEHdKsn3iOAh5LBqeY4zPDHPgqHVcE,6887
398
- machineconfig/utils/installer_utils/installer_abc.py,sha256=iB1_PZLQGouCdEA8bixdB4kZAQ2OnPqZeRcwaf4LzuI,5178
399
- machineconfig/utils/installer_utils/installer_class.py,sha256=Pvaz8n8BEBZMVzXyNprVN9djVkx8Qp-0WwR61BQ1eRc,22388
399
+ machineconfig/utils/installer_utils/installer_abc.py,sha256=6lN_luAmyiPnncD9o-TjRQBYZHCwdrLU8V9eFp9eZBc,9549
400
+ machineconfig/utils/installer_utils/installer_class.py,sha256=6IQswaC9mxIdeaMG-rOt-vqyKGYibBRMvC0UglZ_3mI,20268
400
401
  machineconfig/utils/schemas/fire_agents/fire_agents_input.py,sha256=CCs5ebomW1acKWZRpv9dyDzM-W6pwvVplikcutE2D8I,2339
401
402
  machineconfig/utils/schemas/installer/installer_types.py,sha256=DLagmIe0G5-xg7HZ9VrlFCDk1gIbwvX7O4gZjwq0wh0,1326
402
403
  machineconfig/utils/schemas/layouts/layout_types.py,sha256=M1ZFCz_kjRZPhxM19rIYUDR5lDDpwa09odR_ihtIFq0,1932
403
404
  machineconfig/utils/schemas/repos/repos_types.py,sha256=ECVr-3IVIo8yjmYmVXX2mnDDN1SLSwvQIhx4KDDQHBQ,405
404
- machineconfig-3.97.dist-info/METADATA,sha256=41d56Jx9vgeCV42fom4BZPQrRIj-yV3CRoMJondht1c,7032
405
- machineconfig-3.97.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
406
- machineconfig-3.97.dist-info/entry_points.txt,sha256=94GY2PC5gimDHncsCsa2RM-xDRVbWsp8a01p4YGDb2M,1282
407
- machineconfig-3.97.dist-info/top_level.txt,sha256=porRtB8qms8fOIUJgK-tO83_FeH6Bpe12oUVC670teA,14
408
- machineconfig-3.97.dist-info/RECORD,,
405
+ machineconfig-3.98.dist-info/METADATA,sha256=Lp-8scw6tGrHgQ7ENdFL1_uwZYhb2pT3V6P87zYmWtc,7032
406
+ machineconfig-3.98.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
407
+ machineconfig-3.98.dist-info/entry_points.txt,sha256=c6ea0waVseT1rbfz1bw3k-eph2yVaB67x9hx64Mpvfs,1066
408
+ machineconfig-3.98.dist-info/top_level.txt,sha256=porRtB8qms8fOIUJgK-tO83_FeH6Bpe12oUVC670teA,14
409
+ machineconfig-3.98.dist-info/RECORD,,
@@ -5,17 +5,14 @@ cloud_mount = machineconfig.scripts.python.cloud_mount:arg_parser
5
5
  cloud_repo_sync = machineconfig.scripts.python.cloud_repo_sync:args_parser
6
6
  cloud_sync = machineconfig.scripts.python.cloud_sync:arg_parser
7
7
  croshell = machineconfig.scripts.python.croshell:arg_parser
8
- devops = machineconfig.scripts.python.devops:args_parser
8
+ devops = machineconfig.scripts.python.devops:app
9
9
  fire = machineconfig.scripts.python.fire_jobs:main_from_parser
10
10
  fire_agents = machineconfig.scripts.python.fire_agents:main
11
11
  ftpx = machineconfig.scripts.python.ftpx:main_from_parser
12
- ia = machineconfig.scripts.python.interactive:main
13
12
  initai = machineconfig.scripts.python.ai.initai:main
14
- install = machineconfig.scripts.python.devops_devapps_install:main_with_parser
15
13
  kill_process = machineconfig.utils.procs:main
16
14
  mount_nfs = machineconfig.scripts.python.mount_nfs:main
17
15
  mount_nw_drive = machineconfig.scripts.python.mount_nw_drive:main
18
16
  repos = machineconfig.scripts.python.repos:main_from_parser
19
- share_terminal = machineconfig.scripts.python.share_terminal:main_with_parser
20
17
  start_slidev = machineconfig.scripts.python.start_slidev:arg_parser
21
18
  wifi_conn = machineconfig.scripts.python.wifi_conn:arg_parser