machineconfig 5.59__py3-none-any.whl → 5.60__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.
- machineconfig/scripts/python/devops_helpers/cli_config.py +8 -0
- machineconfig/scripts/python/devops_helpers/cli_self.py +1 -1
- machineconfig/scripts/python/env_manager/__init__.py +1 -0
- machineconfig/scripts/python/env_manager/path_manager_backend.py +47 -0
- machineconfig/scripts/python/env_manager/path_manager_tui.py +219 -0
- machineconfig/utils/ssh.py +49 -35
- {machineconfig-5.59.dist-info → machineconfig-5.60.dist-info}/METADATA +2 -1
- {machineconfig-5.59.dist-info → machineconfig-5.60.dist-info}/RECORD +11 -9
- machineconfig/scripts/python/devops_navigator.py.backup +0 -899
- {machineconfig-5.59.dist-info → machineconfig-5.60.dist-info}/WHEEL +0 -0
- {machineconfig-5.59.dist-info → machineconfig-5.60.dist-info}/entry_points.txt +0 -0
- {machineconfig-5.59.dist-info → machineconfig-5.60.dist-info}/top_level.txt +0 -0
|
@@ -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,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,textual {path}")
|
|
46
46
|
|
|
47
47
|
|
|
48
48
|
@cli_app.command(no_args_is_help=True)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
a = 2
|
|
@@ -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()
|
machineconfig/utils/ssh.py
CHANGED
|
@@ -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
|
-
|
|
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
|
|
226
|
+
cmd=f"""$HOME/.local/bin/uv run --with machineconfig python {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
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
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 python {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
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
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.
|
|
3
|
+
Version: 5.60
|
|
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
|
|
@@ -125,7 +125,6 @@ machineconfig/scripts/python/cloud.py,sha256=kRH9Pt1yEkASFskIVEgRmkidrksdkgv2-bB
|
|
|
125
125
|
machineconfig/scripts/python/croshell.py,sha256=GfqDkXdHCGDLCoHIHyJV2sqMrqhCWaOWB2FXKy2T0cw,7184
|
|
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=
|
|
173
|
+
machineconfig/scripts/python/devops_helpers/cli_config.py,sha256=966fT3Of0-5ptEQQ1qIvctY1Nx1HFiLBMPPN2E0ef-E,3956
|
|
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=
|
|
178
|
+
machineconfig/scripts/python/devops_helpers/cli_self.py,sha256=ZBUisvjdowT0dH9uM1cvObFk4AwUp72TGy-3ulRNDvo,2279
|
|
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
|
|
@@ -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=
|
|
386
|
+
machineconfig/utils/ssh.py,sha256=fIMF73C4S2G6QvKk6cC3z_noXIHe0q5kZJNgQELuXGM,22233
|
|
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.
|
|
409
|
-
machineconfig-5.
|
|
410
|
-
machineconfig-5.
|
|
411
|
-
machineconfig-5.
|
|
412
|
-
machineconfig-5.
|
|
410
|
+
machineconfig-5.60.dist-info/METADATA,sha256=MyPbosxLDOkM4rrESgjCui2LO8NlvwrAIlaBKmiBIrc,3133
|
|
411
|
+
machineconfig-5.60.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
412
|
+
machineconfig-5.60.dist-info/entry_points.txt,sha256=0zMBUFkDgYw5mB3ASxpONEjTFMAXAkTFHHfAr5c1SKg,423
|
|
413
|
+
machineconfig-5.60.dist-info/top_level.txt,sha256=porRtB8qms8fOIUJgK-tO83_FeH6Bpe12oUVC670teA,14
|
|
414
|
+
machineconfig-5.60.dist-info/RECORD,,
|