Prefer xiaohe ensure-agent hints and support non-interactive yes installs.
Install scripts and product CLI can install the default backend without a picker, and skip messages point at xiaohe when it is on PATH.
This commit is contained in:
@@ -25,12 +25,14 @@ def installable_backends() -> list[str]:
|
||||
def run_ensure_agents(
|
||||
*,
|
||||
prefer: list[str] | None = None,
|
||||
yes: bool = False,
|
||||
) -> list[str]:
|
||||
"""Show status, let user pick missing CLIs, install them.
|
||||
|
||||
``prefer``: when interactive, Enter defaults to these names (intersected
|
||||
with missing) instead of all missing — used by xiaohe for its default
|
||||
agent. Returns backends that remain missing afterwards.
|
||||
agent. ``yes``: skip the picker and install prefer (or all missing).
|
||||
Returns backends that remain missing afterwards.
|
||||
"""
|
||||
targets = installable_backends()
|
||||
if not targets:
|
||||
@@ -66,7 +68,8 @@ def run_ensure_agents(
|
||||
console.print("[green]All installable agent CLIs ready.[/green]")
|
||||
return []
|
||||
|
||||
if not _is_interactive():
|
||||
interactive = _is_interactive() and not yes
|
||||
if not interactive:
|
||||
to_install = (
|
||||
[n for n in (prefer or []) if n in missing] or list(missing)
|
||||
)
|
||||
@@ -140,15 +143,23 @@ def run_ensure_agents(
|
||||
still = [n for n in missing if n not in to_install or n in failed]
|
||||
if failed:
|
||||
console.print()
|
||||
hint = (
|
||||
"xiaohe ensure-agent"
|
||||
if __import__("shutil").which("xiaohe")
|
||||
else "myagents ensure-agent"
|
||||
)
|
||||
console.print(
|
||||
"[yellow]Some installs failed.[/yellow] Install Node.js if needed, "
|
||||
"then re-run [cyan]myagents ensure-agent[/cyan]."
|
||||
f"then: [cyan]{hint}[/cyan]."
|
||||
)
|
||||
elif not still:
|
||||
console.print("[green]Selected agent CLIs ready.[/green]")
|
||||
console.print(
|
||||
" Launch: [cyan]myclaude[/cyan] / [cyan]mycodex[/cyan] / …"
|
||||
)
|
||||
if __import__("shutil").which("xiaohe"):
|
||||
console.print(" Next: [cyan]xiaohe[/cyan]")
|
||||
else:
|
||||
console.print(
|
||||
" Launch: [cyan]myclaude[/cyan] / [cyan]mycodex[/cyan] / …"
|
||||
)
|
||||
return still
|
||||
|
||||
|
||||
|
||||
+16
-7
@@ -393,6 +393,15 @@ def _exec_tmux(backend: str, chat_cwd: Path, cmd: list[str]) -> None:
|
||||
raise SystemExit(proc.returncode)
|
||||
|
||||
|
||||
def _ensure_agent_hint() -> str:
|
||||
"""Prefer product-facing xiaohe when installed; else myagents."""
|
||||
return (
|
||||
"xiaohe ensure-agent"
|
||||
if shutil.which("xiaohe")
|
||||
else "myagents ensure-agent"
|
||||
)
|
||||
|
||||
|
||||
def _run_install(config: dict) -> str | None:
|
||||
"""Run ``install_cmd`` and return the resolved binary path, or None."""
|
||||
install_cmd = config.get("install_cmd")
|
||||
@@ -400,12 +409,12 @@ def _run_install(config: dict) -> str | None:
|
||||
return None
|
||||
installer = shutil.which(install_cmd[0])
|
||||
if not installer:
|
||||
hint = _ensure_agent_hint()
|
||||
stderr_console.print(
|
||||
f"[red]{install_cmd[0]} not found[/red] — cannot auto-install "
|
||||
f"{config['binary']}.\n"
|
||||
" Install Node.js (e.g. [cyan]brew install node[/cyan]), then run "
|
||||
"[cyan]myagents ensure-agent[/cyan] or launch "
|
||||
f"[cyan]my{config.get('binary', 'claude')}[/cyan]."
|
||||
" Run: [cyan]brew install node[/cyan] (or install Node.js), then "
|
||||
f"[cyan]{hint}[/cyan]."
|
||||
)
|
||||
return None
|
||||
stderr_console.print(
|
||||
@@ -417,10 +426,10 @@ def _run_install(config: dict) -> str | None:
|
||||
)
|
||||
proc = subprocess.run([installer, *install_cmd[1:]], check=False)
|
||||
if proc.returncode != 0:
|
||||
hint = _ensure_agent_hint()
|
||||
stderr_console.print(
|
||||
f"[red]Install failed (exit {proc.returncode}).[/red]\n"
|
||||
" Fix the error above, then run "
|
||||
"[cyan]myagents ensure-agent[/cyan]."
|
||||
f" Run: [cyan]{hint}[/cyan]."
|
||||
)
|
||||
return None
|
||||
# Refresh PATH for this process; offer to persist npm bin into shell rc.
|
||||
@@ -460,9 +469,9 @@ def _offer_install(config: dict, *, yes: bool | None = None) -> str | None:
|
||||
except (click.Abort, EOFError):
|
||||
return None
|
||||
if answer.strip().lower() not in ("y", "yes", ""):
|
||||
hint = _ensure_agent_hint()
|
||||
stderr_console.print(
|
||||
"[dim]Skipped.[/dim] Later: [cyan]myagents ensure-agent[/cyan] "
|
||||
"or launch again (e.g. [cyan]myclaude[/cyan])."
|
||||
f"[dim]Skipped. Later:[/dim] [cyan]{hint}[/cyan]"
|
||||
)
|
||||
return None
|
||||
return _run_install(config)
|
||||
|
||||
Reference in New Issue
Block a user