diff --git a/myagents/commands/ensure_agent.py b/myagents/commands/ensure_agent.py index 11e7e2c..7825fdf 100644 --- a/myagents/commands/ensure_agent.py +++ b/myagents/commands/ensure_agent.py @@ -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 diff --git a/myagents/launcher.py b/myagents/launcher.py index 17b0f3d..2522776 100644 --- a/myagents/launcher.py +++ b/myagents/launcher.py @@ -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)