machineconfig 5.37__py3-none-any.whl → 5.39__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of machineconfig might be problematic. Click here for more details.

Files changed (117) hide show
  1. machineconfig/cluster/remote/script_execution.py +0 -1
  2. machineconfig/cluster/sessions_managers/zellij_utils/process_monitor.py +2 -4
  3. machineconfig/jobs/installer/check_installations.py +2 -2
  4. machineconfig/jobs/installer/custom_dev/nerfont_windows_helper.py +12 -12
  5. machineconfig/jobs/installer/installer_data.json +53 -2
  6. machineconfig/jobs/windows/archive/archive_pygraphviz.ps1 +1 -3
  7. machineconfig/profile/create_helper.py +26 -0
  8. machineconfig/profile/{create.py → create_links.py} +6 -6
  9. machineconfig/profile/{create_frontend.py → create_links_export.py} +6 -10
  10. machineconfig/profile/{shell.py → create_shell_profile.py} +12 -37
  11. machineconfig/scripts/linux/{share_cloud.sh → other/share_cloud.sh} +3 -0
  12. machineconfig/scripts/linux/z_ls +2 -2
  13. machineconfig/scripts/python/agents.py +0 -1
  14. machineconfig/scripts/python/ai/initai.py +3 -4
  15. machineconfig/scripts/python/ai/scripts/lint_and_type_check.ps1 +0 -1
  16. machineconfig/scripts/python/ai/scripts/lint_and_type_check.sh +0 -1
  17. machineconfig/scripts/python/ai/solutions/generic.py +1 -0
  18. machineconfig/scripts/python/croshell.py +12 -2
  19. machineconfig/scripts/python/croshell_helpers/start_slidev.py +2 -2
  20. machineconfig/scripts/python/devops.py +4 -21
  21. machineconfig/scripts/python/devops_helpers/cli_config.py +8 -8
  22. machineconfig/scripts/python/devops_helpers/cli_config_dotfile.py +3 -3
  23. machineconfig/scripts/python/devops_helpers/cli_nw.py +2 -1
  24. machineconfig/scripts/python/devops_helpers/cli_repos.py +1 -3
  25. machineconfig/scripts/python/devops_helpers/cli_self.py +22 -9
  26. machineconfig/scripts/python/devops_helpers/cli_share_server.py +109 -0
  27. machineconfig/scripts/python/devops_helpers/cli_terminal.py +35 -23
  28. machineconfig/scripts/python/devops_helpers/devops_status.py +7 -80
  29. machineconfig/scripts/python/devops_helpers/devops_update_repos.py +64 -45
  30. machineconfig/scripts/python/devops_helpers/themes/choose_pwsh_theme.ps1 +16 -15
  31. machineconfig/scripts/python/devops_navigator.py +183 -80
  32. machineconfig/scripts/python/fire_jobs.py +4 -1
  33. machineconfig/scripts/python/ftpx.py +0 -1
  34. machineconfig/scripts/python/helpers_fire/{fire_gemini.py → agentic_frameworks/fire_gemini.py} +12 -9
  35. machineconfig/scripts/python/helpers_fire/agentic_frameworks/fire_qwen.py +43 -0
  36. machineconfig/scripts/python/helpers_fire/fire_agents_help_launch.py +4 -4
  37. machineconfig/scripts/python/helpers_fire/template.ps1 +29 -0
  38. machineconfig/scripts/python/helpers_fire/template.sh +1 -1
  39. machineconfig/scripts/python/helpers_repos/cloud_repo_sync.py +3 -3
  40. machineconfig/scripts/python/interactive.py +5 -4
  41. machineconfig/scripts/python/nw/mount_nfs +1 -1
  42. machineconfig/scripts/python/nw/mount_nw_drive +1 -2
  43. machineconfig/scripts/python/repos_helpers/count_lines_frontend.py +1 -1
  44. machineconfig/scripts/python/repos_helpers/entrypoint.py +2 -2
  45. machineconfig/scripts/python/repos_helpers/record.py +2 -2
  46. machineconfig/scripts/python/sessions_helpers/sessions_multiprocess.py +3 -1
  47. machineconfig/scripts/windows/{mount_nfs.ps1 → mounts/mount_nfs.ps1} +1 -3
  48. machineconfig/scripts/windows/{mount_ssh.ps1 → mounts/mount_ssh.ps1} +1 -1
  49. machineconfig/settings/lf/linux/lfrc +4 -7
  50. machineconfig/settings/lf/windows/lfrc +4 -22
  51. machineconfig/settings/lvim/windows/archive/config_additional.lua +0 -6
  52. machineconfig/settings/pistol/pistol.conf +1 -1
  53. machineconfig/settings/shells/bash/init.sh +9 -8
  54. machineconfig/settings/shells/pwsh/init.ps1 +10 -4
  55. machineconfig/settings/svim/linux/init.toml +0 -4
  56. machineconfig/settings/svim/windows/init.toml +0 -3
  57. machineconfig/setup_linux/web_shortcuts/interactive.sh +22 -0
  58. machineconfig/setup_windows/web_shortcuts/interactive.ps1 +34 -1
  59. machineconfig/utils/files/dbms.py +4 -1
  60. machineconfig/utils/installer_utils/installer.py +12 -0
  61. machineconfig/utils/installer_utils/installer_abc.py +26 -9
  62. machineconfig/utils/installer_utils/installer_class.py +1 -1
  63. machineconfig/utils/io.py +0 -18
  64. machineconfig/utils/scheduler.py +3 -4
  65. machineconfig/utils/source_of_truth.py +2 -4
  66. machineconfig/utils/ssh.py +1 -1
  67. {machineconfig-5.37.dist-info → machineconfig-5.39.dist-info}/METADATA +8 -4
  68. {machineconfig-5.37.dist-info → machineconfig-5.39.dist-info}/RECORD +84 -114
  69. machineconfig/jobs/windows/start_terminal.ps1 +0 -6
  70. machineconfig/jobs/windows/startup_file.cmd +0 -2
  71. machineconfig/scripts/cloud/init.sh +0 -105
  72. machineconfig/scripts/linux/agents +0 -2
  73. machineconfig/scripts/linux/cloud +0 -2
  74. machineconfig/scripts/linux/croshell +0 -3
  75. machineconfig/scripts/linux/devops +0 -2
  76. machineconfig/scripts/linux/fire +0 -2
  77. machineconfig/scripts/linux/ftpx +0 -2
  78. machineconfig/scripts/linux/kill_process +0 -2
  79. machineconfig/scripts/linux/sessions +0 -2
  80. machineconfig/scripts/linux/start_terminals +0 -3
  81. machineconfig/scripts/windows/agents.ps1 +0 -1
  82. machineconfig/scripts/windows/cloud.ps1 +0 -1
  83. machineconfig/scripts/windows/croshell.ps1 +0 -1
  84. machineconfig/scripts/windows/devops.ps1 +0 -1
  85. machineconfig/scripts/windows/fire.ps1 +0 -1
  86. machineconfig/scripts/windows/ftpx.ps1 +0 -1
  87. machineconfig/scripts/windows/gpt.ps1 +0 -1
  88. machineconfig/scripts/windows/grep.ps1 +0 -2
  89. machineconfig/scripts/windows/kill_process.ps1 +0 -1
  90. machineconfig/scripts/windows/nano.ps1 +0 -3
  91. machineconfig/scripts/windows/pomodoro.ps1 +0 -1
  92. machineconfig/scripts/windows/reload_path.ps1 +0 -3
  93. machineconfig/scripts/windows/scheduler.ps1 +0 -1
  94. machineconfig/scripts/windows/sessions.ps1 +0 -1
  95. machineconfig/scripts/windows/snapshot.ps1 +0 -1
  96. machineconfig/scripts/windows/start_slidev.ps1 +0 -1
  97. machineconfig/scripts/windows/start_terminals.ps1 +0 -1
  98. machineconfig/scripts/windows/wsl_rdp_windows_port_forwarding.ps1 +0 -46
  99. machineconfig/scripts/windows/wsl_ssh_windows_port_forwarding.ps1 +0 -76
  100. machineconfig/setup_linux/machineconfig.sh +0 -20
  101. machineconfig/setup_windows/machineconfig.ps1 +0 -27
  102. /machineconfig/scripts/linux/{share_nfs → other/share_nfs} +0 -0
  103. /machineconfig/scripts/linux/{share_smb → other/share_smb} +0 -0
  104. /machineconfig/scripts/linux/{start_docker → other/start_docker} +0 -0
  105. /machineconfig/scripts/linux/{switch_ip → other/switch_ip} +0 -0
  106. /machineconfig/scripts/{windows/share_nfs.ps1 → python/helpers_fire/agentic_frameworks/__init__.py} +0 -0
  107. /machineconfig/scripts/python/helpers_fire/{fire_crush.json → agentic_frameworks/fire_crush.json} +0 -0
  108. /machineconfig/scripts/python/helpers_fire/{fire_crush.py → agentic_frameworks/fire_crush.py} +0 -0
  109. /machineconfig/scripts/python/helpers_fire/{fire_cursor_agents.py → agentic_frameworks/fire_cursor_agents.py} +0 -0
  110. /machineconfig/scripts/windows/{mount_nw.ps1 → mounts/mount_nw.ps1} +0 -0
  111. /machineconfig/scripts/windows/{mount_smb.ps1 → mounts/mount_smb.ps1} +0 -0
  112. /machineconfig/scripts/windows/{share_cloud.cmd → mounts/share_cloud.cmd} +0 -0
  113. /machineconfig/scripts/windows/{share_smb.ps1 → mounts/share_smb.ps1} +0 -0
  114. /machineconfig/scripts/windows/{unlock_bitlocker.ps1 → mounts/unlock_bitlocker.ps1} +0 -0
  115. {machineconfig-5.37.dist-info → machineconfig-5.39.dist-info}/WHEEL +0 -0
  116. {machineconfig-5.37.dist-info → machineconfig-5.39.dist-info}/entry_points.txt +0 -0
  117. {machineconfig-5.37.dist-info → machineconfig-5.39.dist-info}/top_level.txt +0 -0
@@ -169,7 +169,6 @@
169
169
  # if params.session_name != "":
170
170
  # if platform.system() in ["Linux", "Darwin"]:
171
171
  # Terminal().run(f"""zellij --session {params.session_name} action new-tab --name results """)
172
- # # --layout ~/code/machineconfig/src/machineconfig/settings/zellij/layouts/d.kdl --cwd {res_folder.as_posix()}
173
172
  # Terminal().run(f"""zellij --session {params.session_name} action write-chars "cd {res_folder.as_posix()};lf" """)
174
173
  # elif platform.system() == "Windows":
175
174
  # Terminal().run(f"""wt --window {params.session_name} new-tab --title results -startingDirectory {res_folder.as_posix()} lf """)
@@ -51,12 +51,10 @@ class ProcessMonitor:
51
51
  return {"status": "unknown", "error": f"Tab '{tab_name}' not found in layout config", "running": False, "command": "", "tab_name": tab_name, "processes": [], "remote": self.remote_executor.remote_name}
52
52
 
53
53
  command = tab_config["command"]
54
-
55
54
  try:
56
55
  check_script = self._create_process_check_script(command)
57
- remote_cmd = f"$HOME/code/machineconfig/.venv/bin/python -c {shlex.quote(check_script)}"
56
+ remote_cmd = f"$HOME/.local/bin devops self run-python -c {shlex.quote(check_script)}"
58
57
  result = self.remote_executor.run_command(remote_cmd, timeout=15)
59
-
60
58
  if result.returncode == 0:
61
59
  try:
62
60
  matching_processes = json.loads(result.stdout.strip())
@@ -145,7 +143,7 @@ if __name__ == "__main__":
145
143
  check_timestamp = timestamp_result.stdout.strip() if timestamp_result.returncode == 0 else "unknown"
146
144
 
147
145
  check_script = self._create_fresh_check_script(command)
148
- remote_cmd = f"$HOME/code/machineconfig/.venv/bin/python -c {shlex.quote(check_script)}"
146
+ remote_cmd = f"$HOME/.local/bin/devops self run-python -c {shlex.quote(check_script)}"
149
147
  result = self.remote_executor.run_command(remote_cmd, timeout=15)
150
148
 
151
149
  if result.returncode == 0:
@@ -1,9 +1,9 @@
1
1
 
2
2
  import platform
3
- from machineconfig.utils.source_of_truth import LIBRARY_ROOT
3
+ from machineconfig.utils.source_of_truth import CONFIG_ROOT
4
4
 
5
5
 
6
- APP_SUMMARY_PATH = LIBRARY_ROOT.joinpath(f"profile/records/{platform.system().lower()}/apps_summary_report.csv")
6
+ APP_SUMMARY_PATH = CONFIG_ROOT.joinpath(f"profile/records/{platform.system().lower()}/apps_summary_report.csv")
7
7
  # CLOUD: str = "gdw" # Read.ini(DEFAULTS_PATH)['general']['rclone_config_name']
8
8
  # # my onedrive doesn't allow sharing.
9
9
 
@@ -25,14 +25,14 @@ nerd_fonts: InstallerData = {
25
25
  "doc": "Nerd Fonts is a project that patches developer targeted fonts with a high number of glyphs (icons)",
26
26
  "fileNamePattern": {
27
27
  "amd64": {
28
- "windows": "CaskaydiaCoveNerdFontWindows.zip",
29
- "linux": "CaskaydiaCoveNerdFontLinux.zip",
30
- "macos": "CaskaydiaCoveNerdFontMac.zip",
28
+ "windows": "CascadiaCode.zip",
29
+ "linux": "CascadiaCode.zip",
30
+ "macos": "CascadiaCode.zip",
31
31
  },
32
32
  "arm64": {
33
- "windows": "CaskaydiaCoveNerdFontWindows.zip",
34
- "linux": "CaskaydiaCoveNerdFontLinux.zip",
35
- "macos": "CaskaydiaCoveNerdFontMac.zip",
33
+ "windows": "CascadiaCode.zip",
34
+ "linux": "CascadiaCode.zip",
35
+ "macos": "CascadiaCode.zip",
36
36
  }
37
37
  }
38
38
  }
@@ -40,10 +40,10 @@ nerd_fonts: InstallerData = {
40
40
 
41
41
  # Patterns to match any installed variant (NF, Nerd Font, Mono, Propo, style weights) of Cascadia/Caskaydia
42
42
  # We'll compile them at runtime for flexibility. Keep them simple to avoid false positives.
43
- REQUIRED_FONT_PATTERNS: tuple[str, ...] = (
44
- r"caskaydiacove.*(nf|nerd ?font)",
45
- r"cascadiacode.*(nf|nerd ?font)"
46
- )
43
+ # REQUIRED_FONT_PATTERNS: tuple[str, ...] = (
44
+ # r"caskaydiacove.*(nf|nerd ?font)",
45
+ # r"cascadiacode.*(nf|nerd ?font)"
46
+ # )
47
47
 
48
48
 
49
49
  console = Console()
@@ -92,7 +92,7 @@ def _missing_required_fonts(installed_fonts: Iterable[str]) -> list[str]:
92
92
 
93
93
  installed_norm = [f.lower().replace(" ", "") for f in installed_fonts]
94
94
  missing: list[str] = []
95
- for pattern in REQUIRED_FONT_PATTERNS:
95
+ for pattern in ["cascadiacode*"]:
96
96
  regex = re.compile(pattern)
97
97
  if not any(regex.search(f) for f in installed_norm):
98
98
  missing.append(pattern)
@@ -136,7 +136,7 @@ def install_nerd_fonts() -> None:
136
136
  file = PathExtended.tmpfile(suffix=".ps1")
137
137
  file.parent.mkdir(parents=True, exist_ok=True)
138
138
 
139
- raw_content = LIBRARY_ROOT.joinpath("setup_windows/wt_and_pwsh/install_fonts.ps1").read_text(encoding="utf-8").replace(r".\fonts-to-be-installed", str(folder))
139
+ raw_content = LIBRARY_ROOT.joinpath("jobs/installer/pwsh_scripts/install_fonts.ps1").read_text(encoding="utf-8").replace(r".\fonts-to-be-installed", str(folder))
140
140
  # PowerShell 5.1 can choke on certain unicode chars in some locales; keep ASCII only.
141
141
  content = "".join(ch for ch in raw_content if ord(ch) < 128)
142
142
  file.write_text(content, encoding="utf-8")
@@ -188,6 +188,40 @@
188
188
  }
189
189
  }
190
190
  },
191
+ {
192
+ "appName": "croc",
193
+ "repoURL": "https://github.com/schollz/croc",
194
+ "doc": "🦎 Easily and securely send things from one computer to another",
195
+ "fileNamePattern": {
196
+ "amd64": {
197
+ "linux": "croc_{version}_Linux-64bit.tar.gz",
198
+ "windows": "croc_{version}_Windows-64bit.zip",
199
+ "macos": "croc_{version}_macOS-64bit.tar.gz"
200
+ },
201
+ "arm64": {
202
+ "linux": "croc_{version}_Linux-ARM64.tar.gz",
203
+ "windows": null,
204
+ "macos": "croc_{version}_macOS-ARM64.tar.gz"
205
+ }
206
+ }
207
+ },
208
+ {
209
+ "appName": "wormhole-rs",
210
+ "repoURL": "https://github.com/magic-wormhole/magic-wormhole.rs",
211
+ "doc": "🐛 Get things from one computer to another, safely (Rust implementation)",
212
+ "fileNamePattern": {
213
+ "amd64": {
214
+ "linux": "magic-wormhole-cli-x86_64-unknown-linux-gnu.tgz",
215
+ "windows": "magic-wormhole-cli-x86_64-pc-windows-gnu.tgz",
216
+ "macos": "magic-wormhole-cli-aarch64-apple-darwin.tgz"
217
+ },
218
+ "arm64": {
219
+ "linux": null,
220
+ "windows": null,
221
+ "macos": null
222
+ }
223
+ }
224
+ },
191
225
  {
192
226
  "appName": "easy-sharing",
193
227
  "repoURL": "CMD",
@@ -1328,9 +1362,9 @@
1328
1362
  }
1329
1363
  },
1330
1364
  {
1331
- "appName": "bitwarden",
1365
+ "appName": "bw",
1332
1366
  "repoURL": "CMD",
1333
- "doc": "🔐 bw is a password manager.",
1367
+ "doc": "🔐 bitwarden is a password manager.",
1334
1368
  "fileNamePattern": {
1335
1369
  "amd64": {
1336
1370
  "linux": "npm install -g @bitwarden/cli",
@@ -1752,6 +1786,23 @@
1752
1786
  }
1753
1787
  }
1754
1788
  },
1789
+ {
1790
+ "appName": "docker",
1791
+ "repoURL": "CMD",
1792
+ "doc": "🐳 Docker is an open platform for developing, shipping, and running applications.",
1793
+ "fileNamePattern": {
1794
+ "amd64": {
1795
+ "linux": "docker.sh",
1796
+ "macos": "docker.sh",
1797
+ "windows": null
1798
+ },
1799
+ "arm64": {
1800
+ "linux": "docker.sh",
1801
+ "macos": "docker.sh",
1802
+ "windows": null
1803
+ }
1804
+ }
1805
+ },
1755
1806
  {
1756
1807
  "appName": "lazydocker",
1757
1808
  "repoURL": "https://github.com/jesseduffield/lazydocker",
@@ -5,9 +5,7 @@
5
5
  # winget install Microsoft.VC++2015-2022Redist-x86
6
6
 
7
7
 
8
- . "$env:USERPROFILE\code\machineconfig\.venv\Scripts\Activate.ps1"
9
- Set-Location C:
10
- python -m pip install --global-option=build_ext --global-option="-IC:\Program Files\Graphviz\include" --global-option="-LC:\Program Files\Graphviz\lib" pygraphviz
8
+ uv pip install --global-option=build_ext --global-option="-IC:\Program Files\Graphviz\include" --global-option="-LC:\Program Files\Graphviz\lib" pygraphviz
11
9
  # not including the options as above (from https://pygraphviz.github.io/documentation/stable/install.html)
12
10
  # would result in an error like this: pygraphviz/graphviz_wrap.c(2711): fatal error C1083: Cannot open include file: 'graphviz/cgraph.h': No such file or directory
13
11
 
@@ -0,0 +1,26 @@
1
+
2
+ from typing import Literal
3
+ from machineconfig.utils.source_of_truth import LIBRARY_ROOT, CONFIG_ROOT
4
+
5
+
6
+ def copy_assets_to_machine(which: Literal["scripts", "settings"]):
7
+ # callers, symlink public, shell profile adder (requires init.ps1 and scripts dir to be present on machine)
8
+ import platform
9
+ if platform.system().lower() == "windows":
10
+ system = "windows"
11
+ elif platform.system().lower() == "linux" or platform.system().lower() == "darwin":
12
+ system = "linux"
13
+ else:
14
+ raise NotImplementedError(f"System {platform.system().lower()} not supported")
15
+ match which:
16
+ case "scripts":
17
+ source = LIBRARY_ROOT.joinpath("scripts", system)
18
+ target = CONFIG_ROOT.joinpath("scripts", system)
19
+ case "settings":
20
+ source = LIBRARY_ROOT.joinpath("settings", system)
21
+ target = CONFIG_ROOT.joinpath("settings", system)
22
+ from machineconfig.utils.path_extended import PathExtended
23
+ PathExtended(source).copy(folder=target.parent)
24
+ PathExtended(source).copy(folder=target.parent)
25
+
26
+
@@ -13,7 +13,7 @@ from rich.table import Table
13
13
 
14
14
  from machineconfig.utils.path_extended import PathExtended
15
15
  from machineconfig.utils.links import symlink_map, copy_map
16
- from machineconfig.utils.source_of_truth import LIBRARY_ROOT, CONFIG_PATH
16
+ from machineconfig.utils.source_of_truth import LIBRARY_ROOT, CONFIG_ROOT
17
17
 
18
18
  import platform
19
19
  import subprocess
@@ -63,7 +63,7 @@ def read_mapper() -> MapperFileData:
63
63
  "contents": file_base.get("contents"),
64
64
  "copy": file_base.get("copy"),
65
65
  }
66
- if "LIBRARY_ROOT" in file_map["self_managed_config_file_path"]:
66
+ if "CONFIG_ROOT" in file_map["self_managed_config_file_path"]:
67
67
  if program_key not in public:
68
68
  public[program_key] = []
69
69
  public[program_key].append(file_map)
@@ -107,7 +107,7 @@ def apply_mapper(mapper_data: dict[str, list[ConfigMapper]],
107
107
  console.rule(f"🔄 Processing [bold]{program_name}[/] symlinks", style="cyan")
108
108
  for a_mapper in program_files:
109
109
  config_file_default_path = PathExtended(a_mapper["config_file_default_path"])
110
- self_managed_config_file_path = PathExtended(a_mapper["self_managed_config_file_path"].replace("LIBRARY_ROOT", LIBRARY_ROOT.as_posix()))
110
+ self_managed_config_file_path = PathExtended(a_mapper["self_managed_config_file_path"].replace("CONFIG_ROOT", CONFIG_ROOT.as_posix()))
111
111
 
112
112
  # Determine whether to use copy or symlink
113
113
  use_copy = method == "copy" or a_mapper.get("copy", False)
@@ -215,7 +215,7 @@ def apply_mapper(mapper_data: dict[str, list[ConfigMapper]],
215
215
 
216
216
  if system == "Linux":
217
217
  console.print("\n[bold]📜 Setting executable permissions for scripts...[/bold]")
218
- subprocess.run(f"chmod +x {LIBRARY_ROOT.joinpath(f'scripts/{system.lower()}')} -R", shell=True, capture_output=True, text=True)
218
+ subprocess.run(f"chmod +x {CONFIG_ROOT.joinpath(f'scripts/{system.lower()}')} -R", shell=True, capture_output=True, text=True)
219
219
  console.print("[green]✅ Script permissions updated[/green]")
220
220
 
221
221
  # Display operation summary table
@@ -250,8 +250,8 @@ def apply_mapper(mapper_data: dict[str, list[ConfigMapper]],
250
250
  # Export operation records to CSV
251
251
  import csv
252
252
  from datetime import datetime
253
-
254
- csv_dir = PathExtended(CONFIG_PATH).joinpath("symlink_operations")
253
+
254
+ csv_dir = PathExtended(CONFIG_ROOT).joinpath("symlink_operations")
255
255
  csv_dir.mkdir(parents=True, exist_ok=True)
256
256
 
257
257
  timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
@@ -1,7 +1,6 @@
1
1
 
2
2
  import typer
3
3
  from typing import Optional, Literal
4
- from pathlib import Path
5
4
 
6
5
 
7
6
  def main_public_from_parser(method: Literal["symlink", "copy"] = typer.Option(..., help="Method to use for setting up the config file."),
@@ -12,12 +11,7 @@ def main_public_from_parser(method: Literal["symlink", "copy"] = typer.Option(..
12
11
  SOURCE = Self-Managed-Config-File-Path
13
12
  TARGET = Config-File-Default-Path
14
13
  For public config files, the source always exists, because we know it comes from machineconfig repo."""
15
- from machineconfig.profile.create import ConfigMapper, read_mapper
16
- if method == "symlink":
17
- machineconfig_repo_path = Path.home().joinpath("code/machineconfig")
18
- if not machineconfig_repo_path.exists() or not machineconfig_repo_path.is_dir():
19
- raise FileNotFoundError(f"machineconfig repo not found at {machineconfig_repo_path}. Cannot create symlinks to non-existing source files.")
20
-
14
+ from machineconfig.profile.create_links import ConfigMapper, read_mapper
21
15
  mapper_full = read_mapper()["public"]
22
16
  if which is None:
23
17
  assert interactive is True
@@ -31,7 +25,9 @@ def main_public_from_parser(method: Literal["symlink", "copy"] = typer.Option(..
31
25
  items_chosen = which.split(",")
32
26
  items_objections: dict[str, list[ConfigMapper]] = {item: mapper_full[item] for item in items_chosen if item in mapper_full}
33
27
 
34
- from machineconfig.profile.create import apply_mapper
28
+ from machineconfig.profile.create_links import apply_mapper
29
+ from machineconfig.profile.create_helper import copy_assets_to_machine
30
+ copy_assets_to_machine(which="settings") # config files live here and will be linked to.
35
31
  apply_mapper(mapper_data=items_objections, on_conflict=on_conflict, method=method)
36
32
 
37
33
 
@@ -39,7 +35,7 @@ def main_private_from_parser(method: Literal["symlink", "copy"] = typer.Option(.
39
35
  on_conflict: Literal["throwError", "overwriteSelfManaged", "backupSelfManaged", "overwriteDefaultPath", "backupDefaultPath"] = typer.Option("throwError", help="Action to take on conflict"),
40
36
  which: Optional[str] = typer.Option(None, help="Specific items to process"),
41
37
  interactive: bool = typer.Option(False, help="Run in interactive mode")):
42
- from machineconfig.profile.create import ConfigMapper, read_mapper
38
+ from machineconfig.profile.create_links import ConfigMapper, read_mapper
43
39
 
44
40
  mapper_full = read_mapper()["private"]
45
41
  if which is None:
@@ -54,5 +50,5 @@ def main_private_from_parser(method: Literal["symlink", "copy"] = typer.Option(.
54
50
  items_chosen = which.split(",")
55
51
  items_objections: dict[str, list[ConfigMapper]] = {item: mapper_full[item] for item in items_chosen if item in mapper_full}
56
52
 
57
- from machineconfig.profile.create import apply_mapper
53
+ from machineconfig.profile.create_links import apply_mapper
58
54
  apply_mapper(mapper_data=items_objections, on_conflict=on_conflict, method=method)
@@ -1,8 +1,7 @@
1
1
  """shell"""
2
2
 
3
- from typing import Literal
4
3
  from machineconfig.utils.path_extended import PathExtended
5
- from machineconfig.utils.source_of_truth import LIBRARY_ROOT, CONFIG_PATH
4
+ from machineconfig.utils.source_of_truth import CONFIG_ROOT
6
5
 
7
6
  import platform
8
7
  import os
@@ -36,51 +35,27 @@ def get_shell_profile_path() -> PathExtended:
36
35
  return profile_path
37
36
 
38
37
 
39
- def create_default_shell_profile(method: Literal["copy", "reference"]) -> None:
40
- if method == "reference":
41
- machineconfig_repo_path = PathExtended.home().joinpath("code/machineconfig")
42
- if not machineconfig_repo_path.exists() or not machineconfig_repo_path.is_dir():
43
- raise FileNotFoundError(f"machineconfig repo not found at {machineconfig_repo_path}. Cannot create symlinks to non-existing source files.")
44
-
38
+ def create_default_shell_profile() -> None:
45
39
  shell_profile_path = get_shell_profile_path()
46
40
  shell_profile = shell_profile_path.read_text(encoding="utf-8")
47
41
 
48
- if system == "Windows":
49
- init_script = PathExtended(LIBRARY_ROOT).joinpath("settings/shells/pwsh/init.ps1")
50
-
51
- init_script_copy_path = PathExtended(CONFIG_PATH).joinpath("profile/init.ps1").collapseuser()
52
- init_script_copy_path.parent.mkdir(parents=True, exist_ok=True)
53
- init_script.copy(path=init_script_copy_path, overwrite=True)
42
+ from machineconfig.profile.create_helper import copy_assets_to_machine
43
+ copy_assets_to_machine("settings") # init.ps1 or init.sh live here
44
+ copy_assets_to_machine("scripts") # init scripts are going to reference those scripts.
54
45
 
55
- source_using_copy = f""". {str(init_script_copy_path).replace("~", "$HOME")}"""
56
- source_using_reference = f""". {str(init_script.collapseuser()).replace("~", "$HOME")}"""
46
+ if system == "Windows":
47
+ init_script = PathExtended(CONFIG_ROOT).joinpath("settings/shells/pwsh/init.ps1")
48
+ source_line = f""". {str(init_script.collapseuser()).replace("~", "$HOME")}"""
57
49
  else:
58
- init_script = PathExtended(LIBRARY_ROOT).joinpath("settings/shells/bash/init.sh")
59
- init_script_copy_path = PathExtended(CONFIG_PATH).joinpath("profile/init.sh").collapseuser()
60
- init_script_copy_path.parent.mkdir(parents=True, exist_ok=True)
61
- init_script.copy(path=init_script_copy_path, overwrite=True)
62
-
63
- source_using_reference = f"""source {str(init_script.collapseuser()).replace("~", "$HOME")}"""
64
- source_using_copy = f"""source {str(init_script_copy_path).replace("~", "$HOME")}"""
65
-
66
- match method:
67
- case "copy":
68
- line_of_interest = source_using_copy
69
- line_other = source_using_reference
70
- case "reference":
71
- line_of_interest = source_using_reference
72
- line_other = source_using_copy
50
+ init_script = PathExtended(CONFIG_ROOT).joinpath("settings/shells/bash/init.sh")
51
+ source_line = f"""source {str(init_script).replace("~", "$HOME")}"""
73
52
 
74
53
  was_shell_updated = False
75
- if line_other in shell_profile: # always remove this irrelevant line
76
- shell_profile = shell_profile.replace(line_other, "")
77
- was_shell_updated = True
78
-
79
- if line_of_interest in shell_profile:
54
+ if source_line in shell_profile:
80
55
  console.print(Panel("🔄 PROFILE | Skipping init script sourcing - already present in profile", title="[bold blue]Profile[/bold blue]", border_style="blue"))
81
56
  else:
82
57
  console.print(Panel("📝 PROFILE | Adding init script sourcing to profile", title="[bold blue]Profile[/bold blue]", border_style="blue"))
83
- shell_profile += "\n" + line_of_interest + "\n"
58
+ shell_profile += "\n" + source_line + "\n"
84
59
  if system == "Linux":
85
60
  result = subprocess.run(["cat", "/proc/version"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, check=False)
86
61
  if result.returncode == 0 and result.stdout:
@@ -1,4 +1,5 @@
1
1
  #!/bin/bash
2
+ # https://temp.sh/
2
3
  # 📤 CLOUD FILE SHARING SCRIPT 📤
3
4
  # This script uploads files or directories to transfer.sh for easy sharing
4
5
  # Usage: share_cloud <file|directory> or command | share_cloud <file_name>
@@ -14,6 +15,8 @@ if [ $# -eq 0 ]; then
14
15
  return 1
15
16
  fi
16
17
 
18
+ # https://temp.sh/
19
+
17
20
  # Process the input
18
21
  if tty -s; then
19
22
  # Direct file/directory upload mode
@@ -40,11 +40,11 @@ fi
40
40
  if [[ "${ZJ_SESSIONS}" == *"(current)"* ]]; then
41
41
  # if so, then we are in a zellijsession
42
42
  echo "already inside a session, existing."
43
- COMMANDS=$(ls $HOME/code/machineconfig/src/machineconfig/settings/zellij/commands)
43
+ COMMANDS=$(ls $HOME/.config/machineconfig/settings/zellij/commands)
44
44
  # fzf the results
45
45
  res="$(echo -e "${COMMANDS}" | fzf --ansi)"
46
46
  # run the bash fiZJ_SESSIONSle chosen
47
- bash $HOME/code/machineconfig/src/machineconfig/settings/zellij/commands/$res
47
+ bash $HOME/.config/machineconfig/settings/zellij/commands/$res
48
48
 
49
49
  else # ==> we are not in a zellijsession
50
50
  if [ "${NO_SESSIONS}" -ge 1 ]; then # sessions do exist
@@ -103,7 +103,6 @@ def create(
103
103
  layoutfile = get_agents_launch_layout(session_root=agents_dir)
104
104
  regenerate_py_code = f"""
105
105
  #!/usr/bin/env uv run --python 3.13 --with machineconfig
106
- #!/usr/bin/env uv run --no-dev --project $HOME/code/machineconfig
107
106
  fire_agents create --context-path "{prompt_material_path}" \\
108
107
  --{search_strategy} "{context_path or keyword_search or filename_pattern}" \\
109
108
  --prompt-path "{prompt_path or ''}" \\
@@ -23,12 +23,11 @@ uv init --python 3.13
23
23
  uv venv
24
24
  uv add --upgrade-package pylint pyright mypy pyrefly ty --dev # linters and type checkers
25
25
  uv add --upgrade-package pytest --dev
26
- # uv add typer --dev
26
+ uv add typer --dev
27
27
 
28
28
  """
29
- import subprocess
30
-
31
- subprocess.run(command_to_run, shell=True, check=True)
29
+ from machineconfig.utils.code import run_shell_script
30
+ run_shell_script(command_to_run)
32
31
  else:
33
32
  print("Terminating initai ...")
34
33
  return
@@ -66,7 +66,6 @@ uv run -m cleanpy .
66
66
  uv run -m ruff clean
67
67
  # uv run -m ruff format .
68
68
  uv run -m ruff check . --fix
69
- uv run --no-dev --project $HOME/code/machineconfig -m machineconfig.scripts.python.ai.generate_files
70
69
 
71
70
  New-Item -ItemType Directory -Force -Path .ai/linters | Out-Null
72
71
 
@@ -70,7 +70,6 @@ uv run -m cleanpy .
70
70
  uv run -m ruff clean
71
71
  # uv run -m ruff format .
72
72
  uv run -m ruff check . --fix
73
- uv run --no-dev --project $HOME/code/machineconfig -m machineconfig.scripts.python.ai.generate_files
74
73
 
75
74
  mkdir .ai/linters
76
75
 
@@ -46,6 +46,7 @@ def adjust_gitignore(repo_root: Path) -> None:
46
46
  ".ai",
47
47
  "GEMINI.md",
48
48
  "CLAUDE.md",
49
+ "CRUSH.md",
49
50
  ".cursor",
50
51
  ".github/instructions",
51
52
  ".github/chatmodes",
@@ -46,6 +46,7 @@ console = Console()
46
46
  p = PathExtended(r'{path}').absolute()
47
47
  try:
48
48
  from machineconfig.utils.files.read import Read
49
+ from machineconfig.utils.accessories import pprint
49
50
  dat = Read.read(p)
50
51
  if isinstance(dat, dict):
51
52
  panel_title = f"📄 File Data: {{p.name}}"
@@ -64,12 +65,12 @@ except Exception as e:
64
65
  def main(
65
66
  python: Annotated[bool, typer.Option("--python", "-p", help="flag to use python over IPython.")] = False,
66
67
  fzf: Annotated[bool, typer.Option("--fzf", "-F", help="search with fuzzy finder for python scripts and run them")] = False,
67
- ve: Annotated[Optional[str], typer.Option("--ve", "-v", help="virtual enviroment to use, defaults to activated ve, if existed, else ve.")] = None,
68
68
  profile: Annotated[Optional[str], typer.Option("--profile", "-P", help="ipython profile to use, defaults to default profile.")] = None,
69
69
  read: Annotated[str, typer.Option("--read", "-r", help="read a binary file.")] = "",
70
70
  jupyter: Annotated[bool, typer.Option("--jupyter", "-j", help="run in jupyter interactive console")] = False,
71
71
  streamlit_viewer: Annotated[bool, typer.Option("--stViewer", "-s", help="view in streamlit app")] = False,
72
72
  visidata: Annotated[bool, typer.Option("--visidata", "-V", help="open data file in visidata")] = False,
73
+ local: Annotated[bool, typer.Option("--local", "-l", help="run in local mode, not in virtual env.")]= False,
73
74
  ) -> None:
74
75
  # ==================================================================================
75
76
  # flags processing
@@ -141,7 +142,16 @@ from pathlib import Path
141
142
  else:
142
143
  if interpreter == "ipython": profile = f" --profile {ipython_profile} --no-banner"
143
144
  else: profile = ""
144
- fire_line = f"uv run --python 3.13 --with machineconfig[plot] {interpreter} {interactivity} {profile} {str(pyfile)}"
145
+ if local:
146
+ from machineconfig.utils.source_of_truth import LIBRARY_ROOT
147
+ repo_root = LIBRARY_ROOT.parent.parent
148
+ if repo_root.parent.name == "code" and repo_root.name == "machineconfig" and repo_root.exists() and repo_root.is_dir():
149
+ ve_line = f"--project {str(repo_root)}"
150
+ else:
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
+ return
153
+ else: ve_line = "--with machineconfig[plot]"
154
+ fire_line = f"uv run --python 3.13 {ve_line} {interpreter} {interactivity} {profile} {str(pyfile)}"
145
155
 
146
156
  from machineconfig.utils.code import run_shell_script
147
157
  run_shell_script(fire_line, clean_env=False)
@@ -2,7 +2,7 @@
2
2
  slidev
3
3
  """
4
4
 
5
- from machineconfig.utils.source_of_truth import CONFIG_PATH
5
+ from machineconfig.utils.source_of_truth import CONFIG_ROOT
6
6
  from machineconfig.utils.code import print_code
7
7
  from machineconfig.utils.path_extended import PathExtended
8
8
  from machineconfig.utils.terminal import Response
@@ -13,7 +13,7 @@ import platform
13
13
 
14
14
  PORT_DEFAULT = 3030
15
15
 
16
- SLIDEV_REPO = PathExtended(CONFIG_PATH).joinpath(".cache/slidev")
16
+ SLIDEV_REPO = PathExtended(CONFIG_ROOT).joinpath(".cache/slidev")
17
17
  if not SLIDEV_REPO.joinpath("components").exists():
18
18
  print("📦 Initializing Slidev repository...")
19
19
  subprocess.run(f"cd {SLIDEV_REPO.parent};npm init slidev@latest", check=False, shell=True, text=True)
@@ -5,7 +5,7 @@ from typing import Optional
5
5
 
6
6
  import machineconfig.scripts.python.devops_helpers.cli_repos as cli_repos
7
7
  import machineconfig.scripts.python.devops_helpers.cli_config as cli_config
8
- from machineconfig.scripts.python.devops_helpers.cli_self import self_app
8
+ import machineconfig.scripts.python.devops_helpers.cli_self as cli_self
9
9
  import machineconfig.scripts.python.devops_helpers.cli_data as cli_data
10
10
  import machineconfig.scripts.python.devops_helpers.cli_nw as cli_network
11
11
 
@@ -21,29 +21,12 @@ def install( which: Optional[str] = typer.Option(None, "--which", "-w", help="Co
21
21
  installer_entry_point.main(which=which, group=group, interactive=interactive)
22
22
 
23
23
 
24
- app.add_typer(cli_repos.app, name="repos", help="📁 Manage git repositories")
24
+ app.add_typer(cli_repos.app, name="repos")
25
25
  app.add_typer(cli_config.config_apps, name="config")
26
26
  app.add_typer(cli_data.app_data, name="data")
27
- app.add_typer(self_app, name="self")
27
+ app.add_typer(cli_self.cli_app, name="self")
28
28
  app.add_typer(cli_network.nw_apps, name="network")
29
29
 
30
30
 
31
-
32
-
33
- # @app.command()
34
- # def scheduler():
35
- # """⏰ SCHEDULER"""
36
- # # from machineconfig.scripts.python.scheduler import main as helper
37
- # # helper()
38
-
39
-
40
-
41
- # @app.command()
42
- # def scheduler():
43
- # """⏰ SCHEDULER"""
44
- # # from machineconfig.scripts.python.scheduler import main as helper
45
- # # helper()
46
-
47
-
48
31
  if __name__ == "__main__":
49
- pass
32
+ app()
@@ -13,8 +13,8 @@ def private(method: Literal["symlink", "copy"] = typer.Option(..., "--method", "
13
13
  which: Optional[str] = typer.Option(None, "--which", "-w", help="Specific items to process"),
14
14
  interactive: bool = typer.Option(False, "--interactive", "-ia", help="Run in interactive mode")):
15
15
  """🔗 Manage private configuration files."""
16
- import machineconfig.profile.create_frontend as create_frontend
17
- create_frontend.main_private_from_parser(method=method, on_conflict=on_conflict, which=which, interactive=interactive)
16
+ import machineconfig.profile.create_links_export as create_links_export
17
+ create_links_export.main_private_from_parser(method=method, on_conflict=on_conflict, which=which, interactive=interactive)
18
18
 
19
19
  @config_apps.command(no_args_is_help=True)
20
20
  def public(method: Literal["symlink", "copy"] = typer.Option(..., "--method", "-m", help="Method to use for setting up the config file."),
@@ -22,8 +22,8 @@ def public(method: Literal["symlink", "copy"] = typer.Option(..., "--method", "-
22
22
  which: Optional[str] = typer.Option(None, "--which", "-w", help="Specific items to process"),
23
23
  interactive: bool = typer.Option(False, "--interactive", "-ia", help="Run in interactive mode")):
24
24
  """🔗 Manage public configuration files."""
25
- import machineconfig.profile.create_frontend as create_frontend
26
- create_frontend.main_public_from_parser(method=method, on_conflict=on_conflict, which=which, interactive=interactive)
25
+ import machineconfig.profile.create_links_export as create_links_export
26
+ create_links_export.main_public_from_parser(method=method, on_conflict=on_conflict, which=which, interactive=interactive)
27
27
 
28
28
  @config_apps.command(no_args_is_help=True)
29
29
  def dotfile(file: Annotated[str, typer.Argument(help="file/folder path.")],
@@ -35,11 +35,11 @@ def dotfile(file: Annotated[str, typer.Argument(help="file/folder path.")],
35
35
  dotfile_module.main(file=file, overwrite=overwrite, dest=dest)
36
36
 
37
37
 
38
- @config_apps.command(no_args_is_help=True)
39
- def shell(method: Annotated[Literal["copy", "reference"], typer.Argument(help="Choose the method to configure the shell profile: 'copy' copies the init script directly, 'reference' references machineconfig for dynamic updates.")]):
38
+ @config_apps.command(no_args_is_help=False)
39
+ def shell():
40
40
  """🔗 Configure your shell profile."""
41
- from machineconfig.profile.shell import create_default_shell_profile
42
- create_default_shell_profile(method=method)
41
+ from machineconfig.profile.create_shell_profile import create_default_shell_profile
42
+ create_default_shell_profile()
43
43
 
44
44
 
45
45
  @config_apps.command(no_args_is_help=False)
@@ -23,7 +23,7 @@ def main(
23
23
 
24
24
  from machineconfig.utils.links import symlink_map
25
25
  from machineconfig.utils.path_extended import PathExtended
26
- from machineconfig.utils.source_of_truth import LIBRARY_ROOT, REPO_ROOT
26
+ from machineconfig.utils.source_of_truth import CONFIG_ROOT
27
27
  console = Console()
28
28
  orig_path = PathExtended(file).expanduser().absolute()
29
29
  if dest == "":
@@ -35,7 +35,7 @@ def main(
35
35
  junction = orig_path.split(at=".config", sep=-1)[1]
36
36
  else:
37
37
  junction = orig_path.rel2home()
38
- new_path = PathExtended(REPO_ROOT).joinpath(junction)
38
+ new_path = PathExtended(CONFIG_ROOT).parent.parent.joinpath(junction)
39
39
  else:
40
40
  dest_path = PathExtended(dest).expanduser().absolute()
41
41
  dest_path.mkdir(parents=True, exist_ok=True)
@@ -59,7 +59,7 @@ def main(
59
59
 
60
60
  mapper_snippet = "\n".join(
61
61
  [
62
- f"[bold]📝 Edit configuration file:[/] [cyan]nano {PathExtended(LIBRARY_ROOT)}/symlinks/mapper.toml[/cyan]",
62
+ f"[bold]📝 Edit configuration file:[/] [cyan]nano {PathExtended(CONFIG_ROOT)}/symlinks/mapper.toml[/cyan]",
63
63
  "",
64
64
  f"[{new_path.parent.name}]",
65
65
  f"{orig_path.name.split('.')[0]} = {{ this = '{orig_path.collapseuser().as_posix()}', to_this = '{new_path.collapseuser().as_posix()}' }}",