diff --git a/docs/design-npm-global-install-fixes.html b/docs/design-npm-global-install-fixes.html index cfb8b9680..4ddc0bb1e 100644 --- a/docs/design-npm-global-install-fixes.html +++ b/docs/design-npm-global-install-fixes.html @@ -672,13 +672,13 @@ const nodeModules = resolve(webDir, "node_modules", "@composio", "ao-core");
preflight.checkTmux() — low-level check + auto-install. Logs each attempt
- ("Attempting: brew install tmux") before running. Used by preflight checks and
- non-interactive contexts.preflight.checkTmux() — low-level check-only guard used by
+ ao spawn preflight. It validates tmux -V and throws platform-specific
+ manual install instructions when missing (no install attempts).ensureTmux() in start.ts — interactive wrapper. Uses askYesNo()
to get user consent before running tryInstallWithAttempts() with
tmuxInstallAttempts(). Matches the existing ensureGit() pattern.
- No silent sudo — the user sees what will run and approves it.// start.ts — interactive install with user consent
@@ -687,7 +687,7 @@ async function ensureTmux(): Promise<void> {
if (hasTmux) return;
console.log("⚠ tmux is required for runtime \"tmux\".");
- const shouldInstall = await askYesNo("Install tmux now?", true);
+ const shouldInstall = await askYesNo("Install tmux now?", true, false);
if (shouldInstall) {
const installed = await tryInstallWithAttempts(
tmuxInstallAttempts(),
@@ -794,7 +794,7 @@ async function ensureTmux(): Promise<void> {
Always asks first — uses askYesNo() before running any install command. No silent sudo or background package manager invocations.
Logs each command — shows "Running: brew install tmux" (via tryInstallWithAttempts()) so the user knows exactly what's executing.
Blocks on required failures — for tmux and git, prints platform-specific manual install instructions and exits rather than silently degrading the experience.
- Non-interactive fallback — when not a TTY (CI, piped scripts, agent callers), canPromptForInstall() returns false and askYesNo() returns its default without prompting. Required tools default to true (attempt install), optional tools default to false (skip).
+ Non-interactive fallback — when not a TTY (CI, piped scripts, agent callers), canPromptForInstall() returns false and askYesNo() returns its non-interactive default without prompting. Required and optional tools both default to false (skip), then print manual instructions when required tools are missing.
Consistent pattern — all prerequisite helpers (ensureTmux(), ensureGit(), promptInstallAgentRuntime()) follow the same structure: detect → prompt → install → verify → block or skip.
@@ -891,8 +891,9 @@ function launch(): ChildProcess {
7. Files Changed
- - packages/cli/src/lib/preflight.ts — walk-up resolver, auto-install tmux, platform messages
+ - packages/cli/src/lib/preflight.ts — walk-up resolver, check-only tmux preflight + platform messages
- packages/cli/src/commands/start.ts — centralized
ensureTmux() gate + interactive install prompts for git/tmux/agent runtimes (+ optional gh)
+ - packages/cli/src/lib/detect-agent.ts — shared runtime selection with optional pre-detected list (avoids redundant plugin scan)
- packages/ao/bin/postinstall.js — node-pty spawn-helper chmod
- packages/ao/package.json — postinstall script registration
- packages/web/server/start-all.ts — restart logic with slot-based bookkeeping
@@ -946,17 +947,17 @@ function launch(): ChildProcess {
macOS (Intel + Apple Silicon)
Works
- Auto-installs via brew
Clear error if brew missing
+ Interactive prompt + brew install
Clear error if brew missing or declined
Linux x64
Works
- Auto-installs via apt/dnf
Clear error if sudo unavailable
+ Interactive prompt + apt/dnf install
Clear error if sudo unavailable or declined
Linux arm64 (Graviton)
Works
Direct terminal unavailable (no node-pty prebuild)
- Auto-installs via apt/dnf
Clear error if sudo unavailable
+ Interactive prompt + apt/dnf install
Clear error if sudo unavailable or declined
Windows
@@ -967,9 +968,9 @@ function launch(): ChildProcess {
- Key improvement: Most platforms get tmux auto-installed. When auto-install
- fails, the user gets a one-line command to copy-paste, then ao start again.
- No degraded modes, no confusing config state.
+ Key improvement: Missing prerequisites are handled with explicit user consent in
+ ao start. If install is declined or fails, the CLI prints one-line commands to run
+ manually, then exits clearly.
@@ -1023,12 +1024,12 @@ function launch(): ChildProcess {
ao-core found but dist/index.js missing shows build hint
- tmux auto-install success
- When tmux -V fails initially but install succeeds, checkTmux passes
+ tmux interactive install success
+ When tmux -V fails initially and user-approved install succeeds, ensureTmux() passes
- tmux auto-install failure
- When all install attempts fail, throws with platform-specific instructions
+ tmux interactive install declined/failure
+ When user declines or install attempts fail, prints platform-specific instructions and exits
@@ -1039,9 +1040,9 @@ function launch(): ChildProcess {
11. Design Decisions
- Auto-install tmux, then block with clear instructions on failure.
- We try brew (macOS) and apt/dnf (Linux) automatically. If auto-install fails, we exit
- with a clear one-line install command rather than falling back to runtime: "process".
+ Prompted tmux install in ao start, then block with clear instructions on failure.
+ We ask first, then try brew (macOS) and apt/dnf (Linux) only after consent. If install is
+ declined or fails, we exit with a clear one-line install command rather than falling back to runtime: "process".
The process runtime lacks session attach, terminal panel, and ao send —
a degraded first impression is worse than asking the user to run one command.