Fix #528: non-TTY installer hardcodes the Claude agent
Fixes #528.
Both symptoms
- Installer hardcoded
setup claude— the piped install (curl -fsSL https://basecamp.com/install-cli | bash, a 302 redirect to this repo'sscripts/install.sh) took the non-TTY branch, which unconditionally ranbasecamp setup claude. TheBASECAMP_SKIP_SETUP=1branch did the same. - Claude-first login nudge —
printAgentNudgepointed at the first detected-unhealthy agent in registry order, so it always recommended Claude when both agents were present.
Approach — detection proves presence, not intent
New basecamp setup agents command (always non-interactive): installs the baseline skill and connects coding agents by intent.
BASECAMP_SETUP_AGENTwins:claude|codex|all|none.- Auto (unset): 0 detected → skill only · 1 → connect it · ≥2 → skill only + surface
setup <id>choices (never guess). allforces every registered handler and synthesizes symmetric missing-binary remediation — the Claude handler treats an absent binary as no-op success while Codex errors, so the aggregate runner fills the gap for either.- Invalid value → structured warning + baseline only.
BASECAMP_SKIP_SETUP=1skips only the interactive wizard;setup agentsstill runs.
Styled-safe result envelope
curl | bash renders styled output (piped stdin, TTY stdout), and the styled renderer skips nested map/[]map. So every safety-critical outcome — skill_installed, selector, ambiguous, detected_before, attempted_agents, errors (union of baseline + id-prefixed per-agent), warnings, manual_commands — lives in a top-level flat field; the agents array is JSON-only detail. Ordering is deterministic: set-like fields sorted by id; manual_commands/errors preserve each handler's own sequence with stable first-seen dedup (Codex's remediation is an ordered marketplace-add → upgrade → plugin-add sequence, never lexicographically sorted).
Changes
internal/commands/wizard_agents.go—newSetupAgentsCmd+runNonInteractiveAgentSetupand the typed envelope. Existingsetup claude/setup codexunchanged.internal/commands/auth.go— rewriteprintAgentNudge: one detected-unhealthy agent → itssetup <id>; several → every choice printed directly.scripts/install.sh/scripts/install.ps1— both non-TTY and skip branches runsetup agents; install.sh gains an if-form source guard and documentsBASECAMP_SETUP_AGENT..surfaceregenerated (onlysetup agentsadditions); smoke declaration + newe2e/installer.bats;install.mdupdated.
Tests
internal/commands/setup_agents_test.go— full-CLI (cobra Execute) coverage: styled-output regression (failure survives via top-levelerrors), 0/1/≥2 detection, baseline-skill failure,=allzero/one/two,=codexmissing-binary contract, Codex manual-order preservation (guards against string-sorting),=claudeno-binary (symlink + detection flip + synthesized remediation),=none, invalid selector.internal/commands/auth_test.go— nudge: none / single / multiple detected-unhealthy.e2e/installer.bats— sourcing guard,post_install_setupdispatch (non-TTY + skip →setup agents, neversetup claude), static branch assertions for both scripts.
Verified: make build, targeted go test, make check-surface/check-skill-drift/check-bare-groups/check-naming/check-smoke-coverage/fmt-check/vet/lint, and the smoke + installer bats suites all green. (The full unit suite has a pre-existing network-dependent todos-reposition test that hangs offline; unrelated to this change.)
Summary by cubic
Replaces the non-TTY installer’s hardcoded Claude path with an intent-based, non-interactive agent setup. Adds basecamp setup agents, makes installers cross-version safe, and prevents old releases from launching the interactive wizard.
-
New Features
- Added
basecamp setup agents(non-interactive): installs the baseline skill and connects coding agents by intent; honorsBASECAMP_SETUP_AGENT=claude|codex|all|none(unset auto-detects: 0→skill only, 1→connect it, ≥2→skill only + surfacesetup <id>choices). - Installers (
scripts/install.sh,scripts/install.ps1) runsetup agentsfor non-TTY andBASECAMP_SKIP_SETUP=1. Docs updated with piped-install auto-connect and how to setBASECAMP_SETUP_AGENTin Bash/PowerShell. - Styled-safe result: all critical outcomes are top-level flat fields so they render in styled output; the
agentsarray is JSON-only detail.
- Added
-
Bug Fixes
- Cross-version installers: probe for
setup agents. On older binaries, fall back without reintroducing Claude-first behavior—allruns each supported per-agent setup; explicitclaude/codexis capability-checked and degrades toskill installif unsupported; all calls are guarded so failures never abort install. - PowerShell
Invoke-PostInstallSetup: marks attempted agents on dispatch (not success) to match Bash, so=allonly falls back toskill installwhen no supported per-agent subcommands exist. setup agentsrejects positional args to prevent accidentalsetup <id>typos.- Login nudge points to the detected-unhealthy agent; with multiple, it lists each
basecamp setup <id>option (no bias).
- Cross-version installers: probe for