machineconfig 5.21__py3-none-any.whl → 5.23__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 (45) hide show
  1. machineconfig/cluster/sessions_managers/helpers/zellij_local_helper.py +298 -0
  2. machineconfig/cluster/sessions_managers/helpers/zellij_local_helper_restart.py +77 -0
  3. machineconfig/cluster/sessions_managers/helpers/zellij_local_helper_with_panes.py +228 -0
  4. machineconfig/cluster/sessions_managers/helpers/zellij_local_manager_helper.py +165 -0
  5. machineconfig/cluster/sessions_managers/wt_local.py +100 -75
  6. machineconfig/cluster/sessions_managers/wt_local_manager.py +17 -21
  7. machineconfig/cluster/sessions_managers/wt_remote.py +51 -43
  8. machineconfig/cluster/sessions_managers/wt_remote_manager.py +16 -8
  9. machineconfig/cluster/sessions_managers/wt_utils/layout_generator.py +6 -19
  10. machineconfig/cluster/sessions_managers/zellij_local.py +79 -371
  11. machineconfig/cluster/sessions_managers/zellij_local_manager.py +20 -168
  12. machineconfig/cluster/sessions_managers/zellij_remote.py +38 -39
  13. machineconfig/cluster/sessions_managers/zellij_remote_manager.py +13 -10
  14. machineconfig/cluster/sessions_managers/zellij_utils/example_usage.py +4 -1
  15. machineconfig/cluster/sessions_managers/zellij_utils/layout_generator.py +5 -20
  16. machineconfig/profile/shell.py +1 -1
  17. machineconfig/scripts/python/ai/scripts/lint_and_type_check.ps1 +17 -17
  18. machineconfig/scripts/python/ai/scripts/lint_and_type_check.sh +17 -17
  19. machineconfig/scripts/python/ai/solutions/copilot/instructions/python/dev.instructions.md +1 -1
  20. machineconfig/scripts/python/ai/solutions/copilot/prompts/pyright_fix.md +16 -0
  21. machineconfig/scripts/python/ai/solutions/generic.py +15 -4
  22. machineconfig/scripts/python/cloud_repo_sync.py +26 -25
  23. machineconfig/scripts/python/count_lines.py +6 -6
  24. machineconfig/scripts/python/croshell.py +2 -4
  25. machineconfig/scripts/python/devops.py +7 -2
  26. machineconfig/scripts/python/devops_status.py +521 -0
  27. machineconfig/scripts/python/devops_update_repos.py +1 -1
  28. machineconfig/scripts/python/fire_agents_help_launch.py +6 -1
  29. machineconfig/scripts/python/fire_jobs_args_helper.py +4 -1
  30. machineconfig/scripts/python/helpers/repo_sync_helpers.py +0 -43
  31. machineconfig/scripts/python/onetimeshare.py +0 -1
  32. machineconfig/scripts/windows/share_smb.ps1 +0 -6
  33. machineconfig/setup_linux/repos.sh +1 -29
  34. machineconfig/setup_windows/repos.ps1 +0 -12
  35. machineconfig/utils/files/read.py +4 -6
  36. machineconfig/utils/notifications.py +1 -1
  37. machineconfig/utils/source_of_truth.py +1 -1
  38. machineconfig/utils/ssh.py +2 -13
  39. {machineconfig-5.21.dist-info → machineconfig-5.23.dist-info}/METADATA +1 -1
  40. {machineconfig-5.21.dist-info → machineconfig-5.23.dist-info}/RECORD +43 -39
  41. machineconfig/cluster/sessions_managers/ffile.py +0 -4
  42. machineconfig/scripts/python/ai/solutions/copilot/prompts/allLintersAndTypeCheckers.prompt.md +0 -5
  43. {machineconfig-5.21.dist-info → machineconfig-5.23.dist-info}/WHEEL +0 -0
  44. {machineconfig-5.21.dist-info → machineconfig-5.23.dist-info}/entry_points.txt +0 -0
  45. {machineconfig-5.21.dist-info → machineconfig-5.23.dist-info}/top_level.txt +0 -0
@@ -72,7 +72,7 @@ uv run -m ruff clean
72
72
  uv run -m ruff check . --fix
73
73
  uv run --no-dev --project $HOME/code/machineconfig -m machineconfig.scripts.python.ai.generate_files
74
74
 
75
- mkdir .linters
75
+ mkdir .ai/linters
76
76
 
77
77
  echo -e "${GREEN}🧹 Code cleanup complete!${NC}"
78
78
  echo
@@ -82,38 +82,38 @@ draw_box "🔍 TYPE CHECKERS & LINTERS 🔍" "${BOLD}${PURPLE}"
82
82
  ((CURRENT_STEP++))
83
83
  draw_progress $CURRENT_STEP $TOTAL_STEPS "Pyright Type Checker"
84
84
  echo -e "${BLUE}📋 Analyzing types with Pyright...${NC}"
85
- rm ./.linters/pyright_result.md || true
86
- uv run pyright . > ./.linters/pyright_result.md
87
- echo -e "${GREEN}✅ Results saved to ${UNDERLINE}./.linters/pyright_result.md${NC}"
85
+ rm ./.ai/linters/issues_pyright.md || true
86
+ uv run pyright . > ./.ai/linters/issues_pyright.md
87
+ echo -e "${GREEN}✅ Results saved to ${UNDERLINE}./.ai/linters/issues_pyright.md${NC}"
88
88
 
89
89
  ((CURRENT_STEP++))
90
90
  draw_progress $CURRENT_STEP $TOTAL_STEPS "MyPy Type Checker"
91
91
  echo -e "${BLUE}📋 Analyzing types with MyPy...${NC}"
92
- rm ./.linters/mypy_result.md || true
93
- uv run mypy . > ./.linters/mypy_result.md
94
- echo -e "${GREEN}✅ Results saved to ${UNDERLINE}./.linters/mypy_result.md${NC}"
92
+ rm ./.ai/linters/issues_mypy.md || true
93
+ uv run mypy . > ./.ai/linters/issues_mypy.md
94
+ echo -e "${GREEN}✅ Results saved to ${UNDERLINE}./.ai/linters/issues_mypy.md${NC}"
95
95
 
96
96
  ((CURRENT_STEP++))
97
97
  draw_progress $CURRENT_STEP $TOTAL_STEPS "Pylint Code Analysis"
98
98
  echo -e "${BLUE}📋 Analyzing code quality with Pylint...${NC}"
99
- rm ./.linters/pylint_result.md || true
100
- uv run pylint ./src/ > ./.linters/pylint_result.md
101
- echo -e "${GREEN}✅ Results saved to ${UNDERLINE}./.linters/pylint_result.md${NC}"
99
+ rm ./.ai/linters/issues_pylint.md || true
100
+ uv run pylint ./src/ > ./.ai/linters/issues_pylint.md
101
+ echo -e "${GREEN}✅ Results saved to ${UNDERLINE}./.ai/linters/issues_pylint.md${NC}"
102
102
 
103
103
  ((CURRENT_STEP++))
104
104
  draw_progress $CURRENT_STEP $TOTAL_STEPS "Pyrefly Type Checker"
105
105
  echo -e "${BLUE}📋 Analyzing types with Pyrefly...${NC}"
106
- rm ./.linters/pyrefly_result.md || true
107
- uv run pyrefly check . > ./.linters/pyrefly_result.md
108
- echo -e "${GREEN}✅ Results saved to ${UNDERLINE}./.linters/pyrefly_result.md${NC}"
106
+ rm ./.ai/linters/issues_pyrefly.md || true
107
+ uv run pyrefly check . > ./.ai/linters/issues_pyrefly.md
108
+ echo -e "${GREEN}✅ Results saved to ${UNDERLINE}./.ai/linters/issues_pyrefly.md${NC}"
109
109
 
110
110
  ((CURRENT_STEP++))
111
111
  draw_progress $CURRENT_STEP $TOTAL_STEPS "Ruff Linter"
112
112
  echo -e "${BLUE}📋 Checking code style with Ruff...${NC}"
113
- rm ./.linters/ruff_result.md || true
114
- uv run ruff check . > ./.linters/ruff_result.md
115
- echo -e "${GREEN}✅ Results saved to ${UNDERLINE}./.linters/ruff_result.md${NC}"
113
+ rm ./.ai/linters/issues_ruff.md || true
114
+ uv run ruff check . > ./.ai/linters/issues_ruff.md
115
+ echo -e "${GREEN}✅ Results saved to ${UNDERLINE}./.ai/linters/issues_ruff.md${NC}"
116
116
 
117
117
  echo
118
118
  draw_box "🎉 ALL CHECKS COMPLETED! 🎉" "${BOLD}${GREEN}"
119
- echo -e "${BOLD}${GREEN}📁 Check the ${UNDERLINE}.linters${NC}${BOLD}${GREEN} directory for detailed results.${NC}"
119
+ echo -e "${BOLD}${GREEN}📁 Check the ${UNDERLINE}.ai/linters${NC}${BOLD}${GREEN} directory for detailed results.${NC}"
@@ -34,7 +34,7 @@ applyTo: "**/*.py"
34
34
  * when finished, run a linting static analysis check against files you touched, Any fix any mistakes.
35
35
  * Please run `uv run -m pyright $file_touched` and address all issues. if `pyright is not there, first run `uv add pyright --dev`.
36
36
  * For all type checkers and linters, like mypy, pyright, pyrefly and pylint, there are config files at different levels of the repo all the way up to home directory level. You don't need to worry about them, just be mindful that they exist. The tools themselves will respect the configs therein.
37
- * If you want to run all linters and pycheckers agains the entire project to make sure everything is clean, I prepared a nice shell script, you can run it from the repo root as `./.scripts/lint_and_type_check.sh`. It will produce markdown files that are you are meant to look at @ ./.linters/*.md
37
+ * If you want to run all linters and pycheckers agains the entire project to make sure everything is clean, I prepared a nice shell script, you can run it from the repo root as `./.ai/scripts/lint_and_type_check.sh`. It will produce markdown files that are you are meant to look at @ ./.ai/linters/*.md
38
38
 
39
39
  # General Programming Ethos:
40
40
  * Make sure all the code is rigorous, no lazy stuff.
@@ -0,0 +1,16 @@
1
+ ---
2
+ mode: agent
3
+ ---
4
+
5
+
6
+ $PYRIGHT_ISSUES_FILE = "./.ai/linters/issues_pyright.md"
7
+ $NUM_TASKS = 50
8
+ please create $NUM_TASKS todo-list tasks to go through the first $NUM_TASKS
9
+ from $PYRIGHT_ISSUES_FILE, and solve them independently in each task.
10
+ When creating the tasks, try to keep issues related to one pyfile in one task, so you don't read the same file twice in different tasks.
11
+
12
+ once you solved them, you will have 2 months break from work.
13
+
14
+ Start by runing `./.ai/scripts/lint_and_type_check.sh` to generate $PYRIGHT_ISSUES_FILE only once.
15
+
16
+
@@ -1,16 +1,16 @@
1
+
1
2
  from pathlib import Path
3
+ import platform
2
4
 
3
5
  from machineconfig.utils.source_of_truth import LIBRARY_ROOT
4
6
 
5
7
 
6
8
  def create_dot_scripts(repo_root: Path) -> None:
7
9
  scripts_dir = LIBRARY_ROOT.joinpath("scripts/python/ai/scripts")
8
- target_dir = repo_root.joinpath(".scripts")
10
+ target_dir = repo_root.joinpath(".ai/scripts")
9
11
  import shutil
10
12
  shutil.rmtree(target_dir, ignore_errors=True)
11
13
  target_dir.mkdir(parents=True, exist_ok=True)
12
- # for script_path in scripts_dir.iterdir():
13
- # target_dir.joinpath(script_path.name).write_text(data=script_path.read_text(encoding="utf-8"), encoding="utf-8")
14
14
  import platform
15
15
  if platform.system() == "Windows":
16
16
  script_path = scripts_dir.joinpath("lint_and_type_check.ps1")
@@ -21,6 +21,18 @@ def create_dot_scripts(repo_root: Path) -> None:
21
21
  target_dir.joinpath(script_path.name).write_text(data=script_path.read_text(encoding="utf-8"), encoding="utf-8")
22
22
 
23
23
 
24
+ def adjust_for_os(config_path: Path) -> str:
25
+ if config_path.suffix not in [".md", ".txt"]:
26
+ return config_path.read_text(encoding="utf-8")
27
+ english_text = config_path.read_text(encoding="utf-8")
28
+ if platform.system() == "Windows":
29
+ return english_text.replace("bash", "PowerShell").replace("sh ", "pwsh ").replace("./", ".\\").replace(".sh", ".ps1")
30
+ elif platform.system() in ["Linux", "Darwin"]:
31
+ return english_text.replace("PowerShell", "bash").replace("pwsh ", "sh ").replace(".\\", "./").replace(".ps1", ".sh")
32
+ else:
33
+ raise NotImplementedError(f"Platform {platform.system()} is not supported.")
34
+
35
+
24
36
  def adjust_gitignore(repo_root: Path) -> None:
25
37
  dot_git_ignore_path = repo_root.joinpath(".gitignore")
26
38
  if dot_git_ignore_path.exists() is False:
@@ -32,7 +44,6 @@ def adjust_gitignore(repo_root: Path) -> None:
32
44
  ".links",
33
45
  "notebooks",
34
46
  ".ai",
35
- ".scripts",
36
47
  "GEMINI.md",
37
48
  "CLAUDE.md",
38
49
  ".cursor",
@@ -1,27 +1,31 @@
1
- """utils"""
2
-
3
- from pathlib import Path
4
1
  import git
2
+ from rich.console import Console
3
+ from rich.panel import Panel
4
+ import typer
5
+
5
6
  from machineconfig.utils.io import read_ini
6
7
  from machineconfig.utils.path_extended import PathExtended
7
8
  from machineconfig.utils.terminal import Response
8
-
9
- from machineconfig.scripts.python.helpers.repo_sync_helpers import fetch_dotfiles
10
9
  from machineconfig.utils.source_of_truth import CONFIG_PATH, DEFAULTS_PATH
11
10
  from machineconfig.utils.options import choose_from_options
12
11
  from machineconfig.utils.code import get_shell_file_executing_python_script, write_shell_script_to_file
12
+
13
13
  import platform
14
14
  import subprocess
15
15
  from typing import Optional, Literal
16
- from rich.console import Console
17
- from rich.panel import Panel
16
+ from pathlib import Path
17
+ import sys
18
18
 
19
19
  console = Console()
20
20
 
21
- _ = fetch_dotfiles
22
-
23
21
 
24
- def main(cloud: Optional[str] = None, path: Optional[str] = None, message: Optional[str] = None, action: Literal["ask", "pushLocalMerge", "overwriteLocal", "InspectRepos", "RemoveLocalRclone"] = "ask", pwd: Optional[str] = None):
22
+ def main(
23
+ cloud: Optional[str] = typer.Option(None, "--cloud", "-c", help="Cloud storage profile name. If not provided, uses default from config."),
24
+ path: Optional[str] = typer.Option(None, "--path", "-p", help="Path to the local repository. Defaults to current working directory."),
25
+ message: Optional[str] = typer.Option(None, "--message", "-m", help="Commit message for local changes."),
26
+ on_conflict: Literal["ask", "pushLocalMerge", "overwriteLocal", "InspectRepos", "RemoveLocalRclone"] = typer.Option("ask", "--on-conflict", "-oc", help="Action to take on merge conflict. Default is 'ask'."),
27
+ pwd: Optional[str] = typer.Option(None, "--password", help="Password for encryption/decryption of the remote repository."),
28
+ ):
25
29
  if cloud is None:
26
30
  try:
27
31
  cloud_resolved = read_ini(DEFAULTS_PATH)["general"]["rclone_config_name"]
@@ -31,8 +35,6 @@ def main(cloud: Optional[str] = None, path: Optional[str] = None, message: Optio
31
35
  return ""
32
36
  else:
33
37
  cloud_resolved = cloud
34
-
35
- # repo_root = PathExtended(args.repo).expanduser().absolute()
36
38
  repo_local_root = PathExtended.cwd() if path is None else PathExtended(path).expanduser().absolute()
37
39
  repo_local_obj = git.Repo(repo_local_root, search_parent_directories=True)
38
40
  repo_local_root = PathExtended(repo_local_obj.working_dir) # cwd might have been in a sub directory of repo_root, so its better to redefine it.
@@ -143,7 +145,7 @@ git commit -am "finished merging"
143
145
  print(f"• 4️⃣ {option4:75} 👉 {shell_file_4}")
144
146
 
145
147
  program_content = None
146
- match action:
148
+ match on_conflict:
147
149
  case "ask":
148
150
  choice = choose_from_options(multi=False, msg="Choose one option", options=[option1, option2, option3, option4], fzf=False)
149
151
  if choice == option1:
@@ -165,7 +167,7 @@ git commit -am "finished merging"
165
167
  case "RemoveLocalRclone":
166
168
  program_content = program_4
167
169
  case _:
168
- raise ValueError(f"Unknown action: {action}")
170
+ raise ValueError(f"Unknown action: {on_conflict}")
169
171
  # PROGRAM_PATH.write_text(program_content, encoding="utf-8")
170
172
  subprocess.run(program_content, shell=True, check=True)
171
173
 
@@ -173,17 +175,16 @@ git commit -am "finished merging"
173
175
 
174
176
 
175
177
  def args_parser():
176
- # console.print(Panel("🔄 Repository Synchronization Utility", title_align="left", border_style="blue"))
177
- # parser = argparse.ArgumentParser(description="Secure Repo CLI.")
178
- # parser.add_argument("path", nargs="?", type=str, help="Repository path, defaults to cwd.", default=None)
179
- # parser.add_argument("--cloud", "-c", help="rclone cloud profile name.", default=None)
180
- # parser.add_argument("--message", "-m", help="Commit Message", default=f"new message {randstr()}")
181
- # parser.add_argument("--pwd", "-p", help="Password for encryption", default=None)
182
- # parser.add_argument("--action", "-a", help="Action to take if merge fails.", choices=["ask", "pushLocalMerge", "overwriteLocal", "InspectRepos", "RemoveLocalRclone"], default="ask")
183
- # args = parser.parse_args()
184
- # main(cloud=args.cloud, path=args.path, message=args.message, action=args.action)
185
- import typer
186
- typer.run(main)
178
+ # Check if no arguments provided (excluding the script name)
179
+ if len(sys.argv) == 1:
180
+ app = typer.Typer(add_completion=False, help="Sync a local git repository with a remote encrypted cloud copy.")
181
+ app.command()(main)
182
+ app(["--help"])
183
+ return
184
+
185
+ app = typer.Typer(add_completion=False, no_args_is_help=True, help="Sync a local git repository with a remote encrypted cloud copy.")
186
+ app.command()(main)
187
+ app()
187
188
 
188
189
 
189
190
  if __name__ == "__main__":
@@ -18,12 +18,12 @@ app = typer.Typer()
18
18
 
19
19
 
20
20
  def count_lines_in_commit(commit: "Any") -> int:
21
- total_lines = 0
22
- for file in commit.stats.files:
23
- if str(file).endswith(".py"):
24
- blob = commit.tree / file
25
- total_lines += len(blob.data_stream.read().decode("utf-8").splitlines())
26
- return total_lines
21
+ _total_lines = 0
22
+ for _file in commit.stats.files:
23
+ if str(_file).endswith(".py"):
24
+ _blob = commit.tree / _file
25
+ _total_lines += len(_blob.data_stream.read().decode("utf-8").splitlines())
26
+ return _total_lines
27
27
 
28
28
 
29
29
  def count_historical_loc(repo_path: str) -> int:
@@ -20,10 +20,8 @@ console = Console()
20
20
 
21
21
  def add_print_header_pycode(path: str, title: str):
22
22
  return f"""
23
- try:
24
- from crocodile.file_management import P as PathExtended
25
- except ImportError:
26
- from machineconfig.utils.path_extended import PathExtended
23
+
24
+ from machineconfig.utils.path_extended import PathExtended
27
25
  pycode = PathExtended(r'{path}').read_text(encoding="utf-8")
28
26
  pycode = pycode.split("except Exception: print(pycode)")[2]
29
27
 
@@ -44,19 +44,24 @@ def interactive():
44
44
  @self_app.command()
45
45
  def status():
46
46
  """📊 STATUS of machine, shell profile, apps, symlinks, dotfiles, etc."""
47
- pass
47
+ import machineconfig.scripts.python.devops_status as helper
48
+ helper.main()
48
49
  @self_app.command()
49
50
  def clone():
50
- """📋 CLONE machienconfig locally for faster execution and nightly updates. """
51
+ """📋 CLONE machienconfig locally and incorporate to shell profile for faster execution and nightly updates."""
51
52
  import platform
52
53
  from machineconfig.utils.code import run_shell_script
54
+ from machineconfig.profile.shell import create_default_shell_profile
53
55
  if platform.system() == "Windows":
54
56
  from machineconfig.setup_windows import REPOS
57
+ create_default_shell_profile(method="copy")
55
58
  else:
56
59
  from machineconfig.setup_linux import REPOS
60
+ create_default_shell_profile(method="reference")
57
61
  run_shell_script(REPOS.read_text(encoding="utf-8"))
58
62
 
59
63
 
64
+
60
65
  @config_apps.command(no_args_is_help=True)
61
66
  def private(method: Literal["symlink", "copy"] = typer.Option(..., "--method", "-m", help="Method to use for linking files"),
62
67
  on_conflict: Literal["throwError", "overwriteSelfManaged", "backupSelfManaged", "overwriteDefaultPath", "backupDefaultPath"] = typer.Option("throwError", "--on-conflict", "-o", help="Action to take on conflict"),