machineconfig 7.64__py3-none-any.whl → 7.79__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 (78) hide show
  1. machineconfig/cluster/sessions_managers/utils/maker.py +4 -2
  2. machineconfig/jobs/installer/custom_dev/sysabc.py +26 -0
  3. machineconfig/jobs/installer/installer_data.json +70 -2
  4. machineconfig/profile/create_links_export.py +2 -2
  5. machineconfig/scripts/__init__.py +0 -4
  6. machineconfig/scripts/python/agents.py +22 -17
  7. machineconfig/scripts/python/ai/solutions/copilot/instructions/python/dev.instructions.md +3 -0
  8. machineconfig/scripts/python/croshell.py +22 -17
  9. machineconfig/scripts/python/devops.py +1 -1
  10. machineconfig/scripts/python/devops_navigator.py +0 -4
  11. machineconfig/scripts/python/env_manager/path_manager_tui.py +1 -1
  12. machineconfig/scripts/python/fire_jobs.py +13 -13
  13. machineconfig/scripts/python/ftpx.py +36 -12
  14. machineconfig/scripts/python/helpers/ast_search.py +74 -0
  15. machineconfig/scripts/python/helpers/qr_code.py +166 -0
  16. machineconfig/scripts/python/helpers/repo_rag.py +325 -0
  17. machineconfig/scripts/python/helpers/symantic_search.py +25 -0
  18. machineconfig/scripts/python/helpers_cloud/cloud_copy.py +28 -21
  19. machineconfig/scripts/python/helpers_cloud/cloud_helpers.py +1 -1
  20. machineconfig/scripts/python/helpers_cloud/cloud_mount.py +19 -17
  21. machineconfig/scripts/python/helpers_cloud/cloud_sync.py +8 -7
  22. machineconfig/scripts/python/helpers_croshell/start_slidev.py +6 -7
  23. machineconfig/scripts/python/helpers_devops/cli_nw.py +88 -7
  24. machineconfig/scripts/python/helpers_devops/cli_self.py +7 -6
  25. machineconfig/scripts/python/helpers_devops/cli_share_file.py +7 -7
  26. machineconfig/scripts/python/helpers_devops/cli_share_server.py +12 -11
  27. machineconfig/scripts/python/helpers_devops/cli_terminal.py +6 -5
  28. machineconfig/scripts/python/helpers_devops/cli_utils.py +2 -1
  29. machineconfig/scripts/python/helpers_devops/devops_status.py +7 -19
  30. machineconfig/scripts/python/helpers_fire_command/fire_jobs_route_helper.py +20 -9
  31. machineconfig/scripts/python/helpers_navigator/command_tree.py +50 -18
  32. machineconfig/scripts/python/helpers_repos/cloud_repo_sync.py +5 -3
  33. machineconfig/scripts/python/helpers_repos/count_lines_frontend.py +1 -1
  34. machineconfig/scripts/python/helpers_utils/download.py +4 -3
  35. machineconfig/scripts/python/helpers_utils/path.py +81 -31
  36. machineconfig/scripts/python/interactive.py +1 -1
  37. machineconfig/scripts/python/{machineconfig.py → mcfg_entry.py} +4 -0
  38. machineconfig/scripts/python/msearch.py +21 -2
  39. machineconfig/scripts/python/nw/address.py +132 -0
  40. machineconfig/scripts/python/nw/devops_add_ssh_key.py +8 -5
  41. machineconfig/scripts/python/terminal.py +2 -2
  42. machineconfig/scripts/python/utils.py +10 -9
  43. machineconfig/scripts/windows/mounts/mount_ssh.ps1 +1 -1
  44. machineconfig/settings/lf/windows/lfcd.ps1 +1 -1
  45. machineconfig/settings/shells/nushell/config.nu +2 -2
  46. machineconfig/settings/shells/nushell/env.nu +45 -6
  47. machineconfig/settings/shells/nushell/init.nu +282 -95
  48. machineconfig/settings/shells/pwsh/init.ps1 +1 -0
  49. machineconfig/setup_linux/web_shortcuts/interactive.sh +10 -10
  50. machineconfig/setup_windows/uv.ps1 +8 -1
  51. machineconfig/setup_windows/web_shortcuts/interactive.ps1 +10 -10
  52. machineconfig/setup_windows/web_shortcuts/quick_init.ps1 +3 -2
  53. machineconfig/utils/accessories.py +7 -4
  54. machineconfig/utils/code.py +4 -2
  55. machineconfig/utils/installer_utils/install_from_url.py +180 -0
  56. machineconfig/utils/installer_utils/installer_class.py +18 -10
  57. machineconfig/utils/installer_utils/installer_cli.py +14 -9
  58. machineconfig/utils/links.py +2 -2
  59. machineconfig/utils/meta.py +2 -2
  60. machineconfig/utils/options.py +3 -3
  61. machineconfig/utils/path_extended.py +1 -1
  62. machineconfig/utils/path_helper.py +0 -1
  63. machineconfig/utils/ssh.py +143 -409
  64. machineconfig/utils/ssh_utils/abc.py +8 -0
  65. machineconfig/utils/ssh_utils/copy_from_here.py +110 -0
  66. machineconfig/utils/ssh_utils/copy_to_here.py +302 -0
  67. machineconfig/utils/ssh_utils/utils.py +141 -0
  68. machineconfig/utils/ssh_utils/wsl.py +168 -0
  69. machineconfig/utils/upgrade_packages.py +2 -1
  70. machineconfig/utils/ve.py +11 -4
  71. {machineconfig-7.64.dist-info → machineconfig-7.79.dist-info}/METADATA +1 -1
  72. {machineconfig-7.64.dist-info → machineconfig-7.79.dist-info}/RECORD +77 -68
  73. {machineconfig-7.64.dist-info → machineconfig-7.79.dist-info}/entry_points.txt +2 -2
  74. machineconfig/scripts/python/explore.py +0 -49
  75. /machineconfig/{settings/shells/pwsh/profile.ps1 → scripts/python/helpers_fire_command/f.py} +0 -0
  76. /machineconfig/scripts/{Restore-ThunderbirdProfile.ps1 → windows/mounts/Restore-ThunderbirdProfile.ps1} +0 -0
  77. {machineconfig-7.64.dist-info → machineconfig-7.79.dist-info}/WHEEL +0 -0
  78. {machineconfig-7.64.dist-info → machineconfig-7.79.dist-info}/top_level.txt +0 -0
@@ -7,9 +7,11 @@ from pathlib import Path
7
7
  def get_fire_tab_using_uv(func: FunctionType, tab_weight: int, import_module: bool, uv_with: Optional[list[str]], uv_project_dir: Optional[str]) -> tuple[TabConfig, Path]:
8
8
  from machineconfig.utils.meta import lambda_to_python_script
9
9
  if func.__name__ == "<lambda>":
10
- py_script = lambda_to_python_script(lmb=func, in_global=True, import_module=import_module)
10
+ py_script = lambda_to_python_script(func,
11
+ in_global=True, import_module=import_module)
11
12
  else:
12
- py_script = lambda_to_python_script(lmb=lambda: func(), in_global=True, import_module=import_module)
13
+ py_script = lambda_to_python_script(lambda: func(),
14
+ in_global=True, import_module=import_module)
13
15
  from machineconfig.utils.code import get_uv_command_executing_python_script
14
16
  command_to_run, py_script_path = get_uv_command_executing_python_script(python_script=py_script, uv_with=uv_with, uv_project_dir=uv_project_dir)
15
17
  tab_config: TabConfig = {
@@ -8,7 +8,33 @@ from rich.panel import Panel
8
8
  from machineconfig.utils.schemas.installer.installer_types import InstallerData
9
9
 
10
10
 
11
+ """
12
+ {
13
+ "appName": "Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle",
14
+ "repoURL": "https://github.com/microsoft/winget-cli",
15
+ "doc": "📦 Windows Package Manager CLI",
16
+ "fileNamePattern": {
17
+ "amd64": {
18
+ "linux": null,
19
+ "windows": "Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle",
20
+ "macos": null
21
+ },
22
+ "arm64": {
23
+ "linux": null,
24
+ "windows": "Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle",
25
+ "macos": null
26
+ }
27
+ }
28
+
29
+ """
30
+
11
31
  ps1 = r"""
32
+
33
+ # if windows is missing
34
+ # download latest from cd $HOME/Downloads; d u "https://github.com/microsoft/winget-cli/releases/download/v1.12.170-preview/Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle"
35
+ # this must be run in windows powershell, not in pwsh
36
+ # Add-AppxPackage .\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle
37
+
12
38
  winget install --no-upgrade --name "Powershell" --Id "Microsoft.PowerShell" --source winget --scope user --accept-package-agreements --accept-source-agreements # powershell require admin
13
39
  winget install --no-upgrade --name "Windows Terminal" --Id "Microsoft.WindowsTerminal" --source winget --scope user --accept-package-agreements --accept-source-agreements # Terminal is is installed by default on W 11
14
40
  winget install --no-upgrade --name "GNU Nano" --Id "GNU.Nano" --source winget --scope user --accept-package-agreements --accept-source-agreements
@@ -18,6 +18,23 @@
18
18
  }
19
19
  }
20
20
  },
21
+ {
22
+ "appName": "scrcpy",
23
+ "repoURL": "https://github.com/Genymobile/scrcpy",
24
+ "doc": "This application mirrors Android devices",
25
+ "fileNamePattern": {
26
+ "amd64": {
27
+ "linux": "scrcpy-linux-x86_64-v3.3.3.tar.gz",
28
+ "windows": "scrcpy-win64-v3.3.3.zip",
29
+ "macos": "scrcpy-macos-x86_64-v3.3.3.tar.gz"
30
+ },
31
+ "arm64": {
32
+ "linux": null,
33
+ "windows": null,
34
+ "macos": "scrcpy-macos-aarch64-v3.3.3.tar.gz"
35
+ }
36
+ }
37
+ },
21
38
  {
22
39
  "appName": "fx",
23
40
  "repoURL": "https://github.com/antonmedv/fx",
@@ -885,6 +902,40 @@
885
902
  }
886
903
  }
887
904
  },
905
+ {
906
+ "appName": "meilisearch",
907
+ "repoURL": "https://github.com/meilisearch/meilisearch",
908
+ "doc": "🔍 symantic search at lightening speed",
909
+ "fileNamePattern": {
910
+ "amd64": {
911
+ "linux": "meilisearch-linux-amd64",
912
+ "macos": "meilisearch-macos-amd64",
913
+ "windows": "meilisearch-windows-amd64.exe"
914
+ },
915
+ "arm64": {
916
+ "linux": "meilisearch-linux-aarch64",
917
+ "macos": "meilisearch-macos-aarch64",
918
+ "windows": "meilisearch-windows-aarch64.exe"
919
+ }
920
+ }
921
+ },
922
+ {
923
+ "appName": "ast-grep",
924
+ "repoURL": "https://github.com/ast-grep/ast-grep",
925
+ "doc": "🔍 grep for code - search and rewrite code with ASTs",
926
+ "fileNamePattern": {
927
+ "amd64": {
928
+ "linux": "app-x86_64-unknown-linux-gnu.zip",
929
+ "macos": "app-x86_64-apple-darwin.zip",
930
+ "windows": "app-x86_64-pc-windows-msvc.zip"
931
+ },
932
+ "arm64": {
933
+ "linux": "app-aarch64-unknown-linux-gnu.zip",
934
+ "macos": "app-aarch64-apple-darwin.zip",
935
+ "windows": "app-aarch64-pc-windows-msvc.zip"
936
+ }
937
+ }
938
+ },
888
939
  {
889
940
  "appName": "rg",
890
941
  "repoURL": "https://github.com/BurntSushi/ripgrep",
@@ -1820,6 +1871,23 @@
1820
1871
  }
1821
1872
  }
1822
1873
  },
1874
+ {
1875
+ "appName": "qrterminal",
1876
+ "repoURL": "https://github.com/mdp/qrterminal",
1877
+ "doc": "📷 qr code terminal from string",
1878
+ "fileNamePattern": {
1879
+ "amd64": {
1880
+ "linux": "qrterminal_Linux_x86_64.tar.gz",
1881
+ "macos": "qrterminal_Darwin_x86_64.tar.gz",
1882
+ "windows": "qrterminal_Windows_x86_64.zip"
1883
+ },
1884
+ "arm64": {
1885
+ "linux": "qrterminal_Linux_arm64.tar.gz",
1886
+ "macos": "qrterminal_Darwin_arm64.tar.gz",
1887
+ "windows": "qrterminal_Windows_arm64.zip"
1888
+ }
1889
+ }
1890
+ },
1823
1891
  {
1824
1892
  "appName": "termscp",
1825
1893
  "repoURL": "https://github.com/veeso/termscp",
@@ -2519,7 +2587,7 @@
2519
2587
  }
2520
2588
  },
2521
2589
  {
2522
- "appName": "warp",
2590
+ "appName": "warp-terminal",
2523
2591
  "repoURL": "CMD",
2524
2592
  "doc": "Modern terminal with AI-powered features",
2525
2593
  "fileNamePattern": {
@@ -3403,4 +3471,4 @@
3403
3471
  }
3404
3472
  }
3405
3473
  ]
3406
- }
3474
+ }
@@ -62,8 +62,8 @@ def main_public_from_parser(method: Annotated[Literal["symlink", "s", "copy", "c
62
62
  apply_mapper(mapper_data=items_objections, on_conflict=ON_CONFLICT_MAPPER[on_conflict], method=method)
63
63
 
64
64
 
65
- def main_private_from_parser(method: Annotated[Literal["symlink", "s", "copy", "c"], typer.Option(..., help="Method to use for linking files")],
66
- on_conflict: Annotated[ON_CONFLICT_LOOSE, typer.Option(..., help="Action to take on conflict")] = "throw-error",
65
+ def main_private_from_parser(method: Annotated[Literal["symlink", "s", "copy", "c"], typer.Option(..., "--method", "-m", help="Method to use for linking files")],
66
+ on_conflict: Annotated[ON_CONFLICT_LOOSE, typer.Option(..., "--on-conflict", "-o", help="Action to take on conflict")] = "throw-error",
67
67
  which: Annotated[Optional[str], typer.Option(..., "--which", "-w", help="Specific items to process")] = "all",
68
68
  interactive: Annotated[bool, typer.Option(..., "--interactive", "-i", help="Run in interactive mode")] = False):
69
69
  from machineconfig.profile.create_links import ConfigMapper, read_mapper
@@ -1,4 +0,0 @@
1
- version = "0.5"
2
- release_notes = """
3
- created toml file for symlinks
4
- """
@@ -2,7 +2,6 @@
2
2
 
3
3
  """
4
4
 
5
- from pathlib import Path
6
5
  from typing import cast, Optional, get_args, Annotated
7
6
  import typer
8
7
  from machineconfig.scripts.python.helpers_agents.fire_agents_helper_types import AGENTS, HOST, PROVIDER
@@ -13,22 +12,22 @@ def create(
13
12
  host: Annotated[HOST, typer.Option(..., "--host", "-h", help=f"Machine to run agents on. One of {', '.join(get_args(HOST))}")],
14
13
  model: Annotated[str, typer.Option(..., "--model", "-m", help="Model to use (for crush agent).")],
15
14
  provider: Annotated[PROVIDER, typer.Option(..., "--provider", "-p", help=f"Provider to use (for crush agent). One of {', '.join(get_args(PROVIDER)[:3])}")],
16
- context_path: Annotated[Optional[Path], typer.Option(..., "--context-path", "-c", help="Path to the context file/folder, defaults to .ai/todo/")] = None,
15
+ context_path: Annotated[Optional[str], typer.Option(..., "--context-path", "-c", help="Path to the context file/folder, defaults to .ai/todo/")] = None,
17
16
  separator: Annotated[str, typer.Option(..., "--separator", "-s", help="Separator for context")] = "\n",
18
17
  agent_load: Annotated[int, typer.Option(..., "--agent-load", "-al", help="Number of tasks per prompt")] = 13,
19
18
  prompt: Annotated[Optional[str], typer.Option(..., "--prompt", "-P", help="Prompt prefix as string")] = None,
20
- prompt_path: Annotated[Optional[Path], typer.Option(..., "--prompt-path", "-pp", help="Path to prompt file")] = None,
19
+ prompt_path: Annotated[Optional[str], typer.Option(..., "--prompt-path", "-pp", help="Path to prompt file")] = None,
21
20
  job_name: Annotated[str, typer.Option(..., "--job-name", "-j", help="Job name")] = "AI_Agents",
22
21
  separate: Annotated[bool, typer.Option(..., "--separate", "-S", help="Keep prompt material in separate file to the context.")] = True,
23
- output_path: Annotated[Optional[Path], typer.Option(..., "--output-path", "-o", help="Path to write the layout.json file")] = None,
24
- agents_dir: Annotated[Optional[Path], typer.Option(..., "--agents-dir", "-ad", help="Directory to store agent files. If not provided, will be constructed automatically.")] = None,
22
+ output_path: Annotated[Optional[str], typer.Option(..., "--output-path", "-o", help="Path to write the layout.json file")] = None,
23
+ agents_dir: Annotated[Optional[str], typer.Option(..., "--agents-dir", "-ad", help="Directory to store agent files. If not provided, will be constructed automatically.")] = None,
25
24
  ):
26
25
 
27
26
  from machineconfig.scripts.python.helpers_agents.fire_agents_help_launch import prep_agent_launch, get_agents_launch_layout
28
27
  from machineconfig.scripts.python.helpers_agents.fire_agents_load_balancer import chunk_prompts
29
28
  from machineconfig.utils.accessories import get_repo_root, randstr
30
29
  import json
31
-
30
+ from pathlib import Path
32
31
  # validate mutual exclusive
33
32
  prompt_options = [prompt, prompt_path]
34
33
  provided_prompt = [opt for opt in prompt_options if opt is not None]
@@ -39,12 +38,13 @@ def create(
39
38
  if repo_root is None:
40
39
  typer.echo("💥 Could not determine the repository root. Please run this script from within a git repository.")
41
40
  raise typer.Exit(1)
41
+ return
42
42
  typer.echo(f"Operating @ {repo_root}")
43
43
 
44
44
  if context_path is None:
45
- context_path = repo_root / ".ai" / "todo"
46
-
47
- context_path_resolved = context_path.expanduser().resolve()
45
+ context_path_resolved = Path(repo_root) / ".ai" / "todo"
46
+ else: context_path_resolved = Path(context_path).expanduser().resolve()
47
+
48
48
  if not context_path_resolved.exists():
49
49
  raise typer.BadParameter(f"Path does not exist: {context_path_resolved}")
50
50
 
@@ -60,20 +60,21 @@ def create(
60
60
  raise typer.BadParameter(f"Path is neither file nor directory: {context_path_resolved}")
61
61
 
62
62
  if prompt_path is not None:
63
- prompt_prefix = prompt_path.read_text(encoding="utf-8")
63
+ prompt_prefix = Path(prompt_path).read_text(encoding="utf-8")
64
64
  else:
65
65
  prompt_prefix = cast(str, prompt)
66
66
  agent_selected = agent
67
- if agents_dir is None: agents_dir = repo_root / ".ai" / f"tmp_prompts/{job_name}_{randstr()}"
67
+ if agents_dir is None: agents_dir_obj = Path(repo_root) / ".ai" / f"tmp_prompts/{job_name}_{randstr()}"
68
68
  else:
69
69
  import shutil
70
- if agents_dir.exists():
70
+ if Path(agents_dir).exists():
71
71
  shutil.rmtree(agents_dir)
72
- prep_agent_launch(repo_root=repo_root, agents_dir=agents_dir, prompts_material=prompt_material_re_splitted,
72
+ agents_dir_obj = Path(agents_dir)
73
+ prep_agent_launch(repo_root=repo_root, agents_dir=agents_dir_obj, prompts_material=prompt_material_re_splitted,
73
74
  keep_material_in_separate_file=separate,
74
75
  prompt_prefix=prompt_prefix, machine=host, agent=agent_selected, model=model, provider=provider,
75
76
  job_name=job_name)
76
- layoutfile = get_agents_launch_layout(session_root=agents_dir)
77
+ layoutfile = get_agents_launch_layout(session_root=agents_dir_obj)
77
78
  regenerate_py_code = f"""
78
79
  #!/usr/bin/env uv run --python 3.14 --with machineconfig
79
80
  agents create "{context_path_resolved}" \\
@@ -85,11 +86,11 @@ agents create "{context_path_resolved}" \\
85
86
  --separator "{separator}" \\
86
87
  {"--separate" if separate else ""}
87
88
  """
88
- (agents_dir / "aa_agents_relaunch.sh").write_text(data=regenerate_py_code, encoding="utf-8")
89
- layout_output_path = output_path if output_path is not None else agents_dir / "layout.json"
89
+ (agents_dir_obj / "aa_agents_relaunch.sh").write_text(data=regenerate_py_code, encoding="utf-8")
90
+ layout_output_path = Path(output_path) if output_path is not None else agents_dir_obj / "layout.json"
90
91
  layout_output_path.parent.mkdir(parents=True, exist_ok=True)
91
92
  layout_output_path.write_text(data=json.dumps(layoutfile, indent=4), encoding="utf-8")
92
- typer.echo(f"Created agents in {agents_dir}")
93
+ typer.echo(f"Created agents in {agents_dir_obj}")
93
94
  typer.echo(f"Ceated layout in {layout_output_path}")
94
95
 
95
96
 
@@ -99,6 +100,7 @@ def collect(
99
100
  separator: Annotated[str, typer.Option(..., help="Separator to use when concatenating material files")] = "\n",
100
101
  ) -> None:
101
102
  """Collect all material files from an agent directory and concatenate them."""
103
+ from pathlib import Path
102
104
  if not Path(agent_dir).exists() or not Path(agent_dir).is_dir():
103
105
  raise typer.BadParameter(f"Agent directory does not exist or is not a directory: {agent_dir}")
104
106
 
@@ -137,6 +139,7 @@ def collect(
137
139
  def template():
138
140
  from platform import system
139
141
  import machineconfig.scripts.python.helpers_agents as module
142
+ from pathlib import Path
140
143
  if system() == "Linux" or system() == "Darwin":
141
144
  template_path = Path(module.__file__).parent / "templates/template.sh"
142
145
  elif system() == "Windows":
@@ -157,8 +160,10 @@ def template():
157
160
 
158
161
  def init_config():
159
162
  from machineconfig.scripts.python.ai.initai import add_ai_configs
163
+ from pathlib import Path
160
164
  add_ai_configs(repo_root=Path.cwd())
161
165
 
166
+
162
167
  def get_app():
163
168
  agents_app = typer.Typer(help="🤖 AI Agents management subcommands", no_args_is_help=True, add_help_option=False, add_completion=False)
164
169
  sep = "\n"
@@ -43,3 +43,6 @@ applyTo: "**/*.py"
43
43
  * Please avoid writing README files and avoid docstring and comments in code unless absolutely necessary. Use clear naming conventions instead of documenting.
44
44
  * Always prefer to functional style of programming over OOP.
45
45
  * When passing arguments or constructing dicts or lists or tuples, avoid breaking lines too much, try to use ~ 150 characters per line before breaking to new one.
46
+
47
+ # Privacy:
48
+ * No matter what, never ever open/read/write/list anything under ~/dotfiles
@@ -16,13 +16,15 @@ def croshell(
16
16
  jupyter: Annotated[bool, typer.Option("--jupyter", "-j", help="run in jupyter interactive console")] = False,
17
17
  vscode: Annotated[bool, typer.Option("--vscode", "-c", help="open the script in vscode")] = False,
18
18
  # streamlit_viewer: Annotated[bool, typer.Option("--streamlit", "-s", help="view in streamlit app")] = False,
19
+ uv_with: Annotated[Optional[str], typer.Option("--uv-with", "-w", help="specify uv with packages to use")] = None,
19
20
  visidata: Annotated[bool, typer.Option("--visidata", "-v", help="open data file in visidata")] = False,
20
21
  marimo: Annotated[bool, typer.Option("--marimo", "-m", help="open the notebook using marimo if available")] = False,
21
22
  ) -> None:
23
+ if uv_with is not None: user_uv_with_line = f"--with {uv_with} "
24
+ else: user_uv_with_line = ""
25
+
22
26
  from machineconfig.scripts.python.helpers_croshell.crosh import get_read_python_file_pycode, get_read_data_pycode
23
27
  from machineconfig.utils.meta import lambda_to_python_script
24
- from machineconfig.utils.path_helper import get_choice_file
25
- from machineconfig.utils.path_extended import PathExtended
26
28
  from pathlib import Path
27
29
  from machineconfig.utils.accessories import randstr
28
30
  import json
@@ -37,13 +39,15 @@ def croshell(
37
39
  ipython_profile: Optional[str] = profile
38
40
  file_obj = Path.cwd() # initialization value, could be modified according to args.
39
41
  if path is not None:
42
+ from machineconfig.utils.path_helper import get_choice_file
40
43
  choice_file = get_choice_file(path=path, suffixes={".*"})
41
44
  if choice_file.suffix == ".py":
42
45
  program = choice_file.read_text(encoding="utf-8")
43
46
  text = f"📄 Selected file: {choice_file.name}"
44
47
  console.print(Panel(text, title="[bold blue]Info[/bold blue]"))
45
48
  else:
46
- program = lambda_to_python_script(lambda: get_read_data_pycode(path=str(choice_file)), in_global=True, import_module=False)
49
+ program = lambda_to_python_script(lambda: get_read_data_pycode(path=str(choice_file)),
50
+ in_global=True, import_module=False)
47
51
  text = f"📄 Reading data from: {file_obj.name}"
48
52
  console.print(Panel(text, title="[bold blue]Info[/bold blue]"))
49
53
  else: # if nothing is specified, then run in interactive mode.
@@ -64,11 +68,12 @@ def croshell(
64
68
  return textwrap.dedent("\n".join(inspect.getsource(f).splitlines()[1:]))
65
69
  preprogram += get_body_simple_function_no_args(preprogram_func)
66
70
 
67
- pyfile = PathExtended.tmp().joinpath(f"tmp_scripts/python/croshell/{randstr()}/script.py")
71
+ from pathlib import Path
72
+ pyfile = Path.home().joinpath(f"tmp_results/tmp_scripts/python/croshell/{randstr()}/script.py")
68
73
  pyfile.parent.mkdir(parents=True, exist_ok=True)
69
-
70
74
  title = "Reading Data"
71
- def_code = lambda_to_python_script(lambda: get_read_python_file_pycode(path=str(pyfile), title=title), in_global=False, import_module=False)
75
+ def_code = lambda_to_python_script(lambda: get_read_python_file_pycode(path=str(pyfile), title=title),
76
+ in_global=False, import_module=False)
72
77
  # print(def_code)
73
78
  python_program = preprogram + "\n\n" + def_code + program
74
79
  pyfile.write_text(python_program, encoding="utf-8")
@@ -102,37 +107,37 @@ def croshell(
102
107
  pass
103
108
  if visidata:
104
109
  if file_obj.suffix == ".json":
105
- fire_line = f"uv run --python 3.14 --with visidata vd {str(file_obj)}"
110
+ fire_line = f"uv run --python 3.14 {user_uv_with_line} --with visidata vd {str(file_obj)}"
106
111
  else:
107
- fire_line = f"uv run --python 3.14 --with visidata,pyarrow vd {str(file_obj)}"
112
+ fire_line = f"uv run --python 3.14 {user_uv_with_line}--with visidata,pyarrow vd {str(file_obj)}"
108
113
  elif marimo:
109
- if Path.home().joinpath("code/machineconfig").exists(): requirements = f"""--with marimo --project "{str(Path.home().joinpath("code/machineconfig"))}" """
110
- else: requirements = """--python 3.14 --with "marimo,cowsay,machineconfig[plot]>=7.64" """
114
+ if Path.home().joinpath("code/machineconfig").exists(): requirements = f"""{user_uv_with_line} --with marimo --project "{str(Path.home().joinpath("code/machineconfig"))}" """
115
+ else: requirements = f"""--python 3.14 {user_uv_with_line} user_uv_with_line--with "marimo,cowsay,machineconfig[plot]>=7.79" """
111
116
  fire_line = f"""
112
117
  cd {str(pyfile.parent)}
113
118
  uv run --python 3.14 --with "marimo" marimo convert {pyfile.name} -o marimo_nb.py
114
119
  uv run {requirements} marimo edit --host 0.0.0.0 marimo_nb.py
115
120
  """
116
121
  elif jupyter:
117
- if Path.home().joinpath("code/machineconfig").exists(): requirements = f"""--project "{str(Path.home().joinpath("code/machineconfig"))}" --with jupyterlab """
118
- else: requirements = """--with "cowsay,machineconfig[plot]>=7.64" """
122
+ if Path.home().joinpath("code/machineconfig").exists(): requirements = f"""{user_uv_with_line} --with jupyterlab --project "{str(Path.home().joinpath("code/machineconfig"))}" """
123
+ else: requirements = f"""{user_uv_with_line} --with "cowsay,machineconfig[plot]>=7.79" """
119
124
  fire_line = f"uv run {requirements} jupyter-lab {str(nb_target)}"
120
125
  elif vscode:
126
+ user_uv_add = f"uv add {uv_with}" if uv_with is not None else ""
121
127
  fire_line = f"""
122
128
  cd {str(pyfile.parent)}
123
129
  uv init --python 3.14
124
130
  uv venv
125
- uv add "cowsay,machineconfig[plot]>=7.64"
131
+ uv add "cowsay,machineconfig[plot]>=7.79"
132
+ uv add {user_uv_add}
126
133
  # code serve-web
127
134
  code --new-window {str(pyfile)}
128
135
  """
129
136
  else:
130
137
  if interpreter == "ipython": profile = f" --profile {ipython_profile} --no-banner"
131
138
  else: profile = ""
132
- if Path.home().joinpath("code/machineconfig").exists(): ve_line = f"""--project "{str(Path.home().joinpath("code/machineconfig"))}" """
133
- else: ve_line = """--python 3.14 --with "cowsay,machineconfig[plot]>=7.64" """
134
- # ve_path_maybe, ipython_profile_maybe = get_ve_path_and_ipython_profile(Path.cwd())
135
- # --python 3.14
139
+ if Path.home().joinpath("code/machineconfig").exists(): ve_line = f"""{user_uv_with_line} --project "{str(Path.home().joinpath("code/machineconfig"))}" """
140
+ else: ve_line = f"""--python 3.14 {user_uv_with_line} --with "cowsay,machineconfig[plot]>=7.79" """
136
141
  fire_line = f"uv run {ve_line} {interpreter} {interactivity} {profile} {str(pyfile)}"
137
142
 
138
143
  from machineconfig.utils.code import exit_then_run_shell_script
@@ -16,7 +16,7 @@ def install(which: Annotated[Optional[str], typer.Argument(..., help="Comma-sepa
16
16
  ) -> None:
17
17
  """📦 Install packages"""
18
18
  import machineconfig.utils.installer_utils.installer_cli as installer_entry_point
19
- installer_entry_point.main(which=which, group=group, interactive=interactive)
19
+ installer_entry_point.main_installer_cli(which=which, group=group, interactive=interactive)
20
20
 
21
21
 
22
22
  def get_app():
@@ -1,7 +1,3 @@
1
- """
2
- TUI for navigating through machineconfig command structure using Textual.
3
- """
4
-
5
1
  from machineconfig.scripts.python.helpers_navigator import CommandNavigatorApp
6
2
 
7
3
 
@@ -2,7 +2,7 @@
2
2
  # /// script
3
3
  # requires-python = ">=3.13"
4
4
  # dependencies = [
5
- # "machineconfig>=7.64",
5
+ # "machineconfig>=7.79",
6
6
  # "textual",
7
7
  # "pyperclip",
8
8
  # ]
@@ -7,20 +7,16 @@ fire
7
7
 
8
8
  """
9
9
 
10
- from machineconfig.utils.ve import get_ve_path_and_ipython_profile
11
- from machineconfig.utils.accessories import get_repo_root, randstr
12
- from machineconfig.scripts.python.helpers_fire_command.fire_jobs_args_helper import FireJobArgs, extract_kwargs, parse_fire_args_from_context
13
- from machineconfig.utils.path_helper import get_choice_file
14
-
15
- import platform
16
10
  from typing import Optional, Annotated
17
- from pathlib import Path
18
11
  import typer
19
12
 
20
13
 
21
- def route(args: FireJobArgs, fire_args: str = "") -> None:
14
+ def route(args: "FireJobArgs", fire_args: str = "") -> None:
15
+ from pathlib import Path
16
+ from machineconfig.utils.path_helper import get_choice_file
17
+ from machineconfig.utils.accessories import get_repo_root, randstr
22
18
  choice_file = get_choice_file(args.path, suffixes=None)
23
- repo_root = get_repo_root(Path(choice_file))
19
+ repo_root = get_repo_root(choice_file)
24
20
  print(f"💾 Selected file: {choice_file}.\nRepo root: {repo_root}")
25
21
  if args.marimo:
26
22
  print(f"🧽 Preparing to launch Marimo notebook for `{choice_file}`...")
@@ -38,6 +34,7 @@ uv run --project {repo_root} --with marimo marimo edit --host 0.0.0.0 marimo_nb.
38
34
 
39
35
  # ========================= preparing kwargs_dict
40
36
  if choice_file.suffix == ".py":
37
+ from machineconfig.scripts.python.helpers_fire_command.fire_jobs_args_helper import extract_kwargs
41
38
  kwargs_dict = extract_kwargs(args) # This now returns empty dict, but kept for compatibility
42
39
  else:
43
40
  kwargs_dict = {}
@@ -52,17 +49,17 @@ uv run --project {repo_root} --with marimo marimo edit --host 0.0.0.0 marimo_nb.
52
49
  choice_function = args.function
53
50
 
54
51
  if choice_file.suffix == ".py":
55
- from machineconfig.scripts.python.helpers_fire_command.fire_jobs_route_helper import get_command_streamlit
56
-
57
52
  with_project = f"--project {repo_root} " if repo_root is not None else ""
58
53
  if args.streamlit:
54
+ from machineconfig.scripts.python.helpers_fire_command.fire_jobs_route_helper import get_command_streamlit
59
55
  exe = get_command_streamlit(choice_file=choice_file, environment=args.environment, repo_root=repo_root)
60
56
  exe = f"uv run {with_project} {exe} "
61
57
  elif args.jupyter:
62
58
  exe = f"uv run {with_project} jupyter-lab"
63
59
  else:
64
60
  if args.interactive:
65
- _ve_root_from_file, ipy_profile = get_ve_path_and_ipython_profile(choice_file)
61
+ from machineconfig.utils.ve import get_ve_path_and_ipython_profile
62
+ _ve_root_from_file, ipy_profile = get_ve_path_and_ipython_profile(init_path=choice_file)
66
63
  if ipy_profile is None:
67
64
  ipy_profile = "default"
68
65
  exe = f"uv run {with_project} ipython -i --no-banner --profile {ipy_profile} "
@@ -106,6 +103,7 @@ uv run --project {repo_root} --with marimo marimo edit --host 0.0.0.0 marimo_nb.
106
103
 
107
104
  # ========================= determining basic command structure: putting together exe & choice_file & choice_function & pdb
108
105
  if args.debug:
106
+ import platform
109
107
  if platform.system() == "Windows":
110
108
  command = f"{exe} -m ipdb {choice_file} " # pudb is not available on windows machines, use poor man's debugger instead.
111
109
  elif platform.system() in ["Linux", "Darwin"]:
@@ -173,6 +171,7 @@ uv run --project {repo_root} --with marimo marimo edit --host 0.0.0.0 marimo_nb.
173
171
  export_line = add_to_path(path_variable="PYTHONPATH", directory=str(repo_root))
174
172
  command = export_line + "\n" + command
175
173
  if args.loop:
174
+ import platform
176
175
  if platform.system() in ["Linux", "Darwin"]:
177
176
  command = command + "\nsleep 0.5"
178
177
  elif platform.system() == "Windows":
@@ -214,6 +213,7 @@ def fire(
214
213
  """Main function to process fire jobs arguments."""
215
214
 
216
215
  # Get Fire arguments from context
216
+ from machineconfig.scripts.python.helpers_fire_command.fire_jobs_args_helper import FireJobArgs, parse_fire_args_from_context
217
217
  fire_args = parse_fire_args_from_context(ctx)
218
218
 
219
219
  args = FireJobArgs(
@@ -266,4 +266,4 @@ def main():
266
266
 
267
267
 
268
268
  if __name__ == "__main__":
269
- pass
269
+ from machineconfig.scripts.python.helpers_fire_command.fire_jobs_args_helper import FireJobArgs
@@ -6,17 +6,7 @@ Currently, the only way to work around this is to predifine the host in ~/.ssh/c
6
6
  """
7
7
 
8
8
  import typer
9
- from typing_extensions import Annotated
10
- from rich.console import Console
11
- from rich.panel import Panel
12
-
13
- from machineconfig.utils.ssh import SSH
14
- from machineconfig.utils.path_extended import PathExtended
15
- from machineconfig.scripts.python.helpers_cloud.helpers2 import ES
16
- from machineconfig.utils.accessories import pprint
17
-
18
-
19
- console = Console()
9
+ from typing import Annotated
20
10
 
21
11
 
22
12
  def ftpx(
@@ -25,7 +15,41 @@ def ftpx(
25
15
  recursive: Annotated[bool, typer.Option("--recursive", "-r", help="Send recursively.")] = False,
26
16
  zipFirst: Annotated[bool, typer.Option("--zipFirst", "-z", help="Zip before sending.")] = False,
27
17
  cloud: Annotated[bool, typer.Option("--cloud", "-c", help="Transfer through the cloud.")] = False,
18
+ overwrite_existing: Annotated[bool, typer.Option("--overwrite-existing", "-o", help="Overwrite existing files on remote when sending from local to remote.")] = False,
28
19
  ) -> None:
20
+ from pathlib import Path
21
+ if target == "wsl" or source == "wsl":
22
+ from machineconfig.utils.ssh_utils.wsl import copy_when_inside_windows
23
+ if target == "wsl":
24
+ target_obj = Path(source).expanduser().absolute().relative_to(Path.home())
25
+ source_obj = target_obj
26
+ else:
27
+ source_obj = Path(target).expanduser().absolute().relative_to(Path.home())
28
+ target_obj = source_obj
29
+ copy_when_inside_windows(source_obj, target_obj, overwrite_existing)
30
+ return
31
+ elif source == "win" or target == "win":
32
+ if source == "win":
33
+ source_obj = Path(target).expanduser().absolute().relative_to(Path.home())
34
+ target_obj = source_obj
35
+ else:
36
+ target_obj = Path(source).expanduser().absolute().relative_to(Path.home())
37
+ source_obj = target_obj
38
+ from machineconfig.utils.ssh_utils.wsl import copy_when_inside_wsl
39
+ copy_when_inside_wsl(source_obj, target_obj, overwrite_existing)
40
+ return
41
+
42
+ from rich.console import Console
43
+ from rich.panel import Panel
44
+
45
+ from machineconfig.utils.ssh import SSH
46
+ from machineconfig.utils.path_extended import PathExtended
47
+ from machineconfig.scripts.python.helpers_cloud.helpers2 import ES
48
+ from machineconfig.utils.accessories import pprint
49
+
50
+
51
+ console = Console()
52
+
29
53
  console.print(
30
54
  Panel(
31
55
  "\n".join(
@@ -185,7 +209,7 @@ def ftpx(
185
209
  padding=(1, 2),
186
210
  )
187
211
  )
188
- received_file = ssh.copy_from_here(source_path=resolved_source, target_rel2home=resolved_target, compress_with_zip=zipFirst, recursive=recursive, overwrite_existing=False)
212
+ received_file = ssh.copy_from_here(source_path=resolved_source, target_rel2home=resolved_target, compress_with_zip=zipFirst, recursive=recursive, overwrite_existing=overwrite_existing)
189
213
 
190
214
  if source_is_remote and isinstance(received_file, PathExtended):
191
215
  console.print(