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

@@ -150,7 +150,7 @@ from pathlib import Path
150
150
  else:
151
151
  console.print(Panel("❌ Could not determine the local machineconfig repo root. Please ensure the `REPO_ROOT` in `source_of_truth.py` is correctly set to the local path of the machineconfig repo, or do not use the `--local` flag.", title="Error", border_style="red"))
152
152
  return
153
- else: ve_line = "--with machineconfig[plot]"
153
+ else: ve_line = "--with machineconfig[plot]>=5.6"
154
154
  fire_line = f"uv run --python 3.14 {ve_line} {interpreter} {interactivity} {profile} {str(pyfile)}"
155
155
 
156
156
  from machineconfig.utils.code import run_shell_script
@@ -41,6 +41,14 @@ def shell():
41
41
  from machineconfig.profile.create_shell_profile import create_default_shell_profile
42
42
  create_default_shell_profile()
43
43
 
44
+ @config_apps.command(no_args_is_help=False)
45
+ def path():
46
+ """📚 NAVIGATE PATH variable with TUI"""
47
+ from machineconfig.scripts.python import env_manager as navigator
48
+ from pathlib import Path
49
+ path = Path(navigator.__file__).resolve().parent.joinpath("path_manager_tui.py")
50
+ from machineconfig.utils.code import run_shell_script
51
+ run_shell_script(f"uv run --no-dev --with machineconfig>=5.6,textual {path}")
44
52
 
45
53
  @config_apps.command(no_args_is_help=False)
46
54
  def pwsh_theme():
@@ -42,7 +42,7 @@ def navigate():
42
42
  from pathlib import Path
43
43
  path = Path(navigator.__file__).resolve().parent.joinpath("devops_navigator.py")
44
44
  from machineconfig.utils.code import run_shell_script
45
- run_shell_script(f"uv run --with machineconfig {path}")
45
+ run_shell_script(f"uv run --no-dev --with machineconfig>=5.6,textual {path}")
46
46
 
47
47
 
48
48
  @cli_app.command(no_args_is_help=True)
@@ -0,0 +1,47 @@
1
+ """Cross-platform PATH explorer backend."""
2
+
3
+ import os
4
+ import platform
5
+ from pathlib import Path
6
+ from typing import Literal
7
+
8
+
9
+ PlatformType = Literal["Windows", "Linux", "Darwin"]
10
+
11
+
12
+ def get_platform() -> PlatformType:
13
+ """Get the current platform."""
14
+ return platform.system() # type: ignore[return-value]
15
+
16
+
17
+ def get_path_entries() -> list[str]:
18
+ """Get all PATH entries for the current platform."""
19
+ path_str = os.environ.get("PATH", "")
20
+ separator = ";" if get_platform() == "Windows" else ":"
21
+ return [entry for entry in path_str.split(separator) if entry.strip()]
22
+
23
+
24
+ def get_directory_contents(directory: str, max_items: int = 50) -> list[str]:
25
+ """Get contents of a directory, limited to max_items."""
26
+ try:
27
+ path = Path(directory)
28
+ if not path.exists():
29
+ return ["⚠️ Directory does not exist"]
30
+ if not path.is_dir():
31
+ return ["⚠️ Not a directory"]
32
+
33
+ items = []
34
+ for item in sorted(path.iterdir(), key=lambda p: (not p.is_dir(), p.name.lower())):
35
+ if len(items) >= max_items:
36
+ items.append(f"... and {sum(1 for _ in path.iterdir()) - max_items} more items")
37
+ break
38
+ prefix = "📁 " if item.is_dir() else "📄 "
39
+ items.append(f"{prefix}{item.name}")
40
+
41
+ if not items:
42
+ return ["📭 Empty directory"]
43
+ return items
44
+ except PermissionError:
45
+ return ["⚠️ Permission denied"]
46
+ except Exception as e:
47
+ return [f"⚠️ Error: {e!s}"]
@@ -0,0 +1,219 @@
1
+ """Cross-platform PATH explorer with Textual TUI."""
2
+
3
+ from pathlib import Path
4
+
5
+ from textual import on
6
+ from textual.app import App, ComposeResult
7
+ from textual.binding import Binding
8
+ from textual.containers import Horizontal, Vertical
9
+ from textual.widgets import Footer, Header, Label, ListItem, ListView, Static
10
+
11
+ from machineconfig.scripts.python.env_manager.path_manager_backend import get_directory_contents, get_path_entries, get_platform
12
+
13
+
14
+ class DirectoryPreview(Static):
15
+ """Widget to display directory contents."""
16
+
17
+ def __init__(self, *args, **kwargs) -> None: # type: ignore[no-untyped-def]
18
+ super().__init__(*args, **kwargs)
19
+ self.border_title = "📂 Directory Preview"
20
+
21
+ def update_preview(self, directory: str) -> None:
22
+ """Update the preview with directory contents."""
23
+ if not directory:
24
+ self.update("Select a PATH entry to preview its contents")
25
+ return
26
+
27
+ contents = get_directory_contents(directory, max_items=30)
28
+ preview_text = f"[bold cyan]{directory}[/bold cyan]\n\n"
29
+ preview_text += "\n".join(contents)
30
+ self.update(preview_text)
31
+
32
+
33
+ class StatusBar(Static):
34
+ """Status bar to show messages."""
35
+
36
+ def __init__(self, *args, **kwargs) -> None: # type: ignore[no-untyped-def]
37
+ super().__init__(*args, **kwargs)
38
+ self.border_title = "ℹ️ Status"
39
+
40
+ def show_message(self, message: str, message_type: str = "info") -> None:
41
+ """Display a status message."""
42
+ color = {"info": "cyan", "success": "green", "error": "red", "warning": "yellow"}.get(message_type, "white")
43
+ self.update(f"[{color}]{message}[/{color}]")
44
+
45
+
46
+ class PathExplorerApp(App[None]):
47
+ """A Textual app to explore PATH entries."""
48
+
49
+ CSS = """
50
+ Screen {
51
+ background: $surface;
52
+ }
53
+
54
+ Header {
55
+ background: $primary;
56
+ color: $text;
57
+ }
58
+
59
+ Footer {
60
+ background: $panel;
61
+ }
62
+
63
+ #main-container {
64
+ height: 100%;
65
+ }
66
+
67
+ #left-panel {
68
+ width: 50%;
69
+ height: 100%;
70
+ border: solid $primary;
71
+ padding: 1;
72
+ }
73
+
74
+ #right-panel {
75
+ width: 50%;
76
+ height: 100%;
77
+ border: solid $accent;
78
+ padding: 1;
79
+ }
80
+
81
+ ListView {
82
+ height: 1fr;
83
+ border: solid $accent;
84
+ background: $surface;
85
+ }
86
+
87
+ ListView > ListItem {
88
+ padding: 0 1;
89
+ }
90
+
91
+ ListView > ListItem.--highlight {
92
+ background: $accent 20%;
93
+ }
94
+
95
+ DirectoryPreview {
96
+ height: 1fr;
97
+ border: solid $primary;
98
+ background: $surface;
99
+ padding: 1;
100
+ overflow-y: auto;
101
+ }
102
+
103
+ StatusBar {
104
+ height: 3;
105
+ border: solid $success;
106
+ background: $surface;
107
+ padding: 1;
108
+ }
109
+
110
+ Label {
111
+ padding: 0 1;
112
+ height: auto;
113
+ }
114
+ """
115
+
116
+ BINDINGS = [
117
+ Binding("q", "quit", "Quit", show=True),
118
+ Binding("r", "refresh", "Refresh", show=True),
119
+ Binding("c", "copy_path", "Copy Path", show=True),
120
+ ]
121
+
122
+ def __init__(self) -> None:
123
+ super().__init__()
124
+ self.selected_path: str = ""
125
+
126
+ def compose(self) -> ComposeResult:
127
+ """Create child widgets for the app."""
128
+ platform_name = get_platform()
129
+ yield Header(show_clock=True)
130
+
131
+ with Horizontal(id="main-container"):
132
+ with Vertical(id="left-panel"):
133
+ yield Label(f"🔧 PATH Entries ({platform_name})")
134
+ yield ListView(id="path-list")
135
+
136
+ with Vertical(id="right-panel"):
137
+ yield DirectoryPreview(id="preview")
138
+ yield StatusBar(id="status")
139
+
140
+ yield Footer()
141
+
142
+ def on_mount(self) -> None:
143
+ """Initialize the app when mounted."""
144
+ self.title = "PATH Explorer"
145
+ self.sub_title = f"Platform: {get_platform()}"
146
+ self.refresh_path_list()
147
+ self.query_one("#status", StatusBar).show_message("Ready. Select a PATH entry to preview its contents.", "info")
148
+
149
+ def refresh_path_list(self) -> None:
150
+ """Refresh the list of PATH entries."""
151
+ list_view = self.query_one("#path-list", ListView)
152
+ list_view.clear()
153
+
154
+ entries = get_path_entries()
155
+ for entry in entries:
156
+ path = Path(entry)
157
+ exists = path.exists()
158
+ icon = "✅" if exists else "❌"
159
+ item = ListItem(Label(f"{icon} {entry}"))
160
+ item.set_class(exists, "--valid")
161
+ list_view.append(item)
162
+
163
+ self.query_one("#status", StatusBar).show_message(f"Loaded {len(entries)} PATH entries", "success")
164
+
165
+ @on(ListView.Highlighted)
166
+ def handle_highlight(self, event: ListView.Highlighted) -> None:
167
+ """Handle highlighting of a PATH entry (scroll preview)."""
168
+ if event.item is None:
169
+ return
170
+ label = event.item.query_one(Label)
171
+ text = label.render()
172
+ # Remove the icon prefix
173
+ highlighted_path = str(text).split(" ", 1)[1] if " " in str(text) else str(text)
174
+
175
+ preview = self.query_one("#preview", DirectoryPreview)
176
+ preview.update_preview(highlighted_path)
177
+
178
+ self.query_one("#status", StatusBar).show_message(f"Previewing: {highlighted_path}", "info")
179
+
180
+ @on(ListView.Selected)
181
+ def handle_selection(self, event: ListView.Selected) -> None:
182
+ """Handle selection of a PATH entry (Enter key)."""
183
+ label = event.item.query_one(Label)
184
+ text = label.render()
185
+ # Remove the icon prefix
186
+ self.selected_path = str(text).split(" ", 1)[1] if " " in str(text) else str(text)
187
+
188
+ preview = self.query_one("#preview", DirectoryPreview)
189
+ preview.update_preview(self.selected_path)
190
+
191
+ self.query_one("#status", StatusBar).show_message(f"Selected: {self.selected_path}", "success")
192
+
193
+ def action_refresh(self) -> None:
194
+ """Refresh the PATH list."""
195
+ self.refresh_path_list()
196
+
197
+ def action_copy_path(self) -> None:
198
+ """Copy selected path to clipboard."""
199
+ if not self.selected_path:
200
+ self.query_one("#status", StatusBar).show_message("No PATH entry selected", "warning")
201
+ return
202
+
203
+ # Try to copy to clipboard
204
+ try:
205
+ import pyperclip
206
+ pyperclip.copy(self.selected_path)
207
+ self.query_one("#status", StatusBar).show_message(f"Copied to clipboard: {self.selected_path}", "success")
208
+ except ImportError:
209
+ self.query_one("#status", StatusBar).show_message("pyperclip not available. Install it to enable clipboard support.", "warning")
210
+
211
+
212
+ def main() -> None:
213
+ """Run the PATH Explorer TUI."""
214
+ app = PathExplorerApp()
215
+ app.run()
216
+
217
+
218
+ if __name__ == "__main__":
219
+ main()
@@ -5,7 +5,7 @@
5
5
  # mkdir ~/data/local
6
6
  # sudo mount -o nolock,noatime,nodiratime,proto=tcp,timeo=600,retrans=2,noac alex-p51s-5:/home/alex/data/local ./data/local
7
7
 
8
- uv run --python 3.14 --with machineconfig python -m machineconfig.scripts.python.mount_nfs
8
+ uv run --python 3.14 --with machineconfig>=5.6python -m machineconfig.scripts.python.mount_nfs
9
9
  # Check if remote server is reachable and share folder exists
10
10
  if ! ping -c 1 "$remote_server" &> /dev/null; then
11
11
  echo "💥 Error: Remote server $remote_server is not reachable."
@@ -7,7 +7,7 @@ def analyze_repo_development(repo_path: str = typer.Argument(..., help="Path to
7
7
  from pathlib import Path
8
8
  count_lines_path = Path(count_lines.__file__)
9
9
  # --project $HOME/code/ machineconfig --group plot
10
- cmd = f"""uv run --python 3.14 --with machineconfig[plot] {count_lines_path} analyze-over-time {repo_path}"""
10
+ cmd = f"""uv run --python 3.14 --with machineconfig[plot]>=5.6 {count_lines_path} analyze-over-time {repo_path}"""
11
11
  from machineconfig.utils.code import run_shell_script
12
12
  run_shell_script(cmd)
13
13
 
@@ -7,7 +7,7 @@ $user = ''
7
7
  $sharePath = ''
8
8
  $driveLetter = ''
9
9
 
10
- uv run --python 3.14 --with machineconfig python -m machineconfig.scripts.python.mount_ssh
10
+ uv run --python 3.14 --with machineconfig>=5.6python -m machineconfig.scripts.python.mount_ssh
11
11
 
12
12
  net use T: \\sshfs.kr\$user@$host.local
13
13
  # this worked: net use T: \\sshfs\alex@alex-p51s-5.local
@@ -1,25 +1,25 @@
1
1
  #!/bin/bash
2
2
  . <( curl -sSL "https://raw.githubusercontent.com/thisismygitrepo/machineconfig/main/src/machineconfig/setup_linux/uv.sh")
3
3
  devops() {
4
- "$HOME/.local/bin/uv" run --python 3.14 --with machineconfig devops "$@"
4
+ "$HOME/.local/bin/uv" run --python 3.14 --with machineconfig>=5.6 devops "$@"
5
5
  }
6
6
  agents() {
7
- "$HOME/.local/bin/uv" run --python 3.14 --with machineconfig agents "$@"
7
+ "$HOME/.local/bin/uv" run --python 3.14 --with machineconfig>=5.6 agents "$@"
8
8
  }
9
9
  cloud() {
10
- "$HOME/.local/bin/uv" run --python 3.14 --with machineconfig cloud "$@"
10
+ "$HOME/.local/bin/uv" run --python 3.14 --with machineconfig>=5.6 cloud "$@"
11
11
  }
12
12
  croshell() {
13
- "$HOME/.local/bin/uv" run --python 3.14 --with machineconfig croshell "$@"
13
+ "$HOME/.local/bin/uv" run --python 3.14 --with machineconfig>=5.6 croshell "$@"
14
14
  }
15
15
  fire() {
16
- "$HOME/.local/bin/uv" run --python 3.14 --with machineconfig fire "$@"
16
+ "$HOME/.local/bin/uv" run --python 3.14 --with machineconfig>=5.6fire "$@"
17
17
  }
18
18
  ftpx() {
19
- "$HOME/.local/bin/uv" run --python 3.14 --with machineconfig ftpx "$@"
19
+ "$HOME/.local/bin/uv" run --python 3.14 --with machineconfig>=5.6ftpx "$@"
20
20
  }
21
21
  sessions() {
22
- "$HOME/.local/bin/uv" run --python 3.14 --with machineconfig sessions "$@"
22
+ "$HOME/.local/bin/uv" run --python 3.14 --with machineconfig>=5.6sessions "$@"
23
23
  }
24
24
 
25
25
  echo "devops command is now defined in this shell session."
@@ -2,30 +2,30 @@
2
2
 
3
3
  iex (iwr "https://raw.githubusercontent.com/thisismygitrepo/machineconfig/main/src/machineconfig/setup_windows/uv.ps1").Content
4
4
  function devops {
5
- & "$HOME\.local\bin\uv.exe" run --python 3.14 --with machineconfig devops $args
5
+ & "$HOME\.local\bin\uv.exe" run --python 3.14 --with machineconfig>=5.6 devops $args
6
6
  }
7
7
 
8
8
  function cloud {
9
- & "$HOME\.local\bin\uv.exe" run --python 3.14 --with machineconfig cloud $args
9
+ & "$HOME\.local\bin\uv.exe" run --python 3.14 --with machineconfig>=5.6 cloud $args
10
10
  }
11
11
 
12
12
  function croshell {
13
- & "$HOME\.local\bin\uv.exe" run --python 3.14 --with machineconfig croshell $args
13
+ & "$HOME\.local\bin\uv.exe" run --python 3.14 --with machineconfig>=5.6 croshell $args
14
14
  }
15
15
 
16
16
  function agents {
17
- & "$HOME\.local\bin\uv.exe" run --python 3.14 --with machineconfig agents $args
17
+ & "$HOME\.local\bin\uv.exe" run --python 3.14 --with machineconfig>=5.6 agents $args
18
18
  }
19
19
 
20
20
  function fire {
21
- & "$HOME\.local\bin\uv.exe" run --python 3.14 --with machineconfig fire $args
21
+ & "$HOME\.local\bin\uv.exe" run --python 3.14 --with machineconfig>=5.6 fire $args
22
22
  }
23
23
 
24
24
  function ftpx {
25
- & "$HOME\.local\bin\uv.exe" run --python 3.14 --with machineconfig ftpx $args
25
+ & "$HOME\.local\bin\uv.exe" run --python 3.14 --with machineconfig>=5.6 ftpx $args
26
26
  }
27
27
 
28
28
  function sessions {
29
- & "$HOME\.local\bin\uv.exe" run --python 3.14 --with machineconfig sessions $args
29
+ & "$HOME\.local\bin\uv.exe" run --python 3.14 --with machineconfig>=5.6 sessions $args
30
30
  }
31
31
 
@@ -215,24 +215,36 @@ class SSH: # inferior alternative: https://github.com/fabric/fabric
215
215
  self.terminal_responses.append(res)
216
216
  return res
217
217
  def run_py(self, cmd: str, desc: str = "", return_obj: bool = False, verbose: bool = True, strict_err: bool = False, strict_returncode: bool = False) -> Union[Any, Response]:
218
- assert '"' not in cmd, 'Avoid using `"` in your command. I dont know how to handle this when passing is as command to python in pwsh command.'
218
+ from machineconfig.utils.accessories import randstr
219
+ from pathlib import Path
220
+ cmd_path = Path.home().joinpath(f"tmp_results/tmp_scripts/ssh/runpy_{randstr()}.py")
221
+ cmd_path.parent.mkdir(parents=True, exist_ok=True)
219
222
  if not return_obj:
223
+ cmd_path.write_text(cmd, encoding="utf-8")
224
+ self.copy_from_here(source=cmd_path, target=None)
220
225
  return self.run(
221
- cmd=f"""$HOME/.local/bin/uv run --with machineconfig python -c "{cmd}\n""" + '"',
226
+ cmd=f"""$HOME/.local/bin/uv run --with machineconfig>=5.6python {cmd_path.relative_to(Path.home())}""" + '"',
222
227
  desc=desc or f"run_py on {self.get_remote_repr()}",
223
228
  verbose=verbose,
224
229
  strict_err=strict_err,
225
230
  strict_returncode=strict_returncode,
226
231
  )
227
232
  assert "obj=" in cmd, "The command sent to run_py must have `obj=` statement if return_obj is set to True"
228
- source_file = self.run_py(f"""{cmd}
229
- import pickle
230
- import tempfile
231
- from pathlib import Path
232
- path = tempfile.emkstemp(suffix=".pkl")[1]
233
- Path(path).write_bytes(pickle.dumps(obj))
234
- print(path)""", desc=desc, verbose=verbose, strict_err=True, strict_returncode=True).op.split("\n")[-1]
235
- res = self.copy_to_here(source=source_file, target=PathExtended.tmpfile(suffix=".pkl"))
233
+ return_path = cmd_path.parent.joinpath(f"return_obj_{randstr()}.pkl")
234
+ def func(pkl_path_rel2_home: str) -> None:
235
+ pickle_path_obj = Path.home().joinpath(pkl_path_rel2_home).expanduser().absolute()
236
+ import pickle
237
+ obj = globals().get("obj", None)
238
+ pickle_path_obj.write_bytes(pickle.dumps(obj))
239
+ from machineconfig.utils.meta import function_to_script
240
+ cmd_complement = function_to_script(func=func, call_with_kwargs={"pkl_path_rel2_home": return_path.relative_to(Path.home()).as_posix()})
241
+ cmd_total = f"""{cmd}
242
+ {cmd_complement}
243
+ """
244
+ cmd_path.write_text(cmd_total, encoding="utf-8")
245
+ self.copy_from_here(source=cmd_path, target=None)
246
+ _resp = self.run(f"""$HOME/.local/bin/uv run --with machineconfig>=5.6python {cmd_path}""", desc=desc, verbose=verbose, strict_err=True, strict_returncode=True).op.split("\n")[-1]
247
+ res = self.copy_to_here(source=None, target=return_path)
236
248
  import pickle
237
249
  return pickle.loads(res.read_bytes())
238
250
 
@@ -344,28 +356,30 @@ obj=P(r'{source}').search(folders=False, r=True).collapseuser(strict=False)
344
356
  print("\n")
345
357
  return target_obj
346
358
 
347
- def receieve(self, source: PLike, target: OPLike = None, z: bool = False, r: bool = False) -> PathExtended:
348
- scout = self.run_py(cmd=f"obj=scout(r'{source}', z={z}, r={r})", desc=f"Scouting source `{source}` path on remote", return_obj=True, verbose=False)
349
- assert isinstance(scout, Scout)
350
- if not z and scout.is_dir and scout.files is not None:
351
- if r:
352
- tmp: list[PathExtended] = [self.receieve(source=file.as_posix(), target=PathExtended(target).joinpath(PathExtended(file).relative_to(source)) if target else None, r=False) for file in scout.files]
353
- return tmp[0]
354
- else:
355
- print("Source is a directory! either set `r=True` for recursive sending or raise `zip_first=True` flag.")
356
- if target:
357
- target = PathExtended(target).expanduser().absolute()
358
- else:
359
- target = scout.source_rel2home.expanduser().absolute()
360
- target.parent.mkdir(parents=True, exist_ok=True)
361
- if z and ".zip" not in target.suffix:
362
- target += ".zip"
363
- source = scout.source_full
364
- with self.tqdm_wrap(ascii=True, unit="b", unit_scale=True) as pbar:
365
- self.sftp.get(remotepath=source.as_posix(), localpath=target.as_posix(), callback=pbar.view_bar) # type: ignore # pylint: disable=E1129
366
- if z:
367
- target = target.unzip(inplace=True, content=True)
368
- self.run_py(f"""
369
- from machineconfig.utils.path_extended import PathExtended as P; P(r'{source.as_posix()}').delete(sure=True)""", desc="Cleaning temp zip files @ remote.", strict_returncode=True, strict_err=True)
370
- print("\n")
371
- return target
359
+ # def receieve(self, source: PLike, target: OPLike = None, z: bool = False, r: bool = False) -> PathExtended:
360
+ # scout = self.run_py(cmd=f"obj=scout(r'{source}', z={z}, r={r})", desc=f"Scouting source `{source}` path on remote", return_obj=True, verbose=False)
361
+ # assert isinstance(scout, Scout)
362
+ # if not z and scout.is_dir and scout.files is not None:
363
+ # if r:
364
+ # tmp: list[PathExtended] = [self.receieve(source=file.as_posix(), target=PathExtended(target).joinpath(PathExtended(file).relative_to(source)) if target else None, r=False) for file in scout.files]
365
+ # return tmp[0]
366
+ # else:
367
+ # print("Source is a directory! either set `r=True` for recursive sending or raise `zip_first=True` flag.")
368
+ # if target:
369
+ # target = PathExtended(target).expanduser().absolute()
370
+ # else:
371
+ # target = scout.source_rel2home.expanduser().absolute()
372
+ # target.parent.mkdir(parents=True, exist_ok=True)
373
+ # if z and ".zip" not in target.suffix:
374
+ # target += ".zip"
375
+ # source = scout.source_full
376
+ # with self.tqdm_wrap(ascii=True, unit="b", unit_scale=True) as pbar:
377
+ # self.sftp.get(remotepath=source.as_posix(), localpath=target.as_posix(), callback=pbar.view_bar) # type: ignore # pylint: disable=E1129
378
+ # if z:
379
+ # target = target.unzip(inplace=True, content=True)
380
+ # self.run_py(f"""
381
+ # from machineconfig.utils.path_extended import PathExtended as P;
382
+ # P(r'{source.as_posix()}').delete(sure=True)
383
+ # """, desc="Cleaning temp zip files @ remote.", strict_returncode=True, strict_err=True)
384
+ # print("\n")
385
+ # return target
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: machineconfig
3
- Version: 5.59
3
+ Version: 5.61
4
4
  Summary: Dotfiles management package
5
5
  Author-email: Alex Al-Saffar <programmer@usa.com>
6
6
  License: Apache 2.0
@@ -27,6 +27,7 @@ Requires-Dist: pyjson5>=1.6.9
27
27
  Requires-Dist: questionary>=2.1.1
28
28
  Requires-Dist: typer-slim>=0.19.2
29
29
  Requires-Dist: typer>=0.19.2
30
+ Requires-Dist: textual>=6.2.1
30
31
  Provides-Extra: windows
31
32
  Requires-Dist: pywin32; extra == "windows"
32
33
  Provides-Extra: plot
@@ -122,10 +122,9 @@ machineconfig/scripts/linux/other/switch_ip,sha256=NQfeKMBSbFY3eP6M-BadD-TQo5qMP
122
122
  machineconfig/scripts/python/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
123
123
  machineconfig/scripts/python/agents.py,sha256=mFVAnOdWVDoZTdRjLansS5-MGbCKkqDiGseRmXsU6B0,10478
124
124
  machineconfig/scripts/python/cloud.py,sha256=kRH9Pt1yEkASFskIVEgRmkidrksdkgv2-bBmjLSxzSo,814
125
- machineconfig/scripts/python/croshell.py,sha256=GfqDkXdHCGDLCoHIHyJV2sqMrqhCWaOWB2FXKy2T0cw,7184
125
+ machineconfig/scripts/python/croshell.py,sha256=GawpJM3A4Nqsh2sKZXqRGbQq-GrN1g9XBCoiQBjIm4E,7189
126
126
  machineconfig/scripts/python/devops.py,sha256=UERDj4hEDW2b6CW6w5BPpgZ6UyDCOvOcfjpW1YKP_QE,1481
127
127
  machineconfig/scripts/python/devops_navigator.py,sha256=_PlZrFrxbNHC1tRTx2n57pteUFdkszH9GtKq2JxEm4E,34940
128
- machineconfig/scripts/python/devops_navigator.py.backup,sha256=_PlZrFrxbNHC1tRTx2n57pteUFdkszH9GtKq2JxEm4E,34940
129
128
  machineconfig/scripts/python/fire_jobs.py,sha256=l2qByVK2rxWDUGFliU3HYwrtAI1XsUvOtcGLX4DUA5U,13689
130
129
  machineconfig/scripts/python/ftpx.py,sha256=IoopsHQavcvLqVEDjaDnmfVJHtYgJaEX-B6r84VIO-Y,9445
131
130
  machineconfig/scripts/python/interactive.py,sha256=IRveYja_9omEEhRyM1M6_SlljPY2Eo_GGoK9tTi1nsk,11778
@@ -171,12 +170,12 @@ machineconfig/scripts/python/croshell_helpers/start_slidev.py,sha256=HfJReOusTPh
171
170
  machineconfig/scripts/python/croshell_helpers/viewer.py,sha256=heQNjB9fwn3xxbPgMofhv1Lp6Vtkl76YjjexWWBM0pM,2041
172
171
  machineconfig/scripts/python/croshell_helpers/viewer_template.py,sha256=ve3Q1-iKhCLc0VJijKvAeOYp2xaFOeIOC_XW956GWCc,3944
173
172
  machineconfig/scripts/python/devops_helpers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
174
- machineconfig/scripts/python/devops_helpers/cli_config.py,sha256=lIEKz0v3ANvTHOrcQzHD5Th8gXbgOTShgnnUvPZG5GA,3534
173
+ machineconfig/scripts/python/devops_helpers/cli_config.py,sha256=9gh7dcAm9JguYYqQWLC9qpVJ8Q47TGDZadmjVfYlGAQ,3961
175
174
  machineconfig/scripts/python/devops_helpers/cli_config_dotfile.py,sha256=rjTys4FNf9_feP9flWM7Zvq17dxWmetSiGaHPxp25nk,2737
176
175
  machineconfig/scripts/python/devops_helpers/cli_data.py,sha256=f_2espL92n6SoNb5sFVMvrK7LA29HzfrFAKhxKaud1M,510
177
176
  machineconfig/scripts/python/devops_helpers/cli_nw.py,sha256=4Ko4dA8YXqiRJvuOuwZv3YOvnSJQ7-A11ezJ8EztDis,2068
178
177
  machineconfig/scripts/python/devops_helpers/cli_repos.py,sha256=GQJaCSnvNbIo_CmpYBDZOUyi0kPgn8VCr3a5Dnfy0_w,9681
179
- machineconfig/scripts/python/devops_helpers/cli_self.py,sha256=esK2eWB7GKa0_TphWhsw9UZ3z4H4qt3HpW0VVkaGebI,2262
178
+ machineconfig/scripts/python/devops_helpers/cli_self.py,sha256=ca5SKL8_UwY07rX2dL5jwgMBXQvZxcCdXlMhMfOSLnA,2284
180
179
  machineconfig/scripts/python/devops_helpers/cli_share_server.py,sha256=285OzxttCx7YsrpOkaapMKP1eVGHmG5TkkaSQnY7i3c,3976
181
180
  machineconfig/scripts/python/devops_helpers/cli_terminal.py,sha256=k_PzXaiGyE0vXr0Ii1XcJz2A7UvyPJrR31TRWt4RKRI,6019
182
181
  machineconfig/scripts/python/devops_helpers/devops_add_identity.py,sha256=wvjNgqsLmqD2SxbNCW_usqfp0LI-TDvcJJKGOWt2oFw,3775
@@ -187,6 +186,9 @@ machineconfig/scripts/python/devops_helpers/devops_update_repos.py,sha256=tvD81G
187
186
  machineconfig/scripts/python/devops_helpers/themes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
188
187
  machineconfig/scripts/python/devops_helpers/themes/choose_pwsh_theme.ps1,sha256=58gFOeynADHLTdk8zqEnndBtyNGrln0jvpo76O0UWTw,3136
189
188
  machineconfig/scripts/python/devops_helpers/themes/choose_wezterm_theme.py,sha256=pRXAGe2IpysYshsaF8CKEwHI8EGPtLcM8PtiAqM7vmM,3425
189
+ machineconfig/scripts/python/env_manager/__init__.py,sha256=E4LAHbU1wo2dLjE36ntv8U7QNTe8TasujUAYK9SLvWk,6
190
+ machineconfig/scripts/python/env_manager/path_manager_backend.py,sha256=ZVGlGJALhg7zNABDdwXxL7MFbL2BXPebObipXSLGbic,1552
191
+ machineconfig/scripts/python/env_manager/path_manager_tui.py,sha256=YAZb1KOVpkfTzwApk-KYPplwvDELeU62OIDdg82m-eQ,6748
190
192
  machineconfig/scripts/python/helpers_fire/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
191
193
  machineconfig/scripts/python/helpers_fire/fire_agents_help_launch.py,sha256=vgJMzSyLRTik2lnKYZsNzwoAF-z8Tp1aVi4wMvIJzPs,5627
192
194
  machineconfig/scripts/python/helpers_fire/fire_agents_help_search.py,sha256=qIfSS_su2YJ1Gb0_lu4cbjlJlYMBw0v52NTGiSrGjk8,2991
@@ -213,7 +215,7 @@ machineconfig/scripts/python/helpers_repos/grource.py,sha256=IywQ1NDPcLXM5Tr9xhm
213
215
  machineconfig/scripts/python/helpers_repos/secure_repo.py,sha256=G_quiKOLNkWD5UG8ekexgh9xbpW4Od-J1pLJbLLWnpg,993
214
216
  machineconfig/scripts/python/nw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
215
217
  machineconfig/scripts/python/nw/mount_drive,sha256=zemKofv7hOmRN_V3qK0q580GkfWw3VdikyVVQyiu8j8,3514
216
- machineconfig/scripts/python/nw/mount_nfs,sha256=tdFpYuJ2l2EYCgjYRBJRA8xKkALJcC_u7i8wSGY1UKg,1847
218
+ machineconfig/scripts/python/nw/mount_nfs,sha256=W2j_db7QHKINJHEWtw9uMbSc2A5juHWD7fU6-gu9Nb4,1851
217
219
  machineconfig/scripts/python/nw/mount_nfs.py,sha256=aECrL64j9g-9rF49sVJAjGmzaoGgcMnl3g9v17kQF4c,3239
218
220
  machineconfig/scripts/python/nw/mount_nw_drive,sha256=BqjGBCbwe5ZAsZDO3L0zHhh_gJfZy1CYOcqXA4Y-WkQ,2262
219
221
  machineconfig/scripts/python/nw/mount_nw_drive.py,sha256=iru6AtnTyvyuk6WxlK5R4lDkuliVpPV5_uBTVVhXtjQ,1550
@@ -225,7 +227,7 @@ machineconfig/scripts/python/nw/wsl_windows_transfer.py,sha256=534zlYe3Xsr0mqegA
225
227
  machineconfig/scripts/python/repos_helpers/action.py,sha256=t6x9K43Uy7r5aRpdODfsN-5UoMrYXEG2cVw-Y8l9prw,14847
226
228
  machineconfig/scripts/python/repos_helpers/clone.py,sha256=9vGb9NCXT0lkerPzOJjmFfhU8LSzE-_1LDvjkhgnal0,5461
227
229
  machineconfig/scripts/python/repos_helpers/count_lines.py,sha256=ZLEajCLmlFFY969BehabqGOB9_kkpATO3Lt09L7KULk,15968
228
- machineconfig/scripts/python/repos_helpers/count_lines_frontend.py,sha256=LtD0A1D-zWwwcPt4KtGUQie-iAxl3CojTHySzPmBbDc,560
230
+ machineconfig/scripts/python/repos_helpers/count_lines_frontend.py,sha256=XlGwKNN4RIUyI_T7JJReWZ7anbjuuP2jLiTDteNxtKc,565
229
231
  machineconfig/scripts/python/repos_helpers/entrypoint.py,sha256=C-_D03abE0TkVCJ4jZoliUMAhRRkZ77mcwMoPOuieJQ,2827
230
232
  machineconfig/scripts/python/repos_helpers/record.py,sha256=3T5VmMbvywScZhTW2j4cGLK0T2LSWxKfnXkRTxkuLP4,10994
231
233
  machineconfig/scripts/python/repos_helpers/sync.py,sha256=CLLWy2n2gY9beXPF-mblOQ6R7cKoenkJjMiX7tHQsBk,3091
@@ -238,7 +240,7 @@ machineconfig/scripts/windows/fzfrga.bat,sha256=rU_KBMO6ii2EZ0akMnmDk9vpuhKSUZqk
238
240
  machineconfig/scripts/windows/mounts/mount_nfs.ps1,sha256=XrAdzpxE6a4OccSmWJ7YWHJTnsZK8uXnFE5j9GOPA20,2026
239
241
  machineconfig/scripts/windows/mounts/mount_nw.ps1,sha256=puxcfZc3ZCJerm8pj8OZGVoTYkhzp-h7oV-MrksSqIE,454
240
242
  machineconfig/scripts/windows/mounts/mount_smb.ps1,sha256=PzYWpIO9BpwXjdWlUQL9pnMRnOGNSkxfh4bHukJFme8,69
241
- machineconfig/scripts/windows/mounts/mount_ssh.ps1,sha256=AAp0gTUfzMmP-q82NvouzDG6uy8GZ8eFNS_kXCYH91Q,314
243
+ machineconfig/scripts/windows/mounts/mount_ssh.ps1,sha256=jg-FjEm2JdjrF1CPq4G3hnXsRKkDgLmiWrgP8I4XL7Q,318
242
244
  machineconfig/scripts/windows/mounts/share_cloud.cmd,sha256=exD7JCdxw2LqVjw2MKCYHbVZlEqmelXtwnATng-dhJ4,1028
243
245
  machineconfig/scripts/windows/mounts/share_smb.ps1,sha256=U7x8ULYSjbgzTtiHNSKQuTaZ_apilDvkGV5Xm5hXk5M,384
244
246
  machineconfig/scripts/windows/mounts/unlock_bitlocker.ps1,sha256=Wv-SLscdckV-1mG3p82VXKPY9zW3hgkRmcLUXIZ1daE,253
@@ -353,7 +355,7 @@ machineconfig/setup_linux/others/mint_keyboard_shortcuts.sh,sha256=F5dbg0n9RHsKG
353
355
  machineconfig/setup_linux/ssh/openssh_all.sh,sha256=3dg6HEUFbHQOzLfSAtzK_D_GB8rGCCp_aBnxNdnidVc,824
354
356
  machineconfig/setup_linux/ssh/openssh_wsl.sh,sha256=1eeRGrloVB34K5z8yWVUMG5b9pV-WBfHgV9jqXiYgCQ,1398
355
357
  machineconfig/setup_linux/web_shortcuts/android.sh,sha256=gzep6bBhK7FCBvGcXK0fdJCtkSfBOftt0aFyDZq_eMs,68
356
- machineconfig/setup_linux/web_shortcuts/interactive.sh,sha256=_qk2RHrfM0-xA_HlnFgk8DtSNN-c3jA0m_UaMrffTYg,824
358
+ machineconfig/setup_linux/web_shortcuts/interactive.sh,sha256=gMn74zeDGp940-8dpq3irOE3j1lucUodKZmkpBhs18k,856
357
359
  machineconfig/setup_windows/__init__.py,sha256=NnSVZkIBoxoMgkj-_KAqGonH3YziBIWXOKDEcmNAGTY,386
358
360
  machineconfig/setup_windows/apps.ps1,sha256=G5GqZ9G0aiQr_A-HaahtRdzpaTTdW6n3DRKMZWDTSPc,11214
359
361
  machineconfig/setup_windows/uv.ps1,sha256=mzkFJUQ57dukVQtY7WqAQIVUDMcixnkir8aNM_TYrl4,350
@@ -363,7 +365,7 @@ machineconfig/setup_windows/others/power_options.ps1,sha256=c7Hn94jBD5GWF29CxMhm
363
365
  machineconfig/setup_windows/ssh/add-sshkey.ps1,sha256=qfPdqCpd9KP3VhH4ifsUm1Xvec7c0QVl4Wt8JIAm9HQ,1653
364
366
  machineconfig/setup_windows/ssh/add_identity.ps1,sha256=b8ZXpmNUSw3IMYvqSY7ClpdWPG39FS7MefoWnRhWN2U,506
365
367
  machineconfig/setup_windows/ssh/openssh-server.ps1,sha256=OMlYQdvuJQNxF5EILLPizB6BZAT3jAmDsv1WcVVxpFQ,2529
366
- machineconfig/setup_windows/web_shortcuts/interactive.ps1,sha256=4mZx9YSRD6pyk17dtxBikg1CDZs83FVZgZ2BLpPhHd0,863
368
+ machineconfig/setup_windows/web_shortcuts/interactive.ps1,sha256=ip168kzXFM49Gpre-PGaOnJS8w-XtTRYxOj54eL1NMs,898
367
369
  machineconfig/setup_windows/wt_and_pwsh/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
368
370
  machineconfig/setup_windows/wt_and_pwsh/set_wt_settings.py,sha256=ogxJnwpdcpH7N6dFJu95UCNoGYirZKQho_3X0F_hmXs,6791
369
371
  machineconfig/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -381,7 +383,7 @@ machineconfig/utils/procs.py,sha256=w75oGKfR7FpT1pGTGd2XscnEOO0IHBWxohLbi69hLqg,
381
383
  machineconfig/utils/scheduler.py,sha256=jZ_1yghqA3-aINPRmE_76gboqJc0UElroR7urNOfXKs,14940
382
384
  machineconfig/utils/scheduling.py,sha256=RF1iXJpqf4Dg18jdZWtBixz97KAHC6VKYqTFSpdLWuc,11188
383
385
  machineconfig/utils/source_of_truth.py,sha256=ZAnCRltiM07ig--P6g9_6nEAvNFC4X4ERFTVcvpIYsE,764
384
- machineconfig/utils/ssh.py,sha256=EF7VjOcv5oYnKhEMfPSNgyQy4RLqMUKXWJ9GlFoqUxw,21360
386
+ machineconfig/utils/ssh.py,sha256=-kcc4ZM8HDf33zc2vwXJmSvj5Z_H8bGt2XjJkzGZits,22241
385
387
  machineconfig/utils/terminal.py,sha256=IlmOByfQG-vjhaFFxxzU5rWzP5_qUzmalRfuey3PAmc,11801
386
388
  machineconfig/utils/upgrade_packages.py,sha256=H96zVJEWXJW07nh5vhjuSCrPtXGqoUb7xeJsFYYdmCI,3330
387
389
  machineconfig/utils/ve.py,sha256=L-6PBXnQGXThiwWgheJMQoisAZOZA6SVCbGw2J-GFnI,2414
@@ -405,8 +407,8 @@ machineconfig/utils/schemas/fire_agents/fire_agents_input.py,sha256=Xbi59rU35AzR
405
407
  machineconfig/utils/schemas/installer/installer_types.py,sha256=QClRY61QaduBPJoSpdmTIdgS9LS-RvE-QZ-D260tD3o,1214
406
408
  machineconfig/utils/schemas/layouts/layout_types.py,sha256=TcqlZdGVoH8htG5fHn1KWXhRdPueAcoyApppZsPAPto,2020
407
409
  machineconfig/utils/schemas/repos/repos_types.py,sha256=ECVr-3IVIo8yjmYmVXX2mnDDN1SLSwvQIhx4KDDQHBQ,405
408
- machineconfig-5.59.dist-info/METADATA,sha256=sGRrPypQIIvxiaL6rrcNeV72CNH1JqRFllT5da_heZM,3103
409
- machineconfig-5.59.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
410
- machineconfig-5.59.dist-info/entry_points.txt,sha256=0zMBUFkDgYw5mB3ASxpONEjTFMAXAkTFHHfAr5c1SKg,423
411
- machineconfig-5.59.dist-info/top_level.txt,sha256=porRtB8qms8fOIUJgK-tO83_FeH6Bpe12oUVC670teA,14
412
- machineconfig-5.59.dist-info/RECORD,,
410
+ machineconfig-5.61.dist-info/METADATA,sha256=nd79KwlS2YYJxQmmBfNFaZZqajq_Q3RMMkDHvAzZw_A,3133
411
+ machineconfig-5.61.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
412
+ machineconfig-5.61.dist-info/entry_points.txt,sha256=0zMBUFkDgYw5mB3ASxpONEjTFMAXAkTFHHfAr5c1SKg,423
413
+ machineconfig-5.61.dist-info/top_level.txt,sha256=porRtB8qms8fOIUJgK-tO83_FeH6Bpe12oUVC670teA,14
414
+ machineconfig-5.61.dist-info/RECORD,,