machineconfig 2.0__py3-none-any.whl → 2.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of machineconfig might be problematic. Click here for more details.
- machineconfig/cluster/cloud_manager.py +0 -3
- machineconfig/cluster/data_transfer.py +0 -1
- machineconfig/cluster/file_manager.py +0 -1
- machineconfig/cluster/job_params.py +0 -3
- machineconfig/cluster/loader_runner.py +0 -3
- machineconfig/cluster/remote_machine.py +0 -1
- machineconfig/cluster/script_notify_upon_completion.py +0 -1
- machineconfig/cluster/sessions_managers/archive/create_zellij_template.py +5 -6
- machineconfig/cluster/sessions_managers/archive/session_managers.py +0 -1
- machineconfig/cluster/sessions_managers/enhanced_command_runner.py +17 -57
- machineconfig/cluster/sessions_managers/wt_local.py +36 -110
- machineconfig/cluster/sessions_managers/wt_local_manager.py +42 -112
- machineconfig/cluster/sessions_managers/wt_remote.py +23 -30
- machineconfig/cluster/sessions_managers/wt_remote_manager.py +20 -62
- machineconfig/cluster/sessions_managers/wt_utils/layout_generator.py +10 -15
- machineconfig/cluster/sessions_managers/wt_utils/process_monitor.py +27 -127
- machineconfig/cluster/sessions_managers/wt_utils/remote_executor.py +10 -43
- machineconfig/cluster/sessions_managers/wt_utils/session_manager.py +22 -101
- machineconfig/cluster/sessions_managers/wt_utils/status_reporter.py +11 -39
- machineconfig/cluster/sessions_managers/zellij_local.py +49 -102
- machineconfig/cluster/sessions_managers/zellij_local_manager.py +34 -78
- machineconfig/cluster/sessions_managers/zellij_remote.py +17 -24
- machineconfig/cluster/sessions_managers/zellij_remote_manager.py +7 -13
- machineconfig/cluster/sessions_managers/zellij_utils/example_usage.py +4 -2
- machineconfig/cluster/sessions_managers/zellij_utils/layout_generator.py +6 -6
- machineconfig/cluster/sessions_managers/zellij_utils/process_monitor.py +18 -88
- machineconfig/cluster/sessions_managers/zellij_utils/remote_executor.py +2 -6
- machineconfig/cluster/sessions_managers/zellij_utils/session_manager.py +12 -40
- machineconfig/cluster/sessions_managers/zellij_utils/status_reporter.py +3 -2
- machineconfig/cluster/templates/cli_click.py +0 -1
- machineconfig/cluster/templates/cli_gooey.py +0 -2
- machineconfig/cluster/templates/cli_trogon.py +0 -1
- machineconfig/cluster/templates/run_cloud.py +0 -1
- machineconfig/cluster/templates/run_cluster.py +0 -1
- machineconfig/cluster/templates/run_remote.py +0 -1
- machineconfig/cluster/templates/utils.py +27 -46
- machineconfig/jobs/__pycache__/__init__.cpython-313.pyc +0 -0
- machineconfig/jobs/linux/msc/cli_agents.sh +16 -0
- machineconfig/jobs/python/check_installations.py +2 -1
- machineconfig/jobs/python/create_bootable_media.py +0 -2
- machineconfig/jobs/python/python_ve_symlink.py +9 -11
- machineconfig/jobs/python/tasks.py +0 -1
- machineconfig/jobs/python/vscode/api.py +5 -5
- machineconfig/jobs/python/vscode/link_ve.py +13 -14
- machineconfig/jobs/python/vscode/select_interpreter.py +21 -22
- machineconfig/jobs/python/vscode/sync_code.py +9 -13
- machineconfig/jobs/python_custom_installers/archive/ngrok.py +13 -13
- machineconfig/jobs/python_custom_installers/dev/aider.py +7 -15
- machineconfig/jobs/python_custom_installers/dev/alacritty.py +9 -18
- machineconfig/jobs/python_custom_installers/dev/brave.py +10 -19
- machineconfig/jobs/python_custom_installers/dev/bypass_paywall.py +8 -15
- machineconfig/jobs/python_custom_installers/dev/code.py +12 -32
- machineconfig/jobs/python_custom_installers/dev/cursor.py +3 -14
- machineconfig/jobs/python_custom_installers/dev/docker_desktop.py +8 -7
- machineconfig/jobs/python_custom_installers/dev/espanso.py +15 -19
- machineconfig/jobs/python_custom_installers/dev/goes.py +5 -12
- machineconfig/jobs/python_custom_installers/dev/lvim.py +9 -17
- machineconfig/jobs/python_custom_installers/dev/nerdfont.py +12 -19
- machineconfig/jobs/python_custom_installers/dev/redis.py +12 -20
- machineconfig/jobs/python_custom_installers/dev/wezterm.py +12 -19
- machineconfig/jobs/python_custom_installers/dev/winget.py +5 -23
- machineconfig/jobs/python_custom_installers/docker.py +12 -21
- machineconfig/jobs/python_custom_installers/gh.py +11 -19
- machineconfig/jobs/python_custom_installers/hx.py +32 -16
- machineconfig/jobs/python_custom_installers/warp-cli.py +12 -20
- machineconfig/jobs/python_generic_installers/__pycache__/__init__.cpython-313.pyc +0 -0
- machineconfig/jobs/python_generic_installers/config.json +1 -1
- machineconfig/jobs/python_linux_installers/__pycache__/__init__.cpython-313.pyc +0 -0
- machineconfig/jobs/windows/archive/archive_pygraphviz.ps1 +1 -1
- machineconfig/jobs/windows/msc/cli_agents.bat +0 -0
- machineconfig/jobs/windows/msc/cli_agents.ps1 +0 -0
- machineconfig/jobs/windows/start_terminal.ps1 +1 -1
- machineconfig/profile/create.py +38 -26
- machineconfig/profile/create_hardlinks.py +29 -20
- machineconfig/profile/shell.py +56 -32
- machineconfig/scripts/__init__.py +0 -2
- machineconfig/scripts/__pycache__/__init__.cpython-313.pyc +0 -0
- machineconfig/scripts/cloud/init.sh +2 -2
- machineconfig/scripts/linux/checkout_versions +1 -1
- machineconfig/scripts/linux/choose_wezterm_theme +1 -1
- machineconfig/scripts/linux/cloud_copy +1 -1
- machineconfig/scripts/linux/cloud_manager +1 -1
- machineconfig/scripts/linux/cloud_mount +1 -1
- machineconfig/scripts/linux/cloud_repo_sync +1 -1
- machineconfig/scripts/linux/cloud_sync +1 -1
- machineconfig/scripts/linux/croshell +1 -1
- machineconfig/scripts/linux/devops +7 -7
- machineconfig/scripts/linux/fire +1 -1
- machineconfig/scripts/linux/fire_agents +3 -2
- machineconfig/scripts/linux/ftpx +1 -1
- machineconfig/scripts/linux/gh_models +1 -1
- machineconfig/scripts/linux/kill_process +1 -1
- machineconfig/scripts/linux/mcinit +1 -1
- machineconfig/scripts/linux/repos +1 -1
- machineconfig/scripts/linux/scheduler +1 -1
- machineconfig/scripts/linux/start_slidev +1 -1
- machineconfig/scripts/linux/start_terminals +1 -1
- machineconfig/scripts/linux/url2md +1 -1
- machineconfig/scripts/linux/warp-cli.sh +122 -0
- machineconfig/scripts/linux/wifi_conn +1 -1
- machineconfig/scripts/python/__pycache__/__init__.cpython-313.pyc +0 -0
- machineconfig/scripts/python/__pycache__/devops.cpython-313.pyc +0 -0
- machineconfig/scripts/python/__pycache__/devops_devapps_install.cpython-313.pyc +0 -0
- machineconfig/scripts/python/__pycache__/devops_update_repos.cpython-313.pyc +0 -0
- machineconfig/scripts/python/__pycache__/fire_agents.cpython-313.pyc +0 -0
- machineconfig/scripts/python/ai/__init__.py +0 -0
- machineconfig/scripts/python/ai/generate_files.py +83 -0
- machineconfig/scripts/python/ai/instructions/python/dev.instructions.md +2 -2
- machineconfig/scripts/python/ai/mcinit.py +14 -7
- machineconfig/scripts/python/ai/scripts/lint_and_type_check.sh +10 -5
- machineconfig/scripts/python/archive/tmate_conn.py +5 -5
- machineconfig/scripts/python/archive/tmate_start.py +7 -7
- machineconfig/scripts/python/choose_wezterm_theme.py +35 -32
- machineconfig/scripts/python/cloud_copy.py +23 -14
- machineconfig/scripts/python/cloud_mount.py +36 -24
- machineconfig/scripts/python/cloud_repo_sync.py +40 -27
- machineconfig/scripts/python/cloud_sync.py +4 -4
- machineconfig/scripts/python/croshell.py +40 -29
- machineconfig/scripts/python/devops.py +45 -27
- machineconfig/scripts/python/devops_add_identity.py +15 -25
- machineconfig/scripts/python/devops_add_ssh_key.py +8 -8
- machineconfig/scripts/python/devops_backup_retrieve.py +18 -16
- machineconfig/scripts/python/devops_devapps_install.py +25 -20
- machineconfig/scripts/python/devops_update_repos.py +232 -59
- machineconfig/scripts/python/dotfile.py +17 -15
- machineconfig/scripts/python/fire_agents.py +48 -22
- machineconfig/scripts/python/fire_jobs.py +93 -58
- machineconfig/scripts/python/ftpx.py +26 -15
- machineconfig/scripts/python/get_zellij_cmd.py +8 -7
- machineconfig/scripts/python/helpers/cloud_helpers.py +33 -28
- machineconfig/scripts/python/helpers/helpers2.py +27 -16
- machineconfig/scripts/python/helpers/helpers4.py +45 -32
- machineconfig/scripts/python/helpers/helpers5.py +1 -1
- machineconfig/scripts/python/helpers/repo_sync_helpers.py +32 -10
- machineconfig/scripts/python/mount_nfs.py +9 -16
- machineconfig/scripts/python/mount_nw_drive.py +10 -5
- machineconfig/scripts/python/mount_ssh.py +9 -7
- machineconfig/scripts/python/repos.py +216 -58
- machineconfig/scripts/python/snapshot.py +0 -1
- machineconfig/scripts/python/start_slidev.py +11 -6
- machineconfig/scripts/python/start_terminals.py +22 -16
- machineconfig/scripts/python/viewer_template.py +0 -1
- machineconfig/scripts/python/wifi_conn.py +49 -75
- machineconfig/scripts/python/wsl_windows_transfer.py +9 -7
- machineconfig/scripts/windows/checkout_version.ps1 +1 -3
- machineconfig/scripts/windows/choose_wezterm_theme.ps1 +1 -3
- machineconfig/scripts/windows/cloud_copy.ps1 +2 -6
- machineconfig/scripts/windows/cloud_manager.ps1 +1 -1
- machineconfig/scripts/windows/cloud_repo_sync.ps1 +1 -2
- machineconfig/scripts/windows/cloud_sync.ps1 +2 -2
- machineconfig/scripts/windows/croshell.ps1 +2 -2
- machineconfig/scripts/windows/devops.ps1 +1 -4
- machineconfig/scripts/windows/dotfile.ps1 +1 -3
- machineconfig/scripts/windows/fire.ps1 +1 -1
- machineconfig/scripts/windows/ftpx.ps1 +2 -2
- machineconfig/scripts/windows/gpt.ps1 +1 -1
- machineconfig/scripts/windows/kill_process.ps1 +1 -2
- machineconfig/scripts/windows/mcinit.ps1 +1 -1
- machineconfig/scripts/windows/mount_nfs.ps1 +1 -1
- machineconfig/scripts/windows/mount_ssh.ps1 +1 -1
- machineconfig/scripts/windows/pomodoro.ps1 +1 -1
- machineconfig/scripts/windows/py2exe.ps1 +1 -3
- machineconfig/scripts/windows/repos.ps1 +1 -1
- machineconfig/scripts/windows/scheduler.ps1 +1 -1
- machineconfig/scripts/windows/snapshot.ps1 +2 -2
- machineconfig/scripts/windows/start_slidev.ps1 +1 -1
- machineconfig/scripts/windows/start_terminals.ps1 +1 -1
- machineconfig/scripts/windows/wifi_conn.ps1 +1 -1
- machineconfig/scripts/windows/wsl_windows_transfer.ps1 +1 -3
- machineconfig/settings/lf/linux/lfrc +2 -1
- machineconfig/settings/linters/.ruff_cache/.gitignore +2 -0
- machineconfig/settings/linters/.ruff_cache/CACHEDIR.TAG +1 -0
- machineconfig/settings/lvim/windows/archive/config_additional.lua +1 -1
- machineconfig/settings/svim/linux/init.toml +1 -1
- machineconfig/settings/svim/windows/init.toml +1 -1
- machineconfig/setup_linux/web_shortcuts/croshell.sh +3 -52
- machineconfig/setup_linux/web_shortcuts/interactive.sh +6 -6
- machineconfig/setup_linux/web_shortcuts/ssh.sh +0 -4
- machineconfig/setup_windows/web_shortcuts/all.ps1 +2 -2
- machineconfig/setup_windows/web_shortcuts/ascii_art.ps1 +1 -1
- machineconfig/setup_windows/web_shortcuts/croshell.ps1 +1 -1
- machineconfig/setup_windows/web_shortcuts/interactive.ps1 +5 -5
- machineconfig/setup_windows/wt_and_pwsh/install_fonts.ps1 +51 -15
- machineconfig/setup_windows/wt_and_pwsh/set_pwsh_theme.py +58 -13
- machineconfig/setup_windows/wt_and_pwsh/set_wt_settings.py +45 -37
- machineconfig/utils/ai/generate_file_checklist.py +8 -10
- machineconfig/utils/ai/url2md.py +4 -2
- machineconfig/utils/cloud/onedrive/setup_oauth.py +1 -0
- machineconfig/utils/cloud/onedrive/transaction.py +63 -98
- machineconfig/utils/code.py +62 -41
- machineconfig/utils/installer.py +29 -35
- machineconfig/utils/installer_utils/installer_abc.py +11 -11
- machineconfig/utils/installer_utils/installer_class.py +155 -74
- machineconfig/utils/links.py +112 -31
- machineconfig/utils/notifications.py +211 -0
- machineconfig/utils/options.py +41 -42
- machineconfig/utils/path.py +13 -6
- machineconfig/utils/path_reduced.py +614 -311
- machineconfig/utils/procs.py +48 -42
- machineconfig/utils/scheduling.py +0 -1
- machineconfig/utils/source_of_truth.py +27 -0
- machineconfig/utils/ssh.py +146 -85
- machineconfig/utils/terminal.py +84 -37
- machineconfig/utils/upgrade_packages.py +91 -0
- machineconfig/utils/utils2.py +39 -50
- machineconfig/utils/utils5.py +195 -116
- machineconfig/utils/ve.py +13 -5
- {machineconfig-2.0.dist-info → machineconfig-2.2.dist-info}/METADATA +14 -13
- {machineconfig-2.0.dist-info → machineconfig-2.2.dist-info}/RECORD +212 -237
- machineconfig/jobs/__pycache__/__init__.cpython-311.pyc +0 -0
- machineconfig/jobs/python/__pycache__/__init__.cpython-311.pyc +0 -0
- machineconfig/jobs/python/__pycache__/python_ve_symlink.cpython-311.pyc +0 -0
- machineconfig/jobs/python/archive/python_tools.txt +0 -12
- machineconfig/jobs/python/vscode/__pycache__/select_interpreter.cpython-311.pyc +0 -0
- machineconfig/jobs/python_custom_installers/__pycache__/__init__.cpython-311.pyc +0 -0
- machineconfig/jobs/python_generic_installers/__pycache__/__init__.cpython-311.pyc +0 -0
- machineconfig/jobs/python_generic_installers/update.py +0 -3
- machineconfig/jobs/python_linux_installers/__pycache__/__init__.cpython-311.pyc +0 -0
- machineconfig/profile/__pycache__/__init__.cpython-311.pyc +0 -0
- machineconfig/profile/__pycache__/create.cpython-311.pyc +0 -0
- machineconfig/profile/__pycache__/shell.cpython-311.pyc +0 -0
- machineconfig/scripts/__pycache__/__init__.cpython-311.pyc +0 -0
- machineconfig/scripts/linux/activate_ve +0 -87
- machineconfig/scripts/python/__pycache__/__init__.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/cloud_copy.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/cloud_mount.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/cloud_sync.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/croshell.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/devops.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/devops_backup_retrieve.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/devops_devapps_install.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/devops_update_repos.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/fire_agents.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/fire_jobs.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/fire_jobs.cpython-313.pyc +0 -0
- machineconfig/scripts/python/__pycache__/get_zellij_cmd.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/repos.cpython-311.pyc +0 -0
- machineconfig/scripts/python/ai/__pycache__/init.cpython-311.pyc +0 -0
- machineconfig/scripts/python/ai/__pycache__/mcinit.cpython-311.pyc +0 -0
- machineconfig/scripts/python/helpers/__pycache__/__init__.cpython-311.pyc +0 -0
- machineconfig/scripts/python/helpers/__pycache__/__init__.cpython-313.pyc +0 -0
- machineconfig/scripts/python/helpers/__pycache__/cloud_helpers.cpython-311.pyc +0 -0
- machineconfig/scripts/python/helpers/__pycache__/helpers2.cpython-311.pyc +0 -0
- machineconfig/scripts/python/helpers/__pycache__/helpers4.cpython-311.pyc +0 -0
- machineconfig/scripts/python/helpers/__pycache__/helpers4.cpython-313.pyc +0 -0
- machineconfig/scripts/python/helpers/__pycache__/repo_sync_helpers.cpython-311.pyc +0 -0
- machineconfig/scripts/windows/activate_ve.ps1 +0 -54
- machineconfig/setup_linux/web_shortcuts/all.sh +0 -48
- machineconfig/setup_linux/web_shortcuts/update_system.sh +0 -48
- machineconfig/utils/utils.py +0 -95
- /machineconfig/setup_linux/web_shortcuts/{tmp.sh → android.sh} +0 -0
- {machineconfig-2.0.dist-info → machineconfig-2.2.dist-info}/WHEEL +0 -0
- {machineconfig-2.0.dist-info → machineconfig-2.2.dist-info}/top_level.txt +0 -0
|
@@ -1,21 +1,220 @@
|
|
|
1
|
-
"""Update repositories with fancy output
|
|
2
|
-
"""
|
|
1
|
+
"""Update repositories with fancy output"""
|
|
3
2
|
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
import git
|
|
4
|
+
import subprocess
|
|
5
|
+
import hashlib
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from machineconfig.utils.path_reduced import PathExtended as PathExtended
|
|
8
|
+
from machineconfig.utils.source_of_truth import DEFAULTS_PATH
|
|
6
9
|
from machineconfig.utils.utils2 import read_ini
|
|
7
|
-
from platform import system
|
|
8
10
|
|
|
9
11
|
|
|
10
|
-
|
|
12
|
+
def get_file_hash(file_path: Path) -> str | None:
|
|
13
|
+
"""Get SHA256 hash of a file, return None if file doesn't exist."""
|
|
14
|
+
if not file_path.exists():
|
|
15
|
+
return None
|
|
16
|
+
return hashlib.sha256(file_path.read_bytes()).hexdigest()
|
|
11
17
|
|
|
12
18
|
|
|
13
|
-
def
|
|
19
|
+
def set_permissions_recursive(path: Path, executable: bool = True) -> None:
|
|
20
|
+
"""Set permissions recursively for a directory."""
|
|
21
|
+
if not path.exists():
|
|
22
|
+
return
|
|
23
|
+
|
|
24
|
+
if path.is_file():
|
|
25
|
+
if executable:
|
|
26
|
+
path.chmod(0o755)
|
|
27
|
+
else:
|
|
28
|
+
path.chmod(0o644)
|
|
29
|
+
elif path.is_dir():
|
|
30
|
+
path.chmod(0o755)
|
|
31
|
+
for item in path.rglob("*"):
|
|
32
|
+
set_permissions_recursive(item, executable)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def run_uv_sync(repo_path: Path) -> bool:
|
|
36
|
+
"""Run uv sync in the given repository path. Returns True if successful."""
|
|
37
|
+
try:
|
|
38
|
+
print(f"🔄 Running uv sync in {repo_path}")
|
|
39
|
+
result = subprocess.run(["uv", "sync"], cwd=repo_path, capture_output=True, text=True, check=True)
|
|
40
|
+
print("✅ uv sync completed successfully")
|
|
41
|
+
if result.stdout:
|
|
42
|
+
print(f"📝 Output: {result.stdout}")
|
|
43
|
+
return True
|
|
44
|
+
except subprocess.CalledProcessError as e:
|
|
45
|
+
print(f"❌ uv sync failed: {e}")
|
|
46
|
+
if e.stderr:
|
|
47
|
+
print(f"📝 Error: {e.stderr}")
|
|
48
|
+
return False
|
|
49
|
+
except FileNotFoundError:
|
|
50
|
+
print("⚠️ uv command not found. Please install uv first.")
|
|
51
|
+
return False
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def update_repository(repo: git.Repo, auto_sync: bool = True, allow_password_prompt: bool = False) -> bool:
|
|
55
|
+
"""Update a single repository and return True if pyproject.toml or uv.lock changed."""
|
|
56
|
+
repo_path = Path(repo.working_dir)
|
|
57
|
+
print(f"🔄 {'Updating ' + str(repo_path):.^80}")
|
|
58
|
+
|
|
59
|
+
# Check if this repo has pyproject.toml or uv.lock
|
|
60
|
+
pyproject_path = repo_path / "pyproject.toml"
|
|
61
|
+
uv_lock_path = repo_path / "uv.lock"
|
|
62
|
+
|
|
63
|
+
# Get hashes before pull
|
|
64
|
+
pyproject_hash_before = get_file_hash(pyproject_path)
|
|
65
|
+
uv_lock_hash_before = get_file_hash(uv_lock_path)
|
|
66
|
+
|
|
67
|
+
# Get current commit hash before pull
|
|
68
|
+
commit_before = repo.head.commit.hexsha
|
|
69
|
+
|
|
70
|
+
try:
|
|
71
|
+
# Use subprocess for git pull to get better output control
|
|
72
|
+
dependencies_changed = False
|
|
73
|
+
|
|
74
|
+
# Get list of remotes
|
|
75
|
+
remotes = list(repo.remotes)
|
|
76
|
+
if not remotes:
|
|
77
|
+
print("⚠️ No remotes configured for this repository")
|
|
78
|
+
return False
|
|
79
|
+
|
|
80
|
+
for remote in remotes:
|
|
81
|
+
try:
|
|
82
|
+
print(f"📥 Fetching from {remote.name}...")
|
|
83
|
+
|
|
84
|
+
# Set up environment for git commands
|
|
85
|
+
env = None
|
|
86
|
+
if not allow_password_prompt:
|
|
87
|
+
# Disable interactive prompts
|
|
88
|
+
import os
|
|
89
|
+
|
|
90
|
+
env = os.environ.copy()
|
|
91
|
+
env["GIT_TERMINAL_PROMPT"] = "0"
|
|
92
|
+
env["GIT_ASKPASS"] = "echo" # Returns empty string for any credential request
|
|
93
|
+
|
|
94
|
+
# First fetch to see what's available
|
|
95
|
+
fetch_result = subprocess.run(
|
|
96
|
+
["git", "fetch", remote.name, "--verbose"],
|
|
97
|
+
cwd=repo_path,
|
|
98
|
+
capture_output=True,
|
|
99
|
+
text=True,
|
|
100
|
+
env=env,
|
|
101
|
+
timeout=30, # Add timeout to prevent hanging
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
# Check if fetch failed due to authentication
|
|
105
|
+
if fetch_result.returncode != 0 and not allow_password_prompt:
|
|
106
|
+
auth_error_indicators = [
|
|
107
|
+
"Authentication failed",
|
|
108
|
+
"Password for",
|
|
109
|
+
"Username for",
|
|
110
|
+
"could not read Username",
|
|
111
|
+
"could not read Password",
|
|
112
|
+
"fatal: Authentication failed",
|
|
113
|
+
"fatal: could not read Username",
|
|
114
|
+
"fatal: could not read Password",
|
|
115
|
+
]
|
|
116
|
+
|
|
117
|
+
error_output = (fetch_result.stderr or "") + (fetch_result.stdout or "")
|
|
118
|
+
if any(indicator in error_output for indicator in auth_error_indicators):
|
|
119
|
+
print(f"⚠️ Skipping {remote.name} - authentication required but password prompts are disabled")
|
|
120
|
+
continue
|
|
121
|
+
|
|
122
|
+
if fetch_result.stdout:
|
|
123
|
+
print(f"📡 Fetch output: {fetch_result.stdout.strip()}")
|
|
124
|
+
if fetch_result.stderr:
|
|
125
|
+
print(f"📡 Fetch info: {fetch_result.stderr.strip()}")
|
|
126
|
+
|
|
127
|
+
# Now pull with verbose output
|
|
128
|
+
print(f"📥 Pulling from {remote.name}/{repo.active_branch.name}...")
|
|
129
|
+
pull_result = subprocess.run(["git", "pull", remote.name, repo.active_branch.name, "--verbose"], cwd=repo_path, capture_output=True, text=True, env=env, timeout=30)
|
|
130
|
+
|
|
131
|
+
# Check if pull failed due to authentication
|
|
132
|
+
if pull_result.returncode != 0 and not allow_password_prompt:
|
|
133
|
+
auth_error_indicators = [
|
|
134
|
+
"Authentication failed",
|
|
135
|
+
"Password for",
|
|
136
|
+
"Username for",
|
|
137
|
+
"could not read Username",
|
|
138
|
+
"could not read Password",
|
|
139
|
+
"fatal: Authentication failed",
|
|
140
|
+
"fatal: could not read Username",
|
|
141
|
+
"fatal: could not read Password",
|
|
142
|
+
]
|
|
143
|
+
|
|
144
|
+
error_output = (pull_result.stderr or "") + (pull_result.stdout or "")
|
|
145
|
+
if any(indicator in error_output for indicator in auth_error_indicators):
|
|
146
|
+
print(f"⚠️ Skipping pull from {remote.name} - authentication required but password prompts are disabled")
|
|
147
|
+
continue
|
|
148
|
+
|
|
149
|
+
if pull_result.stdout:
|
|
150
|
+
print(f"📦 Pull output: {pull_result.stdout.strip()}")
|
|
151
|
+
if pull_result.stderr:
|
|
152
|
+
print(f"📦 Pull info: {pull_result.stderr.strip()}")
|
|
153
|
+
|
|
154
|
+
# Check if pull was successful
|
|
155
|
+
if pull_result.returncode == 0:
|
|
156
|
+
# Check if commits changed
|
|
157
|
+
commit_after = repo.head.commit.hexsha
|
|
158
|
+
if commit_before != commit_after:
|
|
159
|
+
print(f"✅ Repository updated: {commit_before[:8]} → {commit_after[:8]}")
|
|
160
|
+
else:
|
|
161
|
+
print("✅ Already up to date")
|
|
162
|
+
else:
|
|
163
|
+
print(f"❌ Pull failed with return code {pull_result.returncode}")
|
|
164
|
+
|
|
165
|
+
except Exception as e:
|
|
166
|
+
print(f"⚠️ Failed to pull from {remote.name}: {e}")
|
|
167
|
+
continue
|
|
168
|
+
|
|
169
|
+
# Check if pyproject.toml or uv.lock changed after pull
|
|
170
|
+
pyproject_hash_after = get_file_hash(pyproject_path)
|
|
171
|
+
uv_lock_hash_after = get_file_hash(uv_lock_path)
|
|
172
|
+
|
|
173
|
+
if pyproject_hash_before != pyproject_hash_after:
|
|
174
|
+
print("📋 pyproject.toml has changed")
|
|
175
|
+
dependencies_changed = True
|
|
176
|
+
|
|
177
|
+
if uv_lock_hash_before != uv_lock_hash_after:
|
|
178
|
+
print("🔒 uv.lock has changed")
|
|
179
|
+
dependencies_changed = True
|
|
180
|
+
|
|
181
|
+
# Special handling for machineconfig repository
|
|
182
|
+
if "machineconfig" in str(repo_path):
|
|
183
|
+
print("🛠 Special handling for machineconfig repository...")
|
|
184
|
+
scripts_path = Path.home() / "scripts"
|
|
185
|
+
if scripts_path.exists():
|
|
186
|
+
set_permissions_recursive(scripts_path)
|
|
187
|
+
print(f"✅ Set permissions for {scripts_path}")
|
|
188
|
+
|
|
189
|
+
linux_jobs_path = repo_path / "src" / "machineconfig" / "jobs" / "linux"
|
|
190
|
+
if linux_jobs_path.exists():
|
|
191
|
+
set_permissions_recursive(linux_jobs_path)
|
|
192
|
+
print(f"✅ Set permissions for {linux_jobs_path}")
|
|
193
|
+
|
|
194
|
+
lf_exe_path = repo_path / "src" / "machineconfig" / "settings" / "lf" / "linux" / "exe"
|
|
195
|
+
if lf_exe_path.exists():
|
|
196
|
+
set_permissions_recursive(lf_exe_path)
|
|
197
|
+
print(f"✅ Set permissions for {lf_exe_path}")
|
|
198
|
+
|
|
199
|
+
# Run uv sync if dependencies changed and auto_sync is enabled
|
|
200
|
+
if dependencies_changed and auto_sync:
|
|
201
|
+
run_uv_sync(repo_path)
|
|
202
|
+
|
|
203
|
+
return dependencies_changed
|
|
204
|
+
|
|
205
|
+
except Exception as e:
|
|
206
|
+
print(f"❌ Error updating repository {repo_path}: {e}")
|
|
207
|
+
return False
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
def main(verbose: bool = True, allow_password_prompt: bool = False) -> str:
|
|
211
|
+
"""Main function to update all configured repositories."""
|
|
14
212
|
_ = verbose
|
|
15
|
-
repos: list[str] = ["~/code/
|
|
213
|
+
repos: list[str] = ["~/code/machineconfig", "~/code/crocodile"]
|
|
16
214
|
try:
|
|
17
|
-
tmp = read_ini(DEFAULTS_PATH)[
|
|
18
|
-
if tmp[-1] == "":
|
|
215
|
+
tmp = read_ini(DEFAULTS_PATH)["general"]["repos"].split(",")
|
|
216
|
+
if tmp[-1] == "":
|
|
217
|
+
tmp = tmp[:-1]
|
|
19
218
|
repos += tmp
|
|
20
219
|
except (FileNotFoundError, KeyError, IndexError):
|
|
21
220
|
print(f"""
|
|
@@ -34,57 +233,31 @@ def main(verbose: bool=True) -> str:
|
|
|
34
233
|
│ to_email = myemail@email.com
|
|
35
234
|
└────────────────────────────────────────────────────────────────""")
|
|
36
235
|
|
|
37
|
-
|
|
236
|
+
# Process repositories
|
|
237
|
+
repos_with_changes = []
|
|
38
238
|
for a_package_path in repos:
|
|
39
239
|
try:
|
|
40
|
-
|
|
41
|
-
repo = git.Repo(str(
|
|
42
|
-
|
|
240
|
+
expanded_path = PathExtended(a_package_path).expanduser()
|
|
241
|
+
repo = git.Repo(str(expanded_path), search_parent_directories=True)
|
|
242
|
+
|
|
243
|
+
# Update repository and check if dependencies changed
|
|
244
|
+
dependencies_changed = update_repository(repo, allow_password_prompt=allow_password_prompt)
|
|
245
|
+
|
|
246
|
+
if dependencies_changed:
|
|
247
|
+
repos_with_changes.append(Path(repo.working_dir))
|
|
248
|
+
|
|
43
249
|
except Exception as ex:
|
|
44
|
-
print(f"""
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
an_addition = f"""
|
|
55
|
-
echo ""
|
|
56
|
-
echo "🔄 {("Updating " + str(a_repo.working_dir)).center(80, "═")}"
|
|
57
|
-
echo "🛠 Special handling for machineconfig repository..."
|
|
58
|
-
cd "{a_repo.working_dir}"
|
|
59
|
-
# git reset --hard
|
|
60
|
-
git pull origin &
|
|
61
|
-
chmod +x ~/scripts -R
|
|
62
|
-
chmod +x ~/code/machineconfig/src/machineconfig/jobs/linux -R
|
|
63
|
-
chmod +x ~/code/machineconfig/src/machineconfig/settings/lf/linux/exe -R
|
|
64
|
-
"""
|
|
65
|
-
additions.append(an_addition)
|
|
66
|
-
else:
|
|
67
|
-
additions.append(f"""
|
|
68
|
-
echo "🔄 {("Updating " + str(a_repo.working_dir)).center(80, "═")}"
|
|
69
|
-
cd "{a_repo.working_dir}"
|
|
70
|
-
{sep.join([f'git pull {remote.name} {a_repo.active_branch.name} &' for remote in a_repo.remotes])}
|
|
71
|
-
"""
|
|
72
|
-
)
|
|
73
|
-
program = "\n".join(additions)
|
|
74
|
-
|
|
75
|
-
elif system() == "Windows":
|
|
76
|
-
program = "\n".join([f"""
|
|
77
|
-
echo "🔄 {("Updating " + str(a_repo.working_dir)).center(80, "═")}"
|
|
78
|
-
cd "{a_repo.working_dir}"
|
|
79
|
-
{sep.join([f'git pull {remote.name} {a_repo.active_branch.name}' for remote in a_repo.remotes])}
|
|
80
|
-
""" for a_repo in repos_objs])
|
|
81
|
-
else: raise NotImplementedError(f"""
|
|
82
|
-
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
83
|
-
┃ ⚠️ Unsupported System: {system()}
|
|
84
|
-
┃ ℹ️ This functionality is only available on Windows and Linux
|
|
85
|
-
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━""")
|
|
86
|
-
return program
|
|
250
|
+
print(f"""❌ Repository Error: Path: {a_package_path}
|
|
251
|
+
Exception: {ex}
|
|
252
|
+
{"-" * 50}""")
|
|
253
|
+
|
|
254
|
+
# Run uv sync for repositories where pyproject.toml or uv.lock changed
|
|
255
|
+
for repo_path in repos_with_changes:
|
|
256
|
+
run_uv_sync(repo_path)
|
|
257
|
+
|
|
258
|
+
# print("\n🎉 All repositories updated successfully!")
|
|
259
|
+
return """echo "🎉 All repositories updated successfully!" """
|
|
87
260
|
|
|
88
261
|
|
|
89
|
-
if __name__ ==
|
|
90
|
-
|
|
262
|
+
if __name__ == "__main__":
|
|
263
|
+
main()
|
|
@@ -1,15 +1,13 @@
|
|
|
1
|
-
"""Like yadm and dotter.
|
|
2
|
-
"""
|
|
1
|
+
"""Like yadm and dotter."""
|
|
3
2
|
|
|
4
|
-
|
|
5
|
-
from machineconfig.utils.
|
|
6
|
-
from machineconfig.
|
|
7
|
-
from machineconfig.utils.utils import LIBRARY_ROOT, REPO_ROOT
|
|
3
|
+
from machineconfig.utils.path_reduced import PathExtended as PathExtended
|
|
4
|
+
from machineconfig.utils.links import symlink_func
|
|
5
|
+
from machineconfig.utils.source_of_truth import LIBRARY_ROOT, REPO_ROOT
|
|
8
6
|
import argparse
|
|
9
7
|
|
|
10
8
|
|
|
11
9
|
def main():
|
|
12
|
-
parser = argparse.ArgumentParser(description=
|
|
10
|
+
parser = argparse.ArgumentParser(description="FTP client")
|
|
13
11
|
|
|
14
12
|
parser.add_argument("file", help="file/folder path.", default="")
|
|
15
13
|
# FLAGS
|
|
@@ -20,11 +18,15 @@ def main():
|
|
|
20
18
|
args = parser.parse_args()
|
|
21
19
|
orig_path = PathExtended(args.file).expanduser().absolute()
|
|
22
20
|
if args.dest == "":
|
|
23
|
-
if "Local" in str(orig_path):
|
|
24
|
-
|
|
25
|
-
elif "
|
|
26
|
-
|
|
27
|
-
|
|
21
|
+
if "Local" in str(orig_path):
|
|
22
|
+
junction = orig_path.split(at="Local", sep=-1)[1]
|
|
23
|
+
elif "Roaming" in str(orig_path):
|
|
24
|
+
junction = orig_path.split(at="Roaming", sep=-1)[1]
|
|
25
|
+
elif ".config" in str(orig_path):
|
|
26
|
+
junction = orig_path.split(at=".config", sep=-1)[1]
|
|
27
|
+
else:
|
|
28
|
+
junction = orig_path.rel2home()
|
|
29
|
+
new_path = PathExtended(REPO_ROOT).joinpath(junction)
|
|
28
30
|
else:
|
|
29
31
|
dest_path = PathExtended(args.dest).expanduser().absolute()
|
|
30
32
|
dest_path.mkdir(parents=True, exist_ok=True)
|
|
@@ -39,12 +41,12 @@ def main():
|
|
|
39
41
|
┃ 🔄 To enshrine this mapping, add the following to mapper.toml:
|
|
40
42
|
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━""")
|
|
41
43
|
print(f"""
|
|
42
|
-
📝 Edit configuration file: nano {LIBRARY_ROOT}/symlinks/mapper.toml
|
|
44
|
+
📝 Edit configuration file: nano {PathExtended(LIBRARY_ROOT)}/symlinks/mapper.toml
|
|
43
45
|
|
|
44
46
|
[{new_path.parent.name}]
|
|
45
|
-
{orig_path.name.split(
|
|
47
|
+
{orig_path.name.split(".")[0]} = {{ this = '{orig_path.collapseuser().as_posix()}', to_this = '{new_path.collapseuser().as_posix()}' }}
|
|
46
48
|
""")
|
|
47
49
|
|
|
48
50
|
|
|
49
|
-
if __name__ ==
|
|
51
|
+
if __name__ == "__main__":
|
|
50
52
|
main()
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
|
|
2
1
|
"""Utility to launch multiple AI agent prompts in a Zellij session.
|
|
3
2
|
|
|
4
3
|
Improved design notes:
|
|
@@ -17,14 +16,20 @@ from typing import Literal, TypeAlias, get_args, Iterable
|
|
|
17
16
|
|
|
18
17
|
from machineconfig.cluster.sessions_managers.zellij_local_manager import ZellijLocalManager
|
|
19
18
|
from machineconfig.utils.utils2 import randstr
|
|
19
|
+
import random
|
|
20
|
+
# import time
|
|
20
21
|
|
|
21
|
-
AGENTS: TypeAlias = Literal[
|
|
22
|
+
AGENTS: TypeAlias = Literal[
|
|
23
|
+
"cursor-agent", "gemini", "crush", "q", "onlyPrepPromptFiles"
|
|
24
|
+
# warp terminal
|
|
25
|
+
]
|
|
22
26
|
TabConfig = dict[str, tuple[str, str]] # tab name -> (cwd, command)
|
|
23
27
|
DEFAULT_AGENT_CAP = 6
|
|
24
28
|
|
|
25
29
|
|
|
26
30
|
def get_gemini_api_keys() -> list[str]:
|
|
27
31
|
from machineconfig.utils.utils2 import read_ini
|
|
32
|
+
|
|
28
33
|
config = read_ini(Path.home().joinpath("dotfiles/creds/llm/gemini/api_keys.ini"))
|
|
29
34
|
res: list[str] = []
|
|
30
35
|
for a_section_name in list(config.sections()):
|
|
@@ -41,12 +46,17 @@ def get_gemini_api_keys() -> list[str]:
|
|
|
41
46
|
def _search_python_files(repo_root: Path, keyword: str) -> list[Path]:
|
|
42
47
|
"""Return all Python files under repo_root whose text contains keyword.
|
|
43
48
|
|
|
44
|
-
|
|
49
|
+
Notes:
|
|
50
|
+
- Skips any paths that reside under a directory named ".venv" at any depth.
|
|
51
|
+
- Errors reading individual files are ignored (decoded with 'ignore').
|
|
45
52
|
"""
|
|
46
53
|
py_files = list(repo_root.rglob("*.py"))
|
|
47
54
|
keyword_lower = keyword.lower()
|
|
48
55
|
matches: list[Path] = []
|
|
49
56
|
for f in py_files:
|
|
57
|
+
# Skip anything under a .venv directory anywhere in the path
|
|
58
|
+
if any(part == ".venv" for part in f.parts):
|
|
59
|
+
continue
|
|
50
60
|
try:
|
|
51
61
|
if keyword_lower in f.read_text(encoding="utf-8", errors="ignore").lower():
|
|
52
62
|
matches.append(f)
|
|
@@ -59,6 +69,8 @@ def _search_python_files(repo_root: Path, keyword: str) -> list[Path]:
|
|
|
59
69
|
def _write_list_file(target: Path, files: Iterable[Path]) -> None:
|
|
60
70
|
target.parent.mkdir(parents=True, exist_ok=True)
|
|
61
71
|
target.write_text("\n".join(str(f) for f in files), encoding="utf-8")
|
|
72
|
+
|
|
73
|
+
|
|
62
74
|
def _chunk_prompts(prompts: list[str], max_agents: int) -> list[str]:
|
|
63
75
|
prompts = [p for p in prompts if p.strip() != ""] # drop blank entries
|
|
64
76
|
if len(prompts) <= max_agents:
|
|
@@ -69,6 +81,8 @@ def _chunk_prompts(prompts: list[str], max_agents: int) -> list[str]:
|
|
|
69
81
|
for i in range(0, len(prompts), chunk_size):
|
|
70
82
|
grouped.append("\nTargeted Locations:\n".join(prompts[i : i + chunk_size]))
|
|
71
83
|
return grouped
|
|
84
|
+
|
|
85
|
+
|
|
72
86
|
def _confirm(message: str, default_no: bool = True) -> bool:
|
|
73
87
|
suffix = "[y/N]" if default_no else "[Y/n]"
|
|
74
88
|
answer = input(f"{message} {suffix} ").strip().lower()
|
|
@@ -89,11 +103,7 @@ def launch_agents(repo_root: Path, prompts: list[str], agent: AGENTS, *, max_age
|
|
|
89
103
|
raise ValueError("No prompts provided")
|
|
90
104
|
|
|
91
105
|
if len(prompts) > max_agents:
|
|
92
|
-
proceed = _confirm(
|
|
93
|
-
message=(
|
|
94
|
-
f"You are about to launch {len(prompts)} agents which exceeds the cap ({max_agents}). Proceed?"
|
|
95
|
-
)
|
|
96
|
-
)
|
|
106
|
+
proceed = _confirm(message=(f"You are about to launch {len(prompts)} agents which exceeds the cap ({max_agents}). Proceed?"))
|
|
97
107
|
if not proceed:
|
|
98
108
|
print("Aborting per user choice.")
|
|
99
109
|
return {}
|
|
@@ -105,6 +115,7 @@ def launch_agents(repo_root: Path, prompts: list[str], agent: AGENTS, *, max_age
|
|
|
105
115
|
for idx, a_prompt in enumerate(prompts):
|
|
106
116
|
prompt_path = tmp_dir / f"agent{idx}_prompt.txt"
|
|
107
117
|
prompt_path.write_text(a_prompt, encoding="utf-8")
|
|
118
|
+
cmd_path = tmp_dir / f"agent{idx}_cmd.sh"
|
|
108
119
|
match agent:
|
|
109
120
|
case "gemini":
|
|
110
121
|
# model = "gemini-2.5-pro"
|
|
@@ -122,27 +133,45 @@ def launch_agents(repo_root: Path, prompts: list[str], agent: AGENTS, *, max_age
|
|
|
122
133
|
cmd = f"""
|
|
123
134
|
export GEMINI_API_KEY={shlex.quote(api_key)}
|
|
124
135
|
echo "Using Gemini API key $GEMINI_API_KEY"
|
|
125
|
-
echo "Launching gemini agent with prompt from {shlex.quote(str(prompt_path))}"
|
|
126
136
|
cat {prompt_path}
|
|
127
137
|
GEMINI_API_KEY={shlex.quote(api_key)} bash -lc 'cat {safe_path} | gemini {model_arg} --yolo --prompt'
|
|
128
138
|
"""
|
|
129
139
|
case "cursor-agent":
|
|
130
140
|
# As originally implemented
|
|
131
141
|
cmd = f"""
|
|
132
|
-
|
|
133
|
-
cat {prompt_path}
|
|
142
|
+
|
|
134
143
|
cursor-agent --print --output-format text < {prompt_path}
|
|
144
|
+
|
|
135
145
|
"""
|
|
136
146
|
case "crush":
|
|
137
147
|
cmd = f"""
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
148
|
+
# cat {prompt_path} | crush run
|
|
149
|
+
crush run {prompt_path}
|
|
150
|
+
"""
|
|
151
|
+
case "q":
|
|
152
|
+
cmd = f"""
|
|
153
|
+
q chat --no-interactive --trust-all-tools {prompt_path}
|
|
154
|
+
"""
|
|
155
|
+
case "onlyPrepPromptFiles":
|
|
156
|
+
cmd = f"""
|
|
157
|
+
echo "Prepared prompt file at {prompt_path}"
|
|
141
158
|
"""
|
|
142
159
|
case _:
|
|
143
160
|
raise ValueError(f"Unsupported agent type: {agent}")
|
|
144
|
-
|
|
145
|
-
|
|
161
|
+
random_sleep_time = random.uniform(0, 5)
|
|
162
|
+
cmd_prefix = f"""
|
|
163
|
+
echo "Sleeping for {random_sleep_time:.2f} seconds to stagger agent startups..."
|
|
164
|
+
sleep {random_sleep_time:.2f}
|
|
165
|
+
echo "Launching `{agent}` with prompt from {prompt_path}"
|
|
166
|
+
echo "Launching `{agent}` with command from {cmd_path}"
|
|
167
|
+
echo "--------START OF AGENT OUTPUT--------"
|
|
168
|
+
sleep 0.1
|
|
169
|
+
"""
|
|
170
|
+
cmd_postfix = """
|
|
171
|
+
sleep 0.1
|
|
172
|
+
echo "---------END OF AGENT OUTPUT---------"
|
|
173
|
+
"""
|
|
174
|
+
cmd_path.write_text(cmd_prefix + cmd + cmd_postfix, encoding="utf-8")
|
|
146
175
|
fire_cmd = f"bash {shlex.quote(str(cmd_path))}"
|
|
147
176
|
tab_config[f"Agent{idx}"] = (str(repo_root), fire_cmd)
|
|
148
177
|
|
|
@@ -189,18 +218,15 @@ def main(): # noqa: C901 - (complexity acceptable for CLI glue)
|
|
|
189
218
|
combined_prompts = [prefix + "\n" + p for p in combined_prompts]
|
|
190
219
|
|
|
191
220
|
from machineconfig.utils.options import choose_one_option
|
|
221
|
+
|
|
192
222
|
agent_selected = choose_one_option(header="Select agent type", options=get_args(AGENTS))
|
|
193
223
|
|
|
194
|
-
tab_config = launch_agents(
|
|
195
|
-
repo_root=repo_root,
|
|
196
|
-
prompts=combined_prompts,
|
|
197
|
-
agent=agent_selected,
|
|
198
|
-
max_agents=DEFAULT_AGENT_CAP,
|
|
199
|
-
)
|
|
224
|
+
tab_config = launch_agents(repo_root=repo_root, prompts=combined_prompts, agent=agent_selected, max_agents=DEFAULT_AGENT_CAP)
|
|
200
225
|
if not tab_config:
|
|
201
226
|
return
|
|
202
227
|
|
|
203
228
|
from machineconfig.utils.utils2 import randstr
|
|
229
|
+
|
|
204
230
|
random_name = randstr(length=3)
|
|
205
231
|
manager = ZellijLocalManager(session2zellij_tabs={"Agents": tab_config}, session_name_prefix=random_name)
|
|
206
232
|
manager.start_all_sessions()
|